merge cuyler's PR

This commit is contained in:
Prakxo
2023-03-13 07:15:03 +00:00
parent cf13cc2139
commit 3dd5dbcf59
48 changed files with 3102 additions and 215 deletions
+295
View File
@@ -0,0 +1,295 @@
#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"
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);
}
return JKRDecomp::sDecompObject;
}
JKRDecomp::JKRDecomp(s32 priority) : JKRThread(JKRDECOMP_STACK_SIZE, JKRDECOMP_THREAD_MSG_BUF_COUNT, priority) {
OSResumeThread(this->mThreadRecord);
}
JKRDecomp::~JKRDecomp() { }
void* JKRDecomp::run() {
OSMessage recMesg;
JKRDecompCommand* cmd;
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);
if (cmd->transferType == JKRDecompCommand::MRAM) {
break;
}
if (cmd->transferType == JKRDecompCommand::ARAM) {
JKRAramPcs_SendCommand(cmd->mAMCommand);
}
}
if (cmd->mCallback == nullptr) {
break;
}
cmd->mCallback((u32)cmd);
}
if (cmd->pMesgQueue1C != nullptr) {
OSSendMessage(cmd->pMesgQueue1C, (OSMessage)1, OS_MESSAGE_NOBLOCK);
}
else {
OSSendMessage(&cmd->mMesgQueue, (OSMessage)1, OS_MESSAGE_NOBLOCK);
}
}
}
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;
cmd->mSkipCount = skipCount;
cmd->mCallback = callback;
return cmd;
}
BOOL JKRDecomp::sendCommand(JKRDecompCommand* cmd) {
BOOL res = OSSendMessage(&JKRDecomp::sMessageQueue, (OSMessage)cmd, OS_MESSAGE_BLOCK);
#ifdef JSYSTEM_DEBUG
if (res == FALSE) {
JPANIC(142, "Decomp MesgBuf FULL!");
}
#endif
return res;
}
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;
}
bool JKRDecomp::sync(JKRDecompCommand* cmd, BOOL noBlock) {
OSMessage msg;
if (!noBlock) {
OSReceiveMessage(&cmd->mMesgQueue, &msg, OS_MESSAGE_BLOCK);
return true;
}
else {
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 res = JKRDecomp::sync(cmd, FALSE);
delete cmd;
return res;
}
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);
}
else if (mode == SZS) {
JKRDecomp::decodeSZS(srcBuffer, dstBuffer, srcLength, skipCount);
}
}
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);
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;
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++;
}
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
skipCount--;
}
}
chunkBits <<= 1;
counter--;
} while (dstOffset < decodedSize);
}
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;
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++;
}
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);
}
chunkBits <<= 1;
chunkBitsLeft--;
} while (dst_buffer != decompEnd);
}
JKRDecomp::CompressionMode JKRDecomp::checkCompressed(u8* buf) {
if (buf[0] == 'Y' && buf[1] == 'a' && buf[3] == '0') {
if (buf[2] == 'y') {
return SZP;
}
if (buf[2] == 'z') {
return SZS;
}
}
return NONE;
}
JKRDecompCommand::JKRDecompCommand() {
OSInitMessageQueue(&this->mMesgQueue, this->mMesgBuffer, 1);
this->mCallback = nullptr;
this->pMesgQueue1C = nullptr;
this->mCmd = this;
this->transferType = MRAM;
}
JKRDecompCommand::~JKRDecompCommand() { }