snes-support save ram

This commit is contained in:
zeromus 2012-09-04 07:09:00 +00:00
parent ca8b778a52
commit f5c0965045
14 changed files with 100 additions and 31 deletions

View File

@ -64,7 +64,7 @@ namespace BizHawk
private int _lagcount = 0;
private int _frame = 0;
public byte[] SaveRam { get { return new byte[0]; } }
public byte[] ReadSaveRam { get { return new byte[0]; } }
public bool DeterministicEmulation { get; set; }
public bool SaveRamModified { get; set; }
public void SaveStateText(TextWriter writer) { SyncState(Serializer.CreateTextWriter(writer)); }

View File

@ -478,7 +478,7 @@ namespace BizHawk.Emulation.Consoles.Calculator
public bool DeterministicEmulation { get { return true; } set { } }
public byte[] SaveRam { get { return null; } }
public byte[] ReadSaveRam { get { return null; } }
public bool SaveRamModified
{
get { return false; }

View File

@ -70,7 +70,7 @@ namespace BizHawk.Emulation.Consoles.Coleco
private int _lagcount = 0;
private int _frame = 0;
public byte[] SaveRam { get { return new byte[0]; } }
public byte[] ReadSaveRam { get { return new byte[0]; } }
public bool DeterministicEmulation { get; set; }
public bool SaveRamModified { get; set; }
public void SaveStateText(TextWriter writer) { SyncState(Serializer.CreateTextWriter(writer)); }

View File

@ -68,7 +68,7 @@ namespace BizHawk.Emulation.Consoles.GB
Frame = 0;
}
public byte[] SaveRam { get { throw new NotImplementedException(); } }
public byte[] ReadSaveRam { get { throw new NotImplementedException(); } }
public bool SaveRamModified { get { return false; } set { } }
public void SaveStateBinary(System.IO.BinaryWriter writer)

View File

@ -775,7 +775,7 @@ namespace BizHawk.Emulation.Consoles.Gameboy
public int LagCount { get { return _lagcount; } set { _lagcount = value; } }
public bool IsLagFrame { get { return islag; } }
public byte[] SaveRam
public byte[] ReadSaveRam
{
get { throw new NotImplementedException(); }
}

View File

@ -122,7 +122,7 @@ namespace BizHawk.Emulation.Consoles.Intellivision
public bool DeterministicEmulation { get; set; }
public byte[] SaveRam { get { return null; } }
public byte[] ReadSaveRam { get { return null; } }
public bool SaveRamModified
{

View File

@ -303,7 +303,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo
public bool DeterministicEmulation { get { return true; } set { } }
public byte[] SaveRam
public byte[] ReadSaveRam
{
get
{

View File

@ -1,4 +1,9 @@
using System;
//TODO
//libsnes needs to be modified to support multiple instances
//rename snes.dll so nobody thinks it's a stock snes.dll (we'll be editing it substantially at some point)
//wrap dll code around some kind of library-accessing interface so that it doesnt malfunction if the dll is unavailable
using System;
using System.Linq;
using System.Diagnostics;
using System.Globalization;
@ -8,7 +13,6 @@ using System.Runtime.InteropServices;
namespace BizHawk.Emulation.Consoles.Nintendo.SNES
{
//TODO - wrap around some kind of library-accessing interface so that it doesnt malfunction if the dll is unavailable
public unsafe static class LibsnesDll
{
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
@ -59,16 +63,49 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
[MarshalAs(UnmanagedType.LPArray)] byte[] rom_data,
int rom_size);
public enum Device : uint
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.U1)]
public static extern SNES_REGION snes_get_region();
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern uint snes_get_memory_size(SNES_MEMORY id);
[DllImport("snes.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint="snes_get_memory_data")]
public static extern IntPtr snes_get_memory_data(SNES_MEMORY id);
public enum SNES_MEMORY : uint
{
None,
Joypad,
Multitap,
Mouse,
SuperScope,
Justifier,
Justifiers,
USART,
CARTRIDGE_RAM = 0,
CARTRIDGE_RTC = 1,
BSX_RAM = 2,
BSX_PRAM = 3,
SUFAMI_TURBO_A_RAM = 4,
SUFAMI_TURBO_B_RAM = 5,
GAME_BOY_RAM = 6,
GAME_BOY_RTC = 7,
WRAM = 100,
APURAM = 101,
VRAM = 102,
OAM = 103,
CGRAM = 104,
}
public enum SNES_REGION : uint
{
NTSC = 0,
PAL = 1,
}
public enum SNES_DEVICE : uint
{
NONE = 0,
JOYPAD = 1,
MULTITAP = 2,
MOUSE = 3,
SUPER_SCOPE = 4,
JUSTIFIER = 5,
JUSTIFIERS = 6,
SERIAL_CABLE = 7
}
public enum SNES_DEVICE_ID : uint
@ -88,8 +125,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
}
}
//TODO - libsnes needs to be modified to support multiple instances
//TODO - rename snes.dll so nobody thinks it's a stock snes.dll (we'll be editing it substantially at some point)
public unsafe class LibsnesCore : IEmulator, IVideoProvider, ISoundProvider
{
static LibsnesCore()
@ -140,7 +175,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
//Console.WriteLine("{0} {1} {2} {3}", port, device, index, id);
string key = "P" + (1 + port) + " ";
if ((LibsnesDll.Device)device == LibsnesDll.Device.Joypad)
if ((LibsnesDll.SNES_DEVICE)device == LibsnesDll.SNES_DEVICE.JOYPAD)
{
switch((LibsnesDll.SNES_DEVICE_ID)id)
{
@ -236,8 +271,31 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
public bool IsLagFrame { get; private set; }
public string SystemId { get { return "SNES"; } }
public bool DeterministicEmulation { get; set; }
public byte[] SaveRam { get { return new byte[0]; } }
public bool SaveRamModified { get; set; }
public bool SaveRamModified
{
set { }
get
{
return LibsnesDll.snes_get_memory_size(LibsnesDll.SNES_MEMORY.CARTRIDGE_RAM) != 0;
}
}
public byte[] ReadSaveRam { get { 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);
var data = LibsnesDll.snes_get_memory_data(id);
var ret = new byte[size];
Marshal.Copy(data,ret,0,size);
return ret;
}
public void StoreSaveRam(byte[] data)
{
var size = (int)LibsnesDll.snes_get_memory_size(LibsnesDll.SNES_MEMORY.CARTRIDGE_RAM);
var emudata = LibsnesDll.snes_get_memory_data(LibsnesDll.SNES_MEMORY.CARTRIDGE_RAM);
Marshal.Copy(data, 0, emudata, size);
}
public void ResetFrameCounter() { }
public void SaveStateText(TextWriter writer) { }

View File

@ -277,7 +277,7 @@ namespace BizHawk.Emulation.Consoles.TurboGrafx
public string Region { get; set; }
public bool DeterministicEmulation { get; set; }
public byte[] SaveRam
public byte[] ReadSaveRam
{
get { return BRAM; }
}

View File

@ -258,7 +258,7 @@ namespace BizHawk.Emulation.Consoles.Sega
public bool DeterministicEmulation { get; set; }
public string SystemId { get { return "GEN"; } }
public byte[] SaveRam
public byte[] ReadSaveRam
{
get { throw new NotImplementedException(); }
}

View File

@ -31,7 +31,7 @@ namespace BizHawk.Emulation.Consoles.Sega
public byte[] SaveRAM = new byte[BankSize * 2];
public byte SaveRamBank;
public byte[] SaveRam { get { return SaveRAM; } }
public byte[] ReadSaveRam { get { return SaveRAM; } }
public bool SaveRamModified { get; set; }
// Machine resources

View File

@ -41,7 +41,7 @@ namespace BizHawk
public int LagCount { get { return 0; } set { return; } }
public bool IsLagFrame { get { return false; } }
public byte[] SaveRam { get { return new byte[0]; } }
public byte[] ReadSaveRam { get { return new byte[0]; } }
public bool DeterministicEmulation { get; set; }
public bool SaveRamModified { get; set; }
public void SaveStateText(TextWriter writer) { }

View File

@ -20,7 +20,12 @@ namespace BizHawk
string SystemId { get; }
bool DeterministicEmulation { get; set; }
byte[] SaveRam { get; }
/// <summary>
/// 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
/// </summary>
byte[] ReadSaveRam { get; }
bool SaveRamModified { get; set; }
void ResetFrameCounter();

View File

@ -1537,12 +1537,18 @@ namespace BizHawk.MultiClient
DumpStatus.ToolTipText = annotation;
}
private void LoadSaveRam()
{
//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(Global.Emulator.SaveRam, 0, Global.Emulator.SaveRam.Length);
reader.Read(sram, 0, Global.Emulator.ReadSaveRam.Length);
if (Global.Emulator is LibsnesCore)
((LibsnesCore)Global.Emulator).StoreSaveRam(sram);
else Array.Copy(sram, Global.Emulator.ReadSaveRam, Global.Emulator.ReadSaveRam.Length);
}
catch { }
}
@ -1569,8 +1575,8 @@ namespace BizHawk.MultiClient
f.Directory.Create();
var writer = new BinaryWriter(new FileStream(path, FileMode.Create, FileAccess.Write));
int len = Util.SaveRamBytesUsed(Global.Emulator.SaveRam);
writer.Write(Global.Emulator.SaveRam, 0, len);
int len = Util.SaveRamBytesUsed(Global.Emulator.ReadSaveRam);
writer.Write(Global.Emulator.ReadSaveRam, 0, len);
writer.Close();
}