From e5241564f4444496f51f4de9bf533b1d910449ec Mon Sep 17 00:00:00 2001 From: notaz Date: Mon, 20 Nov 2023 02:17:24 +0200 Subject: [PATCH] defaut dualshock to digital again, unless overriden ... or a key combo is used libretro/pcsx_rearmed#765 --- frontend/libretro.c | 36 +++++++++++++++++++++++++++++--- frontend/libretro_core_options.h | 14 +++++++++++++ include/psemu_plugin_defs.h | 2 +- libpcsxcore/database.c | 13 ++++++++++++ libpcsxcore/plugins.c | 20 ++++++++++-------- libpcsxcore/plugins.h | 1 + libpcsxcore/psxcommon.h | 1 + 7 files changed, 74 insertions(+), 13 deletions(-) diff --git a/frontend/libretro.c b/frontend/libretro.c index c47d260b..7f331574 100644 --- a/frontend/libretro.c +++ b/frontend/libretro.c @@ -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]; diff --git a/frontend/libretro_core_options.h b/frontend/libretro_core_options.h index 5ec62f4b..85771e2c 100644 --- a/frontend/libretro_core_options.h +++ b/frontend/libretro_core_options.h @@ -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", diff --git a/include/psemu_plugin_defs.h b/include/psemu_plugin_defs.h index 3f4d21b2..6136ca70 100644 --- a/include/psemu_plugin_defs.h +++ b/include/psemu_plugin_defs.h @@ -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; diff --git a/libpcsxcore/database.c b/libpcsxcore/database.c index ebdb69b6..7b860e34 100644 --- a/libpcsxcore/database.c +++ b/libpcsxcore/database.c @@ -47,6 +47,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) } @@ -63,6 +69,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 @@ -116,6 +123,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++) { diff --git a/libpcsxcore/plugins.c b/libpcsxcore/plugins.c index d44442b0..75e1f5fb 100644 --- a/libpcsxcore/plugins.c +++ b/libpcsxcore/plugins.c @@ -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; diff --git a/libpcsxcore/plugins.h b/libpcsxcore/plugins.h index 269ef18a..772452d0 100644 --- a/libpcsxcore/plugins.h +++ b/libpcsxcore/plugins.h @@ -384,6 +384,7 @@ boolean UsingIso(void); void SetCdOpenCaseTime(s64 time); int padFreeze(void *f, int Mode); +int padToggleAnalog(unsigned int index); extern void pl_gun_byte2(int port, unsigned char byte); extern void plat_trigger_vibrate(int pad, int low, int high); diff --git a/libpcsxcore/psxcommon.h b/libpcsxcore/psxcommon.h index 09fb39a4..01b2a9aa 100644 --- a/libpcsxcore/psxcommon.h +++ b/libpcsxcore/psxcommon.h @@ -152,6 +152,7 @@ typedef struct { boolean gpu_slow_list_walking; boolean gpu_busy; boolean gpu_centering; + boolean dualshock_init_analog; } hacks; } PcsxConfig; -- 2.39.2