Browse Source

Add in-game menu

v2
Nathaniel Walizer 7 months ago
parent
commit
78a71959f6
2 changed files with 99 additions and 6 deletions
  1. +81
    -4
      src/linux/port.c
  2. +18
    -2
      src/menu.c

+ 81
- 4
src/linux/port.c View File

@@ -280,7 +280,7 @@ int64_t time_sleep_until(int64_t t_target) {
return t_diff * 1000; return t_diff * 1000;
} }


static nese_Action select_rom(platform_data* plat, char* file, int sz_file);
static nese_Action game_menu(platform_data* plat);


int nese_frame_ready(void* plat_data) { int nese_frame_ready(void* plat_data) {
platform_data* plat = (platform_data*)plat_data; platform_data* plat = (platform_data*)plat_data;
@@ -320,6 +320,7 @@ int nese_frame_ready(void* plat_data) {
nese_Action action = process_events(plat->sys); nese_Action action = process_events(plat->sys);
switch (action) { switch (action) {
case Action_Quit: case Action_Quit:
// TODO: Save SRAM
status = -1; status = -1;
break; break;


@@ -345,18 +346,23 @@ int nese_frame_ready(void* plat_data) {
break; break;


case Action_Menu: case Action_Menu:
action = select_rom(plat, plat->filename, PLAT_FILENAME_SIZE);
if (Action_OK == action) {
action = game_menu(plat);
if (Action_Reset == action) {
nes_reset(plat->sys); nes_reset(plat->sys);
} else if (Action_Save == action) {
status = save_state(plat->sys, plat->cart.filename);
} else if (Action_Load == action) {
status = load_state(plat->sys, plat->cart.filename);
} else if (Action_Quit == action || NULL == plat->sys->cart_header) { } else if (Action_Quit == action || NULL == plat->sys->cart_header) {
status = -1; status = -1;
} }
// TODO: Other Actions?
break; break;


default: default:
} }


// TODO: Perform more actions
// TODO: Perform more actions?


if (0 == status) { if (0 == status) {
plat->t_target += FRAME_TIME_NS; plat->t_target += FRAME_TIME_NS;
@@ -501,6 +507,8 @@ static nese_Action select_rom(platform_data* plat, char* file, int sz_file) {
nese_Action action = Action_OK; nese_Action action = Action_OK;
Menu_State menu = {0}; Menu_State menu = {0};


// TODO: Save SRAM

while (Action_OK == action || NULL == plat->sys->cart_header) { while (Action_OK == action || NULL == plat->sys->cart_header) {
action = run_rom_menu(plat, &menu, file, sz_file); action = run_rom_menu(plat, &menu, file, sz_file);
if (Action_OK == action) { if (Action_OK == action) {
@@ -522,6 +530,75 @@ static nese_Action select_rom(platform_data* plat, char* file, int sz_file) {
return action; return action;
} }


static nese_Action run_game_menu(platform_data* plat, Menu_State* state) {
static char* items[] = {
"Resume",
"Save",
"Restore",
"Reset",
"Select ROM",
"Exit",
};
static const nese_Action choices[] = {
Action_Cancel,
Action_Save,
Action_Load,
Action_Reset,
Action_Menu,
Action_Quit,
};
static const File_List options = {
.files = items,
.count = (sizeof(items) / sizeof(*items)),
};

Menu_State menu = {0};
if (NULL != state) menu = *state;

nese_Action action = run_menu(plat, &menu, &options, 100);
if (Action_Menu == action) {
action = Action_Cancel;
} else if (Action_OK == action) {
if ( menu.cursor >= 0 &&
menu.cursor < (sizeof(choices) / sizeof(*choices))) {
action = choices[menu.cursor];
}
}

if (NULL != state) *state = menu;

return action;
}

static nese_Action game_menu(platform_data* plat) {
nese_Action action = Action_OK;
Menu_State menu = {0};

while (Action_OK == action) {
action = run_game_menu(plat, &menu);

if (Action_Menu == action) {
// Select ROM
action = select_rom(plat, plat->filename, PLAT_FILENAME_SIZE);
if (Action_OK == action) {
// New ROM selected - Exit loop and reset
action = Action_Reset;

} else if (Action_Cancel == action) {
// No ROM selected - Keep the menu running
action = Action_OK;
}

if (NULL == plat->sys->cart_header) {
// A failed ROM load means we shouldn't return to the game menu
action = Action_Quit;
}
}
}

return action;
}



/* Platform Data */ /* Platform Data */




+ 18
- 2
src/menu.c View File

@@ -11,8 +11,8 @@ static nese_Action wait_for_input(void* plat, uint8_t* new_buttons) {
uint8_t changed = 0; uint8_t changed = 0;


while (0 == changed && Action_OK == action) { while (0 == changed && Action_OK == action) {
// TODO: Sleep
uint8_t buttons = input.gamepads[0].buttons; uint8_t buttons = input.gamepads[0].buttons;
// Sleep is implicit in nese_update_input
action = nese_update_input(plat, &input); action = nese_update_input(plat, &input);
changed = (~buttons & input.gamepads[0].buttons); changed = (~buttons & input.gamepads[0].buttons);
} }
@@ -22,6 +22,19 @@ static nese_Action wait_for_input(void* plat, uint8_t* new_buttons) {
return action; return action;
} }


static nese_Action wait_for_input_quiet(void* plat) {
nes_Input input = {0};
nese_Action action = nese_update_input(plat, &input);
uint8_t buttons = input.gamepads[0].buttons;

while (Action_Quit != action && buttons) {
action = nese_update_input(plat, &input);
buttons = input.gamepads[0].buttons;
}

return action;
}



nese_Action modal_popup(void* plat, const char* message, uint32_t color) { nese_Action modal_popup(void* plat, const char* message, uint32_t color) {
int w = 0; int w = 0;
@@ -98,7 +111,8 @@ static void show_menu(void* plat, const Menu_State* menu,
nese_draw_finish(plat); nese_draw_finish(plat);
} }


int run_menu(void* plat, Menu_State* state, const File_List* files, int x) {
nese_Action run_menu(void* plat, Menu_State* state,
const File_List* files, int x) {
Menu_State menu = {0}; Menu_State menu = {0};
if (NULL != state) { if (NULL != state) {
menu = *state; menu = *state;
@@ -160,5 +174,7 @@ int run_menu(void* plat, Menu_State* state, const File_List* files, int x) {


if (NULL != state) *state = menu; if (NULL != state) *state = menu;


wait_for_input_quiet(plat);

return action; return action;
} }

Loading…
Cancel
Save