From 656fd08ee828024f5a0e888f293ca95b7a83cd64 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Sat, 12 Aug 2023 11:44:35 -0400 Subject: [PATCH] Gamestate table (#1354) * gamestate_table.h * move macros * bss * format --- include/macros.h | 10 ---- include/segment_symbols.h | 5 -- include/tables/gamestate_table.h | 17 +++++++ include/variables.h | 3 -- include/z64game.h | 21 ++++++++ src/code/graph.c | 30 ++++-------- src/code/z_game_dlftbls.c | 48 ++++++++++++------- .../actors/ovl_Dm_Char01/z_dm_char01.c | 2 +- 8 files changed, 81 insertions(+), 55 deletions(-) create mode 100644 include/tables/gamestate_table.h diff --git a/include/macros.h b/include/macros.h index f28315815a..b03d01b3ed 100644 --- a/include/macros.h +++ b/include/macros.h @@ -53,21 +53,11 @@ // To be used with `Magic_Add`, but ensures enough magic is added to fill the magic bar to capacity #define MAGIC_FILL_TO_CAPACITY (((void)0, gSaveContext.magicFillTarget) + (gSaveContext.save.saveInfo.playerData.isDoubleMagicAcquired + 1) * MAGIC_NORMAL_METER) -#define CONTROLLER1(gameState) (&(gameState)->input[0]) -#define CONTROLLER2(gameState) (&(gameState)->input[1]) -#define CONTROLLER3(gameState) (&(gameState)->input[2]) -#define CONTROLLER4(gameState) (&(gameState)->input[3]) - #define CHECK_BTN_ALL(state, combo) (~((state) | ~(combo)) == 0) #define CHECK_BTN_ANY(state, combo) (((state) & (combo)) != 0) #define CHECK_FLAG_ALL(flags, mask) (((flags) & (mask)) == (mask)) -#define ALIGN8(val) (((val) + 7) & ~7) -#define ALIGN16(val) (((val) + 0xF) & ~0xF) -#define ALIGN64(val) (((val) + 0x3F) & ~0x3F) -#define ALIGN256(val) (((val) + 0xFF) & ~0xFF) - #define BIT_FLAG_TO_SHIFT(flag) \ ((flag & 0x80) ? 7 : \ (flag & 0x40) ? 6 : \ diff --git a/include/segment_symbols.h b/include/segment_symbols.h index 214970933b..6bf163379b 100644 --- a/include/segment_symbols.h +++ b/include/segment_symbols.h @@ -71,11 +71,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(daytelop) DECLARE_OVERLAY_SEGMENT(kaleido_scope) DECLARE_OVERLAY_SEGMENT(player_actor) diff --git a/include/tables/gamestate_table.h b/include/tables/gamestate_table.h new file mode 100644 index 0000000000..958e2fa4a6 --- /dev/null +++ b/include/tables/gamestate_table.h @@ -0,0 +1,17 @@ +/** + * Gamestate Table + * + * DEFINE_GAMESTATE should be used for gamestates with code loaded from an overlay + * - Argument 0: Gamestate type name (without State suffix, also used for Init and Destroy function names) + * - Argument 1: Gamestate id enum name + * - Argument 2: Gamestate overlay segment name without the `ovl_` prefix + * + * 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) +/* 0x06 */ DEFINE_GAMESTATE(DayTelop, GAMESTATE_DAYTELOP, daytelop) diff --git a/include/variables.h b/include/variables.h index 0afe12864a..e1fa8b4912 100644 --- a/include/variables.h +++ b/include/variables.h @@ -226,9 +226,6 @@ extern ActorId gMaxActorId; extern BgCheckSceneSubdivisionEntry sSceneSubdivisionList[]; extern BgSpecialSceneMaxObjects sCustomDynapolyMem[]; -extern GameStateOverlay gGameStateOverlayTable[]; -extern s32 gGraphNumGameStates; - // extern UNK_TYPE4 D_801BDAC0; // extern UNK_TYPE4 D_801BDAC4; // extern UNK_TYPE4 D_801BDAC8; diff --git a/include/z64game.h b/include/z64game.h index 87dc80764c..87dffe5c37 100644 --- a/include/z64game.h +++ b/include/z64game.h @@ -12,6 +12,18 @@ struct GraphicsContext; struct GameState; +#define DEFINE_GAMESTATE_INTERNAL(typeName, enumName) enumName, +#define DEFINE_GAMESTATE(typeName, enumName, name) DEFINE_GAMESTATE_INTERNAL(typeName, enumName) + +typedef enum GameStateId { +#include "tables/gamestate_table.h" + /* 0x07 */ GAMESTATE_ID_MAX +} GameStateId; + +#undef DEFINE_GAMESTATE +#undef DEFINE_GAMESTATE_INTERNAL + + typedef void (*GameStateFunc)(struct GameState* gameState); typedef struct { @@ -85,6 +97,15 @@ extern f32 gFramerateDivisorHalf; extern f32 gFramerateDivisorThird; +extern GameStateOverlay gGameStateOverlayTable[GAMESTATE_ID_MAX]; +extern GameStateId gGraphNumGameStates; + + +#define CONTROLLER1(gameState) (&(gameState)->input[0]) +#define CONTROLLER2(gameState) (&(gameState)->input[1]) +#define CONTROLLER3(gameState) (&(gameState)->input[2]) +#define CONTROLLER4(gameState) (&(gameState)->input[3]) + #define STOP_GAMESTATE(curState) \ do { \ GameState* state = curState; \ diff --git a/src/code/graph.c b/src/code/graph.c index 24a554dc27..fe1542f66c 100644 --- a/src/code/graph.c +++ b/src/code/graph.c @@ -75,27 +75,17 @@ void Graph_SetNextGfxPool(GraphicsContext* gfxCtx) { GameStateOverlay* Graph_GetNextGameState(GameState* gameState) { GameStateFunc gameStateInit = GameState_GetInit(gameState); - if (gameStateInit == Setup_Init) { - return &gGameStateOverlayTable[0]; - } - if (gameStateInit == MapSelect_Init) { - return &gGameStateOverlayTable[1]; - } - if (gameStateInit == ConsoleLogo_Init) { - return &gGameStateOverlayTable[2]; - } - if (gameStateInit == Play_Init) { - return &gGameStateOverlayTable[3]; - } - if (gameStateInit == TitleSetup_Init) { - return &gGameStateOverlayTable[4]; - } - if (gameStateInit == FileSelect_Init) { - return &gGameStateOverlayTable[5]; - } - if (gameStateInit == DayTelop_Init) { - return &gGameStateOverlayTable[6]; + // Generates code to match gameStateInit to a gamestate entry and returns it if found +#define DEFINE_GAMESTATE_INTERNAL(typeName, enumName) \ + if (gameStateInit == 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 return NULL; } diff --git a/src/code/z_game_dlftbls.c b/src/code/z_game_dlftbls.c index 7336b01f6f..cb3aee3170 100644 --- a/src/code/z_game_dlftbls.c +++ b/src/code/z_game_dlftbls.c @@ -6,22 +6,38 @@ #include "overlays/gamestates/ovl_title/z_title.h" #include "z_title_setup.h" -#define GAMESTATE_OVERLAY(name, init, destroy, size) \ - { \ - NULL, SEGMENT_ROM_START(ovl_##name), SEGMENT_ROM_END(ovl_##name), SEGMENT_START(ovl_##name), \ - SEGMENT_END(ovl_##name), 0, init, destroy, 0, 0, 0, size \ - } -#define GAMESTATE_OVERLAY_INTERNAL(init, destroy, size) \ - { NULL, 0, 0, NULL, NULL, 0, init, destroy, 0, 0, 0, size } +// Linker symbol declarations (used in the table below) +#define DEFINE_GAMESTATE(_typeName, _enumName, segmentName) DECLARE_OVERLAY_SEGMENT(segmentName) +#define DEFINE_GAMESTATE_INTERNAL(_typeName, _enumName) -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)), - GAMESTATE_OVERLAY(daytelop, DayTelop_Init, DayTelop_Destroy, sizeof(DayTelopState)), +#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, segmentName) \ + { NULL, \ + (uintptr_t)SEGMENT_ROM_START(ovl_##segmentName), \ + (uintptr_t)SEGMENT_ROM_END(ovl_##segmentName), \ + SEGMENT_START(ovl_##segmentName), \ + SEGMENT_END(ovl_##segmentName), \ + NULL, \ + typeName##_Init, \ + typeName##_Destroy, \ + NULL, \ + NULL, \ + 0, \ + sizeof(typeName##State) }, + +GameStateOverlay gGameStateOverlayTable[GAMESTATE_ID_MAX] = { +#include "tables/gamestate_table.h" }; -s32 gGraphNumGameStates = ARRAY_COUNT(gGameStateOverlayTable); +#undef DEFINE_GAMESTATE +#undef DEFINE_GAMESTATE_INTERNAL + +GameStateId gGraphNumGameStates = GAMESTATE_ID_MAX; diff --git a/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c b/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c index 96941b8cc9..f31b6d3081 100644 --- a/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c +++ b/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c @@ -3,7 +3,7 @@ * Overlay: ovl_Dm_Char01 * Description: Woodfall scene objects (temple, water, walls, etc) */ -#include "prevent_bss_reordering.h" + #include "z_dm_char01.h" #include "objects/object_mtoride/object_mtoride.h" #include "overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h"