static void zarch_context_reset(void *data) { const char *font_path = NULL; settings_t *settings = config_get_ptr(); zui_t *zui = (zui_t*)data; if (!zui || !settings) return; font_path = settings->video.font_enable ? settings->video.font_path : NULL; if (!menu_display_init_main_font(font_path, zui->font_size)) RARCH_WARN("Failed to load font."); zarch_context_bg_destroy(zui); rarch_task_push_image_load(settings->menu.wallpaper, "cb_menu_wallpaper", menu_display_handle_wallpaper_upload, NULL); zarch_allocate_white_texture(zui); menu_display_ctl(MENU_DISPLAY_CTL_SET_FONT_SIZE, &zui->font_size); zarch_zui_font(); }
static void rmenu_render(void) { bool msg_force; size_t begin, end, i, j, selection; struct font_params font_parms = {0}; char title[256] = {0}; char title_buf[256] = {0}; char title_msg[64] = {0}; menu_handle_t *menu = menu_driver_get_ptr(); file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(); uint64_t *frame_count = video_driver_get_frame_count(); size_t entries_end = menu_entries_get_end(); if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return; if (!menu) return; if (!render_normal) { render_normal = true; return; } menu_display_ctl(MENU_DISPLAY_CTL_MSG_FORCE, &msg_force); if (menu_entries_needs_refresh() && menu_driver_alive() && !msg_force) return; menu_display_fb_unset_dirty(); menu_animation_clear_active(); if (!selection_buf) return; begin = (selection >= (ENTRIES_HEIGHT / 2)) ? (selection - (ENTRIES_HEIGHT / 2)) : 0; end = ((selection + ENTRIES_HEIGHT) <= entries_end) ? selection + ENTRIES_HEIGHT : entries_end; if (entries_end <= ENTRIES_HEIGHT) begin = 0; if (end - begin > ENTRIES_HEIGHT) end = begin + ENTRIES_HEIGHT; menu_entries_get_title(title, sizeof(title)); menu_animation_ticker_str(title_buf, RMENU_TERM_WIDTH, *frame_count / 15, title, true); font_parms.x = POSITION_EDGE_MIN + POSITION_OFFSET; font_parms.y = POSITION_EDGE_MIN + POSITION_RENDER_OFFSET - (POSITION_OFFSET*2); font_parms.scale = FONT_SIZE_NORMAL; font_parms.color = WHITE; video_driver_set_osd_msg(title_buf, &font_parms, NULL); font_parms.x = POSITION_EDGE_MIN + POSITION_OFFSET; font_parms.y = POSITION_EDGE_MAX - (POSITION_OFFSET*2); font_parms.scale = FONT_SIZE_NORMAL; font_parms.color = WHITE; menu_entries_get_core_title(title_msg, sizeof(title_msg)); video_driver_set_osd_msg(title_msg, &font_parms, NULL); j = 0; for (i = begin; i < end; i++, j++) { char entry_path[PATH_MAX_LENGTH] = {0}; char entry_value[PATH_MAX_LENGTH] = {0}; char message[PATH_MAX_LENGTH] = {0}; char entry_title_buf[PATH_MAX_LENGTH] = {0}; char type_str_buf[PATH_MAX_LENGTH] = {0}; unsigned entry_spacing = menu_entry_get_spacing(i); bool entry_selected = menu_entry_is_currently_selected(i); menu_entry_get_value(i, entry_value, sizeof(entry_value)); menu_entry_get_path(i, entry_path, sizeof(entry_path)); menu_animation_ticker_str(entry_title_buf, RMENU_TERM_WIDTH - (entry_spacing + 1 + 2), *frame_count / 15, entry_path, entry_selected); menu_animation_ticker_str(type_str_buf, entry_spacing, *frame_count / 15, entry_value, entry_selected); snprintf(message, sizeof(message), "%c %s", entry_selected ? '>' : ' ', entry_title_buf); font_parms.x = POSITION_EDGE_MIN + POSITION_OFFSET; font_parms.y = POSITION_EDGE_MIN + POSITION_RENDER_OFFSET + (POSITION_OFFSET * j); font_parms.scale = FONT_SIZE_NORMAL; font_parms.color = WHITE; video_driver_set_osd_msg(message, &font_parms, NULL); font_parms.x = POSITION_EDGE_CENTER + POSITION_OFFSET; video_driver_set_osd_msg(type_str_buf, &font_parms, NULL); } }
static void zarch_frame(void *data) { unsigned i; float coord_color[16]; float coord_color2[16]; menu_display_ctx_draw_t draw; menu_display_ctx_coord_draw_t coord_draw; settings_t *settings = config_get_ptr(); zui_t *zui = (zui_t*)data; if (!zui) return; video_driver_get_size(&zui->width, &zui->height); menu_display_ctl(MENU_DISPLAY_CTL_SET_VIEWPORT, NULL); menu_display_ctl(MENU_DISPLAY_CTL_FONT_BUF, &zui->fb_buf); for (i = 0; i < 16; i++) { coord_color[i] = 0; coord_color2[i] = 2.0f; if (i == 3 || i == 7 || i == 11 || i == 15) { coord_color[i] = 0.10f; coord_color2[i] = 0.10f; } } zui->rendering = true; zui->hash = 0; zui->item.hot = 0; /* why do i need this? */ zui->mouse.wheel = menu_input_mouse_state(MENU_MOUSE_WHEEL_DOWN) - menu_input_mouse_state(MENU_MOUSE_WHEEL_UP); zui->ca.coords.vertices = 0; zui->tmp_block.carr.coords.vertices = 0; menu_display_ctl(MENU_DISPLAY_CTL_FONT_BIND_BLOCK, &zui->tmp_block); zarch_zui_push_quad(zui->width, zui->height, zui_bg_screen, &zui->ca, 0, 0, zui->width, zui->height); zarch_zui_snow(zui, &zui->ca, zui->width, zui->height); switch (zarch_layout) { case LAY_HOME: if (zarch_zui_render_sidebar(zui)) return; if (zarch_zui_render_lay_root(zui)) return; break; case LAY_SETTINGS: zarch_zui_render_lay_settings(zui); break; case LAY_PICK_CORE: if (zarch_zui_render_sidebar(zui)) return; if (zarch_zui_render_pick_core(zui)) return; break; } if (settings->menu.mouse.enable) zarch_zui_draw_cursor( zarch_zui_input_state(zui, MENU_ZARCH_MOUSE_X), zarch_zui_input_state(zui, MENU_ZARCH_MOUSE_Y)); if (!zarch_zui_input_state(zui, MENU_ZARCH_PRESSED)) zui->item.active = 0; else if (zui->item.active == 0) zui->item.active = -1; menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL); draw.x = 0; draw.y = 0; draw.width = zui->width; draw.height = zui->height; draw.coords = (struct gfx_coords*)&zui->ca; draw.matrix_data = &zui->mvp; draw.texture = zui->textures.white; draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLES; menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw); menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL); memset(&draw, 0, sizeof(menu_display_ctx_draw_t)); coord_draw.ptr = NULL; menu_display_ctl(MENU_DISPLAY_CTL_TEX_COORDS_GET, &coord_draw); draw.width = zui->width; draw.height = zui->height; draw.texture = zui->textures.bg; draw.handle_alpha = 0.75f; draw.force_transparency = false; draw.color = &coord_color[0]; draw.color2 = &coord_color2[0]; draw.vertex = NULL; draw.tex_coord = coord_draw.ptr; draw.vertex_count = 4; draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP; menu_display_ctl(MENU_DISPLAY_CTL_DRAW_BG, &draw); zui->rendering = false; menu_display_ctl(MENU_DISPLAY_CTL_FONT_FLUSH_BLOCK, NULL); menu_display_ctl(MENU_DISPLAY_CTL_UNSET_VIEWPORT, NULL); }
static void zarch_context_destroy(void *data) { menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_DEINIT, NULL); zarch_context_bg_destroy(data); }
static void zarch_frame(void) { unsigned i; float coord_color[16]; float coord_color2[16]; zui_t *zui = NULL; const struct font_renderer *font_driver = NULL; driver_t *driver = driver_get_ptr(); settings_t *settings = config_get_ptr(); menu_handle_t *menu = menu_driver_get_ptr(); if (!menu) return; (void)driver; zui = (zui_t*)menu->userdata; zui->menu = menu; video_driver_get_size(&zui->width, &zui->height); menu_display_ctl(MENU_DISPLAY_CTL_SET_VIEWPORT, NULL); menu_display_ctl(MENU_DISPLAY_CTL_FONT_BUF, &zui->fb_buf); for (i = 0; i < 16; i++) { coord_color[i] = 0; coord_color2[i] = 2.0f; if (i == 3 || i == 7 || i == 11 || i == 15) { coord_color[i] = 0.10f; coord_color2[i] = 0.10f; } } zui->rendering = true; zui->hash = 0; zui->item.hot = 0; /* why do i need this? */ zui->mouse.wheel = menu_input_mouse_state(MENU_MOUSE_WHEEL_DOWN) - menu_input_mouse_state(MENU_MOUSE_WHEEL_UP); zui->ca.coords.vertices = 0; zui->tmp_block.carr.coords.vertices = 0; font_driver = driver->font_osd_driver; menu_display_font_bind_block(zui->menu, font_driver, &zui->tmp_block); zarch_zui_push_quad(zui->width, zui->height, ZUI_BG_SCREEN, &zui->ca, 0, 0, zui->width, zui->height); zarch_zui_snow(zui, &zui->ca, zui->width, zui->height); switch (layout) { case LAY_HOME: if (zarch_zui_render_sidebar(zui)) return; if (zarch_zui_render_lay_root(zui)) return; break; case LAY_SETTINGS: zarch_zui_render_lay_settings(zui); break; case LAY_PICK_CORE: if (zarch_zui_render_sidebar(zui)) return; if (zarch_zui_render_pick_core(zui)) return; break; } if (settings->menu.mouse.enable) zarch_zui_draw_cursor(zarch_zui_input_state(zui, MENU_ZARCH_MOUSE_X), zarch_zui_input_state(zui, MENU_ZARCH_MOUSE_Y)); if (!zarch_zui_input_state(zui, MENU_ZARCH_PRESSED)) zui->item.active = 0; else if (zui->item.active == 0) zui->item.active = -1; menu_display_blend_begin(); menu_display_draw( 0, 0, zui->width, zui->height, (struct gfx_coords*)&zui->ca, &zui->mvp, zui->textures.white, MENU_DISPLAY_PRIM_TRIANGLES); menu_display_blend_end(); menu_display_draw_bg( zui->width, zui->height, zui->textures.bg.id, 0.75f, false, &coord_color[0], &coord_color2[0], NULL, menu_display_get_tex_coords(), 4, MENU_DISPLAY_PRIM_TRIANGLESTRIP); menu_display_font_flush_block(zui->menu, driver->font_osd_driver); zui->rendering = false; menu_display_ctl(MENU_DISPLAY_CTL_UNSET_VIEWPORT, NULL); }
static void mui_render(void *data) { size_t i = 0; float delta_time, dt; unsigned bottom, width, height, header_height; mui_handle_t *mui = (mui_handle_t*)data; settings_t *settings = config_get_ptr(); if (!mui) return; video_driver_get_size(&width, &height); menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time); dt = delta_time / IDEAL_DT; menu_animation_ctl(MENU_ANIMATION_CTL_UPDATE, &dt); menu_display_ctl(MENU_DISPLAY_CTL_SET_WIDTH, &width); menu_display_ctl(MENU_DISPLAY_CTL_SET_HEIGHT, &height); menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); if (settings->menu.pointer.enable) { int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS); float old_accel_val, new_accel_val; unsigned new_pointer_val = (pointer_y - mui->line_height + mui->scroll_y - 16) / mui->line_height; menu_input_ctl(MENU_INPUT_CTL_POINTER_ACCEL_READ, &old_accel_val); menu_input_ctl(MENU_INPUT_CTL_POINTER_PTR, &new_pointer_val); mui->scroll_y -= old_accel_val / 60.0; new_accel_val = old_accel_val * 0.96; menu_input_ctl(MENU_INPUT_CTL_POINTER_ACCEL_WRITE, &new_accel_val); } if (settings->menu.mouse.enable) { int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS); unsigned new_pointer_val = (mouse_y - mui->line_height + mui->scroll_y - 16) / mui->line_height; menu_input_ctl(MENU_INPUT_CTL_MOUSE_PTR, &new_pointer_val); } if (mui->scroll_y < 0) mui->scroll_y = 0; bottom = menu_entries_get_end() * mui->line_height - height + header_height + mui->tabs_height; if (mui->scroll_y > bottom) mui->scroll_y = bottom; if (menu_entries_get_end() * mui->line_height < height - header_height - mui->tabs_height) mui->scroll_y = 0; if (menu_entries_get_end() < height / mui->line_height) { } else i = mui->scroll_y / mui->line_height; menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &i); }
bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data) { static struct retro_system_info menu_driver_system; static bool menu_driver_pending_quick_menu = false; static bool menu_driver_pending_action = false; static bool menu_driver_prevent_populate = false; static bool menu_driver_load_no_content = false; static bool menu_driver_alive = false; static bool menu_driver_data_own = false; static bool menu_driver_pending_quit = false; static bool menu_driver_pending_shutdown = false; static content_playlist_t *menu_driver_playlist = NULL; static struct video_shader *menu_driver_shader = NULL; static menu_handle_t *menu_driver_data = NULL; static const menu_ctx_driver_t *menu_driver_ctx = NULL; static void *menu_userdata = NULL; settings_t *settings = config_get_ptr(); switch (state) { case RARCH_MENU_CTL_IS_PENDING_ACTION: if (!menu_driver_pending_action) return false; menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_ACTION, NULL); break; case RARCH_MENU_CTL_SET_PENDING_ACTION: menu_driver_pending_action = true; break; case RARCH_MENU_CTL_UNSET_PENDING_ACTION: menu_driver_pending_action = false; break; case RARCH_MENU_CTL_DRIVER_DATA_GET: { menu_handle_t **driver_data = (menu_handle_t**)data; if (!driver_data) return false; *driver_data = menu_driver_data; } break; case RARCH_MENU_CTL_IS_PENDING_QUICK_MENU: return menu_driver_pending_quick_menu; case RARCH_MENU_CTL_SET_PENDING_QUICK_MENU: menu_driver_pending_quick_menu = true; break; case RARCH_MENU_CTL_UNSET_PENDING_QUICK_MENU: menu_driver_pending_quick_menu = false; break; case RARCH_MENU_CTL_IS_PENDING_QUIT: return menu_driver_pending_quit; case RARCH_MENU_CTL_SET_PENDING_QUIT: menu_driver_pending_quit = true; break; case RARCH_MENU_CTL_UNSET_PENDING_QUIT: menu_driver_pending_quit = false; break; case RARCH_MENU_CTL_IS_PENDING_SHUTDOWN: return menu_driver_pending_shutdown; case RARCH_MENU_CTL_SET_PENDING_SHUTDOWN: menu_driver_pending_shutdown = true; break; case RARCH_MENU_CTL_UNSET_PENDING_SHUTDOWN: menu_driver_pending_shutdown = false; break; case RARCH_MENU_CTL_DESTROY: menu_driver_pending_quick_menu = false; menu_driver_pending_action = false; menu_driver_pending_quit = false; menu_driver_pending_shutdown = false; menu_driver_prevent_populate = false; menu_driver_load_no_content = false; menu_driver_alive = false; menu_driver_data_own = false; menu_driver_ctx = NULL; menu_userdata = NULL; break; case RARCH_MENU_CTL_PLAYLIST_FREE: if (menu_driver_playlist) content_playlist_free(menu_driver_playlist); menu_driver_playlist = NULL; break; case RARCH_MENU_CTL_FIND_DRIVER: { int i; driver_ctx_info_t drv; settings_t *settings = config_get_ptr(); drv.label = "menu_driver"; drv.s = settings->menu.driver; driver_ctl(RARCH_DRIVER_CTL_FIND_INDEX, &drv); i = drv.len; if (i >= 0) menu_driver_ctx = (const menu_ctx_driver_t*) menu_driver_find_handle(i); else { unsigned d; RARCH_WARN("Couldn't find any menu driver named \"%s\"\n", settings->menu.driver); RARCH_LOG_OUTPUT("Available menu drivers are:\n"); for (d = 0; menu_driver_find_handle(d); d++) RARCH_LOG_OUTPUT("\t%s\n", menu_driver_find_ident(d)); RARCH_WARN("Going to default to first menu driver...\n"); menu_driver_ctx = (const menu_ctx_driver_t*) menu_driver_find_handle(0); if (!menu_driver_ctx) { retro_fail(1, "find_menu_driver()"); return false; } } } break; case RARCH_MENU_CTL_PLAYLIST_INIT: { const char *path = (const char*)data; if (string_is_empty(path)) return false; menu_driver_playlist = content_playlist_init(path, COLLECTION_SIZE); } break; case RARCH_MENU_CTL_PLAYLIST_GET: { content_playlist_t **playlist = (content_playlist_t**)data; if (!playlist) return false; *playlist = menu_driver_playlist; } break; case RARCH_MENU_CTL_SYSTEM_INFO_GET: { struct retro_system_info **system = (struct retro_system_info**)data; if (!system) return false; *system = &menu_driver_system; } break; case RARCH_MENU_CTL_SYSTEM_INFO_DEINIT: #ifdef HAVE_DYNAMIC libretro_free_system_info(&menu_driver_system); memset(&menu_driver_system, 0, sizeof(struct retro_system_info)); #endif break; case RARCH_MENU_CTL_RENDER_MESSAGEBOX: if (menu_driver_ctx->render_messagebox) menu_driver_ctx->render_messagebox(menu_userdata, menu_driver_data->menu_state.msg); break; case RARCH_MENU_CTL_BLIT_RENDER: if (menu_driver_ctx->render) menu_driver_ctx->render(menu_userdata); break; case RARCH_MENU_CTL_RENDER: if (!menu_driver_data) return false; if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER) != BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_MESSAGEBOX)) BIT64_SET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER); if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_FRAMEBUFFER)) menu_display_ctl(MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL); if (BIT64_GET(menu_driver_data->state, MENU_STATE_RENDER_MESSAGEBOX) && !string_is_empty(menu_driver_data->menu_state.msg)) { menu_driver_ctl(RARCH_MENU_CTL_RENDER_MESSAGEBOX, NULL); if (ui_companion_is_on_foreground()) { const ui_companion_driver_t *ui = ui_companion_get_ptr(); if (ui->render_messagebox) ui->render_messagebox(menu_driver_data->menu_state.msg); } } if (BIT64_GET(menu_driver_data->state, MENU_STATE_BLIT)) { menu_animation_ctl(MENU_ANIMATION_CTL_UPDATE_TIME, NULL); menu_driver_ctl(RARCH_MENU_CTL_BLIT_RENDER, NULL); } if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL) && !runloop_ctl(RUNLOOP_CTL_IS_IDLE, NULL)) menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO, NULL); menu_driver_ctl(RARCH_MENU_CTL_SET_TEXTURE, NULL); menu_driver_data->state = 0; break; case RARCH_MENU_CTL_SHADER_DEINIT: #ifdef HAVE_SHADER_MANAGER if (menu_driver_shader) free(menu_driver_shader); menu_driver_shader = NULL; #endif break; case RARCH_MENU_CTL_SHADER_INIT: #ifdef HAVE_SHADER_MANAGER menu_driver_shader = (struct video_shader*) calloc(1, sizeof(struct video_shader)); if (!menu_driver_shader) return false; #endif break; case RARCH_MENU_CTL_SHADER_GET: { struct video_shader **shader = (struct video_shader**)data; if (!shader) return false; *shader = menu_driver_shader; } break; case RARCH_MENU_CTL_FRAME: if (!menu_driver_alive) return false; if (menu_driver_ctx->frame) menu_driver_ctx->frame(menu_userdata); break; case RARCH_MENU_CTL_SET_PREVENT_POPULATE: menu_driver_prevent_populate = true; break; case RARCH_MENU_CTL_UNSET_PREVENT_POPULATE: menu_driver_prevent_populate = false; break; case RARCH_MENU_CTL_IS_PREVENT_POPULATE: return menu_driver_prevent_populate; case RARCH_MENU_CTL_SET_TOGGLE: menu_driver_toggle(true); break; case RARCH_MENU_CTL_UNSET_TOGGLE: menu_driver_toggle(false); break; case RARCH_MENU_CTL_SET_ALIVE: menu_driver_alive = true; break; case RARCH_MENU_CTL_UNSET_ALIVE: menu_driver_alive = false; break; case RARCH_MENU_CTL_IS_ALIVE: return menu_driver_alive; case RARCH_MENU_CTL_SET_OWN_DRIVER: menu_driver_data_own = true; break; case RARCH_MENU_CTL_UNSET_OWN_DRIVER: if (!content_ctl(CONTENT_CTL_IS_INITED, NULL)) return false; menu_driver_data_own = false; break; case RARCH_MENU_CTL_SET_TEXTURE: if (menu_driver_ctx->set_texture) menu_driver_ctx->set_texture(); break; case RARCH_MENU_CTL_IS_SET_TEXTURE: if (!menu_driver_ctx) return false; return menu_driver_ctx->set_texture; case RARCH_MENU_CTL_OWNS_DRIVER: return menu_driver_data_own; case RARCH_MENU_CTL_DEINIT: menu_driver_ctl(RARCH_MENU_CTL_CONTEXT_DESTROY, NULL); if (menu_driver_ctl(RARCH_MENU_CTL_OWNS_DRIVER, NULL)) return true; if (menu_driver_data) { menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_FREE, NULL); menu_shader_free(menu_driver_data); menu_input_ctl(MENU_INPUT_CTL_DEINIT, NULL); menu_navigation_ctl(MENU_NAVIGATION_CTL_DEINIT, NULL); if (menu_driver_ctx && menu_driver_ctx->free) menu_driver_ctx->free(menu_userdata); if (menu_userdata) free(menu_userdata); menu_userdata = NULL; menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_DEINIT, NULL); menu_display_ctl(MENU_DISPLAY_CTL_DEINIT, NULL); menu_entries_ctl(MENU_ENTRIES_CTL_DEINIT, NULL); event_cmd_ctl(EVENT_CMD_HISTORY_DEINIT, NULL); core_info_ctl(CORE_INFO_CTL_LIST_DEINIT, NULL); core_info_ctl(CORE_INFO_CTL_CURRENT_CORE_FREE, NULL); free(menu_driver_data); } menu_driver_data = NULL; break; case RARCH_MENU_CTL_INIT: if (menu_driver_data) return true; menu_driver_data = (menu_handle_t*) menu_driver_ctx->init(&menu_userdata); if (!menu_driver_data || !menu_init(menu_driver_data)) { retro_fail(1, "init_menu()"); return false; } strlcpy(settings->menu.driver, menu_driver_ctx->ident, sizeof(settings->menu.driver)); if (menu_driver_ctx->lists_init) { if (!menu_driver_ctx->lists_init(menu_driver_data)) { retro_fail(1, "init_menu()"); return false; } } break; case RARCH_MENU_CTL_LOAD_NO_CONTENT_GET: { bool **ptr = (bool**)data; if (!ptr) return false; *ptr = (bool*)&menu_driver_load_no_content; } break; case RARCH_MENU_CTL_HAS_LOAD_NO_CONTENT: return menu_driver_load_no_content; case RARCH_MENU_CTL_SET_LOAD_NO_CONTENT: menu_driver_load_no_content = true; break; case RARCH_MENU_CTL_UNSET_LOAD_NO_CONTENT: menu_driver_load_no_content = false; break; case RARCH_MENU_CTL_NAVIGATION_INCREMENT: if (menu_driver_ctx->navigation_increment) menu_driver_ctx->navigation_increment(menu_userdata); break; case RARCH_MENU_CTL_NAVIGATION_DECREMENT: if (menu_driver_ctx->navigation_decrement) menu_driver_ctx->navigation_decrement(menu_userdata); break; case RARCH_MENU_CTL_NAVIGATION_SET: { bool *scroll = (bool*)data; if (!scroll) return false; if (menu_driver_ctx->navigation_set) menu_driver_ctx->navigation_set(menu_userdata, *scroll); } break; case RARCH_MENU_CTL_NAVIGATION_SET_LAST: if (menu_driver_ctx->navigation_set_last) menu_driver_ctx->navigation_set_last(menu_userdata); break; case RARCH_MENU_CTL_NAVIGATION_ASCEND_ALPHABET: { size_t *ptr_out = (size_t*)data; if (!ptr_out) return false; if (menu_driver_ctx->navigation_ascend_alphabet) menu_driver_ctx->navigation_ascend_alphabet( menu_userdata, ptr_out); } case RARCH_MENU_CTL_NAVIGATION_DESCEND_ALPHABET: { size_t *ptr_out = (size_t*)data; if (!ptr_out) return false; if (menu_driver_ctx->navigation_descend_alphabet) menu_driver_ctx->navigation_descend_alphabet( menu_userdata, ptr_out); } break; case RARCH_MENU_CTL_NAVIGATION_CLEAR: { bool *pending_push = (bool*)data; if (!pending_push) return false; if (menu_driver_ctx->navigation_clear) menu_driver_ctx->navigation_clear( menu_userdata, pending_push); } break; case RARCH_MENU_CTL_POPULATE_ENTRIES: { menu_displaylist_info_t *info = (menu_displaylist_info_t*)data; if (!info) return false; if (menu_driver_ctx->populate_entries) menu_driver_ctx->populate_entries( menu_userdata, info->path, info->label, info->type); } break; case RARCH_MENU_CTL_LIST_GET_ENTRY: { menu_ctx_list_t *list = (menu_ctx_list_t*)data; if (!menu_driver_ctx || !menu_driver_ctx->list_get_entry) { list->entry = NULL; return false; } list->entry = menu_driver_ctx->list_get_entry(menu_userdata, list->type, list->idx); } break; case RARCH_MENU_CTL_LIST_GET_SIZE: { menu_ctx_list_t *list = (menu_ctx_list_t*)data; if (!menu_driver_ctx || !menu_driver_ctx->list_get_size) { list->size = 0; return false; } list->size = menu_driver_ctx->list_get_size(menu_userdata, list->type); } break; case RARCH_MENU_CTL_LIST_GET_SELECTION: { menu_ctx_list_t *list = (menu_ctx_list_t*)data; if (!menu_driver_ctx || !menu_driver_ctx->list_get_selection) { list->selection = 0; return false; } list->selection = menu_driver_ctx->list_get_selection(menu_userdata); } break; case RARCH_MENU_CTL_LIST_FREE: { menu_ctx_list_t *list = (menu_ctx_list_t*)data; if (menu_driver_ctx) { if (menu_driver_ctx->list_free) menu_driver_ctx->list_free(list->list, list->idx, list->list_size); } if (list->list) { file_list_free_userdata (list->list, list->idx); file_list_free_actiondata(list->list, list->idx); } } break; case RARCH_MENU_CTL_LIST_PUSH: { menu_ctx_displaylist_t *disp_list = (menu_ctx_displaylist_t*)data; if (menu_driver_ctx->list_push) if (menu_driver_ctx->list_push(menu_driver_data, menu_userdata, disp_list->info, disp_list->type) == 0) return true; } return false; case RARCH_MENU_CTL_LIST_CLEAR: { file_list_t *list = (file_list_t*)data; if (!list) return false; if (menu_driver_ctx->list_clear) menu_driver_ctx->list_clear(list); } break; case RARCH_MENU_CTL_TOGGLE: { bool *latch = (bool*)data; if (!latch) return false; if (menu_driver_ctx->toggle) menu_driver_ctx->toggle(menu_userdata, *latch); } break; case RARCH_MENU_CTL_REFRESH: { #if 0 bool refresh = false; menu_entries_ctl(MENU_ENTRIES_CTL_LIST_DEINIT, NULL); menu_entries_ctl(MENU_ENTRIES_CTL_SETTINGS_DEINIT, NULL); menu_entries_ctl(MENU_ENTRIES_CTL_INIT, NULL); menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); #endif } break; case RARCH_MENU_CTL_CONTEXT_RESET: if (!menu_driver_ctx || !menu_driver_ctx->context_reset) return false; menu_driver_ctx->context_reset(menu_userdata); break; case RARCH_MENU_CTL_CONTEXT_DESTROY: if (!menu_driver_ctx || !menu_driver_ctx->context_destroy) return false; menu_driver_ctx->context_destroy(menu_userdata); break; case RARCH_MENU_CTL_SHADER_MANAGER_INIT: menu_shader_manager_init(menu_driver_data); break; case RARCH_MENU_CTL_LIST_SET_SELECTION: { file_list_t *list = (file_list_t*)data; if (!list) return false; if (!menu_driver_ctx || !menu_driver_ctx->list_set_selection) return false; menu_driver_ctx->list_set_selection(menu_userdata, list); } break; case RARCH_MENU_CTL_LIST_CACHE: { menu_ctx_list_t *list = (menu_ctx_list_t*)data; if (!list || !menu_driver_ctx || !menu_driver_ctx->list_cache) return false; menu_driver_ctx->list_cache(menu_userdata, list->type, list->action); } break; case RARCH_MENU_CTL_LIST_INSERT: { menu_ctx_list_t *list = (menu_ctx_list_t*)data; if (!list || !menu_driver_ctx || !menu_driver_ctx->list_insert) return false; menu_driver_ctx->list_insert(menu_userdata, list->list, list->path, list->label, list->idx); } break; case RARCH_MENU_CTL_LOAD_IMAGE: { menu_ctx_load_image_t *load_image_info = (menu_ctx_load_image_t*)data; if (!menu_driver_ctx || !menu_driver_ctx->load_image) return false; return menu_driver_ctx->load_image(menu_userdata, load_image_info->data, load_image_info->type); } case RARCH_MENU_CTL_ITERATE: { bool retcode = false; menu_ctx_iterate_t *iterate = (menu_ctx_iterate_t*)data; if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUICK_MENU, NULL)) { bool msg_force = true; menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUICK_MENU, NULL); menu_entries_flush_stack(NULL, MENU_SETTINGS); menu_display_ctl(MENU_DISPLAY_CTL_SET_MSG_FORCE, &msg_force); generic_action_ok_displaylist_push("", "", 0, 0, 0, ACTION_OK_DL_CONTENT_SETTINGS); if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUIT, NULL)) { menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUIT, NULL); return false; } return true; } if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_QUIT, NULL)) { menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_QUIT, NULL); return false; } if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_SHUTDOWN, NULL)) { menu_driver_ctl(RARCH_MENU_CTL_UNSET_PENDING_SHUTDOWN, NULL); if (!event_cmd_ctl(EVENT_CMD_QUIT, NULL)) return false; return true; } if (!menu_driver_ctx || !menu_driver_ctx->iterate) return false; if (menu_driver_ctl(RARCH_MENU_CTL_IS_PENDING_ACTION, &retcode)) { iterate->action = pending_iter.action; pending_iter.action = MENU_ACTION_NOOP; } if (menu_driver_ctx->iterate(menu_driver_data, menu_userdata, iterate->action) == -1) return false; } break; case RARCH_MENU_CTL_ENVIRONMENT: { menu_ctx_environment_t *menu_environ = (menu_ctx_environment_t*)data; if (menu_driver_ctx->environ_cb) { if (menu_driver_ctx->environ_cb(menu_environ->type, menu_environ->data, menu_userdata) == 0) return true; } } return false; case RARCH_MENU_CTL_POINTER_TAP: { menu_ctx_pointer_t *point = (menu_ctx_pointer_t*)data; if (!menu_driver_ctx || !menu_driver_ctx->pointer_tap) { point->retcode = 0; return false; } point->retcode = menu_driver_ctx->pointer_tap(menu_userdata, point->x, point->y, point->ptr, point->cbs, point->entry, point->action); } break; case RARCH_MENU_CTL_BIND_INIT: { menu_ctx_bind_t *bind = (menu_ctx_bind_t*)data; if (!menu_driver_ctx || !menu_driver_ctx->bind_init) { bind->retcode = 0; return false; } bind->retcode = menu_driver_ctx->bind_init( bind->cbs, bind->path, bind->label, bind->type, bind->idx, bind->elem0, bind->elem1, bind->label_hash, bind->menu_label_hash); } break; default: case RARCH_MENU_CTL_NONE: break; } return true; }
/** * event_cmd_ctl: * @cmd : Event command index. * * Performs program event command with index @cmd. * * Returns: true (1) on success, otherwise false (0). **/ bool event_cmd_ctl(enum event_command cmd, void *data) { unsigned i = 0; bool boolean = false; settings_t *settings = config_get_ptr(); rarch_system_info_t *info = NULL; runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info); (void)i; switch (cmd) { case EVENT_CMD_MENU_REFRESH: #ifdef HAVE_MENU menu_driver_ctl(RARCH_MENU_CTL_REFRESH, NULL); #endif break; case EVENT_CMD_SET_PER_GAME_RESOLUTION: #if defined(GEKKO) { unsigned width = 0, height = 0; event_cmd_ctl(EVENT_CMD_VIDEO_SET_ASPECT_RATIO, NULL); if (video_driver_get_video_output_size(&width, &height)) { char msg[128] = {0}; video_driver_set_video_mode(width, height, true); if (width == 0 || height == 0) strlcpy(msg, "Resolution: DEFAULT", sizeof(msg)); else snprintf(msg, sizeof(msg),"Resolution: %dx%d",width, height); runloop_msg_queue_push(msg, 1, 100, true); } } #endif break; case EVENT_CMD_LOAD_CONTENT_PERSIST: #ifdef HAVE_DYNAMIC event_cmd_ctl(EVENT_CMD_LOAD_CORE, NULL); #endif rarch_ctl(RARCH_CTL_LOAD_CONTENT, NULL); break; #ifdef HAVE_FFMPEG case EVENT_CMD_LOAD_CONTENT_FFMPEG: rarch_ctl(RARCH_CTL_LOAD_CONTENT_FFMPEG, NULL); break; #endif case EVENT_CMD_LOAD_CONTENT_IMAGEVIEWER: rarch_ctl(RARCH_CTL_LOAD_CONTENT_IMAGEVIEWER, NULL); break; case EVENT_CMD_LOAD_CONTENT: { #ifdef HAVE_DYNAMIC event_cmd_ctl(EVENT_CMD_LOAD_CONTENT_PERSIST, NULL); #else char *fullpath = NULL; runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath); runloop_ctl(RUNLOOP_CTL_SET_LIBRETRO_PATH, settings->libretro); event_cmd_ctl(EVENT_CMD_EXEC, (void*)fullpath); event_cmd_ctl(EVENT_CMD_QUIT, NULL); #endif } break; case EVENT_CMD_LOAD_CORE_DEINIT: #ifdef HAVE_MENU menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_DEINIT, NULL); #endif break; case EVENT_CMD_LOAD_CORE_PERSIST: event_cmd_ctl(EVENT_CMD_LOAD_CORE_DEINIT, NULL); { #ifdef HAVE_MENU bool *ptr = NULL; struct retro_system_info *system = NULL; menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_GET, &system); if (menu_driver_ctl(RARCH_MENU_CTL_LOAD_NO_CONTENT_GET, &ptr)) { core_info_ctx_find_t info_find; #if defined(HAVE_DYNAMIC) if (!(*settings->libretro)) return false; libretro_get_system_info(settings->libretro, system, ptr); #endif info_find.path = settings->libretro; if (!core_info_ctl(CORE_INFO_CTL_LOAD, &info_find)) return false; } #endif } break; case EVENT_CMD_LOAD_CORE: event_cmd_ctl(EVENT_CMD_LOAD_CORE_PERSIST, NULL); #ifndef HAVE_DYNAMIC event_cmd_ctl(EVENT_CMD_QUIT, NULL); #endif break; case EVENT_CMD_LOAD_STATE: /* Immutable - disallow savestate load when * we absolutely cannot change game state. */ if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) return false; #ifdef HAVE_NETPLAY if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) return false; #endif #ifdef HAVE_CHEEVOS if (settings->cheevos.hardcore_mode_enable) return false; #endif event_main_state(cmd); break; case EVENT_CMD_RESIZE_WINDOWED_SCALE: { unsigned idx = 0; unsigned *window_scale = NULL; runloop_ctl(RUNLOOP_CTL_GET_WINDOWED_SCALE, &window_scale); if (*window_scale == 0) return false; settings->video.scale = *window_scale; if (!settings->video.fullscreen) event_cmd_ctl(EVENT_CMD_REINIT, NULL); runloop_ctl(RUNLOOP_CTL_SET_WINDOWED_SCALE, &idx); } break; case EVENT_CMD_MENU_TOGGLE: #ifdef HAVE_MENU if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); else rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL); #endif break; case EVENT_CMD_CONTROLLERS_INIT: event_init_controllers(); break; case EVENT_CMD_RESET: RARCH_LOG("%s.\n", msg_hash_to_str(MSG_RESET)); runloop_msg_queue_push(msg_hash_to_str(MSG_RESET), 1, 120, true); #ifdef HAVE_CHEEVOS cheevos_ctl(CHEEVOS_CTL_SET_CHEATS, NULL); #endif core_ctl(CORE_CTL_RETRO_RESET, NULL); break; case EVENT_CMD_SAVE_STATE: #ifdef HAVE_CHEEVOS if (settings->cheevos.hardcore_mode_enable) return false; #endif if (settings->savestate_auto_index) settings->state_slot++; event_main_state(cmd); break; case EVENT_CMD_SAVE_STATE_DECREMENT: /* Slot -1 is (auto) slot. */ if (settings->state_slot >= 0) settings->state_slot--; break; case EVENT_CMD_SAVE_STATE_INCREMENT: settings->state_slot++; break; case EVENT_CMD_TAKE_SCREENSHOT: if (!take_screenshot()) return false; break; case EVENT_CMD_UNLOAD_CORE: runloop_ctl(RUNLOOP_CTL_PREPARE_DUMMY, NULL); event_cmd_ctl(EVENT_CMD_LOAD_CORE_DEINIT, NULL); break; case EVENT_CMD_QUIT: rarch_ctl(RARCH_CTL_QUIT, NULL); break; case EVENT_CMD_CHEEVOS_HARDCORE_MODE_TOGGLE: #ifdef HAVE_CHEEVOS cheevos_ctl(CHEEVOS_CTL_TOGGLE_HARDCORE_MODE, NULL); #endif break; case EVENT_CMD_REINIT: { struct retro_hw_render_callback *hwr = NULL; video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); if (hwr->cache_context) video_driver_ctl( RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT, NULL); else video_driver_ctl( RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT, NULL); video_driver_ctl( RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT_ACK, NULL); event_cmd_ctl(EVENT_CMD_RESET_CONTEXT, NULL); video_driver_ctl( RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT, NULL); /* Poll input to avoid possibly stale data to corrupt things. */ input_driver_ctl(RARCH_INPUT_CTL_POLL, NULL); #ifdef HAVE_MENU menu_display_ctl( MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL); if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) event_cmd_ctl(EVENT_CMD_VIDEO_SET_BLOCKING_STATE, NULL); #endif } break; case EVENT_CMD_CHEATS_DEINIT: cheat_manager_state_free(); break; case EVENT_CMD_CHEATS_INIT: event_cmd_ctl(EVENT_CMD_CHEATS_DEINIT, NULL); event_init_cheats(); break; case EVENT_CMD_CHEATS_APPLY: cheat_manager_apply_cheats(); break; case EVENT_CMD_REWIND_DEINIT: #ifdef HAVE_NETPLAY if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) return false; #endif #ifdef HAVE_CHEEVOS if (settings->cheevos.hardcore_mode_enable) return false; #endif state_manager_event_deinit(); break; case EVENT_CMD_REWIND_INIT: #ifdef HAVE_CHEEVOS if (settings->cheevos.hardcore_mode_enable) return false; #endif #ifdef HAVE_NETPLAY if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) #endif init_rewind(); break; case EVENT_CMD_REWIND_TOGGLE: if (settings->rewind_enable) event_cmd_ctl(EVENT_CMD_REWIND_INIT, NULL); else event_cmd_ctl(EVENT_CMD_REWIND_DEINIT, NULL); break; case EVENT_CMD_AUTOSAVE_DEINIT: #ifdef HAVE_THREADS autosave_event_deinit(); #endif break; case EVENT_CMD_AUTOSAVE_INIT: event_cmd_ctl(EVENT_CMD_AUTOSAVE_DEINIT, NULL); #ifdef HAVE_THREADS autosave_event_init(); #endif break; case EVENT_CMD_AUTOSAVE_STATE: event_save_auto_state(); break; case EVENT_CMD_AUDIO_STOP: if (!audio_driver_ctl(RARCH_AUDIO_CTL_ALIVE, NULL)) return false; if (!audio_driver_ctl(RARCH_AUDIO_CTL_STOP, NULL)) return false; break; case EVENT_CMD_AUDIO_START: if (audio_driver_ctl(RARCH_AUDIO_CTL_ALIVE, NULL)) return false; if (!settings->audio.mute_enable && !audio_driver_ctl(RARCH_AUDIO_CTL_START, NULL)) { RARCH_ERR("Failed to start audio driver. " "Will continue without audio.\n"); audio_driver_ctl(RARCH_AUDIO_CTL_UNSET_ACTIVE, NULL); } break; case EVENT_CMD_AUDIO_MUTE_TOGGLE: { const char *msg = !settings->audio.mute_enable ? msg_hash_to_str(MSG_AUDIO_MUTED): msg_hash_to_str(MSG_AUDIO_UNMUTED); if (!audio_driver_ctl(RARCH_AUDIO_CTL_MUTE_TOGGLE, NULL)) { RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_UNMUTE_AUDIO)); return false; } runloop_msg_queue_push(msg, 1, 180, true); RARCH_LOG("%s\n", msg); } break; case EVENT_CMD_OVERLAY_DEINIT: #ifdef HAVE_OVERLAY input_overlay_free(); #endif break; case EVENT_CMD_OVERLAY_INIT: event_cmd_ctl(EVENT_CMD_OVERLAY_DEINIT, NULL); #ifdef HAVE_OVERLAY input_overlay_init(); #endif break; case EVENT_CMD_OVERLAY_NEXT: #ifdef HAVE_OVERLAY input_overlay_next(settings->input.overlay_opacity); #endif break; case EVENT_CMD_DSP_FILTER_DEINIT: audio_driver_dsp_filter_free(); break; case EVENT_CMD_DSP_FILTER_INIT: event_cmd_ctl(EVENT_CMD_DSP_FILTER_DEINIT, NULL); if (!*settings->audio.dsp_plugin) break; audio_driver_dsp_filter_init(settings->audio.dsp_plugin); break; case EVENT_CMD_GPU_RECORD_DEINIT: video_driver_ctl(RARCH_DISPLAY_CTL_GPU_RECORD_DEINIT, NULL); break; case EVENT_CMD_RECORD_DEINIT: if (!recording_deinit()) return false; break; case EVENT_CMD_RECORD_INIT: event_cmd_ctl(EVENT_CMD_HISTORY_DEINIT, NULL); if (!recording_init()) return false; break; case EVENT_CMD_HISTORY_DEINIT: if (g_defaults.history) { content_playlist_write_file(g_defaults.history); content_playlist_free(g_defaults.history); } g_defaults.history = NULL; break; case EVENT_CMD_HISTORY_INIT: event_cmd_ctl(EVENT_CMD_HISTORY_DEINIT, NULL); if (!settings->history_list_enable) return false; RARCH_LOG("%s: [%s].\n", msg_hash_to_str(MSG_LOADING_HISTORY_FILE), settings->content_history_path); g_defaults.history = content_playlist_init( settings->content_history_path, settings->content_history_size); break; case EVENT_CMD_CORE_INFO_DEINIT: core_info_ctl(CORE_INFO_CTL_LIST_DEINIT, NULL); break; case EVENT_CMD_CORE_INFO_INIT: event_cmd_ctl(EVENT_CMD_CORE_INFO_DEINIT, NULL); if (*settings->libretro_directory) core_info_ctl(CORE_INFO_CTL_LIST_INIT, NULL); break; case EVENT_CMD_CORE_DEINIT: { struct retro_hw_render_callback *hwr = NULL; video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); event_deinit_core(true); if (hwr) memset(hwr, 0, sizeof(*hwr)); break; } case EVENT_CMD_CORE_INIT: if (!event_init_core(data)) return false; break; case EVENT_CMD_VIDEO_APPLY_STATE_CHANGES: video_driver_ctl(RARCH_DISPLAY_CTL_APPLY_STATE_CHANGES, NULL); break; case EVENT_CMD_VIDEO_SET_NONBLOCKING_STATE: boolean = true; /* fall-through */ case EVENT_CMD_VIDEO_SET_BLOCKING_STATE: video_driver_ctl(RARCH_DISPLAY_CTL_SET_NONBLOCK_STATE, &boolean); break; case EVENT_CMD_VIDEO_SET_ASPECT_RATIO: video_driver_ctl(RARCH_DISPLAY_CTL_SET_ASPECT_RATIO, NULL); break; case EVENT_CMD_AUDIO_SET_NONBLOCKING_STATE: boolean = true; /* fall-through */ case EVENT_CMD_AUDIO_SET_BLOCKING_STATE: audio_driver_set_nonblocking_state(boolean); break; case EVENT_CMD_OVERLAY_SET_SCALE_FACTOR: #ifdef HAVE_OVERLAY input_overlay_set_scale_factor(settings->input.overlay_scale); #endif break; case EVENT_CMD_OVERLAY_SET_ALPHA_MOD: #ifdef HAVE_OVERLAY input_overlay_set_alpha_mod(settings->input.overlay_opacity); #endif break; case EVENT_CMD_AUDIO_REINIT: { int flags = DRIVER_AUDIO; driver_ctl(RARCH_DRIVER_CTL_UNINIT, &flags); driver_ctl(RARCH_DRIVER_CTL_INIT, &flags); } break; case EVENT_CMD_RESET_CONTEXT: { /* RARCH_DRIVER_CTL_UNINIT clears the callback struct so we * need to make sure to keep a copy */ struct retro_hw_render_callback *hwr = NULL; struct retro_hw_render_callback hwr_copy; int flags = DRIVERS_CMD_ALL; video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); memcpy(&hwr_copy, hwr, sizeof(hwr_copy)); driver_ctl(RARCH_DRIVER_CTL_UNINIT, &flags); memcpy(hwr, &hwr_copy, sizeof(*hwr)); driver_ctl(RARCH_DRIVER_CTL_INIT, &flags); } break; case EVENT_CMD_QUIT_RETROARCH: rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL); break; case EVENT_CMD_SHUTDOWN: #if defined(__linux__) && !defined(ANDROID) runloop_msg_queue_push("Shutting down...", 1, 180, true); rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL); system("shutdown -P now"); #endif break; case EVENT_CMD_REBOOT: #if defined(__linux__) && !defined(ANDROID) runloop_msg_queue_push("Rebooting...", 1, 180, true); rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL); system("shutdown -r now"); #endif break; case EVENT_CMD_RESUME: rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); if (ui_companion_is_on_foreground()) ui_companion_driver_toggle(); break; case EVENT_CMD_RESTART_RETROARCH: if (!frontend_driver_set_fork(FRONTEND_FORK_RESTART)) return false; break; case EVENT_CMD_MENU_SAVE_CURRENT_CONFIG: event_save_current_config(); break; case EVENT_CMD_MENU_SAVE_CONFIG: if (!event_save_core_config()) return false; break; case EVENT_CMD_SHADERS_APPLY_CHANGES: #ifdef HAVE_MENU menu_shader_manager_apply_changes(); #endif break; case EVENT_CMD_PAUSE_CHECKS: if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL)) { RARCH_LOG("%s\n", msg_hash_to_str(MSG_PAUSED)); event_cmd_ctl(EVENT_CMD_AUDIO_STOP, NULL); if (settings->video.black_frame_insertion) video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, NULL); } else { RARCH_LOG("%s\n", msg_hash_to_str(MSG_UNPAUSED)); event_cmd_ctl(EVENT_CMD_AUDIO_START, NULL); } break; case EVENT_CMD_PAUSE_TOGGLE: boolean = runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL); boolean = !boolean; runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); event_cmd_ctl(EVENT_CMD_PAUSE_CHECKS, NULL); break; case EVENT_CMD_UNPAUSE: boolean = false; runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); event_cmd_ctl(EVENT_CMD_PAUSE_CHECKS, NULL); break; case EVENT_CMD_PAUSE: boolean = true; runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); event_cmd_ctl(EVENT_CMD_PAUSE_CHECKS, NULL); break; case EVENT_CMD_MENU_PAUSE_LIBRETRO: #ifdef HAVE_MENU if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) { if (settings->menu.pause_libretro) event_cmd_ctl(EVENT_CMD_AUDIO_STOP, NULL); else event_cmd_ctl(EVENT_CMD_AUDIO_START, NULL); } else { if (settings->menu.pause_libretro) event_cmd_ctl(EVENT_CMD_AUDIO_START, NULL); } #endif break; case EVENT_CMD_SHADER_DIR_DEINIT: runloop_ctl(RUNLOOP_CTL_SHADER_DIR_DEINIT, NULL); break; case EVENT_CMD_SHADER_DIR_INIT: event_cmd_ctl(EVENT_CMD_SHADER_DIR_DEINIT, NULL); if (!runloop_ctl(RUNLOOP_CTL_SHADER_DIR_INIT, NULL)) return false; break; case EVENT_CMD_SAVEFILES: { global_t *global = global_get_ptr(); if (!global->savefiles || !global->sram.use) return false; for (i = 0; i < global->savefiles->size; i++) { ram_type_t ram; ram.type = global->savefiles->elems[i].attr.i; ram.path = global->savefiles->elems[i].data; RARCH_LOG("%s #%u %s \"%s\".\n", msg_hash_to_str(MSG_SAVING_RAM_TYPE), ram.type, msg_hash_to_str(MSG_TO), ram.path); content_ctl(CONTENT_CTL_SAVE_RAM_FILE, &ram); } } return true; case EVENT_CMD_SAVEFILES_DEINIT: { global_t *global = global_get_ptr(); if (!global) break; if (global->savefiles) string_list_free(global->savefiles); global->savefiles = NULL; } break; case EVENT_CMD_SAVEFILES_INIT: { global_t *global = global_get_ptr(); global->sram.use = global->sram.use && !global->sram.save_disable; #ifdef HAVE_NETPLAY global->sram.use = global->sram.use && (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL) || !global->netplay.is_client); #endif if (!global->sram.use) RARCH_LOG("%s\n", msg_hash_to_str(MSG_SRAM_WILL_NOT_BE_SAVED)); if (global->sram.use) event_cmd_ctl(EVENT_CMD_AUTOSAVE_INIT, NULL); } break; case EVENT_CMD_BSV_MOVIE_DEINIT: bsv_movie_ctl(BSV_MOVIE_CTL_DEINIT, NULL); break; case EVENT_CMD_BSV_MOVIE_INIT: event_cmd_ctl(EVENT_CMD_BSV_MOVIE_DEINIT, NULL); bsv_movie_ctl(BSV_MOVIE_CTL_INIT, NULL); break; case EVENT_CMD_NETPLAY_DEINIT: #ifdef HAVE_NETPLAY deinit_netplay(); #endif break; case EVENT_CMD_NETWORK_DEINIT: #ifdef HAVE_NETWORKING network_deinit(); #endif break; case EVENT_CMD_NETWORK_INIT: #ifdef HAVE_NETWORKING network_init(); #endif break; case EVENT_CMD_NETPLAY_INIT: event_cmd_ctl(EVENT_CMD_NETPLAY_DEINIT, NULL); #ifdef HAVE_NETPLAY if (!init_netplay()) return false; #endif break; case EVENT_CMD_NETPLAY_FLIP_PLAYERS: #ifdef HAVE_NETPLAY netplay_driver_ctl(RARCH_NETPLAY_CTL_FLIP_PLAYERS, NULL); #endif break; case EVENT_CMD_FULLSCREEN_TOGGLE: if (!video_driver_ctl(RARCH_DISPLAY_CTL_HAS_WINDOWED, NULL)) return false; /* If we go fullscreen we drop all drivers and * reinitialize to be safe. */ settings->video.fullscreen = !settings->video.fullscreen; event_cmd_ctl(EVENT_CMD_REINIT, NULL); break; case EVENT_CMD_COMMAND_DEINIT: input_driver_ctl(RARCH_INPUT_CTL_COMMAND_DEINIT, NULL); break; case EVENT_CMD_COMMAND_INIT: event_cmd_ctl(EVENT_CMD_COMMAND_DEINIT, NULL); input_driver_ctl(RARCH_INPUT_CTL_COMMAND_INIT, NULL); break; case EVENT_CMD_REMOTE_DEINIT: input_driver_ctl(RARCH_INPUT_CTL_REMOTE_DEINIT, NULL); break; case EVENT_CMD_REMOTE_INIT: event_cmd_ctl(EVENT_CMD_REMOTE_DEINIT, NULL); input_driver_ctl(RARCH_INPUT_CTL_REMOTE_INIT, NULL); break; case EVENT_CMD_TEMPORARY_CONTENT_DEINIT: content_ctl(CONTENT_CTL_DEINIT, NULL); break; case EVENT_CMD_SUBSYSTEM_FULLPATHS_DEINIT: { global_t *global = global_get_ptr(); if (!global) break; if (global->subsystem_fullpaths) string_list_free(global->subsystem_fullpaths); global->subsystem_fullpaths = NULL; } break; case EVENT_CMD_LOG_FILE_DEINIT: retro_main_log_file_deinit(); break; case EVENT_CMD_DISK_APPEND_IMAGE: { const char *path = (const char*)data; if (string_is_empty(path)) return false; return event_disk_control_append_image(path); } case EVENT_CMD_DISK_EJECT_TOGGLE: if (info && info->disk_control_cb.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &info->disk_control_cb; if (control) { bool new_state = !control->get_eject_state(); event_disk_control_set_eject(new_state, true); } } else runloop_msg_queue_push( msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS), 1, 120, true); break; case EVENT_CMD_DISK_NEXT: if (info && info->disk_control_cb.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &info->disk_control_cb; if (!control) return false; if (!control->get_eject_state()) return false; event_check_disk_next(control); } else runloop_msg_queue_push( msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS), 1, 120, true); break; case EVENT_CMD_DISK_PREV: if (info && info->disk_control_cb.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &info->disk_control_cb; if (!control) return false; if (!control->get_eject_state()) return false; event_check_disk_prev(control); } else runloop_msg_queue_push( msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS), 1, 120, true); break; case EVENT_CMD_RUMBLE_STOP: for (i = 0; i < MAX_USERS; i++) { input_driver_set_rumble_state(i, RETRO_RUMBLE_STRONG, 0); input_driver_set_rumble_state(i, RETRO_RUMBLE_WEAK, 0); } break; case EVENT_CMD_GRAB_MOUSE_TOGGLE: { bool ret = false; static bool grab_mouse_state = false; grab_mouse_state = !grab_mouse_state; if (grab_mouse_state) ret = input_driver_ctl(RARCH_INPUT_CTL_GRAB_MOUSE, NULL); else ret = input_driver_ctl(RARCH_INPUT_CTL_UNGRAB_MOUSE, NULL); if (!ret) return false; RARCH_LOG("%s: %s.\n", msg_hash_to_str(MSG_GRAB_MOUSE_STATE), grab_mouse_state ? "yes" : "no"); if (grab_mouse_state) video_driver_ctl(RARCH_DISPLAY_CTL_HIDE_MOUSE, NULL); else video_driver_ctl(RARCH_DISPLAY_CTL_SHOW_MOUSE, NULL); } break; case EVENT_CMD_PERFCNT_REPORT_FRONTEND_LOG: rarch_perf_log(); break; case EVENT_CMD_VOLUME_UP: event_set_volume(0.5f); break; case EVENT_CMD_VOLUME_DOWN: event_set_volume(-0.5f); break; case EVENT_CMD_SET_FRAME_LIMIT: runloop_ctl(RUNLOOP_CTL_SET_FRAME_LIMIT, NULL); break; case EVENT_CMD_EXEC: return event_cmd_exec(data); case EVENT_CMD_NONE: default: return false; } return true; }
static int menu_input_mouse(unsigned *action) { unsigned fb_width, fb_height; video_viewport_t vp; const struct retro_keybind *binds[MAX_USERS]; menu_input_t *menu_input = menu_input_get_ptr(); settings_t *settings = config_get_ptr(); menu_display_ctl(MENU_DISPLAY_CTL_WIDTH, &fb_width); menu_display_ctl(MENU_DISPLAY_CTL_HEIGHT, &fb_height); if (!settings->menu.mouse.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && input_overlay_is_alive()) #endif ) { memset(&menu_input->mouse, 0, sizeof(menu_input->mouse)); return 0; } if (!video_driver_viewport_info(&vp)) return -1; if (menu_input->mouse.hwheeldown) { *action = MENU_ACTION_LEFT; menu_input->mouse.hwheeldown = false; return 0; } if (menu_input->mouse.hwheelup) { *action = MENU_ACTION_RIGHT; menu_input->mouse.hwheelup = false; return 0; } menu_input->mouse.left = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_LEFT); menu_input->mouse.right = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_RIGHT); menu_input->mouse.wheelup = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELUP); menu_input->mouse.wheeldown = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_WHEELDOWN); menu_input->mouse.hwheelup = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELUP); menu_input->mouse.hwheeldown = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELDOWN); menu_input->mouse.dx = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_X); menu_input->mouse.dy = input_driver_state(binds, 0, RETRO_DEVICE_MOUSE, 0, RETRO_DEVICE_ID_MOUSE_Y); menu_input->mouse.screen_x += menu_input->mouse.dx; menu_input->mouse.screen_y += menu_input->mouse.dy; menu_input->mouse.x = ((int)menu_input->mouse.screen_x * (int)fb_width) / (int)vp.width; menu_input->mouse.y = ((int)menu_input->mouse.screen_y * (int)fb_height) / (int)vp.height; if (menu_input->mouse.x < 5) menu_input->mouse.x = 5; if (menu_input->mouse.y < 5) menu_input->mouse.y = 5; if (menu_input->mouse.x > (int)fb_width - 5) menu_input->mouse.x = fb_width - 5; if (menu_input->mouse.y > (int)fb_height - 5) menu_input->mouse.y = fb_height - 5; menu_input->mouse.scrollup = (menu_input->mouse.y == 5); menu_input->mouse.scrolldown = (menu_input->mouse.y == (int)fb_height - 5); if ( (menu_input->mouse.dx != 0) || (menu_input->mouse.dy !=0) || menu_input->mouse.left || menu_input->mouse.wheelup || menu_input->mouse.wheeldown || menu_input->mouse.hwheelup || menu_input->mouse.hwheeldown || menu_input->mouse.scrollup || menu_input->mouse.scrolldown ) menu_animation_ctl(MENU_ANIMATION_CTL_SET_ACTIVE, NULL); return 0; }
bool menu_display_ctl(enum menu_display_ctl_state state, void *data) { unsigned width, height; menu_framebuf_t *frame_buf = menu_display_fb_get_ptr(); menu_display_t *disp = menu_display_get_ptr(); settings_t *settings = config_get_ptr(); switch (state) { case MENU_DISPLAY_CTL_FONT_BUF: { void **ptr = (void**)data; if (!ptr) return false; *ptr = disp->font.buf; } return true; case MENU_DISPLAY_CTL_SET_FONT_BUF: { void **ptr = (void**)data; if (!ptr) return false; disp->font.buf = *ptr; } return true; case MENU_DISPLAY_CTL_FONT_FB: { uint8_t **ptr = (uint8_t**)data; if (!ptr) return false; *ptr = (uint8_t*)disp->font.framebuf; } return true; case MENU_DISPLAY_CTL_SET_FONT_FB: { uint8_t **ptr = (uint8_t**)data; if (!ptr) return false; disp->font.framebuf = *ptr; } return true; case MENU_DISPLAY_CTL_LIBRETRO_RUNNING: { global_t *global = global_get_ptr(); if (!settings->menu.pause_libretro) if (global->inited.main && (global->inited.core.type != CORE_TYPE_DUMMY)) return true; } break; case MENU_DISPLAY_CTL_LIBRETRO: video_driver_set_texture_enable(true, false); if (menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO_RUNNING, NULL)) { driver_t *driver = driver_get_ptr(); bool block_libretro_input = driver->block_libretro_input; driver->block_libretro_input = true; core.retro_run(); driver->block_libretro_input = block_libretro_input; return true; } video_driver_cached_frame(); return true; case MENU_DISPLAY_CTL_SET_WIDTH: { unsigned *ptr = (unsigned*)data; if (!ptr) return false; frame_buf->width = *ptr; } return true; case MENU_DISPLAY_CTL_WIDTH: { unsigned *ptr = (unsigned*)data; if (!ptr) return false; *ptr = frame_buf->width; } return true; case MENU_DISPLAY_CTL_HEIGHT: { unsigned *ptr = (unsigned*)data; if (!ptr) return false; *ptr = frame_buf->height; } return true; case MENU_DISPLAY_CTL_HEADER_HEIGHT: { unsigned *ptr = (unsigned*)data; if (!ptr) return false; *ptr = disp->header_height; } return true; case MENU_DISPLAY_CTL_SET_HEADER_HEIGHT: { unsigned *ptr = (unsigned*)data; if (!ptr) return false; disp->header_height = *ptr; } return true; case MENU_DISPLAY_CTL_FONT_SIZE: { unsigned *ptr = (unsigned*)data; if (!ptr) return false; *ptr = disp->font.size; } return true; case MENU_DISPLAY_CTL_SET_FONT_SIZE: { unsigned *ptr = (unsigned*)data; if (!ptr) return false; disp->font.size = *ptr; } return true; case MENU_DISPLAY_CTL_SET_HEIGHT: { unsigned *ptr = (unsigned*)data; if (!ptr) return false; frame_buf->height = *ptr; } return true; case MENU_DISPLAY_CTL_FB_DATA: { uint16_t **ptr = (uint16_t**)data; if (!ptr) return false; *ptr = frame_buf->data; } return true; case MENU_DISPLAY_CTL_SET_FB_DATA: { uint16_t *ptr = (uint16_t*)data; if (!ptr) return false; frame_buf->data = ptr; } return true; case MENU_DISPLAY_CTL_FB_PITCH: { size_t *ptr = (size_t*)data; if (!ptr) return false; *ptr = frame_buf->pitch; } return true; case MENU_DISPLAY_CTL_SET_FB_PITCH: { size_t *ptr = (size_t*)data; if (!ptr) return false; frame_buf->pitch = *ptr; } return true; case MENU_DISPLAY_CTL_MSG_FORCE: { bool *ptr = (bool*)data; if (!ptr) return false; *ptr = disp->msg_force; } return true; case MENU_DISPLAY_CTL_SET_MSG_FORCE: { bool *ptr = (bool*)data; if (!ptr) return false; disp->msg_force = *ptr; } return true; case MENU_DISPLAY_CTL_FONT_DATA_INIT: { bool *ptr = (bool*)data; if (!ptr) return false; *ptr = disp->font.alloc_framebuf; } return true; case MENU_DISPLAY_CTL_SET_FONT_DATA_INIT: { bool *ptr = (bool*)data; if (!ptr) return false; disp->font.alloc_framebuf = *ptr; } return true; case MENU_DISPLAY_CTL_UPDATE_PENDING: { bool ptr; menu_display_ctl(MENU_DISPLAY_CTL_GET_FRAMEBUFFER_DIRTY_FLAG, &ptr); if (menu_animation_ctl(MENU_ANIMATION_CTL_IS_ACTIVE, NULL) || ptr) return true; } return false; case MENU_DISPLAY_CTL_SET_VIEWPORT: video_driver_get_size(&width, &height); video_driver_set_viewport(width, height, true, false); return true; case MENU_DISPLAY_CTL_UNSET_VIEWPORT: video_driver_get_size(&width, &height); video_driver_set_viewport(width, height, false, true); return true; case MENU_DISPLAY_CTL_GET_FRAMEBUFFER_DIRTY_FLAG: { bool *ptr = (bool*)data; if (!ptr || !frame_buf) return false; *ptr = frame_buf->dirty; } return true; case MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG: if (frame_buf && frame_buf->data) frame_buf->dirty = true; return true; case MENU_DISPLAY_CTL_UNSET_FRAMEBUFFER_DIRTY_FLAG: if (frame_buf && frame_buf->data) frame_buf->dirty = false; return true; case MENU_DISPLAY_CTL_GET_DPI: { float *dpi = (float*)data; *dpi = menu_dpi_override_value; if (!settings) return true; if (settings->menu.dpi.override_enable) *dpi = settings->menu.dpi.override_value; else if (!gfx_ctx_get_metrics(DISPLAY_METRIC_DPI, dpi)) *dpi = menu_dpi_override_value; } return true; } return false; }
static int menu_input_pointer_post_iterate( menu_file_list_cbs_t *cbs, menu_entry_t *entry, unsigned action) { unsigned header_height; size_t selection; static bool pointer_oldpressed[2]; static bool pointer_oldback = false; static int16_t start_x = 0; static int16_t start_y = 0; static int16_t pointer_old_x = 0; static int16_t pointer_old_y = 0; int ret = 0; menu_input_t *menu_input = menu_input_get_ptr(); settings_t *settings = config_get_ptr(); bool check_overlay = false; if (settings) check_overlay = !settings->menu.pointer.enable; if (!menu_input) return -1; if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return -1; menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); #ifdef HAVE_OVERLAY check_overlay = check_overlay || (settings->input.overlay_enable && input_overlay_is_alive()); #endif if (check_overlay) return 0; if (menu_input->pointer.pressed[0]) { gfx_ctx_metrics_t metrics; float dpi; static float accel0 = 0.0f; static float accel1 = 0.0f; int16_t pointer_x = menu_input_pointer_state(MENU_POINTER_X_AXIS); int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS); metrics.type = DISPLAY_METRIC_DPI; metrics.value = &dpi; gfx_ctx_ctl(GFX_CTL_GET_METRICS, &metrics); if (!pointer_oldpressed[0]) { menu_input->pointer.accel = 0; accel0 = 0; accel1 = 0; start_x = pointer_x; start_y = pointer_y; pointer_old_x = pointer_x; pointer_old_y = pointer_y; pointer_oldpressed[0] = true; } else if (abs(pointer_x - start_x) > (dpi / 10) || abs(pointer_y - start_y) > (dpi / 10)) { float s, delta_time; menu_input_ctl(MENU_INPUT_CTL_SET_POINTER_DRAGGED, NULL); menu_input->pointer.dx = pointer_x - pointer_old_x; menu_input->pointer.dy = pointer_y - pointer_old_y; pointer_old_x = pointer_x; pointer_old_y = pointer_y; menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time); s = (menu_input->pointer.dy * 550000000.0 ) / ( dpi * delta_time ); menu_input->pointer.accel = (accel0 + accel1 + s) / 3; accel0 = accel1; accel1 = menu_input->pointer.accel; } } else { if (pointer_oldpressed[0]) { if (!menu_input_ctl(MENU_INPUT_CTL_IS_POINTER_DRAGGED, NULL)) { menu_ctx_pointer_t point; point.x = start_x; point.y = start_y; point.ptr = menu_input->pointer.ptr; point.cbs = cbs; point.entry = entry; point.action = action; menu_driver_ctl(RARCH_MENU_CTL_POINTER_TAP, &point); ret = point.retcode; } pointer_oldpressed[0] = false; start_x = 0; start_y = 0; pointer_old_x = 0; pointer_old_y = 0; menu_input->pointer.dx = 0; menu_input->pointer.dy = 0; menu_input_ctl(MENU_INPUT_CTL_UNSET_POINTER_DRAGGED, NULL); } } if (menu_input->pointer.back) { if (!pointer_oldback) { pointer_oldback = true; menu_entries_pop_stack(&selection, 0, 1); menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection); } } pointer_oldback = menu_input->pointer.back; return ret; }
static void glui_frame(void) { unsigned i, header_height; bool display_kb; GRfloat coord_color[16]; GRfloat coord_color2[16]; GRfloat black_bg[16]; GRfloat bar_bg[16]; GRfloat highlight_bg[16]; GRfloat white_bg[16]; unsigned width, height, ticker_limit; char msg[PATH_MAX_LENGTH]; char title[PATH_MAX_LENGTH]; char title_buf[PATH_MAX_LENGTH]; char title_msg[PATH_MAX_LENGTH]; char timedate[PATH_MAX_LENGTH]; size_t selection; gl_t *gl = NULL; glui_handle_t *glui = NULL; const struct font_renderer *font_driver = NULL; driver_t *driver = driver_get_ptr(); menu_handle_t *menu = menu_driver_get_ptr(); settings_t *settings = config_get_ptr(); uint64_t *frame_count = video_driver_get_frame_count(); const uint32_t normal_color = FONT_COLOR_ARGB_TO_RGBA( settings->menu.entry_normal_color); const uint32_t hover_color = FONT_COLOR_ARGB_TO_RGBA( settings->menu.entry_hover_color); const uint32_t title_color = FONT_COLOR_ARGB_TO_RGBA( settings->menu.title_color); if (!menu || !menu->userdata) return; gl = (gl_t*)video_driver_get_ptr(NULL); if (!gl) return; glui = (glui_handle_t*)menu->userdata; msg[0] = '\0'; title[0] = '\0'; title_buf[0] = '\0'; title_msg[0] = '\0'; timedate[0] = '\0'; video_driver_get_size(&width, &height); menu_display_ctl(MENU_DISPLAY_CTL_SET_VIEWPORT, NULL); menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); for (i = 0; i < 16; i++) { coord_color[i] = 0; coord_color2[i] = 1.0f; black_bg[i] = 0; bar_bg[i] = 0.2; highlight_bg[i] = 1; white_bg[i] = 1; if (i == 3 || i == 7 || i == 11 || i == 15) { black_bg[i] = 0.75f; coord_color[i] = 0.75f; coord_color2[i] = 0.75f; bar_bg[i] = 1.00f; highlight_bg[i] = 0.1f; } } menu_video_frame_background(menu, settings, gl, width, height, glui->textures.bg.id, 0.75f, false, &coord_color[0], &coord_color2[0], &glui_vertexes[0], &glui_tex_coords[0]); menu_entries_get_title(title, sizeof(title)); font_driver = driver->font_osd_driver; menu_display_font_bind_block(menu, font_driver, &glui->list_block); glui_render_menu_list(glui, width, height, menu, normal_color, hover_color); menu_display_font_flush_block(menu, font_driver); if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return; glui_render_quad(gl, 0, header_height - menu->scroll_y + glui->line_height * selection, width, glui->line_height, width, height, &highlight_bg[0]); menu_animation_ctl(MENU_ANIMATION_CTL_SET_ACTIVE, NULL); glui_render_quad(gl, 0, 0, width, header_height, width, height, &bar_bg[0]); ticker_limit = (width - glui->margin*2) / glui->glyph_width - strlen(menu_hash_to_str(MENU_VALUE_BACK)) * 2; menu_animation_ticker_str(title_buf, ticker_limit, *frame_count / 100, title, true); glui_blit_line(width / 2, 0, width, height, title_buf, title_color, TEXT_ALIGN_CENTER); if (menu_entries_show_back()) glui_blit_line(glui->margin, 0, width, height, menu_hash_to_str(MENU_VALUE_BACK), title_color, TEXT_ALIGN_LEFT); glui_render_quad(gl, 0, height - header_height, width, header_height, width, height, &bar_bg[0]); glui_draw_scrollbar(gl, width, height, &white_bg[0]); if (menu_entries_get_core_title(title_msg, sizeof(title_msg)) == 0) glui_blit_line( glui->margin, height - glui->line_height, width, height, title_msg, title_color, TEXT_ALIGN_LEFT); if (settings->menu.timedate_enable) { menu_display_timedate(timedate, sizeof(timedate), 0); glui_blit_line( width - glui->margin, height - glui->line_height, width, height, timedate, hover_color, TEXT_ALIGN_RIGHT); } menu_input_ctl(MENU_INPUT_CTL_KEYBOARD_DISPLAY, &display_kb); if (display_kb) { const char *str = NULL, *label = NULL; menu_input_ctl(MENU_INPUT_CTL_KEYBOARD_BUFF_PTR, &str); menu_input_ctl(MENU_INPUT_CTL_KEYBOARD_LABEL, &label); if (!str) str = ""; glui_render_quad(gl, 0, 0, width, height, width, height, &black_bg[0]); snprintf(msg, sizeof(msg), "%s\n%s", label, str); glui_render_messagebox(msg); } if (glui->box_message[0] != '\0') { glui_render_quad(gl, 0, 0, width, height, width, height, &black_bg[0]); glui_render_messagebox(glui->box_message); glui->box_message[0] = '\0'; } if (settings->menu.mouse.enable) { int16_t mouse_x = menu_input_mouse_state(MENU_MOUSE_X_AXIS); int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS); glui_render_quad(gl, mouse_x - 5, mouse_y - 5, 10, 10, width, height, &white_bg[0]); } gl->shader->use(gl, GL_SHADER_STOCK_BLEND); menu_display_ctl(MENU_DISPLAY_CTL_UNSET_VIEWPORT, NULL); }
static void glui_render(void) { float delta_time, dt; int bottom; unsigned width, height, header_height; glui_handle_t *glui = NULL; menu_handle_t *menu = menu_driver_get_ptr(); settings_t *settings = config_get_ptr(); if (!menu || !menu->userdata) return; video_driver_get_size(&width, &height); glui = (glui_handle_t*)menu->userdata; menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time); dt = delta_time / IDEAL_DT; menu_animation_ctl(MENU_ANIMATION_CTL_UPDATE, &dt); menu_display_ctl(MENU_DISPLAY_CTL_SET_WIDTH, &width); menu_display_ctl(MENU_DISPLAY_CTL_SET_HEIGHT, &height); menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); if (settings->menu.pointer.enable) { int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS); float old_accel_val, new_accel_val; unsigned new_pointer_val = (pointer_y - glui->line_height + menu->scroll_y - 16) / glui->line_height; menu_input_ctl(MENU_INPUT_CTL_POINTER_ACCEL_READ, &old_accel_val); menu_input_ctl(MENU_INPUT_CTL_POINTER_PTR, &new_pointer_val); menu->scroll_y -= old_accel_val / 60.0; new_accel_val = old_accel_val * 0.96; menu_input_ctl(MENU_INPUT_CTL_POINTER_ACCEL_WRITE, &new_accel_val); } if (settings->menu.mouse.enable) { unsigned new_mouse_ptr = 0; bool mouse_scrolldown, mouse_scrollup; int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS); menu_input_ctl(MENU_INPUT_CTL_MOUSE_SCROLL_DOWN, &mouse_scrolldown); menu_input_ctl(MENU_INPUT_CTL_MOUSE_SCROLL_UP, &mouse_scrollup); if (mouse_scrolldown) menu->scroll_y += 10; if (mouse_scrollup) menu->scroll_y -= 10; new_mouse_ptr = (mouse_y - glui->line_height + menu->scroll_y - 16) / glui->line_height; menu_input_ctl(MENU_INPUT_CTL_MOUSE_PTR, &new_mouse_ptr); } if (menu->scroll_y < 0) menu->scroll_y = 0; bottom = menu_entries_get_end() * glui->line_height - height + header_height * 2; if (menu->scroll_y > bottom) menu->scroll_y = bottom; if (menu_entries_get_end() * glui->line_height < height - header_height*2) menu->scroll_y = 0; if (menu_entries_get_end() < height / glui->line_height) menu_entries_set_start(0); else menu_entries_set_start(menu->scroll_y / glui->line_height); }
static void xui_render(void *data) { uint64_t *frame_count; bool display_kb, msg_force; unsigned fb_width; size_t end, i, selection; char title[PATH_MAX_LENGTH] = {0}; const char *dir = NULL; const char *label = NULL; unsigned menu_type = 0; video_driver_ctl(RARCH_DISPLAY_CTL_GET_FRAME_COUNT, &frame_count); menu_display_ctl(MENU_DISPLAY_CTL_WIDTH, &fb_width); menu_display_ctl(MENU_DISPLAY_CTL_MSG_FORCE, &msg_force); if ( menu_entries_ctl(MENU_ENTRIES_CTL_NEEDS_REFRESH, NULL) && menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL) && !msg_force ) return; menu_display_ctl(MENU_DISPLAY_CTL_UNSET_FRAMEBUFFER_DIRTY_FLAG, NULL); menu_animation_ctl(MENU_ANIMATION_CTL_CLEAR_ACTIVE, NULL); xui_render_background(); if (XuiHandleIsValid(m_menutitle)) { menu_entries_get_title(title, sizeof(title)); mbstowcs(strw_buffer, title, sizeof(strw_buffer) / sizeof(wchar_t)); XuiTextElementSetText(m_menutitle, strw_buffer); menu_animation_ticker_str(title, RXUI_TERM_WIDTH(fb_width) - 3, (unsigned int)*frame_count / 15, title, true); } if (XuiHandleIsValid(m_menutitle)) { if (menu_entries_get_core_title(title, sizeof(title)) == 0) { mbstowcs(strw_buffer, title, sizeof(strw_buffer) / sizeof(wchar_t)); XuiTextElementSetText(m_menutitlebottom, strw_buffer); } } end = menu_entries_get_end(); for (i = 0; i < end; i++) { char entry_path[PATH_MAX_LENGTH] = {0}; char entry_value[PATH_MAX_LENGTH] = {0}; wchar_t msg_right[PATH_MAX_LENGTH] = {0}; wchar_t msg_left[PATH_MAX_LENGTH] = {0}; menu_entry_get_value(i, entry_value, sizeof(entry_value)); menu_entry_get_path(i, entry_path, sizeof(entry_path)); mbstowcs(msg_left, entry_path, sizeof(msg_left) / sizeof(wchar_t)); mbstowcs(msg_right, entry_value, sizeof(msg_right) / sizeof(wchar_t)); xui_set_list_text(i, msg_left, msg_right); } if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return; XuiListSetCurSelVisible(m_menulist, selection); menu_input_ctl(MENU_INPUT_CTL_KEYBOARD_DISPLAY, &display_kb); if (display_kb) { char msg[1024] = {0}; const char *str = NULL, *label = NULL; menu_input_ctl(MENU_INPUT_CTL_KEYBOARD_BUFF_PTR, &str); menu_input_ctl(MENU_INPUT_CTL_KEYBOARD_LABEL, &label); if (!str) str = ""; snprintf(msg, sizeof(msg), "%s\n%s", label, str); xui_render_messagebox(msg); } }
static int menu_input_pointer_post_iterate(menu_file_list_cbs_t *cbs, menu_entry_t *entry, unsigned action) { unsigned header_height; size_t selection; int ret = 0; menu_input_t *menu_input = menu_input_get_ptr(); settings_t *settings = config_get_ptr(); if (!menu_input) return -1; if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return -1; menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); if (!settings->menu.pointer.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && input_overlay_is_alive()) #endif ) return 0; if (menu_input->pointer.pressed[0]) { int16_t pointer_x = menu_input_pointer_state(MENU_POINTER_X_AXIS); int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS); if (!menu_input->pointer.oldpressed[0]) { menu_input->pointer.accel = 0; menu_input->pointer.accel0 = 0; menu_input->pointer.accel1 = 0; menu_input->pointer.start_x = pointer_x; menu_input->pointer.start_y = pointer_y; menu_input->pointer.old_x = pointer_x; menu_input->pointer.old_y = pointer_y; menu_input->pointer.oldpressed[0] = true; } else if (abs(pointer_x - menu_input->pointer.start_x) > 3 || abs(pointer_y - menu_input->pointer.start_y) > 3) { float s, delta_time; menu_input->pointer.dragging = true; menu_input->pointer.dx = pointer_x - menu_input->pointer.old_x; menu_input->pointer.dy = pointer_y - menu_input->pointer.old_y; menu_input->pointer.old_x = pointer_x; menu_input->pointer.old_y = pointer_y; menu_animation_ctl(MENU_ANIMATION_CTL_DELTA_TIME, &delta_time); s = menu_input->pointer.dy / delta_time * 1000000.0; menu_input->pointer.accel = (menu_input->pointer.accel0 + menu_input->pointer.accel1 + s) / 3; menu_input->pointer.accel0 = menu_input->pointer.accel1; menu_input->pointer.accel1 = menu_input->pointer.accel; } } else { if (menu_input->pointer.oldpressed[0]) { if (!menu_input->pointer.dragging) ret = menu_driver_pointer_tap(menu_input->pointer.start_x, menu_input->pointer.start_y, menu_input->pointer.ptr, cbs, entry, action); menu_input->pointer.oldpressed[0] = false; menu_input->pointer.start_x = 0; menu_input->pointer.start_y = 0; menu_input->pointer.old_x = 0; menu_input->pointer.old_y = 0; menu_input->pointer.dx = 0; menu_input->pointer.dy = 0; menu_input->pointer.dragging = false; } } if (menu_input->pointer.back) { if (!menu_input->pointer.oldback) { menu_input->pointer.oldback = true; menu_entries_pop_stack(&selection, 0); menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection); } } menu_input->pointer.oldback = menu_input->pointer.back; return ret; }
/** * event_command: * @cmd : Event command index. * * Performs program event command with index @cmd. * * Returns: true (1) on success, otherwise false (0). **/ bool event_command(enum event_command cmd) { unsigned i = 0; bool boolean = false; driver_t *driver = driver_get_ptr(); global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); rarch_system_info_t *system = rarch_system_info_get_ptr(); (void)i; switch (cmd) { case EVENT_CMD_LOAD_CONTENT_PERSIST: #ifdef HAVE_DYNAMIC event_command(EVENT_CMD_LOAD_CORE); #endif rarch_ctl(RARCH_ACTION_STATE_LOAD_CONTENT, NULL); break; #ifdef HAVE_FFMPEG case EVENT_CMD_LOAD_CONTENT_FFMPEG: rarch_ctl(RARCH_ACTION_STATE_LOAD_CONTENT_FFMPEG, NULL); break; #endif case EVENT_CMD_LOAD_CONTENT_IMAGEVIEWER: rarch_ctl(RARCH_ACTION_STATE_LOAD_CONTENT_IMAGEVIEWER, NULL); break; case EVENT_CMD_LOAD_CONTENT: #ifdef HAVE_DYNAMIC event_command(EVENT_CMD_LOAD_CONTENT_PERSIST); #else rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)settings->libretro); rarch_environment_cb(RETRO_ENVIRONMENT_EXEC, (void*)global->path.fullpath); event_command(EVENT_CMD_QUIT); #endif break; case EVENT_CMD_LOAD_CORE_DEINIT: #ifdef HAVE_DYNAMIC libretro_free_system_info(&global->menu.info); #endif break; case EVENT_CMD_LOAD_CORE_PERSIST: event_command(EVENT_CMD_LOAD_CORE_DEINIT); { #ifdef HAVE_MENU menu_handle_t *menu = menu_driver_get_ptr(); if (menu) event_update_system_info(&global->menu.info, &menu->load_no_content); #endif } break; case EVENT_CMD_LOAD_CORE: event_command(EVENT_CMD_LOAD_CORE_PERSIST); #ifndef HAVE_DYNAMIC event_command(EVENT_CMD_QUIT); #endif break; case EVENT_CMD_LOAD_STATE: /* Immutable - disallow savestate load when * we absolutely cannot change game state. */ if (global->bsv.movie) return false; #ifdef HAVE_NETPLAY if (driver->netplay_data) return false; #endif event_main_state(cmd); break; case EVENT_CMD_RESIZE_WINDOWED_SCALE: if (global->pending.windowed_scale == 0) return false; settings->video.scale = global->pending.windowed_scale; if (!settings->video.fullscreen) event_command(EVENT_CMD_REINIT); global->pending.windowed_scale = 0; break; case EVENT_CMD_MENU_TOGGLE: #ifdef HAVE_MENU if (menu_driver_alive()) rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED, NULL); else rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING, NULL); #endif break; case EVENT_CMD_CONTROLLERS_INIT: event_init_controllers(); break; case EVENT_CMD_RESET: RARCH_LOG("%s.\n", msg_hash_to_str(MSG_RESET)); rarch_main_msg_queue_push_new(MSG_RESET, 1, 120, true); core.retro_reset(); /* bSNES since v073r01 resets controllers to JOYPAD * after a reset, so just enforce it here. */ event_command(EVENT_CMD_CONTROLLERS_INIT); break; case EVENT_CMD_SAVE_STATE: if (settings->savestate_auto_index) settings->state_slot++; event_main_state(cmd); break; case EVENT_CMD_SAVE_STATE_DECREMENT: /* Slot -1 is (auto) slot. */ if (settings->state_slot >= 0) settings->state_slot--; break; case EVENT_CMD_SAVE_STATE_INCREMENT: settings->state_slot++; break; case EVENT_CMD_TAKE_SCREENSHOT: if (!take_screenshot()) return false; break; case EVENT_CMD_PREPARE_DUMMY: { #ifdef HAVE_MENU menu_handle_t *menu = menu_driver_get_ptr(); if (menu) menu->load_no_content = false; #endif rarch_main_data_deinit(); *global->path.fullpath = '\0'; rarch_ctl(RARCH_ACTION_STATE_LOAD_CONTENT, NULL); } break; case EVENT_CMD_UNLOAD_CORE: event_command(EVENT_CMD_PREPARE_DUMMY); event_command(EVENT_CMD_LOAD_CORE_DEINIT); break; case EVENT_CMD_QUIT: rarch_ctl(RARCH_ACTION_STATE_QUIT, NULL); break; case EVENT_CMD_REINIT: { const struct retro_hw_render_callback *hw_render = (const struct retro_hw_render_callback*)video_driver_callback(); const input_driver_t *input = driver ? (const input_driver_t*)driver->input : NULL; driver->video_cache_context = hw_render->cache_context; driver->video_cache_context_ack = false; event_command(EVENT_CMD_RESET_CONTEXT); driver->video_cache_context = false; /* Poll input to avoid possibly stale data to corrupt things. */ input->poll(driver->input_data); #ifdef HAVE_MENU menu_display_ctl(MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL); if (menu_driver_alive()) event_command(EVENT_CMD_VIDEO_SET_BLOCKING_STATE); #endif } break; case EVENT_CMD_CHEATS_DEINIT: if (!global) break; if (global->cheat) cheat_manager_free(global->cheat); global->cheat = NULL; break; case EVENT_CMD_CHEATS_INIT: event_command(EVENT_CMD_CHEATS_DEINIT); event_init_cheats(); break; case EVENT_CMD_CHEATS_APPLY: if (!global->cheat) break; cheat_manager_apply_cheats(global->cheat); break; case EVENT_CMD_REMAPPING_DEINIT: break; case EVENT_CMD_REMAPPING_INIT: event_command(EVENT_CMD_REMAPPING_DEINIT); event_init_remapping(); break; case EVENT_CMD_REWIND_DEINIT: if (!global) break; #ifdef HAVE_NETPLAY if (driver->netplay_data) return false; #endif if (global->rewind.state) state_manager_free(global->rewind.state); global->rewind.state = NULL; break; case EVENT_CMD_REWIND_INIT: if (!driver->netplay_data) init_rewind(); break; case EVENT_CMD_REWIND_TOGGLE: if (settings->rewind_enable) event_command(EVENT_CMD_REWIND_INIT); else event_command(EVENT_CMD_REWIND_DEINIT); break; case EVENT_CMD_AUTOSAVE_DEINIT: #ifdef HAVE_THREADS event_deinit_autosave(); #endif break; case EVENT_CMD_AUTOSAVE_INIT: event_command(EVENT_CMD_AUTOSAVE_DEINIT); #ifdef HAVE_THREADS event_init_autosave(); #endif break; case EVENT_CMD_AUTOSAVE_STATE: event_save_auto_state(); break; case EVENT_CMD_AUDIO_STOP: if (!driver->audio_data) return false; if (!audio_driver_alive()) return false; if (!audio_driver_stop()) return false; break; case EVENT_CMD_AUDIO_START: if (!driver->audio_data || audio_driver_alive()) return false; if (!settings->audio.mute_enable && !audio_driver_start()) { RARCH_ERR("Failed to start audio driver. Will continue without audio.\n"); driver->audio_active = false; } break; case EVENT_CMD_AUDIO_MUTE_TOGGLE: { const char *msg = !settings->audio.mute_enable ? msg_hash_to_str(MSG_AUDIO_MUTED): msg_hash_to_str(MSG_AUDIO_UNMUTED); if (!audio_driver_mute_toggle()) { RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_UNMUTE_AUDIO)); return false; } rarch_main_msg_queue_push(msg, 1, 180, true); RARCH_LOG("%s\n", msg); } break; case EVENT_CMD_OVERLAY_DEINIT: #ifdef HAVE_OVERLAY input_overlay_free_ptr(); #endif break; case EVENT_CMD_OVERLAY_INIT: event_command(EVENT_CMD_OVERLAY_DEINIT); #ifdef HAVE_OVERLAY if (input_overlay_new_ptr() == -1) RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_LOAD_OVERLAY)); #endif break; case EVENT_CMD_OVERLAY_NEXT: #ifdef HAVE_OVERLAY input_overlay_next(settings->input.overlay_opacity); #endif break; case EVENT_CMD_DSP_FILTER_DEINIT: if (!global) break; audio_driver_dsp_filter_free(); break; case EVENT_CMD_DSP_FILTER_INIT: event_command(EVENT_CMD_DSP_FILTER_DEINIT); if (!*settings->audio.dsp_plugin) break; audio_driver_dsp_filter_init(settings->audio.dsp_plugin); break; case EVENT_CMD_GPU_RECORD_DEINIT: if (!global) break; if (global->record.gpu_buffer) free(global->record.gpu_buffer); global->record.gpu_buffer = NULL; break; case EVENT_CMD_RECORD_DEINIT: if (!recording_deinit()) return false; break; case EVENT_CMD_RECORD_INIT: event_command(EVENT_CMD_HISTORY_DEINIT); if (!recording_init()) return false; break; case EVENT_CMD_HISTORY_DEINIT: if (g_defaults.history) { content_playlist_write_file(g_defaults.history); content_playlist_free(g_defaults.history); } g_defaults.history = NULL; break; case EVENT_CMD_HISTORY_INIT: event_command(EVENT_CMD_HISTORY_DEINIT); if (!settings->history_list_enable) return false; RARCH_LOG("%s: [%s].\n", msg_hash_to_str(MSG_LOADING_HISTORY_FILE), settings->content_history_path); g_defaults.history = content_playlist_init( settings->content_history_path, settings->content_history_size); break; case EVENT_CMD_CORE_INFO_DEINIT: if (!global) break; if (global->core_info.list) core_info_list_free(global->core_info.list); global->core_info.list = NULL; break; case EVENT_CMD_DATA_RUNLOOP_FREE: rarch_main_data_free(); break; case EVENT_CMD_CORE_INFO_INIT: event_command(EVENT_CMD_CORE_INFO_DEINIT); if (*settings->libretro_directory) global->core_info.list = core_info_list_new(); break; case EVENT_CMD_CORE_DEINIT: { struct retro_hw_render_callback *cb = video_driver_callback(); event_deinit_core(true); if (cb) memset(cb, 0, sizeof(*cb)); break; } case EVENT_CMD_CORE_INIT: if (!event_init_core()) return false; break; case EVENT_CMD_VIDEO_APPLY_STATE_CHANGES: video_driver_apply_state_changes(); break; case EVENT_CMD_VIDEO_SET_NONBLOCKING_STATE: boolean = true; /* fall-through */ case EVENT_CMD_VIDEO_SET_BLOCKING_STATE: video_driver_set_nonblock_state(boolean); break; case EVENT_CMD_VIDEO_SET_ASPECT_RATIO: video_driver_set_aspect_ratio(settings->video.aspect_ratio_idx); break; case EVENT_CMD_AUDIO_SET_NONBLOCKING_STATE: boolean = true; /* fall-through */ case EVENT_CMD_AUDIO_SET_BLOCKING_STATE: audio_driver_set_nonblock_state(boolean); break; case EVENT_CMD_OVERLAY_SET_SCALE_FACTOR: #ifdef HAVE_OVERLAY input_overlay_set_scale_factor(settings->input.overlay_scale); #endif break; case EVENT_CMD_OVERLAY_SET_ALPHA_MOD: #ifdef HAVE_OVERLAY input_overlay_set_alpha_mod(settings->input.overlay_opacity); #endif break; case EVENT_CMD_DRIVERS_DEINIT: uninit_drivers(DRIVERS_CMD_ALL); break; case EVENT_CMD_DRIVERS_INIT: init_drivers(DRIVERS_CMD_ALL); break; case EVENT_CMD_AUDIO_REINIT: uninit_drivers(DRIVER_AUDIO); init_drivers(DRIVER_AUDIO); break; case EVENT_CMD_RESET_CONTEXT: event_command(EVENT_CMD_DRIVERS_DEINIT); event_command(EVENT_CMD_DRIVERS_INIT); break; case EVENT_CMD_QUIT_RETROARCH: rarch_ctl(RARCH_ACTION_STATE_FORCE_QUIT, NULL); break; case EVENT_CMD_RESUME: rarch_ctl(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED, NULL); break; case EVENT_CMD_RESTART_RETROARCH: #if defined(GEKKO) && defined(HW_RVL) fill_pathname_join(global->path.fullpath, g_defaults.dir.core, SALAMANDER_FILE, sizeof(global->path.fullpath)); #endif if (driver->frontend_ctx && driver->frontend_ctx->set_fork) driver->frontend_ctx->set_fork(true, false); break; case EVENT_CMD_MENU_SAVE_CONFIG: if (!event_save_core_config()) return false; break; case EVENT_CMD_SHADERS_APPLY_CHANGES: #ifdef HAVE_MENU menu_shader_manager_apply_changes(); #endif break; case EVENT_CMD_PAUSE_CHECKS: rarch_main_ctl(RARCH_MAIN_CTL_IS_PAUSED, &boolean); if (boolean) { RARCH_LOG("%s\n", msg_hash_to_str(MSG_PAUSED)); event_command(EVENT_CMD_AUDIO_STOP); if (settings->video.black_frame_insertion) video_driver_cached_frame(); } else { RARCH_LOG("%s\n", msg_hash_to_str(MSG_UNPAUSED)); event_command(EVENT_CMD_AUDIO_START); } break; case EVENT_CMD_PAUSE_TOGGLE: rarch_main_ctl(RARCH_MAIN_CTL_IS_PAUSED, &boolean); boolean = !boolean; rarch_main_ctl(RARCH_MAIN_CTL_SET_PAUSED, &boolean); event_command(EVENT_CMD_PAUSE_CHECKS); break; case EVENT_CMD_UNPAUSE: boolean = false; rarch_main_ctl(RARCH_MAIN_CTL_SET_PAUSED, &boolean); event_command(EVENT_CMD_PAUSE_CHECKS); break; case EVENT_CMD_PAUSE: boolean = true; rarch_main_ctl(RARCH_MAIN_CTL_SET_PAUSED, &boolean); event_command(EVENT_CMD_PAUSE_CHECKS); break; case EVENT_CMD_MENU_PAUSE_LIBRETRO: #ifdef HAVE_MENU if (menu_driver_alive()) { if (settings->menu.pause_libretro) event_command(EVENT_CMD_AUDIO_STOP); else event_command(EVENT_CMD_AUDIO_START); } else { if (settings->menu.pause_libretro) event_command(EVENT_CMD_AUDIO_START); } #endif break; case EVENT_CMD_SHADER_DIR_DEINIT: if (!global) break; dir_list_free(global->shader_dir.list); global->shader_dir.list = NULL; global->shader_dir.ptr = 0; break; case EVENT_CMD_SHADER_DIR_INIT: event_command(EVENT_CMD_SHADER_DIR_DEINIT); if (!*settings->video.shader_dir) return false; global->shader_dir.list = dir_list_new_special(NULL, DIR_LIST_SHADERS); if (!global->shader_dir.list || global->shader_dir.list->size == 0) { event_command(EVENT_CMD_SHADER_DIR_DEINIT); return false; } global->shader_dir.ptr = 0; dir_list_sort(global->shader_dir.list, false); for (i = 0; i < global->shader_dir.list->size; i++) RARCH_LOG("%s \"%s\"\n", msg_hash_to_str(MSG_FOUND_SHADER), global->shader_dir.list->elems[i].data); break; case EVENT_CMD_SAVEFILES: event_save_files(); break; case EVENT_CMD_SAVEFILES_DEINIT: if (!global) break; if (global->savefiles) string_list_free(global->savefiles); global->savefiles = NULL; break; case EVENT_CMD_SAVEFILES_INIT: global->sram.use = global->sram.use && !global->sram.save_disable #ifdef HAVE_NETPLAY && (!driver->netplay_data || !global->netplay.is_client) #endif ; if (!global->sram.use) RARCH_LOG("%s\n", msg_hash_to_str(MSG_SRAM_WILL_NOT_BE_SAVED)); if (global->sram.use) event_command(EVENT_CMD_AUTOSAVE_INIT); break; case EVENT_CMD_MSG_QUEUE_DEINIT: rarch_main_msg_queue_free(); break; case EVENT_CMD_MSG_QUEUE_INIT: event_command(EVENT_CMD_MSG_QUEUE_DEINIT); rarch_main_msg_queue_init(); rarch_main_data_init_queues(); break; case EVENT_CMD_BSV_MOVIE_DEINIT: if (!global) break; if (global->bsv.movie) bsv_movie_free(global->bsv.movie); global->bsv.movie = NULL; break; case EVENT_CMD_BSV_MOVIE_INIT: event_command(EVENT_CMD_BSV_MOVIE_DEINIT); event_init_movie(); break; case EVENT_CMD_NETPLAY_DEINIT: #ifdef HAVE_NETPLAY deinit_netplay(); #endif break; case EVENT_CMD_NETWORK_DEINIT: #ifdef HAVE_NETWORKING network_deinit(); #endif break; case EVENT_CMD_NETWORK_INIT: #ifdef HAVE_NETWORKING network_init(); #endif break; case EVENT_CMD_NETPLAY_INIT: event_command(EVENT_CMD_NETPLAY_DEINIT); #ifdef HAVE_NETPLAY if (!init_netplay()) return false; #endif break; case EVENT_CMD_NETPLAY_FLIP_PLAYERS: #ifdef HAVE_NETPLAY { netplay_t *netplay = (netplay_t*)driver->netplay_data; if (!netplay) return false; netplay_flip_users(netplay); } #endif break; case EVENT_CMD_FULLSCREEN_TOGGLE: if (!video_driver_has_windowed()) return false; /* If we go fullscreen we drop all drivers and * reinitialize to be safe. */ settings->video.fullscreen = !settings->video.fullscreen; event_command(EVENT_CMD_REINIT); break; case EVENT_CMD_COMMAND_DEINIT: #ifdef HAVE_COMMAND if (driver->command) rarch_cmd_free(driver->command); driver->command = NULL; #endif break; case EVENT_CMD_COMMAND_INIT: event_command(EVENT_CMD_COMMAND_DEINIT); #ifdef HAVE_COMMAND event_init_command(); #endif break; case EVENT_CMD_TEMPORARY_CONTENT_DEINIT: if (!global) break; if (global->temporary_content) event_free_temporary_content(); global->temporary_content = NULL; break; case EVENT_CMD_SUBSYSTEM_FULLPATHS_DEINIT: if (!global) break; if (global->subsystem_fullpaths) string_list_free(global->subsystem_fullpaths); global->subsystem_fullpaths = NULL; break; case EVENT_CMD_LOG_FILE_DEINIT: if (!global) break; if (global->log_file && global->log_file != stderr) fclose(global->log_file); global->log_file = NULL; break; case EVENT_CMD_DISK_EJECT_TOGGLE: if (system && system->disk_control.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &system->disk_control; if (control) event_check_disk_eject(control); } else rarch_main_msg_queue_push_new( MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS, 1, 120, true); break; case EVENT_CMD_DISK_NEXT: if (system && system->disk_control.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &system->disk_control; if (!control) return false; if (!control->get_eject_state()) return false; event_check_disk_next(control); } else rarch_main_msg_queue_push_new( MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS, 1, 120, true); break; case EVENT_CMD_DISK_PREV: if (system && system->disk_control.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &system->disk_control; if (!control) return false; if (!control->get_eject_state()) return false; event_check_disk_prev(control); } else rarch_main_msg_queue_push_new( MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS, 1, 120, true); break; case EVENT_CMD_RUMBLE_STOP: for (i = 0; i < MAX_USERS; i++) { input_driver_set_rumble_state(i, RETRO_RUMBLE_STRONG, 0); input_driver_set_rumble_state(i, RETRO_RUMBLE_WEAK, 0); } break; case EVENT_CMD_GRAB_MOUSE_TOGGLE: { static bool grab_mouse_state = false; grab_mouse_state = !grab_mouse_state; if (!driver->input || !input_driver_grab_mouse(grab_mouse_state)) return false; RARCH_LOG("%s: %s.\n", msg_hash_to_str(MSG_GRAB_MOUSE_STATE), grab_mouse_state ? "yes" : "no"); video_driver_show_mouse(!grab_mouse_state); } break; case EVENT_CMD_PERFCNT_REPORT_FRONTEND_LOG: rarch_perf_log(); break; case EVENT_CMD_VOLUME_UP: event_set_volume(0.5f); break; case EVENT_CMD_VOLUME_DOWN: event_set_volume(-0.5f); break; case EVENT_CMD_SET_FRAME_LIMIT: rarch_main_ctl(RARCH_MAIN_CTL_SET_FRAME_LIMIT_LAST_TIME, NULL); break; case EVENT_CMD_NONE: default: return false; } return true; }
static int menu_input_mouse_post_iterate(uint64_t *input_mouse, menu_file_list_cbs_t *cbs, unsigned action) { size_t selection; unsigned header_height; settings_t *settings = config_get_ptr(); menu_input_t *menu_input = menu_input_get_ptr(); *input_mouse = MOUSE_ACTION_NONE; menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection); if (!settings->menu.mouse.enable #ifdef HAVE_OVERLAY || (settings->input.overlay_enable && input_overlay_is_alive()) #endif ) { menu_input->mouse.wheeldown = false; menu_input->mouse.wheelup = false; menu_input->mouse.oldleft = false; menu_input->mouse.oldright = false; return 0; } if (menu_input_mouse_state(MENU_MOUSE_LEFT_BUTTON)) { if (!menu_input->mouse.oldleft) { menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L); menu_input->mouse.oldleft = true; if ((unsigned)menu_input->mouse.y < header_height) { menu_entries_pop_stack(&selection, 0); menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection); return 0; } if ((menu_input->mouse.ptr == selection) && cbs && cbs->action_select) { BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_TOGGLE); } else if (menu_input->mouse.ptr <= (menu_entries_get_size() - 1)) { BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_L_SET_NAVIGATION); } } } else menu_input->mouse.oldleft = false; if (menu_input_mouse_state(MENU_MOUSE_RIGHT_BUTTON)) { if (!menu_input->mouse.oldright) { menu_input->mouse.oldright = true; BIT64_SET(*input_mouse, MOUSE_ACTION_BUTTON_R); } } else menu_input->mouse.oldright = false; if (menu_input->mouse.wheeldown) { BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_DOWN); } if (menu_input->mouse.wheelup) { BIT64_SET(*input_mouse, MOUSE_ACTION_WHEEL_UP); } return 0; }
/** * menu_iterate: * @input : input sample for this frame * @old_input : input sample of the previous frame * @trigger_input : difference' input sample - difference * between 'input' and 'old_input' * * Runs RetroArch menu for one frame. * * Returns: 0 on success, -1 if we need to quit out of the loop. **/ int generic_menu_iterate(enum menu_action action) { size_t selection; menu_entry_t entry; enum action_iterate_type iterate_type; const char *label = NULL; int ret = 0; uint32_t label_hash = 0; uint32_t hash = 0; menu_handle_t *menu = menu_driver_get_ptr(); file_list_t *menu_stack = menu_entries_get_menu_stack_ptr(); file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(); menu_entries_get_last_stack(NULL, &label, NULL, NULL); if (!menu) return 0; if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return 0; menu->menu_state.msg[0] = '\0'; hash = menu_hash_calculate(label); iterate_type = action_iterate_type(hash); if (action != MENU_ACTION_NOOP || menu_entries_needs_refresh() || menu_display_ctl(MENU_DISPLAY_CTL_UPDATE_PENDING, NULL)) { BIT64_SET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER); } switch (iterate_type) { case ITERATE_TYPE_HELP: ret = action_iterate_help(menu->menu_state.msg, sizeof(menu->menu_state.msg), label); BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX); BIT64_SET(menu->state, MENU_STATE_POST_ITERATE); if (ret == 1 || action == MENU_ACTION_OK) BIT64_SET(menu->state, MENU_STATE_POP_STACK); break; case ITERATE_TYPE_BIND: if (menu_input_key_bind_iterate(menu->menu_state.msg, sizeof(menu->menu_state.msg))) { menu_entries_pop_stack(&selection); menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection); } else BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX); break; case ITERATE_TYPE_INFO: { menu_file_list_cbs_t *cbs = menu_entries_get_actiondata_at_offset(selection_buf, selection); rarch_setting_t *setting = cbs->setting; if (setting) { char needle[PATH_MAX_LENGTH]; strlcpy(needle, menu_setting_get_name(setting), sizeof(needle)); label_hash = menu_hash_calculate(needle); } ret = menu_hash_get_help(label_hash, menu->menu_state.msg, sizeof(menu->menu_state.msg)); } BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX); BIT64_SET(menu->state, MENU_STATE_POST_ITERATE); if (action == MENU_ACTION_OK) BIT64_SET(menu->state, MENU_STATE_POP_STACK); break; case ITERATE_TYPE_DEFAULT: /* FIXME: Crappy hack, needed for mouse controls to not be completely broken * in case we press back. * * We need to fix this entire mess, mouse controls should not rely on a * hack like this in order to work. */ selection = max(min(selection, (menu_entries_get_size() - 1)), 0); menu_entry_get(&entry, selection, NULL, false); ret = menu_entry_action(&entry, selection, (enum menu_action)action); if (ret) goto end; BIT64_SET(menu->state, MENU_STATE_POST_ITERATE); /* Have to defer it so we let settings refresh. */ if (menu->push_help_screen) { menu_displaylist_info_t info = {0}; info.list = menu_stack; strlcpy(info.label, menu_hash_to_str(MENU_LABEL_HELP), sizeof(info.label)); menu_displaylist_push_list(&info, DISPLAYLIST_HELP); } break; } BIT64_SET(menu->state, MENU_STATE_BLIT); if (BIT64_GET(menu->state, MENU_STATE_POP_STACK)) { size_t new_selection_ptr = selection; menu_entries_pop_stack(&new_selection_ptr); menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection); } if (BIT64_GET(menu->state, MENU_STATE_POST_ITERATE)) menu_input_post_iterate(&ret, action); end: if (ret) return -1; return 0; }
static void mui_frame(void *data) { unsigned header_height; bool display_kb; float black_bg[16] = { 0, 0, 0, 0.75, 0, 0, 0, 0.75, 0, 0, 0, 0.75, 0, 0, 0, 0.75, }; float blue_bg[16] = { 0.13, 0.59, 0.95, 1, 0.13, 0.59, 0.95, 1, 0.13, 0.59, 0.95, 1, 0.13, 0.59, 0.95, 1, }; float lightblue_bg[16] = { 0.89, 0.95, 0.99, 1.00, 0.89, 0.95, 0.99, 1.00, 0.89, 0.95, 0.99, 1.00, 0.89, 0.95, 0.99, 1.00, }; float pure_white[16]= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, }; float white_bg[16]= { 0.98, 0.98, 0.98, 1, 0.98, 0.98, 0.98, 1, 0.98, 0.98, 0.98, 1, 0.98, 0.98, 0.98, 1, }; float white_transp_bg[16]= { 0.98, 0.98, 0.98, 0.90, 0.98, 0.98, 0.98, 0.90, 0.98, 0.98, 0.98, 0.90, 0.98, 0.98, 0.98, 0.90, }; float grey_bg[16]= { 0.78, 0.78, 0.78, 1, 0.78, 0.78, 0.78, 1, 0.78, 0.78, 0.78, 1, 0.78, 0.78, 0.78, 1, }; float shadow_bg[16]= { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.2, 0, 0, 0, 0.2, }; unsigned width, height, ticker_limit, i; char msg[256]; char title[256]; char title_buf[256]; char title_msg[256]; size_t selection; size_t title_margin; uint64_t *frame_count; mui_handle_t *mui = (mui_handle_t*)data; settings_t *settings = config_get_ptr(); const uint32_t normal_color = 0x212121ff; const uint32_t hover_color = 0x212121ff; const uint32_t title_color = 0xffffffff; const uint32_t activetab_color = 0x0096f2ff; const uint32_t passivetab_color = 0x9e9e9eff; bool background_rendered = false; bool libretro_running = menu_display_ctl(MENU_DISPLAY_CTL_LIBRETRO_RUNNING, NULL); video_driver_ctl(RARCH_DISPLAY_CTL_GET_FRAME_COUNT, &frame_count); (void)passivetab_color; (void)activetab_color; if (!mui) return; msg[0] = '\0'; title[0] = '\0'; title_buf[0] = '\0'; title_msg[0] = '\0'; video_driver_get_size(&width, &height); menu_display_ctl(MENU_DISPLAY_CTL_SET_VIEWPORT, NULL); menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); if (libretro_running) { menu_display_draw_bg( width, height, mui->textures.white, 0.75f, false, &white_transp_bg[0], &white_bg[0], NULL, NULL, 4, MENU_DISPLAY_PRIM_TRIANGLESTRIP); } else { menu_display_clear_color(1.0f, 1.0f, 1.0f, 0.75f); if (mui->textures.bg.id) { background_rendered = true; /* Set new opacity for transposed white background */ bgcolor_setalpha(white_transp_bg, 0.30); menu_display_draw_bg( width, height, mui->textures.bg.id, 0.75f, true, &white_transp_bg[0], &white_bg[0], NULL, NULL, 4, MENU_DISPLAY_PRIM_TRIANGLESTRIP); /* Restore opacity of transposed white background */ bgcolor_setalpha(white_transp_bg, 0.90); } } menu_entries_get_title(title, sizeof(title)); if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return; if (background_rendered || libretro_running) bgcolor_setalpha(lightblue_bg, 0.75); else bgcolor_setalpha(lightblue_bg, 1.0); /* highlighted entry */ mui_render_quad(mui, 0, header_height - mui->scroll_y + mui->line_height * selection, width, mui->line_height, width, height, &lightblue_bg[0]); menu_display_font_bind_block(&mui->list_block); mui_render_menu_list(mui, width, height, normal_color, hover_color, &pure_white[0]); menu_display_ctl(MENU_DISPLAY_CTL_FONT_FLUSH_BLOCK, NULL); menu_animation_ctl(MENU_ANIMATION_CTL_SET_ACTIVE, NULL); /* header */ mui_render_quad(mui, 0, 0, width, header_height, width, height, &blue_bg[0]); mui->tabs_height = 0; /* display tabs if depth equal one, if not hide them */ if (mui_list_get_size(mui, MENU_LIST_PLAIN) == 1) { mui_draw_tab_begin(mui, width, height, &white_bg[0], &grey_bg[0]); for (i = 0; i <= MUI_SYSTEM_TAB_END; i++) mui_draw_tab(mui, i, width, height, &pure_white[0]); mui_draw_tab_end(mui, width, height, header_height, &blue_bg[0]); } mui_render_quad(mui, 0, header_height, width, mui->shadow_height, width, height, &shadow_bg[0]); title_margin = mui->margin; if (menu_entries_ctl(MENU_ENTRIES_CTL_SHOW_BACK, NULL)) { title_margin = mui->icon_size; mui_draw_icon(mui, mui->textures.list[MUI_TEXTURE_BACK].id, 0, 0, width, height, 0, 1, &pure_white[0]); } ticker_limit = (width - mui->margin*2) / mui->glyph_width; menu_animation_ticker_str(title_buf, ticker_limit, *frame_count / 100, title, true); /* Title */ if (mui_get_core_title(title_msg, sizeof(title_msg)) == 0) { char title_buf_msg_tmp[256]; char title_buf_msg[256]; size_t usable_width = width - (mui->margin * 2); int ticker_limit, value_len; snprintf(title_buf_msg, sizeof(title_buf), "%s (%s)", title_buf, title_msg); value_len = strlen(title_buf); ticker_limit = (usable_width / mui->glyph_width) - (value_len + 2); menu_animation_ticker_str(title_buf_msg_tmp, ticker_limit, *frame_count / 20, title_buf_msg, true); strlcpy(title_buf, title_buf_msg_tmp, sizeof(title_buf)); } mui_blit_line(title_margin, header_height / 2, width, height, title_buf, title_color, TEXT_ALIGN_LEFT); mui_draw_scrollbar(mui, width, height, &grey_bg[0]); menu_input_ctl(MENU_INPUT_CTL_KEYBOARD_DISPLAY, &display_kb); if (display_kb) { const char *str = NULL, *label = NULL; menu_input_ctl(MENU_INPUT_CTL_KEYBOARD_BUFF_PTR, &str); menu_input_ctl(MENU_INPUT_CTL_KEYBOARD_LABEL, &label); if (!str) str = ""; mui_render_quad(mui, 0, 0, width, height, width, height, &black_bg[0]); snprintf(msg, sizeof(msg), "%s\n%s", label, str); mui_render_messagebox(msg); } if (!string_is_empty(mui->box_message)) { mui_render_quad(mui, 0, 0, width, height, width, height, &black_bg[0]); mui_render_messagebox(mui->box_message); mui->box_message[0] = '\0'; } if (settings->menu.mouse.enable && (settings->video.fullscreen || !video_driver_ctl(RARCH_DISPLAY_CTL_HAS_WINDOWED, NULL))) { int16_t mouse_x = menu_input_mouse_state(MENU_MOUSE_X_AXIS); int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS); mui_draw_cursor(mui, &white_bg[0], mouse_x, mouse_y, width, height); } menu_display_restore_clear_color(); menu_display_ctl(MENU_DISPLAY_CTL_UNSET_VIEWPORT, NULL); }
static void rmenu_xui_render(void) { bool display_kb, msg_force; unsigned fb_width; size_t end, i, selection; char title[PATH_MAX_LENGTH] = {0}; const char *dir = NULL; const char *label = NULL; unsigned menu_type = 0; menu_handle_t *menu = menu_driver_get_ptr(); uint64_t frame_count = video_driver_get_frame_count(); menu_display_ctl(MENU_DISPLAY_CTL_WIDTH, &fb_width); menu_display_ctl(MENU_DISPLAY_CTL_MSG_FORCE, &msg_force); if (!menu) return; if ( menu_entries_needs_refresh() && menu_driver_alive() && !msg_force ) return; menu_display_fb_unset_dirty(); menu_animation_clear_active(); rmenu_xui_render_background(); if (XuiHandleIsValid(m_menutitle)) { menu_entries_get_title(title, sizeof(title)); mbstowcs(strw_buffer, title, sizeof(strw_buffer) / sizeof(wchar_t)); XuiTextElementSetText(m_menutitle, strw_buffer); menu_animation_ticker_str(title, RXUI_TERM_WIDTH(fb_width) - 3, (unsigned int)frame_count / 15, title, true); } if (XuiHandleIsValid(m_menutitle)) { if (menu_entries_get_core_title(title, sizeof(title)) == 0) { mbstowcs(strw_buffer, title, sizeof(strw_buffer) / sizeof(wchar_t)); XuiTextElementSetText(m_menutitlebottom, strw_buffer); } } end = menu_entries_get_end(); for (i = 0; i < end; i++) { char entry_path[PATH_MAX_LENGTH] = {0}; char entry_value[PATH_MAX_LENGTH] = {0}; char msg_right[PATH_MAX_LENGTH] = {0}; wchar_t msg_left[PATH_MAX_LENGTH] = {0}; menu_entry_get_value(i, entry_value, sizeof(entry_value)); menu_entry_get_path(i, entry_path, sizeof(entry_path)); mbstowcs(msg_left, entry_path, sizeof(msg_left) / sizeof(wchar_t)); mbstowcs(msg_right, entry_value, sizeof(msg_right) / sizeof(wchar_t)); rmenu_xui_set_list_text(i, msg_left, msg_right); } if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return; XuiListSetCurSelVisible(m_menulist, selection); menu_input_ctl(MENU_INPUT_CTL_KEYBOARD_DISPLAY, &display_kb); if (display_kb) { char msg[1024] = {0}; const char *str = NULL, *label = NULL; menu_input_ctl(MENU_INPUT_CTL_KEYBOARD_BUFF_PTR, &str); menu_input_ctl(MENU_INPUT_CTL_KEYBOARD_LABEL, &label); if (!str) str = ""; snprintf(msg, sizeof(msg), "%s\n%s", menu->keyboard.label, str); rmenu_xui_render_messagebox(msg); } }