From f3b3a8eed552dfed1f56365d09b8600462f1a1c0 Mon Sep 17 00:00:00 2001 From: Souryo Date: Mon, 24 Aug 2015 20:27:07 -0400 Subject: [PATCH] Replaced FPS limit by "Emulation speed" option --- Core/APU.cpp | 8 +- Core/APU.h | 2 +- Core/Console.cpp | 18 +-- Core/EmulationSettings.cpp | 2 +- Core/EmulationSettings.h | 12 +- Core/IAudioDevice.h | 1 + Core/VirtualController.cpp | 4 +- GUI.NET/Config/VideoInfo.cs | 6 +- .../Forms/Config/frmVideoConfig.Designer.cs | 77 +++++----- GUI.NET/Forms/Config/frmVideoConfig.cs | 25 +--- GUI.NET/Forms/frmMain.Designer.cs | 138 +++++++++++++----- GUI.NET/Forms/frmMain.cs | 99 +++++++++---- GUI.NET/InteropEmu.cs | 2 +- InteropDLL/ConsoleWrapper.cpp | 2 +- Windows/SoundManager.cpp | 14 +- Windows/SoundManager.h | 2 +- 16 files changed, 255 insertions(+), 157 deletions(-) diff --git a/Core/APU.cpp b/Core/APU.cpp index 0801dae0..0c509411 100644 --- a/Core/APU.cpp +++ b/Core/APU.cpp @@ -199,10 +199,14 @@ void APU::Exec() } } -void APU::StopAudio() +void APU::StopAudio(bool clearBuffer) { if(APU::AudioDevice) { - APU::AudioDevice->Pause(); + if(clearBuffer) { + APU::AudioDevice->Stop(); + } else { + APU::AudioDevice->Pause(); + } } } diff --git a/Core/APU.h b/Core/APU.h index 779ca81f..e63132e9 100644 --- a/Core/APU.h +++ b/Core/APU.h @@ -72,5 +72,5 @@ class APU : public Snapshotable, public IMemoryHandler static void ExecStatic(); static void StaticRun(); - static void StopAudio(); + static void StopAudio(bool clearBuffer = false); }; \ No newline at end of file diff --git a/Core/Console.cpp b/Core/Console.cpp index f116e210..e07fac41 100644 --- a/Core/Console.cpp +++ b/Core/Console.cpp @@ -134,6 +134,8 @@ void Console::ResetComponents(bool softReset) _cpu->Reset(softReset); _memoryManager->Reset(softReset); + _apu->StopAudio(true); + if(softReset) { MessageManager::SendNotification(ConsoleNotificationType::GameReset); } else { @@ -231,7 +233,7 @@ void Console::Run() } } } - _apu->StopAudio(); + _apu->StopAudio(true); _stopLock.Release(); _runLock.Release(); } @@ -239,22 +241,18 @@ void Console::Run() void Console::UpdateNesModel(double &frameDelay, bool showMessage) { NesModel model = EmulationSettings::GetNesModel(); - int32_t fpsLimit = EmulationSettings::GetFpsLimit(); + uint32_t emulationSpeed = EmulationSettings::GetEmulationSpeed(); if(model == NesModel::Auto) { model = _mapper->IsPalRom() ? NesModel::PAL : NesModel::NTSC; } - if(fpsLimit == -1) { - frameDelay = (model == NesModel::NTSC ? 16.63926405550947 : 19.99720920217466); //60.1fps (NTSC), 50.01fps (PAL) - } else if(fpsLimit == 50) { - frameDelay = 19.99720920217466; - } else if(fpsLimit == 60) { - frameDelay = 16.63926405550947; - } else if(fpsLimit == 0) { + if(emulationSpeed == 0) { frameDelay = 0; } else { - frameDelay = 1000.0 / fpsLimit; + frameDelay = (model == NesModel::NTSC ? 16.63926405550947 : 19.99720920217466); //60.1fps (NTSC), 50.01fps (PAL) + frameDelay /= (double)emulationSpeed / 100.0; } + _ppu->SetNesModel(model); _apu->SetNesModel(model); } diff --git a/Core/EmulationSettings.cpp b/Core/EmulationSettings.cpp index 7b2005ba..4e26b2a5 100644 --- a/Core/EmulationSettings.cpp +++ b/Core/EmulationSettings.cpp @@ -6,4 +6,4 @@ uint32_t EmulationSettings::AudioLatency = 20000; double EmulationSettings::ChannelVolume[5] = { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f }; NesModel EmulationSettings::Model = NesModel::Auto; OverscanDimensions EmulationSettings::Overscan; -int32_t EmulationSettings::FpsLimit = -1; \ No newline at end of file +uint32_t EmulationSettings::EmulationSpeed = 100; \ No newline at end of file diff --git a/Core/EmulationSettings.h b/Core/EmulationSettings.h index c8ad3769..d8edb69b 100644 --- a/Core/EmulationSettings.h +++ b/Core/EmulationSettings.h @@ -54,7 +54,7 @@ private: static uint32_t AudioLatency; static double ChannelVolume[5]; static NesModel Model; - static int32_t FpsLimit; + static uint32_t EmulationSpeed; static OverscanDimensions Overscan; public: @@ -94,15 +94,15 @@ public: AudioLatency = msLatency; } - //-1: Auto, 0: No limit, Number: Specific FPS - static void SetFpsLimit(int32_t fpsLimit) + //0: No limit, Number: % of default speed (50/60fps) + static void SetEmulationSpeed(uint32_t emulationSpeed) { - FpsLimit = fpsLimit; + EmulationSpeed = emulationSpeed; } - static int32_t GetFpsLimit() + static uint32_t GetEmulationSpeed() { - return FpsLimit; + return EmulationSpeed; } static void SetOverscanDimensions(uint8_t left, uint8_t right, uint8_t top, uint8_t bottom) diff --git a/Core/IAudioDevice.h b/Core/IAudioDevice.h index 4e364bdf..b5cfa83f 100644 --- a/Core/IAudioDevice.h +++ b/Core/IAudioDevice.h @@ -6,5 +6,6 @@ class IAudioDevice { public: virtual void PlayBuffer(int16_t *soundBuffer, uint32_t bufferSize) = 0; + virtual void Stop() = 0; virtual void Pause() = 0; }; \ No newline at end of file diff --git a/Core/VirtualController.cpp b/Core/VirtualController.cpp index 8dbefb5a..6f11fbbc 100644 --- a/Core/VirtualController.cpp +++ b/Core/VirtualController.cpp @@ -45,9 +45,9 @@ ButtonState VirtualController::GetButtonState() _queueSize--; if(_queueSize.load() > _minimumBuffer) { - EmulationSettings::SetFpsLimit(0); + EmulationSettings::SetEmulationSpeed(0); } else { - EmulationSettings::SetFpsLimit(-1); + EmulationSettings::SetEmulationSpeed(100); } _writeLock.Release(); diff --git a/GUI.NET/Config/VideoInfo.cs b/GUI.NET/Config/VideoInfo.cs index e8e07535..061e44cf 100644 --- a/GUI.NET/Config/VideoInfo.cs +++ b/GUI.NET/Config/VideoInfo.cs @@ -11,7 +11,7 @@ namespace Mesen.GUI.Config { public class VideoInfo { - public Int32 FpsLimit = -1; + public UInt32 EmulationSpeed = 100; public bool ShowFPS = false; public UInt32 OverscanLeft = 0; public UInt32 OverscanRight = 0; @@ -25,8 +25,8 @@ namespace Mesen.GUI.Config static public void ApplyConfig() { VideoInfo videoInfo = ConfigManager.Config.VideoInfo; - - InteropEmu.SetFpsLimit(videoInfo.FpsLimit); + + InteropEmu.SetEmulationSpeed(videoInfo.EmulationSpeed); if(ConfigManager.Config.VideoInfo.ShowFPS) { InteropEmu.SetFlags((UInt32)EmulationFlags.ShowFPS); diff --git a/GUI.NET/Forms/Config/frmVideoConfig.Designer.cs b/GUI.NET/Forms/Config/frmVideoConfig.Designer.cs index 35dc12cb..fca8c289 100644 --- a/GUI.NET/Forms/Config/frmVideoConfig.Designer.cs +++ b/GUI.NET/Forms/Config/frmVideoConfig.Designer.cs @@ -45,8 +45,9 @@ this.nudOverscanRight = new System.Windows.Forms.NumericUpDown(); this.chkShowFps = new System.Windows.Forms.CheckBox(); this.flowLayoutPanel6 = new System.Windows.Forms.FlowLayoutPanel(); - this.lblFpsLimit = new System.Windows.Forms.Label(); - this.cboFpsLimit = new System.Windows.Forms.ComboBox(); + this.lblEmulationSpeed = new System.Windows.Forms.Label(); + this.nudEmulationSpeed = new System.Windows.Forms.NumericUpDown(); + this.lblEmuSpeedHint = new System.Windows.Forms.Label(); this.tlpMain.SuspendLayout(); this.grpCropping.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); @@ -60,6 +61,7 @@ this.flowLayoutPanel2.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.nudOverscanRight)).BeginInit(); this.flowLayoutPanel6.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nudEmulationSpeed)).BeginInit(); this.SuspendLayout(); // // baseConfigPanel @@ -88,9 +90,9 @@ // this.grpCropping.Controls.Add(this.tableLayoutPanel1); this.grpCropping.Dock = System.Windows.Forms.DockStyle.Fill; - this.grpCropping.Location = new System.Drawing.Point(3, 53); + this.grpCropping.Location = new System.Drawing.Point(3, 52); this.grpCropping.Name = "grpCropping"; - this.grpCropping.Size = new System.Drawing.Size(356, 252); + this.grpCropping.Size = new System.Drawing.Size(356, 253); this.grpCropping.TabIndex = 7; this.grpCropping.TabStop = false; this.grpCropping.Text = "Video Cropping"; @@ -247,7 +249,7 @@ // chkShowFps // this.chkShowFps.AutoSize = true; - this.chkShowFps.Location = new System.Drawing.Point(3, 30); + this.chkShowFps.Location = new System.Drawing.Point(3, 29); this.chkShowFps.Name = "chkShowFps"; this.chkShowFps.Size = new System.Drawing.Size(76, 17); this.chkShowFps.TabIndex = 9; @@ -257,42 +259,47 @@ // flowLayoutPanel6 // this.flowLayoutPanel6.AutoSize = true; - this.flowLayoutPanel6.Controls.Add(this.lblFpsLimit); - this.flowLayoutPanel6.Controls.Add(this.cboFpsLimit); + this.flowLayoutPanel6.Controls.Add(this.lblEmulationSpeed); + this.flowLayoutPanel6.Controls.Add(this.nudEmulationSpeed); + this.flowLayoutPanel6.Controls.Add(this.lblEmuSpeedHint); this.flowLayoutPanel6.Dock = System.Windows.Forms.DockStyle.Fill; this.flowLayoutPanel6.Location = new System.Drawing.Point(0, 0); this.flowLayoutPanel6.Margin = new System.Windows.Forms.Padding(0); this.flowLayoutPanel6.Name = "flowLayoutPanel6"; - this.flowLayoutPanel6.Size = new System.Drawing.Size(362, 27); + this.flowLayoutPanel6.Size = new System.Drawing.Size(362, 26); this.flowLayoutPanel6.TabIndex = 10; // - // lblFpsLimit + // lblEmulationSpeed // - this.lblFpsLimit.Anchor = System.Windows.Forms.AnchorStyles.Left; - this.lblFpsLimit.AutoSize = true; - this.lblFpsLimit.Location = new System.Drawing.Point(3, 7); - this.lblFpsLimit.Name = "lblFpsLimit"; - this.lblFpsLimit.Size = new System.Drawing.Size(54, 13); - this.lblFpsLimit.TabIndex = 0; - this.lblFpsLimit.Text = "FPS Limit:"; + this.lblEmulationSpeed.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblEmulationSpeed.AutoSize = true; + this.lblEmulationSpeed.Location = new System.Drawing.Point(3, 6); + this.lblEmulationSpeed.Name = "lblEmulationSpeed"; + this.lblEmulationSpeed.Size = new System.Drawing.Size(90, 13); + this.lblEmulationSpeed.TabIndex = 0; + this.lblEmulationSpeed.Text = "Emulation Speed:"; // - // cboFpsLimit + // nudEmulationSpeed // - this.cboFpsLimit.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.cboFpsLimit.FormattingEnabled = true; - this.cboFpsLimit.Items.AddRange(new object[] { - "Auto", - "No Limit", - "60", - "50", - "30", - "25", - "15", - "12"}); - this.cboFpsLimit.Location = new System.Drawing.Point(63, 3); - this.cboFpsLimit.Name = "cboFpsLimit"; - this.cboFpsLimit.Size = new System.Drawing.Size(89, 21); - this.cboFpsLimit.TabIndex = 1; + this.nudEmulationSpeed.Location = new System.Drawing.Point(99, 3); + this.nudEmulationSpeed.Maximum = new decimal(new int[] { + 500, + 0, + 0, + 0}); + this.nudEmulationSpeed.Name = "nudEmulationSpeed"; + this.nudEmulationSpeed.Size = new System.Drawing.Size(48, 20); + this.nudEmulationSpeed.TabIndex = 1; + // + // lblEmuSpeedHint + // + this.lblEmuSpeedHint.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblEmuSpeedHint.AutoSize = true; + this.lblEmuSpeedHint.Location = new System.Drawing.Point(153, 6); + this.lblEmuSpeedHint.Name = "lblEmuSpeedHint"; + this.lblEmuSpeedHint.Size = new System.Drawing.Size(107, 13); + this.lblEmuSpeedHint.TabIndex = 2; + this.lblEmuSpeedHint.Text = "(0 = Maximum speed)"; // // frmVideoConfig // @@ -324,6 +331,7 @@ ((System.ComponentModel.ISupportInitialize)(this.nudOverscanRight)).EndInit(); this.flowLayoutPanel6.ResumeLayout(false); this.flowLayoutPanel6.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nudEmulationSpeed)).EndInit(); this.ResumeLayout(false); } @@ -348,7 +356,8 @@ private System.Windows.Forms.NumericUpDown nudOverscanBottom; private System.Windows.Forms.NumericUpDown nudOverscanRight; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel6; - private System.Windows.Forms.Label lblFpsLimit; - private System.Windows.Forms.ComboBox cboFpsLimit; + private System.Windows.Forms.Label lblEmulationSpeed; + private System.Windows.Forms.NumericUpDown nudEmulationSpeed; + private System.Windows.Forms.Label lblEmuSpeedHint; } } \ No newline at end of file diff --git a/GUI.NET/Forms/Config/frmVideoConfig.cs b/GUI.NET/Forms/Config/frmVideoConfig.cs index cd388dc4..f517f105 100644 --- a/GUI.NET/Forms/Config/frmVideoConfig.cs +++ b/GUI.NET/Forms/Config/frmVideoConfig.cs @@ -18,15 +18,8 @@ namespace Mesen.GUI.Forms.Config InitializeComponent(); Entity = ConfigManager.Config.VideoInfo; - - if(ConfigManager.Config.VideoInfo.FpsLimit == -1) { - cboFpsLimit.SelectedIndex = 0; - } else if(ConfigManager.Config.VideoInfo.FpsLimit == 0) { - cboFpsLimit.SelectedIndex = 1; - } else { - cboFpsLimit.SelectedIndex = cboFpsLimit.Items.IndexOf(ConfigManager.Config.VideoInfo.FpsLimit.ToString()); - } - + + AddBinding("EmulationSpeed", nudEmulationSpeed); AddBinding("ShowFPS", chkShowFps); AddBinding("OverscanLeft", nudOverscanLeft); AddBinding("OverscanRight", nudOverscanRight); @@ -34,20 +27,6 @@ namespace Mesen.GUI.Forms.Config AddBinding("OverscanBottom", nudOverscanBottom); } - protected override void UpdateConfig() - { - int fpsLimit; - if(cboFpsLimit.SelectedIndex == 0) { - fpsLimit = -1; - } else if(cboFpsLimit.SelectedIndex == 1) { - fpsLimit = 0; - } else { - fpsLimit = Int32.Parse(cboFpsLimit.SelectedItem.ToString()); - } - - ((VideoInfo)Entity).FpsLimit = fpsLimit; - } - protected override void OnFormClosed(FormClosedEventArgs e) { base.OnFormClosed(e); diff --git a/GUI.NET/Forms/frmMain.Designer.cs b/GUI.NET/Forms/frmMain.Designer.cs index 0d0ff7a9..2ab52d96 100644 --- a/GUI.NET/Forms/frmMain.Designer.cs +++ b/GUI.NET/Forms/frmMain.Designer.cs @@ -51,10 +51,16 @@ this.mnuReset = new System.Windows.Forms.ToolStripMenuItem(); this.mnuStop = new System.Windows.Forms.ToolStripMenuItem(); this.mnuOptions = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuFpsLimit = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuFpsLimitDefault = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuFpsLimitNoLimit = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuEmulationSpeed = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuEmuSpeedNormal = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem8 = new System.Windows.Forms.ToolStripSeparator(); + this.mnuIncreaseSpeed = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuDecreaseSpeed = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem9 = new System.Windows.Forms.ToolStripSeparator(); + this.mnuEmuSpeedTriple = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuEmuSpeedDouble = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuEmuSpeedHalf = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuEmuSpeedQuarter = new System.Windows.Forms.ToolStripMenuItem(); this.mnuShowFPS = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); this.mnuAudioConfig = new System.Windows.Forms.ToolStripMenuItem(); @@ -88,6 +94,7 @@ this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator(); this.mnuAbout = new System.Windows.Forms.ToolStripMenuItem(); this.dxViewer = new Mesen.GUI.Controls.DXViewer(); + this.mnuEmuSpeedMaximumSpeed = new System.Windows.Forms.ToolStripMenuItem(); this.menuStrip.SuspendLayout(); this.SuspendLayout(); // @@ -208,7 +215,7 @@ // mnuOptions // this.mnuOptions.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.mnuFpsLimit, + this.mnuEmulationSpeed, this.mnuShowFPS, this.toolStripMenuItem1, this.mnuAudioConfig, @@ -219,60 +226,110 @@ this.mnuOptions.Size = new System.Drawing.Size(61, 20); this.mnuOptions.Text = "Options"; // - // mnuFpsLimit + // mnuEmulationSpeed // - this.mnuFpsLimit.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.mnuFpsLimitNoLimit, + this.mnuEmulationSpeed.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.mnuEmuSpeedNormal, this.toolStripMenuItem8, - this.mnuFpsLimitDefault}); - this.mnuFpsLimit.Name = "mnuFpsLimit"; - this.mnuFpsLimit.Size = new System.Drawing.Size(152, 22); - this.mnuFpsLimit.Text = "FPS Limit"; + this.mnuIncreaseSpeed, + this.mnuDecreaseSpeed, + this.mnuEmuSpeedMaximumSpeed, + this.toolStripMenuItem9, + this.mnuEmuSpeedTriple, + this.mnuEmuSpeedDouble, + this.mnuEmuSpeedHalf, + this.mnuEmuSpeedQuarter}); + this.mnuEmulationSpeed.Name = "mnuEmulationSpeed"; + this.mnuEmulationSpeed.Size = new System.Drawing.Size(163, 22); + this.mnuEmulationSpeed.Text = "Emulation Speed"; // - // mnuFpsLimitDefault + // mnuEmuSpeedNormal // - this.mnuFpsLimitDefault.Name = "mnuFpsLimitDefault"; - this.mnuFpsLimitDefault.Size = new System.Drawing.Size(152, 22); - this.mnuFpsLimitDefault.Tag = ""; - this.mnuFpsLimitDefault.Text = "Auto"; - // - // mnuFpsLimitNoLimit - // - this.mnuFpsLimitNoLimit.Name = "mnuFpsLimitNoLimit"; - this.mnuFpsLimitNoLimit.ShortcutKeys = System.Windows.Forms.Keys.F9; - this.mnuFpsLimitNoLimit.Size = new System.Drawing.Size(152, 22); - this.mnuFpsLimitNoLimit.Text = "No Limit"; + this.mnuEmuSpeedNormal.Name = "mnuEmuSpeedNormal"; + this.mnuEmuSpeedNormal.Size = new System.Drawing.Size(182, 22); + this.mnuEmuSpeedNormal.Text = "Normal (100%)"; + this.mnuEmuSpeedNormal.Click += new System.EventHandler(this.mnuEmulationSpeedOption_Click); // // toolStripMenuItem8 // this.toolStripMenuItem8.Name = "toolStripMenuItem8"; - this.toolStripMenuItem8.Size = new System.Drawing.Size(149, 6); + this.toolStripMenuItem8.Size = new System.Drawing.Size(179, 6); + // + // mnuIncreaseSpeed + // + this.mnuIncreaseSpeed.Name = "mnuIncreaseSpeed"; + this.mnuIncreaseSpeed.ShortcutKeyDisplayString = "="; + this.mnuIncreaseSpeed.Size = new System.Drawing.Size(182, 22); + this.mnuIncreaseSpeed.Text = "Increase Speed"; + this.mnuIncreaseSpeed.Click += new System.EventHandler(this.mnuIncreaseSpeed_Click); + // + // mnuDecreaseSpeed + // + this.mnuDecreaseSpeed.Name = "mnuDecreaseSpeed"; + this.mnuDecreaseSpeed.ShortcutKeyDisplayString = "-"; + this.mnuDecreaseSpeed.Size = new System.Drawing.Size(182, 22); + this.mnuDecreaseSpeed.Text = "Decrease Speed"; + this.mnuDecreaseSpeed.Click += new System.EventHandler(this.mnuDecreaseSpeed_Click); + // + // toolStripMenuItem9 + // + this.toolStripMenuItem9.Name = "toolStripMenuItem9"; + this.toolStripMenuItem9.Size = new System.Drawing.Size(179, 6); + // + // mnuEmuSpeedTriple + // + this.mnuEmuSpeedTriple.Name = "mnuEmuSpeedTriple"; + this.mnuEmuSpeedTriple.Size = new System.Drawing.Size(182, 22); + this.mnuEmuSpeedTriple.Tag = ""; + this.mnuEmuSpeedTriple.Text = "Triple (300%)"; + this.mnuEmuSpeedTriple.Click += new System.EventHandler(this.mnuEmulationSpeedOption_Click); + // + // mnuEmuSpeedDouble + // + this.mnuEmuSpeedDouble.Name = "mnuEmuSpeedDouble"; + this.mnuEmuSpeedDouble.Size = new System.Drawing.Size(182, 22); + this.mnuEmuSpeedDouble.Text = "Double (200%)"; + this.mnuEmuSpeedDouble.Click += new System.EventHandler(this.mnuEmulationSpeedOption_Click); + // + // mnuEmuSpeedHalf + // + this.mnuEmuSpeedHalf.Name = "mnuEmuSpeedHalf"; + this.mnuEmuSpeedHalf.Size = new System.Drawing.Size(182, 22); + this.mnuEmuSpeedHalf.Text = "Half (50%)"; + this.mnuEmuSpeedHalf.Click += new System.EventHandler(this.mnuEmulationSpeedOption_Click); + // + // mnuEmuSpeedQuarter + // + this.mnuEmuSpeedQuarter.Name = "mnuEmuSpeedQuarter"; + this.mnuEmuSpeedQuarter.Size = new System.Drawing.Size(182, 22); + this.mnuEmuSpeedQuarter.Text = "Quarter (25%)"; + this.mnuEmuSpeedQuarter.Click += new System.EventHandler(this.mnuEmulationSpeedOption_Click); // // mnuShowFPS // this.mnuShowFPS.CheckOnClick = true; this.mnuShowFPS.Name = "mnuShowFPS"; this.mnuShowFPS.ShortcutKeys = System.Windows.Forms.Keys.F10; - this.mnuShowFPS.Size = new System.Drawing.Size(152, 22); + this.mnuShowFPS.Size = new System.Drawing.Size(163, 22); this.mnuShowFPS.Text = "Show FPS"; this.mnuShowFPS.Click += new System.EventHandler(this.mnuShowFPS_Click); // // toolStripMenuItem1 // this.toolStripMenuItem1.Name = "toolStripMenuItem1"; - this.toolStripMenuItem1.Size = new System.Drawing.Size(149, 6); + this.toolStripMenuItem1.Size = new System.Drawing.Size(160, 6); // // mnuAudioConfig // this.mnuAudioConfig.Name = "mnuAudioConfig"; - this.mnuAudioConfig.Size = new System.Drawing.Size(152, 22); + this.mnuAudioConfig.Size = new System.Drawing.Size(163, 22); this.mnuAudioConfig.Text = "Audio"; this.mnuAudioConfig.Click += new System.EventHandler(this.mnuAudioConfig_Click); // // mnuInput // this.mnuInput.Name = "mnuInput"; - this.mnuInput.Size = new System.Drawing.Size(152, 22); + this.mnuInput.Size = new System.Drawing.Size(163, 22); this.mnuInput.Text = "Input"; this.mnuInput.Click += new System.EventHandler(this.mnuInput_Click); // @@ -283,7 +340,7 @@ this.mnuRegionNtsc, this.mnuRegionPal}); this.mnuRegion.Name = "mnuRegion"; - this.mnuRegion.Size = new System.Drawing.Size(152, 22); + this.mnuRegion.Size = new System.Drawing.Size(163, 22); this.mnuRegion.Text = "Region"; // // mnuRegionAuto @@ -310,7 +367,7 @@ // mnuVideoConfig // this.mnuVideoConfig.Name = "mnuVideoConfig"; - this.mnuVideoConfig.Size = new System.Drawing.Size(152, 22); + this.mnuVideoConfig.Size = new System.Drawing.Size(163, 22); this.mnuVideoConfig.Text = "Video"; this.mnuVideoConfig.Click += new System.EventHandler(this.mnuVideoConfig_Click); // @@ -500,6 +557,14 @@ this.dxViewer.Size = new System.Drawing.Size(1024, 960); this.dxViewer.TabIndex = 1; // + // mnuEmuSpeedMaximumSpeed + // + this.mnuEmuSpeedMaximumSpeed.Name = "mnuEmuSpeedMaximumSpeed"; + this.mnuEmuSpeedMaximumSpeed.ShortcutKeys = System.Windows.Forms.Keys.F9; + this.mnuEmuSpeedMaximumSpeed.Size = new System.Drawing.Size(182, 22); + this.mnuEmuSpeedMaximumSpeed.Text = "Maximum Speed"; + this.mnuEmuSpeedMaximumSpeed.Click += new System.EventHandler(this.mnuEmuSpeedMaximumSpeed_Click); + // // frmMain // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -530,7 +595,7 @@ private System.Windows.Forms.ToolStripMenuItem mnuReset; private System.Windows.Forms.ToolStripMenuItem mnuStop; private System.Windows.Forms.ToolStripMenuItem mnuOptions; - private System.Windows.Forms.ToolStripMenuItem mnuFpsLimit; + private System.Windows.Forms.ToolStripMenuItem mnuEmulationSpeed; private System.Windows.Forms.ToolStripMenuItem mnuShowFPS; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; private System.Windows.Forms.ToolStripMenuItem mnuInput; @@ -570,9 +635,16 @@ private System.Windows.Forms.ToolStripMenuItem mnuRegionAuto; private System.Windows.Forms.ToolStripMenuItem mnuRegionNtsc; private System.Windows.Forms.ToolStripMenuItem mnuRegionPal; - private System.Windows.Forms.ToolStripMenuItem mnuFpsLimitDefault; + private System.Windows.Forms.ToolStripMenuItem mnuEmuSpeedTriple; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem8; - private System.Windows.Forms.ToolStripMenuItem mnuFpsLimitNoLimit; + private System.Windows.Forms.ToolStripMenuItem mnuEmuSpeedNormal; + private System.Windows.Forms.ToolStripMenuItem mnuIncreaseSpeed; + private System.Windows.Forms.ToolStripMenuItem mnuDecreaseSpeed; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem9; + private System.Windows.Forms.ToolStripMenuItem mnuEmuSpeedDouble; + private System.Windows.Forms.ToolStripMenuItem mnuEmuSpeedHalf; + private System.Windows.Forms.ToolStripMenuItem mnuEmuSpeedQuarter; + private System.Windows.Forms.ToolStripMenuItem mnuEmuSpeedMaximumSpeed; } } diff --git a/GUI.NET/Forms/frmMain.cs b/GUI.NET/Forms/frmMain.cs index f1c520b1..92fab55d 100644 --- a/GUI.NET/Forms/frmMain.cs +++ b/GUI.NET/Forms/frmMain.cs @@ -24,7 +24,6 @@ namespace Mesen.GUI.Forms private Thread _renderThread; private frmDebugger _debugger; private bool _stop = false; - private List _fpsLimitOptions = new List(); public frmMain() { @@ -39,10 +38,10 @@ namespace Mesen.GUI.Forms _notifListener = new InteropEmu.NotificationListener(); _notifListener.OnNotification += _notifListener_OnNotification; + InitializeEmulationSpeedMenu(); + UpdateVideoSettings(); - InitializeEmu(); - InitializeFpsLimitMenu(); UpdateMenus(); UpdateRecentFiles(); @@ -65,47 +64,77 @@ namespace Mesen.GUI.Forms UpdateEmulationFlags(); } - void InitializeFpsLimitMenu() + private void InitializeEmulationSpeedMenu() { - int[] fpsValues = new int[] { 120, 100, 60, 50 , 30, 25, 15, 12 }; - mnuFpsLimitDefault.Tag = -1; - mnuFpsLimitNoLimit.Tag = 0; - _fpsLimitOptions.Add(mnuFpsLimitDefault); - _fpsLimitOptions.Add(mnuFpsLimitNoLimit); - foreach(int fpsValue in fpsValues) { - ToolStripMenuItem item = (ToolStripMenuItem)mnuFpsLimit.DropDownItems.Add(fpsValue.ToString()); - item.Tag = fpsValue; - _fpsLimitOptions.Add(item); - } + mnuEmuSpeedNormal.Tag = 100; + mnuEmuSpeedTriple.Tag = 300; + mnuEmuSpeedDouble.Tag = 200; + mnuEmuSpeedHalf.Tag = 50; + mnuEmuSpeedQuarter.Tag = 25; + mnuEmuSpeedMaximumSpeed.Tag = 0; - foreach(ToolStripMenuItem item in _fpsLimitOptions) { - item.Click += mnuFpsLimitValue_Click; - } - - UpdateFpsLimitMenu(); + UpdateEmulationSpeedMenu(); } - void UpdateFpsLimitMenu() + private void UpdateEmulationSpeedMenu() { - foreach(ToolStripMenuItem item in _fpsLimitOptions) { - item.Checked = ((int)item.Tag == ConfigManager.Config.VideoInfo.FpsLimit); + foreach(ToolStripMenuItem item in new ToolStripMenuItem[] { mnuEmuSpeedDouble, mnuEmuSpeedHalf, mnuEmuSpeedNormal, mnuEmuSpeedQuarter, mnuEmuSpeedTriple, mnuEmuSpeedMaximumSpeed }) { + item.Checked = ((int)item.Tag == ConfigManager.Config.VideoInfo.EmulationSpeed); } } - private void mnuFpsLimitValue_Click(object sender, EventArgs e) + private void SetEmulationSpeed(uint emulationSpeed) { - int fpsLimit; - if(sender == mnuFpsLimitNoLimit) { - fpsLimit = mnuFpsLimitNoLimit.Checked ? -1 : 0; + if(emulationSpeed == 0) { + InteropEmu.DisplayMessage("Emulation Speed", "Maximum speed"); } else { - fpsLimit = (int)((ToolStripItem)sender).Tag; + InteropEmu.DisplayMessage("Emulation Speed", emulationSpeed + "%"); } - ConfigManager.Config.VideoInfo.FpsLimit = fpsLimit; + ConfigManager.Config.VideoInfo.EmulationSpeed = emulationSpeed; ConfigManager.ApplyChanges(); - UpdateFpsLimitMenu(); - + UpdateEmulationSpeedMenu(); VideoInfo.ApplyConfig(); } + + private void mnuIncreaseSpeed_Click(object sender, EventArgs e) + { + if(ConfigManager.Config.VideoInfo.EmulationSpeed > 0) { + if(ConfigManager.Config.VideoInfo.EmulationSpeed < 100) { + SetEmulationSpeed(ConfigManager.Config.VideoInfo.EmulationSpeed + 25); + } else if(ConfigManager.Config.VideoInfo.EmulationSpeed < 450) { + SetEmulationSpeed(ConfigManager.Config.VideoInfo.EmulationSpeed + 50); + } else { + SetEmulationSpeed(0); + } + } + } + + private void mnuDecreaseSpeed_Click(object sender, EventArgs e) + { + if(ConfigManager.Config.VideoInfo.EmulationSpeed == 0) { + SetEmulationSpeed(450); + } else if(ConfigManager.Config.VideoInfo.EmulationSpeed <= 100) { + if(ConfigManager.Config.VideoInfo.EmulationSpeed > 25) { + SetEmulationSpeed(ConfigManager.Config.VideoInfo.EmulationSpeed - 25); + } + } else { + SetEmulationSpeed(ConfigManager.Config.VideoInfo.EmulationSpeed - 50); + } + } + + private void mnuEmuSpeedMaximumSpeed_Click(object sender, EventArgs e) + { + if(ConfigManager.Config.VideoInfo.EmulationSpeed == 0) { + SetEmulationSpeed(100); + } else { + SetEmulationSpeed(0); + } + } + + private void mnuEmulationSpeedOption_Click(object sender, EventArgs e) + { + SetEmulationSpeed((uint)((ToolStripItem)sender).Tag); + } void UpdateEmulationFlags() { @@ -118,7 +147,7 @@ namespace Mesen.GUI.Forms void UpdateVideoSettings() { mnuShowFPS.Checked = ConfigManager.Config.VideoInfo.ShowFPS; - UpdateFpsLimitMenu(); + UpdateEmulationSpeedMenu(); dxViewer.Size = VideoInfo.GetViewerSize(); } @@ -180,7 +209,7 @@ namespace Mesen.GUI.Forms mnuConnect.Enabled = !netPlay; mnuDisconnect.Enabled = !mnuConnect.Enabled && !InteropEmu.IsServerRunning(); - mnuFpsLimit.Enabled = !InteropEmu.IsConnected(); + mnuEmulationSpeed.Enabled = !InteropEmu.IsConnected(); bool moviePlaying = InteropEmu.MoviePlaying(); bool movieRecording = InteropEmu.MovieRecording(); @@ -278,6 +307,12 @@ namespace Mesen.GUI.Forms if(keyData == Keys.Escape && _emuThread != null && mnuPause.Enabled) { PauseEmu(); return true; + } else if(keyData == Keys.Oemplus) { + mnuIncreaseSpeed.PerformClick(); + return true; + } else if(keyData == Keys.OemMinus) { + mnuDecreaseSpeed.PerformClick(); + return true; } return base.ProcessCmdKey(ref msg, keyData); } diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index 232cef0e..68037262 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -66,7 +66,7 @@ namespace Mesen.GUI [DllImport(DLLPath)] public static extern void SetChannelVolume(UInt32 channel, double volume); [DllImport(DLLPath)] public static extern void SetAudioLatency(UInt32 msLatency); [DllImport(DLLPath)] public static extern void SetNesModel(NesModel model); - [DllImport(DLLPath)] public static extern void SetFpsLimit(Int32 fpsLimit); + [DllImport(DLLPath)] public static extern void SetEmulationSpeed(UInt32 emulationSpeed); [DllImport(DLLPath)] public static extern void SetOverscanDimensions(UInt32 left, UInt32 right, UInt32 top, UInt32 bottom); [DllImport(DLLPath)] public static extern void DebugInitialize(); diff --git a/InteropDLL/ConsoleWrapper.cpp b/InteropDLL/ConsoleWrapper.cpp index a9f1eb90..e59fcc8b 100644 --- a/InteropDLL/ConsoleWrapper.cpp +++ b/InteropDLL/ConsoleWrapper.cpp @@ -167,7 +167,7 @@ namespace InteropEmu { DllExport void __stdcall SetAudioLatency(uint32_t msLatency) { EmulationSettings::SetAudioLatency(msLatency); } DllExport void __stdcall SetNesModel(uint32_t model) { EmulationSettings::SetNesModel((NesModel)model); } DllExport void __stdcall SetOverscanDimensions(uint32_t left, uint32_t right, uint32_t top, uint32_t bottom) { EmulationSettings::SetOverscanDimensions(left, right, top, bottom); } - DllExport void __stdcall SetFpsLimit(int32_t fpsLimit) { EmulationSettings::SetFpsLimit(fpsLimit); } + DllExport void __stdcall SetEmulationSpeed(uint32_t emulationSpeed) { EmulationSettings::SetEmulationSpeed(emulationSpeed); } } } \ No newline at end of file diff --git a/Windows/SoundManager.cpp b/Windows/SoundManager.cpp index 613c13e5..c3d9db32 100644 --- a/Windows/SoundManager.cpp +++ b/Windows/SoundManager.cpp @@ -153,22 +153,22 @@ void SoundManager::Pause() _secondaryBuffer->Stop(); } -void SoundManager::Play() -{ - _secondaryBuffer->Play(0, 0, DSBPLAY_LOOPING); -} - -void SoundManager::Reset() +void SoundManager::Stop() { _secondaryBuffer->Stop(); ClearSecondaryBuffer(); } +void SoundManager::Play() +{ + _secondaryBuffer->Play(0, 0, DSBPLAY_LOOPING); +} + void SoundManager::PlayBuffer(int16_t *soundBuffer, uint32_t soundBufferSize) { int32_t byteLatency = (int32_t)((float)(APU::SampleRate * EmulationSettings::GetAudioLatency()) / 1000.0f * (APU::BitsPerSample / 8)); if(byteLatency != _previousLatency) { - Reset(); + Stop(); _previousLatency = byteLatency; } DWORD status; diff --git a/Windows/SoundManager.h b/Windows/SoundManager.h index e636db79..fb495a3a 100644 --- a/Windows/SoundManager.h +++ b/Windows/SoundManager.h @@ -13,7 +13,7 @@ public: void PlayBuffer(int16_t *soundBuffer, uint32_t bufferSize); void Play(); void Pause(); - void Reset(); + void Stop(); private: bool InitializeDirectSound(HWND);