mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2026-09-15 11:55:10 -05:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a2c77f255 | ||
|
|
55513bac41 | ||
|
|
9c37ef71ba | ||
|
|
a0a1dea397 | ||
|
|
3c26a3f315 | ||
|
|
b408cd9687 | ||
|
|
be4df516fd | ||
|
|
d1080905e5 | ||
|
|
f87a51bbe4 | ||
|
|
2a4d3e2865 | ||
|
|
6697ff7df1 | ||
|
|
682fe8aa1b | ||
|
|
7d533f60cb | ||
|
|
e5331fbc7c | ||
|
|
77527e346b | ||
|
|
1d0a96fa20 | ||
|
|
63e19aaaf6 | ||
|
|
4c59f16d46 | ||
|
|
7157fdedb7 | ||
|
|
13d29cb62e | ||
|
|
bf48715466 | ||
|
|
24b490e36b |
@@ -1,17 +1,25 @@
|
||||
image: debian
|
||||
image: docker:stable
|
||||
|
||||
variables:
|
||||
DOCKER_TLS_CERTDIR: "/certs"
|
||||
|
||||
services:
|
||||
- docker:19.03.8-dind
|
||||
|
||||
before_script:
|
||||
- docker info
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- release
|
||||
- create-release-package
|
||||
- releasetag
|
||||
|
||||
build:
|
||||
stage: build
|
||||
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:
|
||||
@@ -20,31 +28,17 @@ build:
|
||||
refs:
|
||||
- master
|
||||
|
||||
test:
|
||||
allow_failure: true
|
||||
stage: test
|
||||
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
|
||||
create-release-package:
|
||||
stage: create-release-package
|
||||
variables:
|
||||
GIT_STRATEGY: none
|
||||
dependencies:
|
||||
- build
|
||||
before_script:
|
||||
- apt-get update && apt-get -qq install zip > /dev/null
|
||||
- apk update && apk add zip > /dev/null
|
||||
script:
|
||||
- mv build/bemanitools.zip ./bemanitools.zip
|
||||
- mv build/docker/bemanitools.zip ./bemanitools.zip
|
||||
- rm -r build
|
||||
- find . -mindepth 1 ! -regex '^./bemanitools.zip' -delete
|
||||
- unzip bemanitools.zip
|
||||
- rm bemanitools.zip
|
||||
@@ -55,12 +49,12 @@ release:
|
||||
only:
|
||||
refs:
|
||||
- master
|
||||
|
||||
|
||||
releasetag:
|
||||
stage: releasetag
|
||||
dependencies: []
|
||||
before_script:
|
||||
- apt-get update && apt-get -qq install curl > /dev/null
|
||||
- apk update && apk add curl > /dev/null
|
||||
script:
|
||||
- |
|
||||
curl --silent --show-error \
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
# Release history
|
||||
## 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
|
||||
|
||||
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
|
||||
38
GNUmakefile
38
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
|
||||
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 \
|
||||
@@ -74,6 +80,16 @@ run-tests:
|
||||
version:
|
||||
@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
|
||||
#
|
||||
|
||||
23
Module.mk
23
Module.mk
@@ -183,6 +183,7 @@ $(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-ezusb-exit-hook.dll \
|
||||
@@ -191,10 +192,6 @@ $(zipdir)/tools-x64.zip: \
|
||||
$(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 \
|
||||
@@ -473,6 +470,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 \
|
||||
@@ -525,6 +538,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 \
|
||||
@@ -537,7 +551,6 @@ $(BUILDDIR)/bemanitools.zip: \
|
||||
$(zipdir)/jb-01.zip \
|
||||
$(zipdir)/jb-05-to-07.zip \
|
||||
$(zipdir)/jb-08.zip \
|
||||
$(zipdir)/src.zip \
|
||||
$(zipdir)/sdvx-01-to-04.zip \
|
||||
$(zipdir)/sdvx-05.zip \
|
||||
$(zipdir)/sdvx-05-cn.zip \
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Bemanitools 5
|
||||
[](https://dev.s-ul.eu/djhackers/bemanitools/commits/master)
|
||||
|
||||
Version: 5.30</br>
|
||||
Version: 5.31</br>
|
||||
[Release history](CHANGELOG.md)
|
||||
|
||||
A collection of tools to run [various Bemani arcade games](#list-of-supported-games).
|
||||
@@ -81,6 +81,9 @@ should cover most if not all of the games so far
|
||||
Please refer to the [dedicated documentation](CONTRIBUTING.md).
|
||||
|
||||
# Development
|
||||
## Building
|
||||
See the [development document](doc/development).
|
||||
|
||||
## 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.
|
||||
@@ -88,10 +91,6 @@ important aspects you should know before you get started with development.
|
||||
## 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.
|
||||
|
||||
# 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.
|
||||
|
||||
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.
|
||||
@@ -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.
|
||||
|
||||
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
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "acio/hdxs.h"
|
||||
#include "acio/icca.h"
|
||||
#include "acio/kfca.h"
|
||||
|
||||
@@ -71,6 +72,8 @@ struct ac_io_message {
|
||||
|
||||
struct ac_io_kfca_poll_in kfca_poll_in;
|
||||
struct ac_io_kfca_poll_out kfca_poll_out;
|
||||
|
||||
struct ac_io_hdxs_output hdxs_output;
|
||||
};
|
||||
} cmd;
|
||||
|
||||
|
||||
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
|
||||
@@ -12,6 +12,8 @@ enum ac_io_icca_cmd {
|
||||
AC_IO_ICCA_CMD_SET_SLOT_STATE = 0x0135,
|
||||
AC_IO_ICCA_CMD_BEGIN_KEYPAD = 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 {
|
||||
|
||||
@@ -19,6 +19,7 @@ static char aviodrv_device_node_products[16][4];
|
||||
static bool aciodrv_device_init(void)
|
||||
{
|
||||
uint8_t init_seq[1] = {AC_IO_SOF};
|
||||
uint8_t read_buff[1] = {0x00};
|
||||
|
||||
/* init/reset the device by sending 0xAA until 0xAA is returned */
|
||||
int read = 0;
|
||||
@@ -27,17 +28,20 @@ static bool aciodrv_device_init(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
read = aciodrv_port_read(init_seq, sizeof(init_seq));
|
||||
} while (read == 0);
|
||||
read = aciodrv_port_read(read_buff, sizeof(read_buff));
|
||||
} while ((read <= 0) || (read_buff[0] != init_seq[0]));
|
||||
|
||||
if (read > 0) {
|
||||
log_warning("Obtained SOF, clearing out buffer now");
|
||||
/* empty buffer by reading all data */
|
||||
while (read > 0) {
|
||||
read = aciodrv_port_read(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;
|
||||
}
|
||||
}
|
||||
@@ -314,15 +318,20 @@ bool aciodrv_device_get_node_product_ident(uint8_t node_id, char product[4])
|
||||
bool aciodrv_send_and_recv(struct ac_io_message *msg, int resp_size)
|
||||
{
|
||||
msg->cmd.seq_no = aciodrv_device_msg_counter++;
|
||||
int send_size = offsetof(struct ac_io_message, cmd.raw) + msg->cmd.nbytes;
|
||||
|
||||
if (aciodrv_device_send(
|
||||
(uint8_t *) msg,
|
||||
offsetof(struct ac_io_message, cmd.raw) + msg->cmd.nbytes) <= 0) {
|
||||
#ifdef AC_IO_MSG_LOG
|
||||
log_info("Beginning send on %d: %04x (%d b)", msg->addr, msg->cmd.code, send_size);
|
||||
#endif
|
||||
if (aciodrv_device_send((uint8_t *) msg, send_size) <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t req_code = msg->cmd.code;
|
||||
|
||||
#ifdef AC_IO_MSG_LOG
|
||||
log_info("Beginning recv: (%d b)", resp_size);
|
||||
#endif
|
||||
if (aciodrv_device_receive((uint8_t *) msg, resp_size) <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 {
|
||||
@@ -41,7 +42,8 @@ static void ac_io_emu_icca_cmd_send_version(
|
||||
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 +53,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 +67,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(
|
||||
@@ -123,7 +140,7 @@ void ac_io_emu_icca_dispatch_request(
|
||||
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 +191,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 +203,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 +246,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 +309,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 +368,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 +436,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);
|
||||
|
||||
|
||||
@@ -32,8 +32,7 @@ enum ddr_pad_bit {
|
||||
DDR_P1_MENU_DOWN = 0x01,
|
||||
};
|
||||
|
||||
/* p3io controls menu btn and marquee lights
|
||||
extio controls neons and stage lights. */
|
||||
// see the functions below for more information
|
||||
|
||||
enum p3io_light_bit {
|
||||
LIGHT_P1_MENU = 0x00,
|
||||
@@ -41,7 +40,31 @@ enum p3io_light_bit {
|
||||
LIGHT_P2_LOWER_LAMP = 0x04,
|
||||
LIGHT_P2_UPPER_LAMP = 0x05,
|
||||
LIGHT_P1_LOWER_LAMP = 0x06,
|
||||
LIGHT_P1_UPPER_LAMP = 0x07
|
||||
LIGHT_P1_UPPER_LAMP = 0x07,
|
||||
};
|
||||
|
||||
enum hdxs_light_bit {
|
||||
LIGHT_HD_P1_START = 0x08,
|
||||
LIGHT_HD_P1_UP_DOWN = 0x09,
|
||||
LIGHT_HD_P1_LEFT_RIGHT = 0x0A,
|
||||
LIGHT_HD_P2_START = 0x0B,
|
||||
LIGHT_HD_P2_UP_DOWN = 0x0C,
|
||||
LIGHT_HD_P2_LEFT_RIGHT = 0x0D,
|
||||
};
|
||||
|
||||
enum hdxs_rgb_light_bit {
|
||||
LIGHT_HD_P1_SPEAKER_F_R = 0x20,
|
||||
LIGHT_HD_P1_SPEAKER_F_G = 0x21,
|
||||
LIGHT_HD_P1_SPEAKER_F_B = 0x22,
|
||||
LIGHT_HD_P2_SPEAKER_F_R = 0x23,
|
||||
LIGHT_HD_P2_SPEAKER_F_G = 0x24,
|
||||
LIGHT_HD_P2_SPEAKER_F_B = 0x25,
|
||||
LIGHT_HD_P1_SPEAKER_W_R = 0x26,
|
||||
LIGHT_HD_P1_SPEAKER_W_G = 0x27,
|
||||
LIGHT_HD_P1_SPEAKER_W_B = 0x28,
|
||||
LIGHT_HD_P2_SPEAKER_W_R = 0x29,
|
||||
LIGHT_HD_P2_SPEAKER_W_G = 0x2A,
|
||||
LIGHT_HD_P2_SPEAKER_W_B = 0x2B,
|
||||
};
|
||||
|
||||
enum extio_light_bit {
|
||||
@@ -81,9 +104,26 @@ bool ddr_io_init(
|
||||
thread_join_t thread_join,
|
||||
thread_destroy_t thread_destroy);
|
||||
|
||||
|
||||
/* used to poll the IO for input, note that this is also where lights are
|
||||
flushed to the device for geninput */
|
||||
uint32_t ddr_io_read_pad(void);
|
||||
|
||||
/* The following are optional to implement, and allow lights to be set and
|
||||
emulated as needed */
|
||||
|
||||
/* used to set pad lights, as well as the bass neon on SD cabs */
|
||||
void ddr_io_set_lights_extio(uint32_t extio_lights);
|
||||
|
||||
/* used to set SD panel lights, and HD spot lights */
|
||||
void ddr_io_set_lights_p3io(uint32_t p3io_lights);
|
||||
|
||||
/* used to set HD cab front panel lights */
|
||||
void ddr_io_set_lights_hdxs_panel(uint32_t hdxs_lights);
|
||||
|
||||
/* used to set HD cab speaker RGB lights */
|
||||
void ddr_io_set_lights_hdxs_rgb(uint8_t idx, uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
void ddr_io_fini(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -256,13 +256,33 @@ STRINGTABLE
|
||||
IDS_DDR_P2_DOWN "P2 Down"
|
||||
IDS_DDR_P2_LEFT "P2 Left"
|
||||
IDS_DDR_P2_RIGHT "P2 Right"
|
||||
IDS_DDR_P1_MENU_LIGHT "P1 Menu Lights"
|
||||
IDS_DDR_P1_MENU_LIGHT "P1 Menu Lights / HD Spot Red Satellite"
|
||||
IDS_DDR_P1_TOP_LIGHT "P1 Marquee Top Light"
|
||||
IDS_DDR_P1_BOTTOM_LIGHT "P1 Marquee Bottom Light"
|
||||
IDS_DDR_P2_MENU_LIGHT "P2 Menu Lights"
|
||||
IDS_DDR_P2_MENU_LIGHT "P2 Menu Lights / HD Spot Blue Satellite"
|
||||
IDS_DDR_P2_TOP_LIGHT "P2 Marquee Top Light"
|
||||
IDS_DDR_P2_BOTTOM_LIGHT "P2 Marquee Bottom Light"
|
||||
IDS_DDR_BASS_LIGHT "Bass Neons"
|
||||
IDS_DDR_HD_P1_START "P1 HD Start"
|
||||
IDS_DDR_HD_P1_UP_DOWN "P1 HD Up/Down"
|
||||
IDS_DDR_HD_P1_LEFT_RIGHT "P1 HD Left/Right"
|
||||
IDS_DDR_HD_P2_START "P2 HD Start"
|
||||
IDS_DDR_HD_P2_UP_DOWN "P2 HD Up/Down"
|
||||
IDS_DDR_HD_P2_LEFT_RIGHT "P2 HD Left/Right"
|
||||
IDS_DDR_HD_P1_SPEAKER_F_R "P1 HD Speaker F R"
|
||||
IDS_DDR_HD_P1_SPEAKER_F_G "P1 HD Speaker F G"
|
||||
IDS_DDR_HD_P1_SPEAKER_F_B "P1 HD Speaker F B"
|
||||
IDS_DDR_HD_P2_SPEAKER_F_R "P2 HD Speaker F R"
|
||||
IDS_DDR_HD_P2_SPEAKER_F_G "P2 HD Speaker F G"
|
||||
IDS_DDR_HD_P2_SPEAKER_F_B "P2 HD Speaker F B"
|
||||
IDS_DDR_HD_P1_SPEAKER_W_R "P1 HD Speaker W R"
|
||||
IDS_DDR_HD_P1_SPEAKER_W_G "P1 HD Speaker W G"
|
||||
IDS_DDR_HD_P1_SPEAKER_W_B "P1 HD Speaker W B"
|
||||
IDS_DDR_HD_P2_SPEAKER_W_R "P2 HD Speaker W R"
|
||||
IDS_DDR_HD_P2_SPEAKER_W_G "P2 HD Speaker W G"
|
||||
IDS_DDR_HD_P2_SPEAKER_W_B "P2 HD Speaker W B"
|
||||
IDS_DDR_HD_SPOT_RED_TOP "HD Spot Red Top"
|
||||
IDS_DDR_HD_SPOT_BLUE_TOP "HD Spot Blue Top"
|
||||
IDS_PNM_SCHEMA "pop'n music"
|
||||
IDS_PNM_BTN1 "Button 1"
|
||||
IDS_PNM_BTN2 "Button 2"
|
||||
@@ -273,6 +293,15 @@ STRINGTABLE
|
||||
IDS_PNM_BTN7 "Button 7"
|
||||
IDS_PNM_BTN8 "Button 8"
|
||||
IDS_PNM_BTN9 "Button 9"
|
||||
IDS_PNM_TOP1 "Top neon 1 (topmost red)"
|
||||
IDS_PNM_TOP2 "Top neon 2 (orange)"
|
||||
IDS_PNM_TOP3 "Top neon 3 (green)"
|
||||
IDS_PNM_TOP4 "Top neon 4 (green)"
|
||||
IDS_PNM_TOP5 "Top neon 5 (bottom green)"
|
||||
IDS_PNM_LB "Left lamp (blue)"
|
||||
IDS_PNM_LR "Left lamp (red)"
|
||||
IDS_PNM_RB "Right lamp (blue)"
|
||||
IDS_PNM_RR "Right lamp (red)"
|
||||
IDS_JB_SCHEMA "Jubeat"
|
||||
IDS_JB_PANEL1 "Panel 1"
|
||||
IDS_JB_PANEL2 "Panel 2"
|
||||
|
||||
@@ -105,19 +105,32 @@ int main(int argc, char **argv)
|
||||
eam_io_init(crt_thread_create, crt_thread_join, crt_thread_destroy);
|
||||
eam_io_config_api = eam_io_get_config_api();
|
||||
|
||||
// calculate these and check against the loaded config
|
||||
max_light = -1;
|
||||
|
||||
for (i = 0; i < schema->nlights; i++) {
|
||||
if (max_light < schema->lights[i].bit) {
|
||||
max_light = schema->lights[i].bit;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mapper_config_load(schema->name)) {
|
||||
log_info("Initializing empty config for %s", schema->name);
|
||||
|
||||
max_light = -1;
|
||||
|
||||
for (i = 0; i < schema->nlights; i++) {
|
||||
if (max_light < schema->lights[i].bit) {
|
||||
max_light = schema->lights[i].bit;
|
||||
}
|
||||
}
|
||||
|
||||
mapper_set_nlights((uint8_t)(max_light + 1));
|
||||
mapper_set_nanalogs((uint8_t) schema->nanalogs);
|
||||
} else {
|
||||
// make sure that these are right
|
||||
|
||||
if (mapper_get_nlights() != (max_light + 1)) {
|
||||
log_info("Updating nlights for %s", schema->name);
|
||||
mapper_set_nlights((uint8_t)(max_light + 1));
|
||||
}
|
||||
|
||||
if (mapper_get_nanalogs() != schema->nanalogs) {
|
||||
log_info("Updating nanalogs for %s", schema->name);
|
||||
mapper_set_nanalogs((uint8_t) schema->nanalogs);
|
||||
}
|
||||
}
|
||||
|
||||
memset(&psh, 0, sizeof(psh));
|
||||
|
||||
@@ -243,3 +243,32 @@
|
||||
#define IDS_IIDX_PANEL_S3 40200
|
||||
#define IDS_IIDX_PANEL_S4 40201
|
||||
#define IDS_IIDX_PANEL_S5 40202
|
||||
#define IDS_PNM_TOP1 40203
|
||||
#define IDS_PNM_TOP2 40204
|
||||
#define IDS_PNM_TOP3 40205
|
||||
#define IDS_PNM_TOP4 40206
|
||||
#define IDS_PNM_TOP5 40207
|
||||
#define IDS_PNM_LB 40208
|
||||
#define IDS_PNM_LR 40209
|
||||
#define IDS_PNM_RB 40210
|
||||
#define IDS_PNM_RR 40211
|
||||
#define IDS_DDR_HD_P1_START 40212
|
||||
#define IDS_DDR_HD_P1_UP_DOWN 40213
|
||||
#define IDS_DDR_HD_P1_LEFT_RIGHT 40214
|
||||
#define IDS_DDR_HD_P2_START 40215
|
||||
#define IDS_DDR_HD_P2_UP_DOWN 40216
|
||||
#define IDS_DDR_HD_P2_LEFT_RIGHT 40217
|
||||
#define IDS_DDR_HD_P1_SPEAKER_F_R 40218
|
||||
#define IDS_DDR_HD_P1_SPEAKER_F_G 40219
|
||||
#define IDS_DDR_HD_P1_SPEAKER_F_B 40220
|
||||
#define IDS_DDR_HD_P2_SPEAKER_F_R 40221
|
||||
#define IDS_DDR_HD_P2_SPEAKER_F_G 40222
|
||||
#define IDS_DDR_HD_P2_SPEAKER_F_B 40223
|
||||
#define IDS_DDR_HD_P1_SPEAKER_W_R 40224
|
||||
#define IDS_DDR_HD_P1_SPEAKER_W_G 40225
|
||||
#define IDS_DDR_HD_P1_SPEAKER_W_B 40226
|
||||
#define IDS_DDR_HD_P2_SPEAKER_W_R 40227
|
||||
#define IDS_DDR_HD_P2_SPEAKER_W_G 40228
|
||||
#define IDS_DDR_HD_P2_SPEAKER_W_B 40229
|
||||
#define IDS_DDR_HD_SPOT_RED_TOP 40230
|
||||
#define IDS_DDR_HD_SPOT_BLUE_TOP 40231
|
||||
|
||||
@@ -3,30 +3,32 @@
|
||||
|
||||
#include "util/defs.h"
|
||||
|
||||
static const struct action_def dm_actions[] = {{0x01, IDS_GENERIC_TEST},
|
||||
{0x00, IDS_GENERIC_SERVICE},
|
||||
static const struct action_def dm_actions[] = {
|
||||
{0x01, IDS_GENERIC_TEST},
|
||||
{0x00, IDS_GENERIC_SERVICE},
|
||||
|
||||
{0x08, IDS_DM_START},
|
||||
{0x0F, IDS_DM_MENU_LEFT},
|
||||
{0x11, IDS_DM_MENU_RIGHT},
|
||||
{0x08, IDS_DM_START},
|
||||
{0x0F, IDS_DM_MENU_LEFT},
|
||||
{0x11, IDS_DM_MENU_RIGHT},
|
||||
|
||||
{0x0A, IDS_DM_HI_HAT},
|
||||
{0x0C, IDS_DM_SNARE},
|
||||
{0x0E, IDS_DM_HIGH_TOM},
|
||||
{0x10, IDS_DM_LOW_TOM},
|
||||
{0x12, IDS_DM_CYMBAL},
|
||||
{0x16, IDS_DM_BASS}};
|
||||
{0x0A, IDS_DM_HI_HAT},
|
||||
{0x0C, IDS_DM_SNARE},
|
||||
{0x0E, IDS_DM_HIGH_TOM},
|
||||
{0x10, IDS_DM_LOW_TOM},
|
||||
{0x12, IDS_DM_CYMBAL},
|
||||
{0x16, IDS_DM_BASS}};
|
||||
|
||||
static const struct light_def dm_lights[] = {{0x00, IDS_DM_HI_HAT},
|
||||
{0x01, IDS_DM_SNARE},
|
||||
{0x02, IDS_DM_HIGH_TOM},
|
||||
{0x03, IDS_DM_LOW_TOM},
|
||||
{0x04, IDS_DM_CYMBAL},
|
||||
{0x09, IDS_DM_BASS},
|
||||
{0x0A, IDS_DM_SPEAKER_LIGHT},
|
||||
{0x08, IDS_DM_SPOT_LIGHT},
|
||||
{0x06, IDS_DM_START_LIGHT},
|
||||
{0x07, IDS_DM_MENU_LIGHT}};
|
||||
static const struct light_def dm_lights[] = {
|
||||
{0x00, IDS_DM_HI_HAT},
|
||||
{0x01, IDS_DM_SNARE},
|
||||
{0x02, IDS_DM_HIGH_TOM},
|
||||
{0x03, IDS_DM_LOW_TOM},
|
||||
{0x04, IDS_DM_CYMBAL},
|
||||
{0x09, IDS_DM_BASS},
|
||||
{0x0A, IDS_DM_SPEAKER_LIGHT},
|
||||
{0x08, IDS_DM_SPOT_LIGHT},
|
||||
{0x06, IDS_DM_START_LIGHT},
|
||||
{0x07, IDS_DM_MENU_LIGHT}};
|
||||
|
||||
static const struct action_def gf_actions[] = {
|
||||
{0x01, IDS_GENERIC_TEST}, {0x00, IDS_GENERIC_SERVICE},
|
||||
@@ -43,10 +45,11 @@ static const struct action_def gf_actions[] = {
|
||||
{0x13, IDS_GF_P2_RED}, {0x15, IDS_GF_P2_GREEN},
|
||||
{0x17, IDS_GF_P2_BLUE}};
|
||||
|
||||
static const struct light_def gf_lights[] = {{0x08, IDS_GF_P1_SPOT_LIGHT},
|
||||
{0x09, IDS_GF_P2_SPOT_LIGHT},
|
||||
{0x0A, IDS_GF_P1_START},
|
||||
{0x0B, IDS_GF_P2_START}};
|
||||
static const struct light_def gf_lights[] = {
|
||||
{0x08, IDS_GF_P1_SPOT_LIGHT},
|
||||
{0x09, IDS_GF_P2_SPOT_LIGHT},
|
||||
{0x0A, IDS_GF_P1_START},
|
||||
{0x0B, IDS_GF_P2_START}};
|
||||
|
||||
static const struct action_def iidx_actions[] = {
|
||||
{0x1C, IDS_GENERIC_TEST}, {0x1D, IDS_GENERIC_SERVICE},
|
||||
@@ -101,8 +104,8 @@ static const struct light_def iidx_lights[] = {
|
||||
|
||||
{0x1F, IDS_IIDX_NEON_LIGHT}};
|
||||
|
||||
static const struct analog_def iidx_analogs[] = {{0, IDS_IIDX_P1_TT},
|
||||
{1, IDS_IIDX_P2_TT}};
|
||||
static const struct analog_def iidx_analogs[] = {
|
||||
{0, IDS_IIDX_P1_TT}, {1, IDS_IIDX_P2_TT}};
|
||||
|
||||
static const struct action_def ddr_actions[] = {
|
||||
{0x04, IDS_GENERIC_TEST}, {0x06, IDS_GENERIC_SERVICE},
|
||||
@@ -122,19 +125,48 @@ static const struct action_def ddr_actions[] = {
|
||||
static const struct light_def ddr_lights[] = {
|
||||
/* These are split between non-overlapping P3IO and EXTIO state words */
|
||||
|
||||
// P3IO: SD
|
||||
{0x00, IDS_DDR_P1_MENU_LIGHT},
|
||||
{0x07, IDS_DDR_P1_TOP_LIGHT},
|
||||
{0x07, IDS_DDR_P1_BOTTOM_LIGHT},
|
||||
|
||||
{0x1E, IDS_DDR_P1_UP},
|
||||
{0x1D, IDS_DDR_P1_DOWN},
|
||||
{0x1C, IDS_DDR_P1_LEFT},
|
||||
{0x1B, IDS_DDR_P1_RIGHT},
|
||||
{0x06, IDS_DDR_P1_BOTTOM_LIGHT},
|
||||
|
||||
{0x01, IDS_DDR_P2_MENU_LIGHT},
|
||||
{0x05, IDS_DDR_P2_TOP_LIGHT},
|
||||
{0x04, IDS_DDR_P2_BOTTOM_LIGHT},
|
||||
|
||||
// P3IO: HD
|
||||
{0x02, IDS_DDR_HD_SPOT_RED_TOP},
|
||||
{0x03, IDS_DDR_HD_SPOT_BLUE_TOP},
|
||||
|
||||
// P3IO: HDXS
|
||||
{0x08, IDS_DDR_HD_P1_START},
|
||||
{0x09, IDS_DDR_HD_P1_UP_DOWN},
|
||||
{0x0A, IDS_DDR_HD_P1_LEFT_RIGHT},
|
||||
|
||||
{0x0B, IDS_DDR_HD_P2_START},
|
||||
{0x0C, IDS_DDR_HD_P2_UP_DOWN},
|
||||
{0x0D, IDS_DDR_HD_P2_LEFT_RIGHT},
|
||||
|
||||
{0x20, IDS_DDR_HD_P1_SPEAKER_F_R},
|
||||
{0x21, IDS_DDR_HD_P1_SPEAKER_F_G},
|
||||
{0x22, IDS_DDR_HD_P1_SPEAKER_F_B},
|
||||
{0x23, IDS_DDR_HD_P2_SPEAKER_F_R},
|
||||
{0x24, IDS_DDR_HD_P2_SPEAKER_F_G},
|
||||
{0x25, IDS_DDR_HD_P2_SPEAKER_F_B},
|
||||
{0x26, IDS_DDR_HD_P1_SPEAKER_W_R},
|
||||
{0x27, IDS_DDR_HD_P1_SPEAKER_W_G},
|
||||
{0x28, IDS_DDR_HD_P1_SPEAKER_W_B},
|
||||
{0x29, IDS_DDR_HD_P2_SPEAKER_W_R},
|
||||
{0x2A, IDS_DDR_HD_P2_SPEAKER_W_G},
|
||||
{0x2B, IDS_DDR_HD_P2_SPEAKER_W_B},
|
||||
|
||||
|
||||
// EXTIO
|
||||
{0x1E, IDS_DDR_P1_UP},
|
||||
{0x1D, IDS_DDR_P1_DOWN},
|
||||
{0x1C, IDS_DDR_P1_LEFT},
|
||||
{0x1B, IDS_DDR_P1_RIGHT},
|
||||
|
||||
{0x16, IDS_DDR_P2_UP},
|
||||
{0x15, IDS_DDR_P2_DOWN},
|
||||
{0x14, IDS_DDR_P2_LEFT},
|
||||
@@ -142,18 +174,19 @@ static const struct light_def ddr_lights[] = {
|
||||
|
||||
{0x0E, IDS_DDR_BASS_LIGHT}};
|
||||
|
||||
static const struct action_def pnm_actions[] = {{0x07, IDS_GENERIC_TEST},
|
||||
{0x06, IDS_GENERIC_SERVICE},
|
||||
static const struct action_def pnm_actions[] = {
|
||||
{0x07, IDS_GENERIC_TEST},
|
||||
{0x06, IDS_GENERIC_SERVICE},
|
||||
|
||||
{0x08, IDS_PNM_BTN1},
|
||||
{0x09, IDS_PNM_BTN2},
|
||||
{0x0A, IDS_PNM_BTN3},
|
||||
{0x0B, IDS_PNM_BTN4},
|
||||
{0x0C, IDS_PNM_BTN5},
|
||||
{0x0D, IDS_PNM_BTN6},
|
||||
{0x0E, IDS_PNM_BTN7},
|
||||
{0x0F, IDS_PNM_BTN8},
|
||||
{0x10, IDS_PNM_BTN9}};
|
||||
{0x08, IDS_PNM_BTN1},
|
||||
{0x09, IDS_PNM_BTN2},
|
||||
{0x0A, IDS_PNM_BTN3},
|
||||
{0x0B, IDS_PNM_BTN4},
|
||||
{0x0C, IDS_PNM_BTN5},
|
||||
{0x0D, IDS_PNM_BTN6},
|
||||
{0x0E, IDS_PNM_BTN7},
|
||||
{0x0F, IDS_PNM_BTN8},
|
||||
{0x10, IDS_PNM_BTN9}};
|
||||
|
||||
static const struct light_def pnm_lights[] = {
|
||||
{0x17, IDS_PNM_BTN1},
|
||||
@@ -165,27 +198,37 @@ static const struct light_def pnm_lights[] = {
|
||||
{0x1D, IDS_PNM_BTN7},
|
||||
{0x1E, IDS_PNM_BTN8},
|
||||
{0x1F, IDS_PNM_BTN9},
|
||||
{0x20, IDS_PNM_TOP1},
|
||||
{0x21, IDS_PNM_TOP2},
|
||||
{0x22, IDS_PNM_TOP3},
|
||||
{0x23, IDS_PNM_TOP4},
|
||||
{0x24, IDS_PNM_TOP5},
|
||||
{0x25, IDS_PNM_LB},
|
||||
{0x26, IDS_PNM_LR},
|
||||
{0x27, IDS_PNM_RB},
|
||||
{0x28, IDS_PNM_RR},
|
||||
};
|
||||
|
||||
static const struct action_def jb_actions[] = {{0x10, IDS_GENERIC_TEST},
|
||||
{0x11, IDS_GENERIC_SERVICE},
|
||||
static const struct action_def jb_actions[] = {
|
||||
{0x10, IDS_GENERIC_TEST},
|
||||
{0x11, IDS_GENERIC_SERVICE},
|
||||
|
||||
{0x00, IDS_JB_PANEL1},
|
||||
{0x01, IDS_JB_PANEL2},
|
||||
{0x02, IDS_JB_PANEL3},
|
||||
{0x03, IDS_JB_PANEL4},
|
||||
{0x04, IDS_JB_PANEL5},
|
||||
{0x05, IDS_JB_PANEL6},
|
||||
{0x06, IDS_JB_PANEL7},
|
||||
{0x07, IDS_JB_PANEL8},
|
||||
{0x08, IDS_JB_PANEL9},
|
||||
{0x09, IDS_JB_PANEL10},
|
||||
{0x0A, IDS_JB_PANEL11},
|
||||
{0x0B, IDS_JB_PANEL12},
|
||||
{0x0C, IDS_JB_PANEL13},
|
||||
{0x0D, IDS_JB_PANEL14},
|
||||
{0x0E, IDS_JB_PANEL15},
|
||||
{0x0F, IDS_JB_PANEL16}};
|
||||
{0x00, IDS_JB_PANEL1},
|
||||
{0x01, IDS_JB_PANEL2},
|
||||
{0x02, IDS_JB_PANEL3},
|
||||
{0x03, IDS_JB_PANEL4},
|
||||
{0x04, IDS_JB_PANEL5},
|
||||
{0x05, IDS_JB_PANEL6},
|
||||
{0x06, IDS_JB_PANEL7},
|
||||
{0x07, IDS_JB_PANEL8},
|
||||
{0x08, IDS_JB_PANEL9},
|
||||
{0x09, IDS_JB_PANEL10},
|
||||
{0x0A, IDS_JB_PANEL11},
|
||||
{0x0B, IDS_JB_PANEL12},
|
||||
{0x0C, IDS_JB_PANEL13},
|
||||
{0x0D, IDS_JB_PANEL14},
|
||||
{0x0E, IDS_JB_PANEL15},
|
||||
{0x0F, IDS_JB_PANEL16}};
|
||||
|
||||
static const struct light_def jb_lights[] = {
|
||||
{0x00, IDS_JB_RGB_FRONT_R},
|
||||
@@ -208,15 +251,16 @@ static const struct light_def jb_lights[] = {
|
||||
{0x11, IDS_JB_RGB_WOOFER_B},
|
||||
};
|
||||
|
||||
static const struct action_def sdvx_actions[] = {{0x05, IDS_GENERIC_TEST},
|
||||
{0x04, IDS_GENERIC_SERVICE},
|
||||
{0x0B, IDS_SDVX_START},
|
||||
{0x0A, IDS_SDVX_BTN_A},
|
||||
{0x09, IDS_SDVX_BTN_B},
|
||||
{0x08, IDS_SDVX_BTN_C},
|
||||
{0x15, IDS_SDVX_BTN_D},
|
||||
{0x14, IDS_SDVX_FX_L},
|
||||
{0x13, IDS_SDVX_FX_R}};
|
||||
static const struct action_def sdvx_actions[] = {
|
||||
{0x05, IDS_GENERIC_TEST},
|
||||
{0x04, IDS_GENERIC_SERVICE},
|
||||
{0x0B, IDS_SDVX_START},
|
||||
{0x0A, IDS_SDVX_BTN_A},
|
||||
{0x09, IDS_SDVX_BTN_B},
|
||||
{0x08, IDS_SDVX_BTN_C},
|
||||
{0x15, IDS_SDVX_BTN_D},
|
||||
{0x14, IDS_SDVX_FX_L},
|
||||
{0x13, IDS_SDVX_FX_R}};
|
||||
|
||||
static const struct light_def sdvx_lights[] = {
|
||||
{0x0D, IDS_SDVX_BTN_A}, {0x0E, IDS_SDVX_BTN_B}, {0x0F, IDS_SDVX_BTN_C},
|
||||
@@ -229,19 +273,19 @@ static const struct light_def sdvx_lights[] = {
|
||||
{0x1E, IDS_SDVX_RGB5_B}, {0x1F, IDS_SDVX_RGB6_R}, {0x20, IDS_SDVX_RGB6_G},
|
||||
{0x21, IDS_SDVX_RGB6_B}};
|
||||
|
||||
static const struct analog_def sdvx_analogs[] = {{0, IDS_SDVX_VOL_L},
|
||||
{1, IDS_SDVX_VOL_R}};
|
||||
static const struct analog_def sdvx_analogs[] = {
|
||||
{0, IDS_SDVX_VOL_L}, {1, IDS_SDVX_VOL_R}};
|
||||
|
||||
static const struct action_def rb_actions[] = {{0x00, IDS_GENERIC_TEST},
|
||||
{0x01, IDS_GENERIC_SERVICE}};
|
||||
static const struct action_def rb_actions[] = {
|
||||
{0x00, IDS_GENERIC_TEST}, {0x01, IDS_GENERIC_SERVICE}};
|
||||
|
||||
static const struct action_def bst_actions[] = {
|
||||
{0x05, IDS_GENERIC_TEST},
|
||||
{0x04, IDS_GENERIC_SERVICE},
|
||||
};
|
||||
|
||||
static const struct eam_unit_def schema_eam_unit_defs[] = {{IDS_READER_P1, 0},
|
||||
{IDS_READER_P2, 1}};
|
||||
static const struct eam_unit_def schema_eam_unit_defs[] = {
|
||||
{IDS_READER_P1, 0}, {IDS_READER_P2, 1}};
|
||||
|
||||
const struct schema schemas[] = {
|
||||
{"iidx",
|
||||
|
||||
@@ -9,7 +9,6 @@ libs_ddrhook := \
|
||||
p3io \
|
||||
hook \
|
||||
hooklib \
|
||||
security \
|
||||
util \
|
||||
eamio \
|
||||
ddrio \
|
||||
|
||||
@@ -11,10 +11,14 @@
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "acio/hdxs.h"
|
||||
|
||||
#include "acioemu/addr.h"
|
||||
#include "acioemu/hdxs.h"
|
||||
#include "acioemu/icca.h"
|
||||
|
||||
#include "bemanitools/ddrio.h"
|
||||
|
||||
#include "ddrhook/_com4.h"
|
||||
|
||||
#include "hook/iohook.h"
|
||||
@@ -29,16 +33,60 @@ static struct ac_io_emu com4_ac_io_emu;
|
||||
static struct ac_io_emu_hdxs com4_hdxs;
|
||||
static struct ac_io_emu_icca com4_icca[2];
|
||||
|
||||
static uint32_t check_panel_light(
|
||||
const struct ac_io_hdxs_output *output,
|
||||
uint8_t panel_idx,
|
||||
uint8_t out_idx)
|
||||
{
|
||||
if (output->lights[panel_idx].bit) {
|
||||
return 1 << out_idx;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t upscale_light(uint8_t in_7bit) {
|
||||
if (in_7bit < 0x10) {
|
||||
return in_7bit * 2;
|
||||
} else {
|
||||
// so we can actually reach 0xFF
|
||||
return (in_7bit * 2) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void lights_dispatcher(
|
||||
struct ac_io_emu_hdxs *emu, const struct ac_io_message *req)
|
||||
{
|
||||
const struct ac_io_hdxs_output *output = &req->cmd.hdxs_output;
|
||||
|
||||
uint32_t lights = 0;
|
||||
lights |= check_panel_light(output, AC_IO_HDXS_OUT_P1_START, LIGHT_HD_P1_START);
|
||||
lights |= check_panel_light(output, AC_IO_HDXS_OUT_P1_UP_DOWN, LIGHT_HD_P1_UP_DOWN);
|
||||
lights |= check_panel_light(output, AC_IO_HDXS_OUT_P1_LEFT_RIGHT, LIGHT_HD_P1_LEFT_RIGHT);
|
||||
lights |= check_panel_light(output, AC_IO_HDXS_OUT_P2_START, LIGHT_HD_P2_START);
|
||||
lights |= check_panel_light(output, AC_IO_HDXS_OUT_P2_UP_DOWN, LIGHT_HD_P2_UP_DOWN);
|
||||
lights |= check_panel_light(output, AC_IO_HDXS_OUT_P2_LEFT_RIGHT, LIGHT_HD_P2_LEFT_RIGHT);
|
||||
|
||||
ddr_io_set_lights_hdxs_panel(lights);
|
||||
|
||||
for (uint8_t i = 0; i < 4; ++i) {
|
||||
size_t light_idx = i * 3;
|
||||
|
||||
// these are 7 bit, upscale them to 8 bit
|
||||
uint8_t r = upscale_light(output->lights[light_idx + AC_IO_HDXS_RED].analog);
|
||||
uint8_t g = upscale_light(output->lights[light_idx + AC_IO_HDXS_GREEN].analog);
|
||||
uint8_t b = upscale_light(output->lights[light_idx + AC_IO_HDXS_BLUE].analog);
|
||||
|
||||
ddr_io_set_lights_hdxs_rgb(i, r, g, b);
|
||||
}
|
||||
}
|
||||
|
||||
void com4_init(void)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
/* This isn't a real COM port, we configure the core P3IO emulator code to
|
||||
generate IRPs addressed to COM4 and then we intercept them. */
|
||||
|
||||
p3io_uart_set_path(0, L"COM4");
|
||||
ac_io_emu_init(&com4_ac_io_emu, L"COM4");
|
||||
ac_io_emu_hdxs_init(&com4_hdxs, &com4_ac_io_emu);
|
||||
ac_io_emu_hdxs_init(&com4_hdxs, &com4_ac_io_emu, lights_dispatcher);
|
||||
|
||||
for (i = 0; i < lengthof(com4_icca); i++) {
|
||||
ac_io_emu_icca_init(&com4_icca[i], &com4_ac_io_emu, i);
|
||||
|
||||
@@ -32,7 +32,7 @@ static bool my_dll_entry_main(void);
|
||||
bool standard_def;
|
||||
bool _15khz;
|
||||
|
||||
static const irp_handler_t ddrhook_handlers[] = {
|
||||
static const irp_handler_t ddrhook_com4_handlers[] = {
|
||||
p3io_emu_dispatch_irp,
|
||||
extio_dispatch_irp,
|
||||
spike_dispatch_irp,
|
||||
@@ -40,15 +40,27 @@ static const irp_handler_t ddrhook_handlers[] = {
|
||||
com4_dispatch_irp,
|
||||
};
|
||||
|
||||
static const irp_handler_t ddrhook_handlers[] = {
|
||||
/* Same as above, but without COM4 emulation.
|
||||
See ddrhook/p3io.c for details. */
|
||||
|
||||
p3io_emu_dispatch_irp,
|
||||
extio_dispatch_irp,
|
||||
spike_dispatch_irp,
|
||||
usbmem_dispatch_irp,
|
||||
};
|
||||
|
||||
static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
{
|
||||
int argc;
|
||||
char **argv;
|
||||
bool com4;
|
||||
bool ok;
|
||||
int i;
|
||||
|
||||
log_info("--- Begin ddrhook dll_entry_init ---");
|
||||
|
||||
com4 = true;
|
||||
args_recover(&argc, &argv);
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
@@ -65,13 +77,25 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
case 'w':
|
||||
gfx_set_windowed();
|
||||
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
/* Don't emulate P3IO COM4 and its downstream devices, use the
|
||||
Windows COM4 port instead. */
|
||||
com4 = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
args_free(argc, argv);
|
||||
|
||||
iohook_init(ddrhook_handlers, lengthof(ddrhook_handlers));
|
||||
if (com4) {
|
||||
iohook_init(ddrhook_com4_handlers, lengthof(ddrhook_com4_handlers));
|
||||
} else {
|
||||
iohook_init(ddrhook_handlers, lengthof(ddrhook_handlers));
|
||||
}
|
||||
|
||||
rs232_hook_init();
|
||||
|
||||
master_insert_hooks(NULL);
|
||||
@@ -92,15 +116,17 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
|
||||
return false;
|
||||
}
|
||||
|
||||
log_info("Initializing card reader backend");
|
||||
if (com4) {
|
||||
log_info("Initializing card reader backend");
|
||||
|
||||
eam_io_set_loggers(
|
||||
log_body_misc, log_body_info, log_body_warning, log_body_fatal);
|
||||
eam_io_set_loggers(
|
||||
log_body_misc, log_body_info, log_body_warning, log_body_fatal);
|
||||
|
||||
ok = eam_io_init(avs_thread_create, avs_thread_join, avs_thread_destroy);
|
||||
ok = eam_io_init(avs_thread_create, avs_thread_join, avs_thread_destroy);
|
||||
|
||||
if (!ok) {
|
||||
return false;
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
log_info("--- End ddrhook dll_entry_init ---");
|
||||
|
||||
@@ -29,6 +29,12 @@ static const struct p3io_ops p3io_ddr_ops = {
|
||||
|
||||
void p3io_ddr_init(void)
|
||||
{
|
||||
/* COM4 isn't a real COM port, we configure the core P3IO emulator code to
|
||||
generate IRPs addressed to COM4 and then we possibly intercept them in
|
||||
_com4.c (or possibly don't, in which case the communications will be
|
||||
sent to the real COM4 on your system) */
|
||||
|
||||
p3io_uart_set_path(0, L"COM4");
|
||||
p3io_emu_init(&p3io_ddr_ops, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,3 +7,5 @@ EXPORTS
|
||||
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
|
||||
|
||||
@@ -207,6 +207,21 @@ void ddr_io_set_lights_p3io(uint32_t p3io_lights)
|
||||
atomic_fetch_and(&out.lights, ~clr);
|
||||
}
|
||||
|
||||
void ddr_io_set_lights_hdxs_panel(uint32_t lights)
|
||||
{
|
||||
(void) lights;
|
||||
// stubbed
|
||||
}
|
||||
|
||||
void ddr_io_set_lights_hdxs_rgb(uint8_t idx, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
(void) idx;
|
||||
(void) r;
|
||||
(void) g;
|
||||
(void) b;
|
||||
// stubbed
|
||||
}
|
||||
|
||||
void ddr_io_fini(void)
|
||||
{
|
||||
if (initted) {
|
||||
|
||||
@@ -7,3 +7,5 @@ EXPORTS
|
||||
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
|
||||
|
||||
@@ -168,11 +168,30 @@ void ddr_io_set_lights_p3io(uint32_t lights)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0x0E; i <= 0x1E; i++) {
|
||||
for (i = 0x00; i <= 0x07; i++) {
|
||||
mapper_write_light(i, lights & (1 << i) ? 255 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ddr_io_set_lights_hdxs_panel(uint32_t lights)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0x08; i <= 0x0D; i++) {
|
||||
mapper_write_light(i, lights & (1 << i) ? 255 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ddr_io_set_lights_hdxs_rgb(uint8_t idx, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
if (idx < 4) {
|
||||
uint8_t base = 0x20 + idx * 3;
|
||||
mapper_write_light(base + 0, r);
|
||||
mapper_write_light(base + 1, g);
|
||||
mapper_write_light(base + 2, b);
|
||||
}
|
||||
}
|
||||
|
||||
void ddr_io_fini(void)
|
||||
{
|
||||
log_info("Stopping SMX.DLL");
|
||||
|
||||
@@ -43,7 +43,7 @@ void ddr_io_set_lights_extio(uint32_t lights)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0x00; i <= 0x07; i++) {
|
||||
for (i = 0x0E; i <= 0x1E; i++) {
|
||||
mapper_write_light(i, lights & (1 << i) ? 255 : 0);
|
||||
}
|
||||
}
|
||||
@@ -52,11 +52,30 @@ void ddr_io_set_lights_p3io(uint32_t lights)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0x0E; i <= 0x1E; i++) {
|
||||
for (i = 0x00; i <= 0x07; i++) {
|
||||
mapper_write_light(i, lights & (1 << i) ? 255 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ddr_io_set_lights_hdxs_panel(uint32_t lights)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0x08; i <= 0x0D; i++) {
|
||||
mapper_write_light(i, lights & (1 << i) ? 255 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ddr_io_set_lights_hdxs_rgb(uint8_t idx, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
if (idx < 4) {
|
||||
uint8_t base = 0x20 + idx * 3;
|
||||
mapper_write_light(base + 0, r);
|
||||
mapper_write_light(base + 1, g);
|
||||
mapper_write_light(base + 2, b);
|
||||
}
|
||||
}
|
||||
|
||||
void ddr_io_fini(void)
|
||||
{
|
||||
input_fini();
|
||||
|
||||
@@ -7,3 +7,5 @@ EXPORTS
|
||||
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
|
||||
|
||||
@@ -36,6 +36,8 @@ EXPORTS
|
||||
mapper_get_analog_map
|
||||
mapper_get_analog_sensitivity
|
||||
mapper_get_npages
|
||||
mapper_get_nanalogs
|
||||
mapper_get_nlights
|
||||
mapper_is_analog_absolute
|
||||
mapper_iterate_lights
|
||||
mapper_iterate_actions
|
||||
|
||||
@@ -16,6 +16,7 @@ bool mapper_get_action_map(
|
||||
bool mapper_get_analog_map(uint8_t analog, struct mapped_analog *ma);
|
||||
int32_t mapper_get_analog_sensitivity(uint8_t analog);
|
||||
uint8_t mapper_get_nanalogs(void);
|
||||
uint8_t mapper_get_nlights(void);
|
||||
uint8_t mapper_get_npages(void);
|
||||
bool mapper_is_analog_absolute(uint8_t analog);
|
||||
action_iter_t mapper_iterate_actions(void);
|
||||
|
||||
@@ -149,6 +149,11 @@ uint8_t mapper_get_nanalogs(void)
|
||||
return mapper_impl_get_nanalogs(mapper_inst);
|
||||
}
|
||||
|
||||
uint8_t mapper_get_nlights(void)
|
||||
{
|
||||
return mapper_impl_get_nlights(mapper_inst);
|
||||
}
|
||||
|
||||
uint8_t mapper_get_npages(void)
|
||||
{
|
||||
return mapper_impl_get_npages(mapper_inst);
|
||||
|
||||
@@ -5,6 +5,7 @@ deplibs_jbhook := \
|
||||
|
||||
ldflags_jbhook := \
|
||||
-lws2_32 \
|
||||
-liphlpapi \
|
||||
|
||||
libs_jbhook := \
|
||||
acioemu \
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "hook/iohook.h"
|
||||
|
||||
#include "hooklib/adapter.h"
|
||||
#include "hooklib/app.h"
|
||||
#include "hooklib/rs232.h"
|
||||
#include "hooklib/setupapi.h"
|
||||
@@ -133,6 +134,10 @@ BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
|
||||
app_hook_init(my_dll_entry_init, my_dll_entry_main);
|
||||
iohook_init(jbhook_handlers, lengthof(jbhook_handlers));
|
||||
|
||||
if (!options.disable_adapteremu) {
|
||||
adapter_hook_init();
|
||||
}
|
||||
|
||||
if (!options.disable_cardemu) {
|
||||
rs232_hook_init();
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ void options_init(struct options *options)
|
||||
options->window_framed = false;
|
||||
options->disable_p4ioemu = false;
|
||||
options->disable_cardemu = false;
|
||||
options->disable_adapteremu = false;
|
||||
}
|
||||
|
||||
bool options_read_cmdline(struct options *options, int argc, const char **argv)
|
||||
@@ -64,6 +65,11 @@ bool options_read_cmdline(struct options *options, int argc, const char **argv)
|
||||
break;
|
||||
}
|
||||
|
||||
case 'a': {
|
||||
options->disable_adapteremu = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'c': {
|
||||
options->disable_cardemu = true;
|
||||
break;
|
||||
@@ -90,6 +96,7 @@ void options_print_usage(void)
|
||||
" -h Print this usage message\n"
|
||||
" -w Run the game windowed\n"
|
||||
" -f Run the game in a framed window (needs -w option)\n"
|
||||
" -a Disable adapter hook\n"
|
||||
" -c Disable card emulation (e.g. when running on a "
|
||||
"real cab)\n"
|
||||
" -p Disable p4io emulation (e.g. when running on a "
|
||||
|
||||
@@ -9,6 +9,7 @@ struct options {
|
||||
bool window_framed;
|
||||
bool disable_p4ioemu;
|
||||
bool disable_cardemu;
|
||||
bool disable_adapteremu;
|
||||
};
|
||||
|
||||
void options_init_from_cmdline(struct options *options);
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
LIBRARY ddrio
|
||||
|
||||
EXPORTS
|
||||
ddr_io_fini
|
||||
ddr_io_init
|
||||
ddr_io_read_pad
|
||||
ddr_io_set_lights_extio
|
||||
ddr_io_set_lights_p3io
|
||||
@@ -423,12 +423,10 @@ static void p3io_cmd_get_cab_type_or_dipsw(
|
||||
if (hr == S_OK) {
|
||||
switch (type) {
|
||||
case P3IO_CAB_TYPE_SD:
|
||||
log_misc("%s: Returning cab type SD", __func__);
|
||||
resp->status = 1;
|
||||
break;
|
||||
|
||||
case P3IO_CAB_TYPE_HD:
|
||||
log_misc("%s: Returning cab type HD", __func__);
|
||||
resp->status = 2;
|
||||
break;
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ void p3io_uart_cmd_open_close(
|
||||
}
|
||||
|
||||
end:
|
||||
p3io_resp_init(&resp->hdr, sizeof(resp), &req->hdr);
|
||||
p3io_resp_init(&resp->hdr, sizeof(*resp), &req->hdr);
|
||||
resp->status = 0;
|
||||
resp->u8 = FAILED(hr);
|
||||
}
|
||||
@@ -167,7 +167,7 @@ void p3io_uart_cmd_write(
|
||||
hr = p3io_uart_write(p3io_uart_fds[req->port_no], &iobuf);
|
||||
|
||||
end:
|
||||
p3io_resp_init(&resp->hdr, sizeof(resp), &req->hdr);
|
||||
p3io_resp_init(&resp->hdr, sizeof(*resp), &req->hdr);
|
||||
resp->status = FAILED(hr);
|
||||
resp->nbytes = iobuf.pos;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
uint8_t crc8(const void *ptr, size_t nbytes, uint8_t in)
|
||||
{
|
||||
const uint8_t *bytes;
|
||||
@@ -8,7 +10,7 @@ uint8_t crc8(const void *ptr, size_t nbytes, uint8_t in)
|
||||
size_t i;
|
||||
size_t j;
|
||||
|
||||
// log_assert(ptr != NULL);
|
||||
log_assert(ptr != NULL);
|
||||
|
||||
bytes = ptr;
|
||||
crc = ~in;
|
||||
@@ -35,7 +37,7 @@ uint16_t crc16(const void *ptr, size_t nbytes, uint16_t in)
|
||||
size_t i;
|
||||
size_t j;
|
||||
|
||||
// log_assert(ptr != NULL);
|
||||
log_assert(ptr != NULL);
|
||||
|
||||
bytes = ptr;
|
||||
crc = ~in;
|
||||
@@ -55,6 +57,33 @@ uint16_t crc16(const void *ptr, size_t nbytes, uint16_t in)
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
uint16_t crc16_msb(const void *ptr, size_t nbytes, uint16_t in)
|
||||
{
|
||||
const uint8_t *bytes;
|
||||
uint16_t crc;
|
||||
size_t i;
|
||||
size_t j;
|
||||
|
||||
log_assert(ptr != NULL);
|
||||
|
||||
bytes = ptr;
|
||||
crc = in;
|
||||
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
crc ^= bytes[i] << 8;
|
||||
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (crc & 0x8000) {
|
||||
crc = (crc << 1) ^ 0x1021;
|
||||
} else {
|
||||
crc = crc << 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
uint32_t crc32(const void *ptr, size_t nbytes, uint32_t in)
|
||||
{
|
||||
const uint8_t *bytes;
|
||||
@@ -62,7 +91,7 @@ uint32_t crc32(const void *ptr, size_t nbytes, uint32_t in)
|
||||
size_t i;
|
||||
size_t j;
|
||||
|
||||
// log_assert(ptr != NULL);
|
||||
log_assert(ptr != NULL);
|
||||
|
||||
bytes = ptr;
|
||||
crc = ~in;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
uint8_t crc8(const void *ptr, size_t nbytes, uint8_t in);
|
||||
uint16_t crc16(const void *ptr, size_t nbytes, uint16_t in);
|
||||
uint16_t crc16_msb(const void *ptr, size_t nbytes, uint16_t in);
|
||||
uint32_t crc32(const void *ptr, size_t nbytes, uint32_t in);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -206,8 +206,8 @@ void _Noreturn check_data_eq_failed(
|
||||
line,
|
||||
func,
|
||||
"\tIncorrect result: %s\n"
|
||||
"\tReturn size was: %d\n"
|
||||
"\tExected size: %d\n"
|
||||
"\tReturn size was: %Iu\n"
|
||||
"\tExected size: %Iu\n"
|
||||
"\tReturn value was \"%s\"\n"
|
||||
"\tExpected \"%s\"\n\n",
|
||||
expr,
|
||||
|
||||
Reference in New Issue
Block a user