From 6518cde39a871453159986761e54550cc53fa9f9 Mon Sep 17 00:00:00 2001 From: fysx Date: Sat, 28 Dec 2013 15:28:05 +0100 Subject: [PATCH] Automatically loading assets/game.love if exists --- README.md | 23 +++--- .../src/main/android/SDL_android_main.c | 19 +++-- .../modules/filesystem/physfs/Filesystem.cpp | 81 ++++++++++++++++++- src/org/libsdl/app/SDLActivity.java | 8 +- 4 files changed, 106 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 0b7f2afd..461f3f03 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,6 @@ -Android Native + SDL2 + Lua Example +Android Port of LÖVE, the awesome 2D game engine LÖVE (http://love2d.org) Copyright (c) 2013 Martin Felis -This is a simple example that integrates SDL2 and Lua in a Android -App that uses the Android NDK. - Instructions: ------------- @@ -11,17 +8,15 @@ Install the Android SDK and Android NDK and run ndk-build -in the root folder of this project. - -Features: ---------- -* loading and running of a Lua script -* modification of the color using Lua -* reacting on a touch event using Lua code -* calling a lua function on every frame that does stuff +in the root folder of this project or load the project using Eclipse and +compile/run it using Eclipse. License: -------- -This code is public domain, so feel free to do whatever you want with it. -No liability however. +This project contains code from various projects using various licenses. +Please look into the folders of jni// for the respective +licenses. + +As for the other code and build system files, these are published under the +zlib license (same as LÖVE). diff --git a/jni/SDL2-2.0.1/src/main/android/SDL_android_main.c b/jni/SDL2-2.0.1/src/main/android/SDL_android_main.c index 76e5d9f4..4e248061 100644 --- a/jni/SDL2-2.0.1/src/main/android/SDL_android_main.c +++ b/jni/SDL2-2.0.1/src/main/android/SDL_android_main.c @@ -22,21 +22,30 @@ void Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject SDL_SetMainReady(); + /* get argument from SDLMain in SDLActivity.java */ jboolean isCopy; const char* str = (*env)->GetStringUTFChars(env, obj, &isCopy); /* Run the application code! */ int status; - char *argv[4]; + int argc; + + if (SDL_strlen(str) > 0) + argc = 2; + else + argc = 1; + + /* assemble argv depending on whether we have an argument or not */ + char *argv[argc + 1]; argv[0] = SDL_strdup("SDL_app"); - argv[1] = SDL_strdup("--package-path"); - argv[2] = SDL_strdup(str); - argv[3] = NULL; + if (SDL_strlen(str) > 0) + argv[1] = SDL_strdup(str); + argv[argc] = NULL; if (isCopy == JNI_TRUE) (*env)->ReleaseStringUTFChars(env, obj, str); - status = SDL_main(3, argv); + status = SDL_main(argc, argv); /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */ /* exit(status); */ diff --git a/jni/love/src/modules/filesystem/physfs/Filesystem.cpp b/jni/love/src/modules/filesystem/physfs/Filesystem.cpp index d121021b..b16a0e95 100644 --- a/jni/love/src/modules/filesystem/physfs/Filesystem.cpp +++ b/jni/love/src/modules/filesystem/physfs/Filesystem.cpp @@ -27,6 +27,9 @@ #include "Filesystem.h" +#include "SDL.h" +#include + namespace { size_t getDriveDelim(const std::string &input) @@ -47,6 +50,62 @@ namespace { return input.substr(getDriveDelim(input)+1); } + +#ifdef __ANDROID__ + bool androidCopyGameFromAssets () { + SDL_RWops *asset_game_file = SDL_RWFromFile("game.love", "rb"); + + if (!asset_game_file) { + SDL_Log ("Could not find game.love in assets."); + return false; + } + Sint64 file_size = asset_game_file->size(asset_game_file); + + if (file_size == 0) { + SDL_Log ("Could not find valid game.love in assets. File has zero size.", (int) file_size); + return false; + } + + SDL_Log ("Found game.love in assets. Size: %d", (int) file_size); + + std::string internal_storage_path = SDL_AndroidGetInternalStoragePath(); + std::string internal_game_file = internal_storage_path + "/game.love"; + SDL_RWops *storage_game_file = SDL_RWFromFile (internal_game_file.c_str(), "wb"); + + if (!storage_game_file) { + SDL_Log ("Error creating internal storage game file: %s", SDL_GetError()); + asset_game_file->close(asset_game_file); + return false; + } + + char data_buffer[file_size + 1]; + size_t bytes_read = asset_game_file->read(asset_game_file, data_buffer, sizeof(char), (size_t) file_size); + data_buffer[bytes_read] = '\0'; + + if (bytes_read != file_size) { + SDL_Log ("Error copying asset game file from assets to internal storage %s. Error: %s", internal_game_file.c_str(), SDL_GetError()); + asset_game_file->close(asset_game_file); + storage_game_file->close(storage_game_file); + return false; + } + + size_t bytes_written = storage_game_file->write(storage_game_file, data_buffer, sizeof(char), file_size); + + if (bytes_written != file_size) { + SDL_Log ("Error copying asset game to internal storage: %s", SDL_GetError()); + asset_game_file->close(asset_game_file); + storage_game_file->close(storage_game_file); + return false; + } + + asset_game_file->close(asset_game_file); + storage_game_file->close(storage_game_file); + + SDL_Log ("Copying of asset game to internal storage %s successful!", internal_game_file.c_str()); + + return true; + } +#endif } namespace love @@ -147,12 +206,30 @@ bool Filesystem::setSource(const char *source) if (!game_source.empty()) return false; + std::string new_search_path = source; + +#ifdef __ANDROID__ + if (androidCopyGameFromAssets()) + new_search_path = std::string(SDL_AndroidGetInternalStoragePath()) + std::string("/game.love"); + else { + SDL_RWops *sdcard_main = SDL_RWFromFile("/sdcard/lovegame/main.lua", "rb"); + + if (sdcard_main) { + SDL_Log ("using game from /sdcard/lovegame"); + new_search_path = "/sdcard/lovegame"; + sdcard_main->close(sdcard_main); + } + } +#endif + // Add the directory. - if (!PHYSFS_addToSearchPath(source, 1)) + if (!PHYSFS_addToSearchPath(new_search_path.c_str(), 1)) { + SDL_Log ("mounting of %s failed", new_search_path.c_str()); return false; + } // Save the game source. - game_source = std::string(source); + game_source = new_search_path; return true; } diff --git a/src/org/libsdl/app/SDLActivity.java b/src/org/libsdl/app/SDLActivity.java index 570b43ba..e51c688d 100644 --- a/src/org/libsdl/app/SDLActivity.java +++ b/src/org/libsdl/app/SDLActivity.java @@ -418,6 +418,9 @@ public class SDLActivity extends Activity { class SDLMain implements Runnable { public String path; + public SDLMain () { + this.path = ""; + } public SDLMain (String path) { this.path = path; } @@ -425,10 +428,7 @@ class SDLMain implements Runnable { @Override public void run() { // Runs SDL_main() - Log.v("Java", "calling with arg " + this.path); SDLActivity.nativeInit(this.path); - - //Log.v("SDL", "SDL thread terminated"); } } @@ -566,7 +566,7 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, } apkFilePath = appInfo.sourceDir; - SDLActivity.mSDLThread = new Thread(new SDLMain(apkFilePath), "SDLThread"); + SDLActivity.mSDLThread = new Thread(new SDLMain(), "SDLThread"); enableSensor(Sensor.TYPE_ACCELEROMETER, true); SDLActivity.mSDLThread.start(); }