From: Holger Schemel Date: Fri, 24 May 2024 14:35:49 +0000 (+0200) Subject: added support for opening level set zip files in Android version X-Git-Tag: 4.4.0.0-test-2~22 X-Git-Url: https://git.artsoft.org/?a=commitdiff_plain;h=d30944f339893e4c4c6bc3280b8dc84226aa55f9;p=rocksndiamonds.git added support for opening level set zip files in Android version --- diff --git a/build-projects/android/app/src/main/AndroidManifest.xml.tmpl b/build-projects/android/app/src/main/AndroidManifest.xml.tmpl index 8331804d..9a90444f 100644 --- a/build-projects/android/app/src/main/AndroidManifest.xml.tmpl +++ b/build-projects/android/app/src/main/AndroidManifest.xml.tmpl @@ -55,6 +55,11 @@ + + + + + diff --git a/build-projects/android/app/src/main/java/org/artsoft/rocksndiamonds/rocksndiamonds.java b/build-projects/android/app/src/main/java/org/artsoft/rocksndiamonds/rocksndiamonds.java index eeec2ea4..ee7aed02 100644 --- a/build-projects/android/app/src/main/java/org/artsoft/rocksndiamonds/rocksndiamonds.java +++ b/build-projects/android/app/src/main/java/org/artsoft/rocksndiamonds/rocksndiamonds.java @@ -3,4 +3,118 @@ package org.artsoft.rocksndiamonds; import org.libsdl.app.SDLActivity; -public class rocksndiamonds extends SDLActivity { } +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.os.ParcelFileDescriptor; +import android.provider.OpenableColumns; +import android.util.Log; + +public class rocksndiamonds extends SDLActivity { + private static final String TAG = "RND"; + private String[] args; + + @Override + protected String[] getArguments() { + return args; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + Log.d(TAG, "onCreate"); + + // init program arguments + args = new String[0]; + + // prevent SDL from sending "drop file" event on app start; use program arguments instead + Intent intent = getIntent(); + handleIntent(intent, true); + intent.setData(null); + + super.onCreate(savedInstanceState); + } + + @Override + protected void onNewIntent(Intent intent) { + Log.d(TAG, "onNewIntent"); + + // handle file opened with "open with" when app is already running + handleIntent(intent, false); + } + + private void handleIntent(Intent intent, boolean onCreate) { + Log.d(TAG, "handleIntent"); + + Uri uri = intent.getData(); + if (uri == null) { + Log.d(TAG, "handleIntent: uri == null"); + return; + } + + if (onCreate) { + Log.d(TAG, "handleIntent: starting app with file as argument"); + + // app not running yet -- starting app with "--drop-file" argument + setProgramArgs(uri); + } else { + Log.d(TAG, "handleIntent: sending drop event to running app"); + + // app already running -- sending file as a "drop file" event + sendUriAsDroppedFile(uri); + } + } + + public void sendUriAsDroppedFile(Uri uri) { + SDLActivity.onNativeDropFile(getFileDescriptorStringFromUri(uri)); + } + + private int getFileDescriptorFromUri(Uri uri) { + int fd = -1; + + try { + ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(uri, "r"); + if (pfd == null) { + throw new RuntimeException("pfd is null"); + } + + fd = pfd.dup().detachFd(); + pfd.close(); + } catch (Exception e) { + Log.e(TAG, "Failed to convert URI " + uri.toString() + " to file descriptor", e); + } + + return fd; + } + + private String getFileDescriptorStringFromUri(Uri uri) { + return "fd:" + getFileDescriptorFromUri(uri); + } + + private void setProgramArgs(Uri uri) { + Log.d(TAG, "setProgramArgs"); + + // log some file details + Cursor returnCursor = getContentResolver().query(uri, null, null, null, null); + int nameIndex = returnCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + int sizeIndex = returnCursor.getColumnIndex(OpenableColumns.SIZE); + returnCursor.moveToFirst(); + Log.e(TAG, "setProgramArgs: file name: " + returnCursor.getString(nameIndex)); + Log.e(TAG, "setProgramArgs: file size: " + Long.toString(returnCursor.getLong(sizeIndex))); + + String scheme = uri.getScheme(); + if (scheme != null) { + if (scheme.equals("content")) { + // convert URI to file descriptor + String fd = getFileDescriptorStringFromUri(uri); + Log.e(TAG, "setProgramArgs: setting argument to file descriptor: " + fd); + args = new String[]{ "--drop-file", fd }; + } else if (scheme.equals("file")) { + // directly use regular file + String path = uri.getPath(); + Log.e(TAG, "setProgramArgs: setting argument to file path: " + path); + args = new String[]{ "--drop-file", path }; + } + } + } +} diff --git a/src/events.c b/src/events.c index 04f69108..3406adc5 100644 --- a/src/events.c +++ b/src/events.c @@ -1505,7 +1505,8 @@ static int HandleDropFileEvent(char *filename) Debug("event:dropfile", "filename == '%s'", filename); // check and extract dropped zip files into correct user data directory - if (!strSuffixLower(filename, ".zip")) + if (!strSuffixLower(filename, ".zip") && + !strPrefixLower(filename, "fd:")) { Warn("file '%s' not supported", filename); @@ -1615,6 +1616,12 @@ static void HandleDropCompleteEvent(int num_level_sets_succeeded, void HandleDropEvent(Event *event) { + Debug("event:drop", (event->type == SDL_DROPBEGIN ? "SDL_DROPBEGIN" : + event->type == SDL_DROPFILE ? "SDL_DROPFILE" : + event->type == SDL_DROPTEXT ? "SDL_DROPTEXT" : + event->type == SDL_DROPCOMPLETE ? "SDL_DROPCOMPLETE" : + "(unknown drop event type)")); + static boolean confirm_on_drop_complete = FALSE; static int num_level_sets_succeeded = 0; static int num_artwork_sets_succeeded = 0; diff --git a/src/libgame/zip/ioapi.c b/src/libgame/zip/ioapi.c index 0aa6347a..20da1524 100644 --- a/src/libgame/zip/ioapi.c +++ b/src/libgame/zip/ioapi.c @@ -121,7 +121,11 @@ static voidpf ZCALLBACK fopen64_file_func(ZIP_UNUSED voidpf opaque, const void * if ((filename != NULL) && (mode_fopen != NULL)) { - file = fopen64((const char*)filename, mode_fopen); + const char *fd_prefix = "fd:"; + if (strncmp(filename, fd_prefix, strlen(fd_prefix)) == 0) + file = fdopen(dup(atoi(&filename[strlen(fd_prefix)])), mode_fopen); + else + file = fopen64((const char*)filename, mode_fopen); return file_build_ioposix(file, (const char*)filename); } return file;