frontend: make analogs configurable
[pcsx_rearmed.git] / frontend / menu.c
index cfdc62d..e720de6 100644 (file)
@@ -28,6 +28,7 @@
 #include "linux/in_evdev.h"
 #include "../libpcsxcore/misc.h"
 #include "../libpcsxcore/cdrom.h"
+#include "../libpcsxcore/cdriso.h"
 #include "../libpcsxcore/psemu_plugin_defs.h"
 #include "../libpcsxcore/new_dynarec/new_dynarec.h"
 #include "../plugins/dfinput/main.h"
@@ -44,6 +45,7 @@ typedef enum
        MA_MAIN_RESET_GAME,
        MA_MAIN_LOAD_ROM,
        MA_MAIN_SWAP_CD,
+       MA_MAIN_SWAP_CD_MULTI,
        MA_MAIN_RUN_BIOS,
        MA_MAIN_RUN_EXE,
        MA_MAIN_CONTROLS,
@@ -51,11 +53,13 @@ typedef enum
        MA_MAIN_EXIT,
        MA_CTRL_PLAYER1,
        MA_CTRL_PLAYER2,
+       MA_CTRL_ANALOG,
        MA_CTRL_EMU,
        MA_CTRL_DEV_FIRST,
        MA_CTRL_DEV_NEXT,
        MA_CTRL_NUBS_BTNS,
        MA_CTRL_DEADZONE,
+       MA_CTRL_VIBRATION,
        MA_CTRL_DONE,
        MA_OPT_SAVECFG,
        MA_OPT_SAVECFG_GAME,
@@ -169,7 +173,7 @@ static void menu_sync_config(void)
        default: in_type2 = PSE_PAD_TYPE_STANDARD;
        }
        if (in_evdev_allow_abs_only != allow_abs_only_old) {
-               plat_rescan_inputs();
+               in_probe();
                allow_abs_only_old = in_evdev_allow_abs_only;
        }
 
@@ -267,6 +271,7 @@ static const struct {
        CE_INTVAL(volume_boost),
        CE_INTVAL(psx_clock),
        CE_INTVAL(new_dynarec_hacks),
+       CE_INTVAL(in_enable_vibration),
 };
 
 static char *get_cd_label(void)
@@ -815,6 +820,12 @@ static void keys_write_all(FILE *f)
                                }
                        }
                }
+
+               for (k = 0; k < array_size(in_adev); k++)
+               {
+                       if (in_adev[k] == d)
+                               fprintf(f, "bind_analog = %d\n", k);
+               }
        }
 }
 
@@ -857,7 +868,7 @@ static void keys_load_all(const char *cfg)
        char dev[256], key[128], *act;
        const char *p;
        int bind, bindtype;
-       int dev_id;
+       int ret, dev_id;
 
        p = cfg;
        while (p != NULL && (p = strstr(p, "binddev = ")) != NULL) {
@@ -875,6 +886,21 @@ static void keys_load_all(const char *cfg)
                        if (strncmp(p, "binddev = ", 10) == 0)
                                break;
 
+                       if (strncmp(p, "bind_analog", 11) == 0) {
+                               ret = sscanf(p, "bind_analog = %d", &bind);
+                               p += 11;
+                               if (ret != 1) {
+                                       printf("input: parse error: %16s..\n", p);
+                                       continue;
+                               }
+                               if ((unsigned int)bind >= array_size(in_adev)) {
+                                       printf("input: analog id %d out of range\n", bind);
+                                       continue;
+                               }
+                               in_adev[bind] = dev_id;
+                               continue;
+                       }
+
                        p += 4;
                        if (*p != ' ') {
                                printf("input: parse error: %16s..\n", p);
@@ -922,6 +948,57 @@ static int key_config_loop_wrap(int id, int keys)
        return 0;
 }
 
+static const char *adevnames[IN_MAX_DEVS + 2];
+static int stick_sel[2];
+
+static menu_entry e_menu_keyconfig_analog[] =
+{
+       mee_enum ("Left stick (L3)",  0, stick_sel[0], adevnames),
+       mee_range("  X axis",    0, in_adev_axis[0][0], 0, 7),
+       mee_range("  Y axis",    0, in_adev_axis[0][1], 0, 7),
+       mee_enum ("Right stick (R3)", 0, stick_sel[1], adevnames),
+       mee_range("  X axis",    0, in_adev_axis[1][0], 0, 7),
+       mee_range("  Y axis",    0, in_adev_axis[1][1], 0, 7),
+       mee_end,
+};
+
+static int key_config_analog(int id, int keys)
+{
+       int i, d, count, sel = 0;
+       int sel2dev_map[IN_MAX_DEVS];
+
+       memset(adevnames, 0, sizeof(adevnames));
+       memset(sel2dev_map, 0xff, sizeof(sel2dev_map));
+       memset(stick_sel, 0, sizeof(stick_sel));
+
+       adevnames[0] = "None";
+       i = 1;
+       for (d = 0; d < IN_MAX_DEVS; d++)
+       {
+               const char *name = in_get_dev_name(d, 0, 1);
+               if (name == NULL)
+                       continue;
+
+               count = 0;
+               in_get_config(d, IN_CFG_ABS_AXIS_COUNT, &count);
+               if (count == 0)
+                       continue;
+
+               if (in_adev[0] == d) stick_sel[0] = i;
+               if (in_adev[1] == d) stick_sel[1] = i;
+               sel2dev_map[i] = d;
+               adevnames[i++] = name;
+       }
+       adevnames[i] = NULL;
+
+       me_loop(e_menu_keyconfig_analog, &sel);
+
+       in_adev[0] = sel2dev_map[stick_sel[0]];
+       in_adev[1] = sel2dev_map[stick_sel[1]];
+
+       return 0;
+}
+
 static const char *mgn_dev_name(int id, int *offs)
 {
        const char *name = NULL;
@@ -958,7 +1035,7 @@ static int mh_savecfg(int id, int keys)
 static int mh_input_rescan(int id, int keys)
 {
        //menu_sync_config();
-       plat_rescan_inputs();
+       in_probe();
        me_update_msg("rescan complete.");
 
        return 0;
@@ -971,24 +1048,26 @@ static const char *men_in_type_sel[] = {
        NULL
 };
 static const char h_nub_btns[] = "Experimental, keep this OFF if unsure. Select rescan after change.";
-static const char h_notsgun[] =  "Don't trigger (shoot) when touching screen in gun games.";
+static const char h_notsgun[]  = "Don't trigger (shoot) when touching screen in gun games.";
+static const char h_vibration[]= "Must select analog above and enable this ingame too.";
 
 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("Analog controls",       MA_CTRL_ANALOG,     key_config_analog),
        mee_handler_id("Emulator/Gun controls", MA_CTRL_EMU,        key_config_loop_wrap),
        mee_label     (""),
        mee_enum      ("Port 1 device",     0, in_type_sel1,    men_in_type_sel),
        mee_enum      ("Port 2 device",     0, in_type_sel2,    men_in_type_sel),
        mee_onoff_h   ("Nubs as buttons",   MA_CTRL_NUBS_BTNS,  in_evdev_allow_abs_only, 1, h_nub_btns),
+       mee_onoff_h   ("Vibration",         MA_CTRL_VIBRATION,  in_enable_vibration, 1, h_vibration),
        mee_range     ("Analog deadzone",   MA_CTRL_DEADZONE,   analog_deadzone, 1, 99),
        mee_onoff_h   ("No TS Gun trigger", 0, g_opts, OPT_TSGUN_NOTRIGGER, h_notsgun),
        mee_cust_nosave("Save global config",       MA_OPT_SAVECFG,      mh_savecfg, mgn_saveloadcfg),
        mee_cust_nosave("Save cfg for loaded game", MA_OPT_SAVECFG_GAME, mh_savecfg, mgn_saveloadcfg),
-       mee_handler   ("Rescan devices",  mh_input_rescan),
+       mee_handler   ("Rescan devices:",  mh_input_rescan),
        mee_label     (""),
-       mee_label     ("Input devices:"),
        mee_label_mk  (MA_CTRL_DEV_FIRST, mgn_dev_name),
        mee_label_mk  (MA_CTRL_DEV_NEXT,  mgn_dev_name),
        mee_label_mk  (MA_CTRL_DEV_NEXT,  mgn_dev_name),
@@ -1577,6 +1656,7 @@ static int reload_plugins(const char *cdimg)
        }
        plugin_call_rearmed_cbs();
 
+       cdrIsoMultidiskCount = 1;
        CdromId[0] = '\0';
        CdromLabel[0] = '\0';
 
@@ -1645,6 +1725,8 @@ static int run_cd_image(const char *fname)
        }
 
        ready_to_go = 1;
+       snprintf(hud_msg, sizeof(hud_msg), "Booting up...");
+       hud_new_msg = 2;
        return 0;
 }
 
@@ -1714,6 +1796,24 @@ static int swap_cd_image(void)
        return 0;
 }
 
+static int swap_cd_multidisk(void)
+{
+       cdrIsoMultidiskSelect++;
+       CdromId[0] = '\0';
+       CdromLabel[0] = '\0';
+
+       CDR_close();
+       if (CDR_open() < 0) {
+               me_update_msg("failed to open cdr plugin");
+               return -1;
+       }
+
+       SetCdOpenCaseTime(time(NULL) + 2);
+       LidInterrupt();
+
+       return 0;
+}
+
 static int main_menu_handler(int id, int keys)
 {
        switch (id)
@@ -1742,6 +1842,10 @@ static int main_menu_handler(int id, int keys)
                if (swap_cd_image() == 0)
                        return 1;
                break;
+       case MA_MAIN_SWAP_CD_MULTI:
+               if (swap_cd_multidisk() == 0)
+                       return 1;
+               break;
        case MA_MAIN_RUN_BIOS:
                if (run_bios() == 0)
                        return 1;
@@ -1767,9 +1871,10 @@ static int main_menu_handler(int id, int keys)
 
 static menu_entry e_menu_main2[] =
 {
-       mee_handler_id("Change CD image",    MA_MAIN_SWAP_CD,     main_menu_handler),
-       mee_handler_id("Run BIOS",           MA_MAIN_RUN_BIOS,    main_menu_handler),
-       mee_handler_id("Run EXE",            MA_MAIN_RUN_EXE,     main_menu_handler),
+       mee_handler_id("Change CD image",    MA_MAIN_SWAP_CD,       main_menu_handler),
+       mee_handler_id("Next multidisk CD",  MA_MAIN_SWAP_CD_MULTI, main_menu_handler),
+       mee_handler_id("Run BIOS",           MA_MAIN_RUN_BIOS,      main_menu_handler),
+       mee_handler_id("Run EXE",            MA_MAIN_RUN_EXE,       main_menu_handler),
        mee_handler   ("Memcard manager",    menu_loop_memcards),
        mee_end,
 };
@@ -1779,6 +1884,7 @@ static int main_menu2_handler(int id, int keys)
        static int sel = 0;
 
        me_enable(e_menu_main2, MA_MAIN_SWAP_CD,  ready_to_go);
+       me_enable(e_menu_main2, MA_MAIN_SWAP_CD_MULTI, ready_to_go && cdrIsoMultidiskCount > 1);
        me_enable(e_menu_main2, MA_MAIN_RUN_BIOS, bios_sel != 0);
 
        return me_loop_d(e_menu_main2, &sel, NULL, draw_frame_main);
@@ -2015,6 +2121,7 @@ void menu_init(void)
        me_enable(e_menu_options, MA_OPT_DISP_OPTS, 0);
        me_enable(e_menu_keyconfig, MA_CTRL_NUBS_BTNS, 0);
 #else
+       me_enable(e_menu_keyconfig, MA_CTRL_VIBRATION, 0);
        me_enable(e_menu_keyconfig, MA_CTRL_DEADZONE, 0);
 #endif
 }