# HG changeset patch # User Michael Pavone # Date 1743053422 25200 # Node ID 143cb5762ec904084d6b4bcd72c0a802bbd06dcd # Parent c4256ce2c45a926796b0a32a7736305509abebde Fix generating shader list on Android diff -r c4256ce2c45a -r 143cb5762ec9 android/app/src/main/java/com/retrodev/blastem/BlastEmActivity.java --- 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) { diff -r c4256ce2c45a -r 143cb5762ec9 nuklear_ui/blastem_nuklear.c --- 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; diff -r c4256ce2c45a -r 143cb5762ec9 util.c --- 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 +#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 diff -r c4256ce2c45a -r 143cb5762ec9 util.h --- 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