bool LoadWork(ref LibRetro.retro_game_info gi) { //defer this until loading because during the LibRetroEmulator constructor, we dont have access to the game name and so paths can't be selected //this cannot be done until set_environment is complete if (CoreComm.CoreFileProvider == null) { SaveDirectory = SystemDirectory = ""; } else { SystemDirectory = CoreComm.CoreFileProvider.GetRetroSystemPath(); SaveDirectory = CoreComm.CoreFileProvider.GetRetroSaveRAMDirectory(); SystemDirectoryAtom = unmanagedResources.StringToHGlobalAnsi(SystemDirectory); SaveDirectoryAtom = unmanagedResources.StringToHGlobalAnsi(SaveDirectory); } //defer this until loading because it triggers the core to read save and system paths //if any cores did that from set_environment then i'm assured we can call set_environment again here before retro_init and it should work //--alcaro says any cores that can't handle that should be considered a bug //UPDATE: dosbox does that, so lets try it retro.retro_set_environment(retro_environment_cb); retro.retro_init(); if (!retro.retro_load_game(ref gi)) { Console.WriteLine("retro_load_game() failed"); return(false); } //TODO - libretro cores can return a varying serialize size over time. I tried to get them to write it in the docs... savebuff = new byte[retro.retro_serialize_size()]; savebuff2 = new byte[savebuff.Length + 13]; LibRetro.retro_system_av_info av = new LibRetro.retro_system_av_info(); retro.retro_get_system_av_info(ref av); BufferWidth = (int)av.geometry.base_width; BufferHeight = (int)av.geometry.base_height; vidbuff = new int[av.geometry.max_width * av.geometry.max_height]; dar = av.geometry.aspect_ratio; // TODO: more precise CoreComm.VsyncNum = (int)(10000000 * av.timing.fps); CoreComm.VsyncDen = 10000000; SetupResampler(av.timing.fps, av.timing.sample_rate); (ServiceProvider as BasicServiceProvider).Register <ISoundProvider>(resampler); ControllerDefinition = CreateControllerDefinition(_SyncSettings); return(true); }
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; } }