diff --git a/BizHawk.Client.Common/config/Config.cs b/BizHawk.Client.Common/config/Config.cs index ca6c8cecf8..54a36446c1 100644 --- a/BizHawk.Client.Common/config/Config.cs +++ b/BizHawk.Client.Common/config/Config.cs @@ -134,6 +134,7 @@ namespace BizHawk.Client.Common public int SpeedPercent = 100; public int SpeedPercentAlternate = 400; public bool ClockThrottle = true; + public bool ClockThrottleUseLowCPUMode = false; public bool AutoMinimizeSkipping = true; public bool VSyncThrottle = false; diff --git a/BizHawk.Client.EmuHawk/MainForm.Designer.cs b/BizHawk.Client.EmuHawk/MainForm.Designer.cs index ba6e4decb6..12a4537db8 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Designer.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Designer.cs @@ -148,7 +148,8 @@ this.ProfilesMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator9 = new System.Windows.Forms.ToolStripSeparator(); this.SpeedSkipSubMenu = new System.Windows.Forms.ToolStripMenuItem(); - this.ClickThrottleMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.ClockThrottleMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.ClockThrottleLowCPUMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.AudioThrottleMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.VsyncThrottleMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator27 = new System.Windows.Forms.ToolStripSeparator(); @@ -1456,7 +1457,8 @@ // SpeedSkipSubMenu // this.SpeedSkipSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.ClickThrottleMenuItem, + this.ClockThrottleMenuItem, + this.ClockThrottleLowCPUMenuItem, this.AudioThrottleMenuItem, this.VsyncThrottleMenuItem, this.toolStripSeparator27, @@ -1484,158 +1486,165 @@ this.SpeedSkipSubMenu.Text = "Speed/Skip"; this.SpeedSkipSubMenu.DropDownOpened += new System.EventHandler(this.FrameSkipMenuItem_DropDownOpened); // - // ClickThrottleMenuItem + // ClockThrottleMenuItem // - this.ClickThrottleMenuItem.Name = "ClickThrottleMenuItem"; - this.ClickThrottleMenuItem.Size = new System.Drawing.Size(202, 22); - this.ClickThrottleMenuItem.Text = "Clock Throttle"; - this.ClickThrottleMenuItem.Click += new System.EventHandler(this.ClickThrottleMenuItem_Click); + this.ClockThrottleMenuItem.Name = "ClockThrottleMenuItem"; + this.ClockThrottleMenuItem.Size = new System.Drawing.Size(287, 22); + this.ClockThrottleMenuItem.Text = "Clock Throttle"; + this.ClockThrottleMenuItem.Click += new System.EventHandler(this.ClockThrottleMenuItem_Click); + // + // ClockThrottleLowCPUMenuItem + // + this.ClockThrottleLowCPUMenuItem.Name = "ClockThrottleLowCPUMenuItem"; + this.ClockThrottleLowCPUMenuItem.Size = new System.Drawing.Size(287, 22); + this.ClockThrottleLowCPUMenuItem.Text = "Clock Throttle (Low CPU) [experimental]"; + this.ClockThrottleLowCPUMenuItem.Click += new System.EventHandler(this.ClockThrottleMenuItem_Click); // // AudioThrottleMenuItem // this.AudioThrottleMenuItem.Name = "AudioThrottleMenuItem"; - this.AudioThrottleMenuItem.Size = new System.Drawing.Size(202, 22); + this.AudioThrottleMenuItem.Size = new System.Drawing.Size(287, 22); this.AudioThrottleMenuItem.Text = "Audio Throttle"; this.AudioThrottleMenuItem.Click += new System.EventHandler(this.AudioThrottleMenuItem_Click); // // VsyncThrottleMenuItem // this.VsyncThrottleMenuItem.Name = "VsyncThrottleMenuItem"; - this.VsyncThrottleMenuItem.Size = new System.Drawing.Size(202, 22); + this.VsyncThrottleMenuItem.Size = new System.Drawing.Size(287, 22); this.VsyncThrottleMenuItem.Text = "VSync Throttle"; this.VsyncThrottleMenuItem.Click += new System.EventHandler(this.VsyncThrottleMenuItem_Click); // // toolStripSeparator27 // this.toolStripSeparator27.Name = "toolStripSeparator27"; - this.toolStripSeparator27.Size = new System.Drawing.Size(199, 6); + this.toolStripSeparator27.Size = new System.Drawing.Size(284, 6); // // VsyncEnabledMenuItem // this.VsyncEnabledMenuItem.Name = "VsyncEnabledMenuItem"; - this.VsyncEnabledMenuItem.Size = new System.Drawing.Size(202, 22); + this.VsyncEnabledMenuItem.Size = new System.Drawing.Size(287, 22); this.VsyncEnabledMenuItem.Text = "VSync Enabled"; this.VsyncEnabledMenuItem.Click += new System.EventHandler(this.VsyncEnabledMenuItem_Click); // // toolStripMenuItem3 // this.toolStripMenuItem3.Name = "toolStripMenuItem3"; - this.toolStripMenuItem3.Size = new System.Drawing.Size(199, 6); + this.toolStripMenuItem3.Size = new System.Drawing.Size(284, 6); // // MinimizeSkippingMenuItem // this.MinimizeSkippingMenuItem.Name = "MinimizeSkippingMenuItem"; - this.MinimizeSkippingMenuItem.Size = new System.Drawing.Size(202, 22); + this.MinimizeSkippingMenuItem.Size = new System.Drawing.Size(287, 22); this.MinimizeSkippingMenuItem.Text = "Auto-minimize skipping"; this.MinimizeSkippingMenuItem.Click += new System.EventHandler(this.MinimizeSkippingMenuItem_Click); // // NeverSkipMenuItem // this.NeverSkipMenuItem.Name = "NeverSkipMenuItem"; - this.NeverSkipMenuItem.Size = new System.Drawing.Size(202, 22); + this.NeverSkipMenuItem.Size = new System.Drawing.Size(287, 22); this.NeverSkipMenuItem.Text = "0 (never skip)"; this.NeverSkipMenuItem.Click += new System.EventHandler(this.NeverSkipMenuItem_Click); // // Frameskip1MenuItem // this.Frameskip1MenuItem.Name = "Frameskip1MenuItem"; - this.Frameskip1MenuItem.Size = new System.Drawing.Size(202, 22); + this.Frameskip1MenuItem.Size = new System.Drawing.Size(287, 22); this.Frameskip1MenuItem.Text = "1"; this.Frameskip1MenuItem.Click += new System.EventHandler(this.Frameskip1MenuItem_Click); // // Frameskip2MenuItem // this.Frameskip2MenuItem.Name = "Frameskip2MenuItem"; - this.Frameskip2MenuItem.Size = new System.Drawing.Size(202, 22); + this.Frameskip2MenuItem.Size = new System.Drawing.Size(287, 22); this.Frameskip2MenuItem.Text = "2"; this.Frameskip2MenuItem.Click += new System.EventHandler(this.Frameskip2MenuItem_Click); // // Frameskip3MenuItem // this.Frameskip3MenuItem.Name = "Frameskip3MenuItem"; - this.Frameskip3MenuItem.Size = new System.Drawing.Size(202, 22); + this.Frameskip3MenuItem.Size = new System.Drawing.Size(287, 22); this.Frameskip3MenuItem.Text = "3"; this.Frameskip3MenuItem.Click += new System.EventHandler(this.Frameskip3MenuItem_Click); // // Frameskip4MenuItem // this.Frameskip4MenuItem.Name = "Frameskip4MenuItem"; - this.Frameskip4MenuItem.Size = new System.Drawing.Size(202, 22); + this.Frameskip4MenuItem.Size = new System.Drawing.Size(287, 22); this.Frameskip4MenuItem.Text = "4"; this.Frameskip4MenuItem.Click += new System.EventHandler(this.Frameskip4MenuItem_Click); // // Frameskip5MenuItem // this.Frameskip5MenuItem.Name = "Frameskip5MenuItem"; - this.Frameskip5MenuItem.Size = new System.Drawing.Size(202, 22); + this.Frameskip5MenuItem.Size = new System.Drawing.Size(287, 22); this.Frameskip5MenuItem.Text = "5"; this.Frameskip5MenuItem.Click += new System.EventHandler(this.Frameskip5MenuItem_Click); // // Frameskip6MenuItem // this.Frameskip6MenuItem.Name = "Frameskip6MenuItem"; - this.Frameskip6MenuItem.Size = new System.Drawing.Size(202, 22); + this.Frameskip6MenuItem.Size = new System.Drawing.Size(287, 22); this.Frameskip6MenuItem.Text = "6"; this.Frameskip6MenuItem.Click += new System.EventHandler(this.Frameskip6MenuItem_Click); // // Frameskip7MenuItem // this.Frameskip7MenuItem.Name = "Frameskip7MenuItem"; - this.Frameskip7MenuItem.Size = new System.Drawing.Size(202, 22); + this.Frameskip7MenuItem.Size = new System.Drawing.Size(287, 22); this.Frameskip7MenuItem.Text = "7"; this.Frameskip7MenuItem.Click += new System.EventHandler(this.Frameskip7MenuItem_Click); // // Frameskip8MenuItem // this.Frameskip8MenuItem.Name = "Frameskip8MenuItem"; - this.Frameskip8MenuItem.Size = new System.Drawing.Size(202, 22); + this.Frameskip8MenuItem.Size = new System.Drawing.Size(287, 22); this.Frameskip8MenuItem.Text = "8"; this.Frameskip8MenuItem.Click += new System.EventHandler(this.Frameskip8MenuItem_Click); // // Frameskip9MenuItem // this.Frameskip9MenuItem.Name = "Frameskip9MenuItem"; - this.Frameskip9MenuItem.Size = new System.Drawing.Size(202, 22); + this.Frameskip9MenuItem.Size = new System.Drawing.Size(287, 22); this.Frameskip9MenuItem.Text = "9"; this.Frameskip9MenuItem.Click += new System.EventHandler(this.Frameskip9MenuItem_Click); // // toolStripMenuItem5 // this.toolStripMenuItem5.Name = "toolStripMenuItem5"; - this.toolStripMenuItem5.Size = new System.Drawing.Size(199, 6); + this.toolStripMenuItem5.Size = new System.Drawing.Size(284, 6); // // Speed50MenuItem // this.Speed50MenuItem.Name = "Speed50MenuItem"; - this.Speed50MenuItem.Size = new System.Drawing.Size(202, 22); + this.Speed50MenuItem.Size = new System.Drawing.Size(287, 22); this.Speed50MenuItem.Text = "Speed 50%"; this.Speed50MenuItem.Click += new System.EventHandler(this.Speed50MenuItem_Click); // // Speed75MenuItem // this.Speed75MenuItem.Name = "Speed75MenuItem"; - this.Speed75MenuItem.Size = new System.Drawing.Size(202, 22); + this.Speed75MenuItem.Size = new System.Drawing.Size(287, 22); this.Speed75MenuItem.Text = "Speed 75%"; this.Speed75MenuItem.Click += new System.EventHandler(this.Speed75MenuItem_Click); // // Speed100MenuItem // this.Speed100MenuItem.Name = "Speed100MenuItem"; - this.Speed100MenuItem.Size = new System.Drawing.Size(202, 22); + this.Speed100MenuItem.Size = new System.Drawing.Size(287, 22); this.Speed100MenuItem.Text = "Speed 100%"; this.Speed100MenuItem.Click += new System.EventHandler(this.Speed100MenuItem_Click); // // Speed150MenuItem // this.Speed150MenuItem.Name = "Speed150MenuItem"; - this.Speed150MenuItem.Size = new System.Drawing.Size(202, 22); + this.Speed150MenuItem.Size = new System.Drawing.Size(287, 22); this.Speed150MenuItem.Text = "Speed 150%"; this.Speed150MenuItem.Click += new System.EventHandler(this.Speed150MenuItem_Click); // // Speed200MenuItem // this.Speed200MenuItem.Name = "Speed200MenuItem"; - this.Speed200MenuItem.Size = new System.Drawing.Size(202, 22); + this.Speed200MenuItem.Size = new System.Drawing.Size(287, 22); this.Speed200MenuItem.Text = "Speed 200%"; this.Speed200MenuItem.Click += new System.EventHandler(this.Speed200MenuItem_Click); // @@ -3475,7 +3484,8 @@ private System.Windows.Forms.ToolStripMenuItem Speed100MenuItem; private System.Windows.Forms.ToolStripMenuItem Speed150MenuItem; private System.Windows.Forms.ToolStripMenuItem Speed200MenuItem; - private System.Windows.Forms.ToolStripMenuItem ClickThrottleMenuItem; + private System.Windows.Forms.ToolStripMenuItem ClockThrottleMenuItem; + private System.Windows.Forms.ToolStripMenuItem ClockThrottleLowCPUMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator10; private System.Windows.Forms.ToolStripMenuItem SaveConfigMenuItem; private System.Windows.Forms.ToolStripMenuItem LoadConfigMenuItem; diff --git a/BizHawk.Client.EmuHawk/MainForm.Events.cs b/BizHawk.Client.EmuHawk/MainForm.Events.cs index b0c36dae5d..92c96cd4d9 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Events.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Events.cs @@ -796,7 +796,8 @@ namespace BizHawk.Client.EmuHawk private void FrameSkipMenuItem_DropDownOpened(object sender, EventArgs e) { MinimizeSkippingMenuItem.Checked = Global.Config.AutoMinimizeSkipping; - ClickThrottleMenuItem.Checked = Global.Config.ClockThrottle; + ClockThrottleMenuItem.Checked = Global.Config.ClockThrottle && !Global.Config.ClockThrottleUseLowCPUMode; + ClockThrottleLowCPUMenuItem.Checked = Global.Config.ClockThrottle && Global.Config.ClockThrottleUseLowCPUMode; VsyncThrottleMenuItem.Checked = Global.Config.VSyncThrottle; NeverSkipMenuItem.Checked = Global.Config.FrameSkip == 0; Frameskip1MenuItem.Checked = Global.Config.FrameSkip == 1; @@ -943,9 +944,16 @@ namespace BizHawk.Client.EmuHawk } } - private void ClickThrottleMenuItem_Click(object sender, EventArgs e) + private void ClockThrottleMenuItem_Click(object sender, EventArgs e) { - Global.Config.ClockThrottle ^= true; + // Regular clock throttle and low CPU mode share this event + bool clickedLowCPUMode = sender == ClockThrottleLowCPUMenuItem; + bool isToggling = !Global.Config.ClockThrottle || clickedLowCPUMode == Global.Config.ClockThrottleUseLowCPUMode; + if (isToggling) + { + Global.Config.ClockThrottle ^= true; + } + Global.Config.ClockThrottleUseLowCPUMode = Global.Config.ClockThrottle && clickedLowCPUMode; if (Global.Config.ClockThrottle) { var old = Global.Config.SoundThrottle; diff --git a/BizHawk.Client.EmuHawk/Throttle.cs b/BizHawk.Client.EmuHawk/Throttle.cs index 5a0fe6ec5c..caa640e95a 100644 --- a/BizHawk.Client.EmuHawk/Throttle.cs +++ b/BizHawk.Client.EmuHawk/Throttle.cs @@ -66,6 +66,14 @@ namespace BizHawk.Client.EmuHawk } } + public bool cfg_lowcpumode + { + get + { + return Global.Config.ClockThrottleUseLowCPUMode; + } + } + public void Step(bool allowSleep, int forceFrameSkip) { int skipRate = (forceFrameSkip < 0) ? cfg_frameskiprate : forceFrameSkip; @@ -167,7 +175,6 @@ namespace BizHawk.Client.EmuHawk #if WINDOWS timeBeginPeriod(1); #endif -#if WINDOWS // This seems safe even on other platforms, but needs testing to confirm if (Stopwatch.IsHighResolution) { afsfreq = (ulong)Stopwatch.Frequency; @@ -175,12 +182,9 @@ namespace BizHawk.Client.EmuHawk } else { -#endif afsfreq = 1000; tmethod = 0; -#if WINDOWS } -#endif Console.WriteLine("throttle method: {0}; resolution: {1}", tmethod, afsfreq); tfreq = afsfreq * 65536; } @@ -334,7 +338,6 @@ namespace BizHawk.Client.EmuHawk { AutoFrameSkip_BeforeThrottle(); - bool lowCPUMode = false; // Hard-code to true for testing ulong timePerFrame = tfreq / desiredfps; while (true) @@ -356,7 +359,7 @@ namespace BizHawk.Client.EmuHawk } int sleepy = (int)((timePerFrame - elapsedTime) * 1000 / afsfreq); - if (lowCPUMode && (sleepy >= 2 || paused)) + if (cfg_lowcpumode && (sleepy >= 2 || paused)) { // Subtract 1 to reduce the chance of oversleeping Thread.Sleep(Math.Max(sleepy - 1, 1));