diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs
index 316b395e91..1ba422fa19 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/LibmGBA.cs
@@ -81,10 +81,25 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
[DllImport(dll, CallingConvention = cc)]
public static extern bool BizPutSaveRam(IntPtr ctx, byte[] src, int size);
+ ///
+ /// start a savestate operation
+ ///
+ ///
+ /// private parameter to be passed to BizFinishGetState
+ /// size of buffer to be allocated for BizFinishGetState
+ /// if false, operation failed and BizFinishGetState should not be called
[DllImport(dll, CallingConvention = cc)]
- public static extern int BizGetStateMaxSize(IntPtr ctx);
+ public static extern bool BizStartGetState(IntPtr ctx, ref IntPtr p, ref int size);
+
+ ///
+ /// finish a savestate operation. if StartGetState returned true, this must be called else memory leaks
+ ///
+ /// returned by BizStartGetState
+ /// buffer of length size
+ /// returned by BizStartGetState
[DllImport(dll, CallingConvention = cc)]
- public static extern bool BizGetState(IntPtr ctx, byte[] dest, int size);
+ public static extern void BizFinishGetState(IntPtr p, byte[] dest, int size);
+
[DllImport(dll, CallingConvention = cc)]
public static extern bool BizPutState(IntPtr ctx, byte[] src, int size);
diff --git a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs
index ed48c6fe62..c1dbd4cec8 100644
--- a/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs
+++ b/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/MGBAHawk.cs
@@ -63,8 +63,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
CoreComm.VsyncDen = 4389;
CoreComm.NominalWidth = 240;
CoreComm.NominalHeight = 160;
-
- InitStates();
}
catch
{
@@ -367,14 +365,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
#endregion
- private void InitStates()
- {
- _savebuff = new byte[LibmGBA.BizGetStateMaxSize(_core)];
- _savebuff2 = new byte[_savebuff.Length + 13];
- }
-
- private byte[] _savebuff;
- private byte[] _savebuff2;
+ private byte[] _savebuff = new byte[0];
+ private byte[] _savebuff2 = new byte[13];
public bool BinarySaveStatesPreferred
{
@@ -396,8 +388,16 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
public void SaveStateBinary(BinaryWriter writer)
{
- if (!LibmGBA.BizGetState(_core, _savebuff, _savebuff.Length))
+ IntPtr p = IntPtr.Zero;
+ int size = 0;
+ if (!LibmGBA.BizStartGetState(_core, ref p, ref size))
throw new InvalidOperationException("Core failed to save!");
+ if (size != _savebuff.Length)
+ {
+ _savebuff = new byte[size];
+ _savebuff2 = new byte[size + 13];
+ }
+ LibmGBA.BizFinishGetState(p, _savebuff, size);
writer.Write(_savebuff.Length);
writer.Write(_savebuff, 0, _savebuff.Length);
@@ -412,7 +412,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA
int length = reader.ReadInt32();
if (length != _savebuff.Length)
{
- throw new InvalidOperationException("Unexpected state size!");
+ _savebuff = new byte[length];
+ _savebuff2 = new byte[length + 13];
}
reader.Read(_savebuff, 0, length);
if (!LibmGBA.BizPutState(_core, _savebuff, length))
diff --git a/output/dll/mgba.dll b/output/dll/mgba.dll
index a1ff85cba0..83e1590d1a 100644
Binary files a/output/dll/mgba.dll and b/output/dll/mgba.dll differ
diff --git a/output64/dll/mgba.dll b/output64/dll/mgba.dll
index 751c1383f4..002d048b93 100644
Binary files a/output64/dll/mgba.dll and b/output64/dll/mgba.dll differ