More testing of fog blending.

This commit is contained in:
Ariel Antonitis 2021-04-25 17:00:07 -04:00
parent 4a5dbcb52b
commit 147e101df5
8 changed files with 61 additions and 49 deletions

View File

@ -151,7 +151,7 @@ void ApplyWeatherGammaShiftIfIdle(s8 gammaIndex);
void sub_80ABC7C(u8 gammaIndex, u8 gammaTargetIndex, u8 gammaStepDelay); void sub_80ABC7C(u8 gammaIndex, u8 gammaTargetIndex, u8 gammaStepDelay);
void FadeScreen(u8 mode, s8 delay); void FadeScreen(u8 mode, s8 delay);
bool8 IsWeatherNotFadingIn(void); bool8 IsWeatherNotFadingIn(void);
void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex); void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex, bool8 allowFog);
void ApplyWeatherGammaShiftToPal(u8 paletteIndex); void ApplyWeatherGammaShiftToPal(u8 paletteIndex);
void LoadCustomWeatherSpritePalette(const u16 *palette); void LoadCustomWeatherSpritePalette(const u16 *palette);
void ResetDroughtWeatherPaletteLoading(void); void ResetDroughtWeatherPaletteLoading(void);

View File

@ -1684,7 +1684,7 @@ static void FollowerSetGraphics(struct ObjectEvent *objectEvent, u16 species, u8
if (palette[0] & 0x4000) // If color 15 is blended, use it as the alternate color if (palette[0] & 0x4000) // If color 15 is blended, use it as the alternate color
palette[15] |= 0x8000; palette[15] |= 0x8000;
} }
UpdateSpritePaletteWithTime(sprite->oam.paletteNum); UpdateSpritePaletteWithWeather(sprite->oam.paletteNum, FALSE);
} else } else
sprite->oam.paletteNum = IndexOfSpritePaletteTag(spritePalette->tag); // Tag is always present sprite->oam.paletteNum = IndexOfSpritePaletteTag(spritePalette->tag); // Tag is always present
} }
@ -2186,7 +2186,7 @@ static u8 UpdateSpritePalette(const struct SpritePalette * spritePalette, struct
sprite->inUse = TRUE; sprite->inUse = TRUE;
if (IndexOfSpritePaletteTag(spritePalette->tag) == 0xFF) { if (IndexOfSpritePaletteTag(spritePalette->tag) == 0xFF) {
sprite->oam.paletteNum = LoadSpritePalette(spritePalette); sprite->oam.paletteNum = LoadSpritePalette(spritePalette);
UpdateSpritePaletteWithTime(sprite->oam.paletteNum); UpdateSpritePaletteWithWeather(sprite->oam.paletteNum, FALSE);
} else { } else {
sprite->oam.paletteNum = LoadSpritePalette(spritePalette); sprite->oam.paletteNum = LoadSpritePalette(spritePalette);
} }
@ -2443,7 +2443,7 @@ static u8 LoadSpritePaletteIfTagExists(const struct SpritePalette *spritePalette
if (IndexOfSpritePaletteTag(spritePalette->tag) != 0xFF) if (IndexOfSpritePaletteTag(spritePalette->tag) != 0xFF)
return 0xFF; return 0xFF;
paletteNum = LoadSpritePalette(spritePalette); paletteNum = LoadSpritePalette(spritePalette);
UpdateSpritePaletteWithTime(paletteNum); UpdateSpritePaletteWithWeather(paletteNum, FALSE);
return paletteNum; return paletteNum;
} }

View File

@ -393,7 +393,7 @@ void SetMewAboveGrass(void)
gSprites[mew->spriteId].subpriority = 1; gSprites[mew->spriteId].subpriority = 1;
LoadSpritePalette(&gSpritePalette_GeneralFieldEffect1); LoadSpritePalette(&gSpritePalette_GeneralFieldEffect1);
UpdateSpritePaletteWithWeather(IndexOfSpritePaletteTag(gSpritePalette_GeneralFieldEffect1.tag)); UpdateSpritePaletteWithWeather(IndexOfSpritePaletteTag(gSpritePalette_GeneralFieldEffect1.tag), FALSE);
x = mew->currentCoords.x; x = mew->currentCoords.x;
y = mew->currentCoords.y; y = mew->currentCoords.y;

View File

@ -770,8 +770,7 @@ void FieldEffectScript_LoadFadedPalette(u8 **script)
{ {
struct SpritePalette *palette = (struct SpritePalette *)FieldEffectScript_ReadWord(script); struct SpritePalette *palette = (struct SpritePalette *)FieldEffectScript_ReadWord(script);
LoadSpritePalette(palette); LoadSpritePalette(palette);
UpdateSpritePaletteWithTime(IndexOfSpritePaletteTag(palette->tag)); // Ensure field effects are blended UpdateSpritePaletteWithWeather(IndexOfSpritePaletteTag(palette->tag), FALSE);
UpdateSpritePaletteWithWeather(IndexOfSpritePaletteTag(palette->tag));
(*script) += 4; (*script) += 4;
} }

View File

@ -151,7 +151,7 @@ static void LoadObjectRegularReflectionPalette(struct ObjectEvent *objectEvent,
ApplyIceFilter(mainSprite->oam.paletteNum, filteredData); ApplyIceFilter(mainSprite->oam.paletteNum, filteredData);
} }
paletteNum = LoadSpritePalette(&filteredPalette); paletteNum = LoadSpritePalette(&filteredPalette);
UpdateSpritePaletteWithWeather(paletteNum); UpdateSpritePaletteWithWeather(paletteNum, TRUE);
} }
sprite->oam.paletteNum = paletteNum; sprite->oam.paletteNum = paletteNum;
sprite->oam.objMode = 1; // Alpha blending sprite->oam.objMode = 1; // Alpha blending
@ -170,7 +170,7 @@ static void LoadObjectHighBridgeReflectionPalette(struct ObjectEvent *objectEven
blueData[i] = 0x55c9; blueData[i] = 0x55c9;
} }
sprite->oam.paletteNum = LoadSpritePalette(&bluePalette); sprite->oam.paletteNum = LoadSpritePalette(&bluePalette);
UpdateSpritePaletteWithWeather(sprite->oam.paletteNum); UpdateSpritePaletteWithWeather(sprite->oam.paletteNum, TRUE);
} }
static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite) static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite)
@ -203,7 +203,7 @@ static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite)
ApplyIceFilter(mainSprite->oam.paletteNum, filteredData); ApplyIceFilter(mainSprite->oam.paletteNum, filteredData);
} }
paletteNum = LoadSpritePalette(&filteredPalette); paletteNum = LoadSpritePalette(&filteredPalette);
UpdateSpritePaletteWithWeather(paletteNum); UpdateSpritePaletteWithWeather(paletteNum, TRUE);
} }
reflectionSprite->oam.paletteNum = paletteNum; reflectionSprite->oam.paletteNum = paletteNum;
} }

View File

@ -536,13 +536,16 @@ static void ApplyGammaShift(u8 startPalIndex, u8 numPalettes, s8 gammaIndex)
} }
else else
{ {
u32 palettes = 0; if (MapHasNaturalLight(gMapHeader.mapType)) { // Time-blend
u32 mask = 1 << startPalIndex; u32 palettes = 0;
u8 i; u32 mask = 1 << startPalIndex;
CpuFastCopy(gPlttBufferUnfaded + startPalIndex * 16, gPlttBufferFaded + startPalIndex * 16, numPalettes * 16 * sizeof(u16)); u8 i;
for (i = 0; i < numPalettes; i++, mask <<= 1) for (i = 0; i < numPalettes; i++, mask <<= 1)
palettes |= mask; palettes |= mask;
UpdatePalettesWithTime(palettes); UpdatePalettesWithTime(palettes);
} else { // copy
CpuFastCopy(gPlttBufferUnfaded + startPalIndex * 16, gPlttBufferFaded + startPalIndex * 16, numPalettes * 16 * sizeof(u16));
}
} }
} }
@ -653,7 +656,7 @@ static void ApplyDroughtGammaShiftWithBlend(s8 gammaIndex, u8 blendCoeff, u16 bl
} }
} }
static void ApplyFogBlend(u8 blendCoeff, u16 blendColor) // TODO: How does this interact with time static void ApplyFogBlend(u8 blendCoeff, u16 blendColor) // TODO: Optimize this with time blending
{ {
struct RGBColor color; struct RGBColor color;
u8 rBlend; u8 rBlend;
@ -661,7 +664,11 @@ static void ApplyFogBlend(u8 blendCoeff, u16 blendColor) // TODO: How does this
u8 bBlend; u8 bBlend;
u16 curPalIndex; u16 curPalIndex;
BlendPalette(0, 256, blendCoeff, blendColor); // First blend all palettes with time
CpuFastCopy(gPlttBufferUnfaded, gPlttBufferFaded, 0x400);
UpdatePalettesWithTime(PALETTES_ALL);
// Then blend tile palettes [0, 12] faded->faded
BlendPalettesFine(0x1FFF, gPlttBufferFaded, gPlttBufferFaded, blendCoeff, blendColor);
color = *(struct RGBColor *)&blendColor; color = *(struct RGBColor *)&blendColor;
rBlend = color.r; rBlend = color.r;
gBlend = color.g; gBlend = color.g;
@ -676,7 +683,7 @@ static void ApplyFogBlend(u8 blendCoeff, u16 blendColor) // TODO: How does this
while (palOffset < palEnd) while (palOffset < palEnd)
{ {
struct RGBColor color = *(struct RGBColor *)&gPlttBufferUnfaded[palOffset]; struct RGBColor color = *(struct RGBColor *)&gPlttBufferFaded[palOffset];
u8 r = color.r; u8 r = color.r;
u8 g = color.g; u8 g = color.g;
u8 b = color.b; u8 b = color.b;
@ -695,7 +702,7 @@ static void ApplyFogBlend(u8 blendCoeff, u16 blendColor) // TODO: How does this
} }
else else
{ {
BlendPalette(curPalIndex * 16, 16, blendCoeff, blendColor); BlendPalettesFine(1, gPlttBufferFaded + curPalIndex * 16, gPlttBufferFaded + curPalIndex * 16, blendCoeff, blendColor);
} }
} }
} }
@ -799,10 +806,10 @@ void FadeScreen(u8 mode, s8 delay)
else else
{ {
gWeatherPtr->fadeDestColor = fadeColor; gWeatherPtr->fadeDestColor = fadeColor;
UpdateTimeOfDay();
if (useWeatherPal) if (useWeatherPal)
gWeatherPtr->fadeScreenCounter = 0; // Triggers gamma-shift-based fade-in gWeatherPtr->fadeScreenCounter = 0; // Triggers gamma-shift-based fade-in
else { else {
UpdateTimeOfDay();
if (MapHasNaturalLight(gMapHeader.mapType)) { if (MapHasNaturalLight(gMapHeader.mapType)) {
BeginTimeOfDayPaletteFade(PALETTES_ALL, delay, 16, 0, BeginTimeOfDayPaletteFade(PALETTES_ALL, delay, 16, 0,
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0], (struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0],
@ -826,7 +833,7 @@ bool8 IsWeatherNotFadingIn(void)
return (gWeatherPtr->palProcessingState != WEATHER_PAL_STATE_SCREEN_FADING_IN); return (gWeatherPtr->palProcessingState != WEATHER_PAL_STATE_SCREEN_FADING_IN);
} }
void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex) void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex, bool8 allowFog)
{ {
u16 paletteIndex = 16 + spritePaletteIndex; u16 paletteIndex = 16 + spritePaletteIndex;
u16 i; u16 i;
@ -850,17 +857,22 @@ void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex)
// WEATHER_PAL_STATE_CHANGING_WEATHER // WEATHER_PAL_STATE_CHANGING_WEATHER
// WEATHER_PAL_STATE_CHANGING_IDLE // WEATHER_PAL_STATE_CHANGING_IDLE
default: default:
if (gWeatherPtr->currWeather != WEATHER_FOG_HORIZONTAL) if (gWeatherPtr->currWeather != WEATHER_FOG_HORIZONTAL) {
{ if (gWeatherPtr->gammaIndex)
ApplyGammaShift(paletteIndex, 1, gWeatherPtr->gammaIndex); ApplyGammaShift(paletteIndex, 1, gWeatherPtr->gammaIndex);
} else
else UpdateSpritePaletteWithTime(spritePaletteIndex);
{ } else { // In horizontal fog, only specific palettes should be fog-blended
if (allowFog) {
paletteIndex *= 16; paletteIndex *= 16;
// First blend with time // First blend with time
CpuFastCopy(gPlttBufferUnfaded + paletteIndex, gPlttBufferFaded + paletteIndex, 32); CpuFastCopy(gPlttBufferUnfaded + paletteIndex, gPlttBufferFaded + paletteIndex, 32);
UpdateSpritePaletteWithTime(spritePaletteIndex); UpdateSpritePaletteWithTime(spritePaletteIndex);
// Then blend faded->faded
BlendPalettesFine(1 << (spritePaletteIndex + 16), gPlttBufferFaded + paletteIndex, gPlttBufferFaded + paletteIndex, 12, RGB(28, 31, 28)); BlendPalettesFine(1 << (spritePaletteIndex + 16), gPlttBufferFaded + paletteIndex, gPlttBufferFaded + paletteIndex, 12, RGB(28, 31, 28));
} else { // Otherwise, just time-blend the palette
UpdateSpritePaletteWithTime(spritePaletteIndex);
}
} }
break; break;
} }
@ -883,8 +895,7 @@ static bool8 IsFirstFrameOfWeatherFadeIn(void)
void LoadCustomWeatherSpritePalette(const u16 *palette) void LoadCustomWeatherSpritePalette(const u16 *palette)
{ {
LoadPalette(palette, 0x100 + gWeatherPtr->weatherPicSpritePalIndex * 16, 32); LoadPalette(palette, 0x100 + gWeatherPtr->weatherPicSpritePalIndex * 16, 32);
UpdateSpritePaletteWithTime(gWeatherPtr->weatherPicSpritePalIndex); UpdateSpritePaletteWithWeather(gWeatherPtr->weatherPicSpritePalIndex, TRUE);
UpdateSpritePaletteWithWeather(gWeatherPtr->weatherPicSpritePalIndex);
} }
static void LoadDroughtWeatherPalette(u8 *gammaIndexPtr, u8 *a1) static void LoadDroughtWeatherPalette(u8 *gammaIndexPtr, u8 *a1)

View File

@ -1380,10 +1380,17 @@ static void DestroyFogHorizontalSprites(void);
// Updates just the color of shadows to match special weather blending // Updates just the color of shadows to match special weather blending
static u8 UpdateShadowColor(u16 color) { static u8 UpdateShadowColor(u16 color) {
u8 paletteNum = IndexOfSpritePaletteTag(TAG_WEATHER_START); u8 paletteNum = IndexOfSpritePaletteTag(TAG_WEATHER_START);
u16 tempBuffer[16];
u16 blendedColor;
if (paletteNum != 0xFF) { if (paletteNum != 0xFF) {
u16 index = (paletteNum+16)*16+SHADOW_COLOR_INDEX; u16 index = (paletteNum+16)*16+SHADOW_COLOR_INDEX;
gPlttBufferUnfaded[index] = gPlttBufferFaded[index] = color; gPlttBufferUnfaded[index] = gPlttBufferFaded[index] = color;
// Copy to temporary buffer, blend, and keep just the shadow color index
CpuFastCopy(&gPlttBufferFaded[index-SHADOW_COLOR_INDEX], tempBuffer, 32);
UpdateSpritePaletteWithTime(paletteNum); UpdateSpritePaletteWithTime(paletteNum);
blendedColor = gPlttBufferFaded[index];
CpuFastCopy(tempBuffer, &gPlttBufferFaded[index-SHADOW_COLOR_INDEX], 32);
gPlttBufferFaded[index] = blendedColor;
} }
return paletteNum; return paletteNum;
} }

View File

@ -821,7 +821,7 @@ void LoadMapFromCameraTransition(u8 mapGroup, u8 mapNum)
CopySecondaryTilesetToVramUsingHeap(gMapHeader.mapLayout); CopySecondaryTilesetToVramUsingHeap(gMapHeader.mapLayout);
LoadSecondaryTilesetPalette(gMapHeader.mapLayout); LoadSecondaryTilesetPalette(gMapHeader.mapLayout);
for (paletteIndex = 6; paletteIndex < 13; paletteIndex++) for (paletteIndex = 6; paletteIndex < 13; paletteIndex++) // TODO: Optimize gamma shifts
ApplyWeatherGammaShiftToPal(paletteIndex); ApplyWeatherGammaShiftToPal(paletteIndex);
InitSecondaryTilesetAnimation(); InitSecondaryTilesetAnimation();
@ -829,7 +829,6 @@ void LoadMapFromCameraTransition(u8 mapGroup, u8 mapNum)
RoamerMove(); RoamerMove();
DoCurrentWeather(); DoCurrentWeather();
ResetFieldTasksArgs(); ResetFieldTasksArgs();
UpdatePalettesWithTime(PALETTES_ALL);
RunOnResumeMapScript(); RunOnResumeMapScript();
if (gMapHeader.regionMapSectionId != MAPSEC_BATTLE_FRONTIER if (gMapHeader.regionMapSectionId != MAPSEC_BATTLE_FRONTIER
@ -1512,19 +1511,6 @@ bool8 MapHasNaturalLight(u8 mapType) { // Whether a map type is naturally lit/ou
|| mapType == MAP_TYPE_OCEAN_ROUTE; || mapType == MAP_TYPE_OCEAN_ROUTE;
} }
// TODO: Rewrite palette fading to work with FadeScreen
// Currently, this cancels the "Normal" palette fade started by FadeScreen
static bool8 FadePalettesWithTime(void) { // Only used to fade back in
UpdateTimeOfDay();
if (MapHasNaturalLight(gMapHeader.mapType)) {
ResetPaletteFade();
BeginTimeOfDayPaletteFade(PALETTES_ALL, 0, 16, 0,
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0],
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time1],
currentTimeBlend.weight, 0);
}
}
void UpdatePalettesWithTime(u32 palettes) { void UpdatePalettesWithTime(u32 palettes) {
if (MapHasNaturalLight(gMapHeader.mapType)) { if (MapHasNaturalLight(gMapHeader.mapType)) {
u16 i; u16 i;
@ -1546,7 +1532,18 @@ void UpdatePalettesWithTime(u32 palettes) {
} }
u8 UpdateSpritePaletteWithTime(u8 paletteNum) { u8 UpdateSpritePaletteWithTime(u8 paletteNum) {
UpdatePalettesWithTime(1 << (paletteNum + 16)); if (MapHasNaturalLight(gMapHeader.mapType)) {
u16 offset;
if (GetSpritePaletteTagByPaletteNum(paletteNum) >> 15)
return paletteNum;
offset = (paletteNum + 16) * 16;
TimeMixPalettes(1,
gPlttBufferUnfaded + offset,
gPlttBufferFaded + offset,
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0],
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time1],
currentTimeBlend.weight);
}
return paletteNum; return paletteNum;
} }
@ -1688,7 +1685,6 @@ static void CB2_LoadMap2(void)
DoMapLoadLoop(&gMain.state); DoMapLoadLoop(&gMain.state);
SetFieldVBlankCallback(); SetFieldVBlankCallback();
SetMainCallback1(CB1_Overworld); SetMainCallback1(CB1_Overworld);
// FadePalettesWithTime();
SetMainCallback2(CB2_Overworld); SetMainCallback2(CB2_Overworld);
} }
@ -1745,7 +1741,6 @@ static void CB2_ReturnToFieldLocal(void)
if (ReturnToFieldLocal(&gMain.state)) if (ReturnToFieldLocal(&gMain.state))
{ {
SetFieldVBlankCallback(); SetFieldVBlankCallback();
// FadePalettesWithTime();
SetMainCallback2(CB2_Overworld); SetMainCallback2(CB2_Overworld);
} }
} }