Game Modes
The game uses a global “Game Mode” variable to indicate in which type of screen you are. Screens include the main menu, the startup sequence, walking around on the overworld, watching a cutscene, navigating a debug menu, etc. These game modes can take up to 3 arguments and have 5 mode-specific variables.
Each game mode has an init, update and destroy function. These live in a table at 0x08065CBC/0x08065C48
(US/JP). The update function is called on each game frame (at ~30fps). When switching between game modes, first the
destroy function of the current game mode is called, then the init function of the new game mode.
The game mode data is defined like so:
typedef struct {
u32 dwCurrentGameMode; // 0x00
u32 dwCurrentGameModeArg1; // 0x04
u32 dwCurrentGameModeArg2; // 0x08
u32 dwCurrentGameModeArg3; // 0x0C
u32 dwModeState; // 0x10
u32 dwModeScratchA; // 0x14
u32 dwModeTimer; // 0x18
u32 dwModeSubState; // 0x1C
u32 dwModeScratchB; // 0x20
} GameModeStackContext;
This struct lives at 3 positions (US/JP):
0x03003EF4/0x03003F54: Current game mode0x03003F18/0x03003F78: Next/pending game mode0x03003F3C/0x03003F9C: Previous game mode
To initiate a game mode transition, overwrite dwCurrentGameMode of the pending game mode object with the new game mode
id, ORed with 0x80. For example, to enter the debug menu, set it to 0x99. For a proper transition, also fill in the
arguments and zero out dwModeState, dwModeTimer and any unused arguments.
List of modes
None (0x00)
This game mode contains no code and will simply hang, until a new game mode is requested externally. This game mode does not get used in-game.
Startup (0x01)
LanguageSelect (0x02)
MainMenu (0x03)
LoadGame (0x04)
Options (0x05)
MinigameMenu (0x06)
NewGameMenu (0x07)
Overworld (0x08)
Arguments: (?, roomId, ?)
Battle (0x09)
Arguments:
(roomId, variantId, kindId): Standard/random encounter, indexes into random encounter table astable[room][kind][variant](encounterId, unused, 0xFF): Scripted encounter