diff --git a/android/bifrost.c b/android/bifrost.c
deleted file mode 100644
index 50bffa97ef..0000000000
--- a/android/bifrost.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/* RetroArch - A frontend for libretro.
- * Copyright (C) 2010-2012 - Hans-Kristian Arntzen
- * Copyright (C) 2011-2012 - Daniel De Matteis
- *
- * RetroArch is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Found-
- * ation, either version 3 of the License, or (at your option) any later version.
- *
- * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with RetroArch.
- * If not, see .
- */
-
-/* RetroArch Bifrost:
- * A burning rainbow bridge that reaches between Java (the world)
- * and C/C++, the realm of the gods */
-
-#include
-#include
-#include "../boolean.h"
-
-#include "com_retroarch_rruntime.h"
-
-#include "../console/rarch_console.h"
-#include "../../console/rarch_console_config.h"
-#include "../console/rarch_console_main_wrap.h"
-#include "../console/rarch_console_rom_ext.h"
-#include "../console/rarch_console_settings.h"
-#include "../console/rarch_console_input.h"
-#include "../console/rarch_console_video.h"
-#include "../general.h"
-#include "../conf/config_file.h"
-#include "../conf/config_file_macros.h"
-#include "../file.h"
-
-JNIEXPORT jint JNICALL JNI_OnLoad( JavaVM *vm, void *pvt)
-{
- RARCH_LOG("JNI_OnLoad.\n" );
-
- rarch_main_clear_state();
-
- config_set_defaults();
- input_null.init();
-
- RARCH_LOG("JNI_OnLoad #1.\n" );
-
- const input_driver_t *input = &input_null;
-
- bool find_libretro_file = false;
-
- snprintf(default_paths.config_file, sizeof(default_paths.config_file), "/mnt/extsd/retroarch.cfg");
-
- RARCH_LOG("JNI_OnLoad #1.1.\n" );
-
- rarch_init_msg_queue();
-
- RARCH_LOG("JNI_OnLoad #1.2.\n" );
-
- rarch_settings_set_default();
-
- RARCH_LOG("JNI_OnLoad #1.3.\n" );
- //rarch_input_set_controls_default(input);
- rarch_config_load(default_paths.config_file, find_libretro_file);
-
- RARCH_LOG("JNI_OnLoad #1.4.\n" );
- init_libretro_sym();
-
- RARCH_LOG("JNI_OnLoad #1.5.\n" );
-
-
- input_null.post_init();
- RARCH_LOG("JNI_OnLoad #1.6.\n" );
-
- //video_gl.start();
-
- RARCH_LOG("JNI_OnLoad #1.7.\n" );
-
- //driver.video = &video_gl;
-
- RARCH_LOG("JNI_OnLoad #1.8.\n" );
-
- RARCH_LOG("Reached end of JNI_OnLoad.\n" );
-
- return JNI_VERSION_1_2;
-}
-
-JNIEXPORT void JNICALL JNI_OnUnLoad( JavaVM *vm, void *pvt)
-{
- RARCH_LOG("JNI_OnUnLoad.\n" );
-}
-
-JNIEXPORT void JNICALL Java_com_retroarch_rruntime_load_1game
- (JNIEnv *env, jclass class, jstring j_path, jint j_extract_zip_mode)
-{
- jboolean is_copy = false;
- const char * game_path = (*env)->GetStringUTFChars(env, j_path, &is_copy);
- RARCH_LOG("rruntime_load_game: %s.\n", game_path);
-
- rarch_console_load_game_wrap(game_path, 0, 0);
-
- (*env)->ReleaseStringUTFChars(env, j_path, game_path);
-}
-
-static int counter = 0;
-
-JNIEXPORT jboolean JNICALL Java_com_retroarch_rruntime_run_1frame
- (JNIEnv *env, jclass class)
-{
- counter++;
- RARCH_LOG("counter: %d.\n", counter);
- return rarch_main_iterate();
-}
-
-JNIEXPORT void JNICALL Java_com_retroarch_rruntime_startup
- (JNIEnv *env, jclass class, jstring j_config_path)
-{
- bool retval = false;
- jboolean is_copy = false;
- const char * config_path = (*env)->GetStringUTFChars(env, j_config_path, &is_copy);
-
- RARCH_LOG("rruntime_startup (config file: %s).\n", config_path);
-
- retval = rarch_startup(config_path);
-
- rarch_init_msg_queue();
-
- (*env)->ReleaseStringUTFChars(env, j_config_path, config_path);
-}
-
-JNIEXPORT void JNICALL Java_com_retroarch_rruntime_deinit
- (JNIEnv *env, jclass class)
-{
- rarch_main_deinit();
-}
-
-JNIEXPORT void JNICALL Java_com_retroarch_rruntime_load_1state
- (JNIEnv *env, jclass class)
-{
- rarch_load_state();
-}
-
-JNIEXPORT void JNICALL Java_com_retroarch_rruntime_save_1state
- (JNIEnv *env, jclass class)
-{
- rarch_save_state();
-}
-
-JNIEXPORT void JNICALL Java_com_retroarch_rruntime_settings_1change
- (JNIEnv *env, jclass class, jint j_setting)
-{
- unsigned setting = j_setting;
- rarch_settings_change(setting);
-}
-
-JNIEXPORT void JNICALL Java_com_retroarch_rruntime_settings_1set_1defaults
- (JNIEnv *env, jclass class)
-{
- RARCH_LOG("* rruntime_settings_set_defaults.\n" );
- rarch_settings_set_default();
-}
-
-void gfx_ctx_set_window(JNIEnv *jenv,jobject obj, jobject surface);
-void gfx_ctx_free_window(JNIEnv *jenv,jobject obj, jobject surface);
-
-JNIEXPORT void JNICALL Java_com_retroarch_rruntime_set_window
- (JNIEnv *env, jclass class, jobject obj, jobject surface)
-{
- gfx_ctx_set_window(env, obj, surface);
-}
-
-JNIEXPORT void JNICALL Java_com_retroarch_rruntime_free_window
- (JNIEnv *env, jclass class, jobject obj, jobject surface)
-{
- gfx_ctx_free_window(env, obj, surface);
-}
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
index 2ddcdb0d5a..acc182a206 100644
--- a/android/jni/Android.mk
+++ b/android/jni/Android.mk
@@ -6,10 +6,48 @@ include $(CLEAR_VARS)
APP_OPTIM := debug
LOCAL_MODULE := retroarch
-LOCAL_SRC_FILES = ../../console/griffin/griffin.c ../../console/rzlib/rzlib.c ../bifrost.c
+LOCAL_SRC_FILES = ../../retroarch.c \
+ ../../file.c \
+ ../../file_path.c \
+ ../../hash.c \
+ ../../driver.c \
+ ../../settings.c \
+ ../../dynamic.c \
+ ../../message.c \
+ ../../rewind.c \
+ ../../gfx/gfx_common.c \
+ ../../input/input_common.c \
+ ../../patch.c \
+ ../../fifo_buffer.c \
+ ../../compat/compat.c \
+ ../../audio/null.c \
+ ../../audio/utils.c \
+ ../../audio/hermite.c \
+ ../../gfx/null.c \
+ ../../gfx/gl.c \
+ ../../gfx/scaler/scaler.c \
+ ../../gfx/scaler/pixconv.c \
+ ../../gfx/scaler/scaler_int.c \
+ ../../gfx/scaler/filter.c \
+ ../../gfx/gfx_context.c \
+ ../../gfx/context/androidegl_ctx.c \
+ ../../gfx/math/matrix.c \
+ ../../gfx/shader_glsl.c \
+ ../../gfx/fonts/null_fonts.c \
+ ../../gfx/state_tracker.c \
+ ../../input/null.c \
+ ../../screenshot.c \
+ ../../conf/config_file.c \
+ ../../autosave.c \
+ ../../thread.c \
+ ../../console/rzlib/rzlib.c \
+ main.c
-LOCAL_CFLAGS = -DPERF_TEST -marm -DANDROID -DHAVE_DYNAMIC -DHAVE_DYLIB -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_GLSL -DHAVE_VID_CONTEXT -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DINLINE=inline -DRARCH_CONSOLE -DLSB_FIRST -D__LIBRETRO__ -DHAVE_CONFIGFILE=1 -DHAVE_GRIFFIN=1 -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -Dmain=rarch_main -std=gnu99
+LOCAL_CFLAGS = -marm -DANDROID -DHAVE_DYNAMIC -DHAVE_OPENGL -DHAVE_OPENGLES -DHAVE_OPENGLES2 -DHAVE_GLSL -DHAVE_ZLIB -DHAVE_RARCH_MAIN_WRAP -DINLINE=inline -DLSB_FIRST -D__LIBRETRO__ -DHAVE_CONFIGFILE=1 -DPACKAGE_VERSION=\"$(RARCH_VERSION)\" -std=gnu99
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -landroid -lEGL -lGLESv2 -llog -ldl -lz
+LOCAL_STATIC_LIBRARIES := android_native_app_glue
include $(BUILD_SHARED_LIBRARY)
+
+$(call import-module,android/native_app_glue)
diff --git a/android/jni/main.c b/android/jni/main.c
new file mode 100644
index 0000000000..75391de305
--- /dev/null
+++ b/android/jni/main.c
@@ -0,0 +1,322 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2010-2012 - Hans-Kristian Arntzen
+ * Copyright (C) 2011-2012 - Daniel De Matteis
+ *
+ * RetroArch is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with RetroArch.
+ * If not, see .
+ */
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+
+#include "../../general.h"
+
+JNIEXPORT jint JNICALL JNI_OnLoad( JavaVM *vm, void *pvt)
+{
+ RARCH_LOG("JNI_OnLoad.\n" );
+
+ return JNI_VERSION_1_2;
+}
+
+JNIEXPORT void JNICALL JNI_OnUnLoad( JavaVM *vm, void *pvt)
+{
+ RARCH_LOG("JNI_OnUnLoad.\n" );
+}
+
+/**
+ * Our saved state data.
+ */
+struct saved_state
+{
+ float angle;
+ int32_t x;
+ int32_t y;
+};
+
+/**
+ * Shared state for our app.
+ */
+struct engine
+{
+ struct android_app* app;
+
+ ASensorManager* sensorManager;
+ const ASensor* accelerometerSensor;
+ ASensorEventQueue* sensorEventQueue;
+
+ int animating;
+ EGLDisplay display;
+ EGLSurface surface;
+ EGLContext context;
+ int32_t width;
+ int32_t height;
+ struct saved_state state;
+};
+
+/**
+ * Initialize an EGL context for the current display.
+ */
+static int engine_init_display(struct engine* engine)
+{
+ // initialize OpenGL ES and EGL
+
+ const EGLint attribs[] =
+ {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_BLUE_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_RED_SIZE, 8,
+ EGL_NONE
+ };
+ EGLint w, h, dummy, format;
+ EGLint numConfigs;
+ EGLConfig config;
+ EGLSurface surface;
+ EGLContext context;
+
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+
+ eglInitialize(display, 0, 0);
+
+ /* Here, the application chooses the configuration it desires. In this
+ * sample, we have a very simplified selection process, where we pick
+ * the first EGLConfig that matches our criteria */
+ eglChooseConfig(display, attribs, &config, 1, &numConfigs);
+
+ /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
+ * guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
+ * As soon as we picked a EGLConfig, we can safely reconfigure the
+ * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
+ eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
+
+ ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format);
+
+ surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);
+ context = eglCreateContext(display, config, NULL, NULL);
+
+ if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
+ {
+ RARCH_ERR("Unable to eglMakeCurrent.\n");
+ return -1;
+ }
+
+ eglQuerySurface(display, surface, EGL_WIDTH, &w);
+ eglQuerySurface(display, surface, EGL_HEIGHT, &h);
+
+ engine->display = display;
+ engine->context = context;
+ engine->surface = surface;
+ engine->width = w;
+ engine->height = h;
+ engine->state.angle = 0;
+
+ // Initialize GL state.
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+ glEnable(GL_CULL_FACE);
+ glDisable(GL_DEPTH_TEST);
+
+ return 0;
+}
+
+/**
+ * Just the current frame in the display.
+ */
+static void engine_draw_frame(struct engine* engine)
+{
+ if (engine->display == NULL)
+ return;
+
+ // Just fill the screen with a color.
+ glClearColor(((float)engine->state.x)/engine->width, engine->state.angle,
+ ((float)engine->state.y)/engine->height, 1);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ eglSwapBuffers(engine->display, engine->surface);
+}
+
+/**
+ * Tear down the EGL context currently associated with the display.
+ */
+static void engine_term_display(struct engine* engine)
+{
+ if (engine->display != EGL_NO_DISPLAY)
+ {
+ eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+ if (engine->context != EGL_NO_CONTEXT)
+ eglDestroyContext(engine->display, engine->context);
+ if (engine->surface != EGL_NO_SURFACE)
+ eglDestroySurface(engine->display, engine->surface);
+
+ eglTerminate(engine->display);
+ }
+ engine->animating = 0;
+ engine->display = EGL_NO_DISPLAY;
+ engine->context = EGL_NO_CONTEXT;
+ engine->surface = EGL_NO_SURFACE;
+}
+
+/**
+ * Process the next input event.
+ */
+static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
+{
+ struct engine* engine = (struct engine*)app->userData;
+
+ if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION)
+ {
+ engine->animating = 1;
+ engine->state.x = AMotionEvent_getX(event, 0);
+ engine->state.y = AMotionEvent_getY(event, 0);
+ return 1;
+ }
+ return 0;
+}
+
+/**
+ * Process the next main command.
+ */
+static void engine_handle_cmd(struct android_app* app, int32_t cmd)
+{
+ struct engine* engine = (struct engine*)app->userData;
+
+ switch (cmd)
+ {
+ case APP_CMD_SAVE_STATE:
+ // The system has asked us to save our current state. Do so.
+ engine->app->savedState = malloc(sizeof(struct saved_state));
+ *((struct saved_state*)engine->app->savedState) = engine->state;
+ engine->app->savedStateSize = sizeof(struct saved_state);
+ break;
+ case APP_CMD_INIT_WINDOW:
+ // The window is being shown, get it ready.
+ if (engine->app->window != NULL)
+ {
+ engine_init_display(engine);
+ engine_draw_frame(engine);
+ }
+ break;
+ case APP_CMD_TERM_WINDOW:
+ // The window is being hidden or closed, clean it up.
+ engine_term_display(engine);
+ break;
+ case APP_CMD_GAINED_FOCUS:
+ // When our app gains focus, we start monitoring the accelerometer.
+ if (engine->accelerometerSensor != NULL)
+ {
+ ASensorEventQueue_enableSensor(engine->sensorEventQueue,
+ engine->accelerometerSensor);
+
+ // We'd like to get 60 events per second (in us).
+ ASensorEventQueue_setEventRate(engine->sensorEventQueue,
+ engine->accelerometerSensor, (1000L/60)*1000);
+ }
+ break;
+ case APP_CMD_LOST_FOCUS:
+ // When our app loses focus, we stop monitoring the accelerometer.
+ // This is to avoid consuming battery while not being used.
+ if (engine->accelerometerSensor != NULL)
+ ASensorEventQueue_disableSensor(engine->sensorEventQueue,
+ engine->accelerometerSensor);
+ // Also stop animating.
+ engine->animating = 0;
+ engine_draw_frame(engine);
+ break;
+ }
+}
+
+/**
+ * This is the main entry point of a native application that is using
+ * android_native_app_glue. It runs in its own thread, with its own
+ * event loop for receiving input events and doing other things.
+ */
+void android_main(struct android_app* state)
+{
+ struct engine engine;
+
+ // Make sure glue isn't stripped.
+ app_dummy();
+
+ memset(&engine, 0, sizeof(engine));
+ state->userData = &engine;
+ state->onAppCmd = engine_handle_cmd;
+ state->onInputEvent = engine_handle_input;
+ engine.app = state;
+
+ // Prepare to monitor accelerometer
+ engine.sensorManager = ASensorManager_getInstance();
+ engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager,
+ ASENSOR_TYPE_ACCELEROMETER);
+ engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager,
+ state->looper, LOOPER_ID_USER, NULL, NULL);
+
+ if (state->savedState != NULL) // We are starting with a previous saved state; restore from it.
+ engine.state = *(struct saved_state*)state->savedState;
+
+ // loop waiting for stuff to do.
+
+ while (1)
+ {
+ // Read all pending events.
+ int ident;
+ int events;
+ struct android_poll_source* source;
+
+ // If not animating, we will block forever waiting for events.
+ // If animating, we loop until all events are read, then continue
+ // to draw the next frame of animation.
+ while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events,
+ (void**)&source)) >= 0)
+ {
+ // Process this event.
+ if (source != NULL)
+ source->process(state, source);
+
+ // If a sensor has data, process it now.
+ if (ident == LOOPER_ID_USER && engine.accelerometerSensor != NULL)
+ {
+ ASensorEvent event;
+ while (ASensorEventQueue_getEvents(engine.sensorEventQueue, &event, 1) > 0)
+ RARCH_WARN("accelerometer: x=%f y=%f z=%f.\n", event.acceleration.x,
+ event.acceleration.y, event.acceleration.z);
+ }
+
+ // Check if we are exiting.
+ if (state->destroyRequested != 0)
+ {
+ engine_term_display(&engine);
+ return;
+ }
+ }
+
+ if (engine.animating)
+ {
+ // Done with events; draw next animation frame.
+ engine.state.angle += .01f;
+
+ if (engine.state.angle > 1)
+ engine.state.angle = 0;
+
+ // Drawing is throttled to the screen update rate, so there
+ // is no need to do timing here.
+ engine_draw_frame(&engine);
+ }
+ }
+}
diff --git a/gfx/context/androidegl_ctx.c b/gfx/context/androidegl_ctx.c
index baae97e56f..e07f96f26c 100644
--- a/gfx/context/androidegl_ctx.c
+++ b/gfx/context/androidegl_ctx.c
@@ -340,6 +340,7 @@ const gfx_ctx_driver_t gfx_ctx_android = {
NULL,
"android",
+#ifdef RARCH_CONSOLE
// RARCH_CONSOLE stuff.
gfx_ctx_set_filtering,
gfx_ctx_get_available_resolutions,
@@ -353,4 +354,5 @@ const gfx_ctx_driver_t gfx_ctx_android = {
gfx_ctx_set_fbo,
gfx_ctx_apply_fbo_state_changes,
+#endif
};
diff --git a/gfx/gl.c b/gfx/gl.c
index 4d9ff85283..338280eb32 100644
--- a/gfx/gl.c
+++ b/gfx/gl.c
@@ -38,7 +38,7 @@
#include "shader_cg.h"
#endif
-#ifdef HAVE_XML
+#if defined(HAVE_XML) || defined(HAVE_GLSL)
#include "shader_glsl.h"
#endif
diff --git a/input/input_common.c b/input/input_common.c
index 504a5f124a..942b70bf32 100644
--- a/input/input_common.c
+++ b/input/input_common.c
@@ -29,7 +29,7 @@ static const rarch_joypad_driver_t *joypad_drivers[] = {
#ifdef HAVE_SDL
&sdl_joypad,
#endif
-#ifdef __linux
+#if defined(__linux) && !defined(ANDROID)
&linuxraw_joypad,
#endif
};