diff --git a/love/src/jni/love/src/modules/filesystem/physfs/Filesystem.cpp b/love/src/jni/love/src/modules/filesystem/physfs/Filesystem.cpp index 4d19d58f..3da360e0 100644 --- a/love/src/jni/love/src/modules/filesystem/physfs/Filesystem.cpp +++ b/love/src/jni/love/src/modules/filesystem/physfs/Filesystem.cpp @@ -233,57 +233,29 @@ bool Filesystem::setSource(const char *source) if (!love::android::createStorageDirectories()) 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 mounting first, if that fails, load to memory and mount + if (!PHYSFS_mount(new_search_path.c_str(), nullptr, 1)) { - // 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) - { - 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; } - } - 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 == "") + if (!PHYSFS_mountMemory( + game_archive_ptr, game_archive_size, + love::android::freeGameArchiveMemory, "archive.zip", "/", 0)) { - // ... 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) - { - 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; } } diff --git a/love/src/main/java/org/love2d/android/GameActivity.java b/love/src/main/java/org/love2d/android/GameActivity.java index 215fe830..3d8e5884 100644 --- a/love/src/main/java/org/love2d/android/GameActivity.java +++ b/love/src/main/java/org/love2d/android/GameActivity.java @@ -2,9 +2,11 @@ package org.love2d.android; import org.libsdl.app.SDLActivity; +import java.util.Arrays; import java.util.List; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; +import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -39,7 +41,7 @@ public class GameActivity extends SDLActivity { private static Context context; private static Vibrator vibrator = null; private static boolean immersiveActive = false; - + private static boolean mustCacheArchive = false; @Override protected String[] getLibraries() { return new String[] { @@ -76,14 +78,13 @@ public class GameActivity extends SDLActivity { handleIntent (intent); resetNative(); startNative(); - }; + } protected void handleIntent (Intent intent) { Uri game = intent.getData(); if (game != null) { if (game.getScheme().equals ("file")) { Log.d("GameActivity", "Received intent with path: " + game.getPath()); - // If we were given the path of a main.lua then use its // directory. Otherwise use full path. List path_segments = game.getPathSegments(); @@ -93,12 +94,36 @@ public class GameActivity extends SDLActivity { gamePath = game.getPath(); } } else { - copyGameToCache (game); + // if archive exists, copy it to the cache + copyGameToCache (game); + return; } - Log.d("GameActivity", "new gamePath: " + gamePath); + + } else { + boolean archiveExists = false; + try { + List 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 protected void onDestroy() { @@ -198,7 +223,56 @@ public class GameActivity extends SDLActivity { i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 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) { String destinationFilename = this.getCacheDir().getPath()+"/downloaded.love";