From cefb60528bbc55b6816063507d4370138a8c52d7 Mon Sep 17 00:00:00 2001 From: Anandb71 Date: Sun, 11 Jan 2026 19:25:31 +0530 Subject: [PATCH 1/4] Add speed source selection setting - choose CPU, GPU, or Memory --- RunCat365/ContextMenuManager.cs | 47 ++++++++++++++++++- RunCat365/Program.cs | 25 ++++++++-- RunCat365/Properties/UserSettings.Designer.cs | 12 +++++ RunCat365/Properties/UserSettings.settings | 3 ++ RunCat365/SpeedSource.cs | 34 ++++++++++++++ 5 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 RunCat365/SpeedSource.cs diff --git a/RunCat365/ContextMenuManager.cs b/RunCat365/ContextMenuManager.cs index 81591f21..3a71697b 100644 --- a/RunCat365/ContextMenuManager.cs +++ b/RunCat365/ContextMenuManager.cs @@ -36,6 +36,9 @@ internal ContextMenuManager( Action setFPSMaxLimit, Func getLaunchAtStartup, Func toggleLaunchAtStartup, + Func getSpeedSource, + Action setSpeedSource, + bool isGpuAvailable, Action openRepository, Action onExit ) @@ -99,11 +102,37 @@ Action onExit }; launchAtStartupMenu.Click += (sender, e) => HandleStartupMenuClick(sender, toggleLaunchAtStartup); + var speedSourceMenu = new CustomToolStripMenuItem("Speed based on"); + var cpuSpeedItem = new CustomToolStripMenuItem("CPU") + { + Checked = getSpeedSource() == SpeedSource.CPU + }; + cpuSpeedItem.Click += (sender, e) => HandleSpeedSourceClick(speedSourceMenu, sender, SpeedSource.CPU, setSpeedSource); + speedSourceMenu.DropDownItems.Add(cpuSpeedItem); + + if (isGpuAvailable) + { + var gpuSpeedItem = new CustomToolStripMenuItem("GPU") + { + Checked = getSpeedSource() == SpeedSource.GPU + }; + gpuSpeedItem.Click += (sender, e) => HandleSpeedSourceClick(speedSourceMenu, sender, SpeedSource.GPU, setSpeedSource); + speedSourceMenu.DropDownItems.Add(gpuSpeedItem); + } + + var memorySpeedItem = new CustomToolStripMenuItem("Memory") + { + Checked = getSpeedSource() == SpeedSource.Memory + }; + memorySpeedItem.Click += (sender, e) => HandleSpeedSourceClick(speedSourceMenu, sender, SpeedSource.Memory, setSpeedSource); + speedSourceMenu.DropDownItems.Add(memorySpeedItem); + var settingsMenu = new CustomToolStripMenuItem(Strings.Menu_Settings); settingsMenu.DropDownItems.AddRange( themeMenu, fpsMaxLimitMenu, - launchAtStartupMenu + launchAtStartupMenu, + speedSourceMenu ); var endlessGameMenu = new CustomToolStripMenuItem(Strings.Menu_EndlessGame); @@ -175,6 +204,22 @@ Action assignValueAction } } + private static void HandleSpeedSourceClick( + ToolStripMenuItem parentMenu, + object? sender, + SpeedSource source, + Action setSpeedSource + ) + { + if (sender is null) return; + foreach (ToolStripMenuItem childItem in parentMenu.DropDownItems) + { + childItem.Checked = false; + } + ((ToolStripMenuItem)sender).Checked = true; + setSpeedSource(source); + } + private static Bitmap? GetRunnerThumbnailBitmap(Theme systemTheme, Runner runner) { var iconName = $"{systemTheme.GetString()}_{runner.GetString()}_0".ToLower(); diff --git a/RunCat365/Program.cs b/RunCat365/Program.cs index ccdd51e5..a176656b 100644 --- a/RunCat365/Program.cs +++ b/RunCat365/Program.cs @@ -64,6 +64,7 @@ internal class RunCat365ApplicationContext : ApplicationContext private Runner runner = Runner.Cat; private Theme manualTheme = Theme.System; private FPSMaxLimit fpsMaxLimit = FPSMaxLimit.FPS40; + private SpeedSource speedSource = SpeedSource.CPU; private int fetchCounter = 5; public RunCat365ApplicationContext() @@ -72,6 +73,7 @@ public RunCat365ApplicationContext() _ = Enum.TryParse(UserSettings.Default.Runner, out runner); _ = Enum.TryParse(UserSettings.Default.Theme, out manualTheme); _ = Enum.TryParse(UserSettings.Default.FPSMaxLimit, out fpsMaxLimit); + _ = SpeedSourceExtension.TryParse(UserSettings.Default.SpeedSource, out speedSource); SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(UserPreferenceChanged); @@ -92,6 +94,9 @@ public RunCat365ApplicationContext() f => ChangeFPSMaxLimit(f), () => launchAtStartupManager.GetStartup(), s => launchAtStartupManager.SetStartup(s), + () => speedSource, + s => ChangeSpeedSource(s), + gpuRepository.IsAvailable, () => OpenRepository(), () => Application.Exit() ); @@ -179,6 +184,13 @@ private void ChangeFPSMaxLimit(FPSMaxLimit f) UserSettings.Default.Save(); } + private void ChangeSpeedSource(SpeedSource source) + { + speedSource = source; + UserSettings.Default.SpeedSource = source.GetString(); + UserSettings.Default.Save(); + } + private void AnimationTick(object? sender, EventArgs e) { contextMenuManager.AdvanceFrame(); @@ -203,10 +215,15 @@ NetworkInfo networkInfo contextMenuManager.SetSystemInfoMenuText(string.Join("\n", [.. systemInfoValues])); } - private int CalculateInterval(float cpuTotalValue) + private int CalculateInterval(float cpuValue, float gpuValue, float memoryValue) { - // Range of interval: 25-500 (ms) = 2-40 (fps) - var speed = (float)Math.Max(1.0f, (cpuTotalValue / 5.0f) * fpsMaxLimit.GetRate()); + var load = speedSource switch + { + SpeedSource.GPU => gpuValue, + SpeedSource.Memory => memoryValue, + _ => cpuValue + }; + var speed = (float)Math.Max(1.0f, (load / 5.0f) * fpsMaxLimit.GetRate()); return (int)(500.0f / speed); } @@ -226,7 +243,7 @@ private void FetchTick(object? state, EventArgs e) FetchSystemInfo(cpuInfo, gpuInfo, memoryInfo, storageInfo, networkInfo); animateTimer.Stop(); - animateTimer.Interval = CalculateInterval(cpuInfo.Total); + animateTimer.Interval = CalculateInterval(cpuInfo.Total, gpuInfo.Utilization, memoryInfo.MemoryLoad); animateTimer.Start(); } diff --git a/RunCat365/Properties/UserSettings.Designer.cs b/RunCat365/Properties/UserSettings.Designer.cs index 72b595d0..75c2bad4 100644 --- a/RunCat365/Properties/UserSettings.Designer.cs +++ b/RunCat365/Properties/UserSettings.Designer.cs @@ -70,5 +70,17 @@ public bool FirstLaunch { this["FirstLaunch"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("CPU")] + public string SpeedSource { + get { + return ((string)(this["SpeedSource"])); + } + set { + this["SpeedSource"] = value; + } + } } } diff --git a/RunCat365/Properties/UserSettings.settings b/RunCat365/Properties/UserSettings.settings index 88a899a0..923299d1 100644 --- a/RunCat365/Properties/UserSettings.settings +++ b/RunCat365/Properties/UserSettings.settings @@ -14,5 +14,8 @@ True + + CPU + \ No newline at end of file diff --git a/RunCat365/SpeedSource.cs b/RunCat365/SpeedSource.cs new file mode 100644 index 00000000..9076f233 --- /dev/null +++ b/RunCat365/SpeedSource.cs @@ -0,0 +1,34 @@ +namespace RunCat365 +{ + internal enum SpeedSource + { + CPU, + GPU, + Memory + } + + internal static class SpeedSourceExtension + { + internal static string GetString(this SpeedSource source) + { + return source switch + { + SpeedSource.CPU => "CPU", + SpeedSource.GPU => "GPU", + SpeedSource.Memory => "Memory", + _ => "CPU" + }; + } + + internal static bool TryParse(string? value, out SpeedSource source) + { + source = value switch + { + "GPU" => SpeedSource.GPU, + "Memory" => SpeedSource.Memory, + _ => SpeedSource.CPU + }; + return true; + } + } +} From dd2c341f36d0904fcffa5fcdc50c7e20553f5ae8 Mon Sep 17 00:00:00 2001 From: Anandb71 Date: Tue, 13 Jan 2026 20:10:15 +0530 Subject: [PATCH 2/4] Fix compilation after rebase: update to use GPUInfo.Total --- RunCat365/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RunCat365/Program.cs b/RunCat365/Program.cs index a176656b..f70e33e7 100644 --- a/RunCat365/Program.cs +++ b/RunCat365/Program.cs @@ -243,7 +243,7 @@ private void FetchTick(object? state, EventArgs e) FetchSystemInfo(cpuInfo, gpuInfo, memoryInfo, storageInfo, networkInfo); animateTimer.Stop(); - animateTimer.Interval = CalculateInterval(cpuInfo.Total, gpuInfo.Utilization, memoryInfo.MemoryLoad); + animateTimer.Interval = CalculateInterval(cpuInfo.Total, gpuInfo.Total, memoryInfo.MemoryLoad); animateTimer.Start(); } From ae52ec88f9a8a6d7cbabcb4a11e4444817a2e4dd Mon Sep 17 00:00:00 2001 From: anandb71 Date: Sat, 24 Jan 2026 17:37:48 +0530 Subject: [PATCH 3/4] feat: dynamic tooltip shows speed source metric (CPU/GPU/Memory) --- RunCat365/GPURepository.cs | 5 +++++ RunCat365/MemoryRepository.cs | 5 +++++ RunCat365/Program.cs | 8 +++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/RunCat365/GPURepository.cs b/RunCat365/GPURepository.cs index dac407f4..5710284d 100644 --- a/RunCat365/GPURepository.cs +++ b/RunCat365/GPURepository.cs @@ -12,6 +12,11 @@ struct GPUInfo internal static class GPUInfoExtension { + internal static string GetDescription(this GPUInfo gpuInfo) + { + return $"GPU: {gpuInfo.Total:f1}%"; + } + internal static List GenerateIndicator(this GPUInfo gpuInfo) { var resultLines = new List diff --git a/RunCat365/MemoryRepository.cs b/RunCat365/MemoryRepository.cs index 0675a177..d415d5f1 100644 --- a/RunCat365/MemoryRepository.cs +++ b/RunCat365/MemoryRepository.cs @@ -27,6 +27,11 @@ struct MemoryInfo internal static class MemoryInfoExtension { + internal static string GetDescription(this MemoryInfo memoryInfo) + { + return $"{Strings.SystemInfo_Memory}: {memoryInfo.MemoryLoad}%"; + } + internal static List GenerateIndicator(this MemoryInfo memoryInfo) { var resultLines = new List diff --git a/RunCat365/Program.cs b/RunCat365/Program.cs index f70e33e7..dec855f2 100644 --- a/RunCat365/Program.cs +++ b/RunCat365/Program.cs @@ -204,7 +204,13 @@ private void FetchSystemInfo( NetworkInfo networkInfo ) { - contextMenuManager.SetNotifyIconText(cpuInfo.GetDescription()); + var tooltipText = speedSource switch + { + SpeedSource.GPU => gpuInfo.GetDescription(), + SpeedSource.Memory => memoryInfo.GetDescription(), + _ => cpuInfo.GetDescription() + }; + contextMenuManager.SetNotifyIconText(tooltipText); var systemInfoValues = new List(); systemInfoValues.AddRange(cpuInfo.GenerateIndicator()); From 8b97736fa2535d0eb06905c865f7890badefd19e Mon Sep 17 00:00:00 2001 From: anandb71 Date: Sat, 24 Jan 2026 17:52:26 +0530 Subject: [PATCH 4/4] refactor: replace SpeedSourceExtension with Enum methods --- RunCat365/Program.cs | 2 +- RunCat365/SpeedSource.cs | 19 +------------------ 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/RunCat365/Program.cs b/RunCat365/Program.cs index dec855f2..66024e43 100644 --- a/RunCat365/Program.cs +++ b/RunCat365/Program.cs @@ -73,7 +73,7 @@ public RunCat365ApplicationContext() _ = Enum.TryParse(UserSettings.Default.Runner, out runner); _ = Enum.TryParse(UserSettings.Default.Theme, out manualTheme); _ = Enum.TryParse(UserSettings.Default.FPSMaxLimit, out fpsMaxLimit); - _ = SpeedSourceExtension.TryParse(UserSettings.Default.SpeedSource, out speedSource); + _ = Enum.TryParse(UserSettings.Default.SpeedSource, out speedSource); SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(UserPreferenceChanged); diff --git a/RunCat365/SpeedSource.cs b/RunCat365/SpeedSource.cs index 9076f233..63961ee0 100644 --- a/RunCat365/SpeedSource.cs +++ b/RunCat365/SpeedSource.cs @@ -11,24 +11,7 @@ internal static class SpeedSourceExtension { internal static string GetString(this SpeedSource source) { - return source switch - { - SpeedSource.CPU => "CPU", - SpeedSource.GPU => "GPU", - SpeedSource.Memory => "Memory", - _ => "CPU" - }; - } - - internal static bool TryParse(string? value, out SpeedSource source) - { - source = value switch - { - "GPU" => SpeedSource.GPU, - "Memory" => SpeedSource.Memory, - _ => SpeedSource.CPU - }; - return true; + return source.ToString(); } } }