changeset 2682:143cb5762ec9

Fix generating shader list on Android
author Michael Pavone <pavone@retrodev.com>
date Wed, 26 Mar 2025 22:30:22 -0700
parents c4256ce2c45a
children 596786e43c24
files android/app/src/main/java/com/retrodev/blastem/BlastEmActivity.java nuklear_ui/blastem_nuklear.c util.c util.h
diffstat 4 files changed, 76 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/android/app/src/main/java/com/retrodev/blastem/BlastEmActivity.java	Wed Mar 26 01:20:55 2025 -0700
+++ b/android/app/src/main/java/com/retrodev/blastem/BlastEmActivity.java	Wed Mar 26 22:30:22 2025 -0700
@@ -13,6 +13,7 @@
 import android.view.View;
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Map;
 import java.util.HashMap;
@@ -128,6 +129,15 @@
 		return 0;
 	}
 	
+	public String[] getAssetsList(String path) {
+		try {
+			return getAssets().list(path);
+		} catch (IOException e) {
+			Log.w("BlastEm", "Failed to get assets at '" + path + "': " + e);
+		}
+		return new String[0];
+	}
+	
 	@Override
 	public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
 		if (requestCode == DOC_TREE_CODE) {
--- a/nuklear_ui/blastem_nuklear.c	Wed Mar 26 01:20:55 2025 -0700
+++ b/nuklear_ui/blastem_nuklear.c	Wed Mar 26 22:30:22 2025 -0700
@@ -2092,13 +2092,7 @@
 		progs = NULL;
 		prog_storage = 0;
 	}
-#ifdef DATA_PATH
-	shader_dir = path_append(DATA_PATH, "shaders");
-#else
-	shader_dir = path_append(get_exe_dir(), "shaders");
-#endif
-	entries = get_dir_list(shader_dir, &num_entries);
-	free(shader_dir);
+	entries = get_bundled_dir_list("shaders", &num_entries);
 	progs = get_shader_progs(entries, num_entries, progs, &num_progs, &prog_storage);
 	*num_out = num_progs;
 	return progs;
--- a/util.c	Wed Mar 26 01:20:55 2025 -0700
+++ b/util.c	Wed Mar 26 22:30:22 2025 -0700
@@ -866,6 +866,43 @@
 }
 #include <dirent.h>
 
+#ifdef __ANDROID__
+static dir_entry *jdir_list_helper(JNIEnv *env, jmethodID meth, char *path, size_t *numret)
+{
+	jstring jpath = (*env)->NewStringUTF(env, path);
+	jobject activity = SDL_AndroidGetActivity();
+	jobject ret = (*env)->CallObjectMethod(env, activity, meth, jpath);
+	dir_entry *res = NULL;
+	if (ret) {
+		jsize num = (*env)->GetArrayLength(env, ret);
+		if (numret) {
+			*numret = num;
+		}
+		res = calloc(num, sizeof(dir_entry));
+		for (jsize i = 0; i < num; i++)
+		{
+			jstring entry = (*env)->GetObjectArrayElement(env, ret, i);
+			char const *tmp = (*env)->GetStringUTFChars(env, entry, NULL);
+			jsize len = (*env)->GetStringUTFLength(env, entry);
+			res[i].name = calloc(len + 1, 1);
+			res[i].is_dir = tmp[len-1] == '/';
+			memcpy(res[i].name, tmp, res[i].is_dir ? len -1 : len);
+			(*env)->ReleaseStringUTFChars(env, entry, tmp);
+		}
+		(*env)->DeleteLocalRef(env, ret);
+	}
+	
+	(*env)->DeleteLocalRef(env, activity);
+	if (!res) {
+		if (numret) {
+			*numret = 0;
+		}
+		return NULL;
+	}
+	return res;
+}
+#endif
+
 dir_entry *get_dir_list(char *path, size_t *numret)
 {
 #ifdef __ANDROID__
@@ -883,37 +920,7 @@
 			fatal_error("Failed to find method %s\n", read_uri_dir_name);
 		}
 		debug_message("get_dir_list(%s) using Storage Access Framework\n", path);
-		jstring jpath = (*env)->NewStringUTF(env, path);
-		jobject activity = SDL_AndroidGetActivity();
-		jobject ret = (*env)->CallObjectMethod(env, activity, meth, jpath);
-		dir_entry *res = NULL;
-		if (ret) {
-			jsize num = (*env)->GetArrayLength(env, ret);
-			if (numret) {
-				*numret = num;
-			}
-			res = calloc(num, sizeof(dir_entry));
-			for (jsize i = 0; i < num; i++)
-			{
-				jstring entry = (*env)->GetObjectArrayElement(env, ret, i);
-				char const *tmp = (*env)->GetStringUTFChars(env, entry, NULL);
-				jsize len = (*env)->GetStringUTFLength(env, entry);
-				res[i].name = calloc(len + 1, 1);
-				res[i].is_dir = tmp[len-1] == '/';
-				memcpy(res[i].name, tmp, res[i].is_dir ? len -1 : len);
-				(*env)->ReleaseStringUTFChars(env, entry, tmp);
-			}
-			(*env)->DeleteLocalRef(env, ret);
-		}
-		
-		(*env)->DeleteLocalRef(env, activity);
-		if (!res) {
-			if (numret) {
-				*numret = 0;
-			}
-			return NULL;
-		}
-		return res;
+		return jdir_list_helper(env, meth, path, numret);
 	}
 #endif
 	DIR *d = opendir(path);
@@ -1055,6 +1062,22 @@
 	return ret;
 }
 
+dir_entry *get_bundled_dir_list(char *name, size_t *num_out)
+{
+	static const char activity_class_name[] = "com/retrodev/blastem/BlastEmActivity";
+	static const char get_assets_list_name[] = "getAssetsList";
+	JNIEnv *env = SDL_AndroidGetJNIEnv();
+	jclass act_class = (*env)->FindClass(env, activity_class_name);
+	if (!act_class) {
+		fatal_error("Failed to find activity class %s\n", activity_class_name);
+	}
+	jmethodID meth = (*env)->GetMethodID(env, act_class, get_assets_list_name, "(Ljava/lang/String;)[Ljava/lang/String;");
+	if (!meth) {
+		fatal_error("Failed to find method %s\n", get_assets_list_name);
+	}
+	return jdir_list_helper(env, meth, name, num_out);
+}
+
 static int open_uri(const char *path, const char *mode)
 {
 	static const char activity_class_name[] = "com/retrodev/blastem/BlastEmActivity";
@@ -1173,6 +1196,14 @@
 	fclose(f);
 	return ret;
 }
+
+dir_entry *get_bundled_dir_list(char *name, size_t *num_out)
+{
+	char *path = bundled_file_path(name);
+	dir_entry *ret = get_dir_list(path, num_out);
+	free(path);
+	return ret;
+}
 #endif //ISLIB
 
 #ifdef _WIN32
--- a/util.h	Wed Mar 26 01:20:55 2025 -0700
+++ b/util.h	Wed Mar 26 22:30:22 2025 -0700
@@ -70,8 +70,10 @@
 char *bundled_file_path(char *name);
 //Reads a file bundled with the executable
 char *read_bundled_file(char *name, uint32_t *sizeret);
-//Retunrs an array of normal files and directories residing in a directory
+//Returns an array of normal files and directories residing in a directory
 dir_entry *get_dir_list(char *path, size_t *numret);
+//Returns an array of normal files and directories residing in a bundled directory
+dir_entry *get_bundled_dir_list(char *name, size_t *num_out);
 //Frees a dir list returned by get_dir_list
 void free_dir_list(dir_entry *list, size_t numentries);
 //Performs a case-insensitive sort by file name on a dir list