Ejemplo n.º 1
0
static bool find_first_libretro(char *path, size_t size,
      const char *dir, const char *rom_path)
{
   bool ret = false;
   const char *ext = path_get_extension(rom_path);
   if (!ext || !*ext)
   {
      RARCH_ERR("Path has no extension. Cannot infer libretro implementation.\n");
      return false;
   }

   RARCH_LOG("Searching for valid libretro implementation in: \"%s\".\n", dir);

   struct string_list *list = dir_list_new(dir, DYNAMIC_EXT, false);
   if (!list)
   {
      RARCH_ERR("Couldn't open directory: \"%s\".\n", dir);
      return false;
   }

   for (size_t i = 0; i < list->size && !ret; i++)
   {
      RARCH_LOG("Checking library: \"%s\".\n", list->elems[i].data);
      dylib_t lib = dylib_load(list->elems[i].data);
      if (!lib)
         continue;

      void (*proc)(struct retro_system_info*) = 
         (void (*)(struct retro_system_info*))dylib_proc(lib, "retro_get_system_info");

      if (!proc)
      {
         dylib_close(lib);
         continue;
      }

      struct retro_system_info info = {0};
      proc(&info);

      if (!info.valid_extensions)
      {
         dylib_close(lib);
         continue;
      }

      struct string_list *supported_ext = string_split(info.valid_extensions, "|"); 

      if (string_list_find_elem(supported_ext, ext))
      {
         strlcpy(path, list->elems[i].data, size);
         ret = true;
      }

      string_list_free(supported_ext);
      dylib_close(lib);
   }

   dir_list_free(list);
   return ret;
}
Ejemplo n.º 2
0
static bool gfx_init_dwm(void)
{
   static bool inited = false;

   if (inited)
      return true;

   dwmlib = dylib_load("dwmapi.dll");
   if (!dwmlib)
   {
      RARCH_LOG("Did not find dwmapi.dll.\n");
      return false;
   }
   atexit(gfx_dwm_shutdown);

   HRESULT (WINAPI *mmcss)(BOOL) = 
      (HRESULT (WINAPI*)(BOOL))dylib_proc(dwmlib, "DwmEnableMMCSS");
   if (mmcss)
   {
      RARCH_LOG("Setting multimedia scheduling for DWM.\n");
      mmcss(TRUE);
   }

   inited = true;
   return true;
}
Ejemplo n.º 3
0
HRESULT WINAPI D3D11CreateDeviceAndSwapChain(
      IDXGIAdapter*   pAdapter,
      D3D_DRIVER_TYPE DriverType,
      HMODULE         Software,
      UINT            Flags,
      CONST D3D_FEATURE_LEVEL* pFeatureLevels,
      UINT                     FeatureLevels,
      UINT                     SDKVersion,
      CONST DXGI_SWAP_CHAIN_DESC* pSwapChainDesc,
      IDXGISwapChain**            ppSwapChain,
      ID3D11Device**              ppDevice,
      D3D_FEATURE_LEVEL*          pFeatureLevel,
      ID3D11DeviceContext**       ppImmediateContext)
{
   static dylib_t                                d3d11_dll;
   static PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN fp;

   if (!d3d11_dll)
      d3d11_dll = dylib_load("d3d11.dll");

   if (!d3d11_dll)
      return TYPE_E_CANTLOADLIBRARY;

   if (!fp)
      fp = (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)dylib_proc(
            d3d11_dll, "D3D11CreateDeviceAndSwapChain");

   if (!fp)
      return TYPE_E_DLLFUNCTIONNOTFOUND;

   return fp(
         pAdapter, DriverType, Software, Flags, pFeatureLevels, FeatureLevels, SDKVersion,
         pSwapChainDesc, ppSwapChain, ppDevice, pFeatureLevel, ppImmediateContext);
}
Ejemplo n.º 4
0
static void *gfx_ctx_wgl_init(video_frame_info_t *video_info, void *video_driver)
{
   WNDCLASSEX wndclass = {0};

   (void)video_driver;

   if (g_inited)
      return NULL;

   dll_handle = dylib_load("OpenGL32.dll");
   
   win32_window_reset();
   win32_monitor_init();

   wndclass.lpfnWndProc   = WndProcGL;
   if (!win32_window_init(&wndclass, true, NULL))
           return NULL;

   switch (win32_api)
   {
      case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
         if (!vulkan_context_init(&win32_vk, VULKAN_WSI_WIN32))
            return NULL;
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }

   return (void*)"wgl";
}
Ejemplo n.º 5
0
static dylib_t libretro_get_system_info_lib(const char *path, struct retro_system_info *info, bool *load_no_rom)
{
   dylib_t lib = dylib_load(path);
   if (!lib)
      return NULL;

   void (*proc)(struct retro_system_info*) = 
      (void (*)(struct retro_system_info*))dylib_proc(lib, "retro_get_system_info");

   if (!proc)
   {
      dylib_close(lib);
      return NULL;
   }

   proc(info);

   if (load_no_rom)
   {
      *load_no_rom = false;
      void (*set_environ)(retro_environment_t) =
         (void (*)(retro_environment_t))dylib_proc(lib, "retro_set_environment");

      if (!set_environ)
         return lib;

      libretro_get_environment_info(set_environ, load_no_rom);
   }

   return lib;
}
Ejemplo n.º 6
0
static bool gfx_init_dwm(void)
{
   HRESULT (WINAPI *mmcss)(BOOL);
   static bool inited = false;

   if (inited)
      return true;

   atexit(gfx_dwm_shutdown);

#ifdef HAVE_DYNAMIC
   shell32lib = dylib_load("shell32.dll");
   if (!shell32lib)
   {
      RARCH_WARN("Did not find shell32.dll.\n");
   }

   dwmlib = dylib_load("dwmapi.dll");
   if (!dwmlib)
   {
      RARCH_WARN("Did not find dwmapi.dll.\n");
      return false;
   }

   DragAcceptFiles_func =
      (VOID (WINAPI*)(HWND, BOOL))dylib_proc(shell32lib, "DragAcceptFiles");

   mmcss =
	   (HRESULT(WINAPI*)(BOOL))dylib_proc(dwmlib, "DwmEnableMMCSS");
#else
   DragAcceptFiles_func = DragAcceptFiles;
#if 0
   mmcss                = DwmEnableMMCSS;
#endif
#endif

   if (mmcss)
   {
	   RARCH_LOG("Setting multimedia scheduling for DWM.\n");
	   mmcss(TRUE);
   }

   inited = true;
   return true;
}
Ejemplo n.º 7
0
static bool append_softfilter_plugs(rarch_softfilter_t *filt,
      struct string_list *list)
{
   unsigned i;
   softfilter_simd_mask_t mask = retro_get_cpu_features();

   for (i = 0; i < list->size; i++)
   {
      softfilter_get_implementation_t cb;
      const struct softfilter_implementation *impl = NULL;
      struct rarch_soft_plug *new_plugs = NULL;
      dylib_t lib = dylib_load(list->elems[i].data);

      if (!lib)
         continue;

      cb = (softfilter_get_implementation_t)
         dylib_proc(lib, "softfilter_get_implementation");

      if (!cb)
      {
         dylib_close(lib);
         continue;
      }

      impl = cb(mask);
      if (!impl)
      {
         dylib_close(lib);
         continue;
      }

      if (impl->api_version != SOFTFILTER_API_VERSION)
      {
         dylib_close(lib);
         continue;
      }

      new_plugs = (struct rarch_soft_plug*)
         realloc(filt->plugs, sizeof(*filt->plugs) * (filt->num_plugs + 1));
      if (!new_plugs)
      {
         dylib_close(lib);
         return false;
      }

      RARCH_LOG("[SoftFilter]: Found plug: %s (%s).\n",
            impl->ident, impl->short_ident);
      
      filt->plugs = new_plugs;
      filt->plugs[filt->num_plugs].lib = lib;
      filt->plugs[filt->num_plugs].impl = impl;
      filt->num_plugs++;
   }

   return true;
}
Ejemplo n.º 8
0
static void *btstack_get_handle(void)
{
   void *handle = dylib_load("/usr/lib/libBTstack.dylib");

   if (handle)
      return handle;

   return NULL;
}
Ejemplo n.º 9
0
static void init_dsp_plugin(void)
{
   if (!(*g_settings.audio.dsp_plugin))
      return;

   rarch_dsp_info_t info = {0};

   g_extern.audio_data.dsp_lib = dylib_load(g_settings.audio.dsp_plugin);
   if (!g_extern.audio_data.dsp_lib)
   {
      RARCH_ERR("Failed to open DSP plugin: \"%s\" ...\n", g_settings.audio.dsp_plugin);
      return;
   }

   const rarch_dsp_plugin_t* (RARCH_API_CALLTYPE *plugin_init)(void) = 
      (const rarch_dsp_plugin_t *(RARCH_API_CALLTYPE*)(void))dylib_proc(g_extern.audio_data.dsp_lib, "rarch_dsp_plugin_init");

   if (!plugin_init)
   {
      RARCH_ERR("Failed to find symbol \"rarch_dsp_plugin_init\" in DSP plugin.\n");
      goto error;
   }

   g_extern.audio_data.dsp_plugin = plugin_init();
   if (!g_extern.audio_data.dsp_plugin)
   {
      RARCH_ERR("Failed to get a valid DSP plugin.\n");
      goto error;
   }

   if (g_extern.audio_data.dsp_plugin->api_version != RARCH_DSP_API_VERSION)
   {
      RARCH_ERR("DSP plugin API mismatch. RetroArch: %d, Plugin: %d\n", RARCH_DSP_API_VERSION, g_extern.audio_data.dsp_plugin->api_version);
      goto error;
   }

   RARCH_LOG("Loaded DSP plugin: \"%s\"\n", g_extern.audio_data.dsp_plugin->ident ? g_extern.audio_data.dsp_plugin->ident : "Unknown");

   info.input_rate = g_settings.audio.in_rate;

   g_extern.audio_data.dsp_handle = g_extern.audio_data.dsp_plugin->init(&info);
   if (!g_extern.audio_data.dsp_handle)
   {
      RARCH_ERR("Failed to init DSP plugin.\n");
      goto error;
   }

   return;

error:
   if (g_extern.audio_data.dsp_lib)
      dylib_close(g_extern.audio_data.dsp_lib);
   g_extern.audio_data.dsp_plugin = NULL;
   g_extern.audio_data.dsp_lib = NULL;
}
Ejemplo n.º 10
0
static void *btstack_get_handle(void)
{
#ifdef HAVE_DYNAMIC
   void *handle = dylib_load("/usr/lib/libBTstack.dylib");

   if (handle)
      return handle;
#endif

   return NULL;
}
Ejemplo n.º 11
0
static dylib_t dylib_load_d3d9x(void)
{
   dylib_t dll           = NULL;

   const char **dll_name = d3dx9_dll_list;

   while (!dll && *dll_name)
      dll = dylib_load(*dll_name++);

   return dll;
}
Ejemplo n.º 12
0
static bool append_plugs(rarch_dsp_filter_t *dsp, struct string_list *list)
{
   unsigned i;
   dspfilter_simd_mask_t mask = rarch_get_cpu_features();

   for (i = 0; i < list->size; i++)
   {
      const struct dspfilter_implementation *impl = NULL;
      struct rarch_dsp_plug *new_plugs = NULL;
      dylib_t lib = dylib_load(list->elems[i].data);

      if (!lib)
         continue;

      dspfilter_get_implementation_t cb = (dspfilter_get_implementation_t)
         dylib_proc(lib, "dspfilter_get_implementation");
      if (!cb)
      {
         dylib_close(lib);
         continue;
      }

      impl = cb(mask);
      if (!impl)
      {
         dylib_close(lib);
         continue;
      }

      if (impl->api_version != DSPFILTER_API_VERSION)
      {
         dylib_close(lib);
         continue;
      }

      new_plugs = (struct rarch_dsp_plug*)
         realloc(dsp->plugs, sizeof(*dsp->plugs) * (dsp->num_plugs + 1));
      if (!new_plugs)
      {
         dylib_close(lib);
         return false;
      }

      /* Found plug. */
      
      dsp->plugs = new_plugs;
      dsp->plugs[dsp->num_plugs].lib = lib;
      dsp->plugs[dsp->num_plugs].impl = impl;
      dsp->num_plugs++;
   }

   return true;
}
Ejemplo n.º 13
0
static void *video_ext_init(const video_info_t *video, const input_driver_t **input, void **input_data)
{
   ext_t *ext = (ext_t*)calloc(1, sizeof(*ext));
   if (!ext)
      return NULL;

   const rarch_video_driver_t *(*video_init)(void) = NULL;

   if (!(*g_settings.video.external_driver))
   {
      RARCH_ERR("External driver needs video_external_driver path to be set.\n");
      goto error;
   }

   g_lib = dylib_load(g_settings.video.external_driver);
   if (!g_lib)
   {
      RARCH_ERR("Failed to open library: \"%s\"\n", g_settings.video.external_driver);
      goto error;
   }

   video_init = (const rarch_video_driver_t *(*)(void))dylib_proc(g_lib, "rarch_video_init");
   if (!video_init)
      video_init = (const rarch_video_driver_t *(*)(void))dylib_proc(g_lib, "ssnes_video_init"); // Compat. Will be dropped on ABI break.

   if (!video_init)
   {
      RARCH_ERR("Couldn't find function rarch_video_init in library ...\n");
      goto error;
   }

   ext->driver = video_init();
   if (!ext->driver)
   {
      RARCH_ERR("External driver returned invalid driver handle.\n");
      goto error;
   }

   if (!setup_video(ext, video, input, input_data))
   {
      RARCH_ERR("Failed to start driver.\n");
      goto error;
   }

   g_video_dead = false;
   return ext;

error:
   video_ext_free(ext);
   return NULL;
}
Ejemplo n.º 14
0
static void load_symbols(void)
{
#ifdef HAVE_DYNAMIC
   RARCH_LOG("Loading dynamic libretro from: \"%s\"\n", g_settings.libretro);
   lib_handle = dylib_load(g_settings.libretro);
   if (!lib_handle)
   {
      RARCH_ERR("Failed to open dynamic library: \"%s\"\n", g_settings.libretro);
      rarch_fail(1, "load_dynamic()");
   }
#endif

   SYM(retro_init);
   SYM(retro_deinit);

   SYM(retro_api_version);
   SYM(retro_get_system_info);
   SYM(retro_get_system_av_info);

   SYM(retro_set_environment);
   SYM(retro_set_video_refresh);
   SYM(retro_set_audio_sample);
   SYM(retro_set_audio_sample_batch);
   SYM(retro_set_input_poll);
   SYM(retro_set_input_state);

   SYM(retro_set_controller_port_device);

   SYM(retro_reset);
   SYM(retro_run);

   SYM(retro_serialize_size);
   SYM(retro_serialize);
   SYM(retro_unserialize);

   SYM(retro_cheat_reset);
   SYM(retro_cheat_set);

   SYM(retro_load_game);
   SYM(retro_load_game_special);

   SYM(retro_unload_game);
   SYM(retro_get_region);
   SYM(retro_get_memory_data);
   SYM(retro_get_memory_size);
}
Ejemplo n.º 15
0
static void *gfx_ctx_wgl_init(video_frame_info_t *video_info, void *video_driver)
{
   WNDCLASSEX wndclass     = {0};
   gfx_ctx_wgl_data_t *wgl = (gfx_ctx_wgl_data_t*)calloc(1, sizeof(*wgl));

   if (!wgl)
      return NULL;

   if (g_win32_inited)
      goto error;

#ifdef HAVE_DYNAMIC
   dll_handle = dylib_load("OpenGL32.dll");
#endif

   win32_window_reset();
   win32_monitor_init();

   wndclass.lpfnWndProc   = WndProcGL;
   if (!win32_window_init(&wndclass, true, NULL))
      goto error;

   switch (win32_api)
   {
      case GFX_CTX_VULKAN_API:
#ifdef HAVE_VULKAN
         if (!vulkan_context_init(&win32_vk, VULKAN_WSI_WIN32))
            goto error;
#endif
         break;
      case GFX_CTX_NONE:
      default:
         break;
   }

   return wgl;

error:
   if (wgl)
      free(wgl);
   return NULL;
}
Ejemplo n.º 16
0
static dylib_t libretro_get_system_info_lib(const char *path,
      struct retro_system_info *info, bool *load_no_content)
{
   dylib_t lib = dylib_load(path);
   void (*proc)(struct retro_system_info*);

   if (!lib)
   {
      RARCH_ERR("%s: \"%s\"\n",
            msg_hash_to_str(MSG_FAILED_TO_OPEN_LIBRETRO_CORE),
            path);
      RARCH_ERR("Error(s): %s\n", dylib_error());
      return NULL;
   }

   proc = (void (*)(struct retro_system_info*))
      dylib_proc(lib, "retro_get_system_info");

   if (!proc)
   {
      dylib_close(lib);
      return NULL;
   }

   proc(info);

   if (load_no_content)
   {
      void (*set_environ)(retro_environment_t);
      *load_no_content = false;
      set_environ = (void (*)(retro_environment_t))
         dylib_proc(lib, "retro_set_environment");

      if (!set_environ)
         return lib;

      libretro_get_environment_info(set_environ, load_no_content);
   }

   return lib;
}
Ejemplo n.º 17
0
static void load_dynamic_core(void)
{
   function_t sym       = dylib_proc(NULL, "retro_init");

   if (sym)
   {
      /* Try to verify that -lretro was not linked in from other modules
       * since loading it dynamically and with -l will fail hard. */
      RARCH_ERR("Serious problem. RetroArch wants to load libretro cores"
            "dyamically, but it is already linked.\n");
      RARCH_ERR("This could happen if other modules RetroArch depends on "
            "link against libretro directly.\n");
      RARCH_ERR("Proceeding could cause a crash. Aborting ...\n");
      retroarch_fail(1, "init_libretro_sym()");
   }

   if (string_is_empty(path_get(RARCH_PATH_CORE)))
   {
      RARCH_ERR("RetroArch is built for dynamic libretro cores, but "
            "libretro_path is not set. Cannot continue.\n");
      retroarch_fail(1, "init_libretro_sym()");
   }

   /* Need to use absolute path for this setting. It can be
    * saved to content history, and a relative path would
    * break in that scenario. */
   path_resolve_realpath(
         path_get_ptr(RARCH_PATH_CORE),
         path_get_realsize(RARCH_PATH_CORE));

   RARCH_LOG("Loading dynamic libretro core from: \"%s\"\n",
         path_get(RARCH_PATH_CORE));
   lib_handle = dylib_load(path_get(RARCH_PATH_CORE));
   if (!lib_handle)
   {
      RARCH_ERR("Failed to open libretro core: \"%s\"\n",
            path_get(RARCH_PATH_CORE));
      RARCH_ERR("Error(s): %s\n", dylib_error());
      retroarch_fail(1, "load_dynamic()");
   }
}
Ejemplo n.º 18
0
static dylib_t libretro_get_system_info_lib(const char *path,
      struct retro_system_info *info, bool *load_no_content)
{
   dylib_t lib = dylib_load(path);
   void (*proc)(struct retro_system_info*);

   if (!lib)
   {
      RARCH_ERR("Failed to open libretro core: \"%s\"\n",
            path);
      RARCH_ERR("Error(s): %s\n", dylib_error());
      return NULL;
   }

   proc = (void (*)(struct retro_system_info*))
      dylib_proc(lib, "retro_get_system_info");

   if (!proc)
   {
      dylib_close(lib);
      return NULL;
   }

   proc(info);

   if (load_no_content)
   {
      void (*set_environ)(retro_environment_t);
      *load_no_content = false;
      set_environ = (void (*)(retro_environment_t))
         dylib_proc(lib, "retro_set_environment");

      if (!set_environ)
         return lib;

      libretro_get_environment_info(set_environ, load_no_content);
   }

   return lib;
}
Ejemplo n.º 19
0
void gfx_set_dwm(void)
{
   static bool inited = false;
   if (inited)
      return;
   inited = true;

   dwmlib = dylib_load("dwmapi.dll");
   if (!dwmlib)
   {
      RARCH_LOG("Did not find dwmapi.dll.\n");
      return;
   }
   atexit(gfx_dwm_shutdown);

   HRESULT (WINAPI *mmcss)(BOOL) = (HRESULT (WINAPI*)(BOOL))dylib_proc(dwmlib, "DwmEnableMMCSS");
   if (mmcss)
   {
      RARCH_LOG("Setting multimedia scheduling for DWM.\n");
      mmcss(TRUE);
   }

   if (!g_settings.video.disable_composition)
      return;

   HRESULT (WINAPI *composition_enable)(UINT) = (HRESULT (WINAPI*)(UINT))dylib_proc(dwmlib, "DwmEnableComposition");
   if (!composition_enable)
   {
      RARCH_ERR("Did not find DwmEnableComposition ...\n");
      return;
   }

   HRESULT ret = composition_enable(0);
   if (FAILED(ret))
      RARCH_ERR("Failed to set composition state ...\n");
}
Ejemplo n.º 20
0
void create_gl_context(HWND hwnd, bool *quit)
{
   bool core_context;
   const struct retro_hw_render_callback *hw_render =
      (const struct retro_hw_render_callback*)video_driver_callback();
   bool debug       = hw_render->debug_context;

#ifdef _WIN32
   dll_handle = dylib_load("OpenGL32.dll");
#endif

   g_hdc = GetDC(hwnd);
   setup_pixel_format(g_hdc);

#ifdef GL_DEBUG
   debug = true;
#endif
   core_context = (g_major * 1000 + g_minor) >= 3001;

   if (g_hrc)
   {
      RARCH_LOG("[WGL]: Using cached GL context.\n");
      video_driver_ctl(RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT_ACK, NULL);
   }
   else
   {
      g_hrc = wglCreateContext(g_hdc);
      
      /* We'll create shared context later if not. */
      if (g_hrc && !core_context && !debug) 
      {
         g_hw_hrc = wglCreateContext(g_hdc);
         if (g_hw_hrc)
         {
            if (!wglShareLists(g_hrc, g_hw_hrc))
            {
               RARCH_LOG("[WGL]: Failed to share contexts.\n");
               *quit = true;
            }
         }
         else
            *quit = true;
      }
   }

   if (g_hrc)
   {
      if (wglMakeCurrent(g_hdc, g_hrc))
         g_inited = true;
      else
         *quit     = true;
   }
   else
   {
      *quit        = true;
      return;
   }

   if (core_context || debug)
   {
      int attribs[16];
      int *aptr = attribs;

      if (core_context)
      {
         *aptr++ = WGL_CONTEXT_MAJOR_VERSION_ARB;
         *aptr++ = g_major;
         *aptr++ = WGL_CONTEXT_MINOR_VERSION_ARB;
         *aptr++ = g_minor;

         /* Technically, we don't have core/compat until 3.2.
          * Version 3.1 is either compat or not depending 
          * on GL_ARB_compatibility.
          */
         if ((g_major * 1000 + g_minor) >= 3002)
         {
            *aptr++ = WGL_CONTEXT_PROFILE_MASK_ARB;
            *aptr++ = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
         }
      }

      if (debug)
      {
         *aptr++ = WGL_CONTEXT_FLAGS_ARB;
         *aptr++ = WGL_CONTEXT_DEBUG_BIT_ARB;
      }

      *aptr = 0;

      if (!pcreate_context)
         pcreate_context = (wglCreateContextAttribsProc)
            wglGetProcAddress("wglCreateContextAttribsARB");

      if (pcreate_context)
      {
         HGLRC context = pcreate_context(g_hdc, NULL, attribs);

         if (context)
         {
            wglMakeCurrent(NULL, NULL);
            wglDeleteContext(g_hrc);
            g_hrc = context;
            if (!wglMakeCurrent(g_hdc, g_hrc))
               *quit = true;
         }
         else
            RARCH_ERR("[WGL]: Failed to create core context. Falling back to legacy context.\n");

         if (g_use_hw_ctx)
         {
            g_hw_hrc = pcreate_context(g_hdc, context, attribs);
            if (!g_hw_hrc)
            {
               RARCH_ERR("[WGL]: Failed to create shared context.\n");
               *quit = true;
            }
         }
      }
      else
         RARCH_ERR("[WGL]: wglCreateContextAttribsARB not supported.\n");
   }
}
Ejemplo n.º 21
0
bool d3d9_initialize_symbols(enum gfx_ctx_api api)
{
#ifdef HAVE_DYNAMIC_D3D
   if (d3d9_dylib_initialized)
      return true;

#if defined(DEBUG) || defined(_DEBUG)
   g_d3d9_dll     = dylib_load("d3d9d.dll");
   if(!g_d3d9_dll)
#endif
      g_d3d9_dll  = dylib_load("d3d9.dll");
#ifdef HAVE_D3DX
   g_d3d9x_dll    = dylib_load_d3d9x();

   if (!g_d3d9x_dll)
      return false;
#endif

   if (!g_d3d9_dll)
      return false;
#endif
   
   d3d9_SDKVersion            = 31;
#ifdef HAVE_DYNAMIC_D3D
   D3D9Create                 = (D3D9Create_t)dylib_proc(g_d3d9_dll, "Direct3DCreate9");
#ifdef HAVE_D3DX
   D3D9CompileShaderFromFile  = (D3D9CompileShaderFromFile_t)dylib_proc(g_d3d9x_dll, "D3DXCompileShaderFromFile");
   D3D9CompileShader          = (D3D9CompileShader_t)dylib_proc(g_d3d9x_dll, "D3DXCompileShader");
#ifdef UNICODE
   D3D9CreateFontIndirect     = (D3D9XCreateFontIndirect_t)dylib_proc(g_d3d9x_dll, "D3DXCreateFontIndirectW");
#else
   D3D9CreateFontIndirect     = (D3D9XCreateFontIndirect_t)dylib_proc(g_d3d9x_dll, "D3DXCreateFontIndirectA");
#endif
   D3D9CreateTextureFromFile  = (D3D9CreateTextureFromFile_t)dylib_proc(g_d3d9x_dll, "D3DXCreateTextureFromFileExA");
#endif
#else
   D3D9Create                 = Direct3DCreate9;
#ifdef HAVE_D3DX
   D3D9CompileShaderFromFile  = D3DXCompileShaderFromFile;
   D3D9CompileShader          = D3DXCompileShader;
   D3D9CreateFontIndirect     = D3DXCreateFontIndirect;
   D3D9CreateTextureFromFile  = D3DXCreateTextureFromFileExA;
#endif
#endif

   if (!D3D9Create)
      goto error;

#ifdef _XBOX
   d3d9_SDKVersion          = 0;
#endif
#ifdef HAVE_DYNAMIC_D3D
   d3d9_dylib_initialized = true;
#endif

   return true;

error:
   d3d9_deinitialize_symbols();
   return false;
}
Ejemplo n.º 22
0
static void *audio_ext_init(const char *device, unsigned rate, unsigned latency)
{
   if (!(*g_settings.audio.external_driver))
   {
      RARCH_ERR("Please define an external audio driver.\n");
      return NULL;
   }

   audio_ext_t *ext = (audio_ext_t*)calloc(1, sizeof(*ext));
   if (!ext)
      return NULL;

   rarch_audio_driver_info_t info = {0};
   const rarch_audio_driver_t *(*plugin_load)(void) = NULL;

   ext->lib = dylib_load(g_settings.audio.external_driver);
   if (!ext->lib)
   {
      RARCH_ERR("Failed to load external library \"%s\"\n", g_settings.audio.external_driver);
      goto error;
   }

   plugin_load = (const rarch_audio_driver_t *(*)(void))dylib_proc(ext->lib, "rarch_audio_driver_init");

   if (!plugin_load)
   {
      RARCH_ERR("Failed to find symbol \"rarch_audio_driver_init\" in plugin.\n");
      goto error;
   }

   ext->driver = plugin_load();
   if (!ext->driver)
   {
      RARCH_ERR("Received invalid driver from plugin.\n");
      goto error;
   }

   RARCH_LOG("Loaded external audio driver: \"%s\"\n", ext->driver->ident ? ext->driver->ident : "Unknown");

   if (ext->driver->api_version != RARCH_AUDIO_API_VERSION)
   {
      RARCH_ERR("API mismatch in external audio plugin. RetroArch: %d, Plugin: %d ...\n", RARCH_AUDIO_API_VERSION, ext->driver->api_version);
      goto error;
   }

   info.device = device;
   info.sample_rate = rate;
   info.latency = latency;

   ext->handle = ext->driver->init(&info);
   if (!ext->handle)
   {
      RARCH_ERR("Failed to init audio driver.\n");
      goto error;
   }

   if (ext->driver->sample_rate)
      g_settings.audio.out_rate = ext->driver->sample_rate(ext->handle);

   if (!g_settings.audio.sync)
      ext->driver->set_nonblock_state(ext->handle, RARCH_TRUE);

   return ext;

error:
   audio_ext_free(ext);
   return NULL;
}
Ejemplo n.º 23
0
static void load_symbols(void)
{
#ifdef HAVE_DYNAMIC
   const char *libretro_path = g_settings.libretro;
   char libretro_core_buffer[PATH_MAX];

   if (path_is_directory(g_settings.libretro))
   {
      if (!find_first_libretro(libretro_core_buffer, sizeof(libretro_core_buffer),
               g_settings.libretro, g_extern.fullpath))
      {
         RARCH_ERR("libretro_path is a directory, but no valid libretro implementation was found.\n");
         rarch_fail(1, "load_dynamic()");
      }

      libretro_path = libretro_core_buffer;
   }

   RARCH_LOG("Loading dynamic libretro from: \"%s\"\n", libretro_path);
   lib_handle = dylib_load(libretro_path);
   if (!lib_handle)
   {
      RARCH_ERR("Failed to open dynamic library: \"%s\"\n", libretro_path);
      rarch_fail(1, "load_dynamic()");
   }
#endif

   SYM(retro_init);
   SYM(retro_deinit);

   SYM(retro_api_version);
   SYM(retro_get_system_info);
   SYM(retro_get_system_av_info);

   SYM(retro_set_environment);
   SYM(retro_set_video_refresh);
   SYM(retro_set_audio_sample);
   SYM(retro_set_audio_sample_batch);
   SYM(retro_set_input_poll);
   SYM(retro_set_input_state);

   SYM(retro_set_controller_port_device);

   SYM(retro_reset);
   SYM(retro_run);

   SYM(retro_serialize_size);
   SYM(retro_serialize);
   SYM(retro_unserialize);

   SYM(retro_cheat_reset);
   SYM(retro_cheat_set);

   SYM(retro_load_game);
   SYM(retro_load_game_special);

   SYM(retro_unload_game);
   SYM(retro_get_region);
   SYM(retro_get_memory_data);
   SYM(retro_get_memory_size);
}
Ejemplo n.º 24
0
/**
 * load_symbols:
 * @type                        : Type of core to be loaded.
 *                                If CORE_TYPE_DUMMY, will
 *                                load dummy symbols.
 *
 * Setup libretro callback symbols.
 **/
static void load_symbols(enum rarch_core_type type)
{
   switch (type)
   {
      case CORE_TYPE_PLAIN:
         {
#ifdef HAVE_DYNAMIC
            settings_t *settings = config_get_ptr();
            function_t sym       = dylib_proc(NULL, "retro_init");

            if (sym)
            {
               /* Try to verify that -lretro was not linked in from other modules
                * since loading it dynamically and with -l will fail hard. */
               RARCH_ERR("Serious problem. RetroArch wants to load libretro cores dyamically, but it is already linked.\n");
               RARCH_ERR("This could happen if other modules RetroArch depends on link against libretro directly.\n");
               RARCH_ERR("Proceeding could cause a crash. Aborting ...\n");
               retro_fail(1, "init_libretro_sym()");
            }

            if (!*settings->libretro)
            {
               RARCH_ERR("RetroArch is built for dynamic libretro cores, but libretro_path is not set. Cannot continue.\n");
               retro_fail(1, "init_libretro_sym()");
            }

            /* Need to use absolute path for this setting. It can be
             * saved to content history, and a relative path would
             * break in that scenario. */
            path_resolve_realpath(settings->libretro,
                  sizeof(settings->libretro));

            RARCH_LOG("Loading dynamic libretro core from: \"%s\"\n",
                  settings->libretro);
            lib_handle = dylib_load(settings->libretro);
            if (!lib_handle)
            {
               RARCH_ERR("Failed to open libretro core: \"%s\"\n",
                     settings->libretro);
               RARCH_ERR("Error(s): %s\n", dylib_error());
               retro_fail(1, "load_dynamic()");
            }
#endif
         }

         SYMBOL(retro_init);
         SYMBOL(retro_deinit);

         SYMBOL(retro_api_version);
         SYMBOL(retro_get_system_info);
         SYMBOL(retro_get_system_av_info);

         SYMBOL(retro_set_environment);
         SYMBOL(retro_set_video_refresh);
         SYMBOL(retro_set_audio_sample);
         SYMBOL(retro_set_audio_sample_batch);
         SYMBOL(retro_set_input_poll);
         SYMBOL(retro_set_input_state);

         SYMBOL(retro_set_controller_port_device);

         SYMBOL(retro_reset);
         SYMBOL(retro_run);

         SYMBOL(retro_serialize_size);
         SYMBOL(retro_serialize);
         SYMBOL(retro_unserialize);

         SYMBOL(retro_cheat_reset);
         SYMBOL(retro_cheat_set);

         SYMBOL(retro_load_game);
         SYMBOL(retro_load_game_special);

         SYMBOL(retro_unload_game);
         SYMBOL(retro_get_region);
         SYMBOL(retro_get_memory_data);
         SYMBOL(retro_get_memory_size);
         break;
      case CORE_TYPE_DUMMY:
         SYMBOL_DUMMY(retro_init);
         SYMBOL_DUMMY(retro_deinit);

         SYMBOL_DUMMY(retro_api_version);
         SYMBOL_DUMMY(retro_get_system_info);
         SYMBOL_DUMMY(retro_get_system_av_info);

         SYMBOL_DUMMY(retro_set_environment);
         SYMBOL_DUMMY(retro_set_video_refresh);
         SYMBOL_DUMMY(retro_set_audio_sample);
         SYMBOL_DUMMY(retro_set_audio_sample_batch);
         SYMBOL_DUMMY(retro_set_input_poll);
         SYMBOL_DUMMY(retro_set_input_state);

         SYMBOL_DUMMY(retro_set_controller_port_device);

         SYMBOL_DUMMY(retro_reset);
         SYMBOL_DUMMY(retro_run);

         SYMBOL_DUMMY(retro_serialize_size);
         SYMBOL_DUMMY(retro_serialize);
         SYMBOL_DUMMY(retro_unserialize);

         SYMBOL_DUMMY(retro_cheat_reset);
         SYMBOL_DUMMY(retro_cheat_set);

         SYMBOL_DUMMY(retro_load_game);
         SYMBOL_DUMMY(retro_load_game_special);

         SYMBOL_DUMMY(retro_unload_game);
         SYMBOL_DUMMY(retro_get_region);
         SYMBOL_DUMMY(retro_get_memory_data);
         SYMBOL_DUMMY(retro_get_memory_size);
         break;
#ifdef HAVE_FFMPEG
      case CORE_TYPE_FFMPEG:
         SYMBOL_FFMPEG(retro_init);
         SYMBOL_FFMPEG(retro_deinit);

         SYMBOL_FFMPEG(retro_api_version);
         SYMBOL_FFMPEG(retro_get_system_info);
         SYMBOL_FFMPEG(retro_get_system_av_info);

         SYMBOL_FFMPEG(retro_set_environment);
         SYMBOL_FFMPEG(retro_set_video_refresh);
         SYMBOL_FFMPEG(retro_set_audio_sample);
         SYMBOL_FFMPEG(retro_set_audio_sample_batch);
         SYMBOL_FFMPEG(retro_set_input_poll);
         SYMBOL_FFMPEG(retro_set_input_state);

         SYMBOL_FFMPEG(retro_set_controller_port_device);

         SYMBOL_FFMPEG(retro_reset);
         SYMBOL_FFMPEG(retro_run);

         SYMBOL_FFMPEG(retro_serialize_size);
         SYMBOL_FFMPEG(retro_serialize);
         SYMBOL_FFMPEG(retro_unserialize);

         SYMBOL_FFMPEG(retro_cheat_reset);
         SYMBOL_FFMPEG(retro_cheat_set);

         SYMBOL_FFMPEG(retro_load_game);
         SYMBOL_FFMPEG(retro_load_game_special);

         SYMBOL_FFMPEG(retro_unload_game);
         SYMBOL_FFMPEG(retro_get_region);
         SYMBOL_FFMPEG(retro_get_memory_data);
         SYMBOL_FFMPEG(retro_get_memory_size);
         break;
#endif
      case CORE_TYPE_IMAGEVIEWER:
#ifdef HAVE_IMAGEVIEWER
         SYMBOL_IMAGEVIEWER(retro_init);
         SYMBOL_IMAGEVIEWER(retro_deinit);

         SYMBOL_IMAGEVIEWER(retro_api_version);
         SYMBOL_IMAGEVIEWER(retro_get_system_info);
         SYMBOL_IMAGEVIEWER(retro_get_system_av_info);

         SYMBOL_IMAGEVIEWER(retro_set_environment);
         SYMBOL_IMAGEVIEWER(retro_set_video_refresh);
         SYMBOL_IMAGEVIEWER(retro_set_audio_sample);
         SYMBOL_IMAGEVIEWER(retro_set_audio_sample_batch);
         SYMBOL_IMAGEVIEWER(retro_set_input_poll);
         SYMBOL_IMAGEVIEWER(retro_set_input_state);

         SYMBOL_IMAGEVIEWER(retro_set_controller_port_device);

         SYMBOL_IMAGEVIEWER(retro_reset);
         SYMBOL_IMAGEVIEWER(retro_run);

         SYMBOL_IMAGEVIEWER(retro_serialize_size);
         SYMBOL_IMAGEVIEWER(retro_serialize);
         SYMBOL_IMAGEVIEWER(retro_unserialize);

         SYMBOL_IMAGEVIEWER(retro_cheat_reset);
         SYMBOL_IMAGEVIEWER(retro_cheat_set);

         SYMBOL_IMAGEVIEWER(retro_load_game);
         SYMBOL_IMAGEVIEWER(retro_load_game_special);

         SYMBOL_IMAGEVIEWER(retro_unload_game);
         SYMBOL_IMAGEVIEWER(retro_get_region);
         SYMBOL_IMAGEVIEWER(retro_get_memory_data);
         SYMBOL_IMAGEVIEWER(retro_get_memory_size);
#endif
         break;
   }
}
Ejemplo n.º 25
0
static bool xinput_joypad_init(void)
{
   unsigned i, autoconf_pad;
   XINPUT_STATE dummy_state;
   const char *version = "1.4";
   settings_t *settings = config_get_ptr();

   g_xinput_dll = NULL;

   /* Find the correct path to load the DLL from.
    * Usually this will be from the system directory,
    * but occasionally a user may wish to use a third-party
    * wrapper DLL (such as x360ce); support these by checking
    * the working directory first.
    *
    * No need to check for existance as we will be checking dylib_load's
    * success anyway.
    */

   /* Using dylib_* complicates building joyconfig. */
   g_xinput_dll = (HINSTANCE)dylib_load("xinput1_4.dll"); 
   if (!g_xinput_dll)
   {
      g_xinput_dll = (HINSTANCE)dylib_load("xinput1_3.dll");
      version = "1.3";
   }

   if (!g_xinput_dll)
   {
      RARCH_ERR("Failed to load XInput, ensure DirectX and controller drivers are up to date.\n");
      return false;
   }

   RARCH_LOG("Found XInput v%s.\n", version);

   /* If we get here then an xinput DLL is correctly loaded.
    * First try to load ordinal 100 (XInputGetStateEx).
    */
   g_XInputGetStateEx = (XInputGetStateEx_t)dylib_proc(g_xinput_dll, (const char*)100);
   g_xinput_guide_button_supported = true;

   if (!g_XInputGetStateEx)
   {
      /* no ordinal 100. (Presumably a wrapper.) Load the ordinary
       * XInputGetState, at the cost of losing guide button support.
       */
      g_xinput_guide_button_supported = false;
      g_XInputGetStateEx = (XInputGetStateEx_t)dylib_proc(g_xinput_dll, "XInputGetState");

      if (!g_XInputGetStateEx)
      {
         RARCH_ERR("Failed to init XInput: DLL is invalid or corrupt.\n");
         dylib_close(g_xinput_dll);
         return false; /* DLL was loaded but did not contain the correct function. */
      }
      RARCH_WARN("XInput: No guide button support.\n");
   }

   g_XInputSetState = (XInputSetState_t)dylib_proc(g_xinput_dll, "XInputSetState");
   if (!g_XInputSetState)
   {
      RARCH_ERR("Failed to init XInput: DLL is invalid or corrupt.\n");
      dylib_close(g_xinput_dll);
      return false; /* DLL was loaded but did not contain the correct function. */
   }

   /* Zero out the states. */
   for (i = 0; i < 4; ++i)
      memset(&g_xinput_states[i], 0, sizeof(xinput_joypad_state));

   /* Do a dummy poll to check which controllers are connected. */
   for (i = 0; i < 4; ++i)
   {
      g_xinput_states[i].connected = !(g_XInputGetStateEx(i, &dummy_state) == ERROR_DEVICE_NOT_CONNECTED);
      if (g_xinput_states[i].connected)
         RARCH_LOG("Found XInput controller, user #%u\n", i);
   }

   if ((!g_xinput_states[0].connected) &&
         (!g_xinput_states[1].connected) &&
         (!g_xinput_states[2].connected) &&
         (!g_xinput_states[3].connected))
      return false;

   g_xinput_block_pads = true;

   /* We're going to have to be buddies with dinput if we want to be able
    * to use XInput and non-XInput controllers together. */
   if (!dinput_joypad.init())
   {
      g_xinput_block_pads = false;
      return false;
   }

   for (autoconf_pad = 0; autoconf_pad < MAX_USERS; autoconf_pad++)
   {
      if (pad_index_to_xuser_index(autoconf_pad) > -1)
      {
         autoconfig_params_t params = {{0}};

         strlcpy(settings->input.device_names[autoconf_pad],
               xinput_joypad_name(autoconf_pad),
               sizeof(settings->input.device_names[autoconf_pad]));

         /* TODO - implement VID/PID? */
         params.idx = autoconf_pad;
         strlcpy(params.name, xinput_joypad_name(autoconf_pad), sizeof(params.name));
         strlcpy(params.driver, xinput_joypad.ident, sizeof(params.driver));
         input_config_autoconfigure_joypad(&params);
      }
   }

   return true;
}
Ejemplo n.º 26
0
rarch_softfilter_t *rarch_softfilter_new(const char *filter_path,
      unsigned threads,
      enum retro_pixel_format in_pixel_format,
      unsigned max_width, unsigned max_height)
{
   unsigned i, cpu_features, output_fmts, input_fmts, input_fmt;
   softfilter_get_implementation_t cb;
    
   i = 0;

   (void)i;
   (void)filter_path;

   rarch_softfilter_t *filt = (rarch_softfilter_t*)calloc(1, sizeof(*filt));
   if (!filt)
      return NULL;

   cb = NULL;
#if defined(HAVE_FILTERS_BUILTIN)
   cb = (softfilter_get_implementation_t)softfilter_get_implementation_from_idx(g_settings.video.filter_idx);
#elif defined(HAVE_DYLIB)
   filt->lib = dylib_load(filter_path);
   if (!filt->lib)
      goto error;

   cb = (softfilter_get_implementation_t)dylib_proc(filt->lib, "softfilter_get_implementation");
#endif
   if (!cb)
   {
      RARCH_ERR("Couldn't find softfilter symbol.\n");
      goto error;
   }

   cpu_features = rarch_get_cpu_features();
   filt->impl = cb(cpu_features);
   if (!filt->impl)
      goto error;

   RARCH_LOG("Loaded softfilter \"%s\".\n", filt->impl->ident);

   if (filt->impl->api_version != SOFTFILTER_API_VERSION)
   {
      RARCH_ERR("Softfilter ABI mismatch.\n");
      goto error;
   }

   // Simple assumptions.
   filt->pix_fmt = in_pixel_format;
   input_fmts = filt->impl->query_input_formats();

   switch (in_pixel_format)
   {
      case RETRO_PIXEL_FORMAT_XRGB8888:
         input_fmt = SOFTFILTER_FMT_XRGB8888;
         break;
      case RETRO_PIXEL_FORMAT_RGB565:
         input_fmt = SOFTFILTER_FMT_RGB565;
         break;
      default:
         goto error;
   }

   if (!(input_fmt & input_fmts))
   {
      RARCH_ERR("Softfilter does not support input format.\n");
      goto error;
   }

   output_fmts = filt->impl->query_output_formats(input_fmt);
   if (output_fmts & input_fmt) // If we have a match of input/output formats, use that.
      filt->out_pix_fmt = in_pixel_format;
   else if (output_fmts & SOFTFILTER_FMT_XRGB8888)
      filt->out_pix_fmt = RETRO_PIXEL_FORMAT_XRGB8888;
   else if (output_fmts & SOFTFILTER_FMT_RGB565)
      filt->out_pix_fmt = RETRO_PIXEL_FORMAT_RGB565;
   else
   {
      RARCH_ERR("Did not find suitable output format for softfilter.\n");
      goto error;
   }

   filt->max_width = max_width;
   filt->max_height = max_height;

   filt->impl_data = filt->impl->create(input_fmt, input_fmt, max_width, max_height,
         threads != RARCH_SOFTFILTER_THREADS_AUTO ? threads : rarch_get_cpu_cores(), cpu_features);
   if (!filt->impl_data)
   {
      RARCH_ERR("Failed to create softfilter state.\n");
      goto error;
   }

   threads = filt->impl->query_num_threads(filt->impl_data);
   if (!threads)
   {
      RARCH_ERR("Invalid number of threads.\n");
      goto error;
   }

   RARCH_LOG("Using %u threads for softfilter.\n", threads);

   filt->packets = (struct softfilter_work_packet*)calloc(threads, sizeof(*filt->packets));
   if (!filt->packets)
   {
      RARCH_ERR("Failed to allocate softfilter packets.\n");
      goto error;
   }

#ifdef HAVE_THREADS
   filt->thread_data = (struct filter_thread_data*)calloc(threads, sizeof(*filt->thread_data));
   if (!filt->thread_data)
      goto error;
   filt->threads = threads;

   for (i = 0; i < threads; i++)
   {
      filt->thread_data[i].userdata = filt->impl_data;
      filt->thread_data[i].done = true;

      filt->thread_data[i].lock = slock_new();
      if (!filt->thread_data[i].lock)
         goto error;
      filt->thread_data[i].cond = scond_new();
      if (!filt->thread_data[i].cond)
         goto error;
      filt->thread_data[i].thread = sthread_create(filter_thread_loop, &filt->thread_data[i]);
      if (!filt->thread_data[i].thread)
         goto error;
   }
#endif

   return filt;

error:
   rarch_softfilter_free(filt);
   return NULL;
}
Ejemplo n.º 27
0
static void load_symbols(bool is_dummy)
{
   if (is_dummy)
   {
      SYM_DUMMY(retro_init);
      SYM_DUMMY(retro_deinit);

      SYM_DUMMY(retro_api_version);
      SYM_DUMMY(retro_get_system_info);
      SYM_DUMMY(retro_get_system_av_info);

      SYM_DUMMY(retro_set_environment);
      SYM_DUMMY(retro_set_video_refresh);
      SYM_DUMMY(retro_set_audio_sample);
      SYM_DUMMY(retro_set_audio_sample_batch);
      SYM_DUMMY(retro_set_input_poll);
      SYM_DUMMY(retro_set_input_state);

      SYM_DUMMY(retro_set_controller_port_device);

      SYM_DUMMY(retro_reset);
      SYM_DUMMY(retro_run);

      SYM_DUMMY(retro_serialize_size);
      SYM_DUMMY(retro_serialize);
      SYM_DUMMY(retro_unserialize);

      SYM_DUMMY(retro_cheat_reset);
      SYM_DUMMY(retro_cheat_set);

      SYM_DUMMY(retro_load_game);
      SYM_DUMMY(retro_load_game_special);

      SYM_DUMMY(retro_unload_game);
      SYM_DUMMY(retro_get_region);
      SYM_DUMMY(retro_get_memory_data);
      SYM_DUMMY(retro_get_memory_size);
   }
   else
   {
#ifdef HAVE_DYNAMIC
      if (path_is_directory(g_settings.libretro))
      {
         char libretro_core_buffer[PATH_MAX];
         if (!find_first_libretro(libretro_core_buffer, sizeof(libretro_core_buffer),
                  g_settings.libretro, g_extern.fullpath))
         {
            RARCH_ERR("libretro_path is a directory, but no valid libretro implementation was found.\n");
            rarch_fail(1, "load_dynamic()");
         }

         strlcpy(g_settings.libretro, libretro_core_buffer, sizeof(g_settings.libretro));
      }

      // Need to use absolute path for this setting. It can be saved to ROM history,
      // and a relative path would break in that scenario.
      path_resolve_realpath(g_settings.libretro, sizeof(g_settings.libretro));

      RARCH_LOG("Loading dynamic libretro from: \"%s\"\n", g_settings.libretro);
      lib_handle = dylib_load(g_settings.libretro);
      if (!lib_handle)
      {
         RARCH_ERR("Failed to open dynamic library: \"%s\"\n", g_settings.libretro);
         rarch_fail(1, "load_dynamic()");
      }
#endif

      SYM(retro_init);
      SYM(retro_deinit);

      SYM(retro_api_version);
      SYM(retro_get_system_info);
      SYM(retro_get_system_av_info);

      SYM(retro_set_environment);
      SYM(retro_set_video_refresh);
      SYM(retro_set_audio_sample);
      SYM(retro_set_audio_sample_batch);
      SYM(retro_set_input_poll);
      SYM(retro_set_input_state);

      SYM(retro_set_controller_port_device);

      SYM(retro_reset);
      SYM(retro_run);

      SYM(retro_serialize_size);
      SYM(retro_serialize);
      SYM(retro_unserialize);

      SYM(retro_cheat_reset);
      SYM(retro_cheat_set);

      SYM(retro_load_game);
      SYM(retro_load_game_special);

      SYM(retro_unload_game);
      SYM(retro_get_region);
      SYM(retro_get_memory_data);
      SYM(retro_get_memory_size);
   }
}