release 1.85
[picodrive.git] / platform / common / menu_pico.c
index 3ed768d..0a5e85a 100644 (file)
@@ -7,6 +7,7 @@
  */
 #include <stdio.h>
 #include <string.h>
+#include <time.h>
 
 #include "emu.h"
 #include "menu_pico.h"
@@ -27,7 +28,7 @@
 
 static const char *rom_exts[] = {
        "zip",
-       "bin", "smd", "gen",
+       "bin", "smd", "gen", "md",
        "iso", "cso", "cue",
        "32x",
        "sms",
@@ -37,11 +38,16 @@ static const char *rom_exts[] = {
 // rrrr rggg gggb bbbb
 static unsigned short fname2color(const char *fname)
 {
-       const char *ext = fname + strlen(fname) - 3;
        static const char *other_exts[] = { "gmv", "pat" };
+       const char *ext;
        int i;
 
-       if (ext < fname) ext = fname;
+       ext = strrchr(fname, '.');
+       if (ext++ == NULL) {
+               ext = fname + strlen(fname) - 3;
+               if (ext < fname) ext = fname;
+       }
+
        for (i = 0; rom_exts[i] != NULL; i++)
                if (strcasecmp(ext, rom_exts[i]) == 0) return 0xbdff; // FIXME: mk defines
        for (i = 0; i < array_size(other_exts); i++)
@@ -61,7 +67,6 @@ static const char *men_dummy[] = { NULL };
 #else
 #define MENU_OPTIONS_GFX
 #define MENU_OPTIONS_ADV
-#define menu_main_plat_draw NULL
 #endif
 
 static void make_bg(int no_scale)
@@ -71,6 +76,11 @@ static void make_bg(int no_scale)
        short *dst;
        int x, y;
 
+       if (src == NULL) {
+               memset(g_menubg_ptr, 0, g_menuscreen_w * g_menuscreen_h * 2);
+               return;
+       }
+
        if (!no_scale && g_menuscreen_w / w >= 2 && g_menuscreen_h / h >= 2)
        {
                unsigned int t, *d = g_menubg_ptr;
@@ -125,7 +135,7 @@ static void draw_savestate_bg(int slot)
        const char *fname;
        void *tmp_state;
 
-       fname = emu_get_save_fname(1, 0, slot);
+       fname = emu_get_save_fname(1, 0, slot, NULL);
        if (!fname)
                return;
 
@@ -345,12 +355,15 @@ static const char *mgn_dev_name(int id, int *offs)
 static int mh_saveloadcfg(int id, int keys);
 static const char *mgn_saveloadcfg(int id, int *offs);
 
+const char *indev_names[] = { "none", "3 button pad", "6 button pad", NULL };
+
 static menu_entry e_menu_keyconfig[] =
 {
        mee_handler_id("Player 1",          MA_CTRL_PLAYER1,    key_config_loop_wrap),
        mee_handler_id("Player 2",          MA_CTRL_PLAYER2,    key_config_loop_wrap),
        mee_handler_id("Emulator controls", MA_CTRL_EMU,        key_config_loop_wrap),
-       mee_onoff     ("6 button pad",      MA_OPT_6BUTTON_PAD, PicoOpt, POPT_6BTN_PAD),
+       mee_enum      ("Input device 1",    MA_OPT_INPUT_DEV0,  currentConfig.input_dev0, indev_names),
+       mee_enum      ("Input device 2",    MA_OPT_INPUT_DEV1,  currentConfig.input_dev1, indev_names),
        mee_range     ("Turbo rate",        MA_CTRL_TURBO_RATE, currentConfig.turbo_rate, 1, 30),
        mee_range     ("Analog deadzone",   MA_CTRL_DEADZONE,   currentConfig.analog_deadzone, 1, 99),
        mee_cust_nosave("Save global config",       MA_OPT_SAVECFG, mh_saveloadcfg, mgn_saveloadcfg),
@@ -373,6 +386,10 @@ static int menu_loop_keyconfig(int id, int keys)
 
        me_enable(e_menu_keyconfig, MA_OPT_SAVECFG_GAME, PicoGameLoaded);
        me_loop(e_menu_keyconfig, &sel);
+
+       PicoSetInputDevice(0, currentConfig.input_dev0);
+       PicoSetInputDevice(1, currentConfig.input_dev1);
+
        return 0;
 }
 
@@ -421,7 +438,6 @@ static menu_entry e_menu_cd_options[] =
        mee_cust   ("ReadAhead buffer",     MA_CDOPT_READAHEAD,     mh_cdopt_ra, mgn_cdopt_ra),
        mee_onoff_h("SaveRAM cart",         MA_CDOPT_SAVERAM,       PicoOpt, POPT_EN_MCD_RAMCART, h_srcart),
        mee_onoff_h("Scale/Rot. fx (slow)", MA_CDOPT_SCALEROT_CHIP, PicoOpt, POPT_EN_MCD_GFX, h_scfx),
-       mee_onoff_h("Better sync (slow)",   MA_CDOPT_BETTER_SYNC,   PicoOpt, POPT_EN_MCD_PSYNC, h_bsync),
        mee_end,
 };
 
@@ -439,26 +455,28 @@ static int menu_loop_cd_options(int id, int keys)
 // convert from multiplier of VClk
 static int mh_opt_sh2cycles(int id, int keys)
 {
-       int *mul = (id == MA_32XOPT_MSH2_CYCLES) ? &p32x_msh2_multiplier : &p32x_ssh2_multiplier;
+       int *khz = (id == MA_32XOPT_MSH2_CYCLES) ?
+               &currentConfig.msh2_khz : &currentConfig.ssh2_khz;
 
        if (keys & (PBTN_LEFT|PBTN_RIGHT))
-               *mul += (keys & PBTN_LEFT) ? -10 : 10;
+               *khz += (keys & PBTN_LEFT) ? -50 : 50;
        if (keys & (PBTN_L|PBTN_R))
-               *mul += (keys & PBTN_L) ? -100 : 100;
+               *khz += (keys & PBTN_L) ? -500 : 500;
 
-       if (*mul < 1)
-               *mul = 1;
-       else if (*mul > (10 << SH2_MULTI_SHIFT))
-               *mul = 10 << SH2_MULTI_SHIFT;
+       if (*khz < 1)
+               *khz = 1;
+       else if (*khz > 0x7fffffff / 1000)
+               *khz = 0x7fffffff / 1000;
 
        return 0;
 }
 
 static const char *mgn_opt_sh2cycles(int id, int *offs)
 {
-       int mul = (id == MA_32XOPT_MSH2_CYCLES) ? p32x_msh2_multiplier : p32x_ssh2_multiplier;
-       
-       sprintf(static_buff, "%d", 7670 * mul >> SH2_MULTI_SHIFT);
+       int khz = (id == MA_32XOPT_MSH2_CYCLES) ?
+               currentConfig.msh2_khz : currentConfig.ssh2_khz;
+
+       sprintf(static_buff, "%d", khz);
        return static_buff;
 }
 
@@ -485,6 +503,8 @@ static int menu_loop_32x_options(int id, int keys)
        me_enable(e_menu_32x_options, MA_32XOPT_RENDERER, renderer_names32x[0] != NULL);
        me_loop(e_menu_32x_options, &sel);
 
+       Pico32xSetClocks(currentConfig.msh2_khz * 1000, currentConfig.msh2_khz * 1000);
+
        return 0;
 }
 
@@ -503,6 +523,8 @@ static menu_entry e_menu_adv_options[] =
        mee_onoff     ("Don't save last used ROM", MA_OPT2_NO_LAST_ROM,   currentConfig.EmuOpt, EOPT_NO_AUTOSVCFG),
        mee_onoff     ("Disable idle loop patching",MA_OPT2_NO_IDLE_LOOPS,PicoOpt, POPT_DIS_IDLE_DET),
        mee_onoff     ("Disable frame limiter",    MA_OPT2_NO_FRAME_LIMIT,currentConfig.EmuOpt, EOPT_NO_FRMLIMIT),
+       mee_onoff     ("Enable dynarecs",          MA_OPT2_DYNARECS,      PicoOpt, POPT_EN_DRC),
+       mee_onoff     ("Status line in main menu", MA_OPT2_STATUS_LINE,   currentConfig.EmuOpt, EOPT_SHOW_RTC),
        MENU_OPTIONS_ADV
        mee_end,
 };
@@ -516,14 +538,20 @@ static int menu_loop_adv_options(int id, int keys)
 
 // ------------ gfx options menu ------------
 
-static const char h_gamma[] = "Gamma/brightness adjustment (default 100)";
+static const char h_gamma[] = "Gamma/brightness adjustment (default 1.00)";
+
+static const char *mgn_aopt_gamma(int id, int *offs)
+{
+       sprintf(static_buff, "%i.%02i", currentConfig.gamma / 100, currentConfig.gamma % 100);
+       return static_buff;
+}
 
 static menu_entry e_menu_gfx_options[] =
 {
        mee_enum   ("Video output mode", MA_OPT_VOUT_MODE, plat_target.vout_method, men_dummy),
        mee_enum   ("Renderer",          MA_OPT_RENDERER, currentConfig.renderer, renderer_names),
        mee_enum   ("Filter",            MA_OPT3_FILTERING, currentConfig.filter, men_dummy),
-       mee_range_h("Gamma adjustment",  MA_OPT3_GAMMA, currentConfig.gamma, 1, 200, h_gamma),
+       mee_range_cust_h("Gamma correction", MA_OPT2_GAMMA, currentConfig.gamma, 1, 300, mgn_aopt_gamma, h_gamma),
        MENU_OPTIONS_GFX
        mee_end,
 };
@@ -715,7 +743,7 @@ static menu_entry e_menu_options[] =
        mee_onoff     ("Enable sound",             MA_OPT_ENABLE_SOUND,  currentConfig.EmuOpt, EOPT_EN_SOUND),
        mee_cust      ("Sound Quality",            MA_OPT_SOUND_QUALITY, mh_opt_misc, mgn_opt_sound),
        mee_enum_h    ("Confirm savestate",        MA_OPT_CONFIRM_STATES,currentConfig.confirm_save, men_confirm_save, h_confirm_save),
-       mee_range     ("",                         MA_OPT_CPU_CLOCKS,    currentConfig.CPUclock, 20, 1200),
+       mee_range     ("",                         MA_OPT_CPU_CLOCKS,    currentConfig.CPUclock, 20, 3200),
        mee_handler   ("[Display options]",        menu_loop_gfx_options),
        mee_handler   ("[Sega/Mega CD options]",   menu_loop_cd_options),
 #ifndef NO_32X
@@ -732,10 +760,7 @@ static menu_entry e_menu_options[] =
 static int menu_loop_options(int id, int keys)
 {
        static int sel = 0;
-       int i;
 
-       i = me_id2offset(e_menu_options, MA_OPT_CPU_CLOCKS);
-       e_menu_options[i].enabled = e_menu_options[i].name[0] ? 1 : 0;
        me_enable(e_menu_options, MA_OPT_SAVECFG_GAME, PicoGameLoaded);
        me_enable(e_menu_options, MA_OPT_LOADCFG, config_slot != config_slot_current);
 
@@ -901,7 +926,7 @@ static void debug_menu_loop(void)
 // ------------ main menu ------------
 
 static const char credits[] =
-       "PicoDrive v" VERSION " (c) notaz, 2006-2011\n\n\n"
+       "PicoDrive v" VERSION " (c) notaz, 2006-2013\n\n\n"
        "Credits:\n"
        "fDave: Cyclone 68000 core,\n"
        "      base code of PicoDrive\n"
@@ -909,7 +934,6 @@ static const char credits[] =
        "MAME devs: YM2612 and SN76496 cores\n"
        "Inder, ketchupgun: graphics\n"
 #ifdef __GP2X__
-       "rlyeh and others: minimal SDK\n"
        "Squidge: mmuhack\n"
        "Dzz: ARM940 sample\n"
 #endif
@@ -918,7 +942,57 @@ static const char credits[] =
        " Charles MacDonald, Haze,\n"
        " Stephane Dallongeville,\n"
        " Lordus, Exophase, Rokas,\n"
-       " Nemesis, Tasco Deluxe";
+       " Eke, Nemesis, Tasco Deluxe";
+
+static void menu_main_draw_status(void)
+{
+       static time_t last_bat_read = 0;
+       static int last_bat_val = -1;
+       unsigned short *bp = g_screen_ptr;
+       int bat_h = me_mfont_h * 2 / 3;
+       int i, u, w, wfill, batt_val;
+       struct tm *tmp;
+       time_t ltime;
+       char time_s[16];
+
+       if (!(currentConfig.EmuOpt & EOPT_SHOW_RTC))
+               return;
+
+       ltime = time(NULL);
+       tmp = gmtime(&ltime);
+       strftime(time_s, sizeof(time_s), "%H:%M", tmp);
+
+       text_out16(g_screen_width - me_mfont_w * 6, me_mfont_h + 2, time_s);
+
+       if (ltime - last_bat_read > 10) {
+               last_bat_read = ltime;
+               last_bat_val = batt_val = plat_target_bat_capacity_get();
+       }
+       else
+               batt_val = last_bat_val;
+
+       if (batt_val < 0 || batt_val > 100)
+               return;
+
+       /* battery info */
+       bp += (me_mfont_h * 2 + 2) * g_screen_width + g_screen_width - me_mfont_w * 3 - 3;
+       for (i = 0; i < me_mfont_w * 2; i++)
+               bp[i] = menu_text_color;
+       for (i = 0; i < me_mfont_w * 2; i++)
+               bp[i + g_screen_width * bat_h] = menu_text_color;
+       for (i = 0; i <= bat_h; i++)
+               bp[i * g_screen_width] =
+               bp[i * g_screen_width + me_mfont_w * 2] = menu_text_color;
+       for (i = 2; i < bat_h - 1; i++)
+               bp[i * g_screen_width - 1] =
+               bp[i * g_screen_width - 2] = menu_text_color;
+
+       w = me_mfont_w * 2 - 1;
+       wfill = batt_val * w / 100;
+       for (u = 1; u < bat_h; u++)
+               for (i = 0; i < wfill; i++)
+                       bp[(w - i) + g_screen_width * u] = menu_text_color;
+}
 
 static int main_menu_handler(int id, int keys)
 {
@@ -1008,7 +1082,7 @@ void menu_loop(void)
 
        menu_enter(PicoGameLoaded);
        in_set_config_int(0, IN_CFG_BLOCKING, 1);
-       me_loop_d(e_menu_main, &sel, NULL, menu_main_plat_draw);
+       me_loop_d(e_menu_main, &sel, NULL, menu_main_draw_status);
 
        if (PicoGameLoaded) {
                if (engineState == PGS_Menu)
@@ -1068,7 +1142,8 @@ int menu_loop_tray(void)
                ret = 0; /* no CD inserted */
        }
 
-       while (in_menu_wait_any(NULL, 50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK));
+       while (in_menu_wait_any(NULL, 50) & (PBTN_MENU|PBTN_MOK|PBTN_MBACK))
+               ;
        in_set_config_int(0, IN_CFG_BLOCKING, 0);
        plat_video_menu_leave();
 
@@ -1090,6 +1165,7 @@ void menu_update_msg(const char *msg)
 static menu_entry e_menu_hidden[] =
 {
        mee_onoff("Accurate sprites", MA_OPT_ACC_SPRITES, PicoOpt, 0x080),
+       mee_onoff("autoload savestates", MA_OPT_AUTOLOAD_SAVE, g_autostateld_opt, 1),
        mee_end,
 };
 
@@ -1141,6 +1217,12 @@ void menu_init(void)
 
        menu_init_base();
 
+       i = 0;
+#if defined(_SVP_DRC) || defined(DRC_SH2)
+       i = 1;
+#endif
+       me_enable(e_menu_adv_options, MA_OPT2_DYNARECS, i);
+
        i = me_id2offset(e_menu_gfx_options, MA_OPT_VOUT_MODE);
        e_menu_gfx_options[i].data = plat_target.vout_methods;
        me_enable(e_menu_gfx_options, MA_OPT_VOUT_MODE,
@@ -1151,6 +1233,13 @@ void menu_init(void)
        me_enable(e_menu_gfx_options, MA_OPT3_FILTERING,
                plat_target.hwfilters != NULL);
 
-       me_enable(e_menu_gfx_options, MA_OPT3_GAMMA,
+       me_enable(e_menu_gfx_options, MA_OPT2_GAMMA,
                 plat_target.gamma_set != NULL);
+
+       i = me_id2offset(e_menu_options, MA_OPT_CPU_CLOCKS);
+       e_menu_options[i].enabled = 0;
+       if (plat_target.cpu_clock_set != NULL) {
+               e_menu_options[i].name = "CPU clock";
+               e_menu_options[i].enabled = 1;
+       }
 }