Extend performance overlay to include FT and others

This commit is contained in:
Kamil Trzciński 2022-11-13 14:39:29 +01:00
parent 059d64827f
commit 01f0d6b366
21 changed files with 198 additions and 63 deletions

View file

@ -5,6 +5,7 @@ on:
- '**/**.md'
env:
RELEASE_NAME: SteamDeckTools
DOTNET_VERSION: '6.0.x'
jobs:
@ -38,13 +39,13 @@ jobs:
echo "MajorVer=$majorVer LastVer=$lastVer NextVer=$nextVer"
echo "RELEASE_VERSION=$nextVer" >> $GITHUB_ENV
- name: Build
run: dotnet build --configuration Release --output "FanControl-${{ env.RELEASE_VERSION }}/" "/property:Version=${{ env.RELEASE_VERSION }}"
run: dotnet build --configuration Release --output "${{ env.SteamDeckTools }}-${{ env.RELEASE_VERSION }}/" "/property:Version=${{ env.RELEASE_VERSION }}"
- name: Test
run: dotnet test --no-restore --verbosity normal
- uses: vimtor/action-zip@v1
with:
files: FanControl-${{ env.RELEASE_VERSION }}
dest: FanControl-${{ env.RELEASE_VERSION }}.zip
files: ${{ env.SteamDeckTools }}-${{ env.RELEASE_VERSION }}
dest: ${{ env.SteamDeckTools }}-${{ env.RELEASE_VERSION }}.zip
recursive: true
- uses: ncipollo/release-action@v1
with:

View file

@ -2,6 +2,7 @@ on:
pull_request:
env:
RELEASE_NAME: SteamDeckTools
DOTNET_VERSION: '6.0.x'
jobs:
@ -16,11 +17,11 @@ jobs:
- name: Install dependencies
run: dotnet restore
- name: Build without Version
run: dotnet build --configuration Release --output FanControl-develop/
run: dotnet build --configuration Release --output ${{ env.SteamDeckTools }}-develop/
- name: Test
run: dotnet test --no-restore --verbosity normal
- uses: vimtor/action-zip@v1
with:
files: FanControl-develop
dest: FanControl-develop.zip
files: ${{ env.SteamDeckTools }}-develop
dest: ${{ env.SteamDeckTools }}-develop.zip
recursive: true

View file

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="TaskScheduler" Version="2.10.1" />
</ItemGroup>
<ItemGroup>
<None Update="inpoutx64.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View file

@ -15,18 +15,21 @@ using Microsoft.Win32.TaskScheduler;
using Action = Microsoft.Win32.TaskScheduler.Action;
using Task = Microsoft.Win32.TaskScheduler.Task;
namespace FanControl.FromLibreHardwareMonitor
namespace CommonHelpers.FromLibreHardwareMonitor
{
public class StartupManager
{
private const string RegistryPath = @"Software\Microsoft\Windows\CurrentVersion\Run";
private bool _startup;
public const string Description = "Starts Steam Deck Fan Control on Windows startup.";
public const string NameOf = "Steam Deck Fan Control";
public String NameOf { get; set; }
public String Description { get; set; }
public StartupManager()
public StartupManager(String name, String description)
{
NameOf = name;
Description = description;
if (Environment.OSVersion.Platform >= PlatformID.Unix)
{
IsAvailable = false;
@ -131,7 +134,7 @@ namespace FanControl.FromLibreHardwareMonitor
}
}
private static Task GetTask()
private Task GetTask()
{
try
{
@ -164,19 +167,19 @@ namespace FanControl.FromLibreHardwareMonitor
TaskService.Instance.RootFolder.RegisterTaskDefinition(NameOf, taskDefinition);
}
private static void DeleteTask()
private void DeleteTask()
{
Task task = GetTask();
task?.Folder.DeleteTask(task.Name, false);
}
private static void CreateRegistryKey()
private void CreateRegistryKey()
{
RegistryKey registryKey = Registry.CurrentUser.CreateSubKey(RegistryPath);
registryKey?.SetValue(NameOf, Application.ExecutablePath);
}
private static void DeleteRegistryKey()
private void DeleteRegistryKey()
{
RegistryKey registryKey = Registry.CurrentUser.CreateSubKey(RegistryPath);
registryKey?.DeleteValue(NameOf);

View file

@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace FanControl
namespace CommonHelpers
{
internal class InpOut
{

View file

@ -6,9 +6,9 @@ using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
namespace FanControl
namespace CommonHelpers
{
internal class Vlv0100
public class Vlv0100
{
// Those addresses are taken from DSDT for VLV0100
// and might change at any time with a BIOS update

View file

@ -16,6 +16,10 @@
<PackageReference Include="TaskScheduler" Version="2.10.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommonHelpers\CommonHelpers.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>

View file

@ -1,4 +1,4 @@
using FanControl.FromLibreHardwareMonitor;
using CommonHelpers.FromLibreHardwareMonitor;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@ -17,7 +17,10 @@ namespace FanControl
public partial class FanControlForm : Form
{
private FanController fanControl = new FanController();
private StartupManager startupManager = new StartupManager();
private StartupManager startupManager = new StartupManager(
"Steam Deck Fan Control",
"Starts Steam Deck Fan Control on Windows startup."
);
public FanControlForm()
{

View file

@ -8,6 +8,7 @@ using System.Diagnostics.Metrics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CommonHelpers;
namespace FanControl
{

View file

@ -29,7 +29,7 @@ namespace FanControl
FanMode.Max, new FanSensor.Profile()
{
Type = FanSensor.Profile.ProfileType.Constant,
MinRPM = Vlv0100.MAX_FAN_RPM
MinRPM = CommonHelpers.Vlv0100.MAX_FAN_RPM
}
},
{

View file

@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LibreHardwareMonitor.Hardware;
using CommonHelpers;
namespace FanControl
{

View file

@ -4,6 +4,9 @@
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="PerformanceOverlay.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="PerformanceOverlay.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<PerformanceOverlay.Settings>
@ -15,4 +18,14 @@
</setting>
</PerformanceOverlay.Settings>
</userSettings>
<applicationSettings>
<PerformanceOverlay.Settings>
<setting name="ShowOSDShortcut" serializeAs="String">
<value>F11</value>
</setting>
<setting name="CycleOSDShortcut" serializeAs="String">
<value>Shift+F11</value>
</setting>
</PerformanceOverlay.Settings>
</applicationSettings>
</configuration>

View file

@ -1,8 +1,10 @@
using PerformanceOverlay.External;
using Microsoft.VisualBasic.Logging;
using PerformanceOverlay.External;
using RTSSSharedMemoryNET;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -63,22 +65,27 @@ namespace PerformanceOverlay
osdTimer.Interval = 250;
osdTimer.Enabled = true;
GlobalHotKey.RegisterHotKey("F11", () =>
if (Settings.Default.ShowOSDShortcut != "")
{
showItem.Checked = !showItem.Checked;
});
GlobalHotKey.RegisterHotKey(Settings.Default.ShowOSDShortcut, () =>
{
showItem.Checked = !showItem.Checked;
});
}
// Select next overlay
GlobalHotKey.RegisterHotKey("Shift+F11", () =>
if (Settings.Default.CycleOSDShortcut != "")
{
var values = Enum.GetValues<Overlays.Mode>().ToList();
GlobalHotKey.RegisterHotKey(Settings.Default.CycleOSDShortcut, () =>
{
var values = Enum.GetValues<Overlays.Mode>().ToList();
int index = values.IndexOf(Settings.Default.OSDModeParsed);
Settings.Default.OSDModeParsed = values[(index + 1) % values.Count];
int index = values.IndexOf(Settings.Default.OSDModeParsed);
Settings.Default.OSDModeParsed = values[(index + 1) % values.Count];
showItem.Checked = true;
updateContextItems(contextMenu);
});
showItem.Checked = true;
updateContextItems(contextMenu);
});
}
}
private void updateContextItems(ContextMenuStrip contextMenu)
@ -117,6 +124,11 @@ namespace PerformanceOverlay
{
if (osd == null)
osd = new OSD("PerformanceOverlay");
uint offset = 0;
osdEmbedGraph(ref offset, ref osdOverlay, "[OBJ_FT_SMALL]", -8, -1, 1, 0, 50000.0f, EMBEDDED_OBJECT_GRAPH.FLAG_FRAMETIME);
osdEmbedGraph(ref offset, ref osdOverlay, "[OBJ_FT_LARGE]", -32, -2, 1, 0, 50000.0f, EMBEDDED_OBJECT_GRAPH.FLAG_FRAMETIME);
osd.Update(osdOverlay);
}
catch(SystemException)
@ -125,6 +137,15 @@ namespace PerformanceOverlay
}
}
private uint osdEmbedGraph(ref uint offset, ref String osdOverlay, String name, int dwWidth, int dwHeight, int dwMargin, float fltMin, float fltMax, EMBEDDED_OBJECT_GRAPH dwFlags)
{
uint size = osd.EmbedGraph(offset, new float[0], 0, dwWidth, dwHeight, dwMargin, fltMin, fltMax, dwFlags);
if (size > 0)
osdOverlay = osdOverlay.Replace(name, "<OBJ=" + offset.ToString("X") + ">");
offset += size;
return size;
}
private void ExitItem_Click(object? sender, EventArgs e)
{
Application.Exit();

View file

@ -90,14 +90,16 @@ namespace PerformanceOverlay
public static readonly String[] Helpers =
{
"<C0=008040><C1=0080C0><C2=C08080><C3=FF0000><C4=FFFFFF><C250=FF8000>",
"<A0=-4><A1=5><A2=-2><S0=-50><S1=50>",
"<A0=-4><A1=5><A2=-2><A5=-5><S0=-50><S1=50>",
};
public static readonly Entry OSD = new Entry
{
Nested = {
// Simple just FPS
new Entry { Text = "<C4><FR><C><A><A1><S1><C4> FPS", Include = { Mode.FPS } },
// Minimal and Detail
new Entry {
Nested =
{
@ -107,7 +109,7 @@ namespace PerformanceOverlay
Nested =
{
new Entry("<C4><A0>{BATT_%}<A><A1><S1> %<S><A>"),
new Entry("<C4><A0>{BATT_W}<A><A1><S1> W<S><A>")
new Entry("<C4><A0>{BATT_W}<A><A1><S1> W<S><A>") { IgnoreMissing = true }
}
},
new Entry
@ -117,7 +119,7 @@ namespace PerformanceOverlay
{
new Entry("<C4><A0>{GPU_%}<A><A1><S1> %<S><A>"),
new Entry("<C4><A0>{GPU_W}<A><A1><S1> W<S><A>"),
new Entry { Text = "<C4><A0>{GPU_T}<A><A1><S1> C<S><A>", IgnoreMissing = true }
new Entry { Text = "<C4><A0>{GPU_T}<A><A1><S1> C<S><A>", IgnoreMissing = true, Include = { Mode.Detail } }
}
},
new Entry
@ -127,51 +129,57 @@ namespace PerformanceOverlay
{
new Entry("<C4><A0>{CPU_%}<A><A1><S1> %<S><A>"),
new Entry("<C4><A0>{CPU_W}<A><A1><S1> W<S><A>"),
new Entry { Text = "<C4><A0>{CPU_T}<A><A1><S1> C<S><A>", IgnoreMissing = true }
new Entry { Text = "<C4><A0>{CPU_T}<A><A1><S1> C<S><A>", IgnoreMissing = true, Include = { Mode.Detail } }
}
},
new Entry
{
Text = "<C1>RAM<C>",
Nested =
{
new Entry("<C4><A0>{MEM_GB}<A><A1><S1> GiB<S><A>")
}
Nested = { new Entry("<C4><A0>{MEM_GB}<A><A1><S1> GiB<S><A>") }
},
new Entry
{
Text = "<C1>FAN<C>",
Nested = { new Entry("<C4><A5>{FAN_RPM}<A><A1><S1> RPM<S><A>") },
Include = { Mode.Detail }
},
new Entry
{
Text = "<C2><APP><C>",
Nested =
{
new Entry("<A0><C4><FR><C><A><A1><S1><C4> FPS<C><S><A>")
}
Nested = { new Entry("<A0><C4><FR><C><A><A1><S1><C4> FPS<C><S><A>") }
},
new Entry
{
Text = "<C2><OBJ><C>"
Text = "<C2>[OBJ_FT_SMALL]<C><S1> <A0><FT><A><A1> ms<A><S><C>",
Include = { Mode.Detail }
}
},
Separator = "<C250>|<C> ",
Include = { Mode.Minimal }
Include = { Mode.Minimal, Mode.Detail }
},
new Entry { Text = "<C0>MEM<C> <A0>{MEM_MB}<A><A1><S1> MB<S>", Exclude = { Mode.FPS, Mode.Minimal } },
new Entry { Text = "<C1>CPU<C> <A0>{CPU_%}<A><A1><S1> %<S><A>", Exclude = { Mode.FPS, Mode.Minimal } },
new Entry { Text = "<C1>RAM<C> <A0>{GPU_MB}<A><A1><S1> MB<S><A>", Exclude = { Mode.FPS, Mode.Minimal } },
new Entry { Text = "<C2><APP><C> <A0><C4><FR><C><A><A1><S1><C4> FPS<C><S><A> <A0><C4><FT><C><A><A1><S1><C4> ms<C><S><A>", Exclude = { Mode.FPS, Mode.Minimal } },
new Entry {
Text = "<C1>BAT<C> ",
Nested = {
new Entry("<A0>{BATT_%}<A><A1><S1> %<S><A>"),
new Entry("<A0>{BATT_W}<A><A1><S1> W<S><A>")
Nested =
{
new Entry { Text = "<C1>CPU<C> <A0>{CPU_%}<A><A1><S1> %<S><A> <A0>{CPU_T}<A><A1><S1> C<S><A>" },
new Entry { Text = "<C1>GPU<C> <A0>{GPU_%}<A><A1><S1> %<S><A> <A0>{GPU_T}<A><A1><S1> C<S><A>" },
new Entry { Text = "<C1>RAM<C> <A0>{MEM_MB}<A><A1><S1> MB<S><A0>{GPU_MB}<A><A1><S1> MB<S><A>" },
new Entry { Text = "<C1>FAN<C> <A0>{FAN_RPM}<A><A1><S1> RPM<S><A>" },
new Entry { Text = "<C2><APP><C> <A0><C4><FR><C><A><A1><S1><C4> FPS<C><S><A> <A0><C4><FT><C><A><A1><S1><C4> ms<C><S><A>" },
new Entry {
Text = "<C1>BAT<C> ",
Nested = {
new Entry("<A0>{BATT_%}<A><A1><S1> %<S><A>"),
new Entry("<A0>{BATT_W}<A><A1><S1> W<S><A>")
}
},
new Entry { Text = "<C2><S1>Frametime<S>" },
new Entry { Text = "[OBJ_FT_LARGE]<S1> <A0><FT><A><A1> ms<A><S><C>" },
},
Exclude = { Mode.FPS, Mode.Minimal }
},
new Entry { Text = "<C2><S1>Frametime<S>", Exclude = { Mode.FPS, Mode.Minimal } },
new Entry { Text = "<OBJ>", Exclude = { Mode.FPS, Mode.Minimal } },
new Entry { Text = "<S1> <A0><FT><A><A1> ms<A><S><C>", Exclude = { Mode.FPS, Mode.Minimal } }
},
Separator = "\r\n"
Separator = "\r\n",
Include = { Mode.All }
}
}
};
public static String GetOSD(Mode mode, Sensors sensors)

View file

@ -27,6 +27,10 @@
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CommonHelpers\CommonHelpers.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="RTSSSharedMemoryNET">
<HintPath>RTSSSharedMemoryNET.dll</HintPath>

View file

@ -1,4 +1,5 @@
using RTSSSharedMemoryNET;
using System.Diagnostics;
namespace PerformanceOverlay
{
@ -13,8 +14,13 @@ namespace PerformanceOverlay
{
foreach (var entry in RTSSSharedMemoryNET.OSD.GetOSDEntries())
{
Console.WriteLine("Entry: {0}", entry.Owner);
Console.WriteLine("\t", entry.Text);
Trace.WriteLine("Entry: {0}", entry.Owner);
Trace.WriteLine("\t", entry.Text);
using (var newOSD = new OSD("New OSD"))
{
newOSD.Update(entry.Text);
}
}
}
catch(SystemException)

View file

@ -6,6 +6,7 @@ using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Navigation;
using static PerformanceOverlay.Sensors;
namespace PerformanceOverlay
@ -207,6 +208,16 @@ namespace PerformanceOverlay
SensorName = "Charge/Discharge Rate",
Format = "F1"
}
},
{
"FAN_RPM", new UserValueSensor()
{
Value = delegate ()
{
return (float)CommonHelpers.Vlv0100.GetFanRPM();
},
Format = "F0"
}
}
};

View file

@ -46,5 +46,23 @@ namespace PerformanceOverlay {
this["OSDMode"] = value;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("F11")]
public string ShowOSDShortcut {
get {
return ((string)(this["ShowOSDShortcut"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("Shift+F11")]
public string CycleOSDShortcut {
get {
return ((string)(this["CycleOSDShortcut"]));
}
}
}
}

View file

@ -8,5 +8,11 @@
<Setting Name="OSDMode" Type="System.String" Scope="User">
<Value Profile="(Default)">FPS</Value>
</Setting>
<Setting Name="ShowOSDShortcut" Type="System.String" Scope="Application">
<Value Profile="(Default)">F11</Value>
</Setting>
<Setting Name="CycleOSDShortcut" Type="System.String" Scope="Application">
<Value Profile="(Default)">Shift+F11</Value>
</Setting>
</Settings>
</SettingsFile>

View file

@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FanControl", "FanControl\Fa
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PerformanceOverlay", "PerformanceOverlay\PerformanceOverlay.csproj", "{DCA71DCC-A3ED-4890-A56C-3E2183A3C023}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommonHelpers", "CommonHelpers\CommonHelpers.csproj", "{17728E90-015B-4221-8AA8-68FB359FA12F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -41,6 +43,18 @@ Global
{DCA71DCC-A3ED-4890-A56C-3E2183A3C023}.Release|x64.Build.0 = Release|Any CPU
{DCA71DCC-A3ED-4890-A56C-3E2183A3C023}.Release|x86.ActiveCfg = Release|Any CPU
{DCA71DCC-A3ED-4890-A56C-3E2183A3C023}.Release|x86.Build.0 = Release|Any CPU
{17728E90-015B-4221-8AA8-68FB359FA12F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{17728E90-015B-4221-8AA8-68FB359FA12F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{17728E90-015B-4221-8AA8-68FB359FA12F}.Debug|x64.ActiveCfg = Debug|Any CPU
{17728E90-015B-4221-8AA8-68FB359FA12F}.Debug|x64.Build.0 = Debug|Any CPU
{17728E90-015B-4221-8AA8-68FB359FA12F}.Debug|x86.ActiveCfg = Debug|Any CPU
{17728E90-015B-4221-8AA8-68FB359FA12F}.Debug|x86.Build.0 = Debug|Any CPU
{17728E90-015B-4221-8AA8-68FB359FA12F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{17728E90-015B-4221-8AA8-68FB359FA12F}.Release|Any CPU.Build.0 = Release|Any CPU
{17728E90-015B-4221-8AA8-68FB359FA12F}.Release|x64.ActiveCfg = Release|Any CPU
{17728E90-015B-4221-8AA8-68FB359FA12F}.Release|x64.Build.0 = Release|Any CPU
{17728E90-015B-4221-8AA8-68FB359FA12F}.Release|x86.ActiveCfg = Release|Any CPU
{17728E90-015B-4221-8AA8-68FB359FA12F}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE