From c58633f450b35bba9c0c8fd0cc7efc0769f88c86 Mon Sep 17 00:00:00 2001 From: Jason Yundt Date: Sat, 5 Oct 2024 14:15:35 -0400 Subject: [PATCH] Add DEFAULT_ADDITIONAL_DIRS CMake option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The main motivation behind this change is to make it easier to package Descent 3 for Linux. For example, let’s say that you’re packaging Descent 3 for Debian and you want to make the package work well with Debian’s game-data-packager. The package for the Descent 3 engine will put d3-linux.hog in one directory, and the package for the proprietary Descent 3 game data will put d3.hog into a different directory [1]. The Descent 3 engine package can use the DEFAULT_ADDITIONAL_DIRS CMake option in order to make sure that both d3-linux.hog and d3.hog are located automatically. --- BUILD.md | 25 +++++++++++++----------- Descent3/init.cpp | 4 ++++ USAGE.md | 7 ++++--- cfile/CMakeLists.txt | 13 +++++++++++++ cfile/cfile.cpp | 13 +++++++++++++ cfile/cfile.h | 8 ++++++++ cfile/default_base_directories.h.in | 30 +++++++++++++++++++++++++++++ 7 files changed, 86 insertions(+), 14 deletions(-) create mode 100644 cfile/default_base_directories.h.in diff --git a/BUILD.md b/BUILD.md index 49e9133d..0ed8b771 100644 --- a/BUILD.md +++ b/BUILD.md @@ -195,15 +195,18 @@ cmake --preset linux -DBUILD_TESTING=ON You can also use the [cmake-gui](https://cmake.org/cmake/help/latest/manual/cmake-gui.1.html) front-end to easily set and view CMake cache variable values, and generate build -| Option | Description | Default | -|--------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------| -| `CMAKE_BUILD_TYPE` | `Debug` builds are generally larger, slower and contain extra correctness checks that will validate game data and interrupt gameplay when problems are detected.
`Release` builds are optimized for size and speed and do not include debugging information, which makes it harder to find problems. The build type can also be set using the `--config` argument with a preset. | `Debug` | -| `BUILD_EDITOR` | _(Windows-only)_ Build internal editor. | `OFF` | -| `BUILD_TESTING` | Enable testing. Requires GTest. | `OFF` | -| `ENABLE_LOGGER` | Enable logging to the terminal. | `OFF` | -| `ENABLE_MEM_RTL` | Enable Real-time library memory management functions (disable to verbose memory allocations). | `ON` | -| `FORCE_COLORED_OUTPUT` | Always produce ANSI-colored compiler warnings/errors (GCC/Clang only; esp. useful with Ninja). | `OFF` | -| `FORCE_PORTABLE_INSTALL` | Install all files into local directory defined by `CMAKE_INSTALL_PREFIX`. | `ON` | +| Option | Description | Default | +|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------| +| `CMAKE_BUILD_TYPE` | `Debug` builds are generally larger, slower and contain extra correctness checks that will validate game data and interrupt gameplay when problems are detected.
`Release` builds are optimized for size and speed and do not include debugging information, which makes it harder to find problems. The build type can also be set using the `--config` argument with a preset. | `Debug` | +| `BUILD_EDITOR` | _(Windows-only)_ Build internal editor. | `OFF` | +| `BUILD_TESTING` | Enable testing. Requires GTest. | `OFF` | +| `DEFAULT_ADDITIONAL_DIRS` | A semi-colon separated list of paths that Descent 3 will use as read-only base directories (see [USAGE.md’s Base directories section][1]). Each item in this list is placed between quotation marks in order to form a C++ expression. This will cause issues if the items in the list are not properly escaped. You can use C++ escape sequences in order to embed special characters (like `\`, `"` and `;`) in paths. Example: `C:\\Games\\Descent3\\;D:\\` | A list with one item in it. The item is an empty string. | +| `ENABLE_LOGGER` | Enable logging to the terminal. | `OFF` | +| `ENABLE_MEM_RTL` | Enable Real-time library memory management functions (disable to verbose memory allocations). | `ON` | +| `FORCE_COLORED_OUTPUT` | Always produce ANSI-colored compiler warnings/errors (GCC/Clang only; esp. useful with Ninja). | `OFF` | +| `FORCE_PORTABLE_INSTALL` | Install all files into local directory defined by `CMAKE_INSTALL_PREFIX`. | `ON` | | `OFF` | -| `USE_VCPKG` | Explicitly control whether or not to use vcpkg for dependency resolution. `ON` requires the environment variable `VCPKG_ROOT` to be set. | Determined by the existence of `VCPKG_ROOT` in the environment: If it exists, vcpkg is used. | -| `CODESIGN_IDENTITY` | Sets the macOS code signing identity. If set to something besides the empty string, then the dynamic libraries put into the hog files will be signed using this identity. | The empty string, `""`. | +| `USE_VCPKG` | Explicitly control whether or not to use vcpkg for dependency resolution. `ON` requires the environment variable `VCPKG_ROOT` to be set. | Determined by the existence of `VCPKG_ROOT` in the environment: If it exists, vcpkg is used. | +| `CODESIGN_IDENTITY` | Sets the macOS code signing identity. If set to something besides the empty string, then the dynamic libraries put into the hog files will be signed using this identity. | The empty string, `""`. | + +[1]: ./USAGE.md#base-directories diff --git a/Descent3/init.cpp b/Descent3/init.cpp index c719ee37..ba2d4992 100644 --- a/Descent3/init.cpp +++ b/Descent3/init.cpp @@ -1,6 +1,7 @@ /* * Descent 3 * Copyright (C) 2024 Parallax Software +* Copyright (C) 2024–2025 Descent Developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1424,6 +1425,9 @@ void InitIOSystems(bool editor) { LOG_INFO << "Setting writable preference path " << pref_path; cf_AddBaseDirectory(pref_path); + // Set the default base directories + cf_AddDefaultBaseDirectories(); + // Additional paths int additionaldirarg = 0; while (0 != (additionaldirarg = FindArg("-additionaldir", additionaldirarg))) { diff --git a/USAGE.md b/USAGE.md index 2e05307a..021d35dc 100644 --- a/USAGE.md +++ b/USAGE.md @@ -87,7 +87,7 @@ Descent 3 has two types of base directories: - The writable base directory can contain both read-write files and read-only files. There is only one writeable base directory. By default, the writable base directory gets set to the current working directory. - The read-only base directories can only contain read-only files. There can be any number of read-only base directories. By default, Descent 3 uses zero read-only base directories. -You can set the writable base directory and the list of read-only base directories using the `-setdir`, `-useexedir` and `-additionaldir` command-line options (see [the next section](#command-line-options)). +You can set the writable base directory and the list of read-only base directories using the `-setdir`, `-useexedir` and `-additionaldir` command-line options (see [the next section](#command-line-options)). Descent 3 also has a list of default read-only base directories. Normally, the list of default read-only base directories is empty, but you can change it by using the `DEFAULT_ADDITIONAL_DIRS` CMake option when compiling Descent 3 (see [BUILD.md’s Build Options section](./BUILD.md#build-options)). When Descent 3 tries to find a read-only file, then it will look through the list of base directories in this order: @@ -95,10 +95,11 @@ When Descent 3 tries to find a read-only file, then it will look through the lis - the second-to-last read-only base directory that was specified on the command-line, - the third-to-last read-only base directory that was specified on the command-line, - … -- the first read-only base directory that was specified on the command-line and, finally, +- the first read-only base directory that was specified on the command-line, +- all of the items on the `DEFAULT_ADDITIONAL_DIRS` list in reverse order, and, finally, - the writable base directory. -Files that are in base directories that are higher on that list will override files that are in base directories that are lower on that list. For example, lets say that you run Descent 3 like this: +Files that are in base directories that are higher on that list will override files that are in base directories that are lower on that list. For example, lets say that the `DEFAULT_ADDITIONAL_DIRS` list is empty and that you run Descent 3 like this: ``` Descent3 -setdir /home/user/my-writable-base-directory -additionaldir /home/user/my-read-only-base-directory diff --git a/cfile/CMakeLists.txt b/cfile/CMakeLists.txt index 8ce50798..b62fd0d5 100644 --- a/cfile/CMakeLists.txt +++ b/cfile/CMakeLists.txt @@ -1,5 +1,6 @@ set(HEADERS cfile.h + default_base_directories.h hogfile.h inffile.h) set(CPPS @@ -8,6 +9,17 @@ set(CPPS inffile.cpp ) +set(DEFAULT_ADDITIONAL_DIRS "" CACHE STRING "A list of directories that Descent 3 will use as read-only base directories.") +string(REPLACE ";" "\",\n \"" DEFAULT_ADDITIONAL_DIRS_CPP_EXPR "${DEFAULT_ADDITIONAL_DIRS}") +string(PREPEND DEFAULT_ADDITIONAL_DIRS_CPP_EXPR "\"") +string(APPEND DEFAULT_ADDITIONAL_DIRS_CPP_EXPR "\"") + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/default_base_directories.h.in + ${CMAKE_CURRENT_BINARY_DIR}/default_base_directories.h + @ONLY +) + add_library(cfile STATIC ${HEADERS} ${CPPS}) target_link_libraries(cfile PRIVATE ddebug @@ -20,6 +32,7 @@ target_include_directories(cfile PUBLIC $ + PRIVATE ${CMAKE_CURRENT_BINARY_DIR} # For default_base_directories.h ) if(BUILD_TESTING) diff --git a/cfile/cfile.cpp b/cfile/cfile.cpp index 55c45a61..454b651e 100644 --- a/cfile/cfile.cpp +++ b/cfile/cfile.cpp @@ -1,6 +1,7 @@ /* * Descent 3 * Copyright (C) 2024 Parallax Software + * Copyright (C) 2024–2025 Descent Developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,6 +31,7 @@ #include "byteswap.h" #include "crossplat.h" #include "cfile.h" +#include "default_base_directories.h" #include "ddio.h" #include "hogfile.h" //info about library file #include "log.h" @@ -75,6 +77,17 @@ cfile_error cfe; // The message for unexpected end of file const char *eof_error = "Unexpected end of file"; +/* The user can specify a list of default read-only base directories by setting + * the -DDEFAULT_ADDITIONAL_DIRS CMake option. This function adds those base + * directories to the list of base directories that the game is currently + * using. + */ +void cf_AddDefaultBaseDirectories() { + for (const auto &base_directory : D3::Default_read_only_base_directories) { + cf_AddBaseDirectory(base_directory); + } +} + /* This function should be called at least once before you use anything else * from this module. */ diff --git a/cfile/cfile.h b/cfile/cfile.h index 42796428..5e2df0ba 100644 --- a/cfile/cfile.h +++ b/cfile/cfile.h @@ -1,6 +1,7 @@ /* * Descent 3 * Copyright (C) 2024 Parallax Software + * Copyright (C) 2024–2025 Descent Developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -155,6 +156,13 @@ extern std::vector Base_directories; */ void cf_AddBaseDirectory(const std::filesystem::path &base_directory); +/* The user can specify a list of default read-only base directories by setting + * the -DDEFAULT_ADDITIONAL_DIRS CMake option. This function adds those base + * directories to the list of base directories that the game is currently + * using. + */ +void cf_AddDefaultBaseDirectories(); + /* After you call this function, you must call cf_AddBaseDirectory() at least * once before you use anything else from this module. */ diff --git a/cfile/default_base_directories.h.in b/cfile/default_base_directories.h.in new file mode 100644 index 00000000..9c5620ea --- /dev/null +++ b/cfile/default_base_directories.h.in @@ -0,0 +1,30 @@ +/* + * Descent 3 + * Copyright (C) 2024–2025 Descent Developers + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef DEFAULT_ADDITIONAL_DIRECTORIES_H +#define DEFAULT_ADDITIONAL_DIRECTORIES_H + +#include +#include + +namespace D3 { + const std::initializer_list Default_read_only_base_directories = { + @DEFAULT_ADDITIONAL_DIRS_CPP_EXPR@ + }; +} // namespace D3 + +#endif