idzio: Prepare for switchable backends

This commit is contained in:
Tau 2019-05-04 18:47:34 -04:00
parent 2864d22df2
commit 04189be8f0
5 changed files with 141 additions and 46 deletions

11
idzio/backend.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
#include <stdint.h>
#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);
};

77
idzio/dllmain.c Normal file
View File

@ -0,0 +1,77 @@
#include <windows.h>
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#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;
}

View File

@ -9,7 +9,10 @@ idzio_dll = shared_library(
xinput_lib, xinput_lib,
], ],
sources : [ sources : [
'idzio.c', 'backend.h',
'dllmain.c',
'idzio.h', 'idzio.h',
'xi.c',
'xi.h',
], ],
) )

View File

@ -1,43 +1,49 @@
#include <windows.h> #include <windows.h>
#include <xinput.h> #include <xinput.h>
#include <assert.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#include "idzio/backend.h"
#include "idzio/idzio.h" #include "idzio/idzio.h"
#include "idzio/xi.h"
static bool idz_io_coin; #include "util/dprintf.h"
static uint16_t idz_io_coins;
static bool idz_io_shifting;
static uint8_t idz_io_gear;
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; 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; uint8_t gamebtn;
XINPUT_STATE xi; XINPUT_STATE xi;
WORD xb; WORD xb;
opbtn = 0; assert(gamebtn_out != NULL);
gamebtn = 0; 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)); memset(&xi, 0, sizeof(xi));
XInputGetState(0, &xi); XInputGetState(0, &xi);
xb = xi.Gamepad.wButtons; 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; gamebtn |= IDZ_IO_GAMEBTN_VIEW_CHANGE;
} }
*opbtn_out = opbtn;
*gamebtn_out = gamebtn; *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_inc;
bool shift_dec; bool shift_dec;
XINPUT_STATE xi; XINPUT_STATE xi;
WORD xb; WORD xb;
assert(gear != NULL);
memset(&xi, 0, sizeof(xi)); memset(&xi, 0, sizeof(xi));
XInputGetState(0, &xi); XInputGetState(0, &xi);
xb = xi.Gamepad.wButtons; xb = xi.Gamepad.wButtons;
if (xb & XINPUT_GAMEPAD_START) { 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_inc = xb & (XINPUT_GAMEPAD_X | XINPUT_GAMEPAD_RIGHT_SHOULDER);
shift_dec = xb & (XINPUT_GAMEPAD_Y | XINPUT_GAMEPAD_LEFT_SHOULDER); shift_dec = xb & (XINPUT_GAMEPAD_Y | XINPUT_GAMEPAD_LEFT_SHOULDER);
if (!idz_io_shifting) { if (!idz_xi_shifting) {
if (shift_inc && idz_io_gear < 6) { if (shift_inc && idz_xi_gear < 6) {
idz_io_gear++; idz_xi_gear++;
} }
if (shift_dec && idz_io_gear > 0) { if (shift_dec && idz_xi_gear > 0) {
idz_io_gear--; idz_xi_gear--;
} }
} }
idz_io_shifting = shift_inc || shift_dec; idz_xi_shifting = shift_inc || shift_dec;
*gear = idz_io_gear; *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; XINPUT_STATE xi;
int left; int left;
int right; int right;
assert(out != NULL);
memset(&xi, 0, sizeof(xi)); memset(&xi, 0, sizeof(xi));
XInputGetState(0, &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->accel = xi.Gamepad.bRightTrigger << 8;
out->brake = xi.Gamepad.bLeftTrigger << 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;
}

9
idzio/xi.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
/* Can't call this xinput.h or it will conflict with <xinput.h> */
#include <windows.h>
#include "idzio/backend.h"
HRESULT idz_xi_init(const struct idz_io_backend **backend);