| @@ -10,7 +10,8 @@ | |||||
| package net.lolengine; | package net.lolengine; | ||||
| import android.app.NativeActivity; | |||||
| import android.app.NativeActivity; /* NativeActivity */ | |||||
| import android.os.Bundle; /* Bundle */ | |||||
| import android.content.res.AssetManager; /* getAssets() */ | import android.content.res.AssetManager; /* getAssets() */ | ||||
| import android.graphics.Bitmap; | import android.graphics.Bitmap; | ||||
| @@ -26,12 +27,19 @@ public class LolActivity extends NativeActivity | |||||
| System.loadLibrary("@PROGRAM@"); | System.loadLibrary("@PROGRAM@"); | ||||
| } | } | ||||
| public LolActivity() | |||||
| @Override | |||||
| protected void onCreate(Bundle saved_instance) | |||||
| { | { | ||||
| nativeInit(); | |||||
| super.onCreate(saved_instance); | |||||
| m_assets = getAssets(); | |||||
| nativeInit(m_assets); | |||||
| } | } | ||||
| private native void nativeInit(); | |||||
| private native void nativeInit(AssetManager assets); | |||||
| private AssetManager m_assets; | |||||
| /* | /* | ||||
| * Bitmap loading helpers | * Bitmap loading helpers | ||||
| @@ -41,7 +49,7 @@ public class LolActivity extends NativeActivity | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| return BitmapFactory.decodeStream(getAssets().open(name)); | |||||
| return BitmapFactory.decodeStream(m_assets.open(name)); | |||||
| } | } | ||||
| catch (Exception e) { } | catch (Exception e) { } | ||||
| return null; | return null; | ||||
| @@ -15,6 +15,7 @@ | |||||
| #if defined __ANDROID__ | #if defined __ANDROID__ | ||||
| #include <jni.h> | #include <jni.h> | ||||
| #include <android/asset_manager_jni.h> | |||||
| #include <EGL/egl.h> | #include <EGL/egl.h> | ||||
| #include <GLES/gl.h> | #include <GLES/gl.h> | ||||
| @@ -33,6 +34,7 @@ namespace lol | |||||
| { | { | ||||
| JavaVM *g_vm; | JavaVM *g_vm; | ||||
| jobject g_activity; | jobject g_activity; | ||||
| AAssetManager *g_assets; | |||||
| }; /* namespace lol */ | }; /* namespace lol */ | ||||
| extern "C" jint | extern "C" jint | ||||
| @@ -44,11 +46,14 @@ JNI_OnLoad(JavaVM* vm, void* reserved) | |||||
| } | } | ||||
| extern "C" void | extern "C" void | ||||
| Java_net_lolengine_LolActivity_nativeInit(JNIEnv* env, jobject thiz) | |||||
| Java_net_lolengine_LolActivity_nativeInit(JNIEnv* env, jobject thiz, | |||||
| jobject assets) | |||||
| { | { | ||||
| Log::Info("Java layer initialising activity 0x%08lx", (long)thiz); | Log::Info("Java layer initialising activity 0x%08lx", (long)thiz); | ||||
| env->NewGlobalRef(thiz); /* FIXME: never released! */ | env->NewGlobalRef(thiz); /* FIXME: never released! */ | ||||
| g_activity = thiz; | 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 */ | ||||
| @@ -15,6 +15,8 @@ | |||||
| #if __CELLOS_LV2__ | #if __CELLOS_LV2__ | ||||
| # include <sys/paths.h> | # include <sys/paths.h> | ||||
| # include <cell/cell_fs.h> | # include <cell/cell_fs.h> | ||||
| #elif __ANDROID__ | |||||
| # include <android/asset_manager_jni.h> | |||||
| #endif | #endif | ||||
| #include "core.h" | #include "core.h" | ||||
| @@ -22,6 +24,10 @@ | |||||
| namespace lol | namespace lol | ||||
| { | { | ||||
| #if __ANDROID__ | |||||
| extern AAssetManager *g_assets; | |||||
| #endif | |||||
| class FileData | class FileData | ||||
| { | { | ||||
| friend class File; | friend class File; | ||||
| @@ -34,6 +40,8 @@ class FileData | |||||
| &m_fd, NULL, 0); | &m_fd, NULL, 0); | ||||
| if (err != CELL_FS_SUCCEEDED) | if (err != CELL_FS_SUCCEEDED) | ||||
| m_fd = -1; | m_fd = -1; | ||||
| #elif __ANDROID__ | |||||
| m_asset = AAssetManager_open(g_assets, file.C(), AASSET_MODE_UNKNOWN); | |||||
| #elif HAVE_STDIO_H | #elif HAVE_STDIO_H | ||||
| /* FIXME: no modes, no error checking, no nothing */ | /* FIXME: no modes, no error checking, no nothing */ | ||||
| m_fd = fopen(file.C(), "r"); | m_fd = fopen(file.C(), "r"); | ||||
| @@ -44,6 +52,8 @@ class FileData | |||||
| { | { | ||||
| #if __CELLOS_LV2__ | #if __CELLOS_LV2__ | ||||
| return m_fd > -1; | return m_fd > -1; | ||||
| #elif __ANDROID__ | |||||
| return !!m_asset; | |||||
| #elif HAVE_STDIO_H | #elif HAVE_STDIO_H | ||||
| return !!m_fd; | return !!m_fd; | ||||
| #else | #else | ||||
| @@ -61,6 +71,8 @@ class FileData | |||||
| return -1; | return -1; | ||||
| return (int)done; | return (int)done; | ||||
| #elif __ANDROID__ | |||||
| return AAsset_read(m_asset, buf, count); | |||||
| #elif HAVE_STDIO_H | #elif HAVE_STDIO_H | ||||
| size_t done = fread(buf, 1, count, m_fd); | size_t done = fread(buf, 1, count, m_fd); | ||||
| if (done <= 0) | if (done <= 0) | ||||
| @@ -98,6 +110,11 @@ class FileData | |||||
| #if __CELLOS_LV2__ | #if __CELLOS_LV2__ | ||||
| if (m_fd >= 0) | if (m_fd >= 0) | ||||
| cellFsClose(m_fd); | cellFsClose(m_fd); | ||||
| m_fd = -1; | |||||
| #elif __ANDROID__ | |||||
| if (m_asset) | |||||
| AAsset_close(m_asset); | |||||
| m_asset = nullptr; | |||||
| #elif HAVE_STDIO_H | #elif HAVE_STDIO_H | ||||
| if (m_fd) | if (m_fd) | ||||
| fclose(m_fd); | fclose(m_fd); | ||||
| @@ -107,6 +124,8 @@ class FileData | |||||
| #if __CELLOS_LV2__ | #if __CELLOS_LV2__ | ||||
| int m_fd; | int m_fd; | ||||
| #elif __ANDROID__ | |||||
| AAsset *m_asset; | |||||
| #elif HAVE_STDIO_H | #elif HAVE_STDIO_H | ||||
| FILE *m_fd; | FILE *m_fd; | ||||
| #endif | #endif | ||||
| @@ -48,15 +48,21 @@ void Init(int argc, char *argv[], | |||||
| * Retrieve binary directory, defaulting to current dir. | * Retrieve binary directory, defaulting to current dir. | ||||
| */ | */ | ||||
| #if defined HAVE_GETCWD | |||||
| #if __ANDROID__ | |||||
| /* Android assets are accessed using no prefix at all. */ | |||||
| String binarydir = ""; | |||||
| #elif defined HAVE_GETCWD | |||||
| char *cwd = getcwd(nullptr, 0); | char *cwd = getcwd(nullptr, 0); | ||||
| String binarydir = String(cwd ? cwd : ".") + SEPARATOR; | |||||
| free(cwd); | |||||
| #elif defined HAVE__GETCWD || (defined _WIN32 && !defined _XBOX) | #elif defined HAVE__GETCWD || (defined _WIN32 && !defined _XBOX) | ||||
| char *cwd = _getcwd(nullptr, 0); | char *cwd = _getcwd(nullptr, 0); | ||||
| #else | |||||
| char *cwd = nullptr; | |||||
| #endif | |||||
| String binarydir = String(cwd ? cwd : ".") + SEPARATOR; | String binarydir = String(cwd ? cwd : ".") + SEPARATOR; | ||||
| free(cwd); | free(cwd); | ||||
| #else | |||||
| String binarydir = "./"; | |||||
| #endif | |||||
| if (argc > 0) | if (argc > 0) | ||||
| { | { | ||||
| char const *last_sep = strrchr(argv[0], SEPARATOR); | char const *last_sep = strrchr(argv[0], SEPARATOR); | ||||
| @@ -99,7 +105,7 @@ void Init(int argc, char *argv[], | |||||
| if (!got_rootdir) | if (!got_rootdir) | ||||
| { | { | ||||
| String rootdir = binarydir; | String rootdir = binarydir; | ||||
| if (rootdir.Last() != SEPARATOR) | |||||
| if (rootdir.Count() && rootdir.Last() != SEPARATOR) | |||||
| rootdir += SEPARATOR; | rootdir += SEPARATOR; | ||||
| for (int i = 1; i < sourcesubdir.Count(); ++i) | for (int i = 1; i < sourcesubdir.Count(); ++i) | ||||
| { | { | ||||
| @@ -117,9 +123,9 @@ void Init(int argc, char *argv[], | |||||
| got_rootdir = true; | got_rootdir = true; | ||||
| } | } | ||||
| Log::Debug("binary dir: %s\n", binarydir.C()); | |||||
| Log::Debug("binary dir: “%s”\n", binarydir.C()); | |||||
| for (int i = 0; i < data_dir.Count(); ++i) | for (int i = 0; i < data_dir.Count(); ++i) | ||||
| Log::Debug("data dir %d/%d: %s\n", i + 1, data_dir.Count(), | |||||
| Log::Debug("data dir %d/%d: “%s”\n", i + 1, data_dir.Count(), | |||||
| data_dir[i].C()); | data_dir[i].C()); | ||||
| } | } | ||||