37#include "text/msg_ids.h"
50#define LOBBY_UNIT_RECORD_BYTES 0x154
51#define LOBBY_RECOVERY_RECORD_BYTES 0x140
52#define LOBBY_UNIT_RECORD_COUNT 3
53#define LOBBY_LINK_READY_MASK 3
54#define LOBBY_TRANSFER_RETRY_LIMIT 24
55#define LOBBY_SEND_TIMEOUT_FRAMES 600
56#define LOBBY_RECEIVE_TIMEOUT_FRAMES 900
57#define LOBBY_PEER_WAIT_FRAMES 25
68#define PEER_TAG(a, b, c, d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24))
72#if (LANGUAGE == LANGUAGE_GERMAN)
76#elif (LANGUAGE == LANGUAGE_SPANISH)
80#elif (LANGUAGE == LANGUAGE_FRENCH)
84#elif (LANGUAGE == LANGUAGE_ITALIAN)
89#if (LANGUAGE != LANGUAGE_JAPANESE)
115#define LOBBY_NO_RESULT 0
117#define LOBBY_NO_RESULT
147 if (entrance == 11 || entrance == 9) {
156 s32 serialPlayerId = -1;
170 if (serialPlayerId != 0)
217 for (i = 0; i < 4; i++) {
360 if (record[0x12a] != 0) {
366 if (namePrefix[nameIndex] != 0) {
372 }
while (namePrefix[nameIndex] != 0);
374#if (LANGUAGE == LANGUAGE_GERMAN) || (LANGUAGE == LANGUAGE_SPANISH) || \
375 (LANGUAGE == LANGUAGE_FRENCH) || (LANGUAGE == LANGUAGE_ITALIAN)
376 namePrefix[nameIndex] =
' ';
377 prefixLength = nameIndex + 1;
379 prefixLength = nameIndex;
381 for (nameIndex = 14; nameIndex >= prefixLength; nameIndex--) {
382 record[nameIndex] = record[nameIndex - prefixLength];
384 for (nameIndex = 0; nameIndex < prefixLength; nameIndex++) {
385 record[nameIndex] = namePrefix[nameIndex];
428 if ((transferResult =
433 result = transferResult;
445 if (ownerCount > 0) {
458 source = (
const u8 *)partyAddress;
460 remaining = ownerCount;
462 u8 ownerId = *source++;
468 }
while (remaining != 0);
501 for (i = 7; i >= 0; i--) {
504 for (i = 0; i < ownerCount; i++) {
511 slotMap[ownerIds[i]] = i - 128;
514 if (transferResult == -1) {
515 result = transferResult;
554 heap[0x12a] = tries = 0;
558 result = transferResult;
577 for (j = 0; j < recoveryList->
count; j++) {
581 for (k = j; k < recoveryList->
count - 1; k++) {
584 recoveryList->
count--;
589 result = transferResult;
618 s32 receivedOwnerCount;
648 result = receivedOwnerCount;
650 if (receivedOwnerCount < 0) {
784 *destination++ = *source++;
785 }
while (i <= 0x7c7);
803 messageBase = MsgLobbyPleaseSpeakWhen;
822 messageId = messageBase + 7;
829 messageId = messageBase + 6;
832 messageId = messageBase + 3;
844 messageId = messageBase + 3;
903 if ((facing - 0xa001) <= 0x3ffe) {
904 messageBase = MsgLobbyLooksLikeFirst;
916 messageBase = MsgLobbyLooksLikeFirstTime;
946 displayedPreset = -1;
948 if (presetIndex != displayedPreset) {
951 displayedPreset = presetIndex;
959 if (presetIndex < 0) {
972 if (presetIndex >= 0) {
975 if (presetIndex < 0) {
978 }
else if (loadResult != 0) {
1013 if (count > ownerLimit) {
1016 for (i = 0; i < count; i++) {
1032 s32 messageBase = MsgLobbyCantWaitLets;
1044 messageBase = MsgLobbyWonToldCountOn;
1046 messageBase = MsgLobbyWonWithoutWell;
1049 messageBase = MsgLobbyNotFaultLost;
1051 messageBase = MsgLobbyKnewLostBecause;
1053 }
else if (isaacPresent != 0) {
1054 if (speakerPresent == 0)
1055 messageBase = MsgLobbyGoingFightAlone;
1057 messageBase = MsgLobbyTryingGetAway;
1089 message = MsgLobbyTravelingWarrior;
1092 message = MsgLobbyThreeAlliesFight;
1096 message = MsgLobbyBattleArenaOld;
1118 message = MsgLobbyThreeAlliesFightLinkedFinals;
1120 message = MsgLobbyThreeAlliesFightLinked;
1123 message = MsgLobbyChangeOrderParty;
1205 for (digit = 0; digit <= 2; digit++) {
1221 void (*callback)(void);
1241 for (i = 0; i < 8; i++) {
1260 messageOffset = wins * 2 + 2;
1261 if (messageOffset > 14) {
1310 score = *(
u16 *)score;
1351 if (*(
u16 *)score < (
u16)v) {
1407 0, 1, 1, 1, 1, 0, 0, 0,
1411 { 11,
CONDITION_ALWAYS, 128, 0, 164,
FACING_NORTH, 0, 16, 0, 416, 310, 0 },
1412 { 10,
CONDITION_ALWAYS, 352, 0, 148,
FACING_NORTH, 0, 16, 0, 416, 310, 0 },
1413 { 8,
CONDITION_ALWAYS, 216, 0, 200,
FACING_WEST, 0, 16, 0, 416, 310, 0 },
1414 { 9,
CONDITION_ALWAYS, 216, 0, 200,
FACING_WEST, 0, 16, 0, 416, 310, 0 },
1415 { 1,
CONDITION_ALWAYS, 216, 0, 288,
FACING_NORTH, 0, 16, 0, 416, 310, 0 },
1416 { 0,
CONDITION_ALWAYS, 216, 0, 208,
FACING_NORTH, 0, -1, -1, -1, -1, 0 },
1526 MSGNO(MsgFieldWelcomeToBattleArenaWherePeople)},
1536 MSGNO(MsgFieldToUseSummonQuicklyDjinnMust)},
1539 MSGNO(MsgFieldRemoveDjinnYouRarelyUseSo)},
1541 MSGNO(MsgFieldMonsterBattleRulesSayYouAll)},
1545 MSGNO(MsgFieldAllTheWarriorsAreImpressiveSo)},
struct FieldActor * Object_GetById(s32 actor)
Returns an actor, or NULL if it does not exist.
s32 DebugParty_LoadPreset(s32 preset)
Debug: replaces the party with the members of preset number preset.
Which units are in a battle, and the Djinn recovery list.
The task scheduler: tasks, their order and the scheduler's state.
void(*) SchedulerCallback(void)
The definitions of characters, classes, Djinn and enemies, and a level up's result.
The engine calls the debug menus import, and their palette swatch tiles.
The edition's language, for C to compare (LANGUAGE == LANGUAGE_GERMAN).
static s32 FieldScheduler_AddCallback(SchedulerCallback callback, s32 priority)
Registers a main-image scheduler callback.
static s32 FieldGameFlag_GetByte(s32 flag)
static void FieldUi_AdjustValueWithoutLimit(s32 message, u16 *buffer)
static void FieldGameFlag_SetByte(s32 flag, s32 value)
The scene script layer: the engine services a scene's events call, declared once (Engine_EventBegin,...
void Engine_ActorFaceActor(s32 actor, s32 target, s32 frames)
void Engine_SanctumOpen(s32 priest)
s32 Engine_EventChooseYesNo(s32 actor, s32 flags)
s32 Engine_TaskRemoveCallback(void(*callback)(void))
void Engine_EventWaitForScreen(void)
void Engine_EventOpenScreen(void)
s32 Engine_EventOpenMessage(s32 speaker, s32 flags)
void Engine_GameFlagSet(s32 flag)
void Engine_MapCopyCellsTo(s32 srcX, s32 srcY, s32 destX, s32 destY, s32 width, s32 height)
void Engine_GameFlagClear(s32 flag)
void Engine_ActorWaitForMove(s32 actor)
static void Map_CopyCellAttributes(s32 srcX, s32 srcY, s32 width, s32 height, s32 destX, s32 destY)
void Engine_ActorWalkTo(s32 actor, s32 x, s32 z)
s32 Engine_GameFlagIsSet(s32 flag)
static void Actor_SetSpeed(s32 actor, s32 speed, s32 acceleration)
void Engine_MapRedraw(void)
#define SCENE_TRANSITION(style, variant)
The scene table formats: entrances, exits, placements and events, and the macros that write them.
#define SCENE_EXITS(scene)
#define IF_FLAG_SET(flag)
@ TALK_FACE_PARTY_AND_BACK
#define EVENT_SCRIPT(script)
#define PLACEMENT_SHARE_PREVIOUS_SPRITE
The scene service layer: one typed inline for each engine service a scene calls by its own name,...
Game flags, named where their meaning is shown.
#define FLAG_SCENE_TEMP_05
#define FLAG_SCENE_TEMP_03
#define FLAG_MONSTER_BATTLE_WINS
Monster battles won in a row, added to the monsters' level; -1 after the series ends.
#define FLAG_MONSTER_BATTLE
The link lobby's battle against a monster when no opponent is linked: formations matched to the party...
#define FLAG_SCENE_TEMP_00
#define FLAG_SCENE_TEMP_02
#define FLAG_SCENE_TEMP_01
#define FLAG_SCENE_TEMP_04
#define FLAG_LINK_PARTY_COUNT
the members the linked opponent sent
s32 Sound_LoadPresetParameters(s32 preset)
Copies the mixer code for sound preset preset (0 to 4; anything else is 0) from ROM into IwramSoundPr...
The frame loop's globals: lag counts, the CPU load display and the VBlank flags.
volatile u8 gIdleSleepEnabled
Sleep after three idle minutes.
struct UiWindow * UiText_OpenMessageWindow(s32 message, s32 x, s32 y, u32 packed)
Opens a window sized to a message near tile (x, y) and starts typing the message into it.
s32 UiWork_IsComplete(void)
Returns 1 when every message channel has finished its text (or is idle), and 0 while one is still typ...
GameState, the game's state: play time, coins, the scene and the leader's position,...
#define Battle_SetStart(mode)
Sets the battle start type.
struct GameState gGameState
The work slots of gWorkSlot, read through their own names.
struct EffectStep gMapCellBuffer[]
Map cells; battle effects reuse this as a particle array.
u16 gLinkPeerSignatures[][12]
24 bytes per peer
The screen blend's globals and the graphics routines.
void * Runtime_BumpAllocateAlternatePool(s32 size)
As MemAlloc, but tries EWRAM first.
void * Runtime_AllocateBlock(s32 kind, s32 size)
As Runtime_AllocateHeapBlock, but tries EWRAM first, for blocks that need room more than speed: the b...
The main-image routines scene overlays import.
struct UiWindow * Engine_DebugCreateWindow(s32 x, s32 y, s32 width, s32 height, s32 attrs)
void UiText_DrawQuantity(u32 value, u32 kind)
The hardware's I/O registers and their bits, as pret names them.
Saving, disabling and restoring the interrupt master enable.
#define IRQ_UNLOCK(saved)
Restores the IME value saved by IRQ_LOCK.
#define IRQ_LOCK(saved)
Disables interrupts and saves IME in saved; IRQ_UNLOCK restores it.
The IWRAM call layer: the routines the game keeps resident in IWRAM, each at its fixed address,...
static s32 Iwram_CopyWords(volatile void *destination, const volatile void *source, s32 size)
static s32 Iwram_ClearWords(void *destination, s32 size)
The keypad state the VBlank interrupt keeps.
volatile u32 gKeysPressed
Keys that went down this frame.
volatile u32 gKeysRepeat
Pressed keys, repeating while held: after 19 frames, then every 6.
s32 SceneData_ReturnZero(void)
static s32 LinkLobby_ReceivePartyRecords(void)
Receives three unit records and a recovery table; returns the occupied count or the original transfer...
static s32 LinkLobby_LeaveArena(void)
Removes the link IRQ handlers, restores sound parameters and leaves the arena.
static s32 LinkLobby_InitializeSerial(void)
Reinitializes the serial runtime while interrupts are locked.
struct ScenePlacement gLinkLobbyBattlePlacements[]
#define LOBBY_SEND_TIMEOUT_FRAMES
static s32 LinkLobby_ReportMonsterRecord(s32 actorId)
Reports the stored consecutive-monster-battle record when nonzero.
static s32 LinkLobby_ReportDisconnection(void)
Resets the disconnect trigger and displays the attendant's warning.
static s32 LinkLobby_CopyPartyOwnerIds(u16 *ownerIds)
Copies at most three active owner IDs, terminates with 0xff, and returns count.
static s32 LinkLobby_SaveMonsterBattleResults(void)
Shows saving/saved messages around the monster battle record save.
#define PEER_TAG(a, b, c, d)
struct ScenePlacement gLinkLobbyPlacements[]
static s32 LinkLobby_PeerSlotMatches(s32 slot)
Checks one language-specific peer signature slot and updates link-side flags.
#define LOBBY_PEER_WAIT_FRAMES
u8 * LinkLobby_GetEntrances(void)
static s32 LinkLobby_PromptToParticipate(void)
Prompts for participation unless entering battle or a prompt is still pending.
static s32 sLinkLobbyWaitFrames
static s32 LinkLobby_PartyContains(s32 ownerId)
Tests the first three linked-battle owners, or four outside linked finals.
static s32 LinkLobby_SaveBattleResults(void)
Shows saving/saved messages around the linked battle results save.
static s32 LinkLobby_EnterBattle(void)
Waits for the opponent, exchanges parties and starts the arena battle.
static s32 LinkLobby_OpenSanctum(s32 actorId)
Runs the sanctum service for this actor within an event.
static s32 LinkLobby_SendPartyRecords(void)
Sends up to three active owners, pads missing records, then sends recovery data.
#define LOBBY_TRANSFER_RETRY_LIMIT
#define LOBBY_UNIT_RECORD_BYTES
u8 gLinkLobby_SlotColumns[]
static s32 LinkLobby_ChooseBattleMode(void)
Offers a linked challenge or a monster battle and publishes the response.
#define LOBBY_UNIT_RECORD_COUNT
static s32 LinkLobby_ExplainPartyOrder(s32 actor)
Alternates between the linked-party size and reorder instructions.
s32 LinkLobby_SelectPlacements(void)
Selects the post-link-battle placements for entrances nine and eleven.
s32 LinkLobby_RunRoundResult(void)
Processes the entry's monster/link result and restores lobby polling.
static s32 LinkLobby_PollPeerReady(void)
#define LOBBY_RECEIVE_TIMEOUT_FRAMES
static s32 LinkLobby_ChooseDebugPartyPreset(s32 actorId)
Selects a debug party preset; A accepts and B cancels.
static void LinkLobby_WriteSlotValue(s32 slot)
Publishes a protocol slot value in the outgoing signature payload.
static UNUSED void State_NoOp(void)
UNUSED: the original empty lobby callback.
struct SceneEvent gLinkLobbyEvents[]
static s32 LinkLobby_TalkByProgress(s32 actor)
Chooses each party member's dialogue from participation and round outcome.
struct SceneEntrance gLinkLobbyEntrances[]
static s32 LinkLobby_ReportWinTallies(s32 actor)
Reports total or consecutive linked wins according to the leader's facing.
#define LOBBY_NO_RESULT
What a lobby handler's early exit returns.
#define LOBBY_RECOVERY_RECORD_BYTES
u8 * LinkLobby_GetExits(void)
u8 * LinkLobby_GetEvents(void)
#define LOBBY_LINK_READY_MASK
static s32 LinkLobby_ExchangePartyRecords(void)
Orders send/receive by link side and records the received owner count.
static s32 LinkLobby_TalkToAttendant(s32 actor)
Selects the attendant's rules or post-battle line from the round outcome.
const s32 gLinkLobby_SlotValues[]
static s32 LinkLobby_DrawThreeDigitValue(s32 value)
Draws a right-to-left three-digit value capped at 999, then redraws the map.
void Map_SetLayerEntryFlag(u32 channelIndex)
Pauses tile animation channel channelIndex by setting its paused byte.
void Map_ClearLayerEntryFlag(u32 channelIndex)
Resumes tile animation channel channelIndex by clearing its paused byte.
The heaps: allocating and freeing blocks.
void Runtime_BumpFree(void *buffer)
void Runtime_ReleaseHeapBlock(s32 slot)
The reel game's title lettering.
void Event_SetDestination(s32 scene, s32 entrance)
Makes the event leave for the given entrance of the given scene: raises the exit request 999 and writ...
s32 Party_CountActiveOwners(void)
Returns the number of party members, counted from game flags 0 to 7.
void Field_RequestBattleFromEncounterTable(s32 zoneNo, s32 slotNo)
Sets up a battle with enemy group slot of encounter table zone.
void Event_SetDefeatDestination(s32 scene, s32 entrance)
Sets where the party wakes up after losing a battle (gGameState.defeatScene and defeatEntrance).
void Event_SetNextDestination(s32 scene, s32 entrance)
Sets the scene and entrance that the field goes to next (gGameState.nextScene and nextEntrance).
FIELD_AT_OFFSET and the entity and camera views older scene code reads.
Scene numbers, named after their places.
s32 Scheduler_SetTaskFlags(SchedulerCallback callback, u32 mask)
Stores mask as the flags of the task running callback; bit 0 keeps it running while the overlay tasks...
s32 SerialRuntime_BeginReceive(void *destination)
Starts receiving the partner's blocks into destination: sets the receive destination and clears the r...
s32 SerialRuntime_BeginSend(void *source, s32 size)
Starts sending size bytes from source to the partner in 20-byte blocks: sets the send source,...
void SerialRuntime_RemoveIrqHandlers(void)
Clears gSerialExchangeActive, which stops the per-frame exchange, and removes the link interrupt hand...
s32 SerialRuntime_GetActiveTransfers(void)
Returns bit 0 while a send runs and bit 1 while a receive runs.
void SerialRuntime_Initialize(void)
Resets the serial port into multiplayer mode, installs the serial and timer 3 interrupt handlers,...
The link cable's runtime: serial packets, registers and transfer state.
volatile u16 gLinkStatus
Link status, updated by the VBlank exchange handler.
volatile u16 gSerialReceivedSize
volatile: tagged where it steers, in BattleLink_ReceiveActions (tbs battle.c) and LinkLobby_ReceivePa...
static __inline__ void SerialRuntime_ResetTransferState(void)
struct SerialTransferState gSerialTransfer
Song and sound effect ids, indices into gSound_SongTable.
struct EventWork * gEventWork
void Engine_EventEnd(void)
void Engine_AudioPlayCue()
void Engine_EventBegin(void)
void Engine_EventSetMessage()
void Engine_EventShowMessage()
One side's Djinn recovery list: up to 64 entries and their count.
struct DjinnRecoveryEntry entries[64]
One side's Djinn recovery table, as Djinn_GetRecoveryTable returns it.
struct DjinnRecoveryList list
The running scene's event work: its placement and event tables, its actors, the triggers and exit it ...
s16 raisedTrigger
a raised event for Scene_RunRaisedEvent
s32 startTransition
SCENE_TRANSITION(style, variant).
The game's state: play time, coins, the scene and the leader's position, the active party and the opt...
u8 idleSleepEnabled
the option, saved from gIdleSleepEnabled
u8 activeOwners[8]
the party in order
s32 selectedActor
the leader: its unit and its actor
u16 linkTallies[8]
The link lobby's tallies: 4 the total wins and 7 the consecutive wins it reports, 3 cleared on choosi...
The partner console's signature as the lobby reads it: a word for each slot column.
A scene entrance: where and facing which way the party arrives, and the camera's bounds there (-1 for...
A scene event: its kind and detail, the trigger it answers, its condition and its value (a message or...
An actor a scene places: its sprite, the condition for placing it, how it behaves,...
u8 payload[20]
one block of the data sent
A window: a framed rectangle of the tilemap with its sprite outputs, its opening or closing animation...
The system's routines and globals: interrupts, BIOS sound bias, random numbers and sleep.
Values that differ by patch level or language, chosen once for their code.
#define LOBBY_PREFIX_LIMIT
void UiText_DrawNumber(s32 value, s32 width, struct UiWindow *window, s32 x, s32 y)
Draws a number (width as UiText_FormatNumber) into a text canvas window at pixel (x,...
s32 DjinnRecovery_TickTwenty(void)
Runs DjinnRecovery_Tick twenty times, which sets every recovering Djinni of a party member with HP.
The integer types, TRUE, UNUSED and the fixed-address macros.
void Party_RestoreHpPp(s32 cureConditions)
Restores every party member's HP and PP; with cureConditions 1 it also cures poison and haunting.
struct BattleUnit * UnitGet(u32 owner)
Returns the unit record of owner: 0 to 7 are the playable characters in the game state,...
void * Djinn_GetRecoveryTable(s32 enemySide)
Returns the party's Djinn recovery bank (the standby Djinn and their turns to recover),...
s32 SaveState_ProcessSelectedSlot(void)
Writes the 64-byte save stamp (gSaveStamp, which lies in the first half of the save buffer) into the ...
void UiWork_ClearValueNameTables(void)
Empties the table of message arguments.
void RenderOutput_PrepareForRedraw(struct UiWindow *window)
Clears a window's contents: redraws its empty frame and releases the render outputs it carries.
void UiWork_Finalize(struct UiWindow *window, s32 instant)
Closes a window: clears its contents and remembers its last rectangle.