Devirtualization is an optimization in the generated assembly: when a
class C is polymorphic but also final, ``((C *)ptr)->func()`` can be
turned from an indirect into a static call.
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.