mirror of
https://github.com/pret/pokeemerald.git
synced 2026-09-30 05:53:57 -05:00
Integrated merrp's lighting branch (Day/Night System) (#6562)
This commit is contained in:
@@ -1790,11 +1790,14 @@
|
||||
.4byte \text
|
||||
.endm
|
||||
|
||||
@ Equivalent to fadescreen but copies gPlttBufferUnfaded to an allocated buffer on the fade out
|
||||
@ and the reverse on the fade in, in effect saving gPlttBufferUnfaded to restore it.
|
||||
.macro fadescreenswapbuffers mode:req
|
||||
@ 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
|
||||
.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
|
||||
|
||||
@@ -760,12 +760,12 @@ Common_EventScript_PlayGymBadgeFanfare::
|
||||
return
|
||||
|
||||
Common_EventScript_OutOfCenterPartyHeal::
|
||||
fadescreen FADE_TO_BLACK
|
||||
fadescreenswapbuffers FADE_TO_BLACK
|
||||
playfanfare MUS_HEAL
|
||||
waitfanfare
|
||||
special HealPlayerParty
|
||||
callnative UpdateFollowingPokemon
|
||||
fadescreen FADE_FROM_BLACK
|
||||
fadescreenswapbuffers FADE_FROM_BLACK
|
||||
return
|
||||
|
||||
EventScript_RegionMap::
|
||||
|
||||
@@ -476,6 +476,7 @@ BattleFrontier_BattleDomeBattleRoom_EventScript_SetUpObjects::
|
||||
call BattleFrontier_EventScript_SetBrainObjectGfx
|
||||
setobjectxyperm LOCALID_OPPONENT, 13, 9
|
||||
removeobject LOCALID_OPPONENT
|
||||
delay 1
|
||||
addobject LOCALID_OPPONENT
|
||||
applymovement LOCALID_OPPONENT, BattleFrontier_BattleDomeBattleRoom_Movement_SetInvisibleFacingUp
|
||||
BattleFrontier_BattleDomeBattleRoom_EventScript_EndSetUpObjects::
|
||||
|
||||
@@ -54,13 +54,13 @@ MtChimney_EventScript_Maxie::
|
||||
msgbox MtChimney_Text_MaxieYouHaventSeenLastOfMagma, MSGBOX_DEFAULT
|
||||
closemessage
|
||||
delay 30
|
||||
fadescreen FADE_TO_BLACK
|
||||
fadescreenswapbuffers FADE_TO_BLACK
|
||||
removeobject LOCALID_MAXIE
|
||||
removeobject LOCALID_MAGMA_GRUNT_1
|
||||
removeobject LOCALID_TABITHA
|
||||
removeobject LOCALID_MAGMA_GRUNT_2
|
||||
setflag FLAG_HIDE_MT_CHIMNEY_TEAM_MAGMA
|
||||
fadescreen FADE_FROM_BLACK
|
||||
fadescreenswapbuffers FADE_FROM_BLACK
|
||||
setobjectxyperm LOCALID_ARCHIE, 10, 12
|
||||
addobject LOCALID_ARCHIE
|
||||
call_if_eq VAR_FACING, DIR_EAST, MtChimney_EventScript_ArchieApproachPlayerEast
|
||||
|
||||
@@ -49,7 +49,7 @@ MtPyre_Summit_EventScript_TeamAquaExits::
|
||||
call_if_eq VAR_0x8008, 2, MtPyre_Summit_EventScript_ArchieFacePlayer2
|
||||
msgbox MtPyre_Summit_Text_ArchieWeGotTheOrbLetsGo, MSGBOX_DEFAULT
|
||||
closemessage
|
||||
fadescreen FADE_TO_BLACK
|
||||
fadescreenswapbuffers FADE_TO_BLACK
|
||||
removeobject LOCALID_ARCHIE
|
||||
removeobject LOCALID_GRUNT_1
|
||||
removeobject LOCALID_GRUNT_2
|
||||
@@ -58,7 +58,7 @@ MtPyre_Summit_EventScript_TeamAquaExits::
|
||||
setflag FLAG_HIDE_MT_PYRE_SUMMIT_ARCHIE
|
||||
setflag FLAG_HIDE_MT_PYRE_SUMMIT_TEAM_AQUA
|
||||
fadedefaultbgm
|
||||
fadescreen FADE_FROM_BLACK
|
||||
fadescreenswapbuffers FADE_FROM_BLACK
|
||||
delay 20
|
||||
setvar VAR_MT_PYRE_STATE, 1
|
||||
call_if_eq VAR_0x8008, 0, MtPyre_Summit_EventScript_OldLadyApproachPlayer0
|
||||
|
||||
@@ -48,6 +48,7 @@ SlateportCity_BattleTentBattleRoom_EventScript_EnterRoom::
|
||||
factory_setopponentgfx
|
||||
setobjectxyperm LOCALID_OPPONENT, 5, 1
|
||||
removeobject LOCALID_OPPONENT
|
||||
delay 1
|
||||
addobject LOCALID_OPPONENT
|
||||
applymovement LOCALID_OPPONENT, SlateportCity_BattleTentBattleRoom_Movement_OpponentEnter
|
||||
waitmovement 0
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
- [v1.6.x and earlier](tutorials/how_to_new_pokemon_1_6_0.md)
|
||||
- [How to use the Testing System](tutorials/how_to_testing_system.md)
|
||||
- [How to add new Trainer Slides](tutorials/how_to_new_trainer_slide.md)
|
||||
- [Day/Night System FAQ](tutorials/dns.md)
|
||||
- [Changelog](./CHANGELOG.md)
|
||||
- [1.11.x]()
|
||||
- [Version 1.11.1](changelogs/1.11.x/1.11.1.md)
|
||||
|
||||
25
docs/tutorials/dns.md
Normal file
25
docs/tutorials/dns.md
Normal file
@@ -0,0 +1,25 @@
|
||||
## Day/Night system FAQ
|
||||
|
||||
### Q: How do I disable DNS?
|
||||
A: Set `OW_ENABLE_DNS` to `FALSE` in `include/config/overworld.h`.
|
||||
|
||||
### Q: How do I mark certain colors in a palette as light-blended?
|
||||
A: Create a `.pla` file in the same folder as the `.pal` with the same name.
|
||||
|
||||
In this file you can enter color indices [0,15]
|
||||
on separate lines to mark those colors as being light-blended, i.e:
|
||||
|
||||
`06.pla:`
|
||||
```
|
||||
# A comment
|
||||
0 # if color 0 is listed, uses it to blend with instead of the default!
|
||||
1
|
||||
9
|
||||
10
|
||||
```
|
||||
|
||||
### Q: How do I return to using regular shadows?
|
||||
A: Set `OW_OBJECT_VANILLA_SHADOWS` to `TRUE` in `include/config/overworld.h`.
|
||||
|
||||
### Q: How do I disable shadows for certain locations?
|
||||
A: Shadows can be disabled for certain locations by modifying the `CurrentMapHasShadows` function in `src/overworld.c`.
|
||||
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
|
||||
64 61 42
|
||||
77 73 50
|
||||
85 81 58
|
||||
100 94 66
|
||||
111 105 75
|
||||
119 112 77
|
||||
140 131 92
|
||||
154 145 103
|
||||
171 159 111
|
||||
186 174 123
|
||||
197 183 128
|
||||
209 195 139
|
||||
224 209 146
|
||||
234 219 155
|
||||
249 232 161
|
||||
19
graphics/object_events/palettes/light2.pal
Normal file
19
graphics/object_events/palettes/light2.pal
Normal file
@@ -0,0 +1,19 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
106 202 166
|
||||
58 54 31
|
||||
67 62 33
|
||||
96 89 53
|
||||
110 102 57
|
||||
121 111 67
|
||||
128 119 66
|
||||
156 143 82
|
||||
166 155 96
|
||||
185 169 100
|
||||
199 183 112
|
||||
211 192 113
|
||||
223 203 123
|
||||
237 218 129
|
||||
247 227 137
|
||||
255 237 147
|
||||
19
graphics/object_events/palettes/neon_light.pal
Normal file
19
graphics/object_events/palettes/neon_light.pal
Normal file
@@ -0,0 +1,19 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
104 203 168
|
||||
19 48 64
|
||||
35 87 115
|
||||
58 132 140
|
||||
69 156 166
|
||||
77 193 254
|
||||
106 239 254
|
||||
27 68 89
|
||||
64 22 19
|
||||
115 39 34
|
||||
166 57 49
|
||||
191 66 57
|
||||
222 77 67
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 6.1 KiB |
BIN
graphics/object_events/pics/misc/mart_light.png
Normal file
BIN
graphics/object_events/pics/misc/mart_light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
BIN
graphics/object_events/pics/misc/poke_center_light.png
Normal file
BIN
graphics/object_events/pics/misc/poke_center_light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
@@ -5,5 +5,6 @@
|
||||
|
||||
void InitTimeBasedEvents(void);
|
||||
void DoTimeBasedEvents(void);
|
||||
void FormChangeTimeUpdate();
|
||||
|
||||
#endif // GUARD_CLOCK_H
|
||||
|
||||
@@ -62,31 +62,13 @@
|
||||
#define OW_FOLLOWERS_COPY_WILD_PKMN FALSE // If TRUE, follower Pokémon that know Transform or have Illusion/Imposter will copy wild Pokémon at random.
|
||||
#define OW_BATTLE_ONLY_FORMS TRUE // If TRUE, loads overworld sprites for battle-only forms like Mega Evos. Requires OW_POKEMON_OBJECT_EVENTS.
|
||||
#define B_FLAG_FOLLOWERS_DISABLED 0 // Enables / Disables followers by using a flag. Helpful to disable followers for a period of time.
|
||||
|
||||
|
||||
#define OW_FOLLOWERS_SCRIPT_MOVEMENT TRUE // TRUE: Script collisions hide follower, FLAG_SAFE_FOLLOWER_MOVEMENT on by default
|
||||
// FALSE: Script collisions unhandled, FLAG_SAFE_FOLLOWER_MOVEMENT off by default
|
||||
|
||||
// If set, the only pokemon allowed to follow you
|
||||
// will be those matching species, met location,
|
||||
// and/or met level;
|
||||
// These accept vars, too: VAR_TEMP_1, etc
|
||||
#define OW_MON_ALLOWED_SPECIES (0)
|
||||
#define OW_MON_ALLOWED_MET_LVL (0)
|
||||
#define OW_MON_ALLOWED_MET_LOC (0)
|
||||
// Examples:
|
||||
// Yellow Pikachu:
|
||||
// #define OW_MON_ALLOWED_SPECIES (SPECIES_PIKACHU)
|
||||
// #define OW_MON_ALLOWED_MET_LVL (0)
|
||||
// #define OW_MON_ALLOWED_MET_LOC (MAPSEC_PALLET_TOWN)
|
||||
// Hoenn Starter:
|
||||
// #define OW_MON_ALLOWED_SPECIES (0)
|
||||
// #define OW_MON_ALLOWED_MET_LVL (5)
|
||||
// #define OW_MON_ALLOWED_MET_LOC (MAPSEC_ROUTE_101)
|
||||
// Species set in VAR_XXXX:
|
||||
// #define OW_MON_ALLOWED_SPECIES (VAR_XXXX)
|
||||
// #define OW_MON_ALLOWED_MET_LVL (0)
|
||||
// #define OW_MON_ALLOWED_MET_LOC (0)
|
||||
#define OW_FOLLOWERS_SCRIPT_MOVEMENT TRUE // If TRUE, follower Pokémon only go back to their Poké Ball if a non-player collides with them by setting the FLAG_SAFE_FOLLOWER_MOVEMENT flag by default.
|
||||
// Follower Pokémon Restrictions
|
||||
// If set, the only pokemon allowed to follow you will be those matching species, met location, and/or met level; These accept vars, too: VAR_TEMP_1, etc
|
||||
// For examples, see "docs/tutorials/how_to_new_pokemon.md"
|
||||
#define OW_FOLLOWERS_ALLOWED_SPECIES (0)
|
||||
#define OW_FOLLOWERS_ALLOWED_MET_LVL (0)
|
||||
#define OW_FOLLOWERS_ALLOWED_MET_LOC (0)
|
||||
|
||||
// Out-of-battle Ability effects
|
||||
#define OW_SYNCHRONIZE_NATURE GEN_LATEST // In Gen8+, if a Pokémon with Synchronize leads the party, wild Pokémon will always have their same Nature as opposed to the 50% chance in previous games. Gift Pokémon excluded.
|
||||
@@ -111,6 +93,14 @@
|
||||
#define OW_TIME_OF_DAY_DEFAULT TIME_MORNING // Should be set to whatever is the first value in the TimeOfDay enum in rtc.h
|
||||
#define OW_TIME_OF_DAY_FALLBACK OW_TIME_OF_DAY_DEFAULT // The time of day that encounter tables fall back to. Defaults to whatever OW_TIME_OF_DAY_FALLBACK is set to.
|
||||
|
||||
// Lighting
|
||||
#define OW_SHADOW_INTENSITY 4 // Ranges from 0 to 16, where 0 is fully transparent and 16 is black.
|
||||
#define OW_OBJECT_SUBPRIORITY 148 // The higher the value, the farther back compared to other sprites. Shadows should be behind object events.
|
||||
#define OW_ENABLE_DNS TRUE // If set to TRUE, the overworld will be tinted depending on time of day.
|
||||
|
||||
// Object Event Shadows
|
||||
#define OW_OBJECT_VANILLA_SHADOWS FALSE // In vanilla shadows in the overworld are only shown when jumping.
|
||||
|
||||
// Overworld flags
|
||||
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to.
|
||||
// Eg: Replace with FLAG_UNUSED_0x264 so you can use that flag to toggle the feature.
|
||||
|
||||
@@ -242,11 +242,12 @@
|
||||
#define OBJ_EVENT_GFX_HOOH 238
|
||||
#define OBJ_EVENT_GFX_POKE_BALL 239
|
||||
#define OBJ_EVENT_GFX_OW_MON 240
|
||||
#define OBJ_EVENT_GFX_LIGHT_SPRITE 241
|
||||
|
||||
// NOTE: The maximum amount of object events has been expanded from 255 to 65535.
|
||||
// Since dynamic graphics ids still require at least 16 free values, the actual limit
|
||||
// is 65519, but even considering follower Pokémon, this should be more than enough :)
|
||||
#define NUM_OBJ_EVENT_GFX 241
|
||||
#define NUM_OBJ_EVENT_GFX 242
|
||||
|
||||
|
||||
// These are dynamic object gfx ids.
|
||||
@@ -270,6 +271,7 @@
|
||||
#define OBJ_EVENT_GFX_VAR_E (OBJ_EVENT_GFX_VARS + 0xE)
|
||||
#define OBJ_EVENT_GFX_VAR_F (OBJ_EVENT_GFX_VARS + 0xF)
|
||||
|
||||
// Don't use (1u << 15) to avoid conflict with BLEND_IMMUNE_FLAG.
|
||||
#define OBJ_EVENT_MON (1u << 14)
|
||||
#define OBJ_EVENT_MON_SHINY (1u << 13)
|
||||
#define OBJ_EVENT_MON_FEMALE (1u << 12)
|
||||
@@ -305,12 +307,19 @@
|
||||
#define TRACKS_SPOT 4
|
||||
#define TRACKS_BUG 5
|
||||
|
||||
#define LIGHT_TYPE_BALL 0
|
||||
#define LIGHT_TYPE_PKMN_CENTER_SIGN 1
|
||||
#define LIGHT_TYPE_POKE_MART_SIGN 2
|
||||
|
||||
#define FIRST_DECORATION_SPRITE_GFX OBJ_EVENT_GFX_PICHU_DOLL
|
||||
|
||||
#define OBJ_KIND_NORMAL 0
|
||||
#define OBJ_KIND_CLONE 255 // Exclusive to FRLG
|
||||
|
||||
// Special object event local ids
|
||||
// Used for link player OWs in CreateLinkPlayerSprite
|
||||
#define OBJ_EVENT_ID_DYNAMIC_BASE 0xF0
|
||||
|
||||
#define OBJ_EVENT_ID_PLAYER 0xFF
|
||||
#define OBJ_EVENT_ID_CAMERA 0x7F
|
||||
#define OBJ_EVENT_ID_FOLLOWER 0xFE
|
||||
@@ -421,7 +430,10 @@
|
||||
#endif //OW_FOLLOWERS_POKEBALLS
|
||||
// Used as a placeholder follower graphic
|
||||
#define OBJ_EVENT_PAL_TAG_SUBSTITUTE 0x7611
|
||||
#define OBJ_EVENT_PAL_TAG_EMOTES 0x8002
|
||||
#define OBJ_EVENT_PAL_TAG_LIGHT 0x8001
|
||||
#define OBJ_EVENT_PAL_TAG_LIGHT_2 0x8002
|
||||
#define OBJ_EVENT_PAL_TAG_EMOTES 0x8003
|
||||
#define OBJ_EVENT_PAL_TAG_NEON_LIGHT 0x8004
|
||||
// Not a real OW palette tag; used for the white flash applied to followers
|
||||
#define OBJ_EVENT_PAL_TAG_WHITE (OBJ_EVENT_PAL_TAG_NONE - 1)
|
||||
#define OBJ_EVENT_PAL_TAG_NONE 0x11FF
|
||||
|
||||
@@ -133,5 +133,12 @@
|
||||
#define FLDEFF_PAL_TAG_HOF_MONITOR 0x1010
|
||||
#define FLDEFF_PAL_TAG_UNKNOWN 0x1011
|
||||
#define FLDEFF_PAL_TAG_CAVE_DUST 0x1012
|
||||
#define FLDEFF_PAL_TAG_FIELD_MOVE_MON 0x8400
|
||||
|
||||
// tile tags, for field effects that may have many copies on screen at once
|
||||
#define FLDEFF_TILE_TAG_SHADOW_SMALL 0x1400
|
||||
#define FLDEFF_TILE_TAG_SHADOW_MEDIUM 0x1401
|
||||
#define FLDEFF_TILE_TAG_SHADOW_LARGE 0x1402
|
||||
#define FLDEFF_TILE_TAG_SHADOW_EXTRA_LARGE 0x1403
|
||||
|
||||
#endif // GUARD_FIELD_EFFECT_CONSTANTS_H
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
#ifndef GUARD_CONSTANTS_FIELD_WEATHER_H
|
||||
#define GUARD_CONSTANTS_FIELD_WEATHER_H
|
||||
|
||||
#include "config/overworld.h"
|
||||
|
||||
// sPaletteColorMapTypes & field_effect_scripts
|
||||
enum ColorMapType
|
||||
{
|
||||
COLOR_MAP_NONE,
|
||||
COLOR_MAP_DARK_CONTRAST,
|
||||
COLOR_MAP_CONTRAST,
|
||||
};
|
||||
|
||||
#define MAX_RAIN_SPRITES 24
|
||||
#define NUM_CLOUD_SPRITES 3
|
||||
#define NUM_FOG_HORIZONTAL_SPRITES 20
|
||||
@@ -22,4 +32,8 @@
|
||||
#define FADE_FROM_WHITE 2
|
||||
#define FADE_TO_WHITE 3
|
||||
|
||||
// Shadows values
|
||||
#define BASE_SHADOW_INTENSITY (16 - OW_SHADOW_INTENSITY)
|
||||
#define SHADOW_COLOR_INDEX 9 // Within the weather palette, shadow sprites' color index
|
||||
|
||||
#endif // GUARD_CONSTANTS_FIELD_WEATHER_H
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#define RGB_BLACK RGB(0, 0, 0)
|
||||
#define RGB_WHITE RGB(31, 31, 31)
|
||||
#define RGB_GRAY RGB(15, 15, 15)
|
||||
#define RGB_RED RGB(31, 0, 0)
|
||||
#define RGB_GREEN RGB(0, 31, 0)
|
||||
#define RGB_BLUE RGB(0, 0, 31)
|
||||
|
||||
@@ -145,13 +145,17 @@ u16 GetOverworldWeatherSpecies(u16 species);
|
||||
void UpdateFollowingPokemon(void);
|
||||
void RemoveFollowingPokemon(void);
|
||||
struct ObjectEvent *GetFollowerObject(void);
|
||||
u8 GetDirectionToFace(s16, s16, s16, s16);
|
||||
void UpdateLightSprite(struct Sprite *);
|
||||
void TrySpawnObjectEvents(s16 cameraX, s16 cameraY);
|
||||
u8 CreateObjectGraphicsSpriteWithTag(u16 graphicsId, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u16 paletteTag);
|
||||
u8 CreateObjectGraphicsSprite(u16, void (*)(struct Sprite *), s16 x, s16 y, u8 subpriority);
|
||||
u8 TrySpawnObjectEvent(u8 localId, u8 mapNum, u8 mapGroup);
|
||||
u8 SpawnSpecialObjectEventParameterized(u16 graphicsId, u8 movementBehavior, u8 localId, s16 x, s16 y, u8 elevation);
|
||||
u8 SpawnSpecialObjectEvent(struct ObjectEventTemplate *);
|
||||
void SetSpritePosToMapCoords(s16 mapX, s16 mapY, s16 *destX, s16 *destY);
|
||||
void CameraObjectReset(void);
|
||||
u8 LoadObjectEventPalette(u16);
|
||||
u8 UpdateSpritePaletteByTemplate(const struct SpriteTemplate *, struct Sprite *);
|
||||
void ObjectEventSetGraphicsId(struct ObjectEvent *, u16 graphicsId);
|
||||
void ObjectEventTurn(struct ObjectEvent *, u8 direction);
|
||||
|
||||
@@ -21,7 +21,7 @@ bool8 UpdateRevealDisguise(struct ObjectEvent *);
|
||||
void StartRevealDisguise(struct ObjectEvent *);
|
||||
void StartAshFieldEffect(s16, s16, u16, s16);
|
||||
void SetUpReflection(struct ObjectEvent *, struct Sprite *, u8);
|
||||
void SetUpShadow(struct ObjectEvent *, struct Sprite *);
|
||||
void SetUpShadow(struct ObjectEvent *);
|
||||
u32 StartFieldEffectForObjectEvent(u8, struct ObjectEvent *);
|
||||
u8 FindTallGrassFieldEffectSpriteId(u8 localId, u8 mapNum, u8 mapGroup, s16 x, s16 y);
|
||||
void UpdateRayquazaSpotlightEffect(struct Sprite *);
|
||||
|
||||
@@ -44,7 +44,8 @@ struct Weather
|
||||
s8 targetColorMapIndex;
|
||||
u8 colorMapStepDelay;
|
||||
u8 colorMapStepCounter;
|
||||
u16 fadeDestColor;
|
||||
u16 fadeDestColor:15;
|
||||
u16 noShadows:1; // Certain weathers require blend coeffs that do not work nice with shadows
|
||||
u8 palProcessingState;
|
||||
u8 fadeScreenCounter;
|
||||
bool8 readyForInit;
|
||||
@@ -147,9 +148,10 @@ void SetCurrentAndNextWeatherNoDelay(u8 weather);
|
||||
void ApplyWeatherColorMapIfIdle(s8 colorMapIndex);
|
||||
void ApplyWeatherColorMapIfIdle_Gradual(u8 colorMapIndex, u8 targetColorMapIndex, u8 colorMapStepDelay);
|
||||
void FadeScreen(u8 mode, s8 delay);
|
||||
void FadeScreenHardware(u32 mode, s32 delay);
|
||||
bool8 IsWeatherNotFadingIn(void);
|
||||
void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex);
|
||||
void ApplyWeatherColorMapToPal(u8 paletteIndex);
|
||||
void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex, bool8 allowFog);
|
||||
void ApplyWeatherColorMapToPals(u8 startPalIndex, u8 numPalettes);
|
||||
void LoadCustomWeatherSpritePalette(const u16 *palette);
|
||||
void ResetDroughtWeatherPaletteLoading(void);
|
||||
bool8 LoadDroughtWeatherPalettes(void);
|
||||
@@ -164,7 +166,9 @@ void PlayRainStoppingSoundEffect(void);
|
||||
u8 IsWeatherChangeComplete(void);
|
||||
void SetWeatherScreenFadeOut(void);
|
||||
void SetWeatherPalStateIdle(void);
|
||||
const u8 *SetPaletteColorMapType(u8 paletteIndex, enum ColorMapType colorMapType);
|
||||
void PreservePaletteInWeather(u8 preservedPalIndex);
|
||||
void ResetPaletteColorMapType(u8 paletteIndex);
|
||||
void ResetPreservedPalettesInWeather(void);
|
||||
bool32 IsWeatherAlphaBlend(void);
|
||||
|
||||
@@ -190,6 +194,7 @@ void Thunderstorm_Main(void);
|
||||
void Thunderstorm_InitAll(void);
|
||||
bool8 Thunderstorm_Finish(void);
|
||||
void FogHorizontal_InitVars(void);
|
||||
u8 UpdateShadowColor(u16 color);
|
||||
void FogHorizontal_Main(void);
|
||||
void FogHorizontal_InitAll(void);
|
||||
bool8 FogHorizontal_Finish(void);
|
||||
|
||||
@@ -45,7 +45,7 @@ void InitTrainerHillMap(void);
|
||||
void InitBattlePyramidMap(bool8 setPlayerPosition);
|
||||
void CopyMapTilesetsToVram(struct MapLayout const *mapLayout);
|
||||
void LoadMapTilesetPalettes(struct MapLayout const *mapLayout);
|
||||
void LoadSecondaryTilesetPalette(struct MapLayout const *mapLayout);
|
||||
void LoadSecondaryTilesetPalette(struct MapLayout const *mapLayout, bool8 skipFaded);
|
||||
void CopySecondaryTilesetToVramUsingHeap(struct MapLayout const *mapLayout);
|
||||
void CopyPrimaryTilesetToVram(const struct MapLayout *);
|
||||
void CopySecondaryTilesetToVram(const struct MapLayout *);
|
||||
|
||||
@@ -111,6 +111,8 @@ enum {
|
||||
COND_MSG_LEAVES,
|
||||
COND_MSG_ICE,
|
||||
COND_MSG_BURN,
|
||||
COND_MSG_DAY,
|
||||
COND_MSG_NIGHT,
|
||||
COND_MSG_COUNT,
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -37,8 +37,11 @@ typedef void (*TilesetCB)(void);
|
||||
|
||||
struct Tileset
|
||||
{
|
||||
/*0x00*/ bool8 isCompressed;
|
||||
/*0x00*/ u8 isCompressed:1;
|
||||
/*0x00*/ u8 swapPalettes:7; // Bitmask determining whether palette has an alternate, night-time palette
|
||||
/*0x01*/ bool8 isSecondary;
|
||||
/*0x02*/ u8 lightPalettes; // Bitmask determining whether a palette should be time-blended as a light
|
||||
/*0x03*/ u8 customLightColor; // Bitmask determining which light palettes have custom light colors (color 15)
|
||||
/*0x04*/ const u32 *tiles;
|
||||
/*0x08*/ const u16 (*palettes)[16];
|
||||
/*0x0C*/ const u16 *metatiles;
|
||||
@@ -188,14 +191,15 @@ struct ObjectEvent
|
||||
u32 inShallowFlowingWater:1;
|
||||
u32 inSandPile:1;
|
||||
u32 inHotSprings:1;
|
||||
u32 hasShadow:1;
|
||||
u32 noShadow:1;
|
||||
u32 spriteAnimPausedBackup:1;
|
||||
/*0x03*/ u32 spriteAffineAnimPausedBackup:1;
|
||||
u32 disableJumpLandingGroundEffect:1;
|
||||
u32 fixedPriority:1;
|
||||
u32 hideReflection:1;
|
||||
u32 shiny:1; // OW mon shininess
|
||||
u32 padding:3;
|
||||
u32 jumpDone:1;
|
||||
u32 padding:2;
|
||||
/*0x04*/ u16 graphicsId; // 12 bits for species; high 4 bits for form
|
||||
/*0x06*/ u8 movementType;
|
||||
/*0x07*/ u8 trainerType;
|
||||
|
||||
@@ -569,6 +569,8 @@ struct SaveBlock2
|
||||
|
||||
extern struct SaveBlock2 *gSaveBlock2Ptr;
|
||||
|
||||
extern u8 UpdateSpritePaletteWithTime(u8);
|
||||
|
||||
struct SecretBaseParty
|
||||
{
|
||||
u32 personality[PARTY_SIZE];
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
|
||||
#define SKIP_OBJECT_EVENT_LOAD 1
|
||||
|
||||
// trigger a time-of-day blend once
|
||||
#define HOURS_BLEND_ONCE 25
|
||||
// don't update gTimeBlend
|
||||
#define HOURS_FREEZE_BLEND 26
|
||||
|
||||
struct InitialPlayerAvatarState
|
||||
{
|
||||
u8 transitionFlags;
|
||||
@@ -40,6 +45,7 @@ struct LinkPlayerObjectEvent
|
||||
u8 movementMode;
|
||||
};
|
||||
|
||||
// Exported RAM declarations
|
||||
extern struct WarpData gLastUsedWarp;
|
||||
extern struct LinkPlayerObjectEvent gLinkPlayerObjectEvents[4];
|
||||
|
||||
@@ -53,6 +59,10 @@ extern u8 gLocalLinkPlayerId;
|
||||
extern u8 gFieldLinkPlayerCount;
|
||||
extern bool8 gExitStairsMovementDisabled;
|
||||
extern bool8 gSkipShowMonAnim;
|
||||
extern u8 gTimeOfDay;
|
||||
extern s16 gTimeUpdateCounter;
|
||||
|
||||
extern struct TimeBlendSettings gTimeBlend;
|
||||
|
||||
extern const struct UCoords32 gDirectionToVectors[];
|
||||
|
||||
@@ -130,6 +140,11 @@ void CleanupOverworldWindowsAndTilemaps(void);
|
||||
bool32 IsOverworldLinkActive(void);
|
||||
void CB1_Overworld(void);
|
||||
void CB2_OverworldBasic(void);
|
||||
void UpdateTimeOfDay(void);
|
||||
bool32 MapHasNaturalLight(u8 mapType);
|
||||
bool32 CurrentMapHasShadows(void);
|
||||
void UpdateAltBgPalettes(u16 palettes);
|
||||
void UpdatePalettesWithTime(u32);
|
||||
void CB2_Overworld(void);
|
||||
void SetMainCallback1(void (*cb)(void));
|
||||
void SetUnusedCallback(void *func);
|
||||
@@ -156,6 +171,7 @@ bool32 Overworld_RecvKeysFromLinkIsRunning(void);
|
||||
bool32 Overworld_SendKeysToLinkIsRunning(void);
|
||||
bool32 IsSendingKeysOverCable(void);
|
||||
void ClearLinkPlayerObjectEvents(void);
|
||||
bool16 SetTimeOfDay(u16 hours);
|
||||
|
||||
// Item Description Headers
|
||||
enum ItemObtainFlags
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#ifndef GUARD_PALETTE_H
|
||||
#define GUARD_PALETTE_H
|
||||
|
||||
#define gPaletteFade_selectedPalettes (gPaletteFade.multipurpose1) // normal and fast fade
|
||||
#define gPaletteFade_blendCnt (gPaletteFade.multipurpose1) // hardware fade
|
||||
#define gPaletteFade_delay (gPaletteFade.multipurpose2) // normal and hardware fade
|
||||
#define gPaletteFade_submode (gPaletteFade.multipurpose2) // fast fade
|
||||
#define gPaletteFadeSelectedPalettes (gPaletteFade.multipurpose1) // normal and fast fade
|
||||
#define gPaletteFadeBlendCnt (gPaletteFade.multipurpose1) // hardware fade
|
||||
#define gPaletteFadeDelay (gPaletteFade.multipurpose2) // normal and hardware fade
|
||||
#define gPaletteFadeSubmode (gPaletteFade.multipurpose2) // fast fade
|
||||
|
||||
#define PLTT_BUFFER_SIZE (PLTT_SIZE / sizeof(u16))
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#define PALETTE_FADE_STATUS_LOADING 0xFF
|
||||
|
||||
#define PALETTES_BG 0x0000FFFF
|
||||
// like PALETTES_BG but excludes UI pals [13, 15]
|
||||
#define PALETTES_MAP 0x00001FFF
|
||||
#define PALETTES_OBJECTS 0xFFFF0000
|
||||
#define PALETTES_ALL (PALETTES_BG | PALETTES_OBJECTS)
|
||||
|
||||
@@ -24,6 +26,10 @@
|
||||
#define OBJ_PLTT_ID(n) (OBJ_PLTT_OFFSET + PLTT_ID(n))
|
||||
#define OBJ_PLTT_ID2(n) (PLTT_ID((n) + 16))
|
||||
|
||||
// Used to determine whether a sprite palette tag should be excluded from time (and weather) blending
|
||||
#define BLEND_IMMUNE_FLAG (1 << 15)
|
||||
#define IS_BLEND_IMMUNE_TAG(tag) ((tag) & BLEND_IMMUNE_FLAG)
|
||||
|
||||
enum
|
||||
{
|
||||
FAST_FADE_IN_FROM_WHITE,
|
||||
@@ -32,26 +38,50 @@ enum
|
||||
FAST_FADE_OUT_TO_BLACK,
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
u32 multipurpose1;
|
||||
u8 delayCounter:6;
|
||||
u16 y:5; // blend coefficient
|
||||
u16 targetY:5; // target blend coefficient
|
||||
u16 blendColor:15;
|
||||
bool16 active:1;
|
||||
u16 multipurpose2:6;
|
||||
bool16 yDec:1; // whether blend coefficient is decreasing
|
||||
bool16 bufferTransferDisabled:1;
|
||||
u16 mode:2;
|
||||
bool16 shouldResetBlendRegisters:1;
|
||||
bool16 hardwareFadeFinishing:1;
|
||||
u16 softwareFadeFinishingCounter:5;
|
||||
bool16 softwareFadeFinishing:1;
|
||||
bool16 objPaletteToggle:1;
|
||||
u8 deltaY:4; // rate of change of blend coefficient
|
||||
u32 multipurpose1; // This field needs to exist or errors will occur
|
||||
// These three are only used for TOD blending
|
||||
struct BlendSettings *bld0;
|
||||
struct BlendSettings *bld1;
|
||||
u32 weight:9; // [0, 256], so must be 9 bits
|
||||
u32 delayCounter:6;
|
||||
u32 y:5; // blend coefficient
|
||||
u32 targetY:5; // target blend coefficient
|
||||
u32 multipurpose2:6;
|
||||
bool32 active:1;
|
||||
u32 blendColor:15;
|
||||
// end of word
|
||||
bool32 yDec:1; // whether blend coefficient is decreasing
|
||||
bool32 bufferTransferDisabled:1;
|
||||
u32 mode:2;
|
||||
bool32 shouldResetBlendRegisters:1;
|
||||
bool32 hardwareFadeFinishing:1;
|
||||
u32 softwareFadeFinishingCounter:5;
|
||||
bool32 softwareFadeFinishing:1;
|
||||
bool32 objPaletteToggle:1;
|
||||
u32 deltaY:4; // rate of change of blend coefficient
|
||||
u32 padding:15;
|
||||
};
|
||||
|
||||
extern const struct BlendSettings gTimeOfDayBlend[];
|
||||
|
||||
extern struct PaletteFadeControl gPaletteFade;
|
||||
extern u32 gPlttBufferTransferPending;
|
||||
extern u16 ALIGNED(4) gPlttBufferUnfaded[PLTT_BUFFER_SIZE];
|
||||
@@ -59,11 +89,14 @@ extern u16 ALIGNED(4) gPlttBufferFaded[PLTT_BUFFER_SIZE];
|
||||
|
||||
void LoadCompressedPalette(const u32 *src, u32 offset, u32 size);
|
||||
void LoadPalette(const void *src, u32 offset, u32 size);
|
||||
void LoadPaletteFast(const void *src, u32 offset, u32 size);
|
||||
void FillPalette(u32 value, u32 offset, u32 size);
|
||||
void TransferPlttBuffer(void);
|
||||
u32 UpdatePaletteFade(void);
|
||||
void ResetPaletteFade(void);
|
||||
bool32 BeginNormalPaletteFade(u32 selectedPalettes, s8 delay, u8 startY, u8 targetY, u32 blendColor);
|
||||
bool32 BeginTimeOfDayPaletteFade(u32 selectedPalettes, s8 delay, u8 startY, u8 targetY, struct BlendSettings *bld0, struct BlendSettings *bld1, u32 weight, u32 color);
|
||||
void PaletteStruct_ResetById(u32 id);
|
||||
void ResetPaletteFadeControl(void);
|
||||
void InvertPlttBuffer(u32 selectedPalettes);
|
||||
void TintPlttBuffer(u32 selectedPalettes, s8 r, s8 g, s8 b);
|
||||
@@ -71,8 +104,13 @@ void UnfadePlttBuffer(u32 selectedPalettes);
|
||||
void BeginFastPaletteFade(u32 submode);
|
||||
void BeginHardwarePaletteFade(u32 blendCnt, u32 delay, u32 y, u32 targetY, u32 shouldResetBlendRegisters);
|
||||
void BlendPalettes(u32 selectedPalettes, u8 coeff, u32 color);
|
||||
void BlendPalettesFine(u32 palettes, u16 *src, u16 *dst, u32 coeff, u32 color);
|
||||
void BlendPalettesUnfaded(u32 selectedPalettes, u8 coeff, u32 color);
|
||||
void BlendPalettesGradually(u32 selectedPalettes, s8 delay, u8 coeff, u8 coeffTarget, u16 color, u8 priority, u8 id);
|
||||
void TimeBlendPalette(u16 palOffset, u32 coeff, u32 blendColor);
|
||||
void TintPalette_RGB_Copy(u16 palOffset, u32 blendColor);
|
||||
void TimeMixPalettes(u32 palettes, u16 *src, u16 *dst, struct BlendSettings *blend0, struct BlendSettings *blend1, u16 weight0);
|
||||
void AvgPaletteWeighted(u16 *src0, u16 *src1, u16 *dst, u16 weight0);
|
||||
void TintPalette_GrayScale(u16 *palette, u32 count);
|
||||
void TintPalette_GrayScale2(u16 *palette, u32 count);
|
||||
void TintPalette_SepiaTone(u16 *palette, u32 count);
|
||||
|
||||
@@ -318,6 +318,7 @@ void RequestSpriteSheetCopy(const struct SpriteSheet *sheet);
|
||||
u16 LoadSpriteSheetDeferred(const struct SpriteSheet *sheet);
|
||||
void FreeAllSpritePalettes(void);
|
||||
u32 LoadSpritePalette(const struct SpritePalette *palette);
|
||||
u8 LoadSpritePaletteInSlot(const struct SpritePalette *palette, u8 paletteNum);
|
||||
void LoadSpritePalettes(const struct SpritePalette *palettes);
|
||||
u32 AllocSpritePalette(u16 tag);
|
||||
u32 IndexOfSpritePaletteTag(u16 tag);
|
||||
|
||||
@@ -2065,18 +2065,23 @@ static void SetBattlerMonData(u32 battler, struct Pokemon *party, u32 monId)
|
||||
HandleLowHpMusicChange(&party[gBattlerPartyIndexes[battler]], battler);
|
||||
}
|
||||
|
||||
// In normal singles, if follower pokemon is out, have it slide in instead of being thrown
|
||||
static bool8 ShouldDoSlideInAnim(void)
|
||||
// In normal singles, if follower Pokémon exists, and the Pokémon following is being sent out, have it slide in instead of being thrown
|
||||
static bool8 ShouldDoSlideInAnim(u32 battler)
|
||||
{
|
||||
struct ObjectEvent *followerObj = GetFollowerObject();
|
||||
if (!followerObj || followerObj->invisible)
|
||||
return FALSE;
|
||||
|
||||
if (gBattleTypeFlags & (
|
||||
BATTLE_TYPE_LINK | BATTLE_TYPE_DOUBLE | BATTLE_TYPE_FRONTIER | BATTLE_TYPE_FIRST_BATTLE |
|
||||
BATTLE_TYPE_SAFARI | BATTLE_TYPE_WALLY_TUTORIAL | BATTLE_TYPE_EREADER_TRAINER | BATTLE_TYPE_TWO_OPPONENTS |
|
||||
BATTLE_TYPE_INGAME_PARTNER | BATTLE_TYPE_RECORDED | BATTLE_TYPE_TRAINER_HILL)
|
||||
)
|
||||
return FALSE;
|
||||
|
||||
if (GetFirstLiveMon() != &gPlayerParty[gBattlerPartyIndexes[battler]])
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -2857,7 +2862,7 @@ void BtlController_HandleIntroTrainerBallThrow(u32 battler, u16 tagTrainerPal, c
|
||||
if (side == B_SIDE_PLAYER)
|
||||
{
|
||||
StoreSpriteCallbackInData6(&gSprites[gBattleStruct->trainerSlideSpriteIds[battler]], SpriteCB_FreePlayerSpriteLoadMonSprite);
|
||||
StartSpriteAnim(&gSprites[gBattleStruct->trainerSlideSpriteIds[battler]], ShouldDoSlideInAnim() ? 2 : 1);
|
||||
StartSpriteAnim(&gSprites[gBattleStruct->trainerSlideSpriteIds[battler]], ShouldDoSlideInAnim(battler) ? 2 : 1);
|
||||
|
||||
paletteNum = AllocSpritePalette(tagTrainerPal);
|
||||
LoadCompressedPalette(trainerPal, OBJ_PLTT_ID(paletteNum), PLTT_SIZE_4BPP);
|
||||
@@ -2916,17 +2921,17 @@ static void Task_StartSendOutAnim(u8 taskId)
|
||||
if (TwoMonsAtSendOut(battler))
|
||||
{
|
||||
gBattleResources->bufferA[battler][1] = gBattlerPartyIndexes[battler];
|
||||
StartSendOutAnim(battler, FALSE, FALSE, ShouldDoSlideInAnim());
|
||||
StartSendOutAnim(battler, FALSE, FALSE, ShouldDoSlideInAnim(battler));
|
||||
|
||||
battlerPartner = battler ^ BIT_FLANK;
|
||||
gBattleResources->bufferA[battlerPartner][1] = gBattlerPartyIndexes[battlerPartner];
|
||||
BattleLoadMonSpriteGfx(&gPlayerParty[gBattlerPartyIndexes[battlerPartner]], battlerPartner);
|
||||
StartSendOutAnim(battlerPartner, FALSE, FALSE, ShouldDoSlideInAnim());
|
||||
StartSendOutAnim(battlerPartner, FALSE, FALSE, ShouldDoSlideInAnim(battler));
|
||||
}
|
||||
else
|
||||
{
|
||||
gBattleResources->bufferA[battler][1] = gBattlerPartyIndexes[battler];
|
||||
StartSendOutAnim(battler, FALSE, FALSE, ShouldDoSlideInAnim());
|
||||
StartSendOutAnim(battler, FALSE, FALSE, ShouldDoSlideInAnim(battler));
|
||||
}
|
||||
gBattlerControllerFuncs[battler] = (void*)(GetWordTaskArg(taskId, tControllerFunc_1));
|
||||
DestroyTask(taskId);
|
||||
|
||||
@@ -1355,6 +1355,7 @@ static void InitPatternWeaveTransition(struct Task *task)
|
||||
sTransitionData->WIN0V = DISPLAY_HEIGHT;
|
||||
sTransitionData->BLDCNT = BLDCNT_TGT1_BG0 | BLDCNT_EFFECT_BLEND | BLDCNT_TGT2_ALL;
|
||||
sTransitionData->BLDALPHA = BLDALPHA_BLEND(task->tBlendTarget2, task->tBlendTarget1);
|
||||
UpdateShadowColor(RGB_GRAY);
|
||||
|
||||
for (i = 0; i < DISPLAY_HEIGHT; i++)
|
||||
gScanlineEffectRegBuffers[1][i] = DISPLAY_WIDTH;
|
||||
@@ -3885,6 +3886,8 @@ static void VBlankCB_AngledWipes(void)
|
||||
#define tFadeFromGrayIncrement data[5]
|
||||
#define tDelayTimer data[6]
|
||||
#define tBlend data[7]
|
||||
#define tBldCntSaved data[8]
|
||||
#define tShadowColor data[9]
|
||||
|
||||
static void CreateIntroTask(s16 fadeToGrayDelay, s16 fadeFromGrayDelay, s16 numFades, s16 fadeToGrayIncrement, s16 fadeFromGrayIncrement)
|
||||
{
|
||||
@@ -3912,17 +3915,28 @@ void Task_BattleTransition_Intro(u8 taskId)
|
||||
|
||||
static bool8 TransitionIntro_FadeToGray(struct Task *task)
|
||||
{
|
||||
u8 paletteNum = IndexOfSpritePaletteTag(TAG_WEATHER_START);
|
||||
u16 index = OBJ_PLTT_ID(paletteNum) + SHADOW_COLOR_INDEX;
|
||||
if (task->tDelayTimer == 0 || --task->tDelayTimer == 0)
|
||||
{
|
||||
task->tDelayTimer = task->tFadeToGrayDelay;
|
||||
task->tBlend += task->tFadeToGrayIncrement;
|
||||
if (task->tBlend > 16)
|
||||
task->tBlend = 16;
|
||||
if (paletteNum < 16)
|
||||
task->tShadowColor = gPlttBufferFaded[index];
|
||||
BlendPalettes(PALETTES_ALL, task->tBlend, RGB(11, 11, 11));
|
||||
if (paletteNum < 16)
|
||||
gPlttBufferFaded[index] = task->tShadowColor;
|
||||
}
|
||||
if (task->tBlend >= 16)
|
||||
{
|
||||
// Fade to gray complete, start fade back
|
||||
// Save BLDCNT and turn off targets temporarily
|
||||
task->tBldCntSaved = GetGpuReg(REG_OFFSET_BLDCNT);
|
||||
SetGpuReg(REG_OFFSET_BLDCNT, task->tBldCntSaved & ~BLDCNT_TGT2_BG_ALL);
|
||||
if (paletteNum < 16)
|
||||
gPlttBufferFaded[index] = RGB(11, 11, 11);
|
||||
task->tState++;
|
||||
task->tDelayTimer = task->tFadeFromGrayDelay;
|
||||
}
|
||||
@@ -3933,11 +3947,19 @@ static bool8 TransitionIntro_FadeFromGray(struct Task *task)
|
||||
{
|
||||
if (task->tDelayTimer == 0 || --task->tDelayTimer == 0)
|
||||
{
|
||||
u8 paletteNum = IndexOfSpritePaletteTag(TAG_WEATHER_START);
|
||||
task->tDelayTimer = task->tFadeFromGrayDelay;
|
||||
task->tBlend -= task->tFadeFromGrayIncrement;
|
||||
if (task->tBlend < 0)
|
||||
task->tBlend = 0;
|
||||
BlendPalettes(PALETTES_ALL, task->tBlend, RGB(11, 11, 11));
|
||||
// Restore BLDCNT
|
||||
SetGpuReg(REG_OFFSET_BLDCNT, task->tBldCntSaved);
|
||||
if (paletteNum < 16)
|
||||
{
|
||||
u16 index = OBJ_PLTT_ID(paletteNum) + SHADOW_COLOR_INDEX;
|
||||
gPlttBufferFaded[index] = task->tShadowColor;
|
||||
}
|
||||
}
|
||||
if (task->tBlend == 0)
|
||||
{
|
||||
@@ -4230,6 +4252,7 @@ static bool8 FrontierLogoWave_Init(struct Task *task)
|
||||
LZ77UnCompVram(sFrontierLogo_Tileset, tileset);
|
||||
LoadPalette(sFrontierLogo_Palette, BG_PLTT_ID(15), sizeof(sFrontierLogo_Palette));
|
||||
sTransitionData->cameraY = 0;
|
||||
UpdateShadowColor(RGB_GRAY);
|
||||
|
||||
task->tState++;
|
||||
return FALSE;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "global.h"
|
||||
#include "clock.h"
|
||||
#include "event_data.h"
|
||||
#include "rtc.h"
|
||||
#include "time_events.h"
|
||||
@@ -15,7 +16,6 @@
|
||||
|
||||
static void UpdatePerDay(struct Time *localTime);
|
||||
static void UpdatePerMinute(struct Time *localTime);
|
||||
static void FormChangeTimeUpdate();
|
||||
|
||||
void InitTimeBasedEvents(void)
|
||||
{
|
||||
@@ -72,12 +72,11 @@ static void UpdatePerMinute(struct Time *localTime)
|
||||
{
|
||||
BerryTreeTimeUpdate(minutes);
|
||||
gSaveBlock2Ptr->lastBerryTreeUpdate = *localTime;
|
||||
FormChangeTimeUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void FormChangeTimeUpdate()
|
||||
void FormChangeTimeUpdate()
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < PARTY_SIZE; i++)
|
||||
|
||||
@@ -35,6 +35,7 @@ extern const struct SpriteTemplate gFieldEffectObjectTemplate_AshLaunch;
|
||||
extern const struct SpriteTemplate gFieldEffectObjectTemplate_Bubbles;
|
||||
extern const struct SpriteTemplate gFieldEffectObjectTemplate_SmallSparkle;
|
||||
extern const struct SpriteTemplate gFieldEffectObjectTemplate_Rayquaza;
|
||||
extern const struct SpriteTemplate gFieldEffectObjectTemplate_BallLight;
|
||||
extern const struct SpriteTemplate gFieldEffectObjectTemplate_SlitherTracks;
|
||||
extern const struct SpriteTemplate gFieldEffectObjectTemplate_BugTracks;
|
||||
extern const struct SpriteTemplate gFieldEffectObjectTemplate_SpotTracks;
|
||||
|
||||
@@ -28,8 +28,56 @@ static const struct SpriteFrameImage sPicTable_ShadowExtraLarge[] = {
|
||||
obj_frame_tiles(gFieldEffectObjectPic_ShadowExtraLarge),
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowSmall = {
|
||||
const struct SpriteFrameImage gFieldEffectObjectPicTable_BallLight[] = {
|
||||
obj_frame_tiles(gFieldEffectObjectPic_BallLight),
|
||||
};
|
||||
|
||||
const struct SpriteFrameImage gFieldEffectObjectPicTable_PokeCenterLight[] = {
|
||||
obj_frame_tiles(gFieldEffectObjectPic_PokeCenterLight),
|
||||
};
|
||||
|
||||
const struct SpriteFrameImage gFieldEffectObjectPicTable_MartLight[] = {
|
||||
obj_frame_tiles(gFieldEffectObjectPic_MartLight),
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gFieldEffectObjectTemplate_BallLight = {
|
||||
.tileTag = OBJ_EVENT_PAL_TAG_LIGHT,
|
||||
.paletteTag = OBJ_EVENT_PAL_TAG_LIGHT,
|
||||
.oam = &gObjectEventBaseOam_32x32,
|
||||
.anims = sAnimTable_Inanimate,
|
||||
.images = gFieldEffectObjectPicTable_BallLight,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = UpdateLightSprite,
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gFieldEffectObjectTemplate_PokeCenterLight = {
|
||||
.tileTag = TAG_NONE,
|
||||
.paletteTag = OBJ_EVENT_PAL_TAG_NEON_LIGHT,
|
||||
.oam = &gObjectEventBaseOam_16x16,
|
||||
.anims = sAnimTable_Inanimate,
|
||||
.images = gFieldEffectObjectPicTable_PokeCenterLight,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = UpdateLightSprite,
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gFieldEffectObjectTemplate_MartLight = {
|
||||
.tileTag = TAG_NONE,
|
||||
.paletteTag = OBJ_EVENT_PAL_TAG_NEON_LIGHT,
|
||||
.oam = &gObjectEventBaseOam_16x16,
|
||||
.anims = sAnimTable_Inanimate,
|
||||
.images = gFieldEffectObjectPicTable_MartLight,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = UpdateLightSprite,
|
||||
};
|
||||
|
||||
const struct SpriteTemplate *const gFieldEffectLightTemplates[] = {
|
||||
&gFieldEffectObjectTemplate_BallLight,
|
||||
&gFieldEffectObjectTemplate_PokeCenterLight,
|
||||
&gFieldEffectObjectTemplate_MartLight,
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowSmall = {
|
||||
.tileTag = FLDEFF_TILE_TAG_SHADOW_SMALL,
|
||||
.paletteTag = TAG_WEATHER_START,
|
||||
.oam = &gObjectEventBaseOam_8x8,
|
||||
.anims = sAnimTable_Shadow,
|
||||
@@ -39,7 +87,7 @@ const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowSmall = {
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowMedium = {
|
||||
.tileTag = TAG_NONE,
|
||||
.tileTag = FLDEFF_TILE_TAG_SHADOW_MEDIUM,
|
||||
.paletteTag = TAG_WEATHER_START,
|
||||
.oam = &gObjectEventBaseOam_16x8,
|
||||
.anims = sAnimTable_Shadow,
|
||||
@@ -49,7 +97,7 @@ const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowMedium = {
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowLarge = {
|
||||
.tileTag = TAG_NONE,
|
||||
.tileTag = FLDEFF_TILE_TAG_SHADOW_LARGE,
|
||||
.paletteTag = TAG_WEATHER_START,
|
||||
.oam = &gObjectEventBaseOam_32x8,
|
||||
.anims = sAnimTable_Shadow,
|
||||
@@ -59,7 +107,7 @@ const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowLarge = {
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gFieldEffectObjectTemplate_ShadowExtraLarge = {
|
||||
.tileTag = TAG_NONE,
|
||||
.tileTag = FLDEFF_TILE_TAG_SHADOW_EXTRA_LARGE,
|
||||
.paletteTag = TAG_WEATHER_START,
|
||||
.oam = &gObjectEventBaseOam_64x32,
|
||||
.anims = sAnimTable_Shadow,
|
||||
|
||||
@@ -293,7 +293,9 @@ 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");
|
||||
static const u32 sFiller[0x48] = {};
|
||||
const u32 gFieldEffectObjectPic_BallLight[] = INCBIN_U32("graphics/object_events/pics/misc/light.4bpp");
|
||||
const u32 gFieldEffectObjectPic_PokeCenterLight[] = INCBIN_U32("graphics/object_events/pics/misc/poke_center_light.4bpp");
|
||||
const u32 gFieldEffectObjectPic_MartLight[] = INCBIN_U32("graphics/object_events/pics/misc/mart_light.4bpp");
|
||||
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");
|
||||
const u16 gFieldEffectPal_CutGrass[] = INCBIN_U16("graphics/field_effects/palettes/cut_grass.gbapal");
|
||||
@@ -380,9 +382,12 @@ const u32 gObjectEventPic_RayquazaCutscene[] = INCBIN_U32("graphics/object_event
|
||||
const u16 gObjectEventPal_HoOh[] = INCBIN_U16("graphics/object_events/palettes/ho_oh.gbapal");
|
||||
const u16 gObjectEventPal_Lugia[] = INCBIN_U16("graphics/object_events/palettes/lugia.gbapal");
|
||||
|
||||
const u16 gObjectEventPal_Substitute[] = INCBIN_U16("graphics/pokemon/question_mark/overworld.gbapal");
|
||||
const u16 gObjectEventPaletteLight[] = INCBIN_U16("graphics/object_events/palettes/light.gbapal");
|
||||
const u16 gObjectEventPaletteLight2[] = INCBIN_U16("graphics/object_events/palettes/light2.gbapal");
|
||||
const u16 gObjectEventPal_Substitute[] = INCBIN_U16("graphics/object_events/pics/pokemon_old/substitute.gbapal");
|
||||
|
||||
const u16 gObjectEventPaletteEmotes[] = INCBIN_U16("graphics/misc/emotes.gbapal");
|
||||
const u16 gObjectEventPaletteNeonLight[] = INCBIN_U16("graphics/object_events/palettes/neon_light.gbapal");
|
||||
|
||||
#if OW_FOLLOWERS_POKEBALLS
|
||||
const u32 gObjectEventPic_MasterBall[] = INCBIN_U32("graphics/object_events/pics/misc/ball_master.4bpp");
|
||||
|
||||
@@ -4671,3 +4671,22 @@ const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Follower = {
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
};
|
||||
|
||||
const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_BallLight = {
|
||||
.tileTag = TAG_NONE,
|
||||
.paletteTag = OBJ_EVENT_PAL_TAG_LIGHT,
|
||||
.reflectionPaletteTag = OBJ_EVENT_PAL_TAG_LIGHT_2,
|
||||
.size = 512,
|
||||
.width = 32,
|
||||
.height = 32,
|
||||
.paletteSlot = PALSLOT_NPC_1,
|
||||
.shadowSize = SHADOW_SIZE_NONE,
|
||||
.inanimate = TRUE,
|
||||
.compressed = FALSE,
|
||||
.tracks = TRACKS_NONE,
|
||||
.oam = &gObjectEventBaseOam_32x32,
|
||||
.subspriteTables = sOamTables_32x32,
|
||||
.anims = sAnimTable_Inanimate,
|
||||
.images = gFieldEffectObjectPicTable_BallLight,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
};
|
||||
|
||||
@@ -239,6 +239,7 @@ extern const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_HoOh;
|
||||
// Begin pokemon event objects
|
||||
extern const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_PokeBall;
|
||||
extern const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Follower;
|
||||
extern const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_BallLight;
|
||||
|
||||
extern const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Bard;
|
||||
extern const struct ObjectEventGraphicsInfo gObjectEventGraphicsInfo_Hipster;
|
||||
@@ -490,6 +491,7 @@ const struct ObjectEventGraphicsInfo *const gObjectEventGraphicsInfoPointers[NUM
|
||||
[OBJ_EVENT_GFX_HOOH] = &gObjectEventGraphicsInfo_HoOh,
|
||||
[OBJ_EVENT_GFX_POKE_BALL] = &gObjectEventGraphicsInfo_PokeBall,
|
||||
[OBJ_EVENT_GFX_OW_MON] = &gObjectEventGraphicsInfo_Follower,
|
||||
[OBJ_EVENT_GFX_LIGHT_SPRITE] = &gObjectEventGraphicsInfo_BallLight,
|
||||
};
|
||||
|
||||
const struct ObjectEventGraphicsInfo *const gMauvilleOldManGraphicsInfoPointers[] = {
|
||||
|
||||
@@ -1117,8 +1117,9 @@ static const struct SpriteFrameImage sPicTable_PokeBall[] = {
|
||||
overworld_frame(gObjectEventPic_PokeBall, 2, 4, 0),
|
||||
};
|
||||
|
||||
#if OW_FOLLOWERS_POKEBALLS
|
||||
extern const struct SpriteFrameImage gFieldEffectObjectPicTable_BallLight[];
|
||||
|
||||
#if OW_FOLLOWERS_POKEBALLS
|
||||
#define POKEBALL_PIC_FRAMES(name) \
|
||||
overworld_frame(gObjectEventPic_##name##Ball, 2, 4, 0), \
|
||||
overworld_frame(gObjectEventPic_##name##Ball, 2, 4, 1), \
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
#include "fieldmap.h"
|
||||
|
||||
// Whether a palette has a night version, located at ((x + 9) % 16).pal
|
||||
#define SWAP_PAL(x) ((x) < NUM_PALS_IN_PRIMARY ? 1 << (x) : 1 << ((x) - NUM_PALS_IN_PRIMARY))
|
||||
|
||||
const struct Tileset gTileset_General =
|
||||
{
|
||||
.isCompressed = TRUE,
|
||||
|
||||
@@ -2131,7 +2131,7 @@ static u8 AddDecorationIconObjectFromObjectEvent(u16 tilesTag, u16 paletteTag, u
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteId = CreateObjectGraphicsSprite(sPlaceDecorationGraphicsDataBuffer.decoration->tiles[0], SpriteCallbackDummy, 0, 0, 1);
|
||||
spriteId = CreateObjectGraphicsSpriteWithTag(sPlaceDecorationGraphicsDataBuffer.decoration->tiles[0], SpriteCallbackDummy, 0, 0, 1, paletteTag);
|
||||
}
|
||||
return spriteId;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "pokeball.h"
|
||||
#include "random.h"
|
||||
#include "region_map.h"
|
||||
#include "rtc.h"
|
||||
#include "script.h"
|
||||
#include "sound.h"
|
||||
#include "sprite.h"
|
||||
@@ -186,7 +187,7 @@ static void SetSpriteDataForNormalStep(struct Sprite *, u8, u8);
|
||||
static void InitSpriteForFigure8Anim(struct Sprite *);
|
||||
static bool8 AnimateSpriteInFigure8(struct Sprite *);
|
||||
u8 GetDirectionToFace(s16 x1, s16 y1, s16 x2, s16 y2);
|
||||
static void FollowerSetGraphics(struct ObjectEvent * objectEvent, u32 species, bool32 shiny, bool32 female);
|
||||
static void FollowerSetGraphics(struct ObjectEvent *objEvent, u32 species, bool32 shiny, bool32 female);
|
||||
static void ObjectEventSetGraphics(struct ObjectEvent *, const struct ObjectEventGraphicsInfo *);
|
||||
static void SpriteCB_VirtualObject(struct Sprite *);
|
||||
static void DoShadowFieldEffect(struct ObjectEvent *);
|
||||
@@ -545,7 +546,10 @@ static const struct SpritePalette sObjectEventSpritePalettes[] = {
|
||||
#endif //ITEM_STRANGE_BALL
|
||||
#endif //OW_FOLLOWERS_POKEBALLS
|
||||
{gObjectEventPal_Substitute, OBJ_EVENT_PAL_TAG_SUBSTITUTE},
|
||||
{gObjectEventPaletteLight, OBJ_EVENT_PAL_TAG_LIGHT},
|
||||
{gObjectEventPaletteLight2, OBJ_EVENT_PAL_TAG_LIGHT_2},
|
||||
{gObjectEventPaletteEmotes, OBJ_EVENT_PAL_TAG_EMOTES},
|
||||
{gObjectEventPaletteNeonLight, OBJ_EVENT_PAL_TAG_NEON_LIGHT},
|
||||
#ifdef BUGFIX
|
||||
{NULL, OBJ_EVENT_PAL_TAG_NONE},
|
||||
#else
|
||||
@@ -1348,7 +1352,7 @@ u8 GetFirstInactiveObjectEventId(void)
|
||||
|
||||
u8 GetObjectEventIdByLocalIdAndMap(u8 localId, u8 mapNum, u8 mapGroupId)
|
||||
{
|
||||
if (localId < OBJ_EVENT_ID_FOLLOWER)
|
||||
if (localId < OBJ_EVENT_ID_DYNAMIC_BASE)
|
||||
return GetObjectEventIdByLocalIdAndMapInternal(localId, mapNum, mapGroupId);
|
||||
|
||||
return GetObjectEventIdByLocalId(localId);
|
||||
@@ -1833,7 +1837,7 @@ static u32 LoadDynamicFollowerPaletteFromGraphicsId(u16 graphicsId, struct Sprit
|
||||
}
|
||||
|
||||
// Used to create a sprite using a graphicsId associated with object events.
|
||||
u8 CreateObjectGraphicsSprite(u16 graphicsId, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority)
|
||||
u8 CreateObjectGraphicsSpriteWithTag(u16 graphicsId, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority, u16 paletteTag)
|
||||
{
|
||||
struct SpriteTemplate *spriteTemplate;
|
||||
const struct SubspriteTable *subspriteTables;
|
||||
@@ -1880,6 +1884,11 @@ u8 CreateObjectGraphicsSprite(u16 graphicsId, void (*callback)(struct Sprite *),
|
||||
return spriteId;
|
||||
}
|
||||
|
||||
u8 CreateObjectGraphicsSprite(u16 graphicsId, void (*callback)(struct Sprite *), s16 x, s16 y, u8 subpriority)
|
||||
{
|
||||
return CreateObjectGraphicsSpriteWithTag(graphicsId, callback, x, y, subpriority, TAG_NONE);
|
||||
}
|
||||
|
||||
#define sVirtualObjId data[0]
|
||||
#define sVirtualObjElev data[1]
|
||||
|
||||
@@ -1935,12 +1944,10 @@ struct Pokemon *GetFirstLiveMon(void)
|
||||
for (i = 0; i < PARTY_SIZE; i++)
|
||||
{
|
||||
struct Pokemon *mon = &gPlayerParty[i];
|
||||
if ((OW_MON_ALLOWED_SPECIES && GetMonData(mon, MON_DATA_SPECIES_OR_EGG) != VarGet(OW_MON_ALLOWED_SPECIES))
|
||||
|| (OW_MON_ALLOWED_MET_LVL && GetMonData(mon, MON_DATA_MET_LEVEL) != VarGet(OW_MON_ALLOWED_MET_LVL))
|
||||
|| (OW_MON_ALLOWED_MET_LOC && GetMonData(mon, MON_DATA_MET_LOCATION) != VarGet(OW_MON_ALLOWED_MET_LOC)))
|
||||
{
|
||||
if ((OW_FOLLOWERS_ALLOWED_SPECIES && GetMonData(mon, MON_DATA_SPECIES_OR_EGG) != VarGet(OW_FOLLOWERS_ALLOWED_SPECIES))
|
||||
|| (OW_FOLLOWERS_ALLOWED_MET_LVL && GetMonData(mon, MON_DATA_MET_LEVEL) != VarGet(OW_FOLLOWERS_ALLOWED_MET_LVL))
|
||||
|| (OW_FOLLOWERS_ALLOWED_MET_LOC && GetMonData(mon, MON_DATA_MET_LOCATION) != VarGet(OW_FOLLOWERS_ALLOWED_MET_LOC)))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gPlayerParty[i].hp > 0 && !(gPlayerParty[i].box.isEgg || gPlayerParty[i].box.isBadEgg))
|
||||
return &gPlayerParty[i];
|
||||
@@ -2061,7 +2068,7 @@ static u32 LoadDynamicFollowerPalette(u32 species, bool32 shiny, bool32 female)
|
||||
}
|
||||
|
||||
if (gWeatherPtr->currWeather != WEATHER_FOG_HORIZONTAL) // don't want to weather blend in fog
|
||||
UpdateSpritePaletteWithWeather(paletteNum);
|
||||
UpdateSpritePaletteWithWeather(paletteNum, FALSE);
|
||||
return paletteNum;
|
||||
}
|
||||
|
||||
@@ -2080,10 +2087,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);
|
||||
}
|
||||
}
|
||||
|
||||
// Like FollowerSetGraphics, but does not recenter sprite on a metatile
|
||||
@@ -2128,7 +2131,7 @@ static void RefreshFollowerGraphics(struct ObjectEvent *objEvent)
|
||||
{
|
||||
UpdateSpritePalette(&sObjectEventSpritePalettes[i], sprite);
|
||||
if (gWeatherPtr->currWeather != WEATHER_FOG_HORIZONTAL) // don't want to weather blend in fog
|
||||
UpdateSpritePaletteWithWeather(sprite->oam.paletteNum);
|
||||
UpdateSpritePaletteWithWeather(sprite->oam.paletteNum, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2341,9 +2344,15 @@ bool32 CheckMsgCondition(const struct MsgCondition *cond, struct Pokemon *mon, u
|
||||
return (multi == cond->data.bytes[0] || multi == cond->data.bytes[1]);
|
||||
case MSG_COND_MUSIC:
|
||||
return (cond->data.raw == GetCurrentMapMusic());
|
||||
// Added on `lighting` branch
|
||||
// case MSG_COND_TIME_OF_DAY:
|
||||
// break;
|
||||
case MSG_COND_TIME_OF_DAY:
|
||||
{
|
||||
// Must match time of day, have natural light on the map,
|
||||
// and not have weather that obscures the sky
|
||||
u32 weather = GetCurrentWeather();
|
||||
return (cond->data.raw == gTimeOfDay
|
||||
&& MapHasNaturalLight(gMapHeader.mapType)
|
||||
&& (weather == WEATHER_NONE || weather == WEATHER_SUNNY_CLOUDS || weather == WEATHER_SUNNY));
|
||||
}
|
||||
case MSG_COND_NEAR_MB:
|
||||
multi = FindMetatileBehaviorWithinRange(obj->currentCoords.x,
|
||||
obj->currentCoords.y,
|
||||
@@ -2563,6 +2572,156 @@ void GetFollowerAction(struct ScriptContext *ctx) // Essentially a big switch fo
|
||||
gFollowerBasicMessages[emotion].script);
|
||||
}
|
||||
|
||||
#define sLightType data[5]
|
||||
#define sLightXPos data[6]
|
||||
#define sLightYPos data[7]
|
||||
|
||||
// Sprite 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->sLightXPos;
|
||||
s16 y = sprite->sLightYPos;
|
||||
u16 sheetTileStart;
|
||||
u32 paletteNum;
|
||||
if (!(x >= left && x <= right && y >= top && y <= bottom))
|
||||
{
|
||||
sheetTileStart = sprite->sheetTileStart;
|
||||
paletteNum = sprite->oam.paletteNum;
|
||||
DestroySprite(sprite);
|
||||
FieldEffectFreeTilesIfUnused(sheetTileStart);
|
||||
FieldEffectFreePaletteIfUnused(paletteNum);
|
||||
Weather_SetBlendCoeffs(7, BASE_SHADOW_INTENSITY); // TODO: Restore original blend coeffs at dawn
|
||||
return;
|
||||
}
|
||||
|
||||
if (gTimeOfDay != TIME_NIGHT)
|
||||
{
|
||||
sprite->invisible = TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
// Note: Don't set window registers during hardware fade!
|
||||
switch (sprite->sLightType)
|
||||
{
|
||||
default:
|
||||
case LIGHT_TYPE_BALL:
|
||||
if (gPaletteFade.active) // if palette fade is active, don't flicker since the timer won't be updated
|
||||
{
|
||||
Weather_SetBlendCoeffs(7, BASE_SHADOW_INTENSITY);
|
||||
sprite->invisible = FALSE;
|
||||
}
|
||||
else if (gPlayerAvatar.tileTransitionState)
|
||||
{
|
||||
Weather_SetBlendCoeffs(7, BASE_SHADOW_INTENSITY); // As long as the second coefficient stays 12, shadows will not change
|
||||
sprite->invisible = FALSE;
|
||||
if (GetSpritePaletteTagByPaletteNum(sprite->oam.paletteNum) == OBJ_EVENT_PAL_TAG_LIGHT_2)
|
||||
LoadSpritePaletteInSlot(&sObjectEventSpritePalettes[FindObjectEventPaletteIndexByTag(OBJ_EVENT_PAL_TAG_LIGHT)], sprite->oam.paletteNum);
|
||||
}
|
||||
else if ((sprite->invisible = gTimeUpdateCounter & 1))
|
||||
{
|
||||
Weather_SetBlendCoeffs(7, BASE_SHADOW_INTENSITY);
|
||||
sprite->invisible = FALSE;
|
||||
if (GetSpritePaletteTagByPaletteNum(sprite->oam.paletteNum) == OBJ_EVENT_PAL_TAG_LIGHT_2)
|
||||
LoadSpritePaletteInSlot(&sObjectEventSpritePalettes[FindObjectEventPaletteIndexByTag(OBJ_EVENT_PAL_TAG_LIGHT)], sprite->oam.paletteNum);
|
||||
}
|
||||
break;
|
||||
case LIGHT_TYPE_PKMN_CENTER_SIGN:
|
||||
case LIGHT_TYPE_POKE_MART_SIGN:
|
||||
Weather_SetBlendCoeffs(12, BASE_SHADOW_INTENSITY);
|
||||
sprite->invisible = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Spawn a light at a map coordinate
|
||||
static void SpawnLightSprite(s16 x, s16 y, s16 camX, s16 camY, u32 lightType)
|
||||
{
|
||||
struct Sprite *sprite;
|
||||
const struct SpriteTemplate *template;
|
||||
u32 i;
|
||||
for (i = 0; i < MAX_SPRITES; i++)
|
||||
{
|
||||
sprite = &gSprites[i];
|
||||
if (sprite->inUse && sprite->callback == UpdateLightSprite && sprite->sLightXPos == x && sprite->sLightYPos == y)
|
||||
return;
|
||||
}
|
||||
lightType = min(lightType, ARRAY_COUNT(gFieldEffectLightTemplates) - 1); // bounds checking
|
||||
template = gFieldEffectLightTemplates[lightType];
|
||||
LoadSpriteSheetByTemplate(template, 0, 0);
|
||||
sprite = &gSprites[CreateSprite(template, 0, 0, 0)];
|
||||
if (lightType == 0 && (i = IndexOfSpritePaletteTag(template->paletteTag + 1)) < 16)
|
||||
sprite->oam.paletteNum = i;
|
||||
else
|
||||
UpdateSpritePaletteByTemplate(template, sprite);
|
||||
GetMapCoordsFromSpritePos(x + camX, y + camY, &sprite->x, &sprite->y);
|
||||
sprite->sLightType = lightType;
|
||||
sprite->sLightXPos = x;
|
||||
sprite->sLightYPos = y;
|
||||
sprite->affineAnims = gDummySpriteAffineAnimTable;
|
||||
sprite->affineAnimBeginning = TRUE;
|
||||
sprite->coordOffsetEnabled = TRUE;
|
||||
switch (lightType)
|
||||
{
|
||||
default:
|
||||
case LIGHT_TYPE_BALL:
|
||||
sprite->centerToCornerVecX = -(32 >> 1);
|
||||
sprite->centerToCornerVecY = -(32 >> 1);
|
||||
sprite->oam.priority = 1;
|
||||
sprite->oam.objMode = ST_OAM_OBJ_BLEND;
|
||||
sprite->oam.affineMode = ST_OAM_AFFINE_NORMAL;
|
||||
sprite->x += 8;
|
||||
sprite->y += 22 + sprite->centerToCornerVecY;
|
||||
break;
|
||||
case LIGHT_TYPE_PKMN_CENTER_SIGN:
|
||||
case LIGHT_TYPE_POKE_MART_SIGN:
|
||||
sprite->centerToCornerVecX = -(16 >> 1);
|
||||
sprite->centerToCornerVecY = -(16 >> 1);
|
||||
sprite->oam.priority = 2;
|
||||
sprite->subpriority = 0xFF;
|
||||
sprite->oam.objMode = ST_OAM_OBJ_BLEND;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#undef sLightType
|
||||
#undef sLightXPos
|
||||
#undef sLightYPos
|
||||
|
||||
void TrySpawnLightSprites(s16 camX, s16 camY)
|
||||
{
|
||||
u32 i;
|
||||
u8 objectCount;
|
||||
s16 left = gSaveBlock1Ptr->pos.x - 2;
|
||||
s16 right = gSaveBlock1Ptr->pos.x + MAP_OFFSET_W + 2;
|
||||
s16 top = gSaveBlock1Ptr->pos.y;
|
||||
s16 bottom = gSaveBlock1Ptr->pos.y + MAP_OFFSET_H + 2;
|
||||
if (gMapHeader.events == NULL)
|
||||
return;
|
||||
|
||||
if (InBattlePyramid())
|
||||
objectCount = GetNumBattlePyramidObjectEvents();
|
||||
else if (InTrainerHill())
|
||||
objectCount = 2;
|
||||
else
|
||||
objectCount = gMapHeader.events->objectEventCount;
|
||||
|
||||
for (i = 0; i < objectCount; i++)
|
||||
{
|
||||
struct ObjectEventTemplate *template = &gSaveBlock1Ptr->objectEventTemplates[i];
|
||||
s16 npcX = template->x + MAP_OFFSET;
|
||||
s16 npcY = template->y + MAP_OFFSET;
|
||||
if (top <= npcY && bottom >= npcY
|
||||
&& left <= npcX && right >= npcX
|
||||
&& !FlagGet(template->flagId)
|
||||
&& template->graphicsId == OBJ_EVENT_GFX_LIGHT_SPRITE) // event is light sprite instead
|
||||
SpawnLightSprite(npcX, npcY, camX, camY, template->trainerRange_berryTreeId);
|
||||
}
|
||||
}
|
||||
|
||||
void TrySpawnObjectEvents(s16 cameraX, s16 cameraY)
|
||||
{
|
||||
u8 i;
|
||||
@@ -2588,9 +2747,13 @@ void TrySpawnObjectEvents(s16 cameraX, s16 cameraY)
|
||||
s16 npcX = template->x + MAP_OFFSET;
|
||||
s16 npcY = template->y + MAP_OFFSET;
|
||||
|
||||
if (top <= npcY && bottom >= npcY && left <= npcX && right >= npcX
|
||||
&& !FlagGet(template->flagId))
|
||||
TrySpawnObjectEventTemplate(template, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, cameraX, cameraY);
|
||||
if (top <= npcY && bottom >= npcY && left <= npcX && right >= npcX && !FlagGet(template->flagId))
|
||||
{
|
||||
if (template->graphicsId == OBJ_EVENT_GFX_LIGHT_SPRITE)
|
||||
SpawnLightSprite(npcX, npcY, cameraX, cameraY, template->trainerRange_berryTreeId); // light sprite instead
|
||||
else
|
||||
TrySpawnObjectEventTemplate(template, gSaveBlock1Ptr->location.mapNum, gSaveBlock1Ptr->location.mapGroup, cameraX, cameraY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2646,6 +2809,7 @@ void SpawnObjectEventsOnReturnToField(s16 x, s16 y)
|
||||
SpawnObjectEventOnReturnToField(i, x, y);
|
||||
}
|
||||
CreateReflectionEffectSprites();
|
||||
TrySpawnLightSprites(x, y);
|
||||
}
|
||||
|
||||
static void SpawnObjectEventOnReturnToField(u8 objectEventId, s16 x, s16 y)
|
||||
@@ -2720,7 +2884,7 @@ static void ResetObjectEventFldEffData(struct ObjectEvent *objectEvent)
|
||||
{
|
||||
objectEvent->singleMovementActive = FALSE;
|
||||
objectEvent->triggerGroundEffectsOnMove = TRUE;
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
objectEvent->hasReflection = FALSE;
|
||||
objectEvent->inShortGrass = FALSE;
|
||||
objectEvent->inShallowFlowingWater = FALSE;
|
||||
@@ -2744,7 +2908,17 @@ static u8 UpdateSpritePalette(const struct SpritePalette *spritePalette, struct
|
||||
sprite->inUse = FALSE;
|
||||
FieldEffectFreePaletteIfUnused(sprite->oam.paletteNum);
|
||||
sprite->inUse = TRUE;
|
||||
return sprite->oam.paletteNum = LoadSpritePalette(spritePalette);
|
||||
if (IndexOfSpritePaletteTag(spritePalette->tag) == 0xFF)
|
||||
{
|
||||
sprite->oam.paletteNum = LoadSpritePalette(spritePalette);
|
||||
UpdateSpritePaletteWithWeather(sprite->oam.paletteNum, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite->oam.paletteNum = LoadSpritePalette(spritePalette);
|
||||
}
|
||||
|
||||
return sprite->oam.paletteNum;
|
||||
}
|
||||
|
||||
// Find and update based on template's paletteTag
|
||||
@@ -2999,12 +3173,15 @@ static void UNUSED LoadObjectEventPaletteSet(u16 *paletteTags)
|
||||
LoadObjectEventPalette(paletteTags[i]);
|
||||
}
|
||||
|
||||
// Really just loads the palette and applies weather fade
|
||||
static u8 LoadSpritePaletteIfTagExists(const struct SpritePalette *spritePalette)
|
||||
{
|
||||
u8 paletteNum = IndexOfSpritePaletteTag(spritePalette->tag);
|
||||
if (paletteNum != 0xFF) // don't load twice; return
|
||||
return paletteNum;
|
||||
paletteNum = LoadSpritePalette(spritePalette);
|
||||
if (paletteNum != 0xFF)
|
||||
UpdateSpritePaletteWithWeather(paletteNum, FALSE);
|
||||
return paletteNum;
|
||||
}
|
||||
|
||||
@@ -5542,7 +5719,7 @@ bool8 FollowablePlayerMovement_Step(struct ObjectEvent *objectEvent, struct Spri
|
||||
direction = gObjectEvents[gPlayerAvatar.objectEventId].movementDirection;
|
||||
objectEvent->facingDirectionLocked = TRUE;
|
||||
}
|
||||
|
||||
|
||||
MoveCoords(direction, &x, &y);
|
||||
GetCollisionAtCoords(objectEvent, x, y, direction); // Sets directionOverwrite for stairs
|
||||
if (GetLedgeJumpDirection(x, y, direction) != DIR_NONE)
|
||||
@@ -7050,6 +7227,8 @@ static void InitJump(struct ObjectEvent *objectEvent, struct Sprite *sprite, u8
|
||||
|
||||
static void InitJumpRegular(struct ObjectEvent *objectEvent, struct Sprite *sprite, u8 direction, u8 distance, u8 type)
|
||||
{
|
||||
if (OW_OBJECT_VANILLA_SHADOWS)
|
||||
SetUpShadow(objectEvent);
|
||||
// For follower only, match the anim duration of the player's movement, whether dashing, walking or jumping
|
||||
if (objectEvent->localId == OBJ_EVENT_ID_FOLLOWER
|
||||
&& type == JUMP_TYPE_HIGH
|
||||
@@ -7088,6 +7267,10 @@ static u8 UpdateJumpAnim(struct ObjectEvent *objectEvent, struct Sprite *sprite,
|
||||
objectEvent->triggerGroundEffectsOnStop = TRUE;
|
||||
objectEvent->landingJump = TRUE;
|
||||
sprite->animPaused = TRUE;
|
||||
if (OW_OBJECT_VANILLA_SHADOWS)
|
||||
// Somewhat ugly workaround, the shadow is disabled in UpdateShadowFieldEffect,
|
||||
// but due to code changes from DNS, it needs new signaling
|
||||
objectEvent->jumpDone = TRUE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -7144,7 +7327,7 @@ bool8 MovementAction_Jump2Down_Step1(struct ObjectEvent *objectEvent, struct Spr
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -7161,7 +7344,7 @@ bool8 MovementAction_Jump2Up_Step1(struct ObjectEvent *objectEvent, struct Sprit
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -7178,7 +7361,7 @@ bool8 MovementAction_Jump2Left_Step1(struct ObjectEvent *objectEvent, struct Spr
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -7195,7 +7378,7 @@ bool8 MovementAction_Jump2Right_Step1(struct ObjectEvent *objectEvent, struct Sp
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8081,7 +8264,7 @@ bool8 MovementAction_JumpDown_Step1(struct ObjectEvent *objectEvent, struct Spri
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = 0;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8098,7 +8281,7 @@ bool8 MovementAction_JumpUp_Step1(struct ObjectEvent *objectEvent, struct Sprite
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = 0;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8115,7 +8298,7 @@ bool8 MovementAction_JumpLeft_Step1(struct ObjectEvent *objectEvent, struct Spri
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = 0;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8132,7 +8315,7 @@ bool8 MovementAction_JumpRight_Step1(struct ObjectEvent *objectEvent, struct Spr
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = 0;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8149,7 +8332,7 @@ bool8 MovementAction_JumpInPlaceDown_Step1(struct ObjectEvent *objectEvent, stru
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = 0;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8166,7 +8349,7 @@ bool8 MovementAction_JumpInPlaceUp_Step1(struct ObjectEvent *objectEvent, struct
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = 0;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8183,7 +8366,7 @@ bool8 MovementAction_JumpInPlaceLeft_Step1(struct ObjectEvent *objectEvent, stru
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = 0;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8200,7 +8383,7 @@ bool8 MovementAction_JumpInPlaceRight_Step1(struct ObjectEvent *objectEvent, str
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = 0;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8217,7 +8400,7 @@ bool8 MovementAction_JumpInPlaceDownUp_Step1(struct ObjectEvent *objectEvent, st
|
||||
{
|
||||
if (DoJumpInPlaceAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = 0;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8234,7 +8417,7 @@ bool8 MovementAction_JumpInPlaceUpDown_Step1(struct ObjectEvent *objectEvent, st
|
||||
{
|
||||
if (DoJumpInPlaceAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = 0;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8251,7 +8434,7 @@ bool8 MovementAction_JumpInPlaceLeftRight_Step1(struct ObjectEvent *objectEvent,
|
||||
{
|
||||
if (DoJumpInPlaceAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = 0;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8268,7 +8451,7 @@ bool8 MovementAction_JumpInPlaceRightLeft_Step1(struct ObjectEvent *objectEvent,
|
||||
{
|
||||
if (DoJumpInPlaceAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = 0;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8713,7 +8896,7 @@ bool8 MovementAction_AcroWheelieHopFaceDown_Step1(struct ObjectEvent *objectEven
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8730,7 +8913,7 @@ bool8 MovementAction_AcroWheelieHopFaceUp_Step1(struct ObjectEvent *objectEvent,
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8747,7 +8930,7 @@ bool8 MovementAction_AcroWheelieHopFaceLeft_Step1(struct ObjectEvent *objectEven
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8764,7 +8947,7 @@ bool8 MovementAction_AcroWheelieHopFaceRight_Step1(struct ObjectEvent *objectEve
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8781,7 +8964,7 @@ bool8 MovementAction_AcroWheelieHopDown_Step1(struct ObjectEvent *objectEvent, s
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8798,7 +8981,7 @@ bool8 MovementAction_AcroWheelieHopUp_Step1(struct ObjectEvent *objectEvent, str
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8818,7 +9001,7 @@ bool8 MovementAction_AcroWheelieHopLeft_Step1(struct ObjectEvent *objectEvent, s
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8838,7 +9021,7 @@ bool8 MovementAction_AcroWheelieHopRight_Step1(struct ObjectEvent *objectEvent,
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8855,7 +9038,7 @@ bool8 MovementAction_AcroWheelieJumpDown_Step1(struct ObjectEvent *objectEvent,
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8872,7 +9055,7 @@ bool8 MovementAction_AcroWheelieJumpUp_Step1(struct ObjectEvent *objectEvent, st
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8892,7 +9075,7 @@ bool8 MovementAction_AcroWheelieJumpLeft_Step1(struct ObjectEvent *objectEvent,
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -8912,7 +9095,7 @@ bool8 MovementAction_AcroWheelieJumpRight_Step1(struct ObjectEvent *objectEvent,
|
||||
{
|
||||
if (DoJumpAnim(objectEvent, sprite))
|
||||
{
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
sprite->sActionFuncId = 2;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -10025,14 +10208,17 @@ static void (*const sGroundEffectFuncs[])(struct ObjectEvent *objEvent, struct S
|
||||
|
||||
static void DoFlaggedGroundEffects(struct ObjectEvent *objEvent, struct Sprite *sprite, u32 flags)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
u32 i;
|
||||
if (ObjectEventIsFarawayIslandMew(objEvent) == TRUE && !ShouldMewShakeGrass(objEvent))
|
||||
return;
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(sGroundEffectFuncs); i++, flags >>= 1)
|
||||
if (flags & 1)
|
||||
sGroundEffectFuncs[i](objEvent, sprite);
|
||||
if (!OW_OBJECT_VANILLA_SHADOWS && CurrentMapHasShadows() && !(gWeatherPtr->noShadows || objEvent->inHotSprings || objEvent->inSandPile || MetatileBehavior_IsPuddle(objEvent->currentMetatileBehavior)))
|
||||
{
|
||||
SetUpShadow(objEvent);
|
||||
}
|
||||
}
|
||||
|
||||
void filters_out_some_ground_effects(struct ObjectEvent *objEvent, u32 *flags)
|
||||
@@ -10791,9 +10977,9 @@ u32 StartFieldEffectForObjectEvent(u8 fieldEffectId, struct ObjectEvent *objectE
|
||||
|
||||
static void DoShadowFieldEffect(struct ObjectEvent *objectEvent)
|
||||
{
|
||||
if (!objectEvent->hasShadow)
|
||||
if (objectEvent->noShadow)
|
||||
{
|
||||
objectEvent->hasShadow = TRUE;
|
||||
objectEvent->noShadow = FALSE;
|
||||
StartFieldEffectForObjectEvent(FLDEFF_SHADOW, objectEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ void SetMewAboveGrass(void)
|
||||
gSprites[mew->spriteId].subpriority = 1;
|
||||
|
||||
LoadSpritePalette(&gSpritePalette_GeneralFieldEffect1);
|
||||
UpdateSpritePaletteWithWeather(IndexOfSpritePaletteTag(gSpritePalette_GeneralFieldEffect1.tag));
|
||||
UpdateSpritePaletteWithWeather(IndexOfSpritePaletteTag(gSpritePalette_GeneralFieldEffect1.tag), FALSE);
|
||||
|
||||
x = mew->currentCoords.x;
|
||||
y = mew->currentCoords.y;
|
||||
|
||||
@@ -791,9 +791,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));
|
||||
u32 paletteSlot = LoadSpritePalette(palette);
|
||||
(*script) += 4;
|
||||
SetPaletteColorMapType(paletteSlot + 16, T1_READ_8(*script));
|
||||
UpdateSpritePaletteWithWeather(paletteSlot, TRUE);
|
||||
(*script)++;
|
||||
}
|
||||
|
||||
void FieldEffectScript_LoadPalette(u8 **script)
|
||||
@@ -849,6 +851,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);
|
||||
}
|
||||
}
|
||||
@@ -1626,6 +1629,7 @@ static bool8 EscalatorWarpOut_WaitForPlayer(struct Task *task)
|
||||
if (!ObjectEventIsMovementOverridden(objectEvent) || ObjectEventClearHeldMovementIfFinished(objectEvent))
|
||||
{
|
||||
ObjectEventSetHeldMovement(objectEvent, GetFaceDirectionMovementAction(GetPlayerFacingDirection()));
|
||||
objectEvent->noShadow = TRUE; // hide shadow for cleaner movement
|
||||
task->tState++;
|
||||
task->data[2] = 0;
|
||||
task->data[3] = 0;
|
||||
@@ -1747,6 +1751,7 @@ static bool8 EscalatorWarpIn_Init(struct Task *task)
|
||||
u8 behavior;
|
||||
CameraObjectFreeze();
|
||||
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
||||
objectEvent->noShadow = TRUE;
|
||||
ObjectEventSetHeldMovement(objectEvent, GetFaceDirectionMovementAction(DIR_EAST));
|
||||
PlayerGetDestCoords(&x, &y);
|
||||
behavior = MapGridGetMetatileBehaviorAt(x, y);
|
||||
@@ -1843,6 +1848,7 @@ static bool8 EscalatorWarpIn_End(struct Task *task)
|
||||
{
|
||||
struct ObjectEvent *objectEvent;
|
||||
objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
||||
objectEvent->noShadow = FALSE;
|
||||
if (ObjectEventClearHeldMovementIfFinished(objectEvent))
|
||||
{
|
||||
CameraObjectReset();
|
||||
@@ -1995,6 +2001,7 @@ static bool8 LavaridgeGymB1FWarpEffect_Init(struct Task *task, struct ObjectEven
|
||||
SetCameraPanningCallback(NULL);
|
||||
gPlayerAvatar.preventStep = TRUE;
|
||||
objectEvent->fixedPriority = 1;
|
||||
objectEvent->noShadow = TRUE;
|
||||
task->data[1] = 1;
|
||||
task->data[0]++;
|
||||
if (objectEvent->localId == OBJ_EVENT_ID_PLAYER) // Hide follower before warping
|
||||
@@ -2191,6 +2198,7 @@ static bool8 LavaridgeGym1FWarpEffect_Init(struct Task *task, struct ObjectEvent
|
||||
CameraObjectFreeze();
|
||||
gPlayerAvatar.preventStep = TRUE;
|
||||
objectEvent->fixedPriority = 1;
|
||||
objectEvent->noShadow = TRUE;
|
||||
task->data[0]++;
|
||||
if (objectEvent->localId == OBJ_EVENT_ID_PLAYER) // Hide follower before warping
|
||||
HideFollowerForFieldEffect();
|
||||
@@ -3314,7 +3322,7 @@ static void FlyOutFieldEffect_FlyOffWithBird(struct Task *task)
|
||||
struct ObjectEvent *objectEvent = &gObjectEvents[gPlayerAvatar.objectEventId];
|
||||
ObjectEventClearHeldMovementIfActive(objectEvent);
|
||||
objectEvent->inanimate = FALSE;
|
||||
objectEvent->hasShadow = FALSE;
|
||||
objectEvent->noShadow = TRUE;
|
||||
SetFlyBirdPlayerSpriteId(task->tBirdSpriteId, objectEvent->spriteId);
|
||||
CameraObjectFreeze();
|
||||
task->tState++;
|
||||
@@ -3536,6 +3544,7 @@ static void FlyInFieldEffect_BirdSwoopDown(struct Task *task)
|
||||
ObjectEventTurn(objectEvent, DIR_WEST);
|
||||
StartSpriteAnim(&gSprites[objectEvent->spriteId], ANIM_GET_ON_OFF_POKEMON_WEST);
|
||||
objectEvent->invisible = FALSE;
|
||||
objectEvent->noShadow = TRUE;
|
||||
task->tBirdSpriteId = CreateFlyBirdSprite();
|
||||
StartFlyBirdSwoopDown(task->tBirdSpriteId);
|
||||
SetFlyBirdPlayerSpriteId(task->tBirdSpriteId, objectEvent->spriteId);
|
||||
|
||||
@@ -54,11 +54,11 @@ u32 FldEff_Shadow(void);
|
||||
#define sReflectionVerticalOffset data[2]
|
||||
#define sIsStillReflection data[7]
|
||||
|
||||
void SetUpShadow(struct ObjectEvent *objectEvent, struct Sprite *sprite)
|
||||
void SetUpShadow(struct ObjectEvent *objectEvent)
|
||||
{
|
||||
gFieldEffectArguments[0] = objectEvent->localId;
|
||||
gFieldEffectArguments[1] = gSaveBlock1Ptr->location.mapNum;
|
||||
gFieldEffectArguments[2] = gSaveBlock1Ptr->location.mapGroup;
|
||||
gFieldEffectArguments[1] = objectEvent->mapNum;
|
||||
gFieldEffectArguments[2] = objectEvent->mapGroup;
|
||||
FldEff_Shadow();
|
||||
}
|
||||
|
||||
@@ -114,15 +114,16 @@ static void LoadObjectReflectionPalette(struct ObjectEvent *objectEvent, struct
|
||||
// Apply a blue tint effect to a palette
|
||||
static void ApplyPondFilter(u8 paletteNum, u16 *dest)
|
||||
{
|
||||
u32 i, r, g, b;
|
||||
// CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32);
|
||||
u32 i;
|
||||
s32 r, g, b;
|
||||
u16 *src = gPlttBufferUnfaded + OBJ_PLTT_ID(paletteNum);
|
||||
*dest++ = *src++; // copy transparency
|
||||
for (i = 0; i < 16 - 1; i++)
|
||||
{
|
||||
r = GET_R(src[i]);
|
||||
g = GET_G(src[i]);
|
||||
b = GET_B(src[i]);
|
||||
u32 color = *src++;
|
||||
r = (color << 27) >> 27;
|
||||
g = (color << 22) >> 27;
|
||||
b = (color << 17) >> 27;
|
||||
b += 10;
|
||||
if (b > 31)
|
||||
b = 31;
|
||||
@@ -133,21 +134,22 @@ static void ApplyPondFilter(u8 paletteNum, u16 *dest)
|
||||
// Apply a ice tint effect to a palette
|
||||
static void ApplyIceFilter(u8 paletteNum, u16 *dest)
|
||||
{
|
||||
u32 i, r, g, b;
|
||||
// CpuCopy16(gPlttBufferUnfaded + 0x100 + paletteNum * 16, dest, 32);
|
||||
u32 i;
|
||||
s32 r, g, b;
|
||||
u16 *src = gPlttBufferUnfaded + OBJ_PLTT_ID(paletteNum);
|
||||
*dest++ = *src++; // copy transparency
|
||||
for (i = 0; i < 16 - 1; i++)
|
||||
{
|
||||
r = GET_R(src[i]);
|
||||
u32 color = *src++;
|
||||
r = (color << 27) >> 27;
|
||||
g = (color << 22) >> 27;
|
||||
b = (color << 17) >> 27;
|
||||
r -= 5;
|
||||
if (r > 31)
|
||||
if (r < 0)
|
||||
r = 0;
|
||||
g = GET_G(src[i]);
|
||||
g += 3;
|
||||
if (g > 31)
|
||||
g = 31;
|
||||
b = GET_B(src[i]);
|
||||
b += 16;
|
||||
if (b > 31)
|
||||
b = 31;
|
||||
@@ -171,7 +173,7 @@ static void LoadObjectRegularReflectionPalette(struct ObjectEvent *objectEvent,
|
||||
else
|
||||
ApplyIceFilter(mainSprite->oam.paletteNum, filteredData);
|
||||
paletteNum = LoadSpritePalette(&filteredPal);
|
||||
UpdateSpritePaletteWithWeather(paletteNum);
|
||||
UpdateSpritePaletteWithWeather(paletteNum, TRUE);
|
||||
}
|
||||
sprite->oam.paletteNum = paletteNum;
|
||||
sprite->oam.objMode = ST_OAM_OBJ_BLEND;
|
||||
@@ -185,7 +187,7 @@ static void LoadObjectHighBridgeReflectionPalette(struct ObjectEvent *objectEven
|
||||
struct SpritePalette bluePalette = {.tag = HIGH_BRIDGE_PAL_TAG, .data = blueData};
|
||||
CpuFill16(0x55C9, blueData, PLTT_SIZE_4BPP);
|
||||
sprite->oam.paletteNum = LoadSpritePalette(&bluePalette);
|
||||
UpdateSpritePaletteWithWeather(sprite->oam.paletteNum);
|
||||
UpdateSpritePaletteWithWeather(sprite->oam.paletteNum, TRUE);
|
||||
}
|
||||
|
||||
static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite)
|
||||
@@ -221,7 +223,7 @@ static void UpdateObjectReflectionSprite(struct Sprite *reflectionSprite)
|
||||
else
|
||||
ApplyIceFilter(mainSprite->oam.paletteNum, filteredData);
|
||||
paletteNum = LoadSpritePalette(&filteredPal);
|
||||
UpdateSpritePaletteWithWeather(paletteNum);
|
||||
UpdateSpritePaletteWithWeather(paletteNum, TRUE);
|
||||
}
|
||||
reflectionSprite->oam.paletteNum = paletteNum;
|
||||
}
|
||||
@@ -333,22 +335,26 @@ u32 FldEff_Shadow(void)
|
||||
u8 objectEventId;
|
||||
const struct ObjectEventGraphicsInfo *graphicsInfo;
|
||||
u8 spriteId;
|
||||
u8 i;
|
||||
for (i = 0; i < MAX_SPRITES; i++)
|
||||
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]);
|
||||
graphicsInfo = GetObjectEventGraphicsInfo(gObjectEvents[objectEventId].graphicsId);
|
||||
if (graphicsInfo->shadowSize == SHADOW_SIZE_NONE) // don't create a shadow at all
|
||||
return 0;
|
||||
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[sShadowEffectTemplateIds[graphicsInfo->shadowSize]], 0, 0, 0x94);
|
||||
LoadSpriteSheetByTemplate(gFieldEffectObjectTemplatePointers[sShadowEffectTemplateIds[graphicsInfo->shadowSize]], 0, 0);
|
||||
spriteId = CreateSpriteAtEnd(gFieldEffectObjectTemplatePointers[sShadowEffectTemplateIds[graphicsInfo->shadowSize]], 0, 0, OW_OBJECT_SUBPRIORITY + 1);
|
||||
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];
|
||||
@@ -383,8 +389,19 @@ void UpdateShadowFieldEffect(struct Sprite *sprite)
|
||||
sprite->y = linkedSprite->y + sprite->sYOffset;
|
||||
#endif
|
||||
sprite->invisible = linkedSprite->invisible;
|
||||
if (!objectEvent->active || !objectEvent->hasShadow
|
||||
if (objectEvent->jumpDone)
|
||||
{
|
||||
// Ugly signaling to disable shadows after a jump
|
||||
objectEvent->noShadow = TRUE;
|
||||
objectEvent->jumpDone = FALSE;
|
||||
}
|
||||
if (!objectEvent->active
|
||||
|| objectEvent->noShadow
|
||||
|| objectEvent->inHotSprings
|
||||
|| objectEvent->inSandPile
|
||||
|| gWeatherPtr->noShadows
|
||||
|| MetatileBehavior_IsPokeGrass(objectEvent->currentMetatileBehavior)
|
||||
|| MetatileBehavior_IsPuddle(objectEvent->currentMetatileBehavior)
|
||||
|| MetatileBehavior_IsSurfableWaterOrUnderwater(objectEvent->currentMetatileBehavior)
|
||||
|| MetatileBehavior_IsSurfableWaterOrUnderwater(objectEvent->previousMetatileBehavior))
|
||||
{
|
||||
@@ -1516,7 +1533,7 @@ static u32 ShowDisguiseFieldEffect(u8 fldEff, u8 fldEffObj, u8 paletteNum)
|
||||
if (spriteId != MAX_SPRITES)
|
||||
{
|
||||
struct Sprite *sprite = &gSprites[spriteId];
|
||||
UpdateSpritePaletteByTemplate(gFieldEffectObjectTemplatePointers[fldEffObj], sprite);
|
||||
sprite->oam.paletteNum = LoadObjectEventPalette(gFieldEffectObjectTemplatePointers[fldEffObj]->paletteTag);
|
||||
sprite->coordOffsetEnabled ++;
|
||||
sprite->sFldEff = fldEff;
|
||||
sprite->sLocalId = gFieldEffectArguments[0];
|
||||
|
||||
@@ -1157,6 +1157,7 @@ static void Task_OrbEffect(u8 taskId)
|
||||
ClearGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_WIN1_ON);
|
||||
SetGpuRegBits(REG_OFFSET_BLDCNT, gOrbEffectBackgroundLayerFlags[0]);
|
||||
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(12, 7));
|
||||
UpdateShadowColor(RGB(9, 8, 8));
|
||||
SetGpuReg(REG_OFFSET_WININ, WININ_WIN0_BG_ALL | WININ_WIN0_OBJ | WININ_WIN0_CLR);
|
||||
SetGpuReg(REG_OFFSET_WINOUT, WINOUT_WIN01_BG1 | WINOUT_WIN01_BG2 | WINOUT_WIN01_BG3 | WINOUT_WIN01_OBJ);
|
||||
SetBgTilemapPalette(0, 0, 0, DISPLAY_TILE_WIDTH, DISPLAY_TILE_HEIGHT, 0xF);
|
||||
@@ -1224,6 +1225,7 @@ static void Task_OrbEffect(u8 taskId)
|
||||
SetGpuReg(REG_OFFSET_DISPCNT, tDispCnt);
|
||||
SetGpuReg(REG_OFFSET_BLDCNT, tBldCnt);
|
||||
SetGpuReg(REG_OFFSET_BLDALPHA, tBldAlpha);
|
||||
UpdateShadowColor(RGB_BLACK);
|
||||
SetGpuReg(REG_OFFSET_WININ, tWinIn);
|
||||
SetGpuReg(REG_OFFSET_WINOUT, tWinOut);
|
||||
ScriptContext_Enable();
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
#include "constants/battle_frontier.h"
|
||||
#include "constants/weather.h"
|
||||
#include "constants/metatile_labels.h"
|
||||
#include "constants/rgb.h"
|
||||
#include "palette.h"
|
||||
#include "battle_util.h"
|
||||
#include "naming_screen.h"
|
||||
@@ -3281,6 +3282,7 @@ static void ChangeDeoxysRockLevel(u8 rockLevel)
|
||||
{
|
||||
u8 paletteNum = IndexOfSpritePaletteTag(OBJ_EVENT_PAL_TAG_BIRTH_ISLAND_STONE);
|
||||
LoadPalette(&sDeoxysRockPalettes[rockLevel], OBJ_PLTT_ID(paletteNum), PLTT_SIZEOF(4));
|
||||
UpdateSpritePaletteWithWeather(paletteNum, FALSE);
|
||||
|
||||
if (rockLevel == 0)
|
||||
PlaySE(SE_M_CONFUSE_RAY); // Failure sound
|
||||
@@ -3332,7 +3334,7 @@ void SetDeoxysRockPalette(void)
|
||||
u32 paletteNum = IndexOfSpritePaletteTag(OBJ_EVENT_PAL_TAG_BIRTH_ISLAND_STONE);
|
||||
LoadPalette(&sDeoxysRockPalettes[(u8)VarGet(VAR_DEOXYS_ROCK_LEVEL)], OBJ_PLTT_ID(paletteNum), PLTT_SIZEOF(4));
|
||||
// Set faded to all black, weather blending handled during fade-in
|
||||
CpuFill16(0, &gPlttBufferFaded[OBJ_PLTT_ID(paletteNum)], 32);
|
||||
CpuFill16(RGB_BLACK, &gPlttBufferFaded[OBJ_PLTT_ID(paletteNum)], PLTT_SIZE_4BPP);
|
||||
}
|
||||
|
||||
void SetPCBoxToSendMon(u8 boxId)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "constants/weather.h"
|
||||
#include "constants/rgb.h"
|
||||
#include "util.h"
|
||||
#include "decompress.h"
|
||||
#include "event_object_movement.h"
|
||||
#include "field_weather.h"
|
||||
#include "fieldmap.h"
|
||||
@@ -18,16 +19,10 @@
|
||||
#include "trig.h"
|
||||
#include "gpu_regs.h"
|
||||
#include "field_camera.h"
|
||||
#include "overworld.h"
|
||||
|
||||
#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;
|
||||
@@ -208,7 +203,7 @@ void StartWeather(void)
|
||||
sPaletteColorMapTypes = sBasePaletteColorMapTypes;
|
||||
|
||||
gWeatherPtr->contrastColorMapSpritePalIndex = index;
|
||||
gWeatherPtr->weatherPicSpritePalIndex = AllocSpritePalette(PALTAG_WEATHER_2);
|
||||
gWeatherPtr->weatherPicSpritePalIndex = 0xFF; // defer allocation until needed
|
||||
gWeatherPtr->rainSpriteCount = 0;
|
||||
gWeatherPtr->curRainSpriteIndex = 0;
|
||||
gWeatherPtr->cloudSpritesCreated = 0;
|
||||
@@ -318,7 +313,8 @@ static void Task_WeatherMain(u8 taskId)
|
||||
|
||||
static void None_Init(void)
|
||||
{
|
||||
Weather_SetBlendCoeffs(8, 12); // Indoor shadows
|
||||
Weather_SetBlendCoeffs(8, BASE_SHADOW_INTENSITY); // Indoor shadows
|
||||
gWeatherPtr->noShadows = FALSE;
|
||||
gWeatherPtr->targetColorMapIndex = 0;
|
||||
gWeatherPtr->colorMapStepDelay = 0;
|
||||
}
|
||||
@@ -458,18 +454,31 @@ static void ApplyColorMap(u8 startPalIndex, u8 numPalettes, s8 colorMapIndex)
|
||||
|
||||
if (colorMapIndex > 0)
|
||||
{
|
||||
// Create the palette mask
|
||||
u32 palettes = PALETTES_ALL;
|
||||
numPalettes += startPalIndex;
|
||||
palettes = (palettes >> startPalIndex) << startPalIndex;
|
||||
palettes = (palettes << (32 - numPalettes)) >> (32 - numPalettes);
|
||||
numPalettes -= startPalIndex;
|
||||
colorMapIndex--;
|
||||
palOffset = PLTT_ID(startPalIndex);
|
||||
UpdateAltBgPalettes(palettes & PALETTES_BG);
|
||||
// Thunder gamma-shift looks bad on night-blended palettes, so ignore time blending in some situations
|
||||
if (colorMapIndex <= 3 && MapHasNaturalLight(gMapHeader.mapType))
|
||||
UpdatePalettesWithTime(palettes);
|
||||
else
|
||||
CpuFastCopy(gPlttBufferUnfaded + palOffset, gPlttBufferFaded + palOffset, PLTT_SIZE_4BPP * numPalettes);
|
||||
numPalettes += startPalIndex;
|
||||
curPalIndex = startPalIndex;
|
||||
|
||||
// Loop through the specified palette range and apply necessary color maps.
|
||||
while (curPalIndex < numPalettes)
|
||||
{
|
||||
if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_NONE)
|
||||
// don't blend special palettes immune to blending
|
||||
if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_NONE ||
|
||||
(curPalIndex >= 16 && IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(curPalIndex - 16))))
|
||||
{
|
||||
// No palette change.
|
||||
CpuFastCopy(&gPlttBufferUnfaded[palOffset], &gPlttBufferFaded[palOffset], PLTT_SIZE_4BPP);
|
||||
palOffset += 16;
|
||||
}
|
||||
else
|
||||
@@ -484,7 +493,7 @@ static void ApplyColorMap(u8 startPalIndex, u8 numPalettes, s8 colorMapIndex)
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
// Apply color map to the original color.
|
||||
struct RGBColor baseColor = *(struct RGBColor *)&gPlttBufferUnfaded[palOffset];
|
||||
struct RGBColor baseColor = *(struct RGBColor *)&gPlttBufferFaded[palOffset];
|
||||
r = colorMap[baseColor.r];
|
||||
g = colorMap[baseColor.g];
|
||||
b = colorMap[baseColor.b];
|
||||
@@ -525,8 +534,17 @@ static void ApplyColorMap(u8 startPalIndex, u8 numPalettes, s8 colorMapIndex)
|
||||
}
|
||||
else
|
||||
{
|
||||
// No palette blending.
|
||||
CpuFastCopy(&gPlttBufferUnfaded[PLTT_ID(startPalIndex)], &gPlttBufferFaded[PLTT_ID(startPalIndex)], numPalettes * PLTT_SIZE_4BPP);
|
||||
if (MapHasNaturalLight(gMapHeader.mapType))
|
||||
{
|
||||
// Time-blend
|
||||
u32 palettes = ((1 << numPalettes) - 1) << startPalIndex;
|
||||
UpdateAltBgPalettes(palettes & PALETTES_BG);
|
||||
UpdatePalettesWithTime(palettes);
|
||||
}
|
||||
else
|
||||
{
|
||||
CpuFastCopy(&gPlttBufferUnfaded[PLTT_ID(startPalIndex)], &gPlttBufferFaded[PLTT_ID(startPalIndex)], numPalettes * PLTT_SIZE_4BPP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,10 +565,13 @@ static void ApplyColorMapWithBlend(u8 startPalIndex, u8 numPalettes, s8 colorMap
|
||||
|
||||
while (curPalIndex < numPalettes)
|
||||
{
|
||||
UpdateAltBgPalettes((1 << (palOffset >> 4)) & PALETTES_BG);
|
||||
CpuFastCopy(gPlttBufferUnfaded + palOffset, gPlttBufferFaded + palOffset, 16 * sizeof(u16));
|
||||
UpdatePalettesWithTime(1 << (palOffset >> 4)); // Apply TOD blend
|
||||
if (sPaletteColorMapTypes[curPalIndex] == COLOR_MAP_NONE)
|
||||
{
|
||||
// No color map. Simply blend the colors.
|
||||
BlendPalette(palOffset, 16, blendCoeff, blendColor);
|
||||
BlendPalettesFine(1, gPlttBufferFaded + palOffset, gPlttBufferFaded + palOffset, blendCoeff, blendColor);
|
||||
palOffset += 16;
|
||||
}
|
||||
else
|
||||
@@ -564,7 +585,7 @@ static void ApplyColorMapWithBlend(u8 startPalIndex, u8 numPalettes, s8 colorMap
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
struct RGBColor baseColor = *(struct RGBColor *)&gPlttBufferUnfaded[palOffset];
|
||||
struct RGBColor baseColor = *(struct RGBColor *)&gPlttBufferFaded[palOffset];
|
||||
u8 r = colorMap[baseColor.r];
|
||||
u8 g = colorMap[baseColor.g];
|
||||
u8 b = colorMap[baseColor.b];
|
||||
@@ -636,51 +657,28 @@ static void ApplyDroughtColorMapWithBlend(s8 colorMapIndex, u8 blendCoeff, u32 b
|
||||
}
|
||||
}
|
||||
|
||||
// This is only called during fade-in/fade-out in fog
|
||||
// blendCoeff & blendColor are the *fade* colors, not fog colors
|
||||
static void ApplyFogBlend(u8 blendCoeff, u32 blendColor)
|
||||
{
|
||||
struct RGBColor color;
|
||||
u8 rBlend;
|
||||
u8 gBlend;
|
||||
u8 bBlend;
|
||||
u16 curPalIndex;
|
||||
u32 curPalIndex;
|
||||
u16 fogCoeff = min((gTimeOfDay + 1) * 4, 12);
|
||||
|
||||
BlendPalette(BG_PLTT_ID(0), 16 * 16, blendCoeff, blendColor);
|
||||
color = *(struct RGBColor *)&blendColor;
|
||||
rBlend = color.r;
|
||||
gBlend = color.g;
|
||||
bBlend = color.b;
|
||||
// First blend all palettes with time
|
||||
UpdateAltBgPalettes(PALETTES_BG);
|
||||
CpuFastCopy(gPlttBufferUnfaded, gPlttBufferFaded, PLTT_BUFFER_SIZE * 2);
|
||||
UpdatePalettesWithTime(PALETTES_ALL);
|
||||
// Then blend tile palettes [0, 12] faded->faded with fadeIn color
|
||||
BlendPalettesFine(PALETTES_MAP, gPlttBufferFaded, gPlttBufferFaded, blendCoeff, blendColor);
|
||||
|
||||
// Do fog blending on marked sprite palettes
|
||||
for (curPalIndex = 16; curPalIndex < 32; curPalIndex++)
|
||||
{
|
||||
if (LightenSpritePaletteInFog(curPalIndex))
|
||||
{
|
||||
u16 palEnd = PLTT_ID(curPalIndex + 1);
|
||||
u16 palOffset = PLTT_ID(curPalIndex);
|
||||
|
||||
while (palOffset < palEnd)
|
||||
{
|
||||
struct RGBColor color = *(struct RGBColor *)&gPlttBufferUnfaded[palOffset];
|
||||
u8 r = color.r;
|
||||
u8 g = color.g;
|
||||
u8 b = color.b;
|
||||
|
||||
r += ((28 - r) * 3) >> 2;
|
||||
g += ((31 - g) * 3) >> 2;
|
||||
b += ((28 - b) * 3) >> 2;
|
||||
|
||||
r += ((rBlend - r) * blendCoeff) >> 4;
|
||||
g += ((gBlend - g) * blendCoeff) >> 4;
|
||||
b += ((bBlend - b) * blendCoeff) >> 4;
|
||||
|
||||
gPlttBufferFaded[palOffset] = RGB2(r, g, b);
|
||||
palOffset++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BlendPalette(PLTT_ID(curPalIndex), 16, blendCoeff, blendColor);
|
||||
}
|
||||
BlendPalettesFine(1, gPlttBufferFaded + PLTT_ID(curPalIndex), gPlttBufferFaded + PLTT_ID(curPalIndex), fogCoeff, RGB(28, 31, 28));
|
||||
}
|
||||
// Finally blend all sprite palettes faded->faded with fadeIn color
|
||||
BlendPalettesFine(PALETTES_OBJECTS, gPlttBufferFaded, gPlttBufferFaded, blendCoeff, blendColor);
|
||||
}
|
||||
|
||||
static void MarkFogSpritePalToLighten(u8 paletteIndex)
|
||||
@@ -694,7 +692,10 @@ static void MarkFogSpritePalToLighten(u8 paletteIndex)
|
||||
|
||||
static bool8 LightenSpritePaletteInFog(u8 paletteIndex)
|
||||
{
|
||||
u16 i;
|
||||
u32 i;
|
||||
|
||||
if (paletteIndex >= 16 && IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(paletteIndex - 16)))
|
||||
return FALSE;
|
||||
|
||||
for (i = 0; i < gWeatherPtr->lightenedFogSpritePalsCount; i++)
|
||||
{
|
||||
@@ -772,8 +773,10 @@ void FadeScreen(u8 mode, s8 delay)
|
||||
|
||||
if (fadeOut)
|
||||
{
|
||||
if (useWeatherPal)
|
||||
CpuFastCopy(gPlttBufferFaded, gPlttBufferUnfaded, PLTT_SIZE);
|
||||
// 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_BUFFER_SIZE * 2);
|
||||
|
||||
BeginNormalPaletteFade(PALETTES_ALL, delay, 0, 16, fadeColor);
|
||||
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_SCREEN_FADING_OUT;
|
||||
@@ -781,10 +784,20 @@ void FadeScreen(u8 mode, s8 delay)
|
||||
else
|
||||
{
|
||||
gWeatherPtr->fadeDestColor = fadeColor;
|
||||
UpdateTimeOfDay();
|
||||
if (useWeatherPal)
|
||||
gWeatherPtr->fadeScreenCounter = 0;
|
||||
{
|
||||
gWeatherPtr->fadeScreenCounter = 0; // Triggers gamma-shift-based fade-in
|
||||
}
|
||||
else if (MapHasNaturalLight(gMapHeader.mapType))
|
||||
{
|
||||
UpdateAltBgPalettes(PALETTES_BG);
|
||||
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;
|
||||
@@ -794,12 +807,41 @@ 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)
|
||||
void 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;
|
||||
}
|
||||
}
|
||||
|
||||
bool8 IsWeatherNotFadingIn(void)
|
||||
{
|
||||
return (gWeatherPtr->palProcessingState != WEATHER_PAL_STATE_SCREEN_FADING_IN);
|
||||
}
|
||||
|
||||
void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex)
|
||||
void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex, bool8 allowFog)
|
||||
{
|
||||
u16 paletteIndex = 16 + spritePaletteIndex;
|
||||
u16 i;
|
||||
@@ -826,20 +868,37 @@ void UpdateSpritePaletteWithWeather(u8 spritePaletteIndex)
|
||||
default:
|
||||
if (gWeatherPtr->currWeather != WEATHER_FOG_HORIZONTAL)
|
||||
{
|
||||
ApplyColorMap(paletteIndex, 1, gWeatherPtr->colorMapIndex);
|
||||
if (gWeatherPtr->colorMapIndex)
|
||||
ApplyColorMap(paletteIndex, 1, gWeatherPtr->colorMapIndex);
|
||||
else
|
||||
UpdateSpritePaletteWithTime(spritePaletteIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
paletteIndex = PLTT_ID(paletteIndex);
|
||||
BlendPalette(paletteIndex, 16, 12, RGB(28, 31, 28));
|
||||
// In horizontal fog, only specific palettes should be fog-blended
|
||||
if (allowFog)
|
||||
{
|
||||
i = min((gTimeOfDay + 1) * 4, 12); // fog coeff, highest in day and lowest at night
|
||||
paletteIndex = PLTT_ID(paletteIndex);
|
||||
// First blend with time
|
||||
CpuFastCopy(gPlttBufferUnfaded + paletteIndex, gPlttBufferFaded + paletteIndex, PLTT_SIZE_4BPP);
|
||||
UpdateSpritePaletteWithTime(spritePaletteIndex);
|
||||
// Then blend faded->faded with fog coeff
|
||||
BlendPalettesFine(1, gPlttBufferFaded + paletteIndex, gPlttBufferFaded + paletteIndex, i, RGB(28, 31, 28));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, just time-blend the palette
|
||||
UpdateSpritePaletteWithTime(spritePaletteIndex);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ApplyWeatherColorMapToPal(u8 paletteIndex)
|
||||
void ApplyWeatherColorMapToPals(u8 startPalIndex, u8 numPalettes)
|
||||
{
|
||||
ApplyColorMap(paletteIndex, 1, gWeatherPtr->colorMapIndex);
|
||||
ApplyColorMap(startPalIndex, numPalettes, gWeatherPtr->colorMapIndex);
|
||||
}
|
||||
|
||||
static bool8 UNUSED IsFirstFrameOfWeatherFadeIn(void)
|
||||
@@ -852,8 +911,11 @@ static bool8 UNUSED IsFirstFrameOfWeatherFadeIn(void)
|
||||
|
||||
void LoadCustomWeatherSpritePalette(const u16 *palette)
|
||||
{
|
||||
if (gWeatherPtr->weatherPicSpritePalIndex > 16 // haven't allocated palette yet
|
||||
&& (gWeatherPtr->weatherPicSpritePalIndex = AllocSpritePalette(PALTAG_WEATHER_2)) > 16)
|
||||
return;
|
||||
LoadPalette(palette, OBJ_PLTT_ID(gWeatherPtr->weatherPicSpritePalIndex), PLTT_SIZE_4BPP);
|
||||
UpdateSpritePaletteWithWeather(gWeatherPtr->weatherPicSpritePalIndex);
|
||||
UpdateSpritePaletteWithWeather(gWeatherPtr->weatherPicSpritePalIndex, TRUE);
|
||||
}
|
||||
|
||||
static void LoadDroughtWeatherPalette(u8 *palsIndex, u8 *palsOffset)
|
||||
@@ -934,7 +996,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)
|
||||
@@ -1084,11 +1149,29 @@ void SetWeatherPalStateIdle(void)
|
||||
gWeatherPtr->palProcessingState = WEATHER_PAL_STATE_IDLE;
|
||||
}
|
||||
|
||||
const u8 *SetPaletteColorMapType(u8 paletteIndex, enum ColorMapType 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 ResetPaletteColorMapType(u8 paletteIndex)
|
||||
{
|
||||
if (sPaletteColorMapTypes != sBasePaletteColorMapTypes)
|
||||
sFieldEffectPaletteColorMapTypes[paletteIndex] = sBasePaletteColorMapTypes[paletteIndex];
|
||||
}
|
||||
|
||||
void ResetPreservedPalettesInWeather(void)
|
||||
|
||||
@@ -8,11 +8,13 @@
|
||||
#include "script.h"
|
||||
#include "constants/weather.h"
|
||||
#include "constants/songs.h"
|
||||
#include "constants/rgb.h"
|
||||
#include "sound.h"
|
||||
#include "sprite.h"
|
||||
#include "task.h"
|
||||
#include "trig.h"
|
||||
#include "gpu_regs.h"
|
||||
#include "palette.h"
|
||||
|
||||
EWRAM_DATA static u8 sCurrentAbnormalWeather = 0;
|
||||
|
||||
@@ -93,6 +95,7 @@ static const struct SpriteTemplate sCloudSpriteTemplate =
|
||||
|
||||
void Clouds_InitVars(void)
|
||||
{
|
||||
gWeatherPtr->noShadows = FALSE;
|
||||
gWeatherPtr->targetColorMapIndex = 0;
|
||||
gWeatherPtr->colorMapStepDelay = 20;
|
||||
gWeatherPtr->weatherGfxLoaded = FALSE;
|
||||
@@ -149,11 +152,14 @@ bool8 Clouds_Finish(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
STATIC_ASSERT(OW_SHADOW_INTENSITY >= 0 && OW_SHADOW_INTENSITY <= 16, ObjEventShadowTransparencyNotInRange)
|
||||
|
||||
void Sunny_InitVars(void)
|
||||
{
|
||||
gWeatherPtr->targetColorMapIndex = 0;
|
||||
gWeatherPtr->colorMapStepDelay = 20;
|
||||
Weather_SetBlendCoeffs(8, 12);
|
||||
Weather_SetBlendCoeffs(8, BASE_SHADOW_INTENSITY); // preserve shadow darkness
|
||||
gWeatherPtr->noShadows = FALSE;
|
||||
}
|
||||
|
||||
void Sunny_InitAll(void)
|
||||
@@ -237,6 +243,7 @@ void Drought_InitVars(void)
|
||||
gWeatherPtr->weatherGfxLoaded = FALSE;
|
||||
gWeatherPtr->targetColorMapIndex = 0;
|
||||
gWeatherPtr->colorMapStepDelay = 0;
|
||||
gWeatherPtr->noShadows = FALSE;
|
||||
}
|
||||
|
||||
void Drought_InitAll(void)
|
||||
@@ -479,6 +486,8 @@ void Rain_InitVars(void)
|
||||
gWeatherPtr->targetColorMapIndex = 3;
|
||||
gWeatherPtr->colorMapStepDelay = 20;
|
||||
SetRainStrengthFromSoundEffect(SE_RAIN);
|
||||
Weather_SetBlendCoeffs(8, BASE_SHADOW_INTENSITY); // preserve shadow darkness
|
||||
gWeatherPtr->noShadows = FALSE;
|
||||
}
|
||||
|
||||
void Rain_InitAll(void)
|
||||
@@ -772,6 +781,8 @@ void Snow_InitVars(void)
|
||||
gWeatherPtr->colorMapStepDelay = 20;
|
||||
gWeatherPtr->targetSnowflakeSpriteCount = NUM_SNOWFLAKE_SPRITES;
|
||||
gWeatherPtr->snowflakeVisibleCounter = 0;
|
||||
Weather_SetBlendCoeffs(8, BASE_SHADOW_INTENSITY); // preserve shadow darkness
|
||||
gWeatherPtr->noShadows = FALSE;
|
||||
}
|
||||
|
||||
void Snow_InitAll(void)
|
||||
@@ -1019,6 +1030,8 @@ void Thunderstorm_InitVars(void)
|
||||
gWeatherPtr->weatherGfxLoaded = FALSE; // duplicate assignment
|
||||
gWeatherPtr->thunderEnqueued = FALSE;
|
||||
SetRainStrengthFromSoundEffect(SE_THUNDERSTORM);
|
||||
Weather_SetBlendCoeffs(8, BASE_SHADOW_INTENSITY); // preserve shadow darkness
|
||||
gWeatherPtr->noShadows = FALSE;
|
||||
}
|
||||
|
||||
void Thunderstorm_InitAll(void)
|
||||
@@ -1047,6 +1060,8 @@ void Downpour_InitVars(void)
|
||||
gWeatherPtr->colorMapStepDelay = 20;
|
||||
gWeatherPtr->weatherGfxLoaded = FALSE; // duplicate assignment
|
||||
SetRainStrengthFromSoundEffect(SE_DOWNPOUR);
|
||||
Weather_SetBlendCoeffs(8, BASE_SHADOW_INTENSITY); // preserve shadow darkness
|
||||
gWeatherPtr->noShadows = FALSE;
|
||||
}
|
||||
|
||||
void Downpour_InitAll(void)
|
||||
@@ -1339,6 +1354,26 @@ void FogHorizontal_Main(void);
|
||||
static void CreateFogHorizontalSprites(void);
|
||||
static void DestroyFogHorizontalSprites(void);
|
||||
|
||||
// Updates just the color of shadows to match special weather blending
|
||||
u8 UpdateShadowColor(u16 color)
|
||||
{
|
||||
u8 paletteNum = IndexOfSpritePaletteTag(TAG_WEATHER_START);
|
||||
u16 ALIGNED(4) tempBuffer[16];
|
||||
u16 blendedColor;
|
||||
if (paletteNum < 16)
|
||||
{
|
||||
u16 index = OBJ_PLTT_ID(paletteNum) + SHADOW_COLOR_INDEX;
|
||||
gPlttBufferUnfaded[index] = gPlttBufferFaded[index] = color;
|
||||
// Copy to temporary buffer, blend, and keep just the shadow color index
|
||||
CpuFastCopy(&gPlttBufferFaded[index - SHADOW_COLOR_INDEX], tempBuffer, PLTT_SIZE_4BPP);
|
||||
UpdateSpritePaletteWithTime(paletteNum);
|
||||
blendedColor = gPlttBufferFaded[index];
|
||||
CpuFastCopy(tempBuffer, &gPlttBufferFaded[index - SHADOW_COLOR_INDEX], PLTT_SIZE_4BPP);
|
||||
gPlttBufferFaded[index] = blendedColor;
|
||||
}
|
||||
return paletteNum;
|
||||
}
|
||||
|
||||
void FogHorizontal_InitVars(void)
|
||||
{
|
||||
gWeatherPtr->initStep = 0;
|
||||
@@ -1352,6 +1387,7 @@ void FogHorizontal_InitVars(void)
|
||||
gWeatherPtr->fogHScrollPosX = 0;
|
||||
Weather_SetBlendCoeffs(0, 16);
|
||||
}
|
||||
gWeatherPtr->noShadows = FALSE;
|
||||
}
|
||||
|
||||
void FogHorizontal_InitAll(void)
|
||||
@@ -1374,9 +1410,14 @@ void FogHorizontal_Main(void)
|
||||
case 0:
|
||||
CreateFogHorizontalSprites();
|
||||
if (gWeatherPtr->currWeather == WEATHER_FOG_HORIZONTAL)
|
||||
{
|
||||
Weather_SetTargetBlendCoeffs(12, 8, 3);
|
||||
UpdateShadowColor(RGB_GRAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
Weather_SetTargetBlendCoeffs(4, 16, 0);
|
||||
}
|
||||
gWeatherPtr->initStep++;
|
||||
break;
|
||||
case 1:
|
||||
@@ -1413,6 +1454,7 @@ bool8 FogHorizontal_Finish(void)
|
||||
gWeatherPtr->finishStep++;
|
||||
break;
|
||||
default:
|
||||
UpdateShadowColor(RGB_BLACK);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
@@ -1503,9 +1545,9 @@ void Ash_InitVars(void)
|
||||
gWeatherPtr->ashUnused = 20; // Never read
|
||||
if (!gWeatherPtr->ashSpritesCreated)
|
||||
{
|
||||
Weather_SetBlendCoeffs(0, 16);
|
||||
SetGpuReg(REG_OFFSET_BLDALPHA, BLDALPHA_BLEND(64, 63)); // These aren't valid blend coefficients!
|
||||
Weather_SetBlendCoeffs(0, BASE_SHADOW_INTENSITY);
|
||||
}
|
||||
gWeatherPtr->noShadows = FALSE;
|
||||
}
|
||||
|
||||
void Ash_InitAll(void)
|
||||
@@ -1531,7 +1573,7 @@ void Ash_Main(void)
|
||||
if (!gWeatherPtr->ashSpritesCreated)
|
||||
CreateAshSprites();
|
||||
|
||||
Weather_SetTargetBlendCoeffs(16, 0, 1);
|
||||
Weather_SetTargetBlendCoeffs(10, 12, 1);
|
||||
gWeatherPtr->initStep++;
|
||||
break;
|
||||
case 2:
|
||||
@@ -1552,7 +1594,7 @@ bool8 Ash_Finish(void)
|
||||
switch (gWeatherPtr->finishStep)
|
||||
{
|
||||
case 0:
|
||||
Weather_SetTargetBlendCoeffs(0, 16, 1);
|
||||
Weather_SetTargetBlendCoeffs(0, 12, 1);
|
||||
gWeatherPtr->finishStep++;
|
||||
break;
|
||||
case 1:
|
||||
@@ -1722,6 +1764,7 @@ void FogDiagonal_InitVars(void)
|
||||
gWeatherPtr->fogDPosY = 0;
|
||||
Weather_SetBlendCoeffs(0, 16);
|
||||
}
|
||||
gWeatherPtr->noShadows = TRUE;
|
||||
}
|
||||
|
||||
void FogDiagonal_InitAll(void)
|
||||
@@ -1935,6 +1978,7 @@ void Sandstorm_InitVars(void)
|
||||
|
||||
Weather_SetBlendCoeffs(0, 16);
|
||||
}
|
||||
gWeatherPtr->noShadows = FALSE;
|
||||
}
|
||||
|
||||
void Sandstorm_InitAll(void)
|
||||
@@ -1959,7 +2003,8 @@ void Sandstorm_Main(void)
|
||||
gWeatherPtr->initStep++;
|
||||
break;
|
||||
case 1:
|
||||
Weather_SetTargetBlendCoeffs(16, 0, 0);
|
||||
Weather_SetTargetBlendCoeffs(16, 2, 0);
|
||||
UpdateShadowColor(RGB_GRAY);
|
||||
gWeatherPtr->initStep++;
|
||||
break;
|
||||
case 2:
|
||||
@@ -1985,9 +2030,12 @@ bool8 Sandstorm_Finish(void)
|
||||
case 1:
|
||||
if (Weather_UpdateBlend())
|
||||
gWeatherPtr->finishStep++;
|
||||
if (gWeatherPtr->currBlendEVB == 12)
|
||||
UpdateShadowColor(RGB_BLACK);
|
||||
break;
|
||||
case 2:
|
||||
DestroySandstormSprites();
|
||||
UpdateShadowColor(RGB_BLACK);
|
||||
gWeatherPtr->finishStep++;
|
||||
break;
|
||||
default:
|
||||
@@ -2221,6 +2269,8 @@ void Shade_InitVars(void)
|
||||
gWeatherPtr->initStep = 0;
|
||||
gWeatherPtr->targetColorMapIndex = 3;
|
||||
gWeatherPtr->colorMapStepDelay = 20;
|
||||
Weather_SetBlendCoeffs(8, BASE_SHADOW_INTENSITY); // preserve shadow darkness
|
||||
gWeatherPtr->noShadows = FALSE;
|
||||
}
|
||||
|
||||
void Shade_InitAll(void)
|
||||
@@ -2282,6 +2332,7 @@ void Bubbles_InitVars(void)
|
||||
gWeatherPtr->bubblesCoordsIndex = 0;
|
||||
gWeatherPtr->bubblesSpriteCount = 0;
|
||||
}
|
||||
gWeatherPtr->noShadows = TRUE;
|
||||
}
|
||||
|
||||
void Bubbles_InitAll(void)
|
||||
|
||||
@@ -877,22 +877,27 @@ static void UNUSED ApplyGlobalTintToPaletteSlot(u8 slot, u8 count)
|
||||
|
||||
}
|
||||
|
||||
static void LoadTilesetPalette(struct Tileset const *tileset, u16 destOffset, u16 size)
|
||||
static void LoadTilesetPalette(struct Tileset const *tileset, u16 destOffset, u16 size, bool8 skipFaded)
|
||||
{
|
||||
u16 black = RGB_BLACK;
|
||||
|
||||
if (tileset)
|
||||
{
|
||||
if (tileset->isSecondary == FALSE)
|
||||
{
|
||||
LoadPalette(&black, destOffset, PLTT_SIZEOF(1));
|
||||
LoadPalette(tileset->palettes[0] + 1, destOffset + 1, size - PLTT_SIZEOF(1));
|
||||
ApplyGlobalTintToPaletteEntries(destOffset + 1, (size - PLTT_SIZEOF(1)) >> 1);
|
||||
if (skipFaded)
|
||||
CpuFastCopy(tileset->palettes, &gPlttBufferUnfaded[destOffset], size); // always word-aligned
|
||||
else
|
||||
LoadPaletteFast(tileset->palettes, destOffset, size);
|
||||
gPlttBufferFaded[destOffset] = gPlttBufferUnfaded[destOffset] = RGB_BLACK;
|
||||
ApplyGlobalTintToPaletteEntries(destOffset + 1, (size - 2) >> 1);
|
||||
}
|
||||
else if (tileset->isSecondary == TRUE)
|
||||
{
|
||||
LoadPalette(tileset->palettes[NUM_PALS_IN_PRIMARY], destOffset, size);
|
||||
ApplyGlobalTintToPaletteEntries(destOffset, size >> 1);
|
||||
// All 'gTilesetPalettes_' arrays should have ALIGNED(4) in them,
|
||||
// but we use SmartCopy here just in case they don't
|
||||
if (skipFaded)
|
||||
CpuCopy16(tileset->palettes[NUM_PALS_IN_PRIMARY], &gPlttBufferUnfaded[destOffset], size);
|
||||
else
|
||||
LoadPaletteFast(tileset->palettes[NUM_PALS_IN_PRIMARY], destOffset, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -919,12 +924,12 @@ void CopySecondaryTilesetToVramUsingHeap(struct MapLayout const *mapLayout)
|
||||
|
||||
static void LoadPrimaryTilesetPalette(struct MapLayout const *mapLayout)
|
||||
{
|
||||
LoadTilesetPalette(mapLayout->primaryTileset, BG_PLTT_ID(0), NUM_PALS_IN_PRIMARY * PLTT_SIZE_4BPP);
|
||||
LoadTilesetPalette(mapLayout->primaryTileset, 0, NUM_PALS_IN_PRIMARY * PLTT_SIZE_4BPP, FALSE);
|
||||
}
|
||||
|
||||
void LoadSecondaryTilesetPalette(struct MapLayout const *mapLayout)
|
||||
void LoadSecondaryTilesetPalette(struct MapLayout const *mapLayout, bool8 skipFaded)
|
||||
{
|
||||
LoadTilesetPalette(mapLayout->secondaryTileset, BG_PLTT_ID(NUM_PALS_IN_PRIMARY), (NUM_PALS_TOTAL - NUM_PALS_IN_PRIMARY) * PLTT_SIZE_4BPP);
|
||||
LoadTilesetPalette(mapLayout->secondaryTileset, NUM_PALS_IN_PRIMARY * 16, (NUM_PALS_TOTAL - NUM_PALS_IN_PRIMARY) * PLTT_SIZE_4BPP, skipFaded);
|
||||
}
|
||||
|
||||
void CopyMapTilesetsToVram(struct MapLayout const *mapLayout)
|
||||
@@ -941,6 +946,6 @@ void LoadMapTilesetPalettes(struct MapLayout const *mapLayout)
|
||||
if (mapLayout)
|
||||
{
|
||||
LoadPrimaryTilesetPalette(mapLayout);
|
||||
LoadSecondaryTilesetPalette(mapLayout);
|
||||
LoadSecondaryTilesetPalette(mapLayout, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#include "data.h"
|
||||
#include "event_scripts.h"
|
||||
#include "follower_helper.h"
|
||||
#include "overworld.h"
|
||||
#include "rtc.h"
|
||||
#include "constants/battle.h"
|
||||
#include "constants/followers.h"
|
||||
#include "constants/metatile_behaviors.h"
|
||||
@@ -66,6 +68,12 @@ static const u8 sCondMsg40[] = _("{STR_VAR_1} is gnawing at the ice.");
|
||||
static const u8 sCondMsg41[] = _("{STR_VAR_1} is touching the ice.");
|
||||
static const u8* const sIceTexts[] = {sCondMsg26, sCondMsg40, sCondMsg41, NULL};
|
||||
static const u8 sCondMsg42[] = _("{STR_VAR_1}'s burn looks painful!");
|
||||
static const u8 sCondMsg43[] = _("{STR_VAR_1} is happy to see what's\noutdoors!");
|
||||
static const u8 sCondMsg44[] = _("{STR_VAR_1} is looking up at the\nsky.");
|
||||
static const u8* const sDayTexts[] = {sCondMsg43, sCondMsg44, NULL};
|
||||
static const u8 sCondMsg45[] = _("Your POKéMON is staring spellbound\nat the night sky!");
|
||||
static const u8 sCondMsg46[] = _("Your POKéMON is happily gazing at\nthe beautiful, starry sky!");
|
||||
static const u8* const sNightTexts[] = {sCondMsg45, sCondMsg46, NULL};
|
||||
|
||||
// See the struct definition in follower_helper.h for more info
|
||||
const struct FollowerMsgInfoExtended gFollowerConditionalMessages[COND_MSG_COUNT] =
|
||||
@@ -350,6 +358,26 @@ const struct FollowerMsgInfoExtended gFollowerConditionalMessages[COND_MSG_COUNT
|
||||
MATCH_STATUS(STATUS1_BURN),
|
||||
},
|
||||
},
|
||||
[COND_MSG_DAY] =
|
||||
{
|
||||
.text = (u8*)sDayTexts,
|
||||
.textSpread = 1,
|
||||
.emotion = FOLLOWER_EMOTION_MUSIC,
|
||||
.conditions =
|
||||
{
|
||||
MATCH_TIME_OF_DAY(TIME_DAY),
|
||||
},
|
||||
},
|
||||
[COND_MSG_NIGHT] =
|
||||
{
|
||||
.text = (u8*)sNightTexts,
|
||||
.textSpread = 1,
|
||||
.emotion = FOLLOWER_EMOTION_MUSIC,
|
||||
.conditions =
|
||||
{
|
||||
MATCH_TIME_OF_DAY(TIME_NIGHT),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// Pool of "unconditional" follower messages
|
||||
|
||||
@@ -1996,7 +1996,7 @@ const u32 gUnionRoomChat_Keyboard_Gfx[] = INCBIN_U32("graphics/union_room_chat/k
|
||||
const u32 gUnionRoomChat_Keyboard_Tilemap[] = INCBIN_U32("graphics/union_room_chat/keyboard.bin.lz");
|
||||
const u32 gUnionRoomChat_RButtonLabels[] = INCBIN_U32("graphics/union_room_chat/r_button_labels.4bpp.lz");
|
||||
|
||||
const u16 gTilesetPalettes_General[][16] =
|
||||
const u16 ALIGNED(4) gTilesetPalettes_General[][16] =
|
||||
{
|
||||
INCBIN_U16("data/tilesets/primary/general/palettes/00.gbapal"),
|
||||
INCBIN_U16("data/tilesets/primary/general/palettes/01.gbapal"),
|
||||
|
||||
@@ -41,6 +41,7 @@ enum MapPopUp_Themes_BW
|
||||
|
||||
// static functions
|
||||
static void Task_MapNamePopUpWindow(u8 taskId);
|
||||
static void UpdateSecondaryPopUpWindow(u8 secondaryPopUpWindowId);
|
||||
static void ShowMapNamePopUpWindow(void);
|
||||
static void LoadMapNamePopUpWindowBg(void);
|
||||
|
||||
@@ -423,6 +424,7 @@ static void Task_MapNamePopUpWindow(u8 taskId)
|
||||
break;
|
||||
case STATE_WAIT:
|
||||
// Wait while the window is fully onscreen.
|
||||
UpdateSecondaryPopUpWindow(GetSecondaryPopUpWindowId());
|
||||
if (++task->tOnscreenTimer > 120)
|
||||
{
|
||||
task->tOnscreenTimer = 0;
|
||||
@@ -500,6 +502,20 @@ void HideMapNamePopUpWindow(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void UpdateSecondaryPopUpWindow(u8 secondaryPopUpWindowId)
|
||||
{
|
||||
u8 mapDisplayHeader[24];
|
||||
u8 *withoutPrefixPtr = &(mapDisplayHeader[0]);
|
||||
|
||||
if (OW_POPUP_BW_TIME_MODE != OW_POPUP_BW_TIME_NONE)
|
||||
{
|
||||
RtcCalcLocalTime();
|
||||
FormatDecimalTimeWithoutSeconds(withoutPrefixPtr, gLocalTime.hours, gLocalTime.minutes, OW_POPUP_BW_TIME_MODE == OW_POPUP_BW_TIME_24_HR);
|
||||
AddTextPrinterParameterized(secondaryPopUpWindowId, FONT_SMALL, mapDisplayHeader, GetStringRightAlignXOffset(FONT_SMALL, mapDisplayHeader, DISPLAY_WIDTH) - 5, 8, TEXT_SKIP_DRAW, NULL);
|
||||
}
|
||||
CopyWindowToVram(secondaryPopUpWindowId, COPYWIN_FULL);
|
||||
}
|
||||
|
||||
static void ShowMapNamePopUpWindow(void)
|
||||
{
|
||||
u8 mapDisplayHeader[24];
|
||||
@@ -550,16 +566,8 @@ static void ShowMapNamePopUpWindow(void)
|
||||
if (OW_POPUP_GENERATION == GEN_5)
|
||||
{
|
||||
AddTextPrinterParameterized(mapNamePopUpWindowId, FONT_SHORT, mapDisplayHeader, 8, 2, TEXT_SKIP_DRAW, NULL);
|
||||
|
||||
if (OW_POPUP_BW_TIME_MODE != OW_POPUP_BW_TIME_NONE)
|
||||
{
|
||||
RtcCalcLocalTime();
|
||||
FormatDecimalTimeWithoutSeconds(withoutPrefixPtr, gLocalTime.hours, gLocalTime.minutes, OW_POPUP_BW_TIME_MODE == OW_POPUP_BW_TIME_24_HR);
|
||||
AddTextPrinterParameterized(secondaryPopUpWindowId, FONT_SMALL, mapDisplayHeader, GetStringRightAlignXOffset(FONT_SMALL, mapDisplayHeader, DISPLAY_WIDTH) - 5, 8, TEXT_SKIP_DRAW, NULL);
|
||||
}
|
||||
|
||||
CopyWindowToVram(mapNamePopUpWindowId, COPYWIN_FULL);
|
||||
CopyWindowToVram(secondaryPopUpWindowId, COPYWIN_FULL);
|
||||
UpdateSecondaryPopUpWindow(secondaryPopUpWindowId);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
200
src/overworld.c
200
src/overworld.c
@@ -10,9 +10,11 @@
|
||||
#include "event_data.h"
|
||||
#include "event_object_movement.h"
|
||||
#include "event_scripts.h"
|
||||
#include "fake_rtc.h"
|
||||
#include "field_camera.h"
|
||||
#include "field_control_avatar.h"
|
||||
#include "field_effect.h"
|
||||
#include "field_effect_helpers.h"
|
||||
#include "field_message_box.h"
|
||||
#include "field_player_avatar.h"
|
||||
#include "field_screen_effect.h"
|
||||
@@ -66,6 +68,7 @@
|
||||
#include "vs_seeker.h"
|
||||
#include "frontier_util.h"
|
||||
#include "constants/abilities.h"
|
||||
#include "constants/event_objects.h"
|
||||
#include "constants/layouts.h"
|
||||
#include "constants/map_types.h"
|
||||
#include "constants/region_map_sections.h"
|
||||
@@ -197,6 +200,11 @@ COMMON_DATA bool8 (*gFieldCallback2)(void) = NULL;
|
||||
COMMON_DATA u8 gLocalLinkPlayerId = 0; // This is our player id in a multiplayer mode.
|
||||
COMMON_DATA u8 gFieldLinkPlayerCount = 0;
|
||||
|
||||
u8 gTimeOfDay;
|
||||
struct TimeBlendSettings gTimeBlend;
|
||||
s16 gTimeUpdateCounter; // playTimeVBlanks will eventually overflow, so this is used to update TOD
|
||||
|
||||
// EWRAM vars
|
||||
EWRAM_DATA static u8 sObjectEventLoadFlag = 0;
|
||||
EWRAM_DATA struct WarpData gLastUsedWarp = {0};
|
||||
EWRAM_DATA static struct WarpData sWarpDestination = {0}; // new warp position
|
||||
@@ -206,6 +214,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};
|
||||
EWRAM_DATA bool8 gExitStairsMovementDisabled = FALSE;
|
||||
|
||||
@@ -828,8 +837,6 @@ bool8 SetDiveWarpDive(u16 x, u16 y)
|
||||
|
||||
void LoadMapFromCameraTransition(u8 mapGroup, u8 mapNum)
|
||||
{
|
||||
s32 paletteIndex;
|
||||
|
||||
SetWarpDestination(mapGroup, mapNum, WARP_ID_NONE, -1, -1);
|
||||
|
||||
// Dont transition map music between BF Outside West/East
|
||||
@@ -859,10 +866,9 @@ if (I_VS_SEEKER_CHARGING != 0)
|
||||
RunOnTransitionMapScript();
|
||||
InitMap();
|
||||
CopySecondaryTilesetToVramUsingHeap(gMapHeader.mapLayout);
|
||||
LoadSecondaryTilesetPalette(gMapHeader.mapLayout);
|
||||
LoadSecondaryTilesetPalette(gMapHeader.mapLayout, TRUE); // skip copying to Faded, gamma shift will take care of it
|
||||
|
||||
for (paletteIndex = NUM_PALS_IN_PRIMARY; paletteIndex < NUM_PALS_TOTAL; paletteIndex++)
|
||||
ApplyWeatherColorMapToPal(paletteIndex);
|
||||
ApplyWeatherColorMapToPals(NUM_PALS_IN_PRIMARY, NUM_PALS_TOTAL - NUM_PALS_IN_PRIMARY); // palettes [6,12]
|
||||
|
||||
InitSecondaryTilesetAnimation();
|
||||
UpdateLocationHistoryForRoamer();
|
||||
@@ -907,6 +913,8 @@ static void LoadMapFromWarp(bool32 a1)
|
||||
TrySetMapSaveWarpStatus();
|
||||
ClearTempFieldEventData();
|
||||
ResetDexNavSearch();
|
||||
// reset hours override on every warp
|
||||
sHoursOverride = 0;
|
||||
ResetCyclingRoadChallengeData();
|
||||
RestartWildEncounterImmunitySteps();
|
||||
#if FREE_MATCH_CALL == FALSE
|
||||
@@ -1535,6 +1543,155 @@ void CB1_Overworld(void)
|
||||
DoCB1_Overworld(gMain.newKeys, gMain.heldKeys);
|
||||
}
|
||||
|
||||
#define TINT_NIGHT Q_8_8(0.456) | Q_8_8(0.456) << 8 | Q_8_8(0.615) << 16
|
||||
|
||||
const struct BlendSettings gTimeOfDayBlend[] =
|
||||
{
|
||||
[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 DEFAULT_WEIGHT 256
|
||||
#define TIME_BLEND_WEIGHT(begin, end) (DEFAULT_WEIGHT - (DEFAULT_WEIGHT * ((hours - begin) * MINUTES_PER_HOUR + minutes) / ((end - begin) * MINUTES_PER_HOUR)))
|
||||
|
||||
#define MORNING_HOUR_MIDDLE (MORNING_HOUR_BEGIN + ((MORNING_HOUR_END - MORNING_HOUR_BEGIN) / 2))
|
||||
|
||||
void UpdateTimeOfDay(void)
|
||||
{
|
||||
if (!OW_ENABLE_DNS)
|
||||
return;
|
||||
s32 hours, minutes;
|
||||
RtcCalcLocalTime();
|
||||
hours = sHoursOverride ? sHoursOverride : gLocalTime.hours;
|
||||
minutes = sHoursOverride ? 0 : gLocalTime.minutes;
|
||||
|
||||
if (IsBetweenHours(hours, MORNING_HOUR_BEGIN, MORNING_HOUR_MIDDLE)) // night->morning
|
||||
{
|
||||
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 (IsBetweenHours(hours, MORNING_HOUR_MIDDLE, MORNING_HOUR_END)) // morning->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 (IsBetweenHours(hours, EVENING_HOUR_BEGIN, EVENING_HOUR_END)) // evening
|
||||
{
|
||||
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 (IsBetweenHours(hours, NIGHT_HOUR_BEGIN, NIGHT_HOUR_BEGIN + 1)) // evening->night
|
||||
{
|
||||
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 (IsBetweenHours(hours, NIGHT_HOUR_BEGIN, NIGHT_HOUR_END)) // night
|
||||
{
|
||||
gTimeBlend.weight = DEFAULT_WEIGHT;
|
||||
gTimeBlend.altWeight = 0;
|
||||
gTimeBlend.startBlend = gTimeBlend.endBlend = gTimeOfDayBlend[TIME_NIGHT];
|
||||
gTimeOfDay = TIME_NIGHT;
|
||||
}
|
||||
else // day
|
||||
{
|
||||
gTimeBlend.weight = gTimeBlend.altWeight = DEFAULT_WEIGHT;
|
||||
gTimeBlend.startBlend = gTimeBlend.endBlend = gTimeOfDayBlend[TIME_DAY];
|
||||
gTimeOfDay = TIME_DAY;
|
||||
}
|
||||
}
|
||||
|
||||
#undef MORNING_HOUR_MIDDLE
|
||||
#undef TIME_BLEND_WEIGHT
|
||||
#undef DEFAULT_WEIGHT
|
||||
|
||||
// Whether a map type is naturally lit/outside
|
||||
bool32 MapHasNaturalLight(u8 mapType)
|
||||
{
|
||||
return (mapType == MAP_TYPE_TOWN
|
||||
|| mapType == MAP_TYPE_CITY
|
||||
|| mapType == MAP_TYPE_ROUTE
|
||||
|| mapType == MAP_TYPE_OCEAN_ROUTE);
|
||||
}
|
||||
|
||||
bool32 CurrentMapHasShadows(void)
|
||||
{
|
||||
// Add all conditionals here for maps that shouldn't have shadows
|
||||
// By default only cave maps are excluded from having shadows under object events
|
||||
return (gMapHeader.mapType != MAP_TYPE_UNDERGROUND);
|
||||
}
|
||||
|
||||
// Update & mix day / night bg palettes (into unfaded)
|
||||
void UpdateAltBgPalettes(u16 palettes)
|
||||
{
|
||||
if (!OW_ENABLE_DNS)
|
||||
return;
|
||||
const struct Tileset *primary = gMapHeader.mapLayout->primaryTileset;
|
||||
const struct Tileset *secondary = gMapHeader.mapLayout->secondaryTileset;
|
||||
u32 i = 1;
|
||||
if (!MapHasNaturalLight(gMapHeader.mapType))
|
||||
return;
|
||||
palettes &= ~((1 << NUM_PALS_IN_PRIMARY) - 1) | primary->swapPalettes;
|
||||
palettes &= ((1 << NUM_PALS_IN_PRIMARY) - 1) | (secondary->swapPalettes << NUM_PALS_IN_PRIMARY);
|
||||
palettes &= PALETTES_MAP ^ (1 << 0); // don't blend palette 0, [13,15]
|
||||
palettes >>= 1; // start at palette 1
|
||||
if (!palettes)
|
||||
return;
|
||||
while (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, gTimeBlend.altWeight);
|
||||
else
|
||||
AvgPaletteWeighted(&((u16 *)secondary->palettes)[i * 16], &((u16 *)secondary->palettes)[((i + 9) % 16) * 16], gPlttBufferUnfaded + i * 16, gTimeBlend.altWeight);
|
||||
}
|
||||
i++;
|
||||
palettes >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdatePalettesWithTime(u32 palettes)
|
||||
{
|
||||
if (!OW_ENABLE_DNS || !MapHasNaturalLight(gMapHeader.mapType))
|
||||
return;
|
||||
u32 i;
|
||||
u32 mask = 1 << 16;
|
||||
if (palettes >= (1 << 16))
|
||||
for (i = 0; i < 16; i++, mask <<= 1)
|
||||
{
|
||||
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, &gTimeBlend.startBlend, &gTimeBlend.endBlend, gTimeBlend.weight);
|
||||
}
|
||||
|
||||
u8 UpdateSpritePaletteWithTime(u8 paletteNum)
|
||||
{
|
||||
if (OW_ENABLE_DNS
|
||||
&& MapHasNaturalLight(gMapHeader.mapType)
|
||||
&& !IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(paletteNum)))
|
||||
TimeMixPalettes(1, &gPlttBufferUnfaded[OBJ_PLTT_ID(paletteNum)], &gPlttBufferFaded[OBJ_PLTT_ID(paletteNum)], &gTimeBlend.startBlend, &gTimeBlend.endBlend, gTimeBlend.weight);
|
||||
return paletteNum;
|
||||
}
|
||||
|
||||
static void OverworldBasic(void)
|
||||
{
|
||||
ScriptContext_RunScript();
|
||||
@@ -1546,6 +1703,23 @@ static void OverworldBasic(void)
|
||||
UpdatePaletteFade();
|
||||
UpdateTilesetAnimations();
|
||||
DoScheduledBgTilemapCopiesToVram();
|
||||
// Every minute if no palette fade is active, update TOD blending as needed
|
||||
if (!gPaletteFade.active && --gTimeUpdateCounter <= 0)
|
||||
{
|
||||
struct TimeBlendSettings cachedBlend = gTimeBlend;
|
||||
u32 *bld0 = (u32*)&cachedBlend;
|
||||
u32 *bld1 = (u32*)&gTimeBlend;
|
||||
gTimeUpdateCounter = (SECONDS_PER_MINUTE * 60 / FakeRtc_GetSecondsRatio());
|
||||
UpdateTimeOfDay();
|
||||
FormChangeTimeUpdate();
|
||||
if (bld0[0] != bld1[0]
|
||||
|| bld0[1] != bld1[1]
|
||||
|| bld0[2] != bld1[2])
|
||||
{
|
||||
UpdateAltBgPalettes(PALETTES_BG);
|
||||
UpdatePalettesWithTime(PALETTES_ALL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This CB2 is used when starting
|
||||
@@ -3283,6 +3457,8 @@ static void CreateLinkPlayerSprite(u8 linkPlayerId, u8 gameVersion)
|
||||
sprite->coordOffsetEnabled = TRUE;
|
||||
sprite->data[0] = linkPlayerId;
|
||||
objEvent->triggerGroundEffectsOnMove = FALSE;
|
||||
objEvent->localId = OBJ_EVENT_ID_DYNAMIC_BASE + linkPlayerId;
|
||||
SetUpShadow(objEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3516,3 +3692,17 @@ void ScriptHideItemDescription(struct ScriptContext *ctx)
|
||||
#endif // OW_SHOW_ITEM_DESCRIPTIONS
|
||||
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
590
src/palette.c
590
src/palette.c
@@ -13,11 +13,13 @@ enum
|
||||
NORMAL_FADE,
|
||||
FAST_FADE,
|
||||
HARDWARE_FADE,
|
||||
TIME_OF_DAY_FADE,
|
||||
};
|
||||
|
||||
static u32 UpdateNormalPaletteFade(void);
|
||||
static void BeginFastPaletteFadeInternal(u32);
|
||||
static u32 UpdateFastPaletteFade(void);
|
||||
static u8 UpdateTimeOfDayPaletteFade(void);
|
||||
static u32 UpdateHardwarePaletteFade(void);
|
||||
static void UpdateBlendRegisters(void);
|
||||
static bool32 IsSoftwarePaletteFadeFinishing(void);
|
||||
@@ -53,6 +55,16 @@ void LoadPalette(const void *src, u32 offset, u32 size)
|
||||
CpuCopy16(src, &gPlttBufferFaded[offset], size);
|
||||
}
|
||||
|
||||
// Drop in replacement for LoadPalette, uses CpuFastCopy, size must be 0 % 32
|
||||
void LoadPaletteFast(const void *src, u32 offset, u32 size)
|
||||
{
|
||||
if ((u32)src & 3) // In case palette is not 4 byte aligned
|
||||
return LoadPalette(src, offset, size);
|
||||
CpuFastCopy(src, &gPlttBufferUnfaded[offset], size);
|
||||
// Copying from EWRAM->EWRAM is faster than ROM->EWRAM
|
||||
CpuFastCopy(&gPlttBufferUnfaded[offset], &gPlttBufferFaded[offset], size);
|
||||
}
|
||||
|
||||
void FillPalette(u32 value, u32 offset, u32 size)
|
||||
{
|
||||
CpuFill16(value, &gPlttBufferUnfaded[offset], size);
|
||||
@@ -83,6 +95,8 @@ u32 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();
|
||||
|
||||
@@ -114,9 +128,9 @@ bool32 BeginNormalPaletteFade(u32 selectedPalettes, s8 delay, u8 startY, u8 targ
|
||||
delay = 0;
|
||||
}
|
||||
|
||||
gPaletteFade_selectedPalettes = selectedPalettes;
|
||||
gPaletteFadeSelectedPalettes = selectedPalettes;
|
||||
gPaletteFade.delayCounter = delay;
|
||||
gPaletteFade_delay = delay;
|
||||
gPaletteFadeDelay = delay;
|
||||
gPaletteFade.y = startY;
|
||||
gPaletteFade.targetY = targetY;
|
||||
gPaletteFade.blendColor = blendColor;
|
||||
@@ -141,6 +155,52 @@ bool32 BeginNormalPaletteFade(u32 selectedPalettes, s8 delay, u8 startY, u8 targ
|
||||
}
|
||||
}
|
||||
|
||||
// Like normal palette fade but respects sprite/tile palettes immune to time of day fading
|
||||
bool32 BeginTimeOfDayPaletteFade(u32 selectedPalettes, s8 delay, u8 startY, u8 targetY, struct BlendSettings *bld0, struct BlendSettings *bld1, u32 weight, u32 color)
|
||||
{
|
||||
u8 temp;
|
||||
|
||||
if (gPaletteFade.active)
|
||||
return FALSE;
|
||||
|
||||
gPaletteFade.deltaY = 2;
|
||||
|
||||
if (delay < 0)
|
||||
{
|
||||
gPaletteFade.deltaY += (delay * -1);
|
||||
delay = 0;
|
||||
}
|
||||
|
||||
gPaletteFadeSelectedPalettes = selectedPalettes;
|
||||
gPaletteFade.delayCounter = delay;
|
||||
gPaletteFadeDelay = delay;
|
||||
gPaletteFade.y = startY;
|
||||
gPaletteFade.targetY = targetY;
|
||||
gPaletteFade.active = 1;
|
||||
gPaletteFade.mode = TIME_OF_DAY_FADE;
|
||||
|
||||
gPaletteFade.blendColor = color;
|
||||
gPaletteFade.bld0 = bld0;
|
||||
gPaletteFade.bld1 = bld1;
|
||||
gPaletteFade.weight = weight;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void ResetPaletteFadeControl(void)
|
||||
{
|
||||
gPaletteFade.multipurpose1 = 0;
|
||||
@@ -161,6 +221,117 @@ void ResetPaletteFadeControl(void)
|
||||
gPaletteFade.deltaY = 2;
|
||||
}
|
||||
|
||||
// Like normal palette fade, but respects sprite/tile palettes immune to time of day fading
|
||||
static u8 UpdateTimeOfDayPaletteFade(void)
|
||||
{
|
||||
u16 paletteOffset;
|
||||
u16 selectedPalettes;
|
||||
u16 timePalettes = 0; // palettes passed to the time-blender
|
||||
u16 copyPalettes;
|
||||
u16 *src;
|
||||
u16 *dst;
|
||||
|
||||
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 < gPaletteFadeDelay)
|
||||
{
|
||||
gPaletteFade.delayCounter++;
|
||||
return PALETTE_FADE_STATUS_DELAY;
|
||||
}
|
||||
gPaletteFade.delayCounter = 0;
|
||||
}
|
||||
|
||||
paletteOffset = 0;
|
||||
|
||||
if (!gPaletteFade.objPaletteToggle)
|
||||
{
|
||||
selectedPalettes = gPaletteFadeSelectedPalettes;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedPalettes = gPaletteFadeSelectedPalettes >> 16;
|
||||
paletteOffset = 256;
|
||||
}
|
||||
|
||||
src = gPlttBufferUnfaded + paletteOffset;
|
||||
dst = gPlttBufferFaded + paletteOffset;
|
||||
|
||||
// First pply TOD blend to relevant subset of palettes
|
||||
if (gPaletteFade.objPaletteToggle) // Sprite palettes, don't blend those with tags
|
||||
{
|
||||
u32 i;
|
||||
u32 j = 1;
|
||||
for (i = 0; i < 16; i++, j <<= 1) // Mask out palettes that should not be light blended
|
||||
{
|
||||
if ((selectedPalettes & j) && !IS_BLEND_IMMUNE_TAG(GetSpritePaletteTagByPaletteNum(i)))
|
||||
timePalettes |= j;
|
||||
}
|
||||
}
|
||||
else // tile palettes, don't blend [13, 15]
|
||||
{
|
||||
timePalettes = selectedPalettes & PALETTES_MAP;
|
||||
}
|
||||
TimeMixPalettes(timePalettes, src, dst, gPaletteFade.bld0, gPaletteFade.bld1, gPaletteFade.weight);
|
||||
|
||||
// palettes that were not blended above must be copied through
|
||||
if ((copyPalettes = ~timePalettes))
|
||||
{
|
||||
u16 *src1 = src;
|
||||
u16 *dst1 = dst;
|
||||
while (copyPalettes)
|
||||
{
|
||||
if (copyPalettes & 1)
|
||||
CpuFastCopy(src1, dst1, 32);
|
||||
copyPalettes >>= 1;
|
||||
src1 += 16;
|
||||
dst1 += 16;
|
||||
}
|
||||
}
|
||||
|
||||
// Then, blend from faded->faded with native BlendPalettes
|
||||
BlendPalettesFine(selectedPalettes, dst, dst, gPaletteFade.y, gPaletteFade.blendColor);
|
||||
|
||||
gPaletteFade.objPaletteToggle ^= 1;
|
||||
|
||||
if (!gPaletteFade.objPaletteToggle)
|
||||
{
|
||||
if ((gPaletteFade.yDec && gPaletteFade.y == 0) || (!gPaletteFade.yDec && gPaletteFade.y == gPaletteFade.targetY))
|
||||
{
|
||||
gPaletteFadeSelectedPalettes = 0;
|
||||
gPaletteFade.softwareFadeFinishing = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
s8 val;
|
||||
|
||||
if (!gPaletteFade.yDec)
|
||||
{
|
||||
val = gPaletteFade.y + gPaletteFade.deltaY;
|
||||
if (val > gPaletteFade.targetY)
|
||||
val = gPaletteFade.targetY;
|
||||
gPaletteFade.y = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = gPaletteFade.y - 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 u32 UpdateNormalPaletteFade(void)
|
||||
{
|
||||
u16 paletteOffset;
|
||||
@@ -177,10 +348,10 @@ static u32 UpdateNormalPaletteFade(void)
|
||||
{
|
||||
if (!gPaletteFade.objPaletteToggle)
|
||||
{
|
||||
if (gPaletteFade.delayCounter < gPaletteFade_delay)
|
||||
if (gPaletteFade.delayCounter < gPaletteFadeDelay)
|
||||
{
|
||||
gPaletteFade.delayCounter++;
|
||||
return 2;
|
||||
return PALETTE_FADE_STATUS_DELAY;
|
||||
}
|
||||
gPaletteFade.delayCounter = 0;
|
||||
}
|
||||
@@ -189,11 +360,11 @@ static u32 UpdateNormalPaletteFade(void)
|
||||
|
||||
if (!gPaletteFade.objPaletteToggle)
|
||||
{
|
||||
selectedPalettes = gPaletteFade_selectedPalettes;
|
||||
selectedPalettes = gPaletteFadeSelectedPalettes;
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedPalettes = gPaletteFade_selectedPalettes >> 16;
|
||||
selectedPalettes = gPaletteFadeSelectedPalettes >> 16;
|
||||
paletteOffset = OBJ_PLTT_OFFSET;
|
||||
}
|
||||
|
||||
@@ -215,7 +386,7 @@ static u32 UpdateNormalPaletteFade(void)
|
||||
{
|
||||
if (gPaletteFade.y == gPaletteFade.targetY)
|
||||
{
|
||||
gPaletteFade_selectedPalettes = 0;
|
||||
gPaletteFadeSelectedPalettes = 0;
|
||||
gPaletteFade.softwareFadeFinishing = TRUE;
|
||||
}
|
||||
else
|
||||
@@ -312,7 +483,7 @@ void BeginFastPaletteFade(u32 submode)
|
||||
static void BeginFastPaletteFadeInternal(u32 submode)
|
||||
{
|
||||
gPaletteFade.y = 31;
|
||||
gPaletteFade_submode = submode & 0x3F;
|
||||
gPaletteFadeSubmode = submode & 0x3F;
|
||||
gPaletteFade.active = TRUE;
|
||||
gPaletteFade.mode = FAST_FADE;
|
||||
|
||||
@@ -355,7 +526,7 @@ static u32 UpdateFastPaletteFade(void)
|
||||
paletteOffsetEnd = OBJ_PLTT_OFFSET;
|
||||
}
|
||||
|
||||
switch (gPaletteFade_submode)
|
||||
switch (gPaletteFadeSubmode)
|
||||
{
|
||||
case FAST_FADE_IN_FROM_WHITE:
|
||||
for (i = paletteOffsetStart; i < paletteOffsetEnd; i++)
|
||||
@@ -460,7 +631,7 @@ static u32 UpdateFastPaletteFade(void)
|
||||
|
||||
if (gPaletteFade.y == 0)
|
||||
{
|
||||
switch (gPaletteFade_submode)
|
||||
switch (gPaletteFadeSubmode)
|
||||
{
|
||||
case FAST_FADE_IN_FROM_WHITE:
|
||||
case FAST_FADE_IN_FROM_BLACK:
|
||||
@@ -485,9 +656,9 @@ static u32 UpdateFastPaletteFade(void)
|
||||
|
||||
void BeginHardwarePaletteFade(u32 blendCnt, u32 delay, u32 y, u32 targetY, u32 shouldResetBlendRegisters)
|
||||
{
|
||||
gPaletteFade_blendCnt = blendCnt;
|
||||
gPaletteFadeBlendCnt = blendCnt;
|
||||
gPaletteFade.delayCounter = delay;
|
||||
gPaletteFade_delay = delay;
|
||||
gPaletteFadeDelay = delay;
|
||||
gPaletteFade.y = y;
|
||||
gPaletteFade.targetY = targetY;
|
||||
gPaletteFade.active = TRUE;
|
||||
@@ -506,7 +677,7 @@ static u32 UpdateHardwarePaletteFade(void)
|
||||
if (!gPaletteFade.active)
|
||||
return PALETTE_FADE_STATUS_DONE;
|
||||
|
||||
if (gPaletteFade.delayCounter < gPaletteFade_delay)
|
||||
if (gPaletteFade.delayCounter < gPaletteFadeDelay)
|
||||
{
|
||||
gPaletteFade.delayCounter++;
|
||||
return PALETTE_FADE_STATUS_DELAY;
|
||||
@@ -537,7 +708,8 @@ static u32 UpdateHardwarePaletteFade(void)
|
||||
{
|
||||
if (gPaletteFade.shouldResetBlendRegisters)
|
||||
{
|
||||
gPaletteFade_blendCnt = 0;
|
||||
// clear TGT1
|
||||
gPaletteFadeBlendCnt &= ~0xFF;
|
||||
gPaletteFade.y = 0;
|
||||
}
|
||||
gPaletteFade.shouldResetBlendRegisters = FALSE;
|
||||
@@ -548,15 +720,48 @@ static u32 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_BLDCNT, (u16)gPaletteFadeBlendCnt);
|
||||
SetGpuReg(REG_OFFSET_BLDY, gPaletteFade.y);
|
||||
// If fade-out, also adjust BLDALPHA and DISPCNT
|
||||
if (!gPaletteFade.yDec)
|
||||
{
|
||||
u16 bldAlpha = GetGpuReg(REG_OFFSET_BLDALPHA);
|
||||
u8 tgt1 = BLDALPHA_TGT1(bldAlpha);
|
||||
u8 tgt2 = BLDALPHA_TGT2(bldAlpha);
|
||||
u8 bldFade;
|
||||
|
||||
switch (gPaletteFadeBlendCnt & 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;
|
||||
gPaletteFade.mode = 0;
|
||||
gPaletteFade_blendCnt = 0;
|
||||
gPaletteFadeBlendCnt = 0;
|
||||
gPaletteFade.y = 0;
|
||||
gPaletteFade.active = FALSE;
|
||||
}
|
||||
@@ -585,15 +790,285 @@ static bool32 IsSoftwarePaletteFadeFinishing(void)
|
||||
}
|
||||
}
|
||||
|
||||
// optimized based on lucktyphlosion's BlendPalettesFine
|
||||
void BlendPalettesFine(u32 palettes, u16 *src, u16 *dst, u32 coeff, u32 color)
|
||||
{
|
||||
s32 newR, newG, newB;
|
||||
|
||||
if (!palettes)
|
||||
return;
|
||||
|
||||
coeff *= 2;
|
||||
newR = (color << 27) >> 27;
|
||||
newG = (color << 22) >> 27;
|
||||
newB = (color << 17) >> 27;
|
||||
|
||||
do
|
||||
{
|
||||
if (palettes & 1)
|
||||
{
|
||||
u16 *srcEnd = src + 16;
|
||||
while (src != srcEnd) // Transparency is blended (for backdrop reasons)
|
||||
{
|
||||
u32 srcColor = *src;
|
||||
s32 r = (srcColor << 27) >> 27;
|
||||
s32 g = (srcColor << 22) >> 27;
|
||||
s32 b = (srcColor << 16) >> 26;
|
||||
|
||||
*dst++ = ((r + (((newR - r) * (s32)coeff) >> 5)) << 0)
|
||||
| ((g + (((newG - g) * (s32)coeff) >> 5)) << 5)
|
||||
| ((b + (((newB - (b & 31)) * (s32)coeff) >> 5)) << 10);
|
||||
src++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
src += 16;
|
||||
dst += 16;
|
||||
}
|
||||
palettes >>= 1;
|
||||
} while (palettes);
|
||||
}
|
||||
|
||||
void BlendPalettes(u32 selectedPalettes, u8 coeff, u32 color)
|
||||
{
|
||||
u16 paletteOffset;
|
||||
BlendPalettesFine(selectedPalettes, gPlttBufferUnfaded, gPlttBufferFaded, coeff, color);
|
||||
}
|
||||
|
||||
for (paletteOffset = 0; selectedPalettes; paletteOffset += 16)
|
||||
#define DEFAULT_LIGHT_COLOR 0x3f9f
|
||||
|
||||
// Like BlendPalette, but ignores blendColor if the transparency high bit is set
|
||||
// Optimization help by lucktyphlosion
|
||||
void TimeBlendPalette(u16 palOffset, u32 coeff, u32 blendColor)
|
||||
{
|
||||
s32 newR, newG, newB, defR, defG, defB;
|
||||
u16 *src = gPlttBufferUnfaded + palOffset;
|
||||
u16 *dst = gPlttBufferFaded + palOffset;
|
||||
u32 defaultBlendColor = DEFAULT_LIGHT_COLOR;
|
||||
u16 *srcEnd = src + 16;
|
||||
u32 altBlendColor = *dst++ = *src++; // color 0 is copied through unchanged
|
||||
|
||||
coeff *= 2;
|
||||
newR = (blendColor << 27) >> 27;
|
||||
newG = (blendColor << 22) >> 27;
|
||||
newB = (blendColor << 17) >> 27;
|
||||
|
||||
if (altBlendColor >> 15) // Transparency high bit set; alt blend color
|
||||
{
|
||||
if (selectedPalettes & 1)
|
||||
BlendPalette(paletteOffset, 16, coeff, color);
|
||||
selectedPalettes >>= 1;
|
||||
defR = (altBlendColor << 27) >> 27;
|
||||
defG = (altBlendColor << 22) >> 27;
|
||||
defB = (altBlendColor << 17) >> 27;
|
||||
}
|
||||
else
|
||||
{
|
||||
defR = (defaultBlendColor << 27) >> 27;
|
||||
defG = (defaultBlendColor << 22) >> 27;
|
||||
defB = (defaultBlendColor << 17) >> 27;
|
||||
altBlendColor = 0;
|
||||
}
|
||||
while (src != srcEnd)
|
||||
{
|
||||
u32 srcColor = *src;
|
||||
s32 r = (srcColor << 27) >> 27;
|
||||
s32 g = (srcColor << 22) >> 27;
|
||||
s32 b = (srcColor << 16) >> 26;
|
||||
|
||||
if (srcColor >> 15)
|
||||
{
|
||||
*dst = ((r + (((defR - r) * (s32)coeff) >> 5)) << 0)
|
||||
| ((g + (((defG - g) * (s32)coeff) >> 5)) << 5)
|
||||
| ((b + (((defB - (b & 31)) * (s32)coeff) >> 5)) << 10);
|
||||
}
|
||||
else // Use provided blend color
|
||||
{
|
||||
*dst = ((r + (((newR - r) * (s32)coeff) >> 5)) << 0)
|
||||
| ((g + (((newG - g) * (s32)coeff) >> 5)) << 5)
|
||||
| ((b + (((newB - (b & 31)) * (s32)coeff) >> 5)) << 10);
|
||||
}
|
||||
src++;
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
|
||||
// Blends a weighted average of two blend parameters
|
||||
// Parameters can be either blended (as in BlendPalettes) or tinted (as in TintPaletteRGB_Copy)
|
||||
void TimeMixPalettes(u32 palettes, u16 *src, u16 *dst, struct BlendSettings *blend0, struct BlendSettings *blend1, u16 weight0)
|
||||
{
|
||||
s32 r0, g0, b0, r1, g1, b1, defR, defG, defB, altR, altG, altB;
|
||||
u32 color0, coeff0, color1, coeff1;
|
||||
bool8 tint0, tint1;
|
||||
u32 defaultColor = DEFAULT_LIGHT_COLOR;
|
||||
|
||||
if (!palettes)
|
||||
return;
|
||||
|
||||
color0 = blend0->blendColor;
|
||||
tint0 = blend0->isTint;
|
||||
coeff0 = tint0 ? 16 : blend0->coeff * 2;
|
||||
color1 = blend1->blendColor;
|
||||
tint1 = blend1->isTint;
|
||||
coeff1 = tint1 ? 16 : blend1->coeff * 2;
|
||||
|
||||
if (tint0)
|
||||
{
|
||||
r0 = (color0 << 24) >> 24;
|
||||
g0 = (color0 << 16) >> 24;
|
||||
b0 = (color0 << 8) >> 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
r0 = (color0 << 27) >> 27;
|
||||
g0 = (color0 << 22) >> 27;
|
||||
b0 = (color0 << 17) >> 27;
|
||||
}
|
||||
if (tint1)
|
||||
{
|
||||
r1 = (color1 << 24) >> 24;
|
||||
g1 = (color1 << 16) >> 24;
|
||||
b1 = (color1 << 8) >> 24;
|
||||
}
|
||||
else
|
||||
{
|
||||
r1 = (color1 << 27) >> 27;
|
||||
g1 = (color1 << 22) >> 27;
|
||||
b1 = (color1 << 17) >> 27;
|
||||
}
|
||||
defR = (defaultColor << 27) >> 27;
|
||||
defG = (defaultColor << 22) >> 27;
|
||||
defB = (defaultColor << 17) >> 27;
|
||||
|
||||
do
|
||||
{
|
||||
if (palettes & 1)
|
||||
{
|
||||
u16 *srcEnd = src + 16;
|
||||
u32 altBlendColor = *dst++ = *src++; // color 0 is copied through
|
||||
if (altBlendColor >> 15) // Transparency high bit set; alt blend color
|
||||
{
|
||||
altR = (altBlendColor << 27) >> 27;
|
||||
altG = (altBlendColor << 22) >> 27;
|
||||
altB = (altBlendColor << 17) >> 27;
|
||||
}
|
||||
else
|
||||
{
|
||||
altBlendColor = 0;
|
||||
}
|
||||
while (src != srcEnd)
|
||||
{
|
||||
u32 srcColor = *src;
|
||||
s32 r = (srcColor << 27) >> 27;
|
||||
s32 g = (srcColor << 22) >> 27;
|
||||
s32 b = (srcColor << 17) >> 27;
|
||||
s32 r2, g2, b2;
|
||||
|
||||
if (srcColor >> 15)
|
||||
{
|
||||
if (altBlendColor)
|
||||
{
|
||||
// Use alternate blend color
|
||||
r2 = r + (((altR - r) * (s32)coeff1) >> 5);
|
||||
g2 = g + (((altG - g) * (s32)coeff1) >> 5);
|
||||
b2 = b + (((altB - b) * (s32)coeff1) >> 5);
|
||||
r = r + (((altR - r) * (s32)coeff0) >> 5);
|
||||
g = g + (((altG - g) * (s32)coeff0) >> 5);
|
||||
b = b + (((altB - b) * (s32)coeff0) >> 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use default blend color
|
||||
r2 = r + (((defR - r) * (s32)coeff1) >> 5);
|
||||
g2 = g + (((defG - g) * (s32)coeff1) >> 5);
|
||||
b2 = b + (((defB - b) * (s32)coeff1) >> 5);
|
||||
r = r + (((defR - r) * (s32)coeff0) >> 5);
|
||||
g = g + (((defG - g) * (s32)coeff0) >> 5);
|
||||
b = b + (((defB - b) * (s32)coeff0) >> 5);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use provided blend colors
|
||||
if (!tint1)
|
||||
{
|
||||
// blend-based
|
||||
r2 = (r + (((r1 - r) * (s32)coeff1) >> 5));
|
||||
g2 = (g + (((g1 - g) * (s32)coeff1) >> 5));
|
||||
b2 = (b + (((b1 - b) * (s32)coeff1) >> 5));
|
||||
}
|
||||
else
|
||||
{
|
||||
// tint-based
|
||||
r2 = (u16)((r1 * r)) >> 8;
|
||||
g2 = (u16)((g1 * g)) >> 8;
|
||||
b2 = (u16)((b1 * b)) >> 8;
|
||||
if (r2 > 31)
|
||||
r2 = 31;
|
||||
if (g2 > 31)
|
||||
g2 = 31;
|
||||
if (b2 > 31)
|
||||
b2 = 31;
|
||||
}
|
||||
if (!tint0)
|
||||
{
|
||||
// blend-based
|
||||
r = (r + (((r0 - r) * (s32)coeff0) >> 5));
|
||||
g = (g + (((g0 - g) * (s32)coeff0) >> 5));
|
||||
b = (b + (((b0 - b) * (s32)coeff0) >> 5));
|
||||
}
|
||||
else
|
||||
{
|
||||
// tint-based
|
||||
r = (u16)((r0 * r)) >> 8;
|
||||
g = (u16)((g0 * g)) >> 8;
|
||||
b = (u16)((b0 * b)) >> 8;
|
||||
if (r > 31)
|
||||
r = 31;
|
||||
if (g > 31)
|
||||
g = 31;
|
||||
if (b > 31)
|
||||
b = 31;
|
||||
}
|
||||
}
|
||||
r = r2 + (((r - r2) * (s32)weight0) >> 8);
|
||||
g = g2 + (((g - g2) * (s32)weight0) >> 8);
|
||||
b = b2 + (((b - b2) * (s32)weight0) >> 8);
|
||||
*dst++ = RGB2(r, g, b);
|
||||
// *dst++ = RGB2(r, g, b) | (srcColor >> 15) << 15;
|
||||
src++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
src += 16;
|
||||
dst += 16;
|
||||
}
|
||||
palettes >>= 1;
|
||||
} while (palettes);
|
||||
}
|
||||
|
||||
// Apply weighted average to palettes, preserving high bits of dst throughout
|
||||
void AvgPaletteWeighted(u16 *src0, u16 *src1, u16 *dst, u16 weight0)
|
||||
{
|
||||
u16 *srcEnd = src0 + 16;
|
||||
src0++;
|
||||
src1++;
|
||||
dst++; // leave dst transparency unchanged
|
||||
while (src0 != srcEnd)
|
||||
{
|
||||
u32 src0Color = *src0++;
|
||||
s32 r0 = (src0Color << 27) >> 27;
|
||||
s32 g0 = (src0Color << 22) >> 27;
|
||||
s32 b0 = (src0Color << 17) >> 27;
|
||||
u32 src1Color = *src1++;
|
||||
s32 r1 = (src1Color << 27) >> 27;
|
||||
s32 g1 = (src1Color << 22) >> 27;
|
||||
s32 b1 = (src1Color << 17) >> 27;
|
||||
|
||||
// Average and bitwise-OR
|
||||
r0 = r1 + (((r0 - r1) * weight0) >> 8);
|
||||
g0 = g1 + (((g0 - g1) * weight0) >> 8);
|
||||
b0 = b1 + (((b0 - b1) * weight0) >> 8);
|
||||
*dst = (*dst & RGB_ALPHA) | RGB2(r0, g0, b0); // preserve high bit of dst
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -696,6 +1171,79 @@ void TintPalette_CustomTone(u16 *palette, u32 count, u16 rTone, u16 gTone, u16 b
|
||||
}
|
||||
}
|
||||
|
||||
// Tints from Unfaded to Faded, using a 15-bit GBA color
|
||||
void TintPalette_RGB_Copy(u16 palOffset, u32 blendColor)
|
||||
{
|
||||
s32 newR, newG, newB, rTone = 0, gTone = 0, bTone = 0;
|
||||
u16 *src = gPlttBufferUnfaded + palOffset;
|
||||
u16 *dst = gPlttBufferFaded + palOffset;
|
||||
u32 defaultBlendColor = DEFAULT_LIGHT_COLOR;
|
||||
u16 *srcEnd = src + 16;
|
||||
u16 altBlendIndices = *dst++ = *src++; // color 0 is copied through unchanged
|
||||
u32 altBlendColor;
|
||||
|
||||
newR = ((blendColor << 27) >> 27) << 3;
|
||||
newG = ((blendColor << 22) >> 27) << 3;
|
||||
newB = ((blendColor << 17) >> 27) << 3;
|
||||
|
||||
if (altBlendIndices >> 15) // High bit set; bitmask of which colors to alt-blend
|
||||
{
|
||||
// Note that bit 0 of altBlendIndices specifies color 1
|
||||
altBlendColor = src[14]; // color 15
|
||||
if (altBlendColor >> 15)
|
||||
{
|
||||
// Set alternate blend color
|
||||
rTone = ((altBlendColor << 27) >> 27) << 3;
|
||||
gTone = ((altBlendColor << 22) >> 27) << 3;
|
||||
bTone = ((altBlendColor << 17) >> 27) << 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set default blend color
|
||||
rTone = ((defaultBlendColor << 27) >> 27) << 3;
|
||||
gTone = ((defaultBlendColor << 22) >> 27) << 3;
|
||||
bTone = ((defaultBlendColor << 17) >> 27) << 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
altBlendIndices = 0;
|
||||
}
|
||||
|
||||
while (src != srcEnd)
|
||||
{
|
||||
u32 srcColor = *src;
|
||||
s32 r = (srcColor << 27) >> 27;
|
||||
s32 g = (srcColor << 22) >> 27;
|
||||
s32 b = (srcColor << 17) >> 27;
|
||||
|
||||
if (altBlendIndices & 1)
|
||||
{
|
||||
r = (u16)((rTone * r)) >> 8;
|
||||
g = (u16)((gTone * g)) >> 8;
|
||||
b = (u16)((bTone * b)) >> 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use provided blend color
|
||||
r = (u16)((newR * r)) >> 8;
|
||||
g = (u16)((newG * g)) >> 8;
|
||||
b = (u16)((newB * b)) >> 8;
|
||||
}
|
||||
if (r > 31)
|
||||
r = 31;
|
||||
if (g > 31)
|
||||
g = 31;
|
||||
if (b > 31)
|
||||
b = 31;
|
||||
src++;
|
||||
*dst++ = RGB2(r, g, b);
|
||||
altBlendIndices >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
#undef DEFAULT_LIGHT_COLOR
|
||||
|
||||
#define tCoeff data[0]
|
||||
#define tCoeffTarget data[1]
|
||||
#define tCoeffDelta data[2]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "palette.h"
|
||||
#include "palette_util.h"
|
||||
#include "util.h"
|
||||
#include "overworld.h"
|
||||
|
||||
// "RouletteFlash" is more accurately a general flashing/fading util
|
||||
// this file handles fading the palettes for the color/icon selections on the Roulette wheel
|
||||
@@ -384,7 +385,11 @@ void UpdatePulseBlend(struct PulseBlend *pulseBlend)
|
||||
if (--pulseBlendPalette->delayCounter == 0xFF)
|
||||
{
|
||||
pulseBlendPalette->delayCounter = pulseBlendPalette->pulseBlendSettings.delay;
|
||||
BlendPalette(pulseBlendPalette->pulseBlendSettings.paletteOffset, pulseBlendPalette->pulseBlendSettings.numColors, pulseBlendPalette->blendCoeff, pulseBlendPalette->pulseBlendSettings.blendColor);
|
||||
CpuFastCopy(gPlttBufferUnfaded + pulseBlendPalette->pulseBlendSettings.paletteOffset, gPlttBufferFaded + pulseBlendPalette->pulseBlendSettings.paletteOffset, PLTT_SIZE_4BPP);
|
||||
UpdatePalettesWithTime(1 << (pulseBlendPalette->pulseBlendSettings.paletteOffset >> 4));
|
||||
// pulseBlendSettings has a numColors field, but it is only ever set to 16 (for Mirage Tower)
|
||||
// So, it's ok to use the fine blending here which blends the entire palette
|
||||
BlendPalettesFine(1, gPlttBufferFaded + pulseBlendPalette->pulseBlendSettings.paletteOffset, gPlttBufferFaded + pulseBlendPalette->pulseBlendSettings.paletteOffset, pulseBlendPalette->blendCoeff, pulseBlendPalette->pulseBlendSettings.blendColor);
|
||||
switch (pulseBlendPalette->pulseBlendSettings.fadeType)
|
||||
{
|
||||
case 0: // Fade all the way to the max blend amount, then wrap around
|
||||
|
||||
@@ -741,7 +741,7 @@ static u8 RotatingGate_CreateGate(u8 gateId, s16 deltaX, s16 deltaY)
|
||||
|
||||
template.tileTag = gate->shape + ROTATING_GATE_TILE_TAG;
|
||||
|
||||
spriteId = CreateSprite(&template, 0, 0, 0x93);
|
||||
spriteId = CreateSprite(&template, 0, 0, OW_OBJECT_SUBPRIORITY - 1); // Above shadows
|
||||
if (spriteId == MAX_SPRITES)
|
||||
return MAX_SPRITES;
|
||||
|
||||
|
||||
11
src/rtc.c
11
src/rtc.c
@@ -6,6 +6,7 @@
|
||||
#include "strings.h"
|
||||
#include "text.h"
|
||||
#include "fake_rtc.h"
|
||||
#include "overworld.h"
|
||||
|
||||
// iwram bss
|
||||
static u16 sErrorStatus;
|
||||
@@ -329,14 +330,8 @@ bool8 IsBetweenHours(s32 hours, s32 begin, s32 end)
|
||||
|
||||
enum TimeOfDay GetTimeOfDay(void)
|
||||
{
|
||||
RtcCalcLocalTime();
|
||||
if (IsBetweenHours(gLocalTime.hours, MORNING_HOUR_BEGIN, MORNING_HOUR_END))
|
||||
return TIME_MORNING;
|
||||
else if (IsBetweenHours(gLocalTime.hours, EVENING_HOUR_BEGIN, EVENING_HOUR_END))
|
||||
return TIME_EVENING;
|
||||
else if (IsBetweenHours(gLocalTime.hours, NIGHT_HOUR_BEGIN, NIGHT_HOUR_END))
|
||||
return TIME_NIGHT;
|
||||
return TIME_DAY;
|
||||
UpdateTimeOfDay();
|
||||
return gTimeOfDay;
|
||||
}
|
||||
|
||||
enum TimeOfDay GetTimeOfDayForDex(void)
|
||||
|
||||
35
src/scrcmd.c
35
src/scrcmd.c
@@ -24,6 +24,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"
|
||||
@@ -795,6 +796,13 @@ static bool8 IsPaletteNotActive(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// pauses script until palette fade inactive
|
||||
bool8 ScrFunc_WaitPaletteNotActive(struct ScriptContext *ctx)
|
||||
{
|
||||
SetupNativeScript(ctx, IsPaletteNotActive);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool8 ScrCmd_fadescreen(struct ScriptContext *ctx)
|
||||
{
|
||||
u32 mode = ScriptReadByte(ctx);
|
||||
@@ -818,37 +826,28 @@ 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;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
#include "constants/songs.h"
|
||||
|
||||
#define TAG_SCROLL_ARROW 2100
|
||||
#define TAG_ITEM_ICON_BASE 2110
|
||||
#define TAG_ITEM_ICON_BASE 9110 // immune to time blending
|
||||
|
||||
#define MAX_ITEMS_SHOWN 8
|
||||
|
||||
|
||||
10
src/sprite.c
10
src/sprite.c
@@ -1603,9 +1603,17 @@ void LoadSpritePalettes(const struct SpritePalette *palettes)
|
||||
break;
|
||||
}
|
||||
|
||||
u8 LoadSpritePaletteInSlot(const struct SpritePalette *palette, u8 paletteNum)
|
||||
{
|
||||
paletteNum = min(15, paletteNum);
|
||||
sSpritePaletteTags[paletteNum] = palette->tag;
|
||||
DoLoadSpritePalette(palette->data, paletteNum * 16);
|
||||
return paletteNum;
|
||||
}
|
||||
|
||||
void DoLoadSpritePalette(const u16 *src, u16 paletteOffset)
|
||||
{
|
||||
LoadPalette(src, OBJ_PLTT_OFFSET + paletteOffset, PLTT_SIZE_4BPP);
|
||||
LoadPaletteFast(src, OBJ_PLTT_OFFSET + paletteOffset, PLTT_SIZE_4BPP);
|
||||
}
|
||||
|
||||
u32 AllocSpritePalette(u16 tag)
|
||||
|
||||
@@ -228,6 +228,7 @@ u32 CalcByteArraySum(const u8 *data, u32 length)
|
||||
void BlendPalette(u16 palOffset, u16 numEntries, u8 coeff, u32 blendColor)
|
||||
{
|
||||
u16 i;
|
||||
struct PlttData *data2 = (struct PlttData *) & blendColor;
|
||||
for (i = 0; i < numEntries; i++)
|
||||
{
|
||||
u16 index = i + palOffset;
|
||||
@@ -235,7 +236,7 @@ void BlendPalette(u16 palOffset, u16 numEntries, u8 coeff, u32 blendColor)
|
||||
s8 r = data1->r;
|
||||
s8 g = data1->g;
|
||||
s8 b = data1->b;
|
||||
struct PlttData *data2 = (struct PlttData *)&blendColor;
|
||||
|
||||
gPlttBufferFaded[index] = RGB(r + (((data2->r - r) * coeff) >> 4),
|
||||
g + (((data2->g - g) * coeff) >> 4),
|
||||
b + (((data2->b - b) * coeff) >> 4));
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#define GET_GBA_PAL_BLUE(x) (((x) >> 10) & 0x1F)
|
||||
|
||||
#define SET_GBA_PAL(r, g, b) (((b) << 10) | ((g) << 5) | (r))
|
||||
#define SET_GBA_PAL_RGBA(r, g, b, a) (((a) << 15) | ((b) << 10) | ((g) << 5) | (r))
|
||||
|
||||
#define UPCONVERT_BIT_DEPTH(x) (((x) * 255) / 31)
|
||||
|
||||
@@ -578,8 +579,9 @@ void WriteGbaPalette(char *path, struct Palette *palette)
|
||||
unsigned char red = DOWNCONVERT_BIT_DEPTH(palette->colors[i].red);
|
||||
unsigned char green = DOWNCONVERT_BIT_DEPTH(palette->colors[i].green);
|
||||
unsigned char blue = DOWNCONVERT_BIT_DEPTH(palette->colors[i].blue);
|
||||
bool alpha = palette->colors[i].alpha;
|
||||
|
||||
uint16_t paletteEntry = SET_GBA_PAL(red, green, blue);
|
||||
uint16_t paletteEntry = SET_GBA_PAL_RGBA(red, green, blue, alpha);
|
||||
|
||||
fputc(paletteEntry & 0xFF, fp);
|
||||
fputc(paletteEntry >> 8, fp);
|
||||
|
||||
@@ -10,6 +10,7 @@ struct Color {
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
bool alpha;
|
||||
};
|
||||
|
||||
struct Palette {
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
// Blue - "0 0 255\r\n"
|
||||
// Brown - "150 75 0\r\n"
|
||||
|
||||
#define MAX_LINE_LENGTH 11
|
||||
#define MAX_LINE_LENGTH 64
|
||||
|
||||
void ReadJascPaletteLine(FILE *fp, char *line)
|
||||
{
|
||||
@@ -156,6 +156,42 @@ void ReadJascPalette(char *path, struct Palette *palette)
|
||||
FATAL_ERROR("Garbage after color data.\n");
|
||||
|
||||
fclose(fp);
|
||||
|
||||
// Try to parse alpha/high bit info for colors from auxiliary .pla file
|
||||
char *dot = strrchr(path, '.');
|
||||
if (strcmp(dot, ".pal") != 0)
|
||||
return;
|
||||
strcpy(dot, ".pla"); // replace .pal with .pla
|
||||
fp = fopen(path, "rb");
|
||||
|
||||
if (fp == NULL)
|
||||
return;
|
||||
|
||||
int i = 0;
|
||||
// Keep reading lines until number of colors is reached or we run out
|
||||
while (i < palette->numColors && fgets(line, MAX_LINE_LENGTH, fp) != NULL)
|
||||
{
|
||||
if (line[0] == '#') // comment line; ignore
|
||||
continue;
|
||||
|
||||
char *s = line;
|
||||
char *end;
|
||||
int colorIndex;
|
||||
|
||||
if (!ParseNumber(s, &end, 10, &colorIndex))
|
||||
FATAL_ERROR("Failed to parse aux color index.\n");
|
||||
|
||||
s = end;
|
||||
|
||||
if (colorIndex >= palette->numColors)
|
||||
FATAL_ERROR("Aux color index %d out of bounds.\n", colorIndex);
|
||||
|
||||
palette->colors[colorIndex].alpha = 1; // set alpha color
|
||||
// fprintf(stderr, "Color index: %d\n", colorIndex);
|
||||
i++;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void WriteJascPalette(char *path, struct Palette *palette)
|
||||
|
||||
@@ -291,7 +291,7 @@ void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **a
|
||||
|
||||
void HandlePngToJascPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||
{
|
||||
struct Palette palette = {};
|
||||
struct Palette palette = {0};
|
||||
|
||||
ReadPngPalette(inputPath, &palette);
|
||||
WriteJascPalette(outputPath, &palette);
|
||||
@@ -299,7 +299,7 @@ void HandlePngToJascPaletteCommand(char *inputPath, char *outputPath, int argc U
|
||||
|
||||
void HandlePngToGbaPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||
{
|
||||
struct Palette palette = {};
|
||||
struct Palette palette = {0};
|
||||
|
||||
ReadPngPalette(inputPath, &palette);
|
||||
WriteGbaPalette(outputPath, &palette);
|
||||
@@ -307,7 +307,7 @@ void HandlePngToGbaPaletteCommand(char *inputPath, char *outputPath, int argc UN
|
||||
|
||||
void HandleGbaToJascPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED)
|
||||
{
|
||||
struct Palette palette = {};
|
||||
struct Palette palette = {0};
|
||||
|
||||
ReadGbaPalette(inputPath, &palette);
|
||||
WriteJascPalette(outputPath, &palette);
|
||||
@@ -340,7 +340,7 @@ void HandleJascToGbaPaletteCommand(char *inputPath, char *outputPath, int argc,
|
||||
}
|
||||
}
|
||||
|
||||
struct Palette palette = {};
|
||||
struct Palette palette = {0};
|
||||
|
||||
ReadJascPalette(inputPath, &palette);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user