From 865a64bd96bdbd5ab295039361bef396f1ece189 Mon Sep 17 00:00:00 2001 From: somewhatlurker <52014015+somewhatlurker@users.noreply.github.com> Date: Tue, 11 Aug 2020 00:55:20 +1000 Subject: [PATCH 1/6] TLAC slider emulator: more directly emulate input data to avoid tracking section state, testing for ps4 official controller slider support also allow slider in menu (toggle in keyconfig) and remove need for hardware slider disabling patch (patches/launcher) --- source-code/data/plugins/config.ini | 2 - source-code/data/plugins/keyconfig.ini | 8 ++ .../source/plugins/Launcher/framework.h | 3 - .../source/plugins/Patches/dllmain.cpp | 6 -- .../Components/Input/TouchSliderEmulator.cpp | 89 +++++++++++++------ .../Components/Input/TouchSliderEmulator.h | 7 +- .../Components/Input/TouchSliderState.cpp | 11 ++- .../TLAC/Components/Input/TouchSliderState.h | 30 ++++++- 8 files changed, 114 insertions(+), 42 deletions(-) diff --git a/source-code/data/plugins/config.ini b/source-code/data/plugins/config.ini index 299d86e..3347506 100644 --- a/source-code/data/plugins/config.ini +++ b/source-code/data/plugins/config.ini @@ -78,8 +78,6 @@ No_Timer_Sprite=1 Unlock_Pseudo=0 #Enable the card menu (incomplete, it doesn't bypass the card prompt) Card=0 -#Allow using a real arcade slider attached to COM11 -Hardware_Slider=0 #Enable custom patches Custom_Patches=1 #Prevent data deletion diff --git a/source-code/data/plugins/keyconfig.ini b/source-code/data/plugins/keyconfig.ini index 70fa507..5c204dd 100644 --- a/source-code/data/plugins/keyconfig.ini +++ b/source-code/data/plugins/keyconfig.ini @@ -24,6 +24,14 @@ rumble =true # Pause when focus is lost autopause =true +# allow using slider in menus +# (recommended to disable this and remove MENU_L/R bindings if you have a real slider) +slider_in_menus =false + +# use the hardware slider from hori FT official controller +# warning: alpha untested feature, may not work +ps4_official_slider =false + # JVS Buttons: JVS_TEST = F1 JVS_SERVICE = F2 diff --git a/source-code/source/plugins/Launcher/framework.h b/source-code/source/plugins/Launcher/framework.h index a358d82..7409750 100644 --- a/source-code/source/plugins/Launcher/framework.h +++ b/source-code/source/plugins/Launcher/framework.h @@ -222,9 +222,6 @@ ConfigOptionBase* optionsArray[] = { new NumericOption(L"xinput_preferred", KEYCONFIG_SECTION, KEYCONFIG_FILE, L"XInput Controller Num:", L"Sets the preferred XInput controller.\nIf unavailable, the next connected controller is used.", 0, 0, 3), new OptionMetaSpacer(8), - new BooleanOption(L"hardware_slider", PATCHES_SECTION, CONFIG_FILE, L"Use Hardware Slider", L"Enable this if using a real arcade slider.\n(set the slider to port COM11)", false, false), - new OptionMetaSpacer(8), - new BooleanOption(L"opengl_patch_a", LAUNCHER_SECTION, CONFIG_FILE, L"OpenGL Patch A", L"Ignores some OpenGL-related errors. Don't use both patches at the same time unless you're know what you're doing.", false, false), new BooleanOption(L"opengl_patch_b", LAUNCHER_SECTION, CONFIG_FILE, L"OpenGL Patch B", L"Ignores some OpenGL-related errors. Don't use both patches at the same time unless you're know what you're doing.", false, false), new OptionMetaSpacer(8), diff --git a/source-code/source/plugins/Patches/dllmain.cpp b/source-code/source/plugins/Patches/dllmain.cpp index 00f6f70..3628161 100644 --- a/source-code/source/plugins/Patches/dllmain.cpp +++ b/source-code/source/plugins/Patches/dllmain.cpp @@ -786,12 +786,6 @@ void ApplyPatches() { { InjectCode((void*)0x0000000140565E6B, { 0x90, 0x90 }); } - // The original slider update needs to run for hardware sliders to work -- only patch it when using emulation - if (!nHardwareSlider) - { - // Don't update the touch slider state so we can write our own - InjectCode((void*)0x000000014061579B, { 0x90, 0x90, 0x90, 0x8B, 0x42, 0xE0, 0x90, 0x90, 0x90 }); - } // Quick start { if (nQuickStart == 1) // skip the card/guest screen diff --git a/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp b/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp index 9d22c6e..b6f4f73 100644 --- a/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp +++ b/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp @@ -6,6 +6,7 @@ #include "../../Input/Keyboard/Keyboard.h" #include "../../Input/Bindings/KeyboardBinding.h" #include "../../Input/KeyConfig/Config.h" +#include "../../Input/DirectInput/Ds4/DualShock4.h" #include "../../FileSystem/ConfigFile.h" #include "../../Utilities/Math.h" #include @@ -55,16 +56,22 @@ namespace TLAC::Components FileSystem::ConfigFile configFile(framework::GetModuleDirectory(), KEY_CONFIG_FILE_NAME); configFile.OpenRead(); - Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_LEFT", *LeftSideSlideLeft, { "Q" }); - Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_RIGHT", *LeftSideSlideRight, { "E" }); + usePs4OfficialSlider = configFile.GetBooleanValue("ps4_official_slider"); + enableInMenus = configFile.GetBooleanValue("slider_in_menus"); - Config::BindConfigKeys(configFile.ConfigMap, "RIGHT_SIDE_SLIDE_LEFT", *RightSideSlideLeft, { "U" }); - Config::BindConfigKeys(configFile.ConfigMap, "RIGHT_SIDE_SLIDE_RIGHT", *RightSideSlideRight, { "O" }); + if (!usePs4OfficialSlider) + { + Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_LEFT", *LeftSideSlideLeft, { "Q" }); + Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_RIGHT", *LeftSideSlideRight, { "E" }); - float touchSliderEmulationSpeed = configFile.GetFloatValue("touch_slider_emulation_speed"); - - if (touchSliderEmulationSpeed != 0.0f) - sliderSpeed = touchSliderEmulationSpeed; + Config::BindConfigKeys(configFile.ConfigMap, "RIGHT_SIDE_SLIDE_LEFT", *RightSideSlideLeft, { "U" }); + Config::BindConfigKeys(configFile.ConfigMap, "RIGHT_SIDE_SLIDE_RIGHT", *RightSideSlideRight, { "O" }); + + float touchSliderEmulationSpeed = configFile.GetFloatValue("touch_slider_emulation_speed"); + + if (touchSliderEmulationSpeed != 0.0f) + sliderSpeed = touchSliderEmulationSpeed; + } } void TouchSliderEmulator::Update() @@ -74,20 +81,46 @@ namespace TLAC::Components void TouchSliderEmulator::UpdateInput() { - if (!componentsManager->GetUpdateGameInput() || componentsManager->IsDwGuiActive() || !(*(GameState*)CURRENT_GAME_STATE_ADDRESS == GS_GAME && *(SubGameState*)CURRENT_GAME_SUB_STATE_ADDRESS == SUB_GAME_MAIN)) + if (!componentsManager->GetUpdateGameInput() || componentsManager->IsDwGuiActive() || (!enableInMenus && !(*(GameState*)CURRENT_GAME_STATE_ADDRESS == GS_GAME && *(SubGameState*)CURRENT_GAME_SUB_STATE_ADDRESS == SUB_GAME_MAIN))) return; - sliderIncrement = GetElapsedTime() / sliderSpeed; + if (usePs4OfficialSlider) + { + DualShock4* ds4 = DualShock4::GetInstance(); + if (ds4 == nullptr) + return; - constexpr float sensorStep = (1.0f / SLIDER_SENSORS); + Joystick ls = ds4->GetLeftStick(); + Joystick rs = ds4->GetRightStick(); - EmulateSliderInput(LeftSideSlideLeft, LeftSideSlideRight, ContactPoints[0], 0.0f, 0.5f); - EmulateSliderInput(RightSideSlideLeft, RightSideSlideRight, ContactPoints[1], 0.5f + sensorStep, 1.0f + sensorStep); + // test data + // normalised the same as ds4 sticks, except instead of ushort this uses bytes + // hopefully the scaling to 16 bits doesn't screw things up lol + //Joystick ls = Joystick((float)(0b10101010) / 255 * 2.0f - 1.0f, (float)(0b10000000) / 255 * 2.0f - 1.0f); + //Joystick rs = Joystick((float)(0b10000001) / 255 * 2.0f - 1.0f, (float)(0b11001100) / 255 * 2.0f - 1.0f); - sliderState->ResetSensors(); + uint32_t state = 0; + state |= (uint8_t)((ls.XAxis + 1.0) * 127.5) ^ 0b10000000; + state |= ((uint8_t)((ls.YAxis + 1.0) * 127.5) ^ 0b10000000) << 8; + state |= ((uint8_t)((rs.XAxis + 1.0) * 127.5) ^ 0b10000000) << 16; + state |= ((uint8_t)((rs.YAxis + 1.0) * 127.5) ^ 0b10000000) << 24; - for (int i = 0; i < CONTACT_POINTS; i++) - ApplyContactPoint(ContactPoints[i], i); + ApplyBitfieldState(state); + } + else + { + sliderIncrement = GetElapsedTime() / sliderSpeed; + + constexpr float sensorStep = (1.0f / SLIDER_SENSORS); + + EmulateSliderInput(LeftSideSlideLeft, LeftSideSlideRight, ContactPoints[0], 0.0f, 0.5f); + EmulateSliderInput(RightSideSlideLeft, RightSideSlideRight, ContactPoints[1], 0.5f + sensorStep, 1.0f + sensorStep); + + sliderState->ResetSensors(); + + for (int i = 0; i < CONTACT_POINTS; i++) + ApplyContactPoint(ContactPoints[i]); + } } void TouchSliderEmulator::OnFocusLost() @@ -120,23 +153,25 @@ namespace TLAC::Components contactPoint.InContact = leftDown || rightDown; } - void TouchSliderEmulator::ApplyContactPoint(ContactPoint &contactPoint, int section) + void TouchSliderEmulator::ApplyContactPoint(ContactPoint& contactPoint) { - sliderState->SectionTouched[section] = contactPoint.InContact; - - int pressure = contactPoint.InContact ? FULL_PRESSURE : NO_PRESSURE; - float position = std::clamp(contactPoint.Position, 0.0f, 1.0f); - if (contactPoint.InContact) { + float position = std::clamp(contactPoint.Position, 0.0f, 1.0f); int sensor = (int)(position * (SLIDER_SENSORS - 1)); - sliderState->SetSensor(sensor, pressure); + sliderState->SetSensor(sensor, FULL_PRESSURE); } + } - constexpr float startRange = -1.0f; - constexpr float endRange = +1.0f; - - sliderState->SectionPositions[section] = contactPoint.InContact ? (ConvertRange(0.0f, 1.0f, startRange, endRange, position)) : 0.0f; + void TouchSliderEmulator::ApplyBitfieldState(uint32_t state) + { + for (int i = 0; i < 32; i++) + { + if (state & (1 << (31 - i))) + sliderState->SetSensor(i, FULL_PRESSURE); + else + sliderState->SetSensor(i, NO_PRESSURE); + } } } \ No newline at end of file diff --git a/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.h b/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.h index d491e12..9c90b1b 100644 --- a/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.h +++ b/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.h @@ -25,6 +25,10 @@ namespace TLAC::Components Input::Binding* RightSideSlideLeft; Input::Binding* RightSideSlideRight; + bool usePs4OfficialSlider; + + bool enableInMenus; + TouchSliderEmulator(); ~TouchSliderEmulator(); @@ -53,7 +57,8 @@ namespace TLAC::Components ContactPoint ContactPoints[CONTACT_POINTS]; void EmulateSliderInput(Input::Binding *leftBinding, Input::Binding *rightBinding, ContactPoint &contactPoint, float start, float end); - void ApplyContactPoint(ContactPoint &contactPoint, int section); + void ApplyContactPoint(ContactPoint &contactPoint); + void ApplyBitfieldState(uint32_t state); }; } diff --git a/source-code/source/plugins/TLAC/Components/Input/TouchSliderState.cpp b/source-code/source/plugins/TLAC/Components/Input/TouchSliderState.cpp index 24039e2..e726ac0 100644 --- a/source-code/source/plugins/TLAC/Components/Input/TouchSliderState.cpp +++ b/source-code/source/plugins/TLAC/Components/Input/TouchSliderState.cpp @@ -7,8 +7,15 @@ namespace TLAC::Components if (index < 0 || index >= SLIDER_SENSORS) return; - SensorPressureLevels[index] = value; - SensorTouched[index].IsTouched = value > 0; + uint32_t* ph = SerialState->sliderSerialResponse.sensors[index].pressureHistory; + ph[3] = ph[2]; + ph[2] = ph[1]; + ph[1] = ph[0]; + ph[0] = value; + + SerialState->sliderSerialResponse.scanMode = 1; + SerialState->sliderSerialResponse.scanCount = 1; + SerialState->sliderResponseCnt = 1; } void TouchSliderState::ResetSensors() diff --git a/source-code/source/plugins/TLAC/Components/Input/TouchSliderState.h b/source-code/source/plugins/TLAC/Components/Input/TouchSliderState.h index 3830f9c..8aeaefb 100644 --- a/source-code/source/plugins/TLAC/Components/Input/TouchSliderState.h +++ b/source-code/source/plugins/TLAC/Components/Input/TouchSliderState.h @@ -10,9 +10,37 @@ namespace TLAC::Components { + struct TouchSliderSerialState + { + uint8_t padding[0x1960]; + + int sliderResponseCnt; + struct + { + int scanMode; + int scanCount; + struct + { + uint32_t pressureHistory[4]; // first: current, second: last sample, ... + } sensors[SLIDER_SENSORS]; + } sliderSerialResponse; + + struct + { + int scanMode; + int scanCount; + struct + { + uint32_t pressureHistory[4]; // first: current, second: last sample, ... + } sensors[SLIDER_SENSORS]; + } sliderSerialResponseCopy; // the other one is copied here by the game, feel free to ignore it + }; + struct TouchSliderState { - uint8_t Padding0000[112]; + uint8_t Padding0000[104]; + + TouchSliderSerialState* SerialState; int32_t State; From 32b160f0235989f27833a6234e4868093588b671 Mon Sep 17 00:00:00 2001 From: somewhatlurker <52014015+somewhatlurker@users.noreply.github.com> Date: Tue, 11 Aug 2020 03:20:59 +1000 Subject: [PATCH 2/6] slider emu: check serial state pointer isn't null --- .../plugins/TLAC/Components/Input/TouchSliderState.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source-code/source/plugins/TLAC/Components/Input/TouchSliderState.cpp b/source-code/source/plugins/TLAC/Components/Input/TouchSliderState.cpp index e726ac0..dbee5db 100644 --- a/source-code/source/plugins/TLAC/Components/Input/TouchSliderState.cpp +++ b/source-code/source/plugins/TLAC/Components/Input/TouchSliderState.cpp @@ -6,7 +6,10 @@ namespace TLAC::Components { if (index < 0 || index >= SLIDER_SENSORS) return; - + + if (SerialState == nullptr) + return; + uint32_t* ph = SerialState->sliderSerialResponse.sensors[index].pressureHistory; ph[3] = ph[2]; ph[2] = ph[1]; From 9e888d9a93ea667e7f4f71f4357bb4fcbdbb1df2 Mon Sep 17 00:00:00 2001 From: somewhatlurker <52014015+somewhatlurker@users.noreply.github.com> Date: Tue, 11 Aug 2020 19:38:36 +1000 Subject: [PATCH 3/6] TLAC: ps4 slider support: try to fix issues --- .../TLAC/Components/Input/TouchSliderEmulator.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp b/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp index b6f4f73..24865a9 100644 --- a/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp +++ b/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp @@ -100,10 +100,12 @@ namespace TLAC::Components //Joystick rs = Joystick((float)(0b10000001) / 255 * 2.0f - 1.0f, (float)(0b11001100) / 255 * 2.0f - 1.0f); uint32_t state = 0; - state |= (uint8_t)((ls.XAxis + 1.0) * 127.5) ^ 0b10000000; - state |= ((uint8_t)((ls.YAxis + 1.0) * 127.5) ^ 0b10000000) << 8; - state |= ((uint8_t)((rs.XAxis + 1.0) * 127.5) ^ 0b10000000) << 16; - state |= ((uint8_t)((rs.YAxis + 1.0) * 127.5) ^ 0b10000000) << 24; + state |= (uint8_t)((ls.XAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000; // 0.001 to hopefully fix zero-point (and maybe some rounding errors) + if (state == 0xffffffff) + printf("Joy neutral pos: %6.4f", ls.XAxis); + state |= ((uint8_t)((ls.YAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 8; + state |= ((uint8_t)((rs.XAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 16; + state |= ((uint8_t)((rs.YAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 24; ApplyBitfieldState(state); } From ea80ffb7e1a4bb821a13ce53899f1785d3a8ef12 Mon Sep 17 00:00:00 2001 From: somewhatlurker <52014015+somewhatlurker@users.noreply.github.com> Date: Tue, 11 Aug 2020 21:49:44 +1000 Subject: [PATCH 4/6] TLAC: ps4 slider: hopefully actually fixed now --- .../Components/Input/TouchSliderEmulator.cpp | 38 +++++++++++++------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp b/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp index 24865a9..2581547 100644 --- a/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp +++ b/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp @@ -93,19 +93,33 @@ namespace TLAC::Components Joystick ls = ds4->GetLeftStick(); Joystick rs = ds4->GetRightStick(); - // test data - // normalised the same as ds4 sticks, except instead of ushort this uses bytes - // hopefully the scaling to 16 bits doesn't screw things up lol - //Joystick ls = Joystick((float)(0b10101010) / 255 * 2.0f - 1.0f, (float)(0b10000000) / 255 * 2.0f - 1.0f); - //Joystick rs = Joystick((float)(0b10000001) / 255 * 2.0f - 1.0f, (float)(0b11001100) / 255 * 2.0f - 1.0f); - + // this looks bad because it is -- experimentally derived based on observed values + /* + 0: -1 + 63: -0.507805 + 65: -0.492210 + 126: -0.015640 + 127: -0.007828 + 128: -0.000015 + 129: 0.000015 + 130: 0.007950 + 131: 0.015885 + 192: 0.500023 + 255: 1 + */ uint32_t state = 0; - state |= (uint8_t)((ls.XAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000; // 0.001 to hopefully fix zero-point (and maybe some rounding errors) - if (state == 0xffffffff) - printf("Joy neutral pos: %6.4f", ls.XAxis); - state |= ((uint8_t)((ls.YAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 8; - state |= ((uint8_t)((rs.XAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 16; - state |= ((uint8_t)((rs.YAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 24; + uint8_t read; + //printf("left stick: %8.6f, %8.6f, ", ls.XAxis, ls.YAxis); + read = ls.XAxis < 0 ? ((ls.XAxis + 1.001) * 128) : 255 - (uint8_t)((-ls.XAxis + 1.001) * 126); + //printf("%d, ", (int)read); + state |= read ^ 0b10000000; + read = ls.YAxis < 0 ? ((ls.YAxis + 1.001) * 128) : 255 - (uint8_t)((-ls.YAxis + 1.001) * 126); + //printf("%d\n", (int)read); + state |= (read ^ 0b10000000) << 8; + read = rs.XAxis < 0 ? ((rs.XAxis + 1.001) * 128) : 255 - (uint8_t)((-rs.XAxis + 1.001) * 126); + state |= (read ^ 0b10000000) << 16; + read = rs.YAxis < 0 ? ((rs.YAxis + 1.001) * 128) : 255 - (uint8_t)((-rs.YAxis + 1.001) * 126); + state |= (read ^ 0b10000000) << 24; ApplyBitfieldState(state); } From e20d4c678166a9ec4b45211cbae00b438aaf1a8d Mon Sep 17 00:00:00 2001 From: somewhatlurker <52014015+somewhatlurker@users.noreply.github.com> Date: Wed, 12 Aug 2020 16:47:15 +1000 Subject: [PATCH 5/6] better comments for new keyconfig options --- source-code/data/plugins/keyconfig.ini | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source-code/data/plugins/keyconfig.ini b/source-code/data/plugins/keyconfig.ini index 5c204dd..64226b3 100644 --- a/source-code/data/plugins/keyconfig.ini +++ b/source-code/data/plugins/keyconfig.ini @@ -24,12 +24,14 @@ rumble =true # Pause when focus is lost autopause =true -# allow using slider in menus -# (recommended to disable this and remove MENU_L/R bindings if you have a real slider) +# Allow using slider in menus +# Recommended to enable this and remove MENU_L/R bindings if you have a real slider. +# Also needed to see slider in input test slider_in_menus =false -# use the hardware slider from hori FT official controller -# warning: alpha untested feature, may not work +# Use the hardware slider from HORI FT official controller (PS4 version) +# Warning: alpha feature, may not work properly +# Recommended to remove Ds4_L_Stick_* and Ds4_R_Stick_* from button bindings (JVS_LEFT, JVS_RIGHT, MENU_L, MENU_R). ps4_official_slider =false # JVS Buttons: From 8a5cb7595479ab7dadea2ce8eef056fac76cc2fb Mon Sep 17 00:00:00 2001 From: somewhatlurker <52014015+somewhatlurker@users.noreply.github.com> Date: Wed, 12 Aug 2020 22:34:21 +1000 Subject: [PATCH 6/6] TLAC: proper raw input for PS4 controller slider --- .../Components/Input/TouchSliderEmulator.cpp | 51 +++++++++---------- .../Input/DirectInput/DirectInputDevice.cpp | 39 ++++++++++++++ .../Input/DirectInput/DirectInputDevice.h | 2 + .../TLAC/Input/DirectInput/Ds4/DualShock4.cpp | 19 +++++++ .../TLAC/Input/DirectInput/Ds4/DualShock4.h | 7 ++- 5 files changed, 89 insertions(+), 29 deletions(-) diff --git a/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp b/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp index 2581547..29d9591 100644 --- a/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp +++ b/source-code/source/plugins/TLAC/Components/Input/TouchSliderEmulator.cpp @@ -59,8 +59,22 @@ namespace TLAC::Components usePs4OfficialSlider = configFile.GetBooleanValue("ps4_official_slider"); enableInMenus = configFile.GetBooleanValue("slider_in_menus"); - if (!usePs4OfficialSlider) + if (usePs4OfficialSlider) { + DualShock4* ds4 = DualShock4::GetInstance(); + if (ds4 == nullptr) + DualShock4::rawMode = true; // set raw mode for future instances if no current instance + else + ds4->SetRawMode(true); // if is a current instance, set raw mode on it (also sets for future instances) + } + else + { + DualShock4* ds4 = DualShock4::GetInstance(); + if (ds4 == nullptr) + DualShock4::rawMode = false; // set raw mode for future instances if no current instance + else + ds4->SetRawMode(false); // if is a current instance, set raw mode on it (also sets for future instances) + Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_LEFT", *LeftSideSlideLeft, { "Q" }); Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_RIGHT", *LeftSideSlideRight, { "E" }); @@ -93,33 +107,16 @@ namespace TLAC::Components Joystick ls = ds4->GetLeftStick(); Joystick rs = ds4->GetRightStick(); - // this looks bad because it is -- experimentally derived based on observed values - /* - 0: -1 - 63: -0.507805 - 65: -0.492210 - 126: -0.015640 - 127: -0.007828 - 128: -0.000015 - 129: 0.000015 - 130: 0.007950 - 131: 0.015885 - 192: 0.500023 - 255: 1 - */ uint32_t state = 0; - uint8_t read; - //printf("left stick: %8.6f, %8.6f, ", ls.XAxis, ls.YAxis); - read = ls.XAxis < 0 ? ((ls.XAxis + 1.001) * 128) : 255 - (uint8_t)((-ls.XAxis + 1.001) * 126); - //printf("%d, ", (int)read); - state |= read ^ 0b10000000; - read = ls.YAxis < 0 ? ((ls.YAxis + 1.001) * 128) : 255 - (uint8_t)((-ls.YAxis + 1.001) * 126); - //printf("%d\n", (int)read); - state |= (read ^ 0b10000000) << 8; - read = rs.XAxis < 0 ? ((rs.XAxis + 1.001) * 128) : 255 - (uint8_t)((-rs.XAxis + 1.001) * 126); - state |= (read ^ 0b10000000) << 16; - read = rs.YAxis < 0 ? ((rs.YAxis + 1.001) * 128) : 255 - (uint8_t)((-rs.YAxis + 1.001) * 126); - state |= (read ^ 0b10000000) << 24; + + // DualShock4 normalises sticks to floats -- this undoes that + //printf("left stick: %9.6f, %9.6f, ", ls.XAxis, ls.YAxis); + state |= (uint8_t)((ls.XAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000; // 0.001 to prevent rounding errors + //printf("%d, ", (int)(state ^ 0b10000000)); + state |= ((uint8_t)((ls.YAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 8; + //printf("%d\n", (int)((state >> 8) ^ 0b10000000)); + state |= ((uint8_t)((rs.XAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 16; + state |= ((uint8_t)((rs.YAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 24; ApplyBitfieldState(state); } diff --git a/source-code/source/plugins/TLAC/Input/DirectInput/DirectInputDevice.cpp b/source-code/source/plugins/TLAC/Input/DirectInput/DirectInputDevice.cpp index 85dbd12..385ce57 100644 --- a/source-code/source/plugins/TLAC/Input/DirectInput/DirectInputDevice.cpp +++ b/source-code/source/plugins/TLAC/Input/DirectInput/DirectInputDevice.cpp @@ -53,6 +53,45 @@ namespace TLAC::Input return result; } + HRESULT DirectInputDevice::DI_SetRange(LONG min, LONG max) + { + DIPROPRANGE propData; + propData.lMin = min; + propData.lMax = max; + + propData.diph.dwSize = sizeof(DIPROPRANGE); + propData.diph.dwHeaderSize = sizeof(DIPROPHEADER); + propData.diph.dwHow = DIPH_DEVICE; + propData.diph.dwObj = 0; + + HRESULT result = directInputdevice->SetProperty(DIPROP_RANGE, &propData.diph); + return result; + } + + HRESULT DirectInputDevice::DI_SetRawMode(BOOL raw) + { + // extra unacquire/acquire logic so this can be called on an active device + BOOL wasAcquired = DI_Unacquire() == DI_OK; + + DIPROPDWORD propData; + propData.dwData = raw ? DIPROPCALIBRATIONMODE_RAW : DIPROPCALIBRATIONMODE_COOKED; + + propData.diph.dwSize = sizeof(DIPROPDWORD); + propData.diph.dwHeaderSize = sizeof(DIPROPHEADER); + propData.diph.dwHow = DIPH_DEVICE; + propData.diph.dwObj = 0; + + HRESULT result = NULL; + + if (FAILED(result = directInputdevice->SetProperty(DIPROP_CALIBRATIONMODE, &propData.diph))) + return result; + + if (wasAcquired) + result = DI_Acquire(); + + return result; + } + void DirectInputDevice::DI_Dispose() { if (directInputdevice == nullptr) diff --git a/source-code/source/plugins/TLAC/Input/DirectInput/DirectInputDevice.h b/source-code/source/plugins/TLAC/Input/DirectInput/DirectInputDevice.h index 1579413..ff9be40 100644 --- a/source-code/source/plugins/TLAC/Input/DirectInput/DirectInputDevice.h +++ b/source-code/source/plugins/TLAC/Input/DirectInput/DirectInputDevice.h @@ -16,6 +16,8 @@ namespace TLAC::Input HRESULT DI_Release(); HRESULT DI_Poll(); HRESULT DI_GetDeviceState(DWORD size, LPVOID data); + HRESULT DI_SetRange(LONG min, LONG max); + HRESULT DI_SetRawMode(BOOL raw); void DI_Dispose(); }; diff --git a/source-code/source/plugins/TLAC/Input/DirectInput/Ds4/DualShock4.cpp b/source-code/source/plugins/TLAC/Input/DirectInput/Ds4/DualShock4.cpp index 899f56c..2755edd 100644 --- a/source-code/source/plugins/TLAC/Input/DirectInput/Ds4/DualShock4.cpp +++ b/source-code/source/plugins/TLAC/Input/DirectInput/Ds4/DualShock4.cpp @@ -6,6 +6,7 @@ namespace TLAC::Input { DualShock4* DualShock4::instance; + bool DualShock4::rawMode = false; DualShock4::DualShock4() { @@ -53,11 +54,29 @@ namespace TLAC::Input if (FAILED(result = DI_SetDataFormat(&c_dfDIJoystick2))) return false; + if (FAILED(result = DI_SetRange(0, 255))) // use 8-bit data + return false; + + // set raw mode from previous instance + if (rawMode && FAILED(result = DI_SetRawMode(true))) + return false; + result = DI_Acquire(); return true; } + bool DualShock4::SetRawMode(bool raw) + { + HRESULT result = NULL; + if (FAILED(result = DI_SetRawMode(raw))) + return false; + + rawMode = raw; + + return true; + } + bool DualShock4::PollInput() { lastState = currentState; diff --git a/source-code/source/plugins/TLAC/Input/DirectInput/Ds4/DualShock4.h b/source-code/source/plugins/TLAC/Input/DirectInput/Ds4/DualShock4.h index 8245f7e..acdf4db 100644 --- a/source-code/source/plugins/TLAC/Input/DirectInput/Ds4/DualShock4.h +++ b/source-code/source/plugins/TLAC/Input/DirectInput/Ds4/DualShock4.h @@ -31,6 +31,7 @@ namespace TLAC::Input static bool TryInitializeInstance(); bool Initialize(); + bool SetRawMode(bool raw); bool PollInput() override; bool IsDown(Ds4Button button); @@ -48,6 +49,8 @@ namespace TLAC::Input static inline DualShock4* GetInstance() { return instance; }; static inline void DeleteInstance() { delete instance; instance = nullptr; }; + static bool rawMode; // kinda dodgy, used to set raw mode for all instances without waiting for a single one + private: static DualShock4* instance; @@ -58,8 +61,8 @@ namespace TLAC::Input const float joystickThreshold = 0.5f; const float dpadThreshold = 0.5f; - inline float NormalizeTrigger(long value) { return (float)value / USHRT_MAX; }; - inline float NormalizeStick(long value) { return (float)value / USHRT_MAX * 2.0f - 1.0f; }; + inline float NormalizeTrigger(long value) { return (float)value / UCHAR_MAX; }; + inline float NormalizeStick(long value) { return (float)value / UCHAR_MAX * 2.0f - 1.0f; }; inline Joystick NormalizeStick(long x, long y) { return Joystick(NormalizeStick(x), NormalizeStick(y)); }; void UpdateInternalDs4State(Ds4State &state);