mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2025-01-31 04:03:43 +01:00
jubeat: support p3io games
This commit is contained in:
parent
8ab92872ad
commit
1105a2a130
@ -226,7 +226,7 @@ $$(dll_$1_$2_$3) $$(implib_$1_$2_$3): $$(obj_$1_$2_$3) $$(abslib_$1_$2_$3) \
|
||||
$(V)echo ... $$(dll_$1_$2_$3)
|
||||
$(V)$$(toolchain_$1)gcc -shared \
|
||||
-o $$(dll_$1_$2_$3) -Wl,--out-implib,$$(implib_$1_$2_$3) \
|
||||
$$^ $$(ldflags_$3)
|
||||
-Wl,--start-group $$^ -Wl,--end-group $$(ldflags_$3)
|
||||
$(V)$$(toolchain_$1)strip $$(dll_$1_$2_$3)
|
||||
$(V)$$(toolchain_$1)ranlib $$(implib_$1_$2_$3)
|
||||
|
||||
|
62
Module.mk
62
Module.mk
@ -26,7 +26,8 @@
|
||||
# 8: Patch 3: beatmania IIDX 16 Empress
|
||||
# jubeat
|
||||
#
|
||||
# 10: Patch 4: DanceDanceRevolution X2
|
||||
# 10: Patch 2: jubeat Knit
|
||||
# Patch 4: DanceDanceRevolution X2
|
||||
#
|
||||
# 11: Patch 1: beatmania IIDX 18 Resort Anthem
|
||||
# pop'n music 19 Tune Street
|
||||
@ -71,7 +72,7 @@ cflags += \
|
||||
# Each AVS-dependent project should consume the earliest AVS import definition
|
||||
# that is still ABI-compatible with the real build its target links against.
|
||||
|
||||
avsvers_32 := 1700 1603 1601 1508 1403 1304 1101 803 0
|
||||
avsvers_32 := 1700 1603 1601 1508 1403 1304 1101 1002 803 0
|
||||
avsvers_64 := 1700 1603 1601 1509 1508
|
||||
|
||||
imps += avs avs-ea3
|
||||
@ -136,12 +137,14 @@ include src/main/iidxio-ezusb2/Module.mk
|
||||
include src/main/iidxio/Module.mk
|
||||
include src/main/iidxiotest/Module.mk
|
||||
include src/main/inject/Module.mk
|
||||
include src/main/jbhook/Module.mk
|
||||
include src/main/jbhook1/Module.mk
|
||||
include src/main/jbio-magicbox/Module.mk
|
||||
include src/main/jbio-p4io/Module.mk
|
||||
include src/main/jbio/Module.mk
|
||||
include src/main/jbiotest/Module.mk
|
||||
include src/main/jbhook-util/Module.mk
|
||||
include src/main/jbhook1/Module.mk
|
||||
include src/main/jbhook2/Module.mk
|
||||
include src/main/jbhook3/Module.mk
|
||||
include src/main/launcher/Module.mk
|
||||
include src/main/mempatch-hook/Module.mk
|
||||
include src/main/mm/Module.mk
|
||||
@ -424,28 +427,68 @@ $(zipdir)/jb-01.zip: \
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/jb-02.zip: \
|
||||
build/bin/avs2_1002-32/jbhook1.dll \
|
||||
build/bin/indep-32/inject.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/jbio.dll \
|
||||
dist/jb/config.bat \
|
||||
dist/jb/gamestart-02.bat \
|
||||
dist/jb/jbhook-02.conf \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/jb-03.zip: \
|
||||
build/bin/avs2_1101-32/jbhook2.dll \
|
||||
build/bin/avs2_1101-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/jbio.dll \
|
||||
dist/jb/config.bat \
|
||||
dist/jb/gamestart-03.bat \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/jb-04.zip: \
|
||||
build/bin/avs2_1304-32/jbhook2.dll \
|
||||
build/bin/avs2_1304-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/jbio.dll \
|
||||
dist/jb/config.bat \
|
||||
dist/jb/gamestart-03.bat \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/jb-05-to-07.zip: \
|
||||
build/bin/avs2_1508-32/jbhook.dll \
|
||||
build/bin/avs2_1508-32/jbhook3.dll \
|
||||
build/bin/avs2_1508-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/jbio.dll \
|
||||
dist/jb/config.bat \
|
||||
dist/jb/gamestart.bat \
|
||||
dist/jb/gamestart-04.bat \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/jb-08.zip: \
|
||||
build/bin/avs2_1700-32/jbhook.dll \
|
||||
build/bin/avs2_1700-32/jbhook3.dll \
|
||||
build/bin/avs2_1700-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/jbio.dll \
|
||||
dist/jb/config.bat \
|
||||
dist/jb/gamestart.bat \
|
||||
dist/jb/gamestart-04.bat \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
@ -621,6 +664,9 @@ $(BUILDDIR)/bemanitools.zip: \
|
||||
$(zipdir)/iidx-hwio-x86.zip \
|
||||
$(zipdir)/iidx-hwio-x64.zip \
|
||||
$(zipdir)/jb-01.zip \
|
||||
$(zipdir)/jb-02.zip \
|
||||
$(zipdir)/jb-03.zip \
|
||||
$(zipdir)/jb-04.zip \
|
||||
$(zipdir)/jb-05-to-07.zip \
|
||||
$(zipdir)/jb-08.zip \
|
||||
$(zipdir)/jb-hwio.zip \
|
||||
|
5
dist/jb/gamestart-02.bat
vendored
Normal file
5
dist/jb/gamestart-02.bat
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
@echo off
|
||||
|
||||
cd /d %~dp0
|
||||
|
||||
inject jbhook1.dll jubeat.exe --config jbhook-02.conf %*
|
@ -7,4 +7,4 @@ if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml
|
||||
if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml
|
||||
if not exist dev\raw mkdir dev\raw
|
||||
|
||||
launcher -H 33554432 -K jbhook.dll jubeat.dll
|
||||
launcher -K jbhook2.dll jubeat.dll
|
10
dist/jb/gamestart-04.bat
vendored
Normal file
10
dist/jb/gamestart-04.bat
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
@echo off
|
||||
|
||||
cd /d %~dp0
|
||||
|
||||
if not exist dev\nvram mkdir dev\nvram
|
||||
if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml
|
||||
if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml
|
||||
if not exist dev\raw mkdir dev\raw
|
||||
|
||||
launcher -K jbhook3.dll jubeat.dll
|
15
dist/jb/jbhook-02.conf
vendored
Normal file
15
dist/jb/jbhook-02.conf
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# Run the game windowed
|
||||
gfx.windowed=false
|
||||
|
||||
# URL (e.g. http://my.eamuse.server:80/whatever) or IPV4 (e.g. 127.0.0.1:80) of the target eamuse server. The port is optional but defaults to 80.
|
||||
eamuse.server=localhost:80
|
||||
|
||||
# PCBID
|
||||
eamuse.pcbid=0101020304050607086F
|
||||
|
||||
# EAMID
|
||||
eamuse.eamid=0101020304050607086F
|
||||
|
||||
# Mcode of the game to run.
|
||||
security.mcode=GCI44JAA
|
||||
|
@ -23,14 +23,14 @@ games:
|
||||
* [iidxhook8](iidxhook8.md): CANNON BALLERS, Rootage
|
||||
* [iidxhook8](iidxhook9.md): Heroic Verse
|
||||
|
||||
When building kactools, independent packages are created for each set of games
|
||||
When building bemanitools, independent packages are created for each set of games
|
||||
which are ready to be dropped on top of vanilla AC data dumps. We recommend
|
||||
using prestine dumps to avoid any conflicts with other hardcoded hacks or
|
||||
using pristine dumps to avoid any conflicts with other hardcoded hacks or
|
||||
binary patches.
|
||||
|
||||
## How to run
|
||||
To run your game with iidxhook, you have to use the inject tool to inject the
|
||||
DLL to the game process. *dist/iidx* contains bat scripts with all the
|
||||
DLL to the game process. `dist/iidx` contains bat scripts with all the
|
||||
important parameters configured. Further parameters can be added but might not
|
||||
be required to run the game with default settings.
|
||||
Further information on how to setup the data for each specific version are
|
||||
@ -47,4 +47,4 @@ IO hardware you want to use:
|
||||
game controllers
|
||||
* [iidxio-bio2](iidxhook/iidxio-bio2.md): Support BIO2 hardware
|
||||
* [iidxio-ezusb](iidxhook/iidxio-ezusb.md): Support C02 ezusb FX hardware
|
||||
* [iidxio-ezusb2](iidxhook/iidxio-ezusb2.md): Support IO2 ezusb FX2 hardware
|
||||
* [iidxio-ezusb2](iidxhook/iidxio-ezusb2.md): Support IO2 ezusb FX2 hardware
|
||||
|
77
doc/jbhook/README.md
Normal file
77
doc/jbhook/README.md
Normal file
@ -0,0 +1,77 @@
|
||||
# jbhook
|
||||
|
||||
jbhook is a collection of hook libraries for jubeat providing
|
||||
emulation and various patches to run these games on non BemaniPC hardware and
|
||||
newer Windows versions.
|
||||
|
||||
The hook libraries must be bootstrapped either using [inject](../inject.md) or
|
||||
[launcher](../launcher.md) depending on the version you want to run. Further
|
||||
instructions are given in dedicated readme files for each jbhook version
|
||||
(see below).
|
||||
|
||||
# Versions
|
||||
|
||||
jbhook comes in a few different flavors. The game and its engine changed over
|
||||
the years. Some game versions might require patches/parameters enabled which
|
||||
others don't need or have different AVS versions. Here is the list of supported
|
||||
games:
|
||||
* [jbhook1](jbhook1.md): jubeat, ripples
|
||||
* [jbhook2](jbhook2.md): knit, copious
|
||||
* [jbhook3](jbhook3.md): saucer, prop, qubell, clan, festo
|
||||
|
||||
I sure have trouble remembering which jubeat version is which, here's a handy
|
||||
guide:
|
||||
* 01 - jubeat
|
||||
* 02 - ripples
|
||||
* 03 - knit
|
||||
* 04 - copious
|
||||
* 05 - saucer
|
||||
* 06 - prop
|
||||
* 07 - qubell
|
||||
* 08 - clan
|
||||
* 09 - festo
|
||||
|
||||
When building bemanitools, independent packages are created for each set of games
|
||||
which are ready to be dropped on top of vanilla AC data dumps. We recommend
|
||||
using pristine dumps to avoid any conflicts with other hardcoded hacks or
|
||||
binary patches.
|
||||
|
||||
# How to run
|
||||
|
||||
To run your game with jbhook, you have to use the inject tool to inject the
|
||||
DLL to the game process. `dist/jb` contains bat scripts with all the
|
||||
important parameters configured. Further parameters can be added but might not
|
||||
be required to run the game with default settings.
|
||||
Further information on how to setup the data for each specific version are
|
||||
elaborated in their dedicated readme files.
|
||||
|
||||
# Data setup and running the game
|
||||
|
||||
Ensure your folder with your unpacked data looks like this:
|
||||
- `data`
|
||||
- `prop`
|
||||
- Various dll files including `jubeat.dll` **OR** `jubeat.exe`
|
||||
|
||||
Unpack the package containing jbhook into the folder containing the jubeat
|
||||
binary file.
|
||||
|
||||
Run the `gamestart-XX.bat` file where `XX` denotes the version of the game you want to run.
|
||||
|
||||
# Eamuse network setup
|
||||
|
||||
Running jubeat or ripples? Modify jbhook-01.conf or jbhook-02.conf.
|
||||
|
||||
Running anything newer?
|
||||
* Open the `prop/ea3-config.xml`
|
||||
* Replace the `ea3/network/services` URL with network service URL of your
|
||||
choice (for example http://my.eamuse.com)
|
||||
* Edit the `ea3/id/pcbid`
|
||||
|
||||
# Real hardware support
|
||||
|
||||
Run the launcher without the hook dll: `launcher jubeat.dll`
|
||||
|
||||
# Command line options
|
||||
|
||||
Add the argument *-h* when running inject with jbhook to print help/usage
|
||||
information with a list of parameters you can apply to tweak various things.
|
@ -1,31 +0,0 @@
|
||||
# Game list
|
||||
|
||||
The following games are compatible with this version of jbhook:
|
||||
* saucer
|
||||
* prop
|
||||
* qubell
|
||||
|
||||
# Data setup and running the game
|
||||
|
||||
Ensure your folder with your unpacked data looks like this:
|
||||
- data
|
||||
- prop
|
||||
- Various dll files including jubeat.dll
|
||||
|
||||
Unpack the package containing jbhook into the folder containing the jubeat.dll
|
||||
file.
|
||||
|
||||
Run the gamestart.bat file.
|
||||
|
||||
# Eamuse network setup
|
||||
|
||||
* Open the prop/ea3-config.xml
|
||||
* Replace the *ea3/network/services* URL with network service URL of your
|
||||
choice (for example http://my.eamuse.com)
|
||||
* Edit the *ea3/id/pcbid*
|
||||
|
||||
# Real hardware support
|
||||
|
||||
Run the launcher without the hook dll: *launcher jubeat.dll*
|
||||
|
||||
# Troubleshooting and FAQ
|
21
doc/jbhook/jbhook1.md
Normal file
21
doc/jbhook/jbhook1.md
Normal file
@ -0,0 +1,21 @@
|
||||
# Game list
|
||||
|
||||
The following games are compatible with this version of jbhook:
|
||||
* jubeat
|
||||
* jubeat ripples
|
||||
|
||||
The games must be bootstrapped using [inject](../inject.md).
|
||||
|
||||
# Data setup and running the game
|
||||
|
||||
Unpack the package containing jbhook1 into the revision folder of your choice.
|
||||
Most likely, you want to target the latest revision you have to run the latest
|
||||
binary of the game with any bugfixes by developers.
|
||||
|
||||
Run the `gamestart-01.bat` file as admin.
|
||||
|
||||
# Eamuse network setup
|
||||
|
||||
If you want to run the games online, you have to set a valid PCBID in the
|
||||
configuration file. You also have to set the url of the eamuse server you want
|
||||
to connect to.
|
21
doc/jbhook/jbhook2.md
Normal file
21
doc/jbhook/jbhook2.md
Normal file
@ -0,0 +1,21 @@
|
||||
# Game list
|
||||
|
||||
The following games are compatible with this version of jbhook:
|
||||
* jubeat knit
|
||||
* jubeat copious
|
||||
|
||||
The games must be bootstrapped using [launcher](../launcher.md).
|
||||
|
||||
# Data setup and running the game
|
||||
|
||||
Unpack the package containing jbhook2 into the revision folder of your choice.
|
||||
Most likely, you want to target the latest revision you have to run the latest
|
||||
binary of the game with any bugfixes by developers.
|
||||
|
||||
Run the `gamestart-02.bat` file as admin.
|
||||
|
||||
# Eamuse network setup
|
||||
|
||||
If you want to run the games online, you have to set a valid PCBID in the
|
||||
configuration file. You also have to set the url of the eamuse server you want
|
||||
to connect to.
|
18
doc/jbhook/jbhook3.md
Normal file
18
doc/jbhook/jbhook3.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Game list
|
||||
|
||||
The following games are compatible with this version of jbhook:
|
||||
* jubeat saucer
|
||||
* jubeat prop
|
||||
* jubeat qubell
|
||||
* jubeat clan
|
||||
* jubeat festo
|
||||
|
||||
The games must be bootstrapped using [launcher](../launcher.md).
|
||||
|
||||
# Data setup and running the game
|
||||
|
||||
Unpack the package containing jbhook3 into the revision folder of your choice.
|
||||
Most likely, you want to target the latest revision you have to run the latest
|
||||
binary of the game with any bugfixes by developers.
|
||||
|
||||
Run the `gamestart-03.bat` file as admin.
|
10
src/imports/glhelper.h
Normal file
10
src/imports/glhelper.h
Normal file
@ -0,0 +1,10 @@
|
||||
#include <GL/gl.h>
|
||||
|
||||
void glFramebufferTexture2DEXT(GLenum target,
|
||||
GLenum attachment,
|
||||
GLenum textarget,
|
||||
GLuint texture,
|
||||
GLint level);
|
||||
|
||||
void glGenFramebuffersEXT(GLsizei n,
|
||||
GLuint *ids);
|
5
src/imports/import_32_1002_avs-ea3.def
Normal file
5
src/imports/import_32_1002_avs-ea3.def
Normal file
@ -0,0 +1,5 @@
|
||||
LIBRARY libavs-win32-ea3
|
||||
|
||||
EXPORTS
|
||||
ea3_boot
|
||||
ea3_shutdown
|
37
src/imports/import_32_1002_avs.def
Normal file
37
src/imports/import_32_1002_avs.def
Normal file
@ -0,0 +1,37 @@
|
||||
LIBRARY libavs-win32
|
||||
|
||||
EXPORTS
|
||||
avs_boot
|
||||
avs_net_ctrl
|
||||
avs_shutdown
|
||||
avs_thread_create
|
||||
avs_thread_destroy
|
||||
avs_thread_exit
|
||||
avs_thread_join
|
||||
log_body_fatal
|
||||
log_body_info
|
||||
log_body_misc
|
||||
log_body_warning
|
||||
log_boot
|
||||
log_change_level
|
||||
property_create
|
||||
property_desc_to_buffer
|
||||
property_destroy
|
||||
property_file_write
|
||||
property_insert_read
|
||||
property_mem_write
|
||||
property_read_query_memsize
|
||||
property_search
|
||||
property_set_flag
|
||||
property_node_clone
|
||||
property_node_create
|
||||
property_node_datasize
|
||||
property_node_name
|
||||
property_node_refer
|
||||
property_node_remove
|
||||
property_node_type
|
||||
property_node_traversal
|
||||
property_node_refdata
|
||||
std_getenv
|
||||
std_setenv
|
||||
|
6
src/imports/import_32_1002_glhelper.def
Normal file
6
src/imports/import_32_1002_glhelper.def
Normal file
@ -0,0 +1,6 @@
|
||||
LIBRARY glhelper
|
||||
|
||||
EXPORTS
|
||||
glBindFramebufferEXT
|
||||
glFramebufferTexture2DEXT
|
||||
glGenFramebuffersEXT
|
6
src/imports/import_32_1101_glhelper.def
Normal file
6
src/imports/import_32_1101_glhelper.def
Normal file
@ -0,0 +1,6 @@
|
||||
LIBRARY glhelper
|
||||
|
||||
EXPORTS
|
||||
glBindFramebufferEXT
|
||||
glFramebufferTexture2DEXT
|
||||
glGenFramebuffersEXT
|
6
src/imports/import_32_1304_glhelper.def
Normal file
6
src/imports/import_32_1304_glhelper.def
Normal file
@ -0,0 +1,6 @@
|
||||
LIBRARY glhelper
|
||||
|
||||
EXPORTS
|
||||
glBindFramebufferEXT
|
||||
glFramebufferTexture2DEXT
|
||||
glGenFramebuffersEXT
|
6
src/imports/import_32_803_glhelper.def
Normal file
6
src/imports/import_32_803_glhelper.def
Normal file
@ -0,0 +1,6 @@
|
||||
LIBRARY glhelper
|
||||
|
||||
EXPORTS
|
||||
glBindFramebufferEXT
|
||||
glFramebufferTexture2DEXT
|
||||
glGenFramebuffersEXT
|
@ -4,6 +4,8 @@
|
||||
#include <stdint.h>
|
||||
|
||||
enum ac_io_icca_cmd {
|
||||
/* found on jubeat, sent right after queue loop start */
|
||||
AC_IO_ICCA_CMD_UNKN_0116 = 0x0116,
|
||||
/* Yet unknown command encountered first on jubeat (1) */
|
||||
AC_IO_ICCA_CMD_UNKN_0120 = 0x0120,
|
||||
AC_IO_ICCA_CMD_QUEUE_LOOP_START = 0x0130,
|
||||
|
@ -1,48 +0,0 @@
|
||||
#ifndef AC_IO_ICCB_H
|
||||
#define AC_IO_ICCB_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum ac_io_iccb_cmd {
|
||||
/* found on jubeat prop, sent after acio init req, maybe fw update? */
|
||||
AC_IO_ICCB_CMD_UNK_0100 = 0x0100,
|
||||
/* found on jubeat prop, sent right after queue loop start */
|
||||
AC_IO_ICCB_CMD_UNK_0116 = 0x0116,
|
||||
/* found on jubeat prop, sent after 0100 req */
|
||||
AC_IO_ICCB_CMD_UNK_0120 = 0x0120,
|
||||
AC_IO_ICCB_CMD_QUEUE_LOOP_START = 0x0130,
|
||||
AC_IO_ICCB_CMD_POLL = 0x0134,
|
||||
AC_IO_ICCB_CMD_UNK_135 = 0x0135,
|
||||
AC_IO_ICCB_CMD_SLEEP = 0x013A,
|
||||
AC_IO_ICCB_CMD_READ_CARD = 0x0161
|
||||
};
|
||||
|
||||
enum ac_io_iccb_sensor_state {
|
||||
AC_IO_ICCB_SENSOR_CARD = 0x02,
|
||||
AC_IO_ICCB_SENSOR_NO_CARD = 0x04
|
||||
};
|
||||
|
||||
enum ac_io_iccb_card_type {
|
||||
AC_IO_ICCB_CARD_TYPE_ISO15696 = 0x0,
|
||||
AC_IO_ICCB_CARD_TYPE_FELICA = 0x1,
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct ac_io_iccb_misc {
|
||||
uint8_t unknown;
|
||||
uint8_t subcmd;
|
||||
};
|
||||
|
||||
struct ac_io_iccb_state {
|
||||
uint8_t sensor_state;
|
||||
uint8_t card_type;
|
||||
uint8_t uid[8];
|
||||
uint8_t unk2;
|
||||
uint8_t unk3;
|
||||
uint8_t unk4[4];
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
@ -6,6 +6,5 @@ src_acioemu := \
|
||||
h44b.c \
|
||||
hdxs.c \
|
||||
icca.c \
|
||||
iccb.c \
|
||||
pipe.c \
|
||||
|
||||
|
@ -63,6 +63,8 @@ void ac_io_emu_icca_init(
|
||||
|
||||
// default to 1.6.0
|
||||
icca->version = v160;
|
||||
// default, most common code
|
||||
ac_io_emu_icca_set_product_code(icca, AC_IO_EMU_PROD_CODE_ICCA);
|
||||
}
|
||||
|
||||
void ac_io_emu_icca_set_version(
|
||||
@ -71,6 +73,12 @@ void ac_io_emu_icca_set_version(
|
||||
icca->version = version;
|
||||
}
|
||||
|
||||
void ac_io_emu_icca_set_product_code(
|
||||
struct ac_io_emu_icca *icca, const char product_code[4])
|
||||
{
|
||||
memcpy(icca->product_code, product_code, sizeof(icca->product_code));
|
||||
}
|
||||
|
||||
void ac_io_emu_icca_dispatch_request(
|
||||
struct ac_io_emu_icca *icca, const struct ac_io_message *req)
|
||||
{
|
||||
@ -119,8 +127,9 @@ void ac_io_emu_icca_dispatch_request(
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCA_CMD_UNKN_0116:
|
||||
case AC_IO_ICCA_CMD_UNKN_0120:
|
||||
log_misc("AC_IO_ICCA_CMD_UNKN_0120(%d)", req->addr);
|
||||
log_misc("AC_IO_ICCA_CMD_UNK_%04X(%d)", cmd_code, req->addr);
|
||||
ac_io_emu_icca_send_status(icca, req, 0x00);
|
||||
|
||||
break;
|
||||
@ -138,48 +147,52 @@ void ac_io_emu_icca_dispatch_request(
|
||||
break;
|
||||
|
||||
case AC_IO_ICCA_CMD_SET_SLOT_STATE: {
|
||||
struct ac_io_icca_misc *misc =
|
||||
(struct ac_io_icca_misc *) &req->cmd.raw;
|
||||
uint8_t cmd;
|
||||
if(icca->version == v150) {
|
||||
ac_io_emu_icca_send_state(icca, req, 0, false);
|
||||
} else {
|
||||
struct ac_io_icca_misc *misc =
|
||||
(struct ac_io_icca_misc *) &req->cmd.raw;
|
||||
uint8_t cmd;
|
||||
|
||||
switch (misc->subcmd) {
|
||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_CLOSE:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_CLOSE;
|
||||
break;
|
||||
switch (misc->subcmd) {
|
||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_CLOSE:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_CLOSE;
|
||||
break;
|
||||
|
||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_OPEN:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_OPEN;
|
||||
break;
|
||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_OPEN:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_OPEN;
|
||||
break;
|
||||
|
||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_EJECT:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_EJECT;
|
||||
icca->engaged = false;
|
||||
break;
|
||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_EJECT:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_EJECT;
|
||||
icca->engaged = false;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_READ;
|
||||
break;
|
||||
case 3:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_READ;
|
||||
break;
|
||||
|
||||
default:
|
||||
cmd = 0xFF;
|
||||
log_warning(
|
||||
"Unhandled slot command %X, node %d",
|
||||
misc->subcmd,
|
||||
icca->unit_no);
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmd != 0xFF) {
|
||||
if (!eam_io_card_slot_cmd(icca->unit_no, cmd)) {
|
||||
log_warning(
|
||||
"Eamio failed to handle slot cmd %d for node %d",
|
||||
cmd,
|
||||
icca->unit_no);
|
||||
default:
|
||||
cmd = 0xFF;
|
||||
log_warning(
|
||||
"Unhandled slot command %X, node %d",
|
||||
misc->subcmd,
|
||||
icca->unit_no);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* response with current slot state */
|
||||
ac_io_emu_icca_send_status(icca, req, misc->subcmd);
|
||||
if (cmd != 0xFF) {
|
||||
if (!eam_io_card_slot_cmd(icca->unit_no, cmd)) {
|
||||
log_warning(
|
||||
"Eamio failed to handle slot cmd %d for node %d",
|
||||
cmd,
|
||||
icca->unit_no);
|
||||
}
|
||||
}
|
||||
|
||||
/* response with current slot state */
|
||||
ac_io_emu_icca_send_status(icca, req, misc->subcmd);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@ -202,12 +215,14 @@ void ac_io_emu_icca_dispatch_request(
|
||||
break;
|
||||
|
||||
case AC_IO_ICCA_CMD_POLL_FELICA:
|
||||
icca->detected_new_reader = true;
|
||||
|
||||
if (icca->version == v170) {
|
||||
if (icca->version == v150) {
|
||||
ac_io_emu_icca_send_state(icca, req, 0, false);
|
||||
} else if (icca->version == v170) {
|
||||
ac_io_emu_icca_send_empty(icca, req);
|
||||
icca->detected_new_reader = true;
|
||||
} else {
|
||||
ac_io_emu_icca_send_status(icca, req, 0x01);
|
||||
icca->detected_new_reader = true;
|
||||
}
|
||||
|
||||
break;
|
||||
@ -244,8 +259,6 @@ static void ac_io_emu_icca_cmd_send_version(
|
||||
resp.cmd.version.major = 0x01;
|
||||
|
||||
if (icca->version == v150) {
|
||||
log_warning(
|
||||
"ICCA v1.5.0 emulation requested, please remove this log once implemented");
|
||||
resp.cmd.version.minor = 0x05;
|
||||
} else if (icca->version == v160) {
|
||||
resp.cmd.version.minor = 0x06;
|
||||
@ -262,7 +275,7 @@ static void ac_io_emu_icca_cmd_send_version(
|
||||
|
||||
memcpy(
|
||||
resp.cmd.version.product_code,
|
||||
"ICCA",
|
||||
icca->product_code,
|
||||
sizeof(resp.cmd.version.product_code));
|
||||
strncpy(resp.cmd.version.date, __DATE__, sizeof(resp.cmd.version.date));
|
||||
strncpy(resp.cmd.version.time, __TIME__, sizeof(resp.cmd.version.time));
|
||||
|
@ -12,6 +12,11 @@ enum ac_io_emu_icca_version {
|
||||
v170 = 0x7,
|
||||
};
|
||||
|
||||
// ICC product types for ac_io_emu_icca_set_product_code
|
||||
#define AC_IO_EMU_PROD_CODE_ICCA "ICCA"
|
||||
#define AC_IO_EMU_PROD_CODE_ICCB "ICCB"
|
||||
#define AC_IO_EMU_PROD_CODE_ICCC "ICCC"
|
||||
|
||||
struct ac_io_emu_icca {
|
||||
struct ac_io_emu *emu;
|
||||
uint8_t unit_no;
|
||||
@ -28,6 +33,7 @@ struct ac_io_emu_icca {
|
||||
uint64_t time_counter_last_poll;
|
||||
|
||||
enum ac_io_emu_icca_version version;
|
||||
char product_code[4];
|
||||
bool cipher_started;
|
||||
uint32_t cipher_keys[4];
|
||||
};
|
||||
@ -39,6 +45,12 @@ void ac_io_emu_icca_init(
|
||||
void ac_io_emu_icca_set_version(
|
||||
struct ac_io_emu_icca *icca, enum ac_io_emu_icca_version version);
|
||||
|
||||
// optional, call after init to override default "ICCA" product code.
|
||||
// Some games may refuse to boot or expect a different packet format when using
|
||||
// one of the alternative codes such as ICCB or ICCC
|
||||
void ac_io_emu_icca_set_product_code(
|
||||
struct ac_io_emu_icca *icca, const char product_code[4]);
|
||||
|
||||
void ac_io_emu_icca_dispatch_request(
|
||||
struct ac_io_emu_icca *icca, const struct ac_io_message *req);
|
||||
|
||||
|
@ -1,223 +0,0 @@
|
||||
#define LOG_MODULE "acioemu-iccb"
|
||||
|
||||
#include "acioemu/iccb.h"
|
||||
|
||||
#include <windows.h> /* for _BitScanForward */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "acio/iccb.h"
|
||||
|
||||
#include "acioemu/emu.h"
|
||||
|
||||
#include "bemanitools/eamio.h"
|
||||
|
||||
static void ac_io_emu_iccb_cmd_send_version(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req);
|
||||
|
||||
static void ac_io_emu_iccb_send_state(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req);
|
||||
|
||||
static void ac_io_emu_iccb_send_empty(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req);
|
||||
|
||||
static void ac_io_emu_iccb_send_status(
|
||||
struct ac_io_emu_iccb *iccb,
|
||||
const struct ac_io_message *req,
|
||||
uint8_t status);
|
||||
|
||||
void ac_io_emu_iccb_init(
|
||||
struct ac_io_emu_iccb *iccb, struct ac_io_emu *emu, uint8_t unit_no)
|
||||
{
|
||||
memset(iccb, 0, sizeof(*iccb));
|
||||
iccb->emu = emu;
|
||||
iccb->unit_no = unit_no;
|
||||
}
|
||||
|
||||
void ac_io_emu_iccb_dispatch_request(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req)
|
||||
{
|
||||
uint16_t cmd_code;
|
||||
|
||||
cmd_code = ac_io_u16(req->cmd.code);
|
||||
|
||||
switch (cmd_code) {
|
||||
case AC_IO_CMD_GET_VERSION:
|
||||
log_misc("AC_IO_CMD_GET_VERSION(%d)", req->addr);
|
||||
ac_io_emu_iccb_cmd_send_version(iccb, req);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_CMD_START_UP:
|
||||
log_misc("AC_IO_CMD_START_UP(%d)", req->addr);
|
||||
ac_io_emu_iccb_send_status(iccb, req, 0x00);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_CMD_KEEPALIVE:
|
||||
ac_io_emu_iccb_send_empty(iccb, req);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCB_CMD_QUEUE_LOOP_START:
|
||||
log_misc("AC_IO_CMD_QUEUE_LOOP_START(%d)", req->addr);
|
||||
ac_io_emu_iccb_send_status(iccb, req, 0x00);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCB_CMD_UNK_0100:
|
||||
case AC_IO_ICCB_CMD_UNK_0116:
|
||||
case AC_IO_ICCB_CMD_UNK_0120:
|
||||
log_misc("AC_IO_ICCB_CMD_UNK_%04X(%d)", cmd_code, req->addr);
|
||||
ac_io_emu_iccb_send_status(iccb, req, 0x00);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCB_CMD_SLEEP:
|
||||
ac_io_emu_iccb_send_status(iccb, req, 0x00);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCB_CMD_UNK_135:
|
||||
/* log_misc("AC_IO_ICCB_CMD_UNK_135"); */
|
||||
ac_io_emu_iccb_send_state(iccb, req);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCB_CMD_POLL:
|
||||
/* log_misc("AC_IO_ICCB_CMD_POLL"); */
|
||||
ac_io_emu_iccb_send_state(iccb, req);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCB_CMD_READ_CARD:
|
||||
/* log_misc("AC_IO_ICCB_CMD_READ_CARD"); */
|
||||
ac_io_emu_iccb_send_state(iccb, req);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
log_warning(
|
||||
"Unknown ACIO message %04x on ICCB node, addr=%d",
|
||||
cmd_code,
|
||||
req->addr);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ac_io_emu_iccb_cmd_send_version(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req)
|
||||
{
|
||||
struct ac_io_message resp;
|
||||
|
||||
resp.addr = req->addr | AC_IO_RESPONSE_FLAG;
|
||||
resp.cmd.code = req->cmd.code;
|
||||
resp.cmd.seq_no = req->cmd.seq_no;
|
||||
resp.cmd.nbytes = sizeof(resp.cmd.version);
|
||||
resp.cmd.version.type = ac_io_u32(AC_IO_NODE_TYPE_ICCB);
|
||||
resp.cmd.version.flag = 0x00;
|
||||
resp.cmd.version.major = 0x01;
|
||||
resp.cmd.version.minor = 0x05;
|
||||
resp.cmd.version.revision = 0x01;
|
||||
memcpy(
|
||||
resp.cmd.version.product_code,
|
||||
"ICCB",
|
||||
sizeof(resp.cmd.version.product_code));
|
||||
strncpy(resp.cmd.version.date, __DATE__, sizeof(resp.cmd.version.date));
|
||||
strncpy(resp.cmd.version.time, __TIME__, sizeof(resp.cmd.version.time));
|
||||
|
||||
ac_io_emu_response_push(iccb->emu, &resp, 0);
|
||||
}
|
||||
|
||||
static void ac_io_emu_iccb_send_empty(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req)
|
||||
{
|
||||
struct ac_io_message resp;
|
||||
|
||||
resp.addr = req->addr | AC_IO_RESPONSE_FLAG;
|
||||
resp.cmd.code = req->cmd.code;
|
||||
resp.cmd.seq_no = req->cmd.seq_no;
|
||||
resp.cmd.nbytes = 0;
|
||||
|
||||
ac_io_emu_response_push(iccb->emu, &resp, 0);
|
||||
}
|
||||
|
||||
static void ac_io_emu_iccb_send_status(
|
||||
struct ac_io_emu_iccb *iccb,
|
||||
const struct ac_io_message *req,
|
||||
uint8_t status)
|
||||
{
|
||||
struct ac_io_message resp;
|
||||
|
||||
resp.addr = req->addr | AC_IO_RESPONSE_FLAG;
|
||||
resp.cmd.code = req->cmd.code;
|
||||
resp.cmd.seq_no = req->cmd.seq_no;
|
||||
resp.cmd.nbytes = sizeof(resp.cmd.status);
|
||||
resp.cmd.status = status;
|
||||
|
||||
ac_io_emu_response_push(iccb->emu, &resp, 0);
|
||||
}
|
||||
|
||||
static void ac_io_emu_iccb_send_state(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req)
|
||||
{
|
||||
struct ac_io_message resp;
|
||||
struct ac_io_iccb_state *body;
|
||||
bool sensor;
|
||||
|
||||
/* state update */
|
||||
|
||||
if (!eam_io_poll(iccb->unit_no)) {
|
||||
log_warning("Polling eamio failed");
|
||||
}
|
||||
|
||||
sensor = eam_io_get_sensor_state(iccb->unit_no);
|
||||
|
||||
if (sensor != iccb->last_sensor) {
|
||||
if (sensor) {
|
||||
iccb->card_result =
|
||||
eam_io_read_card(iccb->unit_no, iccb->uid, sizeof(iccb->uid));
|
||||
|
||||
// fault if sensor says to read but we got no card
|
||||
iccb->fault = (iccb->card_result == EAM_IO_CARD_NONE);
|
||||
} else {
|
||||
iccb->fault = false;
|
||||
}
|
||||
}
|
||||
|
||||
iccb->last_sensor = sensor;
|
||||
|
||||
if (iccb->fault) {
|
||||
memset(iccb->uid, 0, sizeof(iccb->uid));
|
||||
}
|
||||
|
||||
/* create response */
|
||||
|
||||
resp.addr = req->addr | AC_IO_RESPONSE_FLAG;
|
||||
resp.cmd.code = req->cmd.code;
|
||||
resp.cmd.seq_no = req->cmd.seq_no;
|
||||
resp.cmd.nbytes = sizeof(struct ac_io_iccb_state);
|
||||
|
||||
body = (struct ac_io_iccb_state *) &resp.cmd.raw;
|
||||
|
||||
if (sensor) {
|
||||
body->sensor_state = AC_IO_ICCB_SENSOR_CARD;
|
||||
} else {
|
||||
body->sensor_state = AC_IO_ICCB_SENSOR_NO_CARD;
|
||||
}
|
||||
|
||||
if (!iccb->fault) {
|
||||
memcpy(body->uid, iccb->uid, sizeof(body->uid));
|
||||
}
|
||||
|
||||
body->card_type = 0x30 | (iccb->card_result - 1);
|
||||
body->unk2 = 0;
|
||||
// this doesn't seem to be an error code. If this is not set to 0x03
|
||||
// on slotted readers (only?), the game throws an unknown status error
|
||||
body->unk3 = 0x03;
|
||||
memset(body->unk4, 0, sizeof(body->unk4));
|
||||
|
||||
ac_io_emu_response_push(iccb->emu, &resp, 0);
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
#ifndef AC_IO_EMU_ICCB_H
|
||||
#define AC_IO_EMU_ICCB_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "acioemu/emu.h"
|
||||
|
||||
struct ac_io_emu_iccb {
|
||||
struct ac_io_emu *emu;
|
||||
uint8_t unit_no;
|
||||
bool fault;
|
||||
bool last_sensor;
|
||||
uint8_t uid[8];
|
||||
uint8_t card_result;
|
||||
};
|
||||
|
||||
void ac_io_emu_iccb_init(
|
||||
struct ac_io_emu_iccb *iccb, struct ac_io_emu *emu, uint8_t unit_no);
|
||||
|
||||
void ac_io_emu_iccb_dispatch_request(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req);
|
||||
|
||||
#endif
|
13
src/main/jbhook-util/Module.mk
Normal file
13
src/main/jbhook-util/Module.mk
Normal file
@ -0,0 +1,13 @@
|
||||
libs += jbhook-util
|
||||
|
||||
libs_jbhook-util := \
|
||||
acioemu \
|
||||
|
||||
src_jbhook-util := \
|
||||
acio.c \
|
||||
eamuse.c \
|
||||
gfx.c \
|
||||
mixer.c \
|
||||
locale.c \
|
||||
p3io.c \
|
||||
p4io.c \
|
@ -18,7 +18,7 @@
|
||||
|
||||
#include "hook/iohook.h"
|
||||
|
||||
#include "jbhook/acio.h"
|
||||
#include "jbhook-util/acio.h"
|
||||
|
||||
#include "imports/avs.h"
|
||||
|
||||
@ -32,20 +32,25 @@ 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)
|
||||
void jbhook_util_ac_io_port_init(const wchar_t *filename)
|
||||
{
|
||||
ac_io_emu_init(&ac_io_emu, L"COM1");
|
||||
ac_io_emu_init(&ac_io_emu, filename);
|
||||
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)
|
||||
void jbhook_util_ac_io_port_fini(void)
|
||||
{
|
||||
ac_io_emu_fini(&ac_io_emu);
|
||||
}
|
||||
|
||||
void jbhook_util_ac_io_set_iccb(void) {
|
||||
ac_io_emu_icca_set_version(&ac_io_emu_icca, v150);
|
||||
ac_io_emu_icca_set_product_code(&ac_io_emu_icca, AC_IO_EMU_PROD_CODE_ICCB);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
ac_io_port_dispatch_irp(struct irp *irp)
|
||||
jbhook_util_ac_io_port_dispatch_irp(struct irp *irp)
|
||||
{
|
||||
const struct ac_io_message *msg;
|
||||
HRESULT hr;
|
28
src/main/jbhook-util/acio.h
Normal file
28
src/main/jbhook-util/acio.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef JBHOOK1_ACIO_H
|
||||
#define JBHOOK1_ACIO_H
|
||||
|
||||
#include "hook/iohook.h"
|
||||
|
||||
/**
|
||||
* Initialize the ACIO backend for jubeat on the specified COM port.
|
||||
*/
|
||||
void jbhook_util_ac_io_port_init(const wchar_t *filename);
|
||||
|
||||
/**
|
||||
* Shutdown the ACIO backend.
|
||||
*/
|
||||
void jbhook_util_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 jbhook_util_ac_io_port_dispatch_irp(struct irp *irp);
|
||||
|
||||
/**
|
||||
* Enable ICCB emulation instead of the default ICCA emulation - some jubeats
|
||||
* will have IO errors unless explicitly set to ICCB mode.
|
||||
*/
|
||||
void jbhook_util_ac_io_set_iccb(void);
|
||||
|
||||
#endif
|
144
src/main/jbhook-util/eamuse.c
Normal file
144
src/main/jbhook-util/eamuse.c
Normal file
@ -0,0 +1,144 @@
|
||||
#define LOG_MODULE "eamuse-hook"
|
||||
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
#include "util/net.h"
|
||||
#include "util/str.h"
|
||||
|
||||
static const char *jbhook_eamuse_konami_url = "eamuse.konami.";
|
||||
|
||||
static int(STDCALL *real_getaddrinfo)(
|
||||
PCSTR pNodeName,
|
||||
PCSTR pServiceName,
|
||||
const ADDRINFOA *pHints,
|
||||
PADDRINFOA *ppResult);
|
||||
|
||||
static int STDCALL my_getaddrinfo(
|
||||
PCSTR pNodeName,
|
||||
PCSTR pServiceName,
|
||||
const ADDRINFOA *pHints,
|
||||
PADDRINFOA *ppResult);
|
||||
|
||||
static DWORD WINAPI my_GetIpAddrTable(
|
||||
PMIB_IPADDRTABLE pIpAddrTable,
|
||||
PULONG pdwSize,
|
||||
BOOL bOrder
|
||||
);
|
||||
|
||||
static const struct hook_symbol eamuse_hook_syms[] = {
|
||||
{
|
||||
.name = "getaddrinfo",
|
||||
.ordinal = 176,
|
||||
.patch = my_getaddrinfo,
|
||||
.link = (void **) &real_getaddrinfo,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hook_symbol network_hook_syms[] = {
|
||||
{
|
||||
.name = "GetIpAddrTable",
|
||||
.patch = my_GetIpAddrTable,
|
||||
},
|
||||
};
|
||||
|
||||
static int STDCALL my_getaddrinfo(
|
||||
PCSTR pNodeName,
|
||||
PCSTR pServiceName,
|
||||
const ADDRINFOA *pHints,
|
||||
PADDRINFOA *ppResult)
|
||||
{
|
||||
log_misc("my_getaddrinfo: %s, %s", pNodeName, pServiceName);
|
||||
|
||||
/* resolve eamuse.konami.fun/com to 127.0.0.1 to avoid lag spikes every
|
||||
150 seconds which might happen in-game as well */
|
||||
if (!strncmp(
|
||||
pNodeName,
|
||||
jbhook_eamuse_konami_url,
|
||||
strlen(jbhook_eamuse_konami_url))) {
|
||||
log_info("Resolve konami.eamuse.XXX -> localhost");
|
||||
pNodeName = "localhost";
|
||||
}
|
||||
|
||||
return real_getaddrinfo(pNodeName, pServiceName, pHints, ppResult);
|
||||
}
|
||||
|
||||
static DWORD get_best_ip(void) {
|
||||
PIP_ADAPTER_INFO info = NULL;
|
||||
struct net_addr addr;
|
||||
// fallback to a very obviously wrong value
|
||||
DWORD ret = (5 << 24) | (7 << 16) | (3 << 8) | (0 << 0);
|
||||
ULONG sz = 0;
|
||||
|
||||
// this uses our hooked GetAdaptersInfo from hooklib/adapter.c, thus using
|
||||
// the preferred interface instead of the default order
|
||||
log_assert(GetAdaptersInfo(info, &sz) == ERROR_BUFFER_OVERFLOW);
|
||||
|
||||
info = malloc(sz);
|
||||
|
||||
if(GetAdaptersInfo(info, &sz) != NO_ERROR) {
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
if(!net_str_parse(info->IpAddressList.IpAddress.String, &addr)) {
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
// MS docs say this should be in network byte order, but we need to return
|
||||
// host byte order for the game to not throw the IP error
|
||||
ret = addr.ipv4.addr;
|
||||
|
||||
CLEANUP:
|
||||
free(info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* In new games via network.dll:network_addr_is_changed and in old games
|
||||
* directly, this function is called to compare the current IP address vs the IP
|
||||
* address when the game was first loaded. If the two are different, an error is
|
||||
* printed. It can be dismissed but will show up every ~10 seconds, impeding
|
||||
* gameplay. Because GetAdaptersInfo is hooked to return a (sometimes) different
|
||||
* adapter, computers with multiple interfaces will often fail this comparison
|
||||
* check. By also hooking this function, the IP addresses of the two calls will
|
||||
* agree.
|
||||
*/
|
||||
static DWORD WINAPI my_GetIpAddrTable(
|
||||
PMIB_IPADDRTABLE pIpAddrTable,
|
||||
PULONG pdwSize,
|
||||
BOOL bOrder
|
||||
) {
|
||||
ULONG in = *pdwSize;
|
||||
// 1 element return table
|
||||
*pdwSize = sizeof(MIB_IPADDRTABLE) + sizeof(MIB_IPADDRROW);
|
||||
|
||||
if(in < *pdwSize) {
|
||||
return ERROR_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
|
||||
pIpAddrTable->dwNumEntries = 1;
|
||||
pIpAddrTable->table[0].dwAddr = get_best_ip();
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
void jbhook_util_eamuse_hook_init(void)
|
||||
{
|
||||
hook_table_apply(
|
||||
NULL, "ws2_32.dll", eamuse_hook_syms, lengthof(eamuse_hook_syms));
|
||||
hook_table_apply(
|
||||
NULL, "iphlpapi.dll", network_hook_syms, lengthof(network_hook_syms));
|
||||
|
||||
log_info("Inserted eamuse hooks");
|
||||
}
|
6
src/main/jbhook-util/eamuse.h
Normal file
6
src/main/jbhook-util/eamuse.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef JBHOOK_UTIL_EAMUSE_H
|
||||
#define JBHOOK_UTIL_EAMUSE_H
|
||||
|
||||
void jbhook_util_eamuse_hook_init(void);
|
||||
|
||||
#endif
|
180
src/main/jbhook-util/gfx.c
Normal file
180
src/main/jbhook-util/gfx.c
Normal file
@ -0,0 +1,180 @@
|
||||
#define LOG_MODULE "jbhook-gfx"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
|
||||
#include "hook/com-proxy.h"
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "imports/glhelper.h"
|
||||
|
||||
#include "jbhook-util/gfx.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
#include "util/str.h"
|
||||
#include "util/time.h"
|
||||
|
||||
static void __stdcall hook_glFlush(void);
|
||||
static void (__stdcall *real_glFlush)(void);
|
||||
|
||||
static void hook_glBindFramebufferEXT(GLenum target, GLuint framebuffer);
|
||||
static void (*real_glBindFramebufferEXT)(GLenum target, GLuint framebuffer);
|
||||
|
||||
static const struct hook_symbol jbhook1_opengl_hook_syms[] = {
|
||||
{.name = "glFlush",
|
||||
.patch = hook_glFlush,
|
||||
.link = (void **) &real_glFlush},
|
||||
};
|
||||
|
||||
static const struct hook_symbol jbhook1_glhelper_hook_syms[] = {
|
||||
{.name = "glBindFramebufferEXT",
|
||||
.patch = hook_glBindFramebufferEXT,
|
||||
.link = (void **) &real_glBindFramebufferEXT},
|
||||
};
|
||||
|
||||
static DWORD STDCALL my_GetGlyphOutline(
|
||||
HDC hdc,
|
||||
UINT uChar,
|
||||
UINT uFormat,
|
||||
LPGLYPHMETRICS lpgm,
|
||||
DWORD cbBuffer,
|
||||
LPVOID lpvBuffer,
|
||||
const MAT2 *lpmat2);
|
||||
|
||||
static DWORD(STDCALL *real_GetGlyphOutline)(
|
||||
HDC hdc,
|
||||
UINT uChar,
|
||||
UINT uFormat,
|
||||
LPGLYPHMETRICS lpgm,
|
||||
DWORD cbBuffer,
|
||||
LPVOID lpvBuffer,
|
||||
const MAT2 *lpmat2);
|
||||
|
||||
static const struct hook_symbol gfx_hook_syms[] = {
|
||||
{.name = "GetGlyphOutlineA",
|
||||
.patch = my_GetGlyphOutline,
|
||||
.link = (void **) &real_GetGlyphOutline},
|
||||
{
|
||||
.name = "IsDBCSLeadByteEx",
|
||||
.patch = my_GetGlyphOutline, // !??
|
||||
.link = (void **) &real_GetGlyphOutline // !??
|
||||
},
|
||||
};
|
||||
|
||||
static DWORD STDCALL my_GetGlyphOutline(
|
||||
HDC hdc,
|
||||
UINT uChar,
|
||||
UINT uFormat,
|
||||
LPGLYPHMETRICS lpgm,
|
||||
DWORD cbBuffer,
|
||||
LPVOID lpvBuffer,
|
||||
const MAT2 *lpmat2)
|
||||
{
|
||||
if (IsDBCSLeadByteEx(CP_ACP, uChar & 0xFF)) {
|
||||
log_warning("!!!!!!!!");
|
||||
|
||||
char tmp[2];
|
||||
|
||||
tmp[0] = uChar & 0xFF;
|
||||
tmp[1] = (uChar >> 8) & 0xFF;
|
||||
|
||||
MultiByteToWideChar(
|
||||
CP_ACP, MB_USEGLYPHCHARS, tmp, 2, lpvBuffer, cbBuffer);
|
||||
}
|
||||
|
||||
return real_GetGlyphOutline(
|
||||
hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, lpmat2);
|
||||
}
|
||||
|
||||
void jbhook_util_gfx_hook_init(void)
|
||||
{
|
||||
hook_table_apply(NULL, "gdi32.dll", gfx_hook_syms, lengthof(gfx_hook_syms));
|
||||
|
||||
log_info("Inserted gfx hooks");
|
||||
}
|
||||
|
||||
void jbhook_util_gfx_set_windowed(bool framed)
|
||||
{
|
||||
}
|
||||
|
||||
void jbhook_util_gfx_install_vertical_hooks(void) {
|
||||
hook_table_apply(
|
||||
NULL,
|
||||
"opengl32.dll",
|
||||
jbhook1_opengl_hook_syms,
|
||||
lengthof(jbhook1_opengl_hook_syms));
|
||||
|
||||
hook_table_apply(
|
||||
NULL,
|
||||
"glhelper.dll",
|
||||
jbhook1_glhelper_hook_syms,
|
||||
lengthof(jbhook1_glhelper_hook_syms));
|
||||
|
||||
log_info("Inserted vertical display hooks");
|
||||
}
|
||||
|
||||
// only jubeat uses openGL, let alone needs rotation at all, so hardcode for now
|
||||
#define W 768
|
||||
#define H 1360
|
||||
|
||||
static GLuint fb;
|
||||
static GLuint color;
|
||||
|
||||
static void fb_init(void) {
|
||||
static bool init_done = false;
|
||||
|
||||
if(init_done) {
|
||||
return;
|
||||
}
|
||||
|
||||
init_done = true;
|
||||
|
||||
glGenFramebuffersEXT(1, &fb);
|
||||
glGenTextures(1, &color);
|
||||
}
|
||||
|
||||
static uint8_t pixels_raw[W*H*3];
|
||||
static uint8_t pixels_rot[W*H*3];
|
||||
|
||||
static void __stdcall hook_glFlush(void) {
|
||||
glReadPixels(0, 0, H, W, GL_RGB, GL_UNSIGNED_BYTE, pixels_raw);
|
||||
|
||||
for(size_t x = 0; x < W; x++) {
|
||||
for(size_t y = 0; y < H; y++) {
|
||||
memcpy(&pixels_rot[3*(y*W + x)], &pixels_raw[3*((W-x)*H + y)], 3);
|
||||
}
|
||||
}
|
||||
|
||||
real_glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDrawPixels(W, H, GL_RGB, GL_UNSIGNED_BYTE, pixels_rot);
|
||||
|
||||
real_glFlush();
|
||||
|
||||
fb_init();
|
||||
real_glBindFramebufferEXT(GL_FRAMEBUFFER, fb);
|
||||
glBindTexture(GL_TEXTURE_2D, color);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, H, W, 0, GL_RGBA,GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
|
||||
}
|
||||
|
||||
static void hook_glBindFramebufferEXT(GLenum target, GLuint framebuffer) {
|
||||
fb_init();
|
||||
|
||||
if(target == GL_FRAMEBUFFER && framebuffer == 0) {
|
||||
framebuffer = fb;
|
||||
}
|
||||
|
||||
return real_glBindFramebufferEXT(target, framebuffer);
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
* Hook some gfx related functions to patch gfx related stuff
|
||||
* like enabling window mode.
|
||||
*/
|
||||
void gfx_hook_init(void);
|
||||
void jbhook_util_gfx_hook_init(void);
|
||||
|
||||
/**
|
||||
* Set the game to window mode.
|
||||
@ -15,6 +15,11 @@ void gfx_hook_init(void);
|
||||
* @param framed True to add a window frame and make the window
|
||||
* movable, resizable, minizable. False for no frame.
|
||||
*/
|
||||
void gfx_set_windowed(bool framed);
|
||||
void jbhook_util_gfx_set_windowed(bool framed);
|
||||
|
||||
/**
|
||||
* Rotate a horizontal-by-default jubeat window to vertical
|
||||
*/
|
||||
void jbhook_util_gfx_install_vertical_hooks(void);
|
||||
|
||||
#endif
|
37
src/main/jbhook-util/locale.c
Normal file
37
src/main/jbhook-util/locale.c
Normal file
@ -0,0 +1,37 @@
|
||||
#define LOG_MODULE "jbhook-locale"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
|
||||
// ANSI/OEM Japanese; Japanese (Shift-JIS)
|
||||
#define CODEPAGE_SHIFT_JIS 932
|
||||
|
||||
static UINT WINAPI hook_GetACP();
|
||||
static UINT WINAPI hook_GetOEMCP();
|
||||
|
||||
static const struct hook_symbol locale_hook_syms[] = {
|
||||
{.name = "GetOEMCP",
|
||||
.patch = hook_GetACP},
|
||||
{.name = "GetOEMCP",
|
||||
.patch = hook_GetOEMCP},
|
||||
};
|
||||
|
||||
static UINT WINAPI hook_GetACP() {
|
||||
return CODEPAGE_SHIFT_JIS;
|
||||
}
|
||||
|
||||
static UINT WINAPI hook_GetOEMCP() {
|
||||
return CODEPAGE_SHIFT_JIS;
|
||||
}
|
||||
|
||||
|
||||
void jbhook_util_locale_hook_init(void)
|
||||
{
|
||||
hook_table_apply(NULL, "kernel32.dll", locale_hook_syms, lengthof(locale_hook_syms));
|
||||
|
||||
log_info("Inserted locale hooks");
|
||||
}
|
6
src/main/jbhook-util/locale.h
Normal file
6
src/main/jbhook-util/locale.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef JBHOOK_LOCALE_H
|
||||
#define JBHOOK_LOCALE_H
|
||||
|
||||
void jbhook_util_locale_hook_init(void);
|
||||
|
||||
#endif
|
79
src/main/jbhook-util/mixer.c
Normal file
79
src/main/jbhook-util/mixer.c
Normal file
@ -0,0 +1,79 @@
|
||||
#define LOG_MODULE "jbhook-mixer"
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
|
||||
MMRESULT STDCALL hook_mixerGetLineControlsA(HMIXEROBJ hmxobj, LPMIXERLINECONTROLSA pmxlc, DWORD fdwControls);
|
||||
MMRESULT STDCALL hook_mixerGetDevCapsA(UINT_PTR uMxId, LPMIXERCAPSA pmxcaps, UINT cbmxcaps);
|
||||
MMRESULT STDCALL hook_mixerOpen(LPHMIXER phmx, UINT uMxId, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen);
|
||||
MMRESULT STDCALL hook_mixerSetControlDetails(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails);
|
||||
MMRESULT STDCALL hook_mixerGetControlDetailsA(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails);
|
||||
MMRESULT STDCALL hook_mixerClose(HMIXER hmx);
|
||||
MMRESULT STDCALL hook_mixerGetLineInfoA(HMIXEROBJ hmxobj, LPMIXERLINEA pmxl, DWORD fdwInfo);
|
||||
|
||||
static const struct hook_symbol mixer_hook_syms[] = {
|
||||
{.name = "mixerGetLineControlsA",
|
||||
.patch = hook_mixerGetLineControlsA},
|
||||
{.name = "mixerGetDevCapsA",
|
||||
.patch = hook_mixerGetDevCapsA},
|
||||
{.name = "mixerOpen",
|
||||
.patch = hook_mixerOpen},
|
||||
{.name = "mixerSetControlDetails",
|
||||
.patch = hook_mixerSetControlDetails},
|
||||
{.name = "mixerGetControlDetailsA",
|
||||
.patch = hook_mixerGetControlDetailsA},
|
||||
{.name = "mixerClose",
|
||||
.patch = hook_mixerClose},
|
||||
{.name = "mixerGetLineInfoA",
|
||||
.patch = hook_mixerGetLineInfoA},
|
||||
};
|
||||
|
||||
/*
|
||||
Some of these functions return values which are used as pointer offsets into
|
||||
memory, but that doesn't matter because the game never *modifies* the
|
||||
pointed-to value, only passes it to the other mixer functions. So it's safe
|
||||
to not set any of the returning data.
|
||||
*/
|
||||
|
||||
MMRESULT STDCALL hook_mixerOpen(LPHMIXER phmx, UINT uMxId, DWORD_PTR dwCallback, DWORD_PTR dwInstance, DWORD fdwOpen) {
|
||||
*(DWORD*)phmx = 1234; // any non-zero value is fine
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
MMRESULT STDCALL hook_mixerClose(HMIXER hmx) {
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
MMRESULT STDCALL hook_mixerGetLineControlsA(HMIXEROBJ hmxobj, LPMIXERLINECONTROLSA pmxlc, DWORD fdwControls) {
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
MMRESULT STDCALL hook_mixerGetDevCapsA(UINT_PTR uMxId, LPMIXERCAPSA pmxcaps, UINT cbmxcaps) {
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
MMRESULT STDCALL hook_mixerGetControlDetailsA(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails) {
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
MMRESULT STDCALL hook_mixerGetLineInfoA(HMIXEROBJ hmxobj, LPMIXERLINEA pmxl, DWORD fdwInfo) {
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
MMRESULT STDCALL hook_mixerSetControlDetails(HMIXEROBJ hmxobj, LPMIXERCONTROLDETAILS pmxcd, DWORD fdwDetails) {
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
|
||||
void jbhook_util_mixer_hook_init(void)
|
||||
{
|
||||
hook_table_apply(NULL, "winmm.dll", mixer_hook_syms, lengthof(mixer_hook_syms));
|
||||
|
||||
log_info("Inserted mixer hooks");
|
||||
}
|
11
src/main/jbhook-util/mixer.h
Normal file
11
src/main/jbhook-util/mixer.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef JBHOOK_MIXER_H
|
||||
#define JBHOOK_MIXER_H
|
||||
|
||||
/**
|
||||
* Hook some mixer related functions and stub out attempts to change the volume.
|
||||
* In addition to being annoying, this can fail on Vista+ on some outputs,
|
||||
* despite not actually preventing sound from playing.
|
||||
*/
|
||||
void jbhook_util_mixer_hook_init(void);
|
||||
|
||||
#endif
|
206
src/main/jbhook-util/p3io.c
Normal file
206
src/main/jbhook-util/p3io.c
Normal file
@ -0,0 +1,206 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "bemanitools/jbio.h"
|
||||
|
||||
#include "jbhook-util/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 jbhook_p3io_read_jamma(void *ctx, uint32_t *state);
|
||||
static HRESULT jbhook_p3io_get_roundplug(
|
||||
void *ctx, uint8_t plug_id, uint8_t *rom, uint8_t *eeprom);
|
||||
static HRESULT jbhook_p3io_set_outputs(void *ctx, uint32_t state);
|
||||
|
||||
/*
|
||||
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 jbhook_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 jbhook_p3io_sys_button_mappings[] = {
|
||||
(1 << 4),
|
||||
(1 << 6),
|
||||
(1 << 5),
|
||||
};
|
||||
|
||||
static struct security_mcode jbhook_p3io_mcode;
|
||||
static struct security_id jbhook_p3io_pcbid;
|
||||
static struct security_id jbhook_p3io_eamid;
|
||||
|
||||
static const struct p3io_ops p3io_ddr_ops = {
|
||||
.read_jamma = jbhook_p3io_read_jamma,
|
||||
.get_roundplug = jbhook_p3io_get_roundplug,
|
||||
.set_outputs = jbhook_p3io_set_outputs,
|
||||
};
|
||||
|
||||
void jbhook_util_p3io_init(
|
||||
const struct security_mcode *mcode,
|
||||
const struct security_id *pcbid,
|
||||
const struct security_id *eamid)
|
||||
{
|
||||
memcpy(&jbhook_p3io_mcode, mcode, sizeof(struct security_mcode));
|
||||
memcpy(&jbhook_p3io_pcbid, pcbid, sizeof(struct security_id));
|
||||
memcpy(&jbhook_p3io_eamid, eamid, sizeof(struct security_id));
|
||||
|
||||
p3io_emu_init(&p3io_ddr_ops, NULL);
|
||||
}
|
||||
|
||||
void jbhook_util_p3io_fini(void)
|
||||
{
|
||||
p3io_emu_fini();
|
||||
}
|
||||
|
||||
static HRESULT jbhook_p3io_read_jamma(void *ctx, uint32_t *state)
|
||||
{
|
||||
uint16_t panels;
|
||||
uint8_t buttons;
|
||||
|
||||
log_assert(state != NULL);
|
||||
|
||||
*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++) {
|
||||
// panels are active-low
|
||||
if ((panels & (1 << i)) == 0) {
|
||||
*state |= jbhook_p3io_panel_mappings[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
// sys buttons are active-high
|
||||
if (buttons & (1 << i)) {
|
||||
*state |= jbhook_p3io_sys_button_mappings[i];
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT jbhook_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, jbhook_p3io_pcbid.id, sizeof(jbhook_p3io_pcbid.id));
|
||||
security_rp3_generate_signed_eeprom_data(
|
||||
SECURITY_RP_UTIL_RP_TYPE_BLACK,
|
||||
&security_rp_sign_key_black_gfdmv4,
|
||||
&jbhook_p3io_mcode,
|
||||
&jbhook_p3io_pcbid,
|
||||
&eeprom_out);
|
||||
} else {
|
||||
/* white */
|
||||
memcpy(rom, jbhook_p3io_eamid.id, sizeof(jbhook_p3io_eamid.id));
|
||||
security_rp3_generate_signed_eeprom_data(
|
||||
SECURITY_RP_UTIL_RP_TYPE_WHITE,
|
||||
&security_rp_sign_key_white_eamuse,
|
||||
&security_mcode_eamuse,
|
||||
&jbhook_p3io_eamid,
|
||||
&eeprom_out);
|
||||
}
|
||||
|
||||
memcpy(eeprom, &eeprom_out, sizeof(struct security_rp3_eeprom));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT jbhook_p3io_set_outputs(void *ctx, uint32_t state) {
|
||||
uint8_t p3io_panel = (state & 0x00FF00) >> 8;
|
||||
uint8_t p3io_coinblocker = (state & 0xFF0000) >> 16;
|
||||
|
||||
enum jb_io_panel_mode panel_mode;
|
||||
|
||||
switch(p3io_panel) {
|
||||
case 5:
|
||||
panel_mode = JB_IO_PANEL_MODE_TOP_LEFT;
|
||||
break;
|
||||
case 4:
|
||||
panel_mode = JB_IO_PANEL_MODE_TOP_RIGHT;
|
||||
break;
|
||||
case 6:
|
||||
panel_mode = JB_IO_PANEL_MODE_BOTTOM_RIGHT;
|
||||
break;
|
||||
case 7:
|
||||
panel_mode = JB_IO_PANEL_MODE_BOTTOM_LEFT;
|
||||
break;
|
||||
default:
|
||||
panel_mode = JB_IO_PANEL_MODE_ALL;
|
||||
break;
|
||||
}
|
||||
|
||||
jb_io_set_panel_mode(panel_mode);
|
||||
|
||||
// 0x40 has been seen to unblock, no other values observed
|
||||
jb_io_set_coin_blocker(p3io_coinblocker == 0x00);
|
||||
|
||||
return S_OK;
|
||||
}
|
@ -9,13 +9,13 @@
|
||||
#include "security/mcode.h"
|
||||
|
||||
/**
|
||||
* Initialize the jbhook1 specific p3io emulation backend.
|
||||
* Initialize the jb01-04 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(
|
||||
void jbhook_util_p3io_init(
|
||||
const struct security_mcode *mcode,
|
||||
const struct security_id *pcbid,
|
||||
const struct security_id *eamid);
|
||||
@ -23,6 +23,6 @@ void jbhook1_p3io_init(
|
||||
/**
|
||||
* Shutdown the p3io emulation backend.
|
||||
*/
|
||||
void jbhook1_p3io_fini(void);
|
||||
void jbhook_util_p3io_fini(void);
|
||||
|
||||
#endif
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "imports/avs.h"
|
||||
|
||||
#include "jbhook/io.h"
|
||||
#include "jbhook-util/p4io.h"
|
||||
|
||||
#include "p4io/cmd.h"
|
||||
|
||||
@ -20,7 +20,7 @@ static uint32_t jbhook_command_handle(
|
||||
void *resp,
|
||||
uint32_t resp_max_len);
|
||||
|
||||
static const struct p4ioemu_device_msg_hook jbhook_io_msg = {
|
||||
static const struct p4ioemu_device_msg_hook jbhook_p4io_msg = {
|
||||
.jamma2_read = jbhook_io_jamma2_read,
|
||||
.command_handle = jbhook_command_handle,
|
||||
.roundplug_read_id = NULL,
|
||||
@ -181,7 +181,7 @@ static uint32_t jbhook_command_handle(
|
||||
}
|
||||
}
|
||||
|
||||
const struct p4ioemu_device_msg_hook *jbhook_io_init(void)
|
||||
const struct p4ioemu_device_msg_hook *jbhook_p4io_init(void)
|
||||
{
|
||||
return &jbhook_io_msg;
|
||||
return &jbhook_p4io_msg;
|
||||
}
|
@ -3,6 +3,6 @@
|
||||
|
||||
#include "p4ioemu/device.h"
|
||||
|
||||
const struct p4ioemu_device_msg_hook *jbhook_io_init(void);
|
||||
const struct p4ioemu_device_msg_hook *jbhook_p4io_init(void);
|
||||
|
||||
#endif
|
||||
#endif
|
15
src/main/jbhook-util/security.h
Normal file
15
src/main/jbhook-util/security.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef JBHOOK_UTIL_SECURITY_H
|
||||
#define JBHOOK_UTIL_SECURITY_H
|
||||
|
||||
#include "security/mcode.h"
|
||||
|
||||
static const struct security_mcode jbhook_util_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,
|
||||
};
|
||||
|
||||
#endif
|
@ -1,25 +0,0 @@
|
||||
avsdlls += jbhook
|
||||
|
||||
deplibs_jbhook := \
|
||||
avs \
|
||||
|
||||
ldflags_jbhook := \
|
||||
-lws2_32 \
|
||||
-liphlpapi \
|
||||
|
||||
libs_jbhook := \
|
||||
acioemu \
|
||||
eamio \
|
||||
jbio \
|
||||
p4ioemu \
|
||||
hook \
|
||||
hooklib \
|
||||
util \
|
||||
|
||||
src_jbhook := \
|
||||
acio.c \
|
||||
dllmain.c \
|
||||
eamuse.c \
|
||||
gfx.c \
|
||||
options.c \
|
||||
io.c
|
@ -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/iccb.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_iccb ac_io_emu_iccb;
|
||||
static struct ac_io_emu_h44b ac_io_emu_h44b;
|
||||
|
||||
void ac_io_port_init(void)
|
||||
{
|
||||
ac_io_emu_init(&ac_io_emu, L"COM2");
|
||||
ac_io_emu_iccb_init(&ac_io_emu_iccb, &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_iccb_dispatch_request(&ac_io_emu_iccb, 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);
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
#ifndef JBHOOK_ACIO_H
|
||||
#define JBHOOK_ACIO_H
|
||||
|
||||
void ac_io_port_init(void);
|
||||
void ac_io_port_fini(void);
|
||||
HRESULT ac_io_port_dispatch_irp(struct irp *irp);
|
||||
|
||||
#endif
|
@ -1,67 +0,0 @@
|
||||
#define LOG_MODULE "eamuse-hook"
|
||||
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
#include "util/str.h"
|
||||
|
||||
static const char *jbhook_eamuse_konami_url = "eamuse.konami.";
|
||||
|
||||
static int(STDCALL *real_getaddrinfo)(
|
||||
PCSTR pNodeName,
|
||||
PCSTR pServiceName,
|
||||
const ADDRINFOA *pHints,
|
||||
PADDRINFOA *ppResult);
|
||||
|
||||
static int STDCALL my_getaddrinfo(
|
||||
PCSTR pNodeName,
|
||||
PCSTR pServiceName,
|
||||
const ADDRINFOA *pHints,
|
||||
PADDRINFOA *ppResult);
|
||||
|
||||
static const struct hook_symbol eamuse_hook_syms[] = {
|
||||
{
|
||||
.name = "getaddrinfo",
|
||||
.ordinal = 176,
|
||||
.patch = my_getaddrinfo,
|
||||
.link = (void **) &real_getaddrinfo,
|
||||
},
|
||||
};
|
||||
|
||||
static int STDCALL my_getaddrinfo(
|
||||
PCSTR pNodeName,
|
||||
PCSTR pServiceName,
|
||||
const ADDRINFOA *pHints,
|
||||
PADDRINFOA *ppResult)
|
||||
{
|
||||
log_misc("my_getaddrinfo: %s, %s", pNodeName, pServiceName);
|
||||
|
||||
/* resolve eamuse.konami.fun/com to 127.0.0.1 to avoid lag spikes every
|
||||
150 seconds which might happen in-game as well */
|
||||
if (!strncmp(
|
||||
pNodeName,
|
||||
jbhook_eamuse_konami_url,
|
||||
strlen(jbhook_eamuse_konami_url))) {
|
||||
log_info("Resolve konami.eamuse.XXX -> localhost");
|
||||
pNodeName = "localhost";
|
||||
}
|
||||
|
||||
return real_getaddrinfo(pNodeName, pServiceName, pHints, ppResult);
|
||||
}
|
||||
|
||||
void jbhook_eamuse_hook_init(void)
|
||||
{
|
||||
hook_table_apply(
|
||||
NULL, "ws2_32.dll", eamuse_hook_syms, lengthof(eamuse_hook_syms));
|
||||
|
||||
log_info("Inserted eamuse hooks");
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#ifndef JBHOOK_EAMUSE_H
|
||||
#define JBHOOK_EAMUSE_H
|
||||
|
||||
void jbhook_eamuse_hook_init(void);
|
||||
|
||||
#endif
|
@ -1,83 +0,0 @@
|
||||
#define LOG_MODULE "jbhook-gfx"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hook/com-proxy.h"
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "jbhook/gfx.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
#include "util/str.h"
|
||||
#include "util/time.h"
|
||||
|
||||
static DWORD STDCALL my_GetGlyphOutline(
|
||||
HDC hdc,
|
||||
UINT uChar,
|
||||
UINT uFormat,
|
||||
LPGLYPHMETRICS lpgm,
|
||||
DWORD cbBuffer,
|
||||
LPVOID lpvBuffer,
|
||||
const MAT2 *lpmat2);
|
||||
|
||||
static DWORD(STDCALL *real_GetGlyphOutline)(
|
||||
HDC hdc,
|
||||
UINT uChar,
|
||||
UINT uFormat,
|
||||
LPGLYPHMETRICS lpgm,
|
||||
DWORD cbBuffer,
|
||||
LPVOID lpvBuffer,
|
||||
const MAT2 *lpmat2);
|
||||
|
||||
static const struct hook_symbol gfx_hook_syms[] = {
|
||||
{.name = "GetGlyphOutlineA",
|
||||
.patch = my_GetGlyphOutline,
|
||||
.link = (void **) &real_GetGlyphOutline},
|
||||
{
|
||||
.name = "IsDBCSLeadByteEx",
|
||||
.patch = my_GetGlyphOutline, // !??
|
||||
.link = (void **) &real_GetGlyphOutline // !??
|
||||
},
|
||||
};
|
||||
|
||||
static DWORD STDCALL my_GetGlyphOutline(
|
||||
HDC hdc,
|
||||
UINT uChar,
|
||||
UINT uFormat,
|
||||
LPGLYPHMETRICS lpgm,
|
||||
DWORD cbBuffer,
|
||||
LPVOID lpvBuffer,
|
||||
const MAT2 *lpmat2)
|
||||
{
|
||||
if (IsDBCSLeadByteEx(CP_ACP, uChar & 0xFF)) {
|
||||
log_warning("!!!!!!!!");
|
||||
|
||||
char tmp[2];
|
||||
|
||||
tmp[0] = uChar & 0xFF;
|
||||
tmp[1] = (uChar >> 8) & 0xFF;
|
||||
|
||||
MultiByteToWideChar(
|
||||
CP_ACP, MB_USEGLYPHCHARS, tmp, 2, lpvBuffer, cbBuffer);
|
||||
}
|
||||
|
||||
return real_GetGlyphOutline(
|
||||
hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, lpmat2);
|
||||
}
|
||||
|
||||
void gfx_hook_init(void)
|
||||
{
|
||||
hook_table_apply(NULL, "gdi32.dll", gfx_hook_syms, lengthof(gfx_hook_syms));
|
||||
|
||||
log_info("Inserted gfx hooks");
|
||||
}
|
||||
|
||||
void gfx_set_windowed(bool framed)
|
||||
{
|
||||
}
|
@ -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 \
|
||||
|
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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("-------------------------------------------------------------");
|
||||
|
@ -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;
|
||||
}
|
27
src/main/jbhook2/Module.mk
Normal file
27
src/main/jbhook2/Module.mk
Normal file
@ -0,0 +1,27 @@
|
||||
avsdlls += jbhook2
|
||||
|
||||
deplibs_jbhook2 := \
|
||||
avs \
|
||||
glhelper \
|
||||
|
||||
ldflags_jbhook2 := \
|
||||
-lws2_32 \
|
||||
-liphlpapi \
|
||||
-lopengl32 \
|
||||
|
||||
libs_jbhook2 := \
|
||||
acioemu \
|
||||
eamio \
|
||||
jbio \
|
||||
jbhook-util \
|
||||
p3ioemu \
|
||||
p3io \
|
||||
p4ioemu \
|
||||
hook \
|
||||
hooklib \
|
||||
security \
|
||||
util \
|
||||
|
||||
src_jbhook2 := \
|
||||
dllmain.c \
|
||||
options.c
|
209
src/main/jbhook2/dllmain.c
Normal file
209
src/main/jbhook2/dllmain.c
Normal file
@ -0,0 +1,209 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bemanitools/eamio.h"
|
||||
#include "bemanitools/jbio.h"
|
||||
|
||||
#include "hook/iohook.h"
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "hooklib/adapter.h"
|
||||
#include "hooklib/app.h"
|
||||
#include "hooklib/rs232.h"
|
||||
#include "hooklib/setupapi.h"
|
||||
|
||||
#include "imports/avs.h"
|
||||
|
||||
#include "jbhook2/options.h"
|
||||
|
||||
#include "jbhook-util/acio.h"
|
||||
#include "jbhook-util/eamuse.h"
|
||||
#include "jbhook-util/gfx.h"
|
||||
#include "jbhook-util/p3io.h"
|
||||
#include "jbhook-util/security.h"
|
||||
|
||||
#include "p3ioemu/devmgr.h"
|
||||
#include "p3ioemu/emu.h"
|
||||
|
||||
#include "p4ioemu/device.h"
|
||||
#include "p4ioemu/setupapi.h"
|
||||
|
||||
#include "security/id.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
#include "util/thread.h"
|
||||
|
||||
static struct options options;
|
||||
|
||||
static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
{
|
||||
jbhook_util_gfx_install_vertical_hooks();
|
||||
|
||||
bool eam_io_ok;
|
||||
bool jb_io_ok;
|
||||
|
||||
eam_io_ok = false;
|
||||
jb_io_ok = false;
|
||||
|
||||
log_info("--- Begin jbhook dll_entry_init ---");
|
||||
|
||||
if (!options.disable_p3ioemu) {
|
||||
log_assert(sidcode != NULL);
|
||||
// pcbid and eamid are only used here for sec check, the ones used for
|
||||
// network access are taken from ea3-config.xml
|
||||
jbhook_util_p3io_init(
|
||||
&jbhook_util_security_default_mcode,
|
||||
&security_id_default, &security_id_default);
|
||||
|
||||
log_info("Starting up jubeat IO backend");
|
||||
|
||||
jb_io_set_loggers(
|
||||
log_impl_misc, log_impl_info, log_impl_warning, log_impl_fatal);
|
||||
|
||||
jb_io_ok =
|
||||
jb_io_init(avs_thread_create, avs_thread_join, avs_thread_destroy);
|
||||
|
||||
if (!jb_io_ok) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.disable_cardemu) {
|
||||
jbhook_util_ac_io_port_init(L"COM1");
|
||||
|
||||
log_info("Starting up card reader backend");
|
||||
|
||||
eam_io_set_loggers(
|
||||
log_impl_misc, log_impl_info, log_impl_warning, log_impl_fatal);
|
||||
|
||||
eam_io_ok =
|
||||
eam_io_init(avs_thread_create, avs_thread_join, avs_thread_destroy);
|
||||
|
||||
if (!eam_io_ok) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
log_info("--- End jbhook dll_entry_init ---");
|
||||
|
||||
bool ret = app_hook_invoke_init(sidcode, param);
|
||||
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
if (eam_io_ok) {
|
||||
eam_io_fini();
|
||||
}
|
||||
|
||||
if (jb_io_ok) {
|
||||
jb_io_fini();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool my_dll_entry_main(void)
|
||||
{
|
||||
bool result;
|
||||
|
||||
result = app_hook_invoke_main();
|
||||
|
||||
log_info("Shutting down card reader backend");
|
||||
eam_io_fini();
|
||||
|
||||
log_info("Shutting down Jubeat IO backend");
|
||||
jb_io_fini();
|
||||
|
||||
if (!options.disable_cardemu) {
|
||||
jbhook_util_ac_io_port_fini();
|
||||
}
|
||||
|
||||
if (!options.disable_p3ioemu) {
|
||||
jbhook_util_p3io_fini();
|
||||
}
|
||||
|
||||
options_fini(&options);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static HWND CDECL
|
||||
my_mwindow_create(HINSTANCE, void *, const char *, DWORD, DWORD, BOOL);
|
||||
static HWND(CDECL *real_mwindow_create)(
|
||||
HINSTANCE, void *, const char *, DWORD, DWORD, BOOL);
|
||||
|
||||
static const struct hook_symbol init_hook_syms[] = {
|
||||
{
|
||||
.name = "mwindow_create",
|
||||
.patch = my_mwindow_create,
|
||||
.link = (void **) &real_mwindow_create,
|
||||
},
|
||||
};
|
||||
|
||||
static HWND CDECL my_mwindow_create(
|
||||
HINSTANCE hinstance,
|
||||
void *callback,
|
||||
const char *window_title,
|
||||
DWORD window_width,
|
||||
DWORD window_height,
|
||||
BOOL fullscreen)
|
||||
{
|
||||
log_info("-------------------------------------------------------------");
|
||||
log_info("---------------- Begin jbhook mwindow_create ----------------");
|
||||
log_info("-------------------------------------------------------------");
|
||||
|
||||
DWORD tmp = window_width;
|
||||
window_width = window_height;
|
||||
window_height = tmp;
|
||||
|
||||
return real_mwindow_create(
|
||||
hinstance,
|
||||
callback,
|
||||
window_title,
|
||||
window_width,
|
||||
window_height,
|
||||
0);
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
|
||||
{
|
||||
if (reason != DLL_PROCESS_ATTACH) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
log_to_external(
|
||||
log_body_misc, log_body_info, log_body_warning, log_body_fatal);
|
||||
|
||||
options_init_from_cmdline(&options);
|
||||
|
||||
hook_table_apply(
|
||||
NULL, "mwindow.dll", init_hook_syms, lengthof(init_hook_syms));
|
||||
|
||||
app_hook_init(my_dll_entry_init, my_dll_entry_main);
|
||||
|
||||
iohook_push_handler(p3io_emu_dispatch_irp);
|
||||
|
||||
iohook_push_handler(jbhook_util_ac_io_port_dispatch_irp);
|
||||
|
||||
if (!options.disable_adapteremu) {
|
||||
adapter_hook_init();
|
||||
}
|
||||
|
||||
if (!options.disable_cardemu) {
|
||||
rs232_hook_init();
|
||||
}
|
||||
|
||||
if (!options.disable_p3ioemu) {
|
||||
p3io_setupapi_insert_hooks(NULL);
|
||||
}
|
||||
|
||||
jbhook_util_gfx_hook_init();
|
||||
jbhook_util_eamuse_hook_init();
|
||||
|
||||
return TRUE;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
LIBRARY jbhook
|
||||
LIBRARY jbhook2
|
||||
|
||||
EXPORTS
|
||||
DllMain@12 @1 NONAME
|
108
src/main/jbhook2/options.c
Normal file
108
src/main/jbhook2/options.c
Normal file
@ -0,0 +1,108 @@
|
||||
#include "jbhook2/options.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util/cmdline.h"
|
||||
#include "util/defs.h"
|
||||
#include "util/hex.h"
|
||||
#include "util/log.h"
|
||||
#include "util/str.h"
|
||||
|
||||
void options_init_from_cmdline(struct options *options)
|
||||
{
|
||||
int argc;
|
||||
char **argv;
|
||||
bool ok;
|
||||
|
||||
args_recover(&argc, &argv);
|
||||
|
||||
options_init(options);
|
||||
|
||||
ok = options_read_cmdline(options, argc, (const char **) argv);
|
||||
|
||||
args_free(argc, argv);
|
||||
|
||||
if (!ok) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void options_init(struct options *options)
|
||||
{
|
||||
options->windowed = false;
|
||||
options->window_framed = false;
|
||||
options->disable_p3ioemu = false;
|
||||
options->disable_cardemu = false;
|
||||
options->disable_adapteremu = false;
|
||||
}
|
||||
|
||||
bool options_read_cmdline(struct options *options, int argc, const char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (argv[i][0] != '-') {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (argv[i][1]) {
|
||||
case 'h': {
|
||||
options_print_usage();
|
||||
return false;
|
||||
}
|
||||
|
||||
case 'w': {
|
||||
options->windowed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'f': {
|
||||
options->window_framed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'a': {
|
||||
options->disable_adapteremu = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'c': {
|
||||
options->disable_cardemu = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'p': {
|
||||
options->disable_p3ioemu = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void options_print_usage(void)
|
||||
{
|
||||
OutputDebugStringA("jbhook for jubeat, build " __DATE__ " " __TIME__ ", gitrev " STRINGIFY(
|
||||
GITREV) "\n"
|
||||
"Usage: launcher.exe -K jbhook2.dll [game exec] <options> \n"
|
||||
"\n"
|
||||
" The following options can be specified after the game exec path:\n"
|
||||
"\n"
|
||||
" -h Print this usage message\n"
|
||||
" -w Run the game windowed\n"
|
||||
" -f Run the game in a framed window (needs -w option)\n"
|
||||
" -a Disable adapter hook\n"
|
||||
" -c Disable card emulation (e.g. when running on a "
|
||||
"real cab)\n"
|
||||
" -p Disable p3io emulation (e.g. when running on a "
|
||||
"real cab)\n");
|
||||
}
|
||||
|
||||
void options_fini(struct options *options)
|
||||
{
|
||||
}
|
22
src/main/jbhook2/options.h
Normal file
22
src/main/jbhook2/options.h
Normal file
@ -0,0 +1,22 @@
|
||||
#ifndef JBHOOK_OPTIONS_H
|
||||
#define JBHOOK_OPTIONS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct options {
|
||||
bool windowed;
|
||||
bool window_framed;
|
||||
bool disable_p3ioemu;
|
||||
bool disable_cardemu;
|
||||
bool disable_adapteremu;
|
||||
};
|
||||
|
||||
void options_init_from_cmdline(struct options *options);
|
||||
|
||||
void options_init(struct options *options);
|
||||
bool options_read_cmdline(struct options *options, int argc, const char **argv);
|
||||
void options_print_usage(void);
|
||||
void options_fini(struct options *options);
|
||||
|
||||
#endif
|
25
src/main/jbhook3/Module.mk
Normal file
25
src/main/jbhook3/Module.mk
Normal file
@ -0,0 +1,25 @@
|
||||
avsdlls += jbhook3
|
||||
|
||||
deplibs_jbhook3 := \
|
||||
avs \
|
||||
|
||||
ldflags_jbhook3 := \
|
||||
-lws2_32 \
|
||||
-liphlpapi \
|
||||
|
||||
libs_jbhook3 := \
|
||||
acioemu \
|
||||
eamio \
|
||||
jbio \
|
||||
jbhook-util \
|
||||
p3ioemu \
|
||||
p3io \
|
||||
p4ioemu \
|
||||
hook \
|
||||
hooklib \
|
||||
security \
|
||||
util \
|
||||
|
||||
src_jbhook3 := \
|
||||
dllmain.c \
|
||||
options.c
|
@ -17,15 +17,19 @@
|
||||
|
||||
#include "imports/avs.h"
|
||||
|
||||
#include "jbhook/acio.h"
|
||||
#include "jbhook/eamuse.h"
|
||||
#include "jbhook/gfx.h"
|
||||
#include "jbhook/io.h"
|
||||
#include "jbhook/options.h"
|
||||
#include "jbhook3/options.h"
|
||||
|
||||
#include "jbhook-util/acio.h"
|
||||
#include "jbhook-util/eamuse.h"
|
||||
#include "jbhook-util/gfx.h"
|
||||
#include "jbhook-util/p4io.h"
|
||||
#include "jbhook-util/security.h"
|
||||
|
||||
#include "p4ioemu/device.h"
|
||||
#include "p4ioemu/setupapi.h"
|
||||
|
||||
#include "security/id.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
#include "util/thread.h"
|
||||
@ -43,7 +47,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
log_info("--- Begin jbhook dll_entry_init ---");
|
||||
|
||||
iohook_push_handler(p4ioemu_dispatch_irp);
|
||||
iohook_push_handler(ac_io_port_dispatch_irp);
|
||||
iohook_push_handler(jbhook_util_ac_io_port_dispatch_irp);
|
||||
|
||||
if (!options.disable_p4ioemu) {
|
||||
log_info("Starting up jubeat IO backend");
|
||||
@ -59,7 +63,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
}
|
||||
|
||||
hook_setupapi_init(&p4ioemu_setupapi_data);
|
||||
p4ioemu_init(jbhook_io_init());
|
||||
p4ioemu_init(jbhook_p4io_init());
|
||||
}
|
||||
|
||||
if (!options.disable_cardemu) {
|
||||
@ -76,12 +80,15 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
}
|
||||
|
||||
rs232_hook_init();
|
||||
ac_io_port_init();
|
||||
jbhook_util_ac_io_port_init(L"COM2");
|
||||
jbhook_util_ac_io_set_iccb();
|
||||
}
|
||||
|
||||
log_info("--- End jbhook dll_entry_init ---");
|
||||
|
||||
return app_hook_invoke_init(sidcode, param);
|
||||
bool ret = app_hook_invoke_init(sidcode, param);
|
||||
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
if (eam_io_ok) {
|
||||
@ -108,7 +115,7 @@ static bool my_dll_entry_main(void)
|
||||
jb_io_fini();
|
||||
|
||||
if (!options.disable_cardemu) {
|
||||
ac_io_port_fini();
|
||||
jbhook_util_ac_io_port_fini();
|
||||
}
|
||||
|
||||
if (!options.disable_p4ioemu) {
|
||||
@ -137,8 +144,8 @@ BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
|
||||
adapter_hook_init();
|
||||
}
|
||||
|
||||
gfx_hook_init();
|
||||
jbhook_eamuse_hook_init();
|
||||
jbhook_util_gfx_hook_init();
|
||||
jbhook_util_eamuse_hook_init();
|
||||
|
||||
return TRUE;
|
||||
}
|
4
src/main/jbhook3/jbhook3.def
Normal file
4
src/main/jbhook3/jbhook3.def
Normal file
@ -0,0 +1,4 @@
|
||||
LIBRARY jbhook3
|
||||
|
||||
EXPORTS
|
||||
DllMain@12 @1 NONAME
|
@ -1,4 +1,4 @@
|
||||
#include "jbhook/options.h"
|
||||
#include "jbhook3/options.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
@ -89,7 +89,7 @@ void options_print_usage(void)
|
||||
{
|
||||
OutputDebugStringA("jbhook for jubeat, build " __DATE__ " " __TIME__ ", gitrev " STRINGIFY(
|
||||
GITREV) "\n"
|
||||
"Usage: launcher.exe -K jbhook.dll [game exec] <options> \n"
|
||||
"Usage: launcher.exe -K jbhook3.dll [game exec] <options> \n"
|
||||
"\n"
|
||||
" The following options can be specified after the game exec path:\n"
|
||||
"\n"
|
@ -2,7 +2,9 @@
|
||||
#define P3IO_IOCTL_H
|
||||
|
||||
enum {
|
||||
P3IO_IOCTL_READ_JAMMA = 0x00222068,
|
||||
P3IO_IOCTL_GET_VERSION = 0x00222004,
|
||||
P3IO_IOCTL_READ_JAMMA = 0x00222068,
|
||||
P3IO_IOCTL_RESET_PIPE = 0x00222098,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -150,10 +150,34 @@ static HRESULT p3io_emu_handle_ioctl(struct irp *irp)
|
||||
uint32_t pad;
|
||||
HRESULT hr;
|
||||
|
||||
if (irp->ioctl != P3IO_IOCTL_READ_JAMMA) {
|
||||
log_warning("Unknown ioctl: %x", irp->ioctl);
|
||||
switch (irp->ioctl) {
|
||||
case P3IO_IOCTL_GET_VERSION: {
|
||||
const char dev_name[] = "bemanitools p3ioemu";
|
||||
|
||||
return E_NOTIMPL;
|
||||
if (irp->read.nbytes < strlen(dev_name)) {
|
||||
log_fatal("Device name string does not fit into buffer");
|
||||
}
|
||||
|
||||
memset(irp->read.bytes, 0, irp->read.nbytes);
|
||||
memcpy(irp->read.bytes, dev_name, strlen(dev_name));
|
||||
irp->read.pos = strlen(dev_name);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
case P3IO_IOCTL_RESET_PIPE:
|
||||
// does not expect a response
|
||||
irp->read.pos = 0;
|
||||
return S_OK;
|
||||
|
||||
case P3IO_IOCTL_READ_JAMMA:
|
||||
// handle it below
|
||||
break;
|
||||
|
||||
default:
|
||||
log_warning("Unknown ioctl %08x", irp->ioctl);
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if (irp->read.nbytes < sizeof(uint32_t)) {
|
||||
|
@ -137,6 +137,19 @@ bool security_id_verify(const struct security_id *id)
|
||||
{
|
||||
log_assert(id);
|
||||
|
||||
return id->header == SECURITY_ID_HEADER &&
|
||||
id->checksum == security_id_checksum_buffer(id->id);
|
||||
if(id->header != SECURITY_ID_HEADER) {
|
||||
log_warning("PCBID header needs to be %02X but was %02X",
|
||||
SECURITY_ID_HEADER, id->header);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t check = id->checksum;
|
||||
uint8_t need = security_id_checksum_buffer(id->id);
|
||||
|
||||
if(check != need) {
|
||||
log_warning("PCBID checksum should be %02X got %02X", need, check);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user