Before this change, Descent 3 would look for all of its game data files
in a single directory. This change allows users to spread out Descent
3’s game data over multiple directories.
Building Descent 3 produces multiple files that can be freely
redistributed (Descent3, d3-linux.hog, online/Direct TCP~IP.d3c, etc.).
Running Descent 3 requires those files and several additional files that
cannot be freely redistributed. Before this change, the files that were
redistributable had to be in the same directory as the files that were
not redistributable. This change makes it so that they can be in
separate directories.
The main motivation behind this change is to allow people to package
Descent 3 for Linux in a reasonable manner. For the most part, binary
packages for Descent 3 will contain all of the freely redistributable
components. Package managers will copy those components into system
directories that are owned by root and that users probably shouldn’t
edit manually. Users will then create a new directory and copy the game
data from their copy of Descent 3 into that new directory. Users will
then be able to run:
Descent3 -setdir <path-to-proprietary-files> -additionaldir <path-to-open-source-files>
The -additionaldir option can also be used to support more complicated
scenarios. For example, if the user is using Debian’s
game-data-packager [1], then they would do something like this:
Descent3 -setdir <path-to-writable-directory> -additionaldir <path-to-gdp-directory> -additionaldir <path-to-open-source-files>
The -additionaldir option can also be used to load a mod that replaces
.hog files:
Descent3 -setdir <path-to-base-game-data> -additionaldir <path-to-mod-files>
[1]: <https://github.com/DescentDevelopers/Descent3/issues/373#issuecomment-2120330650>
Descent 3 is case-insensitive. It doesn’t matter if a file is named
“ppics.hog” or “PPPICS.HOG”. Descent 3 will load the file regardless. In
order to accomplish this, Descent 3 has to have special code for
case-sensitive filesystems. That code must take a fake case-insensitive
path and turn it into a real case-sensitive path.
Before this change, there was multiple chunks of code that helped turn
fake case-insensitive paths into real case-sensitive paths. There was
cf_FindRealFileNameCaseInsenstive(), mve_FindMovieFileRealName() and a
chunk of code in open_file_in_directory() that only exists if __LINUX__
is defined. This removes each of those pieces of code and replaces them
with a new cf_LocatePath() function.
Using the new cf_LocatePath() function has two main advantages over the
old way of doing things. First, having a single function is simpler than
having three different pieces of code. Second, the new cf_LocatePath()
function will make it easier to create a future commit. That future
commit will make Descent 3 look for files in more than just the -setdir
directory. Having a single function that’s responsible for determining
the true path of a file will make it much easier to create that future
commit.
The main motivation behind this commit is to make it easier to create a
future commit. That futures commit will rename the
cf_FindRealFileNameCaseInsensitive() function and change its code
slightly. I was struggling to create that future commit because I found
the code in cf_FindRealFileNameCaseInsensitive() difficult to
understand. This change will make it easier to create that future commit
by making the code in cf_FindRealFileNameCaseInsensitive() easier to
understand.
The main motivation behind this commit is to make it easier to create a
future commit. That future commit will will take multiple different
functions from throughout the codebase and replace them with a new
function named cf_LocatePath().
One of the functions that will get replaced is
cf_FindRealFileNameCaseInsensitive(). There are tests for
cf_FindRealFileNameCaseInsensitive() in cfile/tests/cfile_tests.cpp.
When I make that future commit, I will have to change the tests in
cfile/test/cfile_tests.cpp so that they test the cf_LocatePath()
function instead of the cf_FindRealFileNameCaseInsensitive() function.
There is an important difference between cf_LocatePath() and
cf_FindRealFileNameCaseInsensitive(). cf_LocatePath() depends on the
Base_directory variable. cf_FindRealFileNameCaseInsensitive() does not.
In order to update the tests so that they use cf_LocatePath(), I need to
make sure that the tests have access to the Base_directory variable.
Before this change, the Base_directory variable was declared in
Descent3/init.cpp. That meant that if a program wanted to access
Base_directory, then it would have to link to Descent3/init.cpp. In
other words, we would have to link to Descent3/init.cpp when compiling
the program that currently tests cf_FindRealFileNameCaseInsensitive()
but will test cf_LocatePath() in the future. I tried making that program
link to Descent3/init.cpp, but I gave up after a wile. Descent3/init.cpp
depends on a lot of other things in the codebase.
In order to make it easier to create that future commit, this commit
moves the Base_directory variable into the cfile module. When I create
that future commit, I won’t have to mess with anything linking related
because the cfile tests already link to the cfile module. Additionally,
this change will make compiling that test program more efficient.
There’s not need for the compiler to look at the entirety of
Descent3/init.cpp just because we need a single variable from it.
All functions, that uses cf_ReadBytes(), checks return size, but don't handle potential exceptions. That leads to segfaults on reading of damaged files (i.e. broken savegames).
Before this change, cf_OpenLibrary() did something along the lines of
this:
char id[4];
fread(id, 4, 1, fp);
strncmp(id, "HOG2", 4);
If fread() finishes successfully, then that code is fine. However,
fread() might encounter an error or bump into the end of a file. In
those scenarios, the value of id will not necessarily be initialized
[1]. In other words, when fread() fails, strncmp() might operate on
uninitialized memory.
This change makes sure that the value of id only gets used if fread()
succeeds. Additionally, this change fixes a GCC warning about ignoring
fread()’s return value.
[1]: <https://en.cppreference.com/w/cpp/io/c/fread>
Before this change, cf_OpenLibrary() was inconsistent. Sometimes, it
would refer to the size of a HOG2 id using the literal 4. Other times it
would refer to the size of a HOG2 id using strlen(HOG_TAG_STR). There
was a good reason for this. Some compilers allow you to do this:
char id[strlen(HOG_TAG_STR)];
Other compilers throw an error if you try to do that [1].
This commit makes cf_OpenLibrary() more consistent. It makes it so that
cf_OpenLibrary() always uses the same constant expression when referring
to HOG_TAG_STR’s length.
[1]: <https://devblogs.microsoft.com/oldnewthing/20221114-00/?p=107393>
* Begin by marking functions and variables as static when needed.
* More work.
* More work.
* More pokes.
* More work.
* More work.
* Initial work on the netgames.
* Revert changes to the license header on source files.
* clutter.cpp poke.
* One final poke.
* Move some declarations to headers:
Move paged_in_count and paged_in_num to gamesequence.h
Move DoneLightInstance and StartLightInstance to polymodel.h
* Look over the AI script/plug-ins.
* Going over the changes one last time.
* Fix rebase errors.
* More migration from bare statics to static inlines.
The vast majority of this is fixing up `char *` that should be `const char *`
but a handful of other fixes, like potential buffer overflows that GCC
noticed, etc, were applied as well.
This removes `-Wno-write-strings` from CMakeLists.txt, as it is no longer
necessary, as there is no longer a flood of compiler warning spam when
building.
This does not fix all compiler warnings; there are still a handful, and they
are legitimate, but they can be dealt with in a future commit.
The MACINTOSH define refers to MacOS Classic (not OS X) which we do not
plan to support. Rather than carry the cruft forever, let's delete it.
NOTE: legacy/ is unused but we're keeping it around, so MACINTOSH uses
there are left alone.
Process used for this commit:
```
git rm -r mac
find . \( -iname "*.c" -or -iname "*.cpp" -or -iname "*.h" \) \
-exec unifdef -UMACINTOSH -o {} {} \;
git restore legacy
git add .
```
Test Plan:
On Mac, build both Debug and Release
```
cmake --build --preset mac --config Debug
cmake --build --preset mac --config Release
```
Other modules that depends on it, can reuse includes on linking.
There some files formally not belonging any packages (lib directory), as workaround there temporary include_directories(cfile) on root of project. After migrating all modules this can be removed.