From 9bea9875a81dcca8d7a06e1e4fd0f2a4e393db45 Mon Sep 17 00:00:00 2001 From: zeromus Date: Tue, 18 Apr 2017 03:17:11 -0500 Subject: [PATCH] libretro - fix saveram --- .../BizHawk.Emulation.Cores.csproj | 1 + .../Libretro/LibretroApi_Enums.cs | 11 +++ .../Libretro/LibretroApi_QUERY.cs | 22 ++++++ .../Libretro/LibretroApi_SIG.cs | 14 ++-- .../Libretro/LibretroCore.cs | 68 +++++++++++++----- LibretroBridge/vs2015/LibretroBridge.cpp | 9 ++- output/dll/LibretroBridge.dll | Bin 112640 -> 112640 bytes 7 files changed, 95 insertions(+), 30 deletions(-) create mode 100644 BizHawk.Emulation.Cores/Libretro/LibretroApi_QUERY.cs 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 dadf207262d52dbcf234661b7cc373483d055a08..e23c9fe43ef5f1c48f2d1642572f879d611d4262 100644 GIT binary patch delta 3594 zcmeH}eN+_J6~N~X3$6;d%7=h}3oMEf*O`Icof%*UEhL7hU6ddvBF89H%!fh4rc|*k zt{+R6wZtVpS_z_JLoD%-ERod^4@PP*(j1%E9MX7Am%$pp=X-1HYKv@D` z^Qb--tGN#``=QyhklhC0^}Nij3!#UPc*wHbf3s^nw7OT@b6}aL z$=)>s$FbIZ*dNF7W5W+B+IP%z_vO?6=sbDsmw?Ihj(@Cz(gP=|z~Ql-I2!=19_jVt zewcQvW8)Os*W$_P^3KC_zniiW?|18F0xawNyBbaff=rsiz%`9wL1U>Y%kq_W8p5F( z$meR9MS5q$F!YhnVj+a|L_il*lIlpvOI-DkEZcijPOB#0_ZaH=vNfdj|JeiY1| z_U?!hJZc}NNmUfEP)lBq0$t#mWaV~&&R*ZYM#yJTkN`=57q?L;Z)TG zHR9PBRF7xhMsgw++UXlZq)ZE;blRjOH>cMgE)8i5zCu%Kv-DIH_ z^w2_{(?S^R9}_7R{}@%CQ_;Hf)uX{cQPvRI8oJ6ER)OQN_(tw~mFMxe^UhOpse^QC z!32e5PzzD?`5R<<99#oJzKDZZs3ue6VR7WLuSex$nOGv_qVxO@pU_-JbXb!n*ai2k|z>?r74!U z5`cps(wzW>Roo(6c#A<(G$9pz$piWt)JqCAY+$;8Ns>y;=c_W{m*zSA1`6!`q($2PKSg(mkYD&OL}acxwV z%TzMst0%W~5D)%Dod`OZNfsqSBz<9!EK7vrRc&96%HAY=iQe8CDa&JJoq0O7YiXb} zXCS55SF8A!EB;*c-*??X*H*<oj0+76vJW~|j(Zl5Nnar9p$LOM=6`%aXz#}4 zEc9jBVG3Rtb_%jeiWtOR{Ui7le+EOw-;~NgwBX2>=dPbTlq%a zqf3@33DM;1-4L=u`=Bdt+=ZX||Agl~@q`kNE0=O$%leA3(iMtr@?S+?qS)}Ch2-vm zkOjqmz}10n{pPXI6eY9*ZEBpV30taSvk})G=p@Vb!b4NbaN#TST1R&7g`a_!oZAZ_ z&`bWh7cK?uK0M(>*+yR52aiPdqlyEid?@P_GosY&C4bq6A6~5kmd~^_kH@S>sYBYx zP6s5JJOG(UrSRJIy;N*cL*$;F6zm;(-|L(W2Dd2#g_S8YR99}igU@&Yk95gfexgQ<5EI3P zA|o2aG%-_rSbR*(74yYHvFb^2lUOEN#T}weBx0l3BDRSg;%V`m_`cXLUK0nzLGe5B zk+kJ$tJ0oNt4}+T)}3}E?QU9FdUE=b^o{A(^aJUw>1WfgrhlLApP|n%W@Kd)WRzxD zGxlU0$oMG3U>40Q&H3gH=AC9@e%;(u zW^~L$Oe&MkWRaaGVR43+>0-K>9;TP+V=gmSn11FebDbGre9RqYh`GyfEYF(RTsEIA zVoO;oyMwJ}Ygvw4#XZZlbY46OgZ{J%$e9j&*R_%%IA+wyxV+xo; zrkJTb1cW9pd(rkUx$R+UDF8H!c0(X5tDXERv~Th7{8ho0?Vy=*tz%U))$uvgh3 zHjvYB3}@k<;mWu=u7PXhyj(vw%tfT=QZh;MDToU!G^{sN8f=DILz|(q@Dwz_zX2!x BvT*N*7t zrLYkTjrGtiA}Z{%>MHIY!#SOZK}69lQVe|DKuO z{l4?P&f}hw+$wKSl{cs}7}&(!?hx2IeV`qfR)%59+&dv7>AvH73Wo`+{%+>-p#kZFxMBx>6xyai zpZij=9fstzk~hOx=CFL`#aw_SIlN*gi{rVshXq5e`_Qf@pu>G*S0VJfpL8yR61l~B z=0RM?I`@G^_=2Hb4S%C8kx(DvC7`j_l`Zk4_voWw zCqQja&n%b@bRZh~U^i`yf!wr>3;cfP`zlwtW{qbZ>TCSv>N?fCz2}u&)w@+FJ`4AT=y5DA}7h|J!9k1P9Lu>Snc@i1VR@(6$V%+;>Q z3S5WXBmOw$y@>58*T`mnNjANm1V)Ib3zH$14Y*8~C&PE}C7q{*L^w+y*TTY>+MmY# zhqJIm=Ett{xBvBE!`a(kJA5LviFKhZ*T%sR*upq<~JW3RV$*fHFb`RkZV6EPj0{0TYu zk!{S6&9jmgrhoud^!F*iv3-Pok^(wdxi1y+D{m|S&7%uJllbsmspxQzJ`44!S#=*UCV|u`#l#Gf2rbcME@_Y5p(k5+oNXMXHfz zAv=&-WG~W&bRp-Ei^w1{f{Y3@JihK^l-lNH=m0`3xCGMiJ&1<|6S3 zL9&ho0JEwG9s=i@%B;Dd(L4m2vUJc4p+120A)QDSVn^^t;Fp%T`(~cfVG$dmdK*{f z#6hr4`P8V-L{^}0#sBz1(cXv2h3G4E!ZhqEi9I1zaE%Qe;;@nqm^dVxf)i#XDy1J0 z^NTk*@;7eUUb5k(=ktG4?kFpFA>lb0=M21CPQWJy-(~;Gw5#;6iBIfk`LIi?seVSQ_I) z71zoHx8nO#%!pF9pPqaTBKFn7itsXYDIrxTmmnAE`dXMDer(cw<`?r@weU@35neZK zpgTsHgadWuT~yP$I*=kqu&bDTD5u6Lp$BUrqQ_eY%>k-@ymO7oGihlJ1m|Sw?#^WD zgv`UmE5!mQ@!^-78f{5PUmAYJ&A~f{w4$y-ENIV0>_{H6k^ZM1o(xs?aH`=-_CVbK zZ#LfSmtTkCpzeJz5LFqaPtzCZYxKMI$MoI$3;GfLs6N1uXh=0!4B3XK4C@RV49^?N z4Aq9ChEs;qhQAvI3^xq74SvIPxPcr(A4U&`An`KS1Gd?8=K@8W;Qzri2i+xR2= z3H}s+n(yO3;4kn4{6F|__>M8-!w^RM;l` zR;Utc1eb7BI4=wcgTfWzn&1^~3U>rX3=$s@!^J2uUQ8C}ibT|lCNWE_Tr1{_MPjMw z5MLH|ihIN+u|;eXPl%_)X(qL4hAGpOYuaq8G95B?nZ7XnU;=ZBS#Mr#E-}AiZZ>zD zKQRAjzGYTfqAlqby~So(ZP{nJY5Ca_W{t9HtrqKA>kHN$)^DtSt3@i7wn{GPEvZd9 zA)S^!mA;jRi8LaON@Eg3fT_Tfsv_|uiKLQrvVah>i15Trvd9vWO;!*)$t8Jo({Wgs zaD({BI0@&XxI`|U({mECjM#?O*Nj@nerNluh z$PQ9Xnn)|@Af2R(^pZYuiFk2RV&kSybq%^sU9awpZcyjbMQ8GvOQ@+Ek~M|;9r`MLv%VD%=0!cj^ptc% J6EqU_e*rpGo-P0Y