Start of implementation for time of day filter.

This commit is contained in:
Ariel Antonitis 2020-06-21 22:26:41 -04:00
parent 12e3b4efad
commit 42d5fe07fa
17 changed files with 354 additions and 22 deletions

View file

@ -6,3 +6,4 @@ gFieldCallback
gFieldCallback2
gLocalLinkPlayerId
gFieldLinkPlayerCount
gTimeOfDay

View file

@ -0,0 +1,19 @@
JASC-PAL
0100
16
110 198 165
255 213 18
255 214 38
254 217 39
254 218 53
255 220 65
255 221 76
255 223 86
254 225 95
254 228 104
254 229 112
254 230 120
255 232 132
255 235 148
255 237 162
255 240 176

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -98,6 +98,7 @@ void UpdateFollowingPokemon(void);
void RemoveFollowingPokemon(void);
struct ObjectEvent * GetFollowerObject(void);
u8 GetDirectionToFace(s16, s16, s16, s16);
void UpdateLightSprite(struct Sprite *);
void TrySpawnObjectEvents(s16, s16);
u8 CreateObjectSprite(u8 graphicsId, u8 a1, s16 x, s16 y, u8 z, u8 direction);
u8 AddPseudoObjectEvent(u16, void (*)(struct Sprite *), s16 x, s16 y, u8 subpriority);

View file

@ -488,6 +488,8 @@ struct SaveBlock2
extern struct SaveBlock2 *gSaveBlock2Ptr;
extern u8 UpdateSpritePaletteWithTime(u8);
struct SecretBaseParty
{
u32 personality[PARTY_SIZE];

View file

@ -25,6 +25,10 @@
#define MOVEMENT_MODE_SCRIPTED 2
#define SKIP_OBJECT_EVENT_LOAD 1
#define TIME_OF_DAY_NIGHT 0
#define TIME_OF_DAY_TWILIGHT 1
#define TIME_OF_DAY_DAY 2
#define TIME_OF_DAY_MAX TIME_OF_DAY_DAY
struct InitialPlayerAvatarState
{
@ -52,6 +56,7 @@ extern void (*gFieldCallback)(void);
extern bool8 (*gFieldCallback2)(void);
extern u8 gLocalLinkPlayerId;
extern u8 gFieldLinkPlayerCount;
extern u8 gTimeOfDay;
// Exported ROM declarations
extern const struct UCoords32 gDirectionToVectors[];
@ -130,6 +135,7 @@ void CleanupOverworldWindowsAndTilemaps(void);
bool32 IsUpdateLinkStateCBActive(void);
void CB1_Overworld(void);
void CB2_OverworldBasic(void);
void BlendPalettesWithTime(u32);
void CB2_Overworld(void);
void SetMainCallback1(void (*cb)(void));
void SetUnusedCallback(void *a0);

View file

@ -60,6 +60,7 @@ u8 UpdatePaletteFade(void);
void ResetPaletteFade(void);
void ReadPlttIntoBuffers(void);
bool8 BeginNormalPaletteFade(u32, s8, u8, u8, u16);
bool8 BeginTimeOfDayPaletteFade(u32, s8, u8, u8, u16);
bool8 unref_sub_8073D3C(u32, u8, u8, u8, u16);
void unref_sub_8073D84(u8, u32 *);
void ResetPaletteStructByUid(u16);

View file

@ -35,6 +35,7 @@ const struct SpriteTemplate gFieldEffectObjectTemplate_AshLaunch;
const struct SpriteTemplate gFieldEffectObjectTemplate_Bubbles;
const struct SpriteTemplate gFieldEffectObjectTemplate_SmallSparkle;
const struct SpriteTemplate gFieldEffectObjectTemplate_Rayquaza;
const struct SpriteTemplate gFieldEffectObjectTemplate_BallLight;
const struct SpriteTemplate *const gFieldEffectObjectTemplatePointers[] = {
[FLDEFFOBJ_SHADOW_S] = &gFieldEffectObjectTemplate_ShadowSmall,

View file

@ -28,6 +28,10 @@ static const struct SpriteFrameImage sPicTable_ShadowExtraLarge[] = {
obj_frame_tiles(gFieldEffectObjectPic_ShadowExtraLarge),
};
const struct SpriteFrameImage gFieldEffectObjectPicTable_BallLight[] = {
obj_frame_tiles(gFieldEffectObjectPic_BallLight),
};
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowSmall = {0xFFFF, OBJ_EVENT_PAL_TAG_MAY, &gObjectEventBaseOam_8x8, gFieldEffectObjectImageAnimTable_Shadow, gFieldEffectObjectPicTable_ShadowSmall, gDummySpriteAffineAnimTable, UpdateShadowFieldEffect};
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowMedium = {0xFFFF, OBJ_EVENT_PAL_TAG_MAY, &gObjectEventBaseOam_16x8, gFieldEffectObjectImageAnimTable_Shadow, gFieldEffectObjectPicTable_ShadowMedium, gDummySpriteAffineAnimTable, UpdateShadowFieldEffect};
@ -36,6 +40,8 @@ const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowLarge = {0xFFFF, OB
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowExtraLarge = {0xFFFF, OBJ_EVENT_PAL_TAG_MAY, &gObjectEventBaseOam_64x32, gFieldEffectObjectImageAnimTable_Shadow, gFieldEffectObjectPicTable_ShadowExtraLarge, gDummySpriteAffineAnimTable, UpdateShadowFieldEffect};
const struct SpriteTemplate gFieldEffectObjectTemplate_BallLight = {0xFFFF, OBJ_EVENT_PAL_TAG_LIGHT, &gObjectEventBaseOam_32x32, gObjectEventImageAnimTable_Inanimate, gFieldEffectObjectPicTable_BallLight, gDummySpriteAffineAnimTable, UpdateLightSprite};
static const struct SpriteFrameImage sPicTable_TallGrass[] = {
overworld_frame(gFieldEffectObjectPic_TallGrass, 2, 2, 0),
overworld_frame(gFieldEffectObjectPic_TallGrass, 2, 2, 1),

View file

@ -283,6 +283,7 @@ const u32 gFieldEffectObjectPic_ShadowSmall[] = INCBIN_U32("graphics/field_effec
const u32 gFieldEffectObjectPic_ShadowMedium[] = INCBIN_U32("graphics/field_effects/pics/shadow_medium.4bpp");
const u32 gFieldEffectObjectPic_ShadowLarge[] = INCBIN_U32("graphics/field_effects/pics/shadow_large.4bpp");
const u32 gFieldEffectObjectPic_ShadowExtraLarge[] = INCBIN_U32("graphics/field_effects/pics/shadow_extra_large.4bpp");
const u32 gFieldEffectObjectPic_BallLight[] = INCBIN_U32("graphics/object_events/pics/misc/light.4bpp");
static const u32 sFiller[0x48] = {};
const u8 gFieldEffectPic_CutGrass[] = INCBIN_U8("graphics/field_effects/pics/cut_grass.4bpp");
const u32 gFieldEffectPic_CutGrass_Copy[] = INCBIN_U32("graphics/field_effects/pics/cut_grass.4bpp");
@ -344,14 +345,7 @@ const u32 gObjectEventPic_Greta[] = INCBIN_U32("graphics/object_events/pics/peop
const u32 gObjectEventPic_Noland[] = INCBIN_U32("graphics/object_events/pics/people/frontier_brains/noland.4bpp");
const u32 gObjectEventPic_Lucy[] = INCBIN_U32("graphics/object_events/pics/people/frontier_brains/lucy.4bpp");
const u32 gObjectEventPic_Brandon[] = INCBIN_U32("graphics/object_events/pics/people/frontier_brains/brandon.4bpp");
<<<<<<< HEAD
const u32 gObjectEventPic_Lugia[] = INCBIN_U32("graphics/object_events/pics/pokemon/lugia.4bpp");
const u16 gObjectEventPal_Lugia[] = INCBIN_U16("graphics/object_events/palettes/lugia.gbapal");
const u32 gObjectEventPic_HoOh[] = INCBIN_U32("graphics/object_events/pics/pokemon/ho_oh.4bpp");
const u16 gObjectEventPal_HoOh[] = INCBIN_U16("graphics/object_events/palettes/ho_oh.gbapal");
=======
const u16 gObjectEventPalette32[] = INCBIN_U16("graphics/object_events/palettes/32.gbapal");
>>>>>>> e8c5f3ad6 (Added all 386 follower sprites.)
const u32 gObjectEventPic_AnimatedBall[] = INCBIN_U32("graphics/object_events/pics/misc/animated_ball.4bpp");
const u16 gObjectEventPalette31[] = INCBIN_U16("graphics/object_events/palettes/31.gbapal");
const u32 gObjectEventPic_Bulbasaur[] = INCBIN_U32("graphics/object_events/pics/pokemon/bulbasaur.4bpp");
@ -784,3 +778,4 @@ const u32 gObjectEventPic_LugiaOld[] = INCBIN_U32("graphics/object_events/pics/p
const u32 gObjectEventPic_HoOhOld[] = INCBIN_U32("graphics/object_events/pics/pokemon/ho_oh_old.4bpp");
const u32 gObjectEventPic_GroudonOld[] = INCBIN_U32("graphics/object_events/pics/pokemon/groudon_old.4bpp");
const u32 gObjectEventPic_KyogreOld[] = INCBIN_U32("graphics/object_events/pics/pokemon/kyogre_old.4bpp");
const u16 gObjectEventPaletteLight[] = INCBIN_U16("graphics/object_events/palettes/light.gbapal");

View file

@ -451,6 +451,7 @@ const u8 gInitialMovementTypeFacingDirections[] = {
#define OBJ_EVENT_PAL_TAG_RS_BRENDAN 0x1122
#define OBJ_EVENT_PAL_TAG_RS_MAY 0x1123
#define OBJ_EVENT_PAL_TAG_DYNAMIC 0x1124
#define OBJ_EVENT_PAL_TAG_LIGHT 0x8001
#define OBJ_EVENT_PAL_TAG_NONE 0x11FF
#include "data/object_events/object_event_graphics_info_pointers.h"
@ -498,6 +499,7 @@ static const struct SpritePalette sObjectEventSpritePalettes[] = {
{gObjectEventPal_RubySapphireBrendan, OBJ_EVENT_PAL_TAG_RS_BRENDAN},
{gObjectEventPal_RubySapphireMay, OBJ_EVENT_PAL_TAG_RS_MAY},
{gObjectEventPalette0, OBJ_EVENT_PAL_TAG_DYNAMIC},
{gObjectEventPaletteLight, OBJ_EVENT_PAL_TAG_LIGHT},
{NULL, 0x0000},
};
@ -1753,6 +1755,87 @@ bool8 ScrFunc_followerfly(struct ScriptContext *ctx) {
return FALSE;
}
// Callback for light sprites
void UpdateLightSprite(struct Sprite *sprite) {
s16 left = gSaveBlock1Ptr->pos.x - 2;
s16 right = gSaveBlock1Ptr->pos.x + 17;
s16 top = gSaveBlock1Ptr->pos.y;
s16 bottom = gSaveBlock1Ptr->pos.y + 15;
s16 x = sprite->data[6];
s16 y = sprite->data[7];
u16 sheetTileStart;
u32 paletteNum;
bool8 finished = TRUE;
// Ripped from RemoveObjectEventIfOutsideView
if (x >= left && x <= right
&& y >= top && y <= bottom)
finished = FALSE;
if (x >= left && x <= right
&& y >= top && y <= bottom)
finished = FALSE;
finished = finished ? finished : gTimeOfDay != TIME_OF_DAY_NIGHT;
if (finished) {
sheetTileStart = sprite->sheetTileStart;
paletteNum = sprite->oam.paletteNum;
DestroySprite(sprite);
FieldEffectFreeTilesIfUnused(sheetTileStart);
FieldEffectFreePaletteIfUnused(paletteNum);
return;
}
if (gPlayerAvatar.tileTransitionState) {
Weather_SetBlendCoeffs(7, 12);
sprite->invisible = FALSE;
} else {
Weather_SetBlendCoeffs(12, 12);
sprite->invisible = gSaveBlock2Ptr->playTimeVBlanks & 1;
}
}
// Spawn a light at a map coordinate based on metatile behavior
static void SpawnLightSprite(s16 x, s16 y, s16 camX, s16 camY, u32 behavior) {
struct Sprite *sprite;
u8 i;
for (i = 0; i < MAX_SPRITES; i++) {
sprite = &gSprites[i];
if (sprite->inUse && sprite->callback == UpdateLightSprite && sprite->data[6] == x && sprite->data[7] == y)
return;
}
sprite = &gSprites[CreateSprite(&gFieldEffectObjectTemplate_BallLight, 0, 0, 0)];
UpdateSpritePaletteByTemplate(&gFieldEffectObjectTemplate_BallLight, sprite);
sub_8092FF0(x + camX, y + camY, &sprite->pos1.x, &sprite->pos1.y);
sprite->data[6] = x;
sprite->data[7] = y;
sprite->affineAnims = gDummySpriteAffineAnimTable;
sprite->affineAnimBeginning = TRUE;
sprite->centerToCornerVecX = -(32 >> 1);
sprite->centerToCornerVecY = -(32 >> 1);
sprite->oam.priority = 1;
sprite->oam.objMode = 1; // BLEND
sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL;
sprite->coordOffsetEnabled = TRUE;
sprite->pos1.x += 8;
sprite->pos1.y += 22 + sprite->centerToCornerVecY;
}
void TrySpawnLightSprites(s16 camX, s16 camY) {
s16 left = gSaveBlock1Ptr->pos.x - 2;
s16 right = gSaveBlock1Ptr->pos.x + 17;
s16 top = gSaveBlock1Ptr->pos.y;
s16 bottom = gSaveBlock1Ptr->pos.y + 16;
s16 x, y;
u32 behavior;
if (gTimeOfDay != TIME_OF_DAY_NIGHT)
return;
for (x = left; x <= right; x++) {
for (y = top; y <= bottom; y++) {
behavior = MapGridGetMetatileBehaviorAt(x, y);
if (behavior == 0x04) // TODO: Use an actual constant
SpawnLightSprite(x, y, camX, camY, behavior);
}
}
}
void TrySpawnObjectEvents(s16 cameraX, s16 cameraY)
{
u8 i;
@ -1789,6 +1872,7 @@ void TrySpawnObjectEvents(s16 cameraX, s16 cameraY)
TrySpawnObjectEventTemplate(template, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, cameraX, cameraY);
}
}
TrySpawnLightSprites(cameraX, cameraY);
}
void RemoveObjectEventsOutsideView(void)
@ -1829,7 +1913,7 @@ static void RemoveObjectEventIfOutsideView(struct ObjectEvent *objectEvent)
RemoveObjectEvent(objectEvent);
}
void sub_808E16C(s16 x, s16 y)
void sub_808E16C(s16 x, s16 y) // Called when returning to field
{
u8 i;
@ -1842,6 +1926,7 @@ void sub_808E16C(s16 x, s16 y)
}
}
CreateReflectionEffectSprites();
TrySpawnLightSprites(x, y);
}
static void sub_808E1B8(u8 objectEventId, s16 x, s16 y)
@ -1934,7 +2019,13 @@ static u8 UpdateSpritePalette(const struct SpritePalette * spritePalette, struct
sprite->inUse = FALSE;
FieldEffectFreePaletteIfUnused(sprite->oam.paletteNum);
sprite->inUse = TRUE;
sprite->oam.paletteNum = LoadSpritePalette(spritePalette);
if (IndexOfSpritePaletteTag(spritePalette->tag) == 0xFF) {
sprite->oam.paletteNum = LoadSpritePalette(spritePalette);
UpdateSpritePaletteWithTime(sprite->oam.paletteNum);
} else {
sprite->oam.paletteNum = LoadSpritePalette(spritePalette);
}
return sprite->oam.paletteNum;
}
@ -2186,11 +2277,14 @@ void Unused_LoadObjectEventPaletteSet(u16 *paletteTags)
static u8 sub_808E8F4(const struct SpritePalette *spritePalette)
{
u8 paletteNum;
if (IndexOfSpritePaletteTag(spritePalette->tag) != 0xFF)
{
return 0xFF;
}
return LoadSpritePalette(spritePalette);
paletteNum = LoadSpritePalette(spritePalette);
UpdateSpritePaletteWithTime(paletteNum);
return paletteNum;
}
void PatchObjectPalette(u16 paletteTag, u8 paletteSlot)

View file

@ -146,11 +146,10 @@ static void LoadObjectRegularReflectionPalette(struct ObjectEvent *objectEvent,
}
paletteNum = LoadSpritePalette(&filteredPalette);
UpdateSpritePaletteWithWeather(paletteNum);
UpdateSpritePaletteWithTime(paletteNum);
}
sprite->oam.paletteNum = paletteNum;
// Apply alpha blending
// SetGpuReg(REG_OFFSET_BLDALPHA, sprite->data[7] == FALSE ? BLDALPHA_BLEND(8, 12) : BLDALPHA_BLEND(8, 8));
sprite->oam.objMode = 1; // BLEND
sprite->oam.objMode = 1; // Alpha blending
}
#define HIGH_BRIDGE_PAL_TAG 0x4010
@ -200,6 +199,7 @@ static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite)
}
paletteNum = LoadSpritePalette(&filteredPalette);
UpdateSpritePaletteWithWeather(paletteNum);
UpdateSpritePaletteWithTime(paletteNum);
}
reflectionSprite->oam.paletteNum = paletteNum;
}

View file

@ -254,6 +254,7 @@ static void Task_WeatherMain(u8 taskId)
static void None_Init(void)
{
Weather_SetBlendCoeffs(8, 12); // Indoor shadows
gWeatherPtr->gammaTargetIndex = 0;
gWeatherPtr->gammaStepDelay = 0;
}
@ -860,6 +861,7 @@ void LoadCustomWeatherSpritePalette(const u16 *palette)
{
LoadPalette(palette, 0x100 + gWeatherPtr->weatherPicSpritePalIndex * 16, 32);
UpdateSpritePaletteWithWeather(gWeatherPtr->weatherPicSpritePalIndex);
UpdateSpritePaletteWithTime(gWeatherPtr->weatherPicSpritePalIndex);
}
static void LoadDroughtWeatherPalette(u8 *gammaIndexPtr, u8 *a1)

View file

@ -478,7 +478,7 @@ void Rain_InitVars(void)
gWeatherPtr->rainSpriteVisibleDelay = 8;
gWeatherPtr->isDownpour = FALSE;
gWeatherPtr->targetRainSpriteCount = 10;
gWeatherPtr->gammaTargetIndex = 3;
gWeatherPtr->gammaTargetIndex = gTimeOfDay == TIME_OF_DAY_DAY ? 3 : 0;
gWeatherPtr->gammaStepDelay = 20;
SetRainStrengthFromSoundEffect(SE_RAIN);
}
@ -1020,7 +1020,7 @@ void Thunderstorm_InitVars(void)
gWeatherPtr->rainSpriteVisibleDelay = 4;
gWeatherPtr->isDownpour = FALSE;
gWeatherPtr->targetRainSpriteCount = 16;
gWeatherPtr->gammaTargetIndex = 3;
gWeatherPtr->gammaTargetIndex = gTimeOfDay == TIME_OF_DAY_DAY ? 3 : 0;
gWeatherPtr->gammaStepDelay = 20;
gWeatherPtr->weatherGfxLoaded = FALSE; // duplicate assignment
gWeatherPtr->thunderTriggered = 0;
@ -1116,6 +1116,8 @@ void Thunderstorm_Main(void)
if (--gWeatherPtr->unknown_6E6 == 0)
{
sub_80ABC48(3);
if (gTimeOfDay != TIME_OF_DAY_DAY)
BlendPalettesWithTime(0xFFFFFFFF);
gWeatherPtr->unknown_6EA = 1;
if (--gWeatherPtr->unknown_6EC != 0)
{
@ -1152,7 +1154,7 @@ void Thunderstorm_Main(void)
case 13:
if (--gWeatherPtr->unknown_6E6 == 0)
{
sub_80ABC7C(19, 3, 5);
gTimeOfDay == TIME_OF_DAY_DAY ? sub_80ABC7C(19, 3, 5) : BlendPalettesWithTime(0xFFFFFFFF);
gWeatherPtr->initStep++;
}
break;

View file

@ -42,6 +42,7 @@
#include "random.h"
#include "roamer.h"
#include "rotating_gate.h"
#include "rtc.h"
#include "safari_zone.h"
#include "save.h"
#include "save_location.h"
@ -175,6 +176,8 @@ static u16 (*sPlayerKeyInterceptCallback)(u32);
static bool8 sUnknown_03000E18;
static u8 sRfuKeepAliveTimer;
u8 static gTimeOfDayState;
// IWRAM common
u16 *gBGTilemapBuffers1;
u16 *gBGTilemapBuffers2;
@ -185,6 +188,8 @@ bool8 (*gFieldCallback2)(void);
u8 gLocalLinkPlayerId; // This is our player id in a multiplayer mode.
u8 gFieldLinkPlayerCount;
u8 gTimeOfDay;
// EWRAM vars
EWRAM_DATA static u8 sObjectEventLoadFlag = 0;
EWRAM_DATA struct WarpData gLastUsedWarp = {0};
@ -197,6 +202,7 @@ EWRAM_DATA static u16 sAmbientCrySpecies = 0;
EWRAM_DATA static bool8 sIsAmbientCryWaterMon = FALSE;
EWRAM_DATA struct LinkPlayerObjectEvent gLinkPlayerObjectEvents[4] = {0};
// const rom data
static const struct WarpData sDummyWarpData =
{
@ -811,6 +817,7 @@ void LoadMapFromCameraTransition(u8 mapGroup, u8 mapNum)
RoamerMove();
DoCurrentWeather();
ResetFieldTasksArgs();
BlendPalettesWithTime(0xFFFFFFFF);
RunOnResumeMapScript();
if (gMapHeader.regionMapSectionId != MAPSEC_BATTLE_FRONTIER
@ -1442,6 +1449,59 @@ void CB1_Overworld(void)
DoCB1_Overworld(gMain.newKeys, gMain.heldKeys);
}
struct TimeOfDayBlend {
u8 coeff:4;
u16 blendColor;
};
static const struct TimeOfDayBlend sTimeOfDayBlendVars[] =
{
[TIME_OF_DAY_NIGHT] = {.coeff = 10, .blendColor = 0x1400},
[TIME_OF_DAY_TWILIGHT] = {.coeff = 4, .blendColor = 0x155D},
[TIME_OF_DAY_DAY] = {.coeff = 0, .blendColor = 0},
};
u8 UpdateTimeOfDay(void) {
RtcCalcLocalTime();
if (gLocalTime.hours >= 20 || gLocalTime.hours < 4)
return gTimeOfDay = TIME_OF_DAY_NIGHT;
else if (gLocalTime.hours >= 10 && gLocalTime.hours < 20)
return gTimeOfDay = TIME_OF_DAY_DAY;
return gTimeOfDay = TIME_OF_DAY_TWILIGHT;
}
static bool8 MapHasNaturalLight(u8 mapType) { // Weather a map type is naturally lit/outside
return mapType == MAP_TYPE_TOWN || mapType == MAP_TYPE_CITY || mapType == MAP_TYPE_ROUTE;
}
static bool8 FadePalettesWithTime(void) {
gTimeOfDayState = 0;
gTimeOfDay = UpdateTimeOfDay();
if (MapHasNaturalLight(gMapHeader.mapType)) {
ResetPaletteFade();
BeginTimeOfDayPaletteFade(0xFFFFFFFF, 0, 16, sTimeOfDayBlendVars[gTimeOfDay].coeff, sTimeOfDayBlendVars[gTimeOfDay].blendColor);
}
}
void BlendPalettesWithTime(u32 palettes) {
// Only blend if not transitioning between times and the map type allows
if (gTimeOfDayState == 0 && MapHasNaturalLight(gMapHeader.mapType)) {
u8 i;
for (i = 0; i < 16; i++) {
if (GetSpritePaletteTagByPaletteNum(i) & 0x8000) // Don't blend special sprite palette tags
palettes &= ~(1 << (i + 16));
}
palettes &= ~0xE000; // Don't blend tile palettes [13,15]
gTimeOfDay = gTimeOfDay > TIME_OF_DAY_MAX ? TIME_OF_DAY_MAX : gTimeOfDay;
BlendPalettes(palettes, sTimeOfDayBlendVars[gTimeOfDay].coeff, sTimeOfDayBlendVars[gTimeOfDay].blendColor);
}
}
u8 UpdateSpritePaletteWithTime(u8 paletteNum) {
BlendPalettesWithTime(1 << (paletteNum + 16));
return paletteNum;
}
static void OverworldBasic(void)
{
ScriptContext2_RunScript();
@ -1463,12 +1523,16 @@ void CB2_OverworldBasic(void)
void CB2_Overworld(void)
{
u32 *debugPtr = (u32*) 0x0203de00;
bool32 fading = (gPaletteFade.active != 0);
*debugPtr = (u32) &gTimeOfDay;
if (fading)
SetVBlankCallback(NULL);
OverworldBasic();
if (fading)
SetFieldVBlankCallback();
if (fading) {
SetFieldVBlankCallback();
return;
}
}
void SetMainCallback1(MainCallback cb)
@ -1564,6 +1628,7 @@ static void CB2_LoadMap2(void)
DoMapLoadLoop(&gMain.state);
SetFieldVBlankCallback();
SetMainCallback1(CB1_Overworld);
FadePalettesWithTime();
SetMainCallback2(CB2_Overworld);
}
@ -1620,6 +1685,7 @@ static void CB2_ReturnToFieldLocal(void)
if (ReturnToFieldLocal(&gMain.state))
{
SetFieldVBlankCallback();
FadePalettesWithTime();
SetMainCallback2(CB2_Overworld);
}
}
@ -1966,7 +2032,6 @@ static bool32 ReturnToFieldLocal(u8 *state)
case 3:
return TRUE;
}
return FALSE;
}

View file

@ -11,6 +11,7 @@ enum
NORMAL_FADE,
FAST_FADE,
HARDWARE_FADE,
TIME_OF_DAY_FADE,
};
// These are structs for some unused palette system.
@ -50,6 +51,7 @@ static u8 UpdateNormalPaletteFade(void);
static void BeginFastPaletteFadeInternal(u8);
static u8 UpdateFastPaletteFade(void);
static u8 UpdateHardwarePaletteFade(void);
static u8 UpdateTimeOfDayPaletteFade(void);
static void UpdateBlendRegisters(void);
static bool8 IsSoftwarePaletteFadeFinishing(void);
static void Task_BlendPalettesGradually(u8 taskId);
@ -123,6 +125,8 @@ u8 UpdatePaletteFade(void)
result = UpdateNormalPaletteFade();
else if (gPaletteFade.mode == FAST_FADE)
result = UpdateFastPaletteFade();
else if (gPaletteFade.mode == TIME_OF_DAY_FADE)
result = UpdateTimeOfDayPaletteFade();
else
result = UpdateHardwarePaletteFade();
@ -199,6 +203,53 @@ bool8 BeginNormalPaletteFade(u32 selectedPalettes, s8 delay, u8 startY, u8 targe
}
}
// Like normal palette fade but respects sprite/tile palettes immune to time of day fading
bool8 BeginTimeOfDayPaletteFade(u32 selectedPalettes, s8 delay, u8 startY, u8 targetY, u16 blendColor)
{
u8 temp;
u16 color = blendColor;
if (gPaletteFade.active)
{
return FALSE;
}
else
{
gPaletteFade.deltaY = 2;
if (delay < 0)
{
gPaletteFade.deltaY += (delay * -1);
delay = 0;
}
gPaletteFade_selectedPalettes = selectedPalettes;
gPaletteFade.delayCounter = delay;
gPaletteFade_delay = delay;
gPaletteFade.y = startY;
gPaletteFade.targetY = targetY;
gPaletteFade.blendColor = color;
gPaletteFade.active = 1;
gPaletteFade.mode = TIME_OF_DAY_FADE;
if (startY < targetY)
gPaletteFade.yDec = 0;
else
gPaletteFade.yDec = 1;
UpdatePaletteFade();
temp = gPaletteFade.bufferTransferDisabled;
gPaletteFade.bufferTransferDisabled = 0;
CpuCopy32(gPlttBufferFaded, (void *)PLTT, PLTT_SIZE);
sPlttBufferTransferPending = 0;
if (gPaletteFade.mode == HARDWARE_FADE && gPaletteFade.active)
UpdateBlendRegisters();
gPaletteFade.bufferTransferDisabled = temp;
return TRUE;
}
}
bool8 unref_sub_80A1C1C(u32 a1, u8 a2, u8 a3, u8 a4, u16 a5)
{
ReadPlttIntoBuffers();
@ -405,6 +456,94 @@ static u8 GetPaletteNumByUid(u16 uid)
return 16;
}
// Like normal palette fade, but respects sprite/tile palettes immune to time of day fading
static u8 UpdateTimeOfDayPaletteFade(void) // Like normal, but respects sprite palettes immune to fading
{
u8 paletteNum;
u16 paletteOffset;
u16 selectedPalettes;
if (!gPaletteFade.active)
return PALETTE_FADE_STATUS_DONE;
if (IsSoftwarePaletteFadeFinishing())
return gPaletteFade.active ? PALETTE_FADE_STATUS_ACTIVE : PALETTE_FADE_STATUS_DONE;
if (!gPaletteFade.objPaletteToggle)
{
if (gPaletteFade.delayCounter < gPaletteFade_delay)
{
gPaletteFade.delayCounter++;
return 2;
}
gPaletteFade.delayCounter = 0;
}
paletteOffset = 0;
if (!gPaletteFade.objPaletteToggle)
{
selectedPalettes = gPaletteFade_selectedPalettes;
}
else
{
selectedPalettes = gPaletteFade_selectedPalettes >> 16;
paletteOffset = 256;
}
for (paletteNum = 0; paletteNum < 16; paletteNum++, selectedPalettes >>= 1, paletteOffset += 16) {
if (selectedPalettes & 1) {
if (gPaletteFade.yDec) {
if (gPaletteFade.objPaletteToggle) { // sprite palettes
if (gPaletteFade.y >= gPaletteFade.targetY || GetSpritePaletteTagByPaletteNum(paletteNum) & 0x8000)
BlendPalette(paletteOffset, 16, gPaletteFade.y, gPaletteFade.blendColor);
// tile palettes
} else if (gPaletteFade.y >= gPaletteFade.targetY || (paletteNum >= 13 && paletteNum <= 15)) {
BlendPalette(paletteOffset, 16, gPaletteFade.y, gPaletteFade.blendColor);
}
} else {
BlendPalette(paletteOffset, 16, gPaletteFade.y, gPaletteFade.blendColor);
}
}
}
gPaletteFade.objPaletteToggle ^= 1;
if (!gPaletteFade.objPaletteToggle)
{
if ((gPaletteFade.yDec && gPaletteFade.y == 0) || (!gPaletteFade.yDec && gPaletteFade.y == gPaletteFade.targetY))
{
gPaletteFade_selectedPalettes = 0;
gPaletteFade.softwareFadeFinishing = 1;
}
else
{
s8 val;
if (!gPaletteFade.yDec)
{
val = gPaletteFade.y;
val += gPaletteFade.deltaY;
if (val > gPaletteFade.targetY)
val = gPaletteFade.targetY;
gPaletteFade.y = val;
}
else
{
val = gPaletteFade.y;
val -= gPaletteFade.deltaY;
if (val < 0)
val = 0;
gPaletteFade.y = val;
}
}
}
// gPaletteFade.active cannot change since the last time it was checked. So this
// is equivalent to `return PALETTE_FADE_STATUS_ACTIVE;`
return PALETTE_FADE_STATUS_ACTIVE;
}
static u8 UpdateNormalPaletteFade(void)
{
u16 paletteOffset;
@ -587,7 +726,6 @@ static u8 UpdateFastPaletteFade(void)
if (IsSoftwarePaletteFadeFinishing())
return gPaletteFade.active ? PALETTE_FADE_STATUS_ACTIVE : PALETTE_FADE_STATUS_DONE;
if (gPaletteFade.objPaletteToggle)
{
paletteOffsetStart = 256;
@ -721,7 +859,6 @@ static u8 UpdateFastPaletteFade(void)
gPaletteFade.mode = NORMAL_FADE;
gPaletteFade.softwareFadeFinishing = 1;
}
// gPaletteFade.active cannot change since the last time it was checked. So this
// is equivalent to `return PALETTE_FADE_STATUS_ACTIVE;`
return gPaletteFade.active ? PALETTE_FADE_STATUS_ACTIVE : PALETTE_FADE_STATUS_DONE;