Start of implementation for time of day filter.
This commit is contained in:
parent
12e3b4efad
commit
42d5fe07fa
17 changed files with 354 additions and 22 deletions
|
@ -6,3 +6,4 @@ gFieldCallback
|
|||
gFieldCallback2
|
||||
gLocalLinkPlayerId
|
||||
gFieldLinkPlayerCount
|
||||
gTimeOfDay
|
||||
|
|
Binary file not shown.
19
graphics/object_events/palettes/light.pal
Normal file
19
graphics/object_events/palettes/light.pal
Normal 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
|
BIN
graphics/object_events/pics/misc/light.png
Normal file
BIN
graphics/object_events/pics/misc/light.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3 KiB |
|
@ -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);
|
||||
|
|
|
@ -488,6 +488,8 @@ struct SaveBlock2
|
|||
|
||||
extern struct SaveBlock2 *gSaveBlock2Ptr;
|
||||
|
||||
extern u8 UpdateSpritePaletteWithTime(u8);
|
||||
|
||||
struct SecretBaseParty
|
||||
{
|
||||
u32 personality[PARTY_SIZE];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
141
src/palette.c
141
src/palette.c
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue