mirror of
https://github.com/ayufan/steam-deck-tools.git
synced 2026-02-02 13:44:22 +01:00
PowerControl: Decompose MenuStack.cs into Options/
This commit is contained in:
parent
ebe1cdba87
commit
f207c12935
|
|
@ -2,7 +2,7 @@ namespace PowerControl.Menu
|
|||
{
|
||||
public abstract class MenuItem
|
||||
{
|
||||
public static readonly String[] Helpers =
|
||||
public static readonly String[] OSDHelpers =
|
||||
{
|
||||
"<C0=008040><C1=0080C0><C2=C08080><C3=FF0000><C4=FFFFFF><C250=FF8000>",
|
||||
"<A0=-4><A1=5><A2=-2><A5=-5><S0=-50><S1=50>",
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace PowerControl.Menu
|
|||
{
|
||||
var sb = new StringBuilder();
|
||||
|
||||
sb.AppendJoin("", Helpers);
|
||||
sb.AppendJoin("", OSDHelpers);
|
||||
if (Name != "")
|
||||
sb.AppendLine(Color(Name, Colors.Blue));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,3 @@
|
|||
using CommonHelpers;
|
||||
using PowerControl.Helpers;
|
||||
using PowerControl.Helpers.AMD;
|
||||
using System.Diagnostics;
|
||||
using static PowerControl.Helpers.AMD.DCE;
|
||||
|
||||
namespace PowerControl
|
||||
{
|
||||
internal class MenuStack
|
||||
|
|
@ -13,531 +7,28 @@ namespace PowerControl
|
|||
Name = String.Format("\r\n\r\nPower Control v{0}\r\n", Application.ProductVersion.ToString()),
|
||||
Items =
|
||||
{
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Brightness",
|
||||
Options = { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100 },
|
||||
CycleOptions = false,
|
||||
CurrentValue = delegate()
|
||||
{
|
||||
return Helpers.WindowsSettingsBrightnessController.Get(5.0);
|
||||
},
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
Helpers.WindowsSettingsBrightnessController.Set((int)selected);
|
||||
|
||||
return Helpers.WindowsSettingsBrightnessController.Get(5.0);
|
||||
}
|
||||
},
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Volume",
|
||||
Options = { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100 },
|
||||
CycleOptions = false,
|
||||
CurrentValue = delegate()
|
||||
{
|
||||
try { return Helpers.AudioManager.GetMasterVolume(5.0); }
|
||||
catch(Exception) { return null; }
|
||||
},
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
try
|
||||
{
|
||||
Helpers.AudioManager.SetMasterVolumeMute(false);
|
||||
Helpers.AudioManager.SetMasterVolume((int)selected);
|
||||
|
||||
return Helpers.AudioManager.GetMasterVolume(5.0);
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
// In some cases MasterVolume device is missing
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
Options.Brightness.Instance,
|
||||
Options.Volume.Instance,
|
||||
new Menu.MenuItemSeparator(),
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Resolution",
|
||||
ApplyDelay = 1000,
|
||||
ResetValue = () => {
|
||||
if (!GPUScaling.SafeResolutionChange && !Settings.Default.EnableExperimentalFeatures)
|
||||
return null;
|
||||
return DisplayResolutionController.GetAllResolutions().Last();
|
||||
},
|
||||
OptionsValues = delegate()
|
||||
{
|
||||
var resolutions = DisplayResolutionController.GetAllResolutions();
|
||||
if (resolutions.Count() > 1)
|
||||
return resolutions.Select(item => (object)item).ToArray();
|
||||
return null;
|
||||
},
|
||||
CurrentValue = delegate()
|
||||
{
|
||||
if (!GPUScaling.SafeResolutionChange && !Settings.Default.EnableExperimentalFeatures)
|
||||
return null;
|
||||
return DisplayResolutionController.GetResolution();
|
||||
},
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
DisplayResolutionController.SetResolution((DisplayResolutionController.DisplayResolution)selected);
|
||||
// force refresh Refresh Rate
|
||||
Root["Refresh Rate"].Update();
|
||||
// force reset and refresh of FPS limit
|
||||
Root["FPS Limit"].Reset();
|
||||
Root["FPS Limit"].Update();
|
||||
return DisplayResolutionController.GetResolution();
|
||||
}
|
||||
},
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Refresh Rate",
|
||||
ApplyDelay = 1000,
|
||||
ResetValue = () => { return DisplayResolutionController.GetRefreshRates().Max(); },
|
||||
OptionsValues = delegate()
|
||||
{
|
||||
var refreshRates = DisplayResolutionController.GetRefreshRates();
|
||||
if (refreshRates.Count() > 1)
|
||||
return refreshRates.Select(item => (object)item).ToArray();
|
||||
return null;
|
||||
},
|
||||
CurrentValue = delegate()
|
||||
{
|
||||
return DisplayResolutionController.GetRefreshRate();
|
||||
},
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
DisplayResolutionController.SetRefreshRate((int)selected);
|
||||
// force reset and refresh of FPS limit
|
||||
Root["FPS Limit"].Reset();
|
||||
Root["FPS Limit"].Update();
|
||||
return DisplayResolutionController.GetRefreshRate();
|
||||
}
|
||||
},
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "FPS Limit",
|
||||
ApplyDelay = 500,
|
||||
ResetValue = () => { return "Off"; },
|
||||
OptionsValues = delegate()
|
||||
{
|
||||
var refreshRate = DisplayResolutionController.GetRefreshRate();
|
||||
return new object[]
|
||||
{
|
||||
refreshRate / 4, refreshRate / 2, refreshRate, "Off"
|
||||
};
|
||||
},
|
||||
CurrentValue = delegate()
|
||||
{
|
||||
try
|
||||
{
|
||||
RTSS.LoadProfile();
|
||||
if (RTSS.GetProfileProperty("FramerateLimit", out int framerate))
|
||||
return (framerate == 0) ? "Off" : framerate;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return null;
|
||||
},
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
try
|
||||
{
|
||||
int framerate = 0;
|
||||
if (selected != null && selected.ToString() != "Off")
|
||||
framerate = (int)selected;
|
||||
|
||||
RTSS.LoadProfile();
|
||||
if (!RTSS.SetProfileProperty("FramerateLimit", framerate))
|
||||
return null;
|
||||
if (!RTSS.GetProfileProperty("FramerateLimit", out framerate))
|
||||
return null;
|
||||
RTSS.SaveProfile();
|
||||
RTSS.UpdateProfiles();
|
||||
return (framerate == 0) ? "Off" : framerate;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "GPU Scaling",
|
||||
ApplyDelay = 1000,
|
||||
Options = Enum.GetValues<GPUScaling.ScalingMode>().Cast<object>().Prepend("Off").ToArray(),
|
||||
CurrentValue = delegate()
|
||||
{
|
||||
if (!GPUScaling.IsSupported)
|
||||
return null;
|
||||
if (!GPUScaling.Enabled)
|
||||
return "Off";
|
||||
return GPUScaling.Mode;
|
||||
},
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
if (!GPUScaling.IsSupported)
|
||||
return null;
|
||||
|
||||
if (selected is GPUScaling.ScalingMode)
|
||||
GPUScaling.Mode = (GPUScaling.ScalingMode)selected;
|
||||
else
|
||||
GPUScaling.Enabled = false;
|
||||
|
||||
// Since the RadeonSoftware will try to revert values
|
||||
RadeonSoftware.Kill();
|
||||
|
||||
Root["Resolution"].Update();
|
||||
Root["Refresh Rate"].Update();
|
||||
Root["FPS Limit"].Reset();
|
||||
Root["FPS Limit"].Update();
|
||||
|
||||
if (!GPUScaling.Enabled)
|
||||
return "Off";
|
||||
return GPUScaling.Mode;
|
||||
}
|
||||
},
|
||||
Options.Resolution.Instance,
|
||||
Options.RefreshRate.Instance,
|
||||
Options.FPSLimit.Instance,
|
||||
Options.GPUScalingItem.Instance,
|
||||
#if DEBUG
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Sharpening",
|
||||
ApplyDelay = 500,
|
||||
Options = { "Off", "On" },
|
||||
CurrentValue = delegate()
|
||||
{
|
||||
var value = ImageSharpening.Enabled;
|
||||
if (value is null)
|
||||
return null;
|
||||
return value.Value ? "On" : "Off";
|
||||
},
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
ImageSharpening.Enabled = (string)selected == "On";
|
||||
|
||||
var value = ImageSharpening.Enabled;
|
||||
if (value is null)
|
||||
return null;
|
||||
return value.Value ? "On" : "Off";
|
||||
}
|
||||
},
|
||||
Options.Sharpening.Instance,
|
||||
#endif
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Colors",
|
||||
ApplyDelay = 1000,
|
||||
Options = Enum.GetValues<DCE.Mode>().Cast<object>().ToList(),
|
||||
CurrentValue = delegate()
|
||||
{
|
||||
return DCE.Current;
|
||||
},
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
if (DCE.Current is null)
|
||||
return null;
|
||||
|
||||
DCE.Current = (DCE.Mode)selected;
|
||||
RadeonSoftware.Kill();
|
||||
return DCE.Current;
|
||||
}
|
||||
},
|
||||
Options.GPUColors.Instance,
|
||||
new Menu.MenuItemSeparator(),
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "TDP",
|
||||
Options = { "3W", "4W", "5W", "6W", "7W", "8W", "10W", "12W", "15W" },
|
||||
ApplyDelay = 1000,
|
||||
ResetValue = () => { return "15W"; },
|
||||
ActiveOption = "?",
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
if (!Settings.Default.AckAntiCheat(
|
||||
Controller.TitleWithVersion,
|
||||
"TDP",
|
||||
"Changing TDP requires kernel access for a short period. Leave the game if it uses anti-cheat protection.")
|
||||
)
|
||||
return null;
|
||||
|
||||
uint mW = uint.Parse(selected.ToString().Replace("W", "")) * 1000;
|
||||
|
||||
if (VangoghGPU.IsSupported)
|
||||
{
|
||||
return Instance.WithGlobalMutex<object>(200, () =>
|
||||
{
|
||||
using (var sd = VangoghGPU.Open())
|
||||
{
|
||||
if (sd is null)
|
||||
return null;
|
||||
|
||||
sd.SlowTDP = mW;
|
||||
sd.FastTDP = mW;
|
||||
}
|
||||
|
||||
return selected;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
uint stampLimit = mW/10;
|
||||
|
||||
Process.Start(new ProcessStartInfo()
|
||||
{
|
||||
FileName = "Resources/RyzenAdj/ryzenadj.exe",
|
||||
ArgumentList = {
|
||||
"--stapm-limit=" + stampLimit.ToString(),
|
||||
"--slow-limit=" + mW.ToString(),
|
||||
"--fast-limit=" + mW.ToString(),
|
||||
},
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
});
|
||||
|
||||
return selected;
|
||||
}
|
||||
}
|
||||
},
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "GPU",
|
||||
Options = { "Default", "400MHz", "800MHz", "1200MHz", "1600MHz" },
|
||||
ApplyDelay = 1000,
|
||||
Visible = VangoghGPU.IsSupported,
|
||||
ActiveOption = "?",
|
||||
ResetValue = () => { return "Default"; },
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
if (!Settings.Default.AckAntiCheat(
|
||||
Controller.TitleWithVersion,
|
||||
"GPU",
|
||||
"Changing GPU frequency requires kernel access for a short period. Leave the game if it uses anti-cheat protection.")
|
||||
)
|
||||
return null;
|
||||
|
||||
return Instance.WithGlobalMutex<object>(200, () =>
|
||||
{
|
||||
using (var sd = VangoghGPU.Open())
|
||||
{
|
||||
if (sd is null)
|
||||
return null;
|
||||
|
||||
if (selected.ToString() == "Default")
|
||||
{
|
||||
sd.HardMinGfxClock = 200;
|
||||
return selected;
|
||||
}
|
||||
|
||||
sd.HardMinGfxClock = uint.Parse(selected.ToString().Replace("MHz", ""));
|
||||
return selected;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "CPU",
|
||||
Options = { "Default", "Power-Save", "Balanced", "Max" },
|
||||
ApplyDelay = 1000,
|
||||
ActiveOption = "?",
|
||||
Visible = VangoghGPU.IsSupported,
|
||||
ResetValue = () => { return "Default"; },
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
if (!Settings.Default.AckAntiCheat(
|
||||
Controller.TitleWithVersion,
|
||||
"CPU",
|
||||
"Changing GPU frequency requires kernel access for a short period. Leave the game if it uses anti-cheat protection.")
|
||||
)
|
||||
return null;
|
||||
|
||||
return Instance.WithGlobalMutex<object>(200, () =>
|
||||
{
|
||||
using (var sd = VangoghGPU.Open())
|
||||
{
|
||||
if (sd is null)
|
||||
return null;
|
||||
|
||||
switch(selected.ToString())
|
||||
{
|
||||
case "Default":
|
||||
sd.MinCPUClock = 1400;
|
||||
sd.MaxCPUClock = 3500;
|
||||
break;
|
||||
|
||||
case "Power-Save":
|
||||
sd.MinCPUClock = 1400;
|
||||
sd.MaxCPUClock = 1800;
|
||||
break;
|
||||
|
||||
case "Balanced":
|
||||
sd.MinCPUClock = 2200;
|
||||
sd.MaxCPUClock = 2800;
|
||||
break;
|
||||
|
||||
case "Max":
|
||||
sd.MinCPUClock = 3000;
|
||||
sd.MaxCPUClock = 3500;
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "SMT",
|
||||
ApplyDelay = 500,
|
||||
Options = { "No", "Yes" },
|
||||
ResetValue = () => { return "Yes"; },
|
||||
CurrentValue = delegate()
|
||||
{
|
||||
if (!RTSS.IsOSDForeground(out var processId))
|
||||
return null;
|
||||
if (!ProcessorCores.HasSMTThreads())
|
||||
return null;
|
||||
|
||||
return ProcessorCores.IsUsingSMT(processId.Value) ? "Yes" : "No";
|
||||
},
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
if (!RTSS.IsOSDForeground(out var processId))
|
||||
return null;
|
||||
if (!ProcessorCores.HasSMTThreads())
|
||||
return null;
|
||||
|
||||
ProcessorCores.SetProcessSMT(processId.Value, selected.ToString() == "Yes");
|
||||
|
||||
return ProcessorCores.IsUsingSMT(processId.Value) ? "Yes" : "No";
|
||||
}
|
||||
},
|
||||
Options.TDP.Instance,
|
||||
Options.GPUFrequency.Instance,
|
||||
Options.CPUFrequency.Instance,
|
||||
Options.SMT.Instance,
|
||||
new Menu.MenuItemSeparator(),
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "OSD",
|
||||
ApplyDelay = 500,
|
||||
OptionsValues = delegate()
|
||||
{
|
||||
return Enum.GetValues<OverlayEnabled>().Select(item => (object)item).ToArray();
|
||||
},
|
||||
CurrentValue = delegate()
|
||||
{
|
||||
if (SharedData<OverlayModeSetting>.GetExistingValue(out var value))
|
||||
return value.CurrentEnabled;
|
||||
return null;
|
||||
},
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
if (!SharedData<OverlayModeSetting>.GetExistingValue(out var value))
|
||||
return null;
|
||||
value.DesiredEnabled = (OverlayEnabled)selected;
|
||||
if (!SharedData<OverlayModeSetting>.SetExistingValue(value))
|
||||
return null;
|
||||
return selected;
|
||||
}
|
||||
},
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "OSD Mode",
|
||||
ApplyDelay = 500,
|
||||
OptionsValues = delegate()
|
||||
{
|
||||
return Enum.GetValues<OverlayMode>().Select(item => (object)item).ToArray();
|
||||
},
|
||||
CurrentValue = delegate()
|
||||
{
|
||||
if (SharedData<OverlayModeSetting>.GetExistingValue(out var value))
|
||||
return value.Current;
|
||||
return null;
|
||||
},
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
if (!SharedData<OverlayModeSetting>.GetExistingValue(out var value))
|
||||
return null;
|
||||
value.Desired = (OverlayMode)selected;
|
||||
if (!SharedData<OverlayModeSetting>.SetExistingValue(value))
|
||||
return null;
|
||||
return selected;
|
||||
}
|
||||
},
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "OSD Kernel Drivers",
|
||||
ApplyDelay = 500,
|
||||
OptionsValues = delegate()
|
||||
{
|
||||
return Enum.GetValues<KernelDriversLoaded>().Select(item => (object)item).ToArray();
|
||||
},
|
||||
CurrentValue = delegate()
|
||||
{
|
||||
if (SharedData<OverlayModeSetting>.GetExistingValue(out var value))
|
||||
return value.KernelDriversLoaded;
|
||||
return null;
|
||||
},
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
if (!SharedData<OverlayModeSetting>.GetExistingValue(out var value))
|
||||
return null;
|
||||
value.DesiredKernelDriversLoaded = (KernelDriversLoaded)selected;
|
||||
if (!SharedData<OverlayModeSetting>.SetExistingValue(value))
|
||||
return null;
|
||||
return selected;
|
||||
}
|
||||
},
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "FAN",
|
||||
ApplyDelay = 500,
|
||||
OptionsValues = delegate()
|
||||
{
|
||||
return Enum.GetValues<FanMode>().Select(item => (object)item).ToArray();
|
||||
},
|
||||
CurrentValue = delegate()
|
||||
{
|
||||
if (SharedData<FanModeSetting>.GetExistingValue(out var value))
|
||||
return value.Current;
|
||||
return null;
|
||||
},
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
if (!SharedData<FanModeSetting>.GetExistingValue(out var value))
|
||||
return null;
|
||||
value.Desired = (FanMode)selected;
|
||||
if (!SharedData<FanModeSetting>.SetExistingValue(value))
|
||||
return null;
|
||||
return selected;
|
||||
}
|
||||
},
|
||||
new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Controller",
|
||||
ApplyDelay = 500,
|
||||
OptionsValues = delegate()
|
||||
{
|
||||
if (SharedData<SteamControllerSetting>.GetExistingValue(out var value))
|
||||
return value.SelectableProfiles.SplitWithN();
|
||||
return null;
|
||||
},
|
||||
CurrentValue = delegate()
|
||||
{
|
||||
if (SharedData<SteamControllerSetting>.GetExistingValue(out var value))
|
||||
return value.CurrentProfile.Length > 0 ? value.CurrentProfile : null;
|
||||
return null;
|
||||
},
|
||||
ApplyValue = delegate(object selected)
|
||||
{
|
||||
if (!SharedData<SteamControllerSetting>.GetExistingValue(out var value))
|
||||
return null;
|
||||
value.DesiredProfile = (String)selected;
|
||||
if (!SharedData<SteamControllerSetting>.SetExistingValue(value))
|
||||
return null;
|
||||
return selected;
|
||||
}
|
||||
}
|
||||
Options.PerformanceOverlay.EnabledInstance,
|
||||
Options.PerformanceOverlay.ModeInstance,
|
||||
Options.PerformanceOverlay.KernelDriversInstance,
|
||||
Options.FanControl.Instance,
|
||||
Options.SteamController.Instance
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
22
PowerControl/Options/Brightness.cs
Normal file
22
PowerControl/Options/Brightness.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
namespace PowerControl.Options
|
||||
{
|
||||
public static class Brightness
|
||||
{
|
||||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Brightness",
|
||||
Options = { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100 },
|
||||
CycleOptions = false,
|
||||
CurrentValue = delegate ()
|
||||
{
|
||||
return Helpers.WindowsSettingsBrightnessController.Get(5.0);
|
||||
},
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
Helpers.WindowsSettingsBrightnessController.Set((int)selected);
|
||||
|
||||
return Helpers.WindowsSettingsBrightnessController.Get(5.0);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
62
PowerControl/Options/CPUFrequency.cs
Normal file
62
PowerControl/Options/CPUFrequency.cs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
using PowerControl.Helpers.AMD;
|
||||
|
||||
namespace PowerControl.Options
|
||||
{
|
||||
public static class CPUFrequency
|
||||
{
|
||||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "CPU",
|
||||
Options = { "Default", "Power-Save", "Balanced", "Max" },
|
||||
ApplyDelay = 1000,
|
||||
ActiveOption = "?",
|
||||
Visible = VangoghGPU.IsSupported,
|
||||
ResetValue = () => { return "Default"; },
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
if (!Settings.Default.AckAntiCheat(
|
||||
Controller.TitleWithVersion,
|
||||
"CPU",
|
||||
"Changing GPU frequency requires kernel access for a short period. Leave the game if it uses anti-cheat protection.")
|
||||
)
|
||||
return null;
|
||||
|
||||
return CommonHelpers.Instance.WithGlobalMutex<object>(200, () =>
|
||||
{
|
||||
using (var sd = VangoghGPU.Open())
|
||||
{
|
||||
if (sd is null)
|
||||
return null;
|
||||
|
||||
switch (selected.ToString())
|
||||
{
|
||||
case "Default":
|
||||
sd.MinCPUClock = 1400;
|
||||
sd.MaxCPUClock = 3500;
|
||||
break;
|
||||
|
||||
case "Power-Save":
|
||||
sd.MinCPUClock = 1400;
|
||||
sd.MaxCPUClock = 1800;
|
||||
break;
|
||||
|
||||
case "Balanced":
|
||||
sd.MinCPUClock = 2200;
|
||||
sd.MaxCPUClock = 2800;
|
||||
break;
|
||||
|
||||
case "Max":
|
||||
sd.MinCPUClock = 3000;
|
||||
sd.MaxCPUClock = 3500;
|
||||
break;
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
54
PowerControl/Options/FPSLimit.cs
Normal file
54
PowerControl/Options/FPSLimit.cs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
using CommonHelpers;
|
||||
using PowerControl.Helpers;
|
||||
|
||||
namespace PowerControl.Options
|
||||
{
|
||||
public static class FPSLimit
|
||||
{
|
||||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "FPS Limit",
|
||||
ApplyDelay = 500,
|
||||
ResetValue = () => { return "Off"; },
|
||||
OptionsValues = delegate ()
|
||||
{
|
||||
var refreshRate = DisplayResolutionController.GetRefreshRate();
|
||||
return new object[]
|
||||
{
|
||||
refreshRate / 4, refreshRate / 2, refreshRate, "Off"
|
||||
};
|
||||
},
|
||||
CurrentValue = delegate ()
|
||||
{
|
||||
try
|
||||
{
|
||||
RTSS.LoadProfile();
|
||||
if (RTSS.GetProfileProperty("FramerateLimit", out int framerate))
|
||||
return (framerate == 0) ? "Off" : framerate;
|
||||
}
|
||||
catch { }
|
||||
return null;
|
||||
},
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
try
|
||||
{
|
||||
int framerate = 0;
|
||||
if (selected != null && selected.ToString() != "Off")
|
||||
framerate = (int)selected;
|
||||
|
||||
RTSS.LoadProfile();
|
||||
if (!RTSS.SetProfileProperty("FramerateLimit", framerate))
|
||||
return null;
|
||||
if (!RTSS.GetProfileProperty("FramerateLimit", out framerate))
|
||||
return null;
|
||||
RTSS.SaveProfile();
|
||||
RTSS.UpdateProfiles();
|
||||
return (framerate == 0) ? "Off" : framerate;
|
||||
}
|
||||
catch { }
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
32
PowerControl/Options/FanControl.cs
Normal file
32
PowerControl/Options/FanControl.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using CommonHelpers;
|
||||
|
||||
namespace PowerControl.Options
|
||||
{
|
||||
public static class FanControl
|
||||
{
|
||||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "FAN",
|
||||
ApplyDelay = 500,
|
||||
OptionsValues = delegate ()
|
||||
{
|
||||
return Enum.GetValues<FanMode>().Select(item => (object)item).ToArray();
|
||||
},
|
||||
CurrentValue = delegate ()
|
||||
{
|
||||
if (SharedData<FanModeSetting>.GetExistingValue(out var value))
|
||||
return value.Current;
|
||||
return null;
|
||||
},
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
if (!SharedData<FanModeSetting>.GetExistingValue(out var value))
|
||||
return null;
|
||||
value.Desired = (FanMode)selected;
|
||||
if (!SharedData<FanModeSetting>.SetExistingValue(value))
|
||||
return null;
|
||||
return selected;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
27
PowerControl/Options/GPUColors.cs
Normal file
27
PowerControl/Options/GPUColors.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
using PowerControl.Helpers.AMD;
|
||||
|
||||
namespace PowerControl.Options
|
||||
{
|
||||
public static class GPUColors
|
||||
{
|
||||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Colors",
|
||||
ApplyDelay = 1000,
|
||||
Options = Enum.GetValues<DCE.Mode>().Cast<object>().ToList(),
|
||||
CurrentValue = delegate ()
|
||||
{
|
||||
return DCE.Current;
|
||||
},
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
if (DCE.Current is null)
|
||||
return null;
|
||||
|
||||
DCE.Current = (DCE.Mode)selected;
|
||||
RadeonSoftware.Kill();
|
||||
return DCE.Current;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
44
PowerControl/Options/GPUFrequency.cs
Normal file
44
PowerControl/Options/GPUFrequency.cs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
using PowerControl.Helpers.AMD;
|
||||
|
||||
namespace PowerControl.Options
|
||||
{
|
||||
public static class GPUFrequency
|
||||
{
|
||||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "GPU",
|
||||
Options = { "Default", "400MHz", "800MHz", "1200MHz", "1600MHz" },
|
||||
ApplyDelay = 1000,
|
||||
Visible = VangoghGPU.IsSupported,
|
||||
ActiveOption = "?",
|
||||
ResetValue = () => { return "Default"; },
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
if (!Settings.Default.AckAntiCheat(
|
||||
Controller.TitleWithVersion,
|
||||
"GPU",
|
||||
"Changing GPU frequency requires kernel access for a short period. Leave the game if it uses anti-cheat protection.")
|
||||
)
|
||||
return null;
|
||||
|
||||
return CommonHelpers.Instance.WithGlobalMutex<object>(200, () =>
|
||||
{
|
||||
using (var sd = VangoghGPU.Open())
|
||||
{
|
||||
if (sd is null)
|
||||
return null;
|
||||
|
||||
if (selected.ToString() == "Default")
|
||||
{
|
||||
sd.HardMinGfxClock = 200;
|
||||
return selected;
|
||||
}
|
||||
|
||||
sd.HardMinGfxClock = uint.Parse(selected.ToString().Replace("MHz", ""));
|
||||
return selected;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
44
PowerControl/Options/GPUScalingItem.cs
Normal file
44
PowerControl/Options/GPUScalingItem.cs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
using PowerControl.Helpers.AMD;
|
||||
|
||||
namespace PowerControl.Options
|
||||
{
|
||||
public static class GPUScalingItem
|
||||
{
|
||||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "GPU Scaling",
|
||||
ApplyDelay = 1000,
|
||||
Options = Enum.GetValues<GPUScaling.ScalingMode>().Cast<object>().Prepend("Off").ToArray(),
|
||||
CurrentValue = delegate ()
|
||||
{
|
||||
if (!GPUScaling.IsSupported)
|
||||
return null;
|
||||
if (!GPUScaling.Enabled)
|
||||
return "Off";
|
||||
return GPUScaling.Mode;
|
||||
},
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
if (!GPUScaling.IsSupported)
|
||||
return null;
|
||||
|
||||
if (selected is GPUScaling.ScalingMode)
|
||||
GPUScaling.Mode = (GPUScaling.ScalingMode)selected;
|
||||
else
|
||||
GPUScaling.Enabled = false;
|
||||
|
||||
// Since the RadeonSoftware will try to revert values
|
||||
RadeonSoftware.Kill();
|
||||
|
||||
Resolution.Instance.Update();
|
||||
RefreshRate.Instance.Update();
|
||||
FPSLimit.Instance.Reset();
|
||||
FPSLimit.Instance.Update();
|
||||
|
||||
if (!GPUScaling.Enabled)
|
||||
return "Off";
|
||||
return GPUScaling.Mode;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
82
PowerControl/Options/PerformanceOverlay.cs
Normal file
82
PowerControl/Options/PerformanceOverlay.cs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
using CommonHelpers;
|
||||
|
||||
namespace PowerControl.Options
|
||||
{
|
||||
public static class PerformanceOverlay
|
||||
{
|
||||
public static Menu.MenuItemWithOptions EnabledInstance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "OSD",
|
||||
ApplyDelay = 500,
|
||||
OptionsValues = delegate ()
|
||||
{
|
||||
return Enum.GetValues<OverlayEnabled>().Select(item => (object)item).ToArray();
|
||||
},
|
||||
CurrentValue = delegate ()
|
||||
{
|
||||
if (SharedData<OverlayModeSetting>.GetExistingValue(out var value))
|
||||
return value.CurrentEnabled;
|
||||
return null;
|
||||
},
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
if (!SharedData<OverlayModeSetting>.GetExistingValue(out var value))
|
||||
return null;
|
||||
value.DesiredEnabled = (OverlayEnabled)selected;
|
||||
if (!SharedData<OverlayModeSetting>.SetExistingValue(value))
|
||||
return null;
|
||||
return selected;
|
||||
}
|
||||
};
|
||||
|
||||
public static Menu.MenuItemWithOptions ModeInstance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "OSD Mode",
|
||||
ApplyDelay = 500,
|
||||
OptionsValues = delegate ()
|
||||
{
|
||||
return Enum.GetValues<OverlayMode>().Select(item => (object)item).ToArray();
|
||||
},
|
||||
CurrentValue = delegate ()
|
||||
{
|
||||
if (SharedData<OverlayModeSetting>.GetExistingValue(out var value))
|
||||
return value.Current;
|
||||
return null;
|
||||
},
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
if (!SharedData<OverlayModeSetting>.GetExistingValue(out var value))
|
||||
return null;
|
||||
value.Desired = (OverlayMode)selected;
|
||||
if (!SharedData<OverlayModeSetting>.SetExistingValue(value))
|
||||
return null;
|
||||
return selected;
|
||||
}
|
||||
};
|
||||
|
||||
public static Menu.MenuItemWithOptions KernelDriversInstance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "OSD Kernel Drivers",
|
||||
ApplyDelay = 500,
|
||||
OptionsValues = delegate ()
|
||||
{
|
||||
return Enum.GetValues<KernelDriversLoaded>().Select(item => (object)item).ToArray();
|
||||
},
|
||||
CurrentValue = delegate ()
|
||||
{
|
||||
if (SharedData<OverlayModeSetting>.GetExistingValue(out var value))
|
||||
return value.KernelDriversLoaded;
|
||||
return null;
|
||||
},
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
if (!SharedData<OverlayModeSetting>.GetExistingValue(out var value))
|
||||
return null;
|
||||
value.DesiredKernelDriversLoaded = (KernelDriversLoaded)selected;
|
||||
if (!SharedData<OverlayModeSetting>.SetExistingValue(value))
|
||||
return null;
|
||||
return selected;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
34
PowerControl/Options/RefreshRate.cs
Normal file
34
PowerControl/Options/RefreshRate.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
using PowerControl.Helpers;
|
||||
using PowerControl.Helpers.AMD;
|
||||
|
||||
namespace PowerControl.Options
|
||||
{
|
||||
public static class RefreshRate
|
||||
{
|
||||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Refresh Rate",
|
||||
ApplyDelay = 1000,
|
||||
ResetValue = () => { return DisplayResolutionController.GetRefreshRates().Max(); },
|
||||
OptionsValues = delegate ()
|
||||
{
|
||||
var refreshRates = DisplayResolutionController.GetRefreshRates();
|
||||
if (refreshRates.Count() > 1)
|
||||
return refreshRates.Select(item => (object)item).ToArray();
|
||||
return null;
|
||||
},
|
||||
CurrentValue = delegate ()
|
||||
{
|
||||
return DisplayResolutionController.GetRefreshRate();
|
||||
},
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
DisplayResolutionController.SetRefreshRate((int)selected);
|
||||
// force reset and refresh of FPS limit
|
||||
FPSLimit.Instance.Reset();
|
||||
FPSLimit.Instance.Update();
|
||||
return DisplayResolutionController.GetRefreshRate();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
43
PowerControl/Options/Resolution.cs
Normal file
43
PowerControl/Options/Resolution.cs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
using PowerControl.Helpers;
|
||||
using PowerControl.Helpers.AMD;
|
||||
|
||||
namespace PowerControl.Options
|
||||
{
|
||||
public static class Resolution
|
||||
{
|
||||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Resolution",
|
||||
ApplyDelay = 1000,
|
||||
ResetValue = () =>
|
||||
{
|
||||
if (!GPUScaling.SafeResolutionChange && !Settings.Default.EnableExperimentalFeatures)
|
||||
return null;
|
||||
return DisplayResolutionController.GetAllResolutions().Last();
|
||||
},
|
||||
OptionsValues = delegate ()
|
||||
{
|
||||
var resolutions = DisplayResolutionController.GetAllResolutions();
|
||||
if (resolutions.Count() > 1)
|
||||
return resolutions.Select(item => (object)item).ToArray();
|
||||
return null;
|
||||
},
|
||||
CurrentValue = delegate ()
|
||||
{
|
||||
if (!GPUScaling.SafeResolutionChange && !Settings.Default.EnableExperimentalFeatures)
|
||||
return null;
|
||||
return DisplayResolutionController.GetResolution();
|
||||
},
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
DisplayResolutionController.SetResolution((DisplayResolutionController.DisplayResolution)selected);
|
||||
// force refresh Refresh Rate
|
||||
RefreshRate.Instance.Update();
|
||||
// force reset and refresh of FPS limit
|
||||
FPSLimit.Instance.Reset();
|
||||
FPSLimit.Instance.Update();
|
||||
return DisplayResolutionController.GetResolution();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
36
PowerControl/Options/SMT.cs
Normal file
36
PowerControl/Options/SMT.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using CommonHelpers;
|
||||
using PowerControl.Helpers;
|
||||
|
||||
namespace PowerControl.Options
|
||||
{
|
||||
public static class SMT
|
||||
{
|
||||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "SMT",
|
||||
ApplyDelay = 500,
|
||||
Options = { "No", "Yes" },
|
||||
ResetValue = () => { return "Yes"; },
|
||||
CurrentValue = delegate ()
|
||||
{
|
||||
if (!RTSS.IsOSDForeground(out var processId))
|
||||
return null;
|
||||
if (!ProcessorCores.HasSMTThreads())
|
||||
return null;
|
||||
|
||||
return ProcessorCores.IsUsingSMT(processId.Value) ? "Yes" : "No";
|
||||
},
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
if (!RTSS.IsOSDForeground(out var processId))
|
||||
return null;
|
||||
if (!ProcessorCores.HasSMTThreads())
|
||||
return null;
|
||||
|
||||
ProcessorCores.SetProcessSMT(processId.Value, selected.ToString() == "Yes");
|
||||
|
||||
return ProcessorCores.IsUsingSMT(processId.Value) ? "Yes" : "No";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
31
PowerControl/Options/Sharpening.cs
Normal file
31
PowerControl/Options/Sharpening.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
using PowerControl.Helpers;
|
||||
using PowerControl.Helpers.AMD;
|
||||
|
||||
namespace PowerControl.Options
|
||||
{
|
||||
public static class Sharpening
|
||||
{
|
||||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Sharpening",
|
||||
ApplyDelay = 500,
|
||||
Options = { "Off", "On" },
|
||||
CurrentValue = delegate ()
|
||||
{
|
||||
var value = ImageSharpening.Enabled;
|
||||
if (value is null)
|
||||
return null;
|
||||
return value.Value ? "On" : "Off";
|
||||
},
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
ImageSharpening.Enabled = (string)selected == "On";
|
||||
|
||||
var value = ImageSharpening.Enabled;
|
||||
if (value is null)
|
||||
return null;
|
||||
return value.Value ? "On" : "Off";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
34
PowerControl/Options/SteamController.cs
Normal file
34
PowerControl/Options/SteamController.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
using CommonHelpers;
|
||||
|
||||
namespace PowerControl.Options
|
||||
{
|
||||
public static class SteamController
|
||||
{
|
||||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Controller",
|
||||
ApplyDelay = 500,
|
||||
OptionsValues = delegate ()
|
||||
{
|
||||
if (SharedData<SteamControllerSetting>.GetExistingValue(out var value))
|
||||
return value.SelectableProfiles.SplitWithN();
|
||||
return null;
|
||||
},
|
||||
CurrentValue = delegate ()
|
||||
{
|
||||
if (SharedData<SteamControllerSetting>.GetExistingValue(out var value))
|
||||
return value.CurrentProfile.Length > 0 ? value.CurrentProfile : null;
|
||||
return null;
|
||||
},
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
if (!SharedData<SteamControllerSetting>.GetExistingValue(out var value))
|
||||
return null;
|
||||
value.DesiredProfile = (String)selected;
|
||||
if (!SharedData<SteamControllerSetting>.SetExistingValue(value))
|
||||
return null;
|
||||
return selected;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
64
PowerControl/Options/TDP.cs
Normal file
64
PowerControl/Options/TDP.cs
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
using System.Diagnostics;
|
||||
using PowerControl.Helpers.AMD;
|
||||
|
||||
namespace PowerControl.Options
|
||||
{
|
||||
public static class TDP
|
||||
{
|
||||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "TDP",
|
||||
Options = { "3W", "4W", "5W", "6W", "7W", "8W", "10W", "12W", "15W" },
|
||||
ApplyDelay = 1000,
|
||||
ResetValue = () => { return "15W"; },
|
||||
ActiveOption = "?",
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
if (!Settings.Default.AckAntiCheat(
|
||||
Controller.TitleWithVersion,
|
||||
"TDP",
|
||||
"Changing TDP requires kernel access for a short period. Leave the game if it uses anti-cheat protection.")
|
||||
)
|
||||
return null;
|
||||
|
||||
uint mW = uint.Parse(selected.ToString().Replace("W", "")) * 1000;
|
||||
|
||||
if (VangoghGPU.IsSupported)
|
||||
{
|
||||
return CommonHelpers.Instance.WithGlobalMutex<object>(200, () =>
|
||||
{
|
||||
using (var sd = VangoghGPU.Open())
|
||||
{
|
||||
if (sd is null)
|
||||
return null;
|
||||
|
||||
sd.SlowTDP = mW;
|
||||
sd.FastTDP = mW;
|
||||
}
|
||||
|
||||
return selected;
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
uint stampLimit = mW / 10;
|
||||
|
||||
Process.Start(new ProcessStartInfo()
|
||||
{
|
||||
FileName = "Resources/RyzenAdj/ryzenadj.exe",
|
||||
ArgumentList = {
|
||||
"--stapm-limit=" + stampLimit.ToString(),
|
||||
"--slow-limit=" + mW.ToString(),
|
||||
"--fast-limit=" + mW.ToString(),
|
||||
},
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
});
|
||||
|
||||
return selected;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
32
PowerControl/Options/Volume.cs
Normal file
32
PowerControl/Options/Volume.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
namespace PowerControl.Options
|
||||
{
|
||||
public static class Volume
|
||||
{
|
||||
public static Menu.MenuItemWithOptions Instance = new Menu.MenuItemWithOptions()
|
||||
{
|
||||
Name = "Volume",
|
||||
Options = { 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100 },
|
||||
CycleOptions = false,
|
||||
CurrentValue = delegate ()
|
||||
{
|
||||
try { return Helpers.AudioManager.GetMasterVolume(5.0); }
|
||||
catch (Exception) { return null; }
|
||||
},
|
||||
ApplyValue = delegate (object selected)
|
||||
{
|
||||
try
|
||||
{
|
||||
Helpers.AudioManager.SetMasterVolumeMute(false);
|
||||
Helpers.AudioManager.SetMasterVolume((int)selected);
|
||||
|
||||
return Helpers.AudioManager.GetMasterVolume(5.0);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// In some cases MasterVolume device is missing
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue