mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2026-09-15 03:45:09 -05:00
Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
85a080e6b3 | ||
|
|
28633ded37 | ||
|
|
721897d7b0 | ||
|
|
926bbf2e10 | ||
|
|
ce75e149f7 | ||
|
|
57d9d976ff | ||
|
|
7e731916e2 | ||
|
|
dd9b8faafe | ||
|
|
50ff026b85 | ||
|
|
0ff6134b79 | ||
|
|
ae35b859d9 | ||
|
|
3cf3d44945 | ||
|
|
2a80083af2 | ||
|
|
66e0467ad3 | ||
|
|
c5f0116294 | ||
|
|
ddfa814387 | ||
|
|
088d4bf338 | ||
|
|
f1a7621e2b | ||
|
|
4a3d5fa189 | ||
|
|
0f2828da40 | ||
|
|
ba2016b5bc | ||
|
|
b42c9aa93b | ||
|
|
8de259c639 | ||
|
|
0d54587787 | ||
|
|
4721ba2d3c | ||
|
|
1105a2a130 | ||
|
|
8ab92872ad | ||
|
|
a16dc82cef | ||
|
|
729f5abcc0 | ||
|
|
6e0e5031ac | ||
|
|
f17e8d6739 | ||
|
|
ac02609948 | ||
|
|
c644db03ae | ||
|
|
7d5398b6af | ||
|
|
cac09f8f87 | ||
|
|
85c9c444f1 | ||
|
|
8f2ce1f1b3 | ||
|
|
d3bf381a4f | ||
|
|
3acbc7f251 | ||
|
|
839903ab48 | ||
|
|
c929141e71 | ||
|
|
1477480836 | ||
|
|
bf4322e855 | ||
|
|
3eed0a4ab3 | ||
|
|
a9ade9d9d4 | ||
|
|
26336805d2 | ||
|
|
7d0e916b9f | ||
|
|
a03a5604ec |
145
.gitlab-ci.yml
145
.gitlab-ci.yml
@@ -1,55 +1,136 @@
|
||||
#
|
||||
# This pipeline requires packages to be switched on under the repository settings. Otherwise, you will 403s when
|
||||
# uploading to the package repo is triggered.
|
||||
#
|
||||
# Variables to setup in GitLab CI/CD settings of the project
|
||||
#
|
||||
# The variables with BASE64 postfixes need to contain the base64 encoded data. Otherwise, masking
|
||||
# in GitLab won't work due to not matching their pre-defined regex
|
||||
#
|
||||
# CI_PIGSTALL_DATA_PREFIX_BASE64
|
||||
# CI_PIGSTALL_LINK_BASE64
|
||||
# CI_PIGSTALL_PHP_SESSION_ID
|
||||
# CI_PIGSTALL_SESSION_BASE64
|
||||
#
|
||||
# CI_TOOLS_UPLOAD_KEY
|
||||
# CI_TOOLS_UPLOAD_URL
|
||||
# CI_TOOLS_URL
|
||||
|
||||
image: docker:stable
|
||||
|
||||
variables:
|
||||
DOCKER_TLS_CERTDIR: "/certs"
|
||||
DIST_PACKAGE_RELATIVE_PATH: "build/docker/bemanitools.zip"
|
||||
PACKAGE_REGISTRY_URL: "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/bemanitools"
|
||||
|
||||
services:
|
||||
- docker:19.03.8-dind
|
||||
|
||||
before_script:
|
||||
- docker info
|
||||
|
||||
stages:
|
||||
- build
|
||||
- upload-release
|
||||
- upload
|
||||
- release
|
||||
|
||||
build-master:
|
||||
build:
|
||||
stage: build
|
||||
before_script:
|
||||
- apk update && apk add make > /dev/null
|
||||
script:
|
||||
- make build-docker
|
||||
- mv build/docker/bemanitools.zip bemanitools.zip
|
||||
artifacts:
|
||||
name: "$CI_COMMIT_SHORT_SHA-$CI_JOB_NAME"
|
||||
paths:
|
||||
- bemanitools.zip
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
|
||||
build-tags:
|
||||
stage: build
|
||||
- tags
|
||||
before_script:
|
||||
- apk update && apk add make > /dev/null
|
||||
script:
|
||||
- make build-docker
|
||||
- mv build/docker/bemanitools.zip bemanitools.zip
|
||||
artifacts:
|
||||
name: "$CI_COMMIT_SHORT_SHA-$CI_JOB_NAME"
|
||||
paths:
|
||||
- bemanitools.zip
|
||||
only:
|
||||
- tags
|
||||
- build
|
||||
expire_in: 1 week
|
||||
|
||||
upload-release:
|
||||
stage: upload-release
|
||||
dependencies:
|
||||
- build-tags
|
||||
before_script:
|
||||
- apk update && apk add curl > /dev/null
|
||||
script:
|
||||
- echo "Uploading ${CI_PROJECT_NAME}-${CI_COMMIT_TAG}..."
|
||||
- curl --silent --show-error -F "key=${CI_UPLOAD_KEY}" -F "filename=${CI_PROJECT_NAME}-v${CI_COMMIT_TAG}.zip" -F "file=@./bemanitools.zip" ${CI_UPLOAD_URL}
|
||||
upload-package-registry:
|
||||
stage: upload
|
||||
image: curlimages/curl:latest
|
||||
only:
|
||||
- tags
|
||||
refs:
|
||||
- master
|
||||
- tags
|
||||
dependencies:
|
||||
- build
|
||||
script:
|
||||
- |
|
||||
if [ "${CI_COMMIT_TAG}" ]; then
|
||||
version="${CI_COMMIT_TAG}"
|
||||
else
|
||||
version="${CI_COMMIT_SHORT_SHA}"
|
||||
fi
|
||||
- |
|
||||
curl \
|
||||
--silent \
|
||||
--fail \
|
||||
--show-error \
|
||||
--header "JOB-TOKEN: ${CI_JOB_TOKEN}" \
|
||||
--upload-file "${DIST_PACKAGE_RELATIVE_PATH}" \
|
||||
$PACKAGE_REGISTRY_URL/${version}/bemanitools.zip
|
||||
|
||||
upload-tools-page:
|
||||
stage: upload
|
||||
image: curlimages/curl:latest
|
||||
only:
|
||||
refs:
|
||||
- tags
|
||||
dependencies:
|
||||
- build
|
||||
script:
|
||||
- |
|
||||
curl \
|
||||
--silent \
|
||||
--fail \
|
||||
--show-error \
|
||||
--connect-timeout 5 \
|
||||
--max-time 10 \
|
||||
--retry 5 \
|
||||
-F "key=${CI_TOOLS_UPLOAD_KEY}" \
|
||||
-F "filename=${CI_PROJECT_NAME}-v${CI_COMMIT_TAG}.zip" \
|
||||
-F "file=@${DIST_PACKAGE_RELATIVE_PATH}" \
|
||||
${CI_TOOLS_UPLOAD_URL}
|
||||
|
||||
release-gitlab:
|
||||
stage: release
|
||||
image: registry.gitlab.com/gitlab-org/release-cli:v0.8.0
|
||||
only:
|
||||
refs:
|
||||
- tags
|
||||
script:
|
||||
- version="$CI_COMMIT_TAG"
|
||||
- release_message="$(scripts/ci/create-release-message.sh "${version}" < CHANGELOG.md)"
|
||||
- |
|
||||
release-cli create \
|
||||
--name "bemanitools ${version}" \
|
||||
--description="${release_message}" \
|
||||
--tag-name ${version} \
|
||||
--assets-link "{\"name\":\"Distribution binaries\",\"url\":\"${PACKAGE_REGISTRY_URL}/${version}/bemanitools.zip\"}"
|
||||
|
||||
release-pigstall:
|
||||
stage: release
|
||||
image: curlimages/curl:latest
|
||||
only:
|
||||
refs:
|
||||
- tags
|
||||
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)"
|
||||
- |
|
||||
curl \
|
||||
--silent \
|
||||
--fail \
|
||||
--connect-timeout 5 \
|
||||
--max-time 10 \
|
||||
--retry 5 \
|
||||
--show-error \
|
||||
-H 'Content-Type: application/x-www-form-urlencoded' \
|
||||
-H "Cookie: PHPSESSID=$CI_PIGSTALL_PHP_SESSION_ID; session=${session}" \
|
||||
--data-raw "${data_prefix}&body=${release_message}" \
|
||||
"${link}"
|
||||
|
||||
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,7 +1,28 @@
|
||||
# Release history
|
||||
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.
|
||||
|
||||
## 5.39
|
||||
* jbhook3: Fix window mode, remove window frame option, add show cursor on window option
|
||||
* Code simplification and cleanup round plug modules
|
||||
* Code structure improvements p3io jubeat
|
||||
|
||||
## 5.38
|
||||
* sdvxhook2: Support sound voltex exceed gear
|
||||
|
||||
## 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
|
||||
* iidxhook9: Support for IIDX28
|
||||
* Various bugfixes
|
||||
|
||||
## 5.35
|
||||
* Jubeat: Add jbio-p4io
|
||||
* Nostalgia: Add nostio-panb
|
||||
* Misc: Add wavepass support to aciodrv-icca (and eamio-icca)
|
||||
* Misc: Refactor aciodrv to support multiple devices using the same port (with aciomgr)
|
||||
* Misc: Fix d3d9ex windowed hook not behaving correctly (size/framed)
|
||||
* Misc: Fix docs not being included with release
|
||||
|
||||
@@ -226,7 +226,7 @@ $$(dll_$1_$2_$3) $$(implib_$1_$2_$3): $$(obj_$1_$2_$3) $$(abslib_$1_$2_$3) \
|
||||
$(V)echo ... $$(dll_$1_$2_$3)
|
||||
$(V)$$(toolchain_$1)gcc -shared \
|
||||
-o $$(dll_$1_$2_$3) -Wl,--out-implib,$$(implib_$1_$2_$3) \
|
||||
$$^ $$(ldflags_$3)
|
||||
-Wl,--start-group $$^ -Wl,--end-group $$(ldflags_$3)
|
||||
$(V)$$(toolchain_$1)strip $$(dll_$1_$2_$3)
|
||||
$(V)$$(toolchain_$1)ranlib $$(implib_$1_$2_$3)
|
||||
|
||||
|
||||
74
Module.mk
74
Module.mk
@@ -26,7 +26,8 @@
|
||||
# 8: Patch 3: beatmania IIDX 16 Empress
|
||||
# jubeat
|
||||
#
|
||||
# 10: Patch 4: DanceDanceRevolution X2
|
||||
# 10: Patch 2: jubeat Knit
|
||||
# Patch 4: DanceDanceRevolution X2
|
||||
#
|
||||
# 11: Patch 1: beatmania IIDX 18 Resort Anthem
|
||||
# pop'n music 19 Tune Street
|
||||
@@ -71,7 +72,7 @@ cflags += \
|
||||
# Each AVS-dependent project should consume the earliest AVS import definition
|
||||
# that is still ABI-compatible with the real build its target links against.
|
||||
|
||||
avsvers_32 := 1700 1603 1601 1508 1403 1304 1101 803 0
|
||||
avsvers_32 := 1700 1603 1601 1508 1403 1304 1101 1002 803 0
|
||||
avsvers_64 := 1700 1603 1601 1509 1508
|
||||
|
||||
imps += avs avs-ea3
|
||||
@@ -91,6 +92,7 @@ include src/main/camhook/Module.mk
|
||||
include src/main/cconfig/Module.mk
|
||||
include src/main/config/Module.mk
|
||||
include src/main/d3d9exhook/Module.mk
|
||||
include src/main/ddrhook-util/Module.mk
|
||||
include src/main/ddrhook/Module.mk
|
||||
include src/main/ddrio-mm/Module.mk
|
||||
include src/main/ddrio-smx/Module.mk
|
||||
@@ -135,12 +137,15 @@ include src/main/iidxio-ezusb2/Module.mk
|
||||
include src/main/iidxio/Module.mk
|
||||
include src/main/iidxiotest/Module.mk
|
||||
include src/main/inject/Module.mk
|
||||
include src/main/jbhook/Module.mk
|
||||
include src/main/jbhook1/Module.mk
|
||||
include src/main/jbio-magicbox/Module.mk
|
||||
include src/main/jbio-p4io/Module.mk
|
||||
include src/main/jbio/Module.mk
|
||||
include src/main/jbiotest/Module.mk
|
||||
include src/main/jbhook-util/Module.mk
|
||||
include src/main/jbhook-util-p3io/Module.mk
|
||||
include src/main/jbhook1/Module.mk
|
||||
include src/main/jbhook2/Module.mk
|
||||
include src/main/jbhook3/Module.mk
|
||||
include src/main/launcher/Module.mk
|
||||
include src/main/mempatch-hook/Module.mk
|
||||
include src/main/mm/Module.mk
|
||||
@@ -365,7 +370,7 @@ $(zipdir)/iidx-25-to-26.zip: \
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/iidx-27.zip: \
|
||||
$(zipdir)/iidx-27-to-28.zip: \
|
||||
build/bin/avs2_1700-64/iidxhook9.dll \
|
||||
build/bin/avs2_1700-64/launcher.exe \
|
||||
build/bin/indep-64/config.exe \
|
||||
@@ -375,7 +380,9 @@ $(zipdir)/iidx-27.zip: \
|
||||
build/bin/indep-64/vefxio.dll \
|
||||
dist/iidx/config.bat \
|
||||
dist/iidx/gamestart-27.bat \
|
||||
dist/iidx/gamestart-28.bat \
|
||||
dist/iidx/iidxhook-27.conf \
|
||||
dist/iidx/iidxhook-28.conf \
|
||||
dist/iidx/vefx.txt \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
@@ -421,28 +428,68 @@ $(zipdir)/jb-01.zip: \
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/jb-02.zip: \
|
||||
build/bin/avs2_1002-32/jbhook1.dll \
|
||||
build/bin/indep-32/inject.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/jbio.dll \
|
||||
dist/jb/config.bat \
|
||||
dist/jb/gamestart-02.bat \
|
||||
dist/jb/jbhook-02.conf \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/jb-03.zip: \
|
||||
build/bin/avs2_1101-32/jbhook2.dll \
|
||||
build/bin/avs2_1101-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/jbio.dll \
|
||||
dist/jb/config.bat \
|
||||
dist/jb/gamestart-03.bat \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/jb-04.zip: \
|
||||
build/bin/avs2_1304-32/jbhook2.dll \
|
||||
build/bin/avs2_1304-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/jbio.dll \
|
||||
dist/jb/config.bat \
|
||||
dist/jb/gamestart-03.bat \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/jb-05-to-07.zip: \
|
||||
build/bin/avs2_1508-32/jbhook.dll \
|
||||
build/bin/avs2_1508-32/jbhook3.dll \
|
||||
build/bin/avs2_1508-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/jbio.dll \
|
||||
dist/jb/config.bat \
|
||||
dist/jb/gamestart.bat \
|
||||
dist/jb/gamestart-04.bat \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/jb-08.zip: \
|
||||
build/bin/avs2_1700-32/jbhook.dll \
|
||||
build/bin/avs2_1700-32/jbhook3.dll \
|
||||
build/bin/avs2_1700-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/jbio.dll \
|
||||
dist/jb/config.bat \
|
||||
dist/jb/gamestart.bat \
|
||||
dist/jb/gamestart-04.bat \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
@@ -471,7 +518,7 @@ $(zipdir)/sdvx-01-to-04.zip: \
|
||||
$(V)echo ... $@
|
||||
$(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/sdvxhook2.dll \
|
||||
build/bin/indep-64/config.exe \
|
||||
@@ -614,15 +661,18 @@ $(BUILDDIR)/bemanitools.zip: \
|
||||
$(zipdir)/iidx-20.zip \
|
||||
$(zipdir)/iidx-21-to-24.zip \
|
||||
$(zipdir)/iidx-25-to-26.zip \
|
||||
$(zipdir)/iidx-27.zip \
|
||||
$(zipdir)/iidx-27-to-28.zip \
|
||||
$(zipdir)/iidx-hwio-x86.zip \
|
||||
$(zipdir)/iidx-hwio-x64.zip \
|
||||
$(zipdir)/jb-01.zip \
|
||||
$(zipdir)/jb-02.zip \
|
||||
$(zipdir)/jb-03.zip \
|
||||
$(zipdir)/jb-04.zip \
|
||||
$(zipdir)/jb-05-to-07.zip \
|
||||
$(zipdir)/jb-08.zip \
|
||||
$(zipdir)/jb-hwio.zip \
|
||||
$(zipdir)/sdvx-01-to-04.zip \
|
||||
$(zipdir)/sdvx-05.zip \
|
||||
$(zipdir)/sdvx-05-to-06.zip \
|
||||
$(zipdir)/sdvx-05-cn.zip \
|
||||
$(zipdir)/sdvx-hwio-x86.zip \
|
||||
$(zipdir)/sdvx-hwio-x64.zip \
|
||||
|
||||
22
README.md
22
README.md
@@ -1,7 +1,7 @@
|
||||
# Bemanitools 5
|
||||
[](https://dev.s-ul.net/djhackers/bemanitools/commits/master)
|
||||
|
||||
Version: 5.35
|
||||
Version: 5.39
|
||||
|
||||
[Release history](CHANGELOG.md)
|
||||
|
||||
@@ -55,19 +55,25 @@ The tl;dr version and golden rules of the sections in the document:
|
||||
* Beatmania IIDX 24 SINOBUZ (iidx-21-to-24.zip) using [iidxhook7](doc/iidxhook/iidxhook7.md)
|
||||
* Beatmania IIDX 25 CANNON BALLERS (iidx-25-to-26.zip) using [iidxhook8](doc/iidxhook/iidxhook8.md)
|
||||
* Beatmania IIDX 26 Rootage (iidx-25-to-26.zip) using [iidxhook8](doc/iidxhook/iidxhook8.md)
|
||||
* Beatmania IIDX 27 Heroic Verse (iidx-27.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)
|
||||
* jubeat
|
||||
* jubeat (experimental/buggy) (jb-01.zip) using [jbhook1](doc/jbhook1/jbhook1.md)
|
||||
* jubeat saucer (fulfill) (jb-05-to-07.zip) using jbhook
|
||||
* jubeat prop (jb-05-to-07.zip) using jbhook
|
||||
* jubeat Qubell (jb-05-to-07.zip) using jbhook
|
||||
* jubeat clan (jb-08.zip) using jbhook
|
||||
* jubeat (jb-01.zip) using [jbhook1](doc/jbhook/jbhook1.md)
|
||||
* jubeat ripples (jb-02.zip) using [jbhook1](doc/jbhook/jbhook1.md)
|
||||
* jubeat knit (jb-03.zip) using [jbhook2](doc/jbhook/jbhook2.md)
|
||||
* jubeat copious (jb-04.zip) using [jbhook2](doc/jbhook/jbhook2.md)
|
||||
* 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 BOOTH (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 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
|
||||
Play your favorite non-bemani arcade games with any hardware, e.g. real cabinet hardware, that
|
||||
|
||||
16
dist/iidx/gamestart-28.bat
vendored
Normal file
16
dist/iidx/gamestart-28.bat
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
@echo off
|
||||
cd /d %~dp0
|
||||
|
||||
if not exist dev mkdir dev
|
||||
if not exist dev\e mkdir dev\e
|
||||
if not exist dev\g mkdir dev\g
|
||||
if not exist dev\nvram mkdir dev\nvram
|
||||
if not exist dev\raw mkdir dev\raw
|
||||
if not exist dev\raw\log mkdir dev\raw\log
|
||||
if not exist dev\raw\fscache mkdir dev\raw\fscache
|
||||
|
||||
for /R prop\defaults %%D in (*.*) do (
|
||||
if not exist dev\nvram\%%~nxD copy /y prop\defaults\%%~nxD dev\nvram
|
||||
)
|
||||
|
||||
launcher -H 134217728 -B iidxhook9.dll bm2dx.dll --config iidxhook-28.conf %*
|
||||
5
dist/iidx/iidxhook-14.conf
vendored
5
dist/iidx/iidxhook-14.conf
vendored
@@ -46,8 +46,5 @@ gfx.device_adapter=-1
|
||||
# Disable operator clock setting system clock time
|
||||
misc.disable_clock_set=false
|
||||
|
||||
# Security boot version (e.g. GEC02).
|
||||
sec.boot_version=GQGLDJAA
|
||||
|
||||
# Security black plug mcode id string (e.g. GQC02JAA).
|
||||
sec.black_plug_mcode=GQGLDJA
|
||||
sec.black_plug_mcode=GQGLDJAA
|
||||
5
dist/iidx/iidxhook-15.conf
vendored
5
dist/iidx/iidxhook-15.conf
vendored
@@ -46,8 +46,5 @@ gfx.device_adapter=-1
|
||||
# Disable operator clock setting system clock time
|
||||
misc.disable_clock_set=false
|
||||
|
||||
# Security boot version (e.g. GEC02).
|
||||
sec.boot_version=GQHDDJAA
|
||||
|
||||
# Security black plug mcode id string (e.g. GQC02JAA).
|
||||
sec.black_plug_mcode=GQHDDJA
|
||||
sec.black_plug_mcode=GQHDDJAA
|
||||
5
dist/iidx/iidxhook-16.conf
vendored
5
dist/iidx/iidxhook-16.conf
vendored
@@ -49,8 +49,5 @@ gfx.device_adapter=-1
|
||||
# Disable operator clock setting system clock time
|
||||
misc.disable_clock_set=false
|
||||
|
||||
# Security boot version (e.g. GEC02).
|
||||
sec.boot_version=GQI00JAA
|
||||
|
||||
# Security black plug mcode id string (e.g. GQC02JAA).
|
||||
sec.black_plug_mcode=GQI00JA
|
||||
sec.black_plug_mcode=GQI00JAA
|
||||
5
dist/iidx/iidxhook-17.conf
vendored
5
dist/iidx/iidxhook-17.conf
vendored
@@ -49,8 +49,5 @@ gfx.device_adapter=-1
|
||||
# Disable operator clock setting system clock time
|
||||
misc.disable_clock_set=false
|
||||
|
||||
# Security boot version (e.g. GEC02).
|
||||
sec.boot_version=GCJDJJAA
|
||||
|
||||
# Security black plug mcode id string (e.g. GQC02JAA).
|
||||
sec.black_plug_mcode=GCJDJJA
|
||||
sec.black_plug_mcode=GCJDJJAA
|
||||
78
dist/iidx/iidxhook-28.conf
vendored
Normal file
78
dist/iidx/iidxhook-28.conf
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
# Disable card reader emulation and enable usage of real card reader hardware on COM0 (for games supporting slotted readers)
|
||||
io.disable_card_reader_emu=false
|
||||
|
||||
# Disable BIO2 emulation and enable usage of real BIO2 hardware
|
||||
io.disable_bio2_emu=false
|
||||
|
||||
# Disables the poll limiter, warning very high CPU usage may arise
|
||||
io.disable_poll_limiter=false
|
||||
|
||||
# Lightning cab mode (requires additional IO emulation)
|
||||
io.lightning_mode=false
|
||||
|
||||
# Disable camera connection
|
||||
io.disable_cams=true
|
||||
|
||||
# Disables the built in file hooks, requiring manual file creation
|
||||
io.disable_file_hooks=false
|
||||
|
||||
# Turntable sensitivity multiplier (1.0 is default)
|
||||
io.tt_multiplier=1.0
|
||||
|
||||
# Disables the camera emulation
|
||||
cam.disable_emu=true
|
||||
|
||||
# Override camera device ID detection (copy from device manager, do not escape)
|
||||
cam.device_id1=
|
||||
|
||||
# Override camera device ID detection (copy from device manager, do not escape)
|
||||
cam.device_id2=
|
||||
|
||||
# Run the game in a framed window (requires windowed option)
|
||||
gfx.framed=true
|
||||
|
||||
# Run the game windowed
|
||||
gfx.windowed=false
|
||||
|
||||
# Confine mouse cursor to window
|
||||
gfx.confined=false
|
||||
|
||||
# Windowed width, -1 for default size
|
||||
gfx.window_width=-1
|
||||
|
||||
# Windowed height, -1 for default size
|
||||
gfx.window_height=-1
|
||||
|
||||
# Windowed X, -1 for default X position
|
||||
gfx.window_x=-1
|
||||
|
||||
# Windowed Y, -1 for default Y position
|
||||
gfx.window_y=-1
|
||||
|
||||
# Forced refresh rate, -1 to not force any (try 59 or 60 if monitor check fails to lock on high refresh rate monitors)
|
||||
gfx.forced_refresh_rate=-1
|
||||
|
||||
# D3D9ex device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
|
||||
gfx.device_adapter=-1
|
||||
|
||||
# Orientation to force monitor into, -1 to use default, 0, 1, 2, 3 to do 0, 90, 180, 270 degrees
|
||||
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
|
||||
|
||||
# IP of adapter to force override with
|
||||
adapter.override_ip=
|
||||
|
||||
# Force ASIO audio mode/device (if applicable / TDJ default)
|
||||
asio.force_asio=false
|
||||
|
||||
# Force WASAPI audio mode (if applicable / LDJ default)
|
||||
asio.force_wasapi=true
|
||||
|
||||
# The ASIO device name to use
|
||||
asio.device_name=XONAR SOUND CARD(64)
|
||||
|
||||
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 %*
|
||||
10
dist/jb/gamestart-03.bat
vendored
Normal file
10
dist/jb/gamestart-03.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 jbhook2.dll jubeat.dll -v
|
||||
@@ -7,4 +7,4 @@ if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml
|
||||
if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml
|
||||
if not exist dev\raw mkdir dev\raw
|
||||
|
||||
launcher -H 33554432 -K jbhook.dll jubeat.dll
|
||||
launcher -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
|
||||
gfx.windowed=false
|
||||
|
||||
# rotate the normally-horizontal game window to be vertical
|
||||
gfx.vertical=true
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
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=true
|
||||
|
||||
# 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)
|
||||
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)
|
||||
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
|
||||
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
|
||||
cam.disable_emu=false
|
||||
|
||||
|
||||
@@ -1,21 +1,29 @@
|
||||
# Bemanitools 5 documentation
|
||||
|
||||
This folder contains various types of documentation.
|
||||
|
||||
Table of contents:
|
||||
|
||||
* Key tools
|
||||
* [Inject](inject.md): Readme for one of BT5's key applications, `inject.exe`
|
||||
* [Launcher](launcher.md): Readme for another one of BT5's key applications, `launcher.exe`
|
||||
* [Tools](tools/README.md): Documentation for additional user and development tooling
|
||||
* [Inject](inject.md): Readme for one of BT5's key applications, `inject.exe`
|
||||
* [Launcher](launcher.md): Readme for another one of BT5's key applications, `launcher.exe`
|
||||
* [Tools](tools/README.md): Documentation for additional user and development tooling
|
||||
* Game hooks
|
||||
* [ddrhook](ddrhook/README.md): Documentation relevant to `ddrhook` implementations
|
||||
* [iidxhook](iidxhook/README.md): Documentation relevant to `iidxhook` implementations
|
||||
* [jbhook](jbhook/README.md): Documentation relevant to `jbhook` implementations
|
||||
* [sdvxhook](sdvxhook/README.md): Documentation relevant to `sdvxhook` implementations
|
||||
* [ddrhook](ddrhook/README.md): Documentation relevant to `ddrhook` implementations
|
||||
* [iidxhook](iidxhook/README.md): Documentation relevant to `iidxhook` implementations
|
||||
* [jbhook](jbhook/README.md): Documentation relevant to `jbhook` implementations
|
||||
* [sdvxhook](sdvxhook/README.md): Documentation relevant to `sdvxhook` implementations
|
||||
* Development
|
||||
* [API](api.md): Available APIs for BT5 and instructions how to use them
|
||||
* [Architecture](architecture.md): Outline of BT5's architecture, how things are designed and why
|
||||
* [Development](development.md): Development environment, building, releasing, etc.
|
||||
* [Developer documentation](dev/README.md): Various lose documentation/notes by developers
|
||||
* [Tools](tools/README.md): Documentation for additional user and development tooling
|
||||
* Hardware
|
||||
* [Hardware](hardware/README.md): Anything related to hardware, e.g. IO boards
|
||||
* [API](api.md): Available APIs for BT5 and instructions how to use them
|
||||
* [Architecture](architecture.md): Outline of BT5's architecture, how things are designed and why
|
||||
* [Development](development.md): Development environment, building, releasing, etc.
|
||||
* [Developer documentation](dev/README.md): Various lose documentation/notes by developers
|
||||
* [Tools](tools/README.md): Documentation for additional user and development tooling
|
||||
|
||||
## Further external documentation
|
||||
|
||||
A list of external documentation that can be useful when dealing with bemanitools,
|
||||
supported data and hardware.
|
||||
|
||||
* [arcade-docs](https://github.com/Shizmob/arcade-docs): An open (to read and contribute) repository
|
||||
of arcade hardware and software documentation
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
# BIO2 sub IO turntable bypass cable
|
||||
If you upgraded a C02 wired cabinet, the turntables are connected to the
|
||||
sub IO via a serial line that goes to another sub IO behind the front panel
|
||||
next to the 16seg display. This introduces additional latency as the input
|
||||
data needs to pass through multiple systems/PCBs until it reaches the game.
|
||||
|
||||
This can be reduced by using a so-called "bypass" cable, that connects the
|
||||
turntables directly to the BIO2 sub IO board by emulating the wiring of a
|
||||
D01 cabinet, reducing latency significantly.
|
||||
|
||||
This cable could be ordered with the IIDX Rootage upgrade kit but can also
|
||||
be easily created from scratch.
|
||||
|
||||
## Parts
|
||||
* Some wires
|
||||
* [JST HL](https://jst.de/file/download/219/pitch-3-96-mm-wtw-hl2-pdf) 2x4 pin female connector
|
||||
* [JST HVQ](https://jst.de/file/download/637/hvq) 8 pin female connector
|
||||
* Matching terminals for the connectors
|
||||
|
||||
## Pinout
|
||||
```text
|
||||
JST HL 2x4 pin front view connector
|
||||
|
||||
notch at top
|
||||
___
|
||||
|---------|
|
||||
| 1 2 3 4 |
|
||||
| 5 6 7 8 |
|
||||
|---------|
|
||||
```
|
||||
|
||||
```
|
||||
JST HVQ 8 pin front view connector
|
||||
Numbering on connector matches
|
||||
|
||||
notch at top
|
||||
___________________
|
||||
-------------------
|
||||
|-----------------|
|
||||
| 1 2 3 4 5 6 7 8 |
|
||||
|-----------------|
|
||||
|
||||
```
|
||||
|
||||
Pins of the two connectors need to be connected like this:
|
||||
| JST HL 2x4 pin | JST 8 pin |
|
||||
|----------------|-----------|
|
||||
| 1 | 1 |
|
||||
| 2 | 1 |
|
||||
| 3 | 3 |
|
||||
| 4 | 2 |
|
||||
| 5 | 5 |
|
||||
| 6 | 4 |
|
||||
| 7 | 8 |
|
||||
| 8 | 8 |
|
||||
@@ -1,51 +0,0 @@
|
||||
# Ezusb 1/2 RJ45 to DIN8 connector pinout
|
||||
This was created from using the BIO2 sub IO board to connect pre IIDX 25 cabinet hardware to the
|
||||
BIO2 IO board. The two connector types from different generation IO boards, RJ45 on the ezusb FX
|
||||
(C02) board and a round DIN8 connector on the ezusb FX2 (IO2) board are just different connectors to
|
||||
the same hardware on the PCB.
|
||||
|
||||
Therefore, any C02 wired cabinet can be easily upgraded to IO2 wiring and vice versa by building
|
||||
a simple RJ45 -> DIN8 or DIN8 -> RJ45 adapter.
|
||||
|
||||
The following connection information was traced on a original Konami BIO2 sub IO board.
|
||||
|
||||
RJ45 (female) connector, top view:
|
||||
```text
|
||||
plug insert
|
||||
|
|
||||
|
|
||||
v
|
||||
|-----------|
|
||||
| Top view |
|
||||
| |
|
||||
| Pins |
|
||||
| 7 5 3 1 |
|
||||
| 8 6 4 2 |
|
||||
|-----------|
|
||||
```
|
||||
|
||||
DIN8 (female) connector, top view:
|
||||
```text
|
||||
plug insert
|
||||
|
|
||||
|
|
||||
v
|
||||
|-----------|
|
||||
| Top view |
|
||||
| Pins |
|
||||
| 3 1 2 6 |
|
||||
| 7 4 5 8 9 |
|
||||
|-----------|
|
||||
```
|
||||
|
||||
The two connectors are interconnected on the PCB like this:
|
||||
| RJ45 pins | DIN8 pins |
|
||||
|-----------|-----------|
|
||||
| 1 | 1 |
|
||||
| 2 | 7 |
|
||||
| 3 | 4 |
|
||||
| 4 | 6 |
|
||||
| 5 | 5 |
|
||||
| 6 | 3 |
|
||||
| 7 | 2 |
|
||||
| 8 | 1 |
|
||||
@@ -23,14 +23,14 @@ games:
|
||||
* [iidxhook8](iidxhook8.md): CANNON BALLERS, Rootage
|
||||
* [iidxhook8](iidxhook9.md): Heroic Verse
|
||||
|
||||
When building kactools, independent packages are created for each set of games
|
||||
When building bemanitools, independent packages are created for each set of games
|
||||
which are ready to be dropped on top of vanilla AC data dumps. We recommend
|
||||
using prestine dumps to avoid any conflicts with other hardcoded hacks or
|
||||
using pristine dumps to avoid any conflicts with other hardcoded hacks or
|
||||
binary patches.
|
||||
|
||||
## How to run
|
||||
To run your game with iidxhook, you have to use the inject tool to inject the
|
||||
DLL to the game process. *dist/iidx* contains bat scripts with all the
|
||||
DLL to the game process. `dist/iidx` contains bat scripts with all the
|
||||
important parameters configured. Further parameters can be added but might not
|
||||
be required to run the game with default settings.
|
||||
Further information on how to setup the data for each specific version are
|
||||
@@ -47,4 +47,4 @@ IO hardware you want to use:
|
||||
game controllers
|
||||
* [iidxio-bio2](iidxhook/iidxio-bio2.md): Support BIO2 hardware
|
||||
* [iidxio-ezusb](iidxhook/iidxio-ezusb.md): Support C02 ezusb FX hardware
|
||||
* [iidxio-ezusb2](iidxhook/iidxio-ezusb2.md): Support IO2 ezusb FX2 hardware
|
||||
* [iidxio-ezusb2](iidxhook/iidxio-ezusb2.md): Support IO2 ezusb FX2 hardware
|
||||
|
||||
@@ -57,6 +57,12 @@ If you want to run the games online, you have to set a valid PCBID and EAMID
|
||||
argument. You also have to set the url of the eamuse server you want to
|
||||
connect to.
|
||||
|
||||
Additional note regarding EAMID: This is new compared to the prior games and
|
||||
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](#network-warning-instead-of-network-ok).
|
||||
|
||||
Run the game with the gamestart-XX.bat file and enable network on the operator
|
||||
menu. When enabled, the game seems to hang and expects you to power
|
||||
cycle the machine (i.e. quit the game and restart it).
|
||||
@@ -134,7 +140,7 @@ value to cut down start-up times.
|
||||
|
||||
## "NETWORK WARNING" instead of "NETWORK OK"
|
||||
This can be caused by:
|
||||
* Invalid PCBID
|
||||
* Invalid PCBID/EAMID: Ensure both are [set to the same ID](#eamuse-network-setup)
|
||||
* Firewall blocking connections
|
||||
* Invalid eamuse url or port specified
|
||||
* Game is not run using the Administrator account
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
The following games are compatible with this version of iidxhook:
|
||||
* Heroic Verse
|
||||
* BISTROVER
|
||||
|
||||
The games must be bootstrapped using [launcher](../launcher.md).
|
||||
|
||||
|
||||
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.
|
||||
28
scripts/ci/create-release-message.sh
Executable file
28
scripts/ci/create-release-message.sh
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
|
||||
VERSION="$1"
|
||||
|
||||
section_active=""
|
||||
changelog_excerpt=""
|
||||
|
||||
while IFS= read -r line; do
|
||||
if [ "$section_active" ]; then
|
||||
if [[ "$(echo "$line" | grep '^#')" ]]; then
|
||||
section_active=""
|
||||
else
|
||||
changelog_excerpt="$(printf "%s\n%s" "$changelog_excerpt" "$line")"
|
||||
fi
|
||||
else
|
||||
if [ "$line" = "## $VERSION" ]; then
|
||||
section_active="1"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$changelog_excerpt" ]; then
|
||||
printf "%s" "$changelog_excerpt"
|
||||
exit 0
|
||||
else
|
||||
>&2 echo "Could not find version in changelog: $VERSION"
|
||||
exit 1
|
||||
fi
|
||||
@@ -46,6 +46,12 @@ struct property_node;
|
||||
struct avs_net_interface {
|
||||
uint8_t mac_addr[6];
|
||||
uint8_t unknown[30];
|
||||
#if AVS_VERSION >= 1603
|
||||
uint8_t unknown2[6];
|
||||
#endif
|
||||
#if AVS_VERSION >= 1700
|
||||
uint8_t unknown3[6];
|
||||
#endif
|
||||
};
|
||||
|
||||
enum psmap_type {
|
||||
|
||||
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
|
||||
@@ -9,7 +9,9 @@
|
||||
#include "acio/hdxs.h"
|
||||
#include "acio/icca.h"
|
||||
#include "acio/kfca.h"
|
||||
#include "acio/mdxf.h"
|
||||
#include "acio/panb.h"
|
||||
#include "acio/rvol.h"
|
||||
|
||||
#define AC_IO_SOF 0xAA
|
||||
#define AC_IO_ESCAPE 0xFF
|
||||
@@ -37,9 +39,11 @@ enum ac_io_node_type {
|
||||
AC_IO_NODE_TYPE_LED_STRIP = 0x04020000,
|
||||
AC_IO_NODE_TYPE_LED_SPIKE = 0x05010000,
|
||||
AC_IO_NODE_TYPE_KFCA = 0x09060000,
|
||||
AC_IO_NODE_TYPE_BI2A = 0x0d060000,
|
||||
AC_IO_NODE_TYPE_RVOL = 0x09060001,
|
||||
AC_IO_NODE_TYPE_MDXF = 0x09070000,
|
||||
AC_IO_NODE_TYPE_PANB = 0x090E0000,
|
||||
AC_IO_NODE_TYPE_BMPU = 0x0B000000,
|
||||
AC_IO_NODE_TYPE_BI2A = 0x0D060000,
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
@@ -84,6 +88,12 @@ struct ac_io_message {
|
||||
struct ac_io_panb_poll_out panb_poll_out;
|
||||
|
||||
struct ac_io_hdxs_output hdxs_output;
|
||||
|
||||
struct ac_io_rvol_poll_in rvol_poll_in;
|
||||
struct ac_io_rvol_poll_out rvol_poll_out;
|
||||
|
||||
struct ac_io_mdxf_poll_in mdxf_poll_in;
|
||||
struct ac_io_mdxf_light_out mdxf_light_out;
|
||||
};
|
||||
} cmd;
|
||||
|
||||
|
||||
@@ -4,13 +4,15 @@
|
||||
#include <stdint.h>
|
||||
|
||||
enum ac_io_icca_cmd {
|
||||
/* found on jubeat, sent right after queue loop start */
|
||||
AC_IO_ICCA_CMD_UNKN_0116 = 0x0116,
|
||||
/* Yet unknown command encountered first on jubeat (1) */
|
||||
AC_IO_ICCA_CMD_UNKN_0120 = 0x0120,
|
||||
AC_IO_ICCA_CMD_QUEUE_LOOP_START = 0x0130,
|
||||
AC_IO_ICCA_CMD_ENGAGE = 0x0131,
|
||||
AC_IO_ICCA_CMD_POLL = 0x0134,
|
||||
AC_IO_ICCA_CMD_SET_SLOT_STATE = 0x0135,
|
||||
AC_IO_ICCA_CMD_BEGIN_KEYPAD = 0x013A,
|
||||
AC_IO_ICCA_CMD_DEVICE_CONTROL = 0x013A,
|
||||
AC_IO_ICCA_CMD_POLL_FELICA = 0x0161,
|
||||
AC_IO_ICCA_CMD_KEY_EXCHANGE = 0x0160,
|
||||
AC_IO_ICCA_CMD_POLL_ENCRYPTED = 0x0164,
|
||||
|
||||
@@ -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
|
||||
49
src/main/acio/mdxf.h
Normal file
49
src/main/acio/mdxf.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef AC_IO_MDXF_H
|
||||
#define AC_IO_MDXF_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define AC_IO_CMD_MDXF_POLL 0x0110
|
||||
#define AC_IO_CMD_MDXF_AUTO_GET_START 0x0116
|
||||
#define AC_IO_CMD_MDXF_LIGHT 0x0113
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
union mdxf_panel_sensors_individual {
|
||||
struct {
|
||||
uint8_t right : 1;
|
||||
uint8_t left : 1;
|
||||
uint8_t down : 1;
|
||||
uint8_t up : 1;
|
||||
uint8_t unused : 4;
|
||||
};
|
||||
uint8_t raw;
|
||||
};
|
||||
|
||||
struct mdxf_panel_sensors {
|
||||
uint8_t down : 4;
|
||||
uint8_t up : 4;
|
||||
uint8_t right : 4;
|
||||
uint8_t left : 4;
|
||||
};
|
||||
|
||||
struct ac_io_mdxf_poll_in {
|
||||
struct mdxf_panel_sensors panel;
|
||||
uint8_t unk;
|
||||
};
|
||||
|
||||
struct mdxf_lights {
|
||||
uint8_t up_right;
|
||||
uint8_t down_left;
|
||||
uint8_t up_left;
|
||||
uint8_t down_right;
|
||||
uint8_t unk;
|
||||
};
|
||||
|
||||
struct ac_io_mdxf_light_out {
|
||||
struct mdxf_lights side[2];
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
74
src/main/acio/rvol.h
Normal file
74
src/main/acio/rvol.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#ifndef AC_IO_RVOL_H
|
||||
#define AC_IO_RVOL_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// technically RVOL also can poll with CMD 0x0113
|
||||
// but museca never uses this (it's controlled by if the watchdog is on/off)
|
||||
#define AC_IO_CMD_RVOL_POLL 0x0112
|
||||
#define AC_IO_CMD_RVOL_SET_EXPAND_MODE 0x0114
|
||||
#define AC_IO_CMD_RVOL_AMP_CONTROL 0x0128
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct ac_io_rvol_buttons_1 {
|
||||
uint8_t unk0 : 1;
|
||||
uint8_t unk1 : 1;
|
||||
uint8_t spinner_4 : 1;
|
||||
uint8_t pedal : 1;
|
||||
uint8_t spinner_5 : 1;
|
||||
uint8_t unk5 : 1;
|
||||
uint8_t unk6 : 1;
|
||||
uint8_t unk7 : 1;
|
||||
};
|
||||
|
||||
struct ac_io_rvol_buttons_2 {
|
||||
uint8_t spinner_2 : 1;
|
||||
uint8_t unk1 : 1;
|
||||
uint8_t unk2 : 1;
|
||||
uint8_t spinner_1 : 1;
|
||||
uint8_t unk4 : 1;
|
||||
uint8_t unk5 : 1;
|
||||
uint8_t unk6 : 1;
|
||||
uint8_t unk7 : 1;
|
||||
};
|
||||
|
||||
struct ac_io_rvol_buttons_3 {
|
||||
uint8_t unk0 : 1;
|
||||
uint8_t unk1 : 1;
|
||||
uint8_t unk2 : 1;
|
||||
uint8_t spinner_3 : 1;
|
||||
uint8_t unk4 : 1;
|
||||
uint8_t unk5 : 1;
|
||||
uint8_t unk6 : 1;
|
||||
uint8_t unk7 : 1;
|
||||
};
|
||||
|
||||
struct ac_io_rvol_poll_in {
|
||||
uint8_t unk_0;
|
||||
struct ac_io_rvol_buttons_1 buttons_1;
|
||||
uint8_t unk_2_8[7];
|
||||
struct ac_io_rvol_buttons_2 buttons_2;
|
||||
uint8_t unk_10;
|
||||
struct ac_io_rvol_buttons_3 buttons_3;
|
||||
uint8_t unk_12_15[4];
|
||||
uint8_t spinners[5];
|
||||
uint8_t unk_21_22[2];
|
||||
};
|
||||
|
||||
struct light_rgb {
|
||||
uint8_t r;
|
||||
uint8_t g;
|
||||
uint8_t b;
|
||||
};
|
||||
|
||||
struct ac_io_rvol_poll_out {
|
||||
uint8_t unk0_3[4];
|
||||
struct light_rgb spinner[5];
|
||||
struct light_rgb title;
|
||||
uint8_t unk22_31[10];
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
@@ -8,5 +8,6 @@ src_aciodrv := \
|
||||
icca.c \
|
||||
kfca.c \
|
||||
panb.c \
|
||||
rvol.c \
|
||||
port.c \
|
||||
|
||||
|
||||
@@ -300,6 +300,7 @@ static bool aciodrv_device_get_version(struct aciodrv_device_ctx *device, uint8_
|
||||
msg.cmd.version.time);
|
||||
|
||||
memcpy(version->product, msg.cmd.version.product_code, ACIO_NODE_PRODUCT_CODE_LEN);
|
||||
version->type = ac_io_u32(msg.cmd.version.type);
|
||||
version->major = msg.cmd.version.major;
|
||||
version->minor = msg.cmd.version.minor;
|
||||
version->revision = msg.cmd.version.revision;
|
||||
@@ -392,6 +393,14 @@ bool aciodrv_device_get_node_product_ident(struct aciodrv_device_ctx *device, ui
|
||||
memcpy(product, device->node_versions[node_id].product, ACIO_NODE_PRODUCT_CODE_LEN);
|
||||
return true;
|
||||
}
|
||||
uint32_t aciodrv_device_get_node_product_type(struct aciodrv_device_ctx *device, uint8_t node_id)
|
||||
{
|
||||
if (device->node_count == 0 || node_id > device->node_count) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return device->node_versions[node_id].type;
|
||||
}
|
||||
|
||||
const struct aciodrv_device_node_version *aciodrv_device_get_node_product_version(struct aciodrv_device_ctx *device, uint8_t node_id)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,7 @@ struct aciodrv_device_ctx;
|
||||
|
||||
struct aciodrv_device_node_version {
|
||||
char product[ACIO_NODE_PRODUCT_CODE_LEN];
|
||||
uint32_t type;
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
uint8_t revision;
|
||||
@@ -52,6 +53,15 @@ uint8_t aciodrv_device_get_node_count(struct aciodrv_device_ctx *device);
|
||||
*/
|
||||
bool aciodrv_device_get_node_product_ident(struct aciodrv_device_ctx *device, uint8_t node_id, char product[ACIO_NODE_PRODUCT_CODE_LEN]);
|
||||
|
||||
/**
|
||||
* Get the product identifier of an enumerated node.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node. Needs to be in range of the total node count.
|
||||
* @return product type ID on success, or 0 on failure
|
||||
*/
|
||||
uint32_t aciodrv_device_get_node_product_type(struct aciodrv_device_ctx *device, uint8_t node_id);
|
||||
|
||||
/**
|
||||
* Get the product version of an enumerated node.
|
||||
*
|
||||
|
||||
80
src/main/aciodrv/rvol.c
Normal file
80
src/main/aciodrv/rvol.c
Normal file
@@ -0,0 +1,80 @@
|
||||
#define LOG_MODULE "aciodrv-rvol"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aciodrv/device.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
static bool aciodrv_rvol_change_expand_mode(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
uint8_t mode)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
log_assert(device);
|
||||
|
||||
msg.addr = node_id + 1;
|
||||
msg.cmd.code = ac_io_u16(AC_IO_CMD_RVOL_SET_EXPAND_MODE);
|
||||
msg.cmd.nbytes = 1;
|
||||
|
||||
msg.cmd.raw[0] = (mode | (2 * mode)) << 6;
|
||||
|
||||
if (!aciodrv_send_and_recv(
|
||||
device, &msg, offsetof(struct ac_io_message, cmd.raw) + 1)) {
|
||||
log_warning("RVOL change expand mode failed %d", node_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
log_info("I/O expand mode set %d, mode: %d",
|
||||
node_id, mode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aciodrv_rvol_init(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id)
|
||||
{
|
||||
log_assert(device);
|
||||
|
||||
if (!aciodrv_rvol_change_expand_mode(device, node_id, 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aciodrv_rvol_poll(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
const struct ac_io_rvol_poll_out *pout,
|
||||
struct ac_io_rvol_poll_in *pin)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
log_assert(device);
|
||||
log_assert(pout);
|
||||
|
||||
msg.addr = node_id + 1;
|
||||
msg.cmd.code = ac_io_u16(AC_IO_CMD_RVOL_POLL);
|
||||
msg.cmd.nbytes = sizeof(*pout);
|
||||
/* buffer size of data we expect */
|
||||
msg.cmd.rvol_poll_out = *pout;
|
||||
|
||||
if (!aciodrv_send_and_recv(
|
||||
device,
|
||||
&msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) + sizeof(*pin))) {
|
||||
log_warning("Polling of node %d failed", node_id + 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pin != NULL) {
|
||||
memcpy(pin, &msg.cmd.rvol_poll_in, sizeof(*pin));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
36
src/main/aciodrv/rvol.h
Normal file
36
src/main/aciodrv/rvol.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef ACIODRV_RVOL_H
|
||||
#define ACIODRV_RVOL_H
|
||||
|
||||
#include "acio/rvol.h"
|
||||
|
||||
/**
|
||||
* Initialize a Revolte (KFCA 1.5) IO board
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node to initialize (0 based).
|
||||
* @return True if successful, false on error.
|
||||
* @note This module is supposed to be used in combination with the common
|
||||
* device driver foundation.
|
||||
* @see driver.h
|
||||
*/
|
||||
bool aciodrv_rvol_init(struct aciodrv_device_ctx *device, uint8_t node_id);
|
||||
|
||||
/**
|
||||
* Poll a Revolte (KFCA 1.5) IO board
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node to query (0 based).
|
||||
* @param pout Pointer to a state struct to write to device
|
||||
* @param pin Pointer to a state struct to return the current state to
|
||||
* @return True on success, false on error.
|
||||
* @note This module is supposed to be used in combination with the common
|
||||
* device driver foundation.
|
||||
* @see driver.h
|
||||
*/
|
||||
bool aciodrv_rvol_poll(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
const struct ac_io_rvol_poll_out *pout,
|
||||
struct ac_io_rvol_poll_in *pin);
|
||||
|
||||
#endif
|
||||
@@ -6,6 +6,5 @@ src_acioemu := \
|
||||
h44b.c \
|
||||
hdxs.c \
|
||||
icca.c \
|
||||
iccb.c \
|
||||
pipe.c \
|
||||
|
||||
|
||||
@@ -63,6 +63,8 @@ void ac_io_emu_icca_init(
|
||||
|
||||
// default to 1.6.0
|
||||
icca->version = v160;
|
||||
// default, most common code
|
||||
ac_io_emu_icca_set_product_code(icca, AC_IO_EMU_PROD_CODE_ICCA);
|
||||
}
|
||||
|
||||
void ac_io_emu_icca_set_version(
|
||||
@@ -71,6 +73,12 @@ void ac_io_emu_icca_set_version(
|
||||
icca->version = version;
|
||||
}
|
||||
|
||||
void ac_io_emu_icca_set_product_code(
|
||||
struct ac_io_emu_icca *icca, const char product_code[4])
|
||||
{
|
||||
memcpy(icca->product_code, product_code, sizeof(icca->product_code));
|
||||
}
|
||||
|
||||
void ac_io_emu_icca_dispatch_request(
|
||||
struct ac_io_emu_icca *icca, const struct ac_io_message *req)
|
||||
{
|
||||
@@ -119,14 +127,15 @@ void ac_io_emu_icca_dispatch_request(
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCA_CMD_UNKN_0116:
|
||||
case AC_IO_ICCA_CMD_UNKN_0120:
|
||||
log_misc("AC_IO_ICCA_CMD_UNKN_0120(%d)", req->addr);
|
||||
log_misc("AC_IO_ICCA_CMD_UNK_%04X(%d)", cmd_code, req->addr);
|
||||
ac_io_emu_icca_send_status(icca, req, 0x00);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCA_CMD_BEGIN_KEYPAD:
|
||||
log_misc("AC_IO_ICCA_CMD_BEGIN_KEYPAD(%d)", req->addr);
|
||||
case AC_IO_ICCA_CMD_DEVICE_CONTROL:
|
||||
log_misc("AC_IO_ICCA_CMD_DEVICE_CONTROL(%d)", req->addr);
|
||||
ac_io_emu_icca_send_status(icca, req, 0x00);
|
||||
icca->keypad_started = true;
|
||||
|
||||
@@ -138,48 +147,52 @@ void ac_io_emu_icca_dispatch_request(
|
||||
break;
|
||||
|
||||
case AC_IO_ICCA_CMD_SET_SLOT_STATE: {
|
||||
struct ac_io_icca_misc *misc =
|
||||
(struct ac_io_icca_misc *) &req->cmd.raw;
|
||||
uint8_t cmd;
|
||||
if(icca->version == v150) {
|
||||
ac_io_emu_icca_send_state(icca, req, 0, false);
|
||||
} else {
|
||||
struct ac_io_icca_misc *misc =
|
||||
(struct ac_io_icca_misc *) &req->cmd.raw;
|
||||
uint8_t cmd;
|
||||
|
||||
switch (misc->subcmd) {
|
||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_CLOSE:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_CLOSE;
|
||||
break;
|
||||
switch (misc->subcmd) {
|
||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_CLOSE:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_CLOSE;
|
||||
break;
|
||||
|
||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_OPEN:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_OPEN;
|
||||
break;
|
||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_OPEN:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_OPEN;
|
||||
break;
|
||||
|
||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_EJECT:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_EJECT;
|
||||
icca->engaged = false;
|
||||
break;
|
||||
case AC_IO_ICCA_SUBCMD_CARD_SLOT_EJECT:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_EJECT;
|
||||
icca->engaged = false;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_READ;
|
||||
break;
|
||||
case 3:
|
||||
cmd = EAM_IO_CARD_SLOT_CMD_READ;
|
||||
break;
|
||||
|
||||
default:
|
||||
cmd = 0xFF;
|
||||
log_warning(
|
||||
"Unhandled slot command %X, node %d",
|
||||
misc->subcmd,
|
||||
icca->unit_no);
|
||||
break;
|
||||
}
|
||||
|
||||
if (cmd != 0xFF) {
|
||||
if (!eam_io_card_slot_cmd(icca->unit_no, cmd)) {
|
||||
log_warning(
|
||||
"Eamio failed to handle slot cmd %d for node %d",
|
||||
cmd,
|
||||
icca->unit_no);
|
||||
default:
|
||||
cmd = 0xFF;
|
||||
log_warning(
|
||||
"Unhandled slot command %X, node %d",
|
||||
misc->subcmd,
|
||||
icca->unit_no);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* response with current slot state */
|
||||
ac_io_emu_icca_send_status(icca, req, misc->subcmd);
|
||||
if (cmd != 0xFF) {
|
||||
if (!eam_io_card_slot_cmd(icca->unit_no, cmd)) {
|
||||
log_warning(
|
||||
"Eamio failed to handle slot cmd %d for node %d",
|
||||
cmd,
|
||||
icca->unit_no);
|
||||
}
|
||||
}
|
||||
|
||||
/* response with current slot state */
|
||||
ac_io_emu_icca_send_status(icca, req, misc->subcmd);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -202,12 +215,14 @@ void ac_io_emu_icca_dispatch_request(
|
||||
break;
|
||||
|
||||
case AC_IO_ICCA_CMD_POLL_FELICA:
|
||||
icca->detected_new_reader = true;
|
||||
|
||||
if (icca->version == v170) {
|
||||
if (icca->version == v150) {
|
||||
ac_io_emu_icca_send_state(icca, req, 0, false);
|
||||
} else if (icca->version == v170) {
|
||||
ac_io_emu_icca_send_empty(icca, req);
|
||||
icca->detected_new_reader = true;
|
||||
} else {
|
||||
ac_io_emu_icca_send_status(icca, req, 0x01);
|
||||
icca->detected_new_reader = true;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -244,8 +259,6 @@ static void ac_io_emu_icca_cmd_send_version(
|
||||
resp.cmd.version.major = 0x01;
|
||||
|
||||
if (icca->version == v150) {
|
||||
log_warning(
|
||||
"ICCA v1.5.0 emulation requested, please remove this log once implemented");
|
||||
resp.cmd.version.minor = 0x05;
|
||||
} else if (icca->version == v160) {
|
||||
resp.cmd.version.minor = 0x06;
|
||||
@@ -262,7 +275,7 @@ static void ac_io_emu_icca_cmd_send_version(
|
||||
|
||||
memcpy(
|
||||
resp.cmd.version.product_code,
|
||||
"ICCA",
|
||||
icca->product_code,
|
||||
sizeof(resp.cmd.version.product_code));
|
||||
strncpy(resp.cmd.version.date, __DATE__, sizeof(resp.cmd.version.date));
|
||||
strncpy(resp.cmd.version.time, __TIME__, sizeof(resp.cmd.version.time));
|
||||
|
||||
@@ -12,6 +12,11 @@ enum ac_io_emu_icca_version {
|
||||
v170 = 0x7,
|
||||
};
|
||||
|
||||
// ICC product types for ac_io_emu_icca_set_product_code
|
||||
#define AC_IO_EMU_PROD_CODE_ICCA "ICCA"
|
||||
#define AC_IO_EMU_PROD_CODE_ICCB "ICCB"
|
||||
#define AC_IO_EMU_PROD_CODE_ICCC "ICCC"
|
||||
|
||||
struct ac_io_emu_icca {
|
||||
struct ac_io_emu *emu;
|
||||
uint8_t unit_no;
|
||||
@@ -28,6 +33,7 @@ struct ac_io_emu_icca {
|
||||
uint64_t time_counter_last_poll;
|
||||
|
||||
enum ac_io_emu_icca_version version;
|
||||
char product_code[4];
|
||||
bool cipher_started;
|
||||
uint32_t cipher_keys[4];
|
||||
};
|
||||
@@ -39,6 +45,12 @@ void ac_io_emu_icca_init(
|
||||
void ac_io_emu_icca_set_version(
|
||||
struct ac_io_emu_icca *icca, enum ac_io_emu_icca_version version);
|
||||
|
||||
// optional, call after init to override default "ICCA" product code.
|
||||
// Some games may refuse to boot or expect a different packet format when using
|
||||
// one of the alternative codes such as ICCB or ICCC
|
||||
void ac_io_emu_icca_set_product_code(
|
||||
struct ac_io_emu_icca *icca, const char product_code[4]);
|
||||
|
||||
void ac_io_emu_icca_dispatch_request(
|
||||
struct ac_io_emu_icca *icca, const struct ac_io_message *req);
|
||||
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
#define LOG_MODULE "acioemu-iccb"
|
||||
|
||||
#include "acioemu/iccb.h"
|
||||
|
||||
#include <windows.h> /* for _BitScanForward */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "acio/iccb.h"
|
||||
|
||||
#include "acioemu/emu.h"
|
||||
|
||||
#include "bemanitools/eamio.h"
|
||||
|
||||
static void ac_io_emu_iccb_cmd_send_version(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req);
|
||||
|
||||
static void ac_io_emu_iccb_send_state(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req);
|
||||
|
||||
static void ac_io_emu_iccb_send_empty(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req);
|
||||
|
||||
static void ac_io_emu_iccb_send_status(
|
||||
struct ac_io_emu_iccb *iccb,
|
||||
const struct ac_io_message *req,
|
||||
uint8_t status);
|
||||
|
||||
void ac_io_emu_iccb_init(
|
||||
struct ac_io_emu_iccb *iccb, struct ac_io_emu *emu, uint8_t unit_no)
|
||||
{
|
||||
memset(iccb, 0, sizeof(*iccb));
|
||||
iccb->emu = emu;
|
||||
iccb->unit_no = unit_no;
|
||||
}
|
||||
|
||||
void ac_io_emu_iccb_dispatch_request(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req)
|
||||
{
|
||||
uint16_t cmd_code;
|
||||
|
||||
cmd_code = ac_io_u16(req->cmd.code);
|
||||
|
||||
switch (cmd_code) {
|
||||
case AC_IO_CMD_GET_VERSION:
|
||||
log_misc("AC_IO_CMD_GET_VERSION(%d)", req->addr);
|
||||
ac_io_emu_iccb_cmd_send_version(iccb, req);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_CMD_START_UP:
|
||||
log_misc("AC_IO_CMD_START_UP(%d)", req->addr);
|
||||
ac_io_emu_iccb_send_status(iccb, req, 0x00);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_CMD_KEEPALIVE:
|
||||
ac_io_emu_iccb_send_empty(iccb, req);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCB_CMD_QUEUE_LOOP_START:
|
||||
log_misc("AC_IO_CMD_QUEUE_LOOP_START(%d)", req->addr);
|
||||
ac_io_emu_iccb_send_status(iccb, req, 0x00);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCB_CMD_UNK_0100:
|
||||
case AC_IO_ICCB_CMD_UNK_0116:
|
||||
case AC_IO_ICCB_CMD_UNK_0120:
|
||||
log_misc("AC_IO_ICCB_CMD_UNK_%04X(%d)", cmd_code, req->addr);
|
||||
ac_io_emu_iccb_send_status(iccb, req, 0x00);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCB_CMD_SLEEP:
|
||||
ac_io_emu_iccb_send_status(iccb, req, 0x00);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCB_CMD_UNK_135:
|
||||
/* log_misc("AC_IO_ICCB_CMD_UNK_135"); */
|
||||
ac_io_emu_iccb_send_state(iccb, req);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCB_CMD_POLL:
|
||||
/* log_misc("AC_IO_ICCB_CMD_POLL"); */
|
||||
ac_io_emu_iccb_send_state(iccb, req);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCB_CMD_READ_CARD:
|
||||
/* log_misc("AC_IO_ICCB_CMD_READ_CARD"); */
|
||||
ac_io_emu_iccb_send_state(iccb, req);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
log_warning(
|
||||
"Unknown ACIO message %04x on ICCB node, addr=%d",
|
||||
cmd_code,
|
||||
req->addr);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ac_io_emu_iccb_cmd_send_version(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req)
|
||||
{
|
||||
struct ac_io_message resp;
|
||||
|
||||
resp.addr = req->addr | AC_IO_RESPONSE_FLAG;
|
||||
resp.cmd.code = req->cmd.code;
|
||||
resp.cmd.seq_no = req->cmd.seq_no;
|
||||
resp.cmd.nbytes = sizeof(resp.cmd.version);
|
||||
resp.cmd.version.type = ac_io_u32(AC_IO_NODE_TYPE_ICCB);
|
||||
resp.cmd.version.flag = 0x00;
|
||||
resp.cmd.version.major = 0x01;
|
||||
resp.cmd.version.minor = 0x05;
|
||||
resp.cmd.version.revision = 0x01;
|
||||
memcpy(
|
||||
resp.cmd.version.product_code,
|
||||
"ICCB",
|
||||
sizeof(resp.cmd.version.product_code));
|
||||
strncpy(resp.cmd.version.date, __DATE__, sizeof(resp.cmd.version.date));
|
||||
strncpy(resp.cmd.version.time, __TIME__, sizeof(resp.cmd.version.time));
|
||||
|
||||
ac_io_emu_response_push(iccb->emu, &resp, 0);
|
||||
}
|
||||
|
||||
static void ac_io_emu_iccb_send_empty(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req)
|
||||
{
|
||||
struct ac_io_message resp;
|
||||
|
||||
resp.addr = req->addr | AC_IO_RESPONSE_FLAG;
|
||||
resp.cmd.code = req->cmd.code;
|
||||
resp.cmd.seq_no = req->cmd.seq_no;
|
||||
resp.cmd.nbytes = 0;
|
||||
|
||||
ac_io_emu_response_push(iccb->emu, &resp, 0);
|
||||
}
|
||||
|
||||
static void ac_io_emu_iccb_send_status(
|
||||
struct ac_io_emu_iccb *iccb,
|
||||
const struct ac_io_message *req,
|
||||
uint8_t status)
|
||||
{
|
||||
struct ac_io_message resp;
|
||||
|
||||
resp.addr = req->addr | AC_IO_RESPONSE_FLAG;
|
||||
resp.cmd.code = req->cmd.code;
|
||||
resp.cmd.seq_no = req->cmd.seq_no;
|
||||
resp.cmd.nbytes = sizeof(resp.cmd.status);
|
||||
resp.cmd.status = status;
|
||||
|
||||
ac_io_emu_response_push(iccb->emu, &resp, 0);
|
||||
}
|
||||
|
||||
static void ac_io_emu_iccb_send_state(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req)
|
||||
{
|
||||
struct ac_io_message resp;
|
||||
struct ac_io_iccb_state *body;
|
||||
bool sensor;
|
||||
|
||||
/* state update */
|
||||
|
||||
if (!eam_io_poll(iccb->unit_no)) {
|
||||
log_warning("Polling eamio failed");
|
||||
}
|
||||
|
||||
sensor = eam_io_get_sensor_state(iccb->unit_no);
|
||||
|
||||
if (sensor != iccb->last_sensor) {
|
||||
if (sensor) {
|
||||
iccb->card_result =
|
||||
eam_io_read_card(iccb->unit_no, iccb->uid, sizeof(iccb->uid));
|
||||
|
||||
// fault if sensor says to read but we got no card
|
||||
iccb->fault = (iccb->card_result == EAM_IO_CARD_NONE);
|
||||
} else {
|
||||
iccb->fault = false;
|
||||
}
|
||||
}
|
||||
|
||||
iccb->last_sensor = sensor;
|
||||
|
||||
if (iccb->fault) {
|
||||
memset(iccb->uid, 0, sizeof(iccb->uid));
|
||||
}
|
||||
|
||||
/* create response */
|
||||
|
||||
resp.addr = req->addr | AC_IO_RESPONSE_FLAG;
|
||||
resp.cmd.code = req->cmd.code;
|
||||
resp.cmd.seq_no = req->cmd.seq_no;
|
||||
resp.cmd.nbytes = sizeof(struct ac_io_iccb_state);
|
||||
|
||||
body = (struct ac_io_iccb_state *) &resp.cmd.raw;
|
||||
|
||||
if (sensor) {
|
||||
body->sensor_state = AC_IO_ICCB_SENSOR_CARD;
|
||||
} else {
|
||||
body->sensor_state = AC_IO_ICCB_SENSOR_NO_CARD;
|
||||
}
|
||||
|
||||
if (!iccb->fault) {
|
||||
memcpy(body->uid, iccb->uid, sizeof(body->uid));
|
||||
}
|
||||
|
||||
body->card_type = 0x30 | (iccb->card_result - 1);
|
||||
body->unk2 = 0;
|
||||
// this doesn't seem to be an error code. If this is not set to 0x03
|
||||
// on slotted readers (only?), the game throws an unknown status error
|
||||
body->unk3 = 0x03;
|
||||
memset(body->unk4, 0, sizeof(body->unk4));
|
||||
|
||||
ac_io_emu_response_push(iccb->emu, &resp, 0);
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#ifndef AC_IO_EMU_ICCB_H
|
||||
#define AC_IO_EMU_ICCB_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "acioemu/emu.h"
|
||||
|
||||
struct ac_io_emu_iccb {
|
||||
struct ac_io_emu *emu;
|
||||
uint8_t unit_no;
|
||||
bool fault;
|
||||
bool last_sensor;
|
||||
uint8_t uid[8];
|
||||
uint8_t card_result;
|
||||
};
|
||||
|
||||
void ac_io_emu_iccb_init(
|
||||
struct ac_io_emu_iccb *iccb, struct ac_io_emu *emu, uint8_t unit_no);
|
||||
|
||||
void ac_io_emu_iccb_dispatch_request(
|
||||
struct ac_io_emu_iccb *iccb, const struct ac_io_message *req);
|
||||
|
||||
#endif
|
||||
@@ -9,6 +9,7 @@ libs_aciotest := \
|
||||
src_aciotest := \
|
||||
icca.c \
|
||||
kfca.c \
|
||||
bi2a-sdvx.c \
|
||||
panb.c \
|
||||
rvol.c \
|
||||
bi2a-sdvx.c \
|
||||
main.c \
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "aciotest/icca.h"
|
||||
#include "aciotest/kfca.h"
|
||||
#include "aciotest/panb.h"
|
||||
#include "aciotest/rvol.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
@@ -21,31 +22,37 @@ static uint8_t bi2a_mode = 0;
|
||||
* Enumerate supported ACIO nodes based on their product id.
|
||||
*/
|
||||
static bool aciotest_assign_handler(
|
||||
char product[4], struct aciotest_handler_node_handler *handler)
|
||||
uint32_t product_type, struct aciotest_handler_node_handler *handler)
|
||||
{
|
||||
if (!memcmp(product, "ICCA", 4) || !memcmp(product, "ICCB", 4) ||
|
||||
!memcmp(product, "ICCC", 4)) {
|
||||
if (product_type == AC_IO_NODE_TYPE_ICCA) {
|
||||
handler->init = aciotest_icca_handler_init;
|
||||
handler->update = aciotest_icca_handler_update;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!memcmp(product, "KFCA", 4)) {
|
||||
if (product_type == AC_IO_NODE_TYPE_KFCA) {
|
||||
handler->init = aciotest_kfca_handler_init;
|
||||
handler->update = aciotest_kfca_handler_update;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!memcmp(product, "PANB", 4)) {
|
||||
if (product_type == AC_IO_NODE_TYPE_PANB) {
|
||||
handler->init = aciotest_panb_handler_init;
|
||||
handler->update = aciotest_panb_handler_update;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!memcmp(product, "BI2A", 4)) {
|
||||
if (product_type == AC_IO_NODE_TYPE_RVOL) {
|
||||
handler->init = aciotest_rvol_handler_init;
|
||||
handler->update = aciotest_rvol_handler_update;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (product_type == AC_IO_NODE_TYPE_BI2A) {
|
||||
if (bi2a_mode == 0) {
|
||||
handler->init = aciotest_bi2a_sdvx_handler_init;
|
||||
handler->update = aciotest_bi2a_sdvx_handler_update;
|
||||
@@ -99,22 +106,22 @@ int main(int argc, char **argv)
|
||||
|
||||
for (uint8_t i = 0; i < node_count; i++) {
|
||||
char product[4];
|
||||
uint32_t product_type = aciodrv_device_get_node_product_type(device, i);
|
||||
aciodrv_device_get_node_product_ident(device, i, product);
|
||||
|
||||
printf(
|
||||
"> %d: %c%c%c%c\n",
|
||||
"> %d: %c%c%c%c (%08x)\n",
|
||||
i + 1,
|
||||
product[0],
|
||||
product[1],
|
||||
product[2],
|
||||
product[3]);
|
||||
product[3],
|
||||
product_type);
|
||||
|
||||
if (!aciotest_assign_handler(product, &handler[i])) {
|
||||
if (!aciotest_assign_handler(product_type, &handler[i])) {
|
||||
printf(
|
||||
"ERROR: Unsupported acio node product %c%c%c%c on node %d\n",
|
||||
product[0],
|
||||
product[1],
|
||||
product[2],
|
||||
product[3],
|
||||
"ERROR: Unsupported acio node product %08x on node %d\n",
|
||||
product_type,
|
||||
i);
|
||||
}
|
||||
}
|
||||
|
||||
73
src/main/aciotest/rvol.c
Normal file
73
src/main/aciotest/rvol.c
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "aciotest/rvol.h"
|
||||
|
||||
#include "acio/acio.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aciodrv/rvol.h"
|
||||
|
||||
static struct ac_io_rvol_poll_out pout;
|
||||
|
||||
bool aciotest_rvol_handler_init(
|
||||
struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx)
|
||||
{
|
||||
memset(&pout, 0, sizeof(pout));
|
||||
return aciodrv_rvol_init(device, node_id);
|
||||
}
|
||||
|
||||
bool aciotest_rvol_handler_update(
|
||||
struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx)
|
||||
{
|
||||
struct ac_io_rvol_poll_in pin;
|
||||
|
||||
if (!aciodrv_rvol_poll(device, node_id, &pout, &pin)) {
|
||||
return false;
|
||||
}
|
||||
uint8_t selected_light = pin.spinners[0] / 43;
|
||||
|
||||
printf(
|
||||
">>> RVOL %d\n"
|
||||
"Press: %3d %3d %3d\n"
|
||||
" %3d %3d\n"
|
||||
"\n"
|
||||
"Spin: %3d %3d %3d\n"
|
||||
" %3d %3d\n"
|
||||
"\n"
|
||||
"Pedal: %3d\n"
|
||||
"\n"
|
||||
"Editing light #%d R: %d G: %d B: %d\n"
|
||||
"(Change light with Spinner 1, values with 3-5)\n",
|
||||
node_id,
|
||||
pin.buttons_2.spinner_1,
|
||||
pin.buttons_3.spinner_3,
|
||||
pin.buttons_1.spinner_5,
|
||||
pin.buttons_2.spinner_2,
|
||||
pin.buttons_1.spinner_4,
|
||||
pin.spinners[0],
|
||||
pin.spinners[2],
|
||||
pin.spinners[4],
|
||||
pin.spinners[1],
|
||||
pin.spinners[3],
|
||||
!pin.buttons_1.pedal,
|
||||
selected_light,
|
||||
pin.spinners[2] / 2,
|
||||
pin.spinners[3] / 2,
|
||||
pin.spinners[4] / 2
|
||||
);
|
||||
|
||||
memset(&pout, 0, sizeof(pout));
|
||||
|
||||
if (selected_light == 5) {
|
||||
pout.title.r = pin.spinners[2] / 2;
|
||||
pout.title.g = pin.spinners[3] / 2;
|
||||
pout.title.b = pin.spinners[4] / 2;
|
||||
} else {
|
||||
pout.spinner[selected_light].r = pin.spinners[2] / 2;
|
||||
pout.spinner[selected_light].g = pin.spinners[3] / 2;
|
||||
pout.spinner[selected_light].b = pin.spinners[4] / 2;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
14
src/main/aciotest/rvol.h
Normal file
14
src/main/aciotest/rvol.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef ACIOTEST_RVOL_H
|
||||
#define ACIOTEST_RVOL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "aciodrv/device.h"
|
||||
|
||||
bool aciotest_rvol_handler_init(
|
||||
struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx);
|
||||
bool aciotest_rvol_handler_update(
|
||||
struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx);
|
||||
|
||||
#endif
|
||||
56
src/main/bio2/bi2a-ddr.h
Normal file
56
src/main/bio2/bi2a-ddr.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef BIO2_BI2A_DDR
|
||||
#define BIO2_BI2A_DDR
|
||||
|
||||
#include "bio2/bio2.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct bi2a_ddr_system_panel {
|
||||
uint8_t b_unk1 : 1;
|
||||
uint8_t b_coin : 1;
|
||||
uint8_t b_service : 1;
|
||||
uint8_t b_test : 1;
|
||||
uint8_t b_un2 : 4;
|
||||
};
|
||||
|
||||
struct bi2a_ddr_player_1_panel {
|
||||
uint8_t b_unk : 3;
|
||||
uint8_t b_right : 1;
|
||||
uint8_t b_left : 1;
|
||||
uint8_t b_down : 1;
|
||||
uint8_t b_up : 1;
|
||||
uint8_t b_start : 1;
|
||||
};
|
||||
|
||||
struct bi2a_ddr_player_2_panel {
|
||||
uint8_t b_unk1 : 1;
|
||||
uint8_t b_right : 1;
|
||||
uint8_t b_left : 1;
|
||||
uint8_t b_down : 1;
|
||||
uint8_t b_up : 1;
|
||||
uint8_t b_start : 1;
|
||||
uint8_t b_unk2 : 2;
|
||||
};
|
||||
|
||||
struct bi2a_ddr_state_in {
|
||||
uint8_t unk1;
|
||||
struct bi2a_ddr_system_panel system;
|
||||
uint8_t unk2[7];
|
||||
struct bi2a_ddr_player_1_panel player_1;
|
||||
struct bi2a_ddr_player_2_panel player_2;
|
||||
uint8_t unk3[5];
|
||||
};
|
||||
|
||||
struct bi2a_ddr_state_out {
|
||||
uint8_t unk1[40];
|
||||
};
|
||||
|
||||
_Static_assert(
|
||||
sizeof(struct bi2a_ddr_state_in) == 16,
|
||||
"bi2a_ddr_state_in is the wrong size");
|
||||
_Static_assert(
|
||||
sizeof(struct bi2a_ddr_state_out) == 40,
|
||||
"bi2a_ddr_state_out is the wrong size");
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
@@ -11,6 +11,11 @@ enum bio2_bi2a_cmd {
|
||||
BIO2_BI2A_CMD_INIT = 0x0100,
|
||||
BIO2_BI2A_CMD_WATCHDOG = 0x0120,
|
||||
BIO2_BI2A_CMD_POLL = 0x0152, // For IIDX
|
||||
// For games using libacio for BIO2 communication
|
||||
BIO2_BI2A_CMD_ACIO_POLL_NOWD = 0x0112,
|
||||
BIO2_BI2A_CMD_ACIO_POLL_WD = 0x0113,
|
||||
BIO2_BI2A_CMD_TAPELED_INIT = 0x0140,
|
||||
BIO2_BI2A_CMD_TAPELED_SEND = 0x0141,
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -52,7 +52,7 @@ void d3d9exhook_config_gfx_init(struct cconfig *config)
|
||||
config,
|
||||
D3D9EXHOOK_CONFIG_GFX_CONFINED_KEY,
|
||||
D3D9EXHOOK_CONFIG_GFX_DEFAULT_CONFINED_VALUE,
|
||||
"Confine mouse coursor to window");
|
||||
"Confine mouse cursor to window");
|
||||
|
||||
cconfig_util_set_int(
|
||||
config,
|
||||
|
||||
13
src/main/ddrhook-util/Module.mk
Normal file
13
src/main/ddrhook-util/Module.mk
Normal file
@@ -0,0 +1,13 @@
|
||||
libs += ddrhook-util
|
||||
|
||||
libs_ddrhook-util := \
|
||||
hook \
|
||||
hooklib \
|
||||
util \
|
||||
|
||||
src_ddrhook-util := \
|
||||
dinput.c \
|
||||
gfx.c \
|
||||
guid.c \
|
||||
misc.c \
|
||||
monitor.c \
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <initguid.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "ddrhook/monitor.h"
|
||||
#include "ddrhook-util/monitor.h"
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ddrhook/gfx.h"
|
||||
#include "ddrhook-util/gfx.h"
|
||||
|
||||
#include "hook/pe.h"
|
||||
#include "hook/table.h"
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "ddrhook/monitor.h"
|
||||
#include "ddrhook-util/monitor.h"
|
||||
|
||||
#include "hook/table.h"
|
||||
|
||||
@@ -5,6 +5,7 @@ deplibs_ddrhook := \
|
||||
|
||||
libs_ddrhook := \
|
||||
acioemu \
|
||||
ddrhook-util \
|
||||
p3ioemu \
|
||||
p3io \
|
||||
hook \
|
||||
@@ -17,12 +18,7 @@ src_ddrhook := \
|
||||
extio.c \
|
||||
dllmain.c \
|
||||
_com4.c \
|
||||
dinput.c \
|
||||
gfx.c \
|
||||
guid.c \
|
||||
master.c \
|
||||
misc.c \
|
||||
monitor.c \
|
||||
p3io.c \
|
||||
usbmem.c \
|
||||
spike.c
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
#include "bemanitools/ddrio.h"
|
||||
#include "bemanitools/eamio.h"
|
||||
|
||||
#include "ddrhook-util/gfx.h"
|
||||
|
||||
#include "ddrhook/_com4.h"
|
||||
#include "ddrhook/extio.h"
|
||||
#include "ddrhook/gfx.h"
|
||||
#include "ddrhook/master.h"
|
||||
#include "ddrhook/p3io.h"
|
||||
#include "ddrhook/spike.h"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include "ddrhook/master.h"
|
||||
#include "ddrhook/dinput.h"
|
||||
#include "ddrhook/gfx.h"
|
||||
#include "ddrhook/misc.h"
|
||||
#include "ddrhook/monitor.h"
|
||||
|
||||
#include "ddrhook-util/dinput.h"
|
||||
#include "ddrhook-util/gfx.h"
|
||||
#include "ddrhook-util/misc.h"
|
||||
#include "ddrhook-util/monitor.h"
|
||||
|
||||
#include "hook/table.h"
|
||||
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
static struct security_mcode ezusb_iidx_emu_node_security_plug_boot_version;
|
||||
static uint32_t ezusb_iidx_emu_node_security_plug_boot_seeds[3];
|
||||
|
||||
static struct security_rp_sign_key ezusb_iidx_emu_node_security_plug_black_sign_key;
|
||||
static struct security_rp_sign_key ezusb_iidx_emu_node_security_plug_white_sign_key;
|
||||
|
||||
static struct security_mcode ezusb_iidx_emu_node_security_plug_black_mcode;
|
||||
static struct security_mcode ezusb_iidx_emu_node_security_plug_white_mcode;
|
||||
|
||||
@@ -62,6 +65,28 @@ void ezusb_iidx_emu_node_security_plug_set_boot_seeds(const uint32_t *seeds)
|
||||
sizeof(ezusb_iidx_emu_node_security_plug_boot_seeds));
|
||||
}
|
||||
|
||||
void ezusb_iidx_emu_node_security_plug_set_plug_black_sign_key(
|
||||
const struct security_rp_sign_key *sign_key)
|
||||
{
|
||||
log_misc("black sign key: %s", sign_key->data);
|
||||
|
||||
memcpy(
|
||||
&ezusb_iidx_emu_node_security_plug_black_sign_key,
|
||||
sign_key,
|
||||
sizeof(struct security_rp_sign_key));
|
||||
}
|
||||
|
||||
void ezusb_iidx_emu_node_security_plug_set_plug_white_sign_key(
|
||||
const struct security_rp_sign_key *sign_key)
|
||||
{
|
||||
log_misc("white sign key: %s", sign_key->data);
|
||||
|
||||
memcpy(
|
||||
&ezusb_iidx_emu_node_security_plug_white_sign_key,
|
||||
sign_key,
|
||||
sizeof(struct security_rp_sign_key));
|
||||
}
|
||||
|
||||
void ezusb_iidx_emu_node_security_plug_set_plug_black_mcode(
|
||||
const struct security_mcode *mcode)
|
||||
{
|
||||
@@ -373,7 +398,7 @@ bool ezusb_iidx_emu_node_security_plug_read_packet_v2(
|
||||
|
||||
security_rp2_generate_signed_eeprom_data(
|
||||
SECURITY_RP_UTIL_RP_TYPE_BLACK,
|
||||
&ezusb_iidx_emu_node_security_plug_boot_version,
|
||||
&ezusb_iidx_emu_node_security_plug_black_sign_key,
|
||||
&ezusb_iidx_emu_node_security_plug_black_mcode,
|
||||
&ezusb_iidx_emu_node_security_plug_pcbid,
|
||||
(struct security_rp2_eeprom *) pkg->payload);
|
||||
@@ -415,7 +440,7 @@ bool ezusb_iidx_emu_node_security_plug_read_packet_v2(
|
||||
|
||||
security_rp2_generate_signed_eeprom_data(
|
||||
SECURITY_RP_UTIL_RP_TYPE_WHITE,
|
||||
&ezusb_iidx_emu_node_security_plug_boot_version,
|
||||
&ezusb_iidx_emu_node_security_plug_white_sign_key,
|
||||
&ezusb_iidx_emu_node_security_plug_white_mcode,
|
||||
&ezusb_iidx_emu_node_security_plug_eamid,
|
||||
(struct security_rp2_eeprom *) pkg->payload);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "security/id.h"
|
||||
#include "security/mcode.h"
|
||||
#include "security/rp-sign-key.h"
|
||||
|
||||
/**
|
||||
* Set the boot version of the game. The boot version mcode is used for
|
||||
@@ -23,6 +24,22 @@ void ezusb_iidx_emu_node_security_plug_set_boot_version(
|
||||
*/
|
||||
void ezusb_iidx_emu_node_security_plug_set_boot_seeds(const uint32_t *seeds);
|
||||
|
||||
/**
|
||||
* Set the signing key for the black dongle.
|
||||
*
|
||||
* @param sign_key Pointer to the black dongle sign key.
|
||||
*/
|
||||
void ezusb_iidx_emu_node_security_plug_set_plug_black_sign_key(
|
||||
const struct security_rp_sign_key *sign_key);
|
||||
|
||||
/**
|
||||
* Set the signing key for the white dongle.
|
||||
*
|
||||
* @param sign_key Pointer to the white dongle sign key.
|
||||
*/
|
||||
void ezusb_iidx_emu_node_security_plug_set_plug_white_sign_key(
|
||||
const struct security_rp_sign_key *sign_key);
|
||||
|
||||
/**
|
||||
* The mcode of the target game to boot. This mcode is typically printed onto
|
||||
* the black plug corresponding to the game to boot.
|
||||
|
||||
@@ -168,6 +168,14 @@ void eamuse_set_addr(const struct net_addr *addr)
|
||||
|
||||
tmp_str2 = net_addr_to_str(&eamuse_server_addr_resolved);
|
||||
|
||||
// when resolving URLs with net_str_parse
|
||||
// it will default to NET_INVALID_PORT if no port is specified
|
||||
// assume default 80 here as a good sanity check
|
||||
if (eamuse_server_addr_resolved.ipv4.port == NET_INVALID_PORT) {
|
||||
log_info("No port was specified, using port 80 as fallback");
|
||||
eamuse_server_addr_resolved.ipv4.port = 80;
|
||||
}
|
||||
|
||||
log_info("Target eamuse server %s resolved to %s", tmp_str, tmp_str2);
|
||||
|
||||
free(tmp_str);
|
||||
|
||||
@@ -38,6 +38,8 @@
|
||||
#include "iidxhook-util/eamuse.h"
|
||||
#include "iidxhook-util/settings.h"
|
||||
|
||||
#include "security/rp-sign-key.h"
|
||||
|
||||
#include "util/log.h"
|
||||
#include "util/str.h"
|
||||
#include "util/thread.h"
|
||||
@@ -163,6 +165,10 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
|
||||
ezusb_iidx_emu_node_security_plug_set_boot_version(
|
||||
&config_sec.boot_version);
|
||||
ezusb_iidx_emu_node_security_plug_set_boot_seeds(config_sec.boot_seeds);
|
||||
ezusb_iidx_emu_node_security_plug_set_plug_black_sign_key(
|
||||
&security_rp_sign_key_black_iidx);
|
||||
ezusb_iidx_emu_node_security_plug_set_plug_white_sign_key(
|
||||
&security_rp_sign_key_white_eamuse);
|
||||
ezusb_iidx_emu_node_security_plug_set_plug_black_mcode(
|
||||
&config_sec.black_plug_mcode);
|
||||
ezusb_iidx_emu_node_security_plug_set_plug_white_mcode(
|
||||
@@ -235,7 +241,7 @@ BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
|
||||
{
|
||||
if (reason == DLL_PROCESS_ATTACH) {
|
||||
log_to_writer(log_writer_debug, NULL);
|
||||
|
||||
|
||||
/* Bootstrap hook for further init tasks (see above) */
|
||||
|
||||
hook_table_apply(
|
||||
|
||||
6
src/main/jbhook-util-p3io/Module.mk
Normal file
6
src/main/jbhook-util-p3io/Module.mk
Normal file
@@ -0,0 +1,6 @@
|
||||
libs += jbhook-util-p3io
|
||||
|
||||
src_jbhook-util-p3io := \
|
||||
gfx.c \
|
||||
mixer.c \
|
||||
p3io.c \
|
||||
154
src/main/jbhook-util-p3io/gfx.c
Normal file
154
src/main/jbhook-util-p3io/gfx.c
Normal file
@@ -0,0 +1,154 @@
|
||||
#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-p3io/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},
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
4
src/main/jbhook-util-p3io/gfx.h
Normal file
4
src/main/jbhook-util-p3io/gfx.h
Normal file
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Rotate a horizontal-by-default jubeat window to vertical
|
||||
*/
|
||||
void jbhook_util_gfx_install_vertical_hooks(void);
|
||||
79
src/main/jbhook-util-p3io/mixer.c
Normal file
79
src/main/jbhook-util-p3io/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-p3io/mixer.h
Normal file
11
src/main/jbhook-util-p3io/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/p3io.c
Normal file
206
src/main/jbhook-util-p3io/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/p3io.h"
|
||||
|
||||
#include "p3ioemu/emu.h"
|
||||
#include "p3ioemu/uart.h"
|
||||
|
||||
#include "security/rp-sign-key.h"
|
||||
#include "security/rp3.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
static HRESULT jbhook_p3io_read_jamma(void *ctx, uint32_t *state);
|
||||
static HRESULT jbhook_p3io_get_roundplug(
|
||||
void *ctx, uint8_t plug_id, uint8_t *rom, uint8_t *eeprom);
|
||||
static HRESULT jbhook_p3io_set_outputs(void *ctx, uint32_t state);
|
||||
|
||||
/*
|
||||
0:0 b13
|
||||
0:1 -
|
||||
0:2 b15
|
||||
0:3 -
|
||||
0:4 test
|
||||
0:5 coin
|
||||
0:6 service
|
||||
0:7 -
|
||||
|
||||
1:0 -
|
||||
1:1 b4
|
||||
1:2 b8
|
||||
1:3 b12
|
||||
1:4 b16
|
||||
1:5 b3
|
||||
1:6 b7
|
||||
1:7 b11
|
||||
|
||||
2:0 -
|
||||
2:1 b2
|
||||
2:2 b6
|
||||
2:3 b10
|
||||
2:4 b14
|
||||
2:5 b1
|
||||
2:6 b5
|
||||
2:7 b9
|
||||
|
||||
3:0 -
|
||||
3:1 -
|
||||
3:2 -
|
||||
3:3 -
|
||||
3:4 -
|
||||
3:5 -
|
||||
3:6 -
|
||||
3:7 -
|
||||
*/
|
||||
static const uint32_t jbhook_p3io_panel_mappings[] = {
|
||||
(1 << 21),
|
||||
(1 << 17),
|
||||
(1 << 13),
|
||||
(1 << 9),
|
||||
(1 << 22),
|
||||
(1 << 18),
|
||||
(1 << 14),
|
||||
(1 << 10),
|
||||
(1 << 23),
|
||||
(1 << 19),
|
||||
(1 << 15),
|
||||
(1 << 11),
|
||||
(1 << 0),
|
||||
(1 << 20),
|
||||
(1 << 2),
|
||||
(1 << 12),
|
||||
};
|
||||
|
||||
static const uint32_t jbhook_p3io_sys_button_mappings[] = {
|
||||
(1 << 4),
|
||||
(1 << 6),
|
||||
(1 << 5),
|
||||
};
|
||||
|
||||
static struct security_mcode jbhook_p3io_mcode;
|
||||
static struct security_id jbhook_p3io_pcbid;
|
||||
static struct security_id jbhook_p3io_eamid;
|
||||
|
||||
static const struct p3io_ops p3io_ddr_ops = {
|
||||
.read_jamma = jbhook_p3io_read_jamma,
|
||||
.get_roundplug = jbhook_p3io_get_roundplug,
|
||||
.set_outputs = jbhook_p3io_set_outputs,
|
||||
};
|
||||
|
||||
void jbhook_util_p3io_init(
|
||||
const struct security_mcode *mcode,
|
||||
const struct security_id *pcbid,
|
||||
const struct security_id *eamid)
|
||||
{
|
||||
memcpy(&jbhook_p3io_mcode, mcode, sizeof(struct security_mcode));
|
||||
memcpy(&jbhook_p3io_pcbid, pcbid, sizeof(struct security_id));
|
||||
memcpy(&jbhook_p3io_eamid, eamid, sizeof(struct security_id));
|
||||
|
||||
p3io_emu_init(&p3io_ddr_ops, NULL);
|
||||
}
|
||||
|
||||
void jbhook_util_p3io_fini(void)
|
||||
{
|
||||
p3io_emu_fini();
|
||||
}
|
||||
|
||||
static HRESULT jbhook_p3io_read_jamma(void *ctx, uint32_t *state)
|
||||
{
|
||||
uint16_t panels;
|
||||
uint8_t buttons;
|
||||
|
||||
log_assert(state != NULL);
|
||||
|
||||
*state = 0;
|
||||
|
||||
if (!jb_io_read_inputs()) {
|
||||
log_warning("Reading inputs from jbio failed");
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
panels = jb_io_get_panel_inputs();
|
||||
buttons = jb_io_get_sys_inputs();
|
||||
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
// panels are active-low
|
||||
if ((panels & (1 << i)) == 0) {
|
||||
*state |= jbhook_p3io_panel_mappings[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
// sys buttons are active-high
|
||||
if (buttons & (1 << i)) {
|
||||
*state |= jbhook_p3io_sys_button_mappings[i];
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT jbhook_p3io_get_roundplug(
|
||||
void *ctx, uint8_t plug_id, uint8_t *rom, uint8_t *eeprom)
|
||||
{
|
||||
struct security_rp3_eeprom eeprom_out;
|
||||
|
||||
if (plug_id == 0) {
|
||||
/* black */
|
||||
memcpy(rom, jbhook_p3io_pcbid.id, sizeof(jbhook_p3io_pcbid.id));
|
||||
security_rp3_generate_signed_eeprom_data(
|
||||
SECURITY_RP_UTIL_RP_TYPE_BLACK,
|
||||
&security_rp_sign_key_black_gfdmv4,
|
||||
&jbhook_p3io_mcode,
|
||||
&jbhook_p3io_pcbid,
|
||||
&eeprom_out);
|
||||
} else {
|
||||
/* white */
|
||||
memcpy(rom, jbhook_p3io_eamid.id, sizeof(jbhook_p3io_eamid.id));
|
||||
security_rp3_generate_signed_eeprom_data(
|
||||
SECURITY_RP_UTIL_RP_TYPE_WHITE,
|
||||
&security_rp_sign_key_white_eamuse,
|
||||
&security_mcode_eamuse,
|
||||
&jbhook_p3io_eamid,
|
||||
&eeprom_out);
|
||||
}
|
||||
|
||||
memcpy(eeprom, &eeprom_out, sizeof(struct security_rp3_eeprom));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT jbhook_p3io_set_outputs(void *ctx, uint32_t state) {
|
||||
uint8_t p3io_panel = (state & 0x00FF00) >> 8;
|
||||
uint8_t p3io_coinblocker = (state & 0xFF0000) >> 16;
|
||||
|
||||
enum jb_io_panel_mode panel_mode;
|
||||
|
||||
switch(p3io_panel) {
|
||||
case 5:
|
||||
panel_mode = JB_IO_PANEL_MODE_TOP_LEFT;
|
||||
break;
|
||||
case 4:
|
||||
panel_mode = JB_IO_PANEL_MODE_TOP_RIGHT;
|
||||
break;
|
||||
case 6:
|
||||
panel_mode = JB_IO_PANEL_MODE_BOTTOM_RIGHT;
|
||||
break;
|
||||
case 7:
|
||||
panel_mode = JB_IO_PANEL_MODE_BOTTOM_LEFT;
|
||||
break;
|
||||
default:
|
||||
panel_mode = JB_IO_PANEL_MODE_ALL;
|
||||
break;
|
||||
}
|
||||
|
||||
jb_io_set_panel_mode(panel_mode);
|
||||
|
||||
// 0x40 has been seen to unblock, no other values observed
|
||||
jb_io_set_coin_blocker(p3io_coinblocker == 0x00);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -9,13 +9,13 @@
|
||||
#include "security/mcode.h"
|
||||
|
||||
/**
|
||||
* Initialize the jbhook1 specific p3io emulation backend.
|
||||
* Initialize the jb01-04 specific p3io emulation backend.
|
||||
*
|
||||
* @param mcode Mcode of the target game to run. Required for dongle emulation.
|
||||
* @param pcbid PCBDID
|
||||
* @param eamid EAMID
|
||||
*/
|
||||
void jbhook1_p3io_init(
|
||||
void jbhook_util_p3io_init(
|
||||
const struct security_mcode *mcode,
|
||||
const struct security_id *pcbid,
|
||||
const struct security_id *eamid);
|
||||
@@ -23,6 +23,6 @@ void jbhook1_p3io_init(
|
||||
/**
|
||||
* Shutdown the p3io emulation backend.
|
||||
*/
|
||||
void jbhook1_p3io_fini(void);
|
||||
void jbhook_util_p3io_fini(void);
|
||||
|
||||
#endif
|
||||
10
src/main/jbhook-util/Module.mk
Normal file
10
src/main/jbhook-util/Module.mk
Normal file
@@ -0,0 +1,10 @@
|
||||
libs += jbhook-util
|
||||
|
||||
libs_jbhook-util := \
|
||||
acioemu \
|
||||
|
||||
src_jbhook-util := \
|
||||
acio.c \
|
||||
eamuse.c \
|
||||
locale.c \
|
||||
p4io.c \
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "hook/iohook.h"
|
||||
|
||||
#include "jbhook/acio.h"
|
||||
#include "jbhook-util/acio.h"
|
||||
|
||||
#include "imports/avs.h"
|
||||
|
||||
@@ -32,20 +32,25 @@ static struct ac_io_emu ac_io_emu;
|
||||
static struct ac_io_emu_icca ac_io_emu_icca;
|
||||
static struct ac_io_emu_h44b ac_io_emu_h44b;
|
||||
|
||||
void ac_io_port_init(void)
|
||||
void jbhook_util_ac_io_port_init(const wchar_t *filename)
|
||||
{
|
||||
ac_io_emu_init(&ac_io_emu, L"COM1");
|
||||
ac_io_emu_init(&ac_io_emu, filename);
|
||||
ac_io_emu_icca_init(&ac_io_emu_icca, &ac_io_emu, 0);
|
||||
ac_io_emu_h44b_init(&ac_io_emu_h44b, &ac_io_emu, 1);
|
||||
}
|
||||
|
||||
void ac_io_port_fini(void)
|
||||
void jbhook_util_ac_io_port_fini(void)
|
||||
{
|
||||
ac_io_emu_fini(&ac_io_emu);
|
||||
}
|
||||
|
||||
void jbhook_util_ac_io_set_iccb(void) {
|
||||
ac_io_emu_icca_set_version(&ac_io_emu_icca, v150);
|
||||
ac_io_emu_icca_set_product_code(&ac_io_emu_icca, AC_IO_EMU_PROD_CODE_ICCB);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
ac_io_port_dispatch_irp(struct irp *irp)
|
||||
jbhook_util_ac_io_port_dispatch_irp(struct irp *irp)
|
||||
{
|
||||
const struct ac_io_message *msg;
|
||||
HRESULT hr;
|
||||
28
src/main/jbhook-util/acio.h
Normal file
28
src/main/jbhook-util/acio.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef JBHOOK1_ACIO_H
|
||||
#define JBHOOK1_ACIO_H
|
||||
|
||||
#include "hook/iohook.h"
|
||||
|
||||
/**
|
||||
* Initialize the ACIO backend for jubeat on the specified COM port.
|
||||
*/
|
||||
void jbhook_util_ac_io_port_init(const wchar_t *filename);
|
||||
|
||||
/**
|
||||
* Shutdown the ACIO backend.
|
||||
*/
|
||||
void jbhook_util_ac_io_port_fini(void);
|
||||
|
||||
/**
|
||||
* ACIO backend dispatch irp function. This needs to be hooked up to the iohook
|
||||
* module in order to receive system calls to dispatch for emulation.
|
||||
*/
|
||||
HRESULT jbhook_util_ac_io_port_dispatch_irp(struct irp *irp);
|
||||
|
||||
/**
|
||||
* Enable ICCB emulation instead of the default ICCA emulation - some jubeats
|
||||
* will have IO errors unless explicitly set to ICCB mode.
|
||||
*/
|
||||
void jbhook_util_ac_io_set_iccb(void);
|
||||
|
||||
#endif
|
||||
144
src/main/jbhook-util/eamuse.c
Normal file
144
src/main/jbhook-util/eamuse.c
Normal file
@@ -0,0 +1,144 @@
|
||||
#define LOG_MODULE "eamuse-hook"
|
||||
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
#include "util/net.h"
|
||||
#include "util/str.h"
|
||||
|
||||
static const char *jbhook_eamuse_konami_url = "eamuse.konami.";
|
||||
|
||||
static int(STDCALL *real_getaddrinfo)(
|
||||
PCSTR pNodeName,
|
||||
PCSTR pServiceName,
|
||||
const ADDRINFOA *pHints,
|
||||
PADDRINFOA *ppResult);
|
||||
|
||||
static int STDCALL my_getaddrinfo(
|
||||
PCSTR pNodeName,
|
||||
PCSTR pServiceName,
|
||||
const ADDRINFOA *pHints,
|
||||
PADDRINFOA *ppResult);
|
||||
|
||||
static DWORD WINAPI my_GetIpAddrTable(
|
||||
PMIB_IPADDRTABLE pIpAddrTable,
|
||||
PULONG pdwSize,
|
||||
BOOL bOrder
|
||||
);
|
||||
|
||||
static const struct hook_symbol eamuse_hook_syms[] = {
|
||||
{
|
||||
.name = "getaddrinfo",
|
||||
.ordinal = 176,
|
||||
.patch = my_getaddrinfo,
|
||||
.link = (void **) &real_getaddrinfo,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hook_symbol network_hook_syms[] = {
|
||||
{
|
||||
.name = "GetIpAddrTable",
|
||||
.patch = my_GetIpAddrTable,
|
||||
},
|
||||
};
|
||||
|
||||
static int STDCALL my_getaddrinfo(
|
||||
PCSTR pNodeName,
|
||||
PCSTR pServiceName,
|
||||
const ADDRINFOA *pHints,
|
||||
PADDRINFOA *ppResult)
|
||||
{
|
||||
log_misc("my_getaddrinfo: %s, %s", pNodeName, pServiceName);
|
||||
|
||||
/* resolve eamuse.konami.fun/com to 127.0.0.1 to avoid lag spikes every
|
||||
150 seconds which might happen in-game as well */
|
||||
if (!strncmp(
|
||||
pNodeName,
|
||||
jbhook_eamuse_konami_url,
|
||||
strlen(jbhook_eamuse_konami_url))) {
|
||||
log_info("Resolve konami.eamuse.XXX -> localhost");
|
||||
pNodeName = "localhost";
|
||||
}
|
||||
|
||||
return real_getaddrinfo(pNodeName, pServiceName, pHints, ppResult);
|
||||
}
|
||||
|
||||
static DWORD get_best_ip(void) {
|
||||
PIP_ADAPTER_INFO info = NULL;
|
||||
struct net_addr addr;
|
||||
// fallback to a very obviously wrong value
|
||||
DWORD ret = (5 << 24) | (7 << 16) | (3 << 8) | (0 << 0);
|
||||
ULONG sz = 0;
|
||||
|
||||
// this uses our hooked GetAdaptersInfo from hooklib/adapter.c, thus using
|
||||
// the preferred interface instead of the default order
|
||||
log_assert(GetAdaptersInfo(info, &sz) == ERROR_BUFFER_OVERFLOW);
|
||||
|
||||
info = malloc(sz);
|
||||
|
||||
if(GetAdaptersInfo(info, &sz) != NO_ERROR) {
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
if(!net_str_parse(info->IpAddressList.IpAddress.String, &addr)) {
|
||||
goto CLEANUP;
|
||||
}
|
||||
|
||||
// MS docs say this should be in network byte order, but we need to return
|
||||
// host byte order for the game to not throw the IP error
|
||||
ret = addr.ipv4.addr;
|
||||
|
||||
CLEANUP:
|
||||
free(info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* In new games via network.dll:network_addr_is_changed and in old games
|
||||
* directly, this function is called to compare the current IP address vs the IP
|
||||
* address when the game was first loaded. If the two are different, an error is
|
||||
* printed. It can be dismissed but will show up every ~10 seconds, impeding
|
||||
* gameplay. Because GetAdaptersInfo is hooked to return a (sometimes) different
|
||||
* adapter, computers with multiple interfaces will often fail this comparison
|
||||
* check. By also hooking this function, the IP addresses of the two calls will
|
||||
* agree.
|
||||
*/
|
||||
static DWORD WINAPI my_GetIpAddrTable(
|
||||
PMIB_IPADDRTABLE pIpAddrTable,
|
||||
PULONG pdwSize,
|
||||
BOOL bOrder
|
||||
) {
|
||||
ULONG in = *pdwSize;
|
||||
// 1 element return table
|
||||
*pdwSize = sizeof(MIB_IPADDRTABLE) + sizeof(MIB_IPADDRROW);
|
||||
|
||||
if(in < *pdwSize) {
|
||||
return ERROR_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
|
||||
pIpAddrTable->dwNumEntries = 1;
|
||||
pIpAddrTable->table[0].dwAddr = get_best_ip();
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
void jbhook_util_eamuse_hook_init(void)
|
||||
{
|
||||
hook_table_apply(
|
||||
NULL, "ws2_32.dll", eamuse_hook_syms, lengthof(eamuse_hook_syms));
|
||||
hook_table_apply(
|
||||
NULL, "iphlpapi.dll", network_hook_syms, lengthof(network_hook_syms));
|
||||
|
||||
log_info("Inserted eamuse hooks");
|
||||
}
|
||||
6
src/main/jbhook-util/eamuse.h
Normal file
6
src/main/jbhook-util/eamuse.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef JBHOOK_UTIL_EAMUSE_H
|
||||
#define JBHOOK_UTIL_EAMUSE_H
|
||||
|
||||
void jbhook_util_eamuse_hook_init(void);
|
||||
|
||||
#endif
|
||||
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
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "imports/avs.h"
|
||||
|
||||
#include "jbhook/io.h"
|
||||
#include "jbhook-util/p4io.h"
|
||||
|
||||
#include "p4io/cmd.h"
|
||||
|
||||
@@ -20,7 +20,7 @@ static uint32_t jbhook_command_handle(
|
||||
void *resp,
|
||||
uint32_t resp_max_len);
|
||||
|
||||
static const struct p4ioemu_device_msg_hook jbhook_io_msg = {
|
||||
static const struct p4ioemu_device_msg_hook jbhook_p4io_msg = {
|
||||
.jamma2_read = jbhook_io_jamma2_read,
|
||||
.command_handle = jbhook_command_handle,
|
||||
.roundplug_read_id = NULL,
|
||||
@@ -181,7 +181,7 @@ static uint32_t jbhook_command_handle(
|
||||
}
|
||||
}
|
||||
|
||||
const struct p4ioemu_device_msg_hook *jbhook_io_init(void)
|
||||
const struct p4ioemu_device_msg_hook *jbhook_p4io_init(void)
|
||||
{
|
||||
return &jbhook_io_msg;
|
||||
return &jbhook_p4io_msg;
|
||||
}
|
||||
@@ -3,6 +3,6 @@
|
||||
|
||||
#include "p4ioemu/device.h"
|
||||
|
||||
const struct p4ioemu_device_msg_hook *jbhook_io_init(void);
|
||||
const struct p4ioemu_device_msg_hook *jbhook_p4io_init(void);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -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,20 +0,0 @@
|
||||
#ifndef JBHOOK_D3D8_H
|
||||
#define JBHOOK_D3D8_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* Hook some gfx related functions to patch gfx related stuff
|
||||
* like enabling window mode.
|
||||
*/
|
||||
void gfx_hook_init(void);
|
||||
|
||||
/**
|
||||
* Set the game to window mode.
|
||||
*
|
||||
* @param framed True to add a window frame and make the window
|
||||
* movable, resizable, minizable. False for no frame.
|
||||
*/
|
||||
void gfx_set_windowed(bool framed);
|
||||
|
||||
#endif
|
||||
@@ -1,17 +1,22 @@
|
||||
avsdlls += jbhook1
|
||||
imps += glhelper
|
||||
|
||||
deplibs_jbhook1 := \
|
||||
avs \
|
||||
avs \
|
||||
glhelper \
|
||||
|
||||
ldflags_jbhook1 := \
|
||||
-lws2_32 \
|
||||
-liphlpapi \
|
||||
-lopengl32 \
|
||||
|
||||
libs_jbhook1 := \
|
||||
acioemu \
|
||||
cconfig \
|
||||
eamio \
|
||||
jbio \
|
||||
jbhook-util \
|
||||
jbhook-util-p3io \
|
||||
p3ioemu \
|
||||
p3io \
|
||||
hook \
|
||||
@@ -20,11 +25,9 @@ libs_jbhook1 := \
|
||||
util \
|
||||
|
||||
src_jbhook1 := \
|
||||
acio.c \
|
||||
avs-boot.c \
|
||||
config-gfx.c \
|
||||
config-eamuse.c \
|
||||
config-security.c \
|
||||
dllmain.c \
|
||||
log-gftools.c \
|
||||
p3io.c \
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user