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/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 ccdd51e5..66024e43 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); + _ = Enum.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(); @@ -192,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()); @@ -203,10 +221,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 +249,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.Total, 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..63961ee0 --- /dev/null +++ b/RunCat365/SpeedSource.cs @@ -0,0 +1,17 @@ +namespace RunCat365 +{ + internal enum SpeedSource + { + CPU, + GPU, + Memory + } + + internal static class SpeedSourceExtension + { + internal static string GetString(this SpeedSource source) + { + return source.ToString(); + } + } +}