gba: enable savestates. in the process find and fix an absolutely retarded bug with core savestate loading and bios. fuck #define forever.
This commit is contained in:
parent
b9fac0643a
commit
366370301f
|
@ -159,7 +159,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
|
|||
/// <summary>
|
||||
/// save saveram to a byte buffer
|
||||
/// </summary>
|
||||
/// <param name="data">buffer generated by core. coyp from, but do not modify</param>
|
||||
/// <param name="data">buffer generated by core. copy from, but do not modify</param>
|
||||
/// <param name="size">length of buffer</param>
|
||||
/// <returns>success</returns>
|
||||
[DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
|
@ -184,5 +184,32 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
|
|||
/// </summary>
|
||||
[DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void libmeteor_clearsaveram();
|
||||
|
||||
/// <summary>
|
||||
/// serialize state
|
||||
/// </summary>
|
||||
/// <param name="data">buffer generated by core</param>
|
||||
/// <param name="size">size of buffer</param>
|
||||
/// <returns>success</returns>
|
||||
[DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern bool libmeteor_savestate(ref IntPtr data, ref uint size);
|
||||
|
||||
/// <summary>
|
||||
/// destroy a buffer previously returned by libmeteor_savestate() to avoid leakage
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
[DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void libmeteor_savestate_destroy(IntPtr data);
|
||||
|
||||
/// <summary>
|
||||
/// unserialize state
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <param name="size"></param>
|
||||
/// <returns>success</returns>
|
||||
[DllImport("libmeteor.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern bool libmeteor_loadstate(byte[] data, uint size);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,20 +94,63 @@ namespace BizHawk.Emulation.Consoles.Nintendo.GBA
|
|||
|
||||
#region savestates
|
||||
|
||||
byte[] SaveCoreBinary()
|
||||
{
|
||||
IntPtr ndata = IntPtr.Zero;
|
||||
uint nsize = 0;
|
||||
if (!LibMeteor.libmeteor_savestate(ref ndata, ref nsize))
|
||||
throw new Exception("libmeteor_savestate() failed!");
|
||||
if (ndata == IntPtr.Zero || nsize == 0)
|
||||
throw new Exception("libmeteor_savestate() returned bad!");
|
||||
|
||||
byte[] ret = new byte[nsize];
|
||||
Marshal.Copy(ndata, ret, 0, (int)nsize);
|
||||
LibMeteor.libmeteor_savestate_destroy(ndata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LoadCoreBinary(byte[] data)
|
||||
{
|
||||
if (!LibMeteor.libmeteor_loadstate(data, (uint)data.Length))
|
||||
throw new Exception("libmeteor_loadstate() failed!");
|
||||
}
|
||||
|
||||
public void SaveStateText(System.IO.TextWriter writer)
|
||||
{
|
||||
var temp = SaveStateBinary();
|
||||
temp.SaveAsHex(writer);
|
||||
// write extra copy of stuff we don't use
|
||||
writer.WriteLine("Frame {0}", Frame);
|
||||
}
|
||||
|
||||
public void LoadStateText(System.IO.TextReader reader)
|
||||
{
|
||||
string hex = reader.ReadLine();
|
||||
byte[] state = new byte[hex.Length / 2];
|
||||
state.ReadFromHex(hex);
|
||||
LoadStateBinary(new BinaryReader(new MemoryStream(state)));
|
||||
}
|
||||
|
||||
public void SaveStateBinary(System.IO.BinaryWriter writer)
|
||||
{
|
||||
byte[] data = SaveCoreBinary();
|
||||
writer.Write(data.Length);
|
||||
writer.Write(data);
|
||||
// other variables
|
||||
writer.Write(IsLagFrame);
|
||||
writer.Write(LagCount);
|
||||
writer.Write(Frame);
|
||||
}
|
||||
|
||||
public void LoadStateBinary(System.IO.BinaryReader reader)
|
||||
{
|
||||
int length = reader.ReadInt32();
|
||||
byte[] data = reader.ReadBytes(length);
|
||||
LoadCoreBinary(data);
|
||||
// other variables
|
||||
IsLagFrame = reader.ReadBoolean();
|
||||
LagCount = reader.ReadInt32();
|
||||
Frame = reader.ReadInt32();
|
||||
}
|
||||
|
||||
public byte[] SaveStateBinary()
|
||||
|
|
Binary file not shown.
|
@ -1,6 +1,7 @@
|
|||
#include "ameteor.hpp"
|
||||
#include "ameteor/cartmem.hpp"
|
||||
#include "source/debug.hpp"
|
||||
#include <sstream>
|
||||
|
||||
#define EXPORT extern "C" __declspec(dllexport)
|
||||
|
||||
|
@ -131,8 +132,6 @@ EXPORT void libmeteor_frameadvance()
|
|||
AMeteor::Run(10000000);
|
||||
}
|
||||
|
||||
// TODO: serialize, unserialize
|
||||
|
||||
EXPORT void libmeteor_loadrom(const void *data, unsigned size)
|
||||
{
|
||||
AMeteor::_memory.LoadRom((const uint8_t*)data, size);
|
||||
|
@ -173,5 +172,35 @@ EXPORT void libmeteor_clearsaveram()
|
|||
AMeteor::_memory.DeleteCart();
|
||||
}
|
||||
|
||||
EXPORT int libmeteor_savestate(void **data, unsigned *size)
|
||||
{
|
||||
if (!data || !size)
|
||||
return 0;
|
||||
|
||||
std::ostringstream ss = std::ostringstream(std::ios_base::binary);
|
||||
AMeteor::SaveState(ss);
|
||||
|
||||
std::string s = ss.str();
|
||||
|
||||
void *ret = std::malloc(s.size());
|
||||
if (!ret)
|
||||
return 0;
|
||||
std::memcpy(ret, s.data(), s.size());
|
||||
*data = ret;
|
||||
*size = s.size();
|
||||
return 1;
|
||||
}
|
||||
|
||||
EXPORT void libmeteor_savestate_destroy(void *data)
|
||||
{
|
||||
std::free(data);
|
||||
}
|
||||
|
||||
EXPORT int libmeteor_loadstate(const void *data, unsigned size)
|
||||
{
|
||||
std::istringstream ss = std::istringstream(std::string((const char*)data, size), std::ios_base::binary);
|
||||
return AMeteor::LoadState(ss);
|
||||
}
|
||||
|
||||
// TODO: cartram and system bus memory domains
|
||||
|
||||
|
|
|
@ -519,7 +519,9 @@ namespace AMeteor
|
|||
bool b = m_brom;
|
||||
SS_WRITE_VAR(b);
|
||||
if (b)
|
||||
{
|
||||
SS_WRITE_DATA(m_brom, 0x00004000);
|
||||
}
|
||||
SS_WRITE_DATA(m_wbram, 0x00040000);
|
||||
SS_WRITE_DATA(m_wcram, 0x00008000);
|
||||
SS_WRITE_DATA(m_pram , 0x00000400);
|
||||
|
@ -545,9 +547,13 @@ namespace AMeteor
|
|||
bool b;
|
||||
SS_READ_VAR(b);
|
||||
if (b)
|
||||
{
|
||||
SS_READ_DATA(m_brom , 0x00004000);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnloadBios();
|
||||
}
|
||||
SS_READ_DATA(m_wbram, 0x00040000);
|
||||
SS_READ_DATA(m_wcram, 0x00008000);
|
||||
SS_READ_DATA(m_pram , 0x00000400);
|
||||
|
|
Loading…
Reference in New Issue