From d28cb947176d419e36b8a6ba29d5930e59ed2b55 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Wed, 27 Feb 2013 20:20:29 -0500 Subject: [PATCH] start of RGUI port to Android currently detects menu button to bring up RGUI, but GL does not draw it yet and you cannot exit from the (invisible) RGUI menu yet --- android/native/jni/input_android.c | 9 +- android/native/jni/input_autodetect.c | 5 + console/griffin/griffin.c | 5 +- console/griffin/hook_context.h | 1 + frontend/frontend_android.c | 29 +++- frontend/menu/rgui.c | 56 +++++-- frontend/menu/rmenu_generic.c | 218 ++++++++++++++++++++++++++ gfx/gl.c | 73 ++++++++- gfx/gl_common.h | 5 + gfx/thread_wrapper.c | 18 +++ 10 files changed, 393 insertions(+), 26 deletions(-) create mode 100644 frontend/menu/rmenu_generic.c diff --git a/android/native/jni/input_android.c b/android/native/jni/input_android.c index 9cd31572da..11b1766983 100644 --- a/android/native/jni/input_android.c +++ b/android/native/jni/input_android.c @@ -90,7 +90,7 @@ static void android_input_poll(void *data) struct android_app* android_app = (struct android_app*)g_android; uint64_t *lifecycle_state = &g_extern.lifecycle_state; - *lifecycle_state &= ~((1ULL << RARCH_RESET) | (1ULL << RARCH_REWIND) | (1ULL << RARCH_FAST_FORWARD_KEY) | (1ULL << RARCH_FAST_FORWARD_HOLD_KEY) | (1ULL << RARCH_MUTE) | (1ULL << RARCH_SAVE_STATE_KEY) | (1ULL << RARCH_LOAD_STATE_KEY) | (1ULL << RARCH_STATE_SLOT_PLUS) | (1ULL << RARCH_STATE_SLOT_MINUS)); + *lifecycle_state &= ~((1ULL << RARCH_RESET) | (1ULL << RARCH_REWIND) | (1ULL << RARCH_FAST_FORWARD_KEY) | (1ULL << RARCH_FAST_FORWARD_HOLD_KEY) | (1ULL << RARCH_MUTE) | (1ULL << RARCH_SAVE_STATE_KEY) | (1ULL << RARCH_LOAD_STATE_KEY) | (1ULL << RARCH_STATE_SLOT_PLUS) | (1ULL << RARCH_STATE_SLOT_MINUS) | (1ULL << RARCH_QUIT_KEY)); // Read all pending events. while (AInputQueue_hasEvents(android_app->inputQueue) > 0) @@ -254,6 +254,11 @@ static void android_input_poll(void *data) } #endif + if (!(g_extern.frame_count < g_extern.delay_timer[0]) && g_extern.lifecycle_state & (1ULL << RARCH_RMENU_TOGGLE)) + { + g_extern.lifecycle_state |= (1ULL << RARCH_QUIT_KEY); + } + RARCH_PERFORMANCE_STOP(input_poll); } @@ -262,7 +267,7 @@ static int16_t android_input_state(void *data, const struct retro_keybind **bind switch (device) { case RETRO_DEVICE_JOYPAD: - return ((state[port] & binds[port][id].joykey) && (port < pads_connected)); + return ((port < pads_connected) && (state[port] & binds[port][id].joykey)); case RETRO_DEVICE_POINTER: switch(id) { diff --git a/android/native/jni/input_autodetect.c b/android/native/jni/input_autodetect.c index d61a9066c5..a762eb7fb6 100644 --- a/android/native/jni/input_autodetect.c +++ b/android/native/jni/input_autodetect.c @@ -142,6 +142,11 @@ void input_autodetect_setup (void *data, char *msg, size_t sizeof_msg, unsigned } } + if (port == 0) + { + keycode_lut[AKEYCODE_MENU] |= ((RARCH_RMENU_TOGGLE + 1) << shift); + } + if (g_settings.input.autodetect_enable) { diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index a00bf3d3cd..6f3a8ad783 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -33,8 +33,6 @@ CONSOLE EXTENSIONS ============================================================ */ #ifdef RARCH_CONSOLE -#include "../rarch_console_video.c" - #ifdef HW_DOL #include "../../ngc/ssaram.c" #endif @@ -440,12 +438,15 @@ MENU #endif #ifdef HAVE_RMENU +#include "../rarch_console_video.c" #include "../../frontend/menu/rmenu_settings.c" #if defined(_XBOX360) #include "../../frontend/menu/rmenu_xui.cpp" #elif defined(GEKKO) #include "../../frontend/menu/rmenu_gx.c" +#elif defined(ANDROID) +#include "../../frontend/menu/rmenu_generic.c" #endif #endif diff --git a/console/griffin/hook_context.h b/console/griffin/hook_context.h index 3184a420df..f638edba24 100644 --- a/console/griffin/hook_context.h +++ b/console/griffin/hook_context.h @@ -42,6 +42,7 @@ #ifdef HAVE_RMENU #define context_rmenu_init_func() gl->ctx_driver->rmenu_init() #define context_rmenu_frame_func(ctx) gl->ctx_driver->rmenu_frame(ctx) +#define context_rmenu_free_func() gl->ctx_driver->rmenu_free() #endif #ifdef HAVE_EGL diff --git a/frontend/frontend_android.c b/frontend/frontend_android.c index cee92d11dc..a7213e9749 100644 --- a/frontend/frontend_android.c +++ b/frontend/frontend_android.c @@ -25,6 +25,7 @@ #include "../general.h" #include "../performance.h" #include "../driver.h" +#include "menu/rmenu.h" #include "../config.def.h" @@ -347,21 +348,43 @@ static void *android_app_entry(void *data) if (!android_app_start_main(android_app, &init_ret)) goto exit; - if (g_extern.main_is_init) + menu_init(); + + g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME); +begin_loop: + if(g_extern.lifecycle_mode_state & (1ULL << MODE_GAME)) { - RARCH_LOG("RetroArch started.\n"); + driver.input->poll(NULL); + driver.video->set_aspect_ratio(driver.video_data, g_settings.video.aspect_ratio_idx); + + if (g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_THROTTLE_ENABLE)) + audio_start_func(); while ((input_key_pressed_func(RARCH_PAUSE_TOGGLE)) ? android_run_events(android_app) : rarch_main_iterate()); - RARCH_LOG("RetroArch stopped.\n"); + if (g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_THROTTLE_ENABLE)) + audio_stop_func(); + g_extern.lifecycle_mode_state &= ~(1ULL << MODE_GAME); } + else if(g_extern.lifecycle_mode_state & (1ULL << MODE_MENU)) + { + g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU_PREINIT); + while(rmenu_iterate()); + g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU); + } + else + goto exit; + + goto begin_loop; exit: android_app->activityState = APP_CMD_DEAD; RARCH_LOG("Deinitializing RetroArch...\n"); + menu_free(); + if (g_extern.main_is_init) rarch_main_deinit(); diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c index ed035fa0d8..e7f315f2f5 100644 --- a/frontend/menu/rgui.c +++ b/frontend/menu/rgui.c @@ -116,6 +116,13 @@ unsigned rgui_gx_resolutions[GX_RESOLUTIONS_LAST][2] = { }; unsigned rgui_current_gx_resolution = GX_RESOLUTIONS_640_480; + +static const char *rgui_device_labels[] = { + "GameCube Controller", + "Wiimote", + "Wiimote + Nunchuk", + "Classic Controller", +}; #endif unsigned RGUI_WIDTH = 320; @@ -141,13 +148,6 @@ struct rgui_handle bool alloc_font; }; -static const char *rgui_device_labels[] = { - "GameCube Controller", - "Wiimote", - "Wiimote + Nunchuk", - "Classic Controller", -}; - static const unsigned rgui_controller_lut[] = { RETRO_DEVICE_ID_JOYPAD_UP, RETRO_DEVICE_ID_JOYPAD_DOWN, @@ -177,7 +177,7 @@ static inline bool rgui_is_viewport_menu(rgui_file_type_t menu_type) return (menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT || menu_type == RGUI_SETTINGS_CUSTOM_VIEWPORT_2); } -static void copy_glyph(uint8_t *glyph, const uint8_t *buf) +static void rgui_copy_glyph(uint8_t *glyph, const uint8_t *buf) { for (int y = 0; y < FONT_HEIGHT; y++) { @@ -205,7 +205,7 @@ static void init_font(rgui_handle_t *rgui, const uint8_t *font_bmp_buf) { unsigned y = i / 16; unsigned x = i % 16; - copy_glyph(&font[FONT_OFFSET(i)], + rgui_copy_glyph(&font[FONT_OFFSET(i)], font_bmp_buf + 54 + 3 * (256 * (255 - 16 * y) + 16 * x)); } @@ -227,7 +227,11 @@ rgui_handle_t *rgui_init(const char *base_path, rgui->path_stack = rgui_list_new(); rgui->folder_buf = rgui_list_new(); +#ifdef RARCH_CONSOLE rgui_list_push(rgui->path_stack, base_path, RGUI_FILE_DIRECTORY, 0); +#else + rgui_list_push(rgui->path_stack, base_path, RGUI_SETTINGS, 0); +#endif if (font_bmp_buf) init_font(rgui, font_bmp_buf); @@ -406,7 +410,9 @@ static void render_text(rgui_handle_t *rgui) char message[TERM_WIDTH + 1]; char type_str[TERM_WIDTH + 1]; int w = rgui_is_controller_menu(menu_type) ? 26 : 19; +#ifdef RARCH_CONSOLE unsigned port = menu_type - RGUI_SETTINGS_CONTROLLER_1; +#endif switch (type) { case RGUI_FILE_PLAIN: @@ -493,9 +499,12 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_CONTROLLER_4: snprintf(type_str, sizeof(type_str), "..."); break; +#ifdef GEKKO case RGUI_SETTINGS_BIND_DEVICE: snprintf(type_str, sizeof(type_str), "%s", rgui_device_labels[g_settings.input.device[port]]); break; +#endif +#ifdef RARCH_CONSOLE case RGUI_SETTINGS_BIND_DPAD_EMULATION: snprintf(type_str, sizeof(type_str), "%s", rarch_dpad_emulation_name_lut[g_settings.input.dpad_emulation[port]]); break; @@ -517,6 +526,7 @@ static void render_text(rgui_handle_t *rgui) case RGUI_SETTINGS_BIND_R3: snprintf(type_str, sizeof(type_str), "%s", rarch_input_find_platform_key_label(g_settings.input.binds[port][rgui_controller_lut[type - RGUI_SETTINGS_BIND_UP]].joykey)); break; +#endif default: type_str[0] = 0; w = 0; @@ -573,7 +583,9 @@ static void render_text(rgui_handle_t *rgui) static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t action, rgui_file_type_t menu_type) { - unsigned port = menu_type - RGUI_SETTINGS_CONTROLLER_1; +#ifdef RARCH_CONSOLE + unsigned port = menu_type - RGUI_SETTINGS_CONTROLLER_1; +#endif switch (setting) { @@ -625,9 +637,15 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t unsigned height = g_extern.frame_cache.height; int pitch = g_extern.frame_cache.pitch; +#ifdef RARCH_CONSOLE + const char *screenshot_dir = default_paths.port_dir; +#else + const char *screenshot_dir = g_settings.screenshot_directory; +#endif + // Negative pitch is needed as screenshot takes bottom-up, // but we use top-down. - bool r = screenshot_dump(default_paths.port_dir, + bool r = screenshot_dump(screenshot_dir, data + (height - 1) * (pitch >> 1), width, height, -pitch, false); @@ -838,6 +856,7 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t } break; // controllers +#ifdef GEKKO case RGUI_SETTINGS_BIND_DEVICE: g_settings.input.device[port] += RARCH_DEVICE_LAST; if (action == RGUI_ACTION_START) @@ -851,6 +870,8 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t rarch_input_set_default_keybinds(port); driver.input->set_analog_dpad_mapping(g_settings.input.device[port], g_settings.input.dpad_emulation[port], port); break; +#endif +#ifdef RARCH_CONSOLE case RGUI_SETTINGS_BIND_DPAD_EMULATION: g_settings.input.dpad_emulation[port] += DPAD_EMULATION_LAST; if (action == RGUI_ACTION_START) @@ -892,6 +913,7 @@ static int rgui_settings_toggle_setting(rgui_file_type_t setting, rgui_action_t rarch_input_set_keybind(port, keybind_action, rgui_controller_lut[setting - RGUI_SETTINGS_BIND_UP]); } +#endif default: break; } @@ -934,10 +956,12 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui) #ifdef HAVE_LIBRETRO_MANAGEMENT RGUI_MENU_ITEM("Core", RGUI_SETTINGS_CORE); #endif +#ifdef RARCH_CONSOLE RGUI_MENU_ITEM("Controller #1 Config", RGUI_SETTINGS_CONTROLLER_1); RGUI_MENU_ITEM("Controller #2 Config", RGUI_SETTINGS_CONTROLLER_2); RGUI_MENU_ITEM("Controller #3 Config", RGUI_SETTINGS_CONTROLLER_3); RGUI_MENU_ITEM("Controller #4 Config", RGUI_SETTINGS_CONTROLLER_4); +#endif RGUI_MENU_ITEM("Debug Text", RGUI_SETTINGS_DEBUG_TEXT); RGUI_MENU_ITEM("Restart RetroArch", RGUI_SETTINGS_RESTART_EMULATOR); RGUI_MENU_ITEM("Exit RetroArch", RGUI_SETTINGS_QUIT_EMULATOR); @@ -945,6 +969,7 @@ static void rgui_settings_populate_entries(rgui_handle_t *rgui) static void rgui_settings_controller_populate_entries(rgui_handle_t *rgui) { +#ifdef RARCH_CONSOLE rgui_list_clear(rgui->folder_buf); RGUI_MENU_ITEM("Device", RGUI_SETTINGS_BIND_DEVICE); @@ -965,10 +990,10 @@ static void rgui_settings_controller_populate_entries(rgui_handle_t *rgui) RGUI_MENU_ITEM("R2", RGUI_SETTINGS_BIND_R2); RGUI_MENU_ITEM("L3", RGUI_SETTINGS_BIND_L3); RGUI_MENU_ITEM("R3", RGUI_SETTINGS_BIND_R3); +#endif } - -int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action) +static int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action) { #ifdef GEKKO gx_video_t *gx = (gx_video_t*)driver.video_data; @@ -1088,12 +1113,13 @@ int rgui_viewport_iterate(rgui_handle_t *rgui, rgui_action_t action) return 0; } -int rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t action) +static int rgui_settings_iterate(rgui_handle_t *rgui, rgui_action_t action) { rgui->frame_buf_pitch = RGUI_WIDTH * 2; rgui_file_type_t type = 0; const char *label = 0; - rgui_list_at(rgui->folder_buf, rgui->directory_ptr, &label, &type, NULL); + if (action != RGUI_ACTION_REFRESH) + rgui_list_at(rgui->folder_buf, rgui->directory_ptr, &label, &type, NULL); #ifdef HAVE_LIBRETRO_MANAGEMENT if (type == RGUI_SETTINGS_CORE) label = default_paths.core_dir; diff --git a/frontend/menu/rmenu_generic.c b/frontend/menu/rmenu_generic.c new file mode 100644 index 0000000000..6950001143 --- /dev/null +++ b/frontend/menu/rmenu_generic.c @@ -0,0 +1,218 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2013 - Hans-Kristian Arntzen + * Copyright (C) 2011-2013 - Daniel De Matteis + * + * RetroArch is free software: you can redistribute it and/or modify it under the terms + * of the GNU General Public License as published by the Free Software Found- + * ation, either version 3 of the License, or (at your option) any later version. + * + * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with RetroArch. + * If not, see . + */ + +#include "rmenu.h" +#include "rgui.h" +#include "../../gfx/gl_common.h" + +#include "../../gfx/fonts/bitmap.h" + +static uint16_t menu_framebuf[400 * 240]; +static rgui_handle_t *rgui; + +static bool folder_cb(const char *directory, rgui_file_enum_cb_t file_cb, + void *userdata, void *ctx) +{ + struct string_list *ext_list = string_split(g_extern.system.valid_extensions, "|"); + + char _dir[PATH_MAX]; + snprintf(_dir, sizeof(_dir), "%s/", directory); + DIR *dir = opendir(_dir); + if (!dir) + return false; + + struct dirent *entry; + while ((entry = readdir(dir))) + { + char stat_path[PATH_MAX]; + const char *file_ext = path_get_extension(entry->d_name); + snprintf(stat_path, sizeof(stat_path), "%s/%s", directory, entry->d_name); + bool is_dir; + +#ifdef _DIRENT_HAVE_D_TYPE + is_dir = (entry->d_type == DT_DIR); + if (entry->d_type != DT_REG && !is_dir) + continue; +#else + struct stat st; + if (stat(stat_path, &st) < 0) + continue; + + is_dir = S_ISDIR(st.st_mode); + if (!S_ISREG(st.st_mode) && !is_dir) + continue; +#endif + + if (!is_dir && ext_list && !string_list_find_elem_prefix(ext_list, ".", file_ext)) + continue; + + file_cb(ctx, + entry->d_name, + is_dir ? RGUI_FILE_DIRECTORY : RGUI_FILE_PLAIN, 0); + } + + closedir(dir); + string_list_free(ext_list); + return true; +} + +/*============================================================ +RMENU API +============================================================ */ + +void menu_init(void) +{ + gl_t *gl = (gl_t*)driver.video_data; + + gl->menu_data = (uint32_t *) menu_framebuf; + + rgui = rgui_init("", + menu_framebuf, RGUI_WIDTH * sizeof(uint16_t), + NULL, bitmap_bin, folder_cb, NULL); + + rgui_iterate(rgui, RGUI_ACTION_REFRESH); +} + +void menu_free(void) +{ + rgui_free(rgui); +} + +static uint16_t trigger_state = 0; + +int rmenu_input_process(void *data, void *state) +{ + if (g_extern.lifecycle_mode_state & (1ULL << MODE_LOAD_GAME)) + { + if (g_extern.lifecycle_mode_state & (1ULL << MODE_INFO_DRAW)) + rmenu_settings_msg(S_MSG_LOADING_ROM, 100); + + if (g_extern.fullpath) + g_extern.lifecycle_mode_state |= (1ULL << MODE_INIT); + + g_extern.lifecycle_mode_state &= ~(1ULL << MODE_LOAD_GAME); + return -1; + } + + if (!(g_extern.frame_count < g_extern.delay_timer[0])) + { + bool return_to_game_enable = ((g_extern.lifecycle_mode_state & (1ULL << RARCH_RMENU_TOGGLE)) && g_extern.main_is_init); + + if (return_to_game_enable) + { + g_extern.lifecycle_mode_state |= (1ULL << MODE_GAME); + return -1; + } + } + + return 0; +} + +bool rmenu_iterate(void) +{ + static const struct retro_keybind *binds[] = { + g_settings.input.binds[0] + }; + + static uint16_t old_input_state = 0; + static bool initial_held = true; + static bool first_held = false; + + g_extern.lifecycle_mode_state |= (1ULL << MODE_MENU_DRAW); + driver.video->apply_state_changes(); + + g_extern.frame_count++; + + uint16_t input_state = 0; + + driver.input->poll(NULL); + + for (unsigned i = 0; i < 16; i++) + input_state |= driver.input->input_state(NULL, binds, 0, RETRO_DEVICE_JOYPAD, 0, i) ? (1ULL << i) : 0; + + trigger_state = input_state & ~old_input_state; + bool do_held = input_state & ((1ULL << RETRO_DEVICE_ID_JOYPAD_UP) | (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN) | (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT) | (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT)); + + if(do_held) + { + if(!first_held) + { + first_held = true; + g_extern.delay_timer[1] = g_extern.frame_count + (initial_held ? 15 : 7); + } + + if (!(g_extern.frame_count < g_extern.delay_timer[1])) + { + first_held = false; + trigger_state = input_state; //second input frame set as current frame + } + + initial_held = false; + } + else + { + first_held = false; + initial_held = true; + } + + old_input_state = input_state; + + rgui_action_t action = RGUI_ACTION_NOOP; + + // don't run anything first frame, only capture held inputs for old_input_state + if (trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_UP)) + action = RGUI_ACTION_UP; + else if (trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_DOWN)) + action = RGUI_ACTION_DOWN; + else if (trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_LEFT)) + action = RGUI_ACTION_LEFT; + else if (trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_RIGHT)) + action = RGUI_ACTION_RIGHT; + else if (trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_B)) + action = RGUI_ACTION_CANCEL; + else if (trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_A)) + action = RGUI_ACTION_OK; + else if (trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_START)) + action = RGUI_ACTION_START; + //else if (trigger_state & (1ULL << RETRO_DEVICE_ID_JOYPAD_SELECT)) + // action = RGUI_ACTION_SETTINGS; + + int input_entry_ret = 0; + int input_process_ret = 0; + + input_entry_ret = rgui_iterate(rgui, action); + + // draw last frame for loading messages + rarch_render_cached_frame(); + + input_process_ret = rmenu_input_process(NULL, NULL); + + if (input_entry_ret != 0 || input_process_ret != 0) + goto deinit; + + return true; + +deinit: + // set a timer delay so that we don't instantly switch back to the menu when + // press and holding QUIT in the emulation loop (lasts for 30 frame ticks) + if (!(g_extern.lifecycle_state & (1ULL << RARCH_FRAMEADVANCE))) + g_extern.delay_timer[0] = g_extern.frame_count + 30; + + g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU_DRAW); + g_extern.lifecycle_mode_state &= ~(1ULL << MODE_MENU_INGAME); + + return false; +} diff --git a/gfx/gl.c b/gfx/gl.c index 4748f12c53..004f77b955 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -49,6 +49,10 @@ #include "shader_common.h" +#ifdef HAVE_RMENU +#include "../console/rarch_console_video.h" +#endif + #ifdef __CELLOS_LV2__ #define FPS_COUNTER #endif @@ -57,6 +61,10 @@ #include "../frontend/frontend_android.h" #endif +#ifdef HAVE_RGUI +#include "../frontend/menu/rgui.h" +#endif + // Used for the last pass when rendering to the back buffer. const GLfloat vertexes_flipped[] = { 0, 1, @@ -668,14 +676,12 @@ void gl_init_fbo(void *data, unsigned width, unsigned height) void gl_set_projection(void *data, struct gl_ortho *ortho, bool allow_rotate) { gl_t *gl = (gl_t*)data; -#ifdef RARCH_CONSOLE if (g_extern.lifecycle_mode_state & (1ULL << MODE_VIDEO_OVERSCAN_ENABLE)) { ortho->left = -g_extern.console.screen.overscan_amount / 2; ortho->right = 1 + g_extern.console.screen.overscan_amount / 2; ortho->bottom = -g_extern.console.screen.overscan_amount / 2; } -#endif // Calculate projection. matrix_ortho(&gl->mvp_no_rot, ortho->left, ortho->right, @@ -715,7 +721,7 @@ void gl_set_viewport(void *data, unsigned width, unsigned height, bool force_ful float desired_aspect = g_settings.video.aspect_ratio; float delta; -#ifdef RARCH_CONSOLE +#ifdef HAVE_RGUI if (g_settings.video.aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { x = g_extern.console.screen.viewports.custom_vp.x; @@ -1070,6 +1076,10 @@ static void gl_init_textures(void *data, const video_info_t *video) glGenTextures(TEXTURES, gl->texture); +#ifdef RGUI + glGenTextures(1, &gl->rgui_texture); +#endif + for (unsigned i = 0; i < TEXTURES; i++) { glBindTexture(GL_TEXTURE_2D, gl->texture[i]); @@ -1178,6 +1188,11 @@ static void gl_init_textures(void *data, const video_info_t *video) #endif glGenTextures(TEXTURES, gl->texture); + +#ifdef RGUI + glGenTextures(1, &gl->rgui_texture); +#endif + for (unsigned i = 0; i < TEXTURES; i++) { glBindTexture(GL_TEXTURE_2D, gl->texture[i]); @@ -1237,6 +1252,39 @@ static void gl_pbo_async_readback(void *data) } #endif +#ifdef HAVE_RGUI + +static inline void gl_draw_rgui(void *data) +{ + static const GLfloat white_color_rgui[16] = { + 1.0f, 1.0f, 1.0f, 0.25f, + 1.0f, 1.0f, 1.0f, 0.25f, + 1.0f, 1.0f, 1.0f, 0.25f, + 1.0f, 1.0f, 1.0f, 0.25f, + }; + + gl_t *gl = (gl_t*)data; + + glBindTexture(GL_TEXTURE_2D, gl->rgui_texture); + + glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(RGUI_WIDTH * 2)); + // RGUI is always packed so pitch = width * bpp + glTexImage2D(GL_TEXTURE_2D, + 0, GL_RGB, RGUI_WIDTH, RGUI_HEIGHT, 0, GL_RGB, + GL_UNSIGNED_SHORT_5_6_5, gl->menu_data); + + gl_shader_use_func(gl, 0); + + glEnable(GL_BLEND); + gl->coords.color = white_color_rgui; + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDisable(GL_BLEND); + + gl->coords.color = white_color; +} + +#endif + static bool gl_frame(void *data, const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg) { RARCH_PERFORMANCE_INIT(frame_run); @@ -1310,6 +1358,14 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei gl_set_prev_texture(gl, &tex_info); +#ifdef HAVE_RGUI + if(lifecycle_mode_state & (1ULL << MODE_MENU_DRAW)) + { + RARCH_LOG("rgui draw\n"); + gl_draw_rgui(gl); + } +#endif + #ifdef FPS_COUNTER if (lifecycle_mode_state & (1ULL << MODE_FPS_DRAW)) { @@ -1337,7 +1393,7 @@ static bool gl_frame(void *data, const void *frame, unsigned width, unsigned hei RARCH_PERFORMANCE_STOP(frame_run); -#ifdef HAVE_RMENU +#if defined(HAVE_RMENU) && !defined(HAVE_RGUI) if (lifecycle_mode_state & (1ULL << MODE_MENU_DRAW)) context_rmenu_frame_func(gl); else @@ -1385,6 +1441,10 @@ static void gl_free(void *data) glDeleteTextures(TEXTURES, gl->texture); +#ifdef RGUI + glDeleteTextures(1, &gl->rgui_texture); +#endif + #ifdef HAVE_OVERLAY if (gl->tex_overlay) glDeleteTextures(1, &gl->tex_overlay); @@ -1507,6 +1567,10 @@ static inline void gl_reinit_textures(void *data, const video_info_t *video) glBindTexture(GL_TEXTURE_2D, 0); glDeleteTextures(TEXTURES, gl->texture); +#ifdef RGUI + glDeleteTextures(1, &gl->rgui_texture); +#endif + gl_init_textures(gl, video); gl_init_textures_data(gl); @@ -2041,6 +2105,7 @@ static void gl_set_aspect_ratio(void *data, unsigned aspectratio_index) g_settings.video.aspect_ratio = aspectratio_lut[g_settings.video.aspect_ratio_idx].value; g_settings.video.force_aspect = false; gl->keep_aspect = true; + gl->should_resize = true; } #endif diff --git a/gfx/gl_common.h b/gfx/gl_common.h index 2617f84d28..b7db8c3d59 100644 --- a/gfx/gl_common.h +++ b/gfx/gl_common.h @@ -301,6 +301,11 @@ typedef struct gl struct scaler_ctx pbo_readback_scaler; #endif +#ifdef HAVE_RGUI + GLuint rgui_texture; + uint32_t *menu_data; +#endif + } gl_t; // Windows ... <_< diff --git a/gfx/thread_wrapper.c b/gfx/thread_wrapper.c index 39d8397458..2f513eaa17 100644 --- a/gfx/thread_wrapper.c +++ b/gfx/thread_wrapper.c @@ -535,6 +535,17 @@ static void thread_get_overlay_interface(void *data, const video_overlay_interfa } #endif +#if defined(HAVE_RMENU) + +// all stubs for now, might not have to implement them unless we want to port this to consoles +static void thread_start(void) {} +static void thread_stop(void) {} +static void thread_restart(void) {} +static void thread_apply_state_changes(void) {} +static void thread_set_aspect_ratio(void *data, unsigned aspectratio_index) {} + +#endif + static const video_driver_t video_thread = { thread_init_never_call, // Should never be called directly. thread_frame, @@ -544,6 +555,13 @@ static const video_driver_t video_thread = { thread_set_shader, thread_free, "Thread wrapper", +#if defined(HAVE_RMENU) + thread_start, + thread_stop, + thread_restart, + thread_apply_state_changes, + thread_set_aspect_ratio, +#endif thread_set_rotation, thread_viewport_info, thread_read_viewport,