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

312 lines
9.7 KiB
C++
Raw Normal View History

2021-04-01 02:07:58 +02:00
//
2021-03-28 22:49:05 +02:00
// Generated By: dol2asm
// Translation Unit: JKRDecomp
2021-04-01 02:07:58 +02:00
//
2021-01-03 22:19:54 +01:00
2021-04-01 02:07:58 +02:00
#include "JSystem/JKernel/JKRDecomp.h"
2021-05-03 02:03:24 +02:00
#include "JSystem/JKernel/JKRAramPiece.h"
2021-03-28 22:49:05 +02:00
2021-04-01 02:07:58 +02:00
//
2021-03-28 22:49:05 +02:00
// Declarations:
2021-04-01 02:07:58 +02:00
//
2021-03-28 22:49:05 +02:00
/* ############################################################################################## */
2021-04-06 18:00:35 +02:00
/* 804514B0-804514B8 0009B0 0004+04 1/1 0/0 0/0 .sbss sDecompObject__9JKRDecomp */
2021-05-03 02:03:24 +02:00
JKRDecomp* JKRDecomp::sDecompObject;
2021-03-28 22:49:05 +02:00
2023-09-24 02:05:03 -07:00
JKRDecomp* JKRDecomp::create(s32 priority) {
2021-05-03 02:03:24 +02:00
if (!sDecompObject) {
sDecompObject = new (JKRHeap::getSystemHeap(), 0) JKRDecomp(priority);
}
return sDecompObject;
2020-12-06 21:02:25 +01:00
}
2021-03-28 22:49:05 +02:00
/* ############################################################################################## */
2021-04-06 18:00:35 +02:00
/* 803CC460-803CC480 029580 0020+00 1/1 0/0 0/0 .data sMessageBuffer__9JKRDecomp */
2021-05-03 02:03:24 +02:00
OSMessage JKRDecomp::sMessageBuffer[8] = {0};
2021-03-28 22:49:05 +02:00
2021-04-06 18:00:35 +02:00
/* 803CC480-803CC4A0 0295A0 0020+00 2/2 0/0 0/0 .data sMessageQueue__9JKRDecomp */
2021-05-03 02:03:24 +02:00
OSMessageQueue JKRDecomp::sMessageQueue = {0};
2021-03-28 22:49:05 +02:00
2021-04-06 18:00:35 +02:00
/* 802DB6E0-802DB730 2D6020 0050+00 1/1 0/0 0/0 .text __ct__9JKRDecompFl */
2023-09-24 02:05:03 -07:00
JKRDecomp::JKRDecomp(s32 priority) : JKRThread(0x800, 0x10, priority) {
2021-05-03 02:03:24 +02:00
resume();
2020-12-06 21:02:25 +01:00
}
2021-04-06 18:00:35 +02:00
/* 802DB730-802DB790 2D6070 0060+00 1/0 0/0 0/0 .text __dt__9JKRDecompFv */
2021-05-03 02:03:24 +02:00
JKRDecomp::~JKRDecomp() {}
2020-12-06 21:02:25 +01:00
2021-04-06 18:00:35 +02:00
/* 802DB790-802DB858 2D60D0 00C8+00 1/0 0/0 0/0 .text run__9JKRDecompFv */
2023-02-26 17:50:56 -08:00
void* JKRDecomp::run() {
2021-05-03 02:03:24 +02:00
OSInitMessageQueue(&sMessageQueue, sMessageBuffer, 8);
for (;;) {
OSMessage message;
OSReceiveMessage(&sMessageQueue, &message, OS_MESSAGE_BLOCK);
2021-05-03 02:03:24 +02:00
JKRDecompCommand* command = (JKRDecompCommand*)message;
decode(command->mSrcBuffer, command->mDstBuffer, command->mSrcLength, command->mDstLength);
if (command->field_0x20 != 0) {
if (command->field_0x20 == 1) {
JKRAramPiece::sendCommand(command->mAMCommand);
}
continue;
}
if (command->mCallback) {
(*command->mCallback)((u32)command);
continue;
}
if (command->field_0x1c) {
OSSendMessage(command->field_0x1c, (OSMessage)1, OS_MESSAGE_NOBLOCK);
2021-05-03 02:03:24 +02:00
} else {
OSSendMessage(&command->mMessageQueue, (OSMessage)1, OS_MESSAGE_NOBLOCK);
2021-05-03 02:03:24 +02:00
}
}
2020-12-06 21:02:25 +01:00
}
2021-04-06 18:00:35 +02:00
/* 802DB858-802DB8D0 2D6198 0078+00 1/1 0/0 0/0 .text prepareCommand__9JKRDecompFPUcPUcUlUlPFUl_v
2021-04-01 02:07:58 +02:00
*/
2021-05-03 02:03:24 +02:00
JKRDecompCommand* JKRDecomp::prepareCommand(u8* srcBuffer, u8* dstBuffer, u32 srcLength,
u32 dstLength,
JKRDecompCommand::AsyncCallback callback) {
JKRDecompCommand* command = new (JKRHeap::getSystemHeap(), -4) JKRDecompCommand();
command->mSrcBuffer = srcBuffer;
command->mDstBuffer = dstBuffer;
command->mSrcLength = srcLength;
command->mDstLength = dstLength;
command->mCallback = callback;
return command;
2020-12-06 21:02:25 +01:00
}
2021-04-06 18:00:35 +02:00
/* 802DB8D0-802DB900 2D6210 0030+00 1/1 1/1 0/0 .text sendCommand__9JKRDecompFP16JKRDecompCommand
2021-04-01 02:07:58 +02:00
*/
2021-05-03 02:03:24 +02:00
void JKRDecomp::sendCommand(JKRDecompCommand* command) {
OSSendMessage(&sMessageQueue, command, OS_MESSAGE_NOBLOCK);
2020-12-06 21:02:25 +01:00
}
2021-04-06 18:00:35 +02:00
/* 802DB900-802DB934 2D6240 0034+00 1/1 0/0 0/0 .text orderAsync__9JKRDecompFPUcPUcUlUlPFUl_v */
2021-05-03 02:03:24 +02:00
JKRDecompCommand* JKRDecomp::orderAsync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 dstLength,
JKRDecompCommand::AsyncCallback callback) {
JKRDecompCommand* command =
prepareCommand(srcBuffer, dstBuffer, srcLength, dstLength, callback);
sendCommand(command);
return command;
2020-12-06 21:02:25 +01:00
}
2021-04-06 18:00:35 +02:00
/* 802DB934-802DB988 2D6274 0054+00 1/1 0/0 0/0 .text sync__9JKRDecompFP16JKRDecompCommandi */
2021-05-03 02:03:24 +02:00
bool JKRDecomp::sync(JKRDecompCommand* command, int isNonBlocking) {
OSMessage message;
bool result;
if (isNonBlocking == JKRDECOMP_SYNC_BLOCKING) {
OSReceiveMessage(&command->mMessageQueue, &message, OS_MESSAGE_BLOCK);
2021-05-03 02:03:24 +02:00
result = true;
} else {
result =
OSReceiveMessage(&command->mMessageQueue, &message, OS_MESSAGE_NOBLOCK) != FALSE;
2021-05-03 02:03:24 +02:00
}
return result;
2020-12-06 21:02:25 +01:00
}
2021-04-06 18:00:35 +02:00
/* 802DB988-802DB9DC 2D62C8 0054+00 0/0 5/5 0/0 .text orderSync__9JKRDecompFPUcPUcUlUl */
2021-05-03 02:03:24 +02:00
bool JKRDecomp::orderSync(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 dstLength) {
JKRDecompCommand* command = orderAsync(srcBuffer, dstBuffer, srcLength, dstLength, NULL);
bool result = sync(command, JKRDECOMP_SYNC_BLOCKING);
delete command;
return result;
2020-12-06 21:02:25 +01:00
}
2021-04-06 18:00:35 +02:00
/* 802DB9DC-802DBA58 2D631C 007C+00 1/1 0/0 0/0 .text decode__9JKRDecompFPUcPUcUlUl */
2021-05-03 02:03:24 +02:00
void JKRDecomp::decode(u8* srcBuffer, u8* dstBuffer, u32 srcLength, u32 dstLength) {
JKRCompression compression = checkCompressed(srcBuffer);
if (compression == COMPRESSION_YAY0) {
decodeSZP(srcBuffer, dstBuffer, srcLength, dstLength);
} else if (compression == COMPRESSION_YAZ0) {
decodeSZS(srcBuffer, dstBuffer, srcLength, dstLength);
}
2021-01-03 22:19:54 +01:00
}
2020-12-06 21:02:25 +01:00
2021-04-06 18:00:35 +02:00
/* 802DBA58-802DBC14 2D6398 01BC+00 1/1 0/0 0/0 .text decodeSZP__9JKRDecompFPUcPUcUlUl */
2021-05-03 02:03:24 +02:00
void JKRDecomp::decodeSZP(u8* src, u8* dst, u32 srcLength, u32 dstLength) {
2023-07-21 19:30:25 +03:00
int srcChunkOffset;
int count;
int dstOffset;
u32 length = srcLength;
int linkInfo;
int offset;
int i;
int decodedSize = READU32_BE(src, 4);
int linkTableOffset = READU32_BE(src, 8);
int srcDataOffset = READU32_BE(src, 12);
2021-05-03 02:03:24 +02:00
dstOffset = 0;
2023-02-26 17:50:56 -08:00
u32 counter = 0;
2021-05-03 02:03:24 +02:00
srcChunkOffset = 16;
u32 chunkBits;
if (srcLength == 0)
return;
if (dstLength > decodedSize)
return;
2023-07-21 19:30:25 +03:00
do
{
if (counter == 0)
{
chunkBits = READU32_BE(src, srcChunkOffset);
2023-02-26 17:50:56 -08:00
srcChunkOffset += sizeof(u32);
counter = sizeof(u32) * 8;
2021-05-03 02:03:24 +02:00
}
2023-07-21 19:30:25 +03:00
if (chunkBits & 0x80000000)
{
if (dstLength == 0)
{
2021-05-03 02:03:24 +02:00
dst[dstOffset] = src[srcDataOffset];
length--;
2023-02-26 17:50:56 -08:00
if (length == 0)
2021-05-03 02:03:24 +02:00
return;
2023-07-21 19:30:25 +03:00
}
else
{
2021-05-03 02:03:24 +02:00
dstLength--;
}
dstOffset++;
srcDataOffset++;
2023-07-21 19:30:25 +03:00
}
else
{
2023-02-26 17:50:56 -08:00
linkInfo = src[linkTableOffset] << 8 | src[linkTableOffset + 1];
linkTableOffset += sizeof(u16);
2021-05-03 02:03:24 +02:00
offset = dstOffset - (linkInfo & 0xFFF);
2023-02-26 17:50:56 -08:00
count = (linkInfo >> 12);
2023-07-21 19:30:25 +03:00
if (count == 0)
{
count = (u32)src[srcDataOffset++] + 0x12;
}
else
2021-05-03 02:03:24 +02:00
count += 2;
2023-07-21 19:30:25 +03:00
if (count > decodedSize - dstOffset)
2021-05-03 02:03:24 +02:00
count = decodedSize - dstOffset;
2023-07-21 19:30:25 +03:00
for (i = 0; i < count; i++, dstOffset++, offset++)
{
if (dstLength == 0)
{
2021-05-03 02:03:24 +02:00
dst[dstOffset] = dst[offset - 1];
length--;
2023-02-26 17:50:56 -08:00
if (length == 0)
2021-05-03 02:03:24 +02:00
return;
2023-07-21 19:30:25 +03:00
}
else
2021-05-03 02:03:24 +02:00
dstLength--;
}
}
chunkBits <<= 1;
counter--;
2023-02-26 17:50:56 -08:00
} while (dstOffset < decodedSize);
2021-05-03 02:03:24 +02:00
}
2020-12-06 21:02:25 +01:00
2021-04-06 18:00:35 +02:00
/* 802DBC14-802DBCF8 2D6554 00E4+00 1/1 0/0 0/0 .text decodeSZS__9JKRDecompFPUcPUcUlUl */
2023-02-26 17:50:56 -08:00
void JKRDecomp::decodeSZS(u8* src_buffer, u8* dst_buffer, u32 srcSize, u32 dstSize) {
u8* decompEnd;
u8* copyStart;
2023-02-26 17:50:56 -08:00
s32 copyByteCount;
s32 chunkBitsLeft = 0;
s32 chunkBits;
decompEnd = dst_buffer + *(int*)(src_buffer + 4) - dstSize;
2023-09-25 01:02:29 -07:00
if (srcSize == 0) {
return;
2023-09-25 01:02:29 -07:00
}
if (dstSize > *(u32*)src_buffer) {
return;
2023-09-25 01:02:29 -07:00
}
2023-02-26 17:50:56 -08:00
u8* curSrcPos = src_buffer + 0x10;
do {
if (chunkBitsLeft == 0) {
2023-09-25 01:02:29 -07:00
chunkBits = curSrcPos[0];
chunkBitsLeft = 8;
curSrcPos++;
}
if ((chunkBits & 0x80) != 0) {
2023-02-26 17:50:56 -08:00
if (dstSize == 0) {
2023-09-25 01:02:29 -07:00
dst_buffer[0] = curSrcPos[0];
2023-02-26 17:50:56 -08:00
srcSize--;
dst_buffer++;
2023-02-26 17:50:56 -08:00
if (srcSize == 0)
return;
} else {
2023-02-26 17:50:56 -08:00
dstSize--;
}
curSrcPos++;
} else {
2023-09-25 01:02:29 -07:00
u32 local_28 = curSrcPos[1] | (curSrcPos[0] & 0xF) << 8;
u32 r31 = curSrcPos[0] >> 4;
curSrcPos += 2;
2023-09-25 01:02:29 -07:00
copyStart = dst_buffer - local_28;
if (r31 == 0) {
copyByteCount = curSrcPos[0] + 0x12;
curSrcPos++;
} else {
2023-09-25 01:02:29 -07:00
copyByteCount = r31 + 2;
}
do {
2023-02-26 17:50:56 -08:00
if (dstSize == 0) {
2023-09-25 01:02:29 -07:00
dst_buffer[0] = copyStart[-1];
2023-02-26 17:50:56 -08:00
srcSize--;
dst_buffer++;
2023-02-26 17:50:56 -08:00
if (srcSize == 0)
return;
} else {
2023-02-26 17:50:56 -08:00
dstSize--;
}
copyByteCount--;
copyStart++;
} while (copyByteCount != 0);
}
chunkBits <<= 1;
chunkBitsLeft--;
} while (dst_buffer != decompEnd);
}
2021-03-28 22:49:05 +02:00
2021-04-06 18:00:35 +02:00
/* 802DBCF8-802DBD70 2D6638 0078+00 1/1 4/4 0/0 .text checkCompressed__9JKRDecompFPUc */
2021-05-03 02:03:24 +02:00
JKRCompression JKRDecomp::checkCompressed(u8* src) {
if ((src[0] == 'Y') && (src[1] == 'a') && (src[3] == '0')) {
if (src[2] == 'y') {
return COMPRESSION_YAY0;
}
2023-02-26 17:50:56 -08:00
2021-05-03 02:03:24 +02:00
if (src[2] == 'z') {
return COMPRESSION_YAZ0;
}
}
2023-02-26 17:50:56 -08:00
2021-05-03 02:03:24 +02:00
if ((src[0] == 'A') && (src[1] == 'S') && (src[2] == 'R')) {
return COMPRESSION_ASR;
}
2023-02-26 17:50:56 -08:00
2021-05-03 02:03:24 +02:00
return COMPRESSION_NONE;
2021-03-28 22:49:05 +02:00
}
2021-04-06 18:00:35 +02:00
/* 802DBD70-802DBDC0 2D66B0 0050+00 1/1 0/0 0/0 .text __ct__16JKRDecompCommandFv */
2021-05-03 02:03:24 +02:00
JKRDecompCommand::JKRDecompCommand() {
OSInitMessageQueue(&mMessageQueue, &mMessage, 1);
mCallback = NULL;
field_0x1c = NULL;
mThis = this;
field_0x20 = 0;
2021-03-28 22:49:05 +02:00
}
2021-04-06 18:00:35 +02:00
/* 802DBDC0-802DBDFC 2D6700 003C+00 1/1 0/0 0/0 .text __dt__16JKRDecompCommandFv */
2021-05-03 02:03:24 +02:00
JKRDecompCommand::~JKRDecompCommand() {}