#define LIST_NONE_SD_FILE 1 bool listSdFiles(const char *path, const char *extension, const uint8_t maxlen, const char *selection, uint8_t flags=0) { FILINFO fno; DIR dir; char *fn; /* This function is assuming non-Unicode cfg. */ #if _USE_LFN TCHAR lfn[_MAX_LFN + 1]; fno.lfname = lfn; fno.lfsize = sizeof(lfn); #endif static uint16_t s_last_menu_offset = 0; #if defined(CPUARM) static uint8_t s_last_flags; if (selection) { s_last_flags = flags; memset(reusableBuffer.modelsel.menu_bss, 0, sizeof(reusableBuffer.modelsel.menu_bss)); strcpy(reusableBuffer.modelsel.menu_bss[0], path); strcat(reusableBuffer.modelsel.menu_bss[0], "/"); strncat(reusableBuffer.modelsel.menu_bss[0], selection, maxlen); strcat(reusableBuffer.modelsel.menu_bss[0], extension); if (f_stat(reusableBuffer.modelsel.menu_bss[0], &fno) != FR_OK) { selection = NULL; } } else { flags = s_last_flags; } #endif if (s_menu_offset == 0) { s_last_menu_offset = 0; memset(reusableBuffer.modelsel.menu_bss, 0, sizeof(reusableBuffer.modelsel.menu_bss)); } else if (s_menu_offset == s_menu_count - MENU_MAX_LINES) { s_last_menu_offset = 0xffff; memset(reusableBuffer.modelsel.menu_bss, 0, sizeof(reusableBuffer.modelsel.menu_bss)); } else if (s_menu_offset == s_last_menu_offset) { // should not happen, only there because of Murphy's law return true; } else if (s_menu_offset > s_last_menu_offset) { memmove(reusableBuffer.modelsel.menu_bss[0], reusableBuffer.modelsel.menu_bss[1], (MENU_MAX_LINES-1)*MENU_LINE_LENGTH); memset(reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-1], 0xff, MENU_LINE_LENGTH); } else { memmove(reusableBuffer.modelsel.menu_bss[1], reusableBuffer.modelsel.menu_bss[0], (MENU_MAX_LINES-1)*MENU_LINE_LENGTH); memset(reusableBuffer.modelsel.menu_bss[0], 0, MENU_LINE_LENGTH); } s_menu_count = 0; s_menu_flags = BSS; FRESULT res = f_opendir(&dir, path); /* Open the directory */ if (res == FR_OK) { if (flags & LIST_NONE_SD_FILE) { s_menu_count++; if (selection) { s_last_menu_offset++; } else if (s_menu_offset==0 || s_menu_offset < s_last_menu_offset) { char *line = reusableBuffer.modelsel.menu_bss[0]; memset(line, 0, MENU_LINE_LENGTH); strcpy(line, "---"); s_menu[0] = line; } } for (;;) { res = f_readdir(&dir, &fno); /* Read a directory item */ if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */ #if _USE_LFN fn = *fno.lfname ? fno.lfname : fno.fname; #else fn = fno.fname; #endif uint8_t len = strlen(fn); if (len < 5 || len > maxlen+4 || strcasecmp(fn+len-4, extension) || (fno.fattrib & AM_DIR)) continue; s_menu_count++; fn[len-4] = '\0'; if (s_menu_offset == 0) { if (selection && strncasecmp(fn, selection, maxlen) < 0) { s_last_menu_offset++; } else { for (uint8_t i=0; i=0; i--) { char *line = reusableBuffer.modelsel.menu_bss[i]; if (line[0] == '\0' || strcasecmp(fn, line) > 0) { if (i > 0) memmove(reusableBuffer.modelsel.menu_bss[0], reusableBuffer.modelsel.menu_bss[1], sizeof(reusableBuffer.modelsel.menu_bss[i]) * i); memset(line, 0, MENU_LINE_LENGTH); strcpy(line, fn); break; } } for (uint8_t i=0; i s_last_menu_offset) { if (strcasecmp(fn, reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-2]) > 0 && strcasecmp(fn, reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-1]) < 0) { memset(reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-1], 0, MENU_LINE_LENGTH); strcpy(reusableBuffer.modelsel.menu_bss[MENU_MAX_LINES-1], fn); } } else { if (strcasecmp(fn, reusableBuffer.modelsel.menu_bss[1]) < 0 && strcasecmp(fn, reusableBuffer.modelsel.menu_bss[0]) > 0) { memset(reusableBuffer.modelsel.menu_bss[0], 0, MENU_LINE_LENGTH); strcpy(reusableBuffer.modelsel.menu_bss[0], fn); } } } } if (s_menu_offset > 0) s_last_menu_offset = s_menu_offset; else s_menu_offset = s_last_menu_offset; return s_menu_count; }