Cache filenames in audio folder

This commit is contained in:
GaryOderNichts 2021-07-25 12:04:39 +02:00
parent 4209b88459
commit 292a714d17
5 changed files with 178 additions and 2 deletions

View File

@ -1470,7 +1470,7 @@ bool CStream::Open(const char* filename, uint32 overrideSampleRate)
// Be case-insensitive on linux (from https://github.com/OneSadCookie/fcaseopen/)
#if !defined(_WIN32)
char *real = casepath(filename);
char *real = casepath(filename, false);
if (real) {
strcpy(m_aFilename, real);
free(real);

View File

@ -18,6 +18,8 @@
#include <direct.h>
#include <shlobj.h>
#include <shlguid.h>
#elif defined(__WIIU__)
extern "C" char *_getcwd (char *__buf, size_t __size);
#else
#define _getcwd getcwd
#endif
@ -507,7 +509,7 @@ _FindMP3s(void)
strcat(path, "\\MP3\\");
#if !defined(_WIN32)
char *actualPath = casepath(path);
char *actualPath = casepath(path, false);
if (actualPath) {
strcpy(path, actualPath);
free(actualPath);

View File

@ -195,6 +195,11 @@ int _caserename(const char *old_filename, const char *new_filename)
return result;
}
#ifdef __WIIU__
#define MAX_AUDIO_CACHE_ENTRIES 2000
extern char* audioCacheEntries[MAX_AUDIO_CACHE_ENTRIES];
#endif
// Case-insensitivity on linux (from https://github.com/OneSadCookie/fcaseopen)
// Returned string should freed manually (if exists)
char* casepath(char const* path, bool checkPathFirst)
@ -249,6 +254,9 @@ char* casepath(char const* path, bool checkPathFirst)
rl = 1;
}
#ifdef __WIIU__
bool inAudioFolder = false;
#endif
bool cantProceed = false; // just convert slashes in what's left in string, don't correct case of letters(because we can't)
bool mayBeTrailingSlash = false;
char* c;
@ -274,6 +282,20 @@ char* casepath(char const* path, bool checkPathFirst)
continue;
}
#ifdef __WIIU__
if (inAudioFolder) {
// this is the audio folder just look in the cache
for (int i = 0; i < MAX_AUDIO_CACHE_ENTRIES && audioCacheEntries[i]; i++) {
if (strcasecmp(audioCacheEntries[i], c) == 0) {
strcpy(out + rl, audioCacheEntries[i]);
return out;
}
}
free(out);
return nil;
}
#endif
struct dirent* e;
while (e = readdir(d))
{
@ -285,6 +307,14 @@ char* casepath(char const* path, bool checkPathFirst)
assert(reportedLen == strlen(c) && "casepath: This is not good at all");
closedir(d);
#ifdef __WIIU__
if (strcasecmp("audio", e->d_name) == 0) {
inAudioFolder = true;
break;
}
#endif
d = opendir(out);
// Either it wasn't a folder, or permission error, I/O error etc.

47
src/skel/wiiu/getdelim.c Normal file
View File

@ -0,0 +1,47 @@
#include <stdio.h>
#include <stdlib.h>
ssize_t
getdelim(char **buf, size_t *bufsiz, int delimiter, FILE *fp)
{
char *ptr, *eptr;
if (*buf == NULL || *bufsiz == 0) {
*bufsiz = BUFSIZ;
if ((*buf = malloc(*bufsiz)) == NULL)
return -1;
}
for (ptr = *buf, eptr = *buf + *bufsiz;;) {
int c = fgetc(fp);
if (c == -1) {
if (feof(fp))
return ptr == *buf ? -1 : ptr - *buf;
else
return -1;
}
*ptr++ = c;
if (c == delimiter) {
*ptr = '\0';
return ptr - *buf;
}
if (ptr + 2 >= eptr) {
char *nbuf;
size_t nbufsiz = *bufsiz * 2;
ssize_t d = ptr - *buf;
if ((nbuf = realloc(*buf, nbufsiz)) == NULL)
return -1;
*buf = nbuf;
*bufsiz = nbufsiz;
eptr = nbuf + nbufsiz;
ptr = nbuf + d;
}
}
}
ssize_t
getline(char **buf, size_t *bufsiz, FILE *fp)
{
return getdelim(buf, bufsiz, '\n', fp);
}

View File

@ -814,6 +814,95 @@ void InitialiseLanguage()
setlocale(LC_NUMERIC, "C");
}
/*
*****************************************************************************
This is dumb, the Wii U needs ages to parse the whole audio folder with readdir
This just creates a cache file for looking those up
*/
// audio folder has ~1200 files, 2000 to make sure we have enough
#define MAX_AUDIO_CACHE_ENTRIES 2000 // <- when changing also change in crossplatform.cpp
char* audioCacheEntries[MAX_AUDIO_CACHE_ENTRIES] = { NULL };
extern "C" ssize_t getline(char **buf, size_t *bufsiz, FILE *fp);
static void loadAudioFileCache(void)
{
DIR* d = opendir(".");
if (!d) {
return;
}
char audioDir[PATH_MAX];
bool found = false;
struct dirent* ent;
// find the audio dir with correct capitalization
while (ent = readdir(d)) {
if (strcasecmp("audio", ent->d_name) == 0) {
strcpy(audioDir, ent->d_name);
found = true;
break;
}
}
if (!found) {
return;
}
FILE* f = fopen("/vol/external01/wiiu/apps/reVC/audiofiles.cache", "r");
if (!f) {
debug("Creating audiofiles cache");
DIR* d = opendir(audioDir);
if (!d) {
return;
}
f = fopen("/vol/external01/wiiu/apps/reVC/audiofiles.cache", "w");
if (!f) {
closedir(d);
return;
}
char** entryPtr = audioCacheEntries;
// This will take a while on the Wii U :)
struct dirent* ent;
while (ent = readdir(d)) {
// write to cache
fprintf(f, "%s\n", ent->d_name);
// add entry
if (audioCacheEntries - entryPtr < MAX_AUDIO_CACHE_ENTRIES) {
*entryPtr = (char*) malloc(strlen(ent->d_name) + 1);
strcpy(*entryPtr, ent->d_name);
entryPtr++;
}
}
fclose(f);
closedir(d);
debug("Created audiofiles cache");
return;
}
char** entryPtr = audioCacheEntries;
// read entries from file
size_t size;
while (getline(entryPtr, &size, f) > 0) {
char* entry = *entryPtr;
// remove '\n'
entry[strlen(entry) - 1] = '\0';
entryPtr++;
}
fclose(f);
}
/*
*****************************************************************************
*/
@ -874,6 +963,8 @@ main(int argc, char *argv[])
chdir("/vol/external01/wiiu/apps/reVC");
#endif
loadAudioFileCache();
/*
* Initialize the platform independent data.
* This will in turn initialize the platform specific data...
@ -1361,6 +1452,12 @@ main(int argc, char *argv[])
*/
RsEventHandler(rsTERMINATE, nil);
#ifdef __WIIU__
for (int i = 0; i < MAX_AUDIO_CACHE_ENTRIES && audioCacheEntries[i]; i++) {
free(audioCacheEntries[i]);
}
#endif
#ifdef _DEBUG_BUILD_
WHBLogUdpDeinit();
#endif