Difference between revisions of "Modules/game menu"
From MSX Game Library
< Modules
(Created page with "The {{MOD|game_menu}} module automatically manages menus based on tables representing each page and its interactions. == Dependencies == * {{MOD|input}} * {{MOD|print}} == S...") |
(Replaced content with "{{MODULE |name=game_menu |category=Gameplay |dependency1=input |dependency2=print |dependency3= |sample1=s_menu |sample2= |sample3= }}") |
||
(13 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | + | {{MODULE | |
− | + | |name=game_menu | |
− | = | + | |category=Gameplay |
− | + | |dependency1=input | |
− | + | |dependency2=print | |
− | + | |dependency3= | |
− | + | |sample1=s_menu | |
− | + | |sample2= | |
− | + | |sample3= | |
− | + | }} | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− |
Latest revision as of 00:21, 5 January 2024
The game_menu module automatically manages menus based on tables representing each page and its interactions.
Contents
Usage
To use this module, include "game_menu.h" in your source code, and add "game_menu" to the modules list (LibModules) in your project's configuration file (project_config.js).
The module is data-driven, meaning that its behavior is completely determined by the data passed to it. The system is based on two structures.
Structure that represents an entry on a menu page:
// Menu item structure typedef struct { const c8* Text; // Name of the item u8 Type; // Type of the item (see <MENU_ITEM_TYPE>) void* Action; // Action associated to the item (depends on item type) i16 Value; // Value associated to the item (depends on item type) } MenuItem;
Structure that represents a complete page:
// Menu structure typedef struct { const c8* Title; // Title of the page (NULL means no title) MenuItem* Items; // List of the page's menu entries u8 ItemNum; // Number of the page's menu entries callback Callback; // Function to be called when page is opened } Menu;
A page is generally composed of a list of entries, and a menu is composed of a list of pages.
The menu system initialization function (Menu_Initialize) takes as its parameter an array of pages representing a whole menu.
Menu item types
Here's a list of possible menu entry types and how they use the 'Action' and 'Value' parameters:
MENU_ITEM_ACTION // Execute callback function defined in 'Action' with 'Value' as a parameter MENU_ITEM_GOTO // Change page to the one defined in 'Value' MENU_ITEM_INT // Handle pointer to 8-bits integer defined in 'Action' (can be incremented or decremented) MENU_ITEM_BOOL // Handle pointer to boolean defined in 'Action' (can be turned ON or OFF) MENU_ITEM_TEXT // Handle pointer to zero-terminated string (non-interactive) MENU_ITEM_EMPTY // Empty entry (used to create an empty gap in the menu) MENU_ITEM_UPDATE // Execute callback function defined in 'Action' with 'Value' as a parameter every frame
Exemple
Here's an example of a menu with 2 pages (Main and Option) each containing 5 entries.
// Entries description for the Main menu const MenuItem g_MenuMain[] = { { "Start", MENU_ITEM_ACTION, MenuAction_Start, 1 }, // Entry to start a game (will trigger MenuAction_Start with 'value' parameter equal to '1') { "Options", MENU_ITEM_GOTO, NULL, MENU_OPTION }, // Entry to go to Option menu page (page are defined using their index into the menu structure) { "Align", MENU_ITEM_GOTO, NULL, MENU_ALIGN }, // Entry to go to Align menu page { NULL, MENU_ITEM_EMPTY, NULL, 0 }, // Blank entry to create a gap { "Exit", MENU_ITEM_ACTION, MenuAction_Start, 0 }, // Entry to exit the game (will trigger MenuAction_Start with 'value' parameter equal to '0') }; // Entries description for the Option menu MenuItem g_MenuOption[] = { { "Mode", MENU_ITEM_ACTION, MenuAction_Screen, 0 }, // Entry to change the screen mode (will trigger MenuAction_Screen) { "Integer", MENU_ITEM_INT, &g_Integer, 0 }, // Entry to edit an integer { "Boolean", MENU_ITEM_BOOL, &g_Boolean, 0 }, // Entry to edit a boolean { NULL, MENU_ITEM_EMPTY, NULL, 0 }, // Blank entry to create a gap { "Back", MENU_ITEM_GOTO, NULL, MENU_MAIN }, // Entry to go back to the main menu }; // List of all menus const Menu g_Menus[MENU_MAX] = { { "Main", g_MenuMain, numberof(g_MenuMain), NULL }, // MENU_MAIN { "Options", g_MenuOption, numberof(g_MenuOption), NULL }, // MENU_OPTION };
Then, you can initialize the menu using: Menu_Initialize(&g_Menus);
Samples
See module use cases in the sample programs:
Settings
Library configuration (msxgl_config.h):
#define MENU_USE_DEFAULT_CALLBACK TRUE // Use default input/print callback #define MENU_SCREEN_WIDTH MENU_VARIABLE // Screen width #define MENU_FRAME_X 0 // Frame position X #define MENU_FRAME_Y 6 // Frame position Y #define MENU_FRAME_WIDTH 32 // Frame width #define MENU_FRAME_HEIGHT 8 // Frame height #define MENU_CHAR_CLEAR '\0' // Clear character #define MENU_CHAR_CURSOR '@' // Cursor character #define MENU_CHAR_TRUE 'O' // True character #define MENU_CHAR_FALSE 'X' // False character #define MENU_CHAR_LEFT '<' // Left edit character #define MENU_CHAR_RIGHT '>' // Right edit character #define MENU_TITLE_X 4 // Title position X #define MENU_TITLE_Y 6 // Title position Y #define MENU_ITEM_X 6 // Item label X position #define MENU_ITEM_Y 8 // Item label X position #define MENU_ITEM_X_GOTO 6 // Goto type item label X position #define MENU_ITEM_ALIGN MENU_ITEM_ALIGN_LEFT // Item label alignment #define MENU_ITEM_ALIGN_GOTO MENU_ITEM_ALIGN_LEFT // Goto type item label alignment #define MENU_VALUE_X 14 // Item value X position // Type of cursor // - MENU_CURSOR_MODE_NONE No cursor // - MENU_CURSOR_MODE_CHAR Character cursor // - MENU_CURSOR_MODE_SPRT Sprite cursor #define MENU_CURSOR_MODE MENU_CURSOR_MODE_CHAR #define MENU_CURSOR_OFFSET (-2) // Cursor X position offset
Dependencies
Dependency on other modules:
Documentation