defaut dualshock to digital again, unless overriden
authornotaz <notasas@gmail.com>
Mon, 20 Nov 2023 00:17:24 +0000 (02:17 +0200)
committernotaz <notasas@gmail.com>
Mon, 20 Nov 2023 00:19:44 +0000 (02:19 +0200)
... or a key combo is used
libretro/pcsx_rearmed#765

frontend/libretro.c
frontend/libretro_core_options.h
include/psemu_plugin_defs.h
libpcsxcore/database.c
libpcsxcore/plugins.c
libpcsxcore/plugins.h
libpcsxcore/psxcommon.h

index c47d260..7f33157 100644 (file)
@@ -145,7 +145,9 @@ int in_mouse[8][2];
 int multitap1 = 0;
 int multitap2 = 0;
 int in_enable_vibration = 1;
-int in_enable_crosshair[2] = { 0, 0 };
+static int in_enable_crosshair[2] = { 0, 0 };
+static bool in_dualshock_toggle_enable = 0;
+static bool in_dualshock_toggling = 0;
 
 // NegCon adjustment parameters
 // > The NegCon 'twist' action is somewhat awkward when mapped
@@ -2011,6 +2013,14 @@ static void update_variables(bool in_flight)
          in_enable_vibration = 1;
    }
 
+   var.value = NULL;
+   var.key = "pcsx_rearmed_analog_toggle";
+
+   if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
+   {
+      in_dualshock_toggle_enable = (strcmp(var.value, "enabled") == 0);
+   }
+
    var.value = NULL;
    var.key = "pcsx_rearmed_dithering";
 
@@ -2863,10 +2873,14 @@ static void update_input_mouse(int port, int ret)
 
 static void update_input(void)
 {
-   // reset all keystate, query libretro for keystate
+   int16_t analog_combo =
+      (1 << RETRO_DEVICE_ID_JOYPAD_L) |
+      (1 << RETRO_DEVICE_ID_JOYPAD_R) |
+      (1 << RETRO_DEVICE_ID_JOYPAD_SELECT);
    int i;
    int j;
 
+   // reset all keystate, query libretro for keystate
    for (i = 0; i < PORTS_NUMBER; i++)
    {
       int16_t ret = 0;
@@ -2903,7 +2917,23 @@ static void update_input(void)
          update_input_mouse(i, ret);
          break;      
       default:
-         // Query digital inputs
+         // dualshock ANALOG toggle?
+         if (type == PSE_PAD_TYPE_ANALOGPAD && in_dualshock_toggle_enable
+             && (ret & analog_combo) == analog_combo)
+         {
+            if (!in_dualshock_toggling)
+            {
+               int state = padToggleAnalog(i);
+               char msg[32];
+               snprintf(msg, sizeof(msg), "ANALOG %s", state ? "ON" : "OFF");
+               show_notification(msg, 800, 1);
+               in_dualshock_toggling = true;
+            }
+            return;
+         }
+         in_dualshock_toggling = false;
+
+         // Set digital inputs
          for (j = 0; j < RETRO_PSX_MAP_LEN; j++)
             if (ret & (1 << j))
                in_keystate[i] |= retro_psx_map[j];
index 0ec6123..104b4b4 100644 (file)
@@ -853,6 +853,20 @@ struct retro_core_option_v2_definition option_defs_us[] = {
       },
       "enabled",
    },
+   {
+      "pcsx_rearmed_analog_toggle",
+      "DualShock Analog Mode Toggle",
+      NULL,
+      "When the input device type is DualShock, this option allows the emulated DualShock to be toggled between DIGITAL and ANALOG mode like original hardware. The button combination is L1 + R1 + Select.",
+      NULL,
+      "input",
+      {
+         { "disabled", NULL },
+         { "enabled",  NULL },
+         { NULL, NULL },
+      },
+      "enabled",
+   },
    {
       "pcsx_rearmed_multitap",
       "Multitap Mode",
index 3f4d21b..6136ca7 100644 (file)
@@ -228,7 +228,7 @@ typedef struct
                unsigned char padMode; // 0 : digital 1: analog
                unsigned char cmd4dConfig[6];
                unsigned int  lastUseFrame;
-               unsigned int  digitalModeFrames;
+               unsigned int  unused;
                unsigned char configModeUsed;
                unsigned char padding[3];
        } ds;
index 93ef44b..87b02a9 100644 (file)
@@ -53,6 +53,12 @@ static const char * const gpu_centering_hack_db[] =
        "SLPM86009",
 };
 
+static const char * const dualshock_init_analog_hack_db[] =
+{
+       /* Formula 1 Championship Edition */
+       "SLUS00546",
+};
+
 #define HACK_ENTRY(var, list) \
        { #var, &Config.hacks.var, list, ARRAY_SIZE(list) }
 
@@ -69,6 +75,7 @@ hack_db[] =
        HACK_ENTRY(gpu_slow_list_walking, gpu_slow_llist_db),
        HACK_ENTRY(gpu_busy, gpu_busy_hack_db),
        HACK_ENTRY(gpu_centering, gpu_centering_hack_db),
+       HACK_ENTRY(dualshock_init_analog, dualshock_init_analog_hack_db),
 };
 
 static const struct
@@ -151,6 +158,12 @@ void Apply_Hacks_Cdrom(void)
                }
        }
 
+       if (Config.hacks.dualshock_init_analog) {
+               // assume the default is off, see LoadPAD1plugin()
+               for (i = 0; i < 8; i++)
+                       padToggleAnalog(i);
+       }
+
        /* Apply Memory card hack for Codename Tenka. (The game needs one of the memory card slots to be empty) */
        for (i = 0; i < ARRAY_SIZE(MemorycardHack_db); i++)
        {
index d44442b..75e1f5f 100644 (file)
@@ -490,15 +490,8 @@ static void initBufForRequest(int padIndex, char value) {
                return;
        }
 
-       // switch to analog mode automatically after the game finishes init
-       if (value == 0x42 && pads[padIndex].ds.padMode == 0)
-               pads[padIndex].ds.digitalModeFrames++;
-       if (pads[padIndex].ds.digitalModeFrames == 60*4) {
-               pads[padIndex].ds.padMode = 1;
-               pads[padIndex].ds.digitalModeFrames = 0;
-       }
-
-       if ((u32)(frame_counter - pads[padIndex].ds.lastUseFrame) > 60u)
+       if ((u32)(frame_counter - pads[padIndex].ds.lastUseFrame) > 60u
+           && !Config.hacks.dualshock_init_analog)
                pads[padIndex].ds.padMode = 0; // according to nocash
        pads[padIndex].ds.lastUseFrame = frame_counter;
 
@@ -991,6 +984,15 @@ int padFreeze(void *f, int Mode) {
        return 0;
 }
 
+int padToggleAnalog(unsigned int index)
+{
+       int r = -1;
+
+       if (index < sizeof(pads) / sizeof(pads[0]))
+               r = (pads[index].ds.padMode ^= 1);
+       return r;
+}
+
 
 void *hNETDriver = NULL;
 
index 269ef18..772452d 100644 (file)
@@ -384,6 +384,7 @@ boolean UsingIso(void);
 void SetCdOpenCaseTime(s64 time);\r
 \r
 int padFreeze(void *f, int Mode);\r
+int padToggleAnalog(unsigned int index);\r
 \r
 extern void pl_gun_byte2(int port, unsigned char byte);\r
 extern void plat_trigger_vibrate(int pad, int low, int high);\r
index 09fb39a..01b2a9a 100644 (file)
@@ -152,6 +152,7 @@ typedef struct {
                boolean gpu_slow_list_walking;
                boolean gpu_busy;
                boolean gpu_centering;
+               boolean dualshock_init_analog;
        } hacks;
 } PcsxConfig;