Skip to content

Commit 7761a05

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 aed6784 commit 7761a05

20 files changed

+68
-66
lines changed

Descent3/Game2DLL.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -567,7 +567,7 @@ bool InitGameModule(const char *name, module *mod) {
567567
char dll_name[_MAX_PATH * 2];
568568
char tmp_dll_name[_MAX_PATH * 2];
569569
// Make the hog filename
570-
ddio_MakePath(lib_name, Base_directory, "netgames", name, NULL);
570+
ddio_MakePath(lib_name, Base_directory.u8string().c_str(), "netgames", name, NULL);
571571
strcat(lib_name, ".d3m");
572572
// Make the dll filename
573573
#if defined(WIN32)
@@ -580,7 +580,7 @@ bool InitGameModule(const char *name, module *mod) {
580580

581581
// Open the hog file
582582
if (!cf_OpenLibrary(lib_name)) {
583-
ddio_MakePath(tmp_dll_name, Base_directory, "netgames", name, NULL);
583+
ddio_MakePath(tmp_dll_name, Base_directory.u8string().c_str(), "netgames", name, NULL);
584584
strcat(tmp_dll_name, ".d3m");
585585
Multi_game_dll_name[0] = '\0';
586586
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
@@ -360,7 +360,7 @@ void DemoToggleRecording() {
360360
if (stricmp(szfile + (strlen(szfile) - 4), ".dem") != 0) {
361361
strcat(szfile, ".dem");
362362
}
363-
Demo_fname = std::filesystem::path(Base_directory) / "demo" / szfile;
363+
Demo_fname = Base_directory / "demo" / szfile;
364364
mprintf(0, "Saving demo to file: %s\n", Demo_fname.u8string().c_str());
365365
// Try to create the file
366366
Demo_cfp = cfopen(Demo_fname, "wb");
@@ -1423,7 +1423,7 @@ bool LoadDemoDialog() {
14231423
// return false;
14241424
// #else
14251425

1426-
std::filesystem::path file = std::filesystem::path(Base_directory) / "demo";
1426+
std::filesystem::path file = Base_directory / "demo";
14271427

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

Descent3/descent.h

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

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

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

Descent3/game.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1298,7 +1298,7 @@ void DoScreenshot() {
12981298
count = 1;
12991299
while (!done) {
13001300
snprintf(str, sizeof(str), "Screenshot%.3d.png", count);
1301-
ddio_MakePath(filename, Base_directory, str, NULL);
1301+
ddio_MakePath(filename, Base_directory.u8string().c_str(), str, NULL);
13021302
infile = (CFILE *)cfopen(filename, "rb");
13031303
if (infile == NULL) {
13041304
done = 1;

Descent3/gamesave.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ void QuickSaveGame() {
350350
i = Quicksave_game_slot;
351351

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

355355
fp = fopen(pathname, "rb");
356356
if (fp) {
@@ -393,7 +393,7 @@ void SaveGameDialog() {
393393
#endif
394394

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

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

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

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

@@ -588,7 +588,7 @@ bool LoadGameDialog() {
588588
}
589589

590590
// setup paths.
591-
ddio_MakePath(savegame_dir, Base_directory, "savegame", NULL);
591+
ddio_MakePath(savegame_dir, Base_directory.u8string().c_str(), "savegame", NULL);
592592
ddio_MakePath(pathname, savegame_dir, "*.sav", NULL);
593593

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

Descent3/init.cpp

+6-9
Original file line numberDiff line numberDiff line change
@@ -1025,7 +1025,7 @@ static bool Title_bitmap_init = false;
10251025
uint8_t Use_motion_blur = 0;
10261026

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

10301030
extern int Min_allowed_frametime;
10311031

@@ -1399,8 +1399,7 @@ void InitIOSystems(bool editor) {
13991399
int dirarg = FindArg("-setdir");
14001400
int exedirarg = FindArg("-useexedir");
14011401
if (dirarg) {
1402-
strncpy(Base_directory, GameArgs[dirarg + 1], sizeof(Base_directory) - 1);
1403-
Base_directory[sizeof(Base_directory) - 1] = '\0';
1402+
Base_directory = GameArgs[dirarg + 1];
14041403
} else if (exedirarg) {
14051404
char exec_path[_MAX_PATH];
14061405
memset(exec_path, 0, sizeof(exec_path));
@@ -1409,16 +1408,14 @@ void InitIOSystems(bool editor) {
14091408
Error("Failed to get executable path\n");
14101409
} else {
14111410
std::filesystem::path executablePath(exec_path);
1412-
std::string baseDirectoryString = executablePath.parent_path().string();
1413-
strncpy(Base_directory, baseDirectoryString.c_str(), sizeof(Base_directory) - 1);
1414-
Base_directory[sizeof(Base_directory) - 1] = '\0';
1411+
Base_directory = executablePath.parent_path();
14151412
mprintf(0, "Using working directory of %s\n", Base_directory);
14161413
}
14171414
} else {
1418-
ddio_GetWorkingDir(Base_directory, sizeof(Base_directory));
1415+
Base_directory = std::filesystem::current_path();
14191416
}
14201417

1421-
ddio_SetWorkingDir(Base_directory);
1418+
ddio_SetWorkingDir(Base_directory.u8string().c_str());
14221419

14231420
Descent->set_defer_handler(D3DeferHandler);
14241421

@@ -2048,7 +2045,7 @@ void SetupTempDirectory(void) {
20482045
exit(1);
20492046
}
20502047
// restore working dir
2051-
ddio_SetWorkingDir(Base_directory);
2048+
ddio_SetWorkingDir(Base_directory.u8string().c_str());
20522049
}
20532050

20542051
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
@@ -8094,23 +8094,23 @@ char *GetFileNameFromPlayerAndID(int16_t playernum, int16_t id) {
80948094
break;
80958095
case NETFILE_ID_SHIP_TEX:
80968096
if (NetPlayers[playernum].ship_logo[0])
8097-
ddio_MakePath(rval, Base_directory, "custom", "graphics", NetPlayers[playernum].ship_logo, NULL);
8097+
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "graphics", NetPlayers[playernum].ship_logo, NULL);
80988098
break;
80998099
case NETFILE_ID_VOICE_TAUNT1:
81008100
if (NetPlayers[playernum].voice_taunt1[0])
8101-
ddio_MakePath(rval, Base_directory, "custom", "sounds", NetPlayers[playernum].voice_taunt1, NULL);
8101+
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "sounds", NetPlayers[playernum].voice_taunt1, NULL);
81028102
break;
81038103
case NETFILE_ID_VOICE_TAUNT2:
81048104
if (NetPlayers[playernum].voice_taunt2[0])
8105-
ddio_MakePath(rval, Base_directory, "custom", "sounds", NetPlayers[playernum].voice_taunt2, NULL);
8105+
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "sounds", NetPlayers[playernum].voice_taunt2, NULL);
81068106
break;
81078107
case NETFILE_ID_VOICE_TAUNT3:
81088108
if (NetPlayers[playernum].voice_taunt3[0])
8109-
ddio_MakePath(rval, Base_directory, "custom", "sounds", NetPlayers[playernum].voice_taunt3, NULL);
8109+
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "sounds", NetPlayers[playernum].voice_taunt3, NULL);
81108110
break;
81118111
case NETFILE_ID_VOICE_TAUNT4:
81128112
if (NetPlayers[playernum].voice_taunt4[0])
8113-
ddio_MakePath(rval, Base_directory, "custom", "sounds", NetPlayers[playernum].voice_taunt4, NULL);
8113+
ddio_MakePath(rval, Base_directory.u8string().c_str(), "custom", "sounds", NetPlayers[playernum].voice_taunt4, NULL);
81148114
break;
81158115
default:
81168116
mprintf(0, "Unknown id (%d) passed to GetFileNameFromPlayerAndID()\n", id);

Descent3/multi_dll_mgr.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ void GetMultiAPI(multi_api *api) {
527527
api->vp[2] = (int *)&Game_is_master_tracker_game;
528528
api->vp[3] = (int *)&Game_mode;
529529
api->vp[4] = (int *)NULL; // Current_pilot; no longer a struct
530-
api->vp[5] = (int *)Base_directory;
530+
api->vp[5] = (int *)&Base_directory;
531531
api->vp[6] = (int *)&MultiDLLGameStarting;
532532
api->vp[7] = (int *)MTPilotinfo;
533533
api->vp[8] = (int *)&Num_network_games_known;
@@ -597,7 +597,7 @@ int LoadMultiDLL(const char *name) {
597597
if (MultiDLLHandle.handle)
598598
FreeMultiDLL();
599599

600-
std::filesystem::path dll_path_name = std::filesystem::path(Base_directory) / "online";
600+
std::filesystem::path dll_path_name = Base_directory / "online";
601601
ddio_DoForeachFile(dll_path_name, std::regex(".+\\.tmp"), [](const std::filesystem::path& path, ...) {
602602
std::error_code ec;
603603
std::filesystem::remove(path, ec);
@@ -607,7 +607,7 @@ int LoadMultiDLL(const char *name) {
607607
});
608608

609609
// Make the hog filename
610-
ddio_MakePath(lib_name, Base_directory, "online", name, NULL);
610+
ddio_MakePath(lib_name, Base_directory.u8string().c_str(), "online", name, NULL);
611611
strcat(lib_name, ".d3c");
612612
// Make the dll filename
613613
#if defined(WIN32)
@@ -620,7 +620,7 @@ int LoadMultiDLL(const char *name) {
620620

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

Descent3/multi_ui.cpp

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

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

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

@@ -988,15 +988,15 @@ void DoMultiAllowed(void) {
988988
}
989989

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

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

Descent3/pilot.cpp

+4-4
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)
@@ -3311,7 +3311,7 @@ void _ReadOldPilotFile(pilot *Pilot, bool keyconfig, bool missiondata) {
33113311
std::string pfilename = Pilot->get_filename();
33123312

33133313
// open and process file
3314-
std::filesystem::path filename = std::filesystem::path(Base_directory) / pfilename;
3314+
std::filesystem::path filename = Base_directory / pfilename;
33153315
CFILE *file = cfopen(filename, "rb");
33163316
if (!file)
33173317
return;

Descent3/pilot_class.cpp

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

418418
CFILE *file;
419-
std::filesystem::path real_filename = std::filesystem::path(Base_directory) / filename;
419+
std::filesystem::path real_filename = Base_directory / filename;
420420

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

500500
CFILE *file;
501-
std::filesystem::path real_filename = std::filesystem::path(Base_directory) / filename;
501+
std::filesystem::path real_filename = Base_directory / filename;
502502

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

editor/MainFrm.cpp

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

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

14671467
// 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
@@ -613,7 +613,7 @@ void GameToEditor(bool set_viewer_from_player) {
613613
if (Temp_level_saved) {
614614
char filename[_MAX_PATH];
615615

616-
ddio_MakePath(filename, Base_directory, "GameSave.D3L", NULL); // make explicit path
616+
ddio_MakePath(filename, Base_directory.u8string().c_str(), "GameSave.D3L", NULL); // make explicit path
617617
LoadLevel(filename);
618618
Temp_level_saved = 0;
619619
}
@@ -753,7 +753,7 @@ void EditorToGame() {
753753
// set game working directory
754754
bool set_size = false;
755755
ddio_GetWorkingDir(Editor_dir, sizeof(Editor_dir));
756-
ddio_SetWorkingDir(Base_directory);
756+
ddio_SetWorkingDir(Base_directory.u8string().c_str());
757757

758758
Osiris_ResetAllTimers();
759759

manage/manage.cpp

+7-2
Original file line numberDiff line numberDiff line change
@@ -674,8 +674,13 @@ int mng_LoadTableFiles(int show_progress) {
674674
// This is for initting tables on STAND_ALONE, if the network is down, or if
675675
// the user doesn't want network support
676676
int mng_InitLocalTables() {
677-
// Set the local table directory from the base directory
678-
strcpy(LocalD3Dir, Base_directory);
677+
// Set the local table directory from the base directory.
678+
auto base_directory_string = Base_directory.u8string();
679+
strncpy(LocalD3Dir, base_directory_string.c_str(), sizeof LocalD3Dir);
680+
LocalD3Dir[sizeof LocalD3Dir - 1] = '\0';
681+
if (strlen(LocalD3Dir) != strlen(base_directory_string.c_str())) {
682+
mprintf(0, "Warning: Base_directory is too long to fit in LocalD3Dir, so LocalD3Dir was truncated.");
683+
}
679684
mprintf(1, "Local dir:%s\n", LocalD3Dir);
680685

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

0 commit comments

Comments
 (0)