This commit is contained in:
SiliconA-Z 2026-04-23 14:33:20 -04:00 committed by GitHub
commit d024f47680
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 189 additions and 183 deletions

View File

@ -19,9 +19,9 @@ struct PulseBlendPalette
u8 paletteSelector;
u8 blendCoeff:4;
u8 fadeDirection:1;
s8 unk1_5:1;
s8 available:1;
u32 inUse:1;
u8 flags:1;
u8 available:1;
u8 inUse:1;
u8 delayCounter;
u8 fadeCycleCounter;
struct PulseBlendSettings pulseBlendSettings;
@ -53,7 +53,7 @@ struct RouletteFlashPalette
u8 state:7;
bool8 available:1;
u8 delayCounter;
s8 fadeCycleCounter;
u8 fadeCycleCounter;
s8 colorDelta;
struct RouletteFlashSettings settings;
};
@ -61,19 +61,18 @@ struct RouletteFlashPalette
struct RouletteFlashUtil
{
u8 enabled;
u8 unused;
u16 flags;
struct RouletteFlashPalette palettes[16];
};
int InitPulseBlendPaletteSettings(struct PulseBlend *pulseBlend, const struct PulseBlendSettings *settings);
u8 InitPulseBlendPaletteSettings(struct PulseBlend *pulseBlend, const struct PulseBlendSettings *settings);
void InitPulseBlend(struct PulseBlend *pulseBlend);
void MarkUsedPulseBlendPalettes(struct PulseBlend *pulseBlend, u16 pulseBlendPaletteSelector, u8 multiSelection);
void UnloadUsedPulseBlendPalettes(struct PulseBlend *pulseBlend, u16 pulseBlendPaletteSelector, u8 multiSelection);
void UnmarkUsedPulseBlendPalettes(struct PulseBlend *pulseBlend, u16 pulseBlendPaletteSelector, u8 multiSelection);
void UpdatePulseBlend(struct PulseBlend *pulseBlend);
void FillTilemapRect(u16 *dest, u16 value, u8 left, u8 top, u8 width, u8 height);
void SetTilemapRect(u16 *dest, u16 *src, u8 left, u8 top, u8 width, u8 height);
void SetTilemapRect(u16 *dest, const u16 *src, u8 left, u8 top, u8 width, u8 height);
void RouletteFlash_Run(struct RouletteFlashUtil *flash);
void RouletteFlash_Reset(struct RouletteFlashUtil *flash);
u8 RouletteFlash_Add(struct RouletteFlashUtil *flash, u8 id, const struct RouletteFlashSettings *settings);

View File

@ -52,23 +52,23 @@ static u8 UNUSED RouletteFlash_Remove(struct RouletteFlashUtil *flash, u8 id)
static u8 RouletteFlash_FadePalette(struct RouletteFlashPalette *pal)
{
u8 i;
u8 returnval;
u8 i = 0;
struct PlttData *faded, *unfaded;
for (i = 0; i < pal->settings.numColors; i++)
{
struct PlttData *faded = (struct PlttData *)&gPlttBufferFaded[pal->settings.paletteOffset + i];
struct PlttData *unfaded = (struct PlttData *)&gPlttBufferUnfaded[pal->settings.paletteOffset + i];
faded = (struct PlttData *)&gPlttBufferFaded[pal->settings.paletteOffset + i];
unfaded = (struct PlttData *)&gPlttBufferUnfaded[pal->settings.paletteOffset + i];
switch (pal->state)
{
case 1:
// Fade color
if (faded->r + pal->colorDelta >= 0 && faded->r + pal->colorDelta < 32)
if (faded->r + pal->colorDelta < 32 && faded->r + pal->colorDelta >= 0)
faded->r += pal->colorDelta;
if (faded->g + pal->colorDelta >= 0 && faded->g + pal->colorDelta < 32)
if (faded->g + pal->colorDelta < 32 && faded->g + pal->colorDelta >= 0)
faded->g += pal->colorDelta;
if (faded->b + pal->colorDelta >= 0 && faded->b + pal->colorDelta < 32)
if (faded->b + pal->colorDelta < 32 && faded->b + pal->colorDelta >= 0)
faded->b += pal->colorDelta;
break;
case 2:
@ -94,21 +94,18 @@ static u8 RouletteFlash_FadePalette(struct RouletteFlashPalette *pal)
break;
}
}
if ((u32)pal->fadeCycleCounter++ != pal->settings.numFadeCycles)
{
returnval = 0;
}
if (pal->fadeCycleCounter++ != (u8)pal->settings.numFadeCycles)
return 0;
pal->fadeCycleCounter = 0;
pal->colorDelta *= -1;
if (pal->state == 1)
pal->state++;
else
{
pal->fadeCycleCounter = 0;
pal->colorDelta *= -1;
if (pal->state == 1)
pal->state++;
else
pal->state--;
returnval = 1;
}
return returnval;
pal->state--;
return 1;
}
static u8 RouletteFlash_FlashPalette(struct RouletteFlashPalette *pal)
@ -118,14 +115,15 @@ static u8 RouletteFlash_FlashPalette(struct RouletteFlashPalette *pal)
{
case 1:
// Flash to color
for (; i < pal->settings.numColors; i++)
for (i = 0; i < pal->settings.numColors; i++)
gPlttBufferFaded[pal->settings.paletteOffset + i] = pal->settings.color;
pal->state++;
break;
case 2:
// Restore to original color
for (; i < pal->settings.numColors; i++)
gPlttBufferFaded[pal->settings.paletteOffset + i] = gPlttBufferUnfaded[pal->settings.paletteOffset + i];
for (i = 0; i < pal->settings.numColors; i++)
gPlttBufferFaded[pal->settings.paletteOffset + i] =
gPlttBufferUnfaded[pal->settings.paletteOffset + i];
pal->state--;
break;
}
@ -136,22 +134,22 @@ void RouletteFlash_Run(struct RouletteFlashUtil *flash)
{
u8 i = 0;
if (flash->enabled)
{
for (i = 0; i < ARRAY_COUNT(flash->palettes); i++)
{
if ((flash->flags >> i) & 1)
{
if (--flash->palettes[i].delayCounter == (u8)-1)
{
if (flash->palettes[i].settings.color & FLASHUTIL_USE_EXISTING_COLOR)
RouletteFlash_FadePalette(&flash->palettes[i]);
else
RouletteFlash_FlashPalette(&flash->palettes[i]);
if (!flash->enabled)
return;
flash->palettes[i].delayCounter = flash->palettes[i].settings.delay;
}
}
for (i = 0; i < ARRAY_COUNT(flash->palettes); i++)
{
if (!((flash->flags >> i) & 1))
continue;
if (flash->palettes[i].delayCounter-- == 0)
{
if (flash->palettes[i].settings.color & FLASHUTIL_USE_EXISTING_COLOR)
RouletteFlash_FadePalette(&flash->palettes[i]);
else
RouletteFlash_FlashPalette(&flash->palettes[i]);
flash->palettes[i].delayCounter = flash->palettes[i].settings.delay;
}
}
}
@ -186,10 +184,10 @@ void RouletteFlash_Stop(struct RouletteFlashUtil *flash, u16 flags)
{
if ((flags >> i) & 1)
{
u32 offset = flash->palettes[i].settings.paletteOffset;
u16 *faded = &gPlttBufferFaded[offset];
u16 *unfaded = &gPlttBufferUnfaded[offset];
memcpy(faded, unfaded, flash->palettes[i].settings.numColors * 2);
memcpy(&gPlttBufferFaded[flash->palettes[i].settings.paletteOffset],
&gPlttBufferUnfaded[flash->palettes[i].settings.paletteOffset],
flash->palettes[i].settings.numColors * 2);
flash->palettes[i].state = 0;
flash->palettes[i].fadeCycleCounter = 0;
flash->palettes[i].delayCounter = 0;
@ -218,32 +216,25 @@ void InitPulseBlend(struct PulseBlend *pulseBlend)
{
u8 i = 0;
pulseBlend->usedPulseBlendPalettes = 0;
memset(&pulseBlend->pulseBlendPalettes, 0, sizeof(pulseBlend->pulseBlendPalettes));
for (; i < 16; i++)
memset(pulseBlend->pulseBlendPalettes, 0, sizeof(pulseBlend->pulseBlendPalettes));
for (i = 0; i < ARRAY_COUNT(pulseBlend->pulseBlendPalettes); i++)
pulseBlend->pulseBlendPalettes[i].paletteSelector = i;
}
int InitPulseBlendPaletteSettings(struct PulseBlend *pulseBlend, const struct PulseBlendSettings *settings)
u8 InitPulseBlendPaletteSettings(
struct PulseBlend *pulseBlend, const struct PulseBlendSettings *settings)
{
u8 i = 0;
struct PulseBlendPalette *pulseBlendPalette = NULL;
if (!pulseBlend->pulseBlendPalettes[0].inUse)
for (i = 0; i < ARRAY_COUNT(pulseBlend->pulseBlendPalettes); i++)
{
pulseBlendPalette = &pulseBlend->pulseBlendPalettes[0];
}
else
{
while (++i < 16)
if (!pulseBlend->pulseBlendPalettes[i].inUse)
{
if (!pulseBlend->pulseBlendPalettes[i].inUse)
{
pulseBlendPalette = &pulseBlend->pulseBlendPalettes[i];
break;
}
pulseBlendPalette = &pulseBlend->pulseBlendPalettes[i];
break;
}
}
if (pulseBlendPalette == NULL)
return 0xFF;
@ -270,7 +261,7 @@ static void ClearPulseBlendPalettesSettings(struct PulseBlendPalette *pulseBlend
memset(&pulseBlendPalette->pulseBlendSettings, 0, sizeof(pulseBlendPalette->pulseBlendSettings));
pulseBlendPalette->blendCoeff = 0;
pulseBlendPalette->fadeDirection = 0;
pulseBlendPalette->unk1_5 = 0;
pulseBlendPalette->flags = 0;
pulseBlendPalette->available = 1;
pulseBlendPalette->inUse = 0;
pulseBlendPalette->fadeCycleCounter = 0;
@ -284,16 +275,15 @@ void UnloadUsedPulseBlendPalettes(struct PulseBlend *pulseBlend, u16 pulseBlendP
if (!multiSelection)
{
ClearPulseBlendPalettesSettings(&pulseBlend->pulseBlendPalettes[pulseBlendPaletteSelector & 0xF]);
return;
}
else
{
for (i = 0; i < 16; i++)
{
if ((pulseBlendPaletteSelector & 1) && pulseBlend->pulseBlendPalettes[i].inUse)
ClearPulseBlendPalettesSettings(&pulseBlend->pulseBlendPalettes[i]);
pulseBlendPaletteSelector >>= 1;
}
for (i = 0; i < ARRAY_COUNT(pulseBlend->pulseBlendPalettes); i++)
{
if ((pulseBlendPaletteSelector & 1) && pulseBlend->pulseBlendPalettes[i].inUse)
ClearPulseBlendPalettesSettings(&pulseBlend->pulseBlendPalettes[i]);
pulseBlendPaletteSelector >>= 1;
}
}
@ -306,146 +296,164 @@ void MarkUsedPulseBlendPalettes(struct PulseBlend *pulseBlend, u16 pulseBlendPal
i = pulseBlendPaletteSelector & 0xF;
pulseBlend->pulseBlendPalettes[i].available = 0;
pulseBlend->usedPulseBlendPalettes |= 1 << i;
return;
}
else
for (i = 0; i < ARRAY_COUNT(pulseBlend->pulseBlendPalettes); i++)
{
for (i = 0; i < 16; i++)
if (!(pulseBlendPaletteSelector & 1) || !pulseBlend->pulseBlendPalettes[i].inUse ||
!pulseBlend->pulseBlendPalettes[i].available)
{
if (!(pulseBlendPaletteSelector & 1) || !pulseBlend->pulseBlendPalettes[i].inUse || !pulseBlend->pulseBlendPalettes[i].available)
{
pulseBlendPaletteSelector <<= 1;
}
else
{
pulseBlend->pulseBlendPalettes[i].available = 0;
pulseBlend->usedPulseBlendPalettes |= 1 << i;
}
pulseBlendPaletteSelector <<= 1;
continue;
}
pulseBlend->pulseBlendPalettes[i].available = 0;
pulseBlend->usedPulseBlendPalettes |= 1 << i;
}
}
void UnmarkUsedPulseBlendPalettes(struct PulseBlend *pulseBlend, u16 pulseBlendPaletteSelector, u8 multiSelection)
{
u16 i;
struct PulseBlendPalette *pulseBlendPalette;
u8 j = 0;
struct PulseBlendPalette *pulseBlendPalette;
u16 i = 0;
if (!multiSelection)
{
// BUG: We do not unmark the palette the way we mark it.
#ifdef BUGFIX
j = pulseBlendPaletteSelector & 0xF;
pulseBlendPalette = &pulseBlend->pulseBlendPalettes[j];
#else
pulseBlendPalette = &pulseBlend->pulseBlendPalettes[pulseBlendPaletteSelector & 0xF];
if (!pulseBlendPalette->available && pulseBlendPalette->inUse)
{
if (pulseBlendPalette->pulseBlendSettings.restorePaletteOnUnload)
{
for (i = pulseBlendPalette->pulseBlendSettings.paletteOffset; i < pulseBlendPalette->pulseBlendSettings.paletteOffset + pulseBlendPalette->pulseBlendSettings.numColors; i++)
gPlttBufferFaded[i] = gPlttBufferUnfaded[i];
}
#endif
if (pulseBlendPalette->inUse == 0 || pulseBlendPalette->available)
return;
pulseBlendPalette->available = 1;
pulseBlend->usedPulseBlendPalettes &= ~(1 << j);
if (pulseBlendPalette->pulseBlendSettings.restorePaletteOnUnload)
{
for (i = pulseBlendPalette->pulseBlendSettings.paletteOffset; i < pulseBlendPalette->pulseBlendSettings.paletteOffset + pulseBlendPalette->pulseBlendSettings.numColors; i++)
gPlttBufferFaded[i] = gPlttBufferUnfaded[i];
}
pulseBlendPalette->available = 1;
pulseBlend->usedPulseBlendPalettes &= ~(1 << j);
return;
}
else
{
for (j = 0; j < 16; j++)
{
pulseBlendPalette = &pulseBlend->pulseBlendPalettes[j];
if (!(pulseBlendPaletteSelector & 1) || pulseBlendPalette->available || !pulseBlendPalette->inUse)
{
pulseBlendPaletteSelector <<= 1;
}
else
{
if (pulseBlendPalette->pulseBlendSettings.restorePaletteOnUnload)
{
for (i = pulseBlendPalette->pulseBlendSettings.paletteOffset; i < pulseBlendPalette->pulseBlendSettings.paletteOffset + pulseBlendPalette->pulseBlendSettings.numColors; i++)
gPlttBufferFaded[i] = gPlttBufferUnfaded[i];
}
pulseBlendPalette->available = 1;
pulseBlend->usedPulseBlendPalettes &= ~(1 << j);
}
for (j = 0; j < ARRAY_COUNT(pulseBlend->pulseBlendPalettes); j++)
{
pulseBlendPalette = &pulseBlend->pulseBlendPalettes[j];
if (!(pulseBlendPaletteSelector & 1) || !pulseBlendPalette->inUse || pulseBlendPalette->available)
{
pulseBlendPaletteSelector <<= 1;
continue;
}
if (pulseBlendPalette->pulseBlendSettings.restorePaletteOnUnload)
{
for (i = pulseBlendPalette->pulseBlendSettings.paletteOffset; i < pulseBlendPalette->pulseBlendSettings.paletteOffset + pulseBlendPalette->pulseBlendSettings.numColors; i++)
gPlttBufferFaded[i] = gPlttBufferUnfaded[i];
}
pulseBlendPalette->available = 1;
pulseBlend->usedPulseBlendPalettes &= ~(1 << j);
}
}
void UpdatePulseBlend(struct PulseBlend *pulseBlend)
{
struct PulseBlendPalette *pulseBlendPalette;
u8 i = 0;
u8 j = 0;
struct PulseBlendPalette *pulseBlendPalette = NULL;
if (pulseBlend->usedPulseBlendPalettes)
if (!pulseBlend->usedPulseBlendPalettes)
return;
for (i = 0; i < ARRAY_COUNT(pulseBlend->pulseBlendPalettes); i++)
{
for (i = 0; i < 16; i++)
pulseBlendPalette = &pulseBlend->pulseBlendPalettes[i];
if (!pulseBlendPalette->inUse || pulseBlendPalette->available)
continue;
if (gPaletteFade.active && pulseBlendPalette->pulseBlendSettings.unk7_7)
continue;
if (pulseBlendPalette->delayCounter-- != 0)
continue;
pulseBlendPalette->delayCounter = pulseBlendPalette->pulseBlendSettings.delay;
BlendPalette(pulseBlendPalette->pulseBlendSettings.paletteOffset,
pulseBlendPalette->pulseBlendSettings.numColors,
(u16)pulseBlendPalette->blendCoeff,
pulseBlendPalette->pulseBlendSettings.blendColor);
switch (pulseBlendPalette->pulseBlendSettings.fadeType)
{
pulseBlendPalette = &pulseBlend->pulseBlendPalettes[i];
if ((!pulseBlendPalette->available && pulseBlendPalette->inUse) && (!gPaletteFade.active || !pulseBlendPalette->pulseBlendSettings.unk7_7))
case 0:
// Fade all the way to the max blend amount, then wrap around
// BUG: This comparison will never be true for maxBlendCoeff values that are >= 8. This
// is because maxBlendCoeff is a signed 4-bit field, but blendCoeff is an unsigned 4-bit
// field. This code is never reached, anyway, so the bug is not observable in vanilla
// gameplay.
if (pulseBlendPalette->blendCoeff++ ==
pulseBlendPalette->pulseBlendSettings.maxBlendCoeff)
{
if (--pulseBlendPalette->delayCounter == 0xFF)
pulseBlendPalette->fadeCycleCounter++;
pulseBlendPalette->blendCoeff = 0;
}
break;
case 1:
if (pulseBlendPalette->fadeDirection)
{
if (pulseBlendPalette->blendCoeff-- == 1)
{
pulseBlendPalette->delayCounter = pulseBlendPalette->pulseBlendSettings.delay;
BlendPalette(pulseBlendPalette->pulseBlendSettings.paletteOffset, pulseBlendPalette->pulseBlendSettings.numColors, pulseBlendPalette->blendCoeff, pulseBlendPalette->pulseBlendSettings.blendColor);
switch (pulseBlendPalette->pulseBlendSettings.fadeType)
{
case 0: // Fade all the way to the max blend amount, then wrap around
// BUG: This comparison will never be true for maxBlendCoeff values that are >= 8. This is because
// maxBlendCoeff is a signed 4-bit field, but blendCoeff is an unsigned 4-bit field. This code is never
// reached, anyway, so the bug is not observable in vanilla gameplay.
if (pulseBlendPalette->blendCoeff++ == pulseBlendPalette->pulseBlendSettings.maxBlendCoeff)
{
pulseBlendPalette->fadeCycleCounter++;
pulseBlendPalette->blendCoeff = 0;
}
break;
case 1: // Fade in and out
if (pulseBlendPalette->fadeDirection)
{
if (--pulseBlendPalette->blendCoeff == 0)
{
pulseBlendPalette->fadeCycleCounter++;
pulseBlendPalette->fadeDirection ^= 1;
}
}
else
{
u8 max = (pulseBlendPalette->pulseBlendSettings.maxBlendCoeff - 1) & 0xF;
if (pulseBlendPalette->blendCoeff++ == max)
{
pulseBlendPalette->fadeCycleCounter++;
pulseBlendPalette->fadeDirection ^= 1;
}
}
break;
case (MODERN ? -2 : 2): // Flip back and forth
// This code is never reached in vanilla
if (pulseBlendPalette->fadeDirection)
pulseBlendPalette->blendCoeff = 0;
else
pulseBlendPalette->blendCoeff = pulseBlendPalette->pulseBlendSettings.maxBlendCoeff & 0xF;
pulseBlendPalette->fadeDirection ^= 1;
pulseBlendPalette->fadeCycleCounter++;
break;
}
if (pulseBlendPalette->pulseBlendSettings.numFadeCycles != 0xFF
&& pulseBlendPalette->fadeCycleCounter == pulseBlendPalette->pulseBlendSettings.numFadeCycles)
UnmarkUsedPulseBlendPalettes(pulseBlend, pulseBlendPalette->paletteSelector, FALSE);
pulseBlendPalette->fadeCycleCounter++;
pulseBlendPalette->fadeDirection ^= 1;
}
}
else
{
j = (pulseBlendPalette->pulseBlendSettings.maxBlendCoeff - 1) & 0xF;
if (pulseBlendPalette->blendCoeff++ == j)
{
pulseBlendPalette->fadeCycleCounter++;
pulseBlendPalette->fadeDirection ^= 1;
}
}
break;
#ifdef UBFIX
case -2:
#else
case 2:
#endif
if (pulseBlendPalette->fadeDirection)
pulseBlendPalette->blendCoeff = 0;
else
pulseBlendPalette->blendCoeff = pulseBlendPalette->pulseBlendSettings.maxBlendCoeff & 0xF;
pulseBlendPalette->fadeDirection ^= 1;
pulseBlendPalette->fadeCycleCounter++;
default:
break;
}
if (pulseBlendPalette->pulseBlendSettings.numFadeCycles == 0xFF)
continue;
if (pulseBlendPalette->fadeCycleCounter != pulseBlendPalette->pulseBlendSettings.numFadeCycles)
continue;
UnmarkUsedPulseBlendPalettes(pulseBlend, pulseBlendPalette->paletteSelector, FALSE);
}
}
// Below used for the Roulette grid
void FillTilemapRect(u16 *dest, u16 value, u8 left, u8 top, u8 width, u8 height)
{
u16 *_dest;
u8 i;
u8 j;
i = 0;
dest = &dest[top * 32 + left];
for (; i < height; i++)
u8 i = 0, j = 0;
u16 *_dest = NULL;
dest += top * 32 + left;
for (i = 0; i < height; i++)
{
_dest = dest + i * 32;
for (j = 0; j < width; j++)
@ -453,15 +461,14 @@ void FillTilemapRect(u16 *dest, u16 value, u8 left, u8 top, u8 width, u8 height)
}
}
void SetTilemapRect(u16 *dest, u16 *src, u8 left, u8 top, u8 width, u8 height)
void SetTilemapRect(u16 *dest, const u16 *src, u8 left, u8 top, u8 width, u8 height)
{
u16 *_dest;
u16 *_src = src;
u8 i;
u8 j;
i = 0;
dest = &dest[top * 32 + left];
for (; i < height; i++)
u8 i = 0, j = 0;
u16 *_dest = NULL;
u16 *_src = (u16 *)src;
dest += top * 32 + left;
for (i = 0; i < height; i++)
{
_dest = dest + i * 32;
for (j = 0; j < width; j++)