comparison util.c @ 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
comparison
equal deleted inserted replaced
2681:c4256ce2c45a 2682:143cb5762ec9
864 } 864 }
865 return exe_dir; 865 return exe_dir;
866 } 866 }
867 #include <dirent.h> 867 #include <dirent.h>
868 868
869 #ifdef __ANDROID__
870 static dir_entry *jdir_list_helper(JNIEnv *env, jmethodID meth, char *path, size_t *numret)
871 {
872 jstring jpath = (*env)->NewStringUTF(env, path);
873 jobject activity = SDL_AndroidGetActivity();
874 jobject ret = (*env)->CallObjectMethod(env, activity, meth, jpath);
875 dir_entry *res = NULL;
876 if (ret) {
877 jsize num = (*env)->GetArrayLength(env, ret);
878 if (numret) {
879 *numret = num;
880 }
881 res = calloc(num, sizeof(dir_entry));
882 for (jsize i = 0; i < num; i++)
883 {
884 jstring entry = (*env)->GetObjectArrayElement(env, ret, i);
885 char const *tmp = (*env)->GetStringUTFChars(env, entry, NULL);
886 jsize len = (*env)->GetStringUTFLength(env, entry);
887 res[i].name = calloc(len + 1, 1);
888 res[i].is_dir = tmp[len-1] == '/';
889 memcpy(res[i].name, tmp, res[i].is_dir ? len -1 : len);
890 (*env)->ReleaseStringUTFChars(env, entry, tmp);
891 }
892 (*env)->DeleteLocalRef(env, ret);
893 }
894
895 (*env)->DeleteLocalRef(env, activity);
896 if (!res) {
897 if (numret) {
898 *numret = 0;
899 }
900 return NULL;
901 }
902 return res;
903 }
904 #endif
905
869 dir_entry *get_dir_list(char *path, size_t *numret) 906 dir_entry *get_dir_list(char *path, size_t *numret)
870 { 907 {
871 #ifdef __ANDROID__ 908 #ifdef __ANDROID__
872 debug_message("get_dir_list(%s)\n", path); 909 debug_message("get_dir_list(%s)\n", path);
873 if (startswith(path, "content://")) { 910 if (startswith(path, "content://")) {
881 jmethodID meth = (*env)->GetMethodID(env, act_class, read_uri_dir_name, "(Ljava/lang/String;)[Ljava/lang/String;"); 918 jmethodID meth = (*env)->GetMethodID(env, act_class, read_uri_dir_name, "(Ljava/lang/String;)[Ljava/lang/String;");
882 if (!meth) { 919 if (!meth) {
883 fatal_error("Failed to find method %s\n", read_uri_dir_name); 920 fatal_error("Failed to find method %s\n", read_uri_dir_name);
884 } 921 }
885 debug_message("get_dir_list(%s) using Storage Access Framework\n", path); 922 debug_message("get_dir_list(%s) using Storage Access Framework\n", path);
886 jstring jpath = (*env)->NewStringUTF(env, path); 923 return jdir_list_helper(env, meth, path, numret);
887 jobject activity = SDL_AndroidGetActivity();
888 jobject ret = (*env)->CallObjectMethod(env, activity, meth, jpath);
889 dir_entry *res = NULL;
890 if (ret) {
891 jsize num = (*env)->GetArrayLength(env, ret);
892 if (numret) {
893 *numret = num;
894 }
895 res = calloc(num, sizeof(dir_entry));
896 for (jsize i = 0; i < num; i++)
897 {
898 jstring entry = (*env)->GetObjectArrayElement(env, ret, i);
899 char const *tmp = (*env)->GetStringUTFChars(env, entry, NULL);
900 jsize len = (*env)->GetStringUTFLength(env, entry);
901 res[i].name = calloc(len + 1, 1);
902 res[i].is_dir = tmp[len-1] == '/';
903 memcpy(res[i].name, tmp, res[i].is_dir ? len -1 : len);
904 (*env)->ReleaseStringUTFChars(env, entry, tmp);
905 }
906 (*env)->DeleteLocalRef(env, ret);
907 }
908
909 (*env)->DeleteLocalRef(env, activity);
910 if (!res) {
911 if (numret) {
912 *numret = 0;
913 }
914 return NULL;
915 }
916 return res;
917 } 924 }
918 #endif 925 #endif
919 DIR *d = opendir(path); 926 DIR *d = opendir(path);
920 if (!d) { 927 if (!d) {
921 if (numret) { 928 if (numret) {
1053 } 1060 }
1054 SDL_RWclose(rw); 1061 SDL_RWclose(rw);
1055 return ret; 1062 return ret;
1056 } 1063 }
1057 1064
1065 dir_entry *get_bundled_dir_list(char *name, size_t *num_out)
1066 {
1067 static const char activity_class_name[] = "com/retrodev/blastem/BlastEmActivity";
1068 static const char get_assets_list_name[] = "getAssetsList";
1069 JNIEnv *env = SDL_AndroidGetJNIEnv();
1070 jclass act_class = (*env)->FindClass(env, activity_class_name);
1071 if (!act_class) {
1072 fatal_error("Failed to find activity class %s\n", activity_class_name);
1073 }
1074 jmethodID meth = (*env)->GetMethodID(env, act_class, get_assets_list_name, "(Ljava/lang/String;)[Ljava/lang/String;");
1075 if (!meth) {
1076 fatal_error("Failed to find method %s\n", get_assets_list_name);
1077 }
1078 return jdir_list_helper(env, meth, name, num_out);
1079 }
1080
1058 static int open_uri(const char *path, const char *mode) 1081 static int open_uri(const char *path, const char *mode)
1059 { 1082 {
1060 static const char activity_class_name[] = "com/retrodev/blastem/BlastEmActivity"; 1083 static const char activity_class_name[] = "com/retrodev/blastem/BlastEmActivity";
1061 static const char open_uri_as_fd_name[] = "openUriAsFd"; 1084 static const char open_uri_as_fd_name[] = "openUriAsFd";
1062 JNIEnv *env = SDL_AndroidGetJNIEnv(); 1085 JNIEnv *env = SDL_AndroidGetJNIEnv();
1171 ret = NULL; 1194 ret = NULL;
1172 } 1195 }
1173 fclose(f); 1196 fclose(f);
1174 return ret; 1197 return ret;
1175 } 1198 }
1199
1200 dir_entry *get_bundled_dir_list(char *name, size_t *num_out)
1201 {
1202 char *path = bundled_file_path(name);
1203 dir_entry *ret = get_dir_list(path, num_out);
1204 free(path);
1205 return ret;
1206 }
1176 #endif //ISLIB 1207 #endif //ISLIB
1177 1208
1178 #ifdef _WIN32 1209 #ifdef _WIN32
1179 char const *get_userdata_dir() 1210 char const *get_userdata_dir()
1180 { 1211 {