Skip to content

Commit 977697d

Browse files
committed
Turn Base_directory into an std::filesystem::path
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. Before this commit, the code would work around this problem in two different ways: 1. It would use Descent 3–specific functions that implement path operations on char arrays/pointers (for example, ddio_MakePath()). Once all paths use std::filesystem::path, we’ll be able to simplify the code by removing those functions. 2. It would temporarily convert Base_directory into an std::filesystem::path. This commit simplifies the code by removing those temporary conversions because they are no longer necessary. [1]: 7cd7902 (Merge pull request DescentDevelopers#494 from Jayman2000/encoding-improvements, 2024-07-20) [2]: <rust-lang/rust#12056>
1 parent 16cf59b commit 977697d

22 files changed

+58
-57
lines changed

Descent3/Game2DLL.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ bool InitGameModule(const char *name, module *mod) {
565565
char dll_name[_MAX_PATH * 2];
566566
char tmp_dll_name[_MAX_PATH * 2];
567567
// Make the hog filename
568-
ddio_MakePath(lib_name, Base_directory, "netgames", name, NULL);
568+
ddio_MakePath(lib_name, Base_directory.u8string().c_str(), "netgames", name, NULL);
569569
strcat(lib_name, ".d3m");
570570
// Make the dll filename
571571
#if defined(WIN32)
@@ -578,7 +578,7 @@ bool InitGameModule(const char *name, module *mod) {
578578

579579
// Open the hog file
580580
if (!cf_OpenLibrary(lib_name)) {
581-
ddio_MakePath(tmp_dll_name, Base_directory, "netgames", name, NULL);
581+
ddio_MakePath(tmp_dll_name, Base_directory.u8string().c_str(), "netgames", name, NULL);
582582
strcat(tmp_dll_name, ".d3m");
583583
Multi_game_dll_name[0] = '\0';
584584
goto loaddll;

Descent3/ambient.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ void WriteAmbientData() {
293293
CFILE *ofile;
294294

295295
#ifndef NEWEDITOR
296-
ddio_MakePath(filename, Base_directory, "data", "misc", AMBIENT_FILE_NAME, NULL);
296+
ddio_MakePath(filename, Base_directory.u8string().c_str(), "data", "misc", AMBIENT_FILE_NAME, NULL);
297297
#else
298298
ddio_MakePath(filename, D3HogDir, "data", "misc", AMBIENT_FILE_NAME, NULL);
299299
#endif

Descent3/demofile.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ void DemoToggleRecording() {
359359
if (stricmp(szfile + (strlen(szfile) - 4), ".dem") != 0) {
360360
strcat(szfile, ".dem");
361361
}
362-
Demo_fname = std::filesystem::path(Base_directory) / "demo" / szfile;
362+
Demo_fname = Base_directory / "demo" / szfile;
363363
LOG_INFO.printf("Saving demo to file: %s", Demo_fname.u8string().c_str());
364364
// Try to create the file
365365
Demo_cfp = cfopen(Demo_fname, "wb");
@@ -1408,7 +1408,7 @@ bool LoadDemoDialog() {
14081408
// return false;
14091409
// #else
14101410

1411-
std::filesystem::path file = std::filesystem::path(Base_directory) / "demo";
1411+
std::filesystem::path file = Base_directory / "demo";
14121412

14131413
if (DoPathFileDialog(false, file, TXT_VIEWDEMO, {"*.dem"}, PFDF_FILEMUSTEXIST)) {
14141414
Demo_fname = file;

Descent3/descent.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ void Descent3() {
490490
};
491491

492492
for (auto const &intro : intros) {
493-
PlayMovie(std::filesystem::path(Base_directory) / "movies" / intro);
493+
PlayMovie(Base_directory / "movies" / intro);
494494
}
495495
}
496496

Descent3/descent.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ extern bool Descent_overrided_intro;
182182
#define MSN_NAMELEN 32
183183

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

187187
// Variable to preserve current path. TODO: redundant?
188188
extern std::filesystem::path orig_pwd;

Descent3/game.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1291,7 +1291,7 @@ void DoScreenshot() {
12911291
count = 1;
12921292
while (!done) {
12931293
snprintf(str, sizeof(str), "Screenshot%.3d.png", count);
1294-
ddio_MakePath(filename, Base_directory, str, NULL);
1294+
ddio_MakePath(filename, Base_directory.u8string().c_str(), str, NULL);
12951295
infile = (CFILE *)cfopen(filename, "rb");
12961296
if (infile == NULL) {
12971297
done = 1;

Descent3/gamesave.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ void QuickSaveGame() {
348348
i = Quicksave_game_slot;
349349

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

353353
fp = fopen(pathname, "rb");
354354
if (fp) {
@@ -391,7 +391,7 @@ void SaveGameDialog() {
391391
#endif
392392

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

397397
// create savegame directory if it didn't exist before.
@@ -543,7 +543,7 @@ void __cdecl LoadGameDialogCB(newuiTiledWindow *wnd, void *data)
543543

544544
LOG_DEBUG.printf("savegame slot=%d", id - SAVE_HOTSPOT_ID);
545545

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

@@ -586,7 +586,7 @@ bool LoadGameDialog() {
586586
}
587587

588588
// setup paths.
589-
ddio_MakePath(savegame_dir, Base_directory, "savegame", NULL);
589+
ddio_MakePath(savegame_dir, Base_directory.u8string().c_str(), "savegame", NULL);
590590
ddio_MakePath(pathname, savegame_dir, "*.sav", NULL);
591591

592592
// create savegame directory if it didn't exist before.

Descent3/gamespy.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ int gspy_Init() {
124124
}
125125

126126
// Read the config, resolve the name if needed and setup the server addresses
127-
cfgpath = std::filesystem::path(Base_directory) / gspy_cfgfilename;
127+
cfgpath = Base_directory / gspy_cfgfilename;
128128

129129
gspy_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
130130

Descent3/init.cpp

+6-9
Original file line numberDiff line numberDiff line change
@@ -1027,7 +1027,7 @@ static bool Title_bitmap_init = false;
10271027
uint8_t Use_motion_blur = 0;
10281028

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

10321032
extern int Min_allowed_frametime;
10331033

@@ -1396,8 +1396,7 @@ void InitIOSystems(bool editor) {
13961396
int dirarg = FindArg("-setdir");
13971397
int exedirarg = FindArg("-useexedir");
13981398
if (dirarg) {
1399-
strncpy(Base_directory, GameArgs[dirarg + 1], sizeof(Base_directory) - 1);
1400-
Base_directory[sizeof(Base_directory) - 1] = '\0';
1399+
Base_directory = GameArgs[dirarg + 1];
14011400
} else if (exedirarg) {
14021401
char exec_path[_MAX_PATH];
14031402
memset(exec_path, 0, sizeof(exec_path));
@@ -1406,16 +1405,14 @@ void InitIOSystems(bool editor) {
14061405
Error("Failed to get executable path\n");
14071406
} else {
14081407
std::filesystem::path executablePath(exec_path);
1409-
std::string baseDirectoryString = executablePath.parent_path().string();
1410-
strncpy(Base_directory, baseDirectoryString.c_str(), sizeof(Base_directory) - 1);
1411-
Base_directory[sizeof(Base_directory) - 1] = '\0';
1408+
Base_directory = executablePath.parent_path();
14121409
LOG_INFO << "Using working directory of " << Base_directory;
14131410
}
14141411
} else {
1415-
ddio_GetWorkingDir(Base_directory, sizeof(Base_directory));
1412+
Base_directory = std::filesystem::current_path();
14161413
}
14171414

1418-
ddio_SetWorkingDir(Base_directory);
1415+
ddio_SetWorkingDir(Base_directory.u8string().c_str());
14191416

14201417
Descent->set_defer_handler(D3DeferHandler);
14211418

@@ -2041,7 +2038,7 @@ void SetupTempDirectory(void) {
20412038
exit(1);
20422039
}
20432040
// restore working dir
2044-
ddio_SetWorkingDir(Base_directory);
2041+
ddio_SetWorkingDir(Base_directory.u8string().c_str());
20452042
}
20462043

20472044
void DeleteTempFiles() {

Descent3/mmItem.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ void mmInterface::Create() {
331331
static_menu_background = true;
332332
} else {
333333
char filename[_MAX_PATH];
334-
ddio_MakePath(filename, Base_directory, "movies", "mainmenu", NULL);
334+
ddio_MakePath(filename, Base_directory.u8string().c_str(), "movies", "mainmenu", NULL);
335335
m_movie = StartMovie(filename, true);
336336

337337
if (!m_movie) //[ISB] Didn't find the menu movie?

Descent3/multi.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -8010,23 +8010,23 @@ char *GetFileNameFromPlayerAndID(int16_t playernum, int16_t id) {
80108010
break;
80118011
case NETFILE_ID_SHIP_TEX:
80128012
if (NetPlayers[playernum].ship_logo[0])
8013-
ddio_MakePath(rval, Base_directory, "custom", "graphics", NetPlayers[playernum].ship_logo, NULL);
8013+
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "graphics", NetPlayers[playernum].ship_logo, NULL);
80148014
break;
80158015
case NETFILE_ID_VOICE_TAUNT1:
80168016
if (NetPlayers[playernum].voice_taunt1[0])
8017-
ddio_MakePath(rval, Base_directory, "custom", "sounds", NetPlayers[playernum].voice_taunt1, NULL);
8017+
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "sounds", NetPlayers[playernum].voice_taunt1, NULL);
80188018
break;
80198019
case NETFILE_ID_VOICE_TAUNT2:
80208020
if (NetPlayers[playernum].voice_taunt2[0])
8021-
ddio_MakePath(rval, Base_directory, "custom", "sounds", NetPlayers[playernum].voice_taunt2, NULL);
8021+
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "sounds", NetPlayers[playernum].voice_taunt2, NULL);
80228022
break;
80238023
case NETFILE_ID_VOICE_TAUNT3:
80248024
if (NetPlayers[playernum].voice_taunt3[0])
8025-
ddio_MakePath(rval, Base_directory, "custom", "sounds", NetPlayers[playernum].voice_taunt3, NULL);
8025+
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "sounds", NetPlayers[playernum].voice_taunt3, NULL);
80268026
break;
80278027
case NETFILE_ID_VOICE_TAUNT4:
80288028
if (NetPlayers[playernum].voice_taunt4[0])
8029-
ddio_MakePath(rval, Base_directory, "custom", "sounds", NetPlayers[playernum].voice_taunt4, NULL);
8029+
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "sounds", NetPlayers[playernum].voice_taunt4, NULL);
80308030
break;
80318031
default:
80328032
LOG_FATAL.printf("Unknown id (%d) passed to GetFileNameFromPlayerAndID()", id);

Descent3/multi_dll_mgr.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ void GetMultiAPI(multi_api *api) {
525525
api->vp[2] = (int *)&Game_is_master_tracker_game;
526526
api->vp[3] = (int *)&Game_mode;
527527
api->vp[4] = (int *)NULL; // Current_pilot; no longer a struct
528-
api->vp[5] = (int *)Base_directory;
528+
api->vp[5] = (int *)&Base_directory;
529529
api->vp[6] = (int *)&MultiDLLGameStarting;
530530
api->vp[7] = (int *)MTPilotinfo;
531531
api->vp[8] = (int *)&Num_network_games_known;
@@ -595,7 +595,7 @@ int LoadMultiDLL(const char *name) {
595595
if (MultiDLLHandle.handle)
596596
FreeMultiDLL();
597597

598-
std::filesystem::path dll_path_name = std::filesystem::path(Base_directory) / "online";
598+
std::filesystem::path dll_path_name = Base_directory / "online";
599599
ddio_DoForeachFile(dll_path_name, std::regex(".+\\.tmp"), [](const std::filesystem::path& path, ...) {
600600
std::error_code ec;
601601
std::filesystem::remove(path, ec);
@@ -605,7 +605,7 @@ int LoadMultiDLL(const char *name) {
605605
});
606606

607607
// Make the hog filename
608-
ddio_MakePath(lib_name, Base_directory, "online", name, NULL);
608+
ddio_MakePath(lib_name, Base_directory.u8string().c_str(), "online", name, NULL);
609609
strcat(lib_name, ".d3c");
610610
// Make the dll filename
611611
#if defined(WIN32)
@@ -618,7 +618,7 @@ int LoadMultiDLL(const char *name) {
618618

619619
// Open the hog file
620620
if (!cf_OpenLibrary(lib_name)) {
621-
ddio_MakePath(tmp_dll_name, Base_directory, "online", name, NULL);
621+
ddio_MakePath(tmp_dll_name, Base_directory.u8string().c_str(), "online", name, NULL);
622622
strcat(tmp_dll_name, ".d3c");
623623
Multi_conn_dll_name[0] = 0;
624624
goto loaddll;

Descent3/multi_ui.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ int MainMultiplayerMenu() {
442442

443443
std::vector<std::string> dllnames;
444444

445-
ddio_DoForeachFile(std::filesystem::path(Base_directory) / "online", std::regex(".*\\.d3c"),
445+
ddio_DoForeachFile(Base_directory / "online", std::regex(".*\\.d3c"),
446446
[&dllnames](const std::filesystem::path &path) {
447447
std::string filename = path.stem().string();
448448

@@ -989,15 +989,15 @@ void DoMultiAllowed(void) {
989989
}
990990

991991
void MultiDoConfigSave() {
992-
std::filesystem::path file = std::filesystem::path(Base_directory) / "custom" / "settings";
992+
std::filesystem::path file = Base_directory / "custom" / "settings";
993993
if (DoPathFileDialog(true, file, TXT_MULTISAVESET, {"*.mps"}, 0)) {
994994
file.replace_extension(".mps");
995995
MultiSaveSettings(file);
996996
}
997997
}
998998

999999
void MultiDoConfigLoad() {
1000-
std::filesystem::path file = std::filesystem::path(Base_directory) / "custom" / "settings";
1000+
std::filesystem::path file = Base_directory / "custom" / "settings";
10011001
if (DoPathFileDialog(false, file, TXT_MULTILOADSET, {"*.mps"}, PFDF_FILEMUSTEXIST))
10021002
MultiLoadSettings(file);
10031003
}

Descent3/pilot.cpp

+5-6
Original file line numberDiff line numberDiff line change
@@ -1583,7 +1583,7 @@ bool PltDelete(pilot *Pilot) {
15831583
std::string pfilename = Pilot->get_filename();
15841584
std::error_code ec;
15851585
if (!pfilename.empty()) {
1586-
return std::filesystem::remove(std::filesystem::path(Base_directory) / pfilename, ec);
1586+
return std::filesystem::remove(Base_directory / pfilename, ec);
15871587
} else {
15881588
Int3(); // this is odd
15891589

@@ -1597,7 +1597,7 @@ bool PltDelete(pilot *Pilot) {
15971597
PltMakeFNValid(pname);
15981598

15991599
pfilename = std::string(pname) + PLTEXTENSION;
1600-
return std::filesystem::remove(std::filesystem::path(Base_directory) / pfilename, ec);
1600+
return std::filesystem::remove(Base_directory / pfilename, ec);
16011601
}
16021602
}
16031603

@@ -1636,7 +1636,7 @@ void PltReadFile(pilot *Pilot, bool keyconfig, bool missiondata) {
16361636
return;
16371637

16381638
// open and process file
1639-
std::filesystem::path filename = std::filesystem::path(Base_directory) / pfilename;
1639+
std::filesystem::path filename = Base_directory / pfilename;
16401640
try {
16411641
file = cfopen(filename, "rb");
16421642
if (!file)
@@ -1679,7 +1679,6 @@ std::vector<std::string> PltGetPilots(std::string ignore_filename, int display_d
16791679
// clear list
16801680
PltClearList();
16811681

1682-
std::filesystem::path search = std::filesystem::path(Base_directory);
16831682
std::regex wildcard;
16841683
std::vector<std::string> result;
16851684

@@ -1701,7 +1700,7 @@ std::vector<std::string> PltGetPilots(std::string ignore_filename, int display_d
17011700
break;
17021701
}
17031702

1704-
ddio_DoForeachFile(search, wildcard, [&ignore_filename, &result](const std::filesystem::path &path) {
1703+
ddio_DoForeachFile(Base_directory, wildcard, [&ignore_filename, &result](const std::filesystem::path &path) {
17051704
std::string pilot = path.filename().u8string();
17061705
if (!ignore_filename.empty() && stricmp(ignore_filename.c_str(), pilot.c_str()) == 0) {
17071706
LOG_INFO.printf("Getting Pilots... found %s, but ignoring", pilot.c_str());
@@ -3277,7 +3276,7 @@ void _ReadOldPilotFile(pilot *Pilot, bool keyconfig, bool missiondata) {
32773276
std::string pfilename = Pilot->get_filename();
32783277

32793278
// open and process file
3280-
std::filesystem::path filename = std::filesystem::path(Base_directory) / pfilename;
3279+
std::filesystem::path filename = Base_directory / pfilename;
32813280
CFILE *file = cfopen(filename, "rb");
32823281
if (!file)
32833282
return;

Descent3/pilot_class.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ int pilot::flush(bool new_file) {
415415
}
416416

417417
CFILE *file;
418-
std::filesystem::path real_filename = std::filesystem::path(Base_directory) / filename;
418+
std::filesystem::path real_filename = Base_directory / filename;
419419

420420
if (new_file && cfexist(real_filename)) {
421421
// the file already exists, we can't write out
@@ -497,7 +497,7 @@ int pilot::read(bool skip_config, bool skip_mission_data) {
497497
}
498498

499499
CFILE *file;
500-
std::filesystem::path real_filename = std::filesystem::path(Base_directory) / filename;
500+
std::filesystem::path real_filename = Base_directory / filename;
501501

502502
if (!cfexist(real_filename)) {
503503
// the file already exists, we can't write out

editor/MainFrm.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1460,7 +1460,7 @@ void InitCScripts() {
14601460
CreateNewMine();
14611461

14621462
// Setup include directories for OSIRIS
1463-
ddio_MakePath(path, Base_directory, "data", "levels", NULL);
1463+
ddio_MakePath(path, Base_directory.u8string().c_str(), "data", "levels", NULL);
14641464
}
14651465

14661466
// Copied from winmain.cpp

editor/editor_lighting.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ void DoRadiosityForRooms() {
870870

871871
if (save_after_bsp) {
872872
char filename[_MAX_PATH];
873-
ddio_MakePath(filename, Base_directory, "BSPSave.D3L", NULL);
873+
ddio_MakePath(filename, Base_directory.u8string().c_str(), "BSPSave.D3L", NULL);
874874

875875
// Save the level to
876876
SaveLevel(filename);
@@ -1140,7 +1140,7 @@ void DoRadiosityForRooms() {
11401140
SqueezeLightmaps(0, -1);
11411141

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

11451145
// Save the level to disk
11461146
SaveLevel(filename);

editor/gameeditor.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ void GameToEditor(bool set_viewer_from_player) {
612612
if (Temp_level_saved) {
613613
char filename[_MAX_PATH];
614614

615-
ddio_MakePath(filename, Base_directory, "GameSave.D3L", NULL); // make explicit path
615+
ddio_MakePath(filename, Base_directory.u8string().c_str(), "GameSave.D3L", NULL); // make explicit path
616616
LoadLevel(filename);
617617
Temp_level_saved = 0;
618618
}
@@ -748,7 +748,7 @@ void EditorToGame() {
748748
// set game working directory
749749
bool set_size = false;
750750
ddio_GetWorkingDir(Editor_dir, sizeof(Editor_dir));
751-
ddio_SetWorkingDir(Base_directory);
751+
ddio_SetWorkingDir(Base_directory.u8string().c_str());
752752

753753
Osiris_ResetAllTimers();
754754

manage/manage.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -672,8 +672,13 @@ int mng_LoadTableFiles(int show_progress) {
672672
// This is for initting tables on STAND_ALONE, if the network is down, or if
673673
// the user doesn't want network support
674674
int mng_InitLocalTables() {
675-
// Set the local table directory from the base directory
676-
strcpy(LocalD3Dir, Base_directory);
675+
// Set the local table directory from the base directory.
676+
auto base_directory_string = Base_directory.u8string();
677+
strncpy(LocalD3Dir, base_directory_string.c_str(), sizeof LocalD3Dir);
678+
LocalD3Dir[sizeof LocalD3Dir - 1] = '\0';
679+
if (strlen(LocalD3Dir) != strlen(base_directory_string.c_str())) {
680+
LOG_WARNING << "Base_directory is too long to fit in LocalD3Dir, so LocalD3Dir was truncated.";
681+
}
677682
LOG_INFO << "Local dir: " << LocalD3Dir;
678683

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

0 commit comments

Comments
 (0)