static void *ui_companion_qt_init(void) { ui_companion_qt_t *handle = (ui_companion_qt_t*)calloc(1, sizeof(*handle)); if (!handle) return NULL; #ifdef HAVE_QT_WRAPPER settings_t *settings = config_get_ptr(); handle->lock = slock_new(); handle->thread = sthread_create(qt_thread, handle); if (!handle->thread) { slock_free(handle->lock); free(handle); return NULL; } #endif return handle; }
void rarch_softfilter_free(rarch_softfilter_t *filt) { unsigned i = 0; (void)i; if (!filt) return; free(filt->packets); if (filt->impl && filt->impl_data) filt->impl->destroy(filt->impl_data); #ifdef HAVE_DYLIB for (i = 0; i < filt->num_plugs; i++) { if (filt->plugs[i].lib) dylib_close(filt->plugs[i].lib); } free(filt->plugs); #endif #ifdef HAVE_THREADS for (i = 0; i < filt->threads; i++) { if (!filt->thread_data[i].thread) continue; slock_lock(filt->thread_data[i].lock); filt->thread_data[i].die = true; scond_signal(filt->thread_data[i].cond); slock_unlock(filt->thread_data[i].lock); sthread_join(filt->thread_data[i].thread); slock_free(filt->thread_data[i].lock); scond_free(filt->thread_data[i].cond); } free(filt->thread_data); #endif free(filt); }
static int remove_adapter(void *data, struct libusb_device *dev) { struct libusb_adapter *adapter = (struct libusb_adapter*)&adapters; struct libusb_hid *hid = (struct libusb_hid*)data; while (adapter->next == NULL) return -1; if (adapter->next->device == dev) { struct libusb_adapter *new_next = NULL; const char *name = (const char*)adapter->next->name; input_config_autoconfigure_disconnect(adapter->slot, name); adapter->next->quitting = true; sthread_join(adapter->next->thread); pad_connection_pad_deinit(&hid->slots[adapter->slot], adapter->slot); slock_free(adapter->send_control_lock); fifo_free(adapter->send_control_buffer); libusb_release_interface(adapter->next->handle, adapter->next->interface_number); libusb_close(adapter->next->handle); new_next = adapter->next->next; free(adapter->next); adapter->next = new_next; return 0; } adapter = adapter->next; return -1; }
static void ja_free(void *data) { int i; jack_t *jd = (jack_t*)data; jd->shutdown = true; if (jd->client != NULL) { jack_deactivate(jd->client); jack_client_close(jd->client); } for (i = 0; i < 2; i++) if (jd->buffer[i] != NULL) jack_ringbuffer_free(jd->buffer[i]); if (jd->cond_lock) slock_free(jd->cond_lock); if (jd->cond) scond_free(jd->cond); free(jd); }
static void sunxi_gfx_free(void *data) { struct sunxi_video *_dispvars = (struct sunxi_video*)data; /* Stop the vsync thread and wait for it to join. */ /* When menu is active, vsync thread has already been stopped. */ if (!_dispvars->menu_active) { _dispvars->keep_vsync = false; sthread_join(_dispvars->vsync_thread); } slock_free(_dispvars->pending_mutex); scond_free(_dispvars->vsync_condition); free(_dispvars->pages); /* Restore text console contents and reactivate cursor blinking. */ sunxi_restore_console(_dispvars); sunxi_disp_close(_dispvars->sunxi_disp); free(_dispvars); }
static void gfx_ctx_x_destroy(void *data) { gfx_ctx_x_data_t *x = (gfx_ctx_x_data_t*)data; if (!x) return; gfx_ctx_x_destroy_resources(x); switch (x_api) { case GFX_CTX_VULKAN_API: #ifdef HAVE_VULKAN if (x->vk.context.queue_lock) slock_free(x->vk.context.queue_lock); #endif break; case GFX_CTX_NONE: default: break; } free(data); }
static void audio_thread_free(void *data) { audio_thread_t *thr = (audio_thread_t*)data; if (!thr) return; if (thr->thread) { slock_lock(thr->lock); thr->stopped = false; thr->alive = false; scond_signal(thr->cond); slock_unlock(thr->lock); sthread_join(thr->thread); } if (thr->lock) slock_free(thr->lock); if (thr->cond) scond_free(thr->cond); free(thr); }
static void gfx_ctx_wl_destroy(void *data) { gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; if (!wl) return; gfx_ctx_wl_destroy_resources(wl); switch (wl_api) { case GFX_CTX_VULKAN_API: #if defined(HAVE_VULKAN) && defined(HAVE_THREADS) if (wl->vk.context.queue_lock) slock_free(wl->vk.context.queue_lock); #endif break; case GFX_CTX_NONE: default: break; } free(wl); }
bool runloop_ctl(enum runloop_ctl_state state, void *data) { static rarch_dir_list_t runloop_shader_dir; static char runloop_fullpath[PATH_MAX_LENGTH]; static rarch_system_info_t runloop_system; static unsigned runloop_pending_windowed_scale; static retro_keyboard_event_t runloop_key_event = NULL; static unsigned runloop_max_frames = false; static bool runloop_frame_time_last = false; static bool runloop_set_frame_limit = false; static bool runloop_paused = false; static bool runloop_idle = false; static bool runloop_exec = false; static bool runloop_slowmotion = false; static bool runloop_shutdown_initiated = false; static bool runloop_core_shutdown_initiated = false; static bool runloop_perfcnt_enable = false; static bool runloop_overrides_active = false; static bool runloop_game_options_active = false; #ifdef HAVE_THREADS static slock_t *runloop_msg_queue_lock = NULL; #endif static core_info_t *core_info_current = NULL; static core_info_list_t *core_info_curr_list = NULL; settings_t *settings = config_get_ptr(); switch (state) { case RUNLOOP_CTL_DATA_ITERATE: rarch_task_check(); return true; case RUNLOOP_CTL_SHADER_DIR_DEINIT: shader_dir_free(&runloop_shader_dir); return true; case RUNLOOP_CTL_SHADER_DIR_INIT: return shader_dir_init(&runloop_shader_dir); case RUNLOOP_CTL_SYSTEM_INFO_INIT: core.retro_get_system_info(&runloop_system.info); if (!runloop_system.info.library_name) runloop_system.info.library_name = msg_hash_to_str(MSG_UNKNOWN); if (!runloop_system.info.library_version) runloop_system.info.library_version = "v0"; #ifndef RARCH_CONSOLE strlcpy(runloop_system.title_buf, msg_hash_to_str(MSG_PROGRAM), sizeof(runloop_system.title_buf)); strlcat(runloop_system.title_buf, " : ", sizeof(runloop_system.title_buf)); #endif strlcat(runloop_system.title_buf, runloop_system.info.library_name, sizeof(runloop_system.title_buf)); strlcat(runloop_system.title_buf, " ", sizeof(runloop_system.title_buf)); strlcat(runloop_system.title_buf, runloop_system.info.library_version, sizeof(runloop_system.title_buf)); strlcpy(runloop_system.valid_extensions, runloop_system.info.valid_extensions ? runloop_system.info.valid_extensions : DEFAULT_EXT, sizeof(runloop_system.valid_extensions)); runloop_system.block_extract = runloop_system.info.block_extract; break; case RUNLOOP_CTL_GET_CORE_OPTION_SIZE: { unsigned *idx = (unsigned*)data; if (!idx) return false; *idx = core_option_size(runloop_system.core_options); } return true; case RUNLOOP_CTL_HAS_CORE_OPTIONS: return runloop_system.core_options; case RUNLOOP_CTL_CURRENT_CORE_LIST_FREE: if (core_info_curr_list) core_info_list_free(core_info_curr_list); core_info_curr_list = NULL; return true; case RUNLOOP_CTL_CURRENT_CORE_LIST_INIT: core_info_curr_list = core_info_list_new(); return true; case RUNLOOP_CTL_CURRENT_CORE_LIST_GET: { core_info_list_t **core = (core_info_list_t**)data; if (!core) return false; *core = core_info_curr_list; } return true; case RUNLOOP_CTL_CURRENT_CORE_FREE: if (core_info_current) free(core_info_current); core_info_current = NULL; return true; case RUNLOOP_CTL_CURRENT_CORE_INIT: core_info_current = (core_info_t*)calloc(1, sizeof(core_info_t)); if (!core_info_current) return false; return true; case RUNLOOP_CTL_CURRENT_CORE_GET: { core_info_t **core = (core_info_t**)data; if (!core) return false; *core = core_info_current; } return true; case RUNLOOP_CTL_SYSTEM_INFO_GET: { rarch_system_info_t **system = (rarch_system_info_t**)data; if (!system) return false; *system = &runloop_system; } return true; case RUNLOOP_CTL_SYSTEM_INFO_FREE: if (runloop_system.core_options) { core_option_flush(runloop_system.core_options); core_option_free(runloop_system.core_options); } runloop_system.core_options = NULL; /* No longer valid. */ if (runloop_system.special) free(runloop_system.special); runloop_system.special = NULL; if (runloop_system.ports) free(runloop_system.ports); runloop_system.ports = NULL; runloop_key_event = NULL; global_get_ptr()->frontend_key_event = NULL; audio_driver_unset_callback(); memset(&runloop_system, 0, sizeof(rarch_system_info_t)); break; case RUNLOOP_CTL_IS_FRAME_COUNT_END: { uint64_t *frame_count = NULL; video_driver_ctl(RARCH_DISPLAY_CTL_GET_FRAME_COUNT, &frame_count); return runloop_max_frames && (*frame_count >= runloop_max_frames); } case RUNLOOP_CTL_SET_FRAME_TIME_LAST: runloop_frame_time_last = true; break; case RUNLOOP_CTL_UNSET_FRAME_TIME_LAST: runloop_frame_time_last = false; break; case RUNLOOP_CTL_SET_OVERRIDES_ACTIVE: runloop_overrides_active = true; break; case RUNLOOP_CTL_UNSET_OVERRIDES_ACTIVE: runloop_overrides_active = false; break; case RUNLOOP_CTL_IS_OVERRIDES_ACTIVE: return runloop_overrides_active; case RUNLOOP_CTL_SET_GAME_OPTIONS_ACTIVE: runloop_game_options_active = true; break; case RUNLOOP_CTL_UNSET_GAME_OPTIONS_ACTIVE: runloop_game_options_active = false; break; case RUNLOOP_CTL_IS_GAME_OPTIONS_ACTIVE: return runloop_game_options_active; case RUNLOOP_CTL_IS_FRAME_TIME_LAST: return runloop_frame_time_last; case RUNLOOP_CTL_SET_FRAME_LIMIT: runloop_set_frame_limit = true; break; case RUNLOOP_CTL_UNSET_FRAME_LIMIT: runloop_set_frame_limit = false; break; case RUNLOOP_CTL_SHOULD_SET_FRAME_LIMIT: return runloop_set_frame_limit; case RUNLOOP_CTL_GET_PERFCNT: { bool **perfcnt = (bool**)data; if (!perfcnt) return false; *perfcnt = &runloop_perfcnt_enable; } return true; case RUNLOOP_CTL_SET_PERFCNT_ENABLE: runloop_perfcnt_enable = true; break; case RUNLOOP_CTL_UNSET_PERFCNT_ENABLE: runloop_perfcnt_enable = false; break; case RUNLOOP_CTL_IS_PERFCNT_ENABLE: return runloop_perfcnt_enable; case RUNLOOP_CTL_GET_WINDOWED_SCALE: { unsigned **scale = (unsigned**)data; if (!scale) return false; *scale = (unsigned*)&runloop_pending_windowed_scale; } break; case RUNLOOP_CTL_SET_WINDOWED_SCALE: { unsigned *idx = (unsigned*)data; if (!idx) return false; runloop_pending_windowed_scale = *idx; } break; case RUNLOOP_CTL_SET_LIBRETRO_PATH: { const char *fullpath = (const char*)data; if (!fullpath) return false; strlcpy(settings->libretro, fullpath, sizeof(settings->libretro)); } break; case RUNLOOP_CTL_CLEAR_CONTENT_PATH: *runloop_fullpath = '\0'; break; case RUNLOOP_CTL_GET_CONTENT_PATH: { char **fullpath = (char**)data; if (!fullpath) return false; *fullpath = (char*)runloop_fullpath; } break; case RUNLOOP_CTL_SET_CONTENT_PATH: { const char *fullpath = (const char*)data; if (!fullpath) return false; strlcpy(runloop_fullpath, fullpath, sizeof(runloop_fullpath)); } break; case RUNLOOP_CTL_CHECK_FOCUS: if (settings->pause_nonactive) return video_driver_ctl(RARCH_DISPLAY_CTL_IS_FOCUSED, NULL); return true; case RUNLOOP_CTL_CHECK_IDLE_STATE: { event_cmd_state_t *cmd = (event_cmd_state_t*)data; bool focused = runloop_ctl(RUNLOOP_CTL_CHECK_FOCUS, NULL); check_pause(settings, focused, runloop_cmd_triggered(cmd, RARCH_PAUSE_TOGGLE), runloop_cmd_triggered(cmd, RARCH_FRAMEADVANCE)); if (!runloop_ctl(RUNLOOP_CTL_CHECK_PAUSE_STATE, cmd) || !focused) return false; break; } case RUNLOOP_CTL_CHECK_STATE: { bool tmp = false; event_cmd_state_t *cmd = (event_cmd_state_t*)data; if (!cmd || runloop_idle) return false; if (runloop_cmd_triggered(cmd, RARCH_SCREENSHOT)) event_command(EVENT_CMD_TAKE_SCREENSHOT); if (runloop_cmd_triggered(cmd, RARCH_MUTE)) event_command(EVENT_CMD_AUDIO_MUTE_TOGGLE); if (runloop_cmd_triggered(cmd, RARCH_OSK)) { if (input_driver_ctl(RARCH_INPUT_CTL_IS_KEYBOARD_LINEFEED_ENABLED, NULL)) input_driver_ctl(RARCH_INPUT_CTL_UNSET_KEYBOARD_LINEFEED_ENABLED, NULL); else input_driver_ctl(RARCH_INPUT_CTL_SET_KEYBOARD_LINEFEED_ENABLED, NULL); } if (runloop_cmd_press(cmd, RARCH_VOLUME_UP)) event_command(EVENT_CMD_VOLUME_UP); else if (runloop_cmd_press(cmd, RARCH_VOLUME_DOWN)) event_command(EVENT_CMD_VOLUME_DOWN); #ifdef HAVE_NETPLAY tmp = runloop_cmd_triggered(cmd, RARCH_NETPLAY_FLIP); netplay_driver_ctl(RARCH_NETPLAY_CTL_FLIP_PLAYERS, &tmp); tmp = runloop_cmd_triggered(cmd, RARCH_FULLSCREEN_TOGGLE_KEY); netplay_driver_ctl(RARCH_NETPLAY_CTL_FULLSCREEN_TOGGLE, &tmp); #endif if (!runloop_ctl(RUNLOOP_CTL_CHECK_IDLE_STATE, data)) return false; check_fast_forward_button( runloop_cmd_triggered(cmd, RARCH_FAST_FORWARD_KEY), runloop_cmd_press (cmd, RARCH_FAST_FORWARD_HOLD_KEY), runloop_cmd_pressed (cmd, RARCH_FAST_FORWARD_HOLD_KEY)); check_stateslots(settings, runloop_cmd_triggered(cmd, RARCH_STATE_SLOT_PLUS), runloop_cmd_triggered(cmd, RARCH_STATE_SLOT_MINUS) ); if (runloop_cmd_triggered(cmd, RARCH_SAVE_STATE_KEY)) event_command(EVENT_CMD_SAVE_STATE); else if (runloop_cmd_triggered(cmd, RARCH_LOAD_STATE_KEY)) event_command(EVENT_CMD_LOAD_STATE); state_manager_check_rewind(runloop_cmd_press(cmd, RARCH_REWIND)); tmp = runloop_cmd_press(cmd, RARCH_SLOWMOTION); runloop_ctl(RUNLOOP_CTL_CHECK_SLOWMOTION, &tmp); if (runloop_cmd_triggered(cmd, RARCH_MOVIE_RECORD_TOGGLE)) runloop_ctl(RUNLOOP_CTL_CHECK_MOVIE, NULL); check_shader_dir(&runloop_shader_dir, runloop_cmd_triggered(cmd, RARCH_SHADER_NEXT), runloop_cmd_triggered(cmd, RARCH_SHADER_PREV)); if (runloop_cmd_triggered(cmd, RARCH_DISK_EJECT_TOGGLE)) event_command(EVENT_CMD_DISK_EJECT_TOGGLE); else if (runloop_cmd_triggered(cmd, RARCH_DISK_NEXT)) event_command(EVENT_CMD_DISK_NEXT); else if (runloop_cmd_triggered(cmd, RARCH_DISK_PREV)) event_command(EVENT_CMD_DISK_PREV); if (runloop_cmd_triggered(cmd, RARCH_RESET)) event_command(EVENT_CMD_RESET); cheat_manager_state_checks( runloop_cmd_triggered(cmd, RARCH_CHEAT_INDEX_PLUS), runloop_cmd_triggered(cmd, RARCH_CHEAT_INDEX_MINUS), runloop_cmd_triggered(cmd, RARCH_CHEAT_TOGGLE)); } break; case RUNLOOP_CTL_CHECK_PAUSE_STATE: { bool check_is_oneshot; event_cmd_state_t *cmd = (event_cmd_state_t*)data; if (!cmd) return false; check_is_oneshot = runloop_cmd_triggered(cmd, RARCH_FRAMEADVANCE) || runloop_cmd_press(cmd, RARCH_REWIND); if (!runloop_paused) return true; if (runloop_cmd_triggered(cmd, RARCH_FULLSCREEN_TOGGLE_KEY)) { event_command(EVENT_CMD_FULLSCREEN_TOGGLE); video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, NULL); } if (!check_is_oneshot) return false; } break; case RUNLOOP_CTL_CHECK_SLOWMOTION: { bool *ptr = (bool*)data; if (!ptr) return false; runloop_slowmotion = *ptr; if (!runloop_slowmotion) return false; if (settings->video.black_frame_insertion) video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, NULL); if (state_manager_frame_is_reversed()) runloop_msg_queue_push_new(MSG_SLOW_MOTION_REWIND, 0, 30, true); else runloop_msg_queue_push_new(MSG_SLOW_MOTION, 0, 30, true); } break; case RUNLOOP_CTL_CHECK_MOVIE: if (bsv_movie_ctl(BSV_MOVIE_CTL_PLAYBACK_ON, NULL)) return runloop_ctl(RUNLOOP_CTL_CHECK_MOVIE_PLAYBACK, NULL); if (!bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) return runloop_ctl(RUNLOOP_CTL_CHECK_MOVIE_INIT, NULL); return runloop_ctl(RUNLOOP_CTL_CHECK_MOVIE_RECORD, NULL); case RUNLOOP_CTL_CHECK_MOVIE_RECORD: if (!bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) return false; runloop_msg_queue_push_new( MSG_MOVIE_RECORD_STOPPED, 2, 180, true); RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_RECORD_STOPPED)); event_command(EVENT_CMD_BSV_MOVIE_DEINIT); break; case RUNLOOP_CTL_CHECK_MOVIE_INIT: if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) return false; { char msg[128]; char path[PATH_MAX_LENGTH]; settings->rewind_granularity = 1; if (settings->state_slot > 0) snprintf(path, sizeof(path), "%s%d", bsv_movie_get_path(), settings->state_slot); else strlcpy(path, bsv_movie_get_path(), sizeof(path)); strlcat(path, ".bsv", sizeof(path)); snprintf(msg, sizeof(msg), "%s \"%s\".", msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), path); bsv_movie_init_handle(path, RARCH_MOVIE_RECORD); if (!bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) return false; else if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) { runloop_msg_queue_push(msg, 1, 180, true); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), path); } else { runloop_msg_queue_push_new( MSG_FAILED_TO_START_MOVIE_RECORD, 1, 180, true); RARCH_ERR("%s\n", msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD)); } } break; case RUNLOOP_CTL_CHECK_MOVIE_PLAYBACK: if (!bsv_movie_ctl(BSV_MOVIE_CTL_END, NULL)) return false; runloop_msg_queue_push_new( MSG_MOVIE_PLAYBACK_ENDED, 1, 180, false); RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_PLAYBACK_ENDED)); event_command(EVENT_CMD_BSV_MOVIE_DEINIT); bsv_movie_ctl(BSV_MOVIE_CTL_UNSET_END, NULL); bsv_movie_ctl(BSV_MOVIE_CTL_UNSET_PLAYBACK, NULL); break; case RUNLOOP_CTL_STATE_FREE: runloop_perfcnt_enable = false; runloop_idle = false; runloop_paused = false; runloop_slowmotion = false; runloop_frame_time_last = false; runloop_set_frame_limit = false; runloop_overrides_active = false; runloop_max_frames = 0; break; case RUNLOOP_CTL_GLOBAL_FREE: { global_t *global; event_command(EVENT_CMD_TEMPORARY_CONTENT_DEINIT); event_command(EVENT_CMD_SUBSYSTEM_FULLPATHS_DEINIT); event_command(EVENT_CMD_RECORD_DEINIT); event_command(EVENT_CMD_LOG_FILE_DEINIT); rarch_ctl(RARCH_CTL_UNSET_BLOCK_CONFIG_READ, NULL); runloop_ctl(RUNLOOP_CTL_CLEAR_CONTENT_PATH, NULL); runloop_overrides_active = false; global = global_get_ptr(); memset(global, 0, sizeof(struct global)); } break; case RUNLOOP_CTL_CLEAR_STATE: driver_ctl(RARCH_DRIVER_CTL_DEINIT, NULL); runloop_ctl(RUNLOOP_CTL_STATE_FREE, NULL); runloop_ctl(RUNLOOP_CTL_GLOBAL_FREE, NULL); break; case RUNLOOP_CTL_SET_MAX_FRAMES: { unsigned *ptr = (unsigned*)data; if (!ptr) return false; runloop_max_frames = *ptr; } break; case RUNLOOP_CTL_IS_IDLE: return runloop_idle; case RUNLOOP_CTL_SET_IDLE: { bool *ptr = (bool*)data; if (!ptr) return false; runloop_idle = *ptr; } break; case RUNLOOP_CTL_IS_SLOWMOTION: { bool *ptr = (bool*)data; if (!ptr) return false; *ptr = runloop_slowmotion; } break; case RUNLOOP_CTL_SET_SLOWMOTION: { bool *ptr = (bool*)data; if (!ptr) return false; runloop_slowmotion = *ptr; } break; case RUNLOOP_CTL_SET_PAUSED: { bool *ptr = (bool*)data; if (!ptr) return false; runloop_paused = *ptr; } break; case RUNLOOP_CTL_IS_PAUSED: return runloop_paused; case RUNLOOP_CTL_MSG_QUEUE_FREE: #ifdef HAVE_THREADS slock_free(runloop_msg_queue_lock); runloop_msg_queue_lock = NULL; #endif break; case RUNLOOP_CTL_MSG_QUEUE_DEINIT: if (!g_msg_queue) return true; runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_LOCK, NULL); msg_queue_free(g_msg_queue); runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_UNLOCK, NULL); runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_FREE, NULL); g_msg_queue = NULL; break; case RUNLOOP_CTL_MSG_QUEUE_INIT: runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_DEINIT, NULL); g_msg_queue = msg_queue_new(8); retro_assert(g_msg_queue); #ifdef HAVE_THREADS runloop_msg_queue_lock = slock_new(); retro_assert(runloop_msg_queue_lock); #endif break; case RUNLOOP_CTL_MSG_QUEUE_LOCK: #ifdef HAVE_THREADS slock_lock(runloop_msg_queue_lock); #endif break; case RUNLOOP_CTL_MSG_QUEUE_UNLOCK: #ifdef HAVE_THREADS slock_unlock(runloop_msg_queue_lock); #endif break; case RUNLOOP_CTL_PREPARE_DUMMY: #ifdef HAVE_MENU menu_driver_ctl(RARCH_MENU_CTL_UNSET_LOAD_NO_CONTENT, NULL); #endif runloop_data_clear_state(); runloop_ctl(RUNLOOP_CTL_CLEAR_CONTENT_PATH, NULL); rarch_ctl(RARCH_CTL_LOAD_CONTENT, NULL); break; case RUNLOOP_CTL_SET_CORE_SHUTDOWN: runloop_core_shutdown_initiated = true; break; case RUNLOOP_CTL_UNSET_CORE_SHUTDOWN: runloop_core_shutdown_initiated = false; break; case RUNLOOP_CTL_IS_CORE_SHUTDOWN: return runloop_core_shutdown_initiated; case RUNLOOP_CTL_SET_SHUTDOWN: runloop_shutdown_initiated = true; break; case RUNLOOP_CTL_UNSET_SHUTDOWN: runloop_shutdown_initiated = false; break; case RUNLOOP_CTL_IS_SHUTDOWN: return runloop_shutdown_initiated; case RUNLOOP_CTL_SET_EXEC: runloop_exec = true; break; case RUNLOOP_CTL_UNSET_EXEC: runloop_exec = false; break; case RUNLOOP_CTL_IS_EXEC: return runloop_exec; case RUNLOOP_CTL_DATA_DEINIT: rarch_task_deinit(); break; case RUNLOOP_CTL_IS_CORE_OPTION_UPDATED: return runloop_system.core_options ? core_option_updated(runloop_system.core_options) : false; case RUNLOOP_CTL_CORE_OPTION_PREV: { unsigned *idx = (unsigned*)data; if (!idx) return false; core_option_prev(runloop_system.core_options, *idx); if (ui_companion_is_on_foreground()) ui_companion_driver_notify_refresh(); } return true; case RUNLOOP_CTL_CORE_OPTION_NEXT: { unsigned *idx = (unsigned*)data; if (!idx) return false; core_option_next(runloop_system.core_options, *idx); if (ui_companion_is_on_foreground()) ui_companion_driver_notify_refresh(); } return true; case RUNLOOP_CTL_CORE_OPTIONS_GET: { struct retro_variable *var = (struct retro_variable*)data; if (!runloop_system.core_options || !var) return false; RARCH_LOG("Environ GET_VARIABLE %s:\n", var->key); core_option_get(runloop_system.core_options, var); RARCH_LOG("\t%s\n", var->value ? var->value : "N/A"); } return true; case RUNLOOP_CTL_CORE_OPTIONS_INIT: { char *game_options_path = NULL; bool ret = false; const struct retro_variable *vars = (const struct retro_variable*)data; char buf[PATH_MAX_LENGTH] = {0}; global_t *global = global_get_ptr(); const char *options_path = settings->core_options_path; if (!*options_path && *global->path.config) { fill_pathname_resolve_relative(buf, global->path.config, "retroarch-core-options.cfg", sizeof(buf)); options_path = buf; } if (settings->game_specific_options) ret = rarch_game_specific_options(&game_options_path); if(ret) { runloop_ctl(RUNLOOP_CTL_SET_GAME_OPTIONS_ACTIVE, NULL); runloop_system.core_options = core_option_new(game_options_path, vars); free(game_options_path); } else { runloop_ctl(RUNLOOP_CTL_UNSET_GAME_OPTIONS_ACTIVE, NULL); runloop_system.core_options = core_option_new(options_path, vars); } } break; case RUNLOOP_CTL_CORE_OPTIONS_DEINIT: if (!runloop_system.core_options) return false; core_option_flush(runloop_system.core_options); core_option_free(runloop_system.core_options); runloop_system.core_options = NULL; return true; case RUNLOOP_CTL_KEY_EVENT_GET: { retro_keyboard_event_t **key_event = (retro_keyboard_event_t**)data; if (!key_event) return false; *key_event = &runloop_key_event; } break; case RUNLOOP_CTL_NONE: default: return false; } return true; }
bool runloop_ctl(enum runloop_ctl_state state, void *data) { switch (state) { case RUNLOOP_CTL_SHADER_DIR_DEINIT: shader_dir_free(&runloop_shader_dir); break; case RUNLOOP_CTL_SHADER_DIR_INIT: return shader_dir_init(&runloop_shader_dir); case RUNLOOP_CTL_SYSTEM_INFO_INIT: core_get_system_info(&runloop_system.info); if (!runloop_system.info.library_name) runloop_system.info.library_name = msg_hash_to_str(MSG_UNKNOWN); if (!runloop_system.info.library_version) runloop_system.info.library_version = "v0"; video_driver_set_title_buf(); strlcpy(runloop_system.valid_extensions, runloop_system.info.valid_extensions ? runloop_system.info.valid_extensions : DEFAULT_EXT, sizeof(runloop_system.valid_extensions)); break; case RUNLOOP_CTL_GET_CORE_OPTION_SIZE: { unsigned *idx = (unsigned*)data; if (!idx) return false; *idx = core_option_manager_size(runloop_core_options); } break; case RUNLOOP_CTL_HAS_CORE_OPTIONS: return runloop_core_options; case RUNLOOP_CTL_CORE_OPTIONS_LIST_GET: { core_option_manager_t **coreopts = (core_option_manager_t**)data; if (!coreopts) return false; *coreopts = runloop_core_options; } break; case RUNLOOP_CTL_SYSTEM_INFO_GET: { rarch_system_info_t **system = (rarch_system_info_t**)data; if (!system) return false; *system = &runloop_system; } break; case RUNLOOP_CTL_SYSTEM_INFO_FREE: /* No longer valid. */ if (runloop_system.subsystem.data) free(runloop_system.subsystem.data); runloop_system.subsystem.data = NULL; runloop_system.subsystem.size = 0; if (runloop_system.ports.data) free(runloop_system.ports.data); runloop_system.ports.data = NULL; runloop_system.ports.size = 0; if (runloop_system.mmaps.descriptors) free((void *)runloop_system.mmaps.descriptors); runloop_system.mmaps.descriptors = NULL; runloop_system.mmaps.num_descriptors = 0; runloop_key_event = NULL; runloop_frontend_key_event = NULL; audio_driver_unset_callback(); memset(&runloop_system, 0, sizeof(rarch_system_info_t)); break; case RUNLOOP_CTL_SET_FRAME_TIME_LAST: runloop_frame_time_last_enable = true; break; case RUNLOOP_CTL_UNSET_FRAME_TIME_LAST: if (!runloop_ctl(RUNLOOP_CTL_IS_FRAME_TIME_LAST, NULL)) return false; runloop_frame_time_last = 0; runloop_frame_time_last_enable = false; break; case RUNLOOP_CTL_SET_OVERRIDES_ACTIVE: runloop_overrides_active = true; break; case RUNLOOP_CTL_UNSET_OVERRIDES_ACTIVE: runloop_overrides_active = false; break; case RUNLOOP_CTL_IS_OVERRIDES_ACTIVE: return runloop_overrides_active; case RUNLOOP_CTL_SET_GAME_OPTIONS_ACTIVE: runloop_game_options_active = true; break; case RUNLOOP_CTL_UNSET_GAME_OPTIONS_ACTIVE: runloop_game_options_active = false; break; case RUNLOOP_CTL_IS_GAME_OPTIONS_ACTIVE: return runloop_game_options_active; case RUNLOOP_CTL_IS_FRAME_TIME_LAST: return runloop_frame_time_last_enable; case RUNLOOP_CTL_SET_FRAME_LIMIT: runloop_set_frame_limit = true; break; case RUNLOOP_CTL_UNSET_FRAME_LIMIT: runloop_set_frame_limit = false; break; case RUNLOOP_CTL_SHOULD_SET_FRAME_LIMIT: return runloop_set_frame_limit; case RUNLOOP_CTL_GET_PERFCNT: { bool **perfcnt = (bool**)data; if (!perfcnt) return false; *perfcnt = &runloop_perfcnt_enable; } break; case RUNLOOP_CTL_SET_PERFCNT_ENABLE: runloop_perfcnt_enable = true; break; case RUNLOOP_CTL_UNSET_PERFCNT_ENABLE: runloop_perfcnt_enable = false; break; case RUNLOOP_CTL_IS_PERFCNT_ENABLE: return runloop_perfcnt_enable; case RUNLOOP_CTL_SET_NONBLOCK_FORCED: runloop_force_nonblock = true; break; case RUNLOOP_CTL_UNSET_NONBLOCK_FORCED: runloop_force_nonblock = false; break; case RUNLOOP_CTL_IS_NONBLOCK_FORCED: return runloop_force_nonblock; case RUNLOOP_CTL_SET_FRAME_TIME: { const struct retro_frame_time_callback *info = (const struct retro_frame_time_callback*)data; #ifdef HAVE_NETPLAY global_t *global = global_get_ptr(); /* retro_run() will be called in very strange and * mysterious ways, have to disable it. */ if (global->netplay.enable) return false; #endif runloop_frame_time = *info; } break; case RUNLOOP_CTL_GET_WINDOWED_SCALE: { unsigned **scale = (unsigned**)data; if (!scale) return false; *scale = (unsigned*)&runloop_pending_windowed_scale; } break; case RUNLOOP_CTL_SET_WINDOWED_SCALE: { unsigned *idx = (unsigned*)data; if (!idx) return false; runloop_pending_windowed_scale = *idx; } break; case RUNLOOP_CTL_SET_LIBRETRO_PATH: { const char *fullpath = (const char*)data; if (!fullpath) return false; config_set_active_core_path(fullpath); } break; case RUNLOOP_CTL_CLEAR_CONTENT_PATH: *runloop_fullpath = '\0'; break; case RUNLOOP_CTL_GET_CONTENT_PATH: { char **fullpath = (char**)data; if (!fullpath) return false; *fullpath = (char*)runloop_fullpath; } break; case RUNLOOP_CTL_SET_CONTENT_PATH: { const char *fullpath = (const char*)data; if (!fullpath) return false; strlcpy(runloop_fullpath, fullpath, sizeof(runloop_fullpath)); } break; case RUNLOOP_CTL_CLEAR_DEFAULT_SHADER_PRESET: *runloop_default_shader_preset = '\0'; break; case RUNLOOP_CTL_GET_DEFAULT_SHADER_PRESET: { char **preset = (char**)data; if (!preset) return false; *preset = (char*)runloop_default_shader_preset; } break; case RUNLOOP_CTL_SET_DEFAULT_SHADER_PRESET: { const char *preset = (const char*)data; if (!preset) return false; strlcpy(runloop_default_shader_preset, preset, sizeof(runloop_default_shader_preset)); } break; case RUNLOOP_CTL_FRAME_TIME_FREE: memset(&runloop_frame_time, 0, sizeof(struct retro_frame_time_callback)); runloop_frame_time_last = 0; runloop_max_frames = 0; break; case RUNLOOP_CTL_STATE_FREE: runloop_perfcnt_enable = false; runloop_idle = false; runloop_paused = false; runloop_slowmotion = false; runloop_frame_time_last_enable = false; runloop_set_frame_limit = false; runloop_overrides_active = false; runloop_ctl(RUNLOOP_CTL_FRAME_TIME_FREE, NULL); break; case RUNLOOP_CTL_GLOBAL_FREE: { global_t *global = NULL; command_event(CMD_EVENT_TEMPORARY_CONTENT_DEINIT, NULL); command_event(CMD_EVENT_SUBSYSTEM_FULLPATHS_DEINIT, NULL); command_event(CMD_EVENT_RECORD_DEINIT, NULL); command_event(CMD_EVENT_LOG_FILE_DEINIT, NULL); rarch_ctl(RARCH_CTL_UNSET_BLOCK_CONFIG_READ, NULL); runloop_ctl(RUNLOOP_CTL_CLEAR_CONTENT_PATH, NULL); runloop_overrides_active = false; core_unset_input_descriptors(); global = global_get_ptr(); memset(global, 0, sizeof(struct global)); config_free_state(); } break; case RUNLOOP_CTL_CLEAR_STATE: driver_ctl(RARCH_DRIVER_CTL_DEINIT, NULL); runloop_ctl(RUNLOOP_CTL_STATE_FREE, NULL); runloop_ctl(RUNLOOP_CTL_GLOBAL_FREE, NULL); break; case RUNLOOP_CTL_SET_MAX_FRAMES: { unsigned *ptr = (unsigned*)data; if (!ptr) return false; runloop_max_frames = *ptr; } break; case RUNLOOP_CTL_IS_IDLE: return runloop_idle; case RUNLOOP_CTL_SET_IDLE: { bool *ptr = (bool*)data; if (!ptr) return false; runloop_idle = *ptr; } break; case RUNLOOP_CTL_IS_SLOWMOTION: return runloop_slowmotion; case RUNLOOP_CTL_SET_SLOWMOTION: { bool *ptr = (bool*)data; if (!ptr) return false; runloop_slowmotion = *ptr; } break; case RUNLOOP_CTL_SET_PAUSED: { bool *ptr = (bool*)data; if (!ptr) return false; runloop_paused = *ptr; } break; case RUNLOOP_CTL_IS_PAUSED: return runloop_paused; case RUNLOOP_CTL_MSG_QUEUE_PULL: runloop_msg_queue_lock(); { const char **ret = (const char**)data; if (!ret) return false; *ret = msg_queue_pull(runloop_msg_queue); } runloop_msg_queue_unlock(); break; case RUNLOOP_CTL_MSG_QUEUE_FREE: #ifdef HAVE_THREADS slock_free(_runloop_msg_queue_lock); _runloop_msg_queue_lock = NULL; #endif break; case RUNLOOP_CTL_MSG_QUEUE_CLEAR: msg_queue_clear(runloop_msg_queue); break; case RUNLOOP_CTL_MSG_QUEUE_DEINIT: if (!runloop_msg_queue) return true; runloop_msg_queue_lock(); msg_queue_free(runloop_msg_queue); runloop_msg_queue_unlock(); runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_FREE, NULL); runloop_msg_queue = NULL; break; case RUNLOOP_CTL_MSG_QUEUE_INIT: runloop_ctl(RUNLOOP_CTL_MSG_QUEUE_DEINIT, NULL); runloop_msg_queue = msg_queue_new(8); retro_assert(runloop_msg_queue); #ifdef HAVE_THREADS _runloop_msg_queue_lock = slock_new(); retro_assert(_runloop_msg_queue_lock); #endif break; case RUNLOOP_CTL_TASK_INIT: { #ifdef HAVE_THREADS settings_t *settings = config_get_ptr(); bool threaded_enable = settings->threaded_data_runloop_enable; #else bool threaded_enable = false; #endif task_queue_ctl(TASK_QUEUE_CTL_DEINIT, NULL); task_queue_ctl(TASK_QUEUE_CTL_INIT, &threaded_enable); } break; case RUNLOOP_CTL_SET_CORE_SHUTDOWN: runloop_core_shutdown_initiated = true; break; case RUNLOOP_CTL_UNSET_CORE_SHUTDOWN: runloop_core_shutdown_initiated = false; break; case RUNLOOP_CTL_IS_CORE_SHUTDOWN: return runloop_core_shutdown_initiated; case RUNLOOP_CTL_SET_SHUTDOWN: runloop_shutdown_initiated = true; break; case RUNLOOP_CTL_UNSET_SHUTDOWN: runloop_shutdown_initiated = false; break; case RUNLOOP_CTL_IS_SHUTDOWN: return runloop_shutdown_initiated; case RUNLOOP_CTL_SET_EXEC: runloop_exec = true; break; case RUNLOOP_CTL_UNSET_EXEC: runloop_exec = false; break; case RUNLOOP_CTL_IS_EXEC: return runloop_exec; case RUNLOOP_CTL_DATA_DEINIT: task_queue_ctl(TASK_QUEUE_CTL_DEINIT, NULL); break; case RUNLOOP_CTL_IS_CORE_OPTION_UPDATED: if (!runloop_core_options) return false; return core_option_manager_updated(runloop_core_options); case RUNLOOP_CTL_CORE_OPTION_PREV: { unsigned *idx = (unsigned*)data; if (!idx) return false; core_option_manager_prev(runloop_core_options, *idx); if (ui_companion_is_on_foreground()) ui_companion_driver_notify_refresh(); } break; case RUNLOOP_CTL_CORE_OPTION_NEXT: { unsigned *idx = (unsigned*)data; if (!idx) return false; core_option_manager_next(runloop_core_options, *idx); if (ui_companion_is_on_foreground()) ui_companion_driver_notify_refresh(); } break; case RUNLOOP_CTL_CORE_OPTIONS_GET: { struct retro_variable *var = (struct retro_variable*)data; if (!runloop_core_options || !var) return false; RARCH_LOG("Environ GET_VARIABLE %s:\n", var->key); core_option_manager_get(runloop_core_options, var); RARCH_LOG("\t%s\n", var->value ? var->value : msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE)); } break; case RUNLOOP_CTL_CORE_OPTIONS_INIT: { char *game_options_path = NULL; bool ret = false; char buf[PATH_MAX_LENGTH] = {0}; global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); const char *options_path = settings->path.core_options; const struct retro_variable *vars = (const struct retro_variable*)data; if (string_is_empty(options_path) && !string_is_empty(global->path.config)) { fill_pathname_resolve_relative(buf, global->path.config, file_path_str(FILE_PATH_CORE_OPTIONS_CONFIG), sizeof(buf)); options_path = buf; } if (settings->game_specific_options) ret = rarch_game_specific_options(&game_options_path); if(ret) { runloop_ctl(RUNLOOP_CTL_SET_GAME_OPTIONS_ACTIVE, NULL); runloop_core_options = core_option_manager_new(game_options_path, vars); free(game_options_path); } else { runloop_ctl(RUNLOOP_CTL_UNSET_GAME_OPTIONS_ACTIVE, NULL); runloop_core_options = core_option_manager_new(options_path, vars); } } break; case RUNLOOP_CTL_CORE_OPTIONS_FREE: if (runloop_core_options) core_option_manager_free(runloop_core_options); runloop_core_options = NULL; break; case RUNLOOP_CTL_CORE_OPTIONS_DEINIT: { global_t *global = global_get_ptr(); if (!runloop_core_options) return false; /* check if game options file was just created and flush to that file instead */ if(global && !string_is_empty(global->path.core_options_path)) { core_option_manager_flush_game_specific(runloop_core_options, global->path.core_options_path); global->path.core_options_path[0] = '\0'; } else core_option_manager_flush(runloop_core_options); if (runloop_ctl(RUNLOOP_CTL_IS_GAME_OPTIONS_ACTIVE, NULL)) runloop_ctl(RUNLOOP_CTL_UNSET_GAME_OPTIONS_ACTIVE, NULL); runloop_ctl(RUNLOOP_CTL_CORE_OPTIONS_FREE, NULL); } break; case RUNLOOP_CTL_KEY_EVENT_GET: { retro_keyboard_event_t **key_event = (retro_keyboard_event_t**)data; if (!key_event) return false; *key_event = &runloop_key_event; } break; case RUNLOOP_CTL_FRONTEND_KEY_EVENT_GET: { retro_keyboard_event_t **key_event = (retro_keyboard_event_t**)data; if (!key_event) return false; *key_event = &runloop_frontend_key_event; } break; case RUNLOOP_CTL_HTTPSERVER_INIT: #if defined(HAVE_HTTPSERVER) && defined(HAVE_ZLIB) httpserver_init(8888); #endif break; case RUNLOOP_CTL_HTTPSERVER_DESTROY: #if defined(HAVE_HTTPSERVER) && defined(HAVE_ZLIB) httpserver_destroy(); #endif break; case RUNLOOP_CTL_NONE: default: break; } return true; }
void rarch_main_data_overlay_thread_uninit(void) { #ifdef HAVE_THREADS slock_free(overlay_lock); #endif }
static void gfx_ctx_vc_destroy(void *data) { vc_ctx_data_t *vc = (vc_ctx_data_t*)data; unsigned i; if (!vc) { g_egl_inited = false; return; } if (vc->egl.dpy) { for (i = 0; i < MAX_EGLIMAGE_TEXTURES; i++) { if (vc->eglBuffer[i] && peglDestroyImageKHR) { eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(vc->egl.dpy, vc->pbuff_surf, vc->pbuff_surf, vc->eglimage_ctx); peglDestroyImageKHR(vc->egl.dpy, vc->eglBuffer[i]); } if (vc->vgimage[i]) { eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(vc->egl.dpy, vc->pbuff_surf, vc->pbuff_surf, vc->eglimage_ctx); vgDestroyImage(vc->vgimage[i]); } } if (vc->egl.ctx) { gfx_ctx_vc_bind_api(data, vc_api, 0, 0); eglMakeCurrent(vc->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(vc->egl.dpy, vc->egl.ctx); } if (vc->egl.hw_ctx) eglDestroyContext(vc->egl.dpy, vc->egl.hw_ctx); if (vc->eglimage_ctx) { eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(vc->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(vc->egl.dpy, vc->eglimage_ctx); } if (vc->egl.surf) { gfx_ctx_vc_bind_api(data, vc_api, 0, 0); eglDestroySurface(vc->egl.dpy, vc->egl.surf); } if (vc->pbuff_surf) { eglBindAPI(EGL_OPENVG_API); eglDestroySurface(vc->egl.dpy, vc->pbuff_surf); } eglBindAPI(EGL_OPENVG_API); eglMakeCurrent(vc->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); gfx_ctx_vc_bind_api(data, vc_api, 0, 0); eglMakeCurrent(vc->egl.dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglTerminate(vc->egl.dpy); } vc->egl.ctx = NULL; vc->egl.hw_ctx = NULL; vc->eglimage_ctx = NULL; vc->egl.surf = NULL; vc->pbuff_surf = NULL; vc->egl.dpy = NULL; vc->egl.config = 0; g_egl_inited = false; for (i = 0; i < MAX_EGLIMAGE_TEXTURES; i++) { vc->eglBuffer[i] = NULL; vc->vgimage[i] = 0; } /* Stop generating vsync callbacks if we are doing so. * Don't destroy the context while cbs are being generated! */ if (vc->vsync_callback_set) vc_dispmanx_vsync_callback(vc->dispman_display, NULL, NULL); /* Destroy mutexes and conditions. */ slock_free(vc->vsync_condition_mutex); scond_free(vc->vsync_condition); }
static void gfx_ctx_wgl_destroy(void *data) { HWND window = win32_get_window(); gfx_ctx_wgl_data_t *wgl = (gfx_ctx_wgl_data_t*)data; switch (win32_api) { case GFX_CTX_OPENGL_API: #ifdef HAVE_OPENGL if (win32_hrc) { glFinish(); wglMakeCurrent(NULL, NULL); if (!video_driver_is_video_cache_context()) { if (win32_hw_hrc) wglDeleteContext(win32_hw_hrc); wglDeleteContext(win32_hrc); win32_hrc = NULL; win32_hw_hrc = NULL; } } #endif break; case GFX_CTX_VULKAN_API: #ifdef HAVE_VULKAN vulkan_context_destroy(&win32_vk, win32_vk.vk_surface != VK_NULL_HANDLE); if (win32_vk.context.queue_lock) slock_free(win32_vk.context.queue_lock); memset(&win32_vk, 0, sizeof(win32_vk)); #endif break; case GFX_CTX_NONE: default: break; } if (window && win32_hdc) { ReleaseDC(window, win32_hdc); win32_hdc = NULL; } if (window) { win32_monitor_from_window(); win32_destroy_window(); } if (g_win32_restore_desktop) { win32_monitor_get_info(); g_win32_restore_desktop = false; } #ifdef HAVE_DYNAMIC dylib_close(dll_handle); #endif if (wgl) free(wgl); wgl_adaptive_vsync = false; win32_core_hw_context_enable = false; g_win32_inited = false; win32_major = 0; win32_minor = 0; p_swap_interval = NULL; }
static int add_adapter(void *data, usb_device_entry *dev) { int rc; usb_devdesc desc; const char *device_name = NULL; struct wiiusb_adapter *old_head = NULL; struct wiiusb_hid *hid = (struct wiiusb_hid*)data; struct wiiusb_adapter *adapter = (struct wiiusb_adapter*) calloc(1, sizeof(struct wiiusb_adapter)); (void)rc; if (!adapter) return -1; if (!hid) { free(adapter); RARCH_ERR("Allocation of adapter failed.\n"); return -1; } if (USB_OpenDevice(dev->device_id, dev->vid, dev->pid, &adapter->handle) < 0) { RARCH_ERR("Error opening device 0x%p (VID/PID: %04x:%04x).\n", (void*)&adapter->device, dev->vid, dev->pid); free(adapter); return -1; } adapter->device = *dev; USB_GetDescriptors(adapter->handle, &desc); wiiusb_get_description(&adapter->device, adapter, &desc); if (adapter->endpoint_in == 0) { RARCH_ERR("Could not find HID config for device.\n"); goto error; } if (desc.iManufacturer) { USB_GetAsciiString(adapter->handle, desc.iManufacturer, 0, sizeof(adapter->manufacturer_name), adapter->manufacturer_name); #if 0 RARCH_ERR(" Adapter Manufacturer name: %s\n", adapter->manufacturer_name); #endif } if (desc.iProduct) { USB_GetAsciiString(adapter->handle, desc.iProduct, 0, sizeof(adapter->name), adapter->name); #if 0 RARCH_ERR(" Adapter name: %s\n", adapter->name); #endif } device_name = (const char *)adapter->name; adapter->send_control_lock = slock_new(); adapter->send_control_buffer = fifo_new(4096); if (!adapter->send_control_lock || !adapter->send_control_buffer) { RARCH_ERR("Error creating send control buffer.\n"); goto error; } adapter->slot = pad_connection_pad_init(hid->slots, device_name, desc.idVendor, desc.idProduct, adapter, &wiiusb_hid_device_send_control); if (adapter->slot == -1) goto error; if (!pad_connection_has_interface(hid->slots, adapter->slot)) { RARCH_ERR(" Interface not found (%s).\n", adapter->name); goto error; } RARCH_LOG("Interface found: [%s].\n", adapter->name); RARCH_LOG("Device 0x%p attached (VID/PID: %04x:%04x).\n", adapter->device, desc.idVendor, desc.idProduct); wiiusb_hid_device_add_autodetect(adapter->slot, device_name, wiiusb_hid.ident, desc.idVendor, desc.idProduct); adapter->hid = hid; adapter->thread = sthread_create(adapter_thread, adapter); if (!adapter->thread) { RARCH_ERR("Error initializing adapter thread.\n"); goto error; } adapter->data = memalign(32, 2048); old_head = adapters.next; adapters.next = adapter; adapter->next = old_head; USB_FreeDescriptors(&desc); USB_DeviceRemovalNotifyAsync(adapter->handle, wiiusb_hid_removalnotify_cb, (void *)hid); return 0; error: if (adapter->thread) sthread_join(adapter->thread); if (adapter->send_control_lock) slock_free(adapter->send_control_lock); if (adapter->send_control_buffer) fifo_free(adapter->send_control_buffer); if (adapter) free(adapter); USB_FreeDescriptors(&desc); USB_CloseDevice(&adapter->handle); return -1; }
CDIF_Queue::~CDIF_Queue() { slock_free(ze_mutex); scond_free(ze_cond); }
void MDFND_DestroyMutex(MDFN_Mutex *lock) { slock_free((slock_t*)lock); }
static int add_adapter(void *data, struct libusb_device *dev) { int rc; struct libusb_device_descriptor desc; const char *device_name = NULL; struct libusb_adapter *old_head = NULL; struct libusb_hid *hid = (struct libusb_hid*)data; struct libusb_adapter *adapter = (struct libusb_adapter*) calloc(1, sizeof(struct libusb_adapter)); if (!adapter) return -1; if (!hid) { free(adapter); RARCH_ERR("Allocation of adapter failed.\n"); return -1; } rc = libusb_get_device_descriptor(dev, &desc); if (rc != LIBUSB_SUCCESS) { RARCH_ERR("Error getting device descriptor.\n"); goto error; } adapter->device = dev; libusb_get_description(adapter->device, adapter); if (adapter->endpoint_in == 0) { RARCH_ERR("Could not find HID config for device.\n"); goto error; } rc = libusb_open (adapter->device, &adapter->handle); if (rc != LIBUSB_SUCCESS) { RARCH_ERR("Error opening device 0x%p (VID/PID: %04x:%04x).\n", (void*)adapter->device, desc.idVendor, desc.idProduct); goto error; } if (desc.iManufacturer) { libusb_get_string_descriptor_ascii(adapter->handle, desc.iManufacturer, adapter->manufacturer_name, sizeof(adapter->manufacturer_name)); #if 0 RARCH_ERR(" Adapter Manufacturer name: %s\n", adapter->manufacturer_name); #endif } if (desc.iProduct) { libusb_get_string_descriptor_ascii(adapter->handle, desc.iProduct, adapter->name, sizeof(adapter->name)); #if 0 RARCH_ERR(" Adapter name: %s\n", adapter->name); #endif } device_name = (const char*)adapter->name; if (string_is_empty((const char*)adapter->name)) goto error; adapter->send_control_lock = slock_new(); adapter->send_control_buffer = fifo_new(4096); if (!adapter->send_control_lock || !adapter->send_control_buffer) { RARCH_ERR("Error creating send control buffer.\n"); goto error; } adapter->slot = pad_connection_pad_init(hid->slots, device_name, desc.idVendor, desc.idProduct, adapter, &libusb_hid_device_send_control); if (adapter->slot == -1) goto error; if (!pad_connection_has_interface(hid->slots, adapter->slot)) { RARCH_ERR(" Interface not found (%s).\n", adapter->name); goto error; } RARCH_LOG("Interface found: [%s].\n", adapter->name); if (libusb_kernel_driver_active(adapter->handle, 0) == 1 && libusb_detach_kernel_driver(adapter->handle, 0)) { RARCH_ERR("Error detaching handle 0x%p from kernel.\n", adapter->handle); goto error; } rc = libusb_claim_interface(adapter->handle, adapter->interface_number); if (rc != LIBUSB_SUCCESS) { RARCH_ERR("Error claiming interface %d .\n", adapter->interface_number); goto error; } RARCH_LOG("Device 0x%p attached (VID/PID: %04x:%04x).\n", adapter->device, desc.idVendor, desc.idProduct); libusb_hid_device_add_autodetect(adapter->slot, device_name, libusb_hid.ident, desc.idVendor, desc.idProduct); adapter->hid = hid; adapter->thread = sthread_create(adapter_thread, adapter); if (!adapter->thread) { RARCH_ERR("Error initializing adapter thread.\n"); goto error; } old_head = adapters.next; adapters.next = adapter; adapter->next = old_head; return 0; error: if (adapter->thread) sthread_join(adapter->thread); if (adapter->send_control_lock) slock_free(adapter->send_control_lock); if (adapter->send_control_buffer) fifo_free(adapter->send_control_buffer); if (adapter) free(adapter); return -1; }
Task::Impl::~Impl() { shutdown(); slock_free(mutex); scond_free(condWork); }