Skip to content

Commit 1dc4e13

Browse files
committed
Improvements: ability to move left stick on pitch axis, change roll and yaw axis, display ds & ds4 battery charge on lighbar, also a separate reset button
1 parent 556e841 commit 1dc4e13

File tree

4 files changed

+55
-39
lines changed

4 files changed

+55
-39
lines changed

README.RU.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
Для выхода из режима эмуляции стиков на тачпаде нужно переключиться на режим по умолчанию.
1616

1717

18-
Нажимая на профиль по умолчанию, на DualSense, белые светодиоды отображают текущий статус заряда аккумулятора (1 - 0..25%, 2 - 26..50%, 3 - 51..75%, 4 - 76..100%). Также в программе для DualSense и DualShock 4 отображается текущий заряд.
18+
Нажимая на профиль по умолчанию, на DualSense, белые светодиоды отображают текущий статус заряда аккумулятора (1 - 0..25%, 2 - 26..50%, 3 - 51..75%, 4 - 76..100%), также на DualSense и DualShock 4 показывается статус батареи на световую панель (зелёный - 100..30%, жёлтый - 29..10%, красный - 9..1%), можно отключить в конфиге, параметр `ShowBatteryStatusOnLightBar`. Для DualSense и DualShock 4 отображается текущий заряд в самой программе.
1919

2020

2121
Для изменения яркости 2 раза нажмите на область яркости. Если изменение яркости заблокировано, то подстветка будет выключаться по двойному клику.
@@ -67,11 +67,11 @@
6767
**[Загрузить](https://github.com/r57zone/DSAdvance/releases)**
6868

6969
## Благодарности
70-
* Sony за самые продвинутые геймпады и инвестирование в инновации, а также Nintendo за продвижение подобных инноваций в игры.
70+
* Sony и Nintendo за самые продвинутые геймпады и инвестирование в инновации, а также за продвижение инноваций в игры.
7171
* [ViGEm](https://github.com/ViGEm) за возможность эмуляции разных геймпадов.
7272
* [HIDAPI library](https://github.com/signal11/hidapi), с [исправлениями](https://github.com/libusb/hidapi), за библиотеку для работы с USB устройства. В проекте используется этот [форк](https://github.com/r57zone/hidapi).
7373
* [JoyShockLibrary](https://github.com/JibbSmart/JoyShockLibrary) за классную библиотеку геймпадов, позволяющую легко получить вращение контроллера. Также используется некоторый код из этой библиотеки.
74-
* [Пользователям Reddit](https://www.reddit.com/r/gamedev/comments/jumvi5/dualsense_haptics_leds_and_more_hid_output_report/) за детальное описание выходного USB пакета.
74+
* [Пользователям Reddit](https://www.reddit.com/r/gamedev/comments/jumvi5/dualsense_haptics_leds_and_more_hid_output_report/) за детальное описание выходного USB пакета DualSense.
7575
* DS4Windows[[1]](https://github.com/Jays2Kings/DS4Windows)[[2]](https://github.com/Ryochan7/DS4Windows) за уровень заряда батареи.
7676

7777
## Обратная связь

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Several working modes are supported, they are switched by pressing the touchpad
1616
To exit the stick emulation mode on the touchpad, need to switch to the default mode.
1717

1818

19-
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 in the program for DualSense and DualShock 4 the current charge is displayed.
19+
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.
2020

2121

2222
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).
@@ -63,11 +63,11 @@ In some games, such as Max Payne or Crysis 2, this does not work, the reasons ar
6363
**[Download](https://github.com/r57zone/DSAdvance/releases)**
6464

6565
## Credits
66-
* Sony for the most advanced gamepads and investing in innovation, as well as Nintendo for promoting similar innovations in games.
66+
* Sony and Nintendo for the most advanced gamepads and investment in innovation, and for driving innovation in games.
6767
* [ViGEm](https://github.com/ViGEm) for the ability to emulate different gamepads.
6868
* [HIDAPI library](https://github.com/signal11/hidapi) with [fixes](https://github.com/libusb/hidapi) for the library to work with a USB devices. The project uses this [fork](https://github.com/r57zone/hidapi).
6969
* [JoyShockLibrary](https://github.com/JibbSmart/JoyShockLibrary) for a cool gamepad library that makes it easy to get controller rotation. Also some code from this library is used.
70-
* For [Reddit users](https://www.reddit.com/r/gamedev/comments/jumvi5/dualsense_haptics_leds_and_more_hid_output_report/) for a detailed description of the USB output packet.
70+
* For [Reddit users](https://www.reddit.com/r/gamedev/comments/jumvi5/dualsense_haptics_leds_and_more_hid_output_report/) for a detailed description of the DualSense USB output packet.
7171
* DS4Windows[[1]](https://github.com/Jays2Kings/DS4Windows)[[2]](https://github.com/Ryochan7/DS4Windows) for the battery level.
7272

7373
## Feedback

Source/DSAdvance/DSAdvance.cpp

Lines changed: 49 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,12 @@ void LoadKMProfile(std::string ProfileFile) {
398398
KMJoySensY = IniFile.ReadFloat("MOUSE", "SensitivityY", 100) * 0.22;
399399
}
400400

401+
std::string ResetKeyName;
401402
void MainTextUpdate() {
402403
system("cls");
403404
if (AppStatus.ControllerCount < 1)
404405
printf("\n Connect DualSense, DualShock 4, Pro controller or Joycons and reset.");
405-
printf("\n Press \"CTRL\" + \"R\" to reset controllers.\n");
406+
printf("\n Press \"CTRL\" + \"R\" or \"%s\" to reset controllers.\n", ResetKeyName.c_str());
406407

407408
if (AppStatus.ControllerCount > 0 && AppStatus.ShowBatteryStatus && (CurGamepad.ControllerType == SONY_DUALSENSE || CurGamepad.ControllerType == SONY_DUALSHOCK4)) {
408409
printf(" Gamepad mode:");
@@ -433,19 +434,23 @@ void MainTextUpdate() {
433434
printf(", press \"ALT\" + \"W\" or \"PS\" + \"Share\" to switch.\n");
434435
printf(" Press \"ALT\" + \"B\" or \"PS\" + \"L1\" to turn the backlight on or off.\n");
435436

437+
printf(" Press \"ALT\" + \"F9\" to get the sticks dead zones.\n");
436438
printf(" Press \"ALT\" + \"Escape\" to exit.\n");
437439
}
438440

439441
int main(int argc, char **argv)
440442
{
441-
SetConsoleTitle("DSAdvance 0.8.3");
443+
SetConsoleTitle("DSAdvance 0.8.4");
442444
// Config parameters
443445
CIniReader IniFile("Config.ini");
444446

445447
bool InvertLeftStickX = IniFile.ReadBoolean("Gamepad", "InvertLeftStickX", false);
446448
bool InvertLeftStickY = IniFile.ReadBoolean("Gamepad", "InvertLeftStickY", false);
447449
bool InvertRightStickX = IniFile.ReadBoolean("Gamepad", "InvertRightStickX", false);
448450
bool InvertRightStickY = IniFile.ReadBoolean("Gamepad", "InvertRightStickY", false);
451+
ResetKeyName = IniFile.ReadString("Gamepad", "ResetKey", "NONE");
452+
int ResetKey = KeyNameToKeyCode(ResetKeyName);
453+
bool ShowBatteryStatusOnLightBar = IniFile.ReadBoolean("Gamepad", "ShowBatteryStatusOnLightBar", true);
449454
bool AutoReconnect = IniFile.ReadBoolean("Gamepad", "AutoReconnect", false);
450455
int SleepTimeOut = IniFile.ReadInteger("Gamepad", "SleepTimeOut", 1);
451456

@@ -467,6 +472,9 @@ int main(int argc, char **argv)
467472

468473
AppStatus.AimMode = IniFile.ReadBoolean("Motion", "AimMode", AimMouseMode);
469474
float MotionWheelAngle = IniFile.ReadFloat("Motion", "WheelAngle", 150) / 2.0f;
475+
bool MotionWheelPitch = IniFile.ReadBoolean("Motion", "WheelPitch", false);
476+
bool MotionWheelRoll = IniFile.ReadBoolean("Motion", "WheelRoll", true);
477+
int WheelInvertPitch = IniFile.ReadBoolean("Motion", "WheelInvertPitch", false) ? -1 : 1;
470478
float MotionSensX = IniFile.ReadFloat("Motion", "MouseSensX", 3) / 10.0f;;
471479
float MotionSensY = IniFile.ReadFloat("Motion", "MouseSensY", 3) / 10.0f;;
472480
float JoySensX = IniFile.ReadFloat("Motion", "JoySensX", 3);
@@ -564,33 +572,38 @@ int main(int argc, char **argv)
564572

565573
while (! ( GetAsyncKeyState(VK_LMENU) & 0x8000 && GetAsyncKeyState(VK_ESCAPE) & 0x8000 ) )
566574
{
575+
// Reset
576+
if ((((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0 && (GetAsyncKeyState('R') & 0x8000) != 0) || (GetAsyncKeyState(ResetKey) & 0x8000) != 0 && SkipPollCount == 0) || BTReset || ResetCounter == ResetControllersTimeOut)
577+
{
578+
AppStatus.ControllerCount = JslConnectDevices();
579+
JslGetConnectedDeviceHandles(deviceID, AppStatus.ControllerCount);
580+
GamepadSearch();
581+
GamepadSetState(GamepadOutState);
582+
BTReset = false;
583+
MainTextUpdate();
584+
SkipPollCount = SkipPollTimeOut;
585+
}
567586

568-
// Dead zones
587+
XUSB_REPORT_INIT(&report);
588+
InputState = JslGetSimpleState(deviceID[0]);
589+
MotionState = JslGetMotionState(deviceID[0]);
590+
MotionAngles = QuaternionToEulerAngle(MotionState.quatW, MotionState.quatZ, MotionState.quatX, MotionState.quatY);
591+
592+
// Stick dead zones
569593
if (((GetAsyncKeyState(VK_MENU) & 0x8000) != 0) && (GetAsyncKeyState(VK_F9) & 0x8000) != 0 && SkipPollCount == 0)
570594
{
571595
DeadZoneMode = !DeadZoneMode;
572596
if (DeadZoneMode == false) MainTextUpdate();
573597
SkipPollCount = SkipPollTimeOut;
574598
}
575-
576599
if (DeadZoneMode) {
577-
printf(" Left Stick X=%6.2f, ", abs(InputState.stickLX));
600+
printf(" Left stick X=%6.2f, ", abs(InputState.stickLX));
578601
printf("Y=%6.2f\t", abs(InputState.stickLY));
579-
printf("Right Stick X=%6.2f ", abs(InputState.stickRX));
602+
printf("Right stick X=%6.2f ", abs(InputState.stickRX));
580603
printf("Y=%6.2f\n", abs(InputState.stickRY));
581604
}
582605

583-
if ( ((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0 && (GetAsyncKeyState('R') & 0x8000) != 0 && SkipPollCount == 0 ) || BTReset || ResetCounter == ResetControllersTimeOut)
584-
{
585-
AppStatus.ControllerCount = JslConnectDevices();
586-
JslGetConnectedDeviceHandles(deviceID, AppStatus.ControllerCount);
587-
GamepadSearch();
588-
GamepadSetState(GamepadOutState);
589-
BTReset = false;
590-
MainTextUpdate();
591-
SkipPollCount = SkipPollTimeOut;
592-
}
593-
606+
// Switch emulation mode
594607
if ((((GetAsyncKeyState(VK_MENU) & 0x8000) != 0 && (GetAsyncKeyState('Q') & 0x8000) != 0) || ((InputState.buttons & JSMASK_LEFT || InputState.buttons & JSMASK_RIGHT) && InputState.buttons & JSMASK_PS)) && SkipPollCount == 0) // Disable Xbox controller emulation for games that support DualSense, DualShock, Nintendo controllers or enable only driving & mouse aiming
595608
{
596609
int LastGamepadEmuMode = AppStatus.GamepadEmulationMode;
@@ -608,7 +621,7 @@ int main(int argc, char **argv)
608621
ret = vigem_target_x360_register_notification(client, x360, &notification, nullptr);
609622
}
610623

611-
SkipPollCount = 30; //SkipPollTimeOut; -- 15 is seems not enough to enable or disable Xbox virtual gamepad
624+
SkipPollCount = 30; // 15 is seems not enough to enable or disable Xbox virtual gamepad
612625

613626
if (AppStatus.GamepadEmulationMode == EmuKeyboardAndMouse)
614627
LoadKMProfile(KMProfiles[ProfileIndex]);
@@ -620,20 +633,23 @@ int main(int argc, char **argv)
620633
MainTextUpdate();
621634
}
622635

636+
// Switch aiming mode: mouse / joymouse
623637
if ( ( ((GetAsyncKeyState(VK_MENU) & 0x8000) != 0 && (GetAsyncKeyState('A') & 0x8000) != 0) || (InputState.buttons & JSMASK_PS && InputState.buttons & JSMASK_R) ) && SkipPollCount == 0)
624638
{
625639
AppStatus.AimMode = !AppStatus.AimMode;
626640
MainTextUpdate();
627641
SkipPollCount = SkipPollTimeOut;
628642
}
629643

644+
// Switch modes by pressing or touching
630645
if ( ((GetAsyncKeyState(VK_MENU) & 0x8000) != 0 && (GetAsyncKeyState('W') & 0x8000) != 0) || (InputState.buttons & JSMASK_PS && InputState.buttons & JSMASK_SHARE) && SkipPollCount == 0)
631646
{
632647
AppStatus.ChangeModesWithoutPress = !AppStatus.ChangeModesWithoutPress;
633648
MainTextUpdate();
634649
SkipPollCount = SkipPollTimeOut;
635650
}
636651

652+
// Enable or disable lightbar
637653
if ((((GetAsyncKeyState(VK_MENU) & 0x8000) != 0 && (GetAsyncKeyState('B') & 0x8000) != 0) || (InputState.buttons & JSMASK_PS && InputState.buttons & JSMASK_L)) && SkipPollCount == 0)
638654
{
639655
if (GamepadOutState.LEDBrightness == 255) GamepadOutState.LEDBrightness = DefaultLEDBrightness;
@@ -646,6 +662,7 @@ int main(int argc, char **argv)
646662
SkipPollCount = SkipPollTimeOut;
647663
}
648664

665+
// Switch keyboard and mouse profile
649666
if (AppStatus.GamepadEmulationMode == EmuKeyboardAndMouse && SkipPollCount == 0)
650667
if ( (InputState.buttons & JSMASK_PS && (InputState.buttons & JSMASK_UP || InputState.buttons & JSMASK_DOWN)) ||
651668
( ( (GetAsyncKeyState(VK_MENU) & 0x8000) != 0 && ( (GetAsyncKeyState(VK_UP) & 0x8000) != 0 || (GetAsyncKeyState(VK_DOWN) & 0x8000) != 0) ) && GetConsoleWindow() == GetForegroundWindow()) )
@@ -658,12 +675,7 @@ int main(int argc, char **argv)
658675
PlaySound(ChangeEmuModeWav, NULL, SND_ASYNC);
659676
}
660677

661-
XUSB_REPORT_INIT(&report);
662-
663-
InputState = JslGetSimpleState(deviceID[0]);
664-
MotionState = JslGetMotionState(deviceID[0]);
665-
MotionAngles = QuaternionToEulerAngle(MotionState.quatW, MotionState.quatZ, MotionState.quatX, MotionState.quatY); // ?? correct?
666-
678+
// Switch modes by touchpad
667679
if (JslGetControllerType(deviceID[0]) == JS_TYPE_DS || JslGetControllerType(deviceID[0]) == JS_TYPE_DS4) {
668680

669681
TouchState = JslGetTouchState(deviceID[0]);
@@ -697,14 +709,18 @@ int main(int argc, char **argv)
697709

698710
if (TouchState.t0Y > 0.1 && TouchState.t0Y < 0.7) { // Default mode
699711
GamepadActionMode = GamepadDefaultMode;
700-
GamepadOutState.LEDBlue = 255; GamepadOutState.LEDRed = 0; GamepadOutState.LEDGreen = 0;
701712
// Show battery level
702-
GetBatteryInfo(); BackOutStateCounter = 40; GamepadOutState.PlayersCount = CurGamepad.LEDBatteryLevel; GamepadSetState(GamepadOutState); // JslSetPlayerNumber(deviceID[0], 5);
713+
GetBatteryInfo(); BackOutStateCounter = 40;
714+
if (ShowBatteryStatusOnLightBar) {
715+
if (CurGamepad.BatteryLevel >= 30) { GamepadOutState.LEDBlue = 0; GamepadOutState.LEDRed = 0; GamepadOutState.LEDGreen = 255; } // Battery fine 30%-100%
716+
else if (CurGamepad.BatteryLevel >= 10) { GamepadOutState.LEDBlue = 0; GamepadOutState.LEDGreen = 255; GamepadOutState.LEDRed = 255; } // Battery attention 10..29%
717+
else { GamepadOutState.LEDBlue = 0; GamepadOutState.LEDRed = 255; GamepadOutState.LEDGreen = 0; } // battery alarm 10%
718+
}
719+
GamepadOutState.PlayersCount = CurGamepad.LEDBatteryLevel; // JslSetPlayerNumber(deviceID[0], 5);
703720
AppStatus.ShowBatteryStatus = true;
704721
MainTextUpdate();
705722
} else { // Touch sticks mode
706723
GamepadActionMode = TouchpadSticksMode;
707-
//JslSetRumble(0, 255, 255);
708724
GamepadOutState.LEDBlue = 255; GamepadOutState.LEDRed = 255; GamepadOutState.LEDGreen = 0;
709725
}
710726

@@ -777,7 +793,7 @@ int main(int argc, char **argv)
777793

778794
// GameBar & multi keys
779795
// PS without any keys
780-
if (InputState.buttons == JSMASK_PS && PSReleasedCount == 0) { PSOnlyCheckCount = 15; PSOnlyPressed = true; }
796+
if (InputState.buttons == JSMASK_PS && PSReleasedCount == 0) { PSOnlyCheckCount = 20; PSOnlyPressed = true; }
781797
if (PSOnlyCheckCount > 0) {
782798
if (PSOnlyCheckCount == 1 && PSOnlyPressed)
783799
PSReleasedCount = PSReleasedTimeOut; // Timeout to release the PS button and don't execute commands
@@ -802,9 +818,10 @@ int main(int argc, char **argv)
802818
if (InputState.buttons & JSMASK_PS && InputState.buttons & JSMASK_RCLICK) CustomMulSens = 1; //printf("%5.2f\n", CustomMulSens);
803819

804820
// Gamepad modes
805-
if (GamepadActionMode == MotionDrivingMode) // Motion racing [O--]
806-
report.sThumbLX = ToLeftStick(OffsetYPR(RadToDeg(MotionAngles.Roll), RadToDeg(AnglesOffset.Roll)) * -1, MotionWheelAngle);
807-
else if (GamepadActionMode == MotionAimingMode || GamepadActionMode == MotionAimingModeOnlyPressed) { // Motion aiming [--X}]
821+
if (GamepadActionMode == MotionDrivingMode) { // Motion racing [O--]
822+
report.sThumbLX = MotionWheelRoll ? ToLeftStick(OffsetYPR(RadToDeg(MotionAngles.Roll), RadToDeg(AnglesOffset.Roll)) * -1, MotionWheelAngle) : report.sThumbLX = ToLeftStick(OffsetYPR(RadToDeg(MotionAngles.Yaw), RadToDeg(AnglesOffset.Yaw)) * -1, MotionWheelAngle);
823+
if (MotionWheelPitch) report.sThumbLY = ToLeftStick(OffsetYPR(RadToDeg(MotionAngles.Pitch), RadToDeg(AnglesOffset.Pitch)) * WheelInvertPitch, MotionWheelAngle);
824+
} else if (GamepadActionMode == MotionAimingMode || GamepadActionMode == MotionAimingModeOnlyPressed) { // Motion aiming [--X}]
808825
float DeltaX = OffsetYPR(RadToDeg(MotionAngles.Yaw), RadToDeg(AnglesOffset.Yaw)) * -1;
809826
float DeltaY = OffsetYPR(RadToDeg(MotionAngles.Pitch), RadToDeg(AnglesOffset.Pitch)) * -1;
810827
if (GamepadActionMode == MotionAimingMode || (GamepadActionMode == MotionAimingModeOnlyPressed && InputState.lTrigger > 0) )
@@ -904,7 +921,7 @@ int main(int argc, char **argv)
904921
}
905922

906923
// Battery level display
907-
if (BackOutStateCounter > 0) { if (BackOutStateCounter == 1) { GamepadOutState.PlayersCount = 0; GamepadSetState(GamepadOutState); AppStatus.ShowBatteryStatus = false; MainTextUpdate(); } BackOutStateCounter--; }
924+
if (BackOutStateCounter > 0) { if (BackOutStateCounter == 1) { GamepadOutState.LEDBlue = 255; GamepadOutState.LEDRed = 0; GamepadOutState.LEDGreen = 0; GamepadOutState.PlayersCount = 0; GamepadSetState(GamepadOutState); AppStatus.ShowBatteryStatus = false; MainTextUpdate(); } BackOutStateCounter--; }
908925

909926
if (AutoReconnect) { if (ResetCounter >= ResetControllersTimeOut) ResetCounter = 0; else ResetCounter++; } // Auto reconnect controllers & fix JoyShockLibrary bug with increase in CPU usage when the controller is turned off
910927
//printf("%d \n", ResetCounter);

Source/Launcher/Unit1.pas

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ TMain = class(TForm)
2323
CheckAppClosedTimer: TTimer;
2424
XPManifest1: TXPManifest;
2525
N5: TMenuItem;
26-
N6: TMenuItem;
2726
ProfilesBtn: TMenuItem;
2827
HidHideBtn: TMenuItem;
2928
procedure FormCreate(Sender: TObject);

0 commit comments

Comments
 (0)