frontend: enable SPUIRQWait by default
[pcsx_rearmed.git] / frontend / menu.c
index 0a4c271..7762905 100644 (file)
@@ -60,7 +60,7 @@ enum {
 };
 
 static int last_psx_w, last_psx_h, last_psx_bpp;
-static int scaling, filter, state_slot, cpu_clock, cpu_clock_st;
+static int scaling, filter, cpu_clock, cpu_clock_st;
 static char rom_fname_reload[MAXPATHLEN];
 static char last_selected_fname[MAXPATHLEN];
 static int region, in_type_sel;
@@ -103,28 +103,16 @@ void emu_make_path(char *buff, const char *end, int size)
 
 static int emu_check_save_file(int slot)
 {
-       char fname[MAXPATHLEN];
-       int ret;
-
-       ret = get_state_filename(fname, sizeof(fname), slot);
-       if (ret != 0)
-               return 0;
-
-       ret = CheckState(fname);
+       int ret = emu_check_state(slot);
        return ret == 0 ? 1 : 0;
 }
 
-static int emu_save_load_game(int load, int sram)
+static int emu_save_load_game(int load, int unused)
 {
-       char fname[MAXPATHLEN];
        int ret;
 
-       ret = get_state_filename(fname, sizeof(fname), state_slot);
-       if (ret != 0)
-               return 0;
-
        if (load) {
-               ret = LoadState(fname);
+               ret = emu_load_state(state_slot);
 
                // reflect hle/bios mode from savestate
                if (Config.HLE)
@@ -134,7 +122,7 @@ static int emu_save_load_game(int load, int sram)
                        bios_sel = 1;
        }
        else
-               ret = SaveState(fname);
+               ret = emu_save_state(state_slot);
 
        return ret;
 }
@@ -171,7 +159,8 @@ static void menu_set_defconfig(void)
 
        iUseReverb = 2;
        iUseInterpolation = 1;
-       iXAPitch = iSPUIRQWait = 0;
+       iXAPitch = 0;
+       iSPUIRQWait = 1;
        iUseTimer = 2;
 
        menu_sync_config();
@@ -189,6 +178,10 @@ static void menu_set_defconfig(void)
 #define CE_INTVAL(val) \
        { #val, sizeof(val), &val }
 
+// 'versioned' var, used when defaults change
+#define CE_INTVAL_V(val, ver) \
+       { #val #ver, sizeof(val), &val }
+
 static const struct {
        const char *name;
        size_t len;
@@ -223,9 +216,9 @@ static const struct {
        CE_INTVAL(UseFrameSkip),
        CE_INTVAL(dwActFixes),
        CE_INTVAL(iUseReverb),
-       CE_INTVAL(iUseInterpolation),
        CE_INTVAL(iXAPitch),
-       CE_INTVAL(iSPUIRQWait),
+       CE_INTVAL_V(iUseInterpolation, 2),
+       CE_INTVAL_V(iSPUIRQWait, 2),
        CE_INTVAL(iUseTimer),
 };
 
@@ -251,6 +244,8 @@ static void make_cfg_fname(char *buf, size_t size, int is_game)
                snprintf(buf, size, "." PCSX_DOT_DIR "%s", cfgfile_basename);
 }
 
+static void keys_write_all(FILE *f);
+
 static int menu_write_config(int is_game)
 {
        char cfgfile[MAXPATHLEN];
@@ -289,7 +284,9 @@ static int menu_write_config(int is_game)
        if (!is_game)
                fprintf(f, "lastcdimg = %s\n", last_selected_fname);
 
+       keys_write_all(f);
        fclose(f);
+
        return 0;
 }
 
@@ -305,6 +302,8 @@ static void parse_str_val(char *cval, const char *src)
                *tmp = 0;
 }
 
+static void keys_load_all(const char *cfg);
+
 static int menu_load_config(int is_game)
 {
        char cfgfile[MAXPATHLEN];
@@ -400,6 +399,7 @@ static int menu_load_config(int is_game)
                if (strcmp(Config.Spu, spu_plugins[i]) == 0)
                        { spu_plugsel = i; break; }
 
+       keys_load_all(cfg);
        ret = 0;
 fail_read:
        free(cfg);
@@ -647,6 +647,8 @@ me_bind_action me_ctrl_actions[] =
        { "R1      ", 1 << DKEY_R1 },
        { "L2      ", 1 << DKEY_L2 },
        { "R2      ", 1 << DKEY_R2 },
+       { "L3      ", 1 << DKEY_L3 },
+       { "R3      ", 1 << DKEY_R3 },
        { "START   ", 1 << DKEY_START },
        { "SELECT  ", 1 << DKEY_SELECT },
        { NULL,       0 }
@@ -654,16 +656,186 @@ me_bind_action me_ctrl_actions[] =
 
 me_bind_action emuctrl_actions[] =
 {
-/*
-       { "Load State       ", PEV_STATE_LOAD },
-       { "Save State       ", PEV_STATE_SAVE },
-       { "Prev Save Slot   ", PEV_SSLOT_PREV },
-       { "Next Save Slot   ", PEV_SSLOT_NEXT },
-*/
-       { "Enter Menu       ", PEV_MENU },
+       { "Save State       ", 1 << SACTION_SAVE_STATE },
+       { "Load State       ", 1 << SACTION_LOAD_STATE },
+       { "Prev Save Slot   ", 1 << SACTION_PREV_SSLOT },
+       { "Next Save Slot   ", 1 << SACTION_NEXT_SSLOT },
+       { "Toggle Frameskip ", 1 << SACTION_TOGGLE_FSKIP },
+       { "Enter Menu       ", 1 << SACTION_ENTER_MENU },
        { NULL,                0 }
 };
 
+static char *mystrip(char *str)
+{
+       int i, len;
+
+       len = strlen(str);
+       for (i = 0; i < len; i++)
+               if (str[i] != ' ') break;
+       if (i > 0) memmove(str, str + i, len - i + 1);
+
+       len = strlen(str);
+       for (i = len - 1; i >= 0; i--)
+               if (str[i] != ' ') break;
+       str[i+1] = 0;
+
+       return str;
+}
+
+static void get_line(char *d, size_t size, const char *s)
+{
+       const char *pe;
+       size_t len;
+
+       for (pe = s; *pe != '\r' && *pe != '\n' && *pe != 0; pe++)
+               ;
+       len = pe - s;
+       if (len > size - 1)
+               len = size - 1;
+       strncpy(d, s, len);
+       d[len] = 0;
+
+       mystrip(d);
+}
+
+static void keys_write_all(FILE *f)
+{
+       int d;
+
+       for (d = 0; d < IN_MAX_DEVS; d++)
+       {
+               const int *binds = in_get_dev_binds(d);
+               const char *name = in_get_dev_name(d, 0, 0);
+               int k, count = 0;
+
+               if (binds == NULL || name == NULL)
+                       continue;
+
+               fprintf(f, "binddev = %s\n", name);
+               in_get_config(d, IN_CFG_BIND_COUNT, &count);
+
+               for (k = 0; k < count; k++)
+               {
+                       int i, kbinds, mask;
+                       char act[32];
+
+                       act[0] = act[31] = 0;
+                       name = in_get_key_name(d, k);
+
+                       kbinds = binds[IN_BIND_OFFS(k, IN_BINDTYPE_PLAYER12)];
+                       for (i = 0; kbinds && i < ARRAY_SIZE(me_ctrl_actions) - 1; i++) {
+                               mask = me_ctrl_actions[i].mask;
+                               if (mask & kbinds) {
+                                       strncpy(act, me_ctrl_actions[i].name, 31);
+                                       fprintf(f, "bind %s = player1 %s\n", name, mystrip(act));
+                                       kbinds &= ~mask;
+                               }
+                               mask = me_ctrl_actions[i].mask << 16;
+                               if (mask & kbinds) {
+                                       strncpy(act, me_ctrl_actions[i].name, 31);
+                                       fprintf(f, "bind %s = player2 %s\n", name, mystrip(act));
+                                       kbinds &= ~mask;
+                               }
+                       }
+
+                       kbinds = binds[IN_BIND_OFFS(k, IN_BINDTYPE_EMU)];
+                       for (i = 0; kbinds && i < ARRAY_SIZE(emuctrl_actions) - 1; i++) {
+                               mask = emuctrl_actions[i].mask;
+                               if (mask & kbinds) {
+                                       strncpy(act, emuctrl_actions[i].name, 31);
+                                       fprintf(f, "bind %s = %s\n", name, mystrip(act));
+                                       kbinds &= ~mask;
+                               }
+                       }
+               }
+       }
+}
+
+static int parse_bind_val(const char *val, int *type)
+{
+       int i;
+
+       *type = IN_BINDTYPE_NONE;
+       if (val[0] == 0)
+               return 0;
+       
+       if (strncasecmp(val, "player", 6) == 0)
+       {
+               int player, shift = 0;
+               player = atoi(val + 6) - 1;
+
+               if ((unsigned int)player > 1)
+                       return -1;
+               if (player == 1)
+                       shift = 16;
+
+               *type = IN_BINDTYPE_PLAYER12;
+               for (i = 0; me_ctrl_actions[i].name != NULL; i++) {
+                       if (strncasecmp(me_ctrl_actions[i].name, val + 8, strlen(val + 8)) == 0)
+                               return me_ctrl_actions[i].mask << shift;
+               }
+       }
+       for (i = 0; emuctrl_actions[i].name != NULL; i++) {
+               if (strncasecmp(emuctrl_actions[i].name, val, strlen(val)) == 0) {
+                       *type = IN_BINDTYPE_EMU;
+                       return emuctrl_actions[i].mask;
+               }
+       }
+
+       return -1;
+}
+
+static void keys_load_all(const char *cfg)
+{
+       char dev[256], key[128], *act;
+       const char *p;
+       int bind, bindtype;
+       int dev_id;
+
+       p = cfg;
+       while (p != NULL && (p = strstr(p, "binddev = ")) != NULL) {
+               p += 10;
+
+               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);
+                       continue;
+               }
+
+               in_unbind_all(dev_id, -1, -1);
+               while ((p = strstr(p, "bind"))) {
+                       if (strncmp(p, "binddev = ", 10) == 0)
+                               break;
+
+                       p += 4;
+                       if (*p != ' ') {
+                               printf("input: parse error: %16s..\n", p);
+                               continue;
+                       }
+
+                       get_line(key, sizeof(key), p);
+                       act = strchr(key, '=');
+                       if (act == NULL) {
+                               printf("parse failed: %16s..\n", p);
+                               continue;
+                       }
+                       *act = 0;
+                       act++;
+                       mystrip(key);
+                       mystrip(act);
+
+                       bind = parse_bind_val(act, &bindtype);
+                       if (bind != -1 && bind != 0) {
+                               //printf("bind #%d '%s' %08x (%s)\n", dev_id, key, bind, act);
+                               in_config_bind_key(dev_id, key, bind, bindtype);
+                       }
+                       else
+                               lprintf("config: unhandled action \"%s\"\n", act);
+               }
+       }
+}
+
 static int key_config_loop_wrap(int id, int keys)
 {
        switch (id) {
@@ -859,7 +1031,7 @@ static int menu_loop_plugin_gpu(int id, int keys)
 
 static const char *men_spu_reverb[] = { "Off", "Fake", "On", NULL };
 static const char *men_spu_interp[] = { "None", "Simple", "Gaussian", "Cubic", NULL };
-static const char h_spu_irq_wait[]  = "Wait for CPU; only useful for some games, may cause glitches";
+static const char h_spu_irq_wait[]  = "Wait for CPU (recommended set to ON)";
 static const char h_spu_thread[]    = "Run sound emulation in main thread (recommended)";
 
 static menu_entry e_menu_plugin_spu[] =
@@ -915,7 +1087,7 @@ static int menu_loop_plugin_options(int id, int keys)
 
 // ------------ adv options menu ------------
 
-static const char h_cfg_cpul[]   = "Shows CPU usage in %%";
+static const char h_cfg_cpul[]   = "Shows CPU usage in %";
 static const char h_cfg_fl[]     = "Frame Limiter keeps the game from running too fast";
 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"