diff --git a/android/phoenix/res/xml/prefs.xml b/android/phoenix/res/xml/prefs.xml index d9a77dcbb3..7b1f2ba936 100644 --- a/android/phoenix/res/xml/prefs.xml +++ b/android/phoenix/res/xml/prefs.xml @@ -36,20 +36,20 @@ - + diff --git a/android/phoenix/src/org/retroarch/browser/RetroArch.java b/android/phoenix/src/org/retroarch/browser/RetroArch.java index f7cc6373f9..24b5d0ba77 100644 --- a/android/phoenix/src/org/retroarch/browser/RetroArch.java +++ b/android/phoenix/src/org/retroarch/browser/RetroArch.java @@ -365,7 +365,7 @@ public class RetroArch extends Activity implements config.setBoolean("audio_enable", prefs.getBoolean("audio_enable", true)); config.setBoolean("video_smooth", prefs.getBoolean("video_smooth", true)); config.setBoolean("video_allow_rotate", prefs.getBoolean("video_allow_rotate", true)); - config.setBoolean("savestate_auto_load", prefs.getBoolean("savestate_auto_load", false)); + config.setBoolean("savestate_auto_load", prefs.getBoolean("savestate_auto_load", true)); config.setBoolean("savestate_auto_save", prefs.getBoolean("savestate_auto_save", false)); config.setBoolean("rewind_enable", prefs.getBoolean("rewind_enable", false)); config.setBoolean("video_vsync", prefs.getBoolean("video_vsync", true)); diff --git a/gfx/context/glx_ctx.c b/gfx/context/glx_ctx.c index c181dcf8fa..b0141c1dd6 100644 --- a/gfx/context/glx_ctx.c +++ b/gfx/context/glx_ctx.c @@ -50,108 +50,6 @@ static bool g_is_double; static int (*g_pglSwapInterval)(int); -struct key_bind -{ - unsigned x; - enum retro_key sk; -}; - -static unsigned keysym_lut[RETROK_LAST]; - -static const struct key_bind lut_binds[] = { - { XK_Left, RETROK_LEFT }, - { XK_Right, RETROK_RIGHT }, - { XK_Up, RETROK_UP }, - { XK_Down, RETROK_DOWN }, - { XK_Return, RETROK_RETURN }, - { XK_Tab, RETROK_TAB }, - { XK_Insert, RETROK_INSERT }, - { XK_Home, RETROK_HOME }, - { XK_End, RETROK_END }, - { XK_Page_Up, RETROK_PAGEUP }, - { XK_Page_Down, RETROK_PAGEDOWN }, - { XK_Delete, RETROK_DELETE }, - { XK_Shift_R, RETROK_RSHIFT }, - { XK_Shift_L, RETROK_LSHIFT }, - { XK_Control_L, RETROK_LCTRL }, - { XK_Alt_L, RETROK_LALT }, - { XK_space, RETROK_SPACE }, - { XK_Escape, RETROK_ESCAPE }, - { XK_BackSpace, RETROK_BACKSPACE }, - { XK_KP_Enter, RETROK_KP_ENTER }, - { XK_KP_Add, RETROK_KP_PLUS }, - { XK_KP_Subtract, RETROK_KP_MINUS }, - { XK_KP_Multiply, RETROK_KP_MULTIPLY }, - { XK_KP_Divide, RETROK_KP_DIVIDE }, - { XK_grave, RETROK_BACKQUOTE }, - { XK_Pause, RETROK_PAUSE }, - { XK_KP_0, RETROK_KP0 }, - { XK_KP_1, RETROK_KP1 }, - { XK_KP_2, RETROK_KP2 }, - { XK_KP_3, RETROK_KP3 }, - { XK_KP_4, RETROK_KP4 }, - { XK_KP_5, RETROK_KP5 }, - { XK_KP_6, RETROK_KP6 }, - { XK_KP_7, RETROK_KP7 }, - { XK_KP_8, RETROK_KP8 }, - { XK_KP_9, RETROK_KP9 }, - { XK_0, RETROK_0 }, - { XK_1, RETROK_1 }, - { XK_2, RETROK_2 }, - { XK_3, RETROK_3 }, - { XK_4, RETROK_4 }, - { XK_5, RETROK_5 }, - { XK_6, RETROK_6 }, - { XK_7, RETROK_7 }, - { XK_8, RETROK_8 }, - { XK_9, RETROK_9 }, - { XK_F1, RETROK_F1 }, - { XK_F2, RETROK_F2 }, - { XK_F3, RETROK_F3 }, - { XK_F4, RETROK_F4 }, - { XK_F5, RETROK_F5 }, - { XK_F6, RETROK_F6 }, - { XK_F7, RETROK_F7 }, - { XK_F8, RETROK_F8 }, - { XK_F9, RETROK_F9 }, - { XK_F10, RETROK_F10 }, - { XK_F11, RETROK_F11 }, - { XK_F12, RETROK_F12 }, - { XK_a, RETROK_a }, - { XK_b, RETROK_b }, - { XK_c, RETROK_c }, - { XK_d, RETROK_d }, - { XK_e, RETROK_e }, - { XK_f, RETROK_f }, - { XK_g, RETROK_g }, - { XK_h, RETROK_h }, - { XK_i, RETROK_i }, - { XK_j, RETROK_j }, - { XK_k, RETROK_k }, - { XK_l, RETROK_l }, - { XK_m, RETROK_m }, - { XK_n, RETROK_n }, - { XK_o, RETROK_o }, - { XK_p, RETROK_p }, - { XK_q, RETROK_q }, - { XK_r, RETROK_r }, - { XK_s, RETROK_s }, - { XK_t, RETROK_t }, - { XK_u, RETROK_u }, - { XK_v, RETROK_v }, - { XK_w, RETROK_w }, - { XK_x, RETROK_x }, - { XK_y, RETROK_y }, - { XK_z, RETROK_z }, -}; - -static void init_lut(void) -{ - memset(keysym_lut, 0, sizeof(keysym_lut)); - for (unsigned i = 0; i < sizeof(lut_binds) / sizeof(lut_binds[0]); i++) - keysym_lut[lut_binds[i].sk] = lut_binds[i].x; -} - static void sighandler(int sig) { (void)sig; @@ -165,6 +63,13 @@ static Bool glx_wait_notify(Display *d, XEvent *e, char *arg) return e->type == MapNotify && e->xmap.window == g_win; } +static int nul_handler(Display *dpy, XErrorEvent *event) +{ + (void)dpy; + (void)event; + return 0; +} + static void gfx_ctx_get_video_size(unsigned *width, unsigned *height); static void gfx_ctx_destroy(void); @@ -299,11 +204,8 @@ static bool gfx_ctx_init(void) }; GLXFBConfig *fbcs = NULL; - g_quit = 0; - init_lut(); - g_dpy = XOpenDisplay(NULL); if (!g_dpy) goto error; @@ -440,8 +342,6 @@ static bool gfx_ctx_set_video_mode( XEvent event; XIfEvent(g_dpy, &event, glx_wait_notify, NULL); - XSetInputFocus(g_dpy, g_win, RevertToNone, CurrentTime); - g_ctx = glXCreateNewContext(g_dpy, g_fbc, GLX_RGBA_TYPE, 0, True); if (!g_ctx) { @@ -475,6 +375,12 @@ static bool gfx_ctx_set_video_mode( gfx_ctx_swap_interval(g_interval); + // This can blow up on some drivers. It's not fatal, so override errors for this call. + int (*old_handler)(Display*, XErrorEvent*) = XSetErrorHandler(nul_handler); + XSetInputFocus(g_dpy, g_win, RevertToNone, CurrentTime); + XSync(g_dpy, False); + XSetErrorHandler(old_handler); + XFree(vi); g_has_focus = true; g_inited = true; diff --git a/gfx/context/xegl_ctx.c b/gfx/context/xegl_ctx.c index e4bd6f76d1..07184dde0e 100644 --- a/gfx/context/xegl_ctx.c +++ b/gfx/context/xegl_ctx.c @@ -64,6 +64,13 @@ static Bool egl_wait_notify(Display *d, XEvent *e, char *arg) return e->type == MapNotify && e->xmap.window == g_win; } +static int nul_handler(Display *dpy, XErrorEvent *event) +{ + (void)dpy; + (void)event; + return 0; +} + static void gfx_ctx_get_video_size(unsigned *width, unsigned *height); static void gfx_ctx_destroy(void); @@ -393,7 +400,6 @@ static bool gfx_ctx_set_video_mode( XEvent event; XIfEvent(g_dpy, &event, egl_wait_notify, NULL); - XSetInputFocus(g_dpy, g_win, RevertToNone, CurrentTime); g_quit_atom = XInternAtom(g_dpy, "WM_DELETE_WINDOW", False); if (g_quit_atom) @@ -401,6 +407,12 @@ static bool gfx_ctx_set_video_mode( gfx_ctx_swap_interval(g_interval); + // This can blow up on some drivers. It's not fatal, so override errors for this call. + int (*old_handler)(Display*, XErrorEvent*) = XSetErrorHandler(nul_handler); + XSetInputFocus(g_dpy, g_win, RevertToNone, CurrentTime); + XSync(g_dpy, False); + XSetErrorHandler(old_handler); + XFree(vi); g_has_focus = true; g_inited = true; diff --git a/input/overlay.c b/input/overlay.c index b14fdcb0ff..5225a28cdc 100644 --- a/input/overlay.c +++ b/input/overlay.c @@ -40,6 +40,9 @@ struct overlay_desc float range_x, range_y; uint64_t key_mask; + + unsigned next_index; + char next_index_name[64]; }; struct overlay @@ -58,6 +61,8 @@ struct overlay float center_x, center_y; bool full_screen; + + char name[64]; }; struct input_overlay @@ -72,6 +77,8 @@ struct input_overlay const struct overlay *active; size_t index; size_t size; + + unsigned next_index; }; static void input_overlay_scale(struct overlay *overlay, float scale) @@ -154,6 +161,13 @@ static bool input_overlay_load_desc(config_file_t *conf, struct overlay_desc *de for (const char *tmp = strtok_r(key, "|", &save); tmp; tmp = strtok_r(NULL, "|", &save)) desc->key_mask |= UINT64_C(1) << input_str_to_bind(tmp); + if (desc->key_mask & (UINT64_C(1) << RARCH_OVERLAY_NEXT)) + { + char overlay_target_key[64]; + snprintf(overlay_target_key, sizeof(overlay_target_key), "overlay%u_desc%u_next_target", ol_index, desc_index); + config_get_array(conf, overlay_target_key, desc->next_index_name, sizeof(desc->next_index_name)); + } + desc->x = strtod(x, NULL) / width; desc->y = strtod(y, NULL) / height; @@ -181,6 +195,7 @@ static bool input_overlay_load_overlay(config_file_t *conf, const char *config_p struct overlay *overlay, unsigned index) { char overlay_path_key[64]; + char overlay_name_key[64]; char overlay_path[PATH_MAX]; char overlay_resolved_path[PATH_MAX]; @@ -191,6 +206,9 @@ static bool input_overlay_load_overlay(config_file_t *conf, const char *config_p return false; } + snprintf(overlay_name_key, sizeof(overlay_name_key), "overlay%u_name", index); + config_get_array(conf, overlay_name_key, overlay->name, sizeof(overlay->name)); + fill_pathname_resolve_relative(overlay_resolved_path, config_path, overlay_path, sizeof(overlay_resolved_path)); @@ -272,6 +290,42 @@ static bool input_overlay_load_overlay(config_file_t *conf, const char *config_p return true; } +static ssize_t input_overlay_find_index(const struct overlay *ol, const char *name, size_t size) +{ + for (size_t i = 0; i < size; i++) + { + if (strcmp(ol[i].name, name) == 0) + return i; + } + + return -1; +} + +static bool input_overlay_resolve_targets(struct overlay *ol, size_t index, size_t size) +{ + struct overlay *current = &ol[index]; + + for (size_t i = 0; i < current->size; i++) + { + const char *next = current->descs[i].next_index_name; + if (*next) + { + ssize_t index = input_overlay_find_index(ol, next, size); + if (index < 0) + { + RARCH_ERR("[Overlay]: Couldn't find overlay called: \"%s\".\n", next); + return false; + } + + current->descs[i].next_index = index; + } + else + current->descs[i].next_index = (index + 1) % size; + } + + return true; +} + static bool input_overlay_load_overlays(input_overlay_t *ol, const char *path) { bool ret = true; @@ -315,6 +369,16 @@ static bool input_overlay_load_overlays(input_overlay_t *ol, const char *path) } } + for (size_t i = 0; i < ol->size; i++) + { + if (!input_overlay_resolve_targets(ol->overlays, i, ol->size)) + { + RARCH_ERR("[Overlay]: Failed to resolve next targets.\n"); + ret = false; + goto end; + } + } + end: config_file_free(conf); return ret; @@ -410,7 +474,13 @@ uint64_t input_overlay_poll(input_overlay_t *ol, int16_t norm_x, int16_t norm_y) for (size_t i = 0; i < ol->active->size; i++) { if (inside_hitbox(&ol->active->descs[i], x, y)) - state |= ol->active->descs[i].key_mask; + { + uint64_t mask = ol->active->descs[i].key_mask; + state |= mask; + + if (mask & (UINT64_C(1) << RARCH_OVERLAY_NEXT)) + ol->next_index = ol->active->descs[i].next_index; + } } if (!state) @@ -428,7 +498,7 @@ void input_overlay_poll_clear(input_overlay_t *ol) void input_overlay_next(input_overlay_t *ol) { - ol->index = (ol->index + 1) % ol->size; + ol->index = ol->next_index; ol->active = &ol->overlays[ol->index]; ol->iface->load(ol->iface_data, ol->active->image, ol->active->width, ol->active->height);