diff --git a/Makefile b/Makefile index da6c6a2ae9..ef481521b2 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ install: $(BUILDDIR) .PHONY: run run: build - cd $(BUILDDIR) && ./run game + cd $(BUILDDIR) && ./run main .PHONY: test test: tests checkfast diff --git a/README.md b/README.md index f40bd91d3f..00d3715d85 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Technical foundation [**OpenGL**]: https://www.opengl.org/ [**Opus**]: https://opus-codec.org/ [**nyan**]: https://github.com/SFTtech/nyan -[**Humans**]: https://www.youtube.com/watch?v=fQGbXmkSArs&t=20s +[**Humans**]: https://www.youtube.com/watch?v=fQGbXmkSArs&t=18s Goals ----- diff --git a/buildsystem/DetectProjectVersion.cmake b/buildsystem/DetectProjectVersion.cmake index f7b8258436..8c45b1db64 100644 --- a/buildsystem/DetectProjectVersion.cmake +++ b/buildsystem/DetectProjectVersion.cmake @@ -12,7 +12,7 @@ endif() if(IS_DIRECTORY "${CMAKE_SOURCE_DIR}/.git") message(STATUS "Set PROJECT_VERSION from git.") execute_process( - COMMAND git describe + COMMAND git describe --tags WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" RESULT_VARIABLE _RES OUTPUT_VARIABLE PROJECT_VERSION @@ -30,8 +30,8 @@ set(PROJECT_VERSION_FILE "${CMAKE_SOURCE_DIR}/openage_version") if(EXISTS ${PROJECT_VERSION_FILE}) file(STRINGS ${PROJECT_VERSION_FILE} FILE_DESCRIBE_VERSION) - STRING(REGEX REPLACE "v([0-9]+\\.[0-9]+\\.[0-9]+)" - "\\1" PROJECT_VERSION "${FILE_DESCRIBE_VERSION}") + STRING(REGEX REPLACE "([0-9]+\\.[0-9]+\\.[0-9]+)" + "\\1" PROJECT_VERSION "${FILE_DESCRIBE_VERSION}") endif() # Still could not detect the version. Don't worry, raise a warning (shout a curse word?) and move on. diff --git a/configure b/configure index f6d52a3179..5c32856325 100755 --- a/configure +++ b/configure @@ -113,6 +113,10 @@ def build_type(args): ret = 'Debug' elif mode == 'release': ret = 'Release' + elif mode == 'relwithdebinfo': + ret = 'RelWithDebInfo' + elif mode == 'minsizerel': + ret = 'MinSizeRel' return { "build_type": ret @@ -355,7 +359,7 @@ def parse_args(): formatter_class=argparse.ArgumentDefaultsHelpFormatter) cli.add_argument("--mode", "-m", - choices=["debug", "release"], + choices=["debug", "release", "relwithdebinfo", "minsizerel"], default=getenv("BUILDMODE", default="debug"), help="controls cmake build mode") cli.add_argument("--optimize", "-O", diff --git a/copying.md b/copying.md index 7add8d2036..310076a011 100644 --- a/copying.md +++ b/copying.md @@ -147,6 +147,7 @@ _the openage authors_ are: | Martin | Starman | mstarman à seznam dawt cz | | Zoltán Ács | zoli111 | acszoltan111 à gmail dawt com | | Trevor Slocum | tslocum | trevor à rocket9labs dawt com | +| Munawar Hafiz | munahaf | munawar dawt hafiz à gmail dawt com | If you're a first-time committer, add yourself to the above list. This is not just for legal reasons, but also to keep an overview of all those nicknames. diff --git a/doc/build_instructions/arch_linux.md b/doc/build_instructions/arch_linux.md index d4c1862d0e..7665cb9888 100644 --- a/doc/build_instructions/arch_linux.md +++ b/doc/build_instructions/arch_linux.md @@ -2,10 +2,15 @@ > NOTE: `openage` is packaged in the [AUR](https://aur.archlinux.org/packages/openage-git/)! -This command should provide required packages for Arch Linux installation: +This command should provide required packages from the Arch Linux repositories: `sudo pacman -S --needed eigen python python-mako python-pillow python-numpy python-lz4 python-pygments cython libepoxy libogg libpng ttf-dejavu freetype2 fontconfig harfbuzz cmake sdl2 sdl2_image opusfile opus python-pylint python-toml qt6-declarative` +Additionally, you have to install [`toml11`](https://aur.archlinux.org/packages/toml11) from the AUR. +If you have `yay`, you can run this command: + +`yay -S toml11` + If you don't have a compiler installed, you can select between these commands to install it: - `sudo pacman -S --needed gcc` - `sudo pacman -S --needed clang` diff --git a/doc/changelogs/engine/v0.5.1.md b/doc/changelogs/engine/v0.5.1.md index 6ac9b09442..1eb2514a3d 100644 --- a/doc/changelogs/engine/v0.5.1.md +++ b/doc/changelogs/engine/v0.5.1.md @@ -14,7 +14,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Clang build errors - Wrong type used for asset path on startup - Missing asset directories to CMakeLists -- Faulty length check in AoC conversion processor ## Full commit log diff --git a/doc/changelogs/engine/v0.5.2.md b/doc/changelogs/engine/v0.5.2.md new file mode 100644 index 0000000000..25da0604cb --- /dev/null +++ b/doc/changelogs/engine/v0.5.2.md @@ -0,0 +1,23 @@ +# [0.5.2] - 2023-10-17 +All notable changes for version [0.5.2] are documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) since release [0.4.0]. + +## Changed + +- `make run` now calls `./run main` instead of `./run game` + + +## Fixed + +- Out-of-bound access in matrix constructor +- Version number displayed because non-annotated tags from git were not considered +- Check if clang jthread is joinable before joining +- Prevent engine loop from being optimized out in release builds +- Fix engine modpack export via CLI + + +## Full commit log + +https://github.com/SFTtech/openage/compare/v0.5.1...v0.5.2 diff --git a/doc/media/openage/modpack_definition_file.md b/doc/media/openage/modpack_definition_file.md index a9ff6d6a41..3403949dd6 100644 --- a/doc/media/openage/modpack_definition_file.md +++ b/doc/media/openage/modpack_definition_file.md @@ -31,19 +31,22 @@ The following parameters have to be specified. `[info]` contains general information about the modpack. -| Parameter | Data Type | Optional | Description | -| ------------------ | ------------- | -------- | ------------------------------------------------------------------------ | -| `packagename` | String | No | Name of the modpack. | -| `version` | String | No | Internal version number. Must have [semver](https://semver.org/) format. | -| `versionstr` | String | Yes | Human-readable version string. | -| `repo` | String | Yes | Name of the repo where the package is hosted. | -| `alias` | String | Yes | Alias of the modpack. Aliases can be used for replacing other modpacks. | -| `title` | String | Yes | Title used in UI. | -| `description` | String | Yes | Path to a file with a short description (max 500 chars). | -| `long_description` | String | Yes | Path to a file with a detailed description. | -| `url` | String | Yes | Link to the modpack's website. | -| `license` | Array[String] | Yes | License(s) of the modpack. | - +| Parameter | Data Type | Optional | Description | +| ------------------ | ------------- | -------- | ----------------------------------------------------------------------- | +| `packagename` | String | No | Name of the modpack. | +| `version`\* | String | No | The modpack's internal version number. Must use [semver] format. | +| `versionstr`\* | String | Yes | Human-readable version string. | +| `repo` | String | Yes | Name of the repo where the package is hosted. | +| `alias` | String | Yes | Alias of the modpack. Aliases can be used for replacing other modpacks. | +| `title` | String | Yes | Title used in UI. | +| `description` | String | Yes | Path to a file with a short description (max 500 chars). | +| `long_description` | String | Yes | Path to a file with a detailed description. | +| `url` | String | Yes | Link to the modpack's website. | +| `license` | Array[String] | Yes | License(s) of the modpack. | + +[semver]: https://semver.org/ + +\* `version` is used by the engine to determine the most recent version of a modpack. Therefore, it should be bumped when something in the modpack changes (e.g. whenever a new version gets published). `versionstr` is what is displayed to the user and can contain any string, so it can be used to represent any sensible version format. ## [assets] Section diff --git a/libopenage/engine/engine.cpp b/libopenage/engine/engine.cpp index c3a9985986..9af6d4fe89 100644 --- a/libopenage/engine/engine.cpp +++ b/libopenage/engine/engine.cpp @@ -32,32 +32,28 @@ Engine::Engine(mode mode, // time loop this->time_loop = std::make_shared(); + // game simulation + // this is run in the main thread this->simulation = std::make_shared(this->root_dir, this->cvar_manager, this->time_loop); this->simulation->set_modpacks(mods); + // presenter (optional) if (this->run_mode == mode::FULL) { this->presenter = std::make_shared(this->root_dir, this->simulation, this->time_loop); } + // spawn thread to run time loop this->threads.emplace_back([&]() { this->time_loop->run(); this->time_loop.reset(); }); - this->threads.emplace_back([&]() { - this->simulation->run(); - - this->simulation.reset(); - - if (this->run_mode != mode::FULL) { - this->running = false; - } - }); + // if presenter is used, run it in a separate thread if (this->run_mode == mode::FULL) { this->threads.emplace_back([&]() { this->presenter->run(debug_graphics); @@ -69,13 +65,18 @@ Engine::Engine(mode mode, }); } - log::log(INFO << "Created " << this->threads.size() << " threads" - << " (" << std::jthread::hardware_concurrency() << " available)"); + log::log(INFO << "Using " << this->threads.size() + 1 << " threads " + << "(" << std::jthread::hardware_concurrency() << " available)"); } void Engine::loop() { - while (this->running) { - // TODO + // Run the main game simulation loop: + this->simulation->run(); + + // After stopping, clean up the simulation + this->simulation.reset(); + if (this->run_mode != mode::FULL) { + this->running = false; } } diff --git a/libopenage/engine/engine.h b/libopenage/engine/engine.h index da56e4ead0..967174fe27 100644 --- a/libopenage/engine/engine.h +++ b/libopenage/engine/engine.h @@ -21,7 +21,9 @@ class jthread : public thread { jthread(jthread &&) = default; jthread &operator=(jthread &&) = default; ~jthread() { - this->join(); + if (this->joinable()) { + this->join(); + } } }; } // namespace std diff --git a/libopenage/gamestate/game.cpp b/libopenage/gamestate/game.cpp index 90dfe5ede3..d31310945d 100644 --- a/libopenage/gamestate/game.cpp +++ b/libopenage/gamestate/game.cpp @@ -67,11 +67,12 @@ void Game::load_data(const std::shared_ptr &mod_manager) { recursive = true; if (parts.size() == 1) { // include = "**" - search = include.substr(0, include.size() - 2); + // start in root directory + search = ""; } else { // include = "path/to/somewhere/**" - // remove the slash '/' too + // remove the wildcard '**' and the slash '/' search = include.substr(0, include.size() - 3); } } diff --git a/libopenage/util/matrix.h b/libopenage/util/matrix.h index 6809899e4e..3f723c11ea 100644 --- a/libopenage/util/matrix.h +++ b/libopenage/util/matrix.h @@ -1,4 +1,4 @@ -// Copyright 2015-2018 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once @@ -16,7 +16,7 @@ namespace openage::util { * Matrix class with arithmetic. M rows, N columns. * T = underlying single value type (float, double, ...) */ -template +template class Matrix : public std::array, M> { public: static_assert(M > 0 and N > 0, "0-dimensional matrix not allowed"); @@ -47,8 +47,8 @@ class Matrix : public std::array, M> { /** * Constructor from Vector */ - template ::type> + template ::type> Matrix(const Vector &vec) { for (size_t i = 0; i < M; i++) { (*this)[i][0] = vec[i]; @@ -58,21 +58,25 @@ class Matrix : public std::array, M> { /** * Constructor with N*M values */ - template - Matrix(Ts ... args) { - static_assert(sizeof...(args) == N*M, "not all values supplied"); - - std::array temp{{static_cast(args)...}}; - for (size_t i = 0; i < N*M; i++) { - (*this)[i / (N*M)][i % (N*M)] = temp[i]; + template + Matrix(Ts... args) { + static_assert(sizeof...(args) == N * M, "not all values supplied"); + + std::array temp{{static_cast(args)...}}; + size_t index = 0; + for (size_t row = 0; row < M; row++) { + for (size_t col = 0; col < N; col++) { + (*this)[row][col] = temp[index]; + index += 1; + } } } /** * Constructs the identity matrix for the current size. */ - template ::type> + template ::type> static this_type identity() { this_type res; @@ -86,7 +90,7 @@ class Matrix : public std::array, M> { /** * Test if both matrices contain the same values within epsilon. */ - bool equals(const this_type &other, float eps=default_eps) const { + bool equals(const this_type &other, float eps = default_eps) const { for (size_t i = 0; i < N; i++) { for (size_t j = 0; j < M; j++) { if (std::abs((*this)[i][j] - other[i][j]) >= eps) { @@ -101,7 +105,7 @@ class Matrix : public std::array, M> { * Matrix multiplication */ template - Matrix operator *(const Matrix &other) const { + Matrix operator*(const Matrix &other) const { Matrix res; for (size_t i = 0; i < M; i++) { for (size_t j = 0; j < P; j++) { @@ -117,14 +121,14 @@ class Matrix : public std::array, M> { /** * Matrix-Vector multiplication */ - Matrix operator *(const Vector &vec) const { + Matrix operator*(const Vector &vec) const { return (*this) * static_cast>(vec); } /** * Matrix addition */ - this_type operator +(const this_type &other) const { + this_type operator+(const this_type &other) const { this_type res; for (size_t i = 0; i < M; i++) { for (size_t j = 0; j < N; j++) { @@ -137,7 +141,7 @@ class Matrix : public std::array, M> { /** * Matrix subtraction */ - this_type operator -(const this_type &other) const { + this_type operator-(const this_type &other) const { this_type res; for (size_t i = 0; i < M; i++) { for (size_t j = 0; j < N; j++) { @@ -150,7 +154,7 @@ class Matrix : public std::array, M> { /** * Scalar multiplication with assignment */ - void operator *=(T other) { + void operator*=(T other) { for (size_t i = 0; i < M; i++) { for (size_t j = 0; j < N; j++) { (*this)[i][j] *= other; @@ -161,7 +165,7 @@ class Matrix : public std::array, M> { /** * Scalar multiplication */ - this_type operator *(T other) const { + this_type operator*(T other) const { this_type res(*this); res *= other; return res; @@ -170,7 +174,7 @@ class Matrix : public std::array, M> { /** * Scalar division with assignment */ - void operator /=(T other) { + void operator/=(T other) { for (size_t i = 0; i < M; i++) { for (size_t j = 0; j < N; j++) { (*this)[i][j] /= other; @@ -181,7 +185,7 @@ class Matrix : public std::array, M> { /** * Scalar division */ - this_type operator /(T other) const { + this_type operator/(T other) const { this_type res(*this); res /= other; return res; @@ -191,7 +195,7 @@ class Matrix : public std::array, M> { * Transposition */ Matrix transpose() const { - Matrix res; + Matrix res; for (size_t i = 0; i < M; i++) { for (size_t j = 0; j < N; j++) { res[j][i] = (*this)[i][j]; @@ -203,8 +207,8 @@ class Matrix : public std::array, M> { /** * Conversion to Vector */ - template::type> + template ::type> Vector to_vector() const { Vector res{}; for (size_t i = 0; i < M; i++) { @@ -216,8 +220,8 @@ class Matrix : public std::array, M> { /** * Matrix trace: the sum of all diagonal entries */ - template::type> + template ::type> T trace() const { T res = 0; @@ -231,22 +235,23 @@ class Matrix : public std::array, M> { /** * Print to output stream using '<<' */ - friend std::ostream &operator <<(std::ostream &o, - const this_type &mat) { + friend std::ostream &operator<<(std::ostream &o, + const this_type &mat) { o << "("; - for (size_t j = 0; j < M-1; j++) { + for (size_t j = 0; j < M - 1; j++) { o << "("; - for (size_t i = 0; i < N-1; i++) { + for (size_t i = 0; i < N - 1; i++) { o << mat[j][i] << ",\t"; } - o << mat[j][N-1] << ")"; - o << "," << std::endl << " "; + o << mat[j][N - 1] << ")"; + o << "," << std::endl + << " "; } o << "("; - for (size_t i = 0; i < N-1; i++) { - o << mat[M-1][i] << ",\t"; + for (size_t i = 0; i < N - 1; i++) { + o << mat[M - 1][i] << ",\t"; } - o << mat[M-1][N-1] << "))"; + o << mat[M - 1][N - 1] << "))"; return o; } }; @@ -254,8 +259,8 @@ class Matrix : public std::array, M> { /** * Scalar multiplication with swapped arguments */ -template -Matrix operator *(T a, const Matrix &mat) { +template +Matrix operator*(T a, const Matrix &mat) { return mat * a; } @@ -264,24 +269,24 @@ Matrix operator *(T a, const Matrix &mat) { * because otherwise the above float-multiplication function might not match to * the template deduction. */ -template -Matrix operator *(int64_t a, const Matrix &mat) { +template +Matrix operator*(int64_t a, const Matrix &mat) { return mat * a; } -template +template using Matrix2t = Matrix<2, 2, T>; -template +template using Matrix3t = Matrix<3, 3, T>; -template +template using Matrix4t = Matrix<4, 4, T>; -template +template using Matrixf = Matrix; -template +template using Matrixd = Matrix; using Matrix2f = Matrix<2, 2, float>; @@ -292,4 +297,4 @@ using Matrix2d = Matrix<2, 2, double>; using Matrix3d = Matrix<3, 3, double>; using Matrix4d = Matrix<4, 4, double>; -} // openage::util +} // namespace openage::util diff --git a/openage/convert/processor/conversion/aoc/processor.py b/openage/convert/processor/conversion/aoc/processor.py index 01863e54c0..6f03cc3421 100644 --- a/openage/convert/processor/conversion/aoc/processor.py +++ b/openage/convert/processor/conversion/aoc/processor.py @@ -663,7 +663,7 @@ def create_building_lines(full_data_set: GenieObjectContainer) -> None: upgrade_effects = effect_bundle.get_effects(effect_type=3) - if len(upgrade_effects) < 0: + if len(upgrade_effects) == 0: continue # Search upgrade effects for the line_id diff --git a/openage/convert/tool/api_export.py b/openage/convert/tool/api_export.py index 36f85abafd..e0d14e703e 100644 --- a/openage/convert/tool/api_export.py +++ b/openage/convert/tool/api_export.py @@ -33,7 +33,7 @@ def main(args, error): del error # unused path = Union().root - path.mount(Directory(args.dir)) + path.mount(Directory(args.dir).root) export_api(path) diff --git a/openage_version b/openage_version index 4b9fcbec10..cb0c939a93 100644 --- a/openage_version +++ b/openage_version @@ -1 +1 @@ -0.5.1 +0.5.2