-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRomLister.cpp
153 lines (147 loc) · 3.44 KB
/
RomLister.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <stdio.h>
#include <string.h>
#include "pico.h"
#include "RomLister.h"
#include "FrensHelpers.h"
#include "ff.h"
// class to listing directories and files for a given extension on sd card
namespace Frens
{
// Buffer must have sufficient bytes to contain directory contents
RomLister::RomLister(void *buffer, size_t buffersize, const char *allowedExtensions)
{
entries = (RomEntry *)buffer;
max_entries = buffersize / sizeof(RomEntry);
const char *delimiters = ", ";
extensions = cstr_split(allowedExtensions, delimiters, &numberOfExtensions);
}
RomLister::~RomLister()
{
}
RomLister::RomEntry *RomLister::GetEntries()
{
return entries;
}
char *RomLister::FolderName()
{
return directoryname;
}
size_t RomLister::Count()
{
return numberOfEntries;
}
bool RomLister::IsextensionAllowed(char *filename)
{
if (numberOfExtensions == 0)
{
return true;
}
for (int i = 0; i < numberOfExtensions; i++)
{
if (Frens::cstr_endswith(filename, extensions[i]))
{
return true;
}
}
return false;
}
void RomLister::list(const char *directoryName)
{
FRESULT fr;
numberOfEntries = 0;
strcpy(directoryname, directoryName);
FILINFO file;
RomEntry tempEntry;
if (directoryname == "")
{
return;
}
DIR dir;
printf("chdir(%s)\n", directoryName);
// for f_getcwd to work, set
// #define FF_FS_RPATH 2
// in ffconf.c
fr = f_chdir(directoryName);
if (fr != FR_OK)
{
printf("Error changing dir: %d\n", fr);
return;
}
printf("Listing current directory, reading maximum %d entries.\n", max_entries);
f_opendir(&dir, ".");
while (f_readdir(&dir, &file) == FR_OK && file.fname[0])
{
if (numberOfEntries < max_entries)
{
if (strlen(file.fname) < ROMLISTER_MAXPATH)
{
struct RomEntry romInfo;
strcpy(romInfo.Path, file.fname);
romInfo.IsDirectory = file.fattrib & AM_DIR;
// if (!romInfo.IsDirectory && Frens::cstr_endswith(romInfo.Path, ".nes"))
if (!romInfo.IsDirectory && IsextensionAllowed(romInfo.Path))
{
if (file.fsize < maxRomSize)
{
entries[numberOfEntries++] = romInfo;
}
else
{
printf("Skipping %s, %d KBytes too large.\n", file.fname, (file.fsize - maxRomSize) / 1024);
}
}
else
{
if (romInfo.IsDirectory && strcmp(romInfo.Path, "System Volume Information") != 0 && strcmp(romInfo.Path, "SAVES") != 0 && strcmp(romInfo.Path, "EDFC") != 0)
{
entries[numberOfEntries++] = romInfo;
}
}
} else {
printf("Filename too long: %s\n", file.fname);
}
}
else
{
if ( numberOfEntries == max_entries)
{
printf("Max entries reached.\n");
}
printf("Skipping %s\n", file.fname);
}
}
f_closedir(&dir);
// (bubble) Sort
if (numberOfEntries > 1)
{
for (int pass = 0; pass < numberOfEntries - 1; ++pass)
{
for (int j = 0; j < numberOfEntries - 1 - pass; ++j)
{
int result = 0;
// Directories first in the list
if (entries[j].IsDirectory && entries[j + 1].IsDirectory == false)
{
continue;
}
bool swap = false;
if (entries[j].IsDirectory == false && entries[j + 1].IsDirectory)
{
swap = true;
}
else
{
result = strcasecmp(entries[j].Path, entries[j + 1].Path);
}
if (swap || result > 0)
{
tempEntry = entries[j];
entries[j] = entries[j + 1];
entries[j + 1] = tempEntry;
}
}
}
}
printf("Sort done\n");
}
}