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,
],
sources : [
'idzio.c',
'backend.h',
'dllmain.c',
'idzio.h',
'xi.c',
'xi.h',
],
)

View File

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

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);