@@ -18,5 +18,5 @@ | |||||
</intent-filter> | </intent-filter> | ||||
</activity> | </activity> | ||||
</application> | </application> | ||||
<uses-sdk android:minSdkVersion="9" /> | |||||
<uses-sdk android:minSdkVersion="13" /> | |||||
</manifest> | </manifest> |
@@ -31,14 +31,9 @@ public class LolActivity extends NativeActivity | |||||
protected void onCreate(Bundle saved_instance) | protected void onCreate(Bundle saved_instance) | ||||
{ | { | ||||
super.onCreate(saved_instance); | super.onCreate(saved_instance); | ||||
m_assets = getAssets(); | m_assets = getAssets(); | ||||
nativeInit(m_assets); | |||||
} | } | ||||
private native void nativeInit(AssetManager assets); | |||||
private AssetManager m_assets; | private AssetManager m_assets; | ||||
/* | /* | ||||
@@ -138,7 +138,7 @@ all-local-android: $(foreach p, $(PROGRAMS:%$(EXEEXT)=%), .$(p).androidstamp) | |||||
$(MKDIR_P) "$(d)/libs/armeabi" | $(MKDIR_P) "$(d)/libs/armeabi" | ||||
$(LN_S) "$(abs_builddir)/$(p)$(EXEEXT)" "$(d)/libs/armeabi/lib$(p).so" | $(LN_S) "$(abs_builddir)/$(p)$(EXEEXT)" "$(d)/libs/armeabi/lib$(p).so" | ||||
$(LN_S) "$${ANDROID_NDK_ROOT}/sources/cxx-stl/stlport/libs/armeabi/libstlport_shared.so" "$(d)/libs/armeabi" | $(LN_S) "$${ANDROID_NDK_ROOT}/sources/cxx-stl/stlport/libs/armeabi/libstlport_shared.so" "$(d)/libs/armeabi" | ||||
android update project -t android-9 -n "$(p)" -p "$(d)" | |||||
android update project -t android-19 -n "$(p)" -p "$(d)" | |||||
ant debug -f "$(d)/build.xml" | ant debug -f "$(d)/build.xml" | ||||
touch $@ | touch $@ | ||||
else | else | ||||
@@ -8,7 +8,7 @@ | |||||
// http://www.wtfpl.net/ for more details. | // http://www.wtfpl.net/ for more details. | ||||
// | // | ||||
#if defined HAVE_CONFIG_H | |||||
#if HAVE_CONFIG_H | |||||
# include "config.h" | # include "config.h" | ||||
#endif | #endif | ||||
@@ -26,14 +26,14 @@ void KeyBinding::Bind(const String& device_name, const String& key_name) | |||||
if (!device) | if (!device) | ||||
{ | { | ||||
Log::Warn("Trying to bind controller to device %s which doesn't exist", device_name.C()); | |||||
Log::Warn("Trying to bind key to nonexistent device %s", device_name.C()); | |||||
return; | return; | ||||
} | } | ||||
int keyindex = device->GetKeyIndex(key_name.C()); | int keyindex = device->GetKeyIndex(key_name.C()); | ||||
if (keyindex < 0) | if (keyindex < 0) | ||||
{ | { | ||||
Log::Warn("Trying to bind controller to key %s.%s which doesn't exist", device_name.C(), key_name.C()); | |||||
Log::Warn("Trying to bind nonexistent key %s.%s", device_name.C(), key_name.C()); | |||||
return; | return; | ||||
} | } | ||||
@@ -69,14 +69,14 @@ void AxisBinding::Bind(const String& device_name, const String& axis_name) | |||||
const InputDevice* device = InputDevice::Get(device_name.C()); | const InputDevice* device = InputDevice::Get(device_name.C()); | ||||
if (!device) | if (!device) | ||||
{ | { | ||||
Log::Warn("Trying to bind controller to device %s which doesn't exist", device_name.C()); | |||||
Log::Warn("Trying to bind axis to nonexistent device %s", device_name.C()); | |||||
return; | return; | ||||
} | } | ||||
int axisindex = device->GetAxisIndex(axis_name.C()); | int axisindex = device->GetAxisIndex(axis_name.C()); | ||||
if (axisindex < 0) | if (axisindex < 0) | ||||
{ | { | ||||
Log::Warn("Trying to bind controller to axis %s.%s which doesn't exist", device_name.C(), axis_name.C()); | |||||
Log::Warn("Trying to bind nonexistent axis %s.%s", device_name.C(), axis_name.C()); | |||||
return; | return; | ||||
} | } | ||||
@@ -88,14 +88,14 @@ void AxisBinding::BindKey(const String& device_name, const String& key_name) | |||||
const InputDevice* device = InputDevice::Get(device_name.C()); | const InputDevice* device = InputDevice::Get(device_name.C()); | ||||
if (!device) | if (!device) | ||||
{ | { | ||||
Log::Warn("Trying to bind controller to device %s which doesn't exist", device_name.C()); | |||||
Log::Warn("Trying to bind axis key to nonexistent device %s", device_name.C()); | |||||
return; | return; | ||||
} | } | ||||
int keyindex = device->GetKeyIndex(key_name.C()); | int keyindex = device->GetKeyIndex(key_name.C()); | ||||
if (keyindex < 0) | if (keyindex < 0) | ||||
{ | { | ||||
Log::Warn("Trying to bind controller to key %s.%s which doesn't exist", device_name.C(), key_name.C()); | |||||
Log::Warn("Trying to bind nonexistent axis key %s.%s", device_name.C(), key_name.C()); | |||||
return; | return; | ||||
} | } | ||||
@@ -107,21 +107,21 @@ void AxisBinding::BindKeys(const String& device_name, const String& min_key_name | |||||
const InputDevice* device = InputDevice::Get(device_name.C()); | const InputDevice* device = InputDevice::Get(device_name.C()); | ||||
if (!device) | if (!device) | ||||
{ | { | ||||
Log::Warn("Trying to bind controller to device %s which doesn't exist", device_name.C()); | |||||
Log::Warn("Trying to bind axis keys to nonexistent device %s", device_name.C()); | |||||
return; | return; | ||||
} | } | ||||
int minkeyindex = device->GetKeyIndex(min_key_name.C()); | int minkeyindex = device->GetKeyIndex(min_key_name.C()); | ||||
if (minkeyindex < 0) | if (minkeyindex < 0) | ||||
{ | { | ||||
Log::Warn("Trying to bind controller to key %s.%s which doesn't exist", device_name.C(), min_key_name.C()); | |||||
Log::Warn("Trying to bind nonexistent axis key %s.%s", device_name.C(), min_key_name.C()); | |||||
return; | return; | ||||
} | } | ||||
int maxkeyindex = device->GetKeyIndex(max_key_name.C()); | int maxkeyindex = device->GetKeyIndex(max_key_name.C()); | ||||
if (maxkeyindex < 0) | if (maxkeyindex < 0) | ||||
{ | { | ||||
Log::Warn("Trying to bind controller to key %s.%s which doesn't exist", device_name.C(), max_key_name.C()); | |||||
Log::Warn("Trying to bind nonexistent axis key %s.%s", device_name.C(), max_key_name.C()); | |||||
return; | return; | ||||
} | } | ||||
@@ -231,7 +231,7 @@ Controller::Controller(char const* name, int nb_keys, int nb_axis) | |||||
m_active = false; | m_active = false; | ||||
if (Get(name) != nullptr) | if (Get(name) != nullptr) | ||||
{ | { | ||||
Log::Warn("a controller with this name has already been registered"); | |||||
Log::Warn("controller “%s” has already been registered", name); | |||||
} | } | ||||
controllers.Push(this); | controllers.Push(this); | ||||
} | } | ||||
@@ -8,13 +8,15 @@ | |||||
// http://www.wtfpl.net/ for more details. | // http://www.wtfpl.net/ for more details. | ||||
// | // | ||||
#if defined HAVE_CONFIG_H | |||||
#if HAVE_CONFIG_H | |||||
# include "config.h" | # include "config.h" | ||||
#endif | #endif | ||||
#if defined __ANDROID__ | |||||
#if __ANDROID__ | |||||
#include <jni.h> | #include <jni.h> | ||||
#include <sys/types.h> | |||||
#include <android/asset_manager_jni.h> | #include <android/asset_manager_jni.h> | ||||
#include <EGL/egl.h> | #include <EGL/egl.h> | ||||
@@ -35,7 +37,7 @@ using namespace lol; | |||||
namespace lol | namespace lol | ||||
{ | { | ||||
JavaVM *g_vm; | JavaVM *g_vm; | ||||
jobject g_activity; | |||||
ANativeActivity *g_activity; | |||||
AAssetManager *g_assets; | AAssetManager *g_assets; | ||||
}; /* namespace lol */ | }; /* namespace lol */ | ||||
@@ -43,21 +45,9 @@ extern "C" jint | |||||
JNI_OnLoad(JavaVM* vm, void* reserved) | JNI_OnLoad(JavaVM* vm, void* reserved) | ||||
{ | { | ||||
Log::Info("Java layer loading library, vm=0x%08lx", (long)(intptr_t)vm); | Log::Info("Java layer loading library, vm=0x%08lx", (long)(intptr_t)vm); | ||||
g_vm = vm; | |||||
return JNI_VERSION_1_4; | return JNI_VERSION_1_4; | ||||
} | } | ||||
extern "C" void | |||||
Java_net_lolengine_LolActivity_nativeInit(JNIEnv* env, jobject thiz, | |||||
jobject assets) | |||||
{ | |||||
Log::Info("Java layer initialising activity 0x%08lx", (long)thiz); | |||||
env->NewGlobalRef(thiz); /* FIXME: never released! */ | |||||
g_activity = thiz; | |||||
env->NewGlobalRef(assets); /* FIXME: never released! */ | |||||
g_assets = AAssetManager_fromJava(env, assets); | |||||
} | |||||
/* One of these wrappers will be overridden by the user's version */ | /* One of these wrappers will be overridden by the user's version */ | ||||
void lol_android_main(void) __attribute__((weak)); | void lol_android_main(void) __attribute__((weak)); | ||||
void lol_android_main(int argc, char **argv) __attribute__((weak)); | void lol_android_main(int argc, char **argv) __attribute__((weak)); | ||||
@@ -161,9 +151,8 @@ int lol::AndroidAppData::CreateDisplay() | |||||
eglQuerySurface(m_display, m_surface, EGL_WIDTH, &w); | eglQuerySurface(m_display, m_surface, EGL_WIDTH, &w); | ||||
eglQuerySurface(m_display, m_surface, EGL_HEIGHT, &h); | eglQuerySurface(m_display, m_surface, EGL_HEIGHT, &h); | ||||
/* Launch our ticker */ | |||||
Log::Info("Java layer initialising renderer at %g fps", 60.0f); | |||||
Ticker::Setup(60.0f); | |||||
/* Launch our renderer */ | |||||
Log::Info("Java layer initialising renderer"); | |||||
Video::Setup(ivec2(w, h)); | Video::Setup(ivec2(w, h)); | ||||
return 0; | return 0; | ||||
@@ -278,6 +267,35 @@ void android_main(android_app* native_app) | |||||
{ | { | ||||
Log::Info("Java layer calling main() for app 0x%08lx", (long)native_app); | Log::Info("Java layer calling main() for app 0x%08lx", (long)native_app); | ||||
/* Register native activity */ | |||||
g_activity = native_app->activity; | |||||
/* Register Java VM */ | |||||
g_vm = g_activity->vm; | |||||
/* Get JNI environment */ | |||||
JNIEnv *jni_env; | |||||
jint res = g_vm->GetEnv((void **)&jni_env, JNI_VERSION_1_2); | |||||
if (res < 0) | |||||
{ | |||||
Log::Error("JVM environment not found, trying to attach thread\n"); | |||||
res = g_vm->AttachCurrentThread(&jni_env, nullptr); | |||||
} | |||||
if (res < 0) | |||||
{ | |||||
Log::Error("JVM environment not found, cannot run main()\n"); | |||||
return; | |||||
} | |||||
/* Get asset manager */ | |||||
jclass cls = jni_env->GetObjectClass(g_activity->clazz); | |||||
jmethodID mid = jni_env->GetMethodID(cls, "getAssets", | |||||
"()Landroid/content/res/AssetManager;"); | |||||
jobject assets = jni_env->CallObjectMethod(g_activity->clazz, mid); | |||||
jni_env->NewGlobalRef(assets); /* FIXME: never released! */ | |||||
g_assets = AAssetManager_fromJava(jni_env, assets); | |||||
/* Create our app data */ | |||||
g_data = new AndroidAppData(); | g_data = new AndroidAppData(); | ||||
g_data->m_native_app = native_app; | g_data->m_native_app = native_app; | ||||
@@ -298,6 +316,16 @@ void android_main(android_app* native_app) | |||||
char *argv[] = { "", nullptr }; | char *argv[] = { "", nullptr }; | ||||
char *env[] = { nullptr }; | char *env[] = { nullptr }; | ||||
/* FIXME: this is fucking pathetic. */ | |||||
while (!g_scene) | |||||
{ | |||||
Log::Debug("waiting for g_scene...\n"); | |||||
Timer t; | |||||
t.Wait(0.1); | |||||
} | |||||
Log::Info("running main()\n"); | |||||
/* Call the user's main() function. One of these will work. */ | /* Call the user's main() function. One of these will work. */ | ||||
lol_android_main(); | lol_android_main(); | ||||
lol_android_main(argc, argv); | lol_android_main(argc, argv); | ||||
@@ -307,6 +335,10 @@ void android_main(android_app* native_app) | |||||
lol::AndroidApp::AndroidApp(char const *title, ivec2 res, float fps) | lol::AndroidApp::AndroidApp(char const *title, ivec2 res, float fps) | ||||
: m_data(g_data) | : m_data(g_data) | ||||
{ | { | ||||
/* Launch our ticker */ | |||||
Log::Info("Java layer initialising ticker at %g fps", fps); | |||||
Ticker::Setup(fps); | |||||
m_data->m_wanted_resolution = res; | m_data->m_wanted_resolution = res; | ||||
m_data->m_mouse = InputDeviceInternal::CreateStandardMouse(); | m_data->m_mouse = InputDeviceInternal::CreateStandardMouse(); | ||||
} | } | ||||
@@ -8,14 +8,14 @@ | |||||
// http://www.wtfpl.net/ for more details. | // http://www.wtfpl.net/ for more details. | ||||
// | // | ||||
#if defined HAVE_CONFIG_H | |||||
#if HAVE_CONFIG_H | |||||
# include "config.h" | # include "config.h" | ||||
#endif | #endif | ||||
#include <cstdlib> | #include <cstdlib> | ||||
#ifdef WIN32 | |||||
# define WIN32_LEAN_AND_MEAN | |||||
#if WIN32 | |||||
# define WIN32_LEAN_AND_MEAN 1 | |||||
# include <windows.h> | # include <windows.h> | ||||
#endif | #endif | ||||
@@ -113,12 +113,16 @@ Scene::~Scene() | |||||
void Scene::PushCamera(Camera *cam) | void Scene::PushCamera(Camera *cam) | ||||
{ | { | ||||
ASSERT(this, "trying to push a camera before g_scene is ready"); | |||||
Ticker::Ref(cam); | Ticker::Ref(cam); | ||||
data->m_camera_stack.Push(cam); | data->m_camera_stack.Push(cam); | ||||
} | } | ||||
void Scene::PopCamera(Camera *cam) | void Scene::PopCamera(Camera *cam) | ||||
{ | { | ||||
ASSERT(this, "trying to pop a camera before g_scene is ready"); | |||||
/* Parse from the end because that’s probably where we’ll find | /* Parse from the end because that’s probably where we’ll find | ||||
* our camera first. */ | * our camera first. */ | ||||
for (int i = data->m_camera_stack.Count(); i--; ) | for (int i = data->m_camera_stack.Count(); i--; ) | ||||
@@ -8,7 +8,7 @@ | |||||
// http://www.wtfpl.net/ for more details. | // http://www.wtfpl.net/ for more details. | ||||
// | // | ||||
#if defined HAVE_CONFIG_H | |||||
#if HAVE_CONFIG_H | |||||
# include "config.h" | # include "config.h" | ||||
#endif | #endif | ||||
@@ -16,6 +16,7 @@ | |||||
# include <sys/paths.h> | # include <sys/paths.h> | ||||
# include <cell/cell_fs.h> | # include <cell/cell_fs.h> | ||||
#elif __ANDROID__ | #elif __ANDROID__ | ||||
# include <sys/types.h> | |||||
# include <android/asset_manager_jni.h> | # include <android/asset_manager_jni.h> | ||||
#endif | #endif | ||||