Mercurial > repos > blastem
comparison util.c @ 2681:c4256ce2c45a
Updated Android port using gradle toolchain and with basic Storage Access Framework support for Android 11+ support
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Wed, 26 Mar 2025 01:20:55 -0700 |
parents | bebc3589dedf |
children | 143cb5762ec9 |
comparison
equal
deleted
inserted
replaced
2680:e3394457427e | 2681:c4256ce2c45a |
---|---|
9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
10 #include <errno.h> | 10 #include <errno.h> |
11 | 11 |
12 #ifdef __ANDROID__ | 12 #ifdef __ANDROID__ |
13 #include <android/log.h> | 13 #include <android/log.h> |
14 #include <SDL_system.h> | |
15 #include <jni.h> | |
14 #define info_puts(msg) __android_log_write(ANDROID_LOG_INFO, "BlastEm", msg) | 16 #define info_puts(msg) __android_log_write(ANDROID_LOG_INFO, "BlastEm", msg) |
15 #define warning_puts(msg) __android_log_write(ANDROID_LOG_WARN, "BlastEm", msg) | 17 #define warning_puts(msg) __android_log_write(ANDROID_LOG_WARN, "BlastEm", msg) |
16 #define fatal_puts(msg) __android_log_write(ANDROID_LOG_FATAL, "BlastEm", msg) | 18 #define fatal_puts(msg) __android_log_write(ANDROID_LOG_FATAL, "BlastEm", msg) |
17 | 19 |
18 #define info_printf(msg, args) __android_log_vprint(ANDROID_LOG_INFO, "BlastEm", msg, args) | 20 #define info_printf(msg, args) __android_log_vprint(ANDROID_LOG_INFO, "BlastEm", msg, args) |
864 } | 866 } |
865 #include <dirent.h> | 867 #include <dirent.h> |
866 | 868 |
867 dir_entry *get_dir_list(char *path, size_t *numret) | 869 dir_entry *get_dir_list(char *path, size_t *numret) |
868 { | 870 { |
871 #ifdef __ANDROID__ | |
872 debug_message("get_dir_list(%s)\n", path); | |
873 if (startswith(path, "content://")) { | |
874 static const char activity_class_name[] = "com/retrodev/blastem/BlastEmActivity"; | |
875 static const char read_uri_dir_name[] = "readUriDir"; | |
876 JNIEnv *env = SDL_AndroidGetJNIEnv(); | |
877 jclass act_class = (*env)->FindClass(env, activity_class_name); | |
878 if (!act_class) { | |
879 fatal_error("Failed to find activity class %s\n", activity_class_name); | |
880 } | |
881 jmethodID meth = (*env)->GetMethodID(env, act_class, read_uri_dir_name, "(Ljava/lang/String;)[Ljava/lang/String;"); | |
882 if (!meth) { | |
883 fatal_error("Failed to find method %s\n", read_uri_dir_name); | |
884 } | |
885 debug_message("get_dir_list(%s) using Storage Access Framework\n", path); | |
886 jstring jpath = (*env)->NewStringUTF(env, path); | |
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 } | |
918 #endif | |
869 DIR *d = opendir(path); | 919 DIR *d = opendir(path); |
870 if (!d) { | 920 if (!d) { |
871 if (numret) { | 921 if (numret) { |
872 *numret = 0; | 922 *numret = 0; |
873 } | 923 } |
1002 ret = NULL; | 1052 ret = NULL; |
1003 } | 1053 } |
1004 SDL_RWclose(rw); | 1054 SDL_RWclose(rw); |
1005 return ret; | 1055 return ret; |
1006 } | 1056 } |
1007 #endif | 1057 |
1058 static int open_uri(const char *path, const char *mode) | |
1059 { | |
1060 static const char activity_class_name[] = "com/retrodev/blastem/BlastEmActivity"; | |
1061 static const char open_uri_as_fd_name[] = "openUriAsFd"; | |
1062 JNIEnv *env = SDL_AndroidGetJNIEnv(); | |
1063 jclass act_class = (*env)->FindClass(env, activity_class_name); | |
1064 if (!act_class) { | |
1065 fatal_error("Failed to find activity class %s\n", activity_class_name); | |
1066 } | |
1067 jmethodID meth = (*env)->GetMethodID(env, act_class, open_uri_as_fd_name, "(Ljava/lang/String;Ljava/lang/String;)I"); | |
1068 if (!meth) { | |
1069 fatal_error("Failed to find method %s\n", open_uri_as_fd_name); | |
1070 } | |
1071 jobject activity = SDL_AndroidGetActivity(); | |
1072 jstring jpath = (*env)->NewStringUTF(env, path); | |
1073 jstring jmode = (*env)->NewStringUTF(env, mode); | |
1074 int fd = (*env)->CallIntMethod(env, activity, meth, jpath, jmode); | |
1075 (*env)->DeleteLocalRef(env, activity); | |
1076 return fd; | |
1077 } | |
1078 | |
1079 FILE* fopen_wrapper(const char *path, const char *mode) | |
1080 { | |
1081 if (startswith(path, "content://")) { | |
1082 debug_message("fopen_wrapper(%s, %s) - Using Storage Access Framework\n", path, mode); | |
1083 int fd = open_uri(path, mode); | |
1084 if (!fd) { | |
1085 return NULL; | |
1086 } | |
1087 return fdopen(fd, mode); | |
1088 } else { | |
1089 debug_message("fopen_wrapper(%s, %s) - Norma fopen\n", path, mode); | |
1090 return fopen(path, mode); | |
1091 } | |
1092 } | |
1093 | |
1094 #ifndef DISABLE_ZLIB | |
1095 gzFile gzopen_wrapper(const char *path, const char *mode) | |
1096 { | |
1097 if (startswith(path, "content://")) { | |
1098 debug_message("gzopen_wrapper(%s, %s) - Using Storage Access Framework\n", path, mode); | |
1099 int fd = open_uri(path, mode); | |
1100 if (!fd) { | |
1101 return NULL; | |
1102 } | |
1103 return gzdopen(fd, mode); | |
1104 } else { | |
1105 debug_message("fopen_wrapper(%s, %s) - Norma gzopen\n", path, mode); | |
1106 return gzopen(path, mode); | |
1107 } | |
1108 } | |
1109 #endif | |
1110 #endif // IS_LIB | |
1008 | 1111 |
1009 char const *get_config_dir() | 1112 char const *get_config_dir() |
1010 { | 1113 { |
1011 return SDL_AndroidGetInternalStoragePath(); | 1114 return SDL_AndroidGetInternalStoragePath(); |
1012 } | 1115 } |