diff --git a/include/segment_symbols.h b/include/segment_symbols.h index 61e2a3cbb5..e0741dc8c4 100644 --- a/include/segment_symbols.h +++ b/include/segment_symbols.h @@ -64,10 +64,6 @@ DECLARE_SEGMENT(code) DECLARE_ROM_SEGMENT(code) DECLARE_BSS_SEGMENT(code) -DECLARE_OVERLAY_SEGMENT(title) -DECLARE_OVERLAY_SEGMENT(select) -DECLARE_OVERLAY_SEGMENT(opening) -DECLARE_OVERLAY_SEGMENT(file_choose) DECLARE_OVERLAY_SEGMENT(kaleido_scope) DECLARE_OVERLAY_SEGMENT(player_actor) DECLARE_OVERLAY_SEGMENT(map_mark_data) diff --git a/include/tables/gamestate_table.h b/include/tables/gamestate_table.h new file mode 100644 index 0000000000..280740fe2a --- /dev/null +++ b/include/tables/gamestate_table.h @@ -0,0 +1,16 @@ +/** + * Gamestate Table + * + * DEFINE_GAMESTATE should be used for gamestates with code loaded from an overlay + * - Argument 1: Gamestate type name (without State suffix, also used for Init and Destroy function names) + * - Argument 2: Gamestate id enum name + * - Argument 3: Gamestate overlay spec segment name + * + * DEFINE_GAMESTATE_INTERNAL should be used for gamestates that aren't an overlay, the first two arguments are the same as for DEFINE_GAMESTATE + */ +/* 0x00 */ DEFINE_GAMESTATE_INTERNAL(Setup, GAMESTATE_SETUP) +/* 0x01 */ DEFINE_GAMESTATE(MapSelect, GAMESTATE_MAP_SELECT, select) +/* 0x02 */ DEFINE_GAMESTATE(ConsoleLogo, GAMESTATE_CONSOLE_LOGO, title) +/* 0x03 */ DEFINE_GAMESTATE_INTERNAL(Play, GAMESTATE_PLAY) +/* 0x04 */ DEFINE_GAMESTATE(TitleSetup, GAMESTATE_TITLE_SETUP, opening) +/* 0x05 */ DEFINE_GAMESTATE(FileSelect, GAMESTATE_FILE_SELECT, file_choose) diff --git a/include/z64.h b/include/z64.h index 066d6af7b2..32d1a91d1e 100644 --- a/include/z64.h +++ b/include/z64.h @@ -697,6 +697,16 @@ typedef struct { /* 0x10 */ GameAllocEntry* head; } GameAlloc; // size = 0x14 +// Used in Graph_GetNextGameState in graph.c +#define DEFINE_GAMESTATE_INTERNAL(typeName, enumName) enumName, +#define DEFINE_GAMESTATE(typeName, enumName, name) DEFINE_GAMESTATE_INTERNAL(typeName, enumName) +typedef enum { +#include "tables/gamestate_table.h" + GAMESTATE_ID_MAX +} GameStateId; +#undef DEFINE_GAMESTATE +#undef DEFINE_GAMESTATE_INTERNAL + struct GameState; typedef void (*GameStateFunc)(struct GameState* gameState); diff --git a/src/code/graph.c b/src/code/graph.c index e5309966c7..3d53f891cb 100644 --- a/src/code/graph.c +++ b/src/code/graph.c @@ -116,24 +116,15 @@ void Graph_InitTHGA(GraphicsContext* gfxCtx) { GameStateOverlay* Graph_GetNextGameState(GameState* gameState) { void* gameStateInitFunc = GameState_GetInit(gameState); - if (gameStateInitFunc == Setup_Init) { - return &gGameStateOverlayTable[0]; - } - if (gameStateInitFunc == MapSelect_Init) { - return &gGameStateOverlayTable[1]; - } - if (gameStateInitFunc == ConsoleLogo_Init) { - return &gGameStateOverlayTable[2]; - } - if (gameStateInitFunc == Play_Init) { - return &gGameStateOverlayTable[3]; - } - if (gameStateInitFunc == TitleSetup_Init) { - return &gGameStateOverlayTable[4]; - } - if (gameStateInitFunc == FileSelect_Init) { - return &gGameStateOverlayTable[5]; + // Generates code to match gameStateInitFunc to a gamestate entry and returns it if found +#define DEFINE_GAMESTATE_INTERNAL(typeName, enumName) \ + if (gameStateInitFunc == typeName##_Init) { \ + return &gGameStateOverlayTable[enumName]; \ } +#define DEFINE_GAMESTATE(typeName, enumName, name) DEFINE_GAMESTATE_INTERNAL(typeName, enumName) +#include "tables/gamestate_table.h" +#undef DEFINE_GAMESTATE +#undef DEFINE_GAMESTATE_INTERNAL LOG_ADDRESS("game_init_func", gameStateInitFunc, "../graph.c", 696); return NULL; @@ -421,16 +412,14 @@ void Graph_ThreadEntry(void* arg0) { GraphicsContext gfxCtx; GameState* gameState; u32 size; - GameStateOverlay* nextOvl; + GameStateOverlay* nextOvl = &gGameStateOverlayTable[GAMESTATE_SETUP]; GameStateOverlay* ovl; char faultMsg[0x50]; - nextOvl = &gGameStateOverlayTable[0]; - osSyncPrintf("グラフィックスレッド実行開始\n"); // "Start graphic thread execution" Graph_Init(&gfxCtx); - while (nextOvl) { + while (nextOvl != NULL) { ovl = nextOvl; Overlay_LoadGameState(ovl); diff --git a/src/code/z_game_dlftbls.c b/src/code/z_game_dlftbls.c index bfce662484..8e9f00fecb 100644 --- a/src/code/z_game_dlftbls.c +++ b/src/code/z_game_dlftbls.c @@ -1,18 +1,35 @@ #include "global.h" -#define GAMESTATE_OVERLAY(name, init, destroy, size) \ - { \ - NULL, (uintptr_t)_ovl_##name##SegmentRomStart, (uintptr_t)_ovl_##name##SegmentRomEnd, \ - _ovl_##name##SegmentStart, _ovl_##name##SegmentEnd, NULL, init, destroy, NULL, NULL, 0, size \ - } -#define GAMESTATE_OVERLAY_INTERNAL(init, destroy, size) \ - { NULL, 0, 0, NULL, NULL, NULL, init, destroy, NULL, NULL, 0, size } +// Linker symbol declarations (used in the table below) +#define DEFINE_GAMESTATE(typeName, enumName, name) DECLARE_OVERLAY_SEGMENT(name) +#define DEFINE_GAMESTATE_INTERNAL(typeName, enumName) + +#include "tables/gamestate_table.h" + +#undef DEFINE_GAMESTATE +#undef DEFINE_GAMESTATE_INTERNAL + +// Gamestate Overlay Table definition +#define DEFINE_GAMESTATE_INTERNAL(typeName, enumName) \ + { NULL, 0, 0, NULL, NULL, NULL, typeName##_Init, typeName##_Destroy, NULL, NULL, 0, sizeof(typeName##State) }, + +#define DEFINE_GAMESTATE(typeName, enumName, name) \ + { NULL, \ + (uintptr_t)_ovl_##name##SegmentRomStart, \ + (uintptr_t)_ovl_##name##SegmentRomEnd, \ + _ovl_##name##SegmentStart, \ + _ovl_##name##SegmentEnd, \ + NULL, \ + typeName##_Init, \ + typeName##_Destroy, \ + NULL, \ + NULL, \ + 0, \ + sizeof(typeName##State) }, GameStateOverlay gGameStateOverlayTable[] = { - GAMESTATE_OVERLAY_INTERNAL(Setup_Init, Setup_Destroy, sizeof(SetupState)), - GAMESTATE_OVERLAY(select, MapSelect_Init, MapSelect_Destroy, sizeof(MapSelectState)), - GAMESTATE_OVERLAY(title, ConsoleLogo_Init, ConsoleLogo_Destroy, sizeof(ConsoleLogoState)), - GAMESTATE_OVERLAY_INTERNAL(Play_Init, Play_Destroy, sizeof(PlayState)), - GAMESTATE_OVERLAY(opening, TitleSetup_Init, TitleSetup_Destroy, sizeof(TitleSetupState)), - GAMESTATE_OVERLAY(file_choose, FileSelect_Init, FileSelect_Destroy, sizeof(FileSelectState)), +#include "tables/gamestate_table.h" }; + +#undef DEFINE_GAMESTATE +#undef DEFINE_GAMESTATE_INTERNAL