From ed743c92a8e32a62ecbfc2bc8bfb1a753930a19d Mon Sep 17 00:00:00 2001 From: ToadKing Date: Fri, 22 Feb 2013 12:29:11 -0500 Subject: [PATCH 01/77] (Android/Phoenix) fix two common crashes --- .../phoenix/src/org/retroarch/browser/RetroArch.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/RetroArch.java b/android/phoenix/src/org/retroarch/browser/RetroArch.java index ad360f0da7..8c103fb2a3 100644 --- a/android/phoenix/src/org/retroarch/browser/RetroArch.java +++ b/android/phoenix/src/org/retroarch/browser/RetroArch.java @@ -349,8 +349,10 @@ public class RetroArch extends Activity implements return internal + File.separator + "retroarch.cfg"; else if (external != null && new File(internal + File.separator + "retroarch.cfg").canWrite()) return external + File.separator + "retroarch.cfg"; - else + else if (getCacheDir() != null && getCacheDir().getAbsolutePath() != null) return getCacheDir().getAbsolutePath() + File.separator + "retroarch.cfg"; + else // emergency fallback, all else failed + return "/mnt/sd/retroarch.cfg"; } private void updateConfigFile() { @@ -365,10 +367,10 @@ public class RetroArch extends Activity implements config.setBoolean("video_vsync", prefs.getBoolean("video_vsync", true)); config.setBoolean("input_autodetect_enable", prefs.getBoolean("input_autodetect_enable", true)); config.setBoolean("input_debug_enable", prefs.getBoolean("input_debug_enable", false)); - config.setInt("input_autodetect_icade_profile_pad1", prefs.getInt("input_autodetect_icade_profile_pad1", 0)); - config.setInt("input_autodetect_icade_profile_pad2", prefs.getInt("input_autodetect_icade_profile_pad2", 0)); - config.setInt("input_autodetect_icade_profile_pad3", prefs.getInt("input_autodetect_icade_profile_pad3", 0)); - config.setInt("input_autodetect_icade_profile_pad4", prefs.getInt("input_autodetect_icade_profile_pad4", 0)); + config.setInt("input_autodetect_icade_profile_pad1", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad1", "0"))); + config.setInt("input_autodetect_icade_profile_pad2", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad2", "0"))); + config.setInt("input_autodetect_icade_profile_pad3", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad3", "0"))); + config.setInt("input_autodetect_icade_profile_pad4", Integer.valueOf(prefs.getString("input_autodetect_icade_profile_pad4", "0"))); config.setDouble("video_refresh_rate", getRefreshRate()); config.setBoolean("video_threaded", prefs.getBoolean("video_threaded", false)); From 41a302de43dc7770639159b39d89c4250e1fb8c9 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Fri, 22 Feb 2013 14:57:34 -0500 Subject: [PATCH 02/77] (Android) show message on ROM load failure/crash --- .../src/org/retroarch/browser/RetroArch.java | 33 +++++++++++++++++-- frontend/frontend_android.c | 23 +++++++++++++ frontend/frontend_android.h | 1 + 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/RetroArch.java b/android/phoenix/src/org/retroarch/browser/RetroArch.java index 8c103fb2a3..7b51272711 100644 --- a/android/phoenix/src/org/retroarch/browser/RetroArch.java +++ b/android/phoenix/src/org/retroarch/browser/RetroArch.java @@ -59,11 +59,13 @@ public class RetroArch extends Activity implements AdapterView.OnItemClickListener { private IconAdapter adapter; static private final int ACTIVITY_LOAD_ROM = 0; + static private final int ACTIVITY_NATIVE_ACTIVITY = 1; static private String libretro_path; static private Double report_refreshrate; static private final String TAG = "RetroArch-Phoenix"; private ConfigFile config; private ConfigFile core_config; + private String return_file; private final double getDisplayRefreshRate() { // Android is *very* likely to screw this up. @@ -282,6 +284,12 @@ public class RetroArch extends Activity implements } } + if (getCacheDir() != null && getCacheDir().getAbsolutePath() != null) { + return_file = getCacheDir().getAbsolutePath() + File.pathSeparator + ".return"; + } else { + return_file = getDefaultConfigPath() + ".ret"; + } + this.setVolumeControlStream(AudioManager.STREAM_MUSIC); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { @@ -352,7 +360,7 @@ public class RetroArch extends Activity implements else if (getCacheDir() != null && getCacheDir().getAbsolutePath() != null) return getCacheDir().getAbsolutePath() + File.separator + "retroarch.cfg"; else // emergency fallback, all else failed - return "/mnt/sd/retroarch.cfg"; + return "/mnt/sdcard/retroarch.cfg"; } private void updateConfigFile() { @@ -456,6 +464,7 @@ public class RetroArch extends Activity implements switch (requestCode) { case ACTIVITY_LOAD_ROM: if (data.getStringExtra("PATH") != null) { + new File(return_file).delete(); Toast.makeText(this, "Loading: [" + data.getStringExtra("PATH") + "]...", Toast.LENGTH_SHORT).show(); @@ -463,10 +472,30 @@ public class RetroArch extends Activity implements myIntent.putExtra("ROM", data.getStringExtra("PATH")); myIntent.putExtra("LIBRETRO", libretro_path); myIntent.putExtra("CONFIGFILE", getDefaultConfigPath()); + myIntent.putExtra("RETURN", return_file); myIntent.putExtra("IME", current_ime); - startActivity(myIntent); + startActivityForResult(myIntent, ACTIVITY_NATIVE_ACTIVITY); } break; + case ACTIVITY_NATIVE_ACTIVITY: + Log.i(TAG, "native return"); + AlertDialog.Builder builder = new AlertDialog.Builder(this).setNeutralButton("OK", null); + try { + DataInputStream cacheStream = new DataInputStream(new FileInputStream(return_file)); + int value = cacheStream.readInt(); + cacheStream.close(); + Log.i(TAG, "native return value"); + Log.i(TAG, "native return value:" + value); + if (value != 0) { + builder.setTitle("Error").setMessage("RetroArch Could not load the chosen ROM").show(); + } + } catch (FileNotFoundException e) { + builder.setTitle("Crash").setMessage("RetroArch Crashed").show(); + } catch (IOException e) { + builder.setTitle("Error").setMessage("RetroArch Could not load the chosen ROM").show(); + } + new File(return_file).delete(); + break; } } diff --git a/frontend/frontend_android.c b/frontend/frontend_android.c index cee92d11dc..cf3ae7b336 100644 --- a/frontend/frontend_android.c +++ b/frontend/frontend_android.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "frontend_android.h" #include "../android/native/jni/jni_macros.h" @@ -280,6 +281,12 @@ static bool android_app_start_main(struct android_app *android_app, int *init_re strlcpy(out_args.in, "IME", sizeof(out_args.in)); jni_get(&in_params, &out_args); + // Return value file + out_args.out = android_app->return_file; + out_args.out_sizeof = sizeof(android_app->return_file); + strlcpy(out_args.in, "RETURN", sizeof(out_args.in)); + jni_get(&in_params, &out_args); + (*in_params.java_vm)->DetachCurrentThread(in_params.java_vm); RARCH_LOG("Checking arguments passed ...\n"); @@ -287,6 +294,9 @@ static bool android_app_start_main(struct android_app *android_app, int *init_re RARCH_LOG("Libretro path: [%s].\n", libretro_path); RARCH_LOG("Config file: [%s].\n", config_file); RARCH_LOG("Current IME: [%s].\n", android_app->current_ime); + RARCH_LOG("Return file: [%s].\n", android_app->return_file); + + unlink(android_app->return_file); struct rarch_main_wrap args = {0}; @@ -371,6 +381,19 @@ exit: #endif rarch_main_clear_state(); + int bs_return = bswap_32(init_ret); + FILE *return_file = fopen(android_app->return_file, "w"); + if (return_file) + { + fwrite(&bs_return, 4, 1, return_file); + fclose(return_file); + } + + // returning from the native activity too fast can make the Java frontend not reappear + // work around it only if we fail to load the ROM + if (init_ret != 0) + usleep(1000000); + RARCH_LOG("android_app_destroy!"); if (android_app->inputQueue != NULL) AInputQueue_detachLooper(android_app->inputQueue); diff --git a/frontend/frontend_android.h b/frontend/frontend_android.h index 16e6f21f9f..591493705a 100644 --- a/frontend/frontend_android.h +++ b/frontend/frontend_android.h @@ -49,6 +49,7 @@ struct android_app AInputQueue* pendingInputQueue; ANativeWindow* pendingWindow; char current_ime[PATH_MAX]; + char return_file[PATH_MAX]; }; enum { From 8d35c7f1be82c6e81333dc9ab493e90b2444d6cc Mon Sep 17 00:00:00 2001 From: ToadKing Date: Fri, 22 Feb 2013 15:24:05 -0500 Subject: [PATCH 03/77] (GX) update dist scripts for big stack cores --- Makefile.ngc | 13 +++++++++++-- Makefile.wii | 12 ++++++++---- dist-scripts/ngc-cores.sh | 7 +++++-- dist-scripts/wii-cores.sh | 7 +++++-- gx/ld/ogc.ld | 2 +- gx/ld/rvl.ld | 2 +- 6 files changed, 31 insertions(+), 12 deletions(-) diff --git a/Makefile.ngc b/Makefile.ngc index 4b8c0c7c63..fd8b6ff696 100644 --- a/Makefile.ngc +++ b/Makefile.ngc @@ -4,6 +4,8 @@ DEBUG = 0 HAVE_LOGGER = 1 HAVE_FILE_LOGGER = 0 PERF_TEST = 0 +WHOLE_ARCHIVE_LINK = 0 +BIG_STACK = 0 PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.7" PC_DEVELOPMENT_UDP_PORT = 3490 @@ -32,8 +34,15 @@ LIBDIRS := -L$(DEVKITPRO)/libogc/lib/cube -L. MACHDEP := -DGEKKO -DHW_DOL -mogc -mcpu=750 -meabi -mhard-float CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) -LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map -T gx/ld/ogc.ld -LIBS := -lfat -lretro_ngc -logc +ifeq ($(WHOLE_ARCHIVE_LINK), 1) + WHOLE_START := -Wl,--whole-archive + WHOLE_END := -Wl,--no-whole-archive +endif +LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map +ifeq ($(BIG_STACK), 1) + LDFLAGS += -T gx/ld/ogc.ld +endif +LIBS := -lfat $(WHOLE_START) -lretro_ngc $(WHOLE_END) -logc OBJ = console/griffin/griffin.o diff --git a/Makefile.wii b/Makefile.wii index d90446e342..ba0a331efb 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -4,7 +4,8 @@ DEBUG = 0 HAVE_LOGGER = 0 HAVE_FILE_LOGGER = 0 PERF_TEST = 0 -WHOLE_ARCHIVE_LINK = 0 +WHOLE_ARCHIVE_LINK = 0 +BIG_STACK = 0 PC_DEVELOPMENT_IP_ADDRESS = "192.168.1.100" PC_DEVELOPMENT_UDP_PORT = 3490 @@ -36,10 +37,13 @@ LIBDIRS := -L$(DEVKITPRO)/libogc/lib/wii -L. MACHDEP := -DGEKKO -DHW_RVL -mrvl -mcpu=750 -meabi -mhard-float CFLAGS += -Wall -std=gnu99 $(MACHDEP) $(INCLUDE) ifeq ($(WHOLE_ARCHIVE_LINK), 1) -WHOLE_START := -Wl,--whole-archive -WHOLE_END := -Wl,--no-whole-archive + WHOLE_START := -Wl,--whole-archive + WHOLE_END := -Wl,--no-whole-archive +endif +LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,strdup,-wrap,strndup,-wrap,malloc_usable_size +ifeq ($(BIG_STACK), 1) + LDFLAGS += -T gx/ld/rvl.ld endif -LDFLAGS := $(MACHDEP) -Wl,-Map,$(notdir $(ELF_TARGET)).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,strdup,-wrap,strndup,-wrap,malloc_usable_size -T gx/ld/rvl.ld LIBS := -lfat $(WHOLE_START) -lretro_wii $(WHOLE_END) -logc $(LDFLAGS_WIIUSE) -lbte APP_BOOTER_DIR = wii/app_booter diff --git a/dist-scripts/ngc-cores.sh b/dist-scripts/ngc-cores.sh index e9eb06f5da..62b3139774 100755 --- a/dist-scripts/ngc-cores.sh +++ b/dist-scripts/ngc-cores.sh @@ -5,12 +5,15 @@ make -C ../ -f Makefile.ngc clean || exit 1 for f in *_ngc.a ; do name=`echo "$f" | sed 's/\(_libretro\|\)_ngc.a$//'` whole_archive= + big_stack= if [ $name = "nxengine" ] ; then whole_archive="WHOLE_ARCHIVE_LINK=1" - echo $name yes + fi + if [ $name = "tyrquake" ] ; then + big_stack="BIG_STACK=1" fi cp -f "$f" ../libretro_ngc.a - make -C ../ -f Makefile.ngc $whole_archive -j3 || exit 1 + make -C ../ -f Makefile.ngc $whole_archive $big_stack -j3 || exit 1 mv -f ../retroarch_ngc.dol ../ngc/pkg/$name.dol rm -f ../retroarch_ngc.dol ../retroarch_ngc.elf ../retroarch_ngc.elf.map done diff --git a/dist-scripts/wii-cores.sh b/dist-scripts/wii-cores.sh index cc0ed766cf..0d90919069 100755 --- a/dist-scripts/wii-cores.sh +++ b/dist-scripts/wii-cores.sh @@ -9,12 +9,15 @@ make -C ../ -f Makefile.wii.salamander pkg || exit 1 for f in *_wii.a ; do name=`echo "$f" | sed 's/\(_libretro\|\)_wii.a$//'` whole_archive= + big_stack= if [ $name = "nxengine" ] ; then whole_archive="WHOLE_ARCHIVE_LINK=1" - echo $name yes + fi + if [ $name = "tyrquake" ] ; then + big_stack="BIG_STACK=1" fi cp -f "$f" ../libretro_wii.a - make -C ../ -f Makefile.wii $whole_archive -j3 || exit 1 + make -C ../ -f Makefile.wii $whole_archive $big_stack -j3 || exit 1 mv -f ../retroarch_wii.dol ../wii/pkg/$name.dol rm -f ../retroarch_wii.dol ../retroarch_wii.elf ../retroarch_wii.elf.map done diff --git a/gx/ld/ogc.ld b/gx/ld/ogc.ld index 0086209667..d6d06bc2ce 100644 --- a/gx/ld/ogc.ld +++ b/gx/ld/ogc.ld @@ -257,7 +257,7 @@ SECTIONS } __isIPL = 0; -__stack_addr = (__bss_start + SIZEOF(.bss) + 0x40000 + 7) & (-8); +__stack_addr = (__bss_start + SIZEOF(.bss) + 0x80000 + 7) & (-8); __stack_end = (__bss_start + SIZEOF(.bss)); __intrstack_addr = (__stack_addr + 0x4000); __intrstack_end = (__stack_addr); diff --git a/gx/ld/rvl.ld b/gx/ld/rvl.ld index 7a9867c2f4..e790eec2db 100644 --- a/gx/ld/rvl.ld +++ b/gx/ld/rvl.ld @@ -268,7 +268,7 @@ SECTIONS } __isIPL = 0; -__stack_addr = (__bss_start + SIZEOF(.bss) + 0x40000 + 7) & (-8); +__stack_addr = (__bss_start + SIZEOF(.bss) + 0x80000 + 7) & (-8); __stack_end = (__bss_start + SIZEOF(.bss)); __intrstack_addr = (__stack_addr + 0x4000); __intrstack_end = (__stack_addr); From 653ae663a220b23f72d22062967e43f1de560778 Mon Sep 17 00:00:00 2001 From: ToadKing Date: Fri, 22 Feb 2013 15:48:41 -0500 Subject: [PATCH 04/77] (Android/Phoenix) nit --- android/phoenix/src/org/retroarch/browser/RetroArch.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/RetroArch.java b/android/phoenix/src/org/retroarch/browser/RetroArch.java index 7b51272711..7dfc7c553a 100644 --- a/android/phoenix/src/org/retroarch/browser/RetroArch.java +++ b/android/phoenix/src/org/retroarch/browser/RetroArch.java @@ -315,11 +315,7 @@ public class RetroArch extends Activity implements startActivity(i); } }) - .setNegativeButton("No", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - } - }); + .setNegativeButton("No", null); alert.show(); } } From 232706d66563e6d1edaca1db70570a4e04f0d2cb Mon Sep 17 00:00:00 2001 From: ToadKing Date: Fri, 22 Feb 2013 17:33:41 -0500 Subject: [PATCH 05/77] (Android/Phoenix)expand on ROM load error message --- android/phoenix/src/org/retroarch/browser/RetroArch.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/android/phoenix/src/org/retroarch/browser/RetroArch.java b/android/phoenix/src/org/retroarch/browser/RetroArch.java index 7dfc7c553a..f7cc6373f9 100644 --- a/android/phoenix/src/org/retroarch/browser/RetroArch.java +++ b/android/phoenix/src/org/retroarch/browser/RetroArch.java @@ -474,21 +474,18 @@ public class RetroArch extends Activity implements } break; case ACTIVITY_NATIVE_ACTIVITY: - Log.i(TAG, "native return"); AlertDialog.Builder builder = new AlertDialog.Builder(this).setNeutralButton("OK", null); try { DataInputStream cacheStream = new DataInputStream(new FileInputStream(return_file)); int value = cacheStream.readInt(); cacheStream.close(); - Log.i(TAG, "native return value"); - Log.i(TAG, "native return value:" + value); if (value != 0) { - builder.setTitle("Error").setMessage("RetroArch Could not load the chosen ROM").show(); + throw new IOException(); } } catch (FileNotFoundException e) { builder.setTitle("Crash").setMessage("RetroArch Crashed").show(); } catch (IOException e) { - builder.setTitle("Error").setMessage("RetroArch Could not load the chosen ROM").show(); + builder.setTitle("Error").setMessage("RetroArch Could not load the chosen ROM.\n\nCheck the Cores Guide for details on valid ROMs for this emulator.").show(); } new File(return_file).delete(); break; From eb0476ffaba845af958a1c692ee41bd10c770823 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 23 Feb 2013 14:49:49 +0100 Subject: [PATCH 06/77] Add configurable GL context. --- general.h | 1 + gfx/context/drm_egl_ctx.c | 2 +- gfx/context/xegl_ctx.c | 4 ++-- gfx/gl.c | 45 ++++++++++++++++++++++++++++++++++----- retroarch.cfg | 5 +++++ settings.c | 1 + 6 files changed, 50 insertions(+), 8 deletions(-) diff --git a/general.h b/general.h index 044ff55e54..4974b57621 100644 --- a/general.h +++ b/general.h @@ -155,6 +155,7 @@ struct settings struct { char driver[32]; + char gl_context[32]; float xscale; float yscale; bool fullscreen; diff --git a/gfx/context/drm_egl_ctx.c b/gfx/context/drm_egl_ctx.c index 6172dcb10b..0fd295240f 100644 --- a/gfx/context/drm_egl_ctx.c +++ b/gfx/context/drm_egl_ctx.c @@ -630,6 +630,6 @@ const gfx_ctx_driver_t gfx_ctx_drm_egl = { gfx_ctx_init_egl_image_buffer, gfx_ctx_write_egl_image, NULL, - "drm-egl", + "kms-egl", }; diff --git a/gfx/context/xegl_ctx.c b/gfx/context/xegl_ctx.c index 85b8b7d591..e4bd6f76d1 100644 --- a/gfx/context/xegl_ctx.c +++ b/gfx/context/xegl_ctx.c @@ -369,7 +369,7 @@ static bool gfx_ctx_set_video_mode( if (true_full) { - RARCH_LOG("[GLX]: Using true fullscreen.\n"); + RARCH_LOG("[X/EGL]: Using true fullscreen.\n"); XMapRaised(g_dpy, g_win); } else if (fullscreen) // We attempted true fullscreen, but failed. Attempt using windowed fullscreen. @@ -455,7 +455,7 @@ static void gfx_ctx_destroy(void) g_screen = x11_get_xinerama_monitor(g_dpy, x, y, target.width, target.height); - RARCH_LOG("[GLX]: Saved monitor #%u.\n", g_screen); + RARCH_LOG("[X/EGL]: Saved monitor #%u.\n", g_screen); #endif XUnmapWindow(g_dpy, g_win); diff --git a/gfx/gl.c b/gfx/gl.c index 019c383d02..4748f12c53 100644 --- a/gfx/gl.c +++ b/gfx/gl.c @@ -1569,6 +1569,45 @@ static void gl_init_pbo_readback(void *data) #endif } +static const gfx_ctx_driver_t *gl_get_context(void) +{ +#ifdef HAVE_OPENGLES + enum gfx_ctx_api api = GFX_CTX_OPENGL_ES_API; + const char *api_name = "OpenGL ES"; +#else + enum gfx_ctx_api api = GFX_CTX_OPENGL_API; + const char *api_name = "OpenGL"; +#endif + + if (*g_settings.video.gl_context) + { + const gfx_ctx_driver_t *ctx = gfx_ctx_find_driver(g_settings.video.gl_context); + if (ctx) + { + if (!ctx->bind_api(api)) + { + RARCH_ERR("Failed to bind API %s to context %s.\n", api_name, g_settings.video.gl_context); + return NULL; + } + + if (!ctx->init()) + { + RARCH_ERR("Failed to init GL context: %s.\n", ctx->ident); + return NULL; + } + } + else + { + RARCH_ERR("Didn't find GL context: %s.\n", g_settings.video.gl_context); + return NULL; + } + + return ctx; + } + else + return gfx_ctx_init_first(api); +} + static void *gl_init(const video_info_t *video, const input_driver_t **input, void **input_data) { #ifdef _WIN32 @@ -1589,11 +1628,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo if (!gl) return NULL; -#ifdef HAVE_OPENGLES - gl->ctx_driver = gfx_ctx_init_first(GFX_CTX_OPENGL_ES_API); -#else - gl->ctx_driver = gfx_ctx_init_first(GFX_CTX_OPENGL_API); -#endif + gl->ctx_driver = gl_get_context(); if (!gl->ctx_driver) { free(gl); diff --git a/retroarch.cfg b/retroarch.cfg index 22248ce2cf..9285288f0b 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -40,6 +40,11 @@ # Video driver to use. "gl", "xvideo", "sdl" # video_driver = "gl" +# Which OpenGL context implementation to use. +# Possible ones for desktop are: glx, x-egl, kms-egl, sdl-gl, wgl. +# By default, tries to use first suitable driver. +# video_gl_context = + # Windowed xscale and yscale # (Real x res: base_size * xscale * aspect_ratio, real y res: base_size * yscale) # video_xscale = 3.0 diff --git a/settings.c b/settings.c index 83093c3e13..4e6576e845 100644 --- a/settings.c +++ b/settings.c @@ -648,6 +648,7 @@ bool config_load_file(const char *path) CONFIG_GET_STRING(audio.resampler, "audio_resampler"); CONFIG_GET_STRING(video.driver, "video_driver"); + CONFIG_GET_STRING(video.gl_context, "video_gl_context"); CONFIG_GET_STRING(audio.driver, "audio_driver"); CONFIG_GET_PATH(audio.dsp_plugin, "audio_dsp_plugin"); CONFIG_GET_STRING(input.driver, "input_driver"); From 100c26f067ecffb35789a6861dd2d95276e285e4 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 23 Feb 2013 15:15:10 +0100 Subject: [PATCH 07/77] Avoid failing when XSetInputFocus fails. --- gfx/context/glx_ctx.c | 14 ++++++++++++-- gfx/context/xegl_ctx.c | 13 ++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/gfx/context/glx_ctx.c b/gfx/context/glx_ctx.c index c181dcf8fa..f2aedb4b57 100644 --- a/gfx/context/glx_ctx.c +++ b/gfx/context/glx_ctx.c @@ -165,6 +165,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); @@ -440,8 +447,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 +480,11 @@ 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); + 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..8f4653cfa0 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,11 @@ 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); + XSetErrorHandler(old_handler); + XFree(vi); g_has_focus = true; g_inited = true; From 00d7d6c7ca879478dea385b7001c5c14f23a8ab7 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 23 Feb 2013 15:15:49 +0100 Subject: [PATCH 08/77] Drop redundant input code in GLX. --- gfx/context/glx_ctx.c | 105 ------------------------------------------ 1 file changed, 105 deletions(-) diff --git a/gfx/context/glx_ctx.c b/gfx/context/glx_ctx.c index f2aedb4b57..b7118792dd 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; @@ -306,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; From c78239a10d49fe3b7f7c1c6b405bc2ac271dbf49 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 23 Feb 2013 15:20:47 +0100 Subject: [PATCH 09/77] Avoid async error handling breaking XSetInputFocus. --- gfx/context/glx_ctx.c | 1 + gfx/context/xegl_ctx.c | 1 + 2 files changed, 2 insertions(+) diff --git a/gfx/context/glx_ctx.c b/gfx/context/glx_ctx.c index b7118792dd..b0141c1dd6 100644 --- a/gfx/context/glx_ctx.c +++ b/gfx/context/glx_ctx.c @@ -378,6 +378,7 @@ static bool gfx_ctx_set_video_mode( // 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); diff --git a/gfx/context/xegl_ctx.c b/gfx/context/xegl_ctx.c index 8f4653cfa0..07184dde0e 100644 --- a/gfx/context/xegl_ctx.c +++ b/gfx/context/xegl_ctx.c @@ -410,6 +410,7 @@ static bool gfx_ctx_set_video_mode( // 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); From 4427e5964e6b5a37fe4d1b26cffbaee318c366ca Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 23 Feb 2013 17:53:47 +0100 Subject: [PATCH 10/77] Auto savestate load is true by default. --- android/phoenix/res/xml/prefs.xml | 8 ++++---- android/phoenix/src/org/retroarch/browser/RetroArch.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) 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)); From c9e6f15861ef60ff4609cc71069fdbbe797fcb1b Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 23 Feb 2013 22:57:39 +0100 Subject: [PATCH 11/77] Add out-of-order overlays. --- input/overlay.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-) 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); From 6dd4a9b492f84bddf04249179c3700ba3b450d21 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 24 Feb 2013 02:08:20 +0100 Subject: [PATCH 12/77] Log which SwapInterval implementation is used. --- gfx/context/glx_ctx.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/gfx/context/glx_ctx.c b/gfx/context/glx_ctx.c index b0141c1dd6..88d2ea3e4d 100644 --- a/gfx/context/glx_ctx.c +++ b/gfx/context/glx_ctx.c @@ -361,14 +361,22 @@ static bool gfx_ctx_set_video_mode( g_is_double = val; if (g_is_double) { + const char *swap_func = NULL; + g_pglSwapInterval = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalMESA"); + if (g_pglSwapInterval) + swap_func = "glXSwapIntervalMESA"; + if (!g_pglSwapInterval) - g_pglSwapInterval = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapInterval"); - if (!g_pglSwapInterval) - g_pglSwapInterval = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalMESA"); - if (!g_pglSwapInterval) + { g_pglSwapInterval = (int (*)(int))glXGetProcAddress((const GLubyte*)"glXSwapIntervalSGI"); + if (g_pglSwapInterval) + swap_func = "glXSwapIntervalSGI"; + } + if (!g_pglSwapInterval) RARCH_WARN("[GLX]: Cannot find swap interval call.\n"); + else + RARCH_LOG("[GLX]: Found swap function: %s.\n", swap_func); } else RARCH_WARN("[GLX]: Context is not double buffered!.\n"); @@ -454,6 +462,7 @@ static void gfx_ctx_destroy(void) } g_inited = false; + g_pglSwapInterval = NULL; } static void gfx_ctx_input_driver(const input_driver_t **input, void **input_data) From b1530d981d194efbb24738c1530674cb243be8e1 Mon Sep 17 00:00:00 2001 From: sparklewind Date: Sun, 24 Feb 2013 03:39:19 +0100 Subject: [PATCH 13/77] Added 3 titles from ps1.idlst that I looked up I decided to include digital-only games too, as I feel that it's better in the long run to label them as such rather than ignore them. If you don't like it I'll remove it. --- tools/retrolaunch/launch.conf | 492 +++++++++++++++++----------------- 1 file changed, 249 insertions(+), 243 deletions(-) diff --git a/tools/retrolaunch/launch.conf b/tools/retrolaunch/launch.conf index dbc9c2f490..29f6fce918 100644 --- a/tools/retrolaunch/launch.conf +++ b/tools/retrolaunch/launch.conf @@ -1,243 +1,249 @@ -# PS1 Dualanalog Games ; - -"ps1.007 Racing*" mednafen-psx dualanalog ; -"ps1.007 - The World Is Not Enough*" mednafen-psx dualanalog ; -"ps1.007 - Tomorrow Never Dies*" mednafen-psx dualanalog ; -"ps1.40 Winks*" mednafen-psx dualanalog ; -"ps1.Ace Combat*" mednafen-psx dualanalog ; -"ps1.Aces of the Air*" mednafen-psx dualanalog ; -"ps1.Action Bass*" mednafen-psx dualanalog ; -"ps1.Action Man - Operation Extreme*" mednafen-psx dualanalog ; -"ps1.Advanced V.G. 2*" mednafen-psx dualanalog ; -"ps1.Aironauts*" mednafen-psx dualanalog ; -"ps1.Air Race Championship*" mednafen-psx dualanalog ; -"ps1.Akuji - The Heartless*" mednafen-psx dualanalog ; -"ps1.Alfred Chicken*" mednafen-psx dualanalog ; -"ps1.Alien la Resurrection*" mednafen-psx dualanalog ; -"ps1.Alien Resurrection*" mednafen-psx dualanalog ; -"ps1.Alone In The Dark - The New Nightmare*" mednafen-psx dualanalog ; -"ps1.Alundra 2*" mednafen-psx dualanalog ; -"ps1.Amazing Virtual Sea Monkeys*" mednafen-psx dualanalog ; -"ps1.Animorphs - Shattered Reality*" mednafen-psx dualanalog ; -"ps1.Ape Escape*" mednafen-psx dualanalog ; -"ps1.Apocalypse*" mednafen-psx dualanalog ; -"ps1.Aqua GT*" mednafen-psx dualanalog ; -"ps1.Armored Core - Master of Arena*" mednafen-psx dualanalog ; -"ps1.Armorines - Project Swarm*" mednafen-psx dualanalog ; -"ps1.Army Men 3D*" mednafen-psx dualanalog ; -"ps1.Army Men - Air Attack 2*" mednafen-psx dualanalog ; -"ps1.Army Men - Air Attack*" mednafen-psx dualanalog ; -"ps1.Army Men - Green Rouge*" mednafen-psx dualanalog ; -"ps1.Army Men - Sarge's Heroes 2*" mednafen-psx dualanalog ; -"ps1.Army Men - Sarge's Heroes*" mednafen-psx dualanalog ; -"ps1.Army Men - World War*" mednafen-psx dualanalog ; -"ps1.Assault Retribution*" mednafen-psx dualanalog ; -"ps1.Asterix - Mega Madness*" mednafen-psx dualanalog ; -"ps1.Asteroids*" mednafen-psx dualanalog ; -"ps1.Barbie Explorer" mednafen-psx dualanalog ; -"ps1.Barbie - Gotta Have Games" mednafen-psx dualanalog ; -"ps1.Batman Beyond - Return of the Joker" mednafen-psx dualanalog ; -"ps1.Batman & Robin" mednafen-psx dualanalog ; -"ps1.Beatmania" mednafen-psx dualanalog ; -"ps1.Beat Planet Music" mednafen-psx dualanalog ; -"ps1.Beyblade" mednafen-psx dualanalog ; -"ps1.Big Bass Fishing" mednafen-psx dualanalog ; -"ps1.BioHazard - Director's Cut - Dual Shock*" mednafen-psx dualanalog ; -"ps1.Bishi Bashi Special" mednafen-psx dualanalog ; -"ps1.Blade" mednafen-psx dualanalog ; -"ps1.Blasto!" mednafen-psx dualanalog ; -"ps1.Blast Radius" mednafen-psx dualanalog ; -"ps1.Block Kuzushi" mednafen-psx dualanalog ; -"ps1.Block Wars" mednafen-psx dualanalog ; -"ps1.Bloody Roar 2*" mednafen-psx dualanalog ; -"ps1.Bob the Builder - Can We Fix It" mednafen-psx dualanalog ; -"ps1.Boombots" mednafen-psx dualanalog ; -"ps1.Bratz" mednafen-psx dualanalog ; -"ps1.Brave Fencer Musashi*" mednafen-psx dualanalog ; -"ps1.Breakout" mednafen-psx dualanalog ; -"ps1.Buggy" mednafen-psx dualanalog ; -"ps1.Bugs Bunny - Lost in Time*" mednafen-psx dualanalog ; -"ps1.Bugs Bunny & Taz - Time Busters" mednafen-psx dualanalog ; -"ps1.C-12 - The Final Resistance" mednafen-psx dualanalog ; -"ps1.Captain Commando" mednafen-psx dualanalog ; -"ps1.Cardinal Syn*" mednafen-psx dualanalog ; -"ps1.Carmageddon*" mednafen-psx dualanalog ; -"ps1.Casper - Friends Around The World" mednafen-psx dualanalog ; -"ps1.Chaos Break" mednafen-psx dualanalog ; -"ps1.Chicken Run" mednafen-psx dualanalog ; -"ps1.Chippoke Ralph no Daibouken (Adventure of Little Ralph)" mednafen-psx dualanalog ; -"ps1.Chocobo Racing" mednafen-psx dualanalog ; -"ps1.Chrono Cross*" pcsxr dualanalog ; -"ps1.Colin Mc[rR]ae*" mednafen-psx dualanalog ; -"ps1.Colony Wars*" mednafen-psx dualanalog ; -"ps1.Cosmowarrior Rei" mednafen-psx dualanalog ; -"ps1.Cowboy Bebop" mednafen-psx dualanalog ; -"ps1.Crash Bandicoot 2*" mednafen-psx dualanalog ; -"ps1.Crash Bandicoot 3*" mednafen-psx dualanalog ; -"ps1.Crash Bandicoot Carnival - Crash Bash*" mednafen-psx dualanalog ; -"ps1.Crash Bash Demo" mednafen-psx dualanalog ; -"ps1.Crash Bash" mednafen-psx dualanalog ; -"ps1.Crash Bash" mednafen-psx dualanalog ; -"ps1.Crash Bash & Spyro - Year of the Dragon Demo" mednafen-psx dualanalog ; -"ps1.Crash Team Racing*" mednafen-psx dualanalog multitap ; -"ps1.Crisis Beat" mednafen-psx dualanalog ; -"ps1.Croc 2*" mednafen-psx dualanalog ; -"ps1.Croc - Legend of the Gobbos" mednafen-psx dualanalog ; -"ps1.C - The Contra Adventure" mednafen-psx dualanalog ; -"ps1.CT Special Forces" mednafen-psx dualanalog ; -"ps1.CyberTiger Golf" mednafen-psx dualanalog ; -"ps1.Fighting Force*" mednafen-psx dualanalog ; -"ps1.Future Cop*" mednafen-psx dualanalog ; -"ps1.Legacy of Kain - Soul Reaver*" pcsxr dualanalog ; -"ps1.Saru! Get You!*" mednafen-psx dualanalog ; -"ps1.Simple Characters 2000 Series #02 - Afro Inu - The Puzzle*" mednafen-psx dualanalog ; -"ps1.Soul Reaver - Legacy of Kain*" mednafen-psx dualanalog ; -"ps1.Spyro the Dragon*"" mednafen-psx dualanalog ; -"ps1.Spyro - Year of the Dragon*" mednafen-psx dualanalog ; -"ps1.Vagrant Story*" mednafen-psx dualanalog ; - -"ps1.Earthworm Jim 2" pcsxr ; -"ps1.Mickey's Wild Adventures" pcsxr ; - -# SNES BSNES Performance ; -"snes. - -"ps1.Earthworm Jim 2" pcsxr ; -"ps1.Mickey's Wild Adventures" pcsxr ; - -# SNES BSNES Performance ; -"snes.Psycho Dream*" bsnes-performance ; - -# SNES Multitap Games ; - -"snes.Bakukyuu Renpatsu!! Super B-Daman*" snes9x multitap ; -"snes.Bakutou Dochers - Bumps-jima wa Oosawagi*" snes9x multitap ; -"snes.Barkley Shut Up and Jam!*" snes9x multitap ; -"snes.Barkley Shut Up and Jam!*" snes9x multitap ; -"snes.Battle Cross*" snes9x multitap ; -"snes.Battle Jockey*" snes9x multitap ; -"snes.Bill Walsh College Football*" snes9x multitap ; -"snes.Capcom's Soccer Shootout*" snes9x multitap ; -"snes.College Slam*" snes9x multitap ; -"snes.Crystal Beans From Dungeon Explorer*" snes9x multitap ; -"snes.Dragon - The Bruce Lee Story*" snes9x multitap ; -"snes.Dream Basketball - Dunk and Hoop*" snes9x multitap ; -"snes.Dynamic Stadium*" snes9x multitap ; -"snes.ESPN National Hockey Night*" snes9x multitap ; -"snes.FIFA 98*" snes9x multitap ; -"snes.FIFA International Soccer*" snes9x multitap ; -"snes.FIFA Soccer 96*" snes9x multitap ; -"snes.FIFA Soccer 97*" snes9x multitap ; -"snes.Final Set*" snes9x multitap ; -"snes.Fire Striker*" snes9x multitap ; -"snes.From TV Animation Slam Dunk - SD Heat Up!!*" snes9x multitap ; -"snes.Go! Go! Dodge League*" snes9x multitap ; -"snes.Hammerlock Wrestling*" snes9x multitap ; -"snes.Hat Trick Hero 2*" snes9x multitap ; -"snes.Head-On Soccer*" snes9x multitap ; -"snes.Hebereke no Oishii Puzzle ha Irimasenka*" snes9x multitap ; -"snes.Human Grand Prix III - F1 Triple Battle*" snes9x multitap ; -"snes.Human Grand Prix IV - F1 Dream Battle*" snes9x multitap ; -"snes.Hungry Dinosaurs*" snes9x multitap ; -"snes.International Superstar Soccer Deluxe*" snes9x multitap ; -"snes.J.League Excite Stage '94*" snes9x multitap ; -"snes.J.League Excite Stage '95*" snes9x multitap ; -"snes.J.League Excite Stage '96*" snes9x multitap ; -"snes.J.League Super Soccer '95*" snes9x multitap ; -"snes.J.League Super Soccer*" snes9x multitap ; -"snes.JWP Joshi Pro Wrestling - Pure Wrestle Queens*" snes9x multitap ; -"snes.Jikkyou Power Pro Wrestling '96*" snes9x multitap ; -"snes.Jimmy Connors Pro Tennis Tour*" snes9x multitap ; -"snes.Kunio-kun no Dodge Ball dayo Zenin Shuugou!*" snes9x multitap ; -"snes.Looney Tunes Basketball*" snes9x multitap ; -"snes.Madden NFL '94*" snes9x multitap ; -"snes.Madden NFL '95*" snes9x multitap ; -"snes.Madden NFL '96*" snes9x multitap ; -"snes.Madden NFL '97*" snes9x multitap ; -"snes.Madden NFL '98*" snes9x multitap ; -"snes.Micro Machines 2 - Turbo Tournament*" snes9x multitap ; -"snes.Micro Machines*" snes9x multitap ; -"snes.Mizuki Shigeru no Youkai Hyakkiyakou*" snes9x multitap ; -"snes.Multi Play Volleyball*" snes9x multitap ; -"snes.NBA Give 'N Go*" snes9x multitap ; -"snes.NBA Hang Time*" snes9x multitap ; -"snes.NBA Jam - Tournament Edition*" snes9x multitap ; -"snes.NBA Jam*" snes9x multitap ; -"snes.NBA Live 95*" snes9x multitap ; -"snes.NBA Live 96*" snes9x multitap ; -"snes.NBA Live 97*" snes9x multitap ; -"snes.NBA Live 98*" snes9x multitap ; -"snes.NCAA Final Four Basketball*" snes9x multitap ; -"snes.NCAA Football*" snes9x multitap ; -"snes.NFL Quarterback Club 96*" snes9x multitap ; -"snes.NFL Quarterback Club*" snes9x multitap ; -"snes.NHL '94*" snes9x multitap ; -"snes.NHL '98*" snes9x multitap ; -"snes.NHL Pro Hockey '94*" snes9x multitap ; -"snes.Natsume Championship Wrestling*" snes9x multitap ; -"snes.Peace Keepers, The*" snes9x multitap ; -"snes.Pieces*" snes9x multitap ; -"snes.Rap Jam - Volume One*" snes9x multitap ; -"snes.Saturday Night Slam Masters*" snes9x multitap ; -"snes.Secret of Mana*" snes9x multitap ; -"snes.Shin Nippon Pro Wrestling '94 - Battlefield in Tokyo Dome*" snes9x multitap ; -"snes.Shin Nippon Pro Wrestling - Chou Senshi in Tokyo Dome*" snes9x multitap ; -"snes.Shin Nippon Pro Wrestling Kounin '95 - Tokyo Dome Battle 7*" snes9x multitap ; -"snes.Smash Tennis*" snes9x multitap ; -"snes.Sporting News, The - Power Baseball*" snes9x multitap ; -"snes.Sterling Sharpe End 2 End*" snes9x multitap ; -"snes.Street Hockey '95*" snes9x multitap ; -"snes.Street Racer*" snes9x multitap ; -"snes.Sugoi Hebereke*" snes9x multitap ; -"snes.Sugoro Quest++ Dicenics*" snes9x multitap ; -"snes.Super Bomberman - Panic Bomber W*" snes9x multitap ; -"snes.Super Bomberman 2*" snes9x multitap ; -"snes.Super Bomberman 3*" snes9x multitap ; -"snes.Super Bomberman 4*" snes9x multitap ; -"snes.Super Bomberman 5*" snes9x multitap ; -"snes.Super Bomberman*" snes9x multitap ; -"snes.Super Fire Pro Wrestling - Queen's Special*" snes9x multitap ; -"snes.Super Fire Pro Wrestling Special*" snes9x multitap ; -"snes.Super Fire Pro Wrestling X Premium*" snes9x multitap ; -"snes.Super Fire Pro Wrestling X*" snes9x multitap ; -"snes.Super Formation Soccer 94 - World Cup Final Data*" snes9x multitap ; -"snes.Super Formation Soccer 94*" snes9x multitap ; -"snes.Super Formation Soccer 95 della Serie A - UCC Xaqua*" snes9x multitap ; -"snes.Super Formation Soccer 95 della Serie A*" snes9x multitap ; -"snes.Super Formation Soccer 96*" snes9x multitap ; -"snes.Super Formation Soccer II*" snes9x multitap ; -"snes.Super Ice Hockey*" snes9x multitap ; -"snes.Super Kyousouba - Kaze no Sylphid*" snes9x multitap ; -"snes.Super Power League*" snes9x multitap ; -"snes.Super Tekkyuu Fight!*" snes9x multitap ; -"snes.Super Tetris 3*" snes9x multitap ; -"snes.Syndicate*" snes9x multitap ; -"snes.Tenryu Genichiro no Pro Wrestling Revolution*" snes9x multitap ; -"snes.Tiny Toon Adventures - Wild & Wacky Sports*" snes9x multitap ; -"snes.Top Gear 3000*" snes9x multitap ; -"snes.Turbo Toons*" snes9x multitap ; -"snes.Virtual Soccer*" snes9x multitap ; -"snes.Vs. Collection*" snes9x multitap ; -"snes.WWF Raw*" snes9x multitap ; -"snes.Yuujin no Furi Furi Girls*" snes9x multitap ; -"snes.Zero 4 Champ RR-Z*" snes9x multitap ; -"snes.Zero 4 Champ RR*" snes9x multitap ; - -# Defaults ; - -"gba.*" vba ; -"gbc.*" gambatte ; -"gb.*" gambatte ; -"gg.*" genplus ; -"nes.*" fceu ; -"pcecd.*" mednafen-pce-fast ; -"pce.*" mednafen-pce-fast ; -"ps1.*" mednafen-psx ; -"wswan.*" mednafen-wswan ; -"a26.*" stella ; -"scd.*" genplus ; -"sg1000.*" genplus ; -"smd.*" genplus ; -"sms.*" genplus ; -"snes.*" snes9x ; -"nds.*" desmume ; +# PS1 Gamepad Games ; + +"ps1....Iru!*" mednafen-psx gamepad ; + +# PS1 Dualanalog Games ; + +"ps1.007 - Demain ne Meurt Jamais" mednafen-psx dualanalog ; +"ps1.007 - Le Monde Ne Suffit Pas" mednafen-psx dualanalog ; +"ps1.007 Racing*" mednafen-psx dualanalog ; +"ps1.007 - The World Is Not Enough*" mednafen-psx dualanalog ; +"ps1.007 - Tomorrow Never Dies*" mednafen-psx dualanalog ; +"ps1.40 Winks*" mednafen-psx dualanalog ; +"ps1.Ace Combat*" mednafen-psx dualanalog ; +"ps1.Aces of the Air*" mednafen-psx dualanalog ; +"ps1.Action Bass*" mednafen-psx dualanalog ; +"ps1.Action Man - Operation Extreme*" mednafen-psx dualanalog ; +"ps1.Advanced V.G. 2*" mednafen-psx dualanalog ; +"ps1.Aironauts*" mednafen-psx dualanalog ; +"ps1.Air Race Championship*" mednafen-psx dualanalog ; +"ps1.Akuji - The Heartless*" mednafen-psx dualanalog ; +"ps1.Alfred Chicken*" mednafen-psx dualanalog ; +"ps1.Alien la Resurrection*" mednafen-psx dualanalog ; +"ps1.Alien Resurrection*" mednafen-psx dualanalog ; +"ps1.Alone In The Dark - The New Nightmare*" mednafen-psx dualanalog ; +"ps1.Alundra 2*" mednafen-psx dualanalog ; +"ps1.Amazing Virtual Sea Monkeys*" mednafen-psx dualanalog ; +"ps1.Animorphs - Shattered Reality*" mednafen-psx dualanalog ; +"ps1.Ape Escape*" mednafen-psx dualanalog ; +"ps1.Apocalypse*" mednafen-psx dualanalog ; +"ps1.Aqua GT*" mednafen-psx dualanalog ; +"ps1.Armored Core - Master of Arena*" mednafen-psx dualanalog ; +"ps1.Armorines - Project Swarm*" mednafen-psx dualanalog ; +"ps1.Army Men 3D*" mednafen-psx dualanalog ; +"ps1.Army Men - Air Attack 2*" mednafen-psx dualanalog ; +"ps1.Army Men - Air Attack*" mednafen-psx dualanalog ; +"ps1.Army Men - Green Rouge*" mednafen-psx dualanalog ; +"ps1.Army Men - Sarge's Heroes 2*" mednafen-psx dualanalog ; +"ps1.Army Men - Sarge's Heroes*" mednafen-psx dualanalog ; +"ps1.Army Men - World War*" mednafen-psx dualanalog ; +"ps1.Assault Retribution*" mednafen-psx dualanalog ; +"ps1.Asterix - Mega Madness*" mednafen-psx dualanalog ; +"ps1.Asteroids*" mednafen-psx dualanalog ; +"ps1.Barbie Explorer" mednafen-psx dualanalog ; +"ps1.Barbie - Gotta Have Games" mednafen-psx dualanalog ; +"ps1.Batman Beyond - Return of the Joker" mednafen-psx dualanalog ; +"ps1.Batman & Robin" mednafen-psx dualanalog ; +"ps1.Beatmania" mednafen-psx dualanalog ; +"ps1.Beat Planet Music" mednafen-psx dualanalog ; +"ps1.Beyblade" mednafen-psx dualanalog ; +"ps1.Big Bass Fishing" mednafen-psx dualanalog ; +"ps1.BioHazard - Director's Cut - Dual Shock*" mednafen-psx dualanalog ; +"ps1.Bishi Bashi Special" mednafen-psx dualanalog ; +"ps1.Blade" mednafen-psx dualanalog ; +"ps1.Blasto!" mednafen-psx dualanalog ; +"ps1.Blast Radius" mednafen-psx dualanalog ; +"ps1.Block Kuzushi" mednafen-psx dualanalog ; +"ps1.Block Wars" mednafen-psx dualanalog ; +"ps1.Bloody Roar 2*" mednafen-psx dualanalog ; +"ps1.Bob the Builder - Can We Fix It" mednafen-psx dualanalog ; +"ps1.Boombots" mednafen-psx dualanalog ; +"ps1.Bratz" mednafen-psx dualanalog ; +"ps1.Brave Fencer Musashi*" mednafen-psx dualanalog ; +"ps1.Breakout" mednafen-psx dualanalog ; +"ps1.Buggy" mednafen-psx dualanalog ; +"ps1.Bugs Bunny - Lost in Time*" mednafen-psx dualanalog ; +"ps1.Bugs Bunny & Taz - Time Busters" mednafen-psx dualanalog ; +"ps1.C-12 - The Final Resistance" mednafen-psx dualanalog ; +"ps1.Captain Commando" mednafen-psx dualanalog ; +"ps1.Cardinal Syn*" mednafen-psx dualanalog ; +"ps1.Carmageddon*" mednafen-psx dualanalog ; +"ps1.Casper - Friends Around The World" mednafen-psx dualanalog ; +"ps1.Chaos Break" mednafen-psx dualanalog ; +"ps1.Chicken Run" mednafen-psx dualanalog ; +"ps1.Chippoke Ralph no Daibouken (Adventure of Little Ralph)" mednafen-psx dualanalog ; +"ps1.Chocobo Racing" mednafen-psx dualanalog ; +"ps1.Chrono Cross*" pcsxr dualanalog ; +"ps1.Colin Mc[rR]ae*" mednafen-psx dualanalog ; +"ps1.Colony Wars*" mednafen-psx dualanalog ; +"ps1.Cosmowarrior Rei" mednafen-psx dualanalog ; +"ps1.Cowboy Bebop" mednafen-psx dualanalog ; +"ps1.Crash Bandicoot 2*" mednafen-psx dualanalog ; +"ps1.Crash Bandicoot 3*" mednafen-psx dualanalog ; +"ps1.Crash Bandicoot Carnival - Crash Bash*" mednafen-psx dualanalog ; +"ps1.Crash Bash Demo" mednafen-psx dualanalog ; +"ps1.Crash Bash" mednafen-psx dualanalog ; +"ps1.Crash Bash" mednafen-psx dualanalog ; +"ps1.Crash Bash & Spyro - Year of the Dragon Demo" mednafen-psx dualanalog ; +"ps1.Crash Team Racing*" mednafen-psx dualanalog multitap ; +"ps1.Crisis Beat" mednafen-psx dualanalog ; +"ps1.Croc 2*" mednafen-psx dualanalog ; +"ps1.Croc - Legend of the Gobbos" mednafen-psx dualanalog ; +"ps1.C - The Contra Adventure" mednafen-psx dualanalog ; +"ps1.CT Special Forces" mednafen-psx dualanalog ; +"ps1.CyberTiger Golf" mednafen-psx dualanalog ; +"ps1.Fighting Force*" mednafen-psx dualanalog ; +"ps1.Future Cop*" mednafen-psx dualanalog ; +"ps1.Legacy of Kain - Soul Reaver*" pcsxr dualanalog ; +"ps1.Saru! Get You!*" mednafen-psx dualanalog ; +"ps1.Simple Characters 2000 Series #02 - Afro Inu - The Puzzle*" mednafen-psx dualanalog ; +"ps1.Soul Reaver - Legacy of Kain*" mednafen-psx dualanalog ; +"ps1.Spyro the Dragon*"" mednafen-psx dualanalog ; +"ps1.Spyro - Year of the Dragon*" mednafen-psx dualanalog ; +"ps1.Vagrant Story*" mednafen-psx dualanalog ; + +"ps1.Earthworm Jim 2" pcsxr ; +"ps1.Mickey's Wild Adventures" pcsxr ; + +# SNES BSNES Performance ; +"snes. + +"ps1.Earthworm Jim 2" pcsxr ; +"ps1.Mickey's Wild Adventures" pcsxr ; + +# SNES BSNES Performance ; +"snes.Psycho Dream*" bsnes-performance ; + +# SNES Multitap Games ; + +"snes.Bakukyuu Renpatsu!! Super B-Daman*" snes9x multitap ; +"snes.Bakutou Dochers - Bumps-jima wa Oosawagi*" snes9x multitap ; +"snes.Barkley Shut Up and Jam!*" snes9x multitap ; +"snes.Barkley Shut Up and Jam!*" snes9x multitap ; +"snes.Battle Cross*" snes9x multitap ; +"snes.Battle Jockey*" snes9x multitap ; +"snes.Bill Walsh College Football*" snes9x multitap ; +"snes.Capcom's Soccer Shootout*" snes9x multitap ; +"snes.College Slam*" snes9x multitap ; +"snes.Crystal Beans From Dungeon Explorer*" snes9x multitap ; +"snes.Dragon - The Bruce Lee Story*" snes9x multitap ; +"snes.Dream Basketball - Dunk and Hoop*" snes9x multitap ; +"snes.Dynamic Stadium*" snes9x multitap ; +"snes.ESPN National Hockey Night*" snes9x multitap ; +"snes.FIFA 98*" snes9x multitap ; +"snes.FIFA International Soccer*" snes9x multitap ; +"snes.FIFA Soccer 96*" snes9x multitap ; +"snes.FIFA Soccer 97*" snes9x multitap ; +"snes.Final Set*" snes9x multitap ; +"snes.Fire Striker*" snes9x multitap ; +"snes.From TV Animation Slam Dunk - SD Heat Up!!*" snes9x multitap ; +"snes.Go! Go! Dodge League*" snes9x multitap ; +"snes.Hammerlock Wrestling*" snes9x multitap ; +"snes.Hat Trick Hero 2*" snes9x multitap ; +"snes.Head-On Soccer*" snes9x multitap ; +"snes.Hebereke no Oishii Puzzle ha Irimasenka*" snes9x multitap ; +"snes.Human Grand Prix III - F1 Triple Battle*" snes9x multitap ; +"snes.Human Grand Prix IV - F1 Dream Battle*" snes9x multitap ; +"snes.Hungry Dinosaurs*" snes9x multitap ; +"snes.International Superstar Soccer Deluxe*" snes9x multitap ; +"snes.J.League Excite Stage '94*" snes9x multitap ; +"snes.J.League Excite Stage '95*" snes9x multitap ; +"snes.J.League Excite Stage '96*" snes9x multitap ; +"snes.J.League Super Soccer '95*" snes9x multitap ; +"snes.J.League Super Soccer*" snes9x multitap ; +"snes.JWP Joshi Pro Wrestling - Pure Wrestle Queens*" snes9x multitap ; +"snes.Jikkyou Power Pro Wrestling '96*" snes9x multitap ; +"snes.Jimmy Connors Pro Tennis Tour*" snes9x multitap ; +"snes.Kunio-kun no Dodge Ball dayo Zenin Shuugou!*" snes9x multitap ; +"snes.Looney Tunes Basketball*" snes9x multitap ; +"snes.Madden NFL '94*" snes9x multitap ; +"snes.Madden NFL '95*" snes9x multitap ; +"snes.Madden NFL '96*" snes9x multitap ; +"snes.Madden NFL '97*" snes9x multitap ; +"snes.Madden NFL '98*" snes9x multitap ; +"snes.Micro Machines 2 - Turbo Tournament*" snes9x multitap ; +"snes.Micro Machines*" snes9x multitap ; +"snes.Mizuki Shigeru no Youkai Hyakkiyakou*" snes9x multitap ; +"snes.Multi Play Volleyball*" snes9x multitap ; +"snes.NBA Give 'N Go*" snes9x multitap ; +"snes.NBA Hang Time*" snes9x multitap ; +"snes.NBA Jam - Tournament Edition*" snes9x multitap ; +"snes.NBA Jam*" snes9x multitap ; +"snes.NBA Live 95*" snes9x multitap ; +"snes.NBA Live 96*" snes9x multitap ; +"snes.NBA Live 97*" snes9x multitap ; +"snes.NBA Live 98*" snes9x multitap ; +"snes.NCAA Final Four Basketball*" snes9x multitap ; +"snes.NCAA Football*" snes9x multitap ; +"snes.NFL Quarterback Club 96*" snes9x multitap ; +"snes.NFL Quarterback Club*" snes9x multitap ; +"snes.NHL '94*" snes9x multitap ; +"snes.NHL '98*" snes9x multitap ; +"snes.NHL Pro Hockey '94*" snes9x multitap ; +"snes.Natsume Championship Wrestling*" snes9x multitap ; +"snes.Peace Keepers, The*" snes9x multitap ; +"snes.Pieces*" snes9x multitap ; +"snes.Rap Jam - Volume One*" snes9x multitap ; +"snes.Saturday Night Slam Masters*" snes9x multitap ; +"snes.Secret of Mana*" snes9x multitap ; +"snes.Shin Nippon Pro Wrestling '94 - Battlefield in Tokyo Dome*" snes9x multitap ; +"snes.Shin Nippon Pro Wrestling - Chou Senshi in Tokyo Dome*" snes9x multitap ; +"snes.Shin Nippon Pro Wrestling Kounin '95 - Tokyo Dome Battle 7*" snes9x multitap ; +"snes.Smash Tennis*" snes9x multitap ; +"snes.Sporting News, The - Power Baseball*" snes9x multitap ; +"snes.Sterling Sharpe End 2 End*" snes9x multitap ; +"snes.Street Hockey '95*" snes9x multitap ; +"snes.Street Racer*" snes9x multitap ; +"snes.Sugoi Hebereke*" snes9x multitap ; +"snes.Sugoro Quest++ Dicenics*" snes9x multitap ; +"snes.Super Bomberman - Panic Bomber W*" snes9x multitap ; +"snes.Super Bomberman 2*" snes9x multitap ; +"snes.Super Bomberman 3*" snes9x multitap ; +"snes.Super Bomberman 4*" snes9x multitap ; +"snes.Super Bomberman 5*" snes9x multitap ; +"snes.Super Bomberman*" snes9x multitap ; +"snes.Super Fire Pro Wrestling - Queen's Special*" snes9x multitap ; +"snes.Super Fire Pro Wrestling Special*" snes9x multitap ; +"snes.Super Fire Pro Wrestling X Premium*" snes9x multitap ; +"snes.Super Fire Pro Wrestling X*" snes9x multitap ; +"snes.Super Formation Soccer 94 - World Cup Final Data*" snes9x multitap ; +"snes.Super Formation Soccer 94*" snes9x multitap ; +"snes.Super Formation Soccer 95 della Serie A - UCC Xaqua*" snes9x multitap ; +"snes.Super Formation Soccer 95 della Serie A*" snes9x multitap ; +"snes.Super Formation Soccer 96*" snes9x multitap ; +"snes.Super Formation Soccer II*" snes9x multitap ; +"snes.Super Ice Hockey*" snes9x multitap ; +"snes.Super Kyousouba - Kaze no Sylphid*" snes9x multitap ; +"snes.Super Power League*" snes9x multitap ; +"snes.Super Tekkyuu Fight!*" snes9x multitap ; +"snes.Super Tetris 3*" snes9x multitap ; +"snes.Syndicate*" snes9x multitap ; +"snes.Tenryu Genichiro no Pro Wrestling Revolution*" snes9x multitap ; +"snes.Tiny Toon Adventures - Wild & Wacky Sports*" snes9x multitap ; +"snes.Top Gear 3000*" snes9x multitap ; +"snes.Turbo Toons*" snes9x multitap ; +"snes.Virtual Soccer*" snes9x multitap ; +"snes.Vs. Collection*" snes9x multitap ; +"snes.WWF Raw*" snes9x multitap ; +"snes.Yuujin no Furi Furi Girls*" snes9x multitap ; +"snes.Zero 4 Champ RR-Z*" snes9x multitap ; +"snes.Zero 4 Champ RR*" snes9x multitap ; + +# Defaults ; + +"gba.*" vba ; +"gbc.*" gambatte ; +"gb.*" gambatte ; +"gg.*" genplus ; +"nes.*" fceu ; +"pcecd.*" mednafen-pce-fast ; +"pce.*" mednafen-pce-fast ; +"ps1.*" mednafen-psx ; +"wswan.*" mednafen-wswan ; +"a26.*" stella ; +"scd.*" genplus ; +"sg1000.*" genplus ; +"smd.*" genplus ; +"sms.*" genplus ; +"snes.*" snes9x ; +"nds.*" desmume ; From 5c53c053e2d4f0c3004eb1af0fd03990c0cbe401 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sun, 24 Feb 2013 12:52:48 +0100 Subject: [PATCH 14/77] Plain overlay_next should always go to next. --- input/overlay.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/input/overlay.c b/input/overlay.c index 5225a28cdc..e3575fed95 100644 --- a/input/overlay.c +++ b/input/overlay.c @@ -417,6 +417,7 @@ input_overlay_t *input_overlay_new(const char *overlay) input_overlay_set_alpha_mod(ol, g_settings.input.overlay_opacity); input_overlay_set_scale_factor(ol, 1.0f); + ol->next_index = (ol->index + 1) % ol->size; return ol; @@ -506,6 +507,7 @@ void input_overlay_next(input_overlay_t *ol) ol->active->mod_x, ol->active->mod_y, ol->active->mod_w, ol->active->mod_h); ol->iface->full_screen(ol->iface_data, ol->active->full_screen); ol->blocked = true; + ol->next_index = (ol->index + 1) % ol->size; } bool input_overlay_full_screen(input_overlay_t *ol) From 883f799e74ae95731a3ef6584c738b6fa5a4f475 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 24 Feb 2013 23:55:48 +0100 Subject: [PATCH 15/77] (BB Playbook) Add initial example --- playbook/.cproject | 507 ++++++++ playbook/.project | 76 ++ .../org.eclipse.cdt.codan.core.prefs | 66 ++ playbook/bar-descriptor.xml | 107 ++ playbook/icon.png | Bin 0 -> 2941 bytes playbook/src/bbutil.c | 1051 +++++++++++++++++ playbook/src/bbutil.h | 132 +++ playbook/src/main.c | 366 ++++++ 8 files changed, 2305 insertions(+) create mode 100644 playbook/.cproject create mode 100644 playbook/.project create mode 100644 playbook/.settings/org.eclipse.cdt.codan.core.prefs create mode 100644 playbook/bar-descriptor.xml create mode 100644 playbook/icon.png create mode 100644 playbook/src/bbutil.c create mode 100644 playbook/src/bbutil.h create mode 100644 playbook/src/main.c diff --git a/playbook/.cproject b/playbook/.cproject new file mode 100644 index 0000000000..17e412a641 --- /dev/null +++ b/playbook/.cproject @@ -0,0 +1,507 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/playbook/.project b/playbook/.project new file mode 100644 index 0000000000..656b50ab7e --- /dev/null +++ b/playbook/.project @@ -0,0 +1,76 @@ + + + RetroArch + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + ?name? + + + + org.eclipse.cdt.make.core.append_environment + true + + + org.eclipse.cdt.make.core.buildArguments + + + + org.eclipse.cdt.make.core.buildCommand + make + + + org.eclipse.cdt.make.core.buildLocation + ${workspace_loc:/CubeRotate/Device-Debug} + + + org.eclipse.cdt.make.core.contents + org.eclipse.cdt.make.core.activeConfigSettings + + + org.eclipse.cdt.make.core.enableAutoBuild + false + + + org.eclipse.cdt.make.core.enableCleanBuild + true + + + org.eclipse.cdt.make.core.enableFullBuild + true + + + org.eclipse.cdt.make.core.stopOnError + true + + + org.eclipse.cdt.make.core.useDefaultBuildCmd + true + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + com.qnx.tools.bbt.xml.core.bbtXMLValidationBuilder + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + com.qnx.tools.ide.bbt.core.bbtnature + + diff --git a/playbook/.settings/org.eclipse.cdt.codan.core.prefs b/playbook/.settings/org.eclipse.cdt.codan.core.prefs new file mode 100644 index 0000000000..59043abc64 --- /dev/null +++ b/playbook/.settings/org.eclipse.cdt.codan.core.prefs @@ -0,0 +1,66 @@ +#Sun Feb 24 21:20:16 CET 2013 +eclipse.preferences.version=1 +org.eclipse.cdt.codan.checkers.errnoreturn=Warning +org.eclipse.cdt.codan.checkers.errnoreturn.params={implicit\=>false} +org.eclipse.cdt.codan.checkers.errreturnvalue=Error +org.eclipse.cdt.codan.checkers.errreturnvalue.params={} +org.eclipse.cdt.codan.checkers.noreturn=Error +org.eclipse.cdt.codan.checkers.noreturn.params={implicit\=>false} +org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=-Error +org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=-Error +org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning +org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={} +org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error +org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={} +org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning +org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={no_break_comment\=>"no break",last_case_param\=>true,empty_case_param\=>false} +org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning +org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={unknown\=>false,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=-Error +org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=-Error +org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=-Error +org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.internal.checkers.InvalidArguments=-Error +org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=-Error +org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=-Error +org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=-Error +org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=-Error +org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info +org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={pattern\=>"^[a-z]",macro\=>true,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning +org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={} +org.eclipse.cdt.codan.internal.checkers.OverloadProblem=-Error +org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=-Error +org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=-Error +org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={} +org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning +org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={} +org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning +org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={macro\=>true,exceptions\=>()} +org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning +org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={paramNot\=>false} +org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning +org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={else\=>false,afterelse\=>false} +org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=-Error +org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} +org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning +org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={macro\=>true} +org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning +org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={macro\=>true} +org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning +org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={macro\=>true,exceptions\=>("@(\#)","$Id")} +org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=-Error +org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>false,RUN_ON_INC_BUILD\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}} diff --git a/playbook/bar-descriptor.xml b/playbook/bar-descriptor.xml new file mode 100644 index 0000000000..d6e439dbcb --- /dev/null +++ b/playbook/bar-descriptor.xml @@ -0,0 +1,107 @@ + + + + + + + com.RetroArch + + + RetroArch + + + 1.0.0 + + + 1 + + + + + + Multi-emulator/multi-game system application + + + + + + Example Inc. + + + + + + none + false + + + + core.games + icon.png + + + + armle-v7 + RetroArch + + + armle-v7 + RetroArch + + + armle-v7 + RetroArch + + + armle-v7 + RetroArch + + + x86 + RetroArch + + + x86 + RetroArch + + + x86 + RetroArch + + + + + icon.png + + + + + + + run_native + + + + + + + + + + + + + + + + diff --git a/playbook/icon.png b/playbook/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a113106a99940f98c368dd477e702d7527565924 GIT binary patch literal 2941 zcmZuzc{r3`8-54b$yN~}293QGvP3Z$WQ`bP{p`)yvJNBJcY~& zNEvJ({${%OfH#8z>);Q)lYy=_aQ62rXfMkIN0@x{to;Gt64&1famye5y9h%7;y#>V zhMtpF;kMiI{15;zpCYvHJ_w$o*m-$pSzL}7RLb-4or1~8d;qSx6xq()OQfk{@2~y#tZOdR1mjq#C(6Am1H4{;kq zOw&j$G04Fc-(b}$A-?9T%G%fuR;#S6WL84WM9!k(23)n!Xt}6vVb_6|F%Rv-FTmk& zK;9ZgO1^0epJ{MA5BVsQbV;r>o{@MGkTJcuo7+zbP$7T&riH_gnjQ#<@V!(EsbALw zsv5%zV74JeFd3A!S<1X;^Pdw**P0Ugv8JSVr9h(0V^$a&<6 zgiDsTHh9Un=O)**aW{^_d>aFY)b^5}Uzd`TJ0Es0qa0CKB(L!jJ4Ys0h$#S%T6~^D zo3;6lkD+|bF{q)3!W<4@k>_RY<@6_rcM=HM=QU1z9za}&{u$U?9g4gC@)9|4@pH=5 zGZ+l!2#22w+M4Vhz$^J5ZqIIQZyUAdTvw)IufpsxyXWk&r%zCG9eLT=*|zPWgr+uN za%ALc23@)f7OP<&L0!(JJPM-_{(Ys+Y223`9v=Q$RL{#x3Lec#2|D=o%kTI8Iun~@ zePd%IBT++qnq*7xB*ia<9?k~sAO)cI!o=JDE4fW`omlM2C%E4-hzB7$byjGBE7PMO$T?&<EHwQCr`QeHiuVx*ipLG|EM@~&mIfW?eYbS06zGn^JO6F4tm9=XvUVc33-SmLZ z_M6IdGg=pX49E%2#p~lxd#od!$n+8BPR*a=6YuA{TxxVA(cnu)01zS$w)haWSHLowh!Zw=Q6Pv@=7RJEI!<^>lw_#kHxaNm7CTEqd-wwM{dsEWR4xNGz`> z$|uLVKb}Pe8NTP$2@Gty4GDa2mqWFB;~j>@p0#Mju~(#~vbWgEDhsfKpw4$arDcq{ zS32~)6RSZ_PhaP^+%E=FOG}s|a&9MXZb$bTPgMLzi>vH$w1MvhL0f3TcqNSi-L@M$ z-ZEZmpH`%s<}~seZVaxszrP;|)i*HMo$((cCG}l zp(wYhot?S}twz`{Z@@|@6DS!20K;5)#}+zw{@r8F-Ld3UDV4`lH-V!x4;7?@RpO^3 zhgL<=>mH-fhMR=cMH+J&9jEBtWWLO|bRW$JR2D7u;Ut02KKo>c{@2o@^Z`LZZqkqm z@IossJT#il&dxt^mU}A$3WPPh5?Y*S;(}^#Yf}?d7Y1&!J{uSq2uh)X5F;trqXh=s ziN%bv<|R;L&t(n8>SG{0i)L{e#~I4dh_F-FW7 zugC@pL7tTsIx;<7MTmmaombya-yJoObNmp^#KDOHb#%1VFoeT5k;o8H7`KE`a_GZY;|~< zOI-Luj>HW}k9yYgVQ<{hhZq*$jj@ViMlduvHjuZ2H8@h%v?+tbtE?6*3x}Nx4&OEp zJm-=WdR{2FSs{^AHCd8|d=QbJ8D^E$9UWID-q>lGnsUydlrVRMer?Yt(K4{RtGiLA z2*G;;N{jzA3$W2Wy9?^RyuSWM&6hyg9G2r>l%B6I6h>xeQ>q@;evoICwyuvxHHQUs zJk|cW12txs5%GHk1>HT|JV-`DLIQ(7xJeA#FiYs;!(n#X4;yU$N)=RXWDNd8T}5NBi}!Q(I;Kbz(t)qB*Pksl`OaVBB_3~TYs(4(8yibM zHZife-j;9I-#Dsu{?1W>W&6g4r;D3gRat(-<&cmNkfU+&4&?g(Og4I$H^&F?#+tsW z%;s`Op)TSF6t|+Y%@TzojtYx2IWJ~7b-xf1xYzf&bwN$U22s0L4 zm9W5ZATRMRY|zmAC)(|}Iwy%NR>Y$!PFp1GbJ?e?z+Y^34=W;2n5 z_&NfCwC^RU;QH0!8V?ulY>-FvWZVY*;`00jDNEKbZ1?xWf%mPglf%OWm-+cY{yH>I zUlr*i61zpy)S|#(E-xju`Pz|J?1g4zeAcy+LAwqNA9(ts^|E}F{ZB?Z8XuLs;Ejqh z6C{!u$HLa5obCD4@)I>D!C9pKA|E}@II)k#_j9PL;V~z#RXiaYk Vo0}$k%!9cxfPfomzq#iS^ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bbutil.h" + +#ifdef USING_GL11 +#include +#include +#elif defined(USING_GL20) +#include +#else +#error bbutil must be compiled with either USING_GL11 or USING_GL20 flags +#endif + +#include +#include FT_FREETYPE_H + +#include "png.h" + +EGLDisplay egl_disp; +EGLSurface egl_surf; + +static EGLConfig egl_conf; +static EGLContext egl_ctx; + +static screen_context_t screen_ctx; +static screen_window_t screen_win; +static screen_display_t screen_disp; +static int nbuffers = 2; +static int initialized = 0; + +#ifdef USING_GL20 +static GLuint text_rendering_program; +static int text_program_initialized = 0; +static GLint positionLoc; +static GLint texcoordLoc; +static GLint textureLoc; +static GLint colorLoc; +#endif + +struct font_t { + unsigned int font_texture; + float pt; + float advance[128]; + float width[128]; + float height[128]; + float tex_x1[128]; + float tex_x2[128]; + float tex_y1[128]; + float tex_y2[128]; + float offset_x[128]; + float offset_y[128]; + int initialized; +}; + + +static void +bbutil_egl_perror(const char *msg) { + static const char *errmsg[] = { + "function succeeded", + "EGL is not initialized, or could not be initialized, for the specified display", + "cannot access a requested resource", + "failed to allocate resources for the requested operation", + "an unrecognized attribute or attribute value was passed in an attribute list", + "an EGLConfig argument does not name a valid EGLConfig", + "an EGLContext argument does not name a valid EGLContext", + "the current surface of the calling thread is no longer valid", + "an EGLDisplay argument does not name a valid EGLDisplay", + "arguments are inconsistent", + "an EGLNativePixmapType argument does not refer to a valid native pixmap", + "an EGLNativeWindowType argument does not refer to a valid native window", + "one or more argument values are invalid", + "an EGLSurface argument does not name a valid surface configured for rendering", + "a power management event has occurred", + "unknown error code" + }; + + int message_index = eglGetError() - EGL_SUCCESS; + + if (message_index < 0 || message_index > 14) + message_index = 15; + + fprintf(stderr, "%s: %s\n", msg, errmsg[message_index]); +} + +int +bbutil_init_egl(screen_context_t ctx) { + int usage; + int format = SCREEN_FORMAT_RGBX8888; + EGLint interval = 1; + int rc, num_configs; + + EGLint attrib_list[]= { EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, 0, + EGL_NONE}; + +#ifdef USING_GL11 + usage = SCREEN_USAGE_OPENGL_ES1 | SCREEN_USAGE_ROTATION; + attrib_list[9] = EGL_OPENGL_ES_BIT; +#elif defined(USING_GL20) + usage = SCREEN_USAGE_OPENGL_ES2 | SCREEN_USAGE_ROTATION; + attrib_list[9] = EGL_OPENGL_ES2_BIT; + EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; +#else + fprintf(stderr, "bbutil should be compiled with either USING_GL11 or USING_GL20 -D flags\n"); + return EXIT_FAILURE; +#endif + + //Simple egl initialization + screen_ctx = ctx; + + egl_disp = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (egl_disp == EGL_NO_DISPLAY) { + bbutil_egl_perror("eglGetDisplay"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = eglInitialize(egl_disp, NULL, NULL); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglInitialize"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = eglBindAPI(EGL_OPENGL_ES_API); + + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglBindApi"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + if(!eglChooseConfig(egl_disp, attrib_list, &egl_conf, 1, &num_configs)) { + bbutil_terminate(); + return EXIT_FAILURE; + } + +#ifdef USING_GL20 + egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, attributes); +#elif defined(USING_GL11) + egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, NULL); +#endif + + if (egl_ctx == EGL_NO_CONTEXT) { + bbutil_egl_perror("eglCreateContext"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_create_window(&screen_win, screen_ctx); + if (rc) { + perror("screen_create_window"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_FORMAT, &format); + if (rc) { + perror("screen_set_window_property_iv(SCREEN_PROPERTY_FORMAT)"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage); + if (rc) { + perror("screen_set_window_property_iv(SCREEN_PROPERTY_USAGE)"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_DISPLAY, (void **)&screen_disp); + if (rc) { + perror("screen_get_window_property_pv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + int screen_resolution[2]; + + rc = screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, screen_resolution); + if (rc) { + perror("screen_get_display_property_iv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + int angle = atoi(getenv("ORIENTATION")); + + screen_display_mode_t screen_mode; + rc = screen_get_display_property_pv(screen_disp, SCREEN_PROPERTY_MODE, (void**)&screen_mode); + if (rc) { + perror("screen_get_display_property_pv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + int size[2]; + rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size); + if (rc) { + perror("screen_get_window_property_iv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + int buffer_size[2] = {size[0], size[1]}; + + if ((angle == 0) || (angle == 180)) { + if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) || + ((screen_mode.width < screen_mode.height) && (size[0] > size[1]))) { + buffer_size[1] = size[0]; + buffer_size[0] = size[1]; + } + } else if ((angle == 90) || (angle == 270)){ + if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) || + ((screen_mode.width < screen_mode.height && size[0] < size[1]))) { + buffer_size[1] = size[0]; + buffer_size[0] = size[1]; + } + } else { + fprintf(stderr, "Navigator returned an unexpected orientation angle.\n"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, buffer_size); + if (rc) { + perror("screen_set_window_property_iv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle); + if (rc) { + perror("screen_set_window_property_iv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = screen_create_window_buffers(screen_win, nbuffers); + if (rc) { + perror("screen_create_window_buffers"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL); + if (egl_surf == EGL_NO_SURFACE) { + bbutil_egl_perror("eglCreateWindowSurface"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglMakeCurrent"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + rc = eglSwapInterval(egl_disp, interval); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglSwapInterval"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + initialized = 1; + + return EXIT_SUCCESS; +} + +void +bbutil_terminate() { + //Typical EGL cleanup + if (egl_disp != EGL_NO_DISPLAY) { + eglMakeCurrent(egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + if (egl_surf != EGL_NO_SURFACE) { + eglDestroySurface(egl_disp, egl_surf); + egl_surf = EGL_NO_SURFACE; + } + if (egl_ctx != EGL_NO_CONTEXT) { + eglDestroyContext(egl_disp, egl_ctx); + egl_ctx = EGL_NO_CONTEXT; + } + if (screen_win != NULL) { + screen_destroy_window(screen_win); + screen_win = NULL; + } + eglTerminate(egl_disp); + egl_disp = EGL_NO_DISPLAY; + } + eglReleaseThread(); + + initialized = 0; +} + +void +bbutil_swap() { + int rc = eglSwapBuffers(egl_disp, egl_surf); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglSwapBuffers"); + } +} + +/* Finds the next power of 2 */ +static inline int +nextp2(int x) +{ + int val = 1; + while(val < x) val <<= 1; + return val; +} + +font_t* bbutil_load_font(const char* path, int point_size, int dpi) { + FT_Library library; + FT_Face face; + int c; + int i, j; + font_t* font; + + if (!initialized) { + fprintf(stderr, "EGL has not been initialized\n"); + return NULL; + } + + if (!path){ + fprintf(stderr, "Invalid path to font file\n"); + return NULL; + } + + if(FT_Init_FreeType(&library)) { + fprintf(stderr, "Error loading Freetype library\n"); + return NULL; + } + if (FT_New_Face(library, path,0,&face)) { + fprintf(stderr, "Error loading font %s\n", path); + return NULL; + } + + if(FT_Set_Char_Size ( face, point_size * 64, point_size * 64, dpi, dpi)) { + fprintf(stderr, "Error initializing character parameters\n"); + return NULL; + } + + font = (font_t*) malloc(sizeof(font_t)); + + if (!font) { + fprintf(stderr, "Unable to allocate memory for font structure\n"); + return NULL; + } + + font->initialized = 0; + font->pt = point_size; + + glGenTextures(1, &(font->font_texture)); + + //Let each glyph reside in 32x32 section of the font texture + int segment_size_x = 0, segment_size_y = 0; + int num_segments_x = 16; + int num_segments_y = 8; + + FT_GlyphSlot slot; + FT_Bitmap bmp; + int glyph_width, glyph_height; + + //First calculate the max width and height of a character in a passed font + for(c = 0; c < 128; c++) { + if(FT_Load_Char(face, c, FT_LOAD_RENDER)) { + fprintf(stderr, "FT_Load_Char failed\n"); + free(font); + return NULL; + } + + slot = face->glyph; + bmp = slot->bitmap; + + glyph_width = bmp.width; + glyph_height = bmp.rows; + + if (glyph_width > segment_size_x) { + segment_size_x = glyph_width; + } + + if (glyph_height > segment_size_y) { + segment_size_y = glyph_height; + } + } + + int font_tex_width = nextp2(num_segments_x * segment_size_x); + int font_tex_height = nextp2(num_segments_y * segment_size_y); + + int bitmap_offset_x = 0, bitmap_offset_y = 0; + + GLubyte* font_texture_data = (GLubyte*) calloc(2 * font_tex_width * font_tex_height, sizeof(GLubyte)); + + if (!font_texture_data) { + fprintf(stderr, "Failed to allocate memory for font texture\n"); + free(font); + return NULL; + } + + // Fill font texture bitmap with individual bmp data and record appropriate size, texture coordinates and offsets for every glyph + for(c = 0; c < 128; c++) { + if(FT_Load_Char(face, c, FT_LOAD_RENDER)) { + fprintf(stderr, "FT_Load_Char failed\n"); + free(font); + return NULL; + } + + slot = face->glyph; + bmp = slot->bitmap; + + glyph_width = bmp.width; + glyph_height = bmp.rows; + + div_t temp = div(c, num_segments_x); + + bitmap_offset_x = segment_size_x * temp.rem; + bitmap_offset_y = segment_size_y * temp.quot; + + for (j = 0; j < glyph_height; j++) { + for (i = 0; i < glyph_width; i++) { + font_texture_data[2 * ((bitmap_offset_x + i) + (j + bitmap_offset_y) * font_tex_width) + 0] = + font_texture_data[2 * ((bitmap_offset_x + i) + (j + bitmap_offset_y) * font_tex_width) + 1] = + (i >= bmp.width || j >= bmp.rows)? 0 : bmp.buffer[i + bmp.width * j]; + } + } + + font->advance[c] = (float)(slot->advance.x >> 6); + font->tex_x1[c] = (float)bitmap_offset_x / (float) font_tex_width; + font->tex_x2[c] = (float)(bitmap_offset_x + bmp.width) / (float)font_tex_width; + font->tex_y1[c] = (float)bitmap_offset_y / (float) font_tex_height; + font->tex_y2[c] = (float)(bitmap_offset_y + bmp.rows) / (float)font_tex_height; + font->width[c] = bmp.width; + font->height[c] = bmp.rows; + font->offset_x[c] = (float)slot->bitmap_left; + font->offset_y[c] = (float)((slot->metrics.horiBearingY-face->glyph->metrics.height) >> 6); + } + + glBindTexture(GL_TEXTURE_2D, font->font_texture); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, font_tex_width, font_tex_height, 0, GL_LUMINANCE_ALPHA , GL_UNSIGNED_BYTE, font_texture_data); + + free(font_texture_data); + + FT_Done_Face(face); + FT_Done_FreeType(library); + + font->initialized = 1; + return font; +} + +void bbutil_render_text(font_t* font, const char* msg, float x, float y, float r, float g, float b, float a) { + int i, c; + GLfloat *vertices; + GLfloat *texture_coords; + GLshort* indices; + + float pen_x = 0.0f; + + if (!font) { + fprintf(stderr, "Font must not be null\n"); + return; + } + + if (!font->initialized) { + fprintf(stderr, "Font has not been loaded\n"); + return; + } + + if (!msg) { + return; + } + + const int msg_len = strlen(msg); + + vertices = (GLfloat*) malloc(sizeof(GLfloat) * 8 * msg_len); + texture_coords = (GLfloat*) malloc(sizeof(GLfloat) * 8 * msg_len); + + indices = (GLshort*) malloc(sizeof(GLfloat) * 6 * msg_len); + + for(i = 0; i < msg_len; ++i) { + c = msg[i]; + + vertices[8 * i + 0] = x + pen_x + font->offset_x[c]; + vertices[8 * i + 1] = y + font->offset_y[c]; + vertices[8 * i + 2] = vertices[8 * i + 0] + font->width[c]; + vertices[8 * i + 3] = vertices[8 * i + 1]; + vertices[8 * i + 4] = vertices[8 * i + 0]; + vertices[8 * i + 5] = vertices[8 * i + 1] + font->height[c]; + vertices[8 * i + 6] = vertices[8 * i + 2]; + vertices[8 * i + 7] = vertices[8 * i + 5]; + + texture_coords[8 * i + 0] = font->tex_x1[c]; + texture_coords[8 * i + 1] = font->tex_y2[c]; + texture_coords[8 * i + 2] = font->tex_x2[c]; + texture_coords[8 * i + 3] = font->tex_y2[c]; + texture_coords[8 * i + 4] = font->tex_x1[c]; + texture_coords[8 * i + 5] = font->tex_y1[c]; + texture_coords[8 * i + 6] = font->tex_x2[c]; + texture_coords[8 * i + 7] = font->tex_y1[c]; + + indices[i * 6 + 0] = 4 * i + 0; + indices[i * 6 + 1] = 4 * i + 1; + indices[i * 6 + 2] = 4 * i + 2; + indices[i * 6 + 3] = 4 * i + 2; + indices[i * 6 + 4] = 4 * i + 1; + indices[i * 6 + 5] = 4 * i + 3; + + //Assume we are only working with typewriter fonts + pen_x += font->advance[c]; + } +#ifdef USING_GL11 + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glColor4f(r, g, b, a); + + glVertexPointer(2, GL_FLOAT, 0, vertices); + glTexCoordPointer(2, GL_FLOAT, 0, texture_coords); + glBindTexture(GL_TEXTURE_2D, font->font_texture); + + glDrawElements(GL_TRIANGLES, 6 * msg_len, GL_UNSIGNED_SHORT, indices); + + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); +#elif defined USING_GL20 + if (!text_program_initialized) { + GLint status; + + // Create shaders if this hasn't been done already + const char* v_source = + "precision mediump float;" + "attribute vec2 a_position;" + "attribute vec2 a_texcoord;" + "varying vec2 v_texcoord;" + "void main()" + "{" + " gl_Position = vec4(a_position, 0.0, 1.0);" + " v_texcoord = a_texcoord;" + "}"; + + const char* f_source = + "precision lowp float;" + "varying vec2 v_texcoord;" + "uniform sampler2D u_font_texture;" + "uniform vec4 u_col;" + "void main()" + "{" + " vec4 temp = texture2D(u_font_texture, v_texcoord);" + " gl_FragColor = u_col * temp;" + "}"; + + // Compile the vertex shader + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + + if (!vs) { + fprintf(stderr, "Failed to create vertex shader: %d\n", glGetError()); + return; + } else { + glShaderSource(vs, 1, &v_source, 0); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &status); + if (GL_FALSE == status) { + GLchar log[256]; + glGetShaderInfoLog(vs, 256, NULL, log); + + fprintf(stderr, "Failed to compile vertex shader: %s\n", log); + + glDeleteShader(vs); + } + } + + // Compile the fragment shader + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + + if (!fs) { + fprintf(stderr, "Failed to create fragment shader: %d\n", glGetError()); + return; + } else { + glShaderSource(fs, 1, &f_source, 0); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &status); + if (GL_FALSE == status) { + GLchar log[256]; + glGetShaderInfoLog(fs, 256, NULL, log); + + fprintf(stderr, "Failed to compile fragment shader: %s\n", log); + + glDeleteShader(vs); + glDeleteShader(fs); + + return; + } + } + + // Create and link the program + text_rendering_program = glCreateProgram(); + if (text_rendering_program) + { + glAttachShader(text_rendering_program, vs); + glAttachShader(text_rendering_program, fs); + glLinkProgram(text_rendering_program); + + glGetProgramiv(text_rendering_program, GL_LINK_STATUS, &status); + if (status == GL_FALSE) { + GLchar log[256]; + glGetProgramInfoLog(fs, 256, NULL, log); + + fprintf(stderr, "Failed to link text rendering shader program: %s\n", log); + + glDeleteProgram(text_rendering_program); + text_rendering_program = 0; + + return; + } + } else { + fprintf(stderr, "Failed to create a shader program\n"); + + glDeleteShader(vs); + glDeleteShader(fs); + return; + } + + // We don't need the shaders anymore - the program is enough + glDeleteShader(fs); + glDeleteShader(vs); + + glUseProgram(text_rendering_program); + + // Store the locations of the shader variables we need later + positionLoc = glGetAttribLocation(text_rendering_program, "a_position"); + texcoordLoc = glGetAttribLocation(text_rendering_program, "a_texcoord"); + textureLoc = glGetUniformLocation(text_rendering_program, "u_font_texture"); + colorLoc = glGetUniformLocation(text_rendering_program, "u_col"); + + text_program_initialized = 1; + } + + glEnable(GL_BLEND); + + //Map text coordinates from (0...surface width, 0...surface height) to (-1...1, -1...1) + //this make our vertex shader very simple and also works irrespective of orientation changes + EGLint surface_width, surface_height; + + eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width); + eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height); + + for(i = 0; i < 4 * msg_len; ++i) { + vertices[2 * i + 0] = 2 * vertices[2 * i + 0] / surface_width - 1.0f; + vertices[2 * i + 1] = 2 * vertices[2 * i + 1] / surface_height - 1.0f; + } + + //Render text + glUseProgram(text_rendering_program); + + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, font->font_texture); + glUniform1i(textureLoc, 0); + + glUniform4f(colorLoc, r, g, b, a); + + glEnableVertexAttribArray(positionLoc); + glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, vertices); + + glEnableVertexAttribArray(texcoordLoc); + glVertexAttribPointer(texcoordLoc, 2, GL_FLOAT, GL_FALSE, 0, texture_coords); + + //Draw the string + glDrawElements(GL_TRIANGLES, 6 * msg_len, GL_UNSIGNED_SHORT, indices); + + glDisableVertexAttribArray(positionLoc); + glDisableVertexAttribArray(texcoordLoc); +#else + fprintf(stderr, "bbutil should be compiled with either USING_GL11 or USING_GL20 -D flags\n"); +#endif + + free(vertices); + free(texture_coords); + free(indices); +} + +void bbutil_destroy_font(font_t* font) { + if (!font) { + return; + } + + glDeleteTextures(1, &(font->font_texture)); + + free(font); +} + +void bbutil_measure_text(font_t* font, const char* msg, float* width, float* height) { + int i, c; + + if (!msg) { + return; + } + + const int msg_len =strlen(msg); + + if (width) { + //Width of a text rectangle is a sum advances for every glyph in a string + *width = 0.0f; + + for(i = 0; i < msg_len; ++i) { + c = msg[i]; + *width += font->advance[c]; + } + } + + if (height) { + //Height of a text rectangle is a high of a tallest glyph in a string + *height = 0.0f; + + for(i = 0; i < msg_len; ++i) { + c = msg[i]; + + if (*height < font->height[c]) { + *height = font->height[c]; + } + } + } +} + +int bbutil_load_texture(const char* filename, int* width, int* height, float* tex_x, float* tex_y, unsigned int *tex) { + int i; + GLuint format; + //header for testing if it is a png + png_byte header[8]; + + if (!tex) { + return EXIT_FAILURE; + } + + //open file as binary + FILE *fp = fopen(filename, "rb"); + if (!fp) { + return EXIT_FAILURE; + } + + //read the header + fread(header, 1, 8, fp); + + //test if png + int is_png = !png_sig_cmp(header, 0, 8); + if (!is_png) { + fclose(fp); + return EXIT_FAILURE; + } + + //create png struct + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) { + fclose(fp); + return EXIT_FAILURE; + } + + //create png info struct + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); + fclose(fp); + return EXIT_FAILURE; + } + + //create png info struct + png_infop end_info = png_create_info_struct(png_ptr); + if (!end_info) { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); + fclose(fp); + return EXIT_FAILURE; + } + + //setup error handling (required without using custom error handlers above) + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + fclose(fp); + return EXIT_FAILURE; + } + + //init png reading + png_init_io(png_ptr, fp); + + //let libpng know you already read the first 8 bytes + png_set_sig_bytes(png_ptr, 8); + + // read all the info up to the image data + png_read_info(png_ptr, info_ptr); + + //variables to pass to get info + int bit_depth, color_type; + png_uint_32 image_width, image_height; + + // get info about png + png_get_IHDR(png_ptr, info_ptr, &image_width, &image_height, &bit_depth, &color_type, NULL, NULL, NULL); + + switch (color_type) + { + case PNG_COLOR_TYPE_RGBA: + format = GL_RGBA; + break; + case PNG_COLOR_TYPE_RGB: + format = GL_RGB; + break; + default: + fprintf(stderr,"Unsupported PNG color type (%d) for texture: %s", (int)color_type, filename); + fclose(fp); + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + return NULL; + } + + // Update the png info struct. + png_read_update_info(png_ptr, info_ptr); + + // Row size in bytes. + int rowbytes = png_get_rowbytes(png_ptr, info_ptr); + + // Allocate the image_data as a big block, to be given to opengl + png_byte *image_data = (png_byte*) malloc(sizeof(png_byte) * rowbytes * image_height); + + if (!image_data) { + //clean up memory and close stuff + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + fclose(fp); + return EXIT_FAILURE; + } + + //row_pointers is for pointing to image_data for reading the png with libpng + png_bytep *row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * image_height); + if (!row_pointers) { + //clean up memory and close stuff + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + free(image_data); + fclose(fp); + return EXIT_FAILURE; + } + + // set the individual row_pointers to point at the correct offsets of image_data + for (i = 0; i < image_height; i++) { + row_pointers[image_height - 1 - i] = image_data + i * rowbytes; + } + + //read the png into image_data through row_pointers + png_read_image(png_ptr, row_pointers); + + int tex_width, tex_height; + + tex_width = nextp2(image_width); + tex_height = nextp2(image_height); + + glGenTextures(1, tex); + glBindTexture(GL_TEXTURE_2D, (*tex)); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + if ((tex_width != image_width) || (tex_height != image_height) ) { + glTexImage2D(GL_TEXTURE_2D, 0, format, tex_width, tex_height, 0, format, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width, image_height, format, GL_UNSIGNED_BYTE, image_data); + } else { + glTexImage2D(GL_TEXTURE_2D, 0, format, tex_width, tex_height, 0, format, GL_UNSIGNED_BYTE, image_data); + } + + GLint err = glGetError(); + + //clean up memory and close stuff + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + free(image_data); + free(row_pointers); + fclose(fp); + + if (err == 0) { + //Return physical with and height of texture if pointers are not null + if(width) { + *width = image_width; + } + if (height) { + *height = image_height; + } + //Return modified texture coordinates if pointers are not null + if(tex_x) { + *tex_x = ((float) image_width - 0.5f) / ((float)tex_width); + } + if(tex_y) { + *tex_y = ((float) image_height - 0.5f) / ((float)tex_height); + } + return EXIT_SUCCESS; + } else { + fprintf(stderr, "GL error %i \n", err); + return EXIT_FAILURE; + } +} + +int bbutil_calculate_dpi(screen_context_t ctx) { + int rc; + int screen_phys_size[2]; + + rc = screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_PHYSICAL_SIZE, screen_phys_size); + if (rc) { + perror("screen_get_display_property_iv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + + //Simulator will return 0,0 for physical size of the screen, so use 170 as default dpi + if ((screen_phys_size[0] == 0) && (screen_phys_size[1] == 0)) { + return 170; + } else { + int screen_resolution[2]; + rc = screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, screen_resolution); + if (rc) { + perror("screen_get_display_property_iv"); + bbutil_terminate(); + return EXIT_FAILURE; + } + double diagonal_pixels = sqrt(screen_resolution[0] * screen_resolution[0] + screen_resolution[1] * screen_resolution[1]); + double diagonal_inches = 0.0393700787 * sqrt(screen_phys_size[0] * screen_phys_size[0] + screen_phys_size[1] * screen_phys_size[1]); + return (int)(diagonal_pixels / diagonal_inches + 0.5); + + } +} + +int bbutil_rotate_screen_surface(int angle) { + int rc, rotation, skip = 1, temp;; + EGLint interval = 1; + int size[2]; + + if ((angle != 0) && (angle != 90) && (angle != 180) && (angle != 270)) { + fprintf(stderr, "Invalid angle\n"); + return EXIT_FAILURE; + } + + rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &rotation); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + + rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + + switch (angle - rotation) { + case -270: + case -90: + case 90: + case 270: + temp = size[0]; + size[0] = size[1]; + size[1] = temp; + skip = 0; + break; + } + + if (!skip) { + rc = eglMakeCurrent(egl_disp, NULL, NULL, NULL); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglMakeCurrent"); + return EXIT_FAILURE; + } + + rc = eglDestroySurface(egl_disp, egl_surf); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglMakeCurrent"); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_SOURCE_SIZE, size); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL); + if (egl_surf == EGL_NO_SURFACE) { + bbutil_egl_perror("eglCreateWindowSurface"); + return EXIT_FAILURE; + } + + rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglMakeCurrent"); + return EXIT_FAILURE; + } + + rc = eglSwapInterval(egl_disp, interval); + if (rc != EGL_TRUE) { + bbutil_egl_perror("eglSwapInterval"); + return EXIT_FAILURE; + } + } + + rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle); + if (rc) { + perror("screen_set_window_property_iv"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/playbook/src/bbutil.h b/playbook/src/bbutil.h new file mode 100644 index 0000000000..a8362f91e2 --- /dev/null +++ b/playbook/src/bbutil.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2011-2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _UTILITY_H_INCLUDED +#define _UTILITY_H_INCLUDED + +#include +#include +#include + +extern EGLDisplay egl_disp; +extern EGLSurface egl_surf; + +typedef struct font_t font_t; + +#define BBUTIL_DEFAULT_FONT "/usr/fonts/font_repository/monotype/arial.ttf" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Initializes EGL + * + * @param libscreen context that will be used for EGL setup + * @return EXIT_SUCCESS if initialization succeeded otherwise EXIT_FAILURE + */ +int bbutil_init_egl(screen_context_t ctx); + +/** + * Terminates EGL + */ +void bbutil_terminate(); + +/** + * Swaps default bbutil window surface to the screen + */ +void bbutil_swap(); + +/** + * Loads the font from the specified font file. + * NOTE: should be called after a successful return from bbutil_init() or bbutil_init_egl() call + * @param font_file string indicating the absolute path of the font file + * @param point_size used for glyph generation + * @param dpi used for glyph generation + * @return pointer to font_t structure on success or NULL on failure + */ +font_t* bbutil_load_font(const char* font_file, int point_size, int dpi); + +/** + * Destroys the passed font + * @param font to be destroyed + */ +void bbutil_destroy_font(font_t* font); + +/** + * Renders the specified message using current font starting from the specified + * bottom left coordinates. + * NOTE: must be called after a successful return from bbutil_init() or bbutil_init_egl() call + + * + * @param font to use for rendering + * @param msg the message to display + * @param x, y position of the bottom-left corner of text string in world coordinate space + * @param rgba color for the text to render with + */ +void bbutil_render_text(font_t* font, const char* msg, float x, float y, float r, float g, float b, float a); + +/** + * Returns the non-scaled width and height of a string + * NOTE: must be called after a successful return from bbutil_init() or bbutil_init_egl() call + + * + * @param font to use for measurement of a string size + * @param msg the message to get the size of + * @param return pointer for width of a string + * @param return pointer for height of a string + */ +void bbutil_measure_text(font_t* font, const char* msg, float* width, float* height); + +/** + * Creates and loads a texture from a png file + * NOTE: must be called after a successful return from bbutil_init() or bbutil_init_egl() call + + * + * @param filename path to texture png + * @param return width of texture + * @param return height of texture + * @param return gl texture handle + * @return EXIT_SUCCESS if texture loading succeeded otherwise EXIT_FAILURE + */ + +int bbutil_load_texture(const char* filename, int* width, int* height, float* tex_x, float* tex_y, unsigned int* tex); + +/** + * Returns dpi for a given screen + + * + * @param ctx path libscreen context that corresponds to display of interest + * @return dpi for a given screen + */ + +int bbutil_calculate_dpi(screen_context_t ctx); + +/** + * Rotates the screen to a given angle + + * + * @param angle to rotate screen surface to, must by 0, 90, 180, or 270 + * @return EXIT_SUCCESS if texture loading succeeded otherwise EXIT_FAILURE + */ + +int bbutil_rotate_screen_surface(int angle); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/playbook/src/main.c b/playbook/src/main.c new file mode 100644 index 0000000000..b738e804c5 --- /dev/null +++ b/playbook/src/main.c @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2011-2012 Research In Motion Limited. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "bbutil.h" + +static GLfloat vertices[8]; +static GLfloat colors[16]; + +static GLuint program; + +static GLuint transformLoc; +static GLuint positionLoc; +static GLuint colorLoc; + +static GLfloat matrix[16] = {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1}; + +static GLuint vertexID; +static GLuint colorID; + +static screen_context_t screen_cxt; + + +void handleScreenEvent(bps_event_t *event) { + screen_event_t screen_event = screen_event_get_event(event); + + int screen_val; + screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &screen_val); + + switch (screen_val) { + case SCREEN_EVENT_MTOUCH_TOUCH: + case SCREEN_EVENT_MTOUCH_MOVE: + case SCREEN_EVENT_MTOUCH_RELEASE: + break; + } +} + +int initialize() { + //Initialize vertex and color data + vertices[0] = -0.25f; + vertices[1] = -0.25f; + + vertices[2] = 0.25f; + vertices[3] = -0.25f; + + vertices[4] = -0.25f; + vertices[5] = 0.25f; + + vertices[6] = 0.25f; + vertices[7] = 0.25f; + + colors[0] = 1.0f; + colors[1] = 0.0f; + colors[2] = 1.0f; + colors[3] = 1.0f; + + colors[4] = 1.0f; + colors[5] = 1.0f; + colors[6] = 0.0f; + colors[7] = 1.0f; + + colors[8] = 0.0f; + colors[9] = 1.0f; + colors[10] = 1.0f; + colors[11] = 1.0f; + + colors[12] = 0.0f; + colors[13] = 1.0f; + colors[14] = 1.0f; + colors[15] = 1.0f; + + //Query width and height of the window surface created by utility code + EGLint surface_width, surface_height; + + eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width); + eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height); + + // Create shaders + const char* vSource = + "precision mediump float;" + "uniform mat4 u_projection;" + "uniform mat4 u_transform;" + "attribute vec4 a_position;" + "attribute vec4 a_color;" + "varying vec4 v_color;" + "void main()" + "{" + " gl_Position = u_projection * u_transform * a_position;" + " v_color = a_color;" + "}"; + + const char* fSource = + "varying lowp vec4 v_color;" + "void main()" + "{" + " gl_FragColor = v_color;" + "}"; + + GLint status; + + // Compile the vertex shader + GLuint vs = glCreateShader(GL_VERTEX_SHADER); + if (!vs) { + fprintf(stderr, "Failed to create vertex shader: %d\n", glGetError()); + return EXIT_FAILURE; + } else { + glShaderSource(vs, 1, &vSource, 0); + glCompileShader(vs); + glGetShaderiv(vs, GL_COMPILE_STATUS, &status); + if (GL_FALSE == status) { + GLchar log[256]; + glGetShaderInfoLog(vs, 256, NULL, log); + + fprintf(stderr, "Failed to compile vertex shader: %s\n", log); + + glDeleteShader(vs); + } + } + + // Compile the fragment shader + GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); + if (!fs) { + fprintf(stderr, "Failed to create fragment shader: %d\n", glGetError()); + return EXIT_FAILURE; + } else { + glShaderSource(fs, 1, &fSource, 0); + glCompileShader(fs); + glGetShaderiv(fs, GL_COMPILE_STATUS, &status); + if (GL_FALSE == status) { + GLchar log[256]; + glGetShaderInfoLog(fs, 256, NULL, log); + + fprintf(stderr, "Failed to compile fragment shader: %s\n", log); + + glDeleteShader(vs); + glDeleteShader(fs); + + return EXIT_FAILURE; + } + } + + // Create and link the program + program = glCreateProgram(); + if (program) + { + glAttachShader(program, vs); + glAttachShader(program, fs); + glLinkProgram(program); + + glGetProgramiv(program, GL_LINK_STATUS, &status); + if (status == GL_FALSE) { + GLchar log[256]; + glGetProgramInfoLog(fs, 256, NULL, log); + + fprintf(stderr, "Failed to link shader program: %s\n", log); + + glDeleteProgram(program); + program = 0; + + return EXIT_FAILURE; + } + } else { + fprintf(stderr, "Failed to create a shader program\n"); + + glDeleteShader(vs); + glDeleteShader(fs); + return EXIT_FAILURE; + } + + glUseProgram(program); + + // Set up the orthographic projection - equivalent to glOrtho in GLES1 + GLuint projectionLoc = glGetUniformLocation(program, "u_projection"); + { + GLfloat left = 0.0f; + GLfloat right = (float)(surface_width) / (float)(surface_height); + GLfloat bottom = 0.0f; + GLfloat top = 1.0f; + GLfloat zNear = -1.0f; + GLfloat zFar = 1.0f; + GLfloat ortho[16] = {2.0 / (right-left), 0, 0, 0, + 0, 2.0 / (top-bottom), 0, 0, + 0, 0, -2.0 / (zFar - zNear), 0, + -(right+left)/(right-left), -(top+bottom)/(top-bottom), -(zFar+zNear)/(zFar-zNear), 1}; + glUniformMatrix4fv(projectionLoc, 1, false, ortho); + } + + // Store the locations of the shader variables we need later + transformLoc = glGetUniformLocation(program, "u_transform"); + positionLoc = glGetAttribLocation(program, "a_position"); + colorLoc = glGetAttribLocation(program, "a_color"); + + // We don't need the shaders anymore - the program is enough + glDeleteShader(fs); + glDeleteShader(vs); + + // Generate vertex and color buffers and fill with data + glGenBuffers(1, &vertexID); + glBindBuffer(GL_ARRAY_BUFFER, vertexID); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + glGenBuffers(1, &colorID); + glBindBuffer(GL_ARRAY_BUFFER, colorID); + glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW); + + // Perform the same translation as the GLES1 version + matrix[12] = (float)(surface_width) / (float)(surface_height) / 2; + matrix[13] = 0.5; + glUniformMatrix4fv(transformLoc, 1, false, matrix); + + return EXIT_SUCCESS; +} + +void render() { + // Increment the angle by 0.5 degrees + static float angle = 0.0f; + angle += 0.5f * M_PI / 180.0f; + + //Typical render pass + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Enable and bind the vertex information + glEnableVertexAttribArray(positionLoc); + glBindBuffer(GL_ARRAY_BUFFER, vertexID); + glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0); + + // Enable and bind the color information + glEnableVertexAttribArray(colorLoc); + glBindBuffer(GL_ARRAY_BUFFER, colorID); + glVertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), 0); + + // Effectively apply a rotation of angle about the y-axis. + matrix[0] = cos(angle); + matrix[2] = -sin(angle); + matrix[8] = sin(angle); + matrix[10] = cos(angle); + glUniformMatrix4fv(transformLoc, 1, false, matrix); + + // Same draw call as in GLES1. + glDrawArrays(GL_TRIANGLE_STRIP, 0 , 4); + + // Disable attribute arrays + glDisableVertexAttribArray(positionLoc); + glDisableVertexAttribArray(colorLoc); + + bbutil_swap(); +} + +int main(int argc, char *argv[]) { + int rc; + int exit_application = 0; + + //Create a screen context that will be used to create an EGL surface to to receive libscreen events + screen_create_context(&screen_cxt, 0); + + //Initialize BPS library + bps_initialize(); + + //Use utility code to initialize EGL for rendering with GL ES 2.0 + if (EXIT_SUCCESS != bbutil_init_egl(screen_cxt)) { + fprintf(stderr, "bbutil_init_egl failed\n"); + bbutil_terminate(); + screen_destroy_context(screen_cxt); + return 0; + } + + //Initialize application logic + if (EXIT_SUCCESS != initialize()) { + fprintf(stderr, "initialize failed\n"); + bbutil_terminate(); + screen_destroy_context(screen_cxt); + bps_shutdown(); + return 0; + } + + //Signal BPS library that navigator and screen events will be requested + if (BPS_SUCCESS != screen_request_events(screen_cxt)) { + fprintf(stderr, "screen_request_events failed\n"); + bbutil_terminate(); + screen_destroy_context(screen_cxt); + bps_shutdown(); + return 0; + } + + if (BPS_SUCCESS != navigator_request_events(0)) { + fprintf(stderr, "navigator_request_events failed\n"); + bbutil_terminate(); + screen_destroy_context(screen_cxt); + bps_shutdown(); + return 0; + } + + //Signal BPS library that navigator orientation is not to be locked + if (BPS_SUCCESS != navigator_rotation_lock(false)) { + fprintf(stderr, "navigator_rotation_lock failed\n"); + bbutil_terminate(); + screen_destroy_context(screen_cxt); + bps_shutdown(); + return 0; + } + + while (!exit_application) { + //Request and process all available BPS events + bps_event_t *event = NULL; + + for(;;) { + rc = bps_get_event(&event, 0); + assert(rc == BPS_SUCCESS); + + if (event) { + int domain = bps_event_get_domain(event); + + if (domain == screen_get_domain()) { + handleScreenEvent(event); + } else if ((domain == navigator_get_domain()) + && (NAVIGATOR_EXIT == bps_event_get_code(event))) { + exit_application = 1; + } + } else { + break; + } + } + render(); + } + + //Stop requesting events from libscreen + screen_stop_events(screen_cxt); + + //Shut down BPS library for this process + bps_shutdown(); + + //Use utility code to terminate EGL setup + bbutil_terminate(); + + //Destroy libscreen context + screen_destroy_context(screen_cxt); + return 0; +} From a86792c016ac12bfcf81813b489cd353690d5fad Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 25 Feb 2013 00:01:56 +0100 Subject: [PATCH 16/77] (Playbook) Take out USING_GL11 --- playbook/src/bbutil.c | 45 +------------------------------------------ 1 file changed, 1 insertion(+), 44 deletions(-) diff --git a/playbook/src/bbutil.c b/playbook/src/bbutil.c index 0e56eab62b..239fcb1b44 100644 --- a/playbook/src/bbutil.c +++ b/playbook/src/bbutil.c @@ -26,14 +26,7 @@ #include "bbutil.h" -#ifdef USING_GL11 -#include -#include -#elif defined(USING_GL20) #include -#else -#error bbutil must be compiled with either USING_GL11 or USING_GL20 flags -#endif #include #include FT_FREETYPE_H @@ -120,17 +113,9 @@ bbutil_init_egl(screen_context_t ctx) { EGL_RENDERABLE_TYPE, 0, EGL_NONE}; -#ifdef USING_GL11 - usage = SCREEN_USAGE_OPENGL_ES1 | SCREEN_USAGE_ROTATION; - attrib_list[9] = EGL_OPENGL_ES_BIT; -#elif defined(USING_GL20) usage = SCREEN_USAGE_OPENGL_ES2 | SCREEN_USAGE_ROTATION; attrib_list[9] = EGL_OPENGL_ES2_BIT; EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; -#else - fprintf(stderr, "bbutil should be compiled with either USING_GL11 or USING_GL20 -D flags\n"); - return EXIT_FAILURE; -#endif //Simple egl initialization screen_ctx = ctx; @@ -162,11 +147,7 @@ bbutil_init_egl(screen_context_t ctx) { return EXIT_FAILURE; } -#ifdef USING_GL20 - egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, attributes); -#elif defined(USING_GL11) - egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, NULL); -#endif + egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, attributes); if (egl_ctx == EGL_NO_CONTEXT) { bbutil_egl_perror("eglCreateContext"); @@ -539,28 +520,7 @@ void bbutil_render_text(font_t* font, const char* msg, float x, float y, float r //Assume we are only working with typewriter fonts pen_x += font->advance[c]; } -#ifdef USING_GL11 - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - glColor4f(r, g, b, a); - - glVertexPointer(2, GL_FLOAT, 0, vertices); - glTexCoordPointer(2, GL_FLOAT, 0, texture_coords); - glBindTexture(GL_TEXTURE_2D, font->font_texture); - - glDrawElements(GL_TRIANGLES, 6 * msg_len, GL_UNSIGNED_SHORT, indices); - - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); -#elif defined USING_GL20 if (!text_program_initialized) { GLint status; @@ -711,9 +671,6 @@ void bbutil_render_text(font_t* font, const char* msg, float x, float y, float r glDisableVertexAttribArray(positionLoc); glDisableVertexAttribArray(texcoordLoc); -#else - fprintf(stderr, "bbutil should be compiled with either USING_GL11 or USING_GL20 -D flags\n"); -#endif free(vertices); free(texture_coords); From 343a85c6dc8e0d15133c2c35a692c4fbf80ae7a5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 25 Feb 2013 01:19:12 +0100 Subject: [PATCH 17/77] (Playbook) Add Playbook ifdefs - cut down on compilation errors --- console/griffin/griffin.c | 10 ++- file_path.c | 2 +- general.h | 4 +- playbook/.cproject | 181 ++++++++++++++++++++++++++++++++++---- playbook/.project | 9 +- playbook/src/bbutil.c | 2 - playbook/src/main.c | 1 - 7 files changed, 183 insertions(+), 26 deletions(-) diff --git a/console/griffin/griffin.c b/console/griffin/griffin.c index b66d5101e5..0c0bf4ddef 100644 --- a/console/griffin/griffin.c +++ b/console/griffin/griffin.c @@ -194,11 +194,9 @@ FONTS #if defined(HAVE_OPENGL) || defined(HAVE_D3D8) || defined(HAVE_D3D9) -#ifdef HAVE_FREETYPE +#if defined(HAVE_FREETYPE) #include "../../gfx/fonts/freetype.c" -#endif - -#ifndef DONT_HAVE_BITMAPFONTS +#elif !defined(DONT_HAVE_BITMAPFONTS) #include "../../gfx/fonts/fonts.c" #include "../../gfx/fonts/bitmapfont.c" #endif @@ -315,6 +313,10 @@ AUDIO #include "../../audio/opensl.c" #endif +#ifdef HAVE_AL +#include "../../audio/openal.c" +#endif + #if defined(HAVE_NULLAUDIO) #include "../../audio/null.c" #endif diff --git a/file_path.c b/file_path.c index 8bc72c36c2..38600c2921 100644 --- a/file_path.c +++ b/file_path.c @@ -22,7 +22,7 @@ #include "compat/strl.h" #include "compat/posix_string.h" -#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) +#if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) || defined(__BLACKBERRY_QNX__) #include //stat() is defined here #define S_ISDIR(x) (x & CELL_FS_S_IFDIR) #endif diff --git a/general.h b/general.h index 4974b57621..e415eec7d3 100644 --- a/general.h +++ b/general.h @@ -67,7 +67,7 @@ #endif // Wii and PSL1GHT - for usleep (among others) -#if defined(GEKKO) || defined(__PSL1GHT__) +#if defined(GEKKO) || defined(__PSL1GHT__) || defined(__BLACKBERRY_QNX__) #include #endif @@ -760,7 +760,7 @@ static inline void rarch_sleep(unsigned msec) Sleep(msec); #elif defined(XENON) udelay(1000 * msec); -#elif defined(GEKKO) || defined(__PSL1GHT__) +#elif defined(GEKKO) || defined(__PSL1GHT__) || defined(__BLACKBERRY_QNX__) usleep(1000 * msec); #else struct timespec tv = {0}; diff --git a/playbook/.cproject b/playbook/.cproject index 17e412a641..5bf8be03cb 100644 --- a/playbook/.cproject +++ b/playbook/.cproject @@ -20,7 +20,7 @@