bizswan: savestates
This commit is contained in:
parent
8f87c2e854
commit
0ee073b71b
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using BizHawk.Common;
|
||||||
|
|
||||||
namespace BizHawk.Emulation.Cores.WonderSwan
|
namespace BizHawk.Emulation.Cores.WonderSwan
|
||||||
{
|
{
|
||||||
|
@ -105,6 +106,17 @@ namespace BizHawk.Emulation.Cores.WonderSwan
|
||||||
[DllImport(dd, CallingConvention = cc)]
|
[DllImport(dd, CallingConvention = cc)]
|
||||||
public static extern bool bizswan_getmemoryarea(IntPtr core, int index, out IntPtr name, out int size, out IntPtr data);
|
public static extern bool bizswan_getmemoryarea(IntPtr core, int index, out IntPtr name, out int size, out IntPtr data);
|
||||||
|
|
||||||
|
[DllImport(dd, CallingConvention = cc)]
|
||||||
|
public static extern int bizswan_binstatesize(IntPtr core);
|
||||||
|
[DllImport(dd, CallingConvention = cc)]
|
||||||
|
public static extern bool bizswan_binstatesave(IntPtr core, byte[] data, int length);
|
||||||
|
[DllImport(dd, CallingConvention = cc)]
|
||||||
|
public static extern bool bizswan_binstateload(IntPtr core, byte[] data, int length);
|
||||||
|
|
||||||
|
[DllImport(dd, CallingConvention = cc)]
|
||||||
|
public static extern void bizswan_txtstatesave(IntPtr core, [In]ref TextStateFPtrs ff);
|
||||||
|
[DllImport(dd, CallingConvention = cc)]
|
||||||
|
public static extern void bizswan_txtstateload(IntPtr core, [In]ref TextStateFPtrs ff);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// return a CPU register
|
/// return a CPU register
|
||||||
|
|
|
@ -56,6 +56,8 @@ namespace BizHawk.Emulation.Cores.WonderSwan
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var ss = _SyncSettings.GetNativeSettings();
|
var ss = _SyncSettings.GetNativeSettings();
|
||||||
|
if (deterministicEmulation)
|
||||||
|
ss.userealtime = false;
|
||||||
|
|
||||||
bool rotate = false;
|
bool rotate = false;
|
||||||
|
|
||||||
|
@ -70,6 +72,9 @@ namespace BizHawk.Emulation.Cores.WonderSwan
|
||||||
InitVideo(rotate);
|
InitVideo(rotate);
|
||||||
PutSettings(_Settings);
|
PutSettings(_Settings);
|
||||||
SetMemoryDomains();
|
SetMemoryDomains();
|
||||||
|
|
||||||
|
savebuff = new byte[BizSwan.bizswan_binstatesize(Core)];
|
||||||
|
savebuff2 = new byte[savebuff.Length + 13];
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@ -157,25 +162,81 @@ namespace BizHawk.Emulation.Cores.WonderSwan
|
||||||
|
|
||||||
#region Savestates
|
#region Savestates
|
||||||
|
|
||||||
|
JsonSerializer ser = new JsonSerializer() { Formatting = Formatting.Indented };
|
||||||
|
|
||||||
|
class TextStateData
|
||||||
|
{
|
||||||
|
public int Frame;
|
||||||
|
public int LagCount;
|
||||||
|
public bool IsLagFrame;
|
||||||
|
}
|
||||||
|
|
||||||
public void SaveStateText(TextWriter writer)
|
public void SaveStateText(TextWriter writer)
|
||||||
{
|
{
|
||||||
|
var s = new TextState<TextStateData>();
|
||||||
|
s.Prepare();
|
||||||
|
var ff = s.GetFunctionPointers();
|
||||||
|
BizSwan.bizswan_txtstatesave(Core, ref ff);
|
||||||
|
s.ExtraData.IsLagFrame = IsLagFrame;
|
||||||
|
s.ExtraData.LagCount = LagCount;
|
||||||
|
s.ExtraData.Frame = Frame;
|
||||||
|
|
||||||
|
ser.Serialize(writer, s);
|
||||||
|
// write extra copy of stuff we don't use
|
||||||
|
writer.WriteLine();
|
||||||
|
writer.WriteLine("Frame {0}", Frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadStateText(TextReader reader)
|
public void LoadStateText(TextReader reader)
|
||||||
{
|
{
|
||||||
|
var s = (TextState<TextStateData>)ser.Deserialize(reader, typeof(TextState<TextStateData>));
|
||||||
|
s.Prepare();
|
||||||
|
var ff = s.GetFunctionPointers();
|
||||||
|
BizSwan.bizswan_txtstateload(Core, ref ff);
|
||||||
|
IsLagFrame = s.ExtraData.IsLagFrame;
|
||||||
|
LagCount = s.ExtraData.LagCount;
|
||||||
|
Frame = s.ExtraData.Frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte[] savebuff;
|
||||||
|
byte[] savebuff2;
|
||||||
|
|
||||||
public void SaveStateBinary(BinaryWriter writer)
|
public void SaveStateBinary(BinaryWriter writer)
|
||||||
{
|
{
|
||||||
|
if (!BizSwan.bizswan_binstatesave(Core, savebuff, savebuff.Length))
|
||||||
|
throw new InvalidOperationException("bizswan_binstatesave() returned false!");
|
||||||
|
writer.Write(savebuff.Length);
|
||||||
|
writer.Write(savebuff);
|
||||||
|
|
||||||
|
// other variables
|
||||||
|
writer.Write(IsLagFrame);
|
||||||
|
writer.Write(LagCount);
|
||||||
|
writer.Write(Frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadStateBinary(BinaryReader reader)
|
public void LoadStateBinary(BinaryReader reader)
|
||||||
{
|
{
|
||||||
|
int length = reader.ReadInt32();
|
||||||
|
if (length != savebuff.Length)
|
||||||
|
throw new InvalidOperationException("Save buffer size mismatch!");
|
||||||
|
reader.Read(savebuff, 0, length);
|
||||||
|
if (!BizSwan.bizswan_binstateload(Core, savebuff, savebuff.Length))
|
||||||
|
throw new InvalidOperationException("bizswan_binstateload() returned false!");
|
||||||
|
|
||||||
|
// other variables
|
||||||
|
IsLagFrame = reader.ReadBoolean();
|
||||||
|
LagCount = reader.ReadInt32();
|
||||||
|
Frame = reader.ReadInt32();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] SaveStateBinary()
|
public byte[] SaveStateBinary()
|
||||||
{
|
{
|
||||||
return new byte[0];
|
var ms = new MemoryStream(savebuff2, true);
|
||||||
|
var bw = new BinaryWriter(ms);
|
||||||
|
SaveStateBinary(bw);
|
||||||
|
bw.Flush();
|
||||||
|
ms.Close();
|
||||||
|
return savebuff2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool BinarySaveStatesPreferred
|
public bool BinarySaveStatesPreferred
|
||||||
|
|
Binary file not shown.
|
@ -75,6 +75,7 @@
|
||||||
<ClCompile Include="..\gfx.cpp" />
|
<ClCompile Include="..\gfx.cpp" />
|
||||||
<ClCompile Include="..\interrupt.cpp" />
|
<ClCompile Include="..\interrupt.cpp" />
|
||||||
<ClCompile Include="..\memory.cpp" />
|
<ClCompile Include="..\memory.cpp" />
|
||||||
|
<ClCompile Include="..\newstate.cpp" />
|
||||||
<ClCompile Include="..\rtc.cpp" />
|
<ClCompile Include="..\rtc.cpp" />
|
||||||
<ClCompile Include="..\sound.cpp" />
|
<ClCompile Include="..\sound.cpp" />
|
||||||
<ClCompile Include="..\system.cpp" />
|
<ClCompile Include="..\system.cpp" />
|
||||||
|
@ -90,6 +91,7 @@
|
||||||
<ClInclude Include="..\memory.h" />
|
<ClInclude Include="..\memory.h" />
|
||||||
<ClInclude Include="..\msvc\inttypes.h" />
|
<ClInclude Include="..\msvc\inttypes.h" />
|
||||||
<ClInclude Include="..\msvc\stdint.h" />
|
<ClInclude Include="..\msvc\stdint.h" />
|
||||||
|
<ClInclude Include="..\newstate.h" />
|
||||||
<ClInclude Include="..\rtc.h" />
|
<ClInclude Include="..\rtc.h" />
|
||||||
<ClInclude Include="..\sound.h" />
|
<ClInclude Include="..\sound.h" />
|
||||||
<ClInclude Include="..\system.h" />
|
<ClInclude Include="..\system.h" />
|
||||||
|
|
|
@ -57,6 +57,9 @@
|
||||||
<ClCompile Include="..\system.cpp">
|
<ClCompile Include="..\system.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\newstate.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\eeprom.h">
|
<ClInclude Include="..\eeprom.h">
|
||||||
|
@ -101,6 +104,9 @@
|
||||||
<ClInclude Include="..\system.h">
|
<ClInclude Include="..\system.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\newstate.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\start.inc">
|
<None Include="..\start.inc">
|
||||||
|
|
|
@ -114,9 +114,6 @@ namespace MDFN_IEN_WSWAN
|
||||||
255,255,255,255
|
255,255,255,255
|
||||||
};
|
};
|
||||||
|
|
||||||
//static uint8 iEEPROM_Command, EEPROM_Command;
|
|
||||||
//static uint16 iEEPROM_Address, EEPROM_Address;
|
|
||||||
|
|
||||||
uint8 EEPROM::Read(uint32 A)
|
uint8 EEPROM::Read(uint32 A)
|
||||||
{
|
{
|
||||||
switch(A)
|
switch(A)
|
||||||
|
@ -203,4 +200,15 @@ namespace MDFN_IEN_WSWAN
|
||||||
iEEPROM[0x375] = Blood;
|
iEEPROM[0x375] = Blood;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYNCFUNC(EEPROM)
|
||||||
|
{
|
||||||
|
NSS(iEEPROM_Command);
|
||||||
|
NSS(EEPROM_Command);
|
||||||
|
NSS(iEEPROM_Address);
|
||||||
|
NSS(EEPROM_Address);
|
||||||
|
|
||||||
|
NSS(eeprom_size);
|
||||||
|
NSS(iEEPROM);
|
||||||
|
NSS(wsEEPROM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ public:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
System *sys;
|
System *sys;
|
||||||
|
template<bool isReader>void SyncState(NewState *ns);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
//#include <mednafen/video.h>
|
|
||||||
//#include <trio/trio.h>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
namespace MDFN_IEN_WSWAN
|
namespace MDFN_IEN_WSWAN
|
||||||
|
@ -602,4 +600,71 @@ namespace MDFN_IEN_WSWAN
|
||||||
std::memset(wsCols, 0, sizeof(wsCols));
|
std::memset(wsCols, 0, sizeof(wsCols));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYNCFUNC(GFX)
|
||||||
|
{
|
||||||
|
|
||||||
|
// TCACHE stuff. we invalidate the cache instead of saving it
|
||||||
|
if (isReader)
|
||||||
|
{
|
||||||
|
std::memset(wsTCacheUpdate, 0, sizeof(wsTCacheUpdate));
|
||||||
|
std::memset(wsTCacheUpdate2, 0, sizeof(wsTCacheUpdate2));
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
NSS(tiles);
|
||||||
|
NSS(wsTCache);
|
||||||
|
NSS(wsTCache2);
|
||||||
|
NSS(wsTCacheFlipped);
|
||||||
|
NSS(wsTCacheFlipped2);
|
||||||
|
NSS(wsTCacheUpdate);
|
||||||
|
NSS(wsTCacheUpdate2);
|
||||||
|
NSS(wsTileRow);
|
||||||
|
*/
|
||||||
|
|
||||||
|
NSS(wsVMode);
|
||||||
|
|
||||||
|
NSS(wsMonoPal);
|
||||||
|
NSS(wsColors);
|
||||||
|
NSS(wsCols);
|
||||||
|
|
||||||
|
NSS(ColorMapG);
|
||||||
|
NSS(ColorMap);
|
||||||
|
NSS(LayerEnabled);
|
||||||
|
|
||||||
|
NSS(wsLine);
|
||||||
|
|
||||||
|
NSS(SpriteTable);
|
||||||
|
NSS(SpriteCountCache);
|
||||||
|
NSS(DispControl);
|
||||||
|
NSS(BGColor);
|
||||||
|
NSS(LineCompare);
|
||||||
|
NSS(SPRBase);
|
||||||
|
NSS(SpriteStart);
|
||||||
|
NSS(SpriteCount);
|
||||||
|
NSS(FGBGLoc);
|
||||||
|
NSS(FGx0);
|
||||||
|
NSS(FGy0);
|
||||||
|
NSS(FGx1);
|
||||||
|
NSS(FGy1);
|
||||||
|
NSS(SPRx0);
|
||||||
|
NSS(SPRy0);
|
||||||
|
NSS(SPRx1);
|
||||||
|
NSS(SPRy1);
|
||||||
|
|
||||||
|
NSS(BGXScroll);
|
||||||
|
NSS(BGYScroll);
|
||||||
|
NSS(FGXScroll);
|
||||||
|
NSS(FGYScroll);
|
||||||
|
NSS(LCDControl);
|
||||||
|
NSS(LCDIcons);
|
||||||
|
|
||||||
|
NSS(BTimerControl);
|
||||||
|
NSS(HBTimerPeriod);
|
||||||
|
NSS(VBTimerPeriod);
|
||||||
|
|
||||||
|
NSS(HBCounter);
|
||||||
|
NSS(VBCounter);
|
||||||
|
NSS(VideoMode);
|
||||||
|
|
||||||
|
NSS(wsc); // mono / color
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,9 @@ private:
|
||||||
uint8 wsTCacheUpdate[512];
|
uint8 wsTCacheUpdate[512];
|
||||||
uint8 wsTCacheUpdate2[512];
|
uint8 wsTCacheUpdate2[512];
|
||||||
uint8 wsTileRow[8];
|
uint8 wsTileRow[8];
|
||||||
int wsVMode; // doesn't belong here?
|
|
||||||
// TCACHE/====================================
|
// TCACHE/====================================
|
||||||
|
int wsVMode;
|
||||||
|
|
||||||
uint32 wsMonoPal[16][4];
|
uint32 wsMonoPal[16][4];
|
||||||
uint32 wsColors[8];
|
uint32 wsColors[8];
|
||||||
uint32 wsCols[16][16];
|
uint32 wsCols[16][16];
|
||||||
|
@ -78,16 +79,9 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
System *sys;
|
System *sys;
|
||||||
|
template<bool isReader>void SyncState(NewState *ns);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ?
|
|
||||||
//extern uint32 dx_r,dx_g,dx_b,dx_sr,dx_sg,dx_sb;
|
|
||||||
//extern uint32 dx_bits,dx_pitch,cmov,dx_linewidth_blit,dx_buffer_line;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -74,4 +74,14 @@ namespace MDFN_IEN_WSWAN
|
||||||
Recalc();
|
Recalc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYNCFUNC(Interrupt)
|
||||||
|
{
|
||||||
|
NSS(IStatus);
|
||||||
|
NSS(IEnable);
|
||||||
|
NSS(IVectorBase);
|
||||||
|
|
||||||
|
NSS(IOn_Cache);
|
||||||
|
NSS(IOn_Which);
|
||||||
|
NSS(IVector_Cache);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ private:
|
||||||
void Recalc();
|
void Recalc();
|
||||||
public:
|
public:
|
||||||
System *sys;
|
System *sys;
|
||||||
|
template<bool isReader>void SyncState(NewState *ns);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,9 +27,6 @@
|
||||||
|
|
||||||
namespace MDFN_IEN_WSWAN
|
namespace MDFN_IEN_WSWAN
|
||||||
{
|
{
|
||||||
|
|
||||||
//extern uint16 WSButtonStatus;
|
|
||||||
|
|
||||||
void Memory::Write20(uint32 A, uint8 V)
|
void Memory::Write20(uint32 A, uint8 V)
|
||||||
{
|
{
|
||||||
uint32 offset, bank;
|
uint32 offset, bank;
|
||||||
|
@ -336,4 +333,34 @@ namespace MDFN_IEN_WSWAN
|
||||||
CommData = 0;
|
CommData = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYNCFUNC(Memory)
|
||||||
|
{
|
||||||
|
NSS(wsRAM);
|
||||||
|
//NSS(rom_size);
|
||||||
|
//PSS(wsCartROM, rom_size);
|
||||||
|
NSS(sram_size);
|
||||||
|
PSS(wsSRAM, sram_size);
|
||||||
|
|
||||||
|
NSS(WSButtonStatus);
|
||||||
|
NSS(Lagged);
|
||||||
|
|
||||||
|
NSS(ButtonWhich);
|
||||||
|
NSS(ButtonReadLatch);
|
||||||
|
|
||||||
|
NSS(DMASource);
|
||||||
|
NSS(DMADest);
|
||||||
|
NSS(DMALength);
|
||||||
|
NSS(DMAControl);
|
||||||
|
|
||||||
|
NSS(SoundDMASource);
|
||||||
|
NSS(SoundDMALength);
|
||||||
|
NSS(SoundDMAControl);
|
||||||
|
|
||||||
|
NSS(BankSelector);
|
||||||
|
|
||||||
|
NSS(CommControl);
|
||||||
|
NSS(CommData);
|
||||||
|
|
||||||
|
NSS(language);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
System *sys;
|
System *sys;
|
||||||
|
template<bool isReader>void SyncState(NewState *ns);
|
||||||
private:
|
private:
|
||||||
void CheckDMA();
|
void CheckDMA();
|
||||||
|
|
||||||
|
@ -66,8 +67,6 @@ enum
|
||||||
MEMORY_GSREG_BNK3SLCT,
|
MEMORY_GSREG_BNK3SLCT,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,6 +16,7 @@ SRCS = \
|
||||||
../system.cpp \
|
../system.cpp \
|
||||||
../tcache.cpp \
|
../tcache.cpp \
|
||||||
../v30mz.cpp \
|
../v30mz.cpp \
|
||||||
|
../newstate.cpp \
|
||||||
../Blip/Blip_Buffer.cpp
|
../Blip/Blip_Buffer.cpp
|
||||||
|
|
||||||
OBJS = $(SRCS:.cpp=.o)
|
OBJS = $(SRCS:.cpp=.o)
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include "newstate.h"
|
||||||
|
#include <cstring>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace MDFN_IEN_WSWAN {
|
||||||
|
|
||||||
|
NewStateDummy::NewStateDummy()
|
||||||
|
:length(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void NewStateDummy::Save(const void *ptr, size_t size, const char *name)
|
||||||
|
{
|
||||||
|
length += size;
|
||||||
|
}
|
||||||
|
void NewStateDummy::Load(void *ptr, size_t size, const char *name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
NewStateExternalBuffer::NewStateExternalBuffer(char *buffer, long maxlength)
|
||||||
|
:buffer(buffer), length(0), maxlength(maxlength)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewStateExternalBuffer::Save(const void *ptr, size_t size, const char *name)
|
||||||
|
{
|
||||||
|
if (maxlength - length >= (long)size)
|
||||||
|
{
|
||||||
|
std::memcpy(buffer + length, ptr, size);
|
||||||
|
}
|
||||||
|
length += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewStateExternalBuffer::Load(void *ptr, size_t size, const char *name)
|
||||||
|
{
|
||||||
|
char *dst = static_cast<char *>(ptr);
|
||||||
|
if (maxlength - length >= (long)size)
|
||||||
|
{
|
||||||
|
std::memcpy(dst, buffer + length, size);
|
||||||
|
}
|
||||||
|
length += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
NewStateExternalFunctions::NewStateExternalFunctions(const FPtrs *ff)
|
||||||
|
:Save_(ff->Save_),
|
||||||
|
Load_(ff->Load_),
|
||||||
|
EnterSection_(ff->EnterSection_),
|
||||||
|
ExitSection_(ff->ExitSection_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewStateExternalFunctions::Save(const void *ptr, size_t size, const char *name)
|
||||||
|
{
|
||||||
|
Save_(ptr, size, name);
|
||||||
|
}
|
||||||
|
void NewStateExternalFunctions::Load(void *ptr, size_t size, const char *name)
|
||||||
|
{
|
||||||
|
Load_(ptr, size, name);
|
||||||
|
}
|
||||||
|
void NewStateExternalFunctions::EnterSection(const char *name)
|
||||||
|
{
|
||||||
|
EnterSection_(name);
|
||||||
|
}
|
||||||
|
void NewStateExternalFunctions::ExitSection(const char *name)
|
||||||
|
{
|
||||||
|
ExitSection_(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
#ifndef NEWSTATE_H
|
||||||
|
#define NEWSTATE_H
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace MDFN_IEN_WSWAN {
|
||||||
|
|
||||||
|
class NewState
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void Save(const void *ptr, size_t size, const char *name) = 0;
|
||||||
|
virtual void Load(void *ptr, size_t size, const char *name) = 0;
|
||||||
|
virtual void EnterSection(const char *name) { }
|
||||||
|
virtual void ExitSection(const char *name) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
class NewStateDummy : public NewState
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
long length;
|
||||||
|
public:
|
||||||
|
NewStateDummy();
|
||||||
|
long GetLength() { return length; }
|
||||||
|
void Rewind() { length = 0; }
|
||||||
|
virtual void Save(const void *ptr, size_t size, const char *name);
|
||||||
|
virtual void Load(void *ptr, size_t size, const char *name);
|
||||||
|
};
|
||||||
|
|
||||||
|
class NewStateExternalBuffer : public NewState
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
char *const buffer;
|
||||||
|
long length;
|
||||||
|
const long maxlength;
|
||||||
|
public:
|
||||||
|
NewStateExternalBuffer(char *buffer, long maxlength);
|
||||||
|
long GetLength() { return length; }
|
||||||
|
void Rewind() { length = 0; }
|
||||||
|
bool Overflow() { return length > maxlength; }
|
||||||
|
virtual void Save(const void *ptr, size_t size, const char *name);
|
||||||
|
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:
|
||||||
|
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);
|
||||||
|
public:
|
||||||
|
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);
|
||||||
|
virtual void ExitSection(const char *name);
|
||||||
|
};
|
||||||
|
|
||||||
|
// defines and explicitly instantiates
|
||||||
|
#define SYNCFUNC(x)\
|
||||||
|
template void x::SyncState<false>(NewState *ns);\
|
||||||
|
template void x::SyncState<true>(NewState *ns);\
|
||||||
|
template<bool isReader>void x::SyncState(NewState *ns)
|
||||||
|
|
||||||
|
// N = normal variable
|
||||||
|
// P = pointer to fixed size data
|
||||||
|
// S = "sub object"
|
||||||
|
// T = "ptr to sub object"
|
||||||
|
// R = pointer, store its offset from some other pointer
|
||||||
|
// E = general purpose cased value "enum"
|
||||||
|
|
||||||
|
|
||||||
|
// first line is default value in converted enum; last line is default value in argument x
|
||||||
|
#define EBS(x,d) do { int _ttmp = (d); if (isReader) ns->Load(&_ttmp, sizeof(_ttmp), #x); if (0)
|
||||||
|
#define EVS(x,v,n) else if (!isReader && (x) == (v)) _ttmp = (n); else if (isReader && _ttmp == (n)) (x) = (v)
|
||||||
|
#define EES(x,d) else if (isReader) (x) = (d); if (!isReader) ns->Save(&_ttmp, sizeof(_ttmp), #x); } while (0)
|
||||||
|
|
||||||
|
#define RSS(x,b) do { if (isReader)\
|
||||||
|
{ ptrdiff_t _ttmp; ns->Load(&_ttmp, sizeof(_ttmp), #x); (x) = (_ttmp == (ptrdiff_t)0xdeadbeef ? 0 : (b) + _ttmp); }\
|
||||||
|
else\
|
||||||
|
{ ptrdiff_t _ttmp = (x) == 0 ? 0xdeadbeef : (x) - (b); ns->Save(&_ttmp, sizeof(_ttmp), #x); } } while (0)
|
||||||
|
|
||||||
|
#define PSS(x,s) do { if (isReader) ns->Load((x), (s), #x); else ns->Save((x), (s), #x); } while (0)
|
||||||
|
|
||||||
|
#define NSS(x) do { if (isReader) ns->Load(&(x), sizeof(x), #x); else ns->Save(&(x), sizeof(x), #x); } while (0)
|
||||||
|
|
||||||
|
#define SSS(x) do { ns->EnterSection(#x); (x).SyncState<isReader>(ns); ns->ExitSection(#x); } while (0)
|
||||||
|
|
||||||
|
#define TSS(x) do { ns->EnterSection(#x); (x)->SyncState<isReader>(ns); ns->ExitSection(#x); } while (0)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -112,4 +112,14 @@ namespace MDFN_IEN_WSWAN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYNCFUNC(RTC)
|
||||||
|
{
|
||||||
|
NSS(CurrentTime);
|
||||||
|
NSS(userealtime);
|
||||||
|
|
||||||
|
NSS(ClockCycleCounter);
|
||||||
|
NSS(wsCA15);
|
||||||
|
NSS(Command);
|
||||||
|
NSS(Data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ private:
|
||||||
uint8 Command, Data;
|
uint8 Command, Data;
|
||||||
public:
|
public:
|
||||||
System *sys;
|
System *sys;
|
||||||
|
template<bool isReader>void SyncState(NewState *ns);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -379,4 +379,35 @@ namespace MDFN_IEN_WSWAN
|
||||||
sbuf[y]->clear();
|
sbuf[y]->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYNCFUNC(Sound)
|
||||||
|
{
|
||||||
|
// don't need to save any of the blip stuff
|
||||||
|
|
||||||
|
NSS(period[4]);
|
||||||
|
NSS(volume[4]);
|
||||||
|
NSS(voice_volume);
|
||||||
|
|
||||||
|
NSS(sweep_step);
|
||||||
|
NSS(sweep_value);
|
||||||
|
NSS(noise_control);
|
||||||
|
NSS(control);
|
||||||
|
NSS(output_control);
|
||||||
|
|
||||||
|
NSS(sweep_8192_divider);
|
||||||
|
NSS(sweep_counter);
|
||||||
|
NSS(SampleRAMPos);
|
||||||
|
|
||||||
|
NSS(sample_cache);
|
||||||
|
|
||||||
|
NSS(last_v_val);
|
||||||
|
|
||||||
|
NSS(HyperVoice);
|
||||||
|
NSS(last_hv_val);
|
||||||
|
|
||||||
|
NSS(period_counter);
|
||||||
|
NSS(last_val);
|
||||||
|
NSS(sample_pos);
|
||||||
|
NSS(nreg);
|
||||||
|
NSS(last_ts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
System *sys;
|
System *sys;
|
||||||
|
template<bool isReader>void SyncState(NewState *ns);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -237,6 +237,7 @@ namespace MDFN_IEN_WSWAN
|
||||||
{
|
{
|
||||||
return eeprom.ieeprom_size + eeprom.eeprom_size + memory.sram_size;
|
return eeprom.ieeprom_size + eeprom.eeprom_size + memory.sram_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool System::SaveRamLoad(const uint8 *data, int size)
|
bool System::SaveRamLoad(const uint8 *data, int size)
|
||||||
{
|
{
|
||||||
if (size != SaveRamSize())
|
if (size != SaveRamSize())
|
||||||
|
@ -294,6 +295,18 @@ namespace MDFN_IEN_WSWAN
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYNCFUNC(System)
|
||||||
|
{
|
||||||
|
SSS(gfx);
|
||||||
|
SSS(memory);
|
||||||
|
SSS(eeprom);
|
||||||
|
SSS(rtc);
|
||||||
|
SSS(sound);
|
||||||
|
SSS(cpu);
|
||||||
|
SSS(interrupt);
|
||||||
|
|
||||||
|
NSS(rotate);
|
||||||
|
}
|
||||||
|
|
||||||
EXPORT System *bizswan_new()
|
EXPORT System *bizswan_new()
|
||||||
{
|
{
|
||||||
|
@ -352,4 +365,36 @@ namespace MDFN_IEN_WSWAN
|
||||||
return s->GetMemoryArea(index, *name, *size, *data);
|
return s->GetMemoryArea(index, *name, *size, *data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EXPORT int bizswan_binstatesize(System *s)
|
||||||
|
{
|
||||||
|
NewStateDummy dummy;
|
||||||
|
s->SyncState<false>(&dummy);
|
||||||
|
return dummy.GetLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT int bizswan_binstatesave(System *s, char *data, int length)
|
||||||
|
{
|
||||||
|
NewStateExternalBuffer saver(data, length);
|
||||||
|
s->SyncState<false>(&saver);
|
||||||
|
return !saver.Overflow() && saver.GetLength() == length;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT int bizswan_binstateload(System *s, const char *data, int length)
|
||||||
|
{
|
||||||
|
NewStateExternalBuffer loader(const_cast<char *>(data), length);
|
||||||
|
s->SyncState<true>(&loader);
|
||||||
|
return !loader.Overflow() && loader.GetLength() == length;
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT void bizswan_txtstatesave(System *s, FPtrs *ff)
|
||||||
|
{
|
||||||
|
NewStateExternalFunctions saver(ff);
|
||||||
|
s->SyncState<false>(&saver);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPORT void bizswan_txtstateload(System *s, FPtrs *ff)
|
||||||
|
{
|
||||||
|
NewStateExternalFunctions loader(ff);
|
||||||
|
s->SyncState<true>(&loader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,11 @@ class System;
|
||||||
struct SyncSettings;
|
struct SyncSettings;
|
||||||
struct Settings;
|
struct Settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "wswan.h"
|
#include "wswan.h"
|
||||||
|
|
||||||
|
#include "newstate.h"
|
||||||
|
|
||||||
#include "gfx.h"
|
#include "gfx.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "eeprom.h"
|
#include "eeprom.h"
|
||||||
|
@ -18,7 +21,7 @@ struct Settings;
|
||||||
#include "interrupt.h"
|
#include "interrupt.h"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
|
||||||
namespace MDFN_IEN_WSWAN
|
namespace MDFN_IEN_WSWAN
|
||||||
{
|
{
|
||||||
class System
|
class System
|
||||||
|
@ -52,6 +55,8 @@ public:
|
||||||
Interrupt interrupt;
|
Interrupt interrupt;
|
||||||
|
|
||||||
bool rotate; // rotate screen and controls left 90
|
bool rotate; // rotate screen and controls left 90
|
||||||
|
|
||||||
|
template<bool isReader>void SyncState(NewState *ns);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SyncSettings
|
struct SyncSettings
|
||||||
|
|
|
@ -1027,4 +1027,25 @@ namespace MDFN_IEN_WSWAN
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SYNCFUNC(V30MZ)
|
||||||
|
{
|
||||||
|
NSS(old_CS);
|
||||||
|
NSS(old_IP);
|
||||||
|
NSS(timestamp);
|
||||||
|
NSS(ICount);
|
||||||
|
|
||||||
|
NSS(I);
|
||||||
|
NSS(InHLT);
|
||||||
|
|
||||||
|
NSS(prefix_base);
|
||||||
|
NSS(seg_prefix);
|
||||||
|
|
||||||
|
NSS(parity_table);
|
||||||
|
|
||||||
|
NSS(EA);
|
||||||
|
NSS(EO);
|
||||||
|
NSS(E16);
|
||||||
|
|
||||||
|
NSS(Mod_RM);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,6 +141,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
System *sys;
|
System *sys;
|
||||||
|
template<bool isReader>void SyncState(NewState *ns);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
|
|
||||||
#include <mednafen/types.h>
|
#include <mednafen/types.h>
|
||||||
|
|
||||||
#include "interrupt.h"
|
|
||||||
|
|
||||||
namespace MDFN_IEN_WSWAN
|
namespace MDFN_IEN_WSWAN
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue