Beispiel #1
0
        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.");
                }
            }
        }
Beispiel #2
0
 public void Dispose()
 {
     if (resampler != null)
     {
         resampler.Dispose();
         resampler = null;
     }
     if (retro != null)
     {
         retro.Dispose();
         retro = null;
     }
 }
Beispiel #3
0
 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;
            }
        }
Beispiel #5
0
        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;
            }
        }
Beispiel #6
0
        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;
            }
        }
Beispiel #7
0
 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;
     }
 }
Beispiel #8
0
 public void Dispose()
 {
     if (resampler != null)
     {
         resampler.Dispose();
         resampler = null;
     }
     if (retro != null)
     {
         retro.Dispose();
         retro = null;
     }
 }