From 83e145c36f22eef2b493a3d26af68f2ee774a69d Mon Sep 17 00:00:00 2001 From: goyuken Date: Fri, 14 Sep 2012 22:28:38 +0000 Subject: [PATCH] change the IEmulator saveram interface. i don't like doing this, but there were already two emus with special bandaid logic in MainForm.cs i hope this doesn't break something, but if it does i'll fix it --- .../Consoles/Atari/2600/Atari2600.cs | 9 ++++--- BizHawk.Emulation/Consoles/Calculator/TI83.cs | 4 ++- .../Consoles/Coleco/ColecoVision.cs | 7 +++-- .../Consoles/Intellivision/Intellivision.cs | 4 ++- .../Consoles/Nintendo/Gameboy/Gambatte.cs | 21 +++++++-------- .../Consoles/Nintendo/NES/NES.cs | 27 ++++++++++++++----- .../Consoles/Nintendo/SNES/LibsnesCore.cs | 12 ++++++++- .../Consoles/PC Engine/PCEngine.cs | 8 +++--- .../Consoles/Sega/Genesis/Cart/SaveRAM.cs | 7 +++-- BizHawk.Emulation/Consoles/Sega/SMS/SMS.cs | 4 ++- .../Base Implementations/NullEmulator.cs | 4 ++- BizHawk.Emulation/Interfaces/IEmulator.cs | 18 ++++++++++--- BizHawk.MultiClient/MainForm.cs | 18 +++++++++++-- 13 files changed, 100 insertions(+), 43 deletions(-) diff --git a/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.cs b/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.cs index 2f1489d297..55dace3c72 100644 --- a/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.cs +++ b/BizHawk.Emulation/Consoles/Atari/2600/Atari2600.cs @@ -64,9 +64,12 @@ namespace BizHawk private int _lagcount = 0; private int _frame = 0; - public byte[] ReadSaveRam { get { return new byte[0]; } } - public bool DeterministicEmulation { get; set; } + public byte[] ReadSaveRam() { return null; } + public void StoreSaveRam(byte[] data) { } + public void ClearSaveRam() { } public bool SaveRamModified { get; set; } + + public bool DeterministicEmulation { get; set; } public void SaveStateText(TextWriter writer) { SyncState(Serializer.CreateTextWriter(writer)); } public void LoadStateText(TextReader reader) { SyncState(Serializer.CreateTextReader(reader)); } public void SaveStateBinary(BinaryWriter bw) { SyncState(Serializer.CreateBinaryWriter(bw)); } @@ -80,7 +83,7 @@ namespace BizHawk bw.Flush(); return ms.ToArray(); } - + private IList memoryDomains; public IList MemoryDomains { get { return memoryDomains; } } public MemoryDomain MainMemory { get { return memoryDomains[0]; } } diff --git a/BizHawk.Emulation/Consoles/Calculator/TI83.cs b/BizHawk.Emulation/Consoles/Calculator/TI83.cs index 94824b8c89..e1f401607c 100644 --- a/BizHawk.Emulation/Consoles/Calculator/TI83.cs +++ b/BizHawk.Emulation/Consoles/Calculator/TI83.cs @@ -478,7 +478,9 @@ namespace BizHawk.Emulation.Consoles.Calculator public bool DeterministicEmulation { get { return true; } set { } } - public byte[] ReadSaveRam { get { return null; } } + public byte[] ReadSaveRam() { return null; } + public void StoreSaveRam(byte[] data) { } + public void ClearSaveRam() { } public bool SaveRamModified { get { return false; } diff --git a/BizHawk.Emulation/Consoles/Coleco/ColecoVision.cs b/BizHawk.Emulation/Consoles/Coleco/ColecoVision.cs index f50a12efb4..4e52a816d4 100644 --- a/BizHawk.Emulation/Consoles/Coleco/ColecoVision.cs +++ b/BizHawk.Emulation/Consoles/Coleco/ColecoVision.cs @@ -70,9 +70,12 @@ namespace BizHawk.Emulation.Consoles.Coleco private int _lagcount = 0; private int _frame = 0; - public byte[] ReadSaveRam { get { return new byte[0]; } } - public bool DeterministicEmulation { get; set; } + public byte[] ReadSaveRam() { return null; } + public void StoreSaveRam(byte[] data) { } + public void ClearSaveRam() { } public bool SaveRamModified { get; set; } + + public bool DeterministicEmulation { get; set; } public void SaveStateText(TextWriter writer) { SyncState(Serializer.CreateTextWriter(writer)); } public void LoadStateText(TextReader reader) { SyncState(Serializer.CreateTextReader(reader)); } public void SaveStateBinary(BinaryWriter bw) { SyncState(Serializer.CreateBinaryWriter(bw)); } diff --git a/BizHawk.Emulation/Consoles/Intellivision/Intellivision.cs b/BizHawk.Emulation/Consoles/Intellivision/Intellivision.cs index 3f829386b2..424b04229a 100644 --- a/BizHawk.Emulation/Consoles/Intellivision/Intellivision.cs +++ b/BizHawk.Emulation/Consoles/Intellivision/Intellivision.cs @@ -117,8 +117,10 @@ namespace BizHawk.Emulation.Consoles.Intellivision public bool DeterministicEmulation { get; set; } - public byte[] ReadSaveRam { get { return null; } } + public byte[] ReadSaveRam() { return null; } + public void StoreSaveRam(byte[] data) { } + public void ClearSaveRam() { } public bool SaveRamModified { get { return false; } diff --git a/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs b/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs index 530717e739..1284660e86 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/Gameboy/Gambatte.cs @@ -137,21 +137,18 @@ namespace BizHawk.Emulation.Consoles.GB public bool DeterministicEmulation { get; set; } - public byte[] ReadSaveRam + public byte[] ReadSaveRam() { - get - { - int length = LibGambatte.gambatte_savesavedatalength(GambatteState); + int length = LibGambatte.gambatte_savesavedatalength(GambatteState); - if (length > 0) - { - byte[] ret = new byte[length]; - LibGambatte.gambatte_savesavedata(GambatteState, ret); - return ret; - } - else - return new byte[0]; + if (length > 0) + { + byte[] ret = new byte[length]; + LibGambatte.gambatte_savesavedata(GambatteState, ret); + return ret; } + else + return new byte[0]; } public void StoreSaveRam(byte[] data) diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs index dcce7d69a6..698124d039 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs @@ -303,14 +303,29 @@ namespace BizHawk.Emulation.Consoles.Nintendo public bool DeterministicEmulation { get { return true; } set { } } - public byte[] ReadSaveRam + + + public byte[] ReadSaveRam() { - get - { - if (board == null) return null; - return board.SaveRam; - } + if (board == null || board.SaveRam == null) + return null; + return (byte[])board.SaveRam.Clone(); } + public void StoreSaveRam(byte[] data) + { + if (board == null || board.SaveRam == null) + return; + Array.Copy(data, board.SaveRam, data.Length); + } + + public void ClearSaveRam() + { + if (board == null || board.SaveRam == null) + return; + for (int i = 0; i < board.SaveRam.Length; i++) + board.SaveRam[i] = 0; + } + public bool SaveRamModified { get { if (board == null) return false; if (board.SaveRam == null) return false; return true; } diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs index e16baf3d5d..a8aaf5ab08 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs @@ -414,7 +414,11 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES } } - public byte[] ReadSaveRam { get { return snes_get_memory_data_read(LibsnesDll.SNES_MEMORY.CARTRIDGE_RAM); } } + public byte[] ReadSaveRam() + { + return snes_get_memory_data_read(LibsnesDll.SNES_MEMORY.CARTRIDGE_RAM); + } + public static byte[] snes_get_memory_data_read(LibsnesDll.SNES_MEMORY id) { var size = (int)LibsnesDll.snes_get_memory_size(id); @@ -433,6 +437,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES Marshal.Copy(data, 0, emudata, size); } + public void ClearSaveRam() + { + byte[] cleardata = new byte[(int)LibsnesDll.snes_get_memory_size(LibsnesDll.SNES_MEMORY.CARTRIDGE_RAM)]; + StoreSaveRam(cleardata); + } + public void ResetFrameCounter() { timeFrameCounter = 0; } public void SaveStateText(TextWriter writer) { diff --git a/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs b/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs index 0edfdebc72..ae0c6cfdc9 100644 --- a/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs +++ b/BizHawk.Emulation/Consoles/PC Engine/PCEngine.cs @@ -275,11 +275,9 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx public string Region { get; set; } public bool DeterministicEmulation { get; set; } - public byte[] ReadSaveRam - { - get { return BRAM; } - } - + public byte[] ReadSaveRam() { return (byte[])BRAM.Clone(); } + public void StoreSaveRam(byte[] data) { Array.Copy(data, BRAM, data.Length); } + public void ClearSaveRam() { BRAM = new byte[BRAM.Length]; } public bool SaveRamModified { get; set; } public void SaveStateText(TextWriter writer) diff --git a/BizHawk.Emulation/Consoles/Sega/Genesis/Cart/SaveRAM.cs b/BizHawk.Emulation/Consoles/Sega/Genesis/Cart/SaveRAM.cs index 67c8d529a3..0ae5bb6c35 100644 --- a/BizHawk.Emulation/Consoles/Sega/Genesis/Cart/SaveRAM.cs +++ b/BizHawk.Emulation/Consoles/Sega/Genesis/Cart/SaveRAM.cs @@ -23,10 +23,9 @@ namespace BizHawk.Emulation.Consoles.Sega } } - public byte[] ReadSaveRam // TODO if you're going to rename this to ReadSaveRam, refactor it to be a method, not a property. - { - get { return SaveRAM; } - } + public byte[] ReadSaveRam() { return (byte[])SaveRAM.Clone(); } + public void StoreSaveRam(byte[] data) { Array.Copy(data, SaveRAM, data.Length); } + public void ClearSaveRam() { SaveRAM = new byte[SaveRAM.Length]; } public bool SaveRamModified { get; set; } } diff --git a/BizHawk.Emulation/Consoles/Sega/SMS/SMS.cs b/BizHawk.Emulation/Consoles/Sega/SMS/SMS.cs index 056ce7b984..5f0fadc064 100644 --- a/BizHawk.Emulation/Consoles/Sega/SMS/SMS.cs +++ b/BizHawk.Emulation/Consoles/Sega/SMS/SMS.cs @@ -31,7 +31,9 @@ namespace BizHawk.Emulation.Consoles.Sega public byte[] SaveRAM = new byte[BankSize * 2]; public byte SaveRamBank; - public byte[] ReadSaveRam { get { return SaveRAM; } } + public byte[] ReadSaveRam() { return (byte[])SaveRAM.Clone(); } + public void StoreSaveRam(byte[] data) { Array.Copy(data, SaveRAM, data.Length); } + public void ClearSaveRam() { SaveRAM = new byte[SaveRAM.Length]; } public bool SaveRamModified { get; set; } // Machine resources diff --git a/BizHawk.Emulation/Interfaces/Base Implementations/NullEmulator.cs b/BizHawk.Emulation/Interfaces/Base Implementations/NullEmulator.cs index 72c0d3d4ac..8b7ac4f63b 100644 --- a/BizHawk.Emulation/Interfaces/Base Implementations/NullEmulator.cs +++ b/BizHawk.Emulation/Interfaces/Base Implementations/NullEmulator.cs @@ -41,7 +41,9 @@ namespace BizHawk public int LagCount { get { return 0; } set { return; } } public bool IsLagFrame { get { return false; } } - public byte[] ReadSaveRam { get { return new byte[0]; } } + public byte[] ReadSaveRam() { return null; } + public void StoreSaveRam(byte[] data) { } + public void ClearSaveRam() { } public bool DeterministicEmulation { get; set; } public bool SaveRamModified { get; set; } public void SaveStateText(TextWriter writer) { } diff --git a/BizHawk.Emulation/Interfaces/IEmulator.cs b/BizHawk.Emulation/Interfaces/IEmulator.cs index d62725c3ba..78bc8f3cfe 100644 --- a/BizHawk.Emulation/Interfaces/IEmulator.cs +++ b/BizHawk.Emulation/Interfaces/IEmulator.cs @@ -21,11 +21,21 @@ namespace BizHawk bool DeterministicEmulation { get; set; } /// - /// Don't edit this data, it may be useless as it may be a copy or some compiled data. - /// use StoreSaveRam if you want to store sram into the core. - /// Well, this rule is being violated. This comment is just a reminder that this is a bad architecture + /// return a copy of the saveram. editing it won't do you any good unless you later call StoreSaveRam() /// - byte[] ReadSaveRam { get; } + byte[] ReadSaveRam(); + + /// + /// store new saveram to the emu core. the data should be the same size as the return from ReadSaveRam() + /// + void StoreSaveRam(byte[] data); + + /// + /// reset saveram to a standard initial state + /// + void ClearSaveRam(); + + bool SaveRamModified { get; set; } void ResetFrameCounter(); diff --git a/BizHawk.MultiClient/MainForm.cs b/BizHawk.MultiClient/MainForm.cs index 79562b095d..2bf9c856a1 100644 --- a/BizHawk.MultiClient/MainForm.cs +++ b/BizHawk.MultiClient/MainForm.cs @@ -1555,6 +1555,7 @@ namespace BizHawk.MultiClient //zero says: this is sort of sketchy... but this is no time for rearchitecting try { + /* var sram = new byte[Global.Emulator.ReadSaveRam.Length]; using (var reader = new BinaryReader(new FileStream(PathManager.SaveRamPath(Global.Game), FileMode.Open, FileAccess.Read))) reader.Read(sram, 0, Global.Emulator.ReadSaveRam.Length); @@ -1564,6 +1565,11 @@ namespace BizHawk.MultiClient ((Gameboy)Global.Emulator).StoreSaveRam(sram); else Array.Copy(sram, Global.Emulator.ReadSaveRam, Global.Emulator.ReadSaveRam.Length); + */ + var sram = new byte[Global.Emulator.ReadSaveRam().Length]; + using (var reader = new BinaryReader(new FileStream(PathManager.SaveRamPath(Global.Game), FileMode.Open, FileAccess.Read))) + reader.Read(sram, 0, sram.Length); + Global.Emulator.StoreSaveRam(sram); } catch { } } @@ -1590,8 +1596,13 @@ namespace BizHawk.MultiClient f.Directory.Create(); var writer = new BinaryWriter(new FileStream(path, FileMode.Create, FileAccess.Write)); - int len = Util.SaveRamBytesUsed(Global.Emulator.ReadSaveRam); - writer.Write(Global.Emulator.ReadSaveRam, 0, len); + + var saveram = Global.Emulator.ReadSaveRam(); + + // this assumes that the default state of the core's sram is 0-filled, so don't do + // int len = Util.SaveRamBytesUsed(saveram); + int len = saveram.Length; + writer.Write(saveram, 0, len); writer.Close(); } @@ -3432,6 +3443,7 @@ namespace BizHawk.MultiClient try { + /* var sram = new byte[Global.Emulator.ReadSaveRam.Length]; if (Global.Emulator is LibsnesCore) ((LibsnesCore)Global.Emulator).StoreSaveRam(sram); @@ -3439,6 +3451,8 @@ namespace BizHawk.MultiClient ((Gameboy)Global.Emulator).ClearSaveRam(); else Array.Copy(sram, Global.Emulator.ReadSaveRam, Global.Emulator.ReadSaveRam.Length); + */ + Global.Emulator.ClearSaveRam(); } catch { } }