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:
parent
4f3135439d
commit
a9ebc30ea7
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
@ -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);
|
||||
|
@ -5,6 +5,7 @@ cppflags_vigemstub := \
|
||||
-I src/imports \
|
||||
|
||||
libs_vigemstub := \
|
||||
util \
|
||||
|
||||
src_vigemstub := \
|
||||
helper.c \
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user