switch to dtk setup (#2203)

* switch to dtk setup

* some cleanup / fixes

* cleanup d_a_alink literals

* Restore doxygen, update CI & README.md (#1)

* Fix build image ref (#2)

---------

Co-authored-by: Luke Street <luke@street.dev>
This commit is contained in:
TakaRikka
2024-10-10 07:29:58 -07:00
committed by GitHub
parent 2fd702c0ac
commit 12eb254d76
33438 changed files with 370506 additions and 3055930 deletions
+540
View File
@@ -0,0 +1,540 @@
#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JKernel/JKRAramPiece.h"
#include "JSystem/JKernel/JKRAramStream.h"
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JKernel/JKRExpHeap.h"
#include "JSystem/JUtility/JUTException.h"
#include "dolphin/ar.h"
#include "dolphin/os/OSCache.h"
#include "dolphin/os/OSInterrupt.h"
#include "string.h"
static u8* firstSrcData();
static u8* nextSrcData(u8* param_0);
static int JKRDecompressFromAramToMainRam(u32 src, void* dst, u32 srcLength, u32 dstLength,
u32 offset, u32* resourceSize);
int decompSZS_subroutine(u8* src, u8* dest);
/* 804513C8-804513CC 0008C8 0004+00 3/3 9/9 0/0 .sbss sAramObject__7JKRAram */
JKRAram* JKRAram::sAramObject;
/* 802D1FA4-802D2040 2CC8E4 009C+00 0/0 1/1 0/0 .text create__7JKRAramFUlUllll */
JKRAram* JKRAram::create(u32 aram_audio_buffer_size, u32 aram_audio_graph_size, s32 stream_priority,
s32 decomp_priority, s32 piece_priority) {
if (!sAramObject) {
sAramObject = new (JKRHeap::getSystemHeap(), 0)
JKRAram(aram_audio_buffer_size, aram_audio_graph_size, piece_priority);
}
JKRCreateAramStreamManager(stream_priority);
JKRCreateDecompManager(decomp_priority);
sAramObject->resume();
return sAramObject;
}
/* ############################################################################################## */
/* 803CC128-803CC138 029248 0010+00 1/1 0/0 0/0 .data sMessageBuffer__7JKRAram */
OSMessage JKRAram::sMessageBuffer[4] = {
NULL,
NULL,
NULL,
NULL,
};
/* 803CC138-803CC158 029258 0020+00 1/1 1/1 0/0 .data sMessageQueue__7JKRAram */
OSMessageQueue JKRAram::sMessageQueue = {0};
/* 802D2040-802D214C 2CC980 010C+00 1/1 0/0 0/0 .text __ct__7JKRAramFUlUll */
JKRAram::JKRAram(u32 audio_buffer_size, u32 audio_graph_size, s32 priority)
: JKRThread(0xC00, 0x10, priority) {
u32 aramBase = ARInit(mStackArray, ARRAY_SIZE(mStackArray));
ARQInit();
u32 aramSize = ARGetSize();
mAudioMemorySize = audio_buffer_size;
if (audio_graph_size == 0xFFFFFFFF) {
mGraphMemorySize = (aramSize - audio_buffer_size) - aramBase;
mAramMemorySize = 0;
} else {
mGraphMemorySize = audio_graph_size;
mAramMemorySize = (aramSize - (audio_buffer_size + audio_graph_size)) - aramBase;
}
mAudioMemoryPtr = ARAlloc(mAudioMemorySize);
mGraphMemoryPtr = ARAlloc(mGraphMemorySize);
if (mAramMemorySize) {
mAramMemoryPtr = ARAlloc(mAramMemorySize);
} else {
mAramMemoryPtr = NULL;
}
mAramHeap = new (JKRHeap::getSystemHeap(), 0) JKRAramHeap(mGraphMemoryPtr, mGraphMemorySize);
}
/* 802D214C-802D21DC 2CCA8C 0090+00 1/0 0/0 0/0 .text __dt__7JKRAramFv */
JKRAram::~JKRAram() {
sAramObject = NULL;
if (mAramHeap)
delete mAramHeap;
}
/* 802D21DC-802D2248 2CCB1C 006C+00 1/0 0/0 0/0 .text run__7JKRAramFv */
void* JKRAram::run(void) {
int result;
JKRAMCommand* command;
JKRAramPiece::Message* message;
OSInitMessageQueue(&sMessageQueue, sMessageBuffer, 4);
do {
OSReceiveMessage(&sMessageQueue, (OSMessage*)&message, OS_MESSAGE_BLOCK);
result = message->field_0x00;
command = message->command;
delete message;
switch (result) {
case 1:
JKRAramPiece::startDMA(command);
break;
}
} while (true);
}
/* 802D2248-802D22DC 2CCB88 0094+00 2/2 0/0 0/0 .text
* checkOkAddress__7JKRAramFPUcUlP12JKRAramBlockUl */
void JKRAram::checkOkAddress(u8* addr, u32 size, JKRAramBlock* block, u32 param_4) {
if (!IS_ALIGNED((u32)addr, 0x20) && !IS_ALIGNED(size, 0x20)) {
JUTException::panic(__FILE__, 219, ":::address not 32Byte aligned.");
}
if (block && !IS_ALIGNED((u32)block->getAddress() + param_4, 0x20)) {
JUTException::panic(__FILE__, 227, ":::address not 32Byte aligned.");
}
}
/* 802D22DC-802D233C 2CCC1C 0060+00 1/1 0/0 0/0 .text changeGroupIdIfNeed__7JKRAramFPUci
*/
void JKRAram::changeGroupIdIfNeed(u8* data, int groupId) {
JKRHeap* currentHeap = JKRHeap::getCurrentHeap();
if (currentHeap->getHeapType() == 'EXPH' && groupId >= 0) {
JKRExpHeap::CMemBlock* block = JKRExpHeap::CMemBlock::getBlock(data);
block->newGroupId(groupId);
}
}
/* 802D233C-802D25B4 2CCC7C 0278+00 0/0 3/3 0/0 .text
* mainRamToAram__7JKRAramFPUcUlUl15JKRExpandSwitchUlP7JKRHeapiPUl */
JKRAramBlock* JKRAram::mainRamToAram(u8* buf, u32 bufSize, u32 alignedSize,
JKRExpandSwitch expandSwitch, u32 fileSize, JKRHeap* heap,
int id, u32* pSize) {
JKRAramBlock* block = NULL;
checkOkAddress(buf, bufSize, NULL, 0);
if (expandSwitch == EXPAND_SWITCH_UNKNOWN1) {
expandSwitch = (JKRCheckCompressed_noASR(buf) == COMPRESSION_NONE) ?
EXPAND_SWITCH_UNKNOWN0 :
EXPAND_SWITCH_UNKNOWN1;
}
if (expandSwitch == EXPAND_SWITCH_UNKNOWN1) {
u32 expandSize = JKRDecompExpandSize(buf);
if (fileSize == 0 || fileSize > expandSize) {
fileSize = ALIGN_NEXT(expandSize, 32);
}
if (bufSize == 0) {
JKRAramBlock* allocatedBlock =
(JKRAramBlock*)JKRAllocFromAram(fileSize, JKRAramHeap::HEAD);
block = (JKRAramBlock*)allocatedBlock;
if (allocatedBlock == NULL)
return NULL;
allocatedBlock->newGroupID(decideAramGroupId(id));
bufSize = allocatedBlock->getAddress();
}
if (alignedSize == 0 || alignedSize > expandSize)
alignedSize = ALIGN_NEXT(expandSize, 32);
if (alignedSize > fileSize)
alignedSize = fileSize;
void* allocatedMem = JKRAllocFromHeap(heap, fileSize, -32);
if (allocatedMem == NULL) {
if (block != NULL) {
JKRFreeToAram(block);
}
block = NULL;
} else {
JKRDecompress(buf, (u8*)allocatedMem, fileSize, 0);
JKRAramPcs(0, (u32)allocatedMem, bufSize, alignedSize, block);
JKRFreeToHeap(heap, allocatedMem);
block = block == NULL ? (JKRAramBlock*)-1 : block;
if (pSize != NULL) {
*pSize = alignedSize;
}
}
} else {
if (fileSize != 0 && alignedSize > fileSize)
alignedSize = fileSize;
if (bufSize == 0) {
JKRAramBlock* allocatedBlock =
(JKRAramBlock*)JKRAllocFromAram(alignedSize, JKRAramHeap::HEAD);
block = allocatedBlock;
block->newGroupID(decideAramGroupId(id));
if (block == NULL)
return NULL;
bufSize = allocatedBlock->getAddress();
}
JKRAramPcs(0, (u32)buf, bufSize, alignedSize, block);
block = block == NULL ? (JKRAramBlock*)-1 : block;
if (pSize != NULL)
*pSize = alignedSize;
}
return block;
}
/* 802D25B4-802D2830 2CCEF4 027C+00 0/0 6/6 0/0 .text
* aramToMainRam__7JKRAramFUlPUcUl15JKRExpandSwitchUlP7JKRHeapiPUl */
u8* JKRAram::aramToMainRam(u32 address, u8* buf, u32 p3, JKRExpandSwitch expandSwitch, u32 p5,
JKRHeap* heap, int id, u32* pSize) {
JKRCompression compression = COMPRESSION_NONE;
if (pSize != NULL)
*pSize = 0;
checkOkAddress(buf, address, NULL, 0);
u32 expandSize;
if (expandSwitch == EXPAND_SWITCH_UNKNOWN1) {
u8 buffer[64];
u8* bufPtr = (u8*)ALIGN_NEXT((u32)buffer, 32);
JKRAramPcs(1, address, (u32)bufPtr, sizeof(buffer) / 2,
NULL); // probably change sizeof(buffer) / 2 to 32
compression = JKRCheckCompressed_noASR(bufPtr);
expandSize = JKRDecompExpandSize(bufPtr);
}
if (compression == COMPRESSION_YAZ0) { // SZS
if (p5 != 0 && p5 < expandSize)
expandSize = p5;
if (buf == NULL)
buf = (u8*)JKRAllocFromHeap(heap, expandSize, 32);
if (buf == NULL)
return NULL;
else {
changeGroupIdIfNeed(buf, id);
JKRDecompressFromAramToMainRam(address, buf, p3, expandSize, 0, pSize);
return buf;
}
} else if (compression == COMPRESSION_YAY0) { // SZP
u8* szpSpace = (u8*)JKRAllocFromHeap(heap, p3, -32);
if (szpSpace == NULL) {
return NULL;
} else {
JKRAramPcs(1, address, (u32)szpSpace, p3, NULL);
if (p5 != 0 && p5 < expandSize)
expandSize = p5;
u8* rv;
if (buf == NULL) {
rv = (u8*)JKRAllocFromHeap(heap, expandSize, 32);
} else {
rv = buf;
}
if (rv == NULL) {
JKRFree(szpSpace);
return NULL;
} else {
changeGroupIdIfNeed(rv, id);
JKRDecompress(szpSpace, rv, expandSize, 0);
JKRFreeToHeap(heap, szpSpace);
if (pSize != NULL) {
*pSize = expandSize;
}
return rv;
}
}
} else { // Not compressed or ASR
if (buf == NULL)
buf = (u8*)JKRAllocFromHeap(heap, p3, 32);
if (buf == NULL) {
return NULL;
} else {
changeGroupIdIfNeed(buf, id);
JKRAramPcs(1, address, (u32)buf, p3, NULL);
if (pSize != NULL) {
*pSize = p3;
}
return buf;
}
}
}
/* 804342DC-804342E8 060FFC 000C+00 1/1 0/0 0/0 .bss sAramCommandList__7JKRAram */
JSUList<JKRAMCommand> JKRAram::sAramCommandList;
/* 804342E8-80434300 061008 0018+00 1/1 0/0 0/0 .bss decompMutex */
static OSMutex decompMutex;
/* 804508B8-804508C0 000338 0004+04 1/1 1/1 0/0 .sdata sSZSBufferSize__7JKRAram */
u32 JKRAram::sSZSBufferSize = 0x00000400;
/* 804513CC-804513D0 0008CC 0004+00 3/3 0/0 0/0 .sbss szpBuf */
static u8* szpBuf;
/* 804513D0-804513D4 0008D0 0004+00 3/3 0/0 0/0 .sbss szpEnd */
static u8* szpEnd;
/* 804513D4-804513D8 0008D4 0004+00 2/2 0/0 0/0 .sbss refBuf */
static u8* refBuf;
/* 804513D8-804513DC 0008D8 0004+00 2/2 0/0 0/0 .sbss refEnd */
static u8* refEnd;
/* 804513DC-804513E0 0008DC 0004+00 2/2 0/0 0/0 .sbss refCurrent */
static u8* refCurrent;
/* 804513E0-804513E4 0008E0 0004+00 3/3 0/0 0/0 .sbss srcOffset */
static u32 srcOffset;
/* 804513E4-804513E8 0008E4 0004+00 4/4 0/0 0/0 .sbss transLeft */
static u32 transLeft;
/* 804513E8-804513EC 0008E8 0004+00 3/3 0/0 0/0 .sbss srcLimit */
static u8* srcLimit;
/* 804513EC-804513F0 0008EC 0004+00 3/3 0/0 0/0 .sbss srcAddress */
static u32 srcAddress;
/* 804513F0-804513F4 0008F0 0004+00 2/2 0/0 0/0 .sbss fileOffset */
static u32 fileOffset;
/* 804513F4-804513F8 0008F4 0004+00 2/2 0/0 0/0 .sbss readCount */
static u32 readCount;
/* 804513F8-804513FC 0008F8 0004+00 2/2 0/0 0/0 .sbss maxDest */
static u32 maxDest;
/* 804513FC-80451400 0008FC 0004+00 1/1 0/0 0/0 .sbss None */
static bool s_is_decompress_mutex_initialized;
/* 80451400-80451404 000900 0004+00 2/2 0/0 0/0 .sbss tsPtr */
static u32* tsPtr;
/* 80451404-80451408 000904 0004+00 1/1 0/0 0/0 .sbss tsArea */
static u32 tsArea;
/* 802D2830-802D29A0 2CD170 0170+00 1/1 0/0 0/0 .text
* JKRDecompressFromAramToMainRam__FUlPvUlUlUlPUl */
static int JKRDecompressFromAramToMainRam(u32 src, void* dst, u32 srcLength, u32 dstLength,
u32 offset, u32* resourceSize) {
BOOL interrupts = OSDisableInterrupts();
if (s_is_decompress_mutex_initialized == false) {
OSInitMutex(&decompMutex);
s_is_decompress_mutex_initialized = true;
}
OSRestoreInterrupts(interrupts);
OSLockMutex(&decompMutex);
u32 szsBufferSize = JKRAram::getSZSBufferSize();
szpBuf = (u8*)JKRAllocFromSysHeap(szsBufferSize, 32);
szpEnd = szpBuf + szsBufferSize;
if (offset != 0) {
refBuf = (u8*)JKRAllocFromSysHeap(0x1120, 0);
refEnd = refBuf + 0x1120;
refCurrent = refBuf;
} else {
refBuf = NULL;
}
srcAddress = src;
srcOffset = 0;
transLeft = (srcLength != 0) ? srcLength : -1;
fileOffset = offset;
readCount = 0;
maxDest = dstLength;
tsPtr = (resourceSize != 0) ? resourceSize : &tsArea;
*tsPtr = 0;
decompSZS_subroutine(firstSrcData(), (u8*)dst);
JKRFree(szpBuf);
if (refBuf) {
JKRFree(refBuf);
}
DCStoreRangeNoSync(dst, *tsPtr);
OSUnlockMutex(&decompMutex);
return 0;
}
/* 802D29A0-802D2C40 2CD2E0 02A0+00 1/1 0/0 0/0 .text decompSZS_subroutine__FPUcPUc */
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);
}
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);
*tsPtr = ts;
return 0;
}
/* 802D2C40-802D2CE4 2CD580 00A4+00 1/1 0/0 0/0 .text firstSrcData__Fv */
static u8* firstSrcData() {
srcLimit = szpEnd - 0x19;
u8* buffer = szpBuf;
u32 length;
u32 size = szpEnd - szpBuf;
if (transLeft < size) {
length = transLeft;
} else {
length = size;
}
u32 src = (u32)(srcAddress + srcOffset);
u32 dst = (u32)buffer;
u32 alignedLength = ALIGN_NEXT(length, 0x20);
JKRAramPcs(1, src, dst, alignedLength, NULL);
srcOffset += length;
transLeft -= length;
if (!transLeft) {
srcLimit = buffer + length;
}
return buffer;
}
/* 802D2CE4-802D2DAC 2CD624 00C8+00 1/1 0/0 0/0 .text nextSrcData__FPUc */
static u8* nextSrcData(u8* current) {
u8* dest;
u32 left = (u32)(szpEnd - current);
if (IS_NOT_ALIGNED(left, 0x20))
dest = szpBuf + 0x20 - (left & (0x20 - 1));
else
dest = szpBuf;
memcpy(dest, current, left);
u32 transSize = (u32)(szpEnd - (dest + left));
if (transSize > transLeft)
transSize = transLeft;
JKRAramPcs(1, (u32)(srcAddress + srcOffset), ((u32)dest + left), ALIGN_NEXT(transSize, 0x20),
NULL);
srcOffset += transSize;
transLeft -= transSize;
if (transLeft == 0)
srcLimit = (dest + left) + transSize;
return dest;
}
/* ############################################################################################## */
/* 8039D0A6-8039D0B8 029706 000E+04 0/0 0/0 0/0 .rodata None */
static const char* stringBase_8039D0A6 = "bad aramSync\n";
/* @stringBase0 padding */
static const char* pad_8039D0B4 = "\0\0\0";
+432
View File
@@ -0,0 +1,432 @@
//
// Generated By: dol2asm
// Translation Unit: JKRAramArchive
//
#include "JSystem/JKernel/JKRAramArchive.h"
#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JKernel/JKRDvdAramRipper.h"
#include "JSystem/JKernel/JKRDvdFile.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JUtility/JUTException.h"
#include "dol2asm.h"
#include "math.h"
#include "string.h"
//
// Forward References:
//
extern "C" void __ct__14JKRAramArchiveFlQ210JKRArchive15EMountDirection();
extern "C" void __dt__14JKRAramArchiveFv();
extern "C" void open__14JKRAramArchiveFl();
extern "C" void fetchResource__14JKRAramArchiveFPQ210JKRArchive12SDIFileEntryPUl();
extern "C" void fetchResource__14JKRAramArchiveFPvUlPQ210JKRArchive12SDIFileEntryPUl();
extern "C" void getAramAddress_Entry__14JKRAramArchiveFPQ210JKRArchive12SDIFileEntry();
extern "C" void getAramAddress__14JKRAramArchiveFPCc();
extern "C" void fetchResource_subroutine__14JKRAramArchiveFUlUlPUcUli();
extern "C" void fetchResource_subroutine__14JKRAramArchiveFUlUlP7JKRHeapiPPUc();
extern "C" void getExpandedResSize__14JKRAramArchiveCFPCv();
extern "C" void __dt__7JKRFileFv();
extern "C" extern char const* const JKRAramArchive__stringBase0;
//
// External References:
//
extern "C" void alloc__7JKRHeapFUliP7JKRHeap();
extern "C" void alloc__7JKRHeapFUli();
extern "C" void free__7JKRHeapFPvP7JKRHeap();
extern "C" void free__7JKRHeapFPv();
extern "C" void copyMemory__7JKRHeapFPvPvUl();
extern "C" void* __nw__FUlP7JKRHeapi();
extern "C" void __dl__FPv();
extern "C" void __dt__11JKRDisposerFv();
extern "C" void aramToMainRam__7JKRAramFUlPUcUl15JKRExpandSwitchUlP7JKRHeapiPUl();
extern "C" void alloc__11JKRAramHeapFUlQ211JKRAramHeap10EAllocMode();
extern "C" void unmount__13JKRFileLoaderFv();
extern "C" void becomeCurrent__10JKRArchiveFPCc();
extern "C" void getResource__10JKRArchiveFPCc();
extern "C" void getResource__10JKRArchiveFUlPCc();
extern "C" void readResource__10JKRArchiveFPvUlUlPCc();
extern "C" void readResource__10JKRArchiveFPvUlPCc();
extern "C" void removeResourceAll__10JKRArchiveFv();
extern "C" void removeResource__10JKRArchiveFPv();
extern "C" void detachResource__10JKRArchiveFPv();
extern "C" void getResSize__10JKRArchiveCFPCv();
extern "C" void countFile__10JKRArchiveCFPCc();
extern "C" void getFirstFile__10JKRArchiveCFPCc();
extern "C" void __ct__10JKRArchiveFlQ210JKRArchive10EMountMode();
extern "C" void __dt__10JKRArchiveFv();
extern "C" void findFsResource__10JKRArchiveCFPCcUl();
extern "C" void findPtrResource__10JKRArchiveCFPCv();
extern "C" void setExpandSize__10JKRArchiveFPQ210JKRArchive12SDIFileEntryUl();
extern "C" void getExpandSize__10JKRArchiveCFPQ210JKRArchive12SDIFileEntry();
extern "C" void __ct__10JKRDvdFileFl();
extern "C" void
loadToMainRAM__12JKRDvdRipperFlPUc15JKRExpandSwitchUlP7JKRHeapQ212JKRDvdRipper15EAllocDirectionUlPiPUl();
extern "C" void loadToAram__16JKRDvdAramRipperFlUl15JKRExpandSwitchUlUlPUl();
extern "C" void prepend__10JSUPtrListFP10JSUPtrLink();
extern "C" void remove__10JSUPtrListFP10JSUPtrLink();
extern "C" void panic_f__12JUTExceptionFPCciPCce();
extern "C" void _savegpr_26();
extern "C" void _savegpr_27();
extern "C" void _savegpr_28();
extern "C" void _savegpr_29();
extern "C" void _restgpr_26();
extern "C" void _restgpr_27();
extern "C" void _restgpr_28();
extern "C" void _restgpr_29();
extern "C" u8 sVolumeList__13JKRFileLoader[12];
extern "C" u8 sSystemHeap__7JKRHeap[4];
extern "C" u8 sAramObject__7JKRAram[4];
//
// Declarations:
//
/* ############################################################################################## */
/* 803CC328-803CC348 029448 0020+00 1/1 4/4 0/0 .data __vt__7JKRFile */
SECTION_DATA extern void* __vt__7JKRFile[8] = {
(void*)NULL /* RTTI */,
(void*)NULL,
(void*)__dt__7JKRFileFv,
(void*)NULL,
(void*)NULL,
(void*)NULL,
(void*)NULL,
(void*)NULL,
};
/* 802D70C0-802D7168 2D1A00 00A8+00 0/0 1/1 0/0 .text
* __ct__14JKRAramArchiveFlQ210JKRArchive15EMountDirection */
JKRAramArchive::JKRAramArchive(s32 entryNumber, JKRArchive::EMountDirection mountDirection)
: JKRArchive(entryNumber, MOUNT_ARAM) {
mMountDirection = mountDirection;
if (!this->open(entryNumber)) {
return;
}
mVolumeType = 'RARC';
mVolumeName = mStringTable + mNodes->name_offset;
JKRFileLoader::sVolumeList.prepend(&mFileLoaderLink);
mIsMounted = true;
}
/* 802D7168-802D72A8 2D1AA8 0140+00 1/0 0/0 0/0 .text __dt__14JKRAramArchiveFv */
JKRAramArchive::~JKRAramArchive() {
if (mIsMounted == true) {
if (mArcInfoBlock != NULL) {
SDIFileEntry* entry = mFiles;
for (int i = 0; i < mArcInfoBlock->num_file_entries; entry++, i++) {
if (entry->data != NULL) {
JKRFreeToHeap(mHeap, entry->data);
}
}
JKRFreeToHeap(mHeap, mArcInfoBlock);
mArcInfoBlock = NULL;
}
if (mExpandedSize != NULL) {
JKRFree(mExpandedSize);
mExpandedSize = NULL;
}
if (mDvdFile != NULL) {
delete mDvdFile;
}
if (mBlock != NULL) {
delete mBlock;
}
JKRFileLoader::sVolumeList.remove(&mFileLoaderLink);
mIsMounted = false;
}
}
inline u32 alignNext(u32 var, u32 align) {
return (var + align - 1) & ~(align - 1);
}
/* 802D72A8-802D75E0 2D1BE8 0338+00 1/1 0/0 0/0 .text open__14JKRAramArchiveFl */
bool JKRAramArchive::open(s32 entryNum) {
mArcInfoBlock = NULL;
mNodes = NULL;
mFiles = NULL;
mStringTable = NULL;
mBlock = NULL;
mDvdFile = new (JKRGetSystemHeap(), mMountDirection == MOUNT_DIRECTION_HEAD ? 4 : -4)
JKRDvdFile(entryNum);
if (mDvdFile == NULL) {
mMountMode = 0;
return 0;
}
// NOTE: a different struct is used here for sure, unfortunately i can't get any hits on this
// address, so gonna leave it like this for now
SArcHeader* mem = (SArcHeader*)JKRAllocFromSysHeap(32, -32);
if (mem == NULL) {
mMountMode = 0;
} else {
JKRDvdToMainRam(entryNum, (u8*)mem, EXPAND_SWITCH_UNKNOWN1, 32, NULL,
JKRDvdRipper::ALLOC_DIRECTION_FORWARD, 0, &mCompression, NULL);
DCInvalidateRange(mem, 32);
int alignment = mMountDirection == MOUNT_DIRECTION_HEAD ? 32 : -32;
u32 alignedSize = ALIGN_NEXT(mem->file_data_offset, 32);
mArcInfoBlock = (SArcDataInfo*)JKRAllocFromHeap(mHeap, alignedSize, alignment);
if (mArcInfoBlock == NULL) {
mMountMode = 0;
} else {
JKRDvdToMainRam(entryNum, (u8*)mArcInfoBlock, EXPAND_SWITCH_UNKNOWN1, alignedSize, NULL,
JKRDvdRipper::ALLOC_DIRECTION_FORWARD, 32, NULL, NULL);
DCInvalidateRange(mArcInfoBlock, alignedSize);
mNodes = (SDIDirEntry*)((u8*)mArcInfoBlock + mArcInfoBlock->node_offset);
mFiles = (SDIFileEntry*)((u8*)mArcInfoBlock + mArcInfoBlock->file_entry_offset);
mStringTable = (char*)((u8*)mArcInfoBlock + mArcInfoBlock->string_table_offset);
mExpandedSize = NULL;
u8 compressedFiles = 0; // maybe a check for if the last file is compressed?
SDIFileEntry* fileEntry = mFiles;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
u8 flag = fileEntry->type_flags_and_name_offset >> 24;
if ((flag & 1)) {
compressedFiles |= (flag & JKRARCHIVE_ATTR_COMPRESSION);
}
fileEntry++;
}
if (compressedFiles != 0) {
mExpandedSize = (s32*)JKRAllocFromHeap(mHeap, mArcInfoBlock->num_file_entries << 2,
abs(alignment));
if (mExpandedSize == NULL) {
JKRFree(mArcInfoBlock);
mMountMode = 0;
goto cleanup;
}
memset(mExpandedSize, 0, mArcInfoBlock->num_file_entries << 2);
}
u32 aramSize = ALIGN_NEXT(mem->file_data_length, 32);
mBlock = (JKRAramBlock*)JKRAllocFromAram(
aramSize,
mMountDirection == MOUNT_DIRECTION_HEAD ? JKRAramHeap::HEAD : JKRAramHeap::TAIL);
if (mBlock == NULL) {
if (mArcInfoBlock) {
JKRFree(mArcInfoBlock);
}
if (mExpandedSize) {
JKRFree(mExpandedSize);
}
mMountMode = 0;
} else {
JKRDvdToAram(entryNum, mBlock->getAddress(), EXPAND_SWITCH_UNKNOWN1,
mem->header_length + mem->file_data_offset, 0, NULL);
}
}
}
cleanup:
if (mem != NULL) {
JKRFreeToSysHeap(mem);
}
if (mMountMode == 0) {
#ifdef DEBUG
OSReport(":::[%s: %d] Cannot alloc memory\n", __FILE__, 415);
#endif
if (mDvdFile != NULL) {
delete mDvdFile;
}
return false;
}
return true;
}
/* 802D75E0-802D76F4 2D1F20 0114+00 1/0 0/0 0/0 .text
* fetchResource__14JKRAramArchiveFPQ210JKRArchive12SDIFileEntryPUl */
void* JKRAramArchive::fetchResource(SDIFileEntry* pEntry, u32* pOutSize) {
JUT_ASSERT(442, isMounted());
u32 outSize;
u8* outBuf;
if (pOutSize == NULL) {
pOutSize = &outSize;
}
JKRCompression compression = JKRConvertAttrToCompressionType(pEntry->getFlags());
if (pEntry->data == NULL) {
u32 size = JKRAramArchive::fetchResource_subroutine(
pEntry->data_offset + mBlock->getAddress(), pEntry->data_size, mHeap, compression,
&outBuf);
*pOutSize = size;
if (size == NULL) {
return NULL;
}
pEntry->data = outBuf;
if (compression == COMPRESSION_YAZ0) {
this->setExpandSize(pEntry, *pOutSize);
}
} else {
if (compression == COMPRESSION_YAZ0) {
*pOutSize = this->getExpandSize(pEntry);
} else {
*pOutSize = pEntry->data_size;
}
}
return pEntry->data;
}
/* 802D76F4-802D77F8 2D2034 0104+00 1/0 0/0 0/0 .text
* fetchResource__14JKRAramArchiveFPvUlPQ210JKRArchive12SDIFileEntryPUl */
void* JKRAramArchive::fetchResource(void* buffer, u32 bufferSize, SDIFileEntry* pEntry,
u32* resourceSize) {
JUT_ASSERT(515, isMounted());
u32 size = pEntry->data_size;
if (size > bufferSize) {
size = bufferSize;
}
JKRCompression compression = JKRConvertAttrToCompressionType(pEntry->getFlags());
if (pEntry->data == NULL) {
bufferSize = (s32)ALIGN_PREV(bufferSize, 0x20);
size = JKRAramArchive::fetchResource_subroutine(pEntry->data_offset + mBlock->getAddress(),
size, (u8*)buffer, bufferSize, compression);
} else {
if (compression == COMPRESSION_YAZ0) {
u32 expandSize = this->getExpandSize(pEntry);
if (expandSize != NULL) {
size = expandSize;
}
}
if (size > bufferSize) {
size = bufferSize;
}
JKRHeap::copyMemory(buffer, pEntry->data, size);
}
if (resourceSize != NULL) {
*resourceSize = size;
}
return buffer;
}
/* 802D77F8-802D781C 2D2138 0024+00 1/1 0/0 0/0 .text
* getAramAddress_Entry__14JKRAramArchiveFPQ210JKRArchive12SDIFileEntry */
u32 JKRAramArchive::getAramAddress_Entry(SDIFileEntry* pEntry) {
JUT_ASSERT(572, isMounted());
if (pEntry == NULL) {
return 0;
} else {
return pEntry->data_offset + mBlock->getAddress();
}
}
/* 802D781C-802D7858 2D215C 003C+00 0/0 1/1 0/0 .text getAramAddress__14JKRAramArchiveFPCc */
u32 JKRAramArchive::getAramAddress(char const* name) {
return JKRAramArchive::getAramAddress_Entry(this->findFsResource(name, 0));
}
/* 802D7858-802D7914 2D2198 00BC+00 1/1 1/1 0/0 .text
* fetchResource_subroutine__14JKRAramArchiveFUlUlPUcUli */
u32 JKRAramArchive::fetchResource_subroutine(u32 srcAram, u32 srcLength, u8* dst, u32 dstLength,
int compression) {
JUT_ASSERT(628, (srcAram & 0x1f) == 0);
u32 outLen;
u32 srcSize = ALIGN_NEXT(srcLength, 0x20);
u32 dstSize = ALIGN_PREV(dstLength, 0x20);
switch (compression) {
case COMPRESSION_NONE:
if (srcSize > dstSize) {
srcSize = dstSize;
}
JKRAramToMainRam(srcAram, dst, srcSize, EXPAND_SWITCH_UNKNOWN0, dstSize, NULL, -1, &outLen);
return outLen;
case COMPRESSION_YAY0:
case COMPRESSION_YAZ0:
JKRAramToMainRam(srcAram, dst, srcSize, EXPAND_SWITCH_UNKNOWN1, dstSize, NULL, -1, &outLen);
return outLen;
default:
JUTException::panic(__FILE__, 655, "??? bad sequence\n");
return 0;
}
}
/* 802D7914-802D7A64 2D2254 0150+00 1/1 1/1 0/0 .text
* fetchResource_subroutine__14JKRAramArchiveFUlUlP7JKRHeapiPPUc */
u32 JKRAramArchive::fetchResource_subroutine(u32 entryNum, u32 length, JKRHeap* pHeap,
int compression, u8** out) {
u32 alignedLen = ALIGN_NEXT(length, 0x20);
u8* buffer;
switch (compression) {
case COMPRESSION_NONE:
{
buffer = (u8*)(JKRAllocFromHeap(pHeap, alignedLen, 0x20));
JUT_ASSERT(677, buffer != 0);
JKRAramToMainRam(entryNum, buffer, alignedLen, EXPAND_SWITCH_UNKNOWN0, alignedLen, NULL, -1, NULL);
*out = buffer;
return length;
}
case COMPRESSION_YAY0:
case COMPRESSION_YAZ0:
{
u8 headerBuf[0x40];
u8* alignHeader = (u8*)ALIGN_NEXT((s32)&headerBuf[0], sizeof(SArcHeader));
JKRAramToMainRam(entryNum, alignHeader, sizeof(SArcHeader), EXPAND_SWITCH_UNKNOWN0, 0, NULL, -1, NULL);
u32 decompressedLen = ALIGN_NEXT(JKRDecompExpandSize(alignHeader), sizeof(SArcHeader));
buffer = (u8*)(JKRAllocFromHeap(pHeap, decompressedLen, sizeof(SArcHeader)));
JUT_ASSERT(703, buffer);
u32 readLen;
JKRAramToMainRam(entryNum, buffer, alignedLen, EXPAND_SWITCH_UNKNOWN1, decompressedLen, pHeap, -1, &readLen);
*out = buffer;
return readLen;
}
default:
JUTException::panic(__FILE__, 713, "??? bad sequence\n");
return 0;
}
}
/* 802D7A64-802D7B90 2D23A4 012C+00 1/0 0/0 0/0 .text getExpandedResSize__14JKRAramArchiveCFPCv */
u32 JKRAramArchive::getExpandedResSize(const void* ptr) const {
if (mExpandedSize == NULL) {
return this->getResSize(ptr);
}
JKRArchive::SDIFileEntry* entry = this->findPtrResource(ptr);
if (entry == NULL) {
return 0xFFFFFFFF;
}
if (entry->getCompressFlag() == 0) {
return this->getResSize(ptr);
}
u32 expandSize = this->getExpandSize(entry);
if (expandSize != 0) {
return expandSize;
}
u8 tmpBuf[0x40];
u8* buf = (u8*)ALIGN_PREV((s32)&tmpBuf[0x1F], 0x20);
JKRAramToMainRam(entry->data_offset + mBlock->getAddress(), buf, 0x20, EXPAND_SWITCH_UNKNOWN0,
0, NULL, -1, NULL);
expandSize = JKRDecompExpandSize(buf);
// ??? casting away const?
((JKRArchive*)this)->setExpandSize(entry, expandSize);
return expandSize;
}
/* 802D7B90-802D7BF0 2D24D0 0060+00 1/0 0/0 0/0 .text __dt__7JKRFileFv */
// JKRFile::~JKRFile() {
extern "C" void __dt__7JKRFileFv() {
// NONMATCHING
}
+66
View File
@@ -0,0 +1,66 @@
#include "JSystem/JKernel/JKRAramBlock.h"
#include "JSystem/JKernel/JKRAramHeap.h"
#include "JSystem/JKernel/JKRHeap.h"
/* 802D3304-802D3378 2CDC44 0074+00 2/2 1/1 0/0 .text __ct__12JKRAramBlockFUlUlUlUcb */
JKRAramBlock::JKRAramBlock(u32 address, u32 size, u32 freeSize, u8 groupId, bool isTempMemory)
: mBlockLink(this) {
mAddress = address;
mSize = size;
mFreeSize = freeSize;
mGroupId = groupId;
mIsTempMemory = isTempMemory;
}
/* 802D3378-802D3434 2CDCB8 00BC+00 1/0 0/0 0/0 .text __dt__12JKRAramBlockFv */
JKRAramBlock::~JKRAramBlock() {
JSUList<JKRAramBlock>* list = mBlockLink.getSupervisor();
JSULink<JKRAramBlock>* prev = mBlockLink.getPrev();
if (prev) {
JKRAramBlock* block = prev->getObject();
block->mFreeSize = mSize + mFreeSize + block->mFreeSize;
list->remove(&mBlockLink);
} else {
mFreeSize = mFreeSize + mSize;
mSize = 0;
}
}
/* 802D3434-802D34D0 2CDD74 009C+00 0/0 1/1 0/0 .text allocHead__12JKRAramBlockFUlUcP11JKRAramHeap
*/
JKRAramBlock* JKRAramBlock::allocHead(u32 size, u8 groupId, JKRAramHeap* aramHeap) {
u32 address = mAddress;
u32 usedSize = mSize;
u32 nextAddress = address + usedSize;
u32 freeSize = mFreeSize;
u32 nextFreeSize = freeSize - size;
JKRAramBlock* block = new (aramHeap->getMgrHeap(), 0)
JKRAramBlock(nextAddress, size, nextFreeSize, groupId, false);
mFreeSize = 0;
JSULink<JKRAramBlock>* next = mBlockLink.getNext();
JSUList<JKRAramBlock>* list = mBlockLink.getSupervisor();
list->insert(next, &block->mBlockLink);
return block;
}
/* 802D34D0-802D3574 2CDE10 00A4+00 0/0 1/1 0/0 .text allocTail__12JKRAramBlockFUlUcP11JKRAramHeap
*/
JKRAramBlock* JKRAramBlock::allocTail(u32 size, u8 groupId, JKRAramHeap* aramHeap) {
u32 freeSize = mFreeSize;
u32 address = mAddress;
u32 usedSize = mSize;
u32 endAddress = address + usedSize + freeSize;
u32 tailAddress = endAddress - size;
JKRAramBlock* block =
new (aramHeap->getMgrHeap(), 0) JKRAramBlock(tailAddress, size, 0, groupId, true);
mFreeSize -= size;
JSULink<JKRAramBlock>* next = mBlockLink.getNext();
JSUList<JKRAramBlock>* list = mBlockLink.getSupervisor();
list->insert(next, &block->mBlockLink);
return block;
}
+142
View File
@@ -0,0 +1,142 @@
#include "JSystem/JKernel/JKRAramHeap.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "global.h"
/* 8043430C-80434318 06102C 000C+00 8/8 0/0 0/0 .bss sAramList__11JKRAramHeap */
JSUList<JKRAramBlock> JKRAramHeap::sAramList;
/* 802D2E44-802D2F14 2CD784 00D0+00 0/0 1/1 0/0 .text __ct__11JKRAramHeapFUlUl */
JKRAramHeap::JKRAramHeap(u32 startAddress, u32 size) {
OSInitMutex(&mMutex);
mHeap = JKRHeap::findFromRoot(this);
mSize = ALIGN_PREV(size, 0x20);
mHeadAddress = ALIGN_NEXT(startAddress, 0x20);
mTailAddress = mHeadAddress + mSize;
mGroupId = -1;
JKRAramBlock* block = new (mHeap, 0) JKRAramBlock(mHeadAddress, 0, mSize, -1, false);
sAramList.append(&block->mBlockLink);
}
/* 802D2F14-802D2FBC 2CD854 00A8+00 1/0 0/0 0/0 .text __dt__11JKRAramHeapFv */
JKRAramHeap::~JKRAramHeap() {
JSUListIterator<JKRAramBlock> iterator(sAramList.getFirst());
while (iterator != sAramList.getEnd())
{
delete (iterator++).getObject();
}
}
/* 802D2FBC-802D3034 2CD8FC 0078+00 0/0 5/5 0/0 .text
* alloc__11JKRAramHeapFUlQ211JKRAramHeap10EAllocMode */
JKRAramBlock* JKRAramHeap::alloc(u32 size, JKRAramHeap::EAllocMode allocationMode) {
lock();
JKRAramBlock* block;
if (allocationMode == JKRAramHeap::HEAD) {
block = allocFromHead(size);
} else {
block = allocFromTail(size);
}
unlock();
return block;
}
/* 802D3034-802D30BC 2CD974 0088+00 1/1 0/0 0/0 .text allocFromHead__11JKRAramHeapFUl */
JKRAramBlock* JKRAramHeap::allocFromHead(u32 size) {
u32 alignedSize = ALIGN_NEXT(size, 0x20);
u32 bestFreeSize = UINT32_MAX;
JKRAramBlock* bestBlock = NULL;
JSUList<JKRAramBlock>* list = &sAramList;
for (JSUListIterator<JKRAramBlock> iterator = list; iterator != list->getEnd(); ++iterator) {
JKRAramBlock* block = iterator.getObject();
if (block->mFreeSize < alignedSize)
continue;
if (bestFreeSize <= block->mFreeSize)
continue;
bestFreeSize = block->mFreeSize;
bestBlock = block;
if (block->mFreeSize == alignedSize) {
break;
}
}
if (bestBlock) {
return bestBlock->allocHead(alignedSize, mGroupId, this);
}
return NULL;
}
/* 802D30BC-802D3134 2CD9FC 0078+00 1/1 0/0 0/0 .text allocFromTail__11JKRAramHeapFUl */
JKRAramBlock* JKRAramHeap::allocFromTail(u32 size) {
u32 alignedSize = ALIGN_NEXT(size, 0x20);
JKRAramBlock* tailBlock = NULL;
JSUList<JKRAramBlock>* list = &sAramList;
JSUListIterator<JKRAramBlock> iterator = list->getLast();
for (; iterator != list->getEnd(); --iterator) {
JKRAramBlock* block = iterator.getObject();
if (block->mFreeSize >= alignedSize) {
tailBlock = block;
break;
}
}
if (tailBlock) {
return tailBlock->allocTail(alignedSize, mGroupId, this);
}
return NULL;
}
/* 802D3134-802D31AC 2CDA74 0078+00 0/0 1/1 0/0 .text getFreeSize__11JKRAramHeapFv */
u32 JKRAramHeap::getFreeSize(void) {
u32 maxFreeSize = 0;
lock();
JSUList<JKRAramBlock>* list = &sAramList;
JSUListIterator<JKRAramBlock> iterator = list;
for (; iterator != list->getEnd(); ++iterator) {
if (iterator->mFreeSize > maxFreeSize) {
maxFreeSize = iterator->mFreeSize;
}
}
unlock();
return maxFreeSize;
}
/* 802D31AC-802D3218 2CDAEC 006C+00 0/0 2/2 0/0 .text getTotalFreeSize__11JKRAramHeapFv
*/
u32 JKRAramHeap::getTotalFreeSize(void) {
u32 totalFreeSize = 0;
lock();
JSUList<JKRAramBlock>* list = &sAramList;
JSUListIterator<JKRAramBlock> iterator = list;
for (; iterator != list->getEnd(); ++iterator) {
totalFreeSize += iterator->mFreeSize;
}
unlock();
return totalFreeSize;
}
/* 802D3218-802D326C 2CDB58 0054+00 0/0 2/2 0/0 .text dump__11JKRAramHeapFv */
void JKRAramHeap::dump(void) {
lock();
JSUList<JKRAramBlock>* list = &sAramList;
JSUListIterator<JKRAramBlock> iterator = list;
for (; iterator != list->getEnd(); ++iterator) {}
unlock();
}
+157
View File
@@ -0,0 +1,157 @@
#include "JSystem/JKernel/JKRAramPiece.h"
#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JUtility/JUTException.h"
#include "dolphin/os.h"
/* 802D3574-802D35F4 2CDEB4 0080+00 1/1 0/0 0/0 .text
* prepareCommand__12JKRAramPieceFiUlUlUlP12JKRAramBlockPFUl_v */
JKRAMCommand* JKRAramPiece::prepareCommand(int direction, u32 src, u32 dst, u32 length,
JKRAramBlock* block,
JKRAMCommand::AsyncCallback callback) {
JKRAMCommand* command = new (JKRHeap::getSystemHeap(), -4) JKRAMCommand();
command->mTransferDirection = direction;
command->mSrc = src;
command->mDst = dst;
command->mAramBlock = block;
command->mDataLength = length;
command->mCallback = callback;
return command;
}
/* 802D35F4-802D3614 2CDF34 0020+00 0/0 1/1 0/0 .text sendCommand__12JKRAramPieceFP12JKRAMCommand
*/
void JKRAramPiece::sendCommand(JKRAMCommand* command) {
startDMA(command);
}
/* 80434324-80434330 061044 000C+00 3/3 0/0 0/0 .bss sAramPieceCommandList__12JKRAramPiece */
// JSUList<JKRAMCommand> JKRAramPiece::sAramPieceCommandList;
JSUList<JKRAMCommand> JKRAramPiece::sAramPieceCommandList;
/* 80434330-80434348 061050 0018+00 3/3 0/0 0/0 .bss mMutex__12JKRAramPiece */
OSMutex JKRAramPiece::mMutex;
/* 802D3614-802D3770 2CDF54 015C+00 1/1 0/0 0/0 .text
* orderAsync__12JKRAramPieceFiUlUlUlP12JKRAramBlockPFUl_v */
JKRAMCommand* JKRAramPiece::orderAsync(int direction, u32 source, u32 destination, u32 length,
JKRAramBlock* block, JKRAMCommand::AsyncCallback callback) {
lock();
if ((source & 0x1f) != 0 || (destination & 0x1f) != 0) {
OSReport("direction = %x\n", direction);
OSReport("source = %x\n", source);
OSReport("destination = %x\n", destination);
OSReport("length = %x\n", length);
JUTException::panic(__FILE__, 108, "illegal address. abort.");
}
Message* message = new (JKRHeap::getSystemHeap(), -4) Message();
JKRAMCommand* command =
JKRAramPiece::prepareCommand(direction, source, destination, length, block, callback);
message->field_0x00 = 1;
message->command = command;
OSSendMessage(&JKRAram::sMessageQueue, message, OS_MESSAGE_BLOCK);
if (command->mCallback != NULL) {
sAramPieceCommandList.append(&command->mPieceLink);
}
unlock();
return command;
}
/* 802D3770-802D3838 2CE0B0 00C8+00 1/1 0/0 0/0 .text sync__12JKRAramPieceFP12JKRAMCommandi */
BOOL JKRAramPiece::sync(JKRAMCommand* command, int is_non_blocking) {
OSMessage message;
lock();
if (is_non_blocking == 0) {
OSReceiveMessage(&command->mMessageQueue, &message, OS_MESSAGE_BLOCK);
sAramPieceCommandList.remove(&command->mPieceLink);
unlock();
return TRUE;
}
BOOL result = OSReceiveMessage(&command->mMessageQueue, &message, OS_MESSAGE_NOBLOCK);
if (!result) {
unlock();
return FALSE;
}
sAramPieceCommandList.remove(&command->mPieceLink);
unlock();
return TRUE;
}
/* 802D3838-802D38CC 2CE178 0094+00 0/0 6/6 0/0 .text
* orderSync__12JKRAramPieceFiUlUlUlP12JKRAramBlock */
BOOL JKRAramPiece::orderSync(int direction, u32 source, u32 destination, u32 length,
JKRAramBlock* block) {
lock();
JKRAMCommand* command =
JKRAramPiece::orderAsync(direction, source, destination, length, block, NULL);
BOOL result = JKRAramPiece::sync(command, 0);
delete command;
unlock();
return result;
}
/* 802D38CC-802D3944 2CE20C 0078+00 1/1 1/1 0/0 .text startDMA__12JKRAramPieceFP12JKRAMCommand */
void JKRAramPiece::startDMA(JKRAMCommand* command) {
if (command->mTransferDirection == 1) {
DCInvalidateRange((void*)command->mDst, command->mDataLength);
} else {
DCStoreRange((void*)command->mSrc, command->mDataLength);
}
ARQPostRequest(&command->mRequest, 0, command->mTransferDirection, 0, command->mSrc,
command->mDst, command->mDataLength, JKRAramPiece::doneDMA);
}
/* 802D3944-802D39EC 2CE284 00A8+00 1/1 0/0 0/0 .text doneDMA__12JKRAramPieceFUl */
void JKRAramPiece::doneDMA(u32 requestAddress) {
JKRAMCommand* command = (JKRAMCommand*)requestAddress;
if (command->mTransferDirection == 1) {
DCInvalidateRange((void*)command->mDst, command->mDataLength);
}
if (command->field_0x60 != 0) {
if (command->field_0x60 == 2) {
JKRDecomp::sendCommand(command->mDecompCommand);
}
return;
}
if (command->mCallback) {
(*command->mCallback)(requestAddress);
} else if (command->field_0x5C) {
OSSendMessage(command->field_0x5C, command, OS_MESSAGE_NOBLOCK);
} else {
OSSendMessage(&command->mMessageQueue, command, OS_MESSAGE_NOBLOCK);
}
}
/* 802D39EC-802D3A5C 2CE32C 0070+00 1/1 0/0 0/0 .text __ct__12JKRAMCommandFv */
JKRAMCommand::JKRAMCommand() : mPieceLink(this), field_0x30(this) {
OSInitMessageQueue(&mMessageQueue, &mMessage, 1);
mCallback = NULL;
field_0x5C = NULL;
field_0x60 = 0;
field_0x8C = NULL;
field_0x90 = NULL;
field_0x94 = NULL;
}
/* 802D3A5C-802D3B04 2CE39C 00A8+00 1/1 0/0 0/0 .text __dt__12JKRAMCommandFv */
JKRAMCommand::~JKRAMCommand() {
if (field_0x8C)
delete field_0x8C;
if (field_0x90)
delete field_0x90;
if (field_0x94)
JKRHeap::free(field_0x94, NULL);
}
+230
View File
@@ -0,0 +1,230 @@
#include "JSystem/JKernel/JKRAramStream.h"
#include "JSystem/JKernel/JKRAramPiece.h"
#include "JSystem/JSupport/JSUFileStream.h"
#include "JSystem/JUtility/JUTException.h"
/* ############################################################################################## */
/* 80451408-8045140C 000908 0004+00 1/1 0/0 0/0 .sbss sAramStreamObject__13JKRAramStream
*/
JKRAramStream* JKRAramStream::sAramStreamObject;
/* 802D3B48-802D3BB8 2CE488 0070+00 0/0 1/1 0/0 .text create__13JKRAramStreamFl */
JKRAramStream* JKRAramStream::create(s32 priority) {
if (!sAramStreamObject) {
sAramStreamObject = new (JKRGetSystemHeap(), 0) JKRAramStream(priority);
setTransBuffer(NULL, 0, NULL);
}
return sAramStreamObject;
}
/* ############################################################################################## */
/* 803CC188-803CC198 0292A8 0010+00 1/1 0/0 0/0 .data sMessageBuffer__13JKRAramStream */
void* JKRAramStream::sMessageBuffer[4] = {
NULL,
NULL,
NULL,
NULL,
};
/* 803CC198-803CC1B8 0292B8 0020+00 2/2 0/0 0/0 .data sMessageQueue__13JKRAramStream */
OSMessageQueue JKRAramStream::sMessageQueue = {0};
/* 802D3BB8-802D3C08 2CE4F8 0050+00 1/1 0/0 0/0 .text __ct__13JKRAramStreamFl */
JKRAramStream::JKRAramStream(s32 priority) : JKRThread(0xc00, 0x10, priority) {
resume();
}
/* 802D3C08-802D3C68 2CE548 0060+00 1/0 0/0 0/0 .text __dt__13JKRAramStreamFv */
JKRAramStream::~JKRAramStream() {}
/* 802D3C68-802D3CD8 2CE5A8 0070+00 1/0 0/0 0/0 .text run__13JKRAramStreamFv */
void* JKRAramStream::run() {
OSInitMessageQueue(&sMessageQueue, sMessageBuffer, ARRAY_SIZE(sMessageBuffer));
for (;;) {
OSMessage message;
OSReceiveMessage(&sMessageQueue, &message, OS_MESSAGE_BLOCK);
JKRAramStreamCommand* command = (JKRAramStreamCommand*)message;
switch (command->mType) {
case JKRAramStreamCommand::READ:
readFromAram();
break;
case JKRAramStreamCommand::WRITE:
writeToAram(command);
break;
}
}
}
/* 802D3CD8-802D3CE0 2CE618 0008+00 1/1 0/0 0/0 .text readFromAram__13JKRAramStreamFv */
s32 JKRAramStream::readFromAram() {
return 1;
}
/* ############################################################################################## */
/* 8039D120-8039D120 029780 0000+00 0/0 0/0 0/0 .rodata @stringBase0 */
s32 JKRAramStream::writeToAram(JKRAramStreamCommand* command) {
u32 dstSize = command->mSize;
u32 offset = command->mOffset;
u32 writtenLength = 0;
u32 destination = command->mAddress;
u8* buffer = command->mTransferBuffer;
u32 bufferSize = command->mTransferBufferSize;
JKRHeap* heap = command->mHeap;
if (buffer) {
bufferSize = (bufferSize) ? bufferSize : 0x8000;
command->mTransferBufferSize = bufferSize;
command->mAllocatedTransferBuffer = false;
} else {
bufferSize = (bufferSize) ? bufferSize : 0x8000;
if (heap) {
buffer = (u8*)JKRAllocFromHeap(heap, bufferSize, -0x20);
command->mTransferBuffer = buffer;
} else {
buffer = (u8*)JKRAllocFromSysHeap(bufferSize, -0x20);
command->mTransferBuffer = buffer;
}
command->mTransferBufferSize = bufferSize;
command->mAllocatedTransferBuffer = true;
}
if (!buffer) {
if (!heap) {
JKRGetCurrentHeap()->dump();
} else {
heap->dump();
}
JUTException::panic(__FILE__, 172, ":::Cannot alloc memory\n");
}
if (buffer) {
command->mStream->seek(offset, JSUStreamSeekFrom_SET);
while (dstSize != 0) {
u32 length = (dstSize > bufferSize) ? bufferSize : dstSize;
s32 readLength = command->mStream->read(buffer, length);
if (readLength == 0) {
writtenLength = 0;
break;
}
JKRAramPcs(0, (u32)buffer, destination, length, NULL);
dstSize -= length;
writtenLength += length;
destination += length;
if (command->mReturnSize) {
*command->mReturnSize += length;
}
}
if (command->mAllocatedTransferBuffer) {
JKRFree(buffer);
command->mAllocatedTransferBuffer = false;
}
}
OSSendMessage(&command->mMessageQueue, (OSMessage)writtenLength, OS_MESSAGE_NOBLOCK);
return writtenLength;
}
/* ############################################################################################## */
/* 8045140C-80451410 00090C 0004+00 2/2 0/0 0/0 .sbss transBuffer__13JKRAramStream */
u8* JKRAramStream::transBuffer;
/* 80451410-80451414 000910 0004+00 2/2 0/0 0/0 .sbss transSize__13JKRAramStream */
u32 JKRAramStream::transSize;
/* 80451414-80451418 000914 0004+00 2/2 0/0 0/0 .sbss transHeap__13JKRAramStream */
JKRHeap* JKRAramStream::transHeap;
/* 802D3ED0-802D3FA0 2CE810 00D0+00 0/0 1/1 0/0 .text
* write_StreamToAram_Async__13JKRAramStreamFP18JSUFileInputStreamUlUlUlPUl */
JKRAramStreamCommand* JKRAramStream::write_StreamToAram_Async(JSUFileInputStream* stream, u32 addr,
u32 size, u32 offset,
u32* returnSize) {
JKRAramStreamCommand* command = new (JKRGetSystemHeap(), -4) JKRAramStreamCommand();
command->mType = JKRAramStreamCommand::WRITE;
command->mAddress = addr;
command->mSize = size;
command->mStream = stream;
command->field_0x2c = 0;
command->mOffset = offset;
command->mTransferBuffer = transBuffer;
command->mHeap = transHeap;
command->mTransferBufferSize = transSize;
command->mReturnSize = returnSize;
if (returnSize) {
*returnSize = 0;
}
OSInitMessageQueue(&command->mMessageQueue, &command->mMessage, 1);
OSSendMessage(&sMessageQueue, command, OS_MESSAGE_BLOCK);
return command;
}
/* 802D3FA0-802D4034 2CE8E0 0094+00 0/0 1/1 0/0 .text
* sync__13JKRAramStreamFP20JKRAramStreamCommandi */
JKRAramStreamCommand* JKRAramStream::sync(JKRAramStreamCommand* command, BOOL isNonBlocking) {
OSMessage message;
if (isNonBlocking == 0) {
OSReceiveMessage(&command->mMessageQueue, &message, OS_MESSAGE_BLOCK);
if (message == NULL) {
command = NULL;
return command;
} else {
return command;
}
} else {
BOOL receiveResult =
OSReceiveMessage(&command->mMessageQueue, &message, OS_MESSAGE_NOBLOCK);
if (receiveResult == FALSE) {
command = NULL;
return command;
} else if (message == NULL) {
command = NULL;
return command;
} else {
return command;
}
}
}
/* 802D4034-802D4088 2CE974 0054+00 1/1 1/1 0/0 .text
* setTransBuffer__13JKRAramStreamFPUcUlP7JKRHeap */
void JKRAramStream::setTransBuffer(u8* buffer, u32 bufferSize, JKRHeap* heap) {
transBuffer = NULL;
transSize = 0x8000;
transHeap = NULL;
if (buffer) {
transBuffer = (u8*)ALIGN_NEXT((u32)buffer, 0x20);
}
if (bufferSize) {
transSize = ALIGN_PREV(bufferSize, 0x20);
}
if (heap && !buffer) {
transHeap = heap;
}
}
/* 802D4088-802D4094 2CE9C8 000C+00 1/1 0/0 0/0 .text __ct__20JKRAramStreamCommandFv */
JKRAramStreamCommand::JKRAramStreamCommand() {
mAllocatedTransferBuffer = false;
}
/* 802D4094-802D40F0 2CE9D4 005C+00 0/0 3/0 0/0 .text getAvailable__20JSURandomInputStreamCFv */
// s32 JSURandomInputStream::getAvailable() const {
// should be an inline function
extern "C" s32 getAvailable__20JSURandomInputStreamCFv(JSURandomInputStream* self) {
return self->getLength() - self->getPosition();
}
+243
View File
@@ -0,0 +1,243 @@
#include "JSystem/JKernel/JKRArchive.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "ctype.h"
#include "string.h"
/* ############################################################################################## */
/* 80451420-80451428 000920 0004+04 1/1 5/5 0/0 .sbss sCurrentDirID__10JKRArchive */
u32 JKRArchive::sCurrentDirID;
/* 802D6294-802D6334 2D0BD4 00A0+00 0/0 5/5 0/0 .text
* __ct__10JKRArchiveFlQ210JKRArchive10EMountMode */
JKRArchive::JKRArchive(s32 entryNumber, JKRArchive::EMountMode mountMode) {
mIsMounted = false;
mMountMode = mountMode;
mMountCount = 1;
field_0x58 = 1;
mHeap = JKRHeap::findFromRoot(this);
if (mHeap == NULL) {
mHeap = JKRHeap::getCurrentHeap();
}
mEntryNum = entryNumber;
if (getCurrentVolume() == NULL) {
setCurrentVolume(this);
setCurrentDirID(0);
}
}
/* 802D6334-802D6394 2D0C74 0060+00 0/0 5/4 0/0 .text __dt__10JKRArchiveFv */
JKRArchive::~JKRArchive() {}
/* 802D6394-802D63E0 2D0CD4 004C+00 4/4 0/0 0/0 .text
* isSameName__10JKRArchiveCFRQ210JKRArchive8CArcNameUlUs */
bool JKRArchive::isSameName(JKRArchive::CArcName& name, u32 nameOffset, u16 nameHash) const {
u16 hash = name.getHash();
if (hash != nameHash)
return false;
return strcmp(mStringTable + nameOffset, name.getString()) == 0;
}
/* 802D63E0-802D641C 2D0D20 003C+00 1/1 0/0 0/0 .text findResType__10JKRArchiveCFUl */
JKRArchive::SDIDirEntry* JKRArchive::findResType(u32 type) const {
SDIDirEntry* node = mNodes;
u32 count = 0;
while (count < mArcInfoBlock->num_nodes) {
if (node->type == type) {
return node;
}
node++;
count++;
}
return NULL;
}
/* 802D641C-802D64F4 2D0D5C 00D8+00 0/0 3/3 0/0 .text findDirectory__10JKRArchiveCFPCcUl
*/
JKRArchive::SDIDirEntry* JKRArchive::findDirectory(const char* name, u32 directoryId) const {
if (name == NULL) {
return mNodes + directoryId;
}
CArcName arcName(&name, '/');
SDIDirEntry* dirEntry = mNodes + directoryId;
SDIFileEntry* fileEntry = mFiles + dirEntry->first_file_index;
for (int i = 0; i < dirEntry->num_entries; fileEntry++, i++) {
if (isSameName(arcName, fileEntry->getNameOffset(), fileEntry->name_hash)) {
if (fileEntry->isDirectory()) {
return findDirectory(name, fileEntry->data_offset);
}
break;
}
}
return NULL;
}
/* 802D64F4-802D65A4 2D0E34 00B0+00 0/0 2/2 0/0 .text findTypeResource__10JKRArchiveCFUlPCc */
JKRArchive::SDIFileEntry* JKRArchive::findTypeResource(u32 type, const char* name) const {
if (type) {
CArcName arcName(name);
SDIDirEntry* dirEntry = findResType(type);
if (dirEntry) {
SDIFileEntry* fileEntry = mFiles + dirEntry->first_file_index;
for (int i = 0; i < dirEntry->num_entries; fileEntry++, i++) {
if (isSameName(arcName, fileEntry->getNameOffset(), fileEntry->getNameHash())) {
return fileEntry;
}
}
}
}
return NULL;
}
/* 802D65A4-802D6684 2D0EE4 00E0+00 0/0 4/4 0/0 .text findFsResource__10JKRArchiveCFPCcUl
*/
JKRArchive::SDIFileEntry* JKRArchive::findFsResource(const char* name, u32 directoryId) const {
if (name) {
CArcName arcName(&name, '/');
SDIDirEntry* dirEntry = mNodes + directoryId;
SDIFileEntry* fileEntry = mFiles + dirEntry->first_file_index;
for (int i = 0; i < dirEntry->num_entries; fileEntry++, i++) {
if (isSameName(arcName, fileEntry->getNameOffset(), fileEntry->name_hash)) {
if (fileEntry->isDirectory()) {
return findFsResource(name, fileEntry->data_offset);
}
if (name == NULL) {
return fileEntry;
}
return NULL;
}
}
}
return NULL;
}
/* 802D6684-802D66AC 2D0FC4 0028+00 0/0 7/7 0/0 .text findIdxResource__10JKRArchiveCFUl
*/
JKRArchive::SDIFileEntry* JKRArchive::findIdxResource(u32 fileIndex) const {
if (fileIndex < mArcInfoBlock->num_file_entries) {
return mFiles + fileIndex;
}
return NULL;
}
/* 802D66AC-802D6734 2D0FEC 0088+00 0/0 4/4 0/0 .text findNameResource__10JKRArchiveCFPCc
*/
JKRArchive::SDIFileEntry* JKRArchive::findNameResource(const char* name) const {
SDIFileEntry* fileEntry = mFiles;
CArcName arcName(name);
for (int i = 0; i < mArcInfoBlock->num_file_entries; fileEntry++, i++) {
if (isSameName(arcName, fileEntry->getNameOffset(), fileEntry->getNameHash())) {
return fileEntry;
}
}
return NULL;
}
/* 802D6734-802D6770 2D1074 003C+00 0/0 9/9 0/0 .text findPtrResource__10JKRArchiveCFPCv
*/
JKRArchive::SDIFileEntry* JKRArchive::findPtrResource(const void* resource) const {
SDIFileEntry* fileEntry = mFiles;
for (int i = 0; i < mArcInfoBlock->num_file_entries; fileEntry++, i++) {
if (fileEntry->data == resource) {
return fileEntry;
}
}
return NULL;
}
/* 802D6770-802D67F4 2D10B0 0084+00 0/0 4/4 0/0 .text findIdResource__10JKRArchiveCFUs */
JKRArchive::SDIFileEntry* JKRArchive::findIdResource(u16 id) const {
if (id != 0xFFFF) {
if (id < mArcInfoBlock->num_file_entries) {
SDIFileEntry* fileEntry = mFiles + id;
if (fileEntry->file_id == id && fileEntry->isUnknownFlag1()) {
return fileEntry;
}
}
SDIFileEntry* fileEntry = mFiles;
for (int i = 0; i < mArcInfoBlock->num_file_entries; fileEntry++, i++) {
if (fileEntry->file_id == id && fileEntry->isUnknownFlag1()) {
return fileEntry;
}
}
}
return NULL;
}
/* 802D67F4-802D6884 2D1134 0090+00 2/2 0/0 0/0 .text store__Q210JKRArchive8CArcNameFPCc
*/
void JKRArchive::CArcName::store(const char* name) {
mHash = 0;
s32 length = 0;
while (*name) {
s32 ch = tolower(*name);
mHash = ch + mHash * 3;
if (length < (s32)ARRAY_SIZE(mData)) {
mData[length++] = ch;
}
name++;
}
mLength = (u16)length;
mData[length] = 0;
}
/* 802D6884-802D693C 2D11C4 00B8+00 2/2 0/0 0/0 .text store__Q210JKRArchive8CArcNameFPCcc
*/
const char* JKRArchive::CArcName::store(const char* name, char endChar) {
mHash = 0;
s32 length = 0;
while (*name && *name != endChar) {
s32 lch = tolower((int)*name);
mHash = lch + mHash * 3;
if (length < (s32)ARRAY_SIZE(mData)) {
mData[length++] = lch;
}
name++;
}
mLength = (u16)length;
mData[length] = 0;
if (*name == 0)
return NULL;
return name + 1;
}
/* 802D693C-802D6978 2D127C 003C+00 0/0 5/0 0/0 .text
* setExpandSize__10JKRArchiveFPQ210JKRArchive12SDIFileEntryUl */
void JKRArchive::setExpandSize(SDIFileEntry* fileEntry, u32 expandSize) {
int index = fileEntry - mFiles;
if (!mExpandedSize || index >= mArcInfoBlock->num_file_entries)
return;
mExpandedSize[index] = expandSize;
}
/* 802D6978-802D69B8 2D12B8 0040+00 0/0 5/0 0/0 .text
* getExpandSize__10JKRArchiveCFPQ210JKRArchive12SDIFileEntry */
u32 JKRArchive::getExpandSize(SDIFileEntry* fileEntry) const {
int index = fileEntry - mFiles;
if (!mExpandedSize || index >= mArcInfoBlock->num_file_entries)
return 0;
return mExpandedSize[index];
}
+389
View File
@@ -0,0 +1,389 @@
#include "JSystem/JKernel/JKRAramArchive.h"
#include "JSystem/JKernel/JKRArchive.h"
#include "JSystem/JKernel/JKRCompArchive.h"
#include "JSystem/JKernel/JKRDvdArchive.h"
#include "JSystem/JKernel/JKRFileFinder.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JKernel/JKRMemArchive.h"
#include "JSystem/JUtility/JUTAssert.h"
/* 802D5778-802D57E4 2D00B8 006C+00 2/2 0/0 0/0 .text check_mount_already__10JKRArchiveFlP7JKRHeap
*/
JKRArchive* JKRArchive::check_mount_already(s32 entryNum, JKRHeap* heap) {
if (heap == NULL) {
heap = JKRGetCurrentHeap();
}
JSUList<JKRFileLoader>& volumeList = getVolumeList();
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
if (iterator->getVolumeType() == 'RARC') {
JKRArchive* archive = (JKRArchive*)iterator.getObject();
if (archive->mEntryNum == entryNum && archive->mHeap == heap) {
archive->mMountCount++;
return archive;
}
}
}
return NULL;
}
/* 802D57E4-802D5840 2D0124 005C+00 0/0 1/1 0/0 .text
* mount__10JKRArchiveFPCcQ210JKRArchive10EMountModeP7JKRHeapQ210JKRArchive15EMountDirection */
JKRArchive* JKRArchive::mount(const char* path, EMountMode mountMode, JKRHeap* heap,
EMountDirection mountDirection) {
s32 entryNum = DVDConvertPathToEntrynum(path);
if (entryNum < 0)
return NULL;
return mount(entryNum, mountMode, heap, mountDirection);
}
/* 802D5840-802D58C8 2D0180 0088+00 0/0 1/1 0/0 .text
* mount__10JKRArchiveFPvP7JKRHeapQ210JKRArchive15EMountDirection */
JKRArchive* JKRArchive::mount(void* ptr, JKRHeap* heap,
EMountDirection mountDirection) {
JKRArchive* archive = check_mount_already((s32)ptr, heap);
if (archive)
return archive;
int alignment;
if (mountDirection == MOUNT_DIRECTION_HEAD) {
alignment = 4;
} else {
alignment = -4;
}
archive = new (heap, alignment) JKRMemArchive(ptr, 0xFFFF, JKRMEMBREAK_FLAG_UNKNOWN0);
return archive;
}
/* 802D58C8-802D5A38 2D0208 0170+00 1/1 1/1 0/0 .text
* mount__10JKRArchiveFlQ210JKRArchive10EMountModeP7JKRHeapQ210JKRArchive15EMountDirection */
JKRArchive* JKRArchive::mount(s32 entryNum, JKRArchive::EMountMode mountMode, JKRHeap* heap,
JKRArchive::EMountDirection mountDirection) {
JKRArchive* archive = check_mount_already(entryNum, heap);
if (archive != NULL) {
return archive;
} else {
int alignment;
if (mountDirection == JKRArchive::MOUNT_DIRECTION_HEAD) {
alignment = 4;
} else {
alignment = -4;
}
JKRArchive* archive;
switch (mountMode) {
case JKRArchive::MOUNT_MEM:
archive = new (heap, alignment) JKRMemArchive(entryNum, mountDirection);
break;
case JKRArchive::MOUNT_ARAM:
archive = new (heap, alignment) JKRAramArchive(entryNum, mountDirection);
break;
case JKRArchive::MOUNT_DVD:
archive = new (heap, alignment) JKRDvdArchive(entryNum, mountDirection);
break;
case JKRArchive::MOUNT_COMP:
archive = new (heap, alignment) JKRCompArchive(entryNum, mountDirection);
break;
}
if (archive && archive->getMountMode() == JKRArchive::UNKNOWN_MOUNT_MODE) {
delete archive;
archive = NULL;
}
return archive;
}
}
/* 802D5A38-802D5AC0 2D0378 0088+00 1/0 4/0 0/0 .text becomeCurrent__10JKRArchiveFPCc */
bool JKRArchive::becomeCurrent(const char* path) {
SDIDirEntry* dirEntry;
if (*path == '/') {
path++;
if (*path == '\0')
path = NULL;
dirEntry = findDirectory(path, 0);
} else {
dirEntry = findDirectory(path, getCurrentDirID());
}
bool found = dirEntry != NULL;
if (found) {
setCurrentVolume(this);
setCurrentDirID(dirEntry - mNodes);
}
return found;
}
/* 802D5AC0-802D5B38 2D0400 0078+00 0/0 1/1 0/0 .text
* getDirEntry__10JKRArchiveCFPQ210JKRArchive9SDirEntryUl */
bool JKRArchive::getDirEntry(SDirEntry* dirEntry, u32 index) const {
SDIFileEntry* fileEntry = findIdxResource(index);
if (!fileEntry)
return false;
dirEntry->flags = fileEntry->getFlags();
dirEntry->id = fileEntry->getFileID();
dirEntry->name = mStringTable + fileEntry->getNameOffset();
return true;
}
/* 802D5B38-802D5BE8 2D0478 00B0+00 0/0 9/9 0/0 .text
* getGlbResource__10JKRArchiveFUlPCcP10JKRArchive */
void* JKRArchive::getGlbResource(u32 param_1, const char* path, JKRArchive* archive) {
void* resource = NULL;
if (archive) {
return archive->getResource(param_1, path);
}
JSUList<JKRFileLoader>& volumeList = getVolumeList();
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
if (iterator->getVolumeType() == 'RARC') {
resource = iterator->getResource(param_1, path);
if (resource)
break;
}
}
return resource;
}
/* 802D5BE8-802D5C64 2D0528 007C+00 1/0 4/0 0/0 .text getResource__10JKRArchiveFPCc */
void* JKRArchive::getResource(const char* path) {
JUT_ASSERT(303, isMounted());
SDIFileEntry* fileEntry;
if (*path == '/') {
fileEntry = findFsResource(path + 1, 0);
} else {
fileEntry = findFsResource(path, getCurrentDirID());
}
if (fileEntry) {
return fetchResource(fileEntry, NULL);
}
return NULL;
}
/* 802D5C64-802D5CE4 2D05A4 0080+00 1/0 4/0 0/0 .text getResource__10JKRArchiveFUlPCc */
void* JKRArchive::getResource(u32 type, const char* path) {
JUT_ASSERT(347, isMounted());
SDIFileEntry* fileEntry;
if (type == 0 || type == '????') {
fileEntry = findNameResource(path);
} else {
fileEntry = findTypeResource(type, path);
}
if (fileEntry) {
return fetchResource(fileEntry, NULL);
}
return NULL;
}
/* 802D5CE4-802D5D38 2D0624 0054+00 0/0 1/1 0/0 .text getIdxResource__10JKRArchiveFUl */
void* JKRArchive::getIdxResource(u32 index) {
JUT_ASSERT(384, isMounted());
SDIFileEntry* fileEntry = findIdxResource(index);
if (fileEntry) {
return fetchResource(fileEntry, NULL);
}
return NULL;
}
/* 802D5D38-802D5D8C 2D0678 0054+00 0/0 1/1 0/0 .text getResource__10JKRArchiveFUs */
void* JKRArchive::getResource(u16 id) {
JUT_ASSERT(409, isMounted());
SDIFileEntry* fileEntry = findIdResource(id);
if (fileEntry) {
return fetchResource(fileEntry, NULL);
}
return NULL;
}
/* 802D5D8C-802D5E30 2D06CC 00A4+00 1/0 4/0 0/0 .text readResource__10JKRArchiveFPvUlUlPCc */
u32 JKRArchive::readResource(void* buffer, u32 bufferSize, u32 type, const char* path) {
JUT_ASSERT(493, isMounted());
SDIFileEntry* fileEntry;
if (type == 0 || type == '????') {
fileEntry = findNameResource(path);
} else {
fileEntry = findTypeResource(type, path);
}
if (fileEntry) {
u32 resourceSize;
fetchResource(buffer, bufferSize, fileEntry, &resourceSize);
return resourceSize;
}
return 0;
}
/* 802D5E30-802D5ECC 2D0770 009C+00 1/0 4/0 0/0 .text readResource__10JKRArchiveFPvUlPCc
*/
u32 JKRArchive::readResource(void* buffer, u32 bufferSize, const char* path) {
JUT_ASSERT(539, isMounted());
SDIFileEntry* fileEntry;
if (*path == '/') {
fileEntry = findFsResource(path + 1, 0);
} else {
fileEntry = findFsResource(path, getCurrentDirID());
}
if (fileEntry) {
u32 resourceSize;
fetchResource(buffer, bufferSize, fileEntry, &resourceSize);
return resourceSize;
}
return 0;
}
/* 802D5ECC-802D5F40 2D080C 0074+00 0/0 7/7 1/1 .text readIdxResource__10JKRArchiveFPvUlUl */
u32 JKRArchive::readIdxResource(void* buffer, u32 bufferSize, u32 index) {
JUT_ASSERT(593, isMounted());
SDIFileEntry* fileEntry = findIdxResource(index);
if (fileEntry) {
u32 resourceSize;
fetchResource(buffer, bufferSize, fileEntry, &resourceSize);
return resourceSize;
}
return 0;
}
/* 802D5F40-802D5FB4 2D0880 0074+00 0/0 1/1 0/0 .text readResource__10JKRArchiveFPvUlUs
*/
u32 JKRArchive::readResource(void* buffer, u32 bufferSize, u16 id) {
JUT_ASSERT(625, isMounted());
SDIFileEntry* fileEntry = findIdResource(id);
if (fileEntry) {
u32 resourceSize;
fetchResource(buffer, bufferSize, fileEntry, &resourceSize);
return resourceSize;
}
return 0;
}
/* 802D5FB4-802D603C 2D08F4 0088+00 1/0 2/0 0/0 .text removeResourceAll__10JKRArchiveFv
*/
void JKRArchive::removeResourceAll() {
if (mArcInfoBlock && mMountMode != MOUNT_MEM) {
SDIFileEntry* fileEntry = mFiles;
for (int i = 0; i < mArcInfoBlock->num_file_entries; fileEntry++, i++) {
if (fileEntry->data) {
JKRFreeToHeap(mHeap, fileEntry->data);
fileEntry->data = NULL;
}
}
}
}
/* 802D603C-802D609C 2D097C 0060+00 1/0 2/0 0/0 .text removeResource__10JKRArchiveFPv */
bool JKRArchive::removeResource(void* resource) {
JUT_ASSERT(678, resource != 0);
SDIFileEntry* fileEntry = findPtrResource(resource);
if (fileEntry == NULL)
return false;
fileEntry->data = NULL;
JKRFreeToHeap(mHeap, resource);
return true;
}
/* 802D609C-802D60D8 2D09DC 003C+00 1/0 4/0 0/0 .text detachResource__10JKRArchiveFPv */
bool JKRArchive::detachResource(void* resource) {
JUT_ASSERT(707, resource != 0);
SDIFileEntry* fileEntry = findPtrResource(resource);
if (fileEntry == NULL)
return false;
fileEntry->data = NULL;
return true;
}
/* 802D60D8-802D610C 2D0A18 0034+00 1/0 4/0 0/0 .text getResSize__10JKRArchiveCFPCv */
u32 JKRArchive::getResSize(const void* resource) const {
JUT_ASSERT(732, resource != 0);
SDIFileEntry* fileEntry = findPtrResource(resource);
if (fileEntry == NULL)
return -1;
return fileEntry->data_size;
}
/* 802D610C-802D6150 2D0A4C 0044+00 0/0 1/1 0/0 .text countResource__10JKRArchiveCFv */
u32 JKRArchive::countResource() const {
u32 count = 0;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
if (mFiles[i].isUnknownFlag1()) {
count++;
}
}
return count;
}
/* 802D6150-802D61B0 2D0A90 0060+00 1/0 4/0 0/0 .text countFile__10JKRArchiveCFPCc */
u32 JKRArchive::countFile(const char* path) const {
SDIDirEntry* dirEntry;
if (*path == '/') {
path++;
if (*path == '\0')
path = NULL;
dirEntry = findDirectory(path, 0);
} else {
dirEntry = findDirectory(path, getCurrentDirID());
}
if (dirEntry) {
return dirEntry->num_entries;
}
return 0;
}
/* 802D61B0-802D625C 2D0AF0 00AC+00 1/0 4/0 0/0 .text getFirstFile__10JKRArchiveCFPCc */
JKRFileFinder* JKRArchive::getFirstFile(const char* path) const {
SDIDirEntry* dirEntry;
if (*path == '/') {
path++;
if (*path == '\0')
path = NULL;
dirEntry = findDirectory(path, 0);
} else {
dirEntry = findDirectory(path, getCurrentDirID());
}
if (dirEntry) {
// don't know what is correct here... for now we're casting away const
return new (JKRHeap::getSystemHeap(), 0)
JKRArcFinder((JKRArchive*)this, dirEntry->first_file_index, (u32)dirEntry->num_entries);
}
return NULL;
}
/* 802D625C-802D6294 2D0B9C 0038+00 0/0 2/2 0/0 .text getFileAttribute__10JKRArchiveCFUl
*/
u32 JKRArchive::getFileAttribute(u32 index) const {
SDIFileEntry* fileEntry = findIdxResource(index);
if (fileEntry) {
return fileEntry->getFlags();
}
return 0;
}
+108
View File
@@ -0,0 +1,108 @@
#include "JSystem/JKernel/JKRAssertHeap.h"
/* 802D12C4-802D1300 2CBC04 003C+00 1/1 0/0 0/0 .text __ct__13JKRAssertHeapFPvUlP7JKRHeapb */
JKRAssertHeap::JKRAssertHeap(void* data, unsigned long size, JKRHeap* parent, bool errorFlag)
: JKRHeap(data, size, parent, errorFlag) {}
/* 802D1300-802D1368 2CBC40 0068+00 1/0 0/0 0/0 .text __dt__13JKRAssertHeapFv */
JKRAssertHeap::~JKRAssertHeap() {
this->dispose();
}
/* 802D1368-802D13D8 2CBCA8 0070+00 0/0 1/1 0/0 .text create__13JKRAssertHeapFP7JKRHeap
*/
JKRAssertHeap* JKRAssertHeap::create(JKRHeap* parent) {
if (!parent) {
parent = JKRHeap::getRootHeap();
}
// 0x70 is sizeof(JKRAssertHeap) aligned to 16 bytes
u32 size = 0x70;
int alignment = 16;
void* ptr = JKRHeap::alloc(size, alignment, parent);
if (!ptr)
return NULL;
return new (ptr) JKRAssertHeap(NULL, 0, parent, false);
}
/* 802D13D8-802D1408 2CBD18 0030+00 1/0 0/0 0/0 .text do_destroy__13JKRAssertHeapFv */
void JKRAssertHeap::do_destroy() {
this->~JKRAssertHeap();
}
/* 802D1408-802D1414 2CBD48 000C+00 1/0 0/0 0/0 .text getHeapType__13JKRAssertHeapFv */
u32 JKRAssertHeap::getHeapType() {
return 'ASTH';
}
/* 802D1414-802D141C 2CBD54 0008+00 1/0 0/0 0/0 .text check__13JKRAssertHeapFv */
bool JKRAssertHeap::check() {
return true;
}
/* 802D141C-802D1424 2CBD5C 0008+00 1/0 0/0 0/0 .text dump__13JKRAssertHeapFv */
bool JKRAssertHeap::dump() {
return true;
}
/* 802D1424-802D142C 2CBD64 0008+00 1/0 0/0 0/0 .text dump_sort__13JKRAssertHeapFv */
bool JKRAssertHeap::dump_sort() {
return true;
}
/* 802D142C-802D1434 2CBD6C 0008+00 1/0 0/0 0/0 .text do_changeGroupID__13JKRAssertHeapFUc */
s32 JKRAssertHeap::do_changeGroupID(u8) {
return 0;
}
/* 802D1434-802D143C 2CBD74 0008+00 1/0 0/0 0/0 .text do_getCurrentGroupId__13JKRAssertHeapFv */
u8 JKRAssertHeap::do_getCurrentGroupId() {
return 0;
}
/* 802D143C-802D1444 2CBD7C 0008+00 1/0 0/0 0/0 .text do_alloc__13JKRAssertHeapFUli */
void* JKRAssertHeap::do_alloc(u32, int) {
return NULL;
}
/* 802D1444-802D1448 2CBD84 0004+00 1/0 0/0 0/0 .text do_free__13JKRAssertHeapFPv */
void JKRAssertHeap::do_free(void* param_0) {}
/* 802D1448-802D144C 2CBD88 0004+00 1/0 0/0 0/0 .text do_freeAll__13JKRAssertHeapFv */
void JKRAssertHeap::do_freeAll() {}
/* 802D144C-802D1450 2CBD8C 0004+00 1/0 0/0 0/0 .text do_freeTail__13JKRAssertHeapFv */
void JKRAssertHeap::do_freeTail() {}
/* 802D1450-802D1454 2CBD90 0004+00 1/0 0/0 0/0 .text do_fillFreeArea__13JKRAssertHeapFv
*/
void JKRAssertHeap::do_fillFreeArea() {}
/* 802D1454-802D145C 2CBD94 0008+00 1/0 0/0 0/0 .text do_resize__13JKRAssertHeapFPvUl */
s32 JKRAssertHeap::do_resize(void*, u32) {
return 0;
}
/* 802D145C-802D1464 2CBD9C 0008+00 1/0 0/0 0/0 .text do_getSize__13JKRAssertHeapFPv */
s32 JKRAssertHeap::do_getSize(void*) {
return 0;
}
/* 802D1464-802D146C 2CBDA4 0008+00 1/0 0/0 0/0 .text do_getFreeSize__13JKRAssertHeapFv
*/
s32 JKRAssertHeap::do_getFreeSize() {
return 0;
}
/* 802D146C-802D1474 2CBDAC 0008+00 1/0 0/0 0/0 .text do_getMaxFreeBlock__13JKRAssertHeapFv */
void* JKRAssertHeap::do_getMaxFreeBlock() {
return NULL;
}
/* 802D1474-802D147C 2CBDB4 0008+00 1/0 0/0 0/0 .text do_getTotalFreeSize__13JKRAssertHeapFv */
s32 JKRAssertHeap::do_getTotalFreeSize() {
return 0;
}
+394
View File
@@ -0,0 +1,394 @@
#include "JSystem/JKernel/JKRCompArchive.h"
#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JKernel/JKRAramArchive.h"
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JKernel/JKRDvdAramRipper.h"
#include "JSystem/JKernel/JKRDvdArchive.h"
#include "JSystem/JKernel/JKRDvdFile.h"
#include "JSystem/JKernel/JKRMemArchive.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JUtility/JUTException.h"
#include "math.h"
#include "string.h"
/* 802D87D4-802D887C 2D3114 00A8+00 0/0 1/1 0/0 .text
* __ct__14JKRCompArchiveFlQ210JKRArchive15EMountDirection */
JKRCompArchive::JKRCompArchive(s32 entryNum, JKRArchive::EMountDirection eMountDirection)
: JKRArchive(entryNum, MOUNT_COMP) {
mMountDirection = eMountDirection;
if (!open(entryNum)) {
return;
}
mVolumeType = 'RARC';
mVolumeName = &mStringTable[mNodes->name_offset];
sVolumeList.prepend(&mFileLoaderLink);
mIsMounted = true;
}
/* 802D887C-802D89BC 2D31BC 0140+00 1/0 0/0 0/0 .text __dt__14JKRCompArchiveFv */
JKRCompArchive::~JKRCompArchive() {
if (mArcInfoBlock != NULL) {
SDIFileEntry* file = mFiles;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
if (!((file->type_flags_and_name_offset >> 0x18) & 0x10) && file->data != NULL) {
JKRFreeToHeap(mHeap, file->data);
}
file++;
}
JKRFreeToHeap(mHeap, mArcInfoBlock);
mArcInfoBlock = NULL;
}
if (mAramPart != NULL) {
delete mAramPart;
}
if (mExpandedSize != NULL) {
JKRFree(mExpandedSize);
mExpandedSize = NULL;
}
if (mDvdFile != NULL) {
delete mDvdFile;
}
sVolumeList.remove(&mFileLoaderLink);
mIsMounted = false;
}
/* 802D89BC-802D8F40 2D32FC 0584+00 1/1 0/0 0/0 .text open__14JKRCompArchiveFl */
bool JKRCompArchive::open(s32 entryNum) {
mArcInfoBlock = NULL;
field_0x64 = 0;
mAramPart = NULL;
field_0x6c = 0;
mSizeOfMemPart = 0;
mSizeOfAramPart = 0;
field_0x7c = 0;
mNodes = NULL;
mFiles = NULL;
mStringTable = NULL;
mDvdFile = new (JKRGetSystemHeap(), 0) JKRDvdFile(entryNum);
if(mDvdFile == NULL) {
mMountMode = 0;
return 0;
}
SArcHeader *arcHeader = (SArcHeader *)JKRAllocFromSysHeap(sizeof(SArcHeader), -32); // NOTE: unconfirmed if this struct is used
if(arcHeader == NULL) {
mMountMode = 0;
}
else {
int alignment;
JKRDvdToMainRam(entryNum, (u8 *)arcHeader, EXPAND_SWITCH_UNKNOWN1, 32, NULL, JKRDvdRipper::ALLOC_DIRECTION_FORWARD, 0, &mCompression, NULL);
DCInvalidateRange(arcHeader, 32);
mSizeOfMemPart = arcHeader->field_0x14;
mSizeOfAramPart = arcHeader->field_0x18;
JUT_ASSERT(352, ( mSizeOfMemPart & 0x1f ) == 0);
JUT_ASSERT(353, ( mSizeOfAramPart & 0x1f ) == 0);
switch (mCompression)
{
case COMPRESSION_NONE:
case COMPRESSION_YAZ0:
alignment = mMountDirection == 1 ? 32 : -32;
mArcInfoBlock = (SArcDataInfo *)JKRAllocFromHeap(mHeap, arcHeader->file_data_offset + mSizeOfMemPart, alignment);
if (mArcInfoBlock == NULL) {
mMountMode = 0;
}
else
{
JKRDvdToMainRam(entryNum, (u8 *)mArcInfoBlock, EXPAND_SWITCH_UNKNOWN1, (u32)arcHeader->file_data_offset + mSizeOfMemPart,
NULL, JKRDvdRipper::ALLOC_DIRECTION_FORWARD, 0x20, NULL, NULL);
DCInvalidateRange(mArcInfoBlock, (u32)arcHeader->file_data_offset + mSizeOfMemPart);
field_0x64 = (u32)mArcInfoBlock + arcHeader->file_data_offset;
if (mSizeOfAramPart != 0) {
mAramPart = (JKRAramBlock*)JKRAllocFromAram(mSizeOfAramPart, JKRAramHeap::HEAD);
if(mAramPart == NULL) {
mMountMode = 0;
break;
}
JKRDvdToAram(entryNum, mAramPart->getAddress(), EXPAND_SWITCH_UNKNOWN1, arcHeader->header_length + arcHeader->file_data_offset + mSizeOfMemPart, 0, NULL);
}
mNodes = (SDIDirEntry*)((u32)mArcInfoBlock + mArcInfoBlock->node_offset);
mFiles = (SDIFileEntry *)((u32)mArcInfoBlock + mArcInfoBlock->file_entry_offset);
mStringTable = (char*)((u32)mArcInfoBlock + mArcInfoBlock->string_table_offset);
field_0x6c = arcHeader->header_length + arcHeader->file_data_offset;
}
break;
case COMPRESSION_YAY0:
u32 alignedSize = ALIGN_NEXT(mDvdFile->getFileSize(), 32);
alignment = ((mMountDirection == 1) ? 32 : -32);
u8 *buf = (u8 *)JKRAllocFromSysHeap(alignedSize, -alignment);
if(buf == NULL) {
mMountMode = 0;
}
else {
JKRDvdToMainRam(entryNum, buf, EXPAND_SWITCH_UNKNOWN2, alignedSize, NULL, JKRDvdRipper::ALLOC_DIRECTION_FORWARD, 0, NULL, NULL);
DCInvalidateRange(buf, alignedSize);
u32 expandSize = ALIGN_NEXT(JKRDecompExpandSize(buf), 32);
u8 *mem = (u8 *)JKRAllocFromHeap(mHeap, expandSize, -alignment);
if(mem == NULL) {
mMountMode = 0;
}
else {
arcHeader = (SArcHeader *)mem;
JKRDecompress((u8 *)buf, (u8 *)mem, expandSize, 0);
JKRFreeToSysHeap(buf);
mArcInfoBlock = (SArcDataInfo *)JKRAllocFromHeap(mHeap, arcHeader->file_data_offset + mSizeOfMemPart, alignment);
if(mArcInfoBlock == NULL) {
mMountMode = 0;
}
else {
// arcHeader + 1 should lead to 0x20, which is the data after the header
JKRHeap::copyMemory((u8 *)mArcInfoBlock, arcHeader + 1, (arcHeader->file_data_offset + mSizeOfMemPart));
field_0x64 = (u32)mArcInfoBlock + arcHeader->file_data_offset;
if (mSizeOfAramPart != 0) {
mAramPart = (JKRAramBlock*)JKRAllocFromAram(mSizeOfAramPart, JKRAramHeap::HEAD);
if(mAramPart == NULL) {
mMountMode = 0;
}
else {
JKRMainRamToAram((u8 *)mem + arcHeader->header_length + arcHeader->file_data_offset + mSizeOfMemPart,
mAramPart->getAddress(), mSizeOfAramPart, EXPAND_SWITCH_UNKNOWN0, 0, NULL, -1, NULL);
}
}
}
}
}
mNodes = (SDIDirEntry *)((u32)mArcInfoBlock + mArcInfoBlock->node_offset);
mFiles = (SDIFileEntry *)((u32)mArcInfoBlock + mArcInfoBlock->file_entry_offset);
mStringTable = (char *)((u32)mArcInfoBlock + mArcInfoBlock->string_table_offset);
field_0x6c = arcHeader->header_length + arcHeader->file_data_offset;
break;
}
mExpandedSize = NULL;
u8 compressedFiles = 0;
SDIFileEntry *fileEntry = mFiles;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++)
{
u8 flag = fileEntry->type_flags_and_name_offset >> 0x18;
if (((flag & 0x1) != 0) && (((flag)&0x10) == 0))
{
compressedFiles = compressedFiles | (flag & 4);
}
fileEntry++;
}
if (compressedFiles != 0)
{
mExpandedSize = (s32 *)JKRAllocFromHeap(mHeap, mArcInfoBlock->num_file_entries * 4, abs(alignment));
if (mExpandedSize == NULL)
{
JKRFreeToSysHeap(mArcInfoBlock);
mMountMode = 0;
}
else
{
memset(mExpandedSize, 0, mArcInfoBlock->num_file_entries * 4);
}
}
}
if (arcHeader != NULL)
{
JKRFreeToSysHeap(arcHeader);
}
if(mMountMode == 0) {
#ifdef DEBUG
OSReport(":::[%s: %d] Cannot alloc memory in mounting CompArchive\n", __FILE__, 567);
#endif
if(mDvdFile != NULL) {
delete mDvdFile;
}
return false;
}
return true;
}
/* 802D8F40-802D90C0 2D3880 0180+00 1/0 0/0 0/0 .text
* fetchResource__14JKRCompArchiveFPQ210JKRArchive12SDIFileEntryPUl */
void* JKRCompArchive::fetchResource(SDIFileEntry *fileEntry, u32 *pSize) {
JUT_ASSERT(597, isMounted());
u32 ptrSize;
u32 size = fileEntry->data_size;
int compression = JKRConvertAttrToCompressionType(fileEntry->type_flags_and_name_offset >> 0x18);
if(pSize == NULL) {
pSize = &ptrSize; // this makes barely any sense but ok
}
if (fileEntry->data == NULL) {
u32 flag = fileEntry->type_flags_and_name_offset >> 0x18;
if(flag & 0x10) {
fileEntry->data = (void *)(field_0x64 + fileEntry->data_offset);
*pSize = size;
}
else if (flag & 0x20) {
u8 *data;
*pSize = JKRAramArchive::fetchResource_subroutine(fileEntry->data_offset + mAramPart->getAddress() - mSizeOfMemPart, size, mHeap, compression, &data);
fileEntry->data = data;
if(compression == COMPRESSION_YAZ0) {
setExpandSize(fileEntry, *pSize);
}
}
else if (flag & 0x40) {
u8 *data;
u32 resSize = JKRDvdArchive::fetchResource_subroutine(mEntryNum, field_0x6c + fileEntry->data_offset, fileEntry->data_size, mHeap, compression, mCompression, &data);
if (pSize != NULL) {
*pSize = resSize;
}
fileEntry->data = data;
if (compression == COMPRESSION_YAZ0) {
setExpandSize(fileEntry, *pSize);
}
}
}
else {
if (pSize != NULL) {
*pSize = fileEntry->data_size;
}
}
return fileEntry->data;
}
/* ############################################################################################## */
/* 802D90C0-802D9260 2D3A00 01A0+00 1/0 0/0 0/0 .text
* fetchResource__14JKRCompArchiveFPvUlPQ210JKRArchive12SDIFileEntryPUl */
void *JKRCompArchive::fetchResource(void *data, u32 compressedSize, SDIFileEntry *fileEntry, u32 *pSize)
{
u32 size = 0;
JUT_ASSERT(708, isMounted());
u32 fileSize = fileEntry->data_size;
u32 alignedSize = ALIGN_NEXT(fileSize, 32);
u32 fileFlag = fileEntry->type_flags_and_name_offset >> 0x18;
int compression = JKRConvertAttrToCompressionType(fileFlag);
if(fileEntry->data != NULL) {
if (compression == COMPRESSION_YAZ0) {
u32 expandSize = getExpandSize(fileEntry);
if (expandSize != 0) {
fileSize = expandSize;
}
}
if (fileSize > compressedSize) {
fileSize = compressedSize;
}
JKRHeap::copyMemory(data, fileEntry->data, fileSize);
size = fileSize;
}
else {
if (fileFlag & 0x10) {
size = JKRMemArchive::fetchResource_subroutine((u8 *)(field_0x64 + fileEntry->data_offset), alignedSize, (u8 *)data,
compressedSize & ~31, compression);
}
else if (fileFlag & 0x20) {
size = JKRAramArchive::fetchResource_subroutine(fileEntry->data_offset + mAramPart->getAddress() - mSizeOfMemPart,
alignedSize, (u8 *)data, compressedSize & ~31, compression);
}
else if (fileFlag & 0x40){
size = JKRDvdArchive::fetchResource_subroutine(mEntryNum, field_0x6c + fileEntry->data_offset, alignedSize, (u8 *)data,
compressedSize & ~31, compression, mCompression);
} else {
JUTException::panic(__FILE__, 776, "illegal archive.");
}
}
if(pSize != NULL) {
*pSize = size;
}
return data;
}
/* 802D9260-802D92F4 2D3BA0 0094+00 1/0 0/0 0/0 .text removeResourceAll__14JKRCompArchiveFv */
void JKRCompArchive::removeResourceAll() {
if (mArcInfoBlock != NULL && mMountMode != MOUNT_MEM) {
SDIFileEntry* fileEntry = mFiles;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
int tmp = fileEntry->type_flags_and_name_offset >> 0x18;
if (fileEntry->data != NULL) {
if (!(tmp & 0x10)) {
JKRFreeToHeap(mHeap, fileEntry->data);
}
fileEntry->data = NULL;
}
}
}
}
/* 802D92F4-802D9360 2D3C34 006C+00 1/0 0/0 0/0 .text removeResource__14JKRCompArchiveFPv
*/
bool JKRCompArchive::removeResource(void* resource) {
SDIFileEntry* fileEntry = findPtrResource(resource);
if (!fileEntry)
return false;
if (!((fileEntry->type_flags_and_name_offset >> 0x18) & 0x10)) {
JKRFreeToHeap(mHeap, resource);
}
fileEntry->data = NULL;
return true;
}
/* ############################################################################################## */
/* 802D9360-802D9518 2D3CA0 01B8+00 1/0 0/0 0/0 .text getExpandedResSize__14JKRCompArchiveCFPCv */
u32 JKRCompArchive::getExpandedResSize(const void *resource) const
{
if (mExpandedSize == NULL) {
return getResSize(resource);
}
SDIFileEntry *fileEntry = findPtrResource(resource);
if(!fileEntry) {
return 0xffffffff;
}
u8 flags = (fileEntry->type_flags_and_name_offset >> 0x18);
if((flags & 4) == 0) { // not compressed
return getResSize(resource);
}
if ((flags & 0x10) != 0) {
return JKRDecompExpandSize((u8 *)resource);
}
u8 buf[64];
u8 *bufPtr = (u8 *)ALIGN_NEXT((u32)buf, 32);
if ((flags & 0x20) != 0) {
u32 addr = mAramPart->mAddress;
addr = fileEntry->data_offset + addr;
JKRAramToMainRam(addr, bufPtr, sizeof(buf) / 2, EXPAND_SWITCH_UNKNOWN0, 0, NULL, -1, NULL);
DCInvalidateRange(bufPtr, sizeof(buf) / 2);
}
else if ((flags & 0x40) != 0) {
JKRDvdToMainRam(mEntryNum, bufPtr, EXPAND_SWITCH_UNKNOWN2, sizeof(buf) / 2, NULL, JKRDvdRipper::ALLOC_DIRECTION_FORWARD, field_0x6c + fileEntry->data_offset, NULL, NULL);
DCInvalidateRange(bufPtr, sizeof(buf) / 2);
}
else {
JUTException::panic(__FILE__, 943, "illegal resource.");
}
u32 expandSize = JKRDecompExpandSize(bufPtr);
const_cast<JKRCompArchive *>(this)->setExpandSize(fileEntry, expandSize);
return expandSize;
}
+302
View File
@@ -0,0 +1,302 @@
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JKernel/JKRAramPiece.h"
/* ############################################################################################## */
/* 804514B0-804514B8 0009B0 0004+04 1/1 0/0 0/0 .sbss sDecompObject__9JKRDecomp */
JKRDecomp* JKRDecomp::sDecompObject;
JKRDecomp* JKRDecomp::create(s32 priority) {
if (!sDecompObject) {
sDecompObject = new (JKRHeap::getSystemHeap(), 0) JKRDecomp(priority);
}
return sDecompObject;
}
/* ############################################################################################## */
/* 803CC460-803CC480 029580 0020+00 1/1 0/0 0/0 .data sMessageBuffer__9JKRDecomp */
OSMessage JKRDecomp::sMessageBuffer[8] = {0};
/* 803CC480-803CC4A0 0295A0 0020+00 2/2 0/0 0/0 .data sMessageQueue__9JKRDecomp */
OSMessageQueue JKRDecomp::sMessageQueue = {0};
/* 802DB6E0-802DB730 2D6020 0050+00 1/1 0/0 0/0 .text __ct__9JKRDecompFl */
JKRDecomp::JKRDecomp(s32 priority) : JKRThread(0x800, 0x10, priority) {
resume();
}
/* 802DB730-802DB790 2D6070 0060+00 1/0 0/0 0/0 .text __dt__9JKRDecompFv */
JKRDecomp::~JKRDecomp() {}
/* 802DB790-802DB858 2D60D0 00C8+00 1/0 0/0 0/0 .text run__9JKRDecompFv */
void* JKRDecomp::run() {
OSInitMessageQueue(&sMessageQueue, sMessageBuffer, 8);
for (;;) {
OSMessage message;
OSReceiveMessage(&sMessageQueue, &message, OS_MESSAGE_BLOCK);
JKRDecompCommand* command = (JKRDecompCommand*)message;
decode(command->mSrcBuffer, command->mDstBuffer, command->mSrcLength, command->mDstLength);
if (command->field_0x20 != 0) {
if (command->field_0x20 == 1) {
JKRAramPiece::sendCommand(command->mAMCommand);
}
continue;
}
if (command->mCallback) {
(*command->mCallback)((u32)command);
continue;
}
if (command->field_0x1c) {
OSSendMessage(command->field_0x1c, (OSMessage)1, OS_MESSAGE_NOBLOCK);
} else {
OSSendMessage(&command->mMessageQueue, (OSMessage)1, OS_MESSAGE_NOBLOCK);
}
}
}
/* 802DB858-802DB8D0 2D6198 0078+00 1/1 0/0 0/0 .text prepareCommand__9JKRDecompFPUcPUcUlUlPFUl_v
*/
JKRDecompCommand* JKRDecomp::prepareCommand(u8* srcBuffer, u8* dstBuffer, u32 srcLength,
u32 dstLength,
JKRDecompCommand::AsyncCallback callback) {
JKRDecompCommand* command = new (JKRHeap::getSystemHeap(), -4) JKRDecompCommand();
command->mSrcBuffer = srcBuffer;
command->mDstBuffer = dstBuffer;
command->mSrcLength = srcLength;
command->mDstLength = dstLength;
command->mCallback = callback;
return command;
}
/* 802DB8D0-802DB900 2D6210 0030+00 1/1 1/1 0/0 .text sendCommand__9JKRDecompFP16JKRDecompCommand
*/
void JKRDecomp::sendCommand(JKRDecompCommand* command) {
OSSendMessage(&sMessageQueue, command, OS_MESSAGE_NOBLOCK);
}
/* 802DB900-802DB934 2D6240 0034+00 1/1 0/0 0/0 .text orderAsync__9JKRDecompFPUcPUcUlUlPFUl_v */
JKRDecompCommand* JKRDecomp::orderAsync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 dstLength,
JKRDecompCommand::AsyncCallback callback) {
JKRDecompCommand* command =
prepareCommand(srcBuffer, dstBuffer, srcLength, dstLength, callback);
sendCommand(command);
return command;
}
/* 802DB934-802DB988 2D6274 0054+00 1/1 0/0 0/0 .text sync__9JKRDecompFP16JKRDecompCommandi */
bool JKRDecomp::sync(JKRDecompCommand* command, int isNonBlocking) {
OSMessage message;
bool result;
if (isNonBlocking == JKRDECOMP_SYNC_BLOCKING) {
OSReceiveMessage(&command->mMessageQueue, &message, OS_MESSAGE_BLOCK);
result = true;
} else {
result =
OSReceiveMessage(&command->mMessageQueue, &message, OS_MESSAGE_NOBLOCK) != FALSE;
}
return result;
}
/* 802DB988-802DB9DC 2D62C8 0054+00 0/0 5/5 0/0 .text orderSync__9JKRDecompFPUcPUcUlUl */
bool JKRDecomp::orderSync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 dstLength) {
JKRDecompCommand* command = orderAsync(srcBuffer, dstBuffer, srcLength, dstLength, NULL);
bool result = sync(command, JKRDECOMP_SYNC_BLOCKING);
delete command;
return result;
}
/* 802DB9DC-802DBA58 2D631C 007C+00 1/1 0/0 0/0 .text decode__9JKRDecompFPUcPUcUlUl */
void JKRDecomp::decode(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 dstLength) {
JKRCompression compression = checkCompressed(srcBuffer);
if (compression == COMPRESSION_YAY0) {
decodeSZP(srcBuffer, dstBuffer, srcLength, dstLength);
} else if (compression == COMPRESSION_YAZ0) {
decodeSZS(srcBuffer, dstBuffer, srcLength, dstLength);
}
}
/* 802DBA58-802DBC14 2D6398 01BC+00 1/1 0/0 0/0 .text decodeSZP__9JKRDecompFPUcPUcUlUl */
void JKRDecomp::decodeSZP(u8* src, u8* dst, u32 srcLength, u32 dstLength) {
int srcChunkOffset;
int count;
int dstOffset;
u32 length = srcLength;
int linkInfo;
int offset;
int i;
int decodedSize = READU32_BE(src, 4);
int linkTableOffset = READU32_BE(src, 8);
int srcDataOffset = READU32_BE(src, 12);
dstOffset = 0;
u32 counter = 0;
srcChunkOffset = 16;
u32 chunkBits;
if (srcLength == 0)
return;
if (dstLength > decodedSize)
return;
do
{
if (counter == 0)
{
chunkBits = READU32_BE(src, srcChunkOffset);
srcChunkOffset += sizeof(u32);
counter = sizeof(u32) * 8;
}
if (chunkBits & 0x80000000)
{
if (dstLength == 0)
{
dst[dstOffset] = src[srcDataOffset];
length--;
if (length == 0)
return;
}
else
{
dstLength--;
}
dstOffset++;
srcDataOffset++;
}
else
{
linkInfo = src[linkTableOffset] << 8 | src[linkTableOffset + 1];
linkTableOffset += sizeof(u16);
offset = dstOffset - (linkInfo & 0xFFF);
count = (linkInfo >> 12);
if (count == 0)
{
count = (u32)src[srcDataOffset++] + 0x12;
}
else
count += 2;
if (count > decodedSize - dstOffset)
count = decodedSize - dstOffset;
for (i = 0; i < count; i++, dstOffset++, offset++)
{
if (dstLength == 0)
{
dst[dstOffset] = dst[offset - 1];
length--;
if (length == 0)
return;
}
else
dstLength--;
}
}
chunkBits <<= 1;
counter--;
} while (dstOffset < decodedSize);
}
/* 802DBC14-802DBCF8 2D6554 00E4+00 1/1 0/0 0/0 .text decodeSZS__9JKRDecompFPUcPUcUlUl */
void JKRDecomp::decodeSZS(u8* src_buffer, u8* dst_buffer, u32 srcSize, u32 dstSize) {
u8* decompEnd;
u8* copyStart;
s32 copyByteCount;
s32 chunkBitsLeft = 0;
s32 chunkBits;
decompEnd = dst_buffer + *(int*)(src_buffer + 4) - dstSize;
if (srcSize == 0) {
return;
}
if (dstSize > *(u32*)src_buffer) {
return;
}
u8* curSrcPos = src_buffer + 0x10;
do {
if (chunkBitsLeft == 0) {
chunkBits = curSrcPos[0];
chunkBitsLeft = 8;
curSrcPos++;
}
if ((chunkBits & 0x80) != 0) {
if (dstSize == 0) {
dst_buffer[0] = curSrcPos[0];
srcSize--;
dst_buffer++;
if (srcSize == 0)
return;
} else {
dstSize--;
}
curSrcPos++;
} else {
u32 local_28 = curSrcPos[1] | (curSrcPos[0] & 0xF) << 8;
u32 r31 = curSrcPos[0] >> 4;
curSrcPos += 2;
copyStart = dst_buffer - local_28;
if (r31 == 0) {
copyByteCount = curSrcPos[0] + 0x12;
curSrcPos++;
} else {
copyByteCount = r31 + 2;
}
do {
if (dstSize == 0) {
dst_buffer[0] = copyStart[-1];
srcSize--;
dst_buffer++;
if (srcSize == 0)
return;
} else {
dstSize--;
}
copyByteCount--;
copyStart++;
} while (copyByteCount != 0);
}
chunkBits <<= 1;
chunkBitsLeft--;
} while (dst_buffer != decompEnd);
}
/* 802DBCF8-802DBD70 2D6638 0078+00 1/1 4/4 0/0 .text checkCompressed__9JKRDecompFPUc */
JKRCompression JKRDecomp::checkCompressed(u8* src) {
if ((src[0] == 'Y') && (src[1] == 'a') && (src[3] == '0')) {
if (src[2] == 'y') {
return COMPRESSION_YAY0;
}
if (src[2] == 'z') {
return COMPRESSION_YAZ0;
}
}
if ((src[0] == 'A') && (src[1] == 'S') && (src[2] == 'R')) {
return COMPRESSION_ASR;
}
return COMPRESSION_NONE;
}
/* 802DBD70-802DBDC0 2D66B0 0050+00 1/1 0/0 0/0 .text __ct__16JKRDecompCommandFv */
JKRDecompCommand::JKRDecompCommand() {
OSInitMessageQueue(&mMessageQueue, &mMessage, 1);
mCallback = NULL;
field_0x1c = NULL;
mThis = this;
field_0x20 = 0;
}
/* 802DBDC0-802DBDFC 2D6700 003C+00 1/1 0/0 0/0 .text __dt__16JKRDecompCommandFv */
JKRDecompCommand::~JKRDecompCommand() {}
+18
View File
@@ -0,0 +1,18 @@
#include "JSystem/JKernel/JKRDisposer.h"
#include "JSystem/JKernel/JKRHeap.h"
/* 802D147C-802D14E4 2CBDBC 0068+00 0/0 12/12 0/0 .text __ct__11JKRDisposerFv */
JKRDisposer::JKRDisposer() : mLink(this) {
mHeap = JKRHeap::findFromRoot(this);
if (mHeap) {
mHeap->appendDisposer(this);
}
}
/* 802D14E4-802D1568 2CBE24 0084+00 1/0 10/10 0/0 .text __dt__11JKRDisposerFv */
JKRDisposer::~JKRDisposer() {
JKRHeap* heap = mHeap;
if (heap) {
heap->removeDisposer(this);
}
}
+565
View File
@@ -0,0 +1,565 @@
#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/JSupport/JSUFileStream.h"
#include "dolphin/os/OSCache.h"
#include "dolphin/os/OSInterrupt.h"
#include "dolphin/vi.h"
#include "global.h"
#include "string.h"
static int JKRDecompressFromDVDToAram(JKRDvdFile*, u32, u32, u32, u32, u32, u32*);
static int decompSZS_subroutine(u8*, u32);
static u8* firstSrcData();
static u8* nextSrcData(u8*);
static u32 dmaBufferFlush(u32);
extern "C" void __dt__18JSUFileInputStreamFv();
extern "C" static int JKRDecompressFromDVDToAram__FP10JKRDvdFileUlUlUlUlUlPUl();
extern "C" static int decompSZS_subroutine__FPUcUl();
extern "C" static u8* firstSrcData__Fv();
extern "C" static u8* nextSrcData__FPUc();
extern "C" static int dmaBufferFlush__FUl();
extern "C" void __sinit_JKRDvdAramRipper_cpp();
extern "C" void func_802DB62C(void* _this);
extern "C" u8 sDvdAramAsyncList__16JKRDvdAramRipper[12];
extern "C" u32 sSZSBufferSize__16JKRDvdAramRipper;
//
// External References:
//
extern "C" void alloc__7JKRHeapFUli();
extern "C" void free__7JKRHeapFPvP7JKRHeap();
extern "C" void* __nw__FUlP7JKRHeapi();
extern "C" void __dl__FPv();
extern "C" void alloc__11JKRAramHeapFUlQ211JKRAramHeap10EAllocMode();
extern "C" void orderSync__12JKRAramPieceFiUlUlUlP12JKRAramBlock();
extern "C" void write_StreamToAram_Async__13JKRAramStreamFP18JSUFileInputStreamUlUlUlPUl();
extern "C" void sync__13JKRAramStreamFP20JKRAramStreamCommandi();
extern "C" void checkCompressed__9JKRDecompFPUc();
extern "C" void __ct__10JSUPtrLinkFPv();
extern "C" void __dt__10JSUPtrLinkFv();
extern "C" void __dt__10JSUPtrListFv();
extern "C" void initiate__10JSUPtrListFv();
extern "C" void append__10JSUPtrListFP10JSUPtrLink();
extern "C" void remove__10JSUPtrListFP10JSUPtrLink();
extern "C" void __dt__14JSUInputStreamFv();
extern "C" void __ct__18JSUFileInputStreamFP7JKRFile();
extern "C" void __register_global_object();
extern "C" void _savegpr_23();
extern "C" void _savegpr_24();
extern "C" void _savegpr_25();
extern "C" void _savegpr_26();
extern "C" void _savegpr_29();
extern "C" void _restgpr_23();
extern "C" void _restgpr_24();
extern "C" void _restgpr_25();
extern "C" void _restgpr_26();
extern "C" void _restgpr_29();
extern "C" extern void* __vt__20JSURandomInputStream[9];
extern "C" extern void* __vt__18JSUFileInputStream[9 + 1 /* padding */];
extern "C" u8 sSystemHeap__7JKRHeap[4];
extern "C" u8 sAramObject__7JKRAram[4];
extern "C" bool errorRetry__16JKRDvdAramRipper;
//
// Declarations:
//
/* 802DA874-802DA918 2D51B4 00A4+00 0/0 3/3 0/0 .text
* loadToAram__16JKRDvdAramRipperFlUl15JKRExpandSwitchUlUlPUl */
JKRAramBlock* JKRDvdAramRipper::loadToAram(s32 entryNumber, u32 address,
JKRExpandSwitch expandSwitch, u32 param_3, u32 param_4,
u32* param_5) {
JKRDvdFile dvdFile;
if (!dvdFile.open(entryNumber)) {
return NULL;
} else {
return loadToAram(&dvdFile, address, expandSwitch, param_3, param_4, param_5);
}
}
/* 802DA918-802DA9C0 2D5258 00A8+00 1/1 0/0 0/0 .text
* loadToAram__16JKRDvdAramRipperFP10JKRDvdFileUl15JKRExpandSwitchUlUlPUl */
JKRAramBlock* JKRDvdAramRipper::loadToAram(JKRDvdFile* dvdFile, u32 address,
JKRExpandSwitch expandSwitch, u32 param_3, u32 param_4,
u32* param_5) {
JKRADCommand* command =
loadToAram_Async(dvdFile, address, expandSwitch, NULL, param_3, param_4, param_5);
syncAram(command, 0);
if (command->field_0x48 < 0) {
delete command;
return NULL;
}
if (address) {
delete command;
return (JKRAramBlock*)-1;
}
JKRAramBlock* result = command->mBlock;
delete command;
return result;
}
/* 802DA9C0-802DAA74 2D5300 00B4+00 1/1 0/0 0/0 .text
* loadToAram_Async__16JKRDvdAramRipperFP10JKRDvdFileUl15JKRExpandSwitchPFUl_vUlUlPUl */
JKRADCommand* JKRDvdAramRipper::loadToAram_Async(JKRDvdFile* dvdFile, u32 address,
JKRExpandSwitch expandSwitch,
void (*callback)(u32), u32 param_4, u32 param_5,
u32* param_6) {
JKRADCommand* command = new (JKRHeap::sSystemHeap, -4) JKRADCommand();
command->mDvdFile = dvdFile;
command->mAddress = address;
command->mBlock = NULL;
command->mExpandSwitch = expandSwitch;
command->mCallback = callback;
command->field_0x3c = param_4;
command->field_0x40 = param_5;
command->field_0x44 = param_6;
if (!callCommand_Async(command)) {
delete command;
return NULL;
}
return command;
}
/* 804343B4-804343C0 0610D4 000C+00 3/3 0/0 0/0 .bss sDvdAramAsyncList__16JKRDvdAramRipper */
JSUList<JKRADCommand> JKRDvdAramRipper::sDvdAramAsyncList;
/* 804508D0-804508D4 000350 0004+00 3/3 0/0 0/0 .sdata None */
bool JKRDvdAramRipper::errorRetry = true;
/* 802DAA74-802DADD8 2D53B4 0364+00 1/1 0/0 0/0 .text
* callCommand_Async__16JKRDvdAramRipperFP12JKRADCommand */
JKRADCommand* JKRDvdAramRipper::callCommand_Async(JKRADCommand* command) {
s32 compression;
s32 uncompressedSize;
bool bVar1 = true;
JKRDvdFile* dvdFile = command->mDvdFile;
compression = 0;
OSLockMutex(&dvdFile->mMutex2);
if (command->field_0x44) {
*command->field_0x44 = 0;
}
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_0x40 && fileSize > command->field_0x40) {
fileSize = command->field_0x40;
}
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 (JKRDvdAramRipper::errorRetry == 0) {
delete stream;
return NULL;
}
VIWaitForRetrace();
}
DCInvalidateRange(bufPtr, 0x20);
compression = JKRCheckCompressed_noASR(bufPtr);
u32 expandSize = JKRDecompExpandSize(bufPtr);
uncompressedSize = expandSize;
if (command->field_0x40 && uncompressedSize > command->field_0x40) {
uncompressedSize = command->field_0x40;
}
}
if (compression == 0) {
command->mExpandSwitch = EXPAND_SWITCH_UNKNOWN0;
}
if (command->mExpandSwitch == EXPAND_SWITCH_UNKNOWN1) {
if (command->mAddress == 0 && command->mBlock == NULL) {
command->mBlock = JKRAllocFromAram(uncompressedSize, JKRAramHeap::HEAD);
if (command->mBlock) {
command->mAddress = command->mBlock->getAddress();
}
dvdFile->mBlock = command->mBlock;
}
if (command->mBlock) {
command->mAddress = command->mBlock->getAddress();
}
if (command->mAddress == 0) {
dvdFile->field_0x50 = NULL;
return NULL;
}
} else {
if (command->mAddress == 0 && !command->mBlock) {
command->mBlock = JKRAllocFromAram(fileSize, JKRAramHeap::HEAD);
}
if (command->mBlock) {
command->mAddress = command->mBlock->getAddress();
}
if (command->mAddress == 0) {
dvdFile->field_0x50 = NULL;
return NULL;
}
}
if (compression == 0) {
command->mStreamCommand =
JKRStreamToAram_Async(stream, command->mAddress, fileSize - command->field_0x3c,
command->field_0x3c, NULL, command->field_0x44);
} else if (compression == 1) {
command->mStreamCommand =
JKRStreamToAram_Async(stream, command->mAddress, fileSize - command->field_0x3c,
command->field_0x3c, NULL, command->field_0x44);
} else if (compression == 2) {
command->mStreamCommand = NULL;
JKRDecompressFromDVDToAram(command->mDvdFile, command->mAddress, fileSize,
uncompressedSize, command->field_0x3c, 0,
command->field_0x44);
}
if (!command->mCallback) {
(*((JSUList<JKRADCommand>*)&sDvdAramAsyncList)).append(&command->mLink);
} else {
command->mCallback((u32)command);
}
}
OSUnlockMutex(&dvdFile->mMutex2);
return bVar1 == true ? command : NULL;
}
/* 802DADD8-802DAE48 2D5718 0070+00 0/0 1/0 0/0 .text __dt__18JSUFileInputStreamFv */
// JSUFileInputStream::~JSUFileInputStream() {
extern "C" void __dt__18JSUFileInputStreamFv() {
// NONMATCHING
}
/* 802DAE48-802DAF1C 2D5788 00D4+00 1/1 0/0 0/0 .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_0x48 = -(var1 == NULL);
if (param_1 != 0 && var1 == NULL) {
OSUnlockMutex(&dvdFile->mMutex2);
return false;
}
}
(*((JSUList<JKRADCommand>*)&sDvdAramAsyncList)).remove(&command->mLink);
if (command->mStreamCommand) {
delete command->mStreamCommand;
}
delete dvdFile->mFileStream;
dvdFile->field_0x50 = NULL;
OSUnlockMutex(&dvdFile->mMutex2);
return true;
}
/* 802DAF1C-802DAF5C 2D585C 0040+00 1/1 0/0 0/0 .text __ct__12JKRADCommandFv */
JKRADCommand::JKRADCommand() : mLink(this) {
field_0x48 = 0;
field_0x4c = 0;
}
/* 802DAF5C-802DAFE8 2D589C 008C+00 2/2 0/0 0/0 .text __dt__12JKRADCommandFv */
JKRADCommand::~JKRADCommand() {
if (field_0x4c == 1) {
delete mDvdFile;
}
}
/* ############################################################################################## */
/* 804343C0-804343D8 0610E0 0018+00 1/1 0/0 0/0 .bss decompMutex */
static OSMutex decompMutex;
/* 804508D4-804508D8 000354 0004+00 1/1 1/1 0/0 .sdata sSZSBufferSize__16JKRDvdAramRipper
*/
u32 JKRDvdAramRipper::sSZSBufferSize = 0x00000400;
/* 80451468-8045146C 000968 0004+00 3/3 0/0 0/0 .sbss szpBuf */
static u8* szpBuf;
/* 8045146C-80451470 00096C 0004+00 3/3 0/0 0/0 .sbss szpEnd */
static u8* szpEnd;
/* 80451470-80451474 000970 0004+00 2/2 0/0 0/0 .sbss refBuf */
static u8* refBuf;
/* 80451474-80451478 000974 0004+00 2/2 0/0 0/0 .sbss refEnd */
static u8* refEnd;
/* 80451478-8045147C 000978 0004+00 2/2 0/0 0/0 .sbss refCurrent */
static u8* refCurrent;
/* 8045147C-80451480 00097C 0004+00 2/2 0/0 0/0 .sbss dmaBuf */
static u8* dmaBuf;
/* 80451480-80451484 000980 0004+00 2/2 0/0 0/0 .sbss dmaEnd */
static u8* dmaEnd;
/* 80451484-80451488 000984 0004+00 3/3 0/0 0/0 .sbss dmaCurrent */
static u8* dmaCurrent;
/* 80451488-8045148C 000988 0004+00 3/3 0/0 0/0 .sbss srcOffset */
static u32 srcOffset;
/* 8045148C-80451490 00098C 0004+00 4/4 0/0 0/0 .sbss transLeft */
static u32 transLeft;
/* 80451490-80451494 000990 0004+00 3/3 0/0 0/0 .sbss srcLimit */
static u8* srcLimit;
/* 80451494-80451498 000994 0004+00 3/3 0/0 0/0 .sbss srcFile */
static JKRDvdFile* srcFile;
/* 80451498-8045149C 000998 0004+00 2/2 0/0 0/0 .sbss fileOffset */
static u32 fileOffset;
/* 8045149C-804514A0 00099C 0004+00 2/2 0/0 0/0 .sbss readCount */
static int readCount;
/* 804514A0-804514A4 0009A0 0004+00 2/2 0/0 0/0 .sbss maxDest */
static u32 maxDest;
/* 804514A4-804514A8 0009A4 0004+00 1/1 0/0 0/0 .sbss None */
static bool data_804514A4;
/* 804514A8-804514AC 0009A8 0004+00 2/2 0/0 0/0 .sbss tsPtr */
static u32* tsPtr;
/* 804514AC-804514B0 0009AC 0004+00 1/1 0/0 0/0 .sbss tsArea */
static u32 tsArea;
/* 802DAFE8-802DB160 2D5928 0178+00 1/1 0/0 0/0 .text
* JKRDecompressFromDVDToAram__FP10JKRDvdFileUlUlUlUlUlPUl */
int JKRDecompressFromDVDToAram(JKRDvdFile* dvdFile, u32 param_1, u32 fileSize, u32 uncompressedSize,
u32 param_4, u32 param_5, u32* param_6) {
BOOL level = OSDisableInterrupts();
if (!data_804514A4) {
OSInitMutex(&decompMutex);
data_804514A4 = true;
}
OSRestoreInterrupts(level);
OSLockMutex(&decompMutex);
u32 bufferSize = JKRDvdAramRipper::sSZSBufferSize;
szpBuf = (u8*)JKRAllocFromSysHeap(bufferSize, 0x20);
szpEnd = szpBuf + bufferSize;
refBuf = (u8*)JKRAllocFromSysHeap(0x1120, 0);
refEnd = refBuf + 0x1120;
refCurrent = refBuf;
dmaBuf = (u8*)JKRAllocFromSysHeap(0x100, 0x20);
dmaEnd = dmaBuf + 0x100;
dmaCurrent = dmaBuf;
srcFile = dvdFile;
srcOffset = param_5;
transLeft = fileSize - param_5;
fileOffset = param_4;
readCount = 0;
maxDest = uncompressedSize;
param_6 = param_6 ? param_6 : &tsArea;
tsPtr = param_6;
*param_6 = 0;
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;
}
/* 802DB160-802DB3E8 2D5AA0 0288+00 1/1 0/0 0/0 .text decompSZS_subroutine__FPUcUl */
static int decompSZS_subroutine(u8* src, u32 dest) {
u32 endAddr;
u8* copySource;
s32 validBitCount;
u32 currCodeByte;
s32 numBytes;
u32 var_r26;
u32 startDest;
validBitCount = 0;
currCodeByte = 0;
var_r26 = 0;
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++;
var_r26++;
if (dmaCurrent == dmaEnd) {
startDest += dmaBufferFlush(startDest);
}
if (dest == endAddr) {
break;
}
}
*(refCurrent++) = *src;
if (refCurrent == refEnd) {
refCurrent = refBuf;
}
src++;
readCount++;
} else {
u32 dist = ((src[0] & 0x0F) << 8) | src[1];
numBytes = src[0] >> 4;
src += 2;
copySource = refCurrent - dist - 1;
if (copySource < refBuf) {
copySource += refEnd - refBuf;
}
if (numBytes == 0) {
numBytes = *(src++);
numBytes += 0x12;
} else {
numBytes += 2;
}
do {
if (readCount >= fileOffset) {
*(dmaCurrent++) = *copySource;
dest++;
var_r26++;
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);
*tsPtr = var_r26;
return 0;
}
/* 802DB3E8-802DB49C 2D5D28 00B4+00 1/1 0/0 0/0 .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;
}
/* 802DB49C-802DB580 2D5DDC 00E4+00 1/1 0/0 0/0 .text nextSrcData__FPUc */
// regalloc
#ifdef NONMATCHING
static u8* nextSrcData(u8* src) {
u8* dest;
u32 size = szpEnd - src;
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;
}
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;
}
#else
static u8* nextSrcData(u8* param_0) {
// NONMATCHING
}
#endif
/* 802DB580-802DB5E8 2D5EC0 0068+00 1/1 0/0 0/0 .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;
}
+378
View File
@@ -0,0 +1,378 @@
#include "JSystem/JKernel/JKRDvdArchive.h"
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JKernel/JKRDvdFile.h"
#include "JSystem/JKernel/JKRDvdRipper.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JUtility/JUTException.h"
#include "math.h"
#include "string.h"
#include "global.h"
/* 802D7BF0-802D7C98 2D2530 00A8+00 0/0 1/1 0/0 .text
* __ct__13JKRDvdArchiveFlQ210JKRArchive15EMountDirection */
JKRDvdArchive::JKRDvdArchive(s32 entryNum, JKRArchive::EMountDirection mountDirection)
: JKRArchive(entryNum, MOUNT_DVD) {
mMountDirection = mountDirection;
if (!open(entryNum))
return;
mVolumeType = 'RARC';
mVolumeName = mStringTable + mNodes->name_offset;
getVolumeList().prepend(&mFileLoaderLink);
mIsMounted = true;
}
/* 802D7C98-802D7DB4 2D25D8 011C+00 1/0 0/0 0/0 .text __dt__13JKRDvdArchiveFv */
JKRDvdArchive::~JKRDvdArchive() {
if (mIsMounted == true) {
if (mArcInfoBlock) {
SDIFileEntry* fileEntry = mFiles;
int i = 0;
for (; i < mArcInfoBlock->num_file_entries; fileEntry++, i++) {
if (fileEntry->data) {
JKRFreeToHeap(mHeap, fileEntry->data);
}
}
JKRFreeToHeap(mHeap, mArcInfoBlock);
mArcInfoBlock = NULL;
}
if (mExpandedSize) {
JKRFree(mExpandedSize);
mExpandedSize = NULL;
}
if (mDvdFile) {
delete mDvdFile;
}
getVolumeList().remove(&mFileLoaderLink);
mIsMounted = false;
}
}
/* 802D7DB4-802D8050 2D26F4 029C+00 1/1 0/0 0/0 .text open__13JKRDvdArchiveFl */
bool JKRDvdArchive::open(s32 entryNum) {
mArcInfoBlock = NULL;
mDataOffset = 0;
mNodes = NULL;
mFiles = NULL;
mStringTable = NULL;
mDvdFile = new (JKRGetSystemHeap(), 0) JKRDvdFile(entryNum);
if (!mDvdFile) {
mMountMode = UNKNOWN_MOUNT_MODE;
return false;
}
SArcHeader* arcHeader = (SArcHeader*)JKRAllocFromSysHeap(sizeof(SArcHeader), 0x20);
if (!arcHeader) {
mMountMode = UNKNOWN_MOUNT_MODE;
goto cleanup;
}
JKRDvdToMainRam(entryNum, (u8*)arcHeader, EXPAND_SWITCH_UNKNOWN1, sizeof(SArcHeader), NULL,
JKRDvdRipper::ALLOC_DIRECTION_FORWARD, 0, &mCompression, NULL);
DCInvalidateRange(arcHeader, sizeof(SArcHeader));
int alignment = mMountDirection == MOUNT_DIRECTION_HEAD ? 0x20 : -0x20;
mArcInfoBlock = (SArcDataInfo*)JKRAllocFromHeap(mHeap, arcHeader->file_data_offset, alignment);
if (!mArcInfoBlock) {
mMountMode = UNKNOWN_MOUNT_MODE;
goto cleanup;
}
JKRDvdToMainRam(entryNum, (u8*)mArcInfoBlock, EXPAND_SWITCH_UNKNOWN1,
arcHeader->file_data_offset, NULL, JKRDvdRipper::ALLOC_DIRECTION_FORWARD,
sizeof(SArcHeader), NULL, NULL);
DCInvalidateRange(mArcInfoBlock, arcHeader->file_data_offset);
mNodes = (SDIDirEntry*)((int)&mArcInfoBlock->num_nodes + mArcInfoBlock->node_offset);
mFiles = (SDIFileEntry*)((int)&mArcInfoBlock->num_nodes + mArcInfoBlock->file_entry_offset);
mStringTable = (char*)((int)&mArcInfoBlock->num_nodes + mArcInfoBlock->string_table_offset);
mExpandedSize = NULL;
u8 useCompression = 0;
SDIFileEntry* fileEntry = mFiles;
for (u32 i = 0; i < mArcInfoBlock->num_file_entries; fileEntry++, i++) {
if (fileEntry->isUnknownFlag1()) {
useCompression |= fileEntry->getCompressFlag();
}
}
if (useCompression) {
mExpandedSize = (s32*)JKRAllocFromHeap(mHeap, sizeof(s32) * mArcInfoBlock->num_file_entries,
abs(alignment));
if (!mExpandedSize) {
// !@bug: mArcInfoBlock is allocated from mHeap but free'd to sSystemHeap. I don't know
// what will happen if mHeap != sSystemHeap, but it's still a bug to free to the wrong
// allocator.
JKRFreeToSysHeap(mArcInfoBlock);
mMountMode = UNKNOWN_MOUNT_MODE;
goto cleanup;
}
memset(mExpandedSize, 0, sizeof(s32) * mArcInfoBlock->num_file_entries);
}
mDataOffset = arcHeader->header_length + arcHeader->file_data_offset;
cleanup:
if (arcHeader) {
JKRFreeToSysHeap(arcHeader);
}
if (mMountMode == UNKNOWN_MOUNT_MODE) {
#ifdef DEBUG
OSReport(":::Cannot alloc memory [%s][%d]\n", __FILE__, 397);
#endif
if (mDvdFile) {
delete mDvdFile;
}
return false;
}
return true;
}
/* 802D8050-802D8168 2D2990 0118+00 1/0 0/0 0/0 .text
* fetchResource__13JKRDvdArchiveFPQ210JKRArchive12SDIFileEntryPUl */
void* JKRDvdArchive::fetchResource(SDIFileEntry* fileEntry, u32* returnSize) {
JUT_ASSERT(428, isMounted());
u32 tempReturnSize;
if (returnSize == NULL) {
returnSize = &tempReturnSize;
}
JKRCompression fileCompression = JKRConvertAttrToCompressionType(fileEntry->getAttr());
if (!fileEntry->data) {
u8* resourcePtr;
u32 resourceSize = fetchResource_subroutine(
mEntryNum, mDataOffset + fileEntry->data_offset, fileEntry->data_size, mHeap,
fileCompression, mCompression, &resourcePtr);
*returnSize = resourceSize;
if (resourceSize == 0) {
return NULL;
}
fileEntry->data = resourcePtr;
if (fileCompression == COMPRESSION_YAZ0) {
setExpandSize(fileEntry, *returnSize);
}
} else {
if (fileCompression == COMPRESSION_YAZ0) {
u32 resourceSize = getExpandSize(fileEntry);
*returnSize = resourceSize;
} else {
*returnSize = fileEntry->data_size;
}
}
return fileEntry->data;
}
/* 802D8168-802D826C 2D2AA8 0104+00 1/0 0/0 0/0 .text
* fetchResource__13JKRDvdArchiveFPvUlPQ210JKRArchive12SDIFileEntryPUl */
void* JKRDvdArchive::fetchResource(void* buffer, u32 bufferSize, SDIFileEntry* fileEntry,
u32* returnSize) {
JUT_ASSERT(504, isMounted());
u32 expandSize;
u32 size = fileEntry->data_size;
JKRCompression fileCompression = JKRConvertAttrToCompressionType(fileEntry->getAttr());
if (!fileEntry->data) {
bufferSize = (s32)ALIGN_PREV(bufferSize, 0x20);
size = fetchResource_subroutine(mEntryNum, mDataOffset + fileEntry->data_offset,
fileEntry->data_size, (u8*)buffer, bufferSize, fileCompression,
mCompression);
} else {
if (fileCompression == COMPRESSION_YAZ0) {
expandSize = getExpandSize(fileEntry);
if (expandSize) {
size = expandSize;
}
}
if (size > bufferSize) {
size = bufferSize;
}
JKRHeap::copyMemory(buffer, fileEntry->data, size);
}
if (returnSize) {
*returnSize = size;
}
return buffer;
}
/* 802D826C-802D8474 2D2BAC 0208+00 1/1 1/1 0/0 .text
* fetchResource_subroutine__13JKRDvdArchiveFlUlUlPUcUlii */
u32 JKRDvdArchive::fetchResource_subroutine(s32 entryNum, u32 offset, u32 size, u8* dst,
u32 dstLength, JKRCompression fileCompression,
JKRCompression archiveCompression) {
u32 alignedSize = ALIGN_NEXT(size, 0x20);
u32 alignedDstLength = ALIGN_PREV(dstLength, 0x20);
switch (archiveCompression) {
case COMPRESSION_NONE: {
switch (fileCompression) {
case COMPRESSION_NONE:
if (alignedSize > alignedDstLength) {
alignedSize = alignedDstLength;
}
JKRDvdToMainRam(entryNum, dst, EXPAND_SWITCH_UNKNOWN0, alignedSize, NULL,
JKRDvdRipper::ALLOC_DIRECTION_FORWARD, offset, NULL, NULL);
DCInvalidateRange(dst, alignedSize);
return alignedSize;
case COMPRESSION_YAY0:
case COMPRESSION_YAZ0:
// The dst pointer to JKRDvdToMainRam should be aligned to 32 bytes. This will align
// arcHeader to 32 bytes on the stack.
char arcHeaderBuffer[64];
u8* arcHeader = (u8*)ALIGN_NEXT((u32)arcHeaderBuffer, 0x20);
JKRDvdToMainRam(entryNum, arcHeader, EXPAND_SWITCH_UNKNOWN2, sizeof(SArcHeader),
NULL, JKRDvdRipper::ALLOC_DIRECTION_FORWARD, offset, NULL, NULL);
DCInvalidateRange(arcHeader, sizeof(SArcHeader));
u32 decompressedSize = JKRDecompExpandSize(arcHeader);
u32 alignedDecompressedSize = ALIGN_NEXT(decompressedSize, 0x20);
if (alignedDecompressedSize > alignedDstLength) {
alignedDecompressedSize = alignedDstLength;
}
JKRDvdToMainRam(entryNum, dst, EXPAND_SWITCH_UNKNOWN1, alignedDecompressedSize, NULL,
JKRDvdRipper::ALLOC_DIRECTION_FORWARD, offset, NULL, NULL);
DCInvalidateRange(dst, alignedDecompressedSize);
return decompressedSize;
}
}
case COMPRESSION_YAZ0: {
if (size > alignedDstLength) {
size = alignedDstLength;
}
JKRDvdToMainRam(entryNum, dst, EXPAND_SWITCH_UNKNOWN1, size, NULL,
JKRDvdRipper::ALLOC_DIRECTION_FORWARD, offset, NULL, NULL);
DCInvalidateRange(dst, size);
return size;
}
case COMPRESSION_YAY0: {
JUTException::panic(__FILE__, 649, "Sorry, not applied for SZP archive.\n");
}
default: {
JUTException::panic(__FILE__, 653, "??? bad sequence\n");
return 0;
}
}
}
/* 802D8474-802D8698 2D2DB4 0224+00 1/1 1/1 0/0 .text
* fetchResource_subroutine__13JKRDvdArchiveFlUlUlP7JKRHeapiiPPUc */
u32 JKRDvdArchive::fetchResource_subroutine(s32 entryNum, u32 offset, u32 size, JKRHeap* heap,
JKRCompression fileCompression,
JKRCompression archiveCompression,
u8** returnResource) {
u32 alignedSize = ALIGN_NEXT(size, 0x20);
u8* buffer;
switch (archiveCompression) {
case COMPRESSION_NONE: {
switch (fileCompression) {
case COMPRESSION_NONE:
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, sizeof(SArcHeader));
JUT_ASSERT(675, buffer != 0);
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_UNKNOWN0, alignedSize, NULL,
JKRDvdRipper::ALLOC_DIRECTION_FORWARD, offset, NULL, NULL);
DCInvalidateRange(buffer, alignedSize);
*returnResource = buffer;
return alignedSize;
case COMPRESSION_YAY0:
case COMPRESSION_YAZ0:
// The dst pointer to JKRDvdToMainRam should be aligned to 32 bytes. This will align
// arcHeader to 32 bytes on the stack.
char arcHeaderBuffer[64];
u8* arcHeader = (u8*)ALIGN_NEXT((u32)arcHeaderBuffer, 0x20);
JKRDvdToMainRam(entryNum, arcHeader, EXPAND_SWITCH_UNKNOWN2, sizeof(SArcHeader),
NULL, JKRDvdRipper::ALLOC_DIRECTION_FORWARD, offset, NULL, NULL);
DCInvalidateRange(arcHeader, sizeof(SArcHeader));
alignedSize = JKRDecompExpandSize(arcHeader);
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, sizeof(SArcHeader));
JUT_ASSERT(715, buffer);
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_UNKNOWN1, alignedSize, NULL,
JKRDvdRipper::ALLOC_DIRECTION_FORWARD, offset, NULL, NULL);
DCInvalidateRange(buffer, alignedSize);
*returnResource = buffer;
return alignedSize;
}
}
case COMPRESSION_YAZ0: {
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, sizeof(SArcHeader));
JUT_ASSERT(735, buffer);
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_UNKNOWN1, size, NULL,
JKRDvdRipper::ALLOC_DIRECTION_FORWARD, offset, NULL, NULL);
DCInvalidateRange(buffer, size);
*returnResource = buffer;
return alignedSize;
}
case COMPRESSION_YAY0: {
JUTException::panic(__FILE__, 754, "Sorry, not applied SZP archive.\n");
}
default: {
JUTException::panic(__FILE__, 758, "??? bad sequence\n");
return 0;
}
}
}
/* 802D8698-802D87D4 2D2FD8 013C+00 1/0 0/0 0/0 .text getExpandedResSize__13JKRDvdArchiveCFPCv */
u32 JKRDvdArchive::getExpandedResSize(const void* resource) const {
u32 resourceSize;
if (!mExpandedSize) {
return getResSize(resource);
}
SDIFileEntry* fileEntry = findPtrResource(resource);
if (!fileEntry) {
return -1;
}
if (!fileEntry->isCompressed()) {
return getResSize(resource);
}
resourceSize = getExpandSize(fileEntry);
if (resourceSize) {
return resourceSize;
}
// The dst pointer to JKRDvdToMainRam should be aligned to 32 bytes. This will align arcHeader
// to 32 bytes on the stack.
char buffer[64];
u8* arcHeader = (u8*)ALIGN_NEXT((u32)buffer, 0x20);
JKRDvdToMainRam(mEntryNum, arcHeader, EXPAND_SWITCH_UNKNOWN2, sizeof(SArcHeader), NULL,
JKRDvdRipper::ALLOC_DIRECTION_FORWARD,
mDataOffset + fileEntry->data_offset, NULL, NULL);
DCInvalidateRange(arcHeader, sizeof(SArcHeader));
resourceSize = JKRDecompExpandSize(arcHeader);
// ???
((JKRDvdArchive*)this)->setExpandSize(fileEntry, resourceSize);
return resourceSize;
}
+149
View File
@@ -0,0 +1,149 @@
#include "JSystem/JKernel/JKRDvdFile.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JUtility/JUTException.h"
/* 8043436C-80434378 06108C 000C+00 4/4 0/0 0/0 .bss sDvdList__10JKRDvdFile */
JSUList<JKRDvdFile> JKRDvdFile::sDvdList;
/* 802D9584-802D95F8 2D3EC4 0074+00 0/0 3/3 0/0 .text __ct__10JKRDvdFileFv */
JKRDvdFile::JKRDvdFile() : mDvdLink(this) {
initiate();
}
/* 802D95F8-802D96A0 2D3F38 00A8+00 0/0 2/2 0/0 .text __ct__10JKRDvdFileFPCc */
JKRDvdFile::JKRDvdFile(const char* name) : mDvdLink(this) {
initiate();
bool result = open(name);
mIsAvailable = result;
// weird code. doesn't match without this, maybe remains from assert or something?
if (mIsAvailable)
return;
else
return;
}
/* 802D96A0-802D9748 2D3FE0 00A8+00 0/0 3/3 0/0 .text __ct__10JKRDvdFileFl */
JKRDvdFile::JKRDvdFile(s32 entryNum) : mDvdLink(this) {
initiate();
bool result = open(entryNum);
mIsAvailable = result;
// weird code. doesn't match without this, maybe remains from assert or something?
if (mIsAvailable)
return;
else
return;
}
/* 802D9748-802D97E4 2D4088 009C+00 1/0 5/5 0/0 .text __dt__10JKRDvdFileFv */
JKRDvdFile::~JKRDvdFile() {
close();
}
/* 802D97E4-802D9850 2D4124 006C+00 3/3 0/0 0/0 .text initiate__10JKRDvdFileFv */
void JKRDvdFile::initiate(void) {
mDvdFile = this;
OSInitMutex(&mMutex1);
OSInitMutex(&mMutex2);
OSInitMessageQueue(&mMessageQueue2, &mMessage2, 1);
OSInitMessageQueue(&mMessageQueue1, &mMessage1, 1);
mOSThread = NULL;
field_0x50 = 0;
field_0x58 = 0;
}
/* 802D9850-802D98C4 2D4190 0074+00 1/0 1/1 0/0 .text open__10JKRDvdFileFPCc */
bool JKRDvdFile::open(const char* name) {
if (!mIsAvailable) {
mIsAvailable = DVDOpen(name, &mFileInfo);
if (mIsAvailable) {
getDvdList().append(&mDvdLink);
getStatus();
}
}
return mIsAvailable;
}
/* 802D98C4-802D9938 2D4204 0074+00 1/0 2/2 0/0 .text open__10JKRDvdFileFl */
bool JKRDvdFile::open(s32 entryNum) {
if (!mIsAvailable) {
mIsAvailable = DVDFastOpen(entryNum, &mFileInfo);
if (mIsAvailable) {
getDvdList().append(&mDvdLink);
getStatus();
}
}
return mIsAvailable;
}
/* 802D9938-802D99B4 2D4278 007C+00 1/0 0/0 0/0 .text close__10JKRDvdFileFv */
void JKRDvdFile::close() {
if (mIsAvailable) {
s32 result = DVDClose(&mFileInfo);
if (result != 0) {
mIsAvailable = false;
getDvdList().remove(&mDvdLink);
} else {
JUTException::panic(__FILE__, 213, "cannot close DVD file\n");
}
}
}
/* 802D99B4-802D9A68 2D42F4 00B4+00 1/0 0/0 0/0 .text readData__10JKRDvdFileFPvll */
s32 JKRDvdFile::readData(void* param_1, s32 length, s32 param_3) {
/* clang-format off */
// The assert condition gets stringified as "( length & 0x1f ) == 0",
// with out disabling clang-format the spaces in the condition will
// get removed and the string will be incorrect.
JUT_ASSERT(238, ( length & 0x1f ) == 0);
/* clang-format on */
OSLockMutex(&mMutex1);
if (mOSThread) {
OSUnlockMutex(&mMutex1);
return -1;
}
mOSThread = OSGetCurrentThread();
s32 result = -1;
s32 readAsyncResult =
DVDReadAsyncPrio(&mFileInfo, param_1, length, param_3, JKRDvdFile::doneProcess, 2);
if (readAsyncResult) {
result = sync();
}
mOSThread = NULL;
OSUnlockMutex(&mMutex1);
return result;
}
/* 802D9A68-802D9A70 2D43A8 0008+00 1/0 0/0 0/0 .text writeData__10JKRDvdFileFPCvll */
s32 JKRDvdFile::writeData(void const* param_0, s32 length, s32 param_2) {
/* clang-format off */
JUT_ASSERT(344, ( length & 0x1f ) == 0);
/* clang-format on */
return -1;
}
/* 802D9A70-802D9AC4 2D43B0 0054+00 1/1 0/0 0/0 .text sync__10JKRDvdFileFv */
s32 JKRDvdFile::sync(void) {
OSMessage message;
OSLockMutex(&mMutex1);
OSReceiveMessage(&mMessageQueue2, &message, 1);
mOSThread = NULL;
OSUnlockMutex(&mMutex1);
return (int)message;
}
/* 802D9AC4-802D9AF8 2D4404 0034+00 1/1 0/0 0/0 .text doneProcess__10JKRDvdFileFlP11DVDFileInfo */
void JKRDvdFile::doneProcess(s32 id, DVDFileInfo* fileInfo) {
// fileInfo->field_0x3c looks like some kind of user pointer?
JKRDvdFile* dvdFile = *(JKRDvdFile**)((u8*)fileInfo + 0x3c);
OSSendMessage(&dvdFile->mMessageQueue2, (OSMessage)id, OS_MESSAGE_NOBLOCK);
}
/* 802D9AF8-802D9B00 2D4438 0008+00 1/0 0/0 0/0 .text getFileSize__10JKRDvdFileCFv */
s32 JKRDvdFile::getFileSize(void) const {
return mFileInfo.length;
}
+563
View File
@@ -0,0 +1,563 @@
//
// JKRDvdRipper
//
#include "JSystem/JKernel/JKRDvdRipper.h"
#include "JSystem/JKernel/JKRDvdFile.h"
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JUtility/JUTException.h"
#include "string.h"
#include "dolphin/os/OSCache.h"
#include "dolphin/os/OSInterrupt.h"
#include "dolphin/vi.h"
static int JKRDecompressFromDVD(JKRDvdFile*, void*, u32, u32, u32, u32, u32*);
static int decompSZS_subroutine(u8*, u8*);
static u8* firstSrcData();
static u8* nextSrcData(u8*);
/* 802D9B98-802D9C54 2D44D8 00BC+00 0/0 1/1 0/0 .text
* loadToMainRAM__12JKRDvdRipperFPCcPUc15JKRExpandSwitchUlP7JKRHeapQ212JKRDvdRipper15EAllocDirectionUlPiPUl
*/
void* JKRDvdRipper::loadToMainRAM(char const* name, u8* dst, JKRExpandSwitch expandSwitch,
u32 dstLength, JKRHeap* heap,
JKRDvdRipper::EAllocDirection allocDirection, u32 offset,
int* pCompression, u32* param_8) {
JKRDvdFile file;
if (!file.open(name)) {
return NULL;
}
return loadToMainRAM(&file, dst, expandSwitch, dstLength, heap, allocDirection, offset,
pCompression, param_8);
}
/* 802D9C54-802D9D10 2D4594 00BC+00 0/0 9/9 0/0 .text
* loadToMainRAM__12JKRDvdRipperFlPUc15JKRExpandSwitchUlP7JKRHeapQ212JKRDvdRipper15EAllocDirectionUlPiPUl
*/
void* JKRDvdRipper::loadToMainRAM(s32 entryNumber, u8* dst, JKRExpandSwitch expandSwitch,
u32 dstLength, JKRHeap* heap,
JKRDvdRipper::EAllocDirection allocDirection, u32 offset,
int* pCompression, u32* param_8) {
JKRDvdFile file;
if (!file.open(entryNumber)) {
return NULL;
}
return loadToMainRAM(&file, dst, expandSwitch, dstLength, heap, allocDirection, offset,
pCompression, param_8);
}
/* 804508C8-804508CC 000348 0004+00 3/2 0/0 0/0 .sdata None */
static u8 errorRetry = 0x01;
/* 802D9D10-802DA1E4 2D4650 04D4+00 2/2 0/0 0/0 .text
* loadToMainRAM__12JKRDvdRipperFP10JKRDvdFilePUc15JKRExpandSwitchUlP7JKRHeapQ212JKRDvdRipper15EAllocDirectionUlPiPUl
*/
void* JKRDvdRipper::loadToMainRAM(JKRDvdFile* dvdFile, u8* dst, JKRExpandSwitch expandSwitch,
u32 dstLength, JKRHeap* heap,
JKRDvdRipper::EAllocDirection allocDirection, u32 offset,
int* pCompression, u32* param_8) {
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 || errorRetry == false)
return NULL;
VIWaitForRetrace();
}
DCInvalidateRange(bufPtr, 0x20);
compression = JKRCheckCompressed_noASR(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)
{
JKRFree(dst);
return NULL;
}
}
}
}
else
{
if (dst == NULL)
{
u32 size = fileSizeAligned - offset;
if ((dstLength != 0) && (size > dstLength))
size = dstLength;
dst = (u8 *)JKRAllocFromHeap(heap, size, 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 || !errorRetry)
{
if (hasAllocated == true)
{
JKRFree(dst);
}
return NULL;
}
VIWaitForRetrace();
}
DCInvalidateRange(bufPtr, 32);
compression2 = JKRCheckCompressed_noASR(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 || !errorRetry)
{
if (hasAllocated == true)
JKRFree(dst);
return NULL;
}
VIWaitForRetrace();
}
if (param_8)
{
*param_8 = size;
}
return dst;
}
else if (compression2 == COMPRESSION_YAZ0)
{
JKRDecompressFromDVD(dvdFile, dst, fileSizeAligned, dstLength, 0, offset, param_8);
} else {
JUTException::panic(__FILE__, 0x143, "Sorry, not applied for SZP archive.");
}
return dst;
}
else if (compression == COMPRESSION_YAY0)
{
// SZP decompression
// s32 readoffset = startOffset;
if (offset != 0)
{
JUTException::panic(__FILE__, 0x14d, "Not support SZP with offset read");
}
while (true)
{
int readBytes = DVDReadPrio(dvdFile->getFileInfo(), mem, fileSizeAligned, 0, 2);
if (readBytes >= 0)
break;
if (readBytes == -3 || !errorRetry)
{
if (hasAllocated == true)
JKRFree(dst);
JKRFree(mem);
return NULL;
}
VIWaitForRetrace();
}
DCInvalidateRange(mem, fileSizeAligned);
JKRDecompress(mem, dst, expandSize, offset);
JKRFree(mem);
if (param_8)
{
*param_8 = expandSize;
}
return dst;
}
else if (compression == COMPRESSION_YAZ0)
{
if (JKRDecompressFromDVD(dvdFile, dst, fileSizeAligned, expandSize, offset, 0, param_8) != 0u)
{
if (hasAllocated)
JKRFree(dst);
dst = NULL;
}
return dst;
}
else if (hasAllocated)
{
JKRFree(dst);
dst = NULL;
}
return NULL;
}
/* ############################################################################################## */
/* 80434378-80434384 061098 000C+00 1/1 0/0 0/0 .bss @491 */
static u8 lit_491[12];
/* 80434384-80434390 0610A4 000C+00 1/1 0/0 0/0 .bss sDvdAsyncList__12JKRDvdRipper */
JSUList<JKRDMCommand> JKRDvdRipper::sDvdAsyncList;
/* 80434390-804343A8 0610B0 0018+00 1/1 0/0 0/0 .bss decompMutex */
static OSMutex decompMutex;
/* 804508CC-804508D0 00034C 0004+00 1/1 1/1 0/0 .sdata sSZSBufferSize__12JKRDvdRipper */
u32 JKRDvdRipper::sSZSBufferSize = 0x00000400;
/* 80451428-8045142C 000928 0004+00 3/3 0/0 0/0 .sbss szpBuf */
static u8* szpBuf;
/* 8045142C-80451430 00092C 0004+00 3/3 0/0 0/0 .sbss szpEnd */
static u8* szpEnd;
/* 80451430-80451434 000930 0004+00 2/2 0/0 0/0 .sbss refBuf */
static u8* refBuf;
/* 80451434-80451438 000934 0004+00 2/2 0/0 0/0 .sbss refEnd */
static u8* refEnd;
/* 80451438-8045143C 000938 0004+00 2/2 0/0 0/0 .sbss refCurrent */
static u8* refCurrent;
/* 8045143C-80451440 00093C 0004+00 3/3 0/0 0/0 .sbss srcOffset */
static u32 srcOffset;
/* 80451440-80451444 000940 0004+00 4/4 0/0 0/0 .sbss transLeft */
static u32 transLeft;
/* 80451444-80451448 000944 0004+00 3/3 0/0 0/0 .sbss srcLimit */
static u8* srcLimit;
/* 80451448-8045144C 000948 0004+00 3/3 0/0 0/0 .sbss srcFile */
static JKRDvdFile* srcFile;
/* 8045144C-80451450 00094C 0004+00 2/2 0/0 0/0 .sbss fileOffset */
static u32 fileOffset;
/* 80451450-80451454 000950 0004+00 2/2 0/0 0/0 .sbss readCount */
static u32 readCount;
/* 80451454-80451458 000954 0004+00 2/2 0/0 0/0 .sbss maxDest */
static u32 maxDest;
/* 80451458-8045145C 000958 0004+00 1/1 0/0 0/0 .sbss None */
static bool data_80451458;
/* 8045145C-80451460 00095C 0004+00 2/2 0/0 0/0 .sbss tsPtr */
static u32* tsPtr;
/* 80451460-80451468 000960 0004+04 1/1 0/0 0/0 .sbss tsArea */
static u32 tsArea;
/* 802DA1E4-802DA35C 2D4B24 0178+00 1/1 0/0 0/0 .text
* JKRDecompressFromDVD__FP10JKRDvdFilePvUlUlUlUlPUl */
static int JKRDecompressFromDVD(JKRDvdFile* dvdFile, void* dst, u32 fileSize, u32 inMaxDest,
u32 inFileOffset, u32 inSrcOffset, u32* inTsPtr) {
BOOL interrupts = OSDisableInterrupts();
if (data_80451458 == false)
{
OSInitMutex(&decompMutex);
data_80451458 = true;
}
OSRestoreInterrupts(interrupts);
OSLockMutex(&decompMutex);
int bufSize = JKRDvdRipper::getSZSBufferSize();
szpBuf = (u8 *)JKRAllocFromSysHeap(bufSize, -0x20);
szpEnd = szpBuf + bufSize;
if (inFileOffset != 0)
{
refBuf = (u8 *)JKRAllocFromSysHeap(0x1120, -4);
refEnd = refBuf + 0x1120;
refCurrent = refBuf;
}
else
{
refBuf = NULL;
}
srcFile = dvdFile;
srcOffset = inSrcOffset;
transLeft = fileSize - inSrcOffset;
fileOffset = inFileOffset;
readCount = 0;
maxDest = inMaxDest;
if (!inTsPtr)
{
tsPtr = &tsArea;
}
else
{
tsPtr = inTsPtr;
}
*tsPtr = 0;
u8 *data = firstSrcData();
u32 result = (data != NULL) ? decompSZS_subroutine(data, (u8 *)dst) : -1; // figure out correct datatypes
JKRFree(szpBuf);
if (refBuf)
{
JKRFree(refBuf);
}
DCStoreRangeNoSync(dst, *tsPtr);
OSUnlockMutex(&decompMutex);
return result;
}
/* 802DA35C-802DA60C 2D4C9C 02B0+00 1/1 0/0 0/0 .text decompSZS_subroutine__FPUcPUc */
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);
*tsPtr = ts;
return 0;
}
/* 802DA60C-802DA6D8 2D4F4C 00CC+00 1/1 0/0 0/0 .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->getFileInfo(), buffer, length, srcOffset, 2);
if (result >= 0) {
break;
}
if (result == -3 || !errorRetry) {
return NULL;
}
VIWaitForRetrace();
}
DCInvalidateRange(buffer, length);
srcOffset += length;
transLeft -= length;
return buffer;
}
/* 802DA6D8-802DA7D4 2D5018 00FC+00 1/1 0/0 0/0 .text nextSrcData__FPUc */
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;
memcpy(buf, src, limit);
u32 transSize = (u32)(szpEnd - (buf + limit));
if (transSize > transLeft)
transSize = transLeft;
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();
}
DCInvalidateRange((buf + limit), transSize);
srcOffset += transSize;
transLeft -= transSize;
if (transLeft == 0)
srcLimit = transSize + (buf + limit);
return buf;
}
/* 802DA7D4-802DA7DC -00001 0008+00 0/0 0/0 0/0 .text isErrorRetry__12JKRDvdRipperFv */
u8 JKRDvdRipper::isErrorRetry() {
return errorRetry;
}
File diff suppressed because it is too large Load Diff
+13
View File
@@ -0,0 +1,13 @@
#include "JSystem/JKernel/JKRFile.h"
#include "dolphin/vi.h"
/* 802D9518-802D9584 2D3E58 006C+00 0/0 2/2 0/0 .text read__7JKRFileFPvll */
s32 JKRFile::read(void* data, s32 size, s32 offset) {
while (true) {
s32 result = readData(data, size, offset);
if (size != result)
VIWaitForRetrace();
else
return result;
}
}
+431
View File
@@ -0,0 +1,431 @@
#include "JSystem/JKernel/JKRFileCache.h"
#include "JSystem/JKernel/JKRDvdFile.h"
#include "JSystem/JKernel/JKRFileFinder.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "ctype.h"
#include "string.h"
#include "global.h"
/* 802D49B4-802D4AB4 2CF2F4 0100+00 0/0 2/2 0/0 .text mount__12JKRFileCacheFPCcP7JKRHeapPCc */
JKRFileCache* JKRFileCache::mount(const char* path, JKRHeap* heap, const char* param_3) {
if (!path || *path != '/') {
return NULL;
}
u32 pathLength = strlen(path);
if (pathLength != 1 && path[pathLength - 1] == '/') {
return NULL;
}
JSUList<JKRFileLoader>& volumeList = getVolumeList();
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
if (iterator->getVolumeType() == 'CASH') {
JKRFileCache* fileCache = (JKRFileCache*)iterator.getObject();
if (fileCache->mRootPath) {
if (strcmp(fileCache->mRootPath, path) == 0) {
fileCache->mMountCount++;
return fileCache;
}
}
}
}
return new (heap, 0) JKRFileCache(path, param_3);
}
/* 802D4AB4-802D4C70 2CF3F4 01BC+00 1/1 0/0 0/0 .text __ct__12JKRFileCacheFPCcPCc */
JKRFileCache::JKRFileCache(const char* path, const char* volume) {
mParentHeap = JKRHeap::findFromRoot(this);
mMountCount = 1;
mVolumeType = 'CASH';
u32 pathLength = strlen(path);
mRootPath = (char*)JKRAllocFromHeap(mParentHeap, pathLength + 1, 1);
mCurrentPath = (char*)JKRAllocFromSysHeap(pathLength + 2, 1);
strcpy(mRootPath, path);
strcpy(mCurrentPath, path);
if (path[1] != '\0') {
convStrLower(mRootPath);
convStrLower(mCurrentPath);
strcat(mCurrentPath, "/");
const char* volumePath = volume;
if (!volume) {
volumePath = strrchr(mRootPath, '/');
volumePath++;
}
u32 volumeLength = strlen(volumePath) + 1;
mVolumePath = (char*)JKRAllocFromSysHeap(volumeLength, 0);
strcpy(mVolumePath, volumePath);
convStrLower(mVolumePath);
mVolumeName = mVolumePath;
} else {
const char* volumePath = volume;
if (!volume) {
volumePath = "dvd";
}
u32 volumeLength = strlen(volumePath) + 1;
mVolumePath = (char*)JKRAllocFromSysHeap(volumeLength, 0);
strcpy(mVolumePath, volumePath);
convStrLower(mVolumePath);
mVolumeName = mVolumePath;
}
getVolumeList().prepend(&mFileLoaderLink);
mIsMounted = true;
}
/* 802D4C70-802D4D44 2CF5B0 00D4+00 1/0 0/0 0/0 .text __dt__12JKRFileCacheFv */
JKRFileCache::~JKRFileCache() {
removeResourceAll();
if (mRootPath)
JKRFreeToHeap(mParentHeap, mRootPath);
if (mCurrentPath)
JKRFreeToSysHeap(mCurrentPath);
if (mVolumePath)
JKRFreeToSysHeap(mVolumePath);
getVolumeList().remove(&mFileLoaderLink);
}
/* 802D4D44-802D4DD8 2CF684 0094+00 1/0 0/0 0/0 .text becomeCurrent__12JKRFileCacheFPCc
*/
bool JKRFileCache::becomeCurrent(const char* path) {
char* dvdPathName = getDvdPathName(path);
bool result = DVDChangeDir(dvdPathName);
if (result) {
sCurrentVolume = this;
JKRHeap::sSystemHeap->free(mCurrentPath);
mCurrentPath = dvdPathName;
if (mCurrentPath[1] != '\0') {
strcat(mCurrentPath, "/");
}
} else {
JKRHeap::sSystemHeap->free(dvdPathName);
}
return result;
}
/* 802D4DD8-802D4EDC 2CF718 0104+00 1/0 0/0 0/0 .text getResource__12JKRFileCacheFPCc */
void* JKRFileCache::getResource(const char* path) {
JUT_ASSERT(237, isMounted());
void* buffer = NULL;
char* name = getDvdPathName(path);
JKRDvdFile dvdFile(name);
if (dvdFile.isAvailable()) {
CCacheBlock* cacheBlock = findCacheBlock(dvdFile.getFileID());
if (!cacheBlock) {
u32 fileSize = dvdFile.getFileInfo()->length;
u32 alignedSize = ALIGN_NEXT(fileSize, 0x20);
buffer = JKRAllocFromHeap(mParentHeap, alignedSize, 0x20);
if (buffer) {
dvdFile.read(buffer, alignedSize, 0);
cacheBlock = new (JKRHeap::getSystemHeap(), 0)
CCacheBlock(dvdFile.getFileID(), dvdFile.getFileInfo()->length, buffer);
mCacheBlockList.append(&cacheBlock->mCacheBlockLink);
}
} else {
cacheBlock->mReferenceCount++;
buffer = cacheBlock->mMemoryPtr;
}
}
JKRFreeToSysHeap(name);
return buffer;
}
/* 802D4EDC-802D4F64 2CF81C 0088+00 1/0 0/0 0/0 .text getResource__12JKRFileCacheFUlPCc
*/
void* JKRFileCache::getResource(u32, const char* path) {
JUT_ASSERT(303, isMounted());
char finalPath[256];
u32 rootLength = strlen(mRootPath);
char* filePath = finalPath + rootLength;
strcpy(finalPath, mRootPath);
bool found = findFile(finalPath, path);
if (!found)
return NULL;
return getResource(filePath);
}
/* 802D4F64-802D503C 2CF8A4 00D8+00 1/0 0/0 0/0 .text readResource__12JKRFileCacheFPvUlPCc */
u32 JKRFileCache::readResource(void* dst, u32 dstLength, const char* path) {
JUT_ASSERT(412, isMounted());
char* name = getDvdPathName(path);
JKRDvdFile dvdFile(name);
u32 resourceSize = 0;
// !@bug: (maybe?) Infinite Loop: Because dvdFile.isAvailable() is never updated in the loop-body
// will would never exit the loop.
while (true) {
if (!dvdFile.isAvailable()) {
break;
}
u32 fileSize = dvdFile.getFileInfo()->length;
resourceSize = ALIGN_NEXT(fileSize, 0x20);
dstLength = ALIGN_PREV(dstLength, 0x20);
if (resourceSize > dstLength) {
resourceSize = dstLength;
}
CCacheBlock* cacheBlock = findCacheBlock(dvdFile.getFileID());
if (!cacheBlock) {
dvdFile.read(dst, resourceSize, 0);
} else {
memcpy(dst, cacheBlock->mMemoryPtr, resourceSize);
}
}
JKRFreeToSysHeap(name);
return resourceSize;
}
/* 802D503C-802D50D4 2CF97C 0098+00 1/0 0/0 0/0 .text readResource__12JKRFileCacheFPvUlUlPCc */
u32 JKRFileCache::readResource(void* dst, u32 dstLength, u32, const char* path) {
JUT_ASSERT(344, isMounted());
char finalPath[256];
u32 rootLength = strlen(mRootPath);
char* filePath = finalPath + rootLength;
strcpy(finalPath, mRootPath);
bool found = findFile(finalPath, path);
if (!found)
return NULL;
return readResource(dst, dstLength, filePath);
}
/* 802D50D4-802D5164 2CFA14 0090+00 1/0 0/0 0/0 .text removeResourceAll__12JKRFileCacheFv
*/
void JKRFileCache::removeResourceAll(void) {
JUT_ASSERT(412, isMounted());
JSUListIterator<CCacheBlock> iterator;
iterator = mCacheBlockList.getFirst();
while (iterator != mCacheBlockList.getEnd()) {
JKRFreeToHeap(mParentHeap, iterator->mMemoryPtr);
mCacheBlockList.remove(&iterator.getObject()->mCacheBlockLink);
CCacheBlock* cacheBlock = (iterator++).getObject();
delete cacheBlock;
}
}
/* 802D5164-802D51F8 2CFAA4 0094+00 1/0 0/0 0/0 .text removeResource__12JKRFileCacheFPv
*/
bool JKRFileCache::removeResource(void* resource) {
JUT_ASSERT(463, isMounted());
CCacheBlock* cacheBlock = findCacheBlock(resource);
if (!cacheBlock)
return false;
u32 referenceCount = cacheBlock->mReferenceCount - 1;
cacheBlock->mReferenceCount = referenceCount;
if (referenceCount == 0) {
JKRFreeToHeap(mParentHeap, resource);
mCacheBlockList.remove(&cacheBlock->mCacheBlockLink);
delete cacheBlock;
}
return true;
}
/* 802D51F8-802D526C 2CFB38 0074+00 1/0 0/0 0/0 .text detachResource__12JKRFileCacheFPv
*/
bool JKRFileCache::detachResource(void* resource) {
JUT_ASSERT(490, isMounted());
CCacheBlock* cacheBlock = findCacheBlock(resource);
if (!cacheBlock)
return false;
mCacheBlockList.remove(&cacheBlock->mCacheBlockLink);
delete cacheBlock;
return true;
}
/* 802D526C-802D52A0 2CFBAC 0034+00 1/0 0/0 0/0 .text getResSize__12JKRFileCacheCFPCv */
u32 JKRFileCache::getResSize(const void* resource) const {
CCacheBlock* cacheBlock = findCacheBlock(resource);
if (cacheBlock == NULL) {
return -1;
} else {
return cacheBlock->mFileSize;
}
}
/* 802D52A0-802D531C 2CFBE0 007C+00 1/0 0/0 0/0 .text countFile__12JKRFileCacheCFPCc */
u32 JKRFileCache::countFile(const char* path) const {
DVDDirectory dir;
DVDDirectoryEntry dirEntry;
u32 count = 0;
char* name = getDvdPathName(path);
BOOL result = DVDOpenDir(name, &dir);
if (result != 0) {
while (result = DVDReadDir(&dir, &dirEntry), result != FALSE) {
count = count + 1;
}
DVDCloseDir(&dir);
}
JKRFreeToSysHeap(name);
return count;
}
/* 802D531C-802D53B8 2CFC5C 009C+00 1/0 0/0 0/0 .text getFirstFile__12JKRFileCacheCFPCc
*/
JKRFileFinder* JKRFileCache::getFirstFile(const char* path) const {
char* name = getDvdPathName(path);
JKRHeap* systemHeap = JKRHeap::getSystemHeap();
JKRDvdFinder* finder = new (systemHeap, 0) JKRDvdFinder(name);
JKRFreeToSysHeap(name);
if (finder->isAvailable() != true) {
delete finder;
return NULL;
}
return finder;
}
/* 802D53B8-802D53E4 2CFCF8 002C+00 3/3 0/0 0/0 .text findCacheBlock__12JKRFileCacheCFPCv
*/
JKRFileCache::CCacheBlock* JKRFileCache::findCacheBlock(const void* resource) const {
JSUListIterator<CCacheBlock> iterator;
for (iterator = mCacheBlockList.getFirst(); iterator != mCacheBlockList.getEnd(); ++iterator) {
if (iterator->mMemoryPtr == resource) {
return iterator.getObject();
}
}
return NULL;
}
/* 802D53E4-802D5410 2CFD24 002C+00 2/2 0/0 0/0 .text findCacheBlock__12JKRFileCacheCFUl
*/
JKRFileCache::CCacheBlock* JKRFileCache::findCacheBlock(u32 fileID) const {
JSUListIterator<CCacheBlock> iterator;
for (iterator = mCacheBlockList.getFirst(); iterator != mCacheBlockList.getEnd(); ++iterator) {
if (iterator->mFileId == fileID) {
return iterator.getObject();
}
}
return NULL;
}
/* 802D5410-802D551C 2CFD50 010C+00 2/2 0/0 0/0 .text findFile__12JKRFileCacheCFPcPCc */
bool JKRFileCache::findFile(char* path, const char* fileName) const {
DVDDirectory dir;
DVDDirectoryEntry dirEntry;
bool result = false;
u32 pathLength = strlen(path);
if (DVDOpenDir(path, &dir)) {
while (DVDReadDir(&dir, &dirEntry)) {
if (dirEntry.is_directory) {
char* endOfPath = path + pathLength;
*endOfPath = '/';
strcpy(path + pathLength + 1, dirEntry.name);
result = findFile(path, fileName);
if (result)
break;
*endOfPath = '\0';
} else {
result = (strcmp(fileName, dirEntry.name) == 0);
if (result) {
strcat(path, "/");
strcat(path, fileName);
break;
}
}
}
DVDCloseDir(&dir);
}
return result;
}
/* 802D551C-802D5624 2CFE5C 0108+00 5/5 0/0 0/0 .text getDvdPathName__12JKRFileCacheCFPCc
*/
char* JKRFileCache::getDvdPathName(const char* path) const {
char* newPath;
if (path[0] == '/') {
u32 length = strlen(mRootPath) + strlen(path) + 2;
newPath = (char*)JKRAllocFromSysHeap(length, 1);
strcpy(newPath, mRootPath);
if (path[1]) {
if (mRootPath[1] == 0) {
strcat(newPath, path + 1);
} else {
strcat(newPath, path);
}
}
} else {
u32 length = strlen(mCurrentPath) + strlen(path) + 2;
newPath = (char*)JKRAllocFromSysHeap(length, 1);
strcpy(newPath, mCurrentPath);
strcat(newPath, path);
}
convStrLower(newPath);
return newPath;
}
/* 802D5624-802D566C 2CFF64 0048+00 2/2 0/0 0/0 .text convStrLower__12JKRFileCacheCFPc */
void JKRFileCache::convStrLower(char* buffer) const {
while (*buffer) {
*buffer++ = tolower(*buffer);
}
}
/* 802D566C-802D56C8 2CFFAC 005C+00 1/1 0/0 0/0 .text __ct__Q212JKRFileCache11CCacheBlockFUlUlPCv
*/
JKRFileCache::CCacheBlock::CCacheBlock(u32 fileId, u32 fileSize, const void* resource)
: mCacheBlockLink(this) {
mReferenceCount = 1;
mFileId = fileId;
mFileSize = fileSize;
mMemoryPtr = (void*)resource; // todo: don't cast away const
}
/* 802D56C8-802D56F4 2D0008 002C+00 1/0 0/0 0/0 .text getFsResource__12JKRFileCacheFPCc
*/
void* JKRFileCache::getFsResource(const char* path) {
return getResource(path);
}
/* 802D56F4-802D5720 2D0034 002C+00 1/0 0/0 0/0 .text getNameResource__12JKRFileCacheFUlPCc */
void* JKRFileCache::getNameResource(u32 type, const char* path) {
return getResource(type, path);
}
/* 802D5720-802D574C 2D0060 002C+00 1/0 0/0 0/0 .text readFsResource__12JKRFileCacheFPvUlPCc */
u32 JKRFileCache::readFsResource(void* dst, u32 dstLength, const char* path) {
return readResource(dst, dstLength, path);
}
/* 802D574C-802D5778 2D008C 002C+00 1/0 0/0 0/0 .text readNameResource__12JKRFileCacheFPvUlUlPCc
*/
u32 JKRFileCache::readNameResource(void* dst, u32 dstLength, u32 type, const char* path) {
return readResource(dst, dstLength, type, path);
}
+70
View File
@@ -0,0 +1,70 @@
#include "JSystem/JKernel/JKRFileFinder.h"
#include "JSystem/JKernel/JKRArchive.h"
/* 802D4638-802D46C4 2CEF78 008C+00 0/0 1/1 0/0 .text __ct__12JKRArcFinderFP10JKRArchivell */
JKRArcFinder::JKRArcFinder(JKRArchive* archive, s32 startIndex, s32 numEntries) : JKRFileFinder() {
mArchive = archive;
mIsAvailable = numEntries > 0;
mStartIndex = startIndex;
mEndIndex = startIndex + numEntries - 1;
mNextIndex = mStartIndex;
findNextFile();
}
/* 802D46C4-802D4770 2CF004 00AC+00 1/0 0/0 0/0 .text findNextFile__12JKRArcFinderFv */
bool JKRArcFinder::findNextFile(void) {
JKRArchive::SDirEntry entry;
if (mIsAvailable) {
mIsAvailable = !(mNextIndex > mEndIndex);
if (mIsAvailable) {
mIsAvailable = mArchive->getDirEntry(&entry, mNextIndex);
mEntryName = entry.name;
mEntryFileIndex = mNextIndex;
mEntryId = entry.id;
mEntryTypeFlags = entry.flags;
mIsFileOrDirectory = (mEntryTypeFlags >> 1) & 1;
mNextIndex++;
}
}
return mIsAvailable;
}
/* 802D4770-802D47F4 2CF0B0 0084+00 0/0 1/1 0/0 .text __ct__12JKRDvdFinderFPCc */
JKRDvdFinder::JKRDvdFinder(const char* directory) : JKRFileFinder() {
mDvdIsOpen = DVDOpenDir(directory, &mDvdDirectory);
mIsAvailable = mDvdIsOpen;
findNextFile();
}
/* 802D47F4-802D4874 2CF134 0080+00 1/0 0/0 0/0 .text __dt__12JKRDvdFinderFv */
JKRDvdFinder::~JKRDvdFinder() {
if (mDvdIsOpen) {
DVDCloseDir(&mDvdDirectory);
}
}
/* 802D4874-802D4910 2CF1B4 009C+00 1/0 0/0 0/0 .text findNextFile__12JKRDvdFinderFv */
bool JKRDvdFinder::findNextFile(void) {
if (mIsAvailable) {
DVDDirectoryEntry directoryEntry;
mIsAvailable = DVDReadDir(&mDvdDirectory, &directoryEntry);
if (mIsAvailable) {
mIsFileOrDirectory = directoryEntry.is_directory != 0;
mEntryName = directoryEntry.name;
mEntryFileIndex = directoryEntry.entry_number;
mEntryId = 0;
// only matches with enum
// TODO: placeholder
enum EntryTypeFlags {
EntryTypeFlags1 = 1,
EntryTypeFlags2 = 2,
};
mEntryTypeFlags = mIsFileOrDirectory ? EntryTypeFlags2 : EntryTypeFlags1;
}
}
return mIsAvailable;
}
+162
View File
@@ -0,0 +1,162 @@
#include "JSystem/JKernel/JKRFileLoader.h"
#include "string.h"
#include "ctype.h"
#include "global.h"
/* ############################################################################################## */
/* 80451418-80451420 000918 0004+04 2/2 3/3 0/0 .sbss sCurrentVolume__13JKRFileLoader */
JKRFileLoader* JKRFileLoader::sCurrentVolume;
/* 80434354-80434360 061074 000C+00 5/5 14/14 0/0 .bss sVolumeList__13JKRFileLoader */
JSUList<JKRFileLoader> JKRFileLoader::sVolumeList;
/* 802D40F0-802D4148 2CEA30 0058+00 0/0 2/2 0/0 .text __ct__13JKRFileLoaderFv */
JKRFileLoader::JKRFileLoader(void)
: mFileLoaderLink(this), mVolumeName(NULL), mVolumeType(0), mMountCount(0) {}
/* 802D4148-802D41D4 2CEA88 008C+00 1/0 2/2 0/0 .text __dt__13JKRFileLoaderFv */
JKRFileLoader::~JKRFileLoader() {
if (getCurrentVolume() == this) {
setCurrentVolume(NULL);
}
}
/* 802D41D4-802D4224 2CEB14 0050+00 1/0 6/0 0/0 .text unmount__13JKRFileLoaderFv */
void JKRFileLoader::unmount(void) {
s32 count = mMountCount;
if (mMountCount != 0) {
count--;
mMountCount = count;
if (count == 0) {
delete this;
}
}
}
/* 802D4224-802D4270 2CEB64 004C+00 0/0 2/2 0/0 .text getGlbResource__13JKRFileLoaderFPCc
*/
void* JKRFileLoader::getGlbResource(const char* name) {
const char* name_reference[1];
name_reference[0] = name;
JKRFileLoader* fileLoader = findVolume(name_reference);
void* resource;
if (fileLoader == NULL) {
resource = NULL;
} else {
resource = fileLoader->getResource(name_reference[0]);
}
return resource;
}
/* 802D4270-802D4308 2CEBB0 0098+00 0/0 29/29 1/1 .text
* getGlbResource__13JKRFileLoaderFPCcP13JKRFileLoader */
void* JKRFileLoader::getGlbResource(const char* name, JKRFileLoader* fileLoader) {
void* resource = NULL;
if (fileLoader) {
return fileLoader->getResource(0, name);
}
JSUList<JKRFileLoader>& volumeList = getVolumeList();
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
resource = iterator->getResource(0, name);
if (resource)
break;
}
return resource;
}
/* 802D4308-802D43A0 2CEC48 0098+00 0/0 1/1 0/0 .text
* removeResource__13JKRFileLoaderFPvP13JKRFileLoader */
bool JKRFileLoader::removeResource(void* resource, JKRFileLoader* fileLoader) {
if (fileLoader) {
return fileLoader->removeResource(resource);
}
JSUList<JKRFileLoader>& volumeList = getVolumeList();
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
if (iterator->removeResource(resource)) {
return true;
}
}
return false;
}
/* 802D43A0-802D4438 2CECE0 0098+00 0/0 2/2 0/0 .text
* detachResource__13JKRFileLoaderFPvP13JKRFileLoader */
bool JKRFileLoader::detachResource(void* resource, JKRFileLoader* fileLoader) {
if (fileLoader) {
return fileLoader->detachResource(resource);
}
JSUList<JKRFileLoader>& volumeList = getVolumeList();
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
if (iterator->detachResource(resource)) {
return true;
}
}
return false;
}
/* 802D4438-802D44C4 2CED78 008C+00 1/1 0/0 0/0 .text findVolume__13JKRFileLoaderFPPCc */
JKRFileLoader* JKRFileLoader::findVolume(const char** volumeName) {
if (*volumeName[0] != '/') {
return getCurrentVolume();
}
char volumeNameBuffer[0x101];
*volumeName = fetchVolumeName(volumeNameBuffer, ARRAY_SIZE(volumeNameBuffer), *volumeName);
JSUList<JKRFileLoader>& volumeList = getVolumeList();
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
if (strcmp(volumeNameBuffer, iterator->mVolumeName) == 0) {
return iterator.getObject();
}
}
return NULL;
}
/* ############################################################################################## */
/* 804508C0-804508C8 000340 0002+06 1/1 0/0 0/0 .sdata rootPath$2498 */
static char rootPath[2] = "/";
/* 802D44C4-802D45A0 2CEE04 00DC+00 1/1 0/0 0/0 .text fetchVolumeName__13JKRFileLoaderFPclPCc */
const char* JKRFileLoader::fetchVolumeName(char* buffer, s32 bufferSize, const char* path) {
if (strcmp(path, "/") == 0) {
strcpy(buffer, rootPath);
return rootPath;
}
path++;
while (*path != 0 && *path != '/') {
if (1 < bufferSize) {
int lower_char;
int ch = (int)*path;
if (ch == -1) {
lower_char = -1;
} else {
lower_char = __lower_map[ch & 0xFF];
}
*buffer = lower_char;
buffer++;
bufferSize--;
}
path++;
}
*buffer = '\0';
if (*path == '\0') {
path = rootPath;
}
return path;
}
+510
View File
@@ -0,0 +1,510 @@
/**
* JKRHeap.cpp
* JSystem Heap Framework
*/
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JUtility/JUTException.h"
/* 80451370-80451374 000870 0004+00 3/3 44/44 0/0 .sbss sSystemHeap__7JKRHeap */
JKRHeap* JKRHeap::sSystemHeap;
/* 80451374-80451378 000874 0004+00 4/4 23/22 0/0 .sbss sCurrentHeap__7JKRHeap */
JKRHeap* JKRHeap::sCurrentHeap;
/* 80451378-8045137C 000878 0004+00 3/3 10/10 0/0 .sbss sRootHeap__7JKRHeap */
JKRHeap* JKRHeap::sRootHeap;
#ifdef DEBUG
JKRHeap* JKRHeap::sRootHeap2;
#endif
/* 8045137C-80451380 00087C 0004+00 2/2 3/3 0/0 .sbss mErrorHandler__7JKRHeap */
JKRErrorHandler JKRHeap::mErrorHandler;
/* 80451380-80451384 000880 0004+00 1/1 0/0 0/0 .sbss None */
static bool data_80451380;
/* 802CE138-802CE264 2C8A78 012C+00 0/0 3/3 0/0 .text __ct__7JKRHeapFPvUlP7JKRHeapb */
JKRHeap::JKRHeap(void* data, u32 size, JKRHeap* parent, bool errorFlag)
: JKRDisposer(), mChildTree(this), mDisposerList() {
OSInitMutex(&mMutex);
mSize = size;
mStart = (u8*)data;
mEnd = (u8*)data + size;
if (parent == NULL) {
becomeSystemHeap();
becomeCurrentHeap();
} else {
parent->mChildTree.appendChild(&mChildTree);
if (getSystemHeap() == getRootHeap()) {
becomeSystemHeap();
}
if (getCurrentHeap() == getRootHeap()) {
becomeCurrentHeap();
}
}
mErrorFlag = errorFlag;
if (mErrorFlag == true && mErrorHandler == NULL) {
mErrorHandler = JKRDefaultMemoryErrorRoutine;
}
mDebugFill = data_804508B0;
mCheckMemoryFilled = data_80451380;
mInitFlag = false;
}
/* 802CE264-802CE378 2C8BA4 0114+00 1/0 3/3 0/0 .text __dt__7JKRHeapFv */
JKRHeap::~JKRHeap() {
mChildTree.getParent()->removeChild(&mChildTree);
JSUTree<JKRHeap>* nextRootHeap = sRootHeap->mChildTree.getFirstChild();
if (sCurrentHeap == this) {
sCurrentHeap = !nextRootHeap ? sRootHeap : nextRootHeap->getObject();
}
if (sSystemHeap == this) {
sSystemHeap = !nextRootHeap ? sRootHeap : nextRootHeap->getObject();
}
}
/* ############################################################################################## */
/* 80451384-80451388 000884 0004+00 1/1 1/1 0/0 .sbss mCodeStart__7JKRHeap */
void* JKRHeap::mCodeStart;
/* 80451388-8045138C 000888 0004+00 1/1 1/1 0/0 .sbss mCodeEnd__7JKRHeap */
void* JKRHeap::mCodeEnd;
/* 8045138C-80451390 00088C 0004+00 1/1 1/1 0/0 .sbss mUserRamStart__7JKRHeap */
void* JKRHeap::mUserRamStart;
/* 80451390-80451394 000890 0004+00 1/1 1/1 0/0 .sbss mUserRamEnd__7JKRHeap */
void* JKRHeap::mUserRamEnd;
/* 80451394-80451398 000894 0004+00 1/1 2/2 0/0 .sbss mMemorySize__7JKRHeap */
u32 JKRHeap::mMemorySize;
/* 802CE378-802CE428 2C8CB8 00B0+00 0/0 1/1 0/0 .text initArena__7JKRHeapFPPcPUli */
bool JKRHeap::initArena(char** memory, u32* size, int maxHeaps) {
void* ram_start;
void* ram_end;
void* arenaStart;
void* arenaLo = OSGetArenaLo();
void* arenaHi = OSGetArenaHi();
if (arenaLo == arenaHi)
return false;
arenaStart = OSInitAlloc(arenaLo, arenaHi, maxHeaps);
ram_start = (void*)ALIGN_NEXT((u32)arenaStart, 0x20);
ram_end = (void*)ALIGN_PREV((u32)arenaHi, 0x20);
GLOBAL_MEMORY* codeStart = (GLOBAL_MEMORY*)OSPhysicalToCached(0);
mCodeStart = codeStart;
mCodeEnd = ram_start;
mUserRamStart = ram_start;
mUserRamEnd = ram_end;
mMemorySize = codeStart->memory_size;
OSSetArenaLo(ram_end);
OSSetArenaHi(ram_end);
*memory = (char*)ram_start;
*size = (u32)ram_end - (u32)ram_start;
return true;
}
/* 802CE428-802CE438 2C8D68 0010+00 1/1 0/0 0/0 .text becomeSystemHeap__7JKRHeapFv */
JKRHeap* JKRHeap::becomeSystemHeap() {
JKRHeap* prev = sSystemHeap;
sSystemHeap = this;
return prev;
}
/* 802CE438-802CE448 2C8D78 0010+00 1/1 22/22 1/1 .text becomeCurrentHeap__7JKRHeapFv */
JKRHeap* JKRHeap::becomeCurrentHeap() {
JKRHeap* prev = sCurrentHeap;
sCurrentHeap = this;
return prev;
}
/* 802CE448-802CE474 2C8D88 002C+00 0/0 5/5 1/1 .text destroy__7JKRHeapFv */
void JKRHeap::destroy() {
do_destroy();
}
/* 802CE474-802CE4D4 2C8DB4 0060+00 6/6 23/23 0/0 .text alloc__7JKRHeapFUliP7JKRHeap */
void* JKRHeap::alloc(u32 size, int alignment, JKRHeap* heap) {
if (heap != NULL) {
return heap->alloc(size, alignment);
}
if (sCurrentHeap != NULL) {
return sCurrentHeap->alloc(size, alignment);
}
return NULL;
}
/* 802CE4D4-802CE500 2C8E14 002C+00 1/1 30/30 1/1 .text alloc__7JKRHeapFUli */
void* JKRHeap::alloc(u32 size, int alignment) {
if (mInitFlag) {
JUT_WARN(393, "alloc %x byte in heap %x", size, this);
}
return do_alloc(size, alignment);
}
/* 802CE500-802CE548 2C8E40 0048+00 2/2 38/38 1/1 .text free__7JKRHeapFPvP7JKRHeap */
void JKRHeap::free(void* ptr, JKRHeap* heap) {
if (!heap) {
heap = findFromRoot(ptr);
if (!heap)
return;
}
heap->free(ptr);
}
/* 802CE548-802CE574 2C8E88 002C+00 1/1 29/29 0/0 .text free__7JKRHeapFPv */
void JKRHeap::free(void* ptr) {
if (mInitFlag) {
JUT_WARN(441, "free %x in heap %x", ptr, this);
}
do_free(ptr);
}
/* 802CE574-802CE5CC 2C8EB4 0058+00 1/0 5/2 0/0 .text callAllDisposer__7JKRHeapFv */
void JKRHeap::callAllDisposer() {
JSUListIterator<JKRDisposer> iterator;
while ((iterator = mDisposerList.getFirst()) != mDisposerList.getEnd()) {
iterator->~JKRDisposer();
}
}
/* 802CE5CC-802CE5F8 2C8F0C 002C+00 0/0 12/12 0/0 .text freeAll__7JKRHeapFv */
void JKRHeap::freeAll() {
if (mInitFlag) {
JUT_WARN(493, "freeAll in heap %x", this);
}
do_freeAll();
}
/* 802CE5F8-802CE624 2C8F38 002C+00 0/0 1/1 0/0 .text freeTail__7JKRHeapFv */
void JKRHeap::freeTail() {
if (mInitFlag) {
JUT_WARN(507, "freeTail in heap %x", this);
}
do_freeTail();
}
/* 802CE624-802CE684 2C8F64 0060+00 0/0 1/1 0/0 .text resize__7JKRHeapFPvUlP7JKRHeap */
s32 JKRHeap::resize(void* ptr, u32 size, JKRHeap* heap) {
if (!heap) {
heap = findFromRoot(ptr);
if (!heap)
return -1;
}
return heap->resize(ptr, size);
}
/* 802CE684-802CE6B0 2C8FC4 002C+00 1/1 1/1 0/0 .text resize__7JKRHeapFPvUl */
s32 JKRHeap::resize(void* ptr, u32 size) {
if (mInitFlag) {
JUT_WARN(567, "resize block %x into %x in heap %x", ptr, size, this);
}
return do_resize(ptr, size);
}
/* 802CE6B0-802CE700 2C8FF0 0050+00 0/0 4/4 0/0 .text getSize__7JKRHeapFPvP7JKRHeap */
s32 JKRHeap::getSize(void* ptr, JKRHeap* heap) {
if (!heap) {
heap = findFromRoot(ptr);
if (!heap)
return -1;
}
return heap->getSize(ptr);
}
/* 802CE700-802CE72C 2C9040 002C+00 1/1 1/1 0/0 .text getSize__7JKRHeapFPv */
s32 JKRHeap::getSize(void* ptr) {
return do_getSize(ptr);
}
/* 802CE72C-802CE758 2C906C 002C+00 1/1 18/18 0/0 .text getFreeSize__7JKRHeapFv */
s32 JKRHeap::getFreeSize() {
return do_getFreeSize();
}
/* 802CE758-802CE784 2C9098 002C+00 1/1 0/0 0/0 .text getMaxFreeBlock__7JKRHeapFv */
void* JKRHeap::getMaxFreeBlock() {
return do_getMaxFreeBlock();
}
/* 802CE784-802CE7B0 2C90C4 002C+00 0/0 32/32 0/0 .text getTotalFreeSize__7JKRHeapFv */
s32 JKRHeap::getTotalFreeSize() {
return do_getTotalFreeSize();
}
/* 802CE7B0-802CE7DC 2C90F0 002C+00 0/0 1/1 0/0 .text changeGroupID__7JKRHeapFUc */
s32 JKRHeap::changeGroupID(u8 groupID) {
if (mInitFlag) {
JUT_WARN(646, "change heap ID into %x in heap %x", groupID, this);
}
return do_changeGroupID(groupID);
}
/* 802CE7DC-802CE83C 2C911C 0060+00 0/0 2/2 0/0 .text getMaxAllocatableSize__7JKRHeapFi
*/
u32 JKRHeap::getMaxAllocatableSize(int alignment) {
u32 maxFreeBlock = (u32)getMaxFreeBlock();
u32 ptrOffset = (alignment - 1) & alignment - (maxFreeBlock & 0xf);
return ~(alignment - 1) & (getFreeSize() - ptrOffset);
}
/* 802CE83C-802CE894 2C917C 0058+00 3/3 8/8 0/0 .text findFromRoot__7JKRHeapFPv */
JKRHeap* JKRHeap::findFromRoot(void* ptr) {
if (sRootHeap == NULL) {
return NULL;
}
if (sRootHeap->mStart <= ptr && ptr < sRootHeap->mEnd) {
return sRootHeap->find(ptr);
}
return sRootHeap->findAllHeap(ptr);
}
/* 802CE894-802CE93C 2C91D4 00A8+00 1/1 1/1 0/0 .text find__7JKRHeapCFPv */
JKRHeap* JKRHeap::find(void* memory) const {
if (mStart <= memory && memory < mEnd) {
if (mChildTree.getNumChildren() != 0) {
for (JSUTreeIterator<JKRHeap> iterator(mChildTree.getFirstChild());
iterator != mChildTree.getEndChild(); ++iterator)
{
JKRHeap* result = iterator->find(memory);
if (result) {
return result;
}
}
}
return const_cast<JKRHeap*>(this);
}
return NULL;
}
/* 802CE93C-802CE9E4 2C927C 00A8+00 1/1 0/0 0/0 .text findAllHeap__7JKRHeapCFPv */
JKRHeap* JKRHeap::findAllHeap(void* ptr) const {
if (mChildTree.getNumChildren() != 0) {
for (JSUTreeIterator<JKRHeap> iterator(mChildTree.getFirstChild());
iterator != mChildTree.getEndChild(); ++iterator)
{
JKRHeap* result = iterator->findAllHeap(ptr);
if (result) {
return result;
}
}
}
if (mStart <= ptr && ptr < mEnd) {
return const_cast<JKRHeap*>(this);
}
return NULL;
}
/* 802CE9E4-802CEA78 2C9324 0094+00 2/2 0/0 0/0 .text dispose_subroutine__7JKRHeapFUlUl
*/
void JKRHeap::dispose_subroutine(u32 begin, u32 end) {
JSUListIterator<JKRDisposer> last_iterator;
JSUListIterator<JKRDisposer> next_iterator;
JSUListIterator<JKRDisposer> iterator;
for (iterator = mDisposerList.getFirst(); iterator != mDisposerList.getEnd();
iterator = next_iterator)
{
JKRDisposer* disposer = iterator.getObject();
if ((void*)begin <= disposer && disposer < (void*)end) {
disposer->~JKRDisposer();
if (last_iterator == NULL) {
next_iterator = mDisposerList.getFirst();
} else {
next_iterator = last_iterator;
next_iterator++;
}
} else {
last_iterator = iterator;
next_iterator = iterator;
next_iterator++;
}
}
}
/* 802CEA78-802CEAA0 2C93B8 0028+00 0/0 1/1 0/0 .text dispose__7JKRHeapFPvUl */
bool JKRHeap::dispose(void* ptr, u32 size) {
dispose_subroutine((u32)ptr, (u32)ptr + size);
return false;
}
/* 802CEAA0-802CEAC0 2C93E0 0020+00 0/0 1/1 0/0 .text dispose__7JKRHeapFPvPv */
void JKRHeap::dispose(void* begin, void* end) {
dispose_subroutine((u32)begin, (u32)end);
}
/* 802CEAC0-802CEB18 2C9400 0058+00 0/0 3/3 0/0 .text dispose__7JKRHeapFv */
void JKRHeap::dispose() {
JSUListIterator<JKRDisposer> iterator;
while ((iterator = mDisposerList.getFirst()) != mDisposerList.getEnd()) {
iterator->~JKRDisposer();
}
}
/* 802CEB18-802CEB40 2C9458 0028+00 0/0 4/4 0/0 .text copyMemory__7JKRHeapFPvPvUl */
void JKRHeap::copyMemory(void* dst, void* src, u32 size) {
u32 count = (size + 3) / 4;
u32* dst_32 = (u32*)dst;
u32* src_32 = (u32*)src;
while (count > 0) {
*dst_32 = *src_32;
dst_32++;
src_32++;
count--;
}
}
/* 802CEB40-802CEB78 2C9480 0038+00 2/2 0/0 0/0 .text JKRDefaultMemoryErrorRoutine__FPvUli */
void JKRDefaultMemoryErrorRoutine(void* heap, u32 size, int alignment) {
#ifdef DEBUG
OSReport("Error: Cannot allocate memory %d(0x%x)byte in %d byte alignment from %08x\n", size,
size, alignment, heap);
#endif
JUTException::panic(__FILE__, 831, "abort\n");
}
/* 802CEB78-802CEB88 2C94B8 0010+00 0/0 2/2 0/0 .text setErrorFlag__7JKRHeapFb */
bool JKRHeap::setErrorFlag(bool errorFlag) {
bool prev = mErrorFlag;
mErrorFlag = errorFlag;
return prev;
}
/* 802CEB88-802CEBA8 2C94C8 0020+00 0/0 1/1 0/0 .text setErrorHandler__7JKRHeapFPFPvUli_v
*/
JKRErrorHandler JKRHeap::setErrorHandler(JKRErrorHandler errorHandler) {
JKRErrorHandler prev = mErrorHandler;
if (!errorHandler) {
errorHandler = JKRDefaultMemoryErrorRoutine;
}
mErrorHandler = errorHandler;
return prev;
}
/* 802CEBA8-802CEC4C 2C94E8 00A4+00 0/0 1/1 0/0 .text isSubHeap__7JKRHeapCFP7JKRHeap */
bool JKRHeap::isSubHeap(JKRHeap* heap) const {
if (!heap)
return false;
if (mChildTree.getNumChildren() != 0) {
JSUTreeIterator<JKRHeap> iterator;
for (iterator = mChildTree.getFirstChild(); iterator != mChildTree.getEndChild();
++iterator)
{
if (iterator.getObject() == heap) {
return true;
}
if (iterator.getObject()->isSubHeap(heap)) {
return true;
}
}
}
return false;
}
/* 802CEC4C-802CEC74 2C958C 0028+00 0/0 278/278 377/377 .text __nw__FUl */
void* operator new(size_t size) {
return JKRHeap::alloc(size, 4, NULL);
}
/* 802CEC74-802CEC98 2C95B4 0024+00 0/0 15/15 0/0 .text __nw__FUli */
void* operator new(size_t size, int alignment) {
return JKRHeap::alloc(size, alignment, NULL);
}
/* 802CEC98-802CECC4 2C95D8 002C+00 0/0 47/47 0/0 .text __nw__FUlP7JKRHeapi */
void* operator new(size_t size, JKRHeap* heap, int alignment) {
return JKRHeap::alloc(size, alignment, heap);
}
/* 802CECC4-802CECEC 2C9604 0028+00 0/0 52/52 15/15 .text __nwa__FUl */
void* operator new[](size_t size) {
return JKRHeap::alloc(size, 4, NULL);
}
/* 802CECEC-802CED10 2C962C 0024+00 0/0 29/29 0/0 .text __nwa__FUli */
void* operator new[](size_t size, int alignment) {
return JKRHeap::alloc(size, alignment, NULL);
}
/* 802CED10-802CED3C 2C9650 002C+00 0/0 25/25 0/0 .text __nwa__FUlP7JKRHeapi */
void* operator new[](size_t size, JKRHeap* heap, int alignment) {
return JKRHeap::alloc(size, alignment, heap);
}
/* 802CED3C-802CED60 2C967C 0024+00 1/1 847/847 4665/4665 .text __dl__FPv */
void operator delete(void* ptr) {
JKRHeap::free(ptr, NULL);
}
/* 802CED60-802CED84 2C96A0 0024+00 0/0 20/20 3/3 .text __dla__FPv */
void operator delete[](void* ptr) {
JKRHeap::free(ptr, NULL);
}
/* 802CED84-802CED88 2C96C4 0004+00 1/0 1/0 0/0 .text
* state_register__7JKRHeapCFPQ27JKRHeap6TStateUl */
void JKRHeap::state_register(JKRHeap::TState* p, u32 id) const {
JUT_ASSERT(1213, p != 0);
JUT_ASSERT(1214, p->getHeap() == this);
}
/* 802CED88-802CEDA0 2C96C8 0018+00 1/0 1/0 0/0 .text
* state_compare__7JKRHeapCFRCQ27JKRHeap6TStateRCQ27JKRHeap6TState */
bool JKRHeap::state_compare(const JKRHeap::TState& r1, const JKRHeap::TState& r2) const {
JUT_ASSERT(1222, r1.getHeap() == r2.getHeap());
return r1.getCheckCode() == r2.getCheckCode();
}
/* 802CEDA0-802CEDA4 2C96E0 0004+00 1/0 3/0 0/0 .text state_dump__7JKRHeapCFRCQ27JKRHeap6TState */
void JKRHeap::state_dump(const JKRHeap::TState& p) const {
JUT_LOG(1246, "check-code : 0x%08x", p.getCheckCode());
JUT_LOG(1247, "id : 0x%08x", p.getId());
JUT_LOG(1248, "used size : %u", p.getUsedSize());
}
/* 802CEDA4-802CEDAC 2C96E4 0008+00 1/0 1/0 0/0 .text do_changeGroupID__7JKRHeapFUc */
s32 JKRHeap::do_changeGroupID(u8 param_0) {
return 0;
}
/* 802CEDAC-802CEDB4 2C96EC 0008+00 1/0 1/0 0/0 .text do_getCurrentGroupId__7JKRHeapFv */
u8 JKRHeap::do_getCurrentGroupId() {
return 0;
}
+242
View File
@@ -0,0 +1,242 @@
#include "JSystem/JKernel/JKRMemArchive.h"
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JKernel/JKRDvdRipper.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JUtility/JUTException.h"
#include "string.h"
#include "global.h"
/* 802D69B8-802D6A6C 2D12F8 00B4+00 0/0 2/2 0/0 .text
* __ct__13JKRMemArchiveFlQ210JKRArchive15EMountDirection */
JKRMemArchive::JKRMemArchive(s32 entryNum, JKRArchive::EMountDirection mountDirection)
: JKRArchive(entryNum, MOUNT_MEM) {
mIsMounted = false;
mMountDirection = mountDirection;
if (!open(entryNum, mMountDirection)) {
return;
}
mVolumeType = 'RARC';
mVolumeName = mStringTable + mNodes->name_offset;
getVolumeList().prepend(&mFileLoaderLink);
mIsMounted = true;
}
/* 802D6A6C-802D6B24 2D13AC 00B8+00 0/0 2/2 0/0 .text __ct__13JKRMemArchiveFPvUl15JKRMemBreakFlag
*/
JKRMemArchive::JKRMemArchive(void* buffer, u32 bufferSize, JKRMemBreakFlag param_3)
: JKRArchive((s32)buffer, MOUNT_MEM) {
mIsMounted = false;
if (!open(buffer, bufferSize, param_3)) {
return;
}
mVolumeType = 'RARC';
mVolumeName = mStringTable + mNodes->name_offset;
getVolumeList().prepend(&mFileLoaderLink);
mIsMounted = true;
}
/* 802D6B24-802D6BCC 2D1464 00A8+00 1/0 0/0 0/0 .text __dt__13JKRMemArchiveFv */
JKRMemArchive::~JKRMemArchive() {
if (mIsMounted == true) {
if (mIsOpen) {
if (mArcHeader)
JKRFreeToHeap(mHeap, mArcHeader);
}
getVolumeList().remove(&mFileLoaderLink);
mIsMounted = false;
}
}
/* 802D6BCC-802D6D30 2D150C 0164+00 1/1 0/0 0/0 .text
* open__13JKRMemArchiveFlQ210JKRArchive15EMountDirection */
bool JKRMemArchive::open(s32 entryNum, JKRArchive::EMountDirection mountDirection) {
mArcHeader = NULL;
mArcInfoBlock = NULL;
mArchiveData = NULL;
mNodes = NULL;
mFiles = NULL;
mStringTable = NULL;
mIsOpen = false;
mMountDirection = mountDirection;
if (mMountDirection == JKRArchive::MOUNT_DIRECTION_HEAD) {
u32 loadedSize;
mArcHeader = (SArcHeader *)JKRDvdToMainRam(
entryNum, NULL, EXPAND_SWITCH_UNKNOWN1, 0, mHeap, JKRDvdRipper::ALLOC_DIRECTION_FORWARD,
0, (int *)&mCompression, &loadedSize);
if (mArcHeader) {
DCInvalidateRange(mArcHeader, loadedSize);
}
}
else {
u32 loadedSize;
mArcHeader = (SArcHeader *)JKRDvdToMainRam(
entryNum, NULL, EXPAND_SWITCH_UNKNOWN1, 0, mHeap,
JKRDvdRipper::ALLOC_DIRECTION_BACKWARD, 0, (int *)&mCompression, &loadedSize);
if (mArcHeader) {
DCInvalidateRange(mArcHeader, loadedSize);
}
}
if (!mArcHeader) {
mMountMode = UNKNOWN_MOUNT_MODE;
}
else {
JUT_ASSERT(438, mArcHeader->signature =='RARC');
mArcInfoBlock = (SArcDataInfo *)((u8 *)mArcHeader + mArcHeader->header_length);
mNodes = (SDIDirEntry *)((u8 *)&mArcInfoBlock->num_nodes + mArcInfoBlock->node_offset);
mFiles = (SDIFileEntry *)((u8 *)&mArcInfoBlock->num_nodes + mArcInfoBlock->file_entry_offset);
mStringTable = (char *)((u8 *)&mArcInfoBlock->num_nodes + mArcInfoBlock->string_table_offset);
mArchiveData =
(u8 *)((u32)mArcHeader + mArcHeader->header_length + mArcHeader->file_data_offset);
mIsOpen = true;
}
#ifdef DEBUG
if (mMountMode == 0) {
OSReport(":::Cannot alloc memory [%s][%d]\n", __FILE__, 460);
}
#endif
return (mMountMode == UNKNOWN_MOUNT_MODE) ? false : true;
}
/* 802D6D30-802D6DDC 2D1670 00AC+00 1/1 0/0 0/0 .text open__13JKRMemArchiveFPvUl15JKRMemBreakFlag
*/
bool JKRMemArchive::open(void* buffer, u32 bufferSize, JKRMemBreakFlag flag) {
mArcHeader = (SArcHeader *)buffer;
JUT_ASSERT(491, mArcHeader->signature =='RARC');
mArcInfoBlock = (SArcDataInfo *)((u8 *)mArcHeader + mArcHeader->header_length);
mNodes = (SDIDirEntry *)((u8 *)&mArcInfoBlock->num_nodes + mArcInfoBlock->node_offset);
mFiles = (SDIFileEntry *)((u8 *)&mArcInfoBlock->num_nodes + mArcInfoBlock->file_entry_offset);
mStringTable = (char *)((u8 *)&mArcInfoBlock->num_nodes + mArcInfoBlock->string_table_offset);
mArchiveData = (u8 *)(((u32)mArcHeader + mArcHeader->header_length) + mArcHeader->file_data_offset);
mIsOpen = (flag == JKRMEMBREAK_FLAG_UNKNOWN1) ? true : false; // mIsOpen might be u8
mHeap = JKRHeap::findFromRoot(buffer);
mCompression = COMPRESSION_NONE;
return true;
}
/* 802D6DDC-802D6E10 2D171C 0034+00 1/0 0/0 0/0 .text
* fetchResource__13JKRMemArchiveFPQ210JKRArchive12SDIFileEntryPUl */
void* JKRMemArchive::fetchResource(SDIFileEntry* fileEntry, u32* resourceSize) {
JUT_ASSERT(555, isMounted());
if (!fileEntry->data) {
fileEntry->data = mArchiveData + fileEntry->data_offset;
}
if (resourceSize) {
*resourceSize = fileEntry->data_size;
}
return fileEntry->data;
}
/* 802D6E10-802D6ED0 2D1750 00C0+00 1/0 0/0 0/0 .text
* fetchResource__13JKRMemArchiveFPvUlPQ210JKRArchive12SDIFileEntryPUl */
void* JKRMemArchive::fetchResource(void* buffer, u32 bufferSize, SDIFileEntry* fileEntry,
u32* resourceSize) {
JUT_ASSERT(595, isMounted());
u32 srcLength = fileEntry->data_size;
if (srcLength > bufferSize) {
srcLength = bufferSize;
}
if (fileEntry->data != NULL) {
memcpy(buffer, fileEntry->data, srcLength);
} else {
JKRCompression compression = JKRConvertAttrToCompressionType(fileEntry->getAttr());
void* data = mArchiveData + fileEntry->data_offset;
srcLength =
fetchResource_subroutine((u8*)data, srcLength, (u8*)buffer, bufferSize, compression);
}
if (resourceSize) {
*resourceSize = srcLength;
}
return buffer;
}
/* 802D6ED0-802D6F20 2D1810 0050+00 1/0 0/0 0/0 .text removeResourceAll__13JKRMemArchiveFv */
void JKRMemArchive::removeResourceAll(void) {
JUT_ASSERT(642, isMounted());
if (mArcInfoBlock == NULL)
return;
if (mMountMode == MOUNT_MEM)
return;
// !@bug: looping over file entries without incrementing the fileEntry pointer. Thus, only the
// first fileEntry will clear/remove the resource data.
SDIFileEntry* fileEntry = mFiles;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
if (fileEntry->data) {
fileEntry->data = NULL;
}
}
}
/* 802D6F20-802D6F5C 2D1860 003C+00 1/0 0/0 0/0 .text removeResource__13JKRMemArchiveFPv
*/
bool JKRMemArchive::removeResource(void* resource) {
JUT_ASSERT(673, isMounted());
SDIFileEntry* fileEntry = findPtrResource(resource);
if (!fileEntry)
return false;
fileEntry->data = NULL;
return true;
}
/* 802D6F5C-802D7030 2D189C 00D4+00 1/1 1/1 0/0 .text
* fetchResource_subroutine__13JKRMemArchiveFPUcUlPUcUli */
u32 JKRMemArchive::fetchResource_subroutine(u8* src, u32 srcLength, u8* dst, u32 dstLength,
JKRCompression compression) {
switch (compression) {
case COMPRESSION_NONE:
if (srcLength > dstLength) {
srcLength = dstLength;
}
memcpy(dst, src, srcLength);
return srcLength;
case COMPRESSION_YAY0:
case COMPRESSION_YAZ0:
u32 expendedSize = JKRDecompExpandSize(src);
srcLength = expendedSize;
if (expendedSize > dstLength) {
srcLength = dstLength;
}
JKRDecompress(src, dst, srcLength, 0);
return srcLength;
default: {
JUTException::panic(__FILE__, 723, "??? bad sequence\n");
} break;
}
return 0;
}
/* 802D7030-802D70C0 2D1970 0090+00 1/0 0/0 0/0 .text getExpandedResSize__13JKRMemArchiveCFPCv */
u32 JKRMemArchive::getExpandedResSize(const void* resource) const {
SDIFileEntry* fileEntry = findPtrResource(resource);
if (fileEntry == NULL)
return -1;
if (fileEntry->isCompressed() == false) {
return getResSize(resource);
} else {
return JKRDecompExpandSize((u8*)resource);
}
}
+297
View File
@@ -0,0 +1,297 @@
#include "JSystem/JKernel/JKRSolidHeap.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JUtility/JUTConsole.h"
/* 802D0A24-802D0AD0 2CB364 00AC+00 0/0 4/4 1/1 .text create__12JKRSolidHeapFUlP7JKRHeapb
*/
JKRSolidHeap* JKRSolidHeap::create(u32 size, JKRHeap* heap, bool useErrorHandler) {
if (!heap) {
heap = getRootHeap();
}
if (size == 0xffffffff) {
size = heap->getMaxAllocatableSize(0x10);
}
u32 alignedSize = ALIGN_PREV(size, 0x10);
u32 solidHeapSize = ALIGN_NEXT(sizeof(JKRSolidHeap), 0x10);
if (alignedSize < solidHeapSize)
return NULL;
JKRSolidHeap* solidHeap = (JKRSolidHeap*)JKRAllocFromHeap(heap, alignedSize, 0x10);
void* dataPtr = (u8*)solidHeap + solidHeapSize;
if (!solidHeap)
return NULL;
solidHeap =
new (solidHeap) JKRSolidHeap(dataPtr, alignedSize - solidHeapSize, heap, useErrorHandler);
return solidHeap;
}
/* 802D0AD0-802D0B30 2CB410 0060+00 1/0 0/0 0/0 .text do_destroy__12JKRSolidHeapFv */
void JKRSolidHeap::do_destroy(void) {
JKRHeap* parent = getParent();
if (parent) {
this->~JKRSolidHeap();
JKRFreeToHeap(parent, this);
}
}
/* 802D0B30-802D0B8C 2CB470 005C+00 1/1 0/0 0/0 .text __ct__12JKRSolidHeapFPvUlP7JKRHeapb
*/
JKRSolidHeap::JKRSolidHeap(void* start, u32 size, JKRHeap* parent, bool useErrorHandler)
: JKRHeap(start, size, parent, useErrorHandler) {
mFreeSize = mSize;
mSolidHead = (u8*)mStart;
mSolidTail = (u8*)mEnd;
field_0x78 = NULL;
}
/* 802D0B8C-802D0BF4 2CB4CC 0068+00 1/0 0/0 0/0 .text __dt__12JKRSolidHeapFv */
JKRSolidHeap::~JKRSolidHeap(void) {
dispose();
}
/* 802D0BF4-802D0CB0 2CB534 00BC+00 0/0 5/5 1/1 .text adjustSize__12JKRSolidHeapFv */
s32 JKRSolidHeap::adjustSize(void) {
JKRHeap* parent = getParent();
if (parent) {
lock();
u32 thisSize = (u32)mStart - (u32)this;
u32 newSize = ALIGN_NEXT(mSolidHead - mStart, 0x20);
if (parent->resize(this, thisSize + newSize) != -1) {
mFreeSize = 0;
mSize = newSize;
mEnd = mStart + mSize;
mSolidHead = mEnd;
mSolidTail = mEnd;
}
unlock();
return thisSize + newSize;
}
return -1;
}
/* 802D0CB0-802D0D58 2CB5F0 00A8+00 1/0 0/0 0/0 .text do_alloc__12JKRSolidHeapFUli */
void* JKRSolidHeap::do_alloc(u32 size, int alignment) {
#ifdef DEBUG
// TODO(Julgodis): JUTAssertion::setConfirmMessage
/* if (alignment != 0) {
int u = abs(alignment);
JUT_ASSERT(219, u < 0x80);
JUT_ASSERT(220, JGadget::binary::isPower2(u));
} */
#endif
lock();
if (size < 4) {
size = 4;
}
void* ptr;
if (alignment >= 0) {
ptr = allocFromHead(size, alignment < 4 ? 4 : alignment);
} else {
if (-alignment < 4) {
alignment = 4;
} else {
alignment = -alignment;
}
ptr = allocFromTail(size, alignment);
}
unlock();
return ptr;
}
/* 802D0D58-802D0E20 2CB698 00C8+00 1/1 0/0 0/0 .text allocFromHead__12JKRSolidHeapFUli
*/
void* JKRSolidHeap::allocFromHead(u32 size, int alignment) {
size = ALIGN_NEXT(size, 0x4);
void* ptr = NULL;
u32 alignedStart = (alignment - 1 + (u32)mSolidHead) & ~(alignment - 1);
u32 offset = alignedStart - (u32)mSolidHead;
u32 totalSize = size + offset;
if (totalSize <= mFreeSize) {
ptr = (void*)alignedStart;
mSolidHead += totalSize;
mFreeSize -= totalSize;
} else {
JUTWarningConsole_f("allocFromHead: cannot alloc memory (0x%x byte).\n", totalSize);
if (getErrorFlag() == true) {
callErrorHandler(this, size, alignment);
}
}
return ptr;
}
/* 802D0E20-802D0EE4 2CB760 00C4+00 1/1 0/0 0/0 .text allocFromTail__12JKRSolidHeapFUli
*/
void* JKRSolidHeap::allocFromTail(u32 size, int alignment) {
size = ALIGN_NEXT(size, 4);
void* ptr = NULL;
u32 alignedStart = ALIGN_PREV((u32)mSolidTail - size, alignment);
u32 totalSize = (u32)mSolidTail - (u32)alignedStart;
if (totalSize <= mFreeSize) {
ptr = (void*)alignedStart;
mSolidTail -= totalSize;
mFreeSize -= totalSize;
} else {
JUTWarningConsole_f("allocFromTail: cannot alloc memory (0x%x byte).\n", totalSize);
if (getErrorFlag() == true) {
callErrorHandler(this, size, alignment);
}
}
return ptr;
}
/* 802D0EE4-802D0F14 2CB824 0030+00 1/0 0/0 0/0 .text do_free__12JKRSolidHeapFPv */
void JKRSolidHeap::do_free(void* ptr) {
JUTWarningConsole_f("free: cannot free memory block (%08x)\n", ptr);
}
/* 802D0F14-802D0F74 2CB854 0060+00 1/0 0/0 0/0 .text do_freeAll__12JKRSolidHeapFv */
void JKRSolidHeap::do_freeAll(void) {
lock();
this->JKRHeap::callAllDisposer();
mFreeSize = mSize;
mSolidHead = (u8*)mStart;
mSolidTail = (u8*)mEnd;
field_0x78 = NULL;
unlock();
}
/* 802D0F74-802D1000 2CB8B4 008C+00 1/0 0/0 0/0 .text do_freeTail__12JKRSolidHeapFv */
void JKRSolidHeap::do_freeTail(void) {
lock();
if (mSolidTail != mEnd) {
dispose(mSolidTail, mEnd);
}
this->mFreeSize = ((u32)mEnd - (u32)mSolidTail + mFreeSize);
this->mSolidTail = mEnd;
JKRSolidHeap::Unknown* unknown = field_0x78;
while (unknown) {
unknown->field_0xc = mEnd;
unknown = unknown->mNext;
}
unlock();
}
/* 802D1000-802D1004 2CB940 0004+00 1/0 0/0 0/0 .text do_fillFreeArea__12JKRSolidHeapFv
*/
void JKRSolidHeap::do_fillFreeArea() {
#ifdef DEBUG
// fillMemory(mSolidHead, mEnd - mSolidHead, (uint)DAT_8074a8ba);
#endif
}
/* 802D1004-802D1038 2CB944 0034+00 1/0 0/0 0/0 .text do_resize__12JKRSolidHeapFPvUl */
s32 JKRSolidHeap::do_resize(void* ptr, u32 newSize) {
JUTWarningConsole_f("resize: cannot resize memory block (%08x: %d)\n", ptr, newSize);
return -1;
}
/* 802D1038-802D106C 2CB978 0034+00 1/0 0/0 0/0 .text do_getSize__12JKRSolidHeapFPv */
s32 JKRSolidHeap::do_getSize(void* ptr) {
JUTWarningConsole_f("getSize: cannot get memory block size (%08x)\n", ptr);
return -1;
}
/* 802D106C-802D10FC 2CB9AC 0090+00 1/0 0/0 0/0 .text check__12JKRSolidHeapFv */
bool JKRSolidHeap::check(void) {
lock();
bool result = true;
u32 calculatedSize =
((u32)mSolidHead - (u32)mStart) + mFreeSize + ((u32)mEnd - (u32)mSolidTail);
u32 availableSize = mSize;
if (calculatedSize != availableSize) {
result = false;
JUTWarningConsole_f("check: bad total memory block size (%08X, %08X)\n", availableSize,
calculatedSize);
}
unlock();
return result;
}
/* 802D10FC-802D11FC 2CBA3C 0100+00 1/0 0/0 0/0 .text dump__12JKRSolidHeapFv */
bool JKRSolidHeap::dump(void) {
bool result = check();
lock();
u32 headSize = ((u32)mSolidHead - (u32)mStart);
u32 tailSize = ((u32)mEnd - (u32)mSolidTail);
s32 htSize = headSize + tailSize;
JUTReportConsole_f("head %08x: %08x\n", mStart, headSize);
JUTReportConsole_f("tail %08x: %08x\n", mSolidTail, ((u32)mEnd - (u32)mSolidTail));
u32 totalSize = mSize;
float percentage = (float)htSize / (float)totalSize * 100.0f;
JUTReportConsole_f("%d / %d bytes (%6.2f%%) used\n", htSize, totalSize, percentage);
unlock();
return result;
}
/* 802D11FC-802D1258 2CBB3C 005C+00 1/0 0/0 0/0 .text
* state_register__12JKRSolidHeapCFPQ27JKRHeap6TStateUl */
void JKRSolidHeap::state_register(JKRHeap::TState* p, u32 id) const {
JUT_ASSERT(604, p != 0);
JUT_ASSERT(605, p->getHeap() == this);
getState_(p);
setState_u32ID_(p, id);
setState_uUsedSize_(p, getUsedSize((JKRSolidHeap*)this));
u32 r29 = (u32)mSolidHead;
r29 += (u32)mSolidTail * 3;
setState_u32CheckCode_(p, r29);
}
/* 802D1258-802D1288 2CBB98 0030+00 1/0 0/0 0/0 .text
* state_compare__12JKRSolidHeapCFRCQ27JKRHeap6TStateRCQ27JKRHeap6TState */
bool JKRSolidHeap::state_compare(JKRHeap::TState const& r1, JKRHeap::TState const& r2) const {
JUT_ASSERT(632, r1.getHeap() == r2.getHeap());
bool result = true;
if (r1.getCheckCode() != r2.getCheckCode()) {
result = false;
}
if (r1.getUsedSize() != r2.getUsedSize()) {
result = false;
}
return result;
}
/* 802D1288-802D1294 2CBBC8 000C+00 1/0 0/0 0/0 .text getHeapType__12JKRSolidHeapFv */
u32 JKRSolidHeap::getHeapType(void) {
return 'SLID';
}
/* 802D1294-802D129C 2CBBD4 0008+00 1/0 0/0 0/0 .text do_getFreeSize__12JKRSolidHeapFv */
s32 JKRSolidHeap::do_getFreeSize(void) {
return mFreeSize;
}
/* 802D129C-802D12A4 2CBBDC 0008+00 1/0 0/0 0/0 .text do_getMaxFreeBlock__12JKRSolidHeapFv */
void* JKRSolidHeap::do_getMaxFreeBlock(void) {
return mSolidHead;
}
/* 802D12A4-802D12C4 2CBBE4 0020+00 1/0 0/0 0/0 .text do_getTotalFreeSize__12JKRSolidHeapFv */
s32 JKRSolidHeap::do_getTotalFreeSize(void) {
return getFreeSize();
}
+328
View File
@@ -0,0 +1,328 @@
#include "JSystem/JKernel/JKRThread.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JUtility/JUTConsole.h"
#include "stdio.h"
#include "dol2asm.h"
/* 8043428C-80434298 060FAC 000C+00 5/6 0/0 0/0 .bss sThreadList__9JKRThread */
JSUList<JKRThread> JKRThread::sThreadList(0);
/* 804513B0-804513B4 0008B0 0004+00 2/2 1/1 0/0 .sbss sManager__15JKRThreadSwitch */
JKRThreadSwitch* JKRThreadSwitch::sManager;
/* 804513B4-804513B8 0008B4 0004+00 3/3 0/0 0/0 .sbss sTotalCount__15JKRThreadSwitch */
u32 JKRThreadSwitch::sTotalCount;
/* 804513B8-804513BC 0008B8 0004+00 1/1 0/0 0/0 .sbss sTotalStart__15JKRThreadSwitch */
u32 JKRThreadSwitch::sTotalStart;
/* 804513BC-804513C0 0008BC 0004+00 1/1 0/0 0/0 .sbss None */
static u32 data_804513BC;
/* 804513C0-804513C4 0008C0 0004+00 1/1 0/0 0/0 .sbss mUserPreCallback__15JKRThreadSwitch
*/
JKRThreadSwitch_PreCallback JKRThreadSwitch::mUserPreCallback;
/* 804513C4-804513C8 0008C4 0004+00 1/1 0/0 0/0 .sbss mUserPostCallback__15JKRThreadSwitch */
JKRThreadSwitch_PostCallback JKRThreadSwitch::mUserPostCallback;
/* 802D1568-802D1610 2CBEA8 00A8+00 0/0 4/4 0/0 .text __ct__9JKRThreadFUlii */
JKRThread::JKRThread(u32 stack_size, int message_count, int param_3) : mThreadListLink(this) {
JKRHeap* heap = JKRHeap::findFromRoot(this);
if (heap == NULL) {
heap = JKRHeap::getSystemHeap();
}
setCommon_heapSpecified(heap, stack_size, param_3);
setCommon_mesgQueue(mHeap, message_count);
}
/* 802D1610-802D16B8 2CBF50 00A8+00 0/0 2/2 0/0 .text __ct__9JKRThreadFP7JKRHeapUlii */
JKRThread::JKRThread(JKRHeap* heap, u32 stack_size, int message_count, int param_4)
: mThreadListLink(this) {
if (heap == NULL) {
heap = JKRHeap::getCurrentHeap();
}
setCommon_heapSpecified(heap, stack_size, param_4);
setCommon_mesgQueue(mHeap, message_count);
}
/* 802D16B8-802D1758 2CBFF8 00A0+00 0/0 5/5 0/0 .text __ct__9JKRThreadFP8OSThreadi */
JKRThread::JKRThread(OSThread* thread, int message_count) : mThreadListLink(this) {
mHeap = NULL;
mThreadRecord = thread;
mStackSize = (u32)thread->stack_end - (u32)thread->stack_base;
mStackMemory = thread->stack_base;
setCommon_mesgQueue(JKRHeap::getSystemHeap(), message_count);
}
/* 802D1758-802D1830 2CC098 00D8+00 1/0 9/9 0/0 .text __dt__9JKRThreadFv */
JKRThread::~JKRThread() {
getList().remove(&mThreadListLink);
if (mHeap) {
BOOL result = OSIsThreadTerminated(mThreadRecord);
if (result == FALSE) {
OSDetachThread(mThreadRecord);
OSCancelThread(mThreadRecord);
}
JKRFreeToHeap(mHeap, mStackMemory);
JKRFreeToHeap(mHeap, mThreadRecord);
}
JKRFree(mMessages);
}
/* 802D1830-802D18A4 2CC170 0074+00 3/3 0/0 0/0 .text setCommon_mesgQueue__9JKRThreadFP7JKRHeapi
*/
void JKRThread::setCommon_mesgQueue(JKRHeap* heap, int message_count) {
mMessageCount = message_count;
mMessages = (OSMessage*)JKRHeap::alloc(mMessageCount * sizeof(OSMessage), 0, heap);
OSInitMessageQueue(&mMessageQueue, mMessages, mMessageCount);
getList().append(&mThreadListLink);
mCurrentHeap = NULL;
mCurrentHeapError = NULL;
}
/* 802D18A4-802D1934 2CC1E4 0090+00 2/2 0/0 0/0 .text
* setCommon_heapSpecified__9JKRThreadFP7JKRHeapUli */
void JKRThread::setCommon_heapSpecified(JKRHeap* heap, u32 stack_size, int param_3) {
mHeap = heap;
mStackSize = stack_size & 0xffffffe0;
mStackMemory = JKRAllocFromHeap(mHeap, mStackSize, 0x20);
mThreadRecord = (OSThread*)JKRAllocFromHeap(mHeap, sizeof(OSThread), 0x20);
void* stackBase = (void*)((int)mStackMemory + mStackSize);
OSCreateThread(mThreadRecord, start, this, stackBase, mStackSize, param_3, 1);
}
/* 802D1934-802D1960 2CC274 002C+00 1/1 0/0 0/0 .text start__9JKRThreadFPv */
void* JKRThread::start(void* param) {
JKRThread* thread = (JKRThread*)param;
return thread->run();
}
/* 802D1960-802D199C 2CC2A0 003C+00 1/1 0/0 0/0 .text searchThread__9JKRThreadFP8OSThread
*/
JKRThread* JKRThread::searchThread(OSThread* thread) {
JSUList<JKRThread>& threadList = getList();
JSUListIterator<JKRThread> iterator;
for (iterator = threadList.getFirst(); iterator != threadList.getEnd(); ++iterator) {
if (iterator->getThreadRecord() == thread) {
return iterator.getObject();
}
}
return NULL;
}
/* 802D199C-802D1A14 2CC2DC 0078+00 1/1 0/0 0/0 .text __ct__15JKRThreadSwitchFP7JKRHeap
*/
JKRThreadSwitch::JKRThreadSwitch(JKRHeap* param_0) {
mHeap = param_0;
OSSetSwitchThreadCallback(JKRThreadSwitch::callback);
this->field_0xC = 0;
this->field_0x10 = 1;
this->field_0x18 = 0;
sTotalCount = 0;
data_804513BC = 0;
sTotalStart = 0;
this->field_0x20 = 0;
this->field_0x24 = 0;
mSetNextHeap = true;
}
/* 802D1A14-802D1A70 2CC354 005C+00 0/0 1/1 0/0 .text createManager__15JKRThreadSwitchFP7JKRHeap
*/
JKRThreadSwitch* JKRThreadSwitch::createManager(JKRHeap* heap) {
JUT_ASSERT(343, sManager == 0);
if (!heap) {
heap = JKRGetCurrentHeap();
}
sManager = new (heap, 0) JKRThreadSwitch(heap);
return sManager;
}
/* 802D1A70-802D1AE4 2CC3B0 0074+00 0/0 1/1 0/0 .text enter__15JKRThreadSwitchFP9JKRThreadi */
JKRThread* JKRThreadSwitch::enter(JKRThread* thread, int thread_id) {
if (!thread) {
return NULL;
}
JKRThread* found_thread = JKRThread::searchThread(thread->getThreadRecord());
if (found_thread) {
thread = found_thread;
}
JKRThread::TLoad* loadInfo = thread->getLoadInfo();
loadInfo->clear();
loadInfo->setValid(true);
loadInfo->setId(thread_id);
return thread;
}
static void dummyStrings() {
DEAD_STRING("on");
DEAD_STRING("off");
DEAD_STRING("JKRThread:%x OSThread:%x Load:ID:%d (%s)\n");
}
/* 802D1AE4-802D1C74 2CC424 0190+00 1/1 0/0 0/0 .text
* callback__15JKRThreadSwitchFP8OSThreadP8OSThread */
void JKRThreadSwitch::callback(OSThread* current, OSThread* next) {
if (mUserPreCallback) {
(*mUserPreCallback)(current, next);
}
sTotalCount = sTotalCount + 1;
JKRHeap* next_heap = NULL;
JSUList<JKRThread>& threadList = JKRThread::getList();
JSUListIterator<JKRThread> iterator;
for (iterator = threadList.getFirst(); iterator != threadList.getEnd(); ++iterator) {
JKRThread* thread = iterator.getObject();
if (thread->getThreadRecord() == current) {
thread->setCurrentHeap(JKRHeap::getCurrentHeap());
JKRThread::TLoad* loadInfo = thread->getLoadInfo();
if (loadInfo->isValid()) {
loadInfo->addCurrentCost();
}
}
if (thread->getThreadRecord() == next) {
JKRThread::TLoad* loadInfo = thread->getLoadInfo();
if (loadInfo->isValid()) {
loadInfo->setCurrentTime();
loadInfo->incCount();
}
if (sManager->mSetNextHeap) {
next_heap = thread->getCurrentHeap();
if (!next_heap) {
next_heap = JKRHeap::getCurrentHeap();
} else if (JKRHeap::getRootHeap()->isSubHeap(next_heap)) {
continue;
#ifdef DEBUG
} else if (!JKRHeap::getRootHeap2()->isSubHeap(next_heap)) {
continue;
#endif
} else {
switch (thread->getCurrentHeapError()) {
case 0:
JUT_PANIC(508, "JKRThreadSwitch: currentHeap destroyed.");
break;
case 1:
JUTWarningConsole("JKRThreadSwitch: currentHeap destroyed.\n");
next_heap = JKRHeap::getCurrentHeap();
break;
case 2:
next_heap = JKRHeap::getCurrentHeap();
break;
case 3:
next_heap = JKRHeap::getSystemHeap();
break;
}
}
}
}
}
if (next_heap) {
next_heap->becomeCurrentHeap();
}
if (mUserPostCallback) {
(*mUserPostCallback)(current, next);
}
}
/* 802D1C74-802D1E14 2CC5B4 01A0+00 1/0 0/0 0/0 .text
* draw__15JKRThreadSwitchFP14JKRThreadName_P10JUTConsole */
void JKRThreadSwitch::draw(JKRThreadName_* thread_name_list, JUTConsole* console) {
const char* print_0 = " total: switch:%3d time:%d(%df)\n";
const char* print_1 = " -------------------------------------\n";
if (!console) {
#ifdef DEBUG
OSReport(print_0, getTotalCount(), (int)this->field_0x18, this->field_0x10);
OSReport(print_1);
#endif
} else {
console->clear();
console->print_f(print_0, getTotalCount(), (int)this->field_0x18, this->field_0x10);
console->print(print_1);
}
JSUList<JKRThread>& threadList = JKRThread::getList();
JSUListIterator<JKRThread> iterator;
for (iterator = threadList.getFirst(); iterator != threadList.getEnd(); ++iterator) {
JKRThread* thread = iterator.getObject();
JKRThread::TLoad* loadInfo = thread->getLoadInfo();
if (loadInfo->isValid()) {
char* thread_print_name = NULL;
if (thread_name_list) {
JKRThreadName_* thread_name = thread_name_list;
for (; thread_name->name; thread_name++) {
if (thread_name->id == loadInfo->getId()) {
thread_print_name = thread_name->name;
break;
}
}
}
if (!thread_print_name) {
char buffer[16];
sprintf(buffer, "%d", loadInfo->getId());
thread_print_name = buffer;
}
u32 switch_count = loadInfo->getCount();
float cost_per_0x18 = loadInfo->getCost() / (float)this->field_0x18;
u32 cost_int = (u32)(cost_per_0x18 * 100.0f);
u32 cost_float = (u32)(cost_per_0x18 * 1000.0f) % 10;
if (!console) {
#ifdef DEBUG
OSReport(" [%10s] switch:%5d cost:%2d.%d%%\n", thread_print_name, switch_count,
cost_int, cost_float);
#endif
} else {
console->print_f(" [%10s] switch:%5d cost:%2d.%d%%\n", thread_print_name,
switch_count, cost_int, cost_float);
}
}
}
}
/* 802D1E14-802D1E1C 2CC754 0008+00 1/0 0/0 0/0 .text run__9JKRThreadFv */
void* JKRThread::run() {
return NULL;
}
/* 802D1E1C-802D1E4C 2CC75C 0030+00 1/0 0/0 0/0 .text draw__15JKRThreadSwitchFP14JKRThreadName_ */
void JKRThreadSwitch::draw(JKRThreadName_* thread_name_list) {
draw(thread_name_list, NULL);
}
/* 802D1E4C-802D1E94 2CC78C 0048+00 1/0 0/0 0/0 .text __dt__15JKRThreadSwitchFv */
JKRThreadSwitch::~JKRThreadSwitch() {}
/* 804342A4-804342B0 060FC4 000C+00 0/1 0/0 0/0 .bss sTaskList__7JKRTask */
#pragma push
#pragma force_active on
JSUList<JKRTask> JKRTask::sTaskList;
#pragma pop
/* ############################################################################################## */
/* 804342B0-804342D0 060FD0 0020+00 0/0 0/0 0/0 .bss sEndMesgQueue__7JKRTask */
#pragma push
#pragma force_active on
u8 JKRTask::sEndMesgQueue[32];
#pragma pop