mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2025-02-20 20:41:10 +01:00
vigem-iidxio: Add vigem implementation with iidxio interface
This uses vigem to create two virtual xbox gamepads and hooks up the iidxio API to them. It allows you to use anything that implements the BT5's iidxio API as a game controller, e.g. iidxio-bio2, iidxio-ezusb1/2 to play any game that supports xbox game controllers, e.g. lunatic rave, IIDX infinitas. Further features include setting your own custom 16seg text from a configuration file or enable some hardcoded light sequence to make your cabinet look bad ass even when playing "Big Rigs: Over the Road Racing"
This commit is contained in:
parent
5658658d3a
commit
41187091b0
@ -155,6 +155,7 @@ include src/main/security/Module.mk
|
||||
include src/main/unicorntail/Module.mk
|
||||
include src/main/util/Module.mk
|
||||
include src/main/vefxio/Module.mk
|
||||
include src/main/vigem-iidxio/Module.mk
|
||||
include src/main/vigem-sdvxio/Module.mk
|
||||
include src/main/vigemstub/Module.mk
|
||||
|
||||
@ -382,6 +383,7 @@ $(zipdir)/iidx-hwio-x86.zip: \
|
||||
build/bin/indep-32/iidxio-ezusb.dll \
|
||||
build/bin/indep-32/iidxio-ezusb2.dll \
|
||||
dist/iidx/iidxio-bio2.conf \
|
||||
build/bin/indep-32/vigem-iidxio.exe \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
@ -392,6 +394,7 @@ $(zipdir)/iidx-hwio-x64.zip: \
|
||||
build/bin/indep-64/iidxio-ezusb.dll \
|
||||
build/bin/indep-64/iidxio-ezusb2.dll \
|
||||
dist/iidx/iidxio-bio2.conf \
|
||||
build/bin/indep-64/vigem-iidxio.exe \
|
||||
| $(zipdir)/
|
||||
$(V)echo ... $@
|
||||
$(V)zip -j $@ $^
|
||||
|
22
src/main/vigem-iidxio/Module.mk
Normal file
22
src/main/vigem-iidxio/Module.mk
Normal file
@ -0,0 +1,22 @@
|
||||
exes += vigem-iidxio
|
||||
|
||||
deplibs_vigem-iidxio := \
|
||||
ViGEmClient \
|
||||
|
||||
cppflags_vigem-iidxio := \
|
||||
-I src/imports \
|
||||
|
||||
ldflags_vigem-iidxio := \
|
||||
-lsetupapi \
|
||||
|
||||
libs_vigem-iidxio := \
|
||||
cconfig \
|
||||
iidxio \
|
||||
util \
|
||||
vigemstub \
|
||||
|
||||
src_vigem-iidxio := \
|
||||
cab-16seg-sequencer.c \
|
||||
cab-light-sequencer.c \
|
||||
main.c \
|
||||
config.c \
|
87
src/main/vigem-iidxio/cab-16seg-sequencer.c
Normal file
87
src/main/vigem-iidxio/cab-16seg-sequencer.c
Normal file
@ -0,0 +1,87 @@
|
||||
#define LOG_MODULE "vigem-iidx-cab-16seg-sequencer"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "util/log.h"
|
||||
#include "util/time.h"
|
||||
|
||||
static const uint8_t _MAX_LEN_16SEG = 9;
|
||||
|
||||
static bool _enabled;
|
||||
|
||||
static uint64_t _time_counter;
|
||||
static size_t _text_pos;
|
||||
|
||||
static char _text[1024 + 1];
|
||||
static size_t _text_len;
|
||||
|
||||
static uint32_t _scroll_cycle_time_ms;
|
||||
|
||||
static void _create_display_string_with_wrap_around(char* out_16seg)
|
||||
{
|
||||
size_t cur_text_pos = _text_pos;
|
||||
|
||||
for (uint8_t i = 0; i < _MAX_LEN_16SEG; i++) {
|
||||
if (cur_text_pos >= _text_len) {
|
||||
cur_text_pos = 0;
|
||||
}
|
||||
|
||||
out_16seg[i] = _text[cur_text_pos];
|
||||
cur_text_pos++;
|
||||
}
|
||||
}
|
||||
|
||||
void vigem_iidxio_cab_16seg_sequencer_init(const char* text, uint32_t scroll_cycle_time_ms)
|
||||
{
|
||||
log_assert(text);
|
||||
|
||||
_text_len = strlen(text);
|
||||
|
||||
if (_text_len + 1 > sizeof(_text)) {
|
||||
log_warning("Truncating input text as it exceeds the max size");
|
||||
strncpy(_text, text, sizeof(_text) - 1);
|
||||
} else {
|
||||
strcpy(_text, text);
|
||||
}
|
||||
|
||||
_scroll_cycle_time_ms = scroll_cycle_time_ms;
|
||||
|
||||
_time_counter = time_get_counter();
|
||||
_enabled = true;
|
||||
|
||||
if (_enabled) {
|
||||
log_info("Initialized, cycle time %d ms, text \"%s\"", _scroll_cycle_time_ms, _text);
|
||||
}
|
||||
}
|
||||
|
||||
void vigem_iidxio_cab_16seg_sequencer_update(char* out_16seg)
|
||||
{
|
||||
log_assert(out_16seg);
|
||||
|
||||
memset(out_16seg, ' ', _MAX_LEN_16SEG);
|
||||
|
||||
if (!_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t counter_now = time_get_counter();
|
||||
uint32_t cycle_time_elapsed_ms = time_get_elapsed_ms(counter_now - _time_counter);
|
||||
|
||||
if (cycle_time_elapsed_ms >= _scroll_cycle_time_ms) {
|
||||
_time_counter = counter_now;
|
||||
_text_pos++;
|
||||
|
||||
if (_text_pos >= _text_len) {
|
||||
_text_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Have static text if not exceeding 16seg display size
|
||||
if (_text_len <= _MAX_LEN_16SEG) {
|
||||
memcpy(out_16seg, _text, _text_len);
|
||||
} else {
|
||||
_create_display_string_with_wrap_around(out_16seg);
|
||||
}
|
||||
}
|
8
src/main/vigem-iidxio/cab-16seg-sequencer.h
Normal file
8
src/main/vigem-iidxio/cab-16seg-sequencer.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef VIGEM_IIDXIO_CAB_16SEG_SEQUENCER_H
|
||||
#define VIGEM_IIDXIO_CAB_16SEG_SEQUENCER_H
|
||||
|
||||
void vigem_iidxio_cab_16seg_sequencer_init(const char* text, uint32_t scroll_cycle_time_ms);
|
||||
|
||||
void vigem_iidxio_cab_16seg_sequencer_update(char* out_16seg);
|
||||
|
||||
#endif
|
48
src/main/vigem-iidxio/cab-light-sequencer.c
Normal file
48
src/main/vigem-iidxio/cab-light-sequencer.c
Normal file
@ -0,0 +1,48 @@
|
||||
#define LOG_MODULE "vigem-iidx-cab-light-sequencer"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/log.h"
|
||||
#include "util/time.h"
|
||||
|
||||
static const uint32_t _SEQ_CYCLE_TIME_MS = 2000;
|
||||
|
||||
static bool _enabled;
|
||||
|
||||
static uint64_t _time_counter;
|
||||
|
||||
void vigem_iidxio_cab_light_sequencer_init()
|
||||
{
|
||||
_time_counter = time_get_counter();
|
||||
_enabled = true;
|
||||
|
||||
if (_enabled) {
|
||||
log_info("Initialized");
|
||||
}
|
||||
}
|
||||
|
||||
void vigem_iidxio_cab_light_sequencer_update(bool* out_neon, uint8_t* out_spots)
|
||||
{
|
||||
log_assert(out_neon);
|
||||
log_assert(out_spots);
|
||||
|
||||
if (!_enabled) {
|
||||
*out_neon = false;
|
||||
*out_spots = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t counter_now = time_get_counter();
|
||||
uint32_t cycle_time_elapsed_ms = time_get_elapsed_ms(counter_now - _time_counter);
|
||||
|
||||
if (cycle_time_elapsed_ms < _SEQ_CYCLE_TIME_MS / 2) {
|
||||
*out_neon = false;
|
||||
} else {
|
||||
*out_neon = true;
|
||||
}
|
||||
|
||||
if (cycle_time_elapsed_ms >= _SEQ_CYCLE_TIME_MS) {
|
||||
_time_counter = counter_now;
|
||||
}
|
||||
}
|
11
src/main/vigem-iidxio/cab-light-sequencer.h
Normal file
11
src/main/vigem-iidxio/cab-light-sequencer.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef VIGEM_IIDXIO_CAB_LIGHT_SEQUENCER_H
|
||||
#define VIGEM_IIDXIO_CAB_LIGHT_SEQUENCER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void vigem_iidxio_cab_light_sequencer_init();
|
||||
|
||||
void vigem_iidxio_cab_light_sequencer_update(bool* out_neon, uint8_t* out_spots);
|
||||
|
||||
#endif
|
143
src/main/vigem-iidxio/config.c
Normal file
143
src/main/vigem-iidxio/config.c
Normal file
@ -0,0 +1,143 @@
|
||||
#include "cconfig/cconfig-main.h"
|
||||
#include "cconfig/cconfig-util.h"
|
||||
|
||||
#include "vigem-iidxio/config.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
#define VIGEM_IIDXIO_CONFIG_ENABLE_KEYLIGHT_KEY "vigem.iidxio.enable_keylight"
|
||||
#define VIGEM_IIDXIO_CONFIG_RELATIVE_ANALOG_KEY "vigem.iidxio.use_relative_analog"
|
||||
#define VIGEM_IIDXIO_CONFIG_ENABLE_CAB_LIGHT_SEQ_KEY "vigem.iidxio.enable_cab_light_seq"
|
||||
#define VIGEM_IIDXIO_CONFIG_TEXT_16SEG_KEY "vigem.iidxio.text_16seg"
|
||||
#define VIGEM_IIDXIO_CONFIG_TEXT_SCROLL_CYCLE_TIME_MS_KEY "vigem.iidxio.text_scroll_cycle_time_ms"
|
||||
|
||||
#define VIGEM_IIDXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE true
|
||||
#define VIGEM_IIDXIO_CONFIG_DEFAULT_RELATIVE_ANALOG_VALUE false
|
||||
#define VIGEM_IIDXIO_CONFIG_DEFAULT_ENABLE_CAB_LIGHT_SEQ_VALUE false
|
||||
#define VIGEM_IIDXIO_CONFIG_DEFAULT_TEXT_16SEG_VALUE ""
|
||||
#define VIGEM_IIDXIO_CONFIG_DEFAULT_TEXT_SCROLL_CYCLE_TIME_MS_VALUE 500
|
||||
|
||||
static void _vigem_iidxio_config_init(struct cconfig *config)
|
||||
{
|
||||
cconfig_util_set_bool(
|
||||
config,
|
||||
VIGEM_IIDXIO_CONFIG_ENABLE_KEYLIGHT_KEY,
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE,
|
||||
"Enable input based key lighting");
|
||||
|
||||
cconfig_util_set_bool(
|
||||
config,
|
||||
VIGEM_IIDXIO_CONFIG_RELATIVE_ANALOG_KEY,
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_RELATIVE_ANALOG_VALUE,
|
||||
"Use relative mode analog mapping");
|
||||
|
||||
cconfig_util_set_bool(
|
||||
config,
|
||||
VIGEM_IIDXIO_CONFIG_ENABLE_CAB_LIGHT_SEQ_KEY,
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_ENABLE_CAB_LIGHT_SEQ_VALUE,
|
||||
"Enable built in cabinet light sequence");
|
||||
|
||||
cconfig_util_set_str(
|
||||
config,
|
||||
VIGEM_IIDXIO_CONFIG_TEXT_16SEG_KEY,
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_TEXT_16SEG_VALUE,
|
||||
"Display text on 16seg. If text exceeds 9 char display limit, it will scroll");
|
||||
|
||||
cconfig_util_set_int(
|
||||
config,
|
||||
VIGEM_IIDXIO_CONFIG_TEXT_SCROLL_CYCLE_TIME_MS_KEY,
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_TEXT_SCROLL_CYCLE_TIME_MS_VALUE,
|
||||
"Cycle time/scroll speed for text exceeding 16seg display length (9) to scroll from right");
|
||||
}
|
||||
|
||||
static void _vigem_iidxio_config_get(
|
||||
struct vigem_iidxio_config *vigem_config, struct cconfig *config)
|
||||
{
|
||||
if (!cconfig_util_get_bool(
|
||||
config,
|
||||
VIGEM_IIDXIO_CONFIG_ENABLE_KEYLIGHT_KEY,
|
||||
&vigem_config->enable_keylight,
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%d'",
|
||||
VIGEM_IIDXIO_CONFIG_ENABLE_KEYLIGHT_KEY,
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE);
|
||||
}
|
||||
|
||||
if (!cconfig_util_get_bool(
|
||||
config,
|
||||
VIGEM_IIDXIO_CONFIG_RELATIVE_ANALOG_KEY,
|
||||
&vigem_config->relative_analog,
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_RELATIVE_ANALOG_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%d'",
|
||||
VIGEM_IIDXIO_CONFIG_RELATIVE_ANALOG_KEY,
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_RELATIVE_ANALOG_VALUE);
|
||||
}
|
||||
|
||||
if (!cconfig_util_get_bool(
|
||||
config,
|
||||
VIGEM_IIDXIO_CONFIG_ENABLE_CAB_LIGHT_SEQ_KEY,
|
||||
&vigem_config->enable_cab_light_seq,
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_ENABLE_CAB_LIGHT_SEQ_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%d'",
|
||||
VIGEM_IIDXIO_CONFIG_ENABLE_CAB_LIGHT_SEQ_KEY,
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_ENABLE_CAB_LIGHT_SEQ_VALUE);
|
||||
}
|
||||
|
||||
if (!cconfig_util_get_str(
|
||||
config,
|
||||
VIGEM_IIDXIO_CONFIG_TEXT_16SEG_KEY,
|
||||
vigem_config->text_16seg,
|
||||
sizeof(vigem_config->text_16seg),
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_TEXT_16SEG_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%s'",
|
||||
VIGEM_IIDXIO_CONFIG_TEXT_16SEG_KEY,
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_TEXT_16SEG_VALUE);
|
||||
}
|
||||
|
||||
if (!cconfig_util_get_int(
|
||||
config,
|
||||
VIGEM_IIDXIO_CONFIG_TEXT_SCROLL_CYCLE_TIME_MS_KEY,
|
||||
&vigem_config->text_scroll_cycle_time_ms,
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_TEXT_SCROLL_CYCLE_TIME_MS_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%d'",
|
||||
VIGEM_IIDXIO_CONFIG_TEXT_SCROLL_CYCLE_TIME_MS_KEY,
|
||||
VIGEM_IIDXIO_CONFIG_DEFAULT_TEXT_SCROLL_CYCLE_TIME_MS_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
bool vigem_iidxio_config_get(struct vigem_iidxio_config *config_out)
|
||||
{
|
||||
struct cconfig *config;
|
||||
|
||||
config = cconfig_init();
|
||||
|
||||
_vigem_iidxio_config_init(config);
|
||||
|
||||
if (!cconfig_main_config_init(
|
||||
config,
|
||||
"--config",
|
||||
"vigem-iidxio.conf",
|
||||
"--help",
|
||||
"-h",
|
||||
"vigem-iidxio",
|
||||
CCONFIG_CMD_USAGE_OUT_STDOUT)) {
|
||||
cconfig_finit(config);
|
||||
return false;
|
||||
}
|
||||
|
||||
_vigem_iidxio_config_get(config_out, config);
|
||||
|
||||
cconfig_finit(config);
|
||||
|
||||
return true;
|
||||
}
|
18
src/main/vigem-iidxio/config.h
Normal file
18
src/main/vigem-iidxio/config.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef VIGEM_IIDXIO_CONFIG_H
|
||||
#define VIGEM_IIDXIO_CONFIG_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "cconfig/cconfig.h"
|
||||
|
||||
struct vigem_iidxio_config {
|
||||
bool enable_keylight;
|
||||
bool relative_analog;
|
||||
bool enable_cab_light_seq;
|
||||
char text_16seg[1024 + 1];
|
||||
int32_t text_scroll_cycle_time_ms;
|
||||
};
|
||||
|
||||
bool vigem_iidxio_config_get(struct vigem_iidxio_config *config_out);
|
||||
|
||||
#endif
|
315
src/main/vigem-iidxio/main.c
Normal file
315
src/main/vigem-iidxio/main.c
Normal file
@ -0,0 +1,315 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <ViGEm/Client.h>
|
||||
|
||||
#include "bemanitools/iidxio.h"
|
||||
|
||||
#include "util/log.h"
|
||||
#include "util/math.h"
|
||||
#include "util/thread.h"
|
||||
#include "util/time.h"
|
||||
|
||||
#include "vigem-iidxio/cab-16seg-sequencer.h"
|
||||
#include "vigem-iidxio/cab-light-sequencer.h"
|
||||
#include "vigem-iidxio/config.h"
|
||||
|
||||
#include "vigemstub/helper.h"
|
||||
|
||||
#define ANALOG_FIXED_SENSITIVITY 256
|
||||
|
||||
static int16_t _convert_analog_to_s16(uint8_t val)
|
||||
{
|
||||
return (int64_t) val * 256;
|
||||
}
|
||||
|
||||
static int16_t _filter_floor(int32_t value, int16_t floor) {
|
||||
if (abs(value) < floor) {
|
||||
return 0;
|
||||
}
|
||||
if (value > INT16_MAX) {
|
||||
value = INT16_MAX;
|
||||
}
|
||||
if (value < INT16_MIN) {
|
||||
value = INT16_MIN;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static int32_t _convert_relative_analog(
|
||||
uint8_t val, uint8_t last, int32_t buffered_last, int16_t multiplier)
|
||||
{
|
||||
int16_t delta = get_wrapped_delta_s16(val, last, UINT8_MAX);
|
||||
|
||||
if (delta == 0) {
|
||||
// ease the stick back to 0 like a real stick would
|
||||
return buffered_last / 2.f;
|
||||
} else {
|
||||
int64_t result = buffered_last;
|
||||
result += delta * multiplier;
|
||||
|
||||
// we use an i32 to store the buffered value
|
||||
// so that we can overshoot an i16 by up to 1.5x
|
||||
// this allows users to stay at the min/max stick positions
|
||||
// without perfect knob turning
|
||||
if (result > INT16_MAX * 1.5) {
|
||||
result = INT16_MAX * 1.5;
|
||||
}
|
||||
if (result < INT16_MIN * 1.5) {
|
||||
result = INT16_MIN * 1.5;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
static bool _check_key(uint16_t input, size_t idx_in)
|
||||
{
|
||||
if ((input >> idx_in) & 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static uint16_t _check_assign_key(uint16_t input, size_t idx_in, size_t bit_out)
|
||||
{
|
||||
if (_check_key(input, idx_in)) {
|
||||
return bit_out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
log_to_writer(log_writer_stdout, NULL);
|
||||
|
||||
struct vigem_iidxio_config config;
|
||||
|
||||
if (!vigem_iidxio_config_get(&config)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
iidx_io_set_loggers(
|
||||
log_impl_misc, log_impl_info, log_impl_warning, log_impl_fatal);
|
||||
|
||||
if (!iidx_io_init(crt_thread_create, crt_thread_join, crt_thread_destroy)) {
|
||||
log_warning("Initializing iidxio failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PVIGEM_CLIENT client = vigem_helper_setup();
|
||||
|
||||
if (!client) {
|
||||
log_warning("VIGEM client failed to connect");
|
||||
|
||||
iidx_io_fini();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
PVIGEM_TARGET pad[2];
|
||||
|
||||
pad[0] = vigem_helper_add_pad(client);
|
||||
pad[1] = vigem_helper_add_pad(client);
|
||||
|
||||
if (!pad[0] || !pad[1]) {
|
||||
if (!pad[0]) {
|
||||
log_warning("vigem_alloc pad 1 failed");
|
||||
}
|
||||
|
||||
if (!pad[1]) {
|
||||
log_warning("vigem_alloc pad 2 failed");
|
||||
}
|
||||
|
||||
iidx_io_fini();
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool loop = true;
|
||||
|
||||
XUSB_REPORT state[2];
|
||||
|
||||
log_info("vigem init succeeded, beginning poll loop");
|
||||
|
||||
// Initial output state, turn all lights off
|
||||
iidx_io_ep1_set_deck_lights(0);
|
||||
iidx_io_ep1_set_panel_lights(0);
|
||||
iidx_io_ep1_set_top_lamps(0);
|
||||
iidx_io_ep1_set_top_neons(false);
|
||||
|
||||
if (config.enable_cab_light_seq) {
|
||||
vigem_iidxio_cab_light_sequencer_init();
|
||||
}
|
||||
|
||||
if (config.text_16seg[0] != '\0') {
|
||||
vigem_iidxio_cab_16seg_sequencer_init(config.text_16seg, config.text_scroll_cycle_time_ms);
|
||||
}
|
||||
|
||||
uint8_t turntable_buffered[2] = {0, 0};
|
||||
uint8_t turntable_last[2] = {0, 0};
|
||||
|
||||
while (loop) {
|
||||
if (!iidx_io_ep2_recv()) {
|
||||
log_warning("iidxio receiving failed");
|
||||
break;
|
||||
}
|
||||
|
||||
memset(&state[0], 0, sizeof(state[0]));
|
||||
memset(&state[1], 0, sizeof(state[1]));
|
||||
|
||||
// 14 keys
|
||||
uint16_t keys = iidx_io_ep2_get_keys();
|
||||
|
||||
state[0].wButtons |= _check_assign_key(
|
||||
keys, IIDX_IO_KEY_P1_1, XUSB_GAMEPAD_A);
|
||||
state[0].wButtons |= _check_assign_key(
|
||||
keys, IIDX_IO_KEY_P1_2, XUSB_GAMEPAD_B);
|
||||
state[0].wButtons |= _check_assign_key(
|
||||
keys, IIDX_IO_KEY_P1_3, XUSB_GAMEPAD_X);
|
||||
state[0].wButtons |= _check_assign_key(
|
||||
keys, IIDX_IO_KEY_P1_4, XUSB_GAMEPAD_Y);
|
||||
state[0].wButtons |= _check_assign_key(
|
||||
keys, IIDX_IO_KEY_P1_5, XUSB_GAMEPAD_LEFT_SHOULDER);
|
||||
state[0].wButtons |= _check_assign_key(
|
||||
keys, IIDX_IO_KEY_P1_6, XUSB_GAMEPAD_RIGHT_SHOULDER);
|
||||
state[0].wButtons |= _check_assign_key(
|
||||
keys, IIDX_IO_KEY_P1_7, XUSB_GAMEPAD_DPAD_RIGHT);
|
||||
|
||||
state[1].wButtons |= _check_assign_key(
|
||||
keys, IIDX_IO_KEY_P2_1, XUSB_GAMEPAD_A);
|
||||
state[1].wButtons |= _check_assign_key(
|
||||
keys, IIDX_IO_KEY_P2_2, XUSB_GAMEPAD_B);
|
||||
state[1].wButtons |= _check_assign_key(
|
||||
keys, IIDX_IO_KEY_P2_3, XUSB_GAMEPAD_X);
|
||||
state[1].wButtons |= _check_assign_key(
|
||||
keys, IIDX_IO_KEY_P2_4, XUSB_GAMEPAD_Y);
|
||||
state[1].wButtons |= _check_assign_key(
|
||||
keys, IIDX_IO_KEY_P2_5, XUSB_GAMEPAD_LEFT_SHOULDER);
|
||||
state[1].wButtons |= _check_assign_key(
|
||||
keys, IIDX_IO_KEY_P2_6, XUSB_GAMEPAD_RIGHT_SHOULDER);
|
||||
state[1].wButtons |= _check_assign_key(
|
||||
keys, IIDX_IO_KEY_P2_7, XUSB_GAMEPAD_DPAD_RIGHT);
|
||||
|
||||
// Panel buttons
|
||||
uint8_t panel = iidx_io_ep2_get_panel();
|
||||
|
||||
state[0].wButtons |= _check_assign_key(
|
||||
panel, IIDX_IO_PANEL_LIGHT_P1_START, XUSB_GAMEPAD_START);
|
||||
state[1].wButtons |= _check_assign_key(
|
||||
panel, IIDX_IO_PANEL_LIGHT_P2_START, XUSB_GAMEPAD_START);
|
||||
state[0].wButtons |= _check_assign_key(
|
||||
panel, IIDX_IO_PANEL_LIGHT_VEFX, XUSB_GAMEPAD_BACK);
|
||||
state[1].wButtons |= _check_assign_key(
|
||||
panel, IIDX_IO_PANEL_LIGHT_EFFECT, XUSB_GAMEPAD_BACK);
|
||||
|
||||
// System buttons
|
||||
uint8_t system = iidx_io_ep2_get_sys();
|
||||
|
||||
state[0].wButtons |= _check_assign_key(
|
||||
system, IIDX_IO_SYS_TEST, XUSB_GAMEPAD_LEFT_THUMB);
|
||||
state[0].wButtons |= _check_assign_key(
|
||||
system, IIDX_IO_SYS_SERVICE, XUSB_GAMEPAD_RIGHT_THUMB);
|
||||
state[1].wButtons |= _check_assign_key(
|
||||
system, IIDX_IO_SYS_COIN, XUSB_GAMEPAD_LEFT_THUMB);
|
||||
|
||||
// Turntable
|
||||
uint8_t turntable[2];
|
||||
|
||||
turntable[0] = iidx_io_ep2_get_turntable(0);
|
||||
turntable[1] = iidx_io_ep2_get_turntable(1);
|
||||
|
||||
if (config.relative_analog) {
|
||||
turntable_buffered[0] = _convert_relative_analog(
|
||||
turntable[0], turntable_last[0], turntable_buffered[0], ANALOG_FIXED_SENSITIVITY);
|
||||
turntable_buffered[1] = _convert_relative_analog(
|
||||
turntable[1], turntable_last[1], turntable_buffered[1], ANALOG_FIXED_SENSITIVITY);
|
||||
|
||||
state[0].sThumbLX = _filter_floor(turntable_buffered[0], ANALOG_FIXED_SENSITIVITY / 2);
|
||||
state[1].sThumbLX = _filter_floor(turntable_buffered[1], ANALOG_FIXED_SENSITIVITY / 2);
|
||||
|
||||
turntable_last[0] = turntable[0];
|
||||
turntable_last[1] = turntable[1];
|
||||
} else {
|
||||
state[0].sThumbLX = _convert_analog_to_s16(turntable[0]);
|
||||
state[1].sThumbLX = _convert_analog_to_s16(turntable[1]);
|
||||
}
|
||||
|
||||
vigem_target_x360_update(client, pad[0], state[0]);
|
||||
vigem_target_x360_update(client, pad[1], state[1]);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Light related outputs
|
||||
|
||||
if (config.enable_keylight) {
|
||||
iidx_io_ep1_set_deck_lights(keys);
|
||||
iidx_io_ep1_set_panel_lights(panel);
|
||||
}
|
||||
|
||||
if (config.enable_cab_light_seq) {
|
||||
bool neon;
|
||||
uint8_t spots;
|
||||
|
||||
neon = false;
|
||||
spots = 0;
|
||||
|
||||
vigem_iidxio_cab_light_sequencer_update(&neon, &spots);
|
||||
|
||||
iidx_io_ep1_set_top_neons(neon);
|
||||
iidx_io_ep1_set_top_lamps(spots);
|
||||
}
|
||||
|
||||
char buffer_16seg[9];
|
||||
|
||||
vigem_iidxio_cab_16seg_sequencer_update(buffer_16seg);
|
||||
iidx_io_ep3_write_16seg(buffer_16seg);
|
||||
|
||||
if (!iidx_io_ep1_send()) {
|
||||
log_warning("iidxio sending failed");
|
||||
break;
|
||||
}
|
||||
|
||||
if (_check_key(system, IIDX_IO_SYS_TEST) &&
|
||||
_check_key(system, IIDX_IO_SYS_SERVICE)) {
|
||||
log_info("Test + service pressed, exiting...");
|
||||
loop = false;
|
||||
}
|
||||
|
||||
// avoid banging
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
// Cleanup, turn all lights off
|
||||
iidx_io_ep1_set_deck_lights(0);
|
||||
iidx_io_ep1_set_panel_lights(0);
|
||||
iidx_io_ep1_set_top_lamps(0);
|
||||
iidx_io_ep1_set_top_neons(false);
|
||||
|
||||
iidx_io_ep1_send();
|
||||
// Required to handle iidxio-ezusb specific quirks with flushing 16seg text
|
||||
iidx_io_ep2_recv();
|
||||
iidx_io_ep3_write_16seg(" ");
|
||||
|
||||
Sleep(10);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
vigem_target_remove(client, pad[i]);
|
||||
vigem_target_free(pad[i]);
|
||||
}
|
||||
|
||||
vigem_free(client);
|
||||
|
||||
Sleep(1000);
|
||||
|
||||
iidx_io_fini();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user