mirror of
https://github.com/love2d/love-android.git
synced 2026-08-22 05:25:27 +02:00
Automatically loading assets/game.love if exists
This commit is contained in:
@@ -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>
|
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:
|
Instructions:
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
@@ -11,17 +8,15 @@ Install the Android SDK and Android NDK and run
|
|||||||
|
|
||||||
ndk-build
|
ndk-build
|
||||||
|
|
||||||
in the root folder of this project.
|
in the root folder of this project or load the project using Eclipse and
|
||||||
|
compile/run it using Eclipse.
|
||||||
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
|
|
||||||
|
|
||||||
License:
|
License:
|
||||||
--------
|
--------
|
||||||
|
|
||||||
This code is public domain, so feel free to do whatever you want with it.
|
This project contains code from various projects using various licenses.
|
||||||
No liability however.
|
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();
|
SDL_SetMainReady();
|
||||||
|
|
||||||
|
/* get argument from SDLMain in SDLActivity.java */
|
||||||
jboolean isCopy;
|
jboolean isCopy;
|
||||||
const char* str = (*env)->GetStringUTFChars(env, obj, &isCopy);
|
const char* str = (*env)->GetStringUTFChars(env, obj, &isCopy);
|
||||||
|
|
||||||
/* Run the application code! */
|
/* Run the application code! */
|
||||||
int status;
|
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[0] = SDL_strdup("SDL_app");
|
||||||
argv[1] = SDL_strdup("--package-path");
|
if (SDL_strlen(str) > 0)
|
||||||
argv[2] = SDL_strdup(str);
|
argv[1] = SDL_strdup(str);
|
||||||
argv[3] = NULL;
|
argv[argc] = NULL;
|
||||||
|
|
||||||
if (isCopy == JNI_TRUE)
|
if (isCopy == JNI_TRUE)
|
||||||
(*env)->ReleaseStringUTFChars(env, obj, str);
|
(*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 */
|
/* Do not issue an exit or the whole application will terminate instead of just the SDL thread */
|
||||||
/* exit(status); */
|
/* exit(status); */
|
||||||
|
|||||||
@@ -27,6 +27,9 @@
|
|||||||
|
|
||||||
#include "Filesystem.h"
|
#include "Filesystem.h"
|
||||||
|
|
||||||
|
#include "SDL.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
size_t getDriveDelim(const std::string &input)
|
size_t getDriveDelim(const std::string &input)
|
||||||
@@ -47,6 +50,62 @@ namespace
|
|||||||
{
|
{
|
||||||
return input.substr(getDriveDelim(input)+1);
|
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
|
namespace love
|
||||||
@@ -147,12 +206,30 @@ bool Filesystem::setSource(const char *source)
|
|||||||
if (!game_source.empty())
|
if (!game_source.empty())
|
||||||
return false;
|
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.
|
// 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;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Save the game source.
|
// Save the game source.
|
||||||
game_source = std::string(source);
|
game_source = new_search_path;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -418,6 +418,9 @@ public class SDLActivity extends Activity {
|
|||||||
class SDLMain implements Runnable {
|
class SDLMain implements Runnable {
|
||||||
public String path;
|
public String path;
|
||||||
|
|
||||||
|
public SDLMain () {
|
||||||
|
this.path = "";
|
||||||
|
}
|
||||||
public SDLMain (String path) {
|
public SDLMain (String path) {
|
||||||
this.path = path;
|
this.path = path;
|
||||||
}
|
}
|
||||||
@@ -425,10 +428,7 @@ class SDLMain implements Runnable {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Runs SDL_main()
|
// Runs SDL_main()
|
||||||
Log.v("Java", "calling with arg " + this.path);
|
|
||||||
SDLActivity.nativeInit(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;
|
apkFilePath = appInfo.sourceDir;
|
||||||
|
|
||||||
SDLActivity.mSDLThread = new Thread(new SDLMain(apkFilePath), "SDLThread");
|
SDLActivity.mSDLThread = new Thread(new SDLMain(), "SDLThread");
|
||||||
enableSensor(Sensor.TYPE_ACCELEROMETER, true);
|
enableSensor(Sensor.TYPE_ACCELEROMETER, true);
|
||||||
SDLActivity.mSDLThread.start();
|
SDLActivity.mSDLThread.start();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user