16 KiB
Executable File
Functions
Apply VRAM/OAM
- SafeUpdateSprites: Set BG map mode to 0 (disabled) and disable OAM update + UpdateSprites + enable OAM update + DelayFrame + restore original state of BG map mode and OAM update
- UpdateSprites: Compute state of overworld sprites to wShadowOAM. Disable OAM update while editing wShadowOAM, and restore its original state when finished
- ApplyPals: Copy wBGPals1 into wBGPals2 and wOBPals1 into wOBPals2. Does not request pal update during vblank by itself
- ApplyAttrmap: Set BG map mode to 2 (pals) and delay 4 frames, and finally restore original state BG map mode. If LCD disabled instead copy all pals at once immediately
- ApplyTilemap: Set BG map mode to 1 (tiles) and delay 4 frames. If wSpriteUpdatesEnabled is non-0, instead call CopyTilemapAtOnce to do it all in one frame. This delays the next vblank to LY ~$7f
Load font
- LoadFont_NoOAMUpdate: LoadFrame + Hide Window + LoadStandardFont with OAM update disabled
- LoadOverworldFont_NoOAMUpdate: LoadOverworldFontAndFrame + hide Window with OAM update disabled
Textboxes
- Textbox1bpp: TextboxBorder + TextboxAttributes1bpp
- Textbox2bpp: _OverworldTextbox + TextboxAttributes2bpp
- SpeechTextbox1bpp: Textbox1bpp with speech location and dimensions
- SpeechTextbox2bpp: Textbox2bpp with speech location and dimensions
- ClearTextbox: Clear the inside of a speech textbox (fill with " ")
- PrintTextboxText: Print text in speech textbox coordinates with letter delay
- PrintText1bpp, FarPrintText1bpp: SpeechTextbox1bpp + UpdateSprites + ApplyTilemap + ClearTextbox + PrintTextboxText
- PrintText2bpp: SpeechTextbox2bpp + UpdateSprites + ApplyTilemap + ClearTextbox + PrintTextboxText
- MapTextbox: ClearTextbox + redraw tile behind cursor + SafeUpdateSprites + disable OAM update + ApplyTilemap + PrintTextboxText + enable OAM update
- MenuBox: Calls Textbox1bpp or Textbox2bpp, depending on the value of wText2bpp, with menu location and dimensions.
Overworld map scrolling
- LoadScreenTilemap: From the metatile-based 24x20 map in wSurroundingTiles, load the corresponding 20x18 tiles to wTilemap. Later, BackupBGMap* from ScrollMap* copies new row/column from wTilemap to wBGMapBuffer. _ScrollBGMapPalettes populates wBGMapPalBuffer based on the tiles at wBGMapBuffer. These are read during vblank by UpdateBGMapBuffer.
- LoadScreenAttrmapPals: Load wAttrmap palette numbers based on the tileset palettes of the current map. Called only by LoadScreenTilemapAndAttrmapPals.
- LoadScreenTilemapAndAttrmapPals: LoadScreenTilemap + LoadScreenAttrmapPals. Often used to reload screen after closing a text box.
Overworld map anchoring
- ReanchorBGMap_NoOAMUpdate: LoadScreenTilemapAndAttrmapPals + HDMATransferTilemapAndAttrmap_OpenAndCloseMenu, then fill BG map with all black while Window is displayed, finally anchor map and objects. Shall by followed by CopyTilemapAtOnce or by a HDMATransferTilemapAndAttrmap_* to redraw the screen.
- OpenText1bpp, OpenText2bpp: ClearMenuAndWindowData + ReanchorBGMap_NoOAMUpdate + SpeechTextbox1bpp + HDMATransferTilemapAndAttrmap_OpenAndCloseMenu + hide Window
- OpenText1bpp: Loads 1bpp font (LoadFont_NoOAMUpdate)
- OpenText2bpp: Doesn't load 2bpp font
- RefreshScreen: Same as OpenText functions but doesn't call any SpeechTextbox
VRAM transfer
- Request1bpp, Request2bpp: Copy 1bpp or 2bpp tiles at a rate of TILES_PER_CYCLE (8) per frame during vblank. Wait until complete
- Copy1bpp, Copy2bpp: Copy 1bpp or 2bpp tiles immediately
- Get1bpp, Get2bpp: Call Copy1bpp or Copy2bpp if LCD disabled. Request1bpp or Request2bpp otherwise
- HDMATransfer1bpp: Copy 1bpp tiles via HDMA. Maximum 16 tiles per frame
- HDMATransfer2bpp: Copy 2bpp tiles via HDMA. No hardcoded limit. Timing considers 1 tile per hblank
- Get1bppViaHDMA, Get2bppViaHDMA: Call Copy1bpp or Copy2bpp if LCD disabled. HDMATransfer1bpp or HDMATransfer2bpp otherwise
- HDMATransferTilemapAndAttrmap_OpenAndCloseMenu, HDMATransferTilemapAndAttrmap_OverworldEffect: Similar, but with slightly different scanline timing. So they're essentially like RefreshScreen minus the anchoring part.
HUD
- EnableWindowHUD: Configure LCD interrupt in LYC=LY mode with corresponding LYC.
- DisableWindowHUD: Configure LCD interrupt in hblank mode
- LoadHUD: Load the HUD at wWhichHUD to the top of wTilemap and wAttrmap
- LoadWindowHUD: Like LoadHUD, but for HUDs that require a Window overlay. Only does anything if hWindowHUDLY is non-0
- ConstructOverworldHUDTilemap: Draw the overworld HUD's tilemap into wOverworldHUDTiles
- TransferOverworldHUDToBGMap: Transfer overworld HUD to vBGMap1/vBGMap3 during v/hblank(s). Tilemap is read from wOverworldHUDTiles, attrmap is all PAL_BG_TEXT | PRIORITY.
- RefreshOverworldHUD: ConstructOverworldHUDTilemap + TransferOverworldHUDToBGMap
Scripts
- refreshscreen: RefreshScreen
- reloadmappart: LoadScreenTilemapAndAttrmapPals + GetMovementPermissions + HDMATransferTilemapAndAttrmap_OverworldEffect + UpdateSprites. Similar to refreshscreen, but does not reanchor. On the other hand, it refreshes movement permissions. Often used after a block change or field move, which can affect collisions.
Changes
RAM addresses
-
hCurBoardEvent: holds a BOARDEVENT_ value.
-
wTurnData ~ wTurnDataEnd: not preserved on save, and cleared at the beginning of BoardMenuScript (i.e. on turn begin). It's part of wMapStatus ~ wMapStatusEnd, so it's also cleared by StartMap. Includes:
- wDieRoll
- wSpacesLeft
-
Addresses within wCurMapData ~ wCurMapDataEnd: preserved on save. Initialized when entering a level (in StartMap), and updated accordingly throughout the level. Includes:
- wCurLevel: this one is not initialized in StartMap, but in LevelSelectionMenu (where it is also used), and stays static during the level.
- wCurTurn
- wCurSpace
- wCurLevelCoins
- wCurLevelExp
- wCurSpaceStruct:
- wCurSpaceXCoord
- wCurSpaceYCoord
- wCurSpaceEffect for non-branch spaces, or wCurSpaceBranchStructPtr (two bytes) for branch spaces
- wCurSpaceNextSpace for non-branch spaces
-
Addresses within wPlayerData ~ wPlayerDataEnd: preserved on save. Includes:
- wUnlockedLevels: flag array that tracks progression regarding which levels have been unlocked.
- wClearedLevelsStage: flag array that tracks progression regarding which levels have been cleared. Each level can have up to four clearable endings (N).
- wUnlockedTechniques: flag array that tracks progression regarding which techniques have been unlocked.
- wCurOverworldMiscPal
-
These addresses share memory region with string buffers from wStringBuffer3 onwards. They are placed in memory in the following order.
- wTempSpaceStruct: Temporary scope. Same structure as wCurSpaceStruct
- wTempSpaceBranchStruct: Temporary scope. The structure is four bytes for next space for each direction (R/L/U/D; -1 if unavailable direction) followed by four bytes for required techniques for each direction (R/L/U/D)
- wViewMapModeRange, wViewMapModeDisplacementY, wViewMapModeDisplacementX: Temporary scope during a Vew Map mode session.
- wBeforeViewMapYCoord, wBeforeViewMapXCoord, wBeforeViewMapMapGroup, wBeforeViewMapMapNumber, wBeforeViewMapDirection: Temporary scope during a Vew Map mode session. Used to preserve player state before entering View Map mode.
-
Additional addresses for View Map mode, that share memory region with wCurBattleMon and wCurMoveNum, which are not used outside of battle:
- wPlayerMockYCoord, wPlayerMockXCoord: Used to handle the player mock sprite through map connections during View Map mode.
-
Addresses for talker events:
- wSeenTrainer* addresses have been repurposed as wSeenTrainerOrTalker*
- wSeenTrainerOrTalkerIsTalker: added right before wSeenTrainerOrTalker*.
- wTempTalker ~ wTempTalkerEnd: allocated to the same address space as wTempTrainer. Same scope as wTempTrainer, but for talker events.
-
Address spaces for backing up the map state (disabled spaces and map objects). Located outside of WRAM banks 0 and 1.
- wDisabledSpacesBackups: preserved on save to sDisabledSpacesBackups.
- wMapObjectsBackups: preserved on save to sMapObjectsBackups.
-
Other WRAM 0 addresses (not preserved on save):
- wText2bpp
- wWhichHUD
- wExitOverworldReason
Overworld workflow
OverworldLoop
is called fromGameMenu_WorldMap
with eitherhMapEntryMethod
=MAPSETUP_ENTERLEVEL
orhMapEntryMethod
=MAPSETUP_CONTINUE
.StartMap
resetswCurTurn
andwCurSpace
ifMAPSETUP_ENTERLEVEL
.StartMap
setshCurBoardEvent
toBOARDEVENT_DISPLAY_MENU
.wScriptFlags2
is cleared.wMapStatus
is set toMAPSTATUS_HANDLE
causingHandleMap
to be called.MapEvents
(fromHandleMap
) callsPlayerEvents
.CheckBoardEvent
queuesBoardMenuScript
which is executed byScriptEvents
.BoardMenuScript.Upkeep
saves the game, clearswTurnData[]
, increaseswCurTurn
, and loads current space towCurSpaceStruct[]
.- If player exits, the
exitoverworld
script setswMapStatus
toMAPSTATUS_DONE
. This causesOverworldLoop
to return back to the game menu. Exit this workflow.
- If player exits, the
- Player rolls die and the animation plays. After the animation,
wDisplaySecondarySprites.SECONDARYSPRITES_SPACES_LEFT_F
is set andhCurBoardEvent
is set toBOARDEVENT_HANDLE_BOARD
. At the end of thisHandleMap
iteration,CheckPlayerState
setswMapEventStatus
toMAPEVENTS_ON
(wScriptFlags2
is not touched so it remains cleared). - In the next
HandleMap
iteration,CheckBoardEvent
fromPlayerEvents
jumps to.board
and then to.no_space_effect
due towScriptFlags2[4]
not being set. - Execution continues in
PlayerEvents
;OWPlayerInput
is eventually called, and thusDoPlayerMovement
. Here,StepTowardsNextSpace
computes based onwCurSpaceNextSpace
what direction key to write towCurInput
, causing the player to begin a movement in that direction. - The player may need to turn to a different direction through the
ChangeDirectionScript
(whenDoPlayerMovement
returns withPLAYERMOVEMENT_TURN
). Otherwise or after that,CheckPlayerState
setswMapEventStatus
toMAPEVENTS_OFF
, - When the step finishes (i.e.
PLAYERSTEP_STOP_F
becomes set) in someHandleMap
iteration,CheckPlayerState
setswScriptFlags2
to $ff andwMapEventStatus
toMAPEVENTS_ON
. - In the next
HandleMap
iteration,CheckBoardEvent.board
is called withwScriptFlags2[4]
set.- If
wCurSpaceNextSpace
matchesNEXT_SPACE_IS_ANCHOR_POINT
: If player is at a tile with an anchor event,wCurSpaceNextSpace
is updated with the next space byte of salid anchor event.wScriptFlags2[4]
is reset. Go back to 7. - If player is not above a tile (
wPlayerTile
) with a space collision:wScriptFlags2[4]
is reset. Go back to 7. - If player is above a tile, the corresponding space script is queued to be executed by
ScriptEvents
in the currentHandleMap
iteration.wScriptFlags2[4]
is reset. Continue to 11.
- If
- The space script loads the value of
wCurSpaceNextSpace
intowCurSpace
, and loads the new space data towCurSpaceStruct[]
. Unless the space is a Branch Space or a Union Space,wSpacesLeft
is decreased.- If the space is a Branch Space, the branch data is loaded to
wTempSpaceBranchStruct
. Then the player is prompted to choose a valid direction.wCurSpaceNextSpace
is populated with the next space that corresponds to the chosen direction. Go back to 6. - If the space is an End Space, a fading out animation plays and then the
exitoverworld
script setswMapStatus
toMAPSTATUS_DONE
. This causesOverworldLoop
to return back to the game menu. Exit this workflow.
- If the space is a Branch Space, the branch data is loaded to
- If
wSpacesLeft
is non-0, go back to 6. - The script code specific to the space type of the landed-on space is executed.
- If player whites out in battle,
Script_BattleWhiteout
executesexitoverworld
. Exit this workflow.
- If player whites out in battle,
- The landed-on space is disabled by executing a block change that converts it into a Grey Space.
hCurBoardEvent
is set toBOARDEVENT_END_TURN
.CheckBoardEvent
does nothing in this state. In the first subsequentHandleMap
iteration where no other kind of event triggers causingPlayerEvents
to return early,hCurBoardEvent
is set toBOARDEVENT_DISPLAY_MENU
. - Go back to 3
View Map mode workflow
- Pressing SELECT in the board menu triggers View Map mode.
hCurBoardEvent
is set toBOARDEVENT_VIEW_MAP_MODE
, player state (coordinates as well as current map in order to support connected maps) is backed up,wPlayerFlags[INVISIBLE_F]
is set, and a static mockup of the player object is loaded to the lastwMapObject
and, in the background, to the firstwObjectStruct
is available. - The board event handler in
CheckBoardEvent
listens for the B button being pressed (except when a DPAD key is simultaneously held). When B is pressed, a script (a singlereloadmapafterviewmapmode
) to exit from View Map mode is queued to be executed byScriptEvents
. Otherwise,DoPlayerMovement.ViewMapMode
handles movement input in this mode. - When requested exit of View Map mode via B button,
reloadmapafterviewmapmode
setshMapEntryMethod
toMAPSETUP_EXITVIEWMAP
,hMapEntryMethod
toSPAWN_FROM_RAM
(required by the map setup commandEnterMapSpawnPoint
to restore the backed up player state), loadsMAPSTATUS_ENTER
tpwMapStatus
, and resetswPlayerFlags[INVISIBLE_F]
(the mocked player object naturally disappears when the map reloads). - Then:
a) If View Map mode was entered from the board menu,
BOARDEVENT_REDISPLAY_MENU
is loaded. It is the same asBOARDEVENT_DISPLAY_MENU
but skipsBoardMenuScript.Upkeep
. b) If View Map mode was entered from the branch menu, insteadBOARDEVENT_RESUME_BRANCH
is loaded, usingwPlayerSpriteSetupFlags[PLAYERSPRITESETUP_CUSTOM_FACING_F]
to maintain the facing direction according to the direction (SPRITEMOVEDATA_*
) of the mocked player object.BOARDEVENT_RESUME_BRANCH
makes sure to shortcut the branch space script by callingBranchSpaceScript_PromptPlayer
directly and avoiding the recomputation of the branch struct that would cause corruption.BOARDEVENT_HANDLE_BOARD
is loaded immediately byBOARDEVENT_RESUME_BRANCH
.
- In View Map mode, regular collisions except for
COLL_OUT_OF_BOUNDS
are ignored whereas going off-limits (i.e. outside of the map limits in a direction where there is no connected map) or off-range is accounted for. - Events other than warpless connections are ignored in View Map mode (as well as button actions, like while in
BOARDEVENT_HANDLE_BOARD
). wTileDown
,wTileUp
, etc., otherwise unused, are borrowed by in order to signal valid directions toInitSecondarySprites
(e.g.wTileDown=COLL_OUT_OF_BOUNDS
means that DOWN direction is not valid).- In View Map mode, the overworld delay is 1 rather than 2.
UpdatePlayerCoords
tracks the displacement during View Map mode in the X and Y axes in order to monitor the allowed range.