Merge branch 'lighting' into lighting-expanded-id
This commit is contained in:
commit
c1d105c31c
@ -1674,13 +1674,14 @@
|
||||
.4byte \text
|
||||
.endm
|
||||
|
||||
@ Equivalent to fadescreen but copies gPlttBufferUnfaded to gPaletteDecompressionBuffer 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 0xdc
|
||||
.byte \mode
|
||||
.byte \nowait
|
||||
.byte \nowait
|
||||
.endm
|
||||
|
||||
@ Buffers the specified trainer's class name to the given string var.
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#include "constants/field_weather.h"
|
||||
@ The first .byte argument of each macro below is an index into gFieldEffectScriptFuncs
|
||||
|
||||
.macro field_eff_loadtiles address:req
|
||||
@ -5,9 +6,10 @@
|
||||
.4byte \address
|
||||
.endm
|
||||
|
||||
.macro field_eff_loadfadedpal address:req
|
||||
.macro field_eff_loadfadedpal address:req, color_map_type=COLOR_MAP_DARK_CONTRAST
|
||||
.byte 1
|
||||
.4byte \address
|
||||
.byte \color_map_type
|
||||
.endm
|
||||
|
||||
.macro field_eff_loadpal address:req
|
||||
@ -24,10 +26,11 @@
|
||||
.byte 4
|
||||
.endm
|
||||
|
||||
.macro field_eff_loadgfx_callnative tiles_address:req, palette_address:req, function_address:req
|
||||
.macro field_eff_loadgfx_callnative tiles_address:req, palette_address:req, function_address:req, color_map_type=COLOR_MAP_DARK_CONTRAST
|
||||
.byte 5
|
||||
.4byte \tiles_address
|
||||
.4byte \palette_address
|
||||
.byte \color_map_type
|
||||
.4byte \function_address
|
||||
.endm
|
||||
|
||||
@ -37,8 +40,9 @@
|
||||
.4byte \function_address
|
||||
.endm
|
||||
|
||||
.macro field_eff_loadfadedpal_callnative palette_address:req, function_address:req
|
||||
.macro field_eff_loadfadedpal_callnative palette_address:req, function_address:req, color_map_type=COLOR_MAP_DARK_CONTRAST
|
||||
.byte 7
|
||||
.4byte \palette_address
|
||||
.byte \color_map_type
|
||||
.4byte \function_address
|
||||
.endm
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
#ifndef GUARD_CONSTANTS_FIELD_WEATHER_H
|
||||
#define GUARD_CONSTANTS_FIELD_WEATHER_H
|
||||
|
||||
// sPaletteColorMapTypes & field_effect_scripts
|
||||
#define COLOR_MAP_NONE 0
|
||||
#define COLOR_MAP_DARK_CONTRAST 1
|
||||
#define COLOR_MAP_CONTRAST 2
|
||||
|
||||
#define MAX_RAIN_SPRITES 24
|
||||
#define NUM_CLOUD_SPRITES 3
|
||||
#define NUM_FOG_HORIZONTAL_SPRITES 20
|
||||
|
||||
@ -152,6 +152,7 @@ void SetCurrentAndNextWeatherNoDelay(u8 weather);
|
||||
void ApplyWeatherColorMapIfIdle(s8 colorMapIndex);
|
||||
void ApplyWeatherColorMapIfIdle_Gradual(u8 colorMapIndex, u8 targetColorMapIndex, u8 colorMapStepDelay);
|
||||
void FadeScreen(u8 mode, s8 delay);
|
||||
u16 FadeScreenHardware(u8 mode, s8 delay);
|
||||
bool8 IsWeatherNotFadingIn(void);
|
||||
void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex, bool8 allowFog);
|
||||
void ApplyWeatherColorMapToPal(u8 paletteIndex);
|
||||
@ -170,7 +171,9 @@ void PlayRainStoppingSoundEffect(void);
|
||||
u8 IsWeatherChangeComplete(void);
|
||||
void SetWeatherScreenFadeOut(void);
|
||||
void SetWeatherPalStateIdle(void);
|
||||
const u8* SetPaletteColorMapType(u8 paletteIndex, u8 colorMapType);
|
||||
void PreservePaletteInWeather(u8 preservedPalIndex);
|
||||
void ResetPaletteColorMapType(u8 paletteIndex);
|
||||
void ResetPreservedPalettesInWeather(void);
|
||||
|
||||
// field_weather_effect.c
|
||||
|
||||
@ -599,6 +599,7 @@
|
||||
#define BLDCNT_EFFECT_BLEND (1 << 6) // 1st+2nd targets mixed (controlled by BLDALPHA)
|
||||
#define BLDCNT_EFFECT_LIGHTEN (2 << 6) // 1st target becomes whiter (controlled by BLDY)
|
||||
#define BLDCNT_EFFECT_DARKEN (3 << 6) // 1st target becomes blacker (controlled by BLDY)
|
||||
#define BLDCNT_EFFECT_EFF_MASK (3 << 6) // mask to check effect
|
||||
// Bits 8-13 select layers for the 2nd target
|
||||
#define BLDCNT_TGT2_BG0 (1 << 8)
|
||||
#define BLDCNT_TGT2_BG1 (1 << 9)
|
||||
@ -611,6 +612,8 @@
|
||||
|
||||
// BLDALPHA
|
||||
#define BLDALPHA_BLEND(target1, target2) (((target2) << 8) | (target1))
|
||||
#define BLDALPHA_TGT1(bld) ((bld) & 0x1F)
|
||||
#define BLDALPHA_TGT2(bld) (((bld) >> 8) & 0x1F)
|
||||
|
||||
// SOUNDCNT_H
|
||||
#define SOUND_CGB_MIX_QUARTER 0x0000
|
||||
|
||||
@ -30,6 +30,11 @@
|
||||
#define TIME_OF_DAY_DAY 2
|
||||
#define TIME_OF_DAY_MAX TIME_OF_DAY_DAY
|
||||
|
||||
// trigger a time-of-day blend once
|
||||
#define HOURS_BLEND_ONCE 25
|
||||
// don't update currentTimeBlend
|
||||
#define HOURS_FREEZE_BLEND 26
|
||||
|
||||
struct InitialPlayerAvatarState
|
||||
{
|
||||
u8 transitionFlags;
|
||||
@ -44,14 +49,6 @@ struct LinkPlayerObjectEvent
|
||||
u8 movementMode;
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) TimeBlendSettings {
|
||||
u16 weight:9;
|
||||
u16 time1:3;
|
||||
u16 time0:3;
|
||||
u16 unused:1;
|
||||
u16 altWeight;
|
||||
};
|
||||
|
||||
// Exported RAM declarations
|
||||
extern struct WarpData gLastUsedWarp;
|
||||
extern struct LinkPlayerObjectEvent gLinkPlayerObjectEvents[4];
|
||||
@ -65,7 +62,7 @@ extern bool8 (*gFieldCallback2)(void);
|
||||
extern u8 gLocalLinkPlayerId;
|
||||
extern u8 gFieldLinkPlayerCount;
|
||||
extern u8 gTimeOfDay;
|
||||
extern u16 gTimeUpdateCounter;
|
||||
extern s16 gTimeUpdateCounter;
|
||||
|
||||
extern struct TimeBlendSettings currentTimeBlend;
|
||||
|
||||
@ -175,5 +172,6 @@ bool32 Overworld_RecvKeysFromLinkIsRunning(void);
|
||||
bool32 Overworld_SendKeysToLinkIsRunning(void);
|
||||
bool32 IsSendingKeysOverCable(void);
|
||||
void ClearLinkPlayerObjectEvents(void);
|
||||
bool16 SetTimeOfDay(u16 hours);
|
||||
|
||||
#endif // GUARD_OVERWORLD_H
|
||||
|
||||
@ -45,6 +45,13 @@ struct BlendSettings {
|
||||
u32 coeff:5;
|
||||
};
|
||||
|
||||
struct __attribute__((packed)) TimeBlendSettings {
|
||||
struct BlendSettings bld0;
|
||||
struct BlendSettings bld1;
|
||||
u16 weight;
|
||||
u16 altWeight;
|
||||
};
|
||||
|
||||
struct PaletteFadeControl
|
||||
{
|
||||
u32 multipurpose1; // This field needs to exist or errors will occur
|
||||
@ -92,7 +99,7 @@ void InvertPlttBuffer(u32 selectedPalettes);
|
||||
void TintPlttBuffer(u32 selectedPalettes, s8 r, s8 g, s8 b);
|
||||
void UnfadePlttBuffer(u32 selectedPalettes);
|
||||
void BeginFastPaletteFade(u8 submode);
|
||||
void BeginHardwarePaletteFade(u8 blendCnt, u8 delay, u8 y, u8 targetY, u8 shouldResetBlendRegisters);
|
||||
void BeginHardwarePaletteFade(u16 blendCnt, u8 delay, u8 y, u8 targetY, u8 shouldResetBlendRegisters);
|
||||
void BlendPalettes(u32 selectedPalettes, u8 coeff, u16 color);
|
||||
void BlendPalettesFine(u32 palettes, u16 *src, u16 *dst, u32 coeff, u32 color);
|
||||
void BlendPalettesUnfaded(u32 selectedPalettes, u8 coeff, u16 color);
|
||||
|
||||
@ -2513,6 +2513,8 @@ void UpdateLightSprite(struct Sprite *sprite) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Note to self: Don't set window registers during hardware fade!
|
||||
|
||||
switch (sprite->data[5]) { // lightType
|
||||
case 0:
|
||||
if (gPaletteFade.active) { // if palette fade is active, don't flicker since the timer won't be updated
|
||||
@ -2566,7 +2568,7 @@ static void SpawnLightSprite(s16 x, s16 y, s16 camX, s16 camY, u32 lightType) {
|
||||
sprite->centerToCornerVecX = -(32 >> 1);
|
||||
sprite->centerToCornerVecY = -(32 >> 1);
|
||||
sprite->oam.priority = 1;
|
||||
sprite->oam.objMode = 1; // BLEND
|
||||
sprite->oam.objMode = ST_OAM_OBJ_BLEND;
|
||||
sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL;
|
||||
sprite->x += 8;
|
||||
sprite->y += 22 + sprite->centerToCornerVecY;
|
||||
@ -2576,7 +2578,7 @@ static void SpawnLightSprite(s16 x, s16 y, s16 camX, s16 camY, u32 lightType) {
|
||||
sprite->centerToCornerVecY = -(16 >> 1);
|
||||
sprite->oam.priority = 2;
|
||||
sprite->subpriority = 0xFF;
|
||||
sprite->oam.objMode = 1; // BLEND
|
||||
sprite->oam.objMode = ST_OAM_OBJ_BLEND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -781,9 +781,11 @@ void FieldEffectScript_LoadTiles(u8 **script)
|
||||
void FieldEffectScript_LoadFadedPalette(u8 **script)
|
||||
{
|
||||
struct SpritePalette *palette = (struct SpritePalette *)FieldEffectScript_ReadWord(script);
|
||||
LoadSpritePalette(palette);
|
||||
UpdateSpritePaletteWithWeather(IndexOfSpritePaletteTag(palette->tag), TRUE);
|
||||
u32 paletteSlot = LoadSpritePalette(palette);
|
||||
(*script) += 4;
|
||||
SetPaletteColorMapType(paletteSlot + 16, T1_READ_8(*script));
|
||||
UpdateSpritePaletteWithWeather(paletteSlot, TRUE);
|
||||
(*script)++;
|
||||
}
|
||||
|
||||
void FieldEffectScript_LoadPalette(u8 **script)
|
||||
@ -839,6 +841,7 @@ void FieldEffectFreePaletteIfUnused(u8 paletteNum)
|
||||
for (i = 0; i < MAX_SPRITES; i++)
|
||||
if (gSprites[i].inUse && gSprites[i].oam.paletteNum == paletteNum)
|
||||
return;
|
||||
ResetPaletteColorMapType(paletteNum + 16);
|
||||
FreeSpritePaletteByTag(tag);
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,8 +56,8 @@ u32 FldEff_Shadow(void);
|
||||
|
||||
void SetUpShadow(struct ObjectEvent *objectEvent, struct Sprite *sprite) {
|
||||
gFieldEffectArguments[0] = objectEvent->localId;
|
||||
gFieldEffectArguments[1] = gSaveBlock1Ptr->location.mapNum;
|
||||
gFieldEffectArguments[2] = gSaveBlock1Ptr->location.mapGroup;
|
||||
gFieldEffectArguments[1] = objectEvent->mapNum;
|
||||
gFieldEffectArguments[2] = objectEvent->mapGroup;
|
||||
FldEff_Shadow();
|
||||
}
|
||||
|
||||
@ -328,7 +328,11 @@ u32 FldEff_Shadow(void)
|
||||
s32 i;
|
||||
for (i = MAX_SPRITES - 1; i > -1; i--) { // Search backwards, because of CreateSpriteAtEnd
|
||||
// Return early if a shadow sprite already exists
|
||||
if (gSprites[i].data[0] == gFieldEffectArguments[0] && gSprites[i].callback == UpdateShadowFieldEffect)
|
||||
if (gSprites[i].callback == UpdateShadowFieldEffect &&
|
||||
gSprites[i].sLocalId == gFieldEffectArguments[0] &&
|
||||
gSprites[i].sMapNum == gFieldEffectArguments[1] &&
|
||||
gSprites[i].sMapGroup == gFieldEffectArguments[2]
|
||||
)
|
||||
return 0;
|
||||
}
|
||||
objectEventId = GetObjectEventIdByLocalIdAndMap(gFieldEffectArguments[0], gFieldEffectArguments[1], gFieldEffectArguments[2]);
|
||||
@ -340,7 +344,7 @@ u32 FldEff_Shadow(void)
|
||||
if (spriteId != MAX_SPRITES)
|
||||
{
|
||||
// SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(8, 12));
|
||||
gSprites[spriteId].oam.objMode = 1; // BLEND
|
||||
gSprites[spriteId].oam.objMode = ST_OAM_OBJ_BLEND;
|
||||
gSprites[spriteId].coordOffsetEnabled = TRUE;
|
||||
gSprites[spriteId].sLocalId = gFieldEffectArguments[0];
|
||||
gSprites[spriteId].sMapNum = gFieldEffectArguments[1];
|
||||
|
||||
@ -20,13 +20,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
|
||||
{
|
||||
u16 r:5;
|
||||
@ -806,8 +799,8 @@ void FadeScreen(u8 mode, s8 delay)
|
||||
if (MapHasNaturalLight(gMapHeader.mapType)) {
|
||||
UpdateAltBgPalettes(PALETTES_BG);
|
||||
BeginTimeOfDayPaletteFade(PALETTES_ALL, delay, 16, 0,
|
||||
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time0],
|
||||
(struct BlendSettings *)&gTimeOfDayBlend[currentTimeBlend.time1],
|
||||
¤tTimeBlend.bld0,
|
||||
¤tTimeBlend.bld1,
|
||||
currentTimeBlend.weight, fadeColor);
|
||||
} else {
|
||||
BeginNormalPaletteFade(PALETTES_ALL, delay, 16, 0, fadeColor);
|
||||
@ -822,6 +815,36 @@ void FadeScreen(u8 mode, s8 delay)
|
||||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
u16 FadeScreenHardware(u8 mode, s8 delay) {
|
||||
u16 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)
|
||||
{
|
||||
return (gWeatherPtr->palProcessingState != WEATHER_PAL_STATE_SCREEN_FADING_IN);
|
||||
@ -986,7 +1009,10 @@ void Weather_SetBlendCoeffs(u8 eva, u8 evb)
|
||||
gWeatherPtr->currBlendEVB = evb;
|
||||
gWeatherPtr->targetBlendEVA = eva;
|
||||
gWeatherPtr->targetBlendEVB = evb;
|
||||
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(eva, evb));
|
||||
|
||||
// don't update BLDALPHA if a hardware fade is on-screen
|
||||
if ((GetGpuReg(REG_OFFSET_BLDCNT) & BLDCNT_EFFECT_EFF_MASK) < BLDCNT_EFFECT_LIGHTEN)
|
||||
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(eva, evb));
|
||||
}
|
||||
|
||||
void Weather_SetTargetBlendCoeffs(u8 eva, u8 evb, int delay)
|
||||
@ -1136,11 +1162,27 @@ 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) {
|
||||
CpuFastCopy(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 ResetPaletteColorMapType(u8 paletteIndex) {
|
||||
if (sPaletteColorMapTypes == sBasePaletteColorMapTypes)
|
||||
return;
|
||||
sFieldEffectPaletteColorMapTypes[paletteIndex] = sBasePaletteColorMapTypes[paletteIndex];
|
||||
}
|
||||
|
||||
void ResetPreservedPalettesInWeather(void)
|
||||
|
||||
@ -881,7 +881,7 @@ static void LoadTilesetPalette(struct Tileset const *tileset, u16 destOffset, u1
|
||||
{
|
||||
// LoadPalette(&black, destOffset, 2);
|
||||
if (skipFaded)
|
||||
CpuFastCopy(tileset->palettes, &gPlttBufferUnfaded[destOffset], size);
|
||||
CpuFastCopy(tileset->palettes, &gPlttBufferUnfaded[destOffset], size); // always word-aligned
|
||||
else
|
||||
LoadPaletteFast(tileset->palettes, destOffset, size);
|
||||
gPlttBufferFaded[destOffset] = gPlttBufferUnfaded[destOffset] = RGB_BLACK; // why does it have to be black?
|
||||
@ -891,11 +891,11 @@ static void LoadTilesetPalette(struct Tileset const *tileset, u16 destOffset, u1
|
||||
}
|
||||
else if (tileset->isSecondary == TRUE)
|
||||
{
|
||||
// (void*) is to silence 'source potentially unaligned' error
|
||||
// All 'gTilesetPalettes_' arrays should have ALIGNED(4) in them
|
||||
if (skipFaded)
|
||||
CpuFastCopy((void*)tileset->palettes[NUM_PALS_IN_PRIMARY], &gPlttBufferUnfaded[destOffset], size);
|
||||
else
|
||||
// All 'gTilesetPalettes_' arrays should have ALIGNED(4) in them,
|
||||
// but we use SmartCopy here just in case they don't
|
||||
if (skipFaded) {
|
||||
CpuSmartCopy16(tileset->palettes[NUM_PALS_IN_PRIMARY], &gPlttBufferUnfaded[destOffset], size);
|
||||
} else
|
||||
LoadPaletteFast(tileset->palettes[NUM_PALS_IN_PRIMARY], destOffset, size);
|
||||
low = NUM_PALS_IN_PRIMARY;
|
||||
high = NUM_PALS_TOTAL;
|
||||
|
||||
139
src/overworld.c
139
src/overworld.c
@ -194,7 +194,7 @@ u8 gFieldLinkPlayerCount;
|
||||
|
||||
u8 gTimeOfDay;
|
||||
struct TimeBlendSettings currentTimeBlend;
|
||||
u16 gTimeUpdateCounter; // playTimeVBlanks will eventually overflow, so this is used to update TOD
|
||||
s16 gTimeUpdateCounter; // playTimeVBlanks will eventually overflow, so this is used to update TOD
|
||||
|
||||
// EWRAM vars
|
||||
EWRAM_DATA static u8 sObjectEventLoadFlag = 0;
|
||||
@ -206,6 +206,7 @@ EWRAM_DATA static u16 sLastMapSectionId = 0;
|
||||
EWRAM_DATA static struct InitialPlayerAvatarState sInitialPlayerAvatarState = {0};
|
||||
EWRAM_DATA static u16 sAmbientCrySpecies = 0;
|
||||
EWRAM_DATA static bool8 sIsAmbientCryWaterMon = FALSE;
|
||||
EWRAM_DATA static u8 sHoursOverride = 0; // used to override apparent time of day hours
|
||||
EWRAM_DATA struct LinkPlayerObjectEvent gLinkPlayerObjectEvents[4] = {0};
|
||||
|
||||
static const struct WarpData sDummyWarpData =
|
||||
@ -853,6 +854,8 @@ static void LoadMapFromWarp(bool32 a1)
|
||||
CheckLeftFriendsSecretBase();
|
||||
TrySetMapSaveWarpStatus();
|
||||
ClearTempFieldEventData();
|
||||
// reset hours override on every warp
|
||||
sHoursOverride = 0;
|
||||
ResetCyclingRoadChallengeData();
|
||||
RestartWildEncounterImmunitySteps();
|
||||
TryUpdateRandomTrainerRematches(gSaveBlock1Ptr->location.mapGroup, gSaveBlock1Ptr->location.mapNum);
|
||||
@ -1481,44 +1484,65 @@ const struct BlendSettings gTimeOfDayBlend[] =
|
||||
u8 UpdateTimeOfDay(void) {
|
||||
s32 hours, minutes;
|
||||
RtcCalcLocalTime();
|
||||
hours = gLocalTime.hours;
|
||||
minutes = gLocalTime.minutes;
|
||||
if (hours < 4) { // night
|
||||
hours = sHoursOverride ? sHoursOverride : gLocalTime.hours;
|
||||
minutes = sHoursOverride ? 0 : gLocalTime.minutes;
|
||||
switch (hours)
|
||||
{
|
||||
case 0 ... 3: // night
|
||||
gTimeOfDay = TIME_OF_DAY_NIGHT;
|
||||
currentTimeBlend.bld0 = currentTimeBlend.bld1 = gTimeOfDayBlend[gTimeOfDay];
|
||||
currentTimeBlend.weight = 256;
|
||||
currentTimeBlend.altWeight = 0;
|
||||
gTimeOfDay = currentTimeBlend.time0 = currentTimeBlend.time1 = TIME_OF_DAY_NIGHT;
|
||||
} else if (hours < 7) { // night->twilight
|
||||
currentTimeBlend.time0 = TIME_OF_DAY_NIGHT;
|
||||
currentTimeBlend.time1 = TIME_OF_DAY_TWILIGHT;
|
||||
break;
|
||||
case 4 ... 6: // night -> twilight
|
||||
currentTimeBlend.bld0 = gTimeOfDayBlend[TIME_OF_DAY_NIGHT];
|
||||
currentTimeBlend.bld1 = gTimeOfDayBlend[TIME_OF_DAY_TWILIGHT];
|
||||
currentTimeBlend.weight = 256 - 256 * ((hours - 4) * 60 + minutes) / ((7-4)*60);
|
||||
currentTimeBlend.altWeight = (256 - currentTimeBlend.weight) / 2;
|
||||
gTimeOfDay = TIME_OF_DAY_DAY;
|
||||
} else if (hours < 10) { // twilight->day
|
||||
currentTimeBlend.time0 = TIME_OF_DAY_TWILIGHT;
|
||||
currentTimeBlend.time1 = TIME_OF_DAY_DAY;
|
||||
break;
|
||||
case 7 ... 9: // twilight -> day
|
||||
currentTimeBlend.bld0 = gTimeOfDayBlend[TIME_OF_DAY_TWILIGHT];
|
||||
currentTimeBlend.bld1 = gTimeOfDayBlend[TIME_OF_DAY_DAY];
|
||||
currentTimeBlend.weight = 256 - 256 * ((hours - 7) * 60 + minutes) / ((10-7)*60);
|
||||
currentTimeBlend.altWeight = (256 - currentTimeBlend.weight) / 2 + 128;
|
||||
gTimeOfDay = TIME_OF_DAY_DAY;
|
||||
} else if (hours < 18) { // day
|
||||
break;
|
||||
case 10 ... 17: // day
|
||||
gTimeOfDay = TIME_OF_DAY_DAY;
|
||||
currentTimeBlend.bld0 = currentTimeBlend.bld1 = gTimeOfDayBlend[gTimeOfDay];
|
||||
currentTimeBlend.weight = currentTimeBlend.altWeight = 256;
|
||||
gTimeOfDay = currentTimeBlend.time0 = currentTimeBlend.time1 = TIME_OF_DAY_DAY;
|
||||
} else if (hours < 20) { // day->twilight
|
||||
currentTimeBlend.time0 = TIME_OF_DAY_DAY;
|
||||
currentTimeBlend.time1 = TIME_OF_DAY_TWILIGHT;
|
||||
break;
|
||||
case 18 ... 19: // day -> twilight
|
||||
currentTimeBlend.bld0 = gTimeOfDayBlend[TIME_OF_DAY_DAY];
|
||||
currentTimeBlend.bld1 = gTimeOfDayBlend[TIME_OF_DAY_TWILIGHT];
|
||||
currentTimeBlend.weight = 256 - 256 * ((hours - 18) * 60 + minutes) / ((20-18)*60);
|
||||
currentTimeBlend.altWeight = currentTimeBlend.weight / 2 + 128;
|
||||
gTimeOfDay = TIME_OF_DAY_TWILIGHT;
|
||||
} else if (hours < 22) { // twilight->night
|
||||
currentTimeBlend.time0 = TIME_OF_DAY_TWILIGHT;
|
||||
currentTimeBlend.time1 = TIME_OF_DAY_NIGHT;
|
||||
break;
|
||||
case 20 ... 21: // twilight -> night
|
||||
currentTimeBlend.bld0 = gTimeOfDayBlend[TIME_OF_DAY_TWILIGHT];
|
||||
currentTimeBlend.bld1 = gTimeOfDayBlend[TIME_OF_DAY_NIGHT];
|
||||
currentTimeBlend.weight = 256 - 256 * ((hours - 20) * 60 + minutes) / ((22-20)*60);
|
||||
currentTimeBlend.altWeight = currentTimeBlend.weight / 2;
|
||||
gTimeOfDay = TIME_OF_DAY_NIGHT;
|
||||
} else { // 22-24, night
|
||||
break;
|
||||
case 22 ... 24:
|
||||
gTimeOfDay = TIME_OF_DAY_NIGHT;
|
||||
currentTimeBlend.bld0 = currentTimeBlend.bld1 = gTimeOfDayBlend[gTimeOfDay];
|
||||
currentTimeBlend.weight = 256;
|
||||
currentTimeBlend.altWeight = 0;
|
||||
gTimeOfDay = currentTimeBlend.time0 = currentTimeBlend.time1 = TIME_OF_DAY_NIGHT;
|
||||
break;
|
||||
// special value; always causes a blend update,
|
||||
// and increments sHoursOverride
|
||||
case HOURS_BLEND_ONCE:
|
||||
currentTimeBlend.weight ^= 1;
|
||||
sHoursOverride++;
|
||||
break;
|
||||
case HOURS_FREEZE_BLEND:
|
||||
break;
|
||||
}
|
||||
|
||||
return gTimeOfDay;
|
||||
}
|
||||
|
||||
@ -1565,32 +1589,32 @@ void UpdatePalettesWithTime(u32 palettes) {
|
||||
if (IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(i)))
|
||||
palettes &= ~(mask);
|
||||
|
||||
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
|
||||
);
|
||||
palettes &= PALETTES_MAP | PALETTES_OBJECTS; // Don't blend UI pals
|
||||
if (!palettes)
|
||||
return;
|
||||
TimeMixPalettes(
|
||||
palettes,
|
||||
gPlttBufferUnfaded,
|
||||
gPlttBufferFaded,
|
||||
¤tTimeBlend.bld0,
|
||||
¤tTimeBlend.bld1,
|
||||
currentTimeBlend.weight
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
u8 UpdateSpritePaletteWithTime(u8 paletteNum) {
|
||||
if (MapHasNaturalLight(gMapHeader.mapType)) {
|
||||
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
|
||||
);
|
||||
return paletteNum;
|
||||
TimeMixPalettes(
|
||||
1,
|
||||
&gPlttBufferUnfaded[OBJ_PLTT_ID(paletteNum)],
|
||||
&gPlttBufferFaded[OBJ_PLTT_ID(paletteNum)],
|
||||
¤tTimeBlend.bld0,
|
||||
¤tTimeBlend.bld1,
|
||||
currentTimeBlend.weight
|
||||
);
|
||||
}
|
||||
return paletteNum;
|
||||
}
|
||||
@ -1607,18 +1631,16 @@ static void OverworldBasic(void)
|
||||
UpdateTilesetAnimations();
|
||||
DoScheduledBgTilemapCopiesToVram();
|
||||
// Every minute if no palette fade is active, update TOD blending as needed
|
||||
if (!gPaletteFade.active && ++gTimeUpdateCounter >= 3600) {
|
||||
struct TimeBlendSettings cachedBlend = {
|
||||
.time0 = currentTimeBlend.time0,
|
||||
.time1 = currentTimeBlend.time1,
|
||||
.weight = currentTimeBlend.weight,
|
||||
};
|
||||
gTimeUpdateCounter = 0;
|
||||
if (!gPaletteFade.active && --gTimeUpdateCounter <= 0) {
|
||||
struct TimeBlendSettings cachedBlend = currentTimeBlend;
|
||||
u32 *bld0 = (u32*)&cachedBlend;
|
||||
u32 *bld1 = (u32*)¤tTimeBlend;
|
||||
gTimeUpdateCounter = 3600;
|
||||
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);
|
||||
}
|
||||
@ -3380,3 +3402,16 @@ static void SpriteCB_LinkPlayer(struct Sprite *sprite)
|
||||
sprite->data[7]++;
|
||||
}
|
||||
}
|
||||
|
||||
// returns old sHoursOverride
|
||||
u16 SetTimeOfDay(u16 hours) {
|
||||
u16 oldHours = sHoursOverride;
|
||||
sHoursOverride = hours;
|
||||
gTimeUpdateCounter = 0;
|
||||
return oldHours;
|
||||
}
|
||||
|
||||
bool8 ScrFunc_settimeofday(struct ScriptContext *ctx) {
|
||||
SetTimeOfDay(ScriptReadByte(ctx));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -896,7 +896,7 @@ static u8 UpdateFastPaletteFade(void)
|
||||
return gPaletteFade.active ? PALETTE_FADE_STATUS_ACTIVE : PALETTE_FADE_STATUS_DONE;
|
||||
}
|
||||
|
||||
void BeginHardwarePaletteFade(u8 blendCnt, u8 delay, u8 y, u8 targetY, u8 shouldResetBlendRegisters)
|
||||
void BeginHardwarePaletteFade(u16 blendCnt, u8 delay, u8 y, u8 targetY, u8 shouldResetBlendRegisters)
|
||||
{
|
||||
gPaletteFade_blendCnt = blendCnt;
|
||||
gPaletteFade.delayCounter = delay;
|
||||
@ -950,7 +950,8 @@ static u8 UpdateHardwarePaletteFade(void)
|
||||
{
|
||||
if (gPaletteFade.shouldResetBlendRegisters)
|
||||
{
|
||||
gPaletteFade_blendCnt = 0;
|
||||
// clear TGT1
|
||||
gPaletteFade_blendCnt &= ~0xFF;
|
||||
gPaletteFade.y = 0;
|
||||
}
|
||||
gPaletteFade.shouldResetBlendRegisters = FALSE;
|
||||
@ -961,10 +962,43 @@ static u8 UpdateHardwarePaletteFade(void)
|
||||
return gPaletteFade.active ? PALETTE_FADE_STATUS_ACTIVE : PALETTE_FADE_STATUS_DONE;
|
||||
}
|
||||
|
||||
// Only called for hardware fades
|
||||
static void UpdateBlendRegisters(void)
|
||||
{
|
||||
SetGpuReg(REG_OFFSET_BLDCNT, (u16)gPaletteFade_blendCnt);
|
||||
SetGpuReg(REG_OFFSET_BLDY, gPaletteFade.y);
|
||||
// If fade-out, also adjust BLDALPHA and DISPCNT
|
||||
if (!gPaletteFade.yDec /*&& gPaletteFade.mode == HARDWARE_FADE*/) {
|
||||
u16 bldAlpha = GetGpuReg(REG_OFFSET_BLDALPHA);
|
||||
u8 tgt1 = BLDALPHA_TGT1(bldAlpha);
|
||||
u8 tgt2 = BLDALPHA_TGT2(bldAlpha);
|
||||
u8 bldFade;
|
||||
|
||||
switch (gPaletteFade_blendCnt & BLDCNT_EFFECT_EFF_MASK)
|
||||
{
|
||||
// FADE_TO_BLACK
|
||||
case BLDCNT_EFFECT_DARKEN:
|
||||
bldFade = BLDALPHA_TGT1(max(0, 16 - gPaletteFade.y));
|
||||
SetGpuReg(
|
||||
REG_OFFSET_BLDALPHA,
|
||||
BLDALPHA_BLEND(min(tgt1, bldFade), min(tgt2, bldFade))
|
||||
);
|
||||
break;
|
||||
// FADE_TO_WHITE
|
||||
case BLDCNT_EFFECT_LIGHTEN:
|
||||
SetGpuReg(
|
||||
REG_OFFSET_BLDALPHA,
|
||||
BLDALPHA_BLEND(min(++tgt1, 31), min(++tgt2, 31))
|
||||
);
|
||||
// cause display to show white when finished
|
||||
// (otherwise blend-mode sprites will still be visible)
|
||||
if (gPaletteFade.hardwareFadeFinishing && gPaletteFade.y >= 16)
|
||||
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_FORCED_BLANK);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_FORCED_BLANK);
|
||||
|
||||
if (gPaletteFade.hardwareFadeFinishing)
|
||||
{
|
||||
gPaletteFade.hardwareFadeFinishing = FALSE;
|
||||
|
||||
17
src/scrcmd.c
17
src/scrcmd.c
@ -23,6 +23,7 @@
|
||||
#include "field_tasks.h"
|
||||
#include "field_weather.h"
|
||||
#include "fieldmap.h"
|
||||
#include "gpu_regs.h"
|
||||
#include "item.h"
|
||||
#include "lilycove_lady.h"
|
||||
#include "main.h"
|
||||
@ -661,19 +662,19 @@ bool8 ScrCmd_fadescreenswapbuffers(struct ScriptContext *ctx)
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case FADE_TO_BLACK:
|
||||
case FADE_TO_WHITE:
|
||||
default:
|
||||
CpuCopy32(gPlttBufferUnfaded, gPaletteDecompressionBuffer, PLTT_SIZE);
|
||||
FadeScreen(mode, 0);
|
||||
break;
|
||||
case FADE_FROM_BLACK:
|
||||
case FADE_FROM_WHITE:
|
||||
CpuCopy32(gPaletteDecompressionBuffer, gPlttBufferUnfaded, PLTT_SIZE);
|
||||
FadeScreen(mode, 0);
|
||||
// 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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user