diff --git a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
index 40b2b1699e..c2e3a9f130 100644
--- a/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
+++ b/BizHawk.Emulation.Cores/BizHawk.Emulation.Cores.csproj
@@ -1193,6 +1193,7 @@
+
diff --git a/BizHawk.Emulation.Cores/Libretro/LibretroApi_Enums.cs b/BizHawk.Emulation.Cores/Libretro/LibretroApi_Enums.cs
index 46883b919f..8b861eb05b 100644
--- a/BizHawk.Emulation.Cores/Libretro/LibretroApi_Enums.cs
+++ b/BizHawk.Emulation.Cores/Libretro/LibretroApi_Enums.cs
@@ -13,6 +13,7 @@ namespace BizHawk.Emulation.Cores.Libretro
Resume,
QUERY_FIRST,
+ QUERY_GetMemory,
QUERY_LAST,
CMD_FIRST,
@@ -32,6 +33,16 @@ namespace BizHawk.Emulation.Cores.Libretro
BRK_InputState,
};
+
+ public enum RETRO_MEMORY
+ {
+ SAVE_RAM = 0,
+ RTC = 1,
+ SYSTEM_RAM = 2,
+ VIDEO_RAM = 3,
+ };
+
+
public enum RETRO_DEVICE
{
NONE = 0,
diff --git a/BizHawk.Emulation.Cores/Libretro/LibretroApi_QUERY.cs b/BizHawk.Emulation.Cores/Libretro/LibretroApi_QUERY.cs
new file mode 100644
index 0000000000..7c25bc5aa5
--- /dev/null
+++ b/BizHawk.Emulation.Cores/Libretro/LibretroApi_QUERY.cs
@@ -0,0 +1,22 @@
+using System;
+
+using BizHawk.Common;
+
+namespace BizHawk.Emulation.Cores.Libretro
+{
+ unsafe partial class LibretroApi
+ {
+ bool Handle_SIG(eMessage msg)
+ {
+ switch (msg)
+ {
+ default:
+ return false;
+
+ } //switch(msg)
+
+ Message(eMessage.Resume);
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/BizHawk.Emulation.Cores/Libretro/LibretroApi_SIG.cs b/BizHawk.Emulation.Cores/Libretro/LibretroApi_SIG.cs
index 7c25bc5aa5..3cd7fb888d 100644
--- a/BizHawk.Emulation.Cores/Libretro/LibretroApi_SIG.cs
+++ b/BizHawk.Emulation.Cores/Libretro/LibretroApi_SIG.cs
@@ -6,17 +6,11 @@ namespace BizHawk.Emulation.Cores.Libretro
{
unsafe partial class LibretroApi
{
- bool Handle_SIG(eMessage msg)
+ public Tuple QUERY_GetMemory(RETRO_MEMORY mem)
{
- switch (msg)
- {
- default:
- return false;
-
- } //switch(msg)
-
- Message(eMessage.Resume);
- return true;
+ comm->value = (uint)mem;
+ Message(eMessage.QUERY_GetMemory);
+ return Tuple.Create(new IntPtr(comm->buf[(int)BufId.Param0]), comm->buf_size[(int)BufId.Param0]);
}
}
}
\ No newline at end of file
diff --git a/BizHawk.Emulation.Cores/Libretro/LibretroCore.cs b/BizHawk.Emulation.Cores/Libretro/LibretroCore.cs
index 79d072d571..a25c852283 100644
--- a/BizHawk.Emulation.Cores/Libretro/LibretroCore.cs
+++ b/BizHawk.Emulation.Cores/Libretro/LibretroCore.cs
@@ -26,7 +26,7 @@ namespace BizHawk.Emulation.Cores.Libretro
public LibretroCore(CoreComm nextComm, string corePath)
{
- //TODO: codepath just for inrospection (lighter weight; no speex, no controls, etc.)
+ //TODO: codepath just for introspection (lighter weight; no speex, no controls, etc.)
ServiceProvider = new BasicServiceProvider(this);
_SyncSettings = new SyncSettings();
@@ -45,12 +45,17 @@ namespace BizHawk.Emulation.Cores.Libretro
//I dont even know for sure what paths I should use until... (what?)
- //not sure about each of these.. but we'll be doing things different than retroarch.
- //i think this may play better with our model [although we might could use a different save directory]
- api.CopyAscii(LibretroApi.BufId.SystemDirectory, Path.GetDirectoryName(corePath));
- api.CopyAscii(LibretroApi.BufId.SaveDirectory, Path.GetDirectoryName(corePath));
- api.CopyAscii(LibretroApi.BufId.CoreDirectory, Path.GetDirectoryName(corePath));
- api.CopyAscii(LibretroApi.BufId.CoreAssetsDirectory, Path.GetDirectoryName(corePath));
+ //not sure about each of these.. but we may be doing things different than retroarch.
+ //I wish I could initialize these with placeholders during a separate introspection codepath..
+ string SystemDirectory = CoreComm.CoreFileProvider.GetRetroSystemPath();
+ string SaveDirectory = CoreComm.CoreFileProvider.GetRetroSaveRAMDirectory();
+ string CoreDirectory = Path.GetDirectoryName(corePath);
+ string CoreAssetsDirectory = Path.GetDirectoryName(corePath);
+
+ api.CopyAscii(LibretroApi.BufId.SystemDirectory, SystemDirectory);
+ api.CopyAscii(LibretroApi.BufId.SaveDirectory, SaveDirectory);
+ api.CopyAscii(LibretroApi.BufId.CoreDirectory, CoreDirectory);
+ api.CopyAscii(LibretroApi.BufId.CoreAssetsDirectory, CoreAssetsDirectory);
api.CMD_SetEnvironment();
@@ -244,27 +249,52 @@ namespace BizHawk.Emulation.Cores.Libretro
public bool DeterministicEmulation { get { return false; } }
public string BoardName { get; private set; }
- public bool SaveRamModified
- {
- get
- {
- //TODO
- return false;
- }
- }
+ #region ISaveRam
+ //TODO - terrible things will happen if this changes at runtime
+
+ byte[] saverambuff = new byte[0];
public byte[] CloneSaveRam()
{
- //TODO
- return new byte[] { };
- }
+ var mem = api.QUERY_GetMemory(LibretroApi.RETRO_MEMORY.SAVE_RAM);
+ var buf = new byte[mem.Item2];
+ Marshal.Copy(mem.Item1, buf, 0, mem.Item2);
+ return buf;
+ }
public void StoreSaveRam(byte[] data)
{
- //TODO
+ var mem = api.QUERY_GetMemory(LibretroApi.RETRO_MEMORY.SAVE_RAM);
+
+ //bail if the size is 0
+ if (mem.Item2 == 0)
+ return;
+
+ Marshal.Copy(data, 0, mem.Item1, mem.Item2);
}
+ public bool SaveRamModified
+ {
+ [FeatureNotImplemented]
+ get
+ {
+ //if we dont have saveram, it isnt modified. otherwise, assume it is
+ var mem = api.QUERY_GetMemory(LibretroApi.RETRO_MEMORY.SAVE_RAM);
+
+ //bail if the size is 0
+ if (mem.Item2 == 0)
+ return false;
+
+ return true;
+ }
+
+ [FeatureNotImplemented]
+ set { throw new NotImplementedException(); }
+ }
+
+ #endregion
+
public void ResetCounters()
{
timeFrameCounter = 0;
diff --git a/LibretroBridge/vs2015/LibretroBridge.cpp b/LibretroBridge/vs2015/LibretroBridge.cpp
index 234b310932..50698aab6f 100644
--- a/LibretroBridge/vs2015/LibretroBridge.cpp
+++ b/LibretroBridge/vs2015/LibretroBridge.cpp
@@ -78,6 +78,7 @@ enum eMessage : s32
Resume,
QUERY_FIRST,
+ QUERY_GetMemory,
QUERY_LAST,
CMD_FIRST,
@@ -740,6 +741,12 @@ void cmd_SetEnvironment()
comm.funs.retro_set_environment(retro_environment);
}
+void query_GetMemory()
+{
+ comm.buf_size[BufId::Param0] = comm.funs.retro_get_memory_size(comm.value);
+ comm.buf[BufId::Param0] = comm.funs.retro_get_memory_data(comm.value);
+}
+
const Action kHandlers_CMD[] = {
cmd_SetEnvironment,
cmd_LoadNoGame,
@@ -753,7 +760,7 @@ const Action kHandlers_CMD[] = {
};
const Action kHandlers_QUERY[] = {
- nullptr
+ query_GetMemory,
};
//------------------------------------------------
diff --git a/output/dll/LibretroBridge.dll b/output/dll/LibretroBridge.dll
index dadf207262..e23c9fe43e 100644
Binary files a/output/dll/LibretroBridge.dll and b/output/dll/LibretroBridge.dll differ