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; }
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; }
static void gfx_set_dwm(void) { HRESULT ret; HRESULT (WINAPI *composition_enable)(UINT); settings_t *settings = config_get_ptr(); if (!gfx_init_dwm()) return; if (settings->bools.video_disable_composition == dwm_composition_disabled) return; #ifdef HAVE_DYNAMIC composition_enable = (HRESULT (WINAPI*)(UINT))dylib_proc(dwmlib, "DwmEnableComposition"); #endif if (!composition_enable) { RARCH_ERR("Did not find DwmEnableComposition ...\n"); return; } ret = composition_enable(!settings->bools.video_disable_composition); if (FAILED(ret)) RARCH_ERR("Failed to set composition state ...\n"); dwm_composition_disabled = settings->bools.video_disable_composition; }
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; }
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; }
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); }
void init_libretro_sym(bool dummy) { // Guarantee that we can do "dirty" casting. // Every OS that this program supports should pass this ... rarch_assert(sizeof(void*) == sizeof(void (*)(void))); if (!dummy) { #ifdef HAVE_DYNAMIC // Try to verify that -lretro was not linked in from other modules // since loading it dynamically and with -l will fail hard. function_t sym = dylib_proc(NULL, "retro_init"); if (sym) { RARCH_ERR("Serious problem. RetroArch wants to load libretro 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"); rarch_fail(1, "init_libretro_sym()"); } if (!*g_settings.libretro) { RARCH_ERR("RetroArch is built for dynamic libretro, but libretro_path is not set. Cannot continue.\n"); rarch_fail(1, "init_libretro_sym()"); } #endif } load_symbols(dummy); pretro_set_environment(environment_cb); }
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; }
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; }
static void frontend_win32_init(void *data) { typedef BOOL (WINAPI *isProcessDPIAwareProc)(); typedef BOOL (WINAPI *setProcessDPIAwareProc)(); HMODULE handle = GetModuleHandle(TEXT("User32.dll")); isProcessDPIAwareProc isDPIAwareProc = (isProcessDPIAwareProc)dylib_proc(handle, "IsProcessDPIAware"); setProcessDPIAwareProc setDPIAwareProc = (setProcessDPIAwareProc)dylib_proc(handle, "SetProcessDPIAware"); if (isDPIAwareProc) { if (!isDPIAwareProc()) { if (setDPIAwareProc) setDPIAwareProc(); } } }
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; }
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; }
static void frontend_win32_init(void *data) { typedef BOOL (WINAPI *isProcessDPIAwareProc)(); typedef BOOL (WINAPI *setProcessDPIAwareProc)(); #ifdef HAVE_DYNAMIC HMODULE handle = GetModuleHandle("User32.dll"); isProcessDPIAwareProc isDPIAwareProc = (isProcessDPIAwareProc)dylib_proc(handle, "IsProcessDPIAware"); setProcessDPIAwareProc setDPIAwareProc = (setProcessDPIAwareProc)dylib_proc(handle, "SetProcessDPIAware"); #else isProcessDPIAwareProc isDPIAwareProc = IsProcessDPIAware; setProcessDPIAwareProc setDPIAwareProc = SetProcessDPIAware; #endif if (isDPIAwareProc) if (!isDPIAwareProc()) if (setDPIAwareProc) setDPIAwareProc(); }
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; }
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; }
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"); }
static bool btstack_try_load(void) { #ifdef HAVE_DYNAMIC unsigned i; #endif void *handle = NULL; if (btstack_tested) return btstack_loaded; btstack_tested = true; btstack_loaded = false; handle = btstack_get_handle(); if (!handle) return false; #ifdef HAVE_DYNAMIC for (i = 0; grabbers[i].name; i ++) { *grabbers[i].target = dylib_proc(handle, grabbers[i].name); if (!*grabbers[i].target) { dylib_close(handle); return false; } } #endif #if defined(HAVE_COCOA) || defined(HAVE_COCOATOUCH) run_loop_init_ptr(RUN_LOOP_COCOA); #else run_loop_init_ptr(RUN_LOOP_POSIX); #endif bt_register_packet_handler_ptr(btpad_packet_handler); btstack_loaded = true; return true; }
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()"); } }
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; }
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; }
/** * 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; } }
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(¶ms); } } return true; }
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; }