forked from Dniel97/segatools
idzhook: Add initial XInput-backed IDZero hook
This commit is contained in:
parent
b550efd4a9
commit
8f8d7c6a22
75
idzhook/_com10.c
Normal file
75
idzhook/_com10.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "aimeio/aimeio.h"
|
||||||
|
|
||||||
|
#include "board/sg-led.h"
|
||||||
|
#include "board/sg-nfc.h"
|
||||||
|
#include "board/sg-reader.h"
|
||||||
|
|
||||||
|
#include "divahook/_com10.h"
|
||||||
|
|
||||||
|
#include "hook/iohook.h"
|
||||||
|
|
||||||
|
static HRESULT com10_handle_irp(struct irp *irp);
|
||||||
|
static HRESULT com10_mifare_poll(void *ctx, uint32_t *uid);
|
||||||
|
static HRESULT com10_mifare_read_luid(
|
||||||
|
void *ctx,
|
||||||
|
uint32_t uid,
|
||||||
|
uint8_t *luid,
|
||||||
|
size_t nbytes);
|
||||||
|
static void com10_led_set_color(void *ctx, uint8_t r, uint8_t g, uint8_t b);
|
||||||
|
|
||||||
|
static const struct sg_nfc_ops com10_nfc_ops = {
|
||||||
|
.mifare_poll = com10_mifare_poll,
|
||||||
|
.mifare_read_luid = com10_mifare_read_luid,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct sg_led_ops com10_led_ops = {
|
||||||
|
.set_color = com10_led_set_color,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct sg_reader com10_reader;
|
||||||
|
|
||||||
|
HRESULT com10_hook_init(void)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = aime_io_init();
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
sg_reader_init(&com10_reader, 10, &com10_nfc_ops, &com10_led_ops, NULL);
|
||||||
|
|
||||||
|
return iohook_push_handler(com10_handle_irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT com10_handle_irp(struct irp *irp)
|
||||||
|
{
|
||||||
|
assert(irp != NULL);
|
||||||
|
|
||||||
|
return sg_reader_handle_irp(&com10_reader, irp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT com10_mifare_poll(void *ctx, uint32_t *uid)
|
||||||
|
{
|
||||||
|
return aime_io_mifare_poll(0, uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT com10_mifare_read_luid(
|
||||||
|
void *ctx,
|
||||||
|
uint32_t uid,
|
||||||
|
uint8_t *luid,
|
||||||
|
size_t luid_size)
|
||||||
|
{
|
||||||
|
return aime_io_mifare_read_luid(0, uid, luid, luid_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void com10_led_set_color(void *ctx, uint8_t r, uint8_t g, uint8_t b)
|
||||||
|
{
|
||||||
|
aime_io_led_set_color(0, r, g, b);
|
||||||
|
}
|
5
idzhook/_com10.h
Normal file
5
idzhook/_com10.h
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
HRESULT com10_hook_init(void);
|
82
idzhook/dllmain.c
Normal file
82
idzhook/dllmain.c
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "amex/ds.h"
|
||||||
|
#include "amex/eeprom.h"
|
||||||
|
#include "amex/gpio.h"
|
||||||
|
#include "amex/jvs.h"
|
||||||
|
#include "amex/sram.h"
|
||||||
|
|
||||||
|
#include "hook/process.h"
|
||||||
|
|
||||||
|
#include "hooklib/serial.h"
|
||||||
|
|
||||||
|
#include "idzhook/_com10.h"
|
||||||
|
#include "idzhook/jvs.h"
|
||||||
|
|
||||||
|
#include "platform/hwmon.h"
|
||||||
|
#include "platform/nusec.h"
|
||||||
|
|
||||||
|
#include "util/clock.h"
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
#include "util/gfx.h"
|
||||||
|
#include "util/spike.h"
|
||||||
|
|
||||||
|
static process_entry_t idz_startup;
|
||||||
|
|
||||||
|
static DWORD CALLBACK idz_pre_startup(void)
|
||||||
|
{
|
||||||
|
dprintf("--- Begin idz_pre_startup ---\n");
|
||||||
|
|
||||||
|
/* Hook Win32 APIs */
|
||||||
|
|
||||||
|
clock_hook_init();
|
||||||
|
serial_hook_init();
|
||||||
|
|
||||||
|
/* Initialize platform API emulation */
|
||||||
|
|
||||||
|
hwmon_hook_init();
|
||||||
|
nusec_hook_init();
|
||||||
|
|
||||||
|
/* Initialize AMEX emulation */
|
||||||
|
|
||||||
|
ds_hook_init();
|
||||||
|
eeprom_hook_init();
|
||||||
|
gpio_hook_init();
|
||||||
|
jvs_hook_init();
|
||||||
|
sram_hook_init();
|
||||||
|
|
||||||
|
/* Initialize Initial D Zero I/O board emulation */
|
||||||
|
|
||||||
|
com10_hook_init();
|
||||||
|
idz_jvs_init();
|
||||||
|
|
||||||
|
/* Initialize debug helpers */
|
||||||
|
|
||||||
|
spike_hook_init("idzspike.txt");
|
||||||
|
|
||||||
|
dprintf("--- End idz_pre_startup ---\n");
|
||||||
|
|
||||||
|
/* Jump to EXE start address */
|
||||||
|
|
||||||
|
return idz_startup();
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI DllMain(HMODULE mod, DWORD cause, void *ctx)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (cause != DLL_PROCESS_ATTACH) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr = process_hijack_startup(idz_pre_startup, &idz_startup);
|
||||||
|
|
||||||
|
if (!SUCCEEDED(hr)) {
|
||||||
|
dprintf("Failed to hijack process startup: %x\n", (int) hr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCEEDED(hr);
|
||||||
|
}
|
1
idzhook/idzhook.def
Normal file
1
idzhook/idzhook.def
Normal file
@ -0,0 +1 @@
|
|||||||
|
LIBRARY idzhook
|
144
idzhook/jvs.c
Normal file
144
idzhook/jvs.c
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include <xinput.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "amex/jvs.h"
|
||||||
|
|
||||||
|
#include "board/io3.h"
|
||||||
|
|
||||||
|
#include "idzhook/jvs.h"
|
||||||
|
|
||||||
|
#include "jvs/jvs-bus.h"
|
||||||
|
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
|
static void idz_jvs_read_switches(void *ctx, struct io3_switch_state *out);
|
||||||
|
static uint16_t idz_jvs_read_analog(void *ctx, uint8_t analog_no);
|
||||||
|
static uint16_t idz_jvs_consume_coins(void *ctx, uint8_t slot_no);
|
||||||
|
|
||||||
|
static const struct io3_ops idz_jvs_io3_ops = {
|
||||||
|
.read_switches = idz_jvs_read_switches,
|
||||||
|
.read_analog = idz_jvs_read_analog,
|
||||||
|
.consume_coins = idz_jvs_consume_coins,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct io3 idz_jvs_io3;
|
||||||
|
static bool idz_jvs_coin;
|
||||||
|
|
||||||
|
void idz_jvs_init(void)
|
||||||
|
{
|
||||||
|
io3_init(&idz_jvs_io3, NULL, &idz_jvs_io3_ops, NULL);
|
||||||
|
jvs_attach(&idz_jvs_io3.jvs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void idz_jvs_read_switches(void *ctx, struct io3_switch_state *out)
|
||||||
|
{
|
||||||
|
XINPUT_STATE xi;
|
||||||
|
WORD xb;
|
||||||
|
|
||||||
|
assert(out != NULL);
|
||||||
|
|
||||||
|
memset(&xi, 0, sizeof(xi));
|
||||||
|
XInputGetState(0, &xi);
|
||||||
|
xb = xi.Gamepad.wButtons;
|
||||||
|
|
||||||
|
/* Update gameplay buttons (P2 JVS input is not even polled) */
|
||||||
|
|
||||||
|
if (xb & XINPUT_GAMEPAD_START) {
|
||||||
|
out->p1 |= 1 << 15;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xb & XINPUT_GAMEPAD_DPAD_UP) {
|
||||||
|
out->p1 |= 1 << 13;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xb & XINPUT_GAMEPAD_DPAD_DOWN) {
|
||||||
|
out->p1 |= 1 << 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xb & XINPUT_GAMEPAD_DPAD_LEFT) {
|
||||||
|
out->p1 |= 1 << 11;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xb & XINPUT_GAMEPAD_DPAD_RIGHT) {
|
||||||
|
out->p1 |= 1 << 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xb & XINPUT_GAMEPAD_BACK) {
|
||||||
|
out->p1 |= 1 << 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update test/service buttons */
|
||||||
|
|
||||||
|
if (GetAsyncKeyState('1')) {
|
||||||
|
out->system = 0x80;
|
||||||
|
} else {
|
||||||
|
out->system = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetAsyncKeyState('2')) {
|
||||||
|
out->p1 |= 1 << 14;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t idz_jvs_read_analog(void *ctx, uint8_t analog_no)
|
||||||
|
{
|
||||||
|
XINPUT_STATE xi;
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
if (analog_no > 2) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&xi, 0, sizeof(xi));
|
||||||
|
XInputGetState(0, &xi);
|
||||||
|
|
||||||
|
switch (analog_no) {
|
||||||
|
case 0:
|
||||||
|
/* Wheel */
|
||||||
|
tmp = xi.Gamepad.sThumbLX;
|
||||||
|
|
||||||
|
if (abs(tmp) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
|
||||||
|
return tmp + 0x8000;
|
||||||
|
} else {
|
||||||
|
return 0x8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
/* Accel */
|
||||||
|
return xi.Gamepad.bRightTrigger << 8;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
/* Brake */
|
||||||
|
return xi.Gamepad.bLeftTrigger << 8;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t idz_jvs_consume_coins(void *ctx, uint8_t slot_no)
|
||||||
|
{
|
||||||
|
if (slot_no > 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetAsyncKeyState('3')) {
|
||||||
|
if (idz_jvs_coin) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
dprintf("IDZero JVS: Coin drop\n");
|
||||||
|
idz_jvs_coin = true;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
idz_jvs_coin = false;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
3
idzhook/jvs.h
Normal file
3
idzhook/jvs.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void idz_jvs_init(void);
|
27
idzhook/meson.build
Normal file
27
idzhook/meson.build
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
shared_library(
|
||||||
|
'idzhook',
|
||||||
|
name_prefix : '',
|
||||||
|
include_directories : inc,
|
||||||
|
implicit_include_directories : false,
|
||||||
|
vs_module_defs : 'idzhook.def',
|
||||||
|
c_pch : '../precompiled.h',
|
||||||
|
dependencies : [
|
||||||
|
capnhook.get_variable('hook_dep'),
|
||||||
|
capnhook.get_variable('hooklib_dep'),
|
||||||
|
xinput_lib,
|
||||||
|
],
|
||||||
|
link_with : [
|
||||||
|
aimeio_dll,
|
||||||
|
amex_lib,
|
||||||
|
board_lib,
|
||||||
|
jvs_lib,
|
||||||
|
platform_lib,
|
||||||
|
util_lib,
|
||||||
|
],
|
||||||
|
sources : [
|
||||||
|
'_com10.c',
|
||||||
|
'dllmain.c',
|
||||||
|
'jvs.c',
|
||||||
|
'jvs.h',
|
||||||
|
],
|
||||||
|
)
|
@ -39,5 +39,6 @@ subdir('util')
|
|||||||
subdir('aimeio')
|
subdir('aimeio')
|
||||||
subdir('cardhook')
|
subdir('cardhook')
|
||||||
subdir('chunihook')
|
subdir('chunihook')
|
||||||
|
subdir('idzhook')
|
||||||
subdir('minihook')
|
subdir('minihook')
|
||||||
subdir('zinput')
|
subdir('zinput')
|
||||||
|
Loading…
Reference in New Issue
Block a user