1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-07-06 16:04:35 +00:00

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
This commit is contained in:
Random 2020-06-22 00:43:14 +02:00 committed by GitHub
parent afce6a3c36
commit ab1ec89f22
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 389 additions and 653 deletions

13
src/code/code_800C3C20.c Normal file
View file

@ -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]);
}
}

201
src/code/jpegdecoder.c Normal file
View file

@ -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;
}

View file

@ -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;

View file

@ -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);

33
src/code/padsetup.c Normal file
View file

@ -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;
}

View file

@ -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);