Skip to content

Commit

Permalink
Turn Base_directory into an std::filesystem::path
Browse files Browse the repository at this point in the history
Before this change, Base_directory was a char array. In general, it’s
better to use an std::filesystem::path to represent paths. Here’s why:

• char arrays have a limited size. If a user creates a file or directory
that has a very long path, then it might not be possible to store that
path in a given char array. You can try to make the char array long
enough to store the longest possible path, but future operating systems
may increase that limit. With std::filesystem::paths, you don’t have
to worry about path length limits.

• char arrays cannot necessarily represent all paths. We try our best to
use UTF-8 for all char arrays [1], but unfortunately, it’s possible to
create a path that cannot be represent using UTF-8 [2]. With an
std::filesystem::paths, stuff like that is less likely to happen because
std::filesystem::path::value_type is platform-specific.

• char arrays don’t have any built-in mechanisms for manipulating paths.
At the moment, we work around this problem with things like the ddio
module. If we make sure that we always use std::filesystem::paths, then
we’ll be able to get rid of or simplify a lot of the ddio module.

[1]: 7cd7902 (Merge pull request DescentDevelopers#494 from Jayman2000/encoding-improvements, 2024-07-20)
[2]: <rust-lang/rust#12056>
  • Loading branch information
Jayman2000 committed Aug 18, 2024
1 parent 0f6c54c commit 5834b66
Show file tree
Hide file tree
Showing 20 changed files with 73 additions and 71 deletions.
4 changes: 2 additions & 2 deletions Descent3/Game2DLL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ bool InitGameModule(const char *name, module *mod) {
char dll_name[_MAX_PATH * 2];
char tmp_dll_name[_MAX_PATH * 2];
// Make the hog filename
ddio_MakePath(lib_name, Base_directory, "netgames", name, NULL);
ddio_MakePath(lib_name, Base_directory.u8string().c_str(), "netgames", name, NULL);
strcat(lib_name, ".d3m");
// Make the dll filename
#if defined(WIN32)
Expand All @@ -578,7 +578,7 @@ bool InitGameModule(const char *name, module *mod) {

// Open the hog file
if (!cf_OpenLibrary(lib_name)) {
ddio_MakePath(tmp_dll_name, Base_directory, "netgames", name, NULL);
ddio_MakePath(tmp_dll_name, Base_directory.u8string().c_str(), "netgames", name, NULL);
strcat(tmp_dll_name, ".d3m");
Multi_game_dll_name[0] = '\0';
goto loaddll;
Expand Down
2 changes: 1 addition & 1 deletion Descent3/ambient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ void WriteAmbientData() {
CFILE *ofile;

#ifndef NEWEDITOR
ddio_MakePath(filename, Base_directory, "data", "misc", AMBIENT_FILE_NAME, NULL);
ddio_MakePath(filename, Base_directory.u8string().c_str(), "data", "misc", AMBIENT_FILE_NAME, NULL);
#else
ddio_MakePath(filename, D3HogDir, "data", "misc", AMBIENT_FILE_NAME, NULL);
#endif
Expand Down
4 changes: 2 additions & 2 deletions Descent3/demofile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ void DemoToggleRecording() {
if (stricmp(szfile + (strlen(szfile) - 4), ".dem") != 0) {
strcat(szfile, ".dem");
}
ddio_MakePath(Demo_fname, Base_directory, "demo", szfile, NULL);
ddio_MakePath(Demo_fname, Base_directory.u8string().c_str(), "demo", szfile, NULL);
mprintf(0, "Saving demo to file: %s\n", Demo_fname);
// Try to create the file
Demo_cfp = cfopen(Demo_fname, "wb");
Expand Down Expand Up @@ -1423,7 +1423,7 @@ bool LoadDemoDialog() {

char file[_MAX_PATH * 2];

ddio_MakePath(file, Base_directory, "demo", NULL);
ddio_MakePath(file, Base_directory.u8string().c_str(), "demo", NULL);

if (DoPathFileDialog(false, file, TXT_VIEWDEMO, "*.dem", PFDF_FILEMUSTEXIST)) {
strcpy(Demo_fname, file);
Expand Down
2 changes: 1 addition & 1 deletion Descent3/descent.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ extern bool Descent_overrided_intro;
#define MSN_NAMELEN 32

// The "root" directory of the D3 file tree
extern char Base_directory[];
extern std::filesystem::path Base_directory;

// Variable to preserve current path. TODO: redundant?
extern std::filesystem::path orig_pwd;
Expand Down
2 changes: 1 addition & 1 deletion Descent3/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1306,7 +1306,7 @@ void DoScreenshot() {
count = 1;
while (!done) {
snprintf(str, sizeof(str), "Screenshot%.3d.png", count);
ddio_MakePath(filename, Base_directory, str, NULL);
ddio_MakePath(filename, Base_directory.u8string().c_str(), str, NULL);
infile = (CFILE *)cfopen(filename, "rb");
if (infile == NULL) {
done = 1;
Expand Down
8 changes: 4 additions & 4 deletions Descent3/gamesave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ void QuickSaveGame() {
i = Quicksave_game_slot;

snprintf(filename, sizeof(filename), "saveg00%d", i);
ddio_MakePath(pathname, Base_directory, "savegame", filename, NULL);
ddio_MakePath(pathname, Base_directory.u8string().c_str(), "savegame", filename, NULL);

fp = fopen(pathname, "rb");
if (fp) {
Expand Down Expand Up @@ -393,7 +393,7 @@ void SaveGameDialog() {
#endif

// setup paths.
ddio_MakePath(savegame_dir, Base_directory, "savegame", NULL);
ddio_MakePath(savegame_dir, Base_directory.u8string().c_str(), "savegame", NULL);
// ddio_MakePath(pathname, savegame_dir, "*.sav", NULL); -unused

// create savegame directory if it didn't exist before.
Expand Down Expand Up @@ -545,7 +545,7 @@ void __cdecl LoadGameDialogCB(newuiTiledWindow *wnd, void *data)

mprintf(0, "savegame slot=%d\n", id - SAVE_HOTSPOT_ID);

ddio_MakePath(savegame_dir, Base_directory, "savegame", NULL);
ddio_MakePath(savegame_dir, Base_directory.u8string().c_str(), "savegame", NULL);
snprintf(filename, sizeof(filename), "saveg00%d", (id - SAVE_HOTSPOT_ID));
ddio_MakePath(pathname, savegame_dir, filename, NULL);

Expand Down Expand Up @@ -588,7 +588,7 @@ bool LoadGameDialog() {
}

// setup paths.
ddio_MakePath(savegame_dir, Base_directory, "savegame", NULL);
ddio_MakePath(savegame_dir, Base_directory.u8string().c_str(), "savegame", NULL);
ddio_MakePath(pathname, savegame_dir, "*.sav", NULL);

// create savegame directory if it didn't exist before.
Expand Down
19 changes: 8 additions & 11 deletions Descent3/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,7 @@ static bool Title_bitmap_init = false;
uint8_t Use_motion_blur = 0;

// The "root" directory of the D3 file tree
char Base_directory[_MAX_PATH];
std::filesystem::path Base_directory;

extern int Min_allowed_frametime;

Expand Down Expand Up @@ -1407,8 +1407,7 @@ void InitIOSystems(bool editor) {
int dirarg = FindArg("-setdir");
int exedirarg = FindArg("-useexedir");
if (dirarg) {
strncpy(Base_directory, GameArgs[dirarg + 1], sizeof(Base_directory) - 1);
Base_directory[sizeof(Base_directory) - 1] = '\0';
Base_directory = GameArgs[dirarg + 1];
} else if (exedirarg) {
char exec_path[_MAX_PATH];
memset(exec_path, 0, sizeof(exec_path));
Expand All @@ -1417,16 +1416,14 @@ void InitIOSystems(bool editor) {
Error("Failed to get executable path\n");
} else {
std::filesystem::path executablePath(exec_path);
std::string baseDirectoryString = executablePath.parent_path().string();
strncpy(Base_directory, baseDirectoryString.c_str(), sizeof(Base_directory) - 1);
Base_directory[sizeof(Base_directory) - 1] = '\0';
Base_directory = executablePath.parent_path();
mprintf(0, "Using working directory of %s\n", Base_directory);
}
} else {
ddio_GetWorkingDir(Base_directory, sizeof(Base_directory));
Base_directory = std::filesystem::current_path();
}

ddio_SetWorkingDir(Base_directory);
ddio_SetWorkingDir(Base_directory.u8string().c_str());

Descent->set_defer_handler(D3DeferHandler);

Expand Down Expand Up @@ -1989,7 +1986,7 @@ void SetupTempDirectory(void) {
strcpy(Descent3_temp_directory, GameArgs[t_arg + 1]);
} else {
// initialize it to custom/cache
ddio_MakePath(Descent3_temp_directory, Base_directory, "custom", "cache", NULL);
ddio_MakePath(Descent3_temp_directory, Base_directory.u8string().c_str(), "custom", "cache", NULL);
}

// verify that temp directory exists
Expand Down Expand Up @@ -2052,7 +2049,7 @@ void SetupTempDirectory(void) {
exit(1);
}
// restore working dir
ddio_SetWorkingDir(Base_directory);
ddio_SetWorkingDir(Base_directory.u8string().c_str());
}

void DeleteTempFiles(void) {
Expand All @@ -2072,7 +2069,7 @@ void DeleteTempFiles(void) {
}

// restore directory
ddio_SetWorkingDir(Base_directory);
ddio_SetWorkingDir(Base_directory.u8string().c_str());
}

/*
Expand Down
2 changes: 1 addition & 1 deletion Descent3/mmItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ void mmInterface::Create() {
static_menu_background = true;
} else {
char filename[_MAX_PATH];
ddio_MakePath(filename, Base_directory, "movies", "mainmenu", NULL);
ddio_MakePath(filename, Base_directory.u8string().c_str(), "movies", "mainmenu", NULL);
m_movie = StartMovie(filename, true);

if (!m_movie) //[ISB] Didn't find the menu movie?
Expand Down
10 changes: 5 additions & 5 deletions Descent3/multi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8095,23 +8095,23 @@ char *GetFileNameFromPlayerAndID(int16_t playernum, int16_t id) {
break;
case NETFILE_ID_SHIP_TEX:
if (NetPlayers[playernum].ship_logo[0])
ddio_MakePath(rval, Base_directory, "custom", "graphics", NetPlayers[playernum].ship_logo, NULL);
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "graphics", NetPlayers[playernum].ship_logo, NULL);
break;
case NETFILE_ID_VOICE_TAUNT1:
if (NetPlayers[playernum].voice_taunt1[0])
ddio_MakePath(rval, Base_directory, "custom", "sounds", NetPlayers[playernum].voice_taunt1, NULL);
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "sounds", NetPlayers[playernum].voice_taunt1, NULL);
break;
case NETFILE_ID_VOICE_TAUNT2:
if (NetPlayers[playernum].voice_taunt2[0])
ddio_MakePath(rval, Base_directory, "custom", "sounds", NetPlayers[playernum].voice_taunt2, NULL);
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "sounds", NetPlayers[playernum].voice_taunt2, NULL);
break;
case NETFILE_ID_VOICE_TAUNT3:
if (NetPlayers[playernum].voice_taunt3[0])
ddio_MakePath(rval, Base_directory, "custom", "sounds", NetPlayers[playernum].voice_taunt3, NULL);
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "sounds", NetPlayers[playernum].voice_taunt3, NULL);
break;
case NETFILE_ID_VOICE_TAUNT4:
if (NetPlayers[playernum].voice_taunt4[0])
ddio_MakePath(rval, Base_directory, "custom", "sounds", NetPlayers[playernum].voice_taunt4, NULL);
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "sounds", NetPlayers[playernum].voice_taunt4, NULL);
break;
default:
mprintf(0, "Unknown id (%d) passed to GetFileNameFromPlayerAndID()\n", id);
Expand Down
8 changes: 4 additions & 4 deletions Descent3/multi_dll_mgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,7 @@ void GetMultiAPI(multi_api *api) {
api->vp[2] = (int *)&Game_is_master_tracker_game;
api->vp[3] = (int *)&Game_mode;
api->vp[4] = (int *)NULL; // Current_pilot; no longer a struct
api->vp[5] = (int *)Base_directory;
api->vp[5] = (int *)&Base_directory;
api->vp[6] = (int *)&MultiDLLGameStarting;
api->vp[7] = (int *)MTPilotinfo;
api->vp[8] = (int *)&Num_network_games_known;
Expand Down Expand Up @@ -597,10 +597,10 @@ int LoadMultiDLL(const char *name) {
if (MultiDLLHandle.handle)
FreeMultiDLL();

ddio_MakePath(dll_path_name, Base_directory, "online", "*.tmp", NULL);
ddio_MakePath(dll_path_name, Base_directory.u8string().c_str(), "online", "*.tmp", NULL);
ddio_DeleteFile(dll_path_name);
// Make the hog filename
ddio_MakePath(lib_name, Base_directory, "online", name, NULL);
ddio_MakePath(lib_name, Base_directory.u8string().c_str(), "online", name, NULL);
strcat(lib_name, ".d3c");
// Make the dll filename
#if defined(WIN32)
Expand All @@ -611,7 +611,7 @@ int LoadMultiDLL(const char *name) {

// Open the hog file
if (!cf_OpenLibrary(lib_name)) {
ddio_MakePath(tmp_dll_name, Base_directory, "online", name, NULL);
ddio_MakePath(tmp_dll_name, Base_directory.u8string().c_str(), "online", name, NULL);
strcat(tmp_dll_name, ".d3c");
Multi_conn_dll_name[0] = 0;
goto loaddll;
Expand Down
6 changes: 3 additions & 3 deletions Descent3/multi_ui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ int MainMultiplayerMenu() {
char buffer[_MAX_PATH], fname[_MAX_PATH], fext[_MAX_PATH], fdir[_MAX_PATH];
char search[256];

ddio_MakePath(search, Base_directory, "online", "*.d3c", NULL);
ddio_MakePath(search, Base_directory.u8string().c_str(), "online", "*.d3c", NULL);

int dftidx = -1;
dllcount = 0;
Expand Down Expand Up @@ -1066,7 +1066,7 @@ void DoMultiAllowed(void) {
void MultiDoConfigSave(void) {
char file[_MAX_PATH * 2];

ddio_MakePath(file, Base_directory, "custom", "settings", NULL);
ddio_MakePath(file, Base_directory.u8string().c_str(), "custom", "settings", NULL);
if (DoPathFileDialog(true, file, TXT_MULTISAVESET, "*.mps", 0)) {
if (stricmp(file + (strlen(file) - 4), ".mps") != 0)
strcat(file, ".mps");
Expand All @@ -1077,7 +1077,7 @@ void MultiDoConfigSave(void) {
void MultiDoConfigLoad(void) {
char file[_MAX_PATH * 2];

ddio_MakePath(file, Base_directory, "custom", "settings", NULL);
ddio_MakePath(file, Base_directory.u8string().c_str(), "custom", "settings", NULL);
if (DoPathFileDialog(false, file, TXT_MULTILOADSET, "*.mps", PFDF_FILEMUSTEXIST))
MultiLoadSettings(file);
}
Expand Down
14 changes: 7 additions & 7 deletions Descent3/pilot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1724,7 +1724,7 @@ bool PltDelete(pilot *Pilot) {
Pilot->get_filename(pfilename);

if (pfilename[0] != 0) {
ddio_MakePath(filename, Base_directory, pfilename, NULL);
ddio_MakePath(filename, Base_directory.u8string().c_str(), pfilename, NULL);
return (ddio_DeleteFile(pfilename) == 1);
} else {
Int3(); // this is odd
Expand All @@ -1740,7 +1740,7 @@ bool PltDelete(pilot *Pilot) {

strcpy(pfilename, pname);
strcat(pfilename, PLTEXTENSION);
ddio_MakePath(filename, Base_directory, pfilename, NULL);
ddio_MakePath(filename, Base_directory.u8string().c_str(), pfilename, NULL);
return (ddio_DeleteFile(filename) == 1);
}
}
Expand Down Expand Up @@ -1782,7 +1782,7 @@ void PltReadFile(pilot *Pilot, bool keyconfig, bool missiondata) {
return;

// open and process file
ddio_MakePath(filename, Base_directory, pfilename, NULL);
ddio_MakePath(filename, Base_directory.u8string().c_str(), pfilename, NULL);
try {
file = cfopen(filename, "rb");
if (!file)
Expand Down Expand Up @@ -1857,14 +1857,14 @@ char **PltGetPilots(int *count, char *ignore_filename, int display_default_confi
switch (display_default_configs) {
case 0:
ASSERT(loop_count == 0);
ddio_MakePath(search, Base_directory, PLTWILDCARD, NULL);
ddio_MakePath(search, Base_directory.u8string().c_str(), PLTWILDCARD, NULL);
break;
case 1:
ddio_MakePath(search, Base_directory, (loop_count == 0) ? PLTWILDCARD : DPLTWILDCARD, NULL);
ddio_MakePath(search, Base_directory.u8string().c_str(), (loop_count == 0) ? PLTWILDCARD : DPLTWILDCARD, NULL);
break;
case 2:
ASSERT(loop_count == 0);
ddio_MakePath(search, Base_directory, DPLTWILDCARD, NULL);
ddio_MakePath(search, Base_directory.u8string().c_str(), DPLTWILDCARD, NULL);
break;
default:
Int3();
Expand Down Expand Up @@ -3930,7 +3930,7 @@ void _ReadOldPilotFile(pilot *Pilot, bool keyconfig, bool missiondata) {
Pilot->get_filename(pfilename);

// open and process file
ddio_MakePath(filename, Base_directory, pfilename, NULL);
ddio_MakePath(filename, Base_directory.u8string().c_str(), pfilename, NULL);
CFILE *file = cfopen(filename, "rb");
if (!file)
return;
Expand Down
4 changes: 2 additions & 2 deletions Descent3/pilot_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ int pilot::flush(bool new_file) {
char real_filename[_MAX_PATH];

// open and process file
ddio_MakePath(real_filename, Base_directory, filename, NULL);
ddio_MakePath(real_filename, Base_directory.u8string().c_str(), filename, NULL);

if (new_file && cfexist(real_filename)) {
// the file already exists, we can't write out
Expand Down Expand Up @@ -516,7 +516,7 @@ int pilot::read(bool skip_config, bool skip_mission_data) {
char real_filename[_MAX_PATH];

// open and process file
ddio_MakePath(real_filename, Base_directory, filename, NULL);
ddio_MakePath(real_filename, Base_directory.u8string().c_str(), filename, NULL);

if (!cfexist(real_filename)) {
// the file already exists, we can't write out
Expand Down
2 changes: 1 addition & 1 deletion editor/MainFrm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1461,7 +1461,7 @@ void InitCScripts() {
CreateNewMine();

// Setup include directories for OSIRIS
ddio_MakePath(path, Base_directory, "data", "levels", NULL);
ddio_MakePath(path, Base_directory.u8string().c_str(), "data", "levels", NULL);
}

// Copied from winmain.cpp
Expand Down
4 changes: 2 additions & 2 deletions editor/editor_lighting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ void DoRadiosityForRooms() {

if (save_after_bsp) {
char filename[_MAX_PATH];
ddio_MakePath(filename, Base_directory, "BSPSave.D3L", NULL);
ddio_MakePath(filename, Base_directory.u8string().c_str(), "BSPSave.D3L", NULL);

// Save the level to
SaveLevel(filename);
Expand Down Expand Up @@ -1141,7 +1141,7 @@ void DoRadiosityForRooms() {
SqueezeLightmaps(0, -1);

char filename[_MAX_PATH + 1];
ddio_MakePath(filename, Base_directory, "LightSave.D3L", NULL);
ddio_MakePath(filename, Base_directory.u8string().c_str(), "LightSave.D3L", NULL);

// Save the level to disk
SaveLevel(filename);
Expand Down
4 changes: 2 additions & 2 deletions editor/gameeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,7 @@ void GameToEditor(bool set_viewer_from_player) {
if (Temp_level_saved) {
char filename[_MAX_PATH];

ddio_MakePath(filename, Base_directory, "GameSave.D3L", NULL); // make explicit path
ddio_MakePath(filename, Base_directory.u8string().c_str(), "GameSave.D3L", NULL); // make explicit path
LoadLevel(filename);
Temp_level_saved = 0;
}
Expand Down Expand Up @@ -760,7 +760,7 @@ void EditorToGame() {
// set game working directory
bool set_size = false;
ddio_GetWorkingDir(Editor_dir, sizeof(Editor_dir));
ddio_SetWorkingDir(Base_directory);
ddio_SetWorkingDir(Base_directory.u8string().c_str());

Osiris_ResetAllTimers();

Expand Down
9 changes: 7 additions & 2 deletions manage/manage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,8 +674,13 @@ int mng_LoadTableFiles(int show_progress) {
// This is for initting tables on STAND_ALONE, if the network is down, or if
// the user doesn't want network support
int mng_InitLocalTables() {
// Set the local table directory from the base directory
strcpy(LocalD3Dir, Base_directory);
// Set the local table directory from the base directory.
auto base_directory_string = Base_directory.u8string();
strncpy(LocalD3Dir, base_directory_string.c_str(), sizeof LocalD3Dir);
LocalD3Dir[sizeof LocalD3Dir - 1] = '\0';
if (strlen(LocalD3Dir) != strlen(base_directory_string.c_str())) {
mprintf(0, "Warning: Base_directory is too long to fit in LocalD3Dir, so LocalD3Dir was truncated.");
}
mprintf(1, "Local dir:%s\n", LocalD3Dir);

// Make the CFILE system first look at our local directories. If the goods aren't
Expand Down
Loading

0 comments on commit 5834b66

Please sign in to comment.