diff options
| author | Random <28494085+Random06457@users.noreply.github.com> | 2020-04-14 01:03:10 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-13 19:03:10 -0400 |
| commit | 298abfb1280134a4def3dc30fab1530edcb64bb8 (patch) | |
| tree | 96441fd1e1a263ebfd91c23343d6296c4fd96ead /src/code | |
| parent | f3c945cc8227ae308b0e8dba25703b7c5ee99832 (diff) | |
Decompile z_jpeg.c (#70)
* Decompile z_jpeg.c
- Decompile z_jpeg.c
- Move .bss variables from fault.c and fault_drawer.c into .s files to avoid bss reordering
* Rename JPEGWork to JpegWork and minor fix in Jpeg_GetU16
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/fault.c | 14 | ||||
| -rw-r--r-- | src/code/fault_drawer.c | 4 | ||||
| -rw-r--r-- | src/code/graph.c | 16 | ||||
| -rw-r--r-- | src/code/sys_ucode.c | 6 | ||||
| -rw-r--r-- | src/code/z_jpeg.c | 352 | ||||
| -rw-r--r-- | src/code/z_room.c | 10 |
6 files changed, 375 insertions, 27 deletions
diff --git a/src/code/fault.c b/src/code/fault.c index 92f252647..b3270ea7c 100644 --- a/src/code/fault.c +++ b/src/code/fault.c @@ -33,11 +33,11 @@ const char* sExceptionNames[] = { }; // bss -FaultThreadStruct* sFaultStructPtr; -u8 sFaultIsWaitingForInput; -char sFaultStack[0x600]; -char sFaultThreadInfo[0x20]; -FaultThreadStruct gFaultStruct; +extern FaultThreadStruct* sFaultStructPtr; +extern u8 sFaultIsWaitingForInput; +extern char sFaultStack[0x600]; +extern StackEntry sFaultThreadInfo; +extern FaultThreadStruct gFaultStruct; #pragma GLOBAL_ASM("asm/non_matchings/code/fault/pad_800D3F10.s") @@ -804,8 +804,8 @@ void Fault_Start(void) { sFaultStructPtr->faultActive = false; gFaultStruct.faultHandlerEnabled = true; osCreateMesgQueue(&sFaultStructPtr->queue, &sFaultStructPtr->msg, 1); - StackCheck_Init(sFaultThreadInfo, &sFaultStack, sFaultStack + sizeof(sFaultStack), 0, 0x100, "fault"); - osCreateThread(&sFaultStructPtr->thread, 2, &Fault_ThreadEntry, 0, sFaultThreadInfo, 0x7f); + StackCheck_Init(&sFaultThreadInfo, &sFaultStack, sFaultStack + sizeof(sFaultStack), 0, 0x100, "fault"); + osCreateThread(&sFaultStructPtr->thread, 2, &Fault_ThreadEntry, 0, sFaultStack + sizeof(sFaultStack), 0x7f); osStartThread(&sFaultStructPtr->thread); } diff --git a/src/code/fault_drawer.c b/src/code/fault_drawer.c index ef7a784ae..60fc9b2f6 100644 --- a/src/code/fault_drawer.c +++ b/src/code/fault_drawer.c @@ -58,8 +58,8 @@ FaultDrawer sFaultDrawerDefault = { // clang-format on // bss -FaultDrawer sFaultDrawerStruct; -char D_8016B6C0[0x20]; //? unused +extern FaultDrawer sFaultDrawerStruct; +extern char D_8016B6C0[0x20]; // ? unused void FaultDrawer_SetOsSyncPrintfEnabled(u32 enabled) { sFaultDrawerStruct.osSyncPrintfEnabled = enabled; diff --git a/src/code/graph.c b/src/code/graph.c index cd7f5fe2b..5e1d2563d 100644 --- a/src/code/graph.c +++ b/src/code/graph.c @@ -13,13 +13,19 @@ FaultClient sGraphFaultClient; CfbInfo sGraphCfbInfos[3]; FaultClient sGraphUcodeFaultClient; +// clang-format off UCodeInfo D_8012D230[3] = { - { 1, D_80155F50 }, { 2, NULL }, { 3, D_801120C0 + 0xFB0 }, // D_80113070 + { 1, D_80155F50 }, + { 2, NULL }, + { 3, D_80113070 }, }; UCodeInfo D_8012D248[3] = { - { 1, D_80155F50 }, { 2, NULL }, { 3, D_801120C0 + 0xFB0 }, // D_80113070 + { 1, D_80155F50 }, + { 2, NULL }, + { 3, D_80113070 }, }; +// clang-format on void Graph_FaultClient() { void* nextFb; @@ -208,9 +214,9 @@ void Graph_TaskSet00(GraphicsContext* gfxCtx) { task->type = M_GFXTASK; task->flags = OS_SC_DRAM_DLIST; task->ucode_boot = SysUcode_GetUCodeBoot(); - task->ucode_boot_size = SysUcode_GetUcodeBootSize(); - task->ucode = SysUcode_GetUcode(); - task->ucode_data = SysUcode_GetUcodeData(); + task->ucode_boot_size = SysUcode_GetUCodeBootSize(); + task->ucode = SysUcode_GetUCode(); + task->ucode_data = SysUcode_GetUCodeData(); task->ucode_size = 0x1000; task->ucode_data_size = 0x800; task->dram_stack = gGfxSPTaskStack; diff --git a/src/code/sys_ucode.c b/src/code/sys_ucode.c index f23c7239a..e34fd1307 100644 --- a/src/code/sys_ucode.c +++ b/src/code/sys_ucode.c @@ -4,14 +4,14 @@ u32 SysUcode_GetUCodeBoot() { return &D_80009320; } -u32 SysUcode_GetUcodeBootSize() { +u32 SysUcode_GetUCodeBootSize() { return (u32)&D_800093F0 - (u32)&D_80009320; } -u32 SysUcode_GetUcode() { +u32 SysUcode_GetUCode() { return D_8012DBA0; } -u32 SysUcode_GetUcodeData() { +u32 SysUcode_GetUCodeData() { return D_8012DBA4; } diff --git a/src/code/z_jpeg.c b/src/code/z_jpeg.c index 5031ad823..2cbd3191b 100644 --- a/src/code/z_jpeg.c +++ b/src/code/z_jpeg.c @@ -1,12 +1,354 @@ #include <ultra64.h> #include <global.h> +#include <sched.h> +#include <vt.h> -#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/func_8006DE30.s") +#define MARKER_SOI 0xD8 +#define MARKER_SOF 0xC0 +#define MARKER_DHT 0xC4 +#define MARKER_DQT 0xDB +#define MARKER_DRI 0xDD +#define MARKER_SOS 0xDA +#define MARKER_APP0 0xE0 +#define MARKER_APP1 0xE1 +#define MARKER_APP2 0xE2 +#define MARKER_COM 0xFE +#define MARKER_EOI 0xD9 -#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/func_8006DF68.s") +u32 Jpeg_SendTask(JpegContext* ctx) { + // clang-format off + static OSTask_t sJpegTask = { + M_NJPEGTASK, // type + 0, //flags + NULL, // ucode_boot + 0, // ucode_boot_size + D_80114930, // ucode + 0x1000, // ucode_size + D_80157D30, // ucode_data + 0x800, // ucode_data_size + NULL, // dram_stack + 0, // dram_stack_size + NULL, // output_buff + 0, // output_buff_size + NULL, // data_ptr + sizeof(JpegTaskData), // data_size + NULL, // yield_data_ptr + 0x200, // yield_data_size + }; + // clang-format on -#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/func_8006E0A0.s") + JpegWork* workBuf = ctx->workBuf; + u32 pad[2]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/func_8006E0EC.s") + 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]); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/func_8006E418.s") + sJpegTask.flags = 0; + sJpegTask.ucode_boot = SysUcode_GetUCodeBoot(); + sJpegTask.ucode_boot_size = SysUcode_GetUCodeBootSize(); + sJpegTask.yield_data_ptr = &workBuf->yieldData; + sJpegTask.data_ptr = &workBuf->taskData; + + ctx->scTask.next = NULL; + ctx->scTask.flags = OS_SC_NEEDS_RSP; + ctx->scTask.msgQ = &ctx->mq; + ctx->scTask.msg = NULL; + ctx->scTask.framebuffer = NULL; + ctx->scTask.list.t = sJpegTask; + + osSendMesg(&gSchedContext.cmdQ, (OSMesg)&ctx->scTask, OS_MESG_BLOCK); + func_800C95F8(&gSchedContext); // osScKickEntryMsg + osRecvMesg(&ctx->mq, NULL, OS_MESG_BLOCK); +} + +void Jpeg_CopyToZbuffer(u16* src, u16* zbuffer, s32 x, s32 y) { + u16* dst; + s32 i; + + dst = zbuffer + (((y * SCREEN_WIDTH) + x) * 16); + + for (i = 0; i < 16; i++) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; + dst[4] = src[4]; + dst[5] = src[5]; + dst[6] = src[6]; + dst[7] = src[7]; + dst[8] = src[8]; + dst[9] = src[9]; + dst[10] = src[10]; + dst[11] = src[11]; + dst[12] = src[12]; + dst[13] = src[13]; + dst[14] = src[14]; + dst[15] = src[15]; + + src += 16; + dst += SCREEN_WIDTH; + } +} + +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 + } +} + +void Jpeg_ParseMarkers(u8* ptr, JpegContext* ctx) { + u32 exit; + + exit = false; + ctx->dqtCount = 0; + ctx->dhtCount = 0; + + while (true) { + if (exit) { + break; + } + + if (*ptr++ == 0xFF) { + switch (*ptr++) { + case 0: + break; + case MARKER_SOI: { + osSyncPrintf("MARKER_SOI\n"); + break; + } + case MARKER_APP0: { + osSyncPrintf("MARKER_APP0 %d\n", Jpeg_GetU16(ptr)); + ptr += Jpeg_GetU16(ptr); + break; + } + case MARKER_APP1: { + osSyncPrintf("MARKER_APP1 %d\n", Jpeg_GetU16(ptr)); + ptr += Jpeg_GetU16(ptr); + break; + } + case MARKER_APP2: { + osSyncPrintf("MARKER_APP2 %d\n", Jpeg_GetU16(ptr)); + ptr += Jpeg_GetU16(ptr); + break; + } + case MARKER_DQT: { + osSyncPrintf("MARKER_DQT %d %d %02x\n", ctx->dqtCount, Jpeg_GetU16(ptr), ptr[2]); + ctx->dqtPtr[ctx->dqtCount++] = ptr + 2; + ptr += Jpeg_GetU16(ptr); + break; + } + case MARKER_DHT: { + osSyncPrintf("MARKER_DHT %d %d %02x\n", ctx->dhtCount, Jpeg_GetU16(ptr), ptr[2]); + ctx->dhtPtr[ctx->dhtCount++] = ptr + 2; + ptr += Jpeg_GetU16(ptr); + break; + } + case MARKER_DRI: { + osSyncPrintf("MARKER_DRI %d\n", Jpeg_GetU16(ptr)); + ptr += Jpeg_GetU16(ptr); + break; + } + case MARKER_SOF: { + osSyncPrintf("MARKER_SOF %d " + "精度%02x " // accuracy + "垂直%d " // vertical + "水平%d " // horizontal + "compo%02x " + "(1:Y)%d (H0=2,V0=1(422) or 2(420))%02x (量子化テーブル)%02x " + "(2:Cb)%d (H1=1,V1=1)%02x (量子化テーブル)%02x " + "(3:Cr)%d (H2=1,V2=1)%02x (量子化テーブル)%02x\n", + Jpeg_GetU16(ptr), + ptr[2], // precision + Jpeg_GetU16(ptr + 3), // height + Jpeg_GetU16(ptr + 5), // width + ptr[7], // component count + ptr[8], ptr[9], ptr[10], // Y + ptr[11], ptr[12], ptr[13], // Cb + ptr[14], ptr[15], ptr[16] // Cr + ); + + if (ptr[9] == 0x21) // component Y : V0 == 1 + { + ctx->unk_28 = 0; + } else if (ptr[9] == 0x22) // component Y : V0 == 2 + { + ctx->unk_28 = 2; + } + ptr += Jpeg_GetU16(ptr); + break; + } + case MARKER_SOS: { + osSyncPrintf("MARKER_SOS %d\n", Jpeg_GetU16(ptr)); + ptr += Jpeg_GetU16(ptr); + ctx->imageData = ptr; + break; + } + case MARKER_EOI: { + osSyncPrintf("MARKER_EOI\n"); + exit = true; + break; + } + default: { + // Unknown marker + osSyncPrintf("マーカー不明 %02x\n", ptr[-1]); + ptr += Jpeg_GetU16(ptr); + break; + } + } + } + } +} + +// the time diff isn't correct, workBuff->unk_6C0 is kept in a temp register instead of being stored in the stack and +// regalloc differences +#ifdef NON_MATCHING +s32 Jpeg_Decode(void* data, u16* zbuffer, JpegWork* workBuff, u32 workSize) { + s32 y; + s32 x; + u32 j; + u32 i; + JpegContext ctx; // 0x208 + JpegHuffmanTable hTables[4]; // 0xB8 + JpegDecoder decoder; // 0x9C + u32 unk[5]; // 0x88 + u16(*src)[0x180]; + OSTime diff; // 0x78 + OSTime time; // 0x70 + OSTime time2; + + time = osGetTime(); + if (workSize < + sizeof(JpegWork)) { // (?) I guess MB_SIZE=0x180, PROC_OF_MBS=5 which means unk_6C0 is not a part of JpegWork + __assert("worksize >= sizeof(JPEGWork) + MB_SIZE * (PROC_OF_MBS - 1)", "../z_jpeg.c", 527); + } + + osCreateMesgQueue(&ctx.mq, &ctx.msg, 1); + MsgEvent_SendNullTask(); + + time2 = osGetTime(); + diff = time2 - time; + if (1) {} + // Wait for synchronization of fifo buffer + osSyncPrintf("*** fifoバッファの同期待ち time = %6.3f ms ***\n", (f64)(OS_CYCLES_TO_USEC(diff) / 1000.0f)); + + ctx.workBuf = workBuff; + Jpeg_ParseMarkers(data, &ctx); + + time = osGetTime(); + diff = time - time2; + if (1) {} + // Check markers for each segment + osSyncPrintf("*** 各セグメントのマーカーのチェック time = %6.3f ms ***\n", + (f64)(OS_CYCLES_TO_USEC(diff) / 1000.0f)); + + switch (ctx.dqtCount) { + case 1: { + func_800FF540(ctx.dqtPtr[0], &workBuff->qTables[0], 3); + break; + } + case 2: { + func_800FF540(ctx.dqtPtr[0], &workBuff->qTables[0], 1); + func_800FF540(ctx.dqtPtr[1], &workBuff->qTables[1], 1); + func_800FF540(ctx.dqtPtr[1], &workBuff->qTables[2], 1); + break; + } + case 3: { + func_800FF540(ctx.dqtPtr[0], &workBuff->qTables[0], 1); + func_800FF540(ctx.dqtPtr[1], &workBuff->qTables[1], 1); + func_800FF540(ctx.dqtPtr[2], &workBuff->qTables[2], 1); + break; + } + default: + return -1; + } + + time2 = osGetTime(); + diff = time2 - time; + if (1) {} + // Create quantization table + osSyncPrintf("*** 量子化テーブル作成 time = %6.3f ms ***\n", (f64)(OS_CYCLES_TO_USEC(diff) / 1000.0f)); + + switch (ctx.dhtCount) { + case 1: { + if (func_800FF7FC(ctx.dhtPtr[0], &hTables[0], &workBuff->codesLenghts, &workBuff->codes, 4)) { + osSyncPrintf("Error : Cant' make huffman table.\n"); + } + break; + } + case 4: { + if (func_800FF7FC(ctx.dhtPtr[0], &hTables[0], &workBuff->codesLenghts, &workBuff->codes, 1)) { + osSyncPrintf("Error : Cant' make huffman table.\n"); + } + if (func_800FF7FC(ctx.dhtPtr[1], &hTables[1], &workBuff->codesLenghts, &workBuff->codes, 1)) { + osSyncPrintf("Error : Cant' make huffman table.\n"); + } + if (func_800FF7FC(ctx.dhtPtr[2], &hTables[2], &workBuff->codesLenghts, &workBuff->codes, 1)) { + osSyncPrintf("Error : Cant' make huffman table.\n"); + } + if (func_800FF7FC(ctx.dhtPtr[3], &hTables[3], &workBuff->codesLenghts, &workBuff->codes, 1)) { + osSyncPrintf("Error : Cant' make huffman table.\n"); + } + break; + } + default: + return -1; + } + + time = osGetTime(); + diff = time - time2; + if (1) {} + // Huffman table creation + osSyncPrintf("*** ハフマンテーブル作成 time = %6.3f ms ***\n", (f64)(OS_CYCLES_TO_USEC(diff) / 1000.0f)); + + decoder.unk_05 = 2; + decoder.hTablePtrs[0] = &hTables[0]; + decoder.hTablePtrs[1] = &hTables[1]; + decoder.hTablePtrs[2] = &hTables[2]; + decoder.hTablePtrs[3] = &hTables[3]; + if (1) {} + decoder.unk_18 = 0; + decoder.imageData = ctx.imageData; + decoder.unk_04 = ctx.unk_28; + + y = 0; + x = 0; + for (i = 0; i < 300; i += 4) { + if (func_800FFA50(&decoder, &workBuff->unk_6C0, 4, i != 0, unk)) { + osSyncPrintf(VT_FGCOL(RED)); + osSyncPrintf("Error : Can't decode jpeg\n"); + osSyncPrintf(VT_RST); + } else { + Jpeg_SendTask(&ctx); + osInvalDCache(&workBuff->unk_6C0, sizeof(workBuff->unk_6C0[0])); + + src = &workBuff->unk_6C0; + for (j = 0; j < ARRAY_COUNT(workBuff->unk_6C0); j++) { + Jpeg_CopyToZbuffer(&src[j], zbuffer, x, y); + x++; + + if (x >= 20) { + x = 0; + y++; + } + } + } + } + + time2 = osGetTime(); + diff = time2 - time; + if (1) {} + // Unfold & draw + osSyncPrintf("*** 展開 & 描画 time = %6.3f ms ***\n", (f64)(OS_CYCLES_TO_USEC(diff) / 1000.0f)); + + return 0; +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/Jpeg_Decode.s") +#endif diff --git a/src/code/z_room.c b/src/code/z_room.c index dd181d606..442dee0ac 100644 --- a/src/code/z_room.c +++ b/src/code/z_room.c @@ -242,7 +242,7 @@ s32 func_80096238(void* data) { osSyncPrintf("ワークバッファアドレス(Zバッファ)%08x\n", gZBuffer); time = osGetTime(); - if (!func_8006E418(data, gZBuffer, gGfxSPTaskOutputBuffer, sizeof(gGfxSPTaskOutputBuffer))) { + if (!Jpeg_Decode(data, gZBuffer, gGfxSPTaskOutputBuffer, sizeof(gGfxSPTaskOutputBuffer))) { time = osGetTime() - time; // Translates to: "SUCCESS... I THINK. time = %6.3f ms" @@ -375,8 +375,8 @@ void func_80096680(GlobalContext* globalCtx, Room* room, u32 flags) { gfxCtx->polyOpa.p = spA8; } - // gSPLoadUcode(gfxCtx->polyOpa.p++, SysUcode_GetUcode(), SysUcode_GetUcodeData())? - gSPLoadUcodeEx(gfxCtx->polyOpa.p++, SysUcode_GetUcode(), SysUcode_GetUcodeData(), 0x800); + // gSPLoadUcode(gfxCtx->polyOpa.p++, SysUcode_GetUCode(), SysUcode_GetUCodeData())? + gSPLoadUcodeEx(gfxCtx->polyOpa.p++, SysUcode_GetUCode(), SysUcode_GetUCodeData(), 0x800); } } @@ -481,8 +481,8 @@ void func_80096B6C(GlobalContext* globalCtx, Room* room, u32 flags) { gfxCtx->polyOpa.p = spA8; } - // gSPLoadUcode(gfxCtx->polyOpa.p++, SysUcode_GetUcode(), SysUcode_GetUcodeData())? - gSPLoadUcodeEx(gfxCtx->polyOpa.p++, SysUcode_GetUcode(), SysUcode_GetUcodeData(), 0x800); + // gSPLoadUcode(gfxCtx->polyOpa.p++, SysUcode_GetUCode(), SysUcode_GetUCodeData())? + gSPLoadUcodeEx(gfxCtx->polyOpa.p++, SysUcode_GetUCode(), SysUcode_GetUCodeData(), 0x800); } } |
