diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 146bc35135..d512751a0c 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -3305,6 +3305,13 @@ namespace BizHawk.Client.EmuHawk } nextEmulator = new N64(nextComm, game, rom.RomData, video_settings, SaveType); break; + + case "DEBUG": + if (VersionInfo.INTERIM) + { + nextEmulator = LibRetroEmulator.CreateDebug(nextComm, rom.RomData); + } + break; } } diff --git a/BizHawk.Emulation.Common/Database/Database.cs b/BizHawk.Emulation.Common/Database/Database.cs index 5ab93661c2..b47c5bf059 100644 --- a/BizHawk.Emulation.Common/Database/Database.cs +++ b/BizHawk.Emulation.Common/Database/Database.cs @@ -178,6 +178,10 @@ namespace BizHawk.Emulation.Common case ".N64": Game.System = "N64"; break; + + case ".DEBUG": + Game.System = "DEBUG"; + break; } Game.Name = Path.GetFileNameWithoutExtension(fileName).Replace('_', ' '); diff --git a/BizHawk.Emulation.Common/LibRetro.cs b/BizHawk.Emulation.Common/LibRetro.cs index bb1f835de1..fb2a80c560 100644 --- a/BizHawk.Emulation.Common/LibRetro.cs +++ b/BizHawk.Emulation.Common/LibRetro.cs @@ -312,9 +312,9 @@ namespace BizHawk.Emulation.Common public string library_name; public string library_version; public string valid_extensions; - [MarshalAs(UnmanagedType.U8)] + [MarshalAs(UnmanagedType.U1)] public bool need_fullpath; - [MarshalAs(UnmanagedType.U8)] + [MarshalAs(UnmanagedType.U1)] public bool block_extract; } @@ -355,7 +355,7 @@ namespace BizHawk.Emulation.Common // standard callbacks [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - [return:MarshalAs(UnmanagedType.U8)] + [return:MarshalAs(UnmanagedType.U1)] public delegate bool retro_environment_t(RETRO_ENVIRONMENT cmd, IntPtr data); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void retro_video_refresh_t(IntPtr data, uint width, uint height, uint pitch); @@ -400,20 +400,20 @@ namespace BizHawk.Emulation.Common [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate uint epretro_serialize_size(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - [return: MarshalAs(UnmanagedType.U8)] + [return: MarshalAs(UnmanagedType.U1)] public delegate bool epretro_serialize(IntPtr data, uint size); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - [return: MarshalAs(UnmanagedType.U8)] + [return: MarshalAs(UnmanagedType.U1)] public delegate bool epretro_unserialize(IntPtr data, uint size); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void epretro_cheat_reset(); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - public delegate void epretro_cheat_set(uint index, [MarshalAs(UnmanagedType.U8)]bool enabled, string code); + public delegate void epretro_cheat_set(uint index, [MarshalAs(UnmanagedType.U1)]bool enabled, string code); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - [return: MarshalAs(UnmanagedType.U8)] + [return: MarshalAs(UnmanagedType.U1)] public delegate bool epretro_load_game(ref retro_game_info game); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - [return: MarshalAs(UnmanagedType.U8)] + [return: MarshalAs(UnmanagedType.U1)] public delegate bool epretro_load_game_special(uint game_type, ref retro_game_info info, uint num_info); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void epretro_unload_game(); diff --git a/BizHawk.Emulation.Common/LibRetroEmulator.cs b/BizHawk.Emulation.Common/LibRetroEmulator.cs index 67fcdcd201..069c29eeed 100644 --- a/BizHawk.Emulation.Common/LibRetroEmulator.cs +++ b/BizHawk.Emulation.Common/LibRetroEmulator.cs @@ -37,7 +37,9 @@ namespace BizHawk.Emulation.Common case LibRetro.RETRO_ENVIRONMENT.SET_PIXEL_FORMAT: { LibRetro.RETRO_PIXEL_FORMAT fmt = 0; - Marshal.PtrToStructure(data, fmt); + int[] tmp = new int[1]; + Marshal.Copy(data, tmp, 0, 1); + fmt = (LibRetro.RETRO_PIXEL_FORMAT)tmp[0]; switch (fmt) { case LibRetro.RETRO_PIXEL_FORMAT.RGB565: @@ -103,6 +105,29 @@ namespace BizHawk.Emulation.Common private LibRetro retro; + public static LibRetroEmulator CreateDebug(CoreComm nextComm, byte[] debugfile) + { + System.IO.TextReader tr = new System.IO.StreamReader(new System.IO.MemoryStream(debugfile, false)); + string modulename = tr.ReadLine(); + string romname = tr.ReadLine(); + + byte[] romdata = System.IO.File.ReadAllBytes(romname); + + var emu = new LibRetroEmulator(nextComm, modulename); + try + { + if (!emu.Load(romdata)) + throw new Exception("LibRetroEmulator.Load() failed"); + // ... + } + catch + { + emu.Dispose(); + throw; + } + return emu; + } + public LibRetroEmulator(CoreComm nextComm, string modulename) { retro_environment_cb = new LibRetro.retro_environment_t(retro_environment); @@ -113,27 +138,35 @@ namespace BizHawk.Emulation.Common retro_input_state_cb = new LibRetro.retro_input_state_t(retro_input_state); retro = new LibRetro(modulename); - CoreComm = nextComm; + try + { + CoreComm = nextComm; - retro.retro_set_environment(retro_environment_cb); - retro.retro_init(); - retro.retro_set_video_refresh(retro_video_refresh_cb); - retro.retro_set_audio_sample(retro_audio_sample_cb); - retro.retro_set_audio_sample_batch(retro_audio_sample_batch_cb); - retro.retro_set_input_poll(retro_input_poll_cb); - retro.retro_set_input_state(retro_input_state_cb); + LibRetro.retro_system_info sys = new LibRetro.retro_system_info(); + retro.retro_get_system_info(ref sys); + + if (sys.need_fullpath) + throw new ArgumentException("This libretro core needs filepaths"); + if (sys.block_extract) + throw new ArgumentException("This libretro needs non-blocked extract"); + + retro.retro_set_environment(retro_environment_cb); + retro.retro_init(); + retro.retro_set_video_refresh(retro_video_refresh_cb); + retro.retro_set_audio_sample(retro_audio_sample_cb); + retro.retro_set_audio_sample_batch(retro_audio_sample_batch_cb); + retro.retro_set_input_poll(retro_input_poll_cb); + retro.retro_set_input_state(retro_input_state_cb); + } + catch + { + retro.Dispose(); + throw; + } } public bool Load(byte[] data) { - LibRetro.retro_system_info sys = new LibRetro.retro_system_info(); - retro.retro_get_system_info(ref sys); - - if (sys.need_fullpath) - throw new ArgumentException("This libretro core needs filepaths"); - if (sys.block_extract) - throw new ArgumentException("This libretro needs non-blocked extract"); - LibRetro.retro_game_info gi = new LibRetro.retro_game_info(); fixed (byte* p = &data[0]) {