mirror of
https://github.com/jkocon/g-helper.git
synced 2026-02-23 13:00:52 +01:00
Added AutoTDP feature with RTSS source and Intel + ASUS power limiters
This commit is contained in:
337
app/AutoTDP/AutoTDPGameProfileUI.Designer.cs
generated
Normal file
337
app/AutoTDP/AutoTDPGameProfileUI.Designer.cs
generated
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
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();
|
||||||
|
panelLightingContent = new Panel();
|
||||||
|
labelMinTDP = new Label();
|
||||||
|
labelMaxTDP = new Label();
|
||||||
|
sliderMaxTDP = new UI.Slider();
|
||||||
|
numericUpDownFPS = new NumericUpDown();
|
||||||
|
sliderMinTDP = new UI.Slider();
|
||||||
|
label2 = new Label();
|
||||||
|
label3 = new Label();
|
||||||
|
label1 = 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();
|
||||||
|
panelLightingContent.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.Margin = new Padding(2);
|
||||||
|
panelPerformanceHeader.Name = "panelPerformanceHeader";
|
||||||
|
panelPerformanceHeader.Size = new Size(386, 30);
|
||||||
|
panelPerformanceHeader.TabIndex = 53;
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
//
|
||||||
|
// labelSettings
|
||||||
|
//
|
||||||
|
labelSettings.AutoSize = true;
|
||||||
|
labelSettings.Font = new Font("Segoe UI", 9F, FontStyle.Bold, GraphicsUnit.Point);
|
||||||
|
labelSettings.Location = new Point(22, 8);
|
||||||
|
labelSettings.Margin = new Padding(4, 0, 4, 0);
|
||||||
|
labelSettings.Name = "labelSettings";
|
||||||
|
labelSettings.Size = new Size(89, 15);
|
||||||
|
labelSettings.TabIndex = 34;
|
||||||
|
labelSettings.Text = "Game Settings";
|
||||||
|
//
|
||||||
|
// checkBoxEnabled
|
||||||
|
//
|
||||||
|
checkBoxEnabled.Location = new Point(241, 2);
|
||||||
|
checkBoxEnabled.Margin = new Padding(4, 0, 4, 0);
|
||||||
|
checkBoxEnabled.Name = "checkBoxEnabled";
|
||||||
|
checkBoxEnabled.Size = new Size(136, 25);
|
||||||
|
checkBoxEnabled.TabIndex = 53;
|
||||||
|
checkBoxEnabled.Text = "Enabled";
|
||||||
|
checkBoxEnabled.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// panelLightingContent
|
||||||
|
//
|
||||||
|
panelLightingContent.AutoSize = true;
|
||||||
|
panelLightingContent.Controls.Add(labelMinTDP);
|
||||||
|
panelLightingContent.Controls.Add(labelMaxTDP);
|
||||||
|
panelLightingContent.Controls.Add(sliderMaxTDP);
|
||||||
|
panelLightingContent.Controls.Add(numericUpDownFPS);
|
||||||
|
panelLightingContent.Controls.Add(sliderMinTDP);
|
||||||
|
panelLightingContent.Controls.Add(label2);
|
||||||
|
panelLightingContent.Controls.Add(label3);
|
||||||
|
panelLightingContent.Controls.Add(label1);
|
||||||
|
panelLightingContent.Controls.Add(textBoxTitle);
|
||||||
|
panelLightingContent.Controls.Add(textBoxProcessName);
|
||||||
|
panelLightingContent.Controls.Add(labelFPSSource);
|
||||||
|
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(386, 146);
|
||||||
|
panelLightingContent.TabIndex = 57;
|
||||||
|
//
|
||||||
|
// labelMinTDP
|
||||||
|
//
|
||||||
|
labelMinTDP.Location = new Point(342, 91);
|
||||||
|
labelMinTDP.Name = "labelMinTDP";
|
||||||
|
labelMinTDP.Size = new Size(39, 22);
|
||||||
|
labelMinTDP.TabIndex = 67;
|
||||||
|
labelMinTDP.Text = "30W";
|
||||||
|
labelMinTDP.TextAlign = ContentAlignment.MiddleRight;
|
||||||
|
//
|
||||||
|
// labelMaxTDP
|
||||||
|
//
|
||||||
|
labelMaxTDP.Location = new Point(341, 117);
|
||||||
|
labelMaxTDP.Name = "labelMaxTDP";
|
||||||
|
labelMaxTDP.Size = new Size(40, 22);
|
||||||
|
labelMaxTDP.TabIndex = 66;
|
||||||
|
labelMaxTDP.Text = "150W";
|
||||||
|
labelMaxTDP.TextAlign = ContentAlignment.MiddleRight;
|
||||||
|
//
|
||||||
|
// sliderMaxTDP
|
||||||
|
//
|
||||||
|
sliderMaxTDP.AccessibleName = "DPI Slider";
|
||||||
|
sliderMaxTDP.Location = new Point(140, 117);
|
||||||
|
sliderMaxTDP.Margin = new Padding(2);
|
||||||
|
sliderMaxTDP.Max = 200;
|
||||||
|
sliderMaxTDP.Min = 5;
|
||||||
|
sliderMaxTDP.Name = "sliderMaxTDP";
|
||||||
|
sliderMaxTDP.Size = new Size(204, 20);
|
||||||
|
sliderMaxTDP.Step = 1;
|
||||||
|
sliderMaxTDP.TabIndex = 65;
|
||||||
|
sliderMaxTDP.TabStop = false;
|
||||||
|
sliderMaxTDP.Text = "sliderBattery";
|
||||||
|
sliderMaxTDP.Value = 0;
|
||||||
|
//
|
||||||
|
// numericUpDownFPS
|
||||||
|
//
|
||||||
|
numericUpDownFPS.BorderStyle = BorderStyle.None;
|
||||||
|
numericUpDownFPS.Location = new Point(291, 66);
|
||||||
|
numericUpDownFPS.Margin = new Padding(2);
|
||||||
|
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(86, 19);
|
||||||
|
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(140, 93);
|
||||||
|
sliderMinTDP.Margin = new Padding(2);
|
||||||
|
sliderMinTDP.Max = 200;
|
||||||
|
sliderMinTDP.Min = 5;
|
||||||
|
sliderMinTDP.Name = "sliderMinTDP";
|
||||||
|
sliderMinTDP.Size = new Size(204, 20);
|
||||||
|
sliderMinTDP.Step = 1;
|
||||||
|
sliderMinTDP.TabIndex = 63;
|
||||||
|
sliderMinTDP.TabStop = false;
|
||||||
|
sliderMinTDP.Text = "sliderBattery";
|
||||||
|
sliderMinTDP.Value = 0;
|
||||||
|
//
|
||||||
|
// label2
|
||||||
|
//
|
||||||
|
label2.Location = new Point(5, 117);
|
||||||
|
label2.Margin = new Padding(4, 0, 4, 0);
|
||||||
|
label2.Name = "label2";
|
||||||
|
label2.Size = new Size(129, 22);
|
||||||
|
label2.TabIndex = 61;
|
||||||
|
label2.Text = "Max TDP:";
|
||||||
|
label2.TextAlign = ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
|
// label3
|
||||||
|
//
|
||||||
|
label3.Location = new Point(5, 91);
|
||||||
|
label3.Margin = new Padding(4, 0, 4, 0);
|
||||||
|
label3.Name = "label3";
|
||||||
|
label3.Size = new Size(129, 22);
|
||||||
|
label3.TabIndex = 62;
|
||||||
|
label3.Text = "Min TDP:";
|
||||||
|
label3.TextAlign = ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
|
// label1
|
||||||
|
//
|
||||||
|
label1.Location = new Point(5, 63);
|
||||||
|
label1.Margin = new Padding(4, 0, 4, 0);
|
||||||
|
label1.Name = "label1";
|
||||||
|
label1.Size = new Size(129, 22);
|
||||||
|
label1.TabIndex = 60;
|
||||||
|
label1.Text = "Target FPS:";
|
||||||
|
label1.TextAlign = ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
|
// textBoxTitle
|
||||||
|
//
|
||||||
|
textBoxTitle.Location = new Point(140, 36);
|
||||||
|
textBoxTitle.Name = "textBoxTitle";
|
||||||
|
textBoxTitle.Size = new Size(237, 23);
|
||||||
|
textBoxTitle.TabIndex = 59;
|
||||||
|
//
|
||||||
|
// textBoxProcessName
|
||||||
|
//
|
||||||
|
textBoxProcessName.Location = new Point(140, 6);
|
||||||
|
textBoxProcessName.Name = "textBoxProcessName";
|
||||||
|
textBoxProcessName.ReadOnly = true;
|
||||||
|
textBoxProcessName.Size = new Size(237, 23);
|
||||||
|
textBoxProcessName.TabIndex = 58;
|
||||||
|
textBoxProcessName.WordWrap = false;
|
||||||
|
//
|
||||||
|
// labelFPSSource
|
||||||
|
//
|
||||||
|
labelFPSSource.Location = new Point(4, 37);
|
||||||
|
labelFPSSource.Margin = new Padding(4, 0, 4, 0);
|
||||||
|
labelFPSSource.Name = "labelFPSSource";
|
||||||
|
labelFPSSource.Size = new Size(129, 22);
|
||||||
|
labelFPSSource.TabIndex = 57;
|
||||||
|
labelFPSSource.Text = "Name:";
|
||||||
|
labelFPSSource.TextAlign = ContentAlignment.MiddleLeft;
|
||||||
|
//
|
||||||
|
// labelLimiter
|
||||||
|
//
|
||||||
|
labelLimiter.Location = new Point(4, 7);
|
||||||
|
labelLimiter.Margin = new Padding(4, 0, 4, 0);
|
||||||
|
labelLimiter.Name = "labelLimiter";
|
||||||
|
labelLimiter.Size = new Size(129, 22);
|
||||||
|
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(279, 182);
|
||||||
|
buttonSave.Margin = new Padding(2, 4, 2, 4);
|
||||||
|
buttonSave.Name = "buttonSave";
|
||||||
|
buttonSave.Secondary = false;
|
||||||
|
buttonSave.Size = new Size(103, 25);
|
||||||
|
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(4, 182);
|
||||||
|
buttonDelete.Margin = new Padding(2, 4, 2, 4);
|
||||||
|
buttonDelete.Name = "buttonDelete";
|
||||||
|
buttonDelete.Secondary = false;
|
||||||
|
buttonDelete.Size = new Size(103, 25);
|
||||||
|
buttonDelete.TabIndex = 62;
|
||||||
|
buttonDelete.Text = "Delete";
|
||||||
|
buttonDelete.UseVisualStyleBackColor = false;
|
||||||
|
//
|
||||||
|
// AutoTDPGameProfileUI
|
||||||
|
//
|
||||||
|
AutoScaleDimensions = new SizeF(7F, 15F);
|
||||||
|
AutoScaleMode = AutoScaleMode.Font;
|
||||||
|
ClientSize = new Size(386, 217);
|
||||||
|
Controls.Add(buttonDelete);
|
||||||
|
Controls.Add(buttonSave);
|
||||||
|
Controls.Add(panelLightingContent);
|
||||||
|
Controls.Add(panelPerformanceHeader);
|
||||||
|
FormBorderStyle = FormBorderStyle.FixedSingle;
|
||||||
|
MaximizeBox = false;
|
||||||
|
MinimizeBox = false;
|
||||||
|
Name = "AutoTDPGameProfileUI";
|
||||||
|
ShowIcon = false;
|
||||||
|
ShowInTaskbar = false;
|
||||||
|
Text = "Game Profile";
|
||||||
|
panelPerformanceHeader.ResumeLayout(false);
|
||||||
|
panelPerformanceHeader.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)pictureKeyboard).EndInit();
|
||||||
|
panelLightingContent.ResumeLayout(false);
|
||||||
|
panelLightingContent.PerformLayout();
|
||||||
|
((System.ComponentModel.ISupportInitialize)numericUpDownFPS).EndInit();
|
||||||
|
ResumeLayout(false);
|
||||||
|
PerformLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private Panel panelPerformanceHeader;
|
||||||
|
private PictureBox pictureKeyboard;
|
||||||
|
private Label labelSettings;
|
||||||
|
private CheckBox checkBoxEnabled;
|
||||||
|
private Panel panelLightingContent;
|
||||||
|
private Label labelFPSSource;
|
||||||
|
private Label labelLimiter;
|
||||||
|
private TextBox textBoxTitle;
|
||||||
|
private TextBox textBoxProcessName;
|
||||||
|
private UI.RButton buttonSave;
|
||||||
|
private Label label2;
|
||||||
|
private Label label3;
|
||||||
|
private Label label1;
|
||||||
|
private UI.Slider sliderMinTDP;
|
||||||
|
private UI.Slider sliderMaxTDP;
|
||||||
|
private NumericUpDown numericUpDownFPS;
|
||||||
|
private Label labelMinTDP;
|
||||||
|
private Label labelMaxTDP;
|
||||||
|
private UI.RButton buttonDelete;
|
||||||
|
}
|
||||||
|
}
|
||||||
90
app/AutoTDP/AutoTDPGameProfileUI.cs
Normal file
90
app/AutoTDP/AutoTDPGameProfileUI.cs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
120
app/AutoTDP/AutoTDPGameProfileUI.resx
Normal file
120
app/AutoTDP/AutoTDPGameProfileUI.resx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?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>
|
||||||
435
app/AutoTDP/AutoTDPService.cs
Normal file
435
app/AutoTDP/AutoTDPService.cs
Normal file
@@ -0,0 +1,435 @@
|
|||||||
|
using System.Text.Json;
|
||||||
|
using GHelper.AutoTDP.FramerateSource;
|
||||||
|
using GHelper.AutoTDP.PowerLimiter;
|
||||||
|
|
||||||
|
namespace GHelper.AutoTDP
|
||||||
|
{
|
||||||
|
internal class AutoTDPService : IDisposable
|
||||||
|
{
|
||||||
|
|
||||||
|
private static readonly int INTERVAL_APP_CHECK = 5_000;
|
||||||
|
private static readonly int INTERVAL_FPS_CHECK = 2_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 = 8;
|
||||||
|
|
||||||
|
private List<double> FramerateLog = new List<double>();
|
||||||
|
|
||||||
|
private double CurrentTDP;
|
||||||
|
|
||||||
|
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 void Start()
|
||||||
|
{
|
||||||
|
if (!IsEnabled() || IsRunning())
|
||||||
|
{
|
||||||
|
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())
|
||||||
|
{
|
||||||
|
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"))
|
||||||
|
{
|
||||||
|
powerLimiter = new ASUSACPIPowerLimiter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (limiter is not null && limiter.Equals("intel_msr"))
|
||||||
|
{
|
||||||
|
powerLimiter = new IntelMSRPowerLimiter();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveGameProfiles()
|
||||||
|
{
|
||||||
|
string json = JsonSerializer.Serialize(GameProfiles);
|
||||||
|
|
||||||
|
File.WriteAllText(GameProfileFile, json);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void LoadGameProfiles()
|
||||||
|
{
|
||||||
|
if (!File.Exists(GameProfileFile))
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
Logger.WriteLine("[AutoTDPService] No games detected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (GameInstance gi in runningGames)
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
tdpThread = new Thread(() =>
|
||||||
|
{
|
||||||
|
CurrentTDP = powerLimiter.GetCPUPowerLimit();
|
||||||
|
while (currentGame is not null && Running)
|
||||||
|
{
|
||||||
|
GameFPS = framerateSouce.GetFramerate(profile.ProcessName);
|
||||||
|
|
||||||
|
|
||||||
|
Logger.WriteLine("[AutoTDPService] (" + instance.ProcessName + ") Framerate " + GameFPS);
|
||||||
|
|
||||||
|
if (GameFPS < 0.0d)
|
||||||
|
{
|
||||||
|
//Game is not running anymore or RTSS lost its hook
|
||||||
|
Reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
FramerateTargetReachedCounter++;
|
||||||
|
|
||||||
|
if (FramerateTargetReachedCounter >= 4
|
||||||
|
&& FramerateTargetReachedCounter < FPSDipHistorySize
|
||||||
|
&& targetFPS - 0.75 <= FramerateLog.Take(4).Average()
|
||||||
|
&& FramerateLog.Take(3).Average() <= targetFPS + 0.15)
|
||||||
|
{
|
||||||
|
//short dip
|
||||||
|
FramerateDipCounter++;
|
||||||
|
correction = targetFPS + 0.75 - currentFramerate;
|
||||||
|
}
|
||||||
|
else if (FramerateDipCounter >= 5
|
||||||
|
&& targetFPS - 0.75 <= FramerateLog.Average()
|
||||||
|
&& FramerateLog.Average() <= targetFPS + 0.15)
|
||||||
|
{
|
||||||
|
//long dip
|
||||||
|
correction = targetFPS + 1.5 - currentFramerate;
|
||||||
|
FramerateTargetReachedCounter = FPSDipHistorySize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//No dip, no correction
|
||||||
|
correction = 0.0;
|
||||||
|
FramerateTargetReachedCounter = 0;
|
||||||
|
FramerateDipCounter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return correction;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private double TDPDamper(double currentFramerate)
|
||||||
|
{
|
||||||
|
if (double.IsNaN(GameFPSPrevious)) GameFPSPrevious = currentFramerate;
|
||||||
|
double dF = -0.1d;
|
||||||
|
|
||||||
|
// Calculation
|
||||||
|
double deltaError = currentFramerate - GameFPSPrevious;
|
||||||
|
double dT = deltaError / (1010.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;
|
||||||
|
|
||||||
|
|
||||||
|
Logger.WriteLine("[AutoTDPService] Current: " + (int)GameFPS + "FPS");
|
||||||
|
|
||||||
|
|
||||||
|
double delta = profile.TargetFPS - GameFPS - FPSDipCorrection(GameFPS, profile.TargetFPS);
|
||||||
|
delta = Math.Clamp(delta, -15, 15);
|
||||||
|
|
||||||
|
|
||||||
|
double adjustment = (delta * CurrentTDP / GameFPS) * 0.85;
|
||||||
|
//Dampen the changes to not change TDP too aggressively which would cause performance issues
|
||||||
|
adjustment += TDPDamper(GameFPS);
|
||||||
|
|
||||||
|
|
||||||
|
newPL += adjustment;
|
||||||
|
|
||||||
|
//Respect the limits that the user chose
|
||||||
|
newPL = Math.Clamp(newPL, profile.MinTdp, profile.MaxTdp);
|
||||||
|
|
||||||
|
Logger.WriteLine("[AutoTDPService] Setting Power Limit from " + CurrentTDP + "W to " + newPL + "W, Delta:" + adjustment);
|
||||||
|
|
||||||
|
//We only limit to full watts, no fractions. In this case, we will cut off the fractional part
|
||||||
|
powerLimiter.SetCPUPowerLimit((int)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;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Kill RTSS instance if we started one
|
||||||
|
RTSSFramerateSource.Stop();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
311
app/AutoTDP/AutoTDPUI.Designer.cs
generated
Normal file
311
app/AutoTDP/AutoTDPUI.Designer.cs
generated
Normal file
@@ -0,0 +1,311 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
222
app/AutoTDP/AutoTDPUI.cs
Normal file
222
app/AutoTDP/AutoTDPUI.cs
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
using GHelper.AutoTDP.FramerateSource;
|
||||||
|
using GHelper.UI;
|
||||||
|
using Ryzen;
|
||||||
|
|
||||||
|
namespace GHelper.AutoTDP
|
||||||
|
{
|
||||||
|
public partial class AutoTDPUI : RForm
|
||||||
|
{
|
||||||
|
private AutoTDPGameProfileUI? profileUI;
|
||||||
|
public AutoTDPUI()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
InitTheme();
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if ((comboBoxFPSSource.SelectedItem as string).StartsWith("Riva"))
|
||||||
|
{
|
||||||
|
AppConfig.Set("auto_tdp_fps_source", "rtss");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ComboBoxLimiter_DropDownClosed(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if ((comboBoxLimiter.SelectedItem as string).StartsWith("Intel"))
|
||||||
|
{
|
||||||
|
AppConfig.Set("auto_tdp_limiter", "intel_msr");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ((comboBoxLimiter.SelectedItem as string).StartsWith("ASUS ACPI"))
|
||||||
|
{
|
||||||
|
AppConfig.Set("auto_tdp_limiter", "asus_acpi");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
p.Enabled = true;
|
||||||
|
p.TargetFPS = 60;
|
||||||
|
p.MaxTdp = 40;
|
||||||
|
p.MinTdp = 20;
|
||||||
|
|
||||||
|
profileUI = new AutoTDPGameProfileUI(p, this);
|
||||||
|
profileUI.TopMost = true;
|
||||||
|
profileUI.FormClosed += ProfileUI_FormClosed;
|
||||||
|
profileUI.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (!RyzenControl.IsAMD())
|
||||||
|
comboBoxLimiter.Items.Add("Intel MSR Power Limiter");
|
||||||
|
|
||||||
|
|
||||||
|
comboBoxLimiter.Items.Add("ASUS ACPI Power Limiter");
|
||||||
|
|
||||||
|
string? limiter = AppConfig.GetString("auto_tdp_limiter");
|
||||||
|
|
||||||
|
if (comboBoxLimiter.Items.Count > 0 && limiter is null)
|
||||||
|
comboBoxLimiter.SelectedIndex = 0;
|
||||||
|
|
||||||
|
if (!RyzenControl.IsAMD() && limiter is not null && limiter.Equals("intel_msr"))
|
||||||
|
{
|
||||||
|
comboBoxLimiter.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (limiter is not null && limiter.Equals("asus_acpi"))
|
||||||
|
{
|
||||||
|
comboBoxLimiter.SelectedIndex = !RyzenControl.IsAMD() ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (RTSSFramerateSource.IsAvailable())
|
||||||
|
comboBoxFPSSource.Items.Add("Riva Tuner Statistics Server");
|
||||||
|
|
||||||
|
|
||||||
|
string? source = AppConfig.GetString("auto_tdp_fps_source", null);
|
||||||
|
|
||||||
|
if (comboBoxFPSSource.Items.Count > 0 && source is null)
|
||||||
|
comboBoxFPSSource.SelectedIndex = 0;
|
||||||
|
|
||||||
|
if (source is not null && source.Equals("rtss"))
|
||||||
|
{
|
||||||
|
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.TopMost = true;
|
||||||
|
profileUI.FormClosed += ProfileUI_FormClosed;
|
||||||
|
profileUI.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
120
app/AutoTDP/AutoTDPUI.resx
Normal file
120
app/AutoTDP/AutoTDPUI.resx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?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>
|
||||||
17
app/AutoTDP/FramerateSource/IFramerateSource.cs
Normal file
17
app/AutoTDP/FramerateSource/IFramerateSource.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
namespace GHelper.AutoTDP.FramerateSource
|
||||||
|
{
|
||||||
|
|
||||||
|
internal class GameInstance
|
||||||
|
{
|
||||||
|
public string? ProcessName { get; set; }
|
||||||
|
|
||||||
|
public int ProcessID { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal interface IFramerateSource
|
||||||
|
{
|
||||||
|
public double GetFramerate(string processName);
|
||||||
|
|
||||||
|
public List<GameInstance> GetRunningGames();
|
||||||
|
}
|
||||||
|
}
|
||||||
136
app/AutoTDP/FramerateSource/RTSSFramerateSource.cs
Normal file
136
app/AutoTDP/FramerateSource/RTSSFramerateSource.cs
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
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(string processName)
|
||||||
|
{
|
||||||
|
if (!IsRunning)
|
||||||
|
{
|
||||||
|
return -1.0d;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var appE = OSD.GetAppEntries()
|
||||||
|
.Where(x => (x.Flags & AppFlags.MASK) != AppFlags.None).FirstOrDefault(a => a.Name.EndsWith(processName));
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
app/AutoTDP/GameProfile.cs
Normal file
18
app/AutoTDP/GameProfile.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
42
app/AutoTDP/PowerLimiter/ASUSACPIPowerLimiter.cs
Normal file
42
app/AutoTDP/PowerLimiter/ASUSACPIPowerLimiter.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GHelper.AutoTDP.PowerLimiter
|
||||||
|
{
|
||||||
|
internal class ASUSACPIPowerLimiter : IPowerLimiter
|
||||||
|
{
|
||||||
|
|
||||||
|
private int DefaultA0 = Program.acpi.DeviceGet(AsusACPI.PPT_APUA0);
|
||||||
|
private int DefaultA3 = Program.acpi.DeviceGet(AsusACPI.PPT_APUA0);
|
||||||
|
|
||||||
|
public void SetCPUPowerLimit(int watts)
|
||||||
|
{
|
||||||
|
if (Program.acpi.DeviceGet(AsusACPI.PPT_APUA0) >= 0)
|
||||||
|
{
|
||||||
|
Program.acpi.DeviceSet(AsusACPI.PPT_APUA3, watts, "PowerLimit A3");
|
||||||
|
Program.acpi.DeviceSet(AsusACPI.PPT_APUA0, watts, "PowerLimit A0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int GetCPUPowerLimit()
|
||||||
|
{
|
||||||
|
return Program.acpi.DeviceGet(AsusACPI.PPT_APUA0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
//Nothing to dispose here
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetPowerLimits()
|
||||||
|
{
|
||||||
|
//Load limits that were set before the limiter engaged
|
||||||
|
Program.acpi.DeviceSet(AsusACPI.PPT_APUA3, DefaultA0, "PowerLimit A3");
|
||||||
|
Program.acpi.DeviceSet(AsusACPI.PPT_APUA0, DefaultA3, "PowerLimit A0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
app/AutoTDP/PowerLimiter/IPowerLimiter.cs
Normal file
12
app/AutoTDP/PowerLimiter/IPowerLimiter.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
namespace GHelper.AutoTDP.PowerLimiter
|
||||||
|
{
|
||||||
|
internal interface IPowerLimiter : IDisposable
|
||||||
|
{
|
||||||
|
public void SetCPUPowerLimit(int watts);
|
||||||
|
|
||||||
|
public int GetCPUPowerLimit();
|
||||||
|
|
||||||
|
public void ResetPowerLimits();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
106
app/AutoTDP/PowerLimiter/IntelMSRPowerLimiter.cs
Normal file
106
app/AutoTDP/PowerLimiter/IntelMSRPowerLimiter.cs
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
using HidSharp.Reports.Units;
|
||||||
|
using Ryzen;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GHelper.AutoTDP.PowerLimiter
|
||||||
|
{
|
||||||
|
internal class IntelMSRPowerLimiter : IPowerLimiter
|
||||||
|
{
|
||||||
|
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 void ReadPowerUnit()
|
||||||
|
{
|
||||||
|
uint eax = 0;
|
||||||
|
uint edx = 0;
|
||||||
|
|
||||||
|
ols.Rdmsr(0x606, ref eax, ref edx);
|
||||||
|
|
||||||
|
|
||||||
|
uint pwr = eax & 0x03;
|
||||||
|
|
||||||
|
PowerUnit = 1 / Math.Pow(2, pwr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetCPUPowerLimit(int watts)
|
||||||
|
{
|
||||||
|
uint eax = 0;
|
||||||
|
uint edx = 0;
|
||||||
|
|
||||||
|
|
||||||
|
ols.Rdmsr(0x610, 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(0x610, ref eax, ref edx);
|
||||||
|
|
||||||
|
if (DefaultEax == 0)
|
||||||
|
{
|
||||||
|
//Store default settings to reset them on exit
|
||||||
|
DefaultEax = eax;
|
||||||
|
DefaultEdx = edx;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint pl1 = eax & PL1_MASK;
|
||||||
|
uint pl2 = edx & PL2_MASK;
|
||||||
|
|
||||||
|
return (int)(pl1 * PowerUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void ResetPowerLimits()
|
||||||
|
{
|
||||||
|
if (DefaultEax == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ols.Wrmsr(0x610, DefaultEax, DefaultEdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
ols.DeinitializeOls();
|
||||||
|
ols.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -88,6 +88,14 @@
|
|||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="RTSSSharedMemoryNET">
|
||||||
|
<HintPath>RTSSSharedMemoryNET.dll</HintPath>
|
||||||
|
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
|
||||||
|
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Update="Properties\Resources.Designer.cs">
|
<Compile Update="Properties\Resources.Designer.cs">
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
|
|||||||
@@ -14,18 +14,24 @@ Global
|
|||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
Release|Any CPU = Release|Any CPU
|
Release|Any CPU = Release|Any CPU
|
||||||
Release|x64 = Release|x64
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Debug|Any CPU.ActiveCfg = Debug|x64
|
{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|Any CPU.Build.0 = Debug|x64
|
||||||
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Debug|x64.ActiveCfg = Debug|Any CPU
|
{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|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.ActiveCfg = Release|x64
|
||||||
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Release|Any CPU.Build.0 = 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.ActiveCfg = Release|x64
|
||||||
{D6138BB1-8FDB-4835-87EF-2FE41A3DD604}.Release|x64.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using GHelper.Ally;
|
using GHelper.Ally;
|
||||||
|
using GHelper.AutoTDP;
|
||||||
using GHelper.Battery;
|
using GHelper.Battery;
|
||||||
using GHelper.Display;
|
using GHelper.Display;
|
||||||
using GHelper.Gpu;
|
using GHelper.Gpu;
|
||||||
@@ -46,6 +47,8 @@ namespace GHelper
|
|||||||
|
|
||||||
private static PowerLineStatus isPlugged = SystemInformation.PowerStatus.PowerLineStatus;
|
private static PowerLineStatus isPlugged = SystemInformation.PowerStatus.PowerLineStatus;
|
||||||
|
|
||||||
|
public static AutoTDPService autoTDPService = new AutoTDPService();
|
||||||
|
|
||||||
// The main entry point for the application
|
// The main entry point for the application
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
@@ -306,6 +309,7 @@ namespace GHelper
|
|||||||
|
|
||||||
static void OnExit(object sender, EventArgs e)
|
static void OnExit(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
autoTDPService.Shutdown();
|
||||||
trayIcon.Visible = false;
|
trayIcon.Visible = false;
|
||||||
PeripheralsProvider.UnregisterForDeviceEvents();
|
PeripheralsProvider.UnregisterForDeviceEvents();
|
||||||
clamshellControl.UnregisterDisplayEvents();
|
clamshellControl.UnregisterDisplayEvents();
|
||||||
|
|||||||
BIN
app/RTSSSharedMemoryNET.dll
Normal file
BIN
app/RTSSSharedMemoryNET.dll
Normal file
Binary file not shown.
47
app/Settings.Designer.cs
generated
47
app/Settings.Designer.cs
generated
@@ -67,6 +67,8 @@ namespace GHelper
|
|||||||
labelCPUFan = new Label();
|
labelCPUFan = new Label();
|
||||||
panelGPU = new Panel();
|
panelGPU = new Panel();
|
||||||
labelTipGPU = new Label();
|
labelTipGPU = new Label();
|
||||||
|
tableAdditionalGPUFeature = new TableLayoutPanel();
|
||||||
|
buttonAutoTDP = new RButton();
|
||||||
tableAMD = new TableLayoutPanel();
|
tableAMD = new TableLayoutPanel();
|
||||||
buttonOverlay = new RButton();
|
buttonOverlay = new RButton();
|
||||||
buttonFPS = new RButton();
|
buttonFPS = new RButton();
|
||||||
@@ -143,6 +145,7 @@ namespace GHelper
|
|||||||
panelCPUTitle.SuspendLayout();
|
panelCPUTitle.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)picturePerf).BeginInit();
|
((System.ComponentModel.ISupportInitialize)picturePerf).BeginInit();
|
||||||
panelGPU.SuspendLayout();
|
panelGPU.SuspendLayout();
|
||||||
|
tableAdditionalGPUFeature.SuspendLayout();
|
||||||
tableAMD.SuspendLayout();
|
tableAMD.SuspendLayout();
|
||||||
tableGPU.SuspendLayout();
|
tableGPU.SuspendLayout();
|
||||||
panelGPUTitle.SuspendLayout();
|
panelGPUTitle.SuspendLayout();
|
||||||
@@ -723,6 +726,7 @@ namespace GHelper
|
|||||||
panelGPU.AutoSize = true;
|
panelGPU.AutoSize = true;
|
||||||
panelGPU.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
panelGPU.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||||
panelGPU.Controls.Add(labelTipGPU);
|
panelGPU.Controls.Add(labelTipGPU);
|
||||||
|
panelGPU.Controls.Add(tableAdditionalGPUFeature);
|
||||||
panelGPU.Controls.Add(tableAMD);
|
panelGPU.Controls.Add(tableAMD);
|
||||||
panelGPU.Controls.Add(tableGPU);
|
panelGPU.Controls.Add(tableGPU);
|
||||||
panelGPU.Controls.Add(panelGPUTitle);
|
panelGPU.Controls.Add(panelGPUTitle);
|
||||||
@@ -745,6 +749,46 @@ namespace GHelper
|
|||||||
labelTipGPU.Size = new Size(787, 36);
|
labelTipGPU.Size = new Size(787, 36);
|
||||||
labelTipGPU.TabIndex = 20;
|
labelTipGPU.TabIndex = 20;
|
||||||
//
|
//
|
||||||
|
// tableAdditionalGPUFeature
|
||||||
|
//
|
||||||
|
tableAdditionalGPUFeature.AutoSize = true;
|
||||||
|
tableAdditionalGPUFeature.AutoSizeMode = AutoSizeMode.GrowAndShrink;
|
||||||
|
tableAdditionalGPUFeature.ColumnCount = 3;
|
||||||
|
tableAdditionalGPUFeature.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.3333321F));
|
||||||
|
tableAdditionalGPUFeature.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.3333321F));
|
||||||
|
tableAdditionalGPUFeature.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.3333321F));
|
||||||
|
tableAdditionalGPUFeature.Controls.Add(buttonAutoTDP, 0, 0);
|
||||||
|
tableAdditionalGPUFeature.Dock = DockStyle.Top;
|
||||||
|
tableAdditionalGPUFeature.Location = new Point(10, 198);
|
||||||
|
tableAdditionalGPUFeature.Margin = new Padding(2, 1, 2, 1);
|
||||||
|
tableAdditionalGPUFeature.Name = "tableAdditionalGPUFeature";
|
||||||
|
tableAdditionalGPUFeature.RowCount = 1;
|
||||||
|
tableAdditionalGPUFeature.RowStyles.Add(new RowStyle(SizeType.Absolute, 60F));
|
||||||
|
tableAdditionalGPUFeature.Size = new Size(392, 60);
|
||||||
|
tableAdditionalGPUFeature.TabIndex = 25;
|
||||||
|
//
|
||||||
|
// buttonAutoTDP
|
||||||
|
//
|
||||||
|
buttonAutoTDP.Activated = false;
|
||||||
|
buttonAutoTDP.BackColor = SystemColors.ControlLightLight;
|
||||||
|
buttonAutoTDP.BorderColor = Color.Transparent;
|
||||||
|
buttonAutoTDP.BorderRadius = 5;
|
||||||
|
buttonAutoTDP.Dock = DockStyle.Fill;
|
||||||
|
buttonAutoTDP.FlatAppearance.BorderSize = 0;
|
||||||
|
buttonAutoTDP.FlatStyle = FlatStyle.Flat;
|
||||||
|
buttonAutoTDP.ForeColor = SystemColors.ControlText;
|
||||||
|
buttonAutoTDP.Image = Properties.Resources.icons8_processor_32;
|
||||||
|
buttonAutoTDP.ImageAlign = ContentAlignment.MiddleRight;
|
||||||
|
buttonAutoTDP.Location = new Point(1, 1);
|
||||||
|
buttonAutoTDP.Margin = new Padding(1, 1, 1, 1);
|
||||||
|
buttonAutoTDP.Name = "buttonAutoTDP";
|
||||||
|
buttonAutoTDP.Secondary = false;
|
||||||
|
buttonAutoTDP.Size = new Size(128, 38);
|
||||||
|
buttonAutoTDP.TabIndex = 11;
|
||||||
|
buttonAutoTDP.Text = "Auto TDP";
|
||||||
|
buttonAutoTDP.TextImageRelation = TextImageRelation.ImageBeforeText;
|
||||||
|
buttonAutoTDP.UseVisualStyleBackColor = false;
|
||||||
|
//
|
||||||
// tableAMD
|
// tableAMD
|
||||||
//
|
//
|
||||||
tableAMD.AutoSize = true;
|
tableAMD.AutoSize = true;
|
||||||
@@ -1790,6 +1834,7 @@ namespace GHelper
|
|||||||
((System.ComponentModel.ISupportInitialize)picturePerf).EndInit();
|
((System.ComponentModel.ISupportInitialize)picturePerf).EndInit();
|
||||||
panelGPU.ResumeLayout(false);
|
panelGPU.ResumeLayout(false);
|
||||||
panelGPU.PerformLayout();
|
panelGPU.PerformLayout();
|
||||||
|
tableAdditionalGPUFeature.ResumeLayout(false);
|
||||||
tableAMD.ResumeLayout(false);
|
tableAMD.ResumeLayout(false);
|
||||||
tableGPU.ResumeLayout(false);
|
tableGPU.ResumeLayout(false);
|
||||||
panelGPUTitle.ResumeLayout(false);
|
panelGPUTitle.ResumeLayout(false);
|
||||||
@@ -1931,5 +1976,7 @@ namespace GHelper
|
|||||||
private Label labelGammaTitle;
|
private Label labelGammaTitle;
|
||||||
private CheckBox checkMatrixLid;
|
private CheckBox checkMatrixLid;
|
||||||
private Panel panelMatrixAuto;
|
private Panel panelMatrixAuto;
|
||||||
|
private TableLayoutPanel tableAdditionalGPUFeature;
|
||||||
|
private RButton buttonAutoTDP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using GHelper.Ally;
|
using GHelper.Ally;
|
||||||
using GHelper.AnimeMatrix;
|
using GHelper.AnimeMatrix;
|
||||||
|
using GHelper.AutoTDP;
|
||||||
using GHelper.AutoUpdate;
|
using GHelper.AutoUpdate;
|
||||||
using GHelper.Battery;
|
using GHelper.Battery;
|
||||||
using GHelper.Display;
|
using GHelper.Display;
|
||||||
@@ -28,6 +29,7 @@ namespace GHelper
|
|||||||
AutoUpdateControl updateControl;
|
AutoUpdateControl updateControl;
|
||||||
|
|
||||||
AsusMouseSettings? mouseSettings;
|
AsusMouseSettings? mouseSettings;
|
||||||
|
AutoTDPUI? autoTdpUi;
|
||||||
|
|
||||||
public AniMatrixControl matrixControl;
|
public AniMatrixControl matrixControl;
|
||||||
|
|
||||||
@@ -244,6 +246,8 @@ namespace GHelper
|
|||||||
buttonFPS.Click += ButtonFPS_Click;
|
buttonFPS.Click += ButtonFPS_Click;
|
||||||
buttonOverlay.Click += ButtonOverlay_Click;
|
buttonOverlay.Click += ButtonOverlay_Click;
|
||||||
|
|
||||||
|
buttonAutoTDP.Click += ButtonAutoTDP_Click;
|
||||||
|
|
||||||
Text = "G-Helper " + (ProcessHelper.IsUserAdministrator() ? "—" : "-") + " " + AppConfig.GetModelShort();
|
Text = "G-Helper " + (ProcessHelper.IsUserAdministrator() ? "—" : "-") + " " + AppConfig.GetModelShort();
|
||||||
TopMost = AppConfig.Is("topmost");
|
TopMost = AppConfig.Is("topmost");
|
||||||
|
|
||||||
@@ -261,6 +265,32 @@ namespace GHelper
|
|||||||
panelPerformance.Focus();
|
panelPerformance.Focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ButtonAutoTDP_Click(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
autoTdpUi = new AutoTDPUI();
|
||||||
|
autoTdpUi.TopMost = true;
|
||||||
|
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)
|
private void SliderGamma_ValueChanged(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
screenControl.SetGamma(sliderGamma.Value);
|
screenControl.SetGamma(sliderGamma.Value);
|
||||||
@@ -1081,6 +1111,7 @@ namespace GHelper
|
|||||||
|
|
||||||
private void ButtonQuit_Click(object? sender, EventArgs e)
|
private void ButtonQuit_Click(object? sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
Program.autoTDPService.Shutdown();
|
||||||
matrixControl.Dispose();
|
matrixControl.Dispose();
|
||||||
Close();
|
Close();
|
||||||
Program.trayIcon.Visible = false;
|
Program.trayIcon.Visible = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user