(RMenu) Big refactor

This commit is contained in:
twinaphex 2012-12-17 05:30:28 +01:00
parent 6750808e56
commit 8e98968c85
3 changed files with 224 additions and 137 deletions

View File

@ -50,7 +50,6 @@
#include "rmenu.h"
static bool set_libretro_core_as_launch;
filebrowser_t browser;
@ -59,8 +58,6 @@ unsigned set_shader = 0;
unsigned currently_selected_controller_menu = 0;
char m_title[256];
static uint64_t old_state = 0;
static const struct retro_keybind _rmenu_nav_binds[] = {
{ 0, 0, (enum retro_key)0, (1ULL << RETRO_DEVICE_ID_JOYPAD_UP) | (1ULL << RARCH_ANALOG_LEFT_Y_DPAD_UP), 0 },
{ 0, 0, (enum retro_key)0, (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN) | (1ULL << RARCH_ANALOG_LEFT_Y_DPAD_DOWN), 0 },
@ -121,6 +118,10 @@ enum
RMENU_DEVICE_NAV_LAST
};
/*============================================================
EVENT CALLBACKS (AND RELATED)
============================================================ */
static void populate_setting_item(void *data, unsigned input)
{
item *current_item = (item*)data;
@ -613,9 +614,13 @@ void browser_render(void *data)
}
}
int select_file(void *data, uint64_t input)
int select_file(void *data, void *state)
{
menu *current_menu = (menu*)data;
rmenu_state_t *rstate = (rmenu_state_t*)state;
uint64_t input = rstate->input;
DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data;
char extensions[256], comment[256], path[PATH_MAX];
bool ret = true;
@ -727,9 +732,13 @@ int select_file(void *data, uint64_t input)
return 1;
}
int select_directory(void *data, uint64_t input)
int select_directory(void *data, void *state)
{
menu *current_menu = (menu*)data;
rmenu_state_t *rstate = (rmenu_state_t*)state;
uint64_t input = rstate->input;
DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data;
char path[PATH_MAX], msg[256];
bool ret = true;
@ -1567,9 +1576,13 @@ static void set_setting_action(void *data, unsigned switchvalue, uint64_t input)
}
}
static int select_setting(void *data, uint64_t input)
static int select_setting(void *data, void *state)
{
menu *current_menu = (menu*)data;
rmenu_state_t *rstate = (rmenu_state_t*)state;
uint64_t input = rstate->input;
DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data;
item *items = (item*)malloc(current_menu->max_settings * sizeof(*items));
unsigned i;
@ -1674,10 +1687,21 @@ static int select_setting(void *data, uint64_t input)
return 1;
}
int select_rom_input_iterate(void *data, uint64_t input)
int select_rom(void *data, void *state)
{
filebrowser_t *filebrowser = (filebrowser_t*)data;
menu *current_menu = (menu*)data;
rmenu_state_t *rstate = (rmenu_state_t*)state;
uint64_t input = rstate->input;
DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data;
char msg[128];
rmenu_default_positions_t default_pos;
filebrowser_t *filebrowser = &browser;
device_ptr->ctx_driver->rmenu_set_default_pos(&default_pos);
browser_update(filebrowser, input, rarch_console_get_rom_ext());
if (input & (1ULL << RMENU_DEVICE_NAV_SELECT))
menu_stack_push(GENERAL_VIDEO_MENU);
@ -1712,24 +1736,6 @@ int select_rom_input_iterate(void *data, uint64_t input)
}
}
return 1;
}
int select_rom(void *data, uint64_t input)
{
menu *current_menu = (menu*)data;
DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data;
char msg[128];
rmenu_default_positions_t default_pos;
filebrowser_t *filebrowser = &browser;
device_ptr->ctx_driver->rmenu_set_default_pos(&default_pos);
browser_update(filebrowser, input, rarch_console_get_rom_ext());
if(current_menu->input_iterate)
current_menu->input_iterate(filebrowser, input);
bool is_dir = filebrowser_get_current_path_isdir(filebrowser);
if (is_dir)
@ -1756,9 +1762,12 @@ int select_rom(void *data, uint64_t input)
return 1;
}
int ingame_menu_resize(void *data, uint64_t input)
int ingame_menu_resize(void *data, void *state)
{
menu *current_menu = (menu*)data;
rmenu_state_t *rstate = (rmenu_state_t*)state;
uint64_t input = rstate->input;
DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data;
filebrowser_t *filebrowser = NULL;
@ -1918,9 +1927,13 @@ int ingame_menu_resize(void *data, uint64_t input)
return 1;
}
int ingame_menu_screenshot(void *data, uint64_t input)
int ingame_menu_screenshot(void *data, void *state)
{
menu *current_menu = (menu*)data;
rmenu_state_t *rstate = (rmenu_state_t*)state;
uint64_t input = rstate->input;
DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data;
filebrowser_t *filebrowser = NULL;
@ -1947,12 +1960,15 @@ int ingame_menu_screenshot(void *data, uint64_t input)
#define MENU_ITEM_SELECTED(index) (menuitem_colors[index])
int ingame_menu(void *data, uint64_t input)
int ingame_menu(void *data, void *state)
{
//if(!g_extern.console.rmenu.state.ingame_menu.enable)
//return false;
menu *current_menu = (menu*)data;
menu *current_menu = (menu*)data;
rmenu_state_t *rstate = (rmenu_state_t*)state;
uint64_t input = rstate->input;
DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data;
char strw_buffer[256];
unsigned menuitem_colors[MENU_ITEM_LAST];
@ -2175,19 +2191,124 @@ int ingame_menu(void *data, uint64_t input)
return 1;
}
static void rmenu_filebrowser_init(void)
/*============================================================
INPUT POLL CALLBACK
============================================================ */
void rmenu_input_poll(void *data, void *state)
{
menu *current_menu = (menu*)data;
rmenu_state_t *rstate = (rmenu_state_t*)state;
//first button input frame
uint64_t input_state_first_frame = 0;
uint64_t input_state = 0;
static bool first_held = false;
input_ptr.poll(NULL);
for (unsigned i = 0; i < RMENU_DEVICE_NAV_LAST; i++)
input_state |= input_ptr.input_state(NULL, rmenu_nav_binds, 0,
RETRO_DEVICE_JOYPAD, 0, i) ? (1ULL << i) : 0;
//set first button input frame as trigger
rstate->input = input_state & ~(rstate->old_state);
//hold onto first button input frame
input_state_first_frame = input_state;
//second button input frame
input_state = 0;
input_ptr.poll(NULL);
for (unsigned i = 0; i < RMENU_DEVICE_NAV_LAST; i++)
{
input_state |= input_ptr.input_state(NULL, rmenu_nav_binds, 0,
RETRO_DEVICE_JOYPAD, 0, i) ? (1ULL << i) : 0;
}
bool analog_sticks_pressed = (input_state & (1ULL << RMENU_DEVICE_NAV_LEFT_ANALOG_L)) || (input_state & (1ULL << RMENU_DEVICE_NAV_RIGHT_ANALOG_L)) || (input_state & (1ULL << RMENU_DEVICE_NAV_UP_ANALOG_L)) || (input_state & (1ULL << RMENU_DEVICE_NAV_DOWN_ANALOG_L)) || (input_state & (1ULL << RMENU_DEVICE_NAV_LEFT_ANALOG_R)) || (input_state & (1ULL << RMENU_DEVICE_NAV_RIGHT_ANALOG_R)) || (input_state & (1ULL << RMENU_DEVICE_NAV_UP_ANALOG_R)) || (input_state & (1ULL << RMENU_DEVICE_NAV_DOWN_ANALOG_R));
bool shoulder_buttons_pressed = ((input_state & (1ULL << RMENU_DEVICE_NAV_L2)) || (input_state & (1ULL << RMENU_DEVICE_NAV_R2))) && current_menu->category_id != CATEGORY_SETTINGS;
bool do_held = analog_sticks_pressed || shoulder_buttons_pressed;
if(do_held)
{
if(!first_held)
{
first_held = true;
SET_TIMER_EXPIRATION(1, 7);
}
if(IS_TIMER_EXPIRED(1))
{
first_held = false;
rstate->input = input_state; //second input frame set as current frame
}
}
rstate->old_state = input_state_first_frame;
}
/*============================================================
INPUT PROCESS CALLBACK
============================================================ */
void rmenu_input_process(void *data, void *state)
{
(void)data;
rmenu_state_t *rstate = (rmenu_state_t*)state;
if(IS_TIMER_EXPIRED(0))
{
// if we want to force goto the emulation loop, skip this
if(g_extern.console.rmenu.mode != MODE_EMULATION)
{
if(g_extern.console.rmenu.mode == MODE_EXIT)
{
}
// for ingame menu, we need a different precondition because menu_enable
// can be set to false when going back from ingame menu to menu
else if(g_extern.console.rmenu.state.ingame_menu.enable == true)
{
//we want to force exit when g_extern.console.mode is set to MODE_EXIT
if(g_extern.console.rmenu.mode != MODE_EXIT)
g_extern.console.rmenu.mode = (((rstate->old_state & (1ULL << RMENU_DEVICE_NAV_L3)) && (rstate->old_state & (1ULL << RMENU_DEVICE_NAV_R3)) && g_extern.console.emulator_initialized)) ? MODE_EMULATION : MODE_MENU;
}
else
{
bool rmenu_enable = !(((rstate->old_state & (1ULL << RMENU_DEVICE_NAV_L3)) && (rstate->old_state & (1ULL << RMENU_DEVICE_NAV_R3)) && g_extern.console.emulator_initialized));
g_extern.console.rmenu.mode = rmenu_enable ? MODE_MENU : MODE_EMULATION;
}
}
}
}
/*============================================================
RESOURCE CALLBACKS
============================================================ */
void init_filebrowser(void *data)
{
(void)data;
menu_stack_push(FILE_BROWSER_MENU);
filebrowser_set_root_and_ext(&browser, rarch_console_get_rom_ext(), default_paths.filebrowser_startup_dir);
filebrowser_set_root(&tmpBrowser, default_paths.filesystem_root_dir);
}
static void rmenu_filebrowser_free(void)
void free_filebrowser(void *data)
{
(void)data;
filebrowser_free(&browser);
filebrowser_free(&tmpBrowser);
}
/*============================================================
RMENU API
============================================================ */
rmenu_state_t rmenu_state;
void menu_init(void)
{
DEVICE_CAST device_ptr = (DEVICE_CAST)driver.video_data;
@ -2198,14 +2319,21 @@ void menu_init(void)
const char *id = info.library_name ? info.library_name : "Unknown";
snprintf(m_title, sizeof(m_title), "%s %s", id, info.library_version);
rmenu_filebrowser_init();
rmenu_state.init_resources = init_filebrowser;
rmenu_state.free_resources = free_filebrowser;
rmenu_state.input = 0;
rmenu_state.old_state = 0;
if(rmenu_state.init_resources)
rmenu_state.init_resources(&rmenu_state);
device_ptr->ctx_driver->rmenu_init();
}
void menu_free(void)
{
rmenu_filebrowser_free();
if(rmenu_state.free_resources)
rmenu_state.free_resources(&rmenu_state);
}
bool rmenu_iterate(void)
@ -2233,54 +2361,11 @@ bool rmenu_iterate(void)
g_extern.frame_count++;
//first button input frame
uint64_t input_state_first_frame = 0;
uint64_t input_state = 0;
static bool first_held = false;
rmenu_default_positions_t default_pos;
menu_stack_get_current_ptr(&current_menu);
rmenu_default_positions_t default_pos;
device_ptr->ctx_driver->rmenu_set_default_pos(&default_pos);
input_ptr.poll(NULL);
for (unsigned i = 0; i < RMENU_DEVICE_NAV_LAST; i++)
input_state |= input_ptr.input_state(NULL, rmenu_nav_binds, 0,
RETRO_DEVICE_JOYPAD, 0, i) ? (1ULL << i) : 0;
uint64_t trig_state = input_state & ~old_state; //set first button input frame as trigger
input_state_first_frame = input_state; //hold onto first button input frame
//second button input frame
input_state = 0;
input_ptr.poll(NULL);
for (unsigned i = 0; i < RMENU_DEVICE_NAV_LAST; i++)
{
input_state |= input_ptr.input_state(NULL, rmenu_nav_binds, 0,
RETRO_DEVICE_JOYPAD, 0, i) ? (1ULL << i) : 0;
}
bool analog_sticks_pressed = (input_state & (1ULL << RMENU_DEVICE_NAV_LEFT_ANALOG_L)) || (input_state & (1ULL << RMENU_DEVICE_NAV_RIGHT_ANALOG_L)) || (input_state & (1ULL << RMENU_DEVICE_NAV_UP_ANALOG_L)) || (input_state & (1ULL << RMENU_DEVICE_NAV_DOWN_ANALOG_L)) || (input_state & (1ULL << RMENU_DEVICE_NAV_LEFT_ANALOG_R)) || (input_state & (1ULL << RMENU_DEVICE_NAV_RIGHT_ANALOG_R)) || (input_state & (1ULL << RMENU_DEVICE_NAV_UP_ANALOG_R)) || (input_state & (1ULL << RMENU_DEVICE_NAV_DOWN_ANALOG_R));
bool shoulder_buttons_pressed = ((input_state & (1ULL << RMENU_DEVICE_NAV_L2)) || (input_state & (1ULL << RMENU_DEVICE_NAV_R2))) && current_menu.category_id != CATEGORY_SETTINGS;
bool do_held = analog_sticks_pressed || shoulder_buttons_pressed;
if(do_held)
{
if(!first_held)
{
first_held = true;
SET_TIMER_EXPIRATION(1, 7);
}
if(IS_TIMER_EXPIRED(1))
{
first_held = false;
trig_state = input_state; //second input frame set as current frame
}
}
device_ptr->ctx_driver->clear();
if (g_extern.draw_menu)
@ -2288,36 +2373,16 @@ bool rmenu_iterate(void)
rarch_render_cached_frame();
if(current_menu.input_poll)
current_menu.input_poll(&current_menu, &rmenu_state);
int repeat = true;
if(current_menu.iterate)
repeat = current_menu.iterate(&current_menu, trig_state);
if(current_menu.entry)
repeat = current_menu.entry(&current_menu, &rmenu_state);
old_state = input_state_first_frame;
if(IS_TIMER_EXPIRED(0))
{
// if we want to force goto the emulation loop, skip this
if(g_extern.console.rmenu.mode != MODE_EMULATION)
{
if(g_extern.console.rmenu.mode == MODE_EXIT)
{
}
// for ingame menu, we need a different precondition because menu_enable
// can be set to false when going back from ingame menu to menu
else if(g_extern.console.rmenu.state.ingame_menu.enable == true)
{
//we want to force exit when g_extern.console.mode is set to MODE_EXIT
if(g_extern.console.rmenu.mode != MODE_EXIT)
g_extern.console.rmenu.mode = (((old_state & (1ULL << RMENU_DEVICE_NAV_L3)) && (old_state & (1ULL << RMENU_DEVICE_NAV_R3)) && g_extern.console.emulator_initialized)) ? MODE_EMULATION : MODE_MENU;
}
else
{
bool rmenu_enable = !(((old_state & (1ULL << RMENU_DEVICE_NAV_L3)) && (old_state & (1ULL << RMENU_DEVICE_NAV_R3)) && g_extern.console.emulator_initialized));
g_extern.console.rmenu.mode = rmenu_enable ? MODE_MENU : MODE_EMULATION;
}
}
}
if(current_menu.input_process)
current_menu.input_process(&current_menu, &rmenu_state);
if(g_extern.console.rmenu.mode == MODE_EMULATION || g_extern.console.rmenu.mode == MODE_EXIT || repeat == 0)
goto deinit;
@ -2335,7 +2400,10 @@ bool rmenu_iterate(void)
frame_count = 0;
device_ptr->ctx_driver->check_window(&quit, &resize, &width, &height, frame_count);
if(g_extern.draw_menu)
if (quit)
g_extern.console.rmenu.mode = MODE_EXIT;
if (g_extern.draw_menu)
device_ptr->ctx_driver->set_blend(false);
return true;

View File

@ -49,7 +49,9 @@ static void menu_stack_get_current_ptr(menu *current_menu)
unsigned menu_id = menu_stack_enum_array[stack_idx];
current_menu->browser_draw = NULL;
current_menu->input_iterate = NULL;
current_menu->input_process = NULL;
current_menu->input_poll = rmenu_input_poll;
current_menu->input_process = rmenu_input_process;
switch(menu_id)
{
@ -59,7 +61,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->selected = 0;
current_menu->page = 0;
current_menu->category_id = CATEGORY_INGAME_MENU;
current_menu->iterate = ingame_menu;
current_menu->entry = ingame_menu;
break;
case INGAME_MENU_RESIZE:
strlcpy(current_menu->title, "Resize Menu", sizeof(current_menu->title));
@ -67,7 +69,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->selected = 0;
current_menu->page = 0;
current_menu->category_id = CATEGORY_INGAME_MENU;
current_menu->iterate = ingame_menu_resize;
current_menu->entry = ingame_menu_resize;
break;
case INGAME_MENU_SCREENSHOT:
strlcpy(current_menu->title, "Ingame Menu", sizeof(current_menu->title));
@ -75,7 +77,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->selected = 0;
current_menu->page = 0;
current_menu->category_id = CATEGORY_INGAME_MENU;
current_menu->iterate = ingame_menu_screenshot;
current_menu->entry = ingame_menu_screenshot;
break;
case FILE_BROWSER_MENU:
strlcpy(current_menu->title, "Filebrowser", sizeof(current_menu->title));
@ -83,8 +85,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->selected = 0;
current_menu->page = 0;
current_menu->category_id = CATEGORY_FILEBROWSER;
current_menu->iterate = select_rom;
current_menu->input_iterate = select_rom_input_iterate;
current_menu->entry = select_rom;
break;
case LIBRETRO_CHOICE:
strlcpy(current_menu->title, "Libretro", sizeof(current_menu->title));
@ -92,7 +93,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->selected = 0;
current_menu->page = 0;
current_menu->category_id = CATEGORY_FILEBROWSER;
current_menu->iterate = select_file;
current_menu->entry = select_file;
break;
case PRESET_CHOICE:
strlcpy(current_menu->title, "Shader", sizeof(current_menu->title));
@ -100,7 +101,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->selected = 0;
current_menu->page = 0;
current_menu->category_id = CATEGORY_FILEBROWSER;
current_menu->iterate = select_file;
current_menu->entry = select_file;
break;
case INPUT_PRESET_CHOICE:
strlcpy(current_menu->title, "Input", sizeof(current_menu->title));
@ -108,7 +109,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->selected = 0;
current_menu->page = 0;
current_menu->category_id = CATEGORY_FILEBROWSER;
current_menu->iterate = select_file;
current_menu->entry = select_file;
break;
case SHADER_CHOICE:
strlcpy(current_menu->title, "Shaders", sizeof(current_menu->title));
@ -116,7 +117,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->selected = 0;
current_menu->page = 0;
current_menu->category_id = CATEGORY_FILEBROWSER;
current_menu->iterate = select_file;
current_menu->entry = select_file;
break;
case BORDER_CHOICE:
strlcpy(current_menu->title, "Borders", sizeof(current_menu->title));
@ -124,7 +125,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->selected = 0;
current_menu->page = 0;
current_menu->category_id = CATEGORY_FILEBROWSER;
current_menu->iterate = select_file;
current_menu->entry = select_file;
break;
case PATH_DEFAULT_ROM_DIR_CHOICE:
case PATH_SAVESTATES_DIR_CHOICE:
@ -138,7 +139,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->selected = 0;
current_menu->page = 0;
current_menu->category_id = CATEGORY_FILEBROWSER;
current_menu->iterate = select_directory;
current_menu->entry = select_directory;
break;
case GENERAL_VIDEO_MENU:
strlcpy(current_menu->title, "Video", sizeof(current_menu->title));
@ -148,7 +149,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->first_setting = FIRST_VIDEO_SETTING;
current_menu->max_settings = MAX_NO_OF_VIDEO_SETTINGS;
current_menu->category_id = CATEGORY_SETTINGS;
current_menu->iterate = select_setting;
current_menu->entry = select_setting;
break;
case GENERAL_AUDIO_MENU:
strlcpy(current_menu->title, "Audio", sizeof(current_menu->title));
@ -158,7 +159,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->first_setting = FIRST_AUDIO_SETTING;
current_menu->max_settings = MAX_NO_OF_AUDIO_SETTINGS;
current_menu->category_id = CATEGORY_SETTINGS;
current_menu->iterate = select_setting;
current_menu->entry = select_setting;
break;
case EMU_GENERAL_MENU:
strlcpy(current_menu->title, "Retro", sizeof(current_menu->title));
@ -168,7 +169,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->first_setting = FIRST_EMU_SETTING;
current_menu->max_settings = MAX_NO_OF_EMU_SETTINGS;
current_menu->category_id = CATEGORY_SETTINGS;
current_menu->iterate = select_setting;
current_menu->entry = select_setting;
break;
case EMU_VIDEO_MENU:
strlcpy(current_menu->title, "Retro Video", sizeof(current_menu->title));
@ -178,7 +179,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->first_setting = FIRST_EMU_VIDEO_SETTING;
current_menu->max_settings = MAX_NO_OF_EMU_VIDEO_SETTINGS;
current_menu->category_id = CATEGORY_SETTINGS;
current_menu->iterate = select_setting;
current_menu->entry = select_setting;
break;
case EMU_AUDIO_MENU:
strlcpy(current_menu->title, "Retro Audio", sizeof(current_menu->title));
@ -188,7 +189,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->first_setting = FIRST_EMU_AUDIO_SETTING;
current_menu->max_settings = MAX_NO_OF_EMU_AUDIO_SETTINGS;
current_menu->category_id = CATEGORY_SETTINGS;
current_menu->iterate = select_setting;
current_menu->entry = select_setting;
break;
case PATH_MENU:
strlcpy(current_menu->title, "Path", sizeof(current_menu->title));
@ -198,7 +199,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->first_setting = FIRST_PATH_SETTING;
current_menu->max_settings = MAX_NO_OF_PATH_SETTINGS;
current_menu->category_id = CATEGORY_SETTINGS;
current_menu->iterate = select_setting;
current_menu->entry = select_setting;
break;
case CONTROLS_MENU:
strlcpy(current_menu->title, "Controls", sizeof(current_menu->title));
@ -208,7 +209,7 @@ static void menu_stack_get_current_ptr(menu *current_menu)
current_menu->first_setting = FIRST_CONTROLS_SETTING_PAGE_1;
current_menu->max_settings = MAX_NO_OF_CONTROLS_SETTINGS;
current_menu->category_id = CATEGORY_SETTINGS;
current_menu->iterate = select_setting;
current_menu->entry = select_setting;
break;
default:
break;

View File

@ -26,24 +26,42 @@ typedef struct
unsigned char first_setting;
unsigned char max_settings;
unsigned char category_id;
int (*iterate)(void *data, uint64_t input);
int (*input_iterate)(void *data, uint64_t input);
int (*entry)(void *data, void *state);
void (*input_process)(void *data, void *state);
void (*input_poll)(void *data, void *state);
void (*browser_draw)(void *data);
} menu;
// iterate forward declarations
int select_file(void *data, uint64_t input);
int select_directory(void *data, uint64_t input);
int select_setting(void *data, uint64_t input);
int select_rom(void *data, uint64_t input);
int ingame_menu_resize(void *data, uint64_t input);
int ingame_menu_screenshot(void *data, uint64_t input);
int ingame_menu(void *data, uint64_t input);
typedef struct
{
uint64_t input;
uint64_t old_state;
void (*init_resources)(void *data);
void (*free_resources)(void *data);
} rmenu_state_t;
// input iterate forward declarations
int select_rom_input_iterate(void *data, uint64_t input);
// iterate forward declarations
int select_file(void *data, void *state);
int select_directory(void *data, void *state);
int select_setting(void *data, void *state);
int select_rom(void *data, void *state);
int ingame_menu_resize(void *data, void *state);
int ingame_menu_screenshot(void *data, void *state);
int ingame_menu(void *data, void *state);
// input poll forward declarations
void rmenu_input_poll(void *data, void *state);
// input process forward declarations
void rmenu_input_process(void *data, void *state);
// browser_draw forward declarations
void browser_render(void *data);
// init resources forward declarations
void init_filebrowser(void *data);
// free resources forward declarations
void free_filebrowser(void *data);
#endif