Skip to content

Commit

Permalink
Improvements and fixes for Nintendo Switch controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
r57zone committed Dec 14, 2024
1 parent 62b7a6c commit bfbfd40
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 29 deletions.
8 changes: 4 additions & 4 deletions README.RU.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
Для изменения яркости 2 раза нажмите на область яркости. Если изменение яркости заблокировано, то подстветка будет выключаться по двойному клику.


Кнопка `PS` открывает "Xbox Game Bar" (нажимая `Win + G`), `PS + □` - уменьшить громкость, `PS + ○` - увеличить громкость, `PS + △` - увеличивает, а затем уменьшает чувствительность прицеливания (сброс на `PS + R3`), `PS + X` - кнопка микрофона (скриншот / нажатие сконфигурированной кнопки клавиатуры).
Кнопка `PS` или `Capture + Home` открывает "Xbox Game Bar" (нажимая `Win + G`), `PS + □` или `CAPTURE + Y` - уменьшить громкость, `PS + ○` или `PS + A` - увеличить громкость, `PS + △` или `CAPTURE + X` - увеличивает, а затем уменьшает чувствительность прицеливания (сброс на `PS + R3` или `CAPTURE + R3`), `PS + X` или `CAPTURE + B` - кнопка микрофона (скриншот или нажатие сконфигурированной кнопки клавиатуры).


По умолчанию кнопка микрофона делает скриншот `Win + Alt + PrtScr` (для DualShock 4 нажимаем `PS + X`). Изменив параметр `MicCustomKey` на [нужное значение кнопки](https://github.com/r57zone/DSAdvance/blob/master/BINDINGS.RU.md) будет производится её нажатие.
По умолчанию кнопка микрофона делает скриншот `Win + Alt + PrtScr` (для DualShock 4 `PS + X`, а для Nintendo контроллеров `CAPTURE + B`). Изменив параметр `MicCustomKey` на [нужное значение кнопки](https://github.com/r57zone/DSAdvance/blob/master/BINDINGS.RU.md) будет производится её нажатие.


Для эмуляции клавиатуры и мыши, для старых игр, переключите режим работы на `ALT + Q` или `PS + ←` и `PS + →` и выберите нужный профиль или [создайте новый профиль](https://github.com/r57zone/DSAdvance/blob/master/BINDINGS.RU.md). Профили переключаются на клавиши `ALT + ↑` и `ALT + ↓`, если окно активно или на геймпаде, с помощью `PS + ↑` и `PS + ↓`. Профиль по умолчанию позволяет работать в Windows.
Для эмуляции клавиатуры и мыши, для старых игр, переключите режим работы на `ALT + Q` или `PS + ←` и `PS + →`, или `HOME + ←` и `HOME + →`, и выберите нужный профиль или [создайте новый профиль](https://github.com/r57zone/DSAdvance/blob/master/BINDINGS.RU.md). Профили переключаются на клавиши `ALT + ↑` и `ALT + ↓`, если окно активно или на геймпаде, с помощью `PS + ↑` и `PS + ↓` или `HOME + ↑` и `HOME + ↓`. Профиль по умолчанию позволяет работать в Windows.


Для подключения [внешних педалей (DInput)](https://github.com/r57zone/XboxExternalPedals#setup-dinput-pedals-mh-et-live-board) измените параметр `DInput` на `1`, в разделе `ExternalPedals`. Для поключения [внешних педалей на Arduino](https://github.com/r57zone/XboxExternalPedals#setup-arduino-pedals) измените номер COM-порта, изменив параметр `COMPort`.
Expand Down Expand Up @@ -63,7 +63,7 @@


**Не работают адаптивые триггеры или световая панель в игре**<br>
Добавьте игру в список исключений программы "HidHide" и изменить режим "DSAdvance" на "Only mouse".
Добавьте игру в список исключений программы "HidHide" и измените режим "DSAdvance" на "Only mouse".



Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ To exit the stick emulation mode on the touchpad, need to switch to the default
By clicking on the default profile on DualSense the white LEDs display the current battery status (1 - 0..25%, 2 - 26..50%, 3 - 51..75%, 4 - 76..100%), also on DualSense and DualShock 4 the battery status is shown on the lightbar (green - 100..30%, yellow - 29..10%, red - 9..1%), can be disabled in the config, parameter `ShowBatteryStatusOnLightBar`. For DualSense and DualShock 4 the current charge is displayed in the program itself.


The `PS` button opens the "Xbox Game Bar", `PS + □` - decrease the volume, `PS + ○` - increase the volume, `PS + △` - increases and then decreases aiming sensitivity (reset to `PS + R3`), `PS + X` - microphone button (screenshot / pressing configured keyboard button).
`PS` or `Capture + Home` button opens "Xbox Game Bar" (press `Win + G`), `PS + □` or `CAPTURE + Y` - decrease volume, `PS + ○` or `PS + A` - increase volume, `PS + △` or `CAPTURE + X` - increases and then decreases aiming sensitivity (reset to `PS + R3` or `CAPTURE + R3`), `PS + X` or `CAPTURE + B` - microphone button (screenshot or pressing configured keyboard button).


By default, the microphone button takes a screenshot of `Win + Alt + PrtScr` (for DualShock 4 press `PS + X`). By changing the `MicCustomKey` parameter to the [desired button value](https://github.com/r57zone/DSAdvance/blob/master/BINDINGS.md), it will be pressed.
By default, the microphone button takes a screenshot of `Win + Alt + PrtScr` (for DualShock 4 `PS + X`, and for Nintendo controllers `CAPTURE + B`). By changing the `MicCustomKey` parameter to the [desired button value](https://github.com/r57zone/DSAdvance/blob/master/BINDINGS.md), it will be pressed.


To emulate the keyboard and mouse for older games, switch the mode to `ALT + Q` or `PS + ←` and `PS + →` and select the desired profile or [create the desired profile](https://github.com/r57zone/DSAdvance/blob/master/BINDINGS.md). Profiles are switched to the `ALT + ↑` and `ALT + ↓` keys if the window is active or on a gamepad using `PS + ↑` and `PS + ↓`. The default profile allows to work in Windows.
To emulate keyboard and mouse, for old games, switch the operating mode to `ALT + Q` or `PS + ←` and `PS + →`, or `HOME + ←` and `HOME + →`, and select the desired profile or [create the desired profile](https://github.com/r57zone/DSAdvance/blob/master/BINDINGS.md). Profiles are switched to the `ALT + ↑` and `ALT + ↓` keys if the window is active or on a gamepad using `PS + ↑` and `PS + ↓` or `HOME + ↑` and `HOME + ↓`. The default profile allows to work in Windows.


To connect [external pedals (DInput)](https://github.com/r57zone/XboxExternalPedals#setup-dinput-pedals-mh-et-live-board), change the `DInput` parameter to `1`, in the `ExternalPedals` section. To connect [external pedals on Arduino](https://github.com/r57zone/XboxExternalPedals#setup-arduino-pedals), change the COM port number by changing the `COMPort` parameter.
Expand Down
85 changes: 63 additions & 22 deletions Source/DSAdvance/DSAdvance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ void ExternalPedalsDInputSearch() {
for (int JoyID = 0; JoyID < 4; ++JoyID) { // JOYSTICKID4 - 3
if (joyGetPosEx(JoyID, &AppStatus.ExternalPedalsJoyInfo) == JOYERR_NOERROR && // JoyID - JOYSTICKID1..4
joyGetDevCaps(JoyID, &AppStatus.ExternalPedalsJoyCaps, sizeof(AppStatus.ExternalPedalsJoyCaps)) == JOYERR_NOERROR &&
(AppStatus.ExternalPedalsJoyCaps.wMid != 1406 ||
(AppStatus.ExternalPedalsJoyCaps.wPid != 8198 && AppStatus.ExternalPedalsJoyCaps.wPid != 8199)) && // Exclude Pro Controller и JoyCon
AppStatus.ExternalPedalsJoyCaps.wNumButtons == 16) { // DualSense - 15, DigiJoy - 16
AppStatus.ExternalPedalsJoyIndex = JoyID;
AppStatus.ExternalPedalsDInputConnected = true;
Expand Down Expand Up @@ -525,7 +527,7 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

int main(int argc, char **argv)
{
SetConsoleTitle("DSAdvance 0.9.8");
SetConsoleTitle("DSAdvance 0.9.9");

WNDCLASS AppWndClass = {};
AppWndClass.lpfnWndProc = WindowProc;
Expand Down Expand Up @@ -699,16 +701,45 @@ int main(int argc, char **argv)
}

XUSB_REPORT_INIT(&report);
InputState = JslGetSimpleState(CurGamepad.deviceID[0]);

if (JslGetControllerType(CurGamepad.deviceID[0]) == JS_TYPE_DS || JslGetControllerType(CurGamepad.deviceID[0]) == JS_TYPE_DS4 || JslGetControllerType(CurGamepad.deviceID[0]) == JS_TYPE_PRO_CONTROLLER) {
InputState = JslGetSimpleState(CurGamepad.deviceID[0]);
MotionState = JslGetMotionState(CurGamepad.deviceID[0]);

} else if (JslGetControllerType(CurGamepad.deviceID[0]) == JS_TYPE_JOYCON_LEFT || JslGetControllerType(CurGamepad.deviceID[0]) == JS_TYPE_JOYCON_RIGHT) { // The state of the joycons is the same for both
memset(&InputState, 0, sizeof(JOY_SHOCK_STATE));
memset(&MotionState, 0, sizeof(MOTION_STATE));

for (int i = 0; i < AppStatus.ControllerCount; i++) {

if (JslGetControllerType(CurGamepad.deviceID[i]) != JS_TYPE_JOYCON_LEFT && JslGetControllerType(CurGamepad.deviceID[i]) != JS_TYPE_JOYCON_RIGHT) continue;
JOY_SHOCK_STATE tempState = JslGetSimpleState(CurGamepad.deviceID[i]);

InputState.buttons |= tempState.buttons;



if (JslGetControllerType(CurGamepad.deviceID[i]) == JS_TYPE_JOYCON_LEFT) {
InputState.stickLX = tempState.stickLX;
InputState.stickLY = tempState.stickLY;
InputState.lTrigger = tempState.lTrigger;
} else if (JslGetControllerType(CurGamepad.deviceID[i]) == JS_TYPE_JOYCON_RIGHT) {
MotionState = JslGetMotionState(CurGamepad.deviceID[i]);
InputState.stickRX = tempState.stickRX;
InputState.stickRY = tempState.stickRY;
InputState.rTrigger = tempState.rTrigger;
}
}
}

if (AppStatus.ControllerCount < 1) { // We do not process anything during idle time
//InputState = { 0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f };
report.sThumbLX = 1; // Maybe the crash is due to power saving? temporary test
ret = vigem_target_x360_update(client, x360, report); // Vigem always mode only
Sleep(AppStatus.SleepTimeOut);
continue;
}

MotionState = JslGetMotionState(CurGamepad.deviceID[0]);

MotionAngles = QuaternionToEulerAngle(MotionState.quatW, MotionState.quatZ, MotionState.quatX, MotionState.quatY);

// Stick dead zones
Expand Down Expand Up @@ -918,7 +949,7 @@ int main(int argc, char **argv)

report.bLeftTrigger = DeadZoneAxis(InputState.lTrigger, CurGamepad.Triggers.DeadZoneLeft) * 255;
report.bRightTrigger = DeadZoneAxis(InputState.rTrigger, CurGamepad.Triggers.DeadZoneRight) * 255;

// External pedals
if (AppStatus.ExternalPedalsDInputConnected) {
if (joyGetPosEx(AppStatus.ExternalPedalsJoyIndex, &AppStatus.ExternalPedalsJoyInfo) == JOYERR_NOERROR) {
Expand Down Expand Up @@ -946,7 +977,7 @@ int main(int argc, char **argv)
report.wButtons |= InputState.buttons & JSMASK_PLUS ? XINPUT_GAMEPAD_START : 0;
}

if (!(InputState.buttons & JSMASK_PS)) { // During special functions, nothing is pressed in the game
if (!(InputState.buttons & JSMASK_PS && InputState.buttons & JSMASK_CAPTURE && InputState.buttons & JSMASK_CAPTURE)) { // During special functions, nothing is pressed in the game
report.wButtons |= InputState.buttons & JSMASK_L ? XINPUT_GAMEPAD_LEFT_SHOULDER : 0;
report.wButtons |= InputState.buttons & JSMASK_R ? XINPUT_GAMEPAD_RIGHT_SHOULDER : 0;
if (AppStatus.LeftStickMode != LeftStickInvertPressMode) // Invert stick mode
Expand All @@ -968,27 +999,37 @@ int main(int argc, char **argv)
if (JslGetControllerType(CurGamepad.deviceID[0]) == JS_TYPE_PRO_CONTROLLER || JslGetControllerType(CurGamepad.deviceID[0]) == JS_TYPE_JOYCON_LEFT || JslGetControllerType(CurGamepad.deviceID[0]) == JS_TYPE_JOYCON_RIGHT) {
if (SkipPollCount == 0 && InputState.buttons & JSMASK_CAPTURE) { if (GamepadActionMode == 1) GamepadActionMode = 0; else { GamepadActionMode = 1; AnglesOffset = MotionAngles; } SkipPollCount = SkipPollTimeOut; }
if (SkipPollCount == 0 && InputState.buttons & JSMASK_HOME) { if (GamepadActionMode == 0 || GamepadActionMode == 1) GamepadActionMode = LastAIMProCtrlMode; else if (GamepadActionMode == 2) { GamepadActionMode = 3; LastAIMProCtrlMode = 3; } else { GamepadActionMode = 2; LastAIMProCtrlMode = 2; } SkipPollCount = SkipPollTimeOut; }
}

// Sony
} else {

// GameBar & multi keys
// PS without any keys
if (PSReleasedCount == 0 && InputState.buttons == JSMASK_PS) { PSOnlyCheckCount = 20; PSOnlyPressed = true; }
if (PSOnlyCheckCount > 0) {
if (PSOnlyCheckCount == 1 && PSOnlyPressed)
PSReleasedCount = PSReleasedTimeOut; // Timeout to release the PS button and don't execute commands
PSOnlyCheckCount--;
if (InputState.buttons != JSMASK_PS && InputState.buttons != 0) { PSOnlyPressed = false; PSOnlyCheckCount = 0; }
// GameBar & multi keys
// PS without any keys
if (PSReleasedCount == 0 && InputState.buttons == JSMASK_PS) { PSOnlyCheckCount = 20; PSOnlyPressed = true; }
if (PSOnlyCheckCount > 0) {
if (PSOnlyCheckCount == 1 && PSOnlyPressed)
PSReleasedCount = PSReleasedTimeOut; // Timeout to release the PS button and don't execute commands
PSOnlyCheckCount--;
if (InputState.buttons != JSMASK_PS && InputState.buttons != 0) { PSOnlyPressed = false; PSOnlyCheckCount = 0; }
}
if (InputState.buttons & JSMASK_PS && InputState.buttons != JSMASK_PS) PSReleasedCount = PSReleasedTimeOut; // printf("PS + any button\n"); }
if (PSReleasedCount > 0) PSReleasedCount--;
}

KeyPress(VK_GAMEBAR, (PSOnlyCheckCount == 1 && PSOnlyPressed) || (InputState.buttons & JSMASK_CAPTURE && InputState.buttons & JSMASK_HOME), &ButtonsStates.PS);

if (JslGetControllerType(CurGamepad.deviceID[0]) == JS_TYPE_PRO_CONTROLLER || JslGetControllerType(CurGamepad.deviceID[0]) == JS_TYPE_JOYCON_LEFT || JslGetControllerType(CurGamepad.deviceID[0]) == JS_TYPE_JOYCON_RIGHT) {
KeyPress(VK_VOLUME_DOWN2, InputState.buttons & JSMASK_CAPTURE && InputState.buttons & JSMASK_W, &ButtonsStates.VolumeDown);
KeyPress(VK_VOLUME_UP2, InputState.buttons & JSMASK_CAPTURE && InputState.buttons & JSMASK_E, &ButtonsStates.VolumeUP);
} else {
KeyPress(VK_VOLUME_DOWN2, InputState.buttons & JSMASK_PS && InputState.buttons & JSMASK_W, &ButtonsStates.VolumeDown);
KeyPress(VK_VOLUME_UP2, InputState.buttons & JSMASK_PS && InputState.buttons & JSMASK_E, &ButtonsStates.VolumeUP);
}
if (InputState.buttons & JSMASK_PS && InputState.buttons != JSMASK_PS) PSReleasedCount = PSReleasedTimeOut; // printf("PS + any button\n"); }
if (PSReleasedCount > 0) PSReleasedCount--;

KeyPress(VK_GAMEBAR, PSOnlyCheckCount == 1 && PSOnlyPressed, &ButtonsStates.PS);
KeyPress(VK_VOLUME_DOWN2, InputState.buttons & JSMASK_PS && InputState.buttons & JSMASK_W, &ButtonsStates.VolumeDown);
KeyPress(VK_VOLUME_UP2, InputState.buttons & JSMASK_PS && InputState.buttons & JSMASK_E, &ButtonsStates.VolumeUP);
KeyPress(AppStatus.ScreenShotKey, InputState.buttons & JSMASK_MIC || (InputState.buttons & JSMASK_PS && InputState.buttons & JSMASK_S), &ButtonsStates.Mic); // + DualShock 4
KeyPress(AppStatus.ScreenShotKey, InputState.buttons & JSMASK_MIC || ((InputState.buttons & JSMASK_PS || InputState.buttons & JSMASK_CAPTURE) && InputState.buttons & JSMASK_S), &ButtonsStates.Mic); // + DualShock 4

// Custom sens
if (SkipPollCount == 0 && InputState.buttons & JSMASK_PS && InputState.buttons & JSMASK_N) {
if (SkipPollCount == 0 && (InputState.buttons & JSMASK_PS || InputState.buttons & JSMASK_CAPTURE) && InputState.buttons & JSMASK_N) {
CurGamepad.Motion.CustomMulSens += 0.2;
if (CurGamepad.Motion.CustomMulSens > 2.4)
CurGamepad.Motion.CustomMulSens = 0.2;
Expand Down

0 comments on commit bfbfd40

Please sign in to comment.