From 057a13f7a2efad94d8e92ff385775940cee04ebb Mon Sep 17 00:00:00 2001 From: Mahyar Koshkouei Date: Sun, 19 Feb 2017 20:07:27 +0000 Subject: [PATCH] Fix directory flashing Fixed an issue whereby the console would flash when browsing files. Signed-off-by: Mahyar Koshkouei --- include/dr_libs | 2 +- source/main.c | 197 ++++++++++++++++++++++++++++++++++++++---------- source/main.h | 13 ++++ 3 files changed, 171 insertions(+), 41 deletions(-) diff --git a/include/dr_libs b/include/dr_libs index 9b86194..6fb1f8a 160000 --- a/include/dr_libs +++ b/include/dr_libs @@ -1 +1 @@ -Subproject commit 9b86194035dbd10fe068e958023d49bcc901aba6 +Subproject commit 6fb1f8a9f8bb3198e05ee52aa38f177c499c1bef diff --git a/source/main.c b/source/main.c index 013e715..611c0b7 100644 --- a/source/main.c +++ b/source/main.c @@ -116,6 +116,81 @@ static int changeFile(const char* ep_file, struct playbackInfo_t* playbackInfo) return 0; } +static int cmpstringp(const void *p1, const void *p2) +{ + /* The actual arguments to this function are "pointers to + pointers to char", but strcmp(3) arguments are "pointers + to char", hence the following cast plus dereference */ + + return strcasecmp(* (char * const *) p1, * (char * const *) p2); +} + +/** + * Store the list of files and folders in current director to an array. + */ +static int getDir(struct dirList_t* dirList) +{ + DIR *dp; + struct dirent *ep; + int fileNum = 0; + int dirNum = 0; + char* wd = getcwd(NULL, 0); + + if(wd == NULL) + goto out; + + /* Clear strings */ + for(int i = 0; i < dirList->dirNum; i++) + free(dirList->directories[i]); + + for(int i = 0; i < dirList->fileNum; i++) + free(dirList->files[i]); + + free(dirList->currentDir); + + if((dirList->currentDir = strdup(wd)) == NULL) + puts("Failure"); + + if((dp = opendir(wd)) == NULL) + goto out; + + while((ep = readdir(dp)) != NULL) + { + if(ep->d_type == DT_DIR) + { + /* Add more space for another pointer to a dirent struct */ + dirList->directories = realloc(dirList->directories, (dirNum + 1) * sizeof(char*)); + + if((dirList->directories[dirNum] = strdup(ep->d_name)) == NULL) + puts("Failure"); + + dirNum++; + continue; + } + + /* Add more space for another pointer to a dirent struct */ + dirList->files = realloc(dirList->files, (fileNum + 1) * sizeof(char*)); + + if((dirList->files[fileNum] = strdup(ep->d_name)) == NULL) + puts("Failure"); + + fileNum++; + } + + qsort(&dirList->files[0], fileNum, sizeof(char *), cmpstringp); + qsort(&dirList->directories[0], dirNum, sizeof(char *), cmpstringp); + + dirList->dirNum = dirNum; + dirList->fileNum = fileNum; + + if(closedir(dp) != 0) + goto out; + +out: + free(wd); + return fileNum + dirNum; +} + /** * List current directory. * @@ -124,30 +199,24 @@ static int changeFile(const char* ep_file, struct playbackInfo_t* playbackInfo) * \param select File to show as selected. Must be > 0. * \return Number of entries listed or negative on error. */ -static int listDir(int from, int max, int select) +static int listDir(int from, int max, int select, struct dirList_t dirList) { - DIR *dp; - struct dirent *ep; int fileNum = 0; int listed = 0; - char* wd = getcwd(NULL, 0); - if(wd == NULL) - goto err; - - consoleClear(); - printf("Dir: %.33s\n", wd); - - if((dp = opendir(wd)) == NULL) - goto err; + //consoleClear(); + printf("\033[0;0H"); + printf("Dir: %.33s\n", dirList.currentDir); if(from == 0) { - printf("%c../\n", select == 0 ? '>' : ' '); + printf("\33[2K%c../\n", select == 0 ? '>' : ' '); listed++; } + else + max++; - while((ep = readdir(dp)) != NULL) + while(dirList.fileNum + dirList.dirNum > fileNum) { fileNum++; @@ -156,26 +225,32 @@ static int listDir(int from, int max, int select) listed++; - printf("%c%s%.37s%s\n", - select == fileNum ? '>' : ' ', - ep->d_type == DT_DIR ? "\x1b[34;1m" : "", - ep->d_name, - ep->d_type == DT_DIR ? "/\x1b[0m" : ""); + if(dirList.dirNum >= fileNum) + { + printf("\33[2K%c\x1b[34;1m%.37s/\x1b[0m\n", + select == fileNum ? '>' : ' ', + dirList.directories[fileNum - 1]); + + } + + /* fileNum must be referring to a file instead of a directory. */ + if(dirList.dirNum < fileNum) + { + printf("\33[2K%c%.37s\n", + select == fileNum ? '>' : ' ', + dirList.files[fileNum - dirList.dirNum - 1]); + + } if(fileNum == max + from) break; } - if(closedir(dp) != 0) - goto err; + /* TODO: Remove crappy bodge to stop last line from not being cleared. */ + if(from != 0) + printf("\33[2K"); -out: - free(wd); return listed; - -err: - listed = -1; - goto out; } /** @@ -219,6 +294,7 @@ int main(int argc, char **argv) struct errInfo_t errInfo; struct playbackInfo_t playbackInfo; volatile int error = 0; + struct dirList_t dirList = {NULL, 0, NULL, 0, NULL}; gfxInitDefault(); sdmcInit(); @@ -241,7 +317,18 @@ int main(int argc, char **argv) chdir(DEFAULT_DIR); chdir("MUSIC"); - if(listDir(from, MAX_LIST, 0) < 0) + + consoleSelect(&topScreen); + if(getDir(&dirList) > 0) + { + printf("Fourth/%d file: %s\n", dirList.dirNum, dirList.files[3]); + } + else + puts("didn't work"); + + consoleSelect(&bottomScreen); + + if(listDir(from, MAX_LIST, 0, dirList) < 0) { err_print("Unable to list directory."); goto err; @@ -329,7 +416,7 @@ int main(int argc, char **argv) if(fileMax - fileNum > 26 && from != 0) from--; - if(listDir(from, MAX_LIST, fileNum) < 0) + if(listDir(from, MAX_LIST, fileNum, dirList) < 0) err_print("Unable to list directory."); } @@ -343,7 +430,7 @@ int main(int argc, char **argv) from < fileMax - MAX_LIST) from++; - if(listDir(from, MAX_LIST, fileNum) < 0) + if(listDir(from, MAX_LIST, fileNum, dirList) < 0) err_print("Unable to list directory."); } @@ -366,7 +453,7 @@ int main(int argc, char **argv) from = 0; } - if(listDir(from, MAX_LIST, fileNum) < 0) + if(listDir(from, MAX_LIST, fileNum, dirList) < 0) err_print("Unable to list directory."); } @@ -389,10 +476,18 @@ int main(int argc, char **argv) from = fileMax - MAX_LIST; } - if(listDir(from, MAX_LIST, fileNum) < 0) + if(listDir(from, MAX_LIST, fileNum, dirList) < 0) err_print("Unable to list directory."); } + if(kDown) + { + consoleSelect(&topScreen); + printf("dirNum: %d fileNum: %d fileSelected: %d\n", + dirList.dirNum, dirList.fileNum, fileNum); + consoleSelect(&bottomScreen); + } + /* * Pressing B goes up a folder, as well as pressing A or R when ".." * is selected. @@ -401,12 +496,13 @@ int main(int argc, char **argv) ((kDown & KEY_A) && (from == 0 && fileNum == 0))) { chdir(".."); + consoleClear(); + fileMax = getDir(&dirList); fileNum = 0; from = 0; - fileMax = getNumberFiles(); - if(listDir(from, MAX_LIST, fileNum) < 0) + if(listDir(from, MAX_LIST, fileNum, dirList) < 0) err_print("Unable to list directory."); continue; @@ -414,6 +510,31 @@ int main(int argc, char **argv) if(kDown & KEY_A) { + if(dirList.dirNum >= fileNum) + { + consoleSelect(&topScreen); + printf("Changing to %s directory\n", dirList.directories[fileNum - 1]); + consoleSelect(&bottomScreen); + chdir(dirList.directories[fileNum - 1]); + consoleClear(); + fileMax = getDir(&dirList); + fileNum = 0; + from = 0; + if(listDir(from, MAX_LIST, fileNum, dirList) < 0) + err_print("Unable to list directory."); + continue; + } + + if(dirList.dirNum < fileNum) + { + consoleSelect(&topScreen); + printf("Attempting to play %s\n", dirList.files[fileNum - dirList.dirNum - 1]); + changeFile(dirList.files[fileNum - dirList.dirNum - 1], &playbackInfo); + consoleSelect(&bottomScreen); + continue; + } + +#if 0 int audioFileNum = 0; DIR *dp; struct dirent *ep; @@ -439,7 +560,7 @@ int main(int argc, char **argv) fileNum = 0; from = 0; fileMax = getNumberFiles(); - if(listDir(from, MAX_LIST, fileNum) < 0) + if(listDir(from, MAX_LIST, fileNum, dirList) < 0) err_print("Unable to list directory."); closedir(dp); @@ -455,13 +576,9 @@ int main(int argc, char **argv) } else err_print("Unable to open directory."); +#endif } } -#ifdef DEBUG - consoleSelect(&topScreen); - printf("\rNum: %d, Max: %d, from: %d ", fileNum, fileMax, from); - consoleSelect(&bottomScreen); -#endif out: puts("Exiting..."); diff --git a/source/main.h b/source/main.h index 33679b9..d0f31cd 100644 --- a/source/main.h +++ b/source/main.h @@ -7,6 +7,8 @@ * LICENSE file. */ +#include <3ds.h> + #ifndef ctrmus_main_h #define ctrmus_main_h @@ -22,6 +24,17 @@ struct watchdogInfo struct errInfo_t* errInfo; }; +struct dirList_t +{ + char** files; + int fileNum; + + char** directories; + int dirNum; + + char* currentDir; +}; + /** * Allows the playback thread to return any error messages that it may * encounter.