Replace the hrtf_tables option with hrtf-paths
This commit is contained in:
+82
-463
@@ -476,301 +476,69 @@ void al_print(const char *type, const char *func, const char *fmt, ...)
|
||||
static inline int is_slash(int c)
|
||||
{ return (c == '\\' || c == '/'); }
|
||||
|
||||
static size_t strlenW(const WCHAR *str)
|
||||
{
|
||||
const WCHAR *end = str;
|
||||
while(*end) ++end;
|
||||
return end-str;
|
||||
}
|
||||
|
||||
static const WCHAR *strchrW(const WCHAR *str, WCHAR ch)
|
||||
{
|
||||
for(;*str != 0;++str)
|
||||
{
|
||||
if(*str == ch)
|
||||
return str;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const WCHAR *strrchrW(const WCHAR *str, WCHAR ch)
|
||||
{
|
||||
const WCHAR *ret = NULL;
|
||||
for(;*str != 0;++str)
|
||||
{
|
||||
if(*str == ch)
|
||||
ret = str;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const WCHAR *strstrW(const WCHAR *haystack, const WCHAR *needle)
|
||||
{
|
||||
size_t len = strlenW(needle);
|
||||
while(*haystack != 0)
|
||||
{
|
||||
if(CompareStringW(GetThreadLocale(), NORM_IGNORECASE,
|
||||
haystack, len, needle, len) == CSTR_EQUAL)
|
||||
return haystack;
|
||||
|
||||
do {
|
||||
++haystack;
|
||||
} while(((*haystack)&0xC000) == 0x8000);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Compares the filename in the find data with the match string. The match
|
||||
* string may contain the "%r" marker to signifiy a sample rate (really any
|
||||
* positive integer), "%%" to signify a single '%', or "%s" for a (non-greedy)
|
||||
* string.
|
||||
*/
|
||||
static int MatchFilter(const WCHAR *match, const WIN32_FIND_DATAW *fdata)
|
||||
{
|
||||
const WCHAR *name = fdata->cFileName;
|
||||
int ret = 1;
|
||||
|
||||
do {
|
||||
const WCHAR *p = strchrW(match, '%');
|
||||
if(!p)
|
||||
ret = CompareStringW(GetThreadLocale(), NORM_IGNORECASE,
|
||||
match, -1, name, -1) == CSTR_EQUAL;
|
||||
else
|
||||
{
|
||||
int len = p-match;
|
||||
ret = lstrlenW(name) >= len;
|
||||
if(ret)
|
||||
ret = CompareStringW(GetThreadLocale(), NORM_IGNORECASE,
|
||||
match, len, name, len) == CSTR_EQUAL;
|
||||
if(ret)
|
||||
{
|
||||
match += len;
|
||||
name += len;
|
||||
|
||||
++p;
|
||||
if(*p == 'r')
|
||||
{
|
||||
unsigned long l = 0;
|
||||
while(*name >= '0' && *name <= '9')
|
||||
{
|
||||
l = l*10 + (*name-'0');
|
||||
++name;
|
||||
}
|
||||
ret = l > 0;
|
||||
++p;
|
||||
}
|
||||
else if(*p == 's')
|
||||
{
|
||||
const WCHAR *next = p+1;
|
||||
if(*next != '\0' && *next != '%')
|
||||
{
|
||||
const WCHAR *next_p = strchrW(next, '%');
|
||||
const WCHAR *m;
|
||||
|
||||
if(!next_p)
|
||||
m = strstrW(name, next);
|
||||
else
|
||||
{
|
||||
WCHAR *tmp = malloc((next_p - next + 1) * 2);
|
||||
memcpy(tmp, next, (next_p - next) * 2);
|
||||
tmp[next_p - next] = 0;
|
||||
|
||||
m = strstrW(name, tmp);
|
||||
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
ret = !!m;
|
||||
if(ret)
|
||||
{
|
||||
size_t l;
|
||||
if(next_p) l = next_p - next;
|
||||
else l = strlenW(next);
|
||||
|
||||
name = m + l;
|
||||
next += l;
|
||||
}
|
||||
}
|
||||
p = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match = p;
|
||||
} while(ret && match && *match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void RecurseDirectorySearch(const char *path, const WCHAR *match, vector_al_string *results)
|
||||
static void DirectorySearch(const char *path, const char *ext, vector_al_string *results)
|
||||
{
|
||||
al_string pathstr = AL_STRING_INIT_STATIC();
|
||||
WIN32_FIND_DATAW fdata;
|
||||
const WCHAR *sep, *p;
|
||||
WCHAR *wpath;
|
||||
HANDLE hdl;
|
||||
|
||||
if(!match[0])
|
||||
return;
|
||||
al_string_copy_cstr(&pathstr, path);
|
||||
al_string_append_cstr(&pathstr, "\\*");
|
||||
al_string_append_cstr(&pathstr, ext);
|
||||
|
||||
/* Find the last directory separator and the next '%' marker in the match
|
||||
* string. */
|
||||
sep = strrchrW(match, '\\');
|
||||
p = strchrW(match, '%');
|
||||
TRACE("Searching %s\n", al_string_get_cstr(pathstr));
|
||||
|
||||
/* If there's no separator, test the files in the specified path against
|
||||
* the match string, and add the results. */
|
||||
if(!sep)
|
||||
wpath = FromUTF8(al_string_get_cstr(pathstr));
|
||||
|
||||
hdl = FindFirstFileW(wpath, &fdata);
|
||||
if(hdl != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
al_string pathstr = AL_STRING_INIT_STATIC();
|
||||
WCHAR *wpath;
|
||||
size_t base = VECTOR_SIZE(*results);
|
||||
do {
|
||||
al_string str = AL_STRING_INIT_STATIC();
|
||||
al_string_copy_cstr(&str, path);
|
||||
al_string_append_char(&str, '\\');
|
||||
al_string_append_wcstr(&str, fdata.cFileName);
|
||||
TRACE("Got result %s\n", al_string_get_cstr(str));
|
||||
VECTOR_PUSH_BACK(*results, str);
|
||||
} while(FindNextFileW(hdl, &fdata));
|
||||
FindClose(hdl);
|
||||
|
||||
TRACE("Searching %s for %ls\n", path, match);
|
||||
|
||||
al_string_append_cstr(&pathstr, path);
|
||||
al_string_append_cstr(&pathstr, "\\*.*");
|
||||
wpath = FromUTF8(al_string_get_cstr(pathstr));
|
||||
|
||||
hdl = FindFirstFileW(wpath, &fdata);
|
||||
if(hdl != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
size_t base = VECTOR_SIZE(*results);
|
||||
do {
|
||||
if(MatchFilter(match, &fdata))
|
||||
{
|
||||
al_string str = AL_STRING_INIT_STATIC();
|
||||
al_string_copy_cstr(&str, path);
|
||||
al_string_append_char(&str, '\\');
|
||||
al_string_append_wcstr(&str, fdata.cFileName);
|
||||
TRACE("Got result %s\n", al_string_get_cstr(str));
|
||||
VECTOR_PUSH_BACK(*results, str);
|
||||
}
|
||||
} while(FindNextFileW(hdl, &fdata));
|
||||
FindClose(hdl);
|
||||
|
||||
if(VECTOR_SIZE(*results) > base)
|
||||
qsort(VECTOR_ITER_BEGIN(*results)+base, VECTOR_SIZE(*results)-base,
|
||||
sizeof(VECTOR_FRONT(*results)), StringSortCompare);
|
||||
}
|
||||
|
||||
free(wpath);
|
||||
al_string_deinit(&pathstr);
|
||||
|
||||
return;
|
||||
if(VECTOR_SIZE(*results) > base)
|
||||
qsort(VECTOR_ITER_BEGIN(*results)+base, VECTOR_SIZE(*results)-base,
|
||||
sizeof(VECTOR_FRONT(*results)), StringSortCompare);
|
||||
}
|
||||
|
||||
/* If there's no '%' marker, or it's after the final separator, append the
|
||||
* remaining directories to the path and recurse into it with the remaining
|
||||
* filename portion. */
|
||||
if(!p || p-sep >= 0)
|
||||
{
|
||||
al_string npath = AL_STRING_INIT_STATIC();
|
||||
al_string_append_cstr(&npath, path);
|
||||
al_string_append_char(&npath, '\\');
|
||||
al_string_append_wrange(&npath, match, sep);
|
||||
|
||||
TRACE("Recursing into %s with %ls\n", al_string_get_cstr(npath), sep+1);
|
||||
RecurseDirectorySearch(al_string_get_cstr(npath), sep+1, results);
|
||||
|
||||
al_string_deinit(&npath);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Look for the last separator before the '%' marker, and the first
|
||||
* separator after it. */
|
||||
sep = strchrW(match, '\\');
|
||||
if(sep-p >= 0) sep = NULL;
|
||||
for(;;)
|
||||
{
|
||||
const WCHAR *next = strchrW(sep?sep+1:match, '\\');
|
||||
if(next-p < 0)
|
||||
{
|
||||
al_string npath = AL_STRING_INIT_STATIC();
|
||||
WCHAR *nwpath, *nwmatch;
|
||||
|
||||
/* Append up to the last directory before the one with a '%'. */
|
||||
al_string_copy_cstr(&npath, path);
|
||||
if(sep)
|
||||
{
|
||||
al_string_append_char(&npath, '\\');
|
||||
al_string_append_wrange(&npath, match, sep);
|
||||
}
|
||||
al_string_append_cstr(&npath, "\\*.*");
|
||||
nwpath = FromUTF8(al_string_get_cstr(npath));
|
||||
|
||||
/* Take the directory name containing a '%' as a new string to
|
||||
* match against. */
|
||||
if(!sep)
|
||||
{
|
||||
nwmatch = calloc(2, next-match+1);
|
||||
memcpy(nwmatch, match, (next-match)*2);
|
||||
}
|
||||
else
|
||||
{
|
||||
nwmatch = calloc(2, next-(sep+1)+1);
|
||||
memcpy(nwmatch, sep+1, (next-(sep+1))*2);
|
||||
}
|
||||
|
||||
/* For each matching directory name, recurse into it with the
|
||||
* remaining string. */
|
||||
TRACE("Searching %s for %ls\n", al_string_get_cstr(npath), nwmatch);
|
||||
hdl = FindFirstFileW(nwpath, &fdata);
|
||||
if(hdl != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do {
|
||||
if(MatchFilter(nwmatch, &fdata))
|
||||
{
|
||||
al_string ndir = AL_STRING_INIT_STATIC();
|
||||
al_string_copy(&ndir, npath);
|
||||
al_string_append_char(&ndir, '\\');
|
||||
al_string_append_wcstr(&ndir, fdata.cFileName);
|
||||
TRACE("Recursing %s with %ls\n", al_string_get_cstr(ndir), next+1);
|
||||
RecurseDirectorySearch(al_string_get_cstr(ndir), next+1, results);
|
||||
al_string_deinit(&ndir);
|
||||
}
|
||||
} while(FindNextFileW(hdl, &fdata));
|
||||
FindClose(hdl);
|
||||
}
|
||||
|
||||
free(nwmatch);
|
||||
free(nwpath);
|
||||
al_string_deinit(&npath);
|
||||
break;
|
||||
}
|
||||
sep = next;
|
||||
}
|
||||
free(wpath);
|
||||
al_string_deinit(&pathstr);
|
||||
}
|
||||
|
||||
vector_al_string SearchDataFiles(const char *match, const char *subdir)
|
||||
vector_al_string SearchDataFiles(const char *ext, const char *subdir)
|
||||
{
|
||||
static const int ids[2] = { CSIDL_APPDATA, CSIDL_COMMON_APPDATA };
|
||||
static RefCount search_lock;
|
||||
vector_al_string results = VECTOR_INIT_STATIC();
|
||||
WCHAR *wmatch;
|
||||
size_t i;
|
||||
|
||||
while(ATOMIC_EXCHANGE(uint, &search_lock, 1) == 1)
|
||||
althrd_yield();
|
||||
|
||||
wmatch = FromUTF8(match);
|
||||
if(!wmatch)
|
||||
{
|
||||
ERR("Failed to convert UTF-8 filename: \"%s\"\n", match);
|
||||
return results;
|
||||
}
|
||||
for(i = 0;wmatch[i];++i)
|
||||
{
|
||||
if(wmatch[i] == '/')
|
||||
wmatch[i] = '\\';
|
||||
}
|
||||
|
||||
/* If the path is absolute, use it directly. */
|
||||
if(isalpha(wmatch[0]) && wmatch[1] == ':' && is_slash(wmatch[2]))
|
||||
if(isalpha(subdir[0]) && subdir[1] == ':' && is_slash(subdir[2]))
|
||||
{
|
||||
char drv[3] = { (char)wmatch[0], ':', 0 };
|
||||
RecurseDirectorySearch(drv, wmatch+3, &results);
|
||||
al_string path = AL_STRING_INIT_STATIC();
|
||||
al_string_copy_cstr(&path, subdir);
|
||||
#define FIX_SLASH(i) do { if(*(i) == '/') *(i) = '\\'; } while(0)
|
||||
VECTOR_FOR_EACH(char, path, FIX_SLASH);
|
||||
#undef FIX_SLASH
|
||||
|
||||
DirectorySearch(al_string_get_cstr(path), ext, &results);
|
||||
|
||||
al_string_deinit(&path);
|
||||
}
|
||||
else if(wmatch[0] == '\\' && wmatch[1] == '\\' && wmatch[2] == '?' && wmatch[3] == '\\')
|
||||
RecurseDirectorySearch("\\\\?", wmatch+4, &results);
|
||||
else if(subdir[0] == '\\' && subdir[1] == '\\' && subdir[2] == '?' && subdir[3] == '\\')
|
||||
DirectorySearch(subdir, ext, &results);
|
||||
else
|
||||
{
|
||||
al_string path = AL_STRING_INIT_STATIC();
|
||||
@@ -801,7 +569,7 @@ vector_al_string SearchDataFiles(const char *match, const char *subdir)
|
||||
#define FIX_SLASH(i) do { if(*(i) == '/') *(i) = '\\'; } while(0)
|
||||
VECTOR_FOR_EACH(char, path, FIX_SLASH);
|
||||
#undef FIX_SLASH
|
||||
RecurseDirectorySearch(al_string_get_cstr(path), wmatch, &results);
|
||||
DirectorySearch(al_string_get_cstr(path), ext, &results);
|
||||
|
||||
/* Search the local and global data dirs. */
|
||||
for(i = 0;i < COUNTOF(ids);i++)
|
||||
@@ -817,14 +585,13 @@ vector_al_string SearchDataFiles(const char *match, const char *subdir)
|
||||
VECTOR_FOR_EACH(char, path, FIX_SLASH);
|
||||
#undef FIX_SLASH
|
||||
|
||||
RecurseDirectorySearch(al_string_get_cstr(path), wmatch, &results);
|
||||
DirectorySearch(al_string_get_cstr(path), ext, &results);
|
||||
}
|
||||
}
|
||||
|
||||
al_string_deinit(&path);
|
||||
}
|
||||
|
||||
free(wmatch);
|
||||
ATOMIC_STORE(&search_lock, 0);
|
||||
|
||||
return results;
|
||||
@@ -877,192 +644,46 @@ void al_print(const char *type, const char *func, const char *fmt, ...)
|
||||
}
|
||||
|
||||
|
||||
static int MatchFilter(const char *name, const char *match)
|
||||
static void DirectorySearch(const char *path, const char *ext, vector_al_string *results)
|
||||
{
|
||||
int ret = 1;
|
||||
size_t extlen = strlen(ext);
|
||||
DIR *dir;
|
||||
|
||||
do {
|
||||
const char *p = strchr(match, '%');
|
||||
if(!p)
|
||||
ret = strcmp(match, name) == 0;
|
||||
else
|
||||
{
|
||||
size_t len = p-match;
|
||||
ret = strncmp(match, name, len) == 0;
|
||||
if(ret)
|
||||
{
|
||||
match += len;
|
||||
name += len;
|
||||
|
||||
++p;
|
||||
if(*p == 'r')
|
||||
{
|
||||
char *end;
|
||||
ret = strtoul(name, &end, 10) > 0;
|
||||
if(ret) name = end;
|
||||
++p;
|
||||
}
|
||||
else if(*p == 's')
|
||||
{
|
||||
const char *next = p+1;
|
||||
if(*next != '\0' && *next != '%')
|
||||
{
|
||||
const char *next_p = strchr(next, '%');
|
||||
const char *m;
|
||||
|
||||
if(!next_p)
|
||||
m = strstr(name, next);
|
||||
else
|
||||
{
|
||||
char *tmp = malloc(next_p - next + 1);
|
||||
memcpy(tmp, next, next_p - next);
|
||||
tmp[next_p - next] = 0;
|
||||
|
||||
m = strstr(name, tmp);
|
||||
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
ret = !!m;
|
||||
if(ret)
|
||||
{
|
||||
size_t l;
|
||||
if(next_p) l = next_p - next;
|
||||
else l = strlen(next);
|
||||
|
||||
name = m + l;
|
||||
next += l;
|
||||
}
|
||||
}
|
||||
p = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
match = p;
|
||||
} while(ret && match && *match);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void RecurseDirectorySearch(const char *path, const char *match, vector_al_string *results)
|
||||
{
|
||||
char *sep, *p;
|
||||
|
||||
if(!match[0])
|
||||
return;
|
||||
|
||||
sep = strrchr(match, '/');
|
||||
p = strchr(match, '%');
|
||||
|
||||
if(!sep)
|
||||
TRACE("Searching %s for *%s\n", path, ext);
|
||||
dir = opendir(path);
|
||||
if(dir != NULL)
|
||||
{
|
||||
DIR *dir;
|
||||
|
||||
TRACE("Searching %s for %s\n", path?path:"/", match);
|
||||
dir = opendir(path?path:"/");
|
||||
if(dir != NULL)
|
||||
size_t base = VECTOR_SIZE(*results);
|
||||
struct dirent *dirent;
|
||||
while((dirent=readdir(dir)) != NULL)
|
||||
{
|
||||
size_t base = VECTOR_SIZE(*results);
|
||||
struct dirent *dirent;
|
||||
while((dirent=readdir(dir)) != NULL)
|
||||
{
|
||||
al_string str;
|
||||
if(strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0 ||
|
||||
!MatchFilter(dirent->d_name, match))
|
||||
continue;
|
||||
al_string str;
|
||||
size_t len;
|
||||
if(strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
AL_STRING_INIT(str);
|
||||
if(path) al_string_copy_cstr(&str, path);
|
||||
al_string_append_char(&str, '/');
|
||||
al_string_append_cstr(&str, dirent->d_name);
|
||||
TRACE("Got result %s\n", al_string_get_cstr(str));
|
||||
VECTOR_PUSH_BACK(*results, str);
|
||||
}
|
||||
closedir(dir);
|
||||
len = strlen(dirent->d_name);
|
||||
if(!(len > extlen))
|
||||
continue;
|
||||
if(strcasecmp(dirent->d_name+len-extlen, ext) != 0)
|
||||
continue;
|
||||
|
||||
if(VECTOR_SIZE(*results) > base)
|
||||
qsort(VECTOR_ITER_BEGIN(*results)+base, VECTOR_SIZE(*results)-base,
|
||||
sizeof(VECTOR_FRONT(*results)), StringSortCompare);
|
||||
AL_STRING_INIT(str);
|
||||
al_string_copy_cstr(&str, path);
|
||||
al_string_append_char(&str, '/');
|
||||
al_string_append_cstr(&str, dirent->d_name);
|
||||
TRACE("Got result %s\n", al_string_get_cstr(str));
|
||||
VECTOR_PUSH_BACK(*results, str);
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!p || p-sep >= 0)
|
||||
{
|
||||
al_string npath = AL_STRING_INIT_STATIC();
|
||||
if(path) al_string_append_cstr(&npath, path);
|
||||
al_string_append_char(&npath, '/');
|
||||
al_string_append_range(&npath, match, sep);
|
||||
|
||||
TRACE("Recursing into %s with %s\n", al_string_get_cstr(npath), sep+1);
|
||||
RecurseDirectorySearch(al_string_get_cstr(npath), sep+1, results);
|
||||
|
||||
al_string_deinit(&npath);
|
||||
return;
|
||||
}
|
||||
|
||||
sep = strchr(match, '/');
|
||||
if(sep-p >= 0) sep = NULL;
|
||||
for(;;)
|
||||
{
|
||||
char *next = strchr(sep?sep+1:match, '/');
|
||||
if(next-p < 0)
|
||||
{
|
||||
al_string npath = AL_STRING_INIT_STATIC();
|
||||
al_string nmatch = AL_STRING_INIT_STATIC();
|
||||
const char *tomatch;
|
||||
DIR *dir;
|
||||
|
||||
if(!sep)
|
||||
{
|
||||
al_string_append_cstr(&npath, path?path:"/.");
|
||||
tomatch = match;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(path) al_string_append_cstr(&npath, path);
|
||||
al_string_append_char(&npath, '/');
|
||||
al_string_append_range(&npath, match, sep);
|
||||
|
||||
al_string_append_range(&nmatch, sep+1, next);
|
||||
tomatch = al_string_get_cstr(nmatch);
|
||||
}
|
||||
|
||||
TRACE("Searching %s for %s\n", al_string_get_cstr(npath), tomatch);
|
||||
dir = opendir(path?path:"/");
|
||||
if(dir != NULL)
|
||||
{
|
||||
al_string ndir = AL_STRING_INIT_STATIC();
|
||||
struct dirent *dirent;
|
||||
|
||||
while((dirent=readdir(dir)) != NULL)
|
||||
{
|
||||
if(strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0 ||
|
||||
!MatchFilter(dirent->d_name, tomatch))
|
||||
continue;
|
||||
al_string_copy(&ndir, npath);
|
||||
al_string_append_char(&ndir, '/');
|
||||
al_string_append_cstr(&ndir, dirent->d_name);
|
||||
TRACE("Recursing %s with %s\n", al_string_get_cstr(ndir), next+1);
|
||||
RecurseDirectorySearch(al_string_get_cstr(ndir), next+1, results);
|
||||
}
|
||||
closedir(dir);
|
||||
|
||||
al_string_deinit(&ndir);
|
||||
}
|
||||
|
||||
al_string_deinit(&nmatch);
|
||||
al_string_deinit(&npath);
|
||||
break;
|
||||
}
|
||||
|
||||
sep = next;
|
||||
if(VECTOR_SIZE(*results) > base)
|
||||
qsort(VECTOR_ITER_BEGIN(*results)+base, VECTOR_SIZE(*results)-base,
|
||||
sizeof(VECTOR_FRONT(*results)), StringSortCompare);
|
||||
}
|
||||
}
|
||||
|
||||
vector_al_string SearchDataFiles(const char *match, const char *subdir)
|
||||
vector_al_string SearchDataFiles(const char *ext, const char *subdir)
|
||||
{
|
||||
static RefCount search_lock;
|
||||
vector_al_string results = VECTOR_INIT_STATIC();
|
||||
@@ -1070,8 +691,8 @@ vector_al_string SearchDataFiles(const char *match, const char *subdir)
|
||||
while(ATOMIC_EXCHANGE(uint, &search_lock, 1) == 1)
|
||||
althrd_yield();
|
||||
|
||||
if(match[0] == '/')
|
||||
RecurseDirectorySearch(NULL, match+1, &results);
|
||||
if(subdir[0] == '/')
|
||||
DirectorySearch(subdir, ext, &results);
|
||||
else
|
||||
{
|
||||
al_string path = AL_STRING_INIT_STATIC();
|
||||
@@ -1080,29 +701,27 @@ vector_al_string SearchDataFiles(const char *match, const char *subdir)
|
||||
|
||||
/* Search the app-local directory. */
|
||||
if((str=getenv("ALSOFT_LOCAL_PATH")) && *str != '\0')
|
||||
{
|
||||
strncpy(cwdbuf, str, sizeof(cwdbuf)-1);
|
||||
cwdbuf[sizeof(cwdbuf)-1] = '\0';
|
||||
}
|
||||
else if(!getcwd(cwdbuf, sizeof(cwdbuf)))
|
||||
strcpy(cwdbuf, ".");
|
||||
RecurseDirectorySearch(cwdbuf, match, &results);
|
||||
DirectorySearch(str, ext, &results);
|
||||
else if(getcwd(cwdbuf, sizeof(cwdbuf)))
|
||||
DirectorySearch(cwdbuf, ext, &results);
|
||||
else
|
||||
DirectorySearch(".", ext, &results);
|
||||
|
||||
// Search local data dir
|
||||
if((str=getenv("XDG_DATA_HOME")) != NULL && str[0] != '\0')
|
||||
{
|
||||
al_string_append_cstr(&path, str);
|
||||
al_string_copy_cstr(&path, str);
|
||||
al_string_append_char(&path, '/');
|
||||
al_string_append_cstr(&path, subdir);
|
||||
DirectorySearch(al_string_get_cstr(path), ext, &results);
|
||||
}
|
||||
else if((str=getenv("HOME")) != NULL && str[0] != '\0')
|
||||
{
|
||||
al_string_append_cstr(&path, str);
|
||||
al_string_copy_cstr(&path, str);
|
||||
al_string_append_cstr(&path, "/.local/share/");
|
||||
al_string_append_cstr(&path, subdir);
|
||||
DirectorySearch(al_string_get_cstr(path), ext, &results);
|
||||
}
|
||||
if(!al_string_empty(path))
|
||||
RecurseDirectorySearch(al_string_get_cstr(path), match, &results);
|
||||
|
||||
// Search global data dirs
|
||||
if((str=getenv("XDG_DATA_DIRS")) == NULL || str[0] == '\0')
|
||||
@@ -1125,7 +744,7 @@ vector_al_string SearchDataFiles(const char *match, const char *subdir)
|
||||
al_string_append_char(&path, '/');
|
||||
al_string_append_cstr(&path, subdir);
|
||||
|
||||
RecurseDirectorySearch(al_string_get_cstr(path), match, &results);
|
||||
DirectorySearch(al_string_get_cstr(path), ext, &results);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+34
-19
@@ -603,43 +603,58 @@ done:
|
||||
vector_HrtfEntry EnumerateHrtf(const_al_string devname)
|
||||
{
|
||||
vector_HrtfEntry list = VECTOR_INIT_STATIC();
|
||||
const char *fnamelist = "%s.mhr";
|
||||
const char *defaulthrtf = "";
|
||||
const char *pathlist = "";
|
||||
bool usedefaults = true;
|
||||
|
||||
ConfigValueStr(al_string_get_cstr(devname), NULL, "hrtf_tables", &fnamelist);
|
||||
while(fnamelist && *fnamelist)
|
||||
if(ConfigValueStr(al_string_get_cstr(devname), NULL, "hrtf-paths", &pathlist))
|
||||
{
|
||||
while(isspace(*fnamelist) || *fnamelist == ',')
|
||||
fnamelist++;
|
||||
if(*fnamelist != '\0')
|
||||
while(pathlist && *pathlist)
|
||||
{
|
||||
const char *next, *end;
|
||||
|
||||
next = strchr(fnamelist, ',');
|
||||
if(!next)
|
||||
end = fnamelist + strlen(fnamelist);
|
||||
else
|
||||
end = next++;
|
||||
while(isspace(*pathlist) || *pathlist == ',')
|
||||
pathlist++;
|
||||
if(*pathlist == '\0')
|
||||
continue;
|
||||
|
||||
while(end != fnamelist && isspace(*(end-1)))
|
||||
--end;
|
||||
if(end != fnamelist)
|
||||
next = strchr(pathlist, ',');
|
||||
if(next)
|
||||
end = next++;
|
||||
else
|
||||
{
|
||||
al_string fname = AL_STRING_INIT_STATIC();
|
||||
end = pathlist + strlen(pathlist);
|
||||
usedefaults = false;
|
||||
}
|
||||
|
||||
while(end != pathlist && isspace(*(end-1)))
|
||||
--end;
|
||||
if(end != pathlist)
|
||||
{
|
||||
al_string pname = AL_STRING_INIT_STATIC();
|
||||
vector_al_string flist;
|
||||
|
||||
al_string_append_range(&fname, fnamelist, end);
|
||||
al_string_append_range(&pname, pathlist, end);
|
||||
|
||||
flist = SearchDataFiles(al_string_get_cstr(fname), "openal/hrtf");
|
||||
flist = SearchDataFiles(".mhr", al_string_get_cstr(pname));
|
||||
VECTOR_FOR_EACH_PARAMS(al_string, flist, AddFileEntry, &list);
|
||||
VECTOR_DEINIT(flist);
|
||||
|
||||
al_string_deinit(&fname);
|
||||
al_string_deinit(&pname);
|
||||
}
|
||||
|
||||
fnamelist = next;
|
||||
pathlist = next;
|
||||
}
|
||||
}
|
||||
else if(ConfigValueExists(al_string_get_cstr(devname), NULL, "hrtf_tables"))
|
||||
ERR("The hrtf_tables option is deprecated, please use hrtf-paths instead.\n");
|
||||
|
||||
if(usedefaults)
|
||||
{
|
||||
vector_al_string flist = SearchDataFiles(".mhr", "openal/hrtf");
|
||||
VECTOR_FOR_EACH_PARAMS(al_string, flist, AddFileEntry, &list);
|
||||
VECTOR_DEINIT(flist);
|
||||
}
|
||||
|
||||
if(VECTOR_SIZE(list) > 1 && ConfigValueStr(al_string_get_cstr(devname), NULL, "default-hrtf", &defaulthrtf))
|
||||
{
|
||||
|
||||
+7
-11
@@ -102,22 +102,18 @@
|
||||
# that this is the enumerated HRTF name, not necessarily the filename.
|
||||
#default-hrtf =
|
||||
|
||||
## hrtf_tables:
|
||||
# Specifies a comma-separated list of files containing HRTF data sets. The
|
||||
# format of the files are described in hrtf.txt. The filenames may contain
|
||||
# these markers, which will be replaced as needed:
|
||||
# %r - Device sampling rate
|
||||
# %s - Non-greedy string (up to the following matching characters)
|
||||
# %% - Percent sign (%)
|
||||
# The listed files are relative to system-dependant data directories. On
|
||||
# Windows this is:
|
||||
## hrtf-paths:
|
||||
# Specifies a comma-separated list of paths containing HRTF data sets. The
|
||||
# format of the files are described in hrtf.txt. The files within the
|
||||
# directories must have the .mhr file extension to be recognized. By default,
|
||||
# OS-dependent data paths will be used. They will also be used if the list
|
||||
# ends with a comma. On Windows this is:
|
||||
# $AppData\openal\hrtf
|
||||
# And on other systems, it's (in order):
|
||||
# $XDG_DATA_HOME/openal/hrtf (defaults to $HOME/.local/share/openal/hrtf)
|
||||
# $XDG_DATA_DIRS/openal/hrtf (defaults to /usr/local/share/openal/hrtf and
|
||||
# /usr/share/openal/hrtf)
|
||||
# An absolute path may also be specified, if the given file is elsewhere.
|
||||
#hrtf_tables = %s.mhr
|
||||
#hrtf-paths =
|
||||
|
||||
## cf_level:
|
||||
# Sets the crossfeed level for stereo output. Valid values are:
|
||||
|
||||
@@ -494,21 +494,21 @@ void MainWindow::loadConfig(const QString &fname)
|
||||
ui->enableSSE41CheckBox->setChecked(!disabledCpuExts.contains("sse4.1", Qt::CaseInsensitive));
|
||||
ui->enableNeonCheckBox->setChecked(!disabledCpuExts.contains("neon", Qt::CaseInsensitive));
|
||||
|
||||
QStringList hrtf_tables = settings.value("hrtf_tables").toStringList();
|
||||
if(hrtf_tables.size() == 1)
|
||||
hrtf_tables = hrtf_tables[0].split(QChar(','));
|
||||
std::transform(hrtf_tables.begin(), hrtf_tables.end(),
|
||||
hrtf_tables.begin(), std::mem_fun_ref(&QString::trimmed));
|
||||
hrtf_tables.removeDuplicates();
|
||||
if(!hrtf_tables.empty() && !hrtf_tables.contains("%s.mhr"))
|
||||
QStringList hrtf_paths = settings.value("hrtf-paths").toStringList();
|
||||
if(hrtf_paths.size() == 1)
|
||||
hrtf_paths = hrtf_paths[0].split(QChar(','));
|
||||
std::transform(hrtf_paths.begin(), hrtf_paths.end(),
|
||||
hrtf_paths.begin(), std::mem_fun_ref(&QString::trimmed));
|
||||
if(!hrtf_paths.empty() && !hrtf_paths.back().isEmpty())
|
||||
ui->defaultHrtfPathsCheckBox->setCheckState(Qt::Unchecked);
|
||||
else
|
||||
{
|
||||
hrtf_tables.removeOne("%s.mhr");
|
||||
hrtf_paths.removeAll(QString());
|
||||
ui->defaultHrtfPathsCheckBox->setCheckState(Qt::Checked);
|
||||
}
|
||||
hrtf_paths.removeDuplicates();
|
||||
ui->hrtfFileList->clear();
|
||||
ui->hrtfFileList->addItems(hrtf_tables);
|
||||
ui->hrtfFileList->addItems(hrtf_paths);
|
||||
updateHrtfRemoveButton();
|
||||
|
||||
QString hrtfstate = settings.value("hrtf").toString().toLower();
|
||||
@@ -712,20 +712,17 @@ void MainWindow::saveConfig(const QString &fname) const
|
||||
}
|
||||
|
||||
strlist.clear();
|
||||
QList<QListWidgetItem*> items = ui->hrtfFileList->findItems("*", Qt::MatchWildcard);
|
||||
foreach(const QListWidgetItem *item, items)
|
||||
strlist.append(item->text());
|
||||
for(int i = 0;i < ui->hrtfFileList->count();i++)
|
||||
strlist.append(ui->hrtfFileList->item(i)->text());
|
||||
if(!strlist.empty() && ui->defaultHrtfPathsCheckBox->isChecked())
|
||||
strlist.append("%s.mhr");
|
||||
settings.setValue("hrtf_tables", strlist.join(QChar(',')));
|
||||
strlist.append(QString());
|
||||
settings.setValue("hrtf-paths", strlist.join(QChar(',')));
|
||||
|
||||
strlist.clear();
|
||||
items = ui->enabledBackendList->findItems("*", Qt::MatchWildcard);
|
||||
foreach(const QListWidgetItem *item, items)
|
||||
strlist.append(item->text());
|
||||
items = ui->disabledBackendList->findItems("*", Qt::MatchWildcard);
|
||||
foreach(const QListWidgetItem *item, items)
|
||||
strlist.append(QChar('-')+item->text());
|
||||
for(int i = 0;i < ui->enabledBackendList->count();i++)
|
||||
strlist.append(ui->enabledBackendList->item(i)->text());
|
||||
for(int i = 0;i < ui->disabledBackendList->count();i++)
|
||||
strlist.append(QChar('-')+ui->disabledBackendList->item(i)->text());
|
||||
if(strlist.size() == 0 && !ui->backendCheckBox->isChecked())
|
||||
strlist.append("-all");
|
||||
else if(ui->backendCheckBox->isChecked())
|
||||
@@ -843,14 +840,10 @@ void MainWindow::updatePeriodCountSlider()
|
||||
|
||||
void MainWindow::addHrtfFile()
|
||||
{
|
||||
const QStringList datapaths = getAllDataPaths("/openal/hrtf");
|
||||
QStringList fnames = QFileDialog::getOpenFileNames(this, tr("Select Files"),
|
||||
datapaths.empty() ? QString() : datapaths[0],
|
||||
"HRTF Datasets(*.mhr);;All Files(*.*)");
|
||||
if(fnames.isEmpty() == false)
|
||||
QString path = QFileDialog::getExistingDirectory(this, tr("Select HRTF Path"));
|
||||
if(path.isEmpty() == false && !getAllDataPaths("/openal/hrtf").contains(path))
|
||||
{
|
||||
for(QStringList::iterator iter = fnames.begin();iter != fnames.end();iter++)
|
||||
ui->hrtfFileList->addItem(*iter);
|
||||
ui->hrtfFileList->addItem(path);
|
||||
enableApplyButton();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,7 +510,7 @@ frames needed for each mixing update.</string>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>HRTF Profiles</string>
|
||||
<string>HRTF Profile Paths</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
|
||||
Reference in New Issue
Block a user