forked from Hay1tsme/segatools
idzio: Add configuration file
This commit is contained in:
parent
a0664a4008
commit
2907c1a1b5
78
idzio/config.c
Normal file
78
idzio/config.c
Normal file
@ -0,0 +1,78 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "idzio/config.h"
|
||||
|
||||
void idz_di_config_load(struct idz_di_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"dinput",
|
||||
L"deviceName",
|
||||
L"",
|
||||
cfg->device_name,
|
||||
_countof(cfg->device_name),
|
||||
filename);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"dinput",
|
||||
L"brakeAxis",
|
||||
L"RZ",
|
||||
cfg->brake_axis,
|
||||
_countof(cfg->brake_axis),
|
||||
filename);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"dinput",
|
||||
L"accelAxis",
|
||||
L"Y",
|
||||
cfg->accel_axis,
|
||||
_countof(cfg->accel_axis),
|
||||
filename);
|
||||
|
||||
cfg->start = GetPrivateProfileIntW(L"dinput", L"start", 0, filename);
|
||||
cfg->view_chg = GetPrivateProfileIntW(L"dinput", L"viewChg", 0, filename);
|
||||
cfg->shift_dn = GetPrivateProfileIntW(L"dinput", L"shiftDn", 0, filename);
|
||||
cfg->shift_up = GetPrivateProfileIntW(L"dinput", L"shiftUp", 0, filename);
|
||||
}
|
||||
|
||||
void idz_io_config_load(struct idz_io_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->vk_test = GetPrivateProfileIntW(L"io3", L"test", '1', filename);
|
||||
cfg->vk_service = GetPrivateProfileIntW(L"io3", L"service", '2', filename);
|
||||
cfg->vk_coin = GetPrivateProfileIntW(L"io3", L"coin", '3', filename);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"io3",
|
||||
L"mode",
|
||||
L"xinput",
|
||||
cfg->mode,
|
||||
_countof(cfg->mode),
|
||||
filename);
|
||||
|
||||
idz_shifter_config_load(&cfg->shifter, filename);
|
||||
idz_di_config_load(&cfg->di, filename);
|
||||
}
|
||||
|
||||
void idz_shifter_config_load(
|
||||
struct idz_shifter_config *cfg,
|
||||
const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->auto_neutral = GetPrivateProfileIntW(
|
||||
L"io3",
|
||||
L"autoNeutral",
|
||||
0,
|
||||
filename);
|
||||
}
|
||||
|
34
idzio/config.h
Normal file
34
idzio/config.h
Normal file
@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct idz_shifter_config {
|
||||
bool auto_neutral;
|
||||
};
|
||||
|
||||
struct idz_di_config {
|
||||
wchar_t device_name[64];
|
||||
wchar_t brake_axis[16];
|
||||
wchar_t accel_axis[16];
|
||||
uint8_t start;
|
||||
uint8_t view_chg;
|
||||
uint8_t shift_dn;
|
||||
uint8_t shift_up;
|
||||
};
|
||||
|
||||
struct idz_io_config {
|
||||
uint8_t vk_test;
|
||||
uint8_t vk_service;
|
||||
uint8_t vk_coin;
|
||||
wchar_t mode[8];
|
||||
struct idz_shifter_config shifter;
|
||||
struct idz_di_config di;
|
||||
};
|
||||
|
||||
void idz_di_config_load(struct idz_di_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,
|
||||
const wchar_t *filename);
|
198
idzio/di.c
198
idzio/di.c
@ -6,20 +6,47 @@
|
||||
#include <wchar.h>
|
||||
|
||||
#include "idzio/backend.h"
|
||||
#include "idzio/config.h"
|
||||
#include "idzio/di.h"
|
||||
#include "idzio/idzio.h"
|
||||
#include "idzio/shifter.h"
|
||||
#include "idzio/wnd.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
#include "util/str.h"
|
||||
|
||||
struct idz_di_axis {
|
||||
wchar_t name[4];
|
||||
size_t off;
|
||||
};
|
||||
|
||||
union idz_di_state {
|
||||
DIJOYSTATE st;
|
||||
uint8_t bytes[sizeof(DIJOYSTATE)];
|
||||
};
|
||||
|
||||
static HRESULT idz_di_config_apply(const struct idz_di_config *cfg);
|
||||
static const struct idz_di_axis *idz_di_get_axis(const wchar_t *name);
|
||||
static BOOL idz_di_enum_callback(const DIDEVICEINSTANCEW *dev, void *ctx);
|
||||
static void idz_di_try_fx(void);
|
||||
static HRESULT idz_di_poll(DIJOYSTATE *out);
|
||||
static HRESULT idz_di_poll(union idz_di_state *state);
|
||||
static void idz_di_jvs_read_buttons(uint8_t *gamebtn_out);
|
||||
static uint8_t idz_di_decode_pov(DWORD pov);
|
||||
static void idz_di_jvs_read_shifter(uint8_t *gear);
|
||||
static void idz_di_jvs_read_analogs(struct idz_io_analog_state *out);
|
||||
|
||||
static const struct idz_di_axis idz_di_axes[] = {
|
||||
/* Just map DIJOYSTATE for now, we can map DIJOYSTATE2 later if needed */
|
||||
{ .name = L"X", .off = DIJOFS_X },
|
||||
{ .name = L"Y", .off = DIJOFS_Y },
|
||||
{ .name = L"Z", .off = DIJOFS_Z },
|
||||
{ .name = L"RX", .off = DIJOFS_RX },
|
||||
{ .name = L"RY", .off = DIJOFS_RY },
|
||||
{ .name = L"RZ", .off = DIJOFS_RZ },
|
||||
{ .name = L"U", .off = DIJOFS_SLIDER(0) },
|
||||
{ .name = L"V", .off = DIJOFS_SLIDER(1) },
|
||||
};
|
||||
|
||||
static const struct idz_io_backend idz_di_backend = {
|
||||
.jvs_read_buttons = idz_di_jvs_read_buttons,
|
||||
.jvs_read_shifter = idz_di_jvs_read_shifter,
|
||||
@ -30,8 +57,17 @@ static HWND idz_di_wnd;
|
||||
static IDirectInput8W *idz_di_api;
|
||||
static IDirectInputDevice8W *idz_di_dev;
|
||||
static IDirectInputEffect *idz_di_fx;
|
||||
static size_t idz_di_off_brake;
|
||||
static size_t idz_di_off_accel;
|
||||
static uint8_t idz_di_shift_dn;
|
||||
static uint8_t idz_di_shift_up;
|
||||
static uint8_t idz_di_view_chg;
|
||||
static uint8_t idz_di_start;
|
||||
|
||||
HRESULT idz_di_init(HINSTANCE inst, const struct idz_io_backend **backend)
|
||||
HRESULT idz_di_init(
|
||||
const struct idz_di_config *cfg,
|
||||
HINSTANCE inst,
|
||||
const struct idz_io_backend **backend)
|
||||
{
|
||||
HRESULT hr;
|
||||
HMODULE dinput8;
|
||||
@ -39,10 +75,17 @@ HRESULT idz_di_init(HINSTANCE inst, const struct idz_io_backend **backend)
|
||||
wchar_t dll_path[MAX_PATH];
|
||||
UINT path_pos;
|
||||
|
||||
assert(cfg != NULL);
|
||||
assert(backend != NULL);
|
||||
|
||||
*backend = NULL;
|
||||
|
||||
hr = idz_di_config_apply(cfg);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = idz_io_wnd_create(inst, &idz_di_wnd);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
@ -96,15 +139,21 @@ HRESULT idz_di_init(HINSTANCE inst, const struct idz_io_backend **backend)
|
||||
idz_di_api,
|
||||
DI8DEVCLASS_GAMECTRL,
|
||||
idz_di_enum_callback,
|
||||
NULL,
|
||||
(void *) cfg,
|
||||
DIEDFL_ATTACHEDONLY);
|
||||
|
||||
if (FAILED(hr) || idz_di_dev == NULL) {
|
||||
dprintf("Wheel: Could not find a controller: %08x\n", (int) hr);
|
||||
if (FAILED(hr)) {
|
||||
dprintf("Wheel: EnumDevices failed: %08x\n", (int) hr);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (idz_di_dev == NULL) {
|
||||
dprintf("Wheel: Controller not found\n");
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
hr = IDirectInputDevice8_SetCooperativeLevel(
|
||||
idz_di_dev,
|
||||
idz_di_wnd,
|
||||
@ -139,8 +188,101 @@ HRESULT idz_di_init(HINSTANCE inst, const struct idz_io_backend **backend)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT idz_di_config_apply(const struct idz_di_config *cfg)
|
||||
{
|
||||
const struct idz_di_axis *brake_axis;
|
||||
const struct idz_di_axis *accel_axis;
|
||||
|
||||
brake_axis = idz_di_get_axis(cfg->brake_axis);
|
||||
accel_axis = idz_di_get_axis(cfg->accel_axis);
|
||||
|
||||
if (brake_axis == NULL) {
|
||||
dprintf("Wheel: Invalid brake axis: %S\n", cfg->brake_axis);
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (accel_axis == NULL) {
|
||||
dprintf("Wheel: Invalid accel axis: %S\n", cfg->accel_axis);
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (cfg->start > 32) {
|
||||
dprintf("Wheel: Invalid start button: %i\n", cfg->start);
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (cfg->view_chg > 32) {
|
||||
dprintf("Wheel: Invalid view change button: %i\n", cfg->view_chg);
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (cfg->shift_dn > 32) {
|
||||
dprintf("Wheel: Invalid shift down button: %i\n", cfg->shift_dn);
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (cfg->shift_up > 32) {
|
||||
dprintf("Wheel: Invalid shift up button: %i\n", cfg->shift_up);
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
/* Print some debug output to make sure config works... */
|
||||
|
||||
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: 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);
|
||||
dprintf("Wheel: Shift Up button . . : %i\n", cfg->shift_up);
|
||||
dprintf("Wheel: --- End configuration ---\n");
|
||||
|
||||
idz_di_off_brake = accel_axis->off;
|
||||
idz_di_off_accel = brake_axis->off;
|
||||
idz_di_start = cfg->start;
|
||||
idz_di_view_chg = cfg->view_chg;
|
||||
idz_di_shift_dn = cfg->shift_dn;
|
||||
idz_di_shift_up = cfg->shift_up;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static const struct idz_di_axis *idz_di_get_axis(const wchar_t *name)
|
||||
{
|
||||
const struct idz_di_axis *axis;
|
||||
size_t i;
|
||||
|
||||
for (i = 0 ; i < _countof(idz_di_axes) ; i++) {
|
||||
axis = &idz_di_axes[i];
|
||||
|
||||
if (wstr_ieq(name, axis->name)) {
|
||||
return axis;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL idz_di_enum_callback(const DIDEVICEINSTANCEW *dev, void *ctx)
|
||||
{
|
||||
const struct idz_di_config *cfg;
|
||||
|
||||
cfg = ctx;
|
||||
|
||||
if (wcsstr(dev->tszProductName, cfg->device_name) == NULL) {
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
dprintf("Wheel: Using DirectInput device \"%S\"\n", dev->tszProductName);
|
||||
|
||||
IDirectInput8_CreateDevice(
|
||||
idz_di_api,
|
||||
&dev->guidInstance,
|
||||
@ -222,7 +364,7 @@ static void idz_di_try_fx(void)
|
||||
dprintf("Wheel: Force feedback initialized and set to zero\n");
|
||||
}
|
||||
|
||||
static HRESULT idz_di_poll(DIJOYSTATE *out)
|
||||
static HRESULT idz_di_poll(union idz_di_state *out)
|
||||
{
|
||||
HRESULT hr;
|
||||
MSG msg;
|
||||
@ -241,7 +383,10 @@ static HRESULT idz_di_poll(DIJOYSTATE *out)
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
hr = IDirectInputDevice8_GetDeviceState(idz_di_dev, sizeof(*out), out);
|
||||
hr = IDirectInputDevice8_GetDeviceState(
|
||||
idz_di_dev,
|
||||
sizeof(out->st),
|
||||
&out->st);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dprintf("Wheel: I/O error: %08x\n", (int) hr);
|
||||
@ -255,8 +400,8 @@ static HRESULT idz_di_poll(DIJOYSTATE *out)
|
||||
|
||||
static void idz_di_jvs_read_buttons(uint8_t *gamebtn_out)
|
||||
{
|
||||
union idz_di_state state;
|
||||
uint8_t gamebtn;
|
||||
DIJOYSTATE state;
|
||||
HRESULT hr;
|
||||
|
||||
assert(gamebtn_out != NULL);
|
||||
@ -267,13 +412,13 @@ static void idz_di_jvs_read_buttons(uint8_t *gamebtn_out)
|
||||
return;
|
||||
}
|
||||
|
||||
gamebtn = idz_di_decode_pov(state.rgdwPOV[0]);
|
||||
gamebtn = idz_di_decode_pov(state.st.rgdwPOV[0]);
|
||||
|
||||
if (state.rgbButtons[2]) {
|
||||
if (idz_di_start && state.st.rgbButtons[idz_di_start - 1]) {
|
||||
gamebtn |= IDZ_IO_GAMEBTN_START;
|
||||
}
|
||||
|
||||
if (state.rgbButtons[9]) {
|
||||
if (idz_di_view_chg && state.st.rgbButtons[idz_di_view_chg - 1]) {
|
||||
gamebtn |= IDZ_IO_GAMEBTN_VIEW_CHANGE;
|
||||
}
|
||||
|
||||
@ -297,7 +442,9 @@ static uint8_t idz_di_decode_pov(DWORD pov)
|
||||
|
||||
static void idz_di_jvs_read_shifter(uint8_t *gear)
|
||||
{
|
||||
DIJOYSTATE state;
|
||||
union idz_di_state state;
|
||||
bool shift_dn;
|
||||
bool shift_up;
|
||||
HRESULT hr;
|
||||
|
||||
assert(gear != NULL);
|
||||
@ -308,18 +455,28 @@ static void idz_di_jvs_read_shifter(uint8_t *gear)
|
||||
return;
|
||||
}
|
||||
|
||||
if (state.rgbButtons[2]) {
|
||||
idz_shifter_reset();
|
||||
if (idz_di_shift_dn) {
|
||||
shift_dn = state.st.rgbButtons[idz_di_shift_dn - 1];
|
||||
} else {
|
||||
shift_dn = false;
|
||||
}
|
||||
|
||||
idz_shifter_update(state.rgbButtons[0], state.rgbButtons[1]);
|
||||
if (idz_di_shift_up) {
|
||||
shift_up = state.st.rgbButtons[idz_di_shift_up - 1];
|
||||
} else {
|
||||
shift_up = false;
|
||||
}
|
||||
|
||||
idz_shifter_update(shift_dn, shift_up);
|
||||
|
||||
*gear = idz_shifter_current_gear();
|
||||
}
|
||||
|
||||
static void idz_di_jvs_read_analogs(struct idz_io_analog_state *out)
|
||||
{
|
||||
DIJOYSTATE state;
|
||||
union idz_di_state state;
|
||||
const LONG *brake;
|
||||
const LONG *accel;
|
||||
HRESULT hr;
|
||||
|
||||
assert(out != NULL);
|
||||
@ -330,7 +487,10 @@ static void idz_di_jvs_read_analogs(struct idz_io_analog_state *out)
|
||||
return;
|
||||
}
|
||||
|
||||
out->wheel = state.lX - 32768;
|
||||
out->accel = 65535 - state.lRz;
|
||||
out->brake = 65535 - state.lY;
|
||||
brake = (LONG *) &state.bytes[idz_di_off_brake];
|
||||
accel = (LONG *) &state.bytes[idz_di_off_accel];
|
||||
|
||||
out->wheel = state.st.lX - 32768;
|
||||
out->brake = 65535 - *brake;
|
||||
out->accel = 65535 - *accel;
|
||||
}
|
||||
|
@ -1,5 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "idzio/backend.h"
|
||||
#include "idzio/config.h"
|
||||
|
||||
HRESULT idz_di_init(HINSTANCE inst, const struct idz_io_backend **backend);
|
||||
HRESULT idz_di_init(
|
||||
const struct idz_di_config *cfg,
|
||||
HINSTANCE inst,
|
||||
const struct idz_io_backend **backend);
|
||||
|
@ -5,20 +5,39 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "idzio/backend.h"
|
||||
#include "idzio/config.h"
|
||||
#include "idzio/di.h"
|
||||
#include "idzio/idzio.h"
|
||||
#include "idzio/xi.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
#include "util/str.h"
|
||||
|
||||
static HMODULE idz_io_hmodule;
|
||||
static struct idz_io_config idz_io_cfg;
|
||||
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)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
assert(idz_io_backend == NULL);
|
||||
|
||||
return idz_di_init(idz_io_hmodule, &idz_io_backend);
|
||||
idz_io_config_load(&idz_io_cfg, L".\\segatools.ini");
|
||||
|
||||
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);
|
||||
} else {
|
||||
hr = E_INVALIDARG;
|
||||
dprintf("IDZ IO: Invalid IO mode \"%S\", use dinput or xinput\n",
|
||||
idz_io_cfg.mode);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
void idz_io_jvs_read_buttons(uint8_t *opbtn_out, uint8_t *gamebtn_out)
|
||||
@ -31,11 +50,13 @@ void idz_io_jvs_read_buttons(uint8_t *opbtn_out, uint8_t *gamebtn_out)
|
||||
|
||||
opbtn = 0;
|
||||
|
||||
if (GetAsyncKeyState('1')) {
|
||||
if ( idz_io_cfg.vk_test &&
|
||||
(GetAsyncKeyState(idz_io_cfg.vk_test) & 0x8000)) {
|
||||
opbtn |= IDZ_IO_OPBTN_TEST;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState('2')) {
|
||||
if ( idz_io_cfg.vk_service &&
|
||||
(GetAsyncKeyState(idz_io_cfg.vk_service) & 0x8000)) {
|
||||
opbtn |= IDZ_IO_OPBTN_SERVICE;
|
||||
}
|
||||
|
||||
@ -66,7 +87,8 @@ void idz_io_jvs_read_coin_counter(uint16_t *out)
|
||||
|
||||
/* Coin counter is not backend-specific */
|
||||
|
||||
if (GetAsyncKeyState('3')) {
|
||||
if ( idz_io_cfg.vk_coin &&
|
||||
(GetAsyncKeyState(idz_io_cfg.vk_coin) & 0x8000)) {
|
||||
if (!idz_io_coin) {
|
||||
idz_io_coin = true;
|
||||
idz_io_coins++;
|
||||
|
@ -15,6 +15,8 @@ idzio_dll = shared_library(
|
||||
],
|
||||
sources : [
|
||||
'backend.h',
|
||||
'config.c',
|
||||
'config.h',
|
||||
'di.c',
|
||||
'di.h',
|
||||
'dllmain.c',
|
||||
|
Loading…
Reference in New Issue
Block a user