diff --git a/Makefile b/Makefile
index f7eb516e70..492c13e03a 100644
--- a/Makefile
+++ b/Makefile
@@ -89,7 +89,7 @@ ifneq ($(findstring Linux,$(OS)),)
endif
ifeq ($(HAVE_RGUI), 1)
- OBJ += frontend/menu/menu_common.o frontend/menu/rgui.o frontend/menu/history.o
+ OBJ += frontend/menu/menu_common.o frontend/menu/menu_context.o frontend/menu/rgui.o frontend/menu/history.o
endif
ifeq ($(HAVE_THREADS), 1)
diff --git a/Makefile.emscripten b/Makefile.emscripten
index c1e913419c..eb0eeab689 100644
--- a/Makefile.emscripten
+++ b/Makefile.emscripten
@@ -66,7 +66,7 @@ endif
ifeq ($(HAVE_RGUI), 1)
DEFINES += -DHAVE_RGUI
- OBJ += frontend/menu/menu_common.o frontend/menu/rgui.o frontend/menu/history.o
+ OBJ += frontend/menu/menu_common.o frontend/menu/menu_context.o frontend/menu/rgui.o frontend/menu/history.o
endif
ifeq ($(HAVE_SDL), 1)
diff --git a/Makefile.win b/Makefile.win
index c05e716ab4..28cb635e32 100644
--- a/Makefile.win
+++ b/Makefile.win
@@ -102,7 +102,7 @@ JLIBS =
ifeq ($(HAVE_RGUI), 1)
DEFINES += -DHAVE_RGUI
- OBJ += frontend/menu/menu_common.o frontend/menu/rgui.o frontend/menu/history.o
+ OBJ += frontend/menu/menu_common.o frontend/menu/menu_context.o frontend/menu/rgui.o frontend/menu/history.o
endif
ifeq ($(HAVE_WIN32GUI), 1)
diff --git a/frontend/menu/menu_common.c b/frontend/menu/menu_common.c
index 582daeb3ff..3442e64601 100644
--- a/frontend/menu/menu_common.c
+++ b/frontend/menu/menu_common.c
@@ -28,10 +28,12 @@
#else
#include "utils/file_list.h"
#endif
+#include "menu_context.h"
#include "../../compat/posix_string.h"
rgui_handle_t *rgui;
+menu_ctx_driver_t *menu_ctx;
#ifdef HAVE_SHADER_MANAGER
void shader_manager_init(rgui_handle_t *rgui)
@@ -420,7 +422,9 @@ void load_menu_game_prepare(void)
rgui->old_input_state = rgui->trigger_state = 0;
rgui->do_held = false;
rgui->msg_force = true;
- rgui_iterate(rgui);
+
+ if (menu_ctx && menu_ctx->iterate)
+ menu_ctx->iterate(rgui);
#endif
// Draw frame for loading message
@@ -495,9 +499,12 @@ bool load_menu_game(void)
void menu_init(void)
{
- rgui = rgui_init();
+ menu_ctx = (menu_ctx_driver_t*)menu_ctx_init_first();
- if (rgui == NULL)
+ if (menu_ctx && menu_ctx->init)
+ rgui = (rgui_handle_t*)menu_ctx->init();
+
+ if (rgui == NULL || menu_ctx == NULL)
{
RARCH_ERR("Could not initialize menu.\n");
rarch_fail(1, "menu_init()");
@@ -574,7 +581,8 @@ void menu_init(void)
void menu_free(void)
{
- rgui_free(rgui);
+ if (menu_ctx && menu_ctx->free)
+ menu_ctx->free(rgui);
#ifdef HAVE_FILEBROWSER
filebrowser_free(rgui->browser);
@@ -769,7 +777,7 @@ bool menu_iterate(void)
static bool initial_held = true;
static bool first_held = false;
uint64_t input_state = 0;
- int input_entry_ret;
+ int input_entry_ret = 0;
if (g_extern.lifecycle_mode_state & (1ULL << MODE_MENU_PREINIT))
{
@@ -816,7 +824,9 @@ bool menu_iterate(void)
rgui->delay_count++;
rgui->old_input_state = input_state;
- input_entry_ret = rgui_iterate(rgui);
+
+ if (menu_ctx && menu_ctx->iterate)
+ input_entry_ret = menu_ctx->iterate(rgui);
if (driver.video_poke && driver.video_poke->set_texture_enable)
driver.video_poke->set_texture_enable(driver.video_data, rgui->frame_buf_show, MENU_TEXTURE_FULLSCREEN);
diff --git a/frontend/menu/menu_common.h b/frontend/menu/menu_common.h
index 54bbdc0467..64e3abccf2 100644
--- a/frontend/menu/menu_common.h
+++ b/frontend/menu/menu_common.h
@@ -279,11 +279,6 @@ void menu_init(void);
bool menu_iterate(void);
void menu_free(void);
-int rgui_iterate(rgui_handle_t *rgui);
-
-rgui_handle_t *rgui_init(void);
-void rgui_free(rgui_handle_t *rgui);
-
#ifndef HAVE_RMENU_XUI
#if defined(HAVE_RGUI) || defined(HAVE_RMENU)
int rgui_input_postprocess(void *data, uint64_t old_state);
diff --git a/frontend/menu/menu_context.c b/frontend/menu/menu_context.c
new file mode 100644
index 0000000000..3d87080f1b
--- /dev/null
+++ b/frontend/menu/menu_context.c
@@ -0,0 +1,50 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2013 - Hans-Kristian Arntzen
+ *
+ * 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 "menu_context.h"
+#include
+
+#ifdef HAVE_CONFIG_H
+#include "../../config.h"
+#endif
+
+static const menu_ctx_driver_t *menu_ctx_drivers[] = {
+#if defined(HAVE_RMENU)
+ &menu_ctx_rmenu,
+#endif
+#if defined(HAVE_RGUI)
+ &menu_ctx_rgui,
+#endif
+ NULL // zero length array is not valid
+};
+
+const menu_ctx_driver_t *menu_ctx_find_driver(const char *ident)
+{
+ for (unsigned i = 0; menu_ctx_drivers[i]; i++)
+ {
+ if (strcmp(menu_ctx_drivers[i]->ident, ident) == 0)
+ return menu_ctx_drivers[i];
+ }
+
+ return NULL;
+}
+
+const menu_ctx_driver_t *menu_ctx_init_first(void)
+{
+ for (unsigned i = 0; menu_ctx_drivers[i]; i++)
+ return menu_ctx_drivers[i];
+
+ return NULL;
+}
diff --git a/frontend/menu/menu_context.h b/frontend/menu/menu_context.h
new file mode 100644
index 0000000000..4e5a387e46
--- /dev/null
+++ b/frontend/menu/menu_context.h
@@ -0,0 +1,43 @@
+/* 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 .
+ */
+
+#ifndef __MENU_CONTEXT_H
+#define __MENU_CONTEXT_H
+
+#include "../../boolean.h"
+#include "../../driver.h"
+
+#ifdef HAVE_CONFIG_H
+#include "../../config.h"
+#endif
+
+typedef struct menu_ctx_driver
+{
+ int (*iterate)(void*);
+ void* (*init)(void);
+ void (*free)(void*);
+
+ // Human readable string.
+ const char *ident;
+} menu_ctx_driver_t;
+
+extern const menu_ctx_driver_t menu_ctx_rmenu;
+extern const menu_ctx_driver_t menu_ctx_rgui;
+
+const menu_ctx_driver_t *menu_ctx_find_driver(const char *ident); // Finds driver with ident. Does not initialize.
+const menu_ctx_driver_t *menu_ctx_init_first(void); // Finds first suitable driver and initializes.
+
+#endif
diff --git a/frontend/menu/rgui.c b/frontend/menu/rgui.c
index dff32ea568..17fa2ba06d 100644
--- a/frontend/menu/rgui.c
+++ b/frontend/menu/rgui.c
@@ -22,6 +22,7 @@
#include
#include "rgui.h"
+#include "menu_context.h"
#include "utils/file_list.h"
#include "../../general.h"
#include "../../file_ext.h"
@@ -230,7 +231,7 @@ static bool menu_type_is_directory_browser(unsigned type)
static void rgui_settings_populate_entries(rgui_handle_t *rgui);
-rgui_handle_t *rgui_init(void)
+void *rgui_init(void)
{
uint16_t *framebuf = menu_framebuf;
size_t framebuf_pitch = RGUI_WIDTH * sizeof(uint16_t);
@@ -280,8 +281,9 @@ rgui_handle_t *rgui_init(void)
return rgui;
}
-void rgui_free(rgui_handle_t *rgui)
+void rgui_free(void *data)
{
+ rgui_handle_t *rgui = (rgui_handle_t*)data;
if (rgui->alloc_font)
free((uint8_t*)rgui->font);
@@ -2641,8 +2643,9 @@ static bool directory_parse(rgui_handle_t *rgui, const char *directory, unsigned
return true;
}
-int rgui_iterate(rgui_handle_t *rgui)
+int rgui_iterate(void *data)
{
+ rgui_handle_t *rgui = (rgui_handle_t*)data;
rgui_action_t action = RGUI_ACTION_NOOP;
// don't run anything first frame, only capture held inputs for old_input_state
@@ -2977,3 +2980,10 @@ int rgui_input_postprocess(void *data, uint64_t old_state)
return ret;
}
+
+const menu_ctx_driver_t menu_ctx_rgui = {
+ rgui_iterate,
+ rgui_init,
+ rgui_free,
+ "rgui",
+};
diff --git a/frontend/menu/rmenu.c b/frontend/menu/rmenu.c
index 19aad8e7f3..124e48fab7 100644
--- a/frontend/menu/rmenu.c
+++ b/frontend/menu/rmenu.c
@@ -2895,8 +2895,9 @@ int rgui_input_postprocess(void *data, uint64_t old_state)
return ret;
}
-int rgui_iterate(rgui_handle_t *rgui)
+int rgui_iterate(void *data)
{
+ rgui_handle_t *rgui = (rgui_handle_t*)data;
rgui->menu_type = menu_stack_enum_array[stack_idx - 1];
if (rgui->need_refresh)
@@ -2962,7 +2963,7 @@ int rgui_iterate(rgui_handle_t *rgui)
}
-rgui_handle_t *rgui_init(void)
+void *rgui_init(void)
{
rgui_handle_t *rgui = (rgui_handle_t*)calloc(1, sizeof(*rgui));
@@ -2983,8 +2984,9 @@ rgui_handle_t *rgui_init(void)
return rgui;
}
-void rgui_free(rgui_handle_t *rgui)
+void rgui_free(void *data)
{
+ rgui_handle_t *rgui = (rgui_handle_t*)data;
#ifdef _XBOX1
#ifdef HAVE_MENU_PANEL
if (menu_panel->vertex_buf)
@@ -3024,3 +3026,10 @@ void rgui_free(rgui_handle_t *rgui)
}
#endif
}
+
+const menu_ctx_driver_t menu_ctx_rmenu = {
+ rgui_iterate,
+ rgui_init,
+ rgui_free,
+ "rmenu",
+};
diff --git a/griffin/griffin.c b/griffin/griffin.c
index 5ff04b6ea9..24a6255098 100644
--- a/griffin/griffin.c
+++ b/griffin/griffin.c
@@ -526,6 +526,7 @@ MENU
============================================================ */
#ifdef HAVE_MENU
#include "../frontend/menu/menu_common.c"
+#include "../frontend/menu/menu_context.c"
#include "../frontend/menu/history.c"
#if defined(HAVE_RMENU_GUI)
diff --git a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj
index 4b037e80ea..016fccc602 100644
--- a/msvc/msvc-2010/RetroArch-msvc2010.vcxproj
+++ b/msvc/msvc-2010/RetroArch-msvc2010.vcxproj
@@ -190,6 +190,7 @@
+