TLAC: proper raw input for PS4 controller slider
This commit is contained in:
@@ -59,8 +59,22 @@ namespace TLAC::Components
|
|||||||
usePs4OfficialSlider = configFile.GetBooleanValue("ps4_official_slider");
|
usePs4OfficialSlider = configFile.GetBooleanValue("ps4_official_slider");
|
||||||
enableInMenus = configFile.GetBooleanValue("slider_in_menus");
|
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_LEFT", *LeftSideSlideLeft, { "Q" });
|
||||||
Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_RIGHT", *LeftSideSlideRight, { "E" });
|
Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_RIGHT", *LeftSideSlideRight, { "E" });
|
||||||
|
|
||||||
@@ -93,33 +107,16 @@ namespace TLAC::Components
|
|||||||
Joystick ls = ds4->GetLeftStick();
|
Joystick ls = ds4->GetLeftStick();
|
||||||
Joystick rs = ds4->GetRightStick();
|
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;
|
uint32_t state = 0;
|
||||||
uint8_t read;
|
|
||||||
//printf("left stick: %8.6f, %8.6f, ", ls.XAxis, ls.YAxis);
|
// DualShock4 normalises sticks to floats -- this undoes that
|
||||||
read = ls.XAxis < 0 ? ((ls.XAxis + 1.001) * 128) : 255 - (uint8_t)((-ls.XAxis + 1.001) * 126);
|
//printf("left stick: %9.6f, %9.6f, ", ls.XAxis, ls.YAxis);
|
||||||
//printf("%d, ", (int)read);
|
state |= (uint8_t)((ls.XAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000; // 0.001 to prevent rounding errors
|
||||||
state |= read ^ 0b10000000;
|
//printf("%d, ", (int)(state ^ 0b10000000));
|
||||||
read = ls.YAxis < 0 ? ((ls.YAxis + 1.001) * 128) : 255 - (uint8_t)((-ls.YAxis + 1.001) * 126);
|
state |= ((uint8_t)((ls.YAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 8;
|
||||||
//printf("%d\n", (int)read);
|
//printf("%d\n", (int)((state >> 8) ^ 0b10000000));
|
||||||
state |= (read ^ 0b10000000) << 8;
|
state |= ((uint8_t)((rs.XAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 16;
|
||||||
read = rs.XAxis < 0 ? ((rs.XAxis + 1.001) * 128) : 255 - (uint8_t)((-rs.XAxis + 1.001) * 126);
|
state |= ((uint8_t)((rs.YAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 24;
|
||||||
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);
|
ApplyBitfieldState(state);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,45 @@ namespace TLAC::Input
|
|||||||
return result;
|
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()
|
void DirectInputDevice::DI_Dispose()
|
||||||
{
|
{
|
||||||
if (directInputdevice == nullptr)
|
if (directInputdevice == nullptr)
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ namespace TLAC::Input
|
|||||||
HRESULT DI_Release();
|
HRESULT DI_Release();
|
||||||
HRESULT DI_Poll();
|
HRESULT DI_Poll();
|
||||||
HRESULT DI_GetDeviceState(DWORD size, LPVOID data);
|
HRESULT DI_GetDeviceState(DWORD size, LPVOID data);
|
||||||
|
HRESULT DI_SetRange(LONG min, LONG max);
|
||||||
|
HRESULT DI_SetRawMode(BOOL raw);
|
||||||
|
|
||||||
void DI_Dispose();
|
void DI_Dispose();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
namespace TLAC::Input
|
namespace TLAC::Input
|
||||||
{
|
{
|
||||||
DualShock4* DualShock4::instance;
|
DualShock4* DualShock4::instance;
|
||||||
|
bool DualShock4::rawMode = false;
|
||||||
|
|
||||||
DualShock4::DualShock4()
|
DualShock4::DualShock4()
|
||||||
{
|
{
|
||||||
@@ -53,11 +54,29 @@ namespace TLAC::Input
|
|||||||
if (FAILED(result = DI_SetDataFormat(&c_dfDIJoystick2)))
|
if (FAILED(result = DI_SetDataFormat(&c_dfDIJoystick2)))
|
||||||
return false;
|
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();
|
result = DI_Acquire();
|
||||||
|
|
||||||
return true;
|
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()
|
bool DualShock4::PollInput()
|
||||||
{
|
{
|
||||||
lastState = currentState;
|
lastState = currentState;
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ namespace TLAC::Input
|
|||||||
static bool TryInitializeInstance();
|
static bool TryInitializeInstance();
|
||||||
|
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
|
bool SetRawMode(bool raw);
|
||||||
bool PollInput() override;
|
bool PollInput() override;
|
||||||
|
|
||||||
bool IsDown(Ds4Button button);
|
bool IsDown(Ds4Button button);
|
||||||
@@ -48,6 +49,8 @@ namespace TLAC::Input
|
|||||||
static inline DualShock4* GetInstance() { return instance; };
|
static inline DualShock4* GetInstance() { return instance; };
|
||||||
static inline void DeleteInstance() { delete instance; instance = nullptr; };
|
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:
|
private:
|
||||||
static DualShock4* instance;
|
static DualShock4* instance;
|
||||||
|
|
||||||
@@ -58,8 +61,8 @@ namespace TLAC::Input
|
|||||||
const float joystickThreshold = 0.5f;
|
const float joystickThreshold = 0.5f;
|
||||||
const float dpadThreshold = 0.5f;
|
const float dpadThreshold = 0.5f;
|
||||||
|
|
||||||
inline float NormalizeTrigger(long value) { return (float)value / USHRT_MAX; };
|
inline float NormalizeTrigger(long value) { return (float)value / UCHAR_MAX; };
|
||||||
inline float NormalizeStick(long value) { return (float)value / USHRT_MAX * 2.0f - 1.0f; };
|
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)); };
|
inline Joystick NormalizeStick(long x, long y) { return Joystick(NormalizeStick(x), NormalizeStick(y)); };
|
||||||
|
|
||||||
void UpdateInternalDs4State(Ds4State &state);
|
void UpdateInternalDs4State(Ds4State &state);
|
||||||
|
|||||||
Reference in New Issue
Block a user