drc: only override default cycle_multiplier
[pcsx_rearmed.git] / frontend / menu.c
index 1562735..f5d035a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * (C) Gražvydas "notaz" Ignotas, 2010-2013
+ * (C) Gražvydas "notaz" Ignotas, 2010-2015
  *
  * This work is licensed under the terms of any of these licenses
  * (at your option):
@@ -39,6 +39,7 @@
 #include "../plugins/dfinput/externals.h"
 #include "../plugins/dfsound/spu_config.h"
 #include "psemu_plugin_defs.h"
+#include "arm_features.h"
 #include "revision.h"
 
 #define REARMED_BIRTHDAY_TIME 1293306830       /* 25 Dec 2010 */
@@ -75,6 +76,7 @@ typedef enum
        MA_OPT_SAVECFG,
        MA_OPT_SAVECFG_GAME,
        MA_OPT_CPU_CLOCKS,
+       MA_OPT_SPU_THREAD,
        MA_OPT_DISP_OPTS,
        MA_OPT_VARSCALER,
        MA_OPT_VARSCALER_C,
@@ -83,6 +85,8 @@ typedef enum
        MA_OPT_SWFILTER,
        MA_OPT_GAMMA,
        MA_OPT_VOUT_MODE,
+       MA_OPT_SCANLINES,
+       MA_OPT_SCANLINE_LEVEL,
 } menu_id;
 
 static int last_vout_w, last_vout_h, last_vout_bpp;
@@ -90,13 +94,15 @@ static int cpu_clock, cpu_clock_st, volume_boost, frameskip;
 static char last_selected_fname[MAXPATHLEN];
 static int config_save_counter, region, in_type_sel1, in_type_sel2;
 static int psx_clock;
-static int memcard1_sel, memcard2_sel;
+static int memcard1_sel = -1, memcard2_sel = -1;
+extern int g_autostateld_opt;
 int g_opts, g_scaler, g_gamma = 100;
+int scanlines, scanline_level = 20;
 int soft_scaling, analog_deadzone; // for Caanoo
 int soft_filter;
 
-#ifdef __ARM_ARCH_7A__
-#define DEFAULT_PSX_CLOCK 57
+#ifndef HAVE_PRE_ARMV7
+#define DEFAULT_PSX_CLOCK (10000 / CYCLE_MULT_DEFAULT)
 #define DEFAULT_PSX_CLOCK_S "57"
 #else
 #define DEFAULT_PSX_CLOCK 50
@@ -209,6 +215,9 @@ static int optional_cdimg_filter(struct dirent **namelist, int count,
        struct stat64 statf;
        FILE *f;
 
+       if (count <= 1)
+               return count;
+
        for (i = 1; i < count; i++) {
                if (namelist[i] == NULL || namelist[i]->d_type == DT_DIR)
                        continue;
@@ -330,6 +339,8 @@ static void menu_set_defconfig(void)
        analog_deadzone = 50;
        soft_scaling = 1;
        soft_filter = 0;
+       scanlines = 0;
+       scanline_level = 20;
        plat_target.vout_fullscreen = 0;
        psx_clock = DEFAULT_PSX_CLOCK;
 
@@ -386,15 +397,19 @@ static const struct {
        CE_CONFIG_VAL(SpuIrq),
        CE_CONFIG_VAL(RCntFix),
        CE_CONFIG_VAL(VSyncWA),
+       CE_CONFIG_VAL(icache_emulation),
+       CE_CONFIG_VAL(DisableStalls),
        CE_CONFIG_VAL(Cpu),
        CE_INTVAL(region),
-       CE_INTVAL_V(g_scaler, 2),
+       CE_INTVAL_V(g_scaler, 3),
        CE_INTVAL(g_gamma),
        CE_INTVAL(g_layer_x),
        CE_INTVAL(g_layer_y),
        CE_INTVAL(g_layer_w),
        CE_INTVAL(g_layer_h),
        CE_INTVAL(soft_filter),
+       CE_INTVAL(scanlines),
+       CE_INTVAL(scanline_level),
        CE_INTVAL(plat_target.vout_method),
        CE_INTVAL(plat_target.hwfilter),
        CE_INTVAL(plat_target.vout_fullscreen),
@@ -404,6 +419,9 @@ static const struct {
        CE_INTVAL(in_type_sel1),
        CE_INTVAL(in_type_sel2),
        CE_INTVAL(analog_deadzone),
+       CE_INTVAL(memcard1_sel),
+       CE_INTVAL(memcard2_sel),
+       CE_INTVAL(g_autostateld_opt),
        CE_INTVAL_N("adev0_is_nublike", in_adev_is_nublike[0]),
        CE_INTVAL_N("adev1_is_nublike", in_adev_is_nublike[1]),
        CE_INTVAL_V(frameskip, 3),
@@ -413,6 +431,13 @@ static const struct {
        CE_INTVAL_P(gpu_unai.abe_hack),
        CE_INTVAL_P(gpu_unai.no_light),
        CE_INTVAL_P(gpu_unai.no_blend),
+       CE_INTVAL_P(gpu_senquack.ilace_force),
+       CE_INTVAL_P(gpu_senquack.pixel_skip),
+       CE_INTVAL_P(gpu_senquack.lighting),
+       CE_INTVAL_P(gpu_senquack.fast_lighting),
+       CE_INTVAL_P(gpu_senquack.blending),
+       CE_INTVAL_P(gpu_senquack.dithering),
+       CE_INTVAL_P(gpu_senquack.scale_hires),
        CE_INTVAL_P(gpu_neon.allow_interlace),
        CE_INTVAL_P(gpu_neon.enhancement_enable),
        CE_INTVAL_P(gpu_neon.enhancement_no_main),
@@ -430,6 +455,7 @@ static const struct {
        CE_INTVAL(spu_config.iXAPitch),
        CE_INTVAL(spu_config.iUseInterpolation),
        CE_INTVAL(spu_config.iTempo),
+       CE_INTVAL(spu_config.iUseThread),
        CE_INTVAL(config_save_counter),
        CE_INTVAL(in_evdev_allow_abs_only),
        CE_INTVAL(volume_boost),
@@ -661,11 +687,37 @@ fail:
                if (strcmp(Config.Spu, spu_plugins[i]) == 0)
                        { spu_plugsel = i; break; }
 
+       // memcard selections
+       char mcd1_old[sizeof(Config.Mcd1)];
+       char mcd2_old[sizeof(Config.Mcd2)];
+       strcpy(mcd1_old, Config.Mcd1);
+       strcpy(mcd2_old, Config.Mcd2);
+
+       if ((unsigned int)memcard1_sel < ARRAY_SIZE(memcards)) {
+               if (memcard1_sel == 0)
+                       strcpy(Config.Mcd1, "none");
+               else if (memcards[memcard1_sel] != NULL)
+                       snprintf(Config.Mcd1, sizeof(Config.Mcd1), ".%s%s",
+                               MEMCARD_DIR, memcards[memcard1_sel]);
+       }
+       if ((unsigned int)memcard2_sel < ARRAY_SIZE(memcards)) {
+               if (memcard2_sel == 0)
+                       strcpy(Config.Mcd2, "none");
+               else if (memcards[memcard2_sel] != NULL)
+                       snprintf(Config.Mcd2, sizeof(Config.Mcd2), ".%s%s",
+                               MEMCARD_DIR, memcards[memcard2_sel]);
+       }
+       if (strcmp(mcd1_old, Config.Mcd1) || strcmp(mcd2_old, Config.Mcd2))
+               LoadMcds(Config.Mcd1, Config.Mcd2);
+
        return ret;
 }
 
 static const char *filter_exts[] = {
        "bin", "img", "mdf", "iso", "cue", "z",
+       #ifdef HAVE_CHD
+       "chd",
+       #endif
        "bz",  "znx", "pbp", "cbn", NULL
 };
 
@@ -693,7 +745,7 @@ static unsigned short fname2color(const char *fname)
 static void draw_savestate_bg(int slot);
 
 #define MENU_ALIGN_LEFT
-#ifdef __ARM_ARCH_7A__ // assume hires device
+#ifndef HAVE_PRE_ARMV7 // assume hires device
 #define MENU_X2 1
 #else
 #define MENU_X2 0
@@ -774,7 +826,7 @@ static void draw_savestate_bg(int slot)
 
                // darken this so that menu text is visible
                if (g_menuscreen_w - w < 320)
-                       menu_darken_bg(d, d, w * 2, 0);
+                       menu_darken_bg(d, d, w, 0);
        }
 
 out:
@@ -813,7 +865,7 @@ me_bind_action emuctrl_actions[] =
        { "Toggle Frameskip ", 1 << SACTION_TOGGLE_FSKIP },
        { "Take Screenshot  ", 1 << SACTION_SCREENSHOT },
        { "Show/Hide FPS    ", 1 << SACTION_TOGGLE_FPS },
-#ifdef __ARM_ARCH_7A__
+#ifndef HAVE_PRE_ARMV7
        { "Switch Renderer  ", 1 << SACTION_SWITCH_DISPMODE },
 #endif
        { "Fast Forward     ", 1 << SACTION_FAST_FORWARD },
@@ -864,8 +916,6 @@ static void get_line(char *d, size_t size, const char *s)
                len = size - 1;
        strncpy(d, s, len);
        d[len] = 0;
-
-       mystrip(d);
 }
 
 static void keys_write_all(FILE *f)
@@ -972,7 +1022,10 @@ static void keys_load_all(const char *cfg)
        while (p != NULL && (p = strstr(p, "binddev = ")) != NULL) {
                p += 10;
 
+               // don't strip 'dev' because there are weird devices
+               // with names with space at the end
                get_line(dev, sizeof(dev), p);
+
                dev_id = in_config_parse_dev(dev);
                if (dev_id < 0) {
                        printf("input: can't handle dev: %s\n", dev);
@@ -1191,18 +1244,24 @@ static int menu_loop_keyconfig(int id, int keys)
 
 // ------------ gfx options menu ------------
 
-static const char *men_scaler[] = { "1x1", "scaled 4:3", "integer scaled 4:3", "fullscreen", "custom", NULL };
+static const char *men_scaler[] = {
+       "1x1", "integer scaled 2x", "scaled 4:3", "integer scaled 4:3", "fullscreen", "custom", NULL
+};
 static const char *men_soft_filter[] = { "None",
 #ifdef __ARM_NEON__
        "scale2x", "eagle2x",
 #endif
        NULL };
 static const char *men_dummy[] = { NULL };
+static const char h_scaler[]    = "int. 2x  - scales w. or h. 2x if it fits on screen\n"
+                                 "int. 4:3 - uses integer if possible, else fractional";
 static const char h_cscaler[]   = "Displays the scaler layer, you can resize it\n"
                                  "using d-pad or move it using R+d-pad";
-static const char h_overlay[]   = "Overlay provides hardware accelerated scaling";
 static const char h_soft_filter[] = "Works only if game uses low resolution modes";
 static const char h_gamma[]     = "Gamma/brightness adjustment (default 100)";
+#ifdef __ARM_NEON__
+static const char h_scanline_l[]  = "Scanline brightness, 0-100%";
+#endif
 
 static int menu_loop_cscaler(int id, int keys)
 {
@@ -1258,11 +1317,15 @@ static int menu_loop_cscaler(int id, int keys)
 
 static menu_entry e_menu_gfx_options[] =
 {
-       mee_enum      ("Scaler",                   MA_OPT_VARSCALER, g_scaler, men_scaler),
+       mee_enum_h    ("Scaler",                   MA_OPT_VARSCALER, g_scaler, men_scaler, h_scaler),
        mee_enum      ("Video output mode",        MA_OPT_VOUT_MODE, plat_target.vout_method, men_dummy),
        mee_onoff     ("Software Scaling",         MA_OPT_SCALER2, soft_scaling, 1),
        mee_enum      ("Hardware Filter",          MA_OPT_HWFILTER, plat_target.hwfilter, men_dummy),
        mee_enum_h    ("Software Filter",          MA_OPT_SWFILTER, soft_filter, men_soft_filter, h_soft_filter),
+#ifdef __ARM_NEON__
+       mee_onoff     ("Scanlines",                MA_OPT_SCANLINES, scanlines, 1),
+       mee_range_h   ("Scanline brightness",      MA_OPT_SCANLINE_LEVEL, scanline_level, 0, 100, h_scanline_l),
+#endif
        mee_range_h   ("Gamma adjustment",         MA_OPT_GAMMA, g_gamma, 1, 200, h_gamma),
 //     mee_onoff     ("Vsync",                    0, vsync, 1),
        mee_cust_h    ("Setup custom scaler",      MA_OPT_VARSCALER_C, menu_loop_cscaler, NULL, h_cscaler),
@@ -1324,6 +1387,25 @@ static int menu_loop_plugin_gpu_unai(int id, int keys)
        return 0;
 }
 
+static menu_entry e_menu_plugin_gpu_senquack[] =
+{
+       mee_onoff     ("Interlace",                  0, pl_rearmed_cbs.gpu_senquack.ilace_force, 1),
+       mee_onoff     ("Dithering",                  0, pl_rearmed_cbs.gpu_senquack.dithering, 1),
+       mee_onoff     ("Lighting",                   0, pl_rearmed_cbs.gpu_senquack.lighting, 1),
+       mee_onoff     ("Fast lighting",              0, pl_rearmed_cbs.gpu_senquack.fast_lighting, 1),
+       mee_onoff     ("Blending",                   0, pl_rearmed_cbs.gpu_senquack.blending, 1),
+       mee_onoff     ("Pixel skip",                 0, pl_rearmed_cbs.gpu_senquack.pixel_skip, 1),
+       mee_end,
+};
+
+static int menu_loop_plugin_gpu_senquack(int id, int keys)
+{
+       int sel = 0;
+       me_loop(e_menu_plugin_gpu_senquack, &sel);
+       return 0;
+}
+
+
 static const char *men_gpu_dithering[] = { "None", "Game dependant", "Always", NULL };
 //static const char h_gpu_0[]            = "Needed for Chrono Cross";
 static const char h_gpu_1[]            = "Capcom fighting games";
@@ -1425,6 +1507,7 @@ static const char h_plugin_gpu[] =
 #endif
                                   "gpu_peops is Pete's soft GPU, slow but accurate\n"
                                   "gpu_unai is GPU from PCSX4ALL, fast but glitchy\n"
+                                  "gpu_senquack is more accurate but slower\n"
                                   "gpu_gles Pete's hw GPU, uses 3D chip but is glitchy\n"
                                   "must save config and reload the game if changed";
 static const char h_plugin_spu[] = "spunull effectively disables sound\n"
@@ -1432,6 +1515,7 @@ static const char h_plugin_spu[] = "spunull effectively disables sound\n"
 static const char h_gpu_peops[]  = "Configure P.E.Op.S. SoftGL Driver V1.17";
 static const char h_gpu_peopsgl[]= "Configure P.E.Op.S. MesaGL Driver V1.78";
 static const char h_gpu_unai[]   = "Configure Unai/PCSX4ALL Team GPU plugin";
+static const char h_gpu_senquack[]   = "Configure Unai/PCSX4ALL Senquack plugin";
 static const char h_spu[]        = "Configure built-in P.E.Op.S. Sound Driver V1.7";
 
 static menu_entry e_menu_plugin_options[] =
@@ -1444,6 +1528,7 @@ static menu_entry e_menu_plugin_options[] =
 #endif
        mee_handler_h ("Configure gpu_peops plugin",    menu_loop_plugin_gpu_peops, h_gpu_peops),
        mee_handler_h ("Configure gpu_unai GPU plugin", menu_loop_plugin_gpu_unai, h_gpu_unai),
+       mee_handler_h ("Configure gpu_senquack GPU plugin", menu_loop_plugin_gpu_senquack, h_gpu_senquack),
        mee_handler_h ("Configure gpu_gles GPU plugin", menu_loop_plugin_gpu_peopsgl, h_gpu_peopsgl),
        mee_handler_h ("Configure built-in SPU plugin", menu_loop_plugin_spu, h_spu),
        mee_end,
@@ -1467,18 +1552,24 @@ static int menu_loop_plugin_options(int id, int keys)
 
 // ------------ adv options menu ------------
 
+#ifndef DRC_DISABLE
 static const char h_cfg_psxclk[]  = "Over/under-clock the PSX, default is " DEFAULT_PSX_CLOCK_S "\n"
                                    "(lower value - less work for the emu, may be faster)";
 static const char h_cfg_nosmc[]   = "Will cause crashes when loading, break memcards";
 static const char h_cfg_gteunn[]  = "May cause graphical glitches";
 static const char h_cfg_gteflgs[] = "Will cause graphical glitches";
+#endif
+static const char h_cfg_stalls[]  = "Will cause some games to run too fast";
 
 static menu_entry e_menu_speed_hacks[] =
 {
+#ifndef DRC_DISABLE
        mee_range_h   ("PSX CPU clock, %%",        0, psx_clock, 1, 500, h_cfg_psxclk),
        mee_onoff_h   ("Disable SMC checks",       0, new_dynarec_hacks, NDHACK_NO_SMC_CHECK, h_cfg_nosmc),
        mee_onoff_h   ("Assume GTE regs unneeded", 0, new_dynarec_hacks, NDHACK_GTE_UNNEEDED, h_cfg_gteunn),
        mee_onoff_h   ("Disable GTE flags",        0, new_dynarec_hacks, NDHACK_GTE_NO_FLAGS, h_cfg_gteflgs),
+#endif
+       mee_onoff_h   ("Disable CPU/GTE stalls",   0, Config.DisableStalls, 1, h_cfg_stalls),
        mee_end,
 };
 
@@ -1496,16 +1587,18 @@ static const char h_cfg_fl[]     = "Frame Limiter keeps the game from running to
 static const char h_cfg_xa[]     = "Disables XA sound, which can sometimes improve performance";
 static const char h_cfg_cdda[]   = "Disable CD Audio for a performance boost\n"
                                   "(proper .cue/.bin dump is needed otherwise)";
-static const char h_cfg_sio[]    = "You should not need this, breaks games";
+//static const char h_cfg_sio[]    = "You should not need this, breaks games";
 static const char h_cfg_spuirq[] = "Compatibility tweak; should be left off";
-static const char h_cfg_rcnt1[]  = "Parasite Eve 2, Vandal Hearts 1/2 Fix\n"
-                                  "(timing hack, breaks other games)";
+//static const char h_cfg_rcnt1[]  = "Parasite Eve 2, Vandal Hearts 1/2 Fix\n"
+//                                "(timing hack, breaks other games)";
 static const char h_cfg_rcnt2[]  = "InuYasha Sengoku Battle Fix\n"
                                   "(timing hack, breaks other games)";
+#ifndef DRC_DISABLE
 static const char h_cfg_nodrc[]  = "Disable dynamic recompiler and use interpreter\n"
                                   "Might be useful to overcome some dynarec bugs";
-static const char h_cfg_shacks[] = "Breaks games but may give better performance\n"
-                                  "must reload game for any change to take effect";
+#endif
+static const char h_cfg_shacks[] = "Breaks games but may give better performance";
+static const char h_cfg_icache[] = "Support F1 games (only when dynarec is off)";
 
 static menu_entry e_menu_adv_options[] =
 {
@@ -1516,9 +1609,12 @@ static menu_entry e_menu_adv_options[] =
        mee_onoff_h   ("Disable CD Audio",       0, Config.Cdda, 1, h_cfg_cdda),
        //mee_onoff_h   ("SIO IRQ Always Enabled", 0, Config.Sio, 1, h_cfg_sio),
        mee_onoff_h   ("SPU IRQ Always Enabled", 0, Config.SpuIrq, 1, h_cfg_spuirq),
+       mee_onoff_h   ("ICache emulation",       0, Config.icache_emulation, 1, h_cfg_icache),
        //mee_onoff_h   ("Rootcounter hack",       0, Config.RCntFix, 1, h_cfg_rcnt1),
        mee_onoff_h   ("Rootcounter hack 2",     0, Config.VSyncWA, 1, h_cfg_rcnt2),
+#ifndef DRC_DISABLE
        mee_onoff_h   ("Disable dynarec (slow!)",0, Config.Cpu, 1, h_cfg_nodrc),
+#endif
        mee_handler_h ("[Speed hacks]",             menu_loop_speed_hacks, h_cfg_shacks),
        mee_end,
 };
@@ -1558,6 +1654,11 @@ static menu_entry e_menu_options[] =
        mee_onoff     ("Show FPS",                 0, g_opts, OPT_SHOWFPS),
        mee_enum      ("Region",                   0, region, men_region),
        mee_range     ("CPU clock",                MA_OPT_CPU_CLOCKS, cpu_clock, 20, 5000),
+#ifdef C64X_DSP
+       mee_onoff     ("Use C64x DSP for sound",   MA_OPT_SPU_THREAD, spu_config.iUseThread, 1),
+#else
+       mee_onoff     ("Threaded SPU",             MA_OPT_SPU_THREAD, spu_config.iUseThread, 1),
+#endif
        mee_handler_id("[Display]",                MA_OPT_DISP_OPTS, menu_loop_gfx_options),
        mee_handler   ("[BIOS/Plugins]",           menu_loop_plugin_options),
        mee_handler   ("[Advanced]",               menu_loop_adv_options),
@@ -1570,10 +1671,9 @@ 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 = cpu_clock_st > 0 ? 1 : 0;
+       me_enable(e_menu_options, MA_OPT_CPU_CLOCKS, cpu_clock_st > 0);
+       me_enable(e_menu_options, MA_OPT_SPU_THREAD, spu_config.iThreadAvail);
        me_enable(e_menu_options, MA_OPT_SAVECFG_GAME, ready_to_go && CdromId[0]);
 
        me_loop(e_menu_options, &sel);
@@ -1882,7 +1982,7 @@ static const char credits_text[] =
        "PCSX4ALL plugin by PCSX4ALL team\n"
        "  Chui, Franxis, Unai\n\n"
        "integration, optimization and\n"
-       "  frontend (C) 2010-2012 notaz\n";
+       "  frontend (C) 2010-2015 notaz\n";
 
 static int reset_game(void)
 {
@@ -1963,6 +2063,8 @@ static int run_exe(void)
 
 static int run_cd_image(const char *fname)
 {
+       int autoload_state = g_autostateld_opt;
+
        ready_to_go = 0;
        reload_plugins(fname);
 
@@ -1988,6 +2090,28 @@ static int run_cd_image(const char *fname)
        emu_on_new_cd(1);
        ready_to_go = 1;
 
+       if (autoload_state) {
+               unsigned int newest = 0;
+               int time, slot, newest_slot = -1;
+
+               for (slot = 0; slot < 10; slot++) {
+                       if (emu_check_save_file(slot, &time)) {
+                               if ((unsigned int)time > newest) {
+                                       newest = time;
+                                       newest_slot = slot;
+                               }
+                       }
+               }
+
+               if (newest_slot >= 0) {
+                       lprintf("autoload slot %d\n", newest_slot);
+                       emu_load_state(newest_slot);
+               }
+               else {
+                       lprintf("no save to autoload.\n");
+               }
+       }
+
        return 0;
 }
 
@@ -2444,7 +2568,7 @@ void menu_init(void)
        me_enable(e_menu_gfx_options, MA_OPT_GAMMA,
                plat_target.gamma_set != NULL);
 
-#ifndef __ARM_ARCH_7A__
+#ifdef HAVE_PRE_ARMV7
        me_enable(e_menu_gfx_options, MA_OPT_SWFILTER, 0);
 #endif
        me_enable(e_menu_gfx_options, MA_OPT_VARSCALER, MENU_SHOW_VARSCALER);
@@ -2504,7 +2628,11 @@ void menu_prepare_emu(void)
 
        plat_video_menu_leave();
 
+       #ifndef DRC_DISABLE
        psxCpu = (Config.Cpu == CPU_INTERPRETER) ? &psxInt : &psxRec;
+       #else
+       psxCpu = &psxInt;
+       #endif
        if (psxCpu != prev_cpu) {
                prev_cpu->Shutdown();
                psxCpu->Init();
@@ -2512,6 +2640,8 @@ void menu_prepare_emu(void)
                psxCpu->Reset();
        }
 
+       psxCpu->ApplyConfig();
+
        // core doesn't care about Config.Cdda changes,
        // so handle them manually here
        if (Config.Cdda)