Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
205 lines
7.3 KiB
C
205 lines
7.3 KiB
C
// ____________________________
|
|
// ██▀▀█▀▀██▀▀▀▀▀▀▀█▀▀█ │ ▄▄▄ ▄▄
|
|
// ██ ▀ █▄ ▀██▄ ▀ ▄█ ▄▀▀ █ │ ▀█▄ ▄▀██ ▄█▄█ ██▀▄ ██ ▄███
|
|
// █ █ █ ▀▀ ▄█ █ █ ▀▄█ █▄ │ ▄▄█▀ ▀▄██ ██ █ ██▀ ▀█▄ ▀█▄▄
|
|
// ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀────────┘ ▀▀
|
|
// Hello world sample
|
|
//─────────────────────────────────────────────────────────────────────────────
|
|
#include "msxgl.h"
|
|
#include "game/menu.h"
|
|
|
|
//=============================================================================
|
|
// DEFINES
|
|
//=============================================================================
|
|
|
|
// Library's logo
|
|
#define MSX_GL6 "\x01\x02\x03\x04\x05\x06"
|
|
#define MSX_GL8 "\x02\x03\x04\x05"
|
|
|
|
// Index of all menu pages
|
|
enum MENU_PAGES
|
|
{
|
|
MENU_MAIN = 0, // Main page
|
|
MENU_OPTION, // Options page
|
|
MENU_ALIGN, // Align page
|
|
MENU_MAX, // Number of menu
|
|
};
|
|
|
|
// Prototype of functions used by the menu entries
|
|
const c8* MenuAction_Screen(u8 op, i8 value);
|
|
const c8* MenuAction_Start(u8 op, i8 value);
|
|
|
|
typedef struct
|
|
{
|
|
const c8* Name;
|
|
u8 Mode;
|
|
u8 Width;
|
|
const u8* Font;
|
|
const c8* Title;
|
|
u8 Color;
|
|
} ModeInfo;
|
|
|
|
void SetupScreen();
|
|
|
|
//=============================================================================
|
|
// READ-ONLY DATA
|
|
//=============================================================================
|
|
|
|
// Font
|
|
#include "font/font_mgl_sample6.h"
|
|
#include "font/font_mgl_sample8.h"
|
|
|
|
// 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 equal to '1')
|
|
{ "Options", MENU_ITEM_GOTO, NULL, MENU_OPTION }, // Entry to go to Option menu page
|
|
{ "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 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
|
|
};
|
|
|
|
// Entries description for the Align menu
|
|
MenuItem g_MenuAlign[] =
|
|
{
|
|
{ "Left", MENU_ITEM_TEXT+MENU_ITEM_ALIGN_LEFT, NULL, 0 }, // Entry display a text aligned to left
|
|
{ "Center", MENU_ITEM_TEXT+MENU_ITEM_ALIGN_CENTER, NULL, 0 }, // Entry display a text aligned to center
|
|
{ "Right", MENU_ITEM_TEXT+MENU_ITEM_ALIGN_RIGHT, NULL, 0 }, // Entry display a text aligned to right
|
|
{ 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
|
|
{ "Align", g_MenuAlign, numberof(g_MenuAlign), NULL }, // MENU_ALIGN
|
|
};
|
|
|
|
const ModeInfo g_ModeInfos[] =
|
|
{
|
|
{ "Screen 0 (T1)", VDP_MODE_SCREEN0, 40, g_Font_MGL_Sample6, MSX_GL6 " MENU SAMPLE", COLOR_DARK_BLUE },
|
|
{ "Screen 1 (G1)", VDP_MODE_SCREEN1, 32, g_Font_MGL_Sample8, MSX_GL8 " MENU SAMPLE", COLOR_DARK_GREEN },
|
|
{ "Screen 2 (G2)", VDP_MODE_SCREEN2, 32, g_Font_MGL_Sample8, MSX_GL8 " MENU SAMPLE", COLOR_DARK_RED },
|
|
};
|
|
|
|
//=============================================================================
|
|
// MEMORY DATA
|
|
//=============================================================================
|
|
|
|
// Test to end the program
|
|
bool g_Exit = FALSE;
|
|
|
|
// Current screen mode index
|
|
u8 g_ScreenId = 0;
|
|
|
|
// A dummy integer value to be modified in menu
|
|
u8 g_Integer = 0;
|
|
|
|
// A dummy boolean value to be modified in menu
|
|
bool g_Boolean = TRUE;
|
|
|
|
//=============================================================================
|
|
// FUNCTIONS
|
|
//=============================================================================
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Program entry point
|
|
const c8* MenuAction_Screen(u8 op, i8 value)
|
|
{
|
|
value;
|
|
switch (op) // 'op' represents the operation performed on the menu entry when this function is called.
|
|
{
|
|
case MENU_ACTION_GET: // Recovers the value of the input to be displayed.
|
|
return g_ModeInfos[g_ScreenId].Name;
|
|
|
|
case MENU_ACTION_SET: // Manages trigger button pressing
|
|
case MENU_ACTION_INC: // Manages right direction pressing
|
|
g_ScreenId = (g_ScreenId + 1) % numberof(g_ModeInfos);
|
|
SetupScreen();
|
|
break;
|
|
|
|
case MENU_ACTION_DEC: // Manages left direction pressing
|
|
g_ScreenId = (g_ScreenId + numberof(g_ModeInfos) - 1) % numberof(g_ModeInfos);
|
|
SetupScreen();
|
|
break;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Program entry point
|
|
const c8* MenuAction_Start(u8 op, i8 value)
|
|
{
|
|
if (op == MENU_ACTION_SET) // Manages trigger button pressing
|
|
{
|
|
switch (value) // 'value' is defined in the menu entries table (so the same callback function can be called several times with different values)
|
|
{
|
|
case 0: // Exit value
|
|
g_Exit = TRUE;
|
|
break;
|
|
|
|
case 1: // Game start value
|
|
break;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Program entry point
|
|
void SetupScreen()
|
|
{
|
|
const ModeInfo* info = &g_ModeInfos[g_ScreenId];
|
|
|
|
// Initialize screen mode
|
|
VDP_SetColor(info->Color); // Change background color
|
|
VDP_SetMode(info->Mode); // Set screen mode
|
|
VDP_ClearVRAM(); // Clean the whole VRAM
|
|
|
|
// Initialize font
|
|
Print_SetTextFont(info->Font, 1); // Set font characters
|
|
Print_SetColor(COLOR_WHITE, info->Color); // Set font color
|
|
|
|
// Header text
|
|
Print_DrawTextAt(0, 0, info->Title);
|
|
Print_DrawLineH(0, 1, info->Width);
|
|
|
|
// Force menu redraw
|
|
Menu_SetDirty(); // Force current page to be redrawn
|
|
Menu_SetScreenWidth(info->Width); // Set the current screen width (need MENU_SCREEN_WIDTH to be set to MENU_VARIABLE)
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Program entry point
|
|
void main()
|
|
{
|
|
SetupScreen();
|
|
|
|
Menu_Initialize(g_Menus); // Initialize the menu
|
|
// Menu_SetInputCallback(Menu_HandleInput);
|
|
// Menu_SetDrawCallback(Menu_HandleDraw);
|
|
// Menu_SetEventCallback(Menu_HandleEvent);
|
|
Menu_DrawPage(MENU_MAIN); // Display the first page
|
|
|
|
while (!g_Exit)
|
|
{
|
|
// Wait for screen synchronization (50 or 60 Hz)
|
|
Halt();
|
|
|
|
// Update menu
|
|
Menu_Update();
|
|
}
|
|
} |