Automatically loading assets/game.love if exists

This commit is contained in:
fysx
2013-12-28 15:28:05 +01:00
parent 7758fc2412
commit 6518cde39a
4 changed files with 106 additions and 25 deletions
+9 -14
View File
@@ -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 <martin@fysx.org>
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).
@@ -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); */
@@ -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
View File
@@ -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();
}