jubeat: support p3io games

This commit is contained in:
Will Toohey
2021-12-31 20:23:31 +10:00
parent 8ab92872ad
commit 1105a2a130
68 changed files with 1633 additions and 918 deletions
+4 -2
View File
@@ -1,17 +1,21 @@
avsdlls += jbhook1
imps += glhelper
deplibs_jbhook1 := \
avs \
glhelper \
ldflags_jbhook1 := \
-lws2_32 \
-liphlpapi \
-lopengl32 \
libs_jbhook1 := \
acioemu \
cconfig \
eamio \
jbio \
jbhook-util \
p3ioemu \
p3io \
hook \
@@ -20,11 +24,9 @@ libs_jbhook1 := \
util \
src_jbhook1 := \
acio.c \
avs-boot.c \
config-gfx.c \
config-eamuse.c \
config-security.c \
dllmain.c \
log-gftools.c \
p3io.c \
-98
View File
@@ -1,98 +0,0 @@
// clang-format off
// Don't format because the order is important here
#include <windows.h>
#include <ntdef.h>
#include <devioctl.h>
#include <ntddser.h>
// clang-format on
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "acioemu/addr.h"
#include "acioemu/emu.h"
#include "acioemu/h44b.h"
#include "acioemu/icca.h"
#include "hook/iohook.h"
#include "jbhook/acio.h"
#include "imports/avs.h"
#include "util/defs.h"
#include "util/hex.h"
#include "util/iobuf.h"
#include "util/log.h"
#include "util/str.h"
static struct ac_io_emu ac_io_emu;
static struct ac_io_emu_icca ac_io_emu_icca;
static struct ac_io_emu_h44b ac_io_emu_h44b;
void ac_io_port_init(void)
{
ac_io_emu_init(&ac_io_emu, L"COM1");
ac_io_emu_icca_init(&ac_io_emu_icca, &ac_io_emu, 0);
ac_io_emu_h44b_init(&ac_io_emu_h44b, &ac_io_emu, 1);
}
void ac_io_port_fini(void)
{
ac_io_emu_fini(&ac_io_emu);
}
HRESULT
ac_io_port_dispatch_irp(struct irp *irp)
{
const struct ac_io_message *msg;
HRESULT hr;
log_assert(irp != NULL);
if (!ac_io_emu_match_irp(&ac_io_emu, irp)) {
return iohook_invoke_next(irp);
}
for (;;) {
hr = ac_io_emu_dispatch_irp(&ac_io_emu, irp);
if (hr != S_OK) {
return hr;
}
msg = ac_io_emu_request_peek(&ac_io_emu);
switch (msg->addr) {
case 0:
ac_io_emu_cmd_assign_addrs(&ac_io_emu, msg, 2);
break;
case 1:
ac_io_emu_icca_dispatch_request(&ac_io_emu_icca, msg);
break;
case 2:
ac_io_emu_h44b_dispatch_request(&ac_io_emu_h44b, msg);
break;
case AC_IO_BROADCAST:
log_warning("Broadcast(?) message on jubeat ACIO bus?");
break;
default:
log_warning(
"ACIO message on unhandled bus address: %d", msg->addr);
break;
}
ac_io_emu_request_pop(&ac_io_emu);
}
}
-22
View File
@@ -1,22 +0,0 @@
#ifndef JBHOOK1_ACIO_H
#define JBHOOK1_ACIO_H
#include "hook/iohook.h"
/**
* Initialize the ACIO backend for jubeat.
*/
void ac_io_port_init(void);
/**
* Shutdown the ACIO backend.
*/
void ac_io_port_fini(void);
/**
* ACIO backend dispatch irp function. This needs to be hooked up to the iohook
* module in order to receive system calls to dispatch for emulation.
*/
HRESULT ac_io_port_dispatch_irp(struct irp *irp);
#endif
+18
View File
@@ -7,8 +7,10 @@
#include "util/log.h"
#define JBHOOK1_CONFIG_GFX_WINDOWED_KEY "gfx.windowed"
#define JBHOOK1_CONFIG_GFX_VERTICAL_KEY "gfx.vertical"
#define JBHOOK1_CONFIG_GFX_DEFAULT_WINDOWED_VALUE false
#define JBHOOK1_CONFIG_GFX_DEFAULT_VERTICAL_VALUE true
void jbhook1_config_gfx_init(struct cconfig *config)
{
@@ -17,6 +19,11 @@ void jbhook1_config_gfx_init(struct cconfig *config)
JBHOOK1_CONFIG_GFX_WINDOWED_KEY,
JBHOOK1_CONFIG_GFX_DEFAULT_WINDOWED_VALUE,
"Run the game windowed");
cconfig_util_set_bool(
config,
JBHOOK1_CONFIG_GFX_VERTICAL_KEY,
JBHOOK1_CONFIG_GFX_DEFAULT_VERTICAL_VALUE,
"Adjust the rotation of the game window so it runs vertically");
}
void jbhook1_config_gfx_get(
@@ -33,4 +40,15 @@ void jbhook1_config_gfx_get(
JBHOOK1_CONFIG_GFX_WINDOWED_KEY,
JBHOOK1_CONFIG_GFX_DEFAULT_WINDOWED_VALUE);
}
if (!cconfig_util_get_bool(
config,
JBHOOK1_CONFIG_GFX_VERTICAL_KEY,
&config_gfx->vertical,
JBHOOK1_CONFIG_GFX_DEFAULT_VERTICAL_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%d'",
JBHOOK1_CONFIG_GFX_VERTICAL_KEY,
JBHOOK1_CONFIG_GFX_DEFAULT_VERTICAL_VALUE);
}
}
+2 -1
View File
@@ -8,6 +8,7 @@
*/
struct jbhook1_config_gfx {
bool windowed;
bool vertical;
};
/**
@@ -27,4 +28,4 @@ void jbhook1_config_gfx_init(struct cconfig *config);
void jbhook1_config_gfx_get(
struct jbhook1_config_gfx *config_gfx, struct cconfig *config);
#endif
#endif
+3 -10
View File
@@ -4,6 +4,8 @@
#include "jbhook1/config-security.h"
#include "jbhook-util/security.h"
#include "security/mcode.h"
#include "util/log.h"
@@ -12,16 +14,7 @@
#define JBHOOK1_CONFIG_SECURITY_MCODE_KEY "security.mcode"
#define JBHOOK1_CONFIG_SECURITY_DEFAULT_MCODE_VALUE \
jbhook1_config_security_default_mcode
static const struct security_mcode jbhook1_config_security_default_mcode = {
.header = SECURITY_MCODE_HEADER,
.unkn = SECURITY_MCODE_UNKN_C,
.game = SECURITY_MCODE_GAME_JB_1,
.region = SECURITY_MCODE_REGION_JAPAN,
.cabinet = SECURITY_MCODE_CABINET_A,
.revision = SECURITY_MCODE_REVISION_B,
};
jbhook_util_security_default_mcode
void jbhook1_config_security_init(struct cconfig *config)
{
+21 -5
View File
@@ -16,13 +16,17 @@
#include "hooklib/adapter.h"
#include "hooklib/rs232.h"
#include "jbhook1/acio.h"
#include "jbhook1/avs-boot.h"
#include "jbhook1/config-eamuse.h"
#include "jbhook1/config-gfx.h"
#include "jbhook1/config-security.h"
#include "jbhook1/log-gftools.h"
#include "jbhook1/p3io.h"
#include "jbhook-util/acio.h"
#include "jbhook-util/eamuse.h"
#include "jbhook-util/gfx.h"
#include "jbhook-util/mixer.h"
#include "jbhook-util/p3io.h"
#include "p3ioemu/devmgr.h"
#include "p3ioemu/emu.h"
@@ -72,6 +76,8 @@ static HWND CDECL my_mwindow_create(
log_info("---------------- Begin jbhook mwindow_create ----------------");
log_info("-------------------------------------------------------------");
jbhook_util_mixer_hook_init();
config = cconfig_init();
jbhook1_config_gfx_init(config);
@@ -101,6 +107,14 @@ static HWND CDECL my_mwindow_create(
fullscreen = !config_gfx.windowed;
if(config_gfx.vertical) {
DWORD tmp = window_width;
window_width = window_height;
window_height = tmp;
jbhook_util_gfx_install_vertical_hooks();
}
log_info("Starting up jubeat IO backend");
jb_io_set_loggers(
@@ -119,14 +133,16 @@ static HWND CDECL my_mwindow_create(
log_fatal("Initializing card reader backend failed");
}
jbhook_util_eamuse_hook_init();
iohook_push_handler(p3io_emu_dispatch_irp);
iohook_push_handler(ac_io_port_dispatch_irp);
iohook_push_handler(jbhook_util_ac_io_port_dispatch_irp);
rs232_hook_init();
ac_io_port_init();
jbhook_util_ac_io_port_init(L"COM1");
p3io_setupapi_insert_hooks(NULL);
jbhook1_p3io_init(
jbhook_util_p3io_init(
&config_security.mcode, &config_eamuse.pcbid, &config_eamuse.eamid);
log_info("-------------------------------------------------------------");
-171
View File
@@ -1,171 +0,0 @@
#include <windows.h>
#include <stdbool.h>
#include <stdint.h>
#include "bemanitools/jbio.h"
#include "jbhook1/p3io.h"
#include "p3ioemu/emu.h"
#include "p3ioemu/uart.h"
#include "security/rp-sign-key.h"
#include "security/rp3.h"
#include "util/log.h"
static HRESULT jbhook1_p3io_read_jamma(void *ctx, uint32_t *state);
static HRESULT jbhook1_p3io_get_roundplug(
void *ctx, uint8_t plug_id, uint8_t *rom, uint8_t *eeprom);
/*
0:0 b13
0:1 -
0:2 b15
0:3 -
0:4 test
0:5 coin
0:6 service
0:7 -
1:0 -
1:1 b4
1:2 b8
1:3 b12
1:4 b16
1:5 b3
1:6 b7
1:7 b11
2:0 -
2:1 b2
2:2 b6
2:3 b10
2:4 b14
2:5 b1
2:6 b5
2:7 b9
3:0 -
3:1 -
3:2 -
3:3 -
3:4 -
3:5 -
3:6 -
3:7 -
*/
static const uint32_t jbhook1_p3io_panel_mappings[] = {
(1 << 21),
(1 << 17),
(1 << 13),
(1 << 9),
(1 << 22),
(1 << 18),
(1 << 14),
(1 << 10),
(1 << 23),
(1 << 19),
(1 << 15),
(1 << 11),
(1 << 0),
(1 << 20),
(1 << 2),
(1 << 12),
};
static const uint32_t jbhook1_p3io_sys_button_mappings[] = {
(1 << 4),
(1 << 6),
(1 << 5),
};
static struct security_mcode jbhook1_p3io_mcode;
static struct security_id jbhook1_p3io_pcbid;
static struct security_id jbhook1_p3io_eamid;
static const struct p3io_ops p3io_ddr_ops = {
.read_jamma = jbhook1_p3io_read_jamma,
.get_roundplug = jbhook1_p3io_get_roundplug,
};
void jbhook1_p3io_init(
const struct security_mcode *mcode,
const struct security_id *pcbid,
const struct security_id *eamid)
{
memcpy(&jbhook1_p3io_mcode, mcode, sizeof(struct security_mcode));
memcpy(&jbhook1_p3io_pcbid, pcbid, sizeof(struct security_id));
memcpy(&jbhook1_p3io_eamid, eamid, sizeof(struct security_id));
p3io_emu_init(&p3io_ddr_ops, NULL);
}
void jbhook1_p3io_finit(void)
{
p3io_emu_fini();
}
static HRESULT jbhook1_p3io_read_jamma(void *ctx, uint32_t *state)
{
uint16_t panels;
uint8_t buttons;
log_assert(state != NULL);
/* lower three bytes low active, highest byte high active */
*state = 0;
if (!jb_io_read_inputs()) {
log_warning("Reading inputs from jbio failed");
return E_FAIL;
}
panels = jb_io_get_panel_inputs();
buttons = jb_io_get_sys_inputs();
for (uint8_t i = 0; i < 16; i++) {
if (panels & (1 << i)) {
*state |= jbhook1_p3io_panel_mappings[i];
}
}
for (uint8_t i = 0; i < 2; i++) {
if (buttons & (1 << i)) {
*state |= jbhook1_p3io_sys_button_mappings[i];
}
}
return S_OK;
}
static HRESULT jbhook1_p3io_get_roundplug(
void *ctx, uint8_t plug_id, uint8_t *rom, uint8_t *eeprom)
{
struct security_rp3_eeprom eeprom_out;
if (plug_id == 0) {
/* black */
memcpy(rom, jbhook1_p3io_pcbid.id, sizeof(jbhook1_p3io_pcbid.id));
security_rp3_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_BLACK,
&security_rp_sign_key_black_gfdmv4,
&jbhook1_p3io_mcode,
&jbhook1_p3io_pcbid,
&eeprom_out);
} else {
/* white */
memcpy(rom, jbhook1_p3io_eamid.id, sizeof(jbhook1_p3io_eamid.id));
security_rp3_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_WHITE,
&security_rp_sign_key_white_eamuse,
&security_mcode_eamuse,
&jbhook1_p3io_eamid,
&eeprom_out);
}
memcpy(eeprom, &eeprom_out, sizeof(struct security_rp3_eeprom));
return S_OK;
}
-28
View File
@@ -1,28 +0,0 @@
#ifndef JBHOOK1_P3IO_H
#define JBHOOK1_P3IO_H
#include <windows.h>
#include "hook/iohook.h"
#include "security/id.h"
#include "security/mcode.h"
/**
* Initialize the jbhook1 specific p3io emulation backend.
*
* @param mcode Mcode of the target game to run. Required for dongle emulation.
* @param pcbid PCBDID
* @param eamid EAMID
*/
void jbhook1_p3io_init(
const struct security_mcode *mcode,
const struct security_id *pcbid,
const struct security_id *eamid);
/**
* Shutdown the p3io emulation backend.
*/
void jbhook1_p3io_fini(void);
#endif