idac, idz, swdc: Fixed DInput brake/accel, added cubic steering

This commit is contained in:
2023-08-15 17:20:27 +02:00
parent 28ef2d719a
commit 3dc2ec6e69
17 changed files with 257 additions and 84 deletions

View File

@ -71,6 +71,12 @@ void swdc_xi_config_load(struct swdc_xi_config *cfg, const wchar_t *filename)
L"singleStickSteering",
0,
filename);
cfg->linear_steering = GetPrivateProfileIntW(
L"io4",
L"linearSteering",
0,
filename);
}
void swdc_io_config_load(struct swdc_io_config *cfg, const wchar_t *filename)

View File

@ -26,6 +26,7 @@ struct swdc_di_config {
struct swdc_xi_config {
bool single_stick_steering;
bool linear_steering;
};
struct swdc_io_config {

View File

@ -246,8 +246,8 @@ static HRESULT swdc_di_config_apply(const struct swdc_di_config *cfg)
dprintf("Wheel: --- Begin configuration ---\n");
dprintf("Wheel: Device name . . . . : Contains \"%S\"\n",
cfg->device_name);
dprintf("Wheel: Brake axis . . . . . . : %S\n", accel_axis->name);
dprintf("Wheel: Accelerator axis . . . : %S\n", brake_axis->name);
dprintf("Wheel: Brake axis . . . . . . : %S\n", brake_axis->name);
dprintf("Wheel: Accel axis . . . . . . : %S\n", accel_axis->name);
dprintf("Wheel: Start button . . . . . : %i\n", cfg->start);
dprintf("Wheel: View Change button . . : %i\n", cfg->view_chg);
dprintf("Wheel: Shift Down button . . : %i\n", cfg->shift_dn);
@ -260,8 +260,8 @@ static HRESULT swdc_di_config_apply(const struct swdc_di_config *cfg)
dprintf("Wheel: Reverse Accel Axis . . : %i\n", cfg->reverse_accel_axis);
dprintf("Wheel: --- End configuration ---\n");
swdc_di_off_brake = accel_axis->off;
swdc_di_off_accel = brake_axis->off;
swdc_di_off_brake = brake_axis->off;
swdc_di_off_accel = accel_axis->off;
swdc_di_start = cfg->start;
swdc_di_view_chg = cfg->view_chg;
swdc_di_shift_dn = cfg->shift_dn;

View File

@ -1,6 +1,7 @@
#include <windows.h>
#include <xinput.h>
#include <math.h>
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
@ -23,6 +24,7 @@ static const struct swdc_io_backend swdc_xi_backend = {
};
static bool swdc_xi_single_stick_steering;
static bool swdc_xi_linear_steering;
HRESULT swdc_xi_init(const struct swdc_xi_config *cfg, const struct swdc_io_backend **backend)
{
@ -51,9 +53,11 @@ static HRESULT swdc_xi_config_apply(const struct swdc_xi_config *cfg)
{
dprintf("XInput: --- Begin configuration ---\n");
dprintf("XInput: Single Stick Steering : %i\n", cfg->single_stick_steering);
dprintf("XInput: Linear Steering . . . : %i\n", cfg->linear_steering);
dprintf("XInput: --- End configuration ---\n");
swdc_xi_single_stick_steering = cfg->single_stick_steering;
swdc_xi_linear_steering = cfg->linear_steering;
return S_OK;
}
@ -123,6 +127,31 @@ static void swdc_xi_get_gamebtns(uint16_t *gamebtn_out)
*gamebtn_out = gamebtn;
}
static int apply_non_linear_transform(int value, int deadzone_center) {
const int max_input = 32767;
const double power_factor = 3.0;
// Apply deadzone only after passing the center threshold
if (abs(value) < deadzone_center) {
return 0;
}
// Scale the value to the range [-1.0, 1.0]
double scaled_value = (abs(value) - deadzone_center) / (double)(max_input - deadzone_center);
// Apply a non-linear transform (cubing in this case) and preserve the sign
double signed_value = copysign(pow(scaled_value, power_factor), value);
// Scale the value back to the range [-32770, 32767]
int transformed_value = (int)(signed_value * max_input);
// Clamp the value to the range [-32767, 32767]
transformed_value = (transformed_value > max_input) ? max_input : transformed_value;
transformed_value = (transformed_value < -max_input) ? -max_input : transformed_value;
return transformed_value;
}
static void swdc_xi_get_analogs(struct swdc_io_analog_state *out)
{
XINPUT_STATE xi;
@ -135,23 +164,28 @@ static void swdc_xi_get_analogs(struct swdc_io_analog_state *out)
XInputGetState(0, &xi);
left = xi.Gamepad.sThumbLX;
if (left < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
left += XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
} else if (left > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
left -= XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
} else {
left = 0;
}
right = xi.Gamepad.sThumbRX;
if (right < -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) {
right += XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE;
} else if (right > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) {
right -= XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE;
if (!swdc_xi_linear_steering) {
// Apply non-linear transform for both sticks
left = apply_non_linear_transform(left, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
right = apply_non_linear_transform(right, XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
} else {
right = 0;
if (left < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
left += XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
} else if (left > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
left -= XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
} else {
left = 0;
}
if (right < -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) {
right += XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE;
} else if (right > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) {
right -= XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE;
} else {
right = 0;
}
}
if (swdc_xi_single_stick_steering) {