mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2026-09-15 11:55:10 -05:00
Compare commits
242 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a81997dce8 | ||
|
|
bfe68f8708 | ||
|
|
9c1d83d050 | ||
|
|
e4ee94ae2a | ||
|
|
6e0e5031ac | ||
|
|
f17e8d6739 | ||
|
|
ac02609948 | ||
|
|
c644db03ae | ||
|
|
7d5398b6af | ||
|
|
cac09f8f87 | ||
|
|
85c9c444f1 | ||
|
|
8f2ce1f1b3 | ||
|
|
d3bf381a4f | ||
|
|
3acbc7f251 | ||
|
|
839903ab48 | ||
|
|
c929141e71 | ||
|
|
1477480836 | ||
|
|
bf4322e855 | ||
|
|
3eed0a4ab3 | ||
|
|
a9ade9d9d4 | ||
|
|
26336805d2 | ||
|
|
7d0e916b9f | ||
|
|
a03a5604ec | ||
|
|
54e7d783ef | ||
|
|
4ea1397af2 | ||
|
|
fb593df4a1 | ||
|
|
f0c33663e9 | ||
|
|
87ee37d059 | ||
|
|
5688fb7319 | ||
|
|
d529ee484f | ||
|
|
7c43fb7163 | ||
|
|
652d2ef633 | ||
|
|
78884aebad | ||
|
|
549f00bfb3 | ||
|
|
aab45f145f | ||
|
|
6171f0dc60 | ||
|
|
2f05760f4e | ||
|
|
7b5e4772ea | ||
|
|
e266aed1f9 | ||
|
|
0b0e7faef0 | ||
|
|
53866130cb | ||
|
|
dbb8c45a9f | ||
|
|
8ed7d6db71 | ||
|
|
4c746df6a8 | ||
|
|
7d485e7c7e | ||
|
|
deb6e5cf77 | ||
|
|
2a03690772 | ||
|
|
6ce4cce500 | ||
|
|
c6e59bae9b | ||
|
|
31e15ec5ea | ||
|
|
9cef7c03d0 | ||
|
|
f9b37c7a72 | ||
|
|
609c19b0ca | ||
|
|
75b27d5992 | ||
|
|
965df98093 | ||
|
|
0c06d224cc | ||
|
|
fb3d2ea312 | ||
|
|
089253a537 | ||
|
|
a4436747de | ||
|
|
43b11c8778 | ||
|
|
dd7fd860b5 | ||
|
|
18842a1dd3 | ||
|
|
18f6d9ef70 | ||
|
|
592967e191 | ||
|
|
6614cc801e | ||
|
|
8e1151ac02 | ||
|
|
4b60cb6c6c | ||
|
|
770bae4169 | ||
|
|
49d0bc638b | ||
|
|
837affc66c | ||
|
|
ec76ba075f | ||
|
|
f438f04f2a | ||
|
|
865980991e | ||
|
|
37384c15ec | ||
|
|
f0d62cc938 | ||
|
|
bf067de633 | ||
|
|
f3b07aeb0a | ||
|
|
a1a67697c4 | ||
|
|
ce5b1b2eac | ||
|
|
3f2aed65e4 | ||
|
|
22f3845609 | ||
|
|
de0d70d808 | ||
|
|
12c52bb0d8 | ||
|
|
279d4de4b3 | ||
|
|
2b52fbe211 | ||
|
|
78e7c05876 | ||
|
|
9a5418f6a3 | ||
|
|
2363498f73 | ||
|
|
edbbe5ae67 | ||
|
|
d799b69d12 | ||
|
|
91f83cd975 | ||
|
|
adeabbea19 | ||
|
|
41187091b0 | ||
|
|
5658658d3a | ||
|
|
79a74b2d2f | ||
|
|
51484b1d3d | ||
|
|
df8f3bc96a | ||
|
|
ec435e7a7b | ||
|
|
f8a01ed92f | ||
|
|
2b1dd866d0 | ||
|
|
7d129a3e63 | ||
|
|
29db89cebe | ||
|
|
f7e1c8b3f9 | ||
|
|
f667ae5601 | ||
|
|
4b061bdf8f | ||
|
|
13600db1d5 | ||
|
|
e4126500ef | ||
|
|
049f1b4564 | ||
|
|
687c000000 | ||
|
|
1b593a8e23 | ||
|
|
24178121f0 | ||
|
|
62ad4e0616 | ||
|
|
c348a41d22 | ||
|
|
ef377f40d8 | ||
|
|
0c88518a1f | ||
|
|
0bc87db8da | ||
|
|
53f8cb3bf3 | ||
|
|
41edfec702 | ||
|
|
c6c3bdb075 | ||
|
|
b3a89012ca | ||
|
|
f0bc87f1d6 | ||
|
|
7508c43119 | ||
|
|
34be731211 | ||
|
|
bac1ce62e5 | ||
|
|
58689bbc30 | ||
|
|
d5e186ffe2 | ||
|
|
34c95561c4 | ||
|
|
81d697d59a | ||
|
|
3bdda4d123 | ||
|
|
ea8842b58a | ||
|
|
e89889806b | ||
|
|
b3b2f8f433 | ||
|
|
1cdf330cbf | ||
|
|
89c3ada28f | ||
|
|
d9cb953b67 | ||
|
|
7ebb80d600 | ||
|
|
e737d60893 | ||
|
|
f39843b41f | ||
|
|
98d0debd05 | ||
|
|
950584f025 | ||
|
|
e4081c057f | ||
|
|
8c3030354a | ||
|
|
9777eddaa0 | ||
|
|
671723febd | ||
|
|
c1f6166e1b | ||
|
|
538650f7ac | ||
|
|
efd243fd9d | ||
|
|
383b301d3c | ||
|
|
a9d201691a | ||
|
|
ebb6f811b4 | ||
|
|
9e96cf074f | ||
|
|
e6766d4a3b | ||
|
|
843d78bc4b | ||
|
|
0792b29f3d | ||
|
|
e1d4810743 | ||
|
|
2110abc269 | ||
|
|
fc22f76988 | ||
|
|
3d4df4cd64 | ||
|
|
be5a773cb7 | ||
|
|
3ed6ac6290 | ||
|
|
e49149b03d | ||
|
|
af507e6dcb | ||
|
|
a9ebc30ea7 | ||
|
|
4f3135439d | ||
|
|
2d1c09d4e6 | ||
|
|
164d56b6eb | ||
|
|
1712f10f66 | ||
|
|
128496901e | ||
|
|
65a45740d2 | ||
|
|
8bd0f44e24 | ||
|
|
7733912ae2 | ||
|
|
55c9f5a521 | ||
|
|
917dc88826 | ||
|
|
475d438ec7 | ||
|
|
f23d3531a2 | ||
|
|
32c3428c59 | ||
|
|
ee034a1f08 | ||
|
|
54b321c7d9 | ||
|
|
de894ae5ce | ||
|
|
1d25abc10b | ||
|
|
beea9e7bb7 | ||
|
|
fbb69d4550 | ||
|
|
e0fe9bcf94 | ||
|
|
f9c0733af3 | ||
|
|
a016f27652 | ||
|
|
3a1005f1f8 | ||
|
|
f1700ca551 | ||
|
|
60b081b01c | ||
|
|
89989ae49c | ||
|
|
ff1b9ff9a2 | ||
|
|
4c0f60fc93 | ||
|
|
caba39843f | ||
|
|
f028bdeb20 | ||
|
|
bfbb7103ef | ||
|
|
95e073271f | ||
|
|
cdefc2b09e | ||
|
|
9246e7f9e0 | ||
|
|
bbb5157460 | ||
|
|
e0cfc8c948 | ||
|
|
69ef963451 | ||
|
|
93cfb591b7 | ||
|
|
3396c09fbf | ||
|
|
bd8dc18b30 | ||
|
|
86517bd001 | ||
|
|
172c83a854 | ||
|
|
c7137659bc | ||
|
|
8e9abf9906 | ||
|
|
62bb717582 | ||
|
|
4816fb809d | ||
|
|
2a2c77f255 | ||
|
|
55513bac41 | ||
|
|
9c37ef71ba | ||
|
|
a0a1dea397 | ||
|
|
3c26a3f315 | ||
|
|
b408cd9687 | ||
|
|
be4df516fd | ||
|
|
d1080905e5 | ||
|
|
f87a51bbe4 | ||
|
|
2a4d3e2865 | ||
|
|
6697ff7df1 | ||
|
|
682fe8aa1b | ||
|
|
7d533f60cb | ||
|
|
e5331fbc7c | ||
|
|
77527e346b | ||
|
|
1d0a96fa20 | ||
|
|
63e19aaaf6 | ||
|
|
4c59f16d46 | ||
|
|
7157fdedb7 | ||
|
|
13d29cb62e | ||
|
|
bf48715466 | ||
|
|
24b490e36b | ||
|
|
ff2a4b9a2c | ||
|
|
10bddd4905 | ||
|
|
ad5fbc1f5b | ||
|
|
25413bcba8 | ||
|
|
937290f93d | ||
|
|
d04598a570 | ||
|
|
bd382e5509 | ||
|
|
0d3fa54316 | ||
|
|
e8943edff6 | ||
|
|
61f3eb44d2 | ||
|
|
5aa1e27a31 |
169
.gitlab-ci.yml
169
.gitlab-ci.yml
@@ -1,73 +1,136 @@
|
||||
image: debian
|
||||
#
|
||||
# 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
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- upload
|
||||
- release
|
||||
- releasetag
|
||||
|
||||
build:
|
||||
stage: build
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
- tags
|
||||
before_script:
|
||||
- apt-get update && apt-get -qq install clang mingw-w64 git make zip > /dev/null
|
||||
- apk update && apk add make > /dev/null
|
||||
script:
|
||||
- make
|
||||
- make build-docker
|
||||
artifacts:
|
||||
name: "$CI_COMMIT_SHORT_SHA-$CI_JOB_NAME"
|
||||
paths:
|
||||
- build
|
||||
expire_in: 1 week
|
||||
|
||||
upload-package-registry:
|
||||
stage: upload
|
||||
image: curlimages/curl:latest
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
|
||||
test:
|
||||
allow_failure: true
|
||||
stage: test
|
||||
- tags
|
||||
dependencies:
|
||||
- build
|
||||
before_script:
|
||||
- apt-get update && apt-get -qq install make wine unzip > /dev/null
|
||||
- dpkg --add-architecture i386 && apt-get update && apt-get -qq install wine32 > /dev/null
|
||||
script:
|
||||
- ls
|
||||
- make run-tests
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
|
||||
release:
|
||||
stage: release
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
dependencies:
|
||||
- build
|
||||
before_script:
|
||||
- apt-get update && apt-get -qq install zip > /dev/null
|
||||
script:
|
||||
- mv build/bemanitools.zip ./bemanitools.zip
|
||||
- find . -mindepth 1 ! -regex '^./bemanitools.zip' -delete
|
||||
- unzip bemanitools.zip
|
||||
- rm bemanitools.zip
|
||||
artifacts:
|
||||
name: "$CI_COMMIT_SHORT_SHA-$CI_JOB_NAME"
|
||||
paths:
|
||||
- ./*
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
|
||||
releasetag:
|
||||
stage: releasetag
|
||||
dependencies: []
|
||||
before_script:
|
||||
- apt-get update && apt-get -qq install curl > /dev/null
|
||||
script:
|
||||
- |
|
||||
curl --silent --show-error \
|
||||
--data "{\"tag_name\": \"${CI_COMMIT_TAG}\", \"name\": \"${CI_PROJECT_NAME}-${CI_COMMIT_TAG}\", \"description\": \"${CI_COMMIT_TAG_MESSAGE:-No release notes.}\"}" \
|
||||
--header "Content-Type: application/json" \
|
||||
--header "Private-Token: ${CI_PRIVATE_TOKEN}" \
|
||||
--request POST \
|
||||
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/releases"
|
||||
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:
|
||||
- tags
|
||||
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}"
|
||||
|
||||
@@ -8,9 +8,12 @@
|
||||
<!--- Tell us what happens instead of the expected behavior -->
|
||||
|
||||
## Detailed Description
|
||||
<!--- Provide a detailed description of the issue. Include links to screenshots or videos if necessary -->
|
||||
<!--- Provide a detailed description of the issue. Include links to screenshots or videos if
|
||||
necessary -->
|
||||
|
||||
## Steps to reproduce
|
||||
<!-- Try running the game with a default configuration as well. If that also causes issues, please point that out here in the report. This might speed up the debugging process.-->
|
||||
|
||||
<!--- Provide a detailed step by step description how to reproduce this issue -->
|
||||
1.
|
||||
2.
|
||||
@@ -29,16 +32,43 @@
|
||||
|
||||
### Log output
|
||||
See attachment.
|
||||
<!--- Provide log output as attachment. Make sure to censor sensitive data like PCBIDs or device names if necessary -->
|
||||
<!---
|
||||
Provide FULL log output, e.g. inject.log or launcher.log. Please do not guess which things
|
||||
are relevant or not. Without knowing, you might leave out things that are relevant for the developers. You have to enable log output explicitly if not done already.
|
||||
|
||||
For inject.exe and launcher.exe, add `-Y logfile.log` to the command line args to output to a file, e.g. `gamestart.bat -Y logfile.log`.
|
||||
|
||||
!!!!!!
|
||||
REMOVE ANY SENSITIVE DATA LIKE PCBIDS OR DEVICE NAMES BY REPLACING IT THEM WITH
|
||||
|
||||
[REDACTED]
|
||||
|
||||
BEFORE UPLOADING/POSTING ANY LOG DATA!!!
|
||||
|
||||
Use the search and replace feature of any kind of text editor.
|
||||
!!!!!!
|
||||
-->
|
||||
|
||||
### Configuration files
|
||||
See attachment.
|
||||
<!--- Provide any configuration files that you used, e.g. iidxhook-XX.conf. Make sure to censor sensitive data like
|
||||
PCBIDs -->
|
||||
<!--- Provide any configuration files that you used, e.g. iidxhook-XX.conf. This file is located in
|
||||
the same directory as launcher.exe or inject.exe.
|
||||
|
||||
!!!!!!
|
||||
REMOVE ANY SENSITIVE DATA LIKE PCBIDS OR DEVICE NAMES BY REPLACING IT THEM WITH
|
||||
|
||||
[REDACTED]
|
||||
|
||||
BEFORE UPLOADING/POSTING ANY LOG DATA!!!
|
||||
|
||||
Use the search and replace feature of any kind of text editor.
|
||||
!!!!!!
|
||||
-->
|
||||
|
||||
### Command line arguments
|
||||
<!--- Provide how you run the game from the command line, e.g. which gamestart.bat you used and any additional arguments
|
||||
that you provided to it. Also provide the contents of the gamestart.bat you used if you altered it. -->
|
||||
<!--- Provide how you run the game from the command line, e.g. which gamestart.bat you used and any
|
||||
additional arguments that you provided to it. Also provide the contents of the gamestart.bat you
|
||||
used if you altered it. -->
|
||||
|
||||
### APIs used
|
||||
* <!--- List all APIs you used as a bullet list, e.g. iidxio-keyboard, eamio-keyboard -->
|
||||
|
||||
58
CHANGELOG.md
58
CHANGELOG.md
@@ -1,4 +1,62 @@
|
||||
# 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.
|
||||
|
||||
## 0.00
|
||||
|
||||
testing release pipeline
|
||||
|
||||
## 5.37
|
||||
|
||||
## 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
|
||||
* Various bugfixes
|
||||
|
||||
## 5.34
|
||||
* IIDX: Support IO and card reader feature switches to disable emulation in iidxhook4-7
|
||||
* Jubeat: jbio implementation for magicbox hardware
|
||||
* Misc: Various documentation improvements
|
||||
* IIDX: Turntable multiplier (can also be used as inverted) for iidxhook9
|
||||
* IIDX: iidxhook9, add force screen resolution option to fix sometimes wrong auto res detection by
|
||||
iidx27 causing inaccurate/wrong refresh rates on monitor check
|
||||
* IIDX: iidxio BIO2 implementation -> Use BIO2 hardware with any iidxhook or other software
|
||||
supporting BT5's iidxio interface
|
||||
* IIDX: BIO2 exit hook, exit the game pressing Start P1 + Start P2, Effect and VEFX
|
||||
* launcher: Allow overriding service URL from command line
|
||||
* IIDX: vigem-iidxio, tool to allow using iidxio (ezusb, ezusb2 or bio2) to emulate XBOX controllers
|
||||
to play other non arcade games that support xinput, e.g. Lunatic Rave (note: Infinitas does not
|
||||
work with this since it only supports direct input)
|
||||
|
||||
## 5.33
|
||||
* iidxhook9: Support for IIDX27
|
||||
* sdvxio-bio2: Driver for real sdvx5 cabinet IO hardware
|
||||
* vigem-sdvxio: Tool to allow using sdvxio (kfca or bio2) to emulate an xbox controller
|
||||
* Various bugfixes and refactoring for inject and launcher
|
||||
|
||||
## 5.32
|
||||
* Various bugfixes
|
||||
|
||||
## 5.31
|
||||
* DDR: Fix p3io and extio lights not working / being swapped when using geninput
|
||||
* DDR: Add HDXS light support
|
||||
* DDR: Add 64 bit support
|
||||
* DDR: Add option to use COM4 as the p3io rs232 port instead of emulating (for use with acrealio etc.)
|
||||
* Jubeat: Add network adapter hook
|
||||
* Misc: Fix aciodrv sometimes hanging on boot (eamio-icca and sdvxio-kfca)
|
||||
|
||||
## 5.30
|
||||
* SDVX: sdvxhook2 headphone force and cursor confining config options
|
||||
* DDR: Add light support for SMX gen 4 pads
|
||||
|
||||
## 5.29
|
||||
* SDVX: Add option for monitor rotation
|
||||
* SDVX: Add option to allow overriding network adapter IP
|
||||
|
||||
@@ -1,30 +1,83 @@
|
||||
# Contributing
|
||||
Please have a look at the issue board about what's currently going on. If you see an issue that is not assigned yet and
|
||||
that you can and want to work on, please leave a comment to reach out to one of our developers. You can also ask
|
||||
questions and discuss the issue.
|
||||
This document outlines different types of contributions and how YOU can help us to improve the
|
||||
project. Read it, as it provides guidelines that are there to help you and the maintainers.
|
||||
|
||||
# Bug reports
|
||||
Please check if the bug was already reported by searching the existing issues. If it does, feel free to leave a comment
|
||||
that you also have this issue. Add additional information, screenshots, log files etc. The more information and details
|
||||
we have, the easier it might get to solve the issue.
|
||||
## Reporting and discussions: Issues section on gitlab
|
||||
In order to avoid having to manage ongoing discussions and bug reports on different communication
|
||||
channels, e.g. forums, messangers or other closed groups, we ask everyone to treat the issue
|
||||
section on gitlab as the place to open their relevant discussions and bug reports regarding the
|
||||
project.
|
||||
|
||||
When creating new issues, use our template for reporting bugs. It tells you what kind of information we need.
|
||||
The maintainers of the project do not have the time nor motivation to micromanage on the various
|
||||
channels and enter all data here to have it collected. This is a simple task that *ANYONE* can do
|
||||
allowing the maintainers and developers to spend their time on the codebase.
|
||||
|
||||
# Pull requests: bugfixes, new features or other code contributions
|
||||
Pull requests are welcome! May it be a PR to an already known issue or a new feature that you consider as a valuable
|
||||
contribution, please open a PR. If you want to start working on a new feature that was proposed in an issue, yet, it
|
||||
is recommended to reach out to the developers about this, first, to discuss if this contribution is valuable to the
|
||||
project. Otherwise, you might waste your time on implementing something that won't make it into master.
|
||||
## Bug reports
|
||||
Follow these steps when reporting bugs to ensure you provide all information we *always* need and
|
||||
make your report valuable and actionable.
|
||||
|
||||
Please read our [development guidelines](doc/development.md) as they contain valuable information that your contribution
|
||||
meets our standards.
|
||||
1. On the bemanitools repository, go `Issues` on the left-hand sidebar.
|
||||
1. Use the search function to check if there is an already open issue regarding what you want to
|
||||
report
|
||||
1. If that applies, read the open issue to check what's already covered regarding the bug
|
||||
1. Provide additional information or things that are missing. Upload your log files,
|
||||
screenshots, videos etc. Be careful to remove sensitive information like PCBIDs
|
||||
1. Give a thumbs up to the issue to show you are interested/affected as well
|
||||
1. If no existing issue avilable, create a new one
|
||||
1. Come up with a descriptive title
|
||||
1. **USE OUR BUG REPORTING TEMPLATE**: Pick it by selecting `Bug` on the `Description` section
|
||||
1. Follow the sections and their instructions provided by the template and fill them in. All fields
|
||||
are mandatory to provide a comprehensive report if not stated otherwise
|
||||
1. When finished, submit the issue
|
||||
|
||||
Fork the upstream repository and start developing on your personal fork. Make sure to test your changes with games that
|
||||
are affected by them. Pay attention to the target platform/hardware you are testing on! This is valuable information
|
||||
that should be included in the PR.
|
||||
## Pull requests: bugfixes, new features or other code contributions
|
||||
Pull requests are welcome! May it be a merge request to an already known issue or a new feature that
|
||||
you consider as a valuable contribution, please open a MR.
|
||||
|
||||
Once you completed your implementation, open a pull request on the upstream repository to propose your changes. We will review your contribution and get back to you about any changes or when we merge them to our upstream repository. Your changes, once approved, will be included in the next release.
|
||||
**!!! Maintaining documentation by adding new or improving existing documentation is as important as
|
||||
code !!!**
|
||||
|
||||
# Roadmap
|
||||
No concrete roadmap or timeline exists. We want to continue adding support for new games as well as old games (some of
|
||||
the old games supported by BT4 are not supported, yet).
|
||||
If you want to start working on a new feature that was proposed in an issue, yet, it is recommended
|
||||
to reach out to the active developers about this, first, to discuss if this contribution is valuable
|
||||
to the project. Otherwise, you might waste your time on implementing something that won't make it
|
||||
into master.
|
||||
|
||||
Please read our [development guidelines](doc/development.md) as they contain valuable information
|
||||
that your contribution meets our standards. This is not meant to annoy people but ensures
|
||||
consistency that the project stays maintainable for everyone.
|
||||
|
||||
Steps for contributing to the repository using a merge request:
|
||||
1. If you are new to git, take a bit of time to learn the basics which are very simple, e.g. Google
|
||||
for "git tutorial for non-programmers"
|
||||
1. Fork the upstream repository (Fork button on the top right on the main page of the repository)
|
||||
1. You can start editing files like documentation easily inside gitlab which might be the prefered
|
||||
option for many non-coders
|
||||
1. Clone your fork to your local machine and start working on stuff
|
||||
1. Ensure you push your changes to your fork on gitlab
|
||||
1. When done, go to the `Merge Requests` section on the left sidebar of the upstream repository
|
||||
1. Hit the `New merge request` button
|
||||
1. Select the `master` branch as the source branch
|
||||
1. Select whatever branch you worked, likely `master` if you didn't change that, as the target
|
||||
branch
|
||||
1. Hit `Compare branches and continue`
|
||||
1. Provide a descriptive title of what your change is about
|
||||
1. **USE OUR MR TEMPLATES**
|
||||
1. If you submit a bugfix, use the `Bugfix` tempalte and fill in the sections
|
||||
1. If you submit a new feature, use the `Feature` template and fill in the sections
|
||||
1. If you submit some minor fixes or documentation improvements, there is no template for that.
|
||||
Please provide a expressive description what you did and *why* you did that
|
||||
1. If any of your changes are tied to one or multiple issues, link them in the description
|
||||
1. When done, hit `Submit merge request`
|
||||
|
||||
The maintainers will take a look at your submission and provide their feedback. The intention of
|
||||
this process is to ensure the contribution meets the quality standards. Please also see this is
|
||||
a learning opportunity, especially with your first contribution, if a lot of comments and change
|
||||
requests are being made. The maintainers are open to discuss their suggestions/feedback if
|
||||
reasonable feedback is given back to them.
|
||||
|
||||
Once all discussion is resolved and the involved maintainers approved your submission, it will be
|
||||
merged into master and also included in the next release.
|
||||
|
||||
## Roadmap
|
||||
No concrete roadmap or timeline exists. We want to continue adding support for new games as well as
|
||||
old games (some of the old games supported by BT4 are not supported, yet).
|
||||
32
Dockerfile
Normal file
32
Dockerfile
Normal file
@@ -0,0 +1,32 @@
|
||||
FROM fedora:31
|
||||
|
||||
LABEL description="Build environment for bemanitools"
|
||||
|
||||
RUN yum -y install \
|
||||
git \
|
||||
make \
|
||||
zip \
|
||||
clang \
|
||||
mingw64-gcc.x86_64 \
|
||||
mingw32-gcc.x86_64 \
|
||||
wine.x86_64
|
||||
|
||||
RUN mkdir /bemanitools
|
||||
WORKDIR /bemanitools
|
||||
|
||||
# Order optimized for docker layer caching
|
||||
COPY run-tests-wine.sh run-tests-wine.sh
|
||||
COPY CHANGELOG.md CHANGELOG.md
|
||||
COPY CONTRIBUTING.md CONTRIBUTING.md
|
||||
COPY LICENSE LICENSE
|
||||
COPY GNUmakefile GNUmakefile
|
||||
COPY Module.mk Module.mk
|
||||
COPY README.md README.md
|
||||
COPY doc doc
|
||||
COPY dist dist
|
||||
COPY src src
|
||||
# .git folder required or building fails when version is generated
|
||||
COPY .git .git
|
||||
|
||||
# Building
|
||||
RUN make
|
||||
57
GNUmakefile
57
GNUmakefile
@@ -11,19 +11,24 @@ BUILDDIR ?= build
|
||||
# Internal variables
|
||||
#
|
||||
|
||||
depdir := $(BUILDDIR)/dep
|
||||
objdir := $(BUILDDIR)/obj
|
||||
bindir := $(BUILDDIR)/bin
|
||||
builddir_docker := $(BUILDDIR)/docker
|
||||
|
||||
toolchain_32 := i686-w64-mingw32-
|
||||
toolchain_64 := x86_64-w64-mingw32-
|
||||
docker_container_name := "bemanitools-build"
|
||||
docker_image_name := "bemanitools:build"
|
||||
|
||||
gitrev := $(shell git rev-parse HEAD)
|
||||
cppflags := -I src -I src/main -I src/test -DGITREV=$(gitrev)
|
||||
cflags := -O2 -pipe -ffunction-sections -fdata-sections \
|
||||
-Wall -std=c99
|
||||
cflags_release := -Werror
|
||||
ldflags := -Wl,--gc-sections -static-libgcc
|
||||
depdir := $(BUILDDIR)/dep
|
||||
objdir := $(BUILDDIR)/obj
|
||||
bindir := $(BUILDDIR)/bin
|
||||
|
||||
toolchain_32 := i686-w64-mingw32-
|
||||
toolchain_64 := x86_64-w64-mingw32-
|
||||
|
||||
gitrev := $(shell git rev-parse HEAD)
|
||||
cppflags := -I src -I src/main -I src/test -DGITREV=$(gitrev)
|
||||
cflags := -O2 -pipe -ffunction-sections -fdata-sections \
|
||||
-Wall -std=c99 -DPSAPI_VERSION=1
|
||||
cflags_release := -Werror
|
||||
ldflags := -Wl,--gc-sections -static-libgcc
|
||||
|
||||
#
|
||||
# The first target that GNU Make encounters becomes the default target.
|
||||
@@ -33,6 +38,7 @@ ldflags := -Wl,--gc-sections -static-libgcc
|
||||
all: build
|
||||
|
||||
.PHONY: \
|
||||
build-docker \
|
||||
clean \
|
||||
code-format \
|
||||
print-building \
|
||||
@@ -52,27 +58,36 @@ print-building \
|
||||
version
|
||||
|
||||
print-building:
|
||||
@echo "Build gitrev "$(gitrev)"..."
|
||||
$(V)echo "Build gitrev "$(gitrev)"..."
|
||||
|
||||
print-release:
|
||||
@echo "Starting release build..."
|
||||
$(V)echo "Starting release build..."
|
||||
|
||||
clean:
|
||||
@echo "Cleaning up..."
|
||||
$(V)echo "Cleaning up..."
|
||||
$(V)rm -rf $(BUILDDIR)
|
||||
|
||||
code-format:
|
||||
@echo "Applying clang-format..."
|
||||
# -style=file enables reading .clang-format
|
||||
@find src/ -iname *.h -o -iname *.c | xargs clang-format -i -style=file
|
||||
$(V)echo "Applying clang-format..."
|
||||
$(V)find src/ -name '*.c' -o -name '*.h' | xargs clang-format -i -style=file
|
||||
|
||||
run-tests:
|
||||
@echo "Running tests..."
|
||||
@./run-tests-wine.sh
|
||||
$(V)echo "Running tests..."
|
||||
$(V)./run-tests-wine.sh
|
||||
|
||||
# Generate a version file to identify the build
|
||||
version:
|
||||
@echo "$(gitrev)" > version
|
||||
$(V)echo "$(gitrev)" > version
|
||||
|
||||
build-docker:
|
||||
$(V)docker rm -f $(docker_container_name) 2> /dev/null || true
|
||||
$(V)docker build -t $(docker_image_name) -f Dockerfile .
|
||||
$(V)docker create --name $(docker_container_name) $(docker_image_name)
|
||||
$(V)rm -rf $(builddir_docker)
|
||||
$(V)mkdir -p $(builddir_docker)
|
||||
$(V)docker cp $(docker_container_name):/bemanitools/build $(builddir_docker)
|
||||
$(V)mv $(builddir_docker)/build/* $(builddir_docker)
|
||||
$(V)rm -r $(builddir_docker)/build
|
||||
|
||||
#
|
||||
# Pull in module definitions
|
||||
@@ -241,7 +256,7 @@ impdef_$1_$2_$3 ?= src/imports/import_$1_$2_$3.def
|
||||
|
||||
$$(bindir_$1_$2)/lib$3.a: $$(impdef_$1_$2_$3) | $$(bindir_$1_$2)
|
||||
$(V)echo ... $$@ [dlltool]
|
||||
$(V)$$(toolchain_$1)dlltool -l $$@ -d $$<
|
||||
$(V)$$(toolchain_$1)dlltool --kill-at -l $$@ -d $$<
|
||||
|
||||
endef
|
||||
|
||||
|
||||
188
Module.mk
188
Module.mk
@@ -54,9 +54,11 @@
|
||||
#
|
||||
# 17: Patch 0: beatmania IIDX 25 CANNON BALLERS
|
||||
# beatmania IIDX 26 Rootage
|
||||
# beatmania IIDX 27 HEROIC VERSE
|
||||
#
|
||||
# Patch 3: SOUND VOLTEX VIVID WAVE
|
||||
#
|
||||
#
|
||||
|
||||
cflags += \
|
||||
-DWIN32_LEAN_AND_MEAN \
|
||||
@@ -70,13 +72,18 @@ cflags += \
|
||||
# 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_64 := 1700 1603 1601 1508
|
||||
avsvers_64 := 1700 1603 1601 1509 1508
|
||||
|
||||
imps += avs avs-ea3
|
||||
|
||||
include src/main/aciodrv/Module.mk
|
||||
include src/main/aciodrv-proc/Module.mk
|
||||
include src/main/acioemu/Module.mk
|
||||
include src/main/aciomgr/Module.mk
|
||||
include src/main/aciotest/Module.mk
|
||||
include src/main/asio/Module.mk
|
||||
include src/main/bio2drv/Module.mk
|
||||
include src/main/bio2emu-iidx/Module.mk
|
||||
include src/main/bio2emu/Module.mk
|
||||
include src/main/bsthook/Module.mk
|
||||
include src/main/bstio/Module.mk
|
||||
@@ -84,29 +91,32 @@ 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/Module.mk
|
||||
include src/main/ddrio-smx/Module.mk
|
||||
include src/main/ddrio-mm/Module.mk
|
||||
include src/main/eamio/Module.mk
|
||||
include src/main/ddrio-smx/Module.mk
|
||||
include src/main/ddrio/Module.mk
|
||||
include src/main/dinput/Module.mk
|
||||
include src/main/eamio-icca/Module.mk
|
||||
include src/main/eamio/Module.mk
|
||||
include src/main/eamiotest/Module.mk
|
||||
include src/main/ezusb/Module.mk
|
||||
include src/main/ezusb-emu/Module.mk
|
||||
include src/main/ezusb-iidx/Module.mk
|
||||
include src/main/ezusb-iidx-emu/Module.mk
|
||||
include src/main/ezusb-iidx-fpga-flash/Module.mk
|
||||
include src/main/ezusb-iidx-sram-flash/Module.mk
|
||||
include src/main/ezusb-iidx/Module.mk
|
||||
include src/main/ezusb-tool/Module.mk
|
||||
include src/main/ezusb2/Module.mk
|
||||
include src/main/ezusb/Module.mk
|
||||
include src/main/ezusb2-dbg-hook/Module.mk
|
||||
include src/main/ezusb2-emu/Module.mk
|
||||
include src/main/ezusb2-iidx/Module.mk
|
||||
include src/main/ezusb2-iidx-emu/Module.mk
|
||||
include src/main/ezusb2-iidx/Module.mk
|
||||
include src/main/ezusb2-tool/Module.mk
|
||||
include src/main/ezusb-iidx-emu/Module.mk
|
||||
include src/main/ezusb2/Module.mk
|
||||
include src/main/geninput/Module.mk
|
||||
include src/main/hook/Module.mk
|
||||
include src/main/hooklib/Module.mk
|
||||
include src/main/iidx-bio2-exit-hook/Module.mk
|
||||
include src/main/iidx-ezusb-exit-hook/Module.mk
|
||||
include src/main/iidx-ezusb2-exit-hook/Module.mk
|
||||
include src/main/iidx-irbeat-patch/Module.mk
|
||||
@@ -119,38 +129,48 @@ include src/main/iidxhook5/Module.mk
|
||||
include src/main/iidxhook6/Module.mk
|
||||
include src/main/iidxhook7/Module.mk
|
||||
include src/main/iidxhook8/Module.mk
|
||||
include src/main/iidxio/Module.mk
|
||||
include src/main/iidxhook9/Module.mk
|
||||
include src/main/iidxio-bio2/Module.mk
|
||||
include src/main/iidxio-ezusb/Module.mk
|
||||
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/jbio/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/launcher/Module.mk
|
||||
include src/main/mempatch-hook/Module.mk
|
||||
include src/main/mm/Module.mk
|
||||
include src/main/p3io/Module.mk
|
||||
include src/main/p3ioemu/Module.mk
|
||||
include src/main/p4iodrv/Module.mk
|
||||
include src/main/p4ioemu/Module.mk
|
||||
include src/main/pcbidgen/Module.mk
|
||||
include src/main/sdvxhook/Module.mk
|
||||
include src/main/sdvxhook2/Module.mk
|
||||
include src/main/sdvxhook2-cn/Module.mk
|
||||
include src/main/sdvxio/Module.mk
|
||||
include src/main/sdvxhook2/Module.mk
|
||||
include src/main/sdvxio-bio2/Module.mk
|
||||
include src/main/sdvxio-kfca/Module.mk
|
||||
include src/main/sdvxio/Module.mk
|
||||
include src/main/security/Module.mk
|
||||
include src/main/unicorntail/Module.mk
|
||||
include src/main/util/Module.mk
|
||||
include src/main/vefxio/Module.mk
|
||||
include src/main/vigem-iidxio/Module.mk
|
||||
include src/main/vigem-sdvxio/Module.mk
|
||||
include src/main/vigemstub/Module.mk
|
||||
|
||||
include src/test/cconfig/Module.mk
|
||||
include src/test/d3d9hook/Module.mk
|
||||
include src/test/iidxhook-util/Module.mk
|
||||
include src/test/iidxhook8/Module.mk
|
||||
include src/test/security/Module.mk
|
||||
include src/test/test/Module.mk
|
||||
include src/test/util/Module.mk
|
||||
include src/test/iidxhook8/Module.mk
|
||||
|
||||
#
|
||||
# Distribution build rules
|
||||
@@ -167,8 +187,10 @@ $(zipdir)/tools.zip: \
|
||||
build/bin/indep-32/ezusb-iidx-fpga-flash.exe \
|
||||
build/bin/indep-32/ezusb-iidx-sram-flash.exe \
|
||||
build/bin/indep-32/iidxiotest.exe \
|
||||
build/bin/indep-32/iidx-bio2-exit-hook.dll \
|
||||
build/bin/indep-32/iidx-ezusb-exit-hook.dll \
|
||||
build/bin/indep-32/iidx-ezusb2-exit-hook.dll \
|
||||
build/bin/indep-32/jbiotest.exe \
|
||||
build/bin/indep-32/pcbidgen.exe \
|
||||
dist/iidx/ezusb-boot.bat \
|
||||
dist/iidx/ezusb2-boot.bat \
|
||||
@@ -181,27 +203,24 @@ $(zipdir)/tools.zip: \
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/tools-x64.zip: \
|
||||
build/bin/indep-64/aciotest.exe \
|
||||
build/bin/indep-64/eamiotest.exe \
|
||||
build/bin/indep-64/iidxiotest.exe \
|
||||
build/bin/indep-64/iidx-bio2-exit-hook.dll \
|
||||
build/bin/indep-64/iidx-ezusb-exit-hook.dll \
|
||||
build/bin/indep-64/iidx-ezusb2-exit-hook.dll \
|
||||
build/bin/indep-64/jbiotest.exe \
|
||||
build/bin/indep-64/mempatch-hook.dll \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/src.zip: .git/HEAD $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)git archive -o $@ HEAD
|
||||
|
||||
$(zipdir)/iidx-09-to-12.zip: \
|
||||
build/bin/indep-32/iidxhook1.dll \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
build/bin/indep-32/inject.exe \
|
||||
dist/iidx/config.bat \
|
||||
@@ -225,11 +244,8 @@ $(zipdir)/iidx-13.zip: \
|
||||
build/bin/avs2_0-32/iidxhook2.dll \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
build/bin/indep-32/inject.exe \
|
||||
dist/iidx/config.bat \
|
||||
@@ -244,11 +260,8 @@ $(zipdir)/iidx-14-to-17.zip: \
|
||||
build/bin/avs2_0-32/iidxhook3.dll \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
build/bin/indep-32/inject.exe \
|
||||
dist/iidx/config.bat \
|
||||
@@ -270,11 +283,8 @@ $(zipdir)/iidx-18.zip: \
|
||||
build/bin/avs2_1101-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
dist/iidx/config.bat \
|
||||
dist/iidx/gamestart-18.bat \
|
||||
@@ -289,11 +299,8 @@ $(zipdir)/iidx-19.zip: \
|
||||
build/bin/avs2_1304-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
dist/iidx/config.bat \
|
||||
dist/iidx/gamestart-19.bat \
|
||||
@@ -308,11 +315,8 @@ $(zipdir)/iidx-20.zip: \
|
||||
build/bin/avs2_1508-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
dist/iidx/config.bat \
|
||||
dist/iidx/gamestart-20.bat \
|
||||
@@ -327,11 +331,8 @@ $(zipdir)/iidx-21-to-24.zip: \
|
||||
build/bin/avs2_1601-32/launcher.exe \
|
||||
build/bin/indep-32/config.exe \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/iidxio.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
build/bin/indep-32/vefxio.dll \
|
||||
dist/iidx/config.bat \
|
||||
dist/iidx/gamestart-21.bat \
|
||||
@@ -352,11 +353,8 @@ $(zipdir)/iidx-25-to-26.zip: \
|
||||
build/bin/avs2_1700-64/launcher.exe \
|
||||
build/bin/indep-64/config.exe \
|
||||
build/bin/indep-64/eamio.dll \
|
||||
build/bin/indep-64/eamio-icca.dll \
|
||||
build/bin/indep-64/geninput.dll \
|
||||
build/bin/indep-64/iidxio.dll \
|
||||
build/bin/indep-64/iidxio-ezusb.dll \
|
||||
build/bin/indep-64/iidxio-ezusb2.dll \
|
||||
build/bin/indep-64/vefxio.dll \
|
||||
dist/iidx/config.bat \
|
||||
dist/iidx/gamestart-25.bat \
|
||||
@@ -368,6 +366,50 @@ $(zipdir)/iidx-25-to-26.zip: \
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(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 \
|
||||
build/bin/indep-64/eamio.dll \
|
||||
build/bin/indep-64/geninput.dll \
|
||||
build/bin/indep-64/iidxio.dll \
|
||||
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 ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/iidx-hwio-x86.zip: \
|
||||
build/bin/indep-32/aciomgr.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/iidxio-bio2.dll \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
dist/iidx/iidxio-bio2.conf \
|
||||
build/bin/indep-32/vigem-iidxio.exe \
|
||||
dist/iidx/vigem-iidxio.conf \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/iidx-hwio-x64.zip: \
|
||||
build/bin/indep-64/aciomgr.dll \
|
||||
build/bin/indep-64/eamio-icca.dll \
|
||||
build/bin/indep-64/iidxio-bio2.dll \
|
||||
build/bin/indep-64/iidxio-ezusb.dll \
|
||||
build/bin/indep-64/iidxio-ezusb2.dll \
|
||||
dist/iidx/iidxio-bio2.conf \
|
||||
build/bin/indep-64/vigem-iidxio.exe \
|
||||
dist/iidx/vigem-iidxio.conf \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/jb-01.zip: \
|
||||
build/bin/avs2_803-32/jbhook1.dll \
|
||||
build/bin/indep-32/inject.exe \
|
||||
@@ -408,6 +450,17 @@ $(zipdir)/jb-08.zip: \
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/jb-hwio.zip: \
|
||||
build/bin/indep-32/aciomgr.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/jbio-magicbox.dll \
|
||||
build/bin/indep-32/jbio-p4io.dll \
|
||||
dist/jb/jbio-h44b.conf \
|
||||
dist/jb/eamio-icc.conf \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/sdvx-01-to-04.zip: \
|
||||
build/bin/avs2_1508-32/launcher.exe \
|
||||
build/bin/avs2_1508-32/sdvxhook.dll \
|
||||
@@ -415,7 +468,6 @@ $(zipdir)/sdvx-01-to-04.zip: \
|
||||
build/bin/indep-32/eamio.dll \
|
||||
build/bin/indep-32/geninput.dll \
|
||||
build/bin/indep-32/sdvxio.dll \
|
||||
build/bin/indep-32/sdvxio-kfca.dll \
|
||||
dist/sdvx/config.bat \
|
||||
dist/sdvx/gamestart.bat \
|
||||
| $(zipdir)/
|
||||
@@ -429,7 +481,6 @@ $(zipdir)/sdvx-05.zip: \
|
||||
build/bin/indep-64/eamio.dll \
|
||||
build/bin/indep-64/geninput.dll \
|
||||
build/bin/indep-64/sdvxio.dll \
|
||||
build/bin/indep-64/sdvxio-kfca.dll \
|
||||
dist/sdvx5/config.bat \
|
||||
dist/sdvx5/gamestart.bat \
|
||||
dist/sdvx5/sdvxhook2.conf \
|
||||
@@ -451,6 +502,26 @@ $(zipdir)/sdvx-05-cn.zip: \
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/sdvx-hwio-x86.zip: \
|
||||
build/bin/indep-32/aciomgr.dll \
|
||||
build/bin/indep-32/eamio-icca.dll \
|
||||
build/bin/indep-32/sdvxio-kfca.dll \
|
||||
build/bin/indep-32/sdvxio-bio2.dll \
|
||||
build/bin/indep-32/vigem-sdvxio.exe \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/sdvx-hwio-x64.zip: \
|
||||
build/bin/indep-64/aciomgr.dll \
|
||||
build/bin/indep-64/eamio-icca.dll \
|
||||
build/bin/indep-64/sdvxio-kfca.dll \
|
||||
build/bin/indep-64/sdvxio-bio2.dll \
|
||||
build/bin/indep-64/vigem-sdvxio.exe \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/ddr-12-to-16.zip: \
|
||||
build/bin/avs2_1508-32/launcher.exe \
|
||||
build/bin/avs2_1508-32/ddrhook.dll \
|
||||
@@ -471,6 +542,22 @@ $(zipdir)/ddr-12-to-16.zip: \
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/ddr-16-x64.zip: \
|
||||
build/bin/avs2_1603-64/launcher.exe \
|
||||
build/bin/avs2_1603-64/ddrhook.dll \
|
||||
build/bin/avs2_1603-64/unicorntail.dll \
|
||||
build/bin/indep-64/config.exe \
|
||||
build/bin/indep-64/ddrio.dll \
|
||||
build/bin/indep-64/ddrio-mm.dll \
|
||||
build/bin/indep-64/ddrio-smx.dll \
|
||||
build/bin/indep-64/eamio.dll \
|
||||
build/bin/indep-64/geninput.dll \
|
||||
dist/ddr/config.bat \
|
||||
dist/ddr/gamestart-16.bat \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/bst.zip: \
|
||||
build/bin/avs2_1603-64/bsthook.dll \
|
||||
build/bin/avs2_1603-64/launcher.exe \
|
||||
@@ -486,10 +573,7 @@ $(zipdir)/bst.zip: \
|
||||
$(V)zip -j $@ $^
|
||||
|
||||
$(zipdir)/doc.zip: \
|
||||
doc/iidxhook \
|
||||
doc/sdvxhook \
|
||||
doc/jbhook \
|
||||
doc/tools \
|
||||
doc/ \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -r $@ $^
|
||||
@@ -523,6 +607,7 @@ $(BUILDDIR)/tests.zip: \
|
||||
$(BUILDDIR)/bemanitools.zip: \
|
||||
$(zipdir)/bst.zip \
|
||||
$(zipdir)/ddr-12-to-16.zip \
|
||||
$(zipdir)/ddr-16-x64.zip \
|
||||
$(zipdir)/doc.zip \
|
||||
$(zipdir)/iidx-09-to-12.zip \
|
||||
$(zipdir)/iidx-13.zip \
|
||||
@@ -532,13 +617,18 @@ $(BUILDDIR)/bemanitools.zip: \
|
||||
$(zipdir)/iidx-20.zip \
|
||||
$(zipdir)/iidx-21-to-24.zip \
|
||||
$(zipdir)/iidx-25-to-26.zip \
|
||||
$(zipdir)/iidx-27-to-28.zip \
|
||||
$(zipdir)/iidx-hwio-x86.zip \
|
||||
$(zipdir)/iidx-hwio-x64.zip \
|
||||
$(zipdir)/jb-01.zip \
|
||||
$(zipdir)/jb-05-to-07.zip \
|
||||
$(zipdir)/jb-08.zip \
|
||||
$(zipdir)/src.zip \
|
||||
$(zipdir)/jb-hwio.zip \
|
||||
$(zipdir)/sdvx-01-to-04.zip \
|
||||
$(zipdir)/sdvx-05.zip \
|
||||
$(zipdir)/sdvx-05-cn.zip \
|
||||
$(zipdir)/sdvx-hwio-x86.zip \
|
||||
$(zipdir)/sdvx-hwio-x64.zip \
|
||||
$(zipdir)/tools.zip \
|
||||
$(zipdir)/tools-x64.zip \
|
||||
CHANGELOG.md \
|
||||
|
||||
77
README.md
77
README.md
@@ -1,7 +1,8 @@
|
||||
# Bemanitools 5
|
||||
[](https://dev.s-ul.eu/djhackers/bemanitools/commits/master)
|
||||
[](https://dev.s-ul.net/djhackers/bemanitools/commits/master)
|
||||
|
||||
Version: 5.36
|
||||
|
||||
Version: 5.29</br>
|
||||
[Release history](CHANGELOG.md)
|
||||
|
||||
A collection of tools to run [various Bemani arcade games](#list-of-supported-games).
|
||||
@@ -11,7 +12,21 @@ BT5 uses a cleaner approach than BT4 did; specifically, all input and lighting i
|
||||
spoken by the real IO PCBs, instead of replacing chunks of game code like BT4. The benefits of this approach are a more
|
||||
authentic gameplay experience, and easier support for a broader range of releases from each game series.
|
||||
|
||||
# List of supported games
|
||||
## Documentation
|
||||
Browse our [documentation](doc/README.md) as it might already cover various questions and concerns
|
||||
you are looking for or about to ask.
|
||||
|
||||
## Contributions and bug reporting
|
||||
[Read the dedicated CONTRIBUTING.md documentation](CONTRIBUTING.md).
|
||||
|
||||
The tl;dr version and golden rules of the sections in the document:
|
||||
* **EVERYONE** can contribute, this is **NOT** limited to people coding
|
||||
* [Open an issue on gitlab for discussions, feature requests and bug reports](CONTRIBUTING.md#reporting-and-discussions-issues-section-on-github)
|
||||
* [ALWAYS report bugs as issues and ALWAYS use the available bug template](CONTRIBUTING.md#bug-reports)
|
||||
* [Everyone is allowed to submit changes which are not just limited to code by opening merge requests](CONTRIBUTING.md#pull-requests-bugfixes-new-features-or-other-code-contributions)
|
||||
* [Documentation improvements can and even should be contributed by non developers](CONTRIBUTING.md#pull-requests-bugfixes-new-features-or-other-code-contributions)
|
||||
|
||||
## List of supported games (hook libraries)
|
||||
* BeatStream
|
||||
* BeatStream (bst.zip) using bsthook
|
||||
* BeatStream アニムトライヴ (bst.zip) using bsthook
|
||||
@@ -40,6 +55,8 @@ authentic gameplay experience, and easier support for a broader range of release
|
||||
* 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-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
|
||||
@@ -53,13 +70,19 @@ authentic gameplay experience, and easier support for a broader range of release
|
||||
* SOUND VOLTEX IV HEAVENLY HAVEN (sdvx-01-to-04.zip) using sdvxhook
|
||||
* SOUND VOLTEX Vivid Wave (sdvx-05.zip) using sdvxhook2
|
||||
|
||||
# Supported platforms
|
||||
## 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
|
||||
implements BT5 APIs.
|
||||
|
||||
See the dedicated [readme](doc/vigem/README.md) for details.
|
||||
|
||||
## Supported platforms
|
||||
Our main platforms are currently Windows XP and Windows 7 which are also the target platforms on the original hardware
|
||||
of those games. However, as it gets more difficult to get and maintain hardware comptible with Windows XP, this might
|
||||
change in the future. Many games also run on very recent Windows 10 builds but bear with us that it's hard to keep up
|
||||
with Windows updates breaking legacy software.
|
||||
|
||||
# Distribution contents
|
||||
## Distribution contents
|
||||
Check the [list of supported games](#list-of-supported-games) to grab the right files for your game. BT5 also includes
|
||||
a *tools* subpackage (tools.zip) as well as the full source code (src.zip).
|
||||
|
||||
@@ -67,7 +90,7 @@ You will find *.md files in various sub-packages that give you further instructi
|
||||
or FAQ. We advice you to read them as your questions and concerns might already be answered by them. If not, let us
|
||||
know if there is any information that you consider helpful or important to know and should be added.
|
||||
|
||||
# Setup and dependencies
|
||||
## Setup and dependencies
|
||||
Most (older generation) games were developed for Windows XP Embedded but should run fine on any
|
||||
consumer version of Windows XP. Newer versions of Windows, e.g. Windows 7, 8 and 10, should be fine
|
||||
as well. Some hooks also include fixes required to run the games on a more recent version.
|
||||
@@ -77,22 +100,46 @@ Depending on the game, you also need the following dependencies installed:
|
||||
* Microsoft Visual C++ Redistributables 2010 **and** 2013: Depends on the game and age but both
|
||||
should cover most if not all of the games so far
|
||||
|
||||
# Contributions
|
||||
Please refer to the [dedicated documentation](CONTRIBUTING.md).
|
||||
## Development
|
||||
### Building
|
||||
See the [development document](doc/development.md).
|
||||
|
||||
# Development
|
||||
## Architecture
|
||||
### Architecture
|
||||
A dedicate [architecture document](doc/architecture.md) outlines the architecture of Bemanitools and points out the most
|
||||
important aspects you should know before you get started with development.
|
||||
|
||||
## API
|
||||
### API
|
||||
Please refer to the [API documentation](doc/api.md).
|
||||
|
||||
## Source Code
|
||||
The source code is included with this distribution package (src.zip). Please refer to the
|
||||
[development document](doc/development.md) for further details.
|
||||
## Release process
|
||||
Steps for the release process:
|
||||
1. Update the corresponding section in the [changelog](CHANGELOG.md) with bullet points reflecting
|
||||
major features merged into master since the previous release
|
||||
1. Make sure you have the latest `master` state pulled to your local copy
|
||||
1. Tag the release with the next release number which also be found at the
|
||||
[top of the readme](#bemanitools-5) as it always reflects the current version beinged worked on
|
||||
on the `master` branch , e.g. 5.35: `git tag 5.35`
|
||||
1. Push the tag to upstream: `git push origin 5.35`
|
||||
1. The [build pipeline](https://dev.s-ul.net/djhackers/bemanitools/-/pipelines) should start
|
||||
automatically once the tag is pushed including the steps `build` and `upload-release`
|
||||
1. Once completed successfully, the release is uploaded
|
||||
1. Take the changelog of the published version and notify the pigs in the stall about it:
|
||||
1. New post in thread
|
||||
```
|
||||
<insert version here> released: <direct link to published version>
|
||||
|
||||
# License
|
||||
Changelog:
|
||||
<paste changelog here>
|
||||
```
|
||||
1. Update the OP title by bumping the version number in it
|
||||
1. Update the OP post by extending it accordingly (see previous entries)
|
||||
|
||||
1. Bump the version number at the [top of this readme](#bemanitools-5) and add a new empty section
|
||||
in the [changelog](CHANGELOG.md) with the new version number as title. Commit changes and push to
|
||||
`master` branch
|
||||
1. Continue developing and merging MRs until you decide its time for another release
|
||||
|
||||
## License
|
||||
Source code license is the Unlicense; you are permitted to do with this as thou wilt. For details, please refer to the
|
||||
[LICENSE file](LICENSE) included with the source code.
|
||||
|
||||
|
||||
16
dist/iidx/gamestart-27.bat
vendored
Normal file
16
dist/iidx/gamestart-27.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-27.conf %*
|
||||
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 %*
|
||||
6
dist/iidx/iidxhook-18.conf
vendored
6
dist/iidx/iidxhook-18.conf
vendored
@@ -36,3 +36,9 @@ gfx.forced_refresh_rate=-1
|
||||
|
||||
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
|
||||
gfx.device_adapter=-1
|
||||
|
||||
# Disable card reader emulation and enable usage of real card reader hardware on COM1 (for games supporting slotted/wavepass readers)
|
||||
io.disable_card_reader_emu=false
|
||||
|
||||
# Disable ezusb IO emulation and enable usage of real ezusb1/2 IO hardware
|
||||
io.disable_io_emu=false
|
||||
6
dist/iidx/iidxhook-19.conf
vendored
6
dist/iidx/iidxhook-19.conf
vendored
@@ -33,3 +33,9 @@ gfx.forced_refresh_rate=-1
|
||||
|
||||
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
|
||||
gfx.device_adapter=-1
|
||||
|
||||
# Disable card reader emulation and enable usage of real card reader hardware on COM1 (for games supporting slotted/wavepass readers)
|
||||
io.disable_card_reader_emu=false
|
||||
|
||||
# Disable ezusb IO emulation and enable usage of real ezusb1/2 IO hardware
|
||||
io.disable_io_emu=false
|
||||
6
dist/iidx/iidxhook-20.conf
vendored
6
dist/iidx/iidxhook-20.conf
vendored
@@ -33,3 +33,9 @@ gfx.forced_refresh_rate=-1
|
||||
|
||||
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
|
||||
gfx.device_adapter=-1
|
||||
|
||||
# Disable card reader emulation and enable usage of real card reader hardware on COM1 (for games supporting slotted/wavepass readers)
|
||||
io.disable_card_reader_emu=false
|
||||
|
||||
# Disable ezusb IO emulation and enable usage of real ezusb1/2 IO hardware
|
||||
io.disable_io_emu=false
|
||||
6
dist/iidx/iidxhook-21.conf
vendored
6
dist/iidx/iidxhook-21.conf
vendored
@@ -33,3 +33,9 @@ gfx.forced_refresh_rate=-1
|
||||
|
||||
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
|
||||
gfx.device_adapter=-1
|
||||
|
||||
# Disable card reader emulation and enable usage of real card reader hardware on COM1 (for games supporting slotted/wavepass readers)
|
||||
io.disable_card_reader_emu=false
|
||||
|
||||
# Disable ezusb IO emulation and enable usage of real ezusb1/2 IO hardware
|
||||
io.disable_io_emu=false
|
||||
6
dist/iidx/iidxhook-22.conf
vendored
6
dist/iidx/iidxhook-22.conf
vendored
@@ -33,3 +33,9 @@ gfx.forced_refresh_rate=-1
|
||||
|
||||
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
|
||||
gfx.device_adapter=-1
|
||||
|
||||
# Disable card reader emulation and enable usage of real card reader hardware on COM1 (for games supporting slotted/wavepass readers)
|
||||
io.disable_card_reader_emu=false
|
||||
|
||||
# Disable ezusb IO emulation and enable usage of real ezusb1/2 IO hardware
|
||||
io.disable_io_emu=false
|
||||
6
dist/iidx/iidxhook-23.conf
vendored
6
dist/iidx/iidxhook-23.conf
vendored
@@ -33,3 +33,9 @@ gfx.forced_refresh_rate=-1
|
||||
|
||||
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
|
||||
gfx.device_adapter=-1
|
||||
|
||||
# Disable card reader emulation and enable usage of real card reader hardware on COM1 (for games supporting slotted/wavepass readers)
|
||||
io.disable_card_reader_emu=false
|
||||
|
||||
# Disable ezusb IO emulation and enable usage of real ezusb1/2 IO hardware
|
||||
io.disable_io_emu=false
|
||||
6
dist/iidx/iidxhook-24.conf
vendored
6
dist/iidx/iidxhook-24.conf
vendored
@@ -33,3 +33,9 @@ gfx.forced_refresh_rate=-1
|
||||
|
||||
# D3D9 device adapter (monitor), -1 to use default, 0, 1, 2 etc. to use specified adapter
|
||||
gfx.device_adapter=-1
|
||||
|
||||
# Disable card reader emulation and enable usage of real card reader hardware on COM1 (for games supporting slotted/wavepass readers)
|
||||
io.disable_card_reader_emu=false
|
||||
|
||||
# Disable ezusb IO emulation and enable usage of real ezusb1/2 IO hardware
|
||||
io.disable_io_emu=false
|
||||
78
dist/iidx/iidxhook-27.conf
vendored
Normal file
78
dist/iidx/iidxhook-27.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=false
|
||||
|
||||
# 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=false
|
||||
|
||||
# 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)
|
||||
|
||||
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)
|
||||
|
||||
8
dist/iidx/iidxio-bio2.conf
vendored
Normal file
8
dist/iidx/iidxio-bio2.conf
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Autodetect BIO2 port (default: on)
|
||||
bio2.autodetect=true
|
||||
|
||||
# BIO2 serial port. Optional, if autodetect property is turned on
|
||||
bio2.port=COM4
|
||||
|
||||
# BIO2 bus baudrate (real devices expect 115200)
|
||||
bio2.baud=115200
|
||||
26
dist/iidx/vigem-iidxio.conf
vendored
Normal file
26
dist/iidx/vigem-iidxio.conf
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# Use relative mode analog mapping instead of absolute analog values
|
||||
vigem.iidxio.tt.anlog.relative=false
|
||||
|
||||
# Sensitivity value for relative mode (1 to 32767). Tweak if you are having issues with jittering/misfiring/unresponsiveness
|
||||
vigem.iidxio.tt.anlog.relative_sensitivity=1024
|
||||
|
||||
# Button turntable: "debounce" value (1 to 50, recommend 20). Tweak if you are having issues with TT button misfiring/unresponsiveness
|
||||
vigem.iidxio.tt.button.debounce=20
|
||||
|
||||
# Button turntable: minimum ticks required within (debounce * 2) ms to register movement (1 to 4, recommend 2). Tweak if you button input is too (un-) responsive
|
||||
vigem.iidxio.tt.button.threshold=2
|
||||
|
||||
# Print verbose debug output to the console for debugging turntable sensitivity issues
|
||||
vigem.iidxio.tt.debug_output=false
|
||||
|
||||
# Enable input based key lighting
|
||||
vigem.iidxio.cab_light.enable_keylight=true
|
||||
|
||||
# Different cabinet light modes: 0 = off, 1 = neons sequence, 2 = neons flash on TT spin
|
||||
vigem.iidxio.cab_light.light_mode=0
|
||||
|
||||
# Display text on 16seg. If text exceeds 9 char display limit, it will scroll + cycle
|
||||
vigem.iidxio.cab_light.text_16seg=
|
||||
|
||||
# Cycle time/scroll speed for text exceeding 16seg display length (9) to scroll from right
|
||||
vigem.iidxio.cab_light.text_scroll_cycle_time_ms=500
|
||||
5
dist/jb/eamio-icc.conf
vendored
Normal file
5
dist/jb/eamio-icc.conf
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# ICCA serial port
|
||||
icc.port=COM2
|
||||
|
||||
# ICCA bus baudrate (real devices expect 57600)
|
||||
icc.baud=57600
|
||||
2
dist/jb/gamestart.bat
vendored
2
dist/jb/gamestart.bat
vendored
@@ -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 -K jbhook.dll jubeat.dll
|
||||
launcher -H 33554432 -K jbhook.dll jubeat.dll
|
||||
|
||||
5
dist/jb/jbio-h44b.conf
vendored
Normal file
5
dist/jb/jbio-h44b.conf
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# H44B serial port
|
||||
h44b.port=COM2
|
||||
|
||||
# H44B bus baudrate (real devices expect 57600)
|
||||
h44b.baud=57600
|
||||
15
dist/sdvx5/sdvxhook2.conf
vendored
15
dist/sdvx5/sdvxhook2.conf
vendored
@@ -7,18 +7,33 @@ io.disable_bio2_emu=false
|
||||
# Disables the poll limiter, warning very high CPU usage may arise
|
||||
io.disable_poll_limiter=false
|
||||
|
||||
# Forces game to think headphones are attached
|
||||
io.force_headphones=false
|
||||
|
||||
# Disables the built in file hooks, requiring manual file creation (/dev/raw/j.dest)
|
||||
io.disable_file_hooks=false
|
||||
|
||||
# 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=1080
|
||||
|
||||
# Windowed height, -1 for default size
|
||||
gfx.window_height=1920
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
29
doc/README.md
Normal file
29
doc/README.md
Normal file
@@ -0,0 +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
|
||||
* 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
|
||||
* 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
|
||||
|
||||
## 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
|
||||
@@ -22,12 +22,15 @@ The following implementations are already shipped with BT5.
|
||||
* ddrio-smx.dll: StepManiaX platforms
|
||||
* Beatmania IIDX
|
||||
* iidxio.dll (default): Keyboard, joystick and mouse input
|
||||
* iidxio-ezusb.dll: Ezusb (C02 IO) driver
|
||||
* iidxio-ezusb2.dll: Ezusb FX2 (IO2) driver
|
||||
* [iidxio-bio2.dll](iidxhook/iidxio-bio2.md): BIO2 driver
|
||||
* [iidxio-ezusb.dll](iidxhook/iidxio-ezusb.md): Ezusb (C02 IO) driver
|
||||
* [iidxio-ezusb2.dll](iidxhook/iidxio-ezusb2.md): Ezusb FX2 (IO2) driver
|
||||
* jubeat
|
||||
* jbio.dll (default): Keyboard, joystick and mouse input
|
||||
* SOUND VOLTEX
|
||||
* sdvxio.dll (default): Keyboard, joystick and mouse input
|
||||
* [sdvxio-bio2.dll](sdvxhook/sdvxio-bio2.md): BIO2 driver
|
||||
* [sdvxio-kfca.dll](sdvxhook/sdvxio-kfca.md): KFCA IO board driver
|
||||
|
||||
Eamuse hardware support is implemented separately:
|
||||
* eamio.dll (default): Keyboard and joystick input
|
||||
|
||||
14
doc/ddrhook/ddrio-smx.md
Normal file
14
doc/ddrhook/ddrio-smx.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Using SMX pads with BemaniTools (DDR Ace and higher)
|
||||
If you are looking to use StepManiaX pads with DDR, these are supported **natively** for Gen 1 through Gen 5.(And theoretically beyond!) Steps and info below
|
||||
|
||||
## Step-by-Step
|
||||
1. Ensure that you have the latest `SMX.dll` copied to your contents folder. The easiest way to get this is to download and install the latest SMX Config program on [StepManiaX.com](https://data.stepmaniax.com/docs/SMXConfigInstaller-2020-04-03-01.exe). `SMX.dll`'s default install location is `C:\Program Files (x86)\SMXConfig`
|
||||
2. After bemanitools has been copied to your contents folder, rename the regular `ddrio.dll` to something like `ddrio-orig.dll`.
|
||||
3. Rename `ddrio-smx.dll` to `ddrio.dll`.
|
||||
4. Use the config tool to set up the usual stuff.(cards, network, etc.) Be sure to map menu, test, service, and start buttons to your keyboard or other controllers. You **cannot** map SMX panels as joystick inputs.
|
||||
5. Start the game. If everything works properly, the game will boot and your panels will light up when stepped on during gameplay and song selection.
|
||||
|
||||
## Important Things
|
||||
* Pad panel inputs (UDLR on P1 and P2) are mapped automatically. If you've purchased a single pad from StepManiaX, this jumper is installed and will set your pad to P2 by default. If you want to change to P1, you'll need to open up your pads and remove this jumper in the [MCU box](https://data.stepmaniax.com/docs/Stage%20-%20Gen%205%20Manual%20Rev1.pdf).
|
||||
* Panel colors set in the SMX config tool are not used. Colors are set internally by Bemanitools.
|
||||
* If you get a warning about setlights2 when starting the game, your `SMX.dll` is likely out of date. Make sure you've downloaded the latest version of the StepManiaX config tool from stepmaniax.com and have copied the `SMX.dll` to your contents folder.
|
||||
3
doc/dev/README.md
Normal file
3
doc/dev/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Development documentation and notes
|
||||
This folder contains various lose documentation snippets created by the developers. These can be
|
||||
helpful as future reference.
|
||||
192
doc/dev/acio-bio2-iidx-package-dump.md
Normal file
192
doc/dev/acio-bio2-iidx-package-dump.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# ACIO BIO2 IIDX package dump
|
||||
Package dump excerpt of the init sequence of a original Konami IIDX BIO2 with sub IO connected.
|
||||
This was used to identify a missing piece of information that needs to be communicated to the BIO2
|
||||
for IIDX to initialize the sub IO correctly.
|
||||
|
||||
The dump was cut off after two polls as the sequence just keeps on repeating from that point on.
|
||||
|
||||
## Findings for problem to solve
|
||||
With the previous implemention of the BIO2 driver, which was created off references of SDVX KFCA,
|
||||
a BIO2 used with IIDX and the sub IO (to upgrade older C02, IO2 cabinets) connected didn't
|
||||
initialize properly. This resulted in no inputs/outputs other than 14 keys working.
|
||||
|
||||
The problem identified was a different byte, exact meaning not known, that is sent in
|
||||
[exchange 4](#exchange-4-ac-io-cmd-clear). Instead of `0x3B` from the SDVX KFCA based
|
||||
implementation, it needs to be set to `0x2D`.
|
||||
|
||||
## Exchange 1: AC_IO_CMD_ASSIGN_ADDRS
|
||||
### Write
|
||||
```text
|
||||
AA 00 00 01 00 01 00 02
|
||||
|
||||
AA: SOF
|
||||
00: addr
|
||||
0001: AC_IO_CMD_ASSIGN_ADDRS
|
||||
00: seq_no
|
||||
01: nbytes
|
||||
data: 00
|
||||
02: checksum
|
||||
```
|
||||
|
||||
### Read
|
||||
```
|
||||
AA AA 00 00 01 00 01 01 03
|
||||
|
||||
AA: SOF
|
||||
AA: SOF
|
||||
00: addr
|
||||
0001: addr
|
||||
00: seq_no
|
||||
01: nbytes
|
||||
01: data
|
||||
03: checksum
|
||||
```
|
||||
|
||||
## Exchange 2: AC_IO_CMD_GET_VERSION
|
||||
### Write
|
||||
```
|
||||
AA 01 00 02 00 00 03
|
||||
|
||||
AA: SOF
|
||||
01: addr, node 1
|
||||
0002: AC_IO_CMD_GET_VERSION
|
||||
00: seq_no
|
||||
00: nbytes
|
||||
03: checksum
|
||||
```
|
||||
|
||||
### Read
|
||||
```
|
||||
AA AA 81 00 02 00 2C 0D 06 00 00 ...
|
||||
|
||||
AA: SOF
|
||||
AA: SOF
|
||||
81: Response flag + node 1
|
||||
0002: AC_IO_CMD_GET_VERSION
|
||||
00: seq_no
|
||||
2C: nbytes
|
||||
0D 06 00 00 ...: data
|
||||
XX: checksum
|
||||
```
|
||||
|
||||
## Exchange 3: AC_IO_CMD_START_UP
|
||||
### Write
|
||||
```
|
||||
AA 01 00 03 00 00 04
|
||||
|
||||
AA: SOF
|
||||
01: addr
|
||||
0003: AC_IO_CMD_START_UP
|
||||
00: seq_no
|
||||
00: nbytes
|
||||
04: checksum
|
||||
```
|
||||
|
||||
### Read
|
||||
```
|
||||
AA AA 81 00 03 00 01 00 85
|
||||
|
||||
AA: SOF
|
||||
AA: SOF
|
||||
81: Response flag + node 1
|
||||
0003: AC_IO_CMD_START_UP
|
||||
00: seq_no
|
||||
01: nbytes
|
||||
00: data
|
||||
85: checksum
|
||||
```
|
||||
|
||||
## Exchange 4: AC_IO_CMD_CLEAR
|
||||
### Write
|
||||
```
|
||||
AA 01 01 00 00 01 2D 30
|
||||
|
||||
AA: SOF
|
||||
01: addr
|
||||
0100: AC_IO_CMD_CLEAR
|
||||
00: seq_no
|
||||
01: nbytes
|
||||
2D: data
|
||||
30: checksum
|
||||
```
|
||||
|
||||
### Read
|
||||
```
|
||||
AA AA 81 01 00 00 01 00 83
|
||||
|
||||
AA: SOF
|
||||
AA: SOF
|
||||
81: Response flag + node 1
|
||||
0100: AC_IO_CMD_CLEAR
|
||||
00: seq_no
|
||||
01: nbytes
|
||||
00: data
|
||||
83: checksum
|
||||
```
|
||||
|
||||
## Exchange 5: BIO2_BI2A_CMD_WATCHDOG
|
||||
### Write
|
||||
```
|
||||
AA 01 01 20 00 02 00 00 24
|
||||
|
||||
AA: SOF
|
||||
01: addr
|
||||
0120: BIO2_BI2A_CMD_WATCHDOG
|
||||
00: seq_no
|
||||
02: nbytes
|
||||
00 00: data
|
||||
24: checksum
|
||||
```
|
||||
|
||||
### Read
|
||||
```
|
||||
AA AA 81 01 20 00 01 00 A3
|
||||
|
||||
AA: SOF
|
||||
AA: SOF
|
||||
81: Response flag + node 1
|
||||
0120: BIO2_BI2A_CMD_WATCHDOG
|
||||
00: seq_no
|
||||
01: nbytes
|
||||
00: data
|
||||
A3: checksum
|
||||
```
|
||||
|
||||
## Exchange 6: BIO2_BI2A_CMD_POLL
|
||||
### Write
|
||||
```
|
||||
AA 01 01 52 00 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 84
|
||||
|
||||
AA: SOF
|
||||
01: addr
|
||||
0152: BIO2_BI2A_CMD_POLL
|
||||
00: seq_no
|
||||
30: nbtes
|
||||
...: data
|
||||
84: checksum
|
||||
```
|
||||
|
||||
### Read
|
||||
```
|
||||
AA AA 81 01 52 00 2E 00 00 B0 00 F0 00 F0 F0 00 00 00 00 00 02 00 5F 11 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F3
|
||||
|
||||
AA: SOF
|
||||
AA: SOF
|
||||
81: Response flag + node 1
|
||||
0152: BIO2_BI2A_CMD_POLL
|
||||
00: seq_no
|
||||
2E: nbytes
|
||||
...: data
|
||||
F3: checksum
|
||||
```
|
||||
|
||||
## Exchange 7: BIO2_BI2A_CMD_POLL
|
||||
### Write
|
||||
```
|
||||
AA 01 01 52 00 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 84
|
||||
```
|
||||
|
||||
### Read
|
||||
```
|
||||
AA AA 81 01 52 00 2E 00 00 B0 00 F0 00 F0 F0 00 00 00 00 00 02 00 64 11 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 F8
|
||||
```
|
||||
@@ -58,6 +58,18 @@ command:
|
||||
make release
|
||||
```
|
||||
|
||||
## Building with docker
|
||||
You can also build bemanitools using docker which avoids having to setup a full development
|
||||
environment if you are just interested in building binaries for the latest changes. Naturally, this
|
||||
requires you to have the docker daemon installed. Then, run the following command from the root
|
||||
folder of the project:
|
||||
|
||||
```bash
|
||||
make build-docker
|
||||
```
|
||||
|
||||
Once completed successfully, the build output is located in the `build/docker` sub-folder.
|
||||
|
||||
## Creating releases
|
||||
For developers to create official releases with major and minor versioning:
|
||||
1. Ensure that all everything you want to have for this release is merged into master.
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
# iidxhook
|
||||
|
||||
iidxhook is a collection of hook libraries for BeatmaniaIIDX providing
|
||||
emulation and various patches to run these games on non BemaniPC hardware and
|
||||
newer Windows versions.
|
||||
@@ -9,8 +8,7 @@ The hook libraries must be bootstrapped either using [inject](../inject.md) or
|
||||
instructions are given in dedicated readme files for each iidxhook version
|
||||
(see below).
|
||||
|
||||
# Versions
|
||||
|
||||
## Versions
|
||||
iidxhook 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
|
||||
@@ -23,14 +21,14 @@ games:
|
||||
* [iidxhook6](iidxhook6.md): Tricoro
|
||||
* [iidxhook7](iidxhook7.md): SPADA, PENDUAL, copula, SINOBUZ
|
||||
* [iidxhook8](iidxhook8.md): CANNON BALLERS, Rootage
|
||||
* [iidxhook8](iidxhook9.md): Heroic Verse
|
||||
|
||||
When building kactools, 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
|
||||
binary patches.
|
||||
|
||||
# How to run
|
||||
|
||||
## 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
|
||||
important parameters configured. Further parameters can be added but might not
|
||||
@@ -38,7 +36,15 @@ 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.
|
||||
|
||||
# Command line options
|
||||
|
||||
## Command line options
|
||||
Add the argument *-h* when running inject with iidxhook to print help/usage
|
||||
information with a list of parameters you can apply to tweak various things.
|
||||
|
||||
## iidxio API
|
||||
Available implementations that can be swapped out depending on which kind of
|
||||
IO hardware you want to use:
|
||||
* `iidxio`: Default implementation supporting keyboard, mouse and USB
|
||||
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
|
||||
@@ -126,6 +126,16 @@ happens, run the game again.
|
||||
|
||||
# Troubleshooting and FAQ
|
||||
|
||||
## The game is running (very) slow in fullscreen mode but is fine in window mode
|
||||
If you are using a AMD GPU, try disabling "GPU scaling" which you can find in AMD
|
||||
settings UI under "Settings" -> "Display".
|
||||
|
||||
This issue only observed on 9th Style so far.
|
||||
|
||||
Use
|
||||
[bemanitool's built in upscaling feature](#over-underscan-bad-image-quality-or-latency-caused-by-my-monitorsTV-upscaler) if the game is not
|
||||
scaled properly in full screen.
|
||||
|
||||
## Window mode or any other gfx related options do not work when changing them in the config file or using cmd args
|
||||
|
||||
See [this](#Use-d3d8to9-wrapper) section.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -85,17 +85,29 @@ cycle the machine (i.e. quit the game and restart it).
|
||||
|
||||
## USB IO (ezusb)
|
||||
|
||||
Use the specific iidxio API implementations, e.g. iidxio-ezusb2.dll to use
|
||||
the IO2 EZUSB board, to run the game on real hardware. Thanks to a common
|
||||
abstraction layer, you can also use custom IO boards or whatever Konami hardware
|
||||
is going to be available in the future. Obviously, someone has to write a
|
||||
driver, first.
|
||||
You have the following options:
|
||||
* Set `io.disable_io_emu=true` in the `iidxhook.conf` file to not hook ezusb
|
||||
IO communication with an emulation layer. The game will directly talk to the IO.
|
||||
The game supports the ezusb (C02) as well as ezusb FX2 (IO2) boards.
|
||||
* Set `io.disable_io_emu=false` in the `iidxhook.conf` file.
|
||||
Use the specific iidxio API implementations, e.g. `iidxio-ezusb2.dll` to use
|
||||
the IO2 EZUSB board. The common `iidxio` abstraction layer also allows you to
|
||||
use custom IO boards or whatever Konami hardware is going to be available in
|
||||
the future. Obviously, someone has to write an imlementation of the `iidxio`
|
||||
API, first.
|
||||
|
||||
## Slotted/Wave pass card readers
|
||||
|
||||
Replace the default *eamio.dll* with the *eamio-icca.dll* and have either your
|
||||
You have the following options:
|
||||
* Set `io.disable_card_reader_emu=true` in the `iidxhook.conf` file to not hook
|
||||
card reader communication with an emulation layer. The game will directly talk
|
||||
to the real readers though this only supports whatever readers the game
|
||||
directly supports (slotted readers)
|
||||
* Set `io.disable_card_reader_emu=false` in the `iidxhook.conf` file.
|
||||
Replace the default `eamio.dll` with the `eamio-icca.dll` and have either your
|
||||
slotted (IIDX, DDR Supernova or GF/DM type) or new wave pass card readers
|
||||
conencted and and assigned to *COM1*.
|
||||
conencted and and assigned to `COM1`. Other custom implementations of of the
|
||||
`eamio` API also work.
|
||||
|
||||
### ICCA device settings (device manager)
|
||||
* Port: COM1
|
||||
@@ -112,7 +124,7 @@ mainboard.
|
||||
# Known bugs
|
||||
## USBIO (FM-DL TIMEOUT)
|
||||
IIDX occasionally fails to boot with a "USBIO (FM-DL TIMEOUT)" error. If this
|
||||
happens, run the game again.
|
||||
happens, run the game again.
|
||||
|
||||
# Troubleshooting and FAQ
|
||||
|
||||
|
||||
@@ -85,17 +85,29 @@ cycle the machine (i.e. quit the game and restart it).
|
||||
|
||||
## USB IO (ezusb)
|
||||
|
||||
Use the specific iidxio API implementations, e.g. iidxio-ezusb2.dll to use
|
||||
the IO2 EZUSB board, to run the game on real hardware. Thanks to a common
|
||||
abstraction layer, you can also use custom IO boards or whatever Konami hardware
|
||||
is going to be available in the future. Obviously, someone has to write a
|
||||
driver, first.
|
||||
You have the following options:
|
||||
* Set `io.disable_io_emu=true` in the `iidxhook.conf` file to not hook ezusb
|
||||
IO communication with an emulation layer. The game will directly talk to the IO.
|
||||
The game supports the ezusb (C02) as well as ezusb FX2 (IO2) boards.
|
||||
* Set `io.disable_io_emu=false` in the `iidxhook.conf` file.
|
||||
Use the specific iidxio API implementations, e.g. `iidxio-ezusb2.dll` to use
|
||||
the IO2 EZUSB board. The common `iidxio` abstraction layer also allows you to
|
||||
use custom IO boards or whatever Konami hardware is going to be available in
|
||||
the future. Obviously, someone has to write an imlementation of the `iidxio`
|
||||
API, first.
|
||||
|
||||
## Slotted/Wave pass card readers
|
||||
|
||||
Replace the default *eamio.dll* with the *eamio-icca.dll* and have either your
|
||||
You have the following options:
|
||||
* Set `io.disable_card_reader_emu=true` in the `iidxhook.conf` file to not hook
|
||||
card reader communication with an emulation layer. The game will directly talk
|
||||
to the real readers though this only supports whatever readers the game
|
||||
directly supports (wave pass readers)
|
||||
* Set `io.disable_card_reader_emu=false` in the `iidxhook.conf` file.
|
||||
Replace the default `eamio.dll` with the `eamio-icca.dll` and have either your
|
||||
slotted (IIDX, DDR Supernova or GF/DM type) or new wave pass card readers
|
||||
conencted and and assigned to *COM1*.
|
||||
conencted and and assigned to `COM1`. Other custom implementations of of the
|
||||
`eamio` API also work.
|
||||
|
||||
### ICCA device settings (device manager)
|
||||
* Port: COM1
|
||||
|
||||
@@ -96,17 +96,29 @@ cycle the machine (i.e. quit the game and restart it).
|
||||
|
||||
## USB IO (ezusb)
|
||||
|
||||
Use the specific iidxio API implementations, e.g. iidxio-ezusb2.dll to use
|
||||
the IO2 EZUSB board, to run the game on real hardware. Thanks to a common
|
||||
abstraction layer, you can also use custom IO boards or whatever Konami hardware
|
||||
is going to be available in the future. Obviously, someone has to write a
|
||||
driver, first.
|
||||
You have the following options:
|
||||
* Set `io.disable_io_emu=true` in the `iidxhook.conf` file to not hook ezusb
|
||||
IO communication with an emulation layer. The game will directly talk to the IO.
|
||||
The game supports the ezusb (C02) as well as ezusb FX2 (IO2) boards.
|
||||
* Set `io.disable_io_emu=false` in the `iidxhook.conf` file.
|
||||
Use the specific iidxio API implementations, e.g. `iidxio-ezusb2.dll` to use
|
||||
the IO2 EZUSB board. The common `iidxio` abstraction layer also allows you to
|
||||
use custom IO boards or whatever Konami hardware is going to be available in
|
||||
the future. Obviously, someone has to write an imlementation of the `iidxio`
|
||||
API, first.
|
||||
|
||||
## Slotted/Wave pass card readers
|
||||
|
||||
Replace the default *eamio.dll* with the *eamio-icca.dll* and have either your
|
||||
You have the following options:
|
||||
* Set `io.disable_card_reader_emu=true` in the `iidxhook.conf` file to not hook
|
||||
card reader communication with an emulation layer. The game will directly talk
|
||||
to the real readers though this only supports whatever readers the game
|
||||
directly supports (wave pass readers)
|
||||
* Set `io.disable_card_reader_emu=false` in the `iidxhook.conf` file.
|
||||
Replace the default `eamio.dll` with the `eamio-icca.dll` and have either your
|
||||
slotted (IIDX, DDR Supernova or GF/DM type) or new wave pass card readers
|
||||
conencted and and assigned to *COM1*.
|
||||
conencted and and assigned to `COM1`. Other custom implementations of of the
|
||||
`eamio` API also work.
|
||||
|
||||
### ICCA device settings (device manager)
|
||||
* Port: COM1
|
||||
|
||||
@@ -101,17 +101,29 @@ cycle the machine (i.e. quit the game and restart it).
|
||||
|
||||
## USB IO (ezusb)
|
||||
|
||||
Use the specific iidxio API implementations, e.g. iidxio-ezusb2.dll to use
|
||||
the IO2 EZUSB board, to run the game on real hardware. Thanks to a common
|
||||
abstraction layer, you can also use custom IO boards or whatever Konami hardware
|
||||
is going to be available in the future. Obviously, someone has to write a
|
||||
driver, first.
|
||||
You have the following options:
|
||||
* Set `io.disable_io_emu=true` in the `iidxhook.conf` file to not hook ezusb
|
||||
IO communication with an emulation layer. The game will directly talk to the IO.
|
||||
The game supports the ezusb (C02) as well as ezusb FX2 (IO2) boards.
|
||||
* Set `io.disable_io_emu=false` in the `iidxhook.conf` file.
|
||||
Use the specific iidxio API implementations, e.g. `iidxio-ezusb2.dll` to use
|
||||
the IO2 EZUSB board. The common `iidxio` abstraction layer also allows you to
|
||||
use custom IO boards or whatever Konami hardware is going to be available in
|
||||
the future. Obviously, someone has to write an imlementation of the `iidxio`
|
||||
API, first.
|
||||
|
||||
## Slotted/Wave pass card readers
|
||||
|
||||
Replace the default *eamio.dll* with the *eamio-icca.dll* and have either your
|
||||
You have the following options:
|
||||
* Set `io.disable_card_reader_emu=true` in the `iidxhook.conf` file to not hook
|
||||
card reader communication with an emulation layer. The game will directly talk
|
||||
to the real readers though this only supports whatever readers the game
|
||||
directly supports (wave pass readers)
|
||||
* Set `io.disable_card_reader_emu=false` in the `iidxhook.conf` file.
|
||||
Replace the default `eamio.dll` with the `eamio-icca.dll` and have either your
|
||||
slotted (IIDX, DDR Supernova or GF/DM type) or new wave pass card readers
|
||||
conencted and and assigned to *COM1*.
|
||||
conencted and and assigned to `COM1`. Other custom implementations of of the
|
||||
`eamio` API also work.
|
||||
|
||||
### ICCA device settings (device manager)
|
||||
* Port: COM1
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
The following games are compatible with this version of iidxhook:
|
||||
* CANNON BALLERS
|
||||
* Rootage
|
||||
|
||||
The games must be bootstrapped using [launcher](../launcher.md).
|
||||
|
||||
@@ -96,22 +97,31 @@ cycle the machine (i.e. quit the game and restart it).
|
||||
|
||||
### BIO2 hardware
|
||||
|
||||
Set the *io.disable_bio2_emu* configuration value to *1* to disable BIO2
|
||||
emulation to run the game using real BIO2 hardware.
|
||||
Set `io.disable_bio2_emu=true` in the `iidxhook.conf` file to not hook the BIO2
|
||||
communication with an emulation layer. The game will directly talk to the IO.
|
||||
In this mode, tthe game supports the BIO2 board only.
|
||||
|
||||
### Ezusb and other
|
||||
|
||||
Use the specific iidxio API implementations, e.g. iidxio-ezusb2.dll to use
|
||||
the IO2 EZUSB board, to run the game on real hardware. Thanks to a common
|
||||
abstraction layer, you can also use custom IO boards or whatever Konami hardware
|
||||
is going to be available in the future. Obviously, someone has to write a
|
||||
driver, first.
|
||||
Set `io.disable_bio2_emu=false` in the `iidxhook.conf` file.
|
||||
Use the specific iidxio API implementations, e.g. `iidxio-ezusb2.dll` to use
|
||||
the IO2 EZUSB board. The common `iidxio` abstraction layer also allows you to
|
||||
use custom IO boards or whatever Konami hardware is going to be available in
|
||||
the future. Obviously, someone has to write an imlementation of the `iidxio`
|
||||
API, first.
|
||||
|
||||
## Slotted/Wave pass card readers
|
||||
|
||||
Replace the default *eamio.dll* with the *eamio-icca.dll* and have either your
|
||||
You have the following options:
|
||||
* Set `io.disable_card_reader_emu=true` in the `iidxhook.conf` file to not hook
|
||||
card reader communication with an emulation layer. The game will directly talk
|
||||
to the real readers though this only supports whatever readers the game
|
||||
directly supports (wave pass readers)
|
||||
* Set `io.disable_card_reader_emu=false` in the `iidxhook.conf` file.
|
||||
Replace the default `eamio.dll` with the `eamio-icca.dll` and have either your
|
||||
slotted (IIDX, DDR Supernova or GF/DM type) or new wave pass card readers
|
||||
conencted and and assigned to *COM1*.
|
||||
conencted and and assigned to `COM1`. Other custom implementations of of the
|
||||
`eamio` API also work.
|
||||
|
||||
### ICCA device settings (device manager)
|
||||
* Port: COM1
|
||||
@@ -127,6 +137,16 @@ mainboard.
|
||||
|
||||
# Troubleshooting and FAQ
|
||||
|
||||
## The monitor check is showing high fps and I am using a monitor with high refresh rate features, e.g. 120/144hz
|
||||
Sync and timing might be screwed up since the game was never meant to run on
|
||||
such refresh rates. Try setting the option `gfx.forced_refresh_rate` to either
|
||||
`59` or `60`.
|
||||
|
||||
Note: Your GPU driver settings must be configured to allow application overrides
|
||||
on vertical sync/refresh rate options.
|
||||
|
||||
On AMD GPUs, set the "V-Sync" option to `On, unless application specifies`.
|
||||
|
||||
## The game does not run "well" (frame drops, drifting offsync etc)
|
||||
This can be related to various issues:
|
||||
* Make sure to run the game as (true) Administrator especially on Windows 7 and
|
||||
|
||||
237
doc/iidxhook/iidxhook9.md
Normal file
237
doc/iidxhook/iidxhook9.md
Normal file
@@ -0,0 +1,237 @@
|
||||
# Game list
|
||||
|
||||
The following games are compatible with this version of iidxhook:
|
||||
* Heroic Verse
|
||||
* BISTROVER
|
||||
|
||||
The games must be bootstrapped using [launcher](../launcher.md).
|
||||
|
||||
# Data setup and running the game
|
||||
|
||||
## Supported versions of Windows
|
||||
|
||||
This version requires at least Win 7 x64 and will not run, like the
|
||||
former versions, on Win XP x86!
|
||||
|
||||
## Dependencies
|
||||
|
||||
Make sure to have the following dependencies installed:
|
||||
* DirectX 9
|
||||
* Visual C++ 2010 Redistributable Package (x64)
|
||||
|
||||
## Data setup
|
||||
|
||||
We assume that you are using a clean/vanilla data dump. Ensure your ("concents")
|
||||
folder with your unpacked data looks like this:
|
||||
- data
|
||||
- modules
|
||||
- prop
|
||||
|
||||
* Copy/Move all files from the *modules* directory to the root folder, so they
|
||||
are located next to the *data* and *prop* folders.
|
||||
* Copy all files from *prop/defaults* to the *prop* folder.
|
||||
* Setup proper paths for *dev/nvram* and *dev/raw* in *prop/avs-config.xml* by
|
||||
replacing the *<fs>*-block in that file with the following block:
|
||||
```
|
||||
<fs>
|
||||
<root>
|
||||
<device __type="str">.</device>
|
||||
</root>
|
||||
<mounttable>
|
||||
<vfs name="boot" fstype="fs" src="dev/raw" dst="/dev/raw" opt="vf=1,posix=1"/>
|
||||
<vfs name="boot" fstype="fs" src="dev/nvram" dst="/dev/nvram" opt="vf=0,posix=1"/>
|
||||
</mounttable>
|
||||
<nr_mountpoint __type="u16">256</nr_mountpoint>
|
||||
<nr_filedesc __type="u16">256</nr_filedesc>
|
||||
</fs>
|
||||
```
|
||||
* Unpack the package containing iidxhook9 into the root folder so iidxhook9.dll
|
||||
and all other files are located in the same folder as *data*, *prop*,
|
||||
*bm2dx.dll*, etc.
|
||||
* Run the gamestart-XX.bat file as admin. Where XX matches the version you
|
||||
want to run.
|
||||
|
||||
* Note: if you know what you're doing and would like to keep all the dlls in the
|
||||
*modules* folder then you extract iidxhook9 into that directory, move
|
||||
gamestart-XX.bat up, and edit the paths.
|
||||
|
||||
# Configuring iidxhook
|
||||
|
||||
The hook library can be configured via cmd arguments or a configuration file.
|
||||
The latter is generated (*iidxhook-XX.conf* in the same directory) on the first
|
||||
start of the game using the gamestart-XX.bat file (again, XX matches your target
|
||||
game version). It contains default values for all available parameters and
|
||||
comments explaining each parameter. Please follow the comments when configuring
|
||||
your setup.
|
||||
|
||||
Add the argument *-h* when running gamestart-XX.bat
|
||||
(e.g. *gamestart-XX.bat -h*) to print help/usage information with a list of
|
||||
all available parameters. Every parameter can be either set as command line
|
||||
argument or using a configuration file.
|
||||
|
||||
To set a parameter from the command line, just add it as an argument after
|
||||
the bat file like this
|
||||
```
|
||||
gamestart-09.bat -p gfx.windowed=true -p gfx.framed=true
|
||||
```
|
||||
|
||||
The syntax for the "key=value" is the same as in the config file. Make sure
|
||||
to have a pre-ceeding "-p" for every parameter added.
|
||||
|
||||
However, if a parameter is specifed in the configuration file and as a command
|
||||
line argument, the command line argument overrides the config file's value.
|
||||
|
||||
# Eamuse network setup
|
||||
|
||||
If you want to run the games online, you need a valid PCBID and the service URL.
|
||||
Open *prop/ea3-config.xml* and set the values of the *ea3/id/pcbid* and
|
||||
*ea3/network/services* nodes accordingly.
|
||||
|
||||
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).
|
||||
|
||||
# Real hardware support
|
||||
|
||||
## The game does not go into either 640x480 (SD) or 1280x720 (HD) as expected but rather picks a resolution like 1386x768
|
||||
The graphics backend of the game is auto detecting the resolution and refresh
|
||||
rate based on the supported specs reported by the monitor. Depending on that
|
||||
output, this can lead to the game picking some "odd" resolution like 1386x768
|
||||
even the game is set to HD mode (expecting 1280x720).
|
||||
|
||||
Furthermore, this can lead to different refresh rate values on the automatic
|
||||
monitor check, e.g. compared to previous versions (59.94 on Rootage but 60.02
|
||||
on Heroic Verse). Ultimately, the result can be a very offsync gameplay
|
||||
experience with extremely delayed input.
|
||||
|
||||
If that happens, try forcing the resolution to `1280x720` when the game is
|
||||
set to HD mode in the operator menu. Note: Your monitor must also be capable
|
||||
of handling the resolution.
|
||||
|
||||
iidxhook.conf:
|
||||
```text
|
||||
gfx.force_screen_res.width=1280
|
||||
gfx.force_screen_res.height=720
|
||||
```
|
||||
|
||||
## The monitor check is showing high fps and I am using a monitor with high refresh rate features, e.g. 120/144hz
|
||||
Sync and timing might be screwed up since the game was never meant to run on
|
||||
such refresh rates. Try setting the option `gfx.forced_refresh_rate` to either
|
||||
`59` or `60`.
|
||||
|
||||
Note: Your GPU driver settings must be configured to allow application overrides
|
||||
on vertical sync/refresh rate options.
|
||||
|
||||
On AMD GPUs, set the "V-Sync" option to `On, unless application specifies`.
|
||||
|
||||
### BIO2 hardware
|
||||
|
||||
Set `io.disable_bio2_emu=true` in the `iidxhook.conf` file to not hook the BIO2
|
||||
communication with an emulation layer. The game will directly talk to the IO.
|
||||
In this mode, the game supports the BIO2 board only.
|
||||
|
||||
## Driver notes
|
||||
You can use the default driver that Windows (7/10) automatically installs once
|
||||
you connect the BIO2 board via USB to your host. However, these drivers will
|
||||
not allow the game to detect the board correctly, throwing an IO error.
|
||||
The drivers will work fine when using the iidxio API implementation
|
||||
[iidxio-bio2](iidxio-bio2.md).
|
||||
|
||||
If you want to use the BIO2 with the game without the emulation layer, as
|
||||
suggested above, you need to install Konami's original driver which is
|
||||
identical to the stock Windows driver except the device name is different
|
||||
(which is the crucial part for the stock game's automatic detection).
|
||||
|
||||
The driver is available in the bemanitools-supplement repository.
|
||||
|
||||
### Ezusb and other
|
||||
|
||||
Set `io.disable_bio2_emu=false` in the `iidxhook.conf` file.
|
||||
Use the specific iidxio API implementations, e.g. `iidxio-ezusb2.dll` to use
|
||||
the IO2 EZUSB board. The common `iidxio` abstraction layer also allows you to
|
||||
use custom IO boards or whatever Konami hardware is going to be available in
|
||||
the future. Obviously, someone has to write an imlementation of the `iidxio`
|
||||
API, first.
|
||||
|
||||
## Slotted/Wave pass card readers
|
||||
|
||||
You have the following options:
|
||||
* Set `io.disable_card_reader_emu=true` in the `iidxhook.conf` file to not hook
|
||||
card reader communication with an emulation layer. The game will directly talk
|
||||
to the real readers though this only supports whatever readers the game
|
||||
directly supports (wave pass readers)
|
||||
* Set `io.disable_card_reader_emu=false` in the `iidxhook.conf` file.
|
||||
Replace the default `eamio.dll` with the `eamio-icca.dll` and have either your
|
||||
slotted (IIDX, DDR Supernova or GF/DM type) or new wave pass card readers
|
||||
conencted and and assigned to `COM1`. Other custom implementations of of the
|
||||
`eamio` API also work.
|
||||
|
||||
### ICCA device settings (device manager)
|
||||
* Port: COM1
|
||||
* BAUD rate: 57600
|
||||
* Data bits: 8
|
||||
* Parity: None
|
||||
* Stop bits: 1
|
||||
* Flow control: None
|
||||
|
||||
If you encounter issues after the game opened the device, e.g. application
|
||||
stuck, try a USB <-> COM dongle instead of using one of the COM ports of the
|
||||
mainboard.
|
||||
|
||||
# Troubleshooting and FAQ
|
||||
## The turntable input feels laggy/delayed with my BIO2 + sub IO
|
||||
See the [this readme](hardware/bio2-sub-io-turntable-bypass-cable.md) for
|
||||
information about the bypass cable.
|
||||
|
||||
## The game does not run "well" (frame drops, drifting offsync etc)
|
||||
This can be related to various issues:
|
||||
* Make sure to run the game as (true) Administrator especially on Windows 7 and
|
||||
newer. This will also get rid of various other errors (see below) that are
|
||||
related to permission issues.
|
||||
* Run the game's process with a higher priority:
|
||||
```
|
||||
start "" /relatime "gamestart.bat"
|
||||
```
|
||||
* Enforce v-sync enabled in your GPU settings.
|
||||
* Ensure that you have a constant refresh rate around the 60 hz (59.9xx or 60.0xx)
|
||||
that is not jumping around. Use the timebase feature of one of the newer games to
|
||||
check that or enable iidxhook's timebase and check the log output for the
|
||||
determined value. Run this a few times and check if the results differ.
|
||||
|
||||
## "NETWORK WARNING" instead of "NETWORK OK"
|
||||
This can be caused by:
|
||||
* Invalid PCBID
|
||||
* Firewall blocking connections
|
||||
* Invalid eamuse url or port specified
|
||||
* Game is not run using the Administrator account
|
||||
Make sure to check these things first
|
||||
|
||||
## My songs are offsync
|
||||
From IIDX 20 (or Lincle very final revision) onwards, the game comes with
|
||||
a built-in auto timebase option ("monitor check" on startup) which
|
||||
dynamically, detects the refresh rate of your current setup. Thus, BT5's
|
||||
timebase option is not included from this hook version onwards, anymore.
|
||||
Ensure that refresh rate displayed is very stable, e.g. 60.00x hz, and the
|
||||
game should be able to provide you with a smooth and sync game experience.
|
||||
|
||||
## My game runs too fast
|
||||
iidxhook can limit the frame rate for you (refer to help/config file)
|
||||
|
||||
## My game crashes when I try fullscreen
|
||||
Use dxwnd and set settings like "Acquire admin caps" and "Fullscreen only"
|
||||
|
||||
## Background videos aren't working. When starting a song, windows is playing the error sound and a message box appears
|
||||
You are missing a codec to decode and play the videos. There are different
|
||||
methods available to get background videos working. Probably, the easiest
|
||||
solution: grab the CLVSD.ax file and go to Start -> Run -> regsvr32 clvsd.ax
|
||||
Make sure to run cmd.exe as Administrator, otherwise you will get errors caused
|
||||
by invalid permissions.
|
||||
|
||||
## I installed the CLVSD.ax codec but the game crashes or displays a message box that tells me to disable my debugger
|
||||
If songs keep crashing upon start and you get an error message that says
|
||||
```
|
||||
DirectShow Texture3D Sample
|
||||
Could not create source filter to graph! hr=0x80040266
|
||||
```
|
||||
despite having the codec (CLVSD.ax) installed, remove the debug flag (*-D*)
|
||||
from gamestart or use a CLVSD.ax codec which has the debugger checks removed.
|
||||
21
doc/iidxhook/iidxio-bio2.md
Normal file
21
doc/iidxhook/iidxio-bio2.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# IIDXIO API implementation with BIO2 driver
|
||||
This implementation of BT5's iidxio API allows you to use native BIO2 hardware with anything that
|
||||
supports BT5's iidxio API, e.g. all iidxhooks of BT5. Thus, you can play your favorite old IIDX
|
||||
games with the latest generation of hardware.5.
|
||||
|
||||
## Setup
|
||||
* Have `iidxio-bio2.dll` in the same folder as your `iidxhookX.dll`
|
||||
* Rename `iidxio-bio2.dll` to `iidxio.dll`
|
||||
* Ensure that your `gamestart.bat` actually injects the appropriate iidxhook dll, for example:
|
||||
```bat
|
||||
inject iidxhook3.dll bm2dx.exe ...*
|
||||
```
|
||||
or
|
||||
```bat
|
||||
launcher -K iidxhook4.dll bm2dx.dll ...*
|
||||
```
|
||||
* This assumes that the BIO2 is already flashed to the correct firmware. The firmware perists once
|
||||
flashed and does not need to be re-flashed after a power cycle.
|
||||
|
||||
## Driver notes
|
||||
See [here](iidxhook9.md#driver-notes).
|
||||
@@ -1,4 +1,4 @@
|
||||
This library drives a "legacy" ezusb IO board, also known as C02 IO, and
|
||||
This library drives a "legacy" ezusb IO board, also known as C02/D01 IO, and
|
||||
implements the iidxio API of BT5. Thus, it allows you to use this IO board with
|
||||
*any* version of IIDX that is supported by BT5.
|
||||
|
||||
@@ -24,5 +24,7 @@ the status LEDs on the side of the board should show a blinking pattern.
|
||||
dump to the FPGA.
|
||||
* There is a script called ezusb-boot.bat which combines the two steps above
|
||||
and can be integrated into the startup process of a dedicated setup.
|
||||
* If you are using a D01 IO board, use the `fpga-d01.bin` file instead of the
|
||||
`fpga.bin` file.
|
||||
* If you ignore these steps, you will either run into errors or parts of the
|
||||
IO board won't work (e.g. lights).
|
||||
13
doc/jbhook/jbio-magicbox.md
Normal file
13
doc/jbhook/jbio-magicbox.md
Normal file
@@ -0,0 +1,13 @@
|
||||
This library talks to a MagicBox cab's IO and implements the jbio API of BT5.
|
||||
Thus, it allows you to use a MagicBox cab with *any* version of jubeat that is supported by BT5.
|
||||
|
||||
# Setup
|
||||
* Rename `jbio-magicbox.dll` to `jbio.dll`.
|
||||
* Make sure `jbio.dll` is in the same folder as both `jbhook.dll` and `jubeat.dll`
|
||||
* Make sure that you have a copy of the `ch341dll.dll` that comes with MagicBox.
|
||||
* Ensure that your `gamestart.bat` actually injects the appropriate jbhook dll
|
||||
for example:
|
||||
```
|
||||
launcher -K jbhook.dll jubeat.dll ...*
|
||||
```
|
||||
or that the application otherwise uses `jbio.dll`
|
||||
18
doc/jbhook/jbio-p4io.md
Normal file
18
doc/jbhook/jbio-p4io.md
Normal file
@@ -0,0 +1,18 @@
|
||||
This library talks to a P4IO (panel) and H44B through ACIO (lights) of a jubeat cab and implements the jbio API of BT5.
|
||||
Thus, it allows you to use a modern jubeat cab with *any* version of jubeat that is supported by BT5.
|
||||
|
||||
# Setup
|
||||
* Rename `jbio-p4io.dll` to `jbio.dll`.
|
||||
* Make sure `jbio.dll` is in the same folder as both `jbhook.dll`, `aciomgr.dll` and `jubeat.dll`
|
||||
* If you want IC card support via eamio-icca, ensure you also rename `eamio-icca.dll` to `eamio.dll`
|
||||
* Ensure that your `gamestart.bat` actually injects the appropriate jbhook dll
|
||||
for example:
|
||||
```
|
||||
launcher -K jbhook.dll jubeat.dll ...*
|
||||
```
|
||||
or that the application otherwise uses `jbio.dll`
|
||||
|
||||
* If you have P4IO but no H44B, lights will be disabled
|
||||
* You can change the port and baudrate of the H44B node by editing the `jbio-h44b.conf` that should be created by default
|
||||
* If you are using IC card support, you can edit `eamio-icc.conf` to change the port and baudrate
|
||||
* If you are playing on a real cab, the port and baud of H44B and ICCA should be identical
|
||||
18
doc/sdvxhook/sdvxio-bio2.md
Normal file
18
doc/sdvxhook/sdvxio-bio2.md
Normal file
@@ -0,0 +1,18 @@
|
||||
This library talks to a BIO2 BI2A node and implements the sdvxio API of BT5.
|
||||
Thus, it allows you to use a BIO2 SDVX device board with *any* version of SDVX that is supported by BT5.
|
||||
|
||||
# Setup
|
||||
* Make sure that your BIO2 is flashed with a SDVX firmware (if you can boot SDVX5 with it, it's already the right firmware)
|
||||
* The firmware persists between boots, so as long as it's flashed to the correct firmware, you no longer need to do this step
|
||||
* Rename sdvxio-kfca.dll to sdvxio.dll.
|
||||
* Ensure that your gamestart.bat actually injects the appropriate sdvxhook dll
|
||||
for example:
|
||||
```
|
||||
launcher -K sdvxhook.dll soundvoltex.dll ...*
|
||||
```
|
||||
or that the application otherwise uses sdvxio.dll
|
||||
|
||||
* sdvxio-bio2 implements BIO2 device autodetection
|
||||
* if this fails please make a bug report, and set the port manually in the config
|
||||
* You can change the port and baudrate by editing the sdvxio-bio2.conf that should be created by default
|
||||
* Please connect any additional acio devices to their own port (ex: SDVX5 expects an ICCA by itself on COM2)
|
||||
38
doc/tools/README.md
Normal file
38
doc/tools/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Tools
|
||||
Documentation about various additional tooling that is fundamentally not required to run any of
|
||||
BT5's supported games, but provides additional features for users and developers alike.
|
||||
|
||||
## BT5 API
|
||||
Various command line tools for quick and easy testing of BT5 API implementations witohut having
|
||||
to run any target games.
|
||||
|
||||
* [eamiotest](eamiotest.md): `eamio` API
|
||||
* [iidxiotest](iidxiotest.md): `iidxio` API
|
||||
* [jbiotest](jbiotest.md): `jbio` API
|
||||
|
||||
## IO related
|
||||
### ACIO
|
||||
* [aciotest](aciotest.md): Command line tool for quick and easy testing of ACIO devices without
|
||||
having to run a game.
|
||||
|
||||
### Ezusb
|
||||
* [ezusb-iidx-fpga-flash](ezusb-iidx-fpga-flash.md): Tool for flashing the FPGA on ezusb 1 boards.
|
||||
Required if you want to run games without native ezusb support using BT5's iidxio API.
|
||||
* [ezusb-iidx-sram-flash](ezusb-iidx-sram-flash.md): Tool for flashing data to the SRAM of ezusb
|
||||
FX 2 boards. Required if you want to run games without native ezusb FX 2 support using BT5's iidxio
|
||||
API.
|
||||
* [ezusb-tool](ezusb-tool.md): Fundamental tool for flashing the base firmware to ezusb 1/2 boards.
|
||||
Required if you want to run games without native ezusb 1/2 support using BT5's iidxio API.
|
||||
|
||||
### IIDX exit hooks
|
||||
Exit hooks allow you to exit the game using a combination of inputs on native IO hardware.
|
||||
|
||||
Supported IO hardware:
|
||||
* [ezusb](iidx-ezusb-exit-hook.md)
|
||||
* [ezusb 2](iidx-ezusb2-exit-hook.md)
|
||||
* [bio2](iidx-bio2-exit-hook.md)
|
||||
|
||||
## Misc
|
||||
* [mempatch-hook]: Hook library to dynamically apply memory address patches during runtime before
|
||||
your application starts execution. Should be prefered over hardcoded hex-edits if applicable.
|
||||
* [pcbidgen]: Command line tool to generate random PCBIDs
|
||||
17
doc/tools/iidx-bio2-exit-hook.md
Normal file
17
doc/tools/iidx-bio2-exit-hook.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# IIDX BIO2 exit hook
|
||||
A hook library that can be used with BeatmaniaIIDX games that run the BIO2 IO board either natively,
|
||||
e.g. 25+, or using the [iidxio-bio2 backend](../iidxhook/iidx-bio2.md). It allows the player to
|
||||
exit the game by pressing the buttons `Start P1 + Start P2 + VEFX + Effect` simultaneously. This can
|
||||
be useful if you want an option to exit back to your desktop without having a keyboard attached.
|
||||
|
||||
The exit hook lib must be loaded like any other hook lib you are already injecting to the game
|
||||
using either `inject` or `launcher` (depending on the game version). The order for the hook libs is important as they are loaded in the order specified for the inject/launcher call. The entry in the `gamestart.bat` file should look like this for inject:
|
||||
```bat
|
||||
inject iidxhook3.dll -K iidx-bio2-exit-hook.dll bm2dx.exe ...
|
||||
```
|
||||
...and for launcher:
|
||||
```bat
|
||||
launcher -K iidxhook8.dll -K iidx-bio2-exit-hook.dll bm2dx.dll ...
|
||||
```
|
||||
|
||||
Where `iidxhook3.dll` is used for versions 14-15 and `iidxhook8.dll` for versions 25-26.
|
||||
3
doc/tools/jbiotest.md
Normal file
3
doc/tools/jbiotest.md
Normal file
@@ -0,0 +1,3 @@
|
||||
Testing tool for development of jbio libraries used for emulating the main io
|
||||
hardware on bemanitools for jubeat. Just place jbiotest.exe and your
|
||||
custom jbio.dll in the same folder and run jbiotest.exe.
|
||||
13
doc/vigem/README.md
Normal file
13
doc/vigem/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# ViGEm: Virtual Gamepad Emulation Framework
|
||||
Virtual game controller emulation library. Allows us to create in code emulated XBOX controllers.
|
||||
|
||||
This is used to hook up BT5's various IO API libraries allowing you to use any of their
|
||||
implemtations as a game controller on Windows.
|
||||
|
||||
References:
|
||||
* [ViGEmBus](https://github.com/ViGEm/ViGEmBus)
|
||||
* [ViGEmClient](https://github.com/ViGEm/ViGEmClient)
|
||||
|
||||
Available ViGEm client implementations:
|
||||
* [vigem-iidxio](vigem-iidxio.md): Exposes inputs provided by the iidxio API as three XBOX gamepads
|
||||
* [vigem-sdvxio](vigem-sdvxio.md): Exposes inputs provided by the sdvxio API as one XBOX gamepad
|
||||
62
doc/vigem/vigem-iidxio.md
Normal file
62
doc/vigem/vigem-iidxio.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# ViGEm IIDXIO
|
||||
This application allows you to use any iidxio backend, e.g. `iidxio-ezusb.dll`, `iidxio-ezusb2.dll`
|
||||
or `iidxio-bio2.dll`, to be exposed as three XBOX 360 game controller on Windows.
|
||||
|
||||
Thus, it allows you to use a real cabinet with all its IO with *any* game that supports xinput.
|
||||
|
||||
Note: This will not work with games that require Direct Input (dinput), e.g. IIDX Infinitas.
|
||||
|
||||
## Setup
|
||||
* Install [ViGEmBus](https://github.com/ViGEm/ViGEmBus/releases)
|
||||
* Source for compiled binaries: [bemanitools-supplement](https://dev.s-ul.eu/djhackers/bemanitools-supplement)
|
||||
* Place the following in the same folder as `vigem-iidxio.exe`:
|
||||
* Get a copy of [ViGEmClient.dll](https://bin.jvnv.net/file/ZgMJK/ViGEmClient.zip) (or from bemanitools-supplements)
|
||||
* Rename your corresponding `iidxio-XXX.dll`, e.g. `iidxio-bio2.dll`, to `iidxio.dll`.
|
||||
* Run `vigem-iidxio.exe` so that the config file gets created (on first start)
|
||||
* Edit `vigem-iidxio.conf` if needed. Available options are explained in the file
|
||||
|
||||
## Usage
|
||||
* Depending on the iidxio implementation used, you might have to do some setup, e.g. flashing your
|
||||
IO board for [ezusb](../iidxhook/iidxio-ezusb.md#setup) or
|
||||
[ezusb2](../iidxhook/iidxio-ezusb2.md#setup)
|
||||
* Run `vigem-iidxio.exe` and keep it open/running
|
||||
* To quit the program, hit the `TEST` and `SERVICE` buttons at the same time
|
||||
|
||||
## Input mappings
|
||||
| Cabinet | XBOX Gamepad 1 | XBOX Gamepad 2 | XBOX Gamepad 3 |
|
||||
|------------|--------------------|--------------------|--------------------|
|
||||
| P1 Key 1 | A | | |
|
||||
| P1 Key 2 | B | | |
|
||||
| P1 Key 3 | X | | |
|
||||
| P1 Key 4 | Y | | |
|
||||
| P1 Key 5 | Left shoulder | | |
|
||||
| P1 Key 6 | Rights houlder | | |
|
||||
| P1 Key 7 | Start | | |
|
||||
| P2 Key 1 | | A | |
|
||||
| P2 Key 2 | | B | |
|
||||
| P2 Key 3 | | X | |
|
||||
| P2 Key 4 | | Y | |
|
||||
| P2 Key 5 | | Left shoulder | |
|
||||
| P2 Key 6 | | Rights houlder | |
|
||||
| P2 Key 7 | | Start | |
|
||||
| Start P1 | Back | | |
|
||||
| Start P2 | | Back | |
|
||||
| VEFX | | | B |
|
||||
| Effect | | | A |
|
||||
| Test | | | X |
|
||||
| Service | | | Y |
|
||||
| Coin | | | Start |
|
||||
| TT P1 Up | Thumbstick X axis+ | | |
|
||||
| TT P1 Down | Thumbstick X axis- | | |
|
||||
| TT P2 Up | | Thumbstick X axis+ | |
|
||||
| TT P2 Down | | Thumbstick X axis- | |
|
||||
|
||||
Turntables are either in absolute or relative mode depending on how it's defined in the
|
||||
`vigem-iidxio.conf`.
|
||||
|
||||
## Additional Notes For Cabinets (Running on embedded Windows 7):
|
||||
* Make sure that you follow the instructions exactly from the release page
|
||||
([Prerequisites for Windows 7](https://github.com/ViGEm/ViGEmBus/wiki/Prerequisites-for-Windows-7))
|
||||
* If you get an error while trying to install KB3033929, re-enable windows update
|
||||
* If you can't find some of these files, see bemanitools-supplements
|
||||
* Make sure to ewfmgr C: -commit and reboot after installing the drivers (this only needs to be done once)
|
||||
26
doc/vigem/vigem-sdvxio.md
Normal file
26
doc/vigem/vigem-sdvxio.md
Normal file
@@ -0,0 +1,26 @@
|
||||
This application allows you to use any sdvxio backend, e.g. `sdvxio-kfca.dll`, to be available as a XBOX 360 game controller on windows.
|
||||
Thus, it allows you to use a real cab with *any* game that supports xinput.
|
||||
|
||||
# Setup
|
||||
* Install [ViGEmBus](https://github.com/ViGEm/ViGEmBus/releases)
|
||||
* Place the following in the same folder as vigem-sdvxio:
|
||||
* Get a copy of [ViGEmClient.dll](https://bin.jvnv.net/file/ZgMJK/ViGEmClient.zip) (or from bemanitools-supplements)
|
||||
* Rename your corresponding `sdvxio-XXX.dll`, e.g. `sdvxio-kfca.dll`, to `sdvxio.dll`.
|
||||
* Run `vigem-sdvxio.exe` so that the config file gets created
|
||||
* Edit `vigem-sdvxio.conf` so that the config file gets created as needed
|
||||
|
||||
# Usage
|
||||
* Run `vigem-sdvxio.exe`
|
||||
* To quit the program, hit the TEST + SERVICE button at the same time
|
||||
|
||||
# Mapping
|
||||
* BT ABCD are mapped to ABXY
|
||||
* FX LR are mapped to LB/RB
|
||||
* VOL LR are mapped to L thumbstick X/Y (either in absolute or relative mode depending on the config)
|
||||
|
||||
# Additional Notes For Cabinets (Running on embedded Windows 7):
|
||||
* Make sure that you follow the instructions exactly from the release page
|
||||
([Prerequisites for Windows 7](https://github.com/ViGEm/ViGEmBus/wiki/Prerequisites-for-Windows-7))
|
||||
* If you get an error while trying to install KB3033929, re-enable windows update
|
||||
* If you can't find some of these files, see bemanitools-supplements
|
||||
* Make sure to ewfmgr C: -commit and reboot after installing the drivers (this only needs to be done once)
|
||||
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
|
||||
@@ -61,14 +61,24 @@ SMX_EXTERN_C SMX_API void SMX_GetInfo(int pad, struct SMXInfo *info);
|
||||
// Get a mask of the currently pressed panels.
|
||||
SMX_EXTERN_C SMX_API uint16_t SMX_GetInputState(int pad);
|
||||
|
||||
// Update the lights. Both pads are always updated together. lightsData is a
|
||||
// list of 8-bit RGB colors, one for each LED. Each panel has lights in the
|
||||
// following order:
|
||||
// (deprecated) Equivalent to SMX_SetLights2(lightsData, 864).
|
||||
SMX_API void SMX_SetLights(const char lightData[864]);
|
||||
|
||||
// Update the lights. Both pads are always updated together. lightData is a list of 8-bit RGB
|
||||
// colors, one for each LED.
|
||||
//
|
||||
// 0123
|
||||
// 4567
|
||||
// 89AB
|
||||
// CDEF
|
||||
// lightDataSize is the number of bytes in lightsData. This should be 1350 (2 pads * 9 panels *
|
||||
// 25 lights * 3 RGB colors). For backwards-compatibility, this can also be 864.
|
||||
//
|
||||
// Each panel has lights in the following order:
|
||||
//
|
||||
// 00 01 02 03
|
||||
// 16 17 18
|
||||
// 04 05 06 07
|
||||
// 19 20 21
|
||||
// 08 09 10 11
|
||||
// 22 23 24
|
||||
// 12 13 14 15
|
||||
//
|
||||
// Panels are in the following order:
|
||||
//
|
||||
@@ -76,17 +86,17 @@ SMX_EXTERN_C SMX_API uint16_t SMX_GetInputState(int pad);
|
||||
// 345 CDE
|
||||
// 678 F01
|
||||
//
|
||||
// With 18 panels, 16 LEDs per panel and 3 bytes per LED, each light update has
|
||||
// 864 bytes of data.
|
||||
// With 18 panels, 25 LEDs per panel and 3 bytes per LED, each light update has 1350 bytes of data.
|
||||
//
|
||||
// Lights will update at up to 30 FPS. If lights data is sent more quickly, a
|
||||
// best effort will be made to send the most recent lights data available, but
|
||||
// the panels won't update more quickly.
|
||||
// Lights will update at up to 30 FPS. If lights data is sent more quickly, a best effort will be
|
||||
// made to send the most recent lights data available, but the panels won't update more quickly.
|
||||
//
|
||||
// The panels will return to automatic lighting if no lights are received for a
|
||||
// while, so applications controlling lights should send light updates
|
||||
// continually, even if the lights aren't changing.
|
||||
SMX_EXTERN_C SMX_API void SMX_SetLights(const char lightsData[864]);
|
||||
// The panels will return to automatic lighting if no lights are received for a while, so applications
|
||||
// controlling lights should send light updates continually, even if the lights aren't changing.
|
||||
//
|
||||
// For backwards compatibility, if lightDataSize is 864, the old 4x4-only order is used,
|
||||
// which simply omits lights 16-24.
|
||||
SMX_API void SMX_SetLights2(const char *lightData, int lightDataSize);
|
||||
|
||||
// By default, the panels light automatically when stepped on. If a lights
|
||||
// command is sent by the application, this stops happening to allow the
|
||||
|
||||
519
src/imports/ViGEm/Client.h
Normal file
519
src/imports/ViGEm/Client.h
Normal file
@@ -0,0 +1,519 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017-2019 Nefarius Software Solutions e.U. and Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ViGEmClient_h__
|
||||
#define ViGEmClient_h__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ViGEm/Common.h"
|
||||
|
||||
#ifdef VIGEM_DYNAMIC
|
||||
#ifdef VIGEM_EXPORTS
|
||||
#define VIGEM_API __declspec(dllexport)
|
||||
#else
|
||||
#define VIGEM_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define VIGEM_API
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \typedef enum _VIGEM_ERRORS
|
||||
*
|
||||
* \brief Defines an alias representing the ViGEm errors.
|
||||
*/
|
||||
typedef enum _VIGEM_ERRORS {
|
||||
VIGEM_ERROR_NONE = 0x20000000,
|
||||
VIGEM_ERROR_BUS_NOT_FOUND = 0xE0000001,
|
||||
VIGEM_ERROR_NO_FREE_SLOT = 0xE0000002,
|
||||
VIGEM_ERROR_INVALID_TARGET = 0xE0000003,
|
||||
VIGEM_ERROR_REMOVAL_FAILED = 0xE0000004,
|
||||
VIGEM_ERROR_ALREADY_CONNECTED = 0xE0000005,
|
||||
VIGEM_ERROR_TARGET_UNINITIALIZED = 0xE0000006,
|
||||
VIGEM_ERROR_TARGET_NOT_PLUGGED_IN = 0xE0000007,
|
||||
VIGEM_ERROR_BUS_VERSION_MISMATCH = 0xE0000008,
|
||||
VIGEM_ERROR_BUS_ACCESS_FAILED = 0xE0000009,
|
||||
VIGEM_ERROR_CALLBACK_ALREADY_REGISTERED = 0xE0000010,
|
||||
VIGEM_ERROR_CALLBACK_NOT_FOUND = 0xE0000011,
|
||||
VIGEM_ERROR_BUS_ALREADY_CONNECTED = 0xE0000012,
|
||||
VIGEM_ERROR_BUS_INVALID_HANDLE = 0xE0000013,
|
||||
VIGEM_ERROR_XUSB_USERINDEX_OUT_OF_RANGE = 0xE0000014,
|
||||
VIGEM_ERROR_INVALID_PARAMETER = 0xE0000015
|
||||
|
||||
} VIGEM_ERROR;
|
||||
|
||||
/**
|
||||
* \def VIGEM_SUCCESS(_val_) (_val_ == VIGEM_ERROR_NONE);
|
||||
*
|
||||
* \brief A macro that defines success.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param _val_ The VIGEM_ERROR value.
|
||||
*/
|
||||
#define VIGEM_SUCCESS(_val_) (_val_ == VIGEM_ERROR_NONE)
|
||||
|
||||
/**
|
||||
* \typedef struct _VIGEM_CLIENT_T *PVIGEM_CLIENT
|
||||
*
|
||||
* \brief Defines an alias representing a driver connection object.
|
||||
*/
|
||||
typedef struct _VIGEM_CLIENT_T *PVIGEM_CLIENT;
|
||||
|
||||
/**
|
||||
* \typedef struct _VIGEM_TARGET_T *PVIGEM_TARGET
|
||||
*
|
||||
* \brief Defines an alias representing a target device object.
|
||||
*/
|
||||
typedef struct _VIGEM_TARGET_T *PVIGEM_TARGET;
|
||||
|
||||
typedef _Function_class_(EVT_VIGEM_TARGET_ADD_RESULT) VOID CALLBACK
|
||||
EVT_VIGEM_TARGET_ADD_RESULT(
|
||||
PVIGEM_CLIENT Client, PVIGEM_TARGET Target, VIGEM_ERROR Result);
|
||||
|
||||
typedef EVT_VIGEM_TARGET_ADD_RESULT *PFN_VIGEM_TARGET_ADD_RESULT;
|
||||
|
||||
typedef _Function_class_(EVT_VIGEM_X360_NOTIFICATION) VOID CALLBACK
|
||||
EVT_VIGEM_X360_NOTIFICATION(
|
||||
PVIGEM_CLIENT Client,
|
||||
PVIGEM_TARGET Target,
|
||||
UCHAR LargeMotor,
|
||||
UCHAR SmallMotor,
|
||||
UCHAR LedNumber,
|
||||
LPVOID UserData);
|
||||
|
||||
typedef EVT_VIGEM_X360_NOTIFICATION *PFN_VIGEM_X360_NOTIFICATION;
|
||||
|
||||
typedef _Function_class_(EVT_VIGEM_DS4_NOTIFICATION) VOID CALLBACK
|
||||
EVT_VIGEM_DS4_NOTIFICATION(
|
||||
PVIGEM_CLIENT Client,
|
||||
PVIGEM_TARGET Target,
|
||||
UCHAR LargeMotor,
|
||||
UCHAR SmallMotor,
|
||||
DS4_LIGHTBAR_COLOR LightbarColor,
|
||||
LPVOID UserData);
|
||||
|
||||
typedef EVT_VIGEM_DS4_NOTIFICATION *PFN_VIGEM_DS4_NOTIFICATION;
|
||||
|
||||
/**
|
||||
* \fn PVIGEM_CLIENT vigem_alloc(void);
|
||||
*
|
||||
* \brief Allocates an object representing a driver connection.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \return A new driver connection object.
|
||||
*/
|
||||
VIGEM_API PVIGEM_CLIENT vigem_alloc(void);
|
||||
|
||||
/**
|
||||
* \fn void vigem_free(PVIGEM_CLIENT vigem);
|
||||
*
|
||||
* \brief Frees up memory used by the driver connection object.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
*/
|
||||
VIGEM_API void vigem_free(PVIGEM_CLIENT vigem);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_connect(PVIGEM_CLIENT vigem);
|
||||
*
|
||||
* \brief Initializes the driver object and establishes a connection to the
|
||||
* emulation bus driver. Returns an error if no compatible bus device has been
|
||||
* found.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR vigem_connect(PVIGEM_CLIENT vigem);
|
||||
|
||||
/**
|
||||
* \fn void vigem_disconnect(PVIGEM_CLIENT vigem);
|
||||
*
|
||||
* \brief Disconnects from the bus device and resets the driver object state.
|
||||
* The driver object may be reused again after calling this function. When
|
||||
* called, all targets which may still be connected will be destroyed
|
||||
* automatically. Be aware, that allocated target objects won't be automatically
|
||||
* freed, this has to be taken care of by the caller.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
*/
|
||||
VIGEM_API void vigem_disconnect(PVIGEM_CLIENT vigem);
|
||||
|
||||
/**
|
||||
* \fn PVIGEM_TARGET vigem_target_x360_alloc(void);
|
||||
*
|
||||
* \brief Allocates an object representing an Xbox 360 Controller device.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \return A PVIGEM_TARGET representing an Xbox 360 Controller device.
|
||||
*/
|
||||
VIGEM_API PVIGEM_TARGET vigem_target_x360_alloc(void);
|
||||
|
||||
/**
|
||||
* \fn PVIGEM_TARGET vigem_target_ds4_alloc(void);
|
||||
*
|
||||
* \brief Allocates an object representing a DualShock 4 Controller device.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \return A PVIGEM_TARGET representing a DualShock 4 Controller device.
|
||||
*/
|
||||
VIGEM_API PVIGEM_TARGET vigem_target_ds4_alloc(void);
|
||||
|
||||
/**
|
||||
* \fn void vigem_target_free(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Frees up memory used by the target device object. This does not
|
||||
* automatically remove the associated device from the bus, if present. If the
|
||||
* target device doesn't get removed before this call, the device becomes
|
||||
* orphaned until the owning process is terminated.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*/
|
||||
VIGEM_API void vigem_target_free(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_target_add(PVIGEM_CLIENT vigem, PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Adds a provided target device to the bus driver, which is equal to a
|
||||
* device plug-in event of a physical hardware device. This function blocks
|
||||
* until the target device is in full operational mode.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR
|
||||
vigem_target_add(PVIGEM_CLIENT vigem, PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_target_add_async(PVIGEM_CLIENT vigem, PVIGEM_TARGET
|
||||
* target, PVIGEM_TARGET_ADD_RESULT result);
|
||||
*
|
||||
* \brief Adds a provided target device to the bus driver, which is equal to a
|
||||
* device plug-in event of a physical hardware device. This function immediately
|
||||
* returns. An optional callback may be registered which gets called on error or
|
||||
* if the target device has become fully operational.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
* \param result An optional function getting called when the target device
|
||||
* becomes available.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR vigem_target_add_async(
|
||||
PVIGEM_CLIENT vigem,
|
||||
PVIGEM_TARGET target,
|
||||
PFN_VIGEM_TARGET_ADD_RESULT result);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_target_remove(PVIGEM_CLIENT vigem, PVIGEM_TARGET
|
||||
* target);
|
||||
*
|
||||
* \brief Removes a provided target device from the bus driver, which is equal
|
||||
* to a device unplug event of a physical hardware device. The target device
|
||||
* object may be reused after this function is called. If this function is never
|
||||
* called on target device objects, they will be removed from the bus when the
|
||||
* owning process terminates.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR
|
||||
vigem_target_remove(PVIGEM_CLIENT vigem, PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_target_x360_register_notification(PVIGEM_CLIENT vigem,
|
||||
* PVIGEM_TARGET target, PVIGEM_X360_NOTIFICATION notification);
|
||||
*
|
||||
* \brief Registers a function which gets called, when LED index or vibration
|
||||
* state changes occur on the provided target device. This function fails if the
|
||||
* provided target device isn't fully operational or in an erroneous state.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
* \param notification The notification callback.
|
||||
* \param userData The user data passed to the notification callback.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR vigem_target_x360_register_notification(
|
||||
PVIGEM_CLIENT vigem,
|
||||
PVIGEM_TARGET target,
|
||||
PFN_VIGEM_X360_NOTIFICATION notification,
|
||||
LPVOID userData);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_target_ds4_register_notification(PVIGEM_CLIENT vigem,
|
||||
* PVIGEM_TARGET target, PVIGEM_DS4_NOTIFICATION notification);
|
||||
*
|
||||
* \brief Registers a function which gets called, when LightBar or vibration
|
||||
* state changes occur on the provided target device. This function fails if the
|
||||
* provided target device isn't fully operational or in an erroneous state.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
* \param notification The notification callback.
|
||||
* \param userData The user data passed to the notification callback.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR vigem_target_ds4_register_notification(
|
||||
PVIGEM_CLIENT vigem,
|
||||
PVIGEM_TARGET target,
|
||||
PFN_VIGEM_DS4_NOTIFICATION notification,
|
||||
LPVOID userData);
|
||||
|
||||
/**
|
||||
* \fn void vigem_target_x360_unregister_notification(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Removes a previously registered callback function from the provided
|
||||
* target object.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*/
|
||||
VIGEM_API void vigem_target_x360_unregister_notification(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn void vigem_target_ds4_unregister_notification(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Removes a previously registered callback function from the provided
|
||||
* target object.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*/
|
||||
VIGEM_API void vigem_target_ds4_unregister_notification(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn void vigem_target_set_vid(PVIGEM_TARGET target, USHORT vid);
|
||||
*
|
||||
* \brief Overrides the default Vendor ID value with the provided one.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
* \param vid The Vendor ID to set.
|
||||
*/
|
||||
VIGEM_API void vigem_target_set_vid(PVIGEM_TARGET target, USHORT vid);
|
||||
|
||||
/**
|
||||
* \fn void vigem_target_set_pid(PVIGEM_TARGET target, USHORT pid);
|
||||
*
|
||||
* \brief Overrides the default Product ID value with the provided one.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
* \param pid The Product ID to set.
|
||||
*/
|
||||
VIGEM_API void vigem_target_set_pid(PVIGEM_TARGET target, USHORT pid);
|
||||
|
||||
/**
|
||||
* \fn USHORT vigem_target_get_vid(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Returns the Vendor ID of the provided target device object.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*
|
||||
* \return The Vendor ID.
|
||||
*/
|
||||
VIGEM_API USHORT vigem_target_get_vid(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn USHORT vigem_target_get_pid(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Returns the Product ID of the provided target device object.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*
|
||||
* \return The Product ID.
|
||||
*/
|
||||
VIGEM_API USHORT vigem_target_get_pid(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_target_x360_update(PVIGEM_CLIENT vigem, PVIGEM_TARGET
|
||||
* target, XUSB_REPORT report);
|
||||
*
|
||||
* \brief Sends a state report to the provided target device.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
* \param report The report to send to the target device.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR vigem_target_x360_update(
|
||||
PVIGEM_CLIENT vigem, PVIGEM_TARGET target, XUSB_REPORT report);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_ERROR vigem_target_ds4_update(PVIGEM_CLIENT vigem, PVIGEM_TARGET
|
||||
* target, DS4_REPORT report);
|
||||
*
|
||||
* \brief Sends a state report to the provided target device.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
* \param report The report to send to the target device.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR vigem_target_ds4_update(
|
||||
PVIGEM_CLIENT vigem, PVIGEM_TARGET target, DS4_REPORT report);
|
||||
|
||||
/**
|
||||
* \fn ULONG vigem_target_get_index(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Returns the internal index (serial number) the bus driver assigned
|
||||
* to the provided target device object. Note that this value is specific to the
|
||||
* inner workings of the bus driver, it does not reflect related values like
|
||||
* player index or device arrival order experienced by other APIs. It may be
|
||||
* used to identify the target device object for its lifetime. This value
|
||||
* becomes invalid once the target device is removed from the bus and may change
|
||||
* on the next addition of the device.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*
|
||||
* \return The internally used index of the target device.
|
||||
*/
|
||||
VIGEM_API ULONG vigem_target_get_index(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_TARGET_TYPE vigem_target_get_type(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Returns the type of the provided target device object.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 28.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*
|
||||
* \return A VIGEM_TARGET_TYPE.
|
||||
*/
|
||||
VIGEM_API VIGEM_TARGET_TYPE vigem_target_get_type(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn BOOL vigem_target_is_attached(PVIGEM_TARGET target);
|
||||
*
|
||||
* \brief Returns TRUE if the provided target device object is currently
|
||||
* attached to the bus, FALSE otherwise.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 30.08.2017
|
||||
*
|
||||
* \param target The target device object.
|
||||
*
|
||||
* \return TRUE if device is attached to the bus, FALSE otherwise.
|
||||
*/
|
||||
VIGEM_API BOOL vigem_target_is_attached(PVIGEM_TARGET target);
|
||||
|
||||
/**
|
||||
* \fn VIGEM_API VIGEM_ERROR vigem_target_x360_get_user_index(PVIGEM_CLIENT
|
||||
* vigem, PVIGEM_TARGET target, PULONG index);
|
||||
*
|
||||
* \brief Returns the user index of the emulated Xenon device. This value
|
||||
* correspondents to the (zero-based) index number representing the player
|
||||
* number via LED present on a physical controller and is compatible to the
|
||||
* dwUserIndex propery of the XInput* APIs.
|
||||
*
|
||||
* \author Benjamin "Nefarius" H<>glinger
|
||||
* \date 10.05.2018
|
||||
*
|
||||
* \param vigem The driver connection object.
|
||||
* \param target The target device object.
|
||||
* \param index The (zero-based) user index of the Xenon device.
|
||||
*
|
||||
* \return A VIGEM_ERROR.
|
||||
*/
|
||||
VIGEM_API VIGEM_ERROR vigem_target_x360_get_user_index(
|
||||
PVIGEM_CLIENT vigem, PVIGEM_TARGET target, PULONG index);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // ViGEmClient_h__
|
||||
191
src/imports/ViGEm/Common.h
Normal file
191
src/imports/ViGEm/Common.h
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017-2019 Nefarius Software Solutions e.U. and Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// Represents the desired target type for the emulated device.
|
||||
//
|
||||
typedef enum _VIGEM_TARGET_TYPE {
|
||||
//
|
||||
// Microsoft Xbox 360 Controller (wired)
|
||||
//
|
||||
Xbox360Wired = 0,
|
||||
//
|
||||
// Sony DualShock 4 (wired)
|
||||
//
|
||||
DualShock4Wired = 2 // NOTE: 1 skipped on purpose to maintain compatibility
|
||||
|
||||
} VIGEM_TARGET_TYPE,
|
||||
*PVIGEM_TARGET_TYPE;
|
||||
|
||||
//
|
||||
// Possible XUSB report buttons.
|
||||
//
|
||||
typedef enum _XUSB_BUTTON {
|
||||
XUSB_GAMEPAD_DPAD_UP = 0x0001,
|
||||
XUSB_GAMEPAD_DPAD_DOWN = 0x0002,
|
||||
XUSB_GAMEPAD_DPAD_LEFT = 0x0004,
|
||||
XUSB_GAMEPAD_DPAD_RIGHT = 0x0008,
|
||||
XUSB_GAMEPAD_START = 0x0010,
|
||||
XUSB_GAMEPAD_BACK = 0x0020,
|
||||
XUSB_GAMEPAD_LEFT_THUMB = 0x0040,
|
||||
XUSB_GAMEPAD_RIGHT_THUMB = 0x0080,
|
||||
XUSB_GAMEPAD_LEFT_SHOULDER = 0x0100,
|
||||
XUSB_GAMEPAD_RIGHT_SHOULDER = 0x0200,
|
||||
XUSB_GAMEPAD_GUIDE = 0x0400,
|
||||
XUSB_GAMEPAD_A = 0x1000,
|
||||
XUSB_GAMEPAD_B = 0x2000,
|
||||
XUSB_GAMEPAD_X = 0x4000,
|
||||
XUSB_GAMEPAD_Y = 0x8000
|
||||
|
||||
} XUSB_BUTTON,
|
||||
*PXUSB_BUTTON;
|
||||
|
||||
//
|
||||
// Represents an XINPUT_GAMEPAD-compatible report structure.
|
||||
//
|
||||
typedef struct _XUSB_REPORT {
|
||||
USHORT wButtons;
|
||||
BYTE bLeftTrigger;
|
||||
BYTE bRightTrigger;
|
||||
SHORT sThumbLX;
|
||||
SHORT sThumbLY;
|
||||
SHORT sThumbRX;
|
||||
SHORT sThumbRY;
|
||||
|
||||
} XUSB_REPORT, *PXUSB_REPORT;
|
||||
|
||||
//
|
||||
// Initializes a _XUSB_REPORT structure.
|
||||
//
|
||||
VOID FORCEINLINE XUSB_REPORT_INIT(_Out_ PXUSB_REPORT Report)
|
||||
{
|
||||
RtlZeroMemory(Report, sizeof(XUSB_REPORT));
|
||||
}
|
||||
|
||||
//
|
||||
// The color value (RGB) of a DualShock 4 Lightbar
|
||||
//
|
||||
typedef struct _DS4_LIGHTBAR_COLOR {
|
||||
//
|
||||
// Red part of the Lightbar (0-255).
|
||||
//
|
||||
UCHAR Red;
|
||||
|
||||
//
|
||||
// Green part of the Lightbar (0-255).
|
||||
//
|
||||
UCHAR Green;
|
||||
|
||||
//
|
||||
// Blue part of the Lightbar (0-255).
|
||||
//
|
||||
UCHAR Blue;
|
||||
|
||||
} DS4_LIGHTBAR_COLOR, *PDS4_LIGHTBAR_COLOR;
|
||||
|
||||
//
|
||||
// DualShock 4 digital buttons
|
||||
//
|
||||
typedef enum _DS4_BUTTONS {
|
||||
DS4_BUTTON_THUMB_RIGHT = 1 << 15,
|
||||
DS4_BUTTON_THUMB_LEFT = 1 << 14,
|
||||
DS4_BUTTON_OPTIONS = 1 << 13,
|
||||
DS4_BUTTON_SHARE = 1 << 12,
|
||||
DS4_BUTTON_TRIGGER_RIGHT = 1 << 11,
|
||||
DS4_BUTTON_TRIGGER_LEFT = 1 << 10,
|
||||
DS4_BUTTON_SHOULDER_RIGHT = 1 << 9,
|
||||
DS4_BUTTON_SHOULDER_LEFT = 1 << 8,
|
||||
DS4_BUTTON_TRIANGLE = 1 << 7,
|
||||
DS4_BUTTON_CIRCLE = 1 << 6,
|
||||
DS4_BUTTON_CROSS = 1 << 5,
|
||||
DS4_BUTTON_SQUARE = 1 << 4
|
||||
|
||||
} DS4_BUTTONS,
|
||||
*PDS4_BUTTONS;
|
||||
|
||||
//
|
||||
// DualShock 4 special buttons
|
||||
//
|
||||
typedef enum _DS4_SPECIAL_BUTTONS {
|
||||
DS4_SPECIAL_BUTTON_PS = 1 << 0,
|
||||
DS4_SPECIAL_BUTTON_TOUCHPAD = 1 << 1
|
||||
|
||||
} DS4_SPECIAL_BUTTONS,
|
||||
*PDS4_SPECIAL_BUTTONS;
|
||||
|
||||
//
|
||||
// DualShock 4 directional pad (HAT) values
|
||||
//
|
||||
typedef enum _DS4_DPAD_DIRECTIONS {
|
||||
DS4_BUTTON_DPAD_NONE = 0x8,
|
||||
DS4_BUTTON_DPAD_NORTHWEST = 0x7,
|
||||
DS4_BUTTON_DPAD_WEST = 0x6,
|
||||
DS4_BUTTON_DPAD_SOUTHWEST = 0x5,
|
||||
DS4_BUTTON_DPAD_SOUTH = 0x4,
|
||||
DS4_BUTTON_DPAD_SOUTHEAST = 0x3,
|
||||
DS4_BUTTON_DPAD_EAST = 0x2,
|
||||
DS4_BUTTON_DPAD_NORTHEAST = 0x1,
|
||||
DS4_BUTTON_DPAD_NORTH = 0x0
|
||||
|
||||
} DS4_DPAD_DIRECTIONS,
|
||||
*PDS4_DPAD_DIRECTIONS;
|
||||
|
||||
//
|
||||
// DualShock 4 HID Input report
|
||||
//
|
||||
typedef struct _DS4_REPORT {
|
||||
BYTE bThumbLX;
|
||||
BYTE bThumbLY;
|
||||
BYTE bThumbRX;
|
||||
BYTE bThumbRY;
|
||||
USHORT wButtons;
|
||||
BYTE bSpecial;
|
||||
BYTE bTriggerL;
|
||||
BYTE bTriggerR;
|
||||
|
||||
} DS4_REPORT, *PDS4_REPORT;
|
||||
|
||||
//
|
||||
// Sets the current state of the D-PAD on a DualShock 4 report.
|
||||
//
|
||||
VOID FORCEINLINE
|
||||
DS4_SET_DPAD(_Out_ PDS4_REPORT Report, _In_ DS4_DPAD_DIRECTIONS Dpad)
|
||||
{
|
||||
Report->wButtons &= ~0xF;
|
||||
Report->wButtons |= (USHORT) Dpad;
|
||||
}
|
||||
|
||||
VOID FORCEINLINE DS4_REPORT_INIT(_Out_ PDS4_REPORT Report)
|
||||
{
|
||||
RtlZeroMemory(Report, sizeof(DS4_REPORT));
|
||||
|
||||
Report->bThumbLX = 0x80;
|
||||
Report->bThumbLY = 0x80;
|
||||
Report->bThumbRX = 0x80;
|
||||
Report->bThumbRY = 0x80;
|
||||
|
||||
DS4_SET_DPAD(Report, DS4_BUTTON_DPAD_NONE);
|
||||
}
|
||||
68
src/imports/ViGEm/Util.h
Normal file
68
src/imports/ViGEm/Util.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include "ViGEm/Common.h"
|
||||
#include <limits.h>
|
||||
|
||||
VOID FORCEINLINE
|
||||
XUSB_TO_DS4_REPORT(_Out_ PXUSB_REPORT Input, _Out_ PDS4_REPORT Output)
|
||||
{
|
||||
if (Input->wButtons & XUSB_GAMEPAD_BACK)
|
||||
Output->wButtons |= DS4_BUTTON_SHARE;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_START)
|
||||
Output->wButtons |= DS4_BUTTON_OPTIONS;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_LEFT_THUMB)
|
||||
Output->wButtons |= DS4_BUTTON_THUMB_LEFT;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_RIGHT_THUMB)
|
||||
Output->wButtons |= DS4_BUTTON_THUMB_RIGHT;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_LEFT_SHOULDER)
|
||||
Output->wButtons |= DS4_BUTTON_SHOULDER_LEFT;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_RIGHT_SHOULDER)
|
||||
Output->wButtons |= DS4_BUTTON_SHOULDER_RIGHT;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_GUIDE)
|
||||
Output->bSpecial |= DS4_SPECIAL_BUTTON_PS;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_A)
|
||||
Output->wButtons |= DS4_BUTTON_CROSS;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_B)
|
||||
Output->wButtons |= DS4_BUTTON_CIRCLE;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_X)
|
||||
Output->wButtons |= DS4_BUTTON_SQUARE;
|
||||
if (Input->wButtons & XUSB_GAMEPAD_Y)
|
||||
Output->wButtons |= DS4_BUTTON_TRIANGLE;
|
||||
|
||||
Output->bTriggerL = Input->bLeftTrigger;
|
||||
Output->bTriggerR = Input->bRightTrigger;
|
||||
|
||||
if (Input->bLeftTrigger > 0)
|
||||
Output->wButtons |= DS4_BUTTON_TRIGGER_LEFT;
|
||||
if (Input->bRightTrigger > 0)
|
||||
Output->wButtons |= DS4_BUTTON_TRIGGER_RIGHT;
|
||||
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_UP)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_NORTH);
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_RIGHT)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_EAST);
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_DOWN)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_SOUTH);
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_LEFT)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_WEST);
|
||||
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_UP &&
|
||||
Input->wButtons & XUSB_GAMEPAD_DPAD_RIGHT)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_NORTHEAST);
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_RIGHT &&
|
||||
Input->wButtons & XUSB_GAMEPAD_DPAD_DOWN)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_SOUTHEAST);
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_DOWN &&
|
||||
Input->wButtons & XUSB_GAMEPAD_DPAD_LEFT)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_SOUTHWEST);
|
||||
if (Input->wButtons & XUSB_GAMEPAD_DPAD_LEFT &&
|
||||
Input->wButtons & XUSB_GAMEPAD_DPAD_UP)
|
||||
DS4_SET_DPAD(Output, DS4_BUTTON_DPAD_NORTHWEST);
|
||||
|
||||
Output->bThumbLX = ((Input->sThumbLX + ((USHRT_MAX / 2) + 1)) / 257);
|
||||
Output->bThumbLY = (-(Input->sThumbLY + ((USHRT_MAX / 2) - 1)) / 257);
|
||||
Output->bThumbLY = (Output->bThumbLY == 0) ? 0xFF : Output->bThumbLY;
|
||||
Output->bThumbRX = ((Input->sThumbRX + ((USHRT_MAX / 2) + 1)) / 257);
|
||||
Output->bThumbRY = (-(Input->sThumbRY + ((USHRT_MAX / 2) + 1)) / 257);
|
||||
Output->bThumbRY = (Output->bThumbRY == 0) ? 0xFF : Output->bThumbRY;
|
||||
}
|
||||
399
src/imports/ViGEm/km/BusShared.h
Normal file
399
src/imports/ViGEm/km/BusShared.h
Normal file
@@ -0,0 +1,399 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016-2019 Nefarius Software Solutions e.U. and Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
//
|
||||
// GUID identifying the bus device. Used by client library to detect and
|
||||
// communicate.
|
||||
//
|
||||
// IMPORTANT: make sure to change this value if you fork it or introduce
|
||||
// breaking changes!
|
||||
//
|
||||
// {96E42B22-F5E9-42F8-B043-ED0F932F014F}
|
||||
DEFINE_GUID(
|
||||
GUID_DEVINTERFACE_BUSENUM_VIGEM,
|
||||
0x96E42B22,
|
||||
0xF5E9,
|
||||
0x42F8,
|
||||
0xB0,
|
||||
0x43,
|
||||
0xED,
|
||||
0x0F,
|
||||
0x93,
|
||||
0x2F,
|
||||
0x01,
|
||||
0x4F);
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ViGEm/Common.h"
|
||||
|
||||
//
|
||||
// Common version for user-mode library and driver compatibility
|
||||
//
|
||||
// On initialization, the user-mode library has this number embedded
|
||||
// and sends it to the bus on its enumeration. The bus compares this
|
||||
// number to the one it was compiled with. If they match, the bus
|
||||
// access is permitted and success reported. If they mismatch, an
|
||||
// error is reported and the user-mode library skips this instance.
|
||||
//
|
||||
#define VIGEM_COMMON_VERSION 0x0001
|
||||
|
||||
#define FILE_DEVICE_BUSENUM FILE_DEVICE_BUS_EXTENDER
|
||||
#define BUSENUM_IOCTL(_index_) \
|
||||
CTL_CODE(FILE_DEVICE_BUSENUM, _index_, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
#define BUSENUM_W_IOCTL(_index_) \
|
||||
CTL_CODE(FILE_DEVICE_BUSENUM, _index_, METHOD_BUFFERED, FILE_WRITE_DATA)
|
||||
#define BUSENUM_R_IOCTL(_index_) \
|
||||
CTL_CODE(FILE_DEVICE_BUSENUM, _index_, METHOD_BUFFERED, FILE_READ_DATA)
|
||||
#define BUSENUM_RW_IOCTL(_index_) \
|
||||
CTL_CODE( \
|
||||
FILE_DEVICE_BUSENUM, \
|
||||
_index_, \
|
||||
METHOD_BUFFERED, \
|
||||
FILE_WRITE_DATA | FILE_READ_DATA)
|
||||
|
||||
#define IOCTL_VIGEM_BASE 0x801
|
||||
|
||||
//
|
||||
// IO control codes
|
||||
//
|
||||
#define IOCTL_VIGEM_PLUGIN_TARGET BUSENUM_W_IOCTL(IOCTL_VIGEM_BASE + 0x000)
|
||||
#define IOCTL_VIGEM_UNPLUG_TARGET BUSENUM_W_IOCTL(IOCTL_VIGEM_BASE + 0x001)
|
||||
#define IOCTL_VIGEM_CHECK_VERSION BUSENUM_W_IOCTL(IOCTL_VIGEM_BASE + 0x002)
|
||||
|
||||
#define IOCTL_XUSB_REQUEST_NOTIFICATION \
|
||||
BUSENUM_RW_IOCTL(IOCTL_VIGEM_BASE + 0x200)
|
||||
#define IOCTL_XUSB_SUBMIT_REPORT BUSENUM_W_IOCTL(IOCTL_VIGEM_BASE + 0x201)
|
||||
#define IOCTL_DS4_SUBMIT_REPORT BUSENUM_W_IOCTL(IOCTL_VIGEM_BASE + 0x202)
|
||||
#define IOCTL_DS4_REQUEST_NOTIFICATION BUSENUM_W_IOCTL(IOCTL_VIGEM_BASE + 0x203)
|
||||
//#define IOCTL_XGIP_SUBMIT_REPORT BUSENUM_W_IOCTL (IOCTL_VIGEM_BASE +
|
||||
//0x204) #define IOCTL_XGIP_SUBMIT_INTERRUPT BUSENUM_W_IOCTL
|
||||
//(IOCTL_VIGEM_BASE + 0x205)
|
||||
#define IOCTL_XUSB_GET_USER_INDEX BUSENUM_RW_IOCTL(IOCTL_VIGEM_BASE + 0x206)
|
||||
|
||||
//
|
||||
// Data structure used in PlugIn and UnPlug ioctls
|
||||
//
|
||||
|
||||
#pragma region Plugin
|
||||
|
||||
//
|
||||
// Data structure used in IOCTL_VIGEM_PLUGIN_TARGET requests.
|
||||
//
|
||||
typedef struct _VIGEM_PLUGIN_TARGET {
|
||||
//
|
||||
// sizeof (struct _BUSENUM_HARDWARE)
|
||||
//
|
||||
IN ULONG Size;
|
||||
|
||||
//
|
||||
// Serial number of target device.
|
||||
//
|
||||
IN ULONG SerialNo;
|
||||
|
||||
//
|
||||
// Type of the target device to emulate.
|
||||
//
|
||||
VIGEM_TARGET_TYPE TargetType;
|
||||
|
||||
//
|
||||
// If set, the vendor ID the emulated device is reporting
|
||||
//
|
||||
USHORT VendorId;
|
||||
|
||||
//
|
||||
// If set, the product ID the emulated device is reporting
|
||||
//
|
||||
USHORT ProductId;
|
||||
|
||||
} VIGEM_PLUGIN_TARGET, *PVIGEM_PLUGIN_TARGET;
|
||||
|
||||
//
|
||||
// Initializes a VIGEM_PLUGIN_TARGET structure.
|
||||
//
|
||||
VOID FORCEINLINE VIGEM_PLUGIN_TARGET_INIT(
|
||||
_Out_ PVIGEM_PLUGIN_TARGET PlugIn,
|
||||
_In_ ULONG SerialNo,
|
||||
_In_ VIGEM_TARGET_TYPE TargetType)
|
||||
{
|
||||
RtlZeroMemory(PlugIn, sizeof(VIGEM_PLUGIN_TARGET));
|
||||
|
||||
PlugIn->Size = sizeof(VIGEM_PLUGIN_TARGET);
|
||||
PlugIn->SerialNo = SerialNo;
|
||||
PlugIn->TargetType = TargetType;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Unplug
|
||||
|
||||
//
|
||||
// Data structure used in IOCTL_VIGEM_UNPLUG_TARGET requests.
|
||||
//
|
||||
typedef struct _VIGEM_UNPLUG_TARGET {
|
||||
//
|
||||
// sizeof (struct _REMOVE_HARDWARE)
|
||||
//
|
||||
IN ULONG Size;
|
||||
|
||||
//
|
||||
// Serial number of target device.
|
||||
//
|
||||
ULONG SerialNo;
|
||||
|
||||
} VIGEM_UNPLUG_TARGET, *PVIGEM_UNPLUG_TARGET;
|
||||
|
||||
//
|
||||
// Initializes a VIGEM_UNPLUG_TARGET structure.
|
||||
//
|
||||
VOID FORCEINLINE
|
||||
VIGEM_UNPLUG_TARGET_INIT(_Out_ PVIGEM_UNPLUG_TARGET UnPlug, _In_ ULONG SerialNo)
|
||||
{
|
||||
RtlZeroMemory(UnPlug, sizeof(VIGEM_UNPLUG_TARGET));
|
||||
|
||||
UnPlug->Size = sizeof(VIGEM_UNPLUG_TARGET);
|
||||
UnPlug->SerialNo = SerialNo;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Check version
|
||||
|
||||
typedef struct _VIGEM_CHECK_VERSION {
|
||||
IN ULONG Size;
|
||||
|
||||
IN ULONG Version;
|
||||
|
||||
} VIGEM_CHECK_VERSION, *PVIGEM_CHECK_VERSION;
|
||||
|
||||
VOID FORCEINLINE VIGEM_CHECK_VERSION_INIT(
|
||||
_Out_ PVIGEM_CHECK_VERSION CheckVersion, _In_ ULONG Version)
|
||||
{
|
||||
RtlZeroMemory(CheckVersion, sizeof(VIGEM_CHECK_VERSION));
|
||||
|
||||
CheckVersion->Size = sizeof(VIGEM_CHECK_VERSION);
|
||||
CheckVersion->Version = Version;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region XUSB(aka Xbox 360 device) section
|
||||
|
||||
//
|
||||
// Data structure used in IOCTL_XUSB_REQUEST_NOTIFICATION requests.
|
||||
//
|
||||
typedef struct _XUSB_REQUEST_NOTIFICATION {
|
||||
//
|
||||
// sizeof(struct _XUSB_REQUEST_NOTIFICATION)
|
||||
//
|
||||
ULONG Size;
|
||||
|
||||
//
|
||||
// Serial number of target device.
|
||||
//
|
||||
ULONG SerialNo;
|
||||
|
||||
//
|
||||
// Vibration intensity value of the large motor (0-255).
|
||||
//
|
||||
UCHAR LargeMotor;
|
||||
|
||||
//
|
||||
// Vibration intensity value of the small motor (0-255).
|
||||
//
|
||||
UCHAR SmallMotor;
|
||||
|
||||
//
|
||||
// Index number of the slot/LED that XUSB.sys has assigned.
|
||||
//
|
||||
UCHAR LedNumber;
|
||||
|
||||
} XUSB_REQUEST_NOTIFICATION, *PXUSB_REQUEST_NOTIFICATION;
|
||||
|
||||
//
|
||||
// Initializes a XUSB_REQUEST_NOTIFICATION structure.
|
||||
//
|
||||
VOID FORCEINLINE XUSB_REQUEST_NOTIFICATION_INIT(
|
||||
_Out_ PXUSB_REQUEST_NOTIFICATION Request, _In_ ULONG SerialNo)
|
||||
{
|
||||
RtlZeroMemory(Request, sizeof(XUSB_REQUEST_NOTIFICATION));
|
||||
|
||||
Request->Size = sizeof(XUSB_REQUEST_NOTIFICATION);
|
||||
Request->SerialNo = SerialNo;
|
||||
}
|
||||
|
||||
//
|
||||
// Data structure used in IOCTL_XUSB_SUBMIT_REPORT requests.
|
||||
//
|
||||
typedef struct _XUSB_SUBMIT_REPORT {
|
||||
//
|
||||
// sizeof(struct _XUSB_SUBMIT_REPORT)
|
||||
//
|
||||
ULONG Size;
|
||||
|
||||
//
|
||||
// Serial number of target device.
|
||||
//
|
||||
ULONG SerialNo;
|
||||
|
||||
//
|
||||
// Report to submit to the target device.
|
||||
//
|
||||
XUSB_REPORT Report;
|
||||
|
||||
} XUSB_SUBMIT_REPORT, *PXUSB_SUBMIT_REPORT;
|
||||
|
||||
//
|
||||
// Initializes an XUSB report.
|
||||
//
|
||||
VOID FORCEINLINE
|
||||
XUSB_SUBMIT_REPORT_INIT(_Out_ PXUSB_SUBMIT_REPORT Report, _In_ ULONG SerialNo)
|
||||
{
|
||||
RtlZeroMemory(Report, sizeof(XUSB_SUBMIT_REPORT));
|
||||
|
||||
Report->Size = sizeof(XUSB_SUBMIT_REPORT);
|
||||
Report->SerialNo = SerialNo;
|
||||
}
|
||||
|
||||
typedef struct _XUSB_GET_USER_INDEX {
|
||||
//
|
||||
// sizeof(struct _XUSB_GET_USER_INDEX)
|
||||
//
|
||||
ULONG Size;
|
||||
|
||||
//
|
||||
// Serial number of target device.
|
||||
//
|
||||
ULONG SerialNo;
|
||||
|
||||
//
|
||||
// User index of target device.
|
||||
//
|
||||
OUT ULONG UserIndex;
|
||||
|
||||
} XUSB_GET_USER_INDEX, *PXUSB_GET_USER_INDEX;
|
||||
|
||||
//
|
||||
// Initializes XUSB_GET_USER_INDEX structure.
|
||||
//
|
||||
VOID FORCEINLINE XUSB_GET_USER_INDEX_INIT(
|
||||
_Out_ PXUSB_GET_USER_INDEX GetRequest, _In_ ULONG SerialNo)
|
||||
{
|
||||
RtlZeroMemory(GetRequest, sizeof(XUSB_GET_USER_INDEX));
|
||||
|
||||
GetRequest->Size = sizeof(XUSB_GET_USER_INDEX);
|
||||
GetRequest->SerialNo = SerialNo;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region DualShock 4 section
|
||||
|
||||
typedef struct _DS4_OUTPUT_REPORT {
|
||||
//
|
||||
// Vibration intensity value of the small motor (0-255).
|
||||
//
|
||||
UCHAR SmallMotor;
|
||||
|
||||
//
|
||||
// Vibration intensity value of the large motor (0-255).
|
||||
//
|
||||
UCHAR LargeMotor;
|
||||
|
||||
//
|
||||
// Color values of the Lightbar.
|
||||
//
|
||||
DS4_LIGHTBAR_COLOR LightbarColor;
|
||||
|
||||
} DS4_OUTPUT_REPORT, *PDS4_OUTPUT_REPORT;
|
||||
|
||||
//
|
||||
// Data structure used in IOCTL_DS4_REQUEST_NOTIFICATION requests.
|
||||
//
|
||||
typedef struct _DS4_REQUEST_NOTIFICATION {
|
||||
//
|
||||
// sizeof(struct _XUSB_REQUEST_NOTIFICATION)
|
||||
//
|
||||
ULONG Size;
|
||||
|
||||
//
|
||||
// Serial number of target device.
|
||||
//
|
||||
ULONG SerialNo;
|
||||
|
||||
//
|
||||
// The HID output report
|
||||
//
|
||||
DS4_OUTPUT_REPORT Report;
|
||||
|
||||
} DS4_REQUEST_NOTIFICATION, *PDS4_REQUEST_NOTIFICATION;
|
||||
|
||||
//
|
||||
// Initializes a DS4_REQUEST_NOTIFICATION structure.
|
||||
//
|
||||
VOID FORCEINLINE DS4_REQUEST_NOTIFICATION_INIT(
|
||||
_Out_ PDS4_REQUEST_NOTIFICATION Request, _In_ ULONG SerialNo)
|
||||
{
|
||||
RtlZeroMemory(Request, sizeof(DS4_REQUEST_NOTIFICATION));
|
||||
|
||||
Request->Size = sizeof(DS4_REQUEST_NOTIFICATION);
|
||||
Request->SerialNo = SerialNo;
|
||||
}
|
||||
|
||||
//
|
||||
// DualShock 4 request data
|
||||
//
|
||||
typedef struct _DS4_SUBMIT_REPORT {
|
||||
//
|
||||
// sizeof(struct _DS4_SUBMIT_REPORT)
|
||||
//
|
||||
ULONG Size;
|
||||
|
||||
//
|
||||
// Serial number of target device.
|
||||
//
|
||||
ULONG SerialNo;
|
||||
|
||||
//
|
||||
// HID Input report
|
||||
//
|
||||
DS4_REPORT Report;
|
||||
|
||||
} DS4_SUBMIT_REPORT, *PDS4_SUBMIT_REPORT;
|
||||
|
||||
//
|
||||
// Initializes a DualShock 4 report.
|
||||
//
|
||||
VOID FORCEINLINE
|
||||
DS4_SUBMIT_REPORT_INIT(_Out_ PDS4_SUBMIT_REPORT Report, _In_ ULONG SerialNo)
|
||||
{
|
||||
RtlZeroMemory(Report, sizeof(DS4_SUBMIT_REPORT));
|
||||
|
||||
Report->Size = sizeof(DS4_SUBMIT_REPORT);
|
||||
Report->SerialNo = SerialNo;
|
||||
|
||||
DS4_REPORT_INIT(&Report->Report);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
@@ -36,7 +36,8 @@ enum property_type {
|
||||
PROPERTY_TYPE_S64 = 8,
|
||||
PROPERTY_TYPE_U64 = 9,
|
||||
PROPERTY_TYPE_BIN = 10,
|
||||
PROPERTY_TYPE_STR = 11
|
||||
PROPERTY_TYPE_STR = 11,
|
||||
PROPERTY_TYPE_BOOL = 52
|
||||
};
|
||||
|
||||
struct property;
|
||||
@@ -45,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 {
|
||||
@@ -57,8 +64,6 @@ enum psmap_type {
|
||||
PSMAP_TYPE_S64 = 8,
|
||||
PSMAP_TYPE_U64 = 9,
|
||||
PSMAP_TYPE_STR = 10,
|
||||
/* Used on avs 803 instead of value 10 */
|
||||
PSMAP_TYPE_STR_LEGACY = 11,
|
||||
PSMAP_TYPE_ATTR = 45,
|
||||
PSMAP_TYPE_BOOL = 50,
|
||||
};
|
||||
@@ -230,4 +235,6 @@ int avs_fs_addfs(void *filesys_struct);
|
||||
int avs_fs_mount(
|
||||
const char *mountpoint, const char *fsroot, const char *fstype, void *data);
|
||||
|
||||
bool avs_is_active();
|
||||
|
||||
#endif
|
||||
|
||||
19
src/imports/ch341.h
Normal file
19
src/imports/ch341.h
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* This is the header for ch341dll.dll, a library for interfacing with the
|
||||
* CH341 USB to serial/parallel port chip. Magic Box uses this for their
|
||||
* proprietary IO, and it provides access to the panel sensors.
|
||||
*
|
||||
* The full .h for this file is floating around online with many more functions
|
||||
* and comments (in Chinese). Only the bare minimum definitions are provided
|
||||
* here for use in jbio-magicbox
|
||||
*/
|
||||
|
||||
#ifndef IMPORTS_CH341_H
|
||||
#define IMPORTS_CH341_H
|
||||
|
||||
HANDLE WINAPI CH341OpenDevice(ULONG iIndex);
|
||||
VOID WINAPI CH341CloseDevice(ULONG iIndex);
|
||||
BOOL WINAPI CH341EppReadData(ULONG iIndex, PVOID oBuffer, PULONG ioLength);
|
||||
BOOL WINAPI CH341EppSetAddr(ULONG iIndex, UCHAR iAddr);
|
||||
|
||||
#endif
|
||||
@@ -7,6 +7,7 @@ EXPORTS
|
||||
SMX_GetInfo
|
||||
SMX_GetInputState
|
||||
SMX_SetLights
|
||||
SMX_SetLights2
|
||||
SMX_ReenableAutoLights
|
||||
SMX_GetConfig
|
||||
SMX_SetConfig
|
||||
|
||||
27
src/imports/import_32_indep_ViGEmClient.def
Normal file
27
src/imports/import_32_indep_ViGEmClient.def
Normal file
@@ -0,0 +1,27 @@
|
||||
LIBRARY ViGEmClient
|
||||
|
||||
EXPORTS
|
||||
vigem_alloc
|
||||
vigem_connect
|
||||
vigem_disconnect
|
||||
vigem_free
|
||||
vigem_target_add
|
||||
vigem_target_add_async
|
||||
vigem_target_ds4_alloc
|
||||
vigem_target_ds4_register_notification
|
||||
vigem_target_ds4_unregister_notification
|
||||
vigem_target_ds4_update
|
||||
vigem_target_free
|
||||
vigem_target_get_index
|
||||
vigem_target_get_pid
|
||||
vigem_target_get_type
|
||||
vigem_target_get_vid
|
||||
vigem_target_is_attached
|
||||
vigem_target_remove
|
||||
vigem_target_set_pid
|
||||
vigem_target_set_vid
|
||||
vigem_target_x360_alloc
|
||||
vigem_target_x360_get_user_index
|
||||
vigem_target_x360_register_notification
|
||||
vigem_target_x360_unregister_notification
|
||||
vigem_target_x360_update
|
||||
7
src/imports/import_32_indep_ch341.def
Normal file
7
src/imports/import_32_indep_ch341.def
Normal file
@@ -0,0 +1,7 @@
|
||||
LIBRARY ch341dll
|
||||
|
||||
EXPORTS
|
||||
CH341OpenDevice@4=CH341OpenDevice
|
||||
CH341CloseDevice@4=CH341CloseDevice
|
||||
CH341EppReadData@12=CH341EppReadData
|
||||
CH341EppSetAddr@8=CH341EppSetAddr
|
||||
7
src/imports/import_64_1509_avs-ea3.def
Normal file
7
src/imports/import_64_1509_avs-ea3.def
Normal file
@@ -0,0 +1,7 @@
|
||||
LIBRARY libavs-win64-ea3
|
||||
|
||||
EXPORTS
|
||||
ea3_boot @8 NONAME
|
||||
ea3_get_boot_status @11 NONAME
|
||||
ea3_get_pp_status @10 NONAME
|
||||
ea3_shutdown @9 NONAME
|
||||
32
src/imports/import_64_1509_avs.def
Normal file
32
src/imports/import_64_1509_avs.def
Normal file
@@ -0,0 +1,32 @@
|
||||
LIBRARY libavs-win64
|
||||
|
||||
EXPORTS
|
||||
avs_boot @285 NONAME
|
||||
avs_fs_close @65 NONAME
|
||||
avs_fs_lseek @59 NONAME
|
||||
avs_fs_lseek64 @60 NONAME
|
||||
avs_fs_open @58 NONAME
|
||||
avs_fs_read @61 NONAME
|
||||
avs_net_ctrl @98 NONAME
|
||||
avs_shutdown @286 NONAME
|
||||
avs_thread_create @6 NONAME
|
||||
avs_thread_destroy @8 NONAME
|
||||
avs_thread_exit @12 NONAME
|
||||
avs_thread_join @13 NONAME
|
||||
log_body_fatal @357 NONAME
|
||||
log_body_info @359 NONAME
|
||||
log_body_misc @360 NONAME
|
||||
log_body_warning @358 NONAME
|
||||
property_create @127 NONAME
|
||||
property_desc_to_buffer @129 NONAME
|
||||
property_destroy @128 NONAME
|
||||
property_insert_read @131 NONAME
|
||||
property_node_create @145 NONAME
|
||||
property_node_refer @158 NONAME
|
||||
property_node_remove @146 NONAME
|
||||
property_psmap_export @162 NONAME
|
||||
property_psmap_import @161 NONAME
|
||||
property_read_query_memsize @159 NONAME
|
||||
property_search @144 NONAME
|
||||
std_getenv @207 NONAME
|
||||
std_setenv @208 NONAME
|
||||
@@ -23,6 +23,7 @@ EXPORTS
|
||||
std_setenv @213 NONAME
|
||||
avs_boot @298 NONAME
|
||||
avs_shutdown @299 NONAME
|
||||
avs_is_active @302 NONAME
|
||||
log_body_fatal @379 NONAME
|
||||
log_body_warning @380 NONAME
|
||||
log_body_info @381 NONAME
|
||||
|
||||
18
src/imports/import_64_indep_SMX.def
Normal file
18
src/imports/import_64_indep_SMX.def
Normal file
@@ -0,0 +1,18 @@
|
||||
LIBRARY SMX
|
||||
|
||||
EXPORTS
|
||||
SMX_Start
|
||||
SMX_Stop
|
||||
SMX_SetLogCallback
|
||||
SMX_GetInfo
|
||||
SMX_GetInputState
|
||||
SMX_SetLights
|
||||
SMX_SetLights2
|
||||
SMX_ReenableAutoLights
|
||||
SMX_GetConfig
|
||||
SMX_SetConfig
|
||||
SMX_FactoryReset
|
||||
SMX_ForceRecalibration
|
||||
SMX_SetTestMode
|
||||
SMX_GetTestData
|
||||
SMX_Version
|
||||
27
src/imports/import_64_indep_ViGEmClient.def
Normal file
27
src/imports/import_64_indep_ViGEmClient.def
Normal file
@@ -0,0 +1,27 @@
|
||||
LIBRARY ViGEmClient
|
||||
|
||||
EXPORTS
|
||||
vigem_alloc
|
||||
vigem_connect
|
||||
vigem_disconnect
|
||||
vigem_free
|
||||
vigem_target_add
|
||||
vigem_target_add_async
|
||||
vigem_target_ds4_alloc
|
||||
vigem_target_ds4_register_notification
|
||||
vigem_target_ds4_unregister_notification
|
||||
vigem_target_ds4_update
|
||||
vigem_target_free
|
||||
vigem_target_get_index
|
||||
vigem_target_get_pid
|
||||
vigem_target_get_type
|
||||
vigem_target_get_vid
|
||||
vigem_target_is_attached
|
||||
vigem_target_remove
|
||||
vigem_target_set_pid
|
||||
vigem_target_set_vid
|
||||
vigem_target_x360_alloc
|
||||
vigem_target_x360_get_user_index
|
||||
vigem_target_x360_register_notification
|
||||
vigem_target_x360_unregister_notification
|
||||
vigem_target_x360_update
|
||||
@@ -5,8 +5,13 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "acio/h44b.h"
|
||||
#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
|
||||
@@ -34,7 +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)
|
||||
@@ -64,13 +73,27 @@ struct ac_io_message {
|
||||
uint8_t raw[0xFF];
|
||||
uint8_t count;
|
||||
uint8_t status;
|
||||
uint8_t param;
|
||||
struct ac_io_version version;
|
||||
|
||||
struct ac_io_h44b_output h44b_output;
|
||||
|
||||
struct ac_io_icca_misc icca_misc;
|
||||
struct ac_io_icca_state icca_state;
|
||||
|
||||
struct ac_io_kfca_poll_in kfca_poll_in;
|
||||
struct ac_io_kfca_poll_out kfca_poll_out;
|
||||
|
||||
struct ac_io_panb_poll_in panb_poll_in;
|
||||
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;
|
||||
|
||||
|
||||
@@ -14,6 +14,6 @@ struct ac_io_h44b_output {
|
||||
uint8_t right_rgb[3];
|
||||
uint8_t title_rgb[3];
|
||||
uint8_t woofer_rgb[3];
|
||||
};
|
||||
} __attribute__((__packed__));
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
48
src/main/acio/hdxs.h
Normal file
48
src/main/acio/hdxs.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef ACIO_HDXS_H
|
||||
#define ACIO_HDXS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum ac_io_hdxs_cmd {
|
||||
AC_IO_HDXS_CMD_SET_OUTPUTS = 0x0112,
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct ac_io_hdxs_light {
|
||||
uint8_t analog : 7; // rgb component
|
||||
uint8_t bit : 1; // buttons
|
||||
};
|
||||
|
||||
struct ac_io_hdxs_output {
|
||||
uint8_t empty;
|
||||
struct ac_io_hdxs_light lights[12];
|
||||
};
|
||||
|
||||
enum ac_io_hdxs_front_panel_lights {
|
||||
AC_IO_HDXS_OUT_P1_START = 0,
|
||||
AC_IO_HDXS_OUT_P1_UP_DOWN = 1,
|
||||
AC_IO_HDXS_OUT_P1_LEFT_RIGHT = 2,
|
||||
AC_IO_HDXS_OUT_P2_START = 3,
|
||||
AC_IO_HDXS_OUT_P2_UP_DOWN = 4,
|
||||
AC_IO_HDXS_OUT_P2_LEFT_RIGHT = 5,
|
||||
};
|
||||
|
||||
enum ac_io_hdxs_grb_layout {
|
||||
AC_IO_HDXS_GREEN = 0,
|
||||
AC_IO_HDXS_RED = 1,
|
||||
AC_IO_HDXS_BLUE = 2,
|
||||
};
|
||||
|
||||
enum ac_io_hdxs_speaker_lights {
|
||||
AC_IO_HDXS_OUT_P1_SPEAKER_F = 0,
|
||||
AC_IO_HDXS_OUT_P2_SPEAKER_F = 1,
|
||||
AC_IO_HDXS_OUT_P1_SPEAKER_W = 2,
|
||||
AC_IO_HDXS_OUT_P2_SPEAKER_W = 3,
|
||||
};
|
||||
|
||||
_Static_assert(
|
||||
sizeof(struct ac_io_hdxs_output) == 13,
|
||||
"ac_io_hdxs_output is the wrong size");
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
@@ -10,8 +10,10 @@ enum ac_io_icca_cmd {
|
||||
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,
|
||||
};
|
||||
|
||||
enum ac_io_icca_slot_state {
|
||||
@@ -27,6 +29,14 @@ enum ac_io_icca_sensor_state {
|
||||
AC_IO_ICCA_SENSOR_MASK_BACK_ON = (1 << 5)
|
||||
};
|
||||
|
||||
enum ac_io_icca_status_code {
|
||||
AC_IO_ICCA_STATUS_FAULT = 0x00,
|
||||
AC_IO_ICCA_STATUS_IDLE = 0x01,
|
||||
AC_IO_ICCA_STATUS_GOT_UID = 0x02,
|
||||
AC_IO_ICCA_STATUS_IDLE_NEW = 0x04,
|
||||
AC_IO_ICCA_STATUS_BUSY_NEW = 0x01,
|
||||
};
|
||||
|
||||
enum ac_io_icca_keypad_mask {
|
||||
AC_IO_ICCA_KEYPAD_MASK_EMPTY = (1 << 0),
|
||||
AC_IO_ICCA_KEYPAD_MASK_3 = (1 << 1),
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef AC_IO_KFCA_H
|
||||
#define AC_IO_KFCA_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define AC_IO_CMD_KFCA_POLL 0x0113
|
||||
#define AC_IO_CMD_KFCA_WATCHDOG 0x0120
|
||||
#define AC_IO_CMD_KFCA_AMP_CONTROL 0x0128
|
||||
|
||||
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
|
||||
42
src/main/acio/panb.h
Normal file
42
src/main/acio/panb.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef AC_IO_PANB_H
|
||||
#define AC_IO_PANB_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define AC_IO_CMD_PANB_POLL_REPLY 0x0110
|
||||
#define AC_IO_CMD_PANB_SEND_LAMP 0x0111
|
||||
#define AC_IO_CMD_PANB_START_AUTO_INPUT 0x0115
|
||||
|
||||
#define AC_IO_PANB_NUM_NODES 4
|
||||
#define AC_IO_PANB_MAX_KEYS (7*AC_IO_PANB_NUM_NODES)
|
||||
#define AC_IO_PANB_MAX_KEYPAIRS (AC_IO_PANB_MAX_KEYS/2)
|
||||
|
||||
struct ac_io_panb_keypair {
|
||||
uint8_t key2 : 4;
|
||||
uint8_t key1 : 4;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct ac_io_panb_poll_in {
|
||||
/* last received command sequence number (start_auto_input / send_lamp) */
|
||||
uint8_t sub_seq1;
|
||||
/* auto-increment sequence number for autopoll reports */
|
||||
uint8_t sub_seq2;
|
||||
struct ac_io_panb_keypair keypair[AC_IO_PANB_MAX_KEYPAIRS];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct ac_io_panb_color {
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct ac_io_panb_poll_out {
|
||||
struct ac_io_panb_color key[AC_IO_PANB_MAX_KEYS];
|
||||
};
|
||||
#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
|
||||
7
src/main/aciodrv-proc/Module.mk
Normal file
7
src/main/aciodrv-proc/Module.mk
Normal file
@@ -0,0 +1,7 @@
|
||||
libs += aciodrv-proc
|
||||
|
||||
libs_aciodrv-proc := \
|
||||
|
||||
src_aciodrv-proc := \
|
||||
panb.c \
|
||||
|
||||
90
src/main/aciodrv-proc/panb.c
Normal file
90
src/main/aciodrv-proc/panb.c
Normal file
@@ -0,0 +1,90 @@
|
||||
#define LOG_MODULE "aciodrv-proc-panb"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "aciodrv/device.h"
|
||||
#include "aciodrv/panb.h"
|
||||
|
||||
#include "util/thread.h"
|
||||
#include "util/log.h"
|
||||
|
||||
static int auto_poll_proc(void *auto_poll_param);
|
||||
static int auto_poll_threadid;
|
||||
|
||||
static CRITICAL_SECTION keypair_lock;
|
||||
static struct ac_io_panb_keypair _keypair[AC_IO_PANB_MAX_KEYPAIRS];
|
||||
|
||||
static CRITICAL_SECTION auto_poll_stop_lock;
|
||||
static bool auto_poll_stop;
|
||||
|
||||
static int auto_poll_proc(void * param)
|
||||
{
|
||||
struct aciodrv_device_ctx * device = (struct aciodrv_device_ctx *) param;
|
||||
struct ac_io_panb_poll_in poll_in;
|
||||
bool stop;
|
||||
|
||||
do {
|
||||
aciodrv_panb_recv_poll(device, &poll_in);
|
||||
|
||||
EnterCriticalSection(&keypair_lock);
|
||||
memcpy(_keypair, poll_in.keypair, AC_IO_PANB_MAX_KEYPAIRS);
|
||||
LeaveCriticalSection(&keypair_lock);
|
||||
|
||||
EnterCriticalSection(&auto_poll_stop_lock);
|
||||
stop = auto_poll_stop;
|
||||
LeaveCriticalSection(&auto_poll_stop_lock);
|
||||
} while (!stop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool aciodrv_proc_panb_init(struct aciodrv_device_ctx *device)
|
||||
{
|
||||
log_assert(device);
|
||||
|
||||
if (!aciodrv_panb_start_auto_input(device, 0, AC_IO_PANB_NUM_NODES)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto_poll_stop = false;
|
||||
InitializeCriticalSection(&keypair_lock);
|
||||
InitializeCriticalSection(&auto_poll_stop_lock);
|
||||
auto_poll_threadid = thread_create(auto_poll_proc, (void *)device, 0x4000, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aciodrv_proc_panb_get_state(uint8_t *button_state)
|
||||
{
|
||||
struct ac_io_panb_keypair keypair[AC_IO_PANB_MAX_KEYPAIRS];
|
||||
|
||||
EnterCriticalSection(&keypair_lock);
|
||||
memcpy(keypair, _keypair, AC_IO_PANB_MAX_KEYPAIRS);
|
||||
LeaveCriticalSection(&keypair_lock);
|
||||
|
||||
/* splice the keypairs into separate button values */
|
||||
for (int i=0; i<AC_IO_PANB_MAX_KEYPAIRS; i++) {
|
||||
uint8_t but1 = keypair[i].key1;
|
||||
uint8_t but2 = keypair[i].key2;
|
||||
button_state[2*i] = but1;
|
||||
button_state[2*i+1] = but2;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void aciodrv_proc_panb_fini(struct aciodrv_device_ctx *device)
|
||||
{
|
||||
EnterCriticalSection(&auto_poll_stop_lock);
|
||||
auto_poll_stop = true;
|
||||
LeaveCriticalSection(&auto_poll_stop_lock);
|
||||
|
||||
thread_join(auto_poll_threadid, NULL);
|
||||
thread_destroy(auto_poll_threadid);
|
||||
|
||||
DeleteCriticalSection(&keypair_lock);
|
||||
DeleteCriticalSection(&auto_poll_stop_lock);
|
||||
|
||||
/* reset is the only way to disable the auto polling on device side */
|
||||
aciodrv_device_reset(device);
|
||||
}
|
||||
32
src/main/aciodrv-proc/panb.h
Normal file
32
src/main/aciodrv-proc/panb.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef ACIODRV_PROC_PANB_H
|
||||
#define ACIODRV_PROC_PANB_H
|
||||
|
||||
#include "aciodrv/panb.h"
|
||||
|
||||
/**
|
||||
* Initialize a PANB device. This will take care of setting up the auto-poll and processing
|
||||
* the poll messages in a separate thread (this is necessary as failing to process messages
|
||||
* fast enough will cause the device to malfunction).
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @return True if successful, false on error.
|
||||
* @note This function spawns a thread. Caller must call aciodrv_proc_panb_fini to properly
|
||||
* terminate.
|
||||
*/
|
||||
bool aciodrv_proc_panb_init(struct aciodrv_device_ctx *device);
|
||||
|
||||
/**
|
||||
* Retrieve latest known button state from the PANB device.
|
||||
*
|
||||
* @param button_state 28 cell array to store button state
|
||||
* (mandatory, upon calling the array contains values between 0 to 15 indicating the keys velocity).
|
||||
* @return True on success, false on error.
|
||||
*/
|
||||
bool aciodrv_proc_panb_get_state(uint8_t *button_state);
|
||||
|
||||
/**
|
||||
* Properly terminate the thread and reset the device (this is the only way to stop the auto polling).
|
||||
*/
|
||||
void aciodrv_proc_panb_fini(struct aciodrv_device_ctx *device);
|
||||
|
||||
#endif
|
||||
@@ -1,10 +1,13 @@
|
||||
libs += aciodrv
|
||||
|
||||
libs_aciodrv := \
|
||||
|
||||
|
||||
src_aciodrv := \
|
||||
device.c \
|
||||
h44b.c \
|
||||
icca.c \
|
||||
kfca.c \
|
||||
panb.c \
|
||||
rvol.c \
|
||||
port.c \
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#define LOG_MODULE "aciodrv-device"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "aciodrv/device.h"
|
||||
@@ -8,64 +9,107 @@
|
||||
|
||||
#include "util/hex.h"
|
||||
#include "util/log.h"
|
||||
#include "util/mem.h"
|
||||
|
||||
/* Enable to dump all data to the logger */
|
||||
//#define AC_IO_MSG_LOG
|
||||
|
||||
static uint8_t aciodrv_device_msg_counter = 1;
|
||||
static uint8_t aciodrv_device_node_count;
|
||||
static char aviodrv_device_node_products[16][4];
|
||||
#define ACIO_MAX_NODES_PER_PORT 16
|
||||
|
||||
static bool aciodrv_device_init(void)
|
||||
struct aciodrv_device_ctx {
|
||||
HANDLE fd;
|
||||
struct aciodrv_device_node_version node_versions[ACIO_MAX_NODES_PER_PORT];
|
||||
uint8_t msg_counter;
|
||||
uint8_t node_count;
|
||||
};
|
||||
|
||||
bool aciodrv_device_reset(struct aciodrv_device_ctx *device)
|
||||
{
|
||||
uint8_t reset_seq[525] = {0};
|
||||
|
||||
/* init/reset the device by sending 525 NULL bytes */
|
||||
log_info("Resetting device");
|
||||
if (aciodrv_port_write(device->fd, reset_seq, sizeof(reset_seq)) <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* signal to device for a reset */
|
||||
EscapeCommFunction(device->fd, SETBREAK);
|
||||
Sleep(1450);
|
||||
EscapeCommFunction(device->fd, CLRBREAK);
|
||||
Sleep(1200);
|
||||
|
||||
/* ignore the next 100 reads (of whatever length) */
|
||||
for (size_t i = 0; i < 100; ++i) {
|
||||
aciodrv_port_read(device->fd, reset_seq, sizeof(reset_seq));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool aciodrv_device_sof_flush(struct aciodrv_device_ctx *device)
|
||||
{
|
||||
uint8_t init_seq[1] = {AC_IO_SOF};
|
||||
uint8_t read_buff[1] = {0};
|
||||
|
||||
/* init/reset the device by sending 0xAA until 0xAA is returned */
|
||||
/* wait for reset to finish */
|
||||
int read = 0;
|
||||
do {
|
||||
if (aciodrv_port_write(init_seq, sizeof(init_seq)) <= 0) {
|
||||
if (aciodrv_port_write(device->fd, init_seq, sizeof(init_seq)) <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
read = aciodrv_port_read(init_seq, sizeof(init_seq));
|
||||
} while (read == 0);
|
||||
read = aciodrv_port_read(device->fd, read_buff, sizeof(read_buff));
|
||||
} while ((read <= 0) || (read_buff[0] != init_seq[0]));
|
||||
|
||||
if (read > 0) {
|
||||
log_info("Obtained SOF, clearing out buffer now");
|
||||
/* empty buffer by reading all data */
|
||||
while (read > 0) {
|
||||
read = aciodrv_port_read(init_seq, sizeof(init_seq));
|
||||
read = aciodrv_port_read(device->fd, init_seq, sizeof(init_seq));
|
||||
}
|
||||
log_warning("Cleared buffer, init done");
|
||||
|
||||
return read == 0;
|
||||
} else {
|
||||
log_warning("Read failure when trying to clear device state");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool aciodrv_device_init(struct aciodrv_device_ctx *device)
|
||||
{
|
||||
if (!aciodrv_device_reset(device)) {
|
||||
log_warning("Reset failed");
|
||||
return false;
|
||||
}
|
||||
return aciodrv_device_sof_flush(device);
|
||||
}
|
||||
|
||||
#ifdef AC_IO_MSG_LOG
|
||||
static void
|
||||
aciodrv_device_log_buffer(const char *msg, const uint8_t *buffer, int length)
|
||||
aciodrv_device_log_buffer(struct aciodrv_device_ctx *device, const char *msg, const uint8_t *buffer, int length)
|
||||
{
|
||||
char str[4096];
|
||||
|
||||
hex_encode_uc((const void *) buffer, length, str, sizeof(str));
|
||||
log_misc("%s, length %d: %s", msg, length, str);
|
||||
log_misc("[%p] %s, length %d: %s", device->fd, msg, length, str);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool aciodrv_device_send(const uint8_t *buffer, int length)
|
||||
static bool aciodrv_device_send(struct aciodrv_device_ctx *device, const uint8_t *buffer, int length)
|
||||
{
|
||||
uint8_t send_buf[512];
|
||||
int send_buf_pos = 0;
|
||||
uint8_t checksum = 0;
|
||||
|
||||
if (length > sizeof(send_buf)) {
|
||||
log_warning("Send buffer overflow");
|
||||
log_warning("[%p] Send buffer overflow", device->fd);
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef AC_IO_MSG_LOG
|
||||
aciodrv_device_log_buffer("Send (1)", buffer, length);
|
||||
aciodrv_device_log_buffer(device, "Send (1)", buffer, length);
|
||||
#endif
|
||||
|
||||
send_buf[send_buf_pos++] = AC_IO_SOF;
|
||||
@@ -91,18 +135,18 @@ static bool aciodrv_device_send(const uint8_t *buffer, int length)
|
||||
}
|
||||
|
||||
#ifdef AC_IO_MSG_LOG
|
||||
aciodrv_device_log_buffer("Send (2)", send_buf, send_buf_pos);
|
||||
aciodrv_device_log_buffer(device, "Send (2)", send_buf, send_buf_pos);
|
||||
#endif
|
||||
|
||||
if (aciodrv_port_write(send_buf, send_buf_pos) != send_buf_pos) {
|
||||
log_warning("Sending data with length %d failed", send_buf_pos);
|
||||
if (aciodrv_port_write(device->fd, send_buf, send_buf_pos) != send_buf_pos) {
|
||||
log_warning("[%p] Sending data with length %d failed", device->fd, send_buf_pos);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int aciodrv_device_receive(uint8_t *buffer, int size)
|
||||
static int aciodrv_device_receive(struct aciodrv_device_ctx *device, uint8_t *buffer, int max_resp_size)
|
||||
{
|
||||
uint8_t recv_buf[512];
|
||||
int recv_size = 0;
|
||||
@@ -114,16 +158,14 @@ static int aciodrv_device_receive(uint8_t *buffer, int size)
|
||||
of 0xAAs before we get a valid message. */
|
||||
recv_buf[0] = AC_IO_SOF;
|
||||
do {
|
||||
read = aciodrv_port_read(recv_buf, 1);
|
||||
read = aciodrv_port_read(device->fd, recv_buf, 1);
|
||||
} while (recv_buf[0] == AC_IO_SOF);
|
||||
|
||||
if (read > 0) {
|
||||
size += 1;
|
||||
|
||||
if (read > 0) {
|
||||
/* recv_buf[0] is already the first byte of the message.
|
||||
now read until nothing's left */
|
||||
recv_size++;
|
||||
size--;
|
||||
|
||||
/* important: we have to know how much data we expect
|
||||
and have to read until we reach the requested amount.
|
||||
@@ -131,9 +173,10 @@ static int aciodrv_device_receive(uint8_t *buffer, int size)
|
||||
need to handle escaping (which relies on an up to
|
||||
date recv_buf[recv_size]) we loop until we get a
|
||||
non-zero read. */
|
||||
while (size > 0) {
|
||||
size_t expected_size = offsetof(struct ac_io_message, cmd.nbytes) + 1;
|
||||
while (recv_size < expected_size) {
|
||||
do {
|
||||
read = aciodrv_port_read(recv_buf + recv_size, 1);
|
||||
read = aciodrv_port_read(device->fd, recv_buf + recv_size, 1);
|
||||
} while (read == 0);
|
||||
|
||||
if (read < 0) {
|
||||
@@ -146,7 +189,8 @@ static int aciodrv_device_receive(uint8_t *buffer, int size)
|
||||
/* next byte is our real data
|
||||
overwrite escape byte */
|
||||
do {
|
||||
read = aciodrv_port_read(recv_buf + recv_size, 1);
|
||||
read = aciodrv_port_read(
|
||||
device->fd, recv_buf + recv_size, 1);
|
||||
} while (read == 0);
|
||||
|
||||
if (read < 0) {
|
||||
@@ -157,14 +201,23 @@ static int aciodrv_device_receive(uint8_t *buffer, int size)
|
||||
}
|
||||
|
||||
recv_size += read;
|
||||
size -= read;
|
||||
|
||||
if (recv_size > offsetof(struct ac_io_message, cmd.nbytes)) {
|
||||
// header + data + checksum
|
||||
expected_size = offsetof(struct ac_io_message, cmd.raw) + ((struct ac_io_message*)recv_buf)->cmd.nbytes + 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef AC_IO_MSG_LOG
|
||||
aciodrv_device_log_buffer("Recv (1)", recv_buf, recv_size);
|
||||
aciodrv_device_log_buffer(device, "Recv (1)", recv_buf, recv_size);
|
||||
log_warning("Expected %d got %d", max_resp_size - 6, recv_buf[4]);
|
||||
#endif
|
||||
|
||||
/* recv_size - 1: omit checksum for checksum calc */
|
||||
if ((recv_size - 1) > max_resp_size) {
|
||||
log_warning("[%p] Expected %d got %d", device->fd, max_resp_size - 6, recv_buf[4]);
|
||||
return -1;
|
||||
}
|
||||
for (int i = 0; i < recv_size - 1; i++) {
|
||||
checksum += recv_buf[i];
|
||||
buffer[i] = recv_buf[i];
|
||||
@@ -173,12 +226,13 @@ static int aciodrv_device_receive(uint8_t *buffer, int size)
|
||||
result_size = recv_size - 1;
|
||||
|
||||
#ifdef AC_IO_MSG_LOG
|
||||
aciodrv_device_log_buffer("Recv (2)", buffer, result_size);
|
||||
aciodrv_device_log_buffer(device, "Recv (2)", buffer, result_size);
|
||||
#endif
|
||||
|
||||
if (checksum != recv_buf[recv_size - 1]) {
|
||||
log_warning(
|
||||
"Invalid message checksum: %02X != %02X",
|
||||
"[%p] Invalid message checksum: %02X != %02X",
|
||||
device->fd,
|
||||
checksum,
|
||||
recv_buf[recv_size - 1]);
|
||||
return -1;
|
||||
@@ -190,7 +244,7 @@ static int aciodrv_device_receive(uint8_t *buffer, int size)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static uint8_t aciodrv_device_enum_nodes(void)
|
||||
static uint8_t aciodrv_device_enum_nodes(struct aciodrv_device_ctx *device)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
@@ -200,7 +254,9 @@ static uint8_t aciodrv_device_enum_nodes(void)
|
||||
msg.cmd.count = 0;
|
||||
|
||||
if (!aciodrv_send_and_recv(
|
||||
&msg, offsetof(struct ac_io_message, cmd.raw) + 1)) {
|
||||
device,
|
||||
&msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) + 1)) {
|
||||
log_warning("Enumerating nodes failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -210,7 +266,7 @@ static uint8_t aciodrv_device_enum_nodes(void)
|
||||
return msg.cmd.count;
|
||||
}
|
||||
|
||||
static bool aciodrv_device_get_version(uint8_t node_id, char product[4])
|
||||
static bool aciodrv_device_get_version(struct aciodrv_device_ctx *device, uint8_t node_id, struct aciodrv_device_node_version *version)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
@@ -219,6 +275,7 @@ static bool aciodrv_device_get_version(uint8_t node_id, char product[4])
|
||||
msg.cmd.nbytes = 0;
|
||||
|
||||
if (!aciodrv_send_and_recv(
|
||||
device,
|
||||
&msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) +
|
||||
sizeof(struct ac_io_version))) {
|
||||
@@ -242,12 +299,16 @@ static bool aciodrv_device_get_version(uint8_t node_id, char product[4])
|
||||
msg.cmd.version.date,
|
||||
msg.cmd.version.time);
|
||||
|
||||
memcpy(product, msg.cmd.version.product_code, 4);
|
||||
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;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool aciodrv_device_start_node(uint8_t node_id)
|
||||
static bool aciodrv_device_start_node(struct aciodrv_device_ctx *device, uint8_t node_id)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
@@ -256,7 +317,9 @@ static bool aciodrv_device_start_node(uint8_t node_id)
|
||||
msg.cmd.nbytes = 0;
|
||||
|
||||
if (!aciodrv_send_and_recv(
|
||||
&msg, offsetof(struct ac_io_message, cmd.raw) + 1)) {
|
||||
device,
|
||||
&msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) + 1)) {
|
||||
log_warning("Starting node %d failed", node_id);
|
||||
return false;
|
||||
}
|
||||
@@ -265,71 +328,135 @@ static bool aciodrv_device_start_node(uint8_t node_id)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aciodrv_device_open(const char *port, int baud)
|
||||
// deprecated name
|
||||
struct aciodrv_device_ctx *aciodrv_device_open(const char *port_path, int baud)
|
||||
{
|
||||
if (!aciodrv_port_open(port, baud)) {
|
||||
return aciodrv_device_open_path(port_path, baud);
|
||||
}
|
||||
|
||||
struct aciodrv_device_ctx *aciodrv_device_open_path(const char *port_path, int baud)
|
||||
{
|
||||
HANDLE port = aciodrv_port_open(port_path, baud);
|
||||
|
||||
if (!port) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct aciodrv_device_ctx *device = xmalloc(sizeof(struct aciodrv_device_ctx));
|
||||
|
||||
memset(device, 0, sizeof(struct aciodrv_device_ctx));
|
||||
device->fd = port;
|
||||
device->msg_counter = 1;
|
||||
|
||||
if (!aciodrv_device_init(device)) {
|
||||
aciodrv_device_close(device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device->node_count = aciodrv_device_enum_nodes(device);
|
||||
|
||||
if (device->node_count == 0) {
|
||||
aciodrv_device_close(device);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aciodrv_device_init()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aciodrv_device_node_count = aciodrv_device_enum_nodes();
|
||||
if (aciodrv_device_node_count == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < aciodrv_device_node_count; i++) {
|
||||
for (uint8_t i = 0; i < device->node_count; i++) {
|
||||
if (!aciodrv_device_get_version(
|
||||
i + 1, aviodrv_device_node_products[i])) {
|
||||
return false;
|
||||
device, i + 1, &device->node_versions[i])) {
|
||||
aciodrv_device_close(device);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < aciodrv_device_node_count; i++) {
|
||||
if (!aciodrv_device_start_node(i + 1)) {
|
||||
return false;
|
||||
for (uint8_t i = 0; i < device->node_count; i++) {
|
||||
if (!aciodrv_device_start_node(device, i + 1)) {
|
||||
aciodrv_device_close(device);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
log_info("Opening ACIO device on [%p]", device->fd);
|
||||
return device;
|
||||
}
|
||||
|
||||
uint8_t aciodrv_device_get_node_count(void)
|
||||
uint8_t aciodrv_device_get_node_count(struct aciodrv_device_ctx *device)
|
||||
{
|
||||
return aciodrv_device_node_count;
|
||||
return device->node_count;
|
||||
}
|
||||
|
||||
bool aciodrv_device_get_node_product_ident(uint8_t node_id, char product[4])
|
||||
bool aciodrv_device_get_node_product_ident(struct aciodrv_device_ctx *device, uint8_t node_id, char product[ACIO_NODE_PRODUCT_CODE_LEN])
|
||||
{
|
||||
if (aciodrv_device_node_count == 0 || node_id > aciodrv_device_node_count) {
|
||||
if (device->node_count == 0 || node_id > device->node_count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(product, aviodrv_device_node_products[node_id], 4);
|
||||
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)
|
||||
{
|
||||
if (device->node_count == 0 || node_id > device->node_count) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &device->node_versions[node_id];
|
||||
}
|
||||
|
||||
bool aciodrv_send(struct aciodrv_device_ctx *device, struct ac_io_message *msg)
|
||||
{
|
||||
msg->cmd.seq_no = device->msg_counter++;
|
||||
int send_size = offsetof(struct ac_io_message, cmd.raw) + msg->cmd.nbytes;
|
||||
|
||||
#ifdef AC_IO_MSG_LOG
|
||||
log_info(
|
||||
"[%p] Beginning send on %d: %04x (%d b)",
|
||||
device->fd,
|
||||
msg->addr,
|
||||
msg->cmd.code,
|
||||
send_size);
|
||||
#endif
|
||||
if (aciodrv_device_send(device, (uint8_t *) msg, send_size) <= 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aciodrv_send_and_recv(struct ac_io_message *msg, int resp_size)
|
||||
bool aciodrv_recv(struct aciodrv_device_ctx *device, struct ac_io_message *msg, int max_resp_size)
|
||||
{
|
||||
msg->cmd.seq_no = aciodrv_device_msg_counter++;
|
||||
#ifdef AC_IO_MSG_LOG
|
||||
log_info("[%p] Beginning recv: (%d b)", device->fd, max_resp_size);
|
||||
#endif
|
||||
if (aciodrv_device_receive(device, (uint8_t *) msg, max_resp_size) <= 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aciodrv_device_send(
|
||||
(uint8_t *) msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) + msg->cmd.nbytes) <= 0) {
|
||||
bool aciodrv_send_and_recv(struct aciodrv_device_ctx *device, struct ac_io_message *msg, int max_resp_size)
|
||||
{
|
||||
if (!aciodrv_send(device, msg)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t req_code = msg->cmd.code;
|
||||
|
||||
if (aciodrv_device_receive((uint8_t *) msg, resp_size) <= 0) {
|
||||
if (!aciodrv_recv(device, msg, max_resp_size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (req_code != msg->cmd.code) {
|
||||
log_warning(
|
||||
"Received invalid response %04X for request %04X",
|
||||
"[%p] Received invalid response %04X for request %04X",
|
||||
device->fd,
|
||||
msg->cmd.code,
|
||||
req_code);
|
||||
return false;
|
||||
@@ -338,7 +465,13 @@ bool aciodrv_send_and_recv(struct ac_io_message *msg, int resp_size)
|
||||
return true;
|
||||
}
|
||||
|
||||
void aciodrv_device_close(void)
|
||||
void aciodrv_device_close(struct aciodrv_device_ctx *device)
|
||||
{
|
||||
aciodrv_port_close();
|
||||
log_assert(device);
|
||||
|
||||
log_info("Closing ACIO on [%p]", device->fd);
|
||||
|
||||
aciodrv_port_close(device->fd);
|
||||
|
||||
free(device);
|
||||
}
|
||||
|
||||
@@ -5,48 +5,119 @@
|
||||
|
||||
#include "acio/acio.h"
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
#define ACIO_NODE_PRODUCT_CODE_LEN 4
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
/**
|
||||
* Open an ACIO device connected to a serial port.
|
||||
*
|
||||
* @param port Port the device is connected to (e.g. "COM1")
|
||||
* @param baud Baud rate for communication (e.g. 57600 for ICCA)
|
||||
* @return True if opening the port and resetting the device was successful,
|
||||
* false on error.
|
||||
* @return opened device context, NULL on error
|
||||
*/
|
||||
bool aciodrv_device_open(const char *port, int baud);
|
||||
struct aciodrv_device_ctx *aciodrv_device_open(const char *port_path, int baud)
|
||||
#ifdef __GNUC__
|
||||
__attribute__((deprecated("Use aciomgr instead if device is shareable, else aciodrv_device_open_path")))
|
||||
#endif
|
||||
;
|
||||
|
||||
struct aciodrv_device_ctx *aciodrv_device_open_path(const char *port_path, int baud);
|
||||
|
||||
/**
|
||||
* Get the node count on the opened device.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @return Total num of nodes enumerated on the ACIO device.
|
||||
*/
|
||||
uint8_t aciodrv_device_get_node_count(void);
|
||||
uint8_t aciodrv_device_get_node_count(struct aciodrv_device_ctx *device);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param product Buffer to return the product id to.
|
||||
* @return True on success, false on error. If True the variable product
|
||||
* contains the identifier of the queried node.
|
||||
*/
|
||||
bool aciodrv_device_get_node_product_ident(uint8_t node_id, char product[4]);
|
||||
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.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node. Needs to be in range of the total node count.
|
||||
* @return Pointer to the version struct
|
||||
*/
|
||||
const struct aciodrv_device_node_version *aciodrv_device_get_node_product_version(struct aciodrv_device_ctx *device, uint8_t node_id);
|
||||
|
||||
/**
|
||||
* Send a message to the ACIO bus and receive an answer.
|
||||
* Use this to implement the protocol for each type of device that can be
|
||||
* part of the bus.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param msg Msg to send to the bus. Make sure that the buffer backing
|
||||
* this message is big enough to receive the response as well.
|
||||
* @param resp_size Size of the expecting response.
|
||||
* @return True on success, false on error.
|
||||
*/
|
||||
bool aciodrv_send_and_recv(struct ac_io_message *msg, int resp_size);
|
||||
bool aciodrv_send_and_recv(struct aciodrv_device_ctx *device, struct ac_io_message *msg, int max_resp_size);
|
||||
|
||||
/**
|
||||
* Send a message to the ACIO bus.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param msg Msg to send to the bus.
|
||||
* @return True on success, false on error.
|
||||
* @note Prefer the use of aciodrv_send_and_recv when possible. This is for commands which don't trigger a reply.
|
||||
*/
|
||||
bool aciodrv_send(struct aciodrv_device_ctx *device, struct ac_io_message *msg);
|
||||
|
||||
/**
|
||||
* Read a message from the ACIO bus.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param msg Msg to send to the bus. Make sure that the buffer
|
||||
* is big enough to receive the response.
|
||||
* @return True on success, false on error.
|
||||
* @note Prefer the use of aciodrv_send_and_recv when possible. This is for unsollicited incoming messages.
|
||||
*/
|
||||
bool aciodrv_recv(struct aciodrv_device_ctx *device, struct ac_io_message *msg, int max_resp_size);
|
||||
|
||||
/**
|
||||
* Reset an opened device.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @return Total num of nodes enumerated on the ACIO device.
|
||||
*/
|
||||
bool aciodrv_device_reset(struct aciodrv_device_ctx *device);
|
||||
|
||||
/**
|
||||
* Close the previously opened ACIO device.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
*/
|
||||
void aciodrv_device_close(void);
|
||||
void aciodrv_device_close(struct aciodrv_device_ctx *device);
|
||||
|
||||
#endif
|
||||
45
src/main/aciodrv/h44b.c
Normal file
45
src/main/aciodrv/h44b.c
Normal file
@@ -0,0 +1,45 @@
|
||||
#define LOG_MODULE "aciodrv-h44b"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "acio/h44b.h"
|
||||
|
||||
#include "aciodrv/device.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
bool aciodrv_h44b_init(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id)
|
||||
{
|
||||
// unlike input devices like KFCA, H44B has no watchdog or special init code
|
||||
// requirements - shared ACIO node initialisation is enough
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aciodrv_h44b_lights(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
const struct ac_io_h44b_output *lights)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
log_assert(device);
|
||||
log_assert(lights);
|
||||
|
||||
msg.addr = node_id + 1;
|
||||
msg.cmd.code = ac_io_u16(AC_IO_H44B_CMD_SET_OUTPUTS);
|
||||
msg.cmd.nbytes = sizeof(*lights);
|
||||
msg.cmd.h44b_output = *lights;
|
||||
|
||||
if (!aciodrv_send_and_recv(
|
||||
device,
|
||||
&msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) + 1)) {
|
||||
log_warning("Polling of node %d failed", node_id + 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
32
src/main/aciodrv/h44b.h
Normal file
32
src/main/aciodrv/h44b.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef ACIODRV_H44B_H
|
||||
#define ACIODRV_H44B_H
|
||||
|
||||
#include "aciodrv/device.h"
|
||||
#include "acio/h44b.h"
|
||||
|
||||
/**
|
||||
* Initialize an H44B node.
|
||||
*
|
||||
* @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_h44b_init(struct aciodrv_device_ctx *device, uint8_t node_id);
|
||||
|
||||
/**
|
||||
* Set the H44B LEDs
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node to query (0 based).
|
||||
* @param lights Packed lights struct to send
|
||||
* @return True on success, false on error.
|
||||
*/
|
||||
bool aciodrv_h44b_lights(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
const struct ac_io_h44b_output *lights);
|
||||
|
||||
#endif
|
||||
@@ -3,20 +3,27 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "aciodrv/device.h"
|
||||
#include "aciodrv/icca.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
static bool aciodrv_icca_queue_loop_start(uint8_t node_id)
|
||||
static bool aciodrv_icca_queue_loop_start(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
log_assert(device);
|
||||
|
||||
msg.addr = node_id;
|
||||
msg.cmd.code = ac_io_u16(AC_IO_ICCA_CMD_QUEUE_LOOP_START);
|
||||
msg.cmd.nbytes = 1;
|
||||
msg.cmd.status = 0;
|
||||
|
||||
if (!aciodrv_send_and_recv(
|
||||
&msg, offsetof(struct ac_io_message, cmd.raw) + 1)) {
|
||||
device,
|
||||
&msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) + 1)) {
|
||||
log_warning("Starting queue loop failed");
|
||||
return false;
|
||||
}
|
||||
@@ -27,9 +34,11 @@ static bool aciodrv_icca_queue_loop_start(uint8_t node_id)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aciodrv_icca_init(uint8_t node_id)
|
||||
bool aciodrv_icca_init(struct aciodrv_device_ctx *device, uint8_t node_id)
|
||||
{
|
||||
if (!aciodrv_icca_queue_loop_start(node_id + 1)) {
|
||||
log_assert(device);
|
||||
|
||||
if (!aciodrv_icca_queue_loop_start(device, node_id + 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -37,10 +46,15 @@ bool aciodrv_icca_init(uint8_t node_id)
|
||||
}
|
||||
|
||||
bool aciodrv_icca_set_state(
|
||||
uint8_t node_id, int slot_state, struct ac_io_icca_state *state)
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
int slot_state,
|
||||
struct ac_io_icca_state *state)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
log_assert(device);
|
||||
|
||||
msg.addr = node_id + 1;
|
||||
msg.cmd.code = ac_io_u16(AC_IO_ICCA_CMD_SET_SLOT_STATE);
|
||||
msg.cmd.nbytes = 2;
|
||||
@@ -49,7 +63,9 @@ bool aciodrv_icca_set_state(
|
||||
msg.cmd.raw[1] = slot_state;
|
||||
|
||||
if (!aciodrv_send_and_recv(
|
||||
&msg, offsetof(struct ac_io_message, cmd.raw) + msg.cmd.raw[0])) {
|
||||
device,
|
||||
&msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) + msg.cmd.raw[0])) {
|
||||
log_warning("Setting state of node %d failed", node_id + 1);
|
||||
return false;
|
||||
}
|
||||
@@ -61,10 +77,15 @@ bool aciodrv_icca_set_state(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aciodrv_icca_get_state(uint8_t node_id, struct ac_io_icca_state *state)
|
||||
bool aciodrv_icca_get_state(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
struct ac_io_icca_state *state)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
log_assert(device);
|
||||
|
||||
msg.addr = node_id + 1;
|
||||
msg.cmd.code = ac_io_u16(AC_IO_ICCA_CMD_POLL);
|
||||
msg.cmd.nbytes = 1;
|
||||
@@ -72,7 +93,9 @@ bool aciodrv_icca_get_state(uint8_t node_id, struct ac_io_icca_state *state)
|
||||
msg.cmd.count = sizeof(struct ac_io_icca_state);
|
||||
|
||||
if (!aciodrv_send_and_recv(
|
||||
&msg, offsetof(struct ac_io_message, cmd.raw) + msg.cmd.count)) {
|
||||
device,
|
||||
&msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) + msg.cmd.count)) {
|
||||
log_warning("Getting state of node %d failed", node_id + 1);
|
||||
return false;
|
||||
}
|
||||
@@ -84,10 +107,15 @@ bool aciodrv_icca_get_state(uint8_t node_id, struct ac_io_icca_state *state)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aciodrv_icca_read_card(uint8_t node_id, struct ac_io_icca_state *state)
|
||||
bool aciodrv_icca_read_card(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
struct ac_io_icca_state *state)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
log_assert(device);
|
||||
|
||||
msg.addr = node_id + 1;
|
||||
msg.cmd.code = ac_io_u16(AC_IO_ICCA_CMD_ENGAGE);
|
||||
msg.cmd.nbytes = 1;
|
||||
@@ -95,7 +123,9 @@ bool aciodrv_icca_read_card(uint8_t node_id, struct ac_io_icca_state *state)
|
||||
msg.cmd.count = sizeof(struct ac_io_icca_state);
|
||||
|
||||
if (!aciodrv_send_and_recv(
|
||||
&msg, offsetof(struct ac_io_message, cmd.raw) + msg.cmd.count)) {
|
||||
device,
|
||||
&msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) + msg.cmd.count)) {
|
||||
log_warning("Reading card of node %d failed", node_id + 1);
|
||||
return false;
|
||||
}
|
||||
@@ -105,4 +135,53 @@ bool aciodrv_icca_read_card(uint8_t node_id, struct ac_io_icca_state *state)
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool aciodrv_icca_is_slotted(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id)
|
||||
{
|
||||
const struct aciodrv_device_node_version *version;
|
||||
version = aciodrv_device_get_node_product_version(device, node_id);
|
||||
|
||||
// current heuristic is to check if version >= 1.5
|
||||
if (version) {
|
||||
if (version->major == 1) {
|
||||
if (version->minor >= 5) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aciodrv_icca_poll_felica(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
log_assert(device);
|
||||
|
||||
msg.addr = node_id + 1;
|
||||
msg.cmd.code = ac_io_u16(AC_IO_ICCA_CMD_POLL_FELICA);
|
||||
msg.cmd.nbytes = 4;
|
||||
/* buffer size of data we expect */
|
||||
msg.cmd.count = 1;
|
||||
|
||||
// additional data, not sure
|
||||
msg.cmd.raw[1] = 0x03;
|
||||
msg.cmd.raw[2] = 0xFF;
|
||||
msg.cmd.raw[3] = 0xFF;
|
||||
|
||||
if (!aciodrv_send_and_recv(
|
||||
device,
|
||||
&msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) + msg.cmd.count)) {
|
||||
log_warning("Reading card of node %d failed", node_id + 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -6,17 +6,19 @@
|
||||
/**
|
||||
* Initialize an ICCA node.
|
||||
*
|
||||
* @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_icca_init(uint8_t node_id);
|
||||
bool aciodrv_icca_init(struct aciodrv_device_ctx *device, uint8_t node_id);
|
||||
|
||||
/**
|
||||
* Set the state of on ICCA node.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node to set the state for (0 based).
|
||||
* @param slot_state State of the slot (refer to corresponding enum).
|
||||
* @param state Pointer to a state struct to return the current state to
|
||||
@@ -27,11 +29,15 @@ bool aciodrv_icca_init(uint8_t node_id);
|
||||
* @see driver.h
|
||||
*/
|
||||
bool aciodrv_icca_set_state(
|
||||
uint8_t node_id, int slot_state, struct ac_io_icca_state *state);
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
int slot_state,
|
||||
struct ac_io_icca_state *state);
|
||||
|
||||
/**
|
||||
* Get the current state of an ICCA node.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node to query (0 based).
|
||||
* @param state Pointer to a state struct to return the current state to
|
||||
* (optional, NULL for none).
|
||||
@@ -40,7 +46,10 @@ bool aciodrv_icca_set_state(
|
||||
* device driver foundation.
|
||||
* @see driver.h
|
||||
*/
|
||||
bool aciodrv_icca_get_state(uint8_t node_id, struct ac_io_icca_state *state);
|
||||
bool aciodrv_icca_get_state(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
struct ac_io_icca_state *state);
|
||||
|
||||
/**
|
||||
* Trigger a card read action on the ICCA reader. Make sure to call this
|
||||
@@ -48,6 +57,7 @@ bool aciodrv_icca_get_state(uint8_t node_id, struct ac_io_icca_state *state);
|
||||
* to get the most recent card data. Make sure to re-get the state after
|
||||
* a read call. The state returned here might not be up to date for some reason.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node to query (0 based).
|
||||
* @param state Pointer to a state struct to return the current state to
|
||||
* (optional, NULL for none).
|
||||
@@ -56,6 +66,46 @@ bool aciodrv_icca_get_state(uint8_t node_id, struct ac_io_icca_state *state);
|
||||
* device driver foundation.
|
||||
* @see driver.h
|
||||
*/
|
||||
bool aciodrv_icca_read_card(uint8_t node_id, struct ac_io_icca_state *state);
|
||||
bool aciodrv_icca_read_card(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
struct ac_io_icca_state *state);
|
||||
|
||||
#endif
|
||||
/**
|
||||
* Uses some heruistics based on the product ident to determine if the detected
|
||||
* device is a slotted (true) or wavepass reader (false).
|
||||
*
|
||||
* This function will also return false if the provided node_id is invalid.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node to query (0 based).
|
||||
* @return True on slotted, false on wavepass.
|
||||
* @note This module is supposed to be used in combination with the common
|
||||
* device driver foundation.
|
||||
* @see driver.h
|
||||
*/
|
||||
bool aciodrv_icca_is_slotted(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id);
|
||||
|
||||
/**
|
||||
* Polls the felica chip on wavepass readers. This will cause the state of the
|
||||
* reader to be AC_IO_ICCA_STATUS_BUSY_NEW for a few polls, before returning
|
||||
* either: AC_IO_ICCA_STATUS_IDLE_NEW or AC_IO_ICCA_STATUS_GOT_UID.
|
||||
*
|
||||
* The user should take care to call this every so often to actually get new
|
||||
* felica UIDs, instead of just old NFC idents. The game seems to do it every
|
||||
* 5 or so polls after the last AC_IO_ICCA_STATUS_BUSY_NEW poll.
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node to query (0 based).
|
||||
* @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_icca_poll_felica(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,53 +7,58 @@
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
static bool aciodrv_kfca_watchdog_start(uint8_t node_id)
|
||||
static bool aciodrv_kfca_watchdog_start(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id)
|
||||
{
|
||||
// exit early and don't actually call watchdog
|
||||
// the watchdog call actually returns different sized packets depending on
|
||||
// the state this results in an issue during packet processing (see: #68)
|
||||
return true;
|
||||
|
||||
/*
|
||||
struct ac_io_message msg;
|
||||
|
||||
log_assert(device);
|
||||
|
||||
msg.addr = node_id + 1;
|
||||
msg.cmd.code = ac_io_u16(AC_IO_CMD_KFCA_WATCHDOG);
|
||||
msg.cmd.nbytes = 2;
|
||||
msg.cmd.nbytes = 2;
|
||||
|
||||
// uint16_t: 6000
|
||||
msg.cmd.raw[0] = 23;
|
||||
msg.cmd.raw[1] = 112;
|
||||
|
||||
if (!aciodrv_send_and_recv(&msg, offsetof(struct ac_io_message, cmd.raw) +
|
||||
2)) { log_warning("Starting watchdog failed"); return false;
|
||||
if (!aciodrv_send_and_recv(
|
||||
device, &msg, offsetof(struct ac_io_message, cmd.raw) + 2)) {
|
||||
log_warning("Starting watchdog failed"); return false;
|
||||
}
|
||||
|
||||
log_warning("Started watchdog of node %d, status: %d",
|
||||
node_id, msg.cmd.status);
|
||||
log_warning("Started watchdog of node %d, sz: %d, status: %d",
|
||||
node_id, msg.cmd.nbytes, msg.cmd.status);
|
||||
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
|
||||
static bool aciodrv_kfca_amp(uint8_t node_id)
|
||||
bool aciodrv_kfca_amp(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
uint8_t primary,
|
||||
uint8_t headphone,
|
||||
uint8_t unused,
|
||||
uint8_t subwoofer)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
log_assert(device);
|
||||
|
||||
msg.addr = node_id + 1;
|
||||
msg.cmd.code = ac_io_u16(AC_IO_CMD_KFCA_AMP_CONTROL);
|
||||
msg.cmd.nbytes = 4;
|
||||
|
||||
// yes this sets the amp to 100% volume
|
||||
// TODO: expose this to sdvxio instead at some point
|
||||
msg.cmd.raw[0] = 0;
|
||||
msg.cmd.raw[1] = 0;
|
||||
msg.cmd.raw[2] = 0;
|
||||
msg.cmd.raw[3] = 0;
|
||||
msg.cmd.raw[0] = primary;
|
||||
msg.cmd.raw[1] = headphone;
|
||||
msg.cmd.raw[2] = unused;
|
||||
msg.cmd.raw[3] = subwoofer;
|
||||
|
||||
if (!aciodrv_send_and_recv(
|
||||
&msg, offsetof(struct ac_io_message, cmd.raw) + 1)) {
|
||||
device,
|
||||
&msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) + 1)) {
|
||||
log_warning("Setting AMP failed");
|
||||
return false;
|
||||
}
|
||||
@@ -63,13 +68,17 @@ static bool aciodrv_kfca_amp(uint8_t node_id)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aciodrv_kfca_init(uint8_t node_id)
|
||||
bool aciodrv_kfca_init(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id)
|
||||
{
|
||||
if (!aciodrv_kfca_watchdog_start(node_id)) {
|
||||
log_assert(device);
|
||||
|
||||
if (!aciodrv_kfca_watchdog_start(device, node_id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aciodrv_kfca_amp(node_id)) {
|
||||
if (!aciodrv_kfca_amp(device, node_id, 0, 0, 0, 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -77,12 +86,15 @@ bool aciodrv_kfca_init(uint8_t node_id)
|
||||
}
|
||||
|
||||
bool aciodrv_kfca_poll(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
const struct ac_io_kfca_poll_out *pout,
|
||||
struct ac_io_kfca_poll_in *pin)
|
||||
{
|
||||
struct ac_io_message msg;
|
||||
|
||||
log_assert(device);
|
||||
|
||||
msg.addr = node_id + 1;
|
||||
msg.cmd.code = ac_io_u16(AC_IO_CMD_KFCA_POLL);
|
||||
msg.cmd.nbytes = sizeof(*pout);
|
||||
@@ -90,7 +102,9 @@ bool aciodrv_kfca_poll(
|
||||
msg.cmd.kfca_poll_out = *pout;
|
||||
|
||||
if (!aciodrv_send_and_recv(
|
||||
&msg, offsetof(struct ac_io_message, cmd.raw) + sizeof(*pin))) {
|
||||
device,
|
||||
&msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) + sizeof(*pin))) {
|
||||
log_warning("Polling of node %d failed", node_id + 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6,17 +6,19 @@
|
||||
/**
|
||||
* Initialize an KFCA node.
|
||||
*
|
||||
* @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_kfca_init(uint8_t node_id);
|
||||
bool aciodrv_kfca_init(struct aciodrv_device_ctx *device, uint8_t node_id);
|
||||
|
||||
/**
|
||||
* Poll the KFCA io board
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node to query (0 based).
|
||||
* @param state Pointer to a state struct to return the current state to
|
||||
* (optional, NULL for none).
|
||||
@@ -26,8 +28,29 @@ bool aciodrv_kfca_init(uint8_t node_id);
|
||||
* @see driver.h
|
||||
*/
|
||||
bool aciodrv_kfca_poll(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
const struct ac_io_kfca_poll_out *pout,
|
||||
struct ac_io_kfca_poll_in *pin);
|
||||
|
||||
/**
|
||||
* Set the KFCA digital amp level
|
||||
*
|
||||
* @param device Context of opened device
|
||||
* @param node_id Id of the node to query (0 based).
|
||||
* @param primary primary volume (96-0)
|
||||
* @param headphone headphone volume (96-0)
|
||||
* @param unused unknown volume (96-0) (unused)
|
||||
* @param subwoofer subwoofer volume (96-0)
|
||||
* @return True on success, false on error.
|
||||
* @note Note 96 (or 100?) is lowest volume level, 0 is highest
|
||||
*/
|
||||
bool aciodrv_kfca_amp(
|
||||
struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id,
|
||||
uint8_t primary,
|
||||
uint8_t headphone,
|
||||
uint8_t unused,
|
||||
uint8_t subwoofer);
|
||||
|
||||
#endif
|
||||
|
||||
80
src/main/aciodrv/panb.c
Normal file
80
src/main/aciodrv/panb.c
Normal file
@@ -0,0 +1,80 @@
|
||||
#define LOG_MODULE "aciodrv-panb"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "aciodrv/device.h"
|
||||
#include "aciodrv/panb.h"
|
||||
|
||||
#include "util/thread.h"
|
||||
#include "util/log.h"
|
||||
|
||||
bool aciodrv_panb_start_auto_input(struct aciodrv_device_ctx *device, uint8_t node_id, uint8_t node_count)
|
||||
{
|
||||
log_assert(device);
|
||||
struct ac_io_message msg;
|
||||
|
||||
/* only the first node is handling the commands */
|
||||
if (node_id != 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
msg.addr = node_id + 1;
|
||||
msg.cmd.code = ac_io_u16(AC_IO_CMD_PANB_START_AUTO_INPUT);
|
||||
msg.cmd.nbytes = 1;
|
||||
msg.cmd.count = node_count;
|
||||
|
||||
if (!aciodrv_send(device, &msg)) {
|
||||
log_warning("Starting auto input failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
log_info("Started auto input for %d nodes", node_count);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aciodrv_panb_recv_poll(struct aciodrv_device_ctx *device, struct ac_io_panb_poll_in *poll_in)
|
||||
{
|
||||
log_assert(device);
|
||||
struct ac_io_message msg;
|
||||
struct ac_io_panb_poll_in *poll_res = (struct ac_io_panb_poll_in *) &msg.cmd.raw;
|
||||
|
||||
msg.cmd.code = ac_io_u16(AC_IO_CMD_PANB_POLL_REPLY);
|
||||
msg.cmd.nbytes = sizeof(struct ac_io_panb_poll_in);
|
||||
|
||||
if (!aciodrv_recv(device,
|
||||
&msg, offsetof(struct ac_io_message, cmd.raw) + msg.cmd.nbytes + 1)) {
|
||||
log_warning("Getting state failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (poll_in != NULL){
|
||||
memcpy(poll_in, poll_res, sizeof(struct ac_io_panb_poll_in));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aciodrv_panb_send_lamp(struct aciodrv_device_ctx *device,
|
||||
uint8_t node_id, struct ac_io_panb_poll_out *state)
|
||||
{
|
||||
log_assert(device);
|
||||
struct ac_io_message msg;
|
||||
|
||||
/* only the first node is handling the commands */
|
||||
if (node_id != 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
msg.addr = node_id + 1;
|
||||
msg.cmd.code = ac_io_u16(AC_IO_CMD_PANB_SEND_LAMP);
|
||||
msg.cmd.nbytes = 0x54;
|
||||
memcpy(&msg.cmd.raw, state, sizeof(struct ac_io_panb_poll_out));
|
||||
|
||||
if (!aciodrv_send(device, &msg)) {
|
||||
log_warning("Sending lamp state failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
56
src/main/aciodrv/panb.h
Normal file
56
src/main/aciodrv/panb.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#ifndef ACIODRV_PANB_H
|
||||
#define ACIODRV_PANB_H
|
||||
|
||||
#include "acio/panb.h"
|
||||
|
||||
/**
|
||||
* Send the AC_IO_CMD_PANB_START_AUTO_INPUT command on a PANB device.
|
||||
*
|
||||
* @param device Context of opened device.
|
||||
* @param node_id node_id Id of the node to query (0 based).
|
||||
* @param node_count The number of nodes to poll.
|
||||
* @return True if successful, false on error.
|
||||
* @note node_id should be 0, PANB internally manages the other nodes.
|
||||
* @note Upon calling, the device will stop replying to commands and just keep sending
|
||||
* AC_IO_CMD_PANB_POLL_REPLY messages indefinitely. Failure to retrieve them fast enough
|
||||
* will cause the device to malfunction. It is thus advised to make use of the aciodrv-proc
|
||||
* module to spawn a thread that will handle these messages and provide an easy access to the
|
||||
* latest input state.
|
||||
* @note This module is supposed to be used in combination with the common
|
||||
* device driver foundation.
|
||||
* @see driver.h
|
||||
*/
|
||||
bool aciodrv_panb_start_auto_input(struct aciodrv_device_ctx *device, uint8_t node_id, uint8_t node_count);
|
||||
|
||||
/**
|
||||
* Retrieve a AC_IO_CMD_PANB_POLL_REPLY message from a PANB device. This assumes that there
|
||||
* is such message incoming (ie. that start_auto_input has been called prior).
|
||||
*
|
||||
* @param device Context of opened device.
|
||||
* @param poll_in Buffer to hold the received message, or NULL.
|
||||
* @return True if successful, false on error.
|
||||
* @note node_id should be 0, PANB internally manages the other nodes.
|
||||
* @note Failure to retrieve the incoming messages fast enough will cause the device to malfunction.
|
||||
* It is thus advised to make use of the aciodrv-proc module to spawn a thread that will handle these
|
||||
* messages and provide an easy access to the latest input state.
|
||||
* @note This module is supposed to be used in combination with the common
|
||||
* device driver foundation.
|
||||
* @see driver.h
|
||||
*/
|
||||
bool aciodrv_panb_recv_poll(struct aciodrv_device_ctx *device, struct ac_io_panb_poll_in *poll_in);
|
||||
|
||||
/**
|
||||
* Light lamps on a PANB device.
|
||||
*
|
||||
* @param node_id Id of the node to query (0 based).
|
||||
* @param state Pointer to a lamp state struct
|
||||
* (mandatory).
|
||||
* @return True on success, false on error.
|
||||
* @note node_id should be 0, PANB internally manages the other nodes.
|
||||
* @note This module is supposed to be used in combination with the common
|
||||
* device driver foundation.
|
||||
* @see driver.h
|
||||
*/
|
||||
bool aciodrv_panb_send_lamp(struct aciodrv_device_ctx *device, uint8_t node_id, struct ac_io_panb_poll_out *state);
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,6 @@
|
||||
#define LOG_MODULE "aciodrv-port"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -7,17 +8,15 @@
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
static HANDLE aciodrv_port_fd;
|
||||
|
||||
bool aciodrv_port_open(const char *port, int baud)
|
||||
HANDLE aciodrv_port_open(const char *port_path, int baud)
|
||||
{
|
||||
COMMTIMEOUTS ct;
|
||||
DCB dcb;
|
||||
|
||||
log_info("Opening ACIO on %s at %d baud", port, baud);
|
||||
log_info("Opening ACIO on %s at %d baud", port_path, baud);
|
||||
|
||||
aciodrv_port_fd = CreateFile(
|
||||
port,
|
||||
HANDLE port_fd = CreateFile(
|
||||
port_path,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
@@ -25,26 +24,26 @@ bool aciodrv_port_open(const char *port, int baud)
|
||||
FILE_FLAG_WRITE_THROUGH | FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
if (aciodrv_port_fd == INVALID_HANDLE_VALUE) {
|
||||
log_warning("Failed to open %s", port);
|
||||
if (port_fd == INVALID_HANDLE_VALUE) {
|
||||
log_warning("Failed to open %s", port_path);
|
||||
|
||||
goto early_fail;
|
||||
}
|
||||
|
||||
if (!SetCommMask(aciodrv_port_fd, EV_RXCHAR)) {
|
||||
if (!SetCommMask(port_fd, EV_RXCHAR)) {
|
||||
log_warning("SetCommMask failed");
|
||||
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!SetupComm(aciodrv_port_fd, 0x1000, 0x1000)) {
|
||||
if (!SetupComm(port_fd, 0x1000, 0x1000)) {
|
||||
log_warning("SetupComm failed");
|
||||
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!PurgeComm(
|
||||
aciodrv_port_fd,
|
||||
port_fd,
|
||||
PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR)) {
|
||||
log_warning("PurgeComm failed");
|
||||
|
||||
@@ -57,7 +56,7 @@ bool aciodrv_port_open(const char *port, int baud)
|
||||
ct.ReadTotalTimeoutMultiplier = 0;
|
||||
ct.WriteTotalTimeoutMultiplier = 0;
|
||||
|
||||
if (!SetCommTimeouts(aciodrv_port_fd, &ct)) {
|
||||
if (!SetCommTimeouts(port_fd, &ct)) {
|
||||
log_warning("SetCommTimeouts failed");
|
||||
|
||||
goto fail;
|
||||
@@ -65,7 +64,7 @@ bool aciodrv_port_open(const char *port, int baud)
|
||||
|
||||
dcb.DCBlength = sizeof(dcb);
|
||||
|
||||
if (!GetCommState(aciodrv_port_fd, &dcb)) {
|
||||
if (!GetCommState(port_fd, &dcb)) {
|
||||
log_warning("GetCommState failed");
|
||||
|
||||
goto fail;
|
||||
@@ -90,46 +89,47 @@ bool aciodrv_port_open(const char *port, int baud)
|
||||
dcb.XonLim = 100;
|
||||
dcb.XoffLim = 100;
|
||||
|
||||
if (!SetCommState(aciodrv_port_fd, &dcb)) {
|
||||
if (!SetCommState(port_fd, &dcb)) {
|
||||
log_warning("SetCommState failed");
|
||||
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!EscapeCommFunction(aciodrv_port_fd, SETDTR)) {
|
||||
if (!EscapeCommFunction(port_fd, SETDTR)) {
|
||||
log_warning("SETDTR failed: err = %lu", GetLastError());
|
||||
|
||||
goto fail;
|
||||
}
|
||||
|
||||
log_info("Opened ACIO device on %s", port);
|
||||
log_info("[%p] Opened ACIO device on %s", port_fd, port_path);
|
||||
|
||||
return true;
|
||||
return port_fd;
|
||||
|
||||
fail:
|
||||
CloseHandle(aciodrv_port_fd);
|
||||
CloseHandle(port_fd);
|
||||
|
||||
early_fail:
|
||||
aciodrv_port_fd = NULL;
|
||||
return false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int aciodrv_port_read(void *bytes, int nbytes)
|
||||
int aciodrv_port_read(HANDLE port_fd, void *bytes, int nbytes)
|
||||
{
|
||||
DWORD nread;
|
||||
|
||||
if (aciodrv_port_fd == NULL) {
|
||||
log_assert(bytes);
|
||||
|
||||
if (port_fd == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ClearCommError(aciodrv_port_fd, NULL, NULL)) {
|
||||
log_warning("ClearCommError failed");
|
||||
if (!ClearCommError(port_fd, NULL, NULL)) {
|
||||
log_warning("[%p] ClearCommError failed", port_fd);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!ReadFile(aciodrv_port_fd, bytes, nbytes, &nread, NULL)) {
|
||||
log_warning("ReadFile failed: err = %lu", GetLastError());
|
||||
if (!ReadFile(port_fd, bytes, nbytes, &nread, NULL)) {
|
||||
log_warning("[%p] ReadFile failed: err = %lu", port_fd, GetLastError());
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -137,16 +137,18 @@ int aciodrv_port_read(void *bytes, int nbytes)
|
||||
return nread;
|
||||
}
|
||||
|
||||
int aciodrv_port_write(const void *bytes, int nbytes)
|
||||
int aciodrv_port_write(HANDLE port_fd, const void *bytes, int nbytes)
|
||||
{
|
||||
DWORD nwrit;
|
||||
|
||||
if (aciodrv_port_fd == NULL) {
|
||||
log_assert(bytes);
|
||||
|
||||
if (port_fd == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!WriteFile(aciodrv_port_fd, bytes, nbytes, &nwrit, NULL)) {
|
||||
log_warning("WriteFile failed: err = %lu", GetLastError());
|
||||
if (!WriteFile(port_fd, bytes, nbytes, &nwrit, NULL)) {
|
||||
log_warning("[%p] WriteFile failed: err = %lu", port_fd, GetLastError());
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -154,9 +156,9 @@ int aciodrv_port_write(const void *bytes, int nbytes)
|
||||
return nwrit;
|
||||
}
|
||||
|
||||
void aciodrv_port_close(void)
|
||||
void aciodrv_port_close(HANDLE port_fd)
|
||||
{
|
||||
if (aciodrv_port_fd != NULL) {
|
||||
CloseHandle(aciodrv_port_fd);
|
||||
if (port_fd != NULL) {
|
||||
CloseHandle(port_fd);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,39 +4,45 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/**
|
||||
* Open a serial port for communication with a ACIO device.
|
||||
*
|
||||
* @param port Port the device is connected to (e.g. "COM1")
|
||||
* @param baud Baud rate for communication (e.g. 57600 for ICCA)
|
||||
* @return True if opening the com port was successful, false on error.
|
||||
* @return HANDLE of the port, NULL on error
|
||||
* @note This will open and setup the com port, only.
|
||||
*/
|
||||
bool aciodrv_port_open(const char *port, int baud);
|
||||
HANDLE aciodrv_port_open(const char *port_path, int baud);
|
||||
|
||||
/**
|
||||
* Read data from the opened com port.
|
||||
*
|
||||
* @param port_fd HANDLE of opened serial port
|
||||
* @param bytes Pointer to an allocated buffer to read the data into.
|
||||
* @param nbytes Number of bytes to read. Has to be less or equal the allocated
|
||||
* buffer size.
|
||||
* @return Number of bytes read on success or -1 on error.
|
||||
*/
|
||||
int aciodrv_port_read(void *bytes, int nbytes);
|
||||
int aciodrv_port_read(HANDLE port_fd, void *bytes, int nbytes);
|
||||
|
||||
/**
|
||||
* Write data to the opened com port.
|
||||
*
|
||||
* @param port_fd HANDLE of opened serial port
|
||||
* @param bytes Pointer to an allocated buffer with data to write.
|
||||
* @param nbytes Number of bytes to write. Has to be equal or less the size
|
||||
* of the allocated buffer.
|
||||
* @return Number of bytes written on success or -1 on error.
|
||||
*/
|
||||
int aciodrv_port_write(const void *bytes, int nbytes);
|
||||
int aciodrv_port_write(HANDLE port_fd, const void *bytes, int nbytes);
|
||||
|
||||
/**
|
||||
* Close the previously opened com port.
|
||||
*
|
||||
* @param port_fd HANDLE of opened serial port
|
||||
*/
|
||||
void aciodrv_port_close(void);
|
||||
void aciodrv_port_close(HANDLE port_fd);
|
||||
|
||||
#endif
|
||||
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
|
||||
@@ -30,8 +30,16 @@ void ac_io_emu_init(struct ac_io_emu *emu, const wchar_t *filename)
|
||||
log_assert(emu != NULL);
|
||||
log_assert(filename != NULL);
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
memset(emu, 0, sizeof(*emu));
|
||||
emu->fd = iohook_open_dummy_fd();
|
||||
|
||||
hr = iohook_open_nul_fd(&emu->fd);
|
||||
|
||||
if (hr != S_OK) {
|
||||
log_fatal("Opening nul fd failed: %08lx", hr);
|
||||
}
|
||||
|
||||
emu->wfilename = wstr_dup(filename);
|
||||
wstr_narrow(filename, &emu->filename);
|
||||
ac_io_in_init(&emu->in);
|
||||
@@ -126,6 +134,7 @@ static HRESULT ac_io_emu_write(struct ac_io_emu *emu, struct irp *irp)
|
||||
break;
|
||||
}
|
||||
|
||||
// this supplies a single SOF byte per byte read
|
||||
ac_io_in_supply(&emu->in, NULL, 0);
|
||||
ac_io_out_consume_message(&emu->out);
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ void ac_io_emu_h44b_dispatch_request(
|
||||
req->cmd.raw[i * 3 + 2]);
|
||||
}
|
||||
|
||||
jb_io_write_outputs();
|
||||
jb_io_write_lights();
|
||||
|
||||
ac_io_emu_h44b_send_status(h44b, req, 0x00);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#define LOG_MODULE "acioemu-hdxs"
|
||||
|
||||
#include "acio/hdxs.h"
|
||||
#include "acio/acio.h"
|
||||
|
||||
#include "acioemu/emu.h"
|
||||
@@ -18,12 +19,20 @@ static void ac_io_emu_hdxs_send_status(
|
||||
const struct ac_io_message *req,
|
||||
uint8_t status);
|
||||
|
||||
void ac_io_emu_hdxs_init(struct ac_io_emu_hdxs *hdxs, struct ac_io_emu *emu)
|
||||
void ac_io_emu_hdxs_init(
|
||||
struct ac_io_emu_hdxs *hdxs,
|
||||
struct ac_io_emu *emu,
|
||||
acio_hdxs_dispatcher lights_dispatcher)
|
||||
{
|
||||
log_assert(hdxs != NULL);
|
||||
log_assert(emu != NULL);
|
||||
|
||||
if (lights_dispatcher == NULL) {
|
||||
log_warning("NULL lights_dispatcher, HDXS light output won't work");
|
||||
}
|
||||
|
||||
hdxs->emu = emu;
|
||||
hdxs->lights_dispatcher = lights_dispatcher;
|
||||
}
|
||||
|
||||
void ac_io_emu_hdxs_dispatch_request(
|
||||
@@ -51,9 +60,19 @@ void ac_io_emu_hdxs_dispatch_request(
|
||||
|
||||
case AC_IO_CMD_CLEAR:
|
||||
log_misc("AC_IO_CMD_CLEAR(%d)", req->addr);
|
||||
ac_io_emu_hdxs_send_status(hdxs, req, 0x00);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_HDXS_CMD_SET_OUTPUTS:
|
||||
if (hdxs->lights_dispatcher != NULL) {
|
||||
hdxs->lights_dispatcher(hdxs, req);
|
||||
}
|
||||
ac_io_emu_hdxs_send_status(hdxs, req, 0x00);
|
||||
|
||||
break;
|
||||
|
||||
case 0x110:
|
||||
case 0x112:
|
||||
case 0x128:
|
||||
ac_io_emu_hdxs_send_status(hdxs, req, 0x00);
|
||||
|
||||
@@ -86,11 +105,11 @@ static void ac_io_emu_hdxs_cmd_send_version(
|
||||
resp.cmd.version.type = ac_io_u32(AC_IO_NODE_TYPE_LED_STRIP);
|
||||
resp.cmd.version.flag = 0x00;
|
||||
resp.cmd.version.major = 0x01;
|
||||
resp.cmd.version.minor = 0x06;
|
||||
resp.cmd.version.revision = 0x00;
|
||||
resp.cmd.version.minor = 0x00;
|
||||
resp.cmd.version.revision = 0x01;
|
||||
memcpy(
|
||||
resp.cmd.version.product_code,
|
||||
"HDXS",
|
||||
"HDXB",
|
||||
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));
|
||||
|
||||
@@ -5,12 +5,21 @@
|
||||
|
||||
#include "acioemu/emu.h"
|
||||
|
||||
struct ac_io_emu_hdxs;
|
||||
struct ac_io_message;
|
||||
|
||||
typedef void (*acio_hdxs_dispatcher)(
|
||||
struct ac_io_emu_hdxs *emu, const struct ac_io_message *req);
|
||||
|
||||
struct ac_io_emu_hdxs {
|
||||
struct ac_io_emu *emu;
|
||||
// TODO ops vtbl
|
||||
acio_hdxs_dispatcher lights_dispatcher;
|
||||
};
|
||||
|
||||
void ac_io_emu_hdxs_init(struct ac_io_emu_hdxs *hdxs, struct ac_io_emu *emu);
|
||||
void ac_io_emu_hdxs_init(
|
||||
struct ac_io_emu_hdxs *hdxs,
|
||||
struct ac_io_emu *emu,
|
||||
acio_hdxs_dispatcher lights_dispatcher);
|
||||
|
||||
void ac_io_emu_hdxs_dispatch_request(
|
||||
struct ac_io_emu_hdxs *hdxs, const struct ac_io_message *req);
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "bemanitools/eamio.h"
|
||||
|
||||
#include "util/crc.h"
|
||||
#include "util/time.h"
|
||||
|
||||
enum ac_io_icca_subcmd {
|
||||
@@ -28,20 +29,14 @@ enum ac_io_icca_flag {
|
||||
AC_IO_ICCA_FLAG_SOLENOID = 0x40
|
||||
};
|
||||
|
||||
enum ac_io_icca_status_code {
|
||||
AC_IO_ICCA_STATUS_FAULT = 0x00,
|
||||
AC_IO_ICCA_STATUS_IDLE = 0x01,
|
||||
AC_IO_ICCA_STATUS_GOT_UID = 0x02,
|
||||
AC_IO_ICCA_STATUS_IDLE_NEW = 0x04
|
||||
};
|
||||
|
||||
static void ac_io_emu_icca_cmd_send_version(
|
||||
struct ac_io_emu_icca *icca, const struct ac_io_message *req);
|
||||
|
||||
static void ac_io_emu_icca_send_state(
|
||||
struct ac_io_emu_icca *icca,
|
||||
const struct ac_io_message *req,
|
||||
uint64_t delay_us);
|
||||
uint64_t delay_us,
|
||||
bool encrypted);
|
||||
|
||||
static void ac_io_emu_icca_send_empty(
|
||||
struct ac_io_emu_icca *icca, const struct ac_io_message *req);
|
||||
@@ -51,6 +46,12 @@ static void ac_io_emu_icca_send_status(
|
||||
const struct ac_io_message *req,
|
||||
uint8_t status);
|
||||
|
||||
static void ac_io_emu_icca_cipher(
|
||||
struct ac_io_emu_icca *icca, uint8_t *data, size_t length);
|
||||
|
||||
static void ac_io_emu_icca_cipher_set_key(
|
||||
struct ac_io_emu_icca *icca, const struct ac_io_message *req);
|
||||
|
||||
void ac_io_emu_icca_init(
|
||||
struct ac_io_emu_icca *icca, struct ac_io_emu *emu, uint8_t unit_no)
|
||||
{
|
||||
@@ -59,6 +60,15 @@ void ac_io_emu_icca_init(
|
||||
icca->unit_no = unit_no;
|
||||
// queue must be started
|
||||
icca->fault = true;
|
||||
|
||||
// default to 1.6.0
|
||||
icca->version = v160;
|
||||
}
|
||||
|
||||
void ac_io_emu_icca_set_version(
|
||||
struct ac_io_emu_icca *icca, enum ac_io_emu_icca_version version)
|
||||
{
|
||||
icca->version = version;
|
||||
}
|
||||
|
||||
void ac_io_emu_icca_dispatch_request(
|
||||
@@ -115,15 +125,15 @@ void ac_io_emu_icca_dispatch_request(
|
||||
|
||||
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;
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCA_CMD_ENGAGE:
|
||||
ac_io_emu_icca_send_state(icca, req, 0);
|
||||
ac_io_emu_icca_send_state(icca, req, 0, false);
|
||||
|
||||
break;
|
||||
|
||||
@@ -174,6 +184,7 @@ void ac_io_emu_icca_dispatch_request(
|
||||
break;
|
||||
}
|
||||
|
||||
case AC_IO_ICCA_CMD_POLL_ENCRYPTED:
|
||||
case AC_IO_ICCA_CMD_POLL:
|
||||
delay_us = time_get_elapsed_us(
|
||||
time_get_counter() - icca->time_counter_last_poll);
|
||||
@@ -185,13 +196,26 @@ void ac_io_emu_icca_dispatch_request(
|
||||
}
|
||||
|
||||
icca->time_counter_last_poll = time_get_counter();
|
||||
ac_io_emu_icca_send_state(icca, req, delay_us);
|
||||
bool encrypted = cmd_code == AC_IO_ICCA_CMD_POLL_ENCRYPTED;
|
||||
ac_io_emu_icca_send_state(icca, req, delay_us, encrypted);
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCA_CMD_POLL_FELICA:
|
||||
icca->detected_new_reader = true;
|
||||
ac_io_emu_icca_send_status(icca, req, 0x01);
|
||||
|
||||
if (icca->version == v170) {
|
||||
ac_io_emu_icca_send_empty(icca, req);
|
||||
} else {
|
||||
ac_io_emu_icca_send_status(icca, req, 0x01);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AC_IO_ICCA_CMD_KEY_EXCHANGE:
|
||||
icca->detected_new_reader = true;
|
||||
log_misc("AC_IO_ICCA_CMD_KEY_EXCHANGE(%d)", req->addr);
|
||||
ac_io_emu_icca_cipher_set_key(icca, req);
|
||||
|
||||
break;
|
||||
|
||||
@@ -215,10 +239,27 @@ static void ac_io_emu_icca_cmd_send_version(
|
||||
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_ICCA);
|
||||
|
||||
resp.cmd.version.flag = 0x00;
|
||||
resp.cmd.version.major = 0x01;
|
||||
resp.cmd.version.minor = 0x06;
|
||||
|
||||
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;
|
||||
} else if (icca->version == v170) {
|
||||
resp.cmd.version.minor = 0x07;
|
||||
} else {
|
||||
// probably log invalid version here
|
||||
log_warning(
|
||||
"Unknown ICCA version: %d emulation requested",
|
||||
icca->version);
|
||||
}
|
||||
|
||||
resp.cmd.version.revision = 0x00;
|
||||
|
||||
memcpy(
|
||||
resp.cmd.version.product_code,
|
||||
"ICCA",
|
||||
@@ -261,7 +302,8 @@ static void ac_io_emu_icca_send_status(
|
||||
static void ac_io_emu_icca_send_state(
|
||||
struct ac_io_emu_icca *icca,
|
||||
const struct ac_io_message *req,
|
||||
uint64_t delay_us)
|
||||
uint64_t delay_us,
|
||||
bool encrypted)
|
||||
{
|
||||
struct ac_io_message resp;
|
||||
struct ac_io_icca_state *body;
|
||||
@@ -319,7 +361,10 @@ static void ac_io_emu_icca_send_state(
|
||||
} else if (card_full_insert) {
|
||||
body->status_code = AC_IO_ICCA_STATUS_GOT_UID;
|
||||
} else {
|
||||
if (icca->detected_new_reader) {
|
||||
if (icca->detected_new_reader && icca->version == v170) {
|
||||
// else we get a power failure?
|
||||
body->status_code = 0;
|
||||
} else if (icca->detected_new_reader) {
|
||||
body->status_code = AC_IO_ICCA_STATUS_IDLE_NEW;
|
||||
} else {
|
||||
body->status_code = AC_IO_ICCA_STATUS_IDLE;
|
||||
@@ -384,5 +429,88 @@ static void ac_io_emu_icca_send_state(
|
||||
body->status_code = AC_IO_ICCA_STATUS_FAULT;
|
||||
}
|
||||
|
||||
if (encrypted) {
|
||||
size_t base_state_sz = sizeof(struct ac_io_icca_state);
|
||||
resp.cmd.nbytes = base_state_sz + 2;
|
||||
|
||||
if (!icca->cipher_started) {
|
||||
log_warning("No crypto keys set for unit %d", icca->unit_no);
|
||||
} else {
|
||||
uint16_t crc = crc16_msb(resp.cmd.raw, base_state_sz, 0);
|
||||
|
||||
resp.cmd.raw[base_state_sz + 0] = (crc >> 8) & 0xFF;
|
||||
resp.cmd.raw[base_state_sz + 1] = crc & 0xFF;
|
||||
|
||||
ac_io_emu_icca_cipher(icca, resp.cmd.raw, 18);
|
||||
}
|
||||
}
|
||||
|
||||
ac_io_emu_response_push(icca->emu, &resp, delay_us);
|
||||
}
|
||||
|
||||
static void ac_io_emu_icca_cipher_shift_keys(struct ac_io_emu_icca *icca)
|
||||
{
|
||||
uint32_t key4_old = icca->cipher_keys[3];
|
||||
uint32_t key_new = (key4_old << 11) ^ key4_old;
|
||||
uint32_t key1_old = icca->cipher_keys[0];
|
||||
|
||||
// shift keys up
|
||||
icca->cipher_keys[3] = icca->cipher_keys[2];
|
||||
icca->cipher_keys[2] = icca->cipher_keys[1];
|
||||
icca->cipher_keys[1] = icca->cipher_keys[0];
|
||||
icca->cipher_keys[0] =
|
||||
((((key1_old >> 11) ^ key_new) >> 8) ^ key_new ^ key1_old);
|
||||
}
|
||||
|
||||
static void
|
||||
ac_io_emu_icca_cipher(struct ac_io_emu_icca *icca, uint8_t *data, size_t length)
|
||||
{
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
uint8_t count4 = i % 4;
|
||||
// shift keys every 4 bytes
|
||||
if (count4 == 0) {
|
||||
ac_io_emu_icca_cipher_shift_keys(icca);
|
||||
}
|
||||
|
||||
// process data
|
||||
data[i] =
|
||||
(uint8_t)(icca->cipher_keys[0] >> (((3 - count4) << 3)) ^ data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void ac_io_emu_icca_cipher_set_key(
|
||||
struct ac_io_emu_icca *icca, 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 = 4; // 4 bytes, uint32_t
|
||||
|
||||
uint32_t host_key = 0x00000000;
|
||||
host_key |= req->cmd.raw[0] << 24;
|
||||
host_key |= req->cmd.raw[1] << 16;
|
||||
host_key |= req->cmd.raw[2] << 8;
|
||||
host_key |= req->cmd.raw[3];
|
||||
|
||||
// TODO: should probably RNG this
|
||||
uint32_t reader_key = 0x14243444;
|
||||
resp.cmd.raw[0] = (reader_key >> 24) & 0xFF;
|
||||
resp.cmd.raw[1] = (reader_key >> 16) & 0xFF;
|
||||
resp.cmd.raw[2] = (reader_key >> 8) & 0xFF;
|
||||
resp.cmd.raw[3] = (reader_key) & 0xFF;
|
||||
|
||||
// so I looked these constants up, this isn't actually a secure key
|
||||
// generator it's actually Marsaglia's "KISS" algorithm with different
|
||||
// initial states
|
||||
icca->cipher_keys[0] = reader_key ^ 0x5491333;
|
||||
icca->cipher_keys[1] = host_key ^ 0x1F123BB5;
|
||||
icca->cipher_keys[2] = reader_key ^ 0x159A55E5;
|
||||
icca->cipher_keys[3] = host_key ^ 0x75BCD15;
|
||||
|
||||
log_misc("keys set to: H: %08x R: %08x", host_key, reader_key);
|
||||
|
||||
ac_io_emu_response_push(icca->emu, &resp, 0);
|
||||
icca->cipher_started = true;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
|
||||
#include "acioemu/emu.h"
|
||||
|
||||
enum ac_io_emu_icca_version {
|
||||
v150 = 0x5,
|
||||
v160 = 0x6,
|
||||
v170 = 0x7,
|
||||
};
|
||||
|
||||
struct ac_io_emu_icca {
|
||||
struct ac_io_emu *emu;
|
||||
uint8_t unit_no;
|
||||
@@ -20,11 +26,19 @@ struct ac_io_emu_icca {
|
||||
bool keypad_started;
|
||||
bool polling_started;
|
||||
uint64_t time_counter_last_poll;
|
||||
|
||||
enum ac_io_emu_icca_version version;
|
||||
bool cipher_started;
|
||||
uint32_t cipher_keys[4];
|
||||
};
|
||||
|
||||
void ac_io_emu_icca_init(
|
||||
struct ac_io_emu_icca *icca, struct ac_io_emu *emu, uint8_t unit_no);
|
||||
|
||||
// optional, call after init to override default version
|
||||
void ac_io_emu_icca_set_version(
|
||||
struct ac_io_emu_icca *icca, enum ac_io_emu_icca_version version);
|
||||
|
||||
void ac_io_emu_icca_dispatch_request(
|
||||
struct ac_io_emu_icca *icca, const struct ac_io_message *req);
|
||||
|
||||
|
||||
@@ -169,6 +169,10 @@ static void ac_io_emu_iccb_send_state(
|
||||
|
||||
/* 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) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user