Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e1008576ce | ||
|
|
f41cdba8b8 | ||
|
|
1379c1e11b | ||
|
|
d1525a98dd | ||
|
|
329d6a80a3 | ||
|
|
f37f216c69 | ||
|
|
bdf493d2fb | ||
|
|
bec007d52a | ||
|
|
a177913bd6 | ||
|
|
0fdde8b32d | ||
|
|
09b3a6c24a | ||
|
|
f8b2f5f40d | ||
|
|
882a3557c9 | ||
|
|
2454141cab | ||
|
|
4b740c13e8 | ||
|
|
ec4e81d9d3 | ||
|
|
9a964e6bdb | ||
|
|
9b2ed6910e | ||
|
|
82343d8cf1 | ||
|
|
c0101cb614 | ||
|
|
820036087d | ||
|
|
ebd80d3749 | ||
|
|
3bff7f8a5e | ||
|
|
9ce47e7050 | ||
|
|
13c87eaf8d | ||
|
|
f8d394e124 |
-136
@@ -1,136 +0,0 @@
|
|||||||
#
|
|
||||||
# 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
|
|
||||||
- upload
|
|
||||||
- release
|
|
||||||
|
|
||||||
build:
|
|
||||||
stage: build
|
|
||||||
only:
|
|
||||||
refs:
|
|
||||||
- master
|
|
||||||
- tags
|
|
||||||
before_script:
|
|
||||||
- apk update && apk add make > /dev/null
|
|
||||||
script:
|
|
||||||
- make build-docker
|
|
||||||
artifacts:
|
|
||||||
paths:
|
|
||||||
- build
|
|
||||||
expire_in: 1 week
|
|
||||||
|
|
||||||
upload-package-registry:
|
|
||||||
stage: upload
|
|
||||||
image: curlimages/curl:latest
|
|
||||||
only:
|
|
||||||
refs:
|
|
||||||
- master
|
|
||||||
- tags
|
|
||||||
dependencies:
|
|
||||||
- build
|
|
||||||
script:
|
|
||||||
- |
|
|
||||||
if [ "${CI_COMMIT_TAG}" ]; then
|
|
||||||
version="${CI_COMMIT_TAG}"
|
|
||||||
else
|
|
||||||
version="${CI_COMMIT_SHORT_SHA}"
|
|
||||||
fi
|
|
||||||
- |
|
|
||||||
curl \
|
|
||||||
--silent \
|
|
||||||
--fail \
|
|
||||||
--show-error \
|
|
||||||
--header "JOB-TOKEN: ${CI_JOB_TOKEN}" \
|
|
||||||
--upload-file "${DIST_PACKAGE_RELATIVE_PATH}" \
|
|
||||||
$PACKAGE_REGISTRY_URL/${version}/bemanitools.zip
|
|
||||||
|
|
||||||
upload-tools-page:
|
|
||||||
stage: upload
|
|
||||||
image: curlimages/curl:latest
|
|
||||||
only:
|
|
||||||
refs:
|
|
||||||
- tags
|
|
||||||
dependencies:
|
|
||||||
- build
|
|
||||||
script:
|
|
||||||
- |
|
|
||||||
curl \
|
|
||||||
--silent \
|
|
||||||
--fail \
|
|
||||||
--show-error \
|
|
||||||
--connect-timeout 5 \
|
|
||||||
--max-time 10 \
|
|
||||||
--retry 5 \
|
|
||||||
-F "key=${CI_TOOLS_UPLOAD_KEY}" \
|
|
||||||
-F "filename=${CI_PROJECT_NAME}-v${CI_COMMIT_TAG}.zip" \
|
|
||||||
-F "file=@${DIST_PACKAGE_RELATIVE_PATH}" \
|
|
||||||
${CI_TOOLS_UPLOAD_URL}
|
|
||||||
|
|
||||||
release-gitlab:
|
|
||||||
stage: release
|
|
||||||
image: registry.gitlab.com/gitlab-org/release-cli:v0.8.0
|
|
||||||
only:
|
|
||||||
refs:
|
|
||||||
- tags
|
|
||||||
script:
|
|
||||||
- version="$CI_COMMIT_TAG"
|
|
||||||
- release_message="$(scripts/ci/create-release-message.sh "${version}" < CHANGELOG.md)"
|
|
||||||
- |
|
|
||||||
release-cli create \
|
|
||||||
--name "bemanitools ${version}" \
|
|
||||||
--description="${release_message}" \
|
|
||||||
--tag-name ${version} \
|
|
||||||
--assets-link "{\"name\":\"Distribution binaries\",\"url\":\"${PACKAGE_REGISTRY_URL}/${version}/bemanitools.zip\"}"
|
|
||||||
|
|
||||||
release-pigstall:
|
|
||||||
stage: release
|
|
||||||
image: curlimages/curl:latest
|
|
||||||
only:
|
|
||||||
refs:
|
|
||||||
- tags
|
|
||||||
script:
|
|
||||||
- version="${CI_COMMIT_TAG}"
|
|
||||||
- changelog_excerpt="$(scripts/ci/create-release-message.sh "${version}" < CHANGELOG.md)"
|
|
||||||
- release_message="$(printf "bemanitools ${version} released\n${CI_TOOLS_URL}/bemanitools-v${version}.zip\n${changelog_excerpt}")"
|
|
||||||
- session="$(echo "$CI_PIGSTALL_SESSION_BASE64" | base64 -d)"
|
|
||||||
- data_prefix="$(echo "$CI_PIGSTALL_DATA_PREFIX_BASE64" | base64 -d)"
|
|
||||||
- link="$(echo "$CI_PIGSTALL_LINK_BASE64" | base64 -d)"
|
|
||||||
- |
|
|
||||||
curl \
|
|
||||||
--silent \
|
|
||||||
--fail \
|
|
||||||
--connect-timeout 5 \
|
|
||||||
--max-time 10 \
|
|
||||||
--retry 5 \
|
|
||||||
--show-error \
|
|
||||||
-H 'Content-Type: application/x-www-form-urlencoded' \
|
|
||||||
-H "Cookie: PHPSESSID=$CI_PIGSTALL_PHP_SESSION_ID; session=${session}" \
|
|
||||||
--data-raw "${data_prefix}&body=${release_message}" \
|
|
||||||
"${link}"
|
|
||||||
@@ -2,6 +2,34 @@
|
|||||||
Note for CI/CD: Ensure the version formatting in the sections is kept identical to the versions
|
Note for CI/CD: Ensure the version formatting in the sections is kept identical to the versions
|
||||||
given in tags. The pipeline will pick this up and cuts out the relevant section for release notes.
|
given in tags. The pipeline will pick this up and cuts out the relevant section for release notes.
|
||||||
|
|
||||||
|
## 5.48
|
||||||
|
### Features
|
||||||
|
* feat(config): Add invert analog input option. Remark: The old configuration file format is
|
||||||
|
upgraded but downgrading is not possible anymore. The new saves are using a new filename
|
||||||
|
and it doesn't delete the old files, see `C:\Users\<YOUR_USERNAME>\AppData\Roaming\DJHACKERS`
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
## 5.47
|
||||||
|
### Features
|
||||||
|
N/A
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* fix(ddr/p3ioemu): Handle unknown 2B command to fix DDR X IO errors
|
||||||
|
* fix(ddr/p3io): Crash on all supported DDR games due to incorrect p3io message size validation
|
||||||
|
* fix(geninput): Sony DualShock 4 not working
|
||||||
|
|
||||||
|
## 5.46
|
||||||
|
### Features
|
||||||
|
* feat(ddrio): Wrapper/shim library to drive another ddrio in a dedicated IO thread. Improves performance for highly IO
|
||||||
|
bound ddrio implementations, e.g. ddrio-p3io
|
||||||
|
* feat(iidxiotest): bi2a-iidx support
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
* fix(jb03/04): Missing XML in gamestart script
|
||||||
|
* fix(jbhook1): Rotate error message box when screen is rotated
|
||||||
|
* fix(jbhook1): Improve/fix automatic config/nvram fs initialization
|
||||||
|
|
||||||
## 5.45
|
## 5.45
|
||||||
### Features
|
### Features
|
||||||
* feat(iidx 30): Added support
|
* feat(iidx 30): Added support
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ include src/main/d3d9exhook/Module.mk
|
|||||||
include src/main/ddrhook-util/Module.mk
|
include src/main/ddrhook-util/Module.mk
|
||||||
include src/main/ddrhook1/Module.mk
|
include src/main/ddrhook1/Module.mk
|
||||||
include src/main/ddrhook2/Module.mk
|
include src/main/ddrhook2/Module.mk
|
||||||
|
include src/main/ddrio-async/Module.mk
|
||||||
include src/main/ddrio-p3io/Module.mk
|
include src/main/ddrio-p3io/Module.mk
|
||||||
include src/main/ddrio-mm/Module.mk
|
include src/main/ddrio-mm/Module.mk
|
||||||
include src/main/ddrio-smx/Module.mk
|
include src/main/ddrio-smx/Module.mk
|
||||||
@@ -730,6 +731,7 @@ $(zipdir)/ddr-16-x64.zip: \
|
|||||||
$(V)zip -j $@ $^
|
$(V)zip -j $@ $^
|
||||||
|
|
||||||
$(zipdir)/ddr-hwio-x86.zip: \
|
$(zipdir)/ddr-hwio-x86.zip: \
|
||||||
|
build/bin/indep-32/ddrio-async.dll \
|
||||||
build/bin/indep-32/ddrio-p3io.dll \
|
build/bin/indep-32/ddrio-p3io.dll \
|
||||||
build/bin/indep-32/ddrio-mm.dll \
|
build/bin/indep-32/ddrio-mm.dll \
|
||||||
build/bin/indep-32/ddrio-smx.dll \
|
build/bin/indep-32/ddrio-smx.dll \
|
||||||
@@ -741,6 +743,7 @@ $(zipdir)/ddr-hwio-x86.zip: \
|
|||||||
$(V)zip -j $@ $^
|
$(V)zip -j $@ $^
|
||||||
|
|
||||||
$(zipdir)/ddr-hwio-x64.zip: \
|
$(zipdir)/ddr-hwio-x64.zip: \
|
||||||
|
build/bin/indep-64/ddrio-async.dll \
|
||||||
build/bin/indep-64/ddrio-p3io.dll \
|
build/bin/indep-64/ddrio-p3io.dll \
|
||||||
build/bin/indep-64/ddrio-mm.dll \
|
build/bin/indep-64/ddrio-mm.dll \
|
||||||
build/bin/indep-64/ddrio-smx.dll \
|
build/bin/indep-64/ddrio-smx.dll \
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
# Bemanitools 5
|
# Bemanitools 5
|
||||||
[](https://dev.s-ul.net/djhackers/bemanitools/commits/master)
|
|
||||||
|
|
||||||
Version: 5.45
|
Version: `5.48`
|
||||||
|
|
||||||
[Release history](CHANGELOG.md)
|
[Changelog](CHANGELOG.md)
|
||||||
|
|
||||||
A collection of tools to run [various Bemani arcade games](#supported-games).
|
A collection of tools to run [various Bemani arcade games](#supported-games).
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
@@ -3,6 +3,7 @@
|
|||||||
cd /d %~dp0
|
cd /d %~dp0
|
||||||
|
|
||||||
if not exist dev\nvram mkdir dev\nvram
|
if not exist dev\nvram mkdir dev\nvram
|
||||||
|
if not exist dev\nvram\ea3-config.xml copy prop\ea3-config.xml dev\nvram\ea3-config.xml
|
||||||
if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml
|
if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml
|
||||||
if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml
|
if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml
|
||||||
if not exist dev\raw mkdir dev\raw
|
if not exist dev\raw mkdir dev\raw
|
||||||
|
|||||||
Vendored
+1
@@ -3,6 +3,7 @@
|
|||||||
cd /d %~dp0
|
cd /d %~dp0
|
||||||
|
|
||||||
if not exist dev\nvram mkdir dev\nvram
|
if not exist dev\nvram mkdir dev\nvram
|
||||||
|
if not exist dev\nvram\ea3-config.xml copy prop\ea3-config.xml dev\nvram\ea3-config.xml
|
||||||
if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml
|
if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml
|
||||||
if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml
|
if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml
|
||||||
if not exist dev\raw mkdir dev\raw
|
if not exist dev\raw mkdir dev\raw
|
||||||
|
|||||||
+2
-1
@@ -18,7 +18,8 @@ Table of contents:
|
|||||||
* [popnhook](popnhook/README.md): Documentation relevant to `popnhook` implementations
|
* [popnhook](popnhook/README.md): Documentation relevant to `popnhook` implementations
|
||||||
* [sdvxhook](sdvxhook/README.md): Documentation relevant to `sdvxhook` implementations
|
* [sdvxhook](sdvxhook/README.md): Documentation relevant to `sdvxhook` implementations
|
||||||
* Development
|
* Development
|
||||||
* [API](api.md): Available APIs for BT5 and instructions how to use them
|
* [API](api.md): Available APIs and IO (hardware) implementations for BT5 and instructions how
|
||||||
|
to use them
|
||||||
* [Architecture](architecture.md): Outline of BT5's architecture, how things are designed and why
|
* [Architecture](architecture.md): Outline of BT5's architecture, how things are designed and why
|
||||||
* [Development](development.md): Development environment, building, releasing, etc.
|
* [Development](development.md): Development environment, building, releasing, etc.
|
||||||
* [Developer documentation](dev/README.md): Various lose documentation/notes by developers
|
* [Developer documentation](dev/README.md): Various lose documentation/notes by developers
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ The following implementations are already shipped with BT5.
|
|||||||
* [ddrio-p3io.dll](ddrhook/ddrio-p3io.md): DDR P3IO (Dragon PCB) + EXTIO hardware
|
* [ddrio-p3io.dll](ddrhook/ddrio-p3io.md): DDR P3IO (Dragon PCB) + EXTIO hardware
|
||||||
* ddrio-mm.dll: Minimaid hardware
|
* ddrio-mm.dll: Minimaid hardware
|
||||||
* [ddrio-smx.dll](ddrhook/ddrio-smx.md): StepManiaX platforms
|
* [ddrio-smx.dll](ddrhook/ddrio-smx.md): StepManiaX platforms
|
||||||
|
* [ddrio-async](ddrhook/ddrio-async.md): Wrapper/shim library to drive another ddrio in
|
||||||
|
a dedicated IO thread
|
||||||
* Beatmania IIDX
|
* Beatmania IIDX
|
||||||
* iidxio.dll (default): Keyboard, joystick and mouse input
|
* iidxio.dll (default): Keyboard, joystick and mouse input
|
||||||
* [iidxio-bio2.dll](iidxhook/iidxio-bio2.md): BIO2 driver
|
* [iidxio-bio2.dll](iidxhook/iidxio-bio2.md): BIO2 driver
|
||||||
|
|||||||
@@ -46,7 +46,10 @@ IO hardware you want to use:
|
|||||||
* `ddrio`: Default implementation supporting keyboard, mouse and USB
|
* `ddrio`: Default implementation supporting keyboard, mouse and USB
|
||||||
game controllers
|
game controllers
|
||||||
* ddrio-mm: Support Minimaid custom interface
|
* ddrio-mm: Support Minimaid custom interface
|
||||||
* [ddrio-smx](ddrhook/ddrio-smx.md): Support for StepManiaX dance platforms
|
* [ddrio-smx](ddrio-smx.md): Support for StepManiaX dance platforms
|
||||||
|
* [ddrio-p3io](ddrio-p3io.md): P3IO + EXTIO driver implementation
|
||||||
|
* [ddrio-async](ddrio-async.md): Wrapper/shim library to drive another ddrio in
|
||||||
|
a dedicated IO thread
|
||||||
|
|
||||||
## Unicorntail
|
## Unicorntail
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# Asynchronous proxy wrapper for other ddrio implementations
|
||||||
|
|
||||||
|
This implementation of the Bemanitools API is not implementing support for any
|
||||||
|
specific IO hardware. It is a proxy/shim library that loads another ddrio
|
||||||
|
library, e.g. ddrio-p3io, and drives the entire backend in a dedicated IO
|
||||||
|
thread. By implementing this behind the ddrio API, it is fully transparent to
|
||||||
|
any existing application using it.
|
||||||
|
|
||||||
|
The main benefit is the improved IO polling performance depending on how
|
||||||
|
expensive the synchronous calls of the actual hardware are. For example,
|
||||||
|
*ddrio-p3io* has very expensive write calls with ~12 ms duration while read
|
||||||
|
calls take ~4 ms. Therefore, a full update cycle is already about as costly
|
||||||
|
as rendering an entire frame (at 60 fps).
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
For hook libraries, i.e. ddrhookX, but likely applicable to 3rd party
|
||||||
|
applications (consolidate their manuals).
|
||||||
|
|
||||||
|
* Have `ddrio-async.dll` in the same folder as your `ddrhookX.dll`
|
||||||
|
* Rename `ddrio-async.dll` to `ddrio.dll`
|
||||||
|
* Pick another ddrio library as the backend of your choice, e.g. `ddrio-p3io.dl`
|
||||||
|
and put it next to the async `ddrio.dll`
|
||||||
|
* Rename it to `ddrio-async-child.dll`, ddrio-async is looking for that filename
|
||||||
|
in the same folder
|
||||||
|
* Ensure that your `gamestart.bat` actually injects the appropriate `ddrhook.dll`, for example:
|
||||||
|
|
||||||
|
```bat
|
||||||
|
inject ddrhook1.dll ddr.exe ...*
|
||||||
|
```
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
```bat
|
||||||
|
launcher -K ddrhook2.dll arkmdxp3.dll ...*
|
||||||
|
```
|
||||||
+17
-11
@@ -1,18 +1,24 @@
|
|||||||
# Release process
|
# Release process
|
||||||
|
|
||||||
For bemanitools maintainers, steps for the release process:
|
For maintainers, steps for the release process:
|
||||||
|
|
||||||
1. Update the corresponding section in the [changelog](CHANGELOG.md) with bullet points reflecting
|
1. Update the corresponding section in the [changelog](CHANGELOG.md) with bullet points reflecting
|
||||||
major features merged into master since the previous release
|
major features merged into master since the previous release
|
||||||
1. Make sure you have the latest `master` state pulled to your local copy
|
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
|
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
|
[top of the readme](../README.md) as it always reflects the current version being worked on
|
||||||
on the `master` branch , e.g. 5.35: `git tag 5.35`
|
on the `master` branch , e.g. 0.04: `git tag 5.35`
|
||||||
1. Push the tag to upstream: `git push origin 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
|
1. The [build pipeline](https://github.com/djhackersdev/bemanitools/actions) should start
|
||||||
automatically once the tag is pushed including the steps `build` and `upload-release`
|
automatically once the tag is pushed including the steps `build` and `publish-release`
|
||||||
1. Once completed successfully, the release is uploaded
|
1. Once completed successfully, the release is published on the
|
||||||
1. Take the changelog of the published version and notify the pigs in the stall about it:
|
[releases page](https://github.com/djhackersdev/bemanitools/releases/)
|
||||||
|
1. Edit the latest release
|
||||||
|
1. Copy-pate the change log section of the respective version into the description
|
||||||
|
1. Un-check *Set as pre-release*
|
||||||
|
1. Check *Set as the latest release*
|
||||||
|
1. Click *Update release*
|
||||||
|
1. Notify any other channels, e.g. the pigs in the stall, about the latest release:
|
||||||
1. New post in thread
|
1. New post in thread
|
||||||
```
|
```
|
||||||
<insert version here> released: <direct link to published version>
|
<insert version here> released: <direct link to published version>
|
||||||
@@ -23,7 +29,7 @@ automatically once the tag is pushed including the steps `build` and `upload-rel
|
|||||||
1. Update the OP title by bumping the version number in it
|
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. 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
|
1. Bump the version number at the [top of the readme](../README.md) and add a new empty section
|
||||||
in the [changelog](CHANGELOG.md) with the new version number as title. Commit changes and push to
|
in the [changelog](../CHANGELOG.md) with the new version number as title. Commit changes and push to
|
||||||
`master` branch
|
`master` branch
|
||||||
1. Continue developing and merging MRs until you decide its time for another release
|
1. Continue developing and merging PRs until you decide its time for another release
|
||||||
@@ -11,5 +11,6 @@ src_aciotest := \
|
|||||||
kfca.c \
|
kfca.c \
|
||||||
panb.c \
|
panb.c \
|
||||||
rvol.c \
|
rvol.c \
|
||||||
|
bi2a-iidx.c \
|
||||||
bi2a-sdvx.c \
|
bi2a-sdvx.c \
|
||||||
main.c \
|
main.c \
|
||||||
|
|||||||
@@ -0,0 +1,109 @@
|
|||||||
|
#include "aciotest/bi2a-iidx.h"
|
||||||
|
|
||||||
|
#include "acio/acio.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "bio2drv/bi2a-iidx.h"
|
||||||
|
|
||||||
|
bool aciotest_bi2a_iidx_handler_init(
|
||||||
|
struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx)
|
||||||
|
{
|
||||||
|
*ctx = malloc(sizeof(uint32_t));
|
||||||
|
*((uint32_t *) *ctx) = 0;
|
||||||
|
|
||||||
|
return bio2drv_bi2a_iidx_init(device, node_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool aciotest_bi2a_iidx_handler_update(
|
||||||
|
struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx)
|
||||||
|
{
|
||||||
|
struct bi2a_iidx_state_in pin;
|
||||||
|
struct bi2a_iidx_state_out pout;
|
||||||
|
|
||||||
|
memset(&pout, 0, sizeof(pout));
|
||||||
|
|
||||||
|
if (!bio2drv_bi2a_iidx_poll(device, node_id, &pout, &pin)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
printf(
|
||||||
|
"|---------------------------------------|\n"
|
||||||
|
"| R Y G B Neons B G Y R |\n"
|
||||||
|
"| %d %d %d %d %d %d %d %d %d |\n"
|
||||||
|
"|---------------------------------------|\n"
|
||||||
|
"| NOW PLAYING: %c%c%c%c%c%c%c%c%c |\n"
|
||||||
|
"|---------------------------------------|\n"
|
||||||
|
"| Effect %d S1 S2 S3 S4 S5 Test %d|\n"
|
||||||
|
"|StartP1 %d %02d %02d %02d %02d %02d StartP2 %d|\n"
|
||||||
|
"| VEFX %d Service %d|\n"
|
||||||
|
"_________________________________________\n"
|
||||||
|
"| __ __ |\n"
|
||||||
|
"| / \\ _ / \\ |\n"
|
||||||
|
"| | %03d| %d %d %d |%d| %d %d %d | %03d| |\n"
|
||||||
|
"| \\___/ %d %d %d %d |_| %d %d %d %d \\___/ |\n"
|
||||||
|
"| |\n"
|
||||||
|
"|---------------------------------------|\n"
|
||||||
|
"|---------------------------------------|\n",
|
||||||
|
|
||||||
|
pout.SPOTLIGHT2[0].l_state,
|
||||||
|
pout.SPOTLIGHT2[1].l_state,
|
||||||
|
pout.SPOTLIGHT2[2].l_state,
|
||||||
|
pout.SPOTLIGHT2[3].l_state,
|
||||||
|
pout.NEONLAMP.l_state,
|
||||||
|
pout.SPOTLIGHT1[0].l_state,
|
||||||
|
pout.SPOTLIGHT1[1].l_state,
|
||||||
|
pout.SPOTLIGHT1[2].l_state,
|
||||||
|
pout.SPOTLIGHT1[3].l_state,
|
||||||
|
|
||||||
|
pout.SEG16[0],
|
||||||
|
pout.SEG16[1],
|
||||||
|
pout.SEG16[2],
|
||||||
|
pout.SEG16[3],
|
||||||
|
pout.SEG16[4],
|
||||||
|
pout.SEG16[5],
|
||||||
|
pout.SEG16[6],
|
||||||
|
pout.SEG16[7],
|
||||||
|
pout.SEG16[8],
|
||||||
|
|
||||||
|
pin.PANEL.y_effect,
|
||||||
|
pin.SYSTEM.v_test,
|
||||||
|
|
||||||
|
pin.PANEL.y_start1,
|
||||||
|
pin.SLIDER1.s_val,
|
||||||
|
pin.SLIDER2.s_val,
|
||||||
|
pin.SLIDER3.s_val,
|
||||||
|
pin.SLIDER4.s_val,
|
||||||
|
pin.SLIDER5.s_val,
|
||||||
|
pin.PANEL.y_start2,
|
||||||
|
|
||||||
|
pin.PANEL.y_vefx,
|
||||||
|
pin.SYSTEM.v_service,
|
||||||
|
|
||||||
|
pin.TURNTABLE1,
|
||||||
|
pin.P1SW2.b_val,
|
||||||
|
pin.P1SW4.b_val,
|
||||||
|
pin.P1SW6.b_val,
|
||||||
|
pin.SYSTEM.v_coin,
|
||||||
|
pin.P2SW2.b_val,
|
||||||
|
pin.P2SW4.b_val,
|
||||||
|
pin.P2SW6.b_val,
|
||||||
|
pin.TURNTABLE2,
|
||||||
|
|
||||||
|
pin.P1SW1.b_val,
|
||||||
|
pin.P1SW3.b_val,
|
||||||
|
pin.P1SW5.b_val,
|
||||||
|
pin.P1SW7.b_val,
|
||||||
|
pin.P2SW1.b_val,
|
||||||
|
pin.P2SW3.b_val,
|
||||||
|
pin.P2SW5.b_val,
|
||||||
|
pin.P2SW7.b_val
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef ACIOTEST_BI2A_IIDX_H
|
||||||
|
#define ACIOTEST_BI2A_IIDX_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "aciodrv/device.h"
|
||||||
|
|
||||||
|
bool aciotest_bi2a_iidx_handler_init(
|
||||||
|
struct aciodrv_device_ctx *device, uint8_t node_id, void **ctx);
|
||||||
|
bool aciotest_bi2a_iidx_handler_update(
|
||||||
|
struct aciodrv_device_ctx *device, uint8_t node_id, void *ctx);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
#include "aciodrv/device.h"
|
#include "aciodrv/device.h"
|
||||||
|
|
||||||
#include "aciotest/bi2a-sdvx.h"
|
#include "aciotest/bi2a-sdvx.h"
|
||||||
|
#include "aciotest/bi2a-iidx.h"
|
||||||
#include "aciotest/handler.h"
|
#include "aciotest/handler.h"
|
||||||
#include "aciotest/icca.h"
|
#include "aciotest/icca.h"
|
||||||
#include "aciotest/kfca.h"
|
#include "aciotest/kfca.h"
|
||||||
@@ -16,7 +18,7 @@
|
|||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
|
|
||||||
static uint8_t aciotest_cnt = 0;
|
static uint8_t aciotest_cnt = 0;
|
||||||
static uint8_t bi2a_mode = 0;
|
static uint8_t bi2a_mode = 255;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumerate supported ACIO nodes based on their product id.
|
* Enumerate supported ACIO nodes based on their product id.
|
||||||
@@ -53,14 +55,30 @@ static bool aciotest_assign_handler(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (product_type == AC_IO_NODE_TYPE_BI2A) {
|
if (product_type == AC_IO_NODE_TYPE_BI2A) {
|
||||||
if (bi2a_mode == 0) {
|
if (bi2a_mode == 255) {
|
||||||
|
printf(
|
||||||
|
"Unknown BI2A mode specified, please check your command.\n"
|
||||||
|
"Using bi2a-sdvx mode as default, press ENTER to continue\n"
|
||||||
|
);
|
||||||
|
bi2a_mode = 0;
|
||||||
|
getchar();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (bi2a_mode)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
handler->init = aciotest_bi2a_sdvx_handler_init;
|
handler->init = aciotest_bi2a_sdvx_handler_init;
|
||||||
handler->update = aciotest_bi2a_sdvx_handler_update;
|
handler->update = aciotest_bi2a_sdvx_handler_update;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
handler->init = aciotest_bi2a_iidx_handler_init;
|
||||||
|
handler->update = aciotest_bi2a_iidx_handler_update;
|
||||||
|
break;
|
||||||
|
|
||||||
return true;
|
default:
|
||||||
} else {
|
break;
|
||||||
printf("Unknown BI2A device specified");
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -76,13 +94,26 @@ int main(int argc, char **argv)
|
|||||||
"aciotest, build "__DATE__
|
"aciotest, build "__DATE__
|
||||||
" " __TIME__
|
" " __TIME__
|
||||||
"\n"
|
"\n"
|
||||||
"Usage: %s <com port str> <baud rate>\n"
|
"Usage: %s <com port str> <baud rate> <bi2a mode(optional)>\n"
|
||||||
"Example for two slotted readers: %s COM1 57600\n",
|
"Example:\n"
|
||||||
|
"\"%s COM1 57600\" for generic acio device\n"
|
||||||
|
"\"%s COM1 57600 bi2a-iidx\" for the iidx BI2A mode\n"
|
||||||
|
"\"%s COM1 57600 bi2a-sdvx\" for the sdvx BI2A mode\n",
|
||||||
|
argv[0],
|
||||||
|
argv[0],
|
||||||
argv[0],
|
argv[0],
|
||||||
argv[0]);
|
argv[0]);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argc == 4) {
|
||||||
|
if(!strcmp(argv[3],"bi2a-iidx")) {
|
||||||
|
bi2a_mode = 1;
|
||||||
|
} else if(!strcmp(argv[3],"bi2a-sdvx")) {
|
||||||
|
bi2a_mode = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
log_to_writer(log_writer_stdout, NULL);
|
log_to_writer(log_writer_stdout, NULL);
|
||||||
|
|
||||||
struct aciodrv_device_ctx *device =
|
struct aciodrv_device_ctx *device =
|
||||||
@@ -93,7 +124,8 @@ int main(int argc, char **argv)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Opening acio device successful\n");
|
printf("Opening acio device successful, press ENTER to continue\n");
|
||||||
|
getchar();
|
||||||
|
|
||||||
uint8_t node_count = aciodrv_device_get_node_count(device);
|
uint8_t node_count = aciodrv_device_get_node_count(device);
|
||||||
printf("Enumerated %d nodes\n", node_count);
|
printf("Enumerated %d nodes\n", node_count);
|
||||||
|
|||||||
@@ -49,11 +49,13 @@ static INT_PTR analog_ui_handle_init(HWND hwnd, struct analog_def *def);
|
|||||||
static void analog_ui_handle_init_label(HWND hwnd);
|
static void analog_ui_handle_init_label(HWND hwnd);
|
||||||
static void analog_ui_handle_init_dev(HWND hwnd);
|
static void analog_ui_handle_init_dev(HWND hwnd);
|
||||||
static void analog_ui_handle_init_sensitivity(HWND hwnd);
|
static void analog_ui_handle_init_sensitivity(HWND hwnd);
|
||||||
|
static void analog_ui_handle_init_invert(HWND hwnd);
|
||||||
static bool analog_ui_match_device(struct hid_stub *hid);
|
static bool analog_ui_match_device(struct hid_stub *hid);
|
||||||
static void analog_ui_populate_controls(HWND hwnd);
|
static void analog_ui_populate_controls(HWND hwnd);
|
||||||
static INT_PTR analog_ui_handle_device_change(HWND hwnd);
|
static INT_PTR analog_ui_handle_device_change(HWND hwnd);
|
||||||
static INT_PTR analog_ui_handle_control_change(HWND hwnd);
|
static INT_PTR analog_ui_handle_control_change(HWND hwnd);
|
||||||
static INT_PTR analog_ui_handle_sensitivity_change(HWND hwnd);
|
static INT_PTR analog_ui_handle_sensitivity_change(HWND hwnd);
|
||||||
|
static INT_PTR analog_ui_handle_invert_change(HWND hwnd);
|
||||||
static INT_PTR analog_ui_handle_tick(HWND hwnd);
|
static INT_PTR analog_ui_handle_tick(HWND hwnd);
|
||||||
static INT_PTR analog_ui_handle_fini(HWND hwnd);
|
static INT_PTR analog_ui_handle_fini(HWND hwnd);
|
||||||
|
|
||||||
@@ -213,6 +215,15 @@ analog_ui_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case BN_CLICKED:
|
||||||
|
switch (LOWORD(wparam)) {
|
||||||
|
case IDC_ANALOG_INVERT:
|
||||||
|
return analog_ui_handle_invert_change(hwnd);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -248,6 +259,7 @@ static INT_PTR analog_ui_handle_init(HWND hwnd, struct analog_def *def)
|
|||||||
analog_ui_handle_init_label(hwnd);
|
analog_ui_handle_init_label(hwnd);
|
||||||
analog_ui_handle_init_dev(hwnd);
|
analog_ui_handle_init_dev(hwnd);
|
||||||
analog_ui_handle_init_sensitivity(hwnd);
|
analog_ui_handle_init_sensitivity(hwnd);
|
||||||
|
analog_ui_handle_init_invert(hwnd);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -343,6 +355,17 @@ static void analog_ui_handle_init_sensitivity(HWND hwnd)
|
|||||||
EnableWindow(slider, !mapper_is_analog_absolute(ui->def->tag));
|
EnableWindow(slider, !mapper_is_analog_absolute(ui->def->tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void analog_ui_handle_init_invert(HWND hwnd)
|
||||||
|
{
|
||||||
|
struct analog_ui *ui;
|
||||||
|
|
||||||
|
ui = (struct analog_ui *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||||
|
|
||||||
|
if (mapper_get_analog_invert(ui->def->tag)) {
|
||||||
|
SendMessage(GetDlgItem(hwnd, IDC_ANALOG_INVERT), BM_SETCHECK, BST_CHECKED, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool analog_ui_match_device(struct hid_stub *hid)
|
static bool analog_ui_match_device(struct hid_stub *hid)
|
||||||
{
|
{
|
||||||
struct hid_control *controls;
|
struct hid_control *controls;
|
||||||
@@ -519,6 +542,21 @@ static INT_PTR analog_ui_handle_sensitivity_change(HWND hwnd)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static INT_PTR analog_ui_handle_invert_change(HWND hwnd)
|
||||||
|
{
|
||||||
|
struct analog_ui *ui;
|
||||||
|
HWND btn;
|
||||||
|
bool invert;
|
||||||
|
|
||||||
|
ui = (struct analog_ui *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||||
|
btn = GetDlgItem(hwnd, IDC_ANALOG_INVERT);
|
||||||
|
invert = SendMessage(btn, BM_GETCHECK, 0, 0) == BST_CHECKED;
|
||||||
|
|
||||||
|
mapper_set_analog_invert(ui->def->tag, invert);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static INT_PTR analog_ui_handle_tick(HWND hwnd)
|
static INT_PTR analog_ui_handle_tick(HWND hwnd)
|
||||||
{
|
{
|
||||||
struct analog_ui *ui;
|
struct analog_ui *ui;
|
||||||
|
|||||||
@@ -22,18 +22,19 @@ IDR_USAGES USAGES "config/usages.txt"
|
|||||||
// Dialog resources
|
// Dialog resources
|
||||||
//
|
//
|
||||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
IDD_ANALOG DIALOG 0, 0, 220, 100
|
IDD_ANALOG DIALOG 0, 0, 220, 115
|
||||||
STYLE DS_3DLOOK | DS_CENTER | DS_SHELLFONT | WS_VISIBLE | WS_CHILDWINDOW
|
STYLE DS_3DLOOK | DS_CENTER | DS_SHELLFONT | WS_VISIBLE | WS_CHILDWINDOW
|
||||||
EXSTYLE WS_EX_CONTROLPARENT
|
EXSTYLE WS_EX_CONTROLPARENT
|
||||||
FONT 8, "Ms Shell Dlg"
|
FONT 8, "Ms Shell Dlg"
|
||||||
{
|
{
|
||||||
GROUPBOX "", IDC_GROUP, 5, 5, 210, 90
|
GROUPBOX "", IDC_GROUP, 5, 5, 210, 105
|
||||||
CONTROL "", IDC_SENSITIVITY, TRACKBAR_CLASS, WS_TABSTOP | TBS_AUTOTICKS, 10, 75, 200, 15
|
CONTROL "", IDC_SENSITIVITY, TRACKBAR_CLASS, WS_TABSTOP | TBS_AUTOTICKS, 10, 75, 200, 15
|
||||||
LTEXT "Device", IDC_STATIC, 15, 15, 24, 8, SS_LEFT
|
LTEXT "Device", IDC_STATIC, 15, 15, 24, 8, SS_LEFT
|
||||||
COMBOBOX IDC_DEVICE, 15, 25, 135, 30, WS_GROUP | WS_TABSTOP | CBS_DROPDOWNLIST | CBS_HASSTRINGS
|
COMBOBOX IDC_DEVICE, 15, 25, 135, 30, WS_GROUP | WS_TABSTOP | CBS_DROPDOWNLIST | CBS_HASSTRINGS
|
||||||
COMBOBOX IDC_CONTROL, 15, 50, 135, 30, WS_TABSTOP | CBS_DROPDOWNLIST | CBS_HASSTRINGS
|
COMBOBOX IDC_CONTROL, 15, 50, 135, 30, WS_TABSTOP | CBS_DROPDOWNLIST | CBS_HASSTRINGS
|
||||||
LTEXT "Sensitivity", IDC_STATIC, 15, 65, 32, 8, SS_LEFT
|
LTEXT "Sensitivity", IDC_STATIC, 15, 65, 32, 8, SS_LEFT
|
||||||
LTEXT "Control", IDC_STATIC, 15, 40, 23, 8, SS_LEFT
|
LTEXT "Control", IDC_STATIC, 15, 40, 23, 8, SS_LEFT
|
||||||
|
AUTOCHECKBOX "Invert Axis", IDC_ANALOG_INVERT, 15, 95, 141, 8
|
||||||
CONTROL "", IDC_POSITION, "spinner", 0x50020000, 160, 15, 50, 50, 0x02002000
|
CONTROL "", IDC_POSITION, "spinner", 0x50020000, 160, 15, 50, 50, 0x02002000
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +127,7 @@ FONT 8, "Ms Shell Dlg"
|
|||||||
|
|
||||||
|
|
||||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
IDD_TAB_ANALOGS DIALOG 0, 0, 220, 215
|
IDD_TAB_ANALOGS DIALOG 0, 0, 220, 230
|
||||||
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
|
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
|
||||||
CAPTION "Analogs"
|
CAPTION "Analogs"
|
||||||
FONT 8, "Ms Shell Dlg"
|
FONT 8, "Ms Shell Dlg"
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#define IDC_DEVICE 1005
|
#define IDC_DEVICE 1005
|
||||||
#define IDC_BINDING_EDIT 1006
|
#define IDC_BINDING_EDIT 1006
|
||||||
#define IDC_CONTROL 1006
|
#define IDC_CONTROL 1006
|
||||||
|
#define IDC_ANALOG_INVERT 1007
|
||||||
#define IDC_BINDING_CLEAR 1007
|
#define IDC_BINDING_CLEAR 1007
|
||||||
#define IDC_BINDING_MIN 1008
|
#define IDC_BINDING_MIN 1008
|
||||||
#define IDC_PAGE_TEXT 1008
|
#define IDC_PAGE_TEXT 1008
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
dlls += ddrio-async
|
||||||
|
|
||||||
|
ldflags_ddrio-async:= \
|
||||||
|
|
||||||
|
libs_ddrio-async := \
|
||||||
|
util \
|
||||||
|
|
||||||
|
src_ddrio-async := \
|
||||||
|
ddrio.c \
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
LIBRARY ddrio-async
|
||||||
|
|
||||||
|
EXPORTS
|
||||||
|
ddr_io_set_loggers
|
||||||
|
ddr_io_fini
|
||||||
|
ddr_io_init
|
||||||
|
ddr_io_read_pad
|
||||||
|
ddr_io_set_lights_extio
|
||||||
|
ddr_io_set_lights_p3io
|
||||||
|
ddr_io_set_lights_hdxs_panel
|
||||||
|
ddr_io_set_lights_hdxs_rgb
|
||||||
@@ -0,0 +1,268 @@
|
|||||||
|
#define LOG_MODULE "ddrio-async"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <stdatomic.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "bemanitools/ddrio.h"
|
||||||
|
|
||||||
|
#include "util/log.h"
|
||||||
|
#include "util/thread.h"
|
||||||
|
#include "util/time.h"
|
||||||
|
|
||||||
|
typedef void (*ddr_io_set_loggers_t)(
|
||||||
|
log_formatter_t misc,
|
||||||
|
log_formatter_t info,
|
||||||
|
log_formatter_t warning,
|
||||||
|
log_formatter_t fatal);
|
||||||
|
typedef bool (*ddr_io_init_t)(
|
||||||
|
thread_create_t thread_create,
|
||||||
|
thread_join_t thread_join,
|
||||||
|
thread_destroy_t thread_destroy);
|
||||||
|
typedef uint32_t (*ddr_io_read_pad_t)(void);
|
||||||
|
typedef void (*ddr_io_set_lights_extio_t)(uint32_t extio_lights);
|
||||||
|
typedef void (*ddr_io_set_lights_p3io_t)(uint32_t p3io_lights);
|
||||||
|
typedef void (*ddr_io_set_lights_hdxs_panel_t)(uint32_t hdxs_lights);
|
||||||
|
typedef void (*ddr_io_set_lights_hdxs_rgb_t)(uint8_t idx, uint8_t r, uint8_t g, uint8_t b);
|
||||||
|
typedef void (*ddr_io_fini_t)(void);
|
||||||
|
|
||||||
|
static HMODULE _child_ddr_io_module;
|
||||||
|
|
||||||
|
static ddr_io_set_loggers_t _child_ddr_io_set_loggers;
|
||||||
|
static ddr_io_init_t _child_ddr_io_init;
|
||||||
|
static ddr_io_read_pad_t _child_ddr_io_read_pad;
|
||||||
|
static ddr_io_set_lights_extio_t _child_ddr_io_set_lights_extio;
|
||||||
|
static ddr_io_set_lights_p3io_t _child_ddr_io_set_lights_p3io;
|
||||||
|
static ddr_io_set_lights_hdxs_panel_t _child_ddr_io_set_lights_hdxs_panel;
|
||||||
|
static ddr_io_set_lights_hdxs_rgb_t _child_ddr_io_set_lights_hdxs_rgb;
|
||||||
|
static ddr_io_fini_t _child_ddr_io_fini;
|
||||||
|
|
||||||
|
static log_formatter_t _log_formatter_misc;
|
||||||
|
static log_formatter_t _log_formatter_info;
|
||||||
|
static log_formatter_t _log_formatter_warning;
|
||||||
|
static log_formatter_t _log_formatter_fatal;
|
||||||
|
|
||||||
|
static _Atomic(bool) _io_thread_proc_loop;
|
||||||
|
static _Atomic(bool) _io_thread_proc_running;
|
||||||
|
|
||||||
|
static _Atomic(uint32_t) _child_ddr_io_data_pad;
|
||||||
|
static _Atomic(uint32_t) _child_ddr_io_data_extio_lights;
|
||||||
|
static _Atomic(uint32_t) _child_ddr_io_data_p3io_lights;
|
||||||
|
|
||||||
|
static int _io_thread_proc(void *ctx)
|
||||||
|
{
|
||||||
|
uint64_t time_start;
|
||||||
|
uint64_t time_end;
|
||||||
|
uint64_t loop_counter;
|
||||||
|
uint64_t total_time;
|
||||||
|
|
||||||
|
uint32_t prev_child_ddr_io_data_extio_lights;
|
||||||
|
uint32_t prev_child_ddr_io_data_p3io_lights;
|
||||||
|
|
||||||
|
uint32_t local_tmp;
|
||||||
|
|
||||||
|
atomic_store_explicit(
|
||||||
|
&_io_thread_proc_running,
|
||||||
|
true,
|
||||||
|
memory_order_seq_cst);
|
||||||
|
|
||||||
|
log_info("IO thread running");
|
||||||
|
|
||||||
|
prev_child_ddr_io_data_extio_lights = atomic_load_explicit(
|
||||||
|
&_child_ddr_io_data_extio_lights, memory_order_seq_cst);
|
||||||
|
prev_child_ddr_io_data_p3io_lights = atomic_load_explicit(
|
||||||
|
&_child_ddr_io_data_p3io_lights, memory_order_seq_cst);
|
||||||
|
|
||||||
|
time_start = time_get_counter();
|
||||||
|
loop_counter = 0;
|
||||||
|
|
||||||
|
while (atomic_load_explicit(&_io_thread_proc_loop, memory_order_seq_cst)) {
|
||||||
|
local_tmp = _child_ddr_io_read_pad();
|
||||||
|
|
||||||
|
atomic_store_explicit(
|
||||||
|
&_child_ddr_io_data_pad,
|
||||||
|
local_tmp,
|
||||||
|
memory_order_relaxed);
|
||||||
|
|
||||||
|
// Only update outputs when they change gives this loop a major performance boost
|
||||||
|
// The write calls on a p3io for the outputs are very expensive (~12 ms) as they
|
||||||
|
// are executed over the ACIO protocol compared to only the input read
|
||||||
|
// calls (~4 ms) which have a dedicated IOCTL call/endpoint
|
||||||
|
|
||||||
|
local_tmp = atomic_load_explicit(
|
||||||
|
&_child_ddr_io_data_extio_lights,
|
||||||
|
memory_order_relaxed);
|
||||||
|
|
||||||
|
if (local_tmp != prev_child_ddr_io_data_extio_lights) {
|
||||||
|
_child_ddr_io_set_lights_extio(local_tmp);
|
||||||
|
prev_child_ddr_io_data_extio_lights = local_tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
local_tmp = atomic_load_explicit(
|
||||||
|
&_child_ddr_io_data_p3io_lights,
|
||||||
|
memory_order_relaxed);
|
||||||
|
|
||||||
|
if (local_tmp != prev_child_ddr_io_data_p3io_lights) {
|
||||||
|
_child_ddr_io_set_lights_p3io(local_tmp);
|
||||||
|
prev_child_ddr_io_data_p3io_lights = local_tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't hog the CPU
|
||||||
|
SwitchToThread();
|
||||||
|
|
||||||
|
loop_counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_end = time_get_counter();
|
||||||
|
total_time = time_get_elapsed_us(time_end - time_start);
|
||||||
|
|
||||||
|
log_info("IO thread performance: total iterations %lld, avg. loop cycle time %f us",
|
||||||
|
loop_counter, ((double) total_time) / loop_counter);
|
||||||
|
|
||||||
|
atomic_store_explicit(
|
||||||
|
&_io_thread_proc_running,
|
||||||
|
false,
|
||||||
|
memory_order_seq_cst);
|
||||||
|
|
||||||
|
log_info("IO thread shut down");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void* _load_function(HMODULE module, const char* name)
|
||||||
|
{
|
||||||
|
void* ptr;
|
||||||
|
|
||||||
|
ptr = GetProcAddress(module, name);
|
||||||
|
|
||||||
|
if (ptr == NULL) {
|
||||||
|
log_fatal("Could not find function %s in ddr3io child library", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ddr_io_set_loggers(
|
||||||
|
log_formatter_t misc,
|
||||||
|
log_formatter_t info,
|
||||||
|
log_formatter_t warning,
|
||||||
|
log_formatter_t fatal)
|
||||||
|
{
|
||||||
|
_log_formatter_misc = misc;
|
||||||
|
_log_formatter_info = info;
|
||||||
|
_log_formatter_warning = warning;
|
||||||
|
_log_formatter_fatal = fatal;
|
||||||
|
|
||||||
|
log_to_external(misc, info, warning, fatal);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ddr_io_init(
|
||||||
|
thread_create_t thread_create,
|
||||||
|
thread_join_t thread_join,
|
||||||
|
thread_destroy_t thread_destroy)
|
||||||
|
{
|
||||||
|
log_info("Loading ddrio-async-child.dll as child ddrio library...");
|
||||||
|
|
||||||
|
_child_ddr_io_module = LoadLibraryA("ddrio-async-child.dll");
|
||||||
|
|
||||||
|
if (_child_ddr_io_module == NULL) {
|
||||||
|
log_warning("Loading ddrio-async-child.dll failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_child_ddr_io_set_loggers = _load_function(_child_ddr_io_module, "ddr_io_set_loggers");
|
||||||
|
_child_ddr_io_init = _load_function(_child_ddr_io_module, "ddr_io_init");
|
||||||
|
_child_ddr_io_read_pad = _load_function(_child_ddr_io_module, "ddr_io_read_pad");
|
||||||
|
_child_ddr_io_set_lights_extio = _load_function(_child_ddr_io_module, "ddr_io_set_lights_extio");
|
||||||
|
_child_ddr_io_set_lights_p3io = _load_function(_child_ddr_io_module, "ddr_io_set_lights_p3io");
|
||||||
|
_child_ddr_io_set_lights_hdxs_panel = _load_function(_child_ddr_io_module, "ddr_io_set_lights_hdxs_panel");
|
||||||
|
_child_ddr_io_set_lights_hdxs_rgb = _load_function(_child_ddr_io_module, "ddr_io_set_lights_hdxs_rgb");
|
||||||
|
_child_ddr_io_fini = _load_function(_child_ddr_io_module, "ddr_io_fini");
|
||||||
|
|
||||||
|
_child_ddr_io_set_loggers(
|
||||||
|
_log_formatter_misc,
|
||||||
|
_log_formatter_info,
|
||||||
|
_log_formatter_warning,
|
||||||
|
_log_formatter_fatal);
|
||||||
|
|
||||||
|
log_info("Calling child ddr_io_init...");
|
||||||
|
|
||||||
|
if (!_child_ddr_io_init(thread_create, thread_join, thread_destroy)) {
|
||||||
|
log_warning("Child ddr_io_init failed");
|
||||||
|
FreeLibrary(_child_ddr_io_module);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic_store_explicit(
|
||||||
|
&_io_thread_proc_loop,
|
||||||
|
true,
|
||||||
|
memory_order_seq_cst);
|
||||||
|
|
||||||
|
if (!thread_create(_io_thread_proc, NULL, 16384, 0)) {
|
||||||
|
log_warning("Creating IO thread failed");
|
||||||
|
|
||||||
|
_child_ddr_io_fini();
|
||||||
|
FreeLibrary(_child_ddr_io_module);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ddr_io_read_pad(void)
|
||||||
|
{
|
||||||
|
return atomic_load_explicit(&_child_ddr_io_data_pad, memory_order_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ddr_io_set_lights_extio(uint32_t extio_lights)
|
||||||
|
{
|
||||||
|
atomic_store_explicit(
|
||||||
|
&_child_ddr_io_data_extio_lights,
|
||||||
|
extio_lights,
|
||||||
|
memory_order_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ddr_io_set_lights_p3io(uint32_t p3io_lights)
|
||||||
|
{
|
||||||
|
atomic_store_explicit(
|
||||||
|
&_child_ddr_io_data_p3io_lights,
|
||||||
|
p3io_lights,
|
||||||
|
memory_order_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ddr_io_set_lights_hdxs_panel(uint32_t lights)
|
||||||
|
{
|
||||||
|
// Not implemented for now
|
||||||
|
}
|
||||||
|
|
||||||
|
void ddr_io_set_lights_hdxs_rgb(uint8_t idx, uint8_t r, uint8_t g, uint8_t b)
|
||||||
|
{
|
||||||
|
// Not implemented for now
|
||||||
|
}
|
||||||
|
|
||||||
|
void ddr_io_fini(void)
|
||||||
|
{
|
||||||
|
atomic_store_explicit(
|
||||||
|
&_io_thread_proc_loop,
|
||||||
|
false,
|
||||||
|
memory_order_seq_cst);
|
||||||
|
|
||||||
|
log_info("Shutting down IO thread and waiting for it to finish...");
|
||||||
|
|
||||||
|
while (atomic_load_explicit(&_io_thread_proc_running, memory_order_seq_cst)) {
|
||||||
|
Sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info("IO thread finished");
|
||||||
|
|
||||||
|
_child_ddr_io_fini();
|
||||||
|
|
||||||
|
FreeLibrary(_child_ddr_io_module);
|
||||||
|
}
|
||||||
@@ -20,7 +20,7 @@ void dev_list_init(struct dev_list *devs, const GUID *class_guid)
|
|||||||
devs->infolist = SetupDiGetClassDevs(
|
devs->infolist = SetupDiGetClassDevs(
|
||||||
devs->class_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
devs->class_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||||
|
|
||||||
if (devs->infolist == NULL) {
|
if (devs->infolist == INVALID_HANDLE_VALUE) {
|
||||||
log_fatal(
|
log_fatal(
|
||||||
"SetupDiGetClassDevs failed: %08x", (unsigned int) GetLastError());
|
"SetupDiGetClassDevs failed: %08x", (unsigned int) GetLastError());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ EXPORTS
|
|||||||
mapper_get_action_map
|
mapper_get_action_map
|
||||||
mapper_get_analog_map
|
mapper_get_analog_map
|
||||||
mapper_get_analog_sensitivity
|
mapper_get_analog_sensitivity
|
||||||
|
mapper_get_analog_invert
|
||||||
mapper_get_npages
|
mapper_get_npages
|
||||||
mapper_get_nanalogs
|
mapper_get_nanalogs
|
||||||
mapper_get_nlights
|
mapper_get_nlights
|
||||||
@@ -44,6 +45,7 @@ EXPORTS
|
|||||||
mapper_set_action_map
|
mapper_set_action_map
|
||||||
mapper_set_analog_map
|
mapper_set_analog_map
|
||||||
mapper_set_analog_sensitivity
|
mapper_set_analog_sensitivity
|
||||||
|
mapper_set_analog_invert
|
||||||
mapper_set_light_map
|
mapper_set_light_map
|
||||||
mapper_set_nanalogs
|
mapper_set_nanalogs
|
||||||
mapper_set_nlights
|
mapper_set_nlights
|
||||||
|
|||||||
@@ -48,7 +48,12 @@ arrays_fail:
|
|||||||
hid_meta_out_fini_caps(meta);
|
hid_meta_out_fini_caps(meta);
|
||||||
|
|
||||||
caps_fail:
|
caps_fail:
|
||||||
return false;
|
/**
|
||||||
|
* Still allow the device to be used as input.
|
||||||
|
* Useful for devices like the Sony DUALSHOCK 4, where it indicates it can receive outputs
|
||||||
|
* but it errors out when trying to initialize an output report.
|
||||||
|
*/
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@@ -99,9 +104,11 @@ hid_meta_out_init_caps(struct hid_meta_out *meta, PHIDP_PREPARSED_DATA ppd)
|
|||||||
|
|
||||||
caps_val_fail:
|
caps_val_fail:
|
||||||
free(meta->caps_val);
|
free(meta->caps_val);
|
||||||
|
meta->caps_val = NULL;
|
||||||
|
|
||||||
caps_btn_fail:
|
caps_btn_fail:
|
||||||
free(meta->caps_btn);
|
free(meta->caps_btn);
|
||||||
|
meta->caps_btn = NULL;
|
||||||
|
|
||||||
caps_tlc_fail:
|
caps_tlc_fail:
|
||||||
return false;
|
return false;
|
||||||
@@ -114,7 +121,6 @@ static bool hid_meta_out_init_arrays(struct hid_meta_out *meta)
|
|||||||
bool *report_presence;
|
bool *report_presence;
|
||||||
unsigned int nreports;
|
unsigned int nreports;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
uint8_t *bytes;
|
|
||||||
size_t nbytes;
|
size_t nbytes;
|
||||||
size_t count;
|
size_t count;
|
||||||
|
|
||||||
@@ -174,7 +180,6 @@ static bool hid_meta_out_init_arrays(struct hid_meta_out *meta)
|
|||||||
for (i = 0; i < 0x100; i++) {
|
for (i = 0; i < 0x100; i++) {
|
||||||
if (report_presence[i]) {
|
if (report_presence[i]) {
|
||||||
nbytes = meta->caps_tlc.OutputReportByteLength;
|
nbytes = meta->caps_tlc.OutputReportByteLength;
|
||||||
bytes = xmalloc(meta->caps_tlc.OutputReportByteLength);
|
|
||||||
|
|
||||||
if (!hid_report_out_init(
|
if (!hid_report_out_init(
|
||||||
&meta->reports[meta->nreports],
|
&meta->reports[meta->nreports],
|
||||||
@@ -198,14 +203,22 @@ static bool hid_meta_out_init_arrays(struct hid_meta_out *meta)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
r_init_fail:
|
r_init_fail:
|
||||||
free(bytes);
|
|
||||||
|
|
||||||
for (i = meta->nreports; i > 0; i--) {
|
for (i = meta->nreports; i > 0; i--) {
|
||||||
hid_report_out_fini(&meta->reports[i - 1]);
|
hid_report_out_fini(&meta->reports[i - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(report_presence);
|
free(report_presence);
|
||||||
|
|
||||||
|
// Clear out all output/light data
|
||||||
|
meta->nreports = 0;
|
||||||
free(meta->reports);
|
free(meta->reports);
|
||||||
|
meta->reports = NULL;
|
||||||
|
|
||||||
|
meta->nlights = 0;
|
||||||
|
meta->nbuttons = 0;
|
||||||
|
// Failed out before allocating memory
|
||||||
|
meta->lights = NULL;
|
||||||
|
meta->priv_lights = NULL;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -433,5 +446,8 @@ static void hid_meta_out_fini_arrays(struct hid_meta_out *meta)
|
|||||||
static void hid_meta_out_fini_caps(struct hid_meta_out *meta)
|
static void hid_meta_out_fini_caps(struct hid_meta_out *meta)
|
||||||
{
|
{
|
||||||
free(meta->caps_btn);
|
free(meta->caps_btn);
|
||||||
|
meta->caps_btn = NULL;
|
||||||
|
|
||||||
free(meta->caps_val);
|
free(meta->caps_val);
|
||||||
|
meta->caps_val = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ bool mapper_get_action_map(
|
|||||||
uint8_t action, uint8_t page, struct mapped_action *ma);
|
uint8_t action, uint8_t page, struct mapped_action *ma);
|
||||||
bool mapper_get_analog_map(uint8_t analog, struct mapped_analog *ma);
|
bool mapper_get_analog_map(uint8_t analog, struct mapped_analog *ma);
|
||||||
int32_t mapper_get_analog_sensitivity(uint8_t analog);
|
int32_t mapper_get_analog_sensitivity(uint8_t analog);
|
||||||
|
bool mapper_get_analog_invert(uint8_t analog);
|
||||||
uint8_t mapper_get_nanalogs(void);
|
uint8_t mapper_get_nanalogs(void);
|
||||||
uint8_t mapper_get_nlights(void);
|
uint8_t mapper_get_nlights(void);
|
||||||
uint8_t mapper_get_npages(void);
|
uint8_t mapper_get_npages(void);
|
||||||
@@ -25,6 +26,7 @@ void mapper_set_action_map(
|
|||||||
uint8_t action, uint8_t page, uint8_t bit, const struct mapped_action *ma);
|
uint8_t action, uint8_t page, uint8_t bit, const struct mapped_action *ma);
|
||||||
bool mapper_set_analog_map(uint8_t analog, const struct mapped_analog *ma);
|
bool mapper_set_analog_map(uint8_t analog, const struct mapped_analog *ma);
|
||||||
bool mapper_set_analog_sensitivity(uint8_t analog, int32_t sensitivity);
|
bool mapper_set_analog_sensitivity(uint8_t analog, int32_t sensitivity);
|
||||||
|
bool mapper_set_analog_invert(uint8_t analog, bool invert);
|
||||||
void mapper_set_nanalogs(uint8_t nanalogs);
|
void mapper_set_nanalogs(uint8_t nanalogs);
|
||||||
void mapper_set_nlights(uint8_t nlights);
|
void mapper_set_nlights(uint8_t nlights);
|
||||||
void mapper_set_light_map(const struct mapped_light *ml, uint8_t game_light);
|
void mapper_set_light_map(const struct mapped_light *ml, uint8_t game_light);
|
||||||
|
|||||||
@@ -25,10 +25,20 @@ static volatile long input_init_count;
|
|||||||
static FILE *mapper_config_open(const char *game_type, const char *mode)
|
static FILE *mapper_config_open(const char *game_type, const char *mode)
|
||||||
{
|
{
|
||||||
char path[MAX_PATH];
|
char path[MAX_PATH];
|
||||||
|
FILE *f;
|
||||||
|
|
||||||
str_format(path, sizeof(path), "%s_v5_00a07.bin", game_type);
|
str_format(path, sizeof(path), "%s.bin", game_type);
|
||||||
|
f = fopen_appdata("DJHACKERS", path, mode);
|
||||||
|
|
||||||
return fopen_appdata("DJHACKERS", path, mode);
|
// Try to load the old save file only if we're loading
|
||||||
|
if (f == NULL) {
|
||||||
|
if (strchr(mode, 'r') != NULL) {
|
||||||
|
str_format(path, sizeof(path), "%s_v5_00a07.bin", game_type);
|
||||||
|
f = fopen_appdata("DJHACKERS", path, mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void input_set_loggers(
|
void input_set_loggers(
|
||||||
@@ -144,6 +154,11 @@ int32_t mapper_get_analog_sensitivity(uint8_t analog)
|
|||||||
return mapper_impl_get_analog_sensitivity(mapper_inst, analog);
|
return mapper_impl_get_analog_sensitivity(mapper_inst, analog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mapper_get_analog_invert(uint8_t analog)
|
||||||
|
{
|
||||||
|
return mapper_impl_get_analog_invert(mapper_inst, analog);
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t mapper_get_nanalogs(void)
|
uint8_t mapper_get_nanalogs(void)
|
||||||
{
|
{
|
||||||
return mapper_impl_get_nanalogs(mapper_inst);
|
return mapper_impl_get_nanalogs(mapper_inst);
|
||||||
@@ -190,6 +205,11 @@ bool mapper_set_analog_sensitivity(uint8_t analog, int32_t sensitivity)
|
|||||||
return mapper_impl_set_analog_sensitivity(mapper_inst, analog, sensitivity);
|
return mapper_impl_set_analog_sensitivity(mapper_inst, analog, sensitivity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mapper_set_analog_invert(uint8_t analog, bool invert)
|
||||||
|
{
|
||||||
|
return mapper_impl_set_analog_invert(mapper_inst, analog, invert);
|
||||||
|
}
|
||||||
|
|
||||||
void mapper_set_light_map(const struct mapped_light *ml, uint8_t game_light)
|
void mapper_set_light_map(const struct mapped_light *ml, uint8_t game_light)
|
||||||
{
|
{
|
||||||
mapper_impl_set_light_map(mapper_inst, ml, game_light);
|
mapper_impl_set_light_map(mapper_inst, ml, game_light);
|
||||||
|
|||||||
@@ -6,9 +6,25 @@
|
|||||||
#include "util/fs.h"
|
#include "util/fs.h"
|
||||||
#include "util/mem.h"
|
#include "util/mem.h"
|
||||||
|
|
||||||
static bool mapper_impl_config_load_actions(struct mapper *m, FILE *f);
|
enum mapper_config_version {
|
||||||
static bool mapper_impl_config_load_analogs(struct mapper *m, FILE *f);
|
MAPPER_VERSION_BEFORE_VERSIONING = 0,
|
||||||
static bool mapper_impl_config_load_lights(struct mapper *m, FILE *f);
|
MAPPER_VERSION_INVERT_AXIS,
|
||||||
|
|
||||||
|
// --- Add new versions above this line --- //
|
||||||
|
MAPPER_VERSION_PLUS_ONE,
|
||||||
|
MAPPER_VERSION_LATEST = MAPPER_VERSION_PLUS_ONE - 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FOURCC(a, b, c, d) \
|
||||||
|
((uint32_t) (((d) << 24) | ((c) << 16) | ((b) << 8) | (a)))
|
||||||
|
|
||||||
|
// Bemanitools Mapper Data
|
||||||
|
static const uint32_t mapper_fourcc = FOURCC('B', 'T', 'M', 'D');
|
||||||
|
|
||||||
|
static uint32_t mapper_impl_config_load_version(FILE *f);
|
||||||
|
static bool mapper_impl_config_load_actions(struct mapper *m, FILE *f, uint32_t version);
|
||||||
|
static bool mapper_impl_config_load_analogs(struct mapper *m, FILE *f, uint32_t version);
|
||||||
|
static bool mapper_impl_config_load_lights(struct mapper *m, FILE *f, uint32_t version);
|
||||||
static void mapper_impl_config_save_actions(struct mapper *m, FILE *f);
|
static void mapper_impl_config_save_actions(struct mapper *m, FILE *f);
|
||||||
static void mapper_impl_config_save_analogs(struct mapper *m, FILE *f);
|
static void mapper_impl_config_save_analogs(struct mapper *m, FILE *f);
|
||||||
static void mapper_impl_config_save_lights(struct mapper *m, FILE *f);
|
static void mapper_impl_config_save_lights(struct mapper *m, FILE *f);
|
||||||
@@ -16,14 +32,17 @@ static void mapper_impl_config_save_lights(struct mapper *m, FILE *f);
|
|||||||
struct mapper *mapper_impl_config_load(FILE *f)
|
struct mapper *mapper_impl_config_load(FILE *f)
|
||||||
{
|
{
|
||||||
struct mapper *m;
|
struct mapper *m;
|
||||||
|
uint32_t version = MAPPER_VERSION_BEFORE_VERSIONING;
|
||||||
|
|
||||||
hid_mgr_lock(); /* Need to convert from HID objects to /dev nodes */
|
hid_mgr_lock(); /* Need to convert from HID objects to /dev nodes */
|
||||||
|
|
||||||
|
version = mapper_impl_config_load_version(f);
|
||||||
|
|
||||||
m = mapper_impl_create();
|
m = mapper_impl_create();
|
||||||
|
|
||||||
if (!mapper_impl_config_load_actions(m, f) ||
|
if (!mapper_impl_config_load_actions(m, f, version) ||
|
||||||
!mapper_impl_config_load_analogs(m, f) ||
|
!mapper_impl_config_load_analogs(m, f, version) ||
|
||||||
!mapper_impl_config_load_lights(m, f)) {
|
!mapper_impl_config_load_lights(m, f, version)) {
|
||||||
mapper_impl_destroy(m);
|
mapper_impl_destroy(m);
|
||||||
m = NULL;
|
m = NULL;
|
||||||
}
|
}
|
||||||
@@ -33,7 +52,29 @@ struct mapper *mapper_impl_config_load(FILE *f)
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mapper_impl_config_load_actions(struct mapper *m, FILE *f)
|
static uint32_t mapper_impl_config_load_version(FILE *f)
|
||||||
|
{
|
||||||
|
uint32_t fourcc = 0;
|
||||||
|
uint32_t version = MAPPER_VERSION_BEFORE_VERSIONING;
|
||||||
|
|
||||||
|
if (!read_u32(f, &fourcc)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fourcc == mapper_fourcc) {
|
||||||
|
|
||||||
|
if (!read_u32(f, &version)) {
|
||||||
|
fseek(f, -4, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
fseek(f, -4, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool mapper_impl_config_load_actions(struct mapper *m, FILE *f, uint32_t version)
|
||||||
{
|
{
|
||||||
char *dev_node;
|
char *dev_node;
|
||||||
struct mapped_action ma;
|
struct mapped_action ma;
|
||||||
@@ -69,11 +110,12 @@ static bool mapper_impl_config_load_actions(struct mapper *m, FILE *f)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mapper_impl_config_load_analogs(struct mapper *m, FILE *f)
|
static bool mapper_impl_config_load_analogs(struct mapper *m, FILE *f, uint32_t version)
|
||||||
{
|
{
|
||||||
char *dev_node;
|
char *dev_node;
|
||||||
struct mapped_analog ma;
|
struct mapped_analog ma;
|
||||||
int32_t sensitivity;
|
int32_t sensitivity;
|
||||||
|
bool invert;
|
||||||
uint8_t nanalogs;
|
uint8_t nanalogs;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
@@ -101,8 +143,19 @@ static bool mapper_impl_config_load_analogs(struct mapper *m, FILE *f)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (version >= MAPPER_VERSION_INVERT_AXIS) {
|
||||||
|
|
||||||
|
if (!read_u8(f, &invert)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
invert = false;
|
||||||
|
}
|
||||||
|
|
||||||
mapper_impl_set_analog_map(m, i, &ma);
|
mapper_impl_set_analog_map(m, i, &ma);
|
||||||
mapper_impl_set_analog_sensitivity(m, i, sensitivity);
|
mapper_impl_set_analog_sensitivity(m, i, sensitivity);
|
||||||
|
mapper_impl_set_analog_invert(m, i, invert);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(dev_node);
|
free(dev_node);
|
||||||
@@ -111,7 +164,7 @@ static bool mapper_impl_config_load_analogs(struct mapper *m, FILE *f)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mapper_impl_config_load_lights(struct mapper *m, FILE *f)
|
static bool mapper_impl_config_load_lights(struct mapper *m, FILE *f, uint32_t version)
|
||||||
{
|
{
|
||||||
char *dev_node;
|
char *dev_node;
|
||||||
struct mapped_light ml;
|
struct mapped_light ml;
|
||||||
@@ -156,8 +209,13 @@ static bool mapper_impl_config_load_lights(struct mapper *m, FILE *f)
|
|||||||
|
|
||||||
void mapper_impl_config_save(struct mapper *m, FILE *f)
|
void mapper_impl_config_save(struct mapper *m, FILE *f)
|
||||||
{
|
{
|
||||||
|
const uint32_t mapper_latest_version = MAPPER_VERSION_LATEST;
|
||||||
|
|
||||||
hid_mgr_lock();
|
hid_mgr_lock();
|
||||||
|
|
||||||
|
write_u32(f, &mapper_fourcc);
|
||||||
|
write_u32(f, &mapper_latest_version);
|
||||||
|
|
||||||
mapper_impl_config_save_actions(m, f);
|
mapper_impl_config_save_actions(m, f);
|
||||||
mapper_impl_config_save_analogs(m, f);
|
mapper_impl_config_save_analogs(m, f);
|
||||||
mapper_impl_config_save_lights(m, f);
|
mapper_impl_config_save_lights(m, f);
|
||||||
@@ -211,6 +269,7 @@ static void mapper_impl_config_save_analogs(struct mapper *m, FILE *f)
|
|||||||
{
|
{
|
||||||
struct mapped_analog ma;
|
struct mapped_analog ma;
|
||||||
int32_t sensitivity;
|
int32_t sensitivity;
|
||||||
|
bool invert;
|
||||||
uint8_t nanalogs;
|
uint8_t nanalogs;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
@@ -224,10 +283,12 @@ static void mapper_impl_config_save_analogs(struct mapper *m, FILE *f)
|
|||||||
write_str(f, "");
|
write_str(f, "");
|
||||||
} else {
|
} else {
|
||||||
sensitivity = mapper_impl_get_analog_sensitivity(m, i);
|
sensitivity = mapper_impl_get_analog_sensitivity(m, i);
|
||||||
|
invert = mapper_impl_get_analog_invert(m, i);
|
||||||
|
|
||||||
write_str(f, hid_stub_get_dev_node(ma.hid));
|
write_str(f, hid_stub_get_dev_node(ma.hid));
|
||||||
write_u32(f, &ma.control_no);
|
write_u32(f, &ma.control_no);
|
||||||
write_u32(f, &sensitivity);
|
write_u32(f, &sensitivity);
|
||||||
|
write_u8(f, &invert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ struct analog_mapping {
|
|||||||
bool bound;
|
bool bound;
|
||||||
bool valid;
|
bool valid;
|
||||||
bool absolute;
|
bool absolute;
|
||||||
double affine_scale;
|
bool invert;
|
||||||
double affine_bias;
|
double analog_min;
|
||||||
|
double analog_max;
|
||||||
|
double inv_analog_range;
|
||||||
uint8_t pos;
|
uint8_t pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -169,8 +171,9 @@ static void analog_mapping_bind(struct analog_mapping *am)
|
|||||||
|
|
||||||
ctl = &controls[am->src.control_no];
|
ctl = &controls[am->src.control_no];
|
||||||
|
|
||||||
am->affine_bias = ctl->value_min;
|
am->analog_min = ctl->value_min;
|
||||||
am->affine_scale = ctl->value_max - ctl->value_min;
|
am->analog_max = ctl->value_max;
|
||||||
|
am->inv_analog_range = 1.0 / ((int64_t)ctl->value_max - ctl->value_min);
|
||||||
am->absolute = !(ctl->flags & HID_FLAG_RELATIVE);
|
am->absolute = !(ctl->flags & HID_FLAG_RELATIVE);
|
||||||
am->valid = true;
|
am->valid = true;
|
||||||
|
|
||||||
@@ -187,6 +190,7 @@ static void analog_mapping_update(struct analog_mapping *am)
|
|||||||
{
|
{
|
||||||
double tmp;
|
double tmp;
|
||||||
int32_t value;
|
int32_t value;
|
||||||
|
int8_t delta;
|
||||||
|
|
||||||
if (!am->bound) {
|
if (!am->bound) {
|
||||||
analog_mapping_bind(am);
|
analog_mapping_bind(am);
|
||||||
@@ -201,10 +205,24 @@ static void analog_mapping_update(struct analog_mapping *am)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (am->absolute) {
|
if (am->absolute) {
|
||||||
tmp = (value - am->affine_bias) / am->affine_scale;
|
|
||||||
|
if (am->invert) {
|
||||||
|
tmp = am->analog_max - value;
|
||||||
|
} else {
|
||||||
|
tmp = value - am->analog_min;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale the input value to [0,1] range
|
||||||
|
tmp *= am->inv_analog_range;
|
||||||
am->pos = (uint8_t) ((tmp + 0.5) * 256.0);
|
am->pos = (uint8_t) ((tmp + 0.5) * 256.0);
|
||||||
} else {
|
} else {
|
||||||
am->pos += (int8_t) (value * exp(am->sensitivity / 256.0));
|
delta = (int8_t) (value * exp(am->sensitivity / 256.0));
|
||||||
|
|
||||||
|
if (am->invert) {
|
||||||
|
delta *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
am->pos += delta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,6 +424,15 @@ int32_t mapper_impl_get_analog_sensitivity(struct mapper *m, uint8_t analog)
|
|||||||
return m->analogs[analog].sensitivity;
|
return m->analogs[analog].sensitivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mapper_impl_get_analog_invert(struct mapper* m, uint8_t analog)
|
||||||
|
{
|
||||||
|
if (analog >= m->nanalogs) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m->analogs[analog].invert;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t mapper_impl_get_nanalogs(struct mapper *m)
|
uint8_t mapper_impl_get_nanalogs(struct mapper *m)
|
||||||
{
|
{
|
||||||
return m->nanalogs;
|
return m->nanalogs;
|
||||||
@@ -531,6 +558,18 @@ bool mapper_impl_set_analog_sensitivity(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mapper_impl_set_analog_invert(
|
||||||
|
struct mapper *m, uint8_t analog, bool invert)
|
||||||
|
{
|
||||||
|
if (analog >= m->nanalogs) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m->analogs[analog].invert = invert;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void mapper_impl_set_light_map(
|
void mapper_impl_set_light_map(
|
||||||
struct mapper *m, const struct mapped_light *ml, uint8_t game_light)
|
struct mapper *m, const struct mapped_light *ml, uint8_t game_light)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ bool mapper_impl_get_analog_map(
|
|||||||
bool mapper_impl_get_action_map(
|
bool mapper_impl_get_action_map(
|
||||||
struct mapper *m, uint8_t action, uint8_t page, struct mapped_action *ma);
|
struct mapper *m, uint8_t action, uint8_t page, struct mapped_action *ma);
|
||||||
int32_t mapper_impl_get_analog_sensitivity(struct mapper *m, uint8_t analog);
|
int32_t mapper_impl_get_analog_sensitivity(struct mapper *m, uint8_t analog);
|
||||||
|
bool mapper_impl_get_analog_invert(struct mapper *m, uint8_t analog);
|
||||||
uint8_t mapper_impl_get_nanalogs(struct mapper *m);
|
uint8_t mapper_impl_get_nanalogs(struct mapper *m);
|
||||||
uint8_t mapper_impl_get_nlights(struct mapper *m);
|
uint8_t mapper_impl_get_nlights(struct mapper *m);
|
||||||
uint8_t mapper_impl_get_npages(struct mapper *m);
|
uint8_t mapper_impl_get_npages(struct mapper *m);
|
||||||
@@ -73,6 +74,8 @@ bool mapper_impl_set_analog_map(
|
|||||||
struct mapper *m, uint8_t analog, const struct mapped_analog *ma);
|
struct mapper *m, uint8_t analog, const struct mapped_analog *ma);
|
||||||
bool mapper_impl_set_analog_sensitivity(
|
bool mapper_impl_set_analog_sensitivity(
|
||||||
struct mapper *m, uint8_t analog, int32_t sensitivity);
|
struct mapper *m, uint8_t analog, int32_t sensitivity);
|
||||||
|
bool mapper_impl_set_analog_invert(
|
||||||
|
struct mapper *m, uint8_t analog, bool invert);
|
||||||
void mapper_impl_set_light_map(
|
void mapper_impl_set_light_map(
|
||||||
struct mapper *m, const struct mapped_light *ml, uint8_t game_light);
|
struct mapper *m, const struct mapped_light *ml, uint8_t game_light);
|
||||||
void mapper_impl_set_nanalogs(struct mapper *m, uint8_t nanalogs);
|
void mapper_impl_set_nanalogs(struct mapper *m, uint8_t nanalogs);
|
||||||
|
|||||||
+45
-13
@@ -52,18 +52,18 @@ static const struct hook_symbol jbhook1_log_gftools_hook_syms2[] = {
|
|||||||
.link = (void **) &real_ea3_boot},
|
.link = (void **) &real_ea3_boot},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void avs_boot_replace_property_uint32(
|
static void avs_boot_create_property_str(
|
||||||
struct property_node *node, const char *name, uint32_t val)
|
struct property *config, const char *name, const char *val)
|
||||||
{
|
{
|
||||||
struct property_node *tmp;
|
struct property_node *tmp;
|
||||||
|
|
||||||
tmp = property_search(NULL, node, name);
|
tmp = property_node_create(config, NULL, PROPERTY_TYPE_STR, name, val);
|
||||||
|
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
property_node_remove(tmp);
|
property_node_datasize(tmp);
|
||||||
|
} else {
|
||||||
|
log_fatal("Could not avs_boot_create_prop_str(%s, %s)", name, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
property_node_create(NULL, node, PSMAP_TYPE_U32, name, val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void avs_boot_replace_property_str(
|
static void avs_boot_replace_property_str(
|
||||||
@@ -81,11 +81,13 @@ static void avs_boot_replace_property_str(
|
|||||||
|
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
property_node_datasize(tmp);
|
property_node_datasize(tmp);
|
||||||
|
} else {
|
||||||
|
log_fatal("Could not avs_boot_replace_property_str(%s, %s)", name, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void my_avs_boot(
|
static void my_avs_boot(
|
||||||
struct property_node *config,
|
struct property_node *_config,
|
||||||
void *std_heap,
|
void *std_heap,
|
||||||
size_t sz_std_heap,
|
size_t sz_std_heap,
|
||||||
void *avs_heap,
|
void *avs_heap,
|
||||||
@@ -95,14 +97,44 @@ static void my_avs_boot(
|
|||||||
{
|
{
|
||||||
log_info("Called my_avs_boot");
|
log_info("Called my_avs_boot");
|
||||||
|
|
||||||
avs_boot_replace_property_uint32(config, "log/level", 4);
|
// avshelper gates this behind a check that might not always be true
|
||||||
avs_boot_replace_property_str(
|
CreateDirectoryA("./CONF", 0);
|
||||||
|
CreateDirectoryA("./CONF/NVRAM", 0);
|
||||||
|
CreateDirectoryA("./CONF/RAW", 0);
|
||||||
|
|
||||||
|
// The default config isn't very exciting, and we need to replace the NVRAM
|
||||||
|
// settings with our own anyway. Trying to edit the config almost always
|
||||||
|
// fails because of some weird fragmentation issues causing node insert to
|
||||||
|
// fail, so just recreate the entire thing from scratch.
|
||||||
|
uint8_t cfg_buf[2048];
|
||||||
|
struct property *config = property_create(
|
||||||
|
PROPERTY_FLAG_READ | PROPERTY_FLAG_WRITE | PROPERTY_FLAG_CREATE,
|
||||||
|
cfg_buf,
|
||||||
|
sizeof(cfg_buf));
|
||||||
|
|
||||||
|
log_assert(config);
|
||||||
|
|
||||||
|
property_node_create(
|
||||||
|
config, NULL, PROPERTY_TYPE_U32, "/config/log/level", 4);
|
||||||
|
avs_boot_create_property_str(config, "/config/fs/root/device", ".");
|
||||||
|
avs_boot_create_property_str(config, "/config/fs/raw/device", "./CONF/RAW");
|
||||||
|
avs_boot_create_property_str(
|
||||||
config, "/config/fs/nvram/device", "./CONF/NVRAM");
|
config, "/config/fs/nvram/device", "./CONF/NVRAM");
|
||||||
avs_boot_replace_property_str(
|
avs_boot_create_property_str(config, "/config/fs/nvram/fstype", "fs");
|
||||||
config, "/config/fs/raw/device", "./CONF/RAW");
|
avs_boot_create_property_str(config, "/config/fs/nvram/option", "");
|
||||||
|
property_node_create(
|
||||||
|
config, NULL, PROPERTY_TYPE_U16, "/config/net/nr_protocol", 8);
|
||||||
|
property_node_create(
|
||||||
|
config, NULL, PROPERTY_TYPE_U16, "/config/net/nr_socket", 8);
|
||||||
|
property_node_create(
|
||||||
|
config, NULL, PROPERTY_TYPE_U8, "/config/net/enable_raw", 1);
|
||||||
|
|
||||||
|
struct property_node *config_node =
|
||||||
|
property_search(config, NULL, "/config");
|
||||||
|
log_assert(config_node);
|
||||||
|
|
||||||
real_avs_boot(
|
real_avs_boot(
|
||||||
config,
|
config_node,
|
||||||
std_heap,
|
std_heap,
|
||||||
sz_std_heap,
|
sz_std_heap,
|
||||||
avs_heap,
|
avs_heap,
|
||||||
@@ -168,4 +200,4 @@ void jbhook1_avs_boot_set_eamuse_addr(const struct net_addr *server_addr)
|
|||||||
&jbhook1_avs_boot_eamuse_server_addr,
|
&jbhook1_avs_boot_eamuse_server_addr,
|
||||||
server_addr,
|
server_addr,
|
||||||
sizeof(struct net_addr));
|
sizeof(struct net_addr));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,29 @@ my_mwindow_create(HINSTANCE, void *, const char *, DWORD, DWORD, BOOL);
|
|||||||
static HWND(CDECL *real_mwindow_create)(
|
static HWND(CDECL *real_mwindow_create)(
|
||||||
HINSTANCE, void *, const char *, DWORD, DWORD, BOOL);
|
HINSTANCE, void *, const char *, DWORD, DWORD, BOOL);
|
||||||
|
|
||||||
|
static BOOL STDCALL my_CreateProcessA(
|
||||||
|
LPCSTR lpApplicationName,
|
||||||
|
LPSTR lpCommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
|
BOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPVOID lpEnvironment,
|
||||||
|
LPCSTR lpCurrentDirectory,
|
||||||
|
LPSTARTUPINFOA lpStartupInfo,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation);
|
||||||
|
static BOOL(STDCALL *real_CreateProcessA)(
|
||||||
|
LPCSTR lpApplicationName,
|
||||||
|
LPSTR lpCommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
|
BOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPVOID lpEnvironment,
|
||||||
|
LPCSTR lpCurrentDirectory,
|
||||||
|
LPSTARTUPINFOA lpStartupInfo,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation);
|
||||||
|
|
||||||
static const struct hook_symbol init_hook_syms[] = {
|
static const struct hook_symbol init_hook_syms[] = {
|
||||||
{
|
{
|
||||||
.name = "mwindow_create",
|
.name = "mwindow_create",
|
||||||
@@ -55,6 +78,17 @@ static const struct hook_symbol init_hook_syms[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct hook_symbol kernel32_hook_syms[] = {
|
||||||
|
{
|
||||||
|
.name = "CreateProcessA",
|
||||||
|
.patch = my_CreateProcessA,
|
||||||
|
.link = (void **) &real_CreateProcessA,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// so our CreateProcessA hook can check
|
||||||
|
static bool vertical;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This seems to be a good entry point to intercept before the game calls
|
* This seems to be a good entry point to intercept before the game calls
|
||||||
* anything important (very close to the start of WinMain).
|
* anything important (very close to the start of WinMain).
|
||||||
@@ -107,6 +141,7 @@ static HWND CDECL my_mwindow_create(
|
|||||||
jbhook1_log_gftools_init();
|
jbhook1_log_gftools_init();
|
||||||
|
|
||||||
fullscreen = !config_gfx.windowed;
|
fullscreen = !config_gfx.windowed;
|
||||||
|
vertical = config_gfx.vertical;
|
||||||
|
|
||||||
if (config_gfx.vertical) {
|
if (config_gfx.vertical) {
|
||||||
DWORD tmp = window_width;
|
DWORD tmp = window_width;
|
||||||
@@ -175,9 +210,53 @@ BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
|
|||||||
|
|
||||||
/* Actual hooks for game specific stuff */
|
/* Actual hooks for game specific stuff */
|
||||||
|
|
||||||
|
hook_table_apply(
|
||||||
|
NULL,
|
||||||
|
"kernel32.dll",
|
||||||
|
kernel32_hook_syms,
|
||||||
|
lengthof(kernel32_hook_syms));
|
||||||
|
|
||||||
acp_hook_init();
|
acp_hook_init();
|
||||||
adapter_hook_init();
|
adapter_hook_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BOOL STDCALL my_CreateProcessA(
|
||||||
|
LPCSTR lpApplicationName,
|
||||||
|
LPSTR lpCommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
|
BOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPVOID lpEnvironment,
|
||||||
|
LPCSTR lpCurrentDirectory,
|
||||||
|
LPSTARTUPINFOA lpStartupInfo,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation)
|
||||||
|
{
|
||||||
|
LPSTR rot_arg;
|
||||||
|
|
||||||
|
// de-rotate the error window if needed. In theory this should parse the
|
||||||
|
// commandline properly, in practice this works on all the .exe jubeats.
|
||||||
|
if (vertical && lpCommandLine) {
|
||||||
|
if ((rot_arg = strstr(lpCommandLine, " -R90 "))) { // jubeat 01
|
||||||
|
memcpy(rot_arg, " -R0 ", strlen(" -R0 "));
|
||||||
|
} else if ((rot_arg =
|
||||||
|
strstr(lpCommandLine, " -rot:90 "))) { // jubeat 02
|
||||||
|
memcpy(rot_arg, " -rot:0 ", strlen(" -rot:0 "));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return real_CreateProcessA(
|
||||||
|
lpApplicationName,
|
||||||
|
lpCommandLine,
|
||||||
|
lpProcessAttributes,
|
||||||
|
lpThreadAttributes,
|
||||||
|
bInheritHandles,
|
||||||
|
dwCreationFlags,
|
||||||
|
lpEnvironment,
|
||||||
|
lpCurrentDirectory,
|
||||||
|
lpStartupInfo,
|
||||||
|
lpProcessInformation);
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -57,7 +57,7 @@ static HANDLE mm_open_device(void)
|
|||||||
dev_info = SetupDiGetClassDevsW(
|
dev_info = SetupDiGetClassDevsW(
|
||||||
&hid_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
&hid_guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
|
||||||
|
|
||||||
if (dev_info == NULL) {
|
if (dev_info == INVALID_HANDLE_VALUE) {
|
||||||
log_fatal("SetupDiGetClassDevs failed");
|
log_fatal("SetupDiGetClassDevs failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -41,7 +41,7 @@ void p3io_resp_hdr_init(
|
|||||||
{
|
{
|
||||||
log_assert(resp_hdr != NULL);
|
log_assert(resp_hdr != NULL);
|
||||||
log_assert(req_hdr != NULL);
|
log_assert(req_hdr != NULL);
|
||||||
log_assert(nbytes < P3IO_MAX_MESSAGE_SIZE);
|
log_assert(nbytes <= P3IO_MAX_MESSAGE_SIZE);
|
||||||
|
|
||||||
/* Length byte in this packet format counts everything from the length
|
/* Length byte in this packet format counts everything from the length
|
||||||
byte onwards. The length byte itself occurs at the start of the frame. */
|
byte onwards. The length byte itself occurs at the start of the frame. */
|
||||||
|
|||||||
@@ -161,6 +161,11 @@ struct p3io_req_rs232_write {
|
|||||||
uint8_t bytes[128];
|
uint8_t bytes[128];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct p3io_req_unknown_generic {
|
||||||
|
struct p3io_hdr hdr;
|
||||||
|
uint8_t unknown;
|
||||||
|
};
|
||||||
|
|
||||||
struct p3io_req_raw {
|
struct p3io_req_raw {
|
||||||
uint8_t data[P3IO_MAX_MESSAGE_SIZE];
|
uint8_t data[P3IO_MAX_MESSAGE_SIZE];
|
||||||
};
|
};
|
||||||
@@ -182,6 +187,7 @@ union p3io_req_any {
|
|||||||
struct p3io_req_rs232_open_close rs232_open_close;
|
struct p3io_req_rs232_open_close rs232_open_close;
|
||||||
struct p3io_req_rs232_read rs232_read;
|
struct p3io_req_rs232_read rs232_read;
|
||||||
struct p3io_req_rs232_write rs232_write;
|
struct p3io_req_rs232_write rs232_write;
|
||||||
|
struct p3io_req_unknown_generic unknown_generic;
|
||||||
struct p3io_req_raw raw;
|
struct p3io_req_raw raw;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -266,6 +272,11 @@ struct p3io_resp_rs232_write {
|
|||||||
uint8_t nbytes;
|
uint8_t nbytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct p3io_resp_unknown_generic {
|
||||||
|
struct p3io_hdr hdr;
|
||||||
|
uint8_t unknown;
|
||||||
|
};
|
||||||
|
|
||||||
struct p3io_resp_raw {
|
struct p3io_resp_raw {
|
||||||
uint8_t data[P3IO_MAX_MESSAGE_SIZE];
|
uint8_t data[P3IO_MAX_MESSAGE_SIZE];
|
||||||
};
|
};
|
||||||
@@ -286,6 +297,7 @@ union p3io_resp_any {
|
|||||||
struct p3io_resp_rs232_open_close rs232_open_close;
|
struct p3io_resp_rs232_open_close rs232_open_close;
|
||||||
struct p3io_resp_rs232_read rs232_read;
|
struct p3io_resp_rs232_read rs232_read;
|
||||||
struct p3io_resp_rs232_write rs232_write;
|
struct p3io_resp_rs232_write rs232_write;
|
||||||
|
struct p3io_resp_unknown_generic unknown_generic;
|
||||||
struct p3io_resp_raw raw;
|
struct p3io_resp_raw raw;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+25
-7
@@ -49,6 +49,8 @@ static void p3io_cmd_get_video_freq(
|
|||||||
const struct p3io_req_get_video_freq *req,
|
const struct p3io_req_get_video_freq *req,
|
||||||
struct p3io_resp_get_video_freq *resp);
|
struct p3io_resp_get_video_freq *resp);
|
||||||
static void
|
static void
|
||||||
|
p3io_cmd_unknown_2b(const struct p3io_req_unknown_2b *req, struct p3io_resp_unknown_2b *resp);
|
||||||
|
static void
|
||||||
p3io_cmd_init(const struct p3io_req_init *req, struct p3io_resp_init *resp);
|
p3io_cmd_init(const struct p3io_req_init *req, struct p3io_resp_init *resp);
|
||||||
static void p3io_cmd_get_coinstock(
|
static void p3io_cmd_get_coinstock(
|
||||||
const struct p3io_req_coin_stock *req, struct p3io_resp_coin_stock *resp);
|
const struct p3io_req_coin_stock *req, struct p3io_resp_coin_stock *resp);
|
||||||
@@ -56,7 +58,7 @@ static void p3io_cmd_set_coin_counter(
|
|||||||
const struct p3io_req_set_coin_counter *req,
|
const struct p3io_req_set_coin_counter *req,
|
||||||
struct p3io_resp_set_coin_counter *resp);
|
struct p3io_resp_set_coin_counter *resp);
|
||||||
static void
|
static void
|
||||||
p3io_cmd_unknown(const union p3io_req_any *req, struct p3io_resp_raw *resp);
|
p3io_cmd_unknown(const struct p3io_req_unknown_generic *req, struct p3io_resp_unknown_generic *resp);
|
||||||
|
|
||||||
void p3io_emu_init(const struct p3io_ops *ops, void *ctx)
|
void p3io_emu_init(const struct p3io_ops *ops, void *ctx)
|
||||||
{
|
{
|
||||||
@@ -268,6 +270,11 @@ static HRESULT p3io_cmd_dispatch(const union p3io_req_any *req)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case P3IO_CMD_UNKNOWN_2B:
|
||||||
|
p3io_cmd_unknown_2b(&req->unknown_2b, &resp.unknown_2b);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case P3IO_CMD_INIT:
|
case P3IO_CMD_INIT:
|
||||||
p3io_cmd_init(&req->init, &resp.init);
|
p3io_cmd_init(&req->init, &resp.init);
|
||||||
|
|
||||||
@@ -301,7 +308,7 @@ static HRESULT p3io_cmd_dispatch(const union p3io_req_any *req)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
p3io_cmd_unknown(req, &resp.raw);
|
p3io_cmd_unknown(&req->unknown_generic, &resp.unknown_generic);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -511,6 +518,16 @@ static void p3io_cmd_get_video_freq(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
p3io_cmd_unknown_2b(const struct p3io_req_unknown_2b *req, struct p3io_resp_unknown_2b *resp)
|
||||||
|
{
|
||||||
|
log_misc("Unknown 2b");
|
||||||
|
|
||||||
|
p3io_resp_hdr_init(&resp->hdr, sizeof(*resp), &req->hdr);
|
||||||
|
|
||||||
|
resp->unknown = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
p3io_cmd_init(const struct p3io_req_init *req, struct p3io_resp_init *resp)
|
p3io_cmd_init(const struct p3io_req_init *req, struct p3io_resp_init *resp)
|
||||||
{
|
{
|
||||||
@@ -557,15 +574,16 @@ static void p3io_cmd_set_coin_counter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
p3io_cmd_unknown(const union p3io_req_any *req, struct p3io_resp_raw *resp)
|
p3io_cmd_unknown(const struct p3io_req_unknown_generic *req, struct p3io_resp_unknown_generic *resp)
|
||||||
{
|
{
|
||||||
log_warning("Unsupported P3IO command: %02x", req->hdr.cmd);
|
log_warning("Unsupported P3IO command, sending default response (might not work/crash though): %02x",
|
||||||
|
req->hdr.cmd);
|
||||||
|
|
||||||
p3io_resp_hdr_init(
|
p3io_resp_hdr_init(&resp->hdr, sizeof(*resp), &req->hdr);
|
||||||
(struct p3io_hdr *) &resp->data, sizeof(*resp), &req->hdr);
|
|
||||||
|
|
||||||
// Not always applicable/correct as there are several commands not
|
// Not always applicable/correct as there are several commands not
|
||||||
// responding with any data, but fine for the majority of (unsupported)
|
// responding with any data, but fine for the majority of (unsupported)
|
||||||
// commands
|
// commands
|
||||||
resp->data[sizeof(struct p3io_hdr) + 0] = 0;
|
// Remark: This might also lead to unpredictable behaviour or crashes
|
||||||
|
resp->unknown = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user