Difference between revisions of "Modules/game menu"

From MSX Game Library

< Modules

(Dependencies)
(Replaced content with "{{MODULE |name=game_menu |category=Gameplay |dependency1=input |dependency2=print |dependency3= |sample1=s_menu |sample2= |sample3= }}")
 
Line 1: Line 1:
The {{MOD|game_menu}} module automatically manages menus based on tables representing each page and its interactions.
+
{{MODULE
 
+
|name=game_menu
== Dependencies ==
+
|category=Gameplay
Dependency on other modules:
+
|dependency1=input
* {{MOD|input}}
+
|dependency2=print
* {{MOD|print}}
+
|dependency3=
 
+
|sample1=s_menu
== Settings ==
+
|sample2=
Modules can be customized into the project's <tt>msxgl_config.h</tt> file to fullfill your needs:
+
|sample3=
#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 ENU_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 (WIP)
 
#define MENU_CURSOR_MODE MENU_CURSOR_MODE_CHAR
 
#define MENU_CURSOR_OFFSET (-2) // Cursor X position offset
 
 
 
== Usage ==
 
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 (<tt>Menu_Initialize</tt>) 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 itnialize the menu using: <tt>Menu_Initialize(&g_Menus);</tt>
 
 
 
== Annexe ==
 
* See also: Sample program {{SAMPLE|s_menu}}
 
 
 
== Documentation ==
 
{{FRAME_DOC|game_menu}}
 
 
 
[[category:Module]][[category:Module/Gameplay]]
 

Latest revision as of 01:21, 5 January 2024

game_menu

Code: game_menu.h

Category: Gameplay

Dependencies:

Samples:

The game_menu module automatically manages menus based on tables representing each page and its interactions.

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