mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2026-09-15 03:45:09 -05:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50ff026b85 | ||
|
|
0ff6134b79 | ||
|
|
ae35b859d9 | ||
|
|
3cf3d44945 | ||
|
|
2a80083af2 | ||
|
|
66e0467ad3 | ||
|
|
c5f0116294 | ||
|
|
ddfa814387 | ||
|
|
088d4bf338 | ||
|
|
f1a7621e2b | ||
|
|
4a3d5fa189 | ||
|
|
0f2828da40 | ||
|
|
ba2016b5bc | ||
|
|
b42c9aa93b | ||
|
|
8de259c639 | ||
|
|
0d54587787 | ||
|
|
4721ba2d3c | ||
|
|
1105a2a130 | ||
|
|
8ab92872ad | ||
|
|
a16dc82cef | ||
|
|
729f5abcc0 |
@@ -41,6 +41,10 @@ build:
|
|||||||
- apk update && apk add make > /dev/null
|
- apk update && apk add make > /dev/null
|
||||||
script:
|
script:
|
||||||
- make build-docker
|
- make build-docker
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- build
|
||||||
|
expire_in: 1 week
|
||||||
|
|
||||||
upload-package-registry:
|
upload-package-registry:
|
||||||
stage: upload
|
stage: upload
|
||||||
@@ -58,7 +62,7 @@ upload-package-registry:
|
|||||||
else
|
else
|
||||||
version="${CI_COMMIT_SHORT_SHA}"
|
version="${CI_COMMIT_SHORT_SHA}"
|
||||||
fi
|
fi
|
||||||
|
- |
|
||||||
curl \
|
curl \
|
||||||
--silent \
|
--silent \
|
||||||
--fail \
|
--fail \
|
||||||
@@ -96,11 +100,9 @@ release-gitlab:
|
|||||||
refs:
|
refs:
|
||||||
- tags
|
- tags
|
||||||
script:
|
script:
|
||||||
|
- version="$CI_COMMIT_TAG"
|
||||||
|
- release_message="$(scripts/ci/create-release-message.sh "${version}" < CHANGELOG.md)"
|
||||||
- |
|
- |
|
||||||
version="$CI_COMMIT_TAG"
|
|
||||||
|
|
||||||
release_message="$(scripts/ci/create-release-message.sh "${version}" < CHANGELOG.md)"
|
|
||||||
|
|
||||||
release-cli create \
|
release-cli create \
|
||||||
--name "bemanitools ${version}" \
|
--name "bemanitools ${version}" \
|
||||||
--description="${release_message}" \
|
--description="${release_message}" \
|
||||||
@@ -114,18 +116,13 @@ release-pigstall:
|
|||||||
refs:
|
refs:
|
||||||
- tags
|
- tags
|
||||||
script:
|
script:
|
||||||
|
- version="${CI_COMMIT_TAG}"
|
||||||
|
- changelog_excerpt="$(scripts/ci/create-release-message.sh "${version}" < CHANGELOG.md)"
|
||||||
|
- release_message="$(printf "bemanitools ${version} released\n${CI_TOOLS_URL}/bemanitools-v${version}.zip\n${changelog_excerpt}")"
|
||||||
|
- session="$(echo "$CI_PIGSTALL_SESSION_BASE64" | base64 -d)"
|
||||||
|
- data_prefix="$(echo "$CI_PIGSTALL_DATA_PREFIX_BASE64" | base64 -d)"
|
||||||
|
- link="$(echo "$CI_PIGSTALL_LINK_BASE64" | base64 -d)"
|
||||||
- |
|
- |
|
||||||
version="${CI_COMMIT_TAG}"
|
|
||||||
|
|
||||||
changelog_excerpt="$(scripts/ci/create-release-message.sh "${version}" < CHANGELOG.md)"
|
|
||||||
|
|
||||||
release_message="$(printf \
|
|
||||||
"bemanitools ${version} released\n${CI_TOOLS_URL}/bemanitools-v${version}.zip\n${changelog_excerpt}")"
|
|
||||||
|
|
||||||
session="$(echo "$CI_PIGSTALL_SESSION_BASE64" | base64 -d)"
|
|
||||||
data_prefix="$(echo "$CI_PIGSTALL_DATA_PREFIX_BASE64" | base64 -d)"
|
|
||||||
link="$(echo "$CI_PIGSTALL_LINK_BASE64" | base64 -d)"
|
|
||||||
|
|
||||||
curl \
|
curl \
|
||||||
--silent \
|
--silent \
|
||||||
--fail \
|
--fail \
|
||||||
|
|||||||
@@ -2,7 +2,13 @@
|
|||||||
Note for CI/CD: Ensure the version formatting in the sections is kept identical to the versions
|
Note for CI/CD: Ensure the version formatting in the sections is kept identical to the versions
|
||||||
given in tags. The pipeline will pick this up and cuts out the relevant section for release notes.
|
given in tags. The pipeline will pick this up and cuts out the relevant section for release notes.
|
||||||
|
|
||||||
|
## 5.38
|
||||||
|
* sdvxhook2: Support sound voltex exceed gear
|
||||||
|
|
||||||
## 5.37
|
## 5.37
|
||||||
|
* jbhook1: Support jubeat (1) and ripples
|
||||||
|
* jbhook2: Support jubeat knit and copious
|
||||||
|
* jbhook3: Support jubeat saucer, prop, qubell, clan and festo
|
||||||
|
|
||||||
## 5.36
|
## 5.36
|
||||||
* iidxhook9: Support for IIDX28
|
* iidxhook9: Support for IIDX28
|
||||||
|
|||||||
@@ -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)echo ... $$(dll_$1_$2_$3)
|
||||||
$(V)$$(toolchain_$1)gcc -shared \
|
$(V)$$(toolchain_$1)gcc -shared \
|
||||||
-o $$(dll_$1_$2_$3) -Wl,--out-implib,$$(implib_$1_$2_$3) \
|
-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)strip $$(dll_$1_$2_$3)
|
||||||
$(V)$$(toolchain_$1)ranlib $$(implib_$1_$2_$3)
|
$(V)$$(toolchain_$1)ranlib $$(implib_$1_$2_$3)
|
||||||
|
|
||||||
|
|||||||
66
Module.mk
66
Module.mk
@@ -26,7 +26,8 @@
|
|||||||
# 8: Patch 3: beatmania IIDX 16 Empress
|
# 8: Patch 3: beatmania IIDX 16 Empress
|
||||||
# jubeat
|
# jubeat
|
||||||
#
|
#
|
||||||
# 10: Patch 4: DanceDanceRevolution X2
|
# 10: Patch 2: jubeat Knit
|
||||||
|
# Patch 4: DanceDanceRevolution X2
|
||||||
#
|
#
|
||||||
# 11: Patch 1: beatmania IIDX 18 Resort Anthem
|
# 11: Patch 1: beatmania IIDX 18 Resort Anthem
|
||||||
# pop'n music 19 Tune Street
|
# pop'n music 19 Tune Street
|
||||||
@@ -71,7 +72,7 @@ cflags += \
|
|||||||
# Each AVS-dependent project should consume the earliest AVS import definition
|
# Each AVS-dependent project should consume the earliest AVS import definition
|
||||||
# that is still ABI-compatible with the real build its target links against.
|
# 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
|
avsvers_64 := 1700 1603 1601 1509 1508
|
||||||
|
|
||||||
imps += avs avs-ea3
|
imps += avs avs-ea3
|
||||||
@@ -136,12 +137,14 @@ include src/main/iidxio-ezusb2/Module.mk
|
|||||||
include src/main/iidxio/Module.mk
|
include src/main/iidxio/Module.mk
|
||||||
include src/main/iidxiotest/Module.mk
|
include src/main/iidxiotest/Module.mk
|
||||||
include src/main/inject/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-magicbox/Module.mk
|
||||||
include src/main/jbio-p4io/Module.mk
|
include src/main/jbio-p4io/Module.mk
|
||||||
include src/main/jbio/Module.mk
|
include src/main/jbio/Module.mk
|
||||||
include src/main/jbiotest/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/launcher/Module.mk
|
||||||
include src/main/mempatch-hook/Module.mk
|
include src/main/mempatch-hook/Module.mk
|
||||||
include src/main/mm/Module.mk
|
include src/main/mm/Module.mk
|
||||||
@@ -424,28 +427,68 @@ $(zipdir)/jb-01.zip: \
|
|||||||
$(V)echo ... $@
|
$(V)echo ... $@
|
||||||
$(V)zip -j $@ $^
|
$(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: \
|
$(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/avs2_1508-32/launcher.exe \
|
||||||
build/bin/indep-32/config.exe \
|
build/bin/indep-32/config.exe \
|
||||||
build/bin/indep-32/eamio.dll \
|
build/bin/indep-32/eamio.dll \
|
||||||
build/bin/indep-32/geninput.dll \
|
build/bin/indep-32/geninput.dll \
|
||||||
build/bin/indep-32/jbio.dll \
|
build/bin/indep-32/jbio.dll \
|
||||||
dist/jb/config.bat \
|
dist/jb/config.bat \
|
||||||
dist/jb/gamestart.bat \
|
dist/jb/gamestart-04.bat \
|
||||||
| $(zipdir)/
|
| $(zipdir)/
|
||||||
$(V)echo ... $@
|
$(V)echo ... $@
|
||||||
$(V)zip -j $@ $^
|
$(V)zip -j $@ $^
|
||||||
|
|
||||||
$(zipdir)/jb-08.zip: \
|
$(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/avs2_1700-32/launcher.exe \
|
||||||
build/bin/indep-32/config.exe \
|
build/bin/indep-32/config.exe \
|
||||||
build/bin/indep-32/eamio.dll \
|
build/bin/indep-32/eamio.dll \
|
||||||
build/bin/indep-32/geninput.dll \
|
build/bin/indep-32/geninput.dll \
|
||||||
build/bin/indep-32/jbio.dll \
|
build/bin/indep-32/jbio.dll \
|
||||||
dist/jb/config.bat \
|
dist/jb/config.bat \
|
||||||
dist/jb/gamestart.bat \
|
dist/jb/gamestart-04.bat \
|
||||||
| $(zipdir)/
|
| $(zipdir)/
|
||||||
$(V)echo ... $@
|
$(V)echo ... $@
|
||||||
$(V)zip -j $@ $^
|
$(V)zip -j $@ $^
|
||||||
@@ -474,7 +517,7 @@ $(zipdir)/sdvx-01-to-04.zip: \
|
|||||||
$(V)echo ... $@
|
$(V)echo ... $@
|
||||||
$(V)zip -j $@ $^
|
$(V)zip -j $@ $^
|
||||||
|
|
||||||
$(zipdir)/sdvx-05.zip: \
|
$(zipdir)/sdvx-05-to-06.zip: \
|
||||||
build/bin/avs2_1700-64/launcher.exe \
|
build/bin/avs2_1700-64/launcher.exe \
|
||||||
build/bin/avs2_1700-64/sdvxhook2.dll \
|
build/bin/avs2_1700-64/sdvxhook2.dll \
|
||||||
build/bin/indep-64/config.exe \
|
build/bin/indep-64/config.exe \
|
||||||
@@ -621,11 +664,14 @@ $(BUILDDIR)/bemanitools.zip: \
|
|||||||
$(zipdir)/iidx-hwio-x86.zip \
|
$(zipdir)/iidx-hwio-x86.zip \
|
||||||
$(zipdir)/iidx-hwio-x64.zip \
|
$(zipdir)/iidx-hwio-x64.zip \
|
||||||
$(zipdir)/jb-01.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-05-to-07.zip \
|
||||||
$(zipdir)/jb-08.zip \
|
$(zipdir)/jb-08.zip \
|
||||||
$(zipdir)/jb-hwio.zip \
|
$(zipdir)/jb-hwio.zip \
|
||||||
$(zipdir)/sdvx-01-to-04.zip \
|
$(zipdir)/sdvx-01-to-04.zip \
|
||||||
$(zipdir)/sdvx-05.zip \
|
$(zipdir)/sdvx-05-to-06.zip \
|
||||||
$(zipdir)/sdvx-05-cn.zip \
|
$(zipdir)/sdvx-05-cn.zip \
|
||||||
$(zipdir)/sdvx-hwio-x86.zip \
|
$(zipdir)/sdvx-hwio-x86.zip \
|
||||||
$(zipdir)/sdvx-hwio-x64.zip \
|
$(zipdir)/sdvx-hwio-x64.zip \
|
||||||
|
|||||||
19
README.md
19
README.md
@@ -1,7 +1,7 @@
|
|||||||
# Bemanitools 5
|
# Bemanitools 5
|
||||||
[](https://dev.s-ul.net/djhackers/bemanitools/commits/master)
|
[](https://dev.s-ul.net/djhackers/bemanitools/commits/master)
|
||||||
|
|
||||||
Version: 5.36
|
Version: 5.38
|
||||||
|
|
||||||
[Release history](CHANGELOG.md)
|
[Release history](CHANGELOG.md)
|
||||||
|
|
||||||
@@ -58,17 +58,22 @@ The tl;dr version and golden rules of the sections in the document:
|
|||||||
* Beatmania IIDX 27 Heroic Verse (iidx-27-to-28.zip) using [iidxhook9](doc/iidxhook/iidxhook9.md)
|
* Beatmania IIDX 27 Heroic Verse (iidx-27-to-28.zip) using [iidxhook9](doc/iidxhook/iidxhook9.md)
|
||||||
* Beatmania IIDX 28 BISTROVER (iidx-27-to-28.zip) using [iidxhook9](doc/iidxhook/iidxhook9.md)
|
* Beatmania IIDX 28 BISTROVER (iidx-27-to-28.zip) using [iidxhook9](doc/iidxhook/iidxhook9.md)
|
||||||
* jubeat
|
* jubeat
|
||||||
* jubeat (experimental/buggy) (jb-01.zip) using [jbhook1](doc/jbhook1/jbhook1.md)
|
* jubeat (jb-01.zip) using [jbhook1](doc/jbhook/jbhook1.md)
|
||||||
* jubeat saucer (fulfill) (jb-05-to-07.zip) using jbhook
|
* jubeat ripples (jb-02.zip) using [jbhook1](doc/jbhook/jbhook1.md)
|
||||||
* jubeat prop (jb-05-to-07.zip) using jbhook
|
* jubeat knit (jb-03.zip) using [jbhook2](doc/jbhook/jbhook2.md)
|
||||||
* jubeat Qubell (jb-05-to-07.zip) using jbhook
|
* jubeat copious (jb-04.zip) using [jbhook2](doc/jbhook/jbhook2.md)
|
||||||
* jubeat clan (jb-08.zip) using jbhook
|
* jubeat saucer (fulfill) (jb-05-to-07.zip) using [jbhook3](doc/jbhook/jbhook3.md)
|
||||||
|
* jubeat prop (jb-05-to-07.zip) using [jbhook3](doc/jbhook/jbhook3.md)
|
||||||
|
* jubeat qubell (jb-05-to-07.zip) using [jbhook3](doc/jbhook/jbhook3.md)
|
||||||
|
* jubeat clan (jb-08.zip) using [jbhook3](doc/jbhook/jbhook3.md)
|
||||||
|
* jubeat festo (jb-08.zip) using [jbhook3](doc/jbhook/jbhook3.md)
|
||||||
* SOUND VOLTEX
|
* SOUND VOLTEX
|
||||||
* SOUND VOLTEX BOOTH (sdvx-01-to-04.zip) using sdvxhook
|
* SOUND VOLTEX BOOTH (sdvx-01-to-04.zip) using sdvxhook
|
||||||
* SOUND VOLTEX II -infinite infection- (sdvx-01-to-04.zip) using sdvxhook
|
* SOUND VOLTEX II -infinite infection- (sdvx-01-to-04.zip) using sdvxhook
|
||||||
* SOUND VOLTEX III GRAVITY WARS (sdvx-01-to-04.zip) using sdvxhook
|
* SOUND VOLTEX III GRAVITY WARS (sdvx-01-to-04.zip) using sdvxhook
|
||||||
* SOUND VOLTEX IV HEAVENLY HAVEN (sdvx-01-to-04.zip) using sdvxhook
|
* SOUND VOLTEX IV HEAVENLY HAVEN (sdvx-01-to-04.zip) using sdvxhook
|
||||||
* SOUND VOLTEX Vivid Wave (sdvx-05.zip) using sdvxhook2
|
* SOUND VOLTEX Vivid Wave (sdvx-05-to-06) using sdvxhook2
|
||||||
|
* SOUND VOLTEX EXCEED GEAR (sdvx-05-to-06) using sdvxhook2
|
||||||
|
|
||||||
## ViGEm clients: Expose BT5 APIs as XBOX game controllers
|
## ViGEm clients: Expose BT5 APIs as XBOX game controllers
|
||||||
Play your favorite non-bemani arcade games with any hardware, e.g. real cabinet hardware, that
|
Play your favorite non-bemani arcade games with any hardware, e.g. real cabinet hardware, that
|
||||||
|
|||||||
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\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml
|
||||||
if not exist dev\raw mkdir dev\raw
|
if not exist dev\raw mkdir dev\raw
|
||||||
|
|
||||||
launcher -H 33554432 -K jbhook.dll jubeat.dll
|
launcher -H 33554432 -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 -H 33554432 -K jbhook3.dll jubeat.dll
|
||||||
3
dist/jb/jbhook-01.conf
vendored
3
dist/jb/jbhook-01.conf
vendored
@@ -1,6 +1,9 @@
|
|||||||
# Run the game windowed
|
# Run the game windowed
|
||||||
gfx.windowed=false
|
gfx.windowed=false
|
||||||
|
|
||||||
|
# rotate the normally-horizontal game window to be vertical
|
||||||
|
gfx.vertical=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.
|
# 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
|
eamuse.server=localhost:80
|
||||||
|
|
||||||
|
|||||||
18
dist/jb/jbhook-02.conf
vendored
Normal file
18
dist/jb/jbhook-02.conf
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Run the game windowed
|
||||||
|
gfx.windowed=false
|
||||||
|
|
||||||
|
# rotate the normally-horizontal game window to be vertical
|
||||||
|
gfx.vertical=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
|
||||||
|
|
||||||
15
dist/sdvx5/sdvxhook2.conf
vendored
15
dist/sdvx5/sdvxhook2.conf
vendored
@@ -13,6 +13,15 @@ io.force_headphones=false
|
|||||||
# Disables the built in file hooks, requiring manual file creation (/dev/raw/j.dest)
|
# Disables the built in file hooks, requiring manual file creation (/dev/raw/j.dest)
|
||||||
io.disable_file_hooks=false
|
io.disable_file_hooks=false
|
||||||
|
|
||||||
|
# Disables the built in power control hooks, allowing game to modify system power settings
|
||||||
|
io.disable_power_hooks=false
|
||||||
|
|
||||||
|
# Disables the built in NVAPI control hooks, allowing game to modify system monitor settings
|
||||||
|
io.disable_nvapi_hooks=false
|
||||||
|
|
||||||
|
# Emulates the card reader on COM1 instead of COM2
|
||||||
|
io.com1_card_reader=false
|
||||||
|
|
||||||
# Run the game in a framed window (requires windowed option)
|
# Run the game in a framed window (requires windowed option)
|
||||||
gfx.framed=true
|
gfx.framed=true
|
||||||
|
|
||||||
@@ -43,6 +52,12 @@ gfx.device_adapter=-1
|
|||||||
# Orientation to force monitor into, -1 to use default, 0, 1, 2, 3 to do 0, 90, 180, 270 degrees
|
# Orientation to force monitor into, -1 to use default, 0, 1, 2, 3 to do 0, 90, 180, 270 degrees
|
||||||
gfx.force_orientation=-1
|
gfx.force_orientation=-1
|
||||||
|
|
||||||
|
# Force a screen resolution (width), -1 to disable. Use this if the game does not auto detect your monitor's resolution properly, e.g. 1368x768 instead of 1280x720.
|
||||||
|
gfx.force_screen_res.width=-1
|
||||||
|
|
||||||
|
# Force a screen resolution (height), -1 to disable. Use this if the game does not auto detect your monitor's resolution properly, e.g. 1368x768 instead of 1280x720.
|
||||||
|
gfx.force_screen_res.height=-1
|
||||||
|
|
||||||
# Disables the camera emulation
|
# Disables the camera emulation
|
||||||
cam.disable_emu=false
|
cam.disable_emu=false
|
||||||
|
|
||||||
|
|||||||
@@ -23,14 +23,14 @@ games:
|
|||||||
* [iidxhook8](iidxhook8.md): CANNON BALLERS, Rootage
|
* [iidxhook8](iidxhook8.md): CANNON BALLERS, Rootage
|
||||||
* [iidxhook8](iidxhook9.md): Heroic Verse
|
* [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
|
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.
|
binary patches.
|
||||||
|
|
||||||
## How to run
|
## How to run
|
||||||
To run your game with iidxhook, you have to use the inject tool to inject the
|
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
|
important parameters configured. Further parameters can be added but might not
|
||||||
be required to run the game with default settings.
|
be required to run the game with default settings.
|
||||||
Further information on how to setup the data for each specific version are
|
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
|
game controllers
|
||||||
* [iidxio-bio2](iidxhook/iidxio-bio2.md): Support BIO2 hardware
|
* [iidxio-bio2](iidxhook/iidxio-bio2.md): Support BIO2 hardware
|
||||||
* [iidxio-ezusb](iidxhook/iidxio-ezusb.md): Support C02 ezusb FX 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
|
|
||||||
42
doc/jbhook/jbhook1.md
Normal file
42
doc/jbhook/jbhook1.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
The DLLs in this package should be in the same location as the game DLLs and
|
||||||
|
executable - i.e. all these files should be in the same folder:
|
||||||
|
- `inject.exe`
|
||||||
|
- `jubeat.exe`
|
||||||
|
- `jbhook-01.conf`
|
||||||
|
- `eamio.dll`
|
||||||
|
- `libavs-win32.dll`
|
||||||
|
- etc
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
# Eamuse network setup
|
||||||
|
|
||||||
|
If you want to run the games online, you have to set a valid PCBID and EAMID
|
||||||
|
(use the PCBID as the EAMID) in the configuration file or as a command line
|
||||||
|
argument. You also have to set the url of the eamuse server you want to
|
||||||
|
connect to.
|
||||||
|
|
||||||
|
Additional note regarding EAMID: This is provided as the identifier of the
|
||||||
|
"eamuse license" to the server. Depending on the implementation of the server,
|
||||||
|
this can lead to authentication failure resulting in a network error on boot or
|
||||||
|
warning during gameplay.
|
||||||
42
doc/jbhook/jbhook2.md
Normal file
42
doc/jbhook/jbhook2.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
The DLLs in this package should be in the same location as the game DLLs and
|
||||||
|
executable - i.e. all these files should be in the same folder:
|
||||||
|
- `launcher.exe`
|
||||||
|
- `jubeat.dll`
|
||||||
|
- `eamio.dll`
|
||||||
|
- `jbhook2.dll`
|
||||||
|
- `libavs-win32.dll`
|
||||||
|
- etc
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
# Eamuse network setup
|
||||||
|
|
||||||
|
If you want to run the games online, you have to set a valid PCBID and EAMID
|
||||||
|
(use the PCBID as the EAMID) in the configuration file or as a command line
|
||||||
|
argument. You also have to set the url of the eamuse server you want to
|
||||||
|
connect to.
|
||||||
|
|
||||||
|
Additional note regarding EAMID: This is provided as the identifier of the
|
||||||
|
"eamuse license" to the server. Depending on the implementation of the server,
|
||||||
|
this can lead to authentication failure resulting in a network error on boot or
|
||||||
|
warning during gameplay.
|
||||||
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.
|
||||||
@@ -23,6 +23,6 @@ if [ "$changelog_excerpt" ]; then
|
|||||||
printf "%s" "$changelog_excerpt"
|
printf "%s" "$changelog_excerpt"
|
||||||
exit 0
|
exit 0
|
||||||
else
|
else
|
||||||
echo "Could not find version in changelog: $VERSION"
|
>&2 echo "Could not find version in changelog: $VERSION"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
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>
|
#include <stdint.h>
|
||||||
|
|
||||||
enum ac_io_icca_cmd {
|
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) */
|
/* Yet unknown command encountered first on jubeat (1) */
|
||||||
AC_IO_ICCA_CMD_UNKN_0120 = 0x0120,
|
AC_IO_ICCA_CMD_UNKN_0120 = 0x0120,
|
||||||
AC_IO_ICCA_CMD_QUEUE_LOOP_START = 0x0130,
|
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 \
|
h44b.c \
|
||||||
hdxs.c \
|
hdxs.c \
|
||||||
icca.c \
|
icca.c \
|
||||||
iccb.c \
|
|
||||||
pipe.c \
|
pipe.c \
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ void ac_io_emu_icca_init(
|
|||||||
|
|
||||||
// default to 1.6.0
|
// default to 1.6.0
|
||||||
icca->version = v160;
|
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(
|
void ac_io_emu_icca_set_version(
|
||||||
@@ -71,6 +73,12 @@ void ac_io_emu_icca_set_version(
|
|||||||
icca->version = 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(
|
void ac_io_emu_icca_dispatch_request(
|
||||||
struct ac_io_emu_icca *icca, const struct ac_io_message *req)
|
struct ac_io_emu_icca *icca, const struct ac_io_message *req)
|
||||||
{
|
{
|
||||||
@@ -119,8 +127,9 @@ void ac_io_emu_icca_dispatch_request(
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case AC_IO_ICCA_CMD_UNKN_0116:
|
||||||
case AC_IO_ICCA_CMD_UNKN_0120:
|
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);
|
ac_io_emu_icca_send_status(icca, req, 0x00);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -138,48 +147,52 @@ void ac_io_emu_icca_dispatch_request(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case AC_IO_ICCA_CMD_SET_SLOT_STATE: {
|
case AC_IO_ICCA_CMD_SET_SLOT_STATE: {
|
||||||
struct ac_io_icca_misc *misc =
|
if(icca->version == v150) {
|
||||||
(struct ac_io_icca_misc *) &req->cmd.raw;
|
ac_io_emu_icca_send_state(icca, req, 0, false);
|
||||||
uint8_t cmd;
|
} else {
|
||||||
|
struct ac_io_icca_misc *misc =
|
||||||
|
(struct ac_io_icca_misc *) &req->cmd.raw;
|
||||||
|
uint8_t cmd;
|
||||||
|
|
||||||
switch (misc->subcmd) {
|
switch (misc->subcmd) {
|
||||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_CLOSE:
|
case AC_IO_ICCA_SUBCMD_CARD_SLOT_CLOSE:
|
||||||
cmd = EAM_IO_CARD_SLOT_CMD_CLOSE;
|
cmd = EAM_IO_CARD_SLOT_CMD_CLOSE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_OPEN:
|
case AC_IO_ICCA_SUBCMD_CARD_SLOT_OPEN:
|
||||||
cmd = EAM_IO_CARD_SLOT_CMD_OPEN;
|
cmd = EAM_IO_CARD_SLOT_CMD_OPEN;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_EJECT:
|
case AC_IO_ICCA_SUBCMD_CARD_SLOT_EJECT:
|
||||||
cmd = EAM_IO_CARD_SLOT_CMD_EJECT;
|
cmd = EAM_IO_CARD_SLOT_CMD_EJECT;
|
||||||
icca->engaged = false;
|
icca->engaged = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
cmd = EAM_IO_CARD_SLOT_CMD_READ;
|
cmd = EAM_IO_CARD_SLOT_CMD_READ;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
cmd = 0xFF;
|
cmd = 0xFF;
|
||||||
log_warning(
|
log_warning(
|
||||||
"Unhandled slot command %X, node %d",
|
"Unhandled slot command %X, node %d",
|
||||||
misc->subcmd,
|
misc->subcmd,
|
||||||
icca->unit_no);
|
icca->unit_no);
|
||||||
break;
|
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);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* response with current slot state */
|
if (cmd != 0xFF) {
|
||||||
ac_io_emu_icca_send_status(icca, req, misc->subcmd);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
@@ -202,12 +215,14 @@ void ac_io_emu_icca_dispatch_request(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case AC_IO_ICCA_CMD_POLL_FELICA:
|
case AC_IO_ICCA_CMD_POLL_FELICA:
|
||||||
icca->detected_new_reader = true;
|
if (icca->version == v150) {
|
||||||
|
ac_io_emu_icca_send_state(icca, req, 0, false);
|
||||||
if (icca->version == v170) {
|
} else if (icca->version == v170) {
|
||||||
ac_io_emu_icca_send_empty(icca, req);
|
ac_io_emu_icca_send_empty(icca, req);
|
||||||
|
icca->detected_new_reader = true;
|
||||||
} else {
|
} else {
|
||||||
ac_io_emu_icca_send_status(icca, req, 0x01);
|
ac_io_emu_icca_send_status(icca, req, 0x01);
|
||||||
|
icca->detected_new_reader = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -244,8 +259,6 @@ static void ac_io_emu_icca_cmd_send_version(
|
|||||||
resp.cmd.version.major = 0x01;
|
resp.cmd.version.major = 0x01;
|
||||||
|
|
||||||
if (icca->version == v150) {
|
if (icca->version == v150) {
|
||||||
log_warning(
|
|
||||||
"ICCA v1.5.0 emulation requested, please remove this log once implemented");
|
|
||||||
resp.cmd.version.minor = 0x05;
|
resp.cmd.version.minor = 0x05;
|
||||||
} else if (icca->version == v160) {
|
} else if (icca->version == v160) {
|
||||||
resp.cmd.version.minor = 0x06;
|
resp.cmd.version.minor = 0x06;
|
||||||
@@ -262,7 +275,7 @@ static void ac_io_emu_icca_cmd_send_version(
|
|||||||
|
|
||||||
memcpy(
|
memcpy(
|
||||||
resp.cmd.version.product_code,
|
resp.cmd.version.product_code,
|
||||||
"ICCA",
|
icca->product_code,
|
||||||
sizeof(resp.cmd.version.product_code));
|
sizeof(resp.cmd.version.product_code));
|
||||||
strncpy(resp.cmd.version.date, __DATE__, sizeof(resp.cmd.version.date));
|
strncpy(resp.cmd.version.date, __DATE__, sizeof(resp.cmd.version.date));
|
||||||
strncpy(resp.cmd.version.time, __TIME__, sizeof(resp.cmd.version.time));
|
strncpy(resp.cmd.version.time, __TIME__, sizeof(resp.cmd.version.time));
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ enum ac_io_emu_icca_version {
|
|||||||
v170 = 0x7,
|
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_icca {
|
||||||
struct ac_io_emu *emu;
|
struct ac_io_emu *emu;
|
||||||
uint8_t unit_no;
|
uint8_t unit_no;
|
||||||
@@ -28,6 +33,7 @@ struct ac_io_emu_icca {
|
|||||||
uint64_t time_counter_last_poll;
|
uint64_t time_counter_last_poll;
|
||||||
|
|
||||||
enum ac_io_emu_icca_version version;
|
enum ac_io_emu_icca_version version;
|
||||||
|
char product_code[4];
|
||||||
bool cipher_started;
|
bool cipher_started;
|
||||||
uint32_t cipher_keys[4];
|
uint32_t cipher_keys[4];
|
||||||
};
|
};
|
||||||
@@ -39,6 +45,12 @@ void ac_io_emu_icca_init(
|
|||||||
void ac_io_emu_icca_set_version(
|
void ac_io_emu_icca_set_version(
|
||||||
struct ac_io_emu_icca *icca, enum ac_io_emu_icca_version 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(
|
void ac_io_emu_icca_dispatch_request(
|
||||||
struct ac_io_emu_icca *icca, const struct ac_io_message *req);
|
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
|
|
||||||
@@ -52,7 +52,7 @@ void d3d9exhook_config_gfx_init(struct cconfig *config)
|
|||||||
config,
|
config,
|
||||||
D3D9EXHOOK_CONFIG_GFX_CONFINED_KEY,
|
D3D9EXHOOK_CONFIG_GFX_CONFINED_KEY,
|
||||||
D3D9EXHOOK_CONFIG_GFX_DEFAULT_CONFINED_VALUE,
|
D3D9EXHOOK_CONFIG_GFX_DEFAULT_CONFINED_VALUE,
|
||||||
"Confine mouse coursor to window");
|
"Confine mouse cursor to window");
|
||||||
|
|
||||||
cconfig_util_set_int(
|
cconfig_util_set_int(
|
||||||
config,
|
config,
|
||||||
|
|||||||
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 "hook/iohook.h"
|
||||||
|
|
||||||
#include "jbhook/acio.h"
|
#include "jbhook-util/acio.h"
|
||||||
|
|
||||||
#include "imports/avs.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_icca ac_io_emu_icca;
|
||||||
static struct ac_io_emu_h44b ac_io_emu_h44b;
|
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_icca_init(&ac_io_emu_icca, &ac_io_emu, 0);
|
||||||
ac_io_emu_h44b_init(&ac_io_emu_h44b, &ac_io_emu, 1);
|
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);
|
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
|
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;
|
const struct ac_io_message *msg;
|
||||||
HRESULT hr;
|
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
|
||||||
219
src/main/jbhook-util/gfx.c
Normal file
219
src/main/jbhook-util/gfx.c
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
#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 void hook_infodispcore_set_angle(void* this, int angle);
|
||||||
|
|
||||||
|
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},
|
||||||
|
};
|
||||||
|
|
||||||
|
// on knit/copious, this gives us right-side-up errors, too!
|
||||||
|
static const struct hook_symbol jbhook_infodisp_hook_syms[] = {
|
||||||
|
{.name = "?set_angle@infodispcore@@QAEXH@Z",
|
||||||
|
.patch = hook_infodispcore_set_angle},
|
||||||
|
};
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
hook_table_apply(
|
||||||
|
NULL,
|
||||||
|
"infodisp.dll",
|
||||||
|
jbhook_infodisp_hook_syms,
|
||||||
|
lengthof(jbhook_infodisp_hook_syms));
|
||||||
|
|
||||||
|
log_info("Inserted vertical display hooks");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hook_infodispcore_set_angle(void* this, int angle) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
// Welcome to OpenGL land! There is a ton of boilerplate needed here "just" to
|
||||||
|
// rotate the render output
|
||||||
|
|
||||||
|
// only jubeat uses openGL, let alone needs rotation at all, so hardcode for now
|
||||||
|
#define W 768
|
||||||
|
#define H 1360
|
||||||
|
|
||||||
|
// the framebuffer we redirect renders to instead of rendering to the screen
|
||||||
|
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 void __stdcall hook_glFlush(void) {
|
||||||
|
// 3 bytes per RGB pixel
|
||||||
|
// these could really be stack variables but they are too big for gcc's
|
||||||
|
// default stack size, and it's no problem for 6MiB of data to hang around
|
||||||
|
static uint8_t pixels_raw[W*H*3];
|
||||||
|
static uint8_t pixels_rot[W*H*3];
|
||||||
|
|
||||||
|
glReadPixels(0, 0, H, W, GL_RGB, GL_UNSIGNED_BYTE, pixels_raw);
|
||||||
|
|
||||||
|
// CPU copies may seem slow here, but this runs fine on my jubeat cab, so
|
||||||
|
// speed is not a huge concern.
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// now *we* get to draw to the main display
|
||||||
|
real_glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
// the scissor test clips pixels to the game window - must be disabled or
|
||||||
|
// the draw area is cut off vertically
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
glDrawPixels(W, H, GL_RGB, GL_UNSIGNED_BYTE, pixels_rot);
|
||||||
|
|
||||||
|
real_glFlush();
|
||||||
|
|
||||||
|
// reset the framebuffer for the next draw - must be after flush (i.e. when
|
||||||
|
// all state is reset) and before the game tries to draw anything
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// hooking something in glhelper.dll (a jubeat supplied DLL) might seem
|
||||||
|
// insufficiently generic compared to something in opengl32.dll, but the render
|
||||||
|
// loop of the game makes it very difficult to "catch" the rendering at the
|
||||||
|
// right place otherwise. This works with all horizontal jubeats, and they
|
||||||
|
// stopped needing rotation fixes starting with saucer.
|
||||||
|
static void hook_glBindFramebufferEXT(GLenum target, GLuint framebuffer) {
|
||||||
|
fb_init();
|
||||||
|
|
||||||
|
// check this is actually the screen - the game also uses internal
|
||||||
|
// framebuffers for some parts of the display
|
||||||
|
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
|
* Hook some gfx related functions to patch gfx related stuff
|
||||||
* like enabling window mode.
|
* like enabling window mode.
|
||||||
*/
|
*/
|
||||||
void gfx_hook_init(void);
|
void jbhook_util_gfx_hook_init(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the game to window mode.
|
* 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
|
* @param framed True to add a window frame and make the window
|
||||||
* movable, resizable, minizable. False for no frame.
|
* 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
|
#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"
|
#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 mcode Mcode of the target game to run. Required for dongle emulation.
|
||||||
* @param pcbid PCBDID
|
* @param pcbid PCBDID
|
||||||
* @param eamid EAMID
|
* @param eamid EAMID
|
||||||
*/
|
*/
|
||||||
void jbhook1_p3io_init(
|
void jbhook_util_p3io_init(
|
||||||
const struct security_mcode *mcode,
|
const struct security_mcode *mcode,
|
||||||
const struct security_id *pcbid,
|
const struct security_id *pcbid,
|
||||||
const struct security_id *eamid);
|
const struct security_id *eamid);
|
||||||
@@ -23,6 +23,6 @@ void jbhook1_p3io_init(
|
|||||||
/**
|
/**
|
||||||
* Shutdown the p3io emulation backend.
|
* Shutdown the p3io emulation backend.
|
||||||
*/
|
*/
|
||||||
void jbhook1_p3io_fini(void);
|
void jbhook_util_p3io_fini(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "imports/avs.h"
|
#include "imports/avs.h"
|
||||||
|
|
||||||
#include "jbhook/io.h"
|
#include "jbhook-util/p4io.h"
|
||||||
|
|
||||||
#include "p4io/cmd.h"
|
#include "p4io/cmd.h"
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ static uint32_t jbhook_command_handle(
|
|||||||
void *resp,
|
void *resp,
|
||||||
uint32_t resp_max_len);
|
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,
|
.jamma2_read = jbhook_io_jamma2_read,
|
||||||
.command_handle = jbhook_command_handle,
|
.command_handle = jbhook_command_handle,
|
||||||
.roundplug_read_id = NULL,
|
.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"
|
#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
|
||||||
@@ -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
|
avsdlls += jbhook1
|
||||||
|
imps += glhelper
|
||||||
|
|
||||||
deplibs_jbhook1 := \
|
deplibs_jbhook1 := \
|
||||||
avs \
|
avs \
|
||||||
|
glhelper \
|
||||||
|
|
||||||
ldflags_jbhook1 := \
|
ldflags_jbhook1 := \
|
||||||
-lws2_32 \
|
-lws2_32 \
|
||||||
-liphlpapi \
|
-liphlpapi \
|
||||||
|
-lopengl32 \
|
||||||
|
|
||||||
libs_jbhook1 := \
|
libs_jbhook1 := \
|
||||||
acioemu \
|
acioemu \
|
||||||
cconfig \
|
cconfig \
|
||||||
eamio \
|
eamio \
|
||||||
jbio \
|
jbio \
|
||||||
|
jbhook-util \
|
||||||
p3ioemu \
|
p3ioemu \
|
||||||
p3io \
|
p3io \
|
||||||
hook \
|
hook \
|
||||||
@@ -20,11 +24,9 @@ libs_jbhook1 := \
|
|||||||
util \
|
util \
|
||||||
|
|
||||||
src_jbhook1 := \
|
src_jbhook1 := \
|
||||||
acio.c \
|
|
||||||
avs-boot.c \
|
avs-boot.c \
|
||||||
config-gfx.c \
|
config-gfx.c \
|
||||||
config-eamuse.c \
|
config-eamuse.c \
|
||||||
config-security.c \
|
config-security.c \
|
||||||
dllmain.c \
|
dllmain.c \
|
||||||
log-gftools.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"
|
#include "util/log.h"
|
||||||
|
|
||||||
#define JBHOOK1_CONFIG_GFX_WINDOWED_KEY "gfx.windowed"
|
#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_WINDOWED_VALUE false
|
||||||
|
#define JBHOOK1_CONFIG_GFX_DEFAULT_VERTICAL_VALUE true
|
||||||
|
|
||||||
void jbhook1_config_gfx_init(struct cconfig *config)
|
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_WINDOWED_KEY,
|
||||||
JBHOOK1_CONFIG_GFX_DEFAULT_WINDOWED_VALUE,
|
JBHOOK1_CONFIG_GFX_DEFAULT_WINDOWED_VALUE,
|
||||||
"Run the game windowed");
|
"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(
|
void jbhook1_config_gfx_get(
|
||||||
@@ -33,4 +40,15 @@ void jbhook1_config_gfx_get(
|
|||||||
JBHOOK1_CONFIG_GFX_WINDOWED_KEY,
|
JBHOOK1_CONFIG_GFX_WINDOWED_KEY,
|
||||||
JBHOOK1_CONFIG_GFX_DEFAULT_WINDOWED_VALUE);
|
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 {
|
struct jbhook1_config_gfx {
|
||||||
bool windowed;
|
bool windowed;
|
||||||
|
bool vertical;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,4 +28,4 @@ void jbhook1_config_gfx_init(struct cconfig *config);
|
|||||||
void jbhook1_config_gfx_get(
|
void jbhook1_config_gfx_get(
|
||||||
struct jbhook1_config_gfx *config_gfx, struct cconfig *config);
|
struct jbhook1_config_gfx *config_gfx, struct cconfig *config);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -11,10 +11,7 @@
|
|||||||
|
|
||||||
#define JBHOOK1_CONFIG_SECURITY_MCODE_KEY "security.mcode"
|
#define JBHOOK1_CONFIG_SECURITY_MCODE_KEY "security.mcode"
|
||||||
|
|
||||||
#define JBHOOK1_CONFIG_SECURITY_DEFAULT_MCODE_VALUE \
|
static const struct security_mcode security_mcode_h44 = {
|
||||||
jbhook1_config_security_default_mcode
|
|
||||||
|
|
||||||
static const struct security_mcode jbhook1_config_security_default_mcode = {
|
|
||||||
.header = SECURITY_MCODE_HEADER,
|
.header = SECURITY_MCODE_HEADER,
|
||||||
.unkn = SECURITY_MCODE_UNKN_C,
|
.unkn = SECURITY_MCODE_UNKN_C,
|
||||||
.game = SECURITY_MCODE_GAME_JB_1,
|
.game = SECURITY_MCODE_GAME_JB_1,
|
||||||
@@ -27,7 +24,7 @@ void jbhook1_config_security_init(struct cconfig *config)
|
|||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
tmp = security_mcode_to_str(&JBHOOK1_CONFIG_SECURITY_DEFAULT_MCODE_VALUE);
|
tmp = security_mcode_to_str(&security_mcode_h44);
|
||||||
|
|
||||||
cconfig_util_set_str(
|
cconfig_util_set_str(
|
||||||
config,
|
config,
|
||||||
@@ -45,7 +42,7 @@ void jbhook1_config_security_get(
|
|||||||
char mcode[9];
|
char mcode[9];
|
||||||
|
|
||||||
tmp_default =
|
tmp_default =
|
||||||
security_mcode_to_str(&JBHOOK1_CONFIG_SECURITY_DEFAULT_MCODE_VALUE);
|
security_mcode_to_str(&security_mcode_h44);
|
||||||
|
|
||||||
if (!cconfig_util_get_str(
|
if (!cconfig_util_get_str(
|
||||||
config,
|
config,
|
||||||
@@ -70,7 +67,7 @@ void jbhook1_config_security_get(
|
|||||||
|
|
||||||
memcpy(
|
memcpy(
|
||||||
&config_security->mcode,
|
&config_security->mcode,
|
||||||
&JBHOOK1_CONFIG_SECURITY_DEFAULT_MCODE_VALUE,
|
&security_mcode_h44,
|
||||||
sizeof(struct security_mcode));
|
sizeof(struct security_mcode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,13 +16,17 @@
|
|||||||
#include "hooklib/adapter.h"
|
#include "hooklib/adapter.h"
|
||||||
#include "hooklib/rs232.h"
|
#include "hooklib/rs232.h"
|
||||||
|
|
||||||
#include "jbhook1/acio.h"
|
|
||||||
#include "jbhook1/avs-boot.h"
|
#include "jbhook1/avs-boot.h"
|
||||||
#include "jbhook1/config-eamuse.h"
|
#include "jbhook1/config-eamuse.h"
|
||||||
#include "jbhook1/config-gfx.h"
|
#include "jbhook1/config-gfx.h"
|
||||||
#include "jbhook1/config-security.h"
|
#include "jbhook1/config-security.h"
|
||||||
#include "jbhook1/log-gftools.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/devmgr.h"
|
||||||
#include "p3ioemu/emu.h"
|
#include "p3ioemu/emu.h"
|
||||||
@@ -72,6 +76,8 @@ static HWND CDECL my_mwindow_create(
|
|||||||
log_info("---------------- Begin jbhook mwindow_create ----------------");
|
log_info("---------------- Begin jbhook mwindow_create ----------------");
|
||||||
log_info("-------------------------------------------------------------");
|
log_info("-------------------------------------------------------------");
|
||||||
|
|
||||||
|
jbhook_util_mixer_hook_init();
|
||||||
|
|
||||||
config = cconfig_init();
|
config = cconfig_init();
|
||||||
|
|
||||||
jbhook1_config_gfx_init(config);
|
jbhook1_config_gfx_init(config);
|
||||||
@@ -101,6 +107,14 @@ static HWND CDECL my_mwindow_create(
|
|||||||
|
|
||||||
fullscreen = !config_gfx.windowed;
|
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");
|
log_info("Starting up jubeat IO backend");
|
||||||
|
|
||||||
jb_io_set_loggers(
|
jb_io_set_loggers(
|
||||||
@@ -119,14 +133,17 @@ static HWND CDECL my_mwindow_create(
|
|||||||
log_fatal("Initializing card reader backend failed");
|
log_fatal("Initializing card reader backend failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jbhook_util_eamuse_hook_init();
|
||||||
|
|
||||||
iohook_push_handler(p3io_emu_dispatch_irp);
|
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();
|
rs232_hook_init();
|
||||||
ac_io_port_init();
|
jbhook_util_ac_io_port_init(L"COM1");
|
||||||
|
jbhook_util_ac_io_set_iccb();
|
||||||
|
|
||||||
p3io_setupapi_insert_hooks(NULL);
|
p3io_setupapi_insert_hooks(NULL);
|
||||||
jbhook1_p3io_init(
|
jbhook_util_p3io_init(
|
||||||
&config_security.mcode, &config_eamuse.pcbid, &config_eamuse.eamid);
|
&config_security.mcode, &config_eamuse.pcbid, &config_eamuse.eamid);
|
||||||
|
|
||||||
log_info("-------------------------------------------------------------");
|
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
|
||||||
221
src/main/jbhook2/dllmain.c
Normal file
221
src/main/jbhook2/dllmain.c
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
#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 "p3ioemu/devmgr.h"
|
||||||
|
#include "p3ioemu/emu.h"
|
||||||
|
|
||||||
|
#include "p4ioemu/device.h"
|
||||||
|
#include "p4ioemu/setupapi.h"
|
||||||
|
|
||||||
|
#include "security/id.h"
|
||||||
|
#include "security/mcode.h"
|
||||||
|
|
||||||
|
#include "util/defs.h"
|
||||||
|
#include "util/log.h"
|
||||||
|
#include "util/thread.h"
|
||||||
|
|
||||||
|
static struct options options;
|
||||||
|
|
||||||
|
static const struct security_mcode security_mcode_j44 = {
|
||||||
|
.header = SECURITY_MCODE_HEADER,
|
||||||
|
.unkn = SECURITY_MCODE_UNKN_C,
|
||||||
|
.game = SECURITY_MCODE_GAME_JB_3,
|
||||||
|
.region = SECURITY_MCODE_REGION_JAPAN,
|
||||||
|
.cabinet = SECURITY_MCODE_CABINET_C,
|
||||||
|
.revision = SECURITY_MCODE_REVISION_A,
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||||
|
{
|
||||||
|
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.vertical) {
|
||||||
|
jbhook_util_gfx_install_vertical_hooks();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.disable_p3ioemu) {
|
||||||
|
iohook_push_handler(p3io_emu_dispatch_irp);
|
||||||
|
p3io_setupapi_insert_hooks(NULL);
|
||||||
|
|
||||||
|
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.
|
||||||
|
// When booting knit append (and on no other version), the code must
|
||||||
|
// actually match, so the ID used is for append (JCA)
|
||||||
|
jbhook_util_p3io_init(
|
||||||
|
&security_mcode_j44,
|
||||||
|
&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) {
|
||||||
|
iohook_push_handler(jbhook_util_ac_io_port_dispatch_irp);
|
||||||
|
rs232_hook_init();
|
||||||
|
jbhook_util_ac_io_port_init(L"COM1");
|
||||||
|
jbhook_util_ac_io_set_iccb();
|
||||||
|
|
||||||
|
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("-------------------------------------------------------------");
|
||||||
|
|
||||||
|
if(options.vertical) {
|
||||||
|
DWORD tmp = window_width;
|
||||||
|
window_width = window_height;
|
||||||
|
window_height = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
fullscreen = !options.windowed;
|
||||||
|
|
||||||
|
return real_mwindow_create(
|
||||||
|
hinstance,
|
||||||
|
callback,
|
||||||
|
window_title,
|
||||||
|
window_width,
|
||||||
|
window_height,
|
||||||
|
fullscreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (!options.disable_adapteremu) {
|
||||||
|
adapter_hook_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
jbhook_util_gfx_hook_init();
|
||||||
|
jbhook_util_eamuse_hook_init();
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
LIBRARY jbhook
|
LIBRARY jbhook2
|
||||||
|
|
||||||
EXPORTS
|
EXPORTS
|
||||||
DllMain@12 @1 NONAME
|
DllMain@12 @1 NONAME
|
||||||
114
src/main/jbhook2/options.c
Normal file
114
src/main/jbhook2/options.c
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
#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 'v': {
|
||||||
|
options->vertical = 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"
|
||||||
|
" -v Rotate the normally-horizontal game window to be vertical\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)
|
||||||
|
{
|
||||||
|
}
|
||||||
23
src/main/jbhook2/options.h
Normal file
23
src/main/jbhook2/options.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef JBHOOK_OPTIONS_H
|
||||||
|
#define JBHOOK_OPTIONS_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
struct options {
|
||||||
|
bool windowed;
|
||||||
|
bool window_framed;
|
||||||
|
bool vertical;
|
||||||
|
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,18 @@
|
|||||||
|
|
||||||
#include "imports/avs.h"
|
#include "imports/avs.h"
|
||||||
|
|
||||||
#include "jbhook/acio.h"
|
#include "jbhook3/options.h"
|
||||||
#include "jbhook/eamuse.h"
|
|
||||||
#include "jbhook/gfx.h"
|
#include "jbhook-util/acio.h"
|
||||||
#include "jbhook/io.h"
|
#include "jbhook-util/eamuse.h"
|
||||||
#include "jbhook/options.h"
|
#include "jbhook-util/gfx.h"
|
||||||
|
#include "jbhook-util/p4io.h"
|
||||||
|
|
||||||
#include "p4ioemu/device.h"
|
#include "p4ioemu/device.h"
|
||||||
#include "p4ioemu/setupapi.h"
|
#include "p4ioemu/setupapi.h"
|
||||||
|
|
||||||
|
#include "security/id.h"
|
||||||
|
|
||||||
#include "util/defs.h"
|
#include "util/defs.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "util/thread.h"
|
#include "util/thread.h"
|
||||||
@@ -43,7 +46,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
log_info("--- Begin jbhook dll_entry_init ---");
|
log_info("--- Begin jbhook dll_entry_init ---");
|
||||||
|
|
||||||
iohook_push_handler(p4ioemu_dispatch_irp);
|
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) {
|
if (!options.disable_p4ioemu) {
|
||||||
log_info("Starting up jubeat IO backend");
|
log_info("Starting up jubeat IO backend");
|
||||||
@@ -59,7 +62,7 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
}
|
}
|
||||||
|
|
||||||
hook_setupapi_init(&p4ioemu_setupapi_data);
|
hook_setupapi_init(&p4ioemu_setupapi_data);
|
||||||
p4ioemu_init(jbhook_io_init());
|
p4ioemu_init(jbhook_p4io_init());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options.disable_cardemu) {
|
if (!options.disable_cardemu) {
|
||||||
@@ -76,12 +79,15 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
}
|
}
|
||||||
|
|
||||||
rs232_hook_init();
|
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 ---");
|
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:
|
fail:
|
||||||
if (eam_io_ok) {
|
if (eam_io_ok) {
|
||||||
@@ -108,7 +114,7 @@ static bool my_dll_entry_main(void)
|
|||||||
jb_io_fini();
|
jb_io_fini();
|
||||||
|
|
||||||
if (!options.disable_cardemu) {
|
if (!options.disable_cardemu) {
|
||||||
ac_io_port_fini();
|
jbhook_util_ac_io_port_fini();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options.disable_p4ioemu) {
|
if (!options.disable_p4ioemu) {
|
||||||
@@ -137,8 +143,8 @@ BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
|
|||||||
adapter_hook_init();
|
adapter_hook_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
gfx_hook_init();
|
jbhook_util_gfx_hook_init();
|
||||||
jbhook_eamuse_hook_init();
|
jbhook_util_eamuse_hook_init();
|
||||||
|
|
||||||
return TRUE;
|
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>
|
#include <windows.h>
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ void options_print_usage(void)
|
|||||||
{
|
{
|
||||||
OutputDebugStringA("jbhook for jubeat, build " __DATE__ " " __TIME__ ", gitrev " STRINGIFY(
|
OutputDebugStringA("jbhook for jubeat, build " __DATE__ " " __TIME__ ", gitrev " STRINGIFY(
|
||||||
GITREV) "\n"
|
GITREV) "\n"
|
||||||
"Usage: launcher.exe -K jbhook.dll [game exec] <options> \n"
|
"Usage: launcher.exe -K jbhook3.dll [game exec] <options> \n"
|
||||||
"\n"
|
"\n"
|
||||||
" The following options can be specified after the game exec path:\n"
|
" The following options can be specified after the game exec path:\n"
|
||||||
"\n"
|
"\n"
|
||||||
@@ -2,7 +2,9 @@
|
|||||||
#define P3IO_IOCTL_H
|
#define P3IO_IOCTL_H
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
P3IO_IOCTL_READ_JAMMA = 0x00222068,
|
P3IO_IOCTL_GET_VERSION = 0x00222004,
|
||||||
|
P3IO_IOCTL_READ_JAMMA = 0x00222068,
|
||||||
|
P3IO_IOCTL_RESET_PIPE = 0x00222098,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -150,33 +150,54 @@ static HRESULT p3io_emu_handle_ioctl(struct irp *irp)
|
|||||||
uint32_t pad;
|
uint32_t pad;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (irp->ioctl != P3IO_IOCTL_READ_JAMMA) {
|
switch (irp->ioctl) {
|
||||||
log_warning("Unknown ioctl: %x", 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");
|
||||||
|
}
|
||||||
|
|
||||||
if (irp->read.nbytes < sizeof(uint32_t)) {
|
memset(irp->read.bytes, 0, irp->read.nbytes);
|
||||||
log_warning("Insufficient ioctl response buffer space");
|
memcpy(irp->read.bytes, dev_name, strlen(dev_name));
|
||||||
|
irp->read.pos = strlen(dev_name);
|
||||||
|
|
||||||
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
return S_OK;
|
||||||
}
|
|
||||||
|
|
||||||
pad = 0;
|
|
||||||
|
|
||||||
if (p3io_ops->read_jamma != NULL) {
|
|
||||||
hr = p3io_ops->read_jamma(p3io_ops_ctx, &pad);
|
|
||||||
|
|
||||||
if (FAILED(hr)) {
|
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case P3IO_IOCTL_RESET_PIPE:
|
||||||
|
// does not expect a response
|
||||||
|
irp->read.pos = 0;
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
case P3IO_IOCTL_READ_JAMMA:
|
||||||
|
if (irp->read.nbytes < sizeof(uint32_t)) {
|
||||||
|
log_warning("Insufficient ioctl response buffer space");
|
||||||
|
|
||||||
|
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
pad = 0;
|
||||||
|
|
||||||
|
if (p3io_ops->read_jamma != NULL) {
|
||||||
|
hr = p3io_ops->read_jamma(p3io_ops_ctx, &pad);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dest = (uint32_t *) irp->read.bytes;
|
||||||
|
*dest = ~_byteswap_ulong(pad);
|
||||||
|
irp->read.pos = sizeof(pad);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log_warning("Unknown ioctl %08x", irp->ioctl);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dest = (uint32_t *) irp->read.bytes;
|
|
||||||
*dest = ~_byteswap_ulong(pad);
|
|
||||||
irp->read.pos = sizeof(pad);
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT p3io_emu_handle_read(struct irp *irp)
|
static HRESULT p3io_emu_handle_read(struct irp *irp)
|
||||||
|
|||||||
@@ -28,3 +28,5 @@ src_sdvxhook2 := \
|
|||||||
bi2a.c \
|
bi2a.c \
|
||||||
dllmain.c \
|
dllmain.c \
|
||||||
config-io.c \
|
config-io.c \
|
||||||
|
nvapi.c \
|
||||||
|
power.c \
|
||||||
|
|||||||
@@ -30,11 +30,16 @@
|
|||||||
static struct ac_io_emu ac_io_emu;
|
static struct ac_io_emu ac_io_emu;
|
||||||
static struct ac_io_emu_icca ac_io_emu_icca;
|
static struct ac_io_emu_icca ac_io_emu_icca;
|
||||||
|
|
||||||
void ac_io_port_init(void)
|
void ac_io_port_init(bool use_new_reader)
|
||||||
{
|
{
|
||||||
ac_io_emu_init(&ac_io_emu, L"\\\\.\\COM2");
|
if (use_new_reader) {
|
||||||
|
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_icca_init(&ac_io_emu_icca, &ac_io_emu, 0);
|
||||||
|
ac_io_emu_icca_set_version(&ac_io_emu_icca, v170);
|
||||||
|
} else {
|
||||||
|
ac_io_emu_init(&ac_io_emu, L"\\\\.\\COM2");
|
||||||
|
ac_io_emu_icca_init(&ac_io_emu_icca, &ac_io_emu, 0);
|
||||||
|
}
|
||||||
|
|
||||||
rs232_hook_add_fd(ac_io_emu.fd);
|
rs232_hook_add_fd(ac_io_emu.fd);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "hook/iohook.h"
|
#include "hook/iohook.h"
|
||||||
|
|
||||||
void ac_io_port_init(void);
|
void ac_io_port_init(bool use_new_reader);
|
||||||
void ac_io_port_fini(void);
|
void ac_io_port_fini(void);
|
||||||
HRESULT ac_io_port_dispatch_irp(struct irp *irp);
|
HRESULT ac_io_port_dispatch_irp(struct irp *irp);
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,19 @@
|
|||||||
#define SDVXHOOK2_CONFIG_IO_DISABLE_POLL_LIMITER_KEY "io.disable_poll_limiter"
|
#define SDVXHOOK2_CONFIG_IO_DISABLE_POLL_LIMITER_KEY "io.disable_poll_limiter"
|
||||||
#define SDVXHOOK2_CONFIG_IO_FORCE_HEADPHONES_KEY "io.force_headphones"
|
#define SDVXHOOK2_CONFIG_IO_FORCE_HEADPHONES_KEY "io.force_headphones"
|
||||||
#define SDVXHOOK2_CONFIG_IO_DISABLE_FILE_HOOKS_KEY "io.disable_file_hooks"
|
#define SDVXHOOK2_CONFIG_IO_DISABLE_FILE_HOOKS_KEY "io.disable_file_hooks"
|
||||||
|
#define SDVXHOOK2_CONFIG_IO_DISABLE_POWER_HOOKS_KEY "io.disable_power_hooks"
|
||||||
|
#define SDVXHOOK2_CONFIG_IO_DISABLE_NVAPI_HOOKS_KEY "io.disable_nvapi_hooks"
|
||||||
|
#define SDVXHOOK2_CONFIG_IO_COM1_CARD_READER_KEY "io.com1_card_reader"
|
||||||
|
|
||||||
#define SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_CARD_READER_EMU_VALUE false
|
#define SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_CARD_READER_EMU_VALUE false
|
||||||
#define SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_BIO2_EMU_VALUE false
|
#define SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_BIO2_EMU_VALUE false
|
||||||
#define SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_POLL_LIMITER_VALUE false
|
#define SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_POLL_LIMITER_VALUE false
|
||||||
#define SDVXHOOK2_CONFIG_IO_DEFAULT_FORCE_HEADPHONES_VALUE false
|
#define SDVXHOOK2_CONFIG_IO_DEFAULT_FORCE_HEADPHONES_VALUE false
|
||||||
#define SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_FILE_HOOKS_VALUE false
|
#define SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_FILE_HOOKS_VALUE false
|
||||||
|
#define SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_POWER_HOOKS_VALUE false
|
||||||
|
#define SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_NVAPI_HOOKS_VALUE false
|
||||||
|
#define SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_NVAPI_HOOKS_VALUE false
|
||||||
|
#define SDVXHOOK2_CONFIG_IO_DEFAULT_COM1_CARD_READER_VALUE false
|
||||||
|
|
||||||
void sdvxhook2_config_io_init(struct cconfig *config)
|
void sdvxhook2_config_io_init(struct cconfig *config)
|
||||||
{
|
{
|
||||||
@@ -49,6 +56,24 @@ void sdvxhook2_config_io_init(struct cconfig *config)
|
|||||||
SDVXHOOK2_CONFIG_IO_DISABLE_FILE_HOOKS_KEY,
|
SDVXHOOK2_CONFIG_IO_DISABLE_FILE_HOOKS_KEY,
|
||||||
SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_FILE_HOOKS_VALUE,
|
SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_FILE_HOOKS_VALUE,
|
||||||
"Disables the built in file hooks, requiring manual file creation (/dev/raw/j.dest)");
|
"Disables the built in file hooks, requiring manual file creation (/dev/raw/j.dest)");
|
||||||
|
|
||||||
|
cconfig_util_set_bool(
|
||||||
|
config,
|
||||||
|
SDVXHOOK2_CONFIG_IO_DISABLE_POWER_HOOKS_KEY,
|
||||||
|
SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_POWER_HOOKS_VALUE,
|
||||||
|
"Disables the built in power control hooks, allowing game to modify system power settings");
|
||||||
|
|
||||||
|
cconfig_util_set_bool(
|
||||||
|
config,
|
||||||
|
SDVXHOOK2_CONFIG_IO_DISABLE_NVAPI_HOOKS_KEY,
|
||||||
|
SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_NVAPI_HOOKS_VALUE,
|
||||||
|
"Disables the built in NVAPI control hooks, allowing game to modify system monitor settings");
|
||||||
|
|
||||||
|
cconfig_util_set_bool(
|
||||||
|
config,
|
||||||
|
SDVXHOOK2_CONFIG_IO_COM1_CARD_READER_KEY,
|
||||||
|
SDVXHOOK2_CONFIG_IO_DEFAULT_COM1_CARD_READER_VALUE,
|
||||||
|
"Emulates the card reader on COM1 instead of COM2");
|
||||||
}
|
}
|
||||||
|
|
||||||
void sdvxhook2_config_io_get(
|
void sdvxhook2_config_io_get(
|
||||||
@@ -113,4 +138,40 @@ void sdvxhook2_config_io_get(
|
|||||||
SDVXHOOK2_CONFIG_IO_DISABLE_FILE_HOOKS_KEY,
|
SDVXHOOK2_CONFIG_IO_DISABLE_FILE_HOOKS_KEY,
|
||||||
SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_FILE_HOOKS_VALUE);
|
SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_FILE_HOOKS_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cconfig_util_get_bool(
|
||||||
|
config,
|
||||||
|
SDVXHOOK2_CONFIG_IO_DISABLE_POWER_HOOKS_KEY,
|
||||||
|
&config_io->disable_power_hooks,
|
||||||
|
SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_POWER_HOOKS_VALUE)) {
|
||||||
|
log_warning(
|
||||||
|
"Invalid value for key '%s' specified, fallback "
|
||||||
|
"to default '%d'",
|
||||||
|
SDVXHOOK2_CONFIG_IO_DISABLE_POWER_HOOKS_KEY,
|
||||||
|
SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_POWER_HOOKS_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cconfig_util_get_bool(
|
||||||
|
config,
|
||||||
|
SDVXHOOK2_CONFIG_IO_DISABLE_NVAPI_HOOKS_KEY,
|
||||||
|
&config_io->disable_nvapi_hooks,
|
||||||
|
SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_NVAPI_HOOKS_VALUE)) {
|
||||||
|
log_warning(
|
||||||
|
"Invalid value for key '%s' specified, fallback "
|
||||||
|
"to default '%d'",
|
||||||
|
SDVXHOOK2_CONFIG_IO_DISABLE_NVAPI_HOOKS_KEY,
|
||||||
|
SDVXHOOK2_CONFIG_IO_DEFAULT_DISABLE_NVAPI_HOOKS_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cconfig_util_get_bool(
|
||||||
|
config,
|
||||||
|
SDVXHOOK2_CONFIG_IO_COM1_CARD_READER_KEY,
|
||||||
|
&config_io->com1_card_reader,
|
||||||
|
SDVXHOOK2_CONFIG_IO_DEFAULT_COM1_CARD_READER_VALUE)) {
|
||||||
|
log_warning(
|
||||||
|
"Invalid value for key '%s' specified, fallback "
|
||||||
|
"to default '%d'",
|
||||||
|
SDVXHOOK2_CONFIG_IO_COM1_CARD_READER_KEY,
|
||||||
|
SDVXHOOK2_CONFIG_IO_DEFAULT_COM1_CARD_READER_VALUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ struct sdvxhook2_config_io {
|
|||||||
bool disable_poll_limiter;
|
bool disable_poll_limiter;
|
||||||
bool force_headphones;
|
bool force_headphones;
|
||||||
bool disable_file_hooks;
|
bool disable_file_hooks;
|
||||||
|
bool disable_power_hooks;
|
||||||
|
bool disable_nvapi_hooks;
|
||||||
|
bool com1_card_reader;
|
||||||
};
|
};
|
||||||
|
|
||||||
void sdvxhook2_config_io_init(struct cconfig *config);
|
void sdvxhook2_config_io_init(struct cconfig *config);
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
#include "sdvxhook2/acio.h"
|
#include "sdvxhook2/acio.h"
|
||||||
#include "sdvxhook2/bi2a.h"
|
#include "sdvxhook2/bi2a.h"
|
||||||
#include "sdvxhook2/config-io.h"
|
#include "sdvxhook2/config-io.h"
|
||||||
|
#include "sdvxhook2/nvapi.h"
|
||||||
|
#include "sdvxhook2/power.h"
|
||||||
|
|
||||||
#include "camhook/cam.h"
|
#include "camhook/cam.h"
|
||||||
#include "camhook/config-cam.h"
|
#include "camhook/config-cam.h"
|
||||||
@@ -147,14 +149,21 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!config_io.disable_card_reader_emu) {
|
if (!config_io.disable_card_reader_emu) {
|
||||||
ac_io_port_init();
|
ac_io_port_init(config_io.com1_card_reader);
|
||||||
}
|
}
|
||||||
|
|
||||||
// camera hooks
|
|
||||||
if (!config_cam.disable_emu) {
|
if (!config_cam.disable_emu) {
|
||||||
camhook_init(&config_cam);
|
camhook_init(&config_cam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!config_io.disable_power_hooks) {
|
||||||
|
powerhook_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!config_io.disable_nvapi_hooks) {
|
||||||
|
nvapihook_init();
|
||||||
|
}
|
||||||
|
|
||||||
adapter_hook_override(config_adapter.override_ip);
|
adapter_hook_override(config_adapter.override_ip);
|
||||||
|
|
||||||
log_info("--- End sdvxhook dll_entry_init ---");
|
log_info("--- End sdvxhook dll_entry_init ---");
|
||||||
|
|||||||
71
src/main/sdvxhook2/nvapi.c
Normal file
71
src/main/sdvxhook2/nvapi.c
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
#define LOG_MODULE "power-hook"
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
// Don't format because the order is important here
|
||||||
|
#include <windows.h>
|
||||||
|
#include <initguid.h>
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
#include <powrprof.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "hook/com-proxy.h"
|
||||||
|
#include "hook/table.h"
|
||||||
|
|
||||||
|
#include "sdvxhook2/nvapi.h"
|
||||||
|
|
||||||
|
#include "util/log.h"
|
||||||
|
|
||||||
|
static void *my_GetProcAddress(HMODULE dll, const char *name);
|
||||||
|
|
||||||
|
static void *(*real_GetProcAddress)(HMODULE dll, const char *name);
|
||||||
|
|
||||||
|
// nvapi64.dll
|
||||||
|
static void *my_nvapi_QueryInterface(uint32_t FunctionOffset);
|
||||||
|
static void *(*real_nvapi_QueryInterface)(uint32_t FunctionOffset);
|
||||||
|
|
||||||
|
static struct hook_symbol nvapihook_kernel_syms[] = {
|
||||||
|
{.name = "GetProcAddress",
|
||||||
|
.patch = my_GetProcAddress,
|
||||||
|
.link = (void *) &real_GetProcAddress},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void *my_GetProcAddress(HMODULE dll, const char *name)
|
||||||
|
{
|
||||||
|
if (strcmp("nvapi_QueryInterface", name) == 0) {
|
||||||
|
log_info("Request for stub %s", name);
|
||||||
|
real_nvapi_QueryInterface = real_GetProcAddress(dll, name);
|
||||||
|
return &my_nvapi_QueryInterface;
|
||||||
|
}
|
||||||
|
|
||||||
|
// log_warning("Request for unknown stub %s", name);
|
||||||
|
return real_GetProcAddress(dll, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OFFSET_NvAPI_DISP_SetDisplayConfig 0x5D8CF8DE
|
||||||
|
|
||||||
|
static void *my_nvapi_QueryInterface(uint32_t FunctionOffset) {
|
||||||
|
if (FunctionOffset == OFFSET_NvAPI_DISP_SetDisplayConfig) {
|
||||||
|
log_info("Request for interface %x intercepted", FunctionOffset);
|
||||||
|
// no point stubbing this, the error checking for now doesn't check the response anyways
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info("Request for interface %x passed", FunctionOffset);
|
||||||
|
return real_nvapi_QueryInterface(FunctionOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nvapihook_init()
|
||||||
|
{
|
||||||
|
hook_table_apply(
|
||||||
|
NULL,
|
||||||
|
"kernel32.dll",
|
||||||
|
nvapihook_kernel_syms,
|
||||||
|
lengthof(nvapihook_kernel_syms));
|
||||||
|
}
|
||||||
|
|
||||||
|
void nvapihook_fini(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
8
src/main/sdvxhook2/nvapi.h
Normal file
8
src/main/sdvxhook2/nvapi.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef NVAPIHOOK_H
|
||||||
|
#define NVAPIHOOK_H
|
||||||
|
|
||||||
|
void nvapihook_init();
|
||||||
|
|
||||||
|
void nvapihook_fini(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
86
src/main/sdvxhook2/power.c
Normal file
86
src/main/sdvxhook2/power.c
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
#define LOG_MODULE "power-hook"
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
// Don't format because the order is important here
|
||||||
|
#include <windows.h>
|
||||||
|
#include <initguid.h>
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
#include <powrprof.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "hook/com-proxy.h"
|
||||||
|
#include "hook/table.h"
|
||||||
|
|
||||||
|
#include "sdvxhook2/power.h"
|
||||||
|
|
||||||
|
#include "util/log.h"
|
||||||
|
|
||||||
|
static DWORD
|
||||||
|
my_PowerSetActiveScheme(HKEY UserRootPowerKey, const GUID *SchemeGuid);
|
||||||
|
static DWORD my_PowerWriteACValueIndex(
|
||||||
|
HKEY RootPowerKey,
|
||||||
|
const GUID *SchemeGuid,
|
||||||
|
const GUID *SubGroupOfPowerSettingsGuid,
|
||||||
|
const GUID *PowerSettingGuid,
|
||||||
|
DWORD AcValueIndex);
|
||||||
|
static DWORD
|
||||||
|
my_PowerGetActiveScheme(HKEY UserRootPowerKey, GUID **ActivePolicyGuid);
|
||||||
|
|
||||||
|
static DWORD (*real_PowerSetActiveScheme)(
|
||||||
|
HKEY UserRootPowerKey, const GUID *SchemeGuid);
|
||||||
|
static DWORD (*real_PowerWriteACValueIndex)(
|
||||||
|
HKEY RootPowerKey,
|
||||||
|
const GUID *SchemeGuid,
|
||||||
|
const GUID *SubGroupOfPowerSettingsGuid,
|
||||||
|
const GUID *PowerSettingGuid,
|
||||||
|
DWORD AcValueIndex);
|
||||||
|
static DWORD (*real_PowerGetActiveScheme)(
|
||||||
|
HKEY UserRootPowerKey, GUID **ActivePolicyGuid);
|
||||||
|
|
||||||
|
static const struct hook_symbol powerhook_pp_syms[] = {
|
||||||
|
{.name = "PowerGetActiveScheme",
|
||||||
|
.patch = my_PowerGetActiveScheme,
|
||||||
|
.link = (void **) &real_PowerGetActiveScheme},
|
||||||
|
{.name = "PowerWriteACValueIndex",
|
||||||
|
.patch = my_PowerWriteACValueIndex,
|
||||||
|
.link = (void **) &real_PowerWriteACValueIndex},
|
||||||
|
{.name = "PowerSetActiveScheme",
|
||||||
|
.patch = my_PowerSetActiveScheme,
|
||||||
|
.link = (void **) &real_PowerSetActiveScheme},
|
||||||
|
};
|
||||||
|
|
||||||
|
static DWORD
|
||||||
|
my_PowerSetActiveScheme(HKEY UserRootPowerKey, const GUID *SchemeGuid)
|
||||||
|
{
|
||||||
|
// stubbed
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static DWORD my_PowerWriteACValueIndex(
|
||||||
|
HKEY RootPowerKey,
|
||||||
|
const GUID *SchemeGuid,
|
||||||
|
const GUID *SubGroupOfPowerSettingsGuid,
|
||||||
|
const GUID *PowerSettingGuid,
|
||||||
|
DWORD AcValueIndex)
|
||||||
|
{
|
||||||
|
// stubbed
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static DWORD
|
||||||
|
my_PowerGetActiveScheme(HKEY UserRootPowerKey, GUID **ActivePolicyGuid)
|
||||||
|
{
|
||||||
|
// stubbed
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void powerhook_init()
|
||||||
|
{
|
||||||
|
hook_table_apply(
|
||||||
|
NULL, "PowrProf.dll", powerhook_pp_syms, lengthof(powerhook_pp_syms));
|
||||||
|
}
|
||||||
|
|
||||||
|
void powerhook_fini(void)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
8
src/main/sdvxhook2/power.h
Normal file
8
src/main/sdvxhook2/power.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef POWERHOOK_H
|
||||||
|
#define POWERHOOK_H
|
||||||
|
|
||||||
|
void powerhook_init();
|
||||||
|
|
||||||
|
void powerhook_fini(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -6,9 +6,15 @@
|
|||||||
|
|
||||||
#define SDVXIO_KFCA_CONFIG_KFCA_PORT_KEY "kfca.port"
|
#define SDVXIO_KFCA_CONFIG_KFCA_PORT_KEY "kfca.port"
|
||||||
#define SDVXIO_KFCA_CONFIG_KFCA_BAUD_KEY "kfca.baud"
|
#define SDVXIO_KFCA_CONFIG_KFCA_BAUD_KEY "kfca.baud"
|
||||||
|
#define SDVXIO_KFCA_CONFIG_MAIN_AMP_VOLUME_KEY "kfca.main_override"
|
||||||
|
#define SDVXIO_KFCA_CONFIG_HEADPHONE_AMP_VOLUME_KEY "kfca.headphone_override"
|
||||||
|
#define SDVXIO_KFCA_CONFIG_SUBWOOFER_AMP_VOLUME_KEY "kfca.subwoofer_override"
|
||||||
|
|
||||||
#define SDVXIO_KFCA_CONFIG_KFCA_DEFAULT_PORT_VALUE "COM3"
|
#define SDVXIO_KFCA_CONFIG_KFCA_DEFAULT_PORT_VALUE "COM3"
|
||||||
#define SDVXIO_KFCA_CONFIG_KFCA_DEFAULT_BAUD_VALUE 57600
|
#define SDVXIO_KFCA_CONFIG_KFCA_DEFAULT_BAUD_VALUE 57600
|
||||||
|
#define SDVXIO_KFCA_CONFIG_DEFAULT_MAIN_AMP_VOLUME_VALUE -1
|
||||||
|
#define SDVXIO_KFCA_CONFIG_DEFAULT_HEADPHONE_AMP_VOLUME_VALUE -1
|
||||||
|
#define SDVXIO_KFCA_CONFIG_DEFAULT_SUBWOOFER_AMP_VOLUME_VALUE -1
|
||||||
|
|
||||||
void sdvxio_kfca_config_kfca_init(struct cconfig *config)
|
void sdvxio_kfca_config_kfca_init(struct cconfig *config)
|
||||||
{
|
{
|
||||||
@@ -23,6 +29,24 @@ void sdvxio_kfca_config_kfca_init(struct cconfig *config)
|
|||||||
SDVXIO_KFCA_CONFIG_KFCA_BAUD_KEY,
|
SDVXIO_KFCA_CONFIG_KFCA_BAUD_KEY,
|
||||||
SDVXIO_KFCA_CONFIG_KFCA_DEFAULT_BAUD_VALUE,
|
SDVXIO_KFCA_CONFIG_KFCA_DEFAULT_BAUD_VALUE,
|
||||||
"KFCA ACIO bus baudrate (real devices expect 57600)");
|
"KFCA ACIO bus baudrate (real devices expect 57600)");
|
||||||
|
|
||||||
|
cconfig_util_set_int(
|
||||||
|
config,
|
||||||
|
SDVXIO_KFCA_CONFIG_MAIN_AMP_VOLUME_KEY,
|
||||||
|
SDVXIO_KFCA_CONFIG_DEFAULT_MAIN_AMP_VOLUME_VALUE,
|
||||||
|
"SDVXIO digital amp main volume (0-96) 0 is high, 96 is low. -1 is no override.");
|
||||||
|
|
||||||
|
cconfig_util_set_int(
|
||||||
|
config,
|
||||||
|
SDVXIO_KFCA_CONFIG_HEADPHONE_AMP_VOLUME_KEY,
|
||||||
|
SDVXIO_KFCA_CONFIG_DEFAULT_HEADPHONE_AMP_VOLUME_VALUE,
|
||||||
|
"SDVXIO digital amp headphone volume (0-96) 0 is high, 96 is low. -1 is no override.");
|
||||||
|
|
||||||
|
cconfig_util_set_int(
|
||||||
|
config,
|
||||||
|
SDVXIO_KFCA_CONFIG_SUBWOOFER_AMP_VOLUME_KEY,
|
||||||
|
SDVXIO_KFCA_CONFIG_DEFAULT_SUBWOOFER_AMP_VOLUME_VALUE,
|
||||||
|
"SDVXIO digital amp subwoofer volume (0-96) 0 is high, 96 is low. -1 is no override.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void sdvxio_kfca_config_kfca_get(
|
void sdvxio_kfca_config_kfca_get(
|
||||||
@@ -52,4 +76,40 @@ void sdvxio_kfca_config_kfca_get(
|
|||||||
SDVXIO_KFCA_CONFIG_KFCA_BAUD_KEY,
|
SDVXIO_KFCA_CONFIG_KFCA_BAUD_KEY,
|
||||||
SDVXIO_KFCA_CONFIG_KFCA_DEFAULT_BAUD_VALUE);
|
SDVXIO_KFCA_CONFIG_KFCA_DEFAULT_BAUD_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!cconfig_util_get_int(
|
||||||
|
config,
|
||||||
|
SDVXIO_KFCA_CONFIG_MAIN_AMP_VOLUME_KEY,
|
||||||
|
&config_kfca->override_main_volume,
|
||||||
|
SDVXIO_KFCA_CONFIG_DEFAULT_MAIN_AMP_VOLUME_VALUE)) {
|
||||||
|
log_warning(
|
||||||
|
"Invalid value for key '%s' specified, fallback "
|
||||||
|
"to default '%d'",
|
||||||
|
SDVXIO_KFCA_CONFIG_MAIN_AMP_VOLUME_KEY,
|
||||||
|
SDVXIO_KFCA_CONFIG_DEFAULT_MAIN_AMP_VOLUME_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cconfig_util_get_int(
|
||||||
|
config,
|
||||||
|
SDVXIO_KFCA_CONFIG_HEADPHONE_AMP_VOLUME_KEY,
|
||||||
|
&config_kfca->override_headphone_volume,
|
||||||
|
SDVXIO_KFCA_CONFIG_DEFAULT_HEADPHONE_AMP_VOLUME_VALUE)) {
|
||||||
|
log_warning(
|
||||||
|
"Invalid value for key '%s' specified, fallback "
|
||||||
|
"to default '%d'",
|
||||||
|
SDVXIO_KFCA_CONFIG_HEADPHONE_AMP_VOLUME_KEY,
|
||||||
|
SDVXIO_KFCA_CONFIG_DEFAULT_HEADPHONE_AMP_VOLUME_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cconfig_util_get_int(
|
||||||
|
config,
|
||||||
|
SDVXIO_KFCA_CONFIG_SUBWOOFER_AMP_VOLUME_KEY,
|
||||||
|
&config_kfca->override_sub_volume,
|
||||||
|
SDVXIO_KFCA_CONFIG_DEFAULT_SUBWOOFER_AMP_VOLUME_VALUE)) {
|
||||||
|
log_warning(
|
||||||
|
"Invalid value for key '%s' specified, fallback "
|
||||||
|
"to default '%d'",
|
||||||
|
SDVXIO_KFCA_CONFIG_SUBWOOFER_AMP_VOLUME_KEY,
|
||||||
|
SDVXIO_KFCA_CONFIG_DEFAULT_SUBWOOFER_AMP_VOLUME_VALUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
struct sdvxio_kfca_config_kfca {
|
struct sdvxio_kfca_config_kfca {
|
||||||
char port[64];
|
char port[64];
|
||||||
int32_t baud;
|
int32_t baud;
|
||||||
|
int32_t override_main_volume;
|
||||||
|
int32_t override_headphone_volume;
|
||||||
|
int32_t override_sub_volume;
|
||||||
};
|
};
|
||||||
|
|
||||||
void sdvxio_kfca_config_kfca_init(struct cconfig *config);
|
void sdvxio_kfca_config_kfca_init(struct cconfig *config);
|
||||||
|
|||||||
@@ -120,9 +120,24 @@ bool sdvx_io_init(
|
|||||||
if (kfca_node_id != -1) {
|
if (kfca_node_id != -1) {
|
||||||
log_warning("Using KFCA on node: %d", kfca_node_id);
|
log_warning("Using KFCA on node: %d", kfca_node_id);
|
||||||
|
|
||||||
bool init_result = aciodrv_kfca_init(
|
uint8_t primary = 0;
|
||||||
|
uint8_t headphone = 0;
|
||||||
|
uint8_t subwoofer = 0;
|
||||||
|
|
||||||
|
if (config_kfca.override_main_volume >= 0) {
|
||||||
|
primary = config_kfca.override_main_volume;
|
||||||
|
}
|
||||||
|
if (config_kfca.override_headphone_volume >= 0) {
|
||||||
|
headphone = config_kfca.override_headphone_volume;
|
||||||
|
}
|
||||||
|
if (config_kfca.override_sub_volume >= 0) {
|
||||||
|
subwoofer = config_kfca.override_sub_volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool init_result = aciodrv_kfca_amp(
|
||||||
aciomgr_port_checkout(acio_manager_ctx),
|
aciomgr_port_checkout(acio_manager_ctx),
|
||||||
kfca_node_id);
|
kfca_node_id,
|
||||||
|
primary, headphone, 0, subwoofer);
|
||||||
aciomgr_port_checkin(acio_manager_ctx);
|
aciomgr_port_checkin(acio_manager_ctx);
|
||||||
|
|
||||||
if (!init_result) {
|
if (!init_result) {
|
||||||
@@ -240,7 +255,7 @@ bool sdvx_io_set_amp_volume(
|
|||||||
bool amp_result = aciodrv_kfca_amp(
|
bool amp_result = aciodrv_kfca_amp(
|
||||||
aciomgr_port_checkout(acio_manager_ctx),
|
aciomgr_port_checkout(acio_manager_ctx),
|
||||||
kfca_node_id,
|
kfca_node_id,
|
||||||
primary, 96, headphone, subwoofer);
|
primary, headphone, 96, subwoofer);
|
||||||
aciomgr_port_checkin(acio_manager_ctx);
|
aciomgr_port_checkin(acio_manager_ctx);
|
||||||
|
|
||||||
if (!amp_result) {
|
if (!amp_result) {
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ bool sdvx_io_read_input(void)
|
|||||||
sdvx_io_gpio[0] = (pack >> 8) & 0x00FF;
|
sdvx_io_gpio[0] = (pack >> 8) & 0x00FF;
|
||||||
sdvx_io_gpio[1] = (pack >> 16) & 0x00FF;
|
sdvx_io_gpio[1] = (pack >> 16) & 0x00FF;
|
||||||
|
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t sdvx_io_get_input_gpio_sys(void)
|
uint8_t sdvx_io_get_input_gpio_sys(void)
|
||||||
|
|||||||
@@ -137,6 +137,19 @@ bool security_id_verify(const struct security_id *id)
|
|||||||
{
|
{
|
||||||
log_assert(id);
|
log_assert(id);
|
||||||
|
|
||||||
return id->header == SECURITY_ID_HEADER &&
|
if(id->header != SECURITY_ID_HEADER) {
|
||||||
id->checksum == security_id_checksum_buffer(id->id);
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
|
|
||||||
/* Jubeat */
|
/* Jubeat */
|
||||||
#define SECURITY_MCODE_GAME_JB_1 "H44"
|
#define SECURITY_MCODE_GAME_JB_1 "H44"
|
||||||
|
#define SECURITY_MCODE_GAME_JB_3 "J44"
|
||||||
|
|
||||||
/* Region */
|
/* Region */
|
||||||
#define SECURITY_MCODE_REGION_ASIA 'A'
|
#define SECURITY_MCODE_REGION_ASIA 'A'
|
||||||
@@ -58,6 +59,7 @@
|
|||||||
|
|
||||||
/* Cabinet */
|
/* Cabinet */
|
||||||
#define SECURITY_MCODE_CABINET_A 'A'
|
#define SECURITY_MCODE_CABINET_A 'A'
|
||||||
|
#define SECURITY_MCODE_CABINET_C 'C'
|
||||||
|
|
||||||
/* Revision */
|
/* Revision */
|
||||||
#define SECURITY_MCODE_REVISION_A 'A'
|
#define SECURITY_MCODE_REVISION_A 'A'
|
||||||
@@ -104,4 +106,4 @@ bool security_mcode_parse(const char *str, struct security_mcode *mcode);
|
|||||||
*/
|
*/
|
||||||
char *security_mcode_to_str(const struct security_mcode *mcode);
|
char *security_mcode_to_str(const struct security_mcode *mcode);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user