From e6db0ff530a795232b8e4fcf5371f7a56dd8d3f2 Mon Sep 17 00:00:00 2001 From: DizzyEggg Date: Tue, 15 Jul 2025 18:22:42 +0200 Subject: [PATCH] Decompile code_80035F0 --- include/palette_fade_util.h | 16 + ld_script.ld | 4 +- src/code_80035F0.c | 644 ----------------------------------- src/code_8099360.c | 11 +- src/palette_fade_util.c | 646 ++++++++++++++++++++++++++++++++++++ src/palette_util.c | 133 ++++---- sym_iwram.txt | 2 +- sym_iwram_init.txt | 2 +- 8 files changed, 734 insertions(+), 724 deletions(-) create mode 100644 include/palette_fade_util.h delete mode 100644 src/code_80035F0.c create mode 100644 src/palette_fade_util.c diff --git a/include/palette_fade_util.h b/include/palette_fade_util.h new file mode 100644 index 000000000..cf67bb845 --- /dev/null +++ b/include/palette_fade_util.h @@ -0,0 +1,16 @@ +#ifndef GUARD_PALETTE_FADE_UTIL_H +#define GUARD_PALETTE_FADE_UTIL_H + +#include "structs/rgb.h" + +void InitPaletteFadeTable(void); +void SetPaletteFade_Brightness(u16 idx, s32 fadeAmount); +void SetPaletteFade_Blend(u16 idx, s32 fadeAmount, RGB_Array param_3); +void SetPaletteFade_FadeToBlack(u16 idx, s32 fadeAmount, RGB_Array param_3); +void SetPaletteFade_Desaturate(u16 idx, s32 fadeAmount, RGB_Array param_3); +void SetPaletteFade_Modulate(u16 idx, s32 fadeAmount, RGB_Array param_3); +void sub_8003810(u16 idx, RGB_Array param_2); +void sub_800388C(u16 idx1, const RGB_Union *param_2, s32 param_3); +void RunPaletteFadeFunctions(void); + +#endif // GUARD_PALETTE_FADE_UTIL_H diff --git a/ld_script.ld b/ld_script.ld index 2f64a8d5c..c87b17d7c 100755 --- a/ld_script.ld +++ b/ld_script.ld @@ -53,7 +53,7 @@ SECTIONS { src/gba_color_util.o(.text); src/code_8002774.o(.text); src/memory.o(.text); - src/code_80035F0.o(.text); + src/palette_fade_util.o(.text); src/other_random.o(.text); src/util.o(.text); src/bg_palette_buffer.o(.text); @@ -433,7 +433,7 @@ SECTIONS { src/code_8002774.o(.rodata); data/pksdir_5.o(.rodata); src/memory.o(.rodata); - src/code_80035F0.o(.rodata); + src/palette_fade_util.o(.rodata); src/other_random.o(.rodata); src/util.o(.rodata); src/bg_palette_buffer.o(.rodata); diff --git a/src/code_80035F0.c b/src/code_80035F0.c deleted file mode 100644 index 8823348a9..000000000 --- a/src/code_80035F0.c +++ /dev/null @@ -1,644 +0,0 @@ -#include "global.h" -#include "globaldata.h" -#include "bg_palette_buffer.h" -#include "gba_color_util.h" - -IWRAM_INIT bool8 gUnknown_3001B58 = FALSE; -IWRAM_INIT u16 gUnknown_3001B5A = 0; - -typedef struct unkStruct_3000C00 -{ - bool8 unk0; - u8 unk1; - s16 fadeFactor; - RGB_Array unk4; - RGB_Array *unk8; - void (*unkC)(u16, u16); - void (*unk10)(u16); -} unkStruct_3000C00; - -// TODO: make static once whole file is decompiled -#define UNK_3000400_ARR_COUNT 0x200 -#define UNK_3000C00_ARR_COUNT 0x21 -IWRAM_DATA RGB_Union gUnknown_3000400[UNK_3000400_ARR_COUNT] = {0}; -IWRAM_DATA unkStruct_3000C00 gUnknown_3000C00[UNK_3000C00_ARR_COUNT] = {0}; - -void sub_8003A34(u16 param_1, u16 idx); -void sub_8003AC0(u16, u16); -void sub_8003C18(u16, u16); -void sub_8003E2C(u16, u16); -void sub_8003F60(u16, u16); -void sub_8004170(u16 fadeIndex, u16); -void sub_8004388(u16, u16); -void sub_8003B50(u16); -void sub_8003D00(u16); -void sub_8003EC0(u16); -void sub_8004034(u16); -void sub_8004264(u16); -void sub_8004434(u16); -void sub_8003A74(u16); - -NAKED -UNUSED static void sub_80035F8(void) -{ - asm_unified(" .text\n" -" push {lr}\n" -" pop {r0}\n" -" bx r0\n"); -} - -void sub_8003600(void) -{ - unkStruct_3000C00 *it1; - RGB_Union *it2; - bool8 *r6; - s32 i; - s32 zero; - - it1 = &gUnknown_3000C00[0]; - r6 = &gUnknown_3001B58; - zero = 0; - it2 = &gUnknown_3000400[0]; - - for (i = 0; i < UNK_3000400_ARR_COUNT; it2++, i++) - { - it2->asArr.c[0] = zero; - it2->asArr.c[1] = zero; - it2->asArr.c[2] = zero; - it2->asArr.c[3] = zero; - } - - for (i = 0; i < UNK_3000C00_ARR_COUNT; i++, it1++) - { - it1->unk0 = FALSE; - it1->fadeFactor = 256; - it1->unk4.c[0] = 0; - it1->unk4.c[1] = 0; - it1->unk4.c[2] = 0; - it1->unk4.c[3] = 0; - it1->unk8 = 0; - it1->unkC = &sub_8003A34; - it1->unk10 = &sub_8003A74; - } - - *r6 = TRUE; -} - -void sub_8003664(u16 idx, s32 fadeFactor) -{ - unkStruct_3000C00 *ptr = &gUnknown_3000C00[idx]; - - ptr->unk0 = TRUE; - ptr->fadeFactor = fadeFactor; - ptr->unk4.c[0] = 0; - ptr->unk4.c[1] = 0; - ptr->unk4.c[2] = 0; - ptr->unk4.c[3] = 0; - ptr->unk8 = 0; - ptr->unkC = &sub_8003AC0; - ptr->unk10 = &sub_8003B50; - - gUnknown_3001B58 = TRUE; -} - -void sub_80036AC(u16 idx, s32 fadeFactor, RGB_Array param_3) -{ - unkStruct_3000C00 *ptr = &gUnknown_3000C00[idx]; - - ptr->unk0 = TRUE; - ptr->fadeFactor = fadeFactor; - ptr->unk4 = param_3; - ptr->unk8 = 0; - ptr->unkC = &sub_8003C18; - ptr->unk10 = &sub_8003D00; - - gUnknown_3001B58 = TRUE; -} - -void sub_80036F4(u16 idx, s32 fadeFactor, RGB_Array param_3) -{ - unkStruct_3000C00 *ptr = &gUnknown_3000C00[idx]; - - ptr->unk0 = TRUE; - ptr->fadeFactor = fadeFactor; - ptr->unk4 = param_3; - ptr->unk8 = 0; - ptr->unkC = &sub_8003E2C; - ptr->unk10 = &sub_8003EC0; - - gUnknown_3001B58 = TRUE; -} - -static UNUSED void sub_800373C(u16 idx, s32 fadeFactor, RGB_Array *param_3) -{ - unkStruct_3000C00 *ptr = &gUnknown_3000C00[idx]; - - ptr->unk0 = TRUE; - ptr->fadeFactor = fadeFactor; - ptr->unk4.c[0] = 0; - ptr->unk4.c[1] = 0; - ptr->unk4.c[2] = 0; - ptr->unk4.c[3] = 0; - ptr->unk8 = param_3; - ptr->unkC = &sub_8003F60; - ptr->unk10 = &sub_8004034; - - gUnknown_3001B58 = TRUE; -} - -void sub_8003780(u16 idx, s32 fadeFactor, RGB_Array param_3) -{ - unkStruct_3000C00 *ptr = &gUnknown_3000C00[idx]; - - ptr->unk0 = TRUE; - ptr->fadeFactor = fadeFactor; - ptr->unk4 = param_3; - ptr->unk8 = 0; - ptr->unkC = &sub_8004170; - ptr->unk10 = &sub_8004264; - - gUnknown_3001B58 = TRUE; -} - -void sub_80037C8(u16 idx, s32 fadeFactor, RGB_Array param_3) -{ - unkStruct_3000C00 *ptr = &gUnknown_3000C00[idx]; - - ptr->unk0 = TRUE; - ptr->fadeFactor = fadeFactor; - ptr->unk4 = param_3; - ptr->unk8 = 0; - ptr->unkC = &sub_8004388; - ptr->unk10 = &sub_8004434; - - gUnknown_3001B58 = TRUE; -} - -void sub_8003810(u16 idx, RGB_Union param_2) -{ - unkStruct_3000C00 *a = &gUnknown_3000C00[idx / 16]; - a->unk0 = TRUE; - - gUnknown_3000400[idx] = param_2; - gUnknown_3001B58 = TRUE; -} - -static UNUSED void sub_8003844(u16 idx1, u16 idx2) -{ - unkStruct_3000C00 *a = &gUnknown_3000C00[idx1 / 16]; - a->unk0 = TRUE; - - gUnknown_3000400[idx1].asArr = GbaColorToRGB(idx2); - gUnknown_3001B58 = TRUE; -} - -void sub_800388C(u16 idx1, RGB_Union *param_2, s32 param_3) -{ - unkStruct_3000C00 *ptr3; - s32 i; - u16 idx2 = idx1 / 16; - u16 sVar2 = (idx1 + param_3 - 1) / 16; - RGB_Union *ptr1 = &gUnknown_3000400[idx1]; - - for (i = 0; i < param_3; param_2++, ptr1++, i++) - { - *ptr1 = *param_2; - } - - ptr3 = &gUnknown_3000C00[idx2]; - - for (i = idx2; i <= sVar2; i++, ptr3++) - { - ptr3->unk0 = TRUE; - } - - gUnknown_3001B58 = TRUE; -} - -static UNUSED void sub_80038F0(u32 param_1, s16 *param_2, s32 param_3) -{ - u16 idx1; - u16 idx2; - u16 uVar; - RGB_Union *ptr1; - unkStruct_3000C00 *ptr2; - s32 i; - - idx1 = param_1; - idx2 = idx1 / 16; - uVar = (idx1 + param_3 - 1) / 16; - ptr1 = &gUnknown_3000400[idx1]; - - for (i = 0; i < param_3; i++) - { - ptr1->asArr = GbaColorToRGB(*param_2++); - ptr1++; - } - - ptr2 = &gUnknown_3000C00[idx2]; - - for (i = idx2; i <= uVar; i++, ptr2++) - { - ptr2->unk0 = TRUE; - } - - gUnknown_3001B58 = TRUE; -} - -static UNUSED RGB_Array sub_8003978(u16 idx) -{ - return gUnknown_3000400[idx].asArr; -} - -static UNUSED u16 sub_8003988(u16 idx) -{ - return RGBToGbaColor(gUnknown_3000400[idx].asArr); -} - -static UNUSED void sub_80039A4(u16 idx) -{ - gUnknown_3001B5A |= idx; -} - -void sub_80039B8(void) -{ - s32 i; - - if (gUnknown_3001B58) { - unkStruct_3000C00* ptr1 = gUnknown_3000C00; - if (gUnknown_3000C00[0xf].unk0) { - gUnknown_3000C00[UNK_3000C00_ARR_COUNT - 1].unk0 = TRUE; - } - - for (i = 0; i < UNK_3000C00_ARR_COUNT - 1; i++, ptr1++) { - if (ptr1->unk0) { - ptr1->unk10(i); - ptr1->unk0 = FALSE; - } - } - - if (gUnknown_3000C00[UNK_3000C00_ARR_COUNT - 1].unk0) { - unkStruct_3000C00 *ptr2 = &gUnknown_3000C00[UNK_3000C00_ARR_COUNT - 1]; - // here ptr2 == ptr1 - ptr1->unkC(0x20, 0xf0); - ptr2->unk0 = FALSE; - } - - gUnknown_3001B5A = 3; - gUnknown_3001B58 = FALSE; - } -} - -void sub_8003A34(u16 param_1, u16 idx) -{ - RGB_Array *rgb = &gUnknown_3000400[idx].asArr; - u16 color = RGB_TO_GBA2(rgb->c[RGB_R], rgb->c[RGB_G], rgb->c[RGB_B]); - - SetBGPaletteBufferColor(idx, &color); -} - -void sub_8003A74(u16 param_1) -{ - s32 i; - u16 color; - u16 idx = param_1 * 16; - RGB_Array *rgb = &gUnknown_3000400[idx].asArr; - - for (i = 0; i < 16; rgb++, i++) { - color = RGB_TO_GBA(rgb->c[RGB_R], rgb->c[RGB_G], rgb->c[RGB_B]); - SetBGPaletteBufferColor(idx + i, &color); - } -} - -void sub_8003AC0(u16 idx1, u16 idx2) -{ - u16 color; - unkStruct_3000C00 *ptr2 = &gUnknown_3000C00[idx1]; - u16 fadeFactor = ptr2->fadeFactor; - RGB_Array *rgb = &gUnknown_3000400[idx2].asArr; - - if (fadeFactor > 255) { - color = RGB_TO_GBA2(rgb->c[RGB_R], rgb->c[RGB_G], rgb->c[RGB_B]); - } - else if (fadeFactor == 0) { - color = RGB_BLACK; - } - else { - color = RGB_TO_GBA((rgb->c[RGB_R] * fadeFactor) / 256, - (rgb->c[RGB_G] * fadeFactor) / 256, - (rgb->c[RGB_B] * fadeFactor) / 256); - } - - SetBGPaletteBufferColor(idx2, &color); -} - -void sub_8003B50(u16 param1) -{ - u16 color; - s32 i; - unkStruct_3000C00 *ptr1 = &gUnknown_3000C00[param1]; - u16 fadeFactor = ptr1->fadeFactor; - u16 id = param1 * 16; - RGB_Array *rgb = &gUnknown_3000400[id].asArr; - - if (fadeFactor > 255) { - for (i = 0; i < 16; rgb++, i++) { - color = RGB_TO_GBA(rgb->c[RGB_R], rgb->c[RGB_G], rgb->c[RGB_B]); - SetBGPaletteBufferColor(id + i, &color); - } - } - else if (fadeFactor == 0) { - color = RGB_BLACK; - for (i = 0; i < 16; rgb++, i++) { - SetBGPaletteBufferColor(id + i, &color); - } - } - else { - for (i = 0; i < 16; rgb++, i++) { - color = RGB_TO_GBA((rgb->c[RGB_R] * fadeFactor) / 256, - (rgb->c[RGB_G] * fadeFactor) / 256, - (rgb->c[RGB_B] * fadeFactor) / 256); - SetBGPaletteBufferColor(id + i, &color); - } - } -} - -void sub_8003C18(u16 fadeIdx, u16 paletteIdx) -{ - u16 color; - unkStruct_3000C00 *fade = &gUnknown_3000C00[fadeIdx]; - u16 fadeFactor = fade->fadeFactor; - RGB_Array fadeRGB = fade->unk4; - RGB_Array *paletteRGB = &gUnknown_3000400[paletteIdx].asArr; - - if (fadeFactor > 0xFF) { - // Just use the palette color directly - color = RGB_TO_GBA2(paletteRGB->c[RGB_R], paletteRGB->c[RGB_G], paletteRGB->c[RGB_B]); - } - else if (fadeFactor == 0) { - // Fully faded to target color - color = RGB_TO_GBA2(fadeRGB.c[RGB_R], fadeRGB.c[RGB_G], fadeRGB.c[RGB_B]); - } - else { - // Blend - u16 invFade = 256 - fadeFactor; - s32 invFadeR = fadeRGB.c[RGB_R] * invFade; - s32 invFadeG = fadeRGB.c[RGB_G] * invFade; - s32 invFadeB = fadeRGB.c[RGB_B] * invFade; - color = RGB_TO_GBA2((paletteRGB->c[RGB_R] * fadeFactor + invFadeR) / 256, - (paletteRGB->c[RGB_G] * fadeFactor + invFadeG) / 256, - (paletteRGB->c[RGB_B] * fadeFactor + invFadeB) / 256); - } - - SetBGPaletteBufferColor(paletteIdx, &color); -} - -void sub_8003D00(u16 fadeIdx) -{ - s32 i; - u16 color; - unkStruct_3000C00 *fade = &gUnknown_3000C00[fadeIdx]; - u16 fadeFactor = fade->fadeFactor; - RGB_Array fadeRGB = fade->unk4; - u16 basePaletteIdx = fadeIdx * 16; - RGB_Array *paletteRGB = &gUnknown_3000400[basePaletteIdx].asArr; - - if (fadeFactor > 0xFF) { - // Just use the palette color directly - for (i = 0; i < 16; paletteRGB++, i++) { - color = RGB_TO_GBA(paletteRGB->c[RGB_R], paletteRGB->c[RGB_G], paletteRGB->c[RGB_B]); - SetBGPaletteBufferColor(basePaletteIdx + i, &color); - } - } - else if (fadeFactor == 0) { - // Fully faded to target color - color = RGB_TO_GBA2(fadeRGB.c[RGB_R], fadeRGB.c[RGB_G], fadeRGB.c[RGB_B]); - for (i = 0; i < 16; paletteRGB++, i++) { - SetBGPaletteBufferColor(basePaletteIdx + i, &color); - } - } - else { - // Blend - u16 invFade = 256 - fadeFactor; - s32 invFadeR = fadeRGB.c[RGB_R] * invFade; - s32 invFadeG = fadeRGB.c[RGB_G] * invFade; - s32 invFadeB = fadeRGB.c[RGB_B] * invFade; - for (i = 0; i < 16; paletteRGB++, i++) { - color = RGB_TO_GBA((paletteRGB->c[RGB_R] * fadeFactor + invFadeR) / 256, - (paletteRGB->c[RGB_G] * fadeFactor + invFadeG) / 256, - (paletteRGB->c[RGB_B] * fadeFactor + invFadeB) / 256); - SetBGPaletteBufferColor(basePaletteIdx + i, &color); - } - } -} - -void sub_8003E2C(u16 fadeIdx, u16 targetIdx) -{ - u16 color; - unkStruct_3000C00 *fade = &gUnknown_3000C00[fadeIdx]; - u16 fadeFactor = fade->fadeFactor; - RGB_Array fadeRGB = fade->unk4; - - if (fadeFactor > 0xFF) { - color = RGB_TO_GBA2(fadeRGB.c[RGB_R], fadeRGB.c[RGB_G], fadeRGB.c[RGB_B]); - } - else if (fadeFactor == 0) { - color = RGB_BLACK; - } - else { - color = RGB_TO_GBA((fadeRGB.c[RGB_R] * fadeFactor) / 256, - (fadeRGB.c[RGB_G] * fadeFactor) / 256, - (fadeRGB.c[RGB_B] * fadeFactor) / 256); - } - - SetBGPaletteBufferColor(targetIdx, &color); -} - -void sub_8003EC0(u16 fadeIdx) -{ - u16 color; - s32 i; - unkStruct_3000C00 *fade = &gUnknown_3000C00[fadeIdx]; - u16 fadeFactor = fade->fadeFactor; - RGB_Array fadeColor = fade->unk4; - u16 targetStartIdx = fadeIdx * 16; - - if (fadeFactor > 0xFF) { - color = RGB_TO_GBA2(fadeColor.c[RGB_R], fadeColor.c[RGB_G], fadeColor.c[RGB_B]); - } - else if (fadeFactor == 0) { - color = RGB_BLACK; - } - else { - color = RGB_TO_GBA((fadeColor.c[RGB_R] * fadeFactor) / 256, - (fadeColor.c[RGB_G] * fadeFactor) / 256, - (fadeColor.c[RGB_B] * fadeFactor) / 256); - } - - for (i = 0; i < 16; i++) { - SetBGPaletteBufferColor(targetStartIdx + i, &color); - } -} - -void sub_8003F60(u16 fadeIdx, u16 targetIdx) -{ - u16 color; - unkStruct_3000C00 *fade = &gUnknown_3000C00[fadeIdx]; - u16 fadeFactor = fade->fadeFactor; - RGB_Array *fadeSubColor = &fade->unk8[targetIdx % 16]; - RGB_Array *baseColor = &gUnknown_3000400[targetIdx].asArr; - - if (fadeFactor > 0xFF) { - color = RGB_TO_GBA2(baseColor->c[RGB_R], baseColor->c[RGB_G], baseColor->c[RGB_B]); - } - else if (fadeFactor == 0) { - color = RGB_TO_GBA2(fadeSubColor->c[RGB_R], fadeSubColor->c[RGB_G], fadeSubColor->c[RGB_B]); - } - else { - u16 invFade = 256 - fadeFactor; - s32 r = fadeSubColor->c[RGB_R] * invFade + baseColor->c[RGB_R] * fadeFactor; - s32 g = fadeSubColor->c[RGB_G] * invFade + baseColor->c[RGB_G] * fadeFactor; - s32 b = fadeSubColor->c[RGB_B] * invFade + baseColor->c[RGB_B] * fadeFactor; - color = RGB_TO_GBA2(r / 256, g / 256, b / 256); - } - - SetBGPaletteBufferColor(targetIdx, &color); -} - -void sub_8004034(u16 fadeIdx) -{ - u16 color; - s32 i; - unkStruct_3000C00 *fade = &gUnknown_3000C00[fadeIdx]; - u16 fadeFactor = fade->fadeFactor; - RGB_Array *fadeColors = fade->unk8; - u16 targetStartIdx = fadeIdx * 16; - RGB_Array *baseColors = &gUnknown_3000400[targetStartIdx].asArr; - - if (fadeFactor > 0xFF) { - // Fully use base palette - for (i = 0; i < 16; baseColors++, i++) { - color = RGB_TO_GBA(baseColors->c[RGB_R], baseColors->c[RGB_G], baseColors->c[RGB_B]); - ASM_MATCH_TRICK(i); - SetBGPaletteBufferColor(targetStartIdx + i, &color); - } - } - else if (fadeFactor == 0) { - // Fully use fade palette - for (i = 0; i < 16; fadeColors++, i++) { - color = RGB_TO_GBA(fadeColors->c[RGB_R], fadeColors->c[RGB_G], fadeColors->c[RGB_B]); - SetBGPaletteBufferColor(targetStartIdx + i, &color); - } - } - else { - // Blend fade and base - u16 invFade = 256 - fadeFactor; - - for (i = 0; i < 16; baseColors++, fadeColors++, i++) { - s32 r = fadeColors->c[RGB_R] * invFade + baseColors->c[RGB_R] * fadeFactor; - s32 g = fadeColors->c[RGB_G] * invFade + baseColors->c[RGB_G] * fadeFactor; - s32 b = fadeColors->c[RGB_B] * invFade + baseColors->c[RGB_B] * fadeFactor; - color = RGB_TO_GBA(r / 256, g / 256, b / 256); - SetBGPaletteBufferColor(targetStartIdx + i, &color); - } - } -} - -void sub_8004170(u16 fadeIndex, u16 targetIndex) -{ - u16 color; - unkStruct_3000C00 *fade = &gUnknown_3000C00[fadeIndex]; - u16 fadeAmount = fade->fadeFactor; - RGB_Array fadeColor = fade->unk4; - RGB_Array *baseColor = &gUnknown_3000400[targetIndex].asArr; - - if (fadeAmount > 0xFF) { - // No fade, just use base color - color = RGB_TO_GBA2(baseColor->c[RGB_R], baseColor->c[RGB_G], baseColor->c[RGB_B] ); - } - else { - u16 r, g, b; - // Fading to black per channel - - r = fadeColor.c[RGB_R] + ((255 - fadeColor.c[RGB_R]) * fadeAmount) / 256; - g = fadeColor.c[RGB_G] + ((255 - fadeColor.c[RGB_G]) * fadeAmount) / 256; - b = fadeColor.c[RGB_B] + ((255 - fadeColor.c[RGB_B]) * fadeAmount) / 256; - - color = RGB_TO_GBA2((r * baseColor->c[RGB_R]) / 255, (g * baseColor->c[RGB_G]) / 255, (b * baseColor->c[RGB_B]) / 255); - } - - SetBGPaletteBufferColor(targetIndex, &color); -} - -void sub_8004264(u16 fadeIndex) -{ - s32 i; - u16 color; - unkStruct_3000C00 *fade = &gUnknown_3000C00[fadeIndex]; - u16 fadeAmount = fade->fadeFactor; - RGB_Array fadeColor = fade->unk4; - u16 targetIndex = fadeIndex * 16; - RGB_Array *baseColor = &gUnknown_3000400[targetIndex].asArr; - - if (fadeAmount > 0xFF) { - for (i = 0; i < 16; baseColor++, i++) { - // No fade, just use base color - color = RGB_TO_GBA(baseColor->c[RGB_R], baseColor->c[RGB_G], baseColor->c[RGB_B]); - SetBGPaletteBufferColor(targetIndex + i, &color); - } - } - else { - u16 r, g, b; - // Fading to black per channel - - r = fadeColor.c[RGB_R] + ((255 - fadeColor.c[RGB_R]) * fadeAmount) / 256; - g = fadeColor.c[RGB_G] + ((255 - fadeColor.c[RGB_G]) * fadeAmount) / 256; - b = fadeColor.c[RGB_B] + ((255 - fadeColor.c[RGB_B]) * fadeAmount) / 256; - for (i = 0; i < 16; baseColor++, i++) { - color = RGB_TO_GBA((r * baseColor->c[RGB_R]) / 255, (g * baseColor->c[RGB_G]) / 255, (b * baseColor->c[RGB_B]) / 255); - SetBGPaletteBufferColor(targetIndex + i, &color); - } - } -} - -void sub_8004388(u16 fadeIndex, u16 paletteIndex) -{ - u16 color; - u16 r, g, b; - unkStruct_3000C00 *fade = &gUnknown_3000C00[fadeIndex]; - u16 fadeAmount = fade->fadeFactor; - RGB_Array fadeColor = fade->unk4; - RGB_Array *baseColor = &gUnknown_3000400[paletteIndex].asArr; - - if (fadeAmount > 255) - fadeAmount = 256; - - r = fadeColor.c[RGB_R] * fadeAmount / 256; - g = fadeColor.c[RGB_G] * fadeAmount / 256; - b = fadeColor.c[RGB_B] * fadeAmount / 256; - color = RGB_TO_GBA2((r * baseColor->c[RGB_R]) / 255, (g * baseColor->c[RGB_G]) / 255, (b * baseColor->c[RGB_B]) / 255); - SetBGPaletteBufferColor(paletteIndex, &color); -} - -void sub_8004434(u16 fadeIndex) -{ - s32 i; - u16 color; - u16 r, g, b; - unkStruct_3000C00 *fade = &gUnknown_3000C00[fadeIndex]; - u16 fadeAmount = fade->fadeFactor; - RGB_Array fadeColor = fade->unk4; - u16 paletteIndex = fadeIndex * 16; - RGB_Array *baseColors = &gUnknown_3000400[paletteIndex].asArr; - - if (fadeAmount > 255) - fadeAmount = 256; - - r = fadeColor.c[RGB_R] * fadeAmount / 256; - g = fadeColor.c[RGB_G] * fadeAmount / 256; - b = fadeColor.c[RGB_B] * fadeAmount / 256; - for (i = 0; i < 16; baseColors++, i++) { - color = RGB_TO_GBA2((r * baseColors->c[RGB_R]) / 255, (g * baseColors->c[RGB_G]) / 255, (b * baseColors->c[RGB_B]) / 255); - SetBGPaletteBufferColor(paletteIndex + i, &color); - } -} diff --git a/src/code_8099360.c b/src/code_8099360.c index 4a9ec37af..0b8a395f5 100644 --- a/src/code_8099360.c +++ b/src/code_8099360.c @@ -7,16 +7,13 @@ #include "def_filearchives.h" #include "event_flag.h" #include "file_system.h" +#include "palette_fade_util.h" extern u8 gUnknown_20398B8; -extern void sub_8003600(void); -extern s32 sub_800388C(u16, const u8 *, u8); -extern void sub_8003810(u16 idx, RGB_Array param_2); - void sub_8099648(void) { - sub_8003600(); + InitPaletteFadeTable(); sub_809965C(); } @@ -31,7 +28,7 @@ void sub_809965C(void) file = OpenFileAndGetFileDataPtr("fontsppa", &gSystemFileArchive); - sub_800388C(0x1f0, file->data, 0x10); + sub_800388C(0x1f0, (const RGB_Union *) file->data, 0x10); CloseFile(file); } @@ -62,7 +59,7 @@ void sub_8099690(u32 param_1) break; } - sub_800388C(0xF0, (u8 *)pal, 0x10); + sub_800388C(0xF0, (const RGB_Union *)pal, 0x10); var2 = pal; for(index = 0; index < 0x10; index++) { diff --git a/src/palette_fade_util.c b/src/palette_fade_util.c new file mode 100644 index 000000000..a890eeabe --- /dev/null +++ b/src/palette_fade_util.c @@ -0,0 +1,646 @@ +#include "global.h" +#include "globaldata.h" +#include "palette_fade_util.h" +#include "bg_palette_buffer.h" +#include "gba_color_util.h" + +static IWRAM_INIT bool8 sUpdatePaletteFade = FALSE; +static IWRAM_INIT u16 sUnusedPaletteUpdateFlags = 0; + +typedef struct PaletteFadeEntry +{ + bool8 active; + s16 fadeAmount; + RGB_Array fadeColor; + RGB_Array *fadeColorArray; + void (*applyFadeToSingle)(u16, u16); + void (*applyFadeToRow)(u16); +} PaletteFadeEntry; + +#define MAX_FADE_AMOUNT 256 + +#define PALETTE_COLOR_COUNT 0x200 +#define PALETTE_FADE_ENTRY_COUNT 0x21 + +static IWRAM_DATA RGB_Union sRGBPaletteBuffer[PALETTE_COLOR_COUNT] = {0}; +static IWRAM_DATA PaletteFadeEntry sPaletteFadeTable[PALETTE_FADE_ENTRY_COUNT] = {0}; + +static void ApplySinglePalette(u16 param_1, u16 idx); +static void ApplySinglePaletteBrightness(u16, u16); +static void BlendSinglePalette(u16, u16); +static void FadeToBlackSingle(u16, u16); +static void PerEntryBlendSingle(u16, u16); +static void DesaturateSingle(u16 fadeIndex, u16); +static void ModulatePaletteSingle(u16, u16); +static void ApplyRowPaletteBrightness(u16); +static void BlendRowPalette(u16); +static void FadeToBlackRow(u16); +static void PerEntryBlendRow(u16); +static void DesaturateRow(u16); +static void ModulatePaletteRow(u16); +static void ApplyRowPalette(u16); + +NAKED +UNUSED static void sub_80035F8(void) +{ + asm_unified(" .text\n" +" push {lr}\n" +" pop {r0}\n" +" bx r0\n"); +} + +void InitPaletteFadeTable(void) +{ + PaletteFadeEntry *it1; + RGB_Union *it2; + bool8 *r6; + s32 i; + s32 zero; + + it1 = &sPaletteFadeTable[0]; + r6 = &sUpdatePaletteFade; + zero = 0; + it2 = &sRGBPaletteBuffer[0]; + + for (i = 0; i < PALETTE_COLOR_COUNT; it2++, i++) + { + it2->asArr.c[0] = zero; + it2->asArr.c[1] = zero; + it2->asArr.c[2] = zero; + it2->asArr.c[3] = zero; + } + + for (i = 0; i < PALETTE_FADE_ENTRY_COUNT; i++, it1++) + { + it1->active = FALSE; + it1->fadeAmount = 256; + it1->fadeColor.c[0] = 0; + it1->fadeColor.c[1] = 0; + it1->fadeColor.c[2] = 0; + it1->fadeColor.c[3] = 0; + it1->fadeColorArray = 0; + it1->applyFadeToSingle = &ApplySinglePalette; + it1->applyFadeToRow = &ApplyRowPalette; + } + + *r6 = TRUE; +} + +void SetPaletteFade_Brightness(u16 idx, s32 fadeAmount) +{ + PaletteFadeEntry *ptr = &sPaletteFadeTable[idx]; + + ptr->active = TRUE; + ptr->fadeAmount = fadeAmount; + ptr->fadeColor.c[0] = 0; + ptr->fadeColor.c[1] = 0; + ptr->fadeColor.c[2] = 0; + ptr->fadeColor.c[3] = 0; + ptr->fadeColorArray = 0; + ptr->applyFadeToSingle = &ApplySinglePaletteBrightness; + ptr->applyFadeToRow = &ApplyRowPaletteBrightness; + + sUpdatePaletteFade = TRUE; +} + +void SetPaletteFade_Blend(u16 idx, s32 fadeAmount, RGB_Array param_3) +{ + PaletteFadeEntry *ptr = &sPaletteFadeTable[idx]; + + ptr->active = TRUE; + ptr->fadeAmount = fadeAmount; + ptr->fadeColor = param_3; + ptr->fadeColorArray = 0; + ptr->applyFadeToSingle = &BlendSinglePalette; + ptr->applyFadeToRow = &BlendRowPalette; + + sUpdatePaletteFade = TRUE; +} + +void SetPaletteFade_FadeToBlack(u16 idx, s32 fadeAmount, RGB_Array param_3) +{ + PaletteFadeEntry *ptr = &sPaletteFadeTable[idx]; + + ptr->active = TRUE; + ptr->fadeAmount = fadeAmount; + ptr->fadeColor = param_3; + ptr->fadeColorArray = 0; + ptr->applyFadeToSingle = &FadeToBlackSingle; + ptr->applyFadeToRow = &FadeToBlackRow; + + sUpdatePaletteFade = TRUE; +} + +static UNUSED void SetPaletteFade_PerEntryBlend(u16 idx, s32 fadeAmount, RGB_Array *param_3) +{ + PaletteFadeEntry *ptr = &sPaletteFadeTable[idx]; + + ptr->active = TRUE; + ptr->fadeAmount = fadeAmount; + ptr->fadeColor.c[0] = 0; + ptr->fadeColor.c[1] = 0; + ptr->fadeColor.c[2] = 0; + ptr->fadeColor.c[3] = 0; + ptr->fadeColorArray = param_3; + ptr->applyFadeToSingle = &PerEntryBlendSingle; + ptr->applyFadeToRow = &PerEntryBlendRow; + + sUpdatePaletteFade = TRUE; +} + +void SetPaletteFade_Desaturate(u16 idx, s32 fadeAmount, RGB_Array param_3) +{ + PaletteFadeEntry *ptr = &sPaletteFadeTable[idx]; + + ptr->active = TRUE; + ptr->fadeAmount = fadeAmount; + ptr->fadeColor = param_3; + ptr->fadeColorArray = 0; + ptr->applyFadeToSingle = &DesaturateSingle; + ptr->applyFadeToRow = &DesaturateRow; + + sUpdatePaletteFade = TRUE; +} + +void SetPaletteFade_Modulate(u16 idx, s32 fadeAmount, RGB_Array param_3) +{ + PaletteFadeEntry *ptr = &sPaletteFadeTable[idx]; + + ptr->active = TRUE; + ptr->fadeAmount = fadeAmount; + ptr->fadeColor = param_3; + ptr->fadeColorArray = 0; + ptr->applyFadeToSingle = &ModulatePaletteSingle; + ptr->applyFadeToRow = &ModulatePaletteRow; + + sUpdatePaletteFade = TRUE; +} + +void sub_8003810(u16 idx, RGB_Array param_2) +{ + PaletteFadeEntry *a = &sPaletteFadeTable[idx / 16]; + a->active = TRUE; + + sRGBPaletteBuffer[idx].asArr = param_2; + sUpdatePaletteFade = TRUE; +} + +static UNUSED void sub_8003844(u16 idx1, u16 idx2) +{ + PaletteFadeEntry *a = &sPaletteFadeTable[idx1 / 16]; + a->active = TRUE; + + sRGBPaletteBuffer[idx1].asArr = GbaColorToRGB(idx2); + sUpdatePaletteFade = TRUE; +} + +void sub_800388C(u16 idx1, const RGB_Union *param_2, s32 param_3) +{ + PaletteFadeEntry *ptr3; + s32 i; + u16 idx2 = idx1 / 16; + u16 sVar2 = (idx1 + param_3 - 1) / 16; + RGB_Union *ptr1 = &sRGBPaletteBuffer[idx1]; + + for (i = 0; i < param_3; param_2++, ptr1++, i++) + { + *ptr1 = *param_2; + } + + ptr3 = &sPaletteFadeTable[idx2]; + + for (i = idx2; i <= sVar2; i++, ptr3++) + { + ptr3->active = TRUE; + } + + sUpdatePaletteFade = TRUE; +} + +static UNUSED void sub_80038F0(u32 param_1, s16 *param_2, s32 param_3) +{ + u16 idx1; + u16 idx2; + u16 uVar; + RGB_Union *ptr1; + PaletteFadeEntry *ptr2; + s32 i; + + idx1 = param_1; + idx2 = idx1 / 16; + uVar = (idx1 + param_3 - 1) / 16; + ptr1 = &sRGBPaletteBuffer[idx1]; + + for (i = 0; i < param_3; i++) + { + ptr1->asArr = GbaColorToRGB(*param_2++); + ptr1++; + } + + ptr2 = &sPaletteFadeTable[idx2]; + + for (i = idx2; i <= uVar; i++, ptr2++) + { + ptr2->active = TRUE; + } + + sUpdatePaletteFade = TRUE; +} + +static UNUSED RGB_Array sub_8003978(u16 idx) +{ + return sRGBPaletteBuffer[idx].asArr; +} + +static UNUSED u16 sub_8003988(u16 idx) +{ + return RGBToGbaColor(sRGBPaletteBuffer[idx].asArr); +} + +static UNUSED void sub_80039A4(u16 idx) +{ + sUnusedPaletteUpdateFlags |= idx; +} + +void RunPaletteFadeFunctions(void) +{ + s32 i; + + if (sUpdatePaletteFade) { + PaletteFadeEntry* ptr1 = sPaletteFadeTable; + if (sPaletteFadeTable[0xf].active) { + sPaletteFadeTable[PALETTE_FADE_ENTRY_COUNT - 1].active = TRUE; + } + + for (i = 0; i < PALETTE_FADE_ENTRY_COUNT - 1; i++, ptr1++) { + if (ptr1->active) { + ptr1->applyFadeToRow(i); + ptr1->active = FALSE; + } + } + + if (sPaletteFadeTable[PALETTE_FADE_ENTRY_COUNT - 1].active) { + PaletteFadeEntry *ptr2 = &sPaletteFadeTable[PALETTE_FADE_ENTRY_COUNT - 1]; + // here ptr2 == ptr1 + ptr1->applyFadeToSingle(0x20, 0xf0); + ptr2->active = FALSE; + } + + sUnusedPaletteUpdateFlags = 1 | 2; + sUpdatePaletteFade = FALSE; + } +} + +static void ApplySinglePalette(u16 param_1, u16 idx) +{ + RGB_Array *rgb = &sRGBPaletteBuffer[idx].asArr; + u16 color = RGB_TO_GBA2(rgb->c[RGB_R], rgb->c[RGB_G], rgb->c[RGB_B]); + + SetBGPaletteBufferColor(idx, &color); +} + +static void ApplyRowPalette(u16 param_1) +{ + s32 i; + u16 color; + u16 idx = param_1 * 16; + RGB_Array *rgb = &sRGBPaletteBuffer[idx].asArr; + + for (i = 0; i < 16; rgb++, i++) { + color = RGB_TO_GBA(rgb->c[RGB_R], rgb->c[RGB_G], rgb->c[RGB_B]); + SetBGPaletteBufferColor(idx + i, &color); + } +} + +static void ApplySinglePaletteBrightness(u16 idx1, u16 idx2) +{ + u16 color; + PaletteFadeEntry *ptr2 = &sPaletteFadeTable[idx1]; + u16 fadeAmount = ptr2->fadeAmount; + RGB_Array *rgb = &sRGBPaletteBuffer[idx2].asArr; + + if (fadeAmount >= MAX_FADE_AMOUNT) { + color = RGB_TO_GBA2(rgb->c[RGB_R], rgb->c[RGB_G], rgb->c[RGB_B]); + } + else if (fadeAmount == 0) { + color = RGB_BLACK; + } + else { + color = RGB_TO_GBA((rgb->c[RGB_R] * fadeAmount) / 256, + (rgb->c[RGB_G] * fadeAmount) / 256, + (rgb->c[RGB_B] * fadeAmount) / 256); + } + + SetBGPaletteBufferColor(idx2, &color); +} + +static void ApplyRowPaletteBrightness(u16 param1) +{ + u16 color; + s32 i; + PaletteFadeEntry *ptr1 = &sPaletteFadeTable[param1]; + u16 fadeAmount = ptr1->fadeAmount; + u16 id = param1 * 16; + RGB_Array *rgb = &sRGBPaletteBuffer[id].asArr; + + if (fadeAmount >= MAX_FADE_AMOUNT) { + for (i = 0; i < 16; rgb++, i++) { + color = RGB_TO_GBA(rgb->c[RGB_R], rgb->c[RGB_G], rgb->c[RGB_B]); + SetBGPaletteBufferColor(id + i, &color); + } + } + else if (fadeAmount == 0) { + color = RGB_BLACK; + for (i = 0; i < 16; rgb++, i++) { + SetBGPaletteBufferColor(id + i, &color); + } + } + else { + for (i = 0; i < 16; rgb++, i++) { + color = RGB_TO_GBA((rgb->c[RGB_R] * fadeAmount) / 256, + (rgb->c[RGB_G] * fadeAmount) / 256, + (rgb->c[RGB_B] * fadeAmount) / 256); + SetBGPaletteBufferColor(id + i, &color); + } + } +} + +static void BlendSinglePalette(u16 fadeIdx, u16 paletteIdx) +{ + u16 color; + PaletteFadeEntry *fade = &sPaletteFadeTable[fadeIdx]; + u16 fadeAmount = fade->fadeAmount; + RGB_Array fadeRGB = fade->fadeColor; + RGB_Array *paletteRGB = &sRGBPaletteBuffer[paletteIdx].asArr; + + if (fadeAmount >= MAX_FADE_AMOUNT) { + // Just use the palette color directly + color = RGB_TO_GBA2(paletteRGB->c[RGB_R], paletteRGB->c[RGB_G], paletteRGB->c[RGB_B]); + } + else if (fadeAmount == 0) { + // Fully faded to target color + color = RGB_TO_GBA2(fadeRGB.c[RGB_R], fadeRGB.c[RGB_G], fadeRGB.c[RGB_B]); + } + else { + // Blend + u16 invFade = 256 - fadeAmount; + s32 invFadeR = fadeRGB.c[RGB_R] * invFade; + s32 invFadeG = fadeRGB.c[RGB_G] * invFade; + s32 invFadeB = fadeRGB.c[RGB_B] * invFade; + color = RGB_TO_GBA2((paletteRGB->c[RGB_R] * fadeAmount + invFadeR) / 256, + (paletteRGB->c[RGB_G] * fadeAmount + invFadeG) / 256, + (paletteRGB->c[RGB_B] * fadeAmount + invFadeB) / 256); + } + + SetBGPaletteBufferColor(paletteIdx, &color); +} + +static void BlendRowPalette(u16 fadeIdx) +{ + s32 i; + u16 color; + PaletteFadeEntry *fade = &sPaletteFadeTable[fadeIdx]; + u16 fadeAmount = fade->fadeAmount; + RGB_Array fadeRGB = fade->fadeColor; + u16 basePaletteIdx = fadeIdx * 16; + RGB_Array *paletteRGB = &sRGBPaletteBuffer[basePaletteIdx].asArr; + + if (fadeAmount >= MAX_FADE_AMOUNT) { + // Just use the palette color directly + for (i = 0; i < 16; paletteRGB++, i++) { + color = RGB_TO_GBA(paletteRGB->c[RGB_R], paletteRGB->c[RGB_G], paletteRGB->c[RGB_B]); + SetBGPaletteBufferColor(basePaletteIdx + i, &color); + } + } + else if (fadeAmount == 0) { + // Fully faded to target color + color = RGB_TO_GBA2(fadeRGB.c[RGB_R], fadeRGB.c[RGB_G], fadeRGB.c[RGB_B]); + for (i = 0; i < 16; paletteRGB++, i++) { + SetBGPaletteBufferColor(basePaletteIdx + i, &color); + } + } + else { + // Blend + u16 invFade = 256 - fadeAmount; + s32 invFadeR = fadeRGB.c[RGB_R] * invFade; + s32 invFadeG = fadeRGB.c[RGB_G] * invFade; + s32 invFadeB = fadeRGB.c[RGB_B] * invFade; + for (i = 0; i < 16; paletteRGB++, i++) { + color = RGB_TO_GBA((paletteRGB->c[RGB_R] * fadeAmount + invFadeR) / 256, + (paletteRGB->c[RGB_G] * fadeAmount + invFadeG) / 256, + (paletteRGB->c[RGB_B] * fadeAmount + invFadeB) / 256); + SetBGPaletteBufferColor(basePaletteIdx + i, &color); + } + } +} + +static void FadeToBlackSingle(u16 fadeIdx, u16 targetIdx) +{ + u16 color; + PaletteFadeEntry *fade = &sPaletteFadeTable[fadeIdx]; + u16 fadeAmount = fade->fadeAmount; + RGB_Array fadeRGB = fade->fadeColor; + + if (fadeAmount >= MAX_FADE_AMOUNT) { + color = RGB_TO_GBA2(fadeRGB.c[RGB_R], fadeRGB.c[RGB_G], fadeRGB.c[RGB_B]); + } + else if (fadeAmount == 0) { + color = RGB_BLACK; + } + else { + color = RGB_TO_GBA((fadeRGB.c[RGB_R] * fadeAmount) / 256, + (fadeRGB.c[RGB_G] * fadeAmount) / 256, + (fadeRGB.c[RGB_B] * fadeAmount) / 256); + } + + SetBGPaletteBufferColor(targetIdx, &color); +} + +static void FadeToBlackRow(u16 fadeIdx) +{ + u16 color; + s32 i; + PaletteFadeEntry *fade = &sPaletteFadeTable[fadeIdx]; + u16 fadeAmount = fade->fadeAmount; + RGB_Array fadeColor = fade->fadeColor; + u16 targetStartIdx = fadeIdx * 16; + + if (fadeAmount >= MAX_FADE_AMOUNT) { + color = RGB_TO_GBA2(fadeColor.c[RGB_R], fadeColor.c[RGB_G], fadeColor.c[RGB_B]); + } + else if (fadeAmount == 0) { + color = RGB_BLACK; + } + else { + color = RGB_TO_GBA((fadeColor.c[RGB_R] * fadeAmount) / 256, + (fadeColor.c[RGB_G] * fadeAmount) / 256, + (fadeColor.c[RGB_B] * fadeAmount) / 256); + } + + for (i = 0; i < 16; i++) { + SetBGPaletteBufferColor(targetStartIdx + i, &color); + } +} + +static void PerEntryBlendSingle(u16 fadeIdx, u16 targetIdx) +{ + u16 color; + PaletteFadeEntry *fade = &sPaletteFadeTable[fadeIdx]; + u16 fadeAmount = fade->fadeAmount; + RGB_Array *fadeSubColor = &fade->fadeColorArray[targetIdx % 16]; + RGB_Array *baseColor = &sRGBPaletteBuffer[targetIdx].asArr; + + if (fadeAmount >= MAX_FADE_AMOUNT) { + color = RGB_TO_GBA2(baseColor->c[RGB_R], baseColor->c[RGB_G], baseColor->c[RGB_B]); + } + else if (fadeAmount == 0) { + color = RGB_TO_GBA2(fadeSubColor->c[RGB_R], fadeSubColor->c[RGB_G], fadeSubColor->c[RGB_B]); + } + else { + u16 invFade = 256 - fadeAmount; + s32 r = fadeSubColor->c[RGB_R] * invFade + baseColor->c[RGB_R] * fadeAmount; + s32 g = fadeSubColor->c[RGB_G] * invFade + baseColor->c[RGB_G] * fadeAmount; + s32 b = fadeSubColor->c[RGB_B] * invFade + baseColor->c[RGB_B] * fadeAmount; + color = RGB_TO_GBA2(r / 256, g / 256, b / 256); + } + + SetBGPaletteBufferColor(targetIdx, &color); +} + +static void PerEntryBlendRow(u16 fadeIdx) +{ + u16 color; + s32 i; + PaletteFadeEntry *fade = &sPaletteFadeTable[fadeIdx]; + u16 fadeAmount = fade->fadeAmount; + RGB_Array *fadeColors = fade->fadeColorArray; + u16 targetStartIdx = fadeIdx * 16; + RGB_Array *baseColors = &sRGBPaletteBuffer[targetStartIdx].asArr; + + if (fadeAmount >= MAX_FADE_AMOUNT) { + // Fully use base palette + for (i = 0; i < 16; baseColors++, i++) { + color = RGB_TO_GBA(baseColors->c[RGB_R], baseColors->c[RGB_G], baseColors->c[RGB_B]); + ASM_MATCH_TRICK(i); + SetBGPaletteBufferColor(targetStartIdx + i, &color); + } + } + else if (fadeAmount == 0) { + // Fully use fade palette + for (i = 0; i < 16; fadeColors++, i++) { + color = RGB_TO_GBA(fadeColors->c[RGB_R], fadeColors->c[RGB_G], fadeColors->c[RGB_B]); + SetBGPaletteBufferColor(targetStartIdx + i, &color); + } + } + else { + // Blend fade and base + u16 invFade = 256 - fadeAmount; + + for (i = 0; i < 16; baseColors++, fadeColors++, i++) { + s32 r = fadeColors->c[RGB_R] * invFade + baseColors->c[RGB_R] * fadeAmount; + s32 g = fadeColors->c[RGB_G] * invFade + baseColors->c[RGB_G] * fadeAmount; + s32 b = fadeColors->c[RGB_B] * invFade + baseColors->c[RGB_B] * fadeAmount; + color = RGB_TO_GBA(r / 256, g / 256, b / 256); + SetBGPaletteBufferColor(targetStartIdx + i, &color); + } + } +} + +static void DesaturateSingle(u16 fadeIndex, u16 targetIndex) +{ + u16 color; + PaletteFadeEntry *fade = &sPaletteFadeTable[fadeIndex]; + u16 fadeAmount = fade->fadeAmount; + RGB_Array fadeColor = fade->fadeColor; + RGB_Array *baseColor = &sRGBPaletteBuffer[targetIndex].asArr; + + if (fadeAmount >= MAX_FADE_AMOUNT) { + // No fade, just use base color + color = RGB_TO_GBA2(baseColor->c[RGB_R], baseColor->c[RGB_G], baseColor->c[RGB_B] ); + } + else { + u16 r, g, b; + // Fading to black per channel + + r = fadeColor.c[RGB_R] + ((255 - fadeColor.c[RGB_R]) * fadeAmount) / 256; + g = fadeColor.c[RGB_G] + ((255 - fadeColor.c[RGB_G]) * fadeAmount) / 256; + b = fadeColor.c[RGB_B] + ((255 - fadeColor.c[RGB_B]) * fadeAmount) / 256; + + color = RGB_TO_GBA2((r * baseColor->c[RGB_R]) / 255, (g * baseColor->c[RGB_G]) / 255, (b * baseColor->c[RGB_B]) / 255); + } + + SetBGPaletteBufferColor(targetIndex, &color); +} + +static void DesaturateRow(u16 fadeIndex) +{ + s32 i; + u16 color; + PaletteFadeEntry *fade = &sPaletteFadeTable[fadeIndex]; + u16 fadeAmount = fade->fadeAmount; + RGB_Array fadeColor = fade->fadeColor; + u16 targetIndex = fadeIndex * 16; + RGB_Array *baseColor = &sRGBPaletteBuffer[targetIndex].asArr; + + if (fadeAmount >= MAX_FADE_AMOUNT) { + for (i = 0; i < 16; baseColor++, i++) { + // No fade, just use base color + color = RGB_TO_GBA(baseColor->c[RGB_R], baseColor->c[RGB_G], baseColor->c[RGB_B]); + SetBGPaletteBufferColor(targetIndex + i, &color); + } + } + else { + u16 r, g, b; + // Fading to black per channel + + r = fadeColor.c[RGB_R] + ((255 - fadeColor.c[RGB_R]) * fadeAmount) / 256; + g = fadeColor.c[RGB_G] + ((255 - fadeColor.c[RGB_G]) * fadeAmount) / 256; + b = fadeColor.c[RGB_B] + ((255 - fadeColor.c[RGB_B]) * fadeAmount) / 256; + for (i = 0; i < 16; baseColor++, i++) { + color = RGB_TO_GBA((r * baseColor->c[RGB_R]) / 255, (g * baseColor->c[RGB_G]) / 255, (b * baseColor->c[RGB_B]) / 255); + SetBGPaletteBufferColor(targetIndex + i, &color); + } + } +} + +static void ModulatePaletteSingle(u16 fadeIndex, u16 paletteIndex) +{ + u16 color; + u16 r, g, b; + PaletteFadeEntry *fade = &sPaletteFadeTable[fadeIndex]; + u16 fadeAmount = fade->fadeAmount; + RGB_Array fadeColor = fade->fadeColor; + RGB_Array *baseColor = &sRGBPaletteBuffer[paletteIndex].asArr; + + if (fadeAmount >= MAX_FADE_AMOUNT) + fadeAmount = MAX_FADE_AMOUNT; + + r = fadeColor.c[RGB_R] * fadeAmount / 256; + g = fadeColor.c[RGB_G] * fadeAmount / 256; + b = fadeColor.c[RGB_B] * fadeAmount / 256; + color = RGB_TO_GBA2((r * baseColor->c[RGB_R]) / 255, (g * baseColor->c[RGB_G]) / 255, (b * baseColor->c[RGB_B]) / 255); + SetBGPaletteBufferColor(paletteIndex, &color); +} + +static void ModulatePaletteRow(u16 fadeIndex) +{ + s32 i; + u16 color; + u16 r, g, b; + PaletteFadeEntry *fade = &sPaletteFadeTable[fadeIndex]; + u16 fadeAmount = fade->fadeAmount; + RGB_Array fadeColor = fade->fadeColor; + u16 paletteIndex = fadeIndex * 16; + RGB_Array *baseColors = &sRGBPaletteBuffer[paletteIndex].asArr; + + if (fadeAmount >= MAX_FADE_AMOUNT) + fadeAmount = MAX_FADE_AMOUNT; + + r = fadeColor.c[RGB_R] * fadeAmount / 256; + g = fadeColor.c[RGB_G] * fadeAmount / 256; + b = fadeColor.c[RGB_B] * fadeAmount / 256; + for (i = 0; i < 16; baseColors++, i++) { + color = RGB_TO_GBA2((r * baseColors->c[RGB_R]) / 255, (g * baseColors->c[RGB_G]) / 255, (b * baseColors->c[RGB_B]) / 255); + SetBGPaletteBufferColor(paletteIndex + i, &color); + } +} diff --git a/src/palette_util.c b/src/palette_util.c index 4289448e9..116dfc7ba 100644 --- a/src/palette_util.c +++ b/src/palette_util.c @@ -2,14 +2,9 @@ #include "globaldata.h" #include "palette_util.h" #include "bg_palette_buffer.h" +#include "palette_fade_util.h" -extern void sub_80039B8(void); extern void TransferBGPaletteBuffer(void); -extern void sub_80037C8(u16, u32, RGB_Array); -extern void sub_8003664(u16 param_1, u16 param_2); -extern void sub_80036AC(u16, u32, RGB_Array); -extern void sub_80036F4(u16, u32, RGB_Array); -extern void sub_8003780(u16, u32, RGB_Array); struct UnkStruct_2039958 { @@ -45,7 +40,7 @@ static void sub_8099E80(u16 a0, RGB_Array a1); void sub_8099744(void) { - sub_80039B8(); + RunPaletteFadeFunctions(); } void sub_8099750(void) @@ -419,30 +414,30 @@ static void sub_8099DD0(u16 a0) for (i = 0; i < 14; i++) { if (gUnknown_2039998[i] & 1) { - sub_8003664(i, 0x100); + SetPaletteFade_Brightness(i, 0x100); } else { - sub_8003664(i, a0); + SetPaletteFade_Brightness(i, a0); } } for (i = 16; i < 31; i++) { if (gUnknown_2039998[i] & 1) { - sub_8003664(i, 0x100); + SetPaletteFade_Brightness(i, 0x100); } else { - sub_8003664(i, a0); + SetPaletteFade_Brightness(i, a0); } } - sub_8003664(32, a0); + SetPaletteFade_Brightness(32, a0); } static void sub_8099E58(u16 a0) { - sub_8003664(15, a0); - sub_8003664(14, a0); - sub_8003664(31, a0); + SetPaletteFade_Brightness(15, a0); + SetPaletteFade_Brightness(14, a0); + SetPaletteFade_Brightness(31, a0); } static void sub_8099E80(u16 param_1,RGB_Array param_2) @@ -455,221 +450,221 @@ static void sub_8099E80(u16 param_1,RGB_Array param_2) case 1: for (i = 0; i < 16; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_80036AC(i,param_1,param_2); + SetPaletteFade_Blend(i,param_1,param_2); } } for (i = 16; i < 32; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_80036AC(i,param_1,param_2); + SetPaletteFade_Blend(i,param_1,param_2); } } break; case 9: for (i = 14; i < 16; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_80036AC(i,param_1,param_2); + SetPaletteFade_Blend(i,param_1,param_2); } } for (i = 31; i < 32; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_80036AC(i,param_1,param_2); + SetPaletteFade_Blend(i,param_1,param_2); } } break; case 5: for (i = 0; i < 14; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_80036AC(i,param_1,param_2); + SetPaletteFade_Blend(i,param_1,param_2); } } for (i = 16; i < 31; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_80036AC(i,param_1,param_2); + SetPaletteFade_Blend(i,param_1,param_2); } } break; case 2: for (i = 0; i < 16; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_80036F4(i,param_1,param_2); + SetPaletteFade_FadeToBlack(i,param_1,param_2); } } for (i = 16; i < 32; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_80036F4(i,param_1,param_2); + SetPaletteFade_FadeToBlack(i,param_1,param_2); } } break; case 10: for (i = 14; i < 16; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_80036F4(i,param_1,param_2); + SetPaletteFade_FadeToBlack(i,param_1,param_2); } } for (i = 31; i < 32; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_80036F4(i,param_1,param_2); + SetPaletteFade_FadeToBlack(i,param_1,param_2); } } break; case 6: for (i = 0; i < 14; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_80036F4(i,param_1,param_2); + SetPaletteFade_FadeToBlack(i,param_1,param_2); } } for (i = 16; i < 31; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_80036F4(i,param_1,param_2); + SetPaletteFade_FadeToBlack(i,param_1,param_2); } } break; case 3: for (i = 0; i < 16; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_8003780(i,param_1,param_2); + SetPaletteFade_Desaturate(i,param_1,param_2); } } for (i = 16; i < 32; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_8003780(i,param_1,param_2); + SetPaletteFade_Desaturate(i,param_1,param_2); } } break; case 11: for (i = 14; i < 16; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_8003780(i,param_1,param_2); + SetPaletteFade_Desaturate(i,param_1,param_2); } } for (i = 31; i < 32; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_8003780(i,param_1,param_2); + SetPaletteFade_Desaturate(i,param_1,param_2); } } break; case 7: for (i = 0; i < 14; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_8003780(i,param_1,param_2); + SetPaletteFade_Desaturate(i,param_1,param_2); } } for (i = 16; i < 31; i++) { if (gUnknown_2039998[i] & 2) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else { - sub_8003780(i,param_1,param_2); + SetPaletteFade_Desaturate(i,param_1,param_2); } } break; case 4: for (i = 0; i < 16; i ++) { if (gUnknown_2039998[i] & 1) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else if (gUnknown_2039998[i] & 2) { - sub_8003664(i,param_1); + SetPaletteFade_Brightness(i,param_1); } else { - sub_80037C8(i,param_1,param_2); + SetPaletteFade_Modulate(i,param_1,param_2); } } for (i = 16; i < 32; i ++) { if (gUnknown_2039998[i] & 1) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else if (gUnknown_2039998[i] & 2) { - sub_8003664(i,param_1); + SetPaletteFade_Brightness(i,param_1); } else { - sub_80037C8(i,param_1,param_2); + SetPaletteFade_Modulate(i,param_1,param_2); } } break; case 12: for (i = 14; i < 16; i ++) { if (gUnknown_2039998[i] & 1) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else if (gUnknown_2039998[i] & 2) { - sub_8003664(i,param_1); + SetPaletteFade_Brightness(i,param_1); } else { - sub_80037C8(i,param_1,param_2); + SetPaletteFade_Modulate(i,param_1,param_2); } } for (i = 31; i < 32; i ++) { if (gUnknown_2039998[i] & 1) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else if (gUnknown_2039998[i] & 2) { - sub_8003664(i,param_1); + SetPaletteFade_Brightness(i,param_1); } else { - sub_80037C8(i,param_1,param_2); + SetPaletteFade_Modulate(i,param_1,param_2); } } break; @@ -693,25 +688,25 @@ static void sub_8099E80(u16 param_1,RGB_Array param_2) case 8: for (i = 0; i < 14; i ++) { if (gUnknown_2039998[i] & 1) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else if (gUnknown_2039998[i] & 2) { - sub_8003664(i,param_1); + SetPaletteFade_Brightness(i,param_1); } else { - sub_80037C8(i,param_1,param_2); + SetPaletteFade_Modulate(i,param_1,param_2); } } for (i = 16; i < 31; i ++) { if (gUnknown_2039998[i] & 1) { - sub_8003664(i,0x100); + SetPaletteFade_Brightness(i,0x100); } else if (gUnknown_2039998[i] & 2) { - sub_8003664(i,param_1); + SetPaletteFade_Brightness(i,param_1); } else { - sub_80037C8(i,param_1,param_2); + SetPaletteFade_Modulate(i,param_1,param_2); } } break; diff --git a/sym_iwram.txt b/sym_iwram.txt index 6e0313eea..f13a76370 100644 --- a/sym_iwram.txt +++ b/sym_iwram.txt @@ -1,5 +1,5 @@ .include "src/m4a.o" -.include "src/code_80035F0.o" +.include "src/palette_fade_util.o" .include "src/text_1.o" .include "src/music.o" .include "src/dungeon_tilemap.o" diff --git a/sym_iwram_init.txt b/sym_iwram_init.txt index 46da3a2a3..a3f8f371f 100644 --- a/sym_iwram_init.txt +++ b/sym_iwram_init.txt @@ -1,6 +1,6 @@ .align 2 -.include "src/code_80035F0.o" +.include "src/palette_fade_util.o" .include "src/code_8023144.o" .include "src/friend_list.o" .include "src/textbox.o"