mirror of https://github.com/zeldaret/tp.git
407 lines
14 KiB
C++
407 lines
14 KiB
C++
//
|
|
// Generated By: dol2asm
|
|
// Translation Unit: JKRCompArchive
|
|
//
|
|
|
|
#include "JSystem/JKernel/JKRCompArchive.h"
|
|
#include "JSystem/JKernel/JKRAram.h"
|
|
#include "JSystem/JKernel/JKRDvdAramRipper.h"
|
|
#include "JSystem/JKernel/JKRDvdArchive.h"
|
|
#include "JSystem/JKernel/JKRDvdFile.h"
|
|
#include "JSystem/JKernel/JKRMemArchive.h"
|
|
#include "JSystem/JKernel/JKRDecomp.h"
|
|
#include "JSystem/JKernel/JKRAramArchive.h"
|
|
#include "JSystem/JUtility/JUTException.h"
|
|
#include "MSL_C/math.h"
|
|
#include "MSL_C/string.h"
|
|
#include "dolphin/os/OSCache.h"
|
|
|
|
//
|
|
// Forward References:
|
|
//
|
|
|
|
//
|
|
// External References:
|
|
//
|
|
|
|
//
|
|
// Declarations:
|
|
//
|
|
|
|
/* 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) {
|
|
i_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(long 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;
|
|
|
|
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) {
|
|
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) {
|
|
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;
|
|
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_f(__FILE__, 0x308, "%s", "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_f(__FILE__, 0x3af, "%s", "illegal resource.");
|
|
}
|
|
u32 expandSize = JKRDecompExpandSize(bufPtr);
|
|
const_cast<JKRCompArchive *>(this)->setExpandSize(fileEntry, expandSize);
|
|
return expandSize;
|
|
}
|
|
|
|
/* 8039D220-8039D220 029880 0000+00 0/0 0/0 0/0 .rodata @stringBase0 */
|