diff --git a/src/twn_audio.c b/src/twn_audio.c index e4c599c..cf82c54 100644 --- a/src/twn_audio.c +++ b/src/twn_audio.c @@ -72,6 +72,7 @@ static AudioFileType infer_audio_file_type(const char *path) { size_t const path_len = SDL_strlen(path); for (int i = 0; i < AUDIO_FILE_TYPE_COUNT; ++i) { + if (path_len <= audio_exts_len[i]) continue; if (SDL_strncmp(&path[path_len - audio_exts_len[i]], audio_exts[i], audio_exts_len[i]) == 0) return (AudioFileType)i; } diff --git a/src/twn_util.c b/src/twn_util.c index 31bcaee..cf4abe6 100644 --- a/src/twn_util.c +++ b/src/twn_util.c @@ -151,6 +151,39 @@ char *file_to_str(const char *path, size_t *out_len) { return str_out; } + +struct ImageCollectionData { + char *list; + size_t length; +}; +static PHYSFS_EnumerateCallbackResult image_collection_callback(void *data, + const char *origdir, + const char *fname) +{ + struct ImageCollectionData *result = data; + (void)origdir; + + /* TODO: settle down on supported images */ + size_t file_len = SDL_strlen(fname); + size_t dir_len = SDL_strlen(origdir); + + if (CHECK_ENDING(fname, file_len, ".png")) { + result->list = SDL_realloc(result->list, result->length + dir_len + file_len + 1); + if (result->length != 0) + result->list[result->length-1] = '\n'; + SDL_strlcpy(&result->list[result->length], origdir, dir_len); + result->length += dir_len; + result->list[result->length-1] = '/'; + SDL_strlcpy(&result->list[result->length], fname, file_len + 1); + result->length += file_len + 1; + result->list[result->length-1] = '\0'; + } + + return PHYSFS_ENUM_OK; +} + + +/* TODO: caching on file and operation inputs */ static String *read_files; String file_read(char const *file, char const *operation) { @@ -175,9 +208,8 @@ String file_read(char const *file, char const *operation) { arrpush(read_files, s); return s; - } - else if (SDL_strncmp(operation, ":binary", sizeof (":binary") - 1) == 0) { + } else if (SDL_strncmp(operation, ":binary", sizeof (":binary") - 1) == 0) { uint8_t *data; int64_t length = file_to_bytes(file, &data); @@ -193,6 +225,19 @@ String file_read(char const *file, char const *operation) { bool exists = file_exists(file); return exists ? (String){"yes", 3} : (String){"no", 2}; + } else if (SDL_strncmp(operation, ":images", sizeof (":images") - 1) == 0) { + struct ImageCollectionData list = {0}; + if (PHYSFS_enumerate(file, image_collection_callback, &list) == 0) { + CRY_PHYSFS("Error enumerating images"); + if (list.list) SDL_free(list.list); + return (String){NULL, 0}; + } + + String s = {(char *)list.list, (float)list.length - 1}; + arrpush(read_files, s); + + return s; + } else log_warn("No valid operation specified by %s", operation); diff --git a/src/twn_util_c.h b/src/twn_util_c.h index 2edca8e..1b41827 100644 --- a/src/twn_util_c.h +++ b/src/twn_util_c.h @@ -21,6 +21,8 @@ void cry_impl(const char *file, const int line, const char *title, const char *t #define CRY_PHYSFS(title) \ cry_impl(__FILE__, __LINE__, title, PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode())) +#define CHECK_ENDING(p_s, p_ss, p_e) ((p_ss) >= sizeof p_e && SDL_strncmp(&((p_s)[(p_ss) - (sizeof p_e - 1)]), p_e, sizeof p_e - 1) == 0) + void log_info(const char *restrict format, ...); void log_critical(const char *restrict format, ...); void log_warn(const char *restrict format, ...);