Skip to content

Commit

Permalink
Added left / right trigger deadzone & adjustment
Browse files Browse the repository at this point in the history
Similarly to the analog stick deadzone adjustment, the trigger deadzone
is adjusted by a unique button combination (LT/RT)+LS+RT+D-Pad Up/Dn.
The current values are displayed in the context menu. I implemented this
using the same 2-D (XY) deadZoneCalc() function for the analog sticks
with one of the dimensions ignored by passing it a NULL *y_outand 0 for
the input y value.
  • Loading branch information
skajacore committed May 23, 2020
1 parent c74db61 commit 8b68d6c
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 24 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ By default this button combination will be enabled, but if desired you can easil
(right now you'll have to disable the combination manually each time XB2X is ran, but hopefully in future we can store your preference somewhere instead)

#### Deadzone settings
Similar to the Guide button emulation, through the use of the LT+RT+(LS/RS)+DPAD Up/Dn, the deadzone can be set individually on controllers. The current deadzones will be displayed in the context menu each time it is displayed (not live updating). For example, to increase the left analog stick deadzone radius use the button combination LT+RT+LS+DPAD Up (Keep pressing DPAD Up while holding LT+RT+LS to increase by increments of 500). A setting of 3500-4000 works well on my XBOX Controller v2 (US), but ymmv. Xb2XInput does remap the remaining useable range of the axes from origin to max extent. To disable the deadzone button combination, deselect the option through the system tray menu. The deadzone will remain active if the button combination is disabled.
Similarly to the Guide button emulation, use the LT+RT+(LS/RS)+DPAD Up/Dn combinaiton for analog stick deadzone and (LT/RT)+LS+RS+DPAD Up/Dn for trigger deadzone adjustment. The deadzone may be set individually on each controller. The current deadzones will be displayed in the context menu each time it is displayed (not live updating). For example, to increase the left analog stick deadzone radius use the button combination LT+RT+LS+DPAD Up (Keep pressing DPAD Up while holding LT+RT+LS to increase by increments of 500). A setting of 3500-4000 works well on my XBOX Controller v2 (US), but ymmv. Xb2XInput does remap the remaining useable range of the axes from origin to max extent. To disable the deadzone button combination, deselect the option through the system tray menu. The deadzone will remain active if the button combination is disabled.

(right now you'll have to set the deadzone manually each time XB2X is ran, but hopefully in future we can store your preference somewhere instead)

Expand Down
19 changes: 10 additions & 9 deletions Xb2XInput/Xb2XInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ int poll_ms = (1000 / min(1000, poll_rate));
// LT + RT + LS + RS to emulate guide button
bool guideCombinationEnabled = true;

// LT + RT + (LS | RS) + D-Pad Up/Down
// Analog Stick and Trigger Deadzone Adjustment Enabled
bool deadzoneCombinationEnabled = true;

// Vibration support
Expand Down Expand Up @@ -171,27 +171,28 @@ void SysTrayShowContextMenu()
InsertMenu(hPopMenu, 0xFFFFFFFF, MF_BYPOSITION | MF_STRING | MF_GRAYED, ID_TRAY_CONTROLLER + i, ctl_text);
i++;
}

InsertMenu(hPopMenu, 0xFFFFFFFF, MF_SEPARATOR, ID_TRAY_SEP, L"SEP");
InsertMenu(hPopMenu, 0xFFFFFFFF, MF_BYPOSITION | MF_STRING |
(guideCombinationEnabled ? MF_CHECKED : MF_UNCHECKED), ID_TRAY_GUIDEBTN, L"Enable guide button combination (LT+RT+LS+RS)");
InsertMenu(hPopMenu, 0xFFFFFFFF, MF_BYPOSITION | MF_STRING |
(vibrationEnabled ? MF_CHECKED : MF_UNCHECKED), ID_TRAY_VIBING, L"Enable controller vibration");
InsertMenu(hPopMenu, 0xFFFFFFFF, MF_BYPOSITION | MF_STRING |
(StartupIsSet() ? MF_CHECKED : MF_UNCHECKED), ID_TRAY_STARTUP, L"Run on startup");
InsertMenu(hPopMenu, 0xFFFFFFFF, MF_SEPARATOR, ID_TRAY_SEP, L"SEP");
InsertMenu(hPopMenu, 0xFFFFFFFF, MF_BYPOSITION | MF_STRING |
(deadzoneCombinationEnabled ? MF_CHECKED : MF_UNCHECKED), ID_TRAY_DEADZONE, L"Enable Deadzone Adjustment (LT+RT+(LS/RS)+DPAD Up/Dn)");
(deadzoneCombinationEnabled ? MF_CHECKED : MF_UNCHECKED), ID_TRAY_DEADZONE, L"Enable Deadzone Adjustment:");
InsertMenu(hPopMenu, 0xFFFFFFFF, MF_BYPOSITION | MF_STRING | MF_GRAYED | MF_UNCHECKED, ID_TRAY_DEADZONE, L" - Analog Stick (LT+RT+(LS/RS)+DPAD Up/Dn)");
InsertMenu(hPopMenu, 0xFFFFFFFF, MF_BYPOSITION | MF_STRING | MF_GRAYED | MF_UNCHECKED, ID_TRAY_DEADZONE, L" - Trigger ((LT/RT)+LS+RS+DPAD Up/Dn)");

// Insert current deadzone adjustments into context menu
i = 0;
for (auto& controller : pads) {
i++;
auto dz = controller.GetDeadzone();
swprintf_s(ctl_text, L"Deadzone %d: L(%d) R(%d)",i, dz.sThumbL, dz.sThumbR);
swprintf_s(ctl_text, L"Deadzone %d: LS(%d) RS(%d) LT(%d) RT(%d)",i, dz.sThumbL, dz.sThumbR, dz.bLeftTrigger, dz.bRightTrigger);
InsertMenu(hPopMenu, 0xFFFFFFFF, MF_BYPOSITION | MF_STRING | MF_GRAYED, ID_TRAY_DEADZONE+i, ctl_text);
}

InsertMenu(hPopMenu, 0xFFFFFFFF, MF_SEPARATOR, ID_TRAY_SEP, L"SEP");
InsertMenu(hPopMenu, 0xFFFFFFFF, MF_BYPOSITION | MF_STRING |
(vibrationEnabled ? MF_CHECKED : MF_UNCHECKED), ID_TRAY_VIBING, L"Enable controller vibration");
InsertMenu(hPopMenu, 0xFFFFFFFF, MF_BYPOSITION | MF_STRING |
(StartupIsSet() ? MF_CHECKED : MF_UNCHECKED), ID_TRAY_STARTUP, L"Run on startup");
InsertMenu(hPopMenu, 0xFFFFFFFF, MF_SEPARATOR, ID_TRAY_SEP, L"SEP");
InsertMenu(hPopMenu, 0xFFFFFFFF, MF_BYPOSITION | MF_STRING, ID_TRAY_EXIT, L"Exit");

Expand Down
62 changes: 48 additions & 14 deletions Xb2XInput/XboxController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ libusb_device_handle* XboxController::OpenDevice()
if (exists)
continue;

ret = libusb_open_device_with_vid_pid(NULL, desc.idVendor, desc.idProduct);
if (!ret)
// open USB device by libusb_device* returned from device list
if (libusb_open(devs[i],&ret))
continue;

auto controller = XboxController(ret, (uint8_t*)&usb_ports, num_ports);
Expand Down Expand Up @@ -307,6 +307,15 @@ int XboxController::GetUserIndex() {
int XboxController::deadZoneCalc(short *x_out, short *y_out, short x, short y, short deadzone, short sickzone){
// Returns 0 if in deadzone, 1 in sickzone, 2 if passthrough.

// Protect from NULL input pointers (used for 1-D deadzone)
short dummyvar;
if (!x_out){
x_out = &dummyvar;
}
if (!y_out){
y_out = &dummyvar;
}

short status;

// If no deadzone, pass directly through.
Expand Down Expand Up @@ -418,43 +427,60 @@ bool XboxController::update()
gamepad_.wButtons |= input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_WHITE] ? XUSB_GAMEPAD_LEFT_SHOULDER : 0;
gamepad_.wButtons |= input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_BLACK] ? XUSB_GAMEPAD_RIGHT_SHOULDER : 0;

// Copy over remaining analog values
gamepad_.bLeftTrigger = input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_LEFT_TRIGGER];
gamepad_.bRightTrigger = input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_RIGHT_TRIGGER];

// Secret guide combination: LT + RT + LS + RS
extern bool guideCombinationEnabled;
if(guideCombinationEnabled)
if ((input_prev_.Gamepad.wButtons & OGXINPUT_GAMEPAD_LEFT_THUMB) && (input_prev_.Gamepad.wButtons & OGXINPUT_GAMEPAD_RIGHT_THUMB) &&
(gamepad_.bLeftTrigger >= 0x8) && (gamepad_.bRightTrigger >= 0x8))
(input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_LEFT_TRIGGER] >= 0x8) && (input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_RIGHT_TRIGGER] >= 0x8))
{
gamepad_.wButtons |= XUSB_GAMEPAD_GUIDE;

// Clear combination from the emulated pad, don't want it to interfere with guide:
gamepad_.wButtons &= ~XUSB_GAMEPAD_LEFT_THUMB;
gamepad_.wButtons &= ~XUSB_GAMEPAD_RIGHT_THUMB;
gamepad_.bLeftTrigger = 0;
gamepad_.bRightTrigger = 0;
input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_LEFT_TRIGGER] = 0;
input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_RIGHT_TRIGGER] = 0;
}

// Secret Deadzone combination: (LT + RT + (LS | RS) + D-Pad Up/Down
// Secret Deadzone Adjustment Combinations:
extern bool deadzoneCombinationEnabled;
if(deadzoneCombinationEnabled){

// Analog Stick Deadzone Adjustment: LT + RT + (LS | RS) + D-Pad Up/Down
if ((input_prev_.Gamepad.wButtons & OGXINPUT_GAMEPAD_LEFT_THUMB) ^ (input_prev_.Gamepad.wButtons & OGXINPUT_GAMEPAD_RIGHT_THUMB) && // // (LS XOR RS) AND
((gamepad_.bLeftTrigger >= 0x8) && (gamepad_.bRightTrigger >= 0x8)) && // Left and Right Trigger AND
((input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_LEFT_TRIGGER] >= 0x8) && (input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_RIGHT_TRIGGER] >= 0x8)) && // Left and Right Trigger AND
(input_prev_.Gamepad.wButtons & (OGXINPUT_GAMEPAD_DPAD_UP | OGXINPUT_GAMEPAD_DPAD_DOWN))) // Direction to change deadzone
{
// wait for previous deadzone adjustment button release
if (!deadzone_.hold){
short adjustment = (input_prev_.Gamepad.wButtons & OGXINPUT_GAMEPAD_DPAD_UP ? 500 : -500);

if (input_prev_.Gamepad.wButtons & OGXINPUT_GAMEPAD_LEFT_THUMB){
deadzone_.sThumbL = max(deadzone_.sThumbL+adjustment,0);
deadzone_.sThumbL = min(max(deadzone_.sThumbL+adjustment,0), SHRT_MAX);
}
if (input_prev_.Gamepad.wButtons & OGXINPUT_GAMEPAD_RIGHT_THUMB){
deadzone_.sThumbR = max(deadzone_.sThumbR+adjustment,0);
deadzone_.sThumbR = min(max(deadzone_.sThumbR+adjustment,0), SHRT_MAX);
}

// wait for button release
deadzone_.hold = true;
}

// Trigger Deadzone Adjustment: (LT | RT) + LS + RS + D-Pad Up/Down
} else if ((input_prev_.Gamepad.wButtons & OGXINPUT_GAMEPAD_LEFT_THUMB) && (input_prev_.Gamepad.wButtons & OGXINPUT_GAMEPAD_RIGHT_THUMB) && // // (LS && RS) AND
((input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_LEFT_TRIGGER] >= 0x8) ^ (input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_RIGHT_TRIGGER] >= 0x8)) && // Left XOR Right Trigger AND
(input_prev_.Gamepad.wButtons & (OGXINPUT_GAMEPAD_DPAD_UP | OGXINPUT_GAMEPAD_DPAD_DOWN))) // Direction to change deadzone
{
if(!deadzone_.hold){
short adjustment = (input_prev_.Gamepad.wButtons & OGXINPUT_GAMEPAD_DPAD_UP ? 15 : -15);

if (input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_LEFT_TRIGGER]){
deadzone_.bLeftTrigger = min(max(deadzone_.bLeftTrigger+adjustment,0), 0xFF);
}
if (input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_RIGHT_TRIGGER]){
deadzone_.bRightTrigger = min(max(deadzone_.bRightTrigger+adjustment,0), 0xFF);
}

// wait for button release
deadzone_.hold = true;
}
Expand All @@ -463,10 +489,18 @@ bool XboxController::update()
deadzone_.hold = false;
}
}


// Analog Stick Deadzone Calculations
deadZoneCalc(&gamepad_.sThumbLX, &gamepad_.sThumbLY, input_prev_.Gamepad.sThumbLX, input_prev_.Gamepad.sThumbLY, deadzone_.sThumbL, SHRT_MAX);
deadZoneCalc(&gamepad_.sThumbRX, &gamepad_.sThumbRY, input_prev_.Gamepad.sThumbRX, input_prev_.Gamepad.sThumbRY, deadzone_.sThumbR, SHRT_MAX);

// Trigger Deadzone Calculations
short triggerbuf;
deadZoneCalc(&triggerbuf, NULL, input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_LEFT_TRIGGER], 0, deadzone_.bLeftTrigger, 0xFF);
gamepad_.bLeftTrigger = triggerbuf;
deadZoneCalc(&triggerbuf, NULL, input_prev_.Gamepad.bAnalogButtons[OGXINPUT_GAMEPAD_RIGHT_TRIGGER], 0, deadzone_.bRightTrigger, 0xFF);
gamepad_.bRightTrigger = triggerbuf;

// Write gamepad to virtual XInput device
vigem_target_x360_update(vigem, target_, gamepad_);

Expand Down
2 changes: 2 additions & 0 deletions Xb2XInput/XboxController.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ struct XboxOutputReport {
struct Deadzone {
short sThumbL;
short sThumbR;
BYTE bLeftTrigger;
BYTE bRightTrigger;
bool hold;
};

Expand Down

0 comments on commit 8b68d6c

Please sign in to comment.