public LibRetro(string modulename) { // like many other emu cores, libretros are in general single instance, so we track some things lock (AttachedCores) { IntPtr newmodule = Win32.LoadLibrary(modulename); if (newmodule == IntPtr.Zero) { throw new Exception(string.Format("LoadLibrary(\"{0}\") returned NULL", modulename)); } if (AttachedCores.ContainsKey(newmodule)) { // this core is already loaded, so we must detatch the old instance LibRetro martyr = AttachedCores[newmodule]; martyr.retro_deinit(); martyr.ClearAllEntryPoints(); martyr.hModule = IntPtr.Zero; Win32.FreeLibrary(newmodule); // decrease ref count by 1 } AttachedCores[newmodule] = this; hModule = newmodule; if (!ConnectAllEntryPoints()) { ClearAllEntryPoints(); Win32.FreeLibrary(hModule); hModule = IntPtr.Zero; throw new Exception("ConnectAllEntryPoints() failed. The console may contain more details."); } } }
public void Dispose() { if (resampler != null) { resampler.Dispose(); resampler = null; } if (retro != null) { retro.Dispose(); retro = null; } }
public void Dispose() { if (resampler != null) { resampler.Dispose(); resampler = null; } if (retro != null) { retro.Dispose(); retro = null; } unmanagedResources.Dispose(); unmanagedResources = null; }
public LibRetroEmulator(CoreComm nextComm, string modulename) { ServiceProvider = new BasicServiceProvider(this); retro_environment_cb = new LibRetro.retro_environment_t(retro_environment); retro_video_refresh_cb = new LibRetro.retro_video_refresh_t(retro_video_refresh); retro_audio_sample_cb = new LibRetro.retro_audio_sample_t(retro_audio_sample); retro_audio_sample_batch_cb = new LibRetro.retro_audio_sample_batch_t(retro_audio_sample_batch); retro_input_poll_cb = new LibRetro.retro_input_poll_t(retro_input_poll); retro_input_state_cb = new LibRetro.retro_input_state_t(retro_input_state); retro = new LibRetro(modulename); try { CoreComm = nextComm; 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 LibRetroEmulator(CoreComm nextComm, string modulename) { ServiceProvider = new BasicServiceProvider(this); retro_environment_cb = new LibRetro.retro_environment_t(retro_environment); retro_video_refresh_cb = new LibRetro.retro_video_refresh_t(retro_video_refresh); retro_audio_sample_cb = new LibRetro.retro_audio_sample_t(retro_audio_sample); retro_audio_sample_batch_cb = new LibRetro.retro_audio_sample_batch_t(retro_audio_sample_batch); retro_input_poll_cb = new LibRetro.retro_input_poll_t(retro_input_poll); retro_input_state_cb = new LibRetro.retro_input_state_t(retro_input_state); retro = new LibRetro(modulename); try { CoreComm = nextComm; 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 LibRetroEmulator(CoreComm nextComm, string modulename) { ServiceProvider = new BasicServiceProvider(this); _SyncSettings = new SyncSettings(); retro_environment_cb = new LibRetro.retro_environment_t(retro_environment); retro_video_refresh_cb = new LibRetro.retro_video_refresh_t(retro_video_refresh); retro_audio_sample_cb = new LibRetro.retro_audio_sample_t(retro_audio_sample); retro_audio_sample_batch_cb = new LibRetro.retro_audio_sample_batch_t(retro_audio_sample_batch); retro_input_poll_cb = new LibRetro.retro_input_poll_t(retro_input_poll); retro_input_state_cb = new LibRetro.retro_input_state_t(retro_input_state); retro_log_printf_cb = new LibRetro.retro_log_printf_t(retro_log_printf); //no way (need new mechanism) to check for SSSE3, MMXEXT, SSE4, SSE42 retro_perf_callback.get_cpu_features = new LibRetro.retro_get_cpu_features_t(() => (ulong)( (Win32PInvokes.IsProcessorFeaturePresent(Win32PInvokes.ProcessorFeature.InstructionsXMMIAvailable) ? LibRetro.RETRO_SIMD.SSE : 0) | (Win32PInvokes.IsProcessorFeaturePresent(Win32PInvokes.ProcessorFeature.InstructionsXMMI64Available) ? LibRetro.RETRO_SIMD.SSE2 : 0) | (Win32PInvokes.IsProcessorFeaturePresent(Win32PInvokes.ProcessorFeature.InstructionsSSE3Available) ? LibRetro.RETRO_SIMD.SSE3 : 0) | (Win32PInvokes.IsProcessorFeaturePresent(Win32PInvokes.ProcessorFeature.InstructionsMMXAvailable) ? LibRetro.RETRO_SIMD.MMX : 0) )); retro_perf_callback.get_perf_counter = new LibRetro.retro_perf_get_counter_t(() => System.Diagnostics.Stopwatch.GetTimestamp()); retro_perf_callback.get_time_usec = new LibRetro.retro_perf_get_time_usec_t(() => DateTime.Now.Ticks / 10); retro_perf_callback.perf_log = new LibRetro.retro_perf_log_t(() => {}); retro_perf_callback.perf_register = new LibRetro.retro_perf_register_t((ref LibRetro.retro_perf_counter counter) => { }); retro_perf_callback.perf_start = new LibRetro.retro_perf_start_t((ref LibRetro.retro_perf_counter counter) => { }); retro_perf_callback.perf_stop = new LibRetro.retro_perf_stop_t((ref LibRetro.retro_perf_counter counter) => { }); retro = new LibRetro(modulename); try { CoreComm = nextComm; //this series of steps may be mystical. LibRetro.retro_system_info system_info = new LibRetro.retro_system_info(); retro.retro_get_system_info(ref system_info); //the dosbox core calls GET_SYSTEM_DIRECTORY and GET_SAVE_DIRECTORY from retro_set_environment. //so, lets set some temporary values (which we'll replace) SystemDirectory = Path.GetDirectoryName(modulename); SystemDirectoryAtom = unmanagedResources.StringToHGlobalAnsi(SystemDirectory); SaveDirectory = Path.GetDirectoryName(modulename); SaveDirectoryAtom = unmanagedResources.StringToHGlobalAnsi(SaveDirectory); retro.retro_set_environment(retro_environment_cb); 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); //compile descriptive information Description.NeedsArchives = system_info.block_extract; Description.NeedsRomAsPath = system_info.need_fullpath; Description.LibraryName = system_info.library_name; Description.LibraryVersion = system_info.library_version; Description.ValidExtensions = system_info.valid_extensions; Description.SupportsNoGame = environmentInfo.SupportNoGame; } catch { retro.Dispose(); retro = null; throw; } }
bool retro_environment(LibRetro.RETRO_ENVIRONMENT cmd, IntPtr data) { switch (cmd) { case LibRetro.RETRO_ENVIRONMENT.SET_ROTATION: return false; case LibRetro.RETRO_ENVIRONMENT.GET_OVERSCAN: return false; case LibRetro.RETRO_ENVIRONMENT.GET_CAN_DUPE: return true; case LibRetro.RETRO_ENVIRONMENT.SET_MESSAGE: { LibRetro.retro_message msg = new LibRetro.retro_message(); Marshal.PtrToStructure(data, msg); if (!string.IsNullOrEmpty(msg.msg)) Console.WriteLine("LibRetro Message: {0}", msg.msg); return true; } case LibRetro.RETRO_ENVIRONMENT.SHUTDOWN: return false; case LibRetro.RETRO_ENVIRONMENT.SET_PERFORMANCE_LEVEL: return false; case LibRetro.RETRO_ENVIRONMENT.GET_SYSTEM_DIRECTORY: return false; case LibRetro.RETRO_ENVIRONMENT.SET_PIXEL_FORMAT: { LibRetro.RETRO_PIXEL_FORMAT fmt = 0; 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: case LibRetro.RETRO_PIXEL_FORMAT.XRGB1555: case LibRetro.RETRO_PIXEL_FORMAT.XRGB8888: pixelfmt = fmt; Console.WriteLine("New pixel format set: {0}", pixelfmt); return true; default: Console.WriteLine("Unrecognized pixel format: {0}", (int)pixelfmt); return false; } } case LibRetro.RETRO_ENVIRONMENT.SET_INPUT_DESCRIPTORS: return false; case LibRetro.RETRO_ENVIRONMENT.SET_KEYBOARD_CALLBACK: return false; case LibRetro.RETRO_ENVIRONMENT.SET_DISK_CONTROL_INTERFACE: return false; case LibRetro.RETRO_ENVIRONMENT.SET_HW_RENDER: // this can be done in principle, but there's no reason to right now return false; case LibRetro.RETRO_ENVIRONMENT.GET_VARIABLE: return false; case LibRetro.RETRO_ENVIRONMENT.SET_VARIABLES: return false; case LibRetro.RETRO_ENVIRONMENT.GET_VARIABLE_UPDATE: return false; case LibRetro.RETRO_ENVIRONMENT.SET_SUPPORT_NO_GAME: return false; case LibRetro.RETRO_ENVIRONMENT.GET_LIBRETRO_PATH: return false; case LibRetro.RETRO_ENVIRONMENT.SET_AUDIO_CALLBACK: return false; case LibRetro.RETRO_ENVIRONMENT.SET_FRAME_TIME_CALLBACK: return false; case LibRetro.RETRO_ENVIRONMENT.GET_RUMBLE_INTERFACE: return false; case LibRetro.RETRO_ENVIRONMENT.GET_INPUT_DEVICE_CAPABILITIES: return false; default: Console.WriteLine("Unknkown retro_environment command {0}", (int)cmd); return false; } }