(Android) removed bifrost.c - made libretroarch.so now a native

activity
This commit is contained in:
twinaphex 2012-10-14 03:37:08 +02:00
parent 1195e92850
commit 96f5c78304
6 changed files with 366 additions and 182 deletions

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/* RetroArch Bifrost:
* A burning rainbow bridge that reaches between Java (the world)
* and C/C++, the realm of the gods */
#include <stdio.h>
#include <jni.h>
#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);
}

View File

@ -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)

322
android/jni/main.c Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <jni.h>
#include <errno.h>
#include <EGL/egl.h>
#include <GLES/gl.h>
#include <android/sensor.h>
#include <android/log.h>
#include <android_native_app_glue.h>
#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);
}
}
}

View File

@ -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
};

View File

@ -38,7 +38,7 @@
#include "shader_cg.h"
#endif
#ifdef HAVE_XML
#if defined(HAVE_XML) || defined(HAVE_GLSL)
#include "shader_glsl.h"
#endif

View File

@ -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
};