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