diff options
| author | engineer124 <engineer124engineer124@gmail.com> | 2021-11-20 09:35:46 +1100 |
|---|---|---|
| committer | engineer124 <engineer124engineer124@gmail.com> | 2021-11-20 09:35:46 +1100 |
| commit | f0c676d12422acac4844c4e6ed21abe511ae45a1 (patch) | |
| tree | 3ac70ad2404767670c8f8ba7c10d9095cc6a9db1 /src/code | |
| parent | 65cbbf40fdb5ce2f50057334dda7e353920dffa1 (diff) | |
| parent | dfdbd66106ba77c21ccfaa91e9b0c52d4364121b (diff) | |
Merge branch 'audio_bgm' into voice
Diffstat (limited to 'src/code')
| -rw-r--r-- | src/code/audio/code_8019AF00.c | 2 | ||||
| -rw-r--r-- | src/code/code_8010C1B0.c | 2 | ||||
| -rw-r--r-- | src/code/code_801AA020.c | 9 | ||||
| -rw-r--r-- | src/code/jpegdecoder.c | 193 | ||||
| -rw-r--r-- | src/code/jpegutils.c | 156 | ||||
| -rw-r--r-- | src/code/z_common_data.c | 4 | ||||
| -rw-r--r-- | src/code/z_game_over.c | 4 | ||||
| -rw-r--r-- | src/code/z_jpeg.c | 305 | ||||
| -rw-r--r-- | src/code/z_scene.c | 2 |
9 files changed, 646 insertions, 31 deletions
diff --git a/src/code/audio/code_8019AF00.c b/src/code/audio/code_8019AF00.c index 227384d0a..9354af188 100644 --- a/src/code/audio/code_8019AF00.c +++ b/src/code/audio/code_8019AF00.c @@ -296,7 +296,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2D54.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2DE0.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/Audio_IsSequencePlaying.s") #pragma GLOBAL_ASM("asm/non_matchings/code/code_8019AF00/func_801A2E54.s") diff --git a/src/code/code_8010C1B0.c b/src/code/code_8010C1B0.c index 12e0eadb4..2c1fd410f 100644 --- a/src/code/code_8010C1B0.c +++ b/src/code/code_8010C1B0.c @@ -1,7 +1,7 @@ #include "global.h" // Blocks the current thread until all currently queued scheduler tasks have been completed -void func_8010C1B0(void) { +void MsgEvent_SendNullTask(void) { OSScTask task; OSMesgQueue queue; OSMesg msg; diff --git a/src/code/code_801AA020.c b/src/code/code_801AA020.c deleted file mode 100644 index 6cefc66d9..000000000 --- a/src/code/code_801AA020.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801AA020/func_801AA020.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801AA020/func_801AA248.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801AA020/func_801AA3E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_801AA020/func_801AA520.s") diff --git a/src/code/jpegdecoder.c b/src/code/jpegdecoder.c new file mode 100644 index 000000000..336e381f9 --- /dev/null +++ b/src/code/jpegdecoder.c @@ -0,0 +1,193 @@ +#include "z64jpeg.h" +#include "libc/stdbool.h" +#include "macros.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; + u16 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, u16* mcu, s16* unk) { + s8 i = 0; + s8 zeroCount; + s16 coeff; + + if (JpegDecoder_ParseNextSymbol(hTable0, &coeff, &zeroCount)) { + return true; + } + + *unk += coeff; + mcu[i++] = *unk; + while (i < 8 * 8) { + if (JpegDecoder_ParseNextSymbol(hTable1, &coeff, &zeroCount)) { + return true; + } + + 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 false; +} + +s32 JpegDecoder_ParseNextSymbol(JpegHuffmanTable* hTable, s16* outCoeff, s8* outZeroCount) { + u8 codeIdx; + u8 sym; + u16 codeOff = 0; + u16 buff = JpegDecoder_ReadBits(16); + + for (codeIdx = 0; codeIdx < ARRAY_COUNT(hTable->codesB); codeIdx++) { + if (hTable->codesB[codeIdx] == 0xFFFF) { + continue; + } + + codeOff = buff >> (15 - codeIdx); + if (codeOff <= hTable->codesB[codeIdx]) { + break; + } + } + + if (codeIdx >= ARRAY_COUNT(hTable->codesB)) { + return true; + } + + sym = hTable->symbols[hTable->codeOffs[codeIdx] + codeOff - hTable->codesA[codeIdx]]; + *outZeroCount = sym >> 4; + sym &= 0xF; + + sJpegBitStreamBitIdx += codeIdx - 15; + *outCoeff = 0; + if (sym) { + *outCoeff = JpegDecoder_ReadBits(sym); + if (*outCoeff < (1 << (sym - 1))) { + *outCoeff += (-1 << sym) + 1; + } + } + + return false; +} + +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) ? true : false; + + 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 89ed4e97d..904643f46 100644 --- a/src/code/jpegutils.c +++ b/src/code/jpegutils.c @@ -1,17 +1,155 @@ -#include "global.h" +#include "z64jpeg.h" +#include "libc/stdbool.h" +#include "macros.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/jpegutils/func_801A9B10.s") +void JpegUtils_ProcessQuantizationTable(u8* dqt, JpegQuantizationTable* qt, u8 count) { + u8 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/jpegutils/func_801A9B78.s") + for (i = 0; i < count; i++) { + u8 j; -#pragma GLOBAL_ASM("asm/non_matchings/code/jpegutils/func_801A9BFC.s") + dqt++; + for (j = 0; j < ARRAY_COUNT(qt[i].table); j++) { + qt[i].table[j] = *dqt++; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/jpegutils/func_801A9C68.s") +s32 JpegUtils_ParseHuffmanCodesLengths(u8* ptr, u8* codesLengths) { + u8 off = 1; + s16 count = 0; + s16 idx = 1; -#pragma GLOBAL_ASM("asm/non_matchings/code/jpegutils/func_801A9D10.s") + while (off <= 16) { + while (idx <= ptr[off - 1]) { + codesLengths[count++] = off; + idx++; + } + idx = 1; + off++; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/jpegutils/func_801A9DCC.s") + codesLengths[count] = 0; + return count; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/jpegutils/func_801A9EA4.s") +s32 JpegUtils_GetHuffmanCodes(u8* codesLengths, u16* codes) { + s16 idx = 0; + u16 code = 0; + u8 lastLen = codesLengths[0]; -#pragma GLOBAL_ASM("asm/non_matchings/code/jpegutils/func_801A9F4C.s") + while (true) { + while (true) { + codes[idx++] = code++; + + if (codesLengths[idx] != lastLen) { + break; + } + } + + if (codesLengths[idx] == 0) { + break; + } + + while (true) { + if (code <<= 1, codesLengths[idx] == ++lastLen) { + break; + } + } + } + + return idx; +} + +s32 JpegUtils_SetHuffmanTable(u8* data, JpegHuffmanTable* ht, u16* codes) { + u8 idx; + u16 codeOff = 0; + + for (idx = 0; idx < 16; idx++) { + if (data[idx]) { + ht->codeOffs[idx] = codeOff; + ht->codesA[idx] = codes[codeOff]; + codeOff += data[idx] - 1; + ht->codesB[idx] = codes[codeOff]; + codeOff++; + } else { + ht->codesB[idx] = 0xFFFF; + } + } + + return codeOff; +} + +u32 JpegUtils_ProcessHuffmanTableImpl(u8* data, JpegHuffmanTable* ht, u8* codesLengths, u16* codes, u8 isAc) { + s16 ret; + s32 count = JpegUtils_ParseHuffmanCodesLengths(data, codesLengths); + s32 temp; + + ret = count; + if (count == 0 || (isAc && count > 0x100) || (!isAc && count > 0x10)) { + return 0; + } + if (ret != JpegUtils_GetHuffmanCodes(codesLengths, codes)) { + return 0; + } + if (temp = JpegUtils_SetHuffmanTable(data, ht, codes), temp != ret) { + return 0; + } + + return ret; +} + +u32 JpegUtils_ProcessHuffmanTable(u8* dht, JpegHuffmanTable* ht, u8* codesLengths, u16* codes, u8 count) { + u8 idx; + u32 codeCount; + + for (idx = 0; idx < count; idx++) { + u32 ac = (*dht++ >> 4); + + codeCount = JpegUtils_ProcessHuffmanTableImpl(dht, &ht[idx], codesLengths, codes, ac); + if (codeCount == 0) { + return true; + } + + dht += 16; + ht[idx].symbols = dht; + dht += codeCount; + } + return false; +} + +void JpegUtils_SetHuffmanTableOld(u8* data, JpegHuffmanTableOld* ht, u8* codesLengths, u16* codes, s16 count, u8 isAc) { + s16 idx; + u8 a; + + for (idx = 0; idx < count; idx++) { + a = data[idx]; + if (isAc) { + ht->acCodes[a] = codes[idx]; + ht->codeOffs[a] = codesLengths[idx]; + } else { + ht->dcCodes[a] = codes[idx]; + ht->codeOffs[a] = codesLengths[idx]; + } + } +} + +u32 JpegUtils_ProcessHuffmanTableImplOld(u8* dht, JpegHuffmanTableOld* ht, u8* codesLengths, u16* codes) { + u8 isAc = *dht++ >> 4; + s16 count2; + s32 count; + + count2 = count = JpegUtils_ParseHuffmanCodesLengths(dht, codesLengths); + + if (count == 0 || (isAc && count > 0x100) || (!isAc && count > 0x10)) { + return true; + } + + if (JpegUtils_GetHuffmanCodes(codesLengths, codes) != count2) { + return true; + } + + JpegUtils_SetHuffmanTableOld(dht + 0x10, ht, codesLengths, codes, count2, isAc); + + return false; +} diff --git a/src/code/z_common_data.c b/src/code/z_common_data.c index 88fa3e103..26fd324a7 100644 --- a/src/code/z_common_data.c +++ b/src/code/z_common_data.c @@ -5,9 +5,9 @@ SaveContext gSaveContext; void SaveContext_Init(void) { bzero(&gSaveContext, sizeof(gSaveContext)); gSaveContext.playerForm = 0; - gSaveContext.seqIndex = 0xFF; + gSaveContext.seqIndex = (u8)NA_BGM_DISABLED; gSaveContext.nightSeqIndex = 0xFF; - gSaveContext.unk_3F46 = 0; + gSaveContext.unk_3F46 = NA_BGM_GENERAL_SFX; gSaveContext.nextCutsceneIndex = 0xFFEF; gSaveContext.cutsceneTrigger = 0; gSaveContext.unk_3F4D = 0; diff --git a/src/code/z_game_over.c b/src/code/z_game_over.c index c510c1974..979b28cba 100644 --- a/src/code/z_game_over.c +++ b/src/code/z_game_over.c @@ -45,7 +45,7 @@ void GameOver_Update(GlobalContext* globalCtx) { gSaveContext.unk_3DC0 = 2000; gSaveContext.naviTimer = 0; - gSaveContext.seqIndex = 0xFF; + gSaveContext.seqIndex = (u8)NA_BGM_DISABLED; gSaveContext.nightSeqIndex = 0xFF; gSaveContext.eventInf[0] = 0; gSaveContext.eventInf[1] = 0; @@ -66,7 +66,7 @@ void GameOver_Update(GlobalContext* globalCtx) { gameOverCtx->state = GAMEOVER_DEATH_WAIT_GROUND; break; case GAMEOVER_DEATH_FADE_OUT: - if (func_801A8A50(1) != 32) { + if (func_801A8A50(1) != NA_BGM_GAME_OVER) { func_80169F78(globalCtx); if (gSaveContext.respawnFlag != -7) { gSaveContext.respawnFlag = -6; diff --git a/src/code/z_jpeg.c b/src/code/z_jpeg.c index 395a45835..c611ab1f8 100644 --- a/src/code/z_jpeg.c +++ b/src/code/z_jpeg.c @@ -1,11 +1,304 @@ -#include "global.h" +#include "z64jpeg.h" +#include "libc/stdbool.h" +#include "variables.h" +#include "functions.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/func_800F42A0.s") +#define MARKER_ESCAPE 0x00 +#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_800F43BC.s") +/** + * Configures and schedules a JPEG decoder task and waits for it to finish. + */ +void Jpeg_ScheduleDecoderTask(JpegContext* jpegCtx) { + static OSTask_t sJpegTask = { + M_NJPEGTASK, // type + 0, // flags + NULL, // ucode_boot + 0, // ucode_boot_size + gJpegUCode, // ucode + 0x1000, // ucode_size + gJpegUCodeData, // ucode_data + 0x800, // ucode_data_size + NULL, // dram_stack + 0, // dram_stack_size + NULL, // output_buff + NULL, // output_buff_size + NULL, // data_ptr + sizeof(JpegTaskData), // data_size + NULL, // yield_data_ptr + 0x200, // yield_data_size + }; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/func_800F44F4.s") + JpegWork* workBuf = jpegCtx->workBuf; + s32 pad[2]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/func_800F4540.s") + workBuf->taskData.address = &workBuf->data; + workBuf->taskData.mode = jpegCtx->mode; + workBuf->taskData.mbCount = 4; + workBuf->taskData.qTableYPtr = &workBuf->qTableY; + workBuf->taskData.qTableUPtr = &workBuf->qTableU; + workBuf->taskData.qTableVPtr = &workBuf->qTableV; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_jpeg/func_800F470C.s") + sJpegTask.flags = 0; + sJpegTask.ucodeBoot = SysUcode_GetUCodeBoot(); + sJpegTask.ucodeBootSize = SysUcode_GetUCodeBootSize(); + sJpegTask.yieldDataPtr = (u64*)&workBuf->yieldData; + sJpegTask.dataPtr = (u64*)&workBuf->taskData; + + jpegCtx->scTask.next = NULL; + jpegCtx->scTask.flags = OS_SC_NEEDS_RSP; + jpegCtx->scTask.msgQ = &jpegCtx->mq; + jpegCtx->scTask.msg = NULL; + jpegCtx->scTask.framebuffer = NULL; + jpegCtx->scTask.list.t = sJpegTask; + + osSendMesg(&gSchedContext.cmdQ, (OSMesg)&jpegCtx->scTask, OS_MESG_BLOCK); + Sched_SendEntryMsg(&gSchedContext); // osScKickEntryMsg + osRecvMesg(&jpegCtx->mq, NULL, OS_MESG_BLOCK); +} + +/** + * Copies a 16x16 block of decoded image data to the Z-buffer. + */ +void Jpeg_CopyToZbuffer(u16* src, u16* zbuffer, s32 x, s32 y) { + u16* dst = zbuffer + (((y * SCREEN_WIDTH) + x) * 16); + s32 i; + + 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; + } +} + +/** + * Reads an u16 from a possibly unaligned address in memory. + * + * Replaces unaligned 16-bit reads with a pair of aligned reads, allowing for reading the possibly + * unaligned values in JPEG header files. + */ +u16 Jpeg_GetUnalignedU16(u8* ptr) { + if (((u32)ptr & 1) == 0) { + // Read the value normally if it's aligned to a 16-bit address. + return *(u16*)ptr; + } else { + // Read unaligned values using two separate aligned memory accesses when it's not. + return *(u16*)(ptr - 1) << 8 | (*(u16*)(ptr + 1) >> 8); + } +} + +/** + * Parses the markers in the JPEG file, storing information such as the pointer to the image data + * in `jpegCtx` for later processing. + */ +void Jpeg_ParseMarkers(u8* ptr, JpegContext* jpegCtx) { + u32 exit = false; + + jpegCtx->dqtCount = 0; + jpegCtx->dhtCount = 0; + + while (true) { + if (exit) { + break; + } + + // 0xFF indicates the start of a JPEG marker, so look for the next. + if (*ptr++ == 0xFF) { + switch (*ptr++) { + case MARKER_ESCAPE: { + // Compressed value 0xFF is stored as 0xFF00 to escape it, so ignore it. + break; + } + case MARKER_SOI: { + // Start of Image + break; + } + case MARKER_APP0: { + // Application marker for JFIF + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + case MARKER_APP1: { + // Application marker for EXIF + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + case MARKER_APP2: { + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + case MARKER_DQT: { + // Define Quantization Table, stored for later processing + jpegCtx->dqtPtr[jpegCtx->dqtCount++] = ptr + 2; + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + case MARKER_DHT: { + // Define Huffman Table, stored for later processing + jpegCtx->dhtPtr[jpegCtx->dhtCount++] = ptr + 2; + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + case MARKER_DRI: { + // Define Restart Interval + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + case MARKER_SOF: { + // Start of Frame, stores important metadata of the image. + // Only used for extracting the sampling factors (jpegCtx->mode). + + if (ptr[9] == 0x21) { + // component Y : V0 == 1 + jpegCtx->mode = 0; + } else if (ptr[9] == 0x22) { + // component Y : V0 == 2 + jpegCtx->mode = 2; + } + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + case MARKER_SOS: { + // Start of Scan marker, indicates the start of the image data. + ptr += Jpeg_GetUnalignedU16(ptr); + jpegCtx->imageData = ptr; + break; + } + case MARKER_EOI: { + // End of Image + exit = true; + break; + } + default: { + ptr += Jpeg_GetUnalignedU16(ptr); + break; + } + } + } + } +} + +s32 Jpeg_Decode(void* data, void* zbuffer, void* work, u32 workSize) { + s32 y; + s32 x; + s32 j; + s32 i; + JpegContext jpegCtx; + JpegHuffmanTable hTables[4]; + JpegDecoder decoder; + JpegDecoderState state; + JpegWork* workBuff = work; + + if (workSize < sizeof(JpegWork)) { + return -1; + } + + osCreateMesgQueue(&jpegCtx.mq, &jpegCtx.msg, 1); + MsgEvent_SendNullTask(); + + jpegCtx.workBuf = workBuff; + + Jpeg_ParseMarkers(data, &jpegCtx); + + switch (jpegCtx.dqtCount) { + case 1: + JpegUtils_ProcessQuantizationTable(jpegCtx.dqtPtr[0], &workBuff->qTableY, 3); + break; + + case 2: + JpegUtils_ProcessQuantizationTable(jpegCtx.dqtPtr[0], &workBuff->qTableY, 1); + JpegUtils_ProcessQuantizationTable(jpegCtx.dqtPtr[1], &workBuff->qTableU, 1); + JpegUtils_ProcessQuantizationTable(jpegCtx.dqtPtr[1], &workBuff->qTableV, 1); + break; + + case 3: + JpegUtils_ProcessQuantizationTable(jpegCtx.dqtPtr[0], &workBuff->qTableY, 1); + JpegUtils_ProcessQuantizationTable(jpegCtx.dqtPtr[1], &workBuff->qTableU, 1); + JpegUtils_ProcessQuantizationTable(jpegCtx.dqtPtr[2], &workBuff->qTableV, 1); + break; + + default: + return -1; + } + + switch (jpegCtx.dhtCount) { + case 1: + if (JpegUtils_ProcessHuffmanTable(jpegCtx.dhtPtr[0], &hTables[0], workBuff->codesLengths, workBuff->codes, + 4)) { + return -1; + } + break; + + case 4: + // This chained if-else has printfs inside it on debug + if (JpegUtils_ProcessHuffmanTable(jpegCtx.dhtPtr[0], &hTables[0], workBuff->codesLengths, workBuff->codes, + 1)) { + } else if (JpegUtils_ProcessHuffmanTable(jpegCtx.dhtPtr[1], &hTables[1], workBuff->codesLengths, + workBuff->codes, 1)) { + } else if (JpegUtils_ProcessHuffmanTable(jpegCtx.dhtPtr[2], &hTables[2], workBuff->codesLengths, + workBuff->codes, 1)) { + } else if (!JpegUtils_ProcessHuffmanTable(jpegCtx.dhtPtr[3], &hTables[3], workBuff->codesLengths, + workBuff->codes, 1)) { + break; + } + return -1; + + default: + return -1; + } + + decoder.imageData = jpegCtx.imageData; + decoder.mode = jpegCtx.mode; + decoder.unk_05 = 2; + + decoder.hTablePtrs[0] = &hTables[0]; + decoder.hTablePtrs[1] = &hTables[1]; + decoder.hTablePtrs[2] = &hTables[2]; + decoder.hTablePtrs[3] = &hTables[3]; + decoder.unk_18 = 0; + + x = y = 0; + for (i = 0; i < 300; i += 4) { + if (!JpegDecoder_Decode(&decoder, (u16*)workBuff->data, 4, (i != 0), &state)) { + Jpeg_ScheduleDecoderTask(&jpegCtx); + + for (j = 0; j < 4; j++) { + Jpeg_CopyToZbuffer(workBuff->data[j], zbuffer, x, y); + x++; + + if (x >= 20) { + x = 0; + y++; + } + } + } + } + + return 0; +} diff --git a/src/code/z_scene.c b/src/code/z_scene.c index dd158ac07..293a9762d 100644 --- a/src/code/z_scene.c +++ b/src/code/z_scene.c @@ -449,7 +449,7 @@ void Scene_HeaderCmdSoundSettings(GlobalContext* globalCtx, SceneCmd* cmd) { globalCtx->soundCtx.seqIndex = cmd->soundSettings.musicSeq; globalCtx->soundCtx.nightSeqIndex = cmd->soundSettings.nighttimeSFX; - if (gSaveContext.seqIndex == 0xFF || func_801A8A50(0) == 0x57) { + if (gSaveContext.seqIndex == (u8)NA_BGM_DISABLED || func_801A8A50(0) == NA_BGM_FINAL_HOURS) { audio_setBGM(cmd->soundSettings.bgmId); } } |
