#ifndef JKRDECOMP_H #define JKRDECOMP_H #include "types.h" #include "dolphin/os/OSMessage.h" #include "JSystem/JKernel/JKRDvdFile.h" #include "JSystem/JKernel/JKRThread.h" #include "JSystem/JKernel/JKRAram.h" #include "JSystem/JKernel/JKREnum.h" #ifdef __cplusplus #define JKRDECOMP_MSG_BUF_COUNT 4 #define JKRDECOMP_STACK_SIZE 0x4000 #define JKRDECOMP_THREAD_MSG_BUF_COUNT 16 #define JKRDECOMP_READU32BE(ptr, offset) \ (((u32)ptr[offset] << 24) | ((u32)ptr[offset + 1] << 16) | ((u32)ptr[offset + 2] << 8) | (u32)ptr[offset + 3]) #define SZ_MIN_BACKSIZE 3 #define SZ_DEFAULT_BACKSIZE 15 + SZ_MIN_BACKSIZE #define SZP_GETBACKOFS(buf) (((*((u8*)buf) & 0xF) << 8) | (*(((u8*)buf) + 1))) #define SZP_GETCOUNT(buf) (*((u16*)buf) >> 12) typedef void DecompCallback(u32); class JKRDecompCommand { public: enum TransferType { MRAM = 0, ARAM = 1 }; JKRDecompCommand(); ~JKRDecompCommand(); u8 _00[4]; u8* mSrcBuffer; u8* mDstBuffer; u32 mSrcLength; u32 mSkipCount; DecompCallback* mCallback; JKRDecompCommand* mCmd; OSMessageQueue* pMesgQueue1C; TransferType transferType; JKRAMCommand* mAMCommand; OSMessageQueue mMesgQueue; OSMessage mMesgBuffer[1]; }; class JKRDecomp : public JKRThread { public: enum CompressionMode { NONE = 0, SZP = 1, SZS = 2 }; JKRDecomp(s32 decompPriority); virtual ~JKRDecomp(); virtual void* run(); static JKRDecompCommand* prepareCommand(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount, DecompCallback* callback); static CompressionMode checkCompressed(u8* buf); static JKRDecomp* create(s32 decompPriority); static void decode(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount); static void decodeSZP(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount); static void decodeSZS(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount); static bool orderSync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount); static JKRDecompCommand* orderAsync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount, DecompCallback* callback); static bool sync(JKRDecompCommand* cmd, BOOL noBlock); static BOOL sendCommand(JKRDecompCommand* cmd); static OSMessageQueue sMessageQueue; static OSMessage sMessageBuffer[JKRDECOMP_MSG_BUF_COUNT]; static JKRDecomp* sDecompObject; }; inline JKRDecomp* JKRCreateDecompManager(s32 priority) { return JKRDecomp::create(priority); } inline int JKRCheckCompressed_noASR(u8* pBuf) { int compression = JKRDecomp::checkCompressed(pBuf); if (compression == JKRCOMPRESSION_ASR) compression = JKRCOMPRESSION_NONE; return compression; } inline JKRDecomp::CompressionMode JKRCheckCompressed(u8* buf) { return JKRDecomp::checkCompressed(buf); } inline u32 JKRDecompExpandSize(u8* buf) { return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]; } inline void JKRDecompress(u8* src, u8* dst, u32 srcLength, u32 skipCount) { JKRDecomp::orderSync(src, dst, srcLength, skipCount); } int JKRDecompressFromDVD(JKRDvdFile* srcFile, void* buf, u32 size, u32 maxDest, u32 fileOffset, u32 srcOffset); int JKRDecompressFromDVDToAram(JKRDvdFile* srcFile, u32 address, u32 fileSize, u32 maxDest, u32 fileOffset, u32 srcOffset); int JKRDecompressFromAramToMainRam(u32 srcAddress, void* dst, u32 fileSize, u32 maxDest, u32 fileOffset); #endif #endif