mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2025-02-21 21:00:02 +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.
|
Thus, it allows you to use a real cab with *any* game that supports xinput.
|
||||||
|
|
||||||
# Setup
|
# 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:
|
* Place the following in the same folder as vigem-sdvxio:
|
||||||
* Get a copy of ViGEmClient.dll (https://bin.jvnv.net/file/ZgMJK/ViGEmClient.zip)
|
* Get a copy of [ViGEmClient.dll](https://bin.jvnv.net/file/ZgMJK/ViGEmClient.zip) (or from bemanitools-supplements)
|
||||||
* Rename your corresponding sdvxio-device.dll to sdvxio.dll.
|
* 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
|
* Run `vigem-sdvxio.exe` so that the config file gets created
|
||||||
* Edit vigem-sdvxio.conf so that the config file gets created as needed
|
* Edit `vigem-sdvxio.conf` so that the config file gets created as needed
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
* Run vigem-sdvxio.exe
|
* Run `vigem-sdvxio.exe`
|
||||||
* To quit the program, hit the TEST + SERVICE button at the same time
|
* To quit the program, hit the TEST + SERVICE button at the same time
|
||||||
|
|
||||||
# Mapping
|
# Mapping
|
||||||
* BT ABCD are mapped to ABXY
|
* BT ABCD are mapped to ABXY
|
||||||
* FX LR are mapped to LB/RB
|
* 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:
|
# 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)
|
* 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
|
* 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)
|
* 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"
|
#include "util/log.h"
|
||||||
|
|
||||||
#define VIGEM_SDVXIO_CONFIG_ENABLE_KEYLIGHT_KEY "sdvxio.enable_keylight"
|
#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_WINGS_KEY "sdvxio.pwm_wings"
|
||||||
#define VIGEM_SDVXIO_CONFIG_PWM_CONTROLLER_KEY "sdvxio.pwm_controller"
|
#define VIGEM_SDVXIO_CONFIG_PWM_CONTROLLER_KEY "sdvxio.pwm_controller"
|
||||||
#define VIGEM_SDVXIO_CONFIG_AMP_VOLUME_KEY "sdvxio.amp_volume"
|
#define VIGEM_SDVXIO_CONFIG_AMP_VOLUME_KEY "sdvxio.amp_volume"
|
||||||
|
|
||||||
#define VIGEM_SDVXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE true
|
#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_WINGS_VALUE 128
|
||||||
#define VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_CONTROLLER_VALUE 64
|
#define VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_CONTROLLER_VALUE 64
|
||||||
#define VIGEM_SDVXIO_CONFIG_DEFAULT_AMP_VOLUME_VALUE 48
|
#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,
|
VIGEM_SDVXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE,
|
||||||
"Enable input based key lighting");
|
"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(
|
cconfig_util_set_int(
|
||||||
config,
|
config,
|
||||||
VIGEM_SDVXIO_CONFIG_PWM_WINGS_KEY,
|
VIGEM_SDVXIO_CONFIG_PWM_WINGS_KEY,
|
||||||
@ -57,6 +65,18 @@ void vigem_sdvxio_config_get(
|
|||||||
VIGEM_SDVXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE);
|
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(
|
if (!cconfig_util_get_int(
|
||||||
config,
|
config,
|
||||||
VIGEM_SDVXIO_CONFIG_PWM_WINGS_KEY,
|
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;
|
struct cconfig *config;
|
||||||
|
|
||||||
@ -111,7 +131,7 @@ void get_vigem_sdvxio_config(struct vigem_sdvxio_config *config_out)
|
|||||||
"vigem-sdvxio",
|
"vigem-sdvxio",
|
||||||
CCONFIG_CMD_USAGE_OUT_STDOUT)) {
|
CCONFIG_CMD_USAGE_OUT_STDOUT)) {
|
||||||
cconfig_finit(config);
|
cconfig_finit(config);
|
||||||
exit(EXIT_FAILURE);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
vigem_sdvxio_config_get(config_out, config);
|
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) {
|
if (config_out->pwm_wings > 255) {
|
||||||
config_out->pwm_wings = 255;
|
config_out->pwm_wings = 255;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,12 @@
|
|||||||
|
|
||||||
struct vigem_sdvxio_config {
|
struct vigem_sdvxio_config {
|
||||||
bool enable_keylight;
|
bool enable_keylight;
|
||||||
|
bool relative_analog;
|
||||||
int32_t pwm_wings;
|
int32_t pwm_wings;
|
||||||
int32_t pwm_controller;
|
int32_t pwm_controller;
|
||||||
int32_t amp_volume;
|
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
|
#endif
|
@ -15,12 +15,74 @@
|
|||||||
|
|
||||||
#include "vigem-sdvxio/config-vigem-sdvxio.h"
|
#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
|
// val is 10 bit
|
||||||
return (int64_t)(val * 64);
|
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)
|
bool check_key(uint16_t input, size_t idx_in)
|
||||||
{
|
{
|
||||||
if ((input >> idx_in) & 1) {
|
if ((input >> idx_in) & 1) {
|
||||||
@ -87,7 +149,9 @@ int main(int argc, char **argv)
|
|||||||
log_to_writer(log_writer_stdout, NULL);
|
log_to_writer(log_writer_stdout, NULL);
|
||||||
|
|
||||||
struct vigem_sdvxio_config config;
|
struct vigem_sdvxio_config config;
|
||||||
get_vigem_sdvxio_config(&config);
|
if (!get_vigem_sdvxio_config(&config)) {
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
sdvx_io_set_loggers(
|
sdvx_io_set_loggers(
|
||||||
log_impl_misc, log_impl_info, log_impl_warning, log_impl_fatal);
|
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);
|
sdvx_io_set_amp_volume(config.amp_volume, config.amp_volume, config.amp_volume);
|
||||||
|
|
||||||
PVIGEM_CLIENT client = vigem_helper_setup();
|
PVIGEM_CLIENT client = vigem_helper_setup();
|
||||||
|
|
||||||
if (!client) {
|
if (!client) {
|
||||||
log_warning("client failed to connect failed");
|
log_warning("client failed to connect failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PVIGEM_TARGET pad = vigem_helper_add_pad(client);
|
PVIGEM_TARGET pad = vigem_helper_add_pad(client);
|
||||||
|
|
||||||
if (!pad) {
|
if (!pad) {
|
||||||
log_warning("vigem_alloc pad 1 failed");
|
log_warning("vigem_alloc pad 1 failed");
|
||||||
return -1;
|
return -1;
|
||||||
@ -117,10 +183,14 @@ int main(int argc, char **argv)
|
|||||||
uint16_t gpio0;
|
uint16_t gpio0;
|
||||||
uint16_t gpio1;
|
uint16_t gpio1;
|
||||||
uint16_t vol[2] = {0, 0};
|
uint16_t vol[2] = {0, 0};
|
||||||
|
uint16_t last_vol[2] = {0, 0};
|
||||||
|
|
||||||
|
int32_t buffered_vol[2] = {0, 0};
|
||||||
|
|
||||||
XUSB_REPORT state;
|
XUSB_REPORT state;
|
||||||
|
|
||||||
log_info("vigem init succeeded, beginning poll loop");
|
log_info("vigem init succeeded, beginning poll loop");
|
||||||
|
|
||||||
while (loop) {
|
while (loop) {
|
||||||
sdvx_io_read_input();
|
sdvx_io_read_input();
|
||||||
|
|
||||||
@ -133,8 +203,19 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
memset(&state, 0, sizeof(state));
|
memset(&state, 0, sizeof(state));
|
||||||
|
|
||||||
state.sThumbLX = convert_analog_to_s16(vol[0]);
|
if (config.relative_analog) {
|
||||||
state.sThumbRX = convert_analog_to_s16(vol[1]);
|
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(
|
state.wButtons |= check_assign_key(
|
||||||
gpio0, SDVX_IO_IN_GPIO_0_START, XUSB_GAMEPAD_START);
|
gpio0, SDVX_IO_IN_GPIO_0_START, XUSB_GAMEPAD_START);
|
||||||
|
@ -5,6 +5,7 @@ cppflags_vigemstub := \
|
|||||||
-I src/imports \
|
-I src/imports \
|
||||||
|
|
||||||
libs_vigemstub := \
|
libs_vigemstub := \
|
||||||
|
util \
|
||||||
|
|
||||||
src_vigemstub := \
|
src_vigemstub := \
|
||||||
helper.c \
|
helper.c \
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "ViGEm/Client.h"
|
#include "ViGEm/Client.h"
|
||||||
|
|
||||||
|
#include "util/log.h"
|
||||||
#include "vigemstub/helper.h"
|
#include "vigemstub/helper.h"
|
||||||
|
|
||||||
PVIGEM_CLIENT vigem_helper_setup(void)
|
PVIGEM_CLIENT vigem_helper_setup(void)
|
||||||
@ -11,14 +12,14 @@ PVIGEM_CLIENT vigem_helper_setup(void)
|
|||||||
PVIGEM_CLIENT client = vigem_alloc();
|
PVIGEM_CLIENT client = vigem_alloc();
|
||||||
|
|
||||||
if (client == NULL) {
|
if (client == NULL) {
|
||||||
printf("vigem_alloc failed\n");
|
log_warning("vigem_alloc failed\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
VIGEM_ERROR retval = vigem_connect(client);
|
VIGEM_ERROR retval = vigem_connect(client);
|
||||||
|
|
||||||
if (!VIGEM_SUCCESS(retval)) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,14 +31,14 @@ PVIGEM_TARGET vigem_helper_add_pad(PVIGEM_CLIENT client)
|
|||||||
PVIGEM_TARGET pad = vigem_target_x360_alloc();
|
PVIGEM_TARGET pad = vigem_target_x360_alloc();
|
||||||
|
|
||||||
if (pad == NULL) {
|
if (pad == NULL) {
|
||||||
printf("vigem_target_x360_alloc failed\n");
|
log_warning("vigem_target_x360_alloc failed\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
VIGEM_ERROR pir = vigem_target_add(client, pad);
|
VIGEM_ERROR pir = vigem_target_add(client, pad);
|
||||||
|
|
||||||
if (!VIGEM_SUCCESS(pir)) {
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user