mirror of
https://github.com/zeldaret/tww.git
synced 2026-08-21 14:07:29 -04:00
JKRDvdRipper
This commit is contained in:
+1
-1
@@ -777,7 +777,7 @@ config.libs = [
|
||||
Object(Matching, "JSystem/JKernel/JKRCompArchive.cpp"),
|
||||
Object(Matching, "JSystem/JKernel/JKRFile.cpp"),
|
||||
Object(NonMatching, "JSystem/JKernel/JKRDvdFile.cpp"),
|
||||
Object(NonMatching, "JSystem/JKernel/JKRDvdRipper.cpp"),
|
||||
Object(Matching, "JSystem/JKernel/JKRDvdRipper.cpp"),
|
||||
Object(NonMatching, "JSystem/JKernel/JKRDvdAramRipper.cpp"),
|
||||
Object(NonMatching, "JSystem/JKernel/JKRDecomp.cpp"),
|
||||
],
|
||||
|
||||
@@ -26,6 +26,7 @@ class JKRDvdRipper {
|
||||
public:
|
||||
static JSUList<JKRDMCommand> sDvdAsyncList;
|
||||
static u32 sSzpBufferSize;
|
||||
static bool errorRetry;
|
||||
|
||||
enum EAllocDirection {
|
||||
UNKNOWN_EALLOC_DIRECTION = 0,
|
||||
@@ -42,7 +43,7 @@ public:
|
||||
static void* loadToMainRAM(JKRDvdFile*, u8*, JKRExpandSwitch, u32, JKRHeap*, EAllocDirection,
|
||||
u32, int*);
|
||||
|
||||
static u8 isErrorRetry(void);
|
||||
static bool isErrorRetry(void) { return errorRetry; }
|
||||
inline static u32 getSzpBufferSize() { return sSzpBufferSize; }
|
||||
};
|
||||
|
||||
|
||||
@@ -4,49 +4,448 @@
|
||||
//
|
||||
|
||||
#include "JSystem/JKernel/JKRDvdRipper.h"
|
||||
#include "dolphin/types.h"
|
||||
#include "JSystem/JKernel/JKRDecomp.h"
|
||||
#include "JSystem/JKernel/JKRDvdFile.h"
|
||||
#include "JSystem/JUtility/JUTAssert.h"
|
||||
#include "MSL_C/string.h"
|
||||
#include "dolphin/os/OS.h"
|
||||
#include "dolphin/vi/vi.h"
|
||||
#include "global.h"
|
||||
|
||||
static int JKRDecompressFromDVD(JKRDvdFile*, void*, u32, u32, u32, u32);
|
||||
static int decompSZS_subroutine(u8*, u8*);
|
||||
static u8* firstSrcData();
|
||||
static u8* nextSrcData(u8*);
|
||||
|
||||
/* 802BCD4C-802BCE00 .text loadToMainRAM__12JKRDvdRipperFPCcPUc15JKRExpandSwitchUlP7JKRHeapQ212JKRDvdRipper15EAllocDirectionUlPi */
|
||||
void JKRDvdRipper::loadToMainRAM(const char*, unsigned char*, JKRExpandSwitch, unsigned long, JKRHeap*, JKRDvdRipper::EAllocDirection, unsigned long, int*) {
|
||||
/* Nonmatching */
|
||||
void* JKRDvdRipper::loadToMainRAM(const char* name, u8* dst, JKRExpandSwitch expandSwitch, u32 dstLength, JKRHeap* heap, EAllocDirection allocDirection, u32 offset, int* pCompression) {
|
||||
JKRDvdFile file;
|
||||
if (!file.open(name)) {
|
||||
return NULL;
|
||||
}
|
||||
return loadToMainRAM(&file, dst, expandSwitch, dstLength, heap, allocDirection, offset, pCompression);
|
||||
}
|
||||
|
||||
/* 802BCE00-802BCEB4 .text loadToMainRAM__12JKRDvdRipperFlPUc15JKRExpandSwitchUlP7JKRHeapQ212JKRDvdRipper15EAllocDirectionUlPi */
|
||||
void JKRDvdRipper::loadToMainRAM(long, unsigned char*, JKRExpandSwitch, unsigned long, JKRHeap*, JKRDvdRipper::EAllocDirection, unsigned long, int*) {
|
||||
/* Nonmatching */
|
||||
void* JKRDvdRipper::loadToMainRAM(s32 entryNumber, u8* dst, JKRExpandSwitch expandSwitch, u32 dstLength, JKRHeap* heap, EAllocDirection allocDirection, u32 offset, int* pCompression) {
|
||||
JKRDvdFile file;
|
||||
if (!file.open(entryNumber)) {
|
||||
return NULL;
|
||||
}
|
||||
return loadToMainRAM(&file, dst, expandSwitch, dstLength, heap, allocDirection, offset, pCompression);
|
||||
}
|
||||
|
||||
bool JKRDvdRipper::errorRetry = true;
|
||||
|
||||
/* 802BCEB4-802BD324 .text loadToMainRAM__12JKRDvdRipperFP10JKRDvdFilePUc15JKRExpandSwitchUlP7JKRHeapQ212JKRDvdRipper15EAllocDirectionUlPi */
|
||||
void JKRDvdRipper::loadToMainRAM(JKRDvdFile*, unsigned char*, JKRExpandSwitch, unsigned long, JKRHeap*, JKRDvdRipper::EAllocDirection, unsigned long, int*) {
|
||||
/* Nonmatching */
|
||||
void* JKRDvdRipper::loadToMainRAM(JKRDvdFile* dvdFile, u8* dst, JKRExpandSwitch expandSwitch, u32 dstLength, JKRHeap* heap, EAllocDirection allocDirection, u32 offset, int* pCompression) {
|
||||
s32 fileSizeAligned;
|
||||
bool hasAllocated = false;
|
||||
JKRCompression compression = COMPRESSION_NONE;
|
||||
u32 expandSize;
|
||||
u8 *mem = NULL;
|
||||
|
||||
fileSizeAligned = ALIGN_NEXT(dvdFile->getFileSize(), 32);
|
||||
if (expandSwitch == EXPAND_SWITCH_UNKNOWN1) {
|
||||
u8 buffer[0x40];
|
||||
u8 *bufPtr = (u8 *)ALIGN_NEXT((u32)buffer, 32);
|
||||
while (true) {
|
||||
int readBytes = DVDReadPrio(dvdFile->getFileInfo(), bufPtr, 0x20, 0, 2);
|
||||
if (readBytes >= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (readBytes == -3 || !isErrorRetry()) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
DCInvalidateRange(bufPtr, 0x20);
|
||||
|
||||
compression = JKRCheckCompressed(bufPtr);
|
||||
expandSize = JKRDecompExpandSize(bufPtr);
|
||||
}
|
||||
|
||||
if (pCompression) {
|
||||
*pCompression = (int)compression;
|
||||
}
|
||||
|
||||
if (expandSwitch == EXPAND_SWITCH_UNKNOWN1 && compression != COMPRESSION_NONE) {
|
||||
if (dstLength != 0 && expandSize > dstLength) {
|
||||
expandSize = dstLength;
|
||||
}
|
||||
if (dst == NULL) {
|
||||
dst = (u8 *)JKRAllocFromHeap(heap, expandSize, allocDirection == ALLOC_DIRECTION_FORWARD ? 32 : -32);
|
||||
hasAllocated = true;
|
||||
}
|
||||
if (dst == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (compression == COMPRESSION_YAY0) {
|
||||
mem = (u8 *)JKRAllocFromHeap((heap), fileSizeAligned, 32);
|
||||
if (mem == NULL) {
|
||||
if (hasAllocated == true) {
|
||||
i_JKRFree(dst);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (dst == NULL) {
|
||||
dst = (u8 *)JKRAllocFromHeap(heap, fileSizeAligned - offset, allocDirection == ALLOC_DIRECTION_FORWARD ? 32 : -32);
|
||||
hasAllocated = true;
|
||||
}
|
||||
if (dst == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (compression == COMPRESSION_NONE) {
|
||||
JKRCompression compression2 = COMPRESSION_NONE; // maybe for a sub archive?
|
||||
|
||||
if (offset != 0) {
|
||||
u8 buffer[0x40];
|
||||
u8 *bufPtr = (u8 *)ALIGN_NEXT((u32)buffer, 32);
|
||||
while (true) {
|
||||
int readBytes = DVDReadPrio(dvdFile->getFileInfo(), bufPtr, 32, (s32)offset, 2);
|
||||
if (readBytes >= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (readBytes == -3 || !isErrorRetry()) {
|
||||
if (hasAllocated == true) {
|
||||
i_JKRFree(dst);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
DCInvalidateRange(bufPtr, 32);
|
||||
|
||||
compression2 = JKRCheckCompressed(bufPtr);
|
||||
}
|
||||
if ((compression2 == COMPRESSION_NONE || expandSwitch == EXPAND_SWITCH_UNKNOWN2) || expandSwitch == EXPAND_SWITCH_UNKNOWN0) {
|
||||
s32 size = fileSizeAligned - offset;
|
||||
if (dstLength != 0 && dstLength < size)
|
||||
size = dstLength; // probably a ternary
|
||||
while (true) {
|
||||
int readBytes = DVDReadPrio(dvdFile->getFileInfo(), dst, size, (s32)offset, 2);
|
||||
if (readBytes >= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (readBytes == -3 || !isErrorRetry()) {
|
||||
if (hasAllocated == true) {
|
||||
i_JKRFree(dst);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
else if (compression2 == COMPRESSION_YAZ0) {
|
||||
JKRDecompressFromDVD(dvdFile, dst, fileSizeAligned, dstLength, 0, offset);
|
||||
} else {
|
||||
#if VERSION == VERSION_JPN
|
||||
OSPanic(__FILE__, 337, "Sorry, not prepared for SZP resource\n");
|
||||
#else
|
||||
OSPanic(__FILE__, 314, "Sorry, not prepared for SZP resource\n");
|
||||
#endif
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
else if (compression == COMPRESSION_YAY0)
|
||||
{
|
||||
// SZP decompression
|
||||
// s32 readoffset = startOffset;
|
||||
if (offset != 0) {
|
||||
#if VERSION == VERSION_JPN
|
||||
OSPanic(__FILE__, 347, ":::Not support SZP with offset read");
|
||||
#else
|
||||
OSPanic(__FILE__, 324, ":::Not support SZP with offset read");
|
||||
#endif
|
||||
}
|
||||
while (true) {
|
||||
int readBytes = DVDReadPrio(dvdFile->getFileInfo(), mem, fileSizeAligned, 0, 2);
|
||||
if (readBytes >= 0)
|
||||
break;
|
||||
|
||||
if (readBytes == -3 || !isErrorRetry()) {
|
||||
if (hasAllocated == true)
|
||||
i_JKRFree(dst);
|
||||
|
||||
i_JKRFree(mem);
|
||||
return NULL;
|
||||
}
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
JKRDecompress(mem, dst, expandSize, offset);
|
||||
i_JKRFree(mem);
|
||||
return dst;
|
||||
} else if (compression == COMPRESSION_YAZ0) {
|
||||
if (JKRDecompressFromDVD(dvdFile, dst, fileSizeAligned, expandSize, offset, 0) != 0u)
|
||||
{
|
||||
if (hasAllocated)
|
||||
i_JKRFree(dst);
|
||||
dst = NULL;
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
else if (hasAllocated)
|
||||
{
|
||||
i_JKRFree(dst);
|
||||
dst = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JSUList<JKRDMCommand> JKRDvdRipper::sDvdAsyncList;
|
||||
static OSMutex decompMutex;
|
||||
u32 JKRDvdRipper::sSzpBufferSize = 0x00000400;
|
||||
static u8* szpBuf;
|
||||
static u8* szpEnd;
|
||||
static u8* refBuf;
|
||||
static u8* refEnd;
|
||||
static u8* refCurrent;
|
||||
static u32 srcOffset;
|
||||
static u32 transLeft;
|
||||
static u8* srcLimit;
|
||||
static JKRDvdFile* srcFile;
|
||||
static u32 fileOffset;
|
||||
static u32 readCount;
|
||||
static u32 maxDest;
|
||||
static bool isInitMutex;
|
||||
|
||||
/* 802BD324-802BD4F0 .text JKRDecompressFromDVD__FP10JKRDvdFilePvUlUlUlUl */
|
||||
void JKRDecompressFromDVD(JKRDvdFile*, void*, unsigned long, unsigned long, unsigned long, unsigned long) {
|
||||
/* Nonmatching */
|
||||
static int JKRDecompressFromDVD(JKRDvdFile* dvdFile, void* dst, u32 fileSize, u32 inMaxDest, u32 inFileOffset, u32 inSrcOffset) {
|
||||
BOOL interrupts = OSDisableInterrupts();
|
||||
if (isInitMutex == false) {
|
||||
OSInitMutex(&decompMutex);
|
||||
isInitMutex = true;
|
||||
}
|
||||
OSRestoreInterrupts(interrupts);
|
||||
OSLockMutex(&decompMutex);
|
||||
int bufSize = JKRDvdRipper::getSzpBufferSize();
|
||||
szpBuf = (u8 *)JKRAllocFromSysHeap(bufSize, -0x20);
|
||||
#if VERSION == VERSION_JPN
|
||||
JUT_ASSERT(913, szpBuf != 0);
|
||||
#else
|
||||
JUT_ASSERT(884, szpBuf != 0);
|
||||
#endif
|
||||
|
||||
szpEnd = szpBuf + bufSize;
|
||||
if (inFileOffset != 0) {
|
||||
refBuf = (u8 *)JKRAllocFromSysHeap(0x1120, -4);
|
||||
#if VERSION == VERSION_JPN
|
||||
JUT_ASSERT(922, refBuf != 0);
|
||||
#else
|
||||
JUT_ASSERT(893, refBuf != 0);
|
||||
#endif
|
||||
refEnd = refBuf + 0x1120;
|
||||
refCurrent = refBuf;
|
||||
} else {
|
||||
refBuf = NULL;
|
||||
}
|
||||
srcFile = dvdFile;
|
||||
srcOffset = inSrcOffset;
|
||||
transLeft = fileSize - inSrcOffset;
|
||||
fileOffset = inFileOffset;
|
||||
readCount = 0;
|
||||
maxDest = inMaxDest;
|
||||
u8 *data = firstSrcData();
|
||||
u32 result = (data != NULL) ? decompSZS_subroutine(data, (u8 *)dst) : -1; // figure out correct datatypes
|
||||
u32 decompressedSize = ((u32*)data)[1];
|
||||
i_JKRFree(szpBuf);
|
||||
if (refBuf) {
|
||||
i_JKRFree(refBuf);
|
||||
}
|
||||
DCStoreRangeNoSync(dst, decompressedSize);
|
||||
OSUnlockMutex(&decompMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* 802BD4F0-802BD784 .text decompSZS_subroutine__FPUcPUc */
|
||||
void decompSZS_subroutine(unsigned char*, unsigned char*) {
|
||||
/* Nonmatching */
|
||||
static int decompSZS_subroutine(u8* src, u8* dest) {
|
||||
u8 *endPtr;
|
||||
s32 validBitCount = 0;
|
||||
s32 currCodeByte = 0;
|
||||
u32 ts = 0;
|
||||
|
||||
if (src[0] != 'Y' || src[1] != 'a' || src[2] != 'z' || src[3] != '0') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SYaz0Header *header = (SYaz0Header *)src;
|
||||
endPtr = dest + (header->length - fileOffset);
|
||||
if (endPtr > dest + maxDest) {
|
||||
endPtr = dest + maxDest;
|
||||
}
|
||||
|
||||
src += 0x10;
|
||||
do {
|
||||
if (validBitCount == 0) {
|
||||
if ((src > srcLimit) && transLeft) {
|
||||
src = nextSrcData(src);
|
||||
if (!src) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
currCodeByte = *src;
|
||||
validBitCount = 8;
|
||||
src++;
|
||||
}
|
||||
if (currCodeByte & 0x80) {
|
||||
if (fileOffset != 0) {
|
||||
if (readCount >= fileOffset) {
|
||||
*dest = *src;
|
||||
dest++;
|
||||
ts++;
|
||||
if (dest == endPtr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*(refCurrent++) = *src;
|
||||
if (refCurrent == refEnd) {
|
||||
refCurrent = refBuf;
|
||||
}
|
||||
src++;
|
||||
} else {
|
||||
*dest = *src;
|
||||
dest++;
|
||||
src++;
|
||||
ts++;
|
||||
if (dest == endPtr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
readCount++;
|
||||
} else {
|
||||
u32 dist = ((src[0] & 0x0f) << 8) | src[1];
|
||||
s32 numBytes = src[0] >> 4;
|
||||
src += 2;
|
||||
u8 *copySource;
|
||||
if (fileOffset != 0) {
|
||||
copySource = refCurrent - dist - 1;
|
||||
if (copySource < refBuf) {
|
||||
copySource += refEnd - refBuf;
|
||||
}
|
||||
} else {
|
||||
copySource = dest - dist - 1;
|
||||
}
|
||||
if (numBytes == 0) {
|
||||
numBytes = *src + 0x12;
|
||||
src += 1;
|
||||
} else {
|
||||
numBytes += 2;
|
||||
}
|
||||
if (fileOffset != 0) {
|
||||
do {
|
||||
if (readCount >= fileOffset) {
|
||||
*dest = *copySource;
|
||||
dest++;
|
||||
ts++;
|
||||
if (dest == endPtr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*(refCurrent++) = *copySource;
|
||||
if (refCurrent == refEnd) {
|
||||
refCurrent = refBuf;
|
||||
}
|
||||
copySource++;
|
||||
if (copySource == refEnd) {
|
||||
copySource = refBuf;
|
||||
}
|
||||
readCount++;
|
||||
numBytes--;
|
||||
} while (numBytes != 0);
|
||||
} else {
|
||||
do {
|
||||
*dest = *copySource;
|
||||
dest++;
|
||||
ts++;
|
||||
if (dest == endPtr) {
|
||||
break;
|
||||
}
|
||||
readCount++;
|
||||
numBytes--;
|
||||
copySource++;
|
||||
} while (numBytes != 0);
|
||||
}
|
||||
}
|
||||
currCodeByte <<= 1;
|
||||
validBitCount--;
|
||||
} while (dest < endPtr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 802BD784-802BD84C .text firstSrcData__Fv */
|
||||
void firstSrcData() {
|
||||
/* Nonmatching */
|
||||
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->getFileInfo(), buffer, length, srcOffset, 2);
|
||||
if (result >= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (result == -3 || !JKRDvdRipper::isErrorRetry()) {
|
||||
return NULL;
|
||||
}
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
|
||||
srcOffset += length;
|
||||
transLeft -= length;
|
||||
if (transLeft == 0) {
|
||||
srcLimit = buffer + length;
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* 802BD84C-802BD974 .text nextSrcData__FPUc */
|
||||
void nextSrcData(unsigned char*) {
|
||||
/* Nonmatching */
|
||||
}
|
||||
static u8* nextSrcData(u8* src) {
|
||||
u32 limit = szpEnd - src;
|
||||
u8 *buf;
|
||||
if (IS_NOT_ALIGNED(limit, 0x20)) {
|
||||
buf = szpBuf + 0x20 - (limit & (0x20 - 1));
|
||||
} else {
|
||||
buf = szpBuf;
|
||||
}
|
||||
|
||||
/* 802BD974-802BD97C .text isErrorRetry__12JKRDvdRipperFv */
|
||||
void JKRDvdRipper::isErrorRetry() {
|
||||
/* Nonmatching */
|
||||
}
|
||||
memcpy(buf, src, limit);
|
||||
u32 transSize = (u32)(szpEnd - (buf + limit));
|
||||
if (transSize > transLeft) {
|
||||
transSize = transLeft;
|
||||
}
|
||||
#if VERSION == VERSION_JPN
|
||||
JUT_ASSERT(1228, transSize > 0);
|
||||
#else
|
||||
JUT_ASSERT(1176, transSize > 0);
|
||||
#endif
|
||||
|
||||
/* 802BD9C0-802BDA14 .text __dt__23JSUList<12JKRDMCommand>Fv */
|
||||
JSUList<JKRDMCommand>::~JSUList() {
|
||||
/* Nonmatching */
|
||||
while (true) {
|
||||
s32 result = DVDReadPrio(srcFile->getFileInfo(), (buf + limit), transSize, srcOffset, 2);
|
||||
if (result >= 0) {
|
||||
break;
|
||||
}
|
||||
// bug: supposed to call isErrorRetry, but didn't
|
||||
if (result == -3 || !JKRDvdRipper::isErrorRetry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VIWaitForRetrace();
|
||||
}
|
||||
srcOffset += transSize;
|
||||
transLeft -= transSize;
|
||||
if (transLeft == 0) {
|
||||
srcLimit = transSize + (buf + limit);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user