1
0
mirror of https://github.com/djhackersdev/bemanitools.git synced 2025-02-17 19:19:16 +01:00

iidxio-bio2: Add iidxio implementation using bio2 iidx driver

Use the original bio2 hardware with anything that supports BT5's
iidxio interface, e.g. old IIDX versions of BT5.
This commit is contained in:
icex2 2020-12-16 22:50:05 +01:00
parent 41edfec702
commit 53f8cb3bf3
5 changed files with 379 additions and 0 deletions

View File

@ -126,6 +126,7 @@ include src/main/iidxhook6/Module.mk
include src/main/iidxhook7/Module.mk
include src/main/iidxhook8/Module.mk
include src/main/iidxhook9/Module.mk
include src/main/iidxio-bio2/Module.mk
include src/main/iidxio-ezusb/Module.mk
include src/main/iidxio-ezusb2/Module.mk
include src/main/iidxio/Module.mk
@ -374,6 +375,7 @@ $(zipdir)/iidx-27.zip: \
$(zipdir)/iidx-hwio-x86.zip: \
build/bin/indep-32/eamio-icca.dll \
build/bin/indep-32/iidxio-bio2.dll \
build/bin/indep-32/iidxio-ezusb.dll \
build/bin/indep-32/iidxio-ezusb2.dll \
| $(zipdir)/
@ -382,6 +384,7 @@ $(zipdir)/iidx-hwio-x86.zip: \
$(zipdir)/iidx-hwio-x64.zip: \
build/bin/indep-64/eamio-icca.dll \
build/bin/indep-64/iidxio-bio2.dll \
build/bin/indep-64/iidxio-ezusb.dll \
build/bin/indep-64/iidxio-ezusb2.dll \
| $(zipdir)/

View File

@ -22,6 +22,7 @@ The following implementations are already shipped with BT5.
* ddrio-smx.dll: StepManiaX platforms
* Beatmania IIDX
* iidxio.dll (default): Keyboard, joystick and mouse input
* iidxio-bio2.dll: BIO2 driver
* iidxio-ezusb.dll: Ezusb (C02 IO) driver
* iidxio-ezusb2.dll: Ezusb FX2 (IO2) driver
* jubeat

View File

@ -0,0 +1,13 @@
dlls += iidxio-bio2
ldflags_iidxio-bio2 := \
-lsetupapi \
libs_iidxio-bio2 := \
aciodrv \
bio2drv \
cconfig \
util \
src_iidxio-bio2 := \
iidxio.c \

View File

@ -0,0 +1,18 @@
LIBRARY iidxio
EXPORTS
iidx_io_ep1_send
iidx_io_ep1_set_deck_lights
iidx_io_ep1_set_panel_lights
iidx_io_ep1_set_top_lamps
iidx_io_ep1_set_top_neons
iidx_io_ep2_get_keys
iidx_io_ep2_get_panel
iidx_io_ep2_get_sys
iidx_io_ep2_get_slider
iidx_io_ep2_get_turntable
iidx_io_ep2_recv
iidx_io_ep3_write_16seg
iidx_io_fini
iidx_io_init
iidx_io_set_loggers

View File

@ -0,0 +1,344 @@
#include <windows.h>
#define LOG_MODULE "iidxio-bio2"
#include <stdatomic.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "bemanitools/glue.h"
#include "bemanitools/iidxio.h"
#include "cconfig/cconfig-main.h"
#include "aciodrv/device.h"
#include "bio2drv/bi2a-iidx.h"
#include "bio2drv/config-bio2.h"
#include "bio2drv/detect.h"
#define log_misc(...) iidx_io_log_misc(LOG_MODULE, __VA_ARGS__)
#define log_info(...) iidx_io_log_info(LOG_MODULE, __VA_ARGS__)
#define log_warning(...) iidx_io_log_warning(LOG_MODULE, __VA_ARGS__)
#define log_fatal(...) iidx_io_log_fatal(LOG_MODULE, __VA_ARGS__)
static log_formatter_t iidx_io_log_misc;
static log_formatter_t iidx_io_log_info;
static log_formatter_t iidx_io_log_warning;
static log_formatter_t iidx_io_log_fatal;
static char autodetect_buffer[512];
static atomic_bool running;
static atomic_bool processing_io;
static int16_t bio2_node_id;
static struct bi2a_iidx_state_in pin_cur;
static struct bi2a_iidx_state_out pout_staging;
static struct bi2a_iidx_state_out pout_ready;
static bool _bio2_iidx_io_poll(
const struct bi2a_iidx_state_out *pout, struct bi2a_iidx_state_in *pin)
{
if (!running) {
return false;
}
processing_io = true;
if (!bio2drv_bi2a_iidx_poll(bio2_node_id, pout, pin)) {
processing_io = false;
return false;
}
processing_io = false;
return true;
}
void iidx_io_set_loggers(
log_formatter_t misc,
log_formatter_t info,
log_formatter_t warning,
log_formatter_t fatal)
{
iidx_io_log_misc = misc;
iidx_io_log_info = info;
iidx_io_log_warning = warning;
iidx_io_log_fatal = fatal;
bio2drv_set_loggers(misc, info, warning, fatal);
}
bool iidx_io_init(
thread_create_t thread_create,
thread_join_t thread_join,
thread_destroy_t thread_destroy)
{
struct cconfig *config;
struct bio2drv_config_bio2 config_bio2;
config = cconfig_init();
bio2drv_config_bio2_init(config);
if (!cconfig_main_config_init(
config,
"--bio2-config",
"iidxio-bio2.conf",
"--help",
"-h",
"iidxio-bio2",
CCONFIG_CMD_USAGE_OUT_STDOUT)) {
cconfig_finit(config);
exit(EXIT_FAILURE);
}
bio2drv_config_bio2_get(&config_bio2, config);
cconfig_finit(config);
const char *selected_port = config_bio2.port;
if (config_bio2.autodetect) {
log_info("Attempting autodetect");
if (bio2drv_detect(
DETECT_DEVICEID,
0,
autodetect_buffer,
sizeof(autodetect_buffer))) {
selected_port = autodetect_buffer;
} else {
log_info("Autodetect failed, falling back to using specified port");
}
}
if (!aciodrv_device_open(selected_port, config_bio2.baud)) {
log_info("Opening BIO2 device on [%s] failed", selected_port);
return 0;
}
log_info("Opening BIO2 device on [%s] successful", selected_port);
uint8_t node_count = aciodrv_device_get_node_count();
log_info("Enumerated %d nodes", node_count);
bio2_node_id = -1;
for (uint8_t i = 0; i < node_count; i++) {
char product[4];
aciodrv_device_get_node_product_ident(i, product);
log_info(
"> %d: %c%c%c%c\n",
i,
product[0],
product[1],
product[2],
product[3]);
if (!memcmp(product, "BI2A", 4)) {
if (bio2_node_id != -1) {
log_warning("Multiple BI2A found! Using highest node id.");
}
bio2_node_id = i;
}
}
if (bio2_node_id != -1) {
log_warning("Using BI2A on node: %d", bio2_node_id);
if (!bio2drv_bi2a_iidx_init(bio2_node_id)) {
log_warning("Unable to start BI2A on node: %d", bio2_node_id);
return false;
}
running = true;
log_warning("iidxio-bio2 now running");
} else {
log_warning("No bio2 device found");
}
return running;
}
void iidx_io_fini(void)
{
running = false;
while (processing_io) {
// avoid banging
Sleep(1);
}
}
void iidx_io_ep1_set_deck_lights(uint16_t deck_lights)
{
for (uint8_t i = 0; i < sizeof(pout_staging.DECKSW); i++) {
pout_staging.DECKSW[i].l_state = (deck_lights & (1 << i)) > 0;
}
}
void iidx_io_ep1_set_panel_lights(uint8_t panel_lights)
{
pout_staging.PANEL[BI2A_IIDX_PANEL_BUTTON_START_P1].l_state =
(panel_lights & (1 << IIDX_IO_PANEL_P1_START)) > 0;
pout_staging.PANEL[BI2A_IIDX_PANEL_BUTTON_START_P2].l_state =
(panel_lights & (1 << IIDX_IO_PANEL_P2_START)) > 0;
pout_staging.PANEL[BI2A_IIDX_PANEL_BUTTON_VEFX].l_state =
(panel_lights & (1 << IIDX_IO_PANEL_VEFX)) > 0;
pout_staging.PANEL[BI2A_IIDX_PANEL_BUTTON_EFFECT].l_state =
(panel_lights & (1 << IIDX_IO_PANEL_EFFECT)) > 0;
}
void iidx_io_ep1_set_top_lamps(uint8_t top_lamps)
{
pout_staging.SPOTLIGHT1[BI2A_IIDX_SPOTLIGHT_RIGHT_RED].l_state =
(top_lamps & (1 << IIDX_IO_TOP_LAMP_RIGHT_RED)) > 0;
pout_staging.SPOTLIGHT1[BI2A_IIDX_SPOTLIGHT_RIGHT_YELLOW].l_state =
(top_lamps & (1 << IIDX_IO_TOP_LAMP_RIGHT_YELLOW)) > 0;
pout_staging.SPOTLIGHT1[BI2A_IIDX_SPOTLIGHT_RIGHT_GREEN].l_state =
(top_lamps & (1 << IIDX_IO_TOP_LAMP_RIGHT_GREEN)) > 0;
pout_staging.SPOTLIGHT1[BI2A_IIDX_SPOTLIGHT_RIGHT_BLUE].l_state =
(top_lamps & (1 << IIDX_IO_TOP_LAMP_RIGHT_BLUE)) > 0;
pout_staging.SPOTLIGHT2[BI2A_IIDX_SPOTLIGHT_LEFT_RED].l_state =
(top_lamps & (1 << IIDX_IO_TOP_LAMP_LEFT_RED)) > 0;
pout_staging.SPOTLIGHT2[BI2A_IIDX_SPOTLIGHT_LEFT_YELLOW].l_state =
(top_lamps & (1 << IIDX_IO_TOP_LAMP_LEFT_YELLOW)) > 0;
pout_staging.SPOTLIGHT2[BI2A_IIDX_SPOTLIGHT_LEFT_GREEN].l_state =
(top_lamps & (1 << IIDX_IO_TOP_LAMP_LEFT_GREEN)) > 0;
pout_staging.SPOTLIGHT2[BI2A_IIDX_SPOTLIGHT_LEFT_BLUE].l_state =
(top_lamps & (1 << IIDX_IO_TOP_LAMP_LEFT_BLUE)) > 0;
}
void iidx_io_ep1_set_top_neons(bool top_neons)
{
pout_staging.NEONLAMP.l_state = top_neons;
}
bool iidx_io_ep1_send(void)
{
memcpy(&pout_ready, &pout_staging, sizeof(struct bi2a_iidx_state_out));
return true;
}
bool iidx_io_ep2_recv(void)
{
if (!_bio2_iidx_io_poll(&pout_ready, &pin_cur)) {
return false;
}
return true;
}
uint8_t iidx_io_ep2_get_turntable(uint8_t player_no)
{
switch (player_no) {
case 0:
return pin_cur.TURNTABLE1;
case 1:
return pin_cur.TURNTABLE2;
default:
return 0;
}
}
uint8_t iidx_io_ep2_get_slider(uint8_t slider_no)
{
switch (slider_no) {
case 0:
return pin_cur.SLIDER1.s_val & 0xF;
case 1:
return pin_cur.SLIDER2.s_val & 0xF;
case 2:
return pin_cur.SLIDER3.s_val & 0xF;
case 3:
return pin_cur.SLIDER4.s_val & 0xF;
case 4:
return pin_cur.SLIDER5.s_val & 0xF;
default:
return 0;
}
}
uint8_t iidx_io_ep2_get_sys(void)
{
uint8_t state;
state = 0;
if (pin_cur.SYSTEM.v_test) {
state |= (1 << IIDX_IO_SYS_TEST);
}
if (pin_cur.SYSTEM.v_service) {
state |= (1 << IIDX_IO_SYS_SERVICE);
}
if (pin_cur.SYSTEM.v_coin) {
state |= (1 << IIDX_IO_SYS_COIN);
}
return state;
}
uint8_t iidx_io_ep2_get_panel(void)
{
uint8_t state;
state = 0;
if (pin_cur.PANEL.y_start1) {
state |= (1 << IIDX_IO_PANEL_P1_START);
}
if (pin_cur.PANEL.y_start2) {
state |= (1 << IIDX_IO_PANEL_P2_START);
}
if (pin_cur.PANEL.y_vefx) {
state |= (1 << IIDX_IO_PANEL_VEFX);
}
if (pin_cur.PANEL.y_effect) {
state |= (1 << IIDX_IO_PANEL_EFFECT);
}
return state;
}
uint16_t iidx_io_ep2_get_keys(void)
{
uint16_t state;
state = 0;
state |= ((pin_cur.P1SW1.b_val > 0) << IIDX_IO_KEY_P1_1);
state |= ((pin_cur.P1SW2.b_val > 0) << IIDX_IO_KEY_P1_2);
state |= ((pin_cur.P1SW3.b_val > 0) << IIDX_IO_KEY_P1_3);
state |= ((pin_cur.P1SW4.b_val > 0) << IIDX_IO_KEY_P1_4);
state |= ((pin_cur.P1SW5.b_val > 0) << IIDX_IO_KEY_P1_5);
state |= ((pin_cur.P1SW6.b_val > 0) << IIDX_IO_KEY_P1_6);
state |= ((pin_cur.P1SW7.b_val > 0) << IIDX_IO_KEY_P1_7);
state |= ((pin_cur.P2SW1.b_val > 0) << IIDX_IO_KEY_P2_1);
state |= ((pin_cur.P2SW2.b_val > 0) << IIDX_IO_KEY_P2_2);
state |= ((pin_cur.P2SW3.b_val > 0) << IIDX_IO_KEY_P2_3);
state |= ((pin_cur.P2SW4.b_val > 0) << IIDX_IO_KEY_P2_4);
state |= ((pin_cur.P2SW5.b_val > 0) << IIDX_IO_KEY_P2_5);
state |= ((pin_cur.P2SW6.b_val > 0) << IIDX_IO_KEY_P2_6);
state |= ((pin_cur.P2SW7.b_val > 0) << IIDX_IO_KEY_P2_7);
return state;
}
bool iidx_io_ep3_write_16seg(const char *text)
{
memcpy(pout_staging.SEG16, text, sizeof(pout_staging.SEG16));
return true;
}