From d6d188282c24901058112eb285d94872e3fc3a27 Mon Sep 17 00:00:00 2001 From: Sour Date: Wed, 26 Dec 2018 11:24:08 -0500 Subject: [PATCH] NSF: Allow rewinding in NSF player --- Core/Console.cpp | 2 +- Core/NsfMapper.cpp | 22 +++++++- Core/NsfMapper.h | 2 + Core/NsfPpu.cpp | 5 -- Core/NsfPpu.h | 1 - Core/ShortcutKeyHandler.cpp | 2 +- GUI.NET/Controls/ctrlNsfPlayer.Designer.cs | 62 ++++++++++++++++++++-- GUI.NET/Controls/ctrlNsfPlayer.cs | 36 +++++-------- GUI.NET/Controls/ctrlNsfPlayer.resx | 3 ++ GUI.NET/Dependencies/resources.ca.xml | 1 + GUI.NET/Dependencies/resources.en.xml | 1 + GUI.NET/Dependencies/resources.es.xml | 1 + GUI.NET/Dependencies/resources.fr.xml | 1 + GUI.NET/Dependencies/resources.ja.xml | 1 + GUI.NET/Dependencies/resources.pt.xml | 1 + GUI.NET/Dependencies/resources.ru.xml | 1 + GUI.NET/Dependencies/resources.uk.xml | 1 + GUI.NET/Dependencies/resources.zh.xml | 1 + GUI.NET/Forms/frmMain.Options.cs | 2 +- GUI.NET/Forms/frmMain.cs | 15 ++---- GUI.NET/InteropEmu.cs | 2 + InteropDLL/ConsoleWrapper.cpp | 10 ++++ 22 files changed, 124 insertions(+), 49 deletions(-) diff --git a/Core/Console.cpp b/Core/Console.cpp index a482dadb..e150c24a 100644 --- a/Core/Console.cpp +++ b/Core/Console.cpp @@ -589,7 +589,7 @@ void Console::ResetComponents(bool softReset) _debugHud->ClearScreen(); _memoryManager->Reset(softReset); - if(!_settings->CheckFlag(EmulationFlags::DisablePpuReset) || !softReset) { + if(!_settings->CheckFlag(EmulationFlags::DisablePpuReset) || !softReset || NsfMapper::GetInstance()) { _ppu->Reset(); } _apu->Reset(softReset); diff --git a/Core/NsfMapper.cpp b/Core/NsfMapper.cpp index f40b417d..7fbd7ba2 100644 --- a/Core/NsfMapper.cpp +++ b/Core/NsfMapper.cpp @@ -39,7 +39,7 @@ void NsfMapper::InitMapper() _namcoAudio.reset(new Namco163Audio(_console)); _sunsoftAudio.reset(new Sunsoft5bAudio(_console)); - SetCpuMemoryMapping(0x3F00, 0x3FFF, GetWorkRam() + 0x2000, MemoryAccessType::Read); + SetCpuMemoryMapping(0x3F00, 0x3FFF, PrgMemoryType::WorkRam, 0x2000, MemoryAccessType::Read); memcpy(GetWorkRam() + 0x2000, _nsfBios, 0x100); //Clear all register settings @@ -92,7 +92,7 @@ void NsfMapper::InitMapper(RomData& romData) if(_nsfHeader.SoundChips & NsfSoundChips::MMC5) { AddRegisterRange(0x5000, 0x5015, MemoryOperation::Write); //Registers AddRegisterRange(0x5205, 0x5206, MemoryOperation::Any); //Multiplication - SetCpuMemoryMapping(0x5C00, 0x5FFF, GetWorkRam() + 0x3000, MemoryAccessType::ReadWrite); //Exram + SetCpuMemoryMapping(0x5C00, 0x5FFF, PrgMemoryType::WorkRam, 0x3000, MemoryAccessType::ReadWrite); //Exram } if(_nsfHeader.SoundChips & NsfSoundChips::VRC6) { @@ -477,4 +477,22 @@ NsfHeader NsfMapper::GetNsfHeader() ConsoleFeatures NsfMapper::GetAvailableFeatures() { return ConsoleFeatures::Nsf; +} + +void NsfMapper::StreamState(bool saving) +{ + BaseMapper::StreamState(saving); + + SnapshotInfo mmc5Audio { _mmc5Audio.get() }; + SnapshotInfo vrc6Audio { _vrc6Audio.get() }; + SnapshotInfo vrc7Audio { _vrc7Audio.get() }; + SnapshotInfo fdsAudio { _fdsAudio.get() }; + SnapshotInfo namcoAudio { _namcoAudio.get() }; + SnapshotInfo sunsoftAudio { _sunsoftAudio.get() }; + + Stream( + _model, _needInit, _irqEnabled, _irqReloadValue, _irqCounter, _irqStatus, _debugIrqStatus, _mmc5MultiplierValues[0], _mmc5MultiplierValues[1], + _trackEndCounter, _trackFadeCounter, _fadeLength, _silenceDetectDelay, _trackEnded, _allowSilenceDetection, _hasBankSwitching, _ntscSpeed, + _palSpeed, _dendySpeed, _songNumber, mmc5Audio, vrc6Audio, vrc7Audio, fdsAudio, namcoAudio, sunsoftAudio + ); } \ No newline at end of file diff --git a/Core/NsfMapper.h b/Core/NsfMapper.h index 081b00c5..f00cc4a8 100644 --- a/Core/NsfMapper.h +++ b/Core/NsfMapper.h @@ -106,6 +106,8 @@ protected: uint32_t GetWorkRamPageSize() override { return 0x1000; } bool AllowRegisterRead() override { return true; } + void StreamState(bool saving) override; + void InitMapper() override; void InitMapper(RomData& romData) override; void Reset(bool softReset) override; diff --git a/Core/NsfPpu.cpp b/Core/NsfPpu.cpp index 2ce352eb..65a38bb1 100644 --- a/Core/NsfPpu.cpp +++ b/Core/NsfPpu.cpp @@ -6,8 +6,3 @@ void NsfPpu::DrawPixel() { } - -void NsfPpu::SendFrame() -{ - _console->GetNotificationManager()->SendNotification(ConsoleNotificationType::PpuFrameDone); -} diff --git a/Core/NsfPpu.h b/Core/NsfPpu.h index a9d9ba9c..8e1c8e26 100644 --- a/Core/NsfPpu.h +++ b/Core/NsfPpu.h @@ -6,7 +6,6 @@ class NsfPpu : public PPU { protected: void DrawPixel() override; - void SendFrame() override; public: using PPU::PPU; diff --git a/Core/ShortcutKeyHandler.cpp b/Core/ShortcutKeyHandler.cpp index 2b5560aa..cef74c82 100644 --- a/Core/ShortcutKeyHandler.cpp +++ b/Core/ShortcutKeyHandler.cpp @@ -203,7 +203,7 @@ void ShortcutKeyHandler::CheckMappedKeys() } } - if(!isNetplayClient && !MovieManager::Recording() && !settings->CheckFlag(NsfPlayerEnabled)) { + if(!isNetplayClient && !MovieManager::Recording()) { shared_ptr rewindManager = _console->GetRewindManager(); if(rewindManager) { if(DetectKeyPress(EmulatorShortcut::ToggleRewind)) { diff --git a/GUI.NET/Controls/ctrlNsfPlayer.Designer.cs b/GUI.NET/Controls/ctrlNsfPlayer.Designer.cs index a632f78e..f5858311 100644 --- a/GUI.NET/Controls/ctrlNsfPlayer.Designer.cs +++ b/GUI.NET/Controls/ctrlNsfPlayer.Designer.cs @@ -69,6 +69,10 @@ this.tlpRepeatShuffle = new System.Windows.Forms.TableLayoutPanel(); this.picRepeat = new System.Windows.Forms.PictureBox(); this.picShuffle = new System.Windows.Forms.PictureBox(); + this.tmrUpdate = new System.Windows.Forms.Timer(this.components); + this.panel4 = new System.Windows.Forms.Panel(); + this.lblRewinding = new System.Windows.Forms.Label(); + this.lblRewindIcon = new System.Windows.Forms.Label(); this.tlpMain.SuspendLayout(); this.tlpNsfInfo.SuspendLayout(); this.tableLayoutPanel3.SuspendLayout(); @@ -83,6 +87,7 @@ this.tlpRepeatShuffle.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.picRepeat)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.picShuffle)).BeginInit(); + this.panel4.SuspendLayout(); this.SuspendLayout(); // // tlpMain @@ -514,18 +519,20 @@ // this.tableLayoutPanel4.ColumnCount = 1; this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel4.Controls.Add(this.panel3, 0, 2); + this.tableLayoutPanel4.Controls.Add(this.panel4, 0, 2); this.tableLayoutPanel4.Controls.Add(this.panel2, 0, 0); this.tableLayoutPanel4.Controls.Add(this.panel1, 0, 1); + this.tableLayoutPanel4.Controls.Add(this.panel3, 0, 3); this.tableLayoutPanel4.Location = new System.Drawing.Point(5, 5); this.tableLayoutPanel4.Margin = new System.Windows.Forms.Padding(0); this.tableLayoutPanel4.Name = "tableLayoutPanel4"; - this.tableLayoutPanel4.RowCount = 4; + this.tableLayoutPanel4.RowCount = 5; + this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel4.Size = new System.Drawing.Size(121, 60); + this.tableLayoutPanel4.Size = new System.Drawing.Size(121, 85); this.tableLayoutPanel4.TabIndex = 13; // // panel3 @@ -534,7 +541,7 @@ this.panel3.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; this.panel3.Controls.Add(this.lblSlowMotion); this.panel3.Controls.Add(this.lblSlowMotionIcon); - this.panel3.Location = new System.Drawing.Point(0, 36); + this.panel3.Location = new System.Drawing.Point(0, 54); this.panel3.Margin = new System.Windows.Forms.Padding(0); this.panel3.Name = "panel3"; this.panel3.Size = new System.Drawing.Size(79, 18); @@ -629,6 +636,47 @@ this.picShuffle.TabStop = false; this.picShuffle.Click += new System.EventHandler(this.picShuffle_Click); // + // tmrUpdate + // + this.tmrUpdate.Enabled = true; + this.tmrUpdate.Interval = 250; + this.tmrUpdate.Tick += new System.EventHandler(this.tmrUpdate_Tick); + // + // panel4 + // + this.panel4.AutoSize = true; + this.panel4.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; + this.panel4.Controls.Add(this.lblRewinding); + this.panel4.Controls.Add(this.lblRewindIcon); + this.panel4.Location = new System.Drawing.Point(0, 36); + this.panel4.Margin = new System.Windows.Forms.Padding(0); + this.panel4.Name = "panel4"; + this.panel4.Size = new System.Drawing.Size(71, 18); + this.panel4.TabIndex = 3; + // + // lblRewinding + // + this.lblRewinding.AutoSize = true; + this.lblRewinding.ForeColor = System.Drawing.Color.DarkOrange; + this.lblRewinding.Location = new System.Drawing.Point(14, 4); + this.lblRewinding.Margin = new System.Windows.Forms.Padding(0); + this.lblRewinding.Name = "lblRewinding"; + this.lblRewinding.Size = new System.Drawing.Size(57, 13); + this.lblRewinding.TabIndex = 11; + this.lblRewinding.Text = "Rewinding"; + // + // lblRewindIcon + // + this.lblRewindIcon.AutoSize = true; + this.lblRewindIcon.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); + this.lblRewindIcon.ForeColor = System.Drawing.Color.DarkOrange; + this.lblRewindIcon.Location = new System.Drawing.Point(0, 0); + this.lblRewindIcon.Margin = new System.Windows.Forms.Padding(0); + this.lblRewindIcon.Name = "lblRewindIcon"; + this.lblRewindIcon.Size = new System.Drawing.Size(17, 18); + this.lblRewindIcon.TabIndex = 12; + this.lblRewindIcon.Text = "«"; + // // ctrlNsfPlayer // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -662,6 +710,8 @@ this.tlpRepeatShuffle.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.picRepeat)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.picShuffle)).EndInit(); + this.panel4.ResumeLayout(false); + this.panel4.PerformLayout(); this.ResumeLayout(false); } @@ -709,5 +759,9 @@ private System.Windows.Forms.PictureBox picShuffle; private System.Windows.Forms.PictureBox picRepeat; private System.Windows.Forms.Panel pnlBackground; + private System.Windows.Forms.Timer tmrUpdate; + private System.Windows.Forms.Panel panel4; + private System.Windows.Forms.Label lblRewinding; + private System.Windows.Forms.Label lblRewindIcon; } } diff --git a/GUI.NET/Controls/ctrlNsfPlayer.cs b/GUI.NET/Controls/ctrlNsfPlayer.cs index 71ee367c..cbb20881 100644 --- a/GUI.NET/Controls/ctrlNsfPlayer.cs +++ b/GUI.NET/Controls/ctrlNsfPlayer.cs @@ -15,7 +15,6 @@ namespace Mesen.GUI.Controls public partial class ctrlNsfPlayer : BaseControl { private List _trackList = new List(); - private int _frameCount = 0; private bool _fastForwarding = false; private UInt32 _originalSpeed = 100; private bool _disableShortcutKeys = false; @@ -112,31 +111,18 @@ namespace Mesen.GUI.Controls trkVolume.Value = (int)ConfigManager.Config.AudioInfo.MasterVolume; } - public void ResetCount() - { - _frameCount = 0; - this.BeginInvoke((MethodInvoker)(() => this.UpdateTimeDisplay(_frameCount))); - } - - public void CountFrame() - { - _frameCount++; - if(_frameCount % 30 == 0) { - this.BeginInvoke((MethodInvoker)(() => this.UpdateTimeDisplay(_frameCount))); - } - } - - private void UpdateTimeDisplay(int frameCount) + private void UpdateTimeDisplay() { if(!InteropEmu.IsNsf()) { - _frameCount = 0; return; } + UInt32 elapsedFrames = InteropEmu.NsfGetFrameCount(); + NsfHeader header = InteropEmu.NsfGetHeader(); int currentTrack = InteropEmu.NsfGetCurrentTrack(); - TimeSpan time = TimeSpan.FromSeconds((double)frameCount / ((header.Flags & 0x01) == 0x01 ? 50.006978 : 60.098812)); + TimeSpan time = TimeSpan.FromSeconds((double)elapsedFrames / ((header.Flags & 0x01) == 0x01 ? 50.006978 : 60.098812)); string label = time.ToString(time.TotalHours < 1 ? @"mm\:ss" : @"hh\:mm\:ss"); TimeSpan trackTime = GetTrackLength(header, currentTrack); @@ -150,6 +136,7 @@ namespace Mesen.GUI.Controls } lblRecording.Visible = lblRecordingDot.Visible = InteropEmu.WaveIsRecording(); + lblRewinding.Visible = lblRewindIcon.Visible = InteropEmu.IsRewinding(); lblFastForward.Visible = lblFastForwardIcon.Visible = InteropEmu.GetEmulationSpeed() > 100 || InteropEmu.GetEmulationSpeed() == 0 || InteropEmu.CheckFlag(EmulationFlags.Turbo); lblSlowMotion.Visible = lblSlowMotionIcon.Visible = InteropEmu.GetEmulationSpeed() < 100 && InteropEmu.GetEmulationSpeed() > 0 && !InteropEmu.CheckFlag(EmulationFlags.Turbo); @@ -211,6 +198,7 @@ namespace Mesen.GUI.Controls } else { if(InteropEmu.IsNsf()) { UpdateTrackDisplay(); + UpdateTimeDisplay(); toolTip.SetToolTip(btnNext, ResourceHelper.GetMessage("NsfNextTrack")); @@ -259,7 +247,6 @@ namespace Mesen.GUI.Controls newTrack = (InteropEmu.NsfGetCurrentTrack() + 1) % trackCount; } InteropEmu.NsfSelectTrack((byte)newTrack); - _frameCount = 0; } } @@ -267,7 +254,9 @@ namespace Mesen.GUI.Controls { int soundCount = InteropEmu.NsfGetHeader().TotalSongs; int currentTrack = InteropEmu.NsfGetCurrentTrack(); - if(_frameCount < 120) { + + UInt32 elapsedFrames = InteropEmu.NsfGetFrameCount(); + if(elapsedFrames < 120) { //Reload current track if it has been playing for more than 2 seconds currentTrack--; if(currentTrack < 0) { @@ -275,7 +264,6 @@ namespace Mesen.GUI.Controls } } InteropEmu.NsfSelectTrack((byte)currentTrack); - _frameCount = 0; } private void trkVolume_ValueChanged(object sender, EventArgs e) @@ -405,7 +393,6 @@ namespace Mesen.GUI.Controls int currentTrack = InteropEmu.NsfGetCurrentTrack(); if(currentTrack != cboTrack.SelectedIndex) { InteropEmu.NsfSelectTrack((byte)cboTrack.SelectedIndex); - _frameCount = 0; } } @@ -436,6 +423,11 @@ namespace Mesen.GUI.Controls this.tlpNsfInfo.MouseMove -= value; } } + + private void tmrUpdate_Tick(object sender, EventArgs e) + { + UpdateTimeDisplay(); + } } public class ComboboxItem diff --git a/GUI.NET/Controls/ctrlNsfPlayer.resx b/GUI.NET/Controls/ctrlNsfPlayer.resx index e794cb43..56288894 100644 --- a/GUI.NET/Controls/ctrlNsfPlayer.resx +++ b/GUI.NET/Controls/ctrlNsfPlayer.resx @@ -123,4 +123,7 @@ 154, 17 + + 244, 17 + \ No newline at end of file diff --git a/GUI.NET/Dependencies/resources.ca.xml b/GUI.NET/Dependencies/resources.ca.xml index a9fc7964..e5a8a3b4 100644 --- a/GUI.NET/Dependencies/resources.ca.xml +++ b/GUI.NET/Dependencies/resources.ca.xml @@ -115,6 +115,7 @@ Xip de so REC Càmera lenta + Rewinding Avanç ràpid
diff --git a/GUI.NET/Dependencies/resources.en.xml b/GUI.NET/Dependencies/resources.en.xml index 446f571d..4e412521 100644 --- a/GUI.NET/Dependencies/resources.en.xml +++ b/GUI.NET/Dependencies/resources.en.xml @@ -115,6 +115,7 @@ Sound Chips: REC Slow Motion + Rewinding Fast Forward
diff --git a/GUI.NET/Dependencies/resources.es.xml b/GUI.NET/Dependencies/resources.es.xml index 9679a64c..818ccaa8 100644 --- a/GUI.NET/Dependencies/resources.es.xml +++ b/GUI.NET/Dependencies/resources.es.xml @@ -114,6 +114,7 @@ Chip de audio REC Cámara lenta + Rewinding Avance rápido
diff --git a/GUI.NET/Dependencies/resources.fr.xml b/GUI.NET/Dependencies/resources.fr.xml index 6fa93e1b..8f25b9a5 100644 --- a/GUI.NET/Dependencies/resources.fr.xml +++ b/GUI.NET/Dependencies/resources.fr.xml @@ -115,6 +115,7 @@ Puces audio ENR Ralenti + Rembobinage Avance rapide
diff --git a/GUI.NET/Dependencies/resources.ja.xml b/GUI.NET/Dependencies/resources.ja.xml index b981e160..19b1c8c5 100644 --- a/GUI.NET/Dependencies/resources.ja.xml +++ b/GUI.NET/Dependencies/resources.ja.xml @@ -116,6 +116,7 @@ 音源チップ 録音中 スローモーション + 巻き戻し 早送り
diff --git a/GUI.NET/Dependencies/resources.pt.xml b/GUI.NET/Dependencies/resources.pt.xml index 6bc18762..f9a4d9ed 100644 --- a/GUI.NET/Dependencies/resources.pt.xml +++ b/GUI.NET/Dependencies/resources.pt.xml @@ -115,6 +115,7 @@ Chip de áudio REC Câmera lenta + Rewinding Acelerar
diff --git a/GUI.NET/Dependencies/resources.ru.xml b/GUI.NET/Dependencies/resources.ru.xml index 05b17164..f9c357f7 100644 --- a/GUI.NET/Dependencies/resources.ru.xml +++ b/GUI.NET/Dependencies/resources.ru.xml @@ -114,6 +114,7 @@ Звуковые чипы REC Slow Motion + Rewinding Fast Forward
diff --git a/GUI.NET/Dependencies/resources.uk.xml b/GUI.NET/Dependencies/resources.uk.xml index fad85971..921c9cc0 100644 --- a/GUI.NET/Dependencies/resources.uk.xml +++ b/GUI.NET/Dependencies/resources.uk.xml @@ -114,6 +114,7 @@ Звукові чіпи REC Сповільнений Рух + Rewinding Перемотування Вперед
diff --git a/GUI.NET/Dependencies/resources.zh.xml b/GUI.NET/Dependencies/resources.zh.xml index c0fc63c7..6d974d9f 100644 --- a/GUI.NET/Dependencies/resources.zh.xml +++ b/GUI.NET/Dependencies/resources.zh.xml @@ -118,6 +118,7 @@ 声音芯片: 正在录音 慢放 + Rewinding 快进
diff --git a/GUI.NET/Forms/frmMain.Options.cs b/GUI.NET/Forms/frmMain.Options.cs index 4c369065..e3c50e15 100644 --- a/GUI.NET/Forms/frmMain.Options.cs +++ b/GUI.NET/Forms/frmMain.Options.cs @@ -137,7 +137,7 @@ namespace Mesen.GUI.Forms ResourceHelper.UpdateEmuLanguage(); ResourceHelper.ApplyResources(this); UpdateMenus(); - InitializeNsfMode(true); + InitializeNsfMode(); ctrlRecentGames.UpdateGameInfo(); TopMost = ConfigManager.Config.PreferenceInfo.AlwaysOnTop; FormBorderStyle = ConfigManager.Config.PreferenceInfo.DisableMouseResize ? FormBorderStyle.Fixed3D : FormBorderStyle.Sizable; diff --git a/GUI.NET/Forms/frmMain.cs b/GUI.NET/Forms/frmMain.cs index 8b731c48..6da8c307 100644 --- a/GUI.NET/Forms/frmMain.cs +++ b/GUI.NET/Forms/frmMain.cs @@ -638,7 +638,7 @@ namespace Mesen.GUI.Forms VideoInfo.ApplyOverscanConfig(); _currentGame = InteropEmu.GetRomInfo().GetRomName(); InteropEmu.SetNesModel(ConfigManager.Config.Region); - InitializeNsfMode(false, true); + InitializeNsfMode(true); CheatInfo.ApplyCheats(); GameSpecificInfo.ApplyGameSpecificConfig(); UpdateStateMenu(mnuSaveState, true); @@ -661,12 +661,6 @@ namespace Mesen.GUI.Forms }); break; - case InteropEmu.ConsoleNotificationType.PpuFrameDone: - if(InteropEmu.IsNsf()) { - this.ctrlNsfPlayer.CountFrame(); - } - break; - case InteropEmu.ConsoleNotificationType.GameReset: InitializeNsfMode(); break; @@ -1386,7 +1380,7 @@ namespace Mesen.GUI.Forms } } - private void InitializeNsfMode(bool updateTextOnly = false, bool gameLoaded = false) + private void InitializeNsfMode(bool gameLoaded = false) { if(this.InvokeRequired) { if(InteropEmu.IsNsf()) { @@ -1397,7 +1391,7 @@ namespace Mesen.GUI.Forms InteropEmu.StopServer(); } } - this.BeginInvoke((MethodInvoker)(() => this.InitializeNsfMode(updateTextOnly, gameLoaded))); + this.BeginInvoke((MethodInvoker)(() => this.InitializeNsfMode(gameLoaded))); } else { if(InteropEmu.IsNsf()) { this.SetFullscreenState(false); @@ -1415,9 +1409,6 @@ namespace Mesen.GUI.Forms } this._isNsfPlayerMode = true; this.ctrlNsfPlayer.UpdateText(); - if(!updateTextOnly) { - this.ctrlNsfPlayer.ResetCount(); - } this.ctrlNsfPlayer.Visible = true; this.ctrlNsfPlayer.Focus(); diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index d1980faa..0c12af23 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -146,6 +146,7 @@ namespace Mesen.GUI [DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsNsf(); [DllImport(DLLPath)] public static extern void NsfSelectTrack(Byte trackNumber); [DllImport(DLLPath)] public static extern Int32 NsfGetCurrentTrack(); + [DllImport(DLLPath)] public static extern UInt32 NsfGetFrameCount(); [DllImport(DLLPath, EntryPoint = "NsfGetHeader")] private static extern void NsfGetHeaderWrapper(out NsfHeader header); [DllImport(DLLPath)] public static extern void NsfSetNsfConfig(Int32 autoDetectSilenceDelay, Int32 moveToNextTrackTime, [MarshalAs(UnmanagedType.I1)]bool disableApuIrqs); @@ -195,6 +196,7 @@ namespace Mesen.GUI [DllImport(DLLPath)] public static extern UInt32 GetEmulationSpeed(); [DllImport(DLLPath)] public static extern void SetTurboRewindSpeed(UInt32 turboSpeed, UInt32 rewindSpeed); [DllImport(DLLPath)] public static extern void SetRewindBufferSize(UInt32 seconds); + [DllImport(DLLPath)] [return: MarshalAs(UnmanagedType.I1)] public static extern bool IsRewinding(); [DllImport(DLLPath)] public static extern void SetOverclockRate(UInt32 overclockRate, [MarshalAs(UnmanagedType.I1)]bool adjustApu); [DllImport(DLLPath)] public static extern void SetPpuNmiConfig(UInt32 extraScanlinesBeforeNmi, UInt32 extraScanlineAfterNmi); [DllImport(DLLPath)] public static extern void SetOverscanDimensions(UInt32 left, UInt32 right, UInt32 top, UInt32 bottom); diff --git a/InteropDLL/ConsoleWrapper.cpp b/InteropDLL/ConsoleWrapper.cpp index 2b15b958..7406d344 100644 --- a/InteropDLL/ConsoleWrapper.cpp +++ b/InteropDLL/ConsoleWrapper.cpp @@ -629,6 +629,10 @@ namespace InteropEmu { DllExport uint32_t __stdcall GetEmulationSpeed() { return _settings->GetEmulationSpeed(true); } DllExport void __stdcall SetTurboRewindSpeed(uint32_t turboSpeed, uint32_t rewindSpeed) { _settings->SetTurboRewindSpeed(turboSpeed, rewindSpeed); } DllExport void __stdcall SetRewindBufferSize(uint32_t seconds) { _settings->SetRewindBufferSize(seconds); } + DllExport bool __stdcall IsRewinding() { + shared_ptr rewindManager = _console->GetRewindManager(); + return rewindManager ? rewindManager->IsRewinding() : false; + } DllExport void __stdcall SetOverclockRate(uint32_t overclockRate, bool adjustApu) { _settings->SetOverclockRate(overclockRate, adjustApu); } DllExport void __stdcall SetPpuNmiConfig(uint32_t extraScanlinesBeforeNmi, uint32_t extraScanlinesAfterNmi) { _settings->SetPpuNmiConfig(extraScanlinesBeforeNmi, extraScanlinesAfterNmi); } DllExport void __stdcall SetVideoScale(double scale, ConsoleId consoleId) { GetConsoleById(consoleId)->GetSettings()->SetVideoScale(scale); } @@ -667,6 +671,12 @@ namespace InteropEmu { //NSF functions DllExport bool __stdcall IsNsf() { return NsfMapper::GetInstance() != nullptr; } + DllExport uint32_t __stdcall NsfGetFrameCount() { + if(NsfMapper::GetInstance()) { + return _console->GetPpu()->GetFrameCount(); + } + return 0; + } DllExport void __stdcall NsfSelectTrack(uint8_t trackNumber) { if(NsfMapper::GetInstance()) { NsfMapper::GetInstance()->SelectTrack(trackNumber);