diff --git a/BizHawk.Common/BizHawk.Common.csproj b/BizHawk.Common/BizHawk.Common.csproj
index 2c22064973..d7027e8448 100644
--- a/BizHawk.Common/BizHawk.Common.csproj
+++ b/BizHawk.Common/BizHawk.Common.csproj
@@ -35,6 +35,10 @@
true
+
+ False
+ ..\References\Newtonsoft.Json.dll
+
@@ -67,6 +71,7 @@
+
diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
index fedf87a821..dfee1069e0 100644
--- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
+++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
@@ -238,8 +238,6 @@
-
-
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs
index b63fa81c6a..30409cb1bd 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/Gambatte.cs
@@ -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();
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)ser.Deserialize(reader, typeof(TextState));
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
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs
index 78302aee1f..b30c08af6a 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/LibGambatte.cs
@@ -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);
///
/// ROM header title of currently loaded ROM image.
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/StateDebug.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/StateDebug.cs
deleted file mode 100644
index 74b538e1b6..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/StateDebug.cs
+++ /dev/null
@@ -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 Data = new Dictionary();
-
- string Path = "/";
-
- List SaveHistory = new List();
- 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;
- }
- }
-}
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/TextState.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/TextState.cs
deleted file mode 100644
index ff0fd057fb..0000000000
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/TextState.cs
+++ /dev/null
@@ -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 Data = new Dictionary();
- public Dictionary Objects = new Dictionary();
- }
-
- public Node Root = new Node();
-
- [JsonIgnore]
- Stack Nodes;
- [JsonIgnore]
- Node Current { get { return Nodes.Peek(); } }
-
- public void Prepare()
- {
- Nodes = new Stack();
- 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;
-
- }
-}
diff --git a/libgambatte/src/cinterface.cpp b/libgambatte/src/cinterface.cpp
index f5c0987a29..b6bb0328eb 100644
--- a/libgambatte/src/cinterface.cpp
+++ b/libgambatte/src/cinterface.cpp
@@ -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(&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(&loader);
}
diff --git a/libgambatte/src/newstate.cpp b/libgambatte/src/newstate.cpp
index ee4065324b..fa01dbf6ef 100644
--- a/libgambatte/src/newstate.cpp
+++ b/libgambatte/src/newstate.cpp
@@ -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_)
{
}
diff --git a/libgambatte/src/newstate.h b/libgambatte/src/newstate.h
index 5d5e17eeb5..37e2a7038f 100644
--- a/libgambatte/src/newstate.h
+++ b/libgambatte/src/newstate.h
@@ -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);
diff --git a/output/dll/libgambatte.dll b/output/dll/libgambatte.dll
index 5afa60c03e..4d15c97b79 100644
Binary files a/output/dll/libgambatte.dll and b/output/dll/libgambatte.dll differ