Skip to content

Commit

Permalink
Added Custom overlay mode (#750)
Browse files Browse the repository at this point in the history
* Added Custom overlay mode

Keeps RTSS and HWINFO running, but without injecting / refreshing own OSD UI into it, relying on the user to configure their own overlay in RTSS

* Renamed new level to `External`

* Tweaks to changing RTSS profile properties, inspired by RTSS SDK docs:

```c++
// HotkeyHandlerWnd.cpp
if (m_rtssInterface.SetProfileProperty(lpProperty, (LPBYTE)&dwValue, sizeof(dwValue)))
		{
			m_rtssInterface.SaveProfile(lpProfile);
			m_rtssInterface.UpdateProfiles();
		}
```

* Fixes issue where `EnableOSD` is called before RTSS is started

This happens when HC is started, as profile is applied before platform manager starts RTSS, meaning the `EnableOSD` call doesn't get through.

Put logic of toggling OSD into platform manager, to ensure it's properly set whenever RTSS is started AND whenever needs change related to `OnScreenDisplay`
  • Loading branch information
micdah authored Aug 25, 2023
1 parent 88698ce commit f778b11
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 50 deletions.
39 changes: 32 additions & 7 deletions HandheldCompanion/Managers/OSDManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,10 @@ public static string Draw(int processId)
switch (OverlayLevel)
{
default:
case 0:
case 0: // Disabled
break;

case 1:
case 1: // Minimal
{
OverlayRow row1 = new();

Expand All @@ -182,7 +182,7 @@ public static string Draw(int processId)
}
break;

case 2:
case 2: // Extended
{
OverlayRow row1 = new();

Expand Down Expand Up @@ -228,7 +228,7 @@ public static string Draw(int processId)
}
break;

case 3:
case 3: // Full
{
OverlayRow row1 = new();
OverlayRow row2 = new();
Expand Down Expand Up @@ -295,6 +295,15 @@ public static string Draw(int processId)
Content.Add(row6.ToString());
}
break;

case 4: // External
{
/*
* Intended to simply allow RTSS/HWINFO to run, and let the user configure the overlay within those
* tools as they wish
*/
break;
}
}

return string.Join("\n", Content);
Expand Down Expand Up @@ -324,10 +333,26 @@ private static void SettingsManager_SettingValueChanged(string name, object valu
{
OverlayLevel = Convert.ToInt16(value);

if (OverlayLevel != 0)
if (OverlayLevel > 0)
{
if (!RefreshTimer.IsRunning())
RefreshTimer.Start();
if (OverlayLevel == 4)
{
// No need to update OSD in External
RefreshTimer.Stop();

// Remove previous UI in External
foreach (var pair in OnScreenDisplay)
{
var processOSD = pair.Value;
processOSD.Update("");
}
}
else
{
// Other modes need the refresh timer to update OSD
if (!RefreshTimer.IsRunning())
RefreshTimer.Start();
}
}
else
{
Expand Down
36 changes: 25 additions & 11 deletions HandheldCompanion/Managers/PlatformManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,17 +98,18 @@ private static void SettingsManager_SettingValueChanged(string name, object valu

switch (level)
{
case 0:
case 0: // Disabled
CurrentNeeds &= ~PlatformNeeds.OnScreenDisplay;
CurrentNeeds &= ~PlatformNeeds.OnScreenDisplayComplex;
break;
default:
case 1:
case 1: // Minimal
CurrentNeeds |= PlatformNeeds.OnScreenDisplay;
CurrentNeeds &= ~PlatformNeeds.OnScreenDisplayComplex;
break;
case 2:
case 3:
case 2: // Extended
case 3: // Full
case 4: // External
CurrentNeeds |= PlatformNeeds.OnScreenDisplay;
CurrentNeeds |= PlatformNeeds.OnScreenDisplayComplex;
break;
Expand All @@ -124,10 +125,10 @@ private static void SettingsManager_SettingValueChanged(string name, object valu

private static void MonitorPlatforms()
{
/*
* Dependencies:
* HWInfo: OSD
* RTSS: AutoTDP, framerate limiter, OSD
/*
* Dependencies:
* HWInfo: OSD
* RTSS: AutoTDP, framerate limiter, OSD
*/

// Check if the current needs are the same as the previous needs
Expand All @@ -140,7 +141,11 @@ private static void MonitorPlatforms()
if (!PreviousNeeds.HasFlag(PlatformNeeds.OnScreenDisplay))
// Only start RTSS if it was not running before and if it is installed
if (RTSS.IsInstalled)
{
// Start and enable OSD
RTSS.Start();
RTSS.SetEnableOSD(true);
}
if (CurrentNeeds.HasFlag(PlatformNeeds.OnScreenDisplayComplex))
{
// This condition checks if OnScreenDisplayComplex is true
Expand Down Expand Up @@ -168,11 +173,15 @@ private static void MonitorPlatforms()
// Only start RTSS if it was not running before and if it is installed
if (RTSS.IsInstalled)
RTSS.Start();

// Only stop HWiNFO if it was running before
// Only stop HWiNFO if it is installed
if (PreviousNeeds.HasFlag(PlatformNeeds.OnScreenDisplay))
// Only stop HWiNFO if it was running before
// Only stop HWiNFO if it is installed
if (HWiNFO.IsInstalled)
HWiNFO.Stop(true);

// Disable OSD
RTSS.SetEnableOSD(false);
}
else
{
Expand All @@ -182,7 +191,12 @@ private static void MonitorPlatforms()
{
// Only stop HWiNFO and RTSS if they were running before and if they are installed
if (HWiNFO.IsInstalled) HWiNFO.Stop(true);
if (RTSS.IsInstalled) RTSS.Stop();
if (RTSS.IsInstalled)
{
// Disable OSD
RTSS.SetEnableOSD(false);
RTSS.Stop();
}
}
}

Expand Down
37 changes: 35 additions & 2 deletions HandheldCompanion/Platforms/RTSS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ private async void ProcessManager_ForegroundChanged(ProcessEx processEx, Process

do
{
/*
/*
* loop until we either:
* - got an RTSS entry
* - process no longer exists
Expand Down Expand Up @@ -325,24 +325,57 @@ public uint EnableFlag(uint flag, bool status)
return current;
}

public bool SetEnableOSD(bool enable)
{
if (!IsRunning())
return false;

try
{
// Ensure Global profile is loaded
LoadProfile();

// Set EnableOSD as requested
if (SetProfileProperty("EnableOSD", enable ? 1 : 0))
{
// Save and reload profile
SaveProfile();
UpdateProfiles();

return true;
}
}
catch
{
LogManager.LogWarning("Failed to set OSD visibility settings in RTSS");
}

return false;
}

private bool SetTargetFPS(int Limit)
{
if (!IsRunning())
return false;

try
{
// Ensure Global profile is loaded
LoadProfile();

// Set Framerate Limit as requested
if (SetProfileProperty("FramerateLimit", Limit))
{
// Save and reload profile
SaveProfile();
UpdateSettings();
UpdateProfiles();

return true;
}
}
catch
{
LogManager.LogWarning("Failed to set Framerate Limit in RTSS");
}

/*
Expand Down
12 changes: 10 additions & 2 deletions HandheldCompanion/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 31 additions & 28 deletions HandheldCompanion/Properties/Resources.resx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
Expand All @@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
Expand Down Expand Up @@ -789,7 +789,7 @@
<value>Motion activation</value>
</data>
<data name="ProfilesPage_UMCMotionOnOffDesc" xml:space="preserve">
<value>With motion input disabled, use selected button(s) to enable motion,
<value>With motion input disabled, use selected button(s) to enable motion,
with motion input enabled, use selected button(s) to disable motion.</value>
</data>
<data name="ProfilesPage_UMCSelectionRightLeftDesc" xml:space="preserve">
Expand Down Expand Up @@ -1449,6 +1449,9 @@ with motion input enabled, use selected button(s) to disable motion.</value>
<data name="OverlayPage_OverlayDisplayLevel_Minimal" xml:space="preserve">
<value>Minimal</value>
</data>
<data name="OverlayPage_OverlayDisplayLevel_External" xml:space="preserve">
<value>External</value>
</data>
<data name="ProfilesPage_ControllerLayoutDesc" xml:space="preserve">
<value>Change the virtual controller layout</value>
</data>
Expand Down
1 change: 1 addition & 0 deletions HandheldCompanion/Views/Pages/OverlayPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
<Label Content="{x:Static resx:Resources.OverlayPage_OverlayDisplayLevel_Minimal}" />
<Label Content="{x:Static resx:Resources.OverlayPage_OverlayDisplayLevel_Extended}" />
<Label Content="{x:Static resx:Resources.OverlayPage_OverlayDisplayLevel_Full}" />
<Label Content="{x:Static resx:Resources.OverlayPage_OverlayDisplayLevel_External}" />
</ComboBox>
</Grid>
</Border>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
Name="OverlayDisplayLevelFull"
Content="{x:Static resx:Resources.OverlayPage_OverlayDisplayLevel_Full}"
IsEnabled="False" />
<ComboBoxItem Name="OverlayDisplayLevelExternal" Content="{x:Static resx:Resources.OverlayPage_OverlayDisplayLevel_External}" />
</ComboBox>
</Border>
</ui:SimpleStackPanel>
Expand Down

0 comments on commit f778b11

Please sign in to comment.