vigem-sdvxio: Add implementation
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
exes += vigem-sdvxio
|
||||
|
||||
deplibs_vigem-sdvxio := \
|
||||
ViGEmClient \
|
||||
|
||||
cppflags_vigem-sdvxio := \
|
||||
-I src/imports \
|
||||
|
||||
ldflags_vigem-sdvxio := \
|
||||
-lsetupapi \
|
||||
|
||||
libs_vigem-sdvxio := \
|
||||
cconfig \
|
||||
sdvxio \
|
||||
util \
|
||||
vigemstub \
|
||||
|
||||
src_vigem-sdvxio := \
|
||||
main.c \
|
||||
config-vigem-sdvxio.c \
|
||||
@@ -0,0 +1,128 @@
|
||||
#include "cconfig/cconfig-main.h"
|
||||
#include "cconfig/cconfig-util.h"
|
||||
|
||||
#include "vigem-sdvxio/config-vigem-sdvxio.h"
|
||||
|
||||
#include "util/log.h"
|
||||
|
||||
#define VIGEM_SDVXIO_CONFIG_ENABLE_KEYLIGHT_KEY "sdvxio.enable_keylight"
|
||||
#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_PWM_WINGS_VALUE 128
|
||||
#define VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_CONTROLLER_VALUE 64
|
||||
#define VIGEM_SDVXIO_CONFIG_DEFAULT_AMP_VOLUME_VALUE 48
|
||||
|
||||
void vigem_sdvxio_config_init(struct cconfig *config)
|
||||
{
|
||||
cconfig_util_set_bool(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_ENABLE_KEYLIGHT_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE,
|
||||
"Enable input based key lighting");
|
||||
|
||||
cconfig_util_set_int(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_PWM_WINGS_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_WINGS_VALUE,
|
||||
"Brightness to set wings to (0-255)");
|
||||
|
||||
cconfig_util_set_int(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_PWM_CONTROLLER_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_CONTROLLER_VALUE,
|
||||
"Brightness to set control deck to (0-255)");
|
||||
|
||||
cconfig_util_set_int(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_AMP_VOLUME_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_AMP_VOLUME_VALUE,
|
||||
"SDVXIO digital amp volume (0-96) 0 is high, 96 is low.");
|
||||
}
|
||||
|
||||
void vigem_sdvxio_config_get(
|
||||
struct vigem_sdvxio_config *vigem_config, struct cconfig *config)
|
||||
{
|
||||
if (!cconfig_util_get_bool(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_ENABLE_KEYLIGHT_KEY,
|
||||
&vigem_config->enable_keylight,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%d'",
|
||||
VIGEM_SDVXIO_CONFIG_ENABLE_KEYLIGHT_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_ENABLE_KEYLIGHT_VALUE);
|
||||
}
|
||||
|
||||
if (!cconfig_util_get_int(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_PWM_WINGS_KEY,
|
||||
&vigem_config->pwm_wings,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_WINGS_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%d'",
|
||||
VIGEM_SDVXIO_CONFIG_PWM_WINGS_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_WINGS_VALUE);
|
||||
}
|
||||
|
||||
if (!cconfig_util_get_int(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_PWM_CONTROLLER_KEY,
|
||||
&vigem_config->pwm_controller,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_CONTROLLER_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%d'",
|
||||
VIGEM_SDVXIO_CONFIG_PWM_CONTROLLER_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_PWM_CONTROLLER_VALUE);
|
||||
}
|
||||
|
||||
if (!cconfig_util_get_int(
|
||||
config,
|
||||
VIGEM_SDVXIO_CONFIG_AMP_VOLUME_KEY,
|
||||
&vigem_config->amp_volume,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_AMP_VOLUME_VALUE)) {
|
||||
log_warning(
|
||||
"Invalid value for key '%s' specified, fallback "
|
||||
"to default '%d'",
|
||||
VIGEM_SDVXIO_CONFIG_AMP_VOLUME_KEY,
|
||||
VIGEM_SDVXIO_CONFIG_DEFAULT_AMP_VOLUME_VALUE);
|
||||
}
|
||||
}
|
||||
|
||||
void get_vigem_sdvxio_config(struct vigem_sdvxio_config *config_out)
|
||||
{
|
||||
struct cconfig *config;
|
||||
|
||||
config = cconfig_init();
|
||||
|
||||
vigem_sdvxio_config_init(config);
|
||||
|
||||
if (!cconfig_main_config_init(
|
||||
config,
|
||||
"--config",
|
||||
"vigem-sdvxio.conf",
|
||||
"--help",
|
||||
"-h",
|
||||
"vigem-sdvxio",
|
||||
CCONFIG_CMD_USAGE_OUT_STDOUT)) {
|
||||
cconfig_finit(config);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
vigem_sdvxio_config_get(config_out, config);
|
||||
|
||||
cconfig_finit(config);
|
||||
|
||||
if (config_out->pwm_controller > 255) {
|
||||
config_out->pwm_controller = 255;
|
||||
}
|
||||
|
||||
if (config_out->pwm_wings > 255) {
|
||||
config_out->pwm_wings = 255;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef VIGEM_SDVXIO_CONFIG_H
|
||||
#define VIGEM_SDVXIO_CONFIG_H
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "cconfig/cconfig.h"
|
||||
|
||||
struct vigem_sdvxio_config {
|
||||
bool enable_keylight;
|
||||
int32_t pwm_wings;
|
||||
int32_t pwm_controller;
|
||||
int32_t amp_volume;
|
||||
};
|
||||
|
||||
void get_vigem_sdvxio_config(struct vigem_sdvxio_config *config_out);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,183 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Xinput.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "ViGEm/Client.h"
|
||||
|
||||
#include "bemanitools/sdvxio.h"
|
||||
#include "util/log.h"
|
||||
#include "util/thread.h"
|
||||
#include "vigemstub/helper.h"
|
||||
|
||||
#include "vigem-sdvxio/config-vigem-sdvxio.h"
|
||||
|
||||
int64_t convert_analog_to_s16(uint16_t val)
|
||||
{
|
||||
// val is 10 bit
|
||||
return (int64_t)(val * 64);
|
||||
}
|
||||
|
||||
bool check_key(uint16_t input, size_t idx_in)
|
||||
{
|
||||
if ((input >> idx_in) & 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
uint16_t check_assign_gpio(uint16_t input, size_t idx_in, size_t gpio_out)
|
||||
{
|
||||
if (check_key(input, idx_in)) {
|
||||
return 1 << gpio_out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gpio_keylight(uint16_t gpio0, uint16_t gpio1)
|
||||
{
|
||||
uint16_t gpio_lights = 0;
|
||||
|
||||
gpio_lights |= check_assign_gpio(
|
||||
gpio0, SDVX_IO_IN_GPIO_0_START, SDVX_IO_OUT_GPIO_START);
|
||||
gpio_lights |=
|
||||
check_assign_gpio(gpio0, SDVX_IO_IN_GPIO_0_A, SDVX_IO_OUT_GPIO_A);
|
||||
gpio_lights |=
|
||||
check_assign_gpio(gpio0, SDVX_IO_IN_GPIO_0_B, SDVX_IO_OUT_GPIO_B);
|
||||
gpio_lights |=
|
||||
check_assign_gpio(gpio0, SDVX_IO_IN_GPIO_0_C, SDVX_IO_OUT_GPIO_C);
|
||||
gpio_lights |=
|
||||
check_assign_gpio(gpio1, SDVX_IO_IN_GPIO_1_D, SDVX_IO_OUT_GPIO_D);
|
||||
gpio_lights |=
|
||||
check_assign_gpio(gpio1, SDVX_IO_IN_GPIO_1_FX_L, SDVX_IO_OUT_GPIO_FX_L);
|
||||
gpio_lights |=
|
||||
check_assign_gpio(gpio1, SDVX_IO_IN_GPIO_1_FX_R, SDVX_IO_OUT_GPIO_FX_R);
|
||||
|
||||
sdvx_io_set_gpio_lights(gpio_lights);
|
||||
}
|
||||
|
||||
void set_pwm_brightness(uint8_t wing_pwm, uint8_t controller_pwm)
|
||||
{
|
||||
// 0-11 are the 4 wings
|
||||
for (size_t i = 0; i < 12; ++i) {
|
||||
sdvx_io_set_pwm_light(i, wing_pwm);
|
||||
}
|
||||
// 12-17 are the woofer / control deck
|
||||
for (size_t i = 12; i < 18; ++i) {
|
||||
sdvx_io_set_pwm_light(i, controller_pwm);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
log_to_writer(log_writer_stdout, NULL);
|
||||
|
||||
struct vigem_sdvxio_config config;
|
||||
get_vigem_sdvxio_config(&config);
|
||||
|
||||
sdvx_io_set_loggers(
|
||||
log_impl_misc, log_impl_info, log_impl_warning, log_impl_fatal);
|
||||
|
||||
if (!sdvx_io_init(crt_thread_create, crt_thread_join, crt_thread_destroy)) {
|
||||
log_warning("Initializing sdvxio failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool loop = true;
|
||||
|
||||
uint8_t sys;
|
||||
uint16_t gpio0;
|
||||
uint16_t gpio1;
|
||||
uint16_t vol[2] = {0, 0};
|
||||
|
||||
XUSB_REPORT state;
|
||||
|
||||
log_info("vigem init succeeded, beginnning poll loop");
|
||||
while (loop) {
|
||||
sdvx_io_read_input();
|
||||
|
||||
sys = sdvx_io_get_input_gpio_sys();
|
||||
gpio0 = sdvx_io_get_input_gpio(0);
|
||||
gpio1 = sdvx_io_get_input_gpio(1);
|
||||
|
||||
vol[0] = sdvx_io_get_spinner_pos(0);
|
||||
vol[1] = sdvx_io_get_spinner_pos(1);
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
|
||||
state.sThumbLX = convert_analog_to_s16(vol[0]);
|
||||
state.sThumbRX = convert_analog_to_s16(vol[1]);
|
||||
|
||||
state.wButtons |= check_assign_key(
|
||||
gpio0, SDVX_IO_IN_GPIO_0_START, XUSB_GAMEPAD_START);
|
||||
state.wButtons |=
|
||||
check_assign_key(sys, SDVX_IO_IN_GPIO_SYS_TEST, XUSB_GAMEPAD_BACK);
|
||||
state.wButtons |=
|
||||
check_assign_key(gpio0, SDVX_IO_IN_GPIO_0_A, XUSB_GAMEPAD_A);
|
||||
state.wButtons |=
|
||||
check_assign_key(gpio0, SDVX_IO_IN_GPIO_0_B, XUSB_GAMEPAD_B);
|
||||
state.wButtons |=
|
||||
check_assign_key(gpio0, SDVX_IO_IN_GPIO_0_C, XUSB_GAMEPAD_X);
|
||||
state.wButtons |=
|
||||
check_assign_key(gpio1, SDVX_IO_IN_GPIO_1_D, XUSB_GAMEPAD_Y);
|
||||
state.wButtons |= check_assign_key(
|
||||
gpio1, SDVX_IO_IN_GPIO_1_FX_L, XUSB_GAMEPAD_LEFT_SHOULDER);
|
||||
state.wButtons |= check_assign_key(
|
||||
gpio1, SDVX_IO_IN_GPIO_1_FX_R, XUSB_GAMEPAD_RIGHT_SHOULDER);
|
||||
|
||||
vigem_target_x360_update(client, pad, state);
|
||||
|
||||
if (config.enable_keylight) {
|
||||
gpio_keylight(gpio0, gpio1);
|
||||
}
|
||||
|
||||
set_pwm_brightness(config.pwm_wings, config.pwm_controller);
|
||||
sdvx_io_write_output();
|
||||
|
||||
if (check_key(sys, SDVX_IO_IN_GPIO_SYS_TEST) &&
|
||||
check_key(sys, SDVX_IO_IN_GPIO_SYS_SERVICE)) {
|
||||
loop = false;
|
||||
}
|
||||
|
||||
// avoid banging
|
||||
Sleep(1);
|
||||
}
|
||||
|
||||
vigem_target_remove(client, pad);
|
||||
vigem_target_free(pad);
|
||||
|
||||
sdvx_io_set_amp_volume(96, 96, 96);
|
||||
Sleep(1000);
|
||||
|
||||
sdvx_io_fini();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
libs += vigemstub
|
||||
imps += ViGEmClient
|
||||
|
||||
cppflags_vigemstub := \
|
||||
-I src/imports \
|
||||
|
||||
libs_vigemstub := \
|
||||
|
||||
src_vigemstub := \
|
||||
helper.c \
|
||||
|
||||
# This is a dummy module so that the client only gets import libraries generated once
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "ViGEm/Client.h"
|
||||
|
||||
#include "vigemstub/helper.h"
|
||||
|
||||
PVIGEM_CLIENT vigem_helper_setup(void)
|
||||
{
|
||||
PVIGEM_CLIENT client = vigem_alloc();
|
||||
|
||||
if (client == NULL) {
|
||||
printf("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);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
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");
|
||||
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);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pad;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef VIGEMSTUB_HELPER_H
|
||||
#define VIGEMSTUB_HELPER_H
|
||||
|
||||
#include "ViGEm/Client.h"
|
||||
|
||||
PVIGEM_CLIENT vigem_helper_setup();
|
||||
PVIGEM_TARGET vigem_helper_add_pad(PVIGEM_CLIENT client);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user