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