Compare commits

...

66 Commits

Author SHA1 Message Date
96bf8cab81 aime: add portNo to config 2024-12-23 21:49:24 +01:00
a3120181be replace hardcoded enums with #define CTL_CODEs 2024-12-23 21:48:30 +01:00
80d4902cfc remove 5gb wasted space by removing precompiled headers 2024-12-23 21:04:51 +01:00
b4f5cdbe59 Merge pull request 'Add automatically apply OpenSSL patch for Intel Gen 10+ CPUs' (#43) from kagaminehaku/segatools:develop into develop
Reviewed-on: Dniel97/segatools#43
2024-12-23 19:43:47 +00:00
25431a9db1 Add "openssl" config key doc 2024-12-24 02:34:44 +07:00
a705ae8748 Merge pull request 'Add changeable config path' (#53) from GEEKiDoS/segatools:develop into develop
Reviewed-on: Dniel97/segatools#53
2024-12-23 18:04:12 +00:00
b52455339f Merge pull request 'dns: add port overriding support' (#52) from t12i/segatools:develop into develop
Reviewed-on: Dniel97/segatools#52
2024-12-23 17:54:38 +00:00
ff21223f06 Removed the unused lines 2024-12-17 10:06:41 +07:00
047733d122 format code 2024-12-16 11:18:00 +08:00
21bb965382 typo 2024-12-16 11:14:14 +08:00
11556a1332 add changeable config path 2024-12-16 11:09:38 +08:00
d8202e1df4 dns: add port overriding support 2024-12-12 02:28:02 +08:00
2d3d6fc2bb Skip the patch when already patched 2024-11-26 01:40:57 +07:00
6d8ffb46ef Merge pull request 'dns: fix msvc build' (#50) from Haruka/segatools:fixmsvc into develop
Reviewed-on: Dniel97/segatools#50
2024-11-17 13:42:53 +00:00
2069b1ea85 dns: fix msvc build 2024-11-14 13:03:13 +01:00
c80f903cf8 Fix build with Microsoft Visual C++, Fix gfxhook and felica issue (#48)
I just wanna say that It is a SHAME that a Windows ONLY project was not able to build without MINGW
Also where's the missing `3mpxsc.h` in diva hook?

This also fixes the window size issue from hook_CreateWindowExA in gfxhook
And Fixes felica issue as described in #45

Reviewed-on: Dniel97/segatools#48
Reviewed-by: Dniel97 <dniel97@noreply.gitea.tendokyu.moe>
Co-authored-by: GEEKiDoS <geek_ds@foxmail.com>
Co-committed-by: GEEKiDoS <geek_ds@foxmail.com>
2024-11-11 16:28:24 +00:00
ceb2b63e8b Modify host header in HTTP requests to bypass domain censorship in China. (#34)
Co-authored-by: Sanheiii <35133371+Sanheiii@users.noreply.github.com>
Reviewed-on: Dniel97/segatools#34
Co-authored-by: Sanhei <sanhei@noreply.gitea.tendokyu.moe>
Co-committed-by: Sanhei <sanhei@noreply.gitea.tendokyu.moe>
2024-11-11 16:24:33 +00:00
83840e0a87 dns: add new WAHLAP url blocked (#49)
Reviewed-on: Dniel97/segatools#49
Co-authored-by: zaphkito <zaphkito@noreply.gitea.tendokyu.moe>
Co-committed-by: zaphkito <zaphkito@noreply.gitea.tendokyu.moe>
2024-11-10 20:47:40 +00:00
e50d6d8ebc Merge pull request 'Throw fatal when vfs option configured but invalid' (#47) from Bottersnike/segatools:feat/vfs-validation into develop
Reviewed-on: Dniel97/segatools#47
2024-11-05 16:36:43 +00:00
e1a47cf365 Throw fatal when vfs option configured but invalid 2024-11-04 22:55:15 +00:00
8aef1cfa79 Change method set environment variable to current process only using "SetEnvironmentVariableW" 2024-11-05 00:48:21 +07:00
8fc24503c8 diva, fgo: added gfx, close #46 2024-11-03 23:00:43 +01:00
ebf0f0b428 Develop a new/better method to detect cpu using intrinsic functions (__cpuid and __cpuidex) 2024-11-02 00:26:31 +07:00
892eb2b859 idz, idac, swdc: fixed rumble effect 2024-10-29 22:06:07 +01:00
b80b9fbc19 Delete useless comment 2024-10-18 13:44:47 +07:00
cef3406691 Add switch for openssl patch in segatools.ini 2024-10-18 13:34:25 +07:00
97d2d6b9bc resolved camelCase and the " :" problem 2024-10-16 15:53:52 +07:00
f39b9ce3a0 resolve dniel97 comments 2024-10-16 15:01:39 +07:00
243bb778d1 Add automatically apply OpenSSL patch for Intel Gen 10+ CPUs 2024-10-16 04:08:54 +07:00
66317a0054 bump capnhook rev to include serial fixes 2024-10-11 07:32:22 +02:00
8c24e04900 Merge pull request 'printer: Add setting to configure "printing time"' (#39) from Haruka/segatools:printerdelay into develop
Reviewed-on: Dniel97/segatools#39
2024-10-04 12:53:26 +00:00
3bb9404a38 printer: add the default waitTime setting to config 2024-10-04 11:43:34 +02:00
6819963f06 Merge branch 'refs/heads/develop' into printerdelay 2024-10-03 12:12:59 +02:00
36849bd09a Merge branch 'feature/ffb' into develop 2024-09-30 23:23:23 +02:00
5f817c8a36 swdc: minor improvements 2024-09-30 23:17:37 +02:00
259b763a13 idz: add ffb and led emulation 2024-09-30 23:10:16 +02:00
2251585ef0 swdc: add ffb and led emulation 2024-09-30 20:23:28 +02:00
c06bb408e7 idac: add ffb emulation 2024-09-30 18:50:46 +02:00
53fb8c28ea Merge pull request 'kemono: only load I/O dll inside amdaemon' (#38) from Haruka/segatools:kemonofr64bit into develop
Reviewed-on: Dniel97/segatools#38
2024-09-28 13:36:06 +00:00
33452394e6 kemono: also only load aimeio dll in x64 process 2024-09-27 17:50:40 +02:00
4fa9abffe8 printer: add ability to delay printing 2024-09-27 11:06:18 +02:00
88a5bdcd14 kemono: only load I/O dll inside amdaemon 2024-09-26 11:52:00 +02:00
bb773a63ce Merge pull request 'Kemono Friends support / 32-bit CHC300 support' (#36) from Haruka/segatools:kemonofr into develop
Reviewed-on: Dniel97/segatools#36
2024-09-21 15:12:05 +00:00
25e79f87c2 Merge pull request 'felica: fix rare card scan error (correct PMm)' (#33) from zaphkito/segatools:develop into develop
Reviewed-on: Dniel97/segatools#33
2024-09-21 15:10:28 +00:00
79592514ba fgo: fix printer 2024-09-20 11:14:41 +02:00
cdfd3bf655 kemono: not sure why that went missing 2024-09-20 11:09:21 +02:00
f6c12fd230 kemono: Pre-generate printer firmware files 2024-09-19 13:46:49 +02:00
86556ed2c8 kemono: Update start.bat 2024-09-16 14:29:49 +02:00
9de48dd6ce kemono: flip declarations 2024-09-13 16:52:55 +02:00
d257887f6e kemono: fix packagefile again 2024-09-12 13:29:17 +02:00
3eef5dd209 kemono: fix LED board check error 2024-09-12 13:25:38 +02:00
599d5e3211 kemono: fix LED hooking, add button LEDs 2024-09-12 13:25:19 +02:00
f18d074c5f kemono: add missed declarations 2024-09-12 12:50:57 +02:00
6bd1bce419 kemono: mention in readme 2024-09-12 12:50:51 +02:00
96bdacfa7c kemono: remove old amdaemon workaround 2024-09-12 12:40:57 +02:00
d4bb7b6e0e kemono: correct keychip IP range 2024-09-12 12:40:10 +02:00
70ac873d11 kemono: add to package creation 2024-09-12 12:39:42 +02:00
068651b6fa kemono: add support 2024-09-11 13:31:23 +02:00
84e9ed3c9a felica: fix rare card scan error (cucorrect PMm)
from real aime card with official card reader
2024-08-31 13:57:18 +00:00
c827b4c212 Merge pull request 'add almost full vfd implementation' (#31) from Haruka/segatools:vfd into develop
Reviewed-on: Dniel97/segatools#31
Reviewed-by: Dniel97 <dniel97@noreply.gitea.tendokyu.moe>
2024-08-24 21:56:38 +00:00
26624f25b1 hide default vfd ports from configs 2024-08-24 11:14:13 +02:00
824bc9abda default vfd port number to zero (use game-specific port) 2024-08-23 17:24:47 +02:00
cc5b87b559 add vfd settings to docs 2024-08-23 17:23:59 +02:00
e6794807a6 add default port fallback for vfd 2024-08-23 17:20:05 +02:00
54cbbffae9 add almost full vfd implementation 2024-08-23 16:30:22 +02:00
ac0f9f0587 aime firmware fix, mu3 keybinding fix 2024-08-21 15:13:09 +02:00
264 changed files with 6207 additions and 1005 deletions

4
.clang-format Normal file
View File

@ -0,0 +1,4 @@
---
BasedOnStyle: Google
IndentWidth: 4
---

View File

@ -219,6 +219,27 @@ $(BUILD_DIR_ZIP)/tokyo.zip:
$(V)strip $(BUILD_DIR_ZIP)/tokyo/*.{exe,dll}
$(V)cd $(BUILD_DIR_ZIP)/tokyo ; zip -r ../tokyo.zip *
$(BUILD_DIR_ZIP)/kemono.zip:
$(V)echo ... $@
$(V)mkdir -p $(BUILD_DIR_ZIP)/kemono
$(V)mkdir -p $(BUILD_DIR_ZIP)/kemono/DEVICE
$(V)cp $(DIST_DIR)/kemono/segatools.ini \
$(DIST_DIR)/kemono/start.bat \
$(BUILD_DIR_ZIP)/kemono
$(V)cp $(BUILD_DIR_32)/kemonohook/kemonohook.dll \
$(BUILD_DIR_ZIP)/kemono/kemonohook_x86.dll
$(V)cp $(BUILD_DIR_64)/kemonohook/kemonohook.dll \
$(BUILD_DIR_ZIP)/kemono/kemonohook_x64.dll
$(V)cp $(BUILD_DIR_32)/subprojects/capnhook/inject/inject.exe \
$(BUILD_DIR_ZIP)/kemono/inject_x86.exe
$(V)cp $(BUILD_DIR_64)/subprojects/capnhook/inject/inject.exe \
$(BUILD_DIR_ZIP)/kemono/inject_x64.exe
$(V)cp pki/billing.pub \
pki/ca.crt \
$(BUILD_DIR_ZIP)/kemono/DEVICE
for x in exe dll; do strip $(BUILD_DIR_ZIP)/kemono/*.$$x; done
$(V)cd $(BUILD_DIR_ZIP)/kemono ; zip -r ../kemono.zip *
$(BUILD_DIR_ZIP)/doc.zip: \
$(DOC_DIR)/config \
$(DOC_DIR)/chunihook.md \
@ -243,6 +264,7 @@ $(BUILD_DIR_ZIP)/segatools.zip: \
$(BUILD_DIR_ZIP)/cm.zip \
$(BUILD_DIR_ZIP)/tokyo.zip \
$(BUILD_DIR_ZIP)/fgo.zip \
$(BUILD_DIR_ZIP)/kemono.zip \
CHANGELOG.md \
README.md \

View File

@ -1,6 +1,6 @@
# Segatools
Version: `2024-08-20`
Version: `2024-09-30`
Loaders and hardware emulators for SEGA games that run on the Nu and ALLS platforms.
@ -30,6 +30,8 @@ Loaders and hardware emulators for SEGA games that run on the Nu and ALLS platfo
* SEGA World Drivers Championship 2019
* WACCA
* starting from WACCA
* Kemono Friends
* Kemono Friends 3: Planet Tours
## End-users

View File

@ -12,6 +12,7 @@
#include "util/crc.h"
#include "util/dprintf.h"
#include "util/env.h"
struct aime_io_config {
wchar_t aime_path[MAX_PATH];
@ -222,7 +223,7 @@ uint16_t aime_io_get_api_version(void)
HRESULT aime_io_init(void)
{
aime_io_config_read(&aime_io_cfg, L".\\segatools.ini");
aime_io_config_read(&aime_io_cfg, get_config_path());
return S_OK;
}

View File

@ -3,7 +3,6 @@ aimeio_lib = static_library(
name_prefix : '',
include_directories: inc,
implicit_include_directories : false,
c_pch : '../precompiled.h',
link_with : [
util_lib,
],

View File

@ -1,10 +1,11 @@
#include <windows.h>
#include <devioctl.h>
#include <ntdddisk.h>
#include <winioctl.h>
#include <assert.h>
#include <ctype.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "amex/ds.h"
@ -19,13 +20,11 @@
#include "util/dprintf.h"
#include "util/str.h"
#pragma pack(push, 1)
#define DS_IOCTL_GET_ABI_VERSION CTL_CODE(0x8000, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS)
#define DS_IOCTL_SETUP CTL_CODE(0x8000, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS)
#define DS_IOCTL_READ_SECTOR CTL_CODE(0x8000, 0x804, METHOD_BUFFERED, FILE_READ_ACCESS)
enum {
DS_IOCTL_GET_ABI_VERSION = 0x80006000,
DS_IOCTL_SETUP = 0x80006004,
DS_IOCTL_READ_SECTOR = 0x80006010,
};
#pragma pack(push, 1)
struct ds_eeprom {
uint32_t crc32;

View File

@ -6,7 +6,7 @@
#include <winnt.h>
#endif
#include <devioctl.h>
#include <ntdddisk.h>
#include <winioctl.h>
#include <assert.h>
@ -20,9 +20,7 @@
#include "util/dprintf.h"
#include "util/str.h"
enum {
EEPROM_IOCTL_GET_ABI_VERSION = 0x80006000,
};
#define EEPROM_IOCTL_GET_ABI_VERSION CTL_CODE(0x8000, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS)
static HRESULT eeprom_handle_irp(struct irp *irp);
static HRESULT eeprom_handle_open(struct irp *irp);

View File

@ -1,5 +1,6 @@
#include <windows.h>
#include <ntstatus.h>
#include <winioctl.h>
#include <assert.h>
#include <string.h>
@ -13,12 +14,10 @@
#include "util/dprintf.h"
#include "util/str.h"
enum {
GPIO_IOCTL_SET_LEDS = 0x8000A004,
GPIO_IOCTL_GET_PSW = 0x80006008,
GPIO_IOCTL_GET_DIPSW = 0x8000600C,
GPIO_IOCTL_DESCRIBE = 0x80006014,
};
#define GPIO_IOCTL_SET_LEDS CTL_CODE(0x8000, 0x801, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define GPIO_IOCTL_GET_PSW CTL_CODE(0x8000, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS)
#define GPIO_IOCTL_GET_DIPSW CTL_CODE(0x8000, 0x803, METHOD_BUFFERED, FILE_READ_ACCESS)
#define GPIO_IOCTL_DESCRIBE CTL_CODE(0x8000, 0x805, METHOD_BUFFERED, FILE_READ_ACCESS)
enum {
GPIO_TYPE_NONE = 0,

View File

@ -4,6 +4,7 @@
#include <winternl.h>
#include <ntstatus.h>
#include <winioctl.h>
#include <assert.h>
#include <stddef.h>
@ -21,11 +22,9 @@
#include "util/dump.h"
#include "util/str.h"
enum {
JVS_IOCTL_HELLO = 0x80006004,
JVS_IOCTL_SENSE = 0x8000600C,
JVS_IOCTL_TRANSACT = 0x8000E008,
};
#define JVS_IOCTL_HELLO CTL_CODE(0x8000, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS)
#define JVS_IOCTL_TRANSACT CTL_CODE(0x8000, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define JVS_IOCTL_SENSE CTL_CODE(0x8000, 0x803, METHOD_BUFFERED, FILE_READ_ACCESS)
static HRESULT jvs_handle_irp(struct irp *irp);
static HRESULT jvs_handle_open(struct irp *irp);

View File

@ -2,7 +2,6 @@ amex_lib = static_library(
'amex',
include_directories : inc,
implicit_include_directories : false,
c_pch : '../precompiled.h',
dependencies : [
capnhook.get_variable('hook_dep'),
],

View File

@ -6,7 +6,7 @@
#include <winnt.h>
#endif
#include <devioctl.h>
#include <ntdddisk.h>
#include <winioctl.h>
#include <assert.h>
@ -20,9 +20,7 @@
#include "util/dprintf.h"
#include "util/str.h"
enum {
SRAM_IOCTL_GET_ABI_VERSION = 0x80006000,
};
#define SRAM_IOCTL_GET_ABI_VERSION CTL_CODE(0x8000, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS)
static HRESULT sram_handle_irp(struct irp *irp);
static HRESULT sram_handle_open(struct irp *irp);

View File

@ -1,6 +1,7 @@
#pragma once
#include <windows.h>
#include <stdbool.h>
#include "aimeio/aimeio.h"

View File

@ -72,6 +72,7 @@ void aime_config_load(struct aime_config *cfg, const wchar_t *filename)
aime_dll_config_load(&cfg->dll, filename);
cfg->enable = GetPrivateProfileIntW(L"aime", L"enable", 1, filename);
cfg->port_no = GetPrivateProfileIntW(L"aime", L"portNo", 0, filename);
cfg->high_baudrate = GetPrivateProfileIntW(L"aime", L"highBaud", 1, filename);
cfg->gen = GetPrivateProfileIntW(L"aime", L"gen", 0, filename);
}
@ -90,4 +91,14 @@ void vfd_config_load(struct vfd_config *cfg, const wchar_t *filename)
assert(filename != NULL);
cfg->enable = GetPrivateProfileIntW(L"vfd", L"enable", 1, filename);
cfg->port_no = GetPrivateProfileIntW(L"vfd", L"portNo", 0, filename);
cfg->utf_conversion = GetPrivateProfileIntW(L"vfd", L"utfConversion", 0, filename);
}
void ffb_config_load(struct ffb_config *cfg, const wchar_t *filename)
{
assert(cfg != NULL);
assert(filename != NULL);
cfg->enable = GetPrivateProfileIntW(L"ffb", L"enable", 1, filename);
}

View File

@ -6,7 +6,9 @@
#include "board/io4.h"
#include "board/sg-reader.h"
#include "board/vfd.h"
#include "board/ffb.h"
void aime_config_load(struct aime_config *cfg, const wchar_t *filename);
void io4_config_load(struct io4_config *cfg, const wchar_t *filename);
void vfd_config_load(struct vfd_config *cfg, const wchar_t *filename);
void ffb_config_load(struct ffb_config *cfg, const wchar_t *filename);

235
board/ffb.c Normal file
View File

@ -0,0 +1,235 @@
/*
Force Feedback Board (FFB)
This board is used by many SEGA games to provide force feedback to the player.
It is driven by the game software over a serial connection and is used by many
games such as SEGA World Drivers Championship, Initial D Arcade, ...
Part number in schematics is "838-15069 MOTOR DRIVE BD RS232/422 Board".
Some observations:
The maximal strength for any effect is 127, except Damper which maxes out at 40.
The period for rumble effects is in the range 0-40.
*/
#include "board/ffb.h"
#include <assert.h>
#include <stdint.h>
#include <windows.h>
#include "hook/iohook.h"
#include "hooklib/uart.h"
#include "util/dprintf.h"
#include "util/dump.h"
// request format:
// 0x?? - sync + command
// 0x?? - direction/additional command
// 0x?? - strength
// 0x?? - checksum (sum of everything except the sync byte)
enum {
FFB_CMD_TOGGLE = 0x80,
FFB_CMD_CONSTANT_FORCE = 0x84,
FFB_CMD_RUMBLE = 0x85,
FFB_CMD_DAMPER = 0x86,
};
struct ffb_hdr {
uint8_t cmd;
};
union ffb_req_any {
struct ffb_hdr hdr;
uint8_t bytes[3];
};
static HRESULT ffb_handle_irp(struct irp *irp);
static HRESULT ffb_req_dispatch(const union ffb_req_any *req);
static HRESULT ffb_req_toggle(const uint8_t *bytes);
static HRESULT ffb_req_constant_force(const uint8_t *bytes);
static HRESULT ffb_req_rumble(const uint8_t *bytes);
static HRESULT ffb_req_damper(const uint8_t *bytes);
static const struct ffb_ops *ffb_ops;
static struct uart ffb_uart;
static bool ffb_started;
static HRESULT ffb_start_hr;
static uint8_t ffb_written[4];
static uint8_t ffb_readable[4];
/* Static variables to store maximum strength values */
static uint8_t max_constant_force = 0;
static uint8_t max_rumble = 0;
static uint8_t max_period = 0;
static uint8_t max_damper = 0;
HRESULT ffb_hook_init(
const struct ffb_config *cfg,
const struct ffb_ops *ops,
unsigned int port_no)
{
assert(cfg != NULL);
assert(ops != NULL);
if (!cfg->enable) {
return S_FALSE;
}
ffb_ops = ops;
uart_init(&ffb_uart, port_no);
ffb_uart.written.bytes = ffb_written;
ffb_uart.written.nbytes = sizeof(ffb_written);
ffb_uart.readable.bytes = ffb_readable;
ffb_uart.readable.nbytes = sizeof(ffb_readable);
dprintf("FFB: hook enabled.\n");
return iohook_push_handler(ffb_handle_irp);
}
static HRESULT ffb_handle_irp(struct irp *irp)
{
HRESULT hr;
assert(irp != NULL);
if (!uart_match_irp(&ffb_uart, irp)) {
return iohook_invoke_next(irp);
}
hr = uart_handle_irp(&ffb_uart, irp);
if (FAILED(hr) || irp->op != IRP_OP_WRITE) {
return hr;
}
assert(&ffb_uart.written != NULL);
assert(ffb_uart.written.bytes != NULL || ffb_uart.written.nbytes == 0);
assert(ffb_uart.written.pos <= ffb_uart.written.nbytes);
// dprintf("FFB TX:\n");
hr = ffb_req_dispatch((const union ffb_req_any *) ffb_uart.written.bytes);
if (FAILED(hr)) {
dprintf("FFB: Processing error: %x\n", (int)hr);
}
// dump_iobuf(&ffb_uart.written);
ffb_uart.written.pos = 0;
return hr;
}
static HRESULT ffb_req_dispatch(const union ffb_req_any *req)
{
switch (req->hdr.cmd) {
case FFB_CMD_TOGGLE:
return ffb_req_toggle(req->bytes);
case FFB_CMD_CONSTANT_FORCE:
return ffb_req_constant_force(req->bytes);
case FFB_CMD_RUMBLE:
return ffb_req_rumble(req->bytes);
case FFB_CMD_DAMPER:
return ffb_req_damper(req->bytes);
/* There are some test mode specfic commands which doesn't seem to be used in
game at all. The same is true for the initialization phase. */
default:
dprintf("FFB: Unhandled command %02x\n", req->hdr.cmd);
return S_OK;
}
}
static HRESULT ffb_req_toggle(const uint8_t *bytes)
{
uint8_t activate = bytes[2];
if (activate == 0x01) {
dprintf("FFB: Activated\n");
} else {
dprintf("FFB: Deactivated\n");
}
if (ffb_ops->toggle != NULL) {
ffb_ops->toggle(activate == 0x01);
}
return S_OK;
}
static HRESULT ffb_req_constant_force(const uint8_t *bytes)
{
// dprintf("FFB: Constant force\n");
uint8_t direction = bytes[1];
uint8_t force = bytes[2];
if (direction == 0x0) {
// Right
force = 128 - force;
}
// Update max strength if the current force is greater
if (force > max_constant_force) {
max_constant_force = force;
}
// dprintf("FFB: Constant Force Strength: %d (Max: %d)\n", force, max_constant_force);
if (ffb_ops->constant_force != NULL) {
ffb_ops->constant_force(direction, force);
}
return S_OK;
}
static HRESULT ffb_req_rumble(const uint8_t *bytes)
{
// dprintf("FFB: Rumble\n");
uint8_t force = bytes[1];
uint8_t period = bytes[2];
// Update max strength if the current force is greater
if (force > max_rumble) {
max_rumble = force;
}
if (period > max_period) {
max_period = period;
}
// dprintf("FFB: Rumble Period: %d (Max %d), Strength: %d (Max: %d)\n", period, max_period, force, max_rumble);
if (ffb_ops->rumble != NULL) {
ffb_ops->rumble(force, period);
}
return S_OK;
}
static HRESULT ffb_req_damper(const uint8_t *bytes)
{
// dprintf("FFB: Damper\n");
uint8_t force = bytes[2];
// Update max strength if the current force is greater
if (force > max_damper) {
max_damper = force;
}
// dprintf("FFB: Damper Strength: %d (Max: %d)\n", force, max_damper);
if (ffb_ops->damper != NULL) {
ffb_ops->damper(force);
}
return S_OK;
}

21
board/ffb.h Normal file
View File

@ -0,0 +1,21 @@
#pragma once
#include <windows.h>
#include <stdbool.h>
#include <stdint.h>
struct ffb_config {
bool enable;
};
struct ffb_ops {
void (*toggle)(bool active);
void (*constant_force)(uint8_t direction, uint8_t force);
void (*rumble)(uint8_t force, uint8_t period);
void (*damper)(uint8_t force);
};
HRESULT ffb_hook_init(
const struct ffb_config *cfg,
const struct ffb_ops *ops,
unsigned int port_no);

View File

@ -16,6 +16,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include "board/io3.h"

View File

@ -7,6 +7,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include "board/config.h"
#include "board/guid.h"

View File

@ -3,6 +3,7 @@
#include <windows.h>
#include <stdint.h>
#include <stdbool.h>
#define IO4_REPORT_OUT_PAYLOAD_LEN 62

View File

@ -13,6 +13,7 @@
#include <process.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -242,7 +243,7 @@ static HRESULT led15070_handle_irp_locked(int board, struct irp *irp)
dump_iobuf(&boarduart->written);
#endif
req_iobuf.bytes = (byte*)&req;
req_iobuf.bytes = (uint8_t*)&req;
req_iobuf.nbytes = sizeof(req.hdr) + sizeof(req.cmd) + sizeof(req.payload);
req_iobuf.pos = 0;

View File

@ -88,7 +88,7 @@ struct led15093_req_reset {
struct led15093_req_set_timeout {
struct led15093_req_hdr hdr;
uint8_t cmd;
uint8_t count;
uint16_t count;
};
struct led15093_req_set_disable_response {
@ -199,7 +199,7 @@ struct led15093_resp_board_info {
char chip_num[5];
uint8_t endcode; // Always 0xFF
uint8_t fw_ver;
uint8_t rx_buf;
uint16_t rx_buf;
};
struct led15093_resp_protocol_ver {

View File

@ -20,6 +20,7 @@
#include <process.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "board/led15093-cmd.h"
@ -272,7 +273,7 @@ static HRESULT led15093_handle_irp_locked(int board, struct irp *irp)
dump_iobuf(&boarduart->written);
#endif
req_iobuf.bytes = (byte*)&req;
req_iobuf.bytes = (uint8_t*)&req;
req_iobuf.nbytes = sizeof(req.hdr) + sizeof(req.payload);
req_iobuf.pos = 0;

View File

@ -2,7 +2,6 @@ board_lib = static_library(
'board',
include_directories : inc,
implicit_include_directories : false,
c_pch : '../precompiled.h',
dependencies : [
capnhook.get_variable('hook_dep'),
],
@ -47,5 +46,10 @@ board_lib = static_library(
'slider-frame.h',
'vfd.c',
'vfd.h',
'vfd-cmd.h',
'vfd-frame.c',
'vfd-frame.h',
'ffb.c',
'ffb.h'
],
)

View File

@ -5,19 +5,21 @@
#pragma pack(push, 1)
enum {
SG_NFC_CMD_GET_FW_VERSION = 0x30,
SG_NFC_CMD_GET_HW_VERSION = 0x32,
SG_NFC_CMD_RADIO_ON = 0x40,
SG_NFC_CMD_RADIO_OFF = 0x41,
SG_NFC_CMD_POLL = 0x42,
SG_NFC_CMD_MIFARE_SELECT_TAG = 0x43,
SG_NFC_CMD_MIFARE_SET_KEY_BANA = 0x50,
SG_NFC_CMD_MIFARE_READ_BLOCK = 0x52,
SG_NFC_CMD_MIFARE_SET_KEY_AIME = 0x54,
SG_NFC_CMD_MIFARE_AUTHENTICATE = 0x55, /* guess based on time sent */
SG_NFC_CMD_SEND_HEX_DATA = 0x61,
SG_NFC_CMD_RESET = 0x62,
SG_NFC_CMD_FELICA_ENCAP = 0x71,
SG_NFC_CMD_GET_FW_VERSION = 0x30,
SG_NFC_CMD_GET_HW_VERSION = 0x32,
SG_NFC_CMD_RADIO_ON = 0x40,
SG_NFC_CMD_RADIO_OFF = 0x41,
SG_NFC_CMD_POLL = 0x42,
SG_NFC_CMD_MIFARE_SELECT_TAG = 0x43,
SG_NFC_CMD_MIFARE_SET_KEY_AIME = 0x50,
SG_NFC_CMD_MIFARE_AUTHENTICATE_A = 0x51,
SG_NFC_CMD_MIFARE_READ_BLOCK = 0x52,
SG_NFC_CMD_MIFARE_SET_KEY_BANA = 0x54,
SG_NFC_CMD_MIFARE_AUTHENTICATE_B = 0x55,
SG_NFC_CMD_TO_UPDATE_MODE = 0x60,
SG_NFC_CMD_SEND_HEX_DATA = 0x61,
SG_NFC_CMD_RESET = 0x62,
SG_NFC_CMD_FELICA_ENCAP = 0x71,
};
struct sg_nfc_res_get_fw_version {
@ -32,7 +34,7 @@ struct sg_nfc_res_get_hw_version {
struct sg_nfc_req_mifare_set_key {
struct sg_req_header req;
uint8_t key_a[6];
uint8_t key[6];
};
struct sg_nfc_req_mifare_50 {

View File

@ -60,6 +60,11 @@ static HRESULT sg_nfc_cmd_felica_encap(
const struct sg_nfc_req_felica_encap *req,
struct sg_nfc_res_felica_encap *res);
static HRESULT sg_nfc_cmd_send_hex_data(
struct sg_nfc *nfc,
const struct sg_req_header *req,
struct sg_res_header *res);
static HRESULT sg_nfc_cmd_dummy(
struct sg_nfc *nfc,
const struct sg_req_header *req,
@ -184,13 +189,17 @@ static HRESULT sg_nfc_dispatch(
&req->felica_encap,
&res->felica_encap);
case SG_NFC_CMD_MIFARE_AUTHENTICATE:
case SG_NFC_CMD_MIFARE_AUTHENTICATE_A:
case SG_NFC_CMD_MIFARE_AUTHENTICATE_B:
case SG_NFC_CMD_SEND_HEX_DATA:
return sg_nfc_cmd_send_hex_data(nfc, &req->simple, &res->simple);
case SG_NFC_CMD_MIFARE_SELECT_TAG:
case SG_NFC_CMD_MIFARE_SET_KEY_AIME:
case SG_NFC_CMD_MIFARE_SET_KEY_BANA:
case SG_NFC_CMD_RADIO_ON:
case SG_NFC_CMD_RADIO_OFF:
case SG_NFC_CMD_SEND_HEX_DATA: // TODO: implement?
case SG_NFC_CMD_TO_UPDATE_MODE:
return sg_nfc_cmd_dummy(nfc, &req->simple, &res->simple);
default:
@ -345,13 +354,13 @@ static HRESULT sg_nfc_poll_felica(
felica->type = 0x20;
felica->id_len = sizeof(felica->IDm) + sizeof(felica->PMm);
felica->IDm = _byteswap_uint64(IDm);
felica->PMm = _byteswap_uint64(felica_get_generic_PMm());
felica->PMm = _byteswap_uint64(felica_get_amusement_ic_PMm());
/* Initialize FeliCa IC emulator */
nfc->felica.IDm = IDm;
nfc->felica.PMm = felica_get_generic_PMm();
nfc->felica.system_code = 0x0000;
nfc->felica.PMm = felica_get_amusement_ic_PMm();
nfc->felica.system_code = 0x88b4;
return S_OK;
}
@ -442,6 +451,22 @@ static HRESULT sg_nfc_cmd_felica_encap(
return S_OK;
}
static HRESULT sg_nfc_cmd_send_hex_data(
struct sg_nfc *nfc,
const struct sg_req_header *req,
struct sg_res_header *res)
{
sg_res_init(res, req, 0);
/* Firmware checksum length? */
if (req->payload_len == 0x2b) {
/* The firmware is identical flag? */
res->status = 0x20;
}
return S_OK;
}
static HRESULT sg_nfc_cmd_dummy(
struct sg_nfc *nfc,
const struct sg_req_header *req,

View File

@ -47,7 +47,7 @@ static struct sg_led sg_reader_led;
HRESULT sg_reader_hook_init(
const struct aime_config *cfg,
unsigned int port_no,
unsigned int default_port_no,
unsigned int gen,
HINSTANCE self)
{
@ -66,6 +66,11 @@ HRESULT sg_reader_hook_init(
return hr;
}
unsigned int port_no = cfg->port_no;
if (port_no == 0){
port_no = default_port_no;
}
if (cfg->gen != 0) {
gen = cfg->gen;
}
@ -85,6 +90,7 @@ HRESULT sg_reader_hook_init(
sg_reader_uart.baud.BaudRate = 38400;
}
dprintf("NFC Assembly: enabling (port=%d)\n", port_no);
uart_init(&sg_reader_uart, port_no);
sg_reader_uart.written.bytes = sg_reader_written_bytes;
sg_reader_uart.written.nbytes = sizeof(sg_reader_written_bytes);

View File

@ -9,12 +9,13 @@
struct aime_config {
struct aime_dll_config dll;
bool enable;
unsigned int port_no;
bool high_baudrate;
unsigned int gen;
};
HRESULT sg_reader_hook_init(
const struct aime_config *cfg,
unsigned int port_no,
unsigned int default_port_no,
unsigned int gen,
HINSTANCE self);

123
board/vfd-cmd.h Normal file
View File

@ -0,0 +1,123 @@
#pragma once
#include "board/vfd-frame.h"
enum {
VFD_CMD_GET_VERSION = 0x5B,
VFD_CMD_RESET = 0x0B,
VFD_CMD_CLEAR_SCREEN = 0x0C,
VFD_CMD_SET_BRIGHTNESS = 0x20,
VFD_CMD_SET_SCREEN_ON = 0x21,
VFD_CMD_SET_H_SCROLL = 0x22,
VFD_CMD_DRAW_IMAGE = 0x2E,
VFD_CMD_SET_CURSOR = 0x30,
VFD_CMD_SET_ENCODING = 0x32,
VFD_CMD_SET_TEXT_WND = 0x40,
VFD_CMD_SET_TEXT_SPEED = 0x41,
VFD_CMD_WRITE_TEXT = 0x50,
VFD_CMD_ENABLE_SCROLL = 0x51,
VFD_CMD_DISABLE_SCROLL = 0x52,
VFD_CMD_ROTATE = 0x5D,
VFD_CMD_CREATE_CHAR = 0xA3,
VFD_CMD_CREATE_CHAR2 = 0xA4,
};
enum {
VFD_ENC_GB2312 = 0,
VFD_ENC_BIG5 = 1,
VFD_ENC_SHIFT_JIS = 2,
VFD_ENC_KSC5601 = 3,
VFD_ENC_MAX = 3,
};
struct vfd_req_hdr {
uint8_t sync;
uint8_t cmd;
};
struct vfd_req_any {
struct vfd_req_hdr hdr;
uint8_t payload[2054];
};
struct vfd_req_board_info {
struct vfd_req_hdr hdr;
uint8_t unk1;
};
struct vfd_resp_board_info { // \x0201.20\x03
uint8_t unk1;
char version[5];
uint8_t unk2;
};
struct vfd_req_reset {
struct vfd_req_hdr hdr;
};
struct vfd_req_cls {
struct vfd_req_hdr hdr;
};
struct vfd_req_brightness {
struct vfd_req_hdr hdr;
uint8_t brightness;
};
struct vfd_req_power {
struct vfd_req_hdr hdr;
uint8_t power_state;
};
struct vfd_req_hscroll {
struct vfd_req_hdr hdr;
uint8_t x_pos;
};
struct vfd_req_draw {
struct vfd_req_hdr hdr;
uint16_t x0;
uint8_t y0;
uint16_t x1;
uint8_t y1;
uint8_t image[2048];
};
struct vfd_req_cursor {
struct vfd_req_hdr hdr;
uint16_t x;
uint8_t y;
};
struct vfd_req_encoding {
struct vfd_req_hdr hdr;
uint8_t encoding;
};
struct vfd_req_wnd {
struct vfd_req_hdr hdr;
uint16_t x0;
uint8_t y0;
uint16_t x1;
uint8_t y1;
};
struct vfd_req_speed {
struct vfd_req_hdr hdr;
uint8_t encoding;
};
struct vfd_req_scroll {
struct vfd_req_hdr hdr;
};
struct vfd_req_rotate {
struct vfd_req_hdr hdr;
uint8_t unk1;
};
struct vfd_req_create_char {
struct vfd_req_hdr hdr;
uint8_t type;
uint8_t pixels[32];
};

88
board/vfd-frame.c Normal file
View File

@ -0,0 +1,88 @@
#include <windows.h>
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#define SUPER_VERBOSE 1
#include "board/vfd-frame.h"
#include "hook/iobuf.h"
#include "util/dprintf.h"
static HRESULT vfd_frame_encode_byte(struct iobuf *dest, uint8_t byte);
/* Frame structure:
REQUEST:
[0] Sync byte (0x1A or 0x1B)
[1] Packet ID
[2...n-1] Data/payload
--- OR ---
if no sync byte is given, plain static text in the currently configured encoding is expected.
RESPONSE:
This thing never responds, unless it's VFD_CMD_GET_VERSION
*/
bool vfd_frame_sync(struct const_iobuf *src) {
return src->bytes[src->pos] == VFD_SYNC_BYTE || src->bytes[src->pos] == VFD_SYNC_BYTE2;
}
HRESULT vfd_frame_encode(
struct iobuf *dest,
const void *ptr,
size_t nbytes) {
const uint8_t *src;
uint8_t byte;
size_t i;
HRESULT hr;
assert(dest != NULL);
assert(dest->bytes != NULL || dest->nbytes == 0);
assert(dest->pos <= dest->nbytes);
assert(ptr != NULL);
src = ptr;
if (dest->pos >= dest->nbytes) {
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
}
#if SUPER_VERBOSE
dprintf("VFD: RX Buffer:\n");
#endif
for (i = 1; i < nbytes; i++) {
byte = src[i];
#if SUPER_VERBOSE
dprintf("%02x ", byte);
#endif
hr = vfd_frame_encode_byte(dest, byte);
if (FAILED(hr)) {
return hr;
}
}
#if SUPER_VERBOSE
dprintf("\n");
#endif
return hr;
}
static HRESULT vfd_frame_encode_byte(struct iobuf *dest, uint8_t byte) {
if (dest->pos + 1 > dest->nbytes) {
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
}
dest->bytes[dest->pos++] = byte;
return S_OK;
}

20
board/vfd-frame.h Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include <windows.h>
#include <stddef.h>
#include <stdint.h>
#include "hook/iobuf.h"
enum {
VFD_SYNC_BYTE = 0x1B,
VFD_SYNC_BYTE2 = 0x1A,
};
bool vfd_frame_sync(struct const_iobuf *src);
HRESULT vfd_frame_encode(
struct iobuf *dest,
const void *ptr,
size_t nbytes);

View File

@ -2,17 +2,17 @@
directly by amdaemon, and it has something to do with displaying the status
of electronic payments.
Part number in schematics is "VFD GP1232A02A FUTABA".
Little else about this board is known. Black-holing the RS232 comms that it
receives seems to be sufficient for the time being. */
Part number in schematics is "VFD GP1232A02A FUTABA". */
#include <windows.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include "board/config.h"
#include "board/vfd.h"
#include "board/vfd-cmd.h"
#include "hook/iohook.h"
@ -21,33 +21,101 @@
#include "util/dprintf.h"
#include "util/dump.h"
#define SUPER_VERBOSE 0
static HRESULT vfd_handle_irp(struct irp *irp);
static struct uart vfd_uart;
static uint8_t vfd_written[512];
static uint8_t vfd_readable[512];
UINT codepage;
static uint8_t vfd_written[4096];
static uint8_t vfd_readable[4096];
HRESULT vfd_hook_init(const struct vfd_config *cfg, unsigned int port_no)
static int encoding = VFD_ENC_SHIFT_JIS;
HRESULT vfd_handle_get_version(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_reset(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_clear_screen(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_set_brightness(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_set_screen_on(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_set_h_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_draw_image(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_set_cursor(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_set_encoding(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_set_text_wnd(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_set_text_speed(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_write_text(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_enable_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_disable_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_rotate(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_create_char(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
HRESULT vfd_handle_create_char2(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart);
static bool utf_enabled;
HRESULT vfd_hook_init(struct vfd_config *cfg, unsigned int default_port_no)
{
assert(cfg != NULL);
if (!cfg->enable) {
if (!cfg->enable){
return S_FALSE;
}
utf_enabled = cfg->utf_conversion;
unsigned int port_no = cfg->port_no;
if (port_no == 0){
port_no = default_port_no;
}
dprintf("VFD: enabling (port=%d)\n", port_no);
uart_init(&vfd_uart, port_no);
vfd_uart.written.bytes = vfd_written;
vfd_uart.written.nbytes = sizeof(vfd_written);
vfd_uart.readable.bytes = vfd_readable;
vfd_uart.readable.nbytes = sizeof(vfd_readable);
codepage = GetACP();
dprintf("VFD: hook enabled.\n");
return iohook_push_handler(vfd_handle_irp);
}
const char* get_encoding_name(int b){
switch (b){
case 0: return "gb2312";
case 1: return "big5";
case 2: return "shift-jis";
case 3: return "ks_c_5601-1987";
default: return "unknown";
}
}
void print_vfd_text(const char* str, int len){
if (utf_enabled){
wchar_t encoded[1024];
memset(encoded, 0, 1024 * sizeof(wchar_t));
int codepage = 0;
if (encoding == VFD_ENC_GB2312){
codepage = 936;
} else if (encoding == VFD_ENC_BIG5){
codepage = 950;
} else if (encoding == VFD_ENC_SHIFT_JIS){
codepage = 932;
} else if (encoding == VFD_ENC_KSC5601) {
codepage = 949;
}
if (!MultiByteToWideChar(codepage, MB_USEGLYPHCHARS, str, len, encoded, 1024)){
dprintf("VFD: Text conversion failed: %ld", GetLastError());
return;
}
dprintf("VFD: Text: %ls\n", encoded);
} else {
dprintf("VFD: Text: %s\n", str);
}
}
static HRESULT vfd_handle_irp(struct irp *irp)
{
HRESULT hr;
@ -58,67 +126,274 @@ static HRESULT vfd_handle_irp(struct irp *irp)
return iohook_invoke_next(irp);
}
if (irp->op == IRP_OP_OPEN){
dprintf("VFD: Open\n");
} else if (irp->op == IRP_OP_CLOSE){
dprintf("VFD: Close\n");
}
hr = uart_handle_irp(&vfd_uart, irp);
if (FAILED(hr) || irp->op != IRP_OP_WRITE) {
return hr;
}
uint8_t cmd = 0;
uint8_t str_1[512];
uint8_t str_2[512];
uint8_t str_1_len = 0;
uint8_t str_2_len = 0;
for (size_t i = 0; i < vfd_uart.written.pos; i++) {
if (vfd_uart.written.bytes[i] == 0x1B) {
i++;
cmd = vfd_uart.written.bytes[i];
if (cmd == 0x30) {
i += 3;
}
else if (cmd == 0x50) {
i++;
}
continue;
}
if (cmd == 0x30) {
str_1[str_1_len++] = vfd_uart.written.bytes[i];
}
else if (cmd == 0x50) {
str_2[str_2_len++] = vfd_uart.written.bytes[i];
}
}
#if SUPER_VERBOSE
dprintf("VFD TX:\n");
dump_iobuf(&vfd_uart.written);
#endif
if (str_1_len) {
str_1[str_1_len++] = '\0';
if (codepage != 932) {
WCHAR buffer[512];
MultiByteToWideChar(932, 0, (LPCSTR)str_1, str_1_len, buffer, str_1_len);
char str_recode[str_1_len * 3];
WideCharToMultiByte(codepage, 0, buffer, str_1_len, str_recode, str_1_len * 3, NULL, NULL);
dprintf("VFD: %s\n", str_recode);
}
else {
dprintf("VFD: %s\n", str_1);
}
}
struct const_iobuf reader;
iobuf_flip(&reader, &vfd_uart.written);
if (str_2_len) {
str_2[str_2_len++] = '\0';
if (codepage != 932) {
WCHAR buffer[512];
MultiByteToWideChar(932, 0, (LPCSTR)str_2, str_2_len, buffer, str_2_len);
char str_recode[str_2_len * 3];
WideCharToMultiByte(codepage, 0, buffer, str_2_len, str_recode, str_2_len * 3, NULL, NULL);
dprintf("VFD: %s\n", str_recode);
struct iobuf* writer = &vfd_uart.readable;
for (; reader.pos < reader.nbytes ; ){
if (vfd_frame_sync(&reader)) {
reader.pos++; // get the sync byte out of the way
uint8_t cmd;
iobuf_read_8(&reader, &cmd);
if (cmd == VFD_CMD_GET_VERSION) {
hr = vfd_handle_get_version(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_RESET) {
hr = vfd_handle_reset(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_CLEAR_SCREEN) {
hr = vfd_handle_clear_screen(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_SET_BRIGHTNESS) {
hr = vfd_handle_set_brightness(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_SET_SCREEN_ON) {
hr = vfd_handle_set_screen_on(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_SET_H_SCROLL) {
hr = vfd_handle_set_h_scroll(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_DRAW_IMAGE) {
hr = vfd_handle_draw_image(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_SET_CURSOR) {
hr = vfd_handle_set_cursor(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_SET_ENCODING) {
hr = vfd_handle_set_encoding(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_SET_TEXT_WND) {
hr = vfd_handle_set_text_wnd(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_SET_TEXT_SPEED) {
hr = vfd_handle_set_text_speed(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_WRITE_TEXT) {
hr = vfd_handle_write_text(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_ENABLE_SCROLL) {
hr = vfd_handle_enable_scroll(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_DISABLE_SCROLL) {
hr = vfd_handle_disable_scroll(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_ROTATE) {
hr = vfd_handle_rotate(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_CREATE_CHAR) {
hr = vfd_handle_create_char(&reader, writer, &vfd_uart);
} else if (cmd == VFD_CMD_CREATE_CHAR2) {
hr = vfd_handle_create_char2(&reader, writer, &vfd_uart);
} else {
dprintf("VFD: Unknown command 0x%x\n", cmd);
dump_const_iobuf(&reader);
hr = S_FALSE;
}
} else {
dprintf("VFD: %s\n", str_2);
// if no sync byte is sent, we are just getting plain text...
if (reader.pos < reader.nbytes){
int len = 0;
// read chars until we hit a new sync byte or the data ends
while (reader.pos + len + 1 < reader.nbytes && reader.bytes[reader.pos + len] != VFD_SYNC_BYTE && reader.bytes[reader.pos + len] != VFD_SYNC_BYTE2){
len++;
}
char* str = malloc(len);
memset(str, 0, len);
iobuf_read(&reader, str, len);
print_vfd_text(str, len);
free(str);
reader.pos += len;
}
}
if (!SUCCEEDED(hr)){
return hr;
}
}
// dprintf("VFD TX:\n");
// dump_iobuf(&vfd_uart.written);
vfd_uart.written.pos = 0;
return hr;
}
HRESULT vfd_handle_get_version(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
dprintf("VFD: Get Version\n");
struct vfd_resp_board_info resp;
memset(&resp, 0, sizeof(resp));
resp.unk1 = 2;
strcpy(resp.version, "01.20");
resp.unk2 = 1;
return vfd_frame_encode(writer, &resp, sizeof(resp));
}
HRESULT vfd_handle_reset(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
dprintf("VFD: Reset\n");
encoding = VFD_ENC_SHIFT_JIS;
return S_FALSE;
}
HRESULT vfd_handle_clear_screen(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
dprintf("VFD: Clear Screen\n");
return S_FALSE;
}
HRESULT vfd_handle_set_brightness(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
uint8_t b;
iobuf_read_8(reader, &b);
if (b > 4){
dprintf("VFD: Brightness, invalid argument\n");
return E_FAIL;
}
dprintf("VFD: Brightness, %d\n", b);
return S_FALSE;
}
HRESULT vfd_handle_set_screen_on(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
uint8_t b;
iobuf_read_8(reader, &b);
if (b > 1){
dprintf("VFD: Screen Power, invalid argument\n");
return E_FAIL;
}
dprintf("VFD: Screen Power, %d\n", b);
return S_FALSE;
}
HRESULT vfd_handle_set_h_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
uint8_t x;
iobuf_read_8(reader, &x);
dprintf("VFD: Horizontal Scroll, X=%d\n", x);
return S_FALSE;
}
HRESULT vfd_handle_draw_image(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
int w, h;
uint16_t x0, x1;
uint8_t y0, y1;
uint8_t image[2048];
iobuf_read_be16(reader, &x0);
iobuf_read_8(reader, &y0);
iobuf_read_be16(reader, &x1);
iobuf_read_8(reader, &y1);
w = x1 - x0;
h = y1 - y0;
iobuf_read(reader, image, w*h);
dprintf("VFD: Draw image, %dx%d\n", w, h);
return S_FALSE;
}
HRESULT vfd_handle_set_cursor(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
uint16_t x;
uint8_t y;
iobuf_read_be16(reader, &x);
iobuf_read_8(reader, &y);
dprintf("VFD: Set Cursor, x=%d,y=%d\n", x, y);
return S_FALSE;
}
HRESULT vfd_handle_set_encoding(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
uint8_t b;
iobuf_read_8(reader, &b);
dprintf("VFD: Set Encoding, %d (%s)\n", b, get_encoding_name(b));
if (b < 0 || b > VFD_ENC_MAX){
dprintf("Invalid encoding specified\n");
return E_FAIL;
}
encoding = b;
return S_FALSE;
}
HRESULT vfd_handle_set_text_wnd(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
uint16_t x0, x1;
uint8_t y0, y1;
iobuf_read_be16(reader, &x0);
iobuf_read_8(reader, &y0);
iobuf_read_be16(reader, &x1);
iobuf_read_8(reader, &y1);
dprintf("VFD: Set Text Window, p0:%d,%d, p1:%d,%d\n", x0, y0, x1, y1);
return S_FALSE;
}
HRESULT vfd_handle_set_text_speed(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
uint8_t b;
iobuf_read_8(reader, &b);
dprintf("VFD: Set Text Speed, %d\n", b);
return S_FALSE;
}
HRESULT vfd_handle_write_text(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
uint8_t len;
iobuf_read_8(reader, &len);
char* str = malloc(len);
iobuf_read(reader, str, len);
print_vfd_text(str, len);
free(str);
return S_FALSE;
}
HRESULT vfd_handle_enable_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
dprintf("VFD: Enable Scrolling\n");
return S_FALSE;
}
HRESULT vfd_handle_disable_scroll(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
dprintf("VFD: Disable Scrolling\n");
return S_FALSE;
}
HRESULT vfd_handle_rotate(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
uint8_t b;
iobuf_read_8(reader, &b);
dprintf("VFD: Rotate, %d\n", b);
return S_FALSE;
}
HRESULT vfd_handle_create_char(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
uint8_t b;
iobuf_read_8(reader, &b);
char buf[32];
iobuf_read(reader, buf, 32);
dprintf("VFD: Create character, %d\n", b);
return S_FALSE;
}
HRESULT vfd_handle_create_char2(struct const_iobuf* reader, struct iobuf* writer, struct uart* vfd_uart){
uint8_t b, b2;
iobuf_read_8(reader, &b);
iobuf_read_8(reader, &b2);
char buf[16];
iobuf_read(reader, buf, 16);
dprintf("VFD: Create character, %d, %d\n", b, b2);
return S_FALSE;
}

View File

@ -4,7 +4,10 @@
struct vfd_config {
bool enable;
unsigned int port_no;
bool utf_conversion;
};
HRESULT vfd_hook_init(const struct vfd_config *cfg, unsigned int port_no);
HRESULT vfd_hook_init(struct vfd_config *cfg, unsigned int default_port_no);

View File

@ -53,6 +53,7 @@
#include "platform/platform.h"
#include "util/dprintf.h"
#include "util/env.h"
static HMODULE carol_hook_mod;
static process_entry_t carol_startup;
@ -100,7 +101,7 @@ static DWORD CALLBACK carol_pre_startup(void)
/* Config load */
carol_hook_config_load(&carol_hook_cfg, L".\\segatools.ini");
carol_hook_config_load(&carol_hook_cfg, get_config_path());
/* Hook Win32 APIs */
@ -164,7 +165,7 @@ static DWORD CALLBACK carol_pre_startup(void)
}
/* Initialize debug helpers */
spike_hook_init(L".\\segatools.ini");
spike_hook_init(get_config_path());
dprintf("--- End carol_pre_startup ---\n");

View File

@ -4,7 +4,6 @@ shared_library(
include_directories : inc,
implicit_include_directories : false,
vs_module_defs : 'carolhook.def',
c_pch : '../precompiled.h',
dependencies : [
capnhook.get_variable('hook_dep'),
capnhook.get_variable('hooklib_dep'),

View File

@ -8,6 +8,7 @@
#include "carolio/carolio.h"
#include "carolio/config.h"
#include "util/dprintf.h"
#include "util/env.h"
static unsigned int __stdcall carol_io_touch_thread_proc(void *ctx);
@ -25,7 +26,7 @@ uint16_t carol_io_get_api_version(void)
HRESULT carol_io_jvs_init(void)
{
carol_io_config_load(&carol_io_cfg, L".\\segatools.ini");
carol_io_config_load(&carol_io_cfg, get_config_path());
return S_OK;
}
@ -178,4 +179,4 @@ static unsigned int __stdcall carol_io_touch_thread_proc(void *ctx)
}
return 0;
}
}

View File

@ -3,7 +3,6 @@ carolio_lib = static_library(
name_prefix : '',
include_directories : inc,
implicit_include_directories : false,
c_pch : '../precompiled.h',
sources : [
'carolio.c',
'carolio.h',

View File

@ -3,6 +3,7 @@
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include "amex/amex.h"
#include "amex/config.h"

View File

@ -36,6 +36,7 @@
#include "platform/platform.h"
#include "util/dprintf.h"
#include "util/env.h"
static HMODULE chuni_hook_mod;
static process_entry_t chuni_startup;
@ -71,7 +72,7 @@ static DWORD CALLBACK chuni_pre_startup(void)
/* Config load */
chuni_hook_config_load(&chuni_hook_cfg, L".\\segatools.ini");
chuni_hook_config_load(&chuni_hook_cfg, get_config_path());
/* Hook Win32 APIs */
@ -129,7 +130,7 @@ static DWORD CALLBACK chuni_pre_startup(void)
/* Initialize debug helpers */
spike_hook_init(L".\\segatools.ini");
spike_hook_init(get_config_path());
dprintf("--- End chuni_pre_startup ---\n");

View File

@ -4,7 +4,6 @@ shared_library(
include_directories : inc,
implicit_include_directories : false,
vs_module_defs : 'chunihook.def',
c_pch : '../precompiled.h',
dependencies : [
capnhook.get_variable('hook_dep'),
capnhook.get_variable('hooklib_dep'),

View File

@ -4,12 +4,14 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "chuniio/chuniio.h"
#include "chuniio/config.h"
#include "chuniio/ledoutput.h"
#include "util/dprintf.h"
#include "util/env.h"
static unsigned int __stdcall chuni_io_slider_thread_proc(void *ctx);
@ -27,7 +29,7 @@ uint16_t chuni_io_get_api_version(void)
HRESULT chuni_io_jvs_init(void)
{
chuni_io_config_load(&chuni_io_cfg, L".\\segatools.ini");
chuni_io_config_load(&chuni_io_cfg, get_config_path());
led_init_mutex = CreateMutex(
NULL, // default security attributes
@ -92,7 +94,7 @@ void chuni_io_jvs_poll(uint8_t *opbtn, uint8_t *beams)
} else {
// Use actual AIR
for (i = 0; i < 6; i++) {
if(GetAsyncKeyState(chuni_io_cfg.vk_ir[i]) & 0x8000) {
if (GetAsyncKeyState(chuni_io_cfg.vk_ir[i]) & 0x8000) {
*beams |= (1 << i);
} else {
*beams &= ~(1 << i);

View File

@ -3,6 +3,7 @@
#include <assert.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "chuniio/config.h"

View File

@ -2,6 +2,7 @@
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
struct chuni_io_config {
uint8_t vk_test;

View File

@ -13,10 +13,10 @@
// This struct is used to send data related to the slider and billboard LEDs
struct _chuni_led_data_buf_t {
byte framing; // Sync byte
uint8_t framing; // Sync byte
uint8_t board; // LED output the data is for (0-1: billboard, 2: slider)
byte data[LED_OUTPUT_DATA_SIZE_MAX]; // Buffer for LEDs
byte data_len; // How many bytes to output from the buffer
uint8_t data[LED_OUTPUT_DATA_SIZE_MAX]; // Buffer for LEDs
uint8_t data_len; // How many bytes to output from the buffer
};
static byte chuni_led_board_data_lens[LED_BOARDS_TOTAL] = {53*3, 63*3, 31*3};
static uint8_t chuni_led_board_data_lens[LED_BOARDS_TOTAL] = {53*3, 63*3, 31*3};

View File

@ -73,14 +73,14 @@ struct _chuni_led_data_buf_t* escape_led_data(struct _chuni_led_data_buf_t* unes
{
struct _chuni_led_data_buf_t* out_struct = &led_escaped_buf[unescaped->board];
byte* in_buf = unescaped->data;
byte* out_buf = out_struct->data;
uint8_t* in_buf = unescaped->data;
uint8_t* out_buf = out_struct->data;
int i = 0;
int o = 0;
while (i < unescaped->data_len)
{
byte b = in_buf[i++];
uint8_t b = in_buf[i++];
if (b == LED_PACKET_FRAMING || b == LED_PACKET_ESCAPE)
{
out_buf[o++] = LED_PACKET_ESCAPE;
@ -94,7 +94,7 @@ struct _chuni_led_data_buf_t* escape_led_data(struct _chuni_led_data_buf_t* unes
return out_struct;
}
void led_output_update(uint8_t board, const byte* rgb)
void led_output_update(uint8_t board, const uint8_t* rgb)
{
if (board < 0 || board > 2 || !any_outputs_enabled)
{

View File

@ -16,4 +16,4 @@
extern HANDLE led_init_mutex;
HRESULT led_output_init(struct chuni_io_config* const cfg);
void led_output_update(uint8_t board, const byte* rgb);
void led_output_update(uint8_t board, const uint8_t* rgb);

View File

@ -3,7 +3,6 @@ chuniio_lib = static_library(
name_prefix : '',
include_directories : inc,
implicit_include_directories : false,
c_pch : '../precompiled.h',
sources : [
'chu2to3.c',

View File

@ -98,7 +98,7 @@ void led_serial_update(struct _chuni_led_data_buf_t* data)
ReleaseMutex(serial_write_mutex);
}
void led_serial_update_openithm(const byte* rgb)
void led_serial_update_openithm(const uint8_t* rgb)
{
if (serial_port != INVALID_HANDLE_VALUE)
{

View File

@ -8,9 +8,10 @@
#pragma once
#include <windows.h>
#include <stdint.h>
#include "chuniio/leddata.h"
HRESULT led_serial_init(wchar_t led_com[12], DWORD baud);
void led_serial_update(struct _chuni_led_data_buf_t* data);
void led_serial_update_openithm(const byte* rgb);
void led_serial_update_openithm(const uint8_t* rgb);

View File

@ -2,6 +2,7 @@
#include <assert.h>
#include <stdlib.h>
#include <stdlib.h>
#include "chuniio/chu2to3.h"
#include "chusanhook/chuni-dll.h"

View File

@ -1,5 +1,6 @@
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include "board/config.h"

View File

@ -49,6 +49,7 @@
#include "platform/platform.h"
#include "util/dprintf.h"
#include "util/env.h"
static HMODULE chusan_hook_mod;
static process_entry_t chusan_startup;
@ -84,7 +85,7 @@ static DWORD CALLBACK chusan_pre_startup(void)
/* Config load */
chusan_hook_config_load(&chusan_hook_cfg, L".\\segatools.ini");
chusan_hook_config_load(&chusan_hook_cfg, get_config_path());
/* Hook Win32 APIs */
@ -173,7 +174,7 @@ static DWORD CALLBACK chusan_pre_startup(void)
/* Initialize debug helpers */
spike_hook_init(L".\\segatools.ini");
spike_hook_init(get_config_path());
dprintf("--- End chusan_pre_startup ---\n");

View File

@ -4,7 +4,6 @@ shared_library(
include_directories : inc,
implicit_include_directories : false,
vs_module_defs : 'chusanhook.def',
c_pch : '../precompiled.h',
dependencies : [
capnhook.get_variable('hook_dep'),
capnhook.get_variable('hooklib_dep'),

View File

@ -1,5 +1,6 @@
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include "board/config.h"

View File

@ -35,6 +35,7 @@
#include "unityhook/hook.h"
#include "util/dprintf.h"
#include "util/env.h"
static HMODULE cm_hook_mod;
static process_entry_t cm_startup;
@ -48,7 +49,7 @@ static DWORD CALLBACK cm_pre_startup(void)
/* Load config */
cm_hook_config_load(&cm_hook_cfg, L".\\segatools.ini");
cm_hook_config_load(&cm_hook_cfg, get_config_path());
/* Hook Win32 APIs */
@ -101,11 +102,11 @@ static DWORD CALLBACK cm_pre_startup(void)
There seems to be an issue with other DLL hooks if `LoadLibraryW` is
hooked earlier in the `cmhook` initialization. */
unity_hook_init(&cm_hook_cfg.unity, cm_hook_mod);
unity_hook_init(&cm_hook_cfg.unity, cm_hook_mod, NULL);
/* Initialize debug helpers */
spike_hook_init(L".\\segatools.ini");
spike_hook_init(get_config_path());
dprintf("--- End cm_pre_startup ---\n");

View File

@ -4,7 +4,6 @@ shared_library(
include_directories : inc,
implicit_include_directories : false,
vs_module_defs : 'cmhook.def',
c_pch : '../precompiled.h',
dependencies : [
capnhook.get_variable('hook_dep'),
capnhook.get_variable('hooklib_dep'),

View File

@ -6,6 +6,7 @@
#include "cmio/cmio.h"
#include "cmio/config.h"
#include "util/env.h"
static uint8_t cm_opbtn;
static struct cm_io_config cm_io_cfg;
@ -18,7 +19,7 @@ uint16_t cm_io_get_api_version(void)
HRESULT cm_io_init(void)
{
cm_io_config_load(&cm_io_cfg, L".\\segatools.ini");
cm_io_config_load(&cm_io_cfg, get_config_path());
return S_OK;
}

View File

@ -3,7 +3,6 @@ cmio_lib = static_library(
name_prefix : '',
include_directories : inc,
implicit_include_directories : false,
c_pch : '../precompiled.h',
sources : [
'cmio.c',
'cmio.h',

View File

@ -3,6 +3,7 @@
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include "amex/amex.h"
#include "amex/config.h"

View File

@ -23,6 +23,7 @@
#include "platform/platform.h"
#include "util/dprintf.h"
#include "util/env.h"
static HMODULE cxb_hook_mod;
static process_entry_t cxb_startup;
@ -58,7 +59,7 @@ static DWORD CALLBACK cxb_pre_startup(void)
/* Config load */
cxb_hook_config_load(&cxb_hook_cfg, L".\\segatools.ini");
cxb_hook_config_load(&cxb_hook_cfg, get_config_path());
/* Hook Win32 APIs */
@ -110,7 +111,7 @@ static DWORD CALLBACK cxb_pre_startup(void)
/* Initialize debug helpers */
spike_hook_init(L".\\segatools.ini");
spike_hook_init(get_config_path());
dprintf("--- End cxb_pre_startup ---\n");

View File

@ -1,6 +1,9 @@
#include <windows.h>
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "cxbhook/led.h"
#include "cxbhook/cxb-dll.h"

View File

@ -4,7 +4,6 @@ shared_library(
include_directories : inc,
implicit_include_directories : false,
vs_module_defs : 'cxbhook.def',
c_pch : '../precompiled.h',
dependencies : [
capnhook.get_variable('hook_dep'),
capnhook.get_variable('hooklib_dep'),

View File

@ -1,6 +1,9 @@
#include <windows.h>
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <winuser.h>
#include "cxbhook/revio.h"

View File

@ -8,6 +8,7 @@
#include "cxbio/config.h"
#include "util/dprintf.h"
#include "util/env.h"
static bool cxb_io_coin;
static int cxb_io_coins;
@ -21,7 +22,7 @@ uint16_t cxb_io_get_api_version(void)
HRESULT cxb_io_revio_init(void)
{
dprintf("CXB IO: REVIO init\n");
cxb_io_config_load(&cxb_io_cfg, L".\\segatools.ini");
cxb_io_config_load(&cxb_io_cfg, get_config_path());
return S_OK;
}
@ -75,4 +76,4 @@ HRESULT cxb_io_led_init(void)
}
void cxb_io_led_update(int id, int color)
{}
{}

View File

@ -3,7 +3,6 @@ cxbio_lib = static_library(
name_prefix : '',
include_directories : inc,
implicit_include_directories : false,
c_pch : '../precompiled.h',
sources : [
'cxbio.c',
'cxbio.h',

View File

@ -64,6 +64,8 @@ subnet=192.168.126.0
; -----------------------------------------------------------------------------
[gfx]
; Enables the graphics hook.
enable=1
; Force the game to run windowed.
windowed=1
; Add a frame to the game window if running windowed.

View File

@ -56,6 +56,8 @@ subnet=192.168.139.0
; -----------------------------------------------------------------------------
[gfx]
; Enables the graphics hook.
enable=1
; Force the game to run windowed.
windowed=1
; Add a frame to the game window if running windowed.

View File

@ -25,7 +25,7 @@ aimePath=DEVICE\aime.txt
;highBaud=1
[vfd]
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
; Enable VFD emulation. Disable to use a real VFD
; GP1232A02A FUTABA assembly.
enable=1
@ -82,6 +82,8 @@ dipsw3=1
; -----------------------------------------------------------------------------
[gfx]
; Enables the graphics hook.
enable=1
; Force the game to run windowed.
windowed=1
; Add a frame to the game window if running windowed.

View File

@ -23,7 +23,7 @@ enable=1
aimePath=DEVICE\aime.txt
[vfd]
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
; Enable VFD emulation. Disable to use a real VFD
; GP1232A02A FUTABA assembly.
enable=1

View File

@ -75,6 +75,8 @@ path=../DEVICE/sram.bin
; -----------------------------------------------------------------------------
[gfx]
; Enables the graphics hook.
enable=1
; Force the game to run windowed.
windowed=1
; Add a frame to the game window if running windowed.

View File

@ -5,7 +5,7 @@
[vfs]
; Insert the path to the game AMFS directory here (contains ICF1 and ICF2)
amfs=
; Insert the path to the game Option directory here (contains Axxx directories)
; Insert the path to the game Option (mdata) directory here (contains Mxxx directories)
option=
; Create an empty directory somewhere and insert the path here.
; This directory may be shared between multiple SEGA games.
@ -36,6 +36,10 @@ default=127.0.0.1
; Chunithm is extremely picky about its LAN environment, so leaving this
; setting enabled is strongly recommended.
enable=1
; The final octet of the local host's IP address on the virtualized subnet (so,
; if the keychip subnet is `192.168.32.0` and this value is set to `11`, then the
; local host's virtualized LAN IP is `192.168.32.11`).
addrSuffix=11
; -----------------------------------------------------------------------------
; Board settings
@ -54,6 +58,18 @@ dipsw1=1
; that subnet must start with 192.168.
subnet=192.168.78.0
; -----------------------------------------------------------------------------
; Misc. hooks settings
; -----------------------------------------------------------------------------
[gfx]
; Enables the graphics hook.
enable=1
; Force the game to run windowed.
windowed=1
; Add a frame to the game window if running windowed.
framed=0
; -----------------------------------------------------------------------------
; Custom IO settings
; -----------------------------------------------------------------------------

View File

@ -23,7 +23,7 @@ enable=1
aimePath=DEVICE\aime.txt
[vfd]
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
; Enable VFD emulation. Disable to use a real VFD
; GP1232A02A FUTABA assembly.
enable=1
@ -85,6 +85,14 @@ freeplay=0
; Misc. hook settings
; -----------------------------------------------------------------------------
[gfx]
; Enables the graphics hook.
enable=1
; Force the game to run windowed.
windowed=0
; Add a frame to the game window if running windowed.
framed=0
[touch]
; WinTouch emulation setting.
enable=1

View File

@ -75,6 +75,11 @@ dipsw3=0
dipsw4=0
dipsw5=0
[ffb]
; Enable force feedback (838-15069) board emulation. This is required for
; both DirectInput and XInput steering wheel effects.
enable=1
; -----------------------------------------------------------------------------
; LED settings
; -----------------------------------------------------------------------------
@ -231,6 +236,20 @@ reverseAccelAxis=0
reverseBrakeAxis=0
; Force feedback settings.
; Strength of the force feedback spring effect in percent. Possible values
; are 0-100.
centerSpringStrength=30
; Only works when FFB board emulation is enabled!
;
; It is recommended to change the strength inside the Game Test Mode!
;
; These settings are only used when using DirectInput for the wheel.
; The values are in the range 0%-100%, where 0 disables the effect and
; 100 is the maximum.
; Constant force strength, used for centering spring effect.
constantForceStrength=100
; Damper strength, used for steering wheel damper effect.
damperStrength=100
; Rumble strength, used for road surface effects.
rumbleStrength=100
; Rumble duration factor from ms to µs, used to scale the duration of the rumble effect.
rumbleDuration=1000

View File

@ -69,6 +69,20 @@ region=4
; exactly one machine and set this to 0 on all others.
dipsw1=1
[ffb]
; Enable force feedback (838-15069) board emulation. This is required for
; both DirectInput and XInput steering wheel effects.
enable=1
; -----------------------------------------------------------------------------
; LED settings
; -----------------------------------------------------------------------------
[led15070]
; Enable emulation of the 837-15070-02 controlled lights, which handle the
; cabinet and seat LEDs.
enable=1
; -----------------------------------------------------------------------------
; Misc. hooks settings
; -----------------------------------------------------------------------------
@ -212,6 +226,20 @@ reverseAccelAxis=0
reverseBrakeAxis=0
; Force feedback settings.
; Strength of the force feedback spring effect in percent. Possible values
; are 0-100.
centerSpringStrength=30
; Only works when FFB board emulation is enabled!
;
; It is recommended to change the strength inside the Game Test Mode!
;
; These settings are only used when using DirectInput for the wheel.
; The values are in the range 0%-100%, where 0 disables the effect and
; 100 is the maximum.
; Constant force strength, used for centering spring effect.
constantForceStrength=100
; Damper strength, used for steering wheel damper effect.
damperStrength=100
; Rumble strength, used for road surface effects.
rumbleStrength=100
; Rumble duration factor from ms to µs, used to scale the duration of the rumble effect.
rumbleDuration=1000

5
dist/idz/start.bat vendored
View File

@ -2,10 +2,11 @@
pushd %~dp0
inject -k idzhook.dll InitialD0_DX11_Nu.exe
start /min "AM Daemon" inject -d -k idzhook.dll amdaemon.exe -c configDHCP_Final_Common.json configDHCP_Final_JP.json configDHCP_Final_JP_ST1.json configDHCP_Final_JP_ST2.json configDHCP_Final_EX.json configDHCP_Final_EX_ST1.json configDHCP_Final_EX_ST2.json
rem Set dipsw1=0 and uncomment the ServerBox for in store battle?
rem inject -k idzhook.dll ServerBoxD8_Nu_x64.exe
inject -d -k idzhook.dll amdaemon.exe -c configDHCP_Final_Common.json configDHCP_Final_JP.json configDHCP_Final_JP_ST1.json configDHCP_Final_JP_ST2.json configDHCP_Final_EX.json configDHCP_Final_EX_ST1.json configDHCP_Final_EX_ST2.json
inject -d -k idzhook.dll InitialD0_DX11_Nu.exe
taskkill /im ServerBoxD8_Nu_x64.exe > nul 2>&1

150
dist/kemono/segatools.ini vendored Normal file
View File

@ -0,0 +1,150 @@
; -----------------------------------------------------------------------------
; Path settings
; -----------------------------------------------------------------------------
[vfs]
; Insert the path to the game AMFS directory here (contains ICF1 and ICF2)
amfs=
; Insert the path to the game Option directory here (contains Axxx directories)
option=
; Create an empty directory somewhere and insert the path here.
; This directory may be shared between multiple SEGA games.
; NOTE: This has nothing to do with Windows %APPDATA%.
appdata=
; -----------------------------------------------------------------------------
; Device settings
; -----------------------------------------------------------------------------
[aime]
; Enable Aime card reader assembly emulation. Disable to use a real SEGA Aime
; reader.
enable=1
aimePath=DEVICE\aime.txt
[vfd]
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
; GP1232A02A FUTABA assembly.
enable=1
; -----------------------------------------------------------------------------
; Network settings
; -----------------------------------------------------------------------------
[dns]
; Insert the hostname or IP address of the server you wish to use here.
; Note that 127.0.0.1, localhost etc are specifically rejected.
default=127.0.0.1
[netenv]
; Simulate an ideal LAN environment. This may interfere with head-to-head play.
; SEGA games are somewhat picky about its LAN environment, so leaving this
; setting enabled is recommended.
enable=1
; The final octet of the local host's IP address on the virtualized subnet (so,
; if the keychip subnet is `192.168.32.0` and this value is set to `11`, then the
; local host's virtualized LAN IP is `192.168.32.11`).
addrSuffix=11
; -----------------------------------------------------------------------------
; Board settings
; -----------------------------------------------------------------------------
[keychip]
; The /24 LAN subnet that the emulated keychip will tell the game to expect.
; If you disable netenv then you must set this to your LAN's IP subnet, and
; that subnet must start with 192.168.
subnet=192.168.179.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
; Chassis Test button virtual-key code. Default is the 4 key.
test=0x34
; Chassis Service button virtual-key code. Default is the 5 key.
service=0x35
; -----------------------------------------------------------------------------
; Misc. hook settings
; -----------------------------------------------------------------------------
[unity]
; Enable Unity hook. This will allow you to run custom .NET code before the game
enable=1
; Path to a .NET DLL that should run before the game. Useful for loading
; modding frameworks such as BepInEx.
;
; NOTE: For Kemono Friends, BepInEx (or similar) should be installed to the main folder, not the "UnityApp" folder.
targetAssembly=
[printer]
; Sinfonia CHC-C300 printer emulation setting.
enable=1
; Change the printer serial number here.
serial_no="5A-A123"
; Insert the path to the image output directory here.
printerOutPath="DEVICE\print"
; The length in milliseconds the printer should be busy printing.
; Set to 0 to instantly finish printing.
waitTime=20000
; -----------------------------------------------------------------------------
; LED settings
; -----------------------------------------------------------------------------
[led15093]
; 837-15093-06 LED board emulation setting.
enable=1
; -----------------------------------------------------------------------------
; Custom IO settings
; -----------------------------------------------------------------------------
[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=
[kemonoio]
; To use a custom Kemono IO DLL enter its path here.
; Leave empty if you want to use Segatools built-in keyboard input.
path=
; -----------------------------------------------------------------------------
; Input settings
; -----------------------------------------------------------------------------
; Keyboard bindings are specified as hexadecimal (prefixed with 0x) or decimal
; (not prefixed with 0x) virtual-key codes, a list of which can be found here:
;
; https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes
;
; This is, admittedly, not the most user-friendly configuration method in the
; world. An improved solution will be provided later.
[io3]
; 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
; Analog lever (which is actually just four buttons, and not real analog input, default: Arrow keys)
left=0x25
right=0x27
up=0x26
down=0x28
; Controller face buttons (default A, S, D)
red=0x41
green=0x53
blue=0x44
; Menu confirmation key (default RETURN)
start=0x0D

12
dist/kemono/start.bat vendored Normal file
View File

@ -0,0 +1,12 @@
@echo off
pushd %~dp0
start "AM Daemon" /min inject_x64 -d -k kemonohook_x64.dll amdaemon.exe -c config.json
inject_x86 -d -k kemonohook_x86.dll UnityApp\Parade -screen-fullscreen 0 -popupwindow -screen-width 720 -screen-height 1280 -silent-crashes
taskkill /f /im amdaemon.exe > nul 2>&1
echo.
echo Game processes have terminated
pause

View File

@ -23,7 +23,7 @@ enable=1
aimePath=DEVICE\aime.txt
[vfd]
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
; Enable VFD emulation. Disable to use a real VFD
; GP1232A02A FUTABA assembly.
enable=1

View File

@ -23,7 +23,7 @@ enable=1
aimePath=DEVICE\aime.txt
[vfd]
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
; Enable VFD emulation. Disable to use a real VFD
; GP1232A02A FUTABA assembly.
enable=1
@ -74,6 +74,7 @@ dipsw1=1
; -----------------------------------------------------------------------------
[gfx]
; Enables the graphics hook.
enable=1
; Hooks related to the touch boards

View File

@ -23,7 +23,7 @@ enable=1
aimePath=DEVICE\aime.txt
[vfd]
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
; Enable VFD emulation. Disable to use a real VFD
; GP1232A02A FUTABA assembly.
enable=1
@ -70,6 +70,7 @@ dipsw1=1
; -----------------------------------------------------------------------------
[gfx]
; Enables the graphics hook.
enable=1
[unity]
@ -190,7 +191,7 @@ leftSide=0x01 ; Mouse Left
rightSide=0x02 ; Mouse Right
right1=0x4A ; J
right1=0x4B ; K
right2=0x4B ; K
right3=0x4C ; L
leftMenu=0x55 ; U

View File

@ -23,7 +23,7 @@ enable=1
aimePath=DEVICE\aime.txt
[vfd]
; Enable VFD emulation (currently just stubbed). Disable to use a real VFD
; Enable VFD emulation. Disable to use a real VFD
; GP1232A02A FUTABA assembly.
enable=1
@ -65,6 +65,11 @@ enable=1
; allow you to start a game in freeplay mode.
freeplay=0
[ffb]
; Enable force feedback (838-15069) board emulation. This is required for
; both DirectInput and XInput steering wheel effects.
enable=1
; -----------------------------------------------------------------------------
; Custom IO settings
; -----------------------------------------------------------------------------
@ -181,6 +186,20 @@ reverseAccelAxis=0
reverseBrakeAxis=0
; Force feedback settings.
; Strength of the force feedback spring effect in percent. Possible values
; are 0-100.
centerSpringStrength=30
; Only works when FFB board emulation is enabled!
;
; It is recommended to change the strength inside the Game Test Mode!
;
; These settings are only used when using DirectInput for the wheel.
; The values are in the range 0%-100%, where 0 disables the effect and
; 100 is the maximum.
; Constant force strength, used for centering spring effect.
constantForceStrength=100
; Damper strength, used for steering wheel damper effect.
damperStrength=100
; Rumble strength, used for road surface effects.
rumbleStrength=100
; Rumble duration factor from ms to µs, used to scale the duration of the rumble effect.
rumbleDuration=1000

View File

@ -8,6 +8,9 @@
#include "board/config.h"
#include "board/sg-reader.h"
#include "hooklib/config.h"
#include "hooklib/dvd.h"
#include "divahook/config.h"
#include "platform/config.h"
@ -47,6 +50,8 @@ void diva_hook_config_load(
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);
diva_dll_config_load(&cfg->dll, filename);
slider_config_load(&cfg->slider, filename);
}

View File

@ -6,15 +6,23 @@
#include "board/sg-reader.h"
#include "hooklib/dvd.h"
#include "hooklib/touch.h"
#include "gfxhook/config.h"
#include "platform/config.h"
#include "divahook/diva-dll.h"
#include "divahook/slider.h"
#include "platform/platform.h"
struct diva_hook_config {
struct platform_config platform;
struct amex_config amex;
struct aime_config aime;
struct dvd_config dvd;
struct gfx_config gfx;
struct touch_screen_config touch;
struct diva_dll_config dll;
struct slider_config slider;
};

View File

@ -22,6 +22,9 @@
#include "divahook/jvs.h"
#include "divahook/slider.h"
#include "gfxhook/gfx.h"
#include "gfxhook/gl.h"
#include "hook/process.h"
#include "hooklib/serial.h"
@ -30,6 +33,7 @@
#include "platform/platform.h"
#include "util/dprintf.h"
#include "util/env.h"
static HMODULE diva_hook_mod;
static process_entry_t diva_startup;
@ -38,15 +42,30 @@ static struct diva_hook_config diva_hook_cfg;
static DWORD CALLBACK diva_pre_startup(void)
{
HRESULT hr;
HMODULE dbghelp;
dprintf("--- Begin diva_pre_startup ---\n");
/* Pin dbghelp so the path hooks apply to it. */
dbghelp = LoadLibraryW(L"dbghelp.dll");
if (dbghelp != NULL) {
dprintf("Pinned debug helper library, hMod=%p\n", dbghelp);
}
else {
dprintf("Failed to load debug helper library!\n");
}
/* Config load */
diva_hook_config_load(&diva_hook_cfg, L".\\segatools.ini");
diva_hook_config_load(&diva_hook_cfg, get_config_path());
/* Hook Win32 APIs */
dvd_hook_init(&diva_hook_cfg.dvd, diva_hook_mod);
gfx_hook_init(&diva_hook_cfg.gfx);
gfx_gl_hook_init(&diva_hook_cfg.gfx, diva_hook_mod);
serial_hook_init();
/* Initialize emulation hooks */
@ -87,7 +106,7 @@ static DWORD CALLBACK diva_pre_startup(void)
/* Initialize debug helpers */
spike_hook_init(L".\\segatools.ini");
spike_hook_init(get_config_path());
dprintf("--- End diva_pre_startup ---\n");

View File

@ -63,33 +63,33 @@ static void diva_jvs_read_switches(void *ctx, struct io3_switch_state *out)
diva_dll.jvs_poll(&opbtn, &gamebtn);
if (gamebtn & 0x01) {
if (gamebtn & DIVA_IO_GAMEBTN_CIRCLE) {
out->p1 |= 1 << 6;
}
if (gamebtn & 0x02) {
if (gamebtn & DIVA_IO_GAMEBTN_CROSS) {
out->p1 |= 1 << 7;
}
if (gamebtn & 0x04) {
if (gamebtn & DIVA_IO_GAMEBTN_SQUARE) {
out->p1 |= 1 << 8;
}
if (gamebtn & 0x08) {
if (gamebtn & DIVA_IO_GAMEBTN_TRIANGLE) {
out->p1 |= 1 << 9;
}
if (gamebtn & 0x10) {
if (gamebtn & DIVA_IO_GAMEBTN_START) {
out->p1 |= 1 << 15;
}
if (opbtn & 0x01) {
if (opbtn & DIVA_IO_OPBTN_TEST) {
out->system = 0x80;
} else {
out->system = 0;
}
if (opbtn & 0x02) {
if (opbtn & DIVA_IO_OPBTN_SERVICE) {
out->p1 |= 1 << 14;
}
}

View File

@ -4,7 +4,6 @@ shared_library(
include_directories : inc,
implicit_include_directories : false,
vs_module_defs : 'divahook.def',
c_pch : '../precompiled.h',
dependencies : [
capnhook.get_variable('hook_dep'),
capnhook.get_variable('hooklib_dep'),
@ -14,6 +13,7 @@ shared_library(
amex_lib,
board_lib,
divaio_lib,
gfxhook_lib,
hooklib_lib,
jvs_lib,
platform_lib,

View File

@ -7,6 +7,7 @@
#include "divaio/divaio.h"
#include "divaio/config.h"
#include "util/env.h"
static unsigned int __stdcall diva_io_slider_thread_proc(void *ctx);
@ -23,7 +24,7 @@ uint16_t diva_io_get_api_version(void)
HRESULT diva_io_jvs_init(void)
{
diva_io_config_load(&diva_io_cfg, L".\\segatools.ini");
diva_io_config_load(&diva_io_cfg, get_config_path());
return S_OK;
}
@ -37,11 +38,11 @@ void diva_io_jvs_poll(uint8_t *opbtn_out, uint8_t *gamebtn_out)
opbtn = 0;
if (GetAsyncKeyState(diva_io_cfg.vk_test) & 0x8000) {
opbtn |= 1;
opbtn |= DIVA_IO_OPBTN_TEST;
}
if (GetAsyncKeyState(diva_io_cfg.vk_service) & 0x8000) {
opbtn |= 2;
opbtn |= DIVA_IO_OPBTN_SERVICE;
}
for (i = 0 ; i < _countof(diva_io_cfg.vk_buttons) ; i++) {

View File

@ -5,6 +5,19 @@
#include <stdbool.h>
#include <stdint.h>
enum {
DIVA_IO_OPBTN_TEST = 0x01,
DIVA_IO_OPBTN_SERVICE = 0x02
};
enum {
DIVA_IO_GAMEBTN_CIRCLE = 0x01,
DIVA_IO_GAMEBTN_CROSS = 0x02,
DIVA_IO_GAMEBTN_SQUARE = 0x04,
DIVA_IO_GAMEBTN_TRIANGLE = 0x08,
DIVA_IO_GAMEBTN_START = 0x10,
};
/* Get the version of the Project Diva 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

View File

@ -3,7 +3,6 @@ divaio_lib = static_library(
name_prefix : '',
include_directories : inc,
implicit_include_directories : false,
c_pch : '../precompiled.h',
sources : [
'divaio.c',
'divaio.h',

View File

@ -6,6 +6,17 @@ all games.
Keyboard binding settings use
[Virtual-Key Codes](https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes).
## Config Path
The default file path for config file is `./segatools.ini`.
You can modify environment variable `SEGATOOLS_CONFIG_PATH` to another path.
For example, You can have another `start.bat` with following code in it,
Then you can copy `segatools.ini` to `another_config.ini` but with different dns host in it
```bat
set SEGATOOLS_CONFIG_PATH=.\another_config.ini
```
## `[aimeio]`
Controls the card reader driver.
@ -31,6 +42,12 @@ Default: `1`
Enable Aime card reader assembly emulation. Disable to use a real SEGA Aime
reader (COM port number varies by game).
### `portNo`
Default: (game specific)
Sets the COM port to use for the aime card reader assembly.
### `highBaud`
Default: `1`
@ -92,9 +109,21 @@ Controls emulation of the VFD GP1232A02A FUTABA assembly.
Default: `1`
Enable VFD emulation (currently just stubbed). Disable to use a real VFD
Enable VFD emulation. Disable to use a real VFD
GP1232A02A FUTABA assembly (COM port number varies by game).
### `portNo`
Default: (game specific)
Sets the COM port to use for the VFD.
### `utfConversion`
Default: `0`
Converts the strings from the VFD from their respective encoding to UTF, so console output will display as it should on non-Japanese locales.
## `[amvideo]`
Controls the `amvideo.dll` stub built into Segatools. This is a DLL that is
@ -185,6 +214,30 @@ Default: Empty string (i.e. use value from `default` setting)
Overrides the target of the `aime.naominet.jp` host lookup.
### `replaceHost`
Default: `0`
Replace the HOST field in HTTP request headers with the settings above. This may help bypass network restrictions in some regions.
### `startupPort`
Default: `0` (i.e. no operation will perform)
Overrides the port of connections to the `startup` server. The current implementation affects every TCP connection to the port 80.
### `billingPort`
Default: `0` (i.e. no operation will perform)
Overrides the port of connections to the `billing` server. The current implementation affects every TCP connection to the port 8443.
### `aimedbPort`
Default: `0` (i.e. no operation will perform)
Overrides the port of connections to the `aimedb` server. The current implementation affects every TCP connection to the port 22345.
## `[ds]`
Controls emulation of the "DS (Dallas Semiconductor) EEPROM" chip on the AMEX
@ -553,3 +606,16 @@ Default: Empty string
Configure the location of the "Option" data mount point. This mount point is
optional (hence the name, probably) and contains directories which contain
minor over-the-air content updates.
## `[openssl]`
Enable or disable the application of the OpenSSL patch for Intel Gen 10 or newer CPUs.
### `enable`
Default: `1`
Enable the patch automatically sets the OPENSSL_ia32cap variable in the user's environment
table if the CPU meets the requirements. This setting must be enabled on PCs with
Intel Gen 10 or newer CPUs to ensure the game runs properly, but it's ok to leave enabled
on other CPUs since the patch will not run if the CPU requirements are not met.

View File

@ -1,5 +1,6 @@
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include "board/config.h"
@ -122,5 +123,6 @@ void fgo_hook_config_load(
fgo_deck_config_load(&cfg->deck, filename);
ftdi_config_load(&cfg->ftdi, filename);
led15093_config_load(&cfg->led15093, filename);
gfx_config_load(&cfg->gfx, filename);
fgo_dll_config_load(&cfg->dll, filename);
}

View File

@ -9,6 +9,8 @@
#include "hooklib/touch.h"
#include "hooklib/printer.h"
#include "gfxhook/config.h"
#include "fgohook/deck.h"
#include "fgohook/ftdi.h"
#include "fgohook/fgo-dll.h"
@ -26,6 +28,7 @@ struct fgo_hook_config {
struct deck_config deck;
struct ftdi_config ftdi;
struct led15093_config led15093;
struct gfx_config gfx;
struct fgo_dll_config dll;
};

View File

@ -26,6 +26,7 @@
#include "hook/process.h"
#include "hooklib/dll.h"
#include "hooklib/dvd.h"
#include "hooklib/touch.h"
#include "hooklib/printer.h"
@ -33,6 +34,8 @@
#include "hooklib/serial.h"
#include "hooklib/spike.h"
#include "gfxhook/gfx.h"
#include "fgohook/config.h"
#include "fgohook/io4.h"
#include "fgohook/fgo-dll.h"
@ -41,6 +44,7 @@
#include "platform/platform.h"
#include "util/dprintf.h"
#include "util/env.h"
static HMODULE fgo_hook_mod;
static process_entry_t fgo_startup;
@ -49,22 +53,37 @@ static struct fgo_hook_config fgo_hook_cfg;
static DWORD CALLBACK fgo_pre_startup(void)
{
HRESULT hr;
HMODULE dbghelp;
dprintf("--- Begin fgo_pre_startup ---\n");
/* Pin dbghelp so the path hooks apply to it. */
dbghelp = LoadLibraryW(L"dbghelp.dll");
if (dbghelp != NULL) {
dprintf("Pinned debug helper library, hMod=%p\n", dbghelp);
}
else {
dprintf("Failed to load debug helper library!\n");
}
/* Load config */
fgo_hook_config_load(&fgo_hook_cfg, L".\\segatools.ini");
fgo_hook_config_load(&fgo_hook_cfg, get_config_path());
/* Hook Win32 APIs */
dvd_hook_init(&fgo_hook_cfg.dvd, fgo_hook_mod);
gfx_hook_init(&fgo_hook_cfg.gfx);
touch_screen_hook_init(&fgo_hook_cfg.touch, fgo_hook_mod);
serial_hook_init();
/* Hook external DLL APIs */
printer_hook_init(&fgo_hook_cfg.printer, 4, fgo_hook_mod);
dll_hook_push(fgo_hook_mod, L"C330Ausb.dll");
dll_hook_push(fgo_hook_mod, L"C330AFWDLusb.dll");
/* Initialize emulation hooks */
@ -129,7 +148,7 @@ static DWORD CALLBACK fgo_pre_startup(void)
/* Initialize debug helpers */
spike_hook_init(L".\\segatools.ini");
spike_hook_init(get_config_path());
dprintf("--- End fgo_pre_startup ---\n");

View File

@ -44,7 +44,7 @@ EXPORTS
chcusb_selectPrinter
chcusb_selectPrinterSN
chcusb_getPrinterInfo
chcusb_imageformat
chcusb_imageformat=chcusb_imageformat_330
chcusb_setmtf
chcusb_makeGamma
chcusb_setIcctable

View File

@ -16,8 +16,10 @@
#include <windows.h>
#include <setupapi.h>
#include <stdint.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "fgohook/ftdi.h"
@ -116,7 +118,7 @@ static const struct hook_symbol reg_syms[] = {
}
};
#define device_fake_key 0xDEADBEEF
const size_t device_fake_key = 0xDEADBEEF;
static HANDLE ftdi_fd;
static char port_name[8];

View File

@ -4,7 +4,6 @@ shared_library(
include_directories : inc,
implicit_include_directories : false,
vs_module_defs : 'fgohook.def',
c_pch : '../precompiled.h',
dependencies : [
capnhook.get_variable('hook_dep'),
capnhook.get_variable('hooklib_dep'),
@ -13,6 +12,7 @@ shared_library(
link_with : [
aimeio_lib,
board_lib,
gfxhook_lib,
hooklib_lib,
fgoio_lib,
platform_lib,

View File

@ -8,6 +8,7 @@
#include "fgoio/fgoio.h"
#include "fgoio/config.h"
#include "util/dprintf.h"
#include "util/env.h"
static uint8_t fgo_opbtn;
static uint8_t fgo_gamebtn;
@ -23,7 +24,7 @@ uint16_t fgo_io_get_api_version(void)
HRESULT fgo_io_init(void)
{
fgo_io_config_load(&fgo_io_cfg, L".\\segatools.ini");
fgo_io_config_load(&fgo_io_cfg, get_config_path());
return S_OK;
}
@ -109,8 +110,8 @@ HRESULT fgo_io_poll(void)
normalizedMagnitude = 0.0;
}
fgo_stick_x = normalizedLX * normalizedMagnitude * 32767;
fgo_stick_y = normalizedLY * normalizedMagnitude * 32767;
fgo_stick_x = (int16_t)(normalizedLX * normalizedMagnitude * 32767);
fgo_stick_y = (int16_t)(normalizedLY * normalizedMagnitude * 32767);
return S_OK;
}

View File

@ -3,7 +3,6 @@ fgoio_lib = static_library(
name_prefix : '',
include_directories : inc,
implicit_include_directories : false,
c_pch : '../precompiled.h',
dependencies : [
xinput_lib,
],

View File

@ -9,18 +9,53 @@
#include "util/dprintf.h"
typedef BOOL (WINAPI *ShowWindow_t)(HWND hWnd, int nCmdShow);
/* Hook functions */
static BOOL WINAPI hook_ShowWindow(HWND hWnd, int nCmdShow);
static HWND WINAPI hook_CreateWindowExA(
DWORD dwExStyle,
LPCSTR lpClassName,
LPCSTR lpWindowName,
DWORD dwStyle,
int X,
int Y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
/* Link pointers */
static BOOL (WINAPI *next_ShowWindow)(HWND hWnd, int nCmdShow);
static HWND (WINAPI *next_CreateWindowExA)(
DWORD dwExStyle,
LPCSTR lpClassName,
LPCSTR lpWindowName,
DWORD dwStyle,
int X,
int Y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
);
static struct gfx_config gfx_config;
static ShowWindow_t next_ShowWindow;
static const struct hook_symbol gfx_hooks[] = {
{
.name = "ShowWindow",
.patch = hook_ShowWindow,
.link = (void **) &next_ShowWindow,
}, {
.name = "CreateWindowExA",
.patch = hook_CreateWindowExA,
.link = (void **) &next_CreateWindowExA,
},
};
@ -46,3 +81,59 @@ static BOOL WINAPI hook_ShowWindow(HWND hWnd, int nCmdShow)
return next_ShowWindow(hWnd, nCmdShow);
}
static HWND WINAPI hook_CreateWindowExA(
DWORD dwExStyle,
LPCSTR lpClassName,
LPCSTR lpWindowName,
DWORD dwStyle,
int X,
int Y,
int nWidth,
int nHeight,
HWND hWndParent,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam
)
{
RECT rect;
dprintf("Gfx: CreateWindowExA hook hit\n");
if (gfx_config.windowed)
{
if (gfx_config.framed)
dwStyle |= WS_BORDER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU;
else
dwStyle = WS_POPUP;
rect.left = ((X == CW_USEDEFAULT) ? 0 : X);
rect.top = ((Y == CW_USEDEFAULT) ? 0 : Y);
rect.right = rect.left + nWidth;
rect.bottom = rect.top + nHeight;
// Don't care if it's ok or not, since we are creating window and we can't just return a NULL
AdjustWindowRect(&rect, dwStyle, !!hMenu);
X = ((X == CW_USEDEFAULT) ? X : rect.left);
Y = ((Y == CW_USEDEFAULT) ? Y : rect.top);
nWidth = rect.right - rect.left;
nHeight = rect.bottom - rect.top;
}
return next_CreateWindowExA(
dwExStyle,
lpClassName,
lpWindowName,
dwStyle,
X,
Y,
nWidth,
nHeight,
hWndParent,
hMenu,
hInstance,
lpParam
);
}

77
gfxhook/gl.c Normal file
View File

@ -0,0 +1,77 @@
#include <windows.h>
#include <assert.h>
#include <stdlib.h>
#include "gfxhook/gfx.h"
#include "gfxhook/gl.h"
#include "hook/table.h"
#include "hooklib/dll.h"
#include "util/dprintf.h"
/* Hook functions */
static void WINAPI hook_glutFullScreen(void);
static void WINAPI hook_glutInitDisplayMode(unsigned int mode);
/* Link pointers */
static void (WINAPI *next_glutFullScreen)(void);
static void (WINAPI *next_glutInitDisplayMode)(unsigned int mode);
static struct gfx_config gfx_config;
static const struct hook_symbol glut_hooks[] = {
{
.name = "glutFullScreen",
.patch = hook_glutFullScreen,
.link = (void **) &next_glutFullScreen,
}, {
.name = "glutInitDisplayMode",
.patch = hook_glutInitDisplayMode,
.link = (void **) &next_glutInitDisplayMode,
},
};
void gfx_gl_hook_init(const struct gfx_config *cfg, HINSTANCE self)
{
assert(cfg != NULL);
if (!cfg->enable) {
return;
}
memcpy(&gfx_config, cfg, sizeof(*cfg));
hook_table_apply(NULL, "glut32.dll", glut_hooks, _countof(glut_hooks));
if (self != NULL) {
dll_hook_push(self, L"glut32.dll");
}
}
static void WINAPI hook_glutFullScreen(void)
{
dprintf("Gfx: glutFullScreen hook hit\n");
if (gfx_config.windowed) {
return;
}
next_glutFullScreen();
}
static void WINAPI hook_glutInitDisplayMode(unsigned int mode)
{
dprintf("Gfx: glutInitDisplayMode hook hit\n");
// GLUT adds a frame when going windowed
if (gfx_config.windowed && !gfx_config.framed) {
// GLUT_BORDERLESS
mode |= 0x0800;
}
next_glutInitDisplayMode(mode);
}

3
gfxhook/gl.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void gfx_gl_hook_init(const struct gfx_config *cfg, HINSTANCE self);

Some files were not shown because too many files have changed in this diff Show More