From a399dbe91e3c5be4b0e80b2bb2f379f648479906 Mon Sep 17 00:00:00 2001 From: goyuken Date: Wed, 1 Jan 2014 03:03:10 +0000 Subject: [PATCH] NES: Move boardproperties into movie 2.0 syncsettings objects, and add a rudimentary UI for changing them --- BizHawk.Client.Common/RomLoader.cs | 2 +- .../BizHawk.Client.EmuHawk.csproj | 10 ++ BizHawk.Client.EmuHawk/MainForm.Designer.cs | 14 +- BizHawk.Client.EmuHawk/MainForm.Events.cs | 48 ++++--- BizHawk.Client.EmuHawk/MainForm.Movie.cs | 6 + BizHawk.Client.EmuHawk/MainForm.cs | 40 +++--- .../config/NES/DataTableDictionaryBind.cs | 63 +++++++++ .../NES/NESSyncSettingsForm.Designer.cs | 122 ++++++++++++++++++ .../config/NES/NESSyncSettingsForm.cs | 44 +++++++ .../config/NES/NESSyncSettingsForm.resx | 120 +++++++++++++++++ BizHawk.Common/Util.cs | 42 +++++- .../Consoles/Nintendo/NES/BoardSystem.cs | 13 +- .../Nintendo/NES/Boards/MLT-ACTION52.cs | 4 +- .../Consoles/Nintendo/NES/FDS/FDS.cs | 17 --- .../Consoles/Nintendo/NES/NES.cs | 73 +++++------ 15 files changed, 508 insertions(+), 110 deletions(-) create mode 100644 BizHawk.Client.EmuHawk/config/NES/DataTableDictionaryBind.cs create mode 100644 BizHawk.Client.EmuHawk/config/NES/NESSyncSettingsForm.Designer.cs create mode 100644 BizHawk.Client.EmuHawk/config/NES/NESSyncSettingsForm.cs create mode 100644 BizHawk.Client.EmuHawk/config/NES/NESSyncSettingsForm.resx diff --git a/BizHawk.Client.Common/RomLoader.cs b/BizHawk.Client.Common/RomLoader.cs index ec87134041..e35a88d466 100644 --- a/BizHawk.Client.Common/RomLoader.cs +++ b/BizHawk.Client.Common/RomLoader.cs @@ -380,7 +380,7 @@ namespace BizHawk.Client.Common game, rom.FileData, GetCoreSettings(), - Global.MovieSession.Movie.Header.BoardProperties); + GetCoreSyncSettings()); break; case "GB": case "GBC": diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index 235697ded3..284e1c9fe1 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -266,6 +266,7 @@ N64VideoPluginconfig.cs + Form @@ -278,6 +279,12 @@ NESSoundConfig.cs + + Form + + + NESSyncSettingsForm.cs + Form @@ -887,6 +894,9 @@ NESSoundConfig.cs + + NESSyncSettingsForm.cs + PathConfig.cs diff --git a/BizHawk.Client.EmuHawk/MainForm.Designer.cs b/BizHawk.Client.EmuHawk/MainForm.Designer.cs index 787bff434f..16cb4bde69 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Designer.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Designer.cs @@ -346,6 +346,7 @@ this.ClearSRAMContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ShowMenuContextMenuSeparator = new System.Windows.Forms.ToolStripSeparator(); this.ShowMenuContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.moiveSettingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.MainformMenu.SuspendLayout(); this.MainStatusBar.SuspendLayout(); this.MainFormContextMenu.SuspendLayout(); @@ -1958,7 +1959,8 @@ this.toolStripSeparator17, this.NESGraphicSettingsMenuItem, this.NESSoundChannelsMenuItem, - this.FDSControlsMenuItem}); + this.FDSControlsMenuItem, + this.moiveSettingsToolStripMenuItem}); this.NESSubMenu.Name = "NESSubMenu"; this.NESSubMenu.Size = new System.Drawing.Size(38, 17); this.NESSubMenu.Text = "&NES"; @@ -2212,7 +2214,7 @@ // AtariSettingsToolStripMenuItem // this.AtariSettingsToolStripMenuItem.Name = "AtariSettingsToolStripMenuItem"; - this.AtariSettingsToolStripMenuItem.Size = new System.Drawing.Size(152, 22); + this.AtariSettingsToolStripMenuItem.Size = new System.Drawing.Size(125, 22); this.AtariSettingsToolStripMenuItem.Text = "Settings..."; this.AtariSettingsToolStripMenuItem.Click += new System.EventHandler(this.AtariSettingsToolStripMenuItem_Click); // @@ -3019,6 +3021,13 @@ this.ShowMenuContextMenuItem.Text = "Show Menu"; this.ShowMenuContextMenuItem.Click += new System.EventHandler(this.ShowMenuContextMenuItem_Click); // + // moiveSettingsToolStripMenuItem + // + this.moiveSettingsToolStripMenuItem.Name = "moiveSettingsToolStripMenuItem"; + this.moiveSettingsToolStripMenuItem.Size = new System.Drawing.Size(217, 22); + this.moiveSettingsToolStripMenuItem.Text = "Moive Settings..."; + this.moiveSettingsToolStripMenuItem.Click += new System.EventHandler(this.moiveSettingsToolStripMenuItem_Click); + // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 14F); @@ -3376,6 +3385,7 @@ private System.Windows.Forms.ToolStripMenuItem GenesisSubMenu; private System.Windows.Forms.ToolStripMenuItem GenesisSettingsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem AtariSettingsToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem moiveSettingsToolStripMenuItem; } } diff --git a/BizHawk.Client.EmuHawk/MainForm.Events.cs b/BizHawk.Client.EmuHawk/MainForm.Events.cs index c4ce98fbcc..a800c4802b 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Events.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Events.cs @@ -69,13 +69,13 @@ namespace BizHawk.Client.EmuHawk SaveState3MenuItem.Font.Size, _stateSlots.HasSlot(3) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular ); - + SaveState4MenuItem.Font = new Font( SaveState4MenuItem.Font.FontFamily, SaveState4MenuItem.Font.Size, _stateSlots.HasSlot(4) ? (FontStyle.Italic | FontStyle.Bold) : FontStyle.Regular ); - + SaveState5MenuItem.Font = new Font( SaveState5MenuItem.Font.FontFamily, SaveState5MenuItem.Font.Size, @@ -580,7 +580,7 @@ namespace BizHawk.Client.EmuHawk x2SAIMenuItem.Checked = Global.Config.TargetDisplayFilter == 1; SuperX2SAIMenuItem.Checked = Global.Config.TargetDisplayFilter == 2; SuperEagleMenuItem.Checked = Global.Config.TargetDisplayFilter == 3; - scanlines2xToolStripMenuItem.Checked = Global.Config.TargetDisplayFilter == 4; + scanlines2xToolStripMenuItem.Checked = Global.Config.TargetDisplayFilter == 4; } private void DisplayFilterMenuItem_Click(object sender, EventArgs e) @@ -589,10 +589,10 @@ namespace BizHawk.Client.EmuHawk if (sender == x2SAIMenuItem) Global.Config.TargetDisplayFilter = 1; if (sender == SuperX2SAIMenuItem) Global.Config.TargetDisplayFilter = 2; if (sender == SuperEagleMenuItem) Global.Config.TargetDisplayFilter = 3; - if (sender == Scanlines25MenuItem) { Global.Config.TargetDisplayFilter = 4; Global.Config.TargetScanlineFilterIntensity = 192; } - if (sender == Scanlines50MenuItem) { Global.Config.TargetDisplayFilter = 4; Global.Config.TargetScanlineFilterIntensity = 128; } - if (sender == Scanlines75MenuItem) { Global.Config.TargetDisplayFilter = 4; Global.Config.TargetScanlineFilterIntensity = 64; } - if (sender == ScanlinesCustomMenuItem) { Global.Config.TargetDisplayFilter = 4; new ScanlineSlider().Show(); } + if (sender == Scanlines25MenuItem) { Global.Config.TargetDisplayFilter = 4; Global.Config.TargetScanlineFilterIntensity = 192; } + if (sender == Scanlines50MenuItem) { Global.Config.TargetDisplayFilter = 4; Global.Config.TargetScanlineFilterIntensity = 128; } + if (sender == Scanlines75MenuItem) { Global.Config.TargetDisplayFilter = 4; Global.Config.TargetScanlineFilterIntensity = 64; } + if (sender == ScanlinesCustomMenuItem) { Global.Config.TargetDisplayFilter = 4; new ScanlineSlider().Show(); } } private void WindowSizeSubMenu_DropDownOpened(object sender, EventArgs e) @@ -670,7 +670,7 @@ namespace BizHawk.Client.EmuHawk private void DisplayStatusBarMenuItem_Click(object sender, EventArgs e) { Global.Config.DisplayStatusBar ^= true; - + if (!_inFullscreen) { MainStatusBar.Visible = Global.Config.DisplayStatusBar; @@ -875,8 +875,8 @@ namespace BizHawk.Client.EmuHawk { Global.Config.SaveScreenshotWithStates ^= true; GlobalWin.OSD.AddMessage(Global.Config.SaveScreenshotWithStates - ? "Screenshots will be saved in savestates" - : "Screenshots will not be saved in savestates"); + ? "Screenshots will be saved in savestates" + : "Screenshots will not be saved in savestates"); } private void frameAdvanceSkipLagFramesToolStripMenuItem_Click(object sender, EventArgs e) @@ -1100,7 +1100,7 @@ namespace BizHawk.Client.EmuHawk VirtualPadMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Virtual Pad"].Bindings; TraceLoggerMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Trace Logger"].Bindings; TraceLoggerMenuItem.Enabled = Global.Emulator.CoreComm.CpuTraceAvailable; - CheatsMenuItem.Enabled = + CheatsMenuItem.Enabled = HexEditorMenuItem.Enabled = RamSearchMenuItem.Enabled = RamWatchMenuItem.Enabled = @@ -1232,6 +1232,16 @@ namespace BizHawk.Client.EmuHawk } } + + private void moiveSettingsToolStripMenuItem_Click(object sender, EventArgs e) + { + using (var dlg = new config.NES.NESSyncSettingsForm()) + { + dlg.ShowDialog(this); + } + } + + #endregion #region PCE @@ -1698,12 +1708,12 @@ namespace BizHawk.Client.EmuHawk CloseRomContextMenuItem.Visible = UndoSavestateContextMenuItem.Visible = !(Global.Emulator is NullEmulator); - - RecordMovieContextMenuItem.Visible = - PlayMovieContextMenuItem.Visible = + + RecordMovieContextMenuItem.Visible = + PlayMovieContextMenuItem.Visible = LoadLastMovieContextMenuItem.Visible = !(Global.Emulator is NullEmulator) && !Global.MovieSession.Movie.IsActive; - + RestartMovieContextMenuItem.Visible = StopMovieContextMenuItem.Visible = ViewSubtitlesContextMenuItem.Visible = @@ -1718,7 +1728,7 @@ namespace BizHawk.Client.EmuHawk AddSubtitleContextMenuItem.Visible = !(Global.Emulator is NullEmulator) && Global.MovieSession.Movie.IsActive && !Global.MovieSession.ReadOnly; ConfigContextMenuItem.Visible = _inFullscreen; - + ClearSRAMContextMenuItem.Visible = File.Exists(PathManager.SaveRamPath(Global.Game)); ContextSeparator_AfterROM.Visible = OpenRomContextMenuItem.Visible || LoadLastRomContextMenuItem.Visible; @@ -1741,12 +1751,12 @@ namespace BizHawk.Client.EmuHawk } var file = new FileInfo( - PathManager.SaveStatePrefix(Global.Game) + - ".QuickSave" + + PathManager.SaveStatePrefix(Global.Game) + + ".QuickSave" + Global.Config.SaveSlot + ".State.bak" ); - + if (file.Exists) { UndoSavestateContextMenuItem.Enabled = true; diff --git a/BizHawk.Client.EmuHawk/MainForm.Movie.cs b/BizHawk.Client.EmuHawk/MainForm.Movie.cs index a019400fb5..33f8544d40 100644 --- a/BizHawk.Client.EmuHawk/MainForm.Movie.cs +++ b/BizHawk.Client.EmuHawk/MainForm.Movie.cs @@ -48,6 +48,12 @@ namespace BizHawk.Client.EmuHawk }; } } + else if (!record && Global.Emulator.SystemId == "NES") + { + var s = new Emulation.Cores.Nintendo.NES.NES.NESSyncSettings(); + s.BoardProperties = new System.Collections.Generic.Dictionary(Global.MovieSession.Movie.Header.BoardProperties); + this._syncSettingsHack = s; + } // load the rom in any case LoadRom(GlobalWin.MainForm.CurrentlyOpenRom, true, !record); diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index a2cd9a41ae..b9b8f391c7 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -77,7 +77,7 @@ namespace BizHawk.Client.EmuHawk Global.CheatList = new CheatCollection(); Global.CheatList.Changed += ToolHelpers.UpdateCheatRelatedTools; - + UpdateStatusSlots(); UpdateKeyPriorityIcon(); @@ -385,7 +385,7 @@ namespace BizHawk.Client.EmuHawk CheckMessages(); LogConsole.PositionConsole(); - for (;;) + for (; ; ) { Input.Instance.Update(); @@ -454,7 +454,7 @@ namespace BizHawk.Client.EmuHawk } #endregion` - + #region Properties public string CurrentlyOpenRom; @@ -515,7 +515,7 @@ namespace BizHawk.Client.EmuHawk for (; ; ) { - + // loop through all available events var ie = Input.Instance.DequeueEvent(); if (ie == null) { break; } @@ -685,7 +685,7 @@ namespace BizHawk.Client.EmuHawk for (; zoom >= 1; zoom--) { if ((((video.BufferWidth * zoom) + borderWidth) < area.Width) - && (((video.BufferHeight * zoom) + borderHeight) < area.Height)) + && (((video.BufferHeight * zoom) + borderHeight) < area.Height)) { break; } @@ -2144,7 +2144,7 @@ namespace BizHawk.Client.EmuHawk { var oldp = Global.Config.SpeedPercent; int newp; - + if (oldp < 3) { newp = 3; @@ -2201,7 +2201,7 @@ namespace BizHawk.Client.EmuHawk { var oldp = Global.Config.SpeedPercent; int newp; - + if (oldp > 800) { newp = 800; @@ -2274,8 +2274,8 @@ namespace BizHawk.Client.EmuHawk LedLightStatusLabel.Visible = true; } - LedLightStatusLabel.Image = Global.Emulator.CoreComm.DriveLED - ? Properties.Resources.LightOn + LedLightStatusLabel.Image = Global.Emulator.CoreComm.DriveLED + ? Properties.Resources.LightOn : Properties.Resources.LightOff; } else @@ -2318,8 +2318,8 @@ namespace BizHawk.Client.EmuHawk { Global.Config.AcceptBackgroundInput ^= true; GlobalWin.OSD.AddMessage(Global.Config.AcceptBackgroundInput - ? "Background Input enabled" - : "Background Input disabled"); + ? "Background Input enabled" + : "Background Input disabled"); } private static void LimitFrameRateMessage() @@ -2786,8 +2786,8 @@ namespace BizHawk.Client.EmuHawk } // do sound rewire. the plan is to eventually have AVI writing support syncsound input, but it doesn't for the moment - _aviSoundInput = !Global.Emulator.StartAsyncSound() - ? new MetaspuAsync(Global.Emulator.SyncSoundProvider, ESynchMethod.ESynchMethod_V) + _aviSoundInput = !Global.Emulator.StartAsyncSound() + ? new MetaspuAsync(Global.Emulator.SyncSoundProvider, ESynchMethod.ESynchMethod_V) : Global.Emulator.SoundProvider; _dumpProxy = new MetaspuSoundProvider(ESynchMethod.ESynchMethod_V); @@ -2887,8 +2887,8 @@ namespace BizHawk.Client.EmuHawk } else { - output = Global.Config.AVI_CaptureOSD - ? new BmpVideoProvder(CaptureOSD()) + output = Global.Config.AVI_CaptureOSD + ? new BmpVideoProvder(CaptureOSD()) : Global.Emulator.VideoProvider; } @@ -2940,7 +2940,7 @@ namespace BizHawk.Client.EmuHawk // Still needs a good bit of refactoring public bool LoadRom(string path, bool deterministicemulation = false, bool hasmovie = false) { - var loader = new RomLoader + var loader = new RomLoader { ChooseArchive = LoadArhiveChooser, CoreCommMessageCallback = ShowMessageCoreComm @@ -3080,7 +3080,7 @@ namespace BizHawk.Client.EmuHawk file.Directory.Create(); } - + // Make backup first if (Global.Config.BackupSavestates && file.Exists) { @@ -3107,7 +3107,7 @@ namespace BizHawk.Client.EmuHawk // save settings object var t = Global.Emulator.GetType(); Global.Config.PutCoreSettings(Global.Emulator.GetSettings(), t); - + // don't trample config with loaded-from-movie settings if (!Global.MovieSession.Movie.IsActive) { @@ -3186,7 +3186,7 @@ namespace BizHawk.Client.EmuHawk string errorMsg; string warningMsg; var m = MovieImport.ImportFile(fn, out errorMsg, out warningMsg); - + if (!String.IsNullOrWhiteSpace(errorMsg)) { MessageBox.Show(errorMsg, "Conversion error", MessageBoxButtons.OK, MessageBoxIcon.Error); @@ -3199,7 +3199,7 @@ namespace BizHawk.Client.EmuHawk else { GlobalWin.OSD.AddMessage(Path.GetFileName(fn) + " imported as " + "Movies\\" + - Path.GetFileName(fn) + "." + Global.Config.MovieExtension); + Path.GetFileName(fn) + "." + Global.Config.MovieExtension); } if (!Directory.Exists(d)) diff --git a/BizHawk.Client.EmuHawk/config/NES/DataTableDictionaryBind.cs b/BizHawk.Client.EmuHawk/config/NES/DataTableDictionaryBind.cs new file mode 100644 index 0000000000..c911e9c7ef --- /dev/null +++ b/BizHawk.Client.EmuHawk/config/NES/DataTableDictionaryBind.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Data; + +namespace BizHawk.Client.EmuHawk.config.NES +{ + public class DataTableDictionaryBind + { + public DataTable Table { get; private set; } + public IDictionary Dictionary { get; private set; } + + public bool WasModified { get; private set; } + + public DataTableDictionaryBind(IDictionary Dictionary) + { + this.Dictionary = Dictionary; + CreateTable(); + } + + void CreateTable() + { + Table = new DataTable(); + Table.Columns.Add("Key", typeof(TKey)); + Table.Columns.Add("Value", typeof(TValue)); + foreach (var kvp in Dictionary) + Table.Rows.Add(kvp.Key, kvp.Value); + + Table.RowChanged += new DataRowChangeEventHandler(Table_RowChanged); + WasModified = false; + } + + void Table_RowChanged(object sender, DataRowChangeEventArgs e) + { + var key = (TKey)e.Row[0]; + var value = (TValue)e.Row[1]; + + switch (e.Action) + { + case DataRowAction.Add: + if (Dictionary.ContainsKey(key)) + { + e.Row.RejectChanges(); + } + else + { + Dictionary.Add(key, value); + WasModified = true; + } + break; + case DataRowAction.Change: + Dictionary[key] = value; + WasModified = true; + break; + case DataRowAction.Delete: + Dictionary.Remove(key); + WasModified = true; + break; + } + } + } +} diff --git a/BizHawk.Client.EmuHawk/config/NES/NESSyncSettingsForm.Designer.cs b/BizHawk.Client.EmuHawk/config/NES/NESSyncSettingsForm.Designer.cs new file mode 100644 index 0000000000..c615d8f102 --- /dev/null +++ b/BizHawk.Client.EmuHawk/config/NES/NESSyncSettingsForm.Designer.cs @@ -0,0 +1,122 @@ +namespace BizHawk.Client.EmuHawk.config.NES +{ + partial class NESSyncSettingsForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.buttonOK = new System.Windows.Forms.Button(); + this.buttonCancel = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.dataGridView1 = new System.Windows.Forms.DataGridView(); + this.buttonHelp = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit(); + this.SuspendLayout(); + // + // buttonOK + // + this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonOK.Location = new System.Drawing.Point(124, 238); + this.buttonOK.Name = "buttonOK"; + this.buttonOK.Size = new System.Drawing.Size(75, 23); + this.buttonOK.TabIndex = 0; + this.buttonOK.Text = "OK"; + this.buttonOK.UseVisualStyleBackColor = true; + this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click); + // + // buttonCancel + // + this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.buttonCancel.Location = new System.Drawing.Point(205, 238); + this.buttonCancel.Name = "buttonCancel"; + this.buttonCancel.Size = new System.Drawing.Size(75, 23); + this.buttonCancel.TabIndex = 1; + this.buttonCancel.Text = "Cancel"; + this.buttonCancel.UseVisualStyleBackColor = true; + this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 9); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(88, 13); + this.label1.TabIndex = 2; + this.label1.Text = "Board Properties:"; + // + // dataGridView1 + // + this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize; + this.dataGridView1.Location = new System.Drawing.Point(12, 25); + this.dataGridView1.MultiSelect = false; + this.dataGridView1.Name = "dataGridView1"; + this.dataGridView1.Size = new System.Drawing.Size(268, 207); + this.dataGridView1.TabIndex = 3; + // + // buttonHelp + // + this.buttonHelp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.buttonHelp.Location = new System.Drawing.Point(12, 238); + this.buttonHelp.Name = "buttonHelp"; + this.buttonHelp.Size = new System.Drawing.Size(23, 23); + this.buttonHelp.TabIndex = 4; + this.buttonHelp.Text = "?"; + this.buttonHelp.UseVisualStyleBackColor = true; + this.buttonHelp.Click += new System.EventHandler(this.buttonHelp_Click); + // + // NESSyncSettingsForm + // + this.AcceptButton = this.buttonOK; + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.CancelButton = this.buttonCancel; + this.ClientSize = new System.Drawing.Size(292, 273); + this.Controls.Add(this.buttonHelp); + this.Controls.Add(this.dataGridView1); + this.Controls.Add(this.label1); + this.Controls.Add(this.buttonCancel); + this.Controls.Add(this.buttonOK); + this.Name = "NESSyncSettingsForm"; + this.Text = "NES Movie Settings"; + ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button buttonOK; + private System.Windows.Forms.Button buttonCancel; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.DataGridView dataGridView1; + private System.Windows.Forms.Button buttonHelp; + } +} \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/config/NES/NESSyncSettingsForm.cs b/BizHawk.Client.EmuHawk/config/NES/NESSyncSettingsForm.cs new file mode 100644 index 0000000000..d253e61798 --- /dev/null +++ b/BizHawk.Client.EmuHawk/config/NES/NESSyncSettingsForm.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using BizHawk.Client.Common; + +namespace BizHawk.Client.EmuHawk.config.NES +{ + public partial class NESSyncSettingsForm : Form + { + DataTableDictionaryBind DTDB; + BizHawk.Emulation.Cores.Nintendo.NES.NES.NESSyncSettings SyncSettings; + + public NESSyncSettingsForm() + { + InitializeComponent(); + SyncSettings = (BizHawk.Emulation.Cores.Nintendo.NES.NES.NESSyncSettings)Global.Emulator.GetSyncSettings(); + DTDB = new DataTableDictionaryBind(SyncSettings.BoardProperties); + dataGridView1.DataSource = DTDB.Table; + } + + private void buttonCancel_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.Cancel; + Close(); + } + + private void buttonOK_Click(object sender, EventArgs e) + { + DialogResult = DialogResult.OK; + if (DTDB.WasModified) + GlobalWin.MainForm.PutCoreSyncSettings(SyncSettings); + } + + private void buttonHelp_Click(object sender, EventArgs e) + { + MessageBox.Show(this, "Board Properties are special per-mapper system settings. They are only useful to advanced users creating Tool Assisted Superplays. No support will be provided if you break something with them.", "Help"); + } + } +} diff --git a/BizHawk.Client.EmuHawk/config/NES/NESSyncSettingsForm.resx b/BizHawk.Client.EmuHawk/config/NES/NESSyncSettingsForm.resx new file mode 100644 index 0000000000..29dcb1b3a3 --- /dev/null +++ b/BizHawk.Client.EmuHawk/config/NES/NESSyncSettingsForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BizHawk.Common/Util.cs b/BizHawk.Common/Util.cs index 7c9d2c756c..2bc7c71375 100644 --- a/BizHawk.Common/Util.cs +++ b/BizHawk.Common/Util.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Text; +using System.Collections.Generic; namespace BizHawk.Common { @@ -8,9 +9,9 @@ namespace BizHawk.Common { private static readonly char[] HexConvArr = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; private static System.Runtime.InteropServices.GCHandle HexConvHandle; - + public static char* HexConvPtr { get; set; } - + static Util() { HexConvHandle = System.Runtime.InteropServices.GCHandle.Alloc(HexConvArr, System.Runtime.InteropServices.GCHandleType.Pinned); @@ -83,7 +84,7 @@ namespace BizHawk.Common public static string ReadStringAsciiZ(this BinaryReader r) { var sb = new StringBuilder(); - for (;;) + for (; ; ) { int b = r.ReadByte(); if (b <= 0) @@ -375,6 +376,41 @@ namespace BizHawk.Common var precision = "2"; return String.Format("{0:N" + precision + "}{1}", size, suffix); } + + // http://stackoverflow.com/questions/3928822/comparing-2-dictionarystring-string-instances + public static bool DictionaryEqual( + IDictionary first, IDictionary second) + { + if (first == second) return true; + if ((first == null) || (second == null)) return false; + if (first.Count != second.Count) return false; + + var comparer = EqualityComparer.Default; + + foreach (KeyValuePair kvp in first) + { + TValue secondValue; + if (!second.TryGetValue(kvp.Key, out secondValue)) return false; + if (!comparer.Equals(kvp.Value, secondValue)) return false; + } + return true; + } + + public static TValue GetValueOrDefault(this IDictionary dict, TKey key) + { + TValue ret; + dict.TryGetValue(key, out ret); + return ret; + } + + public static TValue GetValueOrDefault(this IDictionary dict, TKey key, TValue defaultvalue) + { + TValue ret; + if (!dict.TryGetValue(key, out ret)) + return defaultvalue; + else + return ret; + } } [Serializable] diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/BoardSystem.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/BoardSystem.cs index 34a7cdc6e9..a3ec63b615 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/BoardSystem.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/BoardSystem.cs @@ -50,7 +50,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES //mixes the board's custom audio into the supplied sample buffer void ApplyCustomAudio(short[] samples); - MapperProperties InitialRegisterValues { get; set; } + Dictionary InitialRegisterValues { get; set; } }; @@ -77,8 +77,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES } - private MapperProperties _initialRegisterValues = new MapperProperties(); - public MapperProperties InitialRegisterValues { get { return _initialRegisterValues; } set { _initialRegisterValues = value; } } + Dictionary _initialRegisterValues = new Dictionary(); + public Dictionary InitialRegisterValues { get { return _initialRegisterValues; } set { _initialRegisterValues = value; } } public abstract bool Configure(NES.EDetectionOrigin origin); public virtual void ClockPPU() { } @@ -351,7 +351,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES newboard = CreateBoardInstance(board.GetType()); } newboard.Create(this); - newboard.InitialRegisterValues = InitialMapperRegisterValues; + // i suppose the old board could have changed its initial register values, although it really shouldn't + // you can't use SyncSettings.BoardProperties here because they very well might be different than before + // in case the user actually changed something in the UI + newboard.InitialRegisterValues = board.InitialRegisterValues; newboard.Configure(origin); newboard.ROM = board.ROM; newboard.VROM = board.VROM; @@ -441,7 +444,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES /// /// finds a board class which can handle the provided cart /// - static Type FindBoard(CartInfo cart, EDetectionOrigin origin, MapperProperties properties) + static Type FindBoard(CartInfo cart, EDetectionOrigin origin, Dictionary properties) { NES nes = new NES(); nes.cart = cart; diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MLT-ACTION52.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MLT-ACTION52.cs index b80b6b3133..58a2e2141e 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MLT-ACTION52.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/Boards/MLT-ACTION52.cs @@ -104,8 +104,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES cheetahmen = true; } - prg_mode = bool.Parse(InitialRegisterValues["prg_mode"] ?? "false"); - prg_reg = int.Parse(InitialRegisterValues["prg_reg"] ?? "0"); + prg_mode = bool.Parse(InitialRegisterValues.GetValueOrDefault("prg_mode", "false")); + prg_reg = int.Parse(InitialRegisterValues.GetValueOrDefault("prg_reg", "0")); return true; } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/FDS/FDS.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/FDS/FDS.cs index c397dccb03..8f8f7e91f0 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/FDS/FDS.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/FDS/FDS.cs @@ -402,22 +402,5 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES if (addr < 0x6000) WRAM[addr + 0x2000] = value; } - - /* - public override void ApplyCustomAudio(short[] samples) - { - audio.ApplyCustomAudio(samples); - } - - public override void Dispose() - { - base.Dispose(); - if (audio != null) - { - audio.Dispose(); - audio = null; - } - } - */ } } diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs index 50795bff9e..e8c1dec85f 100644 --- a/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs +++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/NES/NES.cs @@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES static readonly bool USE_DATABASE = true; public RomStatus RomStatus; - public NES(CoreComm comm, GameInfo game, byte[] rom, object Settings, Dictionary boardProperties = null) + public NES(CoreComm comm, GameInfo game, byte[] rom, object Settings, object SyncSettings) { byte[] fdsbios = comm.CoreFileProvider.GetFirmware("NES", "Bios_FDS", false); if (fdsbios != null && fdsbios.Length == 40976) @@ -26,11 +26,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES fdsbios = tmp; } - if (boardProperties != null) - { - InitialMapperRegisterValues.Set(boardProperties); - } - + this.SyncSettings = (NESSyncSettings)SyncSettings ?? new NESSyncSettings(); CoreComm = comm; CoreComm.CpuTraceAvailable = true; BootGodDB.Initialize(); @@ -78,39 +74,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES return null; } - MapperProperties InitialMapperRegisterValues = new MapperProperties(); - - public class MapperProperties - { - private List> _properties = new List>(); - - public string this[string key] - { - get - { - if(_properties.Any(x => x.Key == key)) - { - return _properties.FirstOrDefault(x => x.Key == key).Value; - } - else - { - return null; - } - } - } - - public void Set(Dictionary values) - { - _properties.Clear(); - _properties.AddRange(values); - } - - public void Add(string key, string value) - { - _properties.Add(new KeyValuePair(key, value)); - } - } - class NESWatch { public enum EDomain @@ -546,6 +509,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES string hash_sha1 = null, hash_md5 = null; Unif unif = null; + Dictionary InitialMapperRegisterValues = new Dictionary(SyncSettings.BoardProperties); + origin = EDetectionOrigin.None; if (file.Length < 16) throw new Exception("Alleged NES rom too small to be anything useful"); @@ -873,9 +838,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES } NESSettings Settings = new NESSettings(); + NESSyncSettings SyncSettings = new NESSyncSettings(); public object GetSettings() { return Settings.Clone(); } - public object GetSyncSettings() { return null; } + public object GetSyncSettings() { return SyncSettings.Clone(); } public bool PutSettings(object o) { Settings = (NESSettings)o; @@ -902,7 +868,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES return false; } - public bool PutSyncSettings(object o) { return false; } + public bool PutSyncSettings(object o) + { + var n = (NESSyncSettings)o; + bool ret = NESSyncSettings.NeedsReboot(SyncSettings, n); + SyncSettings = n; + return ret; + } public class NESSettings { @@ -947,6 +919,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES this.Palette = Palette; } } + + public class NESSyncSettings + { + public Dictionary BoardProperties = new Dictionary(); + + public NESSyncSettings Clone() + { + var ret = (NESSyncSettings)MemberwiseClone(); + ret.BoardProperties = new Dictionary(BoardProperties); + return ret; + } + + public static bool NeedsReboot(NESSyncSettings x, NESSyncSettings y) + { + return !Util.DictionaryEqual(x.BoardProperties, y.BoardProperties); + } + } + + } }