From e3242907b09233d143672360c74e0aaeae9e95fd Mon Sep 17 00:00:00 2001 From: cawtds <38510667+cawtds@users.noreply.github.com> Date: Mon, 18 Nov 2024 10:48:31 +0100 Subject: [PATCH] added drought, aligned with emerald --- graphics/weather/drought/colors_0.bin | Bin 0 -> 8192 bytes graphics/weather/drought/colors_1.bin | Bin 0 -> 8192 bytes graphics/weather/drought/colors_2.bin | Bin 0 -> 8192 bytes graphics/weather/drought/colors_3.bin | Bin 0 -> 8192 bytes graphics/weather/drought/colors_4.bin | Bin 0 -> 8192 bytes graphics/weather/drought/colors_5.bin | Bin 0 -> 8192 bytes include/constants/field_weather.h | 1 + include/field_weather.h | 44 +-- src/field_weather.c | 418 +++++++++++++------------- src/field_weather_effects.c | 106 +++---- src/overworld.c | 4 +- 11 files changed, 299 insertions(+), 274 deletions(-) create mode 100644 graphics/weather/drought/colors_0.bin create mode 100644 graphics/weather/drought/colors_1.bin create mode 100644 graphics/weather/drought/colors_2.bin create mode 100644 graphics/weather/drought/colors_3.bin create mode 100644 graphics/weather/drought/colors_4.bin create mode 100644 graphics/weather/drought/colors_5.bin diff --git a/graphics/weather/drought/colors_0.bin b/graphics/weather/drought/colors_0.bin new file mode 100644 index 0000000000000000000000000000000000000000..e8249d55a5c27be0e31fc2c2c6aeadb7bdd15c3f GIT binary patch literal 8192 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 literal 0 HcmV?d00001 diff --git a/graphics/weather/drought/colors_1.bin b/graphics/weather/drought/colors_1.bin new file mode 100644 index 0000000000000000000000000000000000000000..145423a26786757ce7504ae71a02627cce1f6abe GIT binary patch literal 8192 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

Xg1sB0(a0Pr0 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 literal 0 HcmV?d00001 diff --git a/include/constants/field_weather.h b/include/constants/field_weather.h index e84dbc48c..fe7eb6a1a 100644 --- a/include/constants/field_weather.h +++ b/include/constants/field_weather.h @@ -8,6 +8,7 @@ #define NUM_FOG_DIAGONAL_SPRITES 20 #define NUM_SANDSTORM_SPRITES 20 #define NUM_SWIRL_SANDSTORM_SPRITES 5 +#define NUM_SNOWFLAKE_SPRITES 16 // Controls how the weather should be changing the screen palettes. #define WEATHER_PAL_STATE_CHANGING_WEATHER 0 diff --git a/include/field_weather.h b/include/field_weather.h index 2e7a34a64..22b517543 100644 --- a/include/field_weather.h +++ b/include/field_weather.h @@ -18,6 +18,8 @@ enum { PALTAG_WEATHER = TAG_WEATHER_START, }; +#define NUM_WEATHER_COLOR_MAPS 19 + struct Weather { union @@ -38,12 +40,10 @@ struct Weather struct Sprite *sandstormSprites2[NUM_SWIRL_SANDSTORM_SPRITES]; } s2; } sprites; - u8 gammaShifts[19][32]; - u8 altGammaShifts[19][32]; - s8 gammaIndex; - s8 gammaTargetIndex; - u8 gammaStepDelay; - u8 gammaStepFrameCounter; + s8 colorMapIndex; + s8 targetColorMapIndex; + u8 colorMapStepDelay; + u8 colorMapStepCounter; u16 fadeDestColor; u8 palProcessingState; u8 fadeScreenCounter; @@ -58,7 +58,8 @@ struct Weather u8 weatherGfxLoaded; bool8 weatherChangeComplete; u8 weatherPicSpritePalIndex; - u8 altGammaSpritePalIndex; + u8 contrastColorMapSpritePalIndex; + // Rain u16 rainSpriteVisibleCounter; u8 curRainSpriteIndex; u8 targetRainSpriteCount; @@ -67,34 +68,40 @@ struct Weather u8 isDownpour; u8 rainStrength; bool8 cloudSpritesCreated; + // Snow u16 snowflakeVisibleCounter; u16 snowflakeTimer; u8 snowflakeSpriteCount; u8 targetSnowflakeSpriteCount; - u16 thunderDelay; - u16 thunderCounter; + // Thunderstorm + u16 thunderTimer; + u16 thunderSETimer; bool8 thunderAllowEnd; - bool8 thunderSkipShort; - u8 thunderShortRetries; - bool8 thunderTriggered; + bool8 thunderLongBolt; + u8 thunderShortBolts; + bool8 thunderEnqueued; + // Horizontal fog u16 fogHScrollPosX; u16 fogHScrollCounter; u16 fogHScrollOffset; u8 lightenedFogSpritePals[6]; u8 lightenedFogSpritePalsCount; bool8 fogHSpritesCreated; + // Ash u16 ashBaseSpritesX; u16 ashUnused; bool8 ashSpritesCreated; + // Sandstorm u32 sandstormXOffset; u32 sandstormYOffset; - u8 filler_70C[2]; + u16 sandstormUnused; u16 sandstormBaseSpritesX; u16 sandstormPosY; u16 sandstormWaveIndex; u16 sandstormWaveCounter; bool8 sandstormSpritesCreated; bool8 sandstormSwirlSpritesCreated; + // Diagonal fog u16 fogDBaseSpritesX; u16 fogDPosY; u16 fogDScrollXCounter; @@ -102,11 +109,13 @@ struct Weather u16 fogDXOffset; u16 fogDYOffset; bool8 fogDSpritesCreated; + // Bubbles u16 bubblesDelayCounter; u16 bubblesDelayIndex; u16 bubblesCoordsIndex; u16 bubblesSpriteCount; bool8 bubblesSpritesCreated; + u16 currBlendEVA; u16 currBlendEVB; u16 targetBlendEVA; @@ -114,11 +123,12 @@ struct Weather u8 blendUpdateCounter; u8 blendFrameCounter; u8 blendDelay; + // Drought s16 droughtBrightnessStage; s16 droughtLastBrightnessStage; s16 droughtTimer; s16 droughtState; - u8 filler_744[9]; + u8 droughtUnused[9]; u8 loadDroughtPalsIndex; u8 loadDroughtPalsOffset; }; @@ -155,9 +165,9 @@ bool8 LoadDroughtWeatherPalettes(void); void DroughtStateInit(void); void DroughtStateRun(void); void SetRainStrengthFromSoundEffect(u16 soundEffect); -void WeatherShiftGammaIfPalStateIdle(s8 gammaIndex); -void WeatherBeginGammaFade(u8 gammaIndex, u8 gammaTargetIndex, u8 gammaStepDelay); -void ApplyWeatherGammaShiftToPal(u8 paletteIndex); +void ApplyWeatherColorMapIfIdle(s8 colorMapIndex); +void ApplyWeatherColorMapIfIdle_Gradual(u8 colorMapIndex, u8 targetColorMapIndex, u8 colorMapStepDelay); +void ApplyWeatherColorMapToPal(u8 paletteIndex); void StartWeather(void); void ResumePausedWeather(void); void FadeSelectedPals(u8 mode, s8 delay, u32 selectedPalettes); diff --git a/src/field_weather.c b/src/field_weather.c index ce617f4b0..816160a58 100644 --- a/src/field_weather.c +++ b/src/field_weather.c @@ -19,9 +19,9 @@ enum { - GAMMA_NONE, - GAMMA_NORMAL, - GAMMA_ALT, + COLOR_MAP_NONE, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_CONTRAST, }; struct RGBColor @@ -31,11 +31,6 @@ struct RGBColor u16 b:5; }; -struct WeatherPaletteData -{ - u16 gammaShiftColors[8][0x1000]; // 0x1000 is the number of bytes that make up all palettes. -}; - struct WeatherCallbacks { void (*initVars)(void); @@ -44,9 +39,9 @@ struct WeatherCallbacks bool8 (*finish)(void); }; -static EWRAM_DATA struct Weather sWeather = {}; -static EWRAM_DATA u8 sFieldEffectPaletteGammaTypes[32] = {}; -static EWRAM_DATA const u8 *sPaletteGammaTypes = NULL; +static EWRAM_DATA struct Weather gWeather = {}; +static EWRAM_DATA u8 sFieldEffectPaletteColorMapTypes[32] = {}; +static EWRAM_DATA const u8 *sPaletteColorMapTypes = NULL; static EWRAM_DATA u16 sDroughtFrameDelay = 0; static void Task_WeatherMain(u8 taskId); @@ -54,11 +49,10 @@ static void Task_WeatherInit(u8 taskId); static void None_Init(void); static void None_Main(void); static bool8 None_Finish(void); -static void BuildGammaShiftTables(void); -static void UpdateWeatherGammaShift(void); -static void ApplyGammaShift(u8 startPalIndex, u8 numPalettes, s8 gammaIndex); -static void ApplyGammaShiftWithBlend(u8 startPalIndex, u8 numPalettes, s8 gammaIndex, u8 blendCoeff, u32 blendColor); -static void ApplyDroughtGammaShiftWithBlend(s8 gammaIndex, u8 blendCoeff, u32 blendColor); +static void UpdateWeatherColorMap(void); +static void ApplyColorMap(u8 startPalIndex, u8 numPalettes, s8 colorMapIndex); +static void ApplyColorMapWithBlend(u8 startPalIndex, u8 numPalettes, s8 colorMapIndex, u8 blendCoeff, u32 blendColor); +static void ApplyDroughtColorMapWithBlend(s8 colorMapIndex, u8 blendCoeff, u32 blendColor); static void FadeInScreenWithWeather(void); static bool8 FadeInScreen_RainShowShade(void); static bool8 FadeInScreen_Drought(void); @@ -67,7 +61,64 @@ static void DoNothing(void); static void ApplyFogBlend(u8 blendCoeff, u32 blendColor); static bool8 LightenSpritePaletteInFog(u8 paletteIndex); -struct Weather *const gWeatherPtr = &sWeather; +static const u8 sDarkenedContrastColorMaps[NUM_WEATHER_COLOR_MAPS][32] = +{ + {0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}, + {0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 9, 10, 11, 12, 13, 14, 14, 15, 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, 25, 26, 27}, + {0, 0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 13, 14, 15, 16, 17, 17, 18, 19, 20, 21, 21, 22, 23, 24, 25}, + {0, 1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 11, 11, 12, 13, 14, 14, 15, 16, 17, 17, 18, 19, 20, 20, 21, 22, 23, 24, 24, 25}, + {1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 12, 13, 13, 14, 15, 15, 16, 17, 18, 18, 19, 20, 20, 21, 22, 23, 23, 24, 25, 25}, + {1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 13, 14, 15, 15, 16, 17, 17, 18, 19, 19, 20, 20, 21, 22, 22, 23, 24, 24, 25, 26}, + {1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 15, 15, 16, 16, 17, 18, 18, 19, 19, 20, 21, 21, 22, 22, 23, 24, 24, 25, 26, 26}, + {1, 2, 3, 4, 4, 5, 6, 7, 7, 8, 9, 10, 16, 16, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27}, + {1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27}, + {1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 19, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 24, 25, 25, 26, 26, 27, 27}, + {1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 24, 25, 25, 26, 26, 26, 27, 27, 28}, + {1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 21, 22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 27, 27, 27, 28, 28}, + {1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 23, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 28, 28, 28}, + {1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29}, + {1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 25, 25, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 29, 29, 29}, + {1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29}, + {1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30}, + {1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, + {1, 2, 3, 4, 4, 5, 6, 7, 8, 8, 9, 10, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31} +}; + +static const u8 sContrastColorMaps[NUM_WEATHER_COLOR_MAPS][32] = +{ + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 14, 15, 16, 17, 17, 18, 19, 20, 21, 22, 23, 24, 24, 25, 26, 27, 28, 29, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 16, 17, 18, 18, 19, 20, 21, 22, 22, 23, 24, 25, 26, 26, 27, 28, 29, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16, 17, 18, 19, 19, 20, 21, 22, 22, 23, 24, 25, 25, 26, 27, 28, 28, 29, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 19, 20, 20, 21, 22, 22, 23, 24, 24, 25, 26, 26, 27, 28, 28, 29, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 19, 19, 20, 21, 21, 22, 22, 23, 24, 24, 25, 26, 26, 27, 27, 28, 29, 29, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, 27, 28, 28, 29, 29, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 22, 23, 23, 24, 24, 24, 25, 25, 26, 26, 27, 27, 27, 28, 28, 29, 29, 30, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 24, 25, 25, 25, 26, 26, 26, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 26, 26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 27, 27, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31}, + {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31} +}; + +// The drought weather effect uses a precalculated color lookup table. Presumably this +// is because the underlying color shift calculation is slow. +static const u16 sDroughtWeatherColors[][0x1000] = { + INCBIN_U16("graphics/weather/drought/colors_0.bin"), + INCBIN_U16("graphics/weather/drought/colors_1.bin"), + INCBIN_U16("graphics/weather/drought/colors_2.bin"), + INCBIN_U16("graphics/weather/drought/colors_3.bin"), + INCBIN_U16("graphics/weather/drought/colors_4.bin"), + INCBIN_U16("graphics/weather/drought/colors_5.bin"), +}; + +struct Weather *const gWeatherPtr = &gWeather; static const struct WeatherCallbacks sWeatherFuncs[] = { @@ -89,47 +140,47 @@ static const struct WeatherCallbacks sWeatherFuncs[] = }; static void (*const sWeatherPalStateFuncs[])(void) = { - [WEATHER_PAL_STATE_CHANGING_WEATHER] = UpdateWeatherGammaShift, + [WEATHER_PAL_STATE_CHANGING_WEATHER] = UpdateWeatherColorMap, [WEATHER_PAL_STATE_SCREEN_FADING_IN] = FadeInScreenWithWeather, [WEATHER_PAL_STATE_SCREEN_FADING_OUT] = DoNothing, [WEATHER_PAL_STATE_IDLE] = DoNothing, }; -static const u8 sBasePaletteGammaTypes[32] = { +static const u8 sBasePaletteColorMapTypes[32] = { // background palettes - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NONE, - GAMMA_NONE, - GAMMA_NONE, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_NONE, + COLOR_MAP_NONE, + COLOR_MAP_NONE, // sprite palettes - GAMMA_ALT, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, - GAMMA_NORMAL, + COLOR_MAP_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_DARK_CONTRAST, }; const u16 gDefaultWeatherSpritePalette[] = INCBIN_U16("graphics/weather/default.gbapal"); @@ -150,11 +201,13 @@ void StartWeather(void) { if (!FuncIsActiveTask(Task_WeatherMain)) { - u8 index = AllocSpritePalette(0x1200); + u8 index = AllocSpritePalette(PALTAG_WEATHER); CpuCopy32(gDefaultWeatherSpritePalette, &gPlttBufferUnfaded[OBJ_PLTT_ID(index)], PLTT_SIZE_4BPP); ApplyGlobalFieldPaletteTint(index); - BuildGammaShiftTables(); - gWeatherPtr->altGammaSpritePalIndex = index; + + sPaletteColorMapTypes = sBasePaletteColorMapTypes; + + gWeatherPtr->contrastColorMapSpritePalIndex = index; gWeatherPtr->weatherPicSpritePalIndex = index; gWeatherPtr->rainSpriteCount = 0; gWeatherPtr->curRainSpriteIndex = 0; @@ -230,7 +283,7 @@ static void Task_WeatherMain(u8 taskId) { // Finished cleaning up previous weather. Now transition to next weather. sWeatherFuncs[gWeatherPtr->nextWeather].initVars(); - gWeatherPtr->gammaStepFrameCounter = 0; + gWeatherPtr->colorMapStepCounter = 0; gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_CHANGING_WEATHER; gWeatherPtr->currWeather = gWeatherPtr->nextWeather; gWeatherPtr->weatherChangeComplete = TRUE; @@ -247,8 +300,8 @@ static void Task_WeatherMain(u8 taskId) static void None_Init(void) { - gWeatherPtr->gammaTargetIndex = 0; - gWeatherPtr->gammaStepDelay = 0; + gWeatherPtr->targetColorMapIndex = 0; + gWeatherPtr->colorMapStepDelay = 0; } static void None_Main(void) @@ -260,95 +313,25 @@ static u8 None_Finish(void) return 0; } -// Builds two tables that contain gamma shifts for palette colors. -// It's unclear why the two tables aren't declared as const arrays, since -// this function always builds the same two tables. -static void BuildGammaShiftTables(void) -{ - u16 v0; - u8 (*gammaTable)[32]; - u16 v2; - u16 v4; - u16 v5; - u16 gammaIndex; - u16 v9; - u32 v10; - u16 v11; - s16 dunno; - - sPaletteGammaTypes = sBasePaletteGammaTypes; - for (v0 = 0; v0 <= 1; v0++) - { - if (v0 == 0) - gammaTable = gWeatherPtr->gammaShifts; - else - gammaTable = gWeatherPtr->altGammaShifts; - - for (v2 = 0; v2 < 32; v2++) - { - v4 = v2 << 8; - if (v0 == 0) - v5 = (v2 << 8) / 16; - else - v5 = 0; - for (gammaIndex = 0; gammaIndex <= 2; gammaIndex++) - { - v4 = (v4 - v5); - gammaTable[gammaIndex][v2] = v4 >> 8; - } - v9 = v4; - v10 = 0x1f00 - v4; - if ((0x1f00 - v4) < 0) - { - v10 += 0xf; - } - v11 = v10 >> 4; - if (v2 < 12) - { - for (; gammaIndex < 19; gammaIndex++) - { - v4 += v11; - dunno = v4 - v9; - if (dunno > 0) - v4 -= (dunno + ((u16)dunno >> 15)) >> 1; - gammaTable[gammaIndex][v2] = v4 >> 8; - if (gammaTable[gammaIndex][v2] > 0x1f) - gammaTable[gammaIndex][v2] = 0x1f; - } - } - else - { - for (; gammaIndex < 19; gammaIndex++) - { - v4 += v11; - gammaTable[gammaIndex][v2] = v4 >> 8; - if (gammaTable[gammaIndex][v2] > 0x1f) - gammaTable[gammaIndex][v2] = 0x1f; - } - } - } - } -} - // When the weather is changing, it gradually updates the palettes -// towards the desired gamma shift. -static void UpdateWeatherGammaShift(void) +// towards the desired color map. +static void UpdateWeatherColorMap(void) { - if (gWeatherPtr->gammaIndex == gWeatherPtr->gammaTargetIndex) + if (gWeatherPtr->colorMapIndex == gWeatherPtr->targetColorMapIndex) { gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_IDLE; } else { - if (++gWeatherPtr->gammaStepFrameCounter >= gWeatherPtr->gammaStepDelay) + if (++gWeatherPtr->colorMapStepCounter >= gWeatherPtr->colorMapStepDelay) { - gWeatherPtr->gammaStepFrameCounter = 0; - if (gWeatherPtr->gammaIndex < gWeatherPtr->gammaTargetIndex) - gWeatherPtr->gammaIndex++; + gWeatherPtr->colorMapStepCounter = 0; + if (gWeatherPtr->colorMapIndex < gWeatherPtr->targetColorMapIndex) + gWeatherPtr->colorMapIndex++; else - gWeatherPtr->gammaIndex--; + gWeatherPtr->colorMapIndex--; - ApplyGammaShift(0, 32, gWeatherPtr->gammaIndex); + ApplyColorMap(0, 32, gWeatherPtr->colorMapIndex); } } } @@ -367,21 +350,21 @@ static void FadeInScreenWithWeather(void) case WEATHER_SHADE: if (FadeInScreen_RainShowShade() == FALSE) { - gWeatherPtr->gammaIndex = 3; + gWeatherPtr->colorMapIndex = 3; gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_IDLE; } break; case WEATHER_DROUGHT: if (FadeInScreen_Drought() == FALSE) { - gWeatherPtr->gammaIndex = -6; + gWeatherPtr->colorMapIndex = -6; gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_IDLE; } break; case WEATHER_FOG_HORIZONTAL: if (FadeInScreen_FogHorizontal() == FALSE) { - gWeatherPtr->gammaIndex = 0; + gWeatherPtr->colorMapIndex = 0; gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_IDLE; } break; @@ -392,7 +375,7 @@ static void FadeInScreenWithWeather(void) default: if (!gPaletteFade.active) { - gWeatherPtr->gammaIndex = gWeatherPtr->gammaTargetIndex; + gWeatherPtr->colorMapIndex = gWeatherPtr->targetColorMapIndex; gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_IDLE; } break; @@ -406,12 +389,12 @@ static bool8 FadeInScreen_RainShowShade(void) if (++gWeatherPtr->fadeScreenCounter >= 16) { - ApplyGammaShift(0, 32, 3); + ApplyColorMap(0, 32, 3); gWeatherPtr->fadeScreenCounter = 16; return FALSE; } - ApplyGammaShiftWithBlend(0, 32, 3, 16 - gWeatherPtr->fadeScreenCounter, gWeatherPtr->fadeDestColor); + ApplyColorMapWithBlend(0, 32, 3, 16 - gWeatherPtr->fadeScreenCounter, gWeatherPtr->fadeDestColor); return TRUE; } @@ -422,12 +405,12 @@ static bool8 FadeInScreen_Drought(void) if (++gWeatherPtr->fadeScreenCounter >= 16) { - ApplyGammaShift(0, 32, -6); + ApplyColorMap(0, 32, -6); gWeatherPtr->fadeScreenCounter = 16; return FALSE; } - ApplyDroughtGammaShiftWithBlend(-6, 16 - gWeatherPtr->fadeScreenCounter, gWeatherPtr->fadeDestColor); + ApplyDroughtColorMapWithBlend(-6, 16 - gWeatherPtr->fadeScreenCounter, gWeatherPtr->fadeDestColor); return TRUE; } @@ -444,14 +427,14 @@ static bool8 FadeInScreen_FogHorizontal(void) static void DoNothing(void) { } -static void ApplyGammaShift(u8 startPalIndex, u8 numPalettes, s8 gammaIndex) +static void ApplyColorMap(u8 startPalIndex, u8 numPalettes, s8 colorMapIndex) { u16 curPalIndex; u16 palOffset; - u8 *gammaTable; + const u8 *colorMap; u16 i; - if (gammaIndex > 0) + if (colorMapIndex > 0) { // Create the palette mask u32 palettes = PALETTES_ALL; @@ -460,11 +443,11 @@ static void ApplyGammaShift(u8 startPalIndex, u8 numPalettes, s8 gammaIndex) palettes = (palettes << (32-numPalettes)) >> (32-numPalettes); numPalettes -= startPalIndex; - gammaIndex--; + colorMapIndex--; palOffset = PLTT_ID(startPalIndex); UpdateAltBgPalettes(palettes & PALETTES_BG); // Thunder gamma-shift looks bad on night-blended palettes, so ignore time blending in some situations - if (!(gammaIndex > 3) && MapHasNaturalLight(gMapHeader.mapType)) + if (!(colorMapIndex > 3) && MapHasNaturalLight(gMapHeader.mapType)) UpdatePalettesWithTime(palettes); else CpuFastCopy(gPlttBufferUnfaded + palOffset, gPlttBufferFaded + palOffset, PLTT_SIZE_4BPP * numPalettes); @@ -475,7 +458,7 @@ static void ApplyGammaShift(u8 startPalIndex, u8 numPalettes, s8 gammaIndex) // Loop through the speficied palette range and apply necessary gamma shifts to the colors. while (curPalIndex < numPalettes) { - if (sPaletteGammaTypes[curPalIndex] == GAMMA_NONE || + if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_NONE || (curPalIndex >= 16 && IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(curPalIndex - 16)))) { // No palette change. @@ -486,18 +469,18 @@ static void ApplyGammaShift(u8 startPalIndex, u8 numPalettes, s8 gammaIndex) { u8 r, g, b; - if (sPaletteGammaTypes[curPalIndex] == GAMMA_ALT || curPalIndex - 16 == gWeatherPtr->altGammaSpritePalIndex) - gammaTable = gWeatherPtr->altGammaShifts[gammaIndex]; + if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_CONTRAST || curPalIndex - 16 == gWeatherPtr->contrastColorMapSpritePalIndex) + colorMap = sContrastColorMaps[colorMapIndex]; else - gammaTable = gWeatherPtr->gammaShifts[gammaIndex]; + colorMap = sDarkenedContrastColorMaps[colorMapIndex]; for (i = 0; i < 16; i++) { // Apply gamma shift to the original color. struct RGBColor baseColor = *(struct RGBColor *)&gPlttBufferUnfaded[palOffset]; - r = gammaTable[baseColor.r]; - g = gammaTable[baseColor.g]; - b = gammaTable[baseColor.b]; + r = colorMap[baseColor.r]; + g = colorMap[baseColor.g]; + b = colorMap[baseColor.b]; gPlttBufferFaded[palOffset++] = (b << 10) | (g << 5) | r; } } @@ -505,10 +488,33 @@ static void ApplyGammaShift(u8 startPalIndex, u8 numPalettes, s8 gammaIndex) curPalIndex++; } } - else if (gammaIndex < 0) + else if (colorMapIndex < 0) { // A negative gammIndex value means that the blending will come from the special Drought weather's palette tables. - // Dummied out in FRLG + colorMapIndex = -colorMapIndex - 1; + palOffset = PLTT_ID(startPalIndex); + numPalettes += startPalIndex; + curPalIndex = startPalIndex; + + while (curPalIndex < numPalettes) + { + if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_NONE) + { + // No palette change. + CpuFastCopy(&gPlttBufferUnfaded[palOffset], &gPlttBufferFaded[palOffset], PLTT_SIZE_4BPP); + palOffset += 16; + } + else + { + for (i = 0; i < 16; i++) + { + gPlttBufferFaded[palOffset] = sDroughtWeatherColors[colorMapIndex][DROUGHT_COLOR_INDEX(gPlttBufferUnfaded[palOffset])]; + palOffset++; + } + } + + curPalIndex++; + } } else { @@ -527,7 +533,7 @@ static void ApplyGammaShift(u8 startPalIndex, u8 numPalettes, s8 gammaIndex) } } -static void ApplyGammaShiftWithBlend(u8 startPalIndex, u8 numPalettes, s8 gammaIndex, u8 blendCoeff, u32 blendColor) +static void ApplyColorMapWithBlend(u8 startPalIndex, u8 numPalettes, s8 colorMapIndex, u8 blendCoeff, u32 blendColor) { u16 palOffset; u16 curPalIndex; @@ -539,7 +545,7 @@ static void ApplyGammaShiftWithBlend(u8 startPalIndex, u8 numPalettes, s8 gammaI palOffset = PLTT_ID(startPalIndex); numPalettes += startPalIndex; - gammaIndex--; + colorMapIndex--; curPalIndex = startPalIndex; while (curPalIndex < numPalettes) @@ -547,7 +553,7 @@ static void ApplyGammaShiftWithBlend(u8 startPalIndex, u8 numPalettes, s8 gammaI UpdateAltBgPalettes((1 << (palOffset >> 4)) & PALETTES_BG); CpuFastCopy(gPlttBufferUnfaded + palOffset, gPlttBufferFaded + palOffset, 16 * sizeof(u16)); UpdatePalettesWithTime(1 << (palOffset >> 4)); // Apply TOD blend - if (sPaletteGammaTypes[curPalIndex] == GAMMA_NONE) + if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_NONE) { // No gamma shift. Simply blend the colors. BlendPalette(palOffset, 16, blendCoeff, blendColor); @@ -555,19 +561,19 @@ static void ApplyGammaShiftWithBlend(u8 startPalIndex, u8 numPalettes, s8 gammaI } else { - u8 *gammaTable; + const u8 *colorMap; - if (sPaletteGammaTypes[curPalIndex] == GAMMA_NORMAL) - gammaTable = gWeatherPtr->gammaShifts[gammaIndex]; + if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_DARK_CONTRAST) + colorMap = sDarkenedContrastColorMaps[colorMapIndex]; else - gammaTable = gWeatherPtr->altGammaShifts[gammaIndex]; + colorMap = sContrastColorMaps[colorMapIndex]; for (i = 0; i < 16; i++) { struct RGBColor baseColor = *(struct RGBColor *)&gPlttBufferUnfaded[palOffset]; - u8 r = gammaTable[baseColor.r]; - u8 g = gammaTable[baseColor.g]; - u8 b = gammaTable[baseColor.b]; + u8 r = colorMap[baseColor.r]; + u8 g = colorMap[baseColor.g]; + u8 b = colorMap[baseColor.b]; // Apply gamma shift and target blend color to the original color. r += ((rBlend - r) * blendCoeff) >> 4; @@ -581,7 +587,7 @@ static void ApplyGammaShiftWithBlend(u8 startPalIndex, u8 numPalettes, s8 gammaI } } -static void ApplyDroughtGammaShiftWithBlend(s8 gammaIndex, u8 blendCoeff, u32 blendColor) +static void ApplyDroughtColorMapWithBlend(s8 colorMapIndex, u8 blendCoeff, u32 blendColor) { struct RGBColor color; u8 rBlend; @@ -591,7 +597,7 @@ static void ApplyDroughtGammaShiftWithBlend(s8 gammaIndex, u8 blendCoeff, u32 bl u16 palOffset; u16 i; - gammaIndex = -gammaIndex - 1; + colorMapIndex = -colorMapIndex - 1; color = *(struct RGBColor *)&blendColor; rBlend = color.r; gBlend = color.g; @@ -599,9 +605,9 @@ static void ApplyDroughtGammaShiftWithBlend(s8 gammaIndex, u8 blendCoeff, u32 bl palOffset = 0; for (curPalIndex = 0; curPalIndex < 32; curPalIndex++) { - if (sPaletteGammaTypes[curPalIndex] == GAMMA_NONE) + if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_NONE) { - // No gamma shift. Simply blend the colors. + // No color map. Simply blend the colors. BlendPalette(palOffset, 16, blendCoeff, blendColor); palOffset += 16; } @@ -609,19 +615,28 @@ static void ApplyDroughtGammaShiftWithBlend(s8 gammaIndex, u8 blendCoeff, u32 bl { for (i = 0; i < 16; i++) { + u32 offset; struct RGBColor color1; + struct RGBColor color2; u8 r1, g1, b1; + u8 r2, g2, b2; color1 = *(struct RGBColor *)&gPlttBufferUnfaded[palOffset]; r1 = color1.r; g1 = color1.g; b1 = color1.b; - r1 += ((rBlend - r1) * blendCoeff) >> 4; - g1 += ((gBlend - g1) * blendCoeff) >> 4; - b1 += ((bBlend - b1) * blendCoeff) >> 4; + offset = ((b1 & 0x1E) << 7) | ((g1 & 0x1E) << 3) | ((r1 & 0x1E) >> 1); + color2 = *(struct RGBColor *)&sDroughtWeatherColors[colorMapIndex][offset]; + r2 = color2.r; + g2 = color2.g; + b2 = color2.b; - gPlttBufferFaded[palOffset++] = (b1 << 10) | (g1 << 5) | r1; + r2 += ((rBlend - r2) * blendCoeff) >> 4; + g2 += ((gBlend - g2) * blendCoeff) >> 4; + b2 += ((bBlend - b2) * blendCoeff) >> 4; + + gPlttBufferFaded[palOffset++] = RGB2(r2, g2, b2); } } } @@ -671,25 +686,25 @@ static bool8 LightenSpritePaletteInFog(u8 paletteIndex) return FALSE; } -void WeatherShiftGammaIfPalStateIdle(s8 gammaIndex) +void ApplyWeatherColorMapIfIdle(s8 colorMapIndex) { if (gWeatherPtr->palProcessingState == WEATHER_PAL_STATE_IDLE) { - ApplyGammaShift(0, 32, gammaIndex); - gWeatherPtr->gammaIndex = gammaIndex; + ApplyColorMap(0, 32, colorMapIndex); + gWeatherPtr->colorMapIndex = colorMapIndex; } } -void WeatherBeginGammaFade(u8 gammaIndex, u8 gammaTargetIndex, u8 gammaStepDelay) +void ApplyWeatherColorMapIfIdle_Gradual(u8 colorMapIndex, u8 targetColorMapIndex, u8 colorMapStepDelay) { if (gWeatherPtr->palProcessingState == WEATHER_PAL_STATE_IDLE) { gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_CHANGING_WEATHER; - gWeatherPtr->gammaIndex = gammaIndex; - gWeatherPtr->gammaTargetIndex = gammaTargetIndex; - gWeatherPtr->gammaStepFrameCounter = 0; - gWeatherPtr->gammaStepDelay = gammaStepDelay; - WeatherShiftGammaIfPalStateIdle(gammaIndex); + gWeatherPtr->colorMapIndex = colorMapIndex; + gWeatherPtr->targetColorMapIndex = targetColorMapIndex; + gWeatherPtr->colorMapStepCounter = 0; + gWeatherPtr->colorMapStepDelay = colorMapStepDelay; + ApplyWeatherColorMapIfIdle(colorMapIndex); } } @@ -873,8 +888,8 @@ void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex, bool32 allowFog) default: if (gWeatherPtr->currWeather != WEATHER_FOG_HORIZONTAL) { - if (gWeatherPtr->gammaIndex) - ApplyGammaShift(paletteIndex, 1, gWeatherPtr->gammaIndex); + if (gWeatherPtr->colorMapIndex) + ApplyColorMap(paletteIndex, 1, gWeatherPtr->colorMapIndex); else UpdateSpritePaletteWithTime(spritePaletteIndex); } @@ -901,9 +916,9 @@ void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex, bool32 allowFog) } } -void ApplyWeatherGammaShiftToPal(u8 paletteIndex) +void ApplyWeatherColorMapToPal(u8 paletteIndex) { - ApplyGammaShift(paletteIndex, 1, gWeatherPtr->gammaIndex); + ApplyColorMap(paletteIndex, 1, gWeatherPtr->colorMapIndex); } void LoadCustomWeatherSpritePalette(const u16 *palette) @@ -912,11 +927,10 @@ void LoadCustomWeatherSpritePalette(const u16 *palette) UpdateSpritePaletteWithWeather(gWeatherPtr->weatherPicSpritePalIndex, TRUE); } -static void LoadDroughtWeatherPalette(u8 *gammaIndexPtr, u8 *a1) +static void LoadDroughtWeatherPalette(u8 *palsIndex, u8 *palsOffset) { - // Dummied out in FRLG - // *gammaIndexPtr = 0x20; - // *a1 = 0x20; + *palsIndex = 0x20; + *palsOffset = 0x20; } void ResetDroughtWeatherPaletteLoading(void) @@ -936,9 +950,9 @@ bool8 LoadDroughtWeatherPalettes(void) return FALSE; } -static void SetDroughtGamma(s8 gammaIndex) +static void SetDroughtColorMap(s8 colorMapIndex) { - WeatherShiftGammaIfPalStateIdle(-gammaIndex - 1); + ApplyWeatherColorMapIfIdle(-colorMapIndex - 1); } void DroughtStateInit(void) @@ -959,7 +973,7 @@ void DroughtStateRun(void) if (++gWeatherPtr->droughtTimer > sDroughtFrameDelay) { gWeatherPtr->droughtTimer = 0; - SetDroughtGamma(gWeatherPtr->droughtBrightnessStage++); + SetDroughtColorMap(gWeatherPtr->droughtBrightnessStage++); if (gWeatherPtr->droughtBrightnessStage > 5) { gWeatherPtr->droughtLastBrightnessStage = gWeatherPtr->droughtBrightnessStage; @@ -973,7 +987,7 @@ void DroughtStateRun(void) gWeatherPtr->droughtTimer = (gWeatherPtr->droughtTimer + 3) & 0x7F; gWeatherPtr->droughtBrightnessStage = ((gSineTable[gWeatherPtr->droughtTimer] - 1) >> 6) + 2; if (gWeatherPtr->droughtBrightnessStage != gWeatherPtr->droughtLastBrightnessStage) - SetDroughtGamma(gWeatherPtr->droughtBrightnessStage); + SetDroughtColorMap(gWeatherPtr->droughtBrightnessStage); gWeatherPtr->droughtLastBrightnessStage = gWeatherPtr->droughtBrightnessStage; break; case 2: @@ -981,7 +995,7 @@ void DroughtStateRun(void) if (++gWeatherPtr->droughtTimer > sDroughtFrameDelay) { gWeatherPtr->droughtTimer = 0; - SetDroughtGamma(--gWeatherPtr->droughtBrightnessStage); + SetDroughtColorMap(--gWeatherPtr->droughtBrightnessStage); if (gWeatherPtr->droughtBrightnessStage == 3) gWeatherPtr->droughtState = 0; } @@ -1109,14 +1123,14 @@ void WeatherProcessingIdle(void) void PreservePaletteInWeather(u8 preservedPalIndex) { - CpuCopy16(sBasePaletteGammaTypes, sFieldEffectPaletteGammaTypes, 32); - sFieldEffectPaletteGammaTypes[preservedPalIndex] = GAMMA_NONE; - sPaletteGammaTypes = sFieldEffectPaletteGammaTypes; + CpuCopy16(sBasePaletteColorMapTypes, sFieldEffectPaletteColorMapTypes, 32); + sFieldEffectPaletteColorMapTypes[preservedPalIndex] = COLOR_MAP_NONE; + sPaletteColorMapTypes = sFieldEffectPaletteColorMapTypes; } void ResetPreservedPalettesInWeather(void) { - sPaletteGammaTypes = sBasePaletteGammaTypes; + sPaletteColorMapTypes = sBasePaletteColorMapTypes; } void SlightlyDarkenPalsInWeather(u16 *palbuf, u16 *unused, u32 size) diff --git a/src/field_weather_effects.c b/src/field_weather_effects.c index 6d69e3552..d18668545 100644 --- a/src/field_weather_effects.c +++ b/src/field_weather_effects.c @@ -70,8 +70,8 @@ static const struct SpriteTemplate sCloudSpriteTemplate = { void Clouds_InitVars(void) { - gWeatherPtr->gammaTargetIndex = 0; - gWeatherPtr->gammaStepDelay = 20; + gWeatherPtr->targetColorMapIndex = 0; + gWeatherPtr->colorMapStepDelay = 20; gWeatherPtr->weatherGfxLoaded = FALSE; gWeatherPtr->initStep = 0; if (!gWeatherPtr->cloudSpritesCreated) @@ -128,8 +128,8 @@ bool8 Clouds_Finish(void) void Sunny_InitVars(void) { - gWeatherPtr->gammaTargetIndex = 0; - gWeatherPtr->gammaStepDelay = 20; + gWeatherPtr->targetColorMapIndex = 0; + gWeatherPtr->colorMapStepDelay = 20; } void Sunny_InitAll(void) @@ -211,8 +211,8 @@ void Drought_InitVars(void) { gWeatherPtr->initStep = 0; gWeatherPtr->weatherGfxLoaded = FALSE; - gWeatherPtr->gammaTargetIndex = 0; - gWeatherPtr->gammaStepDelay = 0; + gWeatherPtr->targetColorMapIndex = 0; + gWeatherPtr->colorMapStepDelay = 0; } void Drought_InitAll(void) @@ -442,8 +442,8 @@ void Rain_InitVars(void) gWeatherPtr->rainSpriteVisibleDelay = 8; gWeatherPtr->isDownpour = FALSE; gWeatherPtr->targetRainSpriteCount = 10; - gWeatherPtr->gammaTargetIndex = 3; - gWeatherPtr->gammaStepDelay = 20; + gWeatherPtr->targetColorMapIndex = 3; + gWeatherPtr->colorMapStepDelay = 20; SetRainStrengthFromSoundEffect(SE_RAIN); } @@ -734,9 +734,9 @@ void Snow_InitVars(void) { gWeatherPtr->initStep = 0; gWeatherPtr->weatherGfxLoaded = FALSE; - gWeatherPtr->gammaTargetIndex = 3; - gWeatherPtr->gammaStepDelay = 20; - gWeatherPtr->targetSnowflakeSpriteCount = 16; + gWeatherPtr->targetColorMapIndex = 3; + gWeatherPtr->colorMapStepDelay = 20; + gWeatherPtr->targetSnowflakeSpriteCount = NUM_SNOWFLAKE_SPRITES; gWeatherPtr->snowflakeVisibleCounter = 0; } @@ -1002,10 +1002,10 @@ void Thunderstorm_InitVars(void) gWeatherPtr->rainSpriteVisibleDelay = 4; gWeatherPtr->isDownpour = FALSE; gWeatherPtr->targetRainSpriteCount = 16; - gWeatherPtr->gammaTargetIndex = 3; - gWeatherPtr->gammaStepDelay = 20; + gWeatherPtr->targetColorMapIndex = 3; + gWeatherPtr->colorMapStepDelay = 20; gWeatherPtr->weatherGfxLoaded = FALSE; // duplicate assignment - gWeatherPtr->thunderTriggered = FALSE; + gWeatherPtr->thunderEnqueued = FALSE; SetRainStrengthFromSoundEffect(SE_THUNDERSTORM); } @@ -1031,8 +1031,8 @@ void Downpour_InitVars(void) gWeatherPtr->rainSpriteVisibleDelay = 4; gWeatherPtr->isDownpour = TRUE; gWeatherPtr->targetRainSpriteCount = 24; - gWeatherPtr->gammaTargetIndex = 3; - gWeatherPtr->gammaStepDelay = 20; + gWeatherPtr->targetColorMapIndex = 3; + gWeatherPtr->colorMapStepDelay = 20; gWeatherPtr->weatherGfxLoaded = FALSE; // duplicate assignment SetRainStrengthFromSoundEffect(SE_DOWNPOUR); } @@ -1070,43 +1070,43 @@ void Thunderstorm_Main(void) break; case TSTORM_STATE_LOOP_START: gWeatherPtr->thunderAllowEnd = TRUE; - gWeatherPtr->thunderDelay = (Random() % 360) + 360; + gWeatherPtr->thunderTimer = (Random() % 360) + 360; gWeatherPtr->initStep++; // fall through case TSTORM_STATE_LOOP_WAIT: // Wait between 360-720 frames before trying thunder again - if (--gWeatherPtr->thunderDelay == 0) + if (--gWeatherPtr->thunderTimer == 0) gWeatherPtr->initStep++; break; case TSTORM_STATE_INIT_THUNDER_SHORT_1: gWeatherPtr->thunderAllowEnd = TRUE; - gWeatherPtr->thunderSkipShort = Random() % 2; + gWeatherPtr->thunderLongBolt = Random() % 2; gWeatherPtr->initStep++; break; case TSTORM_STATE_INIT_THUNDER_SHORT_2: - gWeatherPtr->thunderShortRetries = (Random() & 1) + 1; + gWeatherPtr->thunderShortBolts = (Random() & 1) + 1; gWeatherPtr->initStep++; // fall through case TSTORM_STATE_TRY_THUNDER_SHORT: - WeatherShiftGammaIfPalStateIdle(19); - if (!gWeatherPtr->thunderSkipShort && gWeatherPtr->thunderShortRetries == 1) + ApplyWeatherColorMapIfIdle(19); + if (!gWeatherPtr->thunderLongBolt && gWeatherPtr->thunderShortBolts == 1) SetThunderCounter(20); // Do short thunder - gWeatherPtr->thunderDelay = (Random() % 3) + 6; + gWeatherPtr->thunderTimer = (Random() % 3) + 6; gWeatherPtr->initStep++; break; case TSTORM_STATE_TRY_NEW_THUNDER: - if (--gWeatherPtr->thunderDelay == 0) + if (--gWeatherPtr->thunderTimer == 0) { - WeatherShiftGammaIfPalStateIdle(3); + ApplyWeatherColorMapIfIdle(3); gWeatherPtr->thunderAllowEnd = TRUE; - if (--gWeatherPtr->thunderShortRetries != 0) + if (--gWeatherPtr->thunderShortBolts != 0) { // Try a short thunder again - gWeatherPtr->thunderDelay = (Random() % 16) + 60; + gWeatherPtr->thunderTimer = (Random() % 16) + 60; gWeatherPtr->initStep = TSTORM_STATE_WAIT_THUNDER_SHORT; } - else if (!gWeatherPtr->thunderSkipShort) + else if (!gWeatherPtr->thunderLongBolt) { // No more thunder, restart loop gWeatherPtr->initStep = TSTORM_STATE_LOOP_START; @@ -1119,27 +1119,27 @@ void Thunderstorm_Main(void) } break; case TSTORM_STATE_WAIT_THUNDER_SHORT: - if (--gWeatherPtr->thunderDelay == 0) + if (--gWeatherPtr->thunderTimer == 0) gWeatherPtr->initStep = TSTORM_STATE_TRY_THUNDER_SHORT; break; case TSTORM_STATE_INIT_THUNDER_LONG: - gWeatherPtr->thunderDelay = (Random() % 16) + 60; + gWeatherPtr->thunderTimer = (Random() % 16) + 60; gWeatherPtr->initStep++; break; case TSTORM_STATE_WAIT_THUNDER_LONG: - if (--gWeatherPtr->thunderDelay == 0) + if (--gWeatherPtr->thunderTimer == 0) { // Do long thunder SetThunderCounter(100); - WeatherShiftGammaIfPalStateIdle(19); - gWeatherPtr->thunderDelay = (Random() & 0xF) + 30; + ApplyWeatherColorMapIfIdle(19); + gWeatherPtr->thunderTimer = (Random() & 0xF) + 30; gWeatherPtr->initStep++; } break; case TSTORM_STATE_FADE_THUNDER_LONG: - if (--gWeatherPtr->thunderDelay == 0) + if (--gWeatherPtr->thunderTimer == 0) { - WeatherBeginGammaFade(19, 3, 5); + ApplyWeatherColorMapIfIdle_Gradual(19, 3, 5); gWeatherPtr->initStep++; } break; @@ -1178,7 +1178,7 @@ bool8 Thunderstorm_Finish(void) if (!UpdateVisibleRainSprites()) { DestroyRainSprites(); - gWeatherPtr->thunderTriggered = FALSE; + gWeatherPtr->thunderEnqueued = FALSE; gWeatherPtr->finishStep++; return FALSE; } @@ -1191,18 +1191,18 @@ bool8 Thunderstorm_Finish(void) static void SetThunderCounter(u16 max) { - if (!gWeatherPtr->thunderTriggered) + if (!gWeatherPtr->thunderEnqueued) { - gWeatherPtr->thunderCounter = Random() % max; - gWeatherPtr->thunderTriggered = TRUE; + gWeatherPtr->thunderSETimer = Random() % max; + gWeatherPtr->thunderEnqueued = TRUE; } } static void UpdateThunderSound(void) { - if (gWeatherPtr->thunderTriggered == TRUE) + if (gWeatherPtr->thunderEnqueued == TRUE) { - if (gWeatherPtr->thunderCounter == 0) + if (gWeatherPtr->thunderSETimer == 0) { if (IsSEPlaying()) return; @@ -1212,11 +1212,11 @@ static void UpdateThunderSound(void) else PlaySE(SE_THUNDER2); - gWeatherPtr->thunderTriggered = FALSE; + gWeatherPtr->thunderEnqueued = FALSE; } else { - gWeatherPtr->thunderCounter--; + gWeatherPtr->thunderSETimer--; } } } @@ -1309,8 +1309,8 @@ void FogHorizontal_InitVars(void) { gWeatherPtr->initStep = 0; gWeatherPtr->weatherGfxLoaded = FALSE; - gWeatherPtr->gammaTargetIndex = 0; - gWeatherPtr->gammaStepDelay = 20; + gWeatherPtr->targetColorMapIndex = 0; + gWeatherPtr->colorMapStepDelay = 20; if (!gWeatherPtr->fogHSpritesCreated) { gWeatherPtr->fogHScrollCounter = 0; @@ -1464,8 +1464,8 @@ void Ash_InitVars(void) { gWeatherPtr->initStep = 0; gWeatherPtr->weatherGfxLoaded = FALSE; - gWeatherPtr->gammaTargetIndex = 0; - gWeatherPtr->gammaStepDelay = 20; + gWeatherPtr->targetColorMapIndex = 0; + gWeatherPtr->colorMapStepDelay = 20; gWeatherPtr->ashUnused = 20; // Never read if (!gWeatherPtr->ashSpritesCreated) { @@ -1669,8 +1669,8 @@ void FogDiagonal_InitVars(void) { gWeatherPtr->initStep = 0; gWeatherPtr->weatherGfxLoaded = 0; - gWeatherPtr->gammaTargetIndex = 0; - gWeatherPtr->gammaStepDelay = 20; + gWeatherPtr->targetColorMapIndex = 0; + gWeatherPtr->colorMapStepDelay = 20; gWeatherPtr->fogHScrollCounter = 0; gWeatherPtr->fogHScrollOffset = 1; if (!gWeatherPtr->fogDSpritesCreated) @@ -1878,8 +1878,8 @@ void Sandstorm_InitVars(void) { gWeatherPtr->initStep = 0; gWeatherPtr->weatherGfxLoaded = 0; - gWeatherPtr->gammaTargetIndex = 0; - gWeatherPtr->gammaStepDelay = 20; + gWeatherPtr->targetColorMapIndex = 0; + gWeatherPtr->colorMapStepDelay = 20; if (!gWeatherPtr->sandstormSpritesCreated) { gWeatherPtr->sandstormXOffset = gWeatherPtr->sandstormYOffset = 0; @@ -2169,8 +2169,8 @@ static void UpdateSandstormSwirlSprite(struct Sprite *sprite) void Shade_InitVars(void) { gWeatherPtr->initStep = 0; - gWeatherPtr->gammaTargetIndex = 3; - gWeatherPtr->gammaStepDelay = 20; + gWeatherPtr->targetColorMapIndex = 3; + gWeatherPtr->colorMapStepDelay = 20; } void Shade_InitAll(void) diff --git a/src/overworld.c b/src/overworld.c index 9285b0b3c..af44656cc 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -789,8 +789,8 @@ void LoadMapFromCameraTransition(u8 mapGroup, u8 mapNum) InitMap(); CopySecondaryTilesetToVramUsingHeap(gMapHeader.mapLayout); LoadSecondaryTilesetPalette(gMapHeader.mapLayout); - for (paletteIndex = 7; paletteIndex < 13; paletteIndex++) - ApplyWeatherGammaShiftToPal(paletteIndex); + for (paletteIndex = NUM_PALS_IN_PRIMARY; paletteIndex < NUM_PALS_TOTAL; paletteIndex++) + ApplyWeatherColorMapToPal(paletteIndex); InitSecondaryTilesetAnimation(); UpdateLocationHistoryForRoamer(); RoamerMove();