// // Generated by dtk // Translation Unit: JKRDvdAramRipper.cpp // #include "JSystem/JKernel/JKRDvdAramRipper.h" #include "JSystem/JKernel/JKRAram.h" #include "JSystem/JKernel/JKRAramPiece.h" #include "JSystem/JKernel/JKRAramStream.h" #include "JSystem/JKernel/JKRDecomp.h" #include "JSystem/JKernel/JKRDvdFile.h" #include "JSystem/JKernel/JKRHeap.h" #include "JSystem/JSupport/JSUFileStream.h" #include "JSystem/JUtility/JUTAssert.h" #include "MSL_C/string.h" #include "dolphin/os/OSCache.h" #include "dolphin/os/OSInterrupt.h" #include "dolphin/vi/vi.h" #include "global.h" static int JKRDecompressFromDVDToAram(JKRDvdFile*, u32, u32, u32, u32, u32); static int decompSZS_subroutine(u8*, u32); static u8* firstSrcData(); static u8* nextSrcData(u8*); static u32 dmaBufferFlush(u32); /* 802BDA14-802BDAB0 .text loadToAram__16JKRDvdAramRipperFlUl15JKRExpandSwitchUlUl */ JKRAramBlock* JKRDvdAramRipper::loadToAram(s32 entryNumber, u32 address, JKRExpandSwitch expandSwitch, u32 param_3, u32 param_4) { JKRDvdFile dvdFile; if (!dvdFile.open(entryNumber)) { return NULL; } else { return loadToAram(&dvdFile, address, expandSwitch, param_3, param_4); } } /* 802BDAB0-802BDB50 .text loadToAram__16JKRDvdAramRipperFP10JKRDvdFileUl15JKRExpandSwitchUlUl */ JKRAramBlock* JKRDvdAramRipper::loadToAram(JKRDvdFile* dvdFile, u32 address, JKRExpandSwitch expandSwitch, u32 param_3, u32 param_4) { JKRADCommand* command = loadToAram_Async(dvdFile, address, expandSwitch, NULL, param_3, param_4); syncAram(command, 0); if (command->field_0x44 < 0) { delete command; return NULL; } if (address) { delete command; return (JKRAramBlock*)-1; } JKRAramBlock* result = command->mBlock; delete command; return result; } bool JKRDvdAramRipper::errorRetry = true; /* 802BDB50-802BDBFC .text loadToAram_Async__16JKRDvdAramRipperFP10JKRDvdFileUl15JKRExpandSwitchPFUl_vUlUl */ JKRADCommand* JKRDvdAramRipper::loadToAram_Async(JKRDvdFile* dvdFile, u32 address, JKRExpandSwitch expandSwitch, void (*callback)(u32), u32 param_4, u32 param_5) { JKRADCommand* command = new (JKRGetSystemHeap(), -4) JKRADCommand(); command->mDvdFile = dvdFile; command->mAddress = address; command->mBlock = NULL; command->mExpandSwitch = expandSwitch; command->mCallback = callback; command->mOffset = param_4; command->field_0x18 = param_5; if (!callCommand_Async(command)) { delete command; return NULL; } return command; } JSUList JKRDvdAramRipper::sDvdAramAsyncList; /* 802BDBFC-802BDF34 .text callCommand_Async__16JKRDvdAramRipperFP12JKRADCommand */ JKRADCommand* JKRDvdAramRipper::callCommand_Async(JKRADCommand* command) { /* Nonmatching */ s32 compression; s32 uncompressedSize; bool bVar1 = true; JKRDvdFile* dvdFile = command->mDvdFile; compression = 0; OSLockMutex(&dvdFile->mMutex2); if (dvdFile->field_0x50) { bVar1 = false; } else { dvdFile->field_0x50 = OSGetCurrentThread(); JSUFileInputStream* stream = new (JKRGetSystemHeap(), -4) JSUFileInputStream(dvdFile); dvdFile->mFileStream = stream; u32 fileSize = dvdFile->getFileSize(); if (command->field_0x18 && fileSize > command->field_0x18) { fileSize = command->field_0x18; } fileSize = ALIGN_NEXT(fileSize, 0x20); if (command->mExpandSwitch == 1) { u8 buffer[0x40]; u8* bufPtr = (u8*)ALIGN_NEXT((u32)&buffer, 0x20); while (true) { if (DVDReadPrio(dvdFile->getFileInfo(), bufPtr, 0x20, 0, 2) >= 0) { break; } if (errorRetry == 0) { delete stream; return NULL; } VIWaitForRetrace(); } DCInvalidateRange(bufPtr, 0x20); compression = JKRCheckCompressed(bufPtr); uncompressedSize = JKRDecompExpandSize(bufPtr); if (command->field_0x18 && command->field_0x18 > uncompressedSize) { uncompressedSize = command->field_0x18; } } if (compression == 0) { command->mExpandSwitch = EXPAND_SWITCH_UNKNOWN0; } if (command->mExpandSwitch == EXPAND_SWITCH_UNKNOWN1) { if (command->mAddress == 0 && command->mBlock == NULL) { command->mBlock = JKRAram::getAramHeap()->alloc(uncompressedSize, JKRAramHeap::HEAD); if (command->mBlock) { command->mAddress = command->mBlock->mAddress; } dvdFile->mBlock = command->mBlock; } if (command->mBlock) { command->mAddress = command->mBlock->mAddress; } if (command->mAddress == 0) { dvdFile->field_0x50 = NULL; return NULL; } } else { if (command->mAddress == 0 && !command->mBlock) { command->mBlock = JKRAram::getAramHeap()->alloc(fileSize, JKRAramHeap::HEAD); } if (command->mBlock) { command->mAddress = command->mBlock->mAddress; } if (command->mAddress == 0) { dvdFile->field_0x50 = NULL; return NULL; } } if (compression == 0) { command->mStreamCommand = JKRStreamToAram_Async(stream, command->mAddress, fileSize - command->mOffset, command->mOffset, NULL); } else if (compression == 1) { command->mStreamCommand = JKRStreamToAram_Async(stream, command->mAddress, fileSize - command->mOffset, command->mOffset, NULL); } else if (compression == 2) { command->mStreamCommand = NULL; JKRDecompressFromDVDToAram(command->mDvdFile, command->mAddress, fileSize, uncompressedSize, command->mOffset, 0); } if (!command->mCallback) { (*((JSUList*)&sDvdAramAsyncList)).append(&command->mLink); } else { command->mCallback((u32)command); } } OSUnlockMutex(&dvdFile->mMutex2); return bVar1 == true ? command : NULL; } /* 802BDFA4-802BE078 .text syncAram__16JKRDvdAramRipperFP12JKRADCommandi */ bool JKRDvdAramRipper::syncAram(JKRADCommand* command, int param_1) { JKRDvdFile* dvdFile = command->mDvdFile; OSLockMutex(&dvdFile->mMutex2); if (command->mStreamCommand) { JKRAramStreamCommand* var1 = JKRAramStream::sync(command->mStreamCommand, param_1); command->field_0x44 = -(var1 == NULL); if (param_1 != 0 && var1 == NULL) { OSUnlockMutex(&dvdFile->mMutex2); return false; } } (*((JSUList*)&sDvdAramAsyncList)).remove(&command->mLink); if (command->mStreamCommand) { delete command->mStreamCommand; } delete dvdFile->mFileStream; dvdFile->field_0x50 = NULL; OSUnlockMutex(&dvdFile->mMutex2); return true; } /* 802BE078-802BE0B8 .text __ct__12JKRADCommandFv */ JKRADCommand::JKRADCommand() : mLink(this) { field_0x44 = 0; field_0x48 = false; } /* 802BE0B8-802BE144 .text __dt__12JKRADCommandFv */ JKRADCommand::~JKRADCommand() { if (field_0x48 == true) { delete mDvdFile; } } static OSMutex decompMutex; u32 JKRDvdAramRipper::sSzpBufferSize = 0x00000400; static u8* szpBuf; static u8* szpEnd; static u8* refBuf; static u8* refEnd; static u8* refCurrent; static u8* dmaBuf; static u8* dmaEnd; static u8* dmaCurrent; static u32 srcOffset; static u32 transLeft; static u8* srcLimit; static JKRDvdFile* srcFile; static u32 fileOffset; static int readCount; static u32 maxDest; static bool isInitMutex; /* 802BE144-802BE34C .text JKRDecompressFromDVDToAram__FP10JKRDvdFileUlUlUlUlUl */ static int JKRDecompressFromDVDToAram(JKRDvdFile* dvdFile, u32 param_1, u32 fileSize, u32 uncompressedSize, u32 param_4, u32 param_5) { BOOL level = OSDisableInterrupts(); if (!isInitMutex) { OSInitMutex(&decompMutex); isInitMutex = true; } OSRestoreInterrupts(level); OSLockMutex(&decompMutex); u32 bufferSize = JKRDvdAramRipper::getSzpBufferSize(); szpBuf = (u8*)JKRAllocFromSysHeap(bufferSize, 0x20); JUT_ASSERT(693, szpBuf != 0); szpEnd = szpBuf + bufferSize; refBuf = (u8*)JKRAllocFromSysHeap(0x1120, 0); JUT_ASSERT(701, refBuf != 0); refEnd = refBuf + 0x1120; refCurrent = refBuf; dmaBuf = (u8*)JKRAllocFromSysHeap(0x100, 0x20); JUT_ASSERT(710, dmaBuf != 0); dmaEnd = dmaBuf + 0x100; dmaCurrent = dmaBuf; srcFile = dvdFile; srcOffset = param_5; transLeft = fileSize - param_5; fileOffset = param_4; readCount = 0; maxDest = uncompressedSize; u8* first = firstSrcData(); int result = first ? decompSZS_subroutine(first, param_1) : -1; JKRHeap::free(szpBuf, 0); JKRHeap::free(refBuf, 0); JKRHeap::free(dmaBuf, 0); OSUnlockMutex(&decompMutex); return result; } /* 802BE34C-802BE5C0 .text decompSZS_subroutine__FPUcUl */ static int decompSZS_subroutine(u8* src, u32 dest) { u32 endAddr; s32 validBitCount = 0; u32 currCodeByte = 0; u32 startDest = dest; if (src[0] != 'Y' || src[1] != 'a' || src[2] != 'z' || src[3] != '0') { return -1; } SYaz0Header* header = (SYaz0Header*)src; endAddr = dest + (header->length - fileOffset); if (endAddr > dest + maxDest) { endAddr = dest + maxDest; } src += 0x10; do { if (validBitCount == 0) { if ((src > srcLimit) && transLeft) { src = nextSrcData(src); } currCodeByte = *src; validBitCount = 8; src++; } if (currCodeByte & 0x80) { if (readCount >= fileOffset) { *(dmaCurrent++) = *src; dest++; if (dmaCurrent == dmaEnd) { startDest += dmaBufferFlush(startDest); } if (dest == endAddr) { break; } } *(refCurrent++) = *src; if (refCurrent == refEnd) { refCurrent = refBuf; } readCount++; src++; } else { u32 dist = ((src[0] & 0x0f) << 8) | src[1]; s32 numBytes = src[0] >> 4; src += 2; u8* copySource = refCurrent - dist - 1; if (copySource < refBuf) { copySource += refEnd - refBuf; } if (numBytes == 0) { numBytes = *src + 0x12; src += 1; } else { numBytes += 2; } do { if (readCount >= fileOffset) { *(dmaCurrent++) = *copySource; dest++; if (dmaCurrent == dmaEnd) { startDest += dmaBufferFlush(startDest); } if (dest == endAddr) { break; } } *(refCurrent++) = *copySource; if (refCurrent == refEnd) { refCurrent = refBuf; } copySource++; if (copySource == refEnd) { copySource = refBuf; } readCount++; numBytes--; } while (numBytes != 0); } currCodeByte <<= 1; validBitCount--; } while (dest < endAddr); dmaBufferFlush(startDest); return 0; } /* 802BE5C0-802BE674 .text firstSrcData__Fv */ static u8* firstSrcData() { srcLimit = szpEnd - 0x19; u8* buffer = szpBuf; u32 bufSize = szpEnd - buffer; u32 length = transLeft < bufSize ? transLeft : bufSize; while (true) { int result = DVDReadPrio(&srcFile->mFileInfo, buffer, length, 0, 2); if (result >= 0) { break; } if (JKRDvdAramRipper::errorRetry == 0) { return NULL; } VIWaitForRetrace(); } srcOffset += length; transLeft -= length; return buffer; } /* 802BE674-802BE790 .text nextSrcData__FPUc */ static u8* nextSrcData(u8* src) { u32 size = szpEnd - src; u8* dest = IS_NOT_ALIGNED(size, 0x20) ? szpBuf + 0x20 - (size & (0x20 - 1)) : szpBuf; memcpy(dest, src, size); u32 transSize = szpEnd - (dest + size); if (transSize > transLeft) { transSize = transLeft; } JUT_ASSERT(966, transSize > 0); while (true) { s32 result = DVDReadPrio(&srcFile->mFileInfo, dest + size, transSize, srcOffset, 2); if (result >= 0) { break; } if (JKRDvdAramRipper::errorRetry == 0) { return NULL; } VIWaitForRetrace(); } srcOffset += transSize; transLeft -= transSize; if (transLeft == 0) { srcLimit = dest + size + transSize; } return dest; } /* 802BE790-802BE7F8 .text dmaBufferFlush__FUl */ static u32 dmaBufferFlush(u32 param_1) { if (dmaCurrent == dmaBuf) { return 0; } u32 size = ALIGN_NEXT(dmaCurrent - dmaBuf, 0x20); JKRAramPiece::orderSync(0, (u32)dmaBuf, param_1, size, NULL); dmaCurrent = dmaBuf; return size; }