Browse Source

Merge https://bitbucket.org/cigumo/love-android-sdl2/branch/master into setSource_mount_order

Martin Felis 8 years ago
parent
commit
7ebcf9494e

+ 17 - 45
love/src/jni/love/src/modules/filesystem/physfs/Filesystem.cpp

@@ -233,57 +233,29 @@ bool Filesystem::setSource(const char *source)
 	if (!love::android::createStorageDirectories())
 	if (!love::android::createStorageDirectories())
 		SDL_Log("Error creating storage directories!");
 		SDL_Log("Error creating storage directories!");
 
 
-	char* game_archive_ptr = NULL;
-	size_t game_archive_size = 0;
-	bool archive_loaded = false;
+	new_search_path = love::android::getSelectedGameFile();
 
 
-	// try to load the game that was sent to LÖVE via a Intent
-	archive_loaded = love::android::loadGameArchiveToMemory(love::android::getSelectedGameFile(), &game_archive_ptr, &game_archive_size);
-
-	if (!archive_loaded)
-	{
-		// try to load the game in the assets/ folder
-		archive_loaded = love::android::loadGameArchiveToMemory("game.love", &game_archive_ptr, &game_archive_size);
-	}
-
-	if (archive_loaded)
+	// try mounting first, if that fails, load to memory and mount
+	if (!PHYSFS_mount(new_search_path.c_str(), nullptr, 1))
 	{
 	{
-		if (!PHYSFS_mountMemory(game_archive_ptr, game_archive_size, love::android::freeGameArchiveMemory, "archive.zip", "/", 0))
+		// PHYSFS cannot yet mount a zip file inside an .apk
+		SDL_Log("Mounting %s did not work. Loading to memory.",
+				new_search_path.c_str());
+		char* game_archive_ptr = NULL;
+		size_t game_archive_size = 0;
+		if (!love::android::loadGameArchiveToMemory(
+					new_search_path.c_str(), &game_archive_ptr,
+					&game_archive_size))
 		{
 		{
-			SDL_Log("Mounting of in-memory game archive failed!");
-			love::android::freeGameArchiveMemory(game_archive_ptr);
+			SDL_Log("Failure memory loading archive %s", new_search_path.c_str());
 			return false;
 			return false;
 		}
 		}
-	}
-	else
-	{
-		// try to load the game in the directory that was sent to LÖVE via an
-		// Intent ...
-		std::string game_path = std::string(love::android::getSelectedGameFile());
-
-		if (game_path == "")
-		{
-			// ... or fall back to the game at /sdcard/lovegame
-			game_path = "/sdcard/lovegame/";
-		}
-
-		SDL_RWops *sdcard_main = SDL_RWFromFile(std::string(game_path + "main.lua").c_str(), "rb");
-
-		if (sdcard_main)
+		if (!PHYSFS_mountMemory(
+			    game_archive_ptr, game_archive_size,
+			    love::android::freeGameArchiveMemory, "archive.zip", "/", 0))
 		{
 		{
-			new_search_path = game_path;
-			sdcard_main->close(sdcard_main);
-
-			if (!PHYSFS_mount(new_search_path.c_str(), nullptr, 1))
-			{
-				SDL_Log("mounting of %s failed", new_search_path.c_str());
-				return false;
-			}
-		}
-		else
-		{
-			// Neither assets/game.love or /sdcard/lovegame was mounted
-			// sucessfully, therefore simply fail.
+			SDL_Log("Failure mounting in-memory archive.");
+			love::android::freeGameArchiveMemory(game_archive_ptr);
 			return false;
 			return false;
 		}
 		}
 	}
 	}

+ 81 - 7
love/src/main/java/org/love2d/android/GameActivity.java

@@ -2,9 +2,11 @@ package org.love2d.android;
 
 
 import org.libsdl.app.SDLActivity;
 import org.libsdl.app.SDLActivity;
 
 
+import java.util.Arrays;
 import java.util.List;
 import java.util.List;
 import java.io.BufferedInputStream;
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.BufferedOutputStream;
+import java.io.File;
 import java.io.FileOutputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStream;
@@ -39,7 +41,7 @@ public class GameActivity extends SDLActivity {
     private static Context context;
     private static Context context;
     private static Vibrator vibrator = null;
     private static Vibrator vibrator = null;
     private static boolean immersiveActive = false;
     private static boolean immersiveActive = false;
-
+    private static boolean mustCacheArchive = false;
 		@Override 
 		@Override 
 		protected String[] getLibraries() {
 		protected String[] getLibraries() {
 			return new String[] {
 			return new String[] {
@@ -76,14 +78,13 @@ public class GameActivity extends SDLActivity {
       handleIntent (intent);
       handleIntent (intent);
       resetNative();
       resetNative();
       startNative();
       startNative();
-    };
+    }
 
 
     protected void handleIntent (Intent intent) {
     protected void handleIntent (Intent intent) {
       Uri game = intent.getData();
       Uri game = intent.getData();
       if (game != null) {
       if (game != null) {
         if (game.getScheme().equals ("file")) {
         if (game.getScheme().equals ("file")) {
           Log.d("GameActivity", "Received intent with path: " + game.getPath());
           Log.d("GameActivity", "Received intent with path: " + game.getPath());
-
           // If we were given the path of a main.lua then use its
           // If we were given the path of a main.lua then use its
           // directory. Otherwise use full path.
           // directory. Otherwise use full path.
           List<String> path_segments = game.getPathSegments();
           List<String> path_segments = game.getPathSegments();
@@ -93,12 +94,36 @@ public class GameActivity extends SDLActivity {
             gamePath = game.getPath();
             gamePath = game.getPath();
           }
           }
         } else {
         } else {
-          copyGameToCache (game);
+            // if archive exists, copy it to the cache
+            copyGameToCache (game);
+            return;
         }
         }
-
         Log.d("GameActivity", "new gamePath: " + gamePath);
         Log.d("GameActivity", "new gamePath: " + gamePath);
+
+      } else {          
+          boolean archiveExists = false;
+          try {
+              List<String> assets = Arrays.asList(getAssets().list(""));
+              archiveExists = assets.contains("game.love");
+          } catch (Exception e) {
+              Log.d("GameActivity", "could not list application assets:" + e.getMessage());
+          }
+          if (archiveExists) {
+              String df = this.getCacheDir().getPath()+"/game.love";
+              if (mustCacheArchive && copyAssetFile("game.love",df))
+                  gamePath = df;
+              else
+                  gamePath = "game.love";
+          } else {
+              File ext = Environment.getExternalStorageDirectory();              
+              if ((new File(ext,"/lovegame/main.lua")).exists()) {
+                  gamePath = ext.getPath() + "/lovegame/";
+              }
+          }
+
+          Log.d("GameActivity", "new gamePath: " + gamePath);
       }
       }
-    };
+    }
 
 
     @Override
     @Override
     protected void onDestroy() {
     protected void onDestroy() {
@@ -198,7 +223,56 @@ public class GameActivity extends SDLActivity {
       i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
       i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
       context.startActivity(i);
       context.startActivity(i);
     }
     }
-  
+
+    boolean copyAssetFile(String fileName, String destF)
+    {
+        boolean success = false;
+
+        // open streams
+        BufferedOutputStream bos = null;
+        try {
+            bos = new BufferedOutputStream(new FileOutputStream(destF, false));
+        } catch (IOException e) {
+            Log.d ("GameActivity", "Could not open destination file:" + e.getMessage());
+        }
+        InputStream ins = null;
+        try {            
+            ins = getAssets().open(fileName);
+        } catch (IOException e) {
+            Log.d("GameActivity", "Could not open game file:" + e.getMessage());
+        }
+
+        // copy
+        int bytes_written = 0;            
+        if (ins != null && bos != null) {
+            int chunk_read = 0;
+            try {
+                byte[] buf = new byte[8192];
+                chunk_read = ins.read(buf);
+                do {
+                    bos.write(buf, 0, chunk_read);
+                    bytes_written += chunk_read;
+                    chunk_read = ins.read(buf);
+                } while(chunk_read != -1);
+            } catch (IOException e) {
+                Log.d ("GameActivity", "Copying failed:" + e.getMessage());            
+            }
+        }
+        
+        // close streams
+        try {
+            if (ins != null) ins.close();
+            if (bos != null) bos.close();
+            success = true;
+        } catch (IOException e) {
+            Log.d ("GameActivity", "Copying failed: " + e.getMessage());
+        }
+
+        Log.d("GameActivity", "Copied " + fileName + " to " + destF
+              + ". Wrote:" + bytes_written + " bytes");
+        return success;
+    }
+
     void copyGameToCache (Uri sourceuri)
     void copyGameToCache (Uri sourceuri)
     {
     {
       String destinationFilename = this.getCacheDir().getPath()+"/downloaded.love";
       String destinationFilename = this.getCacheDir().getPath()+"/downloaded.love";