Compare commits

..

11 Commits

Author SHA1 Message Date
Serge
27cd55bd4c Merge branch 'main' into srgb 2024-03-05 15:31:12 +01:00
Serge
aeef62afa4 sRGB and Custom gammas support 2024-03-05 15:21:26 +01:00
Serge
6dcfff704e Sleep hotkey for TUF devices 2024-03-05 14:49:27 +01:00
Serge
abc9acd3a8 UV Cleanup 2024-03-05 12:27:06 +01:00
Serge
53d7382417 Set GPU Clocks earlier 2024-03-05 01:17:40 +01:00
Serge
64f4572113 UI tweaks 2024-03-05 00:31:25 +01:00
Serge
8ab1f1fc81 Workaround for bugged BIOS on G14 2024 2024-03-05 00:08:46 +01:00
IceStormNG
251d32e115 Mouse fixes (#2159)
* Support for Strix Carry (P508)

* Fixes polling rate, angle snapping and debounce for Gladius II Origin.

* The Gen2 version of the TuF M3 uses 0-100 for brightness.

* Adds support for ROG Strix Impact III (P518)

* Import/Export feature for mice.

* Suppor for Strix Impact (P303)

* Support for Strix Impact II Electro Punk

* Strix Carry has 50 DPI minimum and increments of 50.
2024-03-03 17:15:40 +01:00
Serge
947e32b97c GPU Power slider fix 2024-03-03 10:24:33 +01:00
Serge
091303d90f Swapped fan curves workaround https://github.com/seerge/g-helper/issues/2155 2024-03-03 10:19:00 +01:00
Serge
c8b929310a Zenbook fn-lock https://github.com/seerge/g-helper/issues/2154 2024-03-03 10:17:25 +01:00
33 changed files with 1701 additions and 3482 deletions

View File

@@ -365,9 +365,9 @@ public static class AppConfig
return ContainsModel("ProArt");
}
public static bool IsVivobook()
public static bool IsVivoZenbook()
{
return ContainsModel("Vivobook");
return ContainsModel("Vivobook") || ContainsModel("Zenbook");
}
// Devices with bugged bios command to change brightness
@@ -514,7 +514,7 @@ public static class AppConfig
try
{
var (bios, model) = GetBiosAndModel();
return (Int32.Parse(bios) == 317);
return (Int32.Parse(bios) == 317 || Int32.Parse(bios) == 316);
}
catch
{
@@ -522,9 +522,19 @@ public static class AppConfig
}
}
public static bool IsResetRequired()
{
return ContainsModel("GA403");
}
public static bool IsFanRequired()
{
return ContainsModel("GA402X") || ContainsModel("G513") || ContainsModel("G713R") || ContainsModel("G713P");
return ContainsModel("GA402X") || ContainsModel("G513") || ContainsModel("G713R") || ContainsModel("G713P") || ContainsModel("GU605") || ContainsModel("GA403");
}
public static bool IsAMDLight()
{
return ContainsModel("GA402X") || ContainsModel("GU605") || ContainsModel("GA403") || ContainsModel("FA507N") || ContainsModel("FA507X") || ContainsModel("FA707N") || ContainsModel("FA707X");
}
public static bool IsPowerRequired()

View File

@@ -308,6 +308,14 @@ public class AsusACPI
{
MaxGPUBoost = 15;
}
if (AppConfig.IsAMDLight())
{
MaxTotal = 90;
}
}
public void Control(uint dwIoControlCode, byte[] lpInBuffer, byte[] lpOutBuffer)
@@ -421,9 +429,16 @@ public class AsusACPI
{
return null;
}
}
public int SetVivoMode(int mode)
{
if (mode == 1) mode = 2;
else if (mode == 2) mode = 1;
return Program.acpi.DeviceSet(VivoBookMode, mode, "VivoMode");
}
public int SetGPUEco(int eco)
{
int ecoFlag = DeviceGet(GPUEco);

View File

@@ -1,336 +0,0 @@
namespace GHelper.AutoTDP
{
partial class AutoTDPGameProfileUI
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
panelPerformanceHeader = new Panel();
pictureKeyboard = new PictureBox();
labelSettings = new Label();
checkBoxEnabled = new CheckBox();
panelGameSettings = new Panel();
labelMinTDP = new Label();
labelMaxTDP = new Label();
sliderMaxTDP = new UI.Slider();
numericUpDownFPS = new NumericUpDown();
sliderMinTDP = new UI.Slider();
labelMaxTDPText = new Label();
labeMinTDPText = new Label();
labelTargetFPS = new Label();
textBoxTitle = new TextBox();
textBoxProcessName = new TextBox();
labelFPSSource = new Label();
labelLimiter = new Label();
buttonSave = new UI.RButton();
buttonDelete = new UI.RButton();
panelPerformanceHeader.SuspendLayout();
((System.ComponentModel.ISupportInitialize)pictureKeyboard).BeginInit();
panelGameSettings.SuspendLayout();
((System.ComponentModel.ISupportInitialize)numericUpDownFPS).BeginInit();
SuspendLayout();
//
// panelPerformanceHeader
//
panelPerformanceHeader.BackColor = SystemColors.ControlLight;
panelPerformanceHeader.Controls.Add(pictureKeyboard);
panelPerformanceHeader.Controls.Add(labelSettings);
panelPerformanceHeader.Controls.Add(checkBoxEnabled);
panelPerformanceHeader.Dock = DockStyle.Top;
panelPerformanceHeader.Location = new Point(0, 0);
panelPerformanceHeader.Name = "panelPerformanceHeader";
panelPerformanceHeader.Size = new Size(551, 50);
panelPerformanceHeader.TabIndex = 53;
//
// pictureKeyboard
//
pictureKeyboard.BackgroundImage = Properties.Resources.icons8_automation_32;
pictureKeyboard.BackgroundImageLayout = ImageLayout.Zoom;
pictureKeyboard.Location = new Point(4, 13);
pictureKeyboard.Name = "pictureKeyboard";
pictureKeyboard.Size = new Size(23, 27);
pictureKeyboard.TabIndex = 35;
pictureKeyboard.TabStop = false;
//
// labelSettings
//
labelSettings.AutoSize = true;
labelSettings.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point);
labelSettings.Location = new Point(31, 13);
labelSettings.Margin = new Padding(6, 0, 6, 0);
labelSettings.Name = "labelSettings";
labelSettings.Size = new Size(135, 25);
labelSettings.TabIndex = 34;
labelSettings.Text = "Game Settings";
//
// checkBoxEnabled
//
checkBoxEnabled.Location = new Point(344, 3);
checkBoxEnabled.Margin = new Padding(6, 0, 6, 0);
checkBoxEnabled.Name = "checkBoxEnabled";
checkBoxEnabled.Size = new Size(194, 42);
checkBoxEnabled.TabIndex = 53;
checkBoxEnabled.Text = "Enabled";
checkBoxEnabled.UseVisualStyleBackColor = true;
//
// panelGameSettings
//
panelGameSettings.AutoSize = true;
panelGameSettings.Controls.Add(labelMinTDP);
panelGameSettings.Controls.Add(labelMaxTDP);
panelGameSettings.Controls.Add(sliderMaxTDP);
panelGameSettings.Controls.Add(numericUpDownFPS);
panelGameSettings.Controls.Add(sliderMinTDP);
panelGameSettings.Controls.Add(labelMaxTDPText);
panelGameSettings.Controls.Add(labeMinTDPText);
panelGameSettings.Controls.Add(labelTargetFPS);
panelGameSettings.Controls.Add(textBoxTitle);
panelGameSettings.Controls.Add(textBoxProcessName);
panelGameSettings.Controls.Add(labelFPSSource);
panelGameSettings.Controls.Add(labelLimiter);
panelGameSettings.Dock = DockStyle.Top;
panelGameSettings.Location = new Point(0, 50);
panelGameSettings.Name = "panelGameSettings";
panelGameSettings.Padding = new Padding(0, 0, 0, 12);
panelGameSettings.Size = new Size(551, 244);
panelGameSettings.TabIndex = 57;
//
// labelMinTDP
//
labelMinTDP.Location = new Point(489, 152);
labelMinTDP.Margin = new Padding(4, 0, 4, 0);
labelMinTDP.Name = "labelMinTDP";
labelMinTDP.Size = new Size(56, 37);
labelMinTDP.TabIndex = 67;
labelMinTDP.Text = "30W";
labelMinTDP.TextAlign = ContentAlignment.MiddleRight;
//
// labelMaxTDP
//
labelMaxTDP.Location = new Point(487, 195);
labelMaxTDP.Margin = new Padding(4, 0, 4, 0);
labelMaxTDP.Name = "labelMaxTDP";
labelMaxTDP.Size = new Size(57, 37);
labelMaxTDP.TabIndex = 66;
labelMaxTDP.Text = "150W";
labelMaxTDP.TextAlign = ContentAlignment.MiddleRight;
//
// sliderMaxTDP
//
sliderMaxTDP.AccessibleName = "DPI Slider";
sliderMaxTDP.Location = new Point(200, 195);
sliderMaxTDP.Max = 200;
sliderMaxTDP.Min = 5;
sliderMaxTDP.Name = "sliderMaxTDP";
sliderMaxTDP.Size = new Size(291, 33);
sliderMaxTDP.Step = 1;
sliderMaxTDP.TabIndex = 65;
sliderMaxTDP.TabStop = false;
sliderMaxTDP.Text = "sliderBattery";
sliderMaxTDP.Value = 0;
//
// numericUpDownFPS
//
numericUpDownFPS.BorderStyle = BorderStyle.None;
numericUpDownFPS.Location = new Point(416, 110);
numericUpDownFPS.Maximum = new decimal(new int[] { 1000, 0, 0, 0 });
numericUpDownFPS.Minimum = new decimal(new int[] { 20, 0, 0, 0 });
numericUpDownFPS.Name = "numericUpDownFPS";
numericUpDownFPS.Size = new Size(123, 27);
numericUpDownFPS.TabIndex = 64;
numericUpDownFPS.TextAlign = HorizontalAlignment.Center;
numericUpDownFPS.Value = new decimal(new int[] { 60, 0, 0, 0 });
//
// sliderMinTDP
//
sliderMinTDP.AccessibleName = "DPI Slider";
sliderMinTDP.Location = new Point(200, 155);
sliderMinTDP.Max = 200;
sliderMinTDP.Min = 5;
sliderMinTDP.Name = "sliderMinTDP";
sliderMinTDP.Size = new Size(291, 33);
sliderMinTDP.Step = 1;
sliderMinTDP.TabIndex = 63;
sliderMinTDP.TabStop = false;
sliderMinTDP.Text = "sliderBattery";
sliderMinTDP.Value = 0;
//
// labelMaxTDPText
//
labelMaxTDPText.Location = new Point(7, 195);
labelMaxTDPText.Margin = new Padding(6, 0, 6, 0);
labelMaxTDPText.Name = "labelMaxTDPText";
labelMaxTDPText.Size = new Size(184, 37);
labelMaxTDPText.TabIndex = 61;
labelMaxTDPText.Text = "Max TDP:";
labelMaxTDPText.TextAlign = ContentAlignment.MiddleLeft;
//
// labeMinTDPText
//
labeMinTDPText.Location = new Point(7, 152);
labeMinTDPText.Margin = new Padding(6, 0, 6, 0);
labeMinTDPText.Name = "labeMinTDPText";
labeMinTDPText.Size = new Size(184, 37);
labeMinTDPText.TabIndex = 62;
labeMinTDPText.Text = "Min TDP:";
labeMinTDPText.TextAlign = ContentAlignment.MiddleLeft;
//
// labelTargetFPS
//
labelTargetFPS.Location = new Point(7, 105);
labelTargetFPS.Margin = new Padding(6, 0, 6, 0);
labelTargetFPS.Name = "labelTargetFPS";
labelTargetFPS.Size = new Size(184, 37);
labelTargetFPS.TabIndex = 60;
labelTargetFPS.Text = "Target FPS:";
labelTargetFPS.TextAlign = ContentAlignment.MiddleLeft;
//
// textBoxTitle
//
textBoxTitle.Location = new Point(200, 60);
textBoxTitle.Margin = new Padding(4, 5, 4, 5);
textBoxTitle.Name = "textBoxTitle";
textBoxTitle.Size = new Size(337, 31);
textBoxTitle.TabIndex = 59;
//
// textBoxProcessName
//
textBoxProcessName.Location = new Point(200, 10);
textBoxProcessName.Margin = new Padding(4, 5, 4, 5);
textBoxProcessName.Name = "textBoxProcessName";
textBoxProcessName.ReadOnly = true;
textBoxProcessName.Size = new Size(337, 31);
textBoxProcessName.TabIndex = 58;
textBoxProcessName.WordWrap = false;
//
// labelFPSSource
//
labelFPSSource.Location = new Point(6, 62);
labelFPSSource.Margin = new Padding(6, 0, 6, 0);
labelFPSSource.Name = "labelFPSSource";
labelFPSSource.Size = new Size(184, 37);
labelFPSSource.TabIndex = 57;
labelFPSSource.Text = "Name:";
labelFPSSource.TextAlign = ContentAlignment.MiddleLeft;
//
// labelLimiter
//
labelLimiter.Location = new Point(6, 12);
labelLimiter.Margin = new Padding(6, 0, 6, 0);
labelLimiter.Name = "labelLimiter";
labelLimiter.Size = new Size(184, 37);
labelLimiter.TabIndex = 47;
labelLimiter.Text = "Process";
labelLimiter.TextAlign = ContentAlignment.MiddleLeft;
//
// buttonSave
//
buttonSave.AccessibleName = "Keyboard Color";
buttonSave.Activated = false;
buttonSave.Anchor = AnchorStyles.Top | AnchorStyles.Right;
buttonSave.BackColor = SystemColors.ButtonHighlight;
buttonSave.BorderColor = Color.Transparent;
buttonSave.BorderRadius = 2;
buttonSave.FlatStyle = FlatStyle.Flat;
buttonSave.ForeColor = SystemColors.ControlText;
buttonSave.Location = new Point(399, 303);
buttonSave.Margin = new Padding(3, 7, 3, 7);
buttonSave.Name = "buttonSave";
buttonSave.Secondary = false;
buttonSave.Size = new Size(147, 42);
buttonSave.TabIndex = 61;
buttonSave.Text = "Save";
buttonSave.UseVisualStyleBackColor = false;
//
// buttonDelete
//
buttonDelete.AccessibleName = "Keyboard Color";
buttonDelete.Activated = false;
buttonDelete.Anchor = AnchorStyles.Top | AnchorStyles.Right;
buttonDelete.BackColor = SystemColors.ButtonHighlight;
buttonDelete.BorderColor = Color.Transparent;
buttonDelete.BorderRadius = 2;
buttonDelete.FlatStyle = FlatStyle.Flat;
buttonDelete.ForeColor = SystemColors.ControlText;
buttonDelete.Location = new Point(6, 303);
buttonDelete.Margin = new Padding(3, 7, 3, 7);
buttonDelete.Name = "buttonDelete";
buttonDelete.Secondary = false;
buttonDelete.Size = new Size(147, 42);
buttonDelete.TabIndex = 62;
buttonDelete.Text = "Delete";
buttonDelete.UseVisualStyleBackColor = false;
//
// AutoTDPGameProfileUI
//
AutoScaleDimensions = new SizeF(10F, 25F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(551, 362);
Controls.Add(buttonDelete);
Controls.Add(buttonSave);
Controls.Add(panelGameSettings);
Controls.Add(panelPerformanceHeader);
FormBorderStyle = FormBorderStyle.FixedSingle;
Margin = new Padding(4, 5, 4, 5);
MaximizeBox = false;
MinimizeBox = false;
Name = "AutoTDPGameProfileUI";
ShowIcon = false;
ShowInTaskbar = false;
Text = "Game Profile";
panelPerformanceHeader.ResumeLayout(false);
panelPerformanceHeader.PerformLayout();
((System.ComponentModel.ISupportInitialize)pictureKeyboard).EndInit();
panelGameSettings.ResumeLayout(false);
panelGameSettings.PerformLayout();
((System.ComponentModel.ISupportInitialize)numericUpDownFPS).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Panel panelPerformanceHeader;
private PictureBox pictureKeyboard;
private Label labelSettings;
private CheckBox checkBoxEnabled;
private Panel panelGameSettings;
private Label labelFPSSource;
private Label labelLimiter;
private TextBox textBoxTitle;
private TextBox textBoxProcessName;
private UI.RButton buttonSave;
private Label labelMaxTDPText;
private Label labeMinTDPText;
private Label labelTargetFPS;
private UI.Slider sliderMinTDP;
private UI.Slider sliderMaxTDP;
private NumericUpDown numericUpDownFPS;
private Label labelMinTDP;
private Label labelMaxTDP;
private UI.RButton buttonDelete;
}
}

View File

@@ -1,90 +0,0 @@
using GHelper.UI;
namespace GHelper.AutoTDP
{
public partial class AutoTDPGameProfileUI : RForm
{
public GameProfile GameProfile;
private AutoTDPUI AutoTDPUI;
public AutoTDPGameProfileUI(GameProfile profile, AutoTDPUI parent)
{
AutoTDPUI = parent;
GameProfile = profile;
InitializeComponent();
sliderMinTDP.ValueChanged += SliderMinTDP_ValueChanged;
sliderMaxTDP.ValueChanged += SliderMaxTDP_ValueChanged;
buttonSave.Click += ButtonSave_Click;
buttonDelete.Click += ButtonDelete_Click;
InitTheme();
Shown += AutoTDPGameProfileUI_Shown;
VisualizeGameProfile();
}
private void ButtonDelete_Click(object? sender, EventArgs e)
{
AutoTDPUI.DeleteGameProfile(GameProfile);
Close();
}
private void ButtonSave_Click(object? sender, EventArgs e)
{
GameProfile.Enabled = checkBoxEnabled.Checked;
GameProfile.GameTitle = textBoxTitle.Text;
GameProfile.TargetFPS = ((int)numericUpDownFPS.Value);
GameProfile.MinTdp = sliderMinTDP.Value;
GameProfile.MaxTdp = sliderMaxTDP.Value;
AutoTDPUI.UpdateGameProfile(GameProfile);
Close();
}
private void SliderMaxTDP_ValueChanged(object? sender, EventArgs e)
{
labelMaxTDP.Text = sliderMaxTDP.Value + "W";
if (sliderMaxTDP.Value < sliderMinTDP.Value)
{
sliderMinTDP.Value = sliderMaxTDP.Value;
}
}
private void SliderMinTDP_ValueChanged(object? sender, EventArgs e)
{
labelMinTDP.Text = sliderMinTDP.Value + "W";
if (sliderMaxTDP.Value < sliderMinTDP.Value)
{
sliderMaxTDP.Value = sliderMinTDP.Value;
}
}
private void AutoTDPGameProfileUI_Shown(object? sender, EventArgs e)
{
if (Height > Program.settingsForm.Height)
{
Top = Program.settingsForm.Top + Program.settingsForm.Height - Height;
}
else
{
Top = Program.settingsForm.Top + 60;
}
Left = Program.settingsForm.Left - Width - ((AutoTDPUI.Width - Width) / 2);
}
private void VisualizeGameProfile()
{
sliderMinTDP.Value = GameProfile.MinTdp;
sliderMaxTDP.Value = GameProfile.MaxTdp;
numericUpDownFPS.Value = GameProfile.TargetFPS;
textBoxProcessName.Text = GameProfile.ProcessName;
textBoxTitle.Text = GameProfile.GameTitle;
checkBoxEnabled.Checked = GameProfile.Enabled;
}
}
}

View File

@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
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
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<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
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
mimetype set.
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
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
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
: 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
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -1,620 +0,0 @@
using System.Collections.Generic;
using System.Text.Json;
using GHelper.AutoTDP.FramerateSource;
using GHelper.AutoTDP.PowerLimiter;
using Ryzen;
namespace GHelper.AutoTDP
{
internal class AutoTDPService : IDisposable
{
private static readonly bool LOG_AUTO_TDP = false;
private static readonly int INTERVAL_MIN_CHECK = 30 * 1_000;
private static readonly int INTERVAL_APP_CHECK = 5_000;
private static readonly int INTERVAL_FPS_CHECK = 500;
string GameProfileFile = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\GHelper\\AutoTDP.json";
IFramerateSource? framerateSouce;
IPowerLimiter? powerLimiter;
public List<GameProfile> GameProfiles = new List<GameProfile>();
private bool Running = false;
private Thread? checkerThread;
private Thread? tdpThread;
private double GameFPSPrevious = double.NaN;
private double GameFPS;
private int FramerateTargetReachedCounter;
private int FramerateDipCounter;
private static readonly int FPSDipHistorySize = 6;
private List<double> FramerateLog = new List<double>();
private double LowestTDP;
private double LowestStableTDP;
private long LowestStableStability = 0;
private int LowestStableChecks = 0;
private double CurrentTDP;
private double LastAdjustment;
private double LastAdjustmentTotal = 0;
private int LastAdjustmentsWithoutImprovement = 0;
private GameInstance? currentGame;
public AutoTDPService()
{
LoadGameProfiles();
Start();
}
/// <summary>
/// Whether the system is enabled and currently running.
/// </summary>
/// <returns></returns>
public bool IsRunning()
{
return Running;
}
/// <summary>
/// Whether a supported game is actively monitored and TDP is adjusted
/// </summary>
/// <returns></returns>
public bool IsActive()
{
return currentGame is not null;
}
public static bool IsAvailable()
{
if (AppConfig.IsAlly())
{
//Not yet supported
return false;
}
return AvailablePowerLimiters().Count > 0 && AvailableFramerateSources().Count > 0;
}
public static List<string> AvailableFramerateSources()
{
List<string> l = new List<string>();
if (RTSSFramerateSource.IsAvailable()) l.Add("rtss");
Logger.WriteLine("[AutoTDPService] Available Framerate Sources: " + string.Join(", ", l.ToArray()));
return l;
}
public static List<string> AvailablePowerLimiters()
{
List<string> l = new List<string>();
if (IntelMSRPowerLimiter.IsAvailable()) l.Add("intel_msr");
if (ASUSACPIPowerLimiter.IsAvailable()) l.Add("asus_acpi");
Logger.WriteLine("[AutoTDPService] Available Power Limiters: " + string.Join(", ", l.ToArray()));
return l;
}
public void Start()
{
if (!IsEnabled() || IsRunning() || !IsAvailable())
{
Logger.WriteLine("[AutoTDPService] Refusing startup. Stats: Enabled: " + IsEnabled() + ", Running: " + IsRunning() + " ,Available: " + IsAvailable());
return;
}
Running = true;
InitFramerateSource();
InitLimiter();
checkerThread = new Thread(() =>
{
while (Running)
{
CheckForGame();
try
{
Thread.Sleep(INTERVAL_APP_CHECK);
}
catch (ThreadInterruptedException)
{
continue;
}
}
});
checkerThread.Start();
}
public bool IsEnabled()
{
return AppConfig.Get("auto_tdp_enabled", 0) == 1;
}
public void InitFramerateSource()
{
string? source = AppConfig.GetString("auto_tdp_fps_source");
if ((source is null || source.Equals("rtss")) && RTSSFramerateSource.IsAvailable())
{
Logger.WriteLine("[AutoTDPService] Initializing RTSSFramerateSource...");
RTSSFramerateSource rtss = new RTSSFramerateSource();
RTSSFramerateSource.Start();
framerateSouce = rtss;
return;
}
}
public void InitLimiter()
{
string? limiter = AppConfig.GetString("auto_tdp_limiter");
if (limiter is null || limiter.Equals("asus_acpi") && ASUSACPIPowerLimiter.IsAvailable())
{
Logger.WriteLine("[AutoTDPService] Initializing ASUSACPIPowerLimiter...");
powerLimiter = new ASUSACPIPowerLimiter();
return;
}
if (limiter is not null && limiter.Equals("intel_msr") && IntelMSRPowerLimiter.IsAvailable())
{
Logger.WriteLine("[AutoTDPService] Initializing IntelMSRPowerLimiter...");
powerLimiter = new IntelMSRPowerLimiter();
return;
}
}
public void SaveGameProfiles()
{
string json = JsonSerializer.Serialize(GameProfiles);
File.WriteAllText(GameProfileFile, json);
}
public void LoadGameProfiles()
{
if (!File.Exists(GameProfileFile))
{
if (GameProfiles is null) GameProfiles = new List<GameProfile>();
return;
}
string? json = File.ReadAllText(GameProfileFile);
if (json == null)
{
return;
}
try
{
GameProfiles = JsonSerializer.Deserialize<List<GameProfile>>(json);
}
catch (Exception e)
{
Logger.WriteLine("[AutoTDPService] Deserialization failed. Creating empty list. Message: " + e.Message);
GameProfiles = new List<GameProfile>();
}
}
public void CheckForGame()
{
if (currentGame is not null)
{
//Already handling a running game. No need to check for other games
return;
}
List<GameInstance> runningGames = framerateSouce.GetRunningGames();
if (runningGames.Count == 0)
{
if (LOG_AUTO_TDP)
Logger.WriteLine("[AutoTDPService] No games detected");
return;
}
foreach (GameInstance gi in runningGames)
{
if (LOG_AUTO_TDP)
Logger.WriteLine("[AutoTDPService] Detected App: " + gi.ProcessName + " PID: " + gi.ProcessID);
if (IsGameInList(gi.ProcessName))
{
Logger.WriteLine("[AutoTDPService] Detected Supported Game: " + gi.ProcessName + " PID: " + gi.ProcessID);
HandleGame(gi);
return;
}
}
}
public GameProfile? ProfileForGame(String? processName)
{
if (processName is null)
{
return null;
}
foreach (GameProfile gp in GameProfiles)
{
if (gp.ProcessName is not null && processName.EndsWith(gp.ProcessName, StringComparison.CurrentCultureIgnoreCase))
{
return gp;
}
}
return null;
}
public bool IsGameInList(String? processName)
{
return ProfileForGame(processName) is not null;
}
public void HandleGame(GameInstance instance)
{
if (currentGame is not null)
{
if (LOG_AUTO_TDP)
Logger.WriteLine("[AutoTDPService] Already handling a game");
return;
}
if (tdpThread is not null)
{
tdpThread.Join();
tdpThread = null;
}
currentGame = instance;
StartGameHandler(instance);
}
public void Reset()
{
currentGame = null;
GameFPSPrevious = double.NaN;
GameFPS = 0;
LastAdjustmentsWithoutImprovement = 0;
LastAdjustment = 0.0;
FramerateLog = new List<double>();
FramerateTargetReachedCounter = 0;
FramerateDipCounter = 0;
LowestStableStability = 0;
LowestStableChecks = 0;
if (powerLimiter is not null)
{
powerLimiter.ResetPowerLimits();
CurrentTDP = powerLimiter.GetCPUPowerLimit();
}
}
public void StartGameHandler(GameInstance instance)
{
GameProfile? profile = ProfileForGame(instance.ProcessName);
if (profile is null || powerLimiter is null || framerateSouce is null)
{
return;
}
Logger.WriteLine("[AutoTDPService] Start handling game: " + instance.ProcessName + " PID: " + instance.ProcessID);
tdpThread = new Thread(() =>
{
CurrentTDP = powerLimiter.GetCPUPowerLimit();
powerLimiter.SavePowerLimits(); // save current power limits to restore them afterwards
LowestStableTDP = profile.MaxTdp;
LowestTDP = profile.MaxTdp;
while (currentGame is not null && Running)
{
double fps = framerateSouce.GetFramerate(instance);
if (LOG_AUTO_TDP)
Logger.WriteLine("[AutoTDPService] (" + instance.ProcessName + ") Framerate " + GameFPS);
if (fps < 0.0d)
{
//Game is not running anymore or RTSS lost its hook
Reset();
return;
}
//prevent FPS from going to 0 which causes issues with the math
GameFPS = Math.Max(5, fps);
AdjustPowerLimit(profile);
try
{
Thread.Sleep(INTERVAL_FPS_CHECK);
}
catch (ThreadInterruptedException)
{
continue;
}
}
});
tdpThread.Start();
}
private double FPSDipCorrection(double currentFramerate, double targetFPS)
{
double correction = 0.0d;
FramerateLog.Insert(0, currentFramerate);
//Remove last entry when exceeding the desired size.
if (FramerateLog.Count > FPSDipHistorySize)
{
FramerateLog.RemoveAt(FramerateLog.Count - 1);
}
if (targetFPS - 1 <= currentFramerate && currentFramerate <= targetFPS + 1)
{
//Framerate is inside ideal range
FramerateTargetReachedCounter++;
if (FramerateTargetReachedCounter >= 3
&& FramerateTargetReachedCounter < FPSDipHistorySize
&& targetFPS - 0.5 <= FramerateLog.Take(3).Average()
&& FramerateLog.Take(3).Average() - 0.05 <= targetFPS)
{
//short dip
FramerateDipCounter++;
FramerateUnstable();
correction = targetFPS + 0.15 - currentFramerate;
}
else if (FramerateDipCounter >= 4
&& targetFPS - 0.5 <= FramerateLog.Average()
&& FramerateLog.Average() - 0.1 <= targetFPS)
{
//long dip
correction = targetFPS + 0.35 - currentFramerate;
FramerateTargetReachedCounter = FPSDipHistorySize;
FramerateVeryUnstable();
}
else
{
FramerateStable();
}
}
else
{
//Framerate not in target range
correction = 0.0;
FramerateTargetReachedCounter = 0;
FramerateDipCounter = 0;
FramerateStable();
}
ProcessStability();
return correction;
}
private void FramerateStable()
{
LowestStableStability++;
}
private void FramerateUnstable()
{
LowestStableStability -= 15;
}
private void FramerateVeryUnstable()
{
LowestStableStability -= 60;
}
private bool Stabilize()
{
return LowestStableChecks * INTERVAL_FPS_CHECK > INTERVAL_MIN_CHECK;
}
private void ProcessStability()
{
if (!Stabilize()) LowestStableChecks++;
if (LowestStableStability < 0 && Stabilize())
{
//If unstable for too often increase lowest stable TDP
LowestStableTDP += 1;
LowestTDP += 1;
LowestStableStability = 0;
return;
}
if (CurrentTDP > LowestStableTDP - 0.1 && CurrentTDP < LowestStableTDP + 0.1 && Stabilize())
{
LowestStableStability++;
if (LowestStableStability > 120)
{
//if stable for long time try to reduce it again
LowestStableTDP = ProfileForGame(currentGame.ProcessName).MaxTdp;
LowestStableStability = 0;
}
}
if (LowestTDP - 0.25 <= CurrentTDP && CurrentTDP <= LowestTDP + 0.25)
{
LowestStableStability++;
if (LowestStableStability > 10 && Stabilize())
{
LowestStableTDP = LowestTDP + (LowestTDP * 0.10); // Add 10% additional wattage to get a smoother framerate
}
}
if (CurrentTDP < LowestTDP - 0.1 && LowestStableStability > 0)
{
LowestStableStability = 0;
LowestTDP = CurrentTDP;
}
LowestStableStability = Math.Min(LowestStableStability, 150);
}
private double TDPDamper(double currentFramerate)
{
if (double.IsNaN(GameFPSPrevious)) GameFPSPrevious = currentFramerate;
double dF = -0.12d;
// PID Compute
double deltaError = currentFramerate - GameFPSPrevious;
double dT = deltaError / (1020.0 / 1000.0);
double damping = CurrentTDP / currentFramerate * dF * dT;
GameFPSPrevious = currentFramerate;
return damping;
}
public void AdjustPowerLimit(GameProfile profile)
{
if (powerLimiter is null)
{
//Should not happen... but we also don't want it to crash
return;
}
double newPL = CurrentTDP;
double fpsCorrection = FPSDipCorrection(GameFPS, profile.GetTDPFPS());
double delta = profile.GetTDPFPS() - GameFPS - fpsCorrection - 1;
delta = Math.Clamp(delta, -15, 15);
double adjustment = (delta * CurrentTDP / GameFPS) * 0.65;
//Dampen the changes to not change TDP too aggressively which would cause performance issues
adjustment += TDPDamper(GameFPS);
adjustment = Math.Min(adjustment, (CurrentTDP * 0.1));
if (GameFPSPrevious > profile.GetTDPFPS() && GameFPS < profile.GetTDPFPS())
{
if (LOG_AUTO_TDP)
Logger.WriteLine("[AutoTDPService] Single Dip, Ignore");
//single dip. Ignore
return;
}
if (LastAdjustment > 0 && GameFPS <= GameFPSPrevious && adjustment > 0)
{
LastAdjustmentsWithoutImprovement++;
LastAdjustmentTotal += adjustment;
//Wait for 3 consecutive power increases and at least 3W increased TDP before judging that increasing power does nothing.
if (LastAdjustmentsWithoutImprovement >= 3 && LastAdjustmentTotal > 3)
{
//Do not adjust if increasing power does not improve framerate.
if (LOG_AUTO_TDP)
Logger.WriteLine("[AutoTDPService] Not adjusting because no improvement from last increase");
return;
}
}
else
{
LastAdjustmentsWithoutImprovement = 0;
LastAdjustmentTotal = 0;
}
newPL += adjustment;
LastAdjustment = adjustment;
//Respect the limits that the user chose
newPL = Math.Clamp(newPL, profile.MinTdp, profile.MaxTdp);
if (newPL < LowestStableTDP && LowestStableTDP < profile.MaxTdp - 1)
{
newPL = LowestStableTDP;
}
if (LOG_AUTO_TDP)
Logger.WriteLine("[AutoTDPService] Power Limit from " + CurrentTDP + "W to " + newPL + "W, Delta:" + adjustment
+ " Lowest: " + LowestTDP + "W, Lowest Stable(" + LowestStableStability + "): " + LowestStableTDP + "W");
//Apply power limits
powerLimiter.SetCPUPowerLimit(newPL);
CurrentTDP = newPL;
}
public void StopGameHandler()
{
if (tdpThread is not null)
{
currentGame = null;
tdpThread.Join();
tdpThread = null;
}
}
public void Shutdown()
{
Running = false;
if (checkerThread is not null)
{
checkerThread.Interrupt();
checkerThread.Join();
}
if (tdpThread is not null)
{
tdpThread.Interrupt();
tdpThread.Join();
}
if (powerLimiter is not null)
{
powerLimiter.ResetPowerLimits();
powerLimiter.Dispose();
powerLimiter = null;
}
if (framerateSouce is not null)
{
framerateSouce = null;
}
currentGame = null;
Reset();
//Kill RTSS instance if we started one
RTSSFramerateSource.Stop();
}
public void Dispose()
{
Shutdown();
}
}
}

View File

@@ -1,311 +0,0 @@
using GHelper.UI;
namespace GHelper.AutoTDP
{
partial class AutoTDPUI
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
panelPerformanceHeader = new Panel();
pictureKeyboard = new PictureBox();
labelGlobalSettings = new Label();
checkBoxEnabled = new CheckBox();
panelLightingContent = new Panel();
comboBoxFPSSource = new RComboBox();
labelFPSSource = new Label();
comboBoxLimiter = new RComboBox();
labelLimiter = new Label();
buttonAddGame = new RButton();
panelGamesHeader = new Panel();
pictureBox1 = new PictureBox();
labelGames = new Label();
tableLayoutGames = new TableLayoutPanel();
buttonGameDummy = new RButton();
panelPerformanceHeader.SuspendLayout();
((System.ComponentModel.ISupportInitialize)pictureKeyboard).BeginInit();
panelLightingContent.SuspendLayout();
panelGamesHeader.SuspendLayout();
((System.ComponentModel.ISupportInitialize)pictureBox1).BeginInit();
tableLayoutGames.SuspendLayout();
SuspendLayout();
//
// panelPerformanceHeader
//
panelPerformanceHeader.BackColor = SystemColors.ControlLight;
panelPerformanceHeader.Controls.Add(pictureKeyboard);
panelPerformanceHeader.Controls.Add(labelGlobalSettings);
panelPerformanceHeader.Controls.Add(checkBoxEnabled);
panelPerformanceHeader.Dock = DockStyle.Top;
panelPerformanceHeader.Location = new Point(0, 0);
panelPerformanceHeader.Margin = new Padding(2);
panelPerformanceHeader.Name = "panelPerformanceHeader";
panelPerformanceHeader.Size = new Size(446, 30);
panelPerformanceHeader.TabIndex = 52;
//
// pictureKeyboard
//
pictureKeyboard.BackgroundImage = Properties.Resources.icons8_automation_32;
pictureKeyboard.BackgroundImageLayout = ImageLayout.Zoom;
pictureKeyboard.Location = new Point(3, 8);
pictureKeyboard.Margin = new Padding(2);
pictureKeyboard.Name = "pictureKeyboard";
pictureKeyboard.Size = new Size(16, 16);
pictureKeyboard.TabIndex = 35;
pictureKeyboard.TabStop = false;
//
// labelGlobalSettings
//
labelGlobalSettings.AutoSize = true;
labelGlobalSettings.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point);
labelGlobalSettings.Location = new Point(22, 8);
labelGlobalSettings.Margin = new Padding(4, 0, 4, 0);
labelGlobalSettings.Name = "labelGlobalSettings";
labelGlobalSettings.Size = new Size(100, 15);
labelGlobalSettings.TabIndex = 34;
labelGlobalSettings.Text = "General Settings";
//
// checkBoxEnabled
//
checkBoxEnabled.Location = new Point(244, 4);
checkBoxEnabled.Margin = new Padding(4, 0, 4, 0);
checkBoxEnabled.Name = "checkBoxEnabled";
checkBoxEnabled.Size = new Size(198, 25);
checkBoxEnabled.TabIndex = 53;
checkBoxEnabled.Text = "Enabled";
checkBoxEnabled.UseVisualStyleBackColor = true;
//
// panelLightingContent
//
panelLightingContent.AutoSize = true;
panelLightingContent.Controls.Add(comboBoxFPSSource);
panelLightingContent.Controls.Add(labelFPSSource);
panelLightingContent.Controls.Add(comboBoxLimiter);
panelLightingContent.Controls.Add(labelLimiter);
panelLightingContent.Dock = DockStyle.Top;
panelLightingContent.Location = new Point(0, 30);
panelLightingContent.Margin = new Padding(2);
panelLightingContent.Name = "panelLightingContent";
panelLightingContent.Padding = new Padding(0, 0, 0, 7);
panelLightingContent.Size = new Size(446, 67);
panelLightingContent.TabIndex = 56;
//
// comboBoxFPSSource
//
comboBoxFPSSource.BorderColor = Color.White;
comboBoxFPSSource.ButtonColor = Color.FromArgb(255, 255, 255);
comboBoxFPSSource.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxFPSSource.FlatStyle = FlatStyle.Flat;
comboBoxFPSSource.FormattingEnabled = true;
comboBoxFPSSource.Location = new Point(244, 37);
comboBoxFPSSource.Margin = new Padding(11, 0, 11, 0);
comboBoxFPSSource.Name = "comboBoxFPSSource";
comboBoxFPSSource.Size = new Size(191, 23);
comboBoxFPSSource.TabIndex = 56;
//
// labelFPSSource
//
labelFPSSource.Location = new Point(4, 37);
labelFPSSource.Margin = new Padding(4, 0, 4, 0);
labelFPSSource.Name = "labelFPSSource";
labelFPSSource.Size = new Size(211, 22);
labelFPSSource.TabIndex = 57;
labelFPSSource.Text = "FPS Source";
//
// comboBoxLimiter
//
comboBoxLimiter.BorderColor = Color.White;
comboBoxLimiter.ButtonColor = Color.FromArgb(255, 255, 255);
comboBoxLimiter.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxLimiter.FlatStyle = FlatStyle.Flat;
comboBoxLimiter.FormattingEnabled = true;
comboBoxLimiter.Location = new Point(244, 7);
comboBoxLimiter.Margin = new Padding(11, 0, 11, 0);
comboBoxLimiter.Name = "comboBoxLimiter";
comboBoxLimiter.Size = new Size(191, 23);
comboBoxLimiter.TabIndex = 46;
//
// labelLimiter
//
labelLimiter.Location = new Point(4, 7);
labelLimiter.Margin = new Padding(4, 0, 4, 0);
labelLimiter.Name = "labelLimiter";
labelLimiter.Size = new Size(211, 22);
labelLimiter.TabIndex = 47;
labelLimiter.Text = "Power Limiter";
//
// buttonAddGame
//
buttonAddGame.AccessibleName = "Keyboard Color";
buttonAddGame.Activated = false;
buttonAddGame.Anchor = AnchorStyles.Top | AnchorStyles.Right;
buttonAddGame.BackColor = SystemColors.ButtonHighlight;
buttonAddGame.BorderColor = Color.Transparent;
buttonAddGame.BorderRadius = 2;
buttonAddGame.FlatStyle = FlatStyle.Flat;
buttonAddGame.ForeColor = SystemColors.ControlText;
buttonAddGame.Location = new Point(339, 3);
buttonAddGame.Margin = new Padding(2, 4, 2, 4);
buttonAddGame.Name = "buttonAddGame";
buttonAddGame.Secondary = false;
buttonAddGame.Size = new Size(103, 25);
buttonAddGame.TabIndex = 60;
buttonAddGame.Text = "Add Game";
buttonAddGame.UseVisualStyleBackColor = false;
//
// panelGamesHeader
//
panelGamesHeader.BackColor = SystemColors.ControlLight;
panelGamesHeader.Controls.Add(pictureBox1);
panelGamesHeader.Controls.Add(buttonAddGame);
panelGamesHeader.Controls.Add(labelGames);
panelGamesHeader.Dock = DockStyle.Top;
panelGamesHeader.Location = new Point(0, 97);
panelGamesHeader.Margin = new Padding(2);
panelGamesHeader.Name = "panelGamesHeader";
panelGamesHeader.Size = new Size(446, 30);
panelGamesHeader.TabIndex = 61;
//
// pictureBox1
//
pictureBox1.BackgroundImage = Properties.Resources.icons8_software_32_white;
pictureBox1.BackgroundImageLayout = ImageLayout.Zoom;
pictureBox1.Location = new Point(3, 8);
pictureBox1.Margin = new Padding(2);
pictureBox1.Name = "pictureBox1";
pictureBox1.Size = new Size(16, 16);
pictureBox1.TabIndex = 35;
pictureBox1.TabStop = false;
//
// labelGames
//
labelGames.AutoSize = true;
labelGames.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point);
labelGames.Location = new Point(22, 8);
labelGames.Margin = new Padding(4, 0, 4, 0);
labelGames.Name = "labelGames";
labelGames.Size = new Size(45, 15);
labelGames.TabIndex = 34;
labelGames.Text = "Games";
//
// tableLayoutGames
//
tableLayoutGames.AutoSize = true;
tableLayoutGames.AutoSizeMode = AutoSizeMode.GrowAndShrink;
tableLayoutGames.ColumnCount = 4;
tableLayoutGames.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25F));
tableLayoutGames.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25F));
tableLayoutGames.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25F));
tableLayoutGames.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 25F));
tableLayoutGames.Controls.Add(buttonGameDummy, 0, 0);
tableLayoutGames.Dock = DockStyle.Top;
tableLayoutGames.Location = new Point(0, 127);
tableLayoutGames.Margin = new Padding(4, 2, 4, 2);
tableLayoutGames.Name = "tableLayoutGames";
tableLayoutGames.RowCount = 7;
tableLayoutGames.RowStyles.Add(new RowStyle(SizeType.Absolute, 60F));
tableLayoutGames.RowStyles.Add(new RowStyle(SizeType.Absolute, 60F));
tableLayoutGames.RowStyles.Add(new RowStyle(SizeType.Absolute, 60F));
tableLayoutGames.RowStyles.Add(new RowStyle(SizeType.Absolute, 60F));
tableLayoutGames.RowStyles.Add(new RowStyle(SizeType.Absolute, 60F));
tableLayoutGames.RowStyles.Add(new RowStyle(SizeType.Absolute, 60F));
tableLayoutGames.RowStyles.Add(new RowStyle(SizeType.Absolute, 60F));
tableLayoutGames.Size = new Size(446, 420);
tableLayoutGames.TabIndex = 62;
//
// buttonGameDummy
//
buttonGameDummy.AccessibleName = "DPI Setting 4";
buttonGameDummy.Activated = false;
buttonGameDummy.AutoSize = true;
buttonGameDummy.AutoSizeMode = AutoSizeMode.GrowAndShrink;
buttonGameDummy.BackColor = SystemColors.ControlLightLight;
buttonGameDummy.BorderColor = Color.LightGreen;
buttonGameDummy.BorderRadius = 5;
buttonGameDummy.Dock = DockStyle.Fill;
buttonGameDummy.FlatAppearance.BorderSize = 0;
buttonGameDummy.FlatStyle = FlatStyle.Flat;
buttonGameDummy.ForeColor = SystemColors.ControlText;
buttonGameDummy.ImageAlign = ContentAlignment.BottomCenter;
buttonGameDummy.Location = new Point(2, 2);
buttonGameDummy.Margin = new Padding(2);
buttonGameDummy.Name = "buttonGameDummy";
buttonGameDummy.Secondary = false;
buttonGameDummy.Size = new Size(107, 56);
buttonGameDummy.TabIndex = 7;
buttonGameDummy.Text = "Genshin Impact\r\n60FPS\r\n";
buttonGameDummy.TextImageRelation = TextImageRelation.ImageAboveText;
buttonGameDummy.UseVisualStyleBackColor = false;
buttonGameDummy.Visible = false;
//
// AutoTDPUI
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(446, 547);
Controls.Add(tableLayoutGames);
Controls.Add(panelGamesHeader);
Controls.Add(panelLightingContent);
Controls.Add(panelPerformanceHeader);
FormBorderStyle = FormBorderStyle.FixedSingle;
MaximizeBox = false;
MinimizeBox = false;
Name = "AutoTDPUI";
ShowIcon = false;
Text = "Auto TDP Settings";
panelPerformanceHeader.ResumeLayout(false);
panelPerformanceHeader.PerformLayout();
((System.ComponentModel.ISupportInitialize)pictureKeyboard).EndInit();
panelLightingContent.ResumeLayout(false);
panelGamesHeader.ResumeLayout(false);
panelGamesHeader.PerformLayout();
((System.ComponentModel.ISupportInitialize)pictureBox1).EndInit();
tableLayoutGames.ResumeLayout(false);
tableLayoutGames.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Panel panelPerformanceHeader;
private PictureBox pictureKeyboard;
private Label labelGlobalSettings;
private Panel panelLightingContent;
private TableLayoutPanel tableLayoutGames;
private UI.RButton rButton1;
private CheckBox checkBoxEnabled;
private UI.RComboBox comboBoxLightingMode;
private Label labelLimiter;
private UI.RComboBox comboBoxFPSSource;
private Label labelFPSSource;
private RComboBox comboBoxLimiter;
private RButton buttonAddGame;
private Panel panelGamesHeader;
private PictureBox pictureBox1;
private Label labelGames;
private RButton buttonGameDummy;
}
}

View File

@@ -1,220 +0,0 @@
using GHelper.AutoTDP.FramerateSource;
using GHelper.AutoTDP.PowerLimiter;
using GHelper.UI;
using Ryzen;
using System.Linq;
namespace GHelper.AutoTDP
{
public partial class AutoTDPUI : RForm
{
private Dictionary<string, string> ModeTexts = new Dictionary<string, string>();
private AutoTDPGameProfileUI? profileUI;
public AutoTDPUI()
{
InitializeComponent();
InitTheme();
ModeTexts.Add("intel_msr", "Intel MSR Power Limiter");
ModeTexts.Add("asus_acpi", "ASUS ACPI Power Limiter");
ModeTexts.Add("rtss", "Riva Tuner Statistics Server");
checkBoxEnabled.CheckedChanged += CheckBoxEnabled_CheckedChanged;
buttonAddGame.Click += ButtonAddGame_Click;
comboBoxLimiter.DropDownClosed += ComboBoxLimiter_DropDownClosed;
comboBoxFPSSource.DropDownClosed += ComboBoxFPSSource_DropDownClosed;
Shown += AutoTDPUI_Shown;
VisualizeGeneralSettings();
VizualizeGameList();
}
private void ComboBoxFPSSource_DropDownClosed(object? sender, EventArgs e)
{
AppConfig.Set("auto_tdp_fps_source", AutoTDPService.AvailableFramerateSources().ElementAt(comboBoxFPSSource.SelectedIndex));
}
private void ComboBoxLimiter_DropDownClosed(object? sender, EventArgs e)
{
AppConfig.Set("auto_tdp_limiter", AutoTDPService.AvailablePowerLimiters().ElementAt(comboBoxLimiter.SelectedIndex));
}
private void CheckBoxEnabled_CheckedChanged(object? sender, EventArgs e)
{
AppConfig.Set("auto_tdp_enabled", checkBoxEnabled.Checked ? 1 : 0);
if (Program.autoTDPService.IsEnabled())
{
Program.autoTDPService.Start();
}
else
{
Program.autoTDPService.Shutdown();
}
}
private void ButtonAddGame_Click(object? sender, EventArgs e)
{
string? path = null;
Thread t = new Thread(() =>
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Executables (*.exe)|*.exe";
if (ofd.ShowDialog() == DialogResult.OK)
{
path = ofd.FileName;
}
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
if (path is null)
{
//User did not select a file
return;
}
GameProfile p = new GameProfile();
p.ProcessName = Path.GetFileName(path);
p.GameTitle = Path.GetFileName(path).Replace(".exe", "");
p.Enabled = true;
p.TargetFPS = 60;
p.MaxTdp = 40;
p.MinTdp = 15;
profileUI = new AutoTDPGameProfileUI(p, this);
profileUI.FormClosed += ProfileUI_FormClosed;
profileUI.ShowDialog(this);
}
private void ProfileUI_FormClosed(object? sender, FormClosedEventArgs e)
{
profileUI = null;
}
private void AutoTDPUI_Shown(object? sender, EventArgs e)
{
if (Height > Program.settingsForm.Height)
{
Top = Program.settingsForm.Top + Program.settingsForm.Height - Height;
}
else
{
Top = Program.settingsForm.Top;
}
Left = Program.settingsForm.Left - Width - 5;
}
private void VisualizeGeneralSettings()
{
checkBoxEnabled.Checked = AppConfig.Get("auto_tdp_enabled", 0) == 1;
comboBoxLimiter.Items.Clear();
comboBoxFPSSource.Items.Clear();
foreach (string s in AutoTDPService.AvailablePowerLimiters())
{
comboBoxLimiter.Items.Add(ModeTexts[s]);
}
foreach (string s in AutoTDPService.AvailableFramerateSources())
{
comboBoxFPSSource.Items.Add(ModeTexts[s]);
}
string? limiter = AppConfig.GetString("auto_tdp_limiter", null);
string? source = AppConfig.GetString("auto_tdp_fps_source", null);
if (limiter is not null && AutoTDPService.AvailablePowerLimiters().Contains(limiter))
{
comboBoxLimiter.SelectedIndex = AutoTDPService.AvailablePowerLimiters().IndexOf(limiter);
}
else
{
comboBoxLimiter.SelectedIndex = 0;
}
if (source is not null && AutoTDPService.AvailableFramerateSources().Contains(source))
{
comboBoxFPSSource.SelectedIndex = AutoTDPService.AvailableFramerateSources().IndexOf(source);
}
else
{
comboBoxFPSSource.SelectedIndex = 0;
}
}
private void VizualizeGameList()
{
//Due to my lousy skills in UI design, the game table is limited to 7x4 games.
buttonAddGame.Enabled = Program.autoTDPService.GameProfiles.Count < 7 * 4;
tableLayoutGames.Controls.Clear();
foreach (GameProfile gp in Program.autoTDPService.GameProfiles)
{
RButton bt = new RButton();
bt.Text = gp.GameTitle + "\n" + gp.TargetFPS + " FPS";
bt.Dock = DockStyle.Fill;
bt.FlatStyle = FlatStyle.Flat;
bt.FlatAppearance.BorderColor = RForm.borderMain;
bt.UseVisualStyleBackColor = false;
bt.AutoSize = true;
bt.AutoSizeMode = AutoSizeMode.GrowAndShrink;
bt.BackColor = RForm.buttonMain;
bt.ForeColor = RForm.foreMain;
bt.Click += Bt_Click;
bt.Tag = gp;
tableLayoutGames.Controls.Add(bt);
}
}
private void Bt_Click(object? sender, EventArgs e)
{
GameProfile gp = (GameProfile)((RButton)sender).Tag;
profileUI = new AutoTDPGameProfileUI(gp, this);
profileUI.FormClosed += ProfileUI_FormClosed;
profileUI.ShowDialog(this);
}
public void DeleteGameProfile(GameProfile gp)
{
if (Program.autoTDPService.IsGameInList(gp.ProcessName))
{
Program.autoTDPService.GameProfiles.Remove(gp);
}
Program.autoTDPService.SaveGameProfiles();
VizualizeGameList();
}
public void UpdateGameProfile(GameProfile gp)
{
if (!Program.autoTDPService.IsGameInList(gp.ProcessName))
{
Program.autoTDPService.GameProfiles.Add(gp);
}
Program.autoTDPService.SaveGameProfiles();
VizualizeGameList();
}
}
}

View File

@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
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
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<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
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
mimetype set.
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
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
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
: 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
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -1,17 +0,0 @@
namespace GHelper.AutoTDP.FramerateSource
{
internal class GameInstance
{
public string? ProcessName { get; set; }
public int ProcessID { get; set; }
}
internal interface IFramerateSource
{
public double GetFramerate(GameInstance instance);
public List<GameInstance> GetRunningGames();
}
}

View File

@@ -1,130 +0,0 @@
using System.Diagnostics;
using RTSSSharedMemoryNET;
namespace GHelper.AutoTDP.FramerateSource
{
internal class RTSSFramerateSource : IFramerateSource
{
private static Process? rtssInstance;
private static OSD? osd;
public static string RTSSPath { get; set; }
public static bool IsRunning => Process.GetProcessesByName("RTSS").Length != 0;
static RTSSFramerateSource()
{
RTSSPath = @"C:\Program Files (x86)\RivaTuner Statistics Server\RTSS.exe";
}
public static bool IsAvailable()
{
return File.Exists(RTSSPath);
}
public static void Start()
{
if ((rtssInstance == null || rtssInstance.HasExited) && !IsRunning && File.Exists(RTSSPath))
{
try
{
rtssInstance = Process.Start(RTSSPath);
Thread.Sleep(2000); // If it works, don't touch it
}
catch (Exception exc)
{
Logger.WriteLine("Could not start RTSS Service" + exc.Message);
}
RunOSD();
}
else
{
RunOSD();
}
}
public List<GameInstance> GetRunningGames()
{
if (!IsRunning)
{
return new List<GameInstance>();
}
List<GameInstance> giL = new List<GameInstance>();
foreach (AppEntry appEntry in OSD.GetAppEntries())
{
GameInstance i = new GameInstance();
i.ProcessID = appEntry.ProcessId;
i.ProcessName = appEntry.Name;
giL.Add(i);
}
return giL;
}
public double GetFramerate(GameInstance instance)
{
if (!IsRunning)
{
return -1.0d;
}
try
{
var appE = OSD.GetAppEntries().FirstOrDefault(a => a.ProcessId == instance.ProcessID);
if (appE is null)
return -1.0d;
return (double)appE.StatFrameTimeBufFramerate / 10;
}
catch (InvalidDataException)
{
}
catch (FileNotFoundException)
{
}
return -1.0d;
}
public static void RunOSD()
{
if (osd == null)
{
try
{
osd = new OSD("GHELPER");
}
catch (Exception exc)
{
Logger.WriteLine("Could not start OSD" + exc.Message);
}
}
}
public static void Stop()
{
if (rtssInstance != null && !rtssInstance.HasExited)
{
try
{
rtssInstance.Kill();
rtssInstance = null;
var proc = Process.GetProcessesByName("RTSSHooksLoader64");
proc[0].Kill();
}
catch (Exception)
{
// Ignored
}
}
}
}
}

View File

@@ -1,18 +0,0 @@
namespace GHelper.AutoTDP
{
public class GameProfile
{
public string GameTitle { get; set; }
public string ProcessName { get; set; }
public int TargetFPS { get; set; }
public int MinTdp { get; set; }
public int MaxTdp { get; set; }
public bool Enabled { get; set; }
public int GetTDPFPS()
{
return TargetFPS - 1;
}
}
}

View File

@@ -1,57 +0,0 @@
using GHelper.Mode;
namespace GHelper.AutoTDP.PowerLimiter
{
internal class ASUSACPIPowerLimiter : IPowerLimiter
{
private bool allAmd;
private bool fPPT;
public ASUSACPIPowerLimiter()
{
allAmd = Program.acpi.IsAllAmdPPT();
fPPT = Program.acpi.DeviceGet(AsusACPI.PPT_APUC1) >= 0;
}
public static bool IsAvailable()
{
return AppConfig.IsASUS();
}
public void SavePowerLimits()
{
}
public void SetCPUPowerLimit(double watts)
{
if (allAmd) // CPU limit all amd models
{
Program.acpi.DeviceSet(AsusACPI.PPT_CPUB0, (int)watts, "PowerLimit B0");
} else {
Program.acpi.DeviceSet(AsusACPI.PPT_APUA3, (int)watts, "PowerLimit A3");
Program.acpi.DeviceSet(AsusACPI.PPT_APUA0, (int)watts, "PowerLimit A0");
if (fPPT) Program.acpi.DeviceSet(AsusACPI.PPT_APUC1, (int)watts, "PowerLimit C1");
}
}
// You can't read PPTs on ASUS :) endpoints just return 0 if they are available
public int GetCPUPowerLimit()
{
return Program.acpi.DeviceGet(AsusACPI.PPT_APUA0);
}
public void Dispose()
{
//Nothing to dispose here
}
// Correct Asus way to reset everything, is just to set mode again
public void ResetPowerLimits()
{
Program.modeControl.SetPerformanceMode(Modes.GetCurrent());
}
}
}

View File

@@ -1,14 +0,0 @@
namespace GHelper.AutoTDP.PowerLimiter
{
internal interface IPowerLimiter : IDisposable
{
public void SetCPUPowerLimit(double watts);
public int GetCPUPowerLimit();
public void ResetPowerLimits();
public void SavePowerLimits();
}
}

View File

@@ -1,110 +0,0 @@
using Ryzen;
namespace GHelper.AutoTDP.PowerLimiter
{
internal class IntelMSRPowerLimiter : IPowerLimiter
{
public static readonly uint MSR_PKG_POWER_LIMIT = 0x610;
public static readonly uint MSR_RAPL_POWER_UNIT = 0x606;
private Ols ols;
private uint DefaultEax = 0; // Set on first reading
private uint DefaultEdx = 0;
//Lower 14 bits are the power limits
private uint PL1_MASK = 0x3FFF;
private uint PL2_MASK = 0x3FFF;
//The power unit factor (Default is 0.125 for most Intel CPUs).
private double PowerUnit = 0x0;
public IntelMSRPowerLimiter()
{
ols = new Ols();
ols.InitializeOls();
ReadPowerUnit();
}
public static bool IsAvailable()
{
return !RyzenControl.IsAMD();
}
public void SavePowerLimits()
{
DefaultEax = 0;
DefaultEdx = 0;
ols.Rdmsr(MSR_PKG_POWER_LIMIT, ref DefaultEax, ref DefaultEdx);
}
public void ReadPowerUnit()
{
uint eax = 0;
uint edx = 0;
ols.Rdmsr(MSR_RAPL_POWER_UNIT, ref eax, ref edx);
uint pwr = eax & 0x03;
PowerUnit = 1 / Math.Pow(2, pwr);
}
public void SetCPUPowerLimit(double watts)
{
uint eax = 0;
uint edx = 0;
ols.Rdmsr(MSR_PKG_POWER_LIMIT, ref eax, ref edx);
uint watsRapl = (uint)(watts / PowerUnit);
//Set limits for both PL1 and PL2
uint eaxFilterd = eax & ~PL1_MASK;
uint edxFilterd = edx & ~PL2_MASK;
eaxFilterd |= watsRapl;
edxFilterd |= watsRapl;
//Enable clamping
eaxFilterd |= 0x8000;
edxFilterd |= 0x8000;
ols.Wrmsr(0x610, eaxFilterd, edxFilterd);
}
public int GetCPUPowerLimit()
{
uint eax = 0;
uint edx = 0;
ols.Rdmsr(MSR_PKG_POWER_LIMIT, ref eax, ref edx);
uint pl1 = eax & PL1_MASK;
uint pl2 = edx & PL2_MASK;
return (int)(pl1 * PowerUnit);
}
public void ResetPowerLimits()
{
if (DefaultEax == 0)
{
return;
}
ols.Wrmsr(MSR_PKG_POWER_LIMIT, DefaultEax, DefaultEdx);
}
public void Dispose()
{
ols.DeinitializeOls();
ols.Dispose();
}
}
}

1202
app/Display/CCD.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,56 @@
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace GHelper.Display
{
enum VisualMode
{
Default,
Racing,
Scenery,
RPG,
FPS,
Cinema,
Eyecare,
Vivid
}
public class ScreenControl
{
public const int MAX_REFRESH = 1000;
public static int activeProfile = 0;
public static DisplayGammaRamp? gammaRamp;
private GammaRamp GetGamma(VisualMode mode)
{
ushort[] GammaR, GammaG, GammaB;
switch (mode)
{
case VisualMode.Racing:
GammaR = new ushort[] { 0, 256, 512, 768, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3584, 3840, 4096, 4352, 4608, 4864, 5120, 5376, 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, 10240, 10496, 10496, 10752, 11008, 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13056, 13312, 13568, 13824, 14080, 14336, 14592, 14848, 15104, 15360, 15360, 15616, 15872, 16128, 16384, 16640, 16896, 17152, 17408, 17664, 17920, 18176, 18432, 18688, 18688, 18944, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, 21248, 21504, 21760, 22016, 22272, 22528, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24320, 24576, 24832, 25088, 25344, 25600, 25856, 26112, 26368, 26368, 26624, 26880, 27136, 27392, 27648, 27904, 28160, 28416, 28672, 28928, 29184, 29440, 29696, 29952, 30208, 30208, 30464, 30720, 30976, 31232, 31488, 31744, 32000, 32256, 32512, 32768, 33024, 33280, 33536, 33792, 34048, 34304, 34560, 34816, 35072, 35328, 35584, 35840, 36096, 36352, 36608, 36864, 37120, 37376, 37632, 37888, 38144, 38400, 38656, 38912, 39168, 39424, 39680, 39936, 40192, 40448, 40704, 40960, 41216, 41472, 41728, 41984, 42240, 42496, 42752, 43008, 43264, 43520, 43776, 44032, 44288, 44544, 44800, 45056, 45312, 45568, 45824, 46080, 46336, 46592, 46848, 47104, 47360, 47616, 47872, 48128, 48384, 48640, 48896, 49152, 49408, 49664, 49920, 50176, 50432, 50688, 50944, 51200, 51456, 51712, 51968, 52224, 52736, 52992, 53248, 53504, 53760, 54016, 54272, 54528, 54784, 55040, 55296, 55552, 55808, 56064, 56320, 56576, 56832, 57088, 57344, 57600, 57856, 58112, 58368, 58624, 59136, 59392, 59648, 59904, 60160, 60416, 60672, 60928, 61184, 61440, 61696, 61952, 62208, 62464, 62720, 62976, 63488, 63744, 64000, 64256, 64512, 64768, 65024, 65280};
GammaG = new ushort[] { 0, 256, 512, 768, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3584, 3840, 4096, 4352, 4608, 4864, 5120, 5376, 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, 10240, 10496, 10496, 10752, 11008, 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13056, 13312, 13568, 13824, 14080, 14336, 14592, 14848, 15104, 15360, 15360, 15616, 15872, 16128, 16384, 16640, 16896, 17152, 17408, 17664, 17920, 18176, 18432, 18688, 18688, 18944, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, 21248, 21504, 21760, 22016, 22272, 22528, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24320, 24576, 24832, 25088, 25344, 25600, 25600, 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27648, 27904, 28160, 28160, 28416, 28672, 28928, 29184, 29440, 29696, 29952, 30208, 30464, 30464, 30720, 30976, 31232, 31488, 31744, 32000, 32256, 32512, 32768, 33024, 33280, 33536, 33792, 34048, 34304, 34560, 34816, 35072, 35328, 35584, 35840, 36096, 36352, 36608, 36864, 37120, 37376, 37632, 37888, 38144, 38400, 38656, 38912, 39168, 39424, 39680, 39936, 40192, 40448, 40704, 40960, 41216, 41472, 41728, 41984, 41984, 42240, 42496, 42752, 43008, 43264, 43520, 43776, 44032, 44288, 44544, 44800, 45056, 45312, 45568, 45824, 45824, 46080, 46336, 46592, 46848, 47104, 47360, 47616, 47872, 48128, 48384, 48640, 48896, 49152, 49408, 49920, 50176, 50432, 50688, 50944, 51200, 51456, 51712, 51968, 52224, 52480, 52736, 52992, 53248, 53504, 53760, 54272, 54528, 54784, 55040, 55296, 55552, 55808, 56064, 56320, 56576, 56832, 57088, 57344, 57600, 57856, 58112, 58368, 58624, 58880, 59136, 59392, 59648, 59904, 60160, 60416, 60672, 60928, 61184, 61440, 61696, 61952, 62208, 62464, 62720, 62976, 63232, 63488, 63744, 64000, 64256};
GammaB = new ushort[] { 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4352, 4608, 4864, 5120, 5376, 5632, 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8448, 8704, 8960, 9216, 9216, 9472, 9728, 9984, 10240, 10496, 10496, 10752, 11008, 11264, 11520, 11776, 12032, 12032, 12288, 12544, 12800, 13056, 13312, 13312, 13568, 13824, 14080, 14336, 14592, 14592, 14848, 15104, 15360, 15616, 15872, 16128, 16384, 16640, 16640, 16896, 17152, 17408, 17664, 17920, 18176, 18432, 18688, 18944, 19200, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, 21248, 21504, 21504, 21760, 22016, 22272, 22528, 22784, 23040, 23296, 23552, 23808, 23808, 24064, 24320, 24576, 24832, 25088, 25344, 25600, 25600, 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27392, 27648, 27904, 28160, 28416, 28672, 28928, 29184, 29184, 29440, 29696, 29952, 30208, 30464, 30720, 30976, 31232, 31232, 31488, 31744, 32000, 32256, 32512, 32768, 33024, 33280, 33536, 33792, 33792, 34048, 34304, 34560, 34816, 35072, 35328, 35584, 35840, 36096, 36096, 36352, 36608, 36864, 37120, 37376, 37632, 37888, 38144, 38400, 38656, 38912, 39168, 39424, 39424, 39680, 39936, 40192, 40448, 40704, 40960, 41216, 41472, 41728, 41984, 42240, 42496, 42752, 43008, 43264, 43264, 43520, 43776, 44032, 44288, 44544, 44800, 45056, 45312, 45568, 45824, 46080, 46336, 46592, 46848, 47104, 47104, 47360, 47616, 47872, 48128, 48384, 48640, 48896, 49152, 49408, 49664, 49920, 50176, 50432, 50688, 50944, 50944, 51200, 51456, 51712, 51968, 52224, 52480, 52736, 52992, 53248, 53504, 53760, 54016, 54272, 54528, 54784, 55040, 55296, 55552, 55808, 56064, 56320, 56576, 56576, 56832, 57088, 57344, 57600, 57856, 58112, 58368, 58624, 58880, 59136, 59392, 59648, 59904, 60160, 60416};
break;
case VisualMode.Scenery:
GammaR = new ushort[] { 7424, 7680, 8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, 10240, 10496, 10496, 10752, 11008, 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13056, 13312, 13568, 13824, 14080, 14336, 14592, 14848, 15104, 15360, 15360, 15616, 15872, 16128, 16384, 16640, 16896, 17152, 17408, 17664, 17920, 18176, 18432, 18688, 18688, 18944, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, 21248, 21504, 21760, 22016, 22272, 22528, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24320, 24576, 24832, 25088, 25344, 25600, 25856, 26112, 26368, 26368, 26624, 26880, 27136, 27392, 27648, 27904, 28160, 28416, 28672, 28928, 29184, 29440, 29696, 29952, 30208, 30208, 30464, 30720, 30976, 31232, 31488, 31744, 32000, 32256, 32512, 32768, 33024, 33280, 33536, 33792, 34048, 34304, 34560, 34816, 35072, 35328, 35584, 35840, 36096, 36352, 36608, 36864, 37120, 37376, 37632, 37888, 38144, 38400, 38656, 38912, 39168, 39424, 39680, 39936, 40192, 40448, 40704, 40960, 41216, 41472, 41728, 41984, 42240, 42496, 42752, 43008, 43264, 43520, 43776, 44032, 44288, 44544, 44800, 45056, 45312, 45568, 45824, 46080, 46336, 46592, 46848, 47104, 47360, 47616, 47872, 48128, 48384, 48640, 48896, 49152, 49408, 49664, 49920, 50176, 50432, 50688, 50944, 51200, 51456, 51712, 51968, 52224, 52736, 52992, 53248, 53504, 53760, 54016, 54272, 54528, 54784, 55040, 55296, 55552, 55808, 56064, 56320, 56576, 56832, 57088, 57344, 57600, 57856, 58112, 58624, 59136, 59392, 59648, 59904, 60160, 60416, 60672, 60928, 61184, 61440, 61696, 61952, 62208, 62464, 62720, 62976, 63488, 63744, 64000, 64256, 64512, 64768, 65024, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280, 65280};
GammaG = new ushort[] { 7424, 7680, 8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, 10240, 10496, 10496, 10752, 11008, 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13056, 13312, 13568, 13824, 14080, 14336, 14592, 14848, 15104, 15360, 15360, 15616, 15872, 16128, 16384, 16640, 16896, 17152, 17408, 17664, 17920, 18176, 18432, 18688, 18688, 18944, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, 21248, 21504, 21760, 22016, 22272, 22528, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24320, 24576, 24832, 25088, 25344, 25600, 25600, 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27648, 27904, 28160, 28160, 28416, 28672, 28928, 29184, 29440, 29696, 29952, 30208, 30464, 30464, 30720, 30976, 31232, 31488, 31744, 32000, 32256, 32512, 32768, 33024, 33280, 33536, 33792, 34048, 34304, 34560, 34816, 35072, 35328, 35584, 35840, 36096, 36352, 36608, 36864, 37120, 37376, 37632, 37888, 38144, 38400, 38656, 38912, 39168, 39424, 39680, 39936, 40192, 40448, 40704, 40960, 41216, 41472, 41728, 41984, 42240, 42496, 42752, 43008, 43264, 43520, 43776, 44032, 44032, 44288, 44544, 44800, 45056, 45312, 45568, 45824, 46080, 46336, 46592, 46848, 47104, 47360, 47616, 47872, 48128, 48384, 48640, 48896, 49152, 49408, 49664, 49920, 50176, 50432, 50688, 50944, 51200, 51456, 51712, 52224, 52480, 52736, 52992, 53248, 53504, 53760, 54016, 54272, 54528, 54784, 55040, 55296, 55552, 55808, 56064, 56320, 56576, 56832, 57088, 57344, 57600, 58112, 58368, 58624, 58880, 59136, 59392, 59648, 59904, 60160, 60672, 60928, 61184, 61440, 61696, 61952, 62208, 62464, 62720, 62976, 63232, 63488, 63744, 64000, 64256, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512, 64512};
GammaB = new ushort[] { 6912, 7168, 7424, 7680, 7936, 8192, 8448, 8704, 8960, 9216, 9472, 9472, 9728, 9984, 10240, 10496, 10752, 11008, 11264, 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13056, 13312, 13568, 13824, 14080, 14336, 14592, 14848, 14848, 15104, 15360, 15616, 15872, 16128, 16384, 16640, 16896, 16896, 17152, 17408, 17664, 17920, 18176, 18432, 18688, 18944, 19200, 19456, 19456, 19712, 19968, 20224, 20480, 20736, 20992, 21248, 21504, 21760, 21760, 22016, 22272, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24064, 24320, 24576, 24832, 25088, 25344, 25600, 25856, 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27648, 27648, 27904, 28160, 28416, 28672, 28928, 29184, 29440, 29440, 29696, 29952, 30208, 30464, 30720, 30976, 31232, 31488, 31488, 31744, 32000, 32256, 32512, 32768, 33024, 33280, 33536, 33792, 34048, 34048, 34304, 34560, 34816, 35072, 35328, 35584, 35840, 36096, 36352, 36352, 36608, 36864, 37120, 37376, 37632, 37888, 38144, 38400, 38656, 38912, 39168, 39424, 39680, 39936, 40192, 40448, 40704, 40960, 41216, 41472, 41728, 41728, 41984, 42240, 42496, 42752, 43008, 43264, 43520, 43776, 44032, 44288, 44544, 44800, 45056, 45312, 45568, 45824, 46080, 46336, 46592, 46848, 47104, 47360, 47616, 47872, 48128, 48384, 48640, 48896, 49152, 49408, 49664, 49664, 49920, 50176, 50432, 50688, 50944, 51200, 51456, 51712, 51968, 52224, 52480, 52736, 52992, 53248, 53504, 53760, 54016, 54272, 54528, 54784, 55296, 55296, 55552, 55808, 56064, 56320, 56576, 56832, 57088, 57344, 57600, 57856, 58112, 58368, 58624, 58880, 59136, 59136, 59392, 59648, 59904, 60160, 60416, 60672, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928, 60928};
break;
default:
GammaR = new ushort[] { 0, 256, 512, 768, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3584, 3840, 4096, 4352, 4608, 4864, 5120, 5376, 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, 10240, 10496, 10496, 10752, 11008, 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13056, 13312, 13568, 13824, 14080, 14336, 14592, 14848, 15104, 15360, 15360, 15616, 15872, 16128, 16384, 16640, 16896, 17152, 17408, 17664, 17920, 18176, 18432, 18688, 18688, 18944, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, 21248, 21504, 21760, 22016, 22272, 22528, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24320, 24576, 24832, 25088, 25344, 25600, 25856, 26112, 26368, 26368, 26624, 26880, 27136, 27392, 27648, 27904, 28160, 28416, 28672, 28928, 29184, 29440, 29696, 29952, 30208, 30208, 30464, 30720, 30976, 31232, 31488, 31744, 32000, 32256, 32512, 32768, 33024, 33280, 33536, 33792, 34048, 34304, 34560, 34816, 35072, 35328, 35584, 35840, 36096, 36352, 36608, 36864, 37120, 37376, 37632, 37888, 38144, 38400, 38656, 38912, 39168, 39424, 39680, 39936, 40192, 40448, 40704, 40960, 41216, 41472, 41728, 41984, 42240, 42496, 42752, 43008, 43264, 43520, 43776, 44032, 44288, 44544, 44800, 45056, 45312, 45568, 45824, 46080, 46336, 46592, 46848, 47104, 47360, 47616, 47872, 48128, 48384, 48640, 48896, 49152, 49408, 49664, 49920, 50176, 50432, 50688, 50944, 51200, 51456, 51712, 51968, 52224, 52736, 52992, 53248, 53504, 53760, 54016, 54272, 54528, 54784, 55040, 55296, 55552, 55808, 56064, 56320, 56576, 56832, 57088, 57344, 57600, 57856, 58112, 58368, 58624, 59136, 59392, 59648, 59904, 60160, 60416, 60672, 60928, 61184, 61440, 61696, 61952, 62208, 62464, 62720, 62976, 63488, 63744, 64000, 64256, 64512, 64768, 65024, 65280 };
GammaG = new ushort[] { 0, 256, 512, 768, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3584, 3840, 4096, 4352, 4608, 4864, 5120, 5376, 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, 10240, 10496, 10496, 10752, 11008, 11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13056, 13312, 13568, 13824, 14080, 14336, 14592, 14848, 15104, 15360, 15360, 15616, 15872, 16128, 16384, 16640, 16896, 17152, 17408, 17664, 17920, 18176, 18432, 18688, 18688, 18944, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, 21248, 21504, 21760, 22016, 22272, 22528, 22528, 22784, 23040, 23296, 23552, 23808, 24064, 24320, 24576, 24832, 25088, 25344, 25600, 25600, 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27648, 27904, 28160, 28160, 28416, 28672, 28928, 29184, 29440, 29696, 29952, 30208, 30464, 30464, 30720, 30976, 31232, 31488, 31744, 32000, 32256, 32512, 32768, 33024, 33280, 33536, 33792, 34048, 34304, 34560, 34816, 35072, 35328, 35584, 35840, 36096, 36352, 36608, 36864, 37120, 37376, 37632, 37888, 38144, 38400, 38656, 38912, 39168, 39424, 39680, 39936, 40192, 40448, 40704, 40960, 41216, 41472, 41728, 41984, 41984, 42240, 42496, 42752, 43008, 43264, 43520, 43776, 44032, 44288, 44544, 44800, 45056, 45312, 45568, 45824, 45824, 46080, 46336, 46592, 46848, 47104, 47360, 47616, 47872, 48128, 48384, 48640, 48896, 49152, 49408, 49920, 50176, 50432, 50688, 50944, 51200, 51456, 51712, 51968, 52224, 52480, 52736, 52992, 53248, 53504, 53760, 54272, 54528, 54784, 55040, 55296, 55552, 55808, 56064, 56320, 56576, 56832, 57088, 57344, 57600, 57856, 58112, 58368, 58624, 58880, 59136, 59392, 59648, 59904, 60160, 60416, 60672, 60928, 61184, 61440, 61696, 61952, 62208, 62464, 62720, 62976, 63232, 63488, 63744, 64000, 64256 };
GammaB = new ushort[] { 0, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304, 2560, 2816, 3072, 3328, 3584, 3840, 4352, 4608, 4864, 5120, 5376, 5632, 5888, 6144, 6400, 6656, 6912, 7168, 7424, 7680, 7936, 8192, 8448, 8704, 8960, 9216, 9216, 9472, 9728, 9984, 10240, 10496, 10496, 10752, 11008, 11264, 11520, 11776, 12032, 12032, 12288, 12544, 12800, 13056, 13312, 13312, 13568, 13824, 14080, 14336, 14592, 14592, 14848, 15104, 15360, 15616, 15872, 16128, 16384, 16640, 16640, 16896, 17152, 17408, 17664, 17920, 18176, 18432, 18688, 18944, 19200, 19200, 19456, 19712, 19968, 20224, 20480, 20736, 20992, 21248, 21504, 21504, 21760, 22016, 22272, 22528, 22784, 23040, 23296, 23552, 23808, 23808, 24064, 24320, 24576, 24832, 25088, 25344, 25600, 25600, 25856, 26112, 26368, 26624, 26880, 27136, 27392, 27392, 27648, 27904, 28160, 28416, 28672, 28928, 29184, 29184, 29440, 29696, 29952, 30208, 30464, 30720, 30976, 31232, 31232, 31488, 31744, 32000, 32256, 32512, 32768, 33024, 33280, 33536, 33792, 33792, 34048, 34304, 34560, 34816, 35072, 35328, 35584, 35840, 36096, 36096, 36352, 36608, 36864, 37120, 37376, 37632, 37888, 38144, 38400, 38656, 38912, 39168, 39424, 39424, 39680, 39936, 40192, 40448, 40704, 40960, 41216, 41472, 41728, 41984, 42240, 42496, 42752, 43008, 43264, 43264, 43520, 43776, 44032, 44288, 44544, 44800, 45056, 45312, 45568, 45824, 46080, 46336, 46592, 46848, 47104, 47104, 47360, 47616, 47872, 48128, 48384, 48640, 48896, 49152, 49408, 49664, 49920, 50176, 50432, 50688, 50944, 50944, 51200, 51456, 51712, 51968, 52224, 52480, 52736, 52992, 53248, 53504, 53760, 54016, 54272, 54528, 54784, 55040, 55296, 55552, 55808, 56064, 56320, 56576, 56576, 56832, 57088, 57344, 57600, 57856, 58112, 58368, 58624, 58880, 59136, 59392, 59648, 59904, 60160, 60416 };
break;
}
return new GammaRamp(GammaR, GammaG, GammaB);
}
public void AutoScreen(bool force = false)
{
if (force || AppConfig.Is("screen_auto"))
@@ -24,6 +66,68 @@ namespace GHelper.Display
}
}
public bool GetSRGB()
{
var screenName = ScreenNative.FindLaptopScreen();
if (screenName is null) return false;
bool userProfiles = CCD.GetUsePerUserDisplayProfiles(screenName);
var defaultProfile = CCD.GetDisplayDefaultColorProfile(screenName);
return defaultProfile is not null && defaultProfile.ToLower().Contains("srgb") && userProfiles;
}
public void ToggleSRGB()
{
var screenName = ScreenNative.FindLaptopScreen();
if (screenName is null) return;
bool userProfiles = CCD.GetUsePerUserDisplayProfiles(screenName);
if (!userProfiles) CCD.SetUsePerUserDisplayProfiles(screenName, true);
var profiles = CCD.GetDisplayColorProfiles(screenName);
var defaultProfile = CCD.GetDisplayDefaultColorProfile(screenName);
Debug.WriteLine($"Default Profile {screenName}: {defaultProfile}");
bool isSRGB = defaultProfile is not null && defaultProfile.ToLower().Contains("srgb") && userProfiles;
bool changed = false;
foreach (var profile in profiles)
{
Debug.WriteLine(profile);
if (!changed && !isSRGB && profile.ToLower().Contains("srgb"))
{
CCD.SetDisplayDefaultColorProfile(screenName, profile);
changed = true;
}
if (!changed && isSRGB && !profile.ToLower().Contains("srgb"))
{
CCD.SetDisplayDefaultColorProfile(screenName, profile);
changed = true;
}
}
if (!changed)
{
if (isSRGB) CCD.SetUsePerUserDisplayProfiles(screenName, false);
else
{
var profile = Application.StartupPath + "ASUS_sRGB.icm";
CCD.AddDisplayColorProfile(screenName, profile, true, false);
}
}
//var colorparams = CCD.GetColorParams(screenName);
//Debug.WriteLine($"{colorparams.MaxLuminance} = {colorparams.RedPointX},{colorparams.RedPointY} {colorparams.GreenPointX},{colorparams.GreenPointY} {colorparams.BluePointX},{colorparams.BluePointY}");
//CCD.SetMinMaxLuminance(0, 0.6, 0.6, screenName);
}
public void SetBrightness(int brightness = -1)
{
if (!AppConfig.IsOLED()) return;
@@ -45,18 +149,20 @@ namespace GHelper.Display
try
{
var handle = ScreenNative.CreateDC(screenName, screenName, null, IntPtr.Zero);
if (gammaRamp is null)
if (true || gammaRamp is null)
{
var gammaDump = new GammaRamp();
if (ScreenNative.GetDeviceGammaRamp(handle, ref gammaDump))
{
gammaRamp = new DisplayGammaRamp(gammaDump);
//Logger.WriteLine("Gamma R: " + string.Join("-", gammaRamp.Red));
//Logger.WriteLine("Gamma G: " + string.Join("-", gammaRamp.Green));
//Logger.WriteLine("Gamma B: " + string.Join("-", gammaRamp.Blue));
Logger.WriteLine("GammaR = {" + string.Join(", ", gammaRamp.Red) + "};");
Logger.WriteLine("GammaG = {" + string.Join(", ", gammaRamp.Green) + "};");
Logger.WriteLine("GammaB = {" + string.Join(", ", gammaRamp.Blue) + "};");
}
}
return;
if (gammaRamp is null || !gammaRamp.IsOriginal())
{
Logger.WriteLine("Not default Gamma");
@@ -68,7 +174,8 @@ namespace GHelper.Display
Logger.WriteLine("Brightness " + bright.ToString() + ": " + result);
} catch (Exception ex)
}
catch (Exception ex)
{
Logger.WriteLine(ex.ToString());
}

View File

@@ -1008,7 +1008,7 @@ namespace GHelper
try
{
if (chartCount > 2)
Size = MinimumSize = new Size(Size.Width, (int)(ControlHelper.GetDpiScale(this).Value * (chartCount * 200 + 100)));
Size = MinimumSize = new Size(Size.Width, Math.Max(MinimumSize.Height, (int)(ControlHelper.GetDpiScale(this).Value * (chartCount * 200 + 100))));
}
catch (Exception ex)
{
@@ -1115,6 +1115,7 @@ namespace GHelper
if (gpuVisible)
{
int gpuPowerVar = Program.acpi.DeviceGet(AsusACPI.GPU_POWER);
Logger.WriteLine("Default GPU Power: " + gpuPowerVar);
trackGPUClockLimit.Value = NvidiaGpuControl.MaxClockLimit;
trackGPUCore.Value = 0;
@@ -1122,7 +1123,7 @@ namespace GHelper
trackGPUBoost.Value = AsusACPI.MaxGPUBoost;
trackGPUTemp.Value = AsusACPI.MaxGPUTemp;
trackGPUPower.Value = (gpuPowerVar >= 0) ? gpuPowerVar : AsusACPI.MaxGPUPower;
trackGPUPower.Value = Math.Max(Math.Min((gpuPowerVar >= 0) ? gpuPowerVar : AsusACPI.MaxGPUPower, AsusACPI.MaxGPUPower), AsusACPI.MinGPUPower);
AppConfig.SetMode("gpu_boost", trackGPUBoost.Value);
AppConfig.SetMode("gpu_temp", trackGPUTemp.Value);

View File

@@ -88,14 +88,6 @@
</Content>
</ItemGroup>
<ItemGroup>
<Reference Include="RTSSSharedMemoryNET">
<HintPath>RTSSSharedMemoryNET.dll</HintPath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>

View File

@@ -14,24 +14,18 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Debug|Any CPU.ActiveCfg = Debug|x64
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Debug|Any CPU.Build.0 = Debug|x64
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Debug|x64.ActiveCfg = Debug|Any CPU
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Debug|x64.Build.0 = Debug|Any CPU
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Debug|x86.ActiveCfg = Debug|Any CPU
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Debug|x86.Build.0 = Debug|Any CPU
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Release|Any CPU.ActiveCfg = Release|x64
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Release|Any CPU.Build.0 = Release|x64
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Release|x64.ActiveCfg = Release|x64
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Release|x64.Build.0 = Release|x64
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Release|x86.ActiveCfg = Release|Any CPU
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -85,7 +85,7 @@ namespace GHelper.Input
InitBacklightTimer();
if (AppConfig.ContainsModel("VivoBook")) Program.acpi.DeviceSet(AsusACPI.FnLock, AppConfig.Is("fn_lock") ? 1 : 0, "FnLock");
if (AppConfig.IsVivoZenbook()) Program.acpi.DeviceSet(AsusACPI.FnLock, AppConfig.Is("fn_lock") ? 1 : 0, "FnLock");
}
@@ -151,7 +151,7 @@ namespace GHelper.Input
// FN-Lock group
if (AppConfig.Is("fn_lock") && !AppConfig.ContainsModel("VivoBook"))
if (AppConfig.Is("fn_lock") && !AppConfig.IsVivoZenbook())
for (Keys i = Keys.F1; i <= Keys.F11; i++) hook.RegisterHotKey(ModifierKeys.None, i);
// Arrow-lock group
@@ -500,7 +500,7 @@ namespace GHelper.Input
case "micmute":
bool muteStatus = Audio.ToggleMute();
Program.toast.RunToast(muteStatus ? "Muted" : "Unmuted", muteStatus ? ToastIcon.MicrophoneMute : ToastIcon.Microphone);
if (AppConfig.IsVivobook()) Program.acpi.DeviceSet(AsusACPI.MicMuteLed, muteStatus ? 1 : 0, "MicmuteLed");
if (AppConfig.IsVivoZenbook()) Program.acpi.DeviceSet(AsusACPI.MicMuteLed, muteStatus ? 1 : 0, "MicmuteLed");
break;
case "brightness_up":
SetBrightness(+10);
@@ -568,7 +568,7 @@ namespace GHelper.Input
int fnLock = AppConfig.Is("fn_lock") ? 0 : 1;
AppConfig.Set("fn_lock", fnLock);
if (AppConfig.ContainsModel("VivoBook"))
if (AppConfig.IsVivoZenbook())
Program.acpi.DeviceSet(AsusACPI.FnLock, fnLock == 1 ? 1 : 0, "FnLock");
else
Program.settingsForm.BeginInvoke(Program.inputDispatcher.RegisterKeys);
@@ -676,7 +676,8 @@ namespace GHelper.Input
return;
case 51: // Fn+F6 on old TUFs
case 53: // Fn+F6 on GA-502DU model
NativeMethods.TurnOffScreen();
SleepEvent();
//NativeMethods.TurnOffScreen();
return;
}
}

View File

@@ -62,39 +62,45 @@ namespace GHelper.Mode
if (!Modes.Exists(mode)) mode = 0;
customFans = false;
customPower = 0;
settings.ShowMode(mode);
SetModeLabel();
Modes.SetCurrent(mode);
int status = Program.acpi.DeviceSet(AsusACPI.PerformanceMode, AppConfig.IsManualModeRequired() ? AsusACPI.PerformanceManual : Modes.GetBase(mode), "Mode");
// Vivobook fallback
if (status != 1)
Task.Run(async () =>
{
int vivoMode = Modes.GetBase(mode);
if (vivoMode == 1) vivoMode = 2;
else if (vivoMode == 2) vivoMode = 1;
Program.acpi.DeviceSet(AsusACPI.VivoBookMode, vivoMode, "VivoMode");
}
bool reset = AppConfig.IsResetRequired() && (Modes.GetBase(oldMode) == Modes.GetBase(mode)) && customPower > 0;
customFans = false;
customPower = 0;
SetModeLabel();
// Workaround for not properly resetting limits on G14 2024
if (reset)
{
Program.acpi.DeviceSet(AsusACPI.PerformanceMode, (Modes.GetBase(oldMode) != 1) ? AsusACPI.PerformanceTurbo : AsusACPI.PerformanceBalanced, "Reset");
await Task.Delay(TimeSpan.FromMilliseconds(1500));
}
int status = Program.acpi.DeviceSet(AsusACPI.PerformanceMode, AppConfig.IsManualModeRequired() ? AsusACPI.PerformanceManual : Modes.GetBase(mode), "Mode");
// Vivobook fallback
if (status != 1) Program.acpi.SetVivoMode(Modes.GetBase(mode));
SetGPUClocks();
AutoFans();
await Task.Delay(TimeSpan.FromMilliseconds(1000));
AutoPower();
});
if (AppConfig.Is("xgm_fan") && Program.acpi.IsXGConnected()) XGM.Reset();
if (notify)
Program.toast.RunToast(Modes.GetCurrentName(), SystemInformation.PowerStatus.PowerLineStatus == PowerLineStatus.Online ? ToastIcon.Charger : ToastIcon.Battery);
SetGPUClocks();
Task.Run(async () =>
{
await Task.Delay(TimeSpan.FromMilliseconds(100));
AutoFans();
await Task.Delay(TimeSpan.FromMilliseconds(1000));
AutoPower();
});
// Power plan from config or defaulting to balanced

View File

@@ -37,7 +37,12 @@
}
public override int DPIIncrements()
{
return 100;
return 50;
}
public override int MinDPI()
{
return 50;
}
public override bool HasDebounceSetting()

View File

@@ -7,6 +7,10 @@
{
}
public StrixImpactII(ushort pid) : base(0x0B05, pid, "mi_00", false)
{
}
public override int DPIProfileCount()
{
return 4;
@@ -174,4 +178,19 @@
}
}
}
public class StrixImpactIIElectroPunk : StrixImpactII
{
public StrixImpactIIElectroPunk() : base(0x1956)
{
}
public override string GetDisplayName()
{
return "ROG Strix Impact II Electro Punk";
}
}
}

View File

@@ -209,6 +209,7 @@ namespace GHelper.Peripherals
DetectMouse(new PugioII());
DetectMouse(new PugioIIWired());
DetectMouse(new StrixImpactII());
DetectMouse(new StrixImpactIIElectroPunk());
DetectMouse(new Chakram());
DetectMouse(new ChakramWired());
DetectMouse(new ChakramCore());

View File

@@ -1,5 +1,4 @@
using GHelper.Ally;
using GHelper.AutoTDP;
using GHelper.Battery;
using GHelper.Display;
using GHelper.Gpu;
@@ -47,8 +46,6 @@ namespace GHelper
private static PowerLineStatus isPlugged = SystemInformation.PowerStatus.PowerLineStatus;
public static AutoTDPService autoTDPService = new AutoTDPService();
// The main entry point for the application
public static void Main(string[] args)
{
@@ -309,7 +306,6 @@ namespace GHelper
static void OnExit(object sender, EventArgs e)
{
autoTDPService.Shutdown();
trayIcon.Visible = false;
PeripheralsProvider.UnregisterForDeviceEvents();
clamshellControl.UnregisterDisplayEvents();

Binary file not shown.

View File

@@ -13,7 +13,7 @@ namespace Ryzen
internal class RyzenControl
{
public static int MinCPUUV => AppConfig.Get("min_uv", -30);
public static int MinCPUUV => AppConfig.Get("min_uv", -40);
public const int MaxCPUUV = 0;
public const int MinIGPUUV = -20;

File diff suppressed because it is too large Load Diff

572
app/Settings.Designer.cs generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,5 @@
using GHelper.Ally;
using GHelper.AnimeMatrix;
using GHelper.AutoTDP;
using GHelper.AutoUpdate;
using GHelper.Battery;
using GHelper.Display;
@@ -29,7 +28,6 @@ namespace GHelper
AutoUpdateControl updateControl;
AsusMouseSettings? mouseSettings;
AutoTDPUI? autoTdpUi;
public AniMatrixControl matrixControl;
@@ -246,8 +244,6 @@ namespace GHelper
buttonFPS.Click += ButtonFPS_Click;
buttonOverlay.Click += ButtonOverlay_Click;
buttonAutoTDP.Click += ButtonAutoTDP_Click;
Text = "G-Helper " + (ProcessHelper.IsUserAdministrator() ? "—" : "-") + " " + AppConfig.GetModelShort();
TopMost = AppConfig.Is("topmost");
@@ -261,6 +257,15 @@ namespace GHelper
panelPerformance.Focus();
InitBrightness();
checkSRGB.Checked = screenControl.GetSRGB();
checkSRGB.CheckedChanged += CheckSRGB_CheckedChanged;
}
private void CheckSRGB_CheckedChanged(object? sender, EventArgs e)
{
screenControl.ToggleSRGB();
}
public void InitBrightness()
@@ -277,36 +282,6 @@ namespace GHelper
}
private void ButtonAutoTDP_Click(object? sender, EventArgs e)
{
if (autoTdpUi is not null)
{
return;
}
autoTdpUi = new AutoTDPUI();
autoTdpUi.FormClosed += AutoTdpUi_FormClosed;
autoTdpUi.Disposed += AutoTdpUi_Disposed;
if (!autoTdpUi.IsDisposed)
{
autoTdpUi.Show();
}
else
{
autoTdpUi = null;
}
}
private void AutoTdpUi_Disposed(object? sender, EventArgs e)
{
autoTdpUi = null;
}
private void AutoTdpUi_FormClosed(object? sender, FormClosedEventArgs e)
{
autoTdpUi = null;
}
private void SliderGamma_ValueChanged(object? sender, EventArgs e)
{
screenControl.SetBrightness(sliderGamma.Value);
@@ -457,8 +432,6 @@ namespace GHelper
Task.Run((Action)RefreshPeripheralsBattery);
updateControl.CheckForUpdates();
tableAdditionalGPUFeature.Visible = AutoTDPService.IsAvailable();
}
}
@@ -1129,7 +1102,6 @@ namespace GHelper
private void ButtonQuit_Click(object? sender, EventArgs e)
{
Program.autoTDPService.Shutdown();
matrixControl.Dispose();
Close();
Program.trayIcon.Visible = false;

View File

@@ -79,7 +79,7 @@ namespace GHelper.USB
public static Color Color1 = Color.White;
public static Color Color2 = Color.Black;
static bool isACPI = AppConfig.IsTUF() || AppConfig.IsVivobook() || AppConfig.IsProArt();
static bool isACPI = AppConfig.IsTUF() || AppConfig.IsVivoZenbook() || AppConfig.IsProArt();
static bool isStrix = AppConfig.IsStrix() && !AppConfig.IsNoDirectRGB();
static bool isStrix4Zone = AppConfig.IsStrixLimitedRGB();

View File

@@ -1,5 +1,5 @@
{
"sdk": {
"version": "7.0.400"
"version": "7.0.406"
}
}