Add support for up to 16bit and signed axis values

This commit is contained in:
patters-match 2024-10-26 20:28:15 +01:00
parent a4d1c16c8c
commit bd4bdd5210
7 changed files with 351 additions and 60 deletions

46
Adaptoid_N64.ini Normal file
View File

@ -0,0 +1,46 @@
// Wish Technologies Adaptoid N64-to-USB-HID converter
// Must be mapped to GamePad for the buffering to work properly (not to a Pro Controller)
[vid=0x06F7,pid=0x0001]
// A / B / L / R buttons
VPAD_BUTTON_A = 0x03, 0x01
// VPAD_BUTTON_B = 0x03, 0x08
VPAD_BUTTON_X = 0x03, 0x08 // Wii U SM64 port uses X rather than B
VPAD_BUTTON_L = 0x03, 0x40
VPAD_BUTTON_R = 0x03, 0x80
// N64 Start button mapped to Wii U + button
VPAD_BUTTON_PLUS = 0x04, 0x01
// N64 Z trigger mapped to Wii U ZL trigger
VPAD_BUTTON_ZL = 0x04, 0x02
// N64 C buttons mapped to Wii U right stick
VPAD_R_STICK_UP = 0x03, 0x20
VPAD_R_STICK_DOWN = 0x03, 0x02
VPAD_R_STICK_LEFT = 0x03, 0x10
VPAD_R_STICK_RIGHT = 0x03, 0x04
// N64 Dpad mapped to Wii U Dpad
VPAD_BUTTON_UP = 0x04, 0x04
VPAD_BUTTON_DOWN = 0x04, 0x08
VPAD_BUTTON_LEFT = 0x04, 0x10
VPAD_BUTTON_RIGHT = 0x04, 0x20
// N64 Stick mapped to Wii U Left Stick
VPad_L_Stick_X = 0x00, 0x00
// VPad_L_Stick_X_Default_MSB = 0x00 // Most significant byte - not needed, since zero
VPad_L_Stick_X_Bit_Length = 0x0C // 12bit HID axis report
VPad_L_Stick_X_Signed = True // Range includes negative values
VPad_L_Stick_X_MinMax = 0x50, 0xB0 // -1200 to 1200 expressed as s16 type (two's complement, i.e. 0xFB50 to 0x04B0)
VPad_L_Stick_X_MinMax_MSB = 0xFB, 0x04 // Most significant bytes
VPad_L_Stick_Y = 0x01, 0x00
// VPad_L_Stick_Y_Default_MSB = 0x00
VPad_L_Stick_Y_Bit_Length = 0x0C
VPad_L_Stick_Y_Bit_Offset = 0x04 // Second 12bit stick axis report is not byte-aligned
VPad_L_Stick_Y_Signed = True
VPad_L_Stick_Y_MinMax = 0x50, 0xB0
VPad_L_Stick_Y_MinMax_MSB = 0xFB, 0x04
VPad_L_Stick_Y_Invert = True
VPad_L_Stick_X_Deadzone = 0x20 // Customize for your controller wear state
VPad_L_Stick_Y_Deadzone = 0x20

View File

@ -111,7 +111,7 @@ public:
static CONTROLLER_PATCHER_RESULT_OR_ERROR UpdateSamplingFunctionAddress(); static CONTROLLER_PATCHER_RESULT_OR_ERROR UpdateSamplingFunctionAddress();
/** /**
Disbale the Controller mapping. Afterwards all connected controllers will be used for the gamepad. Disable the Controller mapping. Afterwards all connected controllers will be used for the gamepad.
@return When the functions failed result < 0 is returned. If the result is == 0 the function was successful. @return When the functions failed result < 0 is returned. If the result is == 0 the function was successful.
**/ **/
static CONTROLLER_PATCHER_RESULT_OR_ERROR disableControllerMapping(); static CONTROLLER_PATCHER_RESULT_OR_ERROR disableControllerMapping();
@ -173,7 +173,7 @@ public:
static BOOL isControllerConnectedAndActive(UController_Type type, int32_t mapping_slot = 0); static BOOL isControllerConnectedAndActive(UController_Type type, int32_t mapping_slot = 0);
/** /**
Search for a connected mouse and returns a pointer to it's data. Search for a connected mouse and returns a pointer to its data.
@return A pointer to the first connected mouse that is found. NULL if no mouse is connected. @return A pointer to the first connected mouse that is found. NULL if no mouse is connected.
**/ **/
static HID_Mouse_Data *getMouseData(); static HID_Mouse_Data *getMouseData();
@ -241,7 +241,7 @@ public:
static CONTROLLER_PATCHER_RESULT_OR_ERROR setKPADConnectedCallback(int32_t chan, WPADConnectCallback callback); static CONTROLLER_PATCHER_RESULT_OR_ERROR setKPADConnectedCallback(int32_t chan, WPADConnectCallback callback);
static CONTROLLER_PATCHER_RESULT_OR_ERROR setKPADExtensionCallback(int32_t chan, WPADConnectCallback callback); static CONTROLLER_PATCHER_RESULT_OR_ERROR setKPADExtensionCallback(int32_t chan, WPADExtensionCallback callback);
static CONTROLLER_PATCHER_RESULT_OR_ERROR setWPADConnectCallback(int32_t chan, WPADConnectCallback callback); static CONTROLLER_PATCHER_RESULT_OR_ERROR setWPADConnectCallback(int32_t chan, WPADConnectCallback callback);

View File

@ -196,6 +196,29 @@ enum Controller_Patcher_Settings {
CONTRPS_PAD4_FILTER, //! CONTRPS_PAD4_FILTER, //!
CONTRPS_PAD5_FILTER, //! CONTRPS_PAD5_FILTER, //!
CONTRPS_MOUSE_STICK, CONTRPS_MOUSE_STICK,
/* Additions for multi-byte stick encoding */
CONTRPS_VPAD_BUTTON_L_STICK_X_BIT_LENGTH, //! 8 / 12 / 16bits, code defaults to 8
CONTRPS_VPAD_BUTTON_L_STICK_Y_BIT_LENGTH,
CONTRPS_VPAD_BUTTON_R_STICK_X_BIT_LENGTH,
CONTRPS_VPAD_BUTTON_R_STICK_Y_BIT_LENGTH,
CONTRPS_VPAD_BUTTON_L_STICK_X_BIT_OFFSET, //! Data may not be byte-aligned
CONTRPS_VPAD_BUTTON_L_STICK_Y_BIT_OFFSET,
CONTRPS_VPAD_BUTTON_R_STICK_X_BIT_OFFSET,
CONTRPS_VPAD_BUTTON_R_STICK_Y_BIT_OFFSET,
CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX_MSB, //! MinMax most significant bytes for >8 bit length values
CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX_MSB,
CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX_MSB,
CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX_MSB,
CONTRPS_VPAD_BUTTON_L_STICK_X_DEFAULT_MSB, //! Stick default value most significant byte for >8 bit length values
CONTRPS_VPAD_BUTTON_L_STICK_Y_DEFAULT_MSB,
CONTRPS_VPAD_BUTTON_R_STICK_X_DEFAULT_MSB,
CONTRPS_VPAD_BUTTON_R_STICK_Y_DEFAULT_MSB,
CONTRPS_VPAD_BUTTON_L_STICK_X_SIGNED, //! Is the data signed (two's complement)?
CONTRPS_VPAD_BUTTON_L_STICK_Y_SIGNED,
CONTRPS_VPAD_BUTTON_R_STICK_X_SIGNED,
CONTRPS_VPAD_BUTTON_R_STICK_Y_SIGNED,
CONTRPS_MAX_VALUE CONTRPS_MAX_VALUE
}; };
/** /**

View File

@ -1166,7 +1166,7 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setKPADConnectedCallback(i
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setKPADExtensionCallback(int32_t chan, WPADConnectCallback callback) { CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcher::setKPADExtensionCallback(int32_t chan, WPADExtensionCallback callback) {
if (chan >= 4) { if (chan >= 4) {
return CONTROLLER_PATCHER_ERROR_INVALID_CHAN; return CONTROLLER_PATCHER_ERROR_INVALID_CHAN;
} }

View File

@ -259,6 +259,28 @@ private:
CONTPRStringToValueSingle["VPAD_R_STICK_X_INVERT"] = CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT; CONTPRStringToValueSingle["VPAD_R_STICK_X_INVERT"] = CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT;
CONTPRStringToValueSingle["VPAD_R_STICK_Y_INVERT"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT; CONTPRStringToValueSingle["VPAD_R_STICK_Y_INVERT"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT;
/* Additions for multi-byte stick encoding */
CONTPRStringToValueSingle["VPAD_L_STICK_X_BIT_LENGTH"] = CONTRPS_VPAD_BUTTON_L_STICK_X_BIT_LENGTH;
CONTPRStringToValueSingle["VPAD_L_STICK_Y_BIT_LENGTH"] = CONTRPS_VPAD_BUTTON_L_STICK_Y_BIT_LENGTH;
CONTPRStringToValueSingle["VPAD_R_STICK_X_BIT_LENGTH"] = CONTRPS_VPAD_BUTTON_R_STICK_X_BIT_LENGTH;
CONTPRStringToValueSingle["VPAD_R_STICK_Y_BIT_LENGTH"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_BIT_LENGTH;
CONTPRStringToValueSingle["VPAD_L_STICK_X_BIT_OFFSET"] = CONTRPS_VPAD_BUTTON_L_STICK_X_BIT_OFFSET;
CONTPRStringToValueSingle["VPAD_L_STICK_Y_BIT_OFFSET"] = CONTRPS_VPAD_BUTTON_L_STICK_Y_BIT_OFFSET;
CONTPRStringToValueSingle["VPAD_R_STICK_X_BIT_OFFSET"] = CONTRPS_VPAD_BUTTON_R_STICK_X_BIT_OFFSET;
CONTPRStringToValueSingle["VPAD_R_STICK_Y_BIT_OFFSET"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_BIT_OFFSET;
CONTPRStringToValue["VPAD_L_STICK_X_MINMAX_MSB"] = CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX_MSB;
CONTPRStringToValue["VPAD_L_STICK_Y_MINMAX_MSB"] = CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX_MSB;
CONTPRStringToValue["VPAD_R_STICK_X_MINMAX_MSB"] = CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX_MSB;
CONTPRStringToValue["VPAD_R_STICK_Y_MINMAX_MSB"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX_MSB;
CONTPRStringToValueSingle["VPAD_L_STICK_X_DEFAULT_MSB"] = CONTRPS_VPAD_BUTTON_L_STICK_X_DEFAULT_MSB;
CONTPRStringToValueSingle["VPAD_L_STICK_Y_DEFAULT_MSB"] = CONTRPS_VPAD_BUTTON_L_STICK_Y_DEFAULT_MSB;
CONTPRStringToValueSingle["VPAD_R_STICK_X_DEFAULT_MSB"] = CONTRPS_VPAD_BUTTON_R_STICK_X_DEFAULT_MSB;
CONTPRStringToValueSingle["VPAD_R_STICK_Y_DEFAULT_MSB"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_DEFAULT_MSB;
CONTPRStringToValueSingle["VPAD_L_STICK_X_SIGNED"] = CONTRPS_VPAD_BUTTON_L_STICK_X_SIGNED;
CONTPRStringToValueSingle["VPAD_L_STICK_Y_SIGNED"] = CONTRPS_VPAD_BUTTON_L_STICK_Y_SIGNED;
CONTPRStringToValueSingle["VPAD_R_STICK_X_SIGNED"] = CONTRPS_VPAD_BUTTON_R_STICK_X_SIGNED;
CONTPRStringToValueSingle["VPAD_R_STICK_Y_SIGNED"] = CONTRPS_VPAD_BUTTON_R_STICK_Y_SIGNED;
CONTPRStringToValueSingle["DOUBLE_USE"] = CONTRPS_DOUBLE_USE; CONTPRStringToValueSingle["DOUBLE_USE"] = CONTRPS_DOUBLE_USE;
CONTPRStringToValueSingle["PAD_COUNT"] = CONTRPS_PAD_COUNT; CONTPRStringToValueSingle["PAD_COUNT"] = CONTRPS_PAD_COUNT;

View File

@ -362,6 +362,17 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::getActivePad(uint32_t
* Stick functions * Stick functions
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
int16_t ControllerPatcherUtils::signExtendValue(uint16_t input, uint8_t bit_length) {
// Check if the input is negative in its original bit length
if (input & (1 << (bit_length - 1))) {
// Sign-extend the value
return (int16_t)(input | (~((1 << bit_length) - 1)));
} else {
// Input is non-negative; return it directly with proper casting
return (int16_t)input;
}
}
CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::normalizeStickValues(VPADVec2D *stick) { CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::normalizeStickValues(VPADVec2D *stick) {
if (stick == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER; if (stick == NULL) return CONTROLLER_PATCHER_ERROR_NULL_POINTER;
@ -390,30 +401,24 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::normalizeStickValues(
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }
float ControllerPatcherUtils::convertAnalogValue(uint8_t value, uint8_t default_val, uint8_t min, uint8_t max, uint8_t invert, uint8_t deadzone) { float ControllerPatcherUtils::convertAnalogValue(int32_t value, int32_t default_val, int32_t min, int32_t max, uint8_t invert, uint8_t deadzone){
int8_t new_value = (int8_t) (value - default_val); if(value >= max) return invert == 0x01 ? -1.0f : 1.0f;
uint8_t range = 0; if(value <= min) return invert == 0x01 ? 1.0f : -1.0f;
if (value >= max) {
if (invert == 0x01) return -1.0f; int32_t range = 0;
return 1.0f; int32_t adjustedValue = value - default_val;
} else if (value <= min) {
if (invert == 0x01) return 1.0f; if(std::abs(adjustedValue) <= (int32_t)deadzone) return 0.0f;
return -1.0f;
} if(adjustedValue > 0) {
if ((value - deadzone) > default_val) { range = max - (default_val + deadzone);
new_value -= deadzone; adjustedValue -= deadzone;
range = (max - (default_val + deadzone));
} else if ((value + deadzone) < default_val) {
new_value += deadzone;
range = ((default_val - deadzone) - min);
} else { } else {
return 0.0f; range = (default_val - deadzone) - min;
} adjustedValue += deadzone;
if (invert != 0x01) {
return (new_value / (1.0f * range));
} else {
return -1.0f * (new_value / (1.0f * range));
} }
float normalizedValue = (float)adjustedValue / range;
return invert == 0x01 ? -normalizedValue : normalizedValue;
} }
VPADVec2D ControllerPatcherUtils::getAnalogValueByButtons(uint8_t stick_values) { VPADVec2D ControllerPatcherUtils::getAnalogValueByButtons(uint8_t stick_values) {
@ -488,58 +493,216 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::convertAnalogSticks(H
int32_t deadzone = 0; int32_t deadzone = 0;
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][0] != CONTROLLER_PATCHER_INVALIDVALUE) { uint16_t l_stick_x_axis_input = 0;
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET) { uint16_t l_stick_y_axis_input = 0;
uint16_t r_stick_x_axis_input = 0;
uint16_t r_stick_y_axis_input = 0;
int16_t l_stick_x_axis_signed = 0;
int16_t l_stick_y_axis_signed = 0;
int16_t r_stick_x_axis_signed = 0;
int16_t r_stick_y_axis_signed = 0;
uint16_t l_stick_x_axis_min = 0;
uint16_t l_stick_x_axis_max = 0;
uint16_t l_stick_x_axis_def = 0;
uint16_t l_stick_y_axis_min = 0;
uint16_t l_stick_y_axis_max = 0;
uint16_t l_stick_y_axis_def = 0;
uint16_t r_stick_x_axis_min = 0;
uint16_t r_stick_x_axis_max = 0;
uint16_t r_stick_x_axis_def = 0;
uint16_t r_stick_y_axis_min = 0;
uint16_t r_stick_y_axis_max = 0;
uint16_t r_stick_y_axis_def = 0;
if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][0] != CONTROLLER_PATCHER_INVALIDVALUE){
if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET){
deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE][1]; deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEADZONE][1];
} }
// Read 1st byte of axis HID data & Min/Max/Default values
l_stick_x_axis_input = cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][0]];
l_stick_x_axis_min = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX][0];
l_stick_x_axis_max = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX][1];
l_stick_x_axis_def = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][1];
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_BIT_LENGTH][0] == CONTROLLER_PATCHER_VALUE_SET && config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_BIT_LENGTH][1] > 8){
// Need more than 8 bits, read 2nd byte of axis HID data
l_stick_x_axis_input |= (cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][0] + 1] << 8);
buffer->leftStick.x += convertAnalogValue(cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][0]], if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_BIT_OFFSET][0] == CONTROLLER_PATCHER_VALUE_SET){
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][1], // Shift right to trim unwanted leading bits
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX][0], l_stick_x_axis_input >>= config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_BIT_OFFSET][1];
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX][1], }
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT][1], // Mask off unwanted trailing bits
deadzone); l_stick_x_axis_input &= ((1 << config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_BIT_LENGTH][1]) - 1);
// Combine most significant bytes of Min/Max/Default values
l_stick_x_axis_min |= (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX_MSB][0] << 8);
l_stick_x_axis_max |= (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_MINMAX_MSB][1] << 8);
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEFAULT_MSB][0] == CONTROLLER_PATCHER_VALUE_SET){
l_stick_x_axis_def |= (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_DEFAULT_MSB][1] << 8);
}
}
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_SIGNED][1]) {
// Extend sign bits if axis HID data is signed
l_stick_x_axis_signed = signExtendValue(l_stick_x_axis_input, config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_BIT_LENGTH][1]);
buffer->leftStick.x += convertAnalogValue(l_stick_x_axis_signed,
(int16_t)l_stick_x_axis_def,
(int16_t)l_stick_x_axis_min,
(int16_t)l_stick_x_axis_max,
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT][1],
deadzone);
} else {
buffer->leftStick.x += convertAnalogValue(l_stick_x_axis_input,
l_stick_x_axis_def,
l_stick_x_axis_min,
l_stick_x_axis_max,
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_INVERT][1],
deadzone);
}
} }
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][0] != CONTROLLER_PATCHER_INVALIDVALUE) { if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][0] != CONTROLLER_PATCHER_INVALIDVALUE){
deadzone = 0; deadzone = 0;
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET) { if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET){
deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE][1]; deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEADZONE][1];
} }
buffer->leftStick.y += convertAnalogValue(cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][0]], // Read 1st byte of axis HID data & Min/Max/Default values
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][1], l_stick_y_axis_input = cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][0]];
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX][0], l_stick_y_axis_min = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX][0];
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX][1], l_stick_y_axis_max = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX][1];
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT][1], l_stick_y_axis_def = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][1];
deadzone);
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_BIT_LENGTH][0] == CONTROLLER_PATCHER_VALUE_SET && config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_BIT_LENGTH][1] > 8){
// Need more than 8 bits, read 2nd byte of axis HID data
l_stick_y_axis_input |= (cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][0] + 1] << 8);
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_BIT_OFFSET][0] == CONTROLLER_PATCHER_VALUE_SET){
// Shift right to trim unwanted leading bits
l_stick_y_axis_input >>= config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_BIT_OFFSET][1];
}
// Mask off unwanted trailing bits
l_stick_y_axis_input &= ((1 << config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_BIT_LENGTH][1]) - 1);
// Combine most significant bytes of Min/Max/Default values
l_stick_y_axis_min |= (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX_MSB][0] << 8);
l_stick_y_axis_max |= (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_MINMAX_MSB][1] << 8);
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEFAULT_MSB][0] == CONTROLLER_PATCHER_VALUE_SET){
l_stick_y_axis_def |= (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_DEFAULT_MSB][1] << 8);
}
}
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_SIGNED][1]) {
// Extend sign bits if axis HID data is signed
l_stick_y_axis_signed = signExtendValue(l_stick_y_axis_input, config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_BIT_LENGTH][1]);
buffer->leftStick.y += convertAnalogValue(l_stick_y_axis_signed,
(int16_t)l_stick_y_axis_def,
(int16_t)l_stick_y_axis_min,
(int16_t)l_stick_y_axis_max,
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT][1],
deadzone);
} else {
buffer->leftStick.y += convertAnalogValue(l_stick_y_axis_input,
l_stick_y_axis_def,
l_stick_y_axis_min,
l_stick_y_axis_max,
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y_INVERT][1],
deadzone);
}
} }
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][0] != CONTROLLER_PATCHER_INVALIDVALUE) { if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][0] != CONTROLLER_PATCHER_INVALIDVALUE){
deadzone = 0; deadzone = 0;
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET) { if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET){
deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE][1]; deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEADZONE][1];
} }
// Read 1st byte of axis HID data & Min/Max/Default values
r_stick_x_axis_input = cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][0]];
r_stick_x_axis_min = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX][0];
r_stick_x_axis_max = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX][1];
r_stick_x_axis_def = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][1];
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_BIT_LENGTH][0] == CONTROLLER_PATCHER_VALUE_SET && config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_BIT_LENGTH][1] > 8){
// Need more than 8 bits, read 2nd byte of axis HID data
r_stick_x_axis_input |= (cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][0] + 1] << 8);
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_BIT_OFFSET][0] == CONTROLLER_PATCHER_VALUE_SET){
// Shift right to trim unwanted leading bits
r_stick_x_axis_input >>= config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_BIT_OFFSET][1];
}
// Mask off unwanted trailing bits
r_stick_x_axis_input &= ((1 << config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_BIT_LENGTH][1]) - 1);
buffer->rightStick.x += convertAnalogValue(cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][0]], // Combine most significant bytes of Min/Max/Default values
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][1], r_stick_x_axis_min |= (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX_MSB][0] << 8);
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX][0], r_stick_x_axis_max |= (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX_MSB][1] << 8);
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_MINMAX][1], if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEFAULT_MSB][0] == CONTROLLER_PATCHER_VALUE_SET){
r_stick_x_axis_def |= (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_DEFAULT_MSB][1] << 8);
}
}
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_SIGNED][1]) {
// Extend sign bits if axis HID data is signed
r_stick_x_axis_signed = signExtendValue(r_stick_x_axis_input, config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_BIT_LENGTH][1]);
buffer->rightStick.x += convertAnalogValue(r_stick_x_axis_signed,
(int16_t)r_stick_x_axis_def,
(int16_t)r_stick_x_axis_min,
(int16_t)r_stick_x_axis_max,
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT][1], config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT][1],
deadzone); deadzone);
} else {
buffer->rightStick.x += convertAnalogValue(r_stick_x_axis_input,
r_stick_x_axis_def,
r_stick_x_axis_min,
r_stick_x_axis_max,
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X_INVERT][1],
deadzone);
}
} }
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][0] != CONTROLLER_PATCHER_INVALIDVALUE) { if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][0] != CONTROLLER_PATCHER_INVALIDVALUE){
deadzone = 0; deadzone = 0;
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET) { if(config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE][0] == CONTROLLER_PATCHER_VALUE_SET){
deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE][1]; deadzone = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEADZONE][1];
} }
// Read 1st byte of axis HID data & Min/Max/Default values
r_stick_y_axis_input = cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][0]];
r_stick_y_axis_min = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX][0];
r_stick_y_axis_max = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX][1];
r_stick_y_axis_def = config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][1];
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_BIT_LENGTH][0] == CONTROLLER_PATCHER_VALUE_SET && config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_BIT_LENGTH][1] > 8){
// Need more than 8 bits, read 2nd byte of axis HID data
r_stick_y_axis_input |= (cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][0] + 1] << 8);
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_BIT_OFFSET][0] == CONTROLLER_PATCHER_VALUE_SET){
// Shift right to trim unwanted leading bits
r_stick_y_axis_input >>= config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_BIT_OFFSET][1];
}
// Mask off unwanted trailing bits
r_stick_y_axis_input &= ((1 << config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_BIT_LENGTH][1]) - 1);
buffer->rightStick.y += convertAnalogValue(cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][0]], // Combine most significant bytes of Min/Max/Default values
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][1], r_stick_y_axis_min |= (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX_MSB][0] << 8);
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX][0], r_stick_y_axis_max |= (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX_MSB][1] << 8);
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_MINMAX][1], if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEFAULT_MSB][0] == CONTROLLER_PATCHER_VALUE_SET){
r_stick_y_axis_def |= (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_DEFAULT_MSB][1] << 8);
}
}
if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_SIGNED][1]) {
// Extend sign bits if axis HID data is signed
r_stick_y_axis_signed = signExtendValue(r_stick_y_axis_input, config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_BIT_LENGTH][1]);
buffer->rightStick.y += convertAnalogValue(r_stick_y_axis_signed,
(int16_t)r_stick_y_axis_def,
(int16_t)r_stick_y_axis_min,
(int16_t)r_stick_y_axis_max,
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT][1], config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT][1],
deadzone); deadzone);
} else {
buffer->rightStick.y += convertAnalogValue(r_stick_y_axis_input,
r_stick_y_axis_def,
r_stick_y_axis_min,
r_stick_y_axis_max,
config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y_INVERT][1],
deadzone);
}
} }
uint8_t stick_values = 0; uint8_t stick_values = 0;
@ -632,10 +795,38 @@ CONTROLLER_PATCHER_RESULT_OR_ERROR ControllerPatcherUtils::convertAnalogSticks(H
} }
} }
/*log_printf("LX %f(%02X) LY %f(%02X) RX %f(%02X) RY %f(%02X)",buffer->leftStick.x,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X][0]], // if (config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_X_SIGNED][1]) {
buffer->leftStick.y,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_L_STICK_Y][0]], // int16_t temp_l_stick_x_axis_min = (int16_t)l_stick_x_axis_min;
buffer->rightStick.x,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_X][0]], // int16_t temp_l_stick_y_axis_min = (int16_t)l_stick_y_axis_min;
buffer->rightStick.y,cur_data[config_controller[deviceslot][CONTRPS_VPAD_BUTTON_R_STICK_Y][0]]);*/ // int16_t temp_l_stick_x_axis_def = (int16_t)l_stick_x_axis_def;
// int16_t temp_l_stick_y_axis_def = (int16_t)l_stick_y_axis_def;
// int16_t temp_l_stick_x_axis_max = (int16_t)l_stick_x_axis_max;
// int16_t temp_l_stick_y_axis_max = (int16_t)l_stick_y_axis_max;
// log_printf(
// "MinX %+5d %04X DefX %+5d MaxX %+5d %04X MinY %+5d %04X DefY %+5d MaxY %+5d %04X X %+1.3f(%+5d %04X) Y %+1.3f(%+5d %04X)\n",
// temp_l_stick_x_axis_min,l_stick_x_axis_min,
// temp_l_stick_x_axis_def,
// temp_l_stick_x_axis_max,l_stick_x_axis_max,
// temp_l_stick_y_axis_min,l_stick_y_axis_min,
// temp_l_stick_y_axis_def,
// temp_l_stick_y_axis_max,l_stick_y_axis_max,
// buffer->leftStick.x,l_stick_x_axis_signed,l_stick_x_axis_signed,
// buffer->leftStick.y,l_stick_y_axis_signed,l_stick_y_axis_signed
// );
// } else {
// log_printf(
// "MinX %+5d %04X DefX %+5d MaxX %+5d %04X MinY %+5d %04X DefY %+5d MaxY %+5d %04X X %+1.3f(%+5d %04X) Y %+1.3f(%+5d %04X)\n",
// l_stick_x_axis_min,l_stick_x_axis_min,
// l_stick_x_axis_def,
// l_stick_x_axis_max,l_stick_x_axis_max,
// l_stick_y_axis_min,l_stick_y_axis_min,
// l_stick_y_axis_def,
// l_stick_y_axis_max,l_stick_y_axis_max,
// buffer->leftStick.x,l_stick_x_axis_input,l_stick_x_axis_input,
// buffer->leftStick.y,l_stick_y_axis_input,l_stick_y_axis_input
// );
// }
} }
return CONTROLLER_PATCHER_ERROR_NONE; return CONTROLLER_PATCHER_ERROR_NONE;
} }

View File

@ -167,6 +167,16 @@ private:
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- /*----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Stick functions * Stick functions
*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ *---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
/**
\brief Sign-extend negative numbers of lower bit lengths into int16_t type
\param input Input value (from HID data)
\param bit_length Bit length of this input number
\return The number in int16_t type
**/
static int16_t signExtendValue(uint16_t input, uint8_t bit_length);
/** /**
\brief Normalizes the stick to valid values. \brief Normalizes the stick to valid values.
@ -188,8 +198,7 @@ private:
\return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful. \return When the functions failed result < 0 is returned. If the result is >= 0 the function was successful.
**/ **/
static float convertAnalogValue(uint8_t value, uint8_t default_val, uint8_t min, uint8_t max, uint8_t invert, uint8_t deadzone); static float convertAnalogValue(int32_t value, int32_t default_val, int32_t min, int32_t max, uint8_t invert,uint8_t deadzone);
/** /**
\brief Calculates a the stick data (VPADVec2D) from given digital direction. \brief Calculates a the stick data (VPADVec2D) from given digital direction.