From 3f9c8d85355099cd1817fc557912120557d74059 Mon Sep 17 00:00:00 2001 From: offtkp Date: Tue, 21 Nov 2023 02:55:37 +0200 Subject: [PATCH] Silly filepicker --- src/jni_driver.cpp | 14 +- src/pandroid/app/src/main/AndroidManifest.xml | 2 +- .../com/panda3ds/pandroid/AlberDriver.java | 2 + .../com/panda3ds/pandroid/MainActivity.java | 48 ++++++- .../panda3ds/pandroid/PandaGlRenderer.java | 12 +- .../java/com/panda3ds/pandroid/PathUtils.java | 125 ++++++++++++++++++ 6 files changed, 193 insertions(+), 10 deletions(-) create mode 100644 src/pandroid/app/src/main/java/com/panda3ds/pandroid/PathUtils.java diff --git a/src/jni_driver.cpp b/src/jni_driver.cpp index 11d19963..74ac0732 100644 --- a/src/jni_driver.cpp +++ b/src/jni_driver.cpp @@ -7,6 +7,7 @@ std::unique_ptr emulator = nullptr; RendererGL* renderer = nullptr; +bool romLoaded = false; extern "C" JNIEXPORT void JNICALL Java_com_panda3ds_pandroid_AlberDriver_Initialize(JNIEnv* env, jobject obj) { emulator = std::make_unique(); @@ -20,8 +21,6 @@ extern "C" JNIEXPORT void JNICALL Java_com_panda3ds_pandroid_AlberDriver_Initial } __android_log_print(ANDROID_LOG_INFO, "AlberDriver", "OpenGL ES %d.%d", GLVersion.major, GLVersion.minor); emulator->initGraphicsContext(nullptr); - // girlboss it for now :3 - emulator->loadROM("/data/data/com.panda3ds.pandroid/files/rom.3ds"); } extern "C" JNIEXPORT void JNICALL Java_com_panda3ds_pandroid_AlberDriver_RunFrame(JNIEnv* env, jobject obj, jint fbo) { @@ -33,4 +32,15 @@ extern "C" JNIEXPORT void JNICALL Java_com_panda3ds_pandroid_AlberDriver_RunFram extern "C" JNIEXPORT void JNICALL Java_com_panda3ds_pandroid_AlberDriver_Finalize(JNIEnv* env, jobject obj) { emulator = nullptr; renderer = nullptr; +} + +extern "C" JNIEXPORT jboolean JNICALL Java_com_panda3ds_pandroid_AlberDriver_HasRomLoaded(JNIEnv* env, jobject obj) { + return romLoaded; +} + +extern "C" JNIEXPORT void JNICALL Java_com_panda3ds_pandroid_AlberDriver_LoadRom(JNIEnv* env, jobject obj, jstring path) { + const char* pathStr = env->GetStringUTFChars(path, nullptr); + __android_log_print(ANDROID_LOG_INFO, "AlberDriver", "Loading ROM %s", pathStr); + romLoaded = emulator->loadROM(pathStr); + env->ReleaseStringUTFChars(path, pathStr); } \ No newline at end of file diff --git a/src/pandroid/app/src/main/AndroidManifest.xml b/src/pandroid/app/src/main/AndroidManifest.xml index 8047484a..0effd35f 100644 --- a/src/pandroid/app/src/main/AndroidManifest.xml +++ b/src/pandroid/app/src/main/AndroidManifest.xml @@ -22,5 +22,5 @@ - + \ No newline at end of file diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/AlberDriver.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/AlberDriver.java index da3b2020..1021e1d2 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/AlberDriver.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/AlberDriver.java @@ -8,6 +8,8 @@ public class AlberDriver { public static native void Initialize(); public static native void RunFrame(int fbo); + public static native boolean HasRomLoaded(); + public static native void LoadRom(String path); public static native void Finalize(); static { diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/MainActivity.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/MainActivity.java index 8cb6b6d1..b7b3726d 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/MainActivity.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/MainActivity.java @@ -1,21 +1,67 @@ package com.panda3ds.pandroid; import androidx.appcompat.app.AppCompatActivity; +import static android.provider.Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION; +import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.view.WindowInsets; import android.view.View; +import android.os.Environment; +import android.widget.Toast; +import android.widget.FrameLayout; +import com.panda3ds.pandroid.PathUtils; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; public class MainActivity extends AppCompatActivity { PandaGlSurfaceView glView; + private static final int PICK_3DS_ROM = 2; + + private void openFile() { + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("*/*"); + startActivityForResult(intent, PICK_3DS_ROM); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - + if (!Environment.isExternalStorageManager()) { + Intent intent = new Intent(ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION); + startActivity(intent); + } + glView = new PandaGlSurfaceView(this); setContentView(glView); + FloatingActionButton fab = new FloatingActionButton(this); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + openFile(); + } + }); + FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(200, 200); + addContentView(fab, params); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == PICK_3DS_ROM) { + if (resultCode == RESULT_OK) { + String path = PathUtils.getPath(getApplicationContext(), data.getData()); + Toast.makeText(getApplicationContext(), "pandroid opening " + path, Toast.LENGTH_LONG).show(); + glView.queueEvent(new Runnable() { + @Override + public void run() { + AlberDriver.LoadRom(path); + } + }); + } + } } } \ No newline at end of file diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/PandaGlRenderer.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/PandaGlRenderer.java index cc6499e6..cb6f90da 100644 --- a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/PandaGlRenderer.java +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/PandaGlRenderer.java @@ -62,12 +62,12 @@ public class PandaGlRenderer implements GLSurfaceView.Renderer { } public void onDrawFrame(GL10 unused) { - AlberDriver.RunFrame(screenFbo); - // is this needed? prob not - glBindTexture(GL_TEXTURE_2D, 0); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - glBindFramebuffer(GL_READ_FRAMEBUFFER, screenFbo); - glBlitFramebuffer(0, 0, 400, 480, 0, 0, screenWidth, screenHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); + if (AlberDriver.HasRomLoaded()) { + AlberDriver.RunFrame(screenFbo); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER, screenFbo); + glBlitFramebuffer(0, 0, 400, 480, 0, 0, screenWidth, screenHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); + } } public void onSurfaceChanged(GL10 unused, int width, int height) { diff --git a/src/pandroid/app/src/main/java/com/panda3ds/pandroid/PathUtils.java b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/PathUtils.java new file mode 100644 index 00000000..740223eb --- /dev/null +++ b/src/pandroid/app/src/main/java/com/panda3ds/pandroid/PathUtils.java @@ -0,0 +1,125 @@ +package com.panda3ds.pandroid; + +import android.content.ContentUris; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; + +public class PathUtils { + + public static String getPath(final Context context, final Uri uri) { + + // DocumentProvider + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) { + + if (isExternalStorageDocument(uri)) {// ExternalStorageProvider + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + String storageDefinition; + + + if("primary".equalsIgnoreCase(type)){ + + return Environment.getExternalStorageDirectory() + "/" + split[1]; + + } else { + + if(Environment.isExternalStorageRemovable()){ + storageDefinition = "EXTERNAL_STORAGE"; + + } else{ + storageDefinition = "SECONDARY_STORAGE"; + } + + return System.getenv(storageDefinition) + "/" + split[1]; + } + + } else if (isDownloadsDocument(uri)) {// DownloadsProvider + + final String id = DocumentsContract.getDocumentId(uri); + final Uri contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + + return getDataColumn(context, contentUri, null, null); + + } else if (isMediaDocument(uri)) {// MediaProvider + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri = null; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[]{ + split[1] + }; + + return getDataColumn(context, contentUri, selection, selectionArgs); + } + + } else if ("content".equalsIgnoreCase(uri.getScheme())) {// MediaStore (and general) + + // Return the remote address + if (isGooglePhotosUri(uri)) + return uri.getLastPathSegment(); + + return getDataColumn(context, uri, null, null); + + } else if ("file".equalsIgnoreCase(uri.getScheme())) {// File + return uri.getPath(); + } + + return null; + } + + public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { + + Cursor cursor = null; + final String column = "_data"; + final String[] projection = { + column + }; + + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); + if (cursor != null && cursor.moveToFirst()) { + final int column_index = cursor.getColumnIndexOrThrow(column); + return cursor.getString(column_index); + } + } finally { + if (cursor != null) + cursor.close(); + } + return null; + } + + + public static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + + public static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + public static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + + public static boolean isGooglePhotosUri(Uri uri) { + return "com.google.android.apps.photos.content".equals(uri.getAuthority()); + } +} \ No newline at end of file