bool recording_deinit(void) { driver_t *driver = driver_get_ptr(); if (!driver->recording_data || !driver->recording) return false; if (driver->recording->finalize) driver->recording->finalize(driver->recording_data); if (driver->recording->free) driver->recording->free(driver->recording_data); driver->recording_data = NULL; driver->recording = NULL; event_command(EVENT_CMD_GPU_RECORD_DEINIT); return true; }
static void gfx_ctx_glx_bind_hw_render(void *data, bool enable) { driver_t *driver = driver_get_ptr(); gfx_ctx_glx_data_t *glx = (gfx_ctx_glx_data_t*)driver->video_context_data; if (!glx) return; (void)data; glx->g_use_hw_ctx = enable; if (!glx->g_dpy) return; if (!glx->g_glx_win) return; glXMakeContextCurrent(glx->g_dpy, glx->g_glx_win, glx->g_glx_win, enable ? glx->g_hw_ctx : glx->g_ctx); }
static bool gl_glsl_set_mvp(void *data, const math_matrix_4x4 *mat) { int loc; driver_t *driver = driver_get_ptr(); glsl_shader_data_t *glsl = (glsl_shader_data_t*)driver->video_shader_data; (void)data; if (!glsl || !glsl->shader->modern) { gl_ff_matrix(mat); return false; } loc = glsl->gl_uniforms[glsl->glsl_active_index].mvp; if (loc >= 0) glUniformMatrix4fv(loc, 1, GL_FALSE, mat->data); return true; }
unsigned video_texture_load(void *data, enum texture_backend_type type, enum texture_filter_type filter_type) { settings_t *settings = config_get_ptr(); const struct retro_hw_render_callback *hw_render = (const struct retro_hw_render_callback*)video_driver_callback(); if (settings->video.threaded && !hw_render->context_type) { driver_t *driver = driver_get_ptr(); thread_video_t *thr = (thread_video_t*)driver->video_data; thread_packet_t pkt = { CMD_CUSTOM_COMMAND }; if (!thr) return 0; switch (type) { case TEXTURE_BACKEND_OPENGL: if (filter_type == TEXTURE_FILTER_MIPMAP_LINEAR || filter_type == TEXTURE_FILTER_MIPMAP_NEAREST) pkt.data.custom_command.method = video_texture_png_load_wrap_gl_mipmap; else pkt.data.custom_command.method = video_texture_png_load_wrap_gl; break; case TEXTURE_BACKEND_DEFAULT: default: pkt.data.custom_command.method = video_texture_png_load_wrap; break; } pkt.data.custom_command.data = (void*)data; thr->send_and_wait(thr, &pkt); return pkt.data.custom_command.return_value; } return video_texture_png_load(data, type, filter_type); }
unsigned video_texture_load(void *data, enum texture_backend_type type, enum texture_filter_type filter_type) { settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); if (settings->video.threaded && !global->system.hw_render_callback.context_type) { driver_t *driver = driver_get_ptr(); thread_video_t *thr = (thread_video_t*)driver->video_data; if (!thr) return 0; switch (type) { case TEXTURE_BACKEND_OPENGL: if (filter_type == TEXTURE_FILTER_MIPMAP_LINEAR || filter_type == TEXTURE_FILTER_MIPMAP_NEAREST) thr->cmd_data.custom_command.method = video_texture_png_load_wrap_gl_mipmap; else thr->cmd_data.custom_command.method = video_texture_png_load_wrap_gl; break; case TEXTURE_BACKEND_DEFAULT: default: thr->cmd_data.custom_command.method = video_texture_png_load_wrap; break; } thr->cmd_data.custom_command.data = (void*)data; thr->send_cmd_func(thr, CMD_CUSTOM_COMMAND); thr->wait_reply_func(thr, CMD_CUSTOM_COMMAND); return thr->cmd_data.custom_command.return_value; } return video_texture_png_load(data, type, filter_type); }
/** * menu_load_content: * * Loads content into currently selected core. * Will also optionally push the content entry to the history playlist. * * Returns: true (1) if successful, otherwise false (0). **/ bool menu_load_content(void) { menu_handle_t *menu = menu_driver_get_ptr(); driver_t *driver = driver_get_ptr(); global_t *global = global_get_ptr(); /* redraw menu frame */ if (menu) menu->msg_force = true; menu_entry_iterate(MENU_ACTION_NOOP); menu_display_fb(); if (!(main_load_content(0, NULL, NULL, menu_environment_get, driver->frontend_ctx->process_args))) { char name[PATH_MAX_LENGTH], msg[PATH_MAX_LENGTH]; fill_pathname_base(name, global->fullpath, sizeof(name)); snprintf(msg, sizeof(msg), "Failed to load %s.\n", name); rarch_main_msg_queue_push(msg, 1, 90, false); if (menu) menu->msg_force = true; return false; } menu_shader_manager_init(menu); event_command(EVENT_CMD_HISTORY_INIT); if (*global->fullpath || (menu && menu->load_no_content)) push_to_history_playlist(); event_command(EVENT_CMD_VIDEO_SET_ASPECT_RATIO); event_command(EVENT_CMD_RESUME); return true; }
bool menu_display_init_main_font(menu_handle_t *menu, const char *font_path, float font_size) { driver_t *driver = driver_get_ptr(); void *video = video_driver_get_ptr(NULL); bool result; if (menu->font.buf) menu_display_free_main_font(menu); result = menu_display_font_init_first( (const void**)&driver->font_osd_driver, &menu->font.buf, video, font_path, font_size); if (result) menu->font.size = font_size; else menu->font.buf = NULL; return result; }
/** * driver_update_system_av_info: * @info : pointer to new A/V info * * Update the system Audio/Video information. * Will reinitialize audio/video drivers. * Used by RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO. * * Returns: true (1) if successful, otherwise false (0). **/ bool driver_update_system_av_info(const struct retro_system_av_info *info) { global_t *global = global_get_ptr(); driver_t *driver = driver_get_ptr(); global->system.av_info = *info; event_command(EVENT_CMD_REINIT); /* Cannot continue recording with different parameters. * Take the easiest route out and just restart the recording. */ if (driver->recording_data) { static const char *msg = "Restarting recording due to driver reinit."; rarch_main_msg_queue_push(msg, 2, 180, false); RARCH_WARN("%s\n", msg); event_command(EVENT_CMD_RECORD_DEINIT); event_command(EVENT_CMD_RECORD_INIT); } return true; }
static void menu_list_destroy(file_list_t *list) { unsigned i; driver_t *driver = driver_get_ptr(); if (!list) return; if (!driver->menu_ctx) goto end; for (i = 0; i < list->size; i++) { menu_driver_list_delete(list, i, list->size); menu_common_list_delete(list, i, list->size); } end: if (list) file_list_free(list); }
bool win32_window_create(void *data, unsigned style, RECT *mon_rect, unsigned width, unsigned height, bool fullscreen) { #ifndef _XBOX driver_t *driver = driver_get_ptr(); g_hwnd = CreateWindowEx(0, "RetroArch", "RetroArch", style, fullscreen ? mon_rect->left : g_pos_x, fullscreen ? mon_rect->top : g_pos_y, width, height, NULL, NULL, NULL, data); if (!g_hwnd) return false; driver->display_type = RARCH_DISPLAY_WIN32; driver->video_display = 0; driver->video_window = (uintptr_t)g_hwnd; #endif return true; }
/* Time to exit out of the main loop? * Reasons for exiting: * a) Shutdown environment callback was invoked. * b) Quit key was pressed. * c) Frame count exceeds or equals maximum amount of frames to run. * d) Video driver no longer alive. * e) End of BSV movie and BSV EOF exit is true. (TODO/FIXME - explain better) */ static INLINE int rarch_main_iterate_time_to_exit(event_cmd_state_t *cmd) { settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); driver_t *driver = driver_get_ptr(); rarch_system_info_t *system = rarch_system_info_get_ptr(); video_driver_t *video = driver ? (video_driver_t*)driver->video : NULL; bool shutdown_pressed = (system && system->shutdown) || cmd->quit_key_pressed; bool video_alive = video && video->alive(driver->video_data); bool movie_end = (global->bsv.movie_end && global->bsv.eof_exit); uint64_t *frame_count = video_driver_get_frame_count(); bool frame_count_end = main_max_frames && (*frame_count >= main_max_frames); if (shutdown_pressed || frame_count_end || movie_end || !video_alive || global->exec) { if (global->exec) global->exec = false; /* Quits out of RetroArch main loop. * On special case, loads dummy core * instead of exiting RetroArch completely. * Aborts core shutdown if invoked. */ if (global->core_shutdown_initiated && settings->load_dummy_on_core_shutdown) { if (!event_command(EVENT_CMD_PREPARE_DUMMY)) return -1; system->shutdown = false; global->core_shutdown_initiated = false; return 0; } return -1; } return 1; }
/** * retro_init_libretro_cbs: * @data : pointer to retro_callbacks object * * Initializes libretro callbacks, and binds the libretro callbacks * to default callback functions. **/ void retro_init_libretro_cbs(void *data) { struct retro_callbacks *cbs = (struct retro_callbacks*)data; driver_t *driver = driver_get_ptr(); global_t *global = global_get_ptr(); if (!cbs) return; (void)driver; (void)global; pretro_set_video_refresh(video_frame); pretro_set_audio_sample(audio_driver_sample); pretro_set_audio_sample_batch(audio_driver_sample_batch); pretro_set_input_state(input_state); pretro_set_input_poll(input_poll); retro_set_default_callbacks(cbs); #ifdef HAVE_NETPLAY if (!driver->netplay_data) return; if (global->netplay_is_spectate) { pretro_set_input_state( (global->netplay_is_client ? input_state_spectate_client : input_state_spectate) ); } else { pretro_set_video_refresh(video_frame_net); pretro_set_audio_sample(audio_sample_net); pretro_set_audio_sample_batch(audio_sample_batch_net); pretro_set_input_state(input_state_net); } #endif }
static int menu_input_pointer(unsigned *action) { int pointer_device, pointer_x, pointer_y; const struct retro_keybind *binds[MAX_USERS]; menu_handle_t *menu = menu_driver_get_ptr(); settings_t *settings = config_get_ptr(); driver_t *driver = driver_get_ptr(); if (!menu) return -1; if (!settings->menu.pointer.enable) { memset(&menu->pointer, 0, sizeof(menu->pointer)); return 0; } pointer_device = driver->menu_ctx->set_texture? RETRO_DEVICE_POINTER : RARCH_DEVICE_POINTER_SCREEN; menu->pointer.pressed[0] = input_driver_state(binds, 0, pointer_device, 0, RETRO_DEVICE_ID_POINTER_PRESSED); menu->pointer.pressed[1] = input_driver_state(binds, 0, pointer_device, 1, RETRO_DEVICE_ID_POINTER_PRESSED); menu->pointer.back = input_driver_state(binds, 0, pointer_device, 0, RARCH_DEVICE_ID_POINTER_BACK); pointer_x = input_driver_state(binds, 0, pointer_device, 0, RETRO_DEVICE_ID_POINTER_X); pointer_y = input_driver_state(binds, 0, pointer_device, 0, RETRO_DEVICE_ID_POINTER_Y); menu->pointer.x = ((pointer_x + 0x7fff) * (int)menu->frame_buf.width) / 0xFFFF; menu->pointer.y = ((pointer_y + 0x7fff) * (int)menu->frame_buf.height) / 0xFFFF; if (menu->pointer.pressed[0] || menu->pointer.oldpressed[0] || menu->pointer.back || menu->pointer.dragging || menu->pointer.dy != 0 || menu->pointer.dx != 0) menu->animation_is_active = true; return 0; }
static void gfx_ctx_drm_egl_bind_hw_render(void *data, bool enable) { driver_t *driver = driver_get_ptr(); gfx_ctx_drm_egl_data_t *drm = (gfx_ctx_drm_egl_data_t*) driver->video_context_data; if (!drm) return; (void)data; drm->g_use_hw_ctx = enable; if (!drm->g_egl_dpy) return; if (!drm->g_egl_surf) return; eglMakeCurrent(drm->g_egl_dpy, drm->g_egl_surf, drm->g_egl_surf, enable ? drm->g_egl_hw_ctx : drm->g_egl_ctx); }
void init_location(void) { driver_t *driver = driver_get_ptr(); rarch_system_info_t *system = rarch_system_info_get_ptr(); /* Resource leaks will follow if location interface is initialized twice. */ if (driver->location_data) return; find_location_driver(); driver->location_data = driver->location->init(); if (!driver->location_data) { RARCH_ERR("Failed to initialize location driver. Will continue without location.\n"); driver->location_active = false; } if (system->location_callback.initialized) system->location_callback.initialized(); }
static void zarch_free(void *data) { menu_handle_t *menu = (menu_handle_t*)data; driver_t *driver = driver_get_ptr(); zui_t *zui = (zui_t*)menu->userdata; const struct font_renderer *font_driver = (const struct font_renderer*)driver->font_osd_driver; if (!zui || !menu) return; gfx_coord_array_free(&zui->ca); gfx_coord_array_free(&zui->tmp_block.carr); if (menu->userdata) free(menu->userdata); menu->userdata = NULL; if (font_driver->bind_block) font_driver->bind_block(driver->font_osd_data, NULL); }
/** * get_self_input_state: * @netplay : pointer to netplay object * * Grab our own input state and send this over the network. * * Returns: true (1) if successful, otherwise false (0). **/ static bool get_self_input_state(netplay_t *netplay) { uint32_t state = 0; struct delta_frame *ptr = &netplay->buffer[netplay->self_ptr]; driver_t *driver = driver_get_ptr(); settings_t *settings = config_get_ptr(); if (!driver->block_libretro_input && netplay->frame_count > 0) { unsigned i; /* First frame we always give zero input since relying on * input from first frame screws up when we use -F 0. */ retro_input_state_t cb = netplay->cbs.state_cb; for (i = 0; i < RARCH_FIRST_META_KEY; i++) { int16_t tmp = cb(settings->input.netplay_client_swap_input ? 0 : !netplay->port, RETRO_DEVICE_JOYPAD, 0, i); state |= tmp ? 1 << i : 0; } } memmove(netplay->packet_buffer, netplay->packet_buffer + 2, sizeof (netplay->packet_buffer) - 2 * sizeof(uint32_t)); netplay->packet_buffer[(UDP_FRAME_PACKETS - 1) * 2] = htonl(netplay->frame_count); netplay->packet_buffer[(UDP_FRAME_PACKETS - 1) * 2 + 1] = htonl(state); if (!send_chunk(netplay)) { warn_hangup(); netplay->has_connection = false; return false; } ptr->self_state = state; netplay->self_ptr = NEXT_PTR(netplay->self_ptr); return true; }
static void menu_action_setting_disp_set_label_shader_parameter( file_list_t* list, unsigned *w, unsigned type, unsigned i, const char *label, char *s, size_t len, const char *entry_label, const char *path, char *s2, size_t len2) { #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_HLSL) const struct video_shader_parameter *param = NULL; struct video_shader *shader = NULL; #endif driver_t *driver = driver_get_ptr(); if (!driver->video_poke) return; if (!driver->video_data) return; *s = '\0'; *w = 19; strlcpy(s2, path, len2); #if defined(HAVE_CG) || defined(HAVE_GLSL) || defined(HAVE_HLSL) shader = video_shader_driver_get_current_shader(); if (!shader) return; param = &shader->parameters[type - MENU_SETTINGS_SHADER_PARAMETER_0]; if (!param) return; snprintf(s, len, "%.2f [%.2f %.2f]", param->current, param->minimum, param->maximum); #endif }
static void apple_hid_device_remove(void *data, IOReturn result, void* sender) { driver_t *driver = driver_get_ptr(); apple_input_data_t *apple = (apple_input_data_t*)driver->input_data; struct apple_hid_adapter *adapter = (struct apple_hid_adapter*)data; apple_hid_t *hid = driver ? (apple_hid_t*)driver->hid_data : NULL; if (adapter && (adapter->slot < MAX_USERS)) { char msg[PATH_MAX_LENGTH]; snprintf(msg, sizeof(msg), "Joypad #%u (%s) disconnected.", adapter->slot, adapter->name); rarch_main_msg_queue_push(msg, 0, 60, false); apple->buttons[adapter->slot] = 0; memset(apple->axes[adapter->slot], 0, sizeof(apple->axes)); pad_connection_pad_deinit(&hid->slots[adapter->slot], adapter->slot); free(adapter); } }
/** ** menu_display_fb: * * Draws menu graphics onscreen. **/ void menu_display_fb(void) { driver_t *driver = driver_get_ptr(); global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); video_driver_set_texture_enable(true, false); if (!settings->menu.pause_libretro) { if (global->main_is_init && !global->libretro_dummy) { bool block_libretro_input = driver->block_libretro_input; driver->block_libretro_input = true; pretro_run(); driver->block_libretro_input = block_libretro_input; return; } } rarch_render_cached_frame(); }
static void xui_render_message(const char *msg) { struct font_params font_parms = {0}; size_t i = 0; size_t j = 0; struct string_list *list = NULL; driver_t *driver = driver_get_ptr(); d3d_video_t *d3d = (d3d_video_t*)driver->video_data; if (!d3d) return; list = string_split(msg, "\n"); if (!list) return; if (list->elems == 0) goto end; for (i = 0; i < list->size; i++, j++) { char *msg = (char*)list->elems[i].data; unsigned msglen = strlen(msg); float msg_width = d3d->resolution_hd_enable ? 160 : 100; float msg_height = 120; float msg_offset = 32; font_parms.x = msg_width; font_parms.y = msg_height + (msg_offset * j); font_parms.scale = 21; video_driver_set_osd_msg(msg, &font_parms, NULL); } end: string_list_free(list); }
static void sdl_ctx_get_video_size(void *data, unsigned *width, unsigned *height) { driver_t *driver = driver_get_ptr(); settings_t *settings = config_get_ptr(); gfx_ctx_sdl_data_t *sdl = (gfx_ctx_sdl_data_t*)driver->video_context_data; if (!sdl) return; *width = sdl->g_width; *height = sdl->g_height; if (!sdl->g_win) { int i = settings->video.monitor_index; #ifdef HAVE_SDL2 SDL_DisplayMode mode = {0}; if (SDL_GetCurrentDisplayMode(i, &mode) < 0) RARCH_WARN("[SDL_GL]: Failed to get display #%i mode: %s\n", i, SDL_GetError()); #else SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE); SDL_Rect mode = {0}; if (!modes) RARCH_WARN("[SDL_GL]: Failed to detect available video modes: %s\n", SDL_GetError()); else if (*modes) mode = **modes; #endif *width = mode.w; *height = mode.h; } }
static void sdl2_gfx_set_handles(sdl2_video_t *vid) { driver_t *driver = driver_get_ptr(); /* SysWMinfo headers are broken on OSX. */ #if defined(_WIN32) || defined(HAVE_X11) SDL_SysWMinfo info; SDL_VERSION(&info.version); if (SDL_GetWindowWMInfo(vid->window, &info) != 1) return; #if defined(_WIN32) driver->display_type = RARCH_DISPLAY_WIN32; driver->video_display = 0; driver->video_window = (uintptr_t)info.info.win.window; #elif defined(HAVE_X11) driver->display_type = RARCH_DISPLAY_X11; driver->video_display = (uintptr_t)info.info.x11.display; driver->video_window = (uintptr_t)info.info.x11.window; #endif #endif }
void menu_list_pop(file_list_t *list, size_t *directory_ptr) { driver_t *driver = driver_get_ptr(); if (!driver->menu_ctx) goto end; if (list->size != 0) { size_t list_size = list->size - 1; menu_driver_list_delete(list, list_size, list_size); menu_common_list_delete(list, list_size, list_size); } end: file_list_pop(list, directory_ptr); if (!driver->menu_ctx) return; menu_driver_list_set_selection(list); menu_common_list_set_selection(list); }
static void sdl_ctx_update_window_title(void *data) { char buf[128] = {0}; char buf_fps[128] = {0}; driver_t *driver = driver_get_ptr(); settings_t *settings = config_get_ptr(); gfx_ctx_sdl_data_t *sdl = (gfx_ctx_sdl_data_t*)driver->video_context_data; if (!sdl) return; if (video_monitor_get_fps(buf, sizeof(buf), buf_fps, sizeof(buf_fps))) { #ifdef HAVE_SDL2 SDL_SetWindowTitle(sdl->g_win, buf); #else SDL_WM_SetCaption(buf, NULL); #endif } if (settings->fps_show) rarch_main_msg_queue_push(buf_fps, 1, 1, false); }
static int menu_input_key_bind_iterate_keyboard(int64_t current, int timeout, bool timed_out) { menu_input_t *menu_input = menu_input_get_ptr(); driver_t *driver = driver_get_ptr(); if (!menu_input) return -1; /* binds.begin is updated in keyboard_press callback. */ if (menu_input->binds.begin > menu_input->binds.last) { /* Avoid new binds triggering things right away. */ driver->flushing_input = true; /* We won't be getting any key events, so just cancel early. */ if (timed_out) input_keyboard_wait_keys_cancel(); return 1; } return 0; }
static void android_gfx_ctx_bind_hw_render(void *data, bool enable) { driver_t *driver = driver_get_ptr(); gfx_ctx_android_data_t *android = NULL; android = (gfx_ctx_android_data_t*)driver->video_context_data; (void)data; if (!android) return; android->g_use_hw_ctx = enable; if (!android->g_egl_dpy) return; if (!android->g_egl_surf) return; eglMakeCurrent(android->g_egl_dpy, android->g_egl_surf, android->g_egl_surf, enable ? android->g_egl_hw_ctx : android->g_egl_ctx); }
static void queue_flip(void) { int ret; struct drm_fb *fb = NULL; driver_t *driver = driver_get_ptr(); gfx_ctx_drm_egl_data_t *drm = (gfx_ctx_drm_egl_data_t*) driver->video_context_data; drm->g_next_bo = gbm_surface_lock_front_buffer(drm->g_gbm_surface); fb = (struct drm_fb*)drm_fb_get_from_bo(drm, drm->g_next_bo); ret = drmModePageFlip(drm->g_drm_fd, drm->g_crtc_id, fb->fb_id, DRM_MODE_PAGE_FLIP_EVENT, &waiting_for_flip); if (ret < 0) { RARCH_ERR("[KMS/EGL]: Failed to queue page flip.\n"); return; } waiting_for_flip = true; }
int32_t cocoa_input_find_any_button(uint32_t port) { unsigned i, buttons = 0; driver_t *driver = driver_get_ptr(); cocoa_input_data_t *apple = (cocoa_input_data_t*)driver->input_data; if (!apple) return -1; if (apple->joypad) apple->joypad->poll(); buttons = apple->buttons[port]; if (port == 0 && apple->icade_enabled) BIT32_SET(buttons, apple->icade_buttons); if (buttons) for (i = 0; i < 32; i++) if (buttons & (1 << i)) return i; return -1; }
/** * driver_set_nonblock_state: * @enable : Enable nonblock state? * * Sets audio and video drivers to nonblock state. * * If @enable is false, sets blocking state for both * audio and video drivers instead. **/ void driver_set_nonblock_state(bool enable) { settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); driver_t *driver = driver_get_ptr(); /* Only apply non-block-state for video if we're using vsync. */ if (driver->video_active && driver->video_data) { bool video_nonblock = enable; if (!settings->video.vsync || global->system.force_nonblock) video_nonblock = true; video_driver_set_nonblock_state(video_nonblock); } if (driver->audio_active && driver->audio_data) audio_driver_set_nonblock_state(settings->audio.sync ? enable : true); global->audio_data.chunk_size = enable ? global->audio_data.nonblock_chunk_size : global->audio_data.block_chunk_size; }