TLAC: revert to old style slider emulation when not using ps4 slider input
This commit is contained in:
@@ -80,6 +80,8 @@ 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 (or PS4 official FT controller)
|
||||
Hardware_Slider=0
|
||||
#Enable custom patches
|
||||
Custom_Patches=1
|
||||
#Prevent data deletion
|
||||
|
||||
@@ -30,6 +30,7 @@ autopause =true
|
||||
slider_in_menus =false
|
||||
|
||||
# Use the hardware slider from HORI FT official controller (PS4 version)
|
||||
# Requires enabling hardware slider support.
|
||||
# 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
|
||||
|
||||
@@ -223,6 +223,9 @@ 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),
|
||||
|
||||
@@ -787,6 +787,12 @@ 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
|
||||
|
||||
@@ -129,18 +129,22 @@ namespace TLAC::Components
|
||||
EmulateSliderInput(LeftSideSlideLeft, LeftSideSlideRight, ContactPoints[0], 0.0f, 0.5f);
|
||||
EmulateSliderInput(RightSideSlideLeft, RightSideSlideRight, ContactPoints[1], 0.5f + sensorStep, 1.0f + sensorStep);
|
||||
|
||||
sliderState->ResetSensors();
|
||||
sliderState->ResetSensors(TouchSliderState::SENSOR_SET_MODE_SECTIONS);
|
||||
|
||||
for (int i = 0; i < CONTACT_POINTS; i++)
|
||||
ApplyContactPoint(ContactPoints[i]);
|
||||
ApplyContactPoint(ContactPoints[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
void TouchSliderEmulator::OnFocusLost()
|
||||
{
|
||||
sliderState->ResetSensors();
|
||||
if (usePs4OfficialSlider)
|
||||
sliderState->ResetSensors(TouchSliderState::SENSOR_SET_MODE_RAW);
|
||||
else
|
||||
sliderState->ResetSensors(TouchSliderState::SENSOR_SET_MODE_SECTIONS);
|
||||
}
|
||||
|
||||
// EmulateSliderInput and ApplyContactPoint are used for analog stick/button slider emulation
|
||||
void TouchSliderEmulator::EmulateSliderInput(Binding *leftBinding, Binding *rightBinding, ContactPoint &contactPoint, float start, float end)
|
||||
{
|
||||
bool leftDown = leftBinding->AnyDown();
|
||||
@@ -166,25 +170,35 @@ namespace TLAC::Components
|
||||
contactPoint.InContact = leftDown || rightDown;
|
||||
}
|
||||
|
||||
void TouchSliderEmulator::ApplyContactPoint(ContactPoint& contactPoint)
|
||||
void TouchSliderEmulator::ApplyContactPoint(ContactPoint& contactPoint, int section)
|
||||
{
|
||||
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, FULL_PRESSURE);
|
||||
sliderState->SetSensor(sensor, pressure, TouchSliderState::SENSOR_SET_MODE_SECTIONS);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// ApplyBitfieldState is used for setting raw slider data
|
||||
void TouchSliderEmulator::ApplyBitfieldState(uint32_t state)
|
||||
{
|
||||
for (int i = 0; i < 32; i++)
|
||||
{
|
||||
if (state & (1 << (31 - i)))
|
||||
sliderState->SetSensor(i, FULL_PRESSURE);
|
||||
sliderState->SetSensor(i, FULL_PRESSURE, TouchSliderState::SENSOR_SET_MODE_RAW);
|
||||
else
|
||||
sliderState->SetSensor(i, NO_PRESSURE);
|
||||
sliderState->SetSensor(i, NO_PRESSURE, TouchSliderState::SENSOR_SET_MODE_RAW);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,7 +57,7 @@ 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);
|
||||
void ApplyContactPoint(ContactPoint &contactPoint, int section);
|
||||
void ApplyBitfieldState(uint32_t state);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,28 +2,36 @@
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
void TouchSliderState::SetSensor(int index, int value)
|
||||
void TouchSliderState::SetSensor(int index, int value, SliderSensorSetMode mode)
|
||||
{
|
||||
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];
|
||||
ph[1] = ph[0];
|
||||
ph[0] = value;
|
||||
if (mode == SENSOR_SET_MODE_RAW)
|
||||
{
|
||||
if (SerialState == nullptr)
|
||||
return;
|
||||
|
||||
SerialState->sliderSerialResponse.scanMode = 1;
|
||||
SerialState->sliderSerialResponse.scanCount = 1;
|
||||
SerialState->sliderResponseCnt = 1;
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
SensorPressureLevels[index] = value;
|
||||
SensorTouched[index].IsTouched = value > 0;
|
||||
}
|
||||
}
|
||||
|
||||
void TouchSliderState::ResetSensors()
|
||||
void TouchSliderState::ResetSensors(SliderSensorSetMode mode)
|
||||
{
|
||||
for (int i = 0; i < SLIDER_SENSORS; i++)
|
||||
SetSensor(i, NO_PRESSURE);
|
||||
SetSensor(i, NO_PRESSURE, mode);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@
|
||||
#define NO_PRESSURE 0
|
||||
#define FULL_PRESSURE 180
|
||||
|
||||
|
||||
namespace TLAC::Components
|
||||
{
|
||||
struct TouchSliderSerialState
|
||||
@@ -64,8 +65,17 @@ namespace TLAC::Components
|
||||
uint8_t Padding[45];
|
||||
} SensorTouched[SLIDER_SENSORS];
|
||||
|
||||
void SetSensor(int index, int value);
|
||||
void ResetSensors();
|
||||
|
||||
// two different places to be set depending on operation mode now
|
||||
// stick/button based emulation directly controls sections and raw slider emulation controls fake serial inputs
|
||||
enum SliderSensorSetMode
|
||||
{
|
||||
SENSOR_SET_MODE_SECTIONS,
|
||||
SENSOR_SET_MODE_RAW
|
||||
};
|
||||
|
||||
void SetSensor(int index, int value, SliderSensorSetMode mode);
|
||||
void ResetSensors(SliderSensorSetMode mode);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -265,7 +265,8 @@ namespace TLAC::Components
|
||||
// no slider while paused
|
||||
// this is simpler than buttons because slider doesn't trigger on press, it triggers on movement
|
||||
// (therefore per-button blocking isn't needed)
|
||||
sliderState->ResetSensors();
|
||||
// SENSOR_SET_MODE_SECTIONS matches old behaviour
|
||||
sliderState->ResetSensors(TouchSliderState::SENSOR_SET_MODE_SECTIONS);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user