From e11d050423d13abe773d38716c69628e582b38fd Mon Sep 17 00:00:00 2001 From: Ariel Antonitis Date: Tue, 6 Apr 2021 01:02:37 -0400 Subject: [PATCH] Added weighted palette average. --- include/palette.h | 1 + src/overworld.c | 13 +++++++++++-- src/palette.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/include/palette.h b/include/palette.h index 0be99d3c64..406f56b84a 100644 --- a/include/palette.h +++ b/include/palette.h @@ -76,6 +76,7 @@ void BeginHardwarePaletteFade(u8, u8, u8, u8, u8); void BlendPalettes(u32 selectedPalettes, u8 coeff, u16 color); void BlendPalettesUnfaded(u32, u8, u16); void BlendPalettesGradually(u32 selectedPalettes, s8 delay, u8 coeff, u8 coeffTarget, u16 color, u8 priority, u8 id); +void AveragePalettes(u16 *palette0, u16* palette1, u16* dest, u16 weight); void TimeBlendPalette(u16 palOffset, u16 numEntries, u8 coeff, u16 blendColor); void TintPalette_RGB_Copy(u16 palOffset, u16 numEntries, u8 coeff, u16 blendColor); void TimeBlendPalettes(u32 palettes, u8 coeff, u16 color); diff --git a/src/overworld.c b/src/overworld.c index 6e7542109f..cd1a1df966 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -1496,7 +1496,8 @@ static bool8 FadePalettesWithTime(void) { void UpdatePalettesWithTime(u32 palettes) { // Only blend if not transitioning between times and the map type allows if (gTimeOfDayState == 0 && MapHasNaturalLight(gMapHeader.mapType)) { - u8 i; + u8 i, j; + u16 tempPaletteBuffer[16]; for (i = 0; i < 16; i++) { if (GetSpritePaletteTagByPaletteNum(i) & 0x8000) // Don't blend special sprite palette tags palettes &= ~(1 << (i + 16)); @@ -1505,7 +1506,15 @@ void UpdatePalettesWithTime(u32 palettes) { gTimeOfDay = min(TIME_OF_DAY_MAX, gTimeOfDay); if (!palettes) return; - TimeBlendPalettes(palettes, sTimeOfDayBlendVars[gTimeOfDay].coeff, sTimeOfDayBlendVars[gTimeOfDay].blendColor); + for (i = 0; palettes; i++) { + if (palettes & 1) { + TimeBlendPalette(i*16, 16, sTimeOfDayBlendVars[gTimeOfDay].coeff, sTimeOfDayBlendVars[gTimeOfDay].blendColor); + CpuFastCopy(&gPlttBufferFaded[i*16], tempPaletteBuffer, 32); + TimeBlendPalette(i*16, 16, sTimeOfDayBlendVars[TIME_OF_DAY_TWILIGHT].coeff, sTimeOfDayBlendVars[TIME_OF_DAY_TWILIGHT].blendColor); + AveragePalettes(tempPaletteBuffer, &gPlttBufferFaded[i*16], &gPlttBufferFaded[i*16], 256); + } + palettes >>= 1; + } } } diff --git a/src/palette.c b/src/palette.c index 34cf0286da..a285a48257 100644 --- a/src/palette.c +++ b/src/palette.c @@ -978,6 +978,35 @@ void BlendPalettes(u32 selectedPalettes, u8 coeff, u16 color) } } +// Computes a weighted average of two palettes, as (p0*weight + (256-weight)*p1)/256 +void AveragePalettes(u16 *palette0, u16* palette1, u16* dest, u16 weight) { + u8 i; + u32 tempColor; + u16 r0, g0, b0, r1, g1, b1, r, g, b; + u16 color0, color1, destColor; + *dest++ = *palette0++; // Copy palette0's transparency color as is + palette1++; + for (i = 1; i < 16; i++) { // Skip transparent color + color0 = *palette0++; + color1 = *palette1++; + r0 = color0 & 0x1F; + g0 = (color0 >> 5) & 0x1F; + b0 = (color0 >> 10) & 0x1F; + r1 = color1 & 0x1F; + g1 = (color1 >> 5) & 0x1F; + b1 = (color1 >> 10) & 0x1F; + r = (weight*r0 + (256-weight)*r1) >> 8; + g = (weight*g0 + (256-weight)*g1) >> 8; + b = (weight*b0 + (256-weight)*b1) >> 8; + r = r > 31 ? 31 : r; + g = g > 31 ? 31 : g; + b = b > 31 ? 31 : b; + destColor = (color0 | color1) & 0x8000; + destColor += r + (g << 5) + (b << 10); + *dest++ = destColor; + } +} + #define DEFAULT_LIGHT_COLOR 0x3f9f // Like BlendPalette, but ignores blendColor if the transparency high bit is set