idac: first segatools support

This commit is contained in:
2023-06-29 11:24:34 +02:00
parent ee6675dd73
commit da97d23b51
25 changed files with 351 additions and 441 deletions

View File

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

View File

@ -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;
};

View File

@ -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");
@ -44,34 +35,10 @@ static DWORD CALLBACK idac_pre_startup(void)
/* Config load */
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;
@ -109,7 +83,7 @@ static DWORD CALLBACK idac_pre_startup(void)
spike_hook_init(L".\\segatools.ini");
dprintf("--- End idac_pre_startup ---\n");
dprintf("--- End idac_pre_startup ---\n");
/* Jump to EXE start address */

View File

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

View File

@ -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 {

View File

@ -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

View File

@ -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
View 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
View File

@ -0,0 +1,7 @@
#pragma once
#include <windows.h>
#include "board/io4.h"
HRESULT idac_io4_hook_init(const struct io4_config *cfg);

View File

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

View File

@ -1,7 +0,0 @@
#pragma once
#include <windows.h>
#include "jvs/jvs-bus.h"
HRESULT idac_jvs_init(struct jvs_node **root);

View File

@ -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',
],