| The changes |
The cause of this bug are the two functions Sys_FindFirst() and Sys_FindNext(). Here are the two
original functions (for win32 - from win32\q_shwin.c):
char *Sys_FindFirst (char *path, unsigned musthave, unsigned canthave )
{
struct _finddata_t findinfo;
if (findhandle)
Sys_Error ("Sys_BeginFind without close");
findhandle = 0;
COM_FilePath (path, findbase);
findhandle = _findfirst (path, &findinfo);
if (findhandle == -1)
return NULL;
if ( !CompareAttributes( findinfo.attrib, musthave, canthave ) )
return NULL;
Com_sprintf (findpath, sizeof(findpath), "%s/%s", findbase, findinfo.name);
return findpath;
}
char *Sys_FindNext ( unsigned musthave, unsigned canthave )
{
struct _finddata_t findinfo;
if (findhandle == -1)
return NULL;
if (_findnext (findhandle, &findinfo) == -1)
return NULL;
if ( !CompareAttributes( findinfo.attrib, musthave, canthave ) )
return NULL;
Com_sprintf (findpath, sizeof(findpath), "%s/%s", findbase, findinfo.name);
return findpath;
}
|
|
You will notice that if a file fails the attribute test in CompareAttributes,
these functions will not continue to search for further matching files. This is
the cause of this bug, since the player menu calls FS_ListFiles() requesting
only directories be listed - so when Sys_FindNext hits a file, it will stop even
if there are further directories yet to be enumerated.
To fix this bug, simply replace these two functions with ones that loop in the
case of failed attribute test - for example:
char *Sys_FindFirst (char *path, unsigned musthave, unsigned canthave )
{
struct _finddata_t findinfo;
if (findhandle)
Sys_Error ("Sys_BeginFind without close");
findhandle = 0;
COM_FilePath (path, findbase);
findhandle = _findfirst(path, &findinfo);
while ((findhandle != -1))
{
if (CompareAttributes(findinfo.attrib, musthave, canthave))
{
Com_sprintf (findpath, sizeof(findpath), "%s/%s", findbase, findinfo.name);
return findpath;
}
else if (_findnext(findhandle, &findinfo) == -1)
{
_findclose(findhandle);
findhandle = -1;
}
}
return NULL;
}
char *Sys_FindNext ( unsigned musthave, unsigned canthave )
{
struct _finddata_t findinfo;
if (findhandle == -1)
return NULL;
while (_findnext(findhandle, &findinfo) != -1)
{
if (CompareAttributes(findinfo.attrib, musthave, canthave))
{
Com_sprintf (findpath, sizeof(findpath), "%s/%s", findbase, findinfo.name);
return findpath;
}
}
return NULL;
}
|
|
|