diff --git a/Core/Console.cpp b/Core/Console.cpp index 4e38ce0d..f116e210 100644 --- a/Core/Console.cpp +++ b/Core/Console.cpp @@ -187,7 +187,7 @@ void Console::Run() if(currentFrameNumber != lastFrameNumber) { lastFrameNumber = currentFrameNumber; - if(EmulationSettings::CheckFlag(EmulationFlags::LimitFPS)) { + if(targetTime > 0) { elapsedTime = clockTimer.GetElapsedMS(); while(targetTime > elapsedTime) { if(targetTime - elapsedTime > 1) { @@ -239,10 +239,22 @@ void Console::Run() void Console::UpdateNesModel(double &frameDelay, bool showMessage) { NesModel model = EmulationSettings::GetNesModel(); + int32_t fpsLimit = EmulationSettings::GetFpsLimit(); if(model == NesModel::Auto) { model = _mapper->IsPalRom() ? NesModel::PAL : NesModel::NTSC; } - frameDelay = (model == NesModel::NTSC ? 16.63926405550947 : 19.99720920217466); //60.1fps (NTSC), 50.01fps (PAL) + + 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) { + frameDelay = 0; + } else { + frameDelay = 1000.0 / fpsLimit; + } _ppu->SetNesModel(model); _apu->SetNesModel(model); } diff --git a/Core/EmulationSettings.cpp b/Core/EmulationSettings.cpp index 6f7e9520..7b2005ba 100644 --- a/Core/EmulationSettings.cpp +++ b/Core/EmulationSettings.cpp @@ -4,5 +4,6 @@ uint32_t EmulationSettings::Flags = 0; uint32_t EmulationSettings::AudioLatency = 20000; double EmulationSettings::ChannelVolume[5] = { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f }; -NesModel EmulationSettings::Model; -OverscanDimensions EmulationSettings::Overscan; \ No newline at end of file +NesModel EmulationSettings::Model = NesModel::Auto; +OverscanDimensions EmulationSettings::Overscan; +int32_t EmulationSettings::FpsLimit = -1; \ No newline at end of file diff --git a/Core/EmulationSettings.h b/Core/EmulationSettings.h index 03921515..c8ad3769 100644 --- a/Core/EmulationSettings.h +++ b/Core/EmulationSettings.h @@ -5,8 +5,7 @@ enum EmulationFlags { Paused = 0x01, - LimitFPS = 0x02, - ShowFPS = 0x04, + ShowFPS = 0x02, }; enum class AudioChannel @@ -55,6 +54,7 @@ private: static uint32_t AudioLatency; static double ChannelVolume[5]; static NesModel Model; + static int32_t FpsLimit; static OverscanDimensions Overscan; public: @@ -94,6 +94,17 @@ public: AudioLatency = msLatency; } + //-1: Auto, 0: No limit, Number: Specific FPS + static void SetFpsLimit(int32_t fpsLimit) + { + FpsLimit = fpsLimit; + } + + static int32_t GetFpsLimit() + { + return FpsLimit; + } + static void SetOverscanDimensions(uint8_t left, uint8_t right, uint8_t top, uint8_t bottom) { Overscan.Left = left; diff --git a/Core/GameClientConnection.cpp b/Core/GameClientConnection.cpp index fc12f674..7d738d39 100644 --- a/Core/GameClientConnection.cpp +++ b/Core/GameClientConnection.cpp @@ -96,9 +96,11 @@ void GameClientConnection::ProcessMessage(NetMessage* message) void GameClientConnection::SendInput() { - uint8_t inputState = _controlDevice->GetButtonState().ToByte(); - if(_lastInputSent != inputState) { - SendNetMessage(InputDataMessage(inputState)); - _lastInputSent = inputState; + if(_gameLoaded) { + uint8_t inputState = _controlDevice->GetButtonState().ToByte(); + if(_lastInputSent != inputState) { + SendNetMessage(InputDataMessage(inputState)); + _lastInputSent = inputState; + } } } \ No newline at end of file diff --git a/Core/VirtualController.cpp b/Core/VirtualController.cpp index 8b56ec69..8dbefb5a 100644 --- a/Core/VirtualController.cpp +++ b/Core/VirtualController.cpp @@ -45,9 +45,9 @@ ButtonState VirtualController::GetButtonState() _queueSize--; if(_queueSize.load() > _minimumBuffer) { - EmulationSettings::ClearFlags(EmulationFlags::LimitFPS); + EmulationSettings::SetFpsLimit(0); } else { - EmulationSettings::SetFlags(EmulationFlags::LimitFPS); + EmulationSettings::SetFpsLimit(-1); } _writeLock.Release(); diff --git a/GUI.NET/Config/VideoInfo.cs b/GUI.NET/Config/VideoInfo.cs index 69acd598..e8e07535 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 bool LimitFPS = true; + public Int32 FpsLimit = -1; public bool ShowFPS = false; public UInt32 OverscanLeft = 0; public UInt32 OverscanRight = 0; @@ -25,11 +25,8 @@ namespace Mesen.GUI.Config static public void ApplyConfig() { VideoInfo videoInfo = ConfigManager.Config.VideoInfo; - if(ConfigManager.Config.VideoInfo.LimitFPS) { - InteropEmu.SetFlags((UInt32)EmulationFlags.LimitFPS); - } else { - InteropEmu.ClearFlags((UInt32)EmulationFlags.LimitFPS); - } + + InteropEmu.SetFpsLimit(videoInfo.FpsLimit); 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 e64f7c38..35dc12cb 100644 --- a/GUI.NET/Forms/Config/frmVideoConfig.Designer.cs +++ b/GUI.NET/Forms/Config/frmVideoConfig.Designer.cs @@ -33,30 +33,33 @@ this.picOverscan = new System.Windows.Forms.PictureBox(); this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel(); this.lblLeft = new System.Windows.Forms.Label(); + this.nudOverscanLeft = new System.Windows.Forms.NumericUpDown(); this.flowLayoutPanel4 = new System.Windows.Forms.FlowLayoutPanel(); this.lblTop = new System.Windows.Forms.Label(); + this.nudOverscanTop = new System.Windows.Forms.NumericUpDown(); this.flowLayoutPanel5 = new System.Windows.Forms.FlowLayoutPanel(); this.lblBottom = new System.Windows.Forms.Label(); + this.nudOverscanBottom = new System.Windows.Forms.NumericUpDown(); this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); this.lblRight = new System.Windows.Forms.Label(); - this.chkLimitFps = new System.Windows.Forms.CheckBox(); - this.chkShowFps = new System.Windows.Forms.CheckBox(); this.nudOverscanRight = new System.Windows.Forms.NumericUpDown(); - this.nudOverscanBottom = new System.Windows.Forms.NumericUpDown(); - this.nudOverscanLeft = new System.Windows.Forms.NumericUpDown(); - this.nudOverscanTop = 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.tlpMain.SuspendLayout(); this.grpCropping.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.picOverscan)).BeginInit(); this.flowLayoutPanel3.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nudOverscanLeft)).BeginInit(); this.flowLayoutPanel4.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nudOverscanTop)).BeginInit(); this.flowLayoutPanel5.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nudOverscanBottom)).BeginInit(); this.flowLayoutPanel2.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.nudOverscanRight)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.nudOverscanBottom)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.nudOverscanLeft)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.nudOverscanTop)).BeginInit(); + this.flowLayoutPanel6.SuspendLayout(); this.SuspendLayout(); // // baseConfigPanel @@ -69,8 +72,8 @@ this.tlpMain.ColumnCount = 1; this.tlpMain.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tlpMain.Controls.Add(this.grpCropping, 0, 2); - this.tlpMain.Controls.Add(this.chkLimitFps, 0, 0); this.tlpMain.Controls.Add(this.chkShowFps, 0, 1); + this.tlpMain.Controls.Add(this.flowLayoutPanel6, 0, 0); this.tlpMain.Dock = System.Windows.Forms.DockStyle.Fill; this.tlpMain.Location = new System.Drawing.Point(0, 0); this.tlpMain.Name = "tlpMain"; @@ -78,7 +81,6 @@ this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); this.tlpMain.Size = new System.Drawing.Size(362, 308); this.tlpMain.TabIndex = 1; // @@ -86,9 +88,9 @@ // this.grpCropping.Controls.Add(this.tableLayoutPanel1); this.grpCropping.Dock = System.Windows.Forms.DockStyle.Fill; - this.grpCropping.Location = new System.Drawing.Point(3, 49); + this.grpCropping.Location = new System.Drawing.Point(3, 53); this.grpCropping.Name = "grpCropping"; - this.grpCropping.Size = new System.Drawing.Size(356, 256); + this.grpCropping.Size = new System.Drawing.Size(356, 252); this.grpCropping.TabIndex = 7; this.grpCropping.TabStop = false; this.grpCropping.Text = "Video Cropping"; @@ -145,6 +147,13 @@ this.lblLeft.Text = "Left"; this.lblLeft.TextAlign = System.Drawing.ContentAlignment.TopCenter; // + // nudOverscanLeft + // + this.nudOverscanLeft.Location = new System.Drawing.Point(3, 16); + this.nudOverscanLeft.Name = "nudOverscanLeft"; + this.nudOverscanLeft.Size = new System.Drawing.Size(50, 20); + this.nudOverscanLeft.TabIndex = 2; + // // flowLayoutPanel4 // this.flowLayoutPanel4.Anchor = System.Windows.Forms.AnchorStyles.None; @@ -168,6 +177,13 @@ this.lblTop.Text = "Top"; this.lblTop.TextAlign = System.Drawing.ContentAlignment.TopCenter; // + // nudOverscanTop + // + this.nudOverscanTop.Location = new System.Drawing.Point(3, 16); + this.nudOverscanTop.Name = "nudOverscanTop"; + this.nudOverscanTop.Size = new System.Drawing.Size(50, 20); + this.nudOverscanTop.TabIndex = 2; + // // flowLayoutPanel5 // this.flowLayoutPanel5.Anchor = System.Windows.Forms.AnchorStyles.None; @@ -191,6 +207,13 @@ this.lblBottom.Text = "Bottom"; this.lblBottom.TextAlign = System.Drawing.ContentAlignment.TopCenter; // + // nudOverscanBottom + // + this.nudOverscanBottom.Location = new System.Drawing.Point(3, 16); + this.nudOverscanBottom.Name = "nudOverscanBottom"; + this.nudOverscanBottom.Size = new System.Drawing.Size(50, 20); + this.nudOverscanBottom.TabIndex = 2; + // // flowLayoutPanel2 // this.flowLayoutPanel2.Anchor = System.Windows.Forms.AnchorStyles.Left; @@ -214,53 +237,62 @@ this.lblRight.Text = "Right"; this.lblRight.TextAlign = System.Drawing.ContentAlignment.TopCenter; // - // chkLimitFps + // nudOverscanRight // - this.chkLimitFps.AutoSize = true; - this.chkLimitFps.Location = new System.Drawing.Point(3, 3); - this.chkLimitFps.Name = "chkLimitFps"; - this.chkLimitFps.Size = new System.Drawing.Size(70, 17); - this.chkLimitFps.TabIndex = 8; - this.chkLimitFps.Text = "Limit FPS"; - this.chkLimitFps.UseVisualStyleBackColor = true; + this.nudOverscanRight.Location = new System.Drawing.Point(3, 16); + this.nudOverscanRight.Name = "nudOverscanRight"; + this.nudOverscanRight.Size = new System.Drawing.Size(50, 20); + this.nudOverscanRight.TabIndex = 1; // // chkShowFps // this.chkShowFps.AutoSize = true; - this.chkShowFps.Location = new System.Drawing.Point(3, 26); + this.chkShowFps.Location = new System.Drawing.Point(3, 30); this.chkShowFps.Name = "chkShowFps"; this.chkShowFps.Size = new System.Drawing.Size(76, 17); this.chkShowFps.TabIndex = 9; this.chkShowFps.Text = "Show FPS"; this.chkShowFps.UseVisualStyleBackColor = true; // - // nudRight + // flowLayoutPanel6 // - this.nudOverscanRight.Location = new System.Drawing.Point(3, 16); - this.nudOverscanRight.Name = "nudRight"; - this.nudOverscanRight.Size = new System.Drawing.Size(50, 20); - this.nudOverscanRight.TabIndex = 1; + this.flowLayoutPanel6.AutoSize = true; + this.flowLayoutPanel6.Controls.Add(this.lblFpsLimit); + this.flowLayoutPanel6.Controls.Add(this.cboFpsLimit); + 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.TabIndex = 10; // - // nudBottom + // lblFpsLimit // - this.nudOverscanBottom.Location = new System.Drawing.Point(3, 16); - this.nudOverscanBottom.Name = "nudBottom"; - this.nudOverscanBottom.Size = new System.Drawing.Size(50, 20); - this.nudOverscanBottom.TabIndex = 2; + 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:"; // - // nudLeft + // cboFpsLimit // - this.nudOverscanLeft.Location = new System.Drawing.Point(3, 16); - this.nudOverscanLeft.Name = "nudLeft"; - this.nudOverscanLeft.Size = new System.Drawing.Size(50, 20); - this.nudOverscanLeft.TabIndex = 2; - // - // nudTop - // - this.nudOverscanTop.Location = new System.Drawing.Point(3, 16); - this.nudOverscanTop.Name = "nudTop"; - this.nudOverscanTop.Size = new System.Drawing.Size(50, 20); - this.nudOverscanTop.TabIndex = 2; + 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; // // frmVideoConfig // @@ -269,6 +301,7 @@ this.ClientSize = new System.Drawing.Size(362, 337); this.Controls.Add(this.tlpMain); this.Name = "frmVideoConfig"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Video Options"; this.Controls.SetChildIndex(this.baseConfigPanel, 0); this.Controls.SetChildIndex(this.tlpMain, 0); @@ -279,16 +312,18 @@ ((System.ComponentModel.ISupportInitialize)(this.picOverscan)).EndInit(); this.flowLayoutPanel3.ResumeLayout(false); this.flowLayoutPanel3.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nudOverscanLeft)).EndInit(); this.flowLayoutPanel4.ResumeLayout(false); this.flowLayoutPanel4.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nudOverscanTop)).EndInit(); this.flowLayoutPanel5.ResumeLayout(false); this.flowLayoutPanel5.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)(this.nudOverscanBottom)).EndInit(); this.flowLayoutPanel2.ResumeLayout(false); this.flowLayoutPanel2.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.nudOverscanRight)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.nudOverscanBottom)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.nudOverscanLeft)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.nudOverscanTop)).EndInit(); + this.flowLayoutPanel6.ResumeLayout(false); + this.flowLayoutPanel6.PerformLayout(); this.ResumeLayout(false); } @@ -297,7 +332,6 @@ private System.Windows.Forms.TableLayoutPanel tlpMain; private System.Windows.Forms.GroupBox grpCropping; - private System.Windows.Forms.CheckBox chkLimitFps; private System.Windows.Forms.CheckBox chkShowFps; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel3; @@ -313,5 +347,8 @@ private System.Windows.Forms.NumericUpDown nudOverscanTop; 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; } } \ No newline at end of file diff --git a/GUI.NET/Forms/Config/frmVideoConfig.cs b/GUI.NET/Forms/Config/frmVideoConfig.cs index 3ba7684a..cd388dc4 100644 --- a/GUI.NET/Forms/Config/frmVideoConfig.cs +++ b/GUI.NET/Forms/Config/frmVideoConfig.cs @@ -19,14 +19,35 @@ namespace Mesen.GUI.Forms.Config 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("ShowFPS", chkShowFps); - AddBinding("LimitFPS", chkLimitFps); AddBinding("OverscanLeft", nudOverscanLeft); AddBinding("OverscanRight", nudOverscanRight); AddBinding("OverscanTop", nudOverscanTop); 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 f5e8f2f5..0d0ff7a9 100644 --- a/GUI.NET/Forms/frmMain.Designer.cs +++ b/GUI.NET/Forms/frmMain.Designer.cs @@ -51,7 +51,10 @@ this.mnuReset = new System.Windows.Forms.ToolStripMenuItem(); this.mnuStop = new System.Windows.Forms.ToolStripMenuItem(); this.mnuOptions = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuLimitFPS = 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.toolStripMenuItem8 = new System.Windows.Forms.ToolStripSeparator(); this.mnuShowFPS = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); this.mnuAudioConfig = new System.Windows.Forms.ToolStripMenuItem(); @@ -205,7 +208,7 @@ // mnuOptions // this.mnuOptions.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.mnuLimitFPS, + this.mnuFpsLimit, this.mnuShowFPS, this.toolStripMenuItem1, this.mnuAudioConfig, @@ -216,40 +219,60 @@ this.mnuOptions.Size = new System.Drawing.Size(61, 20); this.mnuOptions.Text = "Options"; // - // mnuLimitFPS + // mnuFpsLimit // - this.mnuLimitFPS.CheckOnClick = true; - this.mnuLimitFPS.Name = "mnuLimitFPS"; - this.mnuLimitFPS.ShortcutKeys = System.Windows.Forms.Keys.F9; - this.mnuLimitFPS.Size = new System.Drawing.Size(150, 22); - this.mnuLimitFPS.Text = "Limit FPS"; - this.mnuLimitFPS.Click += new System.EventHandler(this.mnuLimitFPS_Click); + this.mnuFpsLimit.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.mnuFpsLimitNoLimit, + this.toolStripMenuItem8, + this.mnuFpsLimitDefault}); + this.mnuFpsLimit.Name = "mnuFpsLimit"; + this.mnuFpsLimit.Size = new System.Drawing.Size(152, 22); + this.mnuFpsLimit.Text = "FPS Limit"; + // + // mnuFpsLimitDefault + // + 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"; + // + // toolStripMenuItem8 + // + this.toolStripMenuItem8.Name = "toolStripMenuItem8"; + this.toolStripMenuItem8.Size = new System.Drawing.Size(149, 6); // // mnuShowFPS // this.mnuShowFPS.CheckOnClick = true; this.mnuShowFPS.Name = "mnuShowFPS"; this.mnuShowFPS.ShortcutKeys = System.Windows.Forms.Keys.F10; - this.mnuShowFPS.Size = new System.Drawing.Size(150, 22); + this.mnuShowFPS.Size = new System.Drawing.Size(152, 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(147, 6); + this.toolStripMenuItem1.Size = new System.Drawing.Size(149, 6); // // mnuAudioConfig // this.mnuAudioConfig.Name = "mnuAudioConfig"; - this.mnuAudioConfig.Size = new System.Drawing.Size(150, 22); + this.mnuAudioConfig.Size = new System.Drawing.Size(152, 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(150, 22); + this.mnuInput.Size = new System.Drawing.Size(152, 22); this.mnuInput.Text = "Input"; this.mnuInput.Click += new System.EventHandler(this.mnuInput_Click); // @@ -260,7 +283,7 @@ this.mnuRegionNtsc, this.mnuRegionPal}); this.mnuRegion.Name = "mnuRegion"; - this.mnuRegion.Size = new System.Drawing.Size(150, 22); + this.mnuRegion.Size = new System.Drawing.Size(152, 22); this.mnuRegion.Text = "Region"; // // mnuRegionAuto @@ -287,7 +310,7 @@ // mnuVideoConfig // this.mnuVideoConfig.Name = "mnuVideoConfig"; - this.mnuVideoConfig.Size = new System.Drawing.Size(150, 22); + this.mnuVideoConfig.Size = new System.Drawing.Size(152, 22); this.mnuVideoConfig.Text = "Video"; this.mnuVideoConfig.Click += new System.EventHandler(this.mnuVideoConfig_Click); // @@ -507,7 +530,7 @@ private System.Windows.Forms.ToolStripMenuItem mnuReset; private System.Windows.Forms.ToolStripMenuItem mnuStop; private System.Windows.Forms.ToolStripMenuItem mnuOptions; - private System.Windows.Forms.ToolStripMenuItem mnuLimitFPS; + private System.Windows.Forms.ToolStripMenuItem mnuFpsLimit; private System.Windows.Forms.ToolStripMenuItem mnuShowFPS; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; private System.Windows.Forms.ToolStripMenuItem mnuInput; @@ -547,6 +570,9 @@ 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.ToolStripSeparator toolStripMenuItem8; + private System.Windows.Forms.ToolStripMenuItem mnuFpsLimitNoLimit; } } diff --git a/GUI.NET/Forms/frmMain.cs b/GUI.NET/Forms/frmMain.cs index fdd723f6..f1c520b1 100644 --- a/GUI.NET/Forms/frmMain.cs +++ b/GUI.NET/Forms/frmMain.cs @@ -24,6 +24,7 @@ namespace Mesen.GUI.Forms private Thread _renderThread; private frmDebugger _debugger; private bool _stop = false; + private List _fpsLimitOptions = new List(); public frmMain() { @@ -41,6 +42,7 @@ namespace Mesen.GUI.Forms UpdateVideoSettings(); InitializeEmu(); + InitializeFpsLimitMenu(); UpdateMenus(); UpdateRecentFiles(); @@ -62,10 +64,51 @@ namespace Mesen.GUI.Forms UpdateEmulationFlags(); } + + void InitializeFpsLimitMenu() + { + 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); + } + + foreach(ToolStripMenuItem item in _fpsLimitOptions) { + item.Click += mnuFpsLimitValue_Click; + } + + UpdateFpsLimitMenu(); + } + + void UpdateFpsLimitMenu() + { + foreach(ToolStripMenuItem item in _fpsLimitOptions) { + item.Checked = ((int)item.Tag == ConfigManager.Config.VideoInfo.FpsLimit); + } + } + + private void mnuFpsLimitValue_Click(object sender, EventArgs e) + { + int fpsLimit; + if(sender == mnuFpsLimitNoLimit) { + fpsLimit = mnuFpsLimitNoLimit.Checked ? -1 : 0; + } else { + fpsLimit = (int)((ToolStripItem)sender).Tag; + } + ConfigManager.Config.VideoInfo.FpsLimit = fpsLimit; + ConfigManager.ApplyChanges(); + UpdateFpsLimitMenu(); + + VideoInfo.ApplyConfig(); + } void UpdateEmulationFlags() { - ConfigManager.Config.VideoInfo.LimitFPS = mnuLimitFPS.Checked; ConfigManager.Config.VideoInfo.ShowFPS = mnuShowFPS.Checked; ConfigManager.ApplyChanges(); @@ -75,7 +118,7 @@ namespace Mesen.GUI.Forms void UpdateVideoSettings() { mnuShowFPS.Checked = ConfigManager.Config.VideoInfo.ShowFPS; - mnuLimitFPS.Checked = ConfigManager.Config.VideoInfo.LimitFPS; + UpdateFpsLimitMenu(); dxViewer.Size = VideoInfo.GetViewerSize(); } @@ -87,7 +130,6 @@ namespace Mesen.GUI.Forms void _notifListener_OnNotification(InteropEmu.NotificationEventArgs e) { if(e.NotificationType == InteropEmu.ConsoleNotificationType.GameLoaded) { - this.Text = "Mesen - " + System.IO.Path.GetFileNameWithoutExtension(InteropEmu.GetROMPath()); CheatInfo.ApplyCheats(); InitializeStateMenu(mnuSaveState, true); InitializeStateMenu(mnuLoadState, false); @@ -120,6 +162,13 @@ namespace Mesen.GUI.Forms if(this.InvokeRequired) { this.BeginInvoke((MethodInvoker)(() => this.UpdateMenus())); } else { + string romFilename = System.IO.Path.GetFileNameWithoutExtension(InteropEmu.GetROMPath()); + if(string.IsNullOrWhiteSpace(romFilename)) { + this.Text = "Mesen"; + } else { + this.Text = "Mesen - " + romFilename; + } + mnuSaveState.Enabled = mnuLoadState.Enabled = mnuPause.Enabled = mnuStop.Enabled = mnuReset.Enabled = (_emuThread != null && !InteropEmu.IsConnected()); mnuPause.Text = InteropEmu.IsPaused() ? "Resume" : "Pause"; @@ -131,6 +180,8 @@ namespace Mesen.GUI.Forms mnuConnect.Enabled = !netPlay; mnuDisconnect.Enabled = !mnuConnect.Enabled && !InteropEmu.IsServerRunning(); + mnuFpsLimit.Enabled = !InteropEmu.IsConnected(); + bool moviePlaying = InteropEmu.MoviePlaying(); bool movieRecording = InteropEmu.MovieRecording(); mnuPlayMovie.Enabled = !netPlay && !moviePlaying && !movieRecording; @@ -234,29 +285,33 @@ namespace Mesen.GUI.Forms const int NumberOfSaveSlots = 5; private void InitializeStateMenu(ToolStripMenuItem menu, bool forSave) { - menu.DropDownItems.Clear(); - for(uint i = 1; i <= frmMain.NumberOfSaveSlots; i++) { - Int64 fileTime = InteropEmu.GetStateInfo(i); - string label; - if(fileTime == 0) { - label = i.ToString() + ". "; - } else { - DateTime dateTime = DateTime.FromFileTime(fileTime); - label = i.ToString() + ". " + dateTime.ToShortDateString() + " " + dateTime.ToShortTimeString(); - } - - ToolStripMenuItem item = (ToolStripMenuItem)menu.DropDownItems.Add(label); - uint stateIndex = i; - item.Click += (object sender, EventArgs e) => { - if(forSave) { - InteropEmu.SaveState(stateIndex); + if(this.InvokeRequired) { + this.BeginInvoke((MethodInvoker)(() => this.InitializeStateMenu(menu, forSave))); + } else { + menu.DropDownItems.Clear(); + for(uint i = 1; i <= frmMain.NumberOfSaveSlots; i++) { + Int64 fileTime = InteropEmu.GetStateInfo(i); + string label; + if(fileTime == 0) { + label = i.ToString() + ". "; } else { - InteropEmu.LoadState(stateIndex); + DateTime dateTime = DateTime.FromFileTime(fileTime); + label = i.ToString() + ". " + dateTime.ToShortDateString() + " " + dateTime.ToShortTimeString(); + } + + ToolStripMenuItem item = (ToolStripMenuItem)menu.DropDownItems.Add(label); + uint stateIndex = i; + item.Click += (object sender, EventArgs e) => { + if(forSave) { + InteropEmu.SaveState(stateIndex); + } else { + InteropEmu.LoadState(stateIndex); + } + }; + item.ShortcutKeys = (Keys)((int)Keys.F1 + i - 1); + if(forSave) { + item.ShortcutKeys |= Keys.Shift; } - }; - item.ShortcutKeys = (Keys)((int)Keys.F1 + i - 1); - if(forSave) { - item.ShortcutKeys |= Keys.Shift; } } } @@ -278,11 +333,6 @@ namespace Mesen.GUI.Forms InteropEmu.Stop(); } - private void mnuLimitFPS_Click(object sender, EventArgs e) - { - UpdateEmulationFlags(); - } - private void mnuShowFPS_Click(object sender, EventArgs e) { UpdateEmulationFlags(); diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index 7b32e757..232cef0e 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -66,6 +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 SetOverscanDimensions(UInt32 left, UInt32 right, UInt32 top, UInt32 bottom); [DllImport(DLLPath)] public static extern void DebugInitialize(); @@ -382,8 +383,7 @@ namespace Mesen.GUI public enum EmulationFlags { Paused = 0x01, - LimitFPS = 0x02, - ShowFPS = 0x04, + ShowFPS = 0x02, } public enum BreakpointType diff --git a/InteropDLL/ConsoleWrapper.cpp b/InteropDLL/ConsoleWrapper.cpp index 0688a541..a9f1eb90 100644 --- a/InteropDLL/ConsoleWrapper.cpp +++ b/InteropDLL/ConsoleWrapper.cpp @@ -167,6 +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); } } } \ No newline at end of file