gameboy: tweak text savestates a bit in preparation to reuse some code for the wonderswan savestates

This commit is contained in:
goyuken 2014-05-31 04:01:07 +00:00
parent 63c361f4e2
commit 8f87c2e854
10 changed files with 54 additions and 178 deletions

View File

@ -35,6 +35,10 @@
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\References\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@ -67,6 +71,7 @@
<Compile Include="Serializer.cs" />
<Compile Include="SettingsUtil.cs" />
<Compile Include="SwitcherStream.cs" />
<Compile Include="TextState.cs" />
<Compile Include="UndoHistory.cs" />
<Compile Include="Util.cs" />
</ItemGroup>

View File

@ -238,8 +238,6 @@
<Compile Include="Consoles\Nintendo\Gameboy\GambatteLink.cs" />
<Compile Include="Consoles\Nintendo\Gameboy\GBColors.cs" />
<Compile Include="Consoles\Nintendo\Gameboy\LibGambatte.cs" />
<Compile Include="Consoles\Nintendo\Gameboy\StateDebug.cs" />
<Compile Include="Consoles\Nintendo\Gameboy\TextState.cs" />
<Compile Include="Consoles\Nintendo\GBA\LibMeteor.cs" />
<Compile Include="Consoles\Nintendo\GBA\Meteor.cs" />
<Compile Include="Consoles\Nintendo\N64\N64Input.cs" />

View File

@ -482,19 +482,27 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
JsonSerializer ser = new JsonSerializer() { Formatting = Formatting.Indented };
// other data in the text state besides core
class TextStateData
{
public int Frame;
public int LagCount;
public bool IsLagFrame;
public ulong _cycleCount;
public uint frameOverflow;
}
public void SaveStateText(System.IO.TextWriter writer)
{
var s = new TextState();
var s = new TextState<TextStateData>();
s.Prepare();
LibGambatte.gambatte_newstatesave_ex(GambatteState,
s.Save,
s.EnterSection,
s.ExitSection);
s.IsLagFrame = IsLagFrame;
s.LagCount = LagCount;
s.Frame = Frame;
s.frameOverflow = frameOverflow;
s._cycleCount = _cycleCount;
var ff = s.GetFunctionPointers();
LibGambatte.gambatte_newstatesave_ex(GambatteState, ref ff);
s.ExtraData.IsLagFrame = IsLagFrame;
s.ExtraData.LagCount = LagCount;
s.ExtraData.Frame = Frame;
s.ExtraData.frameOverflow = frameOverflow;
s.ExtraData._cycleCount = _cycleCount;
ser.Serialize(writer, s);
// write extra copy of stuff we don't use
@ -504,17 +512,15 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
public void LoadStateText(System.IO.TextReader reader)
{
var s = (TextState)ser.Deserialize(reader, typeof(TextState));
var s = (TextState<TextStateData>)ser.Deserialize(reader, typeof(TextState<TextStateData>));
s.Prepare();
LibGambatte.gambatte_newstateload_ex(GambatteState,
s.Load,
s.EnterSection,
s.ExitSection);
IsLagFrame = s.IsLagFrame;
LagCount = s.LagCount;
Frame = s.Frame;
frameOverflow = s.frameOverflow;
_cycleCount = s._cycleCount;
var ff = s.GetFunctionPointers();
LibGambatte.gambatte_newstateload_ex(GambatteState, ref ff);
IsLagFrame = s.ExtraData.IsLagFrame;
LagCount = s.ExtraData.LagCount;
Frame = s.ExtraData.Frame;
frameOverflow = s.ExtraData.frameOverflow;
_cycleCount = s.ExtraData._cycleCount;
}
public void SaveStateBinary(System.IO.BinaryWriter writer)
@ -560,6 +566,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
public bool BinarySaveStatesPreferred { get { return true; } }
/*
void DebugStates()
{
var sd = new StateDebug();
@ -570,7 +577,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
LibGambatte.gambatte_newstatesave_ex(GambatteState, Save, EnterSection, ExitSection);
LibGambatte.gambatte_newstateload_ex(GambatteState, Load, EnterSection, ExitSection);
}
}*/
#endregion

View File

@ -1,5 +1,6 @@
using System;
using System.Runtime.InteropServices;
using BizHawk.Common;
namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{
@ -306,10 +307,10 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
public delegate void SectionFunction(string name);
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_newstatesave_ex(IntPtr core, DataFunction Save, SectionFunction EnterSection, SectionFunction ExitSection);
public static extern void gambatte_newstatesave_ex(IntPtr core, ref TextStateFPtrs ff);
[DllImport("libgambatte.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void gambatte_newstateload_ex(IntPtr core, DataFunction Load, SectionFunction EnterSection, SectionFunction ExitSection);
public static extern void gambatte_newstateload_ex(IntPtr core, ref TextStateFPtrs ff);
/// <summary>
/// ROM header title of currently loaded ROM image.

View File

@ -1,61 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{
/*
* the new gambatte savestater includes functionality that
* could be used to make structured text mode savestates. this module just does a bit of
* sanity checking using that capability
*/
public class StateDebug
{
Dictionary<string, byte[]> Data = new Dictionary<string, byte[]>();
string Path = "/";
List<string> SaveHistory = new List<string>();
int LoadHistoryPos = 0;
public void Save(IntPtr data, int length, string name)
{
byte[] d = new byte[length];
Marshal.Copy(data, d, 0, length);
string s = Path + name;
SaveHistory.Add(s);
if (Data.ContainsKey(s))
throw new Exception("Already stored");
Data[s] = d;
}
public void Load(IntPtr data, int length, string name)
{
string s = Path + name;
byte[] d = Data[s];
if (SaveHistory[LoadHistoryPos++] != s)
throw new Exception("Loading out of order!");
Marshal.Copy(d, 0, data, length);
}
public void EnterSection(string name)
{
Path = Path + name + '/';
}
public void ExitSection(string name)
{
int i = Path.Substring(0, Path.Length - 1).LastIndexOf('/');
if (i < 0)
throw new Exception("Couldn't unwind stack!");
string newPath = Path.Substring(0, i + 1);
string unwind = Path.Substring(0, Path.Length - 1).Substring(i + 1);
if (unwind != name)
throw new Exception("Left wrong section!");
Path = newPath;
}
}
}

View File

@ -1,68 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using Newtonsoft.Json;
namespace BizHawk.Emulation.Cores.Nintendo.Gameboy
{
public class TextState
{
public class Node
{
public Dictionary<string, byte[]> Data = new Dictionary<string, byte[]>();
public Dictionary<string, Node> Objects = new Dictionary<string, Node>();
}
public Node Root = new Node();
[JsonIgnore]
Stack<Node> Nodes;
[JsonIgnore]
Node Current { get { return Nodes.Peek(); } }
public void Prepare()
{
Nodes = new Stack<Node>();
Nodes.Push(Root);
}
public void Save(IntPtr data, int length, string name)
{
byte[] d = new byte[length];
Marshal.Copy(data, d, 0, length);
Current.Data.Add(name, d);
}
public void Load(IntPtr data, int length, string name)
{
byte[] d = Current.Data[name];
Marshal.Copy(d, 0, data, length);
}
public void EnterSection(string name)
{
Node next = null;
Current.Objects.TryGetValue(name, out next);
if (next == null)
{
next = new Node();
Current.Objects.Add(name, next);
}
Nodes.Push(next);
}
public void ExitSection(string name)
{
Node last = Nodes.Pop();
if (Current.Objects[name] != last)
throw new InvalidOperationException();
}
// other data besides the core
public int Frame;
public int LagCount;
public bool IsLagFrame;
public ulong _cycleCount;
public uint frameOverflow;
}
}

View File

@ -168,23 +168,17 @@ GBEXPORT int gambatte_newstateload(void *core, const char *data, long len)
return !loader.Overflow() && loader.GetLength() == len;
}
GBEXPORT void gambatte_newstatesave_ex(void *core,
void (*Save_)(const void *ptr, size_t size, const char *name),
void (*EnterSection_)(const char *name),
void (*ExitSection_)(const char *name))
GBEXPORT void gambatte_newstatesave_ex(void *core, FPtrs *ff)
{
GB *g = (GB *) core;
NewStateExternalFunctions saver(Save_, NULL, EnterSection_, ExitSection_);
NewStateExternalFunctions saver(ff);
g->SyncState<false>(&saver);
}
GBEXPORT void gambatte_newstateload_ex(void *core,
void (*Load_)(void *ptr, size_t size, const char *name),
void (*EnterSection_)(const char *name),
void (*ExitSection_)(const char *name))
GBEXPORT void gambatte_newstateload_ex(void *core, FPtrs *ff)
{
GB *g = (GB *) core;
NewStateExternalFunctions loader(NULL, Load_, EnterSection_, ExitSection_);
NewStateExternalFunctions loader(ff);
g->SyncState<true>(&loader);
}

View File

@ -40,15 +40,11 @@ void NewStateExternalBuffer::Load(void *ptr, size_t size, const char *name)
length += size;
}
NewStateExternalFunctions::NewStateExternalFunctions(
void (*Save_)(const void *ptr, size_t size, const char *name),
void (*Load_)(void *ptr, size_t size, const char *name),
void (*EnterSection_)(const char *name),
void (*ExitSection_)(const char *name))
:Save_(Save_),
Load_(Load_),
EnterSection_(EnterSection_),
ExitSection_(ExitSection_)
NewStateExternalFunctions::NewStateExternalFunctions(const FPtrs *ff)
:Save_(ff->Save_),
Load_(ff->Load_),
EnterSection_(ff->EnterSection_),
ExitSection_(ff->ExitSection_)
{
}

View File

@ -42,6 +42,14 @@ public:
virtual void Load(void *ptr, size_t size, const char *name);
};
struct FPtrs
{
void (*Save_)(const void *ptr, size_t size, const char *name);
void (*Load_)(void *ptr, size_t size, const char *name);
void (*EnterSection_)(const char *name);
void (*ExitSection_)(const char *name);
};
class NewStateExternalFunctions : public NewState
{
private:
@ -50,11 +58,7 @@ private:
void (*EnterSection_)(const char *name);
void (*ExitSection_)(const char *name);
public:
NewStateExternalFunctions(
void (*Save_)(const void *ptr, size_t size, const char *name),
void (*Load_)(void *ptr, size_t size, const char *name),
void (*EnterSection_)(const char *name),
void (*ExitSection_)(const char *name));
NewStateExternalFunctions(const FPtrs *ff);
virtual void Save(const void *ptr, size_t size, const char *name);
virtual void Load(void *ptr, size_t size, const char *name);
virtual void EnterSection(const char *name);

Binary file not shown.