diff options
| author | Random <28494085+Random06457@users.noreply.github.com> | 2020-06-22 00:43:14 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-21 18:43:14 -0400 |
| commit | ab1ec89f22808c38426f7e0d4e4f0e1a5bc3aec9 (patch) | |
| tree | 55db3fee7706e85d9f35c55444fb8fd0617c21b1 /src | |
| parent | afce6a3c3685e09d94aa094ab4f2bb346d58b0ed (diff) | |
Decompile jpegdecoder.c, padsetup.c and code_800C3C20.c (#217)
* Decompile jpegdecoder.c, padsetup.c and code_800C3C20.c
* change func_800C3C20's prototype and rename some fields in jpeg related structs
* Fix comment in Jpeg_GetU16 and change func_800C3C20
* use a switch in padsetup.c
Diffstat (limited to 'src')
| -rw-r--r-- | src/code/code_800C3C20.c | 13 | ||||
| -rw-r--r-- | src/code/jpegdecoder.c | 201 | ||||
| -rw-r--r-- | src/code/jpegutils.c | 6 | ||||
| -rw-r--r-- | src/code/padmgr.c | 2 | ||||
| -rw-r--r-- | src/code/padsetup.c | 33 | ||||
| -rw-r--r-- | src/code/z_jpeg.c | 38 |
6 files changed, 270 insertions, 23 deletions
diff --git a/src/code/code_800C3C20.c b/src/code/code_800C3C20.c new file mode 100644 index 000000000..52d02ca68 --- /dev/null +++ b/src/code/code_800C3C20.c @@ -0,0 +1,13 @@ +#include <global.h> + +u8 D_8012D200[] = { + 0, 1, 2, 3, 4, 5, 6, +}; + +void func_800C3C20(void) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(D_8012D200) & 0xFFFFFFFFu; i++) { + func_800F87A0(D_8012D200[i]); + } +} diff --git a/src/code/jpegdecoder.c b/src/code/jpegdecoder.c new file mode 100644 index 000000000..1f73a4626 --- /dev/null +++ b/src/code/jpegdecoder.c @@ -0,0 +1,201 @@ +#include <global.h> + +u8* sJpegBitStreamPtr; +u32 sJpegBitStreamByteIdx; +u8 sJpegBitStreamBitIdx; +u8 sJpegBitStreamDontSkip; +u32 sJpegBitStreamCurWord; + +s32 JpegDecoder_Decode(JpegDecoder* decoder, u16* mcuBuff, s32 count, u8 isFollowing, JpegDecoderState* state) { + s16 pad; + s16 unk0; + s16 unk1; + s16 unk2; + u32 idx; + s32 inc; + s16 unkCount; + + JpegHuffmanTable* hTable0; + JpegHuffmanTable* hTable1; + JpegHuffmanTable* hTable2; + JpegHuffmanTable* hTable3; + + inc = 0; + sJpegBitStreamPtr = decoder->imageData; + if (decoder->mode == 0) { + unkCount = 2; + } else { + unkCount = 4; + if (decoder->unk_05 == 1) { + inc = 8 * 8 * 2; + } + } + + hTable0 = decoder->hTablePtrs[0]; + hTable1 = decoder->hTablePtrs[1]; + hTable2 = decoder->hTablePtrs[2]; + hTable3 = decoder->hTablePtrs[3]; + + if (!isFollowing) { + sJpegBitStreamByteIdx = 0; + sJpegBitStreamBitIdx = 32; + sJpegBitStreamCurWord = 0; + sJpegBitStreamDontSkip = 0; + unk0 = 0; + unk1 = 0; + unk2 = 0; + } else { + sJpegBitStreamByteIdx = state->byteIdx; + sJpegBitStreamBitIdx = state->bitIdx; + sJpegBitStreamCurWord = state->curWord; + sJpegBitStreamDontSkip = state->dontSkip; + unk0 = state->unk_0C; + unk1 = state->unk_0E; + unk2 = state->unk_10; + } + + while (count != 0) { + for (idx = 0; idx < unkCount; idx++) { + if (JpegDecoder_ProcessMcu(hTable0, hTable1, mcuBuff, &unk0)) { + return 2; + } + mcuBuff += 8 * 8; + } + + if (JpegDecoder_ProcessMcu(hTable2, hTable3, mcuBuff, &unk1)) { + return 2; + } + mcuBuff += 8 * 8; + + if (JpegDecoder_ProcessMcu(hTable2, hTable3, mcuBuff, &unk2)) { + return 2; + } + + count--; + mcuBuff += 8 * 8; + mcuBuff += inc; + } + + state->byteIdx = sJpegBitStreamByteIdx; + state->bitIdx = sJpegBitStreamBitIdx; + state->curWord = sJpegBitStreamCurWord; + state->dontSkip = sJpegBitStreamDontSkip; + state->unk_0C = unk0; + state->unk_0E = unk1; + state->unk_10 = unk2; + return 0; +} + +s32 JpegDecoder_ProcessMcu(JpegHuffmanTable* hTable0, JpegHuffmanTable* hTable1, s16* mcu, s16* unk) { + s8 i = 0; + s8 zeroCount; + s16 coeff; + + if (JpegDecoder_ParseNextSymbol(hTable0, &coeff, &zeroCount)) { + return 1; + } + + *unk += coeff; + mcu[i++] = *unk; + while (i < 8 * 8) { + if (JpegDecoder_ParseNextSymbol(hTable1, &coeff, &zeroCount) != 0) { + return 1; + } + + if (coeff == 0) { + if (zeroCount == 0xF) { + while (zeroCount-- >= 0) { + mcu[i++] = 0; + } + } else { + while (i < 8 * 8) { + mcu[i++] = 0; + } + break; + } + } else { + while (0 < zeroCount--) { + mcu[i++] = 0; + } + mcu[i++] = coeff; + } + } + + return 0; +} + +#ifdef NON_MATCHING +// stack usage (coeffLength is stored as a u32 instead of a u8) +s32 JpegDecoder_ParseNextSymbol(JpegHuffmanTable* hTable, s16* outCoeff, u8* outZeroCount) { + u16 buff; + u8 codeIdx; + u8 sym; + u8 coeffLength; // 0x26 + u16 codeOff; // 0x24 + + codeOff = 0; + buff = JpegDecoder_ReadBits(16); + + for (codeIdx = 0; codeIdx < 16; codeIdx++) { + if (hTable->codesB[codeIdx] == 0xFFFF) { + continue; + } + + codeOff = buff >> (15 - codeIdx); + if (codeOff <= hTable->codesB[codeIdx]) { + break; + } + } + + if (codeIdx >= 16) { + return 1; + } + + sym = hTable->symbols[hTable->codeOffs[codeIdx] + codeOff - hTable->codesA[codeIdx]]; + *outZeroCount = sym >> 4; + coeffLength = sym & 0xF; // not using a temp for "sym & 0xF" puts coeffLength on the stack + + sJpegBitStreamBitIdx += codeIdx - 15; + *outCoeff = 0; + if (coeffLength) { // (cond != 0) instead of (cond) puts coeffLength on the stack + *outCoeff = JpegDecoder_ReadBits(coeffLength); + if (*outCoeff < (1 << (coeffLength - 1))) { + *outCoeff += + (-1 << coeffLength) + 1; // (*outCoeff -= (1 << coeffLength)-1; makes more sense but doesn't match) + } + } + + return 0; +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/code/jpegdecoder/JpegDecoder_ParseNextSymbol.s") +#endif + +u16 JpegDecoder_ReadBits(u8 len) { + u8 byteCount; + u8 data; + s32 ret; + u32 temp; + ret = 0; // this is required for some reason + + for (byteCount = sJpegBitStreamBitIdx >> 3; byteCount > 0; byteCount--) { + data = sJpegBitStreamPtr[sJpegBitStreamByteIdx++]; + if (sJpegBitStreamDontSkip) { + if (data == 0) { + data = sJpegBitStreamPtr[sJpegBitStreamByteIdx++]; + } + } + + sJpegBitStreamDontSkip = (data == 0xFF) ? 1 : 0; + + sJpegBitStreamCurWord <<= 8; + sJpegBitStreamCurWord |= data; + sJpegBitStreamBitIdx -= 8; + } + + ret = (sJpegBitStreamCurWord << (sJpegBitStreamBitIdx)); + temp = ret; + ret = temp >> -len; + sJpegBitStreamBitIdx += len; + return ret; +} diff --git a/src/code/jpegutils.c b/src/code/jpegutils.c index ae23da852..52b8612dd 100644 --- a/src/code/jpegutils.c +++ b/src/code/jpegutils.c @@ -12,7 +12,7 @@ void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 c } } -s32 JpegUtils_ParseHuffmancodesLengths(u8* ptr, u8* codesLengths) { +s32 JpegUtils_ParseHuffmanCodesLengths(u8* ptr, u8* codesLengths) { u8 off = 1; s16 count = 0; s16 idx = 1; @@ -84,7 +84,7 @@ u32 JpegUtils_ProcessHuffmanTableImpl(u8* data, JpegHuffmanTable* ht, u8* codesL s32 count; s32 temp; - count = JpegUtils_ParseHuffmancodesLengths(data, codesLengths); + count = JpegUtils_ParseHuffmanCodesLengths(data, codesLengths); ret = count; if (count == 0 || (isAc && count > 0x100) || (!isAc && count > 0x10)) { return 0; @@ -139,7 +139,7 @@ u32 JpegUtils_ProcessHuffmanTableImplOld(u8* dht, JpegHuffmanTableOld* ht, u8* c isAc = *dht++ >> 4; - count2 = count = JpegUtils_ParseHuffmancodesLengths(dht, codesLengths); + count2 = count = JpegUtils_ParseHuffmanCodesLengths(dht, codesLengths); if (count == 0 || (isAc && count > 0x100) || (!isAc && count > 0x10)) { return 1; diff --git a/src/code/padmgr.c b/src/code/padmgr.c index 33da52e95..13266ab50 100644 --- a/src/code/padmgr.c +++ b/src/code/padmgr.c @@ -412,7 +412,7 @@ void PadMgr_Init(PadMgr* padmgr, OSMesgQueue* siIntMsgQ, IrqMgr* irqMgr, OSId id PadMgr_UnlockSerialMesgQueue(padmgr, siIntMsgQ); osCreateMesgQueue(&padmgr->lockMsgQ, padmgr->lockMsgBuf, 1); PadMgr_UnlockPadData(padmgr); - func_800FCD40(siIntMsgQ, &padmgr->validCtrlrsMask, padmgr); + PadSetup_Init(siIntMsgQ, &padmgr->validCtrlrsMask, padmgr->padStatus); padmgr->ncontrollers = 4; osContSetCh(padmgr->ncontrollers); diff --git a/src/code/padsetup.c b/src/code/padsetup.c new file mode 100644 index 000000000..045724a51 --- /dev/null +++ b/src/code/padsetup.c @@ -0,0 +1,33 @@ +#include <global.h> + +s32 PadSetup_Init(OSMesgQueue* mq, u8* outMask, OSContStatus* status) { + s32 ret; + s32 i; + + *outMask = 0xFF; + ret = osContInit(mq, outMask, status); + if (ret != 0) { + return ret; + } + if (*outMask == 0xFF) { + if (osContStartQuery(mq) != 0) { + return 1; + } + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + osContGetQuery(status); + + *outMask = 0; + for (i = 0; i < 4; i++) { + switch (status[i].errno) { + case 0: + if (status[i].type == CONT_TYPE_NORMAL) { + *outMask |= 1 << i; + } + break; + default: + break; + } + } + } + return 0; +} diff --git a/src/code/z_jpeg.c b/src/code/z_jpeg.c index 609d1412f..70cf1e70e 100644 --- a/src/code/z_jpeg.c +++ b/src/code/z_jpeg.c @@ -39,12 +39,12 @@ u32 Jpeg_SendTask(JpegContext* ctx) { JpegWork* workBuf = ctx->workBuf; u32 pad[2]; - workBuf->taskData.unk_00 = PHYSICAL_TO_VIRTUAL(&workBuf->unk_6C0); - workBuf->taskData.unk_08 = ctx->unk_28; - workBuf->taskData.unk_04 = 4; - workBuf->taskData.qTablePtrs[0] = PHYSICAL_TO_VIRTUAL(&workBuf->qTables[0]); - workBuf->taskData.qTablePtrs[1] = PHYSICAL_TO_VIRTUAL(&workBuf->qTables[1]); - workBuf->taskData.qTablePtrs[2] = PHYSICAL_TO_VIRTUAL(&workBuf->qTables[2]); + workBuf->taskData.address = PHYSICAL_TO_VIRTUAL(&workBuf->unk_6C0); + workBuf->taskData.mode = ctx->mode; + workBuf->taskData.mbCount = 4; + workBuf->taskData.qTableYPtr = PHYSICAL_TO_VIRTUAL(&workBuf->qTableY); + workBuf->taskData.qTableUPtr = PHYSICAL_TO_VIRTUAL(&workBuf->qTableU); + workBuf->taskData.qTableVPtr = PHYSICAL_TO_VIRTUAL(&workBuf->qTableV); sJpegTask.flags = 0; sJpegTask.ucode_boot = SysUcode_GetUCodeBoot(); @@ -97,7 +97,7 @@ u16 Jpeg_GetU16(u8* ptr) { if (((u32)ptr & 1) == 0) { // if the address is aligned to 2 return *(u16*)ptr; } else { - return *(u16*)(ptr - 1) << 8 | (*(u16*)(ptr + 1) >> 8); // ?? it's exactly like *(16*)ptr + return *(u16*)(ptr - 1) << 8 | (*(u16*)(ptr + 1) >> 8); // lhu crashes with unaligned addresses } } @@ -174,10 +174,10 @@ void Jpeg_ParseMarkers(u8* ptr, JpegContext* ctx) { if (ptr[9] == 0x21) // component Y : V0 == 1 { - ctx->unk_28 = 0; + ctx->mode = 0; } else if (ptr[9] == 0x22) // component Y : V0 == 2 { - ctx->unk_28 = 2; + ctx->mode = 2; } ptr += Jpeg_GetU16(ptr); break; @@ -215,7 +215,7 @@ s32 Jpeg_Decode(void* data, u16* zbuffer, JpegWork* workBuff, u32 workSize) { JpegContext ctx; // 0x208 JpegHuffmanTable hTables[4]; // 0xB8 JpegDecoder decoder; // 0x9C - u32 unk[5]; // 0x88 + JpegDecoderState state; // 0x88 u16(*src)[0x180]; OSTime diff; // 0x78 OSTime time; // 0x70 @@ -248,19 +248,19 @@ s32 Jpeg_Decode(void* data, u16* zbuffer, JpegWork* workBuff, u32 workSize) { switch (ctx.dqtCount) { case 1: { - JpegUtils_ProcessQuantizationTable(ctx.dqtPtr[0], &workBuff->qTables[0], 3); + JpegUtils_ProcessQuantizationTable(ctx.dqtPtr[0], &workBuff->qTableY, 3); break; } case 2: { - JpegUtils_ProcessQuantizationTable(ctx.dqtPtr[0], &workBuff->qTables[0], 1); - JpegUtils_ProcessQuantizationTable(ctx.dqtPtr[1], &workBuff->qTables[1], 1); - JpegUtils_ProcessQuantizationTable(ctx.dqtPtr[1], &workBuff->qTables[2], 1); + JpegUtils_ProcessQuantizationTable(ctx.dqtPtr[0], &workBuff->qTableY, 1); + JpegUtils_ProcessQuantizationTable(ctx.dqtPtr[1], &workBuff->qTableU, 1); + JpegUtils_ProcessQuantizationTable(ctx.dqtPtr[1], &workBuff->qTableV, 1); break; } case 3: { - JpegUtils_ProcessQuantizationTable(ctx.dqtPtr[0], &workBuff->qTables[0], 1); - JpegUtils_ProcessQuantizationTable(ctx.dqtPtr[1], &workBuff->qTables[1], 1); - JpegUtils_ProcessQuantizationTable(ctx.dqtPtr[2], &workBuff->qTables[2], 1); + JpegUtils_ProcessQuantizationTable(ctx.dqtPtr[0], &workBuff->qTableY, 1); + JpegUtils_ProcessQuantizationTable(ctx.dqtPtr[1], &workBuff->qTableU, 1); + JpegUtils_ProcessQuantizationTable(ctx.dqtPtr[2], &workBuff->qTableV, 1); break; } default: @@ -318,12 +318,12 @@ s32 Jpeg_Decode(void* data, u16* zbuffer, JpegWork* workBuff, u32 workSize) { if (1) {} decoder.unk_18 = 0; decoder.imageData = ctx.imageData; - decoder.unk_04 = ctx.unk_28; + decoder.mode = ctx.mode; y = 0; x = 0; for (i = 0; i < 300; i += 4) { - if (func_800FFA50(&decoder, &workBuff->unk_6C0, 4, i != 0, unk)) { + if (JpegDecoder_Decode(&decoder, &workBuff->unk_6C0, 4, i != 0, &state)) { osSyncPrintf(VT_FGCOL(RED)); osSyncPrintf("Error : Can't decode jpeg\n"); osSyncPrintf(VT_RST); |
