diff --git a/dist/idz/segatools.ini b/dist/idz/segatools.ini index 5acb230..65ee0cb 100644 --- a/dist/idz/segatools.ini +++ b/dist/idz/segatools.ini @@ -45,6 +45,9 @@ mode=xinput ; Automatically reset the simulated shifter to Neutral when XInput Start is ; pressed (e.g. when navigating menus between races). autoNeutral=1 +; Use the left thumbstick for steering instead of both on XInput Controllers. +; Not recommended as it will not give you the precision needed for this game +singleStickSteering=0 [dinput] ; Name of the DirectInput wheel to use (or any text that occurs in its name) @@ -83,3 +86,7 @@ gear3=3 gear4=4 gear5=5 gear6=6 +; Invert the accelerator and or brake axis +; (Needed when using DirectInput for the Dualshock 4 for example) +reverseAccelAxis=0 +reverseBrakeAxis=0 \ No newline at end of file diff --git a/idzio/config.c b/idzio/config.c index 2422d1a..566c0e3 100644 --- a/idzio/config.c +++ b/idzio/config.c @@ -53,6 +53,17 @@ void idz_di_config_load(struct idz_di_config *cfg, const wchar_t *filename) cfg->shift_dn = GetPrivateProfileIntW(L"dinput", L"shiftDn", 0, filename); cfg->shift_up = GetPrivateProfileIntW(L"dinput", L"shiftUp", 0, filename); + cfg->reverse_brake_axis = GetPrivateProfileIntW( + L"dinput", + L"reverseBrakeAxis", + 0, + filename); + cfg->reverse_accel_axis = GetPrivateProfileIntW( + L"dinput", + L"reverseAccelAxis", + 0, + filename); + for (i = 0 ; i < 6 ; i++) { swprintf_s(key, _countof(key), L"gear%i", i + 1); cfg->gear[i] = GetPrivateProfileIntW(L"dinput", key, i + 1, filename); @@ -60,6 +71,18 @@ void idz_di_config_load(struct idz_di_config *cfg, const wchar_t *filename) } +void idz_xi_config_load(struct idz_xi_config *cfg, const wchar_t *filename) +{ + assert(cfg != NULL); + assert(filename != NULL); + + cfg->single_stick_steering = GetPrivateProfileIntW( + L"io3", + L"singleStickSteering", + 0, + filename); +} + void idz_io_config_load(struct idz_io_config *cfg, const wchar_t *filename) { assert(cfg != NULL); @@ -80,6 +103,7 @@ void idz_io_config_load(struct idz_io_config *cfg, const wchar_t *filename) idz_shifter_config_load(&cfg->shifter, filename); idz_di_config_load(&cfg->di, filename); + idz_xi_config_load(&cfg->xi, filename); } void idz_shifter_config_load( diff --git a/idzio/config.h b/idzio/config.h index 0c2b9f3..19b837a 100644 --- a/idzio/config.h +++ b/idzio/config.h @@ -18,6 +18,12 @@ struct idz_di_config { uint8_t shift_dn; uint8_t shift_up; uint8_t gear[6]; + bool reverse_brake_axis; + bool reverse_accel_axis; +}; + +struct idz_xi_config { + bool single_stick_steering; }; struct idz_io_config { @@ -28,9 +34,11 @@ struct idz_io_config { int restrict_; struct idz_shifter_config shifter; struct idz_di_config di; + struct idz_xi_config xi; }; void idz_di_config_load(struct idz_di_config *cfg, const wchar_t *filename); +void idz_xi_config_load(struct idz_xi_config *cfg, const wchar_t *filename); void idz_io_config_load(struct idz_io_config *cfg, const wchar_t *filename); void idz_shifter_config_load( struct idz_shifter_config *cfg, diff --git a/idzio/di.c b/idzio/di.c index 63aeba0..d8405da 100644 --- a/idzio/di.c +++ b/idzio/di.c @@ -66,6 +66,8 @@ static uint8_t idz_di_shift_up; static uint8_t idz_di_view_chg; static uint8_t idz_di_start; static uint8_t idz_di_gear[6]; +static bool idz_di_reverse_brake_axis; +static bool idz_di_reverse_accel_axis; HRESULT idz_di_init( const struct idz_di_config *cfg, @@ -265,6 +267,8 @@ static HRESULT idz_di_config_apply(const struct idz_di_config *cfg) dprintf("Wheel: View Change button : %i\n", cfg->view_chg); dprintf("Wheel: Shift Down button . : %i\n", cfg->shift_dn); dprintf("Wheel: Shift Up button . . : %i\n", cfg->shift_up); + dprintf("Wheel: Reverse Brake Axis : %i\n", cfg->reverse_brake_axis); + dprintf("Wheel: Reverse Accel Axis : %i\n", cfg->reverse_accel_axis); dprintf("Wheel: --- End configuration ---\n"); if (cfg->shifter_name[0] != L'\0') { @@ -287,6 +291,8 @@ static HRESULT idz_di_config_apply(const struct idz_di_config *cfg) idz_di_view_chg = cfg->view_chg; idz_di_shift_dn = cfg->shift_dn; idz_di_shift_up = cfg->shift_up; + idz_di_reverse_brake_axis = cfg->reverse_brake_axis; + idz_di_reverse_accel_axis = cfg->reverse_accel_axis; for (i = 0 ; i < 6 ; i++) { idz_di_gear[i] = cfg->gear[i]; @@ -501,6 +507,16 @@ static void idz_di_jvs_read_analogs(struct idz_io_analog_state *out) accel = (LONG *) &state.bytes[idz_di_off_accel]; out->wheel = state.st.lX - 32768; - out->brake = 65535 - *brake; - out->accel = 65535 - *accel; + + if (idz_di_reverse_brake_axis) { + out->brake = *brake; + } else { + out->brake = 65535 - *brake; + } + + if (idz_di_reverse_accel_axis) { + out->accel = *accel; + } else { + out->accel = 65535 - *accel; + } } diff --git a/idzio/dllmain.c b/idzio/dllmain.c index 75c7e95..79bc385 100644 --- a/idzio/dllmain.c +++ b/idzio/dllmain.c @@ -30,7 +30,7 @@ HRESULT idz_io_jvs_init(void) if (wstr_ieq(idz_io_cfg.mode, L"dinput")) { hr = idz_di_init(&idz_io_cfg.di, idz_io_hmodule, &idz_io_backend); } else if (wstr_ieq(idz_io_cfg.mode, L"xinput")) { - hr = idz_xi_init(&idz_io_backend); + hr = idz_xi_init(&idz_io_cfg.xi, &idz_io_backend); } else { hr = E_INVALIDARG; dprintf("IDZ IO: Invalid IO mode \"%S\", use dinput or xinput\n", diff --git a/idzio/xi.c b/idzio/xi.c index 526b6c5..c3d33d6 100644 --- a/idzio/xi.c +++ b/idzio/xi.c @@ -6,6 +6,7 @@ #include #include "idzio/backend.h" +#include "idzio/config.h" #include "idzio/idzio.h" #include "idzio/shifter.h" #include "idzio/xi.h" @@ -16,22 +17,45 @@ static void idz_xi_jvs_read_buttons(uint8_t *gamebtn_out); static void idz_xi_jvs_read_shifter(uint8_t *gear); static void idz_xi_jvs_read_analogs(struct idz_io_analog_state *out); +static HRESULT idz_xi_config_apply(const struct idz_xi_config *cfg); + static const struct idz_io_backend idz_xi_backend = { .jvs_read_buttons = idz_xi_jvs_read_buttons, .jvs_read_shifter = idz_xi_jvs_read_shifter, .jvs_read_analogs = idz_xi_jvs_read_analogs, }; -HRESULT idz_xi_init(const struct idz_io_backend **backend) +static bool idz_xi_single_stick_steering; + +HRESULT idz_xi_init(const struct idz_xi_config *cfg, const struct idz_io_backend **backend) { + HRESULT hr; + assert(cfg != NULL); assert(backend != NULL); + hr = idz_xi_config_apply(cfg); + + if (FAILED(hr)) { + return hr; + } + dprintf("XInput: Using XInput controller\n"); *backend = &idz_xi_backend; return S_OK; } +static HRESULT idz_xi_config_apply(const struct idz_xi_config *cfg) +{ + dprintf("XInput: --- Begin configuration ---\n"); + dprintf("XInput: Single Stick Steering : %i\n", cfg->single_stick_steering); + dprintf("XInput: --- End configuration ---\n"); + + idz_xi_single_stick_steering = cfg->single_stick_steering; + + return S_OK; +} + static void idz_xi_jvs_read_buttons(uint8_t *gamebtn_out) { uint8_t gamebtn; @@ -130,7 +154,12 @@ static void idz_xi_jvs_read_analogs(struct idz_io_analog_state *out) right = 0; } - out->wheel = (left + right) / 2; + if(idz_xi_single_stick_steering) { + out->wheel = left; + } else { + out->wheel = (left + right) / 2; + } + out->accel = xi.Gamepad.bRightTrigger << 8; out->brake = xi.Gamepad.bLeftTrigger << 8; } diff --git a/idzio/xi.h b/idzio/xi.h index 8dcb55b..5df6d67 100644 --- a/idzio/xi.h +++ b/idzio/xi.h @@ -5,5 +5,6 @@ #include #include "idzio/backend.h" +#include "idzio/config.h" -HRESULT idz_xi_init(const struct idz_io_backend **backend); +HRESULT idz_xi_init(const struct idz_xi_config *cfg, const struct idz_io_backend **backend);