pokeemerald/src/field_weather.c

1132 lines
36 KiB
C
Raw Normal View History

2018-12-08 19:05:03 +01:00
#include "global.h"
#include "constants/songs.h"
#include "constants/weather.h"
#include "constants/rgb.h"
#include "util.h"
#include "event_object_movement.h"
#include "field_weather.h"
#include "main.h"
#include "menu.h"
#include "palette.h"
#include "random.h"
#include "script.h"
#include "start_menu.h"
#include "sound.h"
#include "sprite.h"
#include "task.h"
#include "trig.h"
#include "gpu_regs.h"
2023-08-19 01:40:31 -05:00
#include "field_camera.h"
2023-11-11 20:08:20 +01:00
#include "overworld.h"
2018-12-08 19:05:03 +01:00
#define DROUGHT_COLOR_INDEX(color) ((((color) >> 1) & 0xF) | (((color) >> 2) & 0xF0) | (((color) >> 3) & 0xF00))
2018-12-08 19:05:03 +01:00
enum
{
2022-10-16 13:06:43 -05:00
COLOR_MAP_NONE,
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_CONTRAST,
2018-12-08 19:05:03 +01:00
};
struct RGBColor
{
u16 r:5;
u16 g:5;
u16 b:5;
};
struct WeatherCallbacks
{
void (*initVars)(void);
void (*main)(void);
void (*initAll)(void);
bool8 (*finish)(void);
};
// This file's functions.
2018-12-08 19:43:21 +01:00
static bool8 LightenSpritePaletteInFog(u8);
2022-10-16 13:06:43 -05:00
static void BuildColorMaps(void);
static void UpdateWeatherColorMap(void);
static void ApplyColorMap(u8 startPalIndex, u8 numPalettes, s8 colorMapIndex);
static void ApplyColorMapWithBlend(u8 startPalIndex, u8 numPalettes, s8 colorMapIndex, u8 blendCoeff, u16 blendColor);
static void ApplyDroughtColorMapWithBlend(s8 colorMapIndex, u8 blendCoeff, u16 blendColor);
2018-12-08 19:43:21 +01:00
static void ApplyFogBlend(u8 blendCoeff, u16 blendColor);
static bool8 FadeInScreen_RainShowShade(void);
static bool8 FadeInScreen_Drought(void);
static bool8 FadeInScreen_FogHorizontal(void);
2018-12-08 19:43:21 +01:00
static void FadeInScreenWithWeather(void);
static void DoNothing(void);
static void Task_WeatherInit(u8 taskId);
static void Task_WeatherMain(u8 taskId);
static void None_Init(void);
static void None_Main(void);
static u8 None_Finish(void);
EWRAM_DATA struct Weather gWeather = {0};
EWRAM_DATA static u8 ALIGNED(2) sFieldEffectPaletteColorMapTypes[32] = {0};
2018-12-08 19:43:21 +01:00
2022-10-16 13:06:43 -05:00
static const u8 *sPaletteColorMapTypes;
2018-12-08 19:43:21 +01:00
// The drought weather effect uses a precalculated color lookup table. Presumably this
// is because the underlying color shift calculation is slow.
2022-05-17 13:51:54 -04:00
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"),
};
2018-12-08 19:43:21 +01:00
2018-12-09 12:16:01 +01:00
// This is a pointer to gWeather. All code in this file accesses gWeather directly,
2018-12-08 19:05:03 +01:00
// while code in other field weather files accesses gWeather through this pointer.
// This is likely the result of compiler optimization, since using the pointer in
// this file produces the same result as accessing gWeather directly.
struct Weather *const gWeatherPtr = &gWeather;
2018-12-08 19:43:21 +01:00
static const struct WeatherCallbacks sWeatherFuncs[] =
2018-12-08 19:05:03 +01:00
{
[WEATHER_NONE] = {None_Init, None_Main, None_Init, None_Finish},
[WEATHER_SUNNY_CLOUDS] = {Clouds_InitVars, Clouds_Main, Clouds_InitAll, Clouds_Finish},
[WEATHER_SUNNY] = {Sunny_InitVars, Sunny_Main, Sunny_InitAll, Sunny_Finish},
[WEATHER_RAIN] = {Rain_InitVars, Rain_Main, Rain_InitAll, Rain_Finish},
[WEATHER_SNOW] = {Snow_InitVars, Snow_Main, Snow_InitAll, Snow_Finish},
[WEATHER_RAIN_THUNDERSTORM] = {Thunderstorm_InitVars, Thunderstorm_Main, Thunderstorm_InitAll, Thunderstorm_Finish},
[WEATHER_FOG_HORIZONTAL] = {FogHorizontal_InitVars, FogHorizontal_Main, FogHorizontal_InitAll, FogHorizontal_Finish},
[WEATHER_VOLCANIC_ASH] = {Ash_InitVars, Ash_Main, Ash_InitAll, Ash_Finish},
[WEATHER_SANDSTORM] = {Sandstorm_InitVars, Sandstorm_Main, Sandstorm_InitAll, Sandstorm_Finish},
[WEATHER_FOG_DIAGONAL] = {FogDiagonal_InitVars, FogDiagonal_Main, FogDiagonal_InitAll, FogDiagonal_Finish},
[WEATHER_UNDERWATER] = {FogHorizontal_InitVars, FogHorizontal_Main, FogHorizontal_InitAll, FogHorizontal_Finish},
[WEATHER_SHADE] = {Shade_InitVars, Shade_Main, Shade_InitAll, Shade_Finish},
[WEATHER_DROUGHT] = {Drought_InitVars, Drought_Main, Drought_InitAll, Drought_Finish},
[WEATHER_DOWNPOUR] = {Downpour_InitVars, Thunderstorm_Main, Downpour_InitAll, Thunderstorm_Finish},
[WEATHER_UNDERWATER_BUBBLES] = {Bubbles_InitVars, Bubbles_Main, Bubbles_InitAll, Bubbles_Finish},
2018-12-08 19:05:03 +01:00
};
void (*const gWeatherPalStateFuncs[])(void) =
{
2022-10-16 13:06:43 -05:00
[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,
2018-12-08 19:05:03 +01:00
};
2022-10-16 13:06:43 -05:00
// This table specifies which of the color maps should be
2018-12-08 19:05:03 +01:00
// applied to each of the background and sprite palettes.
static const u8 ALIGNED(2) sBasePaletteColorMapTypes[32] =
2018-12-08 19:05:03 +01:00
{
// background palettes
2022-10-16 13:06:43 -05:00
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_NONE,
COLOR_MAP_NONE,
2018-12-08 19:05:03 +01:00
// sprite palettes
2022-10-16 13:06:43 -05:00
COLOR_MAP_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
2023-11-11 20:08:20 +01:00
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
2022-10-16 13:06:43 -05:00
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
COLOR_MAP_DARK_CONTRAST,
2018-12-08 19:05:03 +01:00
};
const u16 ALIGNED(4) gFogPalette[] = INCBIN_U16("graphics/weather/fog.gbapal");
2018-12-08 19:05:03 +01:00
void StartWeather(void)
{
if (!FuncIsActiveTask(Task_WeatherMain))
{
2022-10-16 13:06:43 -05:00
u8 index = AllocSpritePalette(PALTAG_WEATHER);
2023-05-23 13:16:18 -04:00
CpuCopy32(gFogPalette, &gPlttBufferUnfaded[OBJ_PLTT_ID(index)], PLTT_SIZE_4BPP);
2022-10-16 13:06:43 -05:00
BuildColorMaps();
gWeatherPtr->contrastColorMapSpritePalIndex = index;
2023-11-11 20:08:20 +01:00
gWeatherPtr->weatherPicSpritePalIndex = 0xFF;
2018-12-08 19:43:21 +01:00
gWeatherPtr->rainSpriteCount = 0;
2019-03-31 21:07:29 -05:00
gWeatherPtr->curRainSpriteIndex = 0;
2018-12-08 19:43:21 +01:00
gWeatherPtr->cloudSpritesCreated = 0;
gWeatherPtr->snowflakeSpriteCount = 0;
gWeatherPtr->ashSpritesCreated = 0;
gWeatherPtr->fogHSpritesCreated = 0;
gWeatherPtr->fogDSpritesCreated = 0;
gWeatherPtr->sandstormSpritesCreated = 0;
gWeatherPtr->sandstormSwirlSpritesCreated = 0;
gWeatherPtr->bubblesSpritesCreated = 0;
2018-12-08 19:43:21 +01:00
gWeatherPtr->lightenedFogSpritePalsCount = 0;
2018-12-08 19:05:03 +01:00
Weather_SetBlendCoeffs(16, 0);
2018-12-08 19:43:21 +01:00
gWeatherPtr->currWeather = 0;
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_IDLE;
gWeatherPtr->readyForInit = FALSE;
gWeatherPtr->weatherChangeComplete = TRUE;
gWeatherPtr->taskId = CreateTask(Task_WeatherInit, 80);
2018-12-08 19:05:03 +01:00
}
}
void SetNextWeather(u8 weather)
2018-12-08 19:05:03 +01:00
{
2019-12-01 19:19:47 -05:00
if (weather != WEATHER_RAIN && weather != WEATHER_RAIN_THUNDERSTORM && weather != WEATHER_DOWNPOUR)
2018-12-08 19:05:03 +01:00
{
PlayRainStoppingSoundEffect();
2018-12-08 19:05:03 +01:00
}
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->nextWeather != weather && gWeatherPtr->currWeather == weather)
2018-12-08 19:05:03 +01:00
{
sWeatherFuncs[weather].initVars();
}
2018-12-08 19:43:21 +01:00
gWeatherPtr->weatherChangeComplete = FALSE;
gWeatherPtr->nextWeather = weather;
gWeatherPtr->finishStep = 0;
2018-12-08 19:05:03 +01:00
}
void SetCurrentAndNextWeather(u8 weather)
2018-12-08 19:05:03 +01:00
{
PlayRainStoppingSoundEffect();
2018-12-08 19:43:21 +01:00
gWeatherPtr->currWeather = weather;
gWeatherPtr->nextWeather = weather;
2018-12-08 19:05:03 +01:00
}
void SetCurrentAndNextWeatherNoDelay(u8 weather)
2018-12-08 19:05:03 +01:00
{
PlayRainStoppingSoundEffect();
2018-12-08 19:43:21 +01:00
gWeatherPtr->currWeather = weather;
gWeatherPtr->nextWeather = weather;
// Overrides the normal delay during screen fading.
2018-12-08 19:43:21 +01:00
gWeatherPtr->readyForInit = TRUE;
2018-12-08 19:05:03 +01:00
}
2018-12-08 19:43:21 +01:00
static void Task_WeatherInit(u8 taskId)
2018-12-08 19:05:03 +01:00
{
// Waits until it's ok to initialize weather.
// When the screen fades in, this is set to TRUE.
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->readyForInit)
2018-12-08 19:05:03 +01:00
{
2023-08-19 01:40:31 -05:00
UpdateCameraPanning();
2018-12-08 19:43:21 +01:00
sWeatherFuncs[gWeatherPtr->currWeather].initAll();
2018-12-08 19:05:03 +01:00
gTasks[taskId].func = Task_WeatherMain;
}
}
2018-12-08 19:43:21 +01:00
static void Task_WeatherMain(u8 taskId)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->currWeather != gWeatherPtr->nextWeather)
2018-12-08 19:05:03 +01:00
{
2019-03-31 21:07:29 -05:00
if (!sWeatherFuncs[gWeatherPtr->currWeather].finish()
&& gWeatherPtr->palProcessingState != WEATHER_PAL_STATE_SCREEN_FADING_OUT)
2018-12-08 19:05:03 +01:00
{
// Finished cleaning up previous weather. Now transition to next weather.
2018-12-08 19:43:21 +01:00
sWeatherFuncs[gWeatherPtr->nextWeather].initVars();
2022-10-16 13:06:43 -05:00
gWeatherPtr->colorMapStepCounter = 0;
2018-12-08 19:43:21 +01:00
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_CHANGING_WEATHER;
gWeatherPtr->currWeather = gWeatherPtr->nextWeather;
gWeatherPtr->weatherChangeComplete = TRUE;
2018-12-08 19:05:03 +01:00
}
}
else
{
2018-12-08 19:43:21 +01:00
sWeatherFuncs[gWeatherPtr->currWeather].main();
2018-12-08 19:05:03 +01:00
}
2018-12-08 19:43:21 +01:00
gWeatherPalStateFuncs[gWeatherPtr->palProcessingState]();
2018-12-08 19:05:03 +01:00
}
2018-12-08 19:43:21 +01:00
static void None_Init(void)
2018-12-08 19:05:03 +01:00
{
2023-11-11 20:08:20 +01:00
Weather_SetBlendCoeffs(8, 12);
gWeatherPtr->noShadows = FALSE;
2022-10-16 13:06:43 -05:00
gWeatherPtr->targetColorMapIndex = 0;
gWeatherPtr->colorMapStepDelay = 0;
2018-12-08 19:05:03 +01:00
}
2018-12-08 19:43:21 +01:00
static void None_Main(void)
2018-12-08 19:05:03 +01:00
{
}
2018-12-08 19:43:21 +01:00
static u8 None_Finish(void)
2018-12-08 19:05:03 +01:00
{
return 0;
}
2022-10-16 13:06:43 -05:00
// Builds two tables that contain color maps, used for directly transforming
// palette colors in weather effects. The colors maps are a spectrum of
// brightness + contrast mappings. By transitioning between the maps, weather
// effects like lightning are created.
2018-12-08 19:05:03 +01:00
// It's unclear why the two tables aren't declared as const arrays, since
// this function always builds the same two tables.
2022-10-16 13:06:43 -05:00
static void BuildColorMaps(void)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
u16 i;
u8 (*colorMaps)[32];
u16 colorVal;
u16 curBrightness;
u16 brightnessDelta;
u16 colorMapIndex;
u16 baseBrightness;
u32 remainingBrightness;
s16 diff;
sPaletteColorMapTypes = sBasePaletteColorMapTypes;
for (i = 0; i < 2; i++)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
if (i == 0)
colorMaps = gWeatherPtr->darkenedContrastColorMaps;
2018-12-08 19:05:03 +01:00
else
2022-10-16 13:06:43 -05:00
colorMaps = gWeatherPtr->contrastColorMaps;
2018-12-08 19:05:03 +01:00
2022-10-16 13:06:43 -05:00
for (colorVal = 0; colorVal < 32; colorVal++)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
curBrightness = colorVal << 8;
if (i == 0)
brightnessDelta = (colorVal << 8) / 16;
2018-12-08 19:05:03 +01:00
else
2022-10-16 13:06:43 -05:00
brightnessDelta = 0;
// First three color mappings are simple brightness modifiers which are
// progressively darker, according to brightnessDelta.
for (colorMapIndex = 0; colorMapIndex < 3; colorMapIndex++)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
curBrightness -= brightnessDelta;
colorMaps[colorMapIndex][colorVal] = curBrightness >> 8;
2018-12-08 19:05:03 +01:00
}
2022-10-16 13:06:43 -05:00
baseBrightness = curBrightness;
remainingBrightness = 0x1f00 - curBrightness;
if ((0x1f00 - curBrightness) < 0)
remainingBrightness += 0xf;
brightnessDelta = remainingBrightness / (NUM_WEATHER_COLOR_MAPS - 3);
if (colorVal < 12)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
// For shadows (color values < 12), the remaining color mappings are
// brightness modifiers, which are increased at a significantly lower rate
// than the midtones and highlights (color values >= 12). This creates a
// high contrast effect, used in the thunderstorm weather.
for (; colorMapIndex < NUM_WEATHER_COLOR_MAPS; colorMapIndex++)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
curBrightness += brightnessDelta;
diff = curBrightness - baseBrightness;
if (diff > 0)
curBrightness -= diff / 2;
colorMaps[colorMapIndex][colorVal] = curBrightness >> 8;
if (colorMaps[colorMapIndex][colorVal] > 31)
colorMaps[colorMapIndex][colorVal] = 31;
2018-12-08 19:05:03 +01:00
}
}
else
{
2022-10-16 13:06:43 -05:00
// For midtones and highlights (color values >= 12), the remaining
// color mappings are simple brightness modifiers which are
// progressively brighter, hitting exactly 31 at the last mapping.
for (; colorMapIndex < NUM_WEATHER_COLOR_MAPS; colorMapIndex++)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
curBrightness += brightnessDelta;
colorMaps[colorMapIndex][colorVal] = curBrightness >> 8;
if (colorMaps[colorMapIndex][colorVal] > 31)
colorMaps[colorMapIndex][colorVal] = 31;
2018-12-08 19:05:03 +01:00
}
}
}
}
}
// When the weather is changing, it gradually updates the palettes
2022-10-16 13:06:43 -05:00
// towards the desired color map.
static void UpdateWeatherColorMap(void)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->palProcessingState != WEATHER_PAL_STATE_SCREEN_FADING_OUT)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
if (gWeatherPtr->colorMapIndex == gWeatherPtr->targetColorMapIndex)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_IDLE;
2018-12-08 19:05:03 +01:00
}
else
{
2022-10-16 13:06:43 -05:00
if (++gWeatherPtr->colorMapStepCounter >= gWeatherPtr->colorMapStepDelay)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
gWeatherPtr->colorMapStepCounter = 0;
if (gWeatherPtr->colorMapIndex < gWeatherPtr->targetColorMapIndex)
gWeatherPtr->colorMapIndex++;
2018-12-08 19:05:03 +01:00
else
2022-10-16 13:06:43 -05:00
gWeatherPtr->colorMapIndex--;
2018-12-08 19:05:03 +01:00
2022-10-16 13:06:43 -05:00
ApplyColorMap(0, 32, gWeatherPtr->colorMapIndex);
2018-12-08 19:05:03 +01:00
}
}
}
}
2018-12-08 19:43:21 +01:00
static void FadeInScreenWithWeather(void)
2018-12-08 19:05:03 +01:00
{
if (++gWeatherPtr->fadeInTimer > 1)
gWeatherPtr->fadeInFirstFrame = FALSE;
2018-12-08 19:05:03 +01:00
2018-12-08 19:43:21 +01:00
switch (gWeatherPtr->currWeather)
2018-12-08 19:05:03 +01:00
{
2019-12-01 19:19:47 -05:00
case WEATHER_RAIN:
case WEATHER_RAIN_THUNDERSTORM:
case WEATHER_DOWNPOUR:
2019-12-06 02:27:58 -05:00
case WEATHER_SHADE:
2018-12-08 19:05:03 +01:00
if (FadeInScreen_RainShowShade() == FALSE)
{
2022-10-16 13:06:43 -05:00
gWeatherPtr->colorMapIndex = 3;
2018-12-08 19:43:21 +01:00
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_IDLE;
2018-12-08 19:05:03 +01:00
}
break;
case WEATHER_DROUGHT:
if (FadeInScreen_Drought() == FALSE)
{
2022-10-16 13:06:43 -05:00
gWeatherPtr->colorMapIndex = -6;
2018-12-08 19:43:21 +01:00
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_IDLE;
2018-12-08 19:05:03 +01:00
}
break;
2019-12-01 19:19:47 -05:00
case WEATHER_FOG_HORIZONTAL:
if (FadeInScreen_FogHorizontal() == FALSE)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
gWeatherPtr->colorMapIndex = 0;
2018-12-08 19:43:21 +01:00
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_IDLE;
2018-12-08 19:05:03 +01:00
}
break;
2023-08-20 13:24:20 -05:00
case WEATHER_SNOW:
2019-12-01 19:19:47 -05:00
case WEATHER_VOLCANIC_ASH:
2018-12-08 19:05:03 +01:00
case WEATHER_SANDSTORM:
2019-12-01 19:19:47 -05:00
case WEATHER_FOG_DIAGONAL:
case WEATHER_UNDERWATER:
2018-12-08 19:05:03 +01:00
default:
if (!gPaletteFade.active)
{
2022-10-16 13:06:43 -05:00
gWeatherPtr->colorMapIndex = gWeatherPtr->targetColorMapIndex;
2018-12-08 19:43:21 +01:00
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_IDLE;
2018-12-08 19:05:03 +01:00
}
break;
}
}
2018-12-08 19:43:21 +01:00
static bool8 FadeInScreen_RainShowShade(void)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->fadeScreenCounter == 16)
2018-12-08 19:05:03 +01:00
return FALSE;
2018-12-08 19:43:21 +01:00
if (++gWeatherPtr->fadeScreenCounter >= 16)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
ApplyColorMap(0, 32, 3);
2018-12-08 19:43:21 +01:00
gWeatherPtr->fadeScreenCounter = 16;
2018-12-08 19:05:03 +01:00
return FALSE;
}
2022-10-16 13:06:43 -05:00
ApplyColorMapWithBlend(0, 32, 3, 16 - gWeatherPtr->fadeScreenCounter, gWeatherPtr->fadeDestColor);
2018-12-08 19:05:03 +01:00
return TRUE;
}
2018-12-08 19:43:21 +01:00
static bool8 FadeInScreen_Drought(void)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->fadeScreenCounter == 16)
2018-12-08 19:05:03 +01:00
return FALSE;
2018-12-08 19:43:21 +01:00
if (++gWeatherPtr->fadeScreenCounter >= 16)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
ApplyColorMap(0, 32, -6);
2018-12-08 19:43:21 +01:00
gWeatherPtr->fadeScreenCounter = 16;
2018-12-08 19:05:03 +01:00
return FALSE;
}
2022-10-16 13:06:43 -05:00
ApplyDroughtColorMapWithBlend(-6, 16 - gWeatherPtr->fadeScreenCounter, gWeatherPtr->fadeDestColor);
2018-12-08 19:05:03 +01:00
return TRUE;
}
static bool8 FadeInScreen_FogHorizontal(void)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->fadeScreenCounter == 16)
2018-12-08 19:05:03 +01:00
return FALSE;
2018-12-08 19:43:21 +01:00
gWeatherPtr->fadeScreenCounter++;
ApplyFogBlend(16 - gWeatherPtr->fadeScreenCounter, gWeatherPtr->fadeDestColor);
2018-12-08 19:05:03 +01:00
return TRUE;
}
2018-12-08 19:43:21 +01:00
static void DoNothing(void)
2018-12-08 19:05:03 +01:00
{ }
2022-10-16 13:06:43 -05:00
static void ApplyColorMap(u8 startPalIndex, u8 numPalettes, s8 colorMapIndex)
2018-12-08 19:05:03 +01:00
{
u16 curPalIndex;
u16 palOffset;
2022-10-16 13:06:43 -05:00
u8 *colorMap;
2018-12-08 19:05:03 +01:00
u16 i;
2022-10-16 13:06:43 -05:00
if (colorMapIndex > 0)
2018-12-08 19:05:03 +01:00
{
2023-11-11 20:08:20 +01:00
u32 palettes = PALETTES_ALL;
numPalettes += startPalIndex;
palettes = (palettes >> startPalIndex) << startPalIndex;
palettes = (palettes << (32 - numPalettes)) >> (32 - numPalettes);
numPalettes -= startPalIndex;
2022-10-16 13:06:43 -05:00
colorMapIndex--;
2023-05-23 13:16:18 -04:00
palOffset = PLTT_ID(startPalIndex);
2023-11-11 20:08:20 +01:00
UpdateAltBgPalettes(palettes & PALETTES_BG);
if (!(colorMapIndex > 3) && MapHasNaturalLight(gMapHeader.mapType))
UpdatePalettesWithTime(palettes);
else
CpuFastCopy(gPlttBufferUnfaded + palOffset, gPlttBufferFaded + palOffset, PLTT_SIZE_4BPP * numPalettes);
2018-12-08 19:05:03 +01:00
numPalettes += startPalIndex;
curPalIndex = startPalIndex;
2022-10-16 13:06:43 -05:00
// Loop through the specified palette range and apply necessary color maps.
2018-12-08 19:05:03 +01:00
while (curPalIndex < numPalettes)
{
2023-11-11 20:08:20 +01:00
if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_NONE || (curPalIndex >= 16 && GetSpritePaletteTagByPaletteNum(curPalIndex - 16) >> 15))
2018-12-08 19:05:03 +01:00
{
// No palette change.
palOffset += 16;
}
else
{
u8 r, g, b;
2022-10-16 13:06:43 -05:00
if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_CONTRAST || curPalIndex - 16 == gWeatherPtr->contrastColorMapSpritePalIndex)
colorMap = gWeatherPtr->contrastColorMaps[colorMapIndex];
2018-12-08 19:05:03 +01:00
else
2022-10-16 13:06:43 -05:00
colorMap = gWeatherPtr->darkenedContrastColorMaps[colorMapIndex];
2018-12-08 19:05:03 +01:00
for (i = 0; i < 16; i++)
{
2022-10-16 13:06:43 -05:00
// Apply color map to the original color.
2023-11-11 20:08:20 +01:00
struct RGBColor baseColor = *(struct RGBColor *)&gPlttBufferFaded[palOffset];
2022-10-16 13:06:43 -05:00
r = colorMap[baseColor.r];
g = colorMap[baseColor.g];
b = colorMap[baseColor.b];
2021-02-14 22:08:19 +00:00
gPlttBufferFaded[palOffset++] = RGB2(r, g, b);
2018-12-08 19:05:03 +01:00
}
}
curPalIndex++;
}
}
2022-10-16 13:06:43 -05:00
else if (colorMapIndex < 0)
2018-12-08 19:05:03 +01:00
{
// A negative gammIndex value means that the blending will come from the special Drought weather's palette tables.
2022-10-16 13:06:43 -05:00
colorMapIndex = -colorMapIndex - 1;
2023-05-23 13:16:18 -04:00
palOffset = PLTT_ID(startPalIndex);
2018-12-08 19:05:03 +01:00
numPalettes += startPalIndex;
curPalIndex = startPalIndex;
while (curPalIndex < numPalettes)
{
2022-10-16 13:06:43 -05:00
if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_NONE)
2018-12-08 19:05:03 +01:00
{
// No palette change.
2023-05-23 13:16:18 -04:00
CpuFastCopy(&gPlttBufferUnfaded[palOffset], &gPlttBufferFaded[palOffset], PLTT_SIZE_4BPP);
2018-12-08 19:05:03 +01:00
palOffset += 16;
}
else
{
for (i = 0; i < 16; i++)
{
2022-10-16 13:06:43 -05:00
gPlttBufferFaded[palOffset] = sDroughtWeatherColors[colorMapIndex][DROUGHT_COLOR_INDEX(gPlttBufferUnfaded[palOffset])];
2018-12-08 19:05:03 +01:00
palOffset++;
}
}
curPalIndex++;
}
}
else
{
2023-11-11 20:08:20 +01:00
if (MapHasNaturalLight(gMapHeader.mapType))
{
u32 palettes = ((1 << numPalettes) - 1) << startPalIndex;
UpdateAltBgPalettes(palettes & PALETTES_BG);
UpdatePalettesWithTime(palettes);
}
else
CpuFastCopy(&gPlttBufferUnfaded[PLTT_ID(startPalIndex)], &gPlttBufferFaded[PLTT_ID(startPalIndex)], numPalettes * PLTT_SIZE_4BPP);
2018-12-08 19:05:03 +01:00
}
}
2022-10-16 13:06:43 -05:00
static void ApplyColorMapWithBlend(u8 startPalIndex, u8 numPalettes, s8 colorMapIndex, u8 blendCoeff, u16 blendColor)
2018-12-08 19:05:03 +01:00
{
u16 palOffset;
u16 curPalIndex;
u16 i;
struct RGBColor color = *(struct RGBColor *)&blendColor;
u8 rBlend = color.r;
u8 gBlend = color.g;
u8 bBlend = color.b;
2023-05-23 13:16:18 -04:00
palOffset = PLTT_ID(startPalIndex);
2018-12-08 19:05:03 +01:00
numPalettes += startPalIndex;
2022-10-16 13:06:43 -05:00
colorMapIndex--;
2018-12-08 19:05:03 +01:00
curPalIndex = startPalIndex;
while (curPalIndex < numPalettes)
{
2023-11-11 20:08:20 +01:00
UpdateAltBgPalettes((1 << (palOffset >> 4)) & PALETTES_BG);
CpuFastCopy(gPlttBufferUnfaded + palOffset, gPlttBufferFaded + palOffset, PLTT_SIZE_4BPP);
UpdatePalettesWithTime(1 << (palOffset >> 4));
2022-10-16 13:06:43 -05:00
if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_NONE)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
// No color map. Simply blend the colors.
2023-11-11 20:08:20 +01:00
BlendPalettesFine(1, gPlttBufferFaded + palOffset, gPlttBufferFaded + palOffset, blendCoeff, blendColor);
2022-08-19 16:32:00 +01:00
palOffset += 16;
2018-12-08 19:05:03 +01:00
}
else
{
2022-10-16 13:06:43 -05:00
u8 *colorMap;
2018-12-08 19:05:03 +01:00
2022-10-16 13:06:43 -05:00
if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_DARK_CONTRAST)
colorMap = gWeatherPtr->darkenedContrastColorMaps[colorMapIndex];
2018-12-08 19:05:03 +01:00
else
2022-10-16 13:06:43 -05:00
colorMap = gWeatherPtr->contrastColorMaps[colorMapIndex];
2018-12-08 19:05:03 +01:00
for (i = 0; i < 16; i++)
{
2023-11-11 20:08:20 +01:00
struct RGBColor baseColor = *(struct RGBColor *)&gPlttBufferFaded[palOffset];
2022-10-16 13:06:43 -05:00
u8 r = colorMap[baseColor.r];
u8 g = colorMap[baseColor.g];
u8 b = colorMap[baseColor.b];
2018-12-08 19:05:03 +01:00
2022-10-16 13:06:43 -05:00
// Apply color map and target blend color to the original color.
2018-12-08 19:05:03 +01:00
r += ((rBlend - r) * blendCoeff) >> 4;
g += ((gBlend - g) * blendCoeff) >> 4;
b += ((bBlend - b) * blendCoeff) >> 4;
2021-02-14 22:08:19 +00:00
gPlttBufferFaded[palOffset++] = RGB2(r, g, b);
2018-12-08 19:05:03 +01:00
}
}
curPalIndex++;
}
}
2022-10-16 13:06:43 -05:00
static void ApplyDroughtColorMapWithBlend(s8 colorMapIndex, u8 blendCoeff, u16 blendColor)
2018-12-08 19:05:03 +01:00
{
struct RGBColor color;
u8 rBlend;
u8 gBlend;
u8 bBlend;
u16 curPalIndex;
u16 palOffset;
u16 i;
2022-10-16 13:06:43 -05:00
colorMapIndex = -colorMapIndex - 1;
2018-12-08 19:05:03 +01:00
color = *(struct RGBColor *)&blendColor;
rBlend = color.r;
gBlend = color.g;
bBlend = color.b;
2022-08-19 16:32:00 +01:00
palOffset = 0;
2018-12-08 19:05:03 +01:00
for (curPalIndex = 0; curPalIndex < 32; curPalIndex++)
{
2022-10-16 13:06:43 -05:00
if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_NONE)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
// No color map. Simply blend the colors.
2018-12-08 19:05:03 +01:00
BlendPalette(palOffset, 16, blendCoeff, blendColor);
2022-08-19 16:32:00 +01:00
palOffset += 16;
2018-12-08 19:05:03 +01:00
}
else
{
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;
offset = ((b1 & 0x1E) << 7) | ((g1 & 0x1E) << 3) | ((r1 & 0x1E) >> 1);
2022-10-16 13:06:43 -05:00
color2 = *(struct RGBColor *)&sDroughtWeatherColors[colorMapIndex][offset];
2018-12-08 19:05:03 +01:00
r2 = color2.r;
g2 = color2.g;
b2 = color2.b;
r2 += ((rBlend - r2) * blendCoeff) >> 4;
g2 += ((gBlend - g2) * blendCoeff) >> 4;
b2 += ((bBlend - b2) * blendCoeff) >> 4;
2021-02-14 22:08:19 +00:00
gPlttBufferFaded[palOffset++] = RGB2(r2, g2, b2);
2018-12-08 19:05:03 +01:00
}
}
}
}
2018-12-08 19:43:21 +01:00
static void ApplyFogBlend(u8 blendCoeff, u16 blendColor)
2018-12-08 19:05:03 +01:00
{
2023-11-11 20:08:20 +01:00
u32 curPalIndex;
u16 fogCoeff = min((gTimeOfDay + 1) * 4, 12);
2018-12-08 19:05:03 +01:00
2023-11-11 20:08:20 +01:00
UpdateAltBgPalettes(PALETTES_BG);
CpuFastCopy(gPlttBufferUnfaded, gPlttBufferFaded, PLTT_BUFFER_SIZE * 2);
UpdatePalettesWithTime(PALETTES_ALL);
BlendPalettesFine(0x1FFF, gPlttBufferFaded, gPlttBufferFaded, blendCoeff, blendColor);
2018-12-08 19:05:03 +01:00
for (curPalIndex = 16; curPalIndex < 32; curPalIndex++)
{
if (LightenSpritePaletteInFog(curPalIndex))
2023-11-11 20:08:20 +01:00
BlendPalettesFine(1, gPlttBufferFaded + PLTT_ID(curPalIndex), gPlttBufferFaded + PLTT_ID(curPalIndex), fogCoeff, RGB(28, 31, 28));
2018-12-08 19:05:03 +01:00
else
{
2022-08-19 15:29:35 +01:00
BlendPalette(PLTT_ID(curPalIndex), 16, blendCoeff, blendColor);
2018-12-08 19:05:03 +01:00
}
}
2023-11-11 20:08:20 +01:00
BlendPalettesFine(PALETTES_OBJECTS, gPlttBufferFaded, gPlttBufferFaded, blendCoeff, blendColor);
2018-12-08 19:05:03 +01:00
}
2018-12-08 19:43:21 +01:00
static void MarkFogSpritePalToLighten(u8 paletteIndex)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->lightenedFogSpritePalsCount < 6)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
gWeatherPtr->lightenedFogSpritePals[gWeatherPtr->lightenedFogSpritePalsCount] = paletteIndex;
gWeatherPtr->lightenedFogSpritePalsCount++;
2018-12-08 19:05:03 +01:00
}
}
2018-12-08 19:43:21 +01:00
static bool8 LightenSpritePaletteInFog(u8 paletteIndex)
2018-12-08 19:05:03 +01:00
{
u16 i;
2023-11-11 20:08:20 +01:00
if (paletteIndex >= 16 && (GetSpritePaletteTagByPaletteNum(i - 16) >> 15))
return FALSE;
2018-12-08 19:43:21 +01:00
for (i = 0; i < gWeatherPtr->lightenedFogSpritePalsCount; i++)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->lightenedFogSpritePals[i] == paletteIndex)
2018-12-08 19:05:03 +01:00
return TRUE;
}
return FALSE;
}
2022-10-16 13:06:43 -05:00
void ApplyWeatherColorMapIfIdle(s8 colorMapIndex)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->palProcessingState == WEATHER_PAL_STATE_IDLE)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
ApplyColorMap(0, 32, colorMapIndex);
gWeatherPtr->colorMapIndex = colorMapIndex;
2018-12-08 19:05:03 +01:00
}
}
2022-10-16 13:06:43 -05:00
void ApplyWeatherColorMapIfIdle_Gradual(u8 colorMapIndex, u8 targetColorMapIndex, u8 colorMapStepDelay)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->palProcessingState == WEATHER_PAL_STATE_IDLE)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_CHANGING_WEATHER;
2022-10-16 13:06:43 -05:00
gWeatherPtr->colorMapIndex = colorMapIndex;
gWeatherPtr->targetColorMapIndex = targetColorMapIndex;
gWeatherPtr->colorMapStepCounter = 0;
gWeatherPtr->colorMapStepDelay = colorMapStepDelay;
ApplyWeatherColorMapIfIdle(colorMapIndex);
2018-12-08 19:05:03 +01:00
}
}
void FadeScreen(u8 mode, s8 delay)
{
u32 fadeColor;
bool8 fadeOut;
bool8 useWeatherPal;
switch (mode)
{
case FADE_FROM_BLACK:
2018-12-09 12:16:01 +01:00
fadeColor = RGB_BLACK;
2018-12-08 19:05:03 +01:00
fadeOut = FALSE;
break;
case FADE_FROM_WHITE:
2018-12-09 12:16:01 +01:00
fadeColor = RGB_WHITEALPHA;
2018-12-08 19:05:03 +01:00
fadeOut = FALSE;
break;
case FADE_TO_BLACK:
2018-12-09 12:16:01 +01:00
fadeColor = RGB_BLACK;
2018-12-08 19:05:03 +01:00
fadeOut = TRUE;
break;
case FADE_TO_WHITE:
2018-12-09 12:16:01 +01:00
fadeColor = RGB_WHITEALPHA;
2018-12-08 19:05:03 +01:00
fadeOut = TRUE;
break;
default:
return;
}
2018-12-08 19:43:21 +01:00
switch (gWeatherPtr->currWeather)
2018-12-08 19:05:03 +01:00
{
2019-12-01 19:19:47 -05:00
case WEATHER_RAIN:
case WEATHER_RAIN_THUNDERSTORM:
case WEATHER_DOWNPOUR:
case WEATHER_FOG_HORIZONTAL:
2019-12-06 02:27:58 -05:00
case WEATHER_SHADE:
2018-12-08 19:05:03 +01:00
case WEATHER_DROUGHT:
useWeatherPal = TRUE;
break;
default:
useWeatherPal = FALSE;
break;
}
if (fadeOut)
{
2023-11-11 20:08:20 +01:00
CpuFastCopy(gPlttBufferFaded, gPlttBufferUnfaded, PLTT_BUFFER_SIZE * 2);
2021-02-24 11:01:02 -05:00
BeginNormalPaletteFade(PALETTES_ALL, delay, 0, 16, fadeColor);
2018-12-08 19:43:21 +01:00
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_SCREEN_FADING_OUT;
2018-12-08 19:05:03 +01:00
}
else
{
2018-12-08 19:43:21 +01:00
gWeatherPtr->fadeDestColor = fadeColor;
2023-11-11 20:08:20 +01:00
UpdateTimeOfDay();
2018-12-08 19:05:03 +01:00
if (useWeatherPal)
2018-12-08 19:43:21 +01:00
gWeatherPtr->fadeScreenCounter = 0;
2018-12-08 19:05:03 +01:00
else
2023-11-11 20:08:20 +01:00
{
if (MapHasNaturalLight(gMapHeader.mapType))
{
UpdateAltBgPalettes(PALETTES_BG);
BeginTimeOfDayPaletteFade(PALETTES_ALL, delay, 16, 0, (struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0], (struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time1], currentTimeBlend.weight, fadeColor);
}
else
BeginNormalPaletteFade(PALETTES_ALL, delay, 16, 0, fadeColor);
}
2018-12-08 19:05:03 +01:00
2018-12-08 19:43:21 +01:00
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_SCREEN_FADING_IN;
gWeatherPtr->fadeInFirstFrame = TRUE;
gWeatherPtr->fadeInTimer = 0;
2018-12-08 19:43:21 +01:00
Weather_SetBlendCoeffs(gWeatherPtr->currBlendEVA, gWeatherPtr->currBlendEVB);
gWeatherPtr->readyForInit = TRUE;
2018-12-08 19:05:03 +01:00
}
}
bool8 IsWeatherNotFadingIn(void)
{
2018-12-08 19:43:21 +01:00
return (gWeatherPtr->palProcessingState != WEATHER_PAL_STATE_SCREEN_FADING_IN);
2018-12-08 19:05:03 +01:00
}
2023-11-11 20:08:20 +01:00
void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex, bool8 allowFog)
2018-12-08 19:05:03 +01:00
{
u16 paletteIndex = 16 + spritePaletteIndex;
u16 i;
2018-12-08 19:43:21 +01:00
switch (gWeatherPtr->palProcessingState)
2018-12-08 19:05:03 +01:00
{
case WEATHER_PAL_STATE_SCREEN_FADING_IN:
if (gWeatherPtr->fadeInFirstFrame)
2018-12-08 19:05:03 +01:00
{
2019-12-01 19:19:47 -05:00
if (gWeatherPtr->currWeather == WEATHER_FOG_HORIZONTAL)
2018-12-08 19:05:03 +01:00
MarkFogSpritePalToLighten(paletteIndex);
2023-05-23 13:16:18 -04:00
paletteIndex = PLTT_ID(paletteIndex);
2018-12-08 19:05:03 +01:00
for (i = 0; i < 16; i++)
2018-12-08 19:43:21 +01:00
gPlttBufferFaded[paletteIndex + i] = gWeatherPtr->fadeDestColor;
2018-12-08 19:05:03 +01:00
}
break;
case WEATHER_PAL_STATE_SCREEN_FADING_OUT:
2022-08-19 15:29:35 +01:00
paletteIndex = PLTT_ID(paletteIndex);
2023-05-23 13:16:18 -04:00
CpuFastCopy(&gPlttBufferFaded[paletteIndex], &gPlttBufferUnfaded[paletteIndex], PLTT_SIZE_4BPP);
2018-12-08 19:05:03 +01:00
BlendPalette(paletteIndex, 16, gPaletteFade.y, gPaletteFade.blendColor);
break;
// WEATHER_PAL_STATE_CHANGING_WEATHER
// WEATHER_PAL_STATE_CHANGING_IDLE
default:
2019-12-01 19:19:47 -05:00
if (gWeatherPtr->currWeather != WEATHER_FOG_HORIZONTAL)
2018-12-08 19:05:03 +01:00
{
2023-11-11 20:08:20 +01:00
if (gWeatherPtr->colorMapIndex)
ApplyColorMap(paletteIndex, 1, gWeatherPtr->colorMapIndex);
else
UpdateSpritePaletteWithTime(spritePaletteIndex);
2018-12-08 19:05:03 +01:00
}
else
{
2023-11-11 20:08:20 +01:00
if (allowFog)
{
i = min((gTimeOfDay + 1) * 4, 12);
paletteIndex = PLTT_ID(paletteIndex);
CpuFastCopy(gPlttBufferUnfaded + paletteIndex, gPlttBufferFaded + paletteIndex, PLTT_SIZE_4BPP);
UpdateSpritePaletteWithTime(spritePaletteIndex);
BlendPalettesFine(1, gPlttBufferFaded + paletteIndex, gPlttBufferFaded + paletteIndex, i, RGB(28, 31, 28));
}
else
UpdateSpritePaletteWithTime(spritePaletteIndex);
2018-12-08 19:05:03 +01:00
}
break;
}
}
2023-11-11 20:08:20 +01:00
void ApplyWeatherColorMapToPal(u8 paletteIndex, u8 numPalettes)
2018-12-08 19:05:03 +01:00
{
2023-11-11 20:08:20 +01:00
ApplyColorMap(paletteIndex, numPalettes, gWeatherPtr->colorMapIndex);
2018-12-08 19:05:03 +01:00
}
// Unused
static bool8 IsFirstFrameOfWeatherFadeIn(void)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->palProcessingState == WEATHER_PAL_STATE_SCREEN_FADING_IN)
return gWeatherPtr->fadeInFirstFrame;
2018-12-08 19:05:03 +01:00
else
return FALSE;
2018-12-08 19:05:03 +01:00
}
void LoadCustomWeatherSpritePalette(const u16 *palette)
{
2023-11-11 20:08:20 +01:00
if (gWeatherPtr->weatherPicSpritePalIndex > 16)
if ((gWeatherPtr->weatherPicSpritePalIndex = AllocSpritePalette(PALTAG_WEATHER_2)) > 16)
return;
2022-08-19 15:29:35 +01:00
LoadPalette(palette, OBJ_PLTT_ID(gWeatherPtr->weatherPicSpritePalIndex), PLTT_SIZE_4BPP);
2023-11-11 20:08:20 +01:00
UpdateSpritePaletteWithWeather(gWeatherPtr->weatherPicSpritePalIndex, TRUE);
2018-12-08 19:05:03 +01:00
}
2022-06-01 12:41:57 -04:00
static void LoadDroughtWeatherPalette(u8 *palsIndex, u8 *palsOffset)
2018-12-08 19:05:03 +01:00
{
2022-06-01 12:41:57 -04:00
*palsIndex = 0x20;
*palsOffset = 0x20;
2018-12-08 19:05:03 +01:00
}
void ResetDroughtWeatherPaletteLoading(void)
{
2018-12-08 19:43:21 +01:00
gWeatherPtr->loadDroughtPalsIndex = 1;
gWeatherPtr->loadDroughtPalsOffset = 1;
2018-12-08 19:05:03 +01:00
}
bool8 LoadDroughtWeatherPalettes(void)
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->loadDroughtPalsIndex < 32)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
LoadDroughtWeatherPalette(&gWeatherPtr->loadDroughtPalsIndex, &gWeatherPtr->loadDroughtPalsOffset);
if (gWeatherPtr->loadDroughtPalsIndex < 32)
2018-12-08 19:05:03 +01:00
return TRUE;
}
return FALSE;
}
2022-10-16 13:06:43 -05:00
static void SetDroughtColorMap(s8 colorMapIndex)
2018-12-08 19:05:03 +01:00
{
2022-10-16 13:06:43 -05:00
ApplyWeatherColorMapIfIdle(-colorMapIndex - 1);
2018-12-08 19:05:03 +01:00
}
void DroughtStateInit(void)
2018-12-08 19:05:03 +01:00
{
gWeatherPtr->droughtBrightnessStage = 0;
gWeatherPtr->droughtTimer = 0;
gWeatherPtr->droughtState = 0;
gWeatherPtr->droughtLastBrightnessStage = 0;
2018-12-08 19:05:03 +01:00
}
void DroughtStateRun(void)
2018-12-08 19:05:03 +01:00
{
switch (gWeatherPtr->droughtState)
2018-12-08 19:05:03 +01:00
{
case 0:
if (++gWeatherPtr->droughtTimer > 5)
2018-12-08 19:05:03 +01:00
{
gWeatherPtr->droughtTimer = 0;
2022-10-16 13:06:43 -05:00
SetDroughtColorMap(gWeatherPtr->droughtBrightnessStage++);
if (gWeatherPtr->droughtBrightnessStage > 5)
2018-12-08 19:05:03 +01:00
{
gWeatherPtr->droughtLastBrightnessStage = gWeatherPtr->droughtBrightnessStage;
gWeatherPtr->droughtState = 1;
gWeatherPtr->droughtTimer = 60;
2018-12-08 19:05:03 +01:00
}
}
break;
case 1:
gWeatherPtr->droughtTimer = (gWeatherPtr->droughtTimer + 3) & 0x7F;
gWeatherPtr->droughtBrightnessStage = ((gSineTable[gWeatherPtr->droughtTimer] - 1) >> 6) + 2;
if (gWeatherPtr->droughtBrightnessStage != gWeatherPtr->droughtLastBrightnessStage)
2022-10-16 13:06:43 -05:00
SetDroughtColorMap(gWeatherPtr->droughtBrightnessStage);
gWeatherPtr->droughtLastBrightnessStage = gWeatherPtr->droughtBrightnessStage;
2018-12-08 19:05:03 +01:00
break;
case 2:
if (++gWeatherPtr->droughtTimer > 5)
2018-12-08 19:05:03 +01:00
{
gWeatherPtr->droughtTimer = 0;
2022-10-16 13:06:43 -05:00
SetDroughtColorMap(--gWeatherPtr->droughtBrightnessStage);
if (gWeatherPtr->droughtBrightnessStage == 3)
gWeatherPtr->droughtState = 0;
2018-12-08 19:05:03 +01:00
}
break;
}
}
void Weather_SetBlendCoeffs(u8 eva, u8 evb)
{
2018-12-08 19:43:21 +01:00
gWeatherPtr->currBlendEVA = eva;
gWeatherPtr->currBlendEVB = evb;
gWeatherPtr->targetBlendEVA = eva;
gWeatherPtr->targetBlendEVB = evb;
2018-12-08 19:05:03 +01:00
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(eva, evb));
}
void Weather_SetTargetBlendCoeffs(u8 eva, u8 evb, int delay)
{
2018-12-08 19:43:21 +01:00
gWeatherPtr->targetBlendEVA = eva;
gWeatherPtr->targetBlendEVB = evb;
gWeatherPtr->blendDelay = delay;
gWeatherPtr->blendFrameCounter = 0;
gWeatherPtr->blendUpdateCounter = 0;
2018-12-08 19:05:03 +01:00
}
bool8 Weather_UpdateBlend(void)
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->currBlendEVA == gWeatherPtr->targetBlendEVA
&& gWeatherPtr->currBlendEVB == gWeatherPtr->targetBlendEVB)
2018-12-08 19:05:03 +01:00
return TRUE;
2018-12-08 19:43:21 +01:00
if (++gWeatherPtr->blendFrameCounter > gWeatherPtr->blendDelay)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
gWeatherPtr->blendFrameCounter = 0;
gWeatherPtr->blendUpdateCounter++;
2018-12-08 19:05:03 +01:00
// Update currBlendEVA and currBlendEVB on alternate frames
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->blendUpdateCounter & 1)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->currBlendEVA < gWeatherPtr->targetBlendEVA)
gWeatherPtr->currBlendEVA++;
else if (gWeatherPtr->currBlendEVA > gWeatherPtr->targetBlendEVA)
gWeatherPtr->currBlendEVA--;
2018-12-08 19:05:03 +01:00
}
else
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->currBlendEVB < gWeatherPtr->targetBlendEVB)
gWeatherPtr->currBlendEVB++;
else if (gWeatherPtr->currBlendEVB > gWeatherPtr->targetBlendEVB)
gWeatherPtr->currBlendEVB--;
2018-12-08 19:05:03 +01:00
}
}
2018-12-08 19:43:21 +01:00
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(gWeatherPtr->currBlendEVA, gWeatherPtr->currBlendEVB));
2018-12-08 19:05:03 +01:00
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->currBlendEVA == gWeatherPtr->targetBlendEVA
&& gWeatherPtr->currBlendEVB == gWeatherPtr->targetBlendEVB)
2018-12-08 19:05:03 +01:00
return TRUE;
return FALSE;
}
2021-04-04 17:52:07 -04:00
// Unused. Uses the same numbering scheme as the coord events
static void SetFieldWeather(u8 weather)
2018-12-08 19:05:03 +01:00
{
2021-04-04 17:52:07 -04:00
switch (weather)
2018-12-08 19:05:03 +01:00
{
2021-04-04 17:52:07 -04:00
case COORD_EVENT_WEATHER_SUNNY_CLOUDS:
2019-12-01 19:19:47 -05:00
SetWeather(WEATHER_SUNNY_CLOUDS);
2018-12-08 19:05:03 +01:00
break;
2021-04-04 17:52:07 -04:00
case COORD_EVENT_WEATHER_SUNNY:
2018-12-08 19:05:03 +01:00
SetWeather(WEATHER_SUNNY);
break;
2021-04-04 17:52:07 -04:00
case COORD_EVENT_WEATHER_RAIN:
2019-12-01 19:19:47 -05:00
SetWeather(WEATHER_RAIN);
2018-12-08 19:05:03 +01:00
break;
2021-04-04 17:52:07 -04:00
case COORD_EVENT_WEATHER_SNOW:
2018-12-08 19:05:03 +01:00
SetWeather(WEATHER_SNOW);
break;
2021-04-04 17:52:07 -04:00
case COORD_EVENT_WEATHER_RAIN_THUNDERSTORM:
2019-12-01 19:19:47 -05:00
SetWeather(WEATHER_RAIN_THUNDERSTORM);
2018-12-08 19:05:03 +01:00
break;
2021-04-04 17:52:07 -04:00
case COORD_EVENT_WEATHER_FOG_HORIZONTAL:
2019-12-01 19:19:47 -05:00
SetWeather(WEATHER_FOG_HORIZONTAL);
2018-12-08 19:05:03 +01:00
break;
2021-04-04 17:52:07 -04:00
case COORD_EVENT_WEATHER_FOG_DIAGONAL:
2019-12-01 19:19:47 -05:00
SetWeather(WEATHER_FOG_DIAGONAL);
2018-12-08 19:05:03 +01:00
break;
2021-04-04 17:52:07 -04:00
case COORD_EVENT_WEATHER_VOLCANIC_ASH:
2019-12-01 19:19:47 -05:00
SetWeather(WEATHER_VOLCANIC_ASH);
2018-12-08 19:05:03 +01:00
break;
2021-04-04 17:52:07 -04:00
case COORD_EVENT_WEATHER_SANDSTORM:
2018-12-08 19:05:03 +01:00
SetWeather(WEATHER_SANDSTORM);
break;
2021-04-04 17:52:07 -04:00
case COORD_EVENT_WEATHER_SHADE:
2019-12-06 02:27:58 -05:00
SetWeather(WEATHER_SHADE);
2018-12-08 19:05:03 +01:00
break;
}
}
u8 GetCurrentWeather(void)
{
2018-12-08 19:43:21 +01:00
return gWeatherPtr->currWeather;
2018-12-08 19:05:03 +01:00
}
void SetRainStrengthFromSoundEffect(u16 soundEffect)
{
2018-12-08 19:43:21 +01:00
if (gWeatherPtr->palProcessingState != WEATHER_PAL_STATE_SCREEN_FADING_OUT)
2018-12-08 19:05:03 +01:00
{
switch (soundEffect)
{
2020-08-20 18:02:00 -04:00
case SE_RAIN:
2018-12-08 19:43:21 +01:00
gWeatherPtr->rainStrength = 0;
2018-12-08 19:05:03 +01:00
break;
2020-08-20 18:02:00 -04:00
case SE_DOWNPOUR:
2018-12-08 19:43:21 +01:00
gWeatherPtr->rainStrength = 1;
2018-12-08 19:05:03 +01:00
break;
2020-08-20 18:02:00 -04:00
case SE_THUNDERSTORM:
2018-12-08 19:43:21 +01:00
gWeatherPtr->rainStrength = 2;
2018-12-08 19:05:03 +01:00
break;
default:
return;
}
PlaySE(soundEffect);
}
}
void PlayRainStoppingSoundEffect(void)
2018-12-08 19:05:03 +01:00
{
if (IsSpecialSEPlaying())
{
2018-12-08 19:43:21 +01:00
switch (gWeatherPtr->rainStrength)
2018-12-08 19:05:03 +01:00
{
case 0:
2020-08-20 18:02:00 -04:00
PlaySE(SE_RAIN_STOP);
2018-12-08 19:05:03 +01:00
break;
case 1:
2020-08-20 18:02:00 -04:00
PlaySE(SE_DOWNPOUR_STOP);
2018-12-08 19:05:03 +01:00
break;
case 2:
default:
2020-08-20 18:02:00 -04:00
PlaySE(SE_THUNDERSTORM_STOP);
2018-12-08 19:05:03 +01:00
break;
}
}
}
u8 IsWeatherChangeComplete(void)
{
2018-12-08 19:43:21 +01:00
return gWeatherPtr->weatherChangeComplete;
2018-12-08 19:05:03 +01:00
}
void SetWeatherScreenFadeOut(void)
{
2018-12-08 19:43:21 +01:00
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_SCREEN_FADING_OUT;
2018-12-08 19:05:03 +01:00
}
2021-04-04 17:52:07 -04:00
void SetWeatherPalStateIdle(void)
2018-12-08 19:05:03 +01:00
{
2018-12-08 19:43:21 +01:00
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_IDLE;
2018-12-08 19:05:03 +01:00
}
void PreservePaletteInWeather(u8 preservedPalIndex)
{
2022-10-16 13:06:43 -05:00
CpuCopy16(sBasePaletteColorMapTypes, sFieldEffectPaletteColorMapTypes, 32);
sFieldEffectPaletteColorMapTypes[preservedPalIndex] = COLOR_MAP_NONE;
sPaletteColorMapTypes = sFieldEffectPaletteColorMapTypes;
2018-12-08 19:05:03 +01:00
}
void ResetPreservedPalettesInWeather(void)
{
2022-10-16 13:06:43 -05:00
sPaletteColorMapTypes = sBasePaletteColorMapTypes;
2018-12-08 19:05:03 +01:00
}