From f4081bc1eecdcfccb932353a8e2c46375dff9877 Mon Sep 17 00:00:00 2001 From: Souryo Date: Wed, 24 Aug 2016 17:32:22 -0400 Subject: [PATCH] Emulation: Added option to set the power on state for RAM (All 0s, all 1s or random values) --- Core/EmulationSettings.cpp | 2 + Core/EmulationSettings.h | 19 ++++++++ Core/MemoryManager.cpp | 18 ++++++-- Core/Movie.cpp | 4 ++ GUI.NET/Dependencies/resources.en.xml | 7 ++- GUI.NET/Dependencies/resources.fr.xml | 6 +++ GUI.NET/Dependencies/resources.ja.xml | 6 +++ .../Config/frmEmulationConfig.Designer.cs | 45 +++++++++++++++++-- GUI.NET/Forms/Config/frmEmulationConfig.cs | 4 +- GUI.NET/InteropEmu.cs | 8 ++++ InteropDLL/ConsoleWrapper.cpp | 1 + 11 files changed, 112 insertions(+), 8 deletions(-) diff --git a/Core/EmulationSettings.cpp b/Core/EmulationSettings.cpp index 1a144894..11135a0c 100644 --- a/Core/EmulationSettings.cpp +++ b/Core/EmulationSettings.cpp @@ -38,6 +38,8 @@ int32_t EmulationSettings::_nsfAutoDetectSilenceDelay = 3000; int32_t EmulationSettings::_nsfMoveToNextTrackTime = 120; bool EmulationSettings::_nsfDisableApuIrqs = true; +RamPowerOnState EmulationSettings::_ramPowerOnState = RamPowerOnState::AllZeros; + InputDisplaySettings EmulationSettings::_inputDisplaySettings = { 0, InputDisplayPosition::TopLeft, false }; OverscanDimensions EmulationSettings::_overscan; diff --git a/Core/EmulationSettings.h b/Core/EmulationSettings.h index 3167e237..8c47525c 100644 --- a/Core/EmulationSettings.h +++ b/Core/EmulationSettings.h @@ -59,6 +59,13 @@ enum class NesModel Dendy = 3, }; +enum class RamPowerOnState +{ + AllZeros = 0, + AllOnes = 1, + Random = 2 +}; + enum class VideoFilterType { None = 0, @@ -297,6 +304,8 @@ private: static InputDisplaySettings _inputDisplaySettings; + static RamPowerOnState _ramPowerOnState; + public: static uint32_t GetMesenVersion() { @@ -757,4 +766,14 @@ public: { return _inputDisplaySettings; } + + static void SetRamPowerOnState(RamPowerOnState state) + { + _ramPowerOnState = state; + } + + static RamPowerOnState GetRamPowerOnState() + { + return _ramPowerOnState; + } }; diff --git a/Core/MemoryManager.cpp b/Core/MemoryManager.cpp index 29424981..8c9b42a3 100644 --- a/Core/MemoryManager.cpp +++ b/Core/MemoryManager.cpp @@ -3,6 +3,7 @@ #include "BaseMapper.h" #include "Debugger.h" #include "CheatManager.h" +#include //Used for open bus uint8_t MemoryManager::_lastReadValue = 0; @@ -22,8 +23,7 @@ MemoryManager::MemoryManager(shared_ptr mapper) _ramReadHandlers = new IMemoryHandler*[RAMSize]; _ramWriteHandlers = new IMemoryHandler*[RAMSize]; - - memset(_internalRAM, 0, InternalRAMSize); + memset(_ramReadHandlers, 0, RAMSize * sizeof(IMemoryHandler*)); memset(_ramWriteHandlers, 0, RAMSize * sizeof(IMemoryHandler*)); } @@ -42,7 +42,19 @@ MemoryManager::~MemoryManager() void MemoryManager::Reset(bool softReset) { if(!softReset) { - memset(_internalRAM, 0, InternalRAMSize); + switch(EmulationSettings::GetRamPowerOnState()) { + default: + case RamPowerOnState::AllZeros: memset(_internalRAM, 0, InternalRAMSize); break; + case RamPowerOnState::AllOnes: memset(_internalRAM, 0xFF, InternalRAMSize); break; + case RamPowerOnState::Random: + std::random_device rd; + std::mt19937 mt(rd()); + std::uniform_int_distribution<> dist(0, 255); + for(int i = 0; i < InternalRAMSize; i++) { + _internalRAM[i] = dist(mt); + } + break; + } } _mapper->Reset(softReset); diff --git a/Core/Movie.cpp b/Core/Movie.cpp index ff636e44..b753618b 100644 --- a/Core/Movie.cpp +++ b/Core/Movie.cpp @@ -95,7 +95,11 @@ void Movie::StartRecording(string filename, bool reset) Reset(); if(reset) { + //Movies need a fixed power up state to be identical on each replay, force all 0s for RAM, no matter the setting + RamPowerOnState originalState = EmulationSettings::GetRamPowerOnState(); + EmulationSettings::SetRamPowerOnState(RamPowerOnState::AllZeros); Console::Reset(false); + EmulationSettings::SetRamPowerOnState(originalState); } else { Console::SaveState(_startState); } diff --git a/GUI.NET/Dependencies/resources.en.xml b/GUI.NET/Dependencies/resources.en.xml index 315c7db9..cd71f374 100644 --- a/GUI.NET/Dependencies/resources.en.xml +++ b/GUI.NET/Dependencies/resources.en.xml @@ -91,7 +91,7 @@ NES Famicom - + None Zapper @@ -125,5 +125,10 @@ Русский Español + + All 0s (Default) + All 1s + Random Values + \ No newline at end of file diff --git a/GUI.NET/Dependencies/resources.fr.xml b/GUI.NET/Dependencies/resources.fr.xml index a51d50ef..4bd486ae 100644 --- a/GUI.NET/Dependencies/resources.fr.xml +++ b/GUI.NET/Dependencies/resources.fr.xml @@ -236,6 +236,7 @@ Utiliser la version alternative du comportement des IRQs du MMC3 Permettre les entrées invalides (Bas+Haut ou Gauche+Droite en même temps) Éliminer la limite de sprites (Réduit le clignotement dans certains jeux) + État initial de la mémoire au démarrage : Overclocking Overclocking du CPU @@ -534,5 +535,10 @@ Русский Español + + Tous les bits à 0 (Défaut) + Tous les bits à 1 + Valeurs aléatoires + \ No newline at end of file diff --git a/GUI.NET/Dependencies/resources.ja.xml b/GUI.NET/Dependencies/resources.ja.xml index 50fcb508..0a41a0e1 100644 --- a/GUI.NET/Dependencies/resources.ja.xml +++ b/GUI.NET/Dependencies/resources.ja.xml @@ -236,6 +236,7 @@ MMC3AのIRQ仕様を使う コントローラでは不可能インプットを可能にする (同時に上と下や右と左) スプライトの制限を解除 (点滅を軽減する) + 起動時のメモリの状態 : オーバークロック オーバークロック @@ -517,5 +518,10 @@ Русский Español + + ビット全てを0にする (デフォルト) + ビット全てを1にする + 乱数 + \ No newline at end of file diff --git a/GUI.NET/Forms/Config/frmEmulationConfig.Designer.cs b/GUI.NET/Forms/Config/frmEmulationConfig.Designer.cs index 6511a50c..0a240dac 100644 --- a/GUI.NET/Forms/Config/frmEmulationConfig.Designer.cs +++ b/GUI.NET/Forms/Config/frmEmulationConfig.Designer.cs @@ -40,6 +40,9 @@ this.chkUseAlternativeMmc3Irq = new System.Windows.Forms.CheckBox(); this.chkAllowInvalidInput = new System.Windows.Forms.CheckBox(); this.chkRemoveSpriteLimit = new System.Windows.Forms.CheckBox(); + this.flowLayoutPanel8 = new System.Windows.Forms.FlowLayoutPanel(); + this.lblRamPowerOnState = new System.Windows.Forms.Label(); + this.cboRamPowerOnState = new System.Windows.Forms.ComboBox(); this.tpgOverclocking = new System.Windows.Forms.TabPage(); this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel(); this.flowLayoutPanel4 = new System.Windows.Forms.FlowLayoutPanel(); @@ -76,6 +79,7 @@ ((System.ComponentModel.ISupportInitialize)(this.nudEmulationSpeed)).BeginInit(); this.tpgAdvanced.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); + this.flowLayoutPanel8.SuspendLayout(); this.tpgOverclocking.SuspendLayout(); this.tableLayoutPanel3.SuspendLayout(); this.flowLayoutPanel4.SuspendLayout(); @@ -198,16 +202,16 @@ this.tableLayoutPanel1.Controls.Add(this.chkUseAlternativeMmc3Irq, 0, 2); this.tableLayoutPanel1.Controls.Add(this.chkAllowInvalidInput, 0, 1); this.tableLayoutPanel1.Controls.Add(this.chkRemoveSpriteLimit, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel8, 0, 3); this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 3); this.tableLayoutPanel1.Name = "tableLayoutPanel1"; - this.tableLayoutPanel1.RowCount = 4; + this.tableLayoutPanel1.RowCount = 5; + this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); - this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); this.tableLayoutPanel1.Size = new System.Drawing.Size(473, 267); this.tableLayoutPanel1.TabIndex = 0; // @@ -241,6 +245,36 @@ this.chkRemoveSpriteLimit.Text = "Remove sprite limit (Reduces flashing)"; this.chkRemoveSpriteLimit.UseVisualStyleBackColor = true; // + // flowLayoutPanel8 + // + this.flowLayoutPanel8.Controls.Add(this.lblRamPowerOnState); + this.flowLayoutPanel8.Controls.Add(this.cboRamPowerOnState); + this.flowLayoutPanel8.Dock = System.Windows.Forms.DockStyle.Fill; + this.flowLayoutPanel8.Location = new System.Drawing.Point(0, 69); + this.flowLayoutPanel8.Margin = new System.Windows.Forms.Padding(0); + this.flowLayoutPanel8.Name = "flowLayoutPanel8"; + this.flowLayoutPanel8.Size = new System.Drawing.Size(473, 27); + this.flowLayoutPanel8.TabIndex = 3; + // + // lblRamPowerOnState + // + this.lblRamPowerOnState.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblRamPowerOnState.AutoSize = true; + this.lblRamPowerOnState.Location = new System.Drawing.Point(3, 7); + this.lblRamPowerOnState.Name = "lblRamPowerOnState"; + this.lblRamPowerOnState.Size = new System.Drawing.Size(159, 13); + this.lblRamPowerOnState.TabIndex = 0; + this.lblRamPowerOnState.Text = "Default power on state for RAM:"; + // + // cboRamPowerOnState + // + this.cboRamPowerOnState.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboRamPowerOnState.FormattingEnabled = true; + this.cboRamPowerOnState.Location = new System.Drawing.Point(168, 3); + this.cboRamPowerOnState.Name = "cboRamPowerOnState"; + this.cboRamPowerOnState.Size = new System.Drawing.Size(176, 21); + this.cboRamPowerOnState.TabIndex = 1; + // // tpgOverclocking // this.tpgOverclocking.Controls.Add(this.tableLayoutPanel3); @@ -627,6 +661,8 @@ this.tpgAdvanced.ResumeLayout(false); this.tableLayoutPanel1.ResumeLayout(false); this.tableLayoutPanel1.PerformLayout(); + this.flowLayoutPanel8.ResumeLayout(false); + this.flowLayoutPanel8.PerformLayout(); this.tpgOverclocking.ResumeLayout(false); this.tableLayoutPanel3.ResumeLayout(false); this.tableLayoutPanel3.PerformLayout(); @@ -694,5 +730,8 @@ private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel7; private System.Windows.Forms.CheckBox chkShowLagCounter; private System.Windows.Forms.Button btnResetLagCounter; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel8; + private System.Windows.Forms.Label lblRamPowerOnState; + private System.Windows.Forms.ComboBox cboRamPowerOnState; } } \ No newline at end of file diff --git a/GUI.NET/Forms/Config/frmEmulationConfig.cs b/GUI.NET/Forms/Config/frmEmulationConfig.cs index 859f2d12..c4c1416f 100644 --- a/GUI.NET/Forms/Config/frmEmulationConfig.cs +++ b/GUI.NET/Forms/Config/frmEmulationConfig.cs @@ -32,7 +32,9 @@ namespace Mesen.GUI.Forms.Config AddBinding("PpuExtraScanlinesBeforeNmi", nudExtraScanlinesBeforeNmi); AddBinding("PpuExtraScanlinesAfterNmi", nudExtraScanlinesAfterNmi); - AddBinding("ShowLagCounter", chkShowLagCounter); + AddBinding("ShowLagCounter", chkShowLagCounter); + + AddBinding("RamPowerOnState", cboRamPowerOnState); } protected override void OnFormClosed(FormClosedEventArgs e) diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index 62b473f6..6c0b0502 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -126,6 +126,7 @@ namespace Mesen.GUI [DllImport(DLLPath)] private static extern void SetFlags(EmulationFlags flags); [DllImport(DLLPath)] private static extern void ClearFlags(EmulationFlags flags); + [DllImport(DLLPath)] public static extern void SetRamPowerOnState(RamPowerOnState state); [DllImport(DLLPath)] public static extern void SetMasterVolume(double volume); [DllImport(DLLPath)] public static extern void SetChannelVolume(AudioChannel channel, double volume); [DllImport(DLLPath)] public static extern void SetSampleRate(UInt32 sampleRate); @@ -817,6 +818,13 @@ namespace Mesen.GUI Famicom = 1 } + public enum RamPowerOnState + { + AllZeros = 0, + AllOnes = 1, + Random = 2 + } + public enum AudioChannel { Square1 = 0, diff --git a/InteropDLL/ConsoleWrapper.cpp b/InteropDLL/ConsoleWrapper.cpp index 47f480b0..7f10a5a1 100644 --- a/InteropDLL/ConsoleWrapper.cpp +++ b/InteropDLL/ConsoleWrapper.cpp @@ -324,6 +324,7 @@ namespace InteropEmu { DllExport void __stdcall SetFlags(EmulationFlags flags) { EmulationSettings::SetFlags(flags); } DllExport void __stdcall ClearFlags(EmulationFlags flags) { EmulationSettings::ClearFlags(flags); } + DllExport void __stdcall SetRamPowerOnState(RamPowerOnState state) { EmulationSettings::SetRamPowerOnState(state); } DllExport void __stdcall SetDisplayLanguage(Language lang) { EmulationSettings::SetDisplayLanguage(lang); } DllExport void __stdcall SetChannelVolume(uint32_t channel, double volume) { EmulationSettings::SetChannelVolume((AudioChannel)channel, volume); } DllExport void __stdcall SetMasterVolume(double volume) { EmulationSettings::SetMasterVolume(volume); }