Fixed palette fades during intermediate times of day.

This commit is contained in:
Ariel Antonitis 2021-04-21 02:53:24 -04:00
parent da345c1eeb
commit 4bb7abb520
3 changed files with 68 additions and 21 deletions

View file

@ -28,7 +28,13 @@ enum
struct PaletteFadeControl
{
u32 multipurpose1;
u32 multipurpose1; // This field needs to exist or errors will occur
u16 blendColor1:15;
u16 tint1:1;
u32 tint0:1;
u32 coeff0:5;
u32 coeff1:5;
u32 weight:9;
u8 delayCounter:6;
u16 y:5; // blend coefficient
u16 targetY:5; // target blend coefficient
@ -66,7 +72,7 @@ u8 UpdatePaletteFade(void);
void ResetPaletteFade(void);
void ReadPlttIntoBuffers(void);
bool8 BeginNormalPaletteFade(u32, s8, u8, u8, u16);
bool8 BeginTimeOfDayPaletteFade(u32, s8, u8, u8, u16);
bool8 BeginTimeOfDayPaletteFade(u32, s8, u8, u8, struct BlendSettings *, struct BlendSettings *, u16);
bool8 unref_sub_8073D3C(u32, u8, u8, u8, u16);
void unref_sub_8073D84(u8, u32 *);
void ResetPaletteStructByUid(u16);

View file

@ -1514,7 +1514,10 @@ static bool8 FadePalettesWithTime(void) { // Only used to fade back in
gTimeOfDay = UpdateTimeOfDay();
if (MapHasNaturalLight(gMapHeader.mapType)) {
ResetPaletteFade();
BeginTimeOfDayPaletteFade(0xFFFFFFFF, 0, 16, sTimeOfDayBlendVars[gTimeOfDay].coeff, sTimeOfDayBlendVars[gTimeOfDay].blendColor);
BeginTimeOfDayPaletteFade(0xFFFFFFFF, 0, 16, 0,
(struct BlendSettings *)&sTimeOfDayBlendVars[currentTimeBlend.time0],
(struct BlendSettings *)&sTimeOfDayBlendVars[currentTimeBlend.time1],
currentTimeBlend.weight);
}
}

View file

@ -55,6 +55,7 @@ static u8 UpdateTimeOfDayPaletteFade(void);
static void UpdateBlendRegisters(void);
static bool8 IsSoftwarePaletteFadeFinishing(void);
static void Task_BlendPalettesGradually(u8 taskId);
static void BlendPalettesFine(u32 palettes, u16 *src, u16 *dst, u32 coeff, u32 color);
// palette buffers require alignment with agbcc because
// unaligned word reads are issued in BlendPalette otherwise
@ -204,10 +205,10 @@ bool8 BeginNormalPaletteFade(u32 selectedPalettes, s8 delay, u8 startY, u8 targe
}
// Like normal palette fade but respects sprite/tile palettes immune to time of day fading
bool8 BeginTimeOfDayPaletteFade(u32 selectedPalettes, s8 delay, u8 startY, u8 targetY, u16 blendColor)
// Blend color here is always assumed to be 0 (black).
bool8 BeginTimeOfDayPaletteFade(u32 selectedPalettes, s8 delay, u8 startY, u8 targetY, struct BlendSettings *bld0, struct BlendSettings *bld1, u16 weight)
{
u8 temp;
u16 color = blendColor;
if (gPaletteFade.active)
{
@ -228,10 +229,17 @@ bool8 BeginTimeOfDayPaletteFade(u32 selectedPalettes, s8 delay, u8 startY, u8 ta
gPaletteFade_delay = delay;
gPaletteFade.y = startY;
gPaletteFade.targetY = targetY;
gPaletteFade.blendColor = color;
gPaletteFade.active = 1;
gPaletteFade.mode = TIME_OF_DAY_FADE;
gPaletteFade.blendColor = bld0->blendColor;
gPaletteFade.coeff0 = bld0->coeff;
gPaletteFade.tint0 = bld0->isTint;
gPaletteFade.blendColor1 = bld1->blendColor;
gPaletteFade.coeff1 = bld1->coeff;
gPaletteFade.tint1 = bld1->isTint;
gPaletteFade.weight = weight;
if (startY < targetY)
gPaletteFade.yDec = 0;
else
@ -462,6 +470,12 @@ static u8 UpdateTimeOfDayPaletteFade(void)
u8 paletteNum;
u16 paletteOffset;
u16 selectedPalettes;
u16 timePalettes = 0; // palettes passed to the time-blender
u16 copyPalettes;
u16 * src;
u16 * dst;
struct BlendSettings bld0;
struct BlendSettings bld1;
if (!gPaletteFade.active)
return PALETTE_FADE_STATUS_DONE;
@ -491,22 +505,47 @@ static u8 UpdateTimeOfDayPaletteFade(void)
paletteOffset = 256;
}
for (paletteNum = 0; paletteNum < 16; paletteNum++, selectedPalettes >>= 1, paletteOffset += 16) {
if (selectedPalettes & 1) {
if (gPaletteFade.yDec) {
if (gPaletteFade.objPaletteToggle) { // sprite palettes
if (gPaletteFade.y >= gPaletteFade.targetY || GetSpritePaletteTagByPaletteNum(paletteNum) & 0x8000)
TimeBlendPalette(paletteOffset, gPaletteFade.y, gPaletteFade.blendColor);
// tile palettes
} else if (gPaletteFade.y >= gPaletteFade.targetY || (paletteNum >= 13 && paletteNum <= 15)) {
TimeBlendPalette(paletteOffset, gPaletteFade.y, gPaletteFade.blendColor);
}
} else {
TimeBlendPalette(paletteOffset, gPaletteFade.y, gPaletteFade.blendColor);
}
// Extract blend settings from palette fade struct TODO: Embed struct within gPaletteFade
bld0.blendColor = gPaletteFade.blendColor;
bld0.coeff = gPaletteFade.coeff0;
bld0.isTint = gPaletteFade.tint0;
bld1.blendColor = gPaletteFade.blendColor1;
bld1.coeff = gPaletteFade.coeff1;
bld1.isTint = gPaletteFade.tint1;
src = gPlttBufferUnfaded + paletteOffset;
dst = gPlttBufferFaded + paletteOffset;
// First pply TOD blend to relevant subset of palettes
if (gPaletteFade.objPaletteToggle) { // Sprite palettes, don't blend those with tags
u8 i;
u16 j = 1;
for (i = 0; i < 16; i++, j <<= 1) { // Mask out palettes that should not be light blended
if ((selectedPalettes & j) && !(GetSpritePaletteTagByPaletteNum(i) >> 15))
timePalettes |= j;
}
} else { // tile palettes, don't blend [13, 15]
timePalettes = selectedPalettes &= ~0xE000;
}
TimeMixPalettes(timePalettes, src, dst, &bld0, &bld1, gPaletteFade.weight);
// palettes that were not blended above must be copied through
if ((copyPalettes = ~timePalettes)) {
u16 * src1 = src;
u16 * dst1 = dst;
while (copyPalettes) {
if (copyPalettes & 1)
CpuFastCopy(src1, dst1, 64);
copyPalettes >>= 1;
src1 += 16;
dst1 += 16;
}
}
// Then, blend from faded->faded with native BlendPalettes
BlendPalettesFine(selectedPalettes, dst, dst, gPaletteFade.y, 0);
gPaletteFade.objPaletteToggle ^= 1;
if (!gPaletteFade.objPaletteToggle)
@ -981,8 +1020,7 @@ static void BlendPalettesFine(u32 palettes, u16 *src, u16 *dst, u32 coeff, u32 c
do {
if (palettes & 1) {
u16 *srcEnd = src + 16;
*dst++ = *src++; // transparency is copied-through
while (src != srcEnd) {
while (src != srcEnd) { // Transparency is blended because it can matter for tile palettes
u32 srcColor = *src;
s32 r = (srcColor << 27) >> 27;
s32 g = (srcColor << 22) >> 27;