From 322b6585a2fb2392f9a555aaff23c3beb6728af6 Mon Sep 17 00:00:00 2001 From: SwareJonge Date: Sun, 30 Apr 2023 22:05:11 +0200 Subject: [PATCH] JKernel 100% --- config/MarioClub_us/dol_slices.yml | 6 + config/Release_eu/dol_slices.yml | 6 + include/JSystem/JKernel/JKRArchive.h | 8 +- libs/JSystem/JKernel/JKRAramArchive.cpp | 339 ++++++++++++++++++ libs/JSystem/JKernel/JKRDvdArchive.cpp | 28 +- libs/JSystem/JKernel/JKRMemArchive.cpp | 2 + .../JKernel/not matched/JKRAramArchive.cpp | 0 7 files changed, 374 insertions(+), 15 deletions(-) create mode 100644 libs/JSystem/JKernel/JKRAramArchive.cpp delete mode 100644 libs/JSystem/JKernel/not matched/JKRAramArchive.cpp diff --git a/config/MarioClub_us/dol_slices.yml b/config/MarioClub_us/dol_slices.yml index 7cf6988..8c2f06e 100644 --- a/config/MarioClub_us/dol_slices.yml +++ b/config/MarioClub_us/dol_slices.yml @@ -87,6 +87,12 @@ libs/JSystem/JKernel/JKRAram.cpp: .sbss: [0x804158a0, 0x804158e0] .sdata2: [0x80417a00, 0x80417a10] +libs/JSystem/JKernel/JKRAramArchive.cpp: + .text: [0x8007a3ac, 0x8007afac] + .data: [0x8038b110, 0x8038b180] + .rodata: [0x80366868, 0x803668f8] + .sdata2: [0x80417a10, 0x80417a28] + libs/JSystem/JKernel/JKRAramBlock.cpp: .text: [0x8007afac, 0x8007b228] .data: [0x8038b180, 0x8038b190] diff --git a/config/Release_eu/dol_slices.yml b/config/Release_eu/dol_slices.yml index 2be3873..79b0342 100644 --- a/config/Release_eu/dol_slices.yml +++ b/config/Release_eu/dol_slices.yml @@ -17,6 +17,12 @@ libs/JSystem/JKernel/JKRAram.cpp: .sdata: [0x803d3258, 0x803d3260] .sdata2: [0x803d6460, 0x803d6468] +libs/JSystem/JKernel/JKRAramArchive.cpp: + .text: [0x8000b3b0, 0x8000beac] + .data: [0x80347b08, 0x80347b78] + .rodata: [0x8032ce00, 0x8032ce28] + .sdata2: [0x803d6468, 0x803d6470] + libs/JSystem/JKernel/JKRAramBlock.cpp: .text: [0x8000beac, 0x8000c138] .data: [0x80347b78, 0x80347b88] diff --git a/include/JSystem/JKernel/JKRArchive.h b/include/JSystem/JKernel/JKRArchive.h index 99a937a..4d58025 100644 --- a/include/JSystem/JKernel/JKRArchive.h +++ b/include/JSystem/JKernel/JKRArchive.h @@ -210,6 +210,7 @@ enum JKRMemBreakFlag class JKRAramArchive : public JKRArchive { public: + JKRAramArchive(); JKRAramArchive(long, EMountDirection); virtual ~JKRAramArchive(); // _08 @@ -218,15 +219,17 @@ public: virtual void *fetchResource(void *, u32, SDIFileEntry *, u32 *); // _44 bool open(long); + u32 getAramAddress_Entry(SDIFileEntry *fileEntry); + u32 getAramAddress(const char *file); static u32 fetchResource_subroutine(u32, u32, u8 *, u32, int); static u32 fetchResource_subroutine(u32, u32, JKRHeap *, int, u8 **); // _00 = VTBL // _00-_5C = JKRArchive - CompressionMethod mCompression; // _5C + int mCompression; // _5C EMountDirection mMountDirection; // _60 JKRAramBlock *mBlock; // _64 - JKRDvdFile *mDvdFile; // _68 + JKRFile *mDvdFile; // _68 }; struct JKRCompArchive : public JKRArchive @@ -263,6 +266,7 @@ struct JKRCompArchive : public JKRArchive struct JKRDvdArchive : public JKRArchive { + JKRDvdArchive(); JKRDvdArchive(long, JKRArchive::EMountDirection); virtual ~JKRDvdArchive(); // _00 diff --git a/libs/JSystem/JKernel/JKRAramArchive.cpp b/libs/JSystem/JKernel/JKRAramArchive.cpp new file mode 100644 index 0000000..4fad7dd --- /dev/null +++ b/libs/JSystem/JKernel/JKRAramArchive.cpp @@ -0,0 +1,339 @@ +#include +#include +#include +#include +#include + +JKRAramArchive::JKRAramArchive() : JKRArchive() {} + +JKRAramArchive::JKRAramArchive(s32 entryNum, EMountDirection mountDirection) : JKRArchive(entryNum, MOUNT_ARAM) +{ + mMountDirection = mountDirection; + if (!open(entryNum)) + { + return; + } + else + { + mVolumeType = 'RARC'; + mVolumeName = &mStrTable[mDirectories->mOffset]; + sVolumeList.prepend(&mFileLoaderLink); + mIsMounted = true; + } +} + +JKRAramArchive::~JKRAramArchive() +{ + if (mIsMounted == true) + { + if (mArcInfoBlock) + { + SDIFileEntry *fileEntries = mFileEntries; + for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) + { + if (fileEntries->mData != nullptr) { + JKRFreeToHeap(mHeap, fileEntries->mData); + } + fileEntries++; + } + JKRFreeToHeap(mHeap, mArcInfoBlock); + mArcInfoBlock = nullptr; + } + + if (mExpandSizes) + { + JKRFree(mExpandSizes); + mExpandSizes = nullptr; + } + if (mDvdFile) { + delete mDvdFile; + } + if (mBlock) { + delete mBlock; + } + + sVolumeList.remove(&mFileLoaderLink); + mIsMounted = false; + } +} + +#ifdef DEBUG +CW_FORCE_STRINGS(JKRAramArchive_cpp, __FILE__, "isMounted()", "mMountCount == 1") +#endif + +bool JKRAramArchive::open(long entryNum) { + mArcInfoBlock = nullptr; + mDirectories = nullptr; + mFileEntries = nullptr; + mStrTable = nullptr; + mBlock = nullptr; + + mDvdFile = new (JKRGetSystemHeap(), mMountDirection == MOUNT_DIRECTION_HEAD ? 4 : -4) JKRDvdFile(entryNum); + if (mDvdFile == nullptr) + { + 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 == nullptr) { + mMountMode = 0; + } + else { + JKRDvdToMainRam(entryNum, (u8 *)mem, Switch_1, 32, nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 0, &mCompression, nullptr); + 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 == nullptr) { + mMountMode = 0; + } + else { + JKRDvdToMainRam(entryNum, (u8 *)mArcInfoBlock, Switch_1, alignedSize, nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 32, nullptr, nullptr); + DCInvalidateRange(mArcInfoBlock, alignedSize); + + mDirectories = (SDIDirEntry *)((u8 *)mArcInfoBlock + mArcInfoBlock->node_offset); + mFileEntries = (SDIFileEntry *)((u8 *)mArcInfoBlock + mArcInfoBlock->file_entry_offset); + mStrTable = (const char *)((u8 *)mArcInfoBlock + mArcInfoBlock->string_table_offset); + mExpandSizes = nullptr; + + u8 compressedFiles = 0; // maybe a check for if the last file is compressed? + + SDIFileEntry *fileEntry = mFileEntries; + for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) + { + u8 flag = fileEntry->mFlag >> 24; + if ((flag & 1)) + { + compressedFiles |= (flag & JKRARCHIVE_ATTR_COMPRESSION); + } + fileEntry++; + } + + if (compressedFiles != 0) + { + mExpandSizes = (u32 *)JKRAllocFromHeap(mHeap, mArcInfoBlock->num_file_entries << 2, abs(alignment)); + if (mExpandSizes == nullptr) + { + JKRFree(mArcInfoBlock); + mMountMode = 0; + goto cleanup; + } + memset(mExpandSizes, 0, mArcInfoBlock->num_file_entries << 2); + } + + u32 aramSize = ALIGN_NEXT(mem->file_data_length, 32); + mBlock = JKRAllocFromAram(aramSize, mMountDirection == MOUNT_DIRECTION_HEAD ? JKRAramHeap::AM_Head : JKRAramHeap::AM_Tail); + if(mBlock == nullptr) { + if (mArcInfoBlock) { + JKRFree(mArcInfoBlock); + } + if(mExpandSizes) { + JKRFree(mExpandSizes); + } + mMountMode = 0; + } + else { + JKRDvdToAram(entryNum, mBlock->getAddress(), Switch_1, mem->header_length + mem->file_data_offset, 0, nullptr); + } + + } + } +cleanup: + if (mem != nullptr) + { + JKRFreeToSysHeap(mem); + } + if (mMountMode == 0) + { + JUT_REPORT_MSG(":::[%s: %d] Cannot alloc memory\n", __FILE__, 415); // TODO: macro + if (mDvdFile != nullptr) + { + delete mDvdFile; + } + return false; + } + return true; +} + +void *JKRAramArchive::fetchResource(SDIFileEntry *fileEntry, u32 *pSize) +{ + JUT_ASSERT(442, isMounted()); + + u32 sizeRef; + u8 *data; + + if (pSize == nullptr) { + pSize = &sizeRef; // this makes barely any sense but ok + } + + int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18); + if(fileEntry->mData == nullptr) { + u32 size = fetchResource_subroutine(fileEntry->mDataOffset + mBlock->getAddress(), fileEntry->mSize, mHeap, compression, &data); + *pSize = size; + if (size == 0) { + return nullptr; + } + fileEntry->mData = data; + if (compression == JKRCOMPRESSION_YAZ0) + { + setExpandSize(fileEntry, *pSize); + } + } + else if (compression == JKRCOMPRESSION_YAZ0) { + *pSize = getExpandSize(fileEntry); + } + else { + *pSize = fileEntry->mSize; + } + + return fileEntry->mData; +} + +void *JKRAramArchive::fetchResource(void *data, u32 compressedSize, SDIFileEntry *fileEntry, u32 *pSize) { + JUT_ASSERT(515, isMounted()); + u32 fileSize = fileEntry->mSize; + if (fileSize > compressedSize) { + fileSize = compressedSize; + } + + int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18); + if (fileEntry->mData == nullptr) { + fileSize = fetchResource_subroutine(fileEntry->mDataOffset + mBlock->getAddress(), fileSize, (u8 *)data, + ALIGN_PREV(compressedSize, 32), compression); + } + else + { + if (compression == JKRCOMPRESSION_YAZ0) + { + u32 expandSize = getExpandSize(fileEntry); + if (expandSize != 0) { + fileSize = expandSize; + } + } + + if (fileSize > compressedSize) { + fileSize = compressedSize; + } + + JKRHeap::copyMemory(data, fileEntry->mData, fileSize); + } + if (pSize != nullptr) + { + *pSize = fileSize; + } + return data; +} + +// UNUSED +u32 JKRAramArchive::getAramAddress_Entry(SDIFileEntry *fileEntry) +{ + JUT_ASSERT(572, isMounted()); + + if(fileEntry == nullptr) { + return 0; + } + return fileEntry->mDataOffset + mBlock->getAddress(); +} + +// UNUSED +u32 JKRAramArchive::getAramAddress(const char *file) { + return getAramAddress_Entry(findFsResource(file, 0)); +} + +u32 JKRAramArchive::fetchResource_subroutine(u32 srcAram, u32 size, u8 *data, u32 expandSize, int compression) +{ + // do macros show in asserts? if not, use a macro here because if i ever reformat this then it'll screw this up + JUT_ASSERT(628, ( srcAram & 0x1f ) == 0); + + u32 sizeRef; + + u32 alignedSize = ALIGN_NEXT(size, 32); + u32 prevAlignedSize = ALIGN_PREV(expandSize, 32); + switch (compression) + { + case JKRCOMPRESSION_NONE: + if (alignedSize > prevAlignedSize) + { + alignedSize = prevAlignedSize; + } + JKRAramToMainRam(srcAram, data, alignedSize, Switch_0, prevAlignedSize, nullptr, -1, &sizeRef); + return sizeRef; + case JKRCOMPRESSION_YAY0: + case JKRCOMPRESSION_YAZ0: + JKRAramToMainRam(srcAram, data, alignedSize, Switch_1, prevAlignedSize, nullptr, -1, &sizeRef); + return sizeRef; + default: + JUT_PANIC(655, "??? bad sequence\n") + return 0; + } +} + +u32 JKRAramArchive::fetchResource_subroutine(u32 srcAram, u32 size, JKRHeap *heap, int compression, u8 **pBuf) +{ + u32 resSize; + u32 alignedSize = ALIGN_NEXT(size, 32); + + u8 *buffer; + switch(compression) { + case JKRCOMPRESSION_NONE: + buffer = (u8 *)JKRAllocFromHeap(heap, alignedSize, 32); + JUT_ASSERT(677, buffer != 0); + + JKRAramToMainRam(srcAram, buffer, alignedSize, Switch_0, alignedSize, nullptr, -1, nullptr); + *pBuf = buffer; + return size; + case JKRCOMPRESSION_YAY0: + case JKRCOMPRESSION_YAZ0: + u8 decompBuf[64]; + u8 *bufptr = (u8 *)ALIGN_NEXT((u32)decompBuf, 32); + JKRAramToMainRam(srcAram, bufptr, sizeof(decompBuf) / 2, Switch_0, 0, nullptr, -1, nullptr); + + u32 expandSize = ALIGN_NEXT(JKRDecompExpandSize(bufptr), 32); + buffer = (u8 *)JKRAllocFromHeap(heap, expandSize, 32); + JUT_ASSERT(703, buffer); + + JKRAramToMainRam(srcAram, buffer, alignedSize, Switch_1, expandSize, heap, -1, &resSize); + *pBuf = buffer; + return resSize; + default: + JUT_PANIC(713, "??? bad sequence\n"); + return 0; + } +} + +u32 JKRAramArchive::getExpandedResSize(const void *resource) const +{ + if (mExpandSizes == 0) + { + return getResSize(resource); + } + + SDIFileEntry *fileEntry = findPtrResource(resource); + if (fileEntry == nullptr) + { + return 0xffffffff; + } + + u8 flags = (fileEntry->mFlag >> 0x18); + if ((flags & 4) == 0) + { // not compressed + return getResSize(resource); + } + + u32 expandSize = getExpandSize(fileEntry); + if (expandSize != 0) + { + return expandSize; + } + + u8 buf[64]; + u8 *bufPtr = (u8 *)ALIGN_NEXT((u32)buf, 32); + + JKRAramToMainRam(fileEntry->mDataOffset + mBlock->getAddress(), bufPtr, sizeof(buf) / 2, Switch_0, 0, nullptr, -1, nullptr); + + u32 decompExpandSize = JKRDecompExpandSize(bufPtr); + const_cast(this)->setExpandSize(fileEntry, decompExpandSize); + return decompExpandSize; +} \ No newline at end of file diff --git a/libs/JSystem/JKernel/JKRDvdArchive.cpp b/libs/JSystem/JKernel/JKRDvdArchive.cpp index 42260d3..2c019c7 100644 --- a/libs/JSystem/JKernel/JKRDvdArchive.cpp +++ b/libs/JSystem/JKernel/JKRDvdArchive.cpp @@ -5,6 +5,8 @@ #include #include +JKRDvdArchive::JKRDvdArchive() : JKRArchive() {} + JKRDvdArchive::JKRDvdArchive(s32 entryNum, EMountDirection mountDirection) : JKRArchive(entryNum, MOUNT_DVD) { mMountDirection = mountDirection; @@ -54,7 +56,7 @@ JKRDvdArchive::~JKRDvdArchive() { } #ifdef DEBUG -CW_FORCE_STRINGS(JKRDvdArchive_cpp, "JKRDvdArchive.cpp", "isMounted()", "mMountCount == 1") +CW_FORCE_STRINGS(JKRDvdArchive_cpp, __FILE__, "isMounted()", "mMountCount == 1") #endif bool JKRDvdArchive::open(long entryNum) @@ -137,37 +139,37 @@ bool JKRDvdArchive::open(long entryNum) return true; } -void *JKRDvdArchive::fetchResource(SDIFileEntry *entry, u32 *outSize) { +void *JKRDvdArchive::fetchResource(SDIFileEntry *fileEntry, u32 *pSize) { JUT_ASSERT(428, isMounted()); u32 sizeptr; u32 size; u8 *data; - if(outSize == nullptr) { - outSize = &sizeptr; + if(pSize == nullptr) { + pSize = &sizeptr; } - int compression = JKRConvertAttrToCompressionType((u8)(entry->mFlag >> 24)); + int compression = JKRConvertAttrToCompressionType((u8)(fileEntry->mFlag >> 24)); - if(entry->mData == nullptr) { - size = fetchResource_subroutine(mEntryNum, _64 + entry->mDataOffset, entry->mSize, mHeap, (int)compression, mCompression, &data); - *outSize = size; + if(fileEntry->mData == nullptr) { + size = fetchResource_subroutine(mEntryNum, _64 + fileEntry->mDataOffset, fileEntry->mSize, mHeap, (int)compression, mCompression, &data); + *pSize = size; if(size == 0) { return nullptr; } - entry->mData = data; + fileEntry->mData = data; if (compression == JKRCOMPRESSION_YAZ0) { - setExpandSize(entry, *outSize); + setExpandSize(fileEntry, *pSize); } } else if (compression == JKRCOMPRESSION_YAZ0) { - *outSize = getExpandSize(entry); + *pSize = getExpandSize(fileEntry); } else { - *outSize = entry->mSize; + *pSize = fileEntry->mSize; } - return entry->mData; + return fileEntry->mData; } void *JKRDvdArchive::fetchResource(void *data, u32 compressedSize, SDIFileEntry *fileEntry, u32 *pSize) diff --git a/libs/JSystem/JKernel/JKRMemArchive.cpp b/libs/JSystem/JKernel/JKRMemArchive.cpp index 911a99d..1f4ecd0 100644 --- a/libs/JSystem/JKernel/JKRMemArchive.cpp +++ b/libs/JSystem/JKernel/JKRMemArchive.cpp @@ -4,6 +4,8 @@ #include #include +JKRMemArchive::JKRMemArchive() : JKRArchive() {} + JKRMemArchive::JKRMemArchive(s32 entryNum, EMountDirection mountDirection) : JKRArchive(entryNum, MOUNT_MEM) { mIsMounted = false; diff --git a/libs/JSystem/JKernel/not matched/JKRAramArchive.cpp b/libs/JSystem/JKernel/not matched/JKRAramArchive.cpp deleted file mode 100644 index e69de29..0000000