Difference between revisions of "Modules/game menu/Usage"

From MSX Game Library

< Modules‎ | game menu

(Created page with "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 e...")
(No difference)

Revision as of 00:20, 5 January 2024

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 table 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);