diff --git a/src/Audio.c b/src/Audio.c index f9bd8a2e9..e4b825d6e 100644 --- a/src/Audio.c +++ b/src/Audio.c @@ -438,12 +438,15 @@ cleanup: return res == ERR_END_OF_STREAM ? 0 : res; } -static void Music_AddFile(const cc_string* path, void* obj) { +static void Music_AddFile(const cc_string* path, void* obj, int isDirectory) { struct StringsBuffer* files = (struct StringsBuffer*)obj; static const cc_string ogg = String_FromConst(".ogg"); - if (!String_CaselessEnds(path, &ogg)) return; - StringsBuffer_Add(files, path); + if (isDirectory) { + Directory_Enum(path, obj, Music_AddFile); + } else if (String_CaselessEnds(path, &ogg)) { + StringsBuffer_Add(files, path); + } } static void Music_RunLoop(void) { diff --git a/src/Game.c b/src/Game.c index c88374481..7339206db 100644 --- a/src/Game.c +++ b/src/Game.c @@ -355,11 +355,12 @@ static void LoadOptions(void) { } #ifdef CC_BUILD_PLUGINS -static void LoadPlugin(const cc_string* path, void* obj) { +static void LoadPlugin(const cc_string* path, void* obj, int isDirectory) { void* lib; void* verSym; /* EXPORT int Plugin_ApiVersion = GAME_API_VER; */ void* compSym; /* EXPORT struct IGameComponent Plugin_Component = { (whatever) } */ int ver; + if (isDirectory) return; /* ignore accepted.txt, deskop.ini, .pdb files, etc */ if (!String_CaselessEnds(path, &DynamicLib_Ext)) return; diff --git a/src/Menus.c b/src/Menus.c index db79d142a..8cbba8486 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -1556,13 +1556,16 @@ static void TexturePackScreen_EntryClick(void* screen, void* widget) { ListScreen_Reload(s); } -static void TexturePackScreen_FilterFiles(const cc_string* path, void* obj) { +static void TexturePackScreen_FilterFiles(const cc_string* path, void* obj, int isDirectory) { static const cc_string zip = String_FromConst(".zip"); cc_string relPath = *path; - if (!String_CaselessEnds(path, &zip)) return; - Utils_UNSAFE_TrimFirstDirectory(&relPath); - StringsBuffer_Add((struct StringsBuffer*)obj, &relPath); + if (isDirectory) { + Directory_Enum(path, obj, TexturePackScreen_FilterFiles); + } else if (String_CaselessEnds(path, &zip)) { + Utils_UNSAFE_TrimFirstDirectory(&relPath); + StringsBuffer_Add((struct StringsBuffer*)obj, &relPath); + } } static void TexturePackScreen_LoadEntries(struct ListScreen* s) { @@ -1787,13 +1790,16 @@ static void LoadLevelScreen_EntryClick(void* screen, void* widget) { ListScreen_Reload(s); } -static void LoadLevelScreen_FilterFiles(const cc_string* path, void* obj) { +static void LoadLevelScreen_FilterFiles(const cc_string* path, void* obj, int isDirectory) { struct MapImporter* imp = MapImporter_Find(path); cc_string relPath = *path; - if (!imp) return; - Utils_UNSAFE_TrimFirstDirectory(&relPath); - StringsBuffer_Add((struct StringsBuffer*)obj, &relPath); + if (isDirectory) { + Directory_Enum(path, obj, LoadLevelScreen_FilterFiles); + } else if (imp) { + Utils_UNSAFE_TrimFirstDirectory(&relPath); + StringsBuffer_Add((struct StringsBuffer*)obj, &relPath); + } } static void LoadLevelScreen_LoadEntries(struct ListScreen* s) { diff --git a/src/Platform.h b/src/Platform.h index ca4b932b3..36e6c7198 100644 --- a/src/Platform.h +++ b/src/Platform.h @@ -185,7 +185,7 @@ int Stopwatch_ElapsedMS(cc_uint64 beg, cc_uint64 end); /* Attempts to create a new directory. */ CC_API cc_result Directory_Create(const cc_string* path); /* Callback function invoked for each file found. */ -typedef void (*Directory_EnumCallback)(const cc_string* filename, void* obj); +typedef void (*Directory_EnumCallback)(const cc_string* filename, void* obj, int isDirectory); /* Invokes a callback function on all filenames in the given directory (and its sub-directories) */ CC_API cc_result Directory_Enum(const cc_string* path, void* obj, Directory_EnumCallback callback); /* Returns non-zero if the given file exists. */ diff --git a/src/Platform_3DS.c b/src/Platform_3DS.c index 09c27d6ec..13e181b5c 100644 --- a/src/Platform_3DS.c +++ b/src/Platform_3DS.c @@ -138,12 +138,7 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall is_dir = entry->d_type == DT_DIR; /* TODO: fallback to stat when this fails */ - if (is_dir) { - res = Directory_Enum(&path, obj, callback); - if (res) { closedir(dirPtr); return res; } - } else { - callback(&path, obj); - } + callback(&path, obj, is_dir); errno = 0; } diff --git a/src/Platform_Dreamcast.c b/src/Platform_Dreamcast.c index 7db8b8270..c11290405 100644 --- a/src/Platform_Dreamcast.c +++ b/src/Platform_Dreamcast.c @@ -243,12 +243,8 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall String_AppendUtf8(&path, src, len); // negative size indicates a directory entry - if (entry->size < 0) { - res = Directory_Enum(&path, obj, callback); - if (res) break; - } else { - callback(&path, obj); - } + int is_dir = entry->size < 0; + callback(&path, obj, is_dir); } int err = errno; // save error from fs_readdir diff --git a/src/Platform_GCWii.c b/src/Platform_GCWii.c index 3c1895adc..989d1c9ad 100644 --- a/src/Platform_GCWii.c +++ b/src/Platform_GCWii.c @@ -174,12 +174,7 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall int is_dir = entry->d_type == DT_DIR; // TODO: fallback to stat when this fails - if (is_dir) { - res = Directory_Enum(&path, obj, callback); - if (res) { closedir(dirPtr); return res; } - } else { - callback(&path, obj); - } + callback(&path, obj, is_dir); errno = 0; } diff --git a/src/Platform_NDS.c b/src/Platform_NDS.c index 355e94b04..5299b859d 100644 --- a/src/Platform_NDS.c +++ b/src/Platform_NDS.c @@ -163,12 +163,8 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall int len = String_Length(src); String_AppendUtf8(&path, src, len); - if (entry->d_type == DT_DIR) { - res = Directory_Enum(&path, obj, callback); - if (res) { closedir(dirPtr); return res; } - } else { - callback(&path, obj); - } + int is_dir = entry->d_type == DT_DIR; + callback(&path, obj, is_dir); errno = 0; } diff --git a/src/Platform_PS2.c b/src/Platform_PS2.c index aee9dac78..601e9cd33 100644 --- a/src/Platform_PS2.c +++ b/src/Platform_PS2.c @@ -166,12 +166,8 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall int len = String_Length(src); String_AppendUtf8(&path, src, len); - if (FIO_SO_ISDIR(entry.stat.mode)) { - res = Directory_Enum(&path, obj, callback); - if (res) break; - } else { - callback(&path, obj); - } + int is_dir = FIO_SO_ISDIR(entry.stat.mode); + callback(&path, obj, is_dir); } fioDclose(fd); diff --git a/src/Platform_PS3.c b/src/Platform_PS3.c index 87b9d74e0..9f3935dbe 100644 --- a/src/Platform_PS3.c +++ b/src/Platform_PS3.c @@ -143,12 +143,8 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall int len = String_Length(src); String_AppendUtf8(&path, src, len); - if (entry.d_type == DT_DIR) { - res = Directory_Enum(&path, obj, callback); - if (res) break; - } else { - callback(&path, obj); - } + int is_dir = entry.d_type == DT_DIR; + callback(&path, obj, is_dir); } sysLv2FsCloseDir(dir_fd); diff --git a/src/Platform_PSP.c b/src/Platform_PSP.c index 53c013b16..2cc12e8b4 100644 --- a/src/Platform_PSP.c +++ b/src/Platform_PSP.c @@ -133,12 +133,8 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall int len = String_Length(src); String_AppendUtf8(&path, src, len); - if (entry.d_stat.st_attr & FIO_SO_IFDIR) { - res = Directory_Enum(&path, obj, callback); - if (res) break; - } else { - callback(&path, obj); - } + int is_dir = entry.d_stat.st_attr & FIO_SO_IFDIR; + callback(&path, obj, is_dir); } sceIoDclose(uid); diff --git a/src/Platform_PSVita.c b/src/Platform_PSVita.c index 8cca2787b..e0d91b620 100644 --- a/src/Platform_PSVita.c +++ b/src/Platform_PSVita.c @@ -116,12 +116,8 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall int len = String_Length(src); String_AppendUtf8(&path, src, len); - if (entry.d_stat.st_attr & SCE_SO_IFDIR) { - res = Directory_Enum(&path, obj, callback); - if (res) break; - } else { - callback(&path, obj); - } + int is_dir = entry.d_stat.st_attr & SCE_SO_IFDIR; + callback(&path, obj, is_dir); } sceIoDclose(uid); diff --git a/src/Platform_Posix.c b/src/Platform_Posix.c index 5870f0b0f..fc6574770 100644 --- a/src/Platform_Posix.c +++ b/src/Platform_Posix.c @@ -253,12 +253,7 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall /* TODO: fallback to stat when this fails */ #endif - if (is_dir) { - res = Directory_Enum(&path, obj, callback); - if (res) { closedir(dirPtr); return res; } - } else { - callback(&path, obj); - } + callback(&path, obj, is_dir); errno = 0; } @@ -497,8 +492,12 @@ void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) { /*########################################################################################################################* *--------------------------------------------------------Font/Text--------------------------------------------------------* *#########################################################################################################################*/ -static void FontDirCallback(const cc_string* path, void* obj) { - SysFonts_Register(path, NULL); +static void FontDirCallback(const cc_string* path, void* obj, int isDirectory) { + if (isDirectory) { + Directory_Enum(path, NULL, FontDirCallback); + } else { + SysFonts_Register(path, NULL); + } } void Platform_LoadSysFonts(void) { @@ -549,7 +548,8 @@ void Platform_LoadSysFonts(void) { String_FromConst("/usr/local/share/fonts") }; #endif - for (i = 0; i < Array_Elems(dirs); i++) { + for (i = 0; i < Array_Elems(dirs); i++) + { Directory_Enum(&dirs[i], NULL, FontDirCallback); } } diff --git a/src/Platform_Switch.c b/src/Platform_Switch.c index ebe1cc3e1..4f517c876 100644 --- a/src/Platform_Switch.c +++ b/src/Platform_Switch.c @@ -157,12 +157,7 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall int is_dir = entry->d_type == DT_DIR; // TODO: fallback to stat when this fails - if (is_dir) { - res = Directory_Enum(&path, obj, callback); - if (res) { closedir(dirPtr); return res; } - } else { - callback(&path, obj); - } + callback(&path, obj, is_dir); errno = 0; } diff --git a/src/Platform_Web.c b/src/Platform_Web.c index 49cf7e4be..173175904 100644 --- a/src/Platform_Web.c +++ b/src/Platform_Web.c @@ -122,7 +122,7 @@ EMSCRIPTEN_KEEPALIVE void Directory_IterCallback(const char* src) { String_InitArray(path, pathBuffer); String_AppendUtf8(&path, src, String_Length(src)); - enum_callback(&path, enum_obj); + enum_callback(&path, enum_obj, false); } extern int interop_DirectoryIter(const char* path); diff --git a/src/Platform_WiiU.c b/src/Platform_WiiU.c index 34b753ce2..6aef17f1c 100644 --- a/src/Platform_WiiU.c +++ b/src/Platform_WiiU.c @@ -156,12 +156,7 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall is_dir = entry->d_type == DT_DIR; /* TODO: fallback to stat when this fails */ - if (is_dir) { - res = Directory_Enum(&path, obj, callback); - if (res) { closedir(dirPtr); return res; } - } else { - callback(&path, obj); - } + callback(&path, obj, is_dir); errno = 0; } diff --git a/src/Platform_Windows.c b/src/Platform_Windows.c index bc29e5a8a..0bb280f18 100644 --- a/src/Platform_Windows.c +++ b/src/Platform_Windows.c @@ -205,6 +205,8 @@ int File_Exists(const cc_string* path) { static cc_result Directory_EnumCore(const cc_string* dirPath, const cc_string* file, DWORD attribs, void* obj, Directory_EnumCallback callback) { cc_string path; char pathBuffer[MAX_PATH + 10]; + int is_dir; + /* ignore . and .. entry */ if (file->length == 1 && file->buffer[0] == '.') return 0; if (file->length == 2 && file->buffer[0] == '.' && file->buffer[1] == '.') return 0; @@ -212,8 +214,8 @@ static cc_result Directory_EnumCore(const cc_string* dirPath, const cc_string* f String_InitArray(path, pathBuffer); String_Format2(&path, "%s/%s", dirPath, file); - if (attribs & FILE_ATTRIBUTE_DIRECTORY) return Directory_Enum(&path, obj, callback); - callback(&path, obj); + is_dir = attribs & FILE_ATTRIBUTE_DIRECTORY; + callback(&path, obj, is_dir); return 0; } @@ -394,11 +396,16 @@ void Waitable_WaitFor(void* handle, cc_uint32 milliseconds) { /*########################################################################################################################* *--------------------------------------------------------Font/Text--------------------------------------------------------* *#########################################################################################################################*/ -static void FontDirCallback(const cc_string* path, void* obj) { +static void FontDirCallback(const cc_string* path, void* obj, int isDirectory) { static const cc_string fonExt = String_FromConst(".fon"); /* Completely skip windows .FON files */ if (String_CaselessEnds(path, &fonExt)) return; - SysFonts_Register(path, NULL); + + if (isDirectory) { + Directory_Enum(path, NULL, FontDirCallback); + } else { + SysFonts_Register(path, NULL); + } } void Platform_LoadSysFonts(void) { @@ -420,7 +427,8 @@ void Platform_LoadSysFonts(void) { } String_AppendConst(&dirs[0], "/fonts"); - for (i = 0; i < Array_Elems(dirs); i++) { + for (i = 0; i < Array_Elems(dirs); i++) + { Directory_Enum(&dirs[i], NULL, FontDirCallback); } } diff --git a/src/Platform_Xbox.c b/src/Platform_Xbox.c index 77851e322..85ff83e29 100644 --- a/src/Platform_Xbox.c +++ b/src/Platform_Xbox.c @@ -122,19 +122,18 @@ int File_Exists(const cc_string* path) { return attribs != INVALID_FILE_ATTRIBUTES && !(attribs & FILE_ATTRIBUTE_DIRECTORY); } -static cc_result Directory_EnumCore(const cc_string* dirPath, const cc_string* file, DWORD attribs, +static void Directory_EnumCore(const cc_string* dirPath, const cc_string* file, DWORD attribs, void* obj, Directory_EnumCallback callback) { cc_string path; char pathBuffer[MAX_PATH + 10]; /* ignore . and .. entry */ - if (file->length == 1 && file->buffer[0] == '.') return 0; - if (file->length == 2 && file->buffer[0] == '.' && file->buffer[1] == '.') return 0; + if (file->length == 1 && file->buffer[0] == '.') return; + if (file->length == 2 && file->buffer[0] == '.' && file->buffer[1] == '.') return; String_InitArray(path, pathBuffer); String_Format2(&path, "%s/%s", dirPath, file); - if (attribs & FILE_ATTRIBUTE_DIRECTORY) return Directory_Enum(&path, obj, callback); - callback(&path, obj); - return 0; + int is_dir = attribs & FILE_ATTRIBUTE_DIRECTORY; + callback(&path, obj, is_dir); } cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCallback callback) { @@ -160,7 +159,7 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall { String_Append(&path, Convert_CodepointToCP437(eA.cFileName[i])); } - if ((res = Directory_EnumCore(dirPath, &path, eA.dwFileAttributes, obj, callback))) return res; + Directory_EnumCore(dirPath, &path, eA.dwFileAttributes, obj, callback); } while (FindNextFileA(find, &eA)); res = GetLastError(); /* return code from FindNextFile */ diff --git a/src/Platform_Xbox360.c b/src/Platform_Xbox360.c index 0eaf831e0..16f608d13 100644 --- a/src/Platform_Xbox360.c +++ b/src/Platform_Xbox360.c @@ -126,12 +126,7 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall int is_dir = entry->d_type == DT_DIR; // TODO: fallback to stat when this fails - if (is_dir) { - res = Directory_Enum(&path, obj, callback); - if (res) { closedir(dirPtr); return res; } - } else { - callback(&path, obj); - } + callback(&path, obj, is_dir); errno = 0; }