Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
00aa352
add subfolder support to cfile
notimaginative Oct 3, 2022
8c02e91
sort files in VP archives before indexing them
notimaginative Oct 9, 2022
ea126d6
fix indexing of sub-subfolders
notimaginative Oct 9, 2022
2e0a8d6
remove unused 8B22K & 16B11K sound path types
notimaginative Oct 9, 2022
bb3c4b9
add more items to skip subfolder scanning
notimaginative Oct 9, 2022
46c30f0
fix windows build issues
notimaginative Oct 10, 2022
048c14c
fix unit tests by allowing 0-byte files to be indexed
notimaginative Oct 10, 2022
c126d13
fix file indexing on windows
notimaginative Oct 11, 2022
562f443
add test for cfile subfolders
notimaginative Oct 11, 2022
10148c5
remove specific 'markup' and 'css' interface subfolders
notimaginative Oct 12, 2022
945d912
add player binds to list of always-root locations
notimaginative Oct 12, 2022
1d766e0
remove file-based localization support
notimaginative Oct 15, 2022
26bd0f3
add subfolder support to cf_find_file_location_ext()
notimaginative Oct 16, 2022
ba70e20
add subfolder tests for cf_find_file_location*()
notimaginative Oct 16, 2022
1fa62b7
add shlwapi to needed win32 libs
notimaginative Oct 22, 2022
ef43018
small bit of cleanup
notimaginative Oct 23, 2022
0dafd6b
add subfolder support to cf_get_file_list()
notimaginative Oct 23, 2022
9b6e05a
add tests for cfile subfolder lists
notimaginative Oct 23, 2022
d83782e
report files that might be shadowed
notimaginative Oct 29, 2022
8a576d0
fix issue with lists when a filter is used
notimaginative Oct 31, 2022
24ad8b1
address review suggestions
notimaginative Nov 8, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmake/platform-win32.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ SET(WIN32_LIBS
winmm
ws2_32
psapi
shlwapi
)

IF (MINGW)
Expand Down
2 changes: 1 addition & 1 deletion code/bmpman/bmpman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1835,7 +1835,7 @@ int bm_load_sub_fast(const char *real_filename, int *handle, int dir_type, bool
}

int bm_load_sub_slow(const char *real_filename, const int num_ext, const char **ext_list, CFILE **img_cfp, int dir_type) {
auto res = cf_find_file_location_ext(real_filename, num_ext, ext_list, dir_type, false);
auto res = cf_find_file_location_ext(real_filename, num_ext, ext_list, dir_type);

// could not be found, or is invalid for some reason
if (!res.found)
Expand Down
73 changes: 45 additions & 28 deletions code/cfile/cfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
{ CF_TYPE_MODELS, "data" DIR_SEPARATOR_STR "models", ".pof", CF_TYPE_DATA },
{ CF_TYPE_TABLES, "data" DIR_SEPARATOR_STR "tables", ".tbl .tbm .lua", CF_TYPE_DATA },
{ CF_TYPE_SOUNDS, "data" DIR_SEPARATOR_STR "sounds", ".wav .ogg", CF_TYPE_DATA },
{ CF_TYPE_SOUNDS_8B22K, "data" DIR_SEPARATOR_STR "sounds" DIR_SEPARATOR_STR "8b22k", ".wav .ogg", CF_TYPE_SOUNDS },
{ CF_TYPE_SOUNDS_16B11K, "data" DIR_SEPARATOR_STR "sounds" DIR_SEPARATOR_STR "16b11k", ".wav .ogg", CF_TYPE_SOUNDS },
{ CF_TYPE_VOICE, "data" DIR_SEPARATOR_STR "voice", "", CF_TYPE_DATA },
{ CF_TYPE_VOICE_BRIEFINGS, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "briefing", ".wav .ogg", CF_TYPE_VOICE },
{ CF_TYPE_VOICE_CMD_BRIEF, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "command_briefings", ".wav .ogg", CF_TYPE_VOICE },
Expand All @@ -70,7 +68,7 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
{ CF_TYPE_VOICE_TRAINING, "data" DIR_SEPARATOR_STR "voice" DIR_SEPARATOR_STR "training", ".wav .ogg", CF_TYPE_VOICE },
{ CF_TYPE_MUSIC, "data" DIR_SEPARATOR_STR "music", ".wav .ogg", CF_TYPE_DATA },
{ CF_TYPE_MOVIES, "data" DIR_SEPARATOR_STR "movies", ".mve .msb .ogg .mp4 .srt .webm .png",CF_TYPE_DATA },
{ CF_TYPE_INTERFACE, "data" DIR_SEPARATOR_STR "interface", ".pcx .ani .dds .tga .eff .png .jpg", CF_TYPE_DATA },
{ CF_TYPE_INTERFACE, "data" DIR_SEPARATOR_STR "interface", ".pcx .ani .dds .tga .eff .png .jpg .rml .rcss", CF_TYPE_DATA },
{ CF_TYPE_FONT, "data" DIR_SEPARATOR_STR "fonts", ".vf .ttf .otf", CF_TYPE_DATA },
{ CF_TYPE_EFFECTS, "data" DIR_SEPARATOR_STR "effects", ".ani .eff .pcx .neb .tga .jpg .png .dds .sdr", CF_TYPE_DATA },
{ CF_TYPE_HUD, "data" DIR_SEPARATOR_STR "hud", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA },
Expand All @@ -79,6 +77,7 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
{ CF_TYPE_SQUAD_IMAGES, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "squads", ".pcx .png .dds", CF_TYPE_PLAYERS },
{ CF_TYPE_SINGLE_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "single", ".pl2 .cs2 .plr .csg .css .json", CF_TYPE_PLAYERS },
{ CF_TYPE_MULTI_PLAYERS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "multi", ".plr .json", CF_TYPE_PLAYERS },
{ CF_TYPE_PLAYER_BINDS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "presets", ".json", CF_TYPE_PLAYERS },
{ CF_TYPE_CACHE, "data" DIR_SEPARATOR_STR "cache", ".clr .tmp .bx", CF_TYPE_DATA }, //clr=cached color
{ CF_TYPE_MULTI_CACHE, "data" DIR_SEPARATOR_STR "multidata", ".pcx .png .jpg .dds .fs2 .txt", CF_TYPE_DATA },
{ CF_TYPE_MISSIONS, "data" DIR_SEPARATOR_STR "missions", ".fs2 .fc2 .ntl .ssv", CF_TYPE_DATA },
Expand All @@ -88,10 +87,7 @@ cf_pathtype Pathtypes[CF_MAX_PATH_TYPES] = {
{ CF_TYPE_INTEL_ANIMS, "data" DIR_SEPARATOR_STR "intelanims", ".pcx .ani .eff .tga .jpg .png .dds", CF_TYPE_DATA },
{ CF_TYPE_SCRIPTS, "data" DIR_SEPARATOR_STR "scripts", ".lua .lc .fnl", CF_TYPE_DATA },
{ CF_TYPE_FICTION, "data" DIR_SEPARATOR_STR "fiction", ".txt", CF_TYPE_DATA },
{ CF_TYPE_FREDDOCS, "data" DIR_SEPARATOR_STR "freddocs", ".html", CF_TYPE_DATA },
{ CF_TYPE_INTERFACE_MARKUP, "data" DIR_SEPARATOR_STR "interface" DIR_SEPARATOR_STR "markup", ".rml", CF_TYPE_INTERFACE },
{ CF_TYPE_INTERFACE_CSS, "data" DIR_SEPARATOR_STR "interface" DIR_SEPARATOR_STR "css", ".rcss", CF_TYPE_INTERFACE },
{ CF_TYPE_PLAYER_BINDS, "data" DIR_SEPARATOR_STR "players" DIR_SEPARATOR_STR "presets", ".json", CF_TYPE_PLAYERS },
{ CF_TYPE_FREDDOCS, "data" DIR_SEPARATOR_STR "freddocs", ".html", CF_TYPE_DATA }
};
// clang-format on

Expand Down Expand Up @@ -473,7 +469,7 @@ int cf_delete(const char *filename, int path_type, uint32_t location_flags)

Assert(CF_TYPE_SPECIFIED(path_type));

cf_create_default_path_string(longname, path_type, filename, false, location_flags);
cf_create_default_path_string(longname, path_type, filename, location_flags);

return (_unlink(longname.c_str()) != -1);
}
Expand Down Expand Up @@ -623,7 +619,7 @@ void cf_create_directory(int dir_type, uint32_t location_flags)
int i;

for (i=num_dirs-1; i>=0; i-- ) {
cf_create_default_path_string(longname, dir_tree[i], nullptr, false, location_flags);
cf_create_default_path_string(longname, dir_tree[i], nullptr, location_flags);
if (stat(longname.c_str(), &statbuf) != 0) {
mprintf(( "CFILE: Creating new directory '%s'\n", longname.c_str() ));
mkdir_recursive(longname.c_str());
Expand All @@ -648,7 +644,7 @@ void cf_create_directory(int dir_type, uint32_t location_flags)
//

CFILE* _cfopen(const char* source, int line, const char* file_path, const char* mode, int type, int dir_type,
bool localize, uint32_t location_flags)
bool /* localize */, uint32_t location_flags)
{
/* Bobboau, what is this doing here? 31 is way too short... - Goober5000
if( strlen(file_path) > 31 )
Expand Down Expand Up @@ -689,7 +685,7 @@ CFILE* _cfopen(const char* source, int line, const char* file_path, const char*
// Create the directory if necessary
cf_create_directory(dir_type, location_flags);

cf_create_default_path_string(longname, dir_type, file_path, false, location_flags);
cf_create_default_path_string(longname, dir_type, file_path, location_flags);
}
Assert( !(type & CFILE_MEMORY_MAPPED) );

Expand Down Expand Up @@ -739,10 +735,8 @@ CFILE* _cfopen(const char* source, int line, const char* file_path, const char*
//================================================
// Search for file on disk, on cdrom, or in a packfile

char copy_file_path[MAX_PATH_LEN]; // FIX change in memory from cf_find_file_location
strcpy_s(copy_file_path, file_path);
auto find_res = cf_find_file_location(file_path, dir_type, location_flags);

auto find_res = cf_find_file_location( copy_file_path, dir_type, localize, location_flags );
if ( find_res.found ) {

// Fount it, now create a cfile out of it
Expand Down Expand Up @@ -1848,28 +1842,51 @@ int cfile_get_path_type(const SCP_string& dir)
{
SCP_string buf = dir;

// Remove trailing slashes; avoid buffer overflow on 1-char strings
while (buf.size() > 0 && (buf[buf.size() - 1] == '\\' || buf[buf.size() - 1] == '/')) {
buf.resize(buf.size() - 1);
// remove leading and trailing slashes
if ( !buf.empty() ) {
auto start = buf.find_first_not_of("\\/");
auto end = buf.find_last_not_of("\\/");

if ( (start > 0) || (end < buf.length()-1) ) {
buf = buf.substr(start, end-start+1);
}
}

// Remove leading slashes
while (buf.size() > 0 && (buf[0] == '\\' || buf[0] == '/')) {
buf = buf.substr(1);
if (buf.empty()) {
return CF_TYPE_ROOT;
}

// Use official DIR_SEPARATOR_CHAR
for (char& c : buf) {
if (c == '\\' || c == '/') {
c = DIR_SEPARATOR_CHAR;
}
}
extern void normalize_directory_separators(SCP_string &str);
normalize_directory_separators(buf);

// identify path type
auto best_match = CF_TYPE_INVALID;

for (auto& Pathtype : Pathtypes) {
if (Pathtype.path != nullptr && buf == Pathtype.path) {
return Pathtype.index;
if ( !Pathtype.path ) {
continue;
}

// skip root, it should have been detected before getting here
if (Pathtype.index == CF_TYPE_ROOT) {
continue;
}

// don't allow unknown subdirs directly under data
if (Pathtype.index == CF_TYPE_DATA) {
if (buf == Pathtype.path) {
best_match = CF_TYPE_DATA;
}

continue;
}

// for everything else just find closest match, allowing for unknown subdirectories
if ( !buf.compare(0, strlen(Pathtype.path), Pathtype.path) ) {
best_match = Pathtype.index;
}
}

return CF_TYPE_INVALID;
return best_match;
}
69 changes: 32 additions & 37 deletions code/cfile/cfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,42 +49,38 @@ typedef struct {
#define CF_TYPE_MODELS 5
#define CF_TYPE_TABLES 6
#define CF_TYPE_SOUNDS 7
#define CF_TYPE_SOUNDS_8B22K 8
#define CF_TYPE_SOUNDS_16B11K 9
#define CF_TYPE_VOICE 10
#define CF_TYPE_VOICE_BRIEFINGS 11
#define CF_TYPE_VOICE_CMD_BRIEF 12
#define CF_TYPE_VOICE_DEBRIEFINGS 13
#define CF_TYPE_VOICE_PERSONAS 14
#define CF_TYPE_VOICE_SPECIAL 15
#define CF_TYPE_VOICE_TRAINING 16
#define CF_TYPE_MUSIC 17
#define CF_TYPE_MOVIES 18
#define CF_TYPE_INTERFACE 19
#define CF_TYPE_FONT 20
#define CF_TYPE_EFFECTS 21
#define CF_TYPE_HUD 22
#define CF_TYPE_PLAYERS 23
#define CF_TYPE_PLAYER_IMAGES 24
#define CF_TYPE_SQUAD_IMAGES 25
#define CF_TYPE_SINGLE_PLAYERS 26
#define CF_TYPE_MULTI_PLAYERS 27
#define CF_TYPE_CACHE 28
#define CF_TYPE_MULTI_CACHE 29
#define CF_TYPE_MISSIONS 30
#define CF_TYPE_CONFIG 31
#define CF_TYPE_DEMOS 32
#define CF_TYPE_CBANIMS 33
#define CF_TYPE_INTEL_ANIMS 34
#define CF_TYPE_SCRIPTS 35
#define CF_TYPE_FICTION 36
#define CF_TYPE_FREDDOCS 37
#define CF_TYPE_INTERFACE_MARKUP 38
#define CF_TYPE_INTERFACE_CSS 39
#define CF_TYPE_PLAYER_BINDS 40
#define CF_TYPE_VOICE 8
#define CF_TYPE_VOICE_BRIEFINGS 9
#define CF_TYPE_VOICE_CMD_BRIEF 10
#define CF_TYPE_VOICE_DEBRIEFINGS 11
#define CF_TYPE_VOICE_PERSONAS 12
#define CF_TYPE_VOICE_SPECIAL 13
#define CF_TYPE_VOICE_TRAINING 14
#define CF_TYPE_MUSIC 15
#define CF_TYPE_MOVIES 16
#define CF_TYPE_INTERFACE 17
#define CF_TYPE_FONT 18
#define CF_TYPE_EFFECTS 19
#define CF_TYPE_HUD 20
#define CF_TYPE_PLAYERS 21
#define CF_TYPE_PLAYER_IMAGES 22
#define CF_TYPE_SQUAD_IMAGES 23
#define CF_TYPE_SINGLE_PLAYERS 24
#define CF_TYPE_MULTI_PLAYERS 25
#define CF_TYPE_PLAYER_BINDS 26
#define CF_TYPE_CACHE 27
#define CF_TYPE_MULTI_CACHE 28
#define CF_TYPE_MISSIONS 29
#define CF_TYPE_CONFIG 30
#define CF_TYPE_DEMOS 31
#define CF_TYPE_CBANIMS 32
#define CF_TYPE_INTEL_ANIMS 33
#define CF_TYPE_SCRIPTS 34
#define CF_TYPE_FICTION 35
#define CF_TYPE_FREDDOCS 36

#define CF_MAX_PATH_TYPES \
41 // Can be as high as you'd like //DTP; yeah but beware alot of things uses CF_MAX_PATH_TYPES
37 // Can be as high as you'd like //DTP; yeah but beware alot of things uses CF_MAX_PATH_TYPES

// TRUE if type is specified and valid
#define CF_TYPE_SPECIFIED(path_type) (((path_type)>CF_TYPE_INVALID) && ((path_type)<CF_MAX_PATH_TYPES))
Expand Down Expand Up @@ -395,7 +391,7 @@ struct CFileLocation {
// size - File size
// offset - Offset into pack file. 0 if not a packfile.
// Returns: If not found returns 0.
CFileLocation cf_find_file_location(const char* filespec, int pathtype, bool localize = false,
CFileLocation cf_find_file_location(const char* filespec, int pathtype,
uint32_t location_flags = CF_LOCATION_ALL);

struct CFileLocationExt : public CFileLocation {
Expand All @@ -419,8 +415,7 @@ struct CFileLocationExt : public CFileLocation {
// offset - Offset into pack file. 0 if not a packfile.
// Returns: If not found returns -1, else returns offset into ext_list.
// (NOTE: This function is exponentially slow, so don't use it unless truely needed!!)
CFileLocationExt cf_find_file_location_ext(const char* filename, const int ext_num, const char** ext_list, int pathtype,
bool localize = false);
CFileLocationExt cf_find_file_location_ext(const char* filename, const int ext_num, const char** ext_list, int pathtype);

// Functions to change directories
int cfile_chdir(const char *dir);
Expand Down
Loading