1#ifndef SEAD_SZS_DECOMPRESSOR_H_
2#define SEAD_SZS_DECOMPRESSOR_H_
3
4#include <basis/seadTypes.h>
5#include <resource/seadDecompressor.h>
6#include <resource/seadResource.h>
7#include <resource/seadResourceMgr.h>
8
9namespace sead
10{
11class SZSDecompressor : public Decompressor
12{
13public:
14 enum Step
15 {
16 cStepNormal = 0,
17 cStepShort = 1,
18 cStepLong = 2,
19 };
20
21 struct DecompContext
22 {
23 DecompContext();
24 DecompContext(void* dst);
25
26 void initialize(void* dst);
27
28 __attribute__((always_inline)) bool doCopy(u32 n)
29 {
30 if (u32(this->destCount) < n)
31 {
32 if (this->forceDestCount == 0)
33 return false;
34
35 n = this->destCount & 0xFFFF;
36 }
37
38 this->destCount -= n;
39
40 do
41 {
42 *this->destp = *(this->destp - this->lzOffset);
43 this->destp += 1;
44 } while (--n != 0);
45
46 this->step = SZSDecompressor::cStepNormal;
47 return true;
48 }
49
50 u8* destp;
51 s32 destCount;
52 s32 forceDestCount;
53 u8 flagMask;
54 u8 flags;
55 u8 packHigh;
56 Step step;
57 u16 lzOffset;
58 u8 headerSize;
59 };
60
61public:
62 SZSDecompressor(u32 workSize, u8* workBuffer);
63 virtual ~SZSDecompressor() {}
64
65 virtual u8* tryDecompFromDevice(const ResourceMgr::LoadArg& loadArg, Resource* resource,
66 u32* outSize, u32* outAllocSize, bool* outAllocated);
67
68 static u32 getDecompAlignment(const void* src);
69 static u32 getDecompSize(const void* src);
70 static s32 readHeader_(DecompContext* context, const u8* src, u32 srcSize);
71 static s32 streamDecomp(DecompContext* context, const void* src, u32 srcSize);
72 static s32 decomp(void* dst, u32 dstSize, const void* src, u32 srcSize);
73
74 u32 mWorkSize;
75 u8* mWorkBuffer;
76};
77
78} // namespace sead
79
80#endif // SEAD_SZS_DECOMPRESSOR_H_
81