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;