diff options
Diffstat (limited to 'frontend/menu.c')
-rw-r--r-- | frontend/menu.c | 335 |
1 files changed, 335 insertions, 0 deletions
diff --git a/frontend/menu.c b/frontend/menu.c new file mode 100644 index 0000000..44bcd07 --- /dev/null +++ b/frontend/menu.c @@ -0,0 +1,335 @@ +#include <sys/stat.h> +#include "common.h" + +#include "frontend/config.h" +#include "frontend/main.h" +#include "frontend/menu.h" +#include "frontend/scale.h" +#include "frontend/plat.h" + +#include "frontend/libpicofe/config_file.h" + +#define MENU_ALIGN_LEFT 0 +#define MENU_X2 0 + +typedef enum +{ + MA_NONE = 1, + MA_MAIN_RESUME_GAME, + MA_MAIN_SAVE_STATE, + MA_MAIN_LOAD_STATE, + MA_MAIN_RESET_GAME, + MA_MAIN_CREDITS, + MA_MAIN_EXIT, + MA_OPT_SAVECFG, + MA_OPT_SAVECFG_GAME, + MA_CTRL_PLAYER1, + MA_CTRL_EMU, +} menu_id; + +int menu_save_config(int is_game); +void menu_set_defaults(void); + +me_bind_action me_ctrl_actions[] = +{ + { "UP ", 1 << KBIT_UP}, + { "DOWN ", 1 << KBIT_DOWN }, + { "LEFT ", 1 << KBIT_LEFT }, + { "RIGHT ", 1 << KBIT_RIGHT }, + { "A BUTTON ", 1 << KBIT_A }, + { "B BUTTON ", 1 << KBIT_B }, + { "START ", 1 << KBIT_START }, + { "SELECT ", 1 << KBIT_SELECT }, + { "L BUTTON ", 1 << KBIT_L }, + { "R BUTTON ", 1 << KBIT_R }, + { NULL, 0 } +}; + +me_bind_action emuctrl_actions[] = +{ + { "Save State ", 1 << EACTION_SAVE_STATE }, + { "Load State ", 1 << EACTION_LOAD_STATE }, + { "Toggle Frameskip ", 1 << EACTION_TOGGLE_FSKIP }, + { "Show/Hide FPS ", 1 << EACTION_TOGGLE_FPS }, + { "Toggle FF ", 1 << EACTION_TOGGLE_FF }, + { "Enter Menu ", 1 << EACTION_MENU }, + { NULL, 0 } +}; + +int emu_check_save_file(int slot, int *time) +{ + char fname[MAXPATHLEN]; + struct stat status; + int ret; + + state_file_name(fname, sizeof(fname), slot); + + ret = stat(fname, &status); + if (ret != 0) + return 0; + + return 1; +} + +int emu_save_load_game(int load, int unused) +{ + int ret; + + if (load) + ret = load_state_file(state_slot); + else + ret = save_state_file(state_slot); + + return ret; +} + +#include "frontend/libpicofe/menu.c" + +static const char *mgn_saveloadcfg(int id, int *offs) +{ + return ""; +} + +static int mh_restore_defaults(int id, int keys) +{ + menu_set_defaults(); + menu_update_msg("defaults restored"); + return 1; +} + +static int mh_savecfg(int id, int keys) +{ + if (menu_save_config(id == MA_OPT_SAVECFG_GAME ? 1 : 0) == 0) + menu_update_msg("config saved"); + else + menu_update_msg("failed to write config"); + + return 1; +} + +static const char h_restore_def[] = "Switches back to default / recommended\n" + "configuration"; + +static const char h_color_correct[] = "Modifies colors to simulate original display"; +static const char h_lcd_blend[] = "Blends frames to simulate LCD lag"; +static const char h_show_fps[] = "Shows frames and vsyncs per second"; +static const char h_dynarec_enable[] = "Improves performance, but may reduce accuracy"; + + +static const char *men_frameskip[] = { "OFF", "Auto", "Manual", NULL }; + +static const char *men_scaling[] = { "Native", "3:2 Sharp", "3:2 Smooth", "4:3 Sharp", "4:3 Smooth", NULL}; + +static menu_entry e_menu_options[] = +{ + mee_enum ("Frameskip", 0, frameskip_style, men_frameskip), + mee_range ("Max Frameskip", 0, max_frameskip, 1, 5), + mee_enum ("Scaling", 0, scaling_mode, men_scaling), + mee_onoff_h ("Color Correction", 0, color_correct, 1, h_color_correct), + mee_onoff_h ("LCD Ghosting", 0, lcd_blend, 1, h_lcd_blend), + mee_onoff_h ("Dynamic Recompiler", 0, dynarec_enable, 1, h_dynarec_enable), + mee_onoff_h ("Show FPS", 0, show_fps, 1, h_show_fps), + mee_cust_nosave ("Save global config", MA_OPT_SAVECFG, mh_savecfg, mgn_saveloadcfg), + mee_cust_nosave ("Save game config", MA_OPT_SAVECFG_GAME, mh_savecfg, mgn_saveloadcfg), + mee_handler_h ("Restore defaults", mh_restore_defaults, h_restore_def), + mee_end, +}; + +static int menu_loop_options(int id, int keys) +{ + static int sel = 0; + int prev_dynarec_enable = dynarec_enable; + + me_loop(e_menu_options, &sel); + + if (prev_dynarec_enable != dynarec_enable) + init_caches(); + + return 0; +} + +static int key_config_loop_wrap(int id, int keys) +{ + switch (id) { + case MA_CTRL_PLAYER1: + key_config_loop(me_ctrl_actions, array_size(me_ctrl_actions) - 1, 0); + break; + case MA_CTRL_EMU: + key_config_loop(emuctrl_actions, array_size(emuctrl_actions) - 1, -1); + break; + default: + break; + } + return 0; +} + +static menu_entry e_menu_keyconfig[] = +{ + mee_handler_id ("Player controls", MA_CTRL_PLAYER1, key_config_loop_wrap), + mee_handler_id ("Emulator controls", MA_CTRL_EMU, key_config_loop_wrap), + mee_cust_nosave ("Save global config", MA_OPT_SAVECFG, mh_savecfg, mgn_saveloadcfg), + mee_cust_nosave ("Save game config", MA_OPT_SAVECFG_GAME, mh_savecfg, mgn_saveloadcfg), + mee_end, +}; + +static int menu_loop_keyconfig(int id, int keys) +{ + static int sel = 0; + me_loop(e_menu_keyconfig, &sel); + return 0; +} + + +static int main_menu_handler(int id, int keys) +{ + switch (id) + { + case MA_MAIN_RESUME_GAME: + return 1; + case MA_MAIN_SAVE_STATE: + return menu_loop_savestate(0); + case MA_MAIN_LOAD_STATE: + return menu_loop_savestate(1); + case MA_MAIN_RESET_GAME: + reset_gba(); + return 1; + case MA_MAIN_EXIT: + should_quit = 1; + return 1; + default: + lprintf("%s: something unknown selected\n", __FUNCTION__); + break; + } + + return 0; +} + +static menu_entry e_menu_main[] = +{ + mee_handler_id("Resume game", MA_MAIN_RESUME_GAME, main_menu_handler), + mee_handler_id("Save State", MA_MAIN_SAVE_STATE, main_menu_handler), + mee_handler_id("Load State", MA_MAIN_LOAD_STATE, main_menu_handler), + mee_handler_id("Reset game", MA_MAIN_RESET_GAME, main_menu_handler), + mee_handler ("Options", menu_loop_options), + mee_handler ("Controls", menu_loop_keyconfig), + /* mee_handler_id("Cheats", MA_MAIN_CHEATS, main_menu_handler), */ + mee_handler_id("Exit", MA_MAIN_EXIT, main_menu_handler), + mee_end, +}; + +void draw_savestate_bg(int slot) +{ +} + +void menu_set_defaults(void) +{ + dynarec_enable = 1; + frameskip_style = 1; + scaling_mode = 0; + max_frameskip = 3; + color_correct = 0; + lcd_blend = 0; + show_fps = 0; + limit_frames = 1; +} + +void menu_loop(void) +{ + static int sel = 0; + plat_video_menu_enter(1); + video_scale(g_menubg_ptr, g_menuscreen_h, g_menuscreen_pp); + menu_darken_bg(g_menubg_ptr, g_menubg_ptr, g_menuscreen_h * g_menuscreen_pp, 0); + me_loop_d(e_menu_main, &sel, NULL, NULL); + + /* wait until menu, ok, back is released */ + while (in_menu_wait_any(NULL, 50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK)) + ; + memset(g_menubg_ptr, 0, g_menuscreen_h * g_menuscreen_pp * sizeof(uint16_t)); + + plat_video_menu_leave(); +} + +int menu_save_config(int is_game) +{ + char config_filename[MAXPATHLEN]; + FILE *config_file; + + config_file_name(config_filename, MAXPATHLEN, is_game); + config_file = fopen(config_filename, "wb"); + if (!config_file) { + fprintf(stderr, "Could not write config to %s\n", config_filename); + return -1; + } + + config_write(config_file); + config_write_keys(config_file); + + fclose(config_file); + return 0; +} + + +void menu_load_config(void) +{ + char config_filename[MAXPATHLEN]; + FILE *config_file; + size_t length; + char *config; + + config_file_name(config_filename, MAXPATHLEN, 1); + config_file = fopen(config_filename, "rb"); + if (!config_file) { + config_file_name(config_filename, MAXPATHLEN, 0); + config_file = fopen(config_filename, "rb"); + } + + if (!config_file) + return; + + fseek(config_file, 0, SEEK_END); + length = ftell(config_file); + fseek(config_file, 0, SEEK_SET); + + config = calloc(1, length); + + if (fread(config, 1, length, config_file)) + fclose(config_file); + + config_read(config); + config_read_keys(config); + + if (config) + free(config); +} + +void menu_init(void) +{ + menu_init_base(); + + menu_set_defaults(); + menu_load_config(); + + g_menubg_src_ptr = calloc(g_menuscreen_w * g_menuscreen_h * 2, 1); + g_menubg_ptr = calloc(g_menuscreen_w * g_menuscreen_h * 2, 1); + if (g_menubg_src_ptr == NULL || g_menubg_ptr == NULL) { + fprintf(stderr, "OOM\n"); + exit(1); + } +} + +void menu_finish(void) +{ +} + +static void debug_menu_loop(void) +{ +} + +void menu_update_msg(const char *msg) +{ + strncpy(menu_error_msg, msg, sizeof(menu_error_msg)); + menu_error_msg[sizeof(menu_error_msg) - 1] = 0; + + menu_error_time = plat_get_ticks_ms(); + lprintf("msg: %s\n", menu_error_msg); +} |