From 045af1fd251a2e5c4f57bf279fe9a3fd7ba86341 Mon Sep 17 00:00:00 2001 From: cawtds <38510667+cawtds@users.noreply.github.com> Date: Sat, 8 Mar 2025 15:27:22 +0100 Subject: [PATCH] dns expansion alignment --- asm/macros/event.inc | 7 +- include/field_weather.h | 10 +++ include/global.fieldmap.h | 1 + include/overworld.h | 12 +-- include/palette.h | 18 ++++- src/event_object_movement.c | 7 +- src/field_effect.c | 11 +-- src/field_weather.c | 69 +++++++++++++---- src/overworld.c | 145 ++++++++++++++++-------------------- src/scrcmd.c | 29 +++----- 10 files changed, 166 insertions(+), 143 deletions(-) diff --git a/asm/macros/event.inc b/asm/macros/event.inc index 1ca62ed8a..e2e04333e 100644 --- a/asm/macros/event.inc +++ b/asm/macros/event.inc @@ -1764,9 +1764,10 @@ .byte SCR_OP_LOCKFORTRAINER .endm - @ Equivalent to fadescreen but copies gPlttBufferUnfaded to gDecompressionBuffer on the fade out - @ and the reverse on the fade in, in effect saving gPlttBufferUnfaded to restore it. - @ If nowait set, does not wait for the fade to complete + @ Equivalent to fadescreen but uses a hardware fade and darken/lighten blend modes, + @ to avoid modifying palettes at all. + @ Useful for fade-out/fade-in without leaving the overworld or entering a new scene. + @ If nowait set, doesn't wait for the fade to complete .macro fadescreenswapbuffers mode:req, nowait=0 .byte SCR_OP_FADESCREENSWAPBUFFERS .byte \mode diff --git a/include/field_weather.h b/include/field_weather.h index 591dfc006..d7553b180 100644 --- a/include/field_weather.h +++ b/include/field_weather.h @@ -4,6 +4,14 @@ #include "global.h" #include "constants/field_weather.h" + +enum +{ + COLOR_MAP_NONE, + COLOR_MAP_DARK_CONTRAST, + COLOR_MAP_CONTRAST, +}; + #define TAG_WEATHER_START 0x1200 enum { GFXTAG_CLOUD = TAG_WEATHER_START, @@ -137,6 +145,7 @@ struct Weather extern struct Weather *const gWeatherPtr; void FadeScreen(u8 mode, s8 delay); +u32 FadeScreenHardware(u32 mode, s32 delay); void SetSavedWeather(u32); u8 GetSavedWeather(void); @@ -152,6 +161,7 @@ u8 GetCurrentWeather(void); void delay(u8, u8, u32); void UpdateSpritePaletteWithWeather(u8 palIdx, bool32 allowFog); void ResetPreservedPalettesInWeather(void); +const u8* SetPaletteColorMapType(u8 paletteIndex, u8 colorMapType); void PreservePaletteInWeather(u8 palIdx); bool32 IsWeatherAlphaBlend(void); diff --git a/include/global.fieldmap.h b/include/global.fieldmap.h index 594ade652..b9fa3a067 100644 --- a/include/global.fieldmap.h +++ b/include/global.fieldmap.h @@ -121,6 +121,7 @@ struct __attribute__((packed, aligned(4))) ObjectEventTemplate u8 movementType; u16 movementRangeX:4; u16 movementRangeY:4; + u16 unused:8; u16 trainerType; u16 trainerRange_berryTreeId; }; diff --git a/include/overworld.h b/include/overworld.h index 491986fc7..e0ef82b31 100644 --- a/include/overworld.h +++ b/include/overworld.h @@ -54,14 +54,6 @@ enum { MUSIC_DISABLE_KEEP, }; -struct __attribute__((packed)) TimeBlendSettings { - u16 weight:9; - u16 time1:3; - u16 time0:3; - u16 unused:1; - u16 altWeight; -}; - extern struct WarpData gLastUsedWarp; extern struct LinkPlayerObjectEvent gLinkPlayerObjectEvents[4]; @@ -81,7 +73,7 @@ extern u8 gGlobalFieldTintMode; extern u8 gTimeOfDay; extern u16 gTimeUpdateCounter; -extern struct TimeBlendSettings currentTimeBlend; +extern struct TimeBlendSettings gTimeBlend; extern const struct Coords32 gDirectionToVectors[]; @@ -195,7 +187,7 @@ u16 SetLinkWaitingForScript(void); void SetMainCallback1(MainCallback cb); void CB1_Overworld(void); void CB2_ReturnToFieldContinueScript(void); -u8 UpdateTimeOfDay(void); +void UpdateTimeOfDay(void); bool8 MapHasNaturalLight(u8 mapType); void UpdateAltBgPalettes(u16 palettes); void UpdatePalettesWithTime(u32); diff --git a/include/palette.h b/include/palette.h index a305704ef..8e1a389fd 100644 --- a/include/palette.h +++ b/include/palette.h @@ -41,10 +41,20 @@ enum FAST_FADE_OUT_TO_BLACK, }; -struct BlendSettings { - u32 blendColor:24; - u32 isTint:1; - u32 coeff:5; +struct BlendSettings +{ + u32 blendColor:24; + u32 isTint:1; + u32 coeff:5; + u32 unused:2; +}; + +struct TimeBlendSettings +{ + struct BlendSettings startBlend; + struct BlendSettings endBlend; + u16 weight; + u16 altWeight; }; struct PaletteFadeControl diff --git a/src/event_object_movement.c b/src/event_object_movement.c index 636f10227..49207af0d 100644 --- a/src/event_object_movement.c +++ b/src/event_object_movement.c @@ -2143,10 +2143,6 @@ static void FollowerSetGraphics(struct ObjectEvent *objEvent, u32 species, bool3 sprite->inUse = TRUE; sprite->oam.paletteNum = LoadDynamicFollowerPalette(species, shiny, female); } - else if (gWeatherPtr->currWeather != WEATHER_FOG_HORIZONTAL) // don't want to weather blend in fog - { - UpdateSpritePaletteWithWeather(gSprites[objEvent->spriteId].oam.paletteNum, FALSE); - } } // Like FollowerSetGraphics, but does not recenter sprite on a metatile @@ -2844,7 +2840,6 @@ static u8 UpdateSpritePalette(const struct SpritePalette *spritePalette, struct { sprite->oam.paletteNum = LoadSpritePalette(spritePalette); } - sprite->oam.paletteNum = LoadSpritePalette(spritePalette); return sprite->oam.paletteNum; } @@ -3097,9 +3092,9 @@ static u8 LoadSpritePaletteIfTagExists(const struct SpritePalette *spritePalette if (paletteNum != 0xFF) // don't load twice; return return paletteNum; paletteNum = LoadSpritePalette(spritePalette); + ApplyGlobalFieldPaletteTint(paletteNum); if (paletteNum != 0xFF) UpdateSpritePaletteWithWeather(paletteNum, FALSE); - ApplyGlobalFieldPaletteTint(paletteNum); return paletteNum; } diff --git a/src/field_effect.c b/src/field_effect.c index ee8b89466..ca81da761 100644 --- a/src/field_effect.c +++ b/src/field_effect.c @@ -446,11 +446,12 @@ void ApplyGlobalFieldPaletteTint(u8 paletteIdx) void FieldEffectScript_LoadFadedPal(const struct SpritePalette * spritePalette) { - u8 idx = IndexOfSpritePaletteTag(spritePalette->tag); - LoadSpritePalette(spritePalette); - if (idx == 0xFF) - ApplyGlobalFieldPaletteTint(IndexOfSpritePaletteTag(spritePalette->tag)); - UpdateSpritePaletteWithWeather(IndexOfSpritePaletteTag(spritePalette->tag), TRUE); + u32 paletteSlot = LoadSpritePalette(spritePalette); + + SetPaletteColorMapType(paletteSlot + 16, COLOR_MAP_DARK_CONTRAST); + if (paletteSlot == 0xFF) + ApplyGlobalFieldPaletteTint(paletteSlot); + UpdateSpritePaletteWithWeather(paletteSlot, TRUE); } void FieldEffectScript_LoadPal(const struct SpritePalette * spritePalette) diff --git a/src/field_weather.c b/src/field_weather.c index 7fa7f0186..b5417f631 100644 --- a/src/field_weather.c +++ b/src/field_weather.c @@ -18,12 +18,6 @@ #define DROUGHT_COLOR_INDEX(color) ((((color) >> 1) & 0xF) | (((color) >> 2) & 0xF0) | (((color) >> 3) & 0xF00)) -enum -{ - COLOR_MAP_NONE, - COLOR_MAP_DARK_CONTRAST, - COLOR_MAP_CONTRAST, -}; struct RGBColor { @@ -162,7 +156,7 @@ static const u8 ALIGNED(2) sBasePaletteColorMapTypes[32] = { COLOR_MAP_DARK_CONTRAST, COLOR_MAP_DARK_CONTRAST, COLOR_MAP_DARK_CONTRAST, - COLOR_MAP_NONE, + COLOR_MAP_DARK_CONTRAST, COLOR_MAP_NONE, COLOR_MAP_NONE, // sprite palettes @@ -769,7 +763,7 @@ void FadeScreen(u8 mode, s8 delay) // Note: Copying faded -> unfaded like this works fine, except if the screen is faded back in // without transitioning to a different screen // For cases like that, use fadescreenswapbuffers - CpuFastCopy(gPlttBufferFaded, gPlttBufferUnfaded, PLTT_SIZE); + CpuFastCopy(gPlttBufferFaded, gPlttBufferUnfaded, PLTT_BUFFER_SIZE * 2); BeginNormalPaletteFade(PALETTES_ALL, delay, 0, 16, fadeColor); gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_SCREEN_FADING_OUT; @@ -779,17 +773,18 @@ void FadeScreen(u8 mode, s8 delay) gWeatherPtr->fadeDestColor = fadeColor; UpdateTimeOfDay(); if (useWeatherPal) - gWeatherPtr->fadeScreenCounter = 0; + { + gWeatherPtr->fadeScreenCounter = 0; // Triggers gamma-shift-based fade-in + } else if (!QL_IS_PLAYBACK_STATE && 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); + BeginTimeOfDayPaletteFade(PALETTES_ALL, delay, 16, 0, &gTimeBlend.startBlend, &gTimeBlend.endBlend, gTimeBlend.weight, fadeColor); } else + { BeginNormalPaletteFade(PALETTES_ALL, delay, 16, 0, fadeColor); + } gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_SCREEN_FADING_IN; gWeatherPtr->fadeInFirstFrame = TRUE; @@ -867,6 +862,36 @@ void FadeSelectedPals(u8 mode, s8 delay, u32 selectedPalettes) } } +// fades screen using BLDY +// Note: This enables blending in all windows; +// These bits may need to be disabled later +// (i.e if blending lighting effects using WINOBJ) +u32 FadeScreenHardware(u32 mode, s32 delay) +{ + u32 bldCnt = GetGpuReg(REG_OFFSET_BLDCNT) & BLDCNT_TGT2_ALL; + bldCnt |= BLDCNT_TGT1_ALL; + // enable blend in all windows + SetGpuRegBits(REG_OFFSET_WININ, WININ_WIN0_CLR | WININ_WIN1_CLR); + SetGpuRegBits(REG_OFFSET_WINOUT, WINOUT_WIN01_CLR); + + switch (mode) + { + case FADE_FROM_BLACK: + BeginHardwarePaletteFade(bldCnt | BLDCNT_EFFECT_DARKEN, delay, 16, 0, TRUE); + break; + case FADE_TO_BLACK: + BeginHardwarePaletteFade(bldCnt | BLDCNT_EFFECT_DARKEN, delay, 0, 16, FALSE); + break; + case FADE_FROM_WHITE: + BeginHardwarePaletteFade(bldCnt | BLDCNT_EFFECT_LIGHTEN, delay, 16, 0, TRUE); + break; + case FADE_TO_WHITE: + BeginHardwarePaletteFade(bldCnt | BLDCNT_EFFECT_LIGHTEN, delay, 0, 16, FALSE); + break; + } + + return 0; +} bool8 IsWeatherNotFadingIn(void) { @@ -1132,11 +1157,23 @@ void SetWeatherPalStateIdle(void) gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_IDLE; } +const u8* SetPaletteColorMapType(u8 paletteIndex, u8 colorMapType) +{ + if (sPaletteColorMapTypes[paletteIndex] == colorMapType) + return sPaletteColorMapTypes; + // setup field effect color map + if (sPaletteColorMapTypes != sFieldEffectPaletteColorMapTypes) + { + CpuCopy16(sBasePaletteColorMapTypes, sFieldEffectPaletteColorMapTypes, 32); + sPaletteColorMapTypes = sFieldEffectPaletteColorMapTypes; + } + sFieldEffectPaletteColorMapTypes[paletteIndex] = colorMapType; + return sPaletteColorMapTypes; +} + void PreservePaletteInWeather(u8 preservedPalIndex) { - CpuCopy16(sBasePaletteColorMapTypes, sFieldEffectPaletteColorMapTypes, 32); - sFieldEffectPaletteColorMapTypes[preservedPalIndex] = COLOR_MAP_NONE; - sPaletteColorMapTypes = sFieldEffectPaletteColorMapTypes; + SetPaletteColorMapType(preservedPalIndex, COLOR_MAP_NONE); } void ResetPreservedPalettesInWeather(void) diff --git a/src/overworld.c b/src/overworld.c index d0eb8f10d..c23696c7d 100644 --- a/src/overworld.c +++ b/src/overworld.c @@ -103,6 +103,7 @@ static EWRAM_DATA struct InitialPlayerAvatarState sInitialPlayerAvatarState = {} EWRAM_DATA bool8 gDisableMapMusicChangeOnMapLoad = MUSIC_DISABLE_OFF; static EWRAM_DATA u16 sAmbientCrySpecies = SPECIES_NONE; static EWRAM_DATA bool8 sIsAmbientCryWaterMon = FALSE; +EWRAM_DATA static u8 sHoursOverride = 0; // used to override apparent time of day hours ALIGNED(4) EWRAM_DATA bool8 gExitStairsMovementDisabled = FALSE; static EWRAM_DATA const struct CreditsOverworldCmd *sCreditsOverworld_Script = NULL; @@ -126,7 +127,7 @@ static bool8 sReceivingFromLink; static u8 sRfuKeepAliveTimer; u8 gTimeOfDay; -struct TimeBlendSettings currentTimeBlend; +struct TimeBlendSettings gTimeBlend; u16 gTimeUpdateCounter; // playTimeVBlanks will eventually overflow, so this is used to update TOD static u8 CountBadgesForOverworldWhiteOutLossCalculation(void); @@ -814,6 +815,8 @@ static void LoadMapFromWarp(bool32 unused) TrySetMapSaveWarpStatus(); ClearTempFieldEventData(); + // reset hours override on every warp + sHoursOverride = 0; ResetCyclingRoadChallengeData(); RestartWildEncounterImmunitySteps(); MapResetTrainerRematches(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum); @@ -1472,78 +1475,73 @@ void CB1_Overworld(void) const struct BlendSettings gTimeOfDayBlend[] = { - [TIME_OF_DAY_NIGHT] = {.coeff = 10, .blendColor = TINT_NIGHT, .isTint = TRUE}, - [TIME_OF_DAY_TWILIGHT] = {.coeff = 4, .blendColor = 0xA8B0E0, .isTint = TRUE}, - [TIME_OF_DAY_DAY] = {.coeff = 0, .blendColor = 0}, + [TIME_MORNING] = {.coeff = 4, .blendColor = 0xA8B0E0, .isTint = TRUE}, + [TIME_DAY] = {.coeff = 0, .blendColor = 0, .isTint = FALSE}, + [TIME_EVENING] = {.coeff = 4, .blendColor = 0xA8B0E0, .isTint = TRUE}, + [TIME_NIGHT] = {.coeff = 10, .blendColor = TINT_NIGHT, .isTint = TRUE}, }; -#define MORNING_START_MINUTES (MORNING_HOUR_BEGIN * MINUTES_PER_HOUR) -#define MORNING_MID_POINT (MORNING_HOUR_BEGIN * MINUTES_PER_HOUR + (MORNING_HOUR_END * MINUTES_PER_HOUR - MORNING_HOUR_BEGIN * MINUTES_PER_HOUR) / 2) -#define MORNING_END_MINUTES (MORNING_HOUR_END * MINUTES_PER_HOUR) -#define EVENING_START_MINUTES (EVENING_HOUR_BEGIN * MINUTES_PER_HOUR) -#define EVENING_MID_POINT (EVENING_HOUR_BEGIN * MINUTES_PER_HOUR + (EVENING_HOUR_END * MINUTES_PER_HOUR - EVENING_HOUR_BEGIN * MINUTES_PER_HOUR) / 2) -#define EVENING_END_MINUTES (EVENING_HOUR_END * MINUTES_PER_HOUR) +#define DEFAULT_WEIGHT 256 +#define TIME_BLEND_WEIGHT(begin, end) (DEFAULT_WEIGHT - (DEFAULT_WEIGHT * ((hours - begin) * MINUTES_PER_HOUR + minutes) / ((end - begin) * MINUTES_PER_HOUR))) -u8 UpdateTimeOfDay(void) +#define MORNING_HOUR_MIDDLE (MORNING_HOUR_BEGIN + ((MORNING_HOUR_END - MORNING_HOUR_BEGIN) / 2)) + +void UpdateTimeOfDay(void) { s32 hours, minutes; - s32 minutesOfDay; RtcCalcLocalTime(); - hours = gLocalTime.hours; - minutes = gLocalTime.minutes; - minutesOfDay = hours * MINUTES_PER_HOUR + minutes; - if (minutesOfDay < MORNING_START_MINUTES) // night + hours = sHoursOverride ? sHoursOverride : gLocalTime.hours; + minutes = sHoursOverride ? 0 : gLocalTime.minutes; + + if (IsBetweenHours(hours, MORNING_HOUR_BEGIN, MORNING_HOUR_MIDDLE)) // night->morning { - currentTimeBlend.weight = 256; - currentTimeBlend.altWeight = 0; - gTimeOfDay = currentTimeBlend.time0 = currentTimeBlend.time1 = TIME_OF_DAY_NIGHT; + gTimeBlend.startBlend = gTimeOfDayBlend[TIME_NIGHT]; + gTimeBlend.endBlend = gTimeOfDayBlend[TIME_MORNING]; + gTimeBlend.weight = TIME_BLEND_WEIGHT(MORNING_HOUR_BEGIN, MORNING_HOUR_MIDDLE); + gTimeBlend.altWeight = (DEFAULT_WEIGHT - gTimeBlend.weight) / 2; + gTimeOfDay = TIME_MORNING; } - else if (minutesOfDay < MORNING_MID_POINT) // night->twilight + else if (IsBetweenHours(hours, MORNING_HOUR_MIDDLE, MORNING_HOUR_END)) // morning->day { - currentTimeBlend.time0 = TIME_OF_DAY_NIGHT; - currentTimeBlend.time1 = TIME_OF_DAY_TWILIGHT; - currentTimeBlend.weight = 256 - 256 * (hours * 60 - MORNING_START_MINUTES + minutes) / (MORNING_MID_POINT - MORNING_START_MINUTES); - currentTimeBlend.altWeight = (256 - currentTimeBlend.weight) / 2; - gTimeOfDay = TIME_OF_DAY_DAY; + gTimeBlend.startBlend = gTimeOfDayBlend[TIME_MORNING]; + gTimeBlend.endBlend = gTimeOfDayBlend[TIME_DAY]; + gTimeBlend.weight = TIME_BLEND_WEIGHT(MORNING_HOUR_MIDDLE, MORNING_HOUR_END); + gTimeBlend.altWeight = (DEFAULT_WEIGHT - gTimeBlend.weight) / 2 + (DEFAULT_WEIGHT / 2); + gTimeOfDay = TIME_MORNING; } - else if (minutesOfDay < MORNING_END_MINUTES) // twilight->day + else if (IsBetweenHours(hours, EVENING_HOUR_BEGIN, EVENING_HOUR_END)) // evening { - currentTimeBlend.time0 = TIME_OF_DAY_TWILIGHT; - currentTimeBlend.time1 = TIME_OF_DAY_DAY; - currentTimeBlend.weight = 256 - 256 * (hours * 60 - MORNING_MID_POINT + minutes) / (MORNING_END_MINUTES - MORNING_MID_POINT); - currentTimeBlend.altWeight = (256 - currentTimeBlend.weight) / 2 + 128; - gTimeOfDay = TIME_OF_DAY_DAY; + gTimeBlend.startBlend = gTimeOfDayBlend[TIME_DAY]; + gTimeBlend.endBlend = gTimeOfDayBlend[TIME_EVENING]; + gTimeBlend.weight = TIME_BLEND_WEIGHT(EVENING_HOUR_BEGIN, EVENING_HOUR_END); + gTimeBlend.altWeight = gTimeBlend.weight / 2 + (DEFAULT_WEIGHT / 2); + gTimeOfDay = TIME_EVENING; } - else if (minutesOfDay < EVENING_START_MINUTES) // day + else if (IsBetweenHours(hours, NIGHT_HOUR_BEGIN, NIGHT_HOUR_BEGIN + 1)) // evening->night { - currentTimeBlend.weight = currentTimeBlend.altWeight = 256; - gTimeOfDay = currentTimeBlend.time0 = currentTimeBlend.time1 = TIME_OF_DAY_DAY; + gTimeBlend.startBlend = gTimeOfDayBlend[TIME_EVENING]; + gTimeBlend.endBlend = gTimeOfDayBlend[TIME_NIGHT]; + gTimeBlend.weight = TIME_BLEND_WEIGHT(NIGHT_HOUR_BEGIN, NIGHT_HOUR_BEGIN + 1); + gTimeBlend.altWeight = gTimeBlend.weight / 2; + gTimeOfDay = TIME_NIGHT; } - else if (minutesOfDay < EVENING_MID_POINT) + else if (IsBetweenHours(hours, NIGHT_HOUR_BEGIN, NIGHT_HOUR_END)) // night { - currentTimeBlend.time0 = TIME_OF_DAY_DAY; - currentTimeBlend.time1 = TIME_OF_DAY_TWILIGHT; - currentTimeBlend.weight = 256 - 256 * (hours * 60 - EVENING_START_MINUTES + minutes) / (EVENING_MID_POINT - EVENING_START_MINUTES); - currentTimeBlend.altWeight = currentTimeBlend.weight / 2 + 128; - gTimeOfDay = TIME_OF_DAY_TWILIGHT; + gTimeBlend.weight = DEFAULT_WEIGHT; + gTimeBlend.altWeight = 0; + gTimeBlend.startBlend = gTimeBlend.endBlend = gTimeOfDayBlend[TIME_NIGHT]; + gTimeOfDay = TIME_NIGHT; } - else if (minutesOfDay < EVENING_END_MINUTES) // twilight->night + else // day { - currentTimeBlend.time0 = TIME_OF_DAY_TWILIGHT; - currentTimeBlend.time1 = TIME_OF_DAY_NIGHT; - currentTimeBlend.weight = 256 - 256 * (hours * 60 - EVENING_MID_POINT + minutes) / (EVENING_END_MINUTES - EVENING_MID_POINT); - currentTimeBlend.altWeight = currentTimeBlend.weight / 2; - gTimeOfDay = TIME_OF_DAY_NIGHT; + gTimeBlend.weight = gTimeBlend.altWeight = DEFAULT_WEIGHT; + gTimeBlend.startBlend = gTimeBlend.endBlend = gTimeOfDayBlend[TIME_DAY]; + gTimeOfDay = TIME_DAY; } - else // 22-24, night - { - currentTimeBlend.weight = 256; - currentTimeBlend.altWeight = 0; - gTimeOfDay = currentTimeBlend.time0 = currentTimeBlend.time1 = TIME_OF_DAY_NIGHT; - } - return gTimeOfDay; } +#undef TIME_BLEND_WEIGHT + // Whether a map type is naturally lit/outside bool8 MapHasNaturalLight(u8 mapType) { @@ -1577,9 +1575,9 @@ void UpdateAltBgPalettes(u16 palettes) if (palettes & 1) { if (i < NUM_PALS_IN_PRIMARY) - AvgPaletteWeighted(&((u16*)primary->palettes)[i*16], &((u16*)primary->palettes)[((i+9)%16)*16], gPlttBufferUnfaded + i * 16, currentTimeBlend.altWeight); + AvgPaletteWeighted(&((u16*)primary->palettes)[i*16], &((u16*)primary->palettes)[((i+9)%16)*16], gPlttBufferUnfaded + i * 16, gTimeBlend.altWeight); else - AvgPaletteWeighted(&((u16*)secondary->palettes)[i*16], &((u16*)secondary->palettes)[((i+9)%16)*16], gPlttBufferUnfaded + i * 16, currentTimeBlend.altWeight); + AvgPaletteWeighted(&((u16*)secondary->palettes)[i*16], &((u16*)secondary->palettes)[((i+9)%16)*16], gPlttBufferUnfaded + i * 16, gTimeBlend.altWeight); } i++; palettes >>= 1; @@ -1602,14 +1600,7 @@ void UpdatePalettesWithTime(u32 palettes) palettes &= PALETTES_MAP | PALETTES_OBJECTS; // Don't blend UI pals if (!palettes) return; - TimeMixPalettes( - palettes, - gPlttBufferUnfaded, - gPlttBufferFaded, - (struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0], - (struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time1], - currentTimeBlend.weight - ); + TimeMixPalettes(palettes, gPlttBufferUnfaded, gPlttBufferFaded, &gTimeBlend.startBlend, &gTimeBlend.endBlend, gTimeBlend.weight); } } @@ -1619,15 +1610,9 @@ u8 UpdateSpritePaletteWithTime(u8 paletteNum) return paletteNum; if (MapHasNaturalLight(gMapHeader.mapType)) { - if (GetSpritePaletteTagByPaletteNum(paletteNum) != 0xFFFF && IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(paletteNum))) + if (IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(paletteNum))) return paletteNum; - TimeMixPalettes(1, - &gPlttBufferUnfaded[OBJ_PLTT_ID(paletteNum)], - &gPlttBufferFaded[OBJ_PLTT_ID(paletteNum)], - (struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0], - (struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time1], - currentTimeBlend.weight - ); + TimeMixPalettes(1, &gPlttBufferUnfaded[OBJ_PLTT_ID(paletteNum)], &gPlttBufferFaded[OBJ_PLTT_ID(paletteNum)], &gTimeBlend.startBlend, &gTimeBlend.endBlend, gTimeBlend.weight); } return paletteNum; } @@ -1645,18 +1630,16 @@ static void OverworldBasic(void) UpdateTilesetAnimations(); DoScheduledBgTilemapCopiesToVram(); // Every minute if no palette fade is active, update TOD blending as needed - if (!gPaletteFade.active && ++gTimeUpdateCounter >= (SECONDS_PER_MINUTE * 60 / FakeRtc_GetSecondsRatio())) + if (!gPaletteFade.active && --gTimeUpdateCounter <= 0 && ++gTimeUpdateCounter >= (SECONDS_PER_MINUTE * 60 / FakeRtc_GetSecondsRatio())) { - struct TimeBlendSettings cachedBlend = { - .time0 = currentTimeBlend.time0, - .time1 = currentTimeBlend.time1, - .weight = currentTimeBlend.weight, - }; - gTimeUpdateCounter = 0; + struct TimeBlendSettings cachedBlend = gTimeBlend; + u32 *bld0 = (u32*)&cachedBlend; + u32 *bld1 = (u32*)&gTimeBlend; + gTimeUpdateCounter = (SECONDS_PER_MINUTE * 60 / FakeRtc_GetSecondsRatio()); UpdateTimeOfDay(); - if (cachedBlend.time0 != currentTimeBlend.time0 - || cachedBlend.time1 != currentTimeBlend.time1 - || cachedBlend.weight != currentTimeBlend.weight) + if (bld0[0] != bld1[0] + || bld0[1] != bld1[1] + || bld0[2] != bld1[2]) { UpdateAltBgPalettes(PALETTES_BG); UpdatePalettesWithTime(PALETTES_ALL); diff --git a/src/scrcmd.c b/src/scrcmd.c index eb25020c5..ca733d3e4 100644 --- a/src/scrcmd.c +++ b/src/scrcmd.c @@ -811,37 +811,30 @@ bool8 ScrCmd_fadescreenspeed(struct ScriptContext * ctx) return TRUE; } -static EWRAM_DATA u32 *sPalBuffer = NULL; - bool8 ScrCmd_fadescreenswapbuffers(struct ScriptContext *ctx) { u8 mode = ScriptReadByte(ctx); + u8 nowait = ScriptReadByte(ctx); Script_RequestEffects(SCREFF_V1 | SCREFF_HARDWARE); switch (mode) { - case FADE_TO_BLACK: - case FADE_TO_WHITE: - default: - if (sPalBuffer == NULL) - { - sPalBuffer = Alloc(PLTT_SIZE); - CpuCopy32(gPlttBufferUnfaded, sPalBuffer, PLTT_SIZE); - FadeScreen(mode, 0); - } - break; case FADE_FROM_BLACK: case FADE_FROM_WHITE: - if (sPalBuffer != NULL) - { - CpuCopy32(sPalBuffer, gPlttBufferUnfaded, PLTT_SIZE); - FadeScreen(mode, 0); - FREE_AND_SET_NULL(sPalBuffer); - } + // Restore last weather blend before fading in, + // since BLDALPHA was modified by fade-out + SetGpuReg( + REG_OFFSET_BLDALPHA, + BLDALPHA_BLEND(gWeatherPtr->currBlendEVA, gWeatherPtr->currBlendEVB) + ); break; } + FadeScreenHardware(mode, 0); + + if (nowait) + return FALSE; SetupNativeScript(ctx, IsPaletteNotActive); return TRUE; }