TLAC: revert to old style slider emulation when not using ps4 slider input

This commit is contained in:
somewhatlurker
2020-08-14 02:20:56 +10:00
parent 90a1c8c6ec
commit 2182d68f1d
9 changed files with 71 additions and 26 deletions
+2
View File
@@ -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
+1
View File
@@ -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
{