1
0
mirror of https://github.com/djhackersdev/bemanitools.git synced 2025-02-20 20:41:10 +01:00

vigem-sdvxio: Add relative mode and address comments

This commit is contained in:
Will Xyen 2020-09-26 18:46:17 -07:00
parent 4f3135439d
commit a9ebc30ea7
6 changed files with 126 additions and 21 deletions

View File

@ -1,24 +1,24 @@
This application allows you to use any sdvxio backend to drive an XB360 controller.
This application allows you to use any sdvxio backend, e.g. `sdvxio-kfca.dll`, to be available as a XBOX 360 game controller on windows.
Thus, it allows you to use a real cab with *any* game that supports xinput.
# Setup
* Install ViGEmBus (https://github.com/ViGEm/ViGEmBus/releases)
* Install [ViGEmBus](https://github.com/ViGEm/ViGEmBus/releases)
* Place the following in the same folder as vigem-sdvxio:
* Get a copy of ViGEmClient.dll (https://bin.jvnv.net/file/ZgMJK/ViGEmClient.zip)
* Rename your corresponding sdvxio-device.dll to sdvxio.dll.
* Run vigem-sdvxio.exe so that the config file gets created
* Edit vigem-sdvxio.conf so that the config file gets created as needed
* Get a copy of [ViGEmClient.dll](https://bin.jvnv.net/file/ZgMJK/ViGEmClient.zip) (or from bemanitools-supplements)
* Rename your corresponding `sdvxio-XXX.dll`, e.g. `sdvxio-kfca.dll`, to `sdvxio.dll`.
* Run `vigem-sdvxio.exe` so that the config file gets created
* Edit `vigem-sdvxio.conf` so that the config file gets created as needed
# Usage
* Run vigem-sdvxio.exe
* Run `vigem-sdvxio.exe`
* To quit the program, hit the TEST + SERVICE button at the same time
# Mapping
* BT ABCD are mapped to ABXY
* FX LR are mapped to LB/RB
* VOL LR are mapped to L/R thumbstick X
* VOL LR are mapped to L thumbstick X/Y (either in absolute or relative mode depending on the config)
# Additional Notes For Cabinets:
* Make sure that you follow the instructions exactly from the release page (Prerequisites for Windows 7)
# Additional Notes For Cabinets (Running on embedded Windows 7):
* Make sure that you follow the instructions exactly from the release page ([Prerequisites for Windows 7](https://github.com/ViGEm/ViGEmBus/wiki/Prerequisites-for-Windows-7))
* If you get an error while trying to install KB3033929, re-enable windows update
* Make sure to ewfmgr C: -commit and reboot after installing the drivers (this only needs to be done once)

View File

@ -6,11 +6,13 @@
#include "util/log.h"
#define VIGEM_SDVXIO_CONFIG_ENABLE_KEYLIGHT_KEY "sdvxio.enable_keylight"
#define VIGEM_SDVXIO_CONFIG_RELATIVE_ANALOG_KEY "sdvxio.use_relative_analog"
#define VIGEM_SDVXIO_CONFIG_PWM_WINGS_KEY "sdvxio.pwm_wings"
#define VIGEM_SDVXIO_CONFIG_PWM_CONTROLLER_KEY "sdvxio.pwm_controller"
#define VIGEM_SDVXIO_CONFIG_AMP_VOLUME_KEY "sdvxio.amp_volume"
#define VIGEM_SDVXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE true
#define VIGEM_SDVXIO_CONFIG_DEFAULT_RELATIVE_ANALOG_VALUE false
#define VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_WINGS_VALUE 128
#define VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_CONTROLLER_VALUE 64
#define VIGEM_SDVXIO_CONFIG_DEFAULT_AMP_VOLUME_VALUE 48
@ -23,6 +25,12 @@ void vigem_sdvxio_config_init(struct cconfig *config)
VIGEM_SDVXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE,
"Enable input based key lighting");
cconfig_util_set_bool(
config,
VIGEM_SDVXIO_CONFIG_RELATIVE_ANALOG_KEY,
VIGEM_SDVXIO_CONFIG_DEFAULT_RELATIVE_ANALOG_VALUE,
"Use relative mode analog mapping");
cconfig_util_set_int(
config,
VIGEM_SDVXIO_CONFIG_PWM_WINGS_KEY,
@ -57,6 +65,18 @@ void vigem_sdvxio_config_get(
VIGEM_SDVXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE);
}
if (!cconfig_util_get_bool(
config,
VIGEM_SDVXIO_CONFIG_RELATIVE_ANALOG_KEY,
&vigem_config->relative_analog,
VIGEM_SDVXIO_CONFIG_DEFAULT_RELATIVE_ANALOG_VALUE)) {
log_warning(
"Invalid value for key '%s' specified, fallback "
"to default '%d'",
VIGEM_SDVXIO_CONFIG_RELATIVE_ANALOG_KEY,
VIGEM_SDVXIO_CONFIG_DEFAULT_RELATIVE_ANALOG_VALUE);
}
if (!cconfig_util_get_int(
config,
VIGEM_SDVXIO_CONFIG_PWM_WINGS_KEY,
@ -94,7 +114,7 @@ void vigem_sdvxio_config_get(
}
}
void get_vigem_sdvxio_config(struct vigem_sdvxio_config *config_out)
bool get_vigem_sdvxio_config(struct vigem_sdvxio_config *config_out)
{
struct cconfig *config;
@ -111,7 +131,7 @@ void get_vigem_sdvxio_config(struct vigem_sdvxio_config *config_out)
"vigem-sdvxio",
CCONFIG_CMD_USAGE_OUT_STDOUT)) {
cconfig_finit(config);
exit(EXIT_FAILURE);
return false;
}
vigem_sdvxio_config_get(config_out, config);
@ -125,4 +145,5 @@ void get_vigem_sdvxio_config(struct vigem_sdvxio_config *config_out)
if (config_out->pwm_wings > 255) {
config_out->pwm_wings = 255;
}
return true;
}

View File

@ -7,11 +7,12 @@
struct vigem_sdvxio_config {
bool enable_keylight;
bool relative_analog;
int32_t pwm_wings;
int32_t pwm_controller;
int32_t amp_volume;
};
void get_vigem_sdvxio_config(struct vigem_sdvxio_config *config_out);
bool get_vigem_sdvxio_config(struct vigem_sdvxio_config *config_out);
#endif

View File

@ -15,12 +15,74 @@
#include "vigem-sdvxio/config-vigem-sdvxio.h"
int64_t convert_analog_to_s16(uint16_t val)
#define ANALOG_FIXED_SENSITIVITY 1024
int16_t convert_analog_to_s16(uint16_t val)
{
// val is 10 bit
return (int64_t)(val * 64);
}
int16_t get_relative_delta(int16_t val, int16_t last)
{
// val is 10 bit
const int16_t half_point = 512; // 2^9
int16_t delta = val - last;
if (delta > half_point) {
delta -= 1024;
}
if (delta < -half_point) {
delta += 1024;
}
// delta is now between (-512 - 512)
return delta;
}
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;
}
int32_t convert_relative_analog(
uint16_t val, uint16_t last, int32_t buffered_last, int16_t multiplier)
{
int16_t delta = get_relative_delta(val, last);
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;
}
}
bool check_key(uint16_t input, size_t idx_in)
{
if ((input >> idx_in) & 1) {
@ -87,7 +149,9 @@ int main(int argc, char **argv)
log_to_writer(log_writer_stdout, NULL);
struct vigem_sdvxio_config config;
get_vigem_sdvxio_config(&config);
if (!get_vigem_sdvxio_config(&config)) {
exit(EXIT_FAILURE);
}
sdvx_io_set_loggers(
log_impl_misc, log_impl_info, log_impl_warning, log_impl_fatal);
@ -100,12 +164,14 @@ int main(int argc, char **argv)
sdvx_io_set_amp_volume(config.amp_volume, config.amp_volume, config.amp_volume);
PVIGEM_CLIENT client = vigem_helper_setup();
if (!client) {
log_warning("client failed to connect failed");
return -1;
}
PVIGEM_TARGET pad = vigem_helper_add_pad(client);
if (!pad) {
log_warning("vigem_alloc pad 1 failed");
return -1;
@ -117,10 +183,14 @@ int main(int argc, char **argv)
uint16_t gpio0;
uint16_t gpio1;
uint16_t vol[2] = {0, 0};
uint16_t last_vol[2] = {0, 0};
int32_t buffered_vol[2] = {0, 0};
XUSB_REPORT state;
log_info("vigem init succeeded, beginning poll loop");
while (loop) {
sdvx_io_read_input();
@ -133,8 +203,19 @@ int main(int argc, char **argv)
memset(&state, 0, sizeof(state));
state.sThumbLX = convert_analog_to_s16(vol[0]);
state.sThumbRX = convert_analog_to_s16(vol[1]);
if (config.relative_analog) {
buffered_vol[0] = convert_relative_analog(vol[0], last_vol[0], buffered_vol[0], ANALOG_FIXED_SENSITIVITY);
buffered_vol[1] = convert_relative_analog(vol[1], last_vol[1], buffered_vol[1], ANALOG_FIXED_SENSITIVITY);
state.sThumbLX = filter_floor(buffered_vol[0], ANALOG_FIXED_SENSITIVITY/2);
state.sThumbLY = filter_floor(buffered_vol[1], ANALOG_FIXED_SENSITIVITY/2);
last_vol[0] = vol[0];
last_vol[1] = vol[1];
} else {
state.sThumbLX = convert_analog_to_s16(vol[0]);
state.sThumbLY = convert_analog_to_s16(vol[1]);
}
state.wButtons |= check_assign_key(
gpio0, SDVX_IO_IN_GPIO_0_START, XUSB_GAMEPAD_START);

View File

@ -5,6 +5,7 @@ cppflags_vigemstub := \
-I src/imports \
libs_vigemstub := \
util \
src_vigemstub := \
helper.c \

View File

@ -4,6 +4,7 @@
#include "ViGEm/Client.h"
#include "util/log.h"
#include "vigemstub/helper.h"
PVIGEM_CLIENT vigem_helper_setup(void)
@ -11,14 +12,14 @@ PVIGEM_CLIENT vigem_helper_setup(void)
PVIGEM_CLIENT client = vigem_alloc();
if (client == NULL) {
printf("vigem_alloc failed\n");
log_warning("vigem_alloc failed\n");
return NULL;
}
VIGEM_ERROR retval = vigem_connect(client);
if (!VIGEM_SUCCESS(retval)) {
printf("ViGEm Bus connection failed with error code: 0x%x\n", retval);
log_warning("ViGEm Bus connection failed with error code: 0x%x\n", retval);
return NULL;
}
@ -30,14 +31,14 @@ PVIGEM_TARGET vigem_helper_add_pad(PVIGEM_CLIENT client)
PVIGEM_TARGET pad = vigem_target_x360_alloc();
if (pad == NULL) {
printf("vigem_target_x360_alloc failed\n");
log_warning("vigem_target_x360_alloc failed\n");
return NULL;
}
VIGEM_ERROR pir = vigem_target_add(client, pad);
if (!VIGEM_SUCCESS(pir)) {
printf("Target plugin failed with error code: 0x%x\n", pir);
log_warning("Target plugin failed with error code: 0x%x\n", pir);
return NULL;
}