diff --git a/include/palette_util.h b/include/palette_util.h index a81078f498f9..928ac172c72e 100644 --- a/include/palette_util.h +++ b/include/palette_util.h @@ -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); diff --git a/src/palette_util.c b/src/palette_util.c index d24321d58053..4c0c06c2a6e7 100755 --- a/src/palette_util.c +++ b/src/palette_util.c @@ -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) + if (!flash->enabled) + return; + + for (i = 0; i < ARRAY_COUNT(flash->palettes); i++) { - for (i = 0; i < ARRAY_COUNT(flash->palettes); i++) + if (!((flash->flags >> i) & 1)) + continue; + + if (flash->palettes[i].delayCounter-- == 0) { - 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->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; - } - } + 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 < ARRAY_COUNT(pulseBlend->pulseBlendPalettes); i++) { - for (i = 0; i < 16; i++) - { - if ((pulseBlendPaletteSelector & 1) && pulseBlend->pulseBlendPalettes[i].inUse) - ClearPulseBlendPalettesSettings(&pulseBlend->pulseBlendPalettes[i]); + if ((pulseBlendPaletteSelector & 1) && pulseBlend->pulseBlendPalettes[i].inUse) + ClearPulseBlendPalettesSettings(&pulseBlend->pulseBlendPalettes[i]); - pulseBlendPaletteSelector >>= 1; - } + 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 < ARRAY_COUNT(pulseBlend->pulseBlendPalettes); j++) { - for (j = 0; j < 16; j++) + pulseBlendPalette = &pulseBlend->pulseBlendPalettes[j]; + if (!(pulseBlendPaletteSelector & 1) || !pulseBlendPalette->inUse || pulseBlendPalette->available) { - 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]; - } + pulseBlendPaletteSelector <<= 1; + continue; + } - 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); } } void UpdatePulseBlend(struct PulseBlend *pulseBlend) { - struct PulseBlendPalette *pulseBlendPalette; u8 i = 0; + u8 j = 0; + struct PulseBlendPalette *pulseBlendPalette = NULL; + + if (!pulseBlend->usedPulseBlendPalettes) + return; - if (pulseBlend->usedPulseBlendPalettes) + 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) + { + pulseBlendPalette->fadeCycleCounter++; + pulseBlendPalette->blendCoeff = 0; + } + break; + case 1: + if (pulseBlendPalette->fadeDirection) + { + if (pulseBlendPalette->blendCoeff-- == 1) + { + pulseBlendPalette->fadeCycleCounter++; + pulseBlendPalette->fadeDirection ^= 1; + } + } + else { - if (--pulseBlendPalette->delayCounter == 0xFF) + j = (pulseBlendPalette->pulseBlendSettings.maxBlendCoeff - 1) & 0xF; + if (pulseBlendPalette->blendCoeff++ == j) { - 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; } } + 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++)