forked from Dniel97/segatools
idac: first segatools support
This commit is contained in:
parent
ee6675dd73
commit
da97d23b51
31
dist/idac/segatools.ini
vendored
31
dist/idac/segatools.ini
vendored
@ -13,14 +13,6 @@ appdata=
|
||||
; Note that 127.0.0.1, localhost etc are specifically rejected.
|
||||
default=127.0.0.1
|
||||
|
||||
[ds]
|
||||
; Region code on the emulated AMEX board DS EEPROM.
|
||||
; 1: Japan
|
||||
; 4: Export (some UI elements in English)
|
||||
;
|
||||
; NOTE: Changing this setting causes a factory reset.
|
||||
region=1
|
||||
|
||||
[netenv]
|
||||
; Simulate an ideal LAN environment. This may interfere with head-to-head play.
|
||||
; SEGA games are somewhat picky about their LAN environment, so leaving this
|
||||
@ -33,25 +25,24 @@ enable=1
|
||||
; that subnet must start with 192.168.
|
||||
subnet=192.168.100.0
|
||||
|
||||
[gpio]
|
||||
; Emulated Nu DIP switch for Distribution Server setting.
|
||||
;
|
||||
; If multiple machines are present on the same LAN then set this to 1 on
|
||||
; exactly one machine and set this to 0 on all others.
|
||||
dipsw1=1
|
||||
|
||||
[aimeio]
|
||||
; To use a custom card reader IO DLL enter its path here.
|
||||
; Leave empty if you want to use Segatools built-in keyboard input.
|
||||
path=
|
||||
|
||||
[idzio]
|
||||
; To use a custom Initial D Zero IO DLL enter its path here.
|
||||
[idacio]
|
||||
; To use a custom Initial D The Arcade IO DLL enter its path here.
|
||||
; Leave empty if you want to use Segatools built-in gamepad/wheel input.
|
||||
path=
|
||||
|
||||
[io3]
|
||||
; Input API selection for JVS input emulator.
|
||||
[io4]
|
||||
; Test button virtual-key code. Default is the 1 key.
|
||||
test=0x31
|
||||
; Service button virtual-key code. Default is the 2 key.
|
||||
service=0x32
|
||||
; Keyboard button to increment coin counter. Default is the 3 key.
|
||||
coin=0x33
|
||||
; Input API selection for IO4 input emulator.
|
||||
; Set "xinput" to use a gamepad and "dinput" to use a steering wheel.
|
||||
mode=xinput
|
||||
; Automatically reset the simulated shifter to Neutral when XInput Start is
|
||||
@ -59,7 +50,7 @@ mode=xinput
|
||||
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
|
||||
singleStickSteering=1
|
||||
; Adjust scaling for steering wheel input.
|
||||
;
|
||||
; This setting scales the steering wheel input so that the maximum positive
|
||||
|
6
dist/idac/start.bat
vendored
6
dist/idac/start.bat
vendored
@ -2,8 +2,10 @@
|
||||
|
||||
pushd %~dp0
|
||||
|
||||
start inject.exe -d -k idachook.dll amdaemon.exe -c config_common.json config_jp.json config_seat_1_jp.json config_seat_2_jp.json config_ex.json config_seat_1_ex.json config_seat_2_ex.json
|
||||
inject -d -k idachook.dll ../WindowsNoEditor/GameProject/Binaries/Win64/GameProject-Win64-Shipping.exe
|
||||
REM start /min inject.exe -d -k idachook.dll amdaemon.exe -f -c config_aime_high_ex.json config_aime_high_jp.json config_aime_normal_ex.json config_aime_normal_jp.json config_common.json config_ex.json config_jp.json config_laninstall_client_ex.json config_laninstall_client_jp.json config_laninstall_server_ex.json config_laninstall_server_jp.json config_seat_1_ex.json config_seat_1_jp.json config_seat_2_ex.json config_seat_2_jp.json config_seat_3_ex.json config_seat_3_jp.json config_seat_4_ex.json config_seat_4_jp.json config_seat_single_ex.json config_seat_single_jp.json
|
||||
start /min inject -d -k idachook.dll amdaemon.exe -f -c config_aime_normal_jp.json config_common.json config_jp.json config_laninstall_server_jp.json config_seat_1_jp.json
|
||||
inject -d -k idachook.dll ..\WindowsNoEditor\GameProject.exe -culture=ja launch=Cabinet ABSLOG="..\..\..\..\..\Userdata\GameProject.log" -Master -UserDir="..\..\..\Userdata" -NotInstalled -UNATTENDED
|
||||
taskkill /f /im amdaemon.exe > nul 2>&1
|
||||
|
||||
echo.
|
||||
echo Game processes have terminated
|
||||
|
@ -1,14 +1,9 @@
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "amex/amex.h"
|
||||
#include "amex/config.h"
|
||||
|
||||
#include "board/config.h"
|
||||
#include "board/sg-reader.h"
|
||||
|
||||
#include "gfxhook/config.h"
|
||||
|
||||
#include "hooklib/config.h"
|
||||
#include "hooklib/dvd.h"
|
||||
|
||||
@ -26,7 +21,7 @@ void idac_dll_config_load(
|
||||
assert(filename != NULL);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"idzio",
|
||||
L"idacio",
|
||||
L"path",
|
||||
L"",
|
||||
cfg->path,
|
||||
@ -42,12 +37,11 @@ void idac_hook_config_load(
|
||||
assert(filename != NULL);
|
||||
|
||||
platform_config_load(&cfg->platform, filename);
|
||||
amex_config_load(&cfg->amex, filename);
|
||||
aime_config_load(&cfg->aime, filename);
|
||||
dvd_config_load(&cfg->dvd, filename);
|
||||
// gfx_config_load(&cfg->gfx, filename);
|
||||
idac_dll_config_load(&cfg->dll, filename);
|
||||
zinput_config_load(&cfg->zinput, filename);
|
||||
dvd_config_load(&cfg->dvd, filename);
|
||||
io4_config_load(&cfg->io4, filename);
|
||||
}
|
||||
|
||||
void zinput_config_load(struct zinput_config *cfg, const wchar_t *filename)
|
||||
|
@ -3,11 +3,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "amex/amex.h"
|
||||
|
||||
#include "board/sg-reader.h"
|
||||
|
||||
#include "gfxhook/gfx.h"
|
||||
#include "board/config.h"
|
||||
|
||||
#include "hooklib/dvd.h"
|
||||
|
||||
@ -18,9 +14,9 @@
|
||||
|
||||
struct idac_hook_config {
|
||||
struct platform_config platform;
|
||||
struct amex_config amex;
|
||||
struct aime_config aime;
|
||||
struct dvd_config dvd;
|
||||
struct io4_config io4;
|
||||
struct idac_dll_config dll;
|
||||
struct zinput_config zinput;
|
||||
};
|
||||
|
@ -1,17 +1,11 @@
|
||||
#include <windows.h>
|
||||
#include <shlwapi.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "amex/amex.h"
|
||||
|
||||
#include "board/sg-reader.h"
|
||||
|
||||
// #include "gfxhook/d3d11.h"
|
||||
// #include "gfxhook/dxgi.h"
|
||||
// #include "gfxhook/gfx.h"
|
||||
#include "board/io4.h"
|
||||
#include "board/vfd.h"
|
||||
|
||||
#include "hook/process.h"
|
||||
|
||||
@ -21,13 +15,12 @@
|
||||
|
||||
#include "idachook/config.h"
|
||||
#include "idachook/idac-dll.h"
|
||||
#include "idachook/jvs.h"
|
||||
#include "idachook/io4.h"
|
||||
#include "idachook/zinput.h"
|
||||
|
||||
#include "platform/platform.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
#include "util/lib.h"
|
||||
|
||||
static HMODULE idac_hook_mod;
|
||||
static process_entry_t idac_startup;
|
||||
@ -35,8 +28,6 @@ static struct idac_hook_config idac_hook_cfg;
|
||||
|
||||
static DWORD CALLBACK idac_pre_startup(void)
|
||||
{
|
||||
wchar_t *module_path;
|
||||
wchar_t *file_name;
|
||||
HRESULT hr;
|
||||
|
||||
dprintf("--- Begin idac_pre_startup ---\n");
|
||||
@ -45,33 +36,9 @@ static DWORD CALLBACK idac_pre_startup(void)
|
||||
|
||||
idac_hook_config_load(&idac_hook_cfg, L".\\segatools.ini");
|
||||
|
||||
/*
|
||||
module_path = module_file_name(NULL);
|
||||
|
||||
if (module_path != NULL) {
|
||||
file_name = PathFindFileNameW(module_path);
|
||||
|
||||
_wcslwr(file_name);
|
||||
|
||||
if (wcsstr(file_name, L"serverbox") != NULL) {
|
||||
dprintf("Executable filename contains 'ServerBox', disabling full-screen mode\n");
|
||||
|
||||
idac_hook_cfg.gfx.windowed = true;
|
||||
idac_hook_cfg.gfx.framed = true;
|
||||
}
|
||||
|
||||
free(module_path);
|
||||
|
||||
module_path = NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
/* Hook Win32 APIs */
|
||||
|
||||
serial_hook_init();
|
||||
// gfx_hook_init(&idac_hook_cfg.gfx);
|
||||
// gfx_d3d11_hook_init(&idac_hook_cfg.gfx, idac_hook_mod);
|
||||
// gfx_dxgi_hook_init(&idac_hook_cfg.gfx, idac_hook_mod);
|
||||
zinput_hook_init(&idac_hook_cfg.zinput);
|
||||
dvd_hook_init(&idac_hook_cfg.dvd, idac_hook_mod);
|
||||
|
||||
@ -80,26 +47,33 @@ static DWORD CALLBACK idac_pre_startup(void)
|
||||
hr = platform_hook_init(
|
||||
&idac_hook_cfg.platform,
|
||||
"SDGT",
|
||||
"ACA2",
|
||||
"ACA4",
|
||||
idac_hook_mod);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hr = sg_reader_hook_init(&idac_hook_cfg.aime, 3, idac_hook_mod);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// Not needed?
|
||||
hr = vfd_hook_init(4);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = idac_dll_init(&idac_hook_cfg.dll, idac_hook_mod);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hr = amex_hook_init(&idac_hook_cfg.amex, idac_jvs_init);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hr = sg_reader_hook_init(&idac_hook_cfg.aime, 10, idac_hook_mod);
|
||||
hr = idac_io4_hook_init(&idac_hook_cfg.io4);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
goto fail;
|
||||
|
@ -10,20 +10,23 @@
|
||||
|
||||
const struct dll_bind_sym idac_dll_syms[] = {
|
||||
{
|
||||
.sym = "idac_io_jvs_init",
|
||||
.off = offsetof(struct idac_dll, jvs_init),
|
||||
.sym = "idac_io_init",
|
||||
.off = offsetof(struct idac_dll, init),
|
||||
}, {
|
||||
.sym = "idac_io_jvs_read_analogs",
|
||||
.off = offsetof(struct idac_dll, jvs_read_analogs),
|
||||
.sym = "idac_io_poll",
|
||||
.off = offsetof(struct idac_dll, poll),
|
||||
}, {
|
||||
.sym = "idac_io_jvs_read_buttons",
|
||||
.off = offsetof(struct idac_dll, jvs_read_buttons),
|
||||
.sym = "idac_io_get_opbtns",
|
||||
.off = offsetof(struct idac_dll, get_opbtns),
|
||||
}, {
|
||||
.sym = "idac_io_jvs_read_shifter",
|
||||
.off = offsetof(struct idac_dll, jvs_read_shifter),
|
||||
.sym = "idac_io_get_gamebtns",
|
||||
.off = offsetof(struct idac_dll, get_gamebtns),
|
||||
}, {
|
||||
.sym = "idac_io_jvs_read_coin_counter",
|
||||
.off = offsetof(struct idac_dll, jvs_read_coin_counter),
|
||||
.sym = "idac_io_get_shifter",
|
||||
.off = offsetof(struct idac_dll, get_shifter),
|
||||
}, {
|
||||
.sym = "idac_io_get_analogs",
|
||||
.off = offsetof(struct idac_dll, get_analogs),
|
||||
}
|
||||
};
|
||||
|
||||
@ -51,14 +54,14 @@ HRESULT idac_dll_init(const struct idac_dll_config *cfg, HINSTANCE self)
|
||||
|
||||
if (owned == NULL) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
dprintf("IDZ IO: Failed to load IO DLL: %lx: %S\n",
|
||||
dprintf("IDAC IO: Failed to load IO DLL: %lx: %S\n",
|
||||
hr,
|
||||
cfg->path);
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
dprintf("IDZ IO: Using custom IO DLL: %S\n", cfg->path);
|
||||
dprintf("IDAC IO: Using custom IO DLL: %S\n", cfg->path);
|
||||
src = owned;
|
||||
} else {
|
||||
owned = NULL;
|
||||
@ -78,7 +81,7 @@ HRESULT idac_dll_init(const struct idac_dll_config *cfg, HINSTANCE self)
|
||||
|
||||
if (idac_dll.api_version >= 0x0200) {
|
||||
hr = E_NOTIMPL;
|
||||
dprintf("IDZ IO: Custom IO DLL implements an unsupported "
|
||||
dprintf("IDAC IO: Custom IO DLL implements an unsupported "
|
||||
"API version (%#04x). Please update Segatools.\n",
|
||||
idac_dll.api_version);
|
||||
|
||||
@ -90,7 +93,7 @@ HRESULT idac_dll_init(const struct idac_dll_config *cfg, HINSTANCE self)
|
||||
|
||||
if (FAILED(hr)) {
|
||||
if (src != self) {
|
||||
dprintf("IDZ IO: Custom IO DLL does not provide function "
|
||||
dprintf("IDAC IO: Custom IO DLL does not provide function "
|
||||
"\"%s\". Please contact your IO DLL's developer for "
|
||||
"further assistance.\n",
|
||||
sym->sym);
|
||||
|
@ -6,11 +6,12 @@
|
||||
|
||||
struct idac_dll {
|
||||
uint16_t api_version;
|
||||
HRESULT (*jvs_init)(void);
|
||||
void (*jvs_read_analogs)(struct idac_io_analog_state *out);
|
||||
void (*jvs_read_buttons)(uint8_t *opbtn, uint8_t *gamebtn);
|
||||
void (*jvs_read_shifter)(uint8_t *gear);
|
||||
void (*jvs_read_coin_counter)(uint16_t *total);
|
||||
HRESULT (*init)(void);
|
||||
HRESULT (*poll)(void);
|
||||
void (*get_opbtns)(uint8_t *opbtn);
|
||||
void (*get_gamebtns)(uint8_t *gamebtn);
|
||||
void (*get_shifter)(uint8_t *gear);
|
||||
void (*get_analogs)(struct idac_io_analog_state *out);
|
||||
};
|
||||
|
||||
struct idac_dll_config {
|
||||
|
@ -1,24 +0,0 @@
|
||||
LIBRARY idachook
|
||||
|
||||
EXPORTS
|
||||
CreateDXGIFactory
|
||||
CreateDXGIFactory1
|
||||
CreateDXGIFactory2
|
||||
D3D11CreateDevice
|
||||
D3D11CreateDeviceAndSwapChain
|
||||
aime_io_get_api_version
|
||||
aime_io_init
|
||||
aime_io_led_set_color
|
||||
aime_io_nfc_get_aime_id
|
||||
aime_io_nfc_get_felica_id
|
||||
aime_io_nfc_poll
|
||||
amDllVideoClose @2
|
||||
amDllVideoGetVBiosVersion @4
|
||||
amDllVideoOpen @1
|
||||
amDllVideoSetResolution @3
|
||||
idac_io_get_api_version
|
||||
idac_io_jvs_init
|
||||
idac_io_jvs_read_analogs
|
||||
idac_io_jvs_read_buttons
|
||||
idac_io_jvs_read_coin_counter
|
||||
idac_io_jvs_read_shifter
|
@ -12,8 +12,9 @@ EXPORTS
|
||||
amDllVideoOpen @1
|
||||
amDllVideoSetResolution @3
|
||||
idac_io_get_api_version
|
||||
idac_io_jvs_init
|
||||
idac_io_jvs_read_analogs
|
||||
idac_io_jvs_read_buttons
|
||||
idac_io_jvs_read_coin_counter
|
||||
idac_io_jvs_read_shifter
|
||||
idac_io_init
|
||||
idac_io_poll
|
||||
idac_io_get_opbtns
|
||||
idac_io_get_gamebtns
|
||||
idac_io_get_shifter
|
||||
idac_io_get_analogs
|
||||
|
138
idachook/io4.c
Normal file
138
idachook/io4.c
Normal file
@ -0,0 +1,138 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "board/io4.h"
|
||||
|
||||
#include "idachook/idac-dll.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
static HRESULT idac_io4_poll(void *ctx, struct io4_state *state);
|
||||
static uint16_t coins;
|
||||
|
||||
static const struct io4_ops idac_io4_ops = {
|
||||
.poll = idac_io4_poll,
|
||||
};
|
||||
|
||||
static const uint16_t idac_gear_signals[] = {
|
||||
/* Neutral */
|
||||
0x0000,
|
||||
/* 1: Left|Up */
|
||||
0x0028,
|
||||
/* 2: Left|Down */
|
||||
0x0018,
|
||||
/* 3: Up */
|
||||
0x0020,
|
||||
/* 4: Down */
|
||||
0x0010,
|
||||
/* 5: Right|Up */
|
||||
0x0024,
|
||||
/* 6: Right|Down */
|
||||
0x0014,
|
||||
};
|
||||
|
||||
HRESULT idac_io4_hook_init(const struct io4_config *cfg)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
assert(idac_dll.init != NULL);
|
||||
|
||||
hr = io4_hook_init(cfg, &idac_io4_ops, NULL);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return idac_dll.init();
|
||||
}
|
||||
|
||||
static HRESULT idac_io4_poll(void *ctx, struct io4_state *state)
|
||||
{
|
||||
uint8_t opbtn;
|
||||
uint8_t gamebtn;
|
||||
uint8_t gear;
|
||||
struct idac_io_analog_state analog_state;
|
||||
HRESULT hr;
|
||||
|
||||
assert(idac_dll.poll != NULL);
|
||||
assert(idac_dll.get_opbtns != NULL);
|
||||
assert(idac_dll.get_gamebtns != NULL);
|
||||
assert(idac_dll.get_analogs != NULL);
|
||||
assert(idac_dll.get_shifter != NULL);
|
||||
|
||||
memset(state, 0, sizeof(*state));
|
||||
memset(&analog_state, 0, sizeof(analog_state));
|
||||
|
||||
hr = idac_dll.poll();
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
opbtn = 0;
|
||||
gamebtn = 0;
|
||||
gear = 0;
|
||||
|
||||
idac_dll.get_opbtns(&opbtn);
|
||||
idac_dll.get_gamebtns(&gamebtn);
|
||||
idac_dll.get_shifter(&gear);
|
||||
idac_dll.get_analogs(&analog_state);
|
||||
|
||||
if (opbtn & IDAC_IO_OPBTN_TEST) {
|
||||
state->buttons[0] |= IO4_BUTTON_TEST;
|
||||
}
|
||||
|
||||
if (opbtn & IDAC_IO_OPBTN_SERVICE) {
|
||||
state->buttons[0] |= IO4_BUTTON_SERVICE;
|
||||
}
|
||||
|
||||
if (opbtn & IDAC_IO_OPBTN_COIN) {
|
||||
coins++;
|
||||
}
|
||||
state->chutes[0] = coins << 8;
|
||||
|
||||
if (gamebtn & IDAC_IO_GAMEBTN_START) {
|
||||
state->buttons[0] |= 1 << 7;
|
||||
}
|
||||
|
||||
if (gamebtn & IDAC_IO_GAMEBTN_VIEW_CHANGE) {
|
||||
state->buttons[0] |= 1 << 1;
|
||||
}
|
||||
|
||||
if (gamebtn & IDAC_IO_GAMEBTN_UP) {
|
||||
state->buttons[0] |= 1 << 5;
|
||||
}
|
||||
|
||||
if (gamebtn & IDAC_IO_GAMEBTN_DOWN) {
|
||||
state->buttons[0] |= 1 << 4;
|
||||
}
|
||||
|
||||
if (gamebtn & IDAC_IO_GAMEBTN_LEFT) {
|
||||
state->buttons[0] |= 1 << 3;
|
||||
}
|
||||
|
||||
if (gamebtn & IDAC_IO_GAMEBTN_RIGHT) {
|
||||
state->buttons[0] |= 1 << 2;
|
||||
}
|
||||
|
||||
/* Update simulated six-speed shifter */
|
||||
|
||||
if (gear > 6) {
|
||||
gear = 6;
|
||||
}
|
||||
|
||||
state->buttons[1] = idac_gear_signals[gear];
|
||||
|
||||
/* Steering wheel increases left-to-right.
|
||||
|
||||
Use 0x8000 as the center point. */
|
||||
|
||||
state->adcs[0] = 0x8000 + analog_state.wheel;
|
||||
state->adcs[1] = analog_state.accel;
|
||||
state->adcs[2] = analog_state.brake;
|
||||
|
||||
return S_OK;
|
||||
}
|
7
idachook/io4.h
Normal file
7
idachook/io4.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "board/io4.h"
|
||||
|
||||
HRESULT idac_io4_hook_init(const struct io4_config *cfg);
|
177
idachook/jvs.c
177
idachook/jvs.c
@ -1,177 +0,0 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "amex/jvs.h"
|
||||
|
||||
#include "board/io3.h"
|
||||
|
||||
#include "idachook/idac-dll.h"
|
||||
#include "idachook/jvs.h"
|
||||
|
||||
#include "jvs/jvs-bus.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
static void idac_jvs_read_analogs(
|
||||
void *ctx,
|
||||
uint16_t *analogs,
|
||||
uint8_t nanalogs);
|
||||
static void idac_jvs_read_switches(void *ctx, struct io3_switch_state *out);
|
||||
static void idac_jvs_read_coin_counter(
|
||||
void *ctx,
|
||||
uint8_t slot_no,
|
||||
uint16_t *out);
|
||||
|
||||
static const struct io3_ops idac_jvs_io3_ops = {
|
||||
.read_switches = idac_jvs_read_switches,
|
||||
.read_analogs = idac_jvs_read_analogs,
|
||||
.read_coin_counter = idac_jvs_read_coin_counter,
|
||||
};
|
||||
|
||||
static const uint16_t idac_jvs_gear_signals[] = {
|
||||
/* Neutral */
|
||||
0x0000,
|
||||
/* 1: Left|Up */
|
||||
0x2800,
|
||||
/* 2: Left|Down */
|
||||
0x1800,
|
||||
/* 3: Up */
|
||||
0x2000,
|
||||
/* 4: Down */
|
||||
0x1000,
|
||||
/* 5: Right|Up */
|
||||
0x2400,
|
||||
/* 6: Right|Down */
|
||||
0x1400,
|
||||
};
|
||||
|
||||
static struct io3 idac_jvs_io3;
|
||||
|
||||
HRESULT idac_jvs_init(struct jvs_node **out)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
assert(out != NULL);
|
||||
assert(idac_dll.jvs_init != NULL);
|
||||
|
||||
dprintf("JVS I/O: Starting Initial D Zero backend DLL\n");
|
||||
hr = idac_dll.jvs_init();
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dprintf("JVS I/O: Backend error, I/O disconnected; %x\n", (int) hr);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
io3_init(&idac_jvs_io3, NULL, &idac_jvs_io3_ops, NULL);
|
||||
*out = io3_to_jvs_node(&idac_jvs_io3);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void idac_jvs_read_switches(void *ctx, struct io3_switch_state *out)
|
||||
{
|
||||
uint8_t opbtn;
|
||||
uint8_t gamebtn;
|
||||
uint8_t gear;
|
||||
|
||||
assert(out != NULL);
|
||||
assert(idac_dll.jvs_read_buttons != NULL);
|
||||
assert(idac_dll.jvs_read_shifter != NULL);
|
||||
|
||||
opbtn = 0;
|
||||
gamebtn = 0;
|
||||
gear = 0;
|
||||
|
||||
idac_dll.jvs_read_buttons(&opbtn, &gamebtn);
|
||||
idac_dll.jvs_read_shifter(&gear);
|
||||
|
||||
/* Update gameplay buttons */
|
||||
|
||||
if (gamebtn & IDAC_IO_GAMEBTN_UP) {
|
||||
out->p1 |= 1 << 13;
|
||||
}
|
||||
|
||||
if (gamebtn & IDAC_IO_GAMEBTN_DOWN) {
|
||||
out->p1 |= 1 << 12;
|
||||
}
|
||||
|
||||
if (gamebtn & IDAC_IO_GAMEBTN_LEFT) {
|
||||
out->p1 |= 1 << 11;
|
||||
}
|
||||
|
||||
if (gamebtn & IDAC_IO_GAMEBTN_RIGHT) {
|
||||
out->p1 |= 1 << 10;
|
||||
}
|
||||
|
||||
if (gamebtn & IDAC_IO_GAMEBTN_START) {
|
||||
out->p1 |= 1 << 15;
|
||||
}
|
||||
|
||||
if (gamebtn & IDAC_IO_GAMEBTN_VIEW_CHANGE) {
|
||||
out->p1 |= 1 << 9;
|
||||
}
|
||||
|
||||
/* Update simulated six-speed shifter */
|
||||
|
||||
if (gear > 6) {
|
||||
gear = 6;
|
||||
}
|
||||
|
||||
out->p2 = idac_jvs_gear_signals[gear];
|
||||
|
||||
/* Update test/service buttons */
|
||||
|
||||
if (opbtn & IDAC_IO_OPBTN_TEST) {
|
||||
out->system = 0x80;
|
||||
} else {
|
||||
out->system = 0;
|
||||
}
|
||||
|
||||
if (opbtn & IDAC_IO_OPBTN_SERVICE) {
|
||||
out->p1 |= 1 << 14;
|
||||
}
|
||||
}
|
||||
|
||||
static void idac_jvs_read_analogs(
|
||||
void *ctx,
|
||||
uint16_t *analogs,
|
||||
uint8_t nanalogs)
|
||||
{
|
||||
struct idac_io_analog_state state;
|
||||
|
||||
assert(analogs != NULL);
|
||||
assert(idac_dll.jvs_read_analogs != NULL);
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
idac_dll.jvs_read_analogs(&state);
|
||||
|
||||
if (nanalogs > 0) {
|
||||
analogs[0] = 0x8000 + state.wheel;
|
||||
}
|
||||
|
||||
if (nanalogs > 1) {
|
||||
analogs[1] = state.accel;
|
||||
}
|
||||
|
||||
if (nanalogs > 2) {
|
||||
analogs[2] = state.brake;
|
||||
}
|
||||
}
|
||||
|
||||
static void idac_jvs_read_coin_counter(
|
||||
void *ctx,
|
||||
uint8_t slot_no,
|
||||
uint16_t *out)
|
||||
{
|
||||
assert(idac_dll.jvs_read_coin_counter != NULL);
|
||||
|
||||
if (slot_no > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
idac_dll.jvs_read_coin_counter(out);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "jvs/jvs-bus.h"
|
||||
|
||||
HRESULT idac_jvs_init(struct jvs_node **root);
|
@ -13,12 +13,9 @@ shared_library(
|
||||
],
|
||||
link_with : [
|
||||
aimeio_lib,
|
||||
amex_lib,
|
||||
board_lib,
|
||||
# gfxhook_lib,
|
||||
hooklib_lib,
|
||||
idacio_lib,
|
||||
jvs_lib,
|
||||
platform_lib,
|
||||
util_lib,
|
||||
],
|
||||
@ -28,8 +25,8 @@ shared_library(
|
||||
'dllmain.c',
|
||||
'idac-dll.c',
|
||||
'idac-dll.h',
|
||||
'jvs.c',
|
||||
'jvs.h',
|
||||
'io4.c',
|
||||
'io4.h',
|
||||
'zinput.c',
|
||||
'zinput.h',
|
||||
],
|
||||
|
@ -5,7 +5,8 @@
|
||||
#include "idacio/idacio.h"
|
||||
|
||||
struct idac_io_backend {
|
||||
void (*jvs_read_buttons)(uint8_t *gamebtn);
|
||||
void (*jvs_read_shifter)(uint8_t *gear);
|
||||
void (*jvs_read_analogs)(struct idac_io_analog_state *state);
|
||||
void (*get_opbtns)(uint8_t *opbtn);
|
||||
void (*get_gamebtns)(uint8_t *gamebtn);
|
||||
void (*get_shifter)(uint8_t *gear);
|
||||
void (*get_analogs)(struct idac_io_analog_state *state);
|
||||
};
|
||||
|
@ -77,7 +77,7 @@ void idac_xi_config_load(struct idac_xi_config *cfg, const wchar_t *filename)
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->single_stick_steering = GetPrivateProfileIntW(
|
||||
L"io3",
|
||||
L"io4",
|
||||
L"singleStickSteering",
|
||||
0,
|
||||
filename);
|
||||
@ -88,13 +88,13 @@ void idac_io_config_load(struct idac_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);
|
||||
cfg->restrict_ = GetPrivateProfileIntW(L"io3", L"restrict", 97, filename);
|
||||
cfg->vk_test = GetPrivateProfileIntW(L"io4", L"test", '1', filename);
|
||||
cfg->vk_service = GetPrivateProfileIntW(L"io4", L"service", '2', filename);
|
||||
cfg->vk_coin = GetPrivateProfileIntW(L"io4", L"coin", '3', filename);
|
||||
cfg->restrict_ = GetPrivateProfileIntW(L"io4", L"restrict", 97, filename);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"io3",
|
||||
L"io4",
|
||||
L"mode",
|
||||
L"xinput",
|
||||
cfg->mode,
|
||||
@ -114,7 +114,7 @@ void idac_shifter_config_load(
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->auto_neutral = GetPrivateProfileIntW(
|
||||
L"io3",
|
||||
L"io4",
|
||||
L"autoNeutral",
|
||||
0,
|
||||
filename);
|
||||
|
34
idacio/di.c
34
idacio/di.c
@ -29,12 +29,12 @@ static BOOL CALLBACK idac_di_enum_callback(
|
||||
static BOOL CALLBACK idac_di_enum_callback_shifter(
|
||||
const DIDEVICEINSTANCEW *dev,
|
||||
void *ctx);
|
||||
static void idac_di_jvs_read_buttons(uint8_t *gamebtn_out);
|
||||
static void idac_di_get_buttons(uint8_t *gamebtn_out);
|
||||
static uint8_t idac_di_decode_pov(DWORD pov);
|
||||
static void idac_di_jvs_read_shifter(uint8_t *gear);
|
||||
static void idac_di_jvs_read_shifter_pos(uint8_t *gear);
|
||||
static void idac_di_jvs_read_shifter_virt(uint8_t *gear);
|
||||
static void idac_di_jvs_read_analogs(struct idac_io_analog_state *out);
|
||||
static void idac_di_get_shifter(uint8_t *gear);
|
||||
static void idac_di_get_shifter_pos(uint8_t *gear);
|
||||
static void idac_di_get_shifter_virt(uint8_t *gear);
|
||||
static void idac_di_get_analogs(struct idac_io_analog_state *out);
|
||||
|
||||
static const struct idac_di_axis idac_di_axes[] = {
|
||||
/* Just map DIJOYSTATE for now, we can map DIJOYSTATE2 later if needed */
|
||||
@ -49,9 +49,9 @@ static const struct idac_di_axis idac_di_axes[] = {
|
||||
};
|
||||
|
||||
static const struct idac_io_backend idac_di_backend = {
|
||||
.jvs_read_buttons = idac_di_jvs_read_buttons,
|
||||
.jvs_read_shifter = idac_di_jvs_read_shifter,
|
||||
.jvs_read_analogs = idac_di_jvs_read_analogs,
|
||||
.get_gamebtns = idac_di_get_buttons,
|
||||
.get_shifter = idac_di_get_shifter,
|
||||
.get_analogs = idac_di_get_analogs,
|
||||
};
|
||||
|
||||
static HWND idac_di_wnd;
|
||||
@ -98,8 +98,8 @@ HRESULT idac_di_init(
|
||||
}
|
||||
|
||||
/* Initial D Zero has some built-in DirectInput support that is not
|
||||
particularly useful. idzhook shorts this out by redirecting dinput8.dll
|
||||
to a no-op implementation of DirectInput. However, idzio does need to
|
||||
particularly useful. idachook shorts this out by redirecting dinput8.dll
|
||||
to a no-op implementation of DirectInput. However, idacio does need to
|
||||
talk to the real operating system implementation of DirectInput without
|
||||
the stub DLL interfering, so build a path to
|
||||
C:\Windows\System32\dinput.dll here. */
|
||||
@ -374,7 +374,7 @@ static BOOL CALLBACK idac_di_enum_callback_shifter(
|
||||
return DIENUM_STOP;
|
||||
}
|
||||
|
||||
static void idac_di_jvs_read_buttons(uint8_t *gamebtn_out)
|
||||
static void idac_di_get_buttons(uint8_t *gamebtn_out)
|
||||
{
|
||||
union idac_di_state state;
|
||||
uint8_t gamebtn;
|
||||
@ -416,18 +416,18 @@ static uint8_t idac_di_decode_pov(DWORD pov)
|
||||
}
|
||||
}
|
||||
|
||||
static void idac_di_jvs_read_shifter(uint8_t *gear)
|
||||
static void idac_di_get_shifter(uint8_t *gear)
|
||||
{
|
||||
assert(gear != NULL);
|
||||
|
||||
if (idac_di_shifter != NULL) {
|
||||
idac_di_jvs_read_shifter_pos(gear);
|
||||
idac_di_get_shifter_pos(gear);
|
||||
} else {
|
||||
idac_di_jvs_read_shifter_virt(gear);
|
||||
idac_di_get_shifter_virt(gear);
|
||||
}
|
||||
}
|
||||
|
||||
static void idac_di_jvs_read_shifter_pos(uint8_t *out)
|
||||
static void idac_di_get_shifter_pos(uint8_t *out)
|
||||
{
|
||||
union idac_di_state state;
|
||||
uint8_t btn_no;
|
||||
@ -457,7 +457,7 @@ static void idac_di_jvs_read_shifter_pos(uint8_t *out)
|
||||
*out = gear;
|
||||
}
|
||||
|
||||
static void idac_di_jvs_read_shifter_virt(uint8_t *gear)
|
||||
static void idac_di_get_shifter_virt(uint8_t *gear)
|
||||
{
|
||||
union idac_di_state state;
|
||||
bool shift_dn;
|
||||
@ -489,7 +489,7 @@ static void idac_di_jvs_read_shifter_virt(uint8_t *gear)
|
||||
*gear = idac_shifter_current_gear();
|
||||
}
|
||||
|
||||
static void idac_di_jvs_read_analogs(struct idac_io_analog_state *out)
|
||||
static void idac_di_get_analogs(struct idac_io_analog_state *out)
|
||||
{
|
||||
union idac_di_state state;
|
||||
const LONG *brake;
|
||||
|
@ -16,14 +16,13 @@
|
||||
static struct idac_io_config idac_io_cfg;
|
||||
static const struct idac_io_backend *idac_io_backend;
|
||||
static bool idac_io_coin;
|
||||
static uint16_t idac_io_coins;
|
||||
|
||||
uint16_t idac_io_get_api_version(void)
|
||||
{
|
||||
return 0x0100;
|
||||
}
|
||||
|
||||
HRESULT idac_io_jvs_init(void)
|
||||
HRESULT idac_io_init(void)
|
||||
{
|
||||
HINSTANCE inst;
|
||||
HRESULT hr;
|
||||
@ -47,20 +46,19 @@ HRESULT idac_io_jvs_init(void)
|
||||
hr = idac_xi_init(&idac_io_cfg.xi, &idac_io_backend);
|
||||
} else {
|
||||
hr = E_INVALIDARG;
|
||||
dprintf("IDZ IO: Invalid IO mode \"%S\", use dinput or xinput\n",
|
||||
dprintf("IDAC IO: Invalid IO mode \"%S\", use dinput or xinput\n",
|
||||
idac_io_cfg.mode);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
void idac_io_jvs_read_buttons(uint8_t *opbtn_out, uint8_t *gamebtn_out)
|
||||
void idac_io_get_opbtns(uint8_t *opbtn_out)
|
||||
{
|
||||
uint8_t opbtn;
|
||||
|
||||
assert(idac_io_backend != NULL);
|
||||
assert(opbtn_out != NULL);
|
||||
assert(gamebtn_out != NULL);
|
||||
|
||||
opbtn = 0;
|
||||
|
||||
@ -72,27 +70,43 @@ void idac_io_jvs_read_buttons(uint8_t *opbtn_out, uint8_t *gamebtn_out)
|
||||
opbtn |= IDAC_IO_OPBTN_SERVICE;
|
||||
}
|
||||
|
||||
*opbtn_out = opbtn;
|
||||
if (GetAsyncKeyState(idac_io_cfg.vk_coin) & 0x8000) {
|
||||
if (!idac_io_coin) {
|
||||
idac_io_coin = true;
|
||||
opbtn |= IDAC_IO_OPBTN_COIN;
|
||||
}
|
||||
} else {
|
||||
idac_io_coin = false;
|
||||
}
|
||||
|
||||
idac_io_backend->jvs_read_buttons(gamebtn_out);
|
||||
*opbtn_out = opbtn;
|
||||
}
|
||||
|
||||
void idac_io_jvs_read_shifter(uint8_t *gear)
|
||||
|
||||
void idac_io_get_gamebtns(uint8_t *gamebtn_out)
|
||||
{
|
||||
assert(idac_io_backend != NULL);
|
||||
assert(gamebtn_out != NULL);
|
||||
|
||||
idac_io_backend->get_gamebtns(gamebtn_out);
|
||||
}
|
||||
|
||||
void idac_io_get_shifter(uint8_t *gear)
|
||||
{
|
||||
assert(gear != NULL);
|
||||
assert(idac_io_backend != NULL);
|
||||
|
||||
idac_io_backend->jvs_read_shifter(gear);
|
||||
idac_io_backend->get_shifter(gear);
|
||||
}
|
||||
|
||||
void idac_io_jvs_read_analogs(struct idac_io_analog_state *out)
|
||||
void idac_io_get_analogs(struct idac_io_analog_state *out)
|
||||
{
|
||||
struct idac_io_analog_state tmp;
|
||||
|
||||
assert(out != NULL);
|
||||
assert(idac_io_backend != NULL);
|
||||
|
||||
idac_io_backend->jvs_read_analogs(&tmp);
|
||||
idac_io_backend->get_analogs(&tmp);
|
||||
|
||||
/* Apply steering wheel restriction. Real cabs only report about 77% of
|
||||
the IO-3's max ADC output value when the wheel is turned to either of
|
||||
@ -104,22 +118,3 @@ void idac_io_jvs_read_analogs(struct idac_io_analog_state *out)
|
||||
out->accel = tmp.accel;
|
||||
out->brake = tmp.brake;
|
||||
}
|
||||
|
||||
void idac_io_jvs_read_coin_counter(uint16_t *out)
|
||||
{
|
||||
assert(out != NULL);
|
||||
|
||||
/* Coin counter is not backend-specific */
|
||||
|
||||
if (idac_io_cfg.vk_coin &&
|
||||
(GetAsyncKeyState(idac_io_cfg.vk_coin) & 0x8000)) {
|
||||
if (!idac_io_coin) {
|
||||
idac_io_coin = true;
|
||||
idac_io_coins++;
|
||||
}
|
||||
} else {
|
||||
idac_io_coin = false;
|
||||
}
|
||||
|
||||
*out = idac_io_coins;
|
||||
}
|
||||
|
9
idacio/idacio.def
Normal file
9
idacio/idacio.def
Normal file
@ -0,0 +1,9 @@
|
||||
LIBRARY idacio
|
||||
|
||||
EXPORTS
|
||||
idac_io_init
|
||||
idac_io_poll
|
||||
idac_io_get_opbtns
|
||||
idac_io_get_gamebtns
|
||||
idac_io_get_shifter
|
||||
idac_io_get_analogs
|
@ -1,17 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
/* INITIAL D THE ARCADE CUSTOM IO API
|
||||
|
||||
This API definition allows custom driver DLLs to be defined for the
|
||||
emulation of Initial D The Arcade cabinets. To be honest, there is very
|
||||
little reason to want to do this, since driving game controllers are a
|
||||
mostly-standardized PC peripheral which can be adequately controlled by the
|
||||
built-in DirectInput and XInput support in idzhook. However, previous
|
||||
versions of Segatools broke this functionality out into a separate DLL just
|
||||
like all of the other supported games, so in the interests of maintaining
|
||||
backwards compatibility we provide the option to load custom IDZIO
|
||||
implementations as well. */
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdint.h>
|
||||
@ -19,6 +7,7 @@
|
||||
enum {
|
||||
IDAC_IO_OPBTN_TEST = 0x01,
|
||||
IDAC_IO_OPBTN_SERVICE = 0x02,
|
||||
IDAC_IO_OPBTN_COIN = 0x04,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -49,7 +38,7 @@ struct idac_io_analog_state {
|
||||
uint16_t brake;
|
||||
};
|
||||
|
||||
/* Get the version of the IDZ IO API that this DLL supports. This
|
||||
/* Get the version of the IDAC IO API that this DLL supports. This
|
||||
function should return a positive 16-bit integer, where the high byte is
|
||||
the major version and the low byte is the minor version (as defined by the
|
||||
Semantic Versioning standard).
|
||||
@ -58,33 +47,48 @@ struct idac_io_analog_state {
|
||||
|
||||
uint16_t idac_io_get_api_version(void);
|
||||
|
||||
/* Initialize JVS-based input. This function will be called before any other
|
||||
idac_io_jvs_*() function calls. Errors returned from this function will
|
||||
manifest as a disconnected JVS bus.
|
||||
/* Initialize the IO DLL. This is the second function that will be called on
|
||||
your DLL, after mu3_io_get_api_version.
|
||||
|
||||
All subsequent calls may originate from arbitrary threads and some may
|
||||
overlap with each other. Ensuring synchronization inside your IO DLL is
|
||||
your responsibility.
|
||||
All subsequent calls to this API may originate from arbitrary threads.
|
||||
|
||||
Minimum API version: 0x0100 */
|
||||
|
||||
HRESULT idac_io_jvs_init(void);
|
||||
HRESULT idac_io_init(void);
|
||||
|
||||
/* Send any queued outputs (of which there are currently none, though this may
|
||||
change in subsequent API versions) and retrieve any new inputs.
|
||||
|
||||
Minimum API version: 0x0100 */
|
||||
|
||||
HRESULT idac_io_poll(void);
|
||||
|
||||
/* Get the state of the cabinet's operator buttons as of the last poll. See
|
||||
MU3_IO_OPBTN enum above: this contains bit mask definitions for button
|
||||
states returned in *opbtn. All buttons are active-high.
|
||||
|
||||
Minimum API version: 0x0100 */
|
||||
|
||||
void idac_io_get_opbtns(uint8_t *opbtn);
|
||||
|
||||
/* Get the state of the cabinet's gameplay buttons as of the last poll. See
|
||||
MU3_IO_GAMEBTN enum above for bit mask definitions. Inputs are split into
|
||||
a left hand side set of inputs and a right hand side set of inputs: the bit
|
||||
mappings are the same in both cases.
|
||||
|
||||
All buttons are active-high, even though some buttons' electrical signals
|
||||
on a real cabinet are active-low.
|
||||
|
||||
Minimum API version: 0x0100 */
|
||||
|
||||
void idac_io_get_gamebtns(uint8_t *gamebtn);
|
||||
|
||||
/* Poll the current state of the cabinet's JVS analog inputs. See structure
|
||||
definition above for details.
|
||||
|
||||
Minimum API version: 0x0100 */
|
||||
|
||||
void idac_io_jvs_read_analogs(struct idac_io_analog_state *out);
|
||||
|
||||
/* Poll the current state of the cabinet's JVS input buttons and return them
|
||||
through the opbtn and gamebtn out parameters. See enum definitions at the
|
||||
top of this file for a list of bit masks to be used with these out
|
||||
parameters.
|
||||
|
||||
Minimum API version: 0x0100 */
|
||||
|
||||
void idac_io_jvs_read_buttons(uint8_t *opbtn, uint8_t *gamebtn);
|
||||
void idac_io_get_analogs(struct idac_io_analog_state *out);
|
||||
|
||||
/* Poll the current position of the six-speed shifter and return it via the
|
||||
gear out parameter. Valid values are 0 for neutral and 1-6 for gears 1-6.
|
||||
@ -95,12 +99,4 @@ void idac_io_jvs_read_buttons(uint8_t *opbtn, uint8_t *gamebtn);
|
||||
|
||||
Minimum API version: 0x0100 */
|
||||
|
||||
void idac_io_jvs_read_shifter(uint8_t *gear);
|
||||
|
||||
/* Read the current state of the coin counter. This value should be incremented
|
||||
for every coin detected by the coin acceptor mechanism. This count does not
|
||||
need to persist beyond the lifetime of the process.
|
||||
|
||||
Minimum API version: 0x0100 */
|
||||
|
||||
void idac_io_jvs_read_coin_counter(uint16_t *total);
|
||||
void idac_io_get_shifter(uint8_t *gear);
|
@ -1,8 +0,0 @@
|
||||
LIBRARY idacio
|
||||
|
||||
EXPORTS
|
||||
idac_io_jvs_init
|
||||
idac_io_jvs_read_analogs
|
||||
idac_io_jvs_read_buttons
|
||||
idac_io_jvs_read_coin_counter
|
||||
idac_io_jvs_read_shifter
|
@ -1,14 +1,14 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "idzio/shifter.h"
|
||||
#include "idacio/shifter.h"
|
||||
|
||||
static bool idac_shifter_shifting;
|
||||
static uint8_t idac_shifter_gear;
|
||||
|
||||
void idac_shifter_reset(void)
|
||||
void idac_shifter_set(uint8_t gear)
|
||||
{
|
||||
idac_shifter_gear = 0;
|
||||
idac_shifter_gear = gear;
|
||||
}
|
||||
|
||||
void idac_shifter_update(bool shift_dn, bool shift_up)
|
||||
|
@ -3,6 +3,6 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void idac_shifter_reset(void);
|
||||
void idac_shifter_set(uint8_t gear);
|
||||
void idac_shifter_update(bool shift_dn, bool shift_up);
|
||||
uint8_t idac_shifter_current_gear(void);
|
||||
|
@ -31,13 +31,13 @@ HRESULT idac_io_wnd_create(HINSTANCE inst, HWND *out)
|
||||
wcx.cbSize = sizeof(wcx);
|
||||
wcx.lpfnWndProc = idac_io_wnd_proc;
|
||||
wcx.hInstance = inst;
|
||||
wcx.lpszClassName = L"IDZIO";
|
||||
wcx.lpszClassName = L"IDACIO";
|
||||
|
||||
atom = RegisterClassExW(&wcx);
|
||||
|
||||
if (atom == 0) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
dprintf("IDZIO: RegisterClassExW failed: %08x\n", (int) hr);
|
||||
dprintf("IDACIO: RegisterClassExW failed: %08x\n", (int) hr);
|
||||
|
||||
goto fail;
|
||||
}
|
||||
@ -58,7 +58,7 @@ HRESULT idac_io_wnd_create(HINSTANCE inst, HWND *out)
|
||||
|
||||
if (hwnd == NULL) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
dprintf("IDZIO: CreateWindowExW failed: %08x\n", (int) hr);
|
||||
dprintf("IDACIO: CreateWindowExW failed: %08x\n", (int) hr);
|
||||
|
||||
goto fail;
|
||||
}
|
||||
|
43
idacio/xi.c
43
idacio/xi.c
@ -13,16 +13,16 @@
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
static void idac_xi_jvs_read_buttons(uint8_t *gamebtn_out);
|
||||
static void idac_xi_jvs_read_shifter(uint8_t *gear);
|
||||
static void idac_xi_jvs_read_analogs(struct idac_io_analog_state *out);
|
||||
static void idac_xi_get_gamebtns(uint8_t *gamebtn_out);
|
||||
static void idac_xi_get_shifter(uint8_t *gear);
|
||||
static void idac_xi_get_analogs(struct idac_io_analog_state *out);
|
||||
|
||||
static HRESULT idac_xi_config_apply(const struct idac_xi_config *cfg);
|
||||
|
||||
static const struct idac_io_backend idac_xi_backend = {
|
||||
.jvs_read_buttons = idac_xi_jvs_read_buttons,
|
||||
.jvs_read_shifter = idac_xi_jvs_read_shifter,
|
||||
.jvs_read_analogs = idac_xi_jvs_read_analogs,
|
||||
.get_gamebtns = idac_xi_get_gamebtns,
|
||||
.get_shifter = idac_xi_get_shifter,
|
||||
.get_analogs = idac_xi_get_analogs,
|
||||
};
|
||||
|
||||
static bool idac_xi_single_stick_steering;
|
||||
@ -45,6 +45,11 @@ HRESULT idac_xi_init(const struct idac_xi_config *cfg, const struct idac_io_back
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT idac_io_poll(void)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT idac_xi_config_apply(const struct idac_xi_config *cfg)
|
||||
{
|
||||
dprintf("XInput: --- Begin configuration ---\n");
|
||||
@ -56,7 +61,7 @@ static HRESULT idac_xi_config_apply(const struct idac_xi_config *cfg)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void idac_xi_jvs_read_buttons(uint8_t *gamebtn_out)
|
||||
static void idac_xi_get_gamebtns(uint8_t *gamebtn_out)
|
||||
{
|
||||
uint8_t gamebtn;
|
||||
XINPUT_STATE xi;
|
||||
@ -97,7 +102,7 @@ static void idac_xi_jvs_read_buttons(uint8_t *gamebtn_out)
|
||||
*gamebtn_out = gamebtn;
|
||||
}
|
||||
|
||||
static void idac_xi_jvs_read_shifter(uint8_t *gear)
|
||||
static void idac_xi_get_shifter(uint8_t *gear)
|
||||
{
|
||||
bool shift_dn;
|
||||
bool shift_up;
|
||||
@ -112,9 +117,25 @@ static void idac_xi_jvs_read_shifter(uint8_t *gear)
|
||||
|
||||
if (xb & XINPUT_GAMEPAD_START) {
|
||||
/* Reset to Neutral when start is pressed */
|
||||
idac_shifter_reset();
|
||||
idac_shifter_set(0);
|
||||
}
|
||||
|
||||
/*
|
||||
// Alternative shifting mode
|
||||
if (xb & XINPUT_GAMEPAD_X) {
|
||||
// Set to Gear 2 when X is pressed
|
||||
idac_shifter_set(2);
|
||||
}
|
||||
|
||||
if (xb & XINPUT_GAMEPAD_Y) {
|
||||
// Set to Gear 3 when Y is pressed
|
||||
idac_shifter_set(3);
|
||||
}
|
||||
|
||||
shift_dn = xb & XINPUT_GAMEPAD_LEFT_SHOULDER;
|
||||
shift_up = xb & XINPUT_GAMEPAD_RIGHT_SHOULDER;
|
||||
*/
|
||||
|
||||
shift_dn = xb & (XINPUT_GAMEPAD_Y | XINPUT_GAMEPAD_LEFT_SHOULDER);
|
||||
shift_up = xb & (XINPUT_GAMEPAD_X | XINPUT_GAMEPAD_RIGHT_SHOULDER);
|
||||
|
||||
@ -123,7 +144,7 @@ static void idac_xi_jvs_read_shifter(uint8_t *gear)
|
||||
*gear = idac_shifter_current_gear();
|
||||
}
|
||||
|
||||
static void idac_xi_jvs_read_analogs(struct idac_io_analog_state *out)
|
||||
static void idac_xi_get_analogs(struct idac_io_analog_state *out)
|
||||
{
|
||||
XINPUT_STATE xi;
|
||||
int left;
|
||||
@ -154,7 +175,7 @@ static void idac_xi_jvs_read_analogs(struct idac_io_analog_state *out)
|
||||
right = 0;
|
||||
}
|
||||
|
||||
if(idac_xi_single_stick_steering) {
|
||||
if (idac_xi_single_stick_steering) {
|
||||
out->wheel = left;
|
||||
} else {
|
||||
out->wheel = (left + right) / 2;
|
||||
|
Loading…
Reference in New Issue
Block a user