diff --git a/idzio/backend.h b/idzio/backend.h new file mode 100644 index 0000000..e0a958f --- /dev/null +++ b/idzio/backend.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +#include "idzio/idzio.h" + +struct idz_io_backend { + void (*jvs_read_buttons)(uint8_t *gamebtn); + void (*jvs_read_shifter)(uint8_t *gear); + void (*jvs_read_analogs)(struct idz_io_analog_state *state); +}; diff --git a/idzio/dllmain.c b/idzio/dllmain.c new file mode 100644 index 0000000..fd5240c --- /dev/null +++ b/idzio/dllmain.c @@ -0,0 +1,77 @@ +#include + +#include +#include +#include + +#include "idzio/backend.h" +#include "idzio/idzio.h" +#include "idzio/xi.h" + +static const struct idz_io_backend *idz_io_backend; +static bool idz_io_coin; +static uint16_t idz_io_coins; + +HRESULT idz_io_init(void) +{ + assert(idz_io_backend == NULL); + + return idz_xi_init(&idz_io_backend); +} + +void idz_io_jvs_read_buttons(uint8_t *opbtn_out, uint8_t *gamebtn_out) +{ + uint8_t opbtn; + + assert(idz_io_backend != NULL); + assert(opbtn_out != NULL); + assert(gamebtn_out != NULL); + + opbtn = 0; + + if (GetAsyncKeyState('1')) { + opbtn |= IDZ_IO_OPBTN_TEST; + } + + if (GetAsyncKeyState('2')) { + opbtn |= IDZ_IO_OPBTN_SERVICE; + } + + *opbtn_out = opbtn; + + idz_io_backend->jvs_read_buttons(gamebtn_out); +} + +void idz_io_jvs_read_shifter(uint8_t *gear) +{ + assert(gear != NULL); + assert(idz_io_backend != NULL); + + idz_io_backend->jvs_read_shifter(gear); +} + +void idz_io_jvs_read_analogs(struct idz_io_analog_state *state) +{ + assert(state != NULL); + assert(idz_io_backend != NULL); + + idz_io_backend->jvs_read_analogs(state); +} + +void idz_io_jvs_read_coin_counter(uint16_t *out) +{ + assert(out != NULL); + + /* Coin counter is not backend-specific */ + + if (GetAsyncKeyState('3')) { + if (!idz_io_coin) { + idz_io_coin = true; + idz_io_coins++; + } + } else { + idz_io_coin = false; + } + + *out = idz_io_coins; +} diff --git a/idzio/meson.build b/idzio/meson.build index b6306d9..80bf6c7 100644 --- a/idzio/meson.build +++ b/idzio/meson.build @@ -9,7 +9,10 @@ idzio_dll = shared_library( xinput_lib, ], sources : [ - 'idzio.c', + 'backend.h', + 'dllmain.c', 'idzio.h', + 'xi.c', + 'xi.h', ], ) diff --git a/idzio/idzio.c b/idzio/xi.c similarity index 62% rename from idzio/idzio.c rename to idzio/xi.c index 80df095..0ef8d68 100644 --- a/idzio/idzio.c +++ b/idzio/xi.c @@ -1,43 +1,49 @@ #include #include +#include #include #include +#include "idzio/backend.h" #include "idzio/idzio.h" +#include "idzio/xi.h" -static bool idz_io_coin; -static uint16_t idz_io_coins; -static bool idz_io_shifting; -static uint8_t idz_io_gear; +#include "util/dprintf.h" -HRESULT idz_io_init(void) +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 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, +}; + +static bool idz_xi_shifting; +static uint8_t idz_xi_gear; + +HRESULT idz_xi_init(const struct idz_io_backend **backend) { + assert(backend != NULL); + + dprintf("IDZ XI: Using XInput controller\n"); + *backend = &idz_xi_backend; + return S_OK; } -void idz_io_jvs_read_buttons(uint8_t *opbtn_out, uint8_t *gamebtn_out) +static void idz_xi_jvs_read_buttons(uint8_t *gamebtn_out) { - uint8_t opbtn; uint8_t gamebtn; XINPUT_STATE xi; WORD xb; - opbtn = 0; + assert(gamebtn_out != NULL); + gamebtn = 0; - /* Update test/service buttons */ - - if (GetAsyncKeyState('1')) { - opbtn |= IDZ_IO_OPBTN_TEST; - } - - if (GetAsyncKeyState('2')) { - opbtn |= IDZ_IO_OPBTN_SERVICE; - } - - /* Update gameplay buttons */ - memset(&xi, 0, sizeof(xi)); XInputGetState(0, &xi); xb = xi.Gamepad.wButtons; @@ -66,48 +72,51 @@ void idz_io_jvs_read_buttons(uint8_t *opbtn_out, uint8_t *gamebtn_out) gamebtn |= IDZ_IO_GAMEBTN_VIEW_CHANGE; } - *opbtn_out = opbtn; *gamebtn_out = gamebtn; } -void idz_io_jvs_read_shifter(uint8_t *gear) +static void idz_xi_jvs_read_shifter(uint8_t *gear) { bool shift_inc; bool shift_dec; XINPUT_STATE xi; WORD xb; + assert(gear != NULL); + memset(&xi, 0, sizeof(xi)); XInputGetState(0, &xi); xb = xi.Gamepad.wButtons; if (xb & XINPUT_GAMEPAD_START) { - idz_io_gear = 0; /* Reset to Neutral when start is pressed */ + idz_xi_gear = 0; /* Reset to Neutral when start is pressed */ } shift_inc = xb & (XINPUT_GAMEPAD_X | XINPUT_GAMEPAD_RIGHT_SHOULDER); shift_dec = xb & (XINPUT_GAMEPAD_Y | XINPUT_GAMEPAD_LEFT_SHOULDER); - if (!idz_io_shifting) { - if (shift_inc && idz_io_gear < 6) { - idz_io_gear++; + if (!idz_xi_shifting) { + if (shift_inc && idz_xi_gear < 6) { + idz_xi_gear++; } - if (shift_dec && idz_io_gear > 0) { - idz_io_gear--; + if (shift_dec && idz_xi_gear > 0) { + idz_xi_gear--; } } - idz_io_shifting = shift_inc || shift_dec; - *gear = idz_io_gear; + idz_xi_shifting = shift_inc || shift_dec; + *gear = idz_xi_gear; } -void idz_io_jvs_read_analogs(struct idz_io_analog_state *out) +static void idz_xi_jvs_read_analogs(struct idz_io_analog_state *out) { XINPUT_STATE xi; int left; int right; + assert(out != NULL); + memset(&xi, 0, sizeof(xi)); XInputGetState(0, &xi); @@ -135,17 +144,3 @@ void idz_io_jvs_read_analogs(struct idz_io_analog_state *out) out->accel = xi.Gamepad.bRightTrigger << 8; out->brake = xi.Gamepad.bLeftTrigger << 8; } - -void idz_io_jvs_read_coin_counter(uint16_t *out) -{ - if (GetAsyncKeyState('3')) { - if (!idz_io_coin) { - idz_io_coin = true; - idz_io_coins++; - } - } else { - idz_io_coin = false; - } - - *out = idz_io_coins; -} diff --git a/idzio/xi.h b/idzio/xi.h new file mode 100644 index 0000000..8dcb55b --- /dev/null +++ b/idzio/xi.h @@ -0,0 +1,9 @@ +#pragma once + +/* Can't call this xinput.h or it will conflict with */ + +#include + +#include "idzio/backend.h" + +HRESULT idz_xi_init(const struct idz_io_backend **backend);