Files
tp/libs/JSystem/JKernel/JKRMemArchive.cpp
T

247 lines
7.7 KiB
C++
Raw Normal View History

2020-12-06 21:02:25 +01:00
#include "JSystem/JKernel/JKRMemArchive/JKRMemArchive.h"
2021-01-05 17:34:58 +01:00
#include "JSystem/JKernel/JKRDvdRipper/JKRDvdRipper.h"
2021-02-20 23:11:44 -05:00
#include "JSystem/JKernel/JKRHeap/JKRHeap.h"
2020-12-06 21:02:25 +01:00
#include "global.h"
#include "msl_c/string.h"
2020-12-06 21:02:25 +01:00
2021-01-31 15:33:34 -05:00
extern "C" {
void DCInvalidateRange(void*, u32);
void findFromRoot__7JKRHeapFPv(void);
2021-03-15 07:12:44 +01:00
void panic_f__12JUTExceptionFPCciPCce(const char* filename, int line, const char* format, ...);
2021-01-31 15:45:36 -05:00
void loadToMainRAM__12JKRDvdRipperFlPUc15JKRExpandSwitchUlP7JKRHeapQ212JKRDvdRipper15EAllocDirectionUlPiPUl(
void);
2021-01-31 15:33:34 -05:00
}
2021-02-20 23:11:44 -05:00
extern const char lbl_8039D160[16]; // "JKRMemArchive.cpp"
2021-01-05 17:34:58 +01:00
JKRMemArchive::JKRMemArchive(long entryNum, JKRArchive::EMountDirection mountDirection)
: JKRArchive(entryNum, MOUNT_MEM) {
mIsMounted = false;
mMountDirection = mountDirection;
if (!open(entryNum, mMountDirection)) {
return;
}
mVolumeType = 'RARC';
mVolumeName = mStringTable + (u32)mNodes->name;
getVolumeList().prepend(&mFileLoaderLink);
mIsMounted = true;
2020-12-06 21:02:25 +01:00
}
2021-01-05 17:34:58 +01:00
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 + (u32)mNodes->name;
getVolumeList().prepend(&mFileLoaderLink);
mIsMounted = true;
2020-12-06 21:02:25 +01:00
}
2021-01-05 17:34:58 +01:00
JKRMemArchive::~JKRMemArchive() {
if (mIsMounted == true) {
if (mIsOpen) {
if (mArcHeader)
JKRFreeToHeap(mHeap, mArcHeader);
}
getVolumeList().remove(&mFileLoaderLink);
mIsMounted = false;
}
2020-12-06 21:02:25 +01:00
}
2021-01-05 17:34:58 +01:00
// full match, except:
// mArchiveData = (u8*)(mArcHeader->file_data_offset + mArcHeader->header_length + (u32)mArcHeader);
// where the addition is swapped.
#ifdef NONMATCHING
bool JKRMemArchive::open(long entryNum, JKRArchive::EMountDirection mountDirection) {
mArcHeader = NULL;
mArcInfoBlock = NULL;
mArchiveData = NULL;
mNodes = NULL;
mFiles = NULL;
mStringTable = NULL;
mIsOpen = false;
mMountDirection = mountDirection;
if (mMountDirection == JKRArchive::HEAD) {
u32 loadedSize;
mArcHeader = (SArcHeader*)JKRDvdRipper::loadToMainRAM(
entryNum, NULL, EXPAND_SWITCH_UNKNOWN1, 0, mHeap, JKRDvdRipper::FORWARD, 0,
&mCompression, &loadedSize);
if (mArcHeader) {
DCInvalidateRange(mArcHeader, loadedSize);
}
} else {
u32 loadedSize;
mArcHeader = (SArcHeader*)JKRDvdRipper::loadToMainRAM(
entryNum, NULL, EXPAND_SWITCH_UNKNOWN1, 0, mHeap, JKRDvdRipper::BACKWARD, 0,
&mCompression, &loadedSize);
if (mArcHeader) {
DCInvalidateRange(mArcHeader, loadedSize);
}
}
if (!mArcHeader) {
mMountMode = UNKNOWN_MOUNT_MODE;
} else {
ASSERT(mArcHeader->signature == 'RARC');
mArcInfoBlock = (SArcDataInfo*)((u8*)mArcHeader + mArcHeader->header_length);
mNodes = (SDirEntry*)((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*)(mArcHeader->file_data_offset + mArcHeader->header_length + (u32)mArcHeader);
mIsOpen = true;
}
return mMountMode != UNKNOWN_MOUNT_MODE;
}
#else
asm bool JKRMemArchive::open(long entryNum, JKRArchive::EMountDirection mountDirection) {
2020-12-06 21:02:25 +01:00
nofralloc
2020-12-26 11:31:49 -05:00
#include "JSystem/JKernel/JKRMemArchive/asm/func_802D6BCC.s"
2020-12-06 21:02:25 +01:00
}
2021-01-05 17:34:58 +01:00
#endif
2020-12-06 21:02:25 +01:00
2021-01-05 17:34:58 +01:00
// full match, except:
// mArchiveData = (u8*)(mArcHeader->file_data_offset + mArcHeader->header_length + (u32)mArcHeader);
// where the addition is swapped.
#ifdef NONMATCHING
bool JKRMemArchive::open(void* buffer, u32 bufferSize, JKRMemBreakFlag flag) {
mArcHeader = (SArcHeader*)buffer;
ASSERT(mArcHeader->signature == 'RARC');
mArcInfoBlock = (SArcDataInfo*)((u8*)mArcHeader + mArcHeader->header_length);
mNodes = (SDirEntry*)((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*)(mArcHeader->file_data_offset + mArcHeader->header_length + (u32)mArcHeader);
mIsOpen = (flag == JKRMEMBREAK_FLAG_UNKNOWN1);
mHeap = JKRHeap::findFromRoot(buffer);
mCompression = JKRDecomp::NONE;
return true;
}
#else
asm bool JKRMemArchive::open(void* buffer, u32 bufferSize, JKRMemBreakFlag flag) {
2020-12-06 21:02:25 +01:00
nofralloc
2020-12-26 11:31:49 -05:00
#include "JSystem/JKernel/JKRMemArchive/asm/func_802D6D30.s"
2020-12-06 21:02:25 +01:00
}
2021-01-05 17:34:58 +01:00
#endif
2020-12-06 21:02:25 +01:00
2021-01-05 17:34:58 +01:00
void* JKRMemArchive::fetchResource(SDIFileEntry* fileEntry, u32* resourceSize) {
if (!fileEntry->data) {
fileEntry->data = mArchiveData + fileEntry->data_offset;
}
if (resourceSize) {
*resourceSize = fileEntry->data_size;
}
return fileEntry->data;
2020-12-06 21:02:25 +01:00
}
2021-01-05 17:34:58 +01:00
void* JKRMemArchive::fetchResource(void* buffer, u32 bufferSize, SDIFileEntry* fileEntry,
u32* resourceSize) {
u32 srcLength = fileEntry->data_size;
if (srcLength > bufferSize) {
srcLength = bufferSize;
}
if (fileEntry->data != NULL) {
memcpy(buffer, fileEntry->data, srcLength);
} else {
2021-01-10 02:15:52 +01:00
JKRCompression compression = JKRConvertAttrToCompressionType(fileEntry->getAttr());
2021-01-05 17:34:58 +01:00
void* data = mArchiveData + fileEntry->data_offset;
srcLength =
fetchResource_subroutine((u8*)data, srcLength, (u8*)buffer, bufferSize, compression);
}
if (resourceSize) {
*resourceSize = srcLength;
}
return buffer;
2020-12-06 21:02:25 +01:00
}
2021-01-05 17:34:58 +01:00
void JKRMemArchive::removeResourceAll(void) {
ASSERT(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;
}
}
2020-12-06 21:02:25 +01:00
}
2021-01-05 17:34:58 +01:00
bool JKRMemArchive::removeResource(void* resource) {
ASSERT(isMounted());
SDIFileEntry* fileEntry = findPtrResource(resource);
if (!fileEntry)
return false;
fileEntry->data = NULL;
return true;
2020-12-06 21:02:25 +01:00
}
2021-01-05 17:34:58 +01:00
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:
2021-01-10 02:15:52 +01:00
u32 expendedSize = JKRDecompExpandSize((SArcHeader*)src);
2021-01-05 17:34:58 +01:00
srcLength = expendedSize;
if (expendedSize > dstLength) {
srcLength = dstLength;
}
JKRDecompress(src, dst, srcLength, 0);
return srcLength;
default: {
const char* file = lbl_8039D160; // "JKRMemArchive.cpp"
const char* format = lbl_8039D160 + 0x12; // "%s"
const char* arg1 = lbl_8039D160 + 0x12 + 0x3; // "??? bad sequence\n"
2021-03-15 07:12:44 +01:00
panic_f__12JUTExceptionFPCciPCce(file, 0x2d3, format, arg1);
2021-01-05 17:34:58 +01:00
} break;
}
return 0;
2020-12-06 21:02:25 +01:00
}
2021-01-10 02:15:52 +01:00
u32 JKRMemArchive::getExpandedResSize(const void* resource) {
2021-01-05 17:34:58 +01:00
SDIFileEntry* fileEntry = findPtrResource(resource);
if (fileEntry == NULL)
2021-01-10 02:15:52 +01:00
return -1;
2021-01-05 17:34:58 +01:00
if (fileEntry->isCompressed() == false) {
return getResSize(resource);
} else {
2021-01-10 02:15:52 +01:00
return JKRDecompExpandSize((SArcHeader*)resource);
2021-01-05 17:34:58 +01:00
}
2020-12-06 21:02:25 +01:00
}