Procházet zdrojové kódy

Automatically loading assets/game.love if exists

fysx před 12 roky
rodič
revize
6518cde39a

+ 9 - 14
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 <[email protected]>
 
-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/<projectname>/ for the respective
+licenses.
+
+As for the other code and build system files, these are published under the
+zlib license (same as LÖVE).

+ 14 - 5
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); */

+ 79 - 2
jni/love/src/modules/filesystem/physfs/Filesystem.cpp

@@ -27,6 +27,9 @@
 
 #include "Filesystem.h"
 
+#include "SDL.h"
+#include <string>
+
 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;
 }

+ 4 - 4
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();
         }