Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge EA to public #1035

Merged
merged 49 commits into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
ac70a3c
Implement CustomWpf (#154)
Valkirie Jan 12, 2024
0e188e6
Implement support for Intel Graphics Control Library (IGCL) (#158)
Valkirie Jan 13, 2024
6c1ddee
Implement new UI classes (#153)
Valkirie Jan 13, 2024
e91b049
Improve ADLX and IGCL (#160)
Valkirie Jan 15, 2024
b794f21
Allow OSD customization (#161)
0SkillAllLuck Jan 15, 2024
c191327
Support GPD WIN MINI (Initial) (#169)
CasperH2O Jan 24, 2024
e6080f2
Build 0.20.4.0
CasperH2O Jan 29, 2024
7d58de2
Update HidHide to 1.4.202 (#182)
Valkirie Feb 3, 2024
85b2bf6
Added support for multi-display and multi-GPU configurations (#186)
Valkirie Feb 16, 2024
35b44ed
Misc fixes (#189)
Valkirie Feb 18, 2024
512c7af
MVVM Rework - Batch 1 (#193)
CasperH2O Feb 29, 2024
a09c08d
Build 0.20.5.0
CasperH2O Feb 29, 2024
57ce44e
Build 0.20.5.1
CasperH2O Mar 5, 2024
e7c15b8
Implement Legion Go per-controller-gyro support (#204)
Valkirie Mar 14, 2024
90cf8c1
Implement JibbSmart's GamepadMotionHelper (#206)
Valkirie Mar 18, 2024
b1fe1fa
Build 0.20.5.2
CasperH2O Mar 18, 2024
d5dc0c3
InnoSetup Update (#209)
CasperH2O Mar 22, 2024
f8a56f8
Build 0.20.5.3
CasperH2O Mar 22, 2024
025600e
implement enum SteeringAxis
Valkirie Mar 25, 2024
182b687
Support for MSI Claw (#213)
romracer Mar 30, 2024
395c775
fix profile management
Valkirie Mar 31, 2024
458c714
Build 0.20.5.4
CasperH2O Mar 30, 2024
c707c79
Build 0.20.5.5
CasperH2O Apr 4, 2024
1de76ae
Update RTSS to 7.3.6
Apr 4, 2024
03bcffa
implement automatic Roll/Yaw swap (#229)
Valkirie Apr 7, 2024
e6a354a
Build 0.20.5.6
CasperH2O Apr 8, 2024
628c65d
improve VirtualManager / ControllerManager relationship
Valkirie Apr 9, 2024
c45bb07
simplify VirtualManager lock logic
Valkirie Apr 9, 2024
584b92c
Improve GPU stability (#235)
Valkirie Apr 11, 2024
87656bd
Update ADLX wrapper (#237)
romracer Apr 11, 2024
723b52e
Update ADLX_Wrapper.dll (#239)
romracer Apr 11, 2024
51fb31f
Crash on launch (#238)
romracer Apr 11, 2024
8cea84c
Update ADLX Wrapper with latest changes (#241)
romracer Apr 12, 2024
edac338
(tentative) to improve locking (#236)
Valkirie Apr 12, 2024
3728b53
Don't spam set the CPU limits (#233)
0SkillAllLuck Apr 12, 2024
c1dce0f
leverage CrossThreadLock on QuickProfilesPage and ProfilesPage
Valkirie Apr 12, 2024
e97fe9f
leverage CrossThreadLock on QuickHomePage
Valkirie Apr 12, 2024
85dd3f0
Increase cTDP range for Arc A380
CasperH2O Apr 12, 2024
e7369f2
Build 0.20.5.7
CasperH2O Apr 12, 2024
2258b39
initialize all MotherboardInfo getters with static object
Valkirie Apr 12, 2024
bc4ce99
update LibreHardwareMonitorLib
Valkirie Apr 12, 2024
1d0990c
Fix OSD custom mode settings (#247)
0SkillAllLuck Apr 13, 2024
12e1f42
AYANEO: Hold RGB control while running (#230)
0SkillAllLuck Apr 13, 2024
ba4d7f6
Cache motherboard info (#250)
romracer Apr 15, 2024
04103e3
Build 0.21.0.0
Valkirie Apr 17, 2024
3f4e2ce
Fixed an issue preventing Lenovo Legion Go right controller from send…
Valkirie Apr 18, 2024
ed72f42
Fixed an issue causing a crash on device with no available audio output
Valkirie Apr 18, 2024
ca6bbac
Installer fixes
romracer Apr 17, 2024
789f750
Build 0.21.0.1
CasperH2O Apr 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions HandheldCompanion.iss
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#define InstallerVersion '0.2'
#define MyAppSetupName 'Handheld Companion'
#define MyBuildId 'HandheldCompanion'
#define MyAppVersion '0.20.5.6'
#define MyAppVersion '0.21.0.1'
#define MyAppPublisher 'BenjaminLSR'
#define MyAppCopyright 'Copyright @ BenjaminLSR'
#define MyAppURL 'https://github.com/Valkirie/HandheldCompanion'
Expand All @@ -49,7 +49,8 @@
#define NewDirectXVersion "9.29.1974"
#define NewViGemVersion "1.22.0.0"
#define NewHidHideVersion "1.5.212"
#define NewRtssVersion "7.3.6"
; RTSS 7.3.6
#define NewRtssVersion "7.3.5.28010"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RTSS version number is inconsistent with the defined constant.

- #define NewRtssVersion "7.3.5.28010"
+ #define NewRtssVersion "7.3.6"

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
#define NewRtssVersion "7.3.5.28010"
#define NewRtssVersion "7.3.6"


//#define DotNetX64DownloadLink "https://download.visualstudio.microsoft.com/download/pr/b280d97f-25a9-4ab7-8a12-8291aa3af117/a37ed0e68f51fcd973e9f6cb4f40b1a7/windowsdesktop-runtime-8.0.0-win-x64.exe"
//#define DotNetX86DownloadLink "https://download.visualstudio.microsoft.com/download/pr/f9e3b581-059d-429f-9f0d-1d1167ff7e32/bd7661030cd5d66cd3eee0fd20b24540/windowsdesktop-runtime-8.0.0-win-x86.exe"
Expand Down Expand Up @@ -724,11 +725,11 @@ end;

procedure Dependency_AddRTSS;
begin
Dependency_Add_With_Version('RTSSSetup735.exe', '{#NewRtssVersion}', regGetInstalledVersion('{#RtssName}'),
Dependency_Add_With_Version('RTSSSetup736.exe', '{#NewRtssVersion}', regGetInstalledVersion('{#RtssName}'),
'/S',
'{#RtssName}',
'{#RtssDownloadLink}',
'', True, False);
'', True, True);

stopProcess('{#EncoderServer64Exe}');
stopProcess('{#RTSSHooksLoader64Exe}');
Expand Down
Binary file modified HandheldCompanion/ADLX_Wrapper.dll
Binary file not shown.
2 changes: 1 addition & 1 deletion HandheldCompanion/Controllers/LegionController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ public override void UpdateInputs(long ticks, float delta, bool commit)
base.UpdateInputs(ticks, delta);
break;
case LegionGo.RightJoyconIndex:
gamepadMotion.ProcessMotion(gX, gY, gZ, aX, aY, aZ, delta);
gamepadMotionR.ProcessMotion(gX, gY, gZ, aX, aY, aZ, delta);
base.UpdateInputs(ticks, delta, gamepadMotionR);
break;
}
Expand Down
7 changes: 1 addition & 6 deletions HandheldCompanion/Devices/IDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public abstract class IDevice
public delegate void PowerStatusChangedEventHandler(IDevice device);

protected static OpenLibSys openLibSys;
protected LockObject updateLock = new();
protected object updateLock = new();

private static IDevice device;

Expand Down Expand Up @@ -829,11 +829,6 @@ protected bool SuspendDevice(string InterfaceId)
return false;
}

protected void PowerStatusChange(IDevice device)
{
PowerStatusChanged?.Invoke(device);
}

public static IEnumerable<HidDevice> GetHidDevices(int vendorId, int deviceId, int minFeatures = 1)
{
HidDevice[] HidDeviceList = HidDevices.Enumerate(vendorId, new int[] { deviceId }).ToArray();
Expand Down
5 changes: 2 additions & 3 deletions HandheldCompanion/HandheldCompanion.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<StartupObject>HandheldCompanion.App</StartupObject>
<OutputPath>$(SolutionDir)bin\$(Configuration)</OutputPath>
<ApplicationIcon>Resources\icon.ico</ApplicationIcon>
<Version>0.20.5.6</Version>
<Version>0.21.0.1</Version>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>AnyCPU;x64;x86</Platforms>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
Expand Down Expand Up @@ -150,11 +150,10 @@
<PackageReference Include="dotnetCampus.WPF" Version="6.0.4-alpha07-test07" />
<PackageReference Include="dotnetCampus.WPF.Dependencies" Version="6.0.4-alpha07-test07" />
<PackageReference Include="dotnetCampus.WPF.Resource" Version="6.0.4-alpha07-test07" />
<PackageReference Include="Fastenshtein" Version="1.0.0.8" />
<PackageReference Include="GregsStack.InputSimulatorStandard" Version="1.3.5" />
<PackageReference Include="iNKORE.UI.WPF.Modern" Version="0.9.25.1" />
<PackageReference Include="HelixToolkit.Core.Wpf" Version="2.25.0" />
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.4-pre274" />
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.4-pre277" />
<PackageReference Include="LiveCharts.Wpf.Core" Version="0.9.8" />
<PackageReference Include="MathConverter" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
Expand Down
36 changes: 13 additions & 23 deletions HandheldCompanion/Managers/PerformanceManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,10 @@ private static async void cpuWatchdog_Elapsed(object? sender, ElapsedEventArgs e

// only request an update if current limit is different than stored
if (ReadTDP != TDP)
{
processor.SetTDPLimit(type, TDP);
CurrentTDP[idx] = TDP;
}
Comment on lines +573 to +576
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure thread safety when updating CurrentTDP array.

The code modifies the CurrentTDP array within a loop that potentially runs on multiple threads due to the asynchronous nature of cpuWatchdog_Elapsed. This could lead to race conditions. Consider using thread-safe operations or synchronization mechanisms when updating shared data.


await Task.Delay(20);
}
Expand Down Expand Up @@ -727,28 +730,18 @@ private static void RequestTDP(PowerType type, double value, bool immediate = fa

// immediately apply
if (immediate)
{
processor.SetTDPLimit((PowerType)idx, value, immediate);
CurrentTDP[idx] = value;
}
}

private static async void RequestTDP(double[] values, bool immediate = false)
{
if (processor is null || !processor.IsInitialized)
return;

for (int idx = (int)PowerType.Slow; idx <= (int)PowerType.Fast; idx++)
{
// make sure we're not trying to run below or above specs
values[idx] = Math.Min(TDPMax, Math.Max(TDPMin, values[idx]));

// update value read by timer
StoredTDP[idx] = values[idx];

// immediately apply
if (immediate)
{
processor.SetTDPLimit((PowerType)idx, values[idx], immediate);
await Task.Delay(20);
}
RequestTDP((PowerType)idx, values[idx], immediate);
await Task.Delay(20);
}
}

Expand Down Expand Up @@ -874,18 +867,15 @@ public static void Start()
// initialize processor
processor = Processor.GetCurrent();

if (processor.IsInitialized)
if (processor is not null && processor.IsInitialized)
{
processor.StatusChanged += Processor_StatusChanged;
processor.Initialize();
}

// deprecated
/*
processor.ValueChanged += Processor_ValueChanged;
processor.LimitChanged += Processor_LimitChanged;
processor.MiscChanged += Processor_MiscChanged;
*/
else
{
ProcessorStatusChanged?.Invoke(false, false);
}
Comment on lines +870 to +878
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handle potential null reference in processor initialization.

The method Start checks if processor is not null and is initialized before attaching event handlers and calling Initialize. However, there's a potential for processor to be null or uninitialized when ProcessorStatusChanged is invoked immediately after. This could lead to a null reference exception. Ensure that processor is properly checked before invoking any methods or accessing its properties.


IsInitialized = true;
Initialized?.Invoke();
Expand Down
4 changes: 3 additions & 1 deletion HandheldCompanion/Managers/ProcessManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Automation;
Expand Down Expand Up @@ -88,7 +89,8 @@ static ProcessManager()

private static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
ForegroundCallback();
// avoid locking UI thread
new Thread(() => { ForegroundCallback(); }).Start();
Comment on lines +92 to +93
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using Task.Run instead of new Thread for better resource management.

Using Task.Run instead of new Thread can lead to better thread pool management and potentially improved performance. Task.Run uses the .NET thread pool, which is optimized for short-running compute-bound operations and can efficiently handle a large number of small tasks by maintaining a pool of threads that are reused.

- new Thread(() => { ForegroundCallback(); }).Start();
+ Task.Run(() => { ForegroundCallback(); });

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// avoid locking UI thread
new Thread(() => { ForegroundCallback(); }).Start();
// avoid locking UI thread
Task.Run(() => { ForegroundCallback(); });

}

private static void OnWindowOpened(object sender, AutomationEventArgs automationEventArgs)
Expand Down
156 changes: 75 additions & 81 deletions HandheldCompanion/Managers/VirtualManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
using Nefarius.ViGEm.Client;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using static HandheldCompanion.Managers.ControllerManager;

namespace HandheldCompanion.Managers
{
Expand All @@ -26,7 +28,7 @@ public static class VirtualManager
public static ushort ProductId = 0x28E; // Xbox 360
public static ushort VendorId = 0x45E; // Microsoft
public static ushort FakeVendorId = 0x76B; // HC
private static CrossThreadLock threadLock = new CrossThreadLock();
private static object threadLock = new();

public static bool IsInitialized;

Expand Down Expand Up @@ -144,12 +146,15 @@ private static void SettingsManager_SettingValueChanged(string name, object valu
}
}

private static void ProfileManager_Applied(Profile profile, UpdateSource source)
private static async void ProfileManager_Applied(Profile profile, UpdateSource source)
{
// SetControllerMode takes care of ignoring identical mode switching
if (HIDmode == profile.HID || profile.HID == HIDmode.NotSelected)
return;

while (ControllerManager.managerStatus == ControllerManagerStatus.Busy)
await Task.Delay(1000);

switch (profile.HID)
{
case HIDmode.Xbox360Controller:
Expand All @@ -161,8 +166,11 @@ private static void ProfileManager_Applied(Profile profile, UpdateSource source)
}
}

private static void ProfileManager_Discarded(Profile profile)
private static async void ProfileManager_Discarded(Profile profile)
{
while (ControllerManager.managerStatus == ControllerManagerStatus.Busy)
await Task.Delay(1000);

// restore default HID mode
if (profile.HID != HIDmode.NotSelected)
SetControllerMode(defaultHIDmode);
Expand All @@ -178,107 +186,93 @@ private static void SetDSUStatus(bool started)

public static void SetControllerMode(HIDmode mode)
{
if (!threadLock.TryEnter(3000))
return;

// do not disconnect if similar to previous mode and connected
if (HIDmode == mode)
lock (threadLock)
{
if (HIDstatus == HIDstatus.Disconnected)
// do not disconnect if similar to previous mode and connected
if (HIDmode == mode)
{
threadLock.Exit();
return;
if (HIDstatus == HIDstatus.Disconnected)
return;
else if (vTarget is not null && vTarget.IsConnected)
return;
}
else if (vTarget is not null && vTarget.IsConnected)

// disconnect current virtual controller
if (vTarget is not null)
{
threadLock.Exit();
return;
vTarget.Disconnect();
vTarget.Dispose();
vTarget = null;
}
}

// disconnect current virtual controller
if (vTarget is not null)
{
vTarget.Disconnect();
vTarget.Dispose();
vTarget = null;
}

switch (mode)
{
default:
case HIDmode.NoController:
if (vTarget is not null)
{
vTarget.Disconnect();
vTarget.Dispose();
vTarget = null;
}
break;

case HIDmode.DualShock4Controller:
vTarget = new DualShock4Target();
break;
switch (mode)
{
default:
case HIDmode.NoController:
if (vTarget is not null)
{
vTarget.Disconnect();
vTarget.Dispose();
vTarget = null;
}
break;

case HIDmode.Xbox360Controller:
// Generate a new random ProductId to help the controller pick empty slot rather than getting its previous one
VendorId = (ushort)new Random().Next(ushort.MinValue, ushort.MaxValue);
ProductId = (ushort)new Random().Next(ushort.MinValue, ushort.MaxValue);
vTarget = new Xbox360Target(VendorId, ProductId);
break;
}
case HIDmode.DualShock4Controller:
vTarget = new DualShock4Target();
break;

ControllerSelected?.Invoke(mode);
case HIDmode.Xbox360Controller:
// Generate a new random ProductId to help the controller pick empty slot rather than getting its previous one
VendorId = (ushort)new Random().Next(ushort.MinValue, ushort.MaxValue);
ProductId = (ushort)new Random().Next(ushort.MinValue, ushort.MaxValue);
vTarget = new Xbox360Target(VendorId, ProductId);
break;
}

// failed to initialize controller
if (vTarget is null)
{
if (mode != HIDmode.NoController)
LogManager.LogError("Failed to initialise virtual controller with HIDmode: {0}", mode);
ControllerSelected?.Invoke(mode);

threadLock.Exit();
return;
}
// failed to initialize controller
if (vTarget is null)
{
if (mode != HIDmode.NoController)
LogManager.LogError("Failed to initialise virtual controller with HIDmode: {0}", mode);

vTarget.Connected += OnTargetConnected;
vTarget.Disconnected += OnTargetDisconnected;
vTarget.Vibrated += OnTargetVibrated;
return;
}

// update current HIDmode
HIDmode = mode;
vTarget.Connected += OnTargetConnected;
vTarget.Disconnected += OnTargetDisconnected;
vTarget.Vibrated += OnTargetVibrated;

threadLock.Exit();
// update current HIDmode
HIDmode = mode;
}

// update status
SetControllerStatus(HIDstatus);
}

public static void SetControllerStatus(HIDstatus status)
{
if (!threadLock.TryEnter(3000))
return;

if (vTarget is null)
{
threadLock.Exit();
return;
}

switch (status)
lock (threadLock)
{
default:
case HIDstatus.Connected:
vTarget.Connect();
break;
case HIDstatus.Disconnected:
vTarget.Disconnect();
break;
}
if (vTarget is null)
return;

// update current HIDstatus
HIDstatus = status;
switch (status)
{
default:
case HIDstatus.Connected:
vTarget.Connect();
break;
case HIDstatus.Disconnected:
vTarget.Disconnect();
break;
}

threadLock.Exit();
// update current HIDstatus
HIDstatus = status;
}
}

private static void OnTargetConnected(ViGEmTarget target)
Expand Down
Loading
Loading