Add & Link JKernel (#142)

* match and link JKRAram.cpp

* match and link JKRExpHeap

* match and link JKRAramStream.cpp

* match and link JKRFileLoader.cpp

* match and link JKRFileFinder.cpp

* JKernel Dump

* match and link JKRAramArchive.cpp

* match and link JKRDvdArchive.cpp

* match and link JKRCompArchive.cpp

* match but not link JKRDvdAramRipper

* small refactors

* match and link JKRThread.cpp

* fix and link JKRDvdAramStream.cpp

* Formatting fixes

---------

Co-authored-by: SwareJonge <olaf23okken@gmail.com>
This commit is contained in:
Cuyler36
2023-11-07 23:34:10 -05:00
committed by GitHub
parent 0db4b04d70
commit 80ef14e480
47 changed files with 6183 additions and 596 deletions
+509
View File
@@ -0,0 +1,509 @@
#include <dolphin/ar.h>
#include <dolphin/string.h>
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JKernel/JKRDvdRipper.h"
#include "JSystem/JKernel/JKRExpHeap.h"
#include "JSystem/JSystem.h"
#include "_mem.h"
JSUList<JKRAMCommand> JKRAram::sAramCommandList;
JKRAram* JKRAram::sAramObject;
u32 JKRAram::sSZSBufferSize = 0x400;
JKRAram* JKRAram::create(u32 aram_audio_buffer_size, u32 aram_audio_graph_size,
s32 streamPriority, s32 decomp_priority,
s32 piece_priority) {
if (!sAramObject) {
sAramObject = new (JKRGetSystemHeap(), 0)
JKRAram(aram_audio_buffer_size, aram_audio_graph_size, piece_priority);
}
JKRCreateAramStreamManager(streamPriority);
JKRCreateDecompManager(decomp_priority);
sAramObject->resume();
return sAramObject;
}
OSMessage JKRAram::sMessageBuffer[4] = {
nullptr,
nullptr,
nullptr,
nullptr,
};
OSMessageQueue JKRAram::sMessageQueue = { 0 };
JKRAram::JKRAram(u32 bufSize, u32 graphSize, s32 priority)
: JKRThread(0x4000, 0x10, priority) {
u32 aramBase = ARInit(mStackArray, ARRAY_COUNT(mStackArray));
ARQInit();
u32 aramSize = ARGetSize();
mAudioMemorySize = bufSize;
if (graphSize == 0xffffffff) {
mGraphMemorySize = aramSize - bufSize - aramBase;
mUserMemorySize = 0;
}
else {
mGraphMemorySize = graphSize;
mUserMemorySize = (aramSize - (bufSize + graphSize) - aramBase);
}
mAudioMemoryPtr = ARAlloc(mAudioMemorySize);
mGraphMemoryPtr = ARAlloc(mGraphMemorySize);
if (mUserMemorySize != 0) { // ternary?
mUserMemoryPtr = ARAlloc(mUserMemorySize);
}
else {
mUserMemoryPtr = nullptr;
}
mAramHeap = new (JKRHeap::getSystemHeap(), 0)
JKRAramHeap(mGraphMemoryPtr, mGraphMemorySize);
}
JKRAram::~JKRAram() {
sAramObject = nullptr;
if (mAramHeap) delete mAramHeap;
}
void* JKRAram::run() {
int result;
JKRAMCommand* command;
JKRAramCommand* message;
OSInitMessageQueue(&sMessageQueue, sMessageBuffer, 4);
do {
OSReceiveMessage(&sMessageQueue, (OSMessage*)&message, OS_MESSAGE_BLOCK);
result = message->mActive;
command = (JKRAMCommand*)message->mArg;
delete message;
switch (result) {
case 1:
JKRAramPiece::startDMA(command);
break;
}
} while (true);
}
bool JKRAram::checkOkAddress(u8* addr, u32 size, JKRAramBlock* block,
u32 blockSize) {
if (!IS_ALIGNED((u32)addr, 0x20) && !IS_ALIGNED(size, 0x20)) {
JPANIC(225, ":::address not 32Byte aligned.");
return false;
}
if (block) {
if (!IS_ALIGNED(block->getAddress() + blockSize, 0x20)) {
JPANIC(234, ":::address not 32Byte aligned.");
return false;
}
}
return true;
}
void JKRAram::changeGroupIdIfNeed(u8* data, int groupId) {
JKRHeap* currentHeap = JKRGetCurrentHeap();
if (currentHeap->getHeapType() == 'EXPH' && groupId >= 0) {
JKRExpHeap::CMemBlock* block = (JKRExpHeap::CMemBlock*)(data + -0x10);
block->newGroupId(groupId);
}
}
JKRAramBlock* JKRAram::mainRamToAram(u8* buf, u32 address, u32 alignedSize,
JKRExpandSwitch expandSwitch, u32 fileSize,
JKRHeap* heap, int id) {
JKRAramBlock* block = nullptr;
checkOkAddress(buf, address, nullptr, 0);
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
expandSwitch = (JKRCheckCompressed(buf) == JKRCOMPRESSION_NONE)
? EXPAND_SWITCH_DEFAULT
: EXPAND_SWITCH_DECOMPRESS;
}
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
u32 expandSize = JKRCheckCompressed(buf) != JKRCOMPRESSION_NONE
? JKRDecompExpandSize(buf)
: 0;
if (fileSize == 0 || fileSize > expandSize) {
fileSize = expandSize;
}
if (address == 0) {
block = JKRAllocFromAram(fileSize, JKRAramHeap::Head);
if (block == nullptr) return nullptr;
block->newGroupID(decideAramGroupId(id));
address = block->getAddress();
}
if (alignedSize == 0 || alignedSize > expandSize) alignedSize = expandSize;
if (fileSize > alignedSize) fileSize = alignedSize;
void* allocatedMem = JKRAllocFromHeap(heap, fileSize, -32);
if (allocatedMem == nullptr) {
if (block != nullptr) {
delete block;
}
block = nullptr;
}
else {
JKRDecompress(buf, (u8*)allocatedMem, fileSize, 0);
JKRAramPcs(0, (u32)allocatedMem, address, alignedSize, block);
JKRFreeToHeap(heap, allocatedMem);
block = block == nullptr ? (JKRAramBlock*)-1 : block;
}
}
else {
if (address == 0) {
block = JKRAllocFromAram(alignedSize, JKRAramHeap::Head);
block->newGroupID(decideAramGroupId(id));
if (block == nullptr) return nullptr;
address = block->getAddress();
}
JKRAramPcs(0, (u32)buf, address, alignedSize, block);
block = block == nullptr ? (JKRAramBlock*)-1 : block;
}
return block;
}
JKRAramBlock* JKRAram::mainRamToAram(u8* buf, JKRAramBlock* block,
u32 alignedSize,
JKRExpandSwitch expandSwitch, u32 fileSize,
JKRHeap* heap, int id) {
checkOkAddress(buf, 0, block, 0);
if (block == nullptr) {
return mainRamToAram(buf, (u32)0, alignedSize, expandSwitch, fileSize, heap,
id);
}
u32 blockSize = block->getSize();
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
fileSize = fileSize >= blockSize ? blockSize : fileSize;
}
alignedSize = alignedSize > blockSize ? blockSize : alignedSize;
return mainRamToAram(buf, block->getAddress(), alignedSize, expandSwitch,
fileSize, heap, id);
}
// TODO: figure out name of parameter 5
u8* JKRAram::aramToMainRam(u32 address, u8* buf, u32 srcSize,
JKRExpandSwitch expandSwitch, u32 p5, JKRHeap* heap,
int id, u32* pSize) {
int compression = JKRCOMPRESSION_NONE;
if (pSize) *pSize = 0;
checkOkAddress(buf, address, nullptr, 0);
u32 expandSize;
if (expandSwitch == EXPAND_SWITCH_DECOMPRESS) {
u8 buffer[64];
u8* bufPtr = (u8*)ALIGN_NEXT((u32)buffer, 32);
JKRAramPcs(1, address, (u32)bufPtr, sizeof(buffer) / 2,
nullptr); // probably change sizeof(buffer) / 2 to 32
compression = JKRCheckCompressed(bufPtr);
expandSize = JKRDecompExpandSize(bufPtr);
}
if (compression == JKRCOMPRESSION_YAZ0) // SZS
{
if (p5 != 0 && p5 < expandSize) expandSize = p5;
if (buf == nullptr) buf = (u8*)JKRAllocFromHeap(heap, expandSize, 32);
if (buf == nullptr)
return nullptr;
else {
changeGroupIdIfNeed(buf, id);
JKRDecompressFromAramToMainRam(address, buf, srcSize, expandSize, 0);
if (pSize) {
*pSize = expandSize;
}
return buf;
}
}
else if (compression == JKRCOMPRESSION_YAY0) // SZP
{
u8* szpSpace = (u8*)JKRAllocFromHeap(heap, srcSize, -32);
if (szpSpace == nullptr) {
return nullptr;
}
else {
JKRAramPcs(1, address, (u32)szpSpace, srcSize, nullptr);
if (p5 != 0 && p5 < expandSize) expandSize = p5;
u8* szpBuffer =
buf == nullptr ? (u8*)JKRAllocFromHeap(heap, expandSize, 32) : buf;
if (szpBuffer == nullptr) {
JKRFree(szpSpace);
return nullptr;
}
else {
changeGroupIdIfNeed(szpBuffer, id);
JKRDecompress(szpSpace, szpBuffer, expandSize, 0);
JKRFreeToHeap(heap, szpSpace);
if (pSize) {
*pSize = expandSize;
}
return szpBuffer;
}
}
}
else // Not compressed or ASR
{
if (buf == nullptr) buf = (u8*)JKRAllocFromHeap(heap, srcSize, 32);
if (buf == nullptr) {
return nullptr;
}
else {
changeGroupIdIfNeed(buf, id);
JKRAramPcs(1, address, (u32)buf, srcSize, nullptr);
if (pSize != nullptr) {
*pSize = srcSize;
}
return buf;
}
}
}
// TODO: figure out what p6 does
u8* JKRAram::aramToMainRam(JKRAramBlock* block, u8* buf, u32 bufSize,
u32 alignedBlockSize, JKRExpandSwitch expandSwitch,
u32 p6, JKRHeap* heap, int id, u32* pSize) {
int compression = JKRCOMPRESSION_NONE;
if (pSize) *pSize = 0;
checkOkAddress(buf, 0, block, alignedBlockSize);
if (block == nullptr) {
JPANIC(667, ":::Bad Aram Block specified.\n");
}
u32 freeSize = block->getSize();
if (alignedBlockSize >= freeSize) return nullptr;
bufSize = bufSize == 0 ? freeSize : bufSize;
if (alignedBlockSize + bufSize > freeSize) {
bufSize = freeSize - alignedBlockSize;
}
return aramToMainRam(alignedBlockSize + block->getAddress(), buf, bufSize,
expandSwitch, p6, heap, id, pSize);
}
static OSMutex decompMutex;
static u8* szpBuf;
static u8* szpEnd;
static u8* refBuf;
static u8* refEnd;
static u8* refCurrent;
static u32 srcOffset;
static u32 transLeft;
static u8* srcLimit;
static u32 srcAddress;
static u32 fileOffset;
static u32 readCount;
static u32 maxDest;
static bool isInitMutex;
static u32* tsPtr;
static u32 tsArea;
static u8* firstSrcData();
static u8* nextSrcData(u8* current);
static int decompSZS_subroutine(u8* src, u8* dest);
void JKRAram::aramSync(JKRAMCommand*, int) {
// JUT_REPORT_MSG("bad aramSync\n");
}
int JKRDecompressFromAramToMainRam(u32 src, void* dst, u32 srcLength,
u32 dstLength, u32 offset) {
szpBuf = (u8*)JKRAllocFromSysHeap(SZP_BUFFERSIZE, 32);
// JUT_ASSERT(szpBuf != 0);
szpEnd = szpBuf + SZP_BUFFERSIZE;
if (offset != 0) {
refBuf = (u8*)JKRAllocFromSysHeap(0x1120, 0);
// JUT_ASSERT(refBuf != 0);
refEnd = refBuf + 0x1120;
refCurrent = refBuf;
}
else {
refBuf = nullptr;
}
srcAddress = src;
srcOffset = 0;
transLeft = (srcLength != 0) ? srcLength : -1;
fileOffset = offset;
readCount = 0;
maxDest = dstLength;
decompSZS_subroutine(firstSrcData(), (u8*)dst);
JKRFree(szpBuf);
if (refBuf) {
JKRFree(refBuf);
}
return 0;
}
int decompSZS_subroutine(u8* src, u8* dest) {
u8* endPtr;
s32 validBitCount = 0;
s32 currCodeByte = 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++;
if (dest == endPtr) {
break;
}
}
*(refCurrent++) = *src;
if (refCurrent == refEnd) {
refCurrent = refBuf;
}
src++;
}
else {
*dest = *src;
dest++;
src++;
if (dest == endPtr) {
break;
}
}
readCount++;
}
else {
u32 dist = src[1] | (src[0] & 0x0f) << 8;
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++;
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++;
if (dest == endPtr) {
break;
}
readCount++;
numBytes--;
copySource++;
} while (numBytes != 0);
}
}
currCodeByte <<= 1;
validBitCount--;
} while (dest < endPtr);
return 0;
}
static u8* firstSrcData() {
srcLimit = szpEnd - 0x19;
u8* buf = szpBuf;
u32 maxSize = (szpEnd - szpBuf);
u32 transSize = MIN(transLeft, maxSize);
JKRAramPcs(1, srcAddress + srcOffset, (u32)buf, ALIGN_NEXT(transSize, 32),
nullptr);
srcOffset += transSize;
transLeft -= transSize;
return buf;
}
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;
// JUT_ASSERT(transSize > 0);
JKRAramPcs(1, (u32)(srcAddress + srcOffset), ((u32)dest + left),
ALIGN_NEXT(transSize, 0x20), nullptr);
srcOffset += transSize;
transLeft -= transSize;
if (transLeft == 0) srcLimit = (dest + left) + transSize;
return dest;
}
+311
View File
@@ -0,0 +1,311 @@
#include <dolphin/os/OSCache.h>
#include <dolphin/string.h>
#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JKernel/JKRArchive.h"
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JKernel/JKRDvdAramRipper.h"
#include "JSystem/JKernel/JKRDvdRipper.h"
#include "JSystem/JSystem.h"
#include "JSystem/JUtility/JUTAssertion.h"
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 (mDvdFile) {
delete mDvdFile;
}
if (mBlock) {
delete mBlock;
}
sVolumeList.remove(&mFileLoaderLink);
mIsMounted = false;
}
}
void JKRAramArchive::fixedInit(s32 entryNum, EMountDirection direction) {
mIsMounted = false;
mMountDirection = direction;
mMountMode = 2;
mMountCount = 1;
_54 = 2;
mHeap = JKRGetCurrentHeap();
mEntryNum = entryNum;
if (sCurrentVolume) return;
sCurrentVolume = this;
sCurrentDirID = 0;
}
bool JKRAramArchive::mountFixed(s32 entryNum, EMountDirection direction) {
if (entryNum < 0) return false;
if (check_mount_already(entryNum)) return false;
fixedInit(entryNum, direction);
if (open(entryNum) == false) {
return false;
}
mVolumeType = 'RARC';
mVolumeName = &mStrTable[mDirectories->mOffset];
sVolumeList.prepend(&mFileLoaderLink);
mIsMounted = true;
return true;
}
bool JKRAramArchive::mountFixed(const char* path, EMountDirection direction) {
s32 entrynum = DVDConvertPathToEntrynum((char*)path);
return mountFixed(entrynum, direction);
}
void JKRAramArchive::unmountFixed() {
if (sCurrentVolume == this) sCurrentVolume = nullptr;
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 (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, EXPAND_SWITCH_DECOMPRESS, 32, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, 0, &mCompression);
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, EXPAND_SWITCH_DECOMPRESS,
alignedSize, nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 32,
nullptr);
mDirectories =
(SDIDirEntry*)((u8*)mArcInfoBlock + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u8*)mArcInfoBlock +
mArcInfoBlock->file_entry_offset);
mStrTable = (const char*)((u8*)mArcInfoBlock +
mArcInfoBlock->string_table_offset);
u32 aramSize = ALIGN_NEXT(mem->file_data_length, 32);
mBlock =
JKRAllocFromAram(aramSize, mMountDirection == MOUNT_DIRECTION_HEAD
? JKRAramHeap::Head
: JKRAramHeap::Tail);
if (mBlock == nullptr) {
mMountMode = 0;
}
else {
JKRDvdToAram(entryNum, mBlock->getAddress(), EXPAND_SWITCH_DECOMPRESS,
mem->header_length + mem->file_data_offset, 0);
}
}
}
cleanup:
if (mem != nullptr) {
JKRFreeToSysHeap(mem);
}
if (mMountMode == 0) {
JREPORTF(":::[%s: %d] Cannot alloc memory\n", __FILE__,
415); // TODO: macro
}
return mMountMode != 0;
}
void* JKRAramArchive::fetchResource(SDIFileEntry* fileEntry, u32* pSize) {
JUT_ASSERT(isMounted());
u32 sizeRef;
u8* data;
if (fileEntry->mData) {
if (pSize) *pSize = fileEntry->mSize;
}
else {
u32 addres = mBlock->getAddress();
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
u32 size =
fetchResource_subroutine(fileEntry->mDataOffset + addres,
fileEntry->mSize, mHeap, compression, &data);
if (pSize) *pSize = size;
fileEntry->mData = (void*)data;
}
return fileEntry->mData;
}
void* JKRAramArchive::fetchResource(void* data, u32 compressedSize,
SDIFileEntry* fileEntry, u32* pSize,
JKRExpandSwitch expandSwitch) {
JUT_ASSERT(isMounted());
u32 fileSize = fileEntry->mSize;
if (fileSize > compressedSize) {
fileSize = compressedSize;
}
if (fileEntry->mData) {
JKRHeap::copyMemory(data, fileEntry->mData, fileSize);
}
else {
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
if (expandSwitch != EXPAND_SWITCH_DECOMPRESS) compression = 0;
fileSize = fetchResource_subroutine(
fileEntry->mDataOffset + mBlock->getAddress(), fileSize, (u8*)data,
compressedSize, compression);
}
if (pSize != nullptr) {
*pSize = fileSize;
}
return data;
}
u32 JKRAramArchive::getAramAddress_Entry(SDIFileEntry* fileEntry) {
JUT_ASSERT(isMounted());
if (fileEntry == nullptr) {
return 0;
}
return fileEntry->mDataOffset + mBlock->getAddress();
}
u32 JKRAramArchive::getAramAddress(u32 type, const char* file) {
SDIFileEntry* entry = findTypeResource(type, file);
return getAramAddress_Entry(entry);
}
u32 JKRAramArchive::fetchResource_subroutine(u32 srcAram, u32 size, u8* data,
u32 expandSize, int compression) {
JUT_ASSERT((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, EXPAND_SWITCH_DEFAULT,
prevAlignedSize, nullptr, -1, &sizeRef);
return sizeRef;
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
JKRAramToMainRam(srcAram, data, alignedSize, EXPAND_SWITCH_DECOMPRESS,
prevAlignedSize, nullptr, -1, &sizeRef);
return sizeRef;
default:
JPANIC(550, ":::??? 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(buffer != 0);
JKRAramToMainRam(srcAram, buffer, alignedSize, EXPAND_SWITCH_DEFAULT,
alignedSize, nullptr, -1, nullptr);
*pBuf = buffer;
return size;
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
u8* header = (u8*)JKRAllocFromHeap(heap, 0x20, 0x20);
JKRAramToMainRam(srcAram, header, 0x20, EXPAND_SWITCH_DEFAULT, 0, nullptr,
-1, nullptr);
u32 expandSize = JKRDecompExpandSize(header);
JKRFreeToHeap(heap, header);
expandSize = ALIGN_NEXT(expandSize, 32);
buffer = (u8*)JKRAllocFromHeap(heap, expandSize, 0x20);
JUT_ASSERT(buffer);
JKRAramToMainRam(srcAram, buffer, alignedSize, EXPAND_SWITCH_DECOMPRESS,
expandSize, heap, -1, &resSize);
*pBuf = buffer;
return resSize;
default:
JPANIC(605, ":::??? bad sequence\n");
return 0;
}
}
+12 -11
View File
@@ -1,14 +1,13 @@
#include "JSystem/JKernel/JKRAram.h"
JKRAramBlock::JKRAramBlock(u32 address, u32 size, u32 freeSize, u8 groupID, bool tempMemory)
: mLink(this)
, mAddress(address)
, mSize(size)
, mFreeSize(freeSize)
, mGroupID(groupID)
, mIsTempMemory(tempMemory)
{
}
JKRAramBlock::JKRAramBlock(u32 address, u32 size, u32 freeSize, u8 groupID,
bool tempMemory)
: mLink(this),
mAddress(address),
mSize(size),
mFreeSize(freeSize),
mGroupID(groupID),
mIsTempMemory(tempMemory) {}
JKRAramBlock::~JKRAramBlock() {
JSULink<JKRAramBlock>* prev = this->mLink.getPrev();
@@ -28,7 +27,8 @@ JKRAramBlock* JKRAramBlock::allocHead(u32 size, u8 groupID, JKRAramHeap* heap) {
u32 address = this->mAddress + this->mSize;
u32 freeSize = this->mFreeSize - size;
JKRAramBlock* block = new(heap->mHeap, nullptr) JKRAramBlock(address, size, freeSize, groupID, false);
JKRAramBlock* block = new (heap->mHeap, nullptr)
JKRAramBlock(address, size, freeSize, groupID, false);
this->mFreeSize = 0;
this->mLink.mPtrList->insert(this->mLink.mNext, &block->mLink);
return block;
@@ -37,7 +37,8 @@ JKRAramBlock* JKRAramBlock::allocHead(u32 size, u8 groupID, JKRAramHeap* heap) {
JKRAramBlock* JKRAramBlock::allocTail(u32 size, u8 groupID, JKRAramHeap* heap) {
u32 address = this->mAddress + this->mSize + this->mFreeSize - size;
JKRAramBlock* block = new(heap->mHeap, nullptr) JKRAramBlock(address, size, 0, groupID, true);
JKRAramBlock* block =
new (heap->mHeap, nullptr) JKRAramBlock(address, size, 0, groupID, true);
this->mFreeSize -= size;
this->mLink.mPtrList->insert(this->mLink.mNext, &block->mLink);
return block;
+20 -17
View File
@@ -12,13 +12,13 @@ JKRAramHeap::JKRAramHeap(u32 baseAddress, u32 size) : JKRDisposer() {
this->mTailAddress = this->mHeadAddress + this->mSize;
this->mGroupID = 0xFF;
JKRAramBlock* block = new (this->mHeap, nullptr)
JKRAramBlock(this->mHeadAddress, 0, this->mSize, 0xFF, false);
JKRAramBlock(this->mHeadAddress, 0, this->mSize, 0xFF, false);
sAramList.append(&block->mLink);
}
JKRAramHeap::~JKRAramHeap() {
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd();) {
it != sAramList.getEnd();) {
delete (it++).getObject();
}
}
@@ -29,7 +29,8 @@ JKRAramBlock* JKRAramHeap::alloc(u32 size, JKRAramHeap::EAllocMode mode) {
if (mode == Head) {
block = this->allocFromHead(size);
} else {
}
else {
block = this->allocFromTail(size);
}
@@ -37,10 +38,9 @@ JKRAramBlock* JKRAramHeap::alloc(u32 size, JKRAramHeap::EAllocMode mode) {
return block;
}
/* Code retrieved from Twilight Princess Debug version & matched. Unused in AC. */
void JKRAramHeap::free(JKRAramBlock* block) {
delete block;
}
/* Code retrieved from Twilight Princess Debug version & matched. Unused in AC.
*/
void JKRAramHeap::free(JKRAramBlock* block) { delete block; }
JKRAramBlock* JKRAramHeap::allocFromHead(u32 size) {
size = ALIGN_NEXT(size, 32);
@@ -48,7 +48,7 @@ JKRAramBlock* JKRAramHeap::allocFromHead(u32 size) {
JKRAramBlock* block = nullptr;
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd(); it++) {
it != sAramList.getEnd(); it++) {
JKRAramBlock* n_block = it.getObject();
if (n_block->mFreeSize >= size && min_size > n_block->mFreeSize) {
min_size = n_block->mFreeSize;
@@ -71,7 +71,7 @@ JKRAramBlock* JKRAramHeap::allocFromTail(u32 size) {
size = ALIGN_NEXT(size, 32);
for (JSUListIterator<JKRAramBlock> it = sAramList.getLast();
it != sAramList.getEnd(); it--) {
it != sAramList.getEnd(); it--) {
JKRAramBlock* n_block = it.getObject();
if (n_block->mFreeSize >= size) {
@@ -96,23 +96,23 @@ void JKRAramHeap::dump() {
JREPORT(" attr address: size gid\n");
for (JSUListIterator<JKRAramBlock> listItr = sAramList.getFirst();
listItr != sAramList.getEnd(); listItr++) {
listItr != sAramList.getEnd(); listItr++) {
if (listItr->mSize != 0) {
JREPORTF("%s %08x: %08x %3d\n",
listItr->isTempMemory() ? " temp" : "alloc", listItr->mAddress,
listItr->mSize, listItr->mGroupID);
listItr->isTempMemory() ? " temp" : "alloc", listItr->mAddress,
listItr->mSize, listItr->mGroupID);
}
if (listItr->mFreeSize != 0) {
JREPORTF(" free %08x: %08x 0\n", listItr->mAddress + listItr->mSize,
listItr->mFreeSize);
listItr->mFreeSize);
}
total_used += listItr->mSize;
}
JREPORTF("%d / %d bytes (%6.2f%%) used\n", total_used, this->mSize,
(f32)total_used / (f32)this->mSize);
(f32)total_used / (f32)this->mSize);
this->unlock();
}
@@ -122,7 +122,8 @@ u32 JKRAramHeap::getFreeSize() {
u32 max_free = 0;
this->lock();
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst(); it != sAramList.getEnd(); it++) {
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd(); it++) {
if (it->mFreeSize > max_free) {
max_free = it->mFreeSize;
}
@@ -137,7 +138,8 @@ u32 JKRAramHeap::getTotalFreeSize() {
u32 total_free = 0;
this->lock();
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst(); it != sAramList.getEnd(); it++) {
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd(); it++) {
total_free += it->mFreeSize;
}
@@ -154,7 +156,8 @@ u32 JKRAramHeap::getUsedSize(u8 groupID) {
total_used = this->mSize - this->getTotalFreeSize();
}
else {
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst(); it != sAramList.getEnd(); it++) {
for (JSUListIterator<JKRAramBlock> it = sAramList.getFirst();
it != sAramList.getEnd(); it++) {
if (groupID == it->mGroupID) {
total_used += it->mSize;
}
+25 -17
View File
@@ -1,19 +1,20 @@
#include "types.h"
#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JKernel/JKRMacro.h"
#include "JSystem/JSystem.h"
#include "dolphin/ar.h"
#include "dolphin/os.h" /* TODO: OSReport lives in libforest in AC */
#include "dolphin/os/OSCache.h"
#include "dolphin/os/OSMessage.h"
#include "dolphin/os.h" /* TODO: OSReport lives in libforest in AC */
#include "JSystem/JKernel/JKRMacro.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JSystem.h"
#include "JSystem/JKernel/JKRAram.h"
#include "types.h"
JSUList<JKRAMCommand> JKRAramPiece::sAramPieceCommandList;
OSMutex JKRAramPiece::mMutex;
JKRAMCommand* JKRAramPiece::prepareCommand(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback) {
JKRAMCommand* JKRAramPiece::prepareCommand(
int direction, u32 source, u32 destination, u32 length,
JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback) {
JKRAMCommand* cmd = new (JKRGetSystemHeap(), -4) JKRAMCommand();
cmd->mDirection = direction;
cmd->mSource = source;
@@ -29,7 +30,9 @@ void JKRAramPiece::sendCommand(JKRAMCommand* cmd) {
JKRAramPiece::startDMA(cmd);
}
JKRAMCommand* JKRAramPiece::orderAsync(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback) {
JKRAMCommand* JKRAramPiece::orderAsync(
int direction, u32 source, u32 destination, u32 length,
JKRAramBlock* aramBlock, JKRAMCommand::AMCommandCallback callback) {
JKRAramPiece::lock();
if (!JKR_ISALIGNED32(source) || !JKR_ISALIGNED32(destination)) {
@@ -41,9 +44,11 @@ JKRAMCommand* JKRAramPiece::orderAsync(int direction, u32 source, u32 destinatio
}
JKRAramCommand* aramCmd = new (JKRGetSystemHeap(), -4) JKRAramCommand();
JKRAMCommand* cmd = JKRAramPiece::prepareCommand(direction, source, destination, length, aramBlock, callback);
JKRAMCommand* cmd = JKRAramPiece::prepareCommand(
direction, source, destination, length, aramBlock, callback);
aramCmd->setting(TRUE, cmd);
OSSendMessage((OSMessageQueue*)&JKRAram::sMessageQueue, (OSMessage)aramCmd, OS_MESSAGE_BLOCK);
OSSendMessage((OSMessageQueue*)&JKRAram::sMessageQueue, (OSMessage)aramCmd,
OS_MESSAGE_BLOCK);
if (cmd->mCallback != nullptr) {
JKRAramPiece::sAramPieceCommandList.append(&cmd->mAramPieceCommandLink);
}
@@ -76,11 +81,12 @@ bool JKRAramPiece::sync(JKRAMCommand* cmd, BOOL noBlock) {
}
}
bool JKRAramPiece::orderSync(int direction, u32 source, u32 destination, u32 length, JKRAramBlock* aramBlock) {
bool JKRAramPiece::orderSync(int direction, u32 source, u32 destination,
u32 length, JKRAramBlock* aramBlock) {
JKRAramPiece::lock();
JKRAMCommand* cmd = JKRAramPiece::orderAsync(direction, source, destination, length, aramBlock, nullptr);
JKRAMCommand* cmd = JKRAramPiece::orderAsync(direction, source, destination,
length, aramBlock, nullptr);
bool res = JKRAramPiece::sync(cmd, FALSE);
delete cmd;
@@ -96,7 +102,8 @@ void JKRAramPiece::startDMA(JKRAMCommand* cmd) {
DCStoreRange((u8*)cmd->mSource, cmd->mLength);
}
ARQPostRequest(cmd, 0, cmd->mDirection, 0, cmd->mSource, cmd->mDestination, cmd->mLength, JKRAramPiece::doneDMA);
ARQPostRequest(cmd, 0, cmd->mDirection, 0, cmd->mSource, cmd->mDestination,
cmd->mLength, JKRAramPiece::doneDMA);
}
void JKRAramPiece::doneDMA(u32 param) {
@@ -115,7 +122,8 @@ void JKRAramPiece::doneDMA(u32 param) {
}
else {
if (cmd->mCompletedMesgQueue != nullptr) {
OSSendMessage(cmd->mCompletedMesgQueue, (OSMessage)cmd, OS_MESSAGE_NOBLOCK);
OSSendMessage(cmd->mCompletedMesgQueue, (OSMessage)cmd,
OS_MESSAGE_NOBLOCK);
}
else {
OSSendMessage(&cmd->mMesgQueue, (OSMessage)cmd, OS_MESSAGE_NOBLOCK);
+213 -2
View File
@@ -1,4 +1,215 @@
#include "JKRAram.h"
#include "JSUStream.h"
#include <dolphin/os.h>
#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JSupport/JSUStream.h"
#include "JSystem/JSystem.h"
#include "JSystem/JUtility/JUTAssertion.h"
#include "types.h"
// From Pikmin Repo
OSMessage JKRAramStream::sMessageBuffer[4] = { 0 };
OSMessageQueue JKRAramStream::sMessageQueue = { 0 };
JKRAramStream* JKRAramStream::sAramStreamObject = nullptr;
u8* JKRAramStream::transBuffer = nullptr;
u32 JKRAramStream::transSize = nullptr;
JKRHeap* JKRAramStream::transHeap = nullptr;
JKRAramStream* JKRAramStream::create(s32 param) {
if (JKRAramStream::sAramStreamObject == nullptr) {
JKRAramStream::sAramStreamObject =
new (JKRGetSystemHeap(), 0) JKRAramStream(param);
setTransBuffer(nullptr, 0, nullptr);
}
return JKRAramStream::sAramStreamObject;
}
JKRAramStream::JKRAramStream(s32 priority) : JKRThread(0x4000, 0x10, priority) {
OSResumeThread(mThreadRecord);
}
JKRAramStream::~JKRAramStream() {};
void* JKRAramStream::run() {
OSMessage result;
OSInitMessageQueue(
&JKRAramStream::sMessageQueue, JKRAramStream::sMessageBuffer,
ARRAY_COUNT(sMessageBuffer)); // jank cast to void** to satisfy prototype
while (true) {
OSReceiveMessage(&JKRAramStream::sMessageQueue, &result, OS_MESSAGE_BLOCK);
JKRAramStreamCommand* command = static_cast<JKRAramStreamCommand*>(result);
switch (command->type) {
case JKRAramStreamCommand::ECT_READ:
readFromAram();
break;
case JKRAramStreamCommand::ECT_WRITE:
writeToAram(command);
break;
}
}
}
u32 JKRAramStream::readFromAram() {
return 1;
} // probably a define evaluating to 1
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 == nullptr) ? 0x8000 : bufferSize;
command->mTransferBufferSize = bufferSize;
command->mAllocatedTransferBuffer = false;
}
else {
bufferSize = (bufferSize == nullptr) ? 0x8000 : bufferSize;
if (heap) {
buffer = (u8*)JKRAllocFromHeap(heap, bufferSize, -0x20);
command->mTransferBuffer = buffer;
}
else {
buffer = (u8*)JKRAllocFromHeap(nullptr, bufferSize, -0x20);
command->mTransferBuffer = buffer;
}
command->mTransferBufferSize = bufferSize;
command->mAllocatedTransferBuffer = true;
}
if (!buffer) {
if (!heap) {
JKRGetCurrentHeap()->dump();
}
else {
heap->dump();
}
JPANIC(169, "abort\n");
}
if (buffer) {
command->mStream->seek(offset, SEEK_SET);
while (dstSize != 0) {
u32 length = (dstSize > bufferSize) ? bufferSize : dstSize;
s32 readLength = command->mStream->read(buffer, length);
JKRAramPcs(0, (u32)buffer, destination, length, nullptr);
dstSize -= length;
writtenLength += length;
destination += length;
}
if (command->mAllocatedTransferBuffer) {
JKRFree(buffer);
command->mAllocatedTransferBuffer = false;
}
}
OSSendMessage(&command->mMessageQueue, (OSMessage)writtenLength,
OS_MESSAGE_NOBLOCK);
return writtenLength;
};
/*
* Unused function, made-up contents. Do not take this seriously!
* While the function exists in the map, this is almost certainly incorrect.
* Should exist to generate JSURandomInputStream::getAvailable() const
* afterwards.
*/
JKRAramStreamCommand* JKRAramStream::write_StreamToAram_Async(
JSUFileInputStream* stream, JKRAramBlock* addr, u32 size, u32 offset) {
JKRAramStreamCommand* command =
new (JKRGetSystemHeap(), -4) JKRAramStreamCommand();
command->type = JKRAramStreamCommand::ECT_WRITE;
command->mAddress = (u32)addr;
command->mSize = size;
command->mStream = stream;
command->_28 = stream->getAvailable();
command->mOffset = offset;
command->mTransferBuffer = transBuffer;
command->mHeap = transHeap;
command->mTransferBufferSize = transSize;
OSInitMessageQueue(&command->mMessageQueue, &command->mMessage, 1);
OSSendMessage(&sMessageQueue, command, OS_MESSAGE_BLOCK);
return command;
}
JKRAramStreamCommand* JKRAramStream::write_StreamToAram_Async(
JSUFileInputStream* stream, u32 addr, u32 size, u32 offset) {
JKRAramStreamCommand* command =
new (JKRGetSystemHeap(), -4) JKRAramStreamCommand();
command->type = JKRAramStreamCommand::ECT_WRITE;
command->mAddress = addr;
command->mSize = size;
command->mStream = stream;
command->_28 = 0;
command->mOffset = offset;
command->mTransferBuffer = transBuffer;
command->mHeap = transHeap;
command->mTransferBufferSize = transSize;
OSInitMessageQueue(&command->mMessageQueue, &command->mMessage, 1);
OSSendMessage(&sMessageQueue, command, OS_MESSAGE_BLOCK);
return command;
}
JKRAramStreamCommand* JKRAramStream::sync(JKRAramStreamCommand* command,
BOOL isNonBlocking) {
OSMessage msg;
if (isNonBlocking == FALSE) {
OSReceiveMessage(&command->mMessageQueue, &msg, OS_MESSAGE_BLOCK);
if (msg == nullptr) {
command = nullptr;
return command;
}
else {
return command;
}
}
else {
BOOL receiveResult =
OSReceiveMessage(&command->mMessageQueue, &msg, OS_MESSAGE_NOBLOCK);
if (receiveResult == FALSE) {
command = nullptr;
return command;
}
else if (msg == nullptr) {
command = nullptr;
return command;
}
else {
return command;
}
}
}
void JKRAramStream::setTransBuffer(u8* buffer, u32 bufferSize, JKRHeap* heap) {
transBuffer = nullptr;
transSize = 0x8000;
transHeap = nullptr;
if (buffer) {
transBuffer = (u8*)ALIGN_NEXT((u32)buffer, 0x20);
}
if (bufferSize) {
transSize = ALIGN_PREV(bufferSize, 0x20);
}
if (heap && !buffer) {
transHeap = heap;
}
}
JKRAramStreamCommand::JKRAramStreamCommand() {
mAllocatedTransferBuffer = false;
}
+242
View File
@@ -0,0 +1,242 @@
#include <MSL_C/ctype.h>
#include <dolphin/string.h>
#include "JSystem/JKernel/JKRArchive.h"
#include "JSystem/JKernel/JKRFileLoader.h"
#include "types.h"
u32 JKRArchive::sCurrentDirID;
JKRArchive::JKRArchive()
{
mIsMounted = false;
mMountDirection = MOUNT_DIRECTION_HEAD;
}
JKRArchive::JKRArchive(s32 entryNum, JKRArchive::EMountMode mountMode)
: JKRFileLoader()
{
mIsMounted = false;
mMountMode = mountMode;
mMountCount = 1;
_54 = 1;
mHeap = JKRHeap::findFromRoot(this);
if (!mHeap)
{
mHeap = JKRHeap::sCurrentHeap;
}
mEntryNum = entryNum;
if (sCurrentVolume == nullptr)
{
sCurrentDirID = 0;
sCurrentVolume = this;
}
}
JKRArchive::JKRArchive(const char* p1, JKRArchive::EMountMode mountMode)
{
// UNUSED FUNCTION
}
JKRArchive::~JKRArchive() {}
bool JKRArchive::isSameName(JKRArchive::CArcName& archiveName,
u32 nameTableOffset, u16 hash) const
{
u16 arcHash = archiveName.getHash();
if (arcHash != hash)
return false;
return strcmp(&mStrTable[nameTableOffset], archiveName.getString()) == 0;
}
JKRArchive::SDIDirEntry* JKRArchive::findResType(u32 type) const
{
SDIDirEntry* dirEntry = mDirectories;
for (u32 i = 0; i < mArcInfoBlock->num_nodes; i++, dirEntry++)
{
if (dirEntry->mType == type)
{
return dirEntry;
}
}
return nullptr;
}
JKRArchive::SDIDirEntry* JKRArchive::findDirectory(const char* path,
u32 index) const
{
if (path == nullptr)
{
return &mDirectories[index];
}
CArcName arcName(&path, '/');
SDIDirEntry* dirEntry = &mDirectories[index];
SDIFileEntry* entry = &mFileEntries[dirEntry->mFirstIdx];
for (int i = 0; i < dirEntry->mNum; entry++, i++)
{
if (isSameName(arcName, entry->mFlag & 0xFFFFFF, entry->mHash))
{
if ((entry->mFlag >> 24) & 0x02)
{
return findDirectory(path, entry->mDataOffset);
}
break;
}
}
return nullptr;
}
JKRArchive::SDIFileEntry* JKRArchive::findTypeResource(u32 type,
const char* name) const
{
if (type != 0)
{
CArcName arcName;
arcName.store(name);
SDIDirEntry* dirEntry = findResType(type);
if (dirEntry != nullptr)
{
SDIFileEntry* fileEntry = mFileEntries + dirEntry->mFirstIdx;
for (int i = 0; i < dirEntry->mNum; fileEntry++, i++)
{
if (isSameName(arcName, fileEntry->mFlag & 0xFFFFFF,
fileEntry->mHash))
{
return fileEntry;
}
}
}
}
return nullptr;
}
JKRArchive::SDIFileEntry* JKRArchive::findFsResource(const char* path,
u32 index) const
{
if (path)
{
CArcName arcName(&path, '/');
SDIDirEntry* dirEntry = &mDirectories[index];
SDIFileEntry* entry = &mFileEntries[dirEntry->mFirstIdx];
for (int i = 0; i < dirEntry->mNum; entry++, i++)
{
if (isSameName(arcName, entry->mFlag & 0xFFFFFF, entry->mHash))
{
if (((entry->mFlag >> 0x18) & 2))
{
return findFsResource(path, entry->mDataOffset);
}
if (path == 0)
{
return entry;
}
return nullptr;
}
}
}
return nullptr;
}
JKRArchive::SDIFileEntry* JKRArchive::findIdxResource(u32 idx) const
{
if (idx < mArcInfoBlock->num_file_entries)
{
return mFileEntries + idx;
}
return nullptr;
}
JKRArchive::SDIFileEntry* JKRArchive::findNameResource(const char* name) const
{
SDIFileEntry* fileEntry = mFileEntries;
CArcName arcName(name);
for (int i = 0; i < mArcInfoBlock->num_file_entries; fileEntry++, i++)
{
if (isSameName(arcName, fileEntry->mFlag & 0xFFFFFF, fileEntry->mHash))
{
return fileEntry;
}
}
return nullptr;
}
JKRArchive::SDIFileEntry* JKRArchive::findPtrResource(const void* ptr) const
{
SDIFileEntry* entry = mFileEntries;
for (u32 i = 0; i < mArcInfoBlock->num_file_entries; entry++, i++)
{
if (entry->mData == ptr)
{
return entry;
}
}
return nullptr;
}
JKRArchive::SDIFileEntry* JKRArchive::findIdResource(u16 id) const
{
SDIFileEntry* entry;
if (id != 0xFFFF)
{
entry = &mFileEntries[id];
if (entry->mFileID == id && (entry->getFlag01()))
{
return entry;
}
entry = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; entry++, i++)
{
if (entry->mFileID == id && (entry->getFlag01()))
{
return entry;
}
}
}
return nullptr;
}
void JKRArchive::CArcName::store(const char* name)
{
mHash = 0;
int count = 0;
while (*name)
{
int lower = tolower(*name);
mHash = lower + mHash * 3;
if (count < 0x100)
{
mString[count++] = lower;
}
name++;
}
_02 = count;
mString[count] = '\0';
}
const char* JKRArchive::CArcName::store(const char* name, char endChar)
{
mHash = 0;
int count = 0;
for (; *name && *name != endChar; name++)
{
int lower = tolower(*name);
mHash = lower + mHash * 3;
if (count < 0x100)
{
mString[count++] = lower;
}
}
_02 = count;
mString[count] = '\0';
if (*name == 0)
return nullptr;
return name + 1;
}
+340
View File
@@ -0,0 +1,340 @@
#include <dolphin/dvd.h>
#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JKernel/JKRArchive.h"
#include "JSystem/JKernel/JKRDisposer.h"
#include "JSystem/JKernel/JKRFileFinder.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JUtility/JUTAssertion.h"
#include "types.h"
// TODO: this file should emit a vtable but it doesn't, luckily JKRArchivePri
// does that and it doesn't cause any issues
JKRArchive* JKRArchive::check_mount_already(s32 entryNum, JKRHeap* pHeap) {
// UNUSED FUNCTION
JKRHeap* heap = pHeap;
if (heap == nullptr) {
heap = JKRGetCurrentHeap();
}
JSUList<JKRFileLoader>& volumeList = JKRArchive::sVolumeList;
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd();
++iterator) {
if (iterator->getVolumeType() == 'RARC') {
JKRArchive* archive =
(JKRArchive*)
iterator.getObject(); // in TP debug it calls operator-> ?
if (archive->mEntryNum == entryNum && archive->mHeap == heap) {
archive->mMountCount++;
return archive;
}
}
}
return nullptr;
}
JKRArchive* JKRArchive::check_mount_already(s32 entryNum) {
JSUList<JKRFileLoader>& volumeList = JKRArchive::sVolumeList;
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd();
++iterator) {
if (iterator->getVolumeType() == 'RARC') {
JKRArchive* archive =
(JKRArchive*)
iterator.getObject(); // in TP debug it calls operator-> ?
if (archive->mEntryNum == entryNum) {
archive->mMountCount++;
return archive;
}
}
}
return nullptr;
}
JKRArchive* JKRArchive::mount(const char* path, EMountMode mode, JKRHeap* heap,
EMountDirection direction) {
int entryNum = DVDConvertPathToEntrynum((char*)path);
if (entryNum < 0) return nullptr;
JKRArchive* mountedArchive = check_mount_already(entryNum);
if (mountedArchive != nullptr) {
return mountedArchive;
}
int alignment = (direction == MOUNT_DIRECTION_HEAD) ? 4 : -4;
JKRArchive* archive;
switch (mode) {
case MOUNT_MEM:
if (entryNum == -1)
archive = nullptr;
else
archive = new (heap, alignment) JKRMemArchive(entryNum, direction);
break;
case MOUNT_ARAM:
archive = new (heap, alignment) JKRAramArchive(entryNum, direction);
break;
case MOUNT_DVD:
archive = new (heap, alignment) JKRDvdArchive(entryNum, direction);
break;
case MOUNT_COMP:
archive = new (heap, alignment) JKRCompArchive(entryNum, direction);
break;
}
if (archive != nullptr && archive->getMountMode() == UNKNOWN_MOUNT_MODE) {
delete archive;
archive = nullptr;
}
return archive;
}
JKRArchive* JKRArchive::mount(void* p1, JKRHeap* heap,
EMountDirection mountDirection) {
JKRArchive* archive = check_mount_already((s32)p1, heap);
if (archive != nullptr) {
return archive;
}
return new (heap, (mountDirection == MOUNT_DIRECTION_HEAD) ? 4 : -4)
JKRMemArchive(p1, 0xFFFF, MBF_0);
}
JKRArchive* JKRArchive::mount(s32 entryNum, EMountMode mountMode, JKRHeap* heap,
EMountDirection mountDirection) {
JKRArchive* archive = check_mount_already(entryNum, heap);
if (archive) {
return archive;
}
else {
int i = (mountDirection == MOUNT_DIRECTION_HEAD) ? 4 : -4;
JKRArchive* archive;
switch (mountMode) {
case MOUNT_MEM:
archive = new (heap, i) JKRMemArchive(entryNum, mountDirection);
break;
case MOUNT_ARAM:
archive = new (heap, i) JKRAramArchive(entryNum, mountDirection);
break;
case MOUNT_DVD:
archive = new (heap, i) JKRDvdArchive(entryNum, mountDirection);
break;
case MOUNT_COMP:
archive = new (heap, i) JKRCompArchive(entryNum, mountDirection);
break;
}
if (archive != nullptr && archive->getMountMode() == UNKNOWN_MOUNT_MODE) {
delete archive;
archive = nullptr;
}
return archive;
}
}
bool JKRArchive::becomeCurrent(const char* path) {
SDIDirEntry* entry;
if (*path == '/') {
const char* directoryName = path + 1;
if (*directoryName == '\0') {
directoryName = nullptr;
}
entry = findDirectory(directoryName, 0);
}
else {
entry = findDirectory(path, sCurrentDirID);
}
bool result = (entry != nullptr);
if (result) {
sCurrentVolume = this;
sCurrentDirID = (entry - mDirectories);
}
return result;
}
bool JKRArchive::getDirEntry(JKRArchive::SDirEntry* dirEntry, u32 p2) const {
SDIFileEntry* fileEntry = findIdxResource(p2);
if (!fileEntry) {
return false;
}
dirEntry->mFlags = fileEntry->mFlag >> 0x18;
dirEntry->mID = fileEntry->mFileID;
dirEntry->mName = (char*)mStrTable + (fileEntry->mFlag & 0xFFFFFF);
return true;
}
void* JKRArchive::getGlbResource(u32 type, const char* name,
JKRArchive* archive) {
void* resource = nullptr;
if (archive) {
return archive->getResource(type, name);
}
for (JSULink<JKRFileLoader>* link = sVolumeList.getFirst(); link != nullptr;
link = link->getNext()) {
if (link->getObject()->getVolumeType() == 'RARC' &&
(resource = link->getObject()->getResource(type, name))) {
break;
}
}
return resource;
}
void* JKRArchive::getResource(const char* path) {
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry;
if (*path == '/') {
fileEntry = findFsResource(path + 1, 0);
}
else {
fileEntry = findFsResource(path, sCurrentDirID);
}
return (fileEntry != nullptr) ? (void*)fetchResource(fileEntry, nullptr)
: nullptr;
}
void* JKRArchive::getResource(u32 type, const char* name) {
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry;
if (type == 0 || type == '????') {
fileEntry = findNameResource(name);
}
else {
fileEntry = findTypeResource(type, name);
}
return (fileEntry != nullptr) ? (void*)fetchResource(fileEntry, nullptr)
: nullptr;
}
void* JKRArchive::getIdxResource(u32 index) {
SDIFileEntry* fileEntry = findIdxResource(index);
return (fileEntry != nullptr) ? (void*)fetchResource(fileEntry, nullptr)
: nullptr;
}
size_t JKRArchive::readResource(void* resourceBuffer, u32 bufferSize, u32 type,
const char* name) {
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry;
if (type == 0 || type == '????') {
fileEntry = findNameResource(name);
}
else {
fileEntry = findTypeResource(type, name);
}
if (fileEntry) {
u32 resourceSize;
fetchResource(resourceBuffer, bufferSize, fileEntry, &resourceSize,
EXPAND_SWITCH_DECOMPRESS);
return resourceSize;
}
return 0;
}
// Returns the size of the resource at the given path, or 0 if not found.
size_t JKRArchive::readResource(void* resourceBuffer, u32 bufferSize,
const char* path,
JKRExpandSwitch expandSwitch) {
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry;
if (*path == '/') {
fileEntry = findFsResource(path + 1, 0);
}
else {
fileEntry = findFsResource(path, sCurrentDirID);
}
if (fileEntry) {
u32 resourceSize;
fetchResource(resourceBuffer, bufferSize, fileEntry, &resourceSize,
expandSwitch);
return resourceSize;
}
return 0;
}
// Returns the size of the resource with the given ID, or 0 if not found.
size_t JKRArchive::readResource(void* resourceBuffer, u32 bufferSize, u16 id) {
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry = findIdResource(id);
if (fileEntry) {
u32 resSize;
fetchResource(resourceBuffer, bufferSize, fileEntry, &resSize,
EXPAND_SWITCH_DEFAULT);
return resSize;
}
return 0;
}
// This function is currently full off bugs, it doesn't increase the pointer to
// the file entries, and sets the pointer of mData to null before it's sent to
// free
void JKRArchive::removeResourceAll() {
if (mArcInfoBlock && mMountMode != MOUNT_MEM) {
SDIFileEntry* entry = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
if (entry->mData) {
entry->mData = nullptr;
JKRFreeToHeap(mHeap, entry->mData);
}
}
}
}
bool JKRArchive::removeResource(void* resource) {
JUT_ASSERT(resource != 0);
SDIFileEntry* entry = findPtrResource(resource);
if (entry == nullptr) {
return false;
}
entry->mData = nullptr;
JKRHeap::free(resource, mHeap);
return true;
}
bool JKRArchive::detachResource(void* resource) {
JUT_ASSERT(resource != 0);
SDIFileEntry* entry = findPtrResource(resource);
if (entry == nullptr) {
return false;
}
entry->mData = nullptr;
return true;
}
s32 JKRArchive::getResSize(const void* resource) const {
JUT_ASSERT(resource != 0);
SDIFileEntry* entry = findPtrResource(resource);
return (entry == nullptr) ? -1 : entry->getSize();
}
u32 JKRArchive::countFile(const char* path) const {
SDIDirEntry* dirEntry;
if (*path == '/') {
const char* pathPtr = path + 1;
if (*pathPtr == '\0') {
pathPtr = nullptr;
}
dirEntry = findDirectory(pathPtr, 0);
}
else {
dirEntry = findDirectory(path, sCurrentDirID);
}
return (dirEntry) ? dirEntry->mNum : 0;
}
JKRFileFinder* JKRArchive::getFirstFile(const char* path) const {
SDIDirEntry* dirEntry;
if (*path == '/') {
const char* pathPtr = path + 1;
if (*pathPtr == '\0') {
pathPtr = nullptr;
}
dirEntry = findDirectory(pathPtr, 0);
}
else {
dirEntry = findDirectory(path, sCurrentDirID);
}
if (dirEntry) {
return new (JKRGetSystemHeap(), 0) JKRArcFinder(
const_cast<JKRArchive*>(this), dirEntry->mFirstIdx, dirEntry->mNum);
}
return nullptr;
}
+342
View File
@@ -0,0 +1,342 @@
#include <dolphin/os/OSCache.h>
#include <dolphin/string.h>
#include "JSystem/JKernel/JKRArchive.h"
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JKernel/JKRDvdAramRipper.h"
#include "JSystem/JKernel/JKRDvdRipper.h"
#include "JSystem/JSystem.h"
#include "JSystem/JUtility/JUTAssertion.h"
JKRCompArchive::JKRCompArchive(long entryNum, EMountDirection mountDirection)
: JKRArchive(entryNum, MOUNT_COMP) {
mMountDirection = mountDirection;
if (!open(entryNum)) {
return;
}
else {
mVolumeType = 'RARC';
mVolumeName = &mStrTable[mDirectories->mOffset];
sVolumeList.prepend(&mFileLoaderLink);
mIsMounted = true;
}
}
#ifdef DEBUG
void stringGen() {
JUT_PANIC("isMounted()");
JUT_PANIC("mMountCount == 1");
}
#endif
JKRCompArchive::~JKRCompArchive() {
if (mArcInfoBlock) {
SDIFileEntry* fileEntries = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
u32 flag = (fileEntries->mFlag >> 24);
if ((flag & 16) == 0 && fileEntries->mData) {
JKRFreeToHeap(mHeap, fileEntries->mData);
}
fileEntries++;
}
JKRFreeToHeap(mHeap, mArcInfoBlock);
mArcInfoBlock = nullptr;
}
if (mAramPart) {
delete mAramPart;
}
if (mDvdFile) {
delete mDvdFile;
}
sVolumeList.remove(&mFileLoaderLink);
mIsMounted = false;
}
bool JKRCompArchive::open(long entryNum) {
mArcInfoBlock = nullptr;
_60 = 0;
mAramPart = nullptr;
_68 = 0;
mSizeOfMemPart = 0;
mSizeOfAramPart = 0;
_78 = 0;
mDirectories = nullptr;
mFileEntries = nullptr;
mStrTable = nullptr;
mDvdFile = new (JKRGetSystemHeap(), 0) JKRDvdFile(entryNum);
if (mDvdFile == nullptr) {
mMountMode = 0;
return 0;
}
SArcHeader* arcHeader = (SArcHeader*)JKRAllocFromSysHeap(
sizeof(SArcHeader), -32); // NOTE: unconfirmed if this struct is used
if (arcHeader == nullptr) {
mMountMode = 0;
}
else {
int alignment;
JKRDvdToMainRam(entryNum, (u8*)arcHeader, EXPAND_SWITCH_DECOMPRESS, 32,
nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 0, &mCompression);
mSizeOfMemPart = arcHeader->_14;
mSizeOfAramPart = arcHeader->_18;
JUT_ASSERT((mSizeOfMemPart & 0x1f) == 0);
JUT_ASSERT((mSizeOfAramPart & 0x1f) == 0);
switch (mCompression) {
case JKRCOMPRESSION_NONE:
case JKRCOMPRESSION_YAZ0:
alignment = mMountDirection == 1 ? 32 : -32;
mArcInfoBlock = (SArcDataInfo*)JKRAllocFromHeap(
mHeap, arcHeader->file_data_offset + mSizeOfMemPart, alignment);
if (mArcInfoBlock == nullptr) {
mMountMode = 0;
}
else {
JKRDvdToMainRam(entryNum, (u8*)mArcInfoBlock,
EXPAND_SWITCH_DECOMPRESS,
(u32)arcHeader->file_data_offset + mSizeOfMemPart,
nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 0x20, nullptr);
_60 = (u32)mArcInfoBlock + arcHeader->file_data_offset;
if (mSizeOfAramPart != 0) {
mAramPart = JKRAllocFromAram(mSizeOfAramPart, JKRAramHeap::Head);
if (mAramPart == nullptr) {
mMountMode = 0;
break;
}
JKRDvdToAram(entryNum, mAramPart->getAddress(),
EXPAND_SWITCH_DECOMPRESS,
arcHeader->header_length +
arcHeader->file_data_offset + mSizeOfMemPart,
0);
}
mDirectories =
(SDIDirEntry*)((u32)mArcInfoBlock + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u32)mArcInfoBlock +
mArcInfoBlock->file_entry_offset);
mStrTable = (const char*)((u32)mArcInfoBlock +
mArcInfoBlock->string_table_offset);
_68 = arcHeader->header_length + arcHeader->file_data_offset;
}
break;
case JKRCOMPRESSION_YAY0:
u32 alignedSize = ALIGN_NEXT(mDvdFile->getFileSize(), 32);
alignment = ((mMountDirection == 1) ? 32 : -32);
u8* buf = (u8*)JKRAllocFromSysHeap(alignedSize, -alignment);
if (buf == nullptr) {
mMountMode = 0;
}
else {
JKRDvdToMainRam(entryNum, buf, EXPAND_SWITCH_NONE, alignedSize,
nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 0, nullptr);
u32 expandSize = ALIGN_NEXT(JKRDecompExpandSize(buf), 32);
u8* mem = (u8*)JKRAllocFromHeap(mHeap, expandSize, -alignment);
if (mem == nullptr) {
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 == nullptr) {
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));
_60 = (u32)mArcInfoBlock + arcHeader->file_data_offset;
if (mSizeOfAramPart != 0) {
mAramPart =
JKRAllocFromAram(mSizeOfAramPart, JKRAramHeap::Head);
if (mAramPart == nullptr) {
mMountMode = 0;
}
else {
JKRMainRamToAram(
(u8*)mem + arcHeader->header_length +
arcHeader->file_data_offset + mSizeOfMemPart,
mAramPart->getAddress(), mSizeOfAramPart,
EXPAND_SWITCH_DEFAULT, 0, nullptr, -1, nullptr);
}
}
}
}
}
mDirectories =
(SDIDirEntry*)((u32)mArcInfoBlock + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u32)mArcInfoBlock +
mArcInfoBlock->file_entry_offset);
mStrTable = (const char*)((u32)mArcInfoBlock +
mArcInfoBlock->string_table_offset);
_68 = arcHeader->header_length + arcHeader->file_data_offset;
break;
}
}
if (arcHeader) {
JKRFreeToHeap(mHeap, arcHeader);
}
if (mMountMode == 0) {
JREPORTF(0, ":::[%s: %d] Cannot alloc memory in mounting CompArchive\n",
__FILE__, 567); // Macro?
if (mDvdFile) {
delete mDvdFile;
mDvdFile = nullptr;
}
}
return mMountMode != 0;
}
void* JKRCompArchive::fetchResource(SDIFileEntry* fileEntry, u32* pSize) {
JUT_ASSERT(isMounted());
u32 ptrSize;
if (fileEntry->mData == nullptr) {
u32 flag = fileEntry->mFlag >> 0x18;
if (flag & 0x10) {
fileEntry->mData = (void*)(_60 + fileEntry->mDataOffset);
if (pSize) *pSize = fileEntry->mSize;
}
else if (flag & 0x20) {
u32 address = mAramPart->getAddress();
int compression =
JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
u8* data;
u32 size = JKRAramArchive::fetchResource_subroutine(
fileEntry->mDataOffset + address - mSizeOfMemPart, fileEntry->mSize,
mHeap, compression, &data);
if (pSize) *pSize = size;
fileEntry->mData = data;
}
else if (flag & 0x40) {
int compression =
JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
u8* data;
u32 size = JKRDvdArchive::fetchResource_subroutine(
mEntryNum, _68 + fileEntry->mDataOffset, fileEntry->mSize, mHeap,
compression, mCompression, &data);
if (pSize) *pSize = size;
fileEntry->mData = data;
}
}
else if (pSize) {
*pSize = fileEntry->mSize;
}
return fileEntry->mData;
}
void* JKRCompArchive::fetchResource(void* data, u32 compressedSize,
SDIFileEntry* fileEntry, u32* pSize,
JKRExpandSwitch expandSwitch) {
// u32 size = 0;
JUT_ASSERT(isMounted());
u32 size = ALIGN_NEXT(fileEntry->mSize, 32);
u32 expandSize = 0;
if (size == 0) JPANIC(651, ":::bad resource size. size = 0\n");
if (fileEntry->mData) {
if (size > (compressedSize & ~31)) {
size = (compressedSize & ~31);
}
JKRHeap::copyMemory(data, fileEntry->mData, size);
expandSize = size;
}
else {
u32 fileFlag = fileEntry->mFlag >> 0x18;
int compression = JKRConvertAttrToCompressionType(fileFlag);
if (expandSwitch != EXPAND_SWITCH_DECOMPRESS) compression = 0;
if (fileFlag & 0x10) {
if (size > (compressedSize & ~31)) {
size = (compressedSize & ~31);
}
if (FLAG_ON(fileFlag, 4)) {
JKRHeap::copyMemory(data, (void*)(_60 + fileEntry->mDataOffset), size);
}
else {
u8* header = (u8*)(_60 + fileEntry->mDataOffset);
expandSize = JKRDecompExpandSize(header);
expandSize =
(expandSize > compressedSize) ? compressedSize : expandSize;
JKRDecompress(header, (u8*)data, expandSize, 0);
}
expandSize = JKRMemArchive::fetchResource_subroutine(
(u8*)(_60 + fileEntry->mDataOffset), size, (u8*)data,
compressedSize, compression);
}
else if (fileFlag & 0x20) {
expandSize = JKRAramArchive::fetchResource_subroutine(
fileEntry->mDataOffset + mAramPart->getAddress() - mSizeOfMemPart,
size, (u8*)data, compressedSize, compression);
}
else if (fileFlag & 0x40) {
expandSize = JKRDvdArchive::fetchResource_subroutine(
mEntryNum, _68 + fileEntry->mDataOffset, size, (u8*)data,
compressedSize, compression, mCompression);
}
else {
JPANIC(731, ":::CompArchive: bad mode.");
}
}
if (pSize) {
*pSize = expandSize;
}
return data;
}
void JKRCompArchive::removeResourceAll() {
if (mArcInfoBlock && mMountMode != MOUNT_MEM) {
SDIFileEntry* fileEntry = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++) {
u32 flag = fileEntry->mFlag >> 0x18;
if (fileEntry->mData) {
if ((flag & 0x10) == 0) {
JKRFreeToHeap(mHeap, fileEntry->mData);
}
fileEntry->mData = nullptr;
}
}
}
}
bool JKRCompArchive::removeResource(void* resource) {
SDIFileEntry* fileEntry = findPtrResource(resource);
if (!fileEntry) return false;
if (((fileEntry->mFlag >> 0x18) & 0x10) == 0) {
JKRFreeToHeap(mHeap, resource);
}
fileEntry->mData = nullptr;
return true;
}
+151 -155
View File
@@ -1,40 +1,45 @@
#include "types.h"
#include "dolphin/os/OSMessage.h"
#include "JSystem/JSystem.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JSystem.h"
#include "dolphin/os/OSMessage.h"
#include "types.h"
OSMessage JKRDecomp::sMessageBuffer[JKRDECOMP_MSG_BUF_COUNT] = { 0 };
OSMessageQueue JKRDecomp::sMessageQueue = { 0 };
JKRDecomp* JKRDecomp::sDecompObject;
JKRDecomp* JKRDecomp::create(s32 decompPriority) {
if (JKRDecomp::sDecompObject == nullptr) {
JKRDecomp::sDecompObject = new(JKRGetSystemHeap(), 0) JKRDecomp(decompPriority);
JKRDecomp::sDecompObject =
new (JKRGetSystemHeap(), 0) JKRDecomp(decompPriority);
}
return JKRDecomp::sDecompObject;
}
JKRDecomp::JKRDecomp(s32 priority) : JKRThread(JKRDECOMP_STACK_SIZE, JKRDECOMP_THREAD_MSG_BUF_COUNT, priority) {
JKRDecomp::JKRDecomp(s32 priority)
: JKRThread(JKRDECOMP_STACK_SIZE, JKRDECOMP_THREAD_MSG_BUF_COUNT,
priority) {
OSResumeThread(this->mThreadRecord);
}
JKRDecomp::~JKRDecomp() { }
JKRDecomp::~JKRDecomp() {}
void* JKRDecomp::run() {
OSMessage recMesg;
JKRDecompCommand* cmd;
OSInitMessageQueue(&JKRDecomp::sMessageQueue, JKRDecomp::sMessageBuffer, JKRDECOMP_MSG_BUF_COUNT);
OSInitMessageQueue(&JKRDecomp::sMessageQueue, JKRDecomp::sMessageBuffer,
JKRDECOMP_MSG_BUF_COUNT);
while (true) {
while (true) {
while (true) {
OSReceiveMessage(&JKRDecomp::sMessageQueue, &recMesg, OS_MESSAGE_BLOCK);
cmd = static_cast<JKRDecompCommand*>(recMesg);
JKRDecomp::decode(cmd->mSrcBuffer, cmd->mDstBuffer, cmd->mSrcLength, cmd->mSkipCount);
JKRDecomp::decode(cmd->mSrcBuffer, cmd->mDstBuffer, cmd->mSrcLength,
cmd->mSkipCount);
if (cmd->transferType == JKRDecompCommand::MRAM) {
break;
@@ -61,9 +66,11 @@ void* JKRDecomp::run() {
}
}
JKRDecompCommand* JKRDecomp::prepareCommand(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount, DecompCallback* callback) {
JKRDecompCommand* cmd = new(JKRGetSystemHeap(), -4) JKRDecompCommand();
JKRDecompCommand* JKRDecomp::prepareCommand(u8* srcBuffer, u8* dstBuffer,
u32 srcLength, u32 skipCount,
DecompCallback* callback) {
JKRDecompCommand* cmd = new (JKRGetSystemHeap(), -4) JKRDecompCommand();
cmd->mSrcBuffer = srcBuffer;
cmd->mDstBuffer = dstBuffer;
cmd->mSrcLength = srcLength;
@@ -74,7 +81,8 @@ JKRDecompCommand* JKRDecomp::prepareCommand(u8* srcBuffer, u8* dstBuffer, u32 sr
}
BOOL JKRDecomp::sendCommand(JKRDecompCommand* cmd) {
BOOL res = OSSendMessage(&JKRDecomp::sMessageQueue, (OSMessage)cmd, OS_MESSAGE_BLOCK);
BOOL res = OSSendMessage(&JKRDecomp::sMessageQueue, (OSMessage)cmd,
OS_MESSAGE_BLOCK);
#ifdef JSYSTEM_DEBUG
if (res == FALSE) {
@@ -85,8 +93,11 @@ BOOL JKRDecomp::sendCommand(JKRDecompCommand* cmd) {
return res;
}
JKRDecompCommand* JKRDecomp::orderAsync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount, DecompCallback* callback) {
JKRDecompCommand* cmd = JKRDecomp::prepareCommand(srcBuffer, dstBuffer, srcLength, skipCount, callback);
JKRDecompCommand* JKRDecomp::orderAsync(u8* srcBuffer, u8* dstBuffer,
u32 srcLength, u32 skipCount,
DecompCallback* callback) {
JKRDecompCommand* cmd = JKRDecomp::prepareCommand(
srcBuffer, dstBuffer, srcLength, skipCount, callback);
JKRDecomp::sendCommand(cmd);
return cmd;
}
@@ -99,18 +110,22 @@ bool JKRDecomp::sync(JKRDecompCommand* cmd, BOOL noBlock) {
return true;
}
else {
return OSReceiveMessage(&cmd->mMesgQueue, &msg, OS_MESSAGE_NOBLOCK) != FALSE;
return OSReceiveMessage(&cmd->mMesgQueue, &msg, OS_MESSAGE_NOBLOCK) !=
FALSE;
}
}
bool JKRDecomp::orderSync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount) {
JKRDecompCommand* cmd = JKRDecomp::orderAsync(srcBuffer, dstBuffer, srcLength, skipCount, nullptr);
bool JKRDecomp::orderSync(u8* srcBuffer, u8* dstBuffer, u32 srcLength,
u32 skipCount) {
JKRDecompCommand* cmd = JKRDecomp::orderAsync(srcBuffer, dstBuffer, srcLength,
skipCount, nullptr);
bool res = JKRDecomp::sync(cmd, FALSE);
delete cmd;
return res;
}
void JKRDecomp::decode(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCount) {
void JKRDecomp::decode(u8* srcBuffer, u8* dstBuffer, u32 srcLength,
u32 skipCount) {
CompressionMode mode = JKRDecomp::checkCompressed(srcBuffer);
if (mode == SZP) {
JKRDecomp::decodeSZP(srcBuffer, dstBuffer, srcLength, skipCount);
@@ -120,154 +135,135 @@ void JKRDecomp::decode(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 skipCoun
}
}
void JKRDecomp::decodeSZP(u8 *src, u8 *dst, u32 srcLength, u32 skipCount)
{
int srcChunkOffset;
int count;
int dstOffset;
u32 length;
int linkInfo;
int offset;
int i;
void JKRDecomp::decodeSZP(u8* src, u8* dst, u32 srcLength, u32 skipCount) {
int srcChunkOffset;
int count;
int dstOffset;
u32 length;
int linkInfo;
int offset;
int i;
int decodedSize = JKRDECOMP_READU32BE(src, 4);
int linkTableOffset = JKRDECOMP_READU32BE(src, 8);
int srcDataOffset = JKRDECOMP_READU32BE(src, 12);
int decodedSize = JKRDECOMP_READU32BE(src, 4);
int linkTableOffset = JKRDECOMP_READU32BE(src, 8);
int srcDataOffset = JKRDECOMP_READU32BE(src, 12);
dstOffset = 0;
u32 counter = 0; // curently counter gets assembled before the READ_U32 operations
srcChunkOffset = 16;
dstOffset = 0;
u32 counter =
0; // curently counter gets assembled before the READ_U32 operations
srcChunkOffset = 16;
u32 chunkBits;
if (srcLength == 0)
return;
if (skipCount > decodedSize)
return;
u32 chunkBits;
if (srcLength == 0) return;
if (skipCount > decodedSize) return;
length = srcLength;
do
{
if (counter == 0)
{
chunkBits = JKRDECOMP_READU32BE(src, srcChunkOffset);
srcChunkOffset += sizeof(u32);
counter = sizeof(u32) * 8;
}
length = srcLength;
do {
if (counter == 0) {
chunkBits = JKRDECOMP_READU32BE(src, srcChunkOffset);
srcChunkOffset += sizeof(u32);
counter = sizeof(u32) * 8;
}
if (chunkBits & 0x80000000)
{
if (skipCount == 0)
{
dst[dstOffset] = src[srcDataOffset];
length--;
if (length == 0)
return;
}
else
{
skipCount--;
}
dstOffset++;
srcDataOffset++;
if (chunkBits & 0x80000000) {
if (skipCount == 0) {
dst[dstOffset] = src[srcDataOffset];
length--;
if (length == 0) return;
}
else {
skipCount--;
}
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 ((int)count > decodedSize - dstOffset) count = decodedSize - dstOffset;
for (i = 0; i < (int)count; i++, dstOffset++, offset++) {
if (skipCount == 0) {
dst[dstOffset] = dst[offset - 1];
length--;
if (length == 0) return;
}
else
{
linkInfo = src[linkTableOffset] << 8 | src[linkTableOffset + 1];
linkTableOffset += sizeof(u16);
skipCount--;
}
}
offset = dstOffset - (linkInfo & 0xFFF);
count = (linkInfo >> 12);
if (count == 0)
{
count = (u32)src[srcDataOffset++] + 0x12;
}
else
count += 2;
if ((int)count > decodedSize - dstOffset)
count = decodedSize - dstOffset;
for (i = 0; i < (int)count; i++, dstOffset++, offset++)
{
if (skipCount == 0)
{
dst[dstOffset] = dst[offset - 1];
length--;
if (length == 0)
return;
}
else
skipCount--;
}
}
chunkBits <<= 1;
counter--;
} while (dstOffset < decodedSize);
chunkBits <<= 1;
counter--;
} while (dstOffset < decodedSize);
}
void JKRDecomp::decodeSZS(u8 *src_buffer, u8 *dst_buffer, u32 srcSize, u32 skipCount) {
void JKRDecomp::decodeSZS(u8* src_buffer, u8* dst_buffer, u32 srcSize,
u32 skipCount) {
u8* decompEnd = dst_buffer + *(u32*)(src_buffer + 4) - skipCount;
u8* copyStart;
s32 copyByteCount;
s32 chunkBitsLeft = 0;
s32 chunkBits;
u8 *decompEnd = dst_buffer + *(u32 *)(src_buffer + 4) - skipCount;
u8 *copyStart;
s32 copyByteCount;
s32 chunkBitsLeft = 0;
s32 chunkBits;
if (srcSize == 0) return;
if (skipCount > *(u32*)src_buffer) return;
if (srcSize == 0)
return;
if (skipCount > *(u32 *)src_buffer)
return;
u8 *curSrcPos = src_buffer + 0x10;
do {
if (chunkBitsLeft == 0) {
chunkBits = *curSrcPos++;
chunkBitsLeft = 8;
}
if ((chunkBits & 0x80) != 0) {
if (skipCount == 0)
{
*dst_buffer = *curSrcPos;
srcSize--;
dst_buffer++;
if (srcSize == 0)
return;
}
else {
skipCount--;
}
curSrcPos++;
u8* curSrcPos = src_buffer + 0x10;
do {
if (chunkBitsLeft == 0) {
chunkBits = *curSrcPos++;
chunkBitsLeft = 8;
}
if ((chunkBits & 0x80) != 0) {
if (skipCount == 0) {
*dst_buffer = *curSrcPos;
srcSize--;
dst_buffer++;
if (srcSize == 0) return;
}
else {
skipCount--;
}
curSrcPos++;
}
else {
u8 curVal = *curSrcPos;
copyStart = dst_buffer - (curSrcPos[1] | (curVal & 0xF) << 8);
curSrcPos += 2;
if (curVal >> 4 == 0) {
copyByteCount = *curSrcPos + 0x12;
curSrcPos++;
}
else {
copyByteCount = (curVal >> 4) + 2;
}
do {
if (skipCount == 0) {
*dst_buffer = *(copyStart - 1);
srcSize--;
dst_buffer++;
if (srcSize == 0) return;
}
else {
u8 curVal = *curSrcPos;
copyStart = dst_buffer - (curSrcPos[1] | (curVal & 0xF) << 8);
curSrcPos += 2;
if (curVal >> 4 == 0) {
copyByteCount = *curSrcPos + 0x12;
curSrcPos++;
}
else {
copyByteCount = (curVal >> 4) + 2;
}
do {
if (skipCount == 0) {
*dst_buffer = *(copyStart - 1);
srcSize--;
dst_buffer++;
if (srcSize == 0)
return;
}
else {
skipCount--;
}
copyByteCount--;
copyStart++;
} while (copyByteCount != 0);
skipCount--;
}
chunkBits <<= 1;
chunkBitsLeft--;
} while (dst_buffer != decompEnd);
copyByteCount--;
copyStart++;
} while (copyByteCount != 0);
}
chunkBits <<= 1;
chunkBitsLeft--;
} while (dst_buffer != decompEnd);
}
JKRDecomp::CompressionMode JKRDecomp::checkCompressed(u8* buf) {
@@ -292,4 +288,4 @@ JKRDecompCommand::JKRDecompCommand() {
this->transferType = MRAM;
}
JKRDecompCommand::~JKRDecompCommand() { }
JKRDecompCommand::~JKRDecompCommand() {}
+1
View File
@@ -1,4 +1,5 @@
#include "JSystem/JKernel/JKRDisposer.h"
#include "JSystem/JKernel/JKRHeap.h"
JKRDisposer::JKRDisposer() : mPointerLinks(this) {
+402
View File
@@ -0,0 +1,402 @@
#include "JSystem/JKernel/JKRDvdAramRipper.h"
#include <_mem.h>
#include <dolphin/string.h>
#include <dolphin/vi.h>
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JKernel/JKRDvdFile.h"
#include "JSystem/JKernel/JKRDvdRipper.h"
#include "JSystem/JUtility/JUTAssertion.h"
JSUList<JKRADCommand> JKRDvdAramRipper::sDvdAramAsyncList;
bool JKRDvdAramRipper::errorRetry = true;
int JKRDvdAramRipper::sSZSBufferSize = 0x400;
JKRAramBlock* JKRDvdAramRipper::loadToAram(s32 entrynum, u32 p2,
JKRExpandSwitch expSwitch, u32 p6,
u32 p7) {
JKRDvdFile dvdFile;
if (!dvdFile.open(entrynum))
return nullptr;
else
return loadToAram(&dvdFile, p2, expSwitch, p6, p7);
}
JKRAramBlock* JKRDvdAramRipper::loadToAram(JKRDvdFile* dvdFile, u32 p1,
JKRExpandSwitch p2, u32 p3, u32 p4) {
JKRADCommand* command = loadToAram_Async(dvdFile, p1, p2, nullptr, p3, p4);
syncAram(command, 0);
if (p1) {
delete command;
return (JKRAramBlock*)-1;
}
JKRAramBlock* result = command->mBlock;
delete command;
return result;
}
JKRADCommand* JKRDvdAramRipper::loadToAram_Async(JKRDvdFile* dvdFile, u32 p1,
JKRExpandSwitch expSwitch,
JKRADCommand::LoadCallback cb,
u32 p4, u32 p5) {
JKRADCommand* command = new (JKRGetSystemHeap(), -4) JKRADCommand();
command->mDvdFile = dvdFile;
command->_1C = p1;
command->mBlock = nullptr;
command->mExpandSwitch = expSwitch;
command->mCallBack = cb;
command->_14 = p4;
command->_18 = p5;
if (!callCommand_Async(command)) {
delete command;
return nullptr;
}
return command;
}
JKRADCommand* JKRDvdAramRipper::callCommand_Async(JKRADCommand* command) {
bool isCmdTrdNull = true;
JKRDvdFile* dvdFile = command->mDvdFile;
int compression = JKRCOMPRESSION_NONE;
OSLockMutex(&dvdFile->mAramMutex);
s32 uncompressedSize;
if (dvdFile->mAramThread) {
isCmdTrdNull = false;
}
else {
dvdFile->mAramThread = OSGetCurrentThread();
JSUFileInputStream* stream =
new (JKRGetSystemHeap(), -4) JSUFileInputStream(dvdFile);
dvdFile->mInputStream = stream;
u32 fileSize = dvdFile->getFileSize();
if (command->_18 && fileSize > command->_18) {
fileSize = command->_18;
}
fileSize = ALIGN_NEXT(fileSize, 0x20);
if (command->mExpandSwitch == EXPAND_SWITCH_DECOMPRESS) {
u8 buffer[0x40];
u8* bufPtr = (u8*)ALIGN_NEXT((u32)buffer, 0x20);
while (true) {
if (DVDReadPrio(dvdFile->getFileInfo(), bufPtr, 0x20, 0, 2) >= 0) {
break;
}
if (errorRetry == false) {
delete stream;
return nullptr;
}
VIWaitForRetrace();
}
compression = JKRCheckCompressed(bufPtr);
u32 expSize = JKRDecompExpandSize(bufPtr);
uncompressedSize = expSize;
if ((command->_18 != 0) && expSize > command->_18) {
uncompressedSize = command->_18;
}
}
if (compression == JKRCOMPRESSION_NONE) {
command->mExpandSwitch = EXPAND_SWITCH_DEFAULT;
}
if (command->mExpandSwitch == EXPAND_SWITCH_DECOMPRESS) {
if (command->_1C == 0 && command->mBlock == nullptr) {
command->mBlock =
JKRAram::getAramHeap()->alloc(uncompressedSize, JKRAramHeap::Head);
if (command->mBlock) {
command->_1C = command->mBlock->mAddress;
}
dvdFile->mAramBlock = command->mBlock;
}
if (command->mBlock) {
command->_1C = command->mBlock->mAddress;
}
if (command->_1C == 0) {
dvdFile->mAramThread = nullptr;
return nullptr;
}
}
else {
if (command->_1C == 0 && !command->mBlock) {
command->mBlock =
JKRAram::getAramHeap()->alloc(fileSize, JKRAramHeap::Head);
}
if (command->mBlock) {
command->_1C = command->mBlock->mAddress;
}
if (command->_1C == 0) {
dvdFile->mAramThread = nullptr;
return nullptr;
}
}
if (compression == 0) {
command->mStreamCommand = JKRAramStream::write_StreamToAram_Async(
stream, command->_1C, fileSize - command->_14, command->_14);
}
else if (compression == JKRCOMPRESSION_YAY0) {
command->mStreamCommand = JKRAramStream::write_StreamToAram_Async(
stream, command->_1C, fileSize - command->_14, command->_14);
}
else if (compression == JKRCOMPRESSION_YAZ0) {
command->mStreamCommand = nullptr;
JKRDecompressFromDVDToAram(command->mDvdFile, command->_1C, fileSize,
uncompressedSize, command->_14, 0);
}
if (!command->mCallBack) {
sDvdAramAsyncList.append(&command->mLink);
}
else {
command->mCallBack((u32)command);
}
}
OSUnlockMutex(&dvdFile->mAramMutex);
return isCmdTrdNull == true ? command : nullptr;
}
bool JKRDvdAramRipper::syncAram(JKRADCommand* command, int p1) {
JKRDvdFile* dvdFile = command->mDvdFile;
OSLockMutex(&dvdFile->mAramMutex);
if (command->mStreamCommand) {
JKRAramStreamCommand* var1 =
JKRAramStream::sync(command->mStreamCommand, p1);
if (p1 != 0 && var1 == nullptr) {
OSUnlockMutex(&dvdFile->mAramMutex);
return false;
}
}
sDvdAramAsyncList.remove(&command->mLink);
if (command->mStreamCommand) {
delete command->mStreamCommand;
}
delete dvdFile->mInputStream;
dvdFile->mAramThread = nullptr;
OSUnlockMutex(&dvdFile->mAramMutex);
return true;
}
JKRADCommand::JKRADCommand() : mLink(this) { _44 = 0; }
JKRADCommand::~JKRADCommand() {
if (_44 == 1) delete mDvdFile;
}
static OSMutex decompMutex;
static u8* szpBuf;
static u8* szpEnd;
static u8* refBuf;
static u8* refEnd;
static u8* refCurrent;
static u8* dmaBuf;
static u8* dmaEnd;
static u8* dmaCurrent;
static u32 srcOffset;
static u32 transLeft;
static u8* srcLimit;
static JKRDvdFile* srcFile;
static u32 fileOffset;
static int readCount;
static u32 maxDest;
static bool isInitMutex;
static u32* tsPtr;
static u32 tsArea;
static int decompSZS_subroutine(u8*, u32);
static u8* firstSrcData();
static u8* nextSrcData(u8*);
static u32 dmaBufferFlush(u32);
int JKRDecompressFromDVDToAram(JKRDvdFile* dvdFile, u32 address, u32 fileSize,
u32 _maxDest, u32 _fileOffset, u32 _srcOffset) {
int result = 0;
szpBuf = (u8*)JKRAllocFromSysHeap(SZP_BUFFERSIZE, 32);
JUT_ASSERT(szpBuf != 0);
szpEnd = szpBuf + SZP_BUFFERSIZE;
refBuf = (u8*)JKRAllocFromSysHeap(REF_BUFFERSIZE, 0);
JUT_ASSERT(refBuf != 0);
refEnd = refBuf + REF_BUFFERSIZE;
refCurrent = refBuf;
dmaBuf = (u8*)JKRAllocFromSysHeap(DMA_BUFFERSIZE, 32);
JUT_ASSERT(dmaBuf != 0);
dmaEnd = dmaBuf + DMA_BUFFERSIZE;
dmaCurrent = dmaBuf;
srcFile = dvdFile;
srcOffset = _srcOffset;
transLeft = fileSize - _srcOffset;
fileOffset = _fileOffset;
readCount = 0;
maxDest = _maxDest;
u8* first = firstSrcData();
if (first) result = decompSZS_subroutine(first, address);
JKRFree(szpBuf);
JKRFree(refBuf);
JKRFree(dmaBuf);
return result;
}
int decompSZS_subroutine(u8* src, u32 dmaAddr) {
u32 endPtr;
u8* copySource;
s32 validBitCount = 0;
s32 currCodeByte = 0;
s32 numBytes;
u32 dmaStart = dmaAddr;
if (src[0] != 'Y' || src[1] != 'a' || src[2] != 'z' || src[3] != '0')
return -1;
SYaz0Header* header = (SYaz0Header*)src;
endPtr = dmaAddr + (header->length - fileOffset);
if (endPtr > dmaAddr + maxDest) endPtr = dmaAddr + maxDest;
src += 0x10;
do {
if (validBitCount == 0) {
if ((src > srcLimit) && transLeft) src = nextSrcData(src);
currCodeByte = *src++;
validBitCount = 8;
}
if (currCodeByte & 0x80) {
if (readCount >= fileOffset) {
dmaAddr++;
*dmaCurrent++ = *src;
if (dmaCurrent == dmaEnd) dmaStart += dmaBufferFlush(dmaStart);
if (dmaAddr == endPtr) break;
}
*(refCurrent++) = *src;
if (refCurrent == refEnd) refCurrent = refBuf;
src++;
readCount++;
}
else {
int t0 = src[0];
int t1 = src[1];
copySource = refCurrent - (t1 | (t0 & 0x0f) << 8) - 1;
numBytes = t0 >> 4;
src += 2;
if (copySource < refBuf) copySource = copySource + (refEnd - refBuf);
if (numBytes == 0)
numBytes = *src++ + 0x12;
else
numBytes += 2;
do {
if (readCount >= fileOffset) {
dmaAddr++;
*(dmaCurrent++) = *copySource;
if (dmaCurrent == dmaEnd) dmaStart += dmaBufferFlush(dmaStart);
if (dmaAddr == endPtr) break;
}
*(refCurrent++) = *copySource;
if (refCurrent == refEnd) refCurrent = refBuf;
copySource++;
if (copySource == refEnd) copySource = refBuf;
readCount++;
numBytes--;
} while (numBytes != 0);
}
currCodeByte <<= 1;
validBitCount--;
} while (dmaAddr < endPtr);
dmaBufferFlush(dmaStart);
return 0;
}
u8* firstSrcData() {
srcLimit = szpEnd - 0x19;
u8* buf = szpBuf;
u32 max = (szpEnd - szpBuf);
u32 transSize = MIN(transLeft, max);
while (true) {
if (0 <= DVDReadPrio(srcFile->getFileInfo(), buf, transSize, 0, 2)) break;
if (!JKRDvdAramRipper::isErrorRetry()) return nullptr;
VIWaitForRetrace();
}
srcOffset += transSize;
transLeft -= transSize;
return buf;
}
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;
JUT_ASSERT(transSize > 0);
while (true) {
int result = DVDReadPrio(srcFile->getFileInfo(), (buf + limit), transSize,
srcOffset, 2);
if (result >= 0) break;
if (!JKRDvdAramRipper::isErrorRetry()) return nullptr;
VIWaitForRetrace();
}
srcOffset += transSize;
transLeft -= transSize;
if (transLeft == 0) srcLimit = transSize + (buf + limit);
return buf;
}
u32 dmaBufferFlush(u32 src) {
if (dmaCurrent == dmaBuf) {
return 0;
}
else {
u32 length = ALIGN_NEXT((u32)(dmaCurrent - dmaBuf), 32);
JKRAramPiece::orderSync(0, (u32)dmaBuf, src, length, nullptr);
dmaCurrent = dmaBuf;
return length;
}
}
+321
View File
@@ -0,0 +1,321 @@
#include <dolphin/os/OSCache.h>
#include <dolphin/string.h>
#include "JSystem/JKernel/JKRArchive.h"
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JKernel/JKRDvdAramRipper.h"
#include "JSystem/JKernel/JKRDvdRipper.h"
#include "JSystem/JSystem.h"
#include "JSystem/JUtility/JUTAssertion.h"
JKRDvdArchive::JKRDvdArchive() : JKRArchive() {}
JKRDvdArchive::JKRDvdArchive(s32 entryNum, EMountDirection mountDirection)
: JKRArchive(entryNum, MOUNT_DVD)
{
mMountDirection = mountDirection;
if (!open(entryNum))
{
return;
}
else
{
mVolumeType = 'RARC';
mVolumeName = &mStrTable[mDirectories->mOffset];
sVolumeList.prepend(&mFileLoaderLink);
mIsMounted = true;
}
}
JKRDvdArchive::~JKRDvdArchive()
{
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);
}
if (mDvdFile)
{
delete mDvdFile;
}
sVolumeList.remove(&mFileLoaderLink);
mIsMounted = false;
}
}
#ifdef DEBUG
CW_FORCE_STRINGS(JKRDvdArchive_cpp, __FILE__, "isMounted()", "mMountCount == 1")
#endif
bool JKRDvdArchive::open(long entryNum)
{
mArcInfoBlock = nullptr;
_60 = 0;
mDirectories = nullptr;
mFileEntries = nullptr;
mStrTable = nullptr;
mDvdFile = new (JKRGetSystemHeap(), 0) JKRDvdFile(entryNum);
if (mDvdFile == nullptr)
{
mMountMode = 0;
return 0;
}
SDIFileEntry* mem = (SDIFileEntry*)JKRAllocFromSysHeap(
32, 32); // NOTE: unconfirmed if this struct was used here
if (mem == nullptr)
{
mMountMode = 0;
}
else
{
JKRDvdToMainRam(entryNum, (u8*)mem, EXPAND_SWITCH_DECOMPRESS, 32, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, 0, &mCompression);
int alignment = mMountDirection == MOUNT_DIRECTION_HEAD ? 32 : -32;
mArcInfoBlock =
(SArcDataInfo*)JKRAllocFromHeap(mHeap, mem->mSize, alignment);
if (mArcInfoBlock == nullptr)
{
mMountMode = 0;
}
else
{
JKRDvdToMainRam(entryNum, (u8*)mArcInfoBlock, EXPAND_SWITCH_DECOMPRESS,
mem->mSize, nullptr, JKRDvdRipper::ALLOC_DIR_TOP, 32,
nullptr);
mDirectories =
(SDIDirEntry*)((u8*)mArcInfoBlock + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u8*)mArcInfoBlock +
mArcInfoBlock->file_entry_offset);
mStrTable = (const char*)((u8*)mArcInfoBlock +
mArcInfoBlock->string_table_offset);
_60 = mem->mDataOffset + mem->mSize; // End of data offset?
}
}
cleanup:
if (mem != nullptr)
{
JKRFreeToSysHeap(mem);
}
if (mMountMode == 0)
{
JREPORTF(":::Cannot alloc memory [%s][%d]\n", __FILE__, 397); // Macro?
if (mDvdFile != nullptr)
{
delete mDvdFile;
}
}
return mMountMode != 0;
}
void* JKRDvdArchive::fetchResource(SDIFileEntry* fileEntry, u32* pSize)
{
JUT_ASSERT(isMounted());
u32 sizeRef;
u8* data;
if (fileEntry->mData == nullptr)
{
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
u32 size = fetchResource_subroutine(mEntryNum, _60 + fileEntry->mDataOffset,
fileEntry->mSize, mHeap,
(int)compression, mCompression, &data);
if (pSize)
*pSize = size;
fileEntry->mData = data;
}
else if (pSize)
{
*pSize = fileEntry->mSize;
}
return fileEntry->mData;
}
void* JKRDvdArchive::fetchResource(void* data, u32 compressedSize,
SDIFileEntry* fileEntry, u32* pSize,
JKRExpandSwitch expandSwitch)
{
JUT_ASSERT(isMounted());
u32 fileSize = compressedSize & -32;
u32 alignedSize = ALIGN_NEXT(fileEntry->mSize, 32);
if (alignedSize > fileSize)
{
alignedSize = fileSize;
}
if (fileEntry->mData == nullptr)
{
int compression = JKRConvertAttrToCompressionType(fileEntry->mFlag >> 0x18);
if (expandSwitch != EXPAND_SWITCH_DECOMPRESS)
compression = 0;
alignedSize = fetchResource_subroutine(
mEntryNum, _60 + fileEntry->mDataOffset, fileEntry->mSize, (u8*)data,
fileSize, compression, mCompression);
}
else
{
JKRHeap::copyMemory(data, fileEntry->mData, alignedSize);
}
if (pSize)
{
*pSize = alignedSize;
}
return data;
}
u32 JKRDvdArchive::fetchResource_subroutine(long entryNum, u32 offset, u32 size,
u8* data, u32 expandSize,
int fileCompression,
int archiveCompression)
{
u32 prevAlignedSize, alignedSize;
alignedSize = ALIGN_NEXT(size, 32);
prevAlignedSize = ALIGN_PREV(expandSize, 32);
switch (archiveCompression)
{
case JKRCOMPRESSION_NONE:
{
switch (fileCompression)
{
case JKRCOMPRESSION_NONE:
if (alignedSize > prevAlignedSize)
{
alignedSize = prevAlignedSize;
}
JKRDvdRipper::loadToMainRAM(
entryNum, data, EXPAND_SWITCH_DEFAULT, alignedSize, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
return alignedSize;
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
u8* header = (u8*)JKRAllocFromSysHeap(0x20, 0x20);
JKRDvdRipper::loadToMainRAM(
entryNum, header, EXPAND_SWITCH_NONE, 0x20, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
u32 expandFileSize = JKRDecompExpandSize(header);
JKRFreeToSysHeap(header);
alignedSize = ALIGN_NEXT(expandFileSize, 32);
if (alignedSize > prevAlignedSize)
{
alignedSize = prevAlignedSize;
}
JKRDvdRipper::loadToMainRAM(
entryNum, data, EXPAND_SWITCH_DECOMPRESS, alignedSize, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
return expandFileSize;
}
}
case JKRCOMPRESSION_YAZ0:
{
if (size > prevAlignedSize)
{
size = prevAlignedSize;
}
JKRDvdRipper::loadToMainRAM(entryNum, data, EXPAND_SWITCH_DECOMPRESS,
size, nullptr, JKRDvdRipper::ALLOC_DIR_TOP,
offset, nullptr);
return size;
}
case JKRCOMPRESSION_YAY0:
{
JPANIC(537, "Sorry, not prepared for SZP archive.\n");
return 0;
}
default:
{
JPANIC(546, ":::??? bad sequence\n");
}
}
return 0;
}
u32 JKRDvdArchive::fetchResource_subroutine(long entryNum, u32 offset, u32 size,
JKRHeap* heap, int fileCompression,
int archiveCompression, u8** pBuf)
{
u32 alignedSize = ALIGN_NEXT(size, 32);
u8* buffer;
switch (archiveCompression)
{
case JKRCOMPRESSION_NONE:
{
switch (fileCompression)
{
case JKRCOMPRESSION_NONE:
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, 32);
JUT_ASSERT(buffer != 0);
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_DEFAULT, alignedSize,
nullptr, JKRDvdRipper::ALLOC_DIR_TOP, offset,
nullptr);
*pBuf = buffer;
return alignedSize;
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
u8* header = (u8*)JKRAllocFromHeap(heap, 0x20, 0x20);
JKRDvdToMainRam(entryNum, header, EXPAND_SWITCH_NONE, 0x20, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
alignedSize = JKRDecompExpandSize(header);
JKRFreeToHeap(heap, header);
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, 0x20);
JUT_ASSERT(buffer);
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_DECOMPRESS,
alignedSize, nullptr, JKRDvdRipper::ALLOC_DIR_TOP,
offset, nullptr);
*pBuf = buffer;
return alignedSize;
}
}
case JKRCOMPRESSION_YAZ0:
{
buffer = (u8*)JKRAllocFromHeap(heap, alignedSize, 32);
JUT_ASSERT(buffer);
JKRDvdToMainRam(entryNum, buffer, EXPAND_SWITCH_DECOMPRESS, size, nullptr,
JKRDvdRipper::ALLOC_DIR_TOP, offset, nullptr);
*pBuf = buffer;
return alignedSize;
}
case JKRCOMPRESSION_YAY0:
{
JPANIC(612, "Sorry, not prepared for SZP archive.\n");
return 0;
}
default:
{
JPANIC(617, ":::??? bad sequence\n");
}
}
return 0;
}
+23 -21
View File
@@ -29,12 +29,12 @@ void JKRDvdFile::initiate() {
/* Reference to self. Used to retrieve reference in the DVDReadAsync
* DVDCallback func. */
this->mDvdFileInfo.mFile = this;
OSInitMutex(&this->mMutex1);
OSInitMutex(&this->mMutex2);
OSInitMessageQueue(&this->mMessageQueue2, &this->mMsg2, 1);
OSInitMessageQueue(&this->mMessageQueue1, &this->mMsg1, 1);
this->mThread2 = nullptr;
this->mThread1 = nullptr;
OSInitMutex(&this->mDvdMutex);
OSInitMutex(&this->mAramMutex);
OSInitMessageQueue(&this->mDvdMessageQueue, &this->mDvdMessage, 1);
OSInitMessageQueue(&this->mAramMessageQueue, &this->mAramMessage, 1);
this->mDvdThread = nullptr;
this->mAramThread = nullptr;
this->_58 = 0;
}
@@ -68,29 +68,31 @@ bool JKRDvdFile::close() {
if (DVDClose(&this->mDvdFileInfo)) {
this->mFileOpen = false;
return sDvdList.remove(&this->mLink);
} else {
}
else {
OSErrorLine(212, "cannot close DVD file\n"); /* JKRDvdFile.cpp line 212 */
}
}
}
int JKRDvdFile::readData(void* data, s32 length, s32 ofs) {
OSLockMutex(&this->mMutex1);
OSLockMutex(&this->mDvdMutex);
s32 retAddr;
if (this->mThread2 != nullptr) {
OSUnlockMutex(&this->mMutex1);
if (this->mDvdThread != nullptr) {
OSUnlockMutex(&this->mDvdMutex);
return -1;
} else {
this->mThread2 = OSGetCurrentThread();
}
else {
this->mDvdThread = OSGetCurrentThread();
retAddr = -1;
if (DVDReadAsync(&this->mDvdFileInfo, data, length, ofs,
JKRDvdFile::doneProcess)) {
JKRDvdFile::doneProcess)) {
retAddr = this->sync();
}
this->mThread2 = nullptr;
OSUnlockMutex(&this->mMutex1);
this->mDvdThread = nullptr;
OSUnlockMutex(&this->mDvdMutex);
}
return retAddr;
@@ -101,14 +103,14 @@ int JKRDvdFile::writeData(const void* data, s32 length, s32 ofs) { return -1; }
s32 JKRDvdFile::sync() {
OSMessage m;
OSLockMutex(&this->mMutex1);
OSReceiveMessage(&this->mMessageQueue2, &m, OS_MESSAGE_BLOCK);
this->mThread2 = nullptr;
OSUnlockMutex(&this->mMutex1);
OSLockMutex(&this->mDvdMutex);
OSReceiveMessage(&this->mDvdMessageQueue, &m, OS_MESSAGE_BLOCK);
this->mDvdThread = nullptr;
OSUnlockMutex(&this->mDvdMutex);
return (s32)m;
}
void JKRDvdFile::doneProcess(s32 result, DVDFileInfo* info) {
OSSendMessage(&static_cast<JKRDvdFileInfo*>(info)->mFile->mMessageQueue2,
(OSMessage)result, OS_MESSAGE_NOBLOCK);
OSSendMessage(&static_cast<JKRDvdFileInfo*>(info)->mFile->mDvdMessageQueue,
(OSMessage)result, OS_MESSAGE_NOBLOCK);
}
+131 -131
View File
@@ -17,7 +17,7 @@ static u8* nextSrcData(u8* nowData);
void* JKRDvdRipper::loadToMainRAM(const char* file, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap, EAllocDirection allocDir, u32 offset, int* compressMode) {
JKRDvdFile dvdFile;
if (!dvdFile.open(file)) {
return nullptr;
}
@@ -28,7 +28,7 @@ void* JKRDvdRipper::loadToMainRAM(const char* file, u8* buf, JKRExpandSwitch exp
void* JKRDvdRipper::loadToMainRAM(s32 entrynum, u8* buf, JKRExpandSwitch expandSwitch, u32 maxDest, JKRHeap* heap, EAllocDirection allocDir, u32 offset, int* compressMode) {
JKRDvdFile dvdFile;
if (!dvdFile.open(entrynum)) {
return nullptr;
}
@@ -108,9 +108,9 @@ void* JKRDvdRipper::loadToMainRAM(JKRDvdFile* file, u8* buf, JKRExpandSwitch exp
u8* aligned_buf = (u8*)ALIGN_NEXT((u32)buffer, 32);
while (true) {
if (DVDReadPrio(file->getFileInfo(), aligned_buf, 32, offset, 2) >= 0) {
break;
break;
}
if (JKRDvdRipper::errorRetry == false) {
return nullptr;
}
@@ -155,7 +155,7 @@ void* JKRDvdRipper::loadToMainRAM(JKRDvdFile* file, u8* buf, JKRExpandSwitch exp
}
/* Looks like a bug here */
#ifndef FIXES
#ifndef FIXES
if (DVDReadPrio(file->getFileInfo(), mem, fileSize, 0, 2) < 0) {
if (JKRDvdRipper::errorRetry == false) {
VIWaitForRetrace();
@@ -169,7 +169,7 @@ void* JKRDvdRipper::loadToMainRAM(JKRDvdFile* file, u8* buf, JKRExpandSwitch exp
JKRFree(mem);
return buf;
}
#else
#else
while (DVDReadPrio(file->getFileInfo(), mem, fileSize, 0, 2) < 0) {
if (JKRDvdRipper::errorRetry == false) {
if (allocated) {
@@ -179,13 +179,13 @@ void* JKRDvdRipper::loadToMainRAM(JKRDvdFile* file, u8* buf, JKRExpandSwitch exp
JKRFree(mem);
return nullptr;
}
VIWaitForRetrace();
}
JKRDecompress(mem, buf, finalSize, 0);
JKRFree(mem);
#endif
#endif
}
else if (fileCompressMode == JKRDecomp::SZS) {
JKRDecompressFromDVD(file, buf, fileSize, finalSize, offset, 0);
@@ -215,12 +215,12 @@ static u32 fileOffset;
static u32 readCount;
static u32 maxDest;
static int JKRDecompressFromDVD(JKRDvdFile* _srcFile, void* buf, u32 size, u32 _maxDest, u32 _fileOffset, u32 _srcOffset) {
int JKRDecompressFromDVD(JKRDvdFile* _srcFile, void* buf, u32 size, u32 _maxDest, u32 _fileOffset, u32 _srcOffset) {
int res = 0;
szpBuf = (u8*)JKRAllocFromSysHeap(SZP_BUFFERSIZE, -32);
szpEnd = szpBuf + SZP_BUFFERSIZE;
if (_fileOffset != 0) {
refBuf = (u8*)JKRAllocFromSysHeap(REF_BUFFERSIZE, -4);
refEnd = refBuf + REF_BUFFERSIZE;
@@ -252,148 +252,148 @@ static int JKRDecompressFromDVD(JKRDvdFile* _srcFile, void* buf, u32 size, u32 _
}
static int decompSZS_subroutine(u8* src, u8* dest) {
u8 *endPtr;
u8* endPtr;
s32 validBitCount = 0;
s32 currCodeByte = 0;
u32 ts = 0;
if ((s32)src[0] != 'Y' || (s32)src[1] != 'a' || (s32)src[2] != 'z' || (s32)src[3] != '0')
{
return -1;
return -1;
}
SZPHeader *header = (SZPHeader *)src;
SZPHeader* header = (SZPHeader*)src;
endPtr = dest + (header->decompSize - fileOffset);
if (endPtr > dest + maxDest)
{
endPtr = dest + maxDest;
endPtr = dest + maxDest;
}
src += 0x10;
do
{
if (validBitCount == 0)
if (validBitCount == 0)
{
if ((src > srcLimit) && transLeft)
{
if ((src > srcLimit) && transLeft)
{
src = nextSrcData(src);
if (!src)
{
return -1;
}
}
currCodeByte = *src;
validBitCount = 8;
src++;
src = nextSrcData(src);
if (!src)
{
return -1;
}
}
if (currCodeByte & 0x80)
currCodeByte = *src;
validBitCount = 8;
src++;
}
if (currCodeByte & 0x80)
{
if (fileOffset != 0)
{
if (fileOffset != 0)
if (readCount >= fileOffset)
{
*dest = *src;
dest++;
ts++;
if (dest == endPtr)
{
if (readCount >= fileOffset)
{
*dest = *src;
dest++;
ts++;
if (dest == endPtr)
{
break;
}
}
*(refCurrent++) = *src;
if (refCurrent == refEnd)
{
refCurrent = refBuf;
}
src++;
break;
}
else
{
*dest = *src;
dest++;
src++;
ts++;
if (dest == endPtr)
{
break;
}
}
readCount++;
}
*(refCurrent++) = *src;
if (refCurrent == refEnd)
{
refCurrent = refBuf;
}
src++;
}
else
{
u32 dist = src[1] | (src[0] & 0x0f) << 8;
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);
}
*dest = *src;
dest++;
src++;
ts++;
if (dest == endPtr)
{
break;
}
}
currCodeByte <<= 1;
validBitCount--;
readCount++;
}
else
{
u32 dist = src[1] | (src[0] & 0x0f) << 8;
s32 numBytes = src[0] >> 4;
src += 2;
u8* copySource;
if (fileOffset != 0)
{
copySource = refCurrent - dist - 1;
if (copySource < refBuf)
{
copySource += refEnd - refBuf;
}
}
else
{
copySource = dest - dist - 1;
}
if (numBytes == 0)
{
numBytes = *src + 0x12;
src += 1;
}
else
{
numBytes += 2;
}
if (fileOffset != 0)
{
do
{
if (readCount >= fileOffset)
{
*dest = *copySource;
dest++;
ts++;
if (dest == endPtr)
{
break;
}
}
*(refCurrent++) = *copySource;
if (refCurrent == refEnd)
{
refCurrent = refBuf;
}
copySource++;
if (copySource == refEnd)
{
copySource = refBuf;
}
readCount++;
numBytes--;
} while (numBytes != 0);
}
else
{
do
{
*dest = *copySource;
dest++;
ts++;
if (dest == endPtr)
{
break;
}
readCount++;
numBytes--;
copySource++;
} while (numBytes != 0);
}
}
currCodeByte <<= 1;
validBitCount--;
} while (dest < endPtr);
return 0;
@@ -442,16 +442,16 @@ static u8* nextSrcData(u8* nowData) {
break;
}
// Oopsies, forgot to call the function
#ifndef FIXES
#ifndef FIXES
if (JKRDvdRipper::isErrorRetry == false) {
return nullptr;
}
#else
#else
if (JKRDvdRipper::isErrorRetry() == false) {
return nullptr;
}
#endif
#endif
VIWaitForRetrace();
}
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -27,17 +27,17 @@
* Nonmatched function. Unused in Animal Crossing.
*/
void JKRFile::read(void* data, s32 length, s32 ofs) {
#ifdef JSYSTEM_DEBUG
#ifdef JSYSTEM_DEBUG
if (!JKR_ISALIGNED(length, 32)) {
JUTAssertion::showAssert(JUTAssertion::getSDevice(), __FILE__, __LINE__, "( length & 0x1f ) == 0");
}
#endif
#endif
while (true) {
if (this->readData(data, length, ofs) == length) {
return;
}
VIWaitForRetrace();
}
}
+63
View File
@@ -0,0 +1,63 @@
#include <dolphin/dvd.h>
#include "JSystem/JKernel/JKRFileFinder.h"
#include "JSystem/JKernel/JKRArchive.h"
JKRArcFinder::JKRArcFinder(JKRArchive* archive, long startindex, long entries) : JKRFileFinder()
{
mArchive = archive;
mIsAvailable = entries > 0;
mStartIndex = startindex;
mEndIndex = startindex + entries - 1;
mNextIndex = mStartIndex;
findNextFile();
}
bool JKRArcFinder::findNextFile()
{
if (mIsAvailable)
{
mIsAvailable = (mNextIndex <= mEndIndex);
if (mIsAvailable)
{
JKRArchive::SDirEntry dirEntry;
mIsAvailable = mArchive->getDirEntry(&dirEntry, mNextIndex);
mBase.mFileName = dirEntry.mName;
mBase.mFileIndex = mNextIndex;
mBase.mFileID = dirEntry.mID;
mBase.mFileTypeFlags = dirEntry.mFlags;
mIsFileOrDir = FLAG_OFF(mBase.mFileTypeFlags, 2);
mNextIndex++;
}
}
return mIsAvailable;
}
// UNUSED
JKRDvdFinder::JKRDvdFinder(const char* path) : JKRFileFinder()
{
mIsDvdOpen = DVDOpenDir(const_cast<char*>(path), &mDir);
mIsAvailable = mIsDvdOpen;
findNextFile();
}
// UNUSED, not sure if it matches
bool JKRDvdFinder::findNextFile()
{
if (mIsAvailable)
{
DVDDirEntry entry;
mIsAvailable = DVDReadDir(&mDir, &entry);
if (mIsAvailable)
{
mIsFileOrDir = (bool)entry.isDir;
mBase.mFileName = entry.name;
mBase.mFileIndex = entry.entryNum;
mBase.mFileID = 0;
mBase.mFileTypeFlags = mIsFileOrDir ? 2 : 1;
}
}
return mIsAvailable;
}
+165
View File
@@ -0,0 +1,165 @@
#include <MSL_C/ctype.h>
#include <dolphin/string.h>
#include "JSystem/JKernel/JKRFileLoader.h"
JSUList<JKRFileLoader> JKRFileLoader::sVolumeList;
JKRFileLoader* JKRFileLoader::sCurrentVolume;
JKRFileLoader::JKRFileLoader() : JKRDisposer(), mFileLoaderLink(this)
{
mVolumeName = nullptr;
mVolumeType = 0;
mMountCount = 0;
}
JKRFileLoader::~JKRFileLoader()
{
if (sCurrentVolume == this)
sCurrentVolume = nullptr;
}
void JKRFileLoader::unmount()
{
if (mMountCount != 0)
{
if (--mMountCount == 0)
delete this;
}
}
void JKRFileLoader::changeDirectory(const char* dir)
{
JKRFileLoader* vol = findVolume(&dir);
if (vol)
vol->becomeCurrent(dir);
}
void* JKRFileLoader::getGlbResource(const char* path)
{
const char* components[2];
components[0] = path;
JKRFileLoader* loader = findVolume(components);
return (loader == nullptr) ? nullptr : loader->getResource(components[0]);
}
void* JKRFileLoader::getGlbResource(const char* name, JKRFileLoader* fileLoader)
{
void* resource = nullptr;
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;
}
size_t JKRFileLoader::readGlbResource(void* resBuf, u32 bufSize, const char* volumeName, JKRExpandSwitch expandSwitch)
{
JKRFileLoader* vol = findVolume(&volumeName);
return vol == nullptr ? 0 : vol->readResource(resBuf, bufSize, volumeName, expandSwitch);
}
bool JKRFileLoader::removeResource(void* resourceBuffer, JKRFileLoader* fileLoader)
{
if (fileLoader)
{
return fileLoader->removeResource(resourceBuffer);
}
JSUList<JKRFileLoader>& volumeList = getVolumeList();
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator)
{
if (iterator->removeResource(resourceBuffer))
return true;
}
return false;
}
bool JKRFileLoader::detachResource(void* resourceBuffer, JKRFileLoader* fileLoader)
{
if (fileLoader)
{
return fileLoader->detachResource(resourceBuffer);
}
JSUList<JKRFileLoader>& volumeList = getVolumeList();
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator)
{
if (iterator->detachResource(resourceBuffer))
return true;
}
return false;
}
JKRFileLoader* JKRFileLoader::findVolume(const char** volumeName)
{
if (*volumeName[0] != '/')
{
return sCurrentVolume;
}
char volumeNameBuffer[0x101];
*volumeName = fetchVolumeName(volumeNameBuffer, ARRAY_COUNT(volumeNameBuffer), *volumeName);
JSUList<JKRFileLoader>& volumeList = sVolumeList;
JSUListIterator<JKRFileLoader> iterator;
for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator)
{
if (strcmp(volumeNameBuffer, iterator->mVolumeName) == 0)
return iterator.getObject();
}
return nullptr;
}
JKRFileFinder* JKRFileLoader::findFirstFile(const char* volumeName)
{
JKRFileFinder* ret = nullptr;
JKRFileLoader* vol = findVolume(&volumeName);
if (vol)
ret = vol->getFirstFile(volumeName);
return ret;
}
const char* JKRFileLoader::fetchVolumeName(char* buffer, long bufferSize, const char* path)
{
static char rootPath[] = "/";
if (strcmp(path, "/") == 0)
{
strcpy(buffer, rootPath);
return rootPath;
}
else
{
path++;
while (*path != 0 && *path != '/')
{
if (1 < bufferSize)
{
*buffer = _tolower(*path);
buffer++;
bufferSize--;
}
path++;
}
buffer[0] = '\0';
if (path[0] == '\0')
path = rootPath;
}
return path;
}
+73 -73
View File
@@ -7,26 +7,26 @@
#include "dolphin/os/OSUtil.h"
#include "dolphin/os/OSAddress.h"
JKRHeap *JKRHeap::sSystemHeap;
JKRHeap *JKRHeap::sCurrentHeap;
JKRHeap *JKRHeap::sRootHeap;
JKRHeapErrorHandler *JKRHeap::mErrorHandler;
void *JKRHeap::mCodeStart;
void *JKRHeap::mCodeEnd;
void *JKRHeap::mUserRamStart;
void *JKRHeap::mUserRamEnd;
JKRHeap* JKRHeap::sSystemHeap;
JKRHeap* JKRHeap::sCurrentHeap;
JKRHeap* JKRHeap::sRootHeap;
JKRHeapErrorHandler* JKRHeap::mErrorHandler;
void* JKRHeap::mCodeStart;
void* JKRHeap::mCodeEnd;
void* JKRHeap::mUserRamStart;
void* JKRHeap::mUserRamEnd;
u32 JKRHeap::mMemorySize;
bool JKRHeap::sDefaultFillFlag = true;
JKRHeap::JKRHeap(void *data, u32 size, JKRHeap *heap, bool errorFlag) : JKRDisposer(),
mChildTree(this),
mDisposerList()
JKRHeap::JKRHeap(void* data, u32 size, JKRHeap* heap, bool errorFlag) : JKRDisposer(),
mChildTree(this),
mDisposerList()
{
OSInitMutex(&mMutex);
mSize = size;
mStart = (u8 *)data;
mEnd = ((u8 *)data + size);
mStart = (u8*)data;
mEnd = ((u8*)data + size);
if (heap == nullptr)
{
becomeSystemHeap();
@@ -50,7 +50,7 @@ JKRHeap::JKRHeap(void *data, u32 size, JKRHeap *heap, bool errorFlag) : JKRDispo
JKRHeap::~JKRHeap()
{
mChildTree.getParent()->removeChild(&mChildTree);
JSUTree<JKRHeap> *nextRootHeap = sRootHeap->mChildTree.getFirstChild();
JSUTree<JKRHeap>* nextRootHeap = sRootHeap->mChildTree.getFirstChild();
if (sCurrentHeap == this)
sCurrentHeap = !nextRootHeap ? sRootHeap : nextRootHeap->getObject();
@@ -58,53 +58,53 @@ JKRHeap::~JKRHeap()
sSystemHeap = !nextRootHeap ? sRootHeap : nextRootHeap->getObject();
}
bool JKRHeap::initArena(char **outUserRamStart, u32 *outUserRamSize, int numHeaps)
bool JKRHeap::initArena(char** outUserRamStart, u32* outUserRamSize, int numHeaps)
{
void *arenaLo = OSGetArenaLo();
void *arenaHi = OSGetArenaHi();
void* arenaLo = OSGetArenaLo();
void* arenaHi = OSGetArenaHi();
if (arenaLo == arenaHi)
{
return false;
}
void *arenaStart = OSInitAlloc(arenaLo, arenaHi, numHeaps);
arenaHi = (u8 *)OSRoundDown32B(arenaHi);
arenaLo = (u8 *)OSRoundUp32B(arenaStart);
u8 *start = (u8 *)OSPhysicalToCached(0);
mCodeStart = (u8 *)start;
mCodeEnd = (u8 *)arenaLo;
mUserRamStart = (u8 *)arenaLo;
mUserRamEnd = (u8 *)arenaHi;
mMemorySize = *(u32 *)((start + 0x28));
void* arenaStart = OSInitAlloc(arenaLo, arenaHi, numHeaps);
arenaHi = (u8*)OSRoundDown32B(arenaHi);
arenaLo = (u8*)OSRoundUp32B(arenaStart);
u8* start = (u8*)OSPhysicalToCached(0);
mCodeStart = (u8*)start;
mCodeEnd = (u8*)arenaLo;
mUserRamStart = (u8*)arenaLo;
mUserRamEnd = (u8*)arenaHi;
mMemorySize = *(u32*)((start + 0x28));
OSSetArenaLo(arenaHi);
OSSetArenaHi(arenaHi);
*outUserRamStart = (char *)arenaLo;
*outUserRamStart = (char*)arenaLo;
*outUserRamSize = (u32)arenaHi - (u32)arenaLo;
return true;
}
JKRHeap *JKRHeap::becomeSystemHeap()
JKRHeap* JKRHeap::becomeSystemHeap()
{
JKRHeap *old = sSystemHeap;
JKRHeap* old = sSystemHeap;
sSystemHeap = this;
return old;
}
JKRHeap *JKRHeap::becomeCurrentHeap()
JKRHeap* JKRHeap::becomeCurrentHeap()
{
JKRHeap *old = sCurrentHeap;
JKRHeap* old = sCurrentHeap;
sCurrentHeap = this;
return old;
}
void JKRHeap::destroy(JKRHeap *heap)
void JKRHeap::destroy(JKRHeap* heap)
{
JUT_ASSERT(200, heap != 0);
heap->destroy();
}
void *JKRHeap::alloc(u32 byteCount, int padding, JKRHeap *heap)
void* JKRHeap::alloc(u32 byteCount, int padding, JKRHeap* heap)
{
void *memory = nullptr;
void* memory = nullptr;
if (heap)
{
memory = heap->do_alloc(byteCount, padding);
@@ -116,13 +116,13 @@ void *JKRHeap::alloc(u32 byteCount, int padding, JKRHeap *heap)
return memory;
}
void *JKRHeap::alloc(u32 byteCount, int padding)
void* JKRHeap::alloc(u32 byteCount, int padding)
{
JUT_WARNING_F(317, !mInitFlag, "alloc %x byte in heap %x", byteCount, this);
return do_alloc(byteCount, padding);
}
void JKRHeap::free(void *memory, JKRHeap *heap)
void JKRHeap::free(void* memory, JKRHeap* heap)
{
if ((heap) || (heap = findFromRoot(memory), heap))
{
@@ -130,7 +130,7 @@ void JKRHeap::free(void *memory, JKRHeap *heap)
}
}
void JKRHeap::free(void *memory)
void JKRHeap::free(void* memory)
{
JUT_WARNING_F(365, !mInitFlag, "free %x in heap %x", memory, this);
do_free(memory);
@@ -157,13 +157,13 @@ void JKRHeap::freeTail()
do_freeTail();
}
void JKRHeap::resize(void *memoryBlock, u32 newSize)
void JKRHeap::resize(void* memoryBlock, u32 newSize)
{
JUT_WARNING_F(491, !mInitFlag, "resize block %x into %x in heap %x", memoryBlock, newSize, this);
do_resize(memoryBlock, newSize);
}
s32 JKRHeap::getSize(void *memoryBlock, JKRHeap *heap)
s32 JKRHeap::getSize(void* memoryBlock, JKRHeap* heap)
{
if (heap == nullptr && (heap = findFromRoot(memoryBlock), heap == nullptr))
{
@@ -173,7 +173,7 @@ s32 JKRHeap::getSize(void *memoryBlock, JKRHeap *heap)
return heap->getSize(memoryBlock);
}
s32 JKRHeap::getSize(void *memoryBlock) { return do_getSize(memoryBlock); }
s32 JKRHeap::getSize(void* memoryBlock) { return do_getSize(memoryBlock); }
s32 JKRHeap::getFreeSize() { return do_getFreeSize(); }
s32 JKRHeap::getTotalFreeSize() { return do_getTotalFreeSize(); }
@@ -185,7 +185,7 @@ s32 JKRHeap::changeGroupID(u8 newGroupID)
u8 JKRHeap::getCurrentGroupId() { return do_getCurrentGroupId(); }
JKRHeap *JKRHeap::findFromRoot(void *ptr)
JKRHeap* JKRHeap::findFromRoot(void* ptr)
{
if (sRootHeap != nullptr)
return sRootHeap->find(ptr);
@@ -193,7 +193,7 @@ JKRHeap *JKRHeap::findFromRoot(void *ptr)
return nullptr;
}
JKRHeap *JKRHeap::find(void *memory) const
JKRHeap* JKRHeap::find(void* memory) const
{
if ((mStart <= memory) && (memory <= mEnd))
{
@@ -201,25 +201,25 @@ JKRHeap *JKRHeap::find(void *memory) const
{
for (JSUTreeIterator<JKRHeap> iterator(mChildTree.getFirstChild()); iterator != mChildTree.getEndChild(); ++iterator)
{
JKRHeap *result = iterator->find(memory);
JKRHeap* result = iterator->find(memory);
if (result)
{
return result;
}
}
}
return const_cast<JKRHeap *>(this);
return const_cast<JKRHeap*>(this);
}
return nullptr;
}
JKRHeap *JKRHeap::findAllHeap(void *memory) const
JKRHeap* JKRHeap::findAllHeap(void* memory) const
{
if (mChildTree.getNumChildren() != 0)
{
for (JSUTreeIterator<JKRHeap> iterator(mChildTree.getFirstChild()); iterator != mChildTree.getEndChild(); ++iterator)
{
JKRHeap *result = iterator->findAllHeap(memory);
JKRHeap* result = iterator->findAllHeap(memory);
if (result)
{
return result;
@@ -229,7 +229,7 @@ JKRHeap *JKRHeap::findAllHeap(void *memory) const
if (mStart <= memory && memory < mEnd)
{
return const_cast<JKRHeap *>(this);
return const_cast<JKRHeap*>(this);
}
return nullptr;
@@ -242,11 +242,11 @@ void JKRHeap::dispose_subroutine(u32 begin, u32 end)
JSUListIterator<JKRDisposer> next_iterator;
JSUListIterator<JKRDisposer> iterator;
for (iterator = mDisposerList.getFirst(); iterator != mDisposerList.getEnd();
iterator = next_iterator)
iterator = next_iterator)
{
JKRDisposer *disposer = iterator.getObject();
JKRDisposer* disposer = iterator.getObject();
if ((void *)begin <= disposer && disposer < (void *)end)
if ((void*)begin <= disposer && disposer < (void*)end)
{
disposer->~JKRDisposer();
if (last_iterator == nullptr)
@@ -268,7 +268,7 @@ void JKRHeap::dispose_subroutine(u32 begin, u32 end)
}
}
bool JKRHeap::dispose(void *memory, u32 size)
bool JKRHeap::dispose(void* memory, u32 size)
{
u32 begin = (u32)memory;
u32 end = (u32)memory + size;
@@ -276,7 +276,7 @@ bool JKRHeap::dispose(void *memory, u32 size)
return false;
}
void JKRHeap::dispose(void *begin, void *end)
void JKRHeap::dispose(void* begin, void* end)
{
dispose_subroutine((u32)begin, (u32)end);
}
@@ -290,12 +290,12 @@ void JKRHeap::dispose()
}
}
void JKRHeap::copyMemory(void *dst, void *src, u32 size)
void JKRHeap::copyMemory(void* dst, void* src, u32 size)
{
u32 count = (size + 3) / 4;
u32 *dst_32 = (u32 *)dst;
u32 *src_32 = (u32 *)src;
u32* dst_32 = (u32*)dst;
u32* src_32 = (u32*)src;
while (count > 0)
{
*dst_32 = *src_32;
@@ -305,15 +305,15 @@ void JKRHeap::copyMemory(void *dst, void *src, u32 size)
}
}
void JKRDefaultMemoryErrorRoutine(void *heap, u32 size, int alignment)
void JKRDefaultMemoryErrorRoutine(void* heap, u32 size, int alignment)
{
// OSReport("Error: Cannot allocate memory %d(0x%x)byte in %d byte alignment from %08x\n", size, size, alignment, heap);
OSErrorLine(710, "abort\n");
}
JKRHeapErrorHandler *JKRHeap::setErrorHandler(JKRHeapErrorHandler *newHandler)
JKRHeapErrorHandler* JKRHeap::setErrorHandler(JKRHeapErrorHandler* newHandler)
{
JKRHeapErrorHandler *oldHandler = mErrorHandler;
JKRHeapErrorHandler* oldHandler = mErrorHandler;
if (!newHandler)
{
newHandler = JKRDefaultMemoryErrorRoutine;
@@ -322,7 +322,7 @@ JKRHeapErrorHandler *JKRHeap::setErrorHandler(JKRHeapErrorHandler *newHandler)
return oldHandler;
}
bool JKRHeap::isSubHeap(JKRHeap *heap) const
bool JKRHeap::isSubHeap(JKRHeap* heap) const
{
if (!heap)
return false;
@@ -347,35 +347,35 @@ bool JKRHeap::isSubHeap(JKRHeap *heap) const
return false;
}
void *operator new(u32 byteCount)
void* operator new(u32 byteCount)
{
return JKRHeap::alloc(byteCount, 4, nullptr);
}
void *operator new(u32 byteCount, int alignment)
void* operator new(u32 byteCount, int alignment)
{
return JKRHeap::alloc(byteCount, alignment, nullptr);
}
void *operator new(u32 byteCount, JKRHeap *heap, int alignment)
void* operator new(u32 byteCount, JKRHeap* heap, int alignment)
{
return JKRHeap::alloc(byteCount, alignment, heap);
}
void *operator new[](u32 byteCount)
void* operator new[](u32 byteCount)
{
return JKRHeap::alloc(byteCount, 4, nullptr);
}
void *operator new[](u32 byteCount, int alignment)
void* operator new[](u32 byteCount, int alignment)
{
return JKRHeap::alloc(byteCount, alignment, nullptr);
}
void *operator new[](u32 byteCount, JKRHeap *heap, int alignment)
void* operator new[](u32 byteCount, JKRHeap* heap, int alignment)
{
return JKRHeap::alloc(byteCount, alignment, heap);
}
// this is not needed without the other pragma and asm bs
void operator delete(void *memory) { JKRHeap::free(memory, nullptr); }
void operator delete[](void *memory) { JKRHeap::free(memory, nullptr); }
// this is not needed without the other pragma and asm bs
void operator delete(void* memory) { JKRHeap::free(memory, nullptr); }
void operator delete[](void* memory) { JKRHeap::free(memory, nullptr); }
/*JKRHeap::TState::TState(const JKRHeap::TState::TArgument &arg, const JKRHeap::TState::TLocation &location)
{
@@ -392,25 +392,25 @@ JKRHeap::TState::TState(const JKRHeap::TState &other, const JKRHeap::TState::TLo
// UNUSED FUNCTION
}*/
JKRHeap::TState::~TState()
JKRHeap::TState::~TState()
{
// Unused, however might need it
}
void JKRHeap::state_register(JKRHeap::TState *p, u32) const
void JKRHeap::state_register(JKRHeap::TState* p, u32) const
{
JUT_ASSERT(1132, p != 0);
JUT_ASSERT(1133, p->getHeap() == this);
}
bool JKRHeap::state_compare(const JKRHeap::TState &r1, const JKRHeap::TState &r2) const
bool JKRHeap::state_compare(const JKRHeap::TState& r1, const JKRHeap::TState& r2) const
{
JUT_ASSERT(1141, r1.getHeap() == r2.getHeap());
return (r1.getCheckCode() == r2.getCheckCode());
}
// fabricated, but probably matches(except for line numbers)
void JKRHeap::state_dumpDifference(const JKRHeap::TState &r1, const JKRHeap::TState &r2)
void JKRHeap::state_dumpDifference(const JKRHeap::TState& r1, const JKRHeap::TState& r2)
{
JUT_LOG_F(1157, "heap : %p / %p", r1.getHeap(), r2.getHeap());
JUT_LOG_F(1158, "check-code : 0x%08x / 0x%08x", r1.getCheckCode(), r2.getCheckCode());
@@ -418,7 +418,7 @@ void JKRHeap::state_dumpDifference(const JKRHeap::TState &r1, const JKRHeap::TSt
JUT_LOG_F(1160, "used size : %10u / %10u", r1.getUsedSize(), r2.getUsedSize());
}
void JKRHeap::state_dump(const TState &state) const
void JKRHeap::state_dump(const TState& state) const
{
JUT_LOG_F(1165, "check-code : 0x%08x", state.getCheckCode());
JUT_LOG_F(1166, "id : 0x%08x", state.getId());
+247
View File
@@ -0,0 +1,247 @@
#include <dolphin/string.h>
#include <dolphin/os/OSCache.h>
#include "JSystem/JSystem.h"
#include "JSystem/JKernel/JKRArchive.h"
#include "JSystem/JKernel/JKRDecomp.h"
#include "JSystem/JKernel/JKRDvdRipper.h"
#include "JSystem/JUtility/JUTAssertion.h"
JKRMemArchive::JKRMemArchive() : JKRArchive() {}
JKRMemArchive::JKRMemArchive(s32 entryNum, EMountDirection mountDirection) : JKRArchive(entryNum, MOUNT_MEM)
{
mIsMounted = false;
mMountDirection = mountDirection;
if (!open(entryNum, mMountDirection))
{
return;
}
else
{
mVolumeType = 'RARC';
mVolumeName = &mStrTable[mDirectories->mOffset];
sVolumeList.prepend(&mFileLoaderLink);
mIsMounted = true;
}
}
JKRMemArchive::JKRMemArchive(void* mem, u32 size, JKRMemBreakFlag breakFlag) : JKRArchive((s32)mem, MOUNT_MEM)
{
mIsMounted = false;
if (!open(mem, size, breakFlag))
{
return;
}
else
{
mVolumeType = 'RARC';
mVolumeName = &mStrTable[mDirectories->mOffset];
sVolumeList.prepend(&mFileLoaderLink);
mIsMounted = true;
}
}
JKRMemArchive::~JKRMemArchive()
{
if (mIsMounted == true)
{
if (mIsOpen && mArcHeader)
JKRFreeToHeap(mHeap, mArcHeader);
sVolumeList.remove(&mFileLoaderLink);
mIsMounted = false;
}
}
#ifdef DEBUG // function is needed to generate certain strings first, however this is not what the original function looks like
void JKRMemArchive::fixedInit(s32)
{
JUT_ASSERT(isMounted());
JUT_PANIC("mMountCount == 1"); // some member is called mMountCount, if there's a game with this assert, fix
JUT_ASSERT(mArcHeader->signature == 'RARC');
}
#endif
bool JKRMemArchive::open(s32 entryNum, JKRArchive::EMountDirection mountDirection)
{
mArcHeader = nullptr;
mArcInfoBlock = nullptr;
mArchiveData = nullptr;
mDirectories = nullptr;
mFileEntries = nullptr;
mStrTable = nullptr;
mIsOpen = false;
mMountDirection = mountDirection;
if (mMountDirection == JKRArchive::MOUNT_DIRECTION_HEAD)
{
u32 loadedSize;
mArcHeader = (SArcHeader*)JKRDvdRipper::loadToMainRAM(
entryNum, nullptr, EXPAND_SWITCH_DECOMPRESS, 0, mHeap, JKRDvdRipper::ALLOC_DIR_TOP,
0, (int*)&mCompression);
}
else
{
u32 loadedSize;
mArcHeader = (SArcHeader*)JKRDvdRipper::loadToMainRAM(
entryNum, nullptr, EXPAND_SWITCH_DECOMPRESS, 0, mHeap,
JKRDvdRipper::ALLOC_DIR_BOTTOM, 0, (int*)&mCompression);
}
if (!mArcHeader)
{
mMountMode = UNKNOWN_MOUNT_MODE;
}
else
{
JUT_ASSERT(mArcHeader->signature == 'RARC');
mArcInfoBlock = (SArcDataInfo*)((u8*)mArcHeader + mArcHeader->header_length);
mDirectories = (SDIDirEntry*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->file_entry_offset);
mStrTable = (char*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->string_table_offset);
mArchiveData =
(u8*)((u32)mArcHeader + mArcHeader->header_length + mArcHeader->file_data_offset);
mIsOpen = true;
}
#if DEBUG
// OS Assert?
if (mMountMode == UNKNOWN_MOUNT_MODE)
{
OSReport(":::Cannot alloc memory [%s][%d]\n", __FILE__, 460);
}
#endif
return (mMountMode == UNKNOWN_MOUNT_MODE) ? false : true;
}
bool JKRMemArchive::open(void* buffer, u32 bufferSize, JKRMemBreakFlag flag)
{
mArcHeader = (SArcHeader*)buffer;
JUT_ASSERT(mArcHeader->signature == 'RARC');
mArcInfoBlock = (SArcDataInfo*)((u8*)mArcHeader + mArcHeader->header_length);
mDirectories = (SDIDirEntry*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->node_offset);
mFileEntries = (SDIFileEntry*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->file_entry_offset);
mStrTable = (char*)((u8*)&mArcInfoBlock->num_nodes + mArcInfoBlock->string_table_offset);
mArchiveData = (u8*)(((u32)mArcHeader + mArcHeader->header_length) + mArcHeader->file_data_offset);
mIsOpen = (flag == MBF_1) ? true : false; // mIsOpen might be u8
mHeap = JKRHeap::findFromRoot(buffer);
mCompression = JKRCOMPRESSION_NONE;
return true;
}
void* JKRMemArchive::fetchResource(SDIFileEntry* fileEntry, u32* resourceSize)
{
JUT_ASSERT(isMounted())
if (!fileEntry->mData)
fileEntry->mData = mArchiveData + fileEntry->mDataOffset;
if (resourceSize)
*resourceSize = fileEntry->mSize;
return fileEntry->mData;
}
void* JKRMemArchive::fetchResource(void* buffer, u32 bufferSize, SDIFileEntry* fileEntry,
u32* resourceSize, JKRExpandSwitch expandSwitch)
{
JUT_ASSERT(isMounted())
bufferSize = (bufferSize & -32);
u32 srcLength = ALIGN_NEXT(fileEntry->mSize, 32);
if (srcLength > bufferSize)
{
srcLength = bufferSize;
}
if (fileEntry->mData != nullptr)
{
JKRHeap::copyMemory(buffer, fileEntry->mData, srcLength);
}
else
{
int compression = JKRConvertAttrToCompressionType(fileEntry->getAttr());
if (expandSwitch != EXPAND_SWITCH_DECOMPRESS)
compression = JKRCOMPRESSION_NONE;
void* data = mArchiveData + fileEntry->mDataOffset;
srcLength =
fetchResource_subroutine((u8*)data, srcLength, (u8*)buffer, bufferSize, compression);
}
if (resourceSize)
{
*resourceSize = srcLength;
}
return buffer;
}
void JKRMemArchive::removeResourceAll(void)
{
JUT_ASSERT(isMounted());
if (mArcInfoBlock == nullptr)
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 = mFileEntries;
for (int i = 0; i < mArcInfoBlock->num_file_entries; i++)
{
if (fileEntry->mData)
{
fileEntry->mData = nullptr;
}
}
}
bool JKRMemArchive::removeResource(void* resource)
{
JUT_ASSERT(isMounted());
SDIFileEntry* fileEntry = findPtrResource(resource);
if (!fileEntry)
return false;
fileEntry->mData = nullptr;
return true;
}
u32 JKRMemArchive::fetchResource_subroutine(u8* src, u32 srcLength, u8* dst, u32 dstLength, int compression)
{
u32 alignedDst = dstLength & -32;
u32 alignedSrc = ALIGN_NEXT(srcLength, 32);
switch (compression)
{
case JKRCOMPRESSION_NONE:
if (alignedSrc > alignedDst)
alignedSrc = alignedDst;
JKRHeap::copyMemory(dst, src, alignedSrc);
return alignedSrc;
case JKRCOMPRESSION_YAY0:
case JKRCOMPRESSION_YAZ0:
u32 expandSize = JKRDecompExpandSize(src);
if (expandSize > alignedDst) {
expandSize = alignedDst;
}
JKRDecompress(src, dst, expandSize, 0);
return expandSize;
default:
{
JPANIC(709, ":::??? bad sequence\n");
return 0;
}
}
return alignedSrc;
}
+68 -15
View File
@@ -1,13 +1,12 @@
#include "JSystem/JKernel/JKRThread.h"
#include "JSystem/JSupport/JSUList.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JKernel/JKRMacro.h"
#include "JSystem/JKernel/JKRThread.h"
#include "JSystem/JKernel/JKRHeap.h"
JSUList<JKRThread> JKRThread::sThreadList;
JKRThread::JKRThread(u32 stackSize, int msgCount, int threadPrio)
: JKRDisposer(), mLink(this) {
: mLink(this) {
this->mHeap = JKRHeap::findFromRoot(this);
if (this->mHeap == nullptr) {
this->mHeap = JKRHeap::sSystemHeap;
@@ -16,26 +15,26 @@ JKRThread::JKRThread(u32 stackSize, int msgCount, int threadPrio)
this->mStackSize = JKR_ALIGN32(stackSize);
this->mStackMemory = JKRHeap::alloc(this->mStackSize, 32, this->mHeap);
this->mThreadRecord =
(OSThread *)JKRHeap::alloc(sizeof(OSThread), 32, this->mHeap);
(OSThread*)JKRHeap::alloc(sizeof(OSThread), 32, this->mHeap);
OSCreateThread(this->mThreadRecord, &JKRThread::start, this,
(void *)((u32)this->mStackMemory + this->mStackSize),
this->mStackSize, threadPrio, OS_THREAD_ATTR_DETACH);
(void*)((u32)this->mStackMemory + this->mStackSize),
this->mStackSize, threadPrio, OS_THREAD_ATTR_DETACH);
this->mMesgCount = msgCount;
this->mMesgBuffer = (OSMessage *)JKRHeap::alloc(
mMesgCount * sizeof(OSMessage), 0, this->mHeap);
this->mMesgBuffer = (OSMessage*)JKRHeap::alloc(
mMesgCount * sizeof(OSMessage), 0, this->mHeap);
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, this->mMesgCount);
JKRThread::sThreadList.append(&this->mLink);
}
JKRThread::JKRThread(OSThread *threadRecord, int msgCount)
: JKRDisposer(), mLink(this) {
JKRThread::JKRThread(OSThread* threadRecord, int msgCount)
: mLink(this) {
this->mHeap = nullptr;
this->mThreadRecord = threadRecord;
this->mStackSize = (u32)threadRecord->stackEnd - (u32)threadRecord->stackBase;
this->mStackMemory = threadRecord->stackBase;
this->mMesgCount = msgCount;
this->mMesgBuffer = (OSMessage *)JKRHeap::sSystemHeap->alloc(
mMesgCount * sizeof(OSMessage), 4);
this->mMesgBuffer = (OSMessage*)JKRHeap::sSystemHeap->alloc(
mMesgCount * sizeof(OSMessage), 4);
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, this->mMesgCount);
JKRThread::sThreadList.append(&this->mLink);
}
@@ -56,6 +55,60 @@ JKRThread::~JKRThread() {
JKRHeap::free(this->mMesgBuffer, nullptr);
}
void *JKRThread::start(void *thread) {
return static_cast<JKRThread*>(thread)->run();
void* JKRThread::start(void* thread) {
return static_cast<JKRThread*>(thread)->run();
}
// UNUSED FUNCTIONS, REQUIRED FOR RTTI
JKRTask::JKRTask() : JKRThread(0x4000, 4, 31)
{
}
JKRTask::~JKRTask() { }
JKRTask* JKRTask::create()
{
return new JKRTask();
}
void JKRTask::destroy() {
delete this;
}
void* JKRTask::run()
{
Request* req;
//OSInitFastCast();
while (true)
{
req = (Request*)waitMessageBlock();
if (req->mCb)
{
req->mCb(req->mArg);
if (mTaskMsgQueue)
{
OSSendMessage(mTaskMsgQueue, req->mMsg, OS_MESSAGE_NOBLOCK);
}
}
req->mCb = nullptr;
}
}
bool JKRTask::request(RequestCallback callback, void* arg, void* msg)
{
Request* req = searchBlank();
if (req == nullptr)
{
return false;
}
req->mCb = callback;
req->mArg = arg;
req->mMsg = msg;
bool sendResult = OSSendMessage(&mMesgQueue, req, OS_MESSAGE_NOBLOCK);
if (!sendResult)
{
req->mCb = nullptr;
}
return sendResult;
}
-3
View File
@@ -1,3 +0,0 @@
#include "JSystem/JKernel/JKRThread.h"
__declspec(weak) void* JKRThread::run() { return nullptr; }
+1
View File
@@ -0,0 +1 @@
# there totally is code in this file, needed to bypass a bug caused by trim_ctors