From 296dd91005af8ae672c2a57a399421cbd7624d19 Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 18 Oct 2023 00:33:34 +0200 Subject: [PATCH 01/95] buildsys: Fix version tag formatting not accepted by regex. --- buildsystem/DetectProjectVersion.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildsystem/DetectProjectVersion.cmake b/buildsystem/DetectProjectVersion.cmake index 8c45b1db64..67782509ec 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 --tags + COMMAND git describe --tags --long WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" RESULT_VARIABLE _RES OUTPUT_VARIABLE PROJECT_VERSION From 80eb80f5757ca92a6de65ba186b3db9578fcb21a Mon Sep 17 00:00:00 2001 From: fabiobarkoski Date: Fri, 20 Oct 2023 19:22:24 -0300 Subject: [PATCH 02/95] doc: Fix typos in converter fixed typos in the architecture and workflow files --- doc/code/converter/architecture_overview.md | 2 +- doc/code/converter/workflow.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/code/converter/architecture_overview.md b/doc/code/converter/architecture_overview.md index 9247952246..22f46d1695 100644 --- a/doc/code/converter/architecture_overview.md +++ b/doc/code/converter/architecture_overview.md @@ -30,7 +30,7 @@ Value objects are used to store primitive data or as definition of how to read p In the converter, the parsers utilize these objects to extract attributes from the original Genie Engine file formats. Extracted attributes are also saved as value objects. -Value objects are treated as *immutable*. Operations on the objects's values will therefore always return +Value objects are treated as *immutable*. Operations on the objects values will therefore always return a new object instance with the result and leave the original values as-is. ### Entity Object diff --git a/doc/code/converter/workflow.md b/doc/code/converter/workflow.md index 5ddd2db621..b4dc4ead9e 100644 --- a/doc/code/converter/workflow.md +++ b/doc/code/converter/workflow.md @@ -66,7 +66,7 @@ content can be accessed in the same way as "loose" files from the source folder. After all relevant source folders are mounted, the converter will begin the main conversion process by reading the available data. Every source file format has -its own reader that is adpated to the constraints and features of the format. +its own reader that is adapted to the constraints and features of the format. However, reading always follows this general workflow: * **Registration**: Enumerates all files with the requested format. @@ -100,7 +100,7 @@ attribute values (e.g. `"attack"`). For example, a `uint32_t` value could be used for a normal integer value or define an ID to a graphics/sound resource. Every unique value type is associated with a Python object type used for storing the attribute. -* **Output mode**: Dtetermines whether the attribute is part of the reader output +* **Output mode**: Determines whether the attribute is part of the reader output or can be skipped (e.g. `SKIP`). The Reader parses attributes one by one and stores them in a `ValueMember` subclass @@ -162,7 +162,7 @@ In general, it involves these 3 steps: 1. Check if a concept group has a certain property 2. If true, create and assign nyan API objects associated with that property -3. Map values from concept group data to the objects' member values +3. Map values from concept group data to the objects member values This is repeated for every property and for every concept group. Most values can be mapped 1-to-1, although some require additional property checks. @@ -173,7 +173,7 @@ that contains the ID and the desired target filename. In the Export stage, the source filename for the given ID is then resolved and the file is parsed, converted and saved at the target location. -At the end of the mappping stage, the resulting nyan objects are put into nyan files +At the end of the mapping stage, the resulting nyan objects are put into nyan files and -- together will the media export requests -- are organized into modpacks which are passed to the exporter. From 08c4521569f73d7329967120fc9c2ec5725b9868 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 22 Oct 2023 17:44:49 +0200 Subject: [PATCH 03/95] assets: Remove dangling refs in modpack info load. --- libopenage/assets/modpack.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libopenage/assets/modpack.cpp b/libopenage/assets/modpack.cpp index acc3865696..e2854280ed 100644 --- a/libopenage/assets/modpack.cpp +++ b/libopenage/assets/modpack.cpp @@ -15,7 +15,7 @@ ModpackInfo parse_modepack_def(const util::Path &info_file) { const auto modpack_def = toml::parse(info_file.resolve_native_path()); // info table - const toml::table &info = toml::find(modpack_def, "info"); + const toml::table info = toml::find(modpack_def, "info"); if (info.contains("name")) { def.id = info.at("name").as_string(); } @@ -63,7 +63,7 @@ ModpackInfo parse_modepack_def(const util::Path &info_file) { } // assets table - const toml::table &assets = toml::find(modpack_def, "assets"); + const toml::table assets = toml::find(modpack_def, "assets"); std::vector includes{}; for (const auto &include : assets.at("include").as_array()) { includes.push_back(include.as_string()); @@ -81,7 +81,7 @@ ModpackInfo parse_modepack_def(const util::Path &info_file) { // dependency table if (modpack_def.contains("dependency")) { - const toml::table &dependency = toml::find(modpack_def, "dependency"); + const toml::table dependency = toml::find(modpack_def, "dependency"); std::vector deps{}; if (not dependency.contains("modpacks")) { @@ -97,7 +97,7 @@ ModpackInfo parse_modepack_def(const util::Path &info_file) { // conflicts table if (modpack_def.contains("conflict")) { - const toml::table &conflict = toml::find(modpack_def, "conflict"); + const toml::table conflict = toml::find(modpack_def, "conflict"); std::vector conflicts{}; if (not conflict.contains("modpacks")) { @@ -113,7 +113,7 @@ ModpackInfo parse_modepack_def(const util::Path &info_file) { // authors table if (modpack_def.contains("authors")) { - const toml::table &authors = toml::find(modpack_def, "authors"); + const toml::table authors = toml::find(modpack_def, "authors"); std::vector author_infos{}; for (const auto &author : authors) { AuthorInfo author_info{}; @@ -143,7 +143,7 @@ ModpackInfo parse_modepack_def(const util::Path &info_file) { author_info.roles = roles; } if (author.second.contains("contact")) { - const toml::table &contact = toml::find(author.second, "contact"); + const toml::table contact = toml::find(author.second, "contact"); std::unordered_map contacts{}; for (const auto &contact_info : contact) { contacts[contact_info.first] = contact_info.second.as_string(); @@ -158,7 +158,7 @@ ModpackInfo parse_modepack_def(const util::Path &info_file) { // authorgroups table if (modpack_def.contains("authorgroups")) { - const toml::table &authorgroups = toml::find(modpack_def, "authorgroups"); + const toml::table authorgroups = toml::find(modpack_def, "authorgroups"); std::vector author_group_infos{}; for (const auto &authorgroup : authorgroups) { AuthorGroupInfo author_group_info{}; From bcacaccdfd4dc56dfb74356a0e571f35f8b7d6a8 Mon Sep 17 00:00:00 2001 From: Leet <36166244+leetfin@users.noreply.github.com> Date: Mon, 23 Oct 2023 17:29:06 -0400 Subject: [PATCH 04/95] Use gender-neutral language --- doc/ideas/gameplay.md | 4 ++-- doc/media/original-metadata.md | 2 +- doc/nyan/api_reference/reference_resistance.md | 2 +- doc/reverse_engineering/game_mechanics/formations.md | 2 +- doc/reverse_engineering/game_mechanics/monk_conversion.md | 2 +- doc/reverse_engineering/game_mechanics/selection.md | 4 ++-- .../game_mechanics/switching_villager_tasks.md | 2 +- doc/reverse_engineering/game_mechanics/town_bell.md | 2 +- doc/reverse_engineering/game_mechanics/wolves.md | 2 +- doc/reverse_engineering/networking/02-header.md | 2 +- .../networking/06-chat_message_spoofing.md | 2 +- doc/reverse_engineering/networking/08-movement.md | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/ideas/gameplay.md b/doc/ideas/gameplay.md index e4e26becd2..29e25e2532 100644 --- a/doc/ideas/gameplay.md +++ b/doc/ideas/gameplay.md @@ -144,7 +144,7 @@ A mode similar to *Trouble in Terrorist Town* and *Secret Hitler*. The game star ### Pure Battle Mode -No buildings, just units. The game generates a map and players can choose a starting position. Then they have a few minutes and a set amount of resources to select an army composition and some techs. After the first phase is over they place their units on the battlefield and have to use what they assembled to destroy their opponent. Utilizing height advantages, microing and tactical positioning contrast the strategic decisions of creating the army. The player who destroys his opponent, inflicts the most resource damage to others or holds strategic positions wins the battle. +No buildings, just units. The game generates a map and players can choose a starting position. Then they have a few minutes and a set amount of resources to select an army composition and some techs. After the first phase is over they place their units on the battlefield and have to use what they assembled to destroy their opponent. Utilizing height advantages, microing and tactical positioning contrast the strategic decisions of creating the army. The player who destroys their opponent, inflicts the most resource damage to others or holds strategic positions wins the battle. ### Micro-nerd Mode (or Mod) @@ -373,7 +373,7 @@ Relics & Kings - e.g. they can have attack bonuses for special units or economic/military bonuses - special abilities for every relic could either be generated when the map is generated or when the relic is discovered based on the actual needs of the player - so the later you go out to get the relic the more it could get useful for you, because it could be better shaped on your personal military/economy but the risk is higher, that another player was going out before you - - if a player scouts the relic first and the ability gets generated in this moment, it will be for the player who scouted it first, so he knows, that this relic could help their own economy/military alot so the player will try to fight about this relic against the enemy heavily -> new gameplay aspect + - if a player scouts the relic first and the ability gets generated in this moment, it will be for the player who scouted it first, so they know, that this relic could help their own economy/military a lot so the player will try to fight about this relic against the enemy heavily -> new gameplay aspect - Relics could have ranged attributes - idea of the devs of AoE II diff --git a/doc/media/original-metadata.md b/doc/media/original-metadata.md index 5e5540fe44..b29583b44a 100644 --- a/doc/media/original-metadata.md +++ b/doc/media/original-metadata.md @@ -2,7 +2,7 @@ Original Metadata ================= All data relevant for the game (e.g. how much costs building the castle? -What cultures exist? Can my priest overclock his "Wololo?") +What cultures exist? Can my priest overclock their "Wololo?") are stored in a binary format in the file `empires2_x1_p1.dat`. The format is described in the [huge struct definition](/openage/convert/value_object/read/media/datfile/empiresdat.py). diff --git a/doc/nyan/api_reference/reference_resistance.md b/doc/nyan/api_reference/reference_resistance.md index e38f838119..1a0b7a5344 100644 --- a/doc/nyan/api_reference/reference_resistance.md +++ b/doc/nyan/api_reference/reference_resistance.md @@ -317,7 +317,7 @@ Resistance to the `MakeHarvestable` effect. Resource spot that should be made harvestable. Effects of type `effect.discrete.make_harvestable.type.MakeHarvestable` are matched to this resistance if they store the same `ResourceSpot` object in their `resource_spot` member. Additionally, the target needs to have a `Harvestable` ability that contains the resource spot. **resist_condition** -Condition which must he fulfilled to make the resource spot harvestable. +Condition which they must fulfill to make the resource spot harvestable. ## resistance.discrete.send_to_container.type.SendToContainer diff --git a/doc/reverse_engineering/game_mechanics/formations.md b/doc/reverse_engineering/game_mechanics/formations.md index dd39371ccd..b93de426e1 100644 --- a/doc/reverse_engineering/game_mechanics/formations.md +++ b/doc/reverse_engineering/game_mechanics/formations.md @@ -123,7 +123,7 @@ The same rules apply, if more than two unit types are used. We will now have a l .............. ``` -Which unit type is sorted into the line first depends on the order in which the player selected the unit types (or how they are ordered inside the selection queue). In the first example of this section, the player selected the archers first and added the skirmishers to his selection. The second and above example would be the result of selecting longbowman first, archers second, skirmishers third and throwing axeman last. +Which unit type is sorted into the line first depends on the order in which the player selected the unit types (or how they are ordered inside the selection queue). In the first example of this section, the player selected the archers first and added the skirmishers to their selection. The second and above example would be the result of selecting longbowman first, archers second, skirmishers third and throwing axeman last. #### Distance Between Units diff --git a/doc/reverse_engineering/game_mechanics/monk_conversion.md b/doc/reverse_engineering/game_mechanics/monk_conversion.md index 583cb61ce1..cf101a942f 100644 --- a/doc/reverse_engineering/game_mechanics/monk_conversion.md +++ b/doc/reverse_engineering/game_mechanics/monk_conversion.md @@ -32,5 +32,5 @@ Units inside a building are not converted and will ungarrison. The same is true [Source](https://www.youtube.com/watch?v=_gjpDWfzaM0) * If a converted unit is "replaced" by the game, e.g. a villager changing to a farmer, the stats are not frozen anymore. -* Converted siege units are only frozen in tech level until the new owner researches a technology that changes the units stats, e.g. chemistry. As soon as the research finishes, the units are replaced with ones that are on the same tech level as the player. Weirdly enough, Onagers are replaced if the player researches Heavy Scorpions but not if he researches Siege/Capped Rams. +* Converted siege units are only frozen in tech level until the new owner researches a technology that changes the units stats, e.g. chemistry. As soon as the research finishes, the units are replaced with ones that are on the same tech level as the player. Weirdly enough, Onagers are replaced if the player researches Heavy Scorpions but not if they research Siege/Capped Rams. * The flaming projectile caused by chemistry research is tied to the tech level of the owner but the +1 damage is kept, if the unit is converted. diff --git a/doc/reverse_engineering/game_mechanics/selection.md b/doc/reverse_engineering/game_mechanics/selection.md index de08156fff..0016ed4ea4 100644 --- a/doc/reverse_engineering/game_mechanics/selection.md +++ b/doc/reverse_engineering/game_mechanics/selection.md @@ -8,7 +8,7 @@ This documents shows the methods of selecting and deselecting units. The player doesn't have to click directly on the sprite of a unit because there is a tolerance factor involved. The tolerance factor is roughly `1 unit width` horizontally and `1 unit height` vertically measured from the center of the unit. This means that clicking in the general area of a unit will be accepted as a valid selection most of the time. -If two units' areas of tolerance overlap, the unit that is in the front seems to be preferred, but clicking directly on the sprite of one of the player's own units will select the unit that is pointed at. When the area of tolerance overlaps with an enemy (or ally) unit, the unit of the player will always be preferred, even if he clicks directly on the sprite of the enemy unit. +If two units' areas of tolerance overlap, the unit that is in the front seems to be preferred, but clicking directly on the sprite of one of the player's own units will select the unit that is pointed at. When the area of tolerance overlaps with an enemy (or ally) unit, the unit of the player will always be preferred, even if they click directly on the sprite of the enemy unit. Relics and animals also have an area of tolerance regarding selection, while resource spots like trees, bushes, gold/stone mines as well as buildings don't. @@ -25,7 +25,7 @@ All of these have a specific purpose and will now be explained further. ### Selection Box -The selection box is the easiest way to select multiple units of any type in AoE2. When the player draws the box around the units he wants to select, the units inside the box will be added to the selection queue, **going from the top to the bottom of the box** until the limit of 40 units is reached. +The selection box is the easiest way to select multiple units of any type in AoE2. When the player draws the box around the units they want to select, the units inside the box will be added to the selection queue, **going from the top to the bottom of the box** until the limit of 40 units is reached. The tolerance factor is also used here, which can result in units which are slightly outside of the selection box to be selected. diff --git a/doc/reverse_engineering/game_mechanics/switching_villager_tasks.md b/doc/reverse_engineering/game_mechanics/switching_villager_tasks.md index 8e1db4838f..b82c84ae69 100644 --- a/doc/reverse_engineering/game_mechanics/switching_villager_tasks.md +++ b/doc/reverse_engineering/game_mechanics/switching_villager_tasks.md @@ -22,4 +22,4 @@ Note: This only happens if the builder was actively working on the construction ## Weird AoE2 Quirks -* If the cheat `aegis` (villagers gather instantly from a resource) is used in a game and the role of a villager changes from "hunter" to "shepard", he will dump all of the resources he is carrying "into" the sheep. +* If the cheat `aegis` (villagers gather instantly from a resource) is used in a game and the role of a villager changes from "hunter" to "shepard", they will dump all of the resources they are carrying "into" the sheep. diff --git a/doc/reverse_engineering/game_mechanics/town_bell.md b/doc/reverse_engineering/game_mechanics/town_bell.md index c3ee341498..c8748b061c 100644 --- a/doc/reverse_engineering/game_mechanics/town_bell.md +++ b/doc/reverse_engineering/game_mechanics/town_bell.md @@ -48,4 +48,4 @@ As soon as the town bell is triggered, the algorithm searches for villagers that In the next step, the algorithm tries to find the nearest garrison for a villager by calculating the distances between the villager and all buildings on the second list. The closest distance calculated and the corresponding garrison are then saved. Afterwards the villager is put into a third list, which is sorted by the *closest distance to any garrison*. This step is repeated for every villager. -Last but not least, the villagers are assigned to a garrison. Since the third list is sorted by closest distance, villagers that are the nearest to a building are guaranteed to get a place, which satisfies the condition that towers prefer the villagers close to them. If the villager is assigned to a building which is already full, the algorithm recalculates the distances to other garrisons and sorts him back into the list. +Last but not least, the villagers are assigned to a garrison. Since the third list is sorted by closest distance, villagers that are the nearest to a building are guaranteed to get a place, which satisfies the condition that towers prefer the villagers close to them. If the villager is assigned to a building which is already full, the algorithm recalculates the distances to other garrisons and sorts them back into the list. diff --git a/doc/reverse_engineering/game_mechanics/wolves.md b/doc/reverse_engineering/game_mechanics/wolves.md index 667a219956..9c467a1cd4 100644 --- a/doc/reverse_engineering/game_mechanics/wolves.md +++ b/doc/reverse_engineering/game_mechanics/wolves.md @@ -14,7 +14,7 @@ Line of sight depends on the selected difficulty of the game. Hard 12 tiles Hardest 12 tiles -As soon as a unit moves into the LOS of a wolf, he will chase and attack the unit. However some unit types are ignored, including: +As soon as a unit moves into the LOS of a wolf, they will chase and attack the unit. However some unit types are ignored, including: * King * Trade Cart diff --git a/doc/reverse_engineering/networking/02-header.md b/doc/reverse_engineering/networking/02-header.md index 4e7e57e67b..a361f5a4e4 100644 --- a/doc/reverse_engineering/networking/02-header.md +++ b/doc/reverse_engineering/networking/02-header.md @@ -20,7 +20,7 @@ end ## Description *:network_source_id*
-The *:network_id* of the person who sent the packet. A *:network_id* is different for every game, but is not generated randomly for all players. When joining the lobby, every player gets assigned `last_network_id - 2` as his own *:network_id* where *last_network_id* is the ID of the person who joined before him. +The *:network_id* of the person who sent the packet. A *:network_id* is different for every game, but is not generated randomly for all players. When joining the lobby, every player gets assigned `last_network_id - 2` as their own *:network_id* where *last_network_id* is the ID of the person who joined before them. *:network_dest_id*
The *:network_id* of the person who should receive the packet. Is only used for sync packets and remains unused for most commands. diff --git a/doc/reverse_engineering/networking/06-chat_message_spoofing.md b/doc/reverse_engineering/networking/06-chat_message_spoofing.md index 4c4d15092c..75d0516b08 100644 --- a/doc/reverse_engineering/networking/06-chat_message_spoofing.md +++ b/doc/reverse_engineering/networking/06-chat_message_spoofing.md @@ -23,7 +23,7 @@ To construct a message the following parameters are needed: * Player number of the spoofed sender * Player number of the receiver(s) -An attacker that is in game with other players will have no problems getting to know the player numbers. As the game is constantly synced, he can easily get the value for *:communication_turn*. +An attacker that is in game with other players will have no problems getting to know the player numbers. As the game is constantly synced, they can easily get the value for *:communication_turn*. Deriving the valid Sender ID of the receiving player is more difficult and depends on the attacker's ability to capture network traffic. The easiest way to discover all Player IDs is by capturing a few packets of normal gameplay beforehand. The IDs of Players 1-8 have a fixed byte position in the data stream. diff --git a/doc/reverse_engineering/networking/08-movement.md b/doc/reverse_engineering/networking/08-movement.md index 4909d82413..6c52684e60 100644 --- a/doc/reverse_engineering/networking/08-movement.md +++ b/doc/reverse_engineering/networking/08-movement.md @@ -74,7 +74,7 @@ end Always has the value `0x03`. *:player_id*
-The ID of the player who moves his units (`0x01` - `0x08`). +The ID of the player who moves their units (`0x01` - `0x08`). *:zero*
The two bytes following the *:player_id* are unused. From db6fa9a8e6447da751636983f304bf1f6a62f46a Mon Sep 17 00:00:00 2001 From: Leet <36166244+leetfin@users.noreply.github.com> Date: Tue, 24 Oct 2023 11:40:00 -0400 Subject: [PATCH 05/95] Fix typo --- doc/nyan/api_reference/reference_resistance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/nyan/api_reference/reference_resistance.md b/doc/nyan/api_reference/reference_resistance.md index 1a0b7a5344..61a2aa06cb 100644 --- a/doc/nyan/api_reference/reference_resistance.md +++ b/doc/nyan/api_reference/reference_resistance.md @@ -317,7 +317,7 @@ Resistance to the `MakeHarvestable` effect. Resource spot that should be made harvestable. Effects of type `effect.discrete.make_harvestable.type.MakeHarvestable` are matched to this resistance if they store the same `ResourceSpot` object in their `resource_spot` member. Additionally, the target needs to have a `Harvestable` ability that contains the resource spot. **resist_condition** -Condition which they must fulfill to make the resource spot harvestable. +Condition which must be fulfilled to make the resource spot harvestable. ## resistance.discrete.send_to_container.type.SendToContainer From 682f52487a7d5276dcee3b77d6c6d477e7650f46 Mon Sep 17 00:00:00 2001 From: zoli111 Date: Sat, 28 Oct 2023 20:55:44 +0200 Subject: [PATCH 06/95] Fix typos --- openage/convert/entity_object/conversion/ror/genie_unit.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openage/convert/entity_object/conversion/ror/genie_unit.py b/openage/convert/entity_object/conversion/ror/genie_unit.py index 86e6b4986c..c2fe46267f 100644 --- a/openage/convert/entity_object/conversion/ror/genie_unit.py +++ b/openage/convert/entity_object/conversion/ror/genie_unit.py @@ -50,7 +50,7 @@ def __init__( def is_garrison(self, civ_id: int = -1) -> bool: """ - Only transport shis can garrison in RoR. + Only transport ships can garrison in RoR. :returns: True if the unit has the unload command (ID: 12). """ @@ -229,7 +229,7 @@ def __init__( def is_garrison(self, civ_id: int = -1) -> bool: """ - Only transport shis can garrison in RoR. + Only transport ships can garrison in RoR. :returns: True if the unit has the unload command (ID: 12). """ From 3bd0674baa59ef268473b498ab55aec0c157c878 Mon Sep 17 00:00:00 2001 From: Ashhar-24 Date: Wed, 1 Nov 2023 02:21:24 +0530 Subject: [PATCH 07/95] util: Temporary file/directory support. --- copying.md | 1 + openage/util/fslike/path.py | 53 +++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/copying.md b/copying.md index 310076a011..e1df2d97bb 100644 --- a/copying.md +++ b/copying.md @@ -148,6 +148,7 @@ _the openage authors_ are: | Zoltán Ács | zoli111 | acszoltan111 à gmail dawt com | | Trevor Slocum | tslocum | trevor à rocket9labs dawt com | | Munawar Hafiz | munahaf | munawar dawt hafiz à gmail dawt com | +| Md Ashhar | ashhar | mdashhar01 à 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/openage/util/fslike/path.py b/openage/util/fslike/path.py index f69479360e..7532ec3e0d 100644 --- a/openage/util/fslike/path.py +++ b/openage/util/fslike/path.py @@ -4,9 +4,12 @@ Provides Path, which is analogous to pathlib.Path, and the type of FSLikeObject.root. """ +from typing import NoReturn from io import UnsupportedOperation, TextIOWrapper -from typing import NoReturn +import os +import pathlib +import tempfile class Path: @@ -32,7 +35,7 @@ class Path: # lower. # pylint: disable=too-many-public-methods - def __init__(self, fsobj, parts=None): + def __init__(self, fsobj, parts: str | bytes | bytearray | list | tuple = None): if isinstance(parts, str): parts = parts.encode() @@ -63,6 +66,9 @@ def __init__(self, fsobj, parts=None): self.fsobj = fsobj + # Set to True by create_temp_file or create_temp_dir + self.is_temp: bool = False + # use tuple instead of list to prevent accidential modification self.parts = tuple(result) @@ -330,3 +336,46 @@ def mount(self, pathobj, priority=0) -> NoReturn: # pylint: disable=no-self-use,unused-argument # TODO: https://github.com/PyCQA/pylint/issues/2329 raise PermissionError("Do not call mount on Path instances!") + + @staticmethod + def get_temp_file(): + """ + Creates a temporary file. + """ + temp_fd, temp_file = tempfile.mkstemp() + + # Close the file descriptor to release resources + os.close(temp_fd) + + # Wrap the temporary file path in a Path object and return it + path = Path(pathlib.Path(temp_file)) + path.is_temp = True + + return path + + @staticmethod + def get_temp_dir(): + """ + Creates a temporary directory. + """ + # Create a temporary directory using tempfile.mkdtemp + temp_dir = tempfile.mkdtemp() + + # Wrap the temporary directory path in a Path object and return it + path = Path(pathlib.Path(temp_dir)) + path.is_temp = True + + return path + + def __del__(self): + """ + Destructor used for temp files and directories. + """ + if self.is_temp: + # Cleanup temp file + if self.exists(): + if self.is_file(): + self.unlink() + + elif self.is_dir(): + self.removerecursive() From 2e10795d7b3649d0870efb60196abc5649555a35 Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 1 Nov 2023 01:42:24 +0100 Subject: [PATCH 08/95] util: Remove __del__ because it doesn't work as destructor. --- openage/util/fslike/path.py | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/openage/util/fslike/path.py b/openage/util/fslike/path.py index 7532ec3e0d..c34a5d6a6c 100644 --- a/openage/util/fslike/path.py +++ b/openage/util/fslike/path.py @@ -366,16 +366,3 @@ def get_temp_dir(): path.is_temp = True return path - - def __del__(self): - """ - Destructor used for temp files and directories. - """ - if self.is_temp: - # Cleanup temp file - if self.exists(): - if self.is_file(): - self.unlink() - - elif self.is_dir(): - self.removerecursive() From fdba30869b37fe56f84dc43e88417fc932a9c66b Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 1 Nov 2023 03:40:37 +0100 Subject: [PATCH 09/95] util: Append mode for paths/unions. --- openage/util/fslike/path.py | 4 ++++ openage/util/fslike/union.py | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/openage/util/fslike/path.py b/openage/util/fslike/path.py index c34a5d6a6c..422b9f176b 100644 --- a/openage/util/fslike/path.py +++ b/openage/util/fslike/path.py @@ -149,6 +149,10 @@ def open_w(self): """ open with mode='wb' """ return self.fsobj.open_w(self.parts) + def open_a(self): + """ open with mode='ab' """ + return self.fsobj.open_a(self.parts) + def _get_native_path(self): """ return the native path (usable by your kernel) of this path, diff --git a/openage/util/fslike/union.py b/openage/util/fslike/union.py index eb28129d01..7b2ca8a8f2 100644 --- a/openage/util/fslike/union.py +++ b/openage/util/fslike/union.py @@ -116,6 +116,14 @@ def open_w(self, parts): raise UnsupportedOperation( "not writable: " + b'/'.join(parts).decode(errors='replace')) + def open_a(self, parts): + for path in self.candidate_paths(parts): + if path.writable(): + return path.open_a() + + raise UnsupportedOperation( + "not appendable: " + b'/'.join(parts).decode(errors='replace')) + def resolve_r(self, parts): for path in self.candidate_paths(parts): if path.is_file() or path.is_dir(): From 6c48b8437a9fcfe7ff87b5adc84260ec450ee8ec Mon Sep 17 00:00:00 2001 From: fabiobarkoski Date: Sat, 28 Oct 2023 00:46:53 -0300 Subject: [PATCH 10/95] Add condition for SLD files added condition to now supported SLD files --- openage/convert/processor/export/media_exporter.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/openage/convert/processor/export/media_exporter.py b/openage/convert/processor/export/media_exporter.py index 8984cbd4bf..1bb6c4faa0 100644 --- a/openage/convert/processor/export/media_exporter.py +++ b/openage/convert/processor/export/media_exporter.py @@ -462,6 +462,10 @@ def _get_media_cache( from ...value_object.read.media.smx import SMX image = SMX(media_file.read()) + elif source_file.suffix.lower() == ".sld": + from ...value_object.read.media.sld import SLD + image = SLD(media_file.read()) + from .texture_merge import merge_frames texture = Texture(image, palettes) merge_frames(texture) From 40c5b7e4fbd10dd7f7334b281e55cc376317c430 Mon Sep 17 00:00:00 2001 From: fabiobarkoski Date: Sat, 28 Oct 2023 00:48:48 -0300 Subject: [PATCH 11/95] Create debug output for execution time per stage and not found sounds created debug output for sounds not found on exporting stage and for execution time for each stage --- copying.md | 1 + .../processor/export/media_exporter.py | 12 +++++ openage/convert/service/debug_info.py | 44 +++++++++++++++++++ openage/convert/tool/driver.py | 20 ++++++++- 4 files changed, 75 insertions(+), 2 deletions(-) diff --git a/copying.md b/copying.md index e1df2d97bb..b524367fb0 100644 --- a/copying.md +++ b/copying.md @@ -149,6 +149,7 @@ _the openage authors_ are: | Trevor Slocum | tslocum | trevor à rocket9labs dawt com | | Munawar Hafiz | munahaf | munawar dawt hafiz à gmail dawt com | | Md Ashhar | ashhar | mdashhar01 à gmail dawt com | +| Fábio Barkoski | fabiobarkoski | fabiobarkoskii à 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/openage/convert/processor/export/media_exporter.py b/openage/convert/processor/export/media_exporter.py index 1bb6c4faa0..7005e262c9 100644 --- a/openage/convert/processor/export/media_exporter.py +++ b/openage/convert/processor/export/media_exporter.py @@ -80,6 +80,8 @@ def export( info("-- Exporting graphics files...") elif media_type is MediaType.SOUNDS: + kwargs["loglevel"] = args.debug_info + kwargs["debugdir"] = args.debugdir export_func = MediaExporter._export_sound info("-- Exporting sound files...") @@ -225,6 +227,10 @@ def _export_graphics( from ...value_object.read.media.sld import SLD image = SLD(media_file.read()) + else: + raise SyntaxError(f"Source file {source_file.name} has an unrecognized extension: " + f"{source_file.suffix.lower()}") + packer_cache = None compr_cache = None if cache_info: @@ -284,6 +290,7 @@ def _export_sound( export_request: MediaExportRequest, sourcedir: Path, exportdir: Path, + **kwargs ) -> None: """ Convert and export a sound file. @@ -308,6 +315,7 @@ def _export_sound( else: # TODO: Filter files that do not exist out sooner + debug_info.debug_not_found_sounds(kwargs["debugdir"], kwargs["loglevel"], source_file) return from ...service.export.opus.opusenc import encode @@ -466,6 +474,10 @@ def _get_media_cache( from ...value_object.read.media.sld import SLD image = SLD(media_file.read()) + else: + raise SyntaxError(f"Source file {source_file.name} has an unrecognized extension: " + f"{source_file.suffix.lower()}") + from .texture_merge import merge_frames texture = Texture(image, palettes) merge_frames(texture) diff --git a/openage/convert/service/debug_info.py b/openage/convert/service/debug_info.py index 50ffd72bc1..39c8b92d3d 100644 --- a/openage/convert/service/debug_info.py +++ b/openage/convert/service/debug_info.py @@ -677,3 +677,47 @@ def debug_media_cache( with logfile.open("w") as log: log.write(logtext) + + +def debug_execution_time(debugdir: Directory, loglevel: int, stages_time: dict[str, float]) -> None: + """ + Create debug output for execution time for each stage + + :param debugdir: Output directory for the debug info. + :type debugdir: Directory + :param loglevel: Determines how detailed the output is. + :type loglevel: int + :param stages_time: Dict with execution time for each stage. + :type stages_time: dict + """ + if loglevel < 1: + return + + logfile = debugdir["execution_time"] + logtext = "".join(f"{k}: {v}\n" for k, v in stages_time.items()) + + with logfile.open("w") as log: + log.write(logtext) + + +def debug_not_found_sounds(debugdir: Directory, loglevel: int, sound: Path) -> None: + """ + Create debug output for sounds not found + + :param debugdir: Output directory for the debug info. + :type debugdir: Directory + :param loglevel: Determines how detailed the output is. + :type loglevel: int + :param sound: Sound object with path and name values. + :type sound: Path + """ + if loglevel < 6: + return + + logfile = debugdir.joinpath("export/not_found_sounds")[sound.stem] + + path = [part.decode() for part in sound.parts] + logtext = f"name: {sound.name}\npath: {'/'.join(path)}" + + with logfile.open("w") as log: + log.write(logtext) diff --git a/openage/convert/tool/driver.py b/openage/convert/tool/driver.py index a1b8bbfddf..d7d664d16e 100644 --- a/openage/convert/tool/driver.py +++ b/openage/convert/tool/driver.py @@ -8,13 +8,14 @@ """ from __future__ import annotations import typing +import timeit from ...log import info, dbg from ..processor.export.modpack_exporter import ModpackExporter from ..service.debug_info import debug_gamedata_format from ..service.debug_info import debug_string_resources, \ - debug_registered_graphics, debug_modpack + debug_registered_graphics, debug_modpack, debug_execution_time from ..service.init.changelog import (ASSET_VERSION) from ..service.read.gamedata import get_gamespec from ..service.read.palette import get_palettes @@ -64,7 +65,7 @@ def convert_metadata(args: Namespace) -> None: gamedata_path = args.targetdir.joinpath('gamedata') if gamedata_path.exists(): gamedata_path.removerecursive() - + read_start = timeit.default_timer() # Read .dat debug_gamedata_format(args.debugdir, args.debug_info, args.game_version) gamespec = get_gamespec(args.srcdir, args.game_version, not args.flag("no_pickle_cache")) @@ -84,16 +85,31 @@ def convert_metadata(args: Namespace) -> None: existing_graphics = get_existing_graphics(args) debug_registered_graphics(args.debugdir, args.debug_info, existing_graphics) + read_end = timeit.default_timer() + + conversion_start = timeit.default_timer() # Convert modpacks = args.converter.convert(gamespec, args, string_resources, existing_graphics) + conversion_end = timeit.default_timer() + + export_start = timeit.default_timer() for modpack in modpacks: ModpackExporter.export(modpack, args) debug_modpack(args.debugdir, args.debug_info, modpack) + export_end = timeit.default_timer() + + stages_time = { + "read": read_end - read_start, + "convert": conversion_end - conversion_start, + "export": export_end - export_start, + } + debug_execution_time(args.debugdir, args.debug_info, stages_time) + # TODO: player palettes # player_palette = PlayerColorTable(palette) # data_formatter.add_data(player_palette.dump("player_palette")) From d900aabbbe759c8a695002b8a4a651a7113cc7f2 Mon Sep 17 00:00:00 2001 From: heinezen Date: Thu, 2 Nov 2023 23:24:57 +0100 Subject: [PATCH 12/95] renderer: Set format correctly on Wayland. --- libopenage/renderer/opengl/context.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libopenage/renderer/opengl/context.cpp b/libopenage/renderer/opengl/context.cpp index d65fe4aae1..91e2fb431b 100644 --- a/libopenage/renderer/opengl/context.cpp +++ b/libopenage/renderer/opengl/context.cpp @@ -29,10 +29,11 @@ gl_context_spec GlContext::find_spec() { for (size_t i_ver = 0; i_ver < gl_versions.size(); ++i_ver) { QOpenGLContext test_context{}; - auto tf = test_format; + test_format.setMajorVersion(gl_versions[i_ver].first); test_format.setMinorVersion(gl_versions[i_ver].second); + test_context.setFormat(test_format); test_context.create(); if (!test_context.isValid()) { @@ -49,6 +50,7 @@ gl_context_spec GlContext::find_spec() { } QOpenGLContext test_context{}; + test_context.setFormat(test_format); test_context.create(); if (!test_context.isValid()) { throw Error(MSG(err) << "Failed to create OpenGL context which previously succeeded. This should not happen!"); From 388511610aa4c706f2211588b7448029ad3ca0d9 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 4 Nov 2023 03:27:52 +0100 Subject: [PATCH 13/95] renderer: Dynamically fetch default fbo. --- libopenage/renderer/opengl/context.cpp | 4 + libopenage/renderer/opengl/context.h | 11 +++ libopenage/renderer/opengl/framebuffer.cpp | 32 +++++++- libopenage/renderer/opengl/framebuffer.h | 73 +++++++++++++---- libopenage/renderer/opengl/render_target.cpp | 34 ++++---- libopenage/renderer/opengl/render_target.h | 82 +++++++++++++++----- libopenage/renderer/opengl/renderer.cpp | 4 +- 7 files changed, 181 insertions(+), 59 deletions(-) diff --git a/libopenage/renderer/opengl/context.cpp b/libopenage/renderer/opengl/context.cpp index 91e2fb431b..e02992d25e 100644 --- a/libopenage/renderer/opengl/context.cpp +++ b/libopenage/renderer/opengl/context.cpp @@ -156,6 +156,10 @@ std::shared_ptr GlContext::get_raw_context() const { return this->gl_context; } +GLuint GlContext::get_default_framebuffer_id() { + return this->gl_context->defaultFramebufferObject(); +} + gl_context_spec GlContext::get_specs() const { return this->specs; } diff --git a/libopenage/renderer/opengl/context.h b/libopenage/renderer/opengl/context.h index 68e3e39c1f..ba5459ed5f 100644 --- a/libopenage/renderer/opengl/context.h +++ b/libopenage/renderer/opengl/context.h @@ -66,6 +66,17 @@ class GlContext { */ std::shared_ptr get_raw_context() const; + /** + * Get the ID of the default framebuffer used for displaying to + * the window. + * + * This value may change on every frame, so it should be called every + * time the default framebuffer is bound. + * + * @return ID of the default (display) framebuffer. + */ + unsigned int get_default_framebuffer_id(); + /** * Get the capabilities of this context. */ diff --git a/libopenage/renderer/opengl/framebuffer.cpp b/libopenage/renderer/opengl/framebuffer.cpp index e9862ff7ce..477c628f90 100644 --- a/libopenage/renderer/opengl/framebuffer.cpp +++ b/libopenage/renderer/opengl/framebuffer.cpp @@ -2,17 +2,25 @@ #include "framebuffer.h" +#include "renderer/opengl/context.h" #include "renderer/opengl/texture.h" namespace openage::renderer::opengl { +GlFramebuffer::GlFramebuffer(const std::shared_ptr &context) : + GlSimpleObject(context, + [](GLuint /*handle*/) {}), + type{gl_framebuffer_t::display} { +} + // TODO the validity of this object is contingent // on its texture existing. use shared_ptr? GlFramebuffer::GlFramebuffer(const std::shared_ptr &context, std::vector> const &textures) : GlSimpleObject(context, - [](GLuint handle) { glDeleteFramebuffers(1, &handle); }) { + [](GLuint handle) { glDeleteFramebuffers(1, &handle); }), + type{gl_framebuffer_t::textures} { GLuint handle; glGenFramebuffers(1, &handle); this->handle = handle; @@ -21,6 +29,10 @@ GlFramebuffer::GlFramebuffer(const std::shared_ptr &context, std::vector drawBuffers; + if (textures.empty()) { + throw Error{ERR << "At least 1 texture must be assigned to texture framebuffer."}; + } + size_t colorTextureCount = 0; for (auto const &texture : textures) { // TODO figure out attachment points from pixel formats @@ -41,12 +53,26 @@ GlFramebuffer::GlFramebuffer(const std::shared_ptr &context, } } +gl_framebuffer_t GlFramebuffer::get_type() const { + return this->type; +} + void GlFramebuffer::bind_read() const { - glBindFramebuffer(GL_READ_FRAMEBUFFER, *this->handle); + if (this->type == gl_framebuffer_t::textures) { + glBindFramebuffer(GL_READ_FRAMEBUFFER, *this->handle); + } + else { + glBindFramebuffer(GL_READ_FRAMEBUFFER, this->context->get_default_framebuffer_id()); + } } void GlFramebuffer::bind_write() const { - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, *this->handle); + if (this->type == gl_framebuffer_t::textures) { + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, *this->handle); + } + else { + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, this->context->get_default_framebuffer_id()); + } } } // namespace openage::renderer::opengl diff --git a/libopenage/renderer/opengl/framebuffer.h b/libopenage/renderer/opengl/framebuffer.h index ccd544f57e..cd37ccb76a 100644 --- a/libopenage/renderer/opengl/framebuffer.h +++ b/libopenage/renderer/opengl/framebuffer.h @@ -7,30 +7,75 @@ #include "renderer/opengl/simple_object.h" -namespace openage { -namespace renderer { -namespace opengl { +namespace openage::renderer::opengl { class GlTexture2d; -/// Represents an OpenGL Framebuffer Object. -/// It is a collection of bitmap targets that can be drawn into -/// and read from. +/** + * The type of OpenGL framebuffer. + */ +enum class gl_framebuffer_t { + /** + * The actual window. This is visible to the user after swapping front and back buffers. + */ + display, + /** + * A bunch of textures. These can be color texture, depth textures, etc. + */ + textures, +}; + +/** + * Represents an OpenGL Framebuffer Object. + * It is a collection of bitmap targets that can be drawn into + * and read from. + */ class GlFramebuffer final : public GlSimpleObject { public: - /// Construct a framebuffer pointing at the given textures. - /// Texture are attached to points specific to their pixel format, - /// e.g. a depth texture will be set as the depth target. + /** + * Construct a framebuffer pointing at the default framebuffer - the window. + * + * Drawing into this framebuffer draws onto the screen. + * + * @param context OpenGL context used for drawing. + */ + GlFramebuffer(const std::shared_ptr &context); + + /** + * Construct a framebuffer pointing at the given textures. + * + * Texture are attached to points specific to their pixel format, + * e.g. a depth texture will be set as the depth target. + * + * @param context OpenGL context used for drawing. + * @param textures Textures targeted by the framebuffer. They are automatically + * attached to the correct attachement points depending on their type. + */ GlFramebuffer(const std::shared_ptr &context, std::vector> const &textures); - /// Bind this framebuffer to GL_READ_FRAMEBUFFER. + /** + * Get the type of this framebuffer. + * + * @return Framebuffer type. + */ + gl_framebuffer_t get_type() const; + + /** + * Bind this framebuffer to \p GL_READ_FRAMEBUFFER. + */ void bind_read() const; - /// Bind this framebuffer to GL_DRAW_FRAMEBUFFER. + /** + * Bind this framebuffer to \p GL_DRAW_FRAMEBUFFER. + */ void bind_write() const; + +private: + /** + * Type of this framebuffer. + */ + gl_framebuffer_t type; }; -} // namespace opengl -} // namespace renderer -} // namespace openage +} // namespace openage::renderer::opengl diff --git a/libopenage/renderer/opengl/render_target.cpp b/libopenage/renderer/opengl/render_target.cpp index b2f844d83b..c0da3a22a8 100644 --- a/libopenage/renderer/opengl/render_target.cpp +++ b/libopenage/renderer/opengl/render_target.cpp @@ -2,17 +2,20 @@ #include "render_target.h" +#include "error/error.h" + #include "renderer/opengl/texture.h" namespace openage::renderer::opengl { -GlRenderTarget::GlRenderTarget(size_t width, size_t height) : - type(gl_render_target_t::display), - size(width, height) {} +GlRenderTarget::GlRenderTarget(const std::shared_ptr &context, size_t width, size_t height) : + type(gl_render_target_t::framebuffer), + size(width, height), + framebuffer(context) {} GlRenderTarget::GlRenderTarget(const std::shared_ptr &context, const std::vector> &textures) : - type(gl_render_target_t::textures), + type(gl_render_target_t::framebuffer), framebuffer({context, textures}), textures(textures) { // TODO: Check if the textures are all the same size @@ -21,7 +24,7 @@ GlRenderTarget::GlRenderTarget(const std::shared_ptr &context, std::vector> GlRenderTarget::get_texture_targets() { std::vector> textures{}; - if (this->type == gl_render_target_t::display) { + if (this->framebuffer->get_type() == gl_framebuffer_t::display) { return textures; } //else upcast pointers @@ -33,8 +36,9 @@ std::vector> GlRenderTarget::get_texture_targets() { } void GlRenderTarget::resize(size_t width, size_t height) { - if (this->type != gl_render_target_t::display) { - throw Error{ERR << "Texture render target should not be resized. Create a new one instead."}; + if (this->framebuffer->get_type() == gl_framebuffer_t::textures) { + throw Error{ERR << "Render target with textured framebuffer should not be resized. " + << "Create a new one instead."}; } this->size = std::make_pair(width, height); @@ -46,23 +50,11 @@ void GlRenderTarget::bind_write() const { // different sizes glViewport(0, 0, size.first, size.second); - if (this->type == gl_render_target_t::textures) { - this->framebuffer->bind_write(); - } - else { - // 0 is the default, window framebuffer - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); - } + this->framebuffer->bind_write(); } void GlRenderTarget::bind_read() const { - if (this->type == gl_render_target_t::textures) { - this->framebuffer->bind_read(); - } - else { - // 0 is the default, window framebuffer - glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - } + this->framebuffer->bind_read(); } } // namespace openage::renderer::opengl diff --git a/libopenage/renderer/opengl/render_target.h b/libopenage/renderer/opengl/render_target.h index 546ac1e8ca..5246b03cb7 100644 --- a/libopenage/renderer/opengl/render_target.h +++ b/libopenage/renderer/opengl/render_target.h @@ -17,50 +17,92 @@ namespace opengl { class GlTexture2d; -/// The type of OpenGL render target +/** + * The type of OpenGL render target. + */ enum class gl_render_target_t { - /// The actual window. This is visible to the user after swapping front and back buffers - display, - /// A bunch of textures - textures, + /** + * Render into a framebuffer. + */ + framebuffer, // TODO renderbuffers mixed with textures }; -/// Represents an OpenGL target that can be drawn into. -/// It can be either a framebuffer or the display (the window). +/** + * Represents an OpenGL target that can be drawn into. + * It can be either a framebuffer with texture attachements or the display (the window). + */ class GlRenderTarget final : public RenderTarget { public: - /// Construct a render target pointed at the default framebuffer - the window. - GlRenderTarget(size_t width, size_t height); - - /// Construct a render target pointing at the given textures. - /// Texture are attached to points specific to their pixel format, - /// e.g. a depth texture will be set as the depth target. + /** + * Construct a render target pointed at the default framebuffer - the window. + * + * @param context OpenGL context used for drawing. + * @param width Current width of the window. + * @param height Current height of the window. + */ + GlRenderTarget(const std::shared_ptr &context, + size_t width, + size_t height); + + /** + * Construct a render target pointing at the given textures. + * Texture are attached to points specific to their pixel format, + * e.g. a depth texture will be set as the depth target. + * + * @param context OpenGL context used for drawing. + * @param textures Texture attachements. + */ GlRenderTarget(const std::shared_ptr &context, std::vector> const &textures); - // Get the targeted textures + /** + * Get the targeted textures. + * + * @return Textures drawn into by the render target. + */ std::vector> get_texture_targets() override; - // Resize the render target for scaling viewport correctly. + /** + * Resize the render target to the specified dimensions. + * + * This is used to scale the viewport to the correct size when + * binding the render target with write access. + * + * @param width New width. + * @param height New height. + */ void resize(size_t width, size_t height); - /// Bind this render target to be drawn into. + /** + * Bind this render target to be drawn into. + */ void bind_write() const; - /// Bind this render target to be read from. + /** + * Bind this render target to be read from. + */ void bind_read() const; private: + /** + * Type of this render target. + */ gl_render_target_t type; - // Size of the window or the texture target + /** + * Size of the window or the texture targets. + */ std::pair size; - /// For textures target type, the framebuffer. + /** + * For framebuffer target type, the framebuffer. + */ std::optional framebuffer; - // target textures if the render target is an fbo + /** + * Target textures if the render target is a textured fbo. + */ std::optional>> textures; }; diff --git a/libopenage/renderer/opengl/renderer.cpp b/libopenage/renderer/opengl/renderer.cpp index f0e513f14c..91cc5b35ee 100644 --- a/libopenage/renderer/opengl/renderer.cpp +++ b/libopenage/renderer/opengl/renderer.cpp @@ -24,7 +24,9 @@ namespace openage::renderer::opengl { GlRenderer::GlRenderer(const std::shared_ptr &ctx, const util::Vector2s &viewport_size) : gl_context{ctx}, - display{std::make_shared(viewport_size[0], viewport_size[1])} { + display{std::make_shared(ctx, + viewport_size[0], + viewport_size[1])} { // global GL alpha blending settings glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); From d63d33e6918b4dba12b77d0055cd732a62ad0dee Mon Sep 17 00:00:00 2001 From: askastitva Date: Fri, 20 Oct 2023 16:02:41 +0530 Subject: [PATCH 14/95] Add atan2 to FixedPoint --- copying.md | 1 + libopenage/util/fixed_point.h | 9 +++++++++ libopenage/util/fixed_point_test.cpp | 3 ++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/copying.md b/copying.md index b524367fb0..cd024a0a13 100644 --- a/copying.md +++ b/copying.md @@ -150,6 +150,7 @@ _the openage authors_ are: | Munawar Hafiz | munahaf | munawar dawt hafiz à gmail dawt com | | Md Ashhar | ashhar | mdashhar01 à gmail dawt com | | Fábio Barkoski | fabiobarkoski | fabiobarkoskii à gmail dawt com | +| Astitva Kamble | askastitva | astitvakamble5 à 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/libopenage/util/fixed_point.h b/libopenage/util/fixed_point.h index 196ca17f54..1e27d15082 100644 --- a/libopenage/util/fixed_point.h +++ b/libopenage/util/fixed_point.h @@ -370,6 +370,10 @@ class FixedPoint { constexpr double sqrt() { return std::sqrt(this->to_double()); } + + constexpr double atan2(const FixedPoint &n) { + return std::atan2(this->to_double(), n.to_double()); + } }; @@ -481,6 +485,11 @@ constexpr double sqrt(openage::util::FixedPoint n) { return n.sqrt(); } +template +constexpr double atan2(openage::util::FixedPoint x, openage::util::FixedPoint y) { + return x.atan2(y); +} + template constexpr openage::util::FixedPoint min(openage::util::FixedPoint x, openage::util::FixedPoint y) { return openage::util::FixedPoint::from_raw_value( diff --git a/libopenage/util/fixed_point_test.cpp b/libopenage/util/fixed_point_test.cpp index 569d177e42..e5728f518c 100644 --- a/libopenage/util/fixed_point_test.cpp +++ b/libopenage/util/fixed_point_test.cpp @@ -1,4 +1,4 @@ -// Copyright 2016-2018 the openage authors. See copying.md for legal info. +// Copyright 2016-2023 the openage authors. See copying.md for legal info. #include "fixed_point.h" @@ -58,6 +58,7 @@ void fixed_point() { TESTEQUALS_FLOAT((e * 10).to_double(), 108.3 * 10, 1e-7); TESTEQUALS_FLOAT((e / 10).to_double(), 108.3 / 10, 1e-7); TESTEQUALS_FLOAT(std::sqrt(e), sqrt(108.3), 1e-7); + TESTEQUALS_FLOAT(std::atan2(e, f), atan2(108.3, -12.4), 1e-7); TESTEQUALS_FLOAT(std::abs(-e).to_double(), 108.3, 1e-7); TESTEQUALS_FLOAT(std::hypot(e, f), hypot(108.3, -12.4), 1e-7); TESTEQUALS_FLOAT(std::min(e, f), -12.4, 1e-7); From f82a89fd6de19c309ec0167fdae23fa129e9ac64 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 18 Nov 2023 15:57:37 +0100 Subject: [PATCH 15/95] assets: Mirror anchor offset when flipping is active. --- assets/shaders/world2d.vert.glsl | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/assets/shaders/world2d.vert.glsl b/assets/shaders/world2d.vert.glsl index 7e01b5a414..76cd6db34d 100644 --- a/assets/shaders/world2d.vert.glsl +++ b/assets/shaders/world2d.vert.glsl @@ -40,9 +40,14 @@ void main() { // this is the position where we want to draw the subtex in 2D vec4 obj_clip_pos = proj * view * model * vec4(obj_world_position, 1.0); + // if the subtex is flipped, we also need to flip the anchor offset + // essentially, we invert the coordinates for the flipped axis + float anchor_x = float(flip_x) * -1.0 * anchor_offset.x + float(!flip_x) * anchor_offset.x; + float anchor_y = float(flip_y) * -1.0 * anchor_offset.y + float(!flip_y) * anchor_offset.y; + // offset the clip position by the offset of the subtex anchor - // this basically aligns the object position and the subtex anchor - obj_clip_pos += vec4(anchor_offset.xy, 0.0, 0.0); + // imagine this as pinning the subtex to the object position at the subtex anchor point + obj_clip_pos += vec4(anchor_x, anchor_y, 0.0, 0.0); // create a move matrix for positioning the vertices // uses the scale and the transformed object position in clip space @@ -51,9 +56,15 @@ void main() { 0.0, 0.0, 1.0, 0.0, obj_clip_pos.x, obj_clip_pos.y, obj_clip_pos.z, 1.0); - // finally calculate the vertex position + // calculate the final vertex position gl_Position = move * vec4(v_position, 0.0, 1.0); + + // if the subtex is flipped, we also need to flip the uv tex coordinates + // essentially, we invert the coordinates for the flipped axis + + // !flip_x is default because OpenGL uses bottom-left as its origin float uv_x = float(!flip_x) * uv.x + float(flip_x) * (1.0 - uv.x); float uv_y = float(flip_y) * uv.y + float(!flip_y) * (1.0 - uv.y); + vert_uv = vec2(uv_x, uv_y); } From d493c800f6b795d018895b8479d32ab29e51fed7 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 12 Nov 2023 21:02:20 +0100 Subject: [PATCH 16/95] doc: PR templates. --- .../PULL_REQUEST_TEMPLATES/pull_request_template.md | 13 +++++++++++++ .github/PULL_REQUEST_TEMPLATES/release_template.md | 7 +++++++ 2 files changed, 20 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATES/pull_request_template.md create mode 100644 .github/PULL_REQUEST_TEMPLATES/release_template.md diff --git a/.github/PULL_REQUEST_TEMPLATES/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATES/pull_request_template.md new file mode 100644 index 0000000000..ed3dfa558f --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATES/pull_request_template.md @@ -0,0 +1,13 @@ +### Merge Checklist + + + + +- [ ] I have read the [contribution guide](doc/contributing.md) +- [ ] I have added my info to [copying.md](copying.md) (only first time contributors) +- [ ] I have run `make checkall` and fixed all mentioned problems + + +### Description + + diff --git a/.github/PULL_REQUEST_TEMPLATES/release_template.md b/.github/PULL_REQUEST_TEMPLATES/release_template.md new file mode 100644 index 0000000000..96661d5de3 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATES/release_template.md @@ -0,0 +1,7 @@ +### Checklist + +- [ ] Changelog + - [ ] Release date + - [ ] Version number in title + - [ ] Full commit log +- [ ] Bump version in `openage_version` From 417aa6d1bd5b36964ae1eb11269c19d93f5146e2 Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 22 Nov 2023 05:11:13 +0100 Subject: [PATCH 17/95] Use block indent for aligning after open brackets. --- .clang-format | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-format b/.clang-format index b870e0ee95..911b0baec5 100644 --- a/.clang-format +++ b/.clang-format @@ -4,7 +4,7 @@ # see documentation in doc/code_style/ for details and explainations. Language: Cpp AccessModifierOffset: -4 -AlignAfterOpenBracket: Align +AlignAfterOpenBracket: BlockIndent AlignArrayOfStructures: None AlignConsecutiveAssignments: false AlignConsecutiveBitFields: false From 7abc01d28289627571fb4221364b15d6e8399027 Mon Sep 17 00:00:00 2001 From: AyiStar Date: Mon, 27 Nov 2023 23:18:37 +0800 Subject: [PATCH 18/95] complete if-else branch to fix pylint error --- copying.md | 1 + openage/convert/entity_object/conversion/aoc/genie_unit.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/copying.md b/copying.md index cd024a0a13..afad82f953 100644 --- a/copying.md +++ b/copying.md @@ -151,6 +151,7 @@ _the openage authors_ are: | Md Ashhar | ashhar | mdashhar01 à gmail dawt com | | Fábio Barkoski | fabiobarkoski | fabiobarkoskii à gmail dawt com | | Astitva Kamble | askastitva | astitvakamble5 à gmail dawt com | +| Haoyang Bi | AyiStar | ayistar à outlook 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/openage/convert/entity_object/conversion/aoc/genie_unit.py b/openage/convert/entity_object/conversion/aoc/genie_unit.py index e719c5f24f..52ded9b659 100644 --- a/openage/convert/entity_object/conversion/aoc/genie_unit.py +++ b/openage/convert/entity_object/conversion/aoc/genie_unit.py @@ -479,6 +479,8 @@ def is_unique(self) -> bool: else: # AoE1 return False + else: + raise ValueError(f"Unknown group type for {repr(self)}") enabling_research_id = head_unit_connection["enabling_research"].value From 85a76747f75ccff568b7bec8f3a078c7269cad83 Mon Sep 17 00:00:00 2001 From: heinezen Date: Tue, 28 Nov 2023 00:54:52 +0100 Subject: [PATCH 19/95] cli: Make 'main' default entrypoint. --- openage/__main__.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openage/__main__.py b/openage/__main__.py index c002490739..a2bac73496 100644 --- a/openage/__main__.py +++ b/openage/__main__.py @@ -99,15 +99,15 @@ def main(argv=None): # pylint: disable=reimported from .main.main import init_subparser - init_subparser(subparsers.add_parser( + main_cli = subparsers.add_parser( "main", - parents=[global_cli, cfg_cli])) + parents=[global_cli, cfg_cli]) + init_subparser(main_cli) from .game.main import init_subparser - game_cli = subparsers.add_parser( + init_subparser(subparsers.add_parser( "game", - parents=[global_cli, cfg_cli]) - init_subparser(game_cli) + parents=[global_cli, cfg_cli])) from .testing.main import init_subparser init_subparser(subparsers.add_parser( @@ -143,8 +143,8 @@ def main(argv=None): print_version() if not args.subcommand: - # the user didn't specify a subcommand. default to 'game'. - args = game_cli.parse_args(argv) + # the user didn't specify a subcommand. default to 'main'. + args = main_cli.parse_args(argv) # process the shared args set_loglevel(verbosity_to_level(args.verbose - args.quiet)) From c0505b67001f025cb9465764669fc10079a2aa48 Mon Sep 17 00:00:00 2001 From: heinezen Date: Mon, 27 Nov 2023 23:49:24 +0100 Subject: [PATCH 20/95] Revert "Merge pull request #1602 from heinezen/clang-format-align" This reverts commit bfa99b5a90e72e78e5340a6456c60094398e8b76, reversing changes made to 4334fffbf6330c82bbdfb430ad5656d2ef15d687. --- .clang-format | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-format b/.clang-format index 911b0baec5..b870e0ee95 100644 --- a/.clang-format +++ b/.clang-format @@ -4,7 +4,7 @@ # see documentation in doc/code_style/ for details and explainations. Language: Cpp AccessModifierOffset: -4 -AlignAfterOpenBracket: BlockIndent +AlignAfterOpenBracket: Align AlignArrayOfStructures: None AlignConsecutiveAssignments: false AlignConsecutiveBitFields: false From 0a6c454abb3f1c830036e95c76bbf776845e105d Mon Sep 17 00:00:00 2001 From: AyiStar Date: Thu, 30 Nov 2023 23:28:20 +0800 Subject: [PATCH 21/95] try adding two math constants E and PI for FixedPoint --- libopenage/util/fixed_point.h | 25 +++++++++++++++++++++---- libopenage/util/fixed_point_test.cpp | 9 +++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/libopenage/util/fixed_point.h b/libopenage/util/fixed_point.h index 1e27d15082..3623091218 100644 --- a/libopenage/util/fixed_point.h +++ b/libopenage/util/fixed_point.h @@ -53,8 +53,8 @@ constexpr static /** - * Helper function that performs either a safe shift-right (amount > 0), - * or a safe shift-left (amount < 0). + * Helper function that performs either a safe shift-right (amount < 0), + * or a safe shift-left (amount >= 0). */ template constexpr static @@ -169,6 +169,17 @@ class FixedPoint { return FixedPoint::from_int(0); } + /** + * Constants + */ + static constexpr FixedPoint e() { + return from_fixedpoint(FixedPoint::from_raw_value(6267931151224907085ll)); + } + + static constexpr FixedPoint pi() { + return from_fixedpoint(FixedPoint::from_raw_value(7244019458077122842ll)); + } + /** * Factory function to get a fixed-point number from an integer. */ @@ -193,10 +204,16 @@ class FixedPoint { /** * Factory function to get a fixed-point number from a fixed-point number of different type. */ - template + template other_fractional_bits)>::type* = nullptr> + static constexpr FixedPoint from_fixedpoint(const FixedPoint &other) { + return FixedPoint::from_raw_value( + safe_shift(static_cast(other.get_raw_value()))); + } + + template ::type* = nullptr> static constexpr FixedPoint from_fixedpoint(const FixedPoint &other) { return FixedPoint::from_raw_value( - safe_shift(other.get_raw_value())); + static_cast(other.get_raw_value() / safe_shiftleft(1))); } /** diff --git a/libopenage/util/fixed_point_test.cpp b/libopenage/util/fixed_point_test.cpp index e5728f518c..72a0a0f088 100644 --- a/libopenage/util/fixed_point_test.cpp +++ b/libopenage/util/fixed_point_test.cpp @@ -6,6 +6,7 @@ #include "../testing/testing.h" #include "stringformatter.h" +#include "math_constants.h" namespace openage { namespace util { @@ -98,6 +99,14 @@ void fixed_point() { std::stringstream sstr("1234.5678"); sstr >> e; TESTEQUALS_FLOAT(e.to_double(), 1234.5678, 1e-7); + + TESTEQUALS_FLOAT(TestType::e().to_double(), math::E, 1e-7); + TESTEQUALS_FLOAT(TestType::pi().to_double(), math::PI, 1e-7); + + using TestTypeShort = FixedPoint; + TESTEQUALS_FLOAT(TestTypeShort::e().to_double(), math::E, 1e-3); + TESTEQUALS_FLOAT(TestTypeShort::pi().to_double(), math::PI, 1e-3); + } }}} // openage::util::tests From 83dc9d54d2710121822dc93f1fe10ffe638c5394 Mon Sep 17 00:00:00 2001 From: AyiStar Date: Mon, 4 Dec 2023 09:14:29 +0000 Subject: [PATCH 22/95] Complete full set of math constants --- libopenage/util/fixed_point.h | 59 +++++++++++++++++++++++++++- libopenage/util/fixed_point_test.cpp | 15 +++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/libopenage/util/fixed_point.h b/libopenage/util/fixed_point.h index 3623091218..39717540bf 100644 --- a/libopenage/util/fixed_point.h +++ b/libopenage/util/fixed_point.h @@ -170,16 +170,73 @@ class FixedPoint { } /** - * Constants + * Math constants represented in FixedPoint */ + // naming, definition and value are kept compatible with `math_constants.h` static constexpr FixedPoint e() { return from_fixedpoint(FixedPoint::from_raw_value(6267931151224907085ll)); } + static constexpr FixedPoint log2e() { + return from_fixedpoint(FixedPoint::from_raw_value(3326628274461080622ll)); + } + + static constexpr FixedPoint log10e() { + return from_fixedpoint(FixedPoint::from_raw_value(1001414895036696345ll)); + } + + static constexpr FixedPoint ln2() { + return from_fixedpoint(FixedPoint::from_raw_value(1598288580650331957ll)); + } + + static constexpr FixedPoint ln10() { + return from_fixedpoint(FixedPoint::from_raw_value(5309399739799983627ll)); + } + static constexpr FixedPoint pi() { return from_fixedpoint(FixedPoint::from_raw_value(7244019458077122842ll)); } + static constexpr FixedPoint pi_2() { + return from_fixedpoint(FixedPoint::from_raw_value(3622009729038561421ll)); + } + + static constexpr FixedPoint pi_4() { + return from_fixedpoint(FixedPoint::from_raw_value(1811004864519280710ll)); + } + + static constexpr FixedPoint inv_pi() { + return from_fixedpoint(FixedPoint::from_raw_value(733972625820500306ll)); + } + + static constexpr FixedPoint inv2_pi() { + return from_fixedpoint(FixedPoint::from_raw_value(1467945251641000613ll)); + } + + static constexpr FixedPoint inv2_sqrt_pi() { + return from_fixedpoint(FixedPoint::from_raw_value(2601865214189558307ll)); + } + + static constexpr FixedPoint tau() { + return from_fixedpoint(FixedPoint::from_raw_value(7244019458077122842ll)); + } + + static constexpr FixedPoint degs_per_rad() { + return from_fixedpoint(FixedPoint::from_raw_value(40244552544872904ll)); + } + + static constexpr FixedPoint rads_per_deg() { + return from_fixedpoint(FixedPoint::from_raw_value(8257192040480628449ll)); + } + + static constexpr FixedPoint sqrt_2() { + return from_fixedpoint(FixedPoint::from_raw_value(3260954456333195553ll)); + } + + static constexpr FixedPoint inv_sqrt_2() { + return from_fixedpoint(FixedPoint::from_raw_value(1630477228166597776ll)); + } + /** * Factory function to get a fixed-point number from an integer. */ diff --git a/libopenage/util/fixed_point_test.cpp b/libopenage/util/fixed_point_test.cpp index 72a0a0f088..7a7fb2bc0c 100644 --- a/libopenage/util/fixed_point_test.cpp +++ b/libopenage/util/fixed_point_test.cpp @@ -101,7 +101,22 @@ void fixed_point() { TESTEQUALS_FLOAT(e.to_double(), 1234.5678, 1e-7); TESTEQUALS_FLOAT(TestType::e().to_double(), math::E, 1e-7); + TESTEQUALS_FLOAT(TestType::log2e().to_double(), math::LOG2E, 1e-7); + TESTEQUALS_FLOAT(TestType::log10e().to_double(), math::LOG10E, 1e-7); + TESTEQUALS_FLOAT(TestType::ln2().to_double(), math::LN2, 1e-7); + TESTEQUALS_FLOAT(TestType::ln10().to_double(), math::LN10, 1e-7); TESTEQUALS_FLOAT(TestType::pi().to_double(), math::PI, 1e-7); + TESTEQUALS_FLOAT(TestType::pi_2().to_double(), math::PI_2, 1e-7); + TESTEQUALS_FLOAT(TestType::pi_4().to_double(), math::PI_4, 1e-7); + TESTEQUALS_FLOAT(TestType::inv_pi().to_double(), math::INV_PI, 1e-7); + TESTEQUALS_FLOAT(TestType::inv2_pi().to_double(), math::INV2_PI, 1e-7); + TESTEQUALS_FLOAT(TestType::inv2_sqrt_pi().to_double(), math::INV2_SQRT_PI, 1e-7); + TESTEQUALS_FLOAT(TestType::tau().to_double(), math::TAU, 1e-7); + TESTEQUALS_FLOAT(TestType::degs_per_rad().to_double(), math::DEGSPERRAD, 1e-7); + TESTEQUALS_FLOAT(TestType::rads_per_deg().to_double(), math::RADSPERDEG, 1e-7); + TESTEQUALS_FLOAT(TestType::sqrt_2().to_double(), math::SQRT_2, 1e-7); + TESTEQUALS_FLOAT(TestType::inv_sqrt_2().to_double(), math::INV_SQRT_2, 1e-7); + using TestTypeShort = FixedPoint; TESTEQUALS_FLOAT(TestTypeShort::e().to_double(), math::E, 1e-3); From 35e9ffb5a5f0dc69604821a8ce817869d9d4aca6 Mon Sep 17 00:00:00 2001 From: heinezen Date: Fri, 15 Dec 2023 17:37:37 +0100 Subject: [PATCH 23/95] ci: Fix macOS build. --- .github/workflows/macosx-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/macosx-ci.yml b/.github/workflows/macosx-ci.yml index c60d76a4da..d7b86776db 100644 --- a/.github/workflows/macosx-ci.yml +++ b/.github/workflows/macosx-ci.yml @@ -55,7 +55,7 @@ jobs: - name: Brew install DeJaVu fonts run: brew tap homebrew/cask-fonts && brew install font-dejavu - name: Remove python's 2to3 link so that 'brew link' does not fail - run: rm '/usr/local/bin/2to3' && rm '/usr/local/bin/2to3-3.11' + run: rm /usr/local/bin/2to3* && rm /usr/local/bin/idle3* - name: Install environment helpers with homebrew run: brew install ccache - name: Install dependencies with homebrew @@ -66,7 +66,7 @@ jobs: # cython, numpy and pygments are in homebrew, # but "cython is keg-only, which means it was not symlinked into /usr/local" # numpy pulls gcc as dep? and pygments doesn't work. - run: pip3 install --upgrade cython numpy mako lz4 pillow pygments toml + run: pip3 install --upgrade cython numpy mako lz4 pillow pygments setuptools toml - name: Configure run: | CLANG_PATH="$HOME/clang-15.0.0/bin/clang++" From cd135ae19854a6c5fa0f257133ed27af788b68c9 Mon Sep 17 00:00:00 2001 From: heinezen Date: Fri, 15 Dec 2023 18:32:09 +0100 Subject: [PATCH 24/95] doc: Add 'setuptools' as conditional dependency. --- doc/building.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/building.md b/doc/building.md index 81d075eebb..c5b8af6180 100644 --- a/doc/building.md +++ b/doc/building.md @@ -32,9 +32,10 @@ Dependency list: C cython >=0.29.31 C cmake >=3.16 A numpy + A lz4 A python imaging library (PIL) -> pillow - RA toml - RA lz4 + RA setuptools (for python>=3.12 and cython<3.1) + A toml CR opengl >=3.3 CR libepoxy CR libpng From 27b05b49327cddb6f9b36f1e9cbb2d91ea194663 Mon Sep 17 00:00:00 2001 From: heinezen Date: Fri, 22 Sep 2023 21:13:19 +0200 Subject: [PATCH 25/95] renderer: Deprecate old renderer code. --- libopenage/assets/assetmanager.h | 2 +- libopenage/assets/legacy_assetmanager.h | 2 +- libopenage/handlers.h | 10 +++---- libopenage/options.h | 29 ++++++++----------- libopenage/presenter/assets/asset_manager.h | 2 +- libopenage/presenter/legacy/game_control.h | 12 ++++---- libopenage/presenter/legacy/legacy.h | 2 +- libopenage/presenter/legacy/legacy_renderer.h | 2 +- libopenage/screenshot.h | 9 +++--- libopenage/texture.h | 23 ++++++++------- 10 files changed, 44 insertions(+), 49 deletions(-) diff --git a/libopenage/assets/assetmanager.h b/libopenage/assets/assetmanager.h index 482f2ac672..5fff6b0328 100644 --- a/libopenage/assets/assetmanager.h +++ b/libopenage/assets/assetmanager.h @@ -26,7 +26,7 @@ class GameSimulation; * Container class for all available assets. * Responsible for loading, providing and updating requested files. */ -class AssetManager final { +class [[deprecated]] AssetManager final { public: explicit AssetManager(qtsdl::GuiItemLink *gui_link); diff --git a/libopenage/assets/legacy_assetmanager.h b/libopenage/assets/legacy_assetmanager.h index 284719b1e1..c4436007e9 100644 --- a/libopenage/assets/legacy_assetmanager.h +++ b/libopenage/assets/legacy_assetmanager.h @@ -24,7 +24,7 @@ class Texture; * Container class for all available assets. * Responsible for loading, providing and updating requested files. */ -class LegacyAssetManager final { +class [[deprecated]] LegacyAssetManager final { public: explicit LegacyAssetManager(qtsdl::GuiItemLink *gui_link); diff --git a/libopenage/handlers.h b/libopenage/handlers.h index 7df7300d45..f695a2589e 100644 --- a/libopenage/handlers.h +++ b/libopenage/handlers.h @@ -14,7 +14,7 @@ class LegacyEngine; /** * superclass for all possible drawing operations in the game. */ -class DrawHandler { +class [[deprecated]] DrawHandler { public: virtual ~DrawHandler() = default; @@ -27,7 +27,7 @@ class DrawHandler { /** * superclass for all possible drawing operations in the game. */ -class HudHandler { +class [[deprecated]] HudHandler { public: virtual ~HudHandler() = default; @@ -40,7 +40,7 @@ class HudHandler { /** * superclass for all calculations being done on engine tick. */ -class TickHandler { +class [[deprecated]] TickHandler { public: virtual ~TickHandler() = default; @@ -53,7 +53,7 @@ class TickHandler { /** * superclass for handling any input event. */ -class InputHandler { +class [[deprecated]] InputHandler { public: virtual ~InputHandler() = default; @@ -66,7 +66,7 @@ class InputHandler { /** * superclass for handling a window resize event. */ -class ResizeHandler { +class [[deprecated]] ResizeHandler { public: virtual ~ResizeHandler() = default; diff --git a/libopenage/options.h b/libopenage/options.h index 320b14a54d..0798007f7b 100644 --- a/libopenage/options.h +++ b/libopenage/options.h @@ -36,10 +36,11 @@ using option_list = std::vector; /** * stores a type and value + * + * TODO: What is this used for? */ class OptionValue { public: - /** * value ownership managed by this */ @@ -71,13 +72,13 @@ class OptionValue { /** * Checks equality */ - bool operator ==(const OptionValue &other) const; + bool operator==(const OptionValue &other) const; /** * Assignment, reference values share their values * non reference values are copied */ - const OptionValue &operator =(const OptionValue &other); + const OptionValue &operator=(const OptionValue &other); /** * Value converted to a string @@ -87,7 +88,7 @@ class OptionValue { /** * read inner type - the templated type must match */ - template + template const T &value() const { return var->get(); } @@ -95,13 +96,12 @@ class OptionValue { const option_type type; private: - /** * set the value */ void set(const OptionValue &other); - template + template void set_value(const OptionValue &other) { const T &other_value = other.value(); if (this->var) { @@ -125,7 +125,6 @@ class OptionValue { */ bool owner; util::VariableBase *var; - }; OptionValue parse(option_type t, const std::string &s); @@ -152,7 +151,6 @@ class OptionAction { private: const opt_func_t function; - }; /** @@ -162,8 +160,9 @@ class OptionAction { * with console interaction or gui elements */ class OptionNode { - template + template friend class Var; + public: OptionNode(std::string panel_name); virtual ~OptionNode(); @@ -171,7 +170,7 @@ class OptionNode { /** * lists all available options in a readable format */ - std::vector list_options(bool recurse=false, const std::string &indent=""); + std::vector list_options(bool recurse = false, const std::string &indent = ""); /** * shows all available variable names @@ -189,7 +188,7 @@ class OptionNode { /** * shortcut for get_variable(name).value() */ - template + template const T &getv(const std::string &name) { return this->get_variable(name).value(); } @@ -217,7 +216,6 @@ class OptionNode { const std::string name; protected: - /** * add types to the interface */ @@ -226,7 +224,6 @@ class OptionNode { void add_action(const OptionAction &action); private: - /** * add child nodes */ @@ -264,13 +261,11 @@ class OptionNode { * option node allowing reflection, while also * being directly accessable as a typed member */ -template +template class Var : public util::Variable { public: - Var(OptionNode *owner, const std::string &name, const T &init) - : + Var(OptionNode *owner, const std::string &name, const T &init) : util::Variable{init} { - owner->add(name, this->value); } }; diff --git a/libopenage/presenter/assets/asset_manager.h b/libopenage/presenter/assets/asset_manager.h index 48075eeaeb..fa3461501b 100644 --- a/libopenage/presenter/assets/asset_manager.h +++ b/libopenage/presenter/assets/asset_manager.h @@ -24,7 +24,7 @@ namespace openage::presenter { * Container class for all available assets. * Responsible for loading, providing and updating requested files. */ -class AssetManager final { +class [[deprecated]] AssetManager final { public: AssetManager(); AssetManager(const util::Path &asset_dir); diff --git a/libopenage/presenter/legacy/game_control.h b/libopenage/presenter/legacy/game_control.h index cad9deab7b..2732ce0345 100644 --- a/libopenage/presenter/legacy/game_control.h +++ b/libopenage/presenter/legacy/game_control.h @@ -32,7 +32,7 @@ class GameControl; /** * Signals for a gui mode. */ -class OutputModeSignals : public QObject { +class [[deprecated]] OutputModeSignals : public QObject { Q_OBJECT public: @@ -55,7 +55,7 @@ class OutputModeSignals : public QObject { * A target for input handling and gui rendering. * This allows to switch to different display UIs. */ -class OutputMode : public input::legacy::InputContext { +class [[deprecated]] OutputMode : public input::legacy::InputContext { public: explicit OutputMode(qtsdl::GuiItemLink *gui_link); virtual ~OutputMode(); @@ -117,7 +117,7 @@ class OutputMode : public input::legacy::InputContext { * This is mainly the game editor. * Shows menus to choose units to build. */ -class CreateMode : public OutputMode { +class [[deprecated]] CreateMode : public OutputMode { public: CreateMode(qtsdl::GuiItemLink *gui_link); @@ -165,7 +165,7 @@ public slots: * Used to control units, issue commands, basically this is where you * sink your time in when playing. */ -class ActionMode : public OutputMode { +class [[deprecated]] ActionMode : public OutputMode { public: ActionMode(qtsdl::GuiItemLink *gui_link); @@ -279,7 +279,7 @@ public slots: /** * UI mode to provide an interface for map editing. */ -class EditorMode : public OutputMode { +class [[deprecated]] EditorMode : public OutputMode { public: explicit EditorMode(qtsdl::GuiItemLink *gui_link); @@ -354,7 +354,7 @@ public slots: * * hud rendering and input handling is redirected to the active mode */ -class GameControl : public openage::HudHandler { +class [[deprecated]] GameControl : public openage::HudHandler { public: explicit GameControl(qtsdl::GuiItemLink *gui_link); diff --git a/libopenage/presenter/legacy/legacy.h b/libopenage/presenter/legacy/legacy.h index b4a82443fd..9ee18ab1c9 100644 --- a/libopenage/presenter/legacy/legacy.h +++ b/libopenage/presenter/legacy/legacy.h @@ -49,7 +49,7 @@ namespace presenter { /** * Temporary container class for the legacy renderer implementation. */ -class LegacyDisplay final : public ResizeHandler +class [[deprecated]] LegacyDisplay final : public ResizeHandler , public options::OptionNode { public: LegacyDisplay(const util::Path &path, LegacyEngine *engine); diff --git a/libopenage/presenter/legacy/legacy_renderer.h b/libopenage/presenter/legacy/legacy_renderer.h index ea60a76623..cde40b869d 100644 --- a/libopenage/presenter/legacy/legacy_renderer.h +++ b/libopenage/presenter/legacy/legacy_renderer.h @@ -25,7 +25,7 @@ class GameMain; * * TODO include fog drawing etc */ -class RenderOptions : public options::OptionNode { +class [[deprecated]] RenderOptions : public options::OptionNode { public: RenderOptions(); diff --git a/libopenage/screenshot.h b/libopenage/screenshot.h index 221f0b43ab..45e2660f5b 100644 --- a/libopenage/screenshot.h +++ b/libopenage/screenshot.h @@ -2,9 +2,9 @@ #pragma once -#include #include #include +#include #include "coord/pixel.h" @@ -19,12 +19,12 @@ class JobManager; * * TODO: move into renderer! */ -class ScreenshotManager { +class [[deprecated]] ScreenshotManager { public: /** * Initializes the screenshot manager with the given job manager. */ - ScreenshotManager(job::JobManager* job_mgr); + ScreenshotManager(job::JobManager *job_mgr); ~ScreenshotManager(); @@ -39,7 +39,6 @@ class ScreenshotManager { coord::viewport_delta window_size; private: - /** to be called to get the next screenshot filename into the array */ std::string gen_next_filename(); @@ -53,4 +52,4 @@ class ScreenshotManager { job::JobManager *job_manager; }; -} // openage +} // namespace openage diff --git a/libopenage/texture.h b/libopenage/texture.h index 5469fe11e3..64283e86cc 100644 --- a/libopenage/texture.h +++ b/libopenage/texture.h @@ -1,14 +1,14 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. +// Copyright 2013-2023 the openage authors. See copying.md for legal info. #pragma once #include -#include #include +#include -#include "gamedata/texture_dummy.h" #include "coord/pixel.h" #include "coord/tile.h" +#include "gamedata/texture_dummy.h" #include "shader/program.h" #include "shader/shader.h" #include "util/path.h" @@ -43,12 +43,12 @@ extern GLint base_texture, mask_texture, base_coord, mask_coord, show_mask; // bitmasks for shader modes constexpr int PLAYERCOLORED = 1 << 0; -constexpr int ALPHAMASKED = 1 << 1; +constexpr int ALPHAMASKED = 1 << 1; /** * enables transfer of data to opengl */ -struct gl_texture_buffer { +struct [[deprecated]] gl_texture_buffer { GLuint id, vertbuf; // this requires loading on the main thread @@ -67,8 +67,10 @@ struct gl_texture_buffer { * * The class supports subtextures, so that one big texture can contain * several small images. These are the ones actually to be rendered. + * + * TODO: Deprecated, replaced by new renderer */ -class Texture { +class [[deprecated]] Texture { public: int w; int h; @@ -83,23 +85,23 @@ class Texture { * Create a texture from a existing image file. * For supported image file types, see the SDL_Image initialization in the engine. */ - Texture(const util::Path &filename, bool use_metafile=false); + Texture(const util::Path &filename, bool use_metafile = false); ~Texture(); /** * Draws the texture at hud coordinates. */ - void draw(const coord::CoordManager &mgr, coord::camhud pos, unsigned int mode=0, bool mirrored=false, int subid=0, unsigned player=0) const; + void draw(const coord::CoordManager &mgr, coord::camhud pos, unsigned int mode = 0, bool mirrored = false, int subid = 0, unsigned player = 0) const; /** * Draws the texture at game coordinates. */ - void draw(const coord::CoordManager &mgr, coord::camgame pos, unsigned int mode=0, bool mirrored=false, int subid=0, unsigned player=0) const; + void draw(const coord::CoordManager &mgr, coord::camgame pos, unsigned int mode = 0, bool mirrored = false, int subid = 0, unsigned player = 0) const; /** * Draws the texture at phys coordinates. */ - void draw(const coord::CoordManager &mgr, coord::phys3 pos, unsigned int mode=0, bool mirrored=false, int subid=0, unsigned player=0) const; + void draw(const coord::CoordManager &mgr, coord::phys3 pos, unsigned int mode = 0, bool mirrored = false, int subid = 0, unsigned player = 0) const; /** * Draws the texture at tile coordinates. @@ -181,7 +183,6 @@ class Texture { void load_in_glthread() const; GLuint make_gl_texture(int iformat, int oformat, int w, int h, void *) const; void unload(); - }; } // namespace openage From 96d08f5d5f566091fde85a33313d23cad7325001 Mon Sep 17 00:00:00 2001 From: heinezen Date: Fri, 22 Sep 2023 21:22:42 +0200 Subject: [PATCH 26/95] renderer: Remove legacy renderer. --- libopenage/presenter/legacy/CMakeLists.txt | 1 - .../presenter/legacy/legacy_renderer.cpp | 214 ------------------ libopenage/presenter/legacy/legacy_renderer.h | 65 ------ 3 files changed, 280 deletions(-) delete mode 100644 libopenage/presenter/legacy/legacy_renderer.cpp delete mode 100644 libopenage/presenter/legacy/legacy_renderer.h diff --git a/libopenage/presenter/legacy/CMakeLists.txt b/libopenage/presenter/legacy/CMakeLists.txt index d4add0acd2..5a57295ab3 100644 --- a/libopenage/presenter/legacy/CMakeLists.txt +++ b/libopenage/presenter/legacy/CMakeLists.txt @@ -1,7 +1,6 @@ add_sources(libopenage game_control.cpp legacy.cpp - legacy_renderer.cpp ) pxdgen( diff --git a/libopenage/presenter/legacy/legacy_renderer.cpp b/libopenage/presenter/legacy/legacy_renderer.cpp deleted file mode 100644 index 3e65693f36..0000000000 --- a/libopenage/presenter/legacy/legacy_renderer.cpp +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "legacy_renderer.h" - -#include -#include -#include -#include -#include - -#include "../../console/console.h" -#include "../../gamedata/color_dummy.h" -#include "../../gamestate/old/game_main.h" -#include "../../gamestate/old/game_spec.h" -#include "../../input/legacy/input_manager.h" -#include "../../legacy_engine.h" -#include "../../log/log.h" -#include "../../renderer/text.h" -#include "../../unit/action.h" -#include "../../unit/command.h" -#include "../../unit/producer.h" -#include "../../unit/unit.h" -#include "../../unit/unit_texture.h" -#include "../../util/externalprofiler.h" -#include "../../util/timer.h" -#include "legacy.h" - -namespace openage { - - -RenderOptions::RenderOptions() : - OptionNode{"RendererOptions"}, - draw_debug{this, "draw_debug", false}, - terrain_blending{this, "terrain_blending", true} {} - - -LegacyRenderer::LegacyRenderer(LegacyEngine *e, presenter::LegacyDisplay *d) : - engine{e}, - display{d} { - // set options structure - this->settings.set_parent(this->display); - - // display callbacks - this->display->register_draw_action(this); - - // fetch asset loading dir - util::Path asset_dir = this->engine->get_root_dir()["assets"]; - - // load textures and stuff - gaben = new Texture{asset_dir["test"]["textures"]["gaben.png"]}; - - std::vector player_color_lines = util::read_csv_file( - asset_dir["converted/player_palette.docx"]); - - std::unique_ptr playercolors = std::make_unique(player_color_lines.size() * 4); - for (size_t i = 0; i < player_color_lines.size(); i++) { - auto line = &player_color_lines[i]; - playercolors[i * 4] = line->r / 255.0; - playercolors[i * 4 + 1] = line->g / 255.0; - playercolors[i * 4 + 2] = line->b / 255.0; - playercolors[i * 4 + 3] = line->a / 255.0; - } - - // shader initialisation - // read shader source codes and create shader objects for wrapping them. - const char *shader_header_code = "#version 120\n"; - std::string equals_epsilon_code = asset_dir["shaders/equalsEpsilon.glsl"].open().read(); - std::string texture_vert_code = asset_dir["shaders/maptexture.vert.glsl"].open().read(); - auto plaintexture_vert = std::make_unique( - GL_VERTEX_SHADER, - std::initializer_list{shader_header_code, texture_vert_code.c_str()}); - - std::string texture_frag_code = asset_dir["shaders/maptexture.frag.glsl"].open().read(); - auto plaintexture_frag = std::make_unique( - GL_FRAGMENT_SHADER, - std::initializer_list{shader_header_code, texture_frag_code.c_str()}); - - std::string teamcolor_frag_code = asset_dir["shaders/teamcolors.frag.glsl"].open().read(); - std::stringstream ss; - ss << player_color_lines.size(); - auto teamcolor_frag = std::make_unique( - GL_FRAGMENT_SHADER, - std::initializer_list{ - shader_header_code, - ("#define NUM_OF_PLAYER_COLORS " + ss.str() + "\n").c_str(), - equals_epsilon_code.c_str(), - teamcolor_frag_code.c_str()}); - - std::string alphamask_vert_code = asset_dir["shaders/alphamask.vert.glsl"].open().read(); - auto alphamask_vert = std::make_unique( - GL_VERTEX_SHADER, - std::initializer_list{shader_header_code, alphamask_vert_code.c_str()}); - - std::string alphamask_frag_code = asset_dir["shaders/alphamask.frag.glsl"].open().read(); - auto alphamask_frag = std::make_unique( - GL_FRAGMENT_SHADER, - std::initializer_list{shader_header_code, alphamask_frag_code.c_str()}); - - std::string texturefont_vert_code = asset_dir["shaders/texturefont.vert.glsl"].open().read(); - auto texturefont_vert = std::make_unique( - GL_VERTEX_SHADER, - std::initializer_list{shader_header_code, texturefont_vert_code.c_str()}); - - std::string texturefont_frag_code = asset_dir["shaders/texturefont.frag.glsl"].open().read(); - auto texturefont_frag = std::make_unique( - GL_FRAGMENT_SHADER, - std::initializer_list{shader_header_code, texturefont_frag_code.c_str()}); - - // create program for rendering simple textures - texture_shader::program = new shader::Program(plaintexture_vert.get(), plaintexture_frag.get()); - texture_shader::program->link(); - texture_shader::texture = texture_shader::program->get_uniform_id("texture"); - texture_shader::tex_coord = texture_shader::program->get_attribute_id("tex_coordinates"); - texture_shader::program->use(); - glUniform1i(texture_shader::texture, 0); - texture_shader::program->stopusing(); - - - // create program for tinting textures at alpha-marked pixels - // with team colors - teamcolor_shader::program = new shader::Program(plaintexture_vert.get(), teamcolor_frag.get()); - teamcolor_shader::program->link(); - teamcolor_shader::texture = teamcolor_shader::program->get_uniform_id("texture"); - teamcolor_shader::tex_coord = teamcolor_shader::program->get_attribute_id("tex_coordinates"); - teamcolor_shader::player_id_var = teamcolor_shader::program->get_uniform_id("player_number"); - teamcolor_shader::alpha_marker_var = teamcolor_shader::program->get_uniform_id("alpha_marker"); - teamcolor_shader::player_color_var = teamcolor_shader::program->get_uniform_id("player_color"); - teamcolor_shader::program->use(); - glUniform1i(teamcolor_shader::texture, 0); - glUniform1f(teamcolor_shader::alpha_marker_var, 254.0 / 255.0); - // fill the teamcolor shader's player color table: - glUniform4fv(teamcolor_shader::player_color_var, 64, playercolors.get()); - teamcolor_shader::program->stopusing(); - - - // create program for drawing textures that are alpha-masked before - alphamask_shader::program = new shader::Program(alphamask_vert.get(), alphamask_frag.get()); - alphamask_shader::program->link(); - alphamask_shader::base_coord = alphamask_shader::program->get_attribute_id("base_tex_coordinates"); - alphamask_shader::mask_coord = alphamask_shader::program->get_attribute_id("mask_tex_coordinates"); - alphamask_shader::show_mask = alphamask_shader::program->get_uniform_id("show_mask"); - alphamask_shader::base_texture = alphamask_shader::program->get_uniform_id("base_texture"); - alphamask_shader::mask_texture = alphamask_shader::program->get_uniform_id("mask_texture"); - alphamask_shader::program->use(); - glUniform1i(alphamask_shader::base_texture, 0); - glUniform1i(alphamask_shader::mask_texture, 1); - alphamask_shader::program->stopusing(); - - // Create program for texture based font rendering - texturefont_shader::program = new shader::Program(texturefont_vert.get(), texturefont_frag.get()); - texturefont_shader::program->link(); - texturefont_shader::texture = texturefont_shader::program->get_uniform_id("texture"); - texturefont_shader::color = texturefont_shader::program->get_uniform_id("color"); - texturefont_shader::tex_coord = texturefont_shader::program->get_attribute_id("tex_coordinates"); - texturefont_shader::program->use(); - glUniform1i(texturefont_shader::texture, 0); - texturefont_shader::program->stopusing(); - - // Renderer keybinds - // TODO: a renderer settings struct - // would allow these to be put somewhere better - input::legacy::ActionManager &action = this->display->get_action_manager(); - auto &global_input_context = this->display->get_input_manager().get_global_context(); - global_input_context.bind(action.get("TOGGLE_BLENDING"), [this](const input::legacy::action_arg_t &) { - this->settings.terrain_blending.value = !this->settings.terrain_blending.value; - }); - global_input_context.bind(action.get("TOGGLE_UNIT_DEBUG"), [this](const input::legacy::action_arg_t &) { - this->settings.draw_debug.value = !this->settings.draw_debug.value; - - log::log(MSG(dbg) << "Toggle debug grid"); - - // TODO remove this hack, use render settings instead - UnitAction::show_debug = !UnitAction::show_debug; - }); - - log::log(MSG(dbg) << "Loaded Renderer"); -} - -LegacyRenderer::~LegacyRenderer() { - // oh noes, release hl3 before that! - delete this->gaben; - - delete texture_shader::program; - delete teamcolor_shader::program; - delete alphamask_shader::program; - delete texturefont_shader::program; -} - - -bool LegacyRenderer::on_draw() { - // draw terrain - GameMain *game = this->display->get_game(); - - if (game) { - // draw gaben, our great and holy protector, bringer of the half-life 3. - gaben->draw(this->display->coord, coord::camgame{0, 0}); - - // TODO move render code out of terrain - if (game->terrain) { - game->terrain->draw(this->display, &this->settings); - } - } - return true; -} - -GameMain *LegacyRenderer::game() const { - return this->display->get_game(); -} - -GameSpec *LegacyRenderer::game_spec() const { - return this->game()->get_spec(); -} - -} // namespace openage diff --git a/libopenage/presenter/legacy/legacy_renderer.h b/libopenage/presenter/legacy/legacy_renderer.h deleted file mode 100644 index cde40b869d..0000000000 --- a/libopenage/presenter/legacy/legacy_renderer.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include -#include - -#include "../../coord/tile.h" -#include "../../gamestate/old/game_spec.h" -#include "../../handlers.h" -#include "../../options.h" -#include "legacy.h" - -namespace openage { - -class GameMain; - -/** - * Options for the renderer. - * These will be included in the user interface - * via reflection, so adding new members will - * always be visible - * - * TODO include fog drawing etc - */ -class [[deprecated]] RenderOptions : public options::OptionNode { -public: - RenderOptions(); - - options::Var draw_debug; - options::Var terrain_blending; -}; - -/** - * renders the editor and action views - */ -class LegacyRenderer : DrawHandler { -public: - LegacyRenderer(LegacyEngine *e, presenter::LegacyDisplay *d); - ~LegacyRenderer(); - - bool on_draw() override; - - /** - * the game this renderer is using - */ - GameMain *game() const; - - /** - * GameSpec used by this renderer - */ - GameSpec *game_spec() const; - - Texture *gaben; - - RenderOptions settings; - -private: - LegacyEngine *engine; - presenter::LegacyDisplay *display; -}; - -} // namespace openage From 4f8e4e6e5dfe5c4250db4035809744bd83673889 Mon Sep 17 00:00:00 2001 From: heinezen Date: Fri, 22 Sep 2023 21:58:52 +0200 Subject: [PATCH 27/95] renderer: Remove legacy asset management. --- libopenage/assets/CMakeLists.txt | 1 - libopenage/assets/assetmanager.cpp | 207 ------------------ libopenage/assets/assetmanager.h | 139 ------------ libopenage/presenter/CMakeLists.txt | 1 - libopenage/presenter/assets/CMakeLists.txt | 3 - libopenage/presenter/assets/asset_manager.cpp | 194 ---------------- libopenage/presenter/assets/asset_manager.h | 105 --------- libopenage/renderer/gui/CMakeLists.txt | 1 - libopenage/renderer/gui/assetmanager_link.cpp | 57 ----- libopenage/renderer/gui/assetmanager_link.h | 60 ----- 10 files changed, 768 deletions(-) delete mode 100644 libopenage/assets/assetmanager.cpp delete mode 100644 libopenage/assets/assetmanager.h delete mode 100644 libopenage/presenter/assets/CMakeLists.txt delete mode 100644 libopenage/presenter/assets/asset_manager.cpp delete mode 100644 libopenage/presenter/assets/asset_manager.h delete mode 100644 libopenage/renderer/gui/assetmanager_link.cpp delete mode 100644 libopenage/renderer/gui/assetmanager_link.h diff --git a/libopenage/assets/CMakeLists.txt b/libopenage/assets/CMakeLists.txt index 681d9882b9..8384d7d988 100644 --- a/libopenage/assets/CMakeLists.txt +++ b/libopenage/assets/CMakeLists.txt @@ -1,5 +1,4 @@ add_sources(libopenage - assetmanager.cpp legacy_assetmanager.cpp mod_manager.cpp modpack.cpp diff --git a/libopenage/assets/assetmanager.cpp b/libopenage/assets/assetmanager.cpp deleted file mode 100644 index a62f0c2d34..0000000000 --- a/libopenage/assets/assetmanager.cpp +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -/** - * TODO: Deprecated in favor of presenter/assets/asset_manager.h - * - */ - -#include "assetmanager.h" - -#if WITH_INOTIFY -#include /* for NAME_MAX */ -#include -#include -#endif - -#include "error/error.h" -#include "log/log.h" -#include "util/compiler.h" -#include "util/file.h" - -#include "texture.h" - -namespace openage { - -AssetManager::AssetManager(qtsdl::GuiItemLink *gui_link) : - missing_tex{nullptr}, - gui_link{gui_link} { -#if WITH_INOTIFY - // initialize the inotify instance - this->inotify_fd = inotify_init1(IN_NONBLOCK); - if (this->inotify_fd < 0) { - throw Error{MSG(err) << "Failed to initialize inotify!"}; - } -#endif -} - - -const util::Path &AssetManager::get_asset_dir() { - return this->asset_path; -} - - -void AssetManager::set_asset_dir(const util::Path &new_path) { - if (this->asset_path != new_path) { - this->asset_path = new_path; - this->clear(); - } -} - - -void AssetManager::set_display(presenter::LegacyDisplay *display) { - this->display = display; -} - - -presenter::LegacyDisplay *AssetManager::get_display() const { - return this->display; -} - -void AssetManager::set_engine(gamestate::GameSimulation *engine) { - this->engine = engine; -} - -gamestate::GameSimulation *AssetManager::get_engine() const { - return this->engine; -} - - -std::shared_ptr AssetManager::load_texture(const std::string &name, - bool use_metafile, - bool null_if_missing) { - // the texture to be associated with the given filename - std::shared_ptr tex; - - util::Path tex_path = this->asset_path[name]; - - // try to open the texture filename. - if (not tex_path.is_file()) { - // TODO: add/fetch inotify watch on the containing folder - // to display the tex as soon at it exists. - - if (null_if_missing) { - return nullptr; - } - else { - // return the big X texture instead - tex = this->get_missing_tex(); - } - } - else { - // create the texture! - tex = std::make_shared(tex_path, use_metafile); - -#if WITH_INOTIFY - std::string native_path = tex_path.resolve_native_path(); - - if (native_path.size() > 0) { - // create inotify update trigger for the requested file - - // TODO: let util::Path do the file watching - int wd = inotify_add_watch( - this->inotify_fd, - native_path.c_str(), - IN_CLOSE_WRITE); - - if (wd < 0) { - log::log(WARN << "Failed to add inotify watch for " << native_path); - } - else { - this->watch_fds[wd] = tex; - } - } -#endif - } - - // pass back the shared_ptr - return tex; -} - - -Texture *AssetManager::get_texture(const std::string &name, bool use_metafile, bool null_if_missing) { - // check whether the requested texture was loaded already - auto tex_it = this->textures.find(name); - - // the texture was not loaded yet: - if (tex_it == this->textures.end()) { - auto tex = this->load_texture(name, use_metafile, null_if_missing); - - if (tex.get() != nullptr) { - // insert the texture into the map - this->textures.insert(std::make_pair(name, tex)); - } - - // and return the texture pointer. - return tex.get(); - } - - return tex_it->second.get(); -} - - -void AssetManager::check_updates() { -#if WITH_INOTIFY - // buffer for at least 4 inotify events - char buf[4 * (sizeof(struct inotify_event) + NAME_MAX + 1)]; - ssize_t len; - - while (true) { - // fetch all events, the kernel won't write "half" structs. - len = read(this->inotify_fd, buf, sizeof(buf)); - - if (len == -1) { - if (errno == EAGAIN) { - // no events, nothing to do. - break; - } - else { - // something went wrong - log::log(WARN << "Failed to read inotify events!"); - break; - } - } - - // process fetched events, - // the kernel guarantees complete events in the buffer. - char *ptr = buf; - while (ptr < buf + len) { - auto *event = reinterpret_cast(ptr); - - if (event->mask & IN_CLOSE_WRITE) { - // TODO: this should invoke callback functions - this->watch_fds[event->wd]->reload(); - } - - // move the buffer ptr to the next event. - ptr += sizeof(struct inotify_event) + event->len; - } - } -#endif -} - -std::shared_ptr AssetManager::get_missing_tex() { - // if not loaded, fetch the "missing" texture (big red X). - if (this->missing_tex.get() == nullptr) [[unlikely]] { - this->missing_tex = std::make_shared( - this->asset_path["test"]["textures"]["missing.png"], - false); - } - - return this->missing_tex; -} - -void AssetManager::clear() { -#if WITH_INOTIFY - for (auto &watch_fd : this->watch_fds) { - int result = inotify_rm_watch(this->inotify_fd, watch_fd.first); - if (result < 0) { - log::log(WARN << "Failed to remove inotify watches"); - } - } - this->watch_fds.clear(); -#endif - - this->textures.clear(); -} - -} // namespace openage diff --git a/libopenage/assets/assetmanager.h b/libopenage/assets/assetmanager.h deleted file mode 100644 index 5fff6b0328..0000000000 --- a/libopenage/assets/assetmanager.h +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include "config.h" - -#include -#include -#include - -#include "presenter/legacy/legacy.h" -#include "util/path.h" - -namespace qtsdl { -class GuiItemLink; -} // namespace qtsdl - -namespace openage { -class Texture; - -namespace gamestate { -class GameSimulation; -} - -/** - * Container class for all available assets. - * Responsible for loading, providing and updating requested files. - */ -class [[deprecated]] AssetManager final { -public: - explicit AssetManager(qtsdl::GuiItemLink *gui_link); - - /** - * Return the path where assets are found in. - */ - const util::Path &get_asset_dir(); - - /** - * Set the asset search path. - */ - void set_asset_dir(const util::Path &asset_dir); - - /** - * Set the game display of this asset manager. - * Called from QML. - */ - void set_display(presenter::LegacyDisplay *display); - - /** - * Return the display responsible for this asset manager. - */ - presenter::LegacyDisplay *get_display() const; - - /** - * Set the game engine of this asset manager. - * Called from QML. - */ - void set_engine(gamestate::GameSimulation *engine); - - /** - * Return the engine responsible for this asset manager. - */ - gamestate::GameSimulation *get_engine() const; - - /** - * Query the Texture for a given filename. - * - * @param name: the asset file name relative to the asset root. - * @param use_metafile: load subtexture information from meta file - * @param null_if_missing: instead of providing the "missing texture", - * return nullptr. - * @returns the queried texture handle. - */ - Texture *get_texture(const std::string &name, bool use_metafile = true, bool null_if_missing = false); - - /** - * Ask the kernel whether there were updates to watched files. - */ - void check_updates(); - -protected: - /** - * Create an internal texture handle. - */ - std::shared_ptr load_texture(const std::string &name, - bool use_metafile = true, - bool null_if_missing = false); - - /** - * Retrieves the texture for missing textures. - */ - std::shared_ptr get_missing_tex(); - -private: - void clear(); - - /** - * The display this asset manager is attached to. - */ - presenter::LegacyDisplay *display; - - /** - * The engine this asset manager is attached to. - */ - gamestate::GameSimulation *engine; - - /** - * The root directory for the available assets. - */ - util::Path asset_path; - - /** - * The replacement texture for missing textures. - */ - std::shared_ptr missing_tex; - - /** - * Map from texture filename to texture instance ptr. - */ - std::unordered_map> textures; - -#if WITH_INOTIFY - /** - * The file descriptor pointing to the inotify instance. - */ - int inotify_fd; - - /** - * Map from inotify watch handle fd to texture instance ptr. - * The kernel returns the handle fd when events are triggered. - */ - std::unordered_map> watch_fds; -#endif - -public: - qtsdl::GuiItemLink *gui_link; -}; - -} // namespace openage diff --git a/libopenage/presenter/CMakeLists.txt b/libopenage/presenter/CMakeLists.txt index d0fc81f7be..5041bacc2c 100644 --- a/libopenage/presenter/CMakeLists.txt +++ b/libopenage/presenter/CMakeLists.txt @@ -3,4 +3,3 @@ add_sources(libopenage ) add_subdirectory("legacy") -add_subdirectory("assets") diff --git a/libopenage/presenter/assets/CMakeLists.txt b/libopenage/presenter/assets/CMakeLists.txt deleted file mode 100644 index 59346cbc3e..0000000000 --- a/libopenage/presenter/assets/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_sources(libopenage - asset_manager.cpp -) diff --git a/libopenage/presenter/assets/asset_manager.cpp b/libopenage/presenter/assets/asset_manager.cpp deleted file mode 100644 index 0077d0db95..0000000000 --- a/libopenage/presenter/assets/asset_manager.cpp +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#include "asset_manager.h" - -#if WITH_INOTIFY -#include /* for NAME_MAX */ -#include -#include -#endif - -#include "error/error.h" -#include "log/log.h" -#include "texture.h" -#include "util/compiler.h" -#include "util/file.h" - -namespace openage::presenter { - -AssetManager::AssetManager() : - missing_tex{nullptr} { -#if WITH_INOTIFY - // initialize the inotify instance - this->inotify_fd = inotify_init1(IN_NONBLOCK); - if (this->inotify_fd < 0) { - throw Error{MSG(err) << "Failed to initialize inotify!"}; - } -#endif -} - -AssetManager::AssetManager(const util::Path &asset_dir) : - asset_dir{asset_dir}, - missing_tex{nullptr} { -#if WITH_INOTIFY - // initialize the inotify instance - this->inotify_fd = inotify_init1(IN_NONBLOCK); - if (this->inotify_fd < 0) { - throw Error{MSG(err) << "Failed to initialize inotify!"}; - } -#endif -} - - -const util::Path &AssetManager::get_asset_dir() { - return this->asset_dir; -} - - -void AssetManager::set_asset_dir(const util::Path &new_path) { - if (this->asset_dir != new_path) { - this->asset_dir = new_path; - this->clear(); - } -} - - -std::shared_ptr AssetManager::load_texture(const std::string &name, - bool use_metafile, - bool null_if_missing) { - // the texture to be associated with the given filename - std::shared_ptr tex; - - util::Path tex_path = this->asset_dir[name]; - - // try to open the texture filename. - if (not tex_path.is_file()) { - // TODO: add/fetch inotify watch on the containing folder - // to display the tex as soon at it exists. - - if (null_if_missing) { - return nullptr; - } - else { - // return the big X texture instead - tex = this->get_missing_tex(); - } - } - else { - // create the texture! - tex = std::make_shared(tex_path, use_metafile); - -#if WITH_INOTIFY - std::string native_path = tex_path.resolve_native_path(); - - if (native_path.size() > 0) { - // create inotify update trigger for the requested file - - // TODO: let util::Path do the file watching - int wd = inotify_add_watch( - this->inotify_fd, - native_path.c_str(), - IN_CLOSE_WRITE); - - if (wd < 0) { - log::log(WARN << "Failed to add inotify watch for " << native_path); - } - else { - this->watch_fds[wd] = tex; - } - } -#endif - } - - // pass back the shared_ptr - return tex; -} - - -Texture *AssetManager::get_texture(const std::string &name, bool use_metafile, bool null_if_missing) { - // check whether the requested texture was loaded already - auto tex_it = this->textures.find(name); - - // the texture was not loaded yet: - if (tex_it == this->textures.end()) { - auto tex = this->load_texture(name, use_metafile, null_if_missing); - - if (tex.get() != nullptr) { - // insert the texture into the map - this->textures.insert(std::make_pair(name, tex)); - } - - // and return the texture pointer. - return tex.get(); - } - - return tex_it->second.get(); -} - - -void AssetManager::check_updates() { -#if WITH_INOTIFY - // buffer for at least 4 inotify events - char buf[4 * (sizeof(struct inotify_event) + NAME_MAX + 1)]; - ssize_t len; - - while (true) { - // fetch all events, the kernel won't write "half" structs. - len = read(this->inotify_fd, buf, sizeof(buf)); - - if (len == -1) { - if (errno == EAGAIN) { - // no events, nothing to do. - break; - } - else { - // something went wrong - log::log(WARN << "Failed to read inotify events!"); - break; - } - } - - // process fetched events, - // the kernel guarantees complete events in the buffer. - char *ptr = buf; - while (ptr < buf + len) { - auto *event = reinterpret_cast(ptr); - - if (event->mask & IN_CLOSE_WRITE) { - // TODO: this should invoke callback functions - this->watch_fds[event->wd]->reload(); - } - - // move the buffer ptr to the next event. - ptr += sizeof(struct inotify_event) + event->len; - } - } -#endif -} - -std::shared_ptr AssetManager::get_missing_tex() { - // if not loaded, fetch the "missing" texture (big red X). - if (this->missing_tex.get() == nullptr) [[unlikely]] { - this->missing_tex = std::make_shared( - this->asset_dir["test"]["textures"]["missing.png"], - false); - } - - return this->missing_tex; -} - -void AssetManager::clear() { -#if WITH_INOTIFY - for (auto &watch_fd : this->watch_fds) { - int result = inotify_rm_watch(this->inotify_fd, watch_fd.first); - if (result < 0) { - log::log(WARN << "Failed to remove inotify watches"); - } - } - this->watch_fds.clear(); -#endif - - this->textures.clear(); -} - -} // namespace openage::presenter diff --git a/libopenage/presenter/assets/asset_manager.h b/libopenage/presenter/assets/asset_manager.h deleted file mode 100644 index fa3461501b..0000000000 --- a/libopenage/presenter/assets/asset_manager.h +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include "config.h" - -#include -#include -#include - -#include "util/path.h" - -namespace qtsdl { -class GuiItemLink; -} // namespace qtsdl - -namespace openage { -class Texture; -} // namespace openage - -namespace openage::presenter { - -/** - * Container class for all available assets. - * Responsible for loading, providing and updating requested files. - */ -class [[deprecated]] AssetManager final { -public: - AssetManager(); - AssetManager(const util::Path &asset_dir); - - /** - * Return the path where assets are found in. - */ - const util::Path &get_asset_dir(); - - /** - * Set the asset search path. - */ - void set_asset_dir(const util::Path &new_path); - - /** - * Query the Texture for a given filename. - * - * @param name: the asset file name relative to the asset root. - * @param use_metafile: load subtexture information from meta file - * @param null_if_missing: instead of providing the "missing texture", - * return nullptr. - * @returns the queried texture handle. - */ - Texture *get_texture(const std::string &name, - bool use_metafile = true, - bool null_if_missing = false); - - /** - * Ask the kernel whether there were updates to watched files. - */ - void check_updates(); - -protected: - /** - * Create an internal texture handle. - */ - std::shared_ptr load_texture(const std::string &name, - bool use_metafile = true, - bool null_if_missing = false); - - /** - * Retrieves the texture for missing textures. - */ - std::shared_ptr get_missing_tex(); - -private: - void clear(); - - /** - * The root directory for the available assets. - */ - util::Path asset_dir; - - /** - * The replacement texture for missing textures. - */ - std::shared_ptr missing_tex; - - /** - * Map from texture filename to texture instance ptr. - */ - std::unordered_map> textures; - -#if WITH_INOTIFY - /** - * The file descriptor pointing to the inotify instance. - */ - int inotify_fd; - - /** - * Map from inotify watch handle fd to texture instance ptr. - * The kernel returns the handle fd when events are triggered. - */ - std::unordered_map> watch_fds; -#endif -}; - -} // namespace openage::presenter diff --git a/libopenage/renderer/gui/CMakeLists.txt b/libopenage/renderer/gui/CMakeLists.txt index 60a1676d76..a0a61a9b62 100644 --- a/libopenage/renderer/gui/CMakeLists.txt +++ b/libopenage/renderer/gui/CMakeLists.txt @@ -1,5 +1,4 @@ add_sources(libopenage - assetmanager_link.cpp engine_link.cpp gui.cpp qml_info.cpp diff --git a/libopenage/renderer/gui/assetmanager_link.cpp b/libopenage/renderer/gui/assetmanager_link.cpp deleted file mode 100644 index 600cf51ffb..0000000000 --- a/libopenage/renderer/gui/assetmanager_link.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "assetmanager_link.h" - -#include - -#include "renderer/gui/engine_link.h" - -namespace openage { - -class LegacyEngine; - -namespace renderer { -namespace gui { - -namespace { -const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "AssetManager"); -} - -AssetManagerLink::AssetManagerLink(QObject *parent) : - GuiItemQObject{parent}, - GuiItem{this} { - Q_UNUSED(registration); -} - -AssetManagerLink::~AssetManagerLink() = default; - - -const util::Path &AssetManagerLink::get_asset_dir() const { - return this->asset_dir; -} - - -void AssetManagerLink::set_asset_dir(const util::Path &asset_dir) { - static auto f = [](AssetManager *_this, const util::Path &dir) { - _this->set_asset_dir(dir); - }; - this->s(f, this->asset_dir, asset_dir); -} - - -EngineLink *AssetManagerLink::get_engine() const { - return this->engine; -} - - -void AssetManagerLink::set_engine(EngineLink *engine_link) { - static auto f = [](AssetManager *_this, gamestate::GameSimulation *engine) { - _this->set_engine(engine); - }; - this->s(f, this->engine, engine_link); -} - - -} // namespace gui -} // namespace renderer -} // namespace openage diff --git a/libopenage/renderer/gui/assetmanager_link.h b/libopenage/renderer/gui/assetmanager_link.h deleted file mode 100644 index 3378558855..0000000000 --- a/libopenage/renderer/gui/assetmanager_link.h +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include "assets/assetmanager.h" -#include "gui/guisys/link/gui_item.h" -#include "util/path.h" - - -namespace openage { -namespace renderer::gui { -class AssetManagerLink; -class EngineLink; -} // namespace renderer::gui -} // namespace openage - -namespace qtsdl { -template <> -struct Wrap { - using Type = openage::renderer::gui::AssetManagerLink; -}; - -template <> -struct Unwrap { - using Type = openage::AssetManager; -}; - -} // namespace qtsdl - - -namespace openage { -namespace renderer { -namespace gui { - -class AssetManagerLink : public qtsdl::GuiItemQObject - , public qtsdl::GuiItem { - Q_OBJECT - - Q_PROPERTY(openage::util::Path assetDir READ get_asset_dir WRITE set_asset_dir) - Q_MOC_INCLUDE("renderer/gui/engine_link.h") - Q_PROPERTY(EngineLink *engine READ get_engine WRITE set_engine) - -public: - explicit AssetManagerLink(QObject *parent = nullptr); - virtual ~AssetManagerLink(); - - const util::Path &get_asset_dir() const; - void set_asset_dir(const util::Path &data_dir); - - EngineLink *get_engine() const; - void set_engine(EngineLink *engine); - -private: - util::Path asset_dir; - EngineLink *engine; -}; - -} // namespace gui -} // namespace renderer -} // namespace openage From c3c4a22dcf5dd93a6b51197dd1fdaf24b099c446 Mon Sep 17 00:00:00 2001 From: heinezen Date: Fri, 22 Sep 2023 23:03:54 +0200 Subject: [PATCH 28/95] assets: Remove old asset management entirely. --- libopenage/assets/CMakeLists.txt | 1 - libopenage/assets/legacy_assetmanager.cpp | 207 ------------ libopenage/assets/legacy_assetmanager.h | 137 -------- libopenage/gamestate/old/game_spec.cpp | 364 ++++++++++------------ libopenage/gamestate/old/game_spec.h | 22 +- libopenage/gui/CMakeLists.txt | 1 - libopenage/gui/assetmanager_link.cpp | 55 ---- libopenage/gui/assetmanager_link.h | 58 ---- libopenage/gui/game_spec_link.cpp | 25 +- libopenage/gui/game_spec_link.h | 6 - libopenage/terrain/terrain.h | 2 +- 11 files changed, 174 insertions(+), 704 deletions(-) delete mode 100644 libopenage/assets/legacy_assetmanager.cpp delete mode 100644 libopenage/assets/legacy_assetmanager.h delete mode 100644 libopenage/gui/assetmanager_link.cpp delete mode 100644 libopenage/gui/assetmanager_link.h diff --git a/libopenage/assets/CMakeLists.txt b/libopenage/assets/CMakeLists.txt index 8384d7d988..234ac3b1b0 100644 --- a/libopenage/assets/CMakeLists.txt +++ b/libopenage/assets/CMakeLists.txt @@ -1,5 +1,4 @@ add_sources(libopenage - legacy_assetmanager.cpp mod_manager.cpp modpack.cpp ) diff --git a/libopenage/assets/legacy_assetmanager.cpp b/libopenage/assets/legacy_assetmanager.cpp deleted file mode 100644 index 1058aee26e..0000000000 --- a/libopenage/assets/legacy_assetmanager.cpp +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -/** - * TODO: Deprecated in favor of presenter/assets/asset_manager.h - * - */ - -#include "legacy_assetmanager.h" - -#if WITH_INOTIFY -#include /* for NAME_MAX */ -#include -#include -#endif - -#include "error/error.h" -#include "log/log.h" -#include "util/compiler.h" -#include "util/file.h" - -#include "texture.h" - -namespace openage { - -LegacyAssetManager::LegacyAssetManager(qtsdl::GuiItemLink *gui_link) : - missing_tex{nullptr}, - gui_link{gui_link} { -#if WITH_INOTIFY - // initialize the inotify instance - this->inotify_fd = inotify_init1(IN_NONBLOCK); - if (this->inotify_fd < 0) { - throw Error{MSG(err) << "Failed to initialize inotify!"}; - } -#endif -} - - -const util::Path &LegacyAssetManager::get_asset_dir() { - return this->asset_path; -} - - -void LegacyAssetManager::set_asset_dir(const util::Path &new_path) { - if (this->asset_path != new_path) { - this->asset_path = new_path; - this->clear(); - } -} - - -void LegacyAssetManager::set_display(presenter::LegacyDisplay *display) { - this->display = display; -} - - -presenter::LegacyDisplay *LegacyAssetManager::get_display() const { - return this->display; -} - -void LegacyAssetManager::set_engine(LegacyEngine *engine) { - this->engine = engine; -} - -LegacyEngine *LegacyAssetManager::get_engine() const { - return this->engine; -} - - -std::shared_ptr LegacyAssetManager::load_texture(const std::string &name, - bool use_metafile, - bool null_if_missing) { - // the texture to be associated with the given filename - std::shared_ptr tex; - - util::Path tex_path = this->asset_path[name]; - - // try to open the texture filename. - if (not tex_path.is_file()) { - // TODO: add/fetch inotify watch on the containing folder - // to display the tex as soon at it exists. - - if (null_if_missing) { - return nullptr; - } - else { - // return the big X texture instead - tex = this->get_missing_tex(); - } - } - else { - // create the texture! - tex = std::make_shared(tex_path, use_metafile); - -#if WITH_INOTIFY - std::string native_path = tex_path.resolve_native_path(); - - if (native_path.size() > 0) { - // create inotify update trigger for the requested file - - // TODO: let util::Path do the file watching - int wd = inotify_add_watch( - this->inotify_fd, - native_path.c_str(), - IN_CLOSE_WRITE); - - if (wd < 0) { - log::log(WARN << "Failed to add inotify watch for " << native_path); - } - else { - this->watch_fds[wd] = tex; - } - } -#endif - } - - // pass back the shared_ptr - return tex; -} - - -Texture *LegacyAssetManager::get_texture(const std::string &name, bool use_metafile, bool null_if_missing) { - // check whether the requested texture was loaded already - auto tex_it = this->textures.find(name); - - // the texture was not loaded yet: - if (tex_it == this->textures.end()) { - auto tex = this->load_texture(name, use_metafile, null_if_missing); - - if (tex.get() != nullptr) { - // insert the texture into the map - this->textures.insert(std::make_pair(name, tex)); - } - - // and return the texture pointer. - return tex.get(); - } - - return tex_it->second.get(); -} - - -void LegacyAssetManager::check_updates() { -#if WITH_INOTIFY - // buffer for at least 4 inotify events - char buf[4 * (sizeof(struct inotify_event) + NAME_MAX + 1)]; - ssize_t len; - - while (true) { - // fetch all events, the kernel won't write "half" structs. - len = read(this->inotify_fd, buf, sizeof(buf)); - - if (len == -1) { - if (errno == EAGAIN) { - // no events, nothing to do. - break; - } - else { - // something went wrong - log::log(WARN << "Failed to read inotify events!"); - break; - } - } - - // process fetched events, - // the kernel guarantees complete events in the buffer. - char *ptr = buf; - while (ptr < buf + len) { - auto *event = reinterpret_cast(ptr); - - if (event->mask & IN_CLOSE_WRITE) { - // TODO: this should invoke callback functions - this->watch_fds[event->wd]->reload(); - } - - // move the buffer ptr to the next event. - ptr += sizeof(struct inotify_event) + event->len; - } - } -#endif -} - -std::shared_ptr LegacyAssetManager::get_missing_tex() { - // if not loaded, fetch the "missing" texture (big red X). - if (this->missing_tex.get() == nullptr) [[unlikely]] { - this->missing_tex = std::make_shared( - this->asset_path["test"]["textures"]["missing.png"], - false); - } - - return this->missing_tex; -} - -void LegacyAssetManager::clear() { -#if WITH_INOTIFY - for (auto &watch_fd : this->watch_fds) { - int result = inotify_rm_watch(this->inotify_fd, watch_fd.first); - if (result < 0) { - log::log(WARN << "Failed to remove inotify watches"); - } - } - this->watch_fds.clear(); -#endif - - this->textures.clear(); -} - -} // namespace openage diff --git a/libopenage/assets/legacy_assetmanager.h b/libopenage/assets/legacy_assetmanager.h deleted file mode 100644 index c4436007e9..0000000000 --- a/libopenage/assets/legacy_assetmanager.h +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include "config.h" - -#include -#include -#include - -#include "presenter/legacy/legacy.h" -#include "util/path.h" - -namespace qtsdl { -class GuiItemLink; -} // namespace qtsdl - -namespace openage { - -class LegacyEngine; -class Texture; - -/** - * Container class for all available assets. - * Responsible for loading, providing and updating requested files. - */ -class [[deprecated]] LegacyAssetManager final { -public: - explicit LegacyAssetManager(qtsdl::GuiItemLink *gui_link); - - /** - * Return the path where assets are found in. - */ - const util::Path &get_asset_dir(); - - /** - * Set the asset search path. - */ - void set_asset_dir(const util::Path &asset_dir); - - /** - * Set the game display of this asset manager. - * Called from QML. - */ - void set_display(presenter::LegacyDisplay *display); - - /** - * Return the display responsible for this asset manager. - */ - presenter::LegacyDisplay *get_display() const; - - /** - * Set the game engine of this asset manager. - * Called from QML. - */ - void set_engine(LegacyEngine *engine); - - /** - * Return the engine responsible for this asset manager. - */ - LegacyEngine *get_engine() const; - - /** - * Query the Texture for a given filename. - * - * @param name: the asset file name relative to the asset root. - * @param use_metafile: load subtexture information from meta file - * @param null_if_missing: instead of providing the "missing texture", - * return nullptr. - * @returns the queried texture handle. - */ - Texture *get_texture(const std::string &name, bool use_metafile = true, bool null_if_missing = false); - - /** - * Ask the kernel whether there were updates to watched files. - */ - void check_updates(); - -protected: - /** - * Create an internal texture handle. - */ - std::shared_ptr load_texture(const std::string &name, - bool use_metafile = true, - bool null_if_missing = false); - - /** - * Retrieves the texture for missing textures. - */ - std::shared_ptr get_missing_tex(); - -private: - void clear(); - - /** - * The display this asset manager is attached to. - */ - presenter::LegacyDisplay *display; - - /** - * The engine this asset manager is attached to. - */ - LegacyEngine *engine; - - /** - * The root directory for the available assets. - */ - util::Path asset_path; - - /** - * The replacement texture for missing textures. - */ - std::shared_ptr missing_tex; - - /** - * Map from texture filename to texture instance ptr. - */ - std::unordered_map> textures; - -#if WITH_INOTIFY - /** - * The file descriptor pointing to the inotify instance. - */ - int inotify_fd; - - /** - * Map from inotify watch handle fd to texture instance ptr. - * The kernel returns the handle fd when events are triggered. - */ - std::unordered_map> watch_fds; -#endif - -public: - qtsdl::GuiItemLink *gui_link; -}; - -} // namespace openage diff --git a/libopenage/gamestate/old/game_spec.cpp b/libopenage/gamestate/old/game_spec.cpp index c35528d62f..048fbc4ce9 100644 --- a/libopenage/gamestate/old/game_spec.cpp +++ b/libopenage/gamestate/old/game_spec.cpp @@ -6,24 +6,22 @@ #include "../../audio/error.h" #include "../../audio/resource_def.h" -#include "../../legacy_engine.h" #include "../../gamedata/blending_mode_dummy.h" #include "../../gamedata/string_resource_dummy.h" #include "../../gamedata/terrain_dummy.h" +#include "../../legacy_engine.h" #include "../../log/log.h" #include "../../rng/global_rng.h" #include "../../unit/producer.h" #include "../../util/compiler.h" #include "../../util/strings.h" #include "../../util/timer.h" -#include "assets/legacy_assetmanager.h" #include "civilisation.h" namespace openage { -GameSpec::GameSpec(LegacyAssetManager *am) : - assetmanager{am}, +GameSpec::GameSpec() : gamedata_loaded{false} { } @@ -34,38 +32,38 @@ bool GameSpec::initialize() { util::Timer load_timer; load_timer.start(); - const util::Path &asset_dir = this->assetmanager->get_asset_dir(); + // const util::Path &asset_dir = this->assetmanager->get_asset_dir(); - log::log(MSG(info) << "Loading game specification files..."); + // log::log(MSG(info) << "Loading game specification files..."); - std::vector string_resources = util::read_csv_file( - asset_dir["converted/string_resources.docx"]); + // std::vector string_resources = util::read_csv_file( + // asset_dir["converted/string_resources.docx"]); - try { - // read the packed csv file - util::CSVCollection raw_gamedata{ - asset_dir["converted/gamedata/gamedata.docx"]}; + // try { + // // read the packed csv file + // util::CSVCollection raw_gamedata{ + // asset_dir["converted/gamedata/gamedata.docx"]}; - // parse the original game description files - this->gamedata = raw_gamedata.read( - "gamedata-empiresdat.docx"); + // // parse the original game description files + // this->gamedata = raw_gamedata.read( + // "gamedata-empiresdat.docx"); - this->load_terrain(this->gamedata[0]); + // this->load_terrain(this->gamedata[0]); - // process and load the game description files - this->on_gamedata_loaded(this->gamedata[0]); - this->gamedata_loaded = true; - } - catch (Error &exc) { - // rethrow allmighty openage exceptions - throw; - } - catch (std::exception &exc) { - // unfortunately we have no idea of the std::exception backtrace - throw Error{ERR << "gamedata could not be loaded: " - << util::typestring(exc) - << ": " << exc.what()}; - } + // // process and load the game description files + // this->on_gamedata_loaded(this->gamedata[0]); + // this->gamedata_loaded = true; + // } + // catch (Error &exc) { + // // rethrow allmighty openage exceptions + // throw; + // } + // catch (std::exception &exc) { + // // unfortunately we have no idea of the std::exception backtrace + // throw Error{ERR << "gamedata could not be loaded: " + // << util::typestring(exc) + // << ": " << exc.what()}; + // } log::log(MSG(info).fmt("Loading time [data]: %5.3f s", load_timer.getval() / 1e9)); @@ -105,7 +103,8 @@ Texture *GameSpec::get_texture(index_t graphic_id) const { Texture *GameSpec::get_texture(const std::string &file_name, bool use_metafile) const { // return nullptr if the texture wasn't found (3rd param) - return this->assetmanager->get_texture(file_name, use_metafile, true); + // return this->assetmanager->get_texture(file_name, use_metafile, true); + return nullptr; } std::shared_ptr GameSpec::get_unit_texture(index_t unit_id) const { @@ -179,85 +178,79 @@ void GameSpec::create_unit_types(unit_meta_list &objects, int civ_id) const { } } +void GameSpec::on_gamedata_loaded(const gamedata::empiresdat &gamedata) { + // const util::Path &asset_dir = this->assetmanager->get_asset_dir(); + // util::Path sound_dir = asset_dir["converted/sounds"]; -LegacyAssetManager *GameSpec::get_asset_manager() const { - return this->assetmanager; -} + // // create graphic id => graphic map + // for (auto &graphic : gamedata.graphics.data) { + // this->graphics[graphic.graphic_id] = &graphic; + // this->slp_to_graphic[graphic.slp_id] = graphic.graphic_id; + // } + // log::log(INFO << "Loading textures..."); -void GameSpec::on_gamedata_loaded(const gamedata::empiresdat &gamedata) { - const util::Path &asset_dir = this->assetmanager->get_asset_dir(); - util::Path sound_dir = asset_dir["converted/sounds"]; + // // create complete set of unit textures + // for (auto &g : this->graphics) { + // this->unit_textures.insert({g.first, std::make_shared(*this, g.second)}); + // } - // create graphic id => graphic map - for (auto &graphic : gamedata.graphics.data) { - this->graphics[graphic.graphic_id] = &graphic; - this->slp_to_graphic[graphic.slp_id] = graphic.graphic_id; - } + // log::log(INFO << "Loading sounds..."); - log::log(INFO << "Loading textures..."); + // // playable sound files for the audio manager + // std::vector load_sound_files; - // create complete set of unit textures - for (auto &g : this->graphics) { - this->unit_textures.insert({g.first, std::make_shared(*this, g.second)}); - } + // // all sounds defined in the game specification + // for (const gamedata::sound &sound : gamedata.sounds.data) { + // std::vector sound_items; - log::log(INFO << "Loading sounds..."); - - // playable sound files for the audio manager - std::vector load_sound_files; - - // all sounds defined in the game specification - for (const gamedata::sound &sound : gamedata.sounds.data) { - std::vector sound_items; - - // each sound may have multiple variation, - // processed in this loop - // these are the single sound files. - for (const gamedata::sound_item &item : sound.sound_items.data) { - if (item.resource_id < 0) { - log::log(SPAM << " Invalid sound resource id < 0"); - continue; - } - - std::string snd_filename = util::sformat("%d.opus", item.resource_id); - util::Path snd_path = sound_dir[snd_filename]; - - if (not snd_path.is_file()) { - continue; - } - - // single items for a sound (so that we can ramdomize it) - sound_items.push_back(item.resource_id); - - // the single sound will be loaded in the audio system. - audio::resource_def resource{ - audio::category_t::GAME, - item.resource_id, - snd_path, - audio::format_t::OPUS, - audio::loader_policy_t::DYNAMIC}; - load_sound_files.push_back(resource); - } + // // each sound may have multiple variation, + // // processed in this loop + // // these are the single sound files. + // for (const gamedata::sound_item &item : sound.sound_items.data) { + // if (item.resource_id < 0) { + // log::log(SPAM << " Invalid sound resource id < 0"); + // continue; + // } + // std::string snd_filename = util::sformat("%d.opus", item.resource_id); + // util::Path snd_path = sound_dir[snd_filename]; - // create test sound objects that can be played later - this->available_sounds.insert({sound.sound_id, - Sound{ - this, - std::move(sound_items)}}); - } + // if (not snd_path.is_file()) { + // continue; + // } + + // // single items for a sound (so that we can ramdomize it) + // sound_items.push_back(item.resource_id); + + // // the single sound will be loaded in the audio system. + // audio::resource_def resource{ + // audio::category_t::GAME, + // item.resource_id, + // snd_path, + // audio::format_t::OPUS, + // audio::loader_policy_t::DYNAMIC}; + // load_sound_files.push_back(resource); + // } + + + // // create test sound objects that can be played later + // this->available_sounds.insert({sound.sound_id, + // Sound{ + // this, + // std::move(sound_items)}}); + // } - // TODO: move out the loading of the sound. - // this class only provides the names and locations + // // TODO: move out the loading of the sound. + // // this class only provides the names and locations - // load the requested sounds. - audio::AudioManager &am = this->assetmanager->get_display()->get_audio_manager(); - am.load_resources(load_sound_files); + // // load the requested sounds. + // audio::AudioManager &am = this->assetmanager->get_display()->get_audio_manager(); + // am.load_resources(load_sound_files); - // this final step occurs after loading media - // as producers require both the graphics and sounds - this->create_abilities(gamedata); + // // this final step occurs after loading media + // // as producers require both the graphics and sounds + // this->create_abilities(gamedata); } bool GameSpec::valid_graphic_id(index_t graphic_id) const { @@ -313,69 +306,69 @@ void GameSpec::load_missile(const gamedata::missile_unit &proj, unit_meta_list & void GameSpec::load_terrain(const gamedata::empiresdat &gamedata) { // fetch blending modes - util::Path convert_dir = this->assetmanager->get_asset_dir()["converted"]; - std::vector blending_meta = util::read_csv_file( - convert_dir["blending_modes.docx"]); - - // copy the terrain metainformation - std::vector terrain_meta = gamedata.terrains.data; - - // remove any disabled textures - terrain_meta.erase( - std::remove_if( - terrain_meta.begin(), - terrain_meta.end(), - [](const gamedata::terrain_type &t) { - return not t.enabled; - }), - terrain_meta.end()); - - // result attributes - this->terrain_data.terrain_id_count = terrain_meta.size(); - this->terrain_data.blendmode_count = blending_meta.size(); - this->terrain_data.textures.resize(terrain_data.terrain_id_count); - this->terrain_data.blending_masks.reserve(terrain_data.blendmode_count); - this->terrain_data.terrain_id_priority_map = std::make_unique( - this->terrain_data.terrain_id_count); - this->terrain_data.terrain_id_blendmode_map = std::make_unique( - this->terrain_data.terrain_id_count); - this->terrain_data.influences_buf = std::make_unique( - this->terrain_data.terrain_id_count); - - - log::log(MSG(dbg) << "Terrain prefs: " - << "tiletypes=" << terrain_data.terrain_id_count << ", " - "blendmodes=" - << terrain_data.blendmode_count); - - // create tile textures (snow, ice, grass, whatever) - for (size_t terrain_id = 0; - terrain_id < terrain_data.terrain_id_count; - terrain_id++) { - auto line = &terrain_meta[terrain_id]; - - // TODO: terrain double-define check? - terrain_data.terrain_id_priority_map[terrain_id] = line->blend_priority; - terrain_data.terrain_id_blendmode_map[terrain_id] = line->blend_mode; - - // TODO: remove hardcoding and rely on nyan data - auto terraintex_filename = util::sformat("converted/terrain/%d.slp.png", - line->slp_id); - - auto new_texture = this->assetmanager->get_texture(terraintex_filename, true); - - terrain_data.textures[terrain_id] = new_texture; - } - - // create blending masks (see doc/media/blendomatic) - for (size_t i = 0; i < terrain_data.blendmode_count; i++) { - auto line = &blending_meta[i]; - - // TODO: remove hardcodingn and use nyan data - std::string mask_filename = util::sformat("converted/blendomatic/mode%02d.png", - line->blend_mode); - terrain_data.blending_masks[i] = this->assetmanager->get_texture(mask_filename); - } + // util::Path convert_dir = this->assetmanager->get_asset_dir()["converted"]; + // std::vector blending_meta = util::read_csv_file( + // convert_dir["blending_modes.docx"]); + + // // copy the terrain metainformation + // std::vector terrain_meta = gamedata.terrains.data; + + // // remove any disabled textures + // terrain_meta.erase( + // std::remove_if( + // terrain_meta.begin(), + // terrain_meta.end(), + // [](const gamedata::terrain_type &t) { + // return not t.enabled; + // }), + // terrain_meta.end()); + + // // result attributes + // this->terrain_data.terrain_id_count = terrain_meta.size(); + // this->terrain_data.blendmode_count = blending_meta.size(); + // this->terrain_data.textures.resize(terrain_data.terrain_id_count); + // this->terrain_data.blending_masks.reserve(terrain_data.blendmode_count); + // this->terrain_data.terrain_id_priority_map = std::make_unique( + // this->terrain_data.terrain_id_count); + // this->terrain_data.terrain_id_blendmode_map = std::make_unique( + // this->terrain_data.terrain_id_count); + // this->terrain_data.influences_buf = std::make_unique( + // this->terrain_data.terrain_id_count); + + + // log::log(MSG(dbg) << "Terrain prefs: " + // << "tiletypes=" << terrain_data.terrain_id_count << ", " + // "blendmodes=" + // << terrain_data.blendmode_count); + + // // create tile textures (snow, ice, grass, whatever) + // for (size_t terrain_id = 0; + // terrain_id < terrain_data.terrain_id_count; + // terrain_id++) { + // auto line = &terrain_meta[terrain_id]; + + // // TODO: terrain double-define check? + // terrain_data.terrain_id_priority_map[terrain_id] = line->blend_priority; + // terrain_data.terrain_id_blendmode_map[terrain_id] = line->blend_mode; + + // // TODO: remove hardcoding and rely on nyan data + // auto terraintex_filename = util::sformat("converted/terrain/%d.slp.png", + // line->slp_id); + + // auto new_texture = this->assetmanager->get_texture(terraintex_filename, true); + + // terrain_data.textures[terrain_id] = new_texture; + // } + + // // create blending masks (see doc/media/blendomatic) + // for (size_t i = 0; i < terrain_data.blendmode_count; i++) { + // auto line = &blending_meta[i]; + + // // TODO: remove hardcodingn and use nyan data + // std::string mask_filename = util::sformat("converted/blendomatic/mode%02d.png", + // line->blend_mode); + // terrain_data.blending_masks[i] = this->assetmanager->get_texture(mask_filename); + // } } @@ -413,25 +406,24 @@ void Sound::play() const { int rand = rng::random_range(0, this->sound_items.size()); int sndid = this->sound_items.at(rand); - try { - // TODO: buhuuuu gnargghh this has to be moved to the asset loading subsystem hnnnng - audio::AudioManager &am = this->game_spec->get_asset_manager()->get_display()->get_audio_manager(); + // try { + // // TODO: buhuuuu gnargghh this has to be moved to the asset loading subsystem hnnnng + // audio::AudioManager &am = this->game_spec->get_asset_manager()->get_display()->get_audio_manager(); - if (not am.is_available()) { - return; - } + // if (not am.is_available()) { + // return; + // } - audio::Sound sound = am.get_sound(audio::category_t::GAME, sndid); - sound.play(); - } - catch (audio::Error &e) { - log::log(MSG(warn) << "cannot play: " << e); - } + // audio::Sound sound = am.get_sound(audio::category_t::GAME, sndid); + // sound.play(); + // } + // catch (audio::Error &e) { + // log::log(MSG(warn) << "cannot play: " << e); + // } } GameSpecHandle::GameSpecHandle(qtsdl::GuiItemLink *gui_link) : active{}, - asset_manager{}, gui_signals{std::make_shared()}, gui_link{gui_link} { } @@ -442,14 +434,6 @@ void GameSpecHandle::set_active(bool active) { this->start_loading_if_needed(); } -void GameSpecHandle::set_asset_manager(LegacyAssetManager *asset_manager) { - if (this->asset_manager != asset_manager) { - this->asset_manager = asset_manager; - - this->start_loading_if_needed(); - } -} - bool GameSpecHandle::is_ready() const { return this->spec && this->spec->load_complete(); } @@ -457,9 +441,6 @@ bool GameSpecHandle::is_ready() const { void GameSpecHandle::invalidate() { this->spec = nullptr; - if (this->asset_manager) - this->asset_manager->check_updates(); - this->start_loading_if_needed(); } @@ -473,13 +454,6 @@ std::shared_ptr GameSpecHandle::get_spec() { } void GameSpecHandle::start_loading_if_needed() { - if (this->active && this->asset_manager && !this->spec) { - // create the game specification - this->spec = std::make_shared(this->asset_manager); - - // the load the data - this->start_load_job(); - } } void GameSpecHandle::start_load_job() { @@ -512,12 +486,6 @@ void GameSpecHandle::start_load_job() { emit gui_signals_ptr->load_job_finished(); } }; - - job::JobManager *job_mgr = this->asset_manager->get_engine()->get_job_manager(); - - std::get>(*spec_and_job_ptr) = job_mgr->enqueue( - perform_load, - load_finished); } } // namespace openage diff --git a/libopenage/gamestate/old/game_spec.h b/libopenage/gamestate/old/game_spec.h index c5a9a66348..0fc34dcd40 100644 --- a/libopenage/gamestate/old/game_spec.h +++ b/libopenage/gamestate/old/game_spec.h @@ -10,8 +10,8 @@ #include "terrain/terrain.h" #include "types.h" -#include #include +#include #include @@ -65,7 +65,7 @@ class Sound { */ class GameSpec { public: - GameSpec(LegacyAssetManager *am); + GameSpec(); virtual ~GameSpec(); /** @@ -133,12 +133,6 @@ class GameSpec { */ void create_unit_types(unit_meta_list &objects, int civ_id) const; - /** - * Return the asset manager used for loading resources - * of this game specification. - */ - LegacyAssetManager *get_asset_manager() const; - private: /** * check graphic id is valid @@ -181,11 +175,6 @@ class GameSpec { */ void on_gamedata_loaded(const gamedata::empiresdat &gamedata); - /** - * Asset management entity that is responsible for textures, sounds, etc. - */ - LegacyAssetManager *assetmanager; - /** * The full original gamedata tree. */ @@ -253,11 +242,6 @@ class GameSpecHandle { */ void set_active(bool active); - /** - * invoked from qml when the asset_manager member is set. - */ - void set_asset_manager(LegacyAssetManager *asset_manager); - /** * Return if the specification was fully loaded. */ @@ -305,8 +289,6 @@ class GameSpecHandle { */ bool active; - LegacyAssetManager *asset_manager; - public: std::shared_ptr gui_signals; qtsdl::GuiItemLink *gui_link; diff --git a/libopenage/gui/CMakeLists.txt b/libopenage/gui/CMakeLists.txt index e63046c401..1697bc8d78 100644 --- a/libopenage/gui/CMakeLists.txt +++ b/libopenage/gui/CMakeLists.txt @@ -1,5 +1,4 @@ add_sources(libopenage - assetmanager_link.cpp actions_list_model.cpp category_contents_list_model.cpp engine_info.cpp diff --git a/libopenage/gui/assetmanager_link.cpp b/libopenage/gui/assetmanager_link.cpp deleted file mode 100644 index 7d05bd5564..0000000000 --- a/libopenage/gui/assetmanager_link.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "assetmanager_link.h" - -#include - -#include "engine_link.h" - -namespace openage { - -class LegacyEngine; - -namespace gui { - -namespace { -const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "LegacyAssetManager"); -} - -AssetManagerLink::AssetManagerLink(QObject *parent) : - GuiItemQObject{parent}, - GuiItem{this} { - Q_UNUSED(registration); -} - -AssetManagerLink::~AssetManagerLink() = default; - - -const util::Path &AssetManagerLink::get_asset_dir() const { - return this->asset_dir; -} - - -void AssetManagerLink::set_asset_dir(const util::Path &asset_dir) { - static auto f = [](LegacyAssetManager *_this, const util::Path &dir) { - _this->set_asset_dir(dir); - }; - this->s(f, this->asset_dir, asset_dir); -} - - -EngineLink *AssetManagerLink::get_engine() const { - return this->engine; -} - - -void AssetManagerLink::set_engine(EngineLink *engine_link) { - static auto f = [](LegacyAssetManager *_this, LegacyEngine *engine) { - _this->set_engine(engine); - }; - this->s(f, this->engine, engine_link); -} - - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/assetmanager_link.h b/libopenage/gui/assetmanager_link.h deleted file mode 100644 index effa0abc33..0000000000 --- a/libopenage/gui/assetmanager_link.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include "../util/path.h" -#include "assets/legacy_assetmanager.h" -#include "guisys/link/gui_item.h" - - -namespace openage { -namespace gui { -class AssetManagerLink; -class EngineLink; -} // namespace gui -} // namespace openage - -namespace qtsdl { -template <> -struct Wrap { - using Type = openage::gui::AssetManagerLink; -}; - -template <> -struct Unwrap { - using Type = openage::LegacyAssetManager; -}; - -} // namespace qtsdl - - -namespace openage { -namespace gui { - -class AssetManagerLink : public qtsdl::GuiItemQObject - , public qtsdl::GuiItem { - Q_OBJECT - - Q_PROPERTY(openage::util::Path assetDir READ get_asset_dir WRITE set_asset_dir) - Q_MOC_INCLUDE("gui/engine_link.h") - Q_PROPERTY(openage::gui::EngineLink *engine READ get_engine WRITE set_engine) - -public: - explicit AssetManagerLink(QObject *parent = nullptr); - virtual ~AssetManagerLink(); - - const util::Path &get_asset_dir() const; - void set_asset_dir(const util::Path &data_dir); - - EngineLink *get_engine() const; - void set_engine(EngineLink *engine); - -private: - util::Path asset_dir; - EngineLink *engine; -}; - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/game_spec_link.cpp b/libopenage/gui/game_spec_link.cpp index dea041ce5c..be8ebf6bb1 100644 --- a/libopenage/gui/game_spec_link.cpp +++ b/libopenage/gui/game_spec_link.cpp @@ -4,23 +4,19 @@ #include -#include "assetmanager_link.h" - namespace openage::gui { namespace { const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "GameSpec"); const int registration_of_ptr = qRegisterMetaType>("shared_ptr"); -} +} // namespace -GameSpecLink::GameSpecLink(QObject *parent) - : +GameSpecLink::GameSpecLink(QObject *parent) : GuiItemQObject{parent}, QQmlParserStatus{}, GuiItem{this}, state{}, active{}, - asset_manager{}, terrain_id_count{} { Q_UNUSED(registration); Q_UNUSED(registration_of_ptr); @@ -42,7 +38,7 @@ void GameSpecLink::componentComplete() { } void GameSpecLink::on_load_job_finished() { - static auto f = [] (GameSpecHandle *_this) { + static auto f = [](GameSpecHandle *_this) { _this->announce_spec(); }; this->i(f); @@ -69,7 +65,7 @@ GameSpecLink::State GameSpecLink::get_state() const { } void GameSpecLink::invalidate() { - static auto f = [] (GameSpecHandle *_this) { + static auto f = [](GameSpecHandle *_this) { _this->invalidate(); }; this->i(f); @@ -82,7 +78,7 @@ bool GameSpecLink::get_active() const { } void GameSpecLink::set_active(bool active) { - static auto f = [] (GameSpecHandle *_this, bool active) { + static auto f = [](GameSpecHandle *_this, bool active) { _this->set_active(active); }; this->s(f, this->active, active); @@ -90,17 +86,6 @@ void GameSpecLink::set_active(bool active) { this->set_state(this->active && this->state == State::Null ? State::Loading : this->state); } -AssetManagerLink* GameSpecLink::get_asset_manager() const { - return this->asset_manager; -} - -void GameSpecLink::set_asset_manager(AssetManagerLink *asset_manager) { - static auto f = [] (GameSpecHandle *_this, LegacyAssetManager *asset_manager) { - _this->set_asset_manager(asset_manager); - }; - this->s(f, this->asset_manager, asset_manager); -} - int GameSpecLink::get_terrain_id_count() const { return this->terrain_id_count; } diff --git a/libopenage/gui/game_spec_link.h b/libopenage/gui/game_spec_link.h index ac2b2dd96e..c896227d23 100644 --- a/libopenage/gui/game_spec_link.h +++ b/libopenage/gui/game_spec_link.h @@ -17,7 +17,6 @@ class GameSpec; namespace gui { -class AssetManagerLink; class GameSpecLink; } // namespace gui @@ -48,7 +47,6 @@ class GameSpecLink : public qtsdl::GuiItemQObject Q_ENUMS(State) Q_PROPERTY(State state READ get_state NOTIFY state_changed) Q_PROPERTY(bool active READ get_active WRITE set_active) - Q_PROPERTY(openage::gui::AssetManagerLink *assetManager READ get_asset_manager WRITE set_asset_manager) Q_PROPERTY(int terrainIdCount READ get_terrain_id_count NOTIFY terrain_id_count_changed) public: @@ -66,9 +64,6 @@ class GameSpecLink : public qtsdl::GuiItemQObject bool get_active() const; void set_active(bool active); - AssetManagerLink *get_asset_manager() const; - void set_asset_manager(AssetManagerLink *asset_manager); - int get_terrain_id_count() const; Q_INVOKABLE void invalidate(); @@ -100,7 +95,6 @@ private slots: State state; bool active; - AssetManagerLink *asset_manager; int terrain_id_count; std::shared_ptr loaded_game_spec; diff --git a/libopenage/terrain/terrain.h b/libopenage/terrain/terrain.h index bb1d876843..c33cd43dee 100644 --- a/libopenage/terrain/terrain.h +++ b/libopenage/terrain/terrain.h @@ -13,9 +13,9 @@ #include "../coord/phys.h" #include "../coord/pixel.h" #include "../coord/tile.h" +#include "../presenter/legacy/legacy.h" #include "../texture.h" #include "../util/misc.h" -#include "assets/legacy_assetmanager.h" namespace openage { From ec0d748e3f256e9e230a00f6122439bf96fba555 Mon Sep 17 00:00:00 2001 From: heinezen Date: Fri, 22 Sep 2023 23:30:02 +0200 Subject: [PATCH 29/95] presenter: Remove legacy game control. --- libopenage/gui/CMakeLists.txt | 1 - libopenage/gui/actions_list_model.cpp | 139 +-- libopenage/gui/actions_list_model.h | 28 +- .../gui/category_contents_list_model.cpp | 39 +- libopenage/gui/category_contents_list_model.h | 7 - libopenage/gui/game_control_link.cpp | 456 --------- libopenage/gui/game_control_link.h | 333 ------- libopenage/gui/resources_list_model.cpp | 24 +- libopenage/gui/resources_list_model.h | 22 +- libopenage/presenter/legacy/CMakeLists.txt | 1 - libopenage/presenter/legacy/game_control.cpp | 916 ------------------ libopenage/presenter/legacy/game_control.h | 395 -------- 12 files changed, 26 insertions(+), 2335 deletions(-) delete mode 100644 libopenage/gui/game_control_link.cpp delete mode 100644 libopenage/gui/game_control_link.h delete mode 100644 libopenage/presenter/legacy/game_control.cpp delete mode 100644 libopenage/presenter/legacy/game_control.h diff --git a/libopenage/gui/CMakeLists.txt b/libopenage/gui/CMakeLists.txt index 1697bc8d78..a1dd56541b 100644 --- a/libopenage/gui/CMakeLists.txt +++ b/libopenage/gui/CMakeLists.txt @@ -3,7 +3,6 @@ add_sources(libopenage category_contents_list_model.cpp engine_info.cpp engine_link.cpp - game_control_link.cpp game_creator.cpp game_main_link.cpp game_saver.cpp diff --git a/libopenage/gui/actions_list_model.cpp b/libopenage/gui/actions_list_model.cpp index 67f2d2780f..a8fa45fa46 100644 --- a/libopenage/gui/actions_list_model.cpp +++ b/libopenage/gui/actions_list_model.cpp @@ -1,9 +1,8 @@ -// Copyright 2016-2019 the openage authors. See copying.md for legal info. +// Copyright 2016-2023 the openage authors. See copying.md for legal info. #include "actions_list_model.h" #include "../log/log.h" -#include "game_control_link.h" #include #include @@ -15,132 +14,13 @@ namespace { const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "ActionsListModel"); } -ActionsListModel::ActionsListModel(QObject *parent) - : - QAbstractListModel{parent}, - action_mode{} { +ActionsListModel::ActionsListModel(QObject *parent) : + QAbstractListModel{parent} { Q_UNUSED(registration); } ActionsListModel::~ActionsListModel() = default; -ActionButtonsType ActionsListModel::get_active_buttons() const { - return this->active_buttons; -} - -void ActionsListModel::set_active_buttons(const ActionButtonsType &active_buttons) { - if (this->active_buttons == active_buttons) { - return; - } - this->active_buttons = active_buttons; - - switch (active_buttons) { - case ActionButtonsType::None: - this->clear_buttons(); - break; - - case ActionButtonsType::MilitaryUnits: - this->clear_buttons(); - this->set_icons_source("image://by-filename/converted/interface/hudactions.slp.png"); - this->beginResetModel(); - this->add_button(6, -1, static_cast(GroupIDs::NoGroup), "SET_ABILITY_PATROL"); - this->add_button(7, -1, static_cast(GroupIDs::NoGroup), "SET_ABILITY_GUARD"); - this->add_button(8, -1, static_cast(GroupIDs::NoGroup), "SET_ABILITY_FOLLOW"); - this->add_button(59, -1, static_cast(GroupIDs::NoGroup), "KILL_UNIT"); - this->add_button(2, -1, static_cast(GroupIDs::NoGroup), "SET_ABILITY_GARRISON"); - - this->add_button(9, 53, static_cast(GroupIDs::StanceGroup), "AGGRESSIVE_STANCE"); - this->add_button(10, 52, static_cast(GroupIDs::StanceGroup), "DEFENSIVE_STANCE"); - this->add_button(11, 51, static_cast(GroupIDs::StanceGroup), "HOLD_STANCE"); - this->add_button(50, 54, static_cast(GroupIDs::StanceGroup), "PASSIVE_STANCE"); - this->add_button(3, -1, static_cast(GroupIDs::NoGroup), "STOP"); - this->endResetModel(); - break; - - case ActionButtonsType::CivilianUnits: - this->clear_buttons(); - this->set_icons_source("image://by-filename/converted/interface/hudactions.slp.png"); - this->beginResetModel(); - this->add_button(30, -1, static_cast(GroupIDs::NoGroup), "BUILD_MENU"); - this->add_button(31, -1, static_cast(GroupIDs::NoGroup), "BUILD_MENU_MIL"); - this->add_button(28, -1, static_cast(GroupIDs::NoGroup), "SET_ABILITY_REPAIR"); - this->add_button(59, -1, static_cast(GroupIDs::NoGroup), "KILL_UNIT"); - this->add_button(2, -1, static_cast(GroupIDs::NoGroup), "SET_ABILITY_GARRISON"); - - this->add_button(-1, -1, static_cast(GroupIDs::NoGroup), ""); - this->add_button(-1, -1, static_cast(GroupIDs::NoGroup), ""); - this->add_button(-1, -1, static_cast(GroupIDs::NoGroup), ""); - this->add_button(-1, -1, static_cast(GroupIDs::NoGroup), ""); - this->add_button(3, -1, static_cast(GroupIDs::NoGroup), "STOP"); - this->endResetModel(); - break; - - case ActionButtonsType::BuildMenu: - this->clear_buttons(); - this->set_icons_source("image://by-filename/converted/interface/50705.slp.png"); - this->beginResetModel(); - this->add_button(34, -1, static_cast(GroupIDs::NoGroup), "BUILDING_HOUS"); - this->add_button(20, -1, static_cast(GroupIDs::NoGroup), "BUILDING_MILL"); - this->add_button(39, -1, static_cast(GroupIDs::NoGroup), "BUILDING_MINE"); - this->add_button(40, -1, static_cast(GroupIDs::NoGroup), "BUILDING_SMIL"); - this->add_button(13, -1, static_cast(GroupIDs::NoGroup), "BUILDING_DOCK"); - this->add_button(35, -1, static_cast(GroupIDs::NoGroup), "BUILDING_FARM"); - this->add_button(4, -1, static_cast(GroupIDs::NoGroup), "BUILDING_BLAC"); - this->add_button(16, -1, static_cast(GroupIDs::NoGroup), "BUILDING_MRKT"); - this->add_button(10, -1, static_cast(GroupIDs::NoGroup), "BUILDING_CRCH"); - this->add_button(32, -1, static_cast(GroupIDs::NoGroup), "BUILDING_UNIV"); - this->add_button(28, -1, static_cast(GroupIDs::NoGroup), "BUILDING_RTWC"); - this->add_button(37, -1, static_cast(GroupIDs::NoGroup), "BUILDING_WNDR"); - // the go back button is not in this slp (is in hudactions.slp.png) - this->endResetModel(); - break; - - case ActionButtonsType::MilBuildMenu: - this->clear_buttons(); - this->set_icons_source("image://by-filename/converted/interface/50705.slp.png"); - this->beginResetModel(); - this->add_button(2, -1, static_cast(GroupIDs::NoGroup), "BUILDING_BRKS"); - this->add_button(0, -1, static_cast(GroupIDs::NoGroup), "BUILDING_ARRG"); - this->add_button(23, -1, static_cast(GroupIDs::NoGroup), "BUILDING_STBL"); - this->add_button(22, -1, static_cast(GroupIDs::NoGroup), "BUILDING_SIWS"); - this->add_button(38, -1, static_cast(GroupIDs::NoGroup), "BUILDING_WCTWX"); - this->add_button(30, -1, static_cast(GroupIDs::NoGroup), "BUILDING_WALL"); - this->add_button(29, -1, static_cast(GroupIDs::NoGroup), "BUILDING_WALL2"); - this->add_button(25, -1, static_cast(GroupIDs::NoGroup), "BUILDING_WCTW"); - this->add_button(42, -1, static_cast(GroupIDs::NoGroup), "BUILDING_WCTW4"); - this->add_button(36, -1, static_cast(GroupIDs::NoGroup), "BUILDING_GTCA2"); - this->add_button(7, -1, static_cast(GroupIDs::NoGroup), "BUILDING_CSTL"); - // the go back button is not in this slp (is in hudactions.slp.png) - this->endResetModel(); - break; - - default: - log::log(MSG(warn) << "Unknown action mode selection"); - } -} - -ActionModeLink* ActionsListModel::get_action_mode() const { - return this->action_mode; -} - -void ActionsListModel::set_action_mode(ActionModeLink *action_mode) { - if (this->action_mode != action_mode) { - if (this->action_mode != nullptr) { - QObject::disconnect(this->action_mode, - &ActionModeLink::buttons_type_changed, - this, - &ActionsListModel::on_buttons_type_changed); - } - - this->action_mode = action_mode; - - QObject::connect(this->action_mode, - &ActionModeLink::buttons_type_changed, - this, - &ActionsListModel::on_buttons_type_changed); - } -} - QUrl ActionsListModel::get_icons_source() const { return QUrl(this->icons_source); } @@ -154,14 +34,6 @@ void ActionsListModel::set_icons_source(const std::string &icons_source) { emit this->icons_source_changed(this->icons_source); } -Q_INVOKABLE void ActionsListModel::set_initial_buttons() { - this->set_active_buttons(ActionButtonsType::None); -} - -void ActionsListModel::on_buttons_type_changed(const ActionButtonsType buttons_type) { - this->set_active_buttons(buttons_type); -} - QHash ActionsListModel::roleNames() const { QHash roles; roles[static_cast(ActionsRoles::IconRole)] = "ico"; @@ -171,7 +43,7 @@ QHash ActionsListModel::roleNames() const { return roles; } -int ActionsListModel::rowCount(const QModelIndex&) const { +int ActionsListModel::rowCount(const QModelIndex &) const { return this->buttons.size(); } @@ -198,4 +70,5 @@ void ActionsListModel::add_button(int ico, int ico_chk, int grp_id, const char * this->buttons.push_back(map); } -}} // namespace openage::gui +} // namespace gui +} // namespace openage diff --git a/libopenage/gui/actions_list_model.h b/libopenage/gui/actions_list_model.h index e0ce30f605..7ffff6a752 100644 --- a/libopenage/gui/actions_list_model.h +++ b/libopenage/gui/actions_list_model.h @@ -1,11 +1,9 @@ -// Copyright 2016-2019 the openage authors. See copying.md for legal info. +// Copyright 2016-2023 the openage authors. See copying.md for legal info. #pragma once #include -#include "game_control_link.h" - #include #include #include @@ -20,25 +18,15 @@ namespace gui { class ActionsListModel : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(ActionButtonsType active_buttons READ get_active_buttons WRITE set_active_buttons) - Q_PROPERTY(ActionModeLink* action_mode READ get_action_mode WRITE set_action_mode) Q_PROPERTY(QUrl iconsSource READ get_icons_source WRITE set_icons_source NOTIFY icons_source_changed) public: - ActionsListModel(QObject *parent=nullptr); + ActionsListModel(QObject *parent = nullptr); virtual ~ActionsListModel(); - ActionButtonsType get_active_buttons() const; - void set_active_buttons(const ActionButtonsType &active_buttons); - - ActionModeLink* get_action_mode() const; - void set_action_mode(ActionModeLink* action_mode); - QUrl get_icons_source() const; void set_icons_source(QUrl icons_source); - Q_INVOKABLE void set_initial_buttons(); - enum class ActionsRoles { IconRole = Qt::UserRole + 1, IconCheckedRole, @@ -54,13 +42,10 @@ class ActionsListModel : public QAbstractListModel { signals: void icons_source_changed(const QUrl icons_source); -private slots: - void on_buttons_type_changed(const ActionButtonsType buttons_type); - private: virtual QHash roleNames() const override; - virtual int rowCount(const QModelIndex&) const override; - virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override; + virtual int rowCount(const QModelIndex &) const override; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; virtual QMap itemData(const QModelIndex &index) const override; /** @@ -78,10 +63,9 @@ private slots: */ void add_button(int ico, int ico_chk, int grp_id, const char *name); - ActionButtonsType active_buttons; - ActionModeLink *action_mode; QUrl icons_source; std::vector> buttons; }; -}} // namespace openage::gui +} // namespace gui +} // namespace openage diff --git a/libopenage/gui/category_contents_list_model.cpp b/libopenage/gui/category_contents_list_model.cpp index 334bf7570f..88408ee458 100644 --- a/libopenage/gui/category_contents_list_model.cpp +++ b/libopenage/gui/category_contents_list_model.cpp @@ -1,11 +1,9 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include "category_contents_list_model.h" #include -#include "game_control_link.h" - namespace openage { namespace gui { @@ -13,10 +11,8 @@ namespace { const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "Category"); } -CategoryContentsListModel::CategoryContentsListModel(QObject *parent) - : - QAbstractListModel{parent}, - editor_mode{} { +CategoryContentsListModel::CategoryContentsListModel(QObject *parent) : + QAbstractListModel{parent} { Q_UNUSED(registration); } @@ -34,28 +30,6 @@ void CategoryContentsListModel::set_name(const QString &name) { } } -EditorModeLink* CategoryContentsListModel::get_editor_mode() const { - return this->editor_mode; -} - -void CategoryContentsListModel::set_editor_mode(EditorModeLink *editor_mode) { - if (this->editor_mode != editor_mode) { - if (this->editor_mode) { - QObject::disconnect(this->editor_mode, &EditorModeLink::categories_content_changed, this, &CategoryContentsListModel::on_categories_content_changed); - QObject::disconnect(this->editor_mode, &EditorModeLink::category_content_changed, this, &CategoryContentsListModel::on_category_content_changed); - } - - this->editor_mode = editor_mode; - - if (this->editor_mode) { - QObject::connect(this->editor_mode, &EditorModeLink::categories_content_changed, this, &CategoryContentsListModel::on_categories_content_changed); - QObject::connect(this->editor_mode, &EditorModeLink::category_content_changed, this, &CategoryContentsListModel::on_category_content_changed); - } - - this->on_categories_content_changed(); - } -} - void CategoryContentsListModel::on_category_content_changed(const std::string &category_name, std::vector> type_and_texture) { if (this->name == QString::fromStdString(category_name)) { this->beginResetModel(); @@ -65,8 +39,6 @@ void CategoryContentsListModel::on_category_content_changed(const std::string &c } void CategoryContentsListModel::on_categories_content_changed() { - if (this->editor_mode) - this->editor_mode->announce_category_content(this->name.toStdString()); } QHash CategoryContentsListModel::roleNames() const { @@ -75,7 +47,7 @@ QHash CategoryContentsListModel::roleNames() const { return names; } -int CategoryContentsListModel::rowCount(const QModelIndex&) const { +int CategoryContentsListModel::rowCount(const QModelIndex &) const { return this->type_and_texture.size(); } @@ -94,4 +66,5 @@ QVariant CategoryContentsListModel::data(const QModelIndex &index, int role) con return QVariant{}; } -}} // namespace openage::gui +} // namespace gui +} // namespace openage diff --git a/libopenage/gui/category_contents_list_model.h b/libopenage/gui/category_contents_list_model.h index b8dde68526..e3845a44db 100644 --- a/libopenage/gui/category_contents_list_model.h +++ b/libopenage/gui/category_contents_list_model.h @@ -14,8 +14,6 @@ namespace openage { namespace gui { -class EditorModeLink; - /** * Adaptor for the contents of a category of the Civilisation. */ @@ -23,7 +21,6 @@ class CategoryContentsListModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(QString name READ get_name WRITE set_name) - Q_PROPERTY(openage::gui::EditorModeLink *editorMode READ get_editor_mode WRITE set_editor_mode) public: CategoryContentsListModel(QObject *parent = nullptr); @@ -32,9 +29,6 @@ class CategoryContentsListModel : public QAbstractListModel { QString get_name() const; void set_name(const QString &name); - EditorModeLink *get_editor_mode() const; - void set_editor_mode(EditorModeLink *editor_mode); - private slots: void on_category_content_changed(const std::string &category_name, std::vector> type_and_texture); void on_categories_content_changed(); @@ -47,7 +41,6 @@ private slots: std::vector> type_and_texture; QString name; - EditorModeLink *editor_mode; }; } // namespace gui diff --git a/libopenage/gui/game_control_link.cpp b/libopenage/gui/game_control_link.cpp deleted file mode 100644 index 4c41678892..0000000000 --- a/libopenage/gui/game_control_link.cpp +++ /dev/null @@ -1,456 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "game_control_link.h" - -#include - -#include - -#include "../legacy_engine.h" -#include "../unit/action.h" -#include "../unit/unit.h" -#include "engine_link.h" -#include "game_main_link.h" - -namespace openage::gui { - -namespace { -const int registration_mode = qmlRegisterUncreatableType("yay.sfttech.openage", 1, 0, "OutputMode", "OutputMode is an abstract interface for the concrete modes like EditorMode or ActionMode."); -const int registration_create = qmlRegisterType("yay.sfttech.openage", 1, 0, "CreateMode"); -const int registration_action = qmlRegisterType("yay.sfttech.openage", 1, 0, "ActionMode"); -const int registration_editor = qmlRegisterType("yay.sfttech.openage", 1, 0, "EditorMode"); -const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "GameControl"); -} // namespace - -OutputModeLink::OutputModeLink(QObject *parent) : - GuiItemQObject{parent}, - QQmlParserStatus{}, - GuiItemInterface{} { -} - -OutputModeLink::~OutputModeLink() = default; - -QString OutputModeLink::get_name() const { - return this->name; -} - -QStringList OutputModeLink::get_binds() const { - return this->binds; -} - -void OutputModeLink::on_announced(const std::string &name) { - auto new_name = QString::fromStdString(name); - - if (this->name != new_name) { - this->name = new_name; - emit this->name_changed(); - } -} - -void OutputModeLink::on_binds_changed( - const std::vector &binds) { - QStringList new_binds; - std::transform( - std::begin(binds), - std::end(binds), - std::back_inserter(new_binds), - [](const std::string &s) { - return QString::fromStdString(s); - }); - - if (this->binds != new_binds) { - this->binds = new_binds; - emit this->binds_changed(); - } -} - -void OutputModeLink::classBegin() { -} - -void OutputModeLink::on_core_adopted() { - QObject::connect(&unwrap(this)->gui_signals, - &OutputModeSignals::announced, - this, - &OutputModeLink::on_announced); - - QObject::connect(&unwrap(this)->gui_signals, - &OutputModeSignals::binds_changed, - this, - &OutputModeLink::on_binds_changed); -} - -void OutputModeLink::componentComplete() { - static auto f = [](OutputMode *_this) { - _this->announce(); - }; - this->i(f); -} - -CreateModeLink::CreateModeLink(QObject *parent) : - Inherits{parent} { - Q_UNUSED(registration_create); -} - -CreateModeLink::~CreateModeLink() = default; - -ActionModeLink::ActionModeLink(QObject *parent) : - Inherits{parent} { - Q_UNUSED(registration_action); -} - -ActionModeLink::~ActionModeLink() = default; - -QString ActionModeLink::get_ability() const { - return this->ability; -} - -QString ActionModeLink::get_population() const { - return this->population; -} - -int ActionModeLink::get_selection_size() const { - return this->selection ? this->selection->get_units_count() : 0; -} - -bool ActionModeLink::get_population_warn() const { - return this->population_warn; -} - -void ActionModeLink::act(const QString &action) { - emit this->action_triggered(action.toStdString()); -} - -void ActionModeLink::on_ability_changed(const std::string &ability) { - this->ability = QString::fromStdString(ability); - emit this->ability_changed(); -} - -void ActionModeLink::on_buttons_type_changed(const ActionButtonsType buttons_type) { - emit this->buttons_type_changed(buttons_type); -} - -void ActionModeLink::on_population_changed(int demand, int capacity, bool warn) { - this->population = QString::number(demand) + "/" + QString::number(capacity); - this->population_warn = warn; - emit this->population_changed(); -} - -void ActionModeLink::on_selection_changed(const UnitSelection *unit_selection, const Player *player) { - this->selection = unit_selection; - - if (this->selection->get_units_count() == 1) { - auto &ref = this->selection->get_first_unit(); - if (ref.is_valid()) { - Unit *u = ref.get(); - - this->selection_name = QString::fromStdString(u->unit_type->name()); - // the icons are split into two sprites - if (u->unit_type->unit_class == gamedata::unit_classes::BUILDING) { - this->selection_icon = QString::fromStdString("50706.slp.png." + std::to_string(u->unit_type->icon)); - } - else { - this->selection_icon = QString::fromStdString("50730.slp.png." + std::to_string(u->unit_type->icon)); - } - this->selection_type = QString::fromStdString("(type: " + std::to_string(u->unit_type->id()) + " " + u->top()->name() + ")"); - - if (u->has_attribute(attr_type::owner)) { - auto &own_attr = u->get_attribute(); - if (own_attr.player.civ->civ_id != 0) { // not gaia - this->selection_owner = QString::fromStdString( - own_attr.player.name + "\n" + own_attr.player.civ->civ_name + "\n" + (!player || *player == own_attr.player ? "" : player->is_ally(own_attr.player) ? "Ally" : - "Enemy")); - // TODO find the team status of the player - } - else { - this->selection_owner = QString::fromStdString(" "); - } - } - - if (u->has_attribute(attr_type::hitpoints) && u->has_attribute(attr_type::damaged)) { - auto &hp = u->get_attribute(); - auto &dm = u->get_attribute(); - // TODO replace ascii health bar with real one - if (hp.hp >= 200) { - this->selection_hp = QString::fromStdString(progress(dm.hp * 1.0f / hp.hp, 8) + " " + std::to_string(dm.hp) + "/" + std::to_string(hp.hp)); - } - else { - this->selection_hp = QString::fromStdString(progress(dm.hp * 1.0f / hp.hp, 4) + " " + std::to_string(dm.hp) + "/" + std::to_string(hp.hp)); - } - } - else { - this->selection_hp = QString::fromStdString(" "); - } - - std::string lines; - if (u->has_attribute(attr_type::resource)) { - auto &res_attr = u->get_attribute(); - lines += std::to_string((int)res_attr.amount) + " " + std::to_string(res_attr.resource_type) + "\n"; - } - if (u->has_attribute(attr_type::building)) { - auto &build_attr = u->get_attribute(); - if (build_attr.completed < 1) { - lines += "Building: " + progress(build_attr.completed, 16) + " " + std::to_string((int)(100 * build_attr.completed)) + "%\n"; - } - } - if (u->has_attribute(attr_type::garrison)) { - auto &garrison_attr = u->get_attribute(); - if (garrison_attr.content.size() > 0) { - lines += "Garrison: " + std::to_string(garrison_attr.content.size()) + " units\n"; - } - } - lines += "\n"; - if (u->has_attribute(attr_type::population)) { - auto &population_attr = u->get_attribute(); - if (population_attr.demand > 1) { - lines += "Population demand: " + std::to_string(population_attr.demand) + " units\n"; - } - if (population_attr.capacity > 0) { - lines += "Population capacity: " + std::to_string(population_attr.capacity) + " units\n"; - } - } - this->selection_attrs = QString::fromStdString(lines); - } - } - else if (this->selection->get_units_count() > 1) { - this->selection_name = QString::fromStdString( - std::to_string(this->selection->get_units_count()) + " units"); - } - - - emit this->selection_changed(); -} - -// TODO remove -std::string ActionModeLink::progress(float progress, int size) { - std::string bar = "["; - for (int i = 0; i < size; i++) { - bar += (i < progress * size ? "=" : " "); - } - return bar + "]"; -} - -void ActionModeLink::on_core_adopted() { - this->Inherits::on_core_adopted(); - QObject::connect(&unwrap(this)->gui_signals, - &ActionModeSignals::ability_changed, - this, - &ActionModeLink::on_ability_changed); - QObject::connect(&unwrap(this)->gui_signals, - &ActionModeSignals::population_changed, - this, - &ActionModeLink::on_population_changed); - QObject::connect(&unwrap(this)->gui_signals, - &ActionModeSignals::selection_changed, - this, - &ActionModeLink::on_selection_changed); - QObject::connect(&unwrap(this)->gui_signals, - &ActionModeSignals::buttons_type_changed, - this, - &ActionModeLink::on_buttons_type_changed); - QObject::connect(this, - &ActionModeLink::action_triggered, - &unwrap(this)->gui_signals, - &ActionModeSignals::on_action); -} - -EditorModeLink::EditorModeLink(QObject *parent) : - Inherits{parent}, - current_type_id{-1}, - current_terrain_id{-1}, - paint_terrain{} { - Q_UNUSED(registration_editor); -} - -EditorModeLink::~EditorModeLink() = default; - -int EditorModeLink::get_current_type_id() const { - return this->current_type_id; -} - -void EditorModeLink::set_current_type_id(int current_type_id) { - static auto f = [](EditorMode *_this, int current_type_id) { - _this->set_current_type_id(current_type_id); - }; - this->s(f, this->current_type_id, current_type_id); -} - -int EditorModeLink::get_current_terrain_id() const { - return this->current_terrain_id; -} - -void EditorModeLink::set_current_terrain_id(int current_terrain_id) { - static auto f = [](EditorMode *_this, int current_terrain_id) { - _this->set_current_terrain_id(current_terrain_id); - }; - this->s(f, this->current_terrain_id, current_terrain_id); -} - -bool EditorModeLink::get_paint_terrain() const { - return this->paint_terrain; -} - -void EditorModeLink::set_paint_terrain(bool paint_terrain) { - static auto f = [](EditorMode *_this, int paint_terrain) { - _this->set_paint_terrain(paint_terrain); - }; - this->s(f, this->paint_terrain, paint_terrain); -} - -QStringList EditorModeLink::get_categories() const { - return this->categories; -} - -void EditorModeLink::announce_category_content(const std::string &category_name) { - static auto f = [](EditorMode *_this, const std::string &category_name) { - _this->announce_category_content(category_name); - }; - this->i(f, category_name); -} - -void EditorModeLink::on_categories_changed(const std::vector &categories) { - this->categories.clear(); - std::transform(std::begin(categories), std::end(categories), std::back_inserter(this->categories), [](const std::string &s) { return QString::fromStdString(s); }); - emit this->categories_changed(); -} - -void EditorModeLink::on_core_adopted() { - this->Inherits::on_core_adopted(); - QObject::connect(&unwrap(this)->gui_signals, &EditorModeSignals::toggle, this, &EditorModeLink::toggle); - QObject::connect(&unwrap(this)->gui_signals, &EditorModeSignals::categories_changed, this, &EditorModeLink::on_categories_changed); - QObject::connect(&unwrap(this)->gui_signals, &EditorModeSignals::categories_content_changed, this, &EditorModeLink::categories_content_changed); - QObject::connect(&unwrap(this)->gui_signals, &EditorModeSignals::category_content_changed, this, &EditorModeLink::category_content_changed); -} - -GameControlLink::GameControlLink(QObject *parent) : - GuiItemQObject{parent}, - QQmlParserStatus{}, - GuiItem{this}, - mode{}, - effective_mode_index{-1}, - mode_index{-1}, - engine{}, - game{}, - current_civ_index{} { - Q_UNUSED(registration_mode); - Q_UNUSED(registration); -} - -GameControlLink::~GameControlLink() = default; - -void GameControlLink::classBegin() { -} - -void GameControlLink::on_core_adopted() { - QObject::connect(&unwrap(this)->gui_signals, &GameControlSignals::mode_changed, this, &GameControlLink::on_mode_changed); - QObject::connect(&unwrap(this)->gui_signals, &GameControlSignals::modes_changed, this, &GameControlLink::on_modes_changed); - QObject::connect(&unwrap(this)->gui_signals, &GameControlSignals::current_player_name_changed, this, &GameControlLink::on_current_player_name_changed); - QObject::connect(&unwrap(this)->gui_signals, &GameControlSignals::current_civ_index_changed, this, &GameControlLink::on_current_civ_index_changed); -} - -void GameControlLink::componentComplete() { - static auto f = [](GameControl *_this) { - _this->announce_mode(); - _this->announce_current_player_name(); - }; - this->i(f); -} - -OutputModeLink *GameControlLink::get_mode() const { - return this->mode; -} - -int GameControlLink::get_effective_mode_index() const { - return this->effective_mode_index; -} - -int GameControlLink::get_mode_index() const { - return this->mode_index; -} - -void GameControlLink::set_mode_index(int mode) { - static auto f = [](GameControl *_this, int mode) { - _this->set_mode(mode, true); - }; - - this->sf(f, this->mode_index, mode); -} - -QVariantList GameControlLink::get_modes() const { - return this->modes; -} - -void GameControlLink::set_modes(const QVariantList &modes) { - static auto f = [](GameControl *_this, const QVariantList &modes) { - std::vector new_modes; - - for (auto m : modes) - if (m.canConvert()) - new_modes.push_back(unwrap(m.value())); - - _this->set_modes(new_modes); - }; - - this->s(f, this->modes, modes); -} - -EngineLink *GameControlLink::get_engine() const { - return this->engine; -} - -void GameControlLink::set_engine(EngineLink *engine) { - static auto f = [](GameControl *_this, LegacyEngine *engine) { - _this->set_engine(engine); - }; - this->s(f, this->engine, engine); -} - -GameMainLink *GameControlLink::get_game() const { - return this->game; -} - -void GameControlLink::set_game(GameMainLink *game) { - static auto f = [](GameControl *_this, GameMainHandle *game) { - _this->set_game(game); - }; - this->s(f, this->game, game); -} - -QString GameControlLink::get_current_player_name() const { - return this->current_player_name; -} - -int GameControlLink::get_current_civ_index() const { - return this->current_civ_index; -} - -void GameControlLink::on_mode_changed(OutputMode *mode, int mode_index) { - auto new_mode = qtsdl::wrap(mode); - - if (this->mode != new_mode || this->effective_mode_index != mode_index) { - this->effective_mode_index = mode_index; - this->mode = new_mode; - emit this->mode_changed(); - } -} - -void GameControlLink::on_modes_changed(OutputMode *mode, int mode_index) { - static auto f = [](GameControl *_this, int mode) { - _this->set_mode(mode); - }; - this->i(f, this->mode_index); - - this->on_mode_changed(mode, mode_index); - emit this->modes_changed(); -} - -void GameControlLink::on_current_player_name_changed(const std::string ¤t_player_name) { - this->current_player_name = QString::fromStdString(current_player_name); - emit this->current_player_name_changed(); -} - -void GameControlLink::on_current_civ_index_changed(int current_civ_index) { - this->current_civ_index = current_civ_index; - emit this->current_civ_index_changed(); -} - -} // namespace openage::gui diff --git a/libopenage/gui/game_control_link.h b/libopenage/gui/game_control_link.h deleted file mode 100644 index 9dde68e924..0000000000 --- a/libopenage/gui/game_control_link.h +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "../presenter/legacy/game_control.h" -#include "guisys/link/gui_item.h" - -namespace openage { -namespace gui { - -class GameControlLink; - -class OutputModeLink; - -} // namespace gui -} // namespace openage - -namespace qtsdl { -template <> -struct Wrap { - using Type = openage::gui::OutputModeLink; -}; - -template <> -struct Unwrap { - using Type = openage::OutputMode; -}; - -} // namespace qtsdl - -namespace openage { -namespace gui { - -class OutputModeLink : public qtsdl::GuiItemQObject - , public QQmlParserStatus - , public qtsdl::GuiItemInterface { - Q_OBJECT - - Q_INTERFACES(QQmlParserStatus) - Q_PROPERTY(QString name READ get_name NOTIFY name_changed) - Q_PROPERTY(QStringList binds READ get_binds NOTIFY binds_changed) - -public: - OutputModeLink(QObject *parent = nullptr); - virtual ~OutputModeLink(); - - QString get_name() const; - QStringList get_binds() const; - -signals: - void name_changed(); - void binds_changed(); - -private slots: - void on_announced(const std::string &name); - void on_binds_changed(const std::vector &binds); - -protected: - virtual void classBegin() override; - virtual void on_core_adopted() override; - virtual void componentComplete() override; - -private: - QString name; - QStringList binds; -}; - -class CreateModeLink; - -} // namespace gui -} // namespace openage - -namespace qtsdl { -template <> -struct Wrap { - using Type = openage::gui::CreateModeLink; -}; - -template <> -struct Unwrap { - using Type = openage::CreateMode; -}; - -} // namespace qtsdl - -namespace openage { -namespace gui { - -class CreateModeLink : public qtsdl::Inherits { - Q_OBJECT - -public: - CreateModeLink(QObject *parent = nullptr); - virtual ~CreateModeLink(); -}; - -class ActionModeLink; - -} // namespace gui -} // namespace openage - -namespace qtsdl { -template <> -struct Wrap { - using Type = openage::gui::ActionModeLink; -}; - -template <> -struct Unwrap { - using Type = openage::ActionMode; -}; - -} // namespace qtsdl - -namespace openage { -namespace gui { - -class ActionModeLink : public qtsdl::Inherits { - Q_OBJECT - - Q_PROPERTY(QString ability READ get_ability NOTIFY ability_changed) - Q_PROPERTY(QString population READ get_population NOTIFY population_changed) - Q_PROPERTY(bool population_warn READ get_population_warn NOTIFY population_changed) - - Q_PROPERTY(int selection_size READ get_selection_size NOTIFY selection_changed) - - Q_PROPERTY(QString selection_name MEMBER selection_name NOTIFY selection_changed) - Q_PROPERTY(QString selection_icon MEMBER selection_icon NOTIFY selection_changed) - Q_PROPERTY(QString selection_type MEMBER selection_type NOTIFY selection_changed) - Q_PROPERTY(QString selection_owner MEMBER selection_owner NOTIFY selection_changed) - Q_PROPERTY(QString selection_hp MEMBER selection_hp NOTIFY selection_changed) - Q_PROPERTY(QString selection_attrs MEMBER selection_attrs NOTIFY selection_changed) - -public: - ActionModeLink(QObject *parent = nullptr); - virtual ~ActionModeLink(); - - QString get_ability() const; - QString get_population() const; - bool get_population_warn() const; - int get_selection_size() const; - - Q_INVOKABLE void act(const QString &action); - -signals: - void ability_changed(); - void action_triggered(const std::string &ability); - void buttons_type_changed(const ActionButtonsType buttons_type); - void population_changed(); - void selection_changed(); - -private slots: - void on_ability_changed(const std::string &ability); - void on_buttons_type_changed(const ActionButtonsType buttons_type); - void on_population_changed(int demand, int capacity, bool warn); - void on_selection_changed(const UnitSelection *unit_selection, const Player *player); - -private: - virtual void on_core_adopted() override; - - QString ability; - QString population; - bool population_warn; - const UnitSelection *selection = nullptr; - - QString selection_name; - QString selection_icon; - QString selection_type; - QString selection_owner; - QString selection_hp; - QString selection_attrs; - - std::string progress(float progress, int size); -}; - -class EditorModeLink; - -} // namespace gui -} // namespace openage - -namespace qtsdl { -template <> -struct Wrap { - using Type = openage::gui::EditorModeLink; -}; - -template <> -struct Unwrap { - using Type = openage::EditorMode; -}; - -} // namespace qtsdl - -namespace openage { -namespace gui { - -class EditorModeLink : public qtsdl::Inherits { - Q_OBJECT - - Q_PROPERTY(int currentTypeId READ get_current_type_id WRITE set_current_type_id) - Q_PROPERTY(int currentTerrainId READ get_current_terrain_id WRITE set_current_terrain_id) - Q_PROPERTY(bool paintTerrain READ get_paint_terrain WRITE set_paint_terrain) - Q_PROPERTY(QStringList categories READ get_categories NOTIFY categories_changed) - -public: - EditorModeLink(QObject *parent = nullptr); - virtual ~EditorModeLink(); - - int get_current_type_id() const; - void set_current_type_id(int current_type_id); - - int get_current_terrain_id() const; - void set_current_terrain_id(int current_terrain_id); - - bool get_paint_terrain() const; - void set_paint_terrain(bool paint_terrain); - - QStringList get_categories() const; - - void announce_category_content(const std::string &category_name); - -signals: - void toggle(); - void categories_changed(); - void categories_content_changed(); - void category_content_changed(const std::string &category_name, std::vector> type_and_texture); - -private slots: - void on_categories_changed(const std::vector &categories); - -private: - virtual void on_core_adopted() override; - - int current_type_id; - int current_terrain_id; - bool paint_terrain; - QStringList categories; -}; - -class EngineLink; -class GameMainLink; -class GameControlLink; - -} // namespace gui -} // namespace openage - -namespace qtsdl { -template <> -struct Wrap { - using Type = openage::gui::GameControlLink; -}; - -template <> -struct Unwrap { - using Type = openage::GameControl; -}; - -} // namespace qtsdl - -namespace openage { -namespace gui { - -class GameControlLink : public qtsdl::GuiItemQObject - , public QQmlParserStatus - , public qtsdl::GuiItem { - Q_OBJECT - - Q_INTERFACES(QQmlParserStatus) - Q_PROPERTY(openage::gui::OutputModeLink *mode READ get_mode NOTIFY mode_changed) - Q_PROPERTY(int effectiveModeIndex READ get_effective_mode_index NOTIFY mode_changed) - Q_PROPERTY(int modeIndex READ get_mode_index WRITE set_mode_index) - Q_PROPERTY(QVariantList modes READ get_modes WRITE set_modes NOTIFY modes_changed) - Q_MOC_INCLUDE("gui/engine_link.h") - Q_MOC_INCLUDE("gui/game_main_link.h") - Q_PROPERTY(openage::gui::EngineLink *engine READ get_engine WRITE set_engine) - Q_PROPERTY(openage::gui::GameMainLink *game READ get_game WRITE set_game) - Q_PROPERTY(QString currentPlayerName READ get_current_player_name NOTIFY current_player_name_changed) - Q_PROPERTY(int currentCivIndex READ get_current_civ_index NOTIFY current_civ_index_changed) - -public: - explicit GameControlLink(QObject *parent = nullptr); - virtual ~GameControlLink(); - - OutputModeLink *get_mode() const; - int get_effective_mode_index() const; - - int get_mode_index() const; - void set_mode_index(int mode); - - QVariantList get_modes() const; - void set_modes(const QVariantList &modes); - - EngineLink *get_engine() const; - void set_engine(EngineLink *engine); - - GameMainLink *get_game() const; - void set_game(GameMainLink *game); - - QString get_current_player_name() const; - int get_current_civ_index() const; - -signals: - void mode_changed(); - void modes_changed(); - void current_player_name_changed(); - void current_civ_index_changed(); - -private slots: - void on_mode_changed(OutputMode *mode, int mode_index); - void on_modes_changed(OutputMode *mode, int mode_index); - void on_current_player_name_changed(const std::string ¤t_player_name); - void on_current_civ_index_changed(int current_civ_index); - -private: - virtual void classBegin() override; - virtual void on_core_adopted() override; - virtual void componentComplete() override; - - OutputModeLink *mode = nullptr; - int effective_mode_index; - int mode_index; - QVariantList modes; - // TODO: remove engine because it's already accessible through the game - EngineLink *engine = nullptr; - GameMainLink *game = nullptr; - QString current_player_name; - int current_civ_index; -}; - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/resources_list_model.cpp b/libopenage/gui/resources_list_model.cpp index ad0106663d..d804d147b4 100644 --- a/libopenage/gui/resources_list_model.cpp +++ b/libopenage/gui/resources_list_model.cpp @@ -9,9 +9,6 @@ #include "../error/error.h" -#include "../presenter/legacy/game_control.h" -#include "game_control_link.h" - namespace openage::gui { namespace { @@ -23,31 +20,12 @@ const auto resource_type_count = static_cast ResourcesListModel::ResourcesListModel(QObject *parent) : QAbstractListModel(parent), - amounts(resource_type_count), - action_mode() { + amounts(resource_type_count) { Q_UNUSED(registration); } ResourcesListModel::~ResourcesListModel() = default; -ActionModeLink *ResourcesListModel::get_action_mode() const { - return this->action_mode; -} - -void ResourcesListModel::set_action_mode(ActionModeLink *action_mode) { - if (this->action_mode != action_mode) { - if (this->action_mode) { - QObject::disconnect(&unwrap(this->action_mode)->gui_signals, &ActionModeSignals::resource_changed, this, &ResourcesListModel::on_resource_changed); - } - - this->action_mode = action_mode; - - if (this->action_mode) { - QObject::connect(&unwrap(this->action_mode)->gui_signals, &ActionModeSignals::resource_changed, this, &ResourcesListModel::on_resource_changed); - } - } -} - void ResourcesListModel::on_resource_changed(game_resource resource, int amount) { int i = static_cast(resource); ENSURE(i >= 0 && i < std::distance(std::begin(this->amounts), std::end(this->amounts)), "Res type index is out of range: '" << i << "'."); diff --git a/libopenage/gui/resources_list_model.h b/libopenage/gui/resources_list_model.h index 574618fb78..51ef6425bb 100644 --- a/libopenage/gui/resources_list_model.h +++ b/libopenage/gui/resources_list_model.h @@ -1,9 +1,9 @@ -// Copyright 2016-2018 the openage authors. See copying.md for legal info. +// Copyright 2016-2023 the openage authors. See copying.md for legal info. #pragma once -#include #include +#include #include @@ -12,33 +12,25 @@ namespace openage { namespace gui { -class ActionModeLink; - /** * Resource table for the gui. */ class ResourcesListModel : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(openage::gui::ActionModeLink* actionMode READ get_action_mode WRITE set_action_mode) - public: - ResourcesListModel(QObject *parent=nullptr); + ResourcesListModel(QObject *parent = nullptr); virtual ~ResourcesListModel(); - ActionModeLink* get_action_mode() const; - void set_action_mode(ActionModeLink *action_mode); - private slots: void on_resource_changed(game_resource resource, int amount); private: - virtual int rowCount(const QModelIndex&) const override; - virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override; + virtual int rowCount(const QModelIndex &) const override; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; std::vector amounts; - - ActionModeLink *action_mode; }; -}} // namespace openage::gui +} // namespace gui +} // namespace openage diff --git a/libopenage/presenter/legacy/CMakeLists.txt b/libopenage/presenter/legacy/CMakeLists.txt index 5a57295ab3..0c5905d0b5 100644 --- a/libopenage/presenter/legacy/CMakeLists.txt +++ b/libopenage/presenter/legacy/CMakeLists.txt @@ -1,5 +1,4 @@ add_sources(libopenage - game_control.cpp legacy.cpp ) diff --git a/libopenage/presenter/legacy/game_control.cpp b/libopenage/presenter/legacy/game_control.cpp deleted file mode 100644 index 91255b1b54..0000000000 --- a/libopenage/presenter/legacy/game_control.cpp +++ /dev/null @@ -1,916 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "game_control.h" - -#include "error/error.h" -#include "gamestate/old/game_spec.h" -#include "legacy_engine.h" -#include "log/log.h" -#include "renderer/color.h" -#include "terrain/terrain_chunk.h" -#include "util/strings.h" - - -namespace openage { - -OutputMode::OutputMode(qtsdl::GuiItemLink *gui_link) : - game_control{nullptr}, - gui_link{gui_link} { -} - -OutputMode::~OutputMode() { - // An empty deconstructor prevents our clients from needing - // to implement one. - // - // The deconstructor is needed in the first place to stop - // the compiler from generating ud2 (undefined) instructors - // for the body of this method. -} - -void OutputMode::announce() { - emit this->gui_signals.announced(this->name()); - - emit this->gui_signals.binds_changed(this->active_binds()); -} - -void OutputMode::set_game_control(GameControl *game_control) { - this->game_control = game_control; - - this->on_game_control_set(); - this->announce(); -} - -CreateMode::CreateMode(qtsdl::GuiItemLink *gui_link) : - OutputMode{gui_link} {} - -bool CreateMode::available() const { - return true; -} - -std::string CreateMode::name() const { - return "Creation Mode"; -} - -void CreateMode::on_game_control_set() {} - -void CreateMode::on_enter() {} - -void CreateMode::on_exit() {} - -void CreateMode::render() {} - - -ActionModeSignals::ActionModeSignals(ActionMode *action_mode) : - action_mode(action_mode) { -} - -void ActionModeSignals::on_action(const std::string &action_name) { - presenter::LegacyDisplay *display = this->action_mode->game_control->get_display(); - - const input::legacy::action_t &action = display->get_action_manager().get(action_name); - input::legacy::InputContext *top_ctxt = &display->get_input_manager().get_top_context(); - - if (top_ctxt == this->action_mode || top_ctxt == &this->action_mode->building_context || top_ctxt == &this->action_mode->build_menu_context || top_ctxt == &this->action_mode->build_menu_mil_context) { - // create an action that just relays the action. - input::legacy::action_arg_t action_arg{ - input::legacy::Event{input::legacy::event_class::ANY, 0, input::legacy::modset_t{}}, - coord::input{0, 0}, - coord::input_delta{0, 0}, - {action}}; - top_ctxt->execute_if_bound(action_arg); - } -} - -ActionMode::ActionMode(qtsdl::GuiItemLink *gui_link) : - OutputMode{gui_link}, - selection{nullptr}, - use_set_ability{false}, - type_focus{nullptr}, - selecting{false}, - rng{rng::random_seed()}, - gui_signals{this} {} - - -void ActionMode::on_game_control_set() { - ENSURE(this->game_control != nullptr, "no control was actually set"); - - LegacyEngine *engine = this->game_control->get_engine(); - presenter::LegacyDisplay *display = this->game_control->get_display(); - ENSURE(engine != nullptr, "engine must be known!"); - - auto &action = display->get_action_manager(); - auto input = &display->get_input_manager(); - coord::CoordManager &coord = display->coord; - - // TODO: the selection should not be used in here! - this->selection = display->get_unit_selection(); - ENSURE(this->selection != nullptr, "selection must be fetched!"); - - this->bind(action.get("TRAIN_OBJECT"), - [this](const input::legacy::action_arg_t &) { - // attempt to train editor selected object - - // randomly select between male and female villagers - auto player = this->game_control->get_current_player(); - auto type = player->get_type(this->rng.probability(0.5) ? 83 : 293); - - Command cmd(*player, type); - cmd.add_flag(command_flag::interrupt); - this->selection->all_invoke(cmd); - }); - - this->bind(action.get("ENABLE_BUILDING_PLACEMENT"), - [](const input::legacy::action_arg_t &) { - // this->building_placement = true; - }); - - this->bind(action.get("DISABLE_SET_ABILITY"), - [this](const input::legacy::action_arg_t &) { - this->use_set_ability = false; - }); - - this->bind(action.get("SET_ABILITY_MOVE"), - [this](const input::legacy::action_arg_t &) { - this->use_set_ability = true; - this->ability = ability_type::move; - emit this->gui_signals.ability_changed(std::to_string(this->ability)); - }); - - this->bind(action.get("SET_ABILITY_GATHER"), - [this](const input::legacy::action_arg_t &) { - this->use_set_ability = true; - this->ability = ability_type::gather; - emit this->gui_signals.ability_changed(std::to_string(this->ability)); - }); - - this->bind(action.get("SET_ABILITY_GARRISON"), - [this](const input::legacy::action_arg_t &) { - this->use_set_ability = true; - this->ability = ability_type::garrison; - emit this->gui_signals.ability_changed(std::to_string(this->ability)); - }); - - this->bind(action.get("SET_ABILITY_REPAIR"), [this](const input::legacy::action_arg_t &) { - this->use_set_ability = true; - this->ability = ability_type::repair; - emit this->gui_signals.ability_changed(std::to_string(this->ability)); - }); - - this->bind(action.get("SPAWN_VILLAGER"), - [this, display](const input::legacy::action_arg_t &) { - auto player = this->game_control->get_current_player(); - - if (player->type_count() > 0) { - UnitType &type = *player->get_type(590); - - // TODO tile position - display->get_game()->placed_units.new_unit(type, *player, this->mousepos_phys3); - } - }); - - this->bind(action.get("KILL_UNIT"), - [this](const input::legacy::action_arg_t &) { - this->selection->kill_unit(*this->game_control->get_current_player()); - }); - - this->bind(action.get("BUILD_MENU"), - [this, input](const input::legacy::action_arg_t &) { - log::log(MSG(dbg) << "Opening build menu"); - input->push_context(&this->build_menu_context); - this->announce_buttons_type(); - }); - - this->bind(action.get("BUILD_MENU_MIL"), - [this, input](const input::legacy::action_arg_t &) { - log::log(MSG(dbg) << "Opening military build menu"); - input->push_context(&this->build_menu_mil_context); - this->announce_buttons_type(); - }); - - this->build_menu_context.bind(action.get("CANCEL"), - [this, input](const input::legacy::action_arg_t &) { - input->remove_context(&this->build_menu_context); - this->announce_buttons_type(); - }); - - this->build_menu_mil_context.bind(action.get("CANCEL"), - [this, input](const input::legacy::action_arg_t &) { - input->remove_context(&this->build_menu_mil_context); - this->announce_buttons_type(); - }); - - // Villager build commands - auto bind_building_key = [this, input](input::legacy::action_t action, int building, input::legacy::InputContext *ctxt) { - ctxt->bind(action, [this, building, ctxt, input](const input::legacy::action_arg_t &) { - auto player = this->game_control->get_current_player(); - if (this->selection->contains_builders(*player)) { - auto player = this->game_control->get_current_player(); - this->type_focus = player->get_type(building); - - if (player->can_make(*this->type_focus)) { - if (&input->get_top_context() != &this->building_context) { - input->remove_context(ctxt); - input->push_context(&this->building_context); - this->announce_buttons_type(); - } - } - else { - // TODO show in game error message - } - } - }); - }; - - bind_building_key(action.get("BUILDING_HOUS"), 70, &this->build_menu_context); // House - bind_building_key(action.get("BUILDING_MILL"), 68, &this->build_menu_context); // Mill - bind_building_key(action.get("BUILDING_MINE"), 584, &this->build_menu_context); // Mining Camp - bind_building_key(action.get("BUILDING_SMIL"), 562, &this->build_menu_context); // Lumber Camp - bind_building_key(action.get("BUILDING_DOCK"), 47, &this->build_menu_context); // Dock - // TODO: Doesn't show until it is placed - bind_building_key(action.get("BUILDING_FARM"), 50, &this->build_menu_context); // Farm - bind_building_key(action.get("BUILDING_BLAC"), 103, &this->build_menu_context); // Blacksmith - bind_building_key(action.get("BUILDING_MRKT"), 84, &this->build_menu_context); // Market - bind_building_key(action.get("BUILDING_CRCH"), 104, &this->build_menu_context); // Monastery - bind_building_key(action.get("BUILDING_UNIV"), 209, &this->build_menu_context); // University - bind_building_key(action.get("BUILDING_RTWC"), 109, &this->build_menu_context); // Town Center - bind_building_key(action.get("BUILDING_WNDR"), 276, &this->build_menu_context); // Wonder - - bind_building_key(action.get("BUILDING_BRKS"), 12, &this->build_menu_mil_context); // Barracks - bind_building_key(action.get("BUILDING_ARRG"), 87, &this->build_menu_mil_context); // Archery Range - bind_building_key(action.get("BUILDING_STBL"), 101, &this->build_menu_mil_context); // Stable - bind_building_key(action.get("BUILDING_SIWS"), 49, &this->build_menu_mil_context); // Siege Workshop - bind_building_key(action.get("BUILDING_WCTWX"), 598, &this->build_menu_mil_context); // Outpost - // TODO for palisade and stone wall: Drag walls, automatically adjust orientation - // TODO: This just cycles through all palisade textures - bind_building_key(action.get("BUILDING_WALL"), 72, &this->build_menu_mil_context); // Palisade Wall - // TODO: Fortified wall has a different ID - bind_building_key(action.get("BUILDING_WALL2"), 117, &this->build_menu_mil_context); // Stone Wall - // TODO: Upgraded versions have different IDs - bind_building_key(action.get("BUILDING_WCTW"), 79, &this->build_menu_mil_context); // Watch Tower - bind_building_key(action.get("BUILDING_WCTW4"), 236, &this->build_menu_mil_context); // Bombard Tower - // TODO: Gate placement - 659 is horizontal closed - bind_building_key(action.get("BUILDING_GTCA2"), 659, &this->build_menu_mil_context); // Gate - bind_building_key(action.get("BUILDING_CSTL"), 82, &this->build_menu_mil_context); // Castle - - this->building_context.bind(action.get("CANCEL"), - [this, input](const input::legacy::action_arg_t &) { - input->remove_context(&this->building_context); - this->announce_buttons_type(); - this->type_focus = nullptr; - }); - - auto bind_build = [this, input, &coord](input::legacy::action_t action, const bool increase) { - this->building_context.bind(action, [this, increase, input, &coord](const input::legacy::action_arg_t &arg) { - this->mousepos_phys3 = arg.mouse.to_phys3(coord, 0); - this->mousepos_tile = this->mousepos_phys3.to_tile(); - - bool placed = this->place_selection(this->mousepos_phys3); - - if (placed && !increase) { - this->type_focus = nullptr; - input->remove_context(&this->building_context); - this->announce_buttons_type(); - } - }); - }; - - bind_build(action.get("BUILD"), false); - bind_build(action.get("KEEP_BUILDING"), true); - - auto bind_select = [this, input, display](input::legacy::action_t action, const bool increase) { - this->bind(action, [this, increase, input, display](const input::legacy::action_arg_t &arg) { - auto mousepos_camgame = arg.mouse.to_camgame(display->coord); - Terrain *terrain = display->get_game()->terrain.get(); - - this->selection->drag_update(mousepos_camgame); - this->selection->drag_release(*this->game_control->get_current_player(), terrain, increase); - InputContext *top_ctxt = &input->get_top_context(); - - if ((this->selection->get_selection_type() != selection_type_t::own_units or this->selection->contains_military(*this->game_control->get_current_player())) - and (top_ctxt == &this->build_menu_context || top_ctxt == &this->build_menu_mil_context)) { - input->remove_context(top_ctxt); - } - this->announce_buttons_type(); - this->announce_current_selection(); - }); - }; - - bind_select(action.get("SELECT"), false); - bind_select(action.get("INCREASE_SELECTION"), true); - - this->bind(action.get("ORDER_SELECT"), [this, input, &coord](const input::legacy::action_arg_t &arg) { - if (this->type_focus) { - // right click can cancel building placement - this->type_focus = nullptr; - input->remove_context(&this->building_context); - this->announce_buttons_type(); - } - - auto cmd = this->get_action(arg.mouse.to_phys3(coord)); - cmd.add_flag(command_flag::interrupt); - this->selection->all_invoke(cmd); - this->use_set_ability = false; - }); - - this->bind(action.get("BEGIN_SELECTION"), [this](const input::legacy::action_arg_t &) { - this->selecting = true; - }); - - this->bind(action.get("END_SELECTION"), [this](const input::legacy::action_arg_t &) { - this->selecting = false; - }); - - this->bind(input::legacy::event_class::MOUSE, [this, &coord](const input::legacy::action_arg_t &arg) { - auto mousepos_camgame = arg.mouse.to_camgame(coord); - this->mousepos_phys3 = mousepos_camgame.to_phys3(coord); - this->mousepos_tile = this->mousepos_phys3.to_tile(); - - // drag selection box - if (arg.e.cc == input::legacy::ClassCode(input::legacy::event_class::MOUSE_MOTION, 0) && this->selecting && !this->type_focus) { - this->selection->drag_update(mousepos_camgame); - this->announce_current_selection(); - return true; - } - return false; - }); -} - -bool ActionMode::available() const { - if (this->game_control == nullptr) { - log::log(MSG(warn) << "ActionMode::available() queried without " - "game control being attached."); - return false; - } - - presenter::LegacyDisplay *display = this->game_control->get_display(); - if (display->get_game() != nullptr) { - return true; - } - else { - log::log(MSG(warn) << "Cannot enter action mode without a game"); - return false; - } -} - -void ActionMode::on_enter() {} - -void ActionMode::on_exit() { - // Since on_exit is called after removing the active mode, if the top context isn't the global one then it must - // be either a build menu or the building context - presenter::LegacyDisplay *display = this->game_control->get_display(); - auto *input_manager = &display->get_input_manager(); - InputContext *top_ctxt = &input_manager->get_top_context(); - if (top_ctxt != &input_manager->get_global_context()) { - if (top_ctxt == &this->building_context) { - this->type_focus = nullptr; - } - input_manager->remove_context(top_ctxt); - this->announce_buttons_type(); - } - this->selecting = false; -} - -Command ActionMode::get_action(const coord::phys3 &pos) const { - presenter::LegacyDisplay *display = this->game_control->get_display(); - GameMain *game = display->get_game(); - - auto obj = game->terrain->obj_at_point(pos); - if (obj) { - Command c(*this->game_control->get_current_player(), &obj->unit, pos); - if (this->use_set_ability) { - c.set_ability(ability); - } - return c; - } - else { - Command c(*this->game_control->get_current_player(), pos); - if (this->use_set_ability) { - c.set_ability(ability); - } - return c; - } -} - -bool ActionMode::place_selection(coord::phys3 point) { - if (this->type_focus) { - auto player = this->game_control->get_current_player(); - - if (player->can_make(*this->type_focus)) { - // confirm building placement with left click - // first create foundation using the producer - presenter::LegacyDisplay *display = this->game_control->get_display(); - - UnitContainer *container = &display->get_game()->placed_units; - UnitReference new_building = container->new_unit(*this->type_focus, *player, point); - - // task all selected villagers to build - // TODO: editor placed objects are completed already - if (new_building.is_valid()) { - player->deduct(this->type_focus->cost.get(*player)); // TODO change, move elsewheres - - Command cmd(*player, new_building.get()); - cmd.set_ability(ability_type::build); - cmd.add_flag(command_flag::interrupt); - this->selection->all_invoke(cmd); - return true; - } - } - else { - // TODO show in game error message - return false; - } - } - return false; -} - -void ActionMode::render() { - ENSURE(this->game_control != nullptr, "game_control is unset"); - LegacyEngine *engine = this->game_control->get_engine(); - presenter::LegacyDisplay *display = this->game_control->get_display(); - - ENSURE(engine != nullptr, "engine is needed to render ActionMode"); - - if (GameMain *game = display->get_game()) { - Player *player = this->game_control->get_current_player(); - - this->announce_resources(); - - if (this->selection && this->selection->get_units_count() > 0) { - this->announce_current_selection(); - } - - // when a building is being placed - if (this->type_focus) { - auto txt = this->type_focus->default_texture(); - auto size = this->type_focus->foundation_size; - - tile_range center = building_center(this->mousepos_phys3, size, *game->terrain); - txt->sample(display->coord, center.draw.to_camhud(display->coord), player->color); - } - } - else { - display->render_text({0, 140}, 12, renderer::Colors::WHITE, "Action Mode requires a game"); - } - - ENSURE(this->selection != nullptr, "selection not set"); - - this->selection->on_drawhud(); -} - -std::string ActionMode::name() const { - return "Action Mode"; -} - -void ActionMode::announce() { - this->OutputMode::announce(); - - this->announce_resources(); - emit this->gui_signals.ability_changed( - this->use_set_ability ? std::to_string(this->ability) : ""); -} - -void ActionMode::announce_resources() { - if (this->game_control) { - if (Player *player = this->game_control->get_current_player()) { - for (auto i = static_cast::type>(game_resource::RESOURCE_TYPE_COUNT); i != 0; --i) { - auto resource_type = static_cast(i - 1); - - emit this->gui_signals.resource_changed( - resource_type, - static_cast(player->amount(resource_type))); - } - emit this->gui_signals.population_changed(player->population.get_demand(), player->population.get_capacity(), player->population.get_space() <= 0 && !player->population.is_capacity_maxed()); - } - } -} - -void ActionMode::announce_buttons_type() { - ActionButtonsType buttons_type; - presenter::LegacyDisplay *display = this->game_control->get_display(); - InputContext *top_ctxt = &display->get_input_manager().get_top_context(); - if (top_ctxt == &this->build_menu_context) { - buttons_type = ActionButtonsType::BuildMenu; - } - else if (top_ctxt == &this->build_menu_mil_context) { - buttons_type = ActionButtonsType::MilBuildMenu; - } - else if (top_ctxt == &this->building_context || this->selection->get_selection_type() != selection_type_t::own_units) { - buttons_type = ActionButtonsType::None; - } - else if (this->selection->contains_military(*this->game_control->get_current_player())) { - buttons_type = ActionButtonsType::MilitaryUnits; - } - else { - buttons_type = ActionButtonsType::CivilianUnits; - } - - if (buttons_type != this->buttons_type) { - this->buttons_type = buttons_type; - emit this->gui_signals.buttons_type_changed(buttons_type); - - // announce the changed input context - this->announce(); - } -} - -EditorModeSignals::EditorModeSignals(EditorMode *editor_mode) : - editor_mode{editor_mode} { -} - -void EditorModeSignals::on_current_player_name_changed() { - this->editor_mode->announce_categories(); -} - -EditorMode::EditorMode(qtsdl::GuiItemLink *gui_link) : - OutputMode{gui_link}, - editor_current_terrain{-1}, - current_type_id{-1}, - paint_terrain{}, - gui_signals{this} {} - - -void EditorMode::on_game_control_set() { - presenter::LegacyDisplay *display = this->game_control->get_display(); - auto &action = display->get_action_manager(); - - // bind required hotkeys - this->bind(action.get("ENABLE_BUILDING_PLACEMENT"), [this](const input::legacy::action_arg_t &) { - log::log(MSG(dbg) << "change category"); - emit this->gui_signals.toggle(); - }); - - this->bind(input::legacy::event_class::MOUSE, [this, display](const input::legacy::action_arg_t &arg) { - if (arg.e.cc == input::legacy::ClassCode(input::legacy::event_class::MOUSE_BUTTON, 1) || display->get_input_manager().is_down(input::legacy::event_class::MOUSE_BUTTON, 1)) { - if (this->paint_terrain) { - this->paint_terrain_at(arg.mouse.to_viewport(display->coord)); - } - else { - this->paint_entity_at(arg.mouse.to_viewport(display->coord), false); - } - return true; - } - else if (arg.e.cc == input::legacy::ClassCode(input::legacy::event_class::MOUSE_BUTTON, 3) || display->get_input_manager().is_down(input::legacy::event_class::MOUSE_BUTTON, 3)) { - if (!this->paint_terrain) { - this->paint_entity_at(arg.mouse.to_viewport(display->coord), true); - } - return true; - } - return false; - }); -} - -bool EditorMode::available() const { - if (this->game_control == nullptr) { - log::log(MSG(warn) << "game_control not yet linked to EditorMode"); - return false; - } - else if (this->game_control->get_display()->get_game() != nullptr) { - return true; - } - else { - log::log(MSG(warn) << "Cannot enter editor mode without a game"); - return false; - } -} - -void EditorMode::on_enter() {} - -void EditorMode::on_exit() {} - -void EditorMode::render() {} - -std::string EditorMode::name() const { - return "Editor mode"; -} - -void EditorMode::set_current_type_id(int current_type_id) { - this->current_type_id = current_type_id; -} - -void EditorMode::set_current_terrain_id(terrain_t current_terrain_id) { - this->editor_current_terrain = current_terrain_id; -} - -void EditorMode::set_paint_terrain(bool paint_terrain) { - this->paint_terrain = paint_terrain; -} - -void EditorMode::paint_terrain_at(const coord::viewport &point) { - presenter::LegacyDisplay *display = this->game_control->get_display(); - Terrain *terrain = display->get_game()->terrain.get(); - - auto mousepos_tile = point.to_tile(display->coord); - - TerrainChunk *chunk = terrain->get_create_chunk(mousepos_tile); - chunk->get_data(mousepos_tile.get_pos_on_chunk())->terrain_id = editor_current_terrain; -} - -void EditorMode::paint_entity_at(const coord::viewport &point, const bool del) { - presenter::LegacyDisplay *display = this->game_control->get_display(); - GameMain *game = display->get_game(); - Terrain *terrain = game->terrain.get(); - - auto mousepos_phys3 = point.to_phys3(display->coord); - auto mousepos_tile = mousepos_phys3.to_tile(); - - TerrainChunk *chunk = terrain->get_create_chunk(mousepos_tile); - // TODO : better detection of presence of unit - if (!chunk->get_data(mousepos_tile.get_pos_on_chunk())->obj.empty()) { - if (del) { - // delete first object currently standing at the clicked position - TerrainObject *obj = chunk->get_data(mousepos_tile.get_pos_on_chunk())->obj[0]; - obj->remove(); - } - } - else if (!del && this->current_type_id != -1) { - Player *player = this->game_control->get_current_player(); - UnitType *selected_type = player->get_type(this->current_type_id); - - // tile is empty so try creating a unit - UnitContainer *container = &game->placed_units; - container->new_unit(*selected_type, *this->game_control->get_current_player(), mousepos_phys3); - } -} - -void EditorMode::announce_categories() { - if (this->game_control) - if (auto player = this->game_control->get_current_player()) - emit this->gui_signals.categories_changed(player->civ->get_type_categories()); - - emit this->gui_signals.categories_content_changed(); -} - -void EditorMode::announce_category_content(const std::string &category_name) { - if (this->game_control) - if (auto player = this->game_control->get_current_player()) { - auto inds = player->civ->get_category(category_name); - std::vector> type_and_texture(inds.size()); - - auto it = std::begin(type_and_texture); - - std::for_each(std::begin(inds), std::end(inds), [player, &it](auto index) { - *it++ = std::make_tuple(index, player->get_type(index)->default_texture()->id); - }); - - emit this->gui_signals.category_content_changed(category_name, type_and_texture); - } -} - -void EditorMode::announce() { - OutputMode::announce(); - this->announce_categories(); -} - -void EditorMode::set_game_control(GameControl *game_control) { - if (this->game_control != game_control) { - if (this->game_control) - QObject::disconnect( - &this->game_control->gui_signals, - &GameControlSignals::current_player_name_changed, - &this->gui_signals, - &EditorModeSignals::on_current_player_name_changed); - - // actually set the control - OutputMode::set_game_control(game_control); - - if (this->game_control) - QObject::connect( - &this->game_control->gui_signals, - &GameControlSignals::current_player_name_changed, - &this->gui_signals, - &EditorModeSignals::on_current_player_name_changed); - - this->announce_categories(); - } - else { - // just set the control - OutputMode::set_game_control(game_control); - } -} - -GameControlSignals::GameControlSignals(GameControl *game_control) : - game_control{game_control} { -} - -void GameControlSignals::on_game_running(bool running) { - if (running) - this->game_control->announce_current_player_name(); -} - -GameControl::GameControl(qtsdl::GuiItemLink *gui_link) : - engine{nullptr}, - game{nullptr}, - active_mode{nullptr}, - active_mode_index{-1}, - current_player{1}, - gui_signals{this}, - gui_link{gui_link} { -} - -void GameControl::set_engine(LegacyEngine *engine) { - // TODO: decide to either go for a full Engine QML-singleton or for a regular object - ENSURE(!this->engine || this->engine == engine, "relinking GameControl to another engine is not supported and not caught properly"); - - if (not this->engine) { - this->engine = engine; - - // add handlers - this->display->register_drawhud_action(this, -1); - - auto &action = this->display->get_action_manager(); - - auto &global_input_context = display->get_input_manager().get_global_context(); - - // advance the active mode - global_input_context.bind(action.get("TOGGLE_CONSTRUCT_MODE"), [this](const input::legacy::action_arg_t &) { - this->set_mode((this->active_mode_index + 1) % this->modes.size()); - }); - - // Switching between players with the 1-8 keys - auto bind_player_switch = [this, &global_input_context](input::legacy::action_t action, size_t player_index) { - global_input_context.bind(action, [this, player_index](const input::legacy::action_arg_t &) { - if (this->current_player != player_index) - if (auto game = this->display->get_game()) - if (player_index < game->player_count()) { - this->current_player = player_index; - this->announce_current_player_name(); - } - }); - }; - - bind_player_switch(action.get("SWITCH_TO_PLAYER_1"), 0); - bind_player_switch(action.get("SWITCH_TO_PLAYER_2"), 1); - bind_player_switch(action.get("SWITCH_TO_PLAYER_3"), 2); - bind_player_switch(action.get("SWITCH_TO_PLAYER_4"), 3); - bind_player_switch(action.get("SWITCH_TO_PLAYER_5"), 4); - bind_player_switch(action.get("SWITCH_TO_PLAYER_6"), 5); - bind_player_switch(action.get("SWITCH_TO_PLAYER_7"), 6); - bind_player_switch(action.get("SWITCH_TO_PLAYER_8"), 7); - - this->display->announce_global_binds(); - } -} -void GameControl::set_display(presenter::LegacyDisplay *display) { - this->display = display; -} - -void GameControl::set_game(GameMainHandle *game) { - if (this->game != game) { - if (this->game) - QObject::disconnect(&this->game->gui_signals, - &GameMainSignals::game_running, - &this->gui_signals, - &GameControlSignals::on_game_running); - - this->game = game; - - if (this->game) - QObject::connect(&this->game->gui_signals, - &GameMainSignals::game_running, - &this->gui_signals, - &GameControlSignals::on_game_running); - } -} - -void GameControl::set_modes(const std::vector &modes) { - const int old_mode_index = this->active_mode_index; - - this->set_mode(-1); - this->modes = modes; - - for (auto mode : this->modes) { - // link the controller to the mode - mode->set_game_control(this); - } - - // announce the newly set modes - emit this->gui_signals.modes_changed(this->active_mode, - this->active_mode_index); - - // try to enter the mode we were in before - // assuming its index didn't change. - if (old_mode_index != -1) { - if (old_mode_index < std::distance(std::begin(this->modes), - std::end(this->modes))) { - this->set_mode(old_mode_index, true); - } - else { - log::log(MSG(warn) << "couldn't enter previous gui mode #" - << old_mode_index << " as it vanished."); - } - } -} - -void GameControl::announce_mode() { - emit this->gui_signals.mode_changed(this->active_mode, - this->active_mode_index); - - if (this->active_mode != nullptr) { - emit this->active_mode->announce(); - } -} - -void GameControl::announce_current_player_name() { - if (Player *player = this->get_current_player()) { - emit this->gui_signals.current_player_name_changed( - "[" + std::to_string(player->color) + "] " + player->name); - emit this->gui_signals.current_civ_index_changed(player->civ->civ_id); - } -} - -void ActionMode::announce_current_selection() { - Player *player = this->game_control->get_current_player(); - emit this->gui_signals.selection_changed(this->selection, player); -} - -bool GameControl::on_drawhud() { - // render the active mode - if (this->active_mode) - this->active_mode->render(); - - return true; -} - -Player *GameControl::get_current_player() const { - if (auto game = this->display->get_game()) { - unsigned int number = game->player_count(); - return game->get_player(this->current_player % number); - } - return nullptr; -} - -void GameControl::set_mode(int mode_index, bool signal_if_unchanged) { - bool need_to_signal = signal_if_unchanged; - - // do we wanna set a new mode? - if (mode_index != -1) { - // if the new mode is valid, available and not active at the moment - if (mode_index < std::distance(std::begin(this->modes), - std::end(this->modes)) - && this->modes[mode_index]->available() - && this->active_mode_index != mode_index) { - ENSURE(!this->active_mode == (this->active_mode_index == -1), - "inconsistency between the active mode index and pointer"); - - // exit from the old mode - if (this->active_mode) { - this->display->get_input_manager().remove_context( - this->active_mode); - - // trigger the exit callback of the mode - if (this->active_mode) { - this->active_mode->on_exit(); - } - } - - // set the new active mode - this->active_mode_index = mode_index; - this->active_mode = this->modes[mode_index]; - - // trigger the entry callback - this->active_mode->on_enter(); - - // add the mode-local input context - this->display->get_input_manager().push_context( - this->active_mode); - - need_to_signal = true; - } - } - else { - // unassign the active mode - if (this->active_mode) { - // remove the input context - this->display->get_input_manager().remove_context( - this->active_mode); - - this->active_mode_index = -1; - this->active_mode = nullptr; - - need_to_signal = true; - } - } - - if (need_to_signal) { - this->announce_mode(); - } -} - -LegacyEngine *GameControl::get_engine() const { - if (this->engine == nullptr) { - throw Error{MSG(err) << "game control doesn't have a valid engine pointer yet"}; - } - - return this->engine; -} - -presenter::LegacyDisplay *GameControl::get_display() const { - if (this->engine == nullptr) { - throw Error{MSG(err) << "game control doesn't have a valid engine pointer yet"}; - } - - return this->display; -} - - -} // namespace openage diff --git a/libopenage/presenter/legacy/game_control.h b/libopenage/presenter/legacy/game_control.h deleted file mode 100644 index 2732ce0345..0000000000 --- a/libopenage/presenter/legacy/game_control.h +++ /dev/null @@ -1,395 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include - -#include "coord/pixel.h" -#include "gamestate/old/game_main.h" -#include "gui/guisys/link/gui_item_link.h" -#include "handlers.h" -#include "input/legacy/input_context.h" -#include "presenter/legacy/legacy.h" -#include "rng/rng.h" -#include "unit/command.h" -#include "unit/selection.h" -#include "unit/unit_type.h" - -namespace qtsdl { -class GuiItemLink; -} // namespace qtsdl - -namespace openage { - -class ActionMode; -class EditorMode; -class LegacyEngine; -class GameControl; - - -/** - * Signals for a gui mode. - */ -class [[deprecated]] OutputModeSignals : public QObject { - Q_OBJECT - -public: -signals: - /** - * Signal is triggered to anounce a new output mode. - * name: name of the gui mode. - */ - void announced(const std::string &name); - - /** - * Signal is triggered when the bindings of the mode change. - * binds: list of strings that describe keybindings. - */ - void binds_changed(const std::vector &binds); -}; - - -/** - * A target for input handling and gui rendering. - * This allows to switch to different display UIs. - */ -class [[deprecated]] OutputMode : public input::legacy::InputContext { -public: - explicit OutputMode(qtsdl::GuiItemLink *gui_link); - virtual ~OutputMode(); - - /** - * Is this mode able to be used? - */ - virtual bool available() const = 0; - - /** - * Called when switching to this mode. - */ - virtual void on_enter() = 0; - - /** - * Called when the mode is left. - */ - virtual void on_exit() = 0; - - /** - * Display this mode. - */ - virtual void render() = 0; - - /** - * Used for displaying the current mode. - */ - virtual std::string name() const = 0; - - /** - * Emit the "announced" signal with (name, InputContext::active_binds). - */ - virtual void announce(); - - /** - * Called when the GameControl is set in QML. - */ - virtual void set_game_control(GameControl *game_control); - - /** - * Called after GameControl has been set by QML from `set_game_control`. - */ - virtual void on_game_control_set() = 0; - -protected: - GameControl *game_control; - -public: - /** - * Signals to be triggered when the mode canges. - */ - OutputModeSignals gui_signals; - - qtsdl::GuiItemLink *gui_link; -}; - - -/** - * This is mainly the game editor. - * Shows menus to choose units to build. - */ -class [[deprecated]] CreateMode : public OutputMode { -public: - CreateMode(qtsdl::GuiItemLink *gui_link); - - bool available() const override; - void on_enter() override; - void on_exit() override; - void render() override; - std::string name() const override; - void on_game_control_set() override; -}; - -enum class ActionButtonsType { - None, - MilitaryUnits, - CivilianUnits, - BuildMenu, - MilBuildMenu -}; - - -class ActionModeSignals : public QObject { - Q_OBJECT - -public: - explicit ActionModeSignals(ActionMode *action_mode); - -public slots: - void on_action(const std::string &action_name); - -signals: - void resource_changed(game_resource resource, int amount); - void population_changed(int demand, int capacity, bool warn); - void selection_changed(const UnitSelection *unit_selection, const Player *player); - void ability_changed(const std::string &ability); - void buttons_type_changed(const ActionButtonsType type); - -private: - ActionMode *action_mode; -}; - - -/** - * This is the main game UI. - * - * Used to control units, issue commands, basically this is where you - * sink your time in when playing. - */ -class [[deprecated]] ActionMode : public OutputMode { -public: - ActionMode(qtsdl::GuiItemLink *gui_link); - - bool available() const override; - void on_enter() override; - void on_exit() override; - void render() override; - std::string name() const override; - void on_game_control_set() override; - -private: - friend ActionModeSignals; - /** - * sends to gui the properties that it needs - */ - virtual void announce() override; - - /** - * sends to gui the amounts of resources - */ - void announce_resources(); - - /** - * sends to gui the buttons it should use for the action buttons - * (if changed) - */ - void announce_buttons_type(); - - void announce_current_selection(); - - /** - * decides which type of right mouse click command - * to issue based on position. - * - * if a unit is at the position the command should target the unit, - * otherwise target ground position - */ - Command get_action(const coord::phys3 &pos) const; - - /** - * Register the keybindings. - */ - void create_binds(); - - /** - * used after opening the build menu - */ - InputContext build_menu_context; - - /** - * used after opening the military build menu - */ - InputContext build_menu_mil_context; - - /** - * used when selecting the building placement - */ - InputContext building_context; - - /** - * places hovering building - */ - bool place_selection(coord::phys3 point); - - // currently selected units - UnitSelection *selection; - - // restrict command abilities - bool use_set_ability; - ability_type ability; - - // a selected type for placement - UnitType *type_focus; - - // TODO these shouldn't be here. remove them ASAP. - // they are used to carry over mouse information - // into some of the game control lambda functions - coord::phys3 mousepos_phys3{0, 0, 0}; - coord::tile mousepos_tile{0, 0}; - bool selecting; - - ActionButtonsType buttons_type; - - // used for random type creation - rng::RNG rng; - -public: - ActionModeSignals gui_signals; -}; - - -class EditorModeSignals : public QObject { - Q_OBJECT - -public: - explicit EditorModeSignals(EditorMode *editor_mode); - -public slots: - void on_current_player_name_changed(); - -signals: - void toggle(); - void categories_changed(const std::vector &categories); - void categories_content_changed(); - void category_content_changed(const std::string &category_name, std::vector> &type_and_texture); - -private: - EditorMode *editor_mode; -}; - -/** - * UI mode to provide an interface for map editing. - */ -class [[deprecated]] EditorMode : public OutputMode { -public: - explicit EditorMode(qtsdl::GuiItemLink *gui_link); - - bool available() const override; - void on_enter() override; - void on_exit() override; - void render() override; - std::string name() const override; - void on_game_control_set() override; - - void set_current_type_id(int current_type_id); - void set_current_terrain_id(openage::terrain_t current_terrain_id); - void set_paint_terrain(bool paint_terrain); - - bool on_single_click(int button, coord::viewport point); - - void announce_categories(); - void announce_category_content(const std::string &category_name); - -private: - virtual void announce() override; - virtual void set_game_control(GameControl *game_control) override; - - void paint_terrain_at(const coord::viewport &point); - void paint_entity_at(const coord::viewport &point, const bool del); - - /** - * currently selected terrain id - */ - terrain_t editor_current_terrain; - int current_type_id; - std::string category; - - /** - * mouse click mode: - * true = terrain painting, - * false = unit placement - */ - bool paint_terrain; - -public: - EditorModeSignals gui_signals; -}; - - -class GameControlSignals : public QObject { - Q_OBJECT - -public: - explicit GameControlSignals(GameControl *game_control); - -public slots: - void on_game_running(bool running); - -signals: - void mode_changed(OutputMode *mode, int mode_index); - void modes_changed(OutputMode *mode, int mode_index); - - void current_player_name_changed(const std::string ¤t_player_name); - void current_civ_index_changed(int current_civ_index); - void is_selected_unit_changed(bool is_selected_unit); - -private: - GameControl *game_control; -}; - - -/** - * connects the gui system with the game engine - * switches between contexts such as editor mode and - * action mode - * - * hud rendering and input handling is redirected to the active mode - */ -class [[deprecated]] GameControl : public openage::HudHandler { -public: - explicit GameControl(qtsdl::GuiItemLink *gui_link); - - void set_engine(LegacyEngine *engine); - void set_display(presenter::LegacyDisplay *engine); - void set_game(GameMainHandle *game); - - void set_modes(const std::vector &modes); - - void set_mode(int mode, bool signal_if_unchanged = false); - void announce_mode(); - void announce_current_player_name(); - - bool on_drawhud() override; - - Player *get_current_player() const; - LegacyEngine *get_engine() const; - presenter::LegacyDisplay *get_display() const; - -private: - LegacyEngine *engine; - presenter::LegacyDisplay *display; - GameMainHandle *game; - - // control modes - std::vector modes; - - OutputMode *active_mode; - int active_mode_index; - - size_t current_player; - -public: - GameControlSignals gui_signals; - qtsdl::GuiItemLink *gui_link; -}; - -} // namespace openage From 3cea703dcf060b8d4fea353794c6b33f61090343 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 23 Sep 2023 00:04:40 +0200 Subject: [PATCH 30/95] presenter: Remove legacy display code. --- libopenage/console/console.cpp | 114 +++-- libopenage/console/console.h | 6 +- libopenage/console/draw.cpp | 134 ++--- libopenage/console/draw.h | 3 +- libopenage/gamestate/old/game_main.cpp | 4 +- libopenage/gamestate/old/game_main.h | 8 +- libopenage/gui/engine_info.h | 10 - libopenage/gui/gui.cpp | 6 +- libopenage/legacy_engine.cpp | 10 - libopenage/legacy_engine.h | 11 - libopenage/presenter/CMakeLists.txt | 2 - libopenage/presenter/legacy/CMakeLists.txt | 7 - libopenage/presenter/legacy/legacy.cpp | 550 --------------------- libopenage/presenter/legacy/legacy.h | 302 ----------- libopenage/terrain/terrain.cpp | 49 -- libopenage/terrain/terrain.h | 7 - 16 files changed, 138 insertions(+), 1085 deletions(-) delete mode 100644 libopenage/presenter/legacy/CMakeLists.txt delete mode 100644 libopenage/presenter/legacy/legacy.cpp delete mode 100644 libopenage/presenter/legacy/legacy.h diff --git a/libopenage/console/console.cpp b/libopenage/console/console.cpp index ae9c2cae77..f2350a01ed 100644 --- a/libopenage/console/console.cpp +++ b/libopenage/console/console.cpp @@ -22,8 +22,8 @@ namespace console { * log console, command console */ -Console::Console(presenter::LegacyDisplay *engine) : - engine{engine}, +Console::Console(/* presenter::LegacyDisplay *display */) : + // display{display}, bottomleft{0, 0}, topright{1, 1}, charsize{1, 1}, @@ -56,64 +56,68 @@ void Console::load_colors(std::vector &colortable) { } void Console::register_to_engine() { - this->engine->register_input_action(this); - this->engine->register_tick_action(this); - this->engine->register_drawhud_action(this); - this->engine->register_resize_action(this); + // TODO: Use new renderer + + // this->display->register_input_action(this); + // this->display->register_tick_action(this); + // this->display->register_drawhud_action(this); + // this->display->register_resize_action(this); // Bind the console toggle key globally - auto &action = this->engine->get_action_manager(); - auto &global = this->engine->get_input_manager().get_global_context(); + // auto &action = this->display->get_action_manager(); + // auto &global = this->display->get_input_manager().get_global_context(); - global.bind(action.get("TOGGLE_CONSOLE"), [this](const input::legacy::action_arg_t &) { - this->set_visible(!this->visible); - }); + // global.bind(action.get("TOGGLE_CONSOLE"), [this](const input::legacy::action_arg_t &) { + // this->set_visible(!this->visible); + // }); // TODO: bind any needed input to InputContext // toggle console will take highest priority - this->input_context.bind(action.get("TOGGLE_CONSOLE"), [this](const input::legacy::action_arg_t &) { - this->set_visible(false); - }); - this->input_context.bind(input::legacy::event_class::UTF8, [this](const input::legacy::action_arg_t &arg) { - // a single char typed into the console - std::string utf8 = arg.e.as_utf8(); - this->buf.write(utf8.c_str()); - command += utf8; - return true; - }); - this->input_context.bind(input::legacy::event_class::NONPRINT, [this](const input::legacy::action_arg_t &arg) { - switch (arg.e.as_char()) { - case 8: // remove a single UTF-8 character - if (this->command.size() > 0) { - util::utf8_pop_back(this->command); - this->buf.pop_last_char(); - } - return true; - - case 13: // interpret command - this->buf.write('\n'); - this->interpret(this->command); - this->command = ""; - return true; - - default: - return false; - } - }); - this->input_context.utf8_mode = true; + // this->input_context.bind(action.get("TOGGLE_CONSOLE"), [this](const input::legacy::action_arg_t &) { + // this->set_visible(false); + // }); + // this->input_context.bind(input::legacy::event_class::UTF8, [this](const input::legacy::action_arg_t &arg) { + // // a single char typed into the console + // std::string utf8 = arg.e.as_utf8(); + // this->buf.write(utf8.c_str()); + // command += utf8; + // return true; + // }); + // this->input_context.bind(input::legacy::event_class::NONPRINT, [this](const input::legacy::action_arg_t &arg) { + // switch (arg.e.as_char()) { + // case 8: // remove a single UTF-8 character + // if (this->command.size() > 0) { + // util::utf8_pop_back(this->command); + // this->buf.pop_last_char(); + // } + // return true; + + // case 13: // interpret command + // this->buf.write('\n'); + // this->interpret(this->command); + // this->command = ""; + // return true; + + // default: + // return false; + // } + // }); + // this->input_context.utf8_mode = true; } void Console::set_visible(bool make_visible) { - if (make_visible) { - this->engine->get_input_manager().push_context(&this->input_context); - this->visible = true; - } - else { - this->engine->get_input_manager().remove_context(&this->input_context); - this->visible = false; - } + // TODO: Use new renderer + + // if (make_visible) { + // this->display->get_input_manager().push_context(&this->input_context); + // this->visible = true; + // } + // else { + // this->display->get_input_manager().remove_context(&this->input_context); + // this->visible = false; + // } } void Console::write(const char *text) { @@ -126,9 +130,11 @@ void Console::interpret(const std::string &command) { this->set_visible(false); } else if (command == "list") { - for (auto &line : this->engine->list_options()) { - this->write(line.c_str()); - } + // TODO: Use new renderer + + // for (auto &line : this->display->list_options()) { + // this->write(line.c_str()); + // } } else if (command.substr(0, 3) == "set") { std::size_t first_space = command.find(" "); @@ -170,7 +176,9 @@ bool Console::on_drawhud() { return true; } - draw::to_opengl(this->engine, this); + // TODO: Use new renderer + + // draw::to_opengl(this->display, this); return true; } diff --git a/libopenage/console/console.h b/libopenage/console/console.h index 8585373eb6..afe4095b51 100644 --- a/libopenage/console/console.h +++ b/libopenage/console/console.h @@ -9,7 +9,6 @@ #include "../gamedata/color_dummy.h" #include "../handlers.h" #include "../input/legacy/input_manager.h" -#include "../presenter/legacy/legacy.h" #include "../renderer/font/font.h" #include "../util/color.h" #include "buf.h" @@ -28,7 +27,7 @@ class Console : InputHandler , HudHandler , ResizeHandler { public: - Console(presenter::LegacyDisplay *renderer); + Console(/* presenter::LegacyDisplay *display */); ~Console(); /** @@ -60,7 +59,8 @@ class Console : InputHandler bool on_resize(coord::viewport_delta new_size) override; protected: - presenter::LegacyDisplay *engine; + // TODO: Replace with new renderer + // presenter::LegacyDisplay *display; public: coord::camhud bottomleft; diff --git a/libopenage/console/draw.cpp b/libopenage/console/draw.cpp index 237c16d91c..187079f86f 100644 --- a/libopenage/console/draw.cpp +++ b/libopenage/console/draw.cpp @@ -18,73 +18,73 @@ namespace openage { namespace console { namespace draw { -void to_opengl(presenter::LegacyDisplay *engine, Console *console) { - coord::camhud topleft{ - console->bottomleft.x, - // TODO This should probably just be console->topright.y - console->bottomleft.y + console->charsize.y * console->buf.dims.y}; - coord::pixel_t ascender = static_cast(console->font.get_ascender()); - - renderer::TextRenderer *text_renderer = engine->get_text_renderer(); - text_renderer->set_font(&console->font); - - int64_t monotime = timing::get_monotonic_time(); - - bool fastblinking_visible = (monotime % 600000000 < 300000000); - bool slowblinking_visible = (monotime % 300000000 < 150000000); - - for (coord::term_t x = 0; x < console->buf.dims.x; x++) { - coord::camhud chartopleft{topleft.x + console->charsize.x * x, 0}; - - for (coord::term_t y = 0; y < console->buf.dims.y; y++) { - chartopleft.y = topleft.y - console->charsize.y * y; - buf_char p = *(console->buf.chrdataptr({x, y - console->buf.scrollback_pos})); - - int fgcolid, bgcolid; - - bool cursor_visible_at_current_pos = (console->buf.cursorpos == coord::term{x, y - console->buf.scrollback_pos}); - - cursor_visible_at_current_pos &= console->buf.cursor_visible; - - if (((p.flags & CHR_NEGATIVE) != 0) xor cursor_visible_at_current_pos) { - bgcolid = p.fgcol; - fgcolid = p.bgcol; - } - else { - bgcolid = p.bgcol; - fgcolid = p.fgcol; - } - - if ((p.flags & CHR_INVISIBLE) - or (p.flags & CHR_BLINKING and not slowblinking_visible) - or (p.flags & CHR_BLINKINGFAST and not fastblinking_visible)) { - fgcolid = bgcolid; - } - - console->termcolors[bgcolid].use(0.8); - - glBegin(GL_QUADS); - { - glVertex3f(chartopleft.x, chartopleft.y, 0); - glVertex3f(chartopleft.x, chartopleft.y - console->charsize.y, 0); - glVertex3f(chartopleft.x + console->charsize.x, chartopleft.y - console->charsize.y, 0); - glVertex3f(chartopleft.x + console->charsize.x, chartopleft.y, 0); - } - glEnd(); - - console->termcolors[fgcolid].use(1); - - char utf8buf[5]; - if (util::utf8_encode(p.cp, utf8buf) == 0) { - //unrepresentable character (question mark in black rhombus) - text_renderer->draw(chartopleft.x, chartopleft.y - ascender, "\uFFFD"); - } - else { - text_renderer->draw(chartopleft.x, chartopleft.y - ascender, utf8buf); - } - } - } -} +// void to_opengl(presenter::LegacyDisplay *engine, Console *console) { +// coord::camhud topleft{ +// console->bottomleft.x, +// // TODO This should probably just be console->topright.y +// console->bottomleft.y + console->charsize.y * console->buf.dims.y}; +// coord::pixel_t ascender = static_cast(console->font.get_ascender()); + +// renderer::TextRenderer *text_renderer = engine->get_text_renderer(); +// text_renderer->set_font(&console->font); + +// int64_t monotime = timing::get_monotonic_time(); + +// bool fastblinking_visible = (monotime % 600000000 < 300000000); +// bool slowblinking_visible = (monotime % 300000000 < 150000000); + +// for (coord::term_t x = 0; x < console->buf.dims.x; x++) { +// coord::camhud chartopleft{topleft.x + console->charsize.x * x, 0}; + +// for (coord::term_t y = 0; y < console->buf.dims.y; y++) { +// chartopleft.y = topleft.y - console->charsize.y * y; +// buf_char p = *(console->buf.chrdataptr({x, y - console->buf.scrollback_pos})); + +// int fgcolid, bgcolid; + +// bool cursor_visible_at_current_pos = (console->buf.cursorpos == coord::term{x, y - console->buf.scrollback_pos}); + +// cursor_visible_at_current_pos &= console->buf.cursor_visible; + +// if (((p.flags & CHR_NEGATIVE) != 0) xor cursor_visible_at_current_pos) { +// bgcolid = p.fgcol; +// fgcolid = p.bgcol; +// } +// else { +// bgcolid = p.bgcol; +// fgcolid = p.fgcol; +// } + +// if ((p.flags & CHR_INVISIBLE) +// or (p.flags & CHR_BLINKING and not slowblinking_visible) +// or (p.flags & CHR_BLINKINGFAST and not fastblinking_visible)) { +// fgcolid = bgcolid; +// } + +// console->termcolors[bgcolid].use(0.8); + +// glBegin(GL_QUADS); +// { +// glVertex3f(chartopleft.x, chartopleft.y, 0); +// glVertex3f(chartopleft.x, chartopleft.y - console->charsize.y, 0); +// glVertex3f(chartopleft.x + console->charsize.x, chartopleft.y - console->charsize.y, 0); +// glVertex3f(chartopleft.x + console->charsize.x, chartopleft.y, 0); +// } +// glEnd(); + +// console->termcolors[fgcolid].use(1); + +// char utf8buf[5]; +// if (util::utf8_encode(p.cp, utf8buf) == 0) { +// //unrepresentable character (question mark in black rhombus) +// text_renderer->draw(chartopleft.x, chartopleft.y - ascender, "\uFFFD"); +// } +// else { +// text_renderer->draw(chartopleft.x, chartopleft.y - ascender, utf8buf); +// } +// } +// } +// } void to_terminal(Buf *buf, util::FD *fd, bool clear) { //move cursor, draw top left corner diff --git a/libopenage/console/draw.h b/libopenage/console/draw.h index 2e35555f05..a359556fb4 100644 --- a/libopenage/console/draw.h +++ b/libopenage/console/draw.h @@ -2,7 +2,6 @@ #pragma once -#include "../presenter/legacy/legacy.h" namespace openage { @@ -22,7 +21,7 @@ namespace draw { /** * experimental and totally inefficient opengl draw of a terminal buffer. */ -void to_opengl(presenter::LegacyDisplay *engine, Console *console); +// void to_opengl(presenter::LegacyDisplay *engine, Console *console); /** * very early and inefficient printing of the console to a pty. diff --git a/libopenage/gamestate/old/game_main.cpp b/libopenage/gamestate/old/game_main.cpp index bd26fe6e48..0fd3624f47 100644 --- a/libopenage/gamestate/old/game_main.cpp +++ b/libopenage/gamestate/old/game_main.cpp @@ -81,7 +81,7 @@ void GameMainHandle::set_engine(LegacyEngine *engine) { void GameMainHandle::clear() { if (this->engine) { this->game = nullptr; - this->display->end_game(); + // this->display->end_game(); announce_running(); } } @@ -94,7 +94,7 @@ void GameMainHandle::set_game(std::unique_ptr &&game) { this->game = game.get(); // then pass on the game to the engine - this->display->start_game(std::move(game)); + // this->display->start_game(std::move(game)); announce_running(); } diff --git a/libopenage/gamestate/old/game_main.h b/libopenage/gamestate/old/game_main.h index 13d1ceb9d1..a7318f25dc 100644 --- a/libopenage/gamestate/old/game_main.h +++ b/libopenage/gamestate/old/game_main.h @@ -2,14 +2,13 @@ #pragma once -#include #include +#include #include #include #include "../../options.h" -#include "../../presenter/legacy/legacy.h" #include "../../terrain/terrain.h" #include "../../unit/unit_container.h" #include "../../util/timing.h" @@ -170,11 +169,6 @@ class GameMainHandle { */ LegacyEngine *engine; - /** - * The engine the main game handle is attached to. - */ - presenter::LegacyDisplay *display; - public: GameMainSignals gui_signals; qtsdl::GuiItemLink *gui_link; diff --git a/libopenage/gui/engine_info.h b/libopenage/gui/engine_info.h index 145821f483..999360ac2a 100644 --- a/libopenage/gui/engine_info.h +++ b/libopenage/gui/engine_info.h @@ -2,17 +2,12 @@ #pragma once -#include "../presenter/legacy/legacy.h" #include "../util/path.h" #include "guisys/public/gui_singleton_items_info.h" namespace openage { class LegacyEngine; -namespace presenter { -class LegacyDisplay; -} - namespace gui { /** @@ -33,11 +28,6 @@ class EngineQMLInfo : public qtsdl::GuiSingletonItemsInfo { */ LegacyEngine *engine; - /** - * The openage display. - */ - presenter::LegacyDisplay *display; - /** * Search path for finding assets n stuff. */ diff --git a/libopenage/gui/gui.cpp b/libopenage/gui/gui.cpp index b9b600d8c5..ebaf20b24a 100644 --- a/libopenage/gui/gui.cpp +++ b/libopenage/gui/gui.cpp @@ -45,9 +45,9 @@ GUI::GUI(SDL_Window *window, source, rootdir}, input{&renderer, &game_logic_updater} { - info->display->register_resize_action(this); - info->display->register_input_action(this); - info->display->register_drawhud_action(this); + // info->display->register_resize_action(this); + // info->display->register_input_action(this); + // info->display->register_drawhud_action(this); util::Path shader_dir = info->asset_dir / "shaders"; diff --git a/libopenage/legacy_engine.cpp b/libopenage/legacy_engine.cpp index af5480032b..8b972316d1 100644 --- a/libopenage/legacy_engine.cpp +++ b/libopenage/legacy_engine.cpp @@ -13,7 +13,6 @@ #include "config.h" #include "error/error.h" #include "log/log.h" -#include "presenter/legacy/legacy.h" #include "version.h" #include "versions/compiletime.h" @@ -30,11 +29,6 @@ LegacyEngine::LegacyEngine(enum mode mode, cvar_manager{cvar_manager}, profiler{this}, gui_link{} { - if (mode == mode::LEGACY) { - this->old_display = std::make_unique(root_dir, this); - return; - } - // TODO: implement FULL and HEADLESS mode :) } @@ -47,10 +41,6 @@ void LegacyEngine::run() { this->job_manager.start(); this->running = true; - if (this->run_mode == mode::LEGACY) { - this->old_display->loop(); - } - this->running = false; } catch (...) { diff --git a/libopenage/legacy_engine.h b/libopenage/legacy_engine.h index bc8b187dff..532a5e17d1 100644 --- a/libopenage/legacy_engine.h +++ b/libopenage/legacy_engine.h @@ -37,11 +37,6 @@ namespace gui { class GuiItemLink; } // namespace gui -namespace presenter { -class LegacyDisplay; -} // namespace presenter - - /** * Qt signals for the engine. */ @@ -201,12 +196,6 @@ class LegacyEngine final { */ std::unique_ptr logsink_file; - /** - * old, deprecated, and initial implementation of the renderer and game simulation. - * TODO: remove - */ - std::unique_ptr old_display; - public: /** * Signal emitting capability for the engine. diff --git a/libopenage/presenter/CMakeLists.txt b/libopenage/presenter/CMakeLists.txt index 5041bacc2c..5a824fab5a 100644 --- a/libopenage/presenter/CMakeLists.txt +++ b/libopenage/presenter/CMakeLists.txt @@ -1,5 +1,3 @@ add_sources(libopenage presenter.cpp ) - -add_subdirectory("legacy") diff --git a/libopenage/presenter/legacy/CMakeLists.txt b/libopenage/presenter/legacy/CMakeLists.txt deleted file mode 100644 index 0c5905d0b5..0000000000 --- a/libopenage/presenter/legacy/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -add_sources(libopenage - legacy.cpp -) - -pxdgen( - legacy.h -) diff --git a/libopenage/presenter/legacy/legacy.cpp b/libopenage/presenter/legacy/legacy.cpp deleted file mode 100644 index a959b1da35..0000000000 --- a/libopenage/presenter/legacy/legacy.cpp +++ /dev/null @@ -1,550 +0,0 @@ -// Copyright 2020-2023 the openage authors. See copying.md for legal info. - -#include "legacy.h" -#include - -#include "../../config.h" -#include "../../error/error.h" -#include "../../gamestate/old/game_main.h" -#include "../../gamestate/old/generator.h" -#include "../../gui/gui.h" -#include "../../log/log.h" -#include "../../texture.h" -#include "../../unit/selection.h" -#include "../../util/color.h" -#include "../../util/fps.h" -#include "../../util/opengl.h" -#include "../../util/strings.h" -#include "../../util/timer.h" -#include "../../version.h" -#include "legacy_engine.h" - -namespace openage::presenter { - - -LegacyDisplay::LegacyDisplay(const util::Path &path, LegacyEngine *engine) : - OptionNode{"Engine"}, - drawing_debug_overlay{this, "drawing_debug_overlay", false}, - drawing_huds{this, "drawing_huds", true}, - screenshot_manager{engine->get_job_manager()}, - action_manager{&this->input_manager, std::shared_ptr(engine->get_cvar_manager())}, - audio_manager{engine->get_job_manager()}, - input_manager{&this->action_manager} { - // TODO get this from config system (cvar) - int32_t fps_limit = 0; - if (fps_limit > 0) { - this->ns_per_frame = 1e9 / fps_limit; - } - else { - this->ns_per_frame = 0; - } - - this->font_manager = std::make_unique(); - for (uint32_t size : {12, 14, 20}) { - fonts[size] = this->font_manager->get_font("DejaVu Serif", "Book", size); - } - - // enqueue the engine's own input handler to the - // execution list. - this->register_resize_action(this); - - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - throw Error(MSG(err) << "SDL video initialization: " << SDL_GetError()); - } - else { - log::log(MSG(info) << "Initialized SDL video subsystems."); - } - - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); - SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - - int32_t window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_MAXIMIZED; - this->window = SDL_CreateWindow( - "openage", - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - this->coord.viewport_size.x, - this->coord.viewport_size.y, - window_flags); - - if (this->window == nullptr) { - throw Error(MSG(err) << "Failed to create SDL window: " << SDL_GetError()); - } - - // load support for the PNG image formats, jpg bit: IMG_INIT_JPG - int wanted_image_formats = IMG_INIT_PNG; - int sdlimg_inited = IMG_Init(wanted_image_formats); - if ((sdlimg_inited & wanted_image_formats) != wanted_image_formats) { - throw Error(MSG(err) << "Failed to init PNG support: " << IMG_GetError()); - } - - if (false) { - this->glcontext = error::create_debug_context(this->window); - } - else { - this->glcontext = SDL_GL_CreateContext(this->window); - } - - if (this->glcontext == nullptr) { - throw Error(MSG(err) << "Failed creating OpenGL context: " << SDL_GetError()); - } - - // check the OpenGL version, for shaders n stuff - if (!epoxy_is_desktop_gl() || epoxy_gl_version() < 21) { - throw Error(MSG(err) << "OpenGL 2.1 not available"); - } - - // to quote the standard doc: - // 'The value gives a rough estimate - // of the largest texture that the GL can handle' - // -> wat? - // anyways, we need at least 1024x1024. - int max_texture_size; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); - log::log(MSG(dbg) << "Maximum supported texture size: " << max_texture_size); - if (max_texture_size < 1024) { - throw Error(MSG(err) << "Maximum supported texture size too small: " << max_texture_size); - } - - int max_texture_units; - glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_texture_units); - log::log(MSG(dbg) << "Maximum supported texture units: " << max_texture_units); - if (max_texture_units < 2) { - throw Error(MSG(err) << "Your GPU has not enough texture units: " << max_texture_units); - } - - // vsync on - SDL_GL_SetSwapInterval(1); - - // enable alpha blending - glEnable(GL_BLEND); - - // order of drawing relevant for depth - // what gets drawn last is displayed on top. - glDisable(GL_DEPTH_TEST); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - //// -- initialize the gui - util::Path qml_root = engine->get_root_dir() / "assets" / "qml"; - if (not qml_root.is_dir()) { - throw Error{ERR << "could not find qml root folder " << qml_root}; - } - - util::Path qml_root_file = qml_root / "main.qml"; - if (not qml_root_file.is_file()) { - throw Error{ERR << "could not find main.qml file " << qml_root_file}; - } - - // TODO: in order to support qml-mods, the fslike and filelike - // library has to be integrated into qt. For now, - // figure out the absolute paths here and pass them in. - - std::string qml_root_str = qml_root.resolve_native_path(); - std::string qml_root_file_str = qml_root_file.resolve_native_path(); - - this->gui = std::make_unique( - this->window, // sdl window for the gui - qml_root_file_str, // entry qml file, absolute path. - qml_root_str // directory to watch for qml file changes - // &engine->get_qml_info() // qml data: Engine *, the data directory, ... - ); - //// -- gui initialization - - - // register the engines input manager - this->register_input_action(&this->input_manager); - - - // initialize engine related global keybinds - auto &global_input_context = this->get_input_manager().get_global_context(); - - input::legacy::ActionManager &action = this->get_action_manager(); - global_input_context.bind(action.get("STOP_GAME"), [engine](const input::legacy::action_arg_t &) { - engine->stop(); - }); - global_input_context.bind(action.get("TOGGLE_HUD"), [this](const input::legacy::action_arg_t &) { - this->drawing_huds.value = !this->drawing_huds.value; - }); - global_input_context.bind(action.get("SCREENSHOT"), [this](const input::legacy::action_arg_t &) { - this->get_screenshot_manager().save_screenshot(this->coord.viewport_size); - }); - global_input_context.bind(action.get("TOGGLE_DEBUG_OVERLAY"), [this](const input::legacy::action_arg_t &) { - this->drawing_debug_overlay.value = !this->drawing_debug_overlay.value; - }); - global_input_context.bind(action.get("TOGGLE_PROFILER"), [engine](const input::legacy::action_arg_t &) { - if (engine->external_profiler.currently_profiling) { - engine->external_profiler.stop(); - engine->external_profiler.show_results(); - } - else { - engine->external_profiler.start(); - } - }); - global_input_context.bind(input::legacy::event_class::MOUSE, [this](const input::legacy::action_arg_t &arg) { - if (arg.e.cc.has_class(input::legacy::event_class::MOUSE_MOTION) && this->get_input_manager().is_down(input::legacy::event_class::MOUSE_BUTTON, 2)) { - this->move_phys_camera(arg.motion.x, arg.motion.y); - return true; - } - return false; - }); - - this->text_renderer = std::make_unique(); - this->unit_selection = std::make_unique(engine); -} - - -LegacyDisplay::~LegacyDisplay() { - // deallocate the gui system - // this looses the opengl context in the qtsdl::GuiRenderer - // deallocation (of the QtOpenGLContext). - // so no gl* functions will be called after the gl context is gone. - this->gui.reset(nullptr); - - SDL_GL_DeleteContext(this->glcontext); - SDL_DestroyWindow(this->window); - IMG_Quit(); - SDL_Quit(); -} - - -bool LegacyDisplay::draw_debug_overlay() { - // Draw FPS counter in the lower right corner - this->render_text( - {this->coord.viewport_size.x - 70, 15}, - 20, - renderer::Colors::WHITE, - "%.0f fps", - this->fps_counter.display_fps); - - // Draw version string in the lower left corner - this->render_text( - {5, 35}, - 20, - renderer::Colors::WHITE, - "openage %s", - version::version); - this->render_text( - {5, 15}, - 12, - renderer::Colors::WHITE, - "%s", - config::config_option_string); - - // this->profiler.show(true); - - return true; -} - - -void LegacyDisplay::register_input_action(InputHandler *handler) { - this->on_input_event.push_back(handler); -} - - -void LegacyDisplay::register_tick_action(TickHandler *handler) { - this->on_engine_tick.push_back(handler); -} - - -void LegacyDisplay::register_drawhud_action(HudHandler *handler, int order) { - if (order < 0) { - this->on_drawhud.insert(this->on_drawhud.begin(), handler); - } - else { - this->on_drawhud.push_back(handler); - } -} - - -void LegacyDisplay::register_draw_action(DrawHandler *handler) { - this->on_drawgame.push_back(handler); -} - - -void LegacyDisplay::register_resize_action(ResizeHandler *handler) { - this->on_resize_handler.push_back(handler); -} - - -bool LegacyDisplay::on_resize(coord::viewport_delta new_size) { - // TODO: move all this to the renderer! - - log::log(MSG(dbg) << "engine window resize to " - << new_size.x << "x" << new_size.y); - - // update engine window size - this->coord.viewport_size = new_size; - - // update camgame window position, set it to center. - this->coord.camgame_viewport = coord::viewport{0, 0} + (this->coord.viewport_size / 2); - - // update camhud window position, set to lower left corner - this->coord.camhud_viewport = {0, coord::pixel_t{this->coord.viewport_size.y}}; - - // reset previous projection matrix - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - // update OpenGL viewport: the rendering area - glViewport(0, 0, this->coord.viewport_size.x, this->coord.viewport_size.y); - - // set orthographic projection: left, right, bottom, top, near_val, far_val - glOrtho(0, this->coord.viewport_size.x, 0, this->coord.viewport_size.y, 9001, -1); - - // reset the modelview matrix - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - return true; -} - - -renderer::TextRenderer *LegacyDisplay::get_text_renderer() { - return this->text_renderer.get(); -} - - -time_nsec_t LegacyDisplay::lastframe_duration_nsec() const { - return this->fps_counter.nsec_lastframe; -} - - -void LegacyDisplay::announce_global_binds() { - // emit this->gui_signals.global_binds_changed( - // this->get_input_manager().get_global_context().active_binds()); -} - - -UnitSelection *LegacyDisplay::get_unit_selection() { - return this->unit_selection.get(); -} - - -void LegacyDisplay::render_text(coord::viewport position, size_t size, const renderer::Color &color, const char *format, ...) { - auto it = this->fonts.find(size); - if (it == this->fonts.end()) { - throw Error(MSG(err) << "Unknown font size requested: " << size); - } - - renderer::Font *font = it->second; - - std::string buf; - va_list vl; - va_start(vl, format); - util::vsformat(format, vl, buf); - va_end(vl); - - this->text_renderer->set_font(font); - this->text_renderer->set_color(color); - this->text_renderer->draw(position.x, position.y, buf); -} - - -void LegacyDisplay::move_phys_camera(float x, float y, float amount) { - // calculate camera position delta from velocity and frame duration - coord::camgame_delta cam_delta{ - static_cast(+x * amount), - static_cast(-y * amount)}; - - // update camera phys position - this->coord.camgame_phys += cam_delta.to_phys3(this->coord, 0); -} - - -GameMain *LegacyDisplay::get_game() { - return this->game.get(); -} - - -void LegacyDisplay::start_game(std::unique_ptr &&game) { - // TODO: maybe implement a proper 1-to-1 connection - ENSURE(game, "linking game to engine problem"); - - this->game = std::move(game); - this->game->set_parent(this); -} - - -void LegacyDisplay::start_game(const Generator &generator) { - this->game = std::make_unique(generator); - this->game->set_parent(this); -} - - -void LegacyDisplay::end_game() { - this->game = nullptr; - this->unit_selection->clear(); -} - - -void LegacyDisplay::loop() { - //SDL_Event event; - //util::Timer cap_timer; - // - //while (this->running) { - // this->profiler.start_frame_measure(); - // this->fps_counter.frame(); - // cap_timer.reset(false); - // - // this->job_manager.execute_callbacks(); - // - // this->profiler.start_measure("events", {1.0, 0.0, 0.0}); - // // top level input handling - // while (SDL_PollEvent(&event)) { - // switch (event.type) { - // case SDL_QUIT: - // this->stop(); - // break; - // - // case SDL_WINDOWEVENT: { - // if (event.window.event == SDL_WINDOWEVENT_RESIZED) { - // coord::viewport_delta new_size{event.window.data1, event.window.data2}; - // - // // call additional handlers for the resize event - // for (auto &handler : on_resize_handler) { - // if (!handler->on_resize(new_size)) { - // break; - // } - // } - // } - // break; - // } - // - // default: - // for (auto &action : this->on_input_event) { - // if (false == action->on_input(&event)) { - // break; - // } - // } - // } // switch event - // } - // - // // here, call to Qt and process all the gui events. - // this->gui->process_events(); - // - // if (this->game) { - // // read camera movement input keys and/or cursor location, - // // and move camera accordingly. - // - // // camera movement speed, in pixels per millisecond - // // one pixel per millisecond equals 14.3 tiles/second - // float mov_x = 0.0, mov_y = 0.0, cam_movement_speed_keyboard = 0.5; - // Uint32 win_flags = SDL_GetWindowFlags(this->window); - // bool inp_focus = win_flags & SDL_WINDOW_INPUT_FOCUS; - // - // input::InputManager &input = this->get_input_manager(); - // using Edge = input::InputManager::Edge; - // - // if (inp_focus and (input.is_down(SDLK_LEFT) or input.is_mouse_at_edge(Edge::LEFT, coord.viewport_size.x))) { - // mov_x = -cam_movement_speed_keyboard; - // } - // if (inp_focus and (input.is_down(SDLK_RIGHT) or input.is_mouse_at_edge(Edge::RIGHT, coord.viewport_size.x))) { - // mov_x = cam_movement_speed_keyboard; - // } - // if (inp_focus and (input.is_down(SDLK_DOWN) or input.is_mouse_at_edge(Edge::DOWN, coord.viewport_size.y))) { - // mov_y = cam_movement_speed_keyboard; - // } - // if (inp_focus and (input.is_down(SDLK_UP) or input.is_mouse_at_edge(Edge::UP, coord.viewport_size.y))) { - // mov_y = -cam_movement_speed_keyboard; - // } - // - // // perform camera movement - // this->move_phys_camera( - // mov_x, - // mov_y, - // static_cast(this->lastframe_duration_nsec()) / 1e6); - // - // // update the currently running game - // this->game->update(this->lastframe_duration_nsec()); - // } - // this->profiler.end_measure("events"); - // - // // call engine tick callback methods - // for (auto &action : this->on_engine_tick) { - // if (false == action->on_tick()) { - // break; - // } - // } - // - // this->profiler.start_measure("rendering", {0.0, 1.0, 0.0}); - // - // // clear the framebuffer to black - // // in the future, we might disable it for lazy drawing - // glClearColor(0.0, 0.0, 0.0, 0.0); - // glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - // - // // invoke all game drawing handlers - // for (auto &action : this->on_drawgame) { - // if (false == action->on_draw()) { - // break; - // } - // } - // - // util::gl_check_error(); - // - // // draw the fps overlay - // if (this->drawing_debug_overlay.value) { - // this->draw_debug_overlay(); - // } - // - // // invoke all hud drawing callback methods - // if (this->drawing_huds.value) { - // for (auto &action : this->on_drawhud) { - // if (false == action->on_drawhud()) { - // break; - // } - // } - // } - // - // this->text_renderer->render(); - // - // util::gl_check_error(); - // - // this->profiler.end_measure("rendering"); - // - // this->profiler.start_measure("idle", {0.0, 0.0, 1.0}); - // - // // the rendering is done - // // swap the drawing buffers to actually show the frame - // SDL_GL_SwapWindow(window); - // - // if (this->ns_per_frame != 0) { - // uint64_t ns_for_current_frame = cap_timer.getval(); - // if (ns_for_current_frame < this->ns_per_frame) { - // SDL_Delay((this->ns_per_frame - ns_for_current_frame) / 1e6); - // } - // } - // - // this->profiler.end_measure("idle"); - // - // this->profiler.end_frame_measure(); - //} -} - - -audio::AudioManager &LegacyDisplay::get_audio_manager() { - return this->audio_manager; -} - - -ScreenshotManager &LegacyDisplay::get_screenshot_manager() { - return this->screenshot_manager; -} - - -input::legacy::ActionManager &LegacyDisplay::get_action_manager() { - return this->action_manager; -} - - -input::legacy::InputManager &LegacyDisplay::get_input_manager() { - return this->input_manager; -} - - -} // namespace openage::presenter diff --git a/libopenage/presenter/legacy/legacy.h b/libopenage/presenter/legacy/legacy.h deleted file mode 100644 index 9ee18ab1c9..0000000000 --- a/libopenage/presenter/legacy/legacy.h +++ /dev/null @@ -1,302 +0,0 @@ -// Copyright 2020-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include "../../audio/audio_manager.h" -// pxd: from libopenage.coord.coordmanager cimport CoordManager -#include "../../coord/coordmanager.h" -#include "../../error/gl_debug.h" -#include "../../handlers.h" -// pxd: from libopenage.input.input_manager cimport InputManager -#include "../../input/legacy/input_manager.h" -#include "../../options.h" -#include "../../renderer/font/font.h" -#include "../../renderer/font/font_manager.h" -#include "../../renderer/text.h" -#include "../../screenshot.h" -#include "../../util/fps.h" -#include "../../util/path.h" -#include "../../util/timing.h" - - -namespace openage { - -class DrawHandler; -class TickHandler; -class ResizeHandler; - -class Generator; -class GameSpec; -class GameMain; -class UnitSelection; - -namespace gui { -class GUI; -} // namespace gui - -namespace renderer { - -class Font; -class FontManager; -class TextRenderer; -class Color; - -} // namespace renderer - - -namespace presenter { - -/** - * Temporary container class for the legacy renderer implementation. - */ -class [[deprecated]] LegacyDisplay final : public ResizeHandler - , public options::OptionNode { -public: - LegacyDisplay(const util::Path &path, LegacyEngine *engine); - - ~LegacyDisplay(); - - /** - * Draw the game version and the current FPS on screen. - */ - bool draw_debug_overlay(); - - /** - * register a new input event handler, run for each input event. - */ - void register_input_action(InputHandler *handler); - - /** - * register a tick action, executed upon engine tick. - */ - void register_tick_action(TickHandler *handler); - - /** - * register a hud drawing handler, drawn in hud coordinates. - * order: 1 above, -1 below - */ - void register_drawhud_action(HudHandler *handler, int order = 1); - - /** - * register a draw handler, run in game coordinates. - */ - void register_draw_action(DrawHandler *handler); - - /** - * register a resize handler, run when the window size changes. - */ - void register_resize_action(ResizeHandler *handler); - - /** - * window resize handler function. - * recalculates opengl settings like viewport and projection matrices. - */ - bool on_resize(coord::viewport_delta new_size) override; - - /** - * return this engine's text renderer. - */ - renderer::TextRenderer *get_text_renderer(); - - /** - * return the number of nanoseconds that have passed - * for rendering the last frame. - * - * use that for fps-independent input actions. - */ - time_nsec_t lastframe_duration_nsec() const; - - /** - * send keybindings help string to gui. - */ - void announce_global_binds(); - - /** - * return this engine's unit selection. - */ - UnitSelection *get_unit_selection(); - - /** - * render text at a position with the specified font size - */ - void render_text(coord::viewport position, size_t size, const renderer::Color &color, const char *format, ...) ATTRIBUTE_FORMAT(5, 6); - - /** - * move the phys3 camera incorporated in the engine - */ - void move_phys_camera(float x, float y, float amount = 1.0); - - /** - * Start a game with the given game generator. - */ - void start_game(const Generator &generator); - - /** - * Start a game with the given initialized game. - */ - void start_game(std::unique_ptr &&game); - - /** - * Stop the running game. - */ - void end_game(); - - /** - * return currently running game or null if a game is not - * currently running - */ - GameMain *get_game(); - - /** - * legacy engine loop function. - * this will be looped once per frame when the game is running. - * - * the loop invokes fps counting, SDL event handling, - * view translation, and calling the main draw_method. - */ - void loop(); - -public: - /** - * return this engine's audio manager. - */ - audio::AudioManager &get_audio_manager(); - - /** - * return this engine's screenshot manager. - */ - ScreenshotManager &get_screenshot_manager(); - - /** - * return this engine's action manager. - */ - input::legacy::ActionManager &get_action_manager(); - - /** - * return this engine's keybind manager. - */ - input::legacy::InputManager &get_input_manager(); - - /** - * FPS and game version are drawn when this is true. - */ - options::Var drawing_debug_overlay; - - /** - * this allows to disable drawing of every registered hud. - */ - options::Var drawing_huds; - - /** - * The coordinate state. - */ - coord::CoordManager coord; - -private: - /** - * the currently running game - */ - std::unique_ptr game; - - /** - * how many nanoseconds are in a frame (1e9 / fps_limit). - * 0 if there is no fps limit. - */ - time_nsec_t ns_per_frame; - - /** - * input event processor objects. - * called for each captured sdl input event. - */ - std::vector on_input_event; - - /** - * run every time the game is being drawn, - * with the renderer set to the camgame system - */ - std::vector on_drawgame; - - /** - * run every time the hud is being drawn, - * with the renderer set to the camhud system - */ - std::vector on_drawhud; - - /** - * list of handlers that are executed upon a resize event. - */ - std::vector on_resize_handler; - - /** - * run on every engine tick, after input handling, before rendering - */ - std::vector on_engine_tick; - - /** - * the frame counter measuring fps. - */ - util::FrameCounter fps_counter; - - /** - * the engine's screenshot manager. - */ - ScreenshotManager screenshot_manager; - - /** - * the engine's action manager. - */ - input::legacy::ActionManager action_manager; - - /** - * the engine's audio manager. - */ - audio::AudioManager audio_manager; - - /** - * the engine's keybind manager. - */ - input::legacy::InputManager input_manager; - - /** - * the engine's unit selection. - */ - std::unique_ptr unit_selection; - - /** - * the text fonts to be used for (can you believe it?) texts. - * maps fontsize -> font - */ - std::unordered_map fonts; - - /** - * SDL window where everything is displayed within. - */ - SDL_Window *window; - - /** - * SDL OpenGL context, we'll only have one, - * but it would allow having multiple ones. - * - * This is actually a void * but sdl2 thought it was a good idea to - * name it like a differently. - */ - SDL_GLContext glcontext; - - /** - * Qt GUI system - */ - std::unique_ptr gui; - - /** - * ttf font loading manager - */ - std::unique_ptr font_manager; - - /** - * 2d text renderer - */ - std::unique_ptr text_renderer; -}; - -} // namespace presenter -} // namespace openage diff --git a/libopenage/terrain/terrain.cpp b/libopenage/terrain/terrain.cpp index a360878984..325db0a5d5 100644 --- a/libopenage/terrain/terrain.cpp +++ b/libopenage/terrain/terrain.cpp @@ -271,55 +271,6 @@ bool Terrain::check_tile_position(const coord::tile & /*pos*/) { } } -void Terrain::draw(presenter::LegacyDisplay *display, RenderOptions *settings) { - // TODO: move this draw invokation to a render manager. - // it can reorder the draw instructions and minimize texture switching. - - // query the window coordinates from the display first - coord::viewport wbl = coord::viewport{0, 0}; - coord::viewport wbr = coord::viewport{display->coord.viewport_size.x, 0}; - coord::viewport wtl = coord::viewport{0, display->coord.viewport_size.y}; - coord::viewport wtr = coord::viewport{display->coord.viewport_size.x, display->coord.viewport_size.y}; - - // top left, bottom right tile coordinates - // that are currently visible in the window - // then convert them to tile coordinates. - coord::tile tl = wtl.to_tile(display->coord); - coord::tile tr = wtr.to_tile(display->coord); - coord::tile bl = wbl.to_tile(display->coord); - coord::tile br = wbr.to_tile(display->coord); - - // main terrain calculation call: get the `terrain_render_data` - auto draw_data = this->create_draw_advice(tl, tr, br, bl, true); - - // TODO: the following loop is totally inefficient and shit. - // it reloads the drawing texture to the gpu FOR EACH TILE! - // nevertheless, currently it works. - - // draw the terrain ground - for (auto &tile : draw_data.tiles) { - // iterate over all layers to be drawn - for (int i = 0; i < tile.count; i++) { - struct tile_data *layer = &tile.data[i]; - - // position, where the tile is drawn - coord::tile tile_pos = layer->pos; - - int mask_id = layer->mask_id; - Texture *texture = layer->tex; - int subtexture_id = layer->subtexture_id; - Texture *mask_texture = layer->mask_tex; - - texture->draw(display->coord, *this, tile_pos, ALPHAMASKED, subtexture_id, mask_texture, mask_id); - } - } - - // TODO: drawing buildings can't be the job of the terrain.. - // draw the buildings - for (auto &object : draw_data.objects) { - // object->draw(*display); - } -} struct terrain_render_data Terrain::create_draw_advice(const coord::tile &ab, const coord::tile &cd, diff --git a/libopenage/terrain/terrain.h b/libopenage/terrain/terrain.h index c33cd43dee..fcde460ad7 100644 --- a/libopenage/terrain/terrain.h +++ b/libopenage/terrain/terrain.h @@ -13,7 +13,6 @@ #include "../coord/phys.h" #include "../coord/pixel.h" #include "../coord/tile.h" -#include "../presenter/legacy/legacy.h" #include "../texture.h" #include "../util/misc.h" @@ -323,12 +322,6 @@ class Terrain { */ int get_blending_mode(terrain_t base_id, terrain_t neighbor_id); - /** - * draw the currently visible terrain area on screen. - * @param display: the display where the terrain should be drawn to. - */ - void draw(presenter::LegacyDisplay *display, RenderOptions *settings); - /** * create the drawing instruction data. * From 5236d44bea6b651a5b71e7c615cbe5e68493b26b Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 23 Sep 2023 01:43:03 +0200 Subject: [PATCH 31/95] renderer: Remove old texture code. --- libopenage/CMakeLists.txt | 1 - libopenage/game_renderer.cpp | 210 -------- libopenage/gamestate/old/game_spec.cpp | 25 - libopenage/gamestate/old/game_spec.h | 10 - libopenage/gui/gui.cpp | 13 +- libopenage/gui/gui.h | 4 - .../gui/integration/private/CMakeLists.txt | 4 - ...e_spec_image_provider_by_filename_impl.cpp | 50 -- ...ame_spec_image_provider_by_filename_impl.h | 27 -- ...spec_image_provider_by_graphic_id_impl.cpp | 31 -- ...e_spec_image_provider_by_graphic_id_impl.h | 27 -- ...ui_game_spec_image_provider_by_id_impl.cpp | 45 -- .../gui_game_spec_image_provider_by_id_impl.h | 25 - ...spec_image_provider_by_terrain_id_impl.cpp | 32 -- ...e_spec_image_provider_by_terrain_id_impl.h | 27 -- .../gui_game_spec_image_provider_impl.cpp | 32 +- .../gui_game_spec_image_provider_impl.h | 21 +- .../private/gui_image_provider_link.cpp | 40 +- .../private/gui_image_provider_link.h | 14 +- .../gui/integration/private/gui_texture.cpp | 38 +- .../private/gui_texture_factory.cpp | 13 +- .../private/gui_texture_handle.cpp | 28 +- .../integration/private/gui_texture_handle.h | 8 +- .../gui/integration/public/CMakeLists.txt | 1 - .../public/gui_game_spec_image_provider.cpp | 37 -- .../public/gui_game_spec_image_provider.h | 26 - libopenage/pathfinding/path.cpp | 47 +- libopenage/pathfinding/path.h | 40 +- libopenage/renderer/gui/gui.h | 3 - libopenage/shader/program.h | 7 +- libopenage/shader/shader.h | 9 +- libopenage/terrain/CMakeLists.txt | 1 - libopenage/terrain/terrain.cpp | 30 +- libopenage/terrain/terrain.h | 16 - libopenage/terrain/terrain_chunk.cpp | 1 - libopenage/terrain/terrain_chunk.h | 3 +- libopenage/terrain/terrain_object.cpp | 16 - libopenage/terrain/terrain_object.h | 13 - libopenage/terrain/terrain_outline.cpp | 60 --- libopenage/terrain/terrain_outline.h | 23 - libopenage/texture.cpp | 447 ------------------ libopenage/texture.h | 188 -------- libopenage/unit/producer.cpp | 33 +- libopenage/unit/producer.h | 17 +- libopenage/unit/unit_texture.cpp | 122 +---- libopenage/unit/unit_texture.h | 34 +- 46 files changed, 127 insertions(+), 1772 deletions(-) delete mode 100644 libopenage/game_renderer.cpp delete mode 100644 libopenage/gui/integration/private/gui_game_spec_image_provider_by_filename_impl.cpp delete mode 100644 libopenage/gui/integration/private/gui_game_spec_image_provider_by_filename_impl.h delete mode 100644 libopenage/gui/integration/private/gui_game_spec_image_provider_by_graphic_id_impl.cpp delete mode 100644 libopenage/gui/integration/private/gui_game_spec_image_provider_by_graphic_id_impl.h delete mode 100644 libopenage/gui/integration/private/gui_game_spec_image_provider_by_id_impl.cpp delete mode 100644 libopenage/gui/integration/private/gui_game_spec_image_provider_by_id_impl.h delete mode 100644 libopenage/gui/integration/private/gui_game_spec_image_provider_by_terrain_id_impl.cpp delete mode 100644 libopenage/gui/integration/private/gui_game_spec_image_provider_by_terrain_id_impl.h delete mode 100644 libopenage/gui/integration/public/gui_game_spec_image_provider.cpp delete mode 100644 libopenage/gui/integration/public/gui_game_spec_image_provider.h delete mode 100644 libopenage/terrain/terrain_outline.cpp delete mode 100644 libopenage/terrain/terrain_outline.h delete mode 100644 libopenage/texture.cpp delete mode 100644 libopenage/texture.h diff --git a/libopenage/CMakeLists.txt b/libopenage/CMakeLists.txt index f1772bfc36..8c17eaa9d5 100644 --- a/libopenage/CMakeLists.txt +++ b/libopenage/CMakeLists.txt @@ -327,7 +327,6 @@ add_sources(libopenage main.cpp options.cpp screenshot.cpp - texture.cpp ${CMAKE_CURRENT_BINARY_DIR}/config.cpp ${CMAKE_CURRENT_BINARY_DIR}/version.cpp ${CODEGEN_SCU_FILE} diff --git a/libopenage/game_renderer.cpp b/libopenage/game_renderer.cpp deleted file mode 100644 index 530d87ad92..0000000000 --- a/libopenage/game_renderer.cpp +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include -#include -#include -#include -#include - -#include "console/console.h" -#include "game_renderer.h" -#include "gamedata/color_dummy.h" -#include "gamestate/old/game_main.h" -#include "gamestate/old/game_spec.h" -#include "input/input_manager.h" -#include "legacy_engine.h" -#include "log/log.h" -#include "renderer/text.h" -#include "terrain/terrain.h" -#include "unit/action.h" -#include "unit/command.h" -#include "unit/producer.h" -#include "unit/unit.h" -#include "unit/unit_texture.h" -#include "util/externalprofiler.h" -#include "util/timer.h" - -namespace openage { - -RenderOptions::RenderOptions() : - OptionNode{"RendererOptions"}, - draw_debug{this, "draw_debug", false}, - terrain_blending{this, "terrain_blending", true} {} - -GameRenderer::GameRenderer(LegacyEngine *e) : - engine{e} { - // set options structure - this->settings.set_parent(this->engine); - - // engine callbacks - this->engine->register_draw_action(this); - - // fetch asset loading dir - util::Path asset_dir = engine->get_root_dir()["assets"]; - - // load textures and stuff - gaben = new Texture{asset_dir["test"]["textures"]["gaben.png"]}; - - std::vector player_color_lines = util::read_csv_file( - asset_dir["converted/player_palette.docx"]); - - std::unique_ptr playercolors = std::make_unique(player_color_lines.size() * 4); - for (size_t i = 0; i < player_color_lines.size(); i++) { - auto line = &player_color_lines[i]; - playercolors[i * 4] = line->r / 255.0; - playercolors[i * 4 + 1] = line->g / 255.0; - playercolors[i * 4 + 2] = line->b / 255.0; - playercolors[i * 4 + 3] = line->a / 255.0; - } - - // shader initialisation - // read shader source codes and create shader objects for wrapping them. - const char *shader_header_code = "#version 120\n"; - std::string equals_epsilon_code = asset_dir["shaders/equalsEpsilon.glsl"].open().read(); - std::string texture_vert_code = asset_dir["shaders/maptexture.vert.glsl"].open().read(); - auto plaintexture_vert = std::make_unique( - GL_VERTEX_SHADER, - std::initializer_list{shader_header_code, texture_vert_code.c_str()}); - - std::string texture_frag_code = asset_dir["shaders/maptexture.frag.glsl"].open().read(); - auto plaintexture_frag = std::make_unique( - GL_FRAGMENT_SHADER, - std::initializer_list{shader_header_code, texture_frag_code.c_str()}); - - std::string teamcolor_frag_code = asset_dir["shaders/teamcolors.frag.glsl"].open().read(); - std::stringstream ss; - ss << player_color_lines.size(); - auto teamcolor_frag = std::make_unique( - GL_FRAGMENT_SHADER, - std::initializer_list{ - shader_header_code, - ("#define NUM_OF_PLAYER_COLORS " + ss.str() + "\n").c_str(), - equals_epsilon_code.c_str(), - teamcolor_frag_code.c_str()}); - - std::string alphamask_vert_code = asset_dir["shaders/alphamask.vert.glsl"].open().read(); - auto alphamask_vert = std::make_unique( - GL_VERTEX_SHADER, - std::initializer_list{shader_header_code, alphamask_vert_code.c_str()}); - - std::string alphamask_frag_code = asset_dir["shaders/alphamask.frag.glsl"].open().read(); - auto alphamask_frag = std::make_unique( - GL_FRAGMENT_SHADER, - std::initializer_list{shader_header_code, alphamask_frag_code.c_str()}); - - std::string texturefont_vert_code = asset_dir["shaders/texturefont.vert.glsl"].open().read(); - auto texturefont_vert = std::make_unique( - GL_VERTEX_SHADER, - std::initializer_list{shader_header_code, texturefont_vert_code.c_str()}); - - std::string texturefont_frag_code = asset_dir["shaders/texturefont.frag.glsl"].open().read(); - auto texturefont_frag = std::make_unique( - GL_FRAGMENT_SHADER, - std::initializer_list{shader_header_code, texturefont_frag_code.c_str()}); - - // create program for rendering simple textures - texture_shader::program = new shader::Program(plaintexture_vert.get(), plaintexture_frag.get()); - texture_shader::program->link(); - texture_shader::texture = texture_shader::program->get_uniform_id("texture"); - texture_shader::tex_coord = texture_shader::program->get_attribute_id("tex_coordinates"); - texture_shader::program->use(); - glUniform1i(texture_shader::texture, 0); - texture_shader::program->stopusing(); - - - // create program for tinting textures at alpha-marked pixels - // with team colors - teamcolor_shader::program = new shader::Program(plaintexture_vert.get(), teamcolor_frag.get()); - teamcolor_shader::program->link(); - teamcolor_shader::texture = teamcolor_shader::program->get_uniform_id("texture"); - teamcolor_shader::tex_coord = teamcolor_shader::program->get_attribute_id("tex_coordinates"); - teamcolor_shader::player_id_var = teamcolor_shader::program->get_uniform_id("player_number"); - teamcolor_shader::alpha_marker_var = teamcolor_shader::program->get_uniform_id("alpha_marker"); - teamcolor_shader::player_color_var = teamcolor_shader::program->get_uniform_id("player_color"); - teamcolor_shader::program->use(); - glUniform1i(teamcolor_shader::texture, 0); - glUniform1f(teamcolor_shader::alpha_marker_var, 254.0 / 255.0); - // fill the teamcolor shader's player color table: - glUniform4fv(teamcolor_shader::player_color_var, 64, playercolors.get()); - teamcolor_shader::program->stopusing(); - - - // create program for drawing textures that are alpha-masked before - alphamask_shader::program = new shader::Program(alphamask_vert.get(), alphamask_frag.get()); - alphamask_shader::program->link(); - alphamask_shader::base_coord = alphamask_shader::program->get_attribute_id("base_tex_coordinates"); - alphamask_shader::mask_coord = alphamask_shader::program->get_attribute_id("mask_tex_coordinates"); - alphamask_shader::show_mask = alphamask_shader::program->get_uniform_id("show_mask"); - alphamask_shader::base_texture = alphamask_shader::program->get_uniform_id("base_texture"); - alphamask_shader::mask_texture = alphamask_shader::program->get_uniform_id("mask_texture"); - alphamask_shader::program->use(); - glUniform1i(alphamask_shader::base_texture, 0); - glUniform1i(alphamask_shader::mask_texture, 1); - alphamask_shader::program->stopusing(); - - // Create program for texture based font rendering - texturefont_shader::program = new shader::Program(texturefont_vert.get(), texturefont_frag.get()); - texturefont_shader::program->link(); - texturefont_shader::texture = texturefont_shader::program->get_uniform_id("texture"); - texturefont_shader::color = texturefont_shader::program->get_uniform_id("color"); - texturefont_shader::tex_coord = texturefont_shader::program->get_attribute_id("tex_coordinates"); - texturefont_shader::program->use(); - glUniform1i(texturefont_shader::texture, 0); - texturefont_shader::program->stopusing(); - - // Renderer keybinds - // TODO: a renderer settings struct - // would allow these to be put somewhere better - input::ActionManager &action = this->engine->get_action_manager(); - auto &global_input_context = engine->get_input_manager().get_global_context(); - global_input_context.bind(action.get("TOGGLE_BLENDING"), [this](const input::action_arg_t &) { - this->settings.terrain_blending.value = !this->settings.terrain_blending.value; - }); - global_input_context.bind(action.get("TOGGLE_UNIT_DEBUG"), [this](const input::action_arg_t &) { - this->settings.draw_debug.value = !this->settings.draw_debug.value; - - log::log(MSG(dbg) << "Toggle debug grid"); - - // TODO remove this hack, use render settings instead - UnitAction::show_debug = !UnitAction::show_debug; - }); - - log::log(MSG(dbg) << "Loaded Renderer"); -} - -GameRenderer::~GameRenderer() { - // oh noes, release hl3 before that! - delete this->gaben; - - delete texture_shader::program; - delete teamcolor_shader::program; - delete alphamask_shader::program; - delete texturefont_shader::program; -} - - -bool GameRenderer::on_draw() { - // draw terrain - GameMain *game = this->engine->get_game(); - - if (game) { - // draw gaben, our great and holy protector, bringer of the half-life 3. - gaben->draw(this->engine->coord, coord::camgame{0, 0}); - - // TODO move render code out of terrain - if (game->terrain) { - game->terrain->draw(this->engine, &this->settings); - } - } - return true; -} - -GameMain *GameRenderer::game() const { - return this->engine->get_game(); -} - -GameSpec *GameRenderer::game_spec() const { - return this->game()->get_spec(); -} - -} // namespace openage diff --git a/libopenage/gamestate/old/game_spec.cpp b/libopenage/gamestate/old/game_spec.cpp index 048fbc4ce9..d696b748f5 100644 --- a/libopenage/gamestate/old/game_spec.cpp +++ b/libopenage/gamestate/old/game_spec.cpp @@ -82,31 +82,6 @@ index_t GameSpec::get_slp_graphic(index_t slp) { return this->slp_to_graphic[slp]; } -Texture *GameSpec::get_texture(index_t graphic_id) const { - if (graphic_id <= 0 || this->graphics.count(graphic_id) == 0) { - log::log(MSG(dbg) << " -> ignoring graphics_id: " << graphic_id); - return nullptr; - } - - auto g = this->graphics.at(graphic_id); - int slp_id = g->slp_id; - if (slp_id <= 0) { - log::log(MSG(dbg) << " -> ignoring negative slp_id: " << slp_id); - return nullptr; - } - - log::log(MSG(dbg) << " slp id/name: " << slp_id << " " << g->name); - std::string tex_fname = util::sformat("converted/graphics/%d.slp.png", slp_id); - - return this->get_texture(tex_fname, true); -} - -Texture *GameSpec::get_texture(const std::string &file_name, bool use_metafile) const { - // return nullptr if the texture wasn't found (3rd param) - // return this->assetmanager->get_texture(file_name, use_metafile, true); - return nullptr; -} - std::shared_ptr GameSpec::get_unit_texture(index_t unit_id) const { if (this->unit_textures.count(unit_id) == 0) { if (unit_id > 0) { diff --git a/libopenage/gamestate/old/game_spec.h b/libopenage/gamestate/old/game_spec.h index 0fc34dcd40..b1377fd2d9 100644 --- a/libopenage/gamestate/old/game_spec.h +++ b/libopenage/gamestate/old/game_spec.h @@ -90,16 +90,6 @@ class GameSpec { */ index_t get_slp_graphic(index_t slp); - /** - * lookup using a texture id, this specifically avoids returning the missing placeholder texture - */ - Texture *get_texture(index_t graphic_id) const; - - /** - * lookup using a texture file name - */ - Texture *get_texture(const std::string &file_name, bool use_metafile = true) const; - /** * get unit texture by graphic id -- this is an directional texture * which also includes graphic deltas diff --git a/libopenage/gui/gui.cpp b/libopenage/gui/gui.cpp index ebaf20b24a..d8ffe9e3e2 100644 --- a/libopenage/gui/gui.cpp +++ b/libopenage/gui/gui.cpp @@ -23,20 +23,9 @@ GUI::GUI(SDL_Window *window, render_updater{}, renderer{window}, game_logic_updater{}, - image_provider_by_filename{ - &render_updater, - GuiGameSpecImageProvider::Type::ByFilename}, - image_provider_by_graphic_id{ - &render_updater, - GuiGameSpecImageProvider::Type::ByGraphicId}, - image_provider_by_terrain_id{ - &render_updater, - GuiGameSpecImageProvider::Type::ByTerrainId}, engine{ &renderer, - {&image_provider_by_filename, - &image_provider_by_graphic_id, - &image_provider_by_terrain_id}, + {}, info}, subtree{ &renderer, diff --git a/libopenage/gui/gui.h b/libopenage/gui/gui.h index 0abb70ff5e..d5adadef70 100644 --- a/libopenage/gui/gui.h +++ b/libopenage/gui/gui.h @@ -12,7 +12,6 @@ #include "guisys/public/gui_renderer.h" #include "guisys/public/gui_subtree.h" #include "integration/public/gui_application_with_logger.h" -#include "integration/public/gui_game_spec_image_provider.h" namespace qtsdl { @@ -58,9 +57,6 @@ class GUI : public InputHandler qtsdl::GuiEventQueue render_updater; qtsdl::GuiRenderer renderer; qtsdl::GuiEventQueue game_logic_updater; - GuiGameSpecImageProvider image_provider_by_filename; - GuiGameSpecImageProvider image_provider_by_graphic_id; - GuiGameSpecImageProvider image_provider_by_terrain_id; qtsdl::GuiEngine engine; qtsdl::GuiSubtree subtree; qtsdl::GuiInput input; diff --git a/libopenage/gui/integration/private/CMakeLists.txt b/libopenage/gui/integration/private/CMakeLists.txt index 97f03fc4f4..f727980b6f 100644 --- a/libopenage/gui/integration/private/CMakeLists.txt +++ b/libopenage/gui/integration/private/CMakeLists.txt @@ -1,9 +1,5 @@ add_sources(libopenage gui_filled_texture_handles.cpp - gui_game_spec_image_provider_by_filename_impl.cpp - gui_game_spec_image_provider_by_graphic_id_impl.cpp - gui_game_spec_image_provider_by_id_impl.cpp - gui_game_spec_image_provider_by_terrain_id_impl.cpp gui_game_spec_image_provider_impl.cpp gui_image_provider_link.cpp gui_log.cpp diff --git a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_filename_impl.cpp b/libopenage/gui/integration/private/gui_game_spec_image_provider_by_filename_impl.cpp deleted file mode 100644 index 216422e5ba..0000000000 --- a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_filename_impl.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2015-2021 the openage authors. See copying.md for legal info. - -#include "gui_game_spec_image_provider_by_filename_impl.h" - -#include "../../../error/error.h" - -#include "../../../gamestate/old/game_spec.h" - -namespace openage::gui { - -GuiGameSpecImageProviderByFilenameImpl::GuiGameSpecImageProviderByFilenameImpl(qtsdl::GuiEventQueue *render_updater) - : - GuiGameSpecImageProviderImpl{render_updater} { -} - -GuiGameSpecImageProviderByFilenameImpl::~GuiGameSpecImageProviderByFilenameImpl() = default; - -const char* GuiGameSpecImageProviderByFilenameImpl::id() { - return "by-filename"; -} - -const char* GuiGameSpecImageProviderByFilenameImpl::get_id() const { - return GuiGameSpecImageProviderByFilenameImpl::id(); -} - -TextureHandle GuiGameSpecImageProviderByFilenameImpl::get_texture_handle(const QString &id) { - ENSURE(this->loaded_game_spec, "trying to actually get a texture from a non-loaded spec"); - - auto filename = id.section(".", 0, -2); - auto subid_str = id.section(".", -1, -1); - - bool ok = false; - const int subid = subid_str.toInt(&ok); - - if (not filename.isEmpty() and ok) { - auto tex = this->loaded_game_spec->get_texture(filename.toStdString()); - - if (tex != nullptr) { - return TextureHandle{tex, subid}; - } - else { - return this->get_missing_texture(); - } - } else { - qWarning("Invalid texture id: 'image://%s/%s'. Example formatting: 'image://%s/myfile.png.18'.", this->get_id(), qUtf8Printable(id), this->get_id()); - return this->get_missing_texture(); - } -} - -} // namespace openage::gui diff --git a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_filename_impl.h b/libopenage/gui/integration/private/gui_game_spec_image_provider_by_filename_impl.h deleted file mode 100644 index 0def78ae82..0000000000 --- a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_filename_impl.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include "gui_game_spec_image_provider_impl.h" - -namespace openage { -namespace gui { - -/** - * Exposes game textures to the Qt by their file name. - * - * Id has a form of . where is an integer. - */ -class GuiGameSpecImageProviderByFilenameImpl : public GuiGameSpecImageProviderImpl { -public: - explicit GuiGameSpecImageProviderByFilenameImpl(qtsdl::GuiEventQueue *render_updater); - virtual ~GuiGameSpecImageProviderByFilenameImpl(); - - static const char* id(); - -private: - virtual const char* get_id() const override; - virtual TextureHandle get_texture_handle(const QString &id) override; -}; - -}} // namespace openage::gui diff --git a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_graphic_id_impl.cpp b/libopenage/gui/integration/private/gui_game_spec_image_provider_by_graphic_id_impl.cpp deleted file mode 100644 index ede6e5ef21..0000000000 --- a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_graphic_id_impl.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2015-2021 the openage authors. See copying.md for legal info. - -#include "gui_game_spec_image_provider_by_graphic_id_impl.h" - -#include "../../../error/error.h" - -#include "../../../gamestate/old/game_spec.h" - -namespace openage::gui { - -GuiGameSpecImageProviderByGraphicIdImpl::GuiGameSpecImageProviderByGraphicIdImpl(qtsdl::GuiEventQueue *render_updater) - : - GuiGameSpecImageProviderByIdImpl{render_updater} { -} - -GuiGameSpecImageProviderByGraphicIdImpl::~GuiGameSpecImageProviderByGraphicIdImpl() = default; - -const char* GuiGameSpecImageProviderByGraphicIdImpl::id() { - return "by-graphic-id"; -} - -const char* GuiGameSpecImageProviderByGraphicIdImpl::get_id() const { - return GuiGameSpecImageProviderByGraphicIdImpl::id(); -} - -openage::Texture* GuiGameSpecImageProviderByGraphicIdImpl::get_texture(int texture_id) { - ENSURE(this->loaded_game_spec, "trying to actually get a texture from a non-loaded spec"); - return this->loaded_game_spec->get_texture(texture_id); -} - -} // namespace openage::gui diff --git a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_graphic_id_impl.h b/libopenage/gui/integration/private/gui_game_spec_image_provider_by_graphic_id_impl.h deleted file mode 100644 index 02e1c1be4b..0000000000 --- a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_graphic_id_impl.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include "gui_game_spec_image_provider_by_id_impl.h" - -namespace openage { -namespace gui { - -/** - * Exposes game textures to the Qt by their id. - * - * Numeric id has a form of .. - */ -class GuiGameSpecImageProviderByGraphicIdImpl : public GuiGameSpecImageProviderByIdImpl { -public: - explicit GuiGameSpecImageProviderByGraphicIdImpl(qtsdl::GuiEventQueue *render_updater); - virtual ~GuiGameSpecImageProviderByGraphicIdImpl(); - - static const char* id(); - -private: - virtual const char* get_id() const override; - virtual openage::Texture* get_texture(int texture_id) override; -}; - -}} // namespace openage::gui diff --git a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_id_impl.cpp b/libopenage/gui/integration/private/gui_game_spec_image_provider_by_id_impl.cpp deleted file mode 100644 index 82752e06de..0000000000 --- a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_id_impl.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "gui_game_spec_image_provider_by_id_impl.h" - -#include "../../../error/error.h" - -#include "../../../gamestate/old/game_spec.h" -#include "gui_texture_factory.h" - -namespace openage::gui { - -GuiGameSpecImageProviderByIdImpl::GuiGameSpecImageProviderByIdImpl(qtsdl::GuiEventQueue *render_updater) : - GuiGameSpecImageProviderImpl{render_updater} { -} - -GuiGameSpecImageProviderByIdImpl::~GuiGameSpecImageProviderByIdImpl() = default; - -TextureHandle GuiGameSpecImageProviderByIdImpl::get_texture_handle(const QString &id) { - ENSURE(this->loaded_game_spec, "trying to actually get a texture from a non-loaded spec"); - - auto ids = id.split("."); - - if (ids.size() == 2) { - bool id_ok = false, subid_ok = false; - const int texture_id = ids[0].toInt(&id_ok); - const int subid = ids[1].toInt(&subid_ok); - - auto tex = (id_ok and subid_ok) ? - this->get_texture(texture_id) : - nullptr; - - if (tex != nullptr and subid < static_cast(tex->get_subtexture_count())) { - return TextureHandle{tex, subid}; - } - else { - return this->get_missing_texture(); - } - } - else { - qWarning("Invalid texture id: 'image://%s/%s'. Example formatting: 'image://%s/7366.18'.", this->get_id(), qUtf8Printable(id), this->get_id()); - return this->get_missing_texture(); - } -} - -} // namespace openage::gui diff --git a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_id_impl.h b/libopenage/gui/integration/private/gui_game_spec_image_provider_by_id_impl.h deleted file mode 100644 index d52402a669..0000000000 --- a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_id_impl.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include "gui_game_spec_image_provider_impl.h" - -namespace openage { -namespace gui { - -/** - * Base for providers that expose textures to the Qt by their id. - * - * Numeric id has a form of .. - */ -class GuiGameSpecImageProviderByIdImpl : public GuiGameSpecImageProviderImpl { -public: - explicit GuiGameSpecImageProviderByIdImpl(qtsdl::GuiEventQueue *render_updater); - virtual ~GuiGameSpecImageProviderByIdImpl(); - -private: - virtual TextureHandle get_texture_handle(const QString &id) override; - virtual openage::Texture* get_texture(int texture_id) = 0; -}; - -}} // namespace openage::gui diff --git a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_terrain_id_impl.cpp b/libopenage/gui/integration/private/gui_game_spec_image_provider_by_terrain_id_impl.cpp deleted file mode 100644 index f875118636..0000000000 --- a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_terrain_id_impl.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2015-2021 the openage authors. See copying.md for legal info. - -#include "gui_game_spec_image_provider_by_terrain_id_impl.h" - -#include "../../../error/error.h" - -#include "../../../gamestate/old/game_spec.h" - -namespace openage::gui { - -GuiGameSpecImageProviderByTerrainIdImpl::GuiGameSpecImageProviderByTerrainIdImpl(qtsdl::GuiEventQueue *render_updater) - : - GuiGameSpecImageProviderByIdImpl{render_updater} { -} - -GuiGameSpecImageProviderByTerrainIdImpl::~GuiGameSpecImageProviderByTerrainIdImpl() = default; - -const char* GuiGameSpecImageProviderByTerrainIdImpl::id() { - return "by-terrain-id"; -} - -const char* GuiGameSpecImageProviderByTerrainIdImpl::get_id() const { - return GuiGameSpecImageProviderByTerrainIdImpl::id(); -} - -openage::Texture* GuiGameSpecImageProviderByTerrainIdImpl::get_texture(int texture_id) { - ENSURE(this->loaded_game_spec, "trying to actually get a texture from a non-loaded spec"); - auto meta = this->loaded_game_spec->get_terrain_meta(); - return meta && texture_id >=0 && texture_id < std::distance(std::begin(meta->textures), std::end(meta->textures)) ? meta->textures[texture_id] : nullptr; -} - -} // namespace openage::gui diff --git a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_terrain_id_impl.h b/libopenage/gui/integration/private/gui_game_spec_image_provider_by_terrain_id_impl.h deleted file mode 100644 index d5aba95279..0000000000 --- a/libopenage/gui/integration/private/gui_game_spec_image_provider_by_terrain_id_impl.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include "gui_game_spec_image_provider_by_id_impl.h" - -namespace openage { -namespace gui { - -/** - * Exposes terrain textures to the Qt by their id. - * - * Numeric id has a form of . where texture-id is the position in the terrain_meta. - */ -class GuiGameSpecImageProviderByTerrainIdImpl : public GuiGameSpecImageProviderByIdImpl { -public: - explicit GuiGameSpecImageProviderByTerrainIdImpl(qtsdl::GuiEventQueue *render_updater); - virtual ~GuiGameSpecImageProviderByTerrainIdImpl(); - - static const char* id(); - -private: - virtual const char* get_id() const override; - virtual openage::Texture* get_texture(int texture_id) override; -}; - -}} // namespace openage::gui diff --git a/libopenage/gui/integration/private/gui_game_spec_image_provider_impl.cpp b/libopenage/gui/integration/private/gui_game_spec_image_provider_impl.cpp index 4be3693854..01579aa8fa 100644 --- a/libopenage/gui/integration/private/gui_game_spec_image_provider_impl.cpp +++ b/libopenage/gui/integration/private/gui_game_spec_image_provider_impl.cpp @@ -1,4 +1,4 @@ -// Copyright 2015-2021 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include "gui_game_spec_image_provider_impl.h" @@ -11,18 +11,16 @@ #include "../../../gamestate/old/game_spec.h" #include "../../guisys/private/gui_event_queue_impl.h" -#include "gui_texture_factory.h" #include "gui_filled_texture_handles.h" +#include "gui_texture_factory.h" namespace openage::gui { -GuiGameSpecImageProviderImpl::GuiGameSpecImageProviderImpl(qtsdl::GuiEventQueue *render_updater) - : +GuiGameSpecImageProviderImpl::GuiGameSpecImageProviderImpl(qtsdl::GuiEventQueue *render_updater) : GuiImageProviderImpl{}, invalidated{}, filled_handles{std::make_shared()}, ended{} { - QThread *render_thread = qtsdl::GuiEventQueueImpl::impl(render_updater)->get_thread(); this->render_thread_callback.moveToThread(render_thread); QObject::connect(&this->render_thread_callback, &qtsdl::GuiCallback::process_blocking, &this->render_thread_callback, &qtsdl::GuiCallback::process, render_thread != QThread::currentThread() ? Qt::BlockingQueuedConnection : Qt::DirectConnection); @@ -30,7 +28,7 @@ GuiGameSpecImageProviderImpl::GuiGameSpecImageProviderImpl(qtsdl::GuiEventQueue GuiGameSpecImageProviderImpl::~GuiGameSpecImageProviderImpl() = default; -void GuiGameSpecImageProviderImpl::on_game_spec_loaded(const std::shared_ptr& loaded_game_spec) { +void GuiGameSpecImageProviderImpl::on_game_spec_loaded(const std::shared_ptr &loaded_game_spec) { ENSURE(loaded_game_spec, "spec hasn't been checked or was invalidated"); std::unique_lock lck{this->loaded_game_spec_mutex}; @@ -44,7 +42,7 @@ void GuiGameSpecImageProviderImpl::on_game_spec_loaded(const std::shared_ptr& loaded_game_spec) { +void GuiGameSpecImageProviderImpl::migrate_to_new_game_spec(const std::shared_ptr &loaded_game_spec) { ENSURE(loaded_game_spec, "spec hasn't been checked or was invalidated"); if (this->loaded_game_spec) { @@ -57,7 +55,8 @@ void GuiGameSpecImageProviderImpl::migrate_to_new_game_spec(const std::shared_pt using namespace std::placeholders; this->filled_handles->refresh_all_handles_with_texture(std::bind(&GuiGameSpecImageProviderImpl::overwrite_texture_handle, this, _1, _2, _3)); }); - } else { + } + else { this->loaded_game_spec = loaded_game_spec; } } @@ -71,12 +70,6 @@ void GuiGameSpecImageProviderImpl::on_game_spec_invalidated() { std::unique_lock lck{this->loaded_game_spec_mutex}; if (this->loaded_game_spec) { - const TextureHandle missing_texture = get_missing_texture(); - - emit this->render_thread_callback.process_blocking([this, &missing_texture] { - this->filled_handles->fill_all_handles_with_texture(missing_texture); - }); - invalidated = true; } } @@ -86,19 +79,16 @@ GuiFilledTextureHandleUser GuiGameSpecImageProviderImpl::fill_texture_handle(con return GuiFilledTextureHandleUser(this->filled_handles, id, requested_size, filled_handle); } -TextureHandle GuiGameSpecImageProviderImpl::get_missing_texture() { - return TextureHandle{this->loaded_game_spec->get_texture("missing.png", false), -1}; -} - -QQuickTextureFactory* GuiGameSpecImageProviderImpl::requestTexture(const QString &id, QSize *size, const QSize &requestedSize) { +QQuickTextureFactory *GuiGameSpecImageProviderImpl::requestTexture(const QString &id, QSize *size, const QSize &requestedSize) { std::unique_lock lck{this->loaded_game_spec_mutex}; - this->loaded_game_spec_cond.wait(lck, [this] {return this->ended || this->loaded_game_spec;}); + this->loaded_game_spec_cond.wait(lck, [this] { return this->ended || this->loaded_game_spec; }); if (this->ended) { qWarning("ImageProvider was stopped during the load, so it'll appear like the requestTexture() isn't implemented."); return this->GuiImageProviderImpl::requestTexture(id, size, requestedSize); - } else { + } + else { auto tex_factory = new GuiTextureFactory{this, id, requestedSize}; *size = tex_factory->textureSize(); return tex_factory; diff --git a/libopenage/gui/integration/private/gui_game_spec_image_provider_impl.h b/libopenage/gui/integration/private/gui_game_spec_image_provider_impl.h index 4882d67447..3fd199dbd0 100644 --- a/libopenage/gui/integration/private/gui_game_spec_image_provider_impl.h +++ b/libopenage/gui/integration/private/gui_game_spec_image_provider_impl.h @@ -1,17 +1,17 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once +#include #include #include -#include #include -#include +#include -#include "../../guisys/private/gui_image_provider_impl.h" #include "../../guisys/private/gui_callback.h" -#include "gui_texture_handle.h" +#include "../../guisys/private/gui_image_provider_impl.h" #include "gui_filled_texture_handles.h" +#include "gui_texture_handle.h" namespace qtsdl { @@ -44,7 +44,7 @@ class GuiGameSpecImageProviderImpl : public qtsdl::GuiImageProviderImpl { * * @param loaded_game_spec new source (can't be null) */ - void on_game_spec_loaded(const std::shared_ptr& loaded_game_spec); + void on_game_spec_loaded(const std::shared_ptr &loaded_game_spec); /** * Set to every sprite the 'missing texture' from current spec. @@ -64,8 +64,6 @@ class GuiGameSpecImageProviderImpl : public qtsdl::GuiImageProviderImpl { GuiFilledTextureHandleUser fill_texture_handle(const QString &id, const QSize &requested_size, SizedTextureHandle *filled_handle); protected: - TextureHandle get_missing_texture(); - std::shared_ptr loaded_game_spec; /** @@ -75,13 +73,13 @@ class GuiGameSpecImageProviderImpl : public qtsdl::GuiImageProviderImpl { private: virtual TextureHandle get_texture_handle(const QString &id) = 0; - virtual QQuickTextureFactory* requestTexture(const QString &id, QSize *size, const QSize &requestedSize) override; + virtual QQuickTextureFactory *requestTexture(const QString &id, QSize *size, const QSize &requestedSize) override; virtual void give_up() override; /** * Change the already produced texture handles to use new source. */ - void migrate_to_new_game_spec(const std::shared_ptr& loaded_game_spec); + void migrate_to_new_game_spec(const std::shared_ptr &loaded_game_spec); void overwrite_texture_handle(const QString &id, const QSize &requested_size, SizedTextureHandle *filled_handle); @@ -100,4 +98,5 @@ class GuiGameSpecImageProviderImpl : public qtsdl::GuiImageProviderImpl { qtsdl::GuiCallback render_thread_callback; }; -}} // namespace openage::gui +} // namespace gui +} // namespace openage diff --git a/libopenage/gui/integration/private/gui_image_provider_link.cpp b/libopenage/gui/integration/private/gui_image_provider_link.cpp index a0454449c7..f2b72eecb3 100644 --- a/libopenage/gui/integration/private/gui_image_provider_link.cpp +++ b/libopenage/gui/integration/private/gui_image_provider_link.cpp @@ -1,4 +1,4 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include "gui_image_provider_link.h" @@ -14,31 +14,17 @@ #include "../../game_spec_link.h" #include "gui_game_spec_image_provider_impl.h" -#include "gui_game_spec_image_provider_by_filename_impl.h" -#include "gui_game_spec_image_provider_by_graphic_id_impl.h" -#include "gui_game_spec_image_provider_by_terrain_id_impl.h" - namespace openage::gui { -namespace { -const int registration_by_filename = qmlRegisterSingletonType("yay.sfttech.openage", 1, 0, "ImageProviderByFilename", &GuiImageProviderLink::provider_by_filename); -const int registration_by_id = qmlRegisterSingletonType("yay.sfttech.openage", 1, 0, "ImageProviderById", &GuiImageProviderLink::provider_by_graphic_id); -const int registration_by_terrain_id = qmlRegisterSingletonType("yay.sfttech.openage", 1, 0, "ImageProviderByTerrainId", &GuiImageProviderLink::provider_by_terrain_id); -} - -GuiImageProviderLink::GuiImageProviderLink(QObject *parent, GuiGameSpecImageProviderImpl &image_provider) - : +GuiImageProviderLink::GuiImageProviderLink(QObject *parent, GuiGameSpecImageProviderImpl &image_provider) : QObject{parent}, image_provider{image_provider}, game_spec{} { - Q_UNUSED(registration_by_filename); - Q_UNUSED(registration_by_id); - Q_UNUSED(registration_by_terrain_id); } GuiImageProviderLink::~GuiImageProviderLink() = default; -GameSpecLink* GuiImageProviderLink::get_game_spec() const { +GameSpecLink *GuiImageProviderLink::get_game_spec() const { return this->game_spec; } @@ -61,30 +47,18 @@ void GuiImageProviderLink::set_game_spec(GameSpecLink *game_spec) { } } -QObject* GuiImageProviderLink::provider(QQmlEngine *engine, const char *id) { - qtsdl::QmlEngineWithSingletonItemsInfo *engine_with_singleton_items_info = qtsdl::checked_static_cast(engine); +QObject *GuiImageProviderLink::provider(QQmlEngine *engine, const char *id) { + qtsdl::QmlEngineWithSingletonItemsInfo *engine_with_singleton_items_info = qtsdl::checked_static_cast(engine); auto image_providers = engine_with_singleton_items_info->get_image_providers(); - auto found_it = std::find_if(std::begin(image_providers), std::end(image_providers), [id] (qtsdl::GuiImageProviderImpl *image_provider) { + auto found_it = std::find_if(std::begin(image_providers), std::end(image_providers), [id](qtsdl::GuiImageProviderImpl *image_provider) { return image_provider->get_id() == id; }); ENSURE(found_it != std::end(image_providers), "The image provider '" << id << "' wasn't created or wasn't passed to the QML engine creation function."); // owned by the QML engine - return new GuiImageProviderLink{nullptr, *qtsdl::checked_static_cast(*found_it)}; -} - -QObject* GuiImageProviderLink::provider_by_filename(QQmlEngine *engine, QJSEngine*) { - return GuiImageProviderLink::provider(engine, GuiGameSpecImageProviderByFilenameImpl::id()); -} - -QObject* GuiImageProviderLink::provider_by_graphic_id(QQmlEngine *engine, QJSEngine*) { - return GuiImageProviderLink::provider(engine, GuiGameSpecImageProviderByGraphicIdImpl::id()); -} - -QObject* GuiImageProviderLink::provider_by_terrain_id(QQmlEngine *engine, QJSEngine*) { - return GuiImageProviderLink::provider(engine, GuiGameSpecImageProviderByTerrainIdImpl::id()); + return new GuiImageProviderLink{nullptr, *qtsdl::checked_static_cast(*found_it)}; } void GuiImageProviderLink::on_game_spec_loaded(GameSpecLink *game_spec, std::shared_ptr loaded_game_spec) { diff --git a/libopenage/gui/integration/private/gui_image_provider_link.h b/libopenage/gui/integration/private/gui_image_provider_link.h index d0f4c3e944..510214f652 100644 --- a/libopenage/gui/integration/private/gui_image_provider_link.h +++ b/libopenage/gui/integration/private/gui_image_provider_link.h @@ -1,4 +1,4 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once @@ -22,13 +22,13 @@ class GameSpecLink; class GuiImageProviderLink : public QObject { Q_OBJECT - Q_PROPERTY(openage::gui::GameSpecLink* gameSpec READ get_game_spec WRITE set_game_spec) + Q_PROPERTY(openage::gui::GameSpecLink *gameSpec READ get_game_spec WRITE set_game_spec) public: explicit GuiImageProviderLink(QObject *parent, GuiGameSpecImageProviderImpl &image_provider); virtual ~GuiImageProviderLink(); - GameSpecLink* get_game_spec() const; + GameSpecLink *get_game_spec() const; /** * Sets the game spec to load textures from. @@ -38,10 +38,7 @@ class GuiImageProviderLink : public QObject { */ void set_game_spec(GameSpecLink *game_spec); - static QObject* provider(QQmlEngine*, const char *id); - static QObject* provider_by_filename(QQmlEngine*, QJSEngine*); - static QObject* provider_by_graphic_id(QQmlEngine*, QJSEngine*); - static QObject* provider_by_terrain_id(QQmlEngine*, QJSEngine*); + static QObject *provider(QQmlEngine *, const char *id); private slots: /** @@ -57,4 +54,5 @@ private slots: QPointer game_spec; }; -}} // namespace openage::gui +} // namespace gui +} // namespace openage diff --git a/libopenage/gui/integration/private/gui_texture.cpp b/libopenage/gui/integration/private/gui_texture.cpp index 7890981918..8c6de0746a 100644 --- a/libopenage/gui/integration/private/gui_texture.cpp +++ b/libopenage/gui/integration/private/gui_texture.cpp @@ -4,7 +4,6 @@ #include -#include "../../../texture.h" #include "gui_make_standalone_subtexture.h" #include "gui_texture.h" @@ -68,32 +67,6 @@ GLuint create_compatible_texture(GLuint texture_id, GLsizei w, GLsizei h) { QSGTexture *GuiTexture::removedFromAtlas(QRhiResourceUpdateBatch *resourceUpdates /* = nullptr */) const { if (this->isAtlasTexture()) { - if (!this->standalone) { - auto tex = this->texture_handle.texture; - auto sub = tex->get_subtexture(this->texture_handle.subid); - - GLuint sub_texture_id = create_compatible_texture(tex->get_texture_id(), sub->w, sub->h); - - std::array fbo; - glGenFramebuffers(fbo.size(), &fbo.front()); - - glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo[0]); - glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->textureId(), 0); - glReadBuffer(GL_COLOR_ATTACHMENT0); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]); - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sub_texture_id, 0); - glDrawBuffer(GL_COLOR_ATTACHMENT0); - - glBlitFramebuffer(sub->x, sub->y, sub->x + sub->w, sub->y + sub->h, 0, 0, sub->w, sub->h, GL_COLOR_BUFFER_BIT, GL_NEAREST); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - - glDeleteFramebuffers(fbo.size(), &fbo.front()); - - this->standalone = make_standalone_subtexture(sub_texture_id, QSize(sub->w, sub->h)); - } - return this->standalone.get(); } @@ -101,18 +74,11 @@ QSGTexture *GuiTexture::removedFromAtlas(QRhiResourceUpdateBatch *resourceUpdate } QRectF GuiTexture::normalizedTextureSubRect() const { - if (this->isAtlasTexture()) { - auto tex = this->texture_handle.texture; - auto sub = tex->get_subtexture(this->texture_handle.subid); - return QTransform::fromScale(tex->w, tex->h).inverted().mapRect(QRectF(sub->x, sub->y, sub->w, sub->h)); - } - else { - return QSGTexture::normalizedTextureSubRect(); - } + return QSGTexture::normalizedTextureSubRect(); } int GuiTexture::textureId() const { - return this->texture_handle.texture->get_texture_id(); + return 0; } QSize GuiTexture::textureSize() const { diff --git a/libopenage/gui/integration/private/gui_texture_factory.cpp b/libopenage/gui/integration/private/gui_texture_factory.cpp index 06abcdada3..35bc04cea1 100644 --- a/libopenage/gui/integration/private/gui_texture_factory.cpp +++ b/libopenage/gui/integration/private/gui_texture_factory.cpp @@ -1,30 +1,27 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include "gui_texture_factory.h" +#include "gui_filled_texture_handles.h" #include "gui_game_spec_image_provider_impl.h" -#include "../../../texture.h" #include "gui_texture.h" -#include "gui_filled_texture_handles.h" namespace openage::gui { -GuiTextureFactory::GuiTextureFactory(GuiGameSpecImageProviderImpl *provider, const QString &id, const QSize &requested_size) - : +GuiTextureFactory::GuiTextureFactory(GuiGameSpecImageProviderImpl *provider, const QString &id, const QSize &requested_size) : texture_handle(), texture_handle_user{provider->fill_texture_handle(id, requested_size, &this->texture_handle)} { } GuiTextureFactory::~GuiTextureFactory() = default; -QSGTexture* GuiTextureFactory::createTexture(QQuickWindow *window) const { +QSGTexture *GuiTextureFactory::createTexture(QQuickWindow *window) const { Q_UNUSED(window); return new GuiTexture{this->texture_handle}; } int GuiTextureFactory::textureByteCount() const { - // assume 32bit textures - return this->texture_handle.texture->w * this->texture_handle.texture->h * 4; + return 0; } QSize GuiTextureFactory::textureSize() const { diff --git a/libopenage/gui/integration/private/gui_texture_handle.cpp b/libopenage/gui/integration/private/gui_texture_handle.cpp index da9c974c80..efe9da7fb8 100644 --- a/libopenage/gui/integration/private/gui_texture_handle.cpp +++ b/libopenage/gui/integration/private/gui_texture_handle.cpp @@ -1,28 +1,25 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include "gui_texture_handle.h" #include -#include "../../../texture.h" namespace openage { namespace gui { -SizedTextureHandle::SizedTextureHandle() - : - TextureHandle{nullptr, 0}, +SizedTextureHandle::SizedTextureHandle() : + TextureHandle{0}, size{} { } -SizedTextureHandle::SizedTextureHandle(const TextureHandle &handle, const QSize &size) - : +SizedTextureHandle::SizedTextureHandle(const TextureHandle &handle, const QSize &size) : TextureHandle(handle), size{size} { } bool isAtlasTexture(const TextureHandle &texture_handle) { - return texture_handle.subid >= 0 && texture_handle.texture->get_subtexture_count() > 1; + return texture_handle.subid >= 0; } QSize textureSize(const SizedTextureHandle &texture_handle) { @@ -30,14 +27,7 @@ QSize textureSize(const SizedTextureHandle &texture_handle) { } QSize native_size(const TextureHandle &texture_handle) { - auto tex = texture_handle.texture; - - if (isAtlasTexture(texture_handle)) { - auto sub = tex->get_subtexture(texture_handle.subid); - return QSize(sub->w, sub->h); - } else { - return QSize(tex->w, tex->h); - } + return QSize(0, 0); } QSize aspect_fit_size(const TextureHandle &texture_handle, const QSize &requested_size) { @@ -48,9 +38,11 @@ QSize aspect_fit_size(const TextureHandle &texture_handle, const QSize &requeste // If requested_size.isEmpty() then the caller don't care how big one or two dimensions can grow. return size.scaled(bounding_size, requested_size.isEmpty() && (requested_size.width() > size.width() || requested_size.height() > size.height()) ? Qt::KeepAspectRatioByExpanding : Qt::KeepAspectRatio); - } else { + } + else { return size; } } -}} // namespace openage::gui +} // namespace gui +} // namespace openage diff --git a/libopenage/gui/integration/private/gui_texture_handle.h b/libopenage/gui/integration/private/gui_texture_handle.h index 58b86ee1bb..5d943a1358 100644 --- a/libopenage/gui/integration/private/gui_texture_handle.h +++ b/libopenage/gui/integration/private/gui_texture_handle.h @@ -1,4 +1,4 @@ -// Copyright 2015-2017 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once @@ -6,13 +6,10 @@ namespace openage { -class Texture; - namespace gui { class TextureHandle { public: - openage::Texture *texture; int subid; }; @@ -36,4 +33,5 @@ QSize native_size(const TextureHandle &texture_handle); */ QSize aspect_fit_size(const TextureHandle &texture_handle, const QSize &requested_size); -}} // namespace openage::gui +} // namespace gui +} // namespace openage diff --git a/libopenage/gui/integration/public/CMakeLists.txt b/libopenage/gui/integration/public/CMakeLists.txt index c7a535bb1f..4acda98465 100644 --- a/libopenage/gui/integration/public/CMakeLists.txt +++ b/libopenage/gui/integration/public/CMakeLists.txt @@ -1,4 +1,3 @@ add_sources(libopenage gui_application_with_logger.cpp - gui_game_spec_image_provider.cpp ) diff --git a/libopenage/gui/integration/public/gui_game_spec_image_provider.cpp b/libopenage/gui/integration/public/gui_game_spec_image_provider.cpp deleted file mode 100644 index 0fb622807b..0000000000 --- a/libopenage/gui/integration/public/gui_game_spec_image_provider.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "gui_game_spec_image_provider.h" - -#include "../../../error/error.h" - -#include "../private/gui_game_spec_image_provider_by_filename_impl.h" -#include "../private/gui_game_spec_image_provider_by_graphic_id_impl.h" -#include "../private/gui_game_spec_image_provider_by_terrain_id_impl.h" - -namespace openage::gui { - -GuiGameSpecImageProvider::GuiGameSpecImageProvider(qtsdl::GuiEventQueue *render_updater, Type type) - : - GuiImageProvider{[render_updater, type] () -> std::unique_ptr { - switch(type) { - case Type::ByFilename: - return std::make_unique(render_updater); - - case Type::ByGraphicId: - return std::make_unique(render_updater); - - case Type::ByTerrainId: - return std::make_unique(render_updater); - - default: - break; - } - - ENSURE(false, "unhandled image provider type"); - return std::unique_ptr{}; - }()} { -} - -GuiGameSpecImageProvider::~GuiGameSpecImageProvider() = default; - -} // namespace openage::gui diff --git a/libopenage/gui/integration/public/gui_game_spec_image_provider.h b/libopenage/gui/integration/public/gui_game_spec_image_provider.h deleted file mode 100644 index 2727d90af6..0000000000 --- a/libopenage/gui/integration/public/gui_game_spec_image_provider.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include "../../guisys/public/gui_image_provider.h" - -namespace qtsdl { -class GuiEventQueue; -} // namespace qtsdl - -namespace openage { -namespace gui { - -class GuiGameSpecImageProvider : public qtsdl::GuiImageProvider { -public: - enum class Type { - ByFilename, - ByGraphicId, - ByTerrainId, - }; - - explicit GuiGameSpecImageProvider(qtsdl::GuiEventQueue *render_updater, Type type); - ~GuiGameSpecImageProvider(); -}; - -}} // namespace openage::gui diff --git a/libopenage/pathfinding/path.cpp b/libopenage/pathfinding/path.cpp index c04e5876c4..c3f5e91eff 100644 --- a/libopenage/pathfinding/path.cpp +++ b/libopenage/pathfinding/path.cpp @@ -1,21 +1,20 @@ -// Copyright 2014-2019 the openage authors. See copying.md for legal info. +// Copyright 2014-2023 the openage authors. See copying.md for legal info. #include -#include "path.h" #include "../terrain/terrain.h" +#include "path.h" namespace openage::path { -bool compare_node_cost::operator ()(const node_pt &lhs, const node_pt &rhs) const { +bool compare_node_cost::operator()(const node_pt &lhs, const node_pt &rhs) const { // TODO: use node operator < return lhs->future_cost < rhs->future_cost; } -Node::Node(const coord::phys3 &pos, node_pt prev) - : +Node::Node(const coord::phys3 &pos, node_pt prev) : position(pos), tile_position(pos.to_tile3().to_tile()), direction{}, @@ -24,22 +23,17 @@ Node::Node(const coord::phys3 &pos, node_pt prev) factor{1.0f}, path_predecessor{prev}, heap_node(nullptr) { - if (prev) { this->direction = (this->position - prev->position).normalize(); // TODO: add dot product to coord - cost_t similarity = ((this->direction.ne.to_float() * - prev->direction.ne.to_float()) + - (this->direction.se.to_float() * - prev->direction.se.to_float())); + cost_t similarity = ((this->direction.ne.to_float() * prev->direction.ne.to_float()) + (this->direction.se.to_float() * prev->direction.se.to_float())); this->factor += (1 - similarity); } } -Node::Node(const coord::phys3 &pos, node_pt prev, cost_t past, cost_t heuristic) - : +Node::Node(const coord::phys3 &pos, node_pt prev, cost_t past, cost_t heuristic) : Node{pos, prev} { this->past_cost = past; this->heuristic_cost = heuristic; @@ -47,12 +41,12 @@ Node::Node(const coord::phys3 &pos, node_pt prev, cost_t past, cost_t heuristic) } -bool Node::operator <(const Node &other) const { +bool Node::operator<(const Node &other) const { return this->future_cost < other.future_cost; } -bool Node::operator ==(const Node &other) const { +bool Node::operator==(const Node &other) const { return this->position == other.position; } @@ -72,7 +66,8 @@ Path Node::generate_backtrace() { Node other = *current; waypoints.push_back(*current); current = current->path_predecessor; - } while (current != nullptr); + } + while (current != nullptr); waypoints.pop_back(); // remove start return {waypoints}; @@ -86,10 +81,10 @@ std::vector Node::get_neighbors(const nodemap_t &nodes, float scale) { coord::phys3 n_pos = this->position + (neigh_phys[n] * scale); if (nodes.count(n_pos) > 0) { - neighbors.push_back( nodes.at(n_pos) ); + neighbors.push_back(nodes.at(n_pos)); } else { - neighbors.push_back( std::make_shared(n_pos, this->shared_from_this()) ); + neighbors.push_back(std::make_shared(n_pos, this->shared_from_this())); } } return neighbors; @@ -114,22 +109,8 @@ bool passable_line(node_pt start, node_pt end, std::function &nodes) - : +Path::Path(const std::vector &nodes) : waypoints{nodes} {} -void Path::draw_path(const coord::CoordManager &mgr) { - glLineWidth(1); - glColor3f(0.3, 1.0, 0.3); - glBegin(GL_LINES); { - for (Node &n : waypoints) { - coord::viewport draw_pos = n.position.to_viewport(mgr); - glVertex3f(draw_pos.x, draw_pos.y, 0); - } - } - glEnd(); -} - - -} // openage::path +} // namespace openage::path diff --git a/libopenage/pathfinding/path.h b/libopenage/pathfinding/path.h index 16784cbd90..033090ca6b 100644 --- a/libopenage/pathfinding/path.h +++ b/libopenage/pathfinding/path.h @@ -1,4 +1,4 @@ -// Copyright 2014-2019 the openage authors. See copying.md for legal info. +// Copyright 2014-2023 the openage authors. See copying.md for legal info. #pragma once @@ -10,9 +10,8 @@ #include "../coord/phys.h" #include "../coord/tile.h" #include "../datastructure/pairing_heap.h" -#include "../util/misc.h" #include "../util/hash.h" - +#include "../util/misc.h" namespace openage { @@ -48,7 +47,7 @@ using nodemap_t = std::unordered_map; * Calls operator < on Node. */ struct compare_node_cost { - bool operator ()(const node_pt &lhs, const node_pt &rhs) const; + bool operator()(const node_pt &lhs, const node_pt &rhs) const; }; /** @@ -59,31 +58,30 @@ using heap_t = datastructure::PairingHeap; /** * Size of phys-coord grid for path nodes. */ -constexpr coord::phys_t path_grid_size{1.f/8}; +constexpr coord::phys_t path_grid_size{1.f / 8}; /** * Phys3 delta coordinates to select for path neighbors. */ constexpr coord::phys3_delta const neigh_phys[] = { - {path_grid_size * 1, path_grid_size * -1, 0}, - {path_grid_size * 1, path_grid_size * 0, 0}, - {path_grid_size * 1, path_grid_size * 1, 0}, - {path_grid_size * 0, path_grid_size * 1, 0}, - {path_grid_size * -1, path_grid_size * 1, 0}, - {path_grid_size * -1, path_grid_size * 0, 0}, + {path_grid_size * 1, path_grid_size * -1, 0}, + {path_grid_size * 1, path_grid_size * 0, 0}, + {path_grid_size * 1, path_grid_size * 1, 0}, + {path_grid_size * 0, path_grid_size * 1, 0}, + {path_grid_size * -1, path_grid_size * 1, 0}, + {path_grid_size * -1, path_grid_size * 0, 0}, {path_grid_size * -1, path_grid_size * -1, 0}, - {path_grid_size * 0, path_grid_size * -1, 0} -}; + {path_grid_size * 0, path_grid_size * -1, 0}}; /** * */ -bool passable_line(node_pt start, node_pt end, std::functionpassable, float samples=5.0f); +bool passable_line(node_pt start, node_pt end, std::function passable, float samples = 5.0f); /** * One navigation waypoint in a path. */ -class Node: public std::enable_shared_from_this { +class Node : public std::enable_shared_from_this { public: Node(const coord::phys3 &pos, node_pt prev); Node(const coord::phys3 &pos, node_pt prev, cost_t past, cost_t heuristic); @@ -91,13 +89,13 @@ class Node: public std::enable_shared_from_this { /** * Orders nodes according to their future cost value. */ - bool operator <(const Node &other) const; + bool operator<(const Node &other) const; /** * Compare the node to another one. * They are the same if their position is. */ - bool operator ==(const Node &other) const; + bool operator==(const Node &other) const; /** * Calculates the actual movement cose to another node. @@ -112,7 +110,7 @@ class Node: public std::enable_shared_from_this { /** * Get all neighbors of this graph node. */ - std::vector get_neighbors(const nodemap_t &, float scale=1.0f); + std::vector get_neighbors(const nodemap_t &, float scale = 1.0f); /** * The tile position this node is associated to. @@ -184,8 +182,6 @@ class Path { Path() = default; Path(const std::vector &nodes); - void draw_path(const coord::CoordManager &mgr); - /** * These are the waypoints to navigate in order. * Includes the start and end node. @@ -203,9 +199,9 @@ namespace std { * Hash function for path nodes. * Just uses their position. */ -template<> +template <> struct hash { - size_t operator ()(const openage::path::Node &x) const { + size_t operator()(const openage::path::Node &x) const { openage::coord::phys3 node_pos = x.position; size_t hash = openage::util::type_hash(); hash = openage::util::hash_combine(hash, std::hash{}(node_pos.ne)); diff --git a/libopenage/renderer/gui/gui.h b/libopenage/renderer/gui/gui.h index bb83217c48..dc8b0fcfdc 100644 --- a/libopenage/renderer/gui/gui.h +++ b/libopenage/renderer/gui/gui.h @@ -7,7 +7,6 @@ #include #include "gui/guisys/public/gui_event_queue.h" -#include "gui/integration/public/gui_game_spec_image_provider.h" #include "renderer/gui/guisys/public/gui_subtree.h" namespace qtgui { @@ -130,8 +129,6 @@ class GUI { */ qtgui::GuiSubtree subtree; - // openage::gui::GuiGameSpecImageProvider image_provider_by_filename; - /** * Reference to the openage renderer. * Used to fetch texture objects for the GUI texture. diff --git a/libopenage/shader/program.h b/libopenage/shader/program.h index c6848d68be..d2244b5bf3 100644 --- a/libopenage/shader/program.h +++ b/libopenage/shader/program.h @@ -1,4 +1,4 @@ -// Copyright 2013-2016 the openage authors. See copying.md for legal info. +// Copyright 2013-2023 the openage authors. See copying.md for legal info. #pragma once @@ -9,7 +9,7 @@ namespace shader { class Shader; -class Program { +class [[deprecated]] Program { public: GLuint id; GLint pos_id, mvpm_id; @@ -43,4 +43,5 @@ class Program { }; -}} // openage::shader +} // namespace shader +} // namespace openage diff --git a/libopenage/shader/shader.h b/libopenage/shader/shader.h index a8a263e6b9..93e44b6123 100644 --- a/libopenage/shader/shader.h +++ b/libopenage/shader/shader.h @@ -1,4 +1,4 @@ -// Copyright 2013-2016 the openage authors. See copying.md for legal info. +// Copyright 2013-2023 the openage authors. See copying.md for legal info. #pragma once @@ -9,9 +9,9 @@ namespace openage { namespace shader { -const char *type_to_string(GLenum type); +[[deprecated]] const char *type_to_string(GLenum type); -class Shader { +class [[deprecated]] Shader { public: Shader(GLenum type, std::initializer_list sources); ~Shader(); @@ -20,4 +20,5 @@ class Shader { GLenum type; }; -}} // openage::shader +} // namespace shader +} // namespace openage diff --git a/libopenage/terrain/CMakeLists.txt b/libopenage/terrain/CMakeLists.txt index 2dbe9a39cc..c7ae65ad65 100644 --- a/libopenage/terrain/CMakeLists.txt +++ b/libopenage/terrain/CMakeLists.txt @@ -2,6 +2,5 @@ add_sources(libopenage terrain.cpp terrain_chunk.cpp terrain_object.cpp - terrain_outline.cpp terrain_search.cpp ) diff --git a/libopenage/terrain/terrain.cpp b/libopenage/terrain/terrain.cpp index 325db0a5d5..59f9239a9d 100644 --- a/libopenage/terrain/terrain.cpp +++ b/libopenage/terrain/terrain.cpp @@ -185,16 +185,6 @@ int Terrain::blendmode(terrain_t terrain_id) { return this->meta->terrain_id_blendmode_map[terrain_id]; } -Texture *Terrain::texture(terrain_t terrain_id) { - this->validate_terrain(terrain_id); - return this->meta->textures[terrain_id]; -} - -Texture *Terrain::blending_mask(ssize_t mask_id) { - this->validate_mask(mask_id); - return this->meta->blending_masks[mask_id]; -} - unsigned Terrain::get_subtexture_id(const coord::tile &pos, unsigned atlas_size) { unsigned result = 0; @@ -367,17 +357,11 @@ struct tile_draw_data Terrain::create_tile_advice(coord::tile position, bool ble this->validate_terrain(base_tile_data.terrain_id); - Texture *tex = this->texture(base_tile_data.terrain_id); - base_tile_data.state = tile_state::existing; base_tile_data.pos = position; base_tile_data.priority = this->priority(base_tile_data.terrain_id); - base_tile_data.tex = tex; - base_tile_data.subtexture_id = this->get_subtexture_id( - position, - std::sqrt(tex->get_subtexture_count())); + base_tile_data.subtexture_id = 0; base_tile_data.blend_mode = -1; - base_tile_data.mask_tex = nullptr; base_tile_data.mask_id = -1; tile.data[tile.count] = base_tile_data; @@ -635,11 +619,7 @@ void Terrain::calculate_masks(coord::tile position, overlay->mask_id = adjacent_mask_id; overlay->blend_mode = blend_mode; overlay->terrain_id = neighbor_terrain_id; - overlay->tex = this->texture(neighbor_terrain_id); - overlay->subtexture_id = this->get_subtexture_id( - position, - std::sqrt(overlay->tex->get_subtexture_count())); - overlay->mask_tex = this->blending_mask(blend_mode); + overlay->subtexture_id = 0; overlay->state = tile_state::existing; tile_data->count += 1; @@ -666,11 +646,7 @@ void Terrain::calculate_masks(coord::tile position, overlay->mask_id = diag_mask_id_map[l]; overlay->blend_mode = blend_mode; overlay->terrain_id = neighbor_terrain_id; - overlay->tex = this->texture(neighbor_terrain_id); - overlay->subtexture_id = this->get_subtexture_id( - position, - std::sqrt(overlay->tex->get_subtexture_count())); - overlay->mask_tex = this->blending_mask(blend_mode); + overlay->subtexture_id = 0; overlay->state = tile_state::existing; tile_data->count += 1; diff --git a/libopenage/terrain/terrain.h b/libopenage/terrain/terrain.h index fcde460ad7..bb43a04e73 100644 --- a/libopenage/terrain/terrain.h +++ b/libopenage/terrain/terrain.h @@ -13,7 +13,6 @@ #include "../coord/phys.h" #include "../coord/pixel.h" #include "../coord/tile.h" -#include "../texture.h" #include "../util/misc.h" namespace openage { @@ -120,11 +119,9 @@ struct tile_data { terrain_t terrain_id; coord::tile pos{0, 0}; int subtexture_id; - Texture *tex; int priority; int mask_id; int blend_mode; - Texture *mask_tex; tile_state state; }; @@ -155,9 +152,6 @@ struct terrain_meta { size_t terrain_id_count; size_t blendmode_count; - std::vector textures; - std::vector blending_masks; - std::unique_ptr terrain_id_priority_map; std::unique_ptr terrain_id_blendmode_map; @@ -307,16 +301,6 @@ class Terrain { */ int blendmode(terrain_t terrain_id); - /** - * get the terrain texture for a given terrain id. - */ - Texture *texture(terrain_t terrain_id); - - /** - * get the blendomatic mask with the given mask id. - */ - Texture *blending_mask(ssize_t mask_id); - /** * return the blending mode id for two given neighbor ids. */ diff --git a/libopenage/terrain/terrain_chunk.cpp b/libopenage/terrain/terrain_chunk.cpp index 46d877175e..acbd76d7a7 100644 --- a/libopenage/terrain/terrain_chunk.cpp +++ b/libopenage/terrain/terrain_chunk.cpp @@ -10,7 +10,6 @@ #include "../error/error.h" #include "../legacy_engine.h" #include "../log/log.h" -#include "../texture.h" #include "../util/misc.h" #include "terrain.h" diff --git a/libopenage/terrain/terrain_chunk.h b/libopenage/terrain/terrain_chunk.h index 0fd5cceecd..4d6d7e24f4 100644 --- a/libopenage/terrain/terrain_chunk.h +++ b/libopenage/terrain/terrain_chunk.h @@ -1,4 +1,4 @@ -// Copyright 2013-2018 the openage authors. See copying.md for legal info. +// Copyright 2013-2023 the openage authors. See copying.md for legal info. #pragma once @@ -7,7 +7,6 @@ #include "../coord/pixel.h" #include "../coord/tile.h" -#include "../texture.h" #include "../util/file.h" namespace openage { diff --git a/libopenage/terrain/terrain_object.cpp b/libopenage/terrain/terrain_object.cpp index fdcf611ae3..c4f4c6c9f9 100644 --- a/libopenage/terrain/terrain_object.cpp +++ b/libopenage/terrain/terrain_object.cpp @@ -10,12 +10,10 @@ #include "../coord/tile.h" #include "../error/error.h" #include "../legacy_engine.h" -#include "../texture.h" #include "../unit/unit.h" #include "terrain.h" #include "terrain_chunk.h" -#include "terrain_outline.h" namespace openage { @@ -59,10 +57,6 @@ bool TerrainObject::check_collisions() const { return this->state == object_state::placed; } -void TerrainObject::draw_outline(const coord::CoordManager &coord) const { - this->outline_texture->draw(coord, this->pos.draw); -} - bool TerrainObject::place(object_state init_state) { if (this->state == object_state::removed) { throw Error(MSG(err) << "Building cannot change state with no position"); @@ -279,13 +273,8 @@ void TerrainObject::place_unchecked(const std::shared_ptr &t, coord::ph } SquareObject::SquareObject(Unit &u, coord::tile_delta foundation_size) : - SquareObject(u, foundation_size, square_outline(foundation_size)) { -} - -SquareObject::SquareObject(Unit &u, coord::tile_delta foundation_size, std::shared_ptr out_tex) : TerrainObject(u), size(foundation_size) { - this->outline_texture = out_tex; } SquareObject::~SquareObject() = default; @@ -369,13 +358,8 @@ coord::phys_t SquareObject::min_axis() const { } RadialObject::RadialObject(Unit &u, float rad) : - RadialObject(u, rad, radial_outline(rad)) { -} - -RadialObject::RadialObject(Unit &u, float rad, std::shared_ptr out_tex) : TerrainObject(u), phys_radius(rad) { - this->outline_texture = out_tex; } RadialObject::~RadialObject() = default; diff --git a/libopenage/terrain/terrain_object.h b/libopenage/terrain/terrain_object.h index 4b6f76097b..2f9384b6ce 100644 --- a/libopenage/terrain/terrain_object.h +++ b/libopenage/terrain/terrain_object.h @@ -123,11 +123,6 @@ class TerrainObject : public std::enable_shared_from_this { */ std::function draw; - /** - * draws outline of this terrain space in current position - */ - void draw_outline(const coord::CoordManager &coord) const; - /** * changes the placement state of this object keeping the existing * position. this is useful for upgrading a floating building to a placed state @@ -254,11 +249,6 @@ class TerrainObject : public std::enable_shared_from_this { TerrainObject *parent; std::vector> children; - /** - * texture for drawing outline - */ - std::shared_ptr outline_texture; - /** * placement function which does not check passibility * used only when passibilty is already checked @@ -309,8 +299,6 @@ class SquareObject : public TerrainObject { private: SquareObject(Unit &u, coord::tile_delta foundation_size); - SquareObject(Unit &u, coord::tile_delta foundation_size, std::shared_ptr out_tex); - friend class TerrainObject; friend class Unit; @@ -342,7 +330,6 @@ class RadialObject : public TerrainObject { private: RadialObject(Unit &u, float rad); - RadialObject(Unit &u, float rad, std::shared_ptr out_tex); friend class TerrainObject; friend class Unit; diff --git a/libopenage/terrain/terrain_outline.cpp b/libopenage/terrain/terrain_outline.cpp deleted file mode 100644 index 6c20fd5983..0000000000 --- a/libopenage/terrain/terrain_outline.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2014-2019 the openage authors. See copying.md for legal info. - -#include -#include - -#include "../texture.h" -#include "terrain_outline.h" - -namespace openage { - -std::shared_ptr square_outline(coord::tile_delta foundation_size) { - int width = (foundation_size.ne + foundation_size.se) * 48; - int height = (foundation_size.ne + foundation_size.se) * 24; - - auto image_data = std::make_unique(width * height); - for (int i = 0; i < width; ++i) { - for (int j = 0; j < height; ++j) { - float w_percent = (float) abs(i - (width / 2)) / (float) (width / 2); - float h_percent = (float) abs(j - (height / 2)) / (float) (height / 2); - - // draw line where (w_percent + h_percent) == 1 - // line variable is in range 0.0 to 1.0 - float line = 1.0f - fabs(1.0f - fabs(h_percent + w_percent)); - unsigned char inten = 255 * pow(line, 16 * width/96); - image_data[i + j * width] = (inten << 24) | (inten << 16) | (inten << 8) | inten; - } - } - - return std::make_shared(width, height, std::move(image_data)); -} - -std::shared_ptr radial_outline(float radius) { - // additional pixels around the edge - int border = 4; - - // image size - int width = border + radius * 96 * 2; - int height = border + radius * 48 * 2; - int half_width = width / 2; - int half_height = height / 2; - - auto image_data = std::make_unique(width * height); - - for (int i = 0; i < width; ++i) { - for (int j = 0; j < height; ++j) { - float w_percent = (float) (border+i-half_width) / (float) (half_width-border); - float h_percent = (float) (border/2+j-half_height) / (float) (half_height-border/2); - - // line drawn where distance to image center == 1 - // line variable is in range 0.0 to 1.0 - float line = 1.0f - fabs(1.0f - std::hypot(w_percent, h_percent)); - unsigned char inten = 255 * pow(line, 32 * width/96); - image_data[i + j * width] = (inten << 24) | (inten << 16) | (inten << 8) | inten; - } - } - - return std::make_shared(width, height, std::move(image_data)); -} - -} // namespace openage diff --git a/libopenage/terrain/terrain_outline.h b/libopenage/terrain/terrain_outline.h deleted file mode 100644 index 8e66fadb6d..0000000000 --- a/libopenage/terrain/terrain_outline.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2014-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "../coord/tile.h" - -namespace openage { - -class Texture; - -/** - * Generate a isometric square outline texture - */ -std::shared_ptr square_outline(coord::tile_delta foundation_size); - -/** - * Generate a isometric circle outline texture - */ -std::shared_ptr radial_outline(float radius); - -} // namespace openage diff --git a/libopenage/texture.cpp b/libopenage/texture.cpp deleted file mode 100644 index ec5ebf2202..0000000000 --- a/libopenage/texture.cpp +++ /dev/null @@ -1,447 +0,0 @@ -// Copyright 2013-2019 the openage authors. See copying.md for legal info. - -#include "texture.h" - -#include -#include - -#include -#include - -#include "log/log.h" -#include "error/error.h" -#include "util/csv.h" -#include "coord/phys.h" - -namespace openage { - -// TODO: remove these global variables!!! -// definition of the shaders, -// they are "external" in the header. -namespace texture_shader { -shader::Program *program; -GLint texture, tex_coord; -} - -namespace teamcolor_shader { -shader::Program *program; -GLint texture, tex_coord; -GLint player_id_var, alpha_marker_var, player_color_var; -} - -namespace alphamask_shader { -shader::Program *program; -GLint base_texture, mask_texture, base_coord, mask_coord, show_mask; -} - -Texture::Texture(int width, int height, std::unique_ptr data) - : - use_metafile{false} { - ENSURE(glGenBuffers != nullptr, "gl not initialized properly"); - - this->w = width; - this->h = height; - this->buffer = std::make_unique(); - this->buffer->transferred = false; - this->buffer->texture_format_in = GL_RGBA8; - this->buffer->texture_format_out = GL_RGBA; - this->buffer->data = std::move(data); - this->subtextures.push_back({0, 0, this->w, this->h, this->w/2, this->h/2}); -} - -Texture::Texture(const util::Path &filename, bool use_metafile) - : - use_metafile{use_metafile}, - filename{filename} { - - // load the texture upon creation - this->load(); -} - -void Texture::load() { - // TODO: use libpng directly. - SDL_Surface *surface; - - // TODO: this will break if there is no native path. - // but then we need to load the image - // from the buffer provided by this->filename.open_r().read(). - - std::string native_path = this->filename.resolve_native_path(); - surface = IMG_Load(native_path.c_str()); - - if (!surface) { - throw Error( - MSG(err) << - "SDL_Image could not load texture from " - << this->filename << " (= " << native_path << "): " - << IMG_GetError() - ); - } else { - log::log(MSG(dbg) << "Texture has been loaded from " << native_path); - } - - this->buffer = std::make_unique(); - - // glTexImage2D format determination - switch (surface->format->BytesPerPixel) { - case 3: // RGB 24 bit - this->buffer->texture_format_in = GL_RGB8; - this->buffer->texture_format_out - = surface->format->Rmask == 0x000000ff - ? GL_RGB - : GL_BGR; - break; - case 4: // RGBA 32 bit - this->buffer->texture_format_in = GL_RGBA8; - this->buffer->texture_format_out - = surface->format->Rmask == 0x000000ff - ? GL_RGBA - : GL_BGRA; - break; - default: - throw Error(MSG(err) << - "Unknown texture bit depth for " << this->filename << ": " << - surface->format->BytesPerPixel << " bytes per pixel"); - - } - - this->w = surface->w; - this->h = surface->h; - - // temporary buffer for pixel data - this->buffer->transferred = false; - this->buffer->data = std::make_unique(this->w * this->h); - std::memcpy( - this->buffer->data.get(), - surface->pixels, - this->w * this->h * surface->format->BytesPerPixel - ); - SDL_FreeSurface(surface); - - if (use_metafile) { - // get subtexture information from the exported metainfo file - this->subtextures = util::read_csv_file( - filename.with_suffix(".docx") - ); - } - else { - // we don't have a subtexture description file. - // use the whole image as one texture then. - gamedata::subtexture s{0, 0, this->w, this->h, this->w/2, this->h/2}; - - this->subtextures.push_back(s); - } -} - -GLuint Texture::make_gl_texture(int iformat, int oformat, int w, int h, void *data) const { - // generate 1 texture handle - GLuint textureid; - glGenTextures(1, &textureid); - glBindTexture(GL_TEXTURE_2D, textureid); - - // sdl surface -> opengl texture - glTexImage2D( - GL_TEXTURE_2D, 0, - iformat, w, h, 0, - oformat, GL_UNSIGNED_BYTE, data - ); - - // settings for later drawing - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - return textureid; -} - -void Texture::load_in_glthread() const { - if (not this->buffer->transferred) { - this->buffer->id = this->make_gl_texture( - this->buffer->texture_format_in, - this->buffer->texture_format_out, - this->w, - this->h, - this->buffer->data.get() - ); - this->buffer->data = nullptr; - glGenBuffers(1, &this->buffer->vertbuf); - this->buffer->transferred = true; - } -} - - -void Texture::unload() { - glDeleteTextures(1, &this->buffer->id); - glDeleteBuffers(1, &this->buffer->vertbuf); -} - - -void Texture::reload() { - this->unload(); - this->load(); -} - - -Texture::~Texture() { - this->unload(); -} - - -void Texture::fix_hotspots(unsigned x, unsigned y) { - for (auto &subtexture : this->subtextures) { - subtexture.cx = x; - subtexture.cy = y; - } -} - - -void Texture::draw(const coord::CoordManager &mgr, const coord::camhud pos, - unsigned int mode, bool mirrored, - int subid, unsigned player) const { - this->draw(pos.to_viewport(mgr), mode, mirrored, subid, player, nullptr, -1); -} - - -void Texture::draw(const coord::CoordManager &mgr, coord::camgame pos, - unsigned int mode, bool mirrored, - int subid, unsigned player) const { - this->draw(pos.to_viewport(mgr), mode, mirrored, subid, player, nullptr, -1); -} - - -void Texture::draw(const coord::CoordManager &mgr, coord::phys3 pos, - unsigned int mode, bool mirrored, - int subid, unsigned player) const { - this->draw(pos.to_viewport(mgr), mode, mirrored, subid, player, nullptr, -1); -} - - -void Texture::draw(const coord::CoordManager &mgr, const Terrain &terrain, - coord::tile pos, unsigned int mode, int subid, - Texture *alpha_texture, int alpha_subid) const { - - // currently used for drawing terrain tiles. - this->draw(pos.to_viewport(mgr, terrain), mode, false, - subid, 0, alpha_texture, alpha_subid); -} - - -void Texture::draw(coord::viewport pos, - unsigned int mode, bool mirrored, - int subid, unsigned player, - Texture *alpha_texture, int alpha_subid) const { - - this->load_in_glthread(); - - glColor4f(1, 1, 1, 1); - - bool use_playercolors = false; - bool use_alphashader = false; - const gamedata::subtexture *mtx; - - int *pos_id, *texcoord_id, *masktexcoord_id; - - // is this texture drawn with an alpha mask? - if ((mode & ALPHAMASKED) && alpha_subid >= 0 && alpha_texture != nullptr) { - alphamask_shader::program->use(); - - // bind the alpha mask texture to slot 1 - glActiveTexture(GL_TEXTURE1); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, alpha_texture->get_texture_id()); - - // get the alphamask subtexture (the blend mask!) - mtx = alpha_texture->get_subtexture(alpha_subid); - pos_id = &alphamask_shader::program->pos_id; - texcoord_id = &alphamask_shader::base_coord; - masktexcoord_id = &alphamask_shader::mask_coord; - use_alphashader = true; - } - // is this texure drawn with replaced pixels for team coloring? - else if (mode & PLAYERCOLORED) { - teamcolor_shader::program->use(); - - //set the desired player id in the shader - glUniform1i(teamcolor_shader::player_id_var, player); - pos_id = &teamcolor_shader::program->pos_id; - texcoord_id = &teamcolor_shader::tex_coord; - use_playercolors = true; - } - // mkay, we just draw the plain texture otherwise. - else { - texture_shader::program->use(); - pos_id = &texture_shader::program->pos_id; - texcoord_id = &texture_shader::tex_coord; - } - - glActiveTexture(GL_TEXTURE0); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, this->buffer->id); - - const gamedata::subtexture *tx = this->get_subtexture(subid); - - int left, right, top, bottom; - - // coordinates where the texture will be drawn on screen. - bottom = pos.y - (tx->h - tx->cy); - top = bottom + tx->h; - - if (not mirrored) { - left = pos.x - tx->cx; - right = left + tx->w; - } else { - left = pos.x + tx->cx; - right = left - tx->w; - } - - // convert the texture boundaries to float - // these will be the vertex coordinates. - float leftf, rightf, topf, bottomf; - leftf = (float) left; - rightf = (float) right; - topf = (float) top; - bottomf = (float) bottom; - - // subtexture coordinates - // left, right, top and bottom bounds as coordinates - // these pick the requested area out of the big texture. - float txl, txr, txt, txb; - this->get_subtexture_coordinates(tx, &txl, &txr, &txt, &txb); - - float mtxl=0, mtxr=0, mtxt=0, mtxb=0; - if (use_alphashader) { - alpha_texture->get_subtexture_coordinates(mtx, &mtxl, &mtxr, &mtxt, &mtxb); - } - - // this array will be uploaded to the GPU. - // it contains all dynamic vertex data (position, tex coordinates, mask coordinates) - float vdata[] { - leftf, topf, - leftf, bottomf, - rightf, bottomf, - rightf, topf, - txl, txt, - txl, txb, - txr, txb, - txr, txt, - mtxl, mtxt, - mtxl, mtxb, - mtxr, mtxb, - mtxr, mtxt - }; - - - // store vertex buffer data, TODO: prepare this sometime earlier. - glBindBuffer(GL_ARRAY_BUFFER, this->buffer->vertbuf); - glBufferData(GL_ARRAY_BUFFER, sizeof(vdata), vdata, GL_STREAM_DRAW); - - // enable vertex buffer and bind it to the vertex attribute - glEnableVertexAttribArray(*pos_id); - glEnableVertexAttribArray(*texcoord_id); - if (use_alphashader) { - glEnableVertexAttribArray(*masktexcoord_id); - } - - // set data types, offsets in the vdata array - glVertexAttribPointer(*pos_id, 2, GL_FLOAT, GL_FALSE, 0, (void *)(0)); - glVertexAttribPointer(*texcoord_id, 2, GL_FLOAT, GL_FALSE, 0, (void *)(sizeof(float) * 8)); - if (use_alphashader) { - glVertexAttribPointer(*masktexcoord_id, 2, GL_FLOAT, GL_FALSE, 0, (void *)(sizeof(float) * 8 * 2)); - } - - // draw the vertex array - glDrawArrays(GL_QUADS, 0, 4); - - - // unbind the current buffer - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glDisableVertexAttribArray(*pos_id); - glDisableVertexAttribArray(*texcoord_id); - if (use_alphashader) { - glDisableVertexAttribArray(*masktexcoord_id); - } - - // disable the shaders. - if (use_playercolors) { - teamcolor_shader::program->stopusing(); - } else if (use_alphashader) { - alphamask_shader::program->stopusing(); - glActiveTexture(GL_TEXTURE1); - glDisable(GL_TEXTURE_2D); - } else { - texture_shader::program->stopusing(); - } - - glActiveTexture(GL_TEXTURE0); - glDisable(GL_TEXTURE_2D); - - //////////////////////////////////////// - /* - int size = 2; - float r = 1.0f, g = 1.0f, b = 0.0f; - glPushMatrix(); - glTranslatef(leftf, bottomf, 0); - glColor3f(r, g, b); - glBegin(GL_TRIANGLES); - glVertex3f(-size, -size, 0); - glVertex3f(-size, size, 0); - glVertex3f(size, size, 0); - glVertex3f(size, size, 0); - glVertex3f(-size, -size, 0); - glVertex3f(size, -size, 0); - glEnd(); - glPopMatrix(); - */ - //////////////////////////////////////// -} - - -const gamedata::subtexture *Texture::get_subtexture(uint64_t subid) const { - if (subid < this->subtextures.size()) { - return &this->subtextures[subid]; - } - else { - throw Error{ - ERR << "Unknown subtexture requested for texture " - << this->filename << ": " << subid - }; - } -} - - -void Texture::get_subtexture_coordinates(uint64_t subid, - float *txl, float *txr, - float *txt, float *txb) const { - const gamedata::subtexture *tx = this->get_subtexture(subid); - this->get_subtexture_coordinates(tx, txl, txr, txt, txb); -} - - -void Texture::get_subtexture_coordinates(const gamedata::subtexture *tx, - float *txl, float *txr, - float *txt, float *txb) const { - *txl = ((float)tx->x) /this->w; - *txr = ((float)(tx->x + tx->w)) /this->w; - *txt = ((float)tx->y) /this->h; - *txb = ((float)(tx->y + tx->h)) /this->h; -} - - -size_t Texture::get_subtexture_count() const { - return this->subtextures.size(); -} - - -void Texture::get_subtexture_size(uint64_t subid, int *w, int *h) const { - const gamedata::subtexture *subtex = this->get_subtexture(subid); - *w = subtex->w; - *h = subtex->h; -} - - -GLuint Texture::get_texture_id() const { - this->load_in_glthread(); - return this->buffer->id; -} - -} // openage diff --git a/libopenage/texture.h b/libopenage/texture.h deleted file mode 100644 index 64283e86cc..0000000000 --- a/libopenage/texture.h +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright 2013-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include - -#include "coord/pixel.h" -#include "coord/tile.h" -#include "gamedata/texture_dummy.h" -#include "shader/program.h" -#include "shader/shader.h" -#include "util/path.h" - - -namespace openage { -class Terrain; - -namespace util { -class Path; -} - -namespace coord { -class CoordManager; -} - -namespace texture_shader { -extern shader::Program *program; -extern GLint texture, tex_coord; -} // namespace texture_shader - -namespace teamcolor_shader { -extern shader::Program *program; -extern GLint texture, tex_coord; -extern GLint player_id_var, alpha_marker_var, player_color_var; -} // namespace teamcolor_shader - -namespace alphamask_shader { -extern shader::Program *program; -extern GLint base_texture, mask_texture, base_coord, mask_coord, show_mask; -} // namespace alphamask_shader - -// bitmasks for shader modes -constexpr int PLAYERCOLORED = 1 << 0; -constexpr int ALPHAMASKED = 1 << 1; - -/** - * enables transfer of data to opengl - */ -struct [[deprecated]] gl_texture_buffer { - GLuint id, vertbuf; - - // this requires loading on the main thread - bool transferred; - int texture_format_in; - int texture_format_out; - std::unique_ptr data; -}; - - -/** - * A texture for rendering graphically. - * - * You may believe it or not, but this class represents a single texture, - * which can be drawn on the screen. - * - * The class supports subtextures, so that one big texture can contain - * several small images. These are the ones actually to be rendered. - * - * TODO: Deprecated, replaced by new renderer - */ -class [[deprecated]] Texture { -public: - int w; - int h; - - /** - * Create a texture from a rgba8 array. - * It will have w * h * 32bit storage. - */ - Texture(int width, int height, std::unique_ptr data); - - /** - * Create a texture from a existing image file. - * For supported image file types, see the SDL_Image initialization in the engine. - */ - Texture(const util::Path &filename, bool use_metafile = false); - ~Texture(); - - /** - * Draws the texture at hud coordinates. - */ - void draw(const coord::CoordManager &mgr, coord::camhud pos, unsigned int mode = 0, bool mirrored = false, int subid = 0, unsigned player = 0) const; - - /** - * Draws the texture at game coordinates. - */ - void draw(const coord::CoordManager &mgr, coord::camgame pos, unsigned int mode = 0, bool mirrored = false, int subid = 0, unsigned player = 0) const; - - /** - * Draws the texture at phys coordinates. - */ - void draw(const coord::CoordManager &mgr, coord::phys3 pos, unsigned int mode = 0, bool mirrored = false, int subid = 0, unsigned player = 0) const; - - /** - * Draws the texture at tile coordinates. - */ - void draw(const coord::CoordManager &mgr, const Terrain &terrain, coord::tile pos, unsigned int mode, int subid, Texture *alpha_texture, int alpha_subid) const; - - /** - * Draws the texture at window coordinates. - */ - void draw(coord::viewport pos, unsigned int mode, bool mirrored, int subid, unsigned player, Texture *alpha_texture, int alpha_subid) const; - - /** - * Reload the image file. Used for inotify refreshing. - */ - void reload(); - - /** - * Get the subtexture coordinates by its id. - */ - const gamedata::subtexture *get_subtexture(uint64_t subid) const; - - /** - * @return the number of available subtextures - */ - size_t get_subtexture_count() const; - - /** - * Fetch the size of the given subtexture. - * @param subid: index of the requested subtexture - * @param w: the subtexture width - * @param h: the subtexture height - */ - void get_subtexture_size(uint64_t subid, int *w, int *h) const; - - /** - * get atlas subtexture coordinates. - * - * left, right, top and bottom bounds as coordinates - * these pick the requested area out of the big texture. - * returned as floats in range 0.0 to 1.0 - */ - void get_subtexture_coordinates(uint64_t subid, float *txl, float *txr, float *txt, float *txb) const; - void get_subtexture_coordinates(const gamedata::subtexture *subtex, float *txl, float *txr, float *txt, float *txb) const; - - /** - * fixes the hotspots of all subtextures to (x,y). - * this is a temporary workaround; such fixes should actually be done in the - * convert script. - */ - void fix_hotspots(unsigned x, unsigned y); - - /** - * activates the influence of a given alpha mask to this texture. - */ - void activate_alphamask(Texture *mask, uint64_t subid); - - /** - * disable a previously activated alpha mask. - */ - void disable_alphamask(); - - /** - * returns the opengl texture id of this texture. - */ - GLuint get_texture_id() const; - -private: - std::unique_ptr buffer; - std::vector subtextures; - bool use_metafile; - - util::Path filename; - - void load(); - - /** - * The texture loadin must occur on the thread that manages the gl context. - */ - void load_in_glthread() const; - GLuint make_gl_texture(int iformat, int oformat, int w, int h, void *) const; - void unload(); -}; - -} // namespace openage diff --git a/libopenage/unit/producer.cpp b/libopenage/unit/producer.cpp index 2e6ed907e6..d03192ee60 100644 --- a/libopenage/unit/producer.cpp +++ b/libopenage/unit/producer.cpp @@ -2,12 +2,11 @@ #include -#include "../legacy_engine.h" #include "../gamedata/unit_dummy.h" +#include "../legacy_engine.h" #include "../log/log.h" #include "../terrain/terrain.h" #include "../terrain/terrain_object.h" -#include "../terrain/terrain_outline.h" #include "../util/strings.h" #include "ability.h" #include "action.h" @@ -83,7 +82,6 @@ ObjectProducer::ObjectProducer(const Player &owner, const GameSpec &spec, const UnitType(owner), dataspec(spec), unit_data(*ud), - terrain_outline{nullptr}, default_tex{spec.get_unit_texture(ud->idle_graphic0)}, dead_unit_id{ud->dead_unit_id} { // copy the class type @@ -114,14 +112,6 @@ ObjectProducer::ObjectProducer(const Player &owner, const GameSpec &spec, const static_cast(this->unit_data.radius_y * 2), }; - // shape of the outline - if (this->unit_data.obstruction_class > 1) { - this->terrain_outline = radial_outline(this->unit_data.radius_x); - } - else { - this->terrain_outline = square_outline(this->foundation_size); - } - // graphic set auto standing = spec.get_unit_texture(this->unit_data.idle_graphic0); if (!standing) { @@ -277,14 +267,6 @@ void ObjectProducer::initialise(Unit *unit, Player &player) { } TerrainObject *ObjectProducer::place(Unit *u, std::shared_ptr terrain, coord::phys3 init_pos) const { - // create new object with correct base shape - if (this->unit_data.obstruction_class > 1) { - u->make_location(this->unit_data.radius_x, this->terrain_outline); - } - else { - u->make_location(this->foundation_size, this->terrain_outline); - } - // find set of allowed terrains std::unordered_set terrains = allowed_terrains(this->unit_data.terrain_restriction); @@ -532,8 +514,6 @@ BuildingProducer::BuildingProducer(const Player &owner, const GameSpec &spec, co this->graphics[graphic_type::dying] = dying_tex; } - this->terrain_outline = square_outline(this->foundation_size); - // TODO get cost, temp fixed cost of 100 wood this->cost.set(cost_type::constant, create_resource_cost(game_resource::wood, 100)); } @@ -646,9 +626,6 @@ std::vector BuildingProducer::get_accepted_resources() { } TerrainObject *BuildingProducer::place(Unit *u, std::shared_ptr terrain, coord::phys3 init_pos) const { - // buildings have a square base - u->make_location(this->foundation_size, this->terrain_outline); - /* * decide what terrain is passable using this lambda * currently unit avoids water and tiles with another unit @@ -762,9 +739,6 @@ ProjectileProducer::ProjectileProducer(const Player &owner, const GameSpec &spec if (destroyed) { this->graphics[graphic_type::dying] = destroyed; } - - // outline - terrain_outline = radial_outline(pd->radius_y); } ProjectileProducer::~ProjectileProducer() = default; @@ -803,11 +777,6 @@ void ProjectileProducer::initialise(Unit *unit, Player &player) { } TerrainObject *ProjectileProducer::place(Unit *u, std::shared_ptr terrain, coord::phys3 init_pos) const { - /* - * radial base shape without collision checking - */ - u->make_location(this->unit_data.radius_y, this->terrain_outline); - TerrainObject *obj_ptr = u->location.get(); std::weak_ptr terrain_ptr = terrain; u->location->passable = [obj_ptr, u, terrain_ptr](const coord::phys3 &pos) -> bool { diff --git a/libopenage/unit/producer.h b/libopenage/unit/producer.h index 804df598cf..53036078de 100644 --- a/libopenage/unit/producer.h +++ b/libopenage/unit/producer.h @@ -1,4 +1,4 @@ -// Copyright 2014-2021 the openage authors. See copying.md for legal info. +// Copyright 2014-2023 the openage authors. See copying.md for legal info. #pragma once @@ -19,7 +19,6 @@ class GameMain; class GameSpec; class Terrain; class TerrainObject; -class Texture; class Sound; class UnitAbility; @@ -32,7 +31,7 @@ std::unordered_set allowed_terrains(const gamedata::ground_type &rest /** * base game data unit type */ -class ObjectProducer: public UnitType { +class ObjectProducer : public UnitType { public: ObjectProducer(const Player &owner, const GameSpec &spec, const gamedata::unit_object *ud); virtual ~ObjectProducer(); @@ -57,7 +56,6 @@ class ObjectProducer: public UnitType { */ const Sound *on_create; const Sound *on_destroy; - std::shared_ptr terrain_outline; std::shared_ptr default_tex; int dead_unit_id; }; @@ -65,7 +63,7 @@ class ObjectProducer: public UnitType { /** * movable unit types */ -class MovableProducer: public ObjectProducer { +class MovableProducer : public ObjectProducer { public: MovableProducer(const Player &owner, const GameSpec &spec, const gamedata::projectile_unit *); virtual ~MovableProducer(); @@ -80,7 +78,6 @@ class MovableProducer: public ObjectProducer { const Sound *on_move; const Sound *on_attack; int projectile; - }; /** @@ -88,7 +85,7 @@ class MovableProducer: public ObjectProducer { * Stores graphics and attributes for a single unit type * in aoe living units are derived from objects */ -class LivingProducer: public MovableProducer { +class LivingProducer : public MovableProducer { public: LivingProducer(const Player &owner, const GameSpec &spec, const gamedata::living_unit *); virtual ~LivingProducer(); @@ -105,7 +102,7 @@ class LivingProducer: public MovableProducer { * Will be replaced with nyan system in future * in aoe buildings are derived from living units */ -class BuildingProducer: public UnitType { +class BuildingProducer : public UnitType { public: BuildingProducer(const Player &owner, const GameSpec &spec, @@ -126,7 +123,6 @@ class BuildingProducer: public UnitType { */ const Sound *on_create; const Sound *on_destroy; - std::shared_ptr terrain_outline; std::shared_ptr texture; std::shared_ptr destroyed; int projectile; @@ -146,7 +142,7 @@ class BuildingProducer: public UnitType { * creates projectiles * todo use MovableProducer as base class */ -class ProjectileProducer: public UnitType { +class ProjectileProducer : public UnitType { public: ProjectileProducer(const Player &owner, const GameSpec &spec, const gamedata::missile_unit *); virtual ~ProjectileProducer(); @@ -159,7 +155,6 @@ class ProjectileProducer: public UnitType { private: const gamedata::missile_unit unit_data; - std::shared_ptr terrain_outline; std::shared_ptr tex; std::shared_ptr sh; // shadow texture std::shared_ptr destroyed; diff --git a/libopenage/unit/unit_texture.cpp b/libopenage/unit/unit_texture.cpp index a146f471b2..0d0636f53a 100644 --- a/libopenage/unit/unit_texture.cpp +++ b/libopenage/unit/unit_texture.cpp @@ -1,4 +1,4 @@ -// Copyright 2015-2021 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include "unit_texture.h" @@ -9,19 +9,16 @@ #include "../coord/pixel.h" #include "../gamestate/old/game_spec.h" #include "../log/log.h" -#include "../texture.h" #include "../util/math.h" #include "../util/math_constants.h" namespace openage { -UnitTexture::UnitTexture(GameSpec &spec, uint16_t graphic_id, bool delta) - : +UnitTexture::UnitTexture(GameSpec &spec, uint16_t graphic_id, bool delta) : UnitTexture{spec, spec.get_graphic_data(graphic_id), delta} {} -UnitTexture::UnitTexture(GameSpec &spec, const gamedata::graphic *graphic, bool delta) - : +UnitTexture::UnitTexture(GameSpec &spec, const gamedata::graphic *graphic, bool delta) : id{graphic->graphic_id}, sound_id{graphic->sound_id}, frame_count{graphic->frame_count}, @@ -30,7 +27,6 @@ UnitTexture::UnitTexture(GameSpec &spec, const gamedata::graphic *graphic, bool frame_rate{graphic->frame_rate}, use_up_angles{graphic->mirroring_mode == 24}, use_deltas{delta}, - texture{nullptr}, draw_this{true}, sound{nullptr}, delta_id{graphic->graphic_deltas.data} { @@ -38,125 +34,23 @@ UnitTexture::UnitTexture(GameSpec &spec, const gamedata::graphic *graphic, bool } bool UnitTexture::is_valid() const { - return texture; + return false; } coord::viewport UnitTexture::size() const { - return coord::viewport{this->texture->w, this->texture->h}; + return coord::viewport{0, 0}; } void UnitTexture::sample(const coord::CoordManager &coord, const coord::camhud &draw_pos, unsigned color) const { - - // draw delta list first - for (auto &d : this->deltas) { - coord::camhud_delta dlt = coord::camhud_delta{d.second.x, d.second.y}; - d.first->sample(coord, draw_pos + dlt, color); - } - - // draw texture - if (this->draw_this) { - this->texture->draw(coord, draw_pos, PLAYERCOLORED, false, 0, color); - } } void UnitTexture::draw(const coord::CoordManager &coord, const coord::camgame &draw_pos, unsigned int frame, unsigned color) const { - - // draw delta list first - for (auto &d : this->deltas) { - d.first->draw(coord, draw_pos + d.second, frame, color); - } - - // draw texture - if (this->draw_this) { - unsigned int to_draw = frame % this->texture->get_subtexture_count(); - this->texture->draw(coord, draw_pos, PLAYERCOLORED, false, to_draw, color); - } } void UnitTexture::draw(const coord::CoordManager &coord, const coord::camgame &draw_pos, coord::phys3_delta &dir, unsigned int frame, unsigned color) const { - unsigned int frame_to_use = frame; - if (this->use_up_angles) { - // up 1 => tilt 0 - // up -1 => tilt 1 - // up has a scale 5 times smaller - double len = math::hypot3(dir.ne.to_double(), dir.se.to_double(), dir.up.to_double()/5); - double up = dir.up.to_double()/(5.0 * len); - frame_to_use = (0.5 - (0.5 * up)) * this->frame_count; - } - else if (this->sound && frame == 0.0) { - this->sound->play(); - } - - // the index for the current direction - unsigned int angle = dir_group(dir, this->angle_count); - - // mirroring is used to make additional image sets - bool mirror = false; - if (this->angles_included <= angle) { - // this->angles_included <= angle < this->angle_count - angle = this->top_frame - angle; - mirror = true; - } - - // draw delta list first - for (auto &d : this->deltas) { - d.first->draw(coord, draw_pos + d.second, dir, frame, color); - } - - if (this->draw_this) { - unsigned int to_draw = this->subtexture(this->texture, angle, frame_to_use); - this->texture->draw(coord, draw_pos, PLAYERCOLORED, mirror, to_draw, color); - } } void UnitTexture::initialise(GameSpec &spec) { - this->texture = spec.get_texture(this->id); - this->sound = spec.get_sound(this->sound_id); - if (not is_valid()) { - this->draw_this = false; - } - - // find deltas - if (this->use_deltas) for (auto d : this->delta_id) { - if (spec.get_graphic_data(d.graphic_id)) { - auto ut = std::make_unique(spec, d.graphic_id, false); - if (ut->is_valid()) { - this->deltas.push_back({std::move(ut), coord::camgame_delta{d.offset_x, d.offset_y}}); - } - } - } - - if (this->draw_this) { - - // the graphic frame count includes deltas - unsigned int subtextures = this->texture->get_subtexture_count(); - if (subtextures >= this->frame_count) { - - // angles with graphic data - this->angles_included = subtextures / this->frame_count; - this->angles_mirrored = this->angle_count - this->angles_included; - this->safe_frame_count = this->frame_count; - } - else { - this->angles_included = 1; - this->angles_mirrored = 0; - this->safe_frame_count = subtextures; - } - - // find the top direction for mirroring over - this->top_frame = this->angle_count - (1 - (this->angles_included - this->angles_mirrored) / 2); - } -} - -unsigned int UnitTexture::subtexture(const Texture *t, unsigned int angle, unsigned int frame) const { - unsigned int tex_frames = t->get_subtexture_count(); - unsigned int count = tex_frames / this->angles_included; - unsigned int to_draw = angle * count + (frame % count); - if (tex_frames <= to_draw) { - log::log(MSG(err) << "Subtexture out of range (" << angle << ", " << frame << ")"); - return 0; - } - return to_draw; } unsigned int dir_group(coord::phys3_delta dir, unsigned int angles) { @@ -169,9 +63,9 @@ unsigned int dir_group(coord::phys3_delta dir, unsigned int angles) { // formula to find the correct angle return static_cast( - round(angles * atan2(dir_se, dir_ne) * (math::INV_PI / 2)) - + first_angle - ) % angles; + round(angles * atan2(dir_se, dir_ne) * (math::INV_PI / 2)) + + first_angle) + % angles; } diff --git a/libopenage/unit/unit_texture.h b/libopenage/unit/unit_texture.h index 20efe9eede..7e44899f8c 100644 --- a/libopenage/unit/unit_texture.h +++ b/libopenage/unit/unit_texture.h @@ -1,4 +1,4 @@ -// Copyright 2015-2021 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once @@ -23,7 +23,7 @@ class Sound; * * This type can also deal with playing position based game sounds. */ -class UnitTexture { +class [[deprecated]] UnitTexture { public: /** * Delta option specifies whether the delta graphics are included. @@ -31,29 +31,29 @@ class UnitTexture { * Note that the game data contains loops in delta links * which mean recursive loading should be avoided */ - UnitTexture(GameSpec &spec, uint16_t graphic_id, bool delta=true); - UnitTexture(GameSpec &spec, const gamedata::graphic *graphic, bool delta=true); + UnitTexture(GameSpec &spec, uint16_t graphic_id, bool delta = true); + UnitTexture(GameSpec &spec, const gamedata::graphic *graphic, bool delta = true); /** * const attributes of the graphic */ - const int16_t id; - const int16_t sound_id; + const int16_t id; + const int16_t sound_id; const unsigned int frame_count; const unsigned int angle_count; - const int16_t mirroring_mode; - const float frame_rate; + const int16_t mirroring_mode; + const float frame_rate; /** * draw object with vertical orientation (arrows) * adding an addtion degree of orientation */ - const bool use_up_angles; + const bool use_up_angles; /** * use delta information */ - const bool use_deltas; + const bool use_deltas; /** * invalid unit textures will cause errors if drawn @@ -68,7 +68,7 @@ class UnitTexture { /** * a sample drawing for hud */ - void sample(const coord::CoordManager &coord, const coord::camhud &draw_pos, unsigned color=1) const; + void sample(const coord::CoordManager &coord, const coord::camhud &draw_pos, unsigned color = 1) const; /** * draw object with no direction @@ -86,11 +86,6 @@ class UnitTexture { void initialise(GameSpec &spec); private: - /** - * use a regular texture for drawing - */ - const Texture *texture; - /** * the above frame count covers the entire graphic (with deltas) * the actual number in the base texture may be different @@ -109,11 +104,6 @@ class UnitTexture { // delta graphics std::vector, coord::camgame_delta>> deltas; - - /** - * find which subtexture should be used for drawing this texture - */ - unsigned int subtexture(const Texture *t, unsigned int angle, unsigned int frame) const; }; /** @@ -125,6 +115,6 @@ class UnitTexture { * @param first_angle offset added to angle, modulo number of angles * @return image set index */ -unsigned int dir_group(coord::phys3_delta dir, unsigned int angles=8); +unsigned int dir_group(coord::phys3_delta dir, unsigned int angles = 8); } // namespace openage From 59caca925ac137cb557d68168c95504aee3327ab Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 23 Sep 2023 02:08:36 +0200 Subject: [PATCH 32/95] renderer: Remove most of the old draw code. --- libopenage/gamestate/old/game_spec.cpp | 10 -- libopenage/gamestate/old/game_spec.h | 12 --- libopenage/handlers.h | 13 --- libopenage/terrain/terrain_chunk.h | 7 -- libopenage/unit/CMakeLists.txt | 1 - libopenage/unit/ability.h | 90 ++++++++-------- libopenage/unit/action.cpp | 40 -------- libopenage/unit/action.h | 9 -- libopenage/unit/attribute.h | 9 +- libopenage/unit/producer.cpp | 136 +------------------------ libopenage/unit/producer.h | 9 -- libopenage/unit/unit.cpp | 67 +----------- libopenage/unit/unit.h | 18 ---- libopenage/unit/unit_texture.cpp | 72 ------------- libopenage/unit/unit_texture.h | 120 ---------------------- libopenage/unit/unit_type.cpp | 19 ++-- libopenage/unit/unit_type.h | 17 +--- 17 files changed, 55 insertions(+), 594 deletions(-) delete mode 100644 libopenage/unit/unit_texture.cpp delete mode 100644 libopenage/unit/unit_texture.h diff --git a/libopenage/gamestate/old/game_spec.cpp b/libopenage/gamestate/old/game_spec.cpp index d696b748f5..ca06c6b7e3 100644 --- a/libopenage/gamestate/old/game_spec.cpp +++ b/libopenage/gamestate/old/game_spec.cpp @@ -82,16 +82,6 @@ index_t GameSpec::get_slp_graphic(index_t slp) { return this->slp_to_graphic[slp]; } -std::shared_ptr GameSpec::get_unit_texture(index_t unit_id) const { - if (this->unit_textures.count(unit_id) == 0) { - if (unit_id > 0) { - log::log(MSG(dbg) << " -> ignoring unit_id: " << unit_id); - } - return nullptr; - } - return this->unit_textures.at(unit_id); -} - const Sound *GameSpec::get_sound(index_t sound_id) const { if (this->available_sounds.count(sound_id) == 0) { if (sound_id > 0) { diff --git a/libopenage/gamestate/old/game_spec.h b/libopenage/gamestate/old/game_spec.h index b1377fd2d9..0e03eb73a5 100644 --- a/libopenage/gamestate/old/game_spec.h +++ b/libopenage/gamestate/old/game_spec.h @@ -5,7 +5,6 @@ #include "../../gamedata/gamedata_dummy.h" #include "../../gamedata/graphic_dummy.h" #include "../../job/job.h" -#include "../../unit/unit_texture.h" #include "../../util/csv.h" #include "terrain/terrain.h" #include "types.h" @@ -90,12 +89,6 @@ class GameSpec { */ index_t get_slp_graphic(index_t slp); - /** - * get unit texture by graphic id -- this is an directional texture - * which also includes graphic deltas - */ - std::shared_ptr get_unit_texture(index_t graphic_id) const; - /** * get sound by sound id */ @@ -190,11 +183,6 @@ class GameSpec { */ std::unordered_map> commands; - /** - * graphic ids -> unit texture for that id - */ - std::unordered_map> unit_textures; - /** * sound ids mapped to playable sounds for all available sounds. */ diff --git a/libopenage/handlers.h b/libopenage/handlers.h index f695a2589e..9d8f00e536 100644 --- a/libopenage/handlers.h +++ b/libopenage/handlers.h @@ -11,19 +11,6 @@ namespace openage { class LegacyEngine; -/** - * superclass for all possible drawing operations in the game. - */ -class [[deprecated]] DrawHandler { -public: - virtual ~DrawHandler() = default; - - /** - * execute the drawing action. - */ - virtual bool on_draw() = 0; -}; - /** * superclass for all possible drawing operations in the game. */ diff --git a/libopenage/terrain/terrain_chunk.h b/libopenage/terrain/terrain_chunk.h index 4d6d7e24f4..676cfcc1e4 100644 --- a/libopenage/terrain/terrain_chunk.h +++ b/libopenage/terrain/terrain_chunk.h @@ -69,13 +69,6 @@ class TerrainChunk { */ chunk_neighbors neighbors; - /** - * draws the terrain chunk on screen. - * - * @param chunk_pos the chunk position where it will be drawn - */ - void draw(coord::chunk chunk_pos); - /** * get tile data by absolute coordinates. */ diff --git a/libopenage/unit/CMakeLists.txt b/libopenage/unit/CMakeLists.txt index 3c7a6e27cc..6550dc0234 100644 --- a/libopenage/unit/CMakeLists.txt +++ b/libopenage/unit/CMakeLists.txt @@ -9,6 +9,5 @@ add_sources(libopenage selection.cpp unit.cpp unit_container.cpp - unit_texture.cpp unit_type.cpp ) diff --git a/libopenage/unit/ability.h b/libopenage/unit/ability.h index 71985ebe8c..b2957c0585 100644 --- a/libopenage/unit/ability.h +++ b/libopenage/unit/ability.h @@ -1,4 +1,4 @@ -// Copyright 2014-2021 the openage authors. See copying.md for legal info. +// Copyright 2014-2023 the openage authors. See copying.md for legal info. #pragma once @@ -16,7 +16,6 @@ class Command; class Sound; class Unit; class UnitAction; -class UnitTexture; class UnitType; /** @@ -54,14 +53,14 @@ const ability_set ability_all = ability_set().set(); /** * the order abilities should be used when available */ -static std::vector ability_priority { - ability_type::gather, // targeting +static std::vector ability_priority{ + ability_type::gather, // targeting ability_type::convert, ability_type::repair, ability_type::heal, ability_type::attack, ability_type::build, - ability_type::move, // positional + ability_type::move, // positional ability_type::patrol, ability_type::garrison, ability_type::ungarrison, // inside buildings @@ -94,7 +93,7 @@ class UnitAbility { /** * applies command to a given unit */ - virtual void invoke(Unit &to_modify, const Command &cmd, bool play_sound=false) = 0; + virtual void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) = 0; /** * some common functions @@ -111,15 +110,14 @@ class UnitAbility { * using a brace enclosed list */ static ability_set set_from_list(const std::vector &items); - }; /** * initiates a move action when given a valid target */ -class MoveAbility: public UnitAbility { +class MoveAbility : public UnitAbility { public: - MoveAbility(const Sound *s=nullptr); + MoveAbility(const Sound *s = nullptr); ability_type type() override { return ability_type::move; @@ -127,7 +125,7 @@ class MoveAbility: public UnitAbility { bool can_invoke(Unit &to_modify, const Command &cmd) override; - void invoke(Unit &to_modify, const Command &cmd, bool play_sound=false) override; + void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; private: const Sound *sound; @@ -136,7 +134,7 @@ class MoveAbility: public UnitAbility { /** * sets the gather point on buildings */ -class SetPointAbility: public UnitAbility { +class SetPointAbility : public UnitAbility { public: SetPointAbility(); @@ -146,16 +144,16 @@ class SetPointAbility: public UnitAbility { bool can_invoke(Unit &to_modify, const Command &cmd) override; - void invoke(Unit &to_modify, const Command &cmd, bool play_sound=false) override; + void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; }; /** * ability to garrision inside a building */ -class GarrisonAbility: public UnitAbility { +class GarrisonAbility : public UnitAbility { public: - GarrisonAbility(const Sound *s=nullptr); + GarrisonAbility(const Sound *s = nullptr); ability_type type() override { return ability_type::garrison; @@ -163,7 +161,7 @@ class GarrisonAbility: public UnitAbility { bool can_invoke(Unit &to_modify, const Command &cmd) override; - void invoke(Unit &to_modify, const Command &cmd, bool play_sound=false) override; + void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; private: const Sound *sound; @@ -172,9 +170,9 @@ class GarrisonAbility: public UnitAbility { /** * ability to ungarrision a building */ -class UngarrisonAbility: public UnitAbility { +class UngarrisonAbility : public UnitAbility { public: - UngarrisonAbility(const Sound *s=nullptr); + UngarrisonAbility(const Sound *s = nullptr); ability_type type() override { return ability_type::ungarrison; @@ -182,7 +180,7 @@ class UngarrisonAbility: public UnitAbility { bool can_invoke(Unit &to_modify, const Command &cmd) override; - void invoke(Unit &to_modify, const Command &cmd, bool play_sound=false) override; + void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; private: const Sound *sound; @@ -191,9 +189,9 @@ class UngarrisonAbility: public UnitAbility { /** * buildings train new objects */ -class TrainAbility: public UnitAbility { +class TrainAbility : public UnitAbility { public: - TrainAbility(const Sound *s=nullptr); + TrainAbility(const Sound *s = nullptr); ability_type type() override { return ability_type::train; @@ -201,7 +199,7 @@ class TrainAbility: public UnitAbility { bool can_invoke(Unit &to_modify, const Command &cmd) override; - void invoke(Unit &to_modify, const Command &cmd, bool play_sound=false) override; + void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; private: const Sound *sound; @@ -210,9 +208,9 @@ class TrainAbility: public UnitAbility { /** * initiates a research */ -class ResearchAbility: public UnitAbility { +class ResearchAbility : public UnitAbility { public: - ResearchAbility(const Sound *s=nullptr); + ResearchAbility(const Sound *s = nullptr); ability_type type() override { return ability_type::research; @@ -220,7 +218,7 @@ class ResearchAbility: public UnitAbility { bool can_invoke(Unit &to_modify, const Command &cmd) override; - void invoke(Unit &to_modify, const Command &cmd, bool play_sound=false) override; + void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; private: const Sound *sound; @@ -229,9 +227,9 @@ class ResearchAbility: public UnitAbility { /** * villagers build new buildings */ -class BuildAbility: public UnitAbility { +class BuildAbility : public UnitAbility { public: - BuildAbility(const Sound *s=nullptr); + BuildAbility(const Sound *s = nullptr); ability_type type() override { return ability_type::build; @@ -239,7 +237,7 @@ class BuildAbility: public UnitAbility { bool can_invoke(Unit &to_modify, const Command &cmd) override; - void invoke(Unit &to_modify, const Command &cmd, bool play_sound=false) override; + void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; private: const Sound *sound; @@ -248,9 +246,9 @@ class BuildAbility: public UnitAbility { /** * initiates an gather resource action when given a valid target */ -class GatherAbility: public UnitAbility { +class GatherAbility : public UnitAbility { public: - GatherAbility(const Sound *s=nullptr); + GatherAbility(const Sound *s = nullptr); ability_type type() override { return ability_type::gather; @@ -258,7 +256,7 @@ class GatherAbility: public UnitAbility { bool can_invoke(Unit &to_modify, const Command &cmd) override; - void invoke(Unit &to_modify, const Command &cmd, bool play_sound=false) override; + void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; private: const Sound *sound; @@ -267,9 +265,9 @@ class GatherAbility: public UnitAbility { /** * initiates an attack action when given a valid target */ -class AttackAbility: public UnitAbility { +class AttackAbility : public UnitAbility { public: - AttackAbility(const Sound *s=nullptr); + AttackAbility(const Sound *s = nullptr); ability_type type() override { return ability_type::attack; @@ -277,7 +275,7 @@ class AttackAbility: public UnitAbility { bool can_invoke(Unit &to_modify, const Command &cmd) override; - void invoke(Unit &to_modify, const Command &cmd, bool play_sound=false) override; + void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; private: const Sound *sound; @@ -286,9 +284,9 @@ class AttackAbility: public UnitAbility { /** * initiates a repair action when given a valid target */ -class RepairAbility: public UnitAbility { +class RepairAbility : public UnitAbility { public: - RepairAbility(const Sound *s=nullptr); + RepairAbility(const Sound *s = nullptr); ability_type type() override { return ability_type::repair; @@ -296,7 +294,7 @@ class RepairAbility: public UnitAbility { bool can_invoke(Unit &to_modify, const Command &cmd) override; - void invoke(Unit &to_modify, const Command &cmd, bool play_sound=false) override; + void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; private: const Sound *sound; @@ -305,9 +303,9 @@ class RepairAbility: public UnitAbility { /** * initiates a heal action when given a valid target */ -class HealAbility: public UnitAbility { +class HealAbility : public UnitAbility { public: - HealAbility(const Sound *s=nullptr); + HealAbility(const Sound *s = nullptr); ability_type type() override { return ability_type::heal; @@ -315,7 +313,7 @@ class HealAbility: public UnitAbility { bool can_invoke(Unit &to_modify, const Command &cmd) override; - void invoke(Unit &to_modify, const Command &cmd, bool play_sound=false) override; + void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; private: const Sound *sound; @@ -325,9 +323,9 @@ class HealAbility: public UnitAbility { * initiates a patrol action when given a valid target * TODO implement */ -class PatrolAbility: public UnitAbility { +class PatrolAbility : public UnitAbility { public: - PatrolAbility(const Sound *s=nullptr); + PatrolAbility(const Sound *s = nullptr); ability_type type() override { return ability_type::patrol; @@ -335,7 +333,7 @@ class PatrolAbility: public UnitAbility { bool can_invoke(Unit &to_modify, const Command &cmd) override; - void invoke(Unit &to_modify, const Command &cmd, bool play_sound=false) override; + void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; private: const Sound *sound; @@ -344,9 +342,9 @@ class PatrolAbility: public UnitAbility { /** * initiates a convert action when given a valid target */ -class ConvertAbility: public UnitAbility { +class ConvertAbility : public UnitAbility { public: - ConvertAbility(const Sound *s=nullptr); + ConvertAbility(const Sound *s = nullptr); ability_type type() override { return ability_type::convert; @@ -354,7 +352,7 @@ class ConvertAbility: public UnitAbility { bool can_invoke(Unit &to_modify, const Command &cmd) override; - void invoke(Unit &to_modify, const Command &cmd, bool play_sound=false) override; + void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; private: const Sound *sound; @@ -369,7 +367,7 @@ std::string to_string(const openage::ability_type &at); /** * hasher for ability type enum */ -template<> +template <> struct hash { typedef underlying_type::type underlying_type; diff --git a/libopenage/unit/action.cpp b/libopenage/unit/action.cpp index 50a03e2155..9370609f2d 100644 --- a/libopenage/unit/action.cpp +++ b/libopenage/unit/action.cpp @@ -12,7 +12,6 @@ #include "command.h" #include "producer.h" #include "research.h" -#include "unit_texture.h" namespace openage { @@ -91,26 +90,6 @@ UnitAction::UnitAction(Unit *u, graphic_type initial_gt) : graphic{initial_gt}, frame{.0f}, frame_rate{.0f} { - auto &g_set = this->current_graphics(); - if (g_set.count(initial_gt) > 0) { - auto utex = g_set.at(initial_gt); - if (utex) { - this->frame_rate = utex->frame_rate; - } - else { - this->entity->log(MSG(dbg) << "Broken graphic (null)"); - } - } - else { - this->entity->log(MSG(dbg) << "Broken graphic (not available)"); - } - - if (this->frame_rate == 0) { - // a random starting point for static graphics - // this creates variations in trees / houses etc - // this value is also deterministic to match across clients - this->frame = (u->id * u->id * 19249) & 0xff; - } } graphic_type UnitAction::type() const { @@ -121,11 +100,6 @@ float UnitAction::current_frame() const { return this->frame; } -const graphic_set &UnitAction::current_graphics() const { - // return the default graphic - return this->entity->unit_type->graphics; -} - void UnitAction::draw_debug(const LegacyEngine &engine) { // draw debug content if available if (show_debug && this->debug_draw_action) { @@ -326,10 +300,6 @@ void TargetAction::set_target(UnitReference new_target) { DecayAction::DecayAction(Unit *e) : UnitAction(e, graphic_type::standing), end_frame{.0f} { - auto &g_set = this->current_graphics(); - if (g_set.count(this->graphic) > 0) { - this->end_frame = g_set.at(this->graphic)->frame_count - 1; - } } void DecayAction::update(unsigned int time) { @@ -346,10 +316,6 @@ DeadAction::DeadAction(Unit *e, std::function on_complete) : UnitAction(e, graphic_type::dying), end_frame{.0f}, on_complete_func{on_complete} { - auto &g_set = this->current_graphics(); - if (g_set.count(graphic) > 0) { - this->end_frame = g_set.at(graphic)->frame_count - 1; - } } void DeadAction::update(unsigned int time) { @@ -1127,9 +1093,6 @@ void AttackAction::update_in_range(unsigned int time, Unit *target_ptr) { if (this->timer.update(time)) { this->attack(*target_ptr); } - - // inc frame - this->frame += time * this->current_graphics().at(graphic)->frame_count * 1.0f / this->timer.get_interval(); } bool AttackAction::completed_in_range(Unit *target_ptr) const { @@ -1183,9 +1146,6 @@ void HealAction::update_in_range(unsigned int time, Unit *target_ptr) { if (this->timer.update(time)) { this->heal(*target_ptr); } - - // inc frame - this->frame += time * this->current_graphics().at(graphic)->frame_count * 1.0f / this->timer.get_interval(); } bool HealAction::completed_in_range(Unit *target_ptr) const { diff --git a/libopenage/unit/action.h b/libopenage/unit/action.h index 60299dc577..ca41229e87 100644 --- a/libopenage/unit/action.h +++ b/libopenage/unit/action.h @@ -146,15 +146,6 @@ class UnitAction { */ virtual std::string name() const = 0; - /** - * determines which graphic should be used for drawing this unit - * finds the default graphic using the units type, used by most actions - * - * this virtual function is overriden for special cases such as - * villager task graphics - */ - virtual const graphic_set ¤t_graphics() const; - void draw_debug(const LegacyEngine &engine); /** diff --git a/libopenage/unit/attribute.h b/libopenage/unit/attribute.h index 2390c1dacc..5a5ce05117 100644 --- a/libopenage/unit/attribute.h +++ b/libopenage/unit/attribute.h @@ -1,4 +1,4 @@ -// Copyright 2014-2021 the openage authors. See copying.md for legal info. +// Copyright 2014-2023 the openage authors. See copying.md for legal info. #pragma once @@ -46,13 +46,6 @@ enum class graphic_type { work }; -class UnitTexture; - -/** - * Collection of graphics attached to each unit. - */ -using graphic_set = std::map>; - /** * List of unit's attribute types. */ diff --git a/libopenage/unit/producer.cpp b/libopenage/unit/producer.cpp index d03192ee60..fae69a6f78 100644 --- a/libopenage/unit/producer.cpp +++ b/libopenage/unit/producer.cpp @@ -12,7 +12,6 @@ #include "action.h" #include "producer.h" #include "unit.h" -#include "unit_texture.h" /** @file * Many values in this file are hardcoded, due to limited understanding of how the original @@ -82,7 +81,6 @@ ObjectProducer::ObjectProducer(const Player &owner, const GameSpec &spec, const UnitType(owner), dataspec(spec), unit_data(*ud), - default_tex{spec.get_unit_texture(ud->idle_graphic0)}, dead_unit_id{ud->dead_unit_id} { // copy the class type this->unit_class = this->unit_data.unit_class; @@ -112,54 +110,6 @@ ObjectProducer::ObjectProducer(const Player &owner, const GameSpec &spec, const static_cast(this->unit_data.radius_y * 2), }; - // graphic set - auto standing = spec.get_unit_texture(this->unit_data.idle_graphic0); - if (!standing) { - // indicates problems with data converion - throw Error(MSG(err) << "Unit id " << this->unit_data.id0 - << " has invalid graphic data, try reconverting the data"); - } - this->graphics[graphic_type::standing] = standing; - auto dying_tex = spec.get_unit_texture(this->unit_data.dying_graphic); - if (dying_tex) { - this->graphics[graphic_type::dying] = dying_tex; - } - - // default extra graphics - this->graphics[graphic_type::attack] = this->graphics[graphic_type::standing]; - this->graphics[graphic_type::work] = this->graphics[graphic_type::standing]; - - // pull extra graphics from unit commands - auto cmds = spec.get_command_data(this->unit_data.id0); - for (auto cmd : cmds) { - // same attack / work graphic - if (cmd->work_sprite_id == -1 && cmd->proceed_sprite_id > 0) { - auto task = spec.get_unit_texture(cmd->proceed_sprite_id); - if (task) { - this->graphics[graphic_type::work] = task; - this->graphics[graphic_type::attack] = task; - } - } - - // separate work and attack graphics - if (cmd->work_sprite_id > 0 && cmd->proceed_sprite_id > 0) { - auto attack = spec.get_unit_texture(cmd->proceed_sprite_id); - auto work = spec.get_unit_texture(cmd->work_sprite_id); - if (attack) { - this->graphics[graphic_type::attack] = attack; - } - if (work) { - this->graphics[graphic_type::work] = work; - } - } - - // villager carrying resources graphics - if (cmd->carry_sprite_id > 0) { - auto carry = spec.get_unit_texture(cmd->carry_sprite_id); - this->graphics[graphic_type::carrying] = carry; - } - } - // TODO get cost, temp fixed cost of 50 food this->cost.set(cost_type::constant, create_resource_cost(game_resource::food, 50)); } @@ -238,24 +188,6 @@ void ObjectProducer::initialise(Unit *unit, Player &player) { unit->push_action(std::make_unique(unit), true); } else { - // if destruction graphic is available - if (this->dead_unit_id) { - unit->push_action( - std::make_unique( - unit, - [this, unit, &player]() { - // modify unit to have dead type - UnitType *t = player.get_type(this->dead_unit_id); - if (t) { - t->initialise(unit, player); - } - }), - true); - } - else if (this->graphics.count(graphic_type::dying) > 0) { - unit->push_action(std::make_unique(unit), true); - } - // the default action unit->push_action(std::make_unique(unit), true); } @@ -329,26 +261,6 @@ MovableProducer::MovableProducer(const Player &owner, const GameSpec &spec, cons on_move{spec.get_sound(this->unit_data.command_sound_id)}, on_attack{spec.get_sound(this->unit_data.command_sound_id)}, projectile{this->unit_data.attack_projectile_primary_unit_id} { - // extra graphics if available - // villagers have invalid attack and walk graphics - // it seems these come from the command data instead - auto walk = spec.get_unit_texture(this->unit_data.move_graphics); - if (!walk) { - // use standing instead - walk = this->graphics[graphic_type::standing]; - } - this->graphics[graphic_type::walking] = walk; - - // reuse as carry graphic if not already set - if (this->graphics.count(graphic_type::carrying) == 0) { - this->graphics[graphic_type::carrying] = walk; - } - - auto attack = spec.get_unit_texture(this->unit_data.attack_sprite_id); - if (attack && attack->is_valid()) { - this->graphics[graphic_type::attack] = attack; - } - // extra abilities this->type_abilities.emplace_back(std::make_shared(this->on_move)); this->type_abilities.emplace_back(std::make_shared(this->on_attack)); @@ -474,8 +386,6 @@ TerrainObject *LivingProducer::place(Unit *unit, std::shared_ptr terrai BuildingProducer::BuildingProducer(const Player &owner, const GameSpec &spec, const gamedata::building_unit *ud) : UnitType(owner), unit_data{*ud}, - texture{spec.get_unit_texture(ud->idle_graphic0)}, - destroyed{spec.get_unit_texture(ud->dying_graphic)}, projectile{this->unit_data.attack_projectile_primary_unit_id}, foundation_terrain{ud->foundation_terrain_id}, enable_collisions{this->unit_data.id0 != 109} { // 109 = town center @@ -505,15 +415,6 @@ BuildingProducer::BuildingProducer(const Player &owner, const GameSpec &spec, co static_cast(this->unit_data.radius_y * 2), }; - // graphic set - this->graphics[graphic_type::construct] = spec.get_unit_texture(ud->construction_graphic_id); - this->graphics[graphic_type::standing] = spec.get_unit_texture(ud->idle_graphic0); - this->graphics[graphic_type::attack] = spec.get_unit_texture(ud->idle_graphic0); - auto dying_tex = spec.get_unit_texture(ud->dying_graphic); - if (dying_tex) { - this->graphics[graphic_type::dying] = dying_tex; - } - // TODO get cost, temp fixed cost of 100 wood this->cost.set(cost_type::constant, create_resource_cost(game_resource::wood, 100)); } @@ -570,9 +471,6 @@ void BuildingProducer::initialise(Unit *unit, Player &player) { this->have_limit = 2; // TODO change to 1, 2 is for testing } - bool has_destruct_graphic = this->destroyed != nullptr; - unit->push_action(std::make_unique(unit, has_destruct_graphic), true); - UnitType *proj_type = this->owner.get_type(this->projectile); if (this->unit_data.attack_projectile_primary_unit_id > 0 && proj_type) { coord::phys_t range_phys = this->unit_data.weapon_range_max; @@ -708,37 +606,14 @@ TerrainObject *BuildingProducer::make_annex(Unit &u, std::shared_ptr t, object_state state = c ? object_state::placed : object_state::placed_no_collision; annex_loc->place(t, start_tile, state); - // create special drawing functions for annexes, - annex_loc->draw = [annex_loc, annex_type, &u, c](const LegacyEngine &e) { - // hack which draws the outline in the right order - // removable once rendering system is improved - if (c && u.selected) { - // annex_loc->get_parent()->draw_outline(e.coord); - } - - // only draw if building is completed - if (u.has_attribute(attr_type::building) && u.get_attribute().completed >= 1.0f) { - u.draw(annex_loc, annex_type->graphics, e); - } - }; return annex_loc; } ProjectileProducer::ProjectileProducer(const Player &owner, const GameSpec &spec, const gamedata::missile_unit *pd) : UnitType(owner), - unit_data{*pd}, - tex{spec.get_unit_texture(this->unit_data.idle_graphic0)}, - sh{spec.get_unit_texture(3379)}, // 3379 = general arrow shadow - destroyed{spec.get_unit_texture(this->unit_data.dying_graphic)} { + unit_data{*pd} { // copy the class type this->unit_class = this->unit_data.unit_class; - - // graphic set - this->graphics[graphic_type::standing] = this->tex; - this->graphics[graphic_type::shadow] = this->sh; - if (destroyed) { - this->graphics[graphic_type::dying] = destroyed; - } } ProjectileProducer::~ProjectileProducer() = default; @@ -769,11 +644,6 @@ void ProjectileProducer::initialise(Unit *unit, Player &player) { unit->add_attribute(std::make_shared>(sp)); unit->add_attribute(std::make_shared>(this->unit_data.projectile_arc)); unit->add_attribute(std::make_shared>(coord::phys3_delta{1, 0, 0})); - - // if destruction graphic is available - if (this->destroyed) { - unit->push_action(std::make_unique(unit), true); - } } TerrainObject *ProjectileProducer::place(Unit *u, std::shared_ptr terrain, coord::phys3 init_pos) const { @@ -816,10 +686,6 @@ TerrainObject *ProjectileProducer::place(Unit *u, std::shared_ptr terra return true; }; - u->location->draw = [u](const LegacyEngine &e) { - u->draw(e); - }; - // try to place the obj, it knows best whether it will fit. if (u->location->place(terrain, init_pos, object_state::placed_no_collision)) { return u->location.get(); diff --git a/libopenage/unit/producer.h b/libopenage/unit/producer.h index 53036078de..2ff837a147 100644 --- a/libopenage/unit/producer.h +++ b/libopenage/unit/producer.h @@ -23,7 +23,6 @@ class Sound; class UnitAbility; class UnitAction; -class UnitTexture; std::unordered_set allowed_terrains(const gamedata::ground_type &restriction); @@ -56,7 +55,6 @@ class ObjectProducer : public UnitType { */ const Sound *on_create; const Sound *on_destroy; - std::shared_ptr default_tex; int dead_unit_id; }; @@ -73,8 +71,6 @@ class MovableProducer : public ObjectProducer { protected: const gamedata::projectile_unit unit_data; - UnitTexture *moving; - UnitTexture *attacking; const Sound *on_move; const Sound *on_attack; int projectile; @@ -123,8 +119,6 @@ class BuildingProducer : public UnitType { */ const Sound *on_create; const Sound *on_destroy; - std::shared_ptr texture; - std::shared_ptr destroyed; int projectile; int foundation_terrain; std::vector get_accepted_resources(); @@ -155,9 +149,6 @@ class ProjectileProducer : public UnitType { private: const gamedata::missile_unit unit_data; - std::shared_ptr tex; - std::shared_ptr sh; // shadow texture - std::shared_ptr destroyed; }; } // namespace openage diff --git a/libopenage/unit/unit.cpp b/libopenage/unit/unit.cpp index 483d651bd1..234d47770e 100644 --- a/libopenage/unit/unit.cpp +++ b/libopenage/unit/unit.cpp @@ -12,7 +12,7 @@ #include "command.h" #include "producer.h" #include "unit.h" -#include "unit_texture.h" + namespace openage { @@ -149,71 +149,6 @@ void Unit::apply_cmd(std::shared_ptr ability, const Command &cmd) { } } - -void Unit::draw(const LegacyEngine &engine) { - // the top action decides the graphic type and action - this->draw(this->location.get(), this->top()->current_graphics(), engine); -} - - -void Unit::draw(TerrainObject *loc, const graphic_set &grpc, const LegacyEngine &engine) { - ENSURE(loc != nullptr, "there should always be a location for a placed unit"); - - auto top_action = this->top(); - auto draw_graphic = top_action->type(); - if (grpc.count(draw_graphic) == 0) { - this->log(MSG(warn) << "Graphic not available"); - return; - } - - // the texture to draw with - auto draw_texture = grpc.at(draw_graphic); - if (!draw_texture) { - this->log(MSG(warn) << "Graphic null"); - return; - } - - // frame specified by the current action - auto draw_frame = top_action->current_frame(); - this->draw(loc->pos.draw, draw_texture, draw_frame, engine); - - // draw a shadow if the graphic is available - if (grpc.count(graphic_type::shadow) > 0) { - auto draw_shadow = grpc.at(graphic_type::shadow); - if (draw_shadow) { - // position without height component - // TODO: terrain elevation - coord::phys3 shadow_pos = loc->pos.draw; - shadow_pos.up = 0; - this->draw(shadow_pos, draw_shadow, draw_frame, engine); - } - } - - // draw debug details - top_action->draw_debug(engine); -} - - -void Unit::draw(coord::phys3 draw_pos, std::shared_ptr graphic, unsigned int frame, const LegacyEngine &engine) { - // players color if available - unsigned color = 0; - if (this->has_attribute(attr_type::owner)) { - auto &own_attr = this->get_attribute(); - color = own_attr.player.color; - } - - // check if object has a direction - if (this->has_attribute(attr_type::direction)) { - // directional textures - auto &d_attr = this->get_attribute(); - coord::phys3_delta draw_dir = d_attr.unit_dir; - // graphic->draw(engine.coord, draw_pos.to_camgame(engine.coord), draw_dir, frame, color); - } - else { - // graphic->draw(engine.coord, draw_pos.to_camgame(engine.coord), frame, color); - } -} - void Unit::give_ability(std::shared_ptr ability) { this->ability_available.emplace(std::make_pair(ability->type(), ability)); } diff --git a/libopenage/unit/unit.h b/libopenage/unit/unit.h index 01416a6ac8..5165ed6a18 100644 --- a/libopenage/unit/unit.h +++ b/libopenage/unit/unit.h @@ -124,24 +124,6 @@ class Unit : public log::LogSource { */ bool update(time_nsec_t lastframe_duration); - /** - * draws this action by taking the graphic type of the top action - * the graphic is found from the current graphic set - * - * this function should be used for most draw purposes - */ - void draw(const LegacyEngine &engine); - - /** - * an generalized draw function which is useful for drawing annexes - */ - void draw(TerrainObject *loc, const graphic_set &graphics, const LegacyEngine &engine); - - /** - * draws with a specific graphic and frame - */ - void draw(coord::phys3 draw_pos, std::shared_ptr graphic, unsigned int frame, const LegacyEngine &engine); - /** * adds an available ability to this unit * this turns targeted objects into actions which are pushed diff --git a/libopenage/unit/unit_texture.cpp b/libopenage/unit/unit_texture.cpp deleted file mode 100644 index 0d0636f53a..0000000000 --- a/libopenage/unit/unit_texture.cpp +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "unit_texture.h" - -#include -#include - -#include "../coord/phys.h" -#include "../coord/pixel.h" -#include "../gamestate/old/game_spec.h" -#include "../log/log.h" -#include "../util/math.h" -#include "../util/math_constants.h" - - -namespace openage { - -UnitTexture::UnitTexture(GameSpec &spec, uint16_t graphic_id, bool delta) : - UnitTexture{spec, spec.get_graphic_data(graphic_id), delta} {} - -UnitTexture::UnitTexture(GameSpec &spec, const gamedata::graphic *graphic, bool delta) : - id{graphic->graphic_id}, - sound_id{graphic->sound_id}, - frame_count{graphic->frame_count}, - angle_count{graphic->angle_count}, - mirroring_mode{graphic->mirroring_mode}, - frame_rate{graphic->frame_rate}, - use_up_angles{graphic->mirroring_mode == 24}, - use_deltas{delta}, - draw_this{true}, - sound{nullptr}, - delta_id{graphic->graphic_deltas.data} { - this->initialise(spec); -} - -bool UnitTexture::is_valid() const { - return false; -} - -coord::viewport UnitTexture::size() const { - return coord::viewport{0, 0}; -} - -void UnitTexture::sample(const coord::CoordManager &coord, const coord::camhud &draw_pos, unsigned color) const { -} - -void UnitTexture::draw(const coord::CoordManager &coord, const coord::camgame &draw_pos, unsigned int frame, unsigned color) const { -} - -void UnitTexture::draw(const coord::CoordManager &coord, const coord::camgame &draw_pos, coord::phys3_delta &dir, unsigned int frame, unsigned color) const { -} - -void UnitTexture::initialise(GameSpec &spec) { -} - -unsigned int dir_group(coord::phys3_delta dir, unsigned int angles) { - unsigned int first_angle = 5 * angles / 8; - - // normalise direction vector - double len = std::hypot(dir.ne, dir.se); - double dir_ne = static_cast(dir.ne) / len; - double dir_se = static_cast(dir.se) / len; - - // formula to find the correct angle - return static_cast( - round(angles * atan2(dir_se, dir_ne) * (math::INV_PI / 2)) - + first_angle) - % angles; -} - - -} // namespace openage diff --git a/libopenage/unit/unit_texture.h b/libopenage/unit/unit_texture.h deleted file mode 100644 index 7e44899f8c..0000000000 --- a/libopenage/unit/unit_texture.h +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -#include "../coord/phys.h" -#include "../gamedata/graphic_dummy.h" - -namespace openage { - -class GameSpec; -class Texture; -class Sound; - -/** - * Handling animated and directional textures based on the game - * graphics data. - * - * These objects handle the drawing of regular textures to use a - * unit's direction and include delta graphics. - * - * This type can also deal with playing position based game sounds. - */ -class [[deprecated]] UnitTexture { -public: - /** - * Delta option specifies whether the delta graphics are included. - * - * Note that the game data contains loops in delta links - * which mean recursive loading should be avoided - */ - UnitTexture(GameSpec &spec, uint16_t graphic_id, bool delta = true); - UnitTexture(GameSpec &spec, const gamedata::graphic *graphic, bool delta = true); - - /** - * const attributes of the graphic - */ - const int16_t id; - const int16_t sound_id; - const unsigned int frame_count; - const unsigned int angle_count; - const int16_t mirroring_mode; - const float frame_rate; - - /** - * draw object with vertical orientation (arrows) - * adding an addtion degree of orientation - */ - const bool use_up_angles; - - /** - * use delta information - */ - const bool use_deltas; - - /** - * invalid unit textures will cause errors if drawn - */ - bool is_valid() const; - - /** - * pixel size of this texture - */ - coord::viewport size() const; - - /** - * a sample drawing for hud - */ - void sample(const coord::CoordManager &coord, const coord::camhud &draw_pos, unsigned color = 1) const; - - /** - * draw object with no direction - */ - void draw(const coord::CoordManager &coord, const coord::camgame &draw_pos, unsigned int frame, unsigned color) const; - - /** - * draw object with direction - */ - void draw(const coord::CoordManager &coord, const coord::camgame &draw_pos, coord::phys3_delta &dir, unsigned int frame, unsigned color) const; - - /** - * initialise graphic data - */ - void initialise(GameSpec &spec); - -private: - /** - * the above frame count covers the entire graphic (with deltas) - * the actual number in the base texture may be different - */ - unsigned int safe_frame_count; - unsigned int angles_included; - unsigned int angles_mirrored; - unsigned int top_frame; - - // avoid drawing missing graphics - bool draw_this; - const Sound *sound; - - // delta graphic ids - std::vector delta_id; - - // delta graphics - std::vector, coord::camgame_delta>> deltas; -}; - -/** - * the set of images to used based on unit direction, - * usually 8 directions to draw for each unit (3 are mirrored) - * - * @param dir a world space direction, - * @param angles number of angles, usually 8 - * @param first_angle offset added to angle, modulo number of angles - * @return image set index - */ -unsigned int dir_group(coord::phys3_delta dir, unsigned int angles = 8); - -} // namespace openage diff --git a/libopenage/unit/unit_type.cpp b/libopenage/unit/unit_type.cpp index bc760bd955..80677ebc75 100644 --- a/libopenage/unit/unit_type.cpp +++ b/libopenage/unit/unit_type.cpp @@ -1,10 +1,10 @@ -// Copyright 2015-2021 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. +#include "unit.h" #include "../gamestate/old/player.h" #include "../terrain/terrain_object.h" #include "../util/math_constants.h" #include "action.h" -#include "unit.h" #include "unit_container.h" #include "unit_type.h" @@ -12,8 +12,7 @@ namespace openage { -UnitTypeMeta::UnitTypeMeta(std::string name, int id, init_func f) - : +UnitTypeMeta::UnitTypeMeta(std::string name, int id, init_func f) : init{f}, type_name{std::move(name)}, type_id{id} { @@ -27,8 +26,7 @@ int UnitTypeMeta::id() const { return this->type_id; } -UnitType::UnitType(const Player &owner) - : +UnitType::UnitType(const Player &owner) : owner{owner}, have_limit{math::INT_INF}, had_limit{math::INT_INF} { @@ -54,10 +52,6 @@ bool UnitType::operator!=(const UnitType &other) const { return !(*this == other); } -UnitTexture *UnitType::default_texture() { - return this->graphics[graphic_type::standing].get(); -} - TerrainObject *UnitType::place_beside(Unit *u, TerrainObject const *other) const { if (!u || !other) { return nullptr; @@ -65,7 +59,7 @@ TerrainObject *UnitType::place_beside(Unit *u, TerrainObject const *other) const // find the range of possible tiles tile_range outline{other->pos.start - coord::tile_delta{1, 1}, - other->pos.end + coord::tile_delta{1, 1}, + other->pos.end + coord::tile_delta{1, 1}, other->pos.draw}; // find a free position adjacent to the object @@ -97,8 +91,7 @@ UnitType *UnitType::parent_type() const { return this->owner.get_type(this->parent_id()); } -NyanType::NyanType(const Player &owner) - : +NyanType::NyanType(const Player &owner) : UnitType(owner) { // TODO: the type should be given attributes and abilities } diff --git a/libopenage/unit/unit_type.h b/libopenage/unit/unit_type.h index 5e960915a3..57dc2c2b49 100644 --- a/libopenage/unit/unit_type.h +++ b/libopenage/unit/unit_type.h @@ -1,4 +1,4 @@ -// Copyright 2015-2021 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once @@ -19,7 +19,6 @@ class TerrainObject; class Unit; class UnitAbility; class UnitContainer; -class UnitTexture; /** @@ -43,7 +42,6 @@ class UnitTypeMeta { private: const std::string type_name; const int type_id; - }; /** @@ -112,11 +110,6 @@ class UnitType { bool operator==(const UnitType &other) const; bool operator!=(const UnitType &other) const; - /** - * Get a default texture for HUD drawing - */ - UnitTexture *default_texture(); - /** * similar to place but places adjacent to an existing object */ @@ -175,11 +168,6 @@ class UnitType { */ int had_limit; - /** - * The set of graphics used for this type - */ - graphic_set graphics; - /** * The index of the icon representing this unit */ @@ -199,7 +187,7 @@ class UnitType { /** * An example of how nyan can work with the type system */ -class NyanType: public UnitType { +class NyanType : public UnitType { public: /** * TODO: give the parsed nyan attributes @@ -213,7 +201,6 @@ class NyanType: public UnitType { std::string name() const override; void initialise(Unit *, Player &) override; TerrainObject *place(Unit *, std::shared_ptr, coord::phys3) const override; - }; } // namespace openage From 44cf90e7715e2bcabfcfa03b605643d0325474a0 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 23 Sep 2023 02:37:34 +0200 Subject: [PATCH 33/95] renderer: Remove legacy signal handling for drawing/inputs. --- libopenage/CMakeLists.txt | 1 - libopenage/console/console.cpp | 72 ++++++------ libopenage/console/console.h | 14 +-- libopenage/gui/gui.cpp | 64 +++++------ libopenage/gui/gui.h | 11 +- libopenage/handlers.cpp | 7 -- libopenage/handlers.h | 66 ----------- libopenage/input/legacy/input_manager.cpp | 128 +++++++++++----------- libopenage/input/legacy/input_manager.h | 5 +- libopenage/legacy_engine.h | 1 - libopenage/unit/selection.cpp | 110 +++++++++---------- libopenage/unit/selection.h | 5 +- libopenage/unit/unit.h | 1 - libopenage/unit/unit_container.h | 5 +- 14 files changed, 201 insertions(+), 289 deletions(-) delete mode 100644 libopenage/handlers.cpp delete mode 100644 libopenage/handlers.h diff --git a/libopenage/CMakeLists.txt b/libopenage/CMakeLists.txt index 8c17eaa9d5..a87c120f50 100644 --- a/libopenage/CMakeLists.txt +++ b/libopenage/CMakeLists.txt @@ -322,7 +322,6 @@ get_codegen_scu_file() # are specified above the source file list. add_sources(libopenage - handlers.cpp legacy_engine.cpp main.cpp options.cpp diff --git a/libopenage/console/console.cpp b/libopenage/console/console.cpp index f2350a01ed..c28b6bab06 100644 --- a/libopenage/console/console.cpp +++ b/libopenage/console/console.cpp @@ -161,54 +161,54 @@ void Console::interpret(const std::string &command) { } } -bool Console::on_tick() { - if (!this->visible) { - return true; - } +// bool Console::on_tick() { +// if (!this->visible) { +// return true; +// } - // TODO: handle stuff such as cursor blinking, - // repeating held-down keys - return true; -} +// // TODO: handle stuff such as cursor blinking, +// // repeating held-down keys +// return true; +// } -bool Console::on_drawhud() { - if (!this->visible) { - return true; - } +// bool Console::on_drawhud() { +// if (!this->visible) { +// return true; +// } - // TODO: Use new renderer +// // TODO: Use new renderer - // draw::to_opengl(this->display, this); +// // draw::to_opengl(this->display, this); - return true; -} +// return true; +// } -bool Console::on_input(SDL_Event *e) { - // only handle inputs if the console is visible - if (!this->visible) { - return true; - } +// bool Console::on_input(SDL_Event *e) { +// // only handle inputs if the console is visible +// if (!this->visible) { +// return true; +// } - switch (e->type) { - case SDL_KEYDOWN: - //TODO handle key inputs +// switch (e->type) { +// case SDL_KEYDOWN: +// //TODO handle key inputs - //do not allow anyone else to handle this input - return false; - } +// //do not allow anyone else to handle this input +// return false; +// } - return true; -} +// return true; +// } -bool Console::on_resize(coord::viewport_delta new_size) { - coord::pixel_t w = this->buf.get_dims().x * this->charsize.x; - coord::pixel_t h = this->buf.get_dims().y * this->charsize.y; +// bool Console::on_resize(coord::viewport_delta new_size) { +// coord::pixel_t w = this->buf.get_dims().x * this->charsize.x; +// coord::pixel_t h = this->buf.get_dims().y * this->charsize.y; - this->bottomleft = {(new_size.x - w) / 2, (new_size.y - h) / 2}; - this->topright = {this->bottomleft.x + w, this->bottomleft.y - h}; +// this->bottomleft = {(new_size.x - w) / 2, (new_size.y - h) / 2}; +// this->topright = {this->bottomleft.x + w, this->bottomleft.y - h}; - return true; -} +// return true; +// } } // namespace console } // namespace openage diff --git a/libopenage/console/console.h b/libopenage/console/console.h index afe4095b51..dc9f00e9ef 100644 --- a/libopenage/console/console.h +++ b/libopenage/console/console.h @@ -7,7 +7,6 @@ #include "../coord/pixel.h" #include "../gamedata/color_dummy.h" -#include "../handlers.h" #include "../input/legacy/input_manager.h" #include "../renderer/font/font.h" #include "../util/color.h" @@ -22,10 +21,7 @@ class LegacyEngine; */ namespace console { -class Console : InputHandler - , TickHandler - , HudHandler - , ResizeHandler { +class Console { public: Console(/* presenter::LegacyDisplay *display */); ~Console(); @@ -53,10 +49,10 @@ class Console : InputHandler */ void interpret(const std::string &command); - bool on_drawhud() override; - bool on_tick() override; - bool on_input(SDL_Event *event) override; - bool on_resize(coord::viewport_delta new_size) override; + // bool on_drawhud() override; + // bool on_tick() override; + // bool on_input(SDL_Event *event) override; + // bool on_resize(coord::viewport_delta new_size) override; protected: // TODO: Replace with new renderer diff --git a/libopenage/gui/gui.cpp b/libopenage/gui/gui.cpp index d8ffe9e3e2..59d6e24c6b 100644 --- a/libopenage/gui/gui.cpp +++ b/libopenage/gui/gui.cpp @@ -93,14 +93,14 @@ void GUI::process_events() { this->application.processEvents(); } -bool GUI::on_resize(coord::viewport_delta new_size) { - this->renderer.resize(new_size.x, new_size.y); - return true; -} +// bool GUI::on_resize(coord::viewport_delta new_size) { +// this->renderer.resize(new_size.x, new_size.y); +// return true; +// } -bool GUI::on_input(SDL_Event *event) { - return not this->input.process(event); -} +// bool GUI::on_input(SDL_Event *event) { +// return not this->input.process(event); +// } namespace { /** @@ -138,43 +138,43 @@ class BlendPreserver { } // namespace -bool GUI::on_drawhud() { - this->render_updater.process_callbacks(); +// bool GUI::on_drawhud() { +// this->render_updater.process_callbacks(); - BlendPreserver preserve_blend; +// BlendPreserver preserve_blend; - auto tex = this->renderer.render(); +// auto tex = this->renderer.render(); - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); +// glEnable(GL_BLEND); +// glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - this->textured_screen_quad_shader->use(); +// this->textured_screen_quad_shader->use(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tex); +// glActiveTexture(GL_TEXTURE0); +// glBindTexture(GL_TEXTURE_2D, tex); - glEnableVertexAttribArray(this->textured_screen_quad_shader->pos_id); +// glEnableVertexAttribArray(this->textured_screen_quad_shader->pos_id); - glBindBuffer(GL_ARRAY_BUFFER, this->screen_quad_vbo); - glVertexAttribPointer( - this->textured_screen_quad_shader->pos_id, - 2, - GL_FLOAT, - GL_FALSE, - 2 * sizeof(float), - 0); +// glBindBuffer(GL_ARRAY_BUFFER, this->screen_quad_vbo); +// glVertexAttribPointer( +// this->textured_screen_quad_shader->pos_id, +// 2, +// GL_FLOAT, +// GL_FALSE, +// 2 * sizeof(float), +// 0); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); +// glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(this->textured_screen_quad_shader->pos_id); - glBindBuffer(GL_ARRAY_BUFFER, 0); +// glDisableVertexAttribArray(this->textured_screen_quad_shader->pos_id); +// glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindTexture(GL_TEXTURE_2D, 0); +// glBindTexture(GL_TEXTURE_2D, 0); - this->textured_screen_quad_shader->stopusing(); +// this->textured_screen_quad_shader->stopusing(); - return true; -} +// return true; +// } } // namespace gui } // namespace openage diff --git a/libopenage/gui/gui.h b/libopenage/gui/gui.h index d5adadef70..8f662bd2ef 100644 --- a/libopenage/gui/gui.h +++ b/libopenage/gui/gui.h @@ -5,7 +5,6 @@ #include #include -#include "../handlers.h" #include "guisys/public/gui_engine.h" #include "guisys/public/gui_event_queue.h" #include "guisys/public/gui_input.h" @@ -33,9 +32,7 @@ class EngineQMLInfo; * * Legacy variant for the "old" renderer. */ -class GUI : public InputHandler - , public ResizeHandler - , public HudHandler { +class GUI { public: explicit GUI(SDL_Window *window, const std::string &source, @@ -46,9 +43,9 @@ class GUI : public InputHandler void process_events(); private: - virtual bool on_resize(coord::viewport_delta new_size) override; - virtual bool on_input(SDL_Event *event) override; - virtual bool on_drawhud() override; + // virtual bool on_resize(coord::viewport_delta new_size) override; + // virtual bool on_input(SDL_Event *event) override; + // virtual bool on_drawhud() override; GLint tex_loc; GLuint screen_quad_vbo; diff --git a/libopenage/handlers.cpp b/libopenage/handlers.cpp deleted file mode 100644 index 8ced9fecfa..0000000000 --- a/libopenage/handlers.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright 2014-2015 the openage authors. See copying.md for legal info. - -#include "handlers.h" - -namespace openage { - -} // namespace openage diff --git a/libopenage/handlers.h b/libopenage/handlers.h deleted file mode 100644 index 9d8f00e536..0000000000 --- a/libopenage/handlers.h +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "coord/pixel.h" - - -namespace openage { - -class LegacyEngine; - -/** - * superclass for all possible drawing operations in the game. - */ -class [[deprecated]] HudHandler { -public: - virtual ~HudHandler() = default; - - /** - * execute the drawing action. - */ - virtual bool on_drawhud() = 0; -}; - -/** - * superclass for all calculations being done on engine tick. - */ -class [[deprecated]] TickHandler { -public: - virtual ~TickHandler() = default; - - /** - * execute the tick action. - */ - virtual bool on_tick() = 0; -}; - -/** - * superclass for handling any input event. - */ -class [[deprecated]] InputHandler { -public: - virtual ~InputHandler() = default; - - /** - * execute the input handler. - */ - virtual bool on_input(SDL_Event *event) = 0; -}; - -/** - * superclass for handling a window resize event. - */ -class [[deprecated]] ResizeHandler { -public: - virtual ~ResizeHandler() = default; - - /** - * execute the resize handler. - */ - virtual bool on_resize(coord::viewport_delta new_size) = 0; -}; - -} // namespace openage diff --git a/libopenage/input/legacy/input_manager.cpp b/libopenage/input/legacy/input_manager.cpp index f8ce7e2999..e8736b5fcd 100644 --- a/libopenage/input/legacy/input_manager.cpp +++ b/libopenage/input/legacy/input_manager.cpp @@ -305,70 +305,70 @@ modset_t InputManager::get_mod() const { } -bool InputManager::on_input(SDL_Event *e) { - // top level input handler - switch (e->type) { - case SDL_KEYUP: { - SDL_Keycode code = reinterpret_cast(e)->keysym.sym; - Event ev = sdl_key(code, SDL_GetModState()); - this->set_state(ev, false); - break; - } // case SDL_KEYUP - - case SDL_KEYDOWN: { - SDL_Keycode code = reinterpret_cast(e)->keysym.sym; - this->set_state(sdl_key(code, SDL_GetModState()), true); - break; - } // case SDL_KEYDOWN - - case SDL_TEXTINPUT: { - this->trigger(utf8(e->text.text)); - break; - } // case SDL_TEXTINPUT - - case SDL_MOUSEBUTTONUP: { - this->set_relative(false); - this->trigger(sdl_mouse_up_down(e->button.button, true, SDL_GetModState())); - Event ev = sdl_mouse(e->button.button, SDL_GetModState()); - this->set_state(ev, false); - break; - } // case SDL_MOUSEBUTTONUP - - case SDL_MOUSEBUTTONDOWN: { - // TODO: set which buttons - if (e->button.button == 2) { - this->set_relative(true); - } - this->trigger(sdl_mouse_up_down(e->button.button, false, SDL_GetModState())); - Event ev = sdl_mouse(e->button.button, SDL_GetModState()); - this->set_state(ev, true); - break; - } // case SDL_MOUSEBUTTONDOWN - - case SDL_MOUSEMOTION: { - if (this->relative_mode) { - this->set_motion(e->motion.xrel, e->motion.yrel); - } - else { - this->set_mouse(e->button.x, e->button.y); - } - - // must occur after setting mouse position - Event ev(event_class::MOUSE_MOTION, 0, this->get_mod()); - this->trigger(ev); - break; - } // case SDL_MOUSEMOTION - - case SDL_MOUSEWHEEL: { - Event ev = sdl_wheel(e->wheel.y, SDL_GetModState()); - this->trigger(ev); - break; - } // case SDL_MOUSEWHEEL - - } // switch (e->type) - - return true; -} +// bool InputManager::on_input(SDL_Event *e) { +// // top level input handler +// switch (e->type) { +// case SDL_KEYUP: { +// SDL_Keycode code = reinterpret_cast(e)->keysym.sym; +// Event ev = sdl_key(code, SDL_GetModState()); +// this->set_state(ev, false); +// break; +// } // case SDL_KEYUP + +// case SDL_KEYDOWN: { +// SDL_Keycode code = reinterpret_cast(e)->keysym.sym; +// this->set_state(sdl_key(code, SDL_GetModState()), true); +// break; +// } // case SDL_KEYDOWN + +// case SDL_TEXTINPUT: { +// this->trigger(utf8(e->text.text)); +// break; +// } // case SDL_TEXTINPUT + +// case SDL_MOUSEBUTTONUP: { +// this->set_relative(false); +// this->trigger(sdl_mouse_up_down(e->button.button, true, SDL_GetModState())); +// Event ev = sdl_mouse(e->button.button, SDL_GetModState()); +// this->set_state(ev, false); +// break; +// } // case SDL_MOUSEBUTTONUP + +// case SDL_MOUSEBUTTONDOWN: { +// // TODO: set which buttons +// if (e->button.button == 2) { +// this->set_relative(true); +// } +// this->trigger(sdl_mouse_up_down(e->button.button, false, SDL_GetModState())); +// Event ev = sdl_mouse(e->button.button, SDL_GetModState()); +// this->set_state(ev, true); +// break; +// } // case SDL_MOUSEBUTTONDOWN + +// case SDL_MOUSEMOTION: { +// if (this->relative_mode) { +// this->set_motion(e->motion.xrel, e->motion.yrel); +// } +// else { +// this->set_mouse(e->button.x, e->button.y); +// } + +// // must occur after setting mouse position +// Event ev(event_class::MOUSE_MOTION, 0, this->get_mod()); +// this->trigger(ev); +// break; +// } // case SDL_MOUSEMOTION + +// case SDL_MOUSEWHEEL: { +// Event ev = sdl_wheel(e->wheel.y, SDL_GetModState()); +// this->trigger(ev); +// break; +// } // case SDL_MOUSEWHEEL + +// } // switch (e->type) + +// return true; +// } std::vector InputManager::active_binds(const std::unordered_map &ctx_actions) const { diff --git a/libopenage/input/legacy/input_manager.h b/libopenage/input/legacy/input_manager.h index 92a0044524..289b95d3c5 100644 --- a/libopenage/input/legacy/input_manager.h +++ b/libopenage/input/legacy/input_manager.h @@ -8,7 +8,6 @@ #include #include -#include "handlers.h" #include "input/legacy/action.h" #include "input/legacy/event.h" #include "input/legacy/input_context.h" @@ -39,7 +38,7 @@ using binding_map_t = std::unordered_map; * bool set_bind(char* bind_char, string action) except + * string get_bind(string action) except + */ -class InputManager : public InputHandler { +class InputManager { public: /** * Screen edges used for edge scrolling. @@ -182,7 +181,7 @@ class InputManager : public InputHandler { /** * When a SDL event happens, this is called. */ - bool on_input(SDL_Event *e) override; + // bool on_input(SDL_Event *e) override; /** * Return a string representation of active key bindings diff --git a/libopenage/legacy_engine.h b/libopenage/legacy_engine.h index 532a5e17d1..396bb5b8d1 100644 --- a/libopenage/legacy_engine.h +++ b/libopenage/legacy_engine.h @@ -14,7 +14,6 @@ // pxd: from libopenage.cvar cimport CVarManager #include "cvar/cvar.h" #include "gui/engine_info.h" -#include "handlers.h" #include "input/legacy/action.h" #include "job/job_manager.h" #include "options.h" diff --git a/libopenage/unit/selection.cpp b/libopenage/unit/selection.cpp index 49ddd78440..d8c4fa44f4 100644 --- a/libopenage/unit/selection.cpp +++ b/libopenage/unit/selection.cpp @@ -24,61 +24,61 @@ UnitSelection::UnitSelection(LegacyEngine *engine) : engine{engine} { } -bool UnitSelection::on_drawhud() { - // // the drag selection box - // if (drag_active) { - // coord::viewport s = this->start.to_viewport(this->engine->coord); - // coord::viewport e = this->end.to_viewport(this->engine->coord); - // glLineWidth(1); - // glColor3f(1.0, 1.0, 1.0); - // glBegin(GL_LINE_LOOP); { - // glVertex3f(s.x, s.y, 0); - // glVertex3f(e.x, s.y, 0); - // glVertex3f(e.x, e.y, 0); - // glVertex3f(s.x, e.y, 0); - // } - // glEnd(); - // } - // - // // draw hp bars for each selected unit - // glLineWidth(3); - // for (auto u : this->units) { - // if (u.second.is_valid()) { - // Unit *unit_ptr = u.second.get(); - // if (unit_ptr->location && - // unit_ptr->has_attribute(attr_type::hitpoints) && - // unit_ptr->has_attribute(attr_type::damaged)) { - // - // auto &hp = unit_ptr->get_attribute(); - // auto &dm = unit_ptr->get_attribute(); - // float percent = static_cast(dm.hp) / static_cast(hp.hp); - // int mid = percent * 28.0f - 14.0f; - // - // coord::phys3 &pos_phys3 = unit_ptr->location->pos.draw; - // auto pos = pos_phys3.to_viewport(this->engine->coord); - // // green part - // glColor3f(0.0, 1.0, 0.0); - // glBegin(GL_LINES); { - // glVertex3f(pos.x - 14, pos.y + 60, 0); - // glVertex3f(pos.x + mid, pos.y + 60, 0); - // } - // glEnd(); - // - // // red part - // glColor3f(1.0, 0.0, 0.0); - // glBegin(GL_LINES); { - // glVertex3f(pos.x + mid, pos.y + 60, 0); - // glVertex3f(pos.x + 14, pos.y + 60, 0); - // } - // glEnd(); - // } - // } - // } - // glColor3f(1.0, 1.0, 1.0); // reset - - // ui graphics 3404 and 3405 - return true; -} +// bool UnitSelection::on_drawhud() { +// // the drag selection box +// if (drag_active) { +// coord::viewport s = this->start.to_viewport(this->engine->coord); +// coord::viewport e = this->end.to_viewport(this->engine->coord); +// glLineWidth(1); +// glColor3f(1.0, 1.0, 1.0); +// glBegin(GL_LINE_LOOP); { +// glVertex3f(s.x, s.y, 0); +// glVertex3f(e.x, s.y, 0); +// glVertex3f(e.x, e.y, 0); +// glVertex3f(s.x, e.y, 0); +// } +// glEnd(); +// } +// +// // draw hp bars for each selected unit +// glLineWidth(3); +// for (auto u : this->units) { +// if (u.second.is_valid()) { +// Unit *unit_ptr = u.second.get(); +// if (unit_ptr->location && +// unit_ptr->has_attribute(attr_type::hitpoints) && +// unit_ptr->has_attribute(attr_type::damaged)) { +// +// auto &hp = unit_ptr->get_attribute(); +// auto &dm = unit_ptr->get_attribute(); +// float percent = static_cast(dm.hp) / static_cast(hp.hp); +// int mid = percent * 28.0f - 14.0f; +// +// coord::phys3 &pos_phys3 = unit_ptr->location->pos.draw; +// auto pos = pos_phys3.to_viewport(this->engine->coord); +// // green part +// glColor3f(0.0, 1.0, 0.0); +// glBegin(GL_LINES); { +// glVertex3f(pos.x - 14, pos.y + 60, 0); +// glVertex3f(pos.x + mid, pos.y + 60, 0); +// } +// glEnd(); +// +// // red part +// glColor3f(1.0, 0.0, 0.0); +// glBegin(GL_LINES); { +// glVertex3f(pos.x + mid, pos.y + 60, 0); +// glVertex3f(pos.x + 14, pos.y + 60, 0); +// } +// glEnd(); +// } +// } +// } +// glColor3f(1.0, 1.0, 1.0); // reset + +// ui graphics 3404 and 3405 +// return true; +// } void UnitSelection::drag_begin(coord::camgame pos) { this->start = pos; diff --git a/libopenage/unit/selection.h b/libopenage/unit/selection.h index e946266009..fd623f91b9 100644 --- a/libopenage/unit/selection.h +++ b/libopenage/unit/selection.h @@ -5,7 +5,6 @@ #include #include "../coord/pixel.h" -#include "../handlers.h" #include "ability.h" #include "unit_container.h" @@ -35,11 +34,11 @@ enum class selection_type_t { /** * a user interface component allowing control of a selected group */ -class UnitSelection : public HudHandler { +class UnitSelection { public: UnitSelection(LegacyEngine *engine); - bool on_drawhud() override; + // bool on_drawhud() override; void drag_begin(coord::camgame pos); void drag_update(coord::camgame pos); void drag_release(const Player &player, Terrain *terrain, bool append = false); diff --git a/libopenage/unit/unit.h b/libopenage/unit/unit.h index 5165ed6a18..d832c26d19 100644 --- a/libopenage/unit/unit.h +++ b/libopenage/unit/unit.h @@ -9,7 +9,6 @@ #include #include "../coord/phys.h" -#include "../handlers.h" #include "../log/logsource.h" #include "../terrain/terrain_object.h" #include "../util/timing.h" diff --git a/libopenage/unit/unit_container.h b/libopenage/unit/unit_container.h index 89c6848990..8627c8582f 100644 --- a/libopenage/unit/unit_container.h +++ b/libopenage/unit/unit_container.h @@ -1,4 +1,4 @@ -// Copyright 2014-2017 the openage authors. See copying.md for legal info. +// Copyright 2014-2023 the openage authors. See copying.md for legal info. #pragma once @@ -7,7 +7,6 @@ #include #include "../coord/tile.h" -#include "../handlers.h" #include "../util/timing.h" @@ -45,7 +44,6 @@ struct reference_data { */ class UnitReference { public: - /** * create an invalid reference */ @@ -60,7 +58,6 @@ class UnitReference { Unit *get() const; private: - /** * The default copy constructor and assignment * will just copy the shared pointer From bbf1b56699bed08c6bc62ac0278f8a4a70215d69 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 23 Sep 2023 02:53:44 +0200 Subject: [PATCH 34/95] input: Remove legacy input system. --- libopenage/console/console.h | 5 +- libopenage/input/CMakeLists.txt | 1 - libopenage/input/legacy/CMakeLists.txt | 11 - libopenage/input/legacy/action.cpp | 176 ---------- libopenage/input/legacy/action.h | 99 ------ libopenage/input/legacy/event.cpp | 164 --------- libopenage/input/legacy/event.h | 162 --------- libopenage/input/legacy/input_context.cpp | 83 ----- libopenage/input/legacy/input_context.h | 117 ------- libopenage/input/legacy/input_manager.cpp | 406 ---------------------- libopenage/input/legacy/input_manager.h | 255 -------------- libopenage/input/legacy/text_to_event.cpp | 132 ------- libopenage/input/legacy/text_to_event.h | 18 - libopenage/legacy_engine.h | 1 - openage/testing/testlist.py | 1 - 15 files changed, 3 insertions(+), 1628 deletions(-) delete mode 100644 libopenage/input/legacy/CMakeLists.txt delete mode 100644 libopenage/input/legacy/action.cpp delete mode 100644 libopenage/input/legacy/action.h delete mode 100644 libopenage/input/legacy/event.cpp delete mode 100644 libopenage/input/legacy/event.h delete mode 100644 libopenage/input/legacy/input_context.cpp delete mode 100644 libopenage/input/legacy/input_context.h delete mode 100644 libopenage/input/legacy/input_manager.cpp delete mode 100644 libopenage/input/legacy/input_manager.h delete mode 100644 libopenage/input/legacy/text_to_event.cpp delete mode 100644 libopenage/input/legacy/text_to_event.h diff --git a/libopenage/console/console.h b/libopenage/console/console.h index dc9f00e9ef..a06b9e6760 100644 --- a/libopenage/console/console.h +++ b/libopenage/console/console.h @@ -7,7 +7,6 @@ #include "../coord/pixel.h" #include "../gamedata/color_dummy.h" -#include "../input/legacy/input_manager.h" #include "../renderer/font/font.h" #include "../util/color.h" #include "buf.h" @@ -18,6 +17,8 @@ class LegacyEngine; /** * In-game console subsystem. Featuring a full terminal emulator. + * + * TODO: Adapt to new engine subsystems. */ namespace console { @@ -70,7 +71,7 @@ class Console { Buf buf; renderer::Font font; - input::legacy::InputContext input_context; + // input::legacy::InputContext input_context; // the command state std::string command; diff --git a/libopenage/input/CMakeLists.txt b/libopenage/input/CMakeLists.txt index d27770d98a..f24e810608 100644 --- a/libopenage/input/CMakeLists.txt +++ b/libopenage/input/CMakeLists.txt @@ -7,5 +7,4 @@ add_sources(libopenage text_to_event.cpp ) -add_subdirectory("legacy") add_subdirectory("controller") diff --git a/libopenage/input/legacy/CMakeLists.txt b/libopenage/input/legacy/CMakeLists.txt deleted file mode 100644 index 799b91e1ee..0000000000 --- a/libopenage/input/legacy/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -add_sources(libopenage - action.cpp - event.cpp - input_context.cpp - input_manager.cpp - text_to_event.cpp -) - -pxdgen( - input_manager.h -) diff --git a/libopenage/input/legacy/action.cpp b/libopenage/input/legacy/action.cpp deleted file mode 100644 index 83d324f161..0000000000 --- a/libopenage/input/legacy/action.cpp +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "action.h" - -#include - -#include "cvar/cvar.h" -#include "input/legacy/input_manager.h" -#include "log/log.h" -#include "log/message.h" -#include "util/repr.h" - - -namespace openage { -namespace input::legacy { - -namespace { - - -// the list of action names that will be added during the constructor of ActionManager. -const std::vector DEFAULT_ACTIONS = { - "START_GAME", - "STOP_GAME", - "TOGGLE_HUD", - "SCREENSHOT", - "TOGGLE_DEBUG_OVERLAY", - "TOGGLE_DEBUG_GRID", - "QUICK_SAVE", - "QUICK_LOAD", - "TOGGLE_MODE", - "TOGGLE_MENU", - "TOGGLE_ITEM", - "TOGGLE_BLENDING", - "TOGGLE_PROFILER", - "TOGGLE_CONSTRUCT_MODE", - "TOGGLE_UNIT_DEBUG", - "TRAIN_OBJECT", - "ENABLE_BUILDING_PLACEMENT", - "DISABLE_SET_ABILITY", - "SET_ABILITY_MOVE", - "SET_ABILITY_GATHER", - "SET_ABILITY_GARRISON", - "TOGGLE_CONSOLE", - "SPAWN_VILLAGER", - "KILL_UNIT", - "BUILD_MENU", - "BUILD_MENU_MIL", - "CANCEL", - "BUILDING_HOUS", - "BUILDING_MILL", - "BUILDING_MINE", - "BUILDING_SMIL", - "BUILDING_DOCK", - "BUILDING_FARM", - "BUILDING_BLAC", - "BUILDING_MRKT", - "BUILDING_CRCH", - "BUILDING_UNIV", - "BUILDING_RTWC", - "BUILDING_WNDR", - "BUILDING_BRKS", - "BUILDING_ARRG", - "BUILDING_STBL", - "BUILDING_SIWS", - "BUILDING_WCTWX", - "BUILDING_WALL", - "BUILDING_WALL2", - "BUILDING_WCTW", - "BUILDING_WCTW4", - "BUILDING_GTCA2", - "BUILDING_CSTL", - "BUILDING_TOWN_CENTER", - "SWITCH_TO_PLAYER_1", - "SWITCH_TO_PLAYER_2", - "SWITCH_TO_PLAYER_3", - "SWITCH_TO_PLAYER_4", - "SWITCH_TO_PLAYER_5", - "SWITCH_TO_PLAYER_6", - "SWITCH_TO_PLAYER_7", - "SWITCH_TO_PLAYER_8", - "UP_ARROW", - "DOWN_ARROW", - "LEFT_ARROW", - "RIGHT_ARROW", - "SELECT", - "DESELECT", - "BEGIN_SELECTION", - "END_SELECTION", - "FORWARD", - "BACK", - "PAINT_TERRAIN", - "BUILDING_5", - "BUILDING_6", - "BUILDING_7", - "BUILDING_8", - "BUILD", - "KEEP_BUILDING", - "INCREASE_SELECTION", - "ORDER_SELECT"}; - -} // anonymous namespace - - -ActionManager::ActionManager(InputManager *input_manager, - const std::shared_ptr &cvar_manager) : - input_manager{input_manager}, - cvar_manager{cvar_manager} { - this->create("UNDEFINED"); - - for (auto &type : DEFAULT_ACTIONS) { - this->create(type); - } -} // anonymous namespace - - -bool ActionManager::create(const std::string &type) { - if (this->actions.find(type) != this->actions.end()) { - // that action is already in the list. fail. - // TODO: throw an exception instead? - // for now, just print a warning log message - log::log(WARN << "can not create action " - << util::repr(type) << ": already exists"); - return false; - } - - action_t action_id = this->next_action_id++; - - this->reverse_map[action_id] = type; - this->actions[type] = action_id; - - // and the corresponding cvar, which modifies the action bindings - // TODO: this has nothing to do with the actionmanager! - // remove the cvarmanager-access here! - this->cvar_manager->create(type, std::make_pair( - // the cvar's getter - [type, this]() { - return this->input_manager->get_bind(type); - }, - // the cvar's setter - [type, this](const std::string &value) { - this->input_manager->set_bind(value.c_str(), type); - })); - - return true; -} - - -action_t ActionManager::get(const std::string &type) { - auto it = this->actions.find(type); - if (it != this->actions.end()) { - return it->second; - } - else { - return this->actions.at("UNDEFINED"); - } -} - - -std::string ActionManager::get_name(const action_t action) { - auto it = this->reverse_map.find(action); - if (it != this->reverse_map.end()) { - return it->second; - } - else { - return "UNDEFINED"; - } -} - - -bool ActionManager::is(const std::string &type, const action_t action) { - return this->get(type) == action; -} - - -} // namespace input::legacy -} // namespace openage diff --git a/libopenage/input/legacy/action.h b/libopenage/input/legacy/action.h deleted file mode 100644 index dadd618ef9..0000000000 --- a/libopenage/input/legacy/action.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include - -#include "coord/pixel.h" -#include "input/legacy/event.h" - -namespace openage { - -class LegacyEngine; - -namespace cvar { -class CVarManager; -} // namespace cvar - -namespace input::legacy { - -class InputManager; - -/** - * Used to identify actions. - */ -using action_t = unsigned int; - - -// TODO this whole class seems rather obsolete... -// remove it and instead provide a proper class for action_t? -/** - * The action manager manages all the actions allow creation, access - * information and equality. - */ -class ActionManager { -public: - ActionManager(InputManager *input_manager, - const std::shared_ptr &cvar_manager); - -public: - action_t get(const std::string &type); - std::string get_name(const action_t action); - bool is(const std::string &type, const action_t action); - -private: - bool create(const std::string &type); - - // mapping from action name to numbers - std::unordered_map actions; - // for high-speed reverse lookups (action number -> name) - std::unordered_map reverse_map; - - InputManager *const input_manager; - const std::shared_ptr cvar_manager; - - // the id of the next action that is added via create(). - action_t next_action_id = 0; -}; - - -// TODO: use action_hint_t = std::pair -// for example a building command -// std::make_pair(action_t::BUILD, 123) -using action_id_t = action_t; - - -/** - * Contains information about a triggered event. - */ -struct action_arg_t { - // Triggering event - const Event e; - - // Mouse position - const coord::input mouse; - const coord::input_delta motion; - - // hints for arg receiver - // these get set globally in input manager - std::vector hints; -}; - - -/** - * Performs the effect of an action. - */ -using action_func_t = std::function; - - -/** - * For receivers of sets of events a bool is returned - * to indicate if the event was used. - */ -using action_check_t = std::function; - - -} // namespace input::legacy -} // namespace openage diff --git a/libopenage/input/legacy/event.cpp b/libopenage/input/legacy/event.cpp deleted file mode 100644 index a2c5d1c004..0000000000 --- a/libopenage/input/legacy/event.cpp +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "event.h" - -#include -#include - -namespace openage::input::legacy { - -ClassCode::ClassCode(event_class cl, code_t code) : - eclass(cl), - code(code) { -} - - -std::vector ClassCode::get_classes() const { - std::vector result; - - // use event_base to traverse up the class tree - event_class ec = this->eclass; - result.push_back(ec); - while (event_base.count(ec) > 0) { - ec = event_base.at(ec); - result.push_back(ec); - } - return result; -} - - -bool ClassCode::has_class(const event_class &ec) const { - for (auto c : this->get_classes()) { - if (c == ec) { - return true; - } - } - return false; -} - - -bool operator==(ClassCode a, ClassCode b) { - return a.eclass == b.eclass && a.code == b.code; -} - - -Event::Event(event_class cl, code_t code, modset_t mod) : - cc(cl, code), - mod(std::move(mod)) {} - - -Event::Event(event_class cl, std::string text, modset_t mod) : - cc(cl, 0), - mod(std::move(mod)), - utf8(std::move(text)) {} - - -char Event::as_char() const { - return (cc.code & 0xff); -} - - -std::string Event::as_utf8() const { - return utf8; -} - - -std::string Event::info() const { - std::string result; - result += "[Event: "; - result += std::to_string(static_cast(this->cc.eclass)); - result += ", "; - result += std::to_string(this->cc.code); - result += ", "; - result += this->as_char(); - result += " ("; - result += std::to_string(this->mod.size()); - result += ")]"; - return result; -} - - -bool Event::operator==(const Event &other) const { - return this->cc == other.cc && this->mod == other.mod && this->utf8 == other.utf8; -} - - -int event_hash::operator()(const Event &e) const { - return class_code_hash()(e.cc); // ^ std::hash()(e.mod) * 3664657; -} - - -int event_class_hash::operator()(const event_class &c) const { - return std::hash()(static_cast(c)); -} - - -int modifier_hash::operator()(const modifier &m) const { - return std::hash()(static_cast(m)); -} - - -int class_code_hash::operator()(const ClassCode &e) const { - return event_class_hash()(e.eclass) ^ std::hash()(e.code) * 3664657; -} - - -modset_t sdl_mod(SDL_Keymod mod) { - // Remove modifiers like num lock and caps lock - // mod = static_cast(mod & this->used_keymods); - modset_t result; - if (mod & KMOD_CTRL) { - result.emplace(modifier::CTRL); - } - if (mod & KMOD_SHIFT) { - result.emplace(modifier::SHIFT); - } - if (mod & KMOD_ALT) { - result.emplace(modifier::ALT); - } - return result; -} - - -Event sdl_key(SDL_Keycode code, SDL_Keymod mod) { - // sdl values for non printable keys - if (code & (1 << 30)) { - return Event(event_class::OTHER, code, sdl_mod(mod)); - } - else { - event_class ec; - char c = (code & 0xff); - if (isdigit(c)) { - ec = event_class::DIGIT; - } - else if (isalpha(c)) { - ec = event_class::ALPHA; - } - else if (isprint(c)) { - ec = event_class::PRINT; - } - else { - ec = event_class::NONPRINT; - } - return Event(ec, code, sdl_mod(mod)); - } -} - -Event utf8(const std::string &text) { - return Event(event_class::UTF8, text, modset_t()); -} - -Event sdl_mouse(int button, SDL_Keymod mod) { - return Event(event_class::MOUSE_BUTTON, button, sdl_mod(mod)); -} - -Event sdl_mouse_up_down(int button, bool up, SDL_Keymod mod) { - return Event(up ? event_class::MOUSE_BUTTON_UP : event_class::MOUSE_BUTTON_DOWN, button, sdl_mod(mod)); -} - -Event sdl_wheel(int direction, SDL_Keymod mod) { - return Event(event_class::MOUSE_WHEEL, direction, sdl_mod(mod)); -} - - -} // namespace openage::input::legacy diff --git a/libopenage/input/legacy/event.h b/libopenage/input/legacy/event.h deleted file mode 100644 index 82d8e9a62e..0000000000 --- a/libopenage/input/legacy/event.h +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include -#include - -#include - -namespace openage { -namespace input::legacy { - -/** - * highest level classes of input - */ -enum class event_class { - ANY, - KEYBOARD, - CHAR, // basic keycodes (lower-case, non-modified) - ALPHA, // abc - DIGIT, // 123 - PRINT, // remaining printable chars - NONPRINT, // tab, return, backspace, delete - OTHER, // arrows, home, end - UTF8, // events with utf8 encoded data - MOUSE, - MOUSE_BUTTON, - MOUSE_BUTTON_UP, - MOUSE_BUTTON_DOWN, - MOUSE_WHEEL, - MOUSE_MOTION -}; - - -struct event_class_hash { - int operator()(const event_class &s) const; -}; - - -/** - * each event type mapped to parent type - */ -static std::unordered_map event_base{ - {event_class::KEYBOARD, event_class::ANY}, - {event_class::CHAR, event_class::KEYBOARD}, - {event_class::ALPHA, event_class::CHAR}, - {event_class::DIGIT, event_class::CHAR}, - {event_class::PRINT, event_class::CHAR}, - {event_class::NONPRINT, event_class::KEYBOARD}, - {event_class::OTHER, event_class::KEYBOARD}, - {event_class::UTF8, event_class::KEYBOARD}, - {event_class::MOUSE, event_class::ANY}, - {event_class::MOUSE_BUTTON, event_class::MOUSE}, - {event_class::MOUSE_WHEEL, event_class::MOUSE}, - {event_class::MOUSE_MOTION, event_class::MOUSE}, -}; - -/** - * mods set on an event - */ -enum class modifier { - CTRL, - ALT, - SHIFT -}; - - -struct modifier_hash { - int operator()(const modifier &s) const; -}; - - -/** - * types used by events - */ -using code_t = int; -using modset_t = std::unordered_set; - - -/** - * base event type containing event handler and event code - */ -class ClassCode { -public: - ClassCode(event_class cl, code_t code); - - /** - * classes ordered with most specific first - */ - std::vector get_classes() const; - bool has_class(const event_class &c) const; - - const event_class eclass; - const code_t code; -}; - - -bool operator==(ClassCode a, ClassCode b); - - -struct class_code_hash { - int operator()(const ClassCode &k) const; -}; - - -/** - * Input event, as triggered by some input device like - * mouse, kezb, joystick, tablet, microwave or dildo. - * Some modifier keys may also be pressed during the event. - */ -class Event { -public: - Event(event_class cl, code_t code, modset_t mod); - Event(event_class cl, std::string, modset_t mod); - - /** - * Return keyboard text as char - * returns 0 for non-text events - */ - char as_char() const; - - /** - * Returns a utf encoded char - * or an empty string for non-utf8 events - */ - std::string as_utf8() const; - - /** - * logable debug info - */ - std::string info() const; - - bool operator==(const Event &other) const; - - const ClassCode cc; - const modset_t mod; - const std::string utf8; -}; - - -struct event_hash { - int operator()(const Event &e) const; -}; - - -using event_set_t = std::unordered_set; - - -// SDL mapping functions - -modset_t sdl_mod(SDL_Keymod mod); -Event sdl_key(SDL_Keycode code, SDL_Keymod mod = KMOD_NONE); -Event utf8(const std::string &text); -Event sdl_mouse(int button, SDL_Keymod mod = KMOD_NONE); -Event sdl_mouse_up_down(int button, bool up, SDL_Keymod mod = KMOD_NONE); -Event sdl_wheel(int direction, SDL_Keymod mod = KMOD_NONE); - - -} // namespace input::legacy -} // namespace openage diff --git a/libopenage/input/legacy/input_context.cpp b/libopenage/input/legacy/input_context.cpp deleted file mode 100644 index b77ae592fe..0000000000 --- a/libopenage/input/legacy/input_context.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "input_context.h" - -#include "input/legacy/input_manager.h" - - -namespace openage { -namespace input::legacy { - - -InputContext::InputContext() : - InputContext{nullptr} {} - - -InputContext::InputContext(InputManager *manager) : - utf8_mode{false} { - this->register_to(manager); -} - - -std::vector InputContext::active_binds() const { - if (this->input_manager == nullptr) { - return {}; - } - - // TODO: try to purge this backpointer to the input manager. - return this->input_manager->active_binds(this->by_type); -} - -void InputContext::bind(action_t type, const action_func_t act) { - this->by_type.emplace(std::make_pair(type, act)); -} - -void InputContext::bind(const Event &ev, const action_func_t act) { - this->by_event.emplace(std::make_pair(ev, act)); -} - -void InputContext::bind(event_class ec, const action_check_t act) { - this->by_class.emplace(std::make_pair(ec, act)); -} - -bool InputContext::execute_if_bound(const action_arg_t &arg) { - // arg type hints are highest priority - for (auto &h : arg.hints) { - auto action = this->by_type.find(h); - if (action != this->by_type.end()) { - action->second(arg); - return true; - } - } - - // specific event mappings - auto action = this->by_event.find(arg.e); - if (action != this->by_event.end()) { - action->second(arg); - return true; - } - - // check all possible class mappings - for (auto &c : arg.e.cc.get_classes()) { - auto action = this->by_class.find(c); - if (action != this->by_class.end() && action->second(arg)) { - return true; - } - } - - return false; -} - - -void InputContext::register_to(InputManager *manager) { - this->input_manager = manager; -} - - -void InputContext::unregister() { - this->input_manager = nullptr; -} - - -} // namespace input::legacy -} // namespace openage diff --git a/libopenage/input/legacy/input_context.h b/libopenage/input/legacy/input_context.h deleted file mode 100644 index ccd0f32cd1..0000000000 --- a/libopenage/input/legacy/input_context.h +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include -#include - -#include "input/legacy/action.h" -#include "input/legacy/event.h" - -namespace openage { -namespace input::legacy { - -class InputManager; - - -/** - * An input context contains all keybindings and actions - * active in e.g. the HUD only. - * For the console, there's a different input context. - * That way, each context can have the same keys - * assigned to different actions, the active context - * decides, which one to trigger. - */ -class InputContext { -public: - /** - * Create an unbound input context. - */ - InputContext(); - - /** - * Create a bound context, assigned to its manager. - */ - InputContext(InputManager *manager); - - virtual ~InputContext() = default; - - /** - * a list of all keys of this context - * which are bound currently in the active context. - * - * TODO: move this method to the input manager. - * as InputManager::active_binds(const InputContext &) const; - */ - std::vector active_binds() const; - - /** - * bind a specific action idetifier - * this is the highest matching priority - */ - void bind(action_t type, const action_func_t act); - - /** - * bind a specific event - * this is the second matching priority - */ - void bind(const Event &ev, const action_func_t act); - - /** - * bind all events of a specific class - * this is the lowest matching priority - */ - void bind(event_class ec, const action_check_t act); - - /** - * lookup an action. If it is bound, execute it. - * @return true when the action is executed, false else. - */ - bool execute_if_bound(const action_arg_t &e); - - /** - * Called by the InputManager where this context - * shall be registered to. - */ - void register_to(InputManager *manager); - - /** - * Remove the registration to an input manager. - */ - void unregister(); - - - /** - * Affects which keyboard events are received: - * true to accpet utf8 text events, - * false to receive regular char events - */ - bool utf8_mode; - -private: - /** - * Input manager this context is bound to. - */ - InputManager *input_manager; - - /** - * Maps an action id to a event execution function. - */ - std::unordered_map by_type; - - /** - * map specific overriding events - */ - std::unordered_map by_event; - - /** - * event to action map - * event_class as key, to ensure all events can be mapped - */ - std::unordered_map by_class; -}; - -} // namespace input::legacy -} // namespace openage diff --git a/libopenage/input/legacy/input_manager.cpp b/libopenage/input/legacy/input_manager.cpp deleted file mode 100644 index e8736b5fcd..0000000000 --- a/libopenage/input/legacy/input_manager.cpp +++ /dev/null @@ -1,406 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include -#include - -#include "input/legacy/action.h" -#include "input/legacy/input_manager.h" -#include "input/legacy/text_to_event.h" -#include "log/log.h" - - -namespace openage::input::legacy { - -InputManager::InputManager(ActionManager *action_manager) : - action_manager{action_manager}, - global_context{this}, - relative_mode{false} { - this->global_context.register_to(this); -} - - -namespace { - -std::string mod_set_string(modset_t mod) { - if (not mod.empty()) { - for (auto &it : mod) { - switch (it) { - case modifier::ALT: - return "ALT + "; - case modifier::CTRL: - return "CTRL + "; - case modifier::SHIFT: - return "SHIFT + "; - default: - break; - } - } - } - return ""; -} - -std::string event_as_string(const Event &event) { - if (not event.as_utf8().empty()) { - return mod_set_string(event.mod) + event.as_utf8(); - } - else { - if (event.cc.eclass == event_class::MOUSE_WHEEL) { - if (event.cc.code == -1) { - return mod_set_string(event.mod) + "Wheel down"; - } - else { - return mod_set_string(event.mod) + "Wheel up"; - } - } - return mod_set_string(event.mod) + SDL_GetKeyName(event.cc.code); - } -} - -} // namespace - - -std::string InputManager::get_bind(const std::string &action_str) { - action_t action = this->action_manager->get(action_str); - if (this->action_manager->is("UNDEFINED", action)) { - return ""; - } - - auto it = this->keys.find(action); - if (it == this->keys.end()) { - return " "; - } - - switch (it->second.cc.eclass) { - case event_class::MOUSE_BUTTON: - return this->mouse_bind_to_string(it->second); - case event_class::MOUSE_WHEEL: - return this->wheel_bind_to_string(it->second); - default: - return this->key_bind_to_string(it->second); - } -} - -bool InputManager::set_bind(const std::string &bind_str, const std::string &action_str) { - try { - action_t action = this->action_manager->get(action_str); - if (this->action_manager->is("UNDEFINED", action)) { - return false; - } - - Event ev = text_to_event(bind_str); - - auto it = this->keys.find(action); - if (it != this->keys.end()) { - this->keys.erase(it); - } - this->keys.emplace(std::make_pair(action, ev)); - - return true; - } - catch (int error) { - return false; - } -} - -std::string InputManager::key_bind_to_string(const Event &ev) { - std::string key_str = std::string(SDL_GetKeyName(ev.cc.code)); - - auto end = ev.mod.end(); - if (ev.mod.find(modifier::ALT) != end) { - key_str = "Alt " + key_str; - } - if (ev.mod.find(modifier::SHIFT) != end) { - key_str = "Shift " + key_str; - } - if (ev.mod.find(modifier::CTRL) != end) { - key_str = "Ctrl " + key_str; - } - return key_str; -} - -std::string InputManager::mouse_bind_to_string(const Event &ev) { - return "MOUSE " + std::to_string(ev.cc.code); -} - -std::string InputManager::wheel_bind_to_string(const Event &ev) { - std::string base = "WHEEL "; - switch (ev.cc.code) { - case 1: - return base + "UP"; - case -1: - return base + "DOWN"; - default: - return ""; - } -} - -InputContext &InputManager::get_global_context() { - return this->global_context; -} - -InputContext &InputManager::get_top_context() { - // return the global input context - // if no override is pushed - if (this->contexts.empty()) { - return this->global_context; - } - return *this->contexts.back(); -} - -void InputManager::push_context(InputContext *context) { - // push the context to the top - this->contexts.push_back(context); - - context->register_to(this); -} - - -void InputManager::remove_context(InputContext *context) { - if (this->contexts.empty()) { - return; - } - - for (auto it = this->contexts.begin(); it != this->contexts.end(); ++it) { - if ((*it) == context) { - this->contexts.erase(it); - context->unregister(); - return; - } - } -} - - -bool InputManager::ignored(const Event &e) { - // filter duplicate utf8 events - // these are ignored unless the top mode enables - // utf8 mode, in which case regular char codes are ignored - return ((e.cc.has_class(event_class::CHAR) || e.cc.has_class(event_class::UTF8)) && this->get_top_context().utf8_mode != e.cc.has_class(event_class::UTF8)); -} - - -bool InputManager::trigger(const Event &e) { - if (this->ignored(e)) { - return false; - } - - // arg passed to receivers - action_arg_t arg{e, this->mouse_position, this->mouse_motion, {}}; - - for (auto &it : this->keys) { - if (e == it.second) { - arg.hints.emplace_back(it.first); - } - } - - // Check context list on top of the stack (most recent bound first) - for (auto it = this->contexts.rbegin(); it != this->contexts.rend(); ++it) { - if ((*it)->execute_if_bound(arg)) { - return true; - } - } - - // If no local keybinds were bound, check the global keybinds - return this->global_context.execute_if_bound(arg); -} - - -void InputManager::set_state(const Event &ev, bool is_down) { - if (this->ignored(ev)) { - return; - } - - // update key states - this->keymod = ev.mod; - bool was_down = this->states[ev.cc]; - this->states[ev.cc] = is_down; - - // a key going from pressed to unpressed - // will automatically trigger event handling - if (was_down && !is_down) { - this->trigger(ev); - } -} - - -void InputManager::set_mouse(int x, int y) { - auto last_position = this->mouse_position; - this->mouse_position = coord::input{coord::pixel_t{x}, coord::pixel_t{y}}; - this->mouse_motion = this->mouse_position - last_position; -} - - -void InputManager::set_motion(int x, int y) { - this->mouse_motion.x = x; - this->mouse_motion.y = y; -} - - -void InputManager::set_relative(bool mode) { - if (this->relative_mode == mode) { - return; - } - - // change mode - this->relative_mode = mode; - if (this->relative_mode) { - SDL_SetRelativeMouseMode(SDL_TRUE); - } - else { - SDL_SetRelativeMouseMode(SDL_FALSE); - } -} - -bool InputManager::is_mouse_at_edge(Edge edge, int window_size) { - int x, y; - SDL_GetMouseState(&x, &y); - - // Border width to consider screen edges for scrolling. - // AoE II appears to be approx 10px. - // TODO: make configurable through cvar. - const int edge_offset = 10; - - if (edge == Edge::LEFT && x <= edge_offset) { - return true; - } - if (edge == Edge::RIGHT && x >= window_size - edge_offset - 1) { - return true; - } - if (edge == Edge::UP && y <= edge_offset) { - return true; - } - if (edge == Edge::DOWN && y >= window_size - edge_offset - 1) { - return true; - } - - return false; -} - -bool InputManager::is_down(const ClassCode &cc) const { - auto it = this->states.find(cc); - if (it != this->states.end()) { - return it->second; - } - return false; -} - - -bool InputManager::is_down(event_class ec, code_t code) const { - return is_down(ClassCode(ec, code)); -} - - -bool InputManager::is_down(SDL_Keycode k) const { - return is_down(sdl_key(k).cc); -} - - -bool InputManager::is_mod_down(modifier mod) const { - return (this->keymod.count(mod) > 0); -} - - -modset_t InputManager::get_mod() const { - SDL_Keymod mod = SDL_GetModState(); - return sdl_mod(mod); -} - - -// bool InputManager::on_input(SDL_Event *e) { -// // top level input handler -// switch (e->type) { -// case SDL_KEYUP: { -// SDL_Keycode code = reinterpret_cast(e)->keysym.sym; -// Event ev = sdl_key(code, SDL_GetModState()); -// this->set_state(ev, false); -// break; -// } // case SDL_KEYUP - -// case SDL_KEYDOWN: { -// SDL_Keycode code = reinterpret_cast(e)->keysym.sym; -// this->set_state(sdl_key(code, SDL_GetModState()), true); -// break; -// } // case SDL_KEYDOWN - -// case SDL_TEXTINPUT: { -// this->trigger(utf8(e->text.text)); -// break; -// } // case SDL_TEXTINPUT - -// case SDL_MOUSEBUTTONUP: { -// this->set_relative(false); -// this->trigger(sdl_mouse_up_down(e->button.button, true, SDL_GetModState())); -// Event ev = sdl_mouse(e->button.button, SDL_GetModState()); -// this->set_state(ev, false); -// break; -// } // case SDL_MOUSEBUTTONUP - -// case SDL_MOUSEBUTTONDOWN: { -// // TODO: set which buttons -// if (e->button.button == 2) { -// this->set_relative(true); -// } -// this->trigger(sdl_mouse_up_down(e->button.button, false, SDL_GetModState())); -// Event ev = sdl_mouse(e->button.button, SDL_GetModState()); -// this->set_state(ev, true); -// break; -// } // case SDL_MOUSEBUTTONDOWN - -// case SDL_MOUSEMOTION: { -// if (this->relative_mode) { -// this->set_motion(e->motion.xrel, e->motion.yrel); -// } -// else { -// this->set_mouse(e->button.x, e->button.y); -// } - -// // must occur after setting mouse position -// Event ev(event_class::MOUSE_MOTION, 0, this->get_mod()); -// this->trigger(ev); -// break; -// } // case SDL_MOUSEMOTION - -// case SDL_MOUSEWHEEL: { -// Event ev = sdl_wheel(e->wheel.y, SDL_GetModState()); -// this->trigger(ev); -// break; -// } // case SDL_MOUSEWHEEL - -// } // switch (e->type) - -// return true; -// } - - -std::vector InputManager::active_binds(const std::unordered_map &ctx_actions) const { - std::vector result; - - // TODO: this only checks the by_type mappings, the others are missing! - for (auto &action : ctx_actions) { - std::string keyboard_key; - - for (auto &key : this->keys) { - if (key.first == action.first) { - keyboard_key = event_as_string(key.second); - break; - } - } - - // this is only possible if the action is registered, - // then this->input_manager != nullptr. - // TODO: try to purge the action manager access here. - // TODO: get_name takes O(n) time - std::string action_type_str = this->get_action_manager()->get_name(action.first); - - result.push_back(keyboard_key + " : " + action_type_str); - } - - return result; -} - - -ActionManager *InputManager::get_action_manager() const { - return this->action_manager; -} - - -} // namespace openage::input::legacy diff --git a/libopenage/input/legacy/input_manager.h b/libopenage/input/legacy/input_manager.h deleted file mode 100644 index 289b95d3c5..0000000000 --- a/libopenage/input/legacy/input_manager.h +++ /dev/null @@ -1,255 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -// pxd: from libcpp cimport bool -#include -// pxd: from libcpp.string cimport string -#include -#include - -#include "input/legacy/action.h" -#include "input/legacy/event.h" -#include "input/legacy/input_context.h" - - -namespace openage { - - -/** - * The openage input layer. - * It gets all the events and processes them accordingly. - */ -namespace input::legacy { - -/** - * maps actions to events. - */ -using binding_map_t = std::unordered_map; - - -/** - * The input manager manages all input layers (hud, game, ...) - * and triggers the registered actions depending on the active layer. - * - * pxd: - * - * cppclass InputManager: - * bool set_bind(char* bind_char, string action) except + - * string get_bind(string action) except + - */ -class InputManager { -public: - /** - * Screen edges used for edge scrolling. - */ - enum class Edge { - LEFT, - RIGHT, - UP, - DOWN - }; - - InputManager(ActionManager *action_manager); - - /** - * Return the string representation of the bind assignated to an action. - */ - std::string get_bind(const std::string &action); - - /** - * Set the given action to be triggered by the given bind (key/mouse - * /wheel). Remove previous assignation. Do nothing if either they - * given bind or action is invalid/unknow. - */ - bool set_bind(const std::string &bind_str, const std::string &action); - - /** - * Return the string representation of the key event. - */ - std::string key_bind_to_string(const Event &ev); - - /** - * Return the string representation of the mouse event. - */ - std::string mouse_bind_to_string(const Event &ev); - - /** - * Return the key representation of the event. - */ - std::string wheel_bind_to_string(const Event &ev); - - /** - * returns the global keybind context. - * actions bound here will be retained even when override_context is called. - */ - InputContext &get_global_context(); - - /** - * Returns the context on top. - * Note there is always a top context - * since the global context will be - * considered on top when none are registered - */ - InputContext &get_top_context(); - - /** - * register a hotkey context by pushing it onto the stack. - * - * this adds the given pointer to the `contexts` list. - * that way the context lays on "top". - * - * if other contexts are registered afterwards, - * it wanders down the stack, i.e. looses priority. - */ - void push_context(InputContext *context); - - /** - * removes any matching registered context from the stack. - * - * the removal is done by finding the given pointer - * in the `contexts` lists, then deleting it in there. - */ - void remove_context(InputContext *context); - - /** - * true if the given event type is being ignored - */ - bool ignored(const Event &e); - - /** - * manages the pressing of an input event (key, mouse, ...). - * first checks whether an action is bound to it. - * if it is, look for an handler to execute that handler. - * returns true if the event was responded to - */ - bool trigger(const Event &e); - - /** - * sets the state of a specific key - */ - void set_state(const Event &ev, bool is_down); - - /** - * updates mouse position state and motion - */ - void set_mouse(int x, int y); - - /** - * updates mouse motion only - */ - void set_motion(int x, int y); - - /** - * enable relative mouse mode - */ - void set_relative(bool mode); - - /** - * Query whether cursor is at edgo of screen - * - * edge variable is enum Edges - * - * @return true when the mouse is at the queried screen edge, false else. - */ - bool is_mouse_at_edge(Edge edge, int window_size); - - /** - * Query stored pressing stat for a key. - * - * note that the function stores a unknown/new keycode - * as 'not pressed' if requested - * @return true when the key is pressed, false else. - */ - bool is_down(const ClassCode &cc) const; - bool is_down(event_class ec, code_t code) const; - - /** - * Most cases should use above is_down(class, code) - * instead to avoid relying on sdl types - * - * Query stored pressing stat for a key. - * @return true when the key is pressed, false else. - */ - bool is_down(SDL_Keycode k) const; - - /** - * Checks whether a key modifier is held down. - */ - bool is_mod_down(modifier mod) const; - - /** - * When a SDL event happens, this is called. - */ - // bool on_input(SDL_Event *e) override; - - /** - * Return a string representation of active key bindings - * from the given context. - */ - std::vector active_binds(const std::unordered_map &ctx_actions) const; - - /** - * Get the action manager attached to this input manager. - */ - ActionManager *get_action_manager() const; - -private: - modset_t get_mod() const; - - /** - * The action manager to used for keybind action lookups. - */ - ActionManager *action_manager; - - /** - * The global context. Used as fallback. - */ - InputContext global_context; - - /** - * Maps actions to events. - */ - binding_map_t keys; - - /** - * Stack of active input contexts. - * The most recent entry is pushed on top of the stack. - */ - std::vector contexts; - - /** - * key to is_down map. - * stores a mapping between keycodes and its pressing state. - * a true value means the key is currently pressed, - * false indicates the key is untouched. - */ - std::unordered_map states; - - /** - * Current key modifiers. - * Included ALL modifiers including num lock and caps lock. - */ - modset_t keymod; - - /** - * mode where mouse position is ignored - * used for map scrolling - */ - bool relative_mode; - - /** - * mouse position in the window - */ - coord::input mouse_position{0, 0}; - - /** - * mouse position relative to the last frame position. - */ - coord::input_delta mouse_motion{0, 0}; - - friend InputContext; -}; - -} // namespace input::legacy -} // namespace openage diff --git a/libopenage/input/legacy/text_to_event.cpp b/libopenage/input/legacy/text_to_event.cpp deleted file mode 100644 index c0d410456b..0000000000 --- a/libopenage/input/legacy/text_to_event.cpp +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright 2016-2023 the openage authors. See copying.md for legal info. - -#include "text_to_event.h" - -#include -#include -#include - -#include "error/error.h" -#include "log/log.h" -#include "testing/testing.h" - - -namespace openage { -namespace input::legacy { - -namespace { -const std::vector modifiers{ - KMOD_LCTRL, KMOD_LSHIFT, KMOD_RCTRL, KMOD_RSHIFT, KMOD_LALT, KMOD_RALT, KMOD_LGUI, KMOD_RGUI, KMOD_CTRL, KMOD_SHIFT, KMOD_ALT, KMOD_GUI, KMOD_MODE, KMOD_CAPS, KMOD_NUM}; - -const std::regex event_pattern{ - "(?:(?:(LCtrl)|(LShift)|(RCtrl)|(RShift)|(LAlt)|(RAlt)|(LGui)|(RGUI)|(Ctrl)|(Shift)|(Alt)|(Gui)|(AltGr)|(Caps)|(NumLck))[[:space:]]+)?" // modifier (optional) - "([^[:space:]]+)" // key - "(?:[[:space:]]+([^[:space:]]+))?" // parameter, like direction (optional) - "[[:space:]]*"}; - -void check_modifiers_once() { - static bool checked = false; - - if (!checked) { - checked = true; - ENSURE(event_pattern.mark_count() == modifiers.size() + 2, "Groups in the input event regex pattern: one per key modifier, key itself and amount."); - } -} - -Event to_event(const std::string &event_type, const std::string ¶m, const int mod) { - try { - if (event_type == "MOUSE") - return sdl_mouse(std::stoi(param), static_cast(mod)); - else if (event_type == "MOUSE_UP") - return sdl_mouse_up_down(std::stoi(param), true, static_cast(mod)); - else if (event_type == "MOUSE_DOWN") - return sdl_mouse_up_down(std::stoi(param), false, static_cast(mod)); - } - catch (std::logic_error &) { - throw Error(MSG(err) << "could not parse mouse button '" << param << "'!"); - } - - if (event_type == "WHEEL") { - if (param == "1" || param == "UP") { - return sdl_wheel(1, static_cast(mod)); - } - else if (param == "-1" || param == "DOWN") { - return sdl_wheel(-1, static_cast(mod)); - } - - throw Error(MSG(err) << "could not parse mouse wheel amount '" << param << "'!"); - } - - SDL_Keycode key_code = SDL_GetKeyFromName(event_type.c_str()); - if (key_code == SDLK_UNKNOWN) { - throw Error(MSG(err) << "could not parse key '" << event_type << "'!"); - } - - if (!param.empty()) - log::log(MSG(warn) << "nothing expected after key name '" << event_type << "', but got '" << param << "'."); - - return sdl_key(key_code, static_cast(mod)); -} - -} // namespace - -/** - * Convert a string to an event, throw if the string is not a valid event. - */ -Event text_to_event(const std::string &event_str) { - check_modifiers_once(); - ENSURE(event_str.find('\n'), "Input event string representation must be one line, got '" << event_str << "'."); - - int mod = 0; - std::smatch event_elements; - - if (std::regex_match(event_str, event_elements, event_pattern)) { - /** - * First element is the entire match, so search from the second. - */ - auto groups_it = std::begin(event_elements) + 1; - - auto first_non_empty = std::find_if(groups_it, std::end(event_elements), [](const std::ssub_match &element) { - return element.length(); - }); - - ENSURE(first_non_empty != std::end(event_elements), "Nothing captured from string representation of event '" << event_str << "': regex pattern is broken."); - - auto index_first_non_empty = std::distance(groups_it, first_non_empty); - - if (index_first_non_empty < std::distance(std::begin(modifiers), std::end(modifiers))) - mod = modifiers[index_first_non_empty]; - - auto event_type = groups_it[modifiers.size()].str(); - ENSURE(!event_type.empty(), "Empty group where key was expected in string representation of event '" << event_str << "': regex pattern is broken."); - - auto param = groups_it[modifiers.size() + 1].str(); - - return to_event(event_type, param, mod); - } - else { - throw Error(MSG(err) << "could not parse keybinding '" << event_str << "'!"); - } -} - -namespace tests { -void parse_event_string() { - text_to_event("q") == Event{event_class::ALPHA, SDL_GetKeyFromName("q"), modset_t{}} || TESTFAIL; - text_to_event("Return") == Event{event_class::NONPRINT, SDL_GetKeyFromName("Return"), modset_t{}} || TESTFAIL; - text_to_event("Ctrl p") == Event{event_class::ALPHA, SDL_GetKeyFromName("p"), sdl_mod(static_cast(KMOD_CTRL))} || TESTFAIL; - text_to_event("Shift MOUSE 1") == Event{event_class::MOUSE_BUTTON, 1, sdl_mod(static_cast(KMOD_SHIFT))} || TESTFAIL; - text_to_event("MOUSE_UP 1") == Event{event_class::MOUSE_BUTTON_UP, 1, modset_t{}} || TESTFAIL; - text_to_event("WHEEL -1") == Event{event_class::MOUSE_WHEEL, -1, modset_t{}} || TESTFAIL; - TESTTHROWS(text_to_event("")); - TESTTHROWS(text_to_event("WHEEL")); - TESTTHROWS(text_to_event("MOUSE")); - TESTTHROWS(text_to_event("MOUSE_DOWN")); - TESTTHROWS(text_to_event("Blurb MOUSE 1")); - TESTTHROWS(text_to_event("Shift MICKEY_MOUSE 1")); - TESTTHROWS(text_to_event("WHEEL TEAR_OFF")); -} - -} // namespace tests - -} // namespace input::legacy -} // namespace openage diff --git a/libopenage/input/legacy/text_to_event.h b/libopenage/input/legacy/text_to_event.h deleted file mode 100644 index 745f33e04b..0000000000 --- a/libopenage/input/legacy/text_to_event.h +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2016-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "input/legacy/event.h" - -namespace openage { -namespace input::legacy { - -/** - * Convert a string to an event, throw if the string is not a valid event. - */ -Event text_to_event(const std::string &event_str); - -} // namespace input::legacy -} // namespace openage diff --git a/libopenage/legacy_engine.h b/libopenage/legacy_engine.h index 396bb5b8d1..cf01cb391a 100644 --- a/libopenage/legacy_engine.h +++ b/libopenage/legacy_engine.h @@ -14,7 +14,6 @@ // pxd: from libopenage.cvar cimport CVarManager #include "cvar/cvar.h" #include "gui/engine_info.h" -#include "input/legacy/action.h" #include "job/job_manager.h" #include "options.h" #include "unit/selection.h" diff --git a/openage/testing/testlist.py b/openage/testing/testlist.py index 939732bd0d..75a684e85e 100644 --- a/openage/testing/testlist.py +++ b/openage/testing/testlist.py @@ -99,7 +99,6 @@ def tests_cpp(): yield "openage::util::tests::vector" yield "openage::util::tests::siphash" yield "openage::util::tests::array_conversion" - yield "openage::input::legacy::tests::parse_event_string", "keybinds parsing" yield "openage::curve::tests::container" yield "openage::curve::tests::curve_types" yield "openage::event::tests::eventtrigger" From 17959b3c464b83c5c1f84daa45fff2665f703190 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 23 Sep 2023 02:59:55 +0200 Subject: [PATCH 35/95] renderer: Remove old shader code. --- libopenage/CMakeLists.txt | 1 - libopenage/console/draw.cpp | 1 - libopenage/gui/gui.cpp | 50 ------ libopenage/gui/gui.h | 12 -- libopenage/renderer/CMakeLists.txt | 1 - libopenage/renderer/text.cpp | 236 ----------------------------- libopenage/renderer/text.h | 125 --------------- libopenage/shader/CMakeLists.txt | 4 - libopenage/shader/program.cpp | 178 ---------------------- libopenage/shader/program.h | 47 ------ libopenage/shader/shader.cpp | 66 -------- libopenage/shader/shader.h | 24 --- libopenage/unit/selection.cpp | 1 - 13 files changed, 746 deletions(-) delete mode 100644 libopenage/renderer/text.cpp delete mode 100644 libopenage/renderer/text.h delete mode 100644 libopenage/shader/CMakeLists.txt delete mode 100644 libopenage/shader/program.cpp delete mode 100644 libopenage/shader/program.h delete mode 100644 libopenage/shader/shader.cpp delete mode 100644 libopenage/shader/shader.h diff --git a/libopenage/CMakeLists.txt b/libopenage/CMakeLists.txt index a87c120f50..af67e9e4ee 100644 --- a/libopenage/CMakeLists.txt +++ b/libopenage/CMakeLists.txt @@ -359,7 +359,6 @@ add_subdirectory("presenter") add_subdirectory("pyinterface") add_subdirectory("renderer") add_subdirectory("rng") -add_subdirectory("shader") add_subdirectory("terrain") add_subdirectory("testing") add_subdirectory("time") diff --git a/libopenage/console/draw.cpp b/libopenage/console/draw.cpp index 187079f86f..c8835d5bcc 100644 --- a/libopenage/console/draw.cpp +++ b/libopenage/console/draw.cpp @@ -10,7 +10,6 @@ #include "../util/timing.h" #include -#include "../renderer/text.h" #include "buf.h" #include "console.h" diff --git a/libopenage/gui/gui.cpp b/libopenage/gui/gui.cpp index 59d6e24c6b..dfa44fdc8b 100644 --- a/libopenage/gui/gui.cpp +++ b/libopenage/gui/gui.cpp @@ -1,9 +1,5 @@ // Copyright 2015-2023 the openage authors. See copying.md for legal info. -// include first to make opengl and libepoxy happy. -#include "../shader/program.h" -#include "../shader/shader.h" - #include "gui.h" #include "../legacy_engine.h" @@ -37,55 +33,9 @@ GUI::GUI(SDL_Window *window, // info->display->register_resize_action(this); // info->display->register_input_action(this); // info->display->register_drawhud_action(this); - - util::Path shader_dir = info->asset_dir / "shaders"; - - const char *shader_header_code = "#version 120\n"; - - auto text_vert_file = (shader_dir / "identity.vert.glsl").open(); - std::string texture_vert_code = text_vert_file.read(); - auto plaintexture_vert = std::make_unique( - GL_VERTEX_SHADER, - std::initializer_list{shader_header_code, texture_vert_code.c_str()}); - text_vert_file.close(); - - auto text_frag_file = (shader_dir / "maptexture.frag.glsl").open(); - std::string texture_frag_code = text_frag_file.read(); - auto plaintexture_frag = std::make_unique( - GL_FRAGMENT_SHADER, - std::initializer_list{shader_header_code, texture_frag_code.c_str()}); - text_vert_file.close(); - - this->textured_screen_quad_shader = std::make_unique( - plaintexture_vert.get(), - plaintexture_frag.get()); - - this->textured_screen_quad_shader->link(); - this->tex_loc = this->textured_screen_quad_shader->get_uniform_id("texture"); - this->textured_screen_quad_shader->use(); - glUniform1i(this->tex_loc, 0); - this->textured_screen_quad_shader->stopusing(); - - const float screen_quad[] = { - -1.f, - -1.f, - 1.f, - -1.f, - 1.f, - 1.f, - -1.f, - 1.f, - }; - - glGenBuffers(1, &this->screen_quad_vbo); - - glBindBuffer(GL_ARRAY_BUFFER, this->screen_quad_vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(screen_quad), screen_quad, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); } GUI::~GUI() { - glDeleteBuffers(1, &this->screen_quad_vbo); } void GUI::process_events() { diff --git a/libopenage/gui/gui.h b/libopenage/gui/gui.h index 8f662bd2ef..600e4be52a 100644 --- a/libopenage/gui/gui.h +++ b/libopenage/gui/gui.h @@ -18,10 +18,6 @@ class GuiSingletonItemsInfo; } // namespace qtsdl namespace openage { -namespace shader { -class Program; -} // namespace shader - namespace gui { class EngineQMLInfo; @@ -47,9 +43,6 @@ class GUI { // virtual bool on_input(SDL_Event *event) override; // virtual bool on_drawhud() override; - GLint tex_loc; - GLuint screen_quad_vbo; - GuiApplicationWithLogger application; qtsdl::GuiEventQueue render_updater; qtsdl::GuiRenderer renderer; @@ -57,11 +50,6 @@ class GUI { qtsdl::GuiEngine engine; qtsdl::GuiSubtree subtree; qtsdl::GuiInput input; - - // needs to be deallocated before the GuiRenderer - // it accesses opengl api functions which require a - // current context: - std::unique_ptr textured_screen_quad_shader; }; } // namespace gui diff --git a/libopenage/renderer/CMakeLists.txt b/libopenage/renderer/CMakeLists.txt index 8a889de978..b6578cd128 100644 --- a/libopenage/renderer/CMakeLists.txt +++ b/libopenage/renderer/CMakeLists.txt @@ -6,7 +6,6 @@ add_sources(libopenage render_factory.cpp renderer.cpp shader_program.cpp - text.cpp texture.cpp texture_array.cpp types.cpp diff --git a/libopenage/renderer/text.cpp b/libopenage/renderer/text.cpp deleted file mode 100644 index 9bb108cc33..0000000000 --- a/libopenage/renderer/text.cpp +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2015-2018 the openage authors. See copying.md for legal info. - -#include "text.h" - -#include - -#include - -#include "../util/strings.h" -#include "font/font.h" - -namespace openage { - -namespace texturefont_shader { -shader::Program *program; -GLint texture, color, tex_coord; -} // namespace texture_shader - -namespace renderer { - -struct text_render_vertex { - float x; - float y; - float u; - float v; - - text_render_vertex() - : - text_render_vertex{0.0f, 0.0f, 0.0f, 0.0f} { - } - - text_render_vertex(float x, float y, float u, float v) - : - x{x}, - y{y}, - u{u}, - v{v} { - } -}; - -struct text_render_task { - GLenum mode; - Color color; - unsigned int num_elements; - unsigned int offset; -}; - -TextRenderer::TextRenderer() - : - current_font{nullptr}, - current_color{255, 255, 255, 255}, - is_dirty{true}, - vbo{0}, - ibo{0} { - - glGenBuffers(1, &this->vbo); - glGenBuffers(1, &this->ibo); -} - -TextRenderer::~TextRenderer() { - if (this->vbo != 0u) { - glDeleteBuffers(1, &this->vbo); - } - if (this->ibo != 0u) { - glDeleteBuffers(1, &this->ibo); - } -} - -void TextRenderer::set_font(Font *font) { - if (this->current_font == font) { - return; - } - - this->current_font = font; - this->is_dirty = true; -} - -void TextRenderer::set_color(const Color &color) { - if (this->current_color == color) { - return; - } - - this->current_color = color; - this->is_dirty = true; -} - -void TextRenderer::draw(coord::viewport position, const char *format, ...) { - std::string text; - va_list vl; - va_start(vl, format); - util::vsformat(format, vl, text); - va_end(vl); - - this->draw(position.x, position.y, text); -} - -void TextRenderer::draw(coord::viewport position, const std::string &text) { - this->draw(position.x, position.y, text); -} - -void TextRenderer::draw(int x, int y, const std::string &text) { - if (this->is_dirty || this->render_batches.empty()) { - this->render_batches.emplace_back(this->current_font, this->current_color); - this->is_dirty = false; - } - - this->render_batches.back().passes.emplace_back(x, y, text); -} - -void TextRenderer::render() { - // Sort the batches by font - std::sort(std::begin(this->render_batches), std::end(this->render_batches), - [](const text_render_batch &a, const text_render_batch &b) -> bool { - return a.font < b.font; - }); - - // Merge consecutive batches if font and color values are same - for (auto current_batch = std::begin(this->render_batches); current_batch != std::end(this->render_batches); ) { - auto next_batch = current_batch; - next_batch++; - if (next_batch != std::end(this->render_batches) && - current_batch->font == next_batch->font && - current_batch->color == next_batch->color) { - // Merge the render passes of current and next batches and remove the next batch - std::move(std::begin(next_batch->passes), - std::end(next_batch->passes), - std::back_inserter(current_batch->passes)); - this->render_batches.erase(next_batch); - } else { - current_batch++; - } - } - - size_t index = 0; - std::vector vertices; - std::vector indices; - std::vector render_tasks; - render_tasks.reserve(this->render_batches.size()); - unsigned int offset = 0; - - // Compute vertices and indices - for (auto &batch : this->render_batches) { - Font *font = batch.font; - - unsigned int num_elements = 0; - - for (auto &pass : batch.passes) { - auto x = static_cast(pass.x); - auto y = static_cast(pass.y); - - std::vector glyphs = font->get_glyphs(pass.text); - - // We will create 4 vertices & 6 indices for each glyph (GL_TRIANGLES) - vertices.resize(vertices.size() + glyphs.size() * 4); - indices.resize(indices.size() + glyphs.size() * 6); - - codepoint_t previous_glyph = 0; - for (codepoint_t glyph : glyphs) { - GlyphAtlas::Entry entry = this->glyph_atlas.get(font, glyph); - - float x0 = x + entry.glyph.x_offset; - float y0 = y + entry.glyph.y_offset - entry.glyph.height; - float x1 = x0 + entry.glyph.width; - float y1 = y0 + entry.glyph.height; - - vertices[index*4 + 0] = {x0, y0, entry.u0, entry.v0}; - vertices[index*4 + 1] = {x0, y1, entry.u0, entry.v1}; - vertices[index*4 + 2] = {x1, y1, entry.u1, entry.v1}; - vertices[index*4 + 3] = {x1, y0, entry.u1, entry.v0}; - - indices[index*6 + 0] = index*4 + 0; - indices[index*6 + 1] = index*4 + 1; - indices[index*6 + 2] = index*4 + 2; - indices[index*6 + 3] = index*4 + 2; - indices[index*6 + 4] = index*4 + 3; - indices[index*6 + 5] = index*4 + 0; - - // Advance the pen position - x += entry.glyph.x_advance; - y += entry.glyph.y_advance; - - // Handle font kerning - if (previous_glyph != 0) { - x += font->get_horizontal_kerning(previous_glyph, glyph); - } - - index++; - num_elements += 6; - previous_glyph = glyph; - } - } - - text_render_task render_task{GL_TRIANGLES, batch.color, num_elements, offset}; - render_tasks.push_back(render_task); - - offset += num_elements; - } - - // Upload vertices and indices - glBindBuffer(GL_ARRAY_BUFFER, this->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->ibo); - - glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(text_render_vertex), &vertices[0], GL_STATIC_DRAW); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW); - - texturefont_shader::program->use(); - - this->glyph_atlas.bind(0); - - glEnableVertexAttribArray(texturefont_shader::program->pos_id); - glEnableVertexAttribArray(texturefont_shader::tex_coord); - - glVertexAttribPointer(texturefont_shader::program->pos_id, 2, GL_FLOAT, GL_FALSE, - sizeof(text_render_vertex), (GLvoid *) offsetof(text_render_vertex, x)); - glVertexAttribPointer(texturefont_shader::tex_coord, 2, GL_FLOAT, GL_FALSE, - sizeof(text_render_vertex), (GLvoid *) offsetof(text_render_vertex, u)); - - for (auto &task : render_tasks) { - glUniform4f(texturefont_shader::color, - task.color.r/255.f, task.color.g/255.f, task.color.b/255.f, task.color.a/255.f); - glDrawElements(task.mode, task.num_elements, GL_UNSIGNED_INT, (GLvoid *) (task.offset * sizeof(unsigned int))); - } - - glDisableVertexAttribArray(texturefont_shader::program->pos_id); - glDisableVertexAttribArray(texturefont_shader::tex_coord); - - texturefont_shader::program->stopusing(); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - // Clear the render batches for next frame - this->render_batches.clear(); -} - -}} // openage::renderer diff --git a/libopenage/renderer/text.h b/libopenage/renderer/text.h deleted file mode 100644 index 116cbe647a..0000000000 --- a/libopenage/renderer/text.h +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include - -#include "../coord/pixel.h" -#include "../shader/program.h" -#include "color.h" -#include "font/glyph_atlas.h" - -namespace openage { - -namespace texturefont_shader { -extern shader::Program *program; -extern GLint texture, color, tex_coord; -} // openage::texturefont_shader - -namespace renderer { - -/** - * Can render text with OpenGL. - * - * TODO: move to the main renderer! - */ -class TextRenderer { - -public: - /** - * Requires a working OpenGL context to create buffer objects. - */ - TextRenderer(); - - virtual ~TextRenderer(); - - /** - * Set the font to be used for the future text draw calls. - * - * @param font: the font to be used. - */ - void set_font(Font *font); - - /** - * Set the color to be used for the future text draw calls. - * - * @param color: the color to be used. - */ - void set_color(const Color &color); - - /** - * Draw a formatted string at the specified position. - * - * @param position: where the text should be displayed. - * @param format: the text format - */ - void draw(coord::viewport position, const char *format, ...); - - /** - * Draw text at the specified position. - * - * @param position: where the text should be displayed. - * @param text: the text to be displayed. - */ - void draw(coord::viewport position, const std::string &text); - - /** - * Draw text at the specified position. - * - * @param x: the position in x-direction. - * @param y: the position in y-direction. - * @param text: the text to be displayed. - */ - void draw(int x, int y, const std::string &text); - - /** - * Render all the text draw requests made during the frame. - */ - void render(); - -private: - /** - * A single text draw request containing the text and position. - */ - struct text_render_batch_pass { - int x; - int y; - std::string text; - - text_render_batch_pass(int x, int y, const std::string &text) - : - x{x}, - y{y}, - text{text} { - } - }; - - /** - * The set of text draw requests with the same font and color. - */ - struct text_render_batch { - Font *font; - Color color; - std::vector passes; - - text_render_batch(Font *font, const Color &color) - : - font{font}, - color{color} { - } - }; - - Font *current_font; - Color current_color; - bool is_dirty; - std::vector render_batches; - - GlyphAtlas glyph_atlas; - - GLuint vbo; - GLuint ibo; -}; - -}} // openage::renderer diff --git a/libopenage/shader/CMakeLists.txt b/libopenage/shader/CMakeLists.txt deleted file mode 100644 index 6477fa9fc7..0000000000 --- a/libopenage/shader/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -add_sources(libopenage - program.cpp - shader.cpp -) diff --git a/libopenage/shader/program.cpp b/libopenage/shader/program.cpp deleted file mode 100644 index 479d91a6ae..0000000000 --- a/libopenage/shader/program.cpp +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2013-2023 the openage authors. See copying.md for legal info. - -#include "program.h" - -#include -#include -#include - -#include "../error/error.h" -#include "../log/log.h" -#include "../util/compiler.h" -#include "../util/file.h" -#include "../util/strings.h" - -#include "shader.h" - -namespace openage::shader { - -Program::Program() : is_linked(false), vert(nullptr), frag(nullptr), geom(nullptr) { - this->id = glCreateProgram(); -} - -Program::Program(Shader *s0, Shader *s1) : Program{} { - this->attach_shader(s0); - this->attach_shader(s1); -} - -Program::~Program() { - glDeleteProgram(this->id); -} - -void Program::attach_shader(Shader *s) { - switch (s->type) { - case GL_VERTEX_SHADER: - this->vert = s; - break; - case GL_FRAGMENT_SHADER: - this->frag = s; - break; - case GL_GEOMETRY_SHADER: - this->geom = s; - break; - } - glAttachShader(this->id, s->id); -} - -void Program::link() { - glLinkProgram(this->id); - this->check(GL_LINK_STATUS); - glValidateProgram(this->id); - this->check(GL_VALIDATE_STATUS); - this->is_linked = true; - this->post_link_hook(); - - if (this->vert != nullptr) { - glDetachShader(this->id, this->vert->id); - } - if (this->frag != nullptr) { - glDetachShader(this->id, this->frag->id); - } - if (this->geom != nullptr) { - glDetachShader(this->id, this->geom->id); - } -} - -/** - * checks a given status for this program. - * - * @param what_to_check GL_LINK_STATUS GL_VALIDATE_STATUS GL_COMPILE_STATUS - */ -void Program::check(GLenum what_to_check) { - GLint status; - glGetProgramiv(this->id, what_to_check, &status); - - if (status != GL_TRUE) { - GLint loglen; - glGetProgramiv(this->id, GL_INFO_LOG_LENGTH, &loglen); - char *infolog = new char[loglen]; - glGetProgramInfoLog(this->id, loglen, nullptr, infolog); - - const char *what_str; - switch(what_to_check) { - case GL_LINK_STATUS: - what_str = "linking"; - break; - case GL_VALIDATE_STATUS: - what_str = "validation"; - break; - case GL_COMPILE_STATUS: - what_str = "compiliation"; - break; - default: - what_str = ""; - break; - } - - auto errormsg = MSG(err); - errormsg << "Program " << what_str << " failed\n" << infolog; - delete[] infolog; - - throw Error(errormsg); - } -} - -void Program::use() { - glUseProgram(this->id); -} - -void Program::stopusing() { - glUseProgram(static_cast(0)); -} - -GLint Program::get_uniform_id(const char *name) { - return glGetUniformLocation(this->id, name); -} - -GLint Program::get_attribute_id(const char *name) { - if (!this->is_linked) [[unlikely]] { - throw Error(MSG(err) << - "Attribute " << name << - " was queried before program was linked!"); - } - - GLint aid = glGetAttribLocation(this->id, name); - - if (aid == -1) [[unlikely]] { - this->dump_active_attributes(); - throw Error(MSG(err) << - "Attribute " << name << " queried but not found or active" - " (pwnt by the compiler)."); - } - - return aid; -} - -void Program::set_attribute_id(const char *name, GLuint id) { - if (!this->is_linked) { - glBindAttribLocation(this->id, id, name); - } - else { - //TODO: maybe enable overwriting, but after that relink the program - throw Error(MSG(err) << "assigned attribute " << name << " = " << id - << " after program was linked!"); - } -} - -void Program::dump_active_attributes() { - auto msg = MSG(warn); - msg << "Dumping shader program active attribute list:"; - - GLint num_attribs; - glGetProgramiv(this->id, GL_ACTIVE_ATTRIBUTES, &num_attribs); - - GLint attrib_max_length; - glGetProgramiv(this->id, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &attrib_max_length); - - for (int i = 0; i < num_attribs; i++) { - GLsizei attrib_length; - GLint attrib_size; - GLenum attrib_type; - char *attrib_name = new char[attrib_max_length]; - glGetActiveAttrib(this->id, i, attrib_max_length, &attrib_length, - &attrib_size, &attrib_type, attrib_name); - - msg << "\n" << - "-> attribute " << attrib_name << ": " - " : type=" << attrib_type << ", size=" << attrib_size; - delete[] attrib_name; - } -} - - -void Program::post_link_hook() { - this->pos_id = this->get_attribute_id("vertex_position"); - this->mvpm_id = this->get_uniform_id("mvp_matrix"); -} - -} // openage::shader diff --git a/libopenage/shader/program.h b/libopenage/shader/program.h deleted file mode 100644 index d2244b5bf3..0000000000 --- a/libopenage/shader/program.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2013-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -namespace openage { -namespace shader { - -class Shader; - -class [[deprecated]] Program { -public: - GLuint id; - GLint pos_id, mvpm_id; - - Program(); - Program(Shader *s0, Shader *s1); - ~Program(); - - void attach_shader(Shader *s); - - void link(); - - void use(); - void stopusing(); - - GLint get_uniform_id(const char *name); - GLint get_attribute_id(const char *name); - - void set_attribute_id(const char *name, GLuint id); - - void dump_active_attributes(); - -private: - bool is_linked; - Shader *vert, *frag, *geom; - - void check(GLenum what_to_check); - GLint get_info(GLenum pname); - char *get_log(); - void post_link_hook(); -}; - - -} // namespace shader -} // namespace openage diff --git a/libopenage/shader/shader.cpp b/libopenage/shader/shader.cpp deleted file mode 100644 index f9a7c555db..0000000000 --- a/libopenage/shader/shader.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2013-2019 the openage authors. See copying.md for legal info. - -#include "shader.h" - -#include -#include - -#include "../error/error.h" -#include "../log/log.h" -#include "../util/file.h" -#include "../util/strings.h" - -namespace openage::shader { - -const char *type_to_string(GLenum type) { - switch (type) { - case GL_VERTEX_SHADER: - return "vertex"; - case GL_FRAGMENT_SHADER: - return "fragment"; - case GL_GEOMETRY_SHADER: - return "geometry"; - default: - return "unknown"; - } -} - -Shader::Shader(GLenum type, std::initializer_list sources) { - //create shader - this->id = glCreateShader(type); - - //store type - this->type = type; - - //load shader source - std::vector x = std::vector(sources); - glShaderSource(this->id, x.size(), x.data(), nullptr); - - //compile shader source - glCompileShader(this->id); - - //check compiliation result - GLint status; - glGetShaderiv(this->id, GL_COMPILE_STATUS, &status); - - if (status != GL_TRUE) { - GLint loglen; - glGetShaderiv(this->id, GL_INFO_LOG_LENGTH, &loglen); - - auto infolog = std::make_unique(loglen); - glGetShaderInfoLog(this->id, loglen, nullptr, infolog.get()); - - auto errmsg = MSG(err); - errmsg << "Failed to compile " << type_to_string(type) << " shader\n" << infolog; - - glDeleteShader(this->id); - - throw Error(errmsg); - } -} - -Shader::~Shader() { - glDeleteShader(this->id); -} - -} // openage::shader diff --git a/libopenage/shader/shader.h b/libopenage/shader/shader.h deleted file mode 100644 index 93e44b6123..0000000000 --- a/libopenage/shader/shader.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2013-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include - -namespace openage { -namespace shader { - -[[deprecated]] const char *type_to_string(GLenum type); - -class [[deprecated]] Shader { -public: - Shader(GLenum type, std::initializer_list sources); - ~Shader(); - - GLuint id; - GLenum type; -}; - -} // namespace shader -} // namespace openage diff --git a/libopenage/unit/selection.cpp b/libopenage/unit/selection.cpp index d8c4fa44f4..48d38ba457 100644 --- a/libopenage/unit/selection.cpp +++ b/libopenage/unit/selection.cpp @@ -8,7 +8,6 @@ #include "../coord/tile.h" #include "../legacy_engine.h" #include "../log/log.h" -#include "../renderer/text.h" #include "../terrain/terrain.h" #include "action.h" #include "command.h" From e5ed4a0a3f1cc20ad690e0b309ca886318e66808 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 23 Sep 2023 19:05:08 +0200 Subject: [PATCH 36/95] refactor: Move OpenGL error checks into renderer. --- libopenage/error/CMakeLists.txt | 1 - libopenage/error/gl_debug.cpp | 70 ------------------- libopenage/error/gl_debug.h | 12 ---- libopenage/renderer/opengl/CMakeLists.txt | 1 + .../opengl.cpp => renderer/opengl/error.cpp} | 20 +++--- .../opengl.h => renderer/opengl/error.h} | 8 +-- libopenage/renderer/opengl/shader_program.cpp | 2 +- libopenage/util/CMakeLists.txt | 1 - 8 files changed, 14 insertions(+), 101 deletions(-) delete mode 100644 libopenage/error/gl_debug.cpp delete mode 100644 libopenage/error/gl_debug.h rename libopenage/{util/opengl.cpp => renderer/opengl/error.cpp} (78%) rename libopenage/{util/opengl.h => renderer/opengl/error.h} (51%) diff --git a/libopenage/error/CMakeLists.txt b/libopenage/error/CMakeLists.txt index 9fefd61a5d..b54fa5e524 100644 --- a/libopenage/error/CMakeLists.txt +++ b/libopenage/error/CMakeLists.txt @@ -2,7 +2,6 @@ add_sources(libopenage backtrace.cpp demo.cpp error.cpp - gl_debug.cpp handlers.cpp stackanalyzer.cpp ) diff --git a/libopenage/error/gl_debug.cpp b/libopenage/error/gl_debug.cpp deleted file mode 100644 index fc89d33d74..0000000000 --- a/libopenage/error/gl_debug.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2016-2023 the openage authors. See copying.md for legal info. - -#include "gl_debug.h" - -#include - -#include "log/message.h" - -#include "error/error.h" - -namespace openage::error { - -namespace { -void APIENTRY callback(GLenum source, GLenum, GLuint, GLenum, GLsizei, const GLchar *message, const void *) { - const char *source_name; - - switch (source) { - case GL_DEBUG_SOURCE_API: - source_name = "API"; - break; - case GL_DEBUG_SOURCE_WINDOW_SYSTEM: - source_name = "window system"; - break; - case GL_DEBUG_SOURCE_SHADER_COMPILER: - source_name = "shader compiler"; - break; - case GL_DEBUG_SOURCE_THIRD_PARTY: - source_name = "third party"; - break; - case GL_DEBUG_SOURCE_APPLICATION: - source_name = "application"; - break; - case GL_DEBUG_SOURCE_OTHER: - source_name = "other"; - break; - default: - source_name = "unknown"; - break; - } - - throw Error(MSG(err) << "OpenGL error from " << source_name << ": '" << message << "'."); -} - -} // namespace - -SDL_GLContext create_debug_context(SDL_Window *window) { - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG); - - auto ctx = SDL_GL_CreateContext(window); - - if (ctx != nullptr) { - GLint flags; - glGetIntegerv(GL_CONTEXT_FLAGS, &flags); - - if (!(flags & GL_CONTEXT_FLAG_DEBUG_BIT)) - throw Error(MSG(err) << "Failed creating a debug OpenGL context."); - - glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_FALSE); - - glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, nullptr, GL_TRUE); - glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, GL_DONT_CARE, 0, nullptr, GL_TRUE); - - glDebugMessageCallback(callback, nullptr); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - } - - return ctx; -} - -} // namespace openage::error diff --git a/libopenage/error/gl_debug.h b/libopenage/error/gl_debug.h deleted file mode 100644 index a874c1086e..0000000000 --- a/libopenage/error/gl_debug.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2016-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -namespace openage { -namespace error { - -SDL_GLContext create_debug_context(SDL_Window *window); - -}} // openage::error diff --git a/libopenage/renderer/opengl/CMakeLists.txt b/libopenage/renderer/opengl/CMakeLists.txt index eb93f1df56..300dac811f 100644 --- a/libopenage/renderer/opengl/CMakeLists.txt +++ b/libopenage/renderer/opengl/CMakeLists.txt @@ -2,6 +2,7 @@ add_sources(libopenage buffer.cpp context.cpp debug.cpp + error.cpp framebuffer.cpp geometry.cpp render_pass.cpp diff --git a/libopenage/util/opengl.cpp b/libopenage/renderer/opengl/error.cpp similarity index 78% rename from libopenage/util/opengl.cpp rename to libopenage/renderer/opengl/error.cpp index 1cc8b31ee3..790847fccc 100644 --- a/libopenage/util/opengl.cpp +++ b/libopenage/renderer/opengl/error.cpp @@ -1,20 +1,18 @@ -// Copyright 2014-2016 the openage authors. See copying.md for legal info. +// Copyright 2014-2023 the openage authors. See copying.md for legal info. -#include "opengl.h" +#include "error.h" #include -#include "../error/error.h" +#include "error/error.h" -namespace openage { -namespace util { +namespace openage::renderer::opengl { void gl_check_error() { int glerrorstate = 0; glerrorstate = glGetError(); if (glerrorstate != GL_NO_ERROR) { - const char *errormsg; //generate error message @@ -63,11 +61,11 @@ void gl_check_error() { // unknown error state errormsg = "unknown error"; } - throw Error(MSG(err) << - "OpenGL error state after running draw method: " << glerrorstate << "\n" - "\t" << errormsg << "\n" - << "Run the game with --gl-debug to get more information: './run game --gl-debug'."); + throw Error(MSG(err) << "OpenGL error state after running draw method: " << glerrorstate << "\n" + "\t" + << errormsg << "\n" + << "Run the game with --gl-debug to get more information: './run game --gl-debug'."); } } -}} // openage::util +} // namespace openage::renderer::opengl diff --git a/libopenage/util/opengl.h b/libopenage/renderer/opengl/error.h similarity index 51% rename from libopenage/util/opengl.h rename to libopenage/renderer/opengl/error.h index d1c3a2e300..5fe692fd2d 100644 --- a/libopenage/util/opengl.h +++ b/libopenage/renderer/opengl/error.h @@ -1,9 +1,8 @@ -// Copyright 2014-2016 the openage authors. See copying.md for legal info. +// Copyright 2014-2023 the openage authors. See copying.md for legal info. #pragma once -namespace openage { -namespace util { +namespace openage::renderer::opengl { /** * query the current opengl context for any errors. @@ -12,5 +11,4 @@ namespace util { */ void gl_check_error(); -} -} +} // namespace openage::renderer::opengl diff --git a/libopenage/renderer/opengl/shader_program.cpp b/libopenage/renderer/opengl/shader_program.cpp index 67127ecc1f..3ccd49ce80 100644 --- a/libopenage/renderer/opengl/shader_program.cpp +++ b/libopenage/renderer/opengl/shader_program.cpp @@ -9,9 +9,9 @@ #include "datastructure/constexpr_map.h" #include "error/error.h" #include "log/log.h" -#include "util/opengl.h" #include "renderer/opengl/context.h" +#include "renderer/opengl/error.h" #include "renderer/opengl/geometry.h" #include "renderer/opengl/lookup.h" #include "renderer/opengl/shader.h" diff --git a/libopenage/util/CMakeLists.txt b/libopenage/util/CMakeLists.txt index ac5b585f06..841a00757f 100644 --- a/libopenage/util/CMakeLists.txt +++ b/libopenage/util/CMakeLists.txt @@ -20,7 +20,6 @@ add_sources(libopenage matrix_test.cpp misc.cpp misc_test.cpp - opengl.cpp os.cpp path.cpp profiler.cpp From 485cfde752449df899e7f690bf5bf583c1375b79 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 23 Sep 2023 19:10:45 +0200 Subject: [PATCH 37/95] refactor: Move old screenshot manager into renderer. --- libopenage/CMakeLists.txt | 1 - .../renderer/stages/screen/CMakeLists.txt | 1 + .../stages/screen}/screenshot.cpp | 38 +++++++++---------- .../{ => renderer/stages/screen}/screenshot.h | 3 ++ 4 files changed, 22 insertions(+), 21 deletions(-) rename libopenage/{ => renderer/stages/screen}/screenshot.cpp (74%) rename libopenage/{ => renderer/stages/screen}/screenshot.h (95%) diff --git a/libopenage/CMakeLists.txt b/libopenage/CMakeLists.txt index af67e9e4ee..8b7d535b96 100644 --- a/libopenage/CMakeLists.txt +++ b/libopenage/CMakeLists.txt @@ -325,7 +325,6 @@ add_sources(libopenage legacy_engine.cpp main.cpp options.cpp - screenshot.cpp ${CMAKE_CURRENT_BINARY_DIR}/config.cpp ${CMAKE_CURRENT_BINARY_DIR}/version.cpp ${CODEGEN_SCU_FILE} diff --git a/libopenage/renderer/stages/screen/CMakeLists.txt b/libopenage/renderer/stages/screen/CMakeLists.txt index b964aae19b..59529a556b 100644 --- a/libopenage/renderer/stages/screen/CMakeLists.txt +++ b/libopenage/renderer/stages/screen/CMakeLists.txt @@ -1,3 +1,4 @@ add_sources(libopenage screen_renderer.cpp + screenshot.cpp ) diff --git a/libopenage/screenshot.cpp b/libopenage/renderer/stages/screen/screenshot.cpp similarity index 74% rename from libopenage/screenshot.cpp rename to libopenage/renderer/stages/screen/screenshot.cpp index dfb3d2d5e1..73b4230106 100644 --- a/libopenage/screenshot.cpp +++ b/libopenage/renderer/stages/screen/screenshot.cpp @@ -16,11 +16,10 @@ #include "log/log.h" #include "util/strings.h" -namespace openage { +namespace openage::renderer::screen { -ScreenshotManager::ScreenshotManager(job::JobManager *job_mgr) - : +ScreenshotManager::ScreenshotManager(job::JobManager *job_mgr) : count{0}, job_manager{job_mgr} { } @@ -30,12 +29,12 @@ ScreenshotManager::~ScreenshotManager() {} std::string ScreenshotManager::gen_next_filename() { - std::time_t t = std::time(NULL); if (t == this->last_time) { this->count++; - } else { + } + else { this->count = 0; this->last_time = t; } @@ -50,12 +49,12 @@ std::string ScreenshotManager::gen_next_filename() { void ScreenshotManager::save_screenshot(coord::viewport_delta size) { coord::pixel_t width = size.x, - height = size.y; + height = size.y; - std::shared_ptr pxdata(new uint8_t[4*width*height], std::default_delete()); + std::shared_ptr pxdata(new uint8_t[4 * width * height], std::default_delete()); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pxdata.get()); - auto encode_function = [this, pxdata, size] () { + auto encode_function = [this, pxdata, size]() { return this->encode_png(pxdata, size); }; this->job_manager->enqueue(encode_function); @@ -66,24 +65,25 @@ bool ScreenshotManager::encode_png(std::shared_ptr pxdata, coord::viewport_delta size) { std::FILE *fout = NULL; coord::pixel_t width = size.x, - height = size.y; - auto warn_fn = [] (png_structp /*png_ptr*/, png_const_charp message) { + height = size.y; + auto warn_fn = [](png_structp /*png_ptr*/, png_const_charp message) { log::log(MSG(err) << "Creating screenshot failed: libpng error: " << message); }; - auto err_fn = [] (png_structp png_ptr, png_const_charp message) { + auto err_fn = [](png_structp png_ptr, png_const_charp message) { log::log(MSG(err) << "Creating screenshot failed: libpng error: " << message); longjmp(png_jmpbuf(png_ptr), 1); }; png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, - (png_voidp) NULL, - err_fn, warn_fn); + (png_voidp)NULL, + err_fn, + warn_fn); if (!png_ptr) return false; png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { - png_destroy_write_struct(&png_ptr, (png_infopp) NULL); + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); return false; } @@ -97,16 +97,14 @@ bool ScreenshotManager::encode_png(std::shared_ptr pxdata, fout = std::fopen(filename.c_str(), "wb"); if (fout == NULL) { png_destroy_write_struct(&png_ptr, &info_ptr); - log::log(MSG(err) << "Could not open '"<< filename << "': " - << std::string(strerror(errno))); + log::log(MSG(err) << "Could not open '" << filename << "': " + << std::string(strerror(errno))); return false; } png_init_io(png_ptr, fout); - png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); + png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); // Put image row pointer into info_ptr so that we can use the high-level // write interface. @@ -129,4 +127,4 @@ bool ScreenshotManager::encode_png(std::shared_ptr pxdata, return true; } -} // openage +} // namespace openage::renderer::screen diff --git a/libopenage/screenshot.h b/libopenage/renderer/stages/screen/screenshot.h similarity index 95% rename from libopenage/screenshot.h rename to libopenage/renderer/stages/screen/screenshot.h index 45e2660f5b..ce330c553f 100644 --- a/libopenage/screenshot.h +++ b/libopenage/renderer/stages/screen/screenshot.h @@ -14,6 +14,8 @@ namespace job { class JobManager; } +namespace renderer::screen { + /** * Takes screenshots, duh. * @@ -52,4 +54,5 @@ class [[deprecated]] ScreenshotManager { job::JobManager *job_manager; }; +} // namespace renderer::screen } // namespace openage From 986b3e001af1efaa88b5da6d6319efeac49b9e0e Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 23 Sep 2023 22:15:41 +0200 Subject: [PATCH 38/95] renderer: Rewrite screenshot manager for new renderer. --- libopenage/renderer/opengl/render_target.cpp | 13 +++ libopenage/renderer/opengl/render_target.h | 7 ++ libopenage/renderer/renderer.h | 9 ++ .../renderer/stages/screen/screenshot.cpp | 103 ++++-------------- .../renderer/stages/screen/screenshot.h | 64 +++++++---- 5 files changed, 92 insertions(+), 104 deletions(-) diff --git a/libopenage/renderer/opengl/render_target.cpp b/libopenage/renderer/opengl/render_target.cpp index c0da3a22a8..ba0505adba 100644 --- a/libopenage/renderer/opengl/render_target.cpp +++ b/libopenage/renderer/opengl/render_target.cpp @@ -22,6 +22,19 @@ GlRenderTarget::GlRenderTarget(const std::shared_ptr &context, this->size = this->textures.value().at(0)->get_info().get_size(); } +resources::Texture2dData GlRenderTarget::into_data() { + // make sure the framebuffer is bound + this->bind_read(); + + std::vector pxdata(this->size.first * this->size.second * 4); + glReadPixels(0, 0, this->size.first, this->size.second, GL_RGBA, GL_UNSIGNED_BYTE, pxdata.data()); + + resources::Texture2dInfo info{this->size.first, + this->size.second, + resources::pixel_format::rgba8}; + return resources::Texture2dData{info, std::move(pxdata)}; +} + std::vector> GlRenderTarget::get_texture_targets() { std::vector> textures{}; if (this->framebuffer->get_type() == gl_framebuffer_t::display) { diff --git a/libopenage/renderer/opengl/render_target.h b/libopenage/renderer/opengl/render_target.h index 5246b03cb7..acf0c0af00 100644 --- a/libopenage/renderer/opengl/render_target.h +++ b/libopenage/renderer/opengl/render_target.h @@ -56,6 +56,13 @@ class GlRenderTarget final : public RenderTarget { GlRenderTarget(const std::shared_ptr &context, std::vector> const &textures); + /** + * Get the pixels stored in the render target's buffer. + * + * @return Texture data with the image contents of the buffer. + */ + resources::Texture2dData into_data() override; + /** * Get the targeted textures. * diff --git a/libopenage/renderer/renderer.h b/libopenage/renderer/renderer.h index 8dec3dec2f..8f6e4ed3b9 100644 --- a/libopenage/renderer/renderer.h +++ b/libopenage/renderer/renderer.h @@ -34,6 +34,15 @@ class RenderTarget : public std::enable_shared_from_this { public: virtual ~RenderTarget() = default; + /** + * Get an image from the pixels in the render target's framebuffer. + * + * This should only be called _after_ rendering to the framebuffer has finished. + * + * @return RGBA texture data. + */ + virtual resources::Texture2dData into_data() = 0; + virtual std::vector> get_texture_targets() = 0; }; diff --git a/libopenage/renderer/stages/screen/screenshot.cpp b/libopenage/renderer/stages/screen/screenshot.cpp index 73b4230106..8fad08cab9 100644 --- a/libopenage/renderer/stages/screen/screenshot.cpp +++ b/libopenage/renderer/stages/screen/screenshot.cpp @@ -11,23 +11,27 @@ #include #include -#include "coord/pixel.h" #include "job/job_manager.h" #include "log/log.h" +#include "renderer/renderer.h" +#include "renderer/resources/texture_data.h" +#include "renderer/stages/screen/screen_renderer.h" #include "util/strings.h" + namespace openage::renderer::screen { -ScreenshotManager::ScreenshotManager(job::JobManager *job_mgr) : +ScreenshotManager::ScreenshotManager(std::shared_ptr &renderer, + util::Path &outdir, + std::shared_ptr &job_mgr) : + outdir{outdir}, count{0}, + last_time{0}, + renderer{renderer}, job_manager{job_mgr} { } - -ScreenshotManager::~ScreenshotManager() {} - - std::string ScreenshotManager::gen_next_filename() { std::time_t t = std::time(NULL); @@ -43,88 +47,21 @@ std::string ScreenshotManager::gen_next_filename() { char timestamp[32]; std::strftime(timestamp, 32, "%Y-%m-%d_%H-%M-%S", std::localtime(&t)); - return util::sformat("/tmp/openage_%s_%02d.png", timestamp, this->count); + return util::sformat("openage_%s_%02d.png", timestamp, this->count); } -void ScreenshotManager::save_screenshot(coord::viewport_delta size) { - coord::pixel_t width = size.x, - height = size.y; +void ScreenshotManager::save_screenshot() { + // get screenshot image from scren renderer + auto pass = this->renderer->get_render_pass(); + auto target = pass->get_target(); + auto image = target->into_data(); - std::shared_ptr pxdata(new uint8_t[4 * width * height], std::default_delete()); - glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pxdata.get()); - - auto encode_function = [this, pxdata, size]() { - return this->encode_png(pxdata, size); + auto store_function = [this, image]() { + image.store(this->outdir / this->gen_next_filename()); + return true; }; - this->job_manager->enqueue(encode_function); -} - - -bool ScreenshotManager::encode_png(std::shared_ptr pxdata, - coord::viewport_delta size) { - std::FILE *fout = NULL; - coord::pixel_t width = size.x, - height = size.y; - auto warn_fn = [](png_structp /*png_ptr*/, png_const_charp message) { - log::log(MSG(err) << "Creating screenshot failed: libpng error: " << message); - }; - auto err_fn = [](png_structp png_ptr, png_const_charp message) { - log::log(MSG(err) << "Creating screenshot failed: libpng error: " << message); - longjmp(png_jmpbuf(png_ptr), 1); - }; - - png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, - (png_voidp)NULL, - err_fn, - warn_fn); - if (!png_ptr) - return false; - - png_infop info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - return false; - } - - if (setjmp(png_jmpbuf(png_ptr))) { - std::fclose(fout); - png_destroy_write_struct(&png_ptr, &info_ptr); - return false; - } - - std::string filename = this->gen_next_filename(); - fout = std::fopen(filename.c_str(), "wb"); - if (fout == NULL) { - png_destroy_write_struct(&png_ptr, &info_ptr); - log::log(MSG(err) << "Could not open '" << filename << "': " - << std::string(strerror(errno))); - return false; - } - - png_init_io(png_ptr, fout); - - png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); - - // Put image row pointer into info_ptr so that we can use the high-level - // write interface. - std::vector row_ptrs; - - // Invert rows. - row_ptrs.reserve(height); - for (int i = 1; i <= height; i++) { - row_ptrs.push_back(pxdata.get() + (height - i) * 4 * width); - } - png_set_rows(png_ptr, info_ptr, &row_ptrs[0]); - - //TODO: print ingame message. - log::log(MSG(info) << "Saving screenshot to '" << filename << "'."); - - png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_FILLER_AFTER, NULL); - - std::fclose(fout); - png_destroy_write_struct(&png_ptr, &info_ptr); - return true; + this->job_manager->enqueue(store_function); } } // namespace openage::renderer::screen diff --git a/libopenage/renderer/stages/screen/screenshot.h b/libopenage/renderer/stages/screen/screenshot.h index ce330c553f..df4ebcee48 100644 --- a/libopenage/renderer/stages/screen/screenshot.h +++ b/libopenage/renderer/stages/screen/screenshot.h @@ -6,7 +6,8 @@ #include #include -#include "coord/pixel.h" +#include "util/path.h" + namespace openage { @@ -15,43 +16,64 @@ class JobManager; } namespace renderer::screen { +class ScreenRenderer; /** * Takes screenshots, duh. - * - * TODO: move into renderer! */ -class [[deprecated]] ScreenshotManager { +class ScreenshotManager { public: /** - * Initializes the screenshot manager with the given job manager. + * Create a new screenshot manager. + * + * @param renderer Screen render stage to take the screenshot from. + * @param outdir Directory where the screenshots are saved. + * @param job_mgr Job manager to use for writing the screenshot to disk. */ - ScreenshotManager(job::JobManager *job_mgr); - - ~ScreenshotManager(); - - /** To be called to save a screenshot. */ - void save_screenshot(coord::viewport_delta size); + ScreenshotManager(std::shared_ptr &renderer, + util::Path &outdir, + std::shared_ptr &job_mgr); - /** To be called by the job manager. Returns true on success, false otherwise. */ - bool encode_png(std::shared_ptr pxdata, - coord::viewport_delta size); + ~ScreenshotManager() = default; - /** size of the game window, in coord_sdl */ - coord::viewport_delta window_size; + /** + * Generate and save a screenshot of the last frame. + */ + void save_screenshot(); private: - /** to be called to get the next screenshot filename into the array */ + /** + * Generates a filename for the screenshot. + * + * @return Filename for the screenshot. + */ std::string gen_next_filename(); - /** contains the number to be in the next screenshot filename */ + /** + * Directory where the screenshots are saved. + */ + util::Path outdir; + + /** + * Counter for the screenshot filename. Used if multiple screenshots + * are taken in the same second. + */ unsigned count; - /** contains the last time when a screenshot was taken */ + /** + * Last time when a screenshot was taken. + */ std::time_t last_time; - /** the job manager this screenshot manager uses */ - job::JobManager *job_manager; + /** + * Screen render stage to take the screenshot from. + */ + std::shared_ptr renderer; + + /** + * Job manager to use for writing the screenshot to disk. + */ + std::shared_ptr job_manager; }; } // namespace renderer::screen From 99078f3431433a52fa123dae58dec3a0d5d87480 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 23 Sep 2023 23:00:05 +0200 Subject: [PATCH 39/95] engine: Remove legacy engine integration. --- libopenage/CMakeLists.txt | 2 - libopenage/audio/audio_manager.h | 2 - libopenage/audio/dynamic_resource.cpp | 1 - libopenage/audio/resource.cpp | 2 - libopenage/console/console.cpp | 1 - libopenage/console/console.h | 2 - libopenage/console/draw.h | 2 - libopenage/gamestate/old/game_main.cpp | 29 -- libopenage/gamestate/old/game_main.h | 8 - libopenage/gamestate/old/game_spec.cpp | 1 - libopenage/gui/CMakeLists.txt | 4 - libopenage/gui/engine_info.cpp | 14 - libopenage/gui/engine_info.h | 39 -- libopenage/gui/engine_link.cpp | 95 ----- libopenage/gui/engine_link.h | 76 ---- libopenage/gui/game_creator.cpp | 40 +- libopenage/gui/game_creator.h | 3 - libopenage/gui/game_main_link.cpp | 73 ---- libopenage/gui/game_main_link.h | 74 ---- libopenage/gui/game_saver.cpp | 47 +-- libopenage/gui/game_saver.h | 11 +- libopenage/gui/gui.cpp | 7 +- libopenage/gui/main_args_link.cpp | 38 -- libopenage/gui/main_args_link.h | 36 -- libopenage/legacy_engine.cpp | 77 ---- libopenage/legacy_engine.h | 209 ---------- .../renderer/stages/screen/screenshot.cpp | 2 +- libopenage/terrain/terrain.cpp | 1 - libopenage/terrain/terrain.h | 1 - libopenage/terrain/terrain_chunk.cpp | 1 - libopenage/terrain/terrain_object.cpp | 2 - libopenage/terrain/terrain_object.h | 6 - libopenage/unit/action.cpp | 8 - libopenage/unit/action.h | 7 - libopenage/unit/producer.cpp | 1 - libopenage/unit/selection.cpp | 6 +- libopenage/unit/selection.h | 6 +- libopenage/unit/unit.cpp | 1 - libopenage/util/profiler.cpp | 375 +++++++++--------- libopenage/util/profiler.h | 179 ++++----- 40 files changed, 301 insertions(+), 1188 deletions(-) delete mode 100644 libopenage/gui/engine_info.cpp delete mode 100644 libopenage/gui/engine_info.h delete mode 100644 libopenage/gui/engine_link.cpp delete mode 100644 libopenage/gui/engine_link.h delete mode 100644 libopenage/gui/game_main_link.cpp delete mode 100644 libopenage/gui/game_main_link.h delete mode 100644 libopenage/gui/main_args_link.cpp delete mode 100644 libopenage/gui/main_args_link.h delete mode 100644 libopenage/legacy_engine.cpp delete mode 100644 libopenage/legacy_engine.h diff --git a/libopenage/CMakeLists.txt b/libopenage/CMakeLists.txt index 8b7d535b96..9dc9db84d9 100644 --- a/libopenage/CMakeLists.txt +++ b/libopenage/CMakeLists.txt @@ -322,7 +322,6 @@ get_codegen_scu_file() # are specified above the source file list. add_sources(libopenage - legacy_engine.cpp main.cpp options.cpp ${CMAKE_CURRENT_BINARY_DIR}/config.cpp @@ -331,7 +330,6 @@ add_sources(libopenage ) pxdgen( - legacy_engine.h main.h ) diff --git a/libopenage/audio/audio_manager.h b/libopenage/audio/audio_manager.h index d97197b5b5..af14d5ebb2 100644 --- a/libopenage/audio/audio_manager.h +++ b/libopenage/audio/audio_manager.h @@ -17,8 +17,6 @@ namespace openage { -class LegacyEngine; - namespace job { class JobManager; } diff --git a/libopenage/audio/dynamic_resource.cpp b/libopenage/audio/dynamic_resource.cpp index bb2347c07b..97aac8df37 100644 --- a/libopenage/audio/dynamic_resource.cpp +++ b/libopenage/audio/dynamic_resource.cpp @@ -4,7 +4,6 @@ #include "../job/job_manager.h" -#include "../legacy_engine.h" #include "../log/log.h" #include "audio_manager.h" diff --git a/libopenage/audio/resource.cpp b/libopenage/audio/resource.cpp index b5b3a3af55..66efcf52c2 100644 --- a/libopenage/audio/resource.cpp +++ b/libopenage/audio/resource.cpp @@ -3,7 +3,6 @@ #include "resource.h" #include "../error/error.h" -#include "../legacy_engine.h" #include "dynamic_resource.h" #include "in_memory_resource.h" @@ -30,7 +29,6 @@ int Resource::get_id() const { std::shared_ptr Resource::create_resource(AudioManager *manager, const resource_def &def) { - if (not def.location.is_file()) [[unlikely]] { throw Error{ERR << "sound file does not exist: " << def.location}; } diff --git a/libopenage/console/console.cpp b/libopenage/console/console.cpp index c28b6bab06..20e414e13d 100644 --- a/libopenage/console/console.cpp +++ b/libopenage/console/console.cpp @@ -3,7 +3,6 @@ #include "console.h" #include "../error/error.h" -#include "../legacy_engine.h" #include "../log/log.h" #include "../util/strings.h" #include "../util/unicode.h" diff --git a/libopenage/console/console.h b/libopenage/console/console.h index a06b9e6760..6994c4cbe9 100644 --- a/libopenage/console/console.h +++ b/libopenage/console/console.h @@ -13,8 +13,6 @@ namespace openage { -class LegacyEngine; - /** * In-game console subsystem. Featuring a full terminal emulator. * diff --git a/libopenage/console/draw.h b/libopenage/console/draw.h index a359556fb4..13634ea5b4 100644 --- a/libopenage/console/draw.h +++ b/libopenage/console/draw.h @@ -5,8 +5,6 @@ namespace openage { -class LegacyEngine; - namespace util { class FD; } // namespace util diff --git a/libopenage/gamestate/old/game_main.cpp b/libopenage/gamestate/old/game_main.cpp index 0fd3624f47..5d928e548a 100644 --- a/libopenage/gamestate/old/game_main.cpp +++ b/libopenage/gamestate/old/game_main.cpp @@ -2,7 +2,6 @@ #include "game_main.h" -#include "../../legacy_engine.h" #include "../../log/log.h" #include "../../terrain/terrain.h" #include "../../unit/unit_type.h" @@ -69,37 +68,9 @@ Civilisation *GameMain::add_civ(int civ_id) { GameMainHandle::GameMainHandle(qtsdl::GuiItemLink *gui_link) : game{}, - engine{}, gui_link{gui_link} { } -void GameMainHandle::set_engine(LegacyEngine *engine) { - ENSURE(!this->engine || this->engine == engine, "relinking GameMain to another engine is not supported and not caught properly"); - this->engine = engine; -} - -void GameMainHandle::clear() { - if (this->engine) { - this->game = nullptr; - // this->display->end_game(); - announce_running(); - } -} - -void GameMainHandle::set_game(std::unique_ptr &&game) { - if (this->engine) { - ENSURE(game, "linking game to engine problem"); - - // remember the pointer - this->game = game.get(); - - // then pass on the game to the engine - // this->display->start_game(std::move(game)); - - announce_running(); - } -} - GameMain *GameMainHandle::get_game() const { return this->game; } diff --git a/libopenage/gamestate/old/game_main.h b/libopenage/gamestate/old/game_main.h index a7318f25dc..af3651aadc 100644 --- a/libopenage/gamestate/old/game_main.h +++ b/libopenage/gamestate/old/game_main.h @@ -18,7 +18,6 @@ namespace openage { -class LegacyEngine; class Generator; class Terrain; @@ -130,8 +129,6 @@ class GameMainHandle { public: explicit GameMainHandle(qtsdl::GuiItemLink *gui_link); - void set_engine(LegacyEngine *engine); - /** * End the game and delete the game handle. */ @@ -164,11 +161,6 @@ class GameMainHandle { */ GameMain *game; - /** - * The engine the main game handle is attached to. - */ - LegacyEngine *engine; - public: GameMainSignals gui_signals; qtsdl::GuiItemLink *gui_link; diff --git a/libopenage/gamestate/old/game_spec.cpp b/libopenage/gamestate/old/game_spec.cpp index ca06c6b7e3..c23ddcd0bd 100644 --- a/libopenage/gamestate/old/game_spec.cpp +++ b/libopenage/gamestate/old/game_spec.cpp @@ -9,7 +9,6 @@ #include "../../gamedata/blending_mode_dummy.h" #include "../../gamedata/string_resource_dummy.h" #include "../../gamedata/terrain_dummy.h" -#include "../../legacy_engine.h" #include "../../log/log.h" #include "../../rng/global_rng.h" #include "../../unit/producer.h" diff --git a/libopenage/gui/CMakeLists.txt b/libopenage/gui/CMakeLists.txt index a1dd56541b..749136617c 100644 --- a/libopenage/gui/CMakeLists.txt +++ b/libopenage/gui/CMakeLists.txt @@ -1,15 +1,11 @@ add_sources(libopenage actions_list_model.cpp category_contents_list_model.cpp - engine_info.cpp - engine_link.cpp game_creator.cpp - game_main_link.cpp game_saver.cpp game_spec_link.cpp generator_link.cpp gui.cpp - main_args_link.cpp registrations.cpp resources_list_model.cpp ) diff --git a/libopenage/gui/engine_info.cpp b/libopenage/gui/engine_info.cpp deleted file mode 100644 index fad4eef3d3..0000000000 --- a/libopenage/gui/engine_info.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2017-2023 the openage authors. See copying.md for legal info. - -#include "engine_info.h" - -namespace openage { -namespace gui { - -EngineQMLInfo::EngineQMLInfo(LegacyEngine *engine, - const util::Path &asset_dir) : - engine{engine}, - asset_dir{asset_dir} {} - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/engine_info.h b/libopenage/gui/engine_info.h deleted file mode 100644 index 999360ac2a..0000000000 --- a/libopenage/gui/engine_info.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2017-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include "../util/path.h" -#include "guisys/public/gui_singleton_items_info.h" - -namespace openage { -class LegacyEngine; - -namespace gui { - -/** - * This container is attached to the QML engine. - * - * It allows that one can access the members in the qml engine context then. - * That also means the members accessible during creation of any singleton QML item. - * - * This struct is used to link the openage Engine with QML in engine_link.cpp. - */ -class EngineQMLInfo : public qtsdl::GuiSingletonItemsInfo { -public: - EngineQMLInfo(LegacyEngine *engine, const util::Path &asset_dir); - - /** - * The openage engine, so it can be "used" in QML as a "QML Singleton". - * With this pointer, all of QML can find back to the engine. - */ - LegacyEngine *engine; - - /** - * Search path for finding assets n stuff. - */ - util::Path asset_dir; -}; - - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/engine_link.cpp b/libopenage/gui/engine_link.cpp deleted file mode 100644 index f98ca82ea4..0000000000 --- a/libopenage/gui/engine_link.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "engine_link.h" - -#include - -#include "../error/error.h" - -#include "../legacy_engine.h" - -#include "guisys/link/qml_engine_with_singleton_items_info.h" -#include "guisys/link/qtsdl_checked_static_cast.h" - -namespace openage::gui { - -namespace { -// this pushes the EngineLink in the QML engine. -// a qml engine calls the static provider() to obtain a handle. -const int registration = qmlRegisterSingletonType("yay.sfttech.openage", 1, 0, "LegacyEngine", &EngineLink::provider); -} // namespace - - -EngineLink::EngineLink(QObject *parent, LegacyEngine *engine) : - GuiSingletonItem{parent}, - core{engine} { - Q_UNUSED(registration); - - ENSURE(!unwrap(this)->gui_link, "Sharing singletons between QML engines is not supported for now."); - - // when the engine announces that the global key bindings - // changed, update the display. - QObject::connect( - &unwrap(this)->gui_signals, - &EngineSignals::global_binds_changed, - this, - &EngineLink::on_global_binds_changed); - - // trigger the engine signal, - // which then triggers this->on_global_binds_changed. - // unwrap(this)->announce_global_binds(); -} - -EngineLink::~EngineLink() { - unwrap(this)->gui_link = nullptr; -} - -// a qml engine requests a handle to the engine link with that static -// method we do this by extracting the per-qmlengine singleton from the -// engine (the qmlenginewithsingletoninfo), then just return the new link -// instance -QObject *EngineLink::provider(QQmlEngine *engine, QJSEngine *) { - // cast the engine to our specialization - qtsdl::QmlEngineWithSingletonItemsInfo *engine_with_singleton_items_info = qtsdl::checked_static_cast(engine); - - // get the singleton container out of the custom qml engine - auto info = static_cast( - engine_with_singleton_items_info->get_singleton_items_info()); - ENSURE(info, "qml-globals were lost or not passed to the gui subsystem"); - - // owned by the QML engine - // this handle contains the pointer to the openage engine, - // obtained through the qmlengine - return new EngineLink{nullptr, info->engine}; -} - -QStringList EngineLink::get_global_binds() const { - return this->global_binds; -} - -void EngineLink::stop() { - this->core->stop(); -} - -void EngineLink::on_global_binds_changed(const std::vector &global_binds) { - QStringList new_global_binds; - - // create the qstring list from the std string list - // which is then displayed in the ui - std::transform( - std::begin(global_binds), - std::end(global_binds), - std::back_inserter(new_global_binds), - [](const std::string &s) { - return QString::fromStdString(s); - }); - - new_global_binds.sort(); - - if (this->global_binds != new_global_binds) { - this->global_binds = new_global_binds; - emit this->global_binds_changed(); - } -} - -} // namespace openage::gui diff --git a/libopenage/gui/engine_link.h b/libopenage/gui/engine_link.h deleted file mode 100644 index dcd587035a..0000000000 --- a/libopenage/gui/engine_link.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "../util/path.h" -#include "guisys/link/gui_singleton_item.h" - -QT_FORWARD_DECLARE_CLASS(QQmlEngine) -QT_FORWARD_DECLARE_CLASS(QJSEngine) - -namespace openage { -class LegacyEngine; - -namespace gui { -class EngineLink; -} // namespace gui -} // namespace openage - -namespace qtsdl { -template <> -struct Wrap { - using Type = openage::gui::EngineLink; -}; - -template <> -struct Unwrap { - using Type = openage::LegacyEngine; -}; - -} // namespace qtsdl - -namespace openage { -namespace gui { - -class EngineLink : public qtsdl::GuiSingletonItem { - Q_OBJECT - - /** - * The text list of global key bindings. - * displayed so one can see what keys are active. - */ - Q_PROPERTY(QStringList globalBinds - READ get_global_binds - NOTIFY global_binds_changed) - -public: - explicit EngineLink(QObject *parent, LegacyEngine *engine); - virtual ~EngineLink(); - - static QObject *provider(QQmlEngine *, QJSEngine *); - - template - U *get() const { - return core; - } - - QStringList get_global_binds() const; - - Q_INVOKABLE void stop(); - -signals: - void global_binds_changed(); - -private slots: - void on_global_binds_changed(const std::vector &global_binds); - -private: - LegacyEngine *core; - - QStringList global_binds; -}; - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/game_creator.cpp b/libopenage/gui/game_creator.cpp index f187ab5ef2..392efe6139 100644 --- a/libopenage/gui/game_creator.cpp +++ b/libopenage/gui/game_creator.cpp @@ -1,4 +1,4 @@ -// Copyright 2015-2021 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include "game_creator.h" @@ -8,7 +8,6 @@ #include "../gamestate/old/game_spec.h" #include "../gamestate/old/generator.h" -#include "game_main_link.h" #include "game_spec_link.h" #include "generator_link.h" @@ -18,11 +17,8 @@ namespace { const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "GameCreator"); } -GameCreator::GameCreator(QObject *parent) - : +GameCreator::GameCreator(QObject *parent) : QObject{parent}, - game{}, - game_spec{}, generator_parameters{} { Q_UNUSED(registration); } @@ -34,11 +30,10 @@ QString GameCreator::get_error_string() const { } void GameCreator::activate() { - static auto f = [] (GameMainHandle *game, - GameSpecHandle *game_spec, - Generator *generator, - std::shared_ptr callback) { - + static auto f = [](GameMainHandle *game, + GameSpecHandle *game_spec, + Generator *generator, + std::shared_ptr callback) { QString error_msg; if (game->is_game_running()) { @@ -60,27 +55,6 @@ void GameCreator::activate() { emit callback->error_message(error_msg); }; - - if (this->game && this->game_spec && this->generator_parameters) { - std::shared_ptr callback = std::make_shared(); - - QObject::connect(callback.get(), &GameCreatorSignals::error_message, this, &GameCreator::on_processed); - - this->game->i(f, this->game_spec, this->generator_parameters, callback); - } else { - this->on_processed([this] { - if (!this->game) - return "provide 'game' before loading"; - if (!this->game_spec) - return "provide 'gameSpec' before loading"; - if (!this->generator_parameters) - return "provide 'generatorParameters' before loading"; - else - ENSURE(false, "unhandled case for refusal to create a game"); - - return "unknown error"; - }()); - } } void GameCreator::clearErrors() { @@ -93,4 +67,4 @@ void GameCreator::on_processed(const QString &error_string) { emit this->error_string_changed(); } -} // namespace openage::gui +} // namespace openage::gui diff --git a/libopenage/gui/game_creator.h b/libopenage/gui/game_creator.h index b3efb1ff4c..c1899971d0 100644 --- a/libopenage/gui/game_creator.h +++ b/libopenage/gui/game_creator.h @@ -16,10 +16,8 @@ class GameCreator : public QObject { Q_ENUMS(State) Q_PROPERTY(QString errorString READ get_error_string NOTIFY error_string_changed) - Q_MOC_INCLUDE("gui/game_main_link.h") Q_MOC_INCLUDE("gui/game_spec_link.h") Q_MOC_INCLUDE("gui/generator_link.h") - Q_PROPERTY(openage::gui::GameMainLink *game MEMBER game NOTIFY game_changed) Q_PROPERTY(openage::gui::GameSpecLink *gameSpec MEMBER game_spec NOTIFY game_spec_changed) Q_PROPERTY(openage::gui::GeneratorLink *generatorParameters MEMBER generator_parameters NOTIFY generator_parameters_changed) @@ -43,7 +41,6 @@ public slots: private: QString error_string; - GameMainLink *game; GameSpecLink *game_spec; GeneratorLink *generator_parameters; }; diff --git a/libopenage/gui/game_main_link.cpp b/libopenage/gui/game_main_link.cpp deleted file mode 100644 index 35b4af4c65..0000000000 --- a/libopenage/gui/game_main_link.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "game_main_link.h" - -#include - -#include "../legacy_engine.h" -#include "engine_link.h" - -namespace openage::gui { - -namespace { -const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "GameMain"); -} - -GameMainLink::GameMainLink(QObject *parent) : - GuiItemQObject{parent}, - QQmlParserStatus{}, - GuiItem{this}, - state{}, - active{}, - engine{} { - Q_UNUSED(registration); -} - -GameMainLink::~GameMainLink() = default; - -void GameMainLink::classBegin() { -} - -void GameMainLink::on_core_adopted() { - QObject::connect(&unwrap(this)->gui_signals, &GameMainSignals::game_running, this, &GameMainLink::on_game_running); -} - -void GameMainLink::componentComplete() { - static auto f = [](GameMainHandle *_this) { - _this->announce_running(); - }; - this->i(f); -} - -GameMainLink::State GameMainLink::get_state() const { - return this->state; -} - -EngineLink *GameMainLink::get_engine() const { - return this->engine; -} - -void GameMainLink::set_engine(EngineLink *engine) { - static auto f = [](GameMainHandle *_this, LegacyEngine *engine) { - _this->set_engine(engine); - }; - this->s(f, this->engine, engine); -} - -void GameMainLink::clear() { - static auto f = [](GameMainHandle *_this) { - _this->clear(); - }; - this->i(f); -} - -void GameMainLink::on_game_running(bool running) { - auto state = running ? State::Running : State::Null; - - if (this->state != state) { - this->state = state; - emit this->state_changed(); - } -} - -} // namespace openage::gui diff --git a/libopenage/gui/game_main_link.h b/libopenage/gui/game_main_link.h deleted file mode 100644 index 0277cab6b8..0000000000 --- a/libopenage/gui/game_main_link.h +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2015-2018 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "guisys/link/gui_item.h" - -#include "../gamestate/old/game_main.h" - -namespace openage { -namespace gui { - -class EngineLink; -class GameMainLink; - -}} // namespace openage::gui - -namespace qtsdl { -template<> -struct Wrap { - using Type = openage::gui::GameMainLink; -}; - -template<> -struct Unwrap { - using Type = openage::GameMainHandle; -}; - -} // namespace qtsdl - -namespace openage { -namespace gui { - -class GameMainLink : public qtsdl::GuiItemQObject, public QQmlParserStatus, public qtsdl::GuiItem { - Q_OBJECT - - Q_INTERFACES(QQmlParserStatus) - Q_ENUMS(State) - Q_PROPERTY(State state READ get_state NOTIFY state_changed) - Q_PROPERTY(openage::gui::EngineLink* engine READ get_engine WRITE set_engine) - -public: - explicit GameMainLink(QObject *parent=nullptr); - virtual ~GameMainLink(); - - enum class State { - Null, Running - }; - - State get_state() const; - - EngineLink* get_engine() const; - void set_engine(EngineLink *engine); - - Q_INVOKABLE void clear(); - -signals: - void state_changed(); - -private slots: - void on_game_running(bool running); - -private: - virtual void classBegin() override; - virtual void on_core_adopted() override; - virtual void componentComplete() override; - - State state; - bool active; - EngineLink *engine; -}; - -}} // namespace openage::gui diff --git a/libopenage/gui/game_saver.cpp b/libopenage/gui/game_saver.cpp index f6793207ca..a700dc704e 100644 --- a/libopenage/gui/game_saver.cpp +++ b/libopenage/gui/game_saver.cpp @@ -1,14 +1,13 @@ -// Copyright 2016-2021 the openage authors. See copying.md for legal info. +// Copyright 2016-2023 the openage authors. See copying.md for legal info. #include "game_saver.h" #include -#include "../gamestate/old/game_save.h" #include "../gamestate/old/game_main.h" +#include "../gamestate/old/game_save.h" #include "../gamestate/old/generator.h" -#include "game_main_link.h" #include "generator_link.h" namespace openage::gui { @@ -17,10 +16,8 @@ namespace { const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "GameSaver"); } -GameSaver::GameSaver(QObject *parent) - : +GameSaver::GameSaver(QObject *parent) : QObject{parent}, - game{}, generator_parameters{} { Q_UNUSED(registration); } @@ -33,47 +30,21 @@ QString GameSaver::get_error_string() const { // called when the save-game button is pressed: void GameSaver::activate() { - static auto f = [] (GameMainHandle *game, - Generator *generator, - std::shared_ptr callback) { - + static auto f = [](GameMainHandle *game, + Generator *generator, + std::shared_ptr callback) { QString error_msg; if (!game->is_game_running()) { error_msg = "no open game to save"; - } else { + } + else { auto filename = generator->getv("load_filename"); gameio::save(game->get_game(), filename); } emit callback->error_message(error_msg); }; - - if (this->game && this->generator_parameters) { - std::shared_ptr callback = std::make_shared(); - QObject::connect(callback.get(), - &GameSaverSignals::error_message, - this, - &GameSaver::on_processed); - - this->game->i(f, this->generator_parameters, callback); - } - else { - QString error_msg = "unknown error"; - - if (!this->game) { - error_msg = "provide 'game' before saving"; - } - - if (!this->generator_parameters) { - error_msg = "provide 'generatorParameters' before saving"; - } - else { - ENSURE(false, "unhandled case for refusal to create a game"); - } - - this->on_processed(error_msg); - } } void GameSaver::clearErrors() { @@ -86,4 +57,4 @@ void GameSaver::on_processed(const QString &error_string) { emit this->error_string_changed(); } -} // namespace openage::gui +} // namespace openage::gui diff --git a/libopenage/gui/game_saver.h b/libopenage/gui/game_saver.h index 13a4183de6..69cbbe75d8 100644 --- a/libopenage/gui/game_saver.h +++ b/libopenage/gui/game_saver.h @@ -1,4 +1,4 @@ -// Copyright 2016-2016 the openage authors. See copying.md for legal info. +// Copyright 2016-2023 the openage authors. See copying.md for legal info. #pragma once @@ -15,11 +15,10 @@ class GameSaver : public QObject { Q_ENUMS(State) Q_PROPERTY(QString errorString READ get_error_string NOTIFY error_string_changed) - Q_PROPERTY(openage::gui::GameMainLink* game MEMBER game NOTIFY game_changed) - Q_PROPERTY(openage::gui::GeneratorLink* generatorParameters MEMBER generator_parameters NOTIFY generator_parameters_changed) + Q_PROPERTY(openage::gui::GeneratorLink *generatorParameters MEMBER generator_parameters NOTIFY generator_parameters_changed) public: - explicit GameSaver(QObject *parent=nullptr); + explicit GameSaver(QObject *parent = nullptr); virtual ~GameSaver(); QString get_error_string() const; @@ -37,7 +36,6 @@ public slots: private: QString error_string; - GameMainLink *game; GeneratorLink *generator_parameters; }; @@ -49,4 +47,5 @@ class GameSaverSignals : public QObject { void error_message(const QString &error); }; -}} // namespace openage::gui +} // namespace gui +} // namespace openage diff --git a/libopenage/gui/gui.cpp b/libopenage/gui/gui.cpp index dfa44fdc8b..590e11124c 100644 --- a/libopenage/gui/gui.cpp +++ b/libopenage/gui/gui.cpp @@ -2,9 +2,7 @@ #include "gui.h" -#include "../legacy_engine.h" #include "../util/path.h" -#include "engine_info.h" namespace openage { @@ -19,10 +17,7 @@ GUI::GUI(SDL_Window *window, render_updater{}, renderer{window}, game_logic_updater{}, - engine{ - &renderer, - {}, - info}, + engine{&renderer}, subtree{ &renderer, &game_logic_updater, diff --git a/libopenage/gui/main_args_link.cpp b/libopenage/gui/main_args_link.cpp deleted file mode 100644 index 8d7b11daa4..0000000000 --- a/libopenage/gui/main_args_link.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "main_args_link.h" - -#include - -#include "../error/error.h" - -#include "engine_info.h" -#include "guisys/link/qml_engine_with_singleton_items_info.h" -#include "guisys/link/qtsdl_checked_static_cast.h" - -namespace openage::gui { - -namespace { -// register "MainArgs" in the qml engine to be used globally. -const int registration = qmlRegisterSingletonType("yay.sfttech.openage", 1, 0, "MainArgs", &MainArgsLink::provider); -} - - -MainArgsLink::MainArgsLink(QObject *parent, const util::Path &asset_dir) - : - QObject{parent}, - asset_dir{asset_dir} { - Q_UNUSED(registration); -} - - -QObject* MainArgsLink::provider(QQmlEngine *engine, QJSEngine*) { - auto *engine_with_singleton_items_info = qtsdl::checked_static_cast(engine); - auto info = static_cast(engine_with_singleton_items_info->get_singleton_items_info()); - ENSURE(info, "globals were lost or not passed to the gui subsystem"); - - // owned by the QML engine - return new MainArgsLink{nullptr, info->asset_dir}; -} - -} // namespace openage::gui diff --git a/libopenage/gui/main_args_link.h b/libopenage/gui/main_args_link.h deleted file mode 100644 index a615860d23..0000000000 --- a/libopenage/gui/main_args_link.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2015-2017 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "../util/path.h" - -QT_FORWARD_DECLARE_CLASS(QQmlEngine) -QT_FORWARD_DECLARE_CLASS(QJSEngine) - -namespace openage { -namespace gui { - -/** - * Used to make arguments of the game available in QML. - */ -class MainArgsLink : public QObject { - Q_OBJECT - - Q_PROPERTY(openage::util::Path assetDir MEMBER asset_dir CONSTANT) - -public: - explicit MainArgsLink(QObject *parent, const util::Path &asset_dir); - virtual ~MainArgsLink() = default; - - /** - * Generates the MainArgsLink object which is then used within QML. - */ - static QObject* provider(QQmlEngine*, QJSEngine*); - -private: - util::Path asset_dir; -}; - -}} // namespace openage::gui diff --git a/libopenage/legacy_engine.cpp b/libopenage/legacy_engine.cpp deleted file mode 100644 index 8b972316d1..0000000000 --- a/libopenage/legacy_engine.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2013-2023 the openage authors. See copying.md for legal info. - -#include "legacy_engine.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "error/error.h" -#include "log/log.h" -#include "version.h" -#include "versions/compiletime.h" - -namespace openage { - -LegacyEngine::LegacyEngine(enum mode mode, - const util::Path &root_dir, - const std::shared_ptr &cvar_manager) : - running{false}, - run_mode{mode}, - root_dir{root_dir}, - job_manager{SDL_GetCPUCount()}, - qml_info{this, root_dir["assets"]}, - cvar_manager{cvar_manager}, - profiler{this}, - gui_link{} { - // TODO: implement FULL and HEADLESS mode :) -} - - -LegacyEngine::~LegacyEngine() {} - - -void LegacyEngine::run() { - try { - this->job_manager.start(); - this->running = true; - - this->running = false; - } - catch (...) { - this->job_manager.stop(); - throw; - } -} - - -void LegacyEngine::stop() { - this->job_manager.stop(); - this->running = false; -} - - -const util::Path &LegacyEngine::get_root_dir() { - return this->root_dir; -} - - -job::JobManager *LegacyEngine::get_job_manager() { - return &this->job_manager; -} - - -std::shared_ptr LegacyEngine::get_cvar_manager() { - return this->cvar_manager; -} - -gui::EngineQMLInfo LegacyEngine::get_qml_info() { - return this->qml_info; -} - -} // namespace openage diff --git a/libopenage/legacy_engine.h b/libopenage/legacy_engine.h deleted file mode 100644 index cf01cb391a..0000000000 --- a/libopenage/legacy_engine.h +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright 2013-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "log/file_logsink.h" -#include "log/log.h" -// pxd: from libopenage.cvar cimport CVarManager -#include "cvar/cvar.h" -#include "gui/engine_info.h" -#include "job/job_manager.h" -#include "options.h" -#include "unit/selection.h" -#include "util/externalprofiler.h" -#include "util/path.h" -#include "util/profiler.h" -#include "util/strings.h" - - -/** - * Main openage namespace to store all things that make the have to do with the game. - * - * Game entity management, graphics drawing, gui stuff, input handling etc. - * So basically everything that makes the game work lies in here... - */ -namespace openage { - -namespace gui { -class GuiItemLink; -} // namespace gui - -/** - * Qt signals for the engine. - */ -class EngineSignals : public QObject { - Q_OBJECT - -public: -signals: - void global_binds_changed(const std::vector &global_binds); -}; - - -/** - * main engine container. - * - * central foundation for everything the openage engine is capable of. - * - * pxd: - * - * cppclass LegacyEngine: - * - * InputManager &get_input_manager() except + - * CVarManager &get_cvar_manager() except + - */ -class LegacyEngine final { -public: - enum class mode { - LEGACY, - HEADLESS, - FULL, - }; - - LegacyEngine(); - - /** - * engine initialization method. - * starts the engine subsystems depending on the requested run mode. - */ - LegacyEngine(mode mode, - const util::Path &root_dir, - const std::shared_ptr &cvar_manager); - - /** - * engine copy constructor. - */ - LegacyEngine(const LegacyEngine ©) = delete; - - /** - * engine assignment operator. - */ - LegacyEngine &operator=(const LegacyEngine ©) = delete; - - /** - * engine move constructor. - */ - LegacyEngine(LegacyEngine &&other) = delete; - - /** - * engine move operator. - */ - LegacyEngine &operator=(LegacyEngine &&other) = delete; - -public: - /** - * engine destructor, cleans up memory etc. - * deletes opengl context, the SDL window, and engine variables. - */ - ~LegacyEngine(); - - /** - * starts the engine loop. - */ - void run(); - - /** - * enqueues the stop of the main loop. - */ - void stop(); - - /** - * return the data directory where the engine was started from. - */ - const util::Path &get_root_dir(); - - /** - * return this engine's job manager. - * - * TODO: remove ptr access - */ - job::JobManager *get_job_manager(); - - /** - * return this engine's cvar manager. - */ - std::shared_ptr get_cvar_manager(); - - /** - * return this engine's qml info. - */ - gui::EngineQMLInfo get_qml_info(); - - /** - * current engine state variable. - * to be set to false to stop the engine loop. - */ - bool running; - - /** - * profiler used by the engine - */ - util::ExternalProfiler external_profiler; - -private: - /** - * Run-mode of the engine, this determines the basic modules to be loaded. - */ - mode run_mode; - - /** - * The engine root directory. - * Uses the openage fslike path abstraction that can mount paths into one. - * - * This means that this path does simulataneously lead to global assets, - * home-folder-assets, settings, and basically the whole filesystem access. - * - * TODO: move this to a settings class, which then also hosts cvar and the options system. - */ - util::Path root_dir; - - /** - * the engine's job manager, for asynchronous background task queuing. - */ - job::JobManager job_manager; - - - /** - * This stores information to be accessible from the QML engine. - * - * Information in there (such as a pointer to the this engine) - * is then usable from within qml files, after some additional magic. - */ - gui::EngineQMLInfo qml_info; - - /** - * the engine's cvar manager. - */ - std::shared_ptr cvar_manager; - - - /** - * the engines profiler - */ - util::Profiler profiler; - - /** - * Logsink to store messages to the filesystem. - */ - std::unique_ptr logsink_file; - -public: - /** - * Signal emitting capability for the engine. - */ - EngineSignals gui_signals; - - /** - * Link to the Qt GUI. - */ - gui::GuiItemLink *gui_link; -}; - -} // namespace openage diff --git a/libopenage/renderer/stages/screen/screenshot.cpp b/libopenage/renderer/stages/screen/screenshot.cpp index 8fad08cab9..e73c875a11 100644 --- a/libopenage/renderer/stages/screen/screenshot.cpp +++ b/libopenage/renderer/stages/screen/screenshot.cpp @@ -1,4 +1,4 @@ -// Copyright 2014-2019 the openage authors. See copying.md for legal info. +// Copyright 2014-2023 the openage authors. See copying.md for legal info. #include "screenshot.h" diff --git a/libopenage/terrain/terrain.cpp b/libopenage/terrain/terrain.cpp index 59f9239a9d..62eeefc32b 100644 --- a/libopenage/terrain/terrain.cpp +++ b/libopenage/terrain/terrain.cpp @@ -11,7 +11,6 @@ #include "../coord/pixel.h" #include "../coord/tile.h" #include "../error/error.h" -#include "../legacy_engine.h" #include "../log/log.h" #include "../util/misc.h" #include "../util/strings.h" diff --git a/libopenage/terrain/terrain.h b/libopenage/terrain/terrain.h index bb43a04e73..4db8fdbcb1 100644 --- a/libopenage/terrain/terrain.h +++ b/libopenage/terrain/terrain.h @@ -17,7 +17,6 @@ namespace openage { -class LegacyEngine; class RenderOptions; class TerrainChunk; class TerrainObject; diff --git a/libopenage/terrain/terrain_chunk.cpp b/libopenage/terrain/terrain_chunk.cpp index acbd76d7a7..aec7d2c6ec 100644 --- a/libopenage/terrain/terrain_chunk.cpp +++ b/libopenage/terrain/terrain_chunk.cpp @@ -8,7 +8,6 @@ #include "../coord/pixel.h" #include "../coord/tile.h" #include "../error/error.h" -#include "../legacy_engine.h" #include "../log/log.h" #include "../util/misc.h" diff --git a/libopenage/terrain/terrain_object.cpp b/libopenage/terrain/terrain_object.cpp index c4f4c6c9f9..a81716491a 100644 --- a/libopenage/terrain/terrain_object.cpp +++ b/libopenage/terrain/terrain_object.cpp @@ -9,7 +9,6 @@ #include "../coord/pixel.h" #include "../coord/tile.h" #include "../error/error.h" -#include "../legacy_engine.h" #include "../unit/unit.h" #include "terrain.h" @@ -20,7 +19,6 @@ namespace openage { TerrainObject::TerrainObject(Unit &u) : unit(u), passable{[](const coord::phys3 &) -> bool { return true; }}, - draw{[](const LegacyEngine & /*e*/) {}}, state{object_state::removed}, occupied_chunk_count{0}, parent{nullptr} { diff --git a/libopenage/terrain/terrain_object.h b/libopenage/terrain/terrain_object.h index 2f9384b6ce..93657db11d 100644 --- a/libopenage/terrain/terrain_object.h +++ b/libopenage/terrain/terrain_object.h @@ -10,7 +10,6 @@ namespace openage { -class LegacyEngine; class Terrain; class TerrainChunk; class Texture; @@ -118,11 +117,6 @@ class TerrainObject : public std::enable_shared_from_this { */ std::function passable; - /** - * specifies content to be drawn - */ - std::function draw; - /** * changes the placement state of this object keeping the existing * position. this is useful for upgrading a floating building to a placed state diff --git a/libopenage/unit/action.cpp b/libopenage/unit/action.cpp index 9370609f2d..65bd1bed8b 100644 --- a/libopenage/unit/action.cpp +++ b/libopenage/unit/action.cpp @@ -3,7 +3,6 @@ #include #include -#include "../legacy_engine.h" #include "../pathfinding/a_star.h" #include "../pathfinding/heuristics.h" #include "../terrain/terrain.h" @@ -100,13 +99,6 @@ float UnitAction::current_frame() const { return this->frame; } -void UnitAction::draw_debug(const LegacyEngine &engine) { - // draw debug content if available - if (show_debug && this->debug_draw_action) { - this->debug_draw_action(engine); - } -} - void UnitAction::face_towards(const coord::phys3 pos) { if (this->entity->has_attribute(attr_type::direction)) { auto &d_attr = this->entity->get_attribute(); diff --git a/libopenage/unit/action.h b/libopenage/unit/action.h index ca41229e87..b0db755fe6 100644 --- a/libopenage/unit/action.h +++ b/libopenage/unit/action.h @@ -146,8 +146,6 @@ class UnitAction { */ virtual std::string name() const = 0; - void draw_debug(const LegacyEngine &engine); - /** * common functions for actions */ @@ -195,11 +193,6 @@ class UnitAction { graphic_type graphic; float frame; float frame_rate; - - /** - * additional drawing for debug purposes - */ - std::function debug_draw_action; }; /** diff --git a/libopenage/unit/producer.cpp b/libopenage/unit/producer.cpp index fae69a6f78..07f6f45463 100644 --- a/libopenage/unit/producer.cpp +++ b/libopenage/unit/producer.cpp @@ -3,7 +3,6 @@ #include #include "../gamedata/unit_dummy.h" -#include "../legacy_engine.h" #include "../log/log.h" #include "../terrain/terrain.h" #include "../terrain/terrain_object.h" diff --git a/libopenage/unit/selection.cpp b/libopenage/unit/selection.cpp index 48d38ba457..354bf8f5ba 100644 --- a/libopenage/unit/selection.cpp +++ b/libopenage/unit/selection.cpp @@ -6,7 +6,6 @@ #include #include "../coord/tile.h" -#include "../legacy_engine.h" #include "../log/log.h" #include "../terrain/terrain.h" #include "action.h" @@ -17,10 +16,9 @@ namespace openage { -UnitSelection::UnitSelection(LegacyEngine *engine) : +UnitSelection::UnitSelection() : selection_type{selection_type_t::nothing}, - drag_active{false}, - engine{engine} { + drag_active{false} { } // bool UnitSelection::on_drawhud() { diff --git a/libopenage/unit/selection.h b/libopenage/unit/selection.h index fd623f91b9..f82fc02bea 100644 --- a/libopenage/unit/selection.h +++ b/libopenage/unit/selection.h @@ -9,8 +9,6 @@ #include "unit_container.h" namespace openage { - -class LegacyEngine; class Terrain; std::vector tiles_in_range(coord::camgame p1, coord::camgame p2, const coord::CoordManager &coord); @@ -36,7 +34,7 @@ enum class selection_type_t { */ class UnitSelection { public: - UnitSelection(LegacyEngine *engine); + UnitSelection(/* LegacyEngine *engine */); // bool on_drawhud() override; void drag_begin(coord::camgame pos); @@ -111,7 +109,7 @@ class UnitSelection { /** * Engine where this selection is attached to. */ - LegacyEngine *engine; + // LegacyEngine *engine; }; } // namespace openage diff --git a/libopenage/unit/unit.cpp b/libopenage/unit/unit.cpp index 234d47770e..bccd729a8e 100644 --- a/libopenage/unit/unit.cpp +++ b/libopenage/unit/unit.cpp @@ -4,7 +4,6 @@ #include #include -#include "../legacy_engine.h" #include "../terrain/terrain.h" #include "ability.h" diff --git a/libopenage/util/profiler.cpp b/libopenage/util/profiler.cpp index 9b0917edd4..95ebd85af7 100644 --- a/libopenage/util/profiler.cpp +++ b/libopenage/util/profiler.cpp @@ -1,7 +1,6 @@ // Copyright 2015-2023 the openage authors. See copying.md for legal info. #include "profiler.h" -#include "../legacy_engine.h" #include "../renderer/color.h" #include "misc.h" @@ -12,192 +11,192 @@ namespace openage::util { -Profiler::Profiler(LegacyEngine *engine) : - engine{engine} {} - - -Profiler::~Profiler() { - this->unregister_all(); -} - -void Profiler::register_component(const std::string &com, color component_color) { - if (this->registered(com)) { - return; - } - - component_time_data cdt; - cdt.display_name = com; - cdt.drawing_color = component_color; - - for (auto &val : cdt.history) { - val = 0; - } - - this->components[com] = cdt; -} - -void Profiler::unregister_component(const std::string &com) { - if (not this->registered(com)) { - return; - } - - this->components.erase(com); -} - -void Profiler::unregister_all() { - std::vector registered_components = this->registered_components(); - - for (auto com : registered_components) { - this->unregister_component(com); - } -} - -std::vector Profiler::registered_components() { - std::vector registered_components; - for (auto &pair : this->components) { - registered_components.push_back(pair.first); - } - - return registered_components; -} - -void Profiler::start_measure(const std::string &com, color component_color) { - if (not this->engine_in_debug_mode()) { - return; - } - - if (not this->registered(com)) { - this->register_component(com, component_color); - } - - this->components[com].start = std::chrono::high_resolution_clock::now(); -} - -void Profiler::end_measure(const std::string &com) { - if (not this->engine_in_debug_mode()) { - return; - } - - if (this->registered(com)) { - std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); - this->components[com].duration = end - this->components[com].start; - } -} - -void Profiler::draw_component_performance(const std::string &com) { - color rgb = this->components[com].drawing_color; - glColor4f(rgb.r, rgb.g, rgb.b, 1.0); - - glLineWidth(1.0); - glBegin(GL_LINE_STRIP); - float x_offset = 0.0; - float offset_factor = static_cast(PROFILER_CANVAS_WIDTH) / static_cast(MAX_DURATION_HISTORY); - float percentage_factor = static_cast(PROFILER_CANVAS_HEIGHT) / 100.0; - - for (auto i = this->insert_pos; mod(i, MAX_DURATION_HISTORY) != mod(this->insert_pos - 1, MAX_DURATION_HISTORY); ++i) { - i = mod(i, MAX_DURATION_HISTORY); - - auto percentage = this->components[com].history.at(i); - glVertex3f(PROFILER_CANVAS_POSITION_X + x_offset, PROFILER_CANVAS_POSITION_Y + percentage * percentage_factor, 0.0); - x_offset += offset_factor; - } - glEnd(); - - // reset color - glColor4f(1.0, 1.0, 1.0, 1.0); -} - -void Profiler::show(bool debug_mode) { - if (debug_mode) { - this->show(); - } -} - -void Profiler::show() { - this->draw_canvas(); - this->draw_legend(); - - for (auto com : this->components) { - this->draw_component_performance(com.first); - } -} - -bool Profiler::registered(const std::string &com) const { - return this->components.find(com) != this->components.end(); -} - -unsigned Profiler::size() const { - return this->components.size(); -} - -void Profiler::start_frame_measure() { - if (this->engine_in_debug_mode()) { - this->frame_start = std::chrono::high_resolution_clock::now(); - } -} - -void Profiler::end_frame_measure() { - if (not this->engine_in_debug_mode()) { - return; - } - - auto frame_end = std::chrono::high_resolution_clock::now(); - this->frame_duration = frame_end - this->frame_start; - - for (auto com : this->registered_components()) { - double percentage = this->duration_to_percentage(this->components[com].duration); - this->append_to_history(com, percentage); - } - - this->insert_pos++; -} - -void Profiler::draw_canvas() { - glColor4f(0.2, 0.2, 0.2, PROFILER_CANVAS_ALPHA); - glRecti(PROFILER_CANVAS_POSITION_X, - PROFILER_CANVAS_POSITION_Y, - PROFILER_CANVAS_POSITION_X + PROFILER_CANVAS_WIDTH, - PROFILER_CANVAS_POSITION_Y + PROFILER_CANVAS_HEIGHT); -} - -void Profiler::draw_legend() { - int offset = 0; - for (auto com : this->components) { - glColor4f(com.second.drawing_color.r, com.second.drawing_color.g, com.second.drawing_color.b, 1.0); - int box_x = PROFILER_CANVAS_POSITION_X + 2; - int box_y = PROFILER_CANVAS_POSITION_Y - PROFILER_COM_BOX_HEIGHT - 2 - offset; - glRecti(box_x, box_y, box_x + PROFILER_COM_BOX_WIDTH, box_y + PROFILER_COM_BOX_HEIGHT); - - glColor4f(0.2, 0.2, 0.2, 1); - coord::viewport position = coord::viewport{box_x + PROFILER_COM_BOX_WIDTH + 2, box_y + 2}; - // this->display->render_text(position, 12, renderer::Colors::WHITE, "%s", com.second.display_name.c_str()); - - offset += PROFILER_COM_BOX_HEIGHT + 2; - } -} - -double Profiler::duration_to_percentage(std::chrono::high_resolution_clock::duration duration) { - double dur = std::chrono::duration_cast(duration).count(); - double ref = std::chrono::duration_cast(this->frame_duration).count(); - double percentage = dur / ref * 100; - return percentage; -} - -void Profiler::append_to_history(const std::string &com, double percentage) { - if (this->insert_pos == MAX_DURATION_HISTORY) { - this->insert_pos = 0; - } - this->components[com].history[this->insert_pos] = percentage; -} - -bool Profiler::engine_in_debug_mode() { - // if (this->display->drawing_debug_overlay.value) { - // return true; - // } - // else { - // return false; - // } - return true; -} +// Profiler::Profiler() : +// {} + + +// Profiler::~Profiler() { +// this->unregister_all(); +// } + +// void Profiler::register_component(const std::string &com, color component_color) { +// if (this->registered(com)) { +// return; +// } + +// component_time_data cdt; +// cdt.display_name = com; +// cdt.drawing_color = component_color; + +// for (auto &val : cdt.history) { +// val = 0; +// } + +// this->components[com] = cdt; +// } + +// void Profiler::unregister_component(const std::string &com) { +// if (not this->registered(com)) { +// return; +// } + +// this->components.erase(com); +// } + +// void Profiler::unregister_all() { +// std::vector registered_components = this->registered_components(); + +// for (auto com : registered_components) { +// this->unregister_component(com); +// } +// } + +// std::vector Profiler::registered_components() { +// std::vector registered_components; +// for (auto &pair : this->components) { +// registered_components.push_back(pair.first); +// } + +// return registered_components; +// } + +// void Profiler::start_measure(const std::string &com, color component_color) { +// if (not this->engine_in_debug_mode()) { +// return; +// } + +// if (not this->registered(com)) { +// this->register_component(com, component_color); +// } + +// this->components[com].start = std::chrono::high_resolution_clock::now(); +// } + +// void Profiler::end_measure(const std::string &com) { +// if (not this->engine_in_debug_mode()) { +// return; +// } + +// if (this->registered(com)) { +// std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); +// this->components[com].duration = end - this->components[com].start; +// } +// } + +// void Profiler::draw_component_performance(const std::string &com) { +// color rgb = this->components[com].drawing_color; +// glColor4f(rgb.r, rgb.g, rgb.b, 1.0); + +// glLineWidth(1.0); +// glBegin(GL_LINE_STRIP); +// float x_offset = 0.0; +// float offset_factor = static_cast(PROFILER_CANVAS_WIDTH) / static_cast(MAX_DURATION_HISTORY); +// float percentage_factor = static_cast(PROFILER_CANVAS_HEIGHT) / 100.0; + +// for (auto i = this->insert_pos; mod(i, MAX_DURATION_HISTORY) != mod(this->insert_pos - 1, MAX_DURATION_HISTORY); ++i) { +// i = mod(i, MAX_DURATION_HISTORY); + +// auto percentage = this->components[com].history.at(i); +// glVertex3f(PROFILER_CANVAS_POSITION_X + x_offset, PROFILER_CANVAS_POSITION_Y + percentage * percentage_factor, 0.0); +// x_offset += offset_factor; +// } +// glEnd(); + +// // reset color +// glColor4f(1.0, 1.0, 1.0, 1.0); +// } + +// void Profiler::show(bool debug_mode) { +// if (debug_mode) { +// this->show(); +// } +// } + +// // void Profiler::show() { +// // this->draw_canvas(); +// // this->draw_legend(); + +// // for (auto com : this->components) { +// // this->draw_component_performance(com.first); +// // } +// // } + +// bool Profiler::registered(const std::string &com) const { +// return this->components.find(com) != this->components.end(); +// } + +// unsigned Profiler::size() const { +// return this->components.size(); +// } + +// void Profiler::start_frame_measure() { +// if (this->engine_in_debug_mode()) { +// this->frame_start = std::chrono::high_resolution_clock::now(); +// } +// } + +// void Profiler::end_frame_measure() { +// if (not this->engine_in_debug_mode()) { +// return; +// } + +// auto frame_end = std::chrono::high_resolution_clock::now(); +// this->frame_duration = frame_end - this->frame_start; + +// for (auto com : this->registered_components()) { +// double percentage = this->duration_to_percentage(this->components[com].duration); +// this->append_to_history(com, percentage); +// } + +// this->insert_pos++; +// } + +// // void Profiler::draw_canvas() { +// // glColor4f(0.2, 0.2, 0.2, PROFILER_CANVAS_ALPHA); +// // glRecti(PROFILER_CANVAS_POSITION_X, +// // PROFILER_CANVAS_POSITION_Y, +// // PROFILER_CANVAS_POSITION_X + PROFILER_CANVAS_WIDTH, +// // PROFILER_CANVAS_POSITION_Y + PROFILER_CANVAS_HEIGHT); +// // } + +// // void Profiler::draw_legend() { +// // int offset = 0; +// // for (auto com : this->components) { +// // glColor4f(com.second.drawing_color.r, com.second.drawing_color.g, com.second.drawing_color.b, 1.0); +// // int box_x = PROFILER_CANVAS_POSITION_X + 2; +// // int box_y = PROFILER_CANVAS_POSITION_Y - PROFILER_COM_BOX_HEIGHT - 2 - offset; +// // glRecti(box_x, box_y, box_x + PROFILER_COM_BOX_WIDTH, box_y + PROFILER_COM_BOX_HEIGHT); + +// // glColor4f(0.2, 0.2, 0.2, 1); +// // coord::viewport position = coord::viewport{box_x + PROFILER_COM_BOX_WIDTH + 2, box_y + 2}; +// // // this->display->render_text(position, 12, renderer::Colors::WHITE, "%s", com.second.display_name.c_str()); + +// // offset += PROFILER_COM_BOX_HEIGHT + 2; +// // } +// // } + +// double Profiler::duration_to_percentage(std::chrono::high_resolution_clock::duration duration) { +// double dur = std::chrono::duration_cast(duration).count(); +// double ref = std::chrono::duration_cast(this->frame_duration).count(); +// double percentage = dur / ref * 100; +// return percentage; +// } + +// void Profiler::append_to_history(const std::string &com, double percentage) { +// if (this->insert_pos == MAX_DURATION_HISTORY) { +// this->insert_pos = 0; +// } +// this->components[com].history[this->insert_pos] = percentage; +// } + +// bool Profiler::engine_in_debug_mode() { +// // if (this->display->drawing_debug_overlay.value) { +// // return true; +// // } +// // else { +// // return false; +// // } +// return true; +// } } // namespace openage::util diff --git a/libopenage/util/profiler.h b/libopenage/util/profiler.h index 24d3946394..1b3641d576 100644 --- a/libopenage/util/profiler.h +++ b/libopenage/util/profiler.h @@ -19,9 +19,6 @@ constexpr int PROFILER_COM_BOX_HEIGHT = 15; namespace openage { -class LegacyEngine; - - namespace util { struct color { @@ -36,95 +33,93 @@ struct component_time_data { std::array history; }; -class Profiler { -public: - Profiler(LegacyEngine *engine); - ~Profiler(); - - /** - * registers a component - * @param com the identifier to distinguish the components - * @param component_color color of the plotted line - */ - void register_component(const std::string &com, color component_color); - - /** - * unregisters an individual component - * @param com component name which should be unregistered - */ - void unregister_component(const std::string &com); - - /** - * unregisters all remaining components - */ - void unregister_all(); - - /** - *returns a vector of registered component names - */ - std::vector registered_components(); - - /* - * starts a measurement for the component com. If com is not yet - * registered, its getting registered and the profiler uses the color - * information given by component_color. The default value is white. - */ - void start_measure(const std::string &com, color component_color = {1.0, 1.0, 1.0}); - - /* - * stops the measurement for the component com. If com is not yet - * registered it does nothing. - */ - void end_measure(const std::string &com); - - /* - * draws the profiler gui if debug_mode is set - */ - void show(bool debug_mode); - - /* - * draws the profiler gui - */ - void show(); - - /* - * true if the component com is already registered, otherwise false - */ - bool registered(const std::string &com) const; - - /* - * returns the number of registered components - */ - unsigned size() const; - - /** - * sets the start point for the actual frame which is used as a reference - * value for the registered components - */ - void start_frame_measure(); - - /** - * sets the end point for the reference time used to compute the portions - * of the components. Each recorded measurement for the registered components - * get appended to their history complete the measurement. - */ - void end_frame_measure(); - -private: - void draw_canvas(); - void draw_legend(); - void draw_component_performance(const std::string &com); - double duration_to_percentage(std::chrono::high_resolution_clock::duration duration); - void append_to_history(const std::string &com, double percentage); - bool engine_in_debug_mode(); - - std::chrono::high_resolution_clock::time_point frame_start; - std::chrono::high_resolution_clock::duration frame_duration; - std::unordered_map components; - int insert_pos = 0; - - LegacyEngine *engine; -}; +// class Profiler { +// public: +// Profiler(); +// ~Profiler(); + +// /** +// * registers a component +// * @param com the identifier to distinguish the components +// * @param component_color color of the plotted line +// */ +// void register_component(const std::string &com, color component_color); + +// /** +// * unregisters an individual component +// * @param com component name which should be unregistered +// */ +// void unregister_component(const std::string &com); + +// /** +// * unregisters all remaining components +// */ +// void unregister_all(); + +// /** +// *returns a vector of registered component names +// */ +// std::vector registered_components(); + +// /* +// * starts a measurement for the component com. If com is not yet +// * registered, its getting registered and the profiler uses the color +// * information given by component_color. The default value is white. +// */ +// void start_measure(const std::string &com, color component_color = {1.0, 1.0, 1.0}); + +// /* +// * stops the measurement for the component com. If com is not yet +// * registered it does nothing. +// */ +// void end_measure(const std::string &com); + +// /* +// * draws the profiler gui if debug_mode is set +// */ +// void show(bool debug_mode); + +// /* +// * draws the profiler gui +// */ +// void show(); + +// /* +// * true if the component com is already registered, otherwise false +// */ +// bool registered(const std::string &com) const; + +// /* +// * returns the number of registered components +// */ +// unsigned size() const; + +// /** +// * sets the start point for the actual frame which is used as a reference +// * value for the registered components +// */ +// void start_frame_measure(); + +// /** +// * sets the end point for the reference time used to compute the portions +// * of the components. Each recorded measurement for the registered components +// * get appended to their history complete the measurement. +// */ +// void end_frame_measure(); + +// private: +// // void draw_canvas(); +// // void draw_legend(); +// void draw_component_performance(const std::string &com); +// double duration_to_percentage(std::chrono::high_resolution_clock::duration duration); +// void append_to_history(const std::string &com, double percentage); +// bool engine_in_debug_mode(); + +// std::chrono::high_resolution_clock::time_point frame_start; +// std::chrono::high_resolution_clock::duration frame_duration; +// std::unordered_map components; +// int insert_pos = 0; +// }; } // namespace util } // namespace openage From c1d4741439533c88c7222e3c14f8bd59edec8f67 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 23 Sep 2023 23:54:57 +0200 Subject: [PATCH 40/95] gamestate: Remove legacy gamestate. --- libopenage/CMakeLists.txt | 1 - libopenage/gamestate/CMakeLists.txt | 3 - libopenage/gamestate/old/CMakeLists.txt | 15 - libopenage/gamestate/old/civilisation.cpp | 65 - libopenage/gamestate/old/civilisation.h | 85 -- libopenage/gamestate/old/cost.cpp | 48 - libopenage/gamestate/old/cost.h | 65 - libopenage/gamestate/old/game_main.cpp | 86 -- libopenage/gamestate/old/game_main.h | 169 --- libopenage/gamestate/old/game_save.cpp | 149 -- libopenage/gamestate/old/game_save.h | 27 - libopenage/gamestate/old/game_spec.cpp | 455 ------ libopenage/gamestate/old/game_spec.h | 290 ---- libopenage/gamestate/old/generator.cpp | 323 ----- libopenage/gamestate/old/generator.h | 179 --- libopenage/gamestate/old/market.cpp | 84 -- libopenage/gamestate/old/market.h | 71 - libopenage/gamestate/old/player.cpp | 291 ---- libopenage/gamestate/old/player.h | 244 ---- .../gamestate/old/population_tracker.cpp | 76 - libopenage/gamestate/old/population_tracker.h | 106 -- libopenage/gamestate/old/resource.cpp | 208 --- libopenage/gamestate/old/resource.h | 209 --- libopenage/gamestate/old/score.cpp | 109 -- libopenage/gamestate/old/score.h | 140 -- libopenage/gamestate/old/team.cpp | 77 - libopenage/gamestate/old/team.h | 75 - libopenage/gamestate/old/types.cpp | 8 - libopenage/gamestate/old/types.h | 16 - libopenage/gui/CMakeLists.txt | 6 - .../gui/category_contents_list_model.cpp | 70 - libopenage/gui/category_contents_list_model.h | 47 - libopenage/gui/game_creator.cpp | 70 - libopenage/gui/game_creator.h | 57 - libopenage/gui/game_saver.cpp | 60 - libopenage/gui/game_saver.h | 51 - libopenage/gui/game_spec_link.cpp | 100 -- libopenage/gui/game_spec_link.h | 104 -- libopenage/gui/generator_link.cpp | 25 - libopenage/gui/generator_link.h | 43 - .../gui/integration/private/CMakeLists.txt | 2 - .../gui_game_spec_image_provider_impl.cpp | 107 -- .../gui_game_spec_image_provider_impl.h | 102 -- .../private/gui_image_provider_link.cpp | 39 +- .../private/gui_image_provider_link.h | 32 +- .../private/gui_texture_factory.cpp | 31 - .../integration/private/gui_texture_factory.h | 33 - libopenage/gui/resources_list_model.cpp | 59 - libopenage/gui/resources_list_model.h | 36 - libopenage/pathfinding/a_star.cpp | 49 +- libopenage/pathfinding/a_star.h | 10 +- libopenage/terrain/CMakeLists.txt | 2 - libopenage/terrain/terrain.cpp | 26 +- libopenage/terrain/terrain.h | 8 - libopenage/terrain/terrain_chunk.cpp | 1 - libopenage/terrain/terrain_chunk.h | 1 - libopenage/terrain/terrain_object.cpp | 463 ------ libopenage/terrain/terrain_object.h | 332 ----- libopenage/terrain/terrain_search.cpp | 104 -- libopenage/terrain/terrain_search.h | 74 - libopenage/unit/CMakeLists.txt | 13 - libopenage/unit/ability.cpp | 446 ------ libopenage/unit/ability.h | 380 ----- libopenage/unit/action.cpp | 1249 ----------------- libopenage/unit/action.h | 720 ---------- libopenage/unit/attribute.cpp | 21 - libopenage/unit/attribute.h | 643 --------- libopenage/unit/attributes.cpp | 44 - libopenage/unit/attributes.h | 64 - libopenage/unit/command.cpp | 103 -- libopenage/unit/command.h | 153 -- libopenage/unit/producer.cpp | 695 --------- libopenage/unit/producer.h | 154 -- libopenage/unit/research.cpp | 63 - libopenage/unit/research.h | 162 --- libopenage/unit/selection.cpp | 306 ---- libopenage/unit/selection.h | 115 -- libopenage/unit/type_pair.cpp | 16 - libopenage/unit/type_pair.h | 37 - libopenage/unit/unit.cpp | 260 ---- libopenage/unit/unit.h | 304 ---- libopenage/unit/unit_container.cpp | 172 --- libopenage/unit/unit_container.h | 145 -- libopenage/unit/unit_type.cpp | 154 -- libopenage/unit/unit_type.h | 206 --- 85 files changed, 34 insertions(+), 12409 deletions(-) delete mode 100644 libopenage/gamestate/old/CMakeLists.txt delete mode 100644 libopenage/gamestate/old/civilisation.cpp delete mode 100644 libopenage/gamestate/old/civilisation.h delete mode 100644 libopenage/gamestate/old/cost.cpp delete mode 100644 libopenage/gamestate/old/cost.h delete mode 100644 libopenage/gamestate/old/game_main.cpp delete mode 100644 libopenage/gamestate/old/game_main.h delete mode 100644 libopenage/gamestate/old/game_save.cpp delete mode 100644 libopenage/gamestate/old/game_save.h delete mode 100644 libopenage/gamestate/old/game_spec.cpp delete mode 100644 libopenage/gamestate/old/game_spec.h delete mode 100644 libopenage/gamestate/old/generator.cpp delete mode 100644 libopenage/gamestate/old/generator.h delete mode 100644 libopenage/gamestate/old/market.cpp delete mode 100644 libopenage/gamestate/old/market.h delete mode 100644 libopenage/gamestate/old/player.cpp delete mode 100644 libopenage/gamestate/old/player.h delete mode 100644 libopenage/gamestate/old/population_tracker.cpp delete mode 100644 libopenage/gamestate/old/population_tracker.h delete mode 100644 libopenage/gamestate/old/resource.cpp delete mode 100644 libopenage/gamestate/old/resource.h delete mode 100644 libopenage/gamestate/old/score.cpp delete mode 100644 libopenage/gamestate/old/score.h delete mode 100644 libopenage/gamestate/old/team.cpp delete mode 100644 libopenage/gamestate/old/team.h delete mode 100644 libopenage/gamestate/old/types.cpp delete mode 100644 libopenage/gamestate/old/types.h delete mode 100644 libopenage/gui/category_contents_list_model.cpp delete mode 100644 libopenage/gui/category_contents_list_model.h delete mode 100644 libopenage/gui/game_creator.cpp delete mode 100644 libopenage/gui/game_creator.h delete mode 100644 libopenage/gui/game_saver.cpp delete mode 100644 libopenage/gui/game_saver.h delete mode 100644 libopenage/gui/game_spec_link.cpp delete mode 100644 libopenage/gui/game_spec_link.h delete mode 100644 libopenage/gui/generator_link.cpp delete mode 100644 libopenage/gui/generator_link.h delete mode 100644 libopenage/gui/integration/private/gui_game_spec_image_provider_impl.cpp delete mode 100644 libopenage/gui/integration/private/gui_game_spec_image_provider_impl.h delete mode 100644 libopenage/gui/integration/private/gui_texture_factory.cpp delete mode 100644 libopenage/gui/integration/private/gui_texture_factory.h delete mode 100644 libopenage/gui/resources_list_model.cpp delete mode 100644 libopenage/gui/resources_list_model.h delete mode 100644 libopenage/terrain/terrain_object.cpp delete mode 100644 libopenage/terrain/terrain_object.h delete mode 100644 libopenage/terrain/terrain_search.cpp delete mode 100644 libopenage/terrain/terrain_search.h delete mode 100644 libopenage/unit/CMakeLists.txt delete mode 100644 libopenage/unit/ability.cpp delete mode 100644 libopenage/unit/ability.h delete mode 100644 libopenage/unit/action.cpp delete mode 100644 libopenage/unit/action.h delete mode 100644 libopenage/unit/attribute.cpp delete mode 100644 libopenage/unit/attribute.h delete mode 100644 libopenage/unit/attributes.cpp delete mode 100644 libopenage/unit/attributes.h delete mode 100644 libopenage/unit/command.cpp delete mode 100644 libopenage/unit/command.h delete mode 100644 libopenage/unit/producer.cpp delete mode 100644 libopenage/unit/producer.h delete mode 100644 libopenage/unit/research.cpp delete mode 100644 libopenage/unit/research.h delete mode 100644 libopenage/unit/selection.cpp delete mode 100644 libopenage/unit/selection.h delete mode 100644 libopenage/unit/type_pair.cpp delete mode 100644 libopenage/unit/type_pair.h delete mode 100644 libopenage/unit/unit.cpp delete mode 100644 libopenage/unit/unit.h delete mode 100644 libopenage/unit/unit_container.cpp delete mode 100644 libopenage/unit/unit_container.h delete mode 100644 libopenage/unit/unit_type.cpp delete mode 100644 libopenage/unit/unit_type.h diff --git a/libopenage/CMakeLists.txt b/libopenage/CMakeLists.txt index 9dc9db84d9..bda4bc1611 100644 --- a/libopenage/CMakeLists.txt +++ b/libopenage/CMakeLists.txt @@ -359,6 +359,5 @@ add_subdirectory("rng") add_subdirectory("terrain") add_subdirectory("testing") add_subdirectory("time") -add_subdirectory("unit") add_subdirectory("util") add_subdirectory("versions") diff --git a/libopenage/gamestate/CMakeLists.txt b/libopenage/gamestate/CMakeLists.txt index c89d9cd52d..dddf843136 100644 --- a/libopenage/gamestate/CMakeLists.txt +++ b/libopenage/gamestate/CMakeLists.txt @@ -20,6 +20,3 @@ add_subdirectory(component/) add_subdirectory(demo/) add_subdirectory(event/) add_subdirectory(system/) - -# TODO: remove once migration is done. -add_subdirectory(old/) diff --git a/libopenage/gamestate/old/CMakeLists.txt b/libopenage/gamestate/old/CMakeLists.txt deleted file mode 100644 index d141c14607..0000000000 --- a/libopenage/gamestate/old/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -add_sources(libopenage - civilisation.cpp - cost.cpp - game_main.cpp - game_save.cpp - game_spec.cpp - generator.cpp - market.cpp - player.cpp - population_tracker.cpp - resource.cpp - score.cpp - team.cpp - types.cpp -) diff --git a/libopenage/gamestate/old/civilisation.cpp b/libopenage/gamestate/old/civilisation.cpp deleted file mode 100644 index 6139ed23fe..0000000000 --- a/libopenage/gamestate/old/civilisation.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2015-2018 the openage authors. See copying.md for legal info. - -#include "civilisation.h" - -#include "../../log/log.h" -#include "../../unit/unit_type.h" - - -namespace openage { - -Civilisation::Civilisation(const GameSpec &spec, int id) - : - civ_id{id}, - civ_name{spec.get_civ_name(id)} { - this->initialise_unit_types(spec); -} - - -std::vector> Civilisation::object_meta() const { - return civ_objects; -} - - -std::vector Civilisation::get_category(const std::string &c) const { - auto cat = this->categories.find(c); - if (cat == this->categories.end()) { - return std::vector(); - } - return cat->second; -} - - -std::vector Civilisation::get_type_categories() const { - return this->all_categories; -} - - -const gamedata::building_unit *Civilisation::get_building_data(index_t unit_id) const { - if (this->buildings.count(unit_id) == 0) { - log::log(MSG(info) << " -> ignoring unit_id: " << unit_id); - return nullptr; - } - return this->buildings.at(unit_id); -} - - -void Civilisation::initialise_unit_types(const GameSpec &spec) { - log::log(MSG(dbg) << "Init units of civilisation " << civ_name); - spec.create_unit_types(this->civ_objects, this->civ_id); - for (auto &type : this->civ_objects) { - this->add_to_category(type->name(), type->id()); - } -} - - -void Civilisation::add_to_category(const std::string &c, index_t type) { - if (this->categories.count(c) == 0) { - this->all_categories.push_back(c); - this->categories[c] = std::vector(); - } - this->categories[c].push_back(type); -} - - -} diff --git a/libopenage/gamestate/old/civilisation.h b/libopenage/gamestate/old/civilisation.h deleted file mode 100644 index 97045031ea..0000000000 --- a/libopenage/gamestate/old/civilisation.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include - -#include "game_spec.h" - -namespace openage { - -/** - * contains the initial tech structure for - * one civilisation - */ -class Civilisation { -public: - Civilisation(const GameSpec &spec, int id); - - /** - * civ index - */ - const int civ_id; - - /** - * civ name - */ - const std::string civ_name; - - /** - * return all the objects available to this civ - */ - std::vector> object_meta() const; - - /** - * return all types in a particular named category - */ - std::vector get_category(const std::string &c) const; - - /** - * return all used categories, such as living, building or projectile - */ - std::vector get_type_categories() const; - - /** - * gamedata for a building - */ - const gamedata::building_unit *get_building_data(index_t unit_id) const; - - /** - * initialise the unit meta data - */ - void initialise_unit_types(const GameSpec &spec); - -private: - - /** - * creates and adds items to categories - */ - void add_to_category(const std::string &c, index_t type); - - /** - * unit types which can be produced by this civilisation. - */ - std::vector> civ_objects; - - /** - * all available categories of units - */ - std::vector all_categories; - - /** - * category lists - */ - std::unordered_map> categories; - - /** - * used for annex creation - */ - std::unordered_map buildings; - -}; - -} diff --git a/libopenage/gamestate/old/cost.cpp b/libopenage/gamestate/old/cost.cpp deleted file mode 100644 index 089cb6da4b..0000000000 --- a/libopenage/gamestate/old/cost.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2017-2021 the openage authors. See copying.md for legal info. - -#include "cost.h" -#include "player.h" - - -namespace openage { - -ResourceCost::ResourceCost() - : - type{cost_type::constant}, - resources{} {} - -ResourceCost::ResourceCost(const ResourceBundle& resources) - : - type{cost_type::constant}, - resources{} { - this->resources.set(resources); -} - -ResourceCost::ResourceCost(cost_type type, const ResourceBundle& multiplier) - : - type{type}, - resources{} { - this->resources.set(multiplier); -} - -ResourceCost::~ResourceCost() = default; - -void ResourceCost::set(cost_type type, const ResourceBundle& resources) { - this->type = type; - this->resources.set(resources); -} - -const ResourceBundle ResourceCost::get(const Player& player) const { - if (type == cost_type::constant) { - return resources; - } - - // calculate dynamic cost - ResourceBundle resources = this->resources.clone(); - if (type == cost_type::workforce) { - resources *= player.get_workforce_count(); - } - return resources; -} - -} // openage diff --git a/libopenage/gamestate/old/cost.h b/libopenage/gamestate/old/cost.h deleted file mode 100644 index 749aa50986..0000000000 --- a/libopenage/gamestate/old/cost.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2017-2019 the openage authors. See copying.md for legal info. - -#pragma once - -#include "resource.h" - - -namespace openage { - -class Player; - -/** - * Types of dynamic cost calculation (and one constant). - * - * Used in ResourceCost - * TODO use in TimeCost - */ -enum class cost_type : int { - /** Constant resources. */ - constant, - /** Dynamic cost based on the workforce. */ - workforce -}; - -/** - * A container for a constant or dynamic ResourceBundle representing the cost. - */ -class ResourceCost { -public: - - /** - * Constant zero cost - */ - ResourceCost(); - - /** - * Constant cost - */ - ResourceCost(const ResourceBundle& resources); - - /** - * Dynamic cost - */ - ResourceCost(cost_type type, const ResourceBundle& multiplier); - - virtual ~ResourceCost(); - - void set(cost_type type, const ResourceBundle& multiplier); - - /** - * Returns the cost. - */ - const ResourceBundle get(const Player& player) const; - -private: - - cost_type type; - - ResourceBundle resources; - -}; - -// TODO implement TimeCost - -} // namespace openage diff --git a/libopenage/gamestate/old/game_main.cpp b/libopenage/gamestate/old/game_main.cpp deleted file mode 100644 index 5d928e548a..0000000000 --- a/libopenage/gamestate/old/game_main.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#include "game_main.h" - -#include "../../log/log.h" -#include "../../terrain/terrain.h" -#include "../../unit/unit_type.h" -#include "game_spec.h" -#include "generator.h" - - -namespace openage { - -GameMain::GameMain(const Generator &generator) : - OptionNode{"GameMain"}, - terrain{generator.terrain()}, - placed_units{}, - spec{generator.get_spec()} { - // players - this->players.reserve(generator.player_names().size()); - unsigned int i = 0; - for (auto &name : generator.player_names()) { - this->players.push_back(std::make_shared(this->add_civ(i), i, name)); - i++; - } - - // initialise types only after all players are added - for (auto &p : this->players) { - p->initialise_unit_types(); - } - - // initialise units - this->placed_units.set_terrain(this->terrain); - generator.add_units(*this); -} - -GameMain::~GameMain() = default; - -unsigned int GameMain::player_count() const { - return this->players.size(); -} - -Player *GameMain::get_player(unsigned int player_id) { - return this->players.at(player_id).get(); -} - -unsigned int GameMain::team_count() const { - return this->teams.size(); -} - -Team *GameMain::get_team(unsigned int team_id) { - return &this->teams.at(team_id); -} - -GameSpec *GameMain::get_spec() { - return this->spec.get(); -} - -void GameMain::update(time_nsec_t lastframe_duration) { - this->placed_units.update_all(lastframe_duration); -} - -Civilisation *GameMain::add_civ(int civ_id) { - auto new_civ = std::make_shared(*this->spec, civ_id); - this->civs.emplace_back(new_civ); - return new_civ.get(); -} - -GameMainHandle::GameMainHandle(qtsdl::GuiItemLink *gui_link) : - game{}, - gui_link{gui_link} { -} - -GameMain *GameMainHandle::get_game() const { - return this->game; -} - -bool GameMainHandle::is_game_running() const { - return this->game != nullptr; -} - -void GameMainHandle::announce_running() { - emit this->gui_signals.game_running(this->game); -} - -} // namespace openage diff --git a/libopenage/gamestate/old/game_main.h b/libopenage/gamestate/old/game_main.h deleted file mode 100644 index af3651aadc..0000000000 --- a/libopenage/gamestate/old/game_main.h +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include - -#include - -#include "../../options.h" -#include "../../terrain/terrain.h" -#include "../../unit/unit_container.h" -#include "../../util/timing.h" -#include "market.h" -#include "player.h" -#include "team.h" - -namespace openage { - -class Generator; -class Terrain; - - -/** - * Contains information for a single game - * This information must be synced across network clients - * - * TODO: include a list of actions to be saved - * as the game replay file - */ -class GameMain : public options::OptionNode { -public: - GameMain(const Generator &generator); - ~GameMain(); - - /** - * the number of players - */ - unsigned int player_count() const; - - /** - * player by index - */ - Player *get_player(unsigned int player_id); - - /** - * the number of teams - */ - unsigned int team_count() const; - - /** - * team by id - */ - Team *get_team(unsigned int team_id); - - /** - * the spec in this games settings - */ - GameSpec *get_spec(); - - /** - * updates the game by one frame - */ - void update(time_nsec_t lastframe_duration); - - /** - * map information - */ - std::shared_ptr terrain; - - /** - * all teams in the game - */ - std::vector teams; - - /** - * The global market (the global market prices). - */ - Market market; - - /** - * all the objects that have been placed. - */ - UnitContainer placed_units; - -private: - /** - * all players in the game - * no objects should be added of removed once populated - */ - std::vector> players; - - /** - * creates a random civ, owned and managed by this game - */ - Civilisation *add_civ(int civ_id); - - /** - * civs used in this game - */ - std::vector> civs; - - std::shared_ptr spec; -}; - -} // namespace openage - -namespace qtsdl { -class GuiItemLink; -} // namespace qtsdl - -namespace openage { - -class GameMainSignals : public QObject { - Q_OBJECT - -public: -signals: - void game_running(bool running); -}; - - -/** - * Class linked to the QML object "GameMain" via GameMainLink. - * Gets instanciated from QML. - */ -class GameMainHandle { -public: - explicit GameMainHandle(qtsdl::GuiItemLink *gui_link); - - /** - * End the game and delete the game handle. - */ - void clear(); - - /** - * Pass the given game to the engine and start it. - */ - void set_game(std::unique_ptr &&game); - - /** - * Return the game. - */ - GameMain *get_game() const; - - /** - * Test if there is a game running. - */ - bool is_game_running() const; - - /** - * Emit a qt signal to notify for changes in a running game. - */ - void announce_running(); - -private: - /** - * The game state as currently owned by the engine, - * just remembered here to access it quickly. - */ - GameMain *game; - -public: - GameMainSignals gui_signals; - qtsdl::GuiItemLink *gui_link; -}; - -} // namespace openage diff --git a/libopenage/gamestate/old/game_save.cpp b/libopenage/gamestate/old/game_save.cpp deleted file mode 100644 index 47d598530b..0000000000 --- a/libopenage/gamestate/old/game_save.cpp +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright 2015-2021 the openage authors. See copying.md for legal info. - -#include "game_save.h" - -#include -#include - -#include "version.h" -#include "../../log/log.h" -#include "../../terrain/terrain_chunk.h" -#include "../../unit/producer.h" -#include "../../unit/unit.h" -#include "../../unit/unit_type.h" -#include "../../versions/compiletime.h" -#include "game_main.h" -#include "game_save.h" -#include "game_spec.h" - -namespace openage::gameio { - -void save_unit(std::ofstream &file, Unit *unit) { - file << unit->unit_type->id() << std::endl; - file << unit->get_attribute().player.player_number << std::endl; - coord::tile pos = unit->location->pos.start; - file << pos.ne << " " << pos.se << std::endl; - - bool has_building_attr = unit->has_attribute(attr_type::building); - file << has_building_attr << std::endl; - if (has_building_attr) { - file << unit->get_attribute().completed << std::endl; - } -} - -void load_unit(std::ifstream &file, GameMain *game) { - int pr_id; - int player_no; - coord::tile_t ne, se; - file >> pr_id; - file >> player_no; - file >> ne; - file >> se; - - UnitType &saved_type = *game->get_player(player_no)->get_type(pr_id); - auto ref = game->placed_units.new_unit(saved_type, *game->get_player(player_no), coord::tile{ne, se}.to_phys3(*game->terrain)); - - bool has_building_attr; - file >> has_building_attr; - if (has_building_attr) { - float completed; - file >> completed; - if (completed >= 1.0f && ref.is_valid()) { - complete_building(*ref.get()); - } - } -} - -void save_tile_content(std::ofstream &file, openage::TileContent *content) { - file << content->terrain_id << std::endl; - file << content->obj.size() << std::endl; -} - -TileContent load_tile_content(std::ifstream &file) { - openage::TileContent content; - file >> content.terrain_id; - - unsigned int o_size; - file >> o_size; - return content; -} - -void save(openage::GameMain *game, const std::string &fname) { - std::ofstream file(fname, std::ofstream::out); - log::log(MSG(dbg) << "saving " + fname); - - // metadata - file << save_label << std::endl; - file << save_version << std::endl; - file << versions::engine_version << std::endl; - - // how many chunks - std::vector used = game->terrain->used_chunks(); - file << used.size() << std::endl; - - // save each chunk - for (coord::chunk &position : used) { - file << position.ne << " " << position.se << std::endl; - openage::TerrainChunk *chunk = game->terrain->get_chunk(position); - - file << chunk->tile_count << std::endl; - for (size_t p = 0; p < chunk->tile_count; ++p) { - save_tile_content( file, chunk->get_data(p) ); - } - } - - // save units - std::vector units = game->placed_units.all_units(); - file << units.size() << std::endl; - for (Unit *u : units) { - save_unit(file, u); - } -} - -void load(openage::GameMain *game, const std::string &fname) { - std::ifstream file(fname, std::ifstream::in); - if (!file.good()) { - log::log(MSG(dbg) << "could not find " + fname); - return; - } - log::log(MSG(dbg) << "loading " + fname); - - // load metadata - std::string file_label; - file >> file_label; - if (file_label != save_label) { - log::log(MSG(warn) << fname << " is not a savefile"); - return; - } - std::string version; - file >> version; - if (version != save_version) { - log::log(MSG(warn) << "savefile has different version"); - } - std::string build; - file >> build; - - // read terrain chunks - unsigned int num_chunks; - file >> num_chunks; - for (unsigned int c = 0; c < num_chunks; ++c) { - coord::chunk_t ne, se; - size_t tile_count; - file >> ne; - file >> se; - file >> tile_count; - openage::TerrainChunk *chunk = game->terrain->get_create_chunk(coord::chunk{ne, se}); - for (size_t p = 0; p < tile_count; ++p) { - *chunk->get_data(p) = load_tile_content( file ); - } - } - - game->placed_units.reset(); - unsigned int num_units; - file >> num_units; - for (unsigned int u = 0; u < num_units; ++u) { - load_unit( file, game ); - } -} - -} // openage::gameio diff --git a/libopenage/gamestate/old/game_save.h b/libopenage/gamestate/old/game_save.h deleted file mode 100644 index 36ddb49b82..0000000000 --- a/libopenage/gamestate/old/game_save.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015-2021 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -namespace openage { - -class GameMain; -class Terrain; - -namespace gameio { - -const std::string save_label = "openage-save-file"; -const std::string save_version = "v0.1"; - -/** - * a game save function that sometimes works - */ -void save(openage::GameMain *, const std::string &fname); - -/** - * a game load function that sometimes works - */ -void load(openage::GameMain *, const std::string &fname); - -}} // openage::gameio diff --git a/libopenage/gamestate/old/game_spec.cpp b/libopenage/gamestate/old/game_spec.cpp deleted file mode 100644 index c23ddcd0bd..0000000000 --- a/libopenage/gamestate/old/game_spec.cpp +++ /dev/null @@ -1,455 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "game_spec.h" - -#include - -#include "../../audio/error.h" -#include "../../audio/resource_def.h" -#include "../../gamedata/blending_mode_dummy.h" -#include "../../gamedata/string_resource_dummy.h" -#include "../../gamedata/terrain_dummy.h" -#include "../../log/log.h" -#include "../../rng/global_rng.h" -#include "../../unit/producer.h" -#include "../../util/compiler.h" -#include "../../util/strings.h" -#include "../../util/timer.h" -#include "civilisation.h" - - -namespace openage { - -GameSpec::GameSpec() : - gamedata_loaded{false} { -} - -GameSpec::~GameSpec() = default; - - -bool GameSpec::initialize() { - util::Timer load_timer; - load_timer.start(); - - // const util::Path &asset_dir = this->assetmanager->get_asset_dir(); - - // log::log(MSG(info) << "Loading game specification files..."); - - // std::vector string_resources = util::read_csv_file( - // asset_dir["converted/string_resources.docx"]); - - // try { - // // read the packed csv file - // util::CSVCollection raw_gamedata{ - // asset_dir["converted/gamedata/gamedata.docx"]}; - - // // parse the original game description files - // this->gamedata = raw_gamedata.read( - // "gamedata-empiresdat.docx"); - - // this->load_terrain(this->gamedata[0]); - - // // process and load the game description files - // this->on_gamedata_loaded(this->gamedata[0]); - // this->gamedata_loaded = true; - // } - // catch (Error &exc) { - // // rethrow allmighty openage exceptions - // throw; - // } - // catch (std::exception &exc) { - // // unfortunately we have no idea of the std::exception backtrace - // throw Error{ERR << "gamedata could not be loaded: " - // << util::typestring(exc) - // << ": " << exc.what()}; - // } - - log::log(MSG(info).fmt("Loading time [data]: %5.3f s", - load_timer.getval() / 1e9)); - return true; -} - -bool GameSpec::load_complete() const { - return this->gamedata_loaded; -} - -terrain_meta *GameSpec::get_terrain_meta() { - return &this->terrain_data; -} - -index_t GameSpec::get_slp_graphic(index_t slp) { - return this->slp_to_graphic[slp]; -} - -const Sound *GameSpec::get_sound(index_t sound_id) const { - if (this->available_sounds.count(sound_id) == 0) { - if (sound_id > 0) { - log::log(MSG(dbg) << " -> ignoring sound_id: " << sound_id); - } - return nullptr; - } - return &this->available_sounds.at(sound_id); -} - - -const gamedata::graphic *GameSpec::get_graphic_data(index_t grp_id) const { - if (this->graphics.count(grp_id) == 0) { - log::log(MSG(dbg) << " -> ignoring grp_id: " << grp_id); - return nullptr; - } - return this->graphics.at(grp_id); -} - -std::vector GameSpec::get_command_data(index_t unit_id) const { - if (this->commands.count(unit_id) == 0) { - return std::vector(); // empty vector - } - return this->commands.at(unit_id); -} - -std::string GameSpec::get_civ_name(int civ_id) const { - return this->gamedata[0].civs.data[civ_id].name; -} - -void GameSpec::create_unit_types(unit_meta_list &objects, int civ_id) const { - if (!this->load_complete()) { - return; - } - - // create projectile types first - for (auto &obj : this->gamedata[0].civs.data[civ_id].units.missile.data) { - this->load_missile(obj, objects); - } - - // create object unit types - for (auto &obj : this->gamedata[0].civs.data[civ_id].units.object.data) { - this->load_object(obj, objects); - } - - // create dead unit types - for (auto &unit : this->gamedata[0].civs.data[civ_id].units.moving.data) { - this->load_object(unit, objects); - } - - // create living unit types - for (auto &unit : this->gamedata[0].civs.data[civ_id].units.living.data) { - this->load_living(unit, objects); - } - - // create building unit types - for (auto &building : this->gamedata[0].civs.data[civ_id].units.building.data) { - this->load_building(building, objects); - } -} - -void GameSpec::on_gamedata_loaded(const gamedata::empiresdat &gamedata) { - // const util::Path &asset_dir = this->assetmanager->get_asset_dir(); - // util::Path sound_dir = asset_dir["converted/sounds"]; - - // // create graphic id => graphic map - // for (auto &graphic : gamedata.graphics.data) { - // this->graphics[graphic.graphic_id] = &graphic; - // this->slp_to_graphic[graphic.slp_id] = graphic.graphic_id; - // } - - // log::log(INFO << "Loading textures..."); - - // // create complete set of unit textures - // for (auto &g : this->graphics) { - // this->unit_textures.insert({g.first, std::make_shared(*this, g.second)}); - // } - - // log::log(INFO << "Loading sounds..."); - - // // playable sound files for the audio manager - // std::vector load_sound_files; - - // // all sounds defined in the game specification - // for (const gamedata::sound &sound : gamedata.sounds.data) { - // std::vector sound_items; - - // // each sound may have multiple variation, - // // processed in this loop - // // these are the single sound files. - // for (const gamedata::sound_item &item : sound.sound_items.data) { - // if (item.resource_id < 0) { - // log::log(SPAM << " Invalid sound resource id < 0"); - // continue; - // } - - // std::string snd_filename = util::sformat("%d.opus", item.resource_id); - // util::Path snd_path = sound_dir[snd_filename]; - - // if (not snd_path.is_file()) { - // continue; - // } - - // // single items for a sound (so that we can ramdomize it) - // sound_items.push_back(item.resource_id); - - // // the single sound will be loaded in the audio system. - // audio::resource_def resource{ - // audio::category_t::GAME, - // item.resource_id, - // snd_path, - // audio::format_t::OPUS, - // audio::loader_policy_t::DYNAMIC}; - // load_sound_files.push_back(resource); - // } - - - // // create test sound objects that can be played later - // this->available_sounds.insert({sound.sound_id, - // Sound{ - // this, - // std::move(sound_items)}}); - // } - - // // TODO: move out the loading of the sound. - // // this class only provides the names and locations - - // // load the requested sounds. - // audio::AudioManager &am = this->assetmanager->get_display()->get_audio_manager(); - // am.load_resources(load_sound_files); - - // // this final step occurs after loading media - // // as producers require both the graphics and sounds - // this->create_abilities(gamedata); -} - -bool GameSpec::valid_graphic_id(index_t graphic_id) const { - if (graphic_id <= 0 || this->graphics.count(graphic_id) == 0) { - return false; - } - if (this->graphics.at(graphic_id)->slp_id <= 0) { - return false; - } - return true; -} - -void GameSpec::load_building(const gamedata::building_unit &building, unit_meta_list &list) const { - // check graphics - if (this->valid_graphic_id(building.idle_graphic0)) { - auto meta_type = std::make_shared("Building", building.id0, [this, &building](const Player &owner) { - return std::make_shared(owner, *this, &building); - }); - list.emplace_back(meta_type); - } -} - -void GameSpec::load_living(const gamedata::living_unit &unit, unit_meta_list &list) const { - // check graphics - if (this->valid_graphic_id(unit.dying_graphic) && this->valid_graphic_id(unit.idle_graphic0) && this->valid_graphic_id(unit.move_graphics)) { - auto meta_type = std::make_shared("Living", unit.id0, [this, &unit](const Player &owner) { - return std::make_shared(owner, *this, &unit); - }); - list.emplace_back(meta_type); - } -} - -void GameSpec::load_object(const gamedata::unit_object &object, unit_meta_list &list) const { - // check graphics - if (this->valid_graphic_id(object.idle_graphic0)) { - auto meta_type = std::make_shared("Object", object.id0, [this, &object](const Player &owner) { - return std::make_shared(owner, *this, &object); - }); - list.emplace_back(meta_type); - } -} - -void GameSpec::load_missile(const gamedata::missile_unit &proj, unit_meta_list &list) const { - // check graphics - if (this->valid_graphic_id(proj.idle_graphic0)) { - auto meta_type = std::make_shared("Projectile", proj.id0, [this, &proj](const Player &owner) { - return std::make_shared(owner, *this, &proj); - }); - list.emplace_back(meta_type); - } -} - - -void GameSpec::load_terrain(const gamedata::empiresdat &gamedata) { - // fetch blending modes - // util::Path convert_dir = this->assetmanager->get_asset_dir()["converted"]; - // std::vector blending_meta = util::read_csv_file( - // convert_dir["blending_modes.docx"]); - - // // copy the terrain metainformation - // std::vector terrain_meta = gamedata.terrains.data; - - // // remove any disabled textures - // terrain_meta.erase( - // std::remove_if( - // terrain_meta.begin(), - // terrain_meta.end(), - // [](const gamedata::terrain_type &t) { - // return not t.enabled; - // }), - // terrain_meta.end()); - - // // result attributes - // this->terrain_data.terrain_id_count = terrain_meta.size(); - // this->terrain_data.blendmode_count = blending_meta.size(); - // this->terrain_data.textures.resize(terrain_data.terrain_id_count); - // this->terrain_data.blending_masks.reserve(terrain_data.blendmode_count); - // this->terrain_data.terrain_id_priority_map = std::make_unique( - // this->terrain_data.terrain_id_count); - // this->terrain_data.terrain_id_blendmode_map = std::make_unique( - // this->terrain_data.terrain_id_count); - // this->terrain_data.influences_buf = std::make_unique( - // this->terrain_data.terrain_id_count); - - - // log::log(MSG(dbg) << "Terrain prefs: " - // << "tiletypes=" << terrain_data.terrain_id_count << ", " - // "blendmodes=" - // << terrain_data.blendmode_count); - - // // create tile textures (snow, ice, grass, whatever) - // for (size_t terrain_id = 0; - // terrain_id < terrain_data.terrain_id_count; - // terrain_id++) { - // auto line = &terrain_meta[terrain_id]; - - // // TODO: terrain double-define check? - // terrain_data.terrain_id_priority_map[terrain_id] = line->blend_priority; - // terrain_data.terrain_id_blendmode_map[terrain_id] = line->blend_mode; - - // // TODO: remove hardcoding and rely on nyan data - // auto terraintex_filename = util::sformat("converted/terrain/%d.slp.png", - // line->slp_id); - - // auto new_texture = this->assetmanager->get_texture(terraintex_filename, true); - - // terrain_data.textures[terrain_id] = new_texture; - // } - - // // create blending masks (see doc/media/blendomatic) - // for (size_t i = 0; i < terrain_data.blendmode_count; i++) { - // auto line = &blending_meta[i]; - - // // TODO: remove hardcodingn and use nyan data - // std::string mask_filename = util::sformat("converted/blendomatic/mode%02d.png", - // line->blend_mode); - // terrain_data.blending_masks[i] = this->assetmanager->get_texture(mask_filename); - // } -} - - -void GameSpec::create_abilities(const gamedata::empiresdat &gamedata) { - // use game data unit commands - int headers = gamedata.unit_headers.data.size(); - int total = 0; - - // it seems the index of the header indicates the unit - for (int i = 0; i < headers; ++i) { - // init unit command vector - std::vector list; - - // add each element - auto &head = gamedata.unit_headers.data[i]; - for (auto &cmd : head.unit_commands.data) { - total++; - - // commands either have a class id or a unit id - // log::dbg("unit command %d %d -> class %d, unit %d, resource %d", i, cmd.id, cmd.class_id, cmd.unit_id, cmd.resource_in); - list.push_back(&cmd); - } - - // insert to command map - this->commands[i] = list; - } -} - - -void Sound::play() const { - if (this->sound_items.size() <= 0) { - return; - } - - int rand = rng::random_range(0, this->sound_items.size()); - int sndid = this->sound_items.at(rand); - - // try { - // // TODO: buhuuuu gnargghh this has to be moved to the asset loading subsystem hnnnng - // audio::AudioManager &am = this->game_spec->get_asset_manager()->get_display()->get_audio_manager(); - - // if (not am.is_available()) { - // return; - // } - - // audio::Sound sound = am.get_sound(audio::category_t::GAME, sndid); - // sound.play(); - // } - // catch (audio::Error &e) { - // log::log(MSG(warn) << "cannot play: " << e); - // } -} - -GameSpecHandle::GameSpecHandle(qtsdl::GuiItemLink *gui_link) : - active{}, - gui_signals{std::make_shared()}, - gui_link{gui_link} { -} - -void GameSpecHandle::set_active(bool active) { - this->active = active; - - this->start_loading_if_needed(); -} - -bool GameSpecHandle::is_ready() const { - return this->spec && this->spec->load_complete(); -} - -void GameSpecHandle::invalidate() { - this->spec = nullptr; - - this->start_loading_if_needed(); -} - -void GameSpecHandle::announce_spec() { - if (this->spec && this->spec->load_complete()) - emit this->gui_signals->game_spec_loaded(this->spec); -} - -std::shared_ptr GameSpecHandle::get_spec() { - return this->spec; -} - -void GameSpecHandle::start_loading_if_needed() { -} - -void GameSpecHandle::start_load_job() { - // store the shared pointers in another sharedptr - // so we can pass them to the other thread - auto spec_and_job = std::make_tuple(this->spec, this->gui_signals, job::Job{}); - auto spec_and_job_ptr = std::make_shared(spec_and_job); - - // lambda to be executed to actually load the data files. - auto perform_load = [spec_and_job_ptr] { - return std::get>(*spec_and_job_ptr)->initialize(); - }; - - auto load_finished = [gui_signals_ptr = this->gui_signals.get()](job::result_function_t result) { - bool load_ok; - try { - load_ok = result(); - } - catch (Error &) { - // TODO: display that error in the ui. - throw; - } - catch (std::exception &) { - // TODO: same here. - throw Error{ERR << "gamespec loading failed!"}; - } - - if (load_ok) { - // send the signal that the load job was finished - emit gui_signals_ptr->load_job_finished(); - } - }; -} - -} // namespace openage diff --git a/libopenage/gamestate/old/game_spec.h b/libopenage/gamestate/old/game_spec.h deleted file mode 100644 index 0e03eb73a5..0000000000 --- a/libopenage/gamestate/old/game_spec.h +++ /dev/null @@ -1,290 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include "../../gamedata/gamedata_dummy.h" -#include "../../gamedata/graphic_dummy.h" -#include "../../job/job.h" -#include "../../util/csv.h" -#include "terrain/terrain.h" -#include "types.h" - -#include -#include -#include - - -namespace openage { - -class LegacyAssetManager; -class GameSpec; -class UnitType; -class UnitTypeMeta; -class Player; - - -/** - * could use unique ptr - */ -using unit_type_list = std::vector>; -using unit_meta_list = std::vector>; - - -/** - * simple sound object - * TODO: move to assetmanager - */ -class Sound { -public: - Sound(GameSpec *spec, std::vector &&sound_items) : - sound_items{sound_items}, - game_spec{spec} {} - - void play() const; - - std::vector sound_items; - - GameSpec *game_spec; -}; - - -/** - * GameSpec gives a collection of all game elements - * this currently includes unit types and terrain types - * This provides a system which can easily allow game modding - * - * uses the LegacyAssetManager to gather - * graphic data, composite textures and sounds. - * - * all types are sorted and stored by id values, - * each data object is referenced by a type and id pair - * - * dealing directly with files done by asset manager - * TODO: should the audio loading should be moved there? - */ -class GameSpec { -public: - GameSpec(); - virtual ~GameSpec(); - - /** - * perform the main loading job. - * this loads all the data into the storage. - */ - bool initialize(); - - /** - * Check if loading has been completed, - * a load percent would be nice - */ - bool load_complete() const; - - /** - * return data used for constructing terrain objects - */ - terrain_meta *get_terrain_meta(); - - /** - * reverse lookup of slp - */ - index_t get_slp_graphic(index_t slp); - - /** - * get sound by sound id - */ - const Sound *get_sound(index_t sound_id) const; - - /** - * gamedata for a graphic - * nyan will have to replace this somehow - */ - const gamedata::graphic *get_graphic_data(index_t grp_id) const; - - /** - * get available commands for a unit id - * nyan will have to replace this somehow - */ - std::vector get_command_data(index_t unit_id) const; - - /** - * returns the name of a civ by index - */ - std::string get_civ_name(int civ_id) const; - - /** - * makes initial unit types for a particular civ id - */ - void create_unit_types(unit_meta_list &objects, int civ_id) const; - -private: - /** - * check graphic id is valid - */ - bool valid_graphic_id(index_t) const; - - /** - * create unit abilities from game data - */ - void create_abilities(const gamedata::empiresdat &gamedata); - - /** - * loads required assets to construct a buildings. - * adds to the type list if the object can be created safely. - */ - void load_building(const gamedata::building_unit &, unit_meta_list &) const; - - /** - * loads assets for living things. - */ - void load_living(const gamedata::living_unit &, unit_meta_list &) const; - - /** - * load assets for other game objects (not building and living). - */ - void load_object(const gamedata::unit_object &, unit_meta_list &) const; - - /** - * load missile assets. - */ - void load_missile(const gamedata::missile_unit &, unit_meta_list &) const; - - /** - * fill in the terrain_data attribute of this - */ - void load_terrain(const gamedata::empiresdat &gamedata); - - /** - * Invoked when the gamedata has been loaded. - */ - void on_gamedata_loaded(const gamedata::empiresdat &gamedata); - - /** - * The full original gamedata tree. - */ - std::vector gamedata; - - /** - * data used for constructing terrain objects - */ - terrain_meta terrain_data; - - /** - * slp to graphic id reverse lookup - */ - std::unordered_map slp_to_graphic; - - /** - * map graphic id to gamedata graphic. - */ - std::unordered_map graphics; - - /** - * commands available for each unit id - */ - std::unordered_map> commands; - - /** - * sound ids mapped to playable sounds for all available sounds. - */ - std::unordered_map available_sounds; - - /** - * has game data been load yet - */ - bool gamedata_loaded; -}; - -} // namespace openage - -namespace qtsdl { -class GuiItemLink; -} // namespace qtsdl - -namespace openage { - -class GameSpecSignals; - -/** - * Game specification instanciated in QML. - * Linked to the "GameSpec" QML type. - * - * Wraps the "GameSpec" C++ class from above. - */ -class GameSpecHandle { -public: - explicit GameSpecHandle(qtsdl::GuiItemLink *gui_link); - - /** - * Control whether this specification can be loaded (=true) - * or will not be loaded (=false). - */ - void set_active(bool active); - - /** - * Return if the specification was fully loaded. - */ - bool is_ready() const; - - /** - * forget everything about the specification and - * reload it with `start_loading_if_needed`. - */ - void invalidate(); - - /** - * signal about a loaded spec if any - */ - void announce_spec(); - - /** - * Return the contained game specification. - */ - std::shared_ptr get_spec(); - -private: - /** - * load the game specification if not already present. - */ - void start_loading_if_needed(); - - /** - * Actually dispatch the loading job to the job manager. - */ - void start_load_job(); - - /** - * called from the job manager when the loading job finished. - */ - void on_loaded(job::result_function_t result); - - /** - * The real game specification. - */ - std::shared_ptr spec; - - /** - * enables the loading of the game specification. - */ - bool active; - -public: - std::shared_ptr gui_signals; - qtsdl::GuiItemLink *gui_link; -}; - -class GameSpecSignals : public QObject { - Q_OBJECT - -public: -signals: - /* - * Some load job has finished. - * - * To be sure that the latest result is used, do the verification at the point of use. - */ - void load_job_finished(); - - void game_spec_loaded(std::shared_ptr loaded_game_spec); -}; - -} // namespace openage diff --git a/libopenage/gamestate/old/generator.cpp b/libopenage/gamestate/old/generator.cpp deleted file mode 100644 index b60ce1ffd7..0000000000 --- a/libopenage/gamestate/old/generator.cpp +++ /dev/null @@ -1,323 +0,0 @@ -// Copyright 2015-2021 the openage authors. See copying.md for legal info. - -#include "generator.h" - -#include "../../log/log.h" -#include "../../rng/rng.h" -#include "../../terrain/terrain_chunk.h" -#include "../../unit/unit.h" -#include "../../util/math_constants.h" -#include "game_main.h" -#include "game_save.h" -#include "game_spec.h" - - -namespace openage { - -coord::tile random_tile(rng::RNG &rng, tileset_t tiles) { - if (tiles.empty()) { - log::log(MSG(err) << "random tile failed"); - return coord::tile{0, 0}; - } - uint64_t index = rng.random() % tiles.size(); - auto it = std::begin(tiles); - std::advance(it, index); - return *it; -} - - -Region::Region(int size) - : - owner{0}, - object_id{0}, - terrain_id{0}, - center{0, 0} { - for (int ne = -size; ne < size; ++ne) { - for (int se = -size; se < size; ++se) { - this->tiles.emplace(coord::tile{ne, se}); - } - } -} - -Region::Region(coord::tile center, tileset_t tiles) - : - owner{0}, - object_id{0}, - terrain_id{0}, - center(center), - tiles{tiles} { -} - -tileset_t Region::get_tiles() const { - return this->tiles; -} - -coord::tile Region::get_center() const { - return this->center; -} - -coord::tile Region::get_tile(rng::RNG &rng) const { - return random_tile(rng, this->tiles); -} - - -tileset_t Region::subset(rng::RNG &rng, coord::tile start_point, unsigned int number, double p) const { - if (p == 0.0) { - return tileset_t(); - } - - // the set of included tiles - std::unordered_set subtiles; - subtiles.emplace(start_point); - - // outside layer of tiles - std::unordered_set edge_set; - - while (subtiles.size() < number) { - if (edge_set.empty()) { - - // try fill the edge list - for (auto &t : subtiles) { - - // check adjacent tiles - for (int i = 0; i < 4; ++i) { - coord::tile adj = t + neigh_tiles[i]; - if (this->tiles.count(adj) && - !subtiles.count(adj)) { - edge_set.emplace(adj); - } - } - } - if (edge_set.empty()) { - - // unable to grow further - return subtiles; - } - } - - // transfer a random tile - coord::tile next_tile = random_tile(rng, edge_set); - edge_set.erase(next_tile); - if (rng.probability(p)) { - subtiles.emplace(next_tile); - } - } - return subtiles; -} - -Region Region::take_tiles(rng::RNG &rng, coord::tile start_point, unsigned int number, double p) { - - tileset_t new_set = this->subset(rng, start_point, number, p); - - // erase from current set - for (auto &t: new_set) { - this->tiles.erase(t); - } - - Region new_region(start_point, new_set); - new_region.terrain_id = this->terrain_id; - return new_region; -} - -Region Region::take_random(rng::RNG &rng, unsigned int number, double p) { - return this->take_tiles(rng, this->get_tile(rng), number, p); -} - -Generator::Generator(qtsdl::GuiItemLink *gui_link) - : - gui_link{gui_link} -{ - this->setv("generation_seed", 4321); - this->setv("terrain_size", 2); - this->setv("terrain_base_id", 0); - this->setv("player_area", 850); - this->setv("player_radius", 10); - this->setv("load_filename", "/tmp/default_save.oas"); - this->setv("from_file", false); - // TODO pick the users name - this->set_csv("player_names", std::vector{"Jonas", "Michael"}); -} - -std::shared_ptr Generator::get_spec() const { - return this->spec; -} - -std::vector Generator::player_names() const { - auto result = this->get_csv("player_names"); - - // gaia is player 0 - result.insert(result.begin(), "Gaia"); - - return result; -} - -void Generator::create_regions() { - - // get option settings - int seed = this->getv("generation_seed"); - int size = this->getv("terrain_size"); - int base_id = this->getv("terrain_base_id"); - int p_area = this->getv("player_area"); - int p_radius = this->getv("player_radius"); - - // enforce some lower limits - size = std::max(1, size); - base_id = std::max(0, base_id); - p_area = std::max(50, p_area); - p_radius = std::max(2, p_radius); - - rng::RNG rng(seed); - Region base(size * 16); - base.terrain_id = base_id; - std::vector player_regions; - - int player_count = this->player_names().size() - 1; - for (int i = 0; i < player_count; ++i) { - log::log(MSG(dbg) << "generate player " << i); - - // space players in a circular pattern - double angle = static_cast(i) / static_cast(player_count); - int ne = size * p_radius * sin(math::TAU * angle); - int se = size * p_radius * cos(math::TAU * angle); - coord::tile player_tile{ne, se}; - - Region player = base.take_tiles(rng, player_tile, p_area, 0.5); - player.terrain_id = 10; - - Region obj_space = player.take_tiles(rng, player.get_center(), p_area / 5, 0.5); - obj_space.owner = i + 1; - obj_space.terrain_id = 8; - - Region trees1 = player.take_random(rng, p_area / 10, 0.3); - trees1.terrain_id = 9; - trees1.object_id = 349; - - Region trees2 = player.take_random(rng, p_area / 10, 0.3); - trees2.terrain_id = 9; - trees2.object_id = 351; - - Region stone = player.take_random(rng, 5, 0.3); - stone.object_id = 102; - - Region gold = player.take_random(rng, 7, 0.3); - gold.object_id = 66; - - Region forage = player.take_random(rng, 6, 0.3); - forage.object_id = 59; - - Region sheep = player.take_random(rng, 4, 0.3); - sheep.owner = obj_space.owner; - sheep.object_id = 594; - - player_regions.push_back(player); - player_regions.push_back(obj_space); - player_regions.push_back(trees1); - player_regions.push_back(trees2); - player_regions.push_back(stone); - player_regions.push_back(gold); - player_regions.push_back(forage); - player_regions.push_back(sheep); - } - - for (int i = 0; i < 6; ++i) { - Region extra_trees = base.take_random(rng, 160, 0.3); - extra_trees.terrain_id = 9; - extra_trees.object_id = 349; - player_regions.push_back(extra_trees); - } - - // set regions - this->regions.clear(); - this->regions.push_back(base); - for (auto &r : player_regions) { - this->regions.push_back(r); - } -} - - -std::shared_ptr Generator::terrain() const { - auto terrain = std::make_shared(this->spec->get_terrain_meta(), true); - for (auto &r : this->regions) { - for (auto &tile : r.get_tiles()) { - TerrainChunk *chunk = terrain->get_create_chunk(tile); - chunk->get_data(tile.get_pos_on_chunk())->terrain_id = r.terrain_id; - } - } - - // mark the 0, 0 tile. - coord::tile debug_tile_pos{0, 0}; - terrain->get_data(debug_tile_pos)->terrain_id = 6; - return terrain; -} - -void Generator::add_units(GameMain &m) const { - for (auto &r : this->regions) { - - // Regions filled with resource objects - // trees / mines - if (r.object_id) { - Player* p = m.get_player(r.owner); - auto otype = p->get_type(r.object_id); - if (!otype) { - break; - } - for (auto &tile : r.get_tiles()) { - m.placed_units.new_unit(*otype, *p, tile.to_phys3(*m.terrain)); - } - } - - // A space for starting town center and villagers - else if (r.owner) { - Player* p = m.get_player(r.owner); - auto tctype = p->get_type(109); // town center - auto mvtype = p->get_type(83); // male villager - auto fvtype = p->get_type(293); // female villager - auto sctype = p->get_type(448); // scout cavarly - if (!tctype || !mvtype || !fvtype || !sctype) { - break; - } - - coord::tile tile = r.get_center(); - tile.ne -= 1; - tile.se -= 1; - - // Place a completed town center - auto ref = m.placed_units.new_unit(*tctype, *p, tile.to_phys3(*m.terrain)); - if (ref.is_valid()) { - complete_building(*ref.get()); - } - - // Place three villagers - tile.ne -= 1; - m.placed_units.new_unit(*fvtype, *p, tile.to_phys3(*m.terrain)); - tile.se += 1; - m.placed_units.new_unit(*mvtype, *p, tile.to_phys3(*m.terrain)); - tile.se += 1; - m.placed_units.new_unit(*fvtype, *p, tile.to_phys3(*m.terrain)); - // TODO uncomment when the scout looks better - //tile.se += 2; - //m.placed_units.new_unit(*sctype, *p, tile.to_tile3().to_phys3()); - } - } -} - -std::unique_ptr Generator::create(std::shared_ptr spec) { - ENSURE(spec->load_complete(), "spec hasn't been checked or was invalidated"); - this->spec = spec; - - if (this->getv("from_file")) { - // create an empty game - this->regions.clear(); - - auto game = std::make_unique(*this); - gameio::load(game.get(), this->getv("load_filename")); - - return game; - } else { - // generation - this->create_regions(); - return std::make_unique(*this); - } -} - -} // namespace openage diff --git a/libopenage/gamestate/old/generator.h b/libopenage/gamestate/old/generator.h deleted file mode 100644 index a2d4bf58b7..0000000000 --- a/libopenage/gamestate/old/generator.h +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "../../coord/tile.h" -#include "../../gui/guisys/public/gui_property_map.h" - -namespace qtsdl { -class GuiItemLink; -} // qtsdl - -namespace openage { - -class GameSpec; -class Terrain; -class GameMain; - -namespace rng { -class RNG; -} // openage::rng - -/** - * the type to store a set of tiles - */ -using tileset_t = std::unordered_set; - -/** - * picks a random tile from a set - */ -coord::tile random_tile(rng::RNG &rng, tileset_t tiles); - -/** - * the four directions available for 2d tiles - */ -constexpr coord::tile_delta const neigh_tiles[] = { - { 1, 0}, - {-1, 0}, - { 0, 1}, - { 0, -1} -}; - -/** - * A region is a set of tiles around a starting point, - * including functions to create child regions - */ -class Region { -public: - /** - * a square of tiles ranging from - * {-size, -size} to {size, size} - */ - Region(int size); - - /** - * a specified set of tiles - */ - Region(coord::tile center, tileset_t tiles); - - /** - * all tiles in this region - */ - tileset_t get_tiles() const; - - /** - * the center point of the region - */ - coord::tile get_center() const; - - /** - * picks a random tile from this subset - */ - coord::tile get_tile(rng::RNG &rng) const; - - /** - * find a group of tiles inside this region, number is the number of tiles to be contained - * in the subset, p is a probability between 0.0 and 1.0 which produces various shapes. a value - * of 1.0 produces circular shapes, where as a low value produces more scattered shapes. a value - * of 0.0 should not be used, and will always return no tiles - */ - tileset_t subset(rng::RNG &rng, coord::tile start_tile, unsigned int number, double p) const; - - /** - * removes the given set of tiles from this region, which get split of as a new child region - */ - Region take_tiles(rng::RNG &rng, coord::tile start_tile, unsigned int number, double p); - - /** - * similiar to take_tiles, but takes a random group of tiles - */ - Region take_random(rng::RNG &rng, unsigned int number, double p); - - /** - * player id of the owner, 0 for none - */ - int owner; - - /** - * the object to be placed on each tile of this region - * 0 for placing no object - */ - int object_id; - - /** - * the base terrain for this region - */ - int terrain_id; - -private: - - /** - * the center tile of this region - */ - coord::tile center; - - /** - * tiles in this region - */ - tileset_t tiles; -}; - - -/** - * Manages creation and setup of new games - * - * required values used to construct a game - * this includes game spec and players - * - * this will be identical for each networked - * player in a game - */ -class Generator : public qtsdl::GuiPropertyMap { -public: - explicit Generator(qtsdl::GuiItemLink *gui_link); - - /** - * game spec used by this generator - */ - std::shared_ptr get_spec() const; - - /** - * return the list of player names - */ - std::vector player_names() const; - - /** - * returns the generated terrain - */ - std::shared_ptr terrain() const; - - /** - * places all initial objects - */ - void add_units(GameMain &m) const; - - /** - * Create a game from a specification. - */ - std::unique_ptr create(std::shared_ptr spec); - -private: - void create_regions(); - - /** - * data version used to create a game - */ - std::shared_ptr spec; - - /** - * the generated data - */ - std::vector regions; - -public: - qtsdl::GuiItemLink *gui_link; -}; - -} // namespace openage diff --git a/libopenage/gamestate/old/market.cpp b/libopenage/gamestate/old/market.cpp deleted file mode 100644 index 4b1d50bc24..0000000000 --- a/libopenage/gamestate/old/market.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2017-2019 the openage authors. See copying.md for legal info. - -#include "player.h" -#include "market.h" - -namespace openage { - -Market::Market() { - // the default prices when a game starts - this->base_prices[game_resource::wood] = 100; - this->base_prices[game_resource::food] = 100; - this->base_prices[game_resource::stone] = 130; -} - -// Price calculation is documented at doc/reverse_engineering/market.md#prices - -bool Market::sell(Player &player, const game_resource res) { - // deduct the standard MARKET_TRANSACTION_AMOUNT of the selling res - if (player.deduct(res, MARKET_TRANSACTION_AMOUNT)) { - // if deduct was successful - // calc the gold received from selling MARKET_TRANSACTION_AMOUNT of res - double amount = this->get_sell_prices(player).get(res); - player.receive(game_resource::gold, amount); - - // decrease the price - this->base_prices[res] -= MARKET_PRICE_D; - if (this->base_prices.get(res) < MARKET_PRICE_MIN) { - this->base_prices[res] = MARKET_PRICE_MIN; - } - return true; - } - return false; -} - -bool Market::buy(Player &player, const game_resource res) { - // calc the gold needed to buy MARKET_TRANSACTION_AMOUNT of res - double price = this->get_buy_prices(player).get(res); - if (player.deduct(game_resource::gold, price)) { - // if deduct was successful - player.receive(res, MARKET_TRANSACTION_AMOUNT); - - // increase the price - this->base_prices[res] += MARKET_PRICE_D; - if (this->base_prices.get(res) > MARKET_PRICE_MAX) { - this->base_prices[res] = MARKET_PRICE_MAX; - } - return true; - } - return false; -} - -ResourceBundle Market::get_buy_prices(const Player &player) const { - return this->get_prices(player, true); -} - -ResourceBundle Market::get_sell_prices(const Player &player) const { - return this->get_prices(player, false); -} - -ResourceBundle Market::get_prices(const Player &player, const bool is_buy) const { - double mult = this->get_multiplier(player, is_buy); - - auto rb = ResourceBundle(this->base_prices); - rb *= mult; - rb.round(); // round to nearest integer - return rb; -} - -double Market::get_multiplier(const Player &/*player*/, const bool is_buy) const { - double base = 0.3; - // TODO change multiplier based on civ bonuses and player researched techs - double mult = base; - - if (is_buy) { - mult = 1 + mult; - } - else { - mult = 1 - mult; - } - - return mult; -} - -} // openage diff --git a/libopenage/gamestate/old/market.h b/libopenage/gamestate/old/market.h deleted file mode 100644 index 643668fe59..0000000000 --- a/libopenage/gamestate/old/market.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2017-2019 the openage authors. See copying.md for legal info. - -#pragma once - -#include "resource.h" - -namespace openage { - -class Player; - -constexpr double MARKET_PRICE_D = 3.0; -constexpr double MARKET_PRICE_MIN = 20.0; -constexpr double MARKET_PRICE_MAX = 9999.0; -constexpr double MARKET_TRANSACTION_AMOUNT = 100.0; - -/** - * The global market prices. - * - * Price calculation is documented at doc/reverse_engineering/market.md#prices - */ -class Market { -public: - Market(); - - /** - * The given player sells the given resource for gold. - * Returns true when the transaction is successful. - */ - bool sell(Player &player, const game_resource res); - - /** - * The given player buys the given resource with gold. - * Returns true when the transaction is successful. - */ - bool buy(Player &player, const game_resource res); - - /** - * Get the selling prices for a given player. - */ - ResourceBundle get_buy_prices(const Player &player) const; - - /** - * Get the buying prices for a given player. - */ - ResourceBundle get_sell_prices(const Player &player) const; - -protected: - - /** - * The getBuyPrices and getSellPrices are redirected here. - */ - ResourceBundle get_prices(const Player &player, const bool is_buy) const; - - /** - * Get the multiplier for the base prices - */ - double get_multiplier(const Player &player, const bool is_buy) const; - -private: - - /** - * Stores the base price values of each resource. - * - * The ResourceBundle is used to represent the prices instead of the amounts - * for each resource. - */ - ResourceBundle base_prices; - -}; - -} // openage diff --git a/libopenage/gamestate/old/player.cpp b/libopenage/gamestate/old/player.cpp deleted file mode 100644 index ed6bd9e8b9..0000000000 --- a/libopenage/gamestate/old/player.cpp +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright 2015-2018 the openage authors. See copying.md for legal info. - -#include "player.h" - -#include - -#include "../../log/log.h" -#include "../../unit/unit.h" -#include "../../unit/unit_type.h" -#include "../../util/math_constants.h" -#include "team.h" - - -namespace openage { - -Player::Player(Civilisation *civ, unsigned int number, std::string name) - : - player_number{number}, - color{number}, - civ{civ}, - name{std::move(name)}, - team{nullptr}, - population{0, 200}, // TODO change, get population cap max from game options - score{this}, - age{1} { // TODO change, get starting age from game options - // starting resources - // TODO change, get starting resources from game options - this->resources.set_all(1000); - // TODO change, get starting resources capacity from game options or nyan - this->resources_capacity.set_all(math::DOUBLE_INF / 2); // half to avoid overflows - this->on_resources_change(); -} - -bool Player::operator ==(const Player &other) const { - return this->player_number == other.player_number; -} - -bool Player::is_enemy(const Player &other) const { - - return !this->is_ally(other); -} - -bool Player::is_ally(const Player &other) const { - - if (this->player_number == other.player_number) { - return true; // same player - } - - if (this->team && this->team->is_member(other)) { - return true; // same team - } - - // everyone else is enemy - return false; -} - -bool Player::owns(Unit &unit) const { - if (unit.has_attribute(attr_type::owner)) { - return this == &unit.get_attribute().player; - } - return false; -} - -void Player::receive(const ResourceBundle& amount) { - this->resources += amount; - this->on_resources_change(); -} - -void Player::receive(const game_resource resource, double amount) { - this->resources[resource] += amount; - this->on_resources_change(); -} - -bool Player::can_receive(const ResourceBundle& amount) const { - return this->resources_capacity.has(this->resources, amount); -} - -bool Player::can_receive(const game_resource resource, double amount) const { - return this->resources_capacity.get(resource) >= this->resources.get(resource) + amount; -} - -bool Player::deduct(const ResourceBundle& amount) { - if (this->resources.deduct(amount)) { - this->on_resources_change(); - return true; - } - return false; -} - -bool Player::deduct(const game_resource resource, double amount) { - if (this->resources[resource] >= amount) { - this->resources[resource] -= amount; - this->on_resources_change(); - return true; - } - return false; -} - -bool Player::can_deduct(const ResourceBundle& amount) const { - return this->resources.has(amount); -} - -bool Player::can_deduct(const game_resource resource, double amount) const { - return this->resources.get(resource) >= amount; -} - -double Player::amount(const game_resource resource) const { - return this->resources.get(resource); -} - -bool Player::can_make(const UnitType &type) const { - return this->can_deduct(type.cost.get(*this)) && - this->get_units_have(type.id()) + this->get_units_pending(type.id()) < type.have_limit && - this->get_units_had(type.id()) + this->get_units_pending(type.id()) < type.had_limit; -} - -size_t Player::type_count() { - return this->available_ids.size(); -} - -UnitType *Player::get_type(index_t type_id) const { - if (this->available_ids.count(type_id) == 0) { - if (type_id > 0) { - log::log(MSG(info) << " -> ignoring type_id: " << type_id); - } - return nullptr; - } - return this->available_ids.at(type_id); -} - -UnitType *Player::get_type_index(size_t type_index) const { - if (type_index < available_objects.size()) { - return available_objects.at(type_index).get(); - } - log::log(MSG(info) << " -> ignoring type_index: " << type_index); - return nullptr; -} - - -void Player::initialise_unit_types() { - log::log(MSG(info) << name << " has civilisation " << this->civ->civ_name); - for (auto &type : this->civ->object_meta()) { - auto shared_type = type->init(*this); - index_t id = shared_type->id(); - this->available_objects.emplace_back(shared_type); - this->available_ids[id] = shared_type.get(); - } -} - -void Player::active_unit_added(Unit *unit, bool from_pending) { - // check if unit is actually active - if (this->is_unit_pending(unit)) { - this->units_pending[unit->unit_type->id()] += 1; - return; - } - - if (from_pending) { - this->units_pending[unit->unit_type->id()] -= 1; - } - - this->units_have[unit->unit_type->id()] += 1; - this->units_had[unit->unit_type->id()] += 1; - // TODO handle here building dependencies - - // population - if (unit->has_attribute(attr_type::population)) { - auto popul = unit->get_attribute(); - if (popul.demand > 0) { - this->population.demand_population(popul.demand); - } - if (popul.capacity > 0) { - this->population.add_capacity(popul.capacity); - } - } - - // resources capacity - if (unit->has_attribute(attr_type::storage)) { - auto storage = unit->get_attribute(); - this->resources_capacity += storage.capacity; - this->on_resources_change(); - } - - // score - // TODO improve selectors - if (unit->unit_type->id() == 82 || unit->unit_type->id() == 276) { // Castle, Wonder - this->score.add_score(score_category::society, unit->unit_type->cost.get(*this).sum() * 0.2); - } else if (unit->has_attribute(attr_type::building) || unit->has_attribute(attr_type::population)) { // building, living - this->score.add_score(score_category::economy, unit->unit_type->cost.get(*this).sum() * 0.2); - } - - // TODO handle here on create unit triggers - // TODO check for unit based win conditions -} - -void Player::active_unit_removed(Unit *unit) { - // check if unit is actually active - if (this->is_unit_pending(unit)) { - this->units_pending[unit->unit_type->id()] -= 1; - return; - } - - this->units_have[unit->unit_type->id()] -= 1; - // TODO handle here building dependencies - - // population - if (unit->has_attribute(attr_type::population)) { - auto popul = unit->get_attribute(); - if (popul.demand > 0) { - this->population.free_population(popul.demand); - } - if (popul.capacity > 0) { - this->population.remove_capacity(popul.capacity); - } - } - - // resources capacity - if (unit->has_attribute(attr_type::storage)) { - auto storage = unit->get_attribute(); - this->resources_capacity -= storage.capacity; - this->on_resources_change(); - } - - // score - // TODO improve selectors - if (unit->unit_type->id() == 82 || unit->unit_type->id() == 276) { // Castle, Wonder - // nothing - } else if (unit->has_attribute(attr_type::building) || unit->has_attribute(attr_type::population)) { // building, living - this->score.remove_score(score_category::economy, unit->unit_type->cost.get(*this).sum() * 0.2); - } - - // TODO handle here on death unit triggers - // TODO check for unit based win conditions -} - -void Player::killed_unit(const Unit & unit) { - // score - this->score.add_score(score_category::military, unit.unit_type->cost.get(*this).sum() * 0.2); -} - -void Player::advance_age() { - this->age += 1; -} - -void Player::on_resources_change() { - - // capacity overflow - if (! (this->resources_capacity >= this->resources_capacity)) { - this->resources.limit(this->resources_capacity); - } - - // score - this->score.update_resources(this->resources); - - // TODO check for resource based win conditions -} - -int Player::get_units_have(int type_id) const { - if (this->units_have.count(type_id)) { - return this->units_have.at(type_id); - } - return 0; -} - -int Player::get_units_had(int type_id) const { - if (this->units_had.count(type_id)) { - return this->units_had.at(type_id); - } - return 0; -} - -int Player::get_units_pending(int type_id) const { - if (this->units_pending.count(type_id)) { - return this->units_pending.at(type_id); - } - return 0; -} - -bool Player::is_unit_pending(Unit *unit) const { - // TODO check aslo if unit is training - return unit->has_attribute(attr_type::building) && unit->get_attribute().completed < 1.0f; -} - -int Player::get_workforce_count() const { - // TODO get all units tagged as work force - return this->units_have.at(83) + this->units_have.at(293) + // villagers - this->units_have.at(13) + // fishing ship - this->units_have.at(128) + // trade cart - this->units_have.at(545); // transport ship -} - -} // openage diff --git a/libopenage/gamestate/old/player.h b/libopenage/gamestate/old/player.h deleted file mode 100644 index 469a6c1f98..0000000000 --- a/libopenage/gamestate/old/player.h +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -#include "civilisation.h" -#include "population_tracker.h" -#include "resource.h" -#include "score.h" - - -namespace openage { - -class Unit; -class Team; - -class Player { -public: - Player(Civilisation *civ, unsigned int number, std::string name); - - /** - * values 0 .. player count - 1 - */ - const unsigned int player_number; - - /** - * values 1 .. player count - * would be better to have rgb color value - */ - const unsigned int color; - - /** - * civilisation and techs of this player - */ - const Civilisation *civ; - - /** - * visible name of this player - */ - const std::string name; - - /** - * the team of this player - * nullptr if member of no team - */ - Team *team; - - /** - * checks if two players are the same - */ - bool operator ==(const Player &other) const; - - /** - * the specified player is an enemy of this player - */ - bool is_enemy(const Player &) const; - - /** - * the specified player is an ally of this player - */ - bool is_ally(const Player &) const; - - /** - * this player owns the specified unit - */ - bool owns(Unit &) const; - - /** - * add to stockpile - */ - void receive(const ResourceBundle& amount); - void receive(const game_resource resource, double amount); - - /** - * Check if can add to stockpile - */ - bool can_receive(const ResourceBundle& amount) const; - bool can_receive(const game_resource resource, double amount) const; - - /** - * remove from stockpile if available - */ - bool deduct(const ResourceBundle& amount); - bool deduct(const game_resource resource, double amount); - - /** - * Check if the player has enough resources to deduct the given amount. - */ - bool can_deduct(const ResourceBundle& amount) const; - bool can_deduct(const game_resource resource, double amount) const; - - /** - * current stockpile amount - */ - double amount(const game_resource resource) const; - - /** - * Check if the player can make a new unit of the given type - */ - bool can_make(const UnitType &type) const; - - /** - * total number of unit types available - */ - size_t type_count(); - - /** - * unit types by aoe gamedata unit ids -- the unit type which corresponds to an aoe unit id - */ - UnitType *get_type(index_t type_id) const; - - /** - * unit types by list index -- a continuous array of all types - * probably not a useful function / can be removed - */ - UnitType *get_type_index(size_t type_index) const; - - /** - * initialise with the base tech level - */ - void initialise_unit_types(); - - /** - * Keeps track of the population information. - */ - PopulationTracker population; - - /** - * The score of the player. - */ - PlayerScore score; - - /** - * Called when a unit is created and active. - * - * If the unit was pending when create (constuction site, training) the method must be - * called again when the unit activates (with the from_penging param set to true) - */ - void active_unit_added(Unit *unit, bool from_pending=false); - - /** - * Called when a unit is destroyed. - */ - void active_unit_removed(Unit *unit); - - /** - * Called when a unit is killed by this player. - */ - void killed_unit(const Unit & unit); - - /** - * Advance to next age; - */ - void advance_age(); - - // Getters - - /** - * Get the number of units the player has for each unit type id. - */ - int get_units_have(int type_id) const; - - /** - * Get the number of units the player ever had for each unit type id. - */ - int get_units_had(int type_id) const; - - /** - * Get the number of units the player has being made for each unit type id. - */ - int get_units_pending(int type_id) const; - - /** - * Get the current age. - * The first age has the value 1. - */ - int get_age() const { return age; } - - /** - * The number of units considered part of the workforce. - */ - int get_workforce_count() const; - - -private: - - bool is_unit_pending(Unit *unit) const; - - /** - * The resources this player currently has - */ - ResourceBundle resources; - - /** - * The resources capacities this player currently has - */ - ResourceBundle resources_capacity; - - /** - * Called when the resources amounts change. - */ - void on_resources_change(); - - /** - * unit types which can be produced by this player. - * TODO revisit, can be simplified? - */ - unit_type_list available_objects; - - /** - * available objects mapped using type id - * unit ids -> unit type for that id - * TODO revisit, can be simplified? - */ - std::unordered_map available_ids; - - /** - * The number of units the player has for each unit type id. - * Used for and event triggers. - */ - std::unordered_map units_have; - - /** - * The number of units the player ever had for each unit type id. - * Used for unit dependencies (eg. Farm). - */ - std::unordered_map units_had; - - /* - * The number of units the player has being made for each unit type id. - * Used for unit limits (eg. Town Center). - */ - std::unordered_map units_pending; - - /** - * The current age. - */ - int age; - -}; - -} // openage diff --git a/libopenage/gamestate/old/population_tracker.cpp b/libopenage/gamestate/old/population_tracker.cpp deleted file mode 100644 index fdb79590f6..0000000000 --- a/libopenage/gamestate/old/population_tracker.cpp +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2017-2019 the openage authors. See copying.md for legal info. - -#include "population_tracker.h" - -namespace openage { - -PopulationTracker::PopulationTracker(int capacity_static, int capacity_max) { - this->demand = 0; - this->capacity_static = capacity_static; - this->capacity_real = 0; - this->capacity_max = capacity_max; - this->update_capacity(); -} - -void PopulationTracker::demand_population(int i) { - this->demand += i; - // TODO triger gui update -} - -void PopulationTracker::free_population(int i) { - this->demand -= i; - // TODO triger gui update -} - -void PopulationTracker::add_capacity_static(int i) { - this->capacity_static += i; - this->update_capacity(); -} - -void PopulationTracker::add_capacity(int i) { - this->capacity_real += i; - this->update_capacity(); -} - -void PopulationTracker::remove_capacity(int i) { - this->capacity_real -= i; - this->update_capacity(); -} - -void PopulationTracker::add_capacity_max(int i) { - this->capacity_max += i; - this->update_capacity(); -} - -void PopulationTracker::update_capacity() { - this->capacity_total = this->capacity_static + this->capacity_real; - // check the capacity limit - if (this->capacity_total > this->capacity_max) { - this->capacity = this->capacity_max; - } else { - this->capacity = this->capacity_total; - } - // TODO triger gui update -} - -int PopulationTracker::get_demand() const { - return this->demand; -} - -int PopulationTracker::get_capacity() const { - return this->capacity; -} - -int PopulationTracker::get_space() const { - return this->capacity - this->demand; -} - -int PopulationTracker::get_capacity_overflow() const { - return this->capacity_total - this->capacity; -} - -bool PopulationTracker::is_capacity_maxed() const { - return this->capacity >= this->capacity_max; -} - -} // openage diff --git a/libopenage/gamestate/old/population_tracker.h b/libopenage/gamestate/old/population_tracker.h deleted file mode 100644 index 431c0f28ea..0000000000 --- a/libopenage/gamestate/old/population_tracker.h +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2017-2019 the openage authors. See copying.md for legal info. - -#pragma once - -namespace openage { - -/** - * Keeps track of the population size and capacity. - */ -class PopulationTracker { -public: - - PopulationTracker(int capacity_static, int capacity_max); - - /** - * Add to the population demand - */ - void demand_population(int i); - - /** - * Remove from the population demand - */ - void free_population(int i); - - /** - * Changes the capacity given by civ bonuses - */ - void add_capacity_static(int i); - - /** - * Add to the capacity given by units - */ - void add_capacity(int i); - - /** - * Remove from the capacity given by units - */ - void remove_capacity(int i); - - /** - * Changes the max capacity given by civ bonuses - */ - void add_capacity_max(int i); - - int get_demand() const; - - int get_capacity() const; - - /** - * Returns the available population capacity for new units. - */ - int get_space() const; - - /** - * Returns the population capacity over the max limit. - */ - int get_capacity_overflow() const; - - /** - * Check if the population capacity has reached the max limit. - */ - bool is_capacity_maxed() const; - -private: - - /** - * Calculates the capacity values based on the limits. - * Must be called when a capacity variable changes. - */ - void update_capacity(); - - /** - * The population demand - */ - int demand; - - /** - * The population capacity given by civ bonuses - */ - int capacity_static; - - /** - * The population capacity given by units - */ - int capacity_real; - - /** - * The max population capacity - */ - int capacity_max; - - // generated values - - /** - * All the population capacity without the limitation - */ - int capacity_total; - - /** - * All the population capacity with the limitation - */ - int capacity; - -}; - -} // openage diff --git a/libopenage/gamestate/old/resource.cpp b/libopenage/gamestate/old/resource.cpp deleted file mode 100644 index 2c3acdda19..0000000000 --- a/libopenage/gamestate/old/resource.cpp +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright 2015-2021 the openage authors. See copying.md for legal info. - -#include -#include -#include - -#include "resource.h" - -namespace openage { - -ResourceBundle Resources::create_bundle() const { - return ResourceBundle(*this); -} - -ResourceBundle::ResourceBundle() - : - ResourceBundle{4} { -} - -ResourceBundle::ResourceBundle(const Resources& resources) - : - ResourceBundle{static_cast(resources.get_count())} { -} - -ResourceBundle::ResourceBundle(const int count) - : - count{count}, - value{new double[count] {0}} { -} - -ResourceBundle::ResourceBundle(const ResourceBundle &resources) - : - ResourceBundle{resources.count} { - this->set(resources); -} - -ResourceBundle ResourceBundle::clone() const { - return ResourceBundle(*this); -} - -ResourceBundle::~ResourceBundle() { - delete[] value; -} - -void ResourceBundle::expand(const ResourceBundle& other) { - this->expand(other.count); -} - -void ResourceBundle::expand(const int count) { - if (this->count == count) { - return; - } - // create new array with old values - auto *new_value = new double[count]; - for (int i = 0; i < this->count; i++) { - new_value[i] = this->value[i]; - } - // replace the private variables - this->count = count; - delete[] value; - this->value = new_value; -} - -bool ResourceBundle::operator> (const ResourceBundle& other) const { - for (int i = 0; i < this->count; i++) { - if (!(this->get(i) > other.get(i))) { - return false; - } - } - // check also resources that are not in both bundles - for (int i = this->count; i < other.count; i++) { - if (other.get(i) > 0) { - return false; - } - } - return true; -} - -bool ResourceBundle::operator>= (const ResourceBundle& other) const { - for (int i = 0; i < this->count; i++) { - if (!(this->get(i) >= other.get(i))) { - return false; - } - } - // check also resources that are not in both bundles - for (int i = this->count; i < other.count; i++) { - if (other.get(i) > 0) { - return false; - } - } - return true; -} - -ResourceBundle& ResourceBundle::operator+= (const ResourceBundle& other) { - this->expand(other); - for (int i = 0; i < this->count; i++) { - (*this)[i] += other.get(i); - } - return *this; -} - -ResourceBundle& ResourceBundle::operator-= (const ResourceBundle& other) { - this->expand(other); - for (int i = 0; i < this->count; i++) { - (*this)[i] -= other.get(i); - } - return *this; -} - -ResourceBundle& ResourceBundle::operator*= (const double a) { - for (int i = 0; i < this->count; i++) { - (*this)[i] *= a; - } - return *this; -} - -ResourceBundle& ResourceBundle::round() { - for (int i = 0; i < this->count; i++) { - (*this)[i] = std::round(this->get(i)); - } - return *this; -} - -bool ResourceBundle::has(const ResourceBundle& amount) const { - return *this >= amount; -} - -bool ResourceBundle::has(const ResourceBundle& amount1, const ResourceBundle& amount2) const { - for (int i = 0; i < this->count; i++) { - if (!(this->get(i) >= amount1.get(i) + amount2.get(i))) { - return false; - } - } - // check also resources that are not in both bundles - for (int i = this->count; i < amount1.count; i++) { - if (amount1.get(i) > 0) { - return false; - } - } - for (int i = this->count; i < amount2.count; i++) { - if (amount2.get(i) > 0) { - return false; - } - } - return true; -} - -bool ResourceBundle::deduct(const ResourceBundle& amount) { - if (this->has(amount)) { - *this -= amount; - return true; - } - return false; -} - -void ResourceBundle::set(const ResourceBundle &amount) { - this->expand(amount); - for (int i = 0; i < this->count; i++) { - (*this)[i] = amount.get(i); - } -} - -void ResourceBundle::set_all(const double amount) { - for (int i = 0; i < this->count; i++) { - (*this)[i] = amount; - } -} - -void ResourceBundle::limit(const ResourceBundle &limits) { - for (int i = 0; i < this->min_count(limits); i++) { - if (this->get(i) > limits.get(i)) { - (*this)[i] = limits.get(i); - } - } -} - -double ResourceBundle::sum() const { - double sum = 0; - for (int i = 0; i < this->count; i++) { - sum += this->get(i); - } - return sum; -} - -int ResourceBundle::min_count(const ResourceBundle &other) { - return this->count <= other.count ? this->count : other.count; -} - -} // openage - -namespace std { - -string to_string(const openage::game_resource &res) { - switch (res) { - case openage::game_resource::wood: - return "wood"; - case openage::game_resource::food: - return "food"; - case openage::game_resource::gold: - return "gold"; - case openage::game_resource::stone: - return "stone"; - default: - return "unknown"; - } -} - -} // namespace std diff --git a/libopenage/gamestate/old/resource.h b/libopenage/gamestate/old/resource.h deleted file mode 100644 index 4a52b5c008..0000000000 --- a/libopenage/gamestate/old/resource.h +++ /dev/null @@ -1,209 +0,0 @@ -// Copyright 2015-2018 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -namespace openage { - -class ResourceBundle; - -/** - * A resource - */ -class Resource { -public: - - Resource(); - - virtual int id() const = 0; - - virtual std::string name() const = 0; - - // TODO add images and icons - -}; - -class ResourceProducer : public Resource { -public: - - ResourceProducer(int id, std::string name) - : - _id{id}, - _name{name} { } - - int id() const override { return _id; } - - std::string name() const override { return _name; } - -private: - - int _id; - std::string _name; -}; - -/** - * All the resources. - * - * The the ids of the resources must be inside [0, count). - * - * The static variables wood, food, gold, stone are the ids of the representing resource. - * Any extension of Resources must use this ids as they are an engine dependency (at the moment). - */ -class Resources { -public: - - Resources(); - - virtual unsigned int get_count() const = 0; - - virtual const Resource& get_resource(int id) const = 0; - - ResourceBundle create_bundle() const; - - // TODO remove when the engine is fully decupled from the data - static const int wood = 0; - static const int food = 1; - static const int gold = 2; - static const int stone = 3; - -}; - -class ClassicResources : public Resources { -public: - - ClassicResources() - : - resources{{Resources::wood, "wood"}, - {Resources::food, "food"}, - {Resources::gold, "gold"}, - {Resources::stone, "stone"}} { - } - - unsigned int get_count() const override { return 4; } - - const Resource& get_resource(int id) const override { return this->resources[id]; }; - -private: - - const ResourceProducer resources[4]; -}; - -// TODO remove, here for backwards compatibility -enum class game_resource : int { - wood = 0, - food = 1, - gold = 2, - stone = 3, - RESOURCE_TYPE_COUNT = 4 -}; - - -/** - * A set of amounts of game resources. - * - * Can be also used to store other information about the resources. - * - * TODO change amounts from doubles to integers - */ -class ResourceBundle { -public: - - // TODO remove, here for backwards compatibility - ResourceBundle(); - - ResourceBundle(const Resources& resources); - - virtual ~ResourceBundle(); - - ResourceBundle(const ResourceBundle& other); - - ResourceBundle clone() const; - - bool operator> (const ResourceBundle& other) const; - bool operator>= (const ResourceBundle& other) const; - - ResourceBundle& operator+= (const ResourceBundle& other); - ResourceBundle& operator-= (const ResourceBundle& other); - - ResourceBundle& operator*= (const double a); - - /** - * Round each value to the nearest integer. - * Returns itself. - */ - ResourceBundle& round(); - - bool has(const ResourceBundle& amount) const; - - bool has(const ResourceBundle& amount1, const ResourceBundle& amount2) const; - - /** - * If amount can't be deducted return false, else deduct the given amount - * and return true. - */ - bool deduct(const ResourceBundle& amount); - - void set(const ResourceBundle& amount); - - void set_all(const double amount); - - void limit(const ResourceBundle& limits); - - double& operator[] (const game_resource res) { return value[static_cast(res)]; } - double& operator[] (const int id) { return value[id]; } - - // Getters - - double get(const game_resource res) const { return value[static_cast(res)]; } - double get(const int id) const { return value[id]; } - - /** - * Returns the sum of all the resources. - */ - double sum() const; - - /** - * The number of resources - */ - int get_count() const { return count; }; - -private: - - ResourceBundle(const int count); - - void expand(const ResourceBundle& other); - - void expand(const int count); - - /** - * The number of resources - */ - int count; - - double *value; - - int min_count(const ResourceBundle& other); - -}; - -} // namespace openage - -namespace std { - -std::string to_string(const openage::game_resource &res); - -/** - * hasher for game resource - */ -template<> struct hash { - typedef underlying_type::type underlying_type; - - size_t operator()(const openage::game_resource &arg) const { - hash hasher; - return hasher(static_cast(arg)); - } -}; - -} // namespace std diff --git a/libopenage/gamestate/old/score.cpp b/libopenage/gamestate/old/score.cpp deleted file mode 100644 index 9d26d9c9f0..0000000000 --- a/libopenage/gamestate/old/score.cpp +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2017-2021 the openage authors. See copying.md for legal info. - -#include - -#include "player.h" -#include "score.h" -#include "team.h" -#include "../../log/log.h" - -namespace openage { - -Score::Score() - : - score{0}, - score_total{0}, - score_exploration{0}, - score_resources{0} { -} - -void Score::add_score(const score_category cat, double value) { - this->add_score(cat, static_cast(std::lround(value))); -} - -void Score::add_score(const score_category cat, int value) { - this->score[static_cast(cat)] += value; - this->update_score(); -} - -void Score::remove_score(const score_category cat, double value) { - this->remove_score(cat, static_cast(std::lround(value))); -} - -void Score::remove_score(const score_category cat, int value) { - this->score[static_cast(cat)] -= value; - this->update_score(); -} - -void Score::update_map_explored(double progress) { - this->remove_score(score_category::technology, this->score_exploration); - this->score_exploration = progress * 1000; - this->add_score(score_category::technology, this->score_exploration); -} - -void Score::update_resources(const ResourceBundle & resources) { - this->remove_score(score_category::economy, this->score_resources); - this->score_resources = resources.sum() * 0.1; - this->add_score(score_category::economy, this->score_resources); -} - -void Score::update_score() { - this->score_total = 0; - for (int i = 0; i < static_cast(score_category::SCORE_CATEGORY_COUNT); i++) { - this->score_total += this->get_score(i); - } -} - -PlayerScore::PlayerScore(Player *player) - : - Score(), - player{player} { -} - -void PlayerScore::update_score() { - Score::update_score(); - // update team score - if (this->player->team) { - this->player->team->score.update_score(); - } -} - -TeamScore::TeamScore(Team *team) - : - Score(), - team{team} { -} - -void TeamScore::update_score() { - // scores are the corresponding sums of players score - for (int i = 0; i < static_cast(score_category::SCORE_CATEGORY_COUNT); i++) { - this->score[i] = 0; - } - for (auto player : this->team->get_players()) { - for (int i = 0; i < static_cast(score_category::SCORE_CATEGORY_COUNT); i++) { - this->score[i] += player->score.get_score(i); - } - } - Score::update_score(); -} - -} // openage - -namespace std { - -string to_string(const openage::score_category &cat) { - switch (cat) { - case openage::score_category::military: - return "military"; - case openage::score_category::economy: - return "economy"; - case openage::score_category::technology: - return "technology"; - case openage::score_category::society: - return "society"; - default: - return "unknown"; - } -} - -} // namespace std diff --git a/libopenage/gamestate/old/score.h b/libopenage/gamestate/old/score.h deleted file mode 100644 index 2a8c762290..0000000000 --- a/libopenage/gamestate/old/score.h +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2017-2018 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "resource.h" - - -namespace openage { - -class Player; -class Team; - -/** - * The categories of sub-scores that sum to a player's score. - */ -enum class score_category : int { - /** 20% of units killed cost */ - military, - /** 20% of alive units cost and 10% of resources */ - economy, - /** 20% of researched technologies and 10 for each 1% of map explored*/ - technology, - /** 20% of Castles and Wonders cost */ - society, - SCORE_CATEGORY_COUNT -}; - -/** - * Keeps track of a score and all the sub-scores - */ -class Score { -public: - - Score(); - - void add_score(const score_category cat, double value); - void add_score(const score_category cat, int value); - - void remove_score(const score_category cat, double value); - void remove_score(const score_category cat, int value); - - /** - * Updates map exploration precentance based sub-scores - */ - void update_map_explored(double progress); - - /** - * Updates resource based sub-scores - */ - void update_resources(const ResourceBundle & resources); - - /** - * Calculates the total score from the sub-scores. - * TODO update gui here - */ - virtual void update_score(); - - // Getters - - int get_score(const score_category cat) const { return score[static_cast(cat)]; } - int get_score(const int index) const { return score[index]; } - - int get_score_total() const { return score_total; } - -protected: - - int score[static_cast(score_category::SCORE_CATEGORY_COUNT)]; - - // generated values - - int score_total; - -private: - - /** Used by update_map_explored. */ - int score_exploration; - - /** Used by update_resources. */ - int score_resources; -}; - - -/** - * The score of a player - */ -class PlayerScore : public Score { -public: - - PlayerScore(Player *player); - - virtual void update_score() override; - -protected: - -private: - - Player *player; -}; - - -/** - * The score of a team - */ -class TeamScore : public Score { -public: - - TeamScore(Team *team); - - virtual void update_score() override; - -protected: - -private: - - Team *team; -}; - -} // namespace openage - -namespace std { - -std::string to_string(const openage::score_category &cat); - -/** - * hasher for score_category - * TODO decide if needed, not used at the moment - */ -template<> -struct hash { - typedef underlying_type::type underlying_type; - - size_t operator()(const openage::score_category &arg) const { - hash hasher; - return hasher(static_cast(arg)); - } -}; - -} // namespace std diff --git a/libopenage/gamestate/old/team.cpp b/libopenage/gamestate/old/team.cpp deleted file mode 100644 index 92e556437f..0000000000 --- a/libopenage/gamestate/old/team.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2016-2021 the openage authors. See copying.md for legal info. - -#include "team.h" - -#include "player.h" -#include "score.h" -#include - - -namespace openage { - -Team::Team(unsigned int id) - : - Team{id, "Anonymous Team", nullptr} {} - -Team::Team(unsigned int id, std::string name) - : - Team{id, std::move(name), nullptr} {} - -Team::Team(unsigned int id, std::string name, Player *leader) - : - id{id}, - name{std::move(name)}, - score{this} { - - if (leader) { - this->add_member(*leader, member_type::leader); - } -} - -bool Team::operator ==(const Team &other) const { - return this->id == other.id; -} - -void Team::add_member(Player &player, const member_type type) { - // if already exists, replace member type - this->members[&player] = type; - // change player team pointer - player.team = this; -} - -void Team::change_member_type(Player &player, const member_type type) { - auto p = this->members.find(&player); - if (p != this->members.end()) { - this->members[&player] = type; - } -} - -bool Team::is_member(const Player &player) const { - auto p = this->members.find(&player); - return (p != this->members.end()); -} - -void Team::remove_member(Player &player) { - this->members.erase(&player); - // change player team pointer - player.team = nullptr; -} - -member_type Team::get_member_type(Player &player) { - auto p = this->members.find(&player); - if (p != this->members.end()) { - return this->members[&player]; - } - // return pseudo member type for completion - return member_type::none; -} - -std::vector Team::get_players() const { - std::vector players; - for (auto& i : members) { - players.push_back(i.first); - } - return players; -} - -} // openage diff --git a/libopenage/gamestate/old/team.h b/libopenage/gamestate/old/team.h deleted file mode 100644 index 657909df9e..0000000000 --- a/libopenage/gamestate/old/team.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2016-2019 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include - - -#include "score.h" - - -namespace openage { - -class Player; - -/** - * Types of membership - */ -enum class member_type { - leader, - member, - recruit, - none // pseudo type -}; - -/** - * A team of players - */ -class Team { -public: - Team(unsigned int id); - Team(unsigned int id, std::string name); - Team(unsigned int id, std::string name, Player *leader); - - /** - * unique id of the team - */ - const unsigned int id; - - /** - * visible name of this team - */ - const std::string name; - - bool operator ==(const Team &other) const; - - - void add_member(Player &player, const member_type type); - - void change_member_type(Player &player, const member_type type); - - bool is_member(const Player &player) const; - - void remove_member(Player &player); - - member_type get_member_type(Player &player); - - /** - * TODO find a better way to get all the players - */ - std::vector get_players() const; - - /** - * The score of the team, based on the team's players score. - */ - TeamScore score; - -private: - - std::unordered_map members; - -}; - -} // openage diff --git a/libopenage/gamestate/old/types.cpp b/libopenage/gamestate/old/types.cpp deleted file mode 100644 index ca80997a97..0000000000 --- a/libopenage/gamestate/old/types.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright 2018-2023 the openage authors. See copying.md for legal info. - -#include "types.h" - - -namespace openage { - -} // openage diff --git a/libopenage/gamestate/old/types.h b/libopenage/gamestate/old/types.h deleted file mode 100644 index 805cd63627..0000000000 --- a/libopenage/gamestate/old/types.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2018-2023 the openage authors. See copying.md for legal info. - -#pragma once - - -namespace openage { - -/** - * The key type mapped to data objects. - * Used for graphics indices, sounds, ... - * TODO: get rid of this. - */ -using index_t = int; - - -} // openage diff --git a/libopenage/gui/CMakeLists.txt b/libopenage/gui/CMakeLists.txt index 749136617c..a96c486f54 100644 --- a/libopenage/gui/CMakeLists.txt +++ b/libopenage/gui/CMakeLists.txt @@ -1,13 +1,7 @@ add_sources(libopenage actions_list_model.cpp - category_contents_list_model.cpp - game_creator.cpp - game_saver.cpp - game_spec_link.cpp - generator_link.cpp gui.cpp registrations.cpp - resources_list_model.cpp ) add_subdirectory("guisys") diff --git a/libopenage/gui/category_contents_list_model.cpp b/libopenage/gui/category_contents_list_model.cpp deleted file mode 100644 index 88408ee458..0000000000 --- a/libopenage/gui/category_contents_list_model.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "category_contents_list_model.h" - -#include - -namespace openage { -namespace gui { - -namespace { -const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "Category"); -} - -CategoryContentsListModel::CategoryContentsListModel(QObject *parent) : - QAbstractListModel{parent} { - Q_UNUSED(registration); -} - -CategoryContentsListModel::~CategoryContentsListModel() = default; - -QString CategoryContentsListModel::get_name() const { - return this->name; -} - -void CategoryContentsListModel::set_name(const QString &name) { - if (this->name != name) { - this->name = name; - - this->on_categories_content_changed(); - } -} - -void CategoryContentsListModel::on_category_content_changed(const std::string &category_name, std::vector> type_and_texture) { - if (this->name == QString::fromStdString(category_name)) { - this->beginResetModel(); - this->type_and_texture = type_and_texture; - this->endResetModel(); - } -} - -void CategoryContentsListModel::on_categories_content_changed() { -} - -QHash CategoryContentsListModel::roleNames() const { - auto names = this->QAbstractListModel::roleNames(); - names.insert(Qt::UserRole + 1, "typeId"); - return names; -} - -int CategoryContentsListModel::rowCount(const QModelIndex &) const { - return this->type_and_texture.size(); -} - -QVariant CategoryContentsListModel::data(const QModelIndex &index, int role) const { - switch (role) { - case Qt::DisplayRole: - return std::get<1>(this->type_and_texture[index.row()]); - - case Qt::UserRole + 1: - return std::get<0>(this->type_and_texture[index.row()]); - - default: - break; - } - - return QVariant{}; -} - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/category_contents_list_model.h b/libopenage/gui/category_contents_list_model.h deleted file mode 100644 index e3845a44db..0000000000 --- a/libopenage/gui/category_contents_list_model.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include -#include - -#include "../gamestate/old/types.h" - -#include - -namespace openage { -namespace gui { - -/** - * Adaptor for the contents of a category of the Civilisation. - */ -class CategoryContentsListModel : public QAbstractListModel { - Q_OBJECT - - Q_PROPERTY(QString name READ get_name WRITE set_name) - -public: - CategoryContentsListModel(QObject *parent = nullptr); - virtual ~CategoryContentsListModel(); - - QString get_name() const; - void set_name(const QString &name); - -private slots: - void on_category_content_changed(const std::string &category_name, std::vector> type_and_texture); - void on_categories_content_changed(); - -private: - virtual QHash roleNames() const override; - virtual int rowCount(const QModelIndex &) const override; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - std::vector> type_and_texture; - - QString name; -}; - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/game_creator.cpp b/libopenage/gui/game_creator.cpp deleted file mode 100644 index 392efe6139..0000000000 --- a/libopenage/gui/game_creator.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "game_creator.h" - -#include - -#include "../gamestate/old/game_main.h" -#include "../gamestate/old/game_spec.h" -#include "../gamestate/old/generator.h" - -#include "game_spec_link.h" -#include "generator_link.h" - -namespace openage::gui { - -namespace { -const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "GameCreator"); -} - -GameCreator::GameCreator(QObject *parent) : - QObject{parent}, - generator_parameters{} { - Q_UNUSED(registration); -} - -GameCreator::~GameCreator() = default; - -QString GameCreator::get_error_string() const { - return this->error_string; -} - -void GameCreator::activate() { - static auto f = [](GameMainHandle *game, - GameSpecHandle *game_spec, - Generator *generator, - std::shared_ptr callback) { - QString error_msg; - - if (game->is_game_running()) { - error_msg = "close existing game before loading"; - } - else if (not game_spec->is_ready()) { - error_msg = "game data has not finished loading"; - } - else { - auto game_main = generator->create(game_spec->get_spec()); - - if (game_main) { - game->set_game(std::move(game_main)); - } - else { - error_msg = "unknown error"; - } - } - - emit callback->error_message(error_msg); - }; -} - -void GameCreator::clearErrors() { - this->error_string.clear(); - emit this->error_string_changed(); -} - -void GameCreator::on_processed(const QString &error_string) { - this->error_string = error_string; - emit this->error_string_changed(); -} - -} // namespace openage::gui diff --git a/libopenage/gui/game_creator.h b/libopenage/gui/game_creator.h deleted file mode 100644 index c1899971d0..0000000000 --- a/libopenage/gui/game_creator.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -namespace openage { -namespace gui { - -class GameMainLink; -class GameSpecLink; -class GeneratorLink; - -class GameCreator : public QObject { - Q_OBJECT - - Q_ENUMS(State) - Q_PROPERTY(QString errorString READ get_error_string NOTIFY error_string_changed) - Q_MOC_INCLUDE("gui/game_spec_link.h") - Q_MOC_INCLUDE("gui/generator_link.h") - Q_PROPERTY(openage::gui::GameSpecLink *gameSpec MEMBER game_spec NOTIFY game_spec_changed) - Q_PROPERTY(openage::gui::GeneratorLink *generatorParameters MEMBER generator_parameters NOTIFY generator_parameters_changed) - -public: - explicit GameCreator(QObject *parent = nullptr); - virtual ~GameCreator(); - - QString get_error_string() const; - - Q_INVOKABLE void activate(); - Q_INVOKABLE void clearErrors(); - -public slots: - void on_processed(const QString &error_string); - -signals: - void error_string_changed(); - void game_changed(); - void game_spec_changed(); - void generator_parameters_changed(); - -private: - QString error_string; - GameSpecLink *game_spec; - GeneratorLink *generator_parameters; -}; - -class GameCreatorSignals : public QObject { - Q_OBJECT - -public: -signals: - void error_message(const QString &error); -}; - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/game_saver.cpp b/libopenage/gui/game_saver.cpp deleted file mode 100644 index a700dc704e..0000000000 --- a/libopenage/gui/game_saver.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2016-2023 the openage authors. See copying.md for legal info. - -#include "game_saver.h" - -#include - -#include "../gamestate/old/game_main.h" -#include "../gamestate/old/game_save.h" -#include "../gamestate/old/generator.h" - -#include "generator_link.h" - -namespace openage::gui { - -namespace { -const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "GameSaver"); -} - -GameSaver::GameSaver(QObject *parent) : - QObject{parent}, - generator_parameters{} { - Q_UNUSED(registration); -} - -GameSaver::~GameSaver() = default; - -QString GameSaver::get_error_string() const { - return this->error_string; -} - -// called when the save-game button is pressed: -void GameSaver::activate() { - static auto f = [](GameMainHandle *game, - Generator *generator, - std::shared_ptr callback) { - QString error_msg; - - if (!game->is_game_running()) { - error_msg = "no open game to save"; - } - else { - auto filename = generator->getv("load_filename"); - gameio::save(game->get_game(), filename); - } - - emit callback->error_message(error_msg); - }; -} - -void GameSaver::clearErrors() { - this->error_string.clear(); - emit this->error_string_changed(); -} - -void GameSaver::on_processed(const QString &error_string) { - this->error_string = error_string; - emit this->error_string_changed(); -} - -} // namespace openage::gui diff --git a/libopenage/gui/game_saver.h b/libopenage/gui/game_saver.h deleted file mode 100644 index 69cbbe75d8..0000000000 --- a/libopenage/gui/game_saver.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2016-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -namespace openage { -namespace gui { - -class GameMainLink; -class GeneratorLink; - -class GameSaver : public QObject { - Q_OBJECT - - Q_ENUMS(State) - Q_PROPERTY(QString errorString READ get_error_string NOTIFY error_string_changed) - Q_PROPERTY(openage::gui::GeneratorLink *generatorParameters MEMBER generator_parameters NOTIFY generator_parameters_changed) - -public: - explicit GameSaver(QObject *parent = nullptr); - virtual ~GameSaver(); - - QString get_error_string() const; - - Q_INVOKABLE void activate(); - Q_INVOKABLE void clearErrors(); - -public slots: - void on_processed(const QString &error_string); - -signals: - void error_string_changed(); - void game_changed(); - void generator_parameters_changed(); - -private: - QString error_string; - GeneratorLink *generator_parameters; -}; - -class GameSaverSignals : public QObject { - Q_OBJECT - -public: -signals: - void error_message(const QString &error); -}; - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/game_spec_link.cpp b/libopenage/gui/game_spec_link.cpp deleted file mode 100644 index be8ebf6bb1..0000000000 --- a/libopenage/gui/game_spec_link.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "game_spec_link.h" - -#include - -namespace openage::gui { - -namespace { -const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "GameSpec"); -const int registration_of_ptr = qRegisterMetaType>("shared_ptr"); -} // namespace - -GameSpecLink::GameSpecLink(QObject *parent) : - GuiItemQObject{parent}, - QQmlParserStatus{}, - GuiItem{this}, - state{}, - active{}, - terrain_id_count{} { - Q_UNUSED(registration); - Q_UNUSED(registration_of_ptr); -} - -GameSpecLink::~GameSpecLink() = default; - -void GameSpecLink::classBegin() { -} - -void GameSpecLink::on_core_adopted() { - auto core = unwrap(this); - QObject::connect(core->gui_signals.get(), &GameSpecSignals::load_job_finished, this, &GameSpecLink::on_load_job_finished); - QObject::connect(core->gui_signals.get(), &GameSpecSignals::game_spec_loaded, this, &GameSpecLink::on_game_spec_loaded); -} - -void GameSpecLink::componentComplete() { - this->on_load_job_finished(); -} - -void GameSpecLink::on_load_job_finished() { - static auto f = [](GameSpecHandle *_this) { - _this->announce_spec(); - }; - this->i(f); -} - -void GameSpecLink::on_game_spec_loaded(std::shared_ptr loaded_game_spec) { - this->loaded_game_spec = loaded_game_spec; - - this->terrain_id_count = this->loaded_game_spec->get_terrain_meta()->terrain_id_count; - - this->state = State::Ready; - - emit this->state_changed(); - emit this->terrain_id_count_changed(); - emit this->game_spec_loaded(this, this->loaded_game_spec); -} - -std::shared_ptr GameSpecLink::get_loaded_spec() { - return this->loaded_game_spec; -} - -GameSpecLink::State GameSpecLink::get_state() const { - return this->state; -} - -void GameSpecLink::invalidate() { - static auto f = [](GameSpecHandle *_this) { - _this->invalidate(); - }; - this->i(f); - - this->set_state(this->active ? State::Loading : State::Null); -} - -bool GameSpecLink::get_active() const { - return this->active; -} - -void GameSpecLink::set_active(bool active) { - static auto f = [](GameSpecHandle *_this, bool active) { - _this->set_active(active); - }; - this->s(f, this->active, active); - - this->set_state(this->active && this->state == State::Null ? State::Loading : this->state); -} - -int GameSpecLink::get_terrain_id_count() const { - return this->terrain_id_count; -} - -void GameSpecLink::set_state(GameSpecLink::State state) { - if (state != this->state) { - this->state = state; - emit this->state_changed(); - } -} - -} // namespace openage::gui diff --git a/libopenage/gui/game_spec_link.h b/libopenage/gui/game_spec_link.h deleted file mode 100644 index c896227d23..0000000000 --- a/libopenage/gui/game_spec_link.h +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include -#include - -#include "guisys/link/gui_item.h" - -#include "../gamestate/old/game_spec.h" - -namespace openage { - -class GameSpec; - -namespace gui { - -class GameSpecLink; - -} // namespace gui -} // namespace openage - -namespace qtsdl { -template <> -struct Wrap { - using Type = openage::gui::GameSpecLink; -}; - -template <> -struct Unwrap { - using Type = openage::GameSpecHandle; -}; - -} // namespace qtsdl - -namespace openage { -namespace gui { - -class GameSpecLink : public qtsdl::GuiItemQObject - , public QQmlParserStatus - , public qtsdl::GuiItem { - Q_OBJECT - - Q_INTERFACES(QQmlParserStatus) - Q_ENUMS(State) - Q_PROPERTY(State state READ get_state NOTIFY state_changed) - Q_PROPERTY(bool active READ get_active WRITE set_active) - Q_PROPERTY(int terrainIdCount READ get_terrain_id_count NOTIFY terrain_id_count_changed) - -public: - explicit GameSpecLink(QObject *parent = nullptr); - virtual ~GameSpecLink(); - - enum class State { - Null, - Loading, - Ready - }; - - State get_state() const; - - bool get_active() const; - void set_active(bool active); - - int get_terrain_id_count() const; - - Q_INVOKABLE void invalidate(); - - std::shared_ptr get_loaded_spec(); - -signals: - /** - * Pass loaded assets to the image provider. - * - * Provider will check if it's still attached to that spec. - * Also it may be invalidated in the meantime, so share the ownership. - */ - void game_spec_loaded(GameSpecLink *game_spec, std::shared_ptr loaded_game_spec); - - void state_changed(); - void terrain_id_count_changed(); - -private slots: - void on_load_job_finished(); - void on_game_spec_loaded(std::shared_ptr loaded_game_spec); - -private: - virtual void classBegin() override; - virtual void on_core_adopted() override; - virtual void componentComplete() override; - - void set_state(State state); - - State state; - bool active; - int terrain_id_count; - - std::shared_ptr loaded_game_spec; -}; - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/generator_link.cpp b/libopenage/gui/generator_link.cpp deleted file mode 100644 index 1b0be636aa..0000000000 --- a/libopenage/gui/generator_link.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "generator_link.h" - -#include - -#include "guisys/link/gui_property_map_impl.h" - -namespace openage::gui { - -namespace -{ -const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "GeneratorParameters"); -} - -GeneratorLink::GeneratorLink(QObject *parent) - : - GuiListModel{parent}, - GuiItemListModel{this} { - Q_UNUSED(registration); -} - -GeneratorLink::~GeneratorLink() = default; - -} // namespace openage::gui diff --git a/libopenage/gui/generator_link.h b/libopenage/gui/generator_link.h deleted file mode 100644 index 7dd3f0567f..0000000000 --- a/libopenage/gui/generator_link.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include "gamestate/old/generator.h" - -#include "guisys/link/gui_item_list_model.h" -#include "guisys/link/gui_list_model.h" - -namespace openage { -class Generator; -namespace gui { -class GeneratorLink; -} -} // namespace openage - -namespace qtsdl { -template <> -struct Wrap { - using Type = openage::gui::GeneratorLink; -}; - -template <> -struct Unwrap { - using Type = openage::Generator; -}; - -} // namespace qtsdl - -namespace openage { -namespace gui { - -class GeneratorLink : public qtsdl::GuiListModel - , public qtsdl::GuiItemListModel { - Q_OBJECT - -public: - GeneratorLink(QObject *parent = nullptr); - virtual ~GeneratorLink(); -}; - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/integration/private/CMakeLists.txt b/libopenage/gui/integration/private/CMakeLists.txt index f727980b6f..88be5e9db6 100644 --- a/libopenage/gui/integration/private/CMakeLists.txt +++ b/libopenage/gui/integration/private/CMakeLists.txt @@ -1,11 +1,9 @@ add_sources(libopenage gui_filled_texture_handles.cpp - gui_game_spec_image_provider_impl.cpp gui_image_provider_link.cpp gui_log.cpp gui_make_standalone_subtexture.cpp gui_standalone_subtexture.cpp gui_texture.cpp - gui_texture_factory.cpp gui_texture_handle.cpp ) diff --git a/libopenage/gui/integration/private/gui_game_spec_image_provider_impl.cpp b/libopenage/gui/integration/private/gui_game_spec_image_provider_impl.cpp deleted file mode 100644 index 01579aa8fa..0000000000 --- a/libopenage/gui/integration/private/gui_game_spec_image_provider_impl.cpp +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "gui_game_spec_image_provider_impl.h" - -#include - -#include - -#include "../../../error/error.h" - -#include "../../../gamestate/old/game_spec.h" -#include "../../guisys/private/gui_event_queue_impl.h" - -#include "gui_filled_texture_handles.h" -#include "gui_texture_factory.h" - -namespace openage::gui { - -GuiGameSpecImageProviderImpl::GuiGameSpecImageProviderImpl(qtsdl::GuiEventQueue *render_updater) : - GuiImageProviderImpl{}, - invalidated{}, - filled_handles{std::make_shared()}, - ended{} { - QThread *render_thread = qtsdl::GuiEventQueueImpl::impl(render_updater)->get_thread(); - this->render_thread_callback.moveToThread(render_thread); - QObject::connect(&this->render_thread_callback, &qtsdl::GuiCallback::process_blocking, &this->render_thread_callback, &qtsdl::GuiCallback::process, render_thread != QThread::currentThread() ? Qt::BlockingQueuedConnection : Qt::DirectConnection); -} - -GuiGameSpecImageProviderImpl::~GuiGameSpecImageProviderImpl() = default; - -void GuiGameSpecImageProviderImpl::on_game_spec_loaded(const std::shared_ptr &loaded_game_spec) { - ENSURE(loaded_game_spec, "spec hasn't been checked or was invalidated"); - - std::unique_lock lck{this->loaded_game_spec_mutex}; - - if (invalidated || loaded_game_spec != this->loaded_game_spec) { - migrate_to_new_game_spec(loaded_game_spec); - invalidated = false; - - lck.unlock(); - this->loaded_game_spec_cond.notify_one(); - } -} - -void GuiGameSpecImageProviderImpl::migrate_to_new_game_spec(const std::shared_ptr &loaded_game_spec) { - ENSURE(loaded_game_spec, "spec hasn't been checked or was invalidated"); - - if (this->loaded_game_spec) { - auto keep_old_game_spec = this->loaded_game_spec; - - // Need to set up this because the load functions use this->loaded_game_spec internally. - this->loaded_game_spec = loaded_game_spec; - - emit this->render_thread_callback.process_blocking([this] { - using namespace std::placeholders; - this->filled_handles->refresh_all_handles_with_texture(std::bind(&GuiGameSpecImageProviderImpl::overwrite_texture_handle, this, _1, _2, _3)); - }); - } - else { - this->loaded_game_spec = loaded_game_spec; - } -} - -void GuiGameSpecImageProviderImpl::overwrite_texture_handle(const QString &id, const QSize &requested_size, SizedTextureHandle *filled_handle) { - const TextureHandle texture_handle = this->get_texture_handle(id); - *filled_handle = {texture_handle, aspect_fit_size(texture_handle, requested_size)}; -} - -void GuiGameSpecImageProviderImpl::on_game_spec_invalidated() { - std::unique_lock lck{this->loaded_game_spec_mutex}; - - if (this->loaded_game_spec) { - invalidated = true; - } -} - -GuiFilledTextureHandleUser GuiGameSpecImageProviderImpl::fill_texture_handle(const QString &id, const QSize &requested_size, SizedTextureHandle *filled_handle) { - this->overwrite_texture_handle(id, requested_size, filled_handle); - return GuiFilledTextureHandleUser(this->filled_handles, id, requested_size, filled_handle); -} - -QQuickTextureFactory *GuiGameSpecImageProviderImpl::requestTexture(const QString &id, QSize *size, const QSize &requestedSize) { - std::unique_lock lck{this->loaded_game_spec_mutex}; - - this->loaded_game_spec_cond.wait(lck, [this] { return this->ended || this->loaded_game_spec; }); - - if (this->ended) { - qWarning("ImageProvider was stopped during the load, so it'll appear like the requestTexture() isn't implemented."); - return this->GuiImageProviderImpl::requestTexture(id, size, requestedSize); - } - else { - auto tex_factory = new GuiTextureFactory{this, id, requestedSize}; - *size = tex_factory->textureSize(); - return tex_factory; - } -} - -void GuiGameSpecImageProviderImpl::give_up() { - { - std::unique_lock lck{this->loaded_game_spec_mutex}; - this->ended = true; - } - - this->loaded_game_spec_cond.notify_one(); -} - -} // namespace openage::gui diff --git a/libopenage/gui/integration/private/gui_game_spec_image_provider_impl.h b/libopenage/gui/integration/private/gui_game_spec_image_provider_impl.h deleted file mode 100644 index 3fd199dbd0..0000000000 --- a/libopenage/gui/integration/private/gui_game_spec_image_provider_impl.h +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include -#include -#include - -#include "../../guisys/private/gui_callback.h" -#include "../../guisys/private/gui_image_provider_impl.h" -#include "gui_filled_texture_handles.h" -#include "gui_texture_handle.h" - -namespace qtsdl { - -class GuiEventQueue; -class GuiEventQueueImpl; - -} // namespace qtsdl - -namespace openage { - -class GameSpec; -class Texture; - -namespace gui { - -class GuiTexture; - -/** - * Exposes game textures to the Qt. - */ -class GuiGameSpecImageProviderImpl : public qtsdl::GuiImageProviderImpl { -public: - explicit GuiGameSpecImageProviderImpl(qtsdl::GuiEventQueue *render_updater); - virtual ~GuiGameSpecImageProviderImpl(); - - /** - * Unblocks the provider. - * - * Refreshes already loaded assets (if this->loaded_game_spec wasn't null before the call). - * - * @param loaded_game_spec new source (can't be null) - */ - void on_game_spec_loaded(const std::shared_ptr &loaded_game_spec); - - /** - * Set to every sprite the 'missing texture' from current spec. - * - * Needed as a visible reaction to setting the property to null. - * We can't unload the textures without recreating the engine, so we keep the old source. - */ - void on_game_spec_invalidated(); - - /** - * Fills in the provided handle object. - * - * Memorizes pointer to it in order to update it if the source changes. - * - * @return pointer to all memorized handles, so the client can unsubscribe. - */ - GuiFilledTextureHandleUser fill_texture_handle(const QString &id, const QSize &requested_size, SizedTextureHandle *filled_handle); - -protected: - std::shared_ptr loaded_game_spec; - - /** - * When true, still uses the old source but shows the 'missing texture'. - */ - bool invalidated; - -private: - virtual TextureHandle get_texture_handle(const QString &id) = 0; - virtual QQuickTextureFactory *requestTexture(const QString &id, QSize *size, const QSize &requestedSize) override; - virtual void give_up() override; - - /** - * Change the already produced texture handles to use new source. - */ - void migrate_to_new_game_spec(const std::shared_ptr &loaded_game_spec); - - void overwrite_texture_handle(const QString &id, const QSize &requested_size, SizedTextureHandle *filled_handle); - - /** - * Changing the texture handles underneath the QSGTexture to reflect the reload of the GameSpec. - * - * It's not a proper Qt usage, so the live reload of the game assets for the gui may break in future Qt releases. - * When it breaks, this feature should be implemented via the recreation of the qml engine. - */ - std::shared_ptr filled_handles; - - std::mutex loaded_game_spec_mutex; - std::condition_variable loaded_game_spec_cond; - bool ended; - - qtsdl::GuiCallback render_thread_callback; -}; - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/integration/private/gui_image_provider_link.cpp b/libopenage/gui/integration/private/gui_image_provider_link.cpp index f2b72eecb3..a770c0f552 100644 --- a/libopenage/gui/integration/private/gui_image_provider_link.cpp +++ b/libopenage/gui/integration/private/gui_image_provider_link.cpp @@ -11,42 +11,14 @@ #include "../../guisys/link/qml_engine_with_singleton_items_info.h" #include "../../guisys/link/qtsdl_checked_static_cast.h" -#include "../../game_spec_link.h" -#include "gui_game_spec_image_provider_impl.h" - namespace openage::gui { -GuiImageProviderLink::GuiImageProviderLink(QObject *parent, GuiGameSpecImageProviderImpl &image_provider) : - QObject{parent}, - image_provider{image_provider}, - game_spec{} { +GuiImageProviderLink::GuiImageProviderLink(QObject *parent) : + QObject{parent} { } GuiImageProviderLink::~GuiImageProviderLink() = default; -GameSpecLink *GuiImageProviderLink::get_game_spec() const { - return this->game_spec; -} - -void GuiImageProviderLink::set_game_spec(GameSpecLink *game_spec) { - if (this->game_spec != game_spec) { - if (this->game_spec) - QObject::disconnect(this->game_spec.data(), &GameSpecLink::game_spec_loaded, this, &GuiImageProviderLink::on_game_spec_loaded); - - if (!game_spec) - this->image_provider.on_game_spec_invalidated(); - - this->game_spec = game_spec; - - if (this->game_spec) { - QObject::connect(this->game_spec.data(), &GameSpecLink::game_spec_loaded, this, &GuiImageProviderLink::on_game_spec_loaded); - - if (std::shared_ptr spec = this->game_spec->get_loaded_spec()) - this->image_provider.on_game_spec_loaded(spec); - } - } -} - QObject *GuiImageProviderLink::provider(QQmlEngine *engine, const char *id) { qtsdl::QmlEngineWithSingletonItemsInfo *engine_with_singleton_items_info = qtsdl::checked_static_cast(engine); auto image_providers = engine_with_singleton_items_info->get_image_providers(); @@ -58,12 +30,7 @@ QObject *GuiImageProviderLink::provider(QQmlEngine *engine, const char *id) { ENSURE(found_it != std::end(image_providers), "The image provider '" << id << "' wasn't created or wasn't passed to the QML engine creation function."); // owned by the QML engine - return new GuiImageProviderLink{nullptr, *qtsdl::checked_static_cast(*found_it)}; -} - -void GuiImageProviderLink::on_game_spec_loaded(GameSpecLink *game_spec, std::shared_ptr loaded_game_spec) { - if (this->game_spec == game_spec) - this->image_provider.on_game_spec_loaded(loaded_game_spec); + return nullptr; } } // namespace openage::gui diff --git a/libopenage/gui/integration/private/gui_image_provider_link.h b/libopenage/gui/integration/private/gui_image_provider_link.h index 510214f652..5090edcf2c 100644 --- a/libopenage/gui/integration/private/gui_image_provider_link.h +++ b/libopenage/gui/integration/private/gui_image_provider_link.h @@ -12,46 +12,16 @@ QT_FORWARD_DECLARE_CLASS(QJSEngine) namespace openage { -class GameSpec; - namespace gui { -class GuiGameSpecImageProviderImpl; -class GameSpecLink; - class GuiImageProviderLink : public QObject { Q_OBJECT - Q_PROPERTY(openage::gui::GameSpecLink *gameSpec READ get_game_spec WRITE set_game_spec) - public: - explicit GuiImageProviderLink(QObject *parent, GuiGameSpecImageProviderImpl &image_provider); + explicit GuiImageProviderLink(QObject *parent); virtual ~GuiImageProviderLink(); - GameSpecLink *get_game_spec() const; - - /** - * Sets the game spec to load textures from. - * - * Setting to null doesn't detach from the spec, but picks the - * 'missing texture' from that spec and sets it to every sprite. - */ - void set_game_spec(GameSpecLink *game_spec); - static QObject *provider(QQmlEngine *, const char *id); - -private slots: - /** - * Pass loaded assets to the image provider. - * - * Need to check if we still attached to that spec. - * Also it may be invalidated in the meantime, so share the ownership. - */ - void on_game_spec_loaded(GameSpecLink *game_spec, std::shared_ptr loaded_game_spec); - -private: - GuiGameSpecImageProviderImpl &image_provider; - QPointer game_spec; }; } // namespace gui diff --git a/libopenage/gui/integration/private/gui_texture_factory.cpp b/libopenage/gui/integration/private/gui_texture_factory.cpp deleted file mode 100644 index 35bc04cea1..0000000000 --- a/libopenage/gui/integration/private/gui_texture_factory.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "gui_texture_factory.h" - -#include "gui_filled_texture_handles.h" -#include "gui_game_spec_image_provider_impl.h" -#include "gui_texture.h" - -namespace openage::gui { - -GuiTextureFactory::GuiTextureFactory(GuiGameSpecImageProviderImpl *provider, const QString &id, const QSize &requested_size) : - texture_handle(), - texture_handle_user{provider->fill_texture_handle(id, requested_size, &this->texture_handle)} { -} - -GuiTextureFactory::~GuiTextureFactory() = default; - -QSGTexture *GuiTextureFactory::createTexture(QQuickWindow *window) const { - Q_UNUSED(window); - return new GuiTexture{this->texture_handle}; -} - -int GuiTextureFactory::textureByteCount() const { - return 0; -} - -QSize GuiTextureFactory::textureSize() const { - return openage::gui::textureSize(this->texture_handle); -} - -} // namespace openage::gui diff --git a/libopenage/gui/integration/private/gui_texture_factory.h b/libopenage/gui/integration/private/gui_texture_factory.h deleted file mode 100644 index bf4007c0a3..0000000000 --- a/libopenage/gui/integration/private/gui_texture_factory.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include - -#include "gui_texture_handle.h" -#include "gui_filled_texture_handles.h" - -namespace openage { -namespace gui { - -class GuiGameSpecImageProviderImpl; - -class GuiTextureFactory : public QQuickTextureFactory { - Q_OBJECT - -public: - explicit GuiTextureFactory(GuiGameSpecImageProviderImpl *provider, const QString &id, const QSize &requested_size); - virtual ~GuiTextureFactory(); - - virtual QSGTexture* createTexture(QQuickWindow *window) const override; - virtual int textureByteCount() const override; - virtual QSize textureSize() const override; - -private: - SizedTextureHandle texture_handle; - GuiFilledTextureHandleUser texture_handle_user; -}; - -}} // namespace openage::gui diff --git a/libopenage/gui/resources_list_model.cpp b/libopenage/gui/resources_list_model.cpp deleted file mode 100644 index d804d147b4..0000000000 --- a/libopenage/gui/resources_list_model.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2016-2023 the openage authors. See copying.md for legal info. - -#include "resources_list_model.h" - -#include -#include - -#include - -#include "../error/error.h" - -namespace openage::gui { - -namespace { -const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "Resources"); - -const auto resource_type_count = static_cast::type>(game_resource::RESOURCE_TYPE_COUNT); - -} // namespace - -ResourcesListModel::ResourcesListModel(QObject *parent) : - QAbstractListModel(parent), - amounts(resource_type_count) { - Q_UNUSED(registration); -} - -ResourcesListModel::~ResourcesListModel() = default; - -void ResourcesListModel::on_resource_changed(game_resource resource, int amount) { - int i = static_cast(resource); - ENSURE(i >= 0 && i < std::distance(std::begin(this->amounts), std::end(this->amounts)), "Res type index is out of range: '" << i << "'."); - - if (this->amounts[i] != amount) { - auto model_index = this->index(i); - - this->amounts[i] = amount; - emit this->dataChanged(model_index, model_index, QVector{Qt::DisplayRole}); - } -} - -int ResourcesListModel::rowCount(const QModelIndex &) const { - ENSURE(resource_type_count == this->amounts.size(), "Res type count is compile-time const '" << resource_type_count << "', but got '" << this->amounts.size() << "'."); - return this->amounts.size(); -} - -QVariant ResourcesListModel::data(const QModelIndex &index, int role) const { - const int i = index.row(); - - switch (role) { - case Qt::DisplayRole: - ENSURE(i >= 0 && i < std::distance(std::begin(this->amounts), std::end(this->amounts)), "Res type index is out of range: '" << i << "'."); - return this->amounts[index.row()]; - - default: - return QVariant{}; - } -} - -} // namespace openage::gui diff --git a/libopenage/gui/resources_list_model.h b/libopenage/gui/resources_list_model.h deleted file mode 100644 index 51ef6425bb..0000000000 --- a/libopenage/gui/resources_list_model.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2016-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -#include - -#include "../gamestate/old/resource.h" - -namespace openage { -namespace gui { - -/** - * Resource table for the gui. - */ -class ResourcesListModel : public QAbstractListModel { - Q_OBJECT - -public: - ResourcesListModel(QObject *parent = nullptr); - virtual ~ResourcesListModel(); - -private slots: - void on_resource_changed(game_resource resource, int amount); - -private: - virtual int rowCount(const QModelIndex &) const override; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - - std::vector amounts; -}; - -} // namespace gui -} // namespace openage diff --git a/libopenage/pathfinding/a_star.cpp b/libopenage/pathfinding/a_star.cpp index 03b85def97..7d9d9275cb 100644 --- a/libopenage/pathfinding/a_star.cpp +++ b/libopenage/pathfinding/a_star.cpp @@ -1,4 +1,4 @@ -// Copyright 2014-2019 the openage authors. See copying.md for legal info. +// Copyright 2014-2023 the openage authors. See copying.md for legal info. /** @file * @@ -17,10 +17,9 @@ #include "../datastructure/pairing_heap.h" #include "../log/log.h" #include "../terrain/terrain.h" -#include "../terrain/terrain_object.h" #include "../util/strings.h" -#include "path.h" #include "heuristics.h" +#include "path.h" namespace openage { @@ -30,7 +29,6 @@ namespace path { Path to_point(coord::phys3 start, coord::phys3 end, std::function passable) { - auto valid_end = [&](const coord::phys3 &point) -> bool { return euclidean_squared_cost(point, end) < path_grid_size.to_float(); }; @@ -41,18 +39,18 @@ Path to_point(coord::phys3 start, } -Path to_object(openage::TerrainObject *to_move, - openage::TerrainObject *end, - coord::phys_t rad) { - coord::phys3 start = to_move->pos.draw; - auto valid_end = [&](const coord::phys3 &pos) -> bool { - return end->from_edge(pos) < rad; - }; - auto heuristic = [&](const coord::phys3 &pos) -> cost_t { - return (end->from_edge(pos) - to_move->min_axis() / 2L).to_float(); - }; - return a_star(start, valid_end, heuristic, to_move->passable); -} +// Path to_object(openage::TerrainObject *to_move, +// openage::TerrainObject *end, +// coord::phys_t rad) { +// coord::phys3 start = to_move->pos.draw; +// auto valid_end = [&](const coord::phys3 &pos) -> bool { +// return end->from_edge(pos) < rad; +// }; +// auto heuristic = [&](const coord::phys3 &pos) -> cost_t { +// return (end->from_edge(pos) - to_move->min_axis() / 2L).to_float(); +// }; +// return a_star(start, valid_end, heuristic, to_move->passable); +// } Path find_nearest(coord::phys3 start, @@ -67,7 +65,6 @@ Path a_star(coord::phys3 start, std::function valid_end, std::function heuristic, std::function passable) { - // path node storage, always provides cheapest next node. heap_t node_candidates; @@ -93,9 +90,7 @@ Path a_star(coord::phys3 start, // node to terminate the search was found if (valid_end(best_candidate->position)) { - log::log(MSG(dbg) << - "path cost is " << - util::FloatFixed<3, 8>{closest_node->future_cost}); + log::log(MSG(dbg) << "path cost is " << util::FloatFixed<3, 8>{closest_node->future_cost}); return best_candidate->generate_backtrace(); } @@ -128,26 +123,26 @@ Path a_star(coord::phys3 start, } // update new cost knowledge - neighbor->past_cost = new_past_cost; - neighbor->future_cost = neighbor->past_cost + neighbor->heuristic_cost; + neighbor->past_cost = new_past_cost; + neighbor->future_cost = neighbor->past_cost + neighbor->heuristic_cost; neighbor->path_predecessor = best_candidate; if (not_visited) { neighbor->heap_node = node_candidates.push(neighbor); visited_tiles[neighbor->position] = neighbor; - } else { + } + else { node_candidates.decrease(neighbor->heap_node); } } } } - log::log(MSG(dbg) << - "incomplete path cost is " << - util::FloatFixed<3, 8>{closest_node->future_cost}); + log::log(MSG(dbg) << "incomplete path cost is " << util::FloatFixed<3, 8>{closest_node->future_cost}); return closest_node->generate_backtrace(); } -}} // namespace openage::path +} // namespace path +} // namespace openage diff --git a/libopenage/pathfinding/a_star.h b/libopenage/pathfinding/a_star.h index 15d95066e1..a7cc5aa75e 100644 --- a/libopenage/pathfinding/a_star.h +++ b/libopenage/pathfinding/a_star.h @@ -1,4 +1,4 @@ -// Copyright 2014-2016 the openage authors. See copying.md for legal info. +// Copyright 2014-2023 the openage authors. See copying.md for legal info. #pragma once @@ -9,8 +9,6 @@ namespace openage { -class TerrainObject; - namespace path { /** @@ -23,9 +21,9 @@ Path to_point(coord::phys3 start, /** * path between 2 objects, with how close to come to end point */ -Path to_object(TerrainObject *to_move, - TerrainObject *end, - coord::phys_t rad); +// Path to_object(TerrainObject *to_move, +// TerrainObject *end, +// coord::phys_t rad); /** * path to nearest object with lambda diff --git a/libopenage/terrain/CMakeLists.txt b/libopenage/terrain/CMakeLists.txt index c7ae65ad65..753cf4249a 100644 --- a/libopenage/terrain/CMakeLists.txt +++ b/libopenage/terrain/CMakeLists.txt @@ -1,6 +1,4 @@ add_sources(libopenage terrain.cpp terrain_chunk.cpp - terrain_object.cpp - terrain_search.cpp ) diff --git a/libopenage/terrain/terrain.cpp b/libopenage/terrain/terrain.cpp index 62eeefc32b..7ad26a0899 100644 --- a/libopenage/terrain/terrain.cpp +++ b/libopenage/terrain/terrain.cpp @@ -16,7 +16,6 @@ #include "../util/strings.h" #include "terrain_chunk.h" -#include "terrain_object.h" namespace openage { @@ -139,23 +138,6 @@ TileContent *Terrain::get_data(const coord::tile &position) { } } -TerrainObject *Terrain::obj_at_point(const coord::phys3 &point) { - coord::tile t = point.to_tile(); - TileContent *tc = this->get_data(t); - if (!tc) { - return nullptr; - } - - // prioritise selecting the smallest object - TerrainObject *smallest = nullptr; - for (auto obj_ptr : tc->obj) { - if (obj_ptr->contains(point) && (!smallest || obj_ptr->min_axis() < smallest->min_axis())) { - smallest = obj_ptr; - } - } - return smallest; -} - bool Terrain::validate_terrain(terrain_t terrain_id) { if (terrain_id >= static_cast(this->meta->terrain_id_count)) { throw Error(MSG(err) << "Requested terrain_id is out of range: " << terrain_id); @@ -301,7 +283,7 @@ struct terrain_render_data Terrain::create_draw_advice(const coord::tile &ab, // ordered set of objects on the terrain (buildings.) // it's ordered by the visibility layers. - auto objects = &data.objects; + // auto objects = &data.objects; coord::tile gb = {gh.ne, ab.se}; coord::tile cf = {cd.ne, ef.se}; @@ -321,9 +303,9 @@ struct terrain_render_data Terrain::create_draw_advice(const coord::tile &ab, // TODO: make the terrain independent of objects standing on it. TileContent *tile_content = this->get_data(tilepos); if (tile_content != nullptr) { - for (auto obj_item : tile_content->obj) { - objects->insert(obj_item); - } + // for (auto obj_item : tile_content->obj) { + // objects->insert(obj_item); + // } } } } diff --git a/libopenage/terrain/terrain.h b/libopenage/terrain/terrain.h index 4db8fdbcb1..02ceba1cae 100644 --- a/libopenage/terrain/terrain.h +++ b/libopenage/terrain/terrain.h @@ -19,7 +19,6 @@ namespace openage { class RenderOptions; class TerrainChunk; -class TerrainObject; /** * type that for terrain ids. @@ -53,7 +52,6 @@ class TileContent { TileContent(); ~TileContent(); terrain_t terrain_id; - std::vector obj; }; @@ -140,7 +138,6 @@ struct tile_draw_data { */ struct terrain_render_data { std::vector tiles; - std::set> objects; }; /** @@ -229,11 +226,6 @@ class Terrain { */ TileContent *get_data(const coord::tile &position); - /** - * an object which contains the given point, null otherwise - */ - TerrainObject *obj_at_point(const coord::phys3 &point); - /** * get the neighbor chunks of a given chunk. * diff --git a/libopenage/terrain/terrain_chunk.cpp b/libopenage/terrain/terrain_chunk.cpp index aec7d2c6ec..0fd77923dc 100644 --- a/libopenage/terrain/terrain_chunk.cpp +++ b/libopenage/terrain/terrain_chunk.cpp @@ -12,7 +12,6 @@ #include "../util/misc.h" #include "terrain.h" -#include "terrain_object.h" namespace openage { diff --git a/libopenage/terrain/terrain_chunk.h b/libopenage/terrain/terrain_chunk.h index 676cfcc1e4..683d46c0fd 100644 --- a/libopenage/terrain/terrain_chunk.h +++ b/libopenage/terrain/terrain_chunk.h @@ -14,7 +14,6 @@ namespace openage { class Terrain; class TerrainChunk; class TileContent; -class TerrainObject; /** diff --git a/libopenage/terrain/terrain_object.cpp b/libopenage/terrain/terrain_object.cpp deleted file mode 100644 index a81716491a..0000000000 --- a/libopenage/terrain/terrain_object.cpp +++ /dev/null @@ -1,463 +0,0 @@ -// Copyright 2013-2023 the openage authors. See copying.md for legal info. - -#include "terrain_object.h" - -#include -#include - -#include "../coord/phys.h" -#include "../coord/pixel.h" -#include "../coord/tile.h" -#include "../error/error.h" -#include "../unit/unit.h" - -#include "terrain.h" -#include "terrain_chunk.h" - -namespace openage { - -TerrainObject::TerrainObject(Unit &u) : - unit(u), - passable{[](const coord::phys3 &) -> bool { return true; }}, - state{object_state::removed}, - occupied_chunk_count{0}, - parent{nullptr} { -} - -TerrainObject::~TerrainObject() { - // remove all connections from terrain - this->unit.log(MSG(dbg) << "Cleanup terrain object"); - this->remove(); -} - -bool TerrainObject::is_floating() const { - // if parent is floating then all children also are - if (this->parent && this->parent->is_floating()) { - return true; - } - return this->state == object_state::floating; -} - -bool TerrainObject::is_placed() const { - // if object has a parent it must be placed - if (this->parent && !this->parent->is_placed()) { - return false; - } - return this->state == object_state::placed || this->state == object_state::placed_no_collision; -} - - -bool TerrainObject::check_collisions() const { - // if object has a parent it must be placed - if (this->parent && !this->parent->is_placed()) { - return false; - } - return this->state == object_state::placed; -} - -bool TerrainObject::place(object_state init_state) { - if (this->state == object_state::removed) { - throw Error(MSG(err) << "Building cannot change state with no position"); - } - - // remove any other floating objects - // which intersect with the new placement - // if non-floating objects are on the foundation - // then this placement will fail - for (coord::tile temp_pos : tile_list(this->pos)) { - std::vector to_remove; - TerrainChunk *chunk = this->get_terrain()->get_chunk(temp_pos); - - if (chunk == nullptr) { - continue; - } - - for (auto obj : chunk->get_data(temp_pos)->obj) { - // ignore self and annexes of self - if (obj != this && obj->get_parent() != this) { - if (obj->is_floating()) { - // floating objects get removed - to_remove.push_back(obj); - } - else if (obj->check_collisions()) { - // solid objects obstruct placement - return false; - } - } - } - - // all obstructing objects get deleted - for (auto remove_obj : to_remove) { - remove_obj->unit.location = nullptr; - } - } - - // set new state - this->state = init_state; - return true; -} - -bool TerrainObject::place(const std::shared_ptr &t, coord::phys3 &position, object_state init_state) { - if (this->state != object_state::removed) { - throw Error(MSG(err) << "This object has already been placed."); - } - else if (init_state == object_state::removed) { - throw Error(MSG(err) << "Cannot place an object with removed state."); - } - - // use passiblity test - if (not this->passable(position)) { - return false; - } - - // place on terrain - this->place_unchecked(t, position); - - // set state - this->state = init_state; - return true; -} - -bool TerrainObject::move(coord::phys3 &position) { - if (this->state == object_state::removed) { - return false; - } - auto old_state = this->state; - - // TODO should do outside of this function - bool can_move = this->passable(position); - if (can_move) { - this->remove(); - this->place_unchecked(this->get_terrain(), position); - this->state = old_state; - } - return can_move; -} - -void TerrainObject::remove() { - // remove all children first - for (auto &c : this->children) { - c->remove(); - } - this->children.clear(); - - if (this->occupied_chunk_count == 0 || this->state == object_state::removed) { - return; - } - - for (coord::tile temp_pos : tile_list(this->pos)) { - TerrainChunk *chunk = this->get_terrain()->get_chunk(temp_pos); - - if (chunk == nullptr) { - continue; - } - - auto &v = chunk->get_data(temp_pos.get_pos_on_chunk())->obj; - auto position_it = std::remove_if( - std::begin(v), - std::end(v), - [this](TerrainObject *obj) { - return this == obj; - }); - v.erase(position_it, std::end(v)); - } - - this->occupied_chunk_count = 0; - this->state = object_state::removed; -} - -void TerrainObject::set_ground(int id, int additional) { - if (not this->is_placed()) { - throw Error(MSG(err) << "Setting ground for object that is not placed yet."); - } - - coord::tile temp_pos = this->pos.start; - temp_pos.ne -= additional; - temp_pos.se -= additional; - while (temp_pos.ne < this->pos.end.ne + additional) { - while (temp_pos.se < this->pos.end.se + additional) { - TerrainChunk *chunk = this->get_terrain()->get_chunk(temp_pos); - - if (chunk == nullptr) { - continue; - } - - chunk->get_data(temp_pos.get_pos_on_chunk())->terrain_id = id; - temp_pos.se++; - } - temp_pos.se = this->pos.start.se - additional; - temp_pos.ne++; - } -} - -const TerrainObject *TerrainObject::get_parent() const { - return this->parent; -} - -std::vector TerrainObject::get_children() const { - // TODO: a better performing way of doing this - // for example accept a lambda to use for each element - // or maintain a duplicate class field for raw pointers - - std::vector result; - for (auto &obj : this->children) { - result.push_back(obj.get()); - } - return result; -} - -bool TerrainObject::operator<(const TerrainObject &other) { - if (this == &other) { - return false; - } - - auto this_ne = this->pos.draw.ne; - auto this_se = this->pos.draw.se; - auto other_ne = other.pos.draw.ne; - auto other_se = other.pos.draw.se; - - auto this_ypos = this_ne - this_se; - auto other_ypos = other_ne - other_se; - - if (this_ypos < other_ypos) { - return false; - } - else if (this_ypos == other_ypos) { - if (this_ne > other_ne) { - return false; - } - else if (this_ne == other_ne) { - return this_se > other_se; - } - } - - return true; -} - -void TerrainObject::place_unchecked(const std::shared_ptr &t, coord::phys3 &position) { - // storing the position: - this->pos = this->get_range(position, *t); - this->terrain = t; - this->occupied_chunk_count = 0; - - bool chunk_known = false; - - - // set pointers to this object on each terrain tile - // where the building will stand and block the ground - for (coord::tile temp_pos : tile_list(this->pos)) { - TerrainChunk *chunk = this->get_terrain()->get_chunk(temp_pos); - - if (chunk == nullptr) { - continue; - } - - for (int c = 0; c < this->occupied_chunk_count; c++) { - if (this->occupied_chunk[c] == chunk) { - chunk_known = true; - } - } - - if (not chunk_known) { - this->occupied_chunk[this->occupied_chunk_count] = chunk; - this->occupied_chunk_count += 1; - } - else { - chunk_known = false; - } - - chunk->get_data(temp_pos.get_pos_on_chunk())->obj.push_back(this); - } -} - -SquareObject::SquareObject(Unit &u, coord::tile_delta foundation_size) : - TerrainObject(u), - size(foundation_size) { -} - -SquareObject::~SquareObject() = default; - -tile_range SquareObject::get_range(const coord::phys3 &pos, const Terrain &terrain) const { - return building_center(pos, this->size, terrain); -} - -coord::phys_t SquareObject::from_edge(const coord::phys3 &point) const { - // clamp between start and end - coord::phys2 start_phys = this->pos.start.to_phys2(); - coord::phys2 end_phys = this->pos.end.to_phys2(); - - coord::phys_t cx = std::max(start_phys.ne, std::min(end_phys.ne, point.ne)); - coord::phys_t cy = std::max(start_phys.se, std::min(end_phys.se, point.se)); - - // distance to clamped point - coord::phys_t dx = point.ne - cx; - coord::phys_t dy = point.se - cy; - return std::hypot(dx, dy); -} - -coord::phys3 SquareObject::on_edge(const coord::phys3 &angle, coord::phys_t /* extra */) const { - // clamp between start and end - // TODO extra is unused - coord::phys2 start_phys = this->pos.start.to_phys2(); - coord::phys2 end_phys = this->pos.end.to_phys2(); - coord::phys_t cx = std::max(start_phys.ne, std::min(end_phys.ne, angle.ne)); - coord::phys_t cy = std::max(start_phys.se, std::min(end_phys.se, angle.se)); - - // todo use extra distance - return coord::phys3{cx, cy, 0}; -} - -bool SquareObject::contains(const coord::phys3 &other) const { - coord::tile other_tile = other.to_tile3().to_tile(); - - for (coord::tile check_pos : tile_list(this->pos)) { - if (check_pos == other_tile) { - return true; - } - } - return false; -} - -bool SquareObject::intersects(const TerrainObject &other, const coord::phys3 &position) const { - if (const auto *sq = dynamic_cast(&other)) { - auto terrain_ptr = this->terrain.lock(); - if (not terrain_ptr) { - throw Error{ERR << "object is not associated to a valid terrain"}; - } - - tile_range rng = this->get_range(position, *terrain_ptr); - return this->pos.end.ne < rng.start.ne - || rng.end.ne < sq->pos.start.ne - || rng.end.se < sq->pos.start.se - || rng.end.se < sq->pos.start.se; - } - else if (const auto *rad = dynamic_cast(&other)) { - auto terrain_ptr = this->terrain.lock(); - if (not terrain_ptr) { - throw Error{ERR << "object is not associated to a valid terrain"}; - } - // clamp between start and end - tile_range rng = this->get_range(position, *terrain_ptr); - coord::phys2 start_phys = rng.start.to_phys2(); - coord::phys2 end_phys = rng.end.to_phys2(); - coord::phys_t cx = std::max(start_phys.ne, std::min(end_phys.ne, rad->pos.draw.ne)); - coord::phys_t cy = std::max(start_phys.se, std::min(end_phys.se, rad->pos.draw.se)); - - // distance to square object base - coord::phys_t dx = rad->pos.draw.ne - cx; - coord::phys_t dy = rad->pos.draw.se - cy; - return std::hypot(dx, dy) < rad->phys_radius.to_double(); - } - return false; -} - -coord::phys_t SquareObject::min_axis() const { - return std::min(this->size.ne, this->size.se); -} - -RadialObject::RadialObject(Unit &u, float rad) : - TerrainObject(u), - phys_radius(rad) { -} - -RadialObject::~RadialObject() = default; - -tile_range RadialObject::get_range(const coord::phys3 &pos, const Terrain & /*terrain*/) const { - tile_range result; - - // create bounds - coord::phys3 p_start = pos, p_end = pos; - p_start.ne -= this->phys_radius; - p_start.se -= this->phys_radius; - p_end.ne += this->phys_radius; - p_end.se += this->phys_radius; - - // set result - result.start = p_start.to_tile3().to_tile(); - result.end = p_end.to_tile3().to_tile() + coord::tile_delta{1, 1}; - result.draw = pos; - return result; -} - -coord::phys_t RadialObject::from_edge(const coord::phys3 &point) const { - return std::max( - coord::phys_t(point.to_phys2().distance(this->pos.draw.to_phys2())) - this->phys_radius, - static_cast(0)); -} - -coord::phys3 RadialObject::on_edge(const coord::phys3 &angle, coord::phys_t extra) const { - return this->pos.draw + (angle - this->pos.draw).to_phys2().normalize((this->phys_radius + extra).to_double()).to_phys3(); -} - -bool RadialObject::contains(const coord::phys3 &other) const { - return this->pos.draw.to_phys2().distance(other.to_phys2()) < this->phys_radius.to_double(); -} - -bool RadialObject::intersects(const TerrainObject &other, const coord::phys3 &position) const { - if (const auto *sq = dynamic_cast(&other)) { - return sq->from_edge(position) < this->phys_radius; - } - else if (const auto *rad = dynamic_cast(&other)) { - return position.to_phys2().distance(rad->pos.draw.to_phys2()) < (this->phys_radius + rad->phys_radius).to_double(); - } - return false; -} - -coord::phys_t RadialObject::min_axis() const { - return this->phys_radius * 2; -} - -std::vector tile_list(const tile_range &rng) { - std::vector tiles; - - coord::tile check_pos = rng.start; - while (check_pos.ne < rng.end.ne) { - while (check_pos.se < rng.end.se) { - tiles.push_back(check_pos); - check_pos.se += 1; - } - check_pos.se = rng.start.se; - check_pos.ne += 1; - } - - // a case when the objects radius is zero - if (tiles.empty()) { - tiles.push_back(rng.start); - } - return tiles; -} - -tile_range building_center(coord::phys3 west, coord::tile_delta size, const Terrain &terrain) { - tile_range result; - - // TODO it should be possible that the building is placed on any position, - // not just tile positions. - result.start = west.to_tile(); - result.end = result.start + size; - - coord::phys2 draw_pos = result.start.to_phys2(); - - draw_pos.ne += coord::phys_t(size.ne / 2.0f); - draw_pos.se += coord::phys_t(size.se / 2.0f); - - result.draw = draw_pos.to_phys3(terrain); - return result; -} - -bool complete_building(Unit &u) { - if (u.has_attribute(attr_type::building)) { - auto &build = u.get_attribute(); - build.completed = 1.0f; - - // set ground under a completed building - auto target_location = u.location.get(); - bool placed_ok = target_location->place(build.completion_state); - if (placed_ok) { - target_location->set_ground(build.foundation_terrain, 0); - } - return placed_ok; - } - return false; -} - -} // namespace openage diff --git a/libopenage/terrain/terrain_object.h b/libopenage/terrain/terrain_object.h deleted file mode 100644 index 93657db11d..0000000000 --- a/libopenage/terrain/terrain_object.h +++ /dev/null @@ -1,332 +0,0 @@ -// Copyright 2013-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -#include "../coord/phys.h" -#include "../coord/tile.h" - -namespace openage { - -class Terrain; -class TerrainChunk; -class Texture; -class Unit; - -/** - * only placed will enable collision checks - */ -enum class object_state { - removed, - floating, - placed, - placed_no_collision -}; - -/** - * A rectangle or square of tiles which is the minimim - * space to fit the units foundation or radius - * the end tile will have ne and se values greater or equal to - * the start tile - */ -struct tile_range { - coord::tile start{0, 0}; - coord::tile end{0, 0}; // start <= end - coord::phys3 draw{0, 0, 0}; // gets used as center point of radial objects -}; - -/** - * get all tiles in the tile range -- useful for iterating - * returns a flat list of tiles between the rectangle enclosed - * by the tile_range start and end tiles - */ -std::vector tile_list(const tile_range &rng); - -/** - * given the west most point of a building foundation and the tile_delta - * size of the foundation, this will return the tile range covered by the base, - * which includes start and end tiles, and phys3 center point (used for drawing) - */ -tile_range building_center(coord::phys3 west, coord::tile_delta size, const Terrain &terrain); - -/** - * sets a building to a fully completed state - */ -bool complete_building(Unit &); - -/** - * Base class for map location types which include square tile aligned - * positions and radial positions This enables two inheriting classes - * SquareObject and RadialObject to specify different areas of the map - * - * All TerrainObjects are owned by a Unit, to construct TerrainObjects, - * use the make_location function on any Unit - * - * This class allows intersection testing between two TerrainObjects to - * cover all cases of intersection (water, land or flying objects) the units - * lambda function is used which takes a tile and returns a bool value of - * whether that tile can be passed by this - * - * The name of this class is likely to change to TerrainBase or TerrainSpace - */ -class TerrainObject : public std::enable_shared_from_this { -public: - TerrainObject(Unit &u); - TerrainObject(const TerrainObject &) = delete; // disable copy constructor - TerrainObject(TerrainObject &&) = delete; // disable move constructor - virtual ~TerrainObject(); - - /** - * the range of tiles which are covered by this object - */ - tile_range pos; - - /* - * unit which is inside this base - * used to find the unit from user actions - * - * every terrain object should contain a single unit - */ - Unit &unit; - - /** - * is the object a floating outline -- it is only an indicator - * of where a building will be built, but not yet started building - * and does not affect any collisions - */ - bool is_floating() const; - - /** - * returns true if this object has been placed. this indicates that the object has a position and exists - * on the map, floating buildings are not considered placed as they are only an indicator - * for where something can begin construction - */ - bool is_placed() const; - - /** - * should this object be tested for collisions, which decides whether another object is allowed - * to overlap the location of this object. arrows and decaying objects will return false - */ - bool check_collisions() const; - - /** - * decide which terrains this object can be on - * this function should be true if given a valid position for the object - */ - std::function passable; - - /** - * changes the placement state of this object keeping the existing - * position. this is useful for upgrading a floating building to a placed state - */ - bool place(object_state init_state); - - /** - * binds the TerrainObject to a certain TerrainChunk. - * - * @param terrain: the terrain where the object will be placed onto. - * @param pos: (tile) position of the (nw,sw) corner - * @param init_state should be floating, placed or placed_no_collision - * @returns true when the object was placed, false when it did not fit at pos. - */ - bool place(const std::shared_ptr &t, coord::phys3 &pos, object_state init_state); - - /** - * moves the object -- returns false if object cannot be moved here - */ - bool move(coord::phys3 &pos); - - /** - * remove this TerrainObject from the terrain chunks. - */ - void remove(); - - /** - * sets all the ground below the object to a terrain id. - * - * @param id: the terrain id to which the ground is set - * @param additional: amount of additional space arround the building - */ - void set_ground(int id, int additional = 0); - - - /** - * appends new annex location for this object - * - * this does not replace any existing annex - */ - template - TerrainObject *make_annex(Arg... args) { - this->children.emplace_back(std::unique_ptr(new T(this->unit, args...))); - auto &annex_ptr = this->children.back(); - annex_ptr->parent = this; - return annex_ptr.get(); - } - - /** - * Returns the parent terrain object, - * if null the object has no parent which is - * the case for most objects - * - * objects with a parent are owned by that object - * and to be placed on the map the parent must also be placed - */ - const TerrainObject *get_parent() const; - - /** - * Returns a list of child objects, this is the inverse of the - * get_parent() function - * - * TODO: this does not perform optimally and is likely to change - */ - std::vector get_children() const; - - /* - * terrain this object was placed on - */ - std::shared_ptr get_terrain() const { - return terrain.lock(); - } - - /** - * comparison for TerrainObjects. - * - * sorting for vertical placement. - * by using this order algorithm, the overlapping order - * is optimal so the objects can be drawn in correct order. - */ - bool operator<(const TerrainObject &other); - - /** - * returns the range of tiles covered if the object was in the given pos - * @param pos the position to find a range for - */ - virtual tile_range get_range(const coord::phys3 &pos, const Terrain &terrain) const = 0; - - /** - * how far is a point from the edge of this object - */ - virtual coord::phys_t from_edge(const coord::phys3 &point) const = 0; - - /** - * get a position on the edge of this object - */ - virtual coord::phys3 on_edge(const coord::phys3 &angle, coord::phys_t extra = 0) const = 0; - - /** - * does this space contain a given point - */ - virtual bool contains(const coord::phys3 &other) const = 0; - - /** - * would this intersect with another object if it were positioned at the given point - */ - virtual bool intersects(const TerrainObject &other, const coord::phys3 &position) const = 0; - - /** - * the shortest line that can be placed across the objects center - */ - virtual coord::phys_t min_axis() const = 0; - -protected: - object_state state; - - std::weak_ptr terrain; - int occupied_chunk_count; - TerrainChunk *occupied_chunk[4]; - - /** - * annexes and grouped units - */ - TerrainObject *parent; - std::vector> children; - - /** - * placement function which does not check passibility - * used only when passibilty is already checked - * otherwise the place function should be used - * this does not modify the units placement state - */ - void place_unchecked(const std::shared_ptr &t, coord::phys3 &position); -}; - -/** - * terrain object class represents one immobile object on the map (building, trees, fish, ...). - * can only be constructed by unit->make_location(...) - */ -class SquareObject : public TerrainObject { -public: - virtual ~SquareObject(); - - - /** - * tile size of this objects base - */ - const coord::tile_delta size; - - /** - * calculate object start and end positions. - * - * @param pos: the center position of the building - * - * set the center position to "middle", - * start_pos is % and end_pos = & - * - * for a building, the # tile will be "the clicked one": - * @ @ @ - * @ @ @ @ %# & - * @ @ @ % # & @ - * % # @ & @ @ - * @ @ @ @ - * @ @ - * @ - */ - tile_range get_range(const coord::phys3 &pos, const Terrain &terrain) const override; - - coord::phys_t from_edge(const coord::phys3 &point) const override; - coord::phys3 on_edge(const coord::phys3 &angle, coord::phys_t extra = 0) const override; - bool contains(const coord::phys3 &other) const override; - bool intersects(const TerrainObject &other, const coord::phys3 &position) const override; - coord::phys_t min_axis() const override; - -private: - SquareObject(Unit &u, coord::tile_delta foundation_size); - - friend class TerrainObject; - friend class Unit; -}; - -/** - * Represents circular shaped objects (movable game units) - * can only be constructed by unit->make_location(...) - */ -class RadialObject : public TerrainObject { -public: - virtual ~RadialObject(); - - /** - * radius of this cirular space - */ - const coord::phys_t phys_radius; - - /** - * finds the range covered if the object was in a position - */ - tile_range get_range(const coord::phys3 &pos, const Terrain &terrain) const override; - - coord::phys_t from_edge(const coord::phys3 &point) const override; - coord::phys3 on_edge(const coord::phys3 &angle, coord::phys_t extra = 0) const override; - bool contains(const coord::phys3 &other) const override; - bool intersects(const TerrainObject &other, const coord::phys3 &position) const override; - coord::phys_t min_axis() const override; - -private: - RadialObject(Unit &u, float rad); - - friend class TerrainObject; - friend class Unit; -}; - -} // namespace openage diff --git a/libopenage/terrain/terrain_search.cpp b/libopenage/terrain/terrain_search.cpp deleted file mode 100644 index 7e3d0db22f..0000000000 --- a/libopenage/terrain/terrain_search.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#include - -#include "terrain.h" -#include "terrain_object.h" -#include "terrain_search.h" - -namespace openage { - -TerrainObject *find_near(const TerrainObject &start, - std::function found, - unsigned int search_limit) { - - auto terrain = start.get_terrain(); - auto tile = start.pos.draw.to_tile3().to_tile(); - TerrainSearch search(terrain, tile); - - for (unsigned int i = 0; i < search_limit; ++i) { - for (auto o : terrain->get_data(tile)->obj) { - - // invalid pointers are removed when the object is deleted - if (found(*o)) { - return o; - } - } - tile = search.next_tile(); - } - - return nullptr; -} - -TerrainObject *find_in_radius(const TerrainObject &start, - std::function found, - float radius) { - auto terrain = start.get_terrain(); - coord::tile start_tile = start.pos.draw.to_tile3().to_tile(); - TerrainSearch search(terrain, start_tile, radius); - - // next_tile will first return the starting tile, so we need to run it once. We also - // shouldn't discard this tile - if it isn't useful, ignore it in found - coord::tile tile = search.next_tile(); - do { - for (auto o : terrain->get_data(tile)->obj) { - if (found(*o)) { - return o; - } - } - tile = search.next_tile(); - // coord::tile doesn't have a != operator, so we need to use !(a==b) - } while (!(tile == start_tile)); - - return nullptr; -} - -TerrainSearch::TerrainSearch(std::shared_ptr t, coord::tile s) - : - TerrainSearch(t, s, .0f) { -} - -TerrainSearch::TerrainSearch(std::shared_ptr t, coord::tile s, float radius) - : - terrain{t}, - start(s), - previous_radius{.0f}, - max_radius{radius} { -} - -coord::tile TerrainSearch::start_tile() const { - return this->start; -} - -void TerrainSearch::reset() { - std::queue empty; - std::swap(this->tiles, empty); - this->visited.clear(); - this->tiles.push(this->start); - this->visited.insert(this->start); -} - -coord::tile TerrainSearch::next_tile() { - // conditions for returning to the initial tile - if (this->tiles.empty() || - (this->max_radius && this->previous_radius > this->max_radius)) { - this->reset(); - } - coord::tile result = this->tiles.front(); - this->tiles.pop(); - - for (auto i = 0; i < 4; ++i) { - auto to_add = result + neigh_tile[i]; - - // check not visited and tile is within map - if (this->visited.count(to_add) == 0 && terrain->get_data(to_add)) { - this->visited.insert(to_add); - this->tiles.push(to_add); - } - } - - this->previous_radius = std::hypot(result.ne - start.ne, result.se - start.se); - return result; -} - -} // namespace openage diff --git a/libopenage/terrain/terrain_search.h b/libopenage/terrain/terrain_search.h deleted file mode 100644 index 3221db31d2..0000000000 --- a/libopenage/terrain/terrain_search.h +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include -#include -#include - -#include "../coord/tile.h" - -namespace openage { - -class Terrain; -class TerrainObject; - -TerrainObject *find_near(const TerrainObject &start, - std::function found, - unsigned int search_limit=500); -TerrainObject *find_in_radius(const TerrainObject &start, - std::function found, - float radius); - -constexpr coord::tile_delta const neigh_tile[] = { - {0, 1}, - {0, -1}, - {1, 0}, - {-1, 0} -}; - -/** - * searches outward from a point and returns nearby objects - * The state of the search is kept within the class, which allows - * a user to look at a limited number of tiles per update cycle - */ -class TerrainSearch { -public: - /** - * next_tile will cover all tiles on the map - */ - TerrainSearch(std::shared_ptr t, coord::tile s); - - /** - * next_tile will iterate over a range of tiles within a radius - */ - TerrainSearch(std::shared_ptr t, coord::tile s, float radius); - ~TerrainSearch() = default; - - /** - * the tile the search began on - */ - coord::tile start_tile() const; - - /** - * restarts the search from the start tile - */ - void reset(); - - /** - * returns all objects on the next tile - */ - coord::tile next_tile(); - -private: - const std::shared_ptr terrain; - const coord::tile start; - std::queue tiles; - std::unordered_set visited; - float previous_radius, max_radius; - -}; - -} // namespace openage diff --git a/libopenage/unit/CMakeLists.txt b/libopenage/unit/CMakeLists.txt deleted file mode 100644 index 6550dc0234..0000000000 --- a/libopenage/unit/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -add_sources(libopenage - ability.cpp - action.cpp - attribute.cpp - attributes.cpp - command.cpp - producer.cpp - research.cpp - selection.cpp - unit.cpp - unit_container.cpp - unit_type.cpp -) diff --git a/libopenage/unit/ability.cpp b/libopenage/unit/ability.cpp deleted file mode 100644 index 0ab1eef175..0000000000 --- a/libopenage/unit/ability.cpp +++ /dev/null @@ -1,446 +0,0 @@ -// Copyright 2014-2021 the openage authors. See copying.md for legal info. - -#include - -#include "../terrain/terrain_object.h" -#include "../gamestate/old/cost.h" -#include "../gamestate/old/player.h" -#include "ability.h" -#include "action.h" -#include "command.h" -#include "research.h" -#include "unit.h" - -namespace openage { - -bool UnitAbility::has_hitpoints(Unit &target) { - return target.has_attribute(attr_type::damaged) && - target.get_attribute().hp > 0; -} - -bool UnitAbility::is_damaged(Unit &target) { - return target.has_attribute(attr_type::damaged) && target.has_attribute(attr_type::hitpoints) && - target.get_attribute().hp < target.get_attribute().hp; -} - -bool UnitAbility::has_resource(Unit &target) { - return target.has_attribute(attr_type::resource) && !target.has_attribute(attr_type::worker) && - target.get_attribute().amount > 0; -} - -bool UnitAbility::is_same_player(Unit &to_modify, Unit &target) { - if (to_modify.has_attribute(attr_type::owner) && - target.has_attribute(attr_type::owner)) { - auto &mod_player = to_modify.get_attribute().player; - auto &tar_player = target.get_attribute().player; - return mod_player.color == tar_player.color; - } - return false; - -} - -bool UnitAbility::is_ally(Unit &to_modify, Unit &target) { - if (to_modify.has_attribute(attr_type::owner) && - target.has_attribute(attr_type::owner)) { - auto &mod_player = to_modify.get_attribute().player; - auto &tar_player = target.get_attribute().player; - return mod_player.is_ally(tar_player); - } - return false; -} - -bool UnitAbility::is_enemy(Unit &to_modify, Unit &target) { - if (to_modify.has_attribute(attr_type::owner) && - target.has_attribute(attr_type::owner)) { - auto &mod_player = to_modify.get_attribute().player; - auto &tar_player = target.get_attribute().player; - return mod_player.is_enemy(tar_player); - } - return false; -} - -MoveAbility::MoveAbility(const Sound *s) - : - sound{s} { -} - -bool MoveAbility::can_invoke(Unit &to_modify, const Command &cmd) { - if (cmd.has_position()) { - return bool(to_modify.location); - } - else if (cmd.has_unit()) { - return to_modify.location && - cmd.unit()->location && - &to_modify != cmd.unit(); // cannot target self - } - return false; -} - -void MoveAbility::invoke(Unit &to_modify, const Command &cmd, bool play_sound) { - to_modify.log(MSG(dbg) << "invoke move action"); - if (play_sound && this->sound) { - this->sound->play(); - } - - if (cmd.has_position()) { - auto target = cmd.position(); - to_modify.push_action(std::make_unique(&to_modify, target)); - } - else if (cmd.has_unit()) { - auto target = cmd.unit(); - - // distance from the targets edge that is required to stop moving - coord::phys_t radius = path::path_grid_size + (to_modify.location->min_axis() / 2L); - - // add the range of the unit if cmd indicator is set - if (cmd.has_flag(command_flag::use_range) && to_modify.has_attribute(attr_type::attack)) { - auto &att = to_modify.get_attribute(); - radius += att.max_range; - } - to_modify.push_action(std::make_unique(&to_modify, target->get_ref(), radius)); - } -} - -SetPointAbility::SetPointAbility() = default; - -bool SetPointAbility::can_invoke(Unit &to_modify, const Command &cmd) { - return cmd.has_position() && - to_modify.has_attribute(attr_type::building); -} - -void SetPointAbility::invoke(Unit &to_modify, const Command &cmd, bool) { - auto &build_attr = to_modify.get_attribute(); - build_attr.gather_point = cmd.position(); -} - - -GarrisonAbility::GarrisonAbility(const Sound *s) - : - sound{s} { -} - -bool GarrisonAbility::can_invoke(Unit &to_modify, const Command &cmd) { - if (!cmd.has_unit()) { - return false; - } - Unit &target = *cmd.unit(); - - // make sure buildings are completed - if (target.has_attribute(attr_type::building)) { - auto &build_attr = target.get_attribute(); - if (build_attr.completed < 1.0f) { - return false; - } - } - return to_modify.location && - target.has_attribute(attr_type::garrison) && - is_ally(to_modify, target); -} - -void GarrisonAbility::invoke(Unit &to_modify, const Command &cmd, bool play_sound) { - to_modify.log(MSG(dbg) << "invoke garrison action"); - if (play_sound && this->sound) { - this->sound->play(); - } - to_modify.push_action(std::make_unique(&to_modify, cmd.unit()->get_ref())); -} - -UngarrisonAbility::UngarrisonAbility(const Sound *s) - : - sound{s} { -} - -bool UngarrisonAbility::can_invoke(Unit &to_modify, const Command &cmd) { - if (to_modify.has_attribute(attr_type::garrison)) { - auto &garrison_attr = to_modify.get_attribute(); - return cmd.has_position() && !garrison_attr.content.empty(); - } - return false; -} - -void UngarrisonAbility::invoke(Unit &to_modify, const Command &cmd, bool play_sound) { - to_modify.log(MSG(dbg) << "invoke ungarrison action"); - if (play_sound && this->sound) { - this->sound->play(); - } - - // add as secondary, so primary action is not disrupted - to_modify.secondary_action(std::make_unique(&to_modify, cmd.position())); -} - -TrainAbility::TrainAbility(const Sound *s) - : - sound{s} { -} - -bool TrainAbility::can_invoke(Unit &to_modify, const Command &cmd) { - if (to_modify.has_attribute(attr_type::building)) { - auto &build_attr = to_modify.get_attribute(); - return cmd.has_type() && 1.0f <= build_attr.completed; - } - return false; -} - -void TrainAbility::invoke(Unit &to_modify, const Command &cmd, bool play_sound) { - to_modify.log(MSG(dbg) << "invoke train action"); - if (play_sound && this->sound) { - this->sound->play(); - } - to_modify.push_action(std::make_unique(&to_modify, cmd.type())); -} - -ResearchAbility::ResearchAbility(const Sound *s) - : - sound{s} { -} - -bool ResearchAbility::can_invoke(Unit &to_modify, const Command &cmd) { - if (to_modify.has_attribute(attr_type::owner) && cmd.has_research()) { - auto &player = to_modify.get_attribute().player; - auto research = cmd.research(); - return research->can_start() && - player.can_deduct(research->type->get_research_cost().get(player)); - } - return false; -} - -void ResearchAbility::invoke(Unit &to_modify, const Command &cmd, bool play_sound) { - if (play_sound && this->sound) { - this->sound->play(); - } - to_modify.push_action(std::make_unique(&to_modify, cmd.research())); -} - -BuildAbility::BuildAbility(const Sound *s) - : - sound{s} { -} - -bool BuildAbility::can_invoke(Unit &to_modify, const Command &cmd) { - if (cmd.has_unit()) { - Unit *target = cmd.unit(); - return to_modify.location && - is_same_player(to_modify, *target) && - target->has_attribute(attr_type::building) && - target->get_attribute().completed < 1.0f; - } - return false; -} - -void BuildAbility::invoke(Unit &to_modify, const Command &cmd, bool play_sound) { - to_modify.log(MSG(dbg) << "invoke build action"); - if (play_sound && this->sound) { - this->sound->play(); - } - - if (cmd.has_unit()) { - to_modify.push_action(std::make_unique(&to_modify, cmd.unit()->get_ref())); - } -} - -GatherAbility::GatherAbility(const Sound *s) - : - sound{s} { -} - -bool GatherAbility::can_invoke(Unit &to_modify, const Command &cmd) { - if (cmd.has_unit()) { - Unit &target = *cmd.unit(); - return &to_modify != &target && - to_modify.location && - to_modify.has_attribute(attr_type::worker) && - has_resource(target); - } - return false; -} - -void GatherAbility::invoke(Unit &to_modify, const Command &cmd, bool play_sound) { - to_modify.log(MSG(dbg) << "invoke gather action"); - if (play_sound && this->sound) { - this->sound->play(); - } - - Unit *target = cmd.unit(); - try { - to_modify.push_action(std::make_unique(&to_modify, target->get_ref())); - } catch (const std::invalid_argument &e) { - to_modify.log(MSG(dbg) << "invoke gather action cancelled due to an exception. Reason: " << e.what()); - } -} - -AttackAbility::AttackAbility(const Sound *s) - : - sound{s} { -} - -bool AttackAbility::can_invoke(Unit &to_modify, const Command &cmd) { - if (cmd.has_unit()) { - Unit &target = *cmd.unit(); - bool target_is_resource = has_resource(target); - return &to_modify != &target && - to_modify.location && - target.location && - target.location->is_placed() && - to_modify.has_attribute(attr_type::attack) && - has_hitpoints(target) && - (is_enemy(to_modify, target) || target_is_resource) && - (cmd.has_flag(command_flag::attack_res) == target_is_resource); - } - return false; -} - -void AttackAbility::invoke(Unit &to_modify, const Command &cmd, bool play_sound) { - to_modify.log(MSG(dbg) << "invoke attack action"); - if (play_sound && this->sound) { - this->sound->play(); - } - - Unit *target = cmd.unit(); - to_modify.push_action(std::make_unique(&to_modify, target->get_ref())); -} - -RepairAbility::RepairAbility(const Sound *s) - : - sound{s} { -} - -bool RepairAbility::can_invoke(Unit &to_modify, const Command &cmd) { - if (cmd.has_unit()) { - Unit &target = *cmd.unit(); - return &to_modify != &target && - to_modify.location && - target.location && - target.location->is_placed() && - is_damaged(target) && - is_ally(to_modify, target); - } - return false; -} - -void RepairAbility::invoke(Unit &to_modify, const Command &cmd, bool play_sound) { - to_modify.log(MSG(dbg) << "invoke repair action"); - if (play_sound && this->sound) { - this->sound->play(); - } - - Unit *target = cmd.unit(); - to_modify.push_action(std::make_unique(&to_modify, target->get_ref())); -} - -HealAbility::HealAbility(const Sound *s) - : - sound{s} { -} - -bool HealAbility::can_invoke(Unit &to_modify, const Command &cmd) { - if (cmd.has_unit()) { - Unit &target = *cmd.unit(); - return &to_modify != &target && - to_modify.location && - target.location && - target.location->is_placed() && - is_damaged(target) && - is_ally(to_modify, target); - } - return false; -} - -void HealAbility::invoke(Unit &to_modify, const Command &cmd, bool play_sound) { - to_modify.log(MSG(dbg) << "invoke heal action"); - if (play_sound && this->sound) { - this->sound->play(); - } - - Unit *target = cmd.unit(); - to_modify.push_action(std::make_unique(&to_modify, target->get_ref())); -} - -PatrolAbility::PatrolAbility(const Sound *s) - : - sound{s} { -} - -bool PatrolAbility::can_invoke(Unit &/*to_modify*/, const Command &/*cmd*/) { - // TODO implement - return false; -} - -void PatrolAbility::invoke(Unit &to_modify, const Command &/*cmd*/, bool play_sound) { - to_modify.log(MSG(dbg) << "not implemented"); - if (play_sound && this->sound) { - this->sound->play(); - } - // TODO implement -} - -ConvertAbility::ConvertAbility(const Sound *s) - : - sound{s} { -} - -bool ConvertAbility::can_invoke(Unit &to_modify, const Command &cmd) { - if (cmd.has_unit()) { - Unit &target = *cmd.unit(); - return &to_modify != &target && - to_modify.location && - target.location && - target.location->is_placed() && - is_enemy(to_modify, target); - } - return false; -} - -void ConvertAbility::invoke(Unit &to_modify, const Command &cmd, bool play_sound) { - to_modify.log(MSG(dbg) << "invoke convert action"); - if (play_sound && this->sound) { - this->sound->play(); - } - - Unit *target = cmd.unit(); - to_modify.push_action(std::make_unique(&to_modify, target->get_ref())); -} - -ability_set UnitAbility::set_from_list(const std::vector &items) { - ability_set result; - for (auto i : items) { - result[static_cast(i)] = 1; - } - return result; -} - -} // namespace openage - -namespace std { - -string to_string(const openage::ability_type &at) { - switch (at) { - case openage::ability_type::move: - return "move"; - case openage::ability_type::garrison: - return "garrison"; - case openage::ability_type::ungarrison: - return "ungarrison"; - case openage::ability_type::patrol: - return "patrol"; - case openage::ability_type::train: - return "train"; - case openage::ability_type::build: - return "build"; - case openage::ability_type::research: - return "research"; - case openage::ability_type::gather: - return "gather"; - case openage::ability_type::attack: - return "attack"; - case openage::ability_type::convert: - return "convert"; - case openage::ability_type::repair: - return "repair"; - case openage::ability_type::heal: - return "heal"; - default: - return "unknown"; - } -} - -} // namespace std diff --git a/libopenage/unit/ability.h b/libopenage/unit/ability.h deleted file mode 100644 index b2957c0585..0000000000 --- a/libopenage/unit/ability.h +++ /dev/null @@ -1,380 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include -#include -#include - -#include "../coord/phys.h" - -namespace openage { - -class Command; -class Sound; -class Unit; -class UnitAction; -class UnitType; - -/** - * roughly the same as command_ability in game data - */ -enum class ability_type { - move, - patrol, - set_point, - garrison, - ungarrison, - train, - build, - research, - gather, - attack, - convert, - repair, - heal, - MAX -}; - -/** - * a container where each ability uses 1 bit - */ -constexpr int ability_type_size = static_cast(ability_type::MAX); -using ability_set = std::bitset; -using ability_id_t = unsigned int; - -/** - * all bits set to 1 - */ -const ability_set ability_all = ability_set().set(); - -/** - * the order abilities should be used when available - */ -static std::vector ability_priority{ - ability_type::gather, // targeting - ability_type::convert, - ability_type::repair, - ability_type::heal, - ability_type::attack, - ability_type::build, - ability_type::move, // positional - ability_type::patrol, - ability_type::garrison, - ability_type::ungarrison, // inside buildings - ability_type::train, - ability_type::research, - ability_type::set_point, -}; - - -/** - * Abilities create an action when given a target - * some abilities target positions such as moving or patrolling - * others target other game objects, such as attacking or - * collecting relics - * - * Abilities are constructed with a default unit texture, but allow the texture - * to be specified with the invoke function - */ -class UnitAbility { -public: - virtual ~UnitAbility() {} - - virtual ability_type type() = 0; - - /** - * true if the paramaters allow an action to be performed - */ - virtual bool can_invoke(Unit &to_modify, const Command &cmd) = 0; - - /** - * applies command to a given unit - */ - virtual void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) = 0; - - /** - * some common functions - */ - bool has_hitpoints(Unit &target); - bool is_damaged(Unit &target); - bool has_resource(Unit &target); - bool is_same_player(Unit &to_modify, Unit &target); - bool is_ally(Unit &to_modify, Unit &target); - bool is_enemy(Unit &to_modify, Unit &target); - - /** - * set bits corresponding to abilities, useful for initialising an ability_set - * using a brace enclosed list - */ - static ability_set set_from_list(const std::vector &items); -}; - -/** - * initiates a move action when given a valid target - */ -class MoveAbility : public UnitAbility { -public: - MoveAbility(const Sound *s = nullptr); - - ability_type type() override { - return ability_type::move; - } - - bool can_invoke(Unit &to_modify, const Command &cmd) override; - - void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; - -private: - const Sound *sound; -}; - -/** - * sets the gather point on buildings - */ -class SetPointAbility : public UnitAbility { -public: - SetPointAbility(); - - ability_type type() override { - return ability_type::set_point; - } - - bool can_invoke(Unit &to_modify, const Command &cmd) override; - - void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; -}; - - -/** - * ability to garrision inside a building - */ -class GarrisonAbility : public UnitAbility { -public: - GarrisonAbility(const Sound *s = nullptr); - - ability_type type() override { - return ability_type::garrison; - } - - bool can_invoke(Unit &to_modify, const Command &cmd) override; - - void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; - -private: - const Sound *sound; -}; - -/** - * ability to ungarrision a building - */ -class UngarrisonAbility : public UnitAbility { -public: - UngarrisonAbility(const Sound *s = nullptr); - - ability_type type() override { - return ability_type::ungarrison; - } - - bool can_invoke(Unit &to_modify, const Command &cmd) override; - - void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; - -private: - const Sound *sound; -}; - -/** - * buildings train new objects - */ -class TrainAbility : public UnitAbility { -public: - TrainAbility(const Sound *s = nullptr); - - ability_type type() override { - return ability_type::train; - } - - bool can_invoke(Unit &to_modify, const Command &cmd) override; - - void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; - -private: - const Sound *sound; -}; - -/** - * initiates a research - */ -class ResearchAbility : public UnitAbility { -public: - ResearchAbility(const Sound *s = nullptr); - - ability_type type() override { - return ability_type::research; - } - - bool can_invoke(Unit &to_modify, const Command &cmd) override; - - void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; - -private: - const Sound *sound; -}; - -/** - * villagers build new buildings - */ -class BuildAbility : public UnitAbility { -public: - BuildAbility(const Sound *s = nullptr); - - ability_type type() override { - return ability_type::build; - } - - bool can_invoke(Unit &to_modify, const Command &cmd) override; - - void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; - -private: - const Sound *sound; -}; - -/** - * initiates an gather resource action when given a valid target - */ -class GatherAbility : public UnitAbility { -public: - GatherAbility(const Sound *s = nullptr); - - ability_type type() override { - return ability_type::gather; - } - - bool can_invoke(Unit &to_modify, const Command &cmd) override; - - void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; - -private: - const Sound *sound; -}; - -/** - * initiates an attack action when given a valid target - */ -class AttackAbility : public UnitAbility { -public: - AttackAbility(const Sound *s = nullptr); - - ability_type type() override { - return ability_type::attack; - } - - bool can_invoke(Unit &to_modify, const Command &cmd) override; - - void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; - -private: - const Sound *sound; -}; - -/** - * initiates a repair action when given a valid target - */ -class RepairAbility : public UnitAbility { -public: - RepairAbility(const Sound *s = nullptr); - - ability_type type() override { - return ability_type::repair; - } - - bool can_invoke(Unit &to_modify, const Command &cmd) override; - - void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; - -private: - const Sound *sound; -}; - -/** - * initiates a heal action when given a valid target - */ -class HealAbility : public UnitAbility { -public: - HealAbility(const Sound *s = nullptr); - - ability_type type() override { - return ability_type::heal; - } - - bool can_invoke(Unit &to_modify, const Command &cmd) override; - - void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; - -private: - const Sound *sound; -}; - -/** - * initiates a patrol action when given a valid target - * TODO implement - */ -class PatrolAbility : public UnitAbility { -public: - PatrolAbility(const Sound *s = nullptr); - - ability_type type() override { - return ability_type::patrol; - } - - bool can_invoke(Unit &to_modify, const Command &cmd) override; - - void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; - -private: - const Sound *sound; -}; - -/** - * initiates a convert action when given a valid target - */ -class ConvertAbility : public UnitAbility { -public: - ConvertAbility(const Sound *s = nullptr); - - ability_type type() override { - return ability_type::convert; - } - - bool can_invoke(Unit &to_modify, const Command &cmd) override; - - void invoke(Unit &to_modify, const Command &cmd, bool play_sound = false) override; - -private: - const Sound *sound; -}; - -} // namespace openage - -namespace std { - -std::string to_string(const openage::ability_type &at); - -/** - * hasher for ability type enum - */ -template <> -struct hash { - typedef underlying_type::type underlying_type; - - size_t operator()(const openage::ability_type &arg) const { - hash hasher; - return hasher(static_cast(arg)); - } -}; - -} // namespace std diff --git a/libopenage/unit/action.cpp b/libopenage/unit/action.cpp deleted file mode 100644 index 65bd1bed8b..0000000000 --- a/libopenage/unit/action.cpp +++ /dev/null @@ -1,1249 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#include -#include - -#include "../pathfinding/a_star.h" -#include "../pathfinding/heuristics.h" -#include "../terrain/terrain.h" -#include "../terrain/terrain_search.h" -#include "action.h" -#include "command.h" -#include "producer.h" -#include "research.h" - -namespace openage { - -IntervalTimer::IntervalTimer(unsigned int interval) : - IntervalTimer{interval, -1} { -} - -IntervalTimer::IntervalTimer(unsigned int interval, int max_triggers) : - interval{interval}, - max_triggers{max_triggers}, - time_left{interval}, - triggers{0} { -} - -void IntervalTimer::skip_to_trigger() { - this->time_left = 0; -} - -bool IntervalTimer::update(unsigned int time) { - if (this->triggers == this->max_triggers) { - return false; - } - else if (this->time_left > time) { - this->time_left -= time; - return false; - } - else { - this->time_left += this->interval - time; - this->triggers += 1; - return true; - } -} - -unsigned int IntervalTimer::get_time_left() const { - return this->time_left; -} - -float IntervalTimer::get_progress() const { - return 1.0f - (this->time_left * 1.0f / this->interval); -} - -bool IntervalTimer::has_triggers() const { - return this->triggers > 0; -} - -bool IntervalTimer::finished() const { - return this->triggers == this->max_triggers; -} - -bool UnitAction::show_debug = false; - -coord::phys_t UnitAction::adjacent_range(Unit *u) { - return path::path_grid_size * 3 + (u->location->min_axis() / 2L); -} - -coord::phys_t UnitAction::get_attack_range(Unit *u) { - coord::phys_t range = adjacent_range(u); - if (u->has_attribute(attr_type::attack)) { - auto &attack = u->get_attribute(); - range += attack.max_range; - } - return range; -} - -coord::phys_t UnitAction::get_heal_range(Unit *u) { - coord::phys_t range = adjacent_range(u); - if (u->has_attribute(attr_type::heal)) { - auto &heal = u->get_attribute(); - range += heal.range; - } - return range; -} - -UnitAction::UnitAction(Unit *u, graphic_type initial_gt) : - entity{u}, - graphic{initial_gt}, - frame{.0f}, - frame_rate{.0f} { -} - -graphic_type UnitAction::type() const { - return this->graphic; -} - -float UnitAction::current_frame() const { - return this->frame; -} - -void UnitAction::face_towards(const coord::phys3 pos) { - if (this->entity->has_attribute(attr_type::direction)) { - auto &d_attr = this->entity->get_attribute(); - d_attr.unit_dir = pos - this->entity->location->pos.draw; - } -} - -bool UnitAction::damage_unit(Unit &target) { - bool killed = false; - - if (target.has_attribute(attr_type::damaged)) { - auto &dm = target.get_attribute(); - - // this is the damage calculation system - - if (dm.hp == 0) { - // already killed, do nothing - } - else if (target.has_attribute(attr_type::armor) && this->entity->has_attribute(attr_type::attack)) { - auto &armor = target.get_attribute().armor; - auto &damage = this->entity->get_attribute().damage; - - unsigned int actual_damage = 0; - for (const auto &pair : armor) { - auto search = damage.find(pair.first); - if (search != damage.end()) { - if (pair.second < search->second) { - actual_damage += search->second - pair.second; - } - } - } - // TODO add elevation modifier here - if (actual_damage < 1) { - actual_damage = 1; - } - - if (dm.hp > actual_damage) { - dm.hp -= actual_damage; - } - else { - dm.hp = 0; - killed = true; - } - } - else { - // TODO remove (keep for testing) - unsigned int dmg = 1; - if (dm.hp > dmg) { - dm.hp -= dmg; - } - else { - dm.hp = 0; - killed = true; - } - } - } - - if (killed) { - // if killed, give credit to a player - if (this->entity->has_attribute(attr_type::owner)) { - auto &owner = this->entity->get_attribute().player; - owner.killed_unit(target); - } - } - - return killed; -} - -void UnitAction::move_to(Unit &target, bool use_range) { - auto &player = this->entity->get_attribute().player; - Command cmd(player, &target); - cmd.set_ability(ability_type::move); - if (use_range) { - cmd.add_flag(command_flag::use_range); - } - this->entity->queue_cmd(cmd); -} - -TargetAction::TargetAction(Unit *u, graphic_type gt, UnitReference r, coord::phys_t rad) : - UnitAction(u, gt), - target{r}, - target_type_id{0}, - repath_attempts{10}, - end_action{false}, - radius{rad} { - // update type - if (this->target.is_valid()) { - auto target_ptr = this->target.get(); - this->target_type_id = target_ptr->unit_type->id(); - } - - // initial value for distance - this->update_distance(); -} - -TargetAction::TargetAction(Unit *u, graphic_type gt, UnitReference r) : - TargetAction(u, gt, r, adjacent_range(u)) { -} - -void TargetAction::update(unsigned int time) { - auto target_ptr = this->update_distance(); - if (!target_ptr) { - return; // target has become invalid - } - - // this update moves a unit within radius of the target - // once within the radius the update gets passed to the class - // derived from TargetAction - - // set direction unit should face - this->face_towards(target_ptr->location->pos.draw); - - // move to within the set radius - if (this->dist_to_target <= this->radius) { - // the derived class controls what to - // do when in range of the target - this->update_in_range(time, target_ptr); - this->repath_attempts = 10; - } - else if (this->repath_attempts) { - // out of range so try move towards - // if this unit has a move ability - this->move_to(*target_ptr); - this->repath_attempts -= 1; - } - else { - // unit is stuck - this->end_action = true; - } -} - -void TargetAction::on_completion() { - // do not retask if action is forced to end - if (this->end_action || !this->entity->location) { - return; - } - - // retask units on nearby objects - // such as gathers targeting a new resource - // when the current target expires - this->on_completion_in_range(this->target_type_id); -} - -bool TargetAction::completed() const { - if (this->end_action || !this->target.is_valid() || !this->target.get()->location) { - return true; - } - return this->completed_in_range(this->target.get()); -} - -coord::phys_t TargetAction::distance_to_target() { - return this->dist_to_target; -} - -Unit *TargetAction::update_distance() { - if (!this->target.is_valid()) { - return nullptr; - } - - // make sure object is not garrisoned - auto target_ptr = this->target.get(); - if (!target_ptr->location) { - return nullptr; - } - - // update distance - this->dist_to_target = target_ptr->location->from_edge(this->entity->location->pos.draw); - - // return the targeted unit - return target_ptr; -} - -UnitReference TargetAction::get_target() const { - return this->target; -} - -int TargetAction::get_target_type_id() const { - return this->target_type_id; -} - -void TargetAction::set_target(UnitReference new_target) { - if (new_target.is_valid()) { - this->target = new_target; - this->update_distance(); - } - else { - this->end_action = true; - } -} - -DecayAction::DecayAction(Unit *e) : - UnitAction(e, graphic_type::standing), - end_frame{.0f} { -} - -void DecayAction::update(unsigned int time) { - this->frame += time * this->frame_rate / 10000.0f; -} - -void DecayAction::on_completion() {} - -bool DecayAction::completed() const { - return this->frame > this->end_frame; -} - -DeadAction::DeadAction(Unit *e, std::function on_complete) : - UnitAction(e, graphic_type::dying), - end_frame{.0f}, - on_complete_func{on_complete} { -} - -void DeadAction::update(unsigned int time) { - if (this->entity->has_attribute(attr_type::damaged)) { - auto &dm = this->entity->get_attribute(); - dm.hp = 0; - } - - // decay resources - if (this->entity->has_attribute(attr_type::resource)) { - auto &resource = this->entity->get_attribute(); - if (resource.decay > 0) { - resource.amount -= resource.decay; - } - } - - // inc frame but do not pass the end frame - // the end frame will remain if the object carries resources - if (this->frame < this->end_frame) { - this->frame += 0.001 + time * this->frame_rate / 3.0f; - } - else { - this->frame = this->end_frame; - } -} - -void DeadAction::on_completion() { - if (this->entity->has_attribute(attr_type::owner)) { - auto &owner = this->entity->get_attribute().player; - owner.active_unit_removed(this->entity); // TODO move before the start of dead action? - } - - this->on_complete_func(); -} - -bool DeadAction::completed() const { - // check resource, trees/huntables with resource are not removed but not workers - if (this->entity->has_attribute(attr_type::resource) && !this->entity->has_attribute(attr_type::worker)) { - auto &res_attr = this->entity->get_attribute(); - return res_attr.amount <= 0; // cannot complete when resource remains - } - return this->frame > this->end_frame; -} - -FoundationAction::FoundationAction(Unit *e, bool add_destruction) : - UnitAction(e, graphic_type::construct), - add_destruct_effect{add_destruction}, - cancel{false} { -} - -void FoundationAction::update(unsigned int) { - if (!this->entity->location) { - this->cancel = true; - } -} - -void FoundationAction::on_completion() { - // do nothing if construction is cancelled - if (this->cancel) { - return; - } - - if (this->entity->has_attribute(attr_type::owner)) { - auto &owner = this->entity->get_attribute().player; - owner.active_unit_added(this->entity, true); - } - - // add destruction effect when available - if (this->add_destruct_effect) { - this->entity->push_action(std::make_unique(this->entity), true); - } - this->entity->push_action(std::make_unique(this->entity), true); -} - -bool FoundationAction::completed() const { - return this->cancel || (this->entity->has_attribute(attr_type::building) && (this->entity->get_attribute().completed >= 1.0f)); -} - -IdleAction::IdleAction(Unit *e) : - UnitAction(e, graphic_type::standing) { - auto terrain = this->entity->location->get_terrain(); - auto current_tile = this->entity->location->pos.draw.to_tile3().to_tile(); - this->search = std::make_shared(terrain, current_tile, 5.0f); - - // currently allow attack and heal automatically - this->auto_abilities = UnitAbility::set_from_list({ability_type::attack, ability_type::heal}); -} - -void IdleAction::update(unsigned int time) { - // auto task searching - if (this->entity->location && this->entity->has_attribute(attr_type::owner) && this->entity->has_attribute(attr_type::attack) && this->entity->has_attribute(attr_type::formation) && this->entity->get_attribute().stance != attack_stance::do_nothing) { - // restart search from new tile when moved - auto terrain = this->entity->location->get_terrain(); - auto current_tile = this->entity->location->pos.draw.to_tile3().to_tile(); - if (!(current_tile == this->search->start_tile())) { - this->search = std::make_shared(terrain, current_tile, 5.0f); - } - - // search one tile per update - // next tile will always be valid - coord::tile tile = this->search->next_tile(); - auto tile_data = terrain->get_data(tile); - auto &player = this->entity->get_attribute().player; - - // find and actions which can be invoked - for (auto object_location : tile_data->obj) { - Command to_object(player, &object_location->unit); - - // only allow abilities in the set of auto ability types - to_object.set_ability_set(auto_abilities); - if (this->entity->queue_cmd(to_object)) { - break; - } - } - } - - // generate resources - // TODO move elsewhere - if (this->entity->has_attribute(attr_type::resource_generator) && this->entity->has_attribute(attr_type::owner)) { - auto &player = this->entity->get_attribute().player; - auto &resource_generator = this->entity->get_attribute(); - - ResourceBundle resources = resource_generator.resources.clone(); - if (resource_generator.rate == 0) { - resources *= time; - } - else { - // TODO add in intervals and not continuously - resources *= time * resource_generator.rate; - } - - player.receive(resources); - } - - // unit carrying resources take the carrying sprite when idle - // we're not updating frames because the carrying sprite is walking - if (entity->has_attribute(attr_type::worker)) { - auto &worker_resource = this->entity->get_attribute(); - if (worker_resource.amount > 0) { - this->graphic = graphic_type::carrying; - } - else { - this->graphic = graphic_type::standing; - this->frame += time * this->frame_rate / 20.0f; - } - } - else { - // inc frame - this->frame += time * this->frame_rate / 20.0f; - } -} - -void IdleAction::on_completion() {} - -bool IdleAction::completed() const { - if (this->entity->has_attribute(attr_type::damaged)) { - auto &dm = this->entity->get_attribute(); - return dm.hp == 0; - } - else if (this->entity->has_attribute(attr_type::resource)) { - auto &res_attr = this->entity->get_attribute(); - return res_attr.amount <= 0.0; - } - return false; -} - -MoveAction::MoveAction(Unit *e, coord::phys3 tar, bool repath) : - UnitAction{e, graphic_type::walking}, - unit_target{}, - target(tar), - radius{path::path_grid_size}, - allow_repath{repath}, - end_action{false} { - this->initialise(); -} - -MoveAction::MoveAction(Unit *e, UnitReference tar, coord::phys_t within_range) : - UnitAction{e, graphic_type::walking}, - unit_target{tar}, - target(tar.get()->location->pos.draw), - radius{within_range}, - allow_repath{false}, - end_action{false} { - this->initialise(); -} - -void MoveAction::initialise() { - // switch workers to the carrying graphic - if (this->entity->has_attribute(attr_type::worker)) { - auto &worker_resource = this->entity->get_attribute(); - if (worker_resource.amount > 0) { - this->graphic = graphic_type::carrying; - } - } - - // set initial distance - this->set_distance(); - - // set an initial path - this->set_path(); - // this->debug_draw_action = [&](const Engine &engine) { - // this->path.draw_path(engine.coord); - // }; -} - -MoveAction::~MoveAction() = default; - -void MoveAction::update(unsigned int time) { - if (this->unit_target.is_valid()) { - // a unit is targeted, which may move - auto &target_object = this->unit_target.get()->location; - - // check for garrisoning objects - if (!target_object) { - this->end_action = true; - return; - } - coord::phys3 &target_pos = target_object->pos.draw; - coord::phys3 &unit_pos = this->entity->location->pos.draw; - - // repath if target changes tiles by a threshold - // this repathing is more frequent when the unit is - // close to its target - coord::phys_t tdx = target_pos.ne - this->target.ne; - coord::phys_t tdy = target_pos.se - this->target.se; - coord::phys_t udx = unit_pos.ne - this->target.ne; - coord::phys_t udy = unit_pos.se - this->target.se; - if (this->path.waypoints.empty() || std::hypot(tdx, tdy) > std::hypot(udx, udy)) { - this->target = target_pos; - this->set_path(); - } - } - - // path not found - if (this->path.waypoints.empty()) { - if (!this->allow_repath) { - this->entity->log(MSG(dbg) << "Path not found -- drop action"); - this->end_action = true; - } - return; - } - - // find distance to move in this update - auto &sp_attr = this->entity->get_attribute(); - double distance_to_move = sp_attr.unit_speed.to_double() * time; - - // current position and direction - coord::phys3 new_position = this->entity->location->pos.draw; - auto &d_attr = this->entity->get_attribute(); - coord::phys3_delta new_direction = d_attr.unit_dir; - - while (distance_to_move > 0) { - if (this->path.waypoints.empty()) { - break; - } - - // find a point to move directly towards - coord::phys3 waypoint = this->next_waypoint(); - coord::phys3_delta move_dir = waypoint - new_position; - - // normalise dir - double distance_to_waypoint = std::hypot(move_dir.ne, move_dir.se); - - if (distance_to_waypoint <= distance_to_move) { - distance_to_move -= distance_to_waypoint; - - // change entity position and direction - new_position = waypoint; - new_direction = move_dir; - - // remove the waypoint - this->path.waypoints.pop_back(); - } - else { - // change entity position and direction - new_position += move_dir * (distance_to_move / distance_to_waypoint); - new_direction = move_dir; - break; - } - } - - // check move collisions - bool move_completed = this->entity->location->move(new_position); - if (move_completed) { - d_attr.unit_dir = new_direction; - this->set_distance(); - } - else { - // cases for modifying path when blocked - if (this->allow_repath) { - this->entity->log(MSG(dbg) << "Path blocked -- finding new path"); - this->set_path(); - } - else { - this->entity->log(MSG(dbg) << "Path blocked -- drop action"); - this->end_action = true; - } - } - - // inc frame - this->frame += time * this->frame_rate / 5.0f; -} - -void MoveAction::on_completion() {} - -bool MoveAction::completed() const { - // no more waypoints to a static location - if (this->end_action || (!this->unit_target.is_valid() && this->path.waypoints.empty())) { - return true; - } - - //close enough to end action - if (this->distance_to_target < this->radius) { - return true; - } - return false; -} - - -coord::phys3 MoveAction::next_waypoint() const { - if (this->path.waypoints.size() > 0) { - return this->path.waypoints.back().position; - } - else { - throw Error{MSG(err) << "No next waypoint available!"}; - } -} - - -void MoveAction::set_path() { - if (this->unit_target.is_valid()) { - this->path = path::to_object(this->entity->location.get(), this->unit_target.get()->location.get(), this->radius); - } - else { - coord::phys3 start = this->entity->location->pos.draw; - coord::phys3 end = this->target; - this->path = path::to_point(start, end, this->entity->location->passable); - } -} - -void MoveAction::set_distance() { - if (this->unit_target.is_valid()) { - auto &target_object = this->unit_target.get()->location; - coord::phys3 &unit_pos = this->entity->location->pos.draw; - this->distance_to_target = target_object->from_edge(unit_pos); - } - else { - coord::phys3_delta move_dir = this->target - this->entity->location->pos.draw; - this->distance_to_target = static_cast(std::hypot(move_dir.ne, move_dir.se)); - } -} - -GarrisonAction::GarrisonAction(Unit *e, UnitReference build) : - TargetAction{e, graphic_type::standing, build}, - complete{false} { -} - -void GarrisonAction::update_in_range(unsigned int, Unit *target_unit) { - auto &garrison_attr = target_unit->get_attribute(); - garrison_attr.content.push_back(this->entity->get_ref()); - - if (this->entity->location) { - this->entity->location->remove(); - this->entity->location = nullptr; - } - this->complete = true; -} - -UngarrisonAction::UngarrisonAction(Unit *e, const coord::phys3 &pos) : - UnitAction{e, graphic_type::standing}, - position(pos), - complete{false} { -} - -void UngarrisonAction::update(unsigned int) { - auto &garrison_attr = this->entity->get_attribute(); - - // try unload all objects currently garrisoned - auto position_it = std::remove_if( - std::begin(garrison_attr.content), - std::end(garrison_attr.content), - [this](UnitReference &u) { - if (u.is_valid()) { - // ptr to unit being ungarrisoned - Unit *unit_ptr = u.get(); - - // make sure it was placed outside - if (unit_ptr->unit_type->place_beside(unit_ptr, this->entity->location.get())) { - // task unit to move to position - auto &player = this->entity->get_attribute().player; - Command cmd(player, this->position); - cmd.set_ability(ability_type::move); - unit_ptr->queue_cmd(cmd); - return true; - } - } - return false; - }); - - // remove elements which were ungarrisoned - garrison_attr.content.erase(position_it, std::end(garrison_attr.content)); - - // completed when no units are remaining - this->complete = garrison_attr.content.empty(); -} - -void UngarrisonAction::on_completion() {} - -TrainAction::TrainAction(Unit *e, UnitType *pp) : - UnitAction{e, graphic_type::standing}, - trained{pp}, - timer{10000, 1}, // TODO get the training time from unit type - started{false}, - complete{false} { - // TODO deduct resources -} - -void TrainAction::update(unsigned int time) { - if (!this->started) { - // check if there is enough population capacity - if (!this->trained->default_attributes.has(attr_type::population)) { - this->started = true; - } - else { - auto &player = this->entity->get_attribute().player; - auto &population_demand = this->trained->default_attributes.get().demand; - bool can_start = population_demand == 0 || population_demand <= player.population.get_space(); - // TODO trigger not enough population capacity message - this->started = can_start; - } - } - - if (this->started) { - // place unit when ready - if (this->timer.finished() || this->timer.update(time)) { - // create using the producer - UnitContainer *container = this->entity->get_container(); - auto &player = this->entity->get_attribute().player; - auto uref = container->new_unit(*this->trained, player, this->entity->location.get()); - - // make sure unit got placed - // try again next update if cannot place - if (uref.is_valid()) { - if (this->entity->has_attribute(attr_type::building)) { - // use a move command to the gather point - auto &build_attr = this->entity->get_attribute(); - Command cmd(player, build_attr.gather_point); - cmd.set_ability(ability_type::move); - uref.get()->queue_cmd(cmd); - } - this->complete = true; - } - } - } -} - -void TrainAction::on_completion() { - if (!this->complete) { - // TODO give back the resources - } -} - -ResearchAction::ResearchAction(Unit *e, Research *research) : - UnitAction{e, graphic_type::standing}, - research{research}, - timer{research->type->get_research_time(), 1}, - complete{false} { - this->research->started(); -} - -void ResearchAction::update(unsigned int time) { - if (timer.update(time)) { - this->complete = true; - this->research->apply(); - this->research->completed(); - } -} - -void ResearchAction::on_completion() { - if (!this->complete) { - this->research->stopped(); - } -} - -BuildAction::BuildAction(Unit *e, UnitReference foundation) : - TargetAction{e, graphic_type::work, foundation}, - complete{.0f}, - build_rate{.0001f} { - // update the units type - if (this->entity->has_attribute(attr_type::multitype)) { - this->entity->get_attribute().switchType(gamedata::unit_classes::BUILDING, this->entity); - } -} - -void BuildAction::update_in_range(unsigned int time, Unit *target_unit) { - if (target_unit->has_attribute(attr_type::building)) { - auto &build = target_unit->get_attribute(); - - // upgrade floating outlines - auto target_location = target_unit->location.get(); - if (target_location->is_floating()) { - // try to place the object - if (target_location->place(object_state::placed)) { - // modify ground terrain - if (build.foundation_terrain > 0) { - target_location->set_ground(build.foundation_terrain, 0); - } - } - else { - // failed to start construction - this->complete = 1.0f; - return; - } - } - - // increment building completion - build.completed += build_rate * time; - this->complete = build.completed; - - if (this->complete >= 1.0f) { - this->complete = build.completed = 1.0f; - target_location->place(build.completion_state); - } - } - else { - this->complete = 1.0f; - } - - // inc frame - this->frame += time * this->frame_rate / 2.5f; -} - -void BuildAction::on_completion() { - if (this->get_target().is_valid() && this->get_target().get()->get_attribute().completed < 1.0f) { - // The BuildAction was just aborted and we shouldn't look for new buildings - return; - } - this->entity->log(MSG(dbg) << "Done building, searching for new building"); - auto valid = [this](const TerrainObject &obj) { - if (!this->entity->get_attribute().player.owns(obj.unit) || !obj.unit.has_attribute(attr_type::building) || obj.unit.get_attribute().completed >= 1.0f) { - return false; - } - this->entity->log(MSG(dbg) << "Found unit " << obj.unit.logsource_name()); - return true; - }; - - TerrainObject *new_target = find_in_radius(*this->entity->location, valid, BuildAction::search_tile_distance); - if (new_target != nullptr) { - this->entity->log(MSG(dbg) << "Found new building, queueing command"); - Command cmd(this->entity->get_attribute().player, &new_target->unit); - this->entity->queue_cmd(cmd); - } - else { - this->entity->log(MSG(dbg) << "Didn't find new building"); - } -} - -RepairAction::RepairAction(Unit *e, UnitReference tar) : - TargetAction{e, graphic_type::work, tar}, - timer{80}, - complete{false} { - if (!tar.is_valid()) { - // the target no longer exists - complete = true; - } - else { - Unit *target = tar.get(); - - if (!target->has_attribute(attr_type::building)) { - this->timer.set_interval(this->timer.get_interval() * 4); - } - - // cost formula: 0.5 * (target cost) / (target max hp) - auto &hp = target->get_attribute(); - auto &owner = this->entity->get_attribute(); - - // get the target unit's cost - this->cost += target->unit_type->cost.get(owner.player); - this->cost *= 0.5 / hp.hp; - - if (!owner.player.deduct(this->cost)) { - // no resources to start - this->complete = true; - } - } -} - -void RepairAction::update_in_range(unsigned int time, Unit *target_unit) { - auto &hp = target_unit->get_attribute(); - auto &dm = target_unit->get_attribute(); - - if (dm.hp >= hp.hp) { - // repaired by something else - this->complete = true; - } - else if (this->timer.update(time)) { - dm.hp += 1; - - if (dm.hp >= hp.hp) { - this->complete = true; - } - - if (!this->complete) { - auto &owner = this->entity->get_attribute(); - if (!owner.player.deduct(this->cost)) { - // no resources to continue - this->complete = true; - } - } - } - - // inc frame - this->frame += time * this->frame_rate / 2.5f; -} - -GatherAction::GatherAction(Unit *e, UnitReference tar) : - TargetAction{e, graphic_type::work, tar}, - complete{false}, - target_resource{true}, - target{tar} { - Unit *target = this->target.get(); - this->resource_class = target->unit_type->unit_class; - - // handle unit type changes based on resource class - if (this->entity->has_attribute(attr_type::multitype)) { - this->entity->get_attribute().switchType(this->resource_class, this->entity); - } - - // set the type of gatherer - auto &worker_resource = this->entity->get_attribute(); - if (target->has_attribute(attr_type::resource)) { - auto &resource_attr = target->get_attribute(); - if (worker_resource.resource_type != resource_attr.resource_type) { - worker_resource.amount = 0; - } - worker_resource.resource_type = resource_attr.resource_type; - } - else { - throw std::invalid_argument("Unit reference has no resource attribute"); - } -} - -GatherAction::~GatherAction() = default; - -void GatherAction::update_in_range(unsigned int time, Unit *targeted_resource) { - auto &worker = this->entity->get_attribute(); - auto &worker_resource = this->entity->get_attribute(); - if (this->target_resource) { - // the targets attributes - if (!targeted_resource->has_attribute(attr_type::resource)) { - complete = true; - return; - } - - // attack objects which have hitpoints (trees, hunt, sheep) - if (this->entity->has_attribute(attr_type::owner) && targeted_resource->has_attribute(attr_type::damaged)) { - auto &pl = this->entity->get_attribute(); - auto &dm = targeted_resource->get_attribute(); - - // only attack if hitpoints remain - if (dm.hp > 0) { - Command cmd(pl.player, targeted_resource); - cmd.set_ability(ability_type::attack); - cmd.add_flag(command_flag::attack_res); - this->entity->queue_cmd(cmd); - return; - } - } - - // need to return to dropsite - if (worker_resource.amount > worker.capacity) { - // move to dropsite location - this->target_resource = false; - this->set_target(this->nearest_dropsite(worker_resource.resource_type)); - } - else { - auto &resource_attr = targeted_resource->get_attribute(); - if (resource_attr.amount <= 0.0) { - // when the resource runs out - if (worker_resource.amount > 0.0) { - this->target_resource = false; - this->set_target(this->nearest_dropsite(worker_resource.resource_type)); - } - else { - this->complete = true; - } - } - else { - // transfer using gather rate - double amount = worker.gather_rate[worker_resource.resource_type] - * resource_attr.gather_rate * time; - worker_resource.amount += amount; - resource_attr.amount -= amount; - } - } - } - else { - // dropsite has been reached - // add value to player stockpile - auto &player = this->entity->get_attribute().player; - player.receive(worker_resource.resource_type, worker_resource.amount); - worker_resource.amount = 0.0; - - // make sure the resource still exists - if (this->target.is_valid() && this->target.get()->get_attribute().amount > 0.0) { - // return to resource collection - this->target_resource = true; - this->set_target(this->target); - } - else { - // resource depleted - this->complete = true; - } - } - - // inc frame - this->frame += time * this->frame_rate / 3.0f; -} - -void GatherAction::on_completion_in_range(int target_type) { - // find a different target with same type - TerrainObject *new_target = nullptr; - new_target = find_near(*this->entity->location, - [target_type](const TerrainObject &obj) { - return obj.unit.unit_type->id() == target_type && !obj.unit.has_attribute(attr_type::worker) && obj.unit.has_attribute(attr_type::resource) && obj.unit.get_attribute().amount > 0.0; - }); - - if (new_target) { - this->entity->log(MSG(dbg) << "auto retasking"); - auto &pl_attr = this->entity->get_attribute(); - Command cmd(pl_attr.player, &new_target->unit); - this->entity->queue_cmd(cmd); - } -} - -UnitReference GatherAction::nearest_dropsite(game_resource res_type) { - // find nearest dropsite from the targeted resource - auto ds = find_near(*this->target.get()->location, - [=, this](const TerrainObject &obj) { - if (not obj.unit.has_attribute(attr_type::building) or &obj.unit == this->entity or &obj.unit == this->target.get()) { - return false; - } - - return obj.unit.get_attribute().completed >= 1.0f && obj.unit.has_attribute(attr_type::owner) && obj.unit.get_attribute().player.owns(*this->entity) && obj.unit.has_attribute(attr_type::dropsite) && obj.unit.get_attribute().accepting_resource(res_type); - }); - - if (ds) { - return ds->unit.get_ref(); - } - else { - this->entity->log(MSG(dbg) << "no dropsite found"); - return UnitReference(); - } -} - -AttackAction::AttackAction(Unit *e, UnitReference tar) : - TargetAction{e, graphic_type::attack, tar, get_attack_range(e)}, - timer{500} { // TODO get fire rate from unit type - - // check if attacking a non resource unit - if (this->entity->has_attribute(attr_type::worker) && (!tar.get()->has_attribute(attr_type::resource) || tar.get()->has_attribute(attr_type::worker))) { - // switch to default villager graphics - if (this->entity->has_attribute(attr_type::multitype)) { - this->entity->get_attribute().switchType(gamedata::unit_classes::CIVILIAN, this->entity); - } - } - - // TODO rivit logic, a start inside the animation should be provided - this->timer.skip_to_trigger(); -} - -AttackAction::~AttackAction() = default; - -void AttackAction::update_in_range(unsigned int time, Unit *target_ptr) { - if (this->timer.update(time)) { - this->attack(*target_ptr); - } -} - -bool AttackAction::completed_in_range(Unit *target_ptr) const { - auto &dm = target_ptr->get_attribute(); - return dm.hp < 1; // is unit still alive? -} - -void AttackAction::attack(Unit &target) { - auto &attack = this->entity->get_attribute(); - if (attack.ptype) { - // add projectile to the game - this->fire_projectile(attack, target.location->pos.draw); - } - else { - this->damage_unit(target); - } -} - -void AttackAction::fire_projectile(const Attribute &att, const coord::phys3 &target) { - // container terrain and initial position - UnitContainer *container = this->entity->get_container(); - coord::phys3 current_pos = this->entity->location->pos.draw; - current_pos.up = att.init_height; - - // create using the producer - auto &player = this->entity->get_attribute().player; - auto projectile_ref = container->new_unit(*att.ptype, player, current_pos); - - // send towards target using a projectile ability (creates projectile motion action) - if (projectile_ref.is_valid()) { - auto projectile = projectile_ref.get(); - auto &projectile_attr = projectile->get_attribute(); - projectile_attr.launcher = this->entity->get_ref(); - projectile_attr.launched = true; - projectile->push_action(std::make_unique(projectile, target), true); - } - else { - this->entity->log(MSG(dbg) << "projectile launch failed"); - } -} - - -HealAction::HealAction(Unit *e, UnitReference tar) : - TargetAction{e, graphic_type::heal, tar, get_attack_range(e)}, - timer{this->entity->get_attribute().rate} { -} - -HealAction::~HealAction() = default; - -void HealAction::update_in_range(unsigned int time, Unit *target_ptr) { - if (this->timer.update(time)) { - this->heal(*target_ptr); - } -} - -bool HealAction::completed_in_range(Unit *target_ptr) const { - auto &hp = target_ptr->get_attribute(); - auto &dm = target_ptr->get_attribute(); - return dm.hp >= hp.hp; // is unit at full hitpoints? -} - -void HealAction::heal(Unit &target) { - auto &heal = this->entity->get_attribute(); - - // TODO move to separate function heal_unit (like damage_unit)? - // heal object - if (target.has_attribute(attr_type::hitpoints) && target.has_attribute(attr_type::damaged)) { - auto &hp = target.get_attribute(); - auto &dm = target.get_attribute(); - if ((dm.hp + heal.life) < hp.hp) { - dm.hp += heal.life; - } - else { - dm.hp = hp.hp; - } - } -} - - -ConvertAction::ConvertAction(Unit *e, UnitReference tar) : - TargetAction{e, graphic_type::attack, tar}, - complete{.0f} { -} - -void ConvertAction::update_in_range(unsigned int, Unit *) {} - -ProjectileAction::ProjectileAction(Unit *e, coord::phys3 target) : - UnitAction{e, graphic_type::standing}, - has_hit{false} { - // find speed to move - auto &sp_attr = this->entity->get_attribute(); - double projectile_speed = sp_attr.unit_speed.to_double(); - - // arc of projectile - auto &pr_attr = this->entity->get_attribute(); - float projectile_arc = pr_attr.projectile_arc; - - // distance and time to target - coord::phys3_delta d = target - this->entity->location->pos.draw; - double distance_to_target = d.length(); - double flight_time = distance_to_target / projectile_speed; - - - if (projectile_arc < 0) { - // TODO negative values probably indicate something - projectile_arc += 0.2; - } - - // now figure gravity from arc parameter - // TODO projectile arc is the ratio between horizontal and - // vertical components of the initial direction - this->grav = 0.01f * (exp(pow(projectile_arc, 0.5f)) - 1) * projectile_speed; - - // inital launch direction - auto &d_attr = this->entity->get_attribute(); - d_attr.unit_dir = d * (projectile_speed / distance_to_target); - - // account for initial height - coord::phys_t initial_height = this->entity->location->pos.draw.up; - d_attr.unit_dir.up = coord::phys_t((grav * flight_time) / 2) - (initial_height * (1 / flight_time)); -} - -ProjectileAction::~ProjectileAction() = default; - -void ProjectileAction::update(unsigned int time) { - auto &d_attr = this->entity->get_attribute(); - - // apply gravity - d_attr.unit_dir.up -= this->grav * time; - - coord::phys3 new_position = this->entity->location->pos.draw + d_attr.unit_dir * time; - if (!this->entity->location->move(new_position)) { - // TODO implement friendly_fire (now friendly_fire is always on), attack_attribute.friendly_fire - - // find object which was hit - auto terrain = this->entity->location->get_terrain(); - TileContent *tc = terrain->get_data(new_position.to_tile3().to_tile()); - if (tc && !tc->obj.empty()) { - for (auto obj_location : tc->obj) { - if (this->entity->location.get() != obj_location && obj_location->check_collisions()) { - this->damage_unit(obj_location->unit); - break; - } - } - } - - // TODO implement area of effect, attack_attribute.area_of_effect - - has_hit = true; - } - - // inc frame - this->frame += time * this->frame_rate; -} - -void ProjectileAction::on_completion() {} - -bool ProjectileAction::completed() const { - return (has_hit || this->entity->location->pos.draw.up <= 0); -} - -} // namespace openage diff --git a/libopenage/unit/action.h b/libopenage/unit/action.h deleted file mode 100644 index b0db755fe6..0000000000 --- a/libopenage/unit/action.h +++ /dev/null @@ -1,720 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -#include "../gamestate/old/resource.h" -#include "../pathfinding/path.h" -#include "attribute.h" -#include "research.h" -#include "unit.h" -#include "unit_container.h" - -namespace openage { - -class TerrainSearch; - -// TODO use a type instead of unsigned int for time - -/** - * A interval triggering timer used in actions. - * TODO find a better name for triggers - */ -class IntervalTimer { -public: - /** - * Constructs a timer with a given interval - */ - IntervalTimer(unsigned int interval); - - /** - * Constructs a timer with a given interval which will - * stop after a given number of triggers. - */ - IntervalTimer(unsigned int interval, int max_triggers); - - void skip_to_trigger(); - - bool update(unsigned int time); - - /** - * Returns the time until the next trigger - */ - unsigned int get_time_left() const; - - float get_progress() const; - - /** - * Returns true if at least one interval has passed. - */ - bool has_triggers() const; - - /** - * Returns true if the interval passed have reached the max. - */ - bool finished() const; - - /** - * Returns the number of intervals passed. - */ - int get_triggers() const { - return this->triggers; - } - - unsigned int get_interval() const { - return this->interval; - } - - void set_interval(unsigned int interval) { - this->interval = interval; - } - -private: - unsigned int interval; - - int max_triggers; - - unsigned int time_left; - - int triggers; -}; - - -/** - * Actions can be pushed onto any units action stack - * - * Each update cycle will perform the update function of the - * action on top of this stack - */ -class UnitAction { -public: - /** - * Require unit to be updated and an initial graphic type - */ - UnitAction(Unit *u, graphic_type initial_gt); - - virtual ~UnitAction() {} - - /** - * type of graphic this action should use - */ - graphic_type type() const; - - /** - * frame number to use on the current graphic - */ - float current_frame() const; - - /** - * each action has its own update functionality which gets called when this - * is the active action - */ - virtual void update(unsigned int time) = 0; - - /** - * action to perform when popped from a units action stack - */ - virtual void on_completion() = 0; - - /** - * gets called for all actions on stack each update cycle - * @return true when action is completed so it and everything above it can be popped - */ - virtual bool completed() const = 0; - - /** - * checks if the action can be interrupted, allowing it to be popped if the user - * specifies a new action, if false the action must reach a completed state - * before removal - * eg dead action must be completed and cannot be discarded - */ - virtual bool allow_interrupt() const = 0; - - /** - * control whether stack can discard the action automatically and - * should the stack be modifiable when this action is on top - * - * if true this action must complete and will not allow new actions - * to be pushed while it is active and also does not update the secondary actions - */ - virtual bool allow_control() const = 0; - - /** - * debug string to identify action types - */ - virtual std::string name() const = 0; - - /** - * common functions for actions - */ - void face_towards(const coord::phys3 pos); - - /** - * Damage a unit, returns true if the unit was killed in the process - */ - bool damage_unit(Unit &target); - - void move_to(Unit &target, bool use_range = true); - - /** - * produce debug info such as visualising paths - */ - static bool show_debug; - - /** - * a small distance to which units are considered touching - * when within this distance - */ - static coord::phys_t adjacent_range(Unit *u); - - /** - * looks at an ranged attributes on the unit - * otherwise returns same as adjacent_range() - */ - static coord::phys_t get_attack_range(Unit *u); - - /** - * looks at heal attribute on the unit - * otherwise returns same as adjacent_range() - */ - static coord::phys_t get_heal_range(Unit *u); - -protected: - /** - * the entity being updated - */ - Unit *entity; - - /** - * common graphic controls - */ - graphic_type graphic; - float frame; - float frame_rate; -}; - -/** - * Base class for actions which target another unit such as - * gather, attack, heal and convert - * TODO implement min range - */ -class TargetAction : public UnitAction { -public: - /** - * action_rad is how close a unit must come to another - * unit to be considered to touch the other, for example in - * gathering resource and melee attack - */ - TargetAction(Unit *e, graphic_type gt, UnitReference r, coord::phys_t action_rad); - - /** - * this constructor uses the default action radius formula which will - * bring the object as near to the target as the pathing grid will allow. - */ - TargetAction(Unit *e, graphic_type gt, UnitReference r); - virtual ~TargetAction() {} - - void update(unsigned int time) override; - void on_completion() override; - bool completed() const override; - bool allow_interrupt() const override { - return true; - } - bool allow_control() const override { - return true; - } - virtual std::string name() const override = 0; - - /** - * Control units action when in range of the target - */ - virtual void update_in_range(unsigned int, Unit *) = 0; - virtual void on_completion_in_range(int target_type) = 0; - virtual bool completed_in_range(Unit *) const = 0; - - coord::phys_t distance_to_target(); - Unit *update_distance(); - - UnitReference get_target() const; - int get_target_type_id() const; - - /** - * changes target, ending action when new target is invalid - */ - void set_target(UnitReference new_target); - -private: - UnitReference target; - int target_type_id; - int repath_attempts; - bool end_action; - - /** - * tracks distance to target from last update - */ - coord::phys_t dist_to_target, radius; -}; - -/** - * plays a fixed number of frames for the units dying animation - */ -class DecayAction : public UnitAction { -public: - DecayAction(Unit *e); - virtual ~DecayAction() {} - - void update(unsigned int time) override; - void on_completion() override; - bool completed() const override; - bool allow_interrupt() const override { - return false; - } - bool allow_control() const override { - return false; - } - std::string name() const override { - return "decay"; - } - -private: - float end_frame; -}; - -/** - * plays a fixed number of frames for the units dying animation - */ -class DeadAction : public UnitAction { -public: - DeadAction( - Unit *e, - std::function on_complete = []() {}); - virtual ~DeadAction() {} - - void update(unsigned int time) override; - void on_completion() override; - bool completed() const override; - bool allow_interrupt() const override { - return false; - } - bool allow_control() const override { - return false; - } - std::string name() const override { - return "dead"; - } - -private: - float end_frame; - std::function on_complete_func; -}; - -/** - * places an idle action on the stack once building is complete - */ -class FoundationAction : public UnitAction { -public: - FoundationAction(Unit *e, bool add_destuction = false); - virtual ~FoundationAction() {} - - void update(unsigned int time) override; - void on_completion() override; - bool completed() const override; - bool allow_interrupt() const override { - return true; - } - bool allow_control() const override { - return false; - } - std::string name() const override { - return "foundation"; - } - -private: - bool add_destruct_effect, cancel; -}; - -/** - * keeps an entity in a fixed position - */ -class IdleAction : public UnitAction { -public: - IdleAction(Unit *e); - virtual ~IdleAction() {} - - void update(unsigned int time) override; - void on_completion() override; - bool completed() const override; - bool allow_interrupt() const override { - return false; - } - bool allow_control() const override { - return true; - } - std::string name() const override { - return "idle"; - } - -private: - // look for auto task actions - std::shared_ptr search; - ability_set auto_abilities; -}; - -/** - * moves an entity to another location - */ -class MoveAction : public UnitAction { -public: - /** - * moves unit to a given fixed location - */ - MoveAction(Unit *e, coord::phys3 tar, bool repath = true); - - /** - * moves a unit to within a distance to another unit - */ - MoveAction(Unit *e, UnitReference tar, coord::phys_t within_range); - virtual ~MoveAction(); - - void update(unsigned int time) override; - void on_completion() override; - bool completed() const override; - bool allow_interrupt() const override { - return true; - } - bool allow_control() const override { - return true; - } - std::string name() const override { - return "move"; - } - - coord::phys3 next_waypoint() const; - -private: - UnitReference unit_target; - coord::phys3 target; - - // how near the units should come to target - coord::phys_t distance_to_target, radius; - - path::Path path; - - // should a new path be found if unit gets blocked - bool allow_repath, end_action; - - void initialise(); - - /** - * use a star to find a path to target - */ - void set_path(); - - /** - * updates the distance_to_target value - */ - void set_distance(); -}; - -/** - * garrison inside a building - */ -class GarrisonAction : public TargetAction { -public: - GarrisonAction(Unit *e, UnitReference build); - virtual ~GarrisonAction() {} - - void update_in_range(unsigned int time, Unit *target_unit) override; - void on_completion_in_range(int) override {} - bool completed_in_range(Unit *) const override { - return this->complete; - } - std::string name() const override { - return "garrison"; - } - -private: - bool complete; -}; - -/** - * garrison inside a building - */ -class UngarrisonAction : public UnitAction { -public: - UngarrisonAction(Unit *e, const coord::phys3 &pos); - virtual ~UngarrisonAction() {} - - void update(unsigned int time) override; - void on_completion() override; - bool completed() const override { - return this->complete; - } - bool allow_interrupt() const override { - return true; - } - bool allow_control() const override { - return true; - } - std::string name() const override { - return "ungarrison"; - } - -private: - coord::phys3 position; - bool complete; -}; - -/** - * trains a new unit - */ -class TrainAction : public UnitAction { -public: - TrainAction(Unit *e, UnitType *pp); - virtual ~TrainAction() {} - - void update(unsigned int time) override; - void on_completion() override; - bool completed() const override { - return this->complete; - } - bool allow_interrupt() const override { - return false; - } - bool allow_control() const override { - return true; - } - std::string name() const override { - return "train"; - } - - float get_progress() const { - return this->timer.get_progress(); - } - -private: - UnitType *trained; - - IntervalTimer timer; - bool started; - bool complete; -}; - -/** - * trains a new unit - */ -class ResearchAction : public UnitAction { -public: - ResearchAction(Unit *e, Research *research); - virtual ~ResearchAction() {} - - void update(unsigned int time) override; - void on_completion() override; - bool completed() const override { - return this->complete; - } - bool allow_interrupt() const override { - return false; - } - bool allow_control() const override { - return true; - } - std::string name() const override { - return "train"; - } - - float get_progress() const { - return this->timer.get_progress(); - } - const ResearchType *get_research_type() const { - return this->research->type; - } - -private: - Research *research; - - IntervalTimer timer; - bool complete; -}; - -/** - * builds a building - */ -class BuildAction : public TargetAction { -public: - BuildAction(Unit *e, UnitReference foundation); - virtual ~BuildAction() {} - - void update_in_range(unsigned int time, Unit *target_unit) override; - void on_completion_in_range(int) override {} - bool completed_in_range(Unit *) const override { - return this->complete >= 1.0f; - } - void on_completion() override; - std::string name() const override { - return "build"; - } - - float get_progress() const { - return this->complete; - } - -private: - float complete, build_rate; - static constexpr float search_tile_distance = 9.0f; -}; - -/** - * repairs a unit - */ -class RepairAction : public TargetAction { -public: - RepairAction(Unit *e, UnitReference tar); - virtual ~RepairAction() {} - - void update_in_range(unsigned int time, Unit *target_unit) override; - void on_completion_in_range(int) override {} - bool completed_in_range(Unit *) const override { - return this->complete; - } - std::string name() const override { - return "repair"; - } - -private: - /** - * stores the cost of the repair for 1hp - */ - ResourceBundle cost; - - IntervalTimer timer; - bool complete; -}; - -/** - * gathers resource from another object - */ -class GatherAction : public TargetAction { -public: - GatherAction(Unit *e, UnitReference tar); - virtual ~GatherAction(); - - void update_in_range(unsigned int time, Unit *target_unit) override; - void on_completion_in_range(int target_type) override; - bool completed_in_range(Unit *) const override { - return this->complete; - } - std::string name() const override { - return "gather"; - } - -private: - bool complete, target_resource; - UnitReference target; - gamedata::unit_classes resource_class; - UnitReference nearest_dropsite(game_resource res_type); -}; - -/** - * attacks another unit - */ -class AttackAction : public TargetAction { -public: - AttackAction(Unit *e, UnitReference tar); - virtual ~AttackAction(); - - void update_in_range(unsigned int time, Unit *target_unit) override; - void on_completion_in_range(int) override {} - bool completed_in_range(Unit *) const override; - std::string name() const override { - return "attack"; - } - -private: - IntervalTimer timer; - - /** - * use attack action - */ - void attack(Unit &target); - - /** - * add a projectile game object which moves towards the target - */ - void fire_projectile(const Attribute &att, const coord::phys3 &target); -}; - -/** - * heals another unit - */ -class HealAction : public TargetAction { -public: - HealAction(Unit *e, UnitReference tar); - virtual ~HealAction(); - - void update_in_range(unsigned int time, Unit *target_unit) override; - void on_completion_in_range(int) override {} - bool completed_in_range(Unit *) const override; - std::string name() const override { - return "heal"; - } - -private: - IntervalTimer timer; - - /** - * use heal action - */ - void heal(Unit &target); -}; - -/** - * convert an object - */ -class ConvertAction : public TargetAction { -public: - ConvertAction(Unit *e, UnitReference tar); - virtual ~ConvertAction() {} - - void update_in_range(unsigned int time, Unit *target_unit) override; - void on_completion_in_range(int) override {} - bool completed_in_range(Unit *) const override { - return this->complete >= 1.0f; - } - std::string name() const override { - return "convert"; - } - -private: - float complete; -}; - -/** - * moves object to fly in a parabolic shape - */ -class ProjectileAction : public UnitAction { -public: - ProjectileAction(Unit *e, coord::phys3 target); - virtual ~ProjectileAction(); - - void update(unsigned int time) override; - void on_completion() override; - bool completed() const override; - bool allow_interrupt() const override { - return false; - } - bool allow_control() const override { - return false; - } - std::string name() const override { - return "projectile"; - } - -private: - double grav; - bool has_hit; -}; - -} // namespace openage diff --git a/libopenage/unit/attribute.cpp b/libopenage/unit/attribute.cpp deleted file mode 100644 index 6826bded35..0000000000 --- a/libopenage/unit/attribute.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2016-2017 the openage authors. See copying.md for legal info. - -#include "attribute.h" -#include "unit.h" -#include "unit_type.h" - -namespace openage { - -bool Attribute::accepting_resource(game_resource res) const { - return std::find(resource_types.begin(), resource_types.end(), res) != resource_types.end(); -} - -void Attribute::switchType(const gamedata::unit_classes cls, Unit *unit) const { - auto search = this->types.find(cls); - if (search != this->types.end()) { - auto &player = unit->get_attribute(); - search->second->reinitialise(unit, player.player); - } -} - -} // namespace openage diff --git a/libopenage/unit/attribute.h b/libopenage/unit/attribute.h deleted file mode 100644 index 5a5ce05117..0000000000 --- a/libopenage/unit/attribute.h +++ /dev/null @@ -1,643 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include - -#include "../coord/tile.h" -#include "../gamedata/unit_dummy.h" -#include "../terrain/terrain_object.h" -#include "../gamestate/old/resource.h" -#include "unit_container.h" - -namespace std { - -/** - * hasher for unit classes enum type - */ -template<> struct hash { - typedef underlying_type::type underlying_type; - - size_t operator()(const openage::gamedata::unit_classes &arg) const { - hash hasher; - return hasher(static_cast(arg)); - } -}; - -} // namespace std - -namespace openage { - -/** - * Types of action graphics - */ -enum class graphic_type { - construct, - shadow, - decay, - dying, - standing, - walking, - carrying, - attack, - heal, - work -}; - -/** - * List of unit's attribute types. - */ -enum class attr_type { - owner, - population, - damaged, - hitpoints, - armor, - attack, - formation, - heal, - speed, - direction, - projectile, - building, - dropsite, - resource, - resource_generator, - worker, - storage, - multitype, - garrison -}; - -/** - * List of unit's attack stance. - * Can be used for buildings also. - */ -enum class attack_stance { - aggressive, - defensive, - stand_ground, - do_nothing -}; - -/** - * List of unit's formation. - * Effect applys on a group of units. - */ -enum class attack_formation { - line, - staggered, - box, - flank -}; - - -/** - * this type gets specialized for each attribute - */ -template class Attribute; - -/** - * Wraps a templated attribute - */ -class AttributeContainer { -public: - AttributeContainer() {} - - AttributeContainer(attr_type t) - : - type{t} {} - - virtual ~AttributeContainer() = default; - - attr_type type; - - /** - * shared attributes are common across all units of - * one type, such as max hp, and gather rates - * - * non shared attributes include a units current hp, - * and the amount a villager is carrying - */ - virtual bool shared() const = 0; - - /** - * Produces an copy of the attribute. - */ - virtual std::shared_ptr copy() const = 0; -}; - -/** - * An unordered_map with a int key used as a type id - * and a unsigned int value used as the amount - */ -using typeamount_map = std::unordered_map; - -/** - * Wraps a templated shared attribute - * - * Shared attributes are common across all units of - * one type - */ -class SharedAttributeContainer: public AttributeContainer { -public: - - SharedAttributeContainer(attr_type t) - : - AttributeContainer{t} {} - - bool shared() const override { - return true; - } -}; - -/** - * Wraps a templated unshared attribute - * - * Shared attributes are copied for each unit of - * one type - */ -class UnsharedAttributeContainer: public AttributeContainer { -public: - - UnsharedAttributeContainer(attr_type t) - : - AttributeContainer{t} {} - - bool shared() const override { - return false; - } -}; - -// ----------------------------- -// attribute definitions go here -// ----------------------------- - -class Player; - -template<> class Attribute: public SharedAttributeContainer { -public: - Attribute(Player &p) - : - SharedAttributeContainer{attr_type::owner}, - player(p) {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - Player &player; -}; - -/** - * The max hitpoints and health bar information. - * TODO change bar information stucture - */ -template<> class Attribute: public SharedAttributeContainer { -public: - Attribute(unsigned int i) - : - SharedAttributeContainer{attr_type::hitpoints}, - hp{i} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - /** - * The max hitpoints - */ - unsigned int hp; - float hp_bar_height; -}; - -/** - * The population capacity and the population demand. - */ -template<> class Attribute: public SharedAttributeContainer { -public: - Attribute(int demand, int capacity) - : - SharedAttributeContainer{attr_type::population}, - demand{demand}, - capacity{capacity} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - int demand; - int capacity; -}; - -/** - * The current hitpoints. - * TODO add last damage taken timestamp - */ -template<> class Attribute: public UnsharedAttributeContainer { -public: - Attribute(unsigned int i) - : - UnsharedAttributeContainer{attr_type::damaged}, - hp{i} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - /** - * The current hitpoint - */ - unsigned int hp; -}; - -template<> class Attribute: public SharedAttributeContainer { -public: - Attribute(typeamount_map a) - : - SharedAttributeContainer{attr_type::armor}, - armor{a} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - typeamount_map armor; -}; - -/** - * TODO can a unit have multiple attacks such as villagers hunting map target classes onto attacks - * TODO remove the first constructor and the default values after (keep for now for compatibility) - */ -template<> class Attribute: public SharedAttributeContainer { -public: - // TODO remove (keep for testing) - // 4 = gamedata::hit_class::UNITS_MELEE (not exported at the moment) - Attribute(UnitType *type, coord::phys_t r, coord::phys_t h, unsigned int d) - : - Attribute{type, r, h, {{4, d}}} {} - - Attribute(UnitType *type, coord::phys_t r, coord::phys_t h, typeamount_map d, - coord::phys_t min_range=0, bool friendly_fire=false, - coord::phys_t area_of_effect=0) - : - SharedAttributeContainer{attr_type::attack}, - ptype{type}, - min_range{min_range}, - max_range{r}, - init_height{h}, - damage{d}, - friendly_fire{friendly_fire}, - area_of_effect{area_of_effect} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - /** - * The projectile's unit type - */ - UnitType *ptype; - - /** - * The min range of the attack - * TODO not used - */ - coord::phys_t min_range; - - /** - * The max range of the attack - */ - coord::phys_t max_range; - - /** - * The height from which the projectile starts - */ - coord::phys_t init_height; - - typeamount_map damage; - - /** - * If the attack can damage allied (friendly) units. - * TODO not used - */ - bool friendly_fire; - - /** - * The radius of the area of effect of the attack or 0 if there is no area_of_effect. - * TODO not used - */ - coord::phys_t area_of_effect; -}; - -/** - * The attack stance and formation - * TODO store patrol and follow command information - */ -template<> class Attribute: public UnsharedAttributeContainer { -public: - - Attribute() - : - Attribute{attack_stance::do_nothing} {} - - Attribute(attack_stance stance) - : - UnsharedAttributeContainer{attr_type::formation}, - stance{stance}, - formation{attack_formation::line} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - attack_stance stance; - attack_formation formation; -}; - -/** - * Healing capabilities. - */ -template<> class Attribute: public SharedAttributeContainer { -public: - Attribute(coord::phys_t r, unsigned int l, unsigned int ra) - : - SharedAttributeContainer{attr_type::heal}, - range{r}, - life{l}, - rate{ra} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - /** - * The max range of the healing. - */ - coord::phys_t range; - - /** - * Life healed in each cycle - */ - unsigned int life; - - /** - * The period of each heal cycle - */ - unsigned int rate; -}; - -template<> class Attribute: public SharedAttributeContainer { -public: - Attribute(coord::phys_t sp) - : - SharedAttributeContainer{attr_type::speed}, - unit_speed{sp} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - // TODO rename to default or normal - coord::phys_t unit_speed; -}; - -template<> class Attribute: public UnsharedAttributeContainer { -public: - Attribute(coord::phys3_delta dir) - : - UnsharedAttributeContainer{attr_type::direction}, - unit_dir(dir) {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - coord::phys3_delta unit_dir; -}; - -template<> class Attribute: public UnsharedAttributeContainer { -public: - Attribute(float arc) - : - UnsharedAttributeContainer{attr_type::projectile}, - projectile_arc{arc}, - launched{false} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - float projectile_arc; - UnitReference launcher; - bool launched; -}; - -/** - * TODO revisit after unit training is improved - */ -template<> class Attribute: public UnsharedAttributeContainer { -public: - Attribute(int foundation_terrain, UnitType *pp, coord::phys3 gather_point) - : - UnsharedAttributeContainer{attr_type::building}, - completed{.0f}, - foundation_terrain{foundation_terrain}, - pp{pp}, - gather_point{gather_point} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - float completed; - int foundation_terrain; - - // set the TerrainObject to this state - // once building has been completed - object_state completion_state; - - // TODO: list allowed trainable producers - UnitType *pp; - - /** - * The go to point after a unit is created. - */ - coord::phys3 gather_point; -}; - -/** - * The resources that are accepted to be dropped. - */ -template<> class Attribute: public SharedAttributeContainer { -public: - Attribute(std::vector types) - : - SharedAttributeContainer{attr_type::dropsite}, - resource_types{types} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - bool accepting_resource(game_resource res) const; - - std::vector resource_types; -}; - -/** - * Resource capacity of a trees, mines, animal, worker etc. - */ -template<> class Attribute: public UnsharedAttributeContainer { -public: - Attribute() - : - Attribute{game_resource::food, 0} {} - - Attribute(game_resource type, double init_amount, double decay=0.0, double gather_rate=1.0) - : - UnsharedAttributeContainer{attr_type::resource}, - resource_type{type}, - amount{init_amount}, - decay{decay}, - gather_rate{gather_rate} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - game_resource resource_type; - - double amount; - - /** - * The rate of decay - */ - double decay; - - /** - * The gather rate multiplier (1.0 is the identity) - */ - double gather_rate; - -}; - -/** - * Resource generator eg. relic. - * While a unit is idle and contains this attribute, it will generate resources for its owner. - * - * A rate of zero means that the generation is continuously and not in intervals. - */ -template<> class Attribute: public SharedAttributeContainer { -public: - - Attribute(ResourceBundle resources, double rate=0) - : - SharedAttributeContainer{attr_type::resource_generator}, - resources{resources}, - rate{rate} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - ResourceBundle resources; - - double rate; - -}; - -/** - * The worker's capacity and gather rates. - */ -template<> class Attribute: public SharedAttributeContainer { -public: - Attribute() - : - SharedAttributeContainer{attr_type::worker} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - /** - * The max number of resources that can be carried. - */ - double capacity; - - /** - * The gather rate for each resource. - * The ResourceBundle class is used but instead of amounts it stores gather rates. - */ - ResourceBundle gather_rate; -}; - -/** - * The worker's capacity and gather rates. - */ -template<> class Attribute: public SharedAttributeContainer { -public: - Attribute() - : - SharedAttributeContainer{attr_type::storage} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - /** - * The capacity for each resource. - */ - ResourceBundle capacity; -}; - -class Unit; - -/** - * Stores the collection of unit types based on a unit class. - * It is used mostly for units with multiple graphics (villagers, trebuchets). - */ -template<> class Attribute: public SharedAttributeContainer { -public: - Attribute() - : - SharedAttributeContainer{attr_type::multitype} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - /** - * Switch the type of a unit based on a given unit class - */ - void switchType(const gamedata::unit_classes cls, Unit *unit) const; - - /** - * The collection of unit class to unit type pairs - */ - std::unordered_map types; -}; - -/** - * Units put inside a building. - * TODO add capacity per type of unit - */ -template<> class Attribute: public UnsharedAttributeContainer { -public: - Attribute() - : - UnsharedAttributeContainer{attr_type::garrison} {} - - std::shared_ptr copy() const override { - return std::make_shared>(*this); - } - - /** - * The units that are garrisoned. - */ - std::vector content; -}; - -} // namespace openage diff --git a/libopenage/unit/attributes.cpp b/libopenage/unit/attributes.cpp deleted file mode 100644 index faa4fa0df5..0000000000 --- a/libopenage/unit/attributes.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2017-2017 the openage authors. See copying.md for legal info. - -#include "attributes.h" - -namespace openage { - -void Attributes::add(const std::shared_ptr attr) { - this->attrs[attr->type] = attr; -} - -void Attributes::add_copies(const Attributes &other) { - this->add_copies(other, true, true); -} - -void Attributes::add_copies(const Attributes &other, bool shared, bool unshared) { - for (auto &i : other.attrs) { - auto &attr = *i.second.get(); - - if (attr.shared()) { - if (shared) { - // pass self - this->add(i.second); - } - } - else if (unshared) { - // create copy - this->add(attr.copy()); - } - } -} - -bool Attributes::remove(const attr_type type) { - return this->attrs.erase(type) > 0; -} - -bool Attributes::has(const attr_type type) const { - return this->attrs.find(type) != this->attrs.end(); -} - -std::shared_ptr Attributes::get(const attr_type type) const { - return this->attrs.at(type); -} - -} // namespace openage diff --git a/libopenage/unit/attributes.h b/libopenage/unit/attributes.h deleted file mode 100644 index cc02ac1193..0000000000 --- a/libopenage/unit/attributes.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2017-2017 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "attribute.h" - -namespace openage { - -/** - * Contains a group of attributes. - * Can contain only one attribute of each type. - */ -class Attributes { -public: - Attributes() {} - - /** - * Add an attribute or replace any attribute of the same type. - */ - void add(const std::shared_ptr attr); - - /** - * Add copies of all the attributes from the given Attributes. - */ - void add_copies(const Attributes &attrs); - - /** - * Add copies of all the attributes from the given Attributes. - * If shared is false, shared attributes are ignored. - * If unshared is false, unshared attributes are ignored. - */ - void add_copies(const Attributes &attrs, bool shared, bool unshared); - - /** - * Remove an attribute based on the type. - */ - bool remove(const attr_type type); - - /** - * Check if the attribute of the given type exists. - */ - bool has(const attr_type type) const; - - /** - * Get the attribute based on the type. - */ - std::shared_ptr get(const attr_type type) const; - - /** - * Get the attribute - */ - template - Attribute &get() const { - return *reinterpret_cast *>(this->attrs.at(T).get()); - } - -private: - - std::map> attrs; -}; - -} // namespace openage diff --git a/libopenage/unit/command.cpp b/libopenage/unit/command.cpp deleted file mode 100644 index ec83664394..0000000000 --- a/libopenage/unit/command.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2014-2017 the openage authors. See copying.md for legal info. - -#include "command.h" - -namespace openage { - -Command::Command(const Player &p, Unit *unit, bool haspos, UnitType *t, Research *res) - : - player(p), - has_pos{haspos}, - u{unit}, - unit_type{t}, - res{res} { - this->modifiers.set(); -} - -Command::Command(const Player &p, Unit *unit) - : - Command{p, unit, false, nullptr, nullptr} { -} - -Command::Command(const Player &p, coord::phys3 position) - : - Command{p, nullptr, true, nullptr, nullptr} { - this->pos = position; -} - -Command::Command(const Player &p, Unit *unit, coord::phys3 position) - : - Command{p, unit, true, nullptr, nullptr} { - this->pos = position; -} - -Command::Command(const Player &p, UnitType *t) - : - Command{p, nullptr, false, t, nullptr} { -} - -Command::Command(const Player &p, Research *res) - : - Command{p, nullptr, false, nullptr, res} { -} - -Command::Command(const Player &p, UnitType *t, coord::phys3 position) - : - Command{p, nullptr, true, t, nullptr} { - this->pos = position; -} - -bool Command::has_unit() const { - return this->u; -} - -bool Command::has_position() const { - return this->has_pos; -} - -bool Command::has_type() const { - return this->unit_type; -} - -bool Command::has_research() const { - return this->res; -} - -Unit *Command::unit() const { - return this->u; -} - -coord::phys3 Command::position() const { - return this->pos; -} - -UnitType *Command::type() const { - return this->unit_type; -} - -Research *Command::research() const { - return this->res; -} - -void Command::set_ability(ability_type t) { - this->modifiers = 0; - this->modifiers[static_cast(t)] = true; -} - -void Command::set_ability_set(ability_set set) { - this->modifiers = set; -} - -const ability_set &Command::ability() const { - return this->modifiers; -} - -void Command::add_flag(command_flag flag) { - this->flags.insert(flag); -} - -bool Command::has_flag(command_flag flag) const { - return 0 < this->flags.count(flag); -} - -} // namespace openage diff --git a/libopenage/unit/command.h b/libopenage/unit/command.h deleted file mode 100644 index 4719e09e0b..0000000000 --- a/libopenage/unit/command.h +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2014-2018 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "../coord/phys.h" -#include "ability.h" - -namespace openage { - -/** - * additional flags which may affect some abilities - */ -enum class command_flag { - interrupt, // the user directly issued this command, stopping other actions - use_range, // move command account for units range - attack_res // allow attack on a resource object -}; - -} // namespace openage - -namespace std { - -/** - * hasher for game command flags - */ -template<> -struct hash { - typedef underlying_type::type underlying_type; - - size_t operator()(const openage::command_flag &arg) const { - hash hasher; - return hasher(static_cast(arg)); - } -}; - -} // namespace std - -namespace openage { - -class Player; -class Research; -class Unit; -class UnitType; - -/* - * Game command from the ui - * TODO reorganize the names of the optional variables and their getters - */ -class Command { -public: - - /** - * target another unit - */ - Command(const Player &, Unit *unit); - - /** - * target a position - */ - Command(const Player &, coord::phys3 position); - - /** - * target another unit or a position - */ - Command(const Player &, Unit *unit, coord::phys3 position); - - /** - * select a type - */ - Command(const Player &, UnitType *t); - - /** - * select a research - */ - Command(const Player &, Research *res); - - /** - * place building foundation - */ - Command(const Player &, UnitType *, coord::phys3); - - bool has_unit() const; - bool has_position() const; - bool has_type() const; - bool has_research() const; - - Unit *unit() const; - coord::phys3 position() const; - UnitType *type() const; - Research *research() const; - - /** - * sets invoked ability type, no other type may be used if - * this gets set - * - * @param type allows a specific ability type to be used - * for example to set a unit to patrol rather than the default move - */ - void set_ability(ability_type t); - - /** - * restricts action to a set of possible ability types - */ - void set_ability_set(ability_set set); - - /** - * the ability types allowed to use this command - */ - const ability_set &ability() const; - - /** - * add addition option to this command - */ - void add_flag(command_flag flag); - - /** - * read the range setting - */ - bool has_flag(command_flag flag) const; - - /** - * player who created the command - */ - const Player &player; - -private: - - /** - * basic constructor, which shouldnt be used directly - */ - Command(const Player &, Unit *unit, bool haspos, UnitType *t, Research *res); - - bool has_pos; - Unit *u; - coord::phys3 pos = {0, 0, 0}; // TODO: make pos a c++17 optional - UnitType *unit_type; - Research *res; - - /** - * additional options - */ - std::unordered_set flags; - - /** - * select actions to use when targeting - */ - ability_set modifiers; - -}; - -} // namespace openage diff --git a/libopenage/unit/producer.cpp b/libopenage/unit/producer.cpp deleted file mode 100644 index 07f6f45463..0000000000 --- a/libopenage/unit/producer.cpp +++ /dev/null @@ -1,695 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#include - -#include "../gamedata/unit_dummy.h" -#include "../log/log.h" -#include "../terrain/terrain.h" -#include "../terrain/terrain_object.h" -#include "../util/strings.h" -#include "ability.h" -#include "action.h" -#include "producer.h" -#include "unit.h" - -/** @file - * Many values in this file are hardcoded, due to limited understanding of how the original - * game files work -- as more becomes known these will be removed. - * - * It is likely the conversion from gamedata to openage units will be done by the nyan - * system in future - */ - -namespace openage { - -std::unordered_set allowed_terrains(const gamedata::ground_type &restriction) { - // returns a terrain whitelist for a given restriction - // you can also define a blacklist for brevity, it will be converted and returned - std::unordered_set whitelist; - std::unordered_set blacklist; - - // 1, 14, and 15 are water, 2 is shore - if (restriction == gamedata::ground_type::WATER || restriction == gamedata::ground_type::WATER_0x0D || restriction == gamedata::ground_type::WATER_SHIP_0x03 || restriction == gamedata::ground_type::WATER_SHIP_0x0F) { - whitelist.insert(1); // water - whitelist.insert(2); // shore - whitelist.insert(4); // shallows - whitelist.insert(14); // medium water - whitelist.insert(15); // deep water - } - else if (restriction == gamedata::ground_type::SOLID) { - blacklist.insert(1); // water - blacklist.insert(4); // shallows - blacklist.insert(14); // medium water - blacklist.insert(15); // deep water - } - else if (restriction == gamedata::ground_type::FOUNDATION || restriction == gamedata::ground_type::NO_ICE_0x08 || restriction == gamedata::ground_type::FOREST) { - blacklist.insert(1); // water - blacklist.insert(4); // shallows - blacklist.insert(14); // medium water - blacklist.insert(15); // deep water - blacklist.insert(18); // ice - } - else { - log::log(MSG(warn) << "undefined terrain restriction, assuming solid"); - blacklist.insert(1); // water - blacklist.insert(4); // shallows - blacklist.insert(14); // medium water - blacklist.insert(15); // deep water - } - - // if we're using a blacklist, fill out a whitelist with everything not on it - if (blacklist.size() > 0) { - // Allow all terrains that are not on blacklist - for (int i = 0; i < 32; ++i) { - if (blacklist.count(i) == 0) { - whitelist.insert(i); - } - } - } - - return whitelist; -} - -ResourceBundle create_resource_cost(game_resource resource, int amount) { - ResourceBundle resources = ResourceBundle(); - resources[resource] = amount; - return resources; -} - -ObjectProducer::ObjectProducer(const Player &owner, const GameSpec &spec, const gamedata::unit_object *ud) : - UnitType(owner), - dataspec(spec), - unit_data(*ud), - dead_unit_id{ud->dead_unit_id} { - // copy the class type - this->unit_class = this->unit_data.unit_class; - this->icon = this->unit_data.icon_id; - - // for now just look for type names ending with "_D" - this->decay = unit_data.name.substr(unit_data.name.length() - 2) == "_D"; - - // find suitable sounds - int creation_sound = this->unit_data.train_sound_id; - int dying_sound = this->unit_data.dying_sound_id; - if (creation_sound == -1) { - creation_sound = this->unit_data.damage_sound_id; - } - if (creation_sound == -1) { - creation_sound = this->unit_data.selection_sound_id; - } - if (dying_sound == -1) { - dying_sound = 323; //generic explosion sound - } - on_create = spec.get_sound(creation_sound); - on_destroy = spec.get_sound(dying_sound); - - // convert the float to the discrete foundation size... - this->foundation_size = { - static_cast(this->unit_data.radius_x * 2), - static_cast(this->unit_data.radius_y * 2), - }; - - // TODO get cost, temp fixed cost of 50 food - this->cost.set(cost_type::constant, create_resource_cost(game_resource::food, 50)); -} - -ObjectProducer::~ObjectProducer() = default; - -int ObjectProducer::id() const { - return this->unit_data.id0; -} - -int ObjectProducer::parent_id() const { - int uid = this->unit_data.id0; - - // male types - if (uid == 156 || uid == 120 || uid == 592 || uid == 123 || uid == 579 || uid == 124) { - return 83; - } - - // female types - else if (uid == 222 || uid == 354 || uid == 590 || uid == 218 || uid == 581 || uid == 220) { - return 293; - } - return uid; -} - -std::string ObjectProducer::name() const { - return this->unit_data.name; -} - -void ObjectProducer::initialise(Unit *unit, Player &player) { - ENSURE(this->owner == player, "unit init from a UnitType of a wrong player which breaks tech levels"); - - // log attributes - unit->log(MSG(dbg) << "setting unit type " << this->unit_data.id0 << " " << this->unit_data.name); - - // reset existing attributes - unit->reset(); - - // initialise unit - unit->unit_type = this; - - // colour - unit->add_attribute(std::make_shared>(player)); - - // hitpoints if available - if (this->unit_data.hit_points > 0) { - unit->add_attribute(std::make_shared>(this->unit_data.hit_points)); - unit->add_attribute(std::make_shared>(this->unit_data.hit_points)); - } - - // collectable resources - if (this->unit_data.unit_class == gamedata::unit_classes::TREES) { - unit->add_attribute(std::make_shared>(game_resource::wood, 125)); - } - else if (this->unit_data.unit_class == gamedata::unit_classes::BERRY_BUSH) { - unit->add_attribute(std::make_shared>(game_resource::food, 100)); - } - else if (this->unit_data.unit_class == gamedata::unit_classes::SEA_FISH) { - unit->add_attribute(std::make_shared>(game_resource::food, 200)); - } - else if (this->unit_data.unit_class == gamedata::unit_classes::PREY_ANIMAL) { - unit->add_attribute(std::make_shared>(game_resource::food, 140)); - } - else if (this->unit_data.unit_class == gamedata::unit_classes::HERDABLE) { - unit->add_attribute(std::make_shared>(game_resource::food, 100, 0.1)); - } - else if (this->unit_data.unit_class == gamedata::unit_classes::GOLD_MINE) { - unit->add_attribute(std::make_shared>(game_resource::gold, 800)); - } - else if (this->unit_data.unit_class == gamedata::unit_classes::STONE_MINE) { - unit->add_attribute(std::make_shared>(game_resource::stone, 350)); - } - - // decaying units have a timed lifespan - if (decay) { - unit->push_action(std::make_unique(unit), true); - } - else { - // the default action - unit->push_action(std::make_unique(unit), true); - } - - // give required abilitys - for (auto &a : this->type_abilities) { - unit->give_ability(a); - } -} - -TerrainObject *ObjectProducer::place(Unit *u, std::shared_ptr terrain, coord::phys3 init_pos) const { - // find set of allowed terrains - std::unordered_set terrains = allowed_terrains(this->unit_data.terrain_restriction); - - /* - * decide what terrain is passable using this lambda - * currently unit avoids water and tiles with another unit - * this function should be true if pos is a valid position of the object - */ - TerrainObject *obj_ptr = u->location.get(); - std::weak_ptr terrain_ptr = terrain; - u->location->passable = [obj_ptr, terrain_ptr, terrains](const coord::phys3 &pos) -> bool { - // if location is deleted, then so is this lambda (deleting terrain implies location is deleted) - // so locking objects here will not return null - auto terrain = terrain_ptr.lock(); - - // look at all tiles in the bases range - for (coord::tile check_pos : tile_list(obj_ptr->get_range(pos, *terrain))) { - TileContent *tc = terrain->get_data(check_pos); - - // invalid tile types - if (!tc || terrains.count(tc->terrain_id) == 0) { - return false; - } - - // compare with objects intersecting the units tile - // ensure no intersections with other objects - for (auto obj_cmp : tc->obj) { - if (obj_ptr != obj_cmp && obj_cmp->check_collisions() && obj_ptr->intersects(*obj_cmp, pos)) { - return false; - } - } - } - return true; - }; - - // u->location->draw = [u, obj_ptr](const Engine &e) { - // if (u->selected) { - // obj_ptr->draw_outline(e.coord); - // } - // u->draw(e); - // }; - - // try to place the obj, it knows best whether it will fit. - auto state = this->decay ? object_state::placed_no_collision : object_state::placed; - if (u->location->place(terrain, init_pos, state)) { - if (this->on_create) { - this->on_create->play(); - } - return u->location.get(); - } - - // placing at the given position failed - u->log(MSG(dbg) << "failed to place object"); - return nullptr; -} - -MovableProducer::MovableProducer(const Player &owner, const GameSpec &spec, const gamedata::projectile_unit *um) : - ObjectProducer(owner, spec, um), - unit_data(*um), - on_move{spec.get_sound(this->unit_data.command_sound_id)}, - on_attack{spec.get_sound(this->unit_data.command_sound_id)}, - projectile{this->unit_data.attack_projectile_primary_unit_id} { - // extra abilities - this->type_abilities.emplace_back(std::make_shared(this->on_move)); - this->type_abilities.emplace_back(std::make_shared(this->on_attack)); -} - -MovableProducer::~MovableProducer() = default; - -void MovableProducer::initialise(Unit *unit, Player &player) { - /* - * call base function - */ - ObjectProducer::initialise(unit, player); - - /* - * basic attributes - */ - if (!unit->has_attribute(attr_type::direction)) { - unit->add_attribute(std::make_shared>(coord::phys3_delta{1, 0, 0})); - } - - /* - * distance per millisecond -- consider original game speed - * where 1.5 in game seconds pass in 1 real second - */ - coord::phys_t sp = this->unit_data.speed / 666; - unit->add_attribute(std::make_shared>(sp)); - - // projectile of melee attacks - UnitType *proj_type = this->owner.get_type(this->projectile); - if (this->unit_data.attack_projectile_primary_unit_id > 0 && proj_type) { - // calculate requirements for ranged attacks - coord::phys_t range_phys = this->unit_data.weapon_range_max; - unit->add_attribute(std::make_shared>(proj_type, range_phys, 48000, 1)); - } - else { - unit->add_attribute(std::make_shared>(nullptr, 0, 0, 1)); - } - unit->add_attribute(std::make_shared>()); -} - -TerrainObject *MovableProducer::place(Unit *unit, std::shared_ptr terrain, coord::phys3 init_pos) const { - return ObjectProducer::place(unit, terrain, init_pos); -} - -LivingProducer::LivingProducer(const Player &owner, const GameSpec &spec, const gamedata::living_unit *ud) : - MovableProducer(owner, spec, ud), - unit_data(*ud) { - // extra abilities - this->type_abilities.emplace_back(std::make_shared(this->on_move)); -} - -LivingProducer::~LivingProducer() = default; - -void LivingProducer::initialise(Unit *unit, Player &player) { - /* - * call base function - */ - MovableProducer::initialise(unit, player); - - // population of 1 for all movable units - if (this->unit_data.unit_class != gamedata::unit_classes::HERDABLE) { - unit->add_attribute(std::make_shared>(1, 0)); - } - - // add worker attributes - if (this->unit_data.unit_class == gamedata::unit_classes::CIVILIAN) { - unit->add_attribute(std::make_shared>()); - unit->add_attribute(std::make_shared>()); - unit->add_attribute(std::make_shared>()); - - // add graphic ids for resource actions - auto &worker_attr = unit->get_attribute(); - worker_attr.capacity = 10.0; - worker_attr.gather_rate[game_resource::wood] = 0.002; - worker_attr.gather_rate[game_resource::food] = 0.002; - worker_attr.gather_rate[game_resource::gold] = 0.002; - worker_attr.gather_rate[game_resource::stone] = 0.002; - - auto &multitype_attr = unit->get_attribute(); - // currently not sure where the game data keeps these values - // todo PREY_ANIMAL SEA_FISH - if (this->parent_id() == 83) { - // male graphics - multitype_attr.types[gamedata::unit_classes::CIVILIAN] = this->parent_type(); // get default villager - multitype_attr.types[gamedata::unit_classes::BUILDING] = this->owner.get_type(156); // builder 118 - multitype_attr.types[gamedata::unit_classes::BERRY_BUSH] = this->owner.get_type(120); // forager - multitype_attr.types[gamedata::unit_classes::HERDABLE] = this->owner.get_type(592); // sheperd - multitype_attr.types[gamedata::unit_classes::TREES] = this->owner.get_type(123); // woodcutter - multitype_attr.types[gamedata::unit_classes::GOLD_MINE] = this->owner.get_type(579); // gold miner - multitype_attr.types[gamedata::unit_classes::STONE_MINE] = this->owner.get_type(124); // stone miner - } - else { - // female graphics - multitype_attr.types[gamedata::unit_classes::CIVILIAN] = this->parent_type(); // get default villager - multitype_attr.types[gamedata::unit_classes::BUILDING] = this->owner.get_type(222); // builder 212 - multitype_attr.types[gamedata::unit_classes::BERRY_BUSH] = this->owner.get_type(354); // forager - multitype_attr.types[gamedata::unit_classes::HERDABLE] = this->owner.get_type(590); // sheperd - multitype_attr.types[gamedata::unit_classes::TREES] = this->owner.get_type(218); // woodcutter - multitype_attr.types[gamedata::unit_classes::GOLD_MINE] = this->owner.get_type(581); // gold miner - multitype_attr.types[gamedata::unit_classes::STONE_MINE] = this->owner.get_type(220); // stone miner - } - unit->give_ability(std::make_shared(this->on_attack)); - unit->give_ability(std::make_shared(this->on_attack)); - unit->give_ability(std::make_shared(this->on_attack)); - } - else if (this->unit_data.unit_class == gamedata::unit_classes::FISHING_BOAT) { - unit->add_attribute(std::make_shared>()); - unit->add_attribute(std::make_shared>()); - - // add fishing abilites - auto &worker_attr = unit->get_attribute(); - worker_attr.capacity = 15.0; - worker_attr.gather_rate[game_resource::food] = 0.002; - - unit->give_ability(std::make_shared(this->on_attack)); - } -} - -TerrainObject *LivingProducer::place(Unit *unit, std::shared_ptr terrain, coord::phys3 init_pos) const { - return MovableProducer::place(unit, terrain, init_pos); -} - -BuildingProducer::BuildingProducer(const Player &owner, const GameSpec &spec, const gamedata::building_unit *ud) : - UnitType(owner), - unit_data{*ud}, - projectile{this->unit_data.attack_projectile_primary_unit_id}, - foundation_terrain{ud->foundation_terrain_id}, - enable_collisions{this->unit_data.id0 != 109} { // 109 = town center - - // copy the class type - this->unit_class = this->unit_data.unit_class; - this->icon = this->unit_data.icon_id; - - // find suitable sounds - int creation_sound = this->unit_data.train_sound_id; - int dying_sound = this->unit_data.dying_sound_id; - if (creation_sound == -1) { - creation_sound = this->unit_data.damage_sound_id; - } - if (creation_sound == -1) { - creation_sound = this->unit_data.selection_sound_id; - } - if (dying_sound == -1) { - dying_sound = 323; //generic explosion sound - } - on_create = spec.get_sound(creation_sound); - on_destroy = spec.get_sound(dying_sound); - - // convert the float to the discrete foundation size... - this->foundation_size = { - static_cast(this->unit_data.radius_x * 2), - static_cast(this->unit_data.radius_y * 2), - }; - - // TODO get cost, temp fixed cost of 100 wood - this->cost.set(cost_type::constant, create_resource_cost(game_resource::wood, 100)); -} - -BuildingProducer::~BuildingProducer() = default; - -int BuildingProducer::id() const { - return this->unit_data.id0; -} - -int BuildingProducer::parent_id() const { - return this->unit_data.id0; -} - -std::string BuildingProducer::name() const { - return this->unit_data.name; -} - -void BuildingProducer::initialise(Unit *unit, Player &player) { - ENSURE(this->owner == player, "unit init from a UnitType of a wrong player which breaks tech levels"); - - // log type - unit->log(MSG(dbg) << "setting unit type " << this->unit_data.id0 << " " << this->unit_data.name); - - // initialize graphic set - unit->unit_type = this; - - auto player_attr = std::make_shared>(player); - unit->add_attribute(player_attr); - - // building specific attribute - auto build_attr = std::make_shared>( - this->foundation_terrain, - this->owner.get_type(293), // fem_villager, male is 83 - unit->location->pos.draw); - build_attr->completion_state = this->enable_collisions ? object_state::placed : object_state::placed_no_collision; - unit->add_attribute(build_attr); - - // garrison and hp for all buildings - unit->add_attribute(std::make_shared>()); - unit->add_attribute(std::make_shared>(this->unit_data.hit_points)); - unit->add_attribute(std::make_shared>(this->unit_data.hit_points)); - - // population - if (this->id() == 109 || this->id() == 70) { // Town center, House - unit->add_attribute(std::make_shared>(0, 5)); - } - else if (this->id() == 82) { // Castle - unit->add_attribute(std::make_shared>(0, 20)); - } - - // limits - if (this->id() == 109 || this->id() == 276) { // Town center, Wonder - this->have_limit = 2; // TODO change to 1, 2 is for testing - } - - UnitType *proj_type = this->owner.get_type(this->projectile); - if (this->unit_data.attack_projectile_primary_unit_id > 0 && proj_type) { - coord::phys_t range_phys = this->unit_data.weapon_range_max; - unit->add_attribute(std::make_shared>(proj_type, range_phys, 350000, 1)); - // formation is used only for the attack_stance - unit->add_attribute(std::make_shared>(attack_stance::aggressive)); - unit->give_ability(std::make_shared()); - } - - // dropsite attribute - std::vector accepted_resources = this->get_accepted_resources(); - if (accepted_resources.size() != 0) { - unit->add_attribute(std::make_shared>(accepted_resources)); - } - - // building can train new units and ungarrison - unit->give_ability(std::make_shared()); - unit->give_ability(std::make_shared()); - unit->give_ability(std::make_shared()); -} - -std::vector BuildingProducer::get_accepted_resources() { - //TODO use a more general approach instead of hard coded ids - - auto id_in = [=, this](std::initializer_list ids) { - return std::any_of(ids.begin(), ids.end(), [=, this](int n) { return n == this->id(); }); - }; - - if (this->id() == 109) { // Town center - return std::vector{ - game_resource::wood, - game_resource::food, - game_resource::gold, - game_resource::stone}; - } - else if (id_in({584, 585, 586, 587})) { // Mine - return std::vector{ - game_resource::gold, - game_resource::stone}; - } - else if (id_in({68, 129, 130, 131})) { // Mill - return std::vector{ - game_resource::food}; - } - else if (id_in({562, 563, 564, 565})) { // Lumberjack camp - return std::vector{ - game_resource::wood}; - } - - return std::vector(); -} - -TerrainObject *BuildingProducer::place(Unit *u, std::shared_ptr terrain, coord::phys3 init_pos) const { - /* - * decide what terrain is passable using this lambda - * currently unit avoids water and tiles with another unit - * this function should be true if pos is a valid position of the object - */ - TerrainObject *obj_ptr = u->location.get(); - std::weak_ptr terrain_ptr = terrain; - - // find set of allowed terrains - std::unordered_set terrains = allowed_terrains(this->unit_data.terrain_restriction); - - u->location->passable = [obj_ptr, terrain_ptr, terrains](const coord::phys3 &pos) -> bool { - auto terrain = terrain_ptr.lock(); - - // look at all tiles in the bases range - for (coord::tile check_pos : tile_list(obj_ptr->get_range(pos, *terrain))) { - TileContent *tc = terrain->get_data(check_pos); - - // check if terrains are suitable and free of content - if (!tc || !terrains.count(tc->terrain_id) || tc->obj.size()) { - return false; - } - } - - return true; - }; - - // drawing function - // bool draw_outline = this->enable_collisions; - // u->location->draw = [u, obj_ptr, draw_outline](const Engine &e) { - // if (u->selected && draw_outline) { - // obj_ptr->draw_outline(e.coord); - // } - // u->draw(e); - // }; - - // try to place the obj, it knows best whether it will fit. - auto state = object_state::floating; - if (!u->location->place(terrain, init_pos, state)) { - return nullptr; - } - - // annex objects - for (unsigned i = 0; i < 4; ++i) { - const gamedata::building_annex &annex = this->unit_data.building_annex.data[i]; - if (annex.unit_id > 0) { - // make objects for annex - coord::phys3 a_pos = u->location->pos.draw; - a_pos.ne += annex.misplaced0; - a_pos.se += annex.misplaced1; - this->make_annex(*u, terrain, annex.unit_id, a_pos, i == 0); - } - } - - // TODO: play sound once built - if (this->on_create) { - this->on_create->play(); - } - return u->location.get(); -} - -TerrainObject *BuildingProducer::make_annex(Unit &u, std::shared_ptr t, int annex_id, coord::phys3 annex_pos, bool c) const { - // for use in lambda drawing functions - auto annex_type = this->owner.get_type(annex_id); - if (!annex_type) { - u.log(MSG(warn) << "Invalid annex type id " << annex_id); - return nullptr; - } - - // foundation size - coord::tile_delta annex_foundation = annex_type->foundation_size; - - // producers place by the nw tile - coord::phys3 start_tile = annex_pos; - start_tile.ne -= annex_foundation.ne / 2.0; - start_tile.se -= annex_foundation.se / 2.0; - - // create and place on terrain - TerrainObject *annex_loc = u.location->make_annex(annex_foundation); - object_state state = c ? object_state::placed : object_state::placed_no_collision; - annex_loc->place(t, start_tile, state); - - return annex_loc; -} - -ProjectileProducer::ProjectileProducer(const Player &owner, const GameSpec &spec, const gamedata::missile_unit *pd) : - UnitType(owner), - unit_data{*pd} { - // copy the class type - this->unit_class = this->unit_data.unit_class; -} - -ProjectileProducer::~ProjectileProducer() = default; - -int ProjectileProducer::id() const { - return this->unit_data.id0; -} - -int ProjectileProducer::parent_id() const { - return this->unit_data.id0; -} - -std::string ProjectileProducer::name() const { - return this->unit_data.name; -} - -void ProjectileProducer::initialise(Unit *unit, Player &player) { - ENSURE(this->owner == player, "unit init from a UnitType of a wrong player which breaks tech levels"); - - // initialize graphic set - unit->unit_type = this; - - auto player_attr = std::make_shared>(player); - unit->add_attribute(player_attr); - - // projectile speed - coord::phys_t sp = this->unit_data.speed / 666; - unit->add_attribute(std::make_shared>(sp)); - unit->add_attribute(std::make_shared>(this->unit_data.projectile_arc)); - unit->add_attribute(std::make_shared>(coord::phys3_delta{1, 0, 0})); -} - -TerrainObject *ProjectileProducer::place(Unit *u, std::shared_ptr terrain, coord::phys3 init_pos) const { - TerrainObject *obj_ptr = u->location.get(); - std::weak_ptr terrain_ptr = terrain; - u->location->passable = [obj_ptr, u, terrain_ptr](const coord::phys3 &pos) -> bool { - if (pos.up > 64000) { - return true; - } - - // avoid intersections with launcher - Unit *launcher = nullptr; - auto terrain = terrain_ptr.lock(); - if (u->has_attribute(attr_type::projectile)) { - auto &pr_attr = u->get_attribute(); - if (pr_attr.launched && pr_attr.launcher.is_valid()) { - launcher = pr_attr.launcher.get(); - } - else { - return true; - } - } - else { - return true; - } - - // look at all tiles in the bases range - for (coord::tile check_pos : tile_list(obj_ptr->get_range(pos, *terrain))) { - TileContent *tc = terrain->get_data(check_pos); - if (!tc) - return false; - - // ensure no intersections with other objects - for (auto obj_cmp : tc->obj) { - if (obj_ptr != obj_cmp && &obj_cmp->unit != launcher && obj_cmp->check_collisions() && obj_ptr->intersects(*obj_cmp, pos)) { - return false; - } - } - } - return true; - }; - - // try to place the obj, it knows best whether it will fit. - if (u->location->place(terrain, init_pos, object_state::placed_no_collision)) { - return u->location.get(); - } - return nullptr; -} - -} // namespace openage diff --git a/libopenage/unit/producer.h b/libopenage/unit/producer.h deleted file mode 100644 index 2ff837a147..0000000000 --- a/libopenage/unit/producer.h +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include - -#include "../coord/tile.h" -#include "../gamedata/gamedata_dummy.h" -#include "../gamedata/graphic_dummy.h" -#include "../gamestate/old/player.h" -#include "unit.h" -#include "unit_type.h" - -namespace openage { - -class GameMain; -class GameSpec; -class Terrain; -class TerrainObject; -class Sound; - -class UnitAbility; -class UnitAction; - - -std::unordered_set allowed_terrains(const gamedata::ground_type &restriction); - -/** - * base game data unit type - */ -class ObjectProducer : public UnitType { -public: - ObjectProducer(const Player &owner, const GameSpec &spec, const gamedata::unit_object *ud); - virtual ~ObjectProducer(); - - int id() const override; - int parent_id() const override; - std::string name() const override; - void initialise(Unit *, Player &) override; - TerrainObject *place(Unit *, std::shared_ptr, coord::phys3) const override; - -protected: - const GameSpec &dataspec; - const gamedata::unit_object unit_data; - - /** - * decaying objects have a timed lifespan - */ - bool decay; - - /** - * Sound id played when object is created or destroyed. - */ - const Sound *on_create; - const Sound *on_destroy; - int dead_unit_id; -}; - -/** - * movable unit types - */ -class MovableProducer : public ObjectProducer { -public: - MovableProducer(const Player &owner, const GameSpec &spec, const gamedata::projectile_unit *); - virtual ~MovableProducer(); - - void initialise(Unit *, Player &) override; - TerrainObject *place(Unit *, std::shared_ptr, coord::phys3) const override; - -protected: - const gamedata::projectile_unit unit_data; - const Sound *on_move; - const Sound *on_attack; - int projectile; -}; - -/** - * temporary class -- will be replaced with nyan system in future - * Stores graphics and attributes for a single unit type - * in aoe living units are derived from objects - */ -class LivingProducer : public MovableProducer { -public: - LivingProducer(const Player &owner, const GameSpec &spec, const gamedata::living_unit *); - virtual ~LivingProducer(); - - void initialise(Unit *, Player &) override; - TerrainObject *place(Unit *, std::shared_ptr, coord::phys3) const override; - -private: - const gamedata::living_unit unit_data; -}; - -/** - * Stores graphics and attributes for a building type - * Will be replaced with nyan system in future - * in aoe buildings are derived from living units - */ -class BuildingProducer : public UnitType { -public: - BuildingProducer(const Player &owner, - const GameSpec &spec, - const gamedata::building_unit *ud); - virtual ~BuildingProducer(); - - int id() const override; - int parent_id() const override; - std::string name() const override; - void initialise(Unit *, Player &) override; - TerrainObject *place(Unit *, std::shared_ptr, coord::phys3) const override; - -private: - const gamedata::building_unit unit_data; - - /** - * Sound id played when object is created or destroyed. - */ - const Sound *on_create; - const Sound *on_destroy; - int projectile; - int foundation_terrain; - std::vector get_accepted_resources(); - - /** - * used for objects like town centers or gates - * where the base does not apply collision checks - */ - bool enable_collisions; - - TerrainObject *make_annex(Unit &u, std::shared_ptr t, int annex_id, coord::phys3 annex_pos, bool c) const; -}; - -/** - * creates projectiles - * todo use MovableProducer as base class - */ -class ProjectileProducer : public UnitType { -public: - ProjectileProducer(const Player &owner, const GameSpec &spec, const gamedata::missile_unit *); - virtual ~ProjectileProducer(); - - int id() const override; - int parent_id() const override; - std::string name() const override; - void initialise(Unit *, Player &) override; - TerrainObject *place(Unit *, std::shared_ptr, coord::phys3) const override; - -private: - const gamedata::missile_unit unit_data; -}; - -} // namespace openage diff --git a/libopenage/unit/research.cpp b/libopenage/unit/research.cpp deleted file mode 100644 index 7161565583..0000000000 --- a/libopenage/unit/research.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2017-2018 the openage authors. See copying.md for legal info. - -#include "../gamestate/old/player.h" -#include "research.h" - - -namespace openage { - -ResearchType::ResearchType(Player &owner) - : - owner{owner} { -} - -std::shared_ptr ResearchType::initialise() const { - return std::make_shared(this); -} - -Research::Research(const ResearchType *type) - : - type{type}, - active_count{0}, - completed_count{0} { -} - -void Research::started() { - this->active_count += 1; -} - -void Research::stopped() { - this->active_count -= 1; -} - -void Research::completed() { - this->active_count -= 1; - this->completed_count += 1; -} - -bool Research::can_start() const { - return this->active_count + this->completed_count < this->type->get_max_repeats(); -} - -bool Research::is_active() const { - return this->active_count > 0; -} - -bool Research::is_researched() const { - return this->completed_count == this->type->get_max_repeats(); -} - -void Research::apply() { - // apply the patch - this->type->apply(); - - // perform category based actions - if (type->category() == research_category::age_advance) { - type->owner.advance_age(); - - } else if (type->category() == research_category::generic) { - // TODO implement a way to handle this category - } -} - -} // namespace openage diff --git a/libopenage/unit/research.h b/libopenage/unit/research.h deleted file mode 100644 index edd73ee8ed..0000000000 --- a/libopenage/unit/research.h +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright 2017-2017 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - - -namespace openage { - -class Player; -class Research; -class ResourceCost; - -enum class research_category : int { - /** - * Research which modify unit type data. - */ - unit_upgrade, - /** - * Research which modify unit type data and also progresses the next age. - * Separate category for simplification. - */ - age_advance, - /** - * Research which modify unit type data and something else. - * (eg. see enemy line of sight) - */ - generic, - RESEARCH_CATEGORY_COUNT -}; - -/** - * Describes a research for a single player - * - * The get_max_repeats (with a default value of 1) can allow for a research to be - * performed multiple types - */ -class ResearchType { -public: - - ResearchType(Player &owner); - - /** - * Gets the unique id of this research type. - */ - virtual int id() const = 0; - - /** - * Gets the name of the research. - */ - virtual std::string name() const = 0; - - /** - * Gets the research category of the research. - */ - virtual research_category category() const = 0; - - /** - * Creates a single Research object. - * Must be called only once. - */ - std::shared_ptr initialise() const; - - /** - * The player who owns this research type - */ - Player &owner; - - /** - * How many times it can be researched. - * All classic researches have a value of 1. - */ - int get_max_repeats() const { return 1; } - - virtual unsigned int get_research_time() const = 0; - - virtual ResourceCost get_research_cost() const = 0; - - /** - * Performs the modifications (eg. apply patch to the unit types) - */ - virtual void apply() const = 0; - -protected: - -private: - -}; - -class NyanResearchType : public ResearchType { - // TODO POST-NYAN Implement - - NyanResearchType(Player &owner); - -}; - -/** - * At most one Research must exist for each ResearchType. - * - * A research represents how many times the research type has been completed (completed count) - * and also how many unit are researching it now (active count). - */ -class Research { -public: - - Research(const ResearchType *type); - - const ResearchType *type; - - /** - * Called when a unit started researching this research. - */ - void started(); - - /** - * Called when a unit stopped researching this research before completing it. - */ - void stopped(); - - /** - * Called when a unit completed researching this research. - */ - void completed(); - - /** - * Returns true if a unit can start researching this research. - */ - bool can_start() const; - - /** - * Returns true if any unit is researching this research. - */ - bool is_active() const; - - /** - * Returns true if it has nothing more to offer (reached max repeats). - */ - bool is_researched() const; - - /** - * Apply the modifications to the owner player. - */ - void apply(); - -protected: - - /** - * The number of units that are researching this research - */ - int active_count; - - /** - * The number of times this research has been completed - */ - int completed_count; - -private: - -}; - -} // namespace openage diff --git a/libopenage/unit/selection.cpp b/libopenage/unit/selection.cpp deleted file mode 100644 index 354bf8f5ba..0000000000 --- a/libopenage/unit/selection.cpp +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "selection.h" - -#include -#include - -#include "../coord/tile.h" -#include "../log/log.h" -#include "../terrain/terrain.h" -#include "action.h" -#include "command.h" -#include "producer.h" -#include "unit.h" - - -namespace openage { - -UnitSelection::UnitSelection() : - selection_type{selection_type_t::nothing}, - drag_active{false} { -} - -// bool UnitSelection::on_drawhud() { -// // the drag selection box -// if (drag_active) { -// coord::viewport s = this->start.to_viewport(this->engine->coord); -// coord::viewport e = this->end.to_viewport(this->engine->coord); -// glLineWidth(1); -// glColor3f(1.0, 1.0, 1.0); -// glBegin(GL_LINE_LOOP); { -// glVertex3f(s.x, s.y, 0); -// glVertex3f(e.x, s.y, 0); -// glVertex3f(e.x, e.y, 0); -// glVertex3f(s.x, e.y, 0); -// } -// glEnd(); -// } -// -// // draw hp bars for each selected unit -// glLineWidth(3); -// for (auto u : this->units) { -// if (u.second.is_valid()) { -// Unit *unit_ptr = u.second.get(); -// if (unit_ptr->location && -// unit_ptr->has_attribute(attr_type::hitpoints) && -// unit_ptr->has_attribute(attr_type::damaged)) { -// -// auto &hp = unit_ptr->get_attribute(); -// auto &dm = unit_ptr->get_attribute(); -// float percent = static_cast(dm.hp) / static_cast(hp.hp); -// int mid = percent * 28.0f - 14.0f; -// -// coord::phys3 &pos_phys3 = unit_ptr->location->pos.draw; -// auto pos = pos_phys3.to_viewport(this->engine->coord); -// // green part -// glColor3f(0.0, 1.0, 0.0); -// glBegin(GL_LINES); { -// glVertex3f(pos.x - 14, pos.y + 60, 0); -// glVertex3f(pos.x + mid, pos.y + 60, 0); -// } -// glEnd(); -// -// // red part -// glColor3f(1.0, 0.0, 0.0); -// glBegin(GL_LINES); { -// glVertex3f(pos.x + mid, pos.y + 60, 0); -// glVertex3f(pos.x + 14, pos.y + 60, 0); -// } -// glEnd(); -// } -// } -// } -// glColor3f(1.0, 1.0, 1.0); // reset - -// ui graphics 3404 and 3405 -// return true; -// } - -void UnitSelection::drag_begin(coord::camgame pos) { - this->start = pos; - this->end = pos; - this->drag_active = true; -} - -// called as the entry point for the selection -// from ActionMode. -void UnitSelection::drag_update(coord::camgame pos) { - if (!this->drag_active) { - this->drag_begin(pos); - } - this->end = pos; -} - -void UnitSelection::drag_release(const Player &player, Terrain *terrain, bool append) { - if (this->start == this->end) { - this->select_point(player, terrain, this->start, append); - } - else { - this->select_space(player, terrain, this->start, this->end, append); - } - this->drag_active = false; -} - -void UnitSelection::clear() { - for (auto u : this->units) { - if (u.second.is_valid()) { - u.second.get()->selected = false; - } - } - this->units.clear(); - this->selection_type = selection_type_t::nothing; -} - -void UnitSelection::toggle_unit(const Player &player, Unit *u, bool append) { - if (this->units.count(u->id) == 0) { - this->add_unit(player, u, append); - } - else { - this->remove_unit(u); - } -} - -void UnitSelection::add_unit(const Player &player, Unit *u, bool append) { - // Only select resources and units with hitpoints > 0 - if (u->has_attribute(attr_type::resource) || (u->has_attribute(attr_type::damaged) && u->get_attribute().hp > 0)) { - selection_type_t unit_type = get_unit_selection_type(player, u); - int unit_type_i = static_cast(unit_type); - int selection_type_i = static_cast(this->selection_type); - - if (unit_type_i > selection_type_i) { - // Don't select this unit as it has too low priority - return; - } - - if (unit_type_i < selection_type_i) { - // Upgrade selection to a higher priority selection - this->clear(); - this->selection_type = unit_type; - } - - // Can't select multiple enemies at once - if (not(unit_type == selection_type_t::own_units || (unit_type == selection_type_t::own_buildings && append))) { - this->clear(); - this->selection_type = unit_type; // Clear resets selection_type - } - - // Finally, add the unit to the selection - u->selected = true; - this->units[u->id] = u->get_ref(); - } -} - -void UnitSelection::remove_unit(Unit *u) { - u->selected = false; - this->units.erase(u->id); - - if (this->units.empty()) { - this->selection_type = selection_type_t::nothing; - } -} - -selection_type_t UnitSelection::get_selection_type() { - return this->selection_type; -} - -void UnitSelection::kill_unit(const Player &player) { - if (this->units.empty()) { - return; - } - - UnitReference &ref = this->units.begin()->second; - if (!ref.is_valid()) { - this->units.erase(this->units.begin()); - - if (this->units.empty()) { - this->selection_type = selection_type_t::nothing; - } - } - else { - Unit *u = ref.get(); - - // Check color: you can only kill your own units - if (u->is_own_unit(player)) { - this->remove_unit(u); - u->delete_unit(); - } - } -} - -bool UnitSelection::contains_builders(const Player &player) { - for (auto &it : units) { - if (it.second.is_valid() && it.second.get()->get_ability(ability_type::build) && it.second.get()->is_own_unit(player)) { - return true; - } - } - return false; -} - -bool UnitSelection::contains_military(const Player &player) { - for (auto &it : units) { - if (it.second.is_valid() && !it.second.get()->get_ability(ability_type::build) && it.second.get()->is_own_unit(player)) { - return true; - } - } - return false; -} - -void UnitSelection::select_point(const Player &player, Terrain *terrain, coord::camgame point, bool append) { - //if (!append) { - // this->clear(); - //} - // - //if (!terrain) { - // log::log(MSG(warn) << "selection terrain not specified"); - // return; - //} - // - //// find any object at selected point - //auto obj = terrain->obj_at_point(point.to_phys3(this->engine->coord)); - //if (obj) { - // this->toggle_unit(player, &obj->unit); - //} -} - -void UnitSelection::select_space(const Player &player, Terrain *terrain, coord::camgame point0, coord::camgame point1, bool append) { - if (!append) { - this->clear(); - } - - coord::camgame min{std::min(point0.x, point1.x), std::min(point0.y, point1.y)}; - coord::camgame max{std::max(point0.x, point1.x), std::max(point0.y, point1.y)}; - - // look at each tile in the range and find all units - //for (coord::tile check_pos : tiles_in_range(point0, point1, this->engine->coord)) { - // TileContent *tc = terrain->get_data(check_pos); - // if (tc) { - // // find objects within selection box - // for (auto unit_location : tc->obj) { - // coord::camgame pos = unit_location->pos.draw.to_camgame(this->engine->coord); - // - // if ((pos.x > min.x and pos.x < max.x) and (pos.y > min.y and pos.y < max.y)) { - // this->add_unit(player, &unit_location->unit, append); - // } - // } - // } - //} -} - -void UnitSelection::all_invoke(Command &cmd) { - for (auto u : this->units) { - if (u.second.is_valid() && u.second.get()->is_own_unit(cmd.player)) { - // allow unit to find best use of the command - // TODO: queue_cmd returns ability which allows playing of sound - u.second.get()->queue_cmd(cmd); - } - } -} - -selection_type_t UnitSelection::get_unit_selection_type(const Player &player, Unit *u) { - bool is_building = u->has_attribute(attr_type::building); - - // Check owner - // TODO implement allied units - if (u->is_own_unit(player)) { - return is_building ? selection_type_t::own_buildings : selection_type_t::own_units; - } - else { - return is_building ? selection_type_t::enemy_building : selection_type_t::enemy_unit; - } -} - -std::vector tiles_in_range(coord::camgame p1, coord::camgame p2, const coord::CoordManager &coord) { - // the remaining corners - coord::camgame p3 = coord::camgame{p1.x, p2.y}; - coord::camgame p4 = coord::camgame{p2.x, p1.y}; - coord::camgame pts[4]{p1, p2, p3, p4}; - - // find the range of tiles covered - coord::tile t1 = pts[0].to_tile(coord); - coord::tile min = t1; - coord::tile max = t1; - - for (unsigned i = 1; i < 4; ++i) { - coord::tile t = pts[i].to_tile(coord); - min.ne = std::min(min.ne, t.ne); - min.se = std::min(min.se, t.se); - max.ne = std::max(max.ne, t.ne); - max.se = std::max(max.se, t.se); - } - - // find all units in the boxed region - std::vector tiles; - coord::tile check_pos = min; - while (check_pos.ne <= max.ne) { - while (check_pos.se <= max.se) { - tiles.push_back(check_pos); - check_pos.se += 1; - } - check_pos.se = min.se; - check_pos.ne += 1; - } - return tiles; -} - -} // namespace openage diff --git a/libopenage/unit/selection.h b/libopenage/unit/selection.h deleted file mode 100644 index f82fc02bea..0000000000 --- a/libopenage/unit/selection.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "../coord/pixel.h" -#include "ability.h" -#include "unit_container.h" - -namespace openage { -class Terrain; - -std::vector tiles_in_range(coord::camgame p1, coord::camgame p2, const coord::CoordManager &coord); - -/** - * A selection of units always has a type - * You can't select units from multiple types at once - * Earlier types have precedence over later types - * - * So you can select a group of units, or a building (or multiple if append is on) - * Enemy units, enemy buildings and other objects may only be selected one at a time - */ -enum class selection_type_t { - own_units, - own_buildings, - enemy_unit, - enemy_building, - nothing -}; - -/** - * a user interface component allowing control of a selected group - */ -class UnitSelection { -public: - UnitSelection(/* LegacyEngine *engine */); - - // bool on_drawhud() override; - void drag_begin(coord::camgame pos); - void drag_update(coord::camgame pos); - void drag_release(const Player &player, Terrain *terrain, bool append = false); - - void clear(); - - void toggle_unit(const Player &player, Unit *u, bool append = false); - void add_unit(const Player &player, Unit *u, bool append = false); - void remove_unit(Unit *u); - - selection_type_t get_selection_type(); - - /** - * kill a single unit in the selection - */ - void kill_unit(const Player &player); - - /** - * checks whether there are any builders in the selection - */ - bool contains_builders(const Player &player); - - /** - * checks whether there are any military units (i.e. non-builders) in the selection - */ - bool contains_military(const Player &player); - - /** - * point unit selection - */ - void select_point(const Player &player, Terrain *terrain, coord::camgame p, bool append = false); - - /** - * boxed unit selection - */ - void select_space(const Player &player, Terrain *terrain, coord::camgame p1, coord::camgame p2, bool append = false); - - /** - * uses command on every selected unit - */ - void all_invoke(Command &cmd); - - int get_units_count() const { - return this->units.size(); - } - - const UnitReference &get_first_unit() const { - return this->units.begin()->second; - } - -private: - /** - * Check whether the currently selected units may be selected at the same time - * If not, deselect some units - * This is the order in which the checks occur: - * Own units > own building(s) > enemy unit > enemy building > any object - * - * So you can select a group of units, or a building (or multiple if append is on) - * Enemy units, enemy buildings and other objects may only be selected one at a time - */ - selection_type_t get_unit_selection_type(const Player &player, Unit *); - - std::unordered_map units; - selection_type_t selection_type; - - bool drag_active; - // TODO: turn these into a C++17 optional - coord::camgame start = {0, 0}, end = {0, 0}; - - /** - * Engine where this selection is attached to. - */ - // LegacyEngine *engine; -}; - -} // namespace openage diff --git a/libopenage/unit/type_pair.cpp b/libopenage/unit/type_pair.cpp deleted file mode 100644 index 725f63c072..0000000000 --- a/libopenage/unit/type_pair.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#include "type_pair.h" - -namespace openage { - -UnitType::UnitType() {} - -bool UnitType::match(Unit *) { - // TODO: types - return true; -} - -TypePair::TypePair() {} - -} // namespace openage diff --git a/libopenage/unit/type_pair.h b/libopenage/unit/type_pair.h deleted file mode 100644 index 7b96cd45bd..0000000000 --- a/libopenage/unit/type_pair.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -namespace openage { - -/** - * units in aoc have a class and a type - */ -class UnitType { -public: - UnitType(); - - /** - * the unit must have either same class or id as this - */ - bool match(class Unit *); - -private: - unsigned int class_id; - unsigned int unit_type_id; -}; - -/** - * many effects in aoc use a pair structure - * such as attack bonuses, armour and selection commands - */ -class TypePair { -public: - TypePair(); - -private: - UnitType a, b; - -}; - -} // namespace openage diff --git a/libopenage/unit/unit.cpp b/libopenage/unit/unit.cpp deleted file mode 100644 index bccd729a8e..0000000000 --- a/libopenage/unit/unit.cpp +++ /dev/null @@ -1,260 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#include -#include -#include - -#include "../terrain/terrain.h" - -#include "ability.h" -#include "action.h" -#include "command.h" -#include "producer.h" -#include "unit.h" - - -namespace openage { - -Unit::Unit(UnitContainer *c, id_t id) : - id{id}, - unit_type{nullptr}, - selected{false}, - pop_destructables{false}, - container(c) {} - -Unit::~Unit() { - // remove any used location from the map - if (this->location) { - this->location->remove(); - } -} - -void Unit::reset() { - this->ability_available.clear(); - this->action_stack.clear(); - this->pop_destructables = false; -} - -bool Unit::has_action() const { - return !this->action_stack.empty(); -} - -bool Unit::accept_commands() const { - return (this->has_action() && this->top()->allow_control()); -} - -bool Unit::is_own_unit(const Player &player) { - return player.owns(*this); -} - -UnitAction *Unit::top() const { - if (this->action_stack.empty()) { - throw Error{MSG(err) << "Unit stack empty - no top action exists"}; - } - return this->action_stack.back().get(); -} - -UnitAction *Unit::before(const UnitAction *action) const { - auto start = std::find_if( - std::begin(this->action_stack), - std::end(this->action_stack), - [action](const std::unique_ptr &a) { - return action == a.get(); - }); - - if (start != std::begin(this->action_stack) && start != std::end(this->action_stack)) { - return (*(start - 1)).get(); - } - return nullptr; -} - -bool Unit::update(time_nsec_t lastframe_duration) { - // if unit is not on the map then do nothing - if (!this->location) { - return true; - } - - // unit is dead (not player controlled) - if (this->pop_destructables) { - this->erase_after( - [](std::unique_ptr &e) { - return e->allow_interrupt() || e->allow_control(); - }, - false); - } - - /* - * the active action is on top - */ - if (this->has_action()) { - // TODO: change the entire unit action timing - // to a higher resolution like nsecs or usecs. - - // time as float, in milliseconds. - auto time_elapsed = lastframe_duration / 1e6; - - this->top()->update(time_elapsed); - - // the top primary action specifies whether - // secondary actions are updated - if (this->top()->allow_control()) { - this->update_secondary(time_elapsed); - } - - // check completion of all primary actions, - // pop completed actions and anything above - this->erase_after( - [](std::unique_ptr &e) { - return e->completed(); - }); - } - - // apply new queued commands - this->apply_all_cmds(); - - return true; -} - -void Unit::update_secondary(int64_t time_elapsed) { - // update secondary actions and remove when completed - auto position_it = std::remove_if( - std::begin(this->action_secondary), - std::end(this->action_secondary), - [time_elapsed](std::unique_ptr &action) { - action->update(time_elapsed); - return action->completed(); - }); - this->action_secondary.erase(position_it, std::end(this->action_secondary)); -} - -void Unit::apply_all_cmds() { - std::lock_guard lock(this->command_queue_lock); - while (!this->command_queue.empty()) { - auto &action = this->command_queue.front(); - this->apply_cmd(action.first, action.second); - this->command_queue.pop(); - } -} - - -void Unit::apply_cmd(std::shared_ptr ability, const Command &cmd) { - // if the interrupt flag is set, discard ongoing actions - bool is_direct = cmd.has_flag(command_flag::interrupt); - if (is_direct) { - this->stop_actions(); - } - if (ability->can_invoke(*this, cmd)) { - ability->invoke(*this, cmd, is_direct); - } -} - -void Unit::give_ability(std::shared_ptr ability) { - this->ability_available.emplace(std::make_pair(ability->type(), ability)); -} - -UnitAbility *Unit::get_ability(ability_type type) { - if (this->ability_available.count(type) > 0) { - return this->ability_available[type].get(); - } - return nullptr; -} - -void Unit::push_action(std::unique_ptr action, bool force) { - // unit not being deleted -- can control unit - if (force || this->accept_commands()) { - this->action_stack.push_back(std::move(action)); - } -} - -void Unit::secondary_action(std::unique_ptr action) { - this->action_secondary.push_back(std::move(action)); -} - -void Unit::add_attribute(std::shared_ptr attr) { - this->attributes.add(attr); -} - -void Unit::add_attributes(const Attributes &attr) { - this->attributes.add_copies(attr); -} - -void Unit::add_attributes(const Attributes &attr, bool shared, bool unshared) { - this->attributes.add_copies(attr, shared, unshared); -} - -bool Unit::has_attribute(attr_type type) const { - return this->attributes.has(type); -} - -std::shared_ptr Unit::queue_cmd(const Command &cmd) { - std::lock_guard lock(this->command_queue_lock); - - // following the specified ability priority - // find suitable ability for this target if available - for (auto &ability : ability_priority) { - auto pair = this->ability_available.find(ability); - if (pair != this->ability_available.end() && cmd.ability()[static_cast(pair->first)] && pair->second->can_invoke(*this, cmd)) { - command_queue.push(std::make_pair(pair->second, cmd)); - return pair->second; - } - } - return nullptr; -} - -void Unit::delete_unit() { - this->pop_destructables = true; -} - -void Unit::stop_gather() { - this->erase_after( - [](std::unique_ptr &e) { - return e->name() == "gather"; - }, - false); -} - -void Unit::stop_actions() { - // work around for workers continuing to work after retasking - if (this->has_attribute(attr_type::worker)) { - this->stop_gather(); - } - - // discard all interruptible tasks - this->erase_after( - [](std::unique_ptr &e) { - return e->allow_interrupt(); - }); -} - -UnitReference Unit::get_ref() { - return UnitReference(this->container, id, this); -} - -UnitContainer *Unit::get_container() const { - return this->container; -} - -std::string Unit::logsource_name() { - return "Unit " + std::to_string(this->id); -} - -void Unit::erase_after(std::function &)> func, bool run_completed) { - auto position_it = std::find_if( - std::begin(this->action_stack), - std::end(this->action_stack), - func); - - if (position_it != std::end(this->action_stack)) { - auto completed_action = std::move(*position_it); - - // erase from the stack - this->action_stack.erase(position_it, std::end(this->action_stack)); - - // perform any completion actions - if (run_completed) { - completed_action->on_completion(); - } - } -} - -} // namespace openage diff --git a/libopenage/unit/unit.h b/libopenage/unit/unit.h deleted file mode 100644 index d832c26d19..0000000000 --- a/libopenage/unit/unit.h +++ /dev/null @@ -1,304 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include -#include -#include - -#include "../coord/phys.h" -#include "../log/logsource.h" -#include "../terrain/terrain_object.h" -#include "../util/timing.h" -#include "ability.h" -#include "attribute.h" -#include "attributes.h" -#include "command.h" -#include "unit_container.h" - - -namespace openage { - -class UnitAbility; -class UnitAction; - -/** - * A game object with current state represented by a stack of actions - * since this class represents both unit and building objects it may be better to - * name as GameObject - * - * it is possible that abilities are not required here and they could be moved - * to selection controller -- units only need the attributes - */ -class Unit : public log::LogSource { -public: - Unit(UnitContainer *c, id_t id); - - /** - * unit cleanup will delete terrain object - */ - virtual ~Unit(); - - /** - * this units unique id value - */ - const id_t id; - - /** - * type of this object, this is set by the the UnitType which - * was most recently applied to this unit - */ - const UnitType *unit_type; - - /** - * should selection features be drawn - * TODO: should be a pointer to selection to be updated - * when unit is removed, or null if not selected - */ - bool selected; - - /** - * space on the map used by this unit - * null if the object is not yet placed or garrisoned - * TODO: make private field - */ - std::unique_ptr location; - - /** - * constructs a new location for this unit replacing any - * existing locatio - * - * uses same args as the location constructor - * except the first which will filled automatically - */ - template - void make_location(Arg... args) { - // remove any existing location first - if (this->location) { - this->location->remove(); - } - - // since Unit is a friend of the location - // make_shared will not work - this->location = std::unique_ptr(new T(*this, args...)); - } - - /** - * removes all actions and abilities - * current attributes are kept - */ - void reset(); - - /** - * checks the entity has an action, if it has no action it should be removed from the game - * @return true if the entity currently has an action - */ - bool has_action() const; - - /** - * true when the unit is alive and able to add new actions - */ - bool accept_commands() const; - - /** - * checks whether the current player is the owner of this unit - */ - bool is_own_unit(const Player &player); - - /** - * returns the current action on top of the stack - */ - UnitAction *top() const; - - /** - * returns action under the passed action in the stack - * returns null if stack size is less than 2 - */ - UnitAction *before(const UnitAction *action) const; - - /** - * update this object using the action currently on top of the stack - */ - bool update(time_nsec_t lastframe_duration); - - /** - * adds an available ability to this unit - * this turns targeted objects into actions which are pushed - * onto the stack, eg. targeting a relic may push a collect relic action - */ - void give_ability(std::shared_ptr); - - /** - * get ability with specified type, null if not available - * - * To invoke commands use the invoke function instead - */ - UnitAbility *get_ability(ability_type type); - - /** - * adds a new action on top of the action stack - * will be performed immediately - */ - void push_action(std::unique_ptr action, bool force = false); - - /** - * adds a secondary action which is always updated - */ - void secondary_action(std::unique_ptr action); - - /** - * give a new attribute this this unit - * this is used to set things like color, hitpoints and speed - */ - void add_attribute(std::shared_ptr attr); - - /** - * Give new attributes to this unit. - * This is used to add the default attributes - */ - void add_attributes(const Attributes &attr); - - /** - * Give new attributes to this unit. - * If shared is false, shared attributes are ignored. - * If unshared is false, unshared attributes are ignored. - */ - void add_attributes(const Attributes &attr, bool shared, bool unshared); - - /** - * returns whether attribute is available - */ - bool has_attribute(attr_type type) const; - - /** - * returns attribute based on templated value - */ - template - Attribute &get_attribute() { - return *reinterpret_cast *>(attributes.get(T).get()); - // TODO change to (templates errors) - //return attributes.get(); - } - - /** - * queues a command to be applied to this unit on the next update - * - * @return the ability which will apply the command if an action was created - * otherwise nullptr is returned when no ability can handle the command - */ - std::shared_ptr queue_cmd(const Command &cmd); - - /** - * removes all gather actions without calling their on_complete actions - * this cancels the gathering action completely - */ - void stop_gather(); - - /** - * removes all actions above and including the first interuptable action - * this will stop any of the units current moving or attacking actions - * a direct command from the user will invoke this function - */ - void stop_actions(); - - /** - * begins unit removal by popping some actions - * - * this is the action that occurs when pressing the delete key - * which plays death sequence and does not remove instantly - */ - void delete_unit(); - - /** - * get a reference which can check against the container - * to ensure this object still exists - */ - UnitReference get_ref(); - - /** - * the container used when constructing this unit - */ - UnitContainer *get_container() const; - - /** - * Returns the unit's name as the LogSource name. - */ - std::string logsource_name() override; - - /** - * Unit attributes include color, hitpoints, speed, objects garrisoned etc - * contains 0 or 1 values for each type - */ - Attributes attributes; - -private: - /** - * ability available -- actions that this entity - * can perform when controlled - */ - std::unordered_map> ability_available; - - - /** - * action stack -- top action determines graphic to be drawn - */ - std::vector> action_stack; - - - /** - * secondary actions are always updated - */ - std::vector> action_secondary; - - - /** - * queue commands to be applied on the next update - */ - std::queue, const Command>> command_queue; - - /** - * mutex controlling updates to the command queue - */ - std::mutex command_queue_lock; - - - /** - * pop any destructable actions on the next update cycle - * and prevent additional actions being added - */ - bool pop_destructables; - - /** - * the container that updates this unit - */ - UnitContainer *container; - - /** - * applies new commands as part of the units update process - */ - void apply_all_cmds(); - - /** - * applies one command using a chosen ability - * locks the command queue mutex while operating - */ - void apply_cmd(std::shared_ptr ability, const Command &cmd); - - /** - * update all secondary actions - */ - void update_secondary(int64_t time_elapsed); - - /** - * erase from action specified by func to the end of the stack - * all actions erased will have the on_complete function called - * - * @param run_completed usually each action has an on_complete() function called when it is removed - * but when run_completed is false this on_complete() function is not called for all popped actions - */ - void erase_after(std::function &)> func, bool run_completed = true); -}; - -} // namespace openage diff --git a/libopenage/unit/unit_container.cpp b/libopenage/unit/unit_container.cpp deleted file mode 100644 index 672fedacd9..0000000000 --- a/libopenage/unit/unit_container.cpp +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2014-2019 the openage authors. See copying.md for legal info. - -#include "unit_container.h" - -#include - -#include "../log/log.h" -#include "../terrain/terrain_object.h" -#include "producer.h" -#include "unit.h" - - -namespace openage { - -reference_data::reference_data(const UnitContainer *c, id_t id, Unit *u) - : - container{c}, - unit_id{id}, - unit_ptr{u} { - if (!u) { - throw Error{MSG(err) << "Cannot reference null unit pointer"}; - } -} - - -UnitReference::UnitReference() - : - data{nullptr} {} - - -UnitReference::UnitReference(const UnitContainer *c, id_t id, Unit *u) - : - data{std::make_shared(c, id, u)} {} - - -bool UnitReference::is_valid() const { - return this->data && - this->data->container->valid_id(this->data->unit_id); -} - - -Unit *UnitReference::get() const { - if (!this->is_valid()) { - throw Error{MSG(err) << "Unit reference is no longer valid"}; - } - return this->data->unit_ptr; -} - - -UnitContainer::UnitContainer() - : - next_new_id{1} {} - - -UnitContainer::~UnitContainer() = default; - - -void UnitContainer::reset() { - this->live_units.clear(); -} - -void UnitContainer::set_terrain(std::shared_ptr &t) { - this->terrain = t; -} - -std::shared_ptr UnitContainer::get_terrain() const { - if (this->terrain.expired()) { - throw Error{MSG(err) << "Terrain has expired"}; - } - return this->terrain.lock(); -} - - -bool UnitContainer::valid_id(id_t id) const { - return (this->live_units.count(id) > 0); -} - - -UnitReference UnitContainer::get_unit(id_t id) { - if (this->valid_id(id)) { - return UnitReference(this, id, this->live_units[id].get()); - } - else { - return UnitReference(this, id, nullptr); - } -} - -UnitReference UnitContainer::new_unit() { - auto id = next_new_id; - next_new_id += 1; - - this->live_units.emplace(id, std::make_unique(this, id)); - return this->live_units[id]->get_ref(); -} - -UnitReference UnitContainer::new_unit(UnitType &type, - Player &owner, - coord::phys3 position) { - - auto new_id = next_new_id; - next_new_id += 1; - - auto newobj = std::make_unique(this, new_id); - - // try placing unit at this location - auto terrain_shared = this->get_terrain(); - auto placed = type.place(newobj.get(), terrain_shared, position); - if (placed) { - type.initialise(newobj.get(), owner); - owner.active_unit_added(newobj.get()); // TODO change, move elsewhere - auto id = newobj->id; - this->live_units.emplace(id, std::move(newobj)); - return this->live_units[id]->get_ref(); - } - return UnitReference(); // is not valid -} - -UnitReference UnitContainer::new_unit(UnitType &type, - Player &owner, - TerrainObject *other) { - auto new_id = next_new_id; - next_new_id += 1; - - auto newobj = std::make_unique(this, new_id); - - // try placing unit - TerrainObject *placed = type.place_beside(newobj.get(), other); - if (placed) { - type.initialise(newobj.get(), owner); - owner.active_unit_added(newobj.get()); // TODO change, move elsewhere - auto id = newobj->id; - this->live_units.emplace(id, std::move(newobj)); - return this->live_units[id]->get_ref(); - } - return UnitReference(); // is not valid -} - - -bool dispatch_command(id_t, const Command &) { - return true; -} - -bool UnitContainer::update_all(time_nsec_t lastframe_duration) { - // update everything and find objects with no actions - std::vector to_remove; - - for (auto &obj : this->live_units) { - obj.second->update(lastframe_duration); - - if (not obj.second->has_action()) { - to_remove.push_back(obj.first); - } - } - - // cleanup and removal of objects - for (auto &obj : to_remove) { - - // unique pointer triggers cleanup - this->live_units.erase(obj); - } - return true; -} - -std::vector UnitContainer::all_units() { - std::vector result; - for (auto &u : this->live_units) { - result.push_back(u.second.get()); - } - return result; -} - -} // namespace openage diff --git a/libopenage/unit/unit_container.h b/libopenage/unit/unit_container.h deleted file mode 100644 index 8627c8582f..0000000000 --- a/libopenage/unit/unit_container.h +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright 2014-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include - -#include "../coord/tile.h" -#include "../util/timing.h" - - -namespace openage { - -class Command; -class Player; -class Terrain; -class TerrainObject; -class Unit; -class UnitContainer; -class UnitType; - - -/** - * Type used to identify each single unit in the game. - */ -using id_t = unsigned long int; - - -/** - * immutable reference data - */ -struct reference_data { - reference_data(const UnitContainer *c, id_t id, Unit *); - - const UnitContainer *const container; - const id_t unit_id; - Unit *const unit_ptr; -}; - -/** - * Reference to a single unit, which may have been removed - * from the game, check is_valid() before calling get() - */ -class UnitReference { -public: - /** - * create an invalid reference - */ - UnitReference(); - - /** - * create referece by unit id - */ - UnitReference(const UnitContainer *c, id_t id, Unit *); - - bool is_valid() const; - Unit *get() const; - -private: - /** - * The default copy constructor and assignment - * will just copy the shared pointer - */ - std::shared_ptr data; -}; - -/** - * the list of units that are currently in use - * will also give a view of the current game state for networking in later milestones - */ -class UnitContainer { -public: - UnitContainer(); - ~UnitContainer(); - - void reset(); - - /** - * sets terrain to initialise units on - */ - void set_terrain(std::shared_ptr &t); - - /** - * returns the terrain which units are placed on - */ - std::shared_ptr get_terrain() const; - - /** - * checks the id is valid - */ - bool valid_id(id_t id) const; - - /** - * returns a reference to a unit - */ - UnitReference get_unit(id_t id); - - /** - * creates a new unit without initialising - */ - UnitReference new_unit(); - - /** - * adds a new unit to the container and initialises using a unit type - */ - UnitReference new_unit(UnitType &type, Player &owner, coord::phys3 position); - - /** - * adds a new unit to the container and initialises using a unit type - * places outside an existing object using the player of that object - */ - UnitReference new_unit(UnitType &type, Player &owner, TerrainObject *other); - - /** - * give a command to a unit -- unit creation and deletion should be done as commands - */ - bool dispatch_command(id_t to_id, const Command &cmd); - - /** - * update dispatched by the game engine on each physics tick. - * this will update all game objects. - */ - bool update_all(time_nsec_t lastframe_duration); - - /** - * gets a list of all units in the container - */ - std::vector all_units(); - -private: - id_t next_new_id; - - /** - * mapping unit ids to unit objects - */ - std::unordered_map> live_units; - - /** - * Terrain for initialising new units - */ - std::weak_ptr terrain; -}; - -} // namespace openage diff --git a/libopenage/unit/unit_type.cpp b/libopenage/unit/unit_type.cpp deleted file mode 100644 index 80677ebc75..0000000000 --- a/libopenage/unit/unit_type.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "unit.h" -#include "../gamestate/old/player.h" -#include "../terrain/terrain_object.h" -#include "../util/math_constants.h" -#include "action.h" -#include "unit_container.h" -#include "unit_type.h" - -#include - -namespace openage { - -UnitTypeMeta::UnitTypeMeta(std::string name, int id, init_func f) : - init{f}, - type_name{std::move(name)}, - type_id{id} { -} - -std::string UnitTypeMeta::name() const { - return this->type_name; -} - -int UnitTypeMeta::id() const { - return this->type_id; -} - -UnitType::UnitType(const Player &owner) : - owner{owner}, - have_limit{math::INT_INF}, - had_limit{math::INT_INF} { -} - -void UnitType::reinitialise(Unit *unit, Player &player) { - // In case reinitialise is not implemented separately - - Attributes tmp; - // copy only unshared - tmp.add_copies(unit->attributes, false, true); - // initialise the new unit - this->initialise(unit, player); - // replace new unshared attributes with the old - unit->attributes.add_copies(tmp); -} - -bool UnitType::operator==(const UnitType &other) const { - return this->type_abilities == other.type_abilities; -} - -bool UnitType::operator!=(const UnitType &other) const { - return !(*this == other); -} - -TerrainObject *UnitType::place_beside(Unit *u, TerrainObject const *other) const { - if (!u || !other) { - return nullptr; - } - - // find the range of possible tiles - tile_range outline{other->pos.start - coord::tile_delta{1, 1}, - other->pos.end + coord::tile_delta{1, 1}, - other->pos.draw}; - - // find a free position adjacent to the object - auto terrain = other->get_terrain(); - for (coord::tile temp_pos : tile_list(outline)) { - TerrainChunk *chunk = terrain->get_chunk(temp_pos); - - if (chunk == nullptr) { - continue; - } - - auto placed = this->place(u, terrain, temp_pos.to_phys3(*terrain)); - if (placed) { - return placed; - } - } - return nullptr; -} - -void UnitType::copy_attributes(Unit *unit) const { - unit->add_attributes(this->default_attributes); -} - -void UnitType::upgrade(const std::shared_ptr &attr) { - this->default_attributes.add(attr); -} - -UnitType *UnitType::parent_type() const { - return this->owner.get_type(this->parent_id()); -} - -NyanType::NyanType(const Player &owner) : - UnitType(owner) { - // TODO: the type should be given attributes and abilities -} - -NyanType::~NyanType() = default; - -int NyanType::id() const { - return 1; -} - -int NyanType::parent_id() const { - return -1; -} - -std::string NyanType::name() const { - return "Nyan"; -} - -void NyanType::initialise(Unit *unit, Player &) { - // removes all actions and abilities - unit->reset(); - - // initialise unit - unit->unit_type = this; - - // the parsed nyan data gives the list of attributes - // and abilities which are given to the unit - for (auto &ability : this->type_abilities) { - unit->give_ability(ability); - } - - // copy all attributes - this->copy_attributes(unit); - - // give idle action - unit->push_action(std::make_unique(unit), true); -} - -TerrainObject *NyanType::place(Unit *unit, std::shared_ptr terrain, coord::phys3 init_pos) const { - // the parsed nyan data gives the rules for terrain placement - // which includes valid terrains, base radius and shape - - unit->make_location(coord::tile_delta{1, 1}); - - // allow unit to go anywhere - unit->location->passable = [](const coord::phys3 &) { - return true; - }; - - // try to place the obj, it knows best whether it will fit. - if (unit->location->place(terrain, init_pos, object_state::placed)) { - return unit->location.get(); - } - - // placing at the given position failed - unit->log(MSG(dbg) << "failed to place object"); - return nullptr; -} - -} // namespace openage diff --git a/libopenage/unit/unit_type.h b/libopenage/unit/unit_type.h deleted file mode 100644 index 57dc2c2b49..0000000000 --- a/libopenage/unit/unit_type.h +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include -#include - -#include "../coord/phys.h" -#include "../gamestate/old/cost.h" -#include "attributes.h" - -namespace openage { - -class Player; -class Terrain; -class TerrainObject; -class Unit; -class UnitAbility; -class UnitContainer; - - -/** - * an abstract unit type which is not yet owned by any player - */ -class UnitTypeMeta { -public: - using type_ptr = std::shared_ptr; - using init_func = std::function; - UnitTypeMeta(std::string name, int id, init_func f); - - std::string name() const; - - int id() const; - - /** - * creates the base unit type for a player - */ - const init_func init; - -private: - const std::string type_name; - const int type_id; -}; - -/** - * UnitType has to main roles: - * - * initialise(unit, player) should be called on a unit to give it a type and the required attributes, abilities and initial actions - * of that type - * - * place(unit, terrain, initial position) is called to customise how the unit gets added to the world -- used to setup the TerrainObject location - * - * UnitType is connected to a player to allow independent tech levels - */ -class UnitType { -public: - UnitType(const Player &owner); - virtual ~UnitType() {} - - /** - * gets the unique id of this unit type - */ - virtual int id() const = 0; - - /** - * gets the parent id of this unit type - * which is used for village base and gather types - */ - virtual int parent_id() const = 0; - - /** - * gets the name of the unit type being produced - */ - virtual std::string name() const = 0; - - /** - * Initialize units attributes to this type spec - * - * This can be called using existing units to modify type - * Ensure that the unit has been placed before seting the units type - * - * TODO: make const - */ - virtual void initialise(Unit *, Player &) = 0; - - /** - * Initialize units shared attributes only to this type spec - * - * This can be called using existing units to modify type if the type - * Ensure that the unit has been placed before seting the units type - * - * TODO define if pure vitrual or not / should be in nyan? - */ - virtual void reinitialise(Unit *, Player &); - - /** - * set unit in place -- return if placement was successful - * - * This should be used when initially creating a unit or - * when a unit is ungarrsioned from a building or object - * TODO: make const - */ - virtual TerrainObject *place(Unit *, std::shared_ptr, coord::phys3) const = 0; - - /** - * compare if two types are the same - */ - bool operator==(const UnitType &other) const; - bool operator!=(const UnitType &other) const; - - /** - * similar to place but places adjacent to an existing object - */ - TerrainObject *place_beside(Unit *, TerrainObject const *) const; - - /** - * copy attributes of this unit type to a new unit instance - */ - void copy_attributes(Unit *unit) const; - - /** - * upgrades one attribute of this unit type - */ - void upgrade(const std::shared_ptr &attr); - - /** - * returns type matching parent_id() - */ - UnitType *parent_type() const; - - /** - * the player who owns this unit type - */ - const Player &owner; - - /** - * all instances of units made from this unit type - * this could allow all units of a type to be upgraded - */ - std::vector instances; - - /** - * abilities given to all instances - */ - std::vector> type_abilities; - - /** - * default attributes which get copied to new units - */ - Attributes default_attributes; - - /** - * The cost of the unit. - */ - ResourceCost cost; - - /** - * The max number of units of this type that a player can have at an instance. - * Use negative values for special cases. - */ - int have_limit; - - /** - * The max number of units of this type that a player can create. - * Use negative values for special cases. - */ - int had_limit; - - /** - * The index of the icon representing this unit - */ - int icon; - - /** - * the square dimensions of the placement - */ - coord::tile_delta foundation_size; - - /** - * raw game data class of this unit instance - */ - gamedata::unit_classes unit_class; -}; - -/** - * An example of how nyan can work with the type system - */ -class NyanType : public UnitType { -public: - /** - * TODO: give the parsed nyan attributes - * to the constructor - */ - NyanType(const Player &owner); - virtual ~NyanType(); - - int id() const override; - int parent_id() const override; - std::string name() const override; - void initialise(Unit *, Player &) override; - TerrainObject *place(Unit *, std::shared_ptr, coord::phys3) const override; -}; - -} // namespace openage From 1b6224ed80b971dc6bdc42edaf1d8e1b8aafa4f8 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 24 Sep 2023 00:00:51 +0200 Subject: [PATCH 41/95] gamedata: Remove old dummy data. --- libopenage/CMakeLists.txt | 1 - libopenage/console/console.cpp | 16 +- libopenage/console/console.h | 3 +- libopenage/gamedata/CMakeLists.txt | 16 - libopenage/gamedata/about | 3 - libopenage/gamedata/blending_mode_dummy.cpp | 46 - libopenage/gamedata/blending_mode_dummy.h | 32 - libopenage/gamedata/civilisation_dummy.cpp | 273 -- libopenage/gamedata/civilisation_dummy.h | 57 - libopenage/gamedata/color_dummy.cpp | 50 - libopenage/gamedata/color_dummy.h | 36 - libopenage/gamedata/gamedata_dummy.cpp | 110 - libopenage/gamedata/gamedata_dummy.h | 88 - libopenage/gamedata/graphic_dummy.cpp | 166 - libopenage/gamedata/graphic_dummy.h | 97 - libopenage/gamedata/player_color_dummy.cpp | 54 - libopenage/gamedata/player_color_dummy.h | 40 - libopenage/gamedata/research_dummy.cpp | 101 - libopenage/gamedata/research_dummy.h | 61 - libopenage/gamedata/sound_dummy.cpp | 81 - libopenage/gamedata/sound_dummy.h | 50 - libopenage/gamedata/string_resource_dummy.cpp | 48 - libopenage/gamedata/string_resource_dummy.h | 34 - libopenage/gamedata/tech_dummy.cpp | 264 -- libopenage/gamedata/tech_dummy.h | 140 - libopenage/gamedata/terrain_dummy.cpp | 274 -- libopenage/gamedata/terrain_dummy.h | 141 - libopenage/gamedata/texture_dummy.cpp | 51 - libopenage/gamedata/texture_dummy.h | 40 - libopenage/gamedata/unit_dummy.cpp | 2820 ----------------- libopenage/gamedata/unit_dummy.h | 515 --- libopenage/gamedata/util_dummy.cpp | 46 - libopenage/gamedata/util_dummy.h | 32 - libopenage/util/color.cpp | 11 +- libopenage/util/color.h | 10 +- 35 files changed, 16 insertions(+), 5791 deletions(-) delete mode 100644 libopenage/gamedata/CMakeLists.txt delete mode 100644 libopenage/gamedata/about delete mode 100644 libopenage/gamedata/blending_mode_dummy.cpp delete mode 100644 libopenage/gamedata/blending_mode_dummy.h delete mode 100644 libopenage/gamedata/civilisation_dummy.cpp delete mode 100644 libopenage/gamedata/civilisation_dummy.h delete mode 100644 libopenage/gamedata/color_dummy.cpp delete mode 100644 libopenage/gamedata/color_dummy.h delete mode 100644 libopenage/gamedata/gamedata_dummy.cpp delete mode 100644 libopenage/gamedata/gamedata_dummy.h delete mode 100644 libopenage/gamedata/graphic_dummy.cpp delete mode 100644 libopenage/gamedata/graphic_dummy.h delete mode 100644 libopenage/gamedata/player_color_dummy.cpp delete mode 100644 libopenage/gamedata/player_color_dummy.h delete mode 100644 libopenage/gamedata/research_dummy.cpp delete mode 100644 libopenage/gamedata/research_dummy.h delete mode 100644 libopenage/gamedata/sound_dummy.cpp delete mode 100644 libopenage/gamedata/sound_dummy.h delete mode 100644 libopenage/gamedata/string_resource_dummy.cpp delete mode 100644 libopenage/gamedata/string_resource_dummy.h delete mode 100644 libopenage/gamedata/tech_dummy.cpp delete mode 100644 libopenage/gamedata/tech_dummy.h delete mode 100644 libopenage/gamedata/terrain_dummy.cpp delete mode 100644 libopenage/gamedata/terrain_dummy.h delete mode 100644 libopenage/gamedata/texture_dummy.cpp delete mode 100644 libopenage/gamedata/texture_dummy.h delete mode 100644 libopenage/gamedata/unit_dummy.cpp delete mode 100644 libopenage/gamedata/unit_dummy.h delete mode 100644 libopenage/gamedata/util_dummy.cpp delete mode 100644 libopenage/gamedata/util_dummy.h diff --git a/libopenage/CMakeLists.txt b/libopenage/CMakeLists.txt index bda4bc1611..3e12a5766c 100644 --- a/libopenage/CMakeLists.txt +++ b/libopenage/CMakeLists.txt @@ -344,7 +344,6 @@ add_subdirectory("datastructure") add_subdirectory("engine") add_subdirectory("error") add_subdirectory("event") -add_subdirectory("gamedata") add_subdirectory("gamestate") add_subdirectory("gui") add_subdirectory("input") diff --git a/libopenage/console/console.cpp b/libopenage/console/console.cpp index 20e414e13d..04cf29d4d1 100644 --- a/libopenage/console/console.cpp +++ b/libopenage/console/console.cpp @@ -44,15 +44,15 @@ Console::Console(/* presenter::LegacyDisplay *display */) : Console::~Console() {} -void Console::load_colors(std::vector &colortable) { - for (auto &c : colortable) { - this->termcolors.emplace_back(c); - } +// void Console::load_colors(std::vector &colortable) { +// for (auto &c : colortable) { +// this->termcolors.emplace_back(c); +// } - if (termcolors.size() != 256) { - throw Error(MSG(err) << "Exactly 256 terminal colors are required."); - } -} +// if (termcolors.size() != 256) { +// throw Error(MSG(err) << "Exactly 256 terminal colors are required."); +// } +// } void Console::register_to_engine() { // TODO: Use new renderer diff --git a/libopenage/console/console.h b/libopenage/console/console.h index 6994c4cbe9..839467e6a1 100644 --- a/libopenage/console/console.h +++ b/libopenage/console/console.h @@ -6,7 +6,6 @@ #include #include "../coord/pixel.h" -#include "../gamedata/color_dummy.h" #include "../renderer/font/font.h" #include "../util/color.h" #include "buf.h" @@ -28,7 +27,7 @@ class Console { /** * load the consoles color table */ - void load_colors(std::vector &colortable); + // void load_colors(std::vector &colortable); /** * register this console to the renderer. diff --git a/libopenage/gamedata/CMakeLists.txt b/libopenage/gamedata/CMakeLists.txt deleted file mode 100644 index 9eb8632148..0000000000 --- a/libopenage/gamedata/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -add_sources(libopenage - blending_mode_dummy.cpp - civilisation_dummy.cpp - color_dummy.cpp - gamedata_dummy.cpp - graphic_dummy.cpp - player_color_dummy.cpp - research_dummy.cpp - sound_dummy.cpp - string_resource_dummy.cpp - tech_dummy.cpp - terrain_dummy.cpp - texture_dummy.cpp - unit_dummy.cpp - util_dummy.cpp -) diff --git a/libopenage/gamedata/about b/libopenage/gamedata/about deleted file mode 100644 index f9e60f268e..0000000000 --- a/libopenage/gamedata/about +++ /dev/null @@ -1,3 +0,0 @@ -all source files in this directory are auto-generated during the build process. - -this file mainly exists to ensure that the directory isn't empty. diff --git a/libopenage/gamedata/blending_mode_dummy.cpp b/libopenage/gamedata/blending_mode_dummy.cpp deleted file mode 100644 index 468c55c84e..0000000000 --- a/libopenage/gamedata/blending_mode_dummy.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - - -#include -#include -#include "blending_mode_dummy.h" -#include "error/error.h" -#include "util/strings.h" - - -namespace openage { -namespace gamedata { - -constexpr size_t blending_mode::member_count; -int blending_mode::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', blending_mode::member_count - ); - - if (buf.size() != blending_mode::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing blending_mode led to " - << buf.size() - << " columns (expected " - << blending_mode::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%d", &this->blend_mode) != 1) { return 0; } - - return -1; -} - -bool blending_mode::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -} // gamedata -} // openage diff --git a/libopenage/gamedata/blending_mode_dummy.h b/libopenage/gamedata/blending_mode_dummy.h deleted file mode 100644 index 55b29788ae..0000000000 --- a/libopenage/gamedata/blending_mode_dummy.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - -#pragma once - -#include -#include -#include -#include "util/csv.h" - - - -namespace openage { -namespace gamedata { - -/** - * describes one blending mode, a blending transition shape between two different terrain types. - */ -struct blending_mode { - int32_t blend_mode; - static constexpr size_t member_count = 1; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -} // gamedata -} // openage diff --git a/libopenage/gamedata/civilisation_dummy.cpp b/libopenage/gamedata/civilisation_dummy.cpp deleted file mode 100644 index e4b0300edf..0000000000 --- a/libopenage/gamedata/civilisation_dummy.cpp +++ /dev/null @@ -1,273 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - - -#include -#include -#include -#include "civilisation_dummy.h" -#include "error/error.h" -#include "unit_dummy.h" -#include "util_dummy.h" -#include "util/csv.h" -#include "util/path.h" -#include "util/strings.h" - - -namespace openage { -namespace gamedata { - -constexpr size_t civilisation::member_count; -int civilisation::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', civilisation::member_count - ); - - if (buf.size() != civilisation::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing civilisation led to " - << buf.size() - << " columns (expected " - << civilisation::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hhd", &this->player_type) != 1) { return 0; } - this->name = buf[1]; - if (sscanf(buf[2].c_str(), "%hd", &this->tech_tree_id) != 1) { return 2; } - if (sscanf(buf[3].c_str(), "%hd", &this->team_bonus_id) != 1) { return 3; } - if (sscanf(buf[5].c_str(), "%hhd", &this->icon_set) != 1) { return 5; } - this->units.subdata_meta.filename = buf[6]; - - return -1; -} - -bool civilisation::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->units.recurse(storage, basedir); - - return true; -} - -int unit_types::fill(const std::string & /*line*/) { - return -1; -} -bool unit_types::recurse(const openage::util::CSVCollection &storage, - const std::string &basedir) { - - // the .filename was set by the previous entry parser already - // so now read the index-file entries - this->subdata_meta.read(storage, basedir); - - int subtype_count = this->subdata_meta.data.size(); - if (subtype_count != 9) { - throw openage::error::Error( - ERR << "multisubtype index file entry count mismatched!" - << subtype_count << " != 9" - ); - } - - // the recursed data files are relative to the subdata_meta filename - std::string metadata_dir = basedir + openage::util::fslike::PATHSEP + openage::util::dirname(this->subdata_meta.filename); - int idx; - int idxtry; - - // read subtype 'action' - idx = -1; - idxtry = 0; - // find the index of the subdata in the metadata - for (auto &file_reference : this->subdata_meta.data) { - if (file_reference.subtype == "action") { - idx = idxtry; - break; - } - idxtry += 1; - } - if (idx == -1) { - throw openage::error::Error( - ERR << "multisubtype index file contains no entry for action!" - ); - } - - // the filename is relative to the metadata file! - this->action.filename = this->subdata_meta.data[idx].filename; - this->action.read(storage, metadata_dir); - - // read subtype 'animated' - idx = -1; - idxtry = 0; - // find the index of the subdata in the metadata - for (auto &file_reference : this->subdata_meta.data) { - if (file_reference.subtype == "animated") { - idx = idxtry; - break; - } - idxtry += 1; - } - if (idx == -1) { - throw openage::error::Error( - ERR << "multisubtype index file contains no entry for animated!" - ); - } - - // the filename is relative to the metadata file! - this->animated.filename = this->subdata_meta.data[idx].filename; - this->animated.read(storage, metadata_dir); - - // read subtype 'building' - idx = -1; - idxtry = 0; - // find the index of the subdata in the metadata - for (auto &file_reference : this->subdata_meta.data) { - if (file_reference.subtype == "building") { - idx = idxtry; - break; - } - idxtry += 1; - } - if (idx == -1) { - throw openage::error::Error( - ERR << "multisubtype index file contains no entry for building!" - ); - } - - // the filename is relative to the metadata file! - this->building.filename = this->subdata_meta.data[idx].filename; - this->building.read(storage, metadata_dir); - - // read subtype 'doppelganger' - idx = -1; - idxtry = 0; - // find the index of the subdata in the metadata - for (auto &file_reference : this->subdata_meta.data) { - if (file_reference.subtype == "doppelganger") { - idx = idxtry; - break; - } - idxtry += 1; - } - if (idx == -1) { - throw openage::error::Error( - ERR << "multisubtype index file contains no entry for doppelganger!" - ); - } - - // the filename is relative to the metadata file! - this->doppelganger.filename = this->subdata_meta.data[idx].filename; - this->doppelganger.read(storage, metadata_dir); - - // read subtype 'living' - idx = -1; - idxtry = 0; - // find the index of the subdata in the metadata - for (auto &file_reference : this->subdata_meta.data) { - if (file_reference.subtype == "living") { - idx = idxtry; - break; - } - idxtry += 1; - } - if (idx == -1) { - throw openage::error::Error( - ERR << "multisubtype index file contains no entry for living!" - ); - } - - // the filename is relative to the metadata file! - this->living.filename = this->subdata_meta.data[idx].filename; - this->living.read(storage, metadata_dir); - - // read subtype 'missile' - idx = -1; - idxtry = 0; - // find the index of the subdata in the metadata - for (auto &file_reference : this->subdata_meta.data) { - if (file_reference.subtype == "missile") { - idx = idxtry; - break; - } - idxtry += 1; - } - if (idx == -1) { - throw openage::error::Error( - ERR << "multisubtype index file contains no entry for missile!" - ); - } - - // the filename is relative to the metadata file! - this->missile.filename = this->subdata_meta.data[idx].filename; - this->missile.read(storage, metadata_dir); - - // read subtype 'moving' - idx = -1; - idxtry = 0; - // find the index of the subdata in the metadata - for (auto &file_reference : this->subdata_meta.data) { - if (file_reference.subtype == "moving") { - idx = idxtry; - break; - } - idxtry += 1; - } - if (idx == -1) { - throw openage::error::Error( - ERR << "multisubtype index file contains no entry for moving!" - ); - } - - // the filename is relative to the metadata file! - this->moving.filename = this->subdata_meta.data[idx].filename; - this->moving.read(storage, metadata_dir); - - // read subtype 'object' - idx = -1; - idxtry = 0; - // find the index of the subdata in the metadata - for (auto &file_reference : this->subdata_meta.data) { - if (file_reference.subtype == "object") { - idx = idxtry; - break; - } - idxtry += 1; - } - if (idx == -1) { - throw openage::error::Error( - ERR << "multisubtype index file contains no entry for object!" - ); - } - - // the filename is relative to the metadata file! - this->object.filename = this->subdata_meta.data[idx].filename; - this->object.read(storage, metadata_dir); - - // read subtype 'tree' - idx = -1; - idxtry = 0; - // find the index of the subdata in the metadata - for (auto &file_reference : this->subdata_meta.data) { - if (file_reference.subtype == "tree") { - idx = idxtry; - break; - } - idxtry += 1; - } - if (idx == -1) { - throw openage::error::Error( - ERR << "multisubtype index file contains no entry for tree!" - ); - } - - // the filename is relative to the metadata file! - this->tree.filename = this->subdata_meta.data[idx].filename; - this->tree.read(storage, metadata_dir); - - return true; -} - -} // gamedata -} // openage diff --git a/libopenage/gamedata/civilisation_dummy.h b/libopenage/gamedata/civilisation_dummy.h deleted file mode 100644 index 1627b4112f..0000000000 --- a/libopenage/gamedata/civilisation_dummy.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - -#pragma once - -#include -#include -#include -#include -#include "unit_dummy.h" -#include "util_dummy.h" -#include "util/csv.h" - - - -namespace openage { -namespace gamedata { - -struct unit_types { - struct openage::util::csv_subdata action; - struct openage::util::csv_subdata animated; - struct openage::util::csv_subdata building; - struct openage::util::csv_subdata doppelganger; - struct openage::util::csv_subdata living; - struct openage::util::csv_subdata missile; - struct openage::util::csv_subdata moving; - struct openage::util::csv_subdata object; - struct openage::util::csv_subdata tree; - struct openage::util::csv_subdata subdata_meta; - - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * describes a civilisation. - */ -struct civilisation { - int8_t player_type; - std::string name; - int16_t tech_tree_id; - int16_t team_bonus_id; - int8_t icon_set; - unit_types units; - static constexpr size_t member_count = 7; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -} // gamedata -} // openage diff --git a/libopenage/gamedata/color_dummy.cpp b/libopenage/gamedata/color_dummy.cpp deleted file mode 100644 index 9985fb0b9d..0000000000 --- a/libopenage/gamedata/color_dummy.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - - -#include -#include -#include "color_dummy.h" -#include "error/error.h" -#include "util/strings.h" - - -namespace openage { -namespace gamedata { - -constexpr size_t palette_color::member_count; -int palette_color::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', palette_color::member_count - ); - - if (buf.size() != palette_color::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing palette_color led to " - << buf.size() - << " columns (expected " - << palette_color::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%d", &this->idx) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hhu", &this->r) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hhu", &this->g) != 1) { return 2; } - if (sscanf(buf[3].c_str(), "%hhu", &this->b) != 1) { return 3; } - if (sscanf(buf[4].c_str(), "%hhu", &this->a) != 1) { return 4; } - - return -1; -} - -bool palette_color::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -} // gamedata -} // openage diff --git a/libopenage/gamedata/color_dummy.h b/libopenage/gamedata/color_dummy.h deleted file mode 100644 index 4c6915e5cb..0000000000 --- a/libopenage/gamedata/color_dummy.h +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - -#pragma once - -#include -#include -#include -#include "util/csv.h" - - - -namespace openage { -namespace gamedata { - -/** - * indexed color storage. - */ -struct palette_color { - int32_t idx; - uint8_t r; - uint8_t g; - uint8_t b; - uint8_t a; - static constexpr size_t member_count = 5; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -} // gamedata -} // openage diff --git a/libopenage/gamedata/gamedata_dummy.cpp b/libopenage/gamedata/gamedata_dummy.cpp deleted file mode 100644 index 959df5237a..0000000000 --- a/libopenage/gamedata/gamedata_dummy.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - - -#include -#include -#include "error/error.h" -#include "gamedata_dummy.h" -#include "util/strings.h" - - -namespace openage { -namespace gamedata { - -constexpr size_t empiresdat::member_count; -int empiresdat::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', empiresdat::member_count - ); - - if (buf.size() != empiresdat::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing empiresdat led to " - << buf.size() - << " columns (expected " - << empiresdat::member_count - << ")!" - ); - } - - this->versionstr = buf[0]; - this->terrain_restrictions.filename = buf[1]; - this->player_colors.filename = buf[2]; - this->sounds.filename = buf[3]; - this->graphics.filename = buf[4]; - if (sscanf(buf[5].c_str(), "%d", &this->virt_function_ptr) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%d", &this->map_pointer) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%d", &this->map_width) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%d", &this->map_height) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%d", &this->world_width) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%d", &this->world_height) != 1) { return 10; } - this->tile_sizes.filename = buf[11]; - if (sscanf(buf[12].c_str(), "%hd", &this->padding1) != 1) { return 12; } - this->terrains.filename = buf[13]; - this->terrain_border.filename = buf[14]; - if (sscanf(buf[15].c_str(), "%d", &this->map_row_offset) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%f", &this->map_min_x) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%f", &this->map_min_y) != 1) { return 17; } - if (sscanf(buf[18].c_str(), "%f", &this->map_max_x) != 1) { return 18; } - if (sscanf(buf[19].c_str(), "%f", &this->map_max_y) != 1) { return 19; } - if (sscanf(buf[20].c_str(), "%f", &this->map_max_xplus1) != 1) { return 20; } - if (sscanf(buf[21].c_str(), "%f", &this->map_min_yplus1) != 1) { return 21; } - if (sscanf(buf[22].c_str(), "%hd", &this->current_row) != 1) { return 22; } - if (sscanf(buf[23].c_str(), "%hd", &this->current_column) != 1) { return 23; } - if (sscanf(buf[24].c_str(), "%hd", &this->block_beginn_row) != 1) { return 24; } - if (sscanf(buf[25].c_str(), "%hd", &this->block_end_row) != 1) { return 25; } - if (sscanf(buf[26].c_str(), "%hd", &this->block_begin_column) != 1) { return 26; } - if (sscanf(buf[27].c_str(), "%hd", &this->block_end_column) != 1) { return 27; } - if (sscanf(buf[28].c_str(), "%d", &this->search_map_ptr) != 1) { return 28; } - if (sscanf(buf[29].c_str(), "%d", &this->search_map_rows_ptr) != 1) { return 29; } - if (sscanf(buf[30].c_str(), "%hhd", &this->any_frame_change) != 1) { return 30; } - if (sscanf(buf[31].c_str(), "%hhd", &this->map_visible_flag) != 1) { return 31; } - if (sscanf(buf[32].c_str(), "%hhd", &this->fog_flag) != 1) { return 32; } - this->effect_bundles.filename = buf[33]; - this->unit_headers.filename = buf[34]; - this->civs.filename = buf[35]; - this->researches.filename = buf[36]; - if (sscanf(buf[37].c_str(), "%d", &this->time_slice) != 1) { return 37; } - if (sscanf(buf[38].c_str(), "%d", &this->unit_kill_rate) != 1) { return 38; } - if (sscanf(buf[39].c_str(), "%d", &this->unit_kill_total) != 1) { return 39; } - if (sscanf(buf[40].c_str(), "%d", &this->unit_hitpoint_rate) != 1) { return 40; } - if (sscanf(buf[41].c_str(), "%d", &this->unit_hitpoint_total) != 1) { return 41; } - if (sscanf(buf[42].c_str(), "%d", &this->razing_kill_rate) != 1) { return 42; } - if (sscanf(buf[43].c_str(), "%d", &this->razing_kill_total) != 1) { return 43; } - if (sscanf(buf[44].c_str(), "%d", &this->total_unit_tech_groups) != 1) { return 44; } - this->age_connections.filename = buf[45]; - this->building_connections.filename = buf[46]; - this->unit_connections.filename = buf[47]; - this->tech_connections.filename = buf[48]; - - return -1; -} - -bool empiresdat::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->terrain_restrictions.read(storage, basedir); - this->player_colors.read(storage, basedir); - this->sounds.read(storage, basedir); - this->graphics.read(storage, basedir); - this->tile_sizes.read(storage, basedir); - this->terrains.read(storage, basedir); - this->terrain_border.read(storage, basedir); - this->effect_bundles.read(storage, basedir); - this->unit_headers.read(storage, basedir); - this->civs.read(storage, basedir); - this->researches.read(storage, basedir); - this->age_connections.read(storage, basedir); - this->building_connections.read(storage, basedir); - this->unit_connections.read(storage, basedir); - this->tech_connections.read(storage, basedir); - - return true; -} - -} // gamedata -} // openage diff --git a/libopenage/gamedata/gamedata_dummy.h b/libopenage/gamedata/gamedata_dummy.h deleted file mode 100644 index d702b8cd4f..0000000000 --- a/libopenage/gamedata/gamedata_dummy.h +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - -#pragma once - -#include -#include -#include -#include "civilisation_dummy.h" -#include "graphic_dummy.h" -#include "player_color_dummy.h" -#include "research_dummy.h" -#include "sound_dummy.h" -#include "tech_dummy.h" -#include "terrain_dummy.h" -#include "unit_dummy.h" -#include "util/csv.h" - - - -namespace openage { -namespace gamedata { - -/** - * empires2_x1_p1.dat structure - */ -struct empiresdat { - std::string versionstr; - openage::util::csv_subdata terrain_restrictions; - openage::util::csv_subdata player_colors; - openage::util::csv_subdata sounds; - openage::util::csv_subdata graphics; - int32_t virt_function_ptr; - int32_t map_pointer; - int32_t map_width; - int32_t map_height; - int32_t world_width; - int32_t world_height; - openage::util::csv_subdata tile_sizes; - int16_t padding1; - openage::util::csv_subdata terrains; - openage::util::csv_subdata terrain_border; - int32_t map_row_offset; - float map_min_x; - float map_min_y; - float map_max_x; - float map_max_y; - float map_max_xplus1; - float map_min_yplus1; - int16_t current_row; - int16_t current_column; - int16_t block_beginn_row; - int16_t block_end_row; - int16_t block_begin_column; - int16_t block_end_column; - int32_t search_map_ptr; - int32_t search_map_rows_ptr; - int8_t any_frame_change; - int8_t map_visible_flag; - int8_t fog_flag; - openage::util::csv_subdata effect_bundles; - openage::util::csv_subdata unit_headers; - openage::util::csv_subdata civs; - openage::util::csv_subdata researches; - int32_t time_slice; - int32_t unit_kill_rate; - int32_t unit_kill_total; - int32_t unit_hitpoint_rate; - int32_t unit_hitpoint_total; - int32_t razing_kill_rate; - int32_t razing_kill_total; - int32_t total_unit_tech_groups; - openage::util::csv_subdata age_connections; - openage::util::csv_subdata building_connections; - openage::util::csv_subdata unit_connections; - openage::util::csv_subdata tech_connections; - static constexpr size_t member_count = 49; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -} // gamedata -} // openage diff --git a/libopenage/gamedata/graphic_dummy.cpp b/libopenage/gamedata/graphic_dummy.cpp deleted file mode 100644 index 6a0d6b63cb..0000000000 --- a/libopenage/gamedata/graphic_dummy.cpp +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - - -#include -#include -#include "error/error.h" -#include "graphic_dummy.h" -#include "util/strings.h" - - -namespace openage { -namespace gamedata { - -constexpr size_t graphic::member_count; -constexpr size_t graphic_attack_sound::member_count; -constexpr size_t graphic_delta::member_count; -constexpr size_t sound_prop::member_count; -int graphic_attack_sound::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', graphic_attack_sound::member_count - ); - - if (buf.size() != graphic_attack_sound::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing graphic_attack_sound led to " - << buf.size() - << " columns (expected " - << graphic_attack_sound::member_count - << ")!" - ); - } - - this->sound_props.filename = buf[0]; - - return -1; -} - -bool graphic_attack_sound::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->sound_props.read(storage, basedir); - - return true; -} - -int graphic_delta::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', graphic_delta::member_count - ); - - if (buf.size() != graphic_delta::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing graphic_delta led to " - << buf.size() - << " columns (expected " - << graphic_delta::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->graphic_id) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hd", &this->padding_1) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%d", &this->sprite_ptr) != 1) { return 2; } - if (sscanf(buf[3].c_str(), "%hd", &this->offset_x) != 1) { return 3; } - if (sscanf(buf[4].c_str(), "%hd", &this->offset_y) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%hd", &this->display_angle) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%hd", &this->padding_2) != 1) { return 6; } - - return -1; -} - -bool graphic_delta::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -int graphic::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', graphic::member_count - ); - - if (buf.size() != graphic::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing graphic led to " - << buf.size() - << " columns (expected " - << graphic::member_count - << ")!" - ); - } - - this->name = buf[0]; - this->filename = buf[1]; - if (sscanf(buf[2].c_str(), "%d", &this->slp_id) != 1) { return 2; } - if (sscanf(buf[3].c_str(), "%hhd", &this->is_loaded) != 1) { return 3; } - if (sscanf(buf[4].c_str(), "%hhd", &this->old_color_flag) != 1) { return 4; } - // parse enum graphics_layer - if (buf[5] == "DUMMY") { - this->layer = graphics_layer::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[5] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[6].c_str(), "%hhd", &this->player_color_force_id) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%hhd", &this->adapt_color) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%hhu", &this->transparent_selection) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hd", &this->sound_id) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%hu", &this->frame_count) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%hu", &this->angle_count) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%f", &this->speed_adjust) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%f", &this->frame_rate) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%f", &this->replay_delay) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%hhd", &this->sequence_type) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%hd", &this->graphic_id) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%hhd", &this->mirroring_mode) != 1) { return 17; } - if (sscanf(buf[18].c_str(), "%hhd", &this->editor_flag) != 1) { return 18; } - this->graphic_deltas.filename = buf[19]; - this->graphic_attack_sounds.filename = buf[20]; - - return -1; -} - -bool graphic::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->graphic_deltas.read(storage, basedir); - this->graphic_attack_sounds.read(storage, basedir); - - return true; -} - -int sound_prop::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', sound_prop::member_count - ); - - if (buf.size() != sound_prop::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing sound_prop led to " - << buf.size() - << " columns (expected " - << sound_prop::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->sound_delay) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hd", &this->sound_id) != 1) { return 1; } - - return -1; -} - -bool sound_prop::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -} // gamedata -} // openage diff --git a/libopenage/gamedata/graphic_dummy.h b/libopenage/gamedata/graphic_dummy.h deleted file mode 100644 index 34f0a2a82f..0000000000 --- a/libopenage/gamedata/graphic_dummy.h +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - -#pragma once - -#include -#include -#include -#include "util/csv.h" - - - -namespace openage { -namespace gamedata { - -/** - * delta definitions for ingame graphics files. - */ -struct graphic_delta { - int16_t graphic_id; - int16_t padding_1; - int32_t sprite_ptr; - int16_t offset_x; - int16_t offset_y; - int16_t display_angle; - int16_t padding_2; - static constexpr size_t member_count = 7; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -enum class graphics_layer { - DUMMY -}; - - -/** - * sound id and delay definition for graphics sounds. - */ -struct sound_prop { - int16_t sound_delay; - int16_t sound_id; - static constexpr size_t member_count = 2; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * attack sounds for a given graphics file. - */ -struct graphic_attack_sound { - openage::util::csv_subdata sound_props; - static constexpr size_t member_count = 1; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * metadata for ingame graphics files. - */ -struct graphic { - std::string name; - std::string filename; - int32_t slp_id; - int8_t is_loaded; - int8_t old_color_flag; - graphics_layer layer; - int8_t player_color_force_id; - int8_t adapt_color; - uint8_t transparent_selection; - int16_t sound_id; - uint16_t frame_count; - uint16_t angle_count; - float speed_adjust; - float frame_rate; - float replay_delay; - int8_t sequence_type; - int16_t graphic_id; - int8_t mirroring_mode; - int8_t editor_flag; - openage::util::csv_subdata graphic_deltas; - openage::util::csv_subdata graphic_attack_sounds; - static constexpr size_t member_count = 21; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -} // gamedata -} // openage diff --git a/libopenage/gamedata/player_color_dummy.cpp b/libopenage/gamedata/player_color_dummy.cpp deleted file mode 100644 index 949b0de3c1..0000000000 --- a/libopenage/gamedata/player_color_dummy.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - - -#include -#include -#include "error/error.h" -#include "player_color_dummy.h" -#include "util/strings.h" - - -namespace openage { -namespace gamedata { - -constexpr size_t player_color::member_count; -int player_color::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', player_color::member_count - ); - - if (buf.size() != player_color::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing player_color led to " - << buf.size() - << " columns (expected " - << player_color::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%d", &this->id) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%d", &this->player_color_base) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%d", &this->outline_color) != 1) { return 2; } - if (sscanf(buf[3].c_str(), "%d", &this->unit_selection_color1) != 1) { return 3; } - if (sscanf(buf[4].c_str(), "%d", &this->unit_selection_color2) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%d", &this->minimap_color1) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%d", &this->minimap_color2) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%d", &this->minimap_color3) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%d", &this->statistics_text_color) != 1) { return 8; } - - return -1; -} - -bool player_color::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -} // gamedata -} // openage diff --git a/libopenage/gamedata/player_color_dummy.h b/libopenage/gamedata/player_color_dummy.h deleted file mode 100644 index ced379fba4..0000000000 --- a/libopenage/gamedata/player_color_dummy.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - -#pragma once - -#include -#include -#include -#include "util/csv.h" - - - -namespace openage { -namespace gamedata { - -/** - * describes player color settings. - */ -struct player_color { - int32_t id; - int32_t player_color_base; - int32_t outline_color; - int32_t unit_selection_color1; - int32_t unit_selection_color2; - int32_t minimap_color1; - int32_t minimap_color2; - int32_t minimap_color3; - int32_t statistics_text_color; - static constexpr size_t member_count = 9; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -} // gamedata -} // openage diff --git a/libopenage/gamedata/research_dummy.cpp b/libopenage/gamedata/research_dummy.cpp deleted file mode 100644 index 3b3a9af15b..0000000000 --- a/libopenage/gamedata/research_dummy.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - - -#include -#include -#include "error/error.h" -#include "research_dummy.h" -#include "util/strings.h" - - -namespace openage { -namespace gamedata { - -constexpr size_t tech::member_count; -constexpr size_t tech_resource_cost::member_count; -int tech::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', tech::member_count - ); - - if (buf.size() != tech::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing tech led to " - << buf.size() - << " columns (expected " - << tech::member_count - << ")!" - ); - } - - this->research_resource_costs.filename = buf[1]; - if (sscanf(buf[2].c_str(), "%hd", &this->required_tech_count) != 1) { return 2; } - if (sscanf(buf[3].c_str(), "%hd", &this->civilization_id) != 1) { return 3; } - if (sscanf(buf[4].c_str(), "%hd", &this->full_tech_mode) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%hd", &this->research_location_id) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%hu", &this->language_dll_name) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%hu", &this->language_dll_description) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%hd", &this->research_time) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hd", &this->tech_effect_id) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%hd", &this->tech_type) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%hd", &this->icon_id) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%hhd", &this->button_id) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%d", &this->language_dll_help) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%d", &this->language_dll_techtree) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%d", &this->hotkey) != 1) { return 15; } - this->name = buf[16]; - - return -1; -} - -bool tech::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->research_resource_costs.read(storage, basedir); - - return true; -} - -int tech_resource_cost::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', tech_resource_cost::member_count - ); - - if (buf.size() != tech_resource_cost::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing tech_resource_cost led to " - << buf.size() - << " columns (expected " - << tech_resource_cost::member_count - << ")!" - ); - } - - // parse enum resource_types - if (buf[0] == "DUMMY") { - this->type_id = resource_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[0] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[1].c_str(), "%hd", &this->amount) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hhd", &this->enabled) != 1) { return 2; } - - return -1; -} - -bool tech_resource_cost::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -} // gamedata -} // openage diff --git a/libopenage/gamedata/research_dummy.h b/libopenage/gamedata/research_dummy.h deleted file mode 100644 index f1a3205c16..0000000000 --- a/libopenage/gamedata/research_dummy.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - -#pragma once - -#include -#include -#include -#include "unit_dummy.h" -#include "util/csv.h" - - - -namespace openage { -namespace gamedata { - -/** - * amount definition for a single type resource for researches. - */ -struct tech_resource_cost { - resource_types type_id; - int16_t amount; - int8_t enabled; - static constexpr size_t member_count = 3; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * one researchable technology. - */ -struct tech { - openage::util::csv_subdata research_resource_costs; - int16_t required_tech_count; - int16_t civilization_id; - int16_t full_tech_mode; - int16_t research_location_id; - uint16_t language_dll_name; - uint16_t language_dll_description; - int16_t research_time; - int16_t tech_effect_id; - int16_t tech_type; - int16_t icon_id; - int8_t button_id; - int32_t language_dll_help; - int32_t language_dll_techtree; - int32_t hotkey; - std::string name; - static constexpr size_t member_count = 17; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -} // gamedata -} // openage diff --git a/libopenage/gamedata/sound_dummy.cpp b/libopenage/gamedata/sound_dummy.cpp deleted file mode 100644 index 67d781d0c0..0000000000 --- a/libopenage/gamedata/sound_dummy.cpp +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - - -#include -#include -#include "error/error.h" -#include "sound_dummy.h" -#include "util/strings.h" - - -namespace openage { -namespace gamedata { - -constexpr size_t sound::member_count; -constexpr size_t sound_item::member_count; -int sound::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', sound::member_count - ); - - if (buf.size() != sound::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing sound led to " - << buf.size() - << " columns (expected " - << sound::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->sound_id) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hd", &this->play_delay) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%d", &this->cache_time) != 1) { return 2; } - this->sound_items.filename = buf[3]; - - return -1; -} - -int sound_item::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', sound_item::member_count - ); - - if (buf.size() != sound_item::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing sound_item led to " - << buf.size() - << " columns (expected " - << sound_item::member_count - << ")!" - ); - } - - this->filename = buf[0]; - if (sscanf(buf[1].c_str(), "%d", &this->resource_id) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hd", &this->probablilty) != 1) { return 2; } - if (sscanf(buf[3].c_str(), "%hd", &this->civilization_id) != 1) { return 3; } - if (sscanf(buf[4].c_str(), "%hd", &this->icon_set) != 1) { return 4; } - - return -1; -} - -bool sound_item::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -bool sound::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->sound_items.read(storage, basedir); - - return true; -} - -} // gamedata -} // openage diff --git a/libopenage/gamedata/sound_dummy.h b/libopenage/gamedata/sound_dummy.h deleted file mode 100644 index 7c004cba5a..0000000000 --- a/libopenage/gamedata/sound_dummy.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - -#pragma once - -#include -#include -#include -#include "util/csv.h" - - - -namespace openage { -namespace gamedata { - -/** - * one possible file for a sound. - */ -struct sound_item { - std::string filename; - int32_t resource_id; - int16_t probablilty; - int16_t civilization_id; - int16_t icon_set; - static constexpr size_t member_count = 5; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * describes a sound, consisting of several sound items. - */ -struct sound { - int16_t sound_id; - int16_t play_delay; - int32_t cache_time; - openage::util::csv_subdata sound_items; - static constexpr size_t member_count = 4; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -} // gamedata -} // openage diff --git a/libopenage/gamedata/string_resource_dummy.cpp b/libopenage/gamedata/string_resource_dummy.cpp deleted file mode 100644 index 7030d15150..0000000000 --- a/libopenage/gamedata/string_resource_dummy.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - - -#include -#include -#include "error/error.h" -#include "string_resource_dummy.h" -#include "util/strings.h" - - -namespace openage { -namespace gamedata { - -constexpr size_t string_resource::member_count; -int string_resource::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', string_resource::member_count - ); - - if (buf.size() != string_resource::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing string_resource led to " - << buf.size() - << " columns (expected " - << string_resource::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%d", &this->id) != 1) { return 0; } - this->lang = buf[1]; - this->text = buf[2]; - - return -1; -} - -bool string_resource::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -} // gamedata -} // openage diff --git a/libopenage/gamedata/string_resource_dummy.h b/libopenage/gamedata/string_resource_dummy.h deleted file mode 100644 index 7673489566..0000000000 --- a/libopenage/gamedata/string_resource_dummy.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - -#pragma once - -#include -#include -#include -#include "util/csv.h" - - - -namespace openage { -namespace gamedata { - -/** - * string id/language to text mapping, extracted from language.dll file. - */ -struct string_resource { - int32_t id; - std::string lang; - std::string text; - static constexpr size_t member_count = 3; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -} // gamedata -} // openage diff --git a/libopenage/gamedata/tech_dummy.cpp b/libopenage/gamedata/tech_dummy.cpp deleted file mode 100644 index f2697695db..0000000000 --- a/libopenage/gamedata/tech_dummy.cpp +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - - -#include -#include -#include "error/error.h" -#include "tech_dummy.h" -#include "util/strings.h" - - -namespace openage { -namespace gamedata { - -constexpr size_t age_tech_tree::member_count; -constexpr size_t building_connection::member_count; -constexpr size_t effect_bundle::member_count; -constexpr size_t other_connection::member_count; -constexpr size_t research_connection::member_count; -constexpr size_t tech_effect::member_count; -constexpr size_t unit_connection::member_count; -int age_tech_tree::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', age_tech_tree::member_count - ); - - if (buf.size() != age_tech_tree::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing age_tech_tree led to " - << buf.size() - << " columns (expected " - << age_tech_tree::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%d", &this->id) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hhd", &this->status) != 1) { return 1; } - if (sscanf(buf[5].c_str(), "%d", &this->connected_slots_used) != 1) { return 5; } - this->other_connections.filename = buf[7]; - if (sscanf(buf[8].c_str(), "%hhd", &this->building_level_count) != 1) { return 8; } - if (sscanf(buf[11].c_str(), "%hhd", &this->max_age_length) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%d", &this->line_mode) != 1) { return 12; } - - return -1; -} - -bool age_tech_tree::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->other_connections.read(storage, basedir); - - return true; -} - -int building_connection::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', building_connection::member_count - ); - - if (buf.size() != building_connection::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing building_connection led to " - << buf.size() - << " columns (expected " - << building_connection::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%d", &this->id) != 1) { return 0; } - if (sscanf(buf[4].c_str(), "%d", &this->connected_slots_used) != 1) { return 4; } - this->other_connections.filename = buf[6]; - if (sscanf(buf[7].c_str(), "%hhd", &this->location_in_age) != 1) { return 7; } - if (sscanf(buf[10].c_str(), "%d", &this->line_mode) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%d", &this->enabling_research) != 1) { return 11; } - - return -1; -} - -bool building_connection::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->other_connections.read(storage, basedir); - - return true; -} - -int effect_bundle::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', effect_bundle::member_count - ); - - if (buf.size() != effect_bundle::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing effect_bundle led to " - << buf.size() - << " columns (expected " - << effect_bundle::member_count - << ")!" - ); - } - - this->name = buf[0]; - this->effects.filename = buf[1]; - - return -1; -} - -bool effect_bundle::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->effects.read(storage, basedir); - - return true; -} - -int other_connection::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', other_connection::member_count - ); - - if (buf.size() != other_connection::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing other_connection led to " - << buf.size() - << " columns (expected " - << other_connection::member_count - << ")!" - ); - } - - // parse enum connection_mode - if (buf[0] == "DUMMY") { - this->other_connection = connection_mode::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[0] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - - return -1; -} - -bool other_connection::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -int research_connection::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', research_connection::member_count - ); - - if (buf.size() != research_connection::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing research_connection led to " - << buf.size() - << " columns (expected " - << research_connection::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%d", &this->id) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hhd", &this->status) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%d", &this->upper_building) != 1) { return 2; } - if (sscanf(buf[6].c_str(), "%d", &this->connected_slots_used) != 1) { return 6; } - this->other_connections.filename = buf[8]; - if (sscanf(buf[9].c_str(), "%d", &this->vertical_line) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%d", &this->location_in_age) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%d", &this->line_mode) != 1) { return 11; } - - return -1; -} - -bool research_connection::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->other_connections.read(storage, basedir); - - return true; -} - -int tech_effect::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', tech_effect::member_count - ); - - if (buf.size() != tech_effect::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing tech_effect led to " - << buf.size() - << " columns (expected " - << tech_effect::member_count - << ")!" - ); - } - - // parse enum effect_apply_type - if (buf[0] == "DUMMY") { - this->type_id = effect_apply_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[0] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[1].c_str(), "%hd", &this->attr_a) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hd", &this->attr_b) != 1) { return 2; } - if (sscanf(buf[3].c_str(), "%hd", &this->attr_c) != 1) { return 3; } - if (sscanf(buf[4].c_str(), "%f", &this->attr_d) != 1) { return 4; } - - return -1; -} - -bool tech_effect::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -int unit_connection::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', unit_connection::member_count - ); - - if (buf.size() != unit_connection::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing unit_connection led to " - << buf.size() - << " columns (expected " - << unit_connection::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%d", &this->id) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hhd", &this->status) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%d", &this->upper_building) != 1) { return 2; } - if (sscanf(buf[3].c_str(), "%d", &this->connected_slots_used) != 1) { return 3; } - this->other_connections.filename = buf[5]; - if (sscanf(buf[6].c_str(), "%d", &this->vertical_line) != 1) { return 6; } - if (sscanf(buf[8].c_str(), "%d", &this->location_in_age) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%d", &this->required_research) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%d", &this->line_mode) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%d", &this->enabling_research) != 1) { return 11; } - - return -1; -} - -bool unit_connection::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->other_connections.read(storage, basedir); - - return true; -} - -} // gamedata -} // openage diff --git a/libopenage/gamedata/tech_dummy.h b/libopenage/gamedata/tech_dummy.h deleted file mode 100644 index bac2cc13ff..0000000000 --- a/libopenage/gamedata/tech_dummy.h +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - -#pragma once - -#include -#include -#include -#include "util/csv.h" - - - -namespace openage { -namespace gamedata { - -enum class connection_mode { - DUMMY -}; - - -enum class effect_apply_type { - DUMMY -}; - - -/** - * misc connection for a building/unit/research connection - */ -struct other_connection { - connection_mode other_connection; - static constexpr size_t member_count = 1; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * items available when this age was reached. - */ -struct age_tech_tree { - int32_t id; - int8_t status; - int32_t connected_slots_used; - openage::util::csv_subdata other_connections; - int8_t building_level_count; - int8_t max_age_length; - int32_t line_mode; - static constexpr size_t member_count = 13; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * new available buildings/units/researches when this building was created. - */ -struct building_connection { - int32_t id; - int32_t connected_slots_used; - openage::util::csv_subdata other_connections; - int8_t location_in_age; - int32_t line_mode; - int32_t enabling_research; - static constexpr size_t member_count = 12; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * applied effect for a research technology. - */ -struct tech_effect { - effect_apply_type type_id; - int16_t attr_a; - int16_t attr_b; - int16_t attr_c; - float attr_d; - static constexpr size_t member_count = 5; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * a bundle of effects. - */ -struct effect_bundle { - std::string name; - openage::util::csv_subdata effects; - static constexpr size_t member_count = 2; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * research updates to apply when activating the technology. - */ -struct research_connection { - int32_t id; - int8_t status; - int32_t upper_building; - int32_t connected_slots_used; - openage::util::csv_subdata other_connections; - int32_t vertical_line; - int32_t location_in_age; - int32_t line_mode; - static constexpr size_t member_count = 12; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * unit updates to apply when activating the technology. - */ -struct unit_connection { - int32_t id; - int8_t status; - int32_t upper_building; - int32_t connected_slots_used; - openage::util::csv_subdata other_connections; - int32_t vertical_line; - int32_t location_in_age; - int32_t required_research; - int32_t line_mode; - int32_t enabling_research; - static constexpr size_t member_count = 12; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -} // gamedata -} // openage diff --git a/libopenage/gamedata/terrain_dummy.cpp b/libopenage/gamedata/terrain_dummy.cpp deleted file mode 100644 index d99f430a4f..0000000000 --- a/libopenage/gamedata/terrain_dummy.cpp +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - - -#include -#include -#include "error/error.h" -#include "terrain_dummy.h" -#include "util/strings.h" - - -namespace openage { -namespace gamedata { - -constexpr size_t frame_data::member_count; -constexpr size_t terrain_animation::member_count; -constexpr size_t terrain_border::member_count; -constexpr size_t terrain_pass_graphic::member_count; -constexpr size_t terrain_restriction::member_count; -constexpr size_t terrain_type::member_count; -constexpr size_t tile_size::member_count; -int frame_data::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', frame_data::member_count - ); - - if (buf.size() != frame_data::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing frame_data led to " - << buf.size() - << " columns (expected " - << frame_data::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->frame_count) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hd", &this->angle_count) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hd", &this->shape_id) != 1) { return 2; } - - return -1; -} - -bool frame_data::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -int terrain_animation::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', terrain_animation::member_count - ); - - if (buf.size() != terrain_animation::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing terrain_animation led to " - << buf.size() - << " columns (expected " - << terrain_animation::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hhd", &this->is_animated) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hd", &this->animation_frame_count) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hd", &this->pause_frame_count) != 1) { return 2; } - if (sscanf(buf[3].c_str(), "%f", &this->interval) != 1) { return 3; } - if (sscanf(buf[4].c_str(), "%f", &this->pause_between_loops) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%hd", &this->frame) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%hd", &this->draw_frame) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%f", &this->animate_last) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%hhd", &this->frame_changed) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hhd", &this->drawn) != 1) { return 9; } - - return -1; -} - -bool terrain_animation::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -int terrain_border::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', terrain_border::member_count - ); - - if (buf.size() != terrain_border::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing terrain_border led to " - << buf.size() - << " columns (expected " - << terrain_border::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hhd", &this->enabled) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hhd", &this->random) != 1) { return 1; } - this->internal_name = buf[2]; - this->filename = buf[3]; - if (sscanf(buf[4].c_str(), "%d", &this->slp_id) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%d", &this->shape_ptr) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%d", &this->sound_id) != 1) { return 6; } - if (sscanf(buf[8].c_str(), "%hhd", &this->is_animated) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hd", &this->animation_frame_count) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%hd", &this->pause_frame_count) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%f", &this->interval) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%f", &this->pause_between_loops) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%hd", &this->frame) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%hd", &this->draw_frame) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%f", &this->animate_last) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%hhd", &this->frame_changed) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%hhd", &this->drawn) != 1) { return 17; } - this->frames.filename = buf[18]; - if (sscanf(buf[19].c_str(), "%hd", &this->draw_tile) != 1) { return 19; } - if (sscanf(buf[20].c_str(), "%hd", &this->underlay_terrain) != 1) { return 20; } - if (sscanf(buf[21].c_str(), "%hd", &this->border_style) != 1) { return 21; } - - return -1; -} - -bool terrain_border::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->frames.read(storage, basedir); - - return true; -} - -int terrain_pass_graphic::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', terrain_pass_graphic::member_count - ); - - if (buf.size() != terrain_pass_graphic::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing terrain_pass_graphic led to " - << buf.size() - << " columns (expected " - << terrain_pass_graphic::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%d", &this->slp_id_exit_tile) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%d", &this->slp_id_enter_tile) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%d", &this->slp_id_walk_tile) != 1) { return 2; } - if (sscanf(buf[3].c_str(), "%d", &this->replication_amount) != 1) { return 3; } - - return -1; -} - -bool terrain_pass_graphic::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -int terrain_restriction::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', terrain_restriction::member_count - ); - - if (buf.size() != terrain_restriction::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing terrain_restriction led to " - << buf.size() - << " columns (expected " - << terrain_restriction::member_count - << ")!" - ); - } - - this->pass_graphics.filename = buf[1]; - - return -1; -} - -bool terrain_restriction::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->pass_graphics.read(storage, basedir); - - return true; -} - -int terrain_type::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', terrain_type::member_count - ); - - if (buf.size() != terrain_type::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing terrain_type led to " - << buf.size() - << " columns (expected " - << terrain_type::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hhd", &this->enabled) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hhd", &this->random) != 1) { return 1; } - this->internal_name = buf[2]; - this->filename = buf[3]; - if (sscanf(buf[4].c_str(), "%d", &this->slp_id) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%d", &this->shape_ptr) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%d", &this->sound_id) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%d", &this->blend_priority) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%d", &this->blend_mode) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hhu", &this->map_color_hi) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%hhu", &this->map_color_med) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%hhu", &this->map_color_low) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%hhu", &this->map_color_cliff_lt) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%hhu", &this->map_color_cliff_rt) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%hhd", &this->passable_terrain) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%hhd", &this->impassable_terrain) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%hhd", &this->is_animated) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%hd", &this->animation_frame_count) != 1) { return 17; } - if (sscanf(buf[18].c_str(), "%hd", &this->pause_frame_count) != 1) { return 18; } - if (sscanf(buf[19].c_str(), "%f", &this->interval) != 1) { return 19; } - if (sscanf(buf[20].c_str(), "%f", &this->pause_between_loops) != 1) { return 20; } - if (sscanf(buf[21].c_str(), "%hd", &this->frame) != 1) { return 21; } - if (sscanf(buf[22].c_str(), "%hd", &this->draw_frame) != 1) { return 22; } - if (sscanf(buf[23].c_str(), "%f", &this->animate_last) != 1) { return 23; } - if (sscanf(buf[24].c_str(), "%hhd", &this->frame_changed) != 1) { return 24; } - if (sscanf(buf[25].c_str(), "%hhd", &this->drawn) != 1) { return 25; } - this->elevation_graphics.filename = buf[26]; - if (sscanf(buf[27].c_str(), "%hd", &this->terrain_replacement_id) != 1) { return 27; } - if (sscanf(buf[28].c_str(), "%hd", &this->terrain_to_draw0) != 1) { return 28; } - if (sscanf(buf[29].c_str(), "%hd", &this->terrain_to_draw1) != 1) { return 29; } - if (sscanf(buf[34].c_str(), "%hd", &this->terrain_units_used_count) != 1) { return 34; } - - return -1; -} - -bool terrain_type::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->elevation_graphics.read(storage, basedir); - - return true; -} - -int tile_size::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', tile_size::member_count - ); - - if (buf.size() != tile_size::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing tile_size led to " - << buf.size() - << " columns (expected " - << tile_size::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->width) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hd", &this->height) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hd", &this->delta_z) != 1) { return 2; } - - return -1; -} - -bool tile_size::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -} // gamedata -} // openage diff --git a/libopenage/gamedata/terrain_dummy.h b/libopenage/gamedata/terrain_dummy.h deleted file mode 100644 index 6985296ed0..0000000000 --- a/libopenage/gamedata/terrain_dummy.h +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - -#pragma once - -#include -#include -#include -#include "util/csv.h" - - - -namespace openage { -namespace gamedata { - -/** - * specification of terrain frames. - */ -struct frame_data { - int16_t frame_count; - int16_t angle_count; - int16_t shape_id; - static constexpr size_t member_count = 3; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * describes animation properties of a terrain type - */ -struct terrain_animation { - int8_t is_animated; - int16_t animation_frame_count; - int16_t pause_frame_count; - float interval; - float pause_between_loops; - int16_t frame; - int16_t draw_frame; - float animate_last; - int8_t frame_changed; - int8_t drawn; - static constexpr size_t member_count = 10; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -struct terrain_pass_graphic { - int32_t slp_id_exit_tile; - int32_t slp_id_enter_tile; - int32_t slp_id_walk_tile; - int32_t replication_amount; - static constexpr size_t member_count = 4; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * size definition of one terrain tile. - */ -struct tile_size { - int16_t width; - int16_t height; - int16_t delta_z; - static constexpr size_t member_count = 3; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * TODO - */ -struct terrain_restriction { - openage::util::csv_subdata pass_graphics; - static constexpr size_t member_count = 2; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * one inter-terraintile border specification. - */ -struct terrain_border : terrain_animation { - int8_t enabled; - int8_t random; - std::string internal_name; - std::string filename; - int32_t slp_id; - int32_t shape_ptr; - int32_t sound_id; - openage::util::csv_subdata frames; - int16_t draw_tile; - int16_t underlay_terrain; - int16_t border_style; - static constexpr size_t member_count = 22; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * describes a terrain type, like water, ice, etc. - */ -struct terrain_type : terrain_animation { - int8_t enabled; - int8_t random; - std::string internal_name; - std::string filename; - int32_t slp_id; - int32_t shape_ptr; - int32_t sound_id; - int32_t blend_priority; - int32_t blend_mode; - uint8_t map_color_hi; - uint8_t map_color_med; - uint8_t map_color_low; - uint8_t map_color_cliff_lt; - uint8_t map_color_cliff_rt; - int8_t passable_terrain; - int8_t impassable_terrain; - openage::util::csv_subdata elevation_graphics; - int16_t terrain_replacement_id; - int16_t terrain_to_draw0; - int16_t terrain_to_draw1; - int16_t terrain_units_used_count; - static constexpr size_t member_count = 35; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -} // gamedata -} // openage diff --git a/libopenage/gamedata/texture_dummy.cpp b/libopenage/gamedata/texture_dummy.cpp deleted file mode 100644 index 6d599c663b..0000000000 --- a/libopenage/gamedata/texture_dummy.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - - -#include -#include -#include "error/error.h" -#include "texture_dummy.h" -#include "util/strings.h" - - -namespace openage { -namespace gamedata { - -constexpr size_t subtexture::member_count; -int subtexture::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', subtexture::member_count - ); - - if (buf.size() != subtexture::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing subtexture led to " - << buf.size() - << " columns (expected " - << subtexture::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%d", &this->x) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%d", &this->y) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%d", &this->w) != 1) { return 2; } - if (sscanf(buf[3].c_str(), "%d", &this->h) != 1) { return 3; } - if (sscanf(buf[4].c_str(), "%d", &this->cx) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%d", &this->cy) != 1) { return 5; } - - return -1; -} - -bool subtexture::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -} // gamedata -} // openage diff --git a/libopenage/gamedata/texture_dummy.h b/libopenage/gamedata/texture_dummy.h deleted file mode 100644 index 9ac92d4e3e..0000000000 --- a/libopenage/gamedata/texture_dummy.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - -#pragma once - -#include -#include -#include -#include "util/csv.h" - - - -namespace openage { -namespace gamedata { - -/** - * one sprite, as part of a texture atlas. - * - * this struct stores information about positions and sizes - * of sprites included in the 'big texture'. - */ -struct subtexture { - int32_t x; - int32_t y; - int32_t w; - int32_t h; - int32_t cx; - int32_t cy; - static constexpr size_t member_count = 6; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -} // gamedata -} // openage diff --git a/libopenage/gamedata/unit_dummy.cpp b/libopenage/gamedata/unit_dummy.cpp deleted file mode 100644 index 190e6774a3..0000000000 --- a/libopenage/gamedata/unit_dummy.cpp +++ /dev/null @@ -1,2820 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - - -#include -#include -#include "error/error.h" -#include "unit_dummy.h" -#include "util/strings.h" - - -namespace openage { -namespace gamedata { - -constexpr size_t action_unit::member_count; -constexpr size_t animated_unit::member_count; -constexpr size_t building_annex::member_count; -constexpr size_t building_unit::member_count; -constexpr size_t damage_graphic::member_count; -constexpr size_t doppelganger_unit::member_count; -constexpr size_t hit_type::member_count; -constexpr size_t living_unit::member_count; -constexpr size_t missile_unit::member_count; -constexpr size_t moving_unit::member_count; -constexpr size_t projectile_unit::member_count; -constexpr size_t resource_cost::member_count; -constexpr size_t resource_storage::member_count; -constexpr size_t tree_unit::member_count; -constexpr size_t unit_command::member_count; -constexpr size_t unit_header::member_count; -constexpr size_t unit_object::member_count; -int action_unit::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', action_unit::member_count - ); - - if (buf.size() != action_unit::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing action_unit led to " - << buf.size() - << " columns (expected " - << action_unit::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->id0) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hu", &this->language_dll_name) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hu", &this->language_dll_creation) != 1) { return 2; } - // parse enum unit_classes - if (buf[3] == "DUMMY") { - this->unit_class = unit_classes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[3] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[4].c_str(), "%hd", &this->idle_graphic0) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%hd", &this->idle_graphic1) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%hd", &this->dying_graphic) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%hd", &this->undead_graphic) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%hhd", &this->death_mode) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hd", &this->hit_points) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%f", &this->line_of_sight) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%hhd", &this->garrison_capacity) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%f", &this->radius_x) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%f", &this->radius_y) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%f", &this->radius_z) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%hd", &this->train_sound_id) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%hd", &this->damage_sound_id) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%hd", &this->dead_unit_id) != 1) { return 17; } - if (sscanf(buf[18].c_str(), "%hhd", &this->placement_mode) != 1) { return 18; } - if (sscanf(buf[19].c_str(), "%hhd", &this->can_be_built_on) != 1) { return 19; } - if (sscanf(buf[20].c_str(), "%hd", &this->icon_id) != 1) { return 20; } - if (sscanf(buf[21].c_str(), "%hhd", &this->hidden_in_editor) != 1) { return 21; } - if (sscanf(buf[22].c_str(), "%hd", &this->old_portrait_icon_id) != 1) { return 22; } - if (sscanf(buf[23].c_str(), "%hhd", &this->enabled) != 1) { return 23; } - if (sscanf(buf[24].c_str(), "%hd", &this->placement_side_terrain0) != 1) { return 24; } - if (sscanf(buf[25].c_str(), "%hd", &this->placement_side_terrain1) != 1) { return 25; } - if (sscanf(buf[26].c_str(), "%hd", &this->placement_terrain0) != 1) { return 26; } - if (sscanf(buf[27].c_str(), "%hd", &this->placement_terrain1) != 1) { return 27; } - if (sscanf(buf[28].c_str(), "%f", &this->clearance_size_x) != 1) { return 28; } - if (sscanf(buf[29].c_str(), "%f", &this->clearance_size_y) != 1) { return 29; } - // parse enum elevation_modes - if (buf[30] == "DUMMY") { - this->elevation_mode = elevation_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[30] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum fog_visibility - if (buf[31] == "DUMMY") { - this->visible_in_fog = fog_visibility::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[31] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum ground_type - if (buf[32] == "DUMMY") { - this->terrain_restriction = ground_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[32] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[33].c_str(), "%hhd", &this->fly_mode) != 1) { return 33; } - if (sscanf(buf[34].c_str(), "%hd", &this->resource_capacity) != 1) { return 34; } - if (sscanf(buf[35].c_str(), "%f", &this->resource_decay) != 1) { return 35; } - // parse enum blast_types - if (buf[36] == "DUMMY") { - this->blast_defense_level = blast_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[36] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum combat_levels - if (buf[37] == "DUMMY") { - this->combat_level = combat_levels::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[37] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum interaction_modes - if (buf[38] == "DUMMY") { - this->interaction_mode = interaction_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[38] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum minimap_modes - if (buf[39] == "DUMMY") { - this->map_draw_level = minimap_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[39] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum command_attributes - if (buf[40] == "DUMMY") { - this->unit_level = command_attributes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[40] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[41].c_str(), "%f", &this->attack_reaction) != 1) { return 41; } - if (sscanf(buf[42].c_str(), "%hhd", &this->minimap_color) != 1) { return 42; } - if (sscanf(buf[43].c_str(), "%d", &this->language_dll_help) != 1) { return 43; } - if (sscanf(buf[44].c_str(), "%d", &this->language_dll_hotkey_text) != 1) { return 44; } - if (sscanf(buf[45].c_str(), "%d", &this->hot_keys) != 1) { return 45; } - if (sscanf(buf[46].c_str(), "%hhd", &this->recyclable) != 1) { return 46; } - if (sscanf(buf[47].c_str(), "%hhd", &this->enable_auto_gather) != 1) { return 47; } - if (sscanf(buf[48].c_str(), "%hhd", &this->doppelgaenger_on_death) != 1) { return 48; } - if (sscanf(buf[49].c_str(), "%hhd", &this->resource_gather_drop) != 1) { return 49; } - if (sscanf(buf[50].c_str(), "%hhu", &this->occlusion_mode) != 1) { return 50; } - // parse enum obstruction_types - if (buf[51] == "DUMMY") { - this->obstruction_type = obstruction_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[51] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[52].c_str(), "%hhd", &this->obstruction_class) != 1) { return 52; } - if (sscanf(buf[53].c_str(), "%hhu", &this->trait) != 1) { return 53; } - if (sscanf(buf[54].c_str(), "%hhd", &this->civilization_id) != 1) { return 54; } - if (sscanf(buf[55].c_str(), "%hd", &this->attribute_piece) != 1) { return 55; } - // parse enum selection_effects - if (buf[56] == "DUMMY") { - this->selection_effect = selection_effects::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[56] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[65].c_str(), "%hhd", &this->convert_terrain) != 1) { return 65; } - this->name = buf[66]; - if (sscanf(buf[67].c_str(), "%hd", &this->id1) != 1) { return 67; } - if (sscanf(buf[68].c_str(), "%hd", &this->id2) != 1) { return 68; } - if (sscanf(buf[69].c_str(), "%f", &this->speed) != 1) { return 69; } - if (sscanf(buf[70].c_str(), "%hd", &this->move_graphics) != 1) { return 70; } - if (sscanf(buf[71].c_str(), "%hd", &this->run_graphics) != 1) { return 71; } - if (sscanf(buf[72].c_str(), "%f", &this->turn_speed) != 1) { return 72; } - if (sscanf(buf[73].c_str(), "%hhd", &this->old_size_class) != 1) { return 73; } - if (sscanf(buf[74].c_str(), "%hd", &this->trail_unit_id) != 1) { return 74; } - if (sscanf(buf[75].c_str(), "%hhu", &this->trail_opsions) != 1) { return 75; } - if (sscanf(buf[76].c_str(), "%f", &this->trail_spacing) != 1) { return 76; } - if (sscanf(buf[77].c_str(), "%hhd", &this->old_move_algorithm) != 1) { return 77; } - if (sscanf(buf[78].c_str(), "%f", &this->turn_radius) != 1) { return 78; } - if (sscanf(buf[79].c_str(), "%f", &this->turn_radius_speed) != 1) { return 79; } - if (sscanf(buf[80].c_str(), "%f", &this->max_yaw_per_sec_moving) != 1) { return 80; } - if (sscanf(buf[81].c_str(), "%f", &this->stationary_yaw_revolution_time) != 1) { return 81; } - if (sscanf(buf[82].c_str(), "%f", &this->max_yaw_per_sec_stationary) != 1) { return 82; } - if (sscanf(buf[83].c_str(), "%hd", &this->default_task_id) != 1) { return 83; } - if (sscanf(buf[84].c_str(), "%f", &this->search_radius) != 1) { return 84; } - if (sscanf(buf[85].c_str(), "%f", &this->work_rate) != 1) { return 85; } - if (sscanf(buf[87].c_str(), "%hhd", &this->task_group) != 1) { return 87; } - if (sscanf(buf[88].c_str(), "%hd", &this->command_sound_id) != 1) { return 88; } - if (sscanf(buf[89].c_str(), "%hd", &this->stop_sound_id) != 1) { return 89; } - if (sscanf(buf[90].c_str(), "%hhd", &this->run_pattern) != 1) { return 90; } - - return -1; -} - -bool action_unit::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->resource_storage.read(storage, basedir); - this->damage_graphics.read(storage, basedir); - - return true; -} - -int animated_unit::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', animated_unit::member_count - ); - - if (buf.size() != animated_unit::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing animated_unit led to " - << buf.size() - << " columns (expected " - << animated_unit::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->id0) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hu", &this->language_dll_name) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hu", &this->language_dll_creation) != 1) { return 2; } - // parse enum unit_classes - if (buf[3] == "DUMMY") { - this->unit_class = unit_classes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[3] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[4].c_str(), "%hd", &this->idle_graphic0) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%hd", &this->idle_graphic1) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%hd", &this->dying_graphic) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%hd", &this->undead_graphic) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%hhd", &this->death_mode) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hd", &this->hit_points) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%f", &this->line_of_sight) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%hhd", &this->garrison_capacity) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%f", &this->radius_x) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%f", &this->radius_y) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%f", &this->radius_z) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%hd", &this->train_sound_id) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%hd", &this->damage_sound_id) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%hd", &this->dead_unit_id) != 1) { return 17; } - if (sscanf(buf[18].c_str(), "%hhd", &this->placement_mode) != 1) { return 18; } - if (sscanf(buf[19].c_str(), "%hhd", &this->can_be_built_on) != 1) { return 19; } - if (sscanf(buf[20].c_str(), "%hd", &this->icon_id) != 1) { return 20; } - if (sscanf(buf[21].c_str(), "%hhd", &this->hidden_in_editor) != 1) { return 21; } - if (sscanf(buf[22].c_str(), "%hd", &this->old_portrait_icon_id) != 1) { return 22; } - if (sscanf(buf[23].c_str(), "%hhd", &this->enabled) != 1) { return 23; } - if (sscanf(buf[24].c_str(), "%hd", &this->placement_side_terrain0) != 1) { return 24; } - if (sscanf(buf[25].c_str(), "%hd", &this->placement_side_terrain1) != 1) { return 25; } - if (sscanf(buf[26].c_str(), "%hd", &this->placement_terrain0) != 1) { return 26; } - if (sscanf(buf[27].c_str(), "%hd", &this->placement_terrain1) != 1) { return 27; } - if (sscanf(buf[28].c_str(), "%f", &this->clearance_size_x) != 1) { return 28; } - if (sscanf(buf[29].c_str(), "%f", &this->clearance_size_y) != 1) { return 29; } - // parse enum elevation_modes - if (buf[30] == "DUMMY") { - this->elevation_mode = elevation_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[30] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum fog_visibility - if (buf[31] == "DUMMY") { - this->visible_in_fog = fog_visibility::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[31] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum ground_type - if (buf[32] == "DUMMY") { - this->terrain_restriction = ground_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[32] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[33].c_str(), "%hhd", &this->fly_mode) != 1) { return 33; } - if (sscanf(buf[34].c_str(), "%hd", &this->resource_capacity) != 1) { return 34; } - if (sscanf(buf[35].c_str(), "%f", &this->resource_decay) != 1) { return 35; } - // parse enum blast_types - if (buf[36] == "DUMMY") { - this->blast_defense_level = blast_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[36] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum combat_levels - if (buf[37] == "DUMMY") { - this->combat_level = combat_levels::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[37] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum interaction_modes - if (buf[38] == "DUMMY") { - this->interaction_mode = interaction_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[38] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum minimap_modes - if (buf[39] == "DUMMY") { - this->map_draw_level = minimap_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[39] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum command_attributes - if (buf[40] == "DUMMY") { - this->unit_level = command_attributes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[40] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[41].c_str(), "%f", &this->attack_reaction) != 1) { return 41; } - if (sscanf(buf[42].c_str(), "%hhd", &this->minimap_color) != 1) { return 42; } - if (sscanf(buf[43].c_str(), "%d", &this->language_dll_help) != 1) { return 43; } - if (sscanf(buf[44].c_str(), "%d", &this->language_dll_hotkey_text) != 1) { return 44; } - if (sscanf(buf[45].c_str(), "%d", &this->hot_keys) != 1) { return 45; } - if (sscanf(buf[46].c_str(), "%hhd", &this->recyclable) != 1) { return 46; } - if (sscanf(buf[47].c_str(), "%hhd", &this->enable_auto_gather) != 1) { return 47; } - if (sscanf(buf[48].c_str(), "%hhd", &this->doppelgaenger_on_death) != 1) { return 48; } - if (sscanf(buf[49].c_str(), "%hhd", &this->resource_gather_drop) != 1) { return 49; } - if (sscanf(buf[50].c_str(), "%hhu", &this->occlusion_mode) != 1) { return 50; } - // parse enum obstruction_types - if (buf[51] == "DUMMY") { - this->obstruction_type = obstruction_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[51] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[52].c_str(), "%hhd", &this->obstruction_class) != 1) { return 52; } - if (sscanf(buf[53].c_str(), "%hhu", &this->trait) != 1) { return 53; } - if (sscanf(buf[54].c_str(), "%hhd", &this->civilization_id) != 1) { return 54; } - if (sscanf(buf[55].c_str(), "%hd", &this->attribute_piece) != 1) { return 55; } - // parse enum selection_effects - if (buf[56] == "DUMMY") { - this->selection_effect = selection_effects::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[56] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[57].c_str(), "%f", &this->selection_shape_x) != 1) { return 57; } - if (sscanf(buf[58].c_str(), "%f", &this->selection_shape_y) != 1) { return 58; } - if (sscanf(buf[59].c_str(), "%f", &this->selection_shape_z) != 1) { return 59; } - this->resource_storage.filename = buf[60]; - this->damage_graphics.filename = buf[61]; - if (sscanf(buf[62].c_str(), "%hd", &this->selection_sound_id) != 1) { return 62; } - if (sscanf(buf[63].c_str(), "%hd", &this->dying_sound_id) != 1) { return 63; } - // parse enum attack_modes - if (buf[64] == "DUMMY") { - this->old_attack_mode = attack_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[64] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[65].c_str(), "%hhd", &this->convert_terrain) != 1) { return 65; } - this->name = buf[66]; - if (sscanf(buf[67].c_str(), "%hd", &this->id1) != 1) { return 67; } - if (sscanf(buf[68].c_str(), "%hd", &this->id2) != 1) { return 68; } - if (sscanf(buf[69].c_str(), "%f", &this->speed) != 1) { return 69; } - - return -1; -} - -bool animated_unit::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->resource_storage.read(storage, basedir); - this->damage_graphics.read(storage, basedir); - - return true; -} - -int building_annex::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', building_annex::member_count - ); - - if (buf.size() != building_annex::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing building_annex led to " - << buf.size() - << " columns (expected " - << building_annex::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->unit_id) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%f", &this->misplaced0) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%f", &this->misplaced1) != 1) { return 2; } - - return -1; -} - -bool building_annex::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -int building_unit::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', building_unit::member_count - ); - - if (buf.size() != building_unit::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing building_unit led to " - << buf.size() - << " columns (expected " - << building_unit::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->id0) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hu", &this->language_dll_name) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hu", &this->language_dll_creation) != 1) { return 2; } - // parse enum unit_classes - if (buf[3] == "DUMMY") { - this->unit_class = unit_classes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[3] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[4].c_str(), "%hd", &this->idle_graphic0) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%hd", &this->idle_graphic1) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%hd", &this->dying_graphic) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%hd", &this->undead_graphic) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%hhd", &this->death_mode) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hd", &this->hit_points) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%f", &this->line_of_sight) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%hhd", &this->garrison_capacity) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%f", &this->radius_x) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%f", &this->radius_y) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%f", &this->radius_z) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%hd", &this->train_sound_id) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%hd", &this->damage_sound_id) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%hd", &this->dead_unit_id) != 1) { return 17; } - if (sscanf(buf[18].c_str(), "%hhd", &this->placement_mode) != 1) { return 18; } - if (sscanf(buf[19].c_str(), "%hhd", &this->can_be_built_on) != 1) { return 19; } - if (sscanf(buf[20].c_str(), "%hd", &this->icon_id) != 1) { return 20; } - if (sscanf(buf[21].c_str(), "%hhd", &this->hidden_in_editor) != 1) { return 21; } - if (sscanf(buf[22].c_str(), "%hd", &this->old_portrait_icon_id) != 1) { return 22; } - if (sscanf(buf[23].c_str(), "%hhd", &this->enabled) != 1) { return 23; } - if (sscanf(buf[24].c_str(), "%hd", &this->placement_side_terrain0) != 1) { return 24; } - if (sscanf(buf[25].c_str(), "%hd", &this->placement_side_terrain1) != 1) { return 25; } - if (sscanf(buf[26].c_str(), "%hd", &this->placement_terrain0) != 1) { return 26; } - if (sscanf(buf[27].c_str(), "%hd", &this->placement_terrain1) != 1) { return 27; } - if (sscanf(buf[28].c_str(), "%f", &this->clearance_size_x) != 1) { return 28; } - if (sscanf(buf[29].c_str(), "%f", &this->clearance_size_y) != 1) { return 29; } - // parse enum elevation_modes - if (buf[30] == "DUMMY") { - this->elevation_mode = elevation_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[30] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum fog_visibility - if (buf[31] == "DUMMY") { - this->visible_in_fog = fog_visibility::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[31] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum ground_type - if (buf[32] == "DUMMY") { - this->terrain_restriction = ground_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[32] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[33].c_str(), "%hhd", &this->fly_mode) != 1) { return 33; } - if (sscanf(buf[34].c_str(), "%hd", &this->resource_capacity) != 1) { return 34; } - if (sscanf(buf[35].c_str(), "%f", &this->resource_decay) != 1) { return 35; } - // parse enum blast_types - if (buf[36] == "DUMMY") { - this->blast_defense_level = blast_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[36] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum combat_levels - if (buf[37] == "DUMMY") { - this->combat_level = combat_levels::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[37] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum interaction_modes - if (buf[38] == "DUMMY") { - this->interaction_mode = interaction_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[38] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum minimap_modes - if (buf[39] == "DUMMY") { - this->map_draw_level = minimap_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[39] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum command_attributes - if (buf[40] == "DUMMY") { - this->unit_level = command_attributes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[40] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[41].c_str(), "%f", &this->attack_reaction) != 1) { return 41; } - if (sscanf(buf[42].c_str(), "%hhd", &this->minimap_color) != 1) { return 42; } - if (sscanf(buf[43].c_str(), "%d", &this->language_dll_help) != 1) { return 43; } - if (sscanf(buf[44].c_str(), "%d", &this->language_dll_hotkey_text) != 1) { return 44; } - if (sscanf(buf[45].c_str(), "%d", &this->hot_keys) != 1) { return 45; } - if (sscanf(buf[46].c_str(), "%hhd", &this->recyclable) != 1) { return 46; } - if (sscanf(buf[47].c_str(), "%hhd", &this->enable_auto_gather) != 1) { return 47; } - if (sscanf(buf[48].c_str(), "%hhd", &this->doppelgaenger_on_death) != 1) { return 48; } - if (sscanf(buf[49].c_str(), "%hhd", &this->resource_gather_drop) != 1) { return 49; } - if (sscanf(buf[50].c_str(), "%hhu", &this->occlusion_mode) != 1) { return 50; } - // parse enum obstruction_types - if (buf[51] == "DUMMY") { - this->obstruction_type = obstruction_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[51] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[52].c_str(), "%hhd", &this->obstruction_class) != 1) { return 52; } - if (sscanf(buf[53].c_str(), "%hhu", &this->trait) != 1) { return 53; } - if (sscanf(buf[54].c_str(), "%hhd", &this->civilization_id) != 1) { return 54; } - if (sscanf(buf[55].c_str(), "%hd", &this->attribute_piece) != 1) { return 55; } - // parse enum selection_effects - if (buf[56] == "DUMMY") { - this->selection_effect = selection_effects::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[56] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[57].c_str(), "%f", &this->selection_shape_x) != 1) { return 57; } - if (sscanf(buf[58].c_str(), "%f", &this->selection_shape_y) != 1) { return 58; } - if (sscanf(buf[59].c_str(), "%f", &this->selection_shape_z) != 1) { return 59; } - this->resource_storage.filename = buf[60]; - this->damage_graphics.filename = buf[61]; - if (sscanf(buf[62].c_str(), "%hd", &this->selection_sound_id) != 1) { return 62; } - if (sscanf(buf[63].c_str(), "%hd", &this->dying_sound_id) != 1) { return 63; } - // parse enum attack_modes - if (buf[64] == "DUMMY") { - this->old_attack_mode = attack_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[64] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[65].c_str(), "%hhd", &this->convert_terrain) != 1) { return 65; } - this->name = buf[66]; - if (sscanf(buf[67].c_str(), "%hd", &this->id1) != 1) { return 67; } - if (sscanf(buf[68].c_str(), "%hd", &this->id2) != 1) { return 68; } - if (sscanf(buf[69].c_str(), "%f", &this->speed) != 1) { return 69; } - if (sscanf(buf[70].c_str(), "%hd", &this->move_graphics) != 1) { return 70; } - if (sscanf(buf[71].c_str(), "%hd", &this->run_graphics) != 1) { return 71; } - if (sscanf(buf[72].c_str(), "%f", &this->turn_speed) != 1) { return 72; } - if (sscanf(buf[73].c_str(), "%hhd", &this->old_size_class) != 1) { return 73; } - if (sscanf(buf[74].c_str(), "%hd", &this->trail_unit_id) != 1) { return 74; } - if (sscanf(buf[75].c_str(), "%hhu", &this->trail_opsions) != 1) { return 75; } - if (sscanf(buf[76].c_str(), "%f", &this->trail_spacing) != 1) { return 76; } - if (sscanf(buf[77].c_str(), "%hhd", &this->old_move_algorithm) != 1) { return 77; } - if (sscanf(buf[78].c_str(), "%f", &this->turn_radius) != 1) { return 78; } - if (sscanf(buf[79].c_str(), "%f", &this->turn_radius_speed) != 1) { return 79; } - if (sscanf(buf[80].c_str(), "%f", &this->max_yaw_per_sec_moving) != 1) { return 80; } - if (sscanf(buf[81].c_str(), "%f", &this->stationary_yaw_revolution_time) != 1) { return 81; } - if (sscanf(buf[82].c_str(), "%f", &this->max_yaw_per_sec_stationary) != 1) { return 82; } - if (sscanf(buf[83].c_str(), "%hd", &this->default_task_id) != 1) { return 83; } - if (sscanf(buf[84].c_str(), "%f", &this->search_radius) != 1) { return 84; } - if (sscanf(buf[85].c_str(), "%f", &this->work_rate) != 1) { return 85; } - if (sscanf(buf[87].c_str(), "%hhd", &this->task_group) != 1) { return 87; } - if (sscanf(buf[88].c_str(), "%hd", &this->command_sound_id) != 1) { return 88; } - if (sscanf(buf[89].c_str(), "%hd", &this->stop_sound_id) != 1) { return 89; } - if (sscanf(buf[90].c_str(), "%hhd", &this->run_pattern) != 1) { return 90; } - if (sscanf(buf[91].c_str(), "%hd", &this->default_armor) != 1) { return 91; } - this->attacks.filename = buf[92]; - this->armors.filename = buf[93]; - // parse enum boundary_ids - if (buf[94] == "DUMMY") { - this->boundary_id = boundary_ids::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[94] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[95].c_str(), "%f", &this->weapon_range_max) != 1) { return 95; } - if (sscanf(buf[96].c_str(), "%f", &this->blast_range) != 1) { return 96; } - if (sscanf(buf[97].c_str(), "%f", &this->attack_speed) != 1) { return 97; } - if (sscanf(buf[98].c_str(), "%hd", &this->attack_projectile_primary_unit_id) != 1) { return 98; } - if (sscanf(buf[99].c_str(), "%hd", &this->accuracy) != 1) { return 99; } - if (sscanf(buf[100].c_str(), "%hhd", &this->break_off_combat) != 1) { return 100; } - if (sscanf(buf[101].c_str(), "%hd", &this->frame_delay) != 1) { return 101; } - // parse enum range_damage_type - if (buf[103] == "DUMMY") { - this->blast_level_offence = range_damage_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[103] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[104].c_str(), "%f", &this->weapon_range_min) != 1) { return 104; } - if (sscanf(buf[105].c_str(), "%f", &this->accuracy_dispersion) != 1) { return 105; } - if (sscanf(buf[106].c_str(), "%hd", &this->attack_sprite_id) != 1) { return 106; } - if (sscanf(buf[107].c_str(), "%hd", &this->melee_armor_displayed) != 1) { return 107; } - if (sscanf(buf[108].c_str(), "%hd", &this->attack_displayed) != 1) { return 108; } - if (sscanf(buf[109].c_str(), "%f", &this->range_displayed) != 1) { return 109; } - if (sscanf(buf[110].c_str(), "%f", &this->reload_time_displayed) != 1) { return 110; } - this->resource_cost.filename = buf[111]; - if (sscanf(buf[112].c_str(), "%hd", &this->creation_time) != 1) { return 112; } - if (sscanf(buf[113].c_str(), "%hd", &this->train_location_id) != 1) { return 113; } - if (sscanf(buf[114].c_str(), "%f", &this->rear_attack_modifier) != 1) { return 114; } - if (sscanf(buf[115].c_str(), "%f", &this->flank_attack_modifier) != 1) { return 115; } - // parse enum creatable_types - if (buf[116] == "DUMMY") { - this->creatable_type = creatable_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[116] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[117].c_str(), "%hhd", &this->hero_mode) != 1) { return 117; } - if (sscanf(buf[118].c_str(), "%d", &this->garrison_graphic) != 1) { return 118; } - if (sscanf(buf[119].c_str(), "%f", &this->attack_projectile_count) != 1) { return 119; } - if (sscanf(buf[120].c_str(), "%hhd", &this->attack_projectile_max_count) != 1) { return 120; } - if (sscanf(buf[121].c_str(), "%f", &this->attack_projectile_spawning_area_width) != 1) { return 121; } - if (sscanf(buf[122].c_str(), "%f", &this->attack_projectile_spawning_area_length) != 1) { return 122; } - if (sscanf(buf[123].c_str(), "%f", &this->attack_projectile_spawning_area_randomness) != 1) { return 123; } - if (sscanf(buf[124].c_str(), "%d", &this->attack_projectile_secondary_unit_id) != 1) { return 124; } - if (sscanf(buf[125].c_str(), "%d", &this->special_graphic_id) != 1) { return 125; } - if (sscanf(buf[126].c_str(), "%hhd", &this->special_activation) != 1) { return 126; } - if (sscanf(buf[127].c_str(), "%hd", &this->pierce_armor_displayed) != 1) { return 127; } - if (sscanf(buf[128].c_str(), "%hd", &this->construction_graphic_id) != 1) { return 128; } - if (sscanf(buf[129].c_str(), "%hd", &this->snow_graphic_id) != 1) { return 129; } - if (sscanf(buf[130].c_str(), "%hhd", &this->adjacent_mode) != 1) { return 130; } - if (sscanf(buf[131].c_str(), "%hd", &this->graphics_angle) != 1) { return 131; } - if (sscanf(buf[132].c_str(), "%hhd", &this->disappears_when_built) != 1) { return 132; } - if (sscanf(buf[133].c_str(), "%hd", &this->stack_unit_id) != 1) { return 133; } - if (sscanf(buf[134].c_str(), "%hd", &this->foundation_terrain_id) != 1) { return 134; } - if (sscanf(buf[135].c_str(), "%hd", &this->old_overlay_id) != 1) { return 135; } - if (sscanf(buf[136].c_str(), "%hd", &this->research_id) != 1) { return 136; } - if (sscanf(buf[137].c_str(), "%hhd", &this->can_burn) != 1) { return 137; } - this->building_annex.filename = buf[138]; - if (sscanf(buf[139].c_str(), "%hd", &this->head_unit_id) != 1) { return 139; } - if (sscanf(buf[140].c_str(), "%hd", &this->transform_unit_id) != 1) { return 140; } - if (sscanf(buf[141].c_str(), "%hd", &this->transform_sound_id) != 1) { return 141; } - if (sscanf(buf[142].c_str(), "%hd", &this->construction_sound_id) != 1) { return 142; } - // parse enum garrison_types - if (buf[143] == "DUMMY") { - this->garrison_type = garrison_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[143] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[144].c_str(), "%f", &this->garrison_heal_rate) != 1) { return 144; } - if (sscanf(buf[145].c_str(), "%f", &this->garrison_repair_rate) != 1) { return 145; } - if (sscanf(buf[146].c_str(), "%hd", &this->salvage_unit_id) != 1) { return 146; } - - return -1; -} - -bool building_unit::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->resource_storage.read(storage, basedir); - this->damage_graphics.read(storage, basedir); - this->attacks.read(storage, basedir); - this->armors.read(storage, basedir); - this->resource_cost.read(storage, basedir); - this->building_annex.read(storage, basedir); - - return true; -} - -int damage_graphic::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', damage_graphic::member_count - ); - - if (buf.size() != damage_graphic::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing damage_graphic led to " - << buf.size() - << " columns (expected " - << damage_graphic::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->graphic_id) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hhd", &this->damage_percent) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hhd", &this->old_apply_mode) != 1) { return 2; } - // parse enum damage_draw_type - if (buf[3] == "DUMMY") { - this->apply_mode = damage_draw_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[3] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - - return -1; -} - -bool damage_graphic::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -int doppelganger_unit::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', doppelganger_unit::member_count - ); - - if (buf.size() != doppelganger_unit::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing doppelganger_unit led to " - << buf.size() - << " columns (expected " - << doppelganger_unit::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->id0) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hu", &this->language_dll_name) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hu", &this->language_dll_creation) != 1) { return 2; } - // parse enum unit_classes - if (buf[3] == "DUMMY") { - this->unit_class = unit_classes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[3] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[4].c_str(), "%hd", &this->idle_graphic0) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%hd", &this->idle_graphic1) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%hd", &this->dying_graphic) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%hd", &this->undead_graphic) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%hhd", &this->death_mode) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hd", &this->hit_points) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%f", &this->line_of_sight) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%hhd", &this->garrison_capacity) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%f", &this->radius_x) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%f", &this->radius_y) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%f", &this->radius_z) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%hd", &this->train_sound_id) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%hd", &this->damage_sound_id) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%hd", &this->dead_unit_id) != 1) { return 17; } - if (sscanf(buf[18].c_str(), "%hhd", &this->placement_mode) != 1) { return 18; } - if (sscanf(buf[19].c_str(), "%hhd", &this->can_be_built_on) != 1) { return 19; } - if (sscanf(buf[20].c_str(), "%hd", &this->icon_id) != 1) { return 20; } - if (sscanf(buf[21].c_str(), "%hhd", &this->hidden_in_editor) != 1) { return 21; } - if (sscanf(buf[22].c_str(), "%hd", &this->old_portrait_icon_id) != 1) { return 22; } - if (sscanf(buf[23].c_str(), "%hhd", &this->enabled) != 1) { return 23; } - if (sscanf(buf[24].c_str(), "%hd", &this->placement_side_terrain0) != 1) { return 24; } - if (sscanf(buf[25].c_str(), "%hd", &this->placement_side_terrain1) != 1) { return 25; } - if (sscanf(buf[26].c_str(), "%hd", &this->placement_terrain0) != 1) { return 26; } - if (sscanf(buf[27].c_str(), "%hd", &this->placement_terrain1) != 1) { return 27; } - if (sscanf(buf[28].c_str(), "%f", &this->clearance_size_x) != 1) { return 28; } - if (sscanf(buf[29].c_str(), "%f", &this->clearance_size_y) != 1) { return 29; } - // parse enum elevation_modes - if (buf[30] == "DUMMY") { - this->elevation_mode = elevation_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[30] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum fog_visibility - if (buf[31] == "DUMMY") { - this->visible_in_fog = fog_visibility::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[31] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum ground_type - if (buf[32] == "DUMMY") { - this->terrain_restriction = ground_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[32] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[33].c_str(), "%hhd", &this->fly_mode) != 1) { return 33; } - if (sscanf(buf[34].c_str(), "%hd", &this->resource_capacity) != 1) { return 34; } - if (sscanf(buf[35].c_str(), "%f", &this->resource_decay) != 1) { return 35; } - // parse enum blast_types - if (buf[36] == "DUMMY") { - this->blast_defense_level = blast_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[36] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum combat_levels - if (buf[37] == "DUMMY") { - this->combat_level = combat_levels::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[37] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum interaction_modes - if (buf[38] == "DUMMY") { - this->interaction_mode = interaction_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[38] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum minimap_modes - if (buf[39] == "DUMMY") { - this->map_draw_level = minimap_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[39] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum command_attributes - if (buf[40] == "DUMMY") { - this->unit_level = command_attributes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[40] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[41].c_str(), "%f", &this->attack_reaction) != 1) { return 41; } - if (sscanf(buf[42].c_str(), "%hhd", &this->minimap_color) != 1) { return 42; } - if (sscanf(buf[43].c_str(), "%d", &this->language_dll_help) != 1) { return 43; } - if (sscanf(buf[44].c_str(), "%d", &this->language_dll_hotkey_text) != 1) { return 44; } - if (sscanf(buf[45].c_str(), "%d", &this->hot_keys) != 1) { return 45; } - if (sscanf(buf[46].c_str(), "%hhd", &this->recyclable) != 1) { return 46; } - if (sscanf(buf[47].c_str(), "%hhd", &this->enable_auto_gather) != 1) { return 47; } - if (sscanf(buf[48].c_str(), "%hhd", &this->doppelgaenger_on_death) != 1) { return 48; } - if (sscanf(buf[49].c_str(), "%hhd", &this->resource_gather_drop) != 1) { return 49; } - if (sscanf(buf[50].c_str(), "%hhu", &this->occlusion_mode) != 1) { return 50; } - // parse enum obstruction_types - if (buf[51] == "DUMMY") { - this->obstruction_type = obstruction_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[51] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[52].c_str(), "%hhd", &this->obstruction_class) != 1) { return 52; } - if (sscanf(buf[53].c_str(), "%hhu", &this->trait) != 1) { return 53; } - if (sscanf(buf[54].c_str(), "%hhd", &this->civilization_id) != 1) { return 54; } - if (sscanf(buf[55].c_str(), "%hd", &this->attribute_piece) != 1) { return 55; } - // parse enum selection_effects - if (buf[56] == "DUMMY") { - this->selection_effect = selection_effects::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[56] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[57].c_str(), "%f", &this->selection_shape_x) != 1) { return 57; } - if (sscanf(buf[58].c_str(), "%f", &this->selection_shape_y) != 1) { return 58; } - if (sscanf(buf[59].c_str(), "%f", &this->selection_shape_z) != 1) { return 59; } - this->resource_storage.filename = buf[60]; - this->damage_graphics.filename = buf[61]; - if (sscanf(buf[62].c_str(), "%hd", &this->selection_sound_id) != 1) { return 62; } - if (sscanf(buf[63].c_str(), "%hd", &this->dying_sound_id) != 1) { return 63; } - // parse enum attack_modes - if (buf[64] == "DUMMY") { - this->old_attack_mode = attack_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[64] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[65].c_str(), "%hhd", &this->convert_terrain) != 1) { return 65; } - this->name = buf[66]; - if (sscanf(buf[67].c_str(), "%hd", &this->id1) != 1) { return 67; } - if (sscanf(buf[68].c_str(), "%hd", &this->id2) != 1) { return 68; } - if (sscanf(buf[69].c_str(), "%f", &this->speed) != 1) { return 69; } - - return -1; -} - -bool doppelganger_unit::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->resource_storage.read(storage, basedir); - this->damage_graphics.read(storage, basedir); - - return true; -} - -int hit_type::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', hit_type::member_count - ); - - if (buf.size() != hit_type::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing hit_type led to " - << buf.size() - << " columns (expected " - << hit_type::member_count - << ")!" - ); - } - - // parse enum hit_class - if (buf[0] == "DUMMY") { - this->type_id = hit_class::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[0] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[1].c_str(), "%hd", &this->amount) != 1) { return 1; } - - return -1; -} - -bool hit_type::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -int living_unit::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', living_unit::member_count - ); - - if (buf.size() != living_unit::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing living_unit led to " - << buf.size() - << " columns (expected " - << living_unit::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->id0) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hu", &this->language_dll_name) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hu", &this->language_dll_creation) != 1) { return 2; } - // parse enum unit_classes - if (buf[3] == "DUMMY") { - this->unit_class = unit_classes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[3] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[4].c_str(), "%hd", &this->idle_graphic0) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%hd", &this->idle_graphic1) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%hd", &this->dying_graphic) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%hd", &this->undead_graphic) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%hhd", &this->death_mode) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hd", &this->hit_points) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%f", &this->line_of_sight) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%hhd", &this->garrison_capacity) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%f", &this->radius_x) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%f", &this->radius_y) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%f", &this->radius_z) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%hd", &this->train_sound_id) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%hd", &this->damage_sound_id) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%hd", &this->dead_unit_id) != 1) { return 17; } - if (sscanf(buf[18].c_str(), "%hhd", &this->placement_mode) != 1) { return 18; } - if (sscanf(buf[19].c_str(), "%hhd", &this->can_be_built_on) != 1) { return 19; } - if (sscanf(buf[20].c_str(), "%hd", &this->icon_id) != 1) { return 20; } - if (sscanf(buf[21].c_str(), "%hhd", &this->hidden_in_editor) != 1) { return 21; } - if (sscanf(buf[22].c_str(), "%hd", &this->old_portrait_icon_id) != 1) { return 22; } - if (sscanf(buf[23].c_str(), "%hhd", &this->enabled) != 1) { return 23; } - if (sscanf(buf[24].c_str(), "%hd", &this->placement_side_terrain0) != 1) { return 24; } - if (sscanf(buf[25].c_str(), "%hd", &this->placement_side_terrain1) != 1) { return 25; } - if (sscanf(buf[26].c_str(), "%hd", &this->placement_terrain0) != 1) { return 26; } - if (sscanf(buf[27].c_str(), "%hd", &this->placement_terrain1) != 1) { return 27; } - if (sscanf(buf[28].c_str(), "%f", &this->clearance_size_x) != 1) { return 28; } - if (sscanf(buf[29].c_str(), "%f", &this->clearance_size_y) != 1) { return 29; } - // parse enum elevation_modes - if (buf[30] == "DUMMY") { - this->elevation_mode = elevation_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[30] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum fog_visibility - if (buf[31] == "DUMMY") { - this->visible_in_fog = fog_visibility::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[31] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum ground_type - if (buf[32] == "DUMMY") { - this->terrain_restriction = ground_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[32] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[33].c_str(), "%hhd", &this->fly_mode) != 1) { return 33; } - if (sscanf(buf[34].c_str(), "%hd", &this->resource_capacity) != 1) { return 34; } - if (sscanf(buf[35].c_str(), "%f", &this->resource_decay) != 1) { return 35; } - // parse enum blast_types - if (buf[36] == "DUMMY") { - this->blast_defense_level = blast_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[36] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum combat_levels - if (buf[37] == "DUMMY") { - this->combat_level = combat_levels::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[37] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum interaction_modes - if (buf[38] == "DUMMY") { - this->interaction_mode = interaction_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[38] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum minimap_modes - if (buf[39] == "DUMMY") { - this->map_draw_level = minimap_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[39] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum command_attributes - if (buf[40] == "DUMMY") { - this->unit_level = command_attributes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[40] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[41].c_str(), "%f", &this->attack_reaction) != 1) { return 41; } - if (sscanf(buf[42].c_str(), "%hhd", &this->minimap_color) != 1) { return 42; } - if (sscanf(buf[43].c_str(), "%d", &this->language_dll_help) != 1) { return 43; } - if (sscanf(buf[44].c_str(), "%d", &this->language_dll_hotkey_text) != 1) { return 44; } - if (sscanf(buf[45].c_str(), "%d", &this->hot_keys) != 1) { return 45; } - if (sscanf(buf[46].c_str(), "%hhd", &this->recyclable) != 1) { return 46; } - if (sscanf(buf[47].c_str(), "%hhd", &this->enable_auto_gather) != 1) { return 47; } - if (sscanf(buf[48].c_str(), "%hhd", &this->doppelgaenger_on_death) != 1) { return 48; } - if (sscanf(buf[49].c_str(), "%hhd", &this->resource_gather_drop) != 1) { return 49; } - if (sscanf(buf[50].c_str(), "%hhu", &this->occlusion_mode) != 1) { return 50; } - // parse enum obstruction_types - if (buf[51] == "DUMMY") { - this->obstruction_type = obstruction_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[51] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[52].c_str(), "%hhd", &this->obstruction_class) != 1) { return 52; } - if (sscanf(buf[53].c_str(), "%hhu", &this->trait) != 1) { return 53; } - if (sscanf(buf[54].c_str(), "%hhd", &this->civilization_id) != 1) { return 54; } - if (sscanf(buf[55].c_str(), "%hd", &this->attribute_piece) != 1) { return 55; } - // parse enum selection_effects - if (buf[56] == "DUMMY") { - this->selection_effect = selection_effects::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[56] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[57].c_str(), "%f", &this->selection_shape_x) != 1) { return 57; } - if (sscanf(buf[58].c_str(), "%f", &this->selection_shape_y) != 1) { return 58; } - if (sscanf(buf[59].c_str(), "%f", &this->selection_shape_z) != 1) { return 59; } - this->resource_storage.filename = buf[60]; - this->damage_graphics.filename = buf[61]; - if (sscanf(buf[62].c_str(), "%hd", &this->selection_sound_id) != 1) { return 62; } - if (sscanf(buf[63].c_str(), "%hd", &this->dying_sound_id) != 1) { return 63; } - // parse enum attack_modes - if (buf[64] == "DUMMY") { - this->old_attack_mode = attack_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[64] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[65].c_str(), "%hhd", &this->convert_terrain) != 1) { return 65; } - this->name = buf[66]; - if (sscanf(buf[67].c_str(), "%hd", &this->id1) != 1) { return 67; } - if (sscanf(buf[68].c_str(), "%hd", &this->id2) != 1) { return 68; } - if (sscanf(buf[69].c_str(), "%f", &this->speed) != 1) { return 69; } - if (sscanf(buf[70].c_str(), "%hd", &this->move_graphics) != 1) { return 70; } - if (sscanf(buf[71].c_str(), "%hd", &this->run_graphics) != 1) { return 71; } - if (sscanf(buf[72].c_str(), "%f", &this->turn_speed) != 1) { return 72; } - if (sscanf(buf[73].c_str(), "%hhd", &this->old_size_class) != 1) { return 73; } - if (sscanf(buf[74].c_str(), "%hd", &this->trail_unit_id) != 1) { return 74; } - if (sscanf(buf[75].c_str(), "%hhu", &this->trail_opsions) != 1) { return 75; } - if (sscanf(buf[76].c_str(), "%f", &this->trail_spacing) != 1) { return 76; } - if (sscanf(buf[77].c_str(), "%hhd", &this->old_move_algorithm) != 1) { return 77; } - if (sscanf(buf[78].c_str(), "%f", &this->turn_radius) != 1) { return 78; } - if (sscanf(buf[79].c_str(), "%f", &this->turn_radius_speed) != 1) { return 79; } - if (sscanf(buf[80].c_str(), "%f", &this->max_yaw_per_sec_moving) != 1) { return 80; } - if (sscanf(buf[81].c_str(), "%f", &this->stationary_yaw_revolution_time) != 1) { return 81; } - if (sscanf(buf[82].c_str(), "%f", &this->max_yaw_per_sec_stationary) != 1) { return 82; } - if (sscanf(buf[83].c_str(), "%hd", &this->default_task_id) != 1) { return 83; } - if (sscanf(buf[84].c_str(), "%f", &this->search_radius) != 1) { return 84; } - if (sscanf(buf[85].c_str(), "%f", &this->work_rate) != 1) { return 85; } - if (sscanf(buf[87].c_str(), "%hhd", &this->task_group) != 1) { return 87; } - if (sscanf(buf[88].c_str(), "%hd", &this->command_sound_id) != 1) { return 88; } - if (sscanf(buf[89].c_str(), "%hd", &this->stop_sound_id) != 1) { return 89; } - if (sscanf(buf[90].c_str(), "%hhd", &this->run_pattern) != 1) { return 90; } - if (sscanf(buf[91].c_str(), "%hd", &this->default_armor) != 1) { return 91; } - this->attacks.filename = buf[92]; - this->armors.filename = buf[93]; - // parse enum boundary_ids - if (buf[94] == "DUMMY") { - this->boundary_id = boundary_ids::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[94] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[95].c_str(), "%f", &this->weapon_range_max) != 1) { return 95; } - if (sscanf(buf[96].c_str(), "%f", &this->blast_range) != 1) { return 96; } - if (sscanf(buf[97].c_str(), "%f", &this->attack_speed) != 1) { return 97; } - if (sscanf(buf[98].c_str(), "%hd", &this->attack_projectile_primary_unit_id) != 1) { return 98; } - if (sscanf(buf[99].c_str(), "%hd", &this->accuracy) != 1) { return 99; } - if (sscanf(buf[100].c_str(), "%hhd", &this->break_off_combat) != 1) { return 100; } - if (sscanf(buf[101].c_str(), "%hd", &this->frame_delay) != 1) { return 101; } - // parse enum range_damage_type - if (buf[103] == "DUMMY") { - this->blast_level_offence = range_damage_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[103] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[104].c_str(), "%f", &this->weapon_range_min) != 1) { return 104; } - if (sscanf(buf[105].c_str(), "%f", &this->accuracy_dispersion) != 1) { return 105; } - if (sscanf(buf[106].c_str(), "%hd", &this->attack_sprite_id) != 1) { return 106; } - if (sscanf(buf[107].c_str(), "%hd", &this->melee_armor_displayed) != 1) { return 107; } - if (sscanf(buf[108].c_str(), "%hd", &this->attack_displayed) != 1) { return 108; } - if (sscanf(buf[109].c_str(), "%f", &this->range_displayed) != 1) { return 109; } - if (sscanf(buf[110].c_str(), "%f", &this->reload_time_displayed) != 1) { return 110; } - this->resource_cost.filename = buf[111]; - if (sscanf(buf[112].c_str(), "%hd", &this->creation_time) != 1) { return 112; } - if (sscanf(buf[113].c_str(), "%hd", &this->train_location_id) != 1) { return 113; } - if (sscanf(buf[114].c_str(), "%f", &this->rear_attack_modifier) != 1) { return 114; } - if (sscanf(buf[115].c_str(), "%f", &this->flank_attack_modifier) != 1) { return 115; } - // parse enum creatable_types - if (buf[116] == "DUMMY") { - this->creatable_type = creatable_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[116] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[117].c_str(), "%hhd", &this->hero_mode) != 1) { return 117; } - if (sscanf(buf[118].c_str(), "%d", &this->garrison_graphic) != 1) { return 118; } - if (sscanf(buf[119].c_str(), "%f", &this->attack_projectile_count) != 1) { return 119; } - if (sscanf(buf[120].c_str(), "%hhd", &this->attack_projectile_max_count) != 1) { return 120; } - if (sscanf(buf[121].c_str(), "%f", &this->attack_projectile_spawning_area_width) != 1) { return 121; } - if (sscanf(buf[122].c_str(), "%f", &this->attack_projectile_spawning_area_length) != 1) { return 122; } - if (sscanf(buf[123].c_str(), "%f", &this->attack_projectile_spawning_area_randomness) != 1) { return 123; } - if (sscanf(buf[124].c_str(), "%d", &this->attack_projectile_secondary_unit_id) != 1) { return 124; } - if (sscanf(buf[125].c_str(), "%d", &this->special_graphic_id) != 1) { return 125; } - if (sscanf(buf[126].c_str(), "%hhd", &this->special_activation) != 1) { return 126; } - if (sscanf(buf[127].c_str(), "%hd", &this->pierce_armor_displayed) != 1) { return 127; } - - return -1; -} - -bool living_unit::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->resource_storage.read(storage, basedir); - this->damage_graphics.read(storage, basedir); - this->attacks.read(storage, basedir); - this->armors.read(storage, basedir); - this->resource_cost.read(storage, basedir); - - return true; -} - -int missile_unit::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', missile_unit::member_count - ); - - if (buf.size() != missile_unit::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing missile_unit led to " - << buf.size() - << " columns (expected " - << missile_unit::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->id0) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hu", &this->language_dll_name) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hu", &this->language_dll_creation) != 1) { return 2; } - // parse enum unit_classes - if (buf[3] == "DUMMY") { - this->unit_class = unit_classes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[3] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[4].c_str(), "%hd", &this->idle_graphic0) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%hd", &this->idle_graphic1) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%hd", &this->dying_graphic) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%hd", &this->undead_graphic) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%hhd", &this->death_mode) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hd", &this->hit_points) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%f", &this->line_of_sight) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%hhd", &this->garrison_capacity) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%f", &this->radius_x) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%f", &this->radius_y) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%f", &this->radius_z) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%hd", &this->train_sound_id) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%hd", &this->damage_sound_id) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%hd", &this->dead_unit_id) != 1) { return 17; } - if (sscanf(buf[18].c_str(), "%hhd", &this->placement_mode) != 1) { return 18; } - if (sscanf(buf[19].c_str(), "%hhd", &this->can_be_built_on) != 1) { return 19; } - if (sscanf(buf[20].c_str(), "%hd", &this->icon_id) != 1) { return 20; } - if (sscanf(buf[21].c_str(), "%hhd", &this->hidden_in_editor) != 1) { return 21; } - if (sscanf(buf[22].c_str(), "%hd", &this->old_portrait_icon_id) != 1) { return 22; } - if (sscanf(buf[23].c_str(), "%hhd", &this->enabled) != 1) { return 23; } - if (sscanf(buf[24].c_str(), "%hd", &this->placement_side_terrain0) != 1) { return 24; } - if (sscanf(buf[25].c_str(), "%hd", &this->placement_side_terrain1) != 1) { return 25; } - if (sscanf(buf[26].c_str(), "%hd", &this->placement_terrain0) != 1) { return 26; } - if (sscanf(buf[27].c_str(), "%hd", &this->placement_terrain1) != 1) { return 27; } - if (sscanf(buf[28].c_str(), "%f", &this->clearance_size_x) != 1) { return 28; } - if (sscanf(buf[29].c_str(), "%f", &this->clearance_size_y) != 1) { return 29; } - // parse enum elevation_modes - if (buf[30] == "DUMMY") { - this->elevation_mode = elevation_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[30] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum fog_visibility - if (buf[31] == "DUMMY") { - this->visible_in_fog = fog_visibility::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[31] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum ground_type - if (buf[32] == "DUMMY") { - this->terrain_restriction = ground_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[32] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[33].c_str(), "%hhd", &this->fly_mode) != 1) { return 33; } - if (sscanf(buf[34].c_str(), "%hd", &this->resource_capacity) != 1) { return 34; } - if (sscanf(buf[35].c_str(), "%f", &this->resource_decay) != 1) { return 35; } - // parse enum blast_types - if (buf[36] == "DUMMY") { - this->blast_defense_level = blast_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[36] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum combat_levels - if (buf[37] == "DUMMY") { - this->combat_level = combat_levels::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[37] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum interaction_modes - if (buf[38] == "DUMMY") { - this->interaction_mode = interaction_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[38] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum minimap_modes - if (buf[39] == "DUMMY") { - this->map_draw_level = minimap_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[39] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum command_attributes - if (buf[40] == "DUMMY") { - this->unit_level = command_attributes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[40] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[41].c_str(), "%f", &this->attack_reaction) != 1) { return 41; } - if (sscanf(buf[42].c_str(), "%hhd", &this->minimap_color) != 1) { return 42; } - if (sscanf(buf[43].c_str(), "%d", &this->language_dll_help) != 1) { return 43; } - if (sscanf(buf[44].c_str(), "%d", &this->language_dll_hotkey_text) != 1) { return 44; } - if (sscanf(buf[45].c_str(), "%d", &this->hot_keys) != 1) { return 45; } - if (sscanf(buf[46].c_str(), "%hhd", &this->recyclable) != 1) { return 46; } - if (sscanf(buf[47].c_str(), "%hhd", &this->enable_auto_gather) != 1) { return 47; } - if (sscanf(buf[48].c_str(), "%hhd", &this->doppelgaenger_on_death) != 1) { return 48; } - if (sscanf(buf[49].c_str(), "%hhd", &this->resource_gather_drop) != 1) { return 49; } - if (sscanf(buf[50].c_str(), "%hhu", &this->occlusion_mode) != 1) { return 50; } - // parse enum obstruction_types - if (buf[51] == "DUMMY") { - this->obstruction_type = obstruction_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[51] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[52].c_str(), "%hhd", &this->obstruction_class) != 1) { return 52; } - if (sscanf(buf[53].c_str(), "%hhu", &this->trait) != 1) { return 53; } - if (sscanf(buf[54].c_str(), "%hhd", &this->civilization_id) != 1) { return 54; } - if (sscanf(buf[55].c_str(), "%hd", &this->attribute_piece) != 1) { return 55; } - // parse enum selection_effects - if (buf[56] == "DUMMY") { - this->selection_effect = selection_effects::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[56] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[57].c_str(), "%f", &this->selection_shape_x) != 1) { return 57; } - if (sscanf(buf[58].c_str(), "%f", &this->selection_shape_y) != 1) { return 58; } - if (sscanf(buf[59].c_str(), "%f", &this->selection_shape_z) != 1) { return 59; } - this->resource_storage.filename = buf[60]; - this->damage_graphics.filename = buf[61]; - if (sscanf(buf[62].c_str(), "%hd", &this->selection_sound_id) != 1) { return 62; } - if (sscanf(buf[63].c_str(), "%hd", &this->dying_sound_id) != 1) { return 63; } - // parse enum attack_modes - if (buf[64] == "DUMMY") { - this->old_attack_mode = attack_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[64] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[65].c_str(), "%hhd", &this->convert_terrain) != 1) { return 65; } - this->name = buf[66]; - if (sscanf(buf[67].c_str(), "%hd", &this->id1) != 1) { return 67; } - if (sscanf(buf[68].c_str(), "%hd", &this->id2) != 1) { return 68; } - if (sscanf(buf[69].c_str(), "%f", &this->speed) != 1) { return 69; } - if (sscanf(buf[70].c_str(), "%hd", &this->move_graphics) != 1) { return 70; } - if (sscanf(buf[71].c_str(), "%hd", &this->run_graphics) != 1) { return 71; } - if (sscanf(buf[72].c_str(), "%f", &this->turn_speed) != 1) { return 72; } - if (sscanf(buf[73].c_str(), "%hhd", &this->old_size_class) != 1) { return 73; } - if (sscanf(buf[74].c_str(), "%hd", &this->trail_unit_id) != 1) { return 74; } - if (sscanf(buf[75].c_str(), "%hhu", &this->trail_opsions) != 1) { return 75; } - if (sscanf(buf[76].c_str(), "%f", &this->trail_spacing) != 1) { return 76; } - if (sscanf(buf[77].c_str(), "%hhd", &this->old_move_algorithm) != 1) { return 77; } - if (sscanf(buf[78].c_str(), "%f", &this->turn_radius) != 1) { return 78; } - if (sscanf(buf[79].c_str(), "%f", &this->turn_radius_speed) != 1) { return 79; } - if (sscanf(buf[80].c_str(), "%f", &this->max_yaw_per_sec_moving) != 1) { return 80; } - if (sscanf(buf[81].c_str(), "%f", &this->stationary_yaw_revolution_time) != 1) { return 81; } - if (sscanf(buf[82].c_str(), "%f", &this->max_yaw_per_sec_stationary) != 1) { return 82; } - if (sscanf(buf[83].c_str(), "%hd", &this->default_task_id) != 1) { return 83; } - if (sscanf(buf[84].c_str(), "%f", &this->search_radius) != 1) { return 84; } - if (sscanf(buf[85].c_str(), "%f", &this->work_rate) != 1) { return 85; } - if (sscanf(buf[87].c_str(), "%hhd", &this->task_group) != 1) { return 87; } - if (sscanf(buf[88].c_str(), "%hd", &this->command_sound_id) != 1) { return 88; } - if (sscanf(buf[89].c_str(), "%hd", &this->stop_sound_id) != 1) { return 89; } - if (sscanf(buf[90].c_str(), "%hhd", &this->run_pattern) != 1) { return 90; } - if (sscanf(buf[91].c_str(), "%hd", &this->default_armor) != 1) { return 91; } - this->attacks.filename = buf[92]; - this->armors.filename = buf[93]; - // parse enum boundary_ids - if (buf[94] == "DUMMY") { - this->boundary_id = boundary_ids::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[94] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[95].c_str(), "%f", &this->weapon_range_max) != 1) { return 95; } - if (sscanf(buf[96].c_str(), "%f", &this->blast_range) != 1) { return 96; } - if (sscanf(buf[97].c_str(), "%f", &this->attack_speed) != 1) { return 97; } - if (sscanf(buf[98].c_str(), "%hd", &this->attack_projectile_primary_unit_id) != 1) { return 98; } - if (sscanf(buf[99].c_str(), "%hd", &this->accuracy) != 1) { return 99; } - if (sscanf(buf[100].c_str(), "%hhd", &this->break_off_combat) != 1) { return 100; } - if (sscanf(buf[101].c_str(), "%hd", &this->frame_delay) != 1) { return 101; } - // parse enum range_damage_type - if (buf[103] == "DUMMY") { - this->blast_level_offence = range_damage_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[103] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[104].c_str(), "%f", &this->weapon_range_min) != 1) { return 104; } - if (sscanf(buf[105].c_str(), "%f", &this->accuracy_dispersion) != 1) { return 105; } - if (sscanf(buf[106].c_str(), "%hd", &this->attack_sprite_id) != 1) { return 106; } - if (sscanf(buf[107].c_str(), "%hd", &this->melee_armor_displayed) != 1) { return 107; } - if (sscanf(buf[108].c_str(), "%hd", &this->attack_displayed) != 1) { return 108; } - if (sscanf(buf[109].c_str(), "%f", &this->range_displayed) != 1) { return 109; } - if (sscanf(buf[110].c_str(), "%f", &this->reload_time_displayed) != 1) { return 110; } - if (sscanf(buf[111].c_str(), "%hhd", &this->projectile_type) != 1) { return 111; } - if (sscanf(buf[112].c_str(), "%hhd", &this->smart_mode) != 1) { return 112; } - if (sscanf(buf[113].c_str(), "%hhd", &this->drop_animation_mode) != 1) { return 113; } - if (sscanf(buf[114].c_str(), "%hhd", &this->penetration_mode) != 1) { return 114; } - if (sscanf(buf[115].c_str(), "%hhd", &this->area_of_effect_special) != 1) { return 115; } - if (sscanf(buf[116].c_str(), "%f", &this->projectile_arc) != 1) { return 116; } - - return -1; -} - -bool missile_unit::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->resource_storage.read(storage, basedir); - this->damage_graphics.read(storage, basedir); - this->attacks.read(storage, basedir); - this->armors.read(storage, basedir); - - return true; -} - -int moving_unit::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', moving_unit::member_count - ); - - if (buf.size() != moving_unit::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing moving_unit led to " - << buf.size() - << " columns (expected " - << moving_unit::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->id0) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hu", &this->language_dll_name) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hu", &this->language_dll_creation) != 1) { return 2; } - // parse enum unit_classes - if (buf[3] == "DUMMY") { - this->unit_class = unit_classes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[3] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[4].c_str(), "%hd", &this->idle_graphic0) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%hd", &this->idle_graphic1) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%hd", &this->dying_graphic) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%hd", &this->undead_graphic) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%hhd", &this->death_mode) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hd", &this->hit_points) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%f", &this->line_of_sight) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%hhd", &this->garrison_capacity) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%f", &this->radius_x) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%f", &this->radius_y) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%f", &this->radius_z) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%hd", &this->train_sound_id) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%hd", &this->damage_sound_id) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%hd", &this->dead_unit_id) != 1) { return 17; } - if (sscanf(buf[18].c_str(), "%hhd", &this->placement_mode) != 1) { return 18; } - if (sscanf(buf[19].c_str(), "%hhd", &this->can_be_built_on) != 1) { return 19; } - if (sscanf(buf[20].c_str(), "%hd", &this->icon_id) != 1) { return 20; } - if (sscanf(buf[21].c_str(), "%hhd", &this->hidden_in_editor) != 1) { return 21; } - if (sscanf(buf[22].c_str(), "%hd", &this->old_portrait_icon_id) != 1) { return 22; } - if (sscanf(buf[23].c_str(), "%hhd", &this->enabled) != 1) { return 23; } - if (sscanf(buf[24].c_str(), "%hd", &this->placement_side_terrain0) != 1) { return 24; } - if (sscanf(buf[25].c_str(), "%hd", &this->placement_side_terrain1) != 1) { return 25; } - if (sscanf(buf[26].c_str(), "%hd", &this->placement_terrain0) != 1) { return 26; } - if (sscanf(buf[27].c_str(), "%hd", &this->placement_terrain1) != 1) { return 27; } - if (sscanf(buf[28].c_str(), "%f", &this->clearance_size_x) != 1) { return 28; } - if (sscanf(buf[29].c_str(), "%f", &this->clearance_size_y) != 1) { return 29; } - // parse enum elevation_modes - if (buf[30] == "DUMMY") { - this->elevation_mode = elevation_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[30] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum fog_visibility - if (buf[31] == "DUMMY") { - this->visible_in_fog = fog_visibility::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[31] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum ground_type - if (buf[32] == "DUMMY") { - this->terrain_restriction = ground_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[32] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[33].c_str(), "%hhd", &this->fly_mode) != 1) { return 33; } - if (sscanf(buf[34].c_str(), "%hd", &this->resource_capacity) != 1) { return 34; } - if (sscanf(buf[35].c_str(), "%f", &this->resource_decay) != 1) { return 35; } - // parse enum blast_types - if (buf[36] == "DUMMY") { - this->blast_defense_level = blast_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[36] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum combat_levels - if (buf[37] == "DUMMY") { - this->combat_level = combat_levels::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[37] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum interaction_modes - if (buf[38] == "DUMMY") { - this->interaction_mode = interaction_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[38] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum minimap_modes - if (buf[39] == "DUMMY") { - this->map_draw_level = minimap_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[39] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum command_attributes - if (buf[40] == "DUMMY") { - this->unit_level = command_attributes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[40] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[41].c_str(), "%f", &this->attack_reaction) != 1) { return 41; } - if (sscanf(buf[42].c_str(), "%hhd", &this->minimap_color) != 1) { return 42; } - if (sscanf(buf[43].c_str(), "%d", &this->language_dll_help) != 1) { return 43; } - if (sscanf(buf[44].c_str(), "%d", &this->language_dll_hotkey_text) != 1) { return 44; } - if (sscanf(buf[45].c_str(), "%d", &this->hot_keys) != 1) { return 45; } - if (sscanf(buf[46].c_str(), "%hhd", &this->recyclable) != 1) { return 46; } - if (sscanf(buf[47].c_str(), "%hhd", &this->enable_auto_gather) != 1) { return 47; } - if (sscanf(buf[48].c_str(), "%hhd", &this->doppelgaenger_on_death) != 1) { return 48; } - if (sscanf(buf[49].c_str(), "%hhd", &this->resource_gather_drop) != 1) { return 49; } - if (sscanf(buf[50].c_str(), "%hhu", &this->occlusion_mode) != 1) { return 50; } - // parse enum obstruction_types - if (buf[51] == "DUMMY") { - this->obstruction_type = obstruction_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[51] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[52].c_str(), "%hhd", &this->obstruction_class) != 1) { return 52; } - if (sscanf(buf[53].c_str(), "%hhu", &this->trait) != 1) { return 53; } - if (sscanf(buf[54].c_str(), "%hhd", &this->civilization_id) != 1) { return 54; } - if (sscanf(buf[55].c_str(), "%hd", &this->attribute_piece) != 1) { return 55; } - // parse enum selection_effects - if (buf[56] == "DUMMY") { - this->selection_effect = selection_effects::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[56] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[57].c_str(), "%f", &this->selection_shape_x) != 1) { return 57; } - if (sscanf(buf[58].c_str(), "%f", &this->selection_shape_y) != 1) { return 58; } - if (sscanf(buf[59].c_str(), "%f", &this->selection_shape_z) != 1) { return 59; } - this->resource_storage.filename = buf[60]; - this->damage_graphics.filename = buf[61]; - if (sscanf(buf[62].c_str(), "%hd", &this->selection_sound_id) != 1) { return 62; } - if (sscanf(buf[63].c_str(), "%hd", &this->dying_sound_id) != 1) { return 63; } - // parse enum attack_modes - if (buf[64] == "DUMMY") { - this->old_attack_mode = attack_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[64] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[65].c_str(), "%hhd", &this->convert_terrain) != 1) { return 65; } - this->name = buf[66]; - if (sscanf(buf[67].c_str(), "%hd", &this->id1) != 1) { return 67; } - if (sscanf(buf[68].c_str(), "%hd", &this->id2) != 1) { return 68; } - if (sscanf(buf[69].c_str(), "%f", &this->speed) != 1) { return 69; } - if (sscanf(buf[70].c_str(), "%hd", &this->move_graphics) != 1) { return 70; } - if (sscanf(buf[71].c_str(), "%hd", &this->run_graphics) != 1) { return 71; } - if (sscanf(buf[72].c_str(), "%f", &this->turn_speed) != 1) { return 72; } - if (sscanf(buf[73].c_str(), "%hhd", &this->old_size_class) != 1) { return 73; } - if (sscanf(buf[74].c_str(), "%hd", &this->trail_unit_id) != 1) { return 74; } - if (sscanf(buf[75].c_str(), "%hhu", &this->trail_opsions) != 1) { return 75; } - if (sscanf(buf[76].c_str(), "%f", &this->trail_spacing) != 1) { return 76; } - if (sscanf(buf[77].c_str(), "%hhd", &this->old_move_algorithm) != 1) { return 77; } - if (sscanf(buf[78].c_str(), "%f", &this->turn_radius) != 1) { return 78; } - if (sscanf(buf[79].c_str(), "%f", &this->turn_radius_speed) != 1) { return 79; } - if (sscanf(buf[80].c_str(), "%f", &this->max_yaw_per_sec_moving) != 1) { return 80; } - if (sscanf(buf[81].c_str(), "%f", &this->stationary_yaw_revolution_time) != 1) { return 81; } - if (sscanf(buf[82].c_str(), "%f", &this->max_yaw_per_sec_stationary) != 1) { return 82; } - - return -1; -} - -bool moving_unit::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->resource_storage.read(storage, basedir); - this->damage_graphics.read(storage, basedir); - - return true; -} - -int projectile_unit::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', projectile_unit::member_count - ); - - if (buf.size() != projectile_unit::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing projectile_unit led to " - << buf.size() - << " columns (expected " - << projectile_unit::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->id0) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hu", &this->language_dll_name) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hu", &this->language_dll_creation) != 1) { return 2; } - // parse enum unit_classes - if (buf[3] == "DUMMY") { - this->unit_class = unit_classes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[3] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[4].c_str(), "%hd", &this->idle_graphic0) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%hd", &this->idle_graphic1) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%hd", &this->dying_graphic) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%hd", &this->undead_graphic) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%hhd", &this->death_mode) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hd", &this->hit_points) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%f", &this->line_of_sight) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%hhd", &this->garrison_capacity) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%f", &this->radius_x) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%f", &this->radius_y) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%f", &this->radius_z) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%hd", &this->train_sound_id) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%hd", &this->damage_sound_id) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%hd", &this->dead_unit_id) != 1) { return 17; } - if (sscanf(buf[18].c_str(), "%hhd", &this->placement_mode) != 1) { return 18; } - if (sscanf(buf[19].c_str(), "%hhd", &this->can_be_built_on) != 1) { return 19; } - if (sscanf(buf[20].c_str(), "%hd", &this->icon_id) != 1) { return 20; } - if (sscanf(buf[21].c_str(), "%hhd", &this->hidden_in_editor) != 1) { return 21; } - if (sscanf(buf[22].c_str(), "%hd", &this->old_portrait_icon_id) != 1) { return 22; } - if (sscanf(buf[23].c_str(), "%hhd", &this->enabled) != 1) { return 23; } - if (sscanf(buf[24].c_str(), "%hd", &this->placement_side_terrain0) != 1) { return 24; } - if (sscanf(buf[25].c_str(), "%hd", &this->placement_side_terrain1) != 1) { return 25; } - if (sscanf(buf[26].c_str(), "%hd", &this->placement_terrain0) != 1) { return 26; } - if (sscanf(buf[27].c_str(), "%hd", &this->placement_terrain1) != 1) { return 27; } - if (sscanf(buf[28].c_str(), "%f", &this->clearance_size_x) != 1) { return 28; } - if (sscanf(buf[29].c_str(), "%f", &this->clearance_size_y) != 1) { return 29; } - // parse enum elevation_modes - if (buf[30] == "DUMMY") { - this->elevation_mode = elevation_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[30] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum fog_visibility - if (buf[31] == "DUMMY") { - this->visible_in_fog = fog_visibility::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[31] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum ground_type - if (buf[32] == "DUMMY") { - this->terrain_restriction = ground_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[32] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[33].c_str(), "%hhd", &this->fly_mode) != 1) { return 33; } - if (sscanf(buf[34].c_str(), "%hd", &this->resource_capacity) != 1) { return 34; } - if (sscanf(buf[35].c_str(), "%f", &this->resource_decay) != 1) { return 35; } - // parse enum blast_types - if (buf[36] == "DUMMY") { - this->blast_defense_level = blast_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[36] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum combat_levels - if (buf[37] == "DUMMY") { - this->combat_level = combat_levels::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[37] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum interaction_modes - if (buf[38] == "DUMMY") { - this->interaction_mode = interaction_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[38] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum minimap_modes - if (buf[39] == "DUMMY") { - this->map_draw_level = minimap_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[39] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum command_attributes - if (buf[40] == "DUMMY") { - this->unit_level = command_attributes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[40] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[41].c_str(), "%f", &this->attack_reaction) != 1) { return 41; } - if (sscanf(buf[42].c_str(), "%hhd", &this->minimap_color) != 1) { return 42; } - if (sscanf(buf[43].c_str(), "%d", &this->language_dll_help) != 1) { return 43; } - if (sscanf(buf[44].c_str(), "%d", &this->language_dll_hotkey_text) != 1) { return 44; } - if (sscanf(buf[45].c_str(), "%d", &this->hot_keys) != 1) { return 45; } - if (sscanf(buf[46].c_str(), "%hhd", &this->recyclable) != 1) { return 46; } - if (sscanf(buf[47].c_str(), "%hhd", &this->enable_auto_gather) != 1) { return 47; } - if (sscanf(buf[48].c_str(), "%hhd", &this->doppelgaenger_on_death) != 1) { return 48; } - if (sscanf(buf[49].c_str(), "%hhd", &this->resource_gather_drop) != 1) { return 49; } - if (sscanf(buf[50].c_str(), "%hhu", &this->occlusion_mode) != 1) { return 50; } - // parse enum obstruction_types - if (buf[51] == "DUMMY") { - this->obstruction_type = obstruction_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[51] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[52].c_str(), "%hhd", &this->obstruction_class) != 1) { return 52; } - if (sscanf(buf[53].c_str(), "%hhu", &this->trait) != 1) { return 53; } - if (sscanf(buf[54].c_str(), "%hhd", &this->civilization_id) != 1) { return 54; } - if (sscanf(buf[55].c_str(), "%hd", &this->attribute_piece) != 1) { return 55; } - // parse enum selection_effects - if (buf[56] == "DUMMY") { - this->selection_effect = selection_effects::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[56] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[57].c_str(), "%f", &this->selection_shape_x) != 1) { return 57; } - if (sscanf(buf[58].c_str(), "%f", &this->selection_shape_y) != 1) { return 58; } - if (sscanf(buf[59].c_str(), "%f", &this->selection_shape_z) != 1) { return 59; } - this->resource_storage.filename = buf[60]; - this->damage_graphics.filename = buf[61]; - if (sscanf(buf[62].c_str(), "%hd", &this->selection_sound_id) != 1) { return 62; } - if (sscanf(buf[63].c_str(), "%hd", &this->dying_sound_id) != 1) { return 63; } - // parse enum attack_modes - if (buf[64] == "DUMMY") { - this->old_attack_mode = attack_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[64] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[65].c_str(), "%hhd", &this->convert_terrain) != 1) { return 65; } - this->name = buf[66]; - if (sscanf(buf[67].c_str(), "%hd", &this->id1) != 1) { return 67; } - if (sscanf(buf[68].c_str(), "%hd", &this->id2) != 1) { return 68; } - if (sscanf(buf[69].c_str(), "%f", &this->speed) != 1) { return 69; } - if (sscanf(buf[70].c_str(), "%hd", &this->move_graphics) != 1) { return 70; } - if (sscanf(buf[71].c_str(), "%hd", &this->run_graphics) != 1) { return 71; } - if (sscanf(buf[72].c_str(), "%f", &this->turn_speed) != 1) { return 72; } - if (sscanf(buf[73].c_str(), "%hhd", &this->old_size_class) != 1) { return 73; } - if (sscanf(buf[74].c_str(), "%hd", &this->trail_unit_id) != 1) { return 74; } - if (sscanf(buf[75].c_str(), "%hhu", &this->trail_opsions) != 1) { return 75; } - if (sscanf(buf[76].c_str(), "%f", &this->trail_spacing) != 1) { return 76; } - if (sscanf(buf[77].c_str(), "%hhd", &this->old_move_algorithm) != 1) { return 77; } - if (sscanf(buf[78].c_str(), "%f", &this->turn_radius) != 1) { return 78; } - if (sscanf(buf[79].c_str(), "%f", &this->turn_radius_speed) != 1) { return 79; } - if (sscanf(buf[80].c_str(), "%f", &this->max_yaw_per_sec_moving) != 1) { return 80; } - if (sscanf(buf[81].c_str(), "%f", &this->stationary_yaw_revolution_time) != 1) { return 81; } - if (sscanf(buf[82].c_str(), "%f", &this->max_yaw_per_sec_stationary) != 1) { return 82; } - if (sscanf(buf[83].c_str(), "%hd", &this->default_task_id) != 1) { return 83; } - if (sscanf(buf[84].c_str(), "%f", &this->search_radius) != 1) { return 84; } - if (sscanf(buf[85].c_str(), "%f", &this->work_rate) != 1) { return 85; } - if (sscanf(buf[87].c_str(), "%hhd", &this->task_group) != 1) { return 87; } - if (sscanf(buf[88].c_str(), "%hd", &this->command_sound_id) != 1) { return 88; } - if (sscanf(buf[89].c_str(), "%hd", &this->stop_sound_id) != 1) { return 89; } - if (sscanf(buf[90].c_str(), "%hhd", &this->run_pattern) != 1) { return 90; } - if (sscanf(buf[91].c_str(), "%hd", &this->default_armor) != 1) { return 91; } - this->attacks.filename = buf[92]; - this->armors.filename = buf[93]; - // parse enum boundary_ids - if (buf[94] == "DUMMY") { - this->boundary_id = boundary_ids::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[94] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[95].c_str(), "%f", &this->weapon_range_max) != 1) { return 95; } - if (sscanf(buf[96].c_str(), "%f", &this->blast_range) != 1) { return 96; } - if (sscanf(buf[97].c_str(), "%f", &this->attack_speed) != 1) { return 97; } - if (sscanf(buf[98].c_str(), "%hd", &this->attack_projectile_primary_unit_id) != 1) { return 98; } - if (sscanf(buf[99].c_str(), "%hd", &this->accuracy) != 1) { return 99; } - if (sscanf(buf[100].c_str(), "%hhd", &this->break_off_combat) != 1) { return 100; } - if (sscanf(buf[101].c_str(), "%hd", &this->frame_delay) != 1) { return 101; } - // parse enum range_damage_type - if (buf[103] == "DUMMY") { - this->blast_level_offence = range_damage_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[103] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[104].c_str(), "%f", &this->weapon_range_min) != 1) { return 104; } - if (sscanf(buf[105].c_str(), "%f", &this->accuracy_dispersion) != 1) { return 105; } - if (sscanf(buf[106].c_str(), "%hd", &this->attack_sprite_id) != 1) { return 106; } - if (sscanf(buf[107].c_str(), "%hd", &this->melee_armor_displayed) != 1) { return 107; } - if (sscanf(buf[108].c_str(), "%hd", &this->attack_displayed) != 1) { return 108; } - if (sscanf(buf[109].c_str(), "%f", &this->range_displayed) != 1) { return 109; } - if (sscanf(buf[110].c_str(), "%f", &this->reload_time_displayed) != 1) { return 110; } - - return -1; -} - -bool projectile_unit::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->resource_storage.read(storage, basedir); - this->damage_graphics.read(storage, basedir); - this->attacks.read(storage, basedir); - this->armors.read(storage, basedir); - - return true; -} - -int resource_cost::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', resource_cost::member_count - ); - - if (buf.size() != resource_cost::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing resource_cost led to " - << buf.size() - << " columns (expected " - << resource_cost::member_count - << ")!" - ); - } - - // parse enum resource_types - if (buf[0] == "DUMMY") { - this->type_id = resource_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[0] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[1].c_str(), "%hd", &this->amount) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hd", &this->enabled) != 1) { return 2; } - - return -1; -} - -bool resource_cost::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -int resource_storage::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', resource_storage::member_count - ); - - if (buf.size() != resource_storage::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing resource_storage led to " - << buf.size() - << " columns (expected " - << resource_storage::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->type) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%f", &this->amount) != 1) { return 1; } - // parse enum resource_handling - if (buf[2] == "DUMMY") { - this->used_mode = resource_handling::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[2] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - - return -1; -} - -bool resource_storage::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -int tree_unit::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', tree_unit::member_count - ); - - if (buf.size() != tree_unit::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing tree_unit led to " - << buf.size() - << " columns (expected " - << tree_unit::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->id0) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hu", &this->language_dll_name) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hu", &this->language_dll_creation) != 1) { return 2; } - // parse enum unit_classes - if (buf[3] == "DUMMY") { - this->unit_class = unit_classes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[3] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[4].c_str(), "%hd", &this->idle_graphic0) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%hd", &this->idle_graphic1) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%hd", &this->dying_graphic) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%hd", &this->undead_graphic) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%hhd", &this->death_mode) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hd", &this->hit_points) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%f", &this->line_of_sight) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%hhd", &this->garrison_capacity) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%f", &this->radius_x) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%f", &this->radius_y) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%f", &this->radius_z) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%hd", &this->train_sound_id) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%hd", &this->damage_sound_id) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%hd", &this->dead_unit_id) != 1) { return 17; } - if (sscanf(buf[18].c_str(), "%hhd", &this->placement_mode) != 1) { return 18; } - if (sscanf(buf[19].c_str(), "%hhd", &this->can_be_built_on) != 1) { return 19; } - if (sscanf(buf[20].c_str(), "%hd", &this->icon_id) != 1) { return 20; } - if (sscanf(buf[21].c_str(), "%hhd", &this->hidden_in_editor) != 1) { return 21; } - if (sscanf(buf[22].c_str(), "%hd", &this->old_portrait_icon_id) != 1) { return 22; } - if (sscanf(buf[23].c_str(), "%hhd", &this->enabled) != 1) { return 23; } - if (sscanf(buf[24].c_str(), "%hd", &this->placement_side_terrain0) != 1) { return 24; } - if (sscanf(buf[25].c_str(), "%hd", &this->placement_side_terrain1) != 1) { return 25; } - if (sscanf(buf[26].c_str(), "%hd", &this->placement_terrain0) != 1) { return 26; } - if (sscanf(buf[27].c_str(), "%hd", &this->placement_terrain1) != 1) { return 27; } - if (sscanf(buf[28].c_str(), "%f", &this->clearance_size_x) != 1) { return 28; } - if (sscanf(buf[29].c_str(), "%f", &this->clearance_size_y) != 1) { return 29; } - // parse enum elevation_modes - if (buf[30] == "DUMMY") { - this->elevation_mode = elevation_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[30] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum fog_visibility - if (buf[31] == "DUMMY") { - this->visible_in_fog = fog_visibility::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[31] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum ground_type - if (buf[32] == "DUMMY") { - this->terrain_restriction = ground_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[32] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[33].c_str(), "%hhd", &this->fly_mode) != 1) { return 33; } - if (sscanf(buf[34].c_str(), "%hd", &this->resource_capacity) != 1) { return 34; } - if (sscanf(buf[35].c_str(), "%f", &this->resource_decay) != 1) { return 35; } - // parse enum blast_types - if (buf[36] == "DUMMY") { - this->blast_defense_level = blast_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[36] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum combat_levels - if (buf[37] == "DUMMY") { - this->combat_level = combat_levels::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[37] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum interaction_modes - if (buf[38] == "DUMMY") { - this->interaction_mode = interaction_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[38] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum minimap_modes - if (buf[39] == "DUMMY") { - this->map_draw_level = minimap_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[39] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum command_attributes - if (buf[40] == "DUMMY") { - this->unit_level = command_attributes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[40] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[41].c_str(), "%f", &this->attack_reaction) != 1) { return 41; } - if (sscanf(buf[42].c_str(), "%hhd", &this->minimap_color) != 1) { return 42; } - if (sscanf(buf[43].c_str(), "%d", &this->language_dll_help) != 1) { return 43; } - if (sscanf(buf[44].c_str(), "%d", &this->language_dll_hotkey_text) != 1) { return 44; } - if (sscanf(buf[45].c_str(), "%d", &this->hot_keys) != 1) { return 45; } - if (sscanf(buf[46].c_str(), "%hhd", &this->recyclable) != 1) { return 46; } - if (sscanf(buf[47].c_str(), "%hhd", &this->enable_auto_gather) != 1) { return 47; } - if (sscanf(buf[48].c_str(), "%hhd", &this->doppelgaenger_on_death) != 1) { return 48; } - if (sscanf(buf[49].c_str(), "%hhd", &this->resource_gather_drop) != 1) { return 49; } - if (sscanf(buf[50].c_str(), "%hhu", &this->occlusion_mode) != 1) { return 50; } - // parse enum obstruction_types - if (buf[51] == "DUMMY") { - this->obstruction_type = obstruction_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[51] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[52].c_str(), "%hhd", &this->obstruction_class) != 1) { return 52; } - if (sscanf(buf[53].c_str(), "%hhu", &this->trait) != 1) { return 53; } - if (sscanf(buf[54].c_str(), "%hhd", &this->civilization_id) != 1) { return 54; } - if (sscanf(buf[55].c_str(), "%hd", &this->attribute_piece) != 1) { return 55; } - // parse enum selection_effects - if (buf[56] == "DUMMY") { - this->selection_effect = selection_effects::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[56] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[57].c_str(), "%f", &this->selection_shape_x) != 1) { return 57; } - if (sscanf(buf[58].c_str(), "%f", &this->selection_shape_y) != 1) { return 58; } - if (sscanf(buf[59].c_str(), "%f", &this->selection_shape_z) != 1) { return 59; } - this->resource_storage.filename = buf[60]; - this->damage_graphics.filename = buf[61]; - if (sscanf(buf[62].c_str(), "%hd", &this->selection_sound_id) != 1) { return 62; } - if (sscanf(buf[63].c_str(), "%hd", &this->dying_sound_id) != 1) { return 63; } - // parse enum attack_modes - if (buf[64] == "DUMMY") { - this->old_attack_mode = attack_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[64] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[65].c_str(), "%hhd", &this->convert_terrain) != 1) { return 65; } - this->name = buf[66]; - if (sscanf(buf[67].c_str(), "%hd", &this->id1) != 1) { return 67; } - if (sscanf(buf[68].c_str(), "%hd", &this->id2) != 1) { return 68; } - - return -1; -} - -bool tree_unit::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->resource_storage.read(storage, basedir); - this->damage_graphics.read(storage, basedir); - - return true; -} - -int unit_command::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', unit_command::member_count - ); - - if (buf.size() != unit_command::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing unit_command led to " - << buf.size() - << " columns (expected " - << unit_command::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->command_used) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hd", &this->command_id) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hhd", &this->is_default) != 1) { return 2; } - // parse enum command_ability - if (buf[3] == "DUMMY") { - this->type = command_ability::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[3] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[4].c_str(), "%hd", &this->class_id) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%hd", &this->unit_id) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%hd", &this->terrain_id) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%hd", &this->resource_in) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%hd", &this->resource_multiplier) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hd", &this->resource_out) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%hd", &this->unused_resource) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%f", &this->work_value1) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%f", &this->work_value2) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%f", &this->work_range) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%hhd", &this->search_mode) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%f", &this->search_time) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%hhd", &this->enable_targeting) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%hhd", &this->combat_level_flag) != 1) { return 17; } - if (sscanf(buf[18].c_str(), "%hd", &this->gather_type) != 1) { return 18; } - // parse enum selection_type - if (buf[19] == "DUMMY") { - this->owner_type = selection_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[19] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[20].c_str(), "%hhd", &this->carry_check) != 1) { return 20; } - if (sscanf(buf[21].c_str(), "%hhd", &this->state_build) != 1) { return 21; } - if (sscanf(buf[22].c_str(), "%hd", &this->move_sprite_id) != 1) { return 22; } - if (sscanf(buf[23].c_str(), "%hd", &this->proceed_sprite_id) != 1) { return 23; } - if (sscanf(buf[24].c_str(), "%hd", &this->work_sprite_id) != 1) { return 24; } - if (sscanf(buf[25].c_str(), "%hd", &this->carry_sprite_id) != 1) { return 25; } - if (sscanf(buf[26].c_str(), "%hd", &this->resource_gather_sound_id) != 1) { return 26; } - if (sscanf(buf[27].c_str(), "%hd", &this->resource_deposit_sound_id) != 1) { return 27; } - - return -1; -} - -bool unit_command::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -int unit_header::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', unit_header::member_count - ); - - if (buf.size() != unit_header::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing unit_header led to " - << buf.size() - << " columns (expected " - << unit_header::member_count - << ")!" - ); - } - - // remember if the following members are undefined - if (buf[0] == "data_absent") { - this->exists = 0; - } else if (buf[0] == "data_exists") { - this->exists = 1; - } else { - throw openage::error::Error(ERR << "unexpected value '"<< buf[0] << "' for ContinueReadMember"); - } - this->unit_commands.filename = buf[1]; - - return -1; -} - -bool unit_header::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->unit_commands.read(storage, basedir); - - return true; -} - -int unit_object::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', unit_object::member_count - ); - - if (buf.size() != unit_object::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing unit_object led to " - << buf.size() - << " columns (expected " - << unit_object::member_count - << ")!" - ); - } - - if (sscanf(buf[0].c_str(), "%hd", &this->id0) != 1) { return 0; } - if (sscanf(buf[1].c_str(), "%hu", &this->language_dll_name) != 1) { return 1; } - if (sscanf(buf[2].c_str(), "%hu", &this->language_dll_creation) != 1) { return 2; } - // parse enum unit_classes - if (buf[3] == "DUMMY") { - this->unit_class = unit_classes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[3] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[4].c_str(), "%hd", &this->idle_graphic0) != 1) { return 4; } - if (sscanf(buf[5].c_str(), "%hd", &this->idle_graphic1) != 1) { return 5; } - if (sscanf(buf[6].c_str(), "%hd", &this->dying_graphic) != 1) { return 6; } - if (sscanf(buf[7].c_str(), "%hd", &this->undead_graphic) != 1) { return 7; } - if (sscanf(buf[8].c_str(), "%hhd", &this->death_mode) != 1) { return 8; } - if (sscanf(buf[9].c_str(), "%hd", &this->hit_points) != 1) { return 9; } - if (sscanf(buf[10].c_str(), "%f", &this->line_of_sight) != 1) { return 10; } - if (sscanf(buf[11].c_str(), "%hhd", &this->garrison_capacity) != 1) { return 11; } - if (sscanf(buf[12].c_str(), "%f", &this->radius_x) != 1) { return 12; } - if (sscanf(buf[13].c_str(), "%f", &this->radius_y) != 1) { return 13; } - if (sscanf(buf[14].c_str(), "%f", &this->radius_z) != 1) { return 14; } - if (sscanf(buf[15].c_str(), "%hd", &this->train_sound_id) != 1) { return 15; } - if (sscanf(buf[16].c_str(), "%hd", &this->damage_sound_id) != 1) { return 16; } - if (sscanf(buf[17].c_str(), "%hd", &this->dead_unit_id) != 1) { return 17; } - if (sscanf(buf[18].c_str(), "%hhd", &this->placement_mode) != 1) { return 18; } - if (sscanf(buf[19].c_str(), "%hhd", &this->can_be_built_on) != 1) { return 19; } - if (sscanf(buf[20].c_str(), "%hd", &this->icon_id) != 1) { return 20; } - if (sscanf(buf[21].c_str(), "%hhd", &this->hidden_in_editor) != 1) { return 21; } - if (sscanf(buf[22].c_str(), "%hd", &this->old_portrait_icon_id) != 1) { return 22; } - if (sscanf(buf[23].c_str(), "%hhd", &this->enabled) != 1) { return 23; } - if (sscanf(buf[24].c_str(), "%hd", &this->placement_side_terrain0) != 1) { return 24; } - if (sscanf(buf[25].c_str(), "%hd", &this->placement_side_terrain1) != 1) { return 25; } - if (sscanf(buf[26].c_str(), "%hd", &this->placement_terrain0) != 1) { return 26; } - if (sscanf(buf[27].c_str(), "%hd", &this->placement_terrain1) != 1) { return 27; } - if (sscanf(buf[28].c_str(), "%f", &this->clearance_size_x) != 1) { return 28; } - if (sscanf(buf[29].c_str(), "%f", &this->clearance_size_y) != 1) { return 29; } - // parse enum elevation_modes - if (buf[30] == "DUMMY") { - this->elevation_mode = elevation_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[30] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum fog_visibility - if (buf[31] == "DUMMY") { - this->visible_in_fog = fog_visibility::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[31] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum ground_type - if (buf[32] == "DUMMY") { - this->terrain_restriction = ground_type::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[32] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[33].c_str(), "%hhd", &this->fly_mode) != 1) { return 33; } - if (sscanf(buf[34].c_str(), "%hd", &this->resource_capacity) != 1) { return 34; } - if (sscanf(buf[35].c_str(), "%f", &this->resource_decay) != 1) { return 35; } - // parse enum blast_types - if (buf[36] == "DUMMY") { - this->blast_defense_level = blast_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[36] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum combat_levels - if (buf[37] == "DUMMY") { - this->combat_level = combat_levels::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[37] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum interaction_modes - if (buf[38] == "DUMMY") { - this->interaction_mode = interaction_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[38] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum minimap_modes - if (buf[39] == "DUMMY") { - this->map_draw_level = minimap_modes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[39] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - // parse enum command_attributes - if (buf[40] == "DUMMY") { - this->unit_level = command_attributes::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[40] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[41].c_str(), "%f", &this->attack_reaction) != 1) { return 41; } - if (sscanf(buf[42].c_str(), "%hhd", &this->minimap_color) != 1) { return 42; } - if (sscanf(buf[43].c_str(), "%d", &this->language_dll_help) != 1) { return 43; } - if (sscanf(buf[44].c_str(), "%d", &this->language_dll_hotkey_text) != 1) { return 44; } - if (sscanf(buf[45].c_str(), "%d", &this->hot_keys) != 1) { return 45; } - if (sscanf(buf[46].c_str(), "%hhd", &this->recyclable) != 1) { return 46; } - if (sscanf(buf[47].c_str(), "%hhd", &this->enable_auto_gather) != 1) { return 47; } - if (sscanf(buf[48].c_str(), "%hhd", &this->doppelgaenger_on_death) != 1) { return 48; } - if (sscanf(buf[49].c_str(), "%hhd", &this->resource_gather_drop) != 1) { return 49; } - if (sscanf(buf[50].c_str(), "%hhu", &this->occlusion_mode) != 1) { return 50; } - // parse enum obstruction_types - if (buf[51] == "DUMMY") { - this->obstruction_type = obstruction_types::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[51] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[52].c_str(), "%hhd", &this->obstruction_class) != 1) { return 52; } - if (sscanf(buf[53].c_str(), "%hhu", &this->trait) != 1) { return 53; } - if (sscanf(buf[54].c_str(), "%hhd", &this->civilization_id) != 1) { return 54; } - if (sscanf(buf[55].c_str(), "%hd", &this->attribute_piece) != 1) { return 55; } - // parse enum selection_effects - if (buf[56] == "DUMMY") { - this->selection_effect = selection_effects::DUMMY; - } - else { - throw openage::error::Error( - MSG(err) - << "unknown enum value '" << buf[56] - << "' encountered. valid are: " - "DUMMY\n---\n" - );} - if (sscanf(buf[65].c_str(), "%hhd", &this->convert_terrain) != 1) { return 65; } - this->name = buf[66]; - if (sscanf(buf[67].c_str(), "%hd", &this->id1) != 1) { return 67; } - if (sscanf(buf[68].c_str(), "%hd", &this->id2) != 1) { return 68; } - - return -1; -} - -bool unit_object::recurse(const openage::util::CSVCollection &storage, const std::string &basedir) { - this->resource_storage.read(storage, basedir); - this->damage_graphics.read(storage, basedir); - - return true; -} - -} // gamedata -} // openage diff --git a/libopenage/gamedata/unit_dummy.h b/libopenage/gamedata/unit_dummy.h deleted file mode 100644 index 4398fa0d11..0000000000 --- a/libopenage/gamedata/unit_dummy.h +++ /dev/null @@ -1,515 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - -#pragma once - -#include -#include -#include -#include "util/csv.h" - - - -namespace openage { -namespace gamedata { - -enum class attack_modes { - DUMMY -}; - - -enum class blast_types { - DUMMY -}; - - -enum class boundary_ids { - DUMMY -}; - - -/** - * a possible building annex. - */ -struct building_annex { - int16_t unit_id; - float misplaced0; - float misplaced1; - static constexpr size_t member_count = 3; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -enum class combat_levels { - DUMMY -}; - - -enum class command_ability { - DUMMY -}; - - -enum class command_attributes { - DUMMY -}; - - -enum class creatable_types { - DUMMY -}; - - -enum class damage_draw_type { - DUMMY -}; - - -enum class elevation_modes { - DUMMY -}; - - -enum class fog_visibility { - DUMMY -}; - - -enum class garrison_types { - DUMMY -}; - - -enum class ground_type { - DUMMY, - WATER, - WATER_0x0D, - WATER_SHIP_0x03, - WATER_SHIP_0x0F, - SOLID, - FOUNDATION, - NO_ICE_0x08, - FOREST -}; - - -enum class hit_class { - DUMMY -}; - - -enum class interaction_modes { - DUMMY -}; - - -enum class minimap_modes { - DUMMY -}; - - -enum class obstruction_types { - DUMMY -}; - - -enum class range_damage_type { - DUMMY -}; - - -enum class resource_handling { - DUMMY -}; - - -enum class resource_types { - DUMMY -}; - - -enum class selection_effects { - DUMMY -}; - - -enum class selection_type { - DUMMY -}; - - -enum class unit_classes { - DUMMY, - BUILDING, - CIVILIAN, - TREES, - HERDABLE, - GOLD_MINE, - STONE_MINE, - BERRY_BUSH, - PREY_ANIMAL, - SEA_FISH, - FISHING_BOAT -}; - - -/** - * stores one possible unit image that is displayed at a given damage percentage. - */ -struct damage_graphic { - int16_t graphic_id; - int8_t damage_percent; - int8_t old_apply_mode; - damage_draw_type apply_mode; - static constexpr size_t member_count = 4; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * determines the resource storage capacity for one unit mode. - */ -struct resource_storage { - int16_t type; - float amount; - resource_handling used_mode; - static constexpr size_t member_count = 3; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * base properties for all units. - */ -struct unit_object { - int16_t id0; - uint16_t language_dll_name; - uint16_t language_dll_creation; - unit_classes unit_class; - int16_t idle_graphic0; - int16_t idle_graphic1; - int16_t dying_graphic; - int16_t undead_graphic; - int8_t death_mode; - int16_t hit_points; - float line_of_sight; - int8_t garrison_capacity; - float radius_x; - float radius_y; - float radius_z; - int16_t train_sound_id; - int16_t damage_sound_id; - int16_t dead_unit_id; - int8_t placement_mode; - int8_t can_be_built_on; - int16_t icon_id; - int8_t hidden_in_editor; - int16_t old_portrait_icon_id; - int8_t enabled; - int16_t placement_side_terrain0; - int16_t placement_side_terrain1; - int16_t placement_terrain0; - int16_t placement_terrain1; - float clearance_size_x; - float clearance_size_y; - elevation_modes elevation_mode; - fog_visibility visible_in_fog; - ground_type terrain_restriction; - int8_t fly_mode; - int16_t resource_capacity; - float resource_decay; - blast_types blast_defense_level; - combat_levels combat_level; - interaction_modes interaction_mode; - minimap_modes map_draw_level; - command_attributes unit_level; - float attack_reaction; - int8_t minimap_color; - int32_t language_dll_help; - int32_t language_dll_hotkey_text; - int32_t hot_keys; - int8_t recyclable; - int8_t enable_auto_gather; - int8_t doppelgaenger_on_death; - int8_t resource_gather_drop; - uint8_t occlusion_mode; - obstruction_types obstruction_type; - int8_t obstruction_class; - uint8_t trait; - int8_t civilization_id; - int16_t attribute_piece; - selection_effects selection_effect; - float selection_shape_x; - float selection_shape_y; - float selection_shape_z; - openage::util::csv_subdata resource_storage; - openage::util::csv_subdata damage_graphics; - int16_t selection_sound_id; - int16_t dying_sound_id; - attack_modes old_attack_mode; - int8_t convert_terrain; - std::string name; - int16_t id1; - int16_t id2; - static constexpr size_t member_count = 69; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * adds speed property to units. - */ -struct animated_unit : unit_object { - float speed; - static constexpr size_t member_count = 70; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * weird doppelganger unit thats actually the same as an animated unit. - */ -struct doppelganger_unit : animated_unit { - static constexpr size_t member_count = 70; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * adds walking graphics, rotations and tracking properties to units. - */ -struct moving_unit : doppelganger_unit { - int16_t move_graphics; - int16_t run_graphics; - float turn_speed; - int8_t old_size_class; - int16_t trail_unit_id; - uint8_t trail_opsions; - float trail_spacing; - int8_t old_move_algorithm; - float turn_radius; - float turn_radius_speed; - float max_yaw_per_sec_moving; - float stationary_yaw_revolution_time; - float max_yaw_per_sec_stationary; - static constexpr size_t member_count = 83; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * adds search radius and work properties, as well as movement sounds. - */ -struct action_unit : moving_unit { - int16_t default_task_id; - float search_radius; - float work_rate; - int8_t task_group; - int16_t command_sound_id; - int16_t stop_sound_id; - int8_t run_pattern; - static constexpr size_t member_count = 91; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * stores attack amount for a damage type. - */ -struct hit_type { - hit_class type_id; - int16_t amount; - static constexpr size_t member_count = 2; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * adds attack and armor properties to units. - */ -struct projectile_unit : action_unit { - int16_t default_armor; - openage::util::csv_subdata attacks; - openage::util::csv_subdata armors; - boundary_ids boundary_id; - float weapon_range_max; - float blast_range; - float attack_speed; - int16_t attack_projectile_primary_unit_id; - int16_t accuracy; - int8_t break_off_combat; - int16_t frame_delay; - range_damage_type blast_level_offence; - float weapon_range_min; - float accuracy_dispersion; - int16_t attack_sprite_id; - int16_t melee_armor_displayed; - int16_t attack_displayed; - float range_displayed; - float reload_time_displayed; - static constexpr size_t member_count = 111; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * adds missile specific unit properties. - */ -struct missile_unit : projectile_unit { - int8_t projectile_type; - int8_t smart_mode; - int8_t drop_animation_mode; - int8_t penetration_mode; - int8_t area_of_effect_special; - float projectile_arc; - static constexpr size_t member_count = 117; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * stores cost for one resource for creating the unit. - */ -struct resource_cost { - resource_types type_id; - int16_t amount; - int16_t enabled; - static constexpr size_t member_count = 3; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * just a tree unit. - */ -struct tree_unit : unit_object { - static constexpr size_t member_count = 69; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * a command a single unit may receive by script or human. - */ -struct unit_command { - int16_t command_used; - int16_t command_id; - int8_t is_default; - command_ability type; - int16_t class_id; - int16_t unit_id; - int16_t terrain_id; - int16_t resource_in; - int16_t resource_multiplier; - int16_t resource_out; - int16_t unused_resource; - float work_value1; - float work_value2; - float work_range; - int8_t search_mode; - float search_time; - int8_t enable_targeting; - int8_t combat_level_flag; - int16_t gather_type; - selection_type owner_type; - int8_t carry_check; - int8_t state_build; - int16_t move_sprite_id; - int16_t proceed_sprite_id; - int16_t work_sprite_id; - int16_t carry_sprite_id; - int16_t resource_gather_sound_id; - int16_t resource_deposit_sound_id; - static constexpr size_t member_count = 28; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * stores a bunch of unit commands. - */ -struct unit_header { - uint8_t exists; - openage::util::csv_subdata unit_commands; - static constexpr size_t member_count = 2; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * adds creation location and garrison unit properties. - */ -struct living_unit : projectile_unit { - openage::util::csv_subdata resource_cost; - int16_t creation_time; - int16_t train_location_id; - float rear_attack_modifier; - float flank_attack_modifier; - creatable_types creatable_type; - int8_t hero_mode; - int32_t garrison_graphic; - float attack_projectile_count; - int8_t attack_projectile_max_count; - float attack_projectile_spawning_area_width; - float attack_projectile_spawning_area_length; - float attack_projectile_spawning_area_randomness; - int32_t attack_projectile_secondary_unit_id; - int32_t special_graphic_id; - int8_t special_activation; - int16_t pierce_armor_displayed; - static constexpr size_t member_count = 128; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -/** - * construction graphics and garrison building properties for units. - */ -struct building_unit : living_unit { - int16_t construction_graphic_id; - int16_t snow_graphic_id; - int8_t adjacent_mode; - int16_t graphics_angle; - int8_t disappears_when_built; - int16_t stack_unit_id; - int16_t foundation_terrain_id; - int16_t old_overlay_id; - int16_t research_id; - int8_t can_burn; - openage::util::csv_subdata building_annex; - int16_t head_unit_id; - int16_t transform_unit_id; - int16_t transform_sound_id; - int16_t construction_sound_id; - garrison_types garrison_type; - float garrison_heal_rate; - float garrison_repair_rate; - int16_t salvage_unit_id; - static constexpr size_t member_count = 148; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -} // gamedata -} // openage diff --git a/libopenage/gamedata/util_dummy.cpp b/libopenage/gamedata/util_dummy.cpp deleted file mode 100644 index ee4c97bb50..0000000000 --- a/libopenage/gamedata/util_dummy.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - - -#include -#include "error/error.h" -#include "util_dummy.h" -#include "util/strings.h" - - -namespace openage { -namespace gamedata { - -constexpr size_t multisubtype_ref::member_count; -int multisubtype_ref::fill(const std::string &line) { - std::vector buf = openage::util::split_escape( - line, ',', multisubtype_ref::member_count - ); - - if (buf.size() != multisubtype_ref::member_count) { - throw openage::error::Error( - ERR - << "Tokenizing multisubtype_ref led to " - << buf.size() - << " columns (expected " - << multisubtype_ref::member_count - << ")!" - ); - } - - this->subtype = buf[0]; - this->filename = buf[1]; - - return -1; -} - -bool multisubtype_ref::recurse(const openage::util::CSVCollection & /*storage*/, const std::string & /*basedir*/) { - return true; -} - -} // gamedata -} // openage diff --git a/libopenage/gamedata/util_dummy.h b/libopenage/gamedata/util_dummy.h deleted file mode 100644 index 87c6b21868..0000000000 --- a/libopenage/gamedata/util_dummy.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. - -// Warning: this file is a dummy file and was auto-generated by the v0.4.1 converter; -// its purpose is to keep the deprecated gamestate compilable and intact; -// these files keep only the minimum functionality and should not be changed; -// For details, see buildsystem/codegen.cmake and openage/codegen. - -#pragma once - -#include -#include -#include "util/csv.h" - - - -namespace openage { -namespace gamedata { - -/** - * format for multi-subtype references - */ -struct multisubtype_ref { - std::string subtype; - std::string filename; - static constexpr size_t member_count = 2; - int fill(const std::string &line); - bool recurse(const openage::util::CSVCollection &storage, const std::string &basedir); - -}; - -} // gamedata -} // openage diff --git a/libopenage/util/color.cpp b/libopenage/util/color.cpp index 5254606f74..fed90a54a4 100644 --- a/libopenage/util/color.cpp +++ b/libopenage/util/color.cpp @@ -1,4 +1,4 @@ -// Copyright 2013-2019 the openage authors. See copying.md for legal info. +// Copyright 2013-2023 the openage authors. See copying.md for legal info. #include "color.h" @@ -6,13 +6,6 @@ namespace openage::util { -col::col(gamedata::palette_color c) { - this->r = c.r; - this->g = c.g; - this->b = c.b; - this->a = c.a; -} - void col::use() { //TODO use glColor4b glColor4f(r / 255.f, g / 255.f, b / 255.f, a / 255.f); @@ -22,4 +15,4 @@ void col::use(float alpha) { glColor4f(r / 255.f, g / 255.f, b / 255.f, alpha); } -} // openage::util +} // namespace openage::util diff --git a/libopenage/util/color.h b/libopenage/util/color.h index 326b1a1e2d..ee7199a8b7 100644 --- a/libopenage/util/color.h +++ b/libopenage/util/color.h @@ -1,15 +1,14 @@ -// Copyright 2013-2021 the openage authors. See copying.md for legal info. +// Copyright 2013-2023 the openage authors. See copying.md for legal info. #pragma once -#include "../gamedata/color_dummy.h" namespace openage { namespace util { struct col { - col(unsigned r, unsigned g, unsigned b, unsigned a) : r{r}, g{g}, b{b}, a{a} {} - col(gamedata::palette_color c); + col(unsigned r, unsigned g, unsigned b, unsigned a) : + r{r}, g{g}, b{b}, a{a} {} unsigned r, g, b, a; @@ -17,4 +16,5 @@ struct col { void use(float alpha); }; -}} // openage::util +} // namespace util +} // namespace openage From 32e968f15f965bd6787e4cedf7ca9684db5c6400 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 24 Sep 2023 00:26:01 +0200 Subject: [PATCH 42/95] coord: Remove deprecated conversions and types. --- libopenage/console/console.cpp | 2 +- libopenage/coord/CMakeLists.txt | 1 - libopenage/coord/coordmanager.cpp | 10 --- libopenage/coord/coordmanager.h | 56 --------------- libopenage/coord/declarations.h | 3 - libopenage/coord/phys.cpp | 43 ----------- libopenage/coord/phys.h | 11 --- libopenage/coord/pixel.cpp | 114 +++--------------------------- libopenage/coord/pixel.h | 62 ++-------------- libopenage/coord/scene.cpp | 3 +- libopenage/coord/tile.cpp | 29 -------- libopenage/coord/tile.h | 9 --- libopenage/pathfinding/path.h | 4 -- 13 files changed, 14 insertions(+), 333 deletions(-) delete mode 100644 libopenage/coord/coordmanager.cpp delete mode 100644 libopenage/coord/coordmanager.h diff --git a/libopenage/console/console.cpp b/libopenage/console/console.cpp index 04cf29d4d1..274cbc087e 100644 --- a/libopenage/console/console.cpp +++ b/libopenage/console/console.cpp @@ -106,7 +106,7 @@ void Console::register_to_engine() { // this->input_context.utf8_mode = true; } -void Console::set_visible(bool make_visible) { +void Console::set_visible(bool /* make_visible */) { // TODO: Use new renderer // if (make_visible) { diff --git a/libopenage/coord/CMakeLists.txt b/libopenage/coord/CMakeLists.txt index 5123577052..7f01010d8a 100644 --- a/libopenage/coord/CMakeLists.txt +++ b/libopenage/coord/CMakeLists.txt @@ -3,7 +3,6 @@ add_sources(libopenage chunk.cpp coord_test.cpp - coordmanager.cpp declarations.cpp phys.cpp pixel.cpp diff --git a/libopenage/coord/coordmanager.cpp b/libopenage/coord/coordmanager.cpp deleted file mode 100644 index 7d175b0702..0000000000 --- a/libopenage/coord/coordmanager.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2017-2018 the openage authors. See copying.md for legal info. - -#include "coordmanager.h" - -namespace openage { -namespace coord { - -// no implementation needed - -}} diff --git a/libopenage/coord/coordmanager.h b/libopenage/coord/coordmanager.h deleted file mode 100644 index 19195de83e..0000000000 --- a/libopenage/coord/coordmanager.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2017-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include "phys.h" -#include "pixel.h" -#include "tile.h" - -namespace openage { -namespace coord { - - -/** - * Holds all coordinate-related state and metadata. - * - * Among other things, this stores the camera positions. - * - * TODO: rename to CoordState! - */ -class CoordManager final { -public: - explicit CoordManager() {}; - - /** - * What's the current size of the viewport? - * (what's the coordinate of the top right pixel + (1, 1)?) - */ - viewport_delta viewport_size{800, 600}; - - /** - * What place (in Phys3) is the origin of the CamGame coordinate system looking at? - */ - phys3 camgame_phys{10, 10, 0}; - - /** - * Where in the viewport is the origin of the CamGame coordinate system? - * (this is usually the center of the viewport). - */ - viewport camgame_viewport{400, 300}; - - /** - * Where in the viewport is the origin of the CamHUD coordinate system? - * (this is usually the bottom left corner of the viewport) - */ - viewport camhud_viewport{0, 0}; - - /** - * The size of a terrain tile, in pixels. - * Rile diamonds are 96 pixels wide and 48 pixels high. - * The area of each tile is 96 * 48 * 0.5 square pixels. - */ - // TODO: dynamically get from nyan data - camgame_delta tile_size{96, 48}; -}; - -}} // namespace openage::coord diff --git a/libopenage/coord/declarations.h b/libopenage/coord/declarations.h index 05b89cb4fa..698b594aac 100644 --- a/libopenage/coord/declarations.h +++ b/libopenage/coord/declarations.h @@ -74,8 +74,5 @@ using term_t = int; struct term_delta; struct term; -// forward declaration of the coord manager -class CoordManager; - } // namespace coord } // namespace openage diff --git a/libopenage/coord/phys.cpp b/libopenage/coord/phys.cpp index bb5e89498d..2daf15ab20 100644 --- a/libopenage/coord/phys.cpp +++ b/libopenage/coord/phys.cpp @@ -2,7 +2,6 @@ #include "phys.h" -#include "coord/coordmanager.h" #include "coord/pixel.h" #include "coord/scene.h" #include "coord/tile.h" @@ -65,16 +64,6 @@ scene2 phys2::to_scene2() const { return scene2(this->ne, this->se); } - -[[deprecated]] phys3 phys2::to_phys3(const Terrain & /* terrain */, phys_t altitude) const { - // TODO: once terrain elevations have been implemented, - // query the terrain elevation at {ne, se}. - phys_t elevation = 0; - - return phys3{this->ne, this->se, elevation + altitude}; -} - - double phys3_delta::length() const { return math::hypot3(this->ne.to_double(), this->se.to_double(), this->up.to_double()); } @@ -108,22 +97,6 @@ phys_angle_t phys3_delta::to_angle(const coord::phys2_delta &other) const { return phys_angle_t::from_float(angle); } - -[[deprecated]] camgame_delta phys3_delta::to_camgame(const CoordManager &mgr) const { - // apply transformation matrix to phys3_delta, to get 'scaled': - // (ne) - // (x) = (+1 +1 +0) (se) - // (y) = (+1 -1 +1) (up) - phys_t x = phys_t{this->ne} * (+1) + this->se * (+1) + this->up * (+0); - phys_t y = phys_t{this->ne} * (+1) + this->se * (-1) + this->up * (+1); - - // add scaling (w/2 for x, h/2 for y) - return camgame_delta{ - static_cast((x * (mgr.tile_size.x / 2)).to_int()), - static_cast((y * (mgr.tile_size.y / 2)).to_int())}; -} - - tile3 phys3::to_tile3() const { return tile3{this->ne.to_int(), this->se.to_int(), this->up.to_int()}; } @@ -143,20 +116,4 @@ scene3 phys3::to_scene3() const { return scene3{this->ne, this->se, this->up}; } - -[[deprecated]] camgame phys3::to_camgame(const CoordManager &mgr) const { - return (*this - mgr.camgame_phys).to_camgame(mgr) + camgame{0, 0}; -} - - -[[deprecated]] viewport phys3::to_viewport(const CoordManager &mgr) const { - return this->to_camgame(mgr).to_viewport(mgr); -} - - -[[deprecated]] camhud phys3::to_camhud(const CoordManager &mgr) const { - return this->to_viewport(mgr).to_camhud(mgr); -} - - } // namespace openage::coord diff --git a/libopenage/coord/phys.h b/libopenage/coord/phys.h index 3a88072fff..7d933410f3 100644 --- a/libopenage/coord/phys.h +++ b/libopenage/coord/phys.h @@ -44,9 +44,6 @@ struct phys2 : CoordNeSeAbsolute { tile to_tile() const; phys3 to_phys3(phys_t up = 0) const; scene2 to_scene2() const; - - // TODO: Remove - [[deprecated]] phys3 to_phys3(const Terrain &terrain, phys_t altitude = 0) const; }; struct phys3_delta : CoordNeSeUpRelative { @@ -66,9 +63,6 @@ struct phys3_delta : CoordNeSeUpRelative { // TODO: This DOES NOT use fixed point math currently phys_angle_t to_angle(const coord::phys2_delta &other = {-1, 1}) const; - - // TODO: Remove - [[deprecated]] camgame_delta to_camgame(const CoordManager &mgr) const; }; struct phys3 : CoordNeSeUpAbsolute { @@ -79,11 +73,6 @@ struct phys3 : CoordNeSeUpAbsolute { tile to_tile() const; phys2 to_phys2() const; scene3 to_scene3() const; - - // TODO: Remove - [[deprecated]] camgame to_camgame(const CoordManager &mgr) const; - [[deprecated]] viewport to_viewport(const CoordManager &mgr) const; - [[deprecated]] camhud to_camhud(const CoordManager &mgr) const; }; diff --git a/libopenage/coord/pixel.cpp b/libopenage/coord/pixel.cpp index 24ad6a507f..c7dac5f815 100644 --- a/libopenage/coord/pixel.cpp +++ b/libopenage/coord/pixel.cpp @@ -2,86 +2,25 @@ #include "pixel.h" -#include "coord/coordmanager.h" #include "coord/phys.h" #include "renderer/camera/camera.h" namespace openage { namespace coord { - -phys3_delta camgame_delta::to_phys3(const CoordManager &mgr, phys_t up) const { - // apply scaling factor; w/2 for x, h/2 for y - phys_t x = phys_t::from_int(this->x) / static_cast(mgr.tile_size.x / 2); - phys_t y = phys_t::from_int(this->y) / static_cast(mgr.tile_size.y / 2); - - // apply transformation matrix to 'scaled', - // to get the relative phys3 position - // - // a camgame position represents a line in the 3D phys space - // a camgame delta of 0 might actually correlate to an arbitrarily - // large phys delta. - // we select one specific point on that line by explicitly specifying the - // 'up' value of the result. - // - // the transformation matrix is: - // - // (ne) = (+0.5 +0.5 +0.5) ( x) - // (se) = (+0.5 -0.5 -0.5) ( y) - // (up) = (+0.0 +0.0 +1.0) (up) - phys3_delta result; - result.ne = (x + y + up) / 2L; - result.se = (x - y - up) / 2L; - result.up = (up); - - return result; -} - - -viewport_delta camgame_delta::to_viewport() const { - return viewport_delta{this->x, this->y}; -} - - -viewport camgame::to_viewport(const CoordManager &mgr) const { - // reverse of viewport::to_camgame - return (*this - camgame{0, 0}).to_viewport() + mgr.camgame_viewport; -} - - -camhud camgame::to_camhud(const CoordManager &mgr) const { - return this->to_viewport(mgr).to_camhud(mgr); -} - - -phys3 camgame::to_phys3(const CoordManager &mgr, phys_t up) const { - return (*this - camgame{0, 0}).to_phys3(mgr, up) + mgr.camgame_phys; -} - - -tile camgame::to_tile(const CoordManager &mgr, phys_t up) const { - return this->to_phys3(mgr, up).to_tile(); -} - - viewport_delta camhud_delta::to_viewport() const { return viewport_delta{this->x, this->y}; } -viewport camhud::to_viewport(const CoordManager &mgr) const { +viewport camhud::to_viewport() const { // reverse of viewport::to_camhud - return (*this - camhud{0, 0}).to_viewport() + mgr.camhud_viewport; + return (*this - camhud{0, 0}).to_viewport() + viewport{0, 0}; } -[[deprecated]] phys3_delta viewport_delta::to_phys3(const CoordManager &mgr, phys_t up) const { - return this->to_camgame().to_phys3(mgr, up); -} - - -camhud viewport::to_camhud(const CoordManager &mgr) const { - return camhud{0, 0} + (*this - mgr.camhud_viewport).to_camhud(); +camhud viewport::to_camhud() const { + return camhud{0, 0} + (*this - viewport{0, 0}).to_camhud(); } @@ -92,44 +31,18 @@ Eigen::Vector2f viewport::to_ndc_space(const std::shared_ptrto_camgame(mgr).to_phys3(mgr, up); -} - - -[[deprecated]] tile viewport::to_tile(const CoordManager &mgr, phys_t up) const { - return this->to_camgame(mgr).to_tile(mgr, up); -} - - -viewport_delta input_delta::to_viewport(const CoordManager &mgr) const { +viewport_delta input_delta::to_viewport(const std::shared_ptr &camera) const { viewport_delta result; result.x = this->x; - result.y = mgr.viewport_size.y - this->y; + result.y = camera->get_viewport_size()[1] - this->y; return result; } -[[deprecated]] camgame_delta input_delta::to_camgame(const CoordManager &mgr) const { - return this->to_viewport(mgr).to_camgame(); -} - - -[[deprecated]] phys3_delta input_delta::to_phys3(const CoordManager &mgr, phys_t up) const { - return this->to_viewport(mgr).to_camgame().to_phys3(mgr, up); -} - - -viewport input::to_viewport(const CoordManager &mgr) const { - return viewport{0, 0} + (*this - input{0, 0}).to_viewport(mgr); +viewport input::to_viewport(const std::shared_ptr &camera) const { + return viewport{0, 0} + (*this - input{0, 0}).to_viewport(camera); } @@ -155,16 +68,5 @@ scene3 input::to_scene3(const std::shared_ptr &camera) return scene3(-p_intersect.z(), p_intersect.x(), 0.0f); } - -[[deprecated]] phys3 input::to_phys3(const CoordManager &mgr, phys_t up) const { - return this->to_viewport(mgr).to_camgame(mgr).to_phys3(mgr, up); -} - - -[[deprecated]] camgame input::to_camgame(const CoordManager &mgr) const { - return this->to_viewport(mgr).to_camgame(mgr); -} - - } // namespace coord } // namespace openage diff --git a/libopenage/coord/pixel.h b/libopenage/coord/pixel.h index 5c42b92a4a..e97106224b 100644 --- a/libopenage/coord/pixel.h +++ b/libopenage/coord/pixel.h @@ -21,41 +21,6 @@ namespace coord { * See doc/code/coordinate-systems.md for more information. */ - -// TODO: Remove -struct [[deprecated]] camgame_delta : CoordXYRelative { - using CoordXYRelative::CoordXYRelative; - - /** - * There are infinite solutions to this conversion problem because - * a 2D coordinate is converted into a 3D coordinate. - * - * The user needs to manually give the 'up' value of the phys3 result. - */ - phys3_delta to_phys3(const CoordManager &mgr, phys_t up = phys_t::zero()) const; - viewport_delta to_viewport() const; -}; - - -// TODO: Remove -struct [[deprecated]] camgame : CoordXYAbsolute { - using CoordXYAbsolute::CoordXYAbsolute; - - /** - * See the comments for camgame_delta::to_phys3. - * - * TODO: Once we have terrain elevation, 'up' will not mean the absolute - * elevation, but instead the returned phys3 coordinate will be - * the intersection between the camgame line and the 3d terrain + - * up altitude. - */ - viewport to_viewport(const CoordManager &mgr) const; - camhud to_camhud(const CoordManager &mgr) const; - phys3 to_phys3(const CoordManager &mgr, phys_t up = phys_t::zero()) const; - tile to_tile(const CoordManager &mgr, phys_t up = phys_t::zero()) const; -}; - - struct camhud_delta : CoordXYRelative { using CoordXYRelative::CoordXYRelative; @@ -68,7 +33,7 @@ struct camhud : CoordXYAbsolute { using CoordXYAbsolute::CoordXYAbsolute; // coordinate conversions - viewport to_viewport(const CoordManager &mgr) const; + viewport to_viewport() const; }; @@ -79,12 +44,6 @@ struct viewport_delta : CoordXYRelative { camhud_delta to_camhud() const { return camhud_delta{this->x, this->y}; } - - // TODO: Remove - [[deprecated]] constexpr camgame_delta to_camgame() const { - return camgame_delta{this->x, this->y}; - } - [[deprecated]] phys3_delta to_phys3(const CoordManager &mgr, phys_t up) const; }; @@ -92,15 +51,10 @@ struct viewport : CoordXYAbsolute { using CoordXYAbsolute::CoordXYAbsolute; // coordinate conversions - camhud to_camhud(const CoordManager &mgr) const; + camhud to_camhud() const; // renderer conversions Eigen::Vector2f to_ndc_space(const std::shared_ptr &camera) const; - - // TODO: Remove - [[deprecated]] camgame to_camgame(const CoordManager &mgr) const; - [[deprecated]] phys3 to_phys3(const CoordManager &mgr, phys_t up = phys_t::zero()) const; - [[deprecated]] tile to_tile(const CoordManager &mgr, phys_t up = phys_t::zero()) const; }; @@ -108,11 +62,7 @@ struct input_delta : CoordXYRelative { using CoordXYRelative::CoordXYRelative; // coordinate conversions - viewport_delta to_viewport(const CoordManager &mgr) const; - - // TODO: Remove - [[deprecated]] camgame_delta to_camgame(const CoordManager &mgr) const; - [[deprecated]] phys3_delta to_phys3(const CoordManager &mgr, phys_t up = phys_t::zero()) const; + viewport_delta to_viewport(const std::shared_ptr &camera) const; }; @@ -120,13 +70,9 @@ struct input : CoordXYAbsolute { using CoordXYAbsolute::CoordXYAbsolute; // coordinate conversions - viewport to_viewport(const CoordManager &mgr) const; + viewport to_viewport(const std::shared_ptr &camera) const; phys3 to_phys3(const std::shared_ptr &camera) const; scene3 to_scene3(const std::shared_ptr &camera) const; - - // TODO: Remove - [[deprecated]] phys3 to_phys3(const CoordManager &mgr, phys_t up = phys_t::zero()) const; - [[deprecated]] camgame to_camgame(const CoordManager &mgr) const; }; diff --git a/libopenage/coord/scene.cpp b/libopenage/coord/scene.cpp index d34519bfe4..45e262d519 100644 --- a/libopenage/coord/scene.cpp +++ b/libopenage/coord/scene.cpp @@ -4,7 +4,6 @@ #include -#include "coord/coordmanager.h" #include "coord/pixel.h" #include "coord/tile.h" #include "util/math.h" @@ -108,7 +107,7 @@ Eigen::Vector3f scene3_delta::to_world_space() const { } float scene3_delta::to_angle(const coord::scene2_delta &other) const { - return this->to_scene2().to_angle(); + return this->to_scene2().to_angle(other); } scene2 scene3::to_scene2() const { diff --git a/libopenage/coord/tile.cpp b/libopenage/coord/tile.cpp index dbd68a0d5a..b89f1e9578 100644 --- a/libopenage/coord/tile.cpp +++ b/libopenage/coord/tile.cpp @@ -3,7 +3,6 @@ #include "tile.h" #include "../terrain/terrain.h" -#include "coordmanager.h" namespace openage::coord { @@ -37,34 +36,6 @@ tile_delta tile::get_pos_on_chunk() const { } -[[deprecated]] tile3 tile::to_tile3(const Terrain & /*terrain*/, tile_t altitude) const { - // TODO: once terrain elevations have been implemented, - // query the terrain elevation at {ne, se}. - tile_t elevation = 0; - - return tile3{this->ne, this->se, elevation + altitude}; -} - - -[[deprecated]] phys3 tile::to_phys3(const Terrain &terrain, tile_t altitude) const { - return this->to_tile3(terrain, altitude).to_phys3(); -} - - -[[deprecated]] camgame tile::to_camgame(const CoordManager &mgr, - const Terrain &terrain, - tile_t altitude) const { - return this->to_phys3(terrain, altitude).to_camgame(mgr); -} - - -[[deprecated]] viewport tile::to_viewport(const CoordManager &mgr, - const Terrain &terrain, - tile_t altitude) const { - return this->to_camgame(mgr, terrain, altitude).to_viewport(mgr); -} - - phys2 tile3::to_phys2() const { return this->to_tile().to_phys2(); } diff --git a/libopenage/coord/tile.h b/libopenage/coord/tile.h index 4570564d32..df08045e21 100644 --- a/libopenage/coord/tile.h +++ b/libopenage/coord/tile.h @@ -14,9 +14,6 @@ class Terrain; namespace coord { -class CoordManager; - - /* * Gameworld tile-related coordinate systems. * See doc/code/coordinate-systems.md for more information. @@ -41,12 +38,6 @@ struct tile : CoordNeSeAbsolute { phys3 to_phys3(tile_t up = 0) const; chunk to_chunk() const; tile_delta get_pos_on_chunk() const; - - // TODO: Remove - [[deprecated]] tile3 to_tile3(const Terrain &terrain, tile_t altitude = 0) const; - [[deprecated]] phys3 to_phys3(const Terrain &terrain, tile_t altitude = 0) const; - [[deprecated]] camgame to_camgame(const CoordManager &mgr, const Terrain &terrain, tile_t altitude = 0) const; - [[deprecated]] viewport to_viewport(const CoordManager &mgr, const Terrain &terrain, tile_t altitude = 0) const; }; struct tile3_delta : CoordNeSeUpRelative { diff --git a/libopenage/pathfinding/path.h b/libopenage/pathfinding/path.h index 033090ca6b..e41ddbcc28 100644 --- a/libopenage/pathfinding/path.h +++ b/libopenage/pathfinding/path.h @@ -16,10 +16,6 @@ namespace openage { -namespace coord { -class CoordManager; -} - namespace path { class Node; From 66b317ef1c77b9f23cfc48f4ded765e3a93ddee2 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 24 Sep 2023 00:33:32 +0200 Subject: [PATCH 43/95] refactor: Remove nyan directory. --- libopenage/nyan/db.h | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 libopenage/nyan/db.h diff --git a/libopenage/nyan/db.h b/libopenage/nyan/db.h deleted file mode 100644 index 23a39980a6..0000000000 --- a/libopenage/nyan/db.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2018-2019 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "../log/log.h" -#include "../error/error.h" - -namespace openage::nyan { - -} From ab404ca601313ec440d7a244c698f92c355392bf Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 24 Sep 2023 00:45:34 +0200 Subject: [PATCH 44/95] refactor: Remove SDL from remaining engine code. --- libopenage/console/console.h | 1 - libopenage/event/demo/main.cpp | 10 +++++-- libopenage/versions/versions.cpp | 49 ++++---------------------------- 3 files changed, 13 insertions(+), 47 deletions(-) diff --git a/libopenage/console/console.h b/libopenage/console/console.h index 839467e6a1..380a563e17 100644 --- a/libopenage/console/console.h +++ b/libopenage/console/console.h @@ -2,7 +2,6 @@ #pragma once -#include #include #include "../coord/pixel.h" diff --git a/libopenage/event/demo/main.cpp b/libopenage/event/demo/main.cpp index 442e9910c7..3ccbed5ac6 100644 --- a/libopenage/event/demo/main.cpp +++ b/libopenage/event/demo/main.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include "config.h" #include "event/demo/aicontroller.h" @@ -13,6 +13,7 @@ #include "event/demo/physics.h" #include "event/event.h" #include "event/event_loop.h" +#include "renderer/gui/integration/public/gui_application_with_logger.h" #if WITH_NCURSES #ifdef __MINGW32__ @@ -41,6 +42,7 @@ enum class timescale { void curvepong(bool disable_gui, bool no_human) { + renderer::gui::GuiApplicationWithLogger gui_app{}; bool enable_gui = not disable_gui; bool human_player = not no_human; @@ -99,6 +101,8 @@ void curvepong(bool disable_gui, bool no_human) { while (state->p1->lives->get(now) > 0 and state->p2->lives->get(now) > 0) { auto loop_start = Clock::now(); + gui_app.process_events(); + #if WITH_NCURSES if (enable_gui) { gui->clear(); @@ -157,7 +161,7 @@ void curvepong(bool disable_gui, bool no_human) { if (speed == timescale::NOSLEEP) { // increase the simulation loop time a bit - SDL_Delay(5); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); } dt_ms_t dt_us = Clock::now() - loop_start; @@ -166,7 +170,7 @@ void curvepong(bool disable_gui, bool no_human) { dt_ms_t wait_time = per_frame - dt_us; if (wait_time > dt_ms_t::zero()) { - SDL_Delay(wait_time.count()); + std::this_thread::sleep_for(wait_time); } } diff --git a/libopenage/versions/versions.cpp b/libopenage/versions/versions.cpp index c94d898f33..8e2e63d215 100644 --- a/libopenage/versions/versions.cpp +++ b/libopenage/versions/versions.cpp @@ -11,37 +11,21 @@ #include #include #include -#include #include -#include "versions/compiletime.h" #include "../util/strings.h" +#include "versions/compiletime.h" namespace openage::versions { std::map get_version_numbers() { - std::map version_numbers; - // SDL runtime version number - SDL_version sdl_runtime_version; - SDL_GetVersion(&sdl_runtime_version); - version_numbers.emplace("SDL-runtime", util::sformat("%d.%d.%d", - sdl_runtime_version.major, - sdl_runtime_version.minor, - sdl_runtime_version.patch)); - // Eigen compiletime version number - version_numbers.emplace("Eigen", util::sformat("%d.%d.%d", - EIGEN_WORLD_VERSION, - EIGEN_MAJOR_VERSION, - EIGEN_MINOR_VERSION)); + version_numbers.emplace("Eigen", util::sformat("%d.%d.%d", EIGEN_WORLD_VERSION, EIGEN_MAJOR_VERSION, EIGEN_MINOR_VERSION)); // Harfbuzz compiletime version number - version_numbers.emplace("Harfbuzz", util::sformat("%d.%d.%d", - HB_VERSION_MAJOR, - HB_VERSION_MINOR, - HB_VERSION_MICRO)); + version_numbers.emplace("Harfbuzz", util::sformat("%d.%d.%d", HB_VERSION_MAJOR, HB_VERSION_MINOR, HB_VERSION_MICRO)); // Add Qt version number version_numbers.emplace("Qt", QT_VERSION_STR); @@ -49,38 +33,17 @@ std::map get_version_numbers() { // Add nyan version number version_numbers.emplace("nyan", nyan_version); - // Add OpenGL version number - // TODO: set the same SDL_GL_CONTEXT_MAJOR_VERSION as the real renderer - if (SDL_Init(SDL_INIT_VIDEO) != 0) { - version_numbers.emplace("OpenGL", SDL_GetError()); - } - else { - SDL_Window *window = SDL_CreateWindow("Query OpenGL version", - 0, 0, 640, 480, - SDL_WINDOW_OPENGL|SDL_WINDOW_HIDDEN); - if (window != nullptr) { - SDL_GLContext glcontext = SDL_GL_CreateContext(window); - if (glcontext != nullptr) { - version_numbers.emplace("OpenGL", - reinterpret_cast(glGetString(GL_VERSION))); - SDL_GL_DeleteContext(glcontext); - } - SDL_DestroyWindow(window); - } - SDL_Quit(); - } - // Add Opus version number std::string opus_version = opus_get_version_string(); version_numbers.emplace("Opus", opus_version.substr(opus_version.find(' ') + 1)); + // TODO: Add OpenGL version number + #ifdef __linux__ // Add libc version number if not MacOSX version_numbers.emplace("libc-runtime", gnu_get_libc_version()); - version_numbers.emplace("libc-compile", util::sformat("%d.%d", - __GLIBC__, - __GLIBC_MINOR__)); + version_numbers.emplace("libc-compile", util::sformat("%d.%d", __GLIBC__, __GLIBC_MINOR__)); #endif #ifdef __APPLE__ From 931a672ed15f77d6d9baa61479f495cab00fd1c6 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 24 Sep 2023 14:43:08 +0200 Subject: [PATCH 45/95] audio: Port audio manager to Qt6. This needs some additional work! --- libopenage/audio/audio_manager.cpp | 188 +++++++++++------------------ libopenage/audio/audio_manager.h | 51 ++++---- 2 files changed, 95 insertions(+), 144 deletions(-) diff --git a/libopenage/audio/audio_manager.cpp b/libopenage/audio/audio_manager.cpp index 5bda65e6e9..ce19e77073 100644 --- a/libopenage/audio/audio_manager.cpp +++ b/libopenage/audio/audio_manager.cpp @@ -3,94 +3,59 @@ #include "audio_manager.h" #include -#include #include +#include +#include +#include +#include + +#include "../log/log.h" +#include "../util/misc.h" #include "error.h" #include "hash_functions.h" #include "resource.h" -#include "../log/log.h" -#include "../util/misc.h" namespace openage { namespace audio { - - - -/** - * Wrapper class for the sdl audio device locking so - * the device doesn't deadlock because of funny exceptions. - */ -class SDLDeviceLock { -public: - explicit SDLDeviceLock(const SDL_AudioDeviceID &id) - : - dev_id{id} { - SDL_LockAudioDevice(this->dev_id); - } - - ~SDLDeviceLock() { - SDL_UnlockAudioDevice(this->dev_id); - } - - SDLDeviceLock(SDLDeviceLock &&) = delete; - SDLDeviceLock(const SDLDeviceLock &) = delete; - SDLDeviceLock& operator =(SDLDeviceLock &&) = delete; - SDLDeviceLock& operator =(const SDLDeviceLock &) = delete; - -private: - SDL_AudioDeviceID dev_id; -}; - - -AudioManager::AudioManager(job::JobManager *job_manager, - const std::string &device_name) - : +AudioManager::AudioManager(const std::shared_ptr &job_manager, + const std::string &device_name) : available{false}, job_manager{job_manager}, - device_name{device_name} { + device_name{device_name}, + device_format{std::make_shared()}, + device{nullptr}, + audio_sink{nullptr} { + // set desired audio output format + this->device_format->setSampleRate(48000); + this->device_format->setSampleFormat(QAudioFormat::SampleFormat::Int16); + this->device_format->setChannelCount(2); + + // find the device with the given name + for (auto &device : QMediaDevices::audioOutputs()) { + if (device.description().toStdString() == device_name) { + this->device = std::make_shared(device); + break; + } + } - if (SDL_Init(SDL_INIT_AUDIO) < 0) { - log::log(MSG(err) - << "SDL audio initialization failed: " - << SDL_GetError()); + // select the default device if the name was not found + if (not this->device) { + this->device = std::make_shared(QMediaDevices::defaultAudioOutput()); return; - } else { - log::log(MSG(info) << "SDL audio subsystems initialized"); } - // set desired audio output format - SDL_AudioSpec desired_spec; - SDL_zero(desired_spec); - desired_spec.freq = 48000; - desired_spec.format = AUDIO_S16LSB; - desired_spec.channels = 2; - desired_spec.samples = 4096; - desired_spec.userdata = this; - - // call back that is invoked once SDL needs the next chunk of data - desired_spec.callback = [] (void *userdata, uint8_t *stream, int len) { - auto *audio_manager = static_cast(userdata); - audio_manager->audio_callback(reinterpret_cast(stream), len / 2); - }; - - // convert device name to valid parameter for sdl call - // if the device name is empty, use a nullptr in order to indicate that the - // default device should be used - const char *c_device_name = device_name.empty() ? - nullptr : device_name.c_str(); - // open audio playback device - device_id = SDL_OpenAudioDevice(c_device_name, 0, &desired_spec, - &device_spec, 0); - - // no device could be opened - if (device_id == 0) { - log::log(MSG(err) << "Error opening audio device: " << SDL_GetError()); + if (not this->device->isFormatSupported(*this->device_format)) { + log::log(MSG(err) << "Audio device does not support the desired format!"); return; } + // create audio sink + this->audio_sink = std::make_unique(*this->device.get(), *this->device_format.get()); + // TODO: connect callback to get audio data to device + // initialize playing sounds vectors using sound_vector = std::vector>; playing_sounds.insert({category_t::GAME, sound_vector{}}); @@ -100,25 +65,23 @@ AudioManager::AudioManager(job::JobManager *job_manager, // create buffer for mixing this->mix_buffer = std::make_unique( - 4 * device_spec.samples * device_spec.channels - ); + 4 * device_format->bytesPerSample() * device_format->channelCount()); - log::log(MSG(info) << - "Using audio device: " - << (device_name.empty() ? "default" : device_name) - << " [freq=" << device_spec.freq - << ", format=" << device_spec.format - << ", channels=" << static_cast(device_spec.channels) - << ", samples=" << device_spec.samples - << "]"); + log::log(MSG(info) << "Using audio device: " + << (device_name.empty() ? "default" : device_name) + << " [sample rate=" << device_format->sampleRate() + << ", format=" << device_format->sampleFormat() + << ", channels=" << device_format->channelCount() + << ", samples=" << device_format->bytesPerSample() + << "]"); - SDL_PauseAudioDevice(device_id, 0); + this->audio_sink->stop(); this->available = true; } AudioManager::~AudioManager() { - SDL_CloseAudioDevice(device_id); + this->audio_sink->stop(); } void AudioManager::load_resources(const std::vector &sound_files) { @@ -148,11 +111,10 @@ Sound AudioManager::get_sound(category_t category, int id) { auto resource = resources.find(std::make_tuple(category, id)); if (resource == std::end(resources)) { throw audio::Error{ - MSG(err) << - "Sound resource does not exist: " - "category=" << category << ", " << - "id=" << id - }; + MSG(err) << "Sound resource does not exist: " + "category=" + << category << ", " + << "id=" << id}; } auto sound_impl = std::make_shared(resource->second); @@ -161,7 +123,7 @@ Sound AudioManager::get_sound(category_t category, int id) { void AudioManager::audio_callback(int16_t *stream, int length) { - std::memset(mix_buffer.get(), 0, length*4); + std::memset(mix_buffer.get(), 0, length * 4); // iterate over all categories for (auto &entry : this->playing_sounds) { @@ -181,28 +143,25 @@ void AudioManager::audio_callback(int16_t *stream, int length) { // write the mix buffer to the output stream and adjust volume for (int i = 0; i < length; i++) { - auto value = mix_buffer[i]/256; + auto value = mix_buffer[i] / 256; if (value > 32767) { value = 32767; - } else if (value < -32768) { + } + else if (value < -32768) { value = -32768; } stream[i] = static_cast(value); } } -void AudioManager::add_sound(const std::shared_ptr& sound) { - SDLDeviceLock lock{this->device_id}; - +void AudioManager::add_sound(const std::shared_ptr &sound) { auto category = sound->get_category(); auto &playing_list = this->playing_sounds.find(category)->second; // TODO probably check if sound already exists in playing list playing_list.push_back(sound); } -void AudioManager::remove_sound(const std::shared_ptr& sound) { - SDLDeviceLock lock{this->device_id}; - +void AudioManager::remove_sound(const std::shared_ptr &sound) { auto category = sound->get_category(); auto &playing_list = this->playing_sounds.find(category)->second; @@ -214,11 +173,11 @@ void AudioManager::remove_sound(const std::shared_ptr& sound) { } } -SDL_AudioSpec AudioManager::get_device_spec() const { - return this->device_spec; +const std::shared_ptr &AudioManager::get_device_spec() const { + return this->device_format; } -job::JobManager *AudioManager::get_job_manager() const { +const std::shared_ptr &AudioManager::get_job_manager() const { return this->job_manager; } @@ -228,32 +187,21 @@ bool AudioManager::is_available() const { std::vector AudioManager::get_devices() { + auto devices = QMediaDevices::audioOutputs(); + std::vector device_list; - auto num_devices = SDL_GetNumAudioDevices(0); - device_list.reserve(num_devices); - for (int i = 0; i < num_devices; i++) { - device_list.emplace_back(SDL_GetAudioDeviceName(i, 0)); - } - return device_list; -} + device_list.reserve(devices.size()); -std::vector AudioManager::get_drivers() { - std::vector driver_list; - auto num_drivers = SDL_GetNumAudioDrivers(); - driver_list.reserve(num_drivers); - for (int i = 0; i < num_drivers; i++) { - driver_list.emplace_back(SDL_GetAudioDriver(i)); + for (auto &device : devices) { + device_list.emplace_back(device.description().toStdString()); } - return driver_list; + + return device_list; } -std::string AudioManager::get_current_driver() { - const char *c_driver = SDL_GetCurrentAudioDriver(); - if (c_driver == nullptr) { - return ""; - } else { - return c_driver; - } +std::string AudioManager::get_default_device() { + return QMediaDevices::defaultAudioOutput().description().toStdString(); } -}} // openage::audio +} // namespace audio +} // namespace openage diff --git a/libopenage/audio/audio_manager.h b/libopenage/audio/audio_manager.h index af14d5ebb2..8d3269a5a2 100644 --- a/libopenage/audio/audio_manager.h +++ b/libopenage/audio/audio_manager.h @@ -7,13 +7,16 @@ #include #include -#include +#include #include "category.h" #include "hash_functions.h" #include "resource_def.h" #include "sound.h" +Q_FORWARD_DECLARE_OBJC_CLASS(QAudioDevice); +Q_FORWARD_DECLARE_OBJC_CLASS(QAudioFormat); +Q_FORWARD_DECLARE_OBJC_CLASS(QAudioSink); namespace openage { @@ -26,6 +29,8 @@ namespace audio { /** * This class provides audio functionality for openage. + * + * TODO: Finish porting to Qt. */ class AudioManager { public: @@ -33,7 +38,7 @@ class AudioManager { * Initializes the audio manager with the given device name. * If the name is empty, the default device is used. */ - AudioManager(job::JobManager *job_manager, + AudioManager(const std::shared_ptr &job_manager, const std::string &device_name = ""); ~AudioManager(); @@ -66,12 +71,12 @@ class AudioManager { /** * Returns the currently used audio output format. */ - SDL_AudioSpec get_device_spec() const; + const std::shared_ptr &get_device_spec() const; /** * Return the game engine the audio manager is attached to. */ - job::JobManager *get_job_manager() const; + const std::shared_ptr &get_job_manager() const; /** * If this audio manager is available. @@ -79,6 +84,16 @@ class AudioManager { */ bool is_available() const; + /** + * Returns a vector of all available device names. + */ + static std::vector get_devices(); + + /** + * Returns the default device name. + */ + static std::string get_default_device(); + private: void add_sound(const std::shared_ptr &sound); void remove_sound(const std::shared_ptr &sound); @@ -96,7 +111,7 @@ class AudioManager { /** * The job manager used in this audio manager for job queuing. */ - job::JobManager *job_manager; + std::shared_ptr job_manager; /** * the used audio device's name @@ -106,12 +121,17 @@ class AudioManager { /** * the audio output format */ - SDL_AudioSpec device_spec; + std::shared_ptr device_format; /** * the used audio device's id */ - SDL_AudioDeviceID device_id; + std::shared_ptr device; + + /** + * the audio sink + */ + std::shared_ptr audio_sink; /** * Buffer used for mixing audio to one stream. @@ -121,23 +141,6 @@ class AudioManager { std::unordered_map, std::shared_ptr> resources; std::unordered_map>> playing_sounds; - - // static functions -public: - /** - * Returns a vector of all available device names. - */ - static std::vector get_devices(); - - /** - * Returns a vector of all available driver names. - */ - static std::vector get_drivers(); - - /** - * Returns the name of the currently used driver. - */ - static std::string get_current_driver(); }; } // namespace audio From ada257f3cc144d9139b68af577548e3343faff99 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 24 Sep 2023 14:54:27 +0200 Subject: [PATCH 46/95] buildsys: Add QtMultimedia dependency. --- doc/build_instructions/arch_linux.md | 2 +- doc/build_instructions/debian.md | 2 +- doc/build_instructions/fedora.md | 2 +- doc/build_instructions/opensuse.md | 2 +- doc/build_instructions/ubuntu.md | 2 +- doc/build_instructions/windows_msvc.md | 2 +- doc/building.md | 2 +- libopenage/CMakeLists.txt | 5 +++-- packaging/docker/devenv/Dockerfile.ubuntu.2204 | 2 ++ 9 files changed, 12 insertions(+), 9 deletions(-) diff --git a/doc/build_instructions/arch_linux.md b/doc/build_instructions/arch_linux.md index 7665cb9888..cd6af02cd7 100644 --- a/doc/build_instructions/arch_linux.md +++ b/doc/build_instructions/arch_linux.md @@ -4,7 +4,7 @@ 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` +`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 qt6-multimedia` Additionally, you have to install [`toml11`](https://aur.archlinux.org/packages/toml11) from the AUR. If you have `yay`, you can run this command: diff --git a/doc/build_instructions/debian.md b/doc/build_instructions/debian.md index 5381ef165e..d9be204189 100644 --- a/doc/build_instructions/debian.md +++ b/doc/build_instructions/debian.md @@ -1,6 +1,6 @@ # Prerequisite steps for Debian users - `sudo apt-get update` - - `sudo apt-get install cmake cython3 libeigen3-dev libepoxy-dev libfontconfig1-dev libfreetype-dev libharfbuzz-dev libogg-dev libopus-dev libopusfile-dev libpng-dev libsdl2-dev libsdl2-image-dev libtoml11-dev python3-dev python3-mako python3-numpy python3-lz4 python3-pil python3-pip python3-pygments python3-toml qml6-module-qtquick-controls qt6-declarative-dev` + - `sudo apt-get install cmake cython3 libeigen3-dev libepoxy-dev libfontconfig1-dev libfreetype-dev libharfbuzz-dev libogg-dev libopus-dev libopusfile-dev libpng-dev libsdl2-dev libsdl2-image-dev libtoml11-dev python3-dev python3-mako python3-numpy python3-lz4 python3-pil python3-pip python3-pygments python3-toml qml6-module-qtquick-controls qt6-declarative-dev qt6-multimedia-dev qml6-module-qtquick3d-spatialaudio` You will also need [nyan](https://github.com/SFTtech/nyan/blob/master/doc/building.md) and its dependencies. diff --git a/doc/build_instructions/fedora.md b/doc/build_instructions/fedora.md index c710a57282..c911ec8eb9 100644 --- a/doc/build_instructions/fedora.md +++ b/doc/build_instructions/fedora.md @@ -2,6 +2,6 @@ Run the following command: -`sudo dnf install clang cmake eigen3-devel fontconfig-devel gcc-c harfbuzz-devel libepoxy-devel libogg-devel libopusenc-devel libpng-devel opusfile-devel python3-Cython python3-devel python3-mako python3-numpy python3-lz4 python3-pillow python3-pygments python3-toml SDL2-devel SDL2_image-devel++ toml11-devel qt6-qtdeclarative-devel` +`sudo dnf install clang cmake eigen3-devel fontconfig-devel gcc-c harfbuzz-devel libepoxy-devel libogg-devel libopusenc-devel libpng-devel opusfile-devel python3-Cython python3-devel python3-mako python3-numpy python3-lz4 python3-pillow python3-pygments python3-toml SDL2-devel SDL2_image-devel++ toml11-devel qt6-qtdeclarative-devel qt6-qtmultimedia-devel` You will also need [nyan](https://github.com/SFTtech/nyan/blob/master/doc/building.md) and its dependencies. diff --git a/doc/build_instructions/opensuse.md b/doc/build_instructions/opensuse.md index e2b51c41ef..15166d5032 100644 --- a/doc/build_instructions/opensuse.md +++ b/doc/build_instructions/opensuse.md @@ -1,5 +1,5 @@ # Prerequisite steps for openSUSE users -- `zypper install --no-recommends cmake doxygen eigen3-devel fontconfig-devel gcc-c graphviz++ harfbuzz-devel libSDL2-devel libSDL2_image-devel libepoxy-devel libfreetype-dev libogg-devel libopus-devel libpng-devel libtoml11-dev libqt6-qtdeclarative-devel libqt6-qtquickcontrols opusfile-devel python3-Cython python3-Mako python3-lz4 python3-Pillow python3-Pygments python3-toml python3-devel` +- `zypper install --no-recommends cmake doxygen eigen3-devel fontconfig-devel gcc-c graphviz++ harfbuzz-devel libSDL2-devel libSDL2_image-devel libepoxy-devel libfreetype-dev libogg-devel libopus-devel libpng-devel libtoml11-dev qt6-declarative-dev qt6-quickcontrols2 qt6-multimedia-dev opusfile-devel python3-Cython python3-Mako python3-lz4 python3-Pillow python3-Pygments python3-toml python3-devel` You will also need [nyan](https://github.com/SFTtech/nyan/blob/master/doc/building.md) and its dependencies. diff --git a/doc/build_instructions/ubuntu.md b/doc/build_instructions/ubuntu.md index bc151975e2..6565169827 100644 --- a/doc/build_instructions/ubuntu.md +++ b/doc/build_instructions/ubuntu.md @@ -3,7 +3,7 @@ Run the following commands: - `sudo apt-get update` - - `sudo apt-get install g++ cmake cython3 libeigen3-dev libepoxy-dev libfontconfig1-dev libfreetype-dev libharfbuzz-dev libogg-dev libopus-dev libopusfile-dev libpng-dev libsdl2-dev libsdl2-image-dev libtoml11-dev python3-dev python3-mako python3-numpy python3-lz4 python3-pil python3-pip python3-pygments python3-toml qml6-module-qtquick-controls qt6-declarative-dev` + - `sudo apt-get install g++ cmake cython3 libeigen3-dev libepoxy-dev libfontconfig1-dev libfreetype-dev libharfbuzz-dev libogg-dev libopus-dev libopusfile-dev libpng-dev libsdl2-dev libsdl2-image-dev libtoml11-dev python3-dev python3-mako python3-numpy python3-lz4 python3-pil python3-pip python3-pygments python3-toml qml6-module-qtquick-controls qt6-declarative-dev qt6-multimedia-dev qml6-module-qtquick3d-spatialaudio` You will also need [nyan](https://github.com/SFTtech/nyan/blob/master/doc/building.md) and its dependencies. diff --git a/doc/build_instructions/windows_msvc.md b/doc/build_instructions/windows_msvc.md index 4c742e0e2c..9ba1c51234 100644 --- a/doc/build_instructions/windows_msvc.md +++ b/doc/build_instructions/windows_msvc.md @@ -45,7 +45,7 @@ _Note:_ Also ensure that `python` and `python3` both point to the correct and th ### vcpkg packages Set up [vcpkg](https://github.com/Microsoft/vcpkg#quick-start). Open a command prompt at `` - vcpkg install dirent eigen3 fontconfig freetype harfbuzz libepoxy libogg libpng opus opusfile qtbase qtdeclarative sdl2 sdl2-image toml11 + vcpkg install dirent eigen3 fontconfig freetype harfbuzz libepoxy libogg libpng opus opusfile qtbase qtdeclarative qtmultimedia sdl2 sdl2-image toml11 _Note:_ The `qt6` port in vcpkg has been split into multiple packages, build times are acceptable now. If you want, you can still use [the prebuilt version](https://www.qt.io/download-open-source/) instead. diff --git a/doc/building.md b/doc/building.md index c5b8af6180..77a87008f0 100644 --- a/doc/building.md +++ b/doc/building.md @@ -56,7 +56,7 @@ Dependency list: S pycodestyle C pygments S pylint - CR qt6 >=6.2 (Core, Quick, QuickControls modules) + CR qt6 >=6.2 (Core, Quick, QuickControls, Multimedia modules) CR toml11 CR O vulkan diff --git a/libopenage/CMakeLists.txt b/libopenage/CMakeLists.txt index 3e12a5766c..7095576dc1 100644 --- a/libopenage/CMakeLists.txt +++ b/libopenage/CMakeLists.txt @@ -65,8 +65,8 @@ set(CMAKE_THREAD_PREFER_PTHREAD TRUE) find_package(Threads REQUIRED) set(QT_VERSION_REQ "6.2") -find_package(Qt6Core ${QT_VERSION_REQ} REQUIRED) -find_package(Qt6Quick ${QT_VERSION_REQ} REQUIRED) +find_package(Qt6 ${QT_VERSION_REQ} REQUIRED COMPONENTS Core Quick Multimedia) +# find_package(Qt6Multimedia ${QT_VERSION_REQ} REQUIRED) if(WANT_BACKTRACE) find_package(GCCBacktrace) @@ -300,6 +300,7 @@ target_link_libraries(libopenage ${EXECINFO_LIB} Qt6::Core Qt6::Quick + Qt6::Multimedia ) ################################################## diff --git a/packaging/docker/devenv/Dockerfile.ubuntu.2204 b/packaging/docker/devenv/Dockerfile.ubuntu.2204 index 40b1dd3abc..0dc50a1960 100644 --- a/packaging/docker/devenv/Dockerfile.ubuntu.2204 +++ b/packaging/docker/devenv/Dockerfile.ubuntu.2204 @@ -35,5 +35,7 @@ RUN apt-get update && DEBIAN_FRONTEND="noninteractive" apt-get install -y sudo \ python3-toml \ qml6-module-qtquick-controls \ qt6-declarative-dev \ + qt6-multimedia-dev \ + qml6-module-qtquick3d-spatialaudio \ && sudo apt-get clean \ && truncate -s 0 ~/.bash_history From 4faf7179bbc2c3eabd94940196e38096d28f373e Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 24 Sep 2023 15:38:49 +0200 Subject: [PATCH 47/95] renderer: Fix clang build not compiling. clang cannot correctly substitute for emplacement apparently. --- libopenage/renderer/opengl/shader_data.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libopenage/renderer/opengl/shader_data.cpp b/libopenage/renderer/opengl/shader_data.cpp index d4f7e040e2..1bfd912518 100644 --- a/libopenage/renderer/opengl/shader_data.cpp +++ b/libopenage/renderer/opengl/shader_data.cpp @@ -1,3 +1,10 @@ // Copyright 2023-2023 the openage authors. See copying.md for legal info. #include "shader_data.h" + + +namespace openage::renderer::opengl { + +// this file is intentionally empty + +} // namespace openage::renderer::opengl From c557ff00792d4dbe989e1fe0b8ba1e841d6ee462 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 24 Sep 2023 16:05:25 +0200 Subject: [PATCH 48/95] gui: Remove SDL2 from classes. --- libopenage/gui/gui.cpp | 4 +- libopenage/gui/gui.h | 2 +- .../gui/guisys/private/gui_ctx_setup.cpp | 4 +- libopenage/gui/guisys/private/gui_ctx_setup.h | 14 +- .../gui/guisys/private/gui_input_impl.cpp | 232 +++++++++--------- .../gui/guisys/private/gui_input_impl.h | 8 +- .../gui/guisys/private/gui_renderer_impl.cpp | 4 +- .../gui/guisys/private/gui_renderer_impl.h | 4 +- .../private/gui_rendering_setup_routines.cpp | 25 +- .../private/gui_rendering_setup_routines.h | 14 +- .../private/platforms/context_extraction.h | 10 +- .../platforms/context_extraction_win32.cpp | 66 ++--- .../platforms/context_extraction_x11.cpp | 2 +- libopenage/gui/guisys/public/gui_input.cpp | 7 +- libopenage/gui/guisys/public/gui_input.h | 4 +- libopenage/gui/guisys/public/gui_renderer.cpp | 5 +- libopenage/gui/guisys/public/gui_renderer.h | 4 +- .../renderer/resources/texture_data.cpp | 2 +- libopenage/renderer/resources/texture_data.h | 4 +- .../docker/devenv/Dockerfile.ubuntu.2204 | 2 - 20 files changed, 197 insertions(+), 220 deletions(-) diff --git a/libopenage/gui/gui.cpp b/libopenage/gui/gui.cpp index 590e11124c..eae5553572 100644 --- a/libopenage/gui/gui.cpp +++ b/libopenage/gui/gui.cpp @@ -9,13 +9,13 @@ namespace openage { namespace gui { -GUI::GUI(SDL_Window *window, +GUI::GUI(/* SDL_Window *window, */ const std::string &source, const std::string &rootdir, EngineQMLInfo *info) : application{}, render_updater{}, - renderer{window}, + renderer{/* window */}, game_logic_updater{}, engine{&renderer}, subtree{ diff --git a/libopenage/gui/gui.h b/libopenage/gui/gui.h index 600e4be52a..36273e5462 100644 --- a/libopenage/gui/gui.h +++ b/libopenage/gui/gui.h @@ -30,7 +30,7 @@ class EngineQMLInfo; */ class GUI { public: - explicit GUI(SDL_Window *window, + explicit GUI(/* SDL_Window *window, */ const std::string &source, const std::string &rootdir, EngineQMLInfo *info = nullptr); diff --git a/libopenage/gui/guisys/private/gui_ctx_setup.cpp b/libopenage/gui/guisys/private/gui_ctx_setup.cpp index aea120b89c..3cc34d35fe 100644 --- a/libopenage/gui/guisys/private/gui_ctx_setup.cpp +++ b/libopenage/gui/guisys/private/gui_ctx_setup.cpp @@ -19,7 +19,7 @@ QOpenGLContext *CtxExtractionMode::get_ctx() { return &this->ctx; } -GuiUniqueRenderingContext::GuiUniqueRenderingContext(SDL_Window *window) : +GuiUniqueRenderingContext::GuiUniqueRenderingContext(/* SDL_Window *window */) : CtxExtractionMode{} { QVariant handle; WId id; @@ -50,7 +50,7 @@ void GuiUniqueRenderingContext::pre_render() { void GuiUniqueRenderingContext::post_render() { } -GuiSeparateRenderingContext::GuiSeparateRenderingContext(SDL_Window *window) : +GuiSeparateRenderingContext::GuiSeparateRenderingContext(/* SDL_Window *window */) : CtxExtractionMode{} { QVariant handle; diff --git a/libopenage/gui/guisys/private/gui_ctx_setup.h b/libopenage/gui/guisys/private/gui_ctx_setup.h index bcc88e932a..28d5feb847 100644 --- a/libopenage/gui/guisys/private/gui_ctx_setup.h +++ b/libopenage/gui/guisys/private/gui_ctx_setup.h @@ -2,14 +2,12 @@ #pragma once -#include -#include #include +#include +#include -#include #include - -struct SDL_Window; +#include QT_FORWARD_DECLARE_CLASS(QOpenGLDebugLogger) @@ -31,7 +29,7 @@ class CtxExtractionMode { /** * @return context that can be used by Qt */ - QOpenGLContext* get_ctx(); + QOpenGLContext *get_ctx(); /** * Function that must be called before rendering the GUI. @@ -52,7 +50,7 @@ class CtxExtractionMode { */ class GuiUniqueRenderingContext : public CtxExtractionMode { public: - explicit GuiUniqueRenderingContext(SDL_Window *window); + explicit GuiUniqueRenderingContext(/* SDL_Window *window */); virtual void pre_render() override; virtual void post_render() override; @@ -63,7 +61,7 @@ class GuiUniqueRenderingContext : public CtxExtractionMode { */ class GuiSeparateRenderingContext : public CtxExtractionMode { public: - explicit GuiSeparateRenderingContext(SDL_Window *window); + explicit GuiSeparateRenderingContext(/* SDL_Window *window */); virtual ~GuiSeparateRenderingContext(); virtual void pre_render() override; diff --git a/libopenage/gui/guisys/private/gui_input_impl.cpp b/libopenage/gui/guisys/private/gui_input_impl.cpp index a92daf4134..c0d177ace9 100644 --- a/libopenage/gui/guisys/private/gui_input_impl.cpp +++ b/libopenage/gui/guisys/private/gui_input_impl.cpp @@ -6,8 +6,6 @@ #include #include -#include - #include "../public/gui_event_queue.h" #include "../public/gui_renderer.h" #include "gui_event_queue_impl.h" @@ -29,123 +27,123 @@ GuiInputImpl::GuiInputImpl(GuiRenderer *renderer, GuiEventQueue *game_logic_upda GuiInputImpl::~GuiInputImpl() = default; namespace { -static_assert(!(Qt::LeftButton & (static_cast(Qt::LeftButton) - 1)), "Qt non-one-bit mask."); -static_assert(!(Qt::RightButton & (static_cast(Qt::RightButton) - 1)), "Qt non-one-bit mask."); -static_assert(!(Qt::MiddleButton & (static_cast(Qt::MiddleButton) - 1)), "Qt non-one-bit mask."); -static_assert(!(Qt::XButton1 & (static_cast(Qt::XButton1) - 1)), "Qt non-one-bit mask."); -static_assert(!(Qt::XButton2 & (static_cast(Qt::XButton2) - 1)), "Qt non-one-bit mask."); - -static_assert(SDL_BUTTON_LMASK == Qt::LeftButton, "SDL/Qt mouse button mask incompatibility."); -static_assert(1 << (SDL_BUTTON_LEFT - 1) == Qt::LeftButton, "SDL/Qt mouse button mask incompatibility."); - -// Right and middle are swapped. -static_assert(SDL_BUTTON_RMASK == Qt::MiddleButton, "SDL/Qt mouse button mask incompatibility."); -static_assert(1 << (SDL_BUTTON_RIGHT - 1) == Qt::MiddleButton, "SDL/Qt mouse button mask incompatibility."); - -static_assert(SDL_BUTTON_MMASK == Qt::RightButton, "SDL/Qt mouse button mask incompatibility."); -static_assert(1 << (SDL_BUTTON_MIDDLE - 1) == Qt::RightButton, "SDL/Qt mouse button mask incompatibility."); - -static_assert(SDL_BUTTON_X1MASK == Qt::XButton1, "SDL/Qt mouse button mask incompatibility."); -static_assert(1 << (SDL_BUTTON_X1 - 1) == Qt::XButton1, "SDL/Qt mouse button mask incompatibility."); - -static_assert(SDL_BUTTON_X2MASK == Qt::XButton2, "SDL/Qt mouse button mask incompatibility."); -static_assert(1 << (SDL_BUTTON_X2 - 1) == Qt::XButton2, "SDL/Qt mouse button mask incompatibility."); - -static_assert(Qt::MiddleButton >> 1 == Qt::RightButton, "Qt::RightButton or Qt::MiddleButton has moved."); - -int sdl_mouse_mask_to_qt(Uint32 state) { - return (state & (Qt::LeftButton | Qt::XButton1 | Qt::XButton2)) | ((state & Qt::RightButton) << 1) | ((state & Qt::MiddleButton) >> 1); -} - -Qt::MouseButtons sdl_mouse_state_to_qt(Uint32 state) { - return static_cast(sdl_mouse_mask_to_qt(state)); -} - -Qt::MouseButton sdl_mouse_btn_to_qt(Uint8 button) { - return static_cast(sdl_mouse_mask_to_qt(1 << (button - 1))); -} - -int sdl_key_to_qt(SDL_Keycode sym) { - switch (sym) { - case SDLK_BACKSPACE: - return Qt::Key_Backspace; - case SDLK_DELETE: - return Qt::Key_Delete; - default: - return 0; - } -} +// static_assert(!(Qt::LeftButton & (static_cast(Qt::LeftButton) - 1)), "Qt non-one-bit mask."); +// static_assert(!(Qt::RightButton & (static_cast(Qt::RightButton) - 1)), "Qt non-one-bit mask."); +// static_assert(!(Qt::MiddleButton & (static_cast(Qt::MiddleButton) - 1)), "Qt non-one-bit mask."); +// static_assert(!(Qt::XButton1 & (static_cast(Qt::XButton1) - 1)), "Qt non-one-bit mask."); +// static_assert(!(Qt::XButton2 & (static_cast(Qt::XButton2) - 1)), "Qt non-one-bit mask."); + +// static_assert(SDL_BUTTON_LMASK == Qt::LeftButton, "SDL/Qt mouse button mask incompatibility."); +// static_assert(1 << (SDL_BUTTON_LEFT - 1) == Qt::LeftButton, "SDL/Qt mouse button mask incompatibility."); + +// // Right and middle are swapped. +// static_assert(SDL_BUTTON_RMASK == Qt::MiddleButton, "SDL/Qt mouse button mask incompatibility."); +// static_assert(1 << (SDL_BUTTON_RIGHT - 1) == Qt::MiddleButton, "SDL/Qt mouse button mask incompatibility."); + +// static_assert(SDL_BUTTON_MMASK == Qt::RightButton, "SDL/Qt mouse button mask incompatibility."); +// static_assert(1 << (SDL_BUTTON_MIDDLE - 1) == Qt::RightButton, "SDL/Qt mouse button mask incompatibility."); + +// static_assert(SDL_BUTTON_X1MASK == Qt::XButton1, "SDL/Qt mouse button mask incompatibility."); +// static_assert(1 << (SDL_BUTTON_X1 - 1) == Qt::XButton1, "SDL/Qt mouse button mask incompatibility."); + +// static_assert(SDL_BUTTON_X2MASK == Qt::XButton2, "SDL/Qt mouse button mask incompatibility."); +// static_assert(1 << (SDL_BUTTON_X2 - 1) == Qt::XButton2, "SDL/Qt mouse button mask incompatibility."); + +// static_assert(Qt::MiddleButton >> 1 == Qt::RightButton, "Qt::RightButton or Qt::MiddleButton has moved."); + +// int sdl_mouse_mask_to_qt(Uint32 state) { +// return (state & (Qt::LeftButton | Qt::XButton1 | Qt::XButton2)) | ((state & Qt::RightButton) << 1) | ((state & Qt::MiddleButton) >> 1); +// } + +// Qt::MouseButtons sdl_mouse_state_to_qt(Uint32 state) { +// return static_cast(sdl_mouse_mask_to_qt(state)); +// } + +// Qt::MouseButton sdl_mouse_btn_to_qt(Uint8 button) { +// return static_cast(sdl_mouse_mask_to_qt(1 << (button - 1))); +// } + +// int sdl_key_to_qt(SDL_Keycode sym) { +// switch (sym) { +// case SDLK_BACKSPACE: +// return Qt::Key_Backspace; +// case SDLK_DELETE: +// return Qt::Key_Delete; +// default: +// return 0; +// } +// } } // namespace -bool GuiInputImpl::process(SDL_Event *e) { - switch (e->type) { - case SDL_MOUSEMOTION: { - QMouseEvent ev{QEvent::MouseMove, QPoint{e->motion.x, e->motion.y}, Qt::MouseButton::NoButton, this->mouse_buttons_state = sdl_mouse_state_to_qt(e->motion.state), Qt::KeyboardModifier::NoModifier}; - ev.setAccepted(false); - - // Allow dragging stuff under the gui overlay. - return relay_input_event(&ev, e->motion.state & (SDL_BUTTON_LMASK | SDL_BUTTON_MMASK | SDL_BUTTON_RMASK)); - } - - case SDL_MOUSEBUTTONDOWN: { - auto button = sdl_mouse_btn_to_qt(e->button.button); - QMouseEvent ev{QEvent::MouseButtonPress, QPoint{e->button.x, e->button.y}, button, this->mouse_buttons_state |= button, Qt::KeyboardModifier::NoModifier}; - ev.setAccepted(false); - - bool accepted = relay_input_event(&ev); - - if (e->button.clicks == 2) { - QMouseEvent ev_dbl{QEvent::MouseButtonDblClick, QPoint{e->button.x, e->button.y}, button, this->mouse_buttons_state, Qt::KeyboardModifier::NoModifier}; - ev_dbl.setAccepted(false); - accepted = relay_input_event(&ev_dbl) || accepted; - } - - return accepted; - } - - case SDL_MOUSEBUTTONUP: { - auto button = sdl_mouse_btn_to_qt(e->button.button); - QMouseEvent ev{QEvent::MouseButtonRelease, QPoint{e->button.x, e->button.y}, button, this->mouse_buttons_state &= ~button, Qt::KeyboardModifier::NoModifier}; - ev.setAccepted(false); - - // Allow dragging stuff under the gui overlay: when no item is grabbed, it probably means that initial MousButtonPress was outside gui. - return relay_input_event(&ev, true); - } - - case SDL_MOUSEWHEEL: { - QPoint pos; - SDL_GetMouseState(&pos.rx(), &pos.ry()); - - QWheelEvent ev{ - pos, - pos, - QPoint{}, - QPoint{e->wheel.x, e->wheel.y}, - this->mouse_buttons_state, - Qt::KeyboardModifier::NoModifier, // Correct states? - Qt::ScrollPhase::NoScrollPhase, // ^ - false, - }; - ev.setAccepted(false); - - return relay_input_event(&ev); - } - - case SDL_KEYDOWN: { - QKeyEvent ev{QEvent::KeyPress, sdl_key_to_qt(e->key.keysym.sym), Qt::NoModifier, QChar(static_cast(e->key.keysym.sym))}; - ev.setAccepted(false); - return relay_input_event(&ev); - } - - case SDL_KEYUP: { - QKeyEvent ev{QEvent::KeyRelease, sdl_key_to_qt(e->key.keysym.sym), Qt::NoModifier, QChar(static_cast(e->key.keysym.sym))}; - ev.setAccepted(false); - return relay_input_event(&ev); - } - - default: - return false; - } +bool GuiInputImpl::process(/* SDL_Event *e */) { + // switch (e->type) { + // case SDL_MOUSEMOTION: { + // QMouseEvent ev{QEvent::MouseMove, QPoint{e->motion.x, e->motion.y}, Qt::MouseButton::NoButton, this->mouse_buttons_state = sdl_mouse_state_to_qt(e->motion.state), Qt::KeyboardModifier::NoModifier}; + // ev.setAccepted(false); + + // // Allow dragging stuff under the gui overlay. + // return relay_input_event(&ev, e->motion.state & (SDL_BUTTON_LMASK | SDL_BUTTON_MMASK | SDL_BUTTON_RMASK)); + // } + + // case SDL_MOUSEBUTTONDOWN: { + // auto button = sdl_mouse_btn_to_qt(e->button.button); + // QMouseEvent ev{QEvent::MouseButtonPress, QPoint{e->button.x, e->button.y}, button, this->mouse_buttons_state |= button, Qt::KeyboardModifier::NoModifier}; + // ev.setAccepted(false); + + // bool accepted = relay_input_event(&ev); + + // if (e->button.clicks == 2) { + // QMouseEvent ev_dbl{QEvent::MouseButtonDblClick, QPoint{e->button.x, e->button.y}, button, this->mouse_buttons_state, Qt::KeyboardModifier::NoModifier}; + // ev_dbl.setAccepted(false); + // accepted = relay_input_event(&ev_dbl) || accepted; + // } + + // return accepted; + // } + + // case SDL_MOUSEBUTTONUP: { + // auto button = sdl_mouse_btn_to_qt(e->button.button); + // QMouseEvent ev{QEvent::MouseButtonRelease, QPoint{e->button.x, e->button.y}, button, this->mouse_buttons_state &= ~button, Qt::KeyboardModifier::NoModifier}; + // ev.setAccepted(false); + + // // Allow dragging stuff under the gui overlay: when no item is grabbed, it probably means that initial MousButtonPress was outside gui. + // return relay_input_event(&ev, true); + // } + + // case SDL_MOUSEWHEEL: { + // QPoint pos; + // SDL_GetMouseState(&pos.rx(), &pos.ry()); + + // QWheelEvent ev{ + // pos, + // pos, + // QPoint{}, + // QPoint{e->wheel.x, e->wheel.y}, + // this->mouse_buttons_state, + // Qt::KeyboardModifier::NoModifier, // Correct states? + // Qt::ScrollPhase::NoScrollPhase, // ^ + // false, + // }; + // ev.setAccepted(false); + + // return relay_input_event(&ev); + // } + + // case SDL_KEYDOWN: { + // QKeyEvent ev{QEvent::KeyPress, sdl_key_to_qt(e->key.keysym.sym), Qt::NoModifier, QChar(static_cast(e->key.keysym.sym))}; + // ev.setAccepted(false); + // return relay_input_event(&ev); + // } + + // case SDL_KEYUP: { + // QKeyEvent ev{QEvent::KeyRelease, sdl_key_to_qt(e->key.keysym.sym), Qt::NoModifier, QChar(static_cast(e->key.keysym.sym))}; + // ev.setAccepted(false); + // return relay_input_event(&ev); + // } + + // default: + // return false; + // } } bool GuiInputImpl::relay_input_event(QEvent *ev, bool only_if_grabbed) { diff --git a/libopenage/gui/guisys/private/gui_input_impl.h b/libopenage/gui/guisys/private/gui_input_impl.h index c3665159a5..8272188c7f 100644 --- a/libopenage/gui/guisys/private/gui_input_impl.h +++ b/libopenage/gui/guisys/private/gui_input_impl.h @@ -6,8 +6,6 @@ #include -#include - namespace qtsdl { class GuiRenderer; @@ -24,13 +22,13 @@ class GuiInputImpl : public QObject { /** * Returns true if the event was accepted. */ - bool process(SDL_Event *e); + bool process(/* SDL_Event *e */); signals: - void input_event(std::atomic *processed, QEvent *ev, bool only_if_grabbed=false); + void input_event(std::atomic *processed, QEvent *ev, bool only_if_grabbed = false); private: - bool relay_input_event(QEvent *ev, bool only_if_grabbed=false); + bool relay_input_event(QEvent *ev, bool only_if_grabbed = false); Qt::MouseButtons mouse_buttons_state; GuiEventQueueImpl *game_logic_updater; diff --git a/libopenage/gui/guisys/private/gui_renderer_impl.cpp b/libopenage/gui/guisys/private/gui_renderer_impl.cpp index cf3bed6a63..a75974655f 100644 --- a/libopenage/gui/guisys/private/gui_renderer_impl.cpp +++ b/libopenage/gui/guisys/private/gui_renderer_impl.cpp @@ -74,9 +74,9 @@ void EventHandlingQuickWindow::on_resized(const QSize &size) { this->resize(size); } -GuiRendererImpl::GuiRendererImpl(SDL_Window *window) : +GuiRendererImpl::GuiRendererImpl(/* SDL_Window *window */) : QObject{}, - gui_rendering_setup_routines{window}, + gui_rendering_setup_routines{/* window */}, need_fbo_resize{true}, need_sync{}, need_render{}, diff --git a/libopenage/gui/guisys/private/gui_renderer_impl.h b/libopenage/gui/guisys/private/gui_renderer_impl.h index 31c1330eea..45186f08c3 100644 --- a/libopenage/gui/guisys/private/gui_renderer_impl.h +++ b/libopenage/gui/guisys/private/gui_renderer_impl.h @@ -25,8 +25,6 @@ #include "gui_rendering_setup_routines.h" -struct SDL_Window; - QT_FORWARD_DECLARE_CLASS(QOpenGLFramebufferObject) namespace qtsdl { @@ -56,7 +54,7 @@ class GuiRendererImpl : public QObject { Q_OBJECT public: - explicit GuiRendererImpl(SDL_Window *window); + explicit GuiRendererImpl(/* SDL_Window *window */); ~GuiRendererImpl(); static GuiRendererImpl *impl(GuiRenderer *renderer); diff --git a/libopenage/gui/guisys/private/gui_rendering_setup_routines.cpp b/libopenage/gui/guisys/private/gui_rendering_setup_routines.cpp index cfb6745438..3fdf554f98 100644 --- a/libopenage/gui/guisys/private/gui_rendering_setup_routines.cpp +++ b/libopenage/gui/guisys/private/gui_rendering_setup_routines.cpp @@ -10,16 +10,17 @@ namespace qtsdl { -GuiRenderingSetupRoutines::GuiRenderingSetupRoutines(SDL_Window *window) { +GuiRenderingSetupRoutines::GuiRenderingSetupRoutines(/* SDL_Window *window */) { try { - this->ctx_extraction_mode = std::make_unique(window); - } catch (const CtxExtractionException&) { - + this->ctx_extraction_mode = std::make_unique(/* window */); + } + catch (const CtxExtractionException &) { qInfo() << "Falling back to separate render context for GUI"; try { - this->ctx_extraction_mode = std::make_unique(window); - } catch (const CtxExtractionException&) { + this->ctx_extraction_mode = std::make_unique(/* window */); + } + catch (const CtxExtractionException &) { assert(false && "setting up context for GUI failed"); } } @@ -27,7 +28,7 @@ GuiRenderingSetupRoutines::GuiRenderingSetupRoutines(SDL_Window *window) { GuiRenderingSetupRoutines::~GuiRenderingSetupRoutines() = default; -QOpenGLContext* GuiRenderingSetupRoutines::get_ctx() { +QOpenGLContext *GuiRenderingSetupRoutines::get_ctx() { return this->ctx_extraction_mode->get_ctx(); } @@ -39,10 +40,8 @@ void GuiRenderingSetupRoutines::post_render() { this->ctx_extraction_mode->post_render(); } -GuiRenderingCtxActivator::GuiRenderingCtxActivator(GuiRenderingSetupRoutines &rendering_setup_routines) - : +GuiRenderingCtxActivator::GuiRenderingCtxActivator(GuiRenderingSetupRoutines &rendering_setup_routines) : rendering_setup_routines{&rendering_setup_routines} { - this->rendering_setup_routines->pre_render(); } @@ -51,14 +50,12 @@ GuiRenderingCtxActivator::~GuiRenderingCtxActivator() { this->rendering_setup_routines->post_render(); } -GuiRenderingCtxActivator::GuiRenderingCtxActivator(GuiRenderingCtxActivator&& o) - : +GuiRenderingCtxActivator::GuiRenderingCtxActivator(GuiRenderingCtxActivator &&o) : rendering_setup_routines{o.rendering_setup_routines} { - o.rendering_setup_routines = nullptr; } -GuiRenderingCtxActivator& GuiRenderingCtxActivator::operator=(GuiRenderingCtxActivator&& o) { +GuiRenderingCtxActivator &GuiRenderingCtxActivator::operator=(GuiRenderingCtxActivator &&o) { this->rendering_setup_routines = o.rendering_setup_routines; o.rendering_setup_routines = nullptr; return *this; diff --git a/libopenage/gui/guisys/private/gui_rendering_setup_routines.h b/libopenage/gui/guisys/private/gui_rendering_setup_routines.h index e392d70cb1..b813f85745 100644 --- a/libopenage/gui/guisys/private/gui_rendering_setup_routines.h +++ b/libopenage/gui/guisys/private/gui_rendering_setup_routines.h @@ -6,8 +6,6 @@ #include -struct SDL_Window; - QT_FORWARD_DECLARE_CLASS(QOpenGLContext) namespace qtsdl { @@ -22,10 +20,10 @@ class GuiRenderingCtxActivator; */ class GuiRenderingSetupRoutines { public: - explicit GuiRenderingSetupRoutines(SDL_Window *window); + explicit GuiRenderingSetupRoutines(/* SDL_Window *window */); ~GuiRenderingSetupRoutines(); - QOpenGLContext* get_ctx(); + QOpenGLContext *get_ctx(); private: friend class GuiRenderingCtxActivator; @@ -44,12 +42,12 @@ class GuiRenderingCtxActivator { explicit GuiRenderingCtxActivator(GuiRenderingSetupRoutines &rendering_setup_routines); ~GuiRenderingCtxActivator(); - GuiRenderingCtxActivator(GuiRenderingCtxActivator&& o); - GuiRenderingCtxActivator& operator=(GuiRenderingCtxActivator&& o); + GuiRenderingCtxActivator(GuiRenderingCtxActivator &&o); + GuiRenderingCtxActivator &operator=(GuiRenderingCtxActivator &&o); private: - GuiRenderingCtxActivator(const GuiRenderingCtxActivator&) = delete; - GuiRenderingCtxActivator& operator=(const GuiRenderingCtxActivator&) = delete; + GuiRenderingCtxActivator(const GuiRenderingCtxActivator &) = delete; + GuiRenderingCtxActivator &operator=(const GuiRenderingCtxActivator &) = delete; GuiRenderingSetupRoutines *rendering_setup_routines; }; diff --git a/libopenage/gui/guisys/private/platforms/context_extraction.h b/libopenage/gui/guisys/private/platforms/context_extraction.h index baf13818bb..1918a3d49c 100644 --- a/libopenage/gui/guisys/private/platforms/context_extraction.h +++ b/libopenage/gui/guisys/private/platforms/context_extraction.h @@ -2,24 +2,22 @@ #pragma once -#include #include +#include -#include #include - -struct SDL_Window; +#include namespace qtsdl { /** * @return current context (or null) and id of the window */ -std::tuple extract_native_context(SDL_Window *window); +// std::tuple extract_native_context(SDL_Window *window); /** * @return current context (or null) and function to get it back to the window */ -std::tuple> extract_native_context_and_switchback_func(SDL_Window *window); +// std::tuple> extract_native_context_and_switchback_func(SDL_Window *window); } // namespace qtsdl diff --git a/libopenage/gui/guisys/private/platforms/context_extraction_win32.cpp b/libopenage/gui/guisys/private/platforms/context_extraction_win32.cpp index 86aba09703..87f4dbf953 100644 --- a/libopenage/gui/guisys/private/platforms/context_extraction_win32.cpp +++ b/libopenage/gui/guisys/private/platforms/context_extraction_win32.cpp @@ -2,46 +2,46 @@ #include -#include #include "context_extraction.h" +#include #include -#include +// #include #include namespace qtsdl { -std::tuple extract_native_context(SDL_Window *window) { - assert(window); - - HGLRC current_context; - SDL_SysWMinfo wm_info; - SDL_VERSION(&wm_info.version); - if (SDL_GetWindowWMInfo(window, &wm_info)) { - current_context = wglGetCurrentContext(); - assert(current_context); - } - QWGLNativeContext nativeContext(current_context, wm_info.info.win.window); - return {QVariant::fromValue(nativeContext), reinterpret_cast(wm_info.info.win.window)}; -} - -std::tuple> extract_native_context_and_switchback_func(SDL_Window *window) { - assert(window); - - HGLRC current_context; - SDL_SysWMinfo wm_info; - SDL_VERSION(&wm_info.version); - if (SDL_GetWindowWMInfo(window, &wm_info)) { - current_context = wglGetCurrentContext(); - assert(current_context); - - return std::make_tuple(QVariant::fromValue(QWGLNativeContext(current_context, wm_info.info.win.window)), [wm_info, current_context] { - wglMakeCurrent(wm_info.info.win.hdc, current_context); - }); - } - - return std::tuple>{}; -} +// std::tuple extract_native_context(/* SDL_Window *window */) { +// assert(window); + +// HGLRC current_context; +// SDL_SysWMinfo wm_info; +// SDL_VERSION(&wm_info.version); +// if (SDL_GetWindowWMInfo(window, &wm_info)) { +// current_context = wglGetCurrentContext(); +// assert(current_context); +// } +// QWGLNativeContext nativeContext(current_context, wm_info.info.win.window); +// return {QVariant::fromValue(nativeContext), reinterpret_cast(wm_info.info.win.window)}; +// } + +// std::tuple> extract_native_context_and_switchback_func(/* SDL_Window *window */) { +// assert(window); + +// HGLRC current_context; +// SDL_SysWMinfo wm_info; +// SDL_VERSION(&wm_info.version); +// if (SDL_GetWindowWMInfo(window, &wm_info)) { +// current_context = wglGetCurrentContext(); +// assert(current_context); + +// return std::make_tuple(QVariant::fromValue(QWGLNativeContext(current_context, wm_info.info.win.window)), [wm_info, current_context] { +// wglMakeCurrent(wm_info.info.win.hdc, current_context); +// }); +// } + +// return std::tuple>{}; +// } } // namespace qtsdl diff --git a/libopenage/gui/guisys/private/platforms/context_extraction_x11.cpp b/libopenage/gui/guisys/private/platforms/context_extraction_x11.cpp index e320c9b6e4..333307c1f9 100644 --- a/libopenage/gui/guisys/private/platforms/context_extraction_x11.cpp +++ b/libopenage/gui/guisys/private/platforms/context_extraction_x11.cpp @@ -6,7 +6,7 @@ // #include #include -#include +// #include // DO NOT INCLUDE ANYTHING HERE, X11 HEADERS BREAK STUFF diff --git a/libopenage/gui/guisys/public/gui_input.cpp b/libopenage/gui/guisys/public/gui_input.cpp index c2e007d944..736c2df8cf 100644 --- a/libopenage/gui/guisys/public/gui_input.cpp +++ b/libopenage/gui/guisys/public/gui_input.cpp @@ -6,15 +6,14 @@ namespace qtsdl { -GuiInput:: GuiInput(GuiRenderer *renderer, GuiEventQueue *game_logic_updater) - : +GuiInput::GuiInput(GuiRenderer *renderer, GuiEventQueue *game_logic_updater) : impl{std::make_unique(renderer, game_logic_updater)} { } GuiInput::~GuiInput() = default; -bool GuiInput::process(SDL_Event *event) { - return this->impl->process(event); +bool GuiInput::process(/* SDL_Event *event */) { + return this->impl->process(/* event */); } } // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_input.h b/libopenage/gui/guisys/public/gui_input.h index 74e8adb118..557c53e67f 100644 --- a/libopenage/gui/guisys/public/gui_input.h +++ b/libopenage/gui/guisys/public/gui_input.h @@ -4,8 +4,6 @@ #include -#include - namespace qtsdl { class GuiRenderer; @@ -23,7 +21,7 @@ class GuiInput { /** * Returns true if the event was accepted. */ - bool process(SDL_Event *event); + bool process(/* SDL_Event *event */); private: friend class GuiInputImpl; diff --git a/libopenage/gui/guisys/public/gui_renderer.cpp b/libopenage/gui/guisys/public/gui_renderer.cpp index 7fb182f0b0..3a0fb99092 100644 --- a/libopenage/gui/guisys/public/gui_renderer.cpp +++ b/libopenage/gui/guisys/public/gui_renderer.cpp @@ -8,9 +8,8 @@ namespace qtsdl { -GuiRenderer::GuiRenderer(SDL_Window *window) - : - impl{std::make_unique(window)} { +GuiRenderer::GuiRenderer(/* SDL_Window *window */) : + impl{std::make_unique(/* window */)} { } GuiRenderer::~GuiRenderer() = default; diff --git a/libopenage/gui/guisys/public/gui_renderer.h b/libopenage/gui/guisys/public/gui_renderer.h index 7139dee405..93ff6dfd89 100644 --- a/libopenage/gui/guisys/public/gui_renderer.h +++ b/libopenage/gui/guisys/public/gui_renderer.h @@ -14,8 +14,6 @@ #include #endif -struct SDL_Window; - namespace qtsdl { class GuiRendererImpl; @@ -26,7 +24,7 @@ class GuiRendererImpl; class GuiRenderer { public: // TODO: allow FBO variant - explicit GuiRenderer(SDL_Window *window); + explicit GuiRenderer(/* SDL_Window *window */); ~GuiRenderer(); GLuint render(); diff --git a/libopenage/renderer/resources/texture_data.cpp b/libopenage/renderer/resources/texture_data.cpp index 0e765b61d7..fe11c19ce5 100644 --- a/libopenage/renderer/resources/texture_data.cpp +++ b/libopenage/renderer/resources/texture_data.cpp @@ -177,7 +177,7 @@ void Texture2dData::store(const util::Path &file) const { QImage image{this->data.data(), size.first, size.second, pix_fmt}; - // Call sdl_image for saving the screenshot to PNG + // Call QImage for saving the screenshot to PNG std::string path = file.resolve_native_path_w(); image.save(path.c_str()); } diff --git a/libopenage/renderer/resources/texture_data.h b/libopenage/renderer/resources/texture_data.h index 0107959d36..004a2bda1e 100644 --- a/libopenage/renderer/resources/texture_data.h +++ b/libopenage/renderer/resources/texture_data.h @@ -31,8 +31,8 @@ class Texture2dData { /// Create a texture from info. /// - /// Uses SDL Image internally. For supported image file types, - /// see the SDL_Image initialization in the engine. + /// Uses QImage internally. For supported image file types, + /// see the QImage initialization in the engine. Texture2dData(Texture2dInfo const &info); /// Construct by moving the information and raw texture data from somewhere else. diff --git a/packaging/docker/devenv/Dockerfile.ubuntu.2204 b/packaging/docker/devenv/Dockerfile.ubuntu.2204 index 0dc50a1960..4976e0c693 100644 --- a/packaging/docker/devenv/Dockerfile.ubuntu.2204 +++ b/packaging/docker/devenv/Dockerfile.ubuntu.2204 @@ -20,8 +20,6 @@ RUN apt-get update && DEBIAN_FRONTEND="noninteractive" apt-get install -y sudo \ libopus-dev \ libopusfile-dev \ libpng-dev \ - libsdl2-dev \ - libsdl2-image-dev \ libtoml11-dev \ make \ ninja-build \ From 1899b16185c5fd0da1cf87b9091285d783d77fb3 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 24 Sep 2023 16:05:48 +0200 Subject: [PATCH 49/95] buildsys: Remove SDL2 from dependencies. --- .github/workflows/macosx-ci.yml | 2 +- buildsystem/modules/FindSDL2Image.cmake | 29 ------------------- doc/build_instructions/arch_linux.md | 2 +- doc/build_instructions/debian.md | 2 +- doc/build_instructions/fedora.md | 2 +- doc/build_instructions/freebsd.md | 2 +- doc/build_instructions/macos.md | 2 +- doc/build_instructions/opensuse.md | 2 +- doc/build_instructions/ubuntu.md | 2 +- doc/build_instructions/windows_msvc.md | 2 +- doc/building.md | 6 ++-- doc/code_style/mom.cpp | 9 ++++-- doc/troubleshooting.md | 15 ---------- libopenage/CMakeLists.txt | 6 ---- libopenage/audio/audio_manager.cpp | 2 +- libopenage/gui/guisys/private/gui_ctx_setup.h | 2 +- .../gui/guisys/private/gui_input_impl.h | 2 +- .../private/gui_rendering_setup_routines.cpp | 2 +- .../private/gui_rendering_setup_routines.h | 2 +- .../private/platforms/context_extraction.h | 2 +- .../platforms/context_extraction_win32.cpp | 2 +- libopenage/gui/guisys/public/gui_input.cpp | 2 +- libopenage/gui/guisys/public/gui_input.h | 2 +- libopenage/gui/guisys/public/gui_renderer.cpp | 2 +- libopenage/gui/guisys/public/gui_renderer.h | 2 +- libopenage/versions/versions.cpp | 2 +- shell.nix | 5 ++-- 27 files changed, 31 insertions(+), 81 deletions(-) delete mode 100644 buildsystem/modules/FindSDL2Image.cmake diff --git a/.github/workflows/macosx-ci.yml b/.github/workflows/macosx-ci.yml index d7b86776db..e38c9e3e6e 100644 --- a/.github/workflows/macosx-ci.yml +++ b/.github/workflows/macosx-ci.yml @@ -59,7 +59,7 @@ jobs: - name: Install environment helpers with homebrew run: brew install ccache - name: Install dependencies with homebrew - run: brew install libepoxy freetype fontconfig harfbuzz sdl2 sdl2_image opus opusfile qt6 libogg libpng toml11 eigen + run: brew install libepoxy freetype fontconfig harfbuzz opus opusfile qt6 libogg libpng toml11 eigen - name: Install nyan dependencies with homebrew run: brew install flex make - name: Install python3 packages diff --git a/buildsystem/modules/FindSDL2Image.cmake b/buildsystem/modules/FindSDL2Image.cmake deleted file mode 100644 index 74b36be8ba..0000000000 --- a/buildsystem/modules/FindSDL2Image.cmake +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2014-2017 the openage authors. See copying.md for legal info. - -find_package(PackageHandleStandardArgs) - -if(APPLE) - find_library(SDL2IMAGE_LIBRARIES SDL2_image DOC "SDL2 library framework for MacOS X") - find_path(SDL2IMAGE_INCLUDE_DIRS SDL_image.h - HINTS - $ENV{SDL2DIR} - PATH_SUFFIXES include/SDL2 include - PATHS - ~/Library/Frameworks - /Library/Frameworks - /usr/local/include/SDL2 - /usr/include/SDL2 - /sw # Fink - /opt/local # DarwinPorts - /opt/csw # Blastwave - /opt - DOC "Include directory for SDL2_image under MacOS X" - ) -else() - find_library(SDL2IMAGE_LIBRARIES SDL2_image DOC "SDL2 library") - find_path(SDL2IMAGE_INCLUDE_DIRS SDL2/SDL_image.h DOC "Include directory for SDL2_image") -endif() - -# handle the QUIETLY and REQUIRED arguments and set SDL2Image_FOUND to TRUE if -# all listed variables are TRUE -find_package_handle_standard_args(SDL2Image DEFAULT_MSG SDL2IMAGE_LIBRARIES) diff --git a/doc/build_instructions/arch_linux.md b/doc/build_instructions/arch_linux.md index cd6af02cd7..9c42ff64fd 100644 --- a/doc/build_instructions/arch_linux.md +++ b/doc/build_instructions/arch_linux.md @@ -4,7 +4,7 @@ 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 qt6-multimedia` +`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 opusfile opus python-pylint python-toml qt6-declarative qt6-multimedia` Additionally, you have to install [`toml11`](https://aur.archlinux.org/packages/toml11) from the AUR. If you have `yay`, you can run this command: diff --git a/doc/build_instructions/debian.md b/doc/build_instructions/debian.md index d9be204189..de74a192fc 100644 --- a/doc/build_instructions/debian.md +++ b/doc/build_instructions/debian.md @@ -1,6 +1,6 @@ # Prerequisite steps for Debian users - `sudo apt-get update` - - `sudo apt-get install cmake cython3 libeigen3-dev libepoxy-dev libfontconfig1-dev libfreetype-dev libharfbuzz-dev libogg-dev libopus-dev libopusfile-dev libpng-dev libsdl2-dev libsdl2-image-dev libtoml11-dev python3-dev python3-mako python3-numpy python3-lz4 python3-pil python3-pip python3-pygments python3-toml qml6-module-qtquick-controls qt6-declarative-dev qt6-multimedia-dev qml6-module-qtquick3d-spatialaudio` + - `sudo apt-get install cmake cython3 libeigen3-dev libepoxy-dev libfontconfig1-dev libfreetype-dev libharfbuzz-dev libogg-dev libopus-dev libopusfile-dev libpng-dev libtoml11-dev python3-dev python3-mako python3-numpy python3-lz4 python3-pil python3-pip python3-pygments python3-toml qml6-module-qtquick-controls qt6-declarative-dev qt6-multimedia-dev qml6-module-qtquick3d-spatialaudio` You will also need [nyan](https://github.com/SFTtech/nyan/blob/master/doc/building.md) and its dependencies. diff --git a/doc/build_instructions/fedora.md b/doc/build_instructions/fedora.md index c911ec8eb9..e18e5f74c2 100644 --- a/doc/build_instructions/fedora.md +++ b/doc/build_instructions/fedora.md @@ -2,6 +2,6 @@ Run the following command: -`sudo dnf install clang cmake eigen3-devel fontconfig-devel gcc-c harfbuzz-devel libepoxy-devel libogg-devel libopusenc-devel libpng-devel opusfile-devel python3-Cython python3-devel python3-mako python3-numpy python3-lz4 python3-pillow python3-pygments python3-toml SDL2-devel SDL2_image-devel++ toml11-devel qt6-qtdeclarative-devel qt6-qtmultimedia-devel` +`sudo dnf install clang cmake eigen3-devel fontconfig-devel gcc-c harfbuzz-devel libepoxy-devel libogg-devel libopusenc-devel libpng-devel opusfile-devel python3-Cython python3-devel python3-mako python3-numpy python3-lz4 python3-pillow python3-pygments python3-toml toml11-devel qt6-qtdeclarative-devel qt6-qtmultimedia-devel` You will also need [nyan](https://github.com/SFTtech/nyan/blob/master/doc/building.md) and its dependencies. diff --git a/doc/build_instructions/freebsd.md b/doc/build_instructions/freebsd.md index b52d7e6177..fb53e1e9e2 100644 --- a/doc/build_instructions/freebsd.md +++ b/doc/build_instructions/freebsd.md @@ -2,7 +2,7 @@ This command should provide required packages for FreeBSD installation: -`sudo pkg install cmake cython eigen3 harfbuzz opus-tools opusfile png py-mako py-numpy py-lz4 py-pillow py-pygments py-toml pylint python qt6 sdl2 sdl2_image toml11` +`sudo pkg install cmake cython eigen3 harfbuzz opus-tools opusfile png py-mako py-numpy py-lz4 py-pillow py-pygments py-toml pylint python qt6 toml11` You will also need [nyan](https://github.com/SFTtech/nyan/blob/master/doc/building.md) and its dependencies. diff --git a/doc/build_instructions/macos.md b/doc/build_instructions/macos.md index ffe6e64f67..ba139c3b12 100644 --- a/doc/build_instructions/macos.md +++ b/doc/build_instructions/macos.md @@ -8,7 +8,7 @@ brew update-reset && brew update brew tap homebrew/cask-fonts brew install font-dejavu -brew install cmake python3 libepoxy freetype fontconfig harfbuzz sdl2 sdl2_image opus opusfile qt6 libogg libpng toml11 eigen +brew install cmake python3 libepoxy freetype fontconfig harfbuzz opus opusfile qt6 libogg libpng toml11 eigen brew install llvm pip3 install cython numpy mako lz4 pillow pygments toml diff --git a/doc/build_instructions/opensuse.md b/doc/build_instructions/opensuse.md index 15166d5032..8b967b1779 100644 --- a/doc/build_instructions/opensuse.md +++ b/doc/build_instructions/opensuse.md @@ -1,5 +1,5 @@ # Prerequisite steps for openSUSE users -- `zypper install --no-recommends cmake doxygen eigen3-devel fontconfig-devel gcc-c graphviz++ harfbuzz-devel libSDL2-devel libSDL2_image-devel libepoxy-devel libfreetype-dev libogg-devel libopus-devel libpng-devel libtoml11-dev qt6-declarative-dev qt6-quickcontrols2 qt6-multimedia-dev opusfile-devel python3-Cython python3-Mako python3-lz4 python3-Pillow python3-Pygments python3-toml python3-devel` +- `zypper install --no-recommends cmake doxygen eigen3-devel fontconfig-devel gcc-c graphviz++ harfbuzz-devel libepoxy-devel libfreetype-dev libogg-devel libopus-devel libpng-devel libtoml11-dev qt6-declarative-dev qt6-quickcontrols2 qt6-multimedia-dev opusfile-devel python3-Cython python3-Mako python3-lz4 python3-Pillow python3-Pygments python3-toml python3-devel` You will also need [nyan](https://github.com/SFTtech/nyan/blob/master/doc/building.md) and its dependencies. diff --git a/doc/build_instructions/ubuntu.md b/doc/build_instructions/ubuntu.md index 6565169827..08fc635abb 100644 --- a/doc/build_instructions/ubuntu.md +++ b/doc/build_instructions/ubuntu.md @@ -3,7 +3,7 @@ Run the following commands: - `sudo apt-get update` - - `sudo apt-get install g++ cmake cython3 libeigen3-dev libepoxy-dev libfontconfig1-dev libfreetype-dev libharfbuzz-dev libogg-dev libopus-dev libopusfile-dev libpng-dev libsdl2-dev libsdl2-image-dev libtoml11-dev python3-dev python3-mako python3-numpy python3-lz4 python3-pil python3-pip python3-pygments python3-toml qml6-module-qtquick-controls qt6-declarative-dev qt6-multimedia-dev qml6-module-qtquick3d-spatialaudio` + - `sudo apt-get install g++ cmake cython3 libeigen3-dev libepoxy-dev libfontconfig1-dev libfreetype-dev libharfbuzz-dev libogg-dev libopus-dev libopusfile-dev libpng-dev libtoml11-dev python3-dev python3-mako python3-numpy python3-lz4 python3-pil python3-pip python3-pygments python3-toml qml6-module-qtquick-controls qt6-declarative-dev qt6-multimedia-dev qml6-module-qtquick3d-spatialaudio` You will also need [nyan](https://github.com/SFTtech/nyan/blob/master/doc/building.md) and its dependencies. diff --git a/doc/build_instructions/windows_msvc.md b/doc/build_instructions/windows_msvc.md index 9ba1c51234..5be6d9167c 100644 --- a/doc/build_instructions/windows_msvc.md +++ b/doc/build_instructions/windows_msvc.md @@ -45,7 +45,7 @@ _Note:_ Also ensure that `python` and `python3` both point to the correct and th ### vcpkg packages Set up [vcpkg](https://github.com/Microsoft/vcpkg#quick-start). Open a command prompt at `` - vcpkg install dirent eigen3 fontconfig freetype harfbuzz libepoxy libogg libpng opus opusfile qtbase qtdeclarative qtmultimedia sdl2 sdl2-image toml11 + vcpkg install dirent eigen3 fontconfig freetype harfbuzz libepoxy libogg libpng opus opusfile qtbase qtdeclarative qtmultimedia toml11 _Note:_ The `qt6` port in vcpkg has been split into multiple packages, build times are acceptable now. If you want, you can still use [the prebuilt version](https://www.qt.io/download-open-source/) instead. diff --git a/doc/building.md b/doc/building.md index 77a87008f0..e7e0339d64 100644 --- a/doc/building.md +++ b/doc/building.md @@ -48,8 +48,6 @@ Dependency list: CR nyan (https://github.com/SFTtech/nyan) CR O ncurses C mako - CR sdl2 - CR sdl2_image CR opusfile CRA opus CRA ogg @@ -167,10 +165,10 @@ The reference package is [created for Gentoo](https://github.com/SFTtech/gentoo- - I wanna see compiler invocations - `make VERBOSE=1` -- My `SDL2_Image`/`Python`/whatever is installed somewhere, but `cmake` can't find it! +- My `Qt`/`Python`/whatever is installed somewhere, but `cmake` can't find it! - Run `ccmake` or `cmake-gui` in the build directory to see and change config variables. - You can manually tell `cmake` where to look. Try something along the lines of - - `./configure -- -DSDL2IMAGE_INCLUDE_DIRS=/whereever/sdl2_image/include/` + - `./configure -- -DPYTHON_INCLUDE_DIRS=/whereever/python/include/` - `-DPython3_EXECUTABLE=/your/py3/directory/` - I get compiler errors about missing header files diff --git a/doc/code_style/mom.cpp b/doc/code_style/mom.cpp index 6655d0956d..ad2bb5d07d 100644 --- a/doc/code_style/mom.cpp +++ b/doc/code_style/mom.cpp @@ -17,13 +17,16 @@ // The associated header file comes first! #include "mom.h" -// System includes follow, sorted alphabetically +// C++ std library includes follow, sorted alphabetically #include #include #include -#include -// Local includes next, sorted alphabetically +// External libraries are next, sorted alphabetically +#include +#include + +// Local includes come last, sorted alphabetically #include "../valve.h" #include "half_life.h" #include "log/log.h" diff --git a/doc/troubleshooting.md b/doc/troubleshooting.md index 5ed9cc440a..a955eca018 100644 --- a/doc/troubleshooting.md +++ b/doc/troubleshooting.md @@ -26,18 +26,3 @@ A workaround would be to make a backup of your AGE2 directory and let the conver backup at subfolder `AGE2/resources` delete all files ***except*** folders. Another workaround would be to backup your AGE2 folder and redownload it to have a clean install. After conversion you can replace it with the backup. - -## Installation - -### Cannot specify compile definitions for target "SDL2::SDL2" which is not built by this project - -This error is specific to a few operating systems. The main cause is that your SDL2 version is too old and does not -include the necessary CMake files defining the target. There is an indepth discussion about this -[here](https://discourse.libsdl.org/t/how-is-sdl2-supposed-to-be-used-with-cmake/31275/16). -As a solution, you should update your SDL packages to SDL >=2.0.12 or **compile the latest SDL2 and SDL2-image from -source**. The latest version includes the necessary CMake files to expose the `SDL2::SDL2` target. - -## Building on Debian 12 -On Debian you might get an error saying that it couldn't find SDL2 library. This happens because the CMAKE prefix and SDL2 path are not set correctly. -The solution is to append at the end of the `./configure` command the cmake variables for both the prefix and SDL2 path, like so: -`./configure -- -DCMAKE_PREFIX_PATH=/usr -DSDL2_DIR=/usr/include/SDL2` (you can use `find` to look for the correct paths) diff --git a/libopenage/CMakeLists.txt b/libopenage/CMakeLists.txt index 7095576dc1..46fc15da13 100644 --- a/libopenage/CMakeLists.txt +++ b/libopenage/CMakeLists.txt @@ -53,9 +53,6 @@ find_library(FONTCONFIG_LIB fontconfig) find_package(toml11 REQUIRED) find_package(Freetype REQUIRED) find_package(PNG REQUIRED) -find_package(SDL2 CONFIG REQUIRED) -target_compile_definitions(SDL2::SDL2 INTERFACE SDL_MAIN_HANDLED) -find_package(SDL2Image REQUIRED) find_package(Opusfile REQUIRED) find_package(Epoxy REQUIRED) find_package(HarfBuzz 1.0.0 REQUIRED) @@ -268,7 +265,6 @@ target_include_directories(libopenage ${EPOXY_INCLUDE_DIRS} ${OPUS_INCLUDE_DIRS} ${PNG_INCLUDE_DIRS} - ${SDL2IMAGE_INCLUDE_DIRS} ${HarfBuzz_INCLUDE_DIRS} ${QTPLATFORM_INCLUDE_DIRS} ) @@ -292,8 +288,6 @@ target_link_libraries(libopenage ${FREETYPE_LIBRARIES} ${EPOXY_LIBRARIES} ${MATH_LIB} - ${SDL2IMAGE_LIBRARIES} - SDL2::SDL2 ${UTIL_LIB} ${HarfBuzz_LIBRARIES} ${RT_LIB} diff --git a/libopenage/audio/audio_manager.cpp b/libopenage/audio/audio_manager.cpp index ce19e77073..b46fbcf7e2 100644 --- a/libopenage/audio/audio_manager.cpp +++ b/libopenage/audio/audio_manager.cpp @@ -1,4 +1,4 @@ -// Copyright 2014-2019 the openage authors. See copying.md for legal info. +// Copyright 2014-2023 the openage authors. See copying.md for legal info. #include "audio_manager.h" diff --git a/libopenage/gui/guisys/private/gui_ctx_setup.h b/libopenage/gui/guisys/private/gui_ctx_setup.h index 28d5feb847..8b5d1952d9 100644 --- a/libopenage/gui/guisys/private/gui_ctx_setup.h +++ b/libopenage/gui/guisys/private/gui_ctx_setup.h @@ -1,4 +1,4 @@ -// Copyright 2017-2017 the openage authors. See copying.md for legal info. +// Copyright 2017-2023 the openage authors. See copying.md for legal info. #pragma once diff --git a/libopenage/gui/guisys/private/gui_input_impl.h b/libopenage/gui/guisys/private/gui_input_impl.h index 8272188c7f..4863b239e8 100644 --- a/libopenage/gui/guisys/private/gui_input_impl.h +++ b/libopenage/gui/guisys/private/gui_input_impl.h @@ -1,4 +1,4 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once diff --git a/libopenage/gui/guisys/private/gui_rendering_setup_routines.cpp b/libopenage/gui/guisys/private/gui_rendering_setup_routines.cpp index 3fdf554f98..059cc3f7b2 100644 --- a/libopenage/gui/guisys/private/gui_rendering_setup_routines.cpp +++ b/libopenage/gui/guisys/private/gui_rendering_setup_routines.cpp @@ -1,4 +1,4 @@ -// Copyright 2017-2019 the openage authors. See copying.md for legal info. +// Copyright 2017-2023 the openage authors. See copying.md for legal info. #include "gui_rendering_setup_routines.h" diff --git a/libopenage/gui/guisys/private/gui_rendering_setup_routines.h b/libopenage/gui/guisys/private/gui_rendering_setup_routines.h index b813f85745..a262228c25 100644 --- a/libopenage/gui/guisys/private/gui_rendering_setup_routines.h +++ b/libopenage/gui/guisys/private/gui_rendering_setup_routines.h @@ -1,4 +1,4 @@ -// Copyright 2017-2017 the openage authors. See copying.md for legal info. +// Copyright 2017-2023 the openage authors. See copying.md for legal info. #pragma once diff --git a/libopenage/gui/guisys/private/platforms/context_extraction.h b/libopenage/gui/guisys/private/platforms/context_extraction.h index 1918a3d49c..7bbf515d8b 100644 --- a/libopenage/gui/guisys/private/platforms/context_extraction.h +++ b/libopenage/gui/guisys/private/platforms/context_extraction.h @@ -1,4 +1,4 @@ -// Copyright 2015-2017 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once diff --git a/libopenage/gui/guisys/private/platforms/context_extraction_win32.cpp b/libopenage/gui/guisys/private/platforms/context_extraction_win32.cpp index 87f4dbf953..1c413ff926 100644 --- a/libopenage/gui/guisys/private/platforms/context_extraction_win32.cpp +++ b/libopenage/gui/guisys/private/platforms/context_extraction_win32.cpp @@ -1,4 +1,4 @@ -// Copyright 2015-2017 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include diff --git a/libopenage/gui/guisys/public/gui_input.cpp b/libopenage/gui/guisys/public/gui_input.cpp index 736c2df8cf..861e6a5f6e 100644 --- a/libopenage/gui/guisys/public/gui_input.cpp +++ b/libopenage/gui/guisys/public/gui_input.cpp @@ -1,4 +1,4 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include "../public/gui_input.h" diff --git a/libopenage/gui/guisys/public/gui_input.h b/libopenage/gui/guisys/public/gui_input.h index 557c53e67f..1a46b227be 100644 --- a/libopenage/gui/guisys/public/gui_input.h +++ b/libopenage/gui/guisys/public/gui_input.h @@ -1,4 +1,4 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once diff --git a/libopenage/gui/guisys/public/gui_renderer.cpp b/libopenage/gui/guisys/public/gui_renderer.cpp index 3a0fb99092..a11063e7e5 100644 --- a/libopenage/gui/guisys/public/gui_renderer.cpp +++ b/libopenage/gui/guisys/public/gui_renderer.cpp @@ -1,4 +1,4 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include "../public/gui_renderer.h" diff --git a/libopenage/gui/guisys/public/gui_renderer.h b/libopenage/gui/guisys/public/gui_renderer.h index 93ff6dfd89..bc8e93dd99 100644 --- a/libopenage/gui/guisys/public/gui_renderer.h +++ b/libopenage/gui/guisys/public/gui_renderer.h @@ -1,4 +1,4 @@ -// Copyright 2015-2017 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once diff --git a/libopenage/versions/versions.cpp b/libopenage/versions/versions.cpp index 8e2e63d215..d2e1fd251a 100644 --- a/libopenage/versions/versions.cpp +++ b/libopenage/versions/versions.cpp @@ -1,4 +1,4 @@ -// Copyright 2020-2020 the openage authors. See copying.md for legal info. +// Copyright 2020-2023 the openage authors. See copying.md for legal info. #include "versions.h" diff --git a/shell.nix b/shell.nix index 5b466174ef..5d80e0669f 100644 --- a/shell.nix +++ b/shell.nix @@ -9,7 +9,7 @@ pkgs.mkShell { #pkgs.gdb pkgs.cmake pkgs.gnumake - pkgs.qt5.full + pkgs.qt6.full #pkgs.qtcreator pkgs.eigen @@ -27,13 +27,12 @@ pkgs.mkShell { pkgs.ftgl pkgs.fontconfig pkgs.harfbuzz - pkgs.SDL2 - pkgs.SDL2_image pkgs.opusfile pkgs.libopus pkgs.python39Packages.pylint pkgs.python39Packages.toml pkgs.libsForQt6.qt6.qtdeclarative pkgs.libsForQt6.qt6.qtquickcontrols + pkgs.libsForQt6.qt6.qtmultimedia ]; } From 475143eb5f6926b5605a0c6bffa4a4abb6841ff8 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 24 Sep 2023 18:37:44 +0200 Subject: [PATCH 50/95] ci: Use Github Actions checkout v4. --- .github/workflows/ubuntu-22.04.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ubuntu-22.04.yml b/.github/workflows/ubuntu-22.04.yml index 3343df5506..b6eaa70230 100644 --- a/.github/workflows/ubuntu-22.04.yml +++ b/.github/workflows/ubuntu-22.04.yml @@ -32,7 +32,7 @@ jobs: run: mkdir -p /tmp/image shell: bash - name: Download devenv image - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: name: devenv-image-compressed.tar.gz path: '/tmp/image' From c7f3d70759cde94e0ebdf158fdfe6df94007a9fe Mon Sep 17 00:00:00 2001 From: heinezen Date: Mon, 25 Sep 2023 22:10:17 +0200 Subject: [PATCH 51/95] ci: Update cached Windows dependencies. --- .github/workflows/windows-server-2019.yml | 2 +- .github/workflows/windows-server-2022.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows-server-2019.yml b/.github/workflows/windows-server-2019.yml index 93a9ecf867..7a2262c00f 100644 --- a/.github/workflows/windows-server-2019.yml +++ b/.github/workflows/windows-server-2019.yml @@ -24,7 +24,7 @@ jobs: mkdir download cd download $zipfile = "openage-dep-x64-windows.zip" - Invoke-WebRequest https://github.com/SFTtech/openage-dependencies/releases/download/v0.5.0/openage-dep-x64-windows.zip -OutFile $zipfile + Invoke-WebRequest https://github.com/SFTtech/openage-dependencies/releases/download/v0.5.1/openage-dep-x64-windows.zip -OutFile $zipfile Expand-Archive -Path $zipfile -DestinationPath . -Force Remove-Item $zipfile (Get-ChildItem . -Recurse -File).FullName diff --git a/.github/workflows/windows-server-2022.yml b/.github/workflows/windows-server-2022.yml index c4deba0d46..f0172b103e 100644 --- a/.github/workflows/windows-server-2022.yml +++ b/.github/workflows/windows-server-2022.yml @@ -24,7 +24,7 @@ jobs: mkdir download cd download $zipfile = "openage-dep-x64-windows.zip" - Invoke-WebRequest https://github.com/SFTtech/openage-dependencies/releases/download/v0.5.0/openage-dep-x64-windows.zip -OutFile $zipfile + Invoke-WebRequest https://github.com/SFTtech/openage-dependencies/releases/download/v0.5.1/openage-dep-x64-windows.zip -OutFile $zipfile Expand-Archive -Path $zipfile -DestinationPath . -Force Remove-Item $zipfile (Get-ChildItem . -Recurse -File).FullName From dbe3c30535a139df4ed3f0fd65762484ff833af5 Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 27 Sep 2023 17:21:08 +0200 Subject: [PATCH 52/95] gui: Remove BlendPreserver object. --- libopenage/gui/gui.cpp | 70 +++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/libopenage/gui/gui.cpp b/libopenage/gui/gui.cpp index eae5553572..9f2df8a983 100644 --- a/libopenage/gui/gui.cpp +++ b/libopenage/gui/gui.cpp @@ -47,41 +47,41 @@ void GUI::process_events() { // return not this->input.process(event); // } -namespace { -/** - * Restores blending function. - */ -class BlendPreserver { -public: - BlendPreserver() : - was_on{}, - src{}, - dst{} { - glGetBooleanv(GL_BLEND, &this->was_on); - - if (this->was_on != GL_FALSE) { - glGetIntegerv(GL_BLEND_SRC_ALPHA, &this->src); - glGetIntegerv(GL_BLEND_DST_ALPHA, &this->dst); - } - } - - ~BlendPreserver() { - if (this->was_on != GL_FALSE) { - glEnable(GL_BLEND); - glBlendFunc(this->src, this->dst); - } - else { - glDisable(GL_BLEND); - } - } - -private: - GLboolean was_on; - GLint src; - GLint dst; -}; - -} // namespace +// namespace { +// /** +// * Restores blending function. +// */ +// class BlendPreserver { +// public: +// BlendPreserver() : +// was_on{}, +// src{}, +// dst{} { +// glGetBooleanv(GL_BLEND, &this->was_on); + +// if (this->was_on != GL_FALSE) { +// glGetIntegerv(GL_BLEND_SRC_ALPHA, &this->src); +// glGetIntegerv(GL_BLEND_DST_ALPHA, &this->dst); +// } +// } + +// ~BlendPreserver() { +// if (this->was_on != GL_FALSE) { +// glEnable(GL_BLEND); +// glBlendFunc(this->src, this->dst); +// } +// else { +// glDisable(GL_BLEND); +// } +// } + +// private: +// GLboolean was_on; +// GLint src; +// GLint dst; +// }; + +// } // namespace // bool GUI::on_drawhud() { // this->render_updater.process_callbacks(); From 9af686fd5b37cc237c43930043a4f0fd67a1d3f0 Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 27 Sep 2023 19:00:40 +0200 Subject: [PATCH 53/95] gui: Fix missing return value. --- libopenage/gui/guisys/private/gui_input_impl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libopenage/gui/guisys/private/gui_input_impl.cpp b/libopenage/gui/guisys/private/gui_input_impl.cpp index c0d177ace9..8675785596 100644 --- a/libopenage/gui/guisys/private/gui_input_impl.cpp +++ b/libopenage/gui/guisys/private/gui_input_impl.cpp @@ -144,6 +144,7 @@ bool GuiInputImpl::process(/* SDL_Event *e */) { // default: // return false; // } + return false; } bool GuiInputImpl::relay_input_event(QEvent *ev, bool only_if_grabbed) { From 351a6d70ec444d40263207b5f375df79735d23d1 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 22 Oct 2023 19:11:21 +0200 Subject: [PATCH 54/95] Add clang-tidy recommendations. --- libopenage/gamestate/player.h | 4 +- libopenage/gui/guisys/link/gui_item_link.h | 55 +++++++++++---------- libopenage/renderer/vulkan/render_target.h | 8 ++- libopenage/renderer/vulkan/shader_program.h | 40 +++++++++------ libopenage/rng/global_rng.h | 6 ++- 5 files changed, 66 insertions(+), 47 deletions(-) diff --git a/libopenage/gamestate/player.h b/libopenage/gamestate/player.h index db6c53b128..d9bdbe3bd2 100644 --- a/libopenage/gamestate/player.h +++ b/libopenage/gamestate/player.h @@ -29,10 +29,10 @@ class Player { // players can't be copied to prevent duplicate IDs Player(const Player &) = delete; - Player(Player &&) = default; + Player(Player &&) = delete; Player &operator=(const Player &) = delete; - Player &operator=(Player &&) = default; + Player &operator=(Player &&) = delete; ~Player() = default; diff --git a/libopenage/gui/guisys/link/gui_item_link.h b/libopenage/gui/guisys/link/gui_item_link.h index 43191ea2ec..60cc7e5572 100644 --- a/libopenage/gui/guisys/link/gui_item_link.h +++ b/libopenage/gui/guisys/link/gui_item_link.h @@ -1,8 +1,9 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once #include +#include #include "qtsdl_checked_static_cast.h" @@ -22,30 +23,30 @@ class GuiItemLink { /** * If the core 'MyClass' has a shell 'MyClassLink' then 'Wrap' must have a 'using Type = MyClassLink' */ -template +template struct Wrap { }; /** * If the core 'MyClass' has a shell 'MyClassLink' then 'Unwrap' must have a 'using Type = MyClass' */ -template +template struct Unwrap { }; -template -typename Unwrap::Type* unwrap(T *t) { +template +typename Unwrap::Type *unwrap(T *t) { return t ? t->template get::Type>() : nullptr; } -template -const typename Unwrap::Type* unwrap(const T *t) { +template +const typename Unwrap::Type *unwrap(const T *t) { return t ? t->template get::Type>() : nullptr; } -template -const typename Wrap::Type* wrap(const U *u) { - return checked_static_cast::Type*>(u->gui_link); +template +const typename Wrap::Type *wrap(const U *u) { + return checked_static_cast::Type *>(u->gui_link); } /** @@ -53,33 +54,33 @@ const typename Wrap::Type* wrap(const U *u) { */ class GuiSingletonItem; -template -typename Wrap::Type* wrap(U *u, typename std::enable_if::Type>::value>::type* = nullptr) { - return u ? checked_static_cast::Type*>(u->gui_link) : nullptr; +template +typename Wrap::Type *wrap(U *u, typename std::enable_if::Type>::value>::type * = nullptr) { + return u ? checked_static_cast::Type *>(u->gui_link) : nullptr; } -template -typename Wrap::Type* wrap(U *u, typename std::enable_if::Type>::value>::type* = nullptr) { - return u ? checked_static_cast::Type*>(u->gui_link) : nullptr; +template +typename Wrap::Type *wrap(U *u, typename std::enable_if::Type>::value>::type * = nullptr) { + return u ? checked_static_cast::Type *>(u->gui_link) : nullptr; } -template -constexpr P&& wrap_if_can(typename std::remove_reference

::type&& p) noexcept { +template +constexpr P &&wrap_if_can(typename std::remove_reference

::type &&p) noexcept { return std::forward

(p); } -template +template T wrap_if_can(typename Unwrap::type>::Type *u) { return wrap(u); } -template -P unwrap_if_can(P& p) { +template +P unwrap_if_can(P &p) { return p; } -template::Type* = nullptr> -typename Unwrap::Type* unwrap_if_can(T *t) { +template ::Type * = nullptr> +typename Unwrap::Type *unwrap_if_can(T *t) { return unwrap(t); } @@ -87,10 +88,10 @@ typename Unwrap::Type* unwrap_if_can(T *t) { * Checking that callable can be called with given argument types. */ struct can_call_test { - template + template static decltype(std::declval()(std::declval()...), std::true_type()) f(int); - template + template static std::false_type f(...); }; @@ -100,7 +101,7 @@ struct can_call_test { * @tparam F callable * @tparam A arguments to test against the callable */ -template +template struct can_call : decltype(can_call_test::f(0)) { }; @@ -113,7 +114,7 @@ struct can_call : decltype(can_call_test::f(0)) { * @tparam F callable * @tparam A arguments to test against the callable */ -template +template constexpr void static_assert_about_unwrapping() { static_assert(can_call{}, "One of possible causes: if you're passing SomethingLink*, then don't forget to #include \"something_link.h\"."); } diff --git a/libopenage/renderer/vulkan/render_target.h b/libopenage/renderer/vulkan/render_target.h index 49db9e5ef1..c7c3ab2bed 100644 --- a/libopenage/renderer/vulkan/render_target.h +++ b/libopenage/renderer/vulkan/render_target.h @@ -3,10 +3,14 @@ #pragma once #include +#include -#include "../renderer.h" +#include -#include "graphics_device.h" +#include "log/log.h" + +#include "renderer/renderer.h" +#include "renderer/vulkan/graphics_device.h" namespace openage { diff --git a/libopenage/renderer/vulkan/shader_program.h b/libopenage/renderer/vulkan/shader_program.h index e46030dd13..e1b2b7c0b2 100644 --- a/libopenage/renderer/vulkan/shader_program.h +++ b/libopenage/renderer/vulkan/shader_program.h @@ -1,12 +1,14 @@ -// Copyright 2017-2018 the openage authors. See copying.md for legal info. +// Copyright 2017-2023 the openage authors. See copying.md for legal info. #pragma once -#include "../../error/error.h" -#include "../../log/log.h" +#include "error/error.h" +#include "log/log.h" -#include "../resources/shader_source.h" -#include "../shader_program.h" +#include + +#include "renderer/resources/shader_source.h" +#include "renderer/shader_program.h" namespace openage { @@ -15,12 +17,18 @@ namespace vulkan { static VkShaderStageFlagBits vk_shader_stage(resources::shader_stage_t stage) { switch (stage) { - case resources::shader_stage_t::vertex: return VK_SHADER_STAGE_VERTEX_BIT; - case resources::shader_stage_t::geometry: return VK_SHADER_STAGE_GEOMETRY_BIT; - case resources::shader_stage_t::tesselation_control: return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; - case resources::shader_stage_t::tesselation_evaluation: return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; - case resources::shader_stage_t::fragment: return VK_SHADER_STAGE_FRAGMENT_BIT; - default: throw Error(MSG(err) << "Unknown shader stage."); + case resources::shader_stage_t::vertex: + return VK_SHADER_STAGE_VERTEX_BIT; + case resources::shader_stage_t::geometry: + return VK_SHADER_STAGE_GEOMETRY_BIT; + case resources::shader_stage_t::tesselation_control: + return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT; + case resources::shader_stage_t::tesselation_evaluation: + return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT; + case resources::shader_stage_t::fragment: + return VK_SHADER_STAGE_FRAGMENT_BIT; + default: + throw Error(MSG(err) << "Unknown shader stage."); } } @@ -29,11 +37,11 @@ class VlkShaderProgram /* final : public ShaderProgram */ { std::vector modules; std::vector pipeline_stage_infos; - explicit VlkShaderProgram(VkDevice dev, std::vector const& srcs) { + explicit VlkShaderProgram(VkDevice dev, std::vector const &srcs) { // TODO reflect with spirv-cross // TODO if glsl, compile to spirv with libshaderc - for (auto const& src : srcs) { + for (auto const &src : srcs) { if (src.get_lang() != resources::shader_lang_t::spirv) { throw Error(MSG(err) << "Unsupported shader language in Vulkan shader."); } @@ -41,7 +49,7 @@ class VlkShaderProgram /* final : public ShaderProgram */ { VkShaderModuleCreateInfo cr_shdr = {}; cr_shdr.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; cr_shdr.codeSize = src.get_source().size(); - cr_shdr.pCode = reinterpret_cast(src.get_source().data()); + cr_shdr.pCode = reinterpret_cast(src.get_source().data()); VkShaderModule mod; VK_CALL_CHECKED(vkCreateShaderModule, dev, &cr_shdr, nullptr, &mod); @@ -61,4 +69,6 @@ class VlkShaderProgram /* final : public ShaderProgram */ { } }; -}}} // openage::renderer::vulkan +} // namespace vulkan +} // namespace renderer +} // namespace openage diff --git a/libopenage/rng/global_rng.h b/libopenage/rng/global_rng.h index 8ed475ae22..9fbe0f3f47 100644 --- a/libopenage/rng/global_rng.h +++ b/libopenage/rng/global_rng.h @@ -1,6 +1,10 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. + #pragma once +#include + + /** @file * This file contains functions for the global random number generator. * From 99d804388cfc3edb08bf5c0c9b4b05315e2fc007 Mon Sep 17 00:00:00 2001 From: heinezen Date: Thu, 2 Nov 2023 00:59:43 +0100 Subject: [PATCH 55/95] gui: Tranfer remaining GUI classes to renderer. --- libopenage/CMakeLists.txt | 1 - libopenage/gui/CMakeLists.txt | 13 - libopenage/gui/actions_list_model.cpp | 74 ----- libopenage/gui/actions_list_model.h | 71 ----- libopenage/gui/gui.cpp | 125 -------- libopenage/gui/gui.h | 56 ---- libopenage/gui/guisys/CMakeLists.txt | 43 --- libopenage/gui/guisys/link/gui_item.cpp | 20 -- .../gui/guisys/link/gui_singleton_item.cpp | 15 - .../gui/guisys/link/gui_singleton_item.h | 19 -- .../qml_engine_with_singleton_items_info.cpp | 45 --- .../qml_engine_with_singleton_items_info.h | 41 --- .../guisys/link/qtsdl_checked_static_cast.h | 15 - .../gui/guisys/private/game_logic_caller.cpp | 21 -- .../gui/guisys/private/game_logic_caller.h | 32 -- .../guisys/private/gui_application_impl.cpp | 62 ---- .../gui/guisys/private/gui_application_impl.h | 40 --- .../gui/guisys/private/gui_callback.cpp | 25 -- libopenage/gui/guisys/private/gui_callback.h | 26 -- .../gui/guisys/private/gui_ctx_setup.cpp | 101 ------- libopenage/gui/guisys/private/gui_ctx_setup.h | 92 ------ .../guisys/private/gui_dedicated_thread.cpp | 82 ------ .../gui/guisys/private/gui_dedicated_thread.h | 35 --- .../gui/guisys/private/gui_engine_impl.cpp | 77 ----- .../gui/guisys/private/gui_engine_impl.h | 54 ---- .../guisys/private/gui_event_queue_impl.cpp | 40 --- .../gui/guisys/private/gui_event_queue_impl.h | 33 --- .../private/gui_image_provider_impl.cpp | 32 -- .../guisys/private/gui_image_provider_impl.h | 27 -- .../gui/guisys/private/gui_input_impl.cpp | 171 ----------- .../gui/guisys/private/gui_input_impl.h | 37 --- .../gui/guisys/private/gui_renderer_impl.cpp | 270 ----------------- .../gui/guisys/private/gui_renderer_impl.h | 168 ----------- .../private/gui_rendering_setup_routines.cpp | 64 ---- .../private/gui_rendering_setup_routines.h | 55 ---- .../gui/guisys/private/gui_subtree_impl.cpp | 275 ------------------ .../gui/guisys/private/gui_subtree_impl.h | 97 ------ .../recursive_directory_watcher.cpp | 39 --- .../livereload/recursive_directory_watcher.h | 31 -- .../recursive_directory_watcher_worker.cpp | 73 ----- .../recursive_directory_watcher_worker.h | 49 ---- .../guisys/private/opengl_debug_logger.cpp | 49 ---- .../gui/guisys/private/opengl_debug_logger.h | 43 --- .../private/platforms/context_extraction.h | 23 -- .../platforms/context_extraction_cocoa.mm | 59 ---- .../platforms/context_extraction_win32.cpp | 47 --- .../platforms/context_extraction_x11.cpp | 61 ---- .../gui/guisys/public/gui_application.cpp | 27 -- .../gui/guisys/public/gui_application.h | 26 -- libopenage/gui/guisys/public/gui_engine.cpp | 16 - libopenage/gui/guisys/public/gui_engine.h | 30 -- .../gui/guisys/public/gui_event_queue.cpp | 20 -- .../gui/guisys/public/gui_event_queue.h | 26 -- .../gui/guisys/public/gui_image_provider.cpp | 16 - .../gui/guisys/public/gui_image_provider.h | 22 -- libopenage/gui/guisys/public/gui_input.cpp | 19 -- libopenage/gui/guisys/public/gui_input.h | 31 -- .../gui/guisys/public/gui_property_map.cpp | 166 ----------- .../gui/guisys/public/gui_property_map.h | 87 ------ libopenage/gui/guisys/public/gui_renderer.cpp | 25 -- libopenage/gui/guisys/public/gui_renderer.h | 38 --- .../guisys/public/gui_singleton_items_info.h | 13 - libopenage/gui/guisys/public/gui_subtree.cpp | 25 -- libopenage/gui/guisys/public/gui_subtree.h | 37 --- libopenage/gui/integration/CMakeLists.txt | 2 - .../gui/integration/private/CMakeLists.txt | 9 - .../private/gui_image_provider_link.cpp | 36 --- .../private/gui_image_provider_link.h | 28 -- .../gui/integration/private/gui_log.cpp | 53 ---- libopenage/gui/integration/private/gui_log.h | 12 - .../gui_make_standalone_subtexture.cpp | 13 - .../gui/integration/public/CMakeLists.txt | 3 - .../public/gui_application_with_logger.cpp | 24 -- .../public/gui_application_with_logger.h | 19 -- libopenage/gui/registrations.cpp | 12 - libopenage/gui/registrations.h | 15 - libopenage/presenter/presenter.cpp | 1 - libopenage/renderer/gui/CMakeLists.txt | 2 - libopenage/renderer/gui/engine_link.cpp | 96 ------ libopenage/renderer/gui/engine_link.h | 81 ------ libopenage/renderer/gui/gui.cpp | 3 - libopenage/renderer/gui/gui.h | 12 - libopenage/renderer/gui/guisys/CMakeLists.txt | 9 + .../renderer/gui/guisys/link/gui_item.cpp | 20 ++ .../{ => renderer}/gui/guisys/link/gui_item.h | 187 ++++++------ .../gui/guisys/link/gui_item_link.h | 7 +- .../gui/guisys/link/gui_item_list_model.h | 34 ++- .../gui/guisys/link/gui_list_model.cpp | 17 +- .../gui/guisys/link/gui_list_model.h | 23 +- .../gui/guisys/link/gui_property_map_impl.cpp | 14 +- .../gui/guisys/link/gui_property_map_impl.h | 7 +- .../gui/guisys/link/gui_singleton_item.cpp | 15 + .../gui/guisys/link/gui_singleton_item.h | 21 ++ .../guisys/link/qtsdl_checked_static_cast.h | 16 + .../gui/guisys/private/gui_ctx_setup.cpp | 3 +- ...erred_initial_constant_property_values.cpp | 9 +- ...eferred_initial_constant_property_values.h | 8 +- .../private/livereload/gui_live_reloader.cpp | 4 +- .../private/livereload/gui_live_reloader.h | 27 +- .../gui/integration/private/CMakeLists.txt | 7 +- .../private/gui_filled_texture_handles.cpp | 30 +- .../private/gui_filled_texture_handles.h | 25 +- .../gui_make_standalone_subtexture.cpp | 14 + .../private/gui_make_standalone_subtexture.h | 6 +- .../private/gui_standalone_subtexture.cpp | 6 +- .../private/gui_standalone_subtexture.h | 6 +- .../gui/integration/private/gui_texture.cpp | 13 +- .../gui/integration/private/gui_texture.h | 6 +- .../private/gui_texture_handle.cpp | 6 +- .../integration/private/gui_texture_handle.h | 7 +- libopenage/renderer/gui/qml_info.cpp | 15 - libopenage/renderer/gui/qml_info.h | 45 --- libopenage/renderer/opengl/window.cpp | 12 +- 113 files changed, 320 insertions(+), 4272 deletions(-) delete mode 100644 libopenage/gui/CMakeLists.txt delete mode 100644 libopenage/gui/actions_list_model.cpp delete mode 100644 libopenage/gui/actions_list_model.h delete mode 100644 libopenage/gui/gui.cpp delete mode 100644 libopenage/gui/gui.h delete mode 100644 libopenage/gui/guisys/CMakeLists.txt delete mode 100644 libopenage/gui/guisys/link/gui_item.cpp delete mode 100644 libopenage/gui/guisys/link/gui_singleton_item.cpp delete mode 100644 libopenage/gui/guisys/link/gui_singleton_item.h delete mode 100644 libopenage/gui/guisys/link/qml_engine_with_singleton_items_info.cpp delete mode 100644 libopenage/gui/guisys/link/qml_engine_with_singleton_items_info.h delete mode 100644 libopenage/gui/guisys/link/qtsdl_checked_static_cast.h delete mode 100644 libopenage/gui/guisys/private/game_logic_caller.cpp delete mode 100644 libopenage/gui/guisys/private/game_logic_caller.h delete mode 100644 libopenage/gui/guisys/private/gui_application_impl.cpp delete mode 100644 libopenage/gui/guisys/private/gui_application_impl.h delete mode 100644 libopenage/gui/guisys/private/gui_callback.cpp delete mode 100644 libopenage/gui/guisys/private/gui_callback.h delete mode 100644 libopenage/gui/guisys/private/gui_ctx_setup.cpp delete mode 100644 libopenage/gui/guisys/private/gui_ctx_setup.h delete mode 100644 libopenage/gui/guisys/private/gui_dedicated_thread.cpp delete mode 100644 libopenage/gui/guisys/private/gui_dedicated_thread.h delete mode 100644 libopenage/gui/guisys/private/gui_engine_impl.cpp delete mode 100644 libopenage/gui/guisys/private/gui_engine_impl.h delete mode 100644 libopenage/gui/guisys/private/gui_event_queue_impl.cpp delete mode 100644 libopenage/gui/guisys/private/gui_event_queue_impl.h delete mode 100644 libopenage/gui/guisys/private/gui_image_provider_impl.cpp delete mode 100644 libopenage/gui/guisys/private/gui_image_provider_impl.h delete mode 100644 libopenage/gui/guisys/private/gui_input_impl.cpp delete mode 100644 libopenage/gui/guisys/private/gui_input_impl.h delete mode 100644 libopenage/gui/guisys/private/gui_renderer_impl.cpp delete mode 100644 libopenage/gui/guisys/private/gui_renderer_impl.h delete mode 100644 libopenage/gui/guisys/private/gui_rendering_setup_routines.cpp delete mode 100644 libopenage/gui/guisys/private/gui_rendering_setup_routines.h delete mode 100644 libopenage/gui/guisys/private/gui_subtree_impl.cpp delete mode 100644 libopenage/gui/guisys/private/gui_subtree_impl.h delete mode 100644 libopenage/gui/guisys/private/livereload/recursive_directory_watcher.cpp delete mode 100644 libopenage/gui/guisys/private/livereload/recursive_directory_watcher.h delete mode 100644 libopenage/gui/guisys/private/livereload/recursive_directory_watcher_worker.cpp delete mode 100644 libopenage/gui/guisys/private/livereload/recursive_directory_watcher_worker.h delete mode 100644 libopenage/gui/guisys/private/opengl_debug_logger.cpp delete mode 100644 libopenage/gui/guisys/private/opengl_debug_logger.h delete mode 100644 libopenage/gui/guisys/private/platforms/context_extraction.h delete mode 100644 libopenage/gui/guisys/private/platforms/context_extraction_cocoa.mm delete mode 100644 libopenage/gui/guisys/private/platforms/context_extraction_win32.cpp delete mode 100644 libopenage/gui/guisys/private/platforms/context_extraction_x11.cpp delete mode 100644 libopenage/gui/guisys/public/gui_application.cpp delete mode 100644 libopenage/gui/guisys/public/gui_application.h delete mode 100644 libopenage/gui/guisys/public/gui_engine.cpp delete mode 100644 libopenage/gui/guisys/public/gui_engine.h delete mode 100644 libopenage/gui/guisys/public/gui_event_queue.cpp delete mode 100644 libopenage/gui/guisys/public/gui_event_queue.h delete mode 100644 libopenage/gui/guisys/public/gui_image_provider.cpp delete mode 100644 libopenage/gui/guisys/public/gui_image_provider.h delete mode 100644 libopenage/gui/guisys/public/gui_input.cpp delete mode 100644 libopenage/gui/guisys/public/gui_input.h delete mode 100644 libopenage/gui/guisys/public/gui_property_map.cpp delete mode 100644 libopenage/gui/guisys/public/gui_property_map.h delete mode 100644 libopenage/gui/guisys/public/gui_renderer.cpp delete mode 100644 libopenage/gui/guisys/public/gui_renderer.h delete mode 100644 libopenage/gui/guisys/public/gui_singleton_items_info.h delete mode 100644 libopenage/gui/guisys/public/gui_subtree.cpp delete mode 100644 libopenage/gui/guisys/public/gui_subtree.h delete mode 100644 libopenage/gui/integration/CMakeLists.txt delete mode 100644 libopenage/gui/integration/private/CMakeLists.txt delete mode 100644 libopenage/gui/integration/private/gui_image_provider_link.cpp delete mode 100644 libopenage/gui/integration/private/gui_image_provider_link.h delete mode 100644 libopenage/gui/integration/private/gui_log.cpp delete mode 100644 libopenage/gui/integration/private/gui_log.h delete mode 100644 libopenage/gui/integration/private/gui_make_standalone_subtexture.cpp delete mode 100644 libopenage/gui/integration/public/CMakeLists.txt delete mode 100644 libopenage/gui/integration/public/gui_application_with_logger.cpp delete mode 100644 libopenage/gui/integration/public/gui_application_with_logger.h delete mode 100644 libopenage/gui/registrations.cpp delete mode 100644 libopenage/gui/registrations.h delete mode 100644 libopenage/renderer/gui/engine_link.cpp delete mode 100644 libopenage/renderer/gui/engine_link.h create mode 100644 libopenage/renderer/gui/guisys/link/gui_item.cpp rename libopenage/{ => renderer}/gui/guisys/link/gui_item.h (62%) rename libopenage/{ => renderer}/gui/guisys/link/gui_item_link.h (97%) rename libopenage/{ => renderer}/gui/guisys/link/gui_item_list_model.h (68%) rename libopenage/{ => renderer}/gui/guisys/link/gui_list_model.cpp (85%) rename libopenage/{ => renderer}/gui/guisys/link/gui_list_model.h (58%) rename libopenage/{ => renderer}/gui/guisys/link/gui_property_map_impl.cpp (66%) rename libopenage/{ => renderer}/gui/guisys/link/gui_property_map_impl.h (74%) create mode 100644 libopenage/renderer/gui/guisys/link/gui_singleton_item.cpp create mode 100644 libopenage/renderer/gui/guisys/link/gui_singleton_item.h create mode 100644 libopenage/renderer/gui/guisys/link/qtsdl_checked_static_cast.h rename libopenage/{ => renderer}/gui/guisys/private/livereload/deferred_initial_constant_property_values.cpp (84%) rename libopenage/{ => renderer}/gui/guisys/private/livereload/deferred_initial_constant_property_values.h (88%) rename libopenage/{ => renderer}/gui/guisys/private/livereload/gui_live_reloader.cpp (98%) rename libopenage/{ => renderer}/gui/guisys/private/livereload/gui_live_reloader.h (78%) rename libopenage/{ => renderer}/gui/integration/private/gui_filled_texture_handles.cpp (70%) rename libopenage/{ => renderer}/gui/integration/private/gui_filled_texture_handles.h (74%) create mode 100644 libopenage/renderer/gui/integration/private/gui_make_standalone_subtexture.cpp rename libopenage/{ => renderer}/gui/integration/private/gui_make_standalone_subtexture.h (87%) rename libopenage/{ => renderer}/gui/integration/private/gui_standalone_subtexture.cpp (91%) rename libopenage/{ => renderer}/gui/integration/private/gui_standalone_subtexture.h (89%) rename libopenage/{ => renderer}/gui/integration/private/gui_texture.cpp (84%) rename libopenage/{ => renderer}/gui/integration/private/gui_texture.h (91%) rename libopenage/{ => renderer}/gui/integration/private/gui_texture_handle.cpp (94%) rename libopenage/{ => renderer}/gui/integration/private/gui_texture_handle.h (92%) delete mode 100644 libopenage/renderer/gui/qml_info.cpp delete mode 100644 libopenage/renderer/gui/qml_info.h diff --git a/libopenage/CMakeLists.txt b/libopenage/CMakeLists.txt index 46fc15da13..12ddac7899 100644 --- a/libopenage/CMakeLists.txt +++ b/libopenage/CMakeLists.txt @@ -340,7 +340,6 @@ add_subdirectory("engine") add_subdirectory("error") add_subdirectory("event") add_subdirectory("gamestate") -add_subdirectory("gui") add_subdirectory("input") add_subdirectory("job") add_subdirectory("log") diff --git a/libopenage/gui/CMakeLists.txt b/libopenage/gui/CMakeLists.txt deleted file mode 100644 index a96c486f54..0000000000 --- a/libopenage/gui/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -add_sources(libopenage - actions_list_model.cpp - gui.cpp - registrations.cpp -) - -add_subdirectory("guisys") - -add_sources(libopenage - ${QT_SDL_SOURCES} -) - -add_subdirectory("integration") diff --git a/libopenage/gui/actions_list_model.cpp b/libopenage/gui/actions_list_model.cpp deleted file mode 100644 index a8fa45fa46..0000000000 --- a/libopenage/gui/actions_list_model.cpp +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2016-2023 the openage authors. See copying.md for legal info. - -#include "actions_list_model.h" - -#include "../log/log.h" - -#include -#include - -namespace openage { -namespace gui { - -namespace { -const int registration = qmlRegisterType("yay.sfttech.openage", 1, 0, "ActionsListModel"); -} - -ActionsListModel::ActionsListModel(QObject *parent) : - QAbstractListModel{parent} { - Q_UNUSED(registration); -} - -ActionsListModel::~ActionsListModel() = default; - -QUrl ActionsListModel::get_icons_source() const { - return QUrl(this->icons_source); -} - -void ActionsListModel::set_icons_source(QUrl icons_source) { - this->icons_source = std::move(icons_source); -} - -void ActionsListModel::set_icons_source(const std::string &icons_source) { - this->icons_source = QUrl(icons_source.c_str()); - emit this->icons_source_changed(this->icons_source); -} - -QHash ActionsListModel::roleNames() const { - QHash roles; - roles[static_cast(ActionsRoles::IconRole)] = "ico"; - roles[static_cast(ActionsRoles::IconCheckedRole)] = "icoChk"; - roles[static_cast(ActionsRoles::GroupIDRole)] = "grpID"; - roles[static_cast(ActionsRoles::NameRole)] = "name"; - return roles; -} - -int ActionsListModel::rowCount(const QModelIndex &) const { - return this->buttons.size(); -} - -QVariant ActionsListModel::data(const QModelIndex &index, int role) const { - return this->buttons.at(index.row()).value(role); -} - -QMap ActionsListModel::itemData(const QModelIndex &index) const { - return this->buttons.at(index.row()); -} - -void ActionsListModel::clear_buttons() { - this->beginResetModel(); - this->buttons.clear(); - this->endResetModel(); -} - -void ActionsListModel::add_button(int ico, int ico_chk, int grp_id, const char *name) { - QMap map; - map[static_cast(ActionsRoles::IconRole)] = QVariant(ico); - map[static_cast(ActionsRoles::IconCheckedRole)] = QVariant(ico_chk); - map[static_cast(ActionsRoles::GroupIDRole)] = QVariant(grp_id); - map[static_cast(ActionsRoles::NameRole)] = QVariant(name); - this->buttons.push_back(map); -} - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/actions_list_model.h b/libopenage/gui/actions_list_model.h deleted file mode 100644 index 7ffff6a752..0000000000 --- a/libopenage/gui/actions_list_model.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2016-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include -#include -#include - -namespace openage { -namespace gui { - -/** - * Model used for the Action Buttons to render (e.g. for civilian units, - * military units, buildings etc.) - */ -class ActionsListModel : public QAbstractListModel { - Q_OBJECT - - Q_PROPERTY(QUrl iconsSource READ get_icons_source WRITE set_icons_source NOTIFY icons_source_changed) - -public: - ActionsListModel(QObject *parent = nullptr); - virtual ~ActionsListModel(); - - QUrl get_icons_source() const; - void set_icons_source(QUrl icons_source); - - enum class ActionsRoles { - IconRole = Qt::UserRole + 1, - IconCheckedRole, - GroupIDRole, - NameRole - }; - - enum class GroupIDs { - NoGroup, - StanceGroup - }; - -signals: - void icons_source_changed(const QUrl icons_source); - -private: - virtual QHash roleNames() const override; - virtual int rowCount(const QModelIndex &) const override; - virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - virtual QMap itemData(const QModelIndex &index) const override; - - /** - * Utility function to create a QUrl from a string and set it as iconsSource - */ - void set_icons_source(const std::string &icons_source); - - /** - * Clears all buttons - */ - void clear_buttons(); - - /** - * Shortcut to creating a QMap for a button - */ - void add_button(int ico, int ico_chk, int grp_id, const char *name); - - QUrl icons_source; - std::vector> buttons; -}; - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/gui.cpp b/libopenage/gui/gui.cpp deleted file mode 100644 index 9f2df8a983..0000000000 --- a/libopenage/gui/gui.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "gui.h" - -#include "../util/path.h" - - -namespace openage { -namespace gui { - - -GUI::GUI(/* SDL_Window *window, */ - const std::string &source, - const std::string &rootdir, - EngineQMLInfo *info) : - application{}, - render_updater{}, - renderer{/* window */}, - game_logic_updater{}, - engine{&renderer}, - subtree{ - &renderer, - &game_logic_updater, - &engine, - source, - rootdir}, - input{&renderer, &game_logic_updater} { - // info->display->register_resize_action(this); - // info->display->register_input_action(this); - // info->display->register_drawhud_action(this); -} - -GUI::~GUI() { -} - -void GUI::process_events() { - this->game_logic_updater.process_callbacks(); - this->application.processEvents(); -} - -// bool GUI::on_resize(coord::viewport_delta new_size) { -// this->renderer.resize(new_size.x, new_size.y); -// return true; -// } - -// bool GUI::on_input(SDL_Event *event) { -// return not this->input.process(event); -// } - -// namespace { -// /** -// * Restores blending function. -// */ -// class BlendPreserver { -// public: -// BlendPreserver() : -// was_on{}, -// src{}, -// dst{} { -// glGetBooleanv(GL_BLEND, &this->was_on); - -// if (this->was_on != GL_FALSE) { -// glGetIntegerv(GL_BLEND_SRC_ALPHA, &this->src); -// glGetIntegerv(GL_BLEND_DST_ALPHA, &this->dst); -// } -// } - -// ~BlendPreserver() { -// if (this->was_on != GL_FALSE) { -// glEnable(GL_BLEND); -// glBlendFunc(this->src, this->dst); -// } -// else { -// glDisable(GL_BLEND); -// } -// } - -// private: -// GLboolean was_on; -// GLint src; -// GLint dst; -// }; - -// } // namespace - -// bool GUI::on_drawhud() { -// this->render_updater.process_callbacks(); - -// BlendPreserver preserve_blend; - -// auto tex = this->renderer.render(); - -// glEnable(GL_BLEND); -// glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - -// this->textured_screen_quad_shader->use(); - -// glActiveTexture(GL_TEXTURE0); -// glBindTexture(GL_TEXTURE_2D, tex); - -// glEnableVertexAttribArray(this->textured_screen_quad_shader->pos_id); - -// glBindBuffer(GL_ARRAY_BUFFER, this->screen_quad_vbo); -// glVertexAttribPointer( -// this->textured_screen_quad_shader->pos_id, -// 2, -// GL_FLOAT, -// GL_FALSE, -// 2 * sizeof(float), -// 0); - -// glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - -// glDisableVertexAttribArray(this->textured_screen_quad_shader->pos_id); -// glBindBuffer(GL_ARRAY_BUFFER, 0); - -// glBindTexture(GL_TEXTURE_2D, 0); - -// this->textured_screen_quad_shader->stopusing(); - -// return true; -// } - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/gui.h b/libopenage/gui/gui.h deleted file mode 100644 index 36273e5462..0000000000 --- a/libopenage/gui/gui.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -#include "guisys/public/gui_engine.h" -#include "guisys/public/gui_event_queue.h" -#include "guisys/public/gui_input.h" -#include "guisys/public/gui_renderer.h" -#include "guisys/public/gui_subtree.h" -#include "integration/public/gui_application_with_logger.h" - - -namespace qtsdl { -class GuiSingletonItemsInfo; -} // namespace qtsdl - -namespace openage { -namespace gui { - -class EngineQMLInfo; - - -/** - * Main entry point for the openage Qt-based user interface. - * - * Legacy variant for the "old" renderer. - */ -class GUI { -public: - explicit GUI(/* SDL_Window *window, */ - const std::string &source, - const std::string &rootdir, - EngineQMLInfo *info = nullptr); - virtual ~GUI(); - - void process_events(); - -private: - // virtual bool on_resize(coord::viewport_delta new_size) override; - // virtual bool on_input(SDL_Event *event) override; - // virtual bool on_drawhud() override; - - GuiApplicationWithLogger application; - qtsdl::GuiEventQueue render_updater; - qtsdl::GuiRenderer renderer; - qtsdl::GuiEventQueue game_logic_updater; - qtsdl::GuiEngine engine; - qtsdl::GuiSubtree subtree; - qtsdl::GuiInput input; -}; - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/guisys/CMakeLists.txt b/libopenage/gui/guisys/CMakeLists.txt deleted file mode 100644 index 922c3ec72c..0000000000 --- a/libopenage/gui/guisys/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -list(APPEND QT_SDL_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/link/gui_item.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/link/gui_list_model.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/link/gui_property_map_impl.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/link/gui_singleton_item.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/link/qml_engine_with_singleton_items_info.cpp -) - -list(APPEND QT_SDL_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/public/gui_application.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/public/gui_engine.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/public/gui_event_queue.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/public/gui_image_provider.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/public/gui_input.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/public/gui_property_map.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/public/gui_renderer.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/public/gui_subtree.cpp -) - -list(APPEND QT_SDL_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/private/game_logic_caller.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/gui_application_impl.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/gui_callback.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/gui_ctx_setup.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/gui_dedicated_thread.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/gui_engine_impl.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/gui_event_queue_impl.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/gui_image_provider_impl.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/gui_input_impl.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/gui_renderer_impl.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/gui_rendering_setup_routines.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/gui_subtree_impl.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/opengl_debug_logger.cpp -) - -list(APPEND QT_SDL_SOURCES - ${CMAKE_CURRENT_SOURCE_DIR}/private/livereload/deferred_initial_constant_property_values.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/livereload/gui_live_reloader.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/livereload/recursive_directory_watcher.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/private/livereload/recursive_directory_watcher_worker.cpp -) - -set(QT_SDL_SOURCES ${QT_SDL_SOURCES} PARENT_SCOPE) diff --git a/libopenage/gui/guisys/link/gui_item.cpp b/libopenage/gui/guisys/link/gui_item.cpp deleted file mode 100644 index d8116501c4..0000000000 --- a/libopenage/gui/guisys/link/gui_item.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2015-2017 the openage authors. See copying.md for legal info. - -#include "gui_item.h" - -namespace qtsdl { - - -QString name_tidier(const char *name) { - QString cleaner_name = QString::fromLatin1(name); - cleaner_name.remove(QRegularExpression("qtsdl|PersistentCoreHolder")); - return cleaner_name; -} - -GuiItemQObject::GuiItemQObject(QObject *parent) - : - QObject{parent}, - GuiItemBase{} { -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/link/gui_singleton_item.cpp b/libopenage/gui/guisys/link/gui_singleton_item.cpp deleted file mode 100644 index c0348a4b90..0000000000 --- a/libopenage/gui/guisys/link/gui_singleton_item.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "gui_singleton_item.h" - -namespace qtsdl { - -GuiSingletonItem::GuiSingletonItem(QObject *parent) - : - QObject{parent}, - GuiItemLink{} { -} - -GuiSingletonItem::~GuiSingletonItem() = default; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/link/gui_singleton_item.h b/libopenage/gui/guisys/link/gui_singleton_item.h deleted file mode 100644 index 73c322ba4d..0000000000 --- a/libopenage/gui/guisys/link/gui_singleton_item.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "gui_item_link.h" - -namespace qtsdl { - -class GuiSingletonItem : public QObject, public GuiItemLink { - Q_OBJECT - -public: - explicit GuiSingletonItem(QObject *parent=nullptr); - virtual ~GuiSingletonItem(); -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/link/qml_engine_with_singleton_items_info.cpp b/libopenage/gui/guisys/link/qml_engine_with_singleton_items_info.cpp deleted file mode 100644 index 8b6f403f29..0000000000 --- a/libopenage/gui/guisys/link/qml_engine_with_singleton_items_info.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#include "qml_engine_with_singleton_items_info.h" - -#include - -namespace qtsdl { - -QmlEngineWithSingletonItemsInfo::QmlEngineWithSingletonItemsInfo(std::vector> &&image_providers, GuiSingletonItemsInfo *singleton_items_info) - : - QmlEngineWithSingletonItemsInfo{image_providers, singleton_items_info} { -} - -QmlEngineWithSingletonItemsInfo::QmlEngineWithSingletonItemsInfo(std::vector> &image_providers, GuiSingletonItemsInfo *singleton_items_info) - : - QQmlEngine{}, - image_providers(image_providers.size()), - singleton_items_info{singleton_items_info} { - - std::transform(std::begin(image_providers), std::end(image_providers), std::begin(this->image_providers), [] (const std::unique_ptr &image_provider) { - return image_provider.get(); - }); - - std::for_each(std::begin(image_providers), std::end(image_providers), [this] (std::unique_ptr &image_provider) { - auto id = image_provider->get_id(); - this->addImageProvider(id, image_provider.release()); - }); -} - -QmlEngineWithSingletonItemsInfo::~QmlEngineWithSingletonItemsInfo() { - std::for_each(std::begin(this->image_providers), std::end(this->image_providers), [this] (GuiImageProviderImpl *image_provider) { - image_provider->give_up(); - this->removeImageProvider(image_provider->get_id()); - }); -} - -GuiSingletonItemsInfo* QmlEngineWithSingletonItemsInfo::get_singleton_items_info() const { - return this->singleton_items_info; -} - -std::vector QmlEngineWithSingletonItemsInfo::get_image_providers() const { - return this->image_providers; -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/link/qml_engine_with_singleton_items_info.h b/libopenage/gui/guisys/link/qml_engine_with_singleton_items_info.h deleted file mode 100644 index 2470f24cce..0000000000 --- a/libopenage/gui/guisys/link/qml_engine_with_singleton_items_info.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2015-2017 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include - -#include "../private/gui_image_provider_impl.h" - -namespace qtsdl { - -class GuiSingletonItemsInfo; - -/** - * The Qml Engine used by openage. - * - * It's extended to contain the "singleton items info" and a list of image providers. - * The singleton item info is just a struct that allows to carry some variables - * in the qml-engine, namely the openage-engine. - * - * That way, the openage-engine and the qml-engine have a 1:1 relation and - * qml can access the main engine directly. - */ -class QmlEngineWithSingletonItemsInfo : public QQmlEngine { - Q_OBJECT - -public: - explicit QmlEngineWithSingletonItemsInfo(std::vector> &&image_providers, GuiSingletonItemsInfo *singleton_items_info=nullptr); - explicit QmlEngineWithSingletonItemsInfo(std::vector> &image_providers, GuiSingletonItemsInfo *singleton_items_info=nullptr); - virtual ~QmlEngineWithSingletonItemsInfo(); - - GuiSingletonItemsInfo* get_singleton_items_info() const; - std::vector get_image_providers() const; - -private: - std::vector image_providers; - GuiSingletonItemsInfo *singleton_items_info; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/link/qtsdl_checked_static_cast.h b/libopenage/gui/guisys/link/qtsdl_checked_static_cast.h deleted file mode 100644 index ecd5506984..0000000000 --- a/libopenage/gui/guisys/link/qtsdl_checked_static_cast.h +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -namespace qtsdl { - -template -T checked_static_cast(U *u) { - assert(dynamic_cast(u)); - return static_cast(u); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/game_logic_caller.cpp b/libopenage/gui/guisys/private/game_logic_caller.cpp deleted file mode 100644 index 3e277f686b..0000000000 --- a/libopenage/gui/guisys/private/game_logic_caller.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "game_logic_caller.h" - -#include "gui_callback.h" - -namespace qtsdl { - -GameLogicCaller::GameLogicCaller() - : - QObject{} { -} - -void GameLogicCaller::set_game_logic_callback(GuiCallback *game_logic_callback) { - QObject::disconnect(this, &GameLogicCaller::in_game_logic_thread, nullptr, nullptr); - QObject::disconnect(this, &GameLogicCaller::in_game_logic_thread_blocking, nullptr, nullptr); - QObject::connect(this, &GameLogicCaller::in_game_logic_thread, game_logic_callback, &GuiCallback::process); - QObject::connect(this, &GameLogicCaller::in_game_logic_thread_blocking, game_logic_callback, &GuiCallback::process_blocking, Qt::DirectConnection); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/game_logic_caller.h b/libopenage/gui/guisys/private/game_logic_caller.h deleted file mode 100644 index ef858b67b4..0000000000 --- a/libopenage/gui/guisys/private/game_logic_caller.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include - -namespace qtsdl { - -class GuiCallback; - -/** - * Attaches to the GuiCallbackImpl. - */ -class GameLogicCaller : public QObject { - Q_OBJECT - -public: - explicit GameLogicCaller(); - - /** - * Set up signal to be able to run code in the game logic thread. - */ - void set_game_logic_callback(GuiCallback *game_logic_callback); - -signals: - void in_game_logic_thread(const std::function& f) const; - void in_game_logic_thread_blocking(const std::function& f) const; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_application_impl.cpp b/libopenage/gui/guisys/private/gui_application_impl.cpp deleted file mode 100644 index bd5f6eeb78..0000000000 --- a/libopenage/gui/guisys/private/gui_application_impl.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "gui_application_impl.h" - -#include -#include - -#include -#include -#include - -namespace qtsdl { - -std::weak_ptr GuiApplicationImpl::instance; - -std::shared_ptr GuiApplicationImpl::get() { - std::shared_ptr candidate = GuiApplicationImpl::instance.lock(); - - assert(!candidate || std::this_thread::get_id() == candidate->owner); - - // Ensure that OpenGL is used and not OpenGL ES. - // This occurred in macos. See issue #1177 (PR #1179) - if (!candidate) { - QSurfaceFormat format; - format.setRenderableType(QSurfaceFormat::OpenGL); - QSurfaceFormat::setDefaultFormat(format); - } - - return candidate ? candidate : std::shared_ptr{new GuiApplicationImpl}; -} - -GuiApplicationImpl::~GuiApplicationImpl() { - assert(std::this_thread::get_id() == this->owner); -} - -void GuiApplicationImpl::processEvents() { - assert(std::this_thread::get_id() == this->owner); -#ifndef __APPLE__ - this->app.processEvents(); -#endif -} - -namespace { - int argc = 1; - char arg[] = "qtsdl"; - char *argv = &arg[0]; -} - -GuiApplicationImpl::GuiApplicationImpl() - : -#ifndef NDEBUG - owner{std::this_thread::get_id()}, -#endif - app{argc, &argv} -{ - // Set locale back to POSIX for the decimal point parsing (see qcoreapplication.html#locale-settings). - std::locale::global(std::locale().combine>(std::locale::classic())); - - qInfo() << "Compiled with Qt" << QT_VERSION_STR << "and run with Qt" << qVersion(); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_application_impl.h b/libopenage/gui/guisys/private/gui_application_impl.h deleted file mode 100644 index 14cd858691..0000000000 --- a/libopenage/gui/guisys/private/gui_application_impl.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -#include - -namespace qtsdl { - -/** - * Houses gui logic event queue. - * - * To launch it in a dedicated thread, use qtsdl::GuiDedicatedThread instead. - */ -class GuiApplicationImpl { -public: - static std::shared_ptr get(); - - ~GuiApplicationImpl(); - - void processEvents(); - -private: - GuiApplicationImpl(); - - GuiApplicationImpl(const GuiApplicationImpl&) = delete; - GuiApplicationImpl& operator=(const GuiApplicationImpl&) = delete; - -#ifndef NDEBUG - const std::thread::id owner; -#endif - - QGuiApplication app; - - static std::weak_ptr instance; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_callback.cpp b/libopenage/gui/guisys/private/gui_callback.cpp deleted file mode 100644 index 57c63ee01c..0000000000 --- a/libopenage/gui/guisys/private/gui_callback.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "gui_callback.h" - -#include - -namespace qtsdl { - -namespace { -const int registration = qRegisterMetaType>("function"); -} - -GuiCallback::GuiCallback() - : - QObject{} { - Q_UNUSED(registration); -} - -GuiCallback::~GuiCallback() = default; - -void GuiCallback::process(const std::function &f) { - f(); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_callback.h b/libopenage/gui/guisys/private/gui_callback.h deleted file mode 100644 index e42515b15f..0000000000 --- a/libopenage/gui/guisys/private/gui_callback.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include -#include - -namespace qtsdl { - -class GuiCallback : public QObject { - Q_OBJECT - -public: - GuiCallback(); - virtual ~GuiCallback(); - -signals: - void process_blocking(const std::function &f); - -public slots: - void process(const std::function &f); -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_ctx_setup.cpp b/libopenage/gui/guisys/private/gui_ctx_setup.cpp deleted file mode 100644 index 3cc34d35fe..0000000000 --- a/libopenage/gui/guisys/private/gui_ctx_setup.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2017-2023 the openage authors. See copying.md for legal info. - -#include "gui_ctx_setup.h" - -#include - -#include - -#include "opengl_debug_logger.h" -#include "platforms/context_extraction.h" - -namespace qtsdl { - -CtxExtractionException::CtxExtractionException(const std::string &what_arg) : - std::runtime_error{what_arg} { -} - -QOpenGLContext *CtxExtractionMode::get_ctx() { - return &this->ctx; -} - -GuiUniqueRenderingContext::GuiUniqueRenderingContext(/* SDL_Window *window */) : - CtxExtractionMode{} { - QVariant handle; - WId id; - - // std::tie(handle, id) = extract_native_context(window); - - // if (handle.isValid()) { - // // pass the SDL opengl context so qt can use it - // this->ctx.setNativeHandle(handle); - this->ctx.create(); - assert(this->ctx.isValid()); - - // reuse the sdl window - QWindow *w = QWindow::fromWinId(id); // fails on Wayland! - w->setSurfaceType(QSurface::OpenGLSurface); - - if (this->ctx.makeCurrent(w)) { - return; - } - // } - - throw CtxExtractionException("adding GUI to the main rendering context failed"); -} - -void GuiUniqueRenderingContext::pre_render() { -} - -void GuiUniqueRenderingContext::post_render() { -} - -GuiSeparateRenderingContext::GuiSeparateRenderingContext(/* SDL_Window *window */) : - CtxExtractionMode{} { - QVariant handle; - - // std::tie(handle, this->make_current_back) = extract_native_context_and_switchback_func(window); - - // if (handle.isValid()) { - // this->main_ctx.setNativeHandle(handle); - this->main_ctx.create(); - assert(this->main_ctx.isValid()); - - auto context_debug_parameters = get_current_opengl_debug_parameters(this->main_ctx); - - this->ctx.setFormat(this->main_ctx.format()); - this->ctx.setShareContext(&this->main_ctx); - this->ctx.create(); - assert(this->ctx.isValid()); - assert(!(this->main_ctx.format().options() ^ this->ctx.format().options()).testFlag(QSurfaceFormat::DebugContext)); - - this->offscreen_surface.setFormat(this->ctx.format()); - this->offscreen_surface.create(); - - this->pre_render(); - apply_opengl_debug_parameters(context_debug_parameters, this->ctx); - this->post_render(); - // } - // else { - // throw CtxExtractionException("creating separate context for GUI failed"); - // } -} - -GuiSeparateRenderingContext::~GuiSeparateRenderingContext() { - this->pre_render(); - this->ctx_logger.reset(); - this->post_render(); -} - -void GuiSeparateRenderingContext::pre_render() { - if (!this->ctx.makeCurrent(&this->offscreen_surface)) { - assert(false); - return; - } -} - -void GuiSeparateRenderingContext::post_render() { - this->make_current_back(); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_ctx_setup.h b/libopenage/gui/guisys/private/gui_ctx_setup.h deleted file mode 100644 index 8b5d1952d9..0000000000 --- a/libopenage/gui/guisys/private/gui_ctx_setup.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2017-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include - -#include -#include - -QT_FORWARD_DECLARE_CLASS(QOpenGLDebugLogger) - -namespace qtsdl { - -class CtxExtractionException : public std::runtime_error { -public: - explicit CtxExtractionException(const std::string &what_arg); -}; - -/** - * Abstract base for the method of getting a Qt-usable context. - */ -class CtxExtractionMode { -public: - virtual ~CtxExtractionMode() { - } - - /** - * @return context that can be used by Qt - */ - QOpenGLContext *get_ctx(); - - /** - * Function that must be called before rendering the GUI. - */ - virtual void pre_render() = 0; - - /** - * Function that must be called after rendering the GUI. - */ - virtual void post_render() = 0; - -protected: - QOpenGLContext ctx; -}; - -/** - * Use the same context to render the GUI. - */ -class GuiUniqueRenderingContext : public CtxExtractionMode { -public: - explicit GuiUniqueRenderingContext(/* SDL_Window *window */); - - virtual void pre_render() override; - virtual void post_render() override; -}; - -/** - * Create a separate context to render the GUI, make it shared with the main context. - */ -class GuiSeparateRenderingContext : public CtxExtractionMode { -public: - explicit GuiSeparateRenderingContext(/* SDL_Window *window */); - virtual ~GuiSeparateRenderingContext(); - - virtual void pre_render() override; - virtual void post_render() override; - -private: - /** - * GL context of the game - */ - QOpenGLContext main_ctx; - - /** - * GL debug logger of the GL context of the GUI - */ - std::unique_ptr ctx_logger; - - /** - * Function to make the game context current - */ - std::function make_current_back; - - /** - * Surface that is needed to make the GUI context current - */ - QOffscreenSurface offscreen_surface; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_dedicated_thread.cpp b/libopenage/gui/guisys/private/gui_dedicated_thread.cpp deleted file mode 100644 index 5eab4a77d0..0000000000 --- a/libopenage/gui/guisys/private/gui_dedicated_thread.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#include "gui_dedicated_thread.h" - -#include -#include - -#include - -#include "gui_application_impl.h" - -namespace qtsdl { - -std::weak_ptr GuiDedicatedThread::instance; - -bool GuiDedicatedThread::exists = false; -std::mutex GuiDedicatedThread::existence_guard; -std::condition_variable GuiDedicatedThread::destroyed; - -GuiDedicatedThread::GuiDedicatedThread() - : - worker{} { - - bool gui_started = false; - std::mutex gui_started_guard; - std::unique_lock lck{gui_started_guard}; - - std::condition_variable proceed_cond; - - this->worker = std::thread{[&] { - auto app = GuiApplicationImpl::get(); - - { - std::unique_lock lckInGui{gui_started_guard}; - gui_started = true; - } - - proceed_cond.notify_one(); - - QCoreApplication::instance()->exec(); - }}; - - proceed_cond.wait(lck, [&] {return gui_started;}); -} - -GuiDedicatedThread::~GuiDedicatedThread() { - QCoreApplication::instance()->quit(); - this->worker.join(); -} - -std::shared_ptr GuiDedicatedThread::get() { - std::shared_ptr candidate; - - std::unique_lock lck{GuiDedicatedThread::existence_guard}; - - GuiDedicatedThread::destroyed.wait(lck, [&candidate] { - return (candidate = GuiDedicatedThread::instance.lock()) || !GuiDedicatedThread::exists; - }); - - if (!candidate) { - GuiDedicatedThread::instance = candidate = std::shared_ptr{new GuiDedicatedThread, [] (GuiDedicatedThread *p) { - delete p; - - if (p) { - std::unique_lock dlck{GuiDedicatedThread::existence_guard}; - GuiDedicatedThread::exists = false; - - dlck.unlock(); - GuiDedicatedThread::destroyed.notify_all(); - } - }}; - - GuiDedicatedThread::exists = true; - - lck.unlock(); - GuiDedicatedThread::destroyed.notify_all(); - } - - return candidate; -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_dedicated_thread.h b/libopenage/gui/guisys/private/gui_dedicated_thread.h deleted file mode 100644 index f96339b5c7..0000000000 --- a/libopenage/gui/guisys/private/gui_dedicated_thread.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include -#include - -namespace qtsdl { - -/** - * Runs the gui logic in separate thread. - * - * For sharing the thread with something else, use qtsdl::GuiApplicationImpl instead. - */ -class GuiDedicatedThread { -public: - static std::shared_ptr get(); - - ~GuiDedicatedThread(); - -private: - GuiDedicatedThread(); - - std::thread worker; - - static std::weak_ptr instance; - - static bool exists; - static std::mutex existence_guard; - static std::condition_variable destroyed; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_engine_impl.cpp b/libopenage/gui/guisys/private/gui_engine_impl.cpp deleted file mode 100644 index e83141fb13..0000000000 --- a/libopenage/gui/guisys/private/gui_engine_impl.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "gui_engine_impl.h" - -#include - -#include -#include -#include - -#include "../public/gui_engine.h" -#include "gui_image_provider_impl.h" -#include "gui_renderer_impl.h" - -namespace qtsdl { - -GuiEngineImpl::GuiEngineImpl(GuiRenderer *renderer, - const std::vector &image_providers, - GuiSingletonItemsInfo *singleton_items_info) - : - QObject{}, - renderer{}, - engine{GuiImageProviderImpl::take_ownership(image_providers), singleton_items_info} { - - QThread *gui_thread = QCoreApplication::instance()->thread(); - this->moveToThread(gui_thread); - this->engine.moveToThread(gui_thread); - this->watcher.moveToThread(gui_thread); - - assert(!this->engine.incubationController()); - this->attach_to(GuiRendererImpl::impl(renderer)); - - QObject::connect(this, - &GuiEngineImpl::rootDirsPathsChanged, - &this->watcher, - &RecursiveDirectoryWatcher::rootDirsPathsChanged); - - QObject::connect(&this->watcher, - &RecursiveDirectoryWatcher::changeDetected, - this, - &GuiEngineImpl::onReload); -} - -GuiEngineImpl::~GuiEngineImpl() = default; - -GuiEngineImpl* GuiEngineImpl::impl(GuiEngine *engine) { - return engine->impl.get(); -} - -void GuiEngineImpl::attach_to(GuiRendererImpl *renderer) { - this->renderer = renderer; - this->engine.setIncubationController(this->renderer->get_window()->incubationController()); -} - -QQmlEngine* GuiEngineImpl::get_qml_engine() { - return &this->engine; -} - -void GuiEngineImpl::onReload() { - qDebug("reloading GUI"); - this->engine.clearComponentCache(); - emit this->reload(); -} - -void GuiEngineImpl::add_root_dir_path(const QString &root_dir_path) { - this->root_dirs_paths.push_back(root_dir_path); - emit this->rootDirsPathsChanged(this->root_dirs_paths); -} - -void GuiEngineImpl::remove_root_dir_path(const QString &root_dir_path) { - if (this->root_dirs_paths.removeOne(root_dir_path)) - emit this->rootDirsPathsChanged(this->root_dirs_paths); - else - qWarning() << "Failed to remove path watched by ReloadableQmlEngine."; -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_engine_impl.h b/libopenage/gui/guisys/private/gui_engine_impl.h deleted file mode 100644 index 57f78569aa..0000000000 --- a/libopenage/gui/guisys/private/gui_engine_impl.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2015-2017 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -#include "../link/qml_engine_with_singleton_items_info.h" -#include "livereload/recursive_directory_watcher.h" - -QT_FORWARD_DECLARE_CLASS(QQuickWindow) - -namespace qtsdl { - -class GuiRenderer; -class GuiRendererImpl; -class GuiImageProvider; -class GuiEngine; -class GuiSingletonItemsInfo; - -class GuiEngineImpl : public QObject { - Q_OBJECT - -public: - explicit GuiEngineImpl(GuiRenderer *renderer, - const std::vector &image_providers=std::vector(), - GuiSingletonItemsInfo *singleton_items_info=nullptr); - virtual ~GuiEngineImpl(); - - static GuiEngineImpl* impl(GuiEngine *engine); - - QQmlEngine* get_qml_engine(); - - void add_root_dir_path(const QString &root_dir_path); - void remove_root_dir_path(const QString &root_dir_path); - -signals: - void reload(); - void rootDirsPathsChanged(const QStringList&); - -public slots: - void attach_to(GuiRendererImpl *renderer); - void onReload(); - -private: - GuiRendererImpl *renderer; - - QmlEngineWithSingletonItemsInfo engine; - RecursiveDirectoryWatcher watcher; - - QStringList root_dirs_paths; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_event_queue_impl.cpp b/libopenage/gui/guisys/private/gui_event_queue_impl.cpp deleted file mode 100644 index bef677b91d..0000000000 --- a/libopenage/gui/guisys/private/gui_event_queue_impl.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "gui_event_queue_impl.h" - -#include - -#ifdef __APPLE__ -#include -#endif -#include - -#include "../public/gui_event_queue.h" - -namespace qtsdl { - -GuiEventQueueImpl::GuiEventQueueImpl() - : - thread{QThread::currentThread()} { -} - -GuiEventQueueImpl::~GuiEventQueueImpl() = default; - -GuiEventQueueImpl* GuiEventQueueImpl::impl(GuiEventQueue *event_queue) { - return event_queue->impl.get(); -} - -void GuiEventQueueImpl::process_callbacks() { - assert(QThread::currentThread() == this->thread); -#ifdef __APPLE__ - if (QThread::currentThread() != QCoreApplication::instance()->thread()) this->callback_processor.processEvents(); -#else - this->callback_processor.processEvents(); -#endif -} - -QThread* GuiEventQueueImpl::get_thread() { - return this->thread; -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_event_queue_impl.h b/libopenage/gui/guisys/private/gui_event_queue_impl.h deleted file mode 100644 index 5c97155f0d..0000000000 --- a/libopenage/gui/guisys/private/gui_event_queue_impl.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -QT_FORWARD_DECLARE_CLASS(QThread) - -namespace qtsdl { - -class GuiEventQueue; - -/** - * Provides synchronization with some game thread. - */ -class GuiEventQueueImpl { -public: - explicit GuiEventQueueImpl(); - ~GuiEventQueueImpl(); - - static GuiEventQueueImpl* impl(GuiEventQueue *event_queue); - - void process_callbacks(); - - QThread* get_thread(); - -private: - QThread * const thread; - QEventLoop callback_processor; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_image_provider_impl.cpp b/libopenage/gui/guisys/private/gui_image_provider_impl.cpp deleted file mode 100644 index 1badada7d2..0000000000 --- a/libopenage/gui/guisys/private/gui_image_provider_impl.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "gui_image_provider_impl.h" - -#include - -#include "../public/gui_image_provider.h" - -namespace qtsdl { - -GuiImageProviderImpl::GuiImageProviderImpl() - : - QQuickImageProvider{QQmlImageProviderBase::Texture, QQuickImageProvider::ForceAsynchronousImageLoading} { -} - -GuiImageProviderImpl::~GuiImageProviderImpl() = default; - -std::unique_ptr GuiImageProviderImpl::take_ownership(GuiImageProvider *image_provider) { - std::unique_ptr ptr{image_provider->impl.release()}; - image_provider->impl = decltype(image_provider->impl) {ptr.get(), [] (GuiImageProviderImpl*) {}}; - return ptr; -} - -std::vector> GuiImageProviderImpl::take_ownership(const std::vector &image_providers) { - std::vector> image_provider_owning_ptrs(image_providers.size()); - - std::transform(std::begin(image_providers), std::end(image_providers), std::begin(image_provider_owning_ptrs), static_cast(*)(GuiImageProvider*)>(GuiImageProviderImpl::take_ownership)); - - return image_provider_owning_ptrs; -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_image_provider_impl.h b/libopenage/gui/guisys/private/gui_image_provider_impl.h deleted file mode 100644 index 409fa1815e..0000000000 --- a/libopenage/gui/guisys/private/gui_image_provider_impl.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -#include - -namespace qtsdl { - -class GuiImageProvider; - -class GuiImageProviderImpl : public QQuickImageProvider { -public: - explicit GuiImageProviderImpl(); - virtual ~GuiImageProviderImpl(); - - static std::unique_ptr take_ownership(GuiImageProvider *image_provider); - static std::vector> take_ownership(const std::vector &image_providers); - - virtual const char* get_id() const = 0; - - virtual void give_up() = 0; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_input_impl.cpp b/libopenage/gui/guisys/private/gui_input_impl.cpp deleted file mode 100644 index 8675785596..0000000000 --- a/libopenage/gui/guisys/private/gui_input_impl.cpp +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "gui_input_impl.h" - -#include -#include -#include - -#include "../public/gui_event_queue.h" -#include "../public/gui_renderer.h" -#include "gui_event_queue_impl.h" -#include "gui_renderer_impl.h" - -namespace qtsdl { - -GuiInputImpl::GuiInputImpl(GuiRenderer *renderer, GuiEventQueue *game_logic_updater) : - QObject{}, - mouse_buttons_state{}, - game_logic_updater{GuiEventQueueImpl::impl(game_logic_updater)} { - const bool logic_diff_input = this->game_logic_updater->get_thread() != QThread::currentThread(); - const bool gui_diff_input = QCoreApplication::instance()->thread() != QThread::currentThread(); - const Qt::ConnectionType input_to_gui = gui_diff_input ? logic_diff_input ? Qt::BlockingQueuedConnection : Qt::QueuedConnection : Qt::DirectConnection; - - QObject::connect(this, &GuiInputImpl::input_event, GuiRendererImpl::impl(renderer)->get_window(), &EventHandlingQuickWindow::on_input_event, input_to_gui); -} - -GuiInputImpl::~GuiInputImpl() = default; - -namespace { -// static_assert(!(Qt::LeftButton & (static_cast(Qt::LeftButton) - 1)), "Qt non-one-bit mask."); -// static_assert(!(Qt::RightButton & (static_cast(Qt::RightButton) - 1)), "Qt non-one-bit mask."); -// static_assert(!(Qt::MiddleButton & (static_cast(Qt::MiddleButton) - 1)), "Qt non-one-bit mask."); -// static_assert(!(Qt::XButton1 & (static_cast(Qt::XButton1) - 1)), "Qt non-one-bit mask."); -// static_assert(!(Qt::XButton2 & (static_cast(Qt::XButton2) - 1)), "Qt non-one-bit mask."); - -// static_assert(SDL_BUTTON_LMASK == Qt::LeftButton, "SDL/Qt mouse button mask incompatibility."); -// static_assert(1 << (SDL_BUTTON_LEFT - 1) == Qt::LeftButton, "SDL/Qt mouse button mask incompatibility."); - -// // Right and middle are swapped. -// static_assert(SDL_BUTTON_RMASK == Qt::MiddleButton, "SDL/Qt mouse button mask incompatibility."); -// static_assert(1 << (SDL_BUTTON_RIGHT - 1) == Qt::MiddleButton, "SDL/Qt mouse button mask incompatibility."); - -// static_assert(SDL_BUTTON_MMASK == Qt::RightButton, "SDL/Qt mouse button mask incompatibility."); -// static_assert(1 << (SDL_BUTTON_MIDDLE - 1) == Qt::RightButton, "SDL/Qt mouse button mask incompatibility."); - -// static_assert(SDL_BUTTON_X1MASK == Qt::XButton1, "SDL/Qt mouse button mask incompatibility."); -// static_assert(1 << (SDL_BUTTON_X1 - 1) == Qt::XButton1, "SDL/Qt mouse button mask incompatibility."); - -// static_assert(SDL_BUTTON_X2MASK == Qt::XButton2, "SDL/Qt mouse button mask incompatibility."); -// static_assert(1 << (SDL_BUTTON_X2 - 1) == Qt::XButton2, "SDL/Qt mouse button mask incompatibility."); - -// static_assert(Qt::MiddleButton >> 1 == Qt::RightButton, "Qt::RightButton or Qt::MiddleButton has moved."); - -// int sdl_mouse_mask_to_qt(Uint32 state) { -// return (state & (Qt::LeftButton | Qt::XButton1 | Qt::XButton2)) | ((state & Qt::RightButton) << 1) | ((state & Qt::MiddleButton) >> 1); -// } - -// Qt::MouseButtons sdl_mouse_state_to_qt(Uint32 state) { -// return static_cast(sdl_mouse_mask_to_qt(state)); -// } - -// Qt::MouseButton sdl_mouse_btn_to_qt(Uint8 button) { -// return static_cast(sdl_mouse_mask_to_qt(1 << (button - 1))); -// } - -// int sdl_key_to_qt(SDL_Keycode sym) { -// switch (sym) { -// case SDLK_BACKSPACE: -// return Qt::Key_Backspace; -// case SDLK_DELETE: -// return Qt::Key_Delete; -// default: -// return 0; -// } -// } -} // namespace - -bool GuiInputImpl::process(/* SDL_Event *e */) { - // switch (e->type) { - // case SDL_MOUSEMOTION: { - // QMouseEvent ev{QEvent::MouseMove, QPoint{e->motion.x, e->motion.y}, Qt::MouseButton::NoButton, this->mouse_buttons_state = sdl_mouse_state_to_qt(e->motion.state), Qt::KeyboardModifier::NoModifier}; - // ev.setAccepted(false); - - // // Allow dragging stuff under the gui overlay. - // return relay_input_event(&ev, e->motion.state & (SDL_BUTTON_LMASK | SDL_BUTTON_MMASK | SDL_BUTTON_RMASK)); - // } - - // case SDL_MOUSEBUTTONDOWN: { - // auto button = sdl_mouse_btn_to_qt(e->button.button); - // QMouseEvent ev{QEvent::MouseButtonPress, QPoint{e->button.x, e->button.y}, button, this->mouse_buttons_state |= button, Qt::KeyboardModifier::NoModifier}; - // ev.setAccepted(false); - - // bool accepted = relay_input_event(&ev); - - // if (e->button.clicks == 2) { - // QMouseEvent ev_dbl{QEvent::MouseButtonDblClick, QPoint{e->button.x, e->button.y}, button, this->mouse_buttons_state, Qt::KeyboardModifier::NoModifier}; - // ev_dbl.setAccepted(false); - // accepted = relay_input_event(&ev_dbl) || accepted; - // } - - // return accepted; - // } - - // case SDL_MOUSEBUTTONUP: { - // auto button = sdl_mouse_btn_to_qt(e->button.button); - // QMouseEvent ev{QEvent::MouseButtonRelease, QPoint{e->button.x, e->button.y}, button, this->mouse_buttons_state &= ~button, Qt::KeyboardModifier::NoModifier}; - // ev.setAccepted(false); - - // // Allow dragging stuff under the gui overlay: when no item is grabbed, it probably means that initial MousButtonPress was outside gui. - // return relay_input_event(&ev, true); - // } - - // case SDL_MOUSEWHEEL: { - // QPoint pos; - // SDL_GetMouseState(&pos.rx(), &pos.ry()); - - // QWheelEvent ev{ - // pos, - // pos, - // QPoint{}, - // QPoint{e->wheel.x, e->wheel.y}, - // this->mouse_buttons_state, - // Qt::KeyboardModifier::NoModifier, // Correct states? - // Qt::ScrollPhase::NoScrollPhase, // ^ - // false, - // }; - // ev.setAccepted(false); - - // return relay_input_event(&ev); - // } - - // case SDL_KEYDOWN: { - // QKeyEvent ev{QEvent::KeyPress, sdl_key_to_qt(e->key.keysym.sym), Qt::NoModifier, QChar(static_cast(e->key.keysym.sym))}; - // ev.setAccepted(false); - // return relay_input_event(&ev); - // } - - // case SDL_KEYUP: { - // QKeyEvent ev{QEvent::KeyRelease, sdl_key_to_qt(e->key.keysym.sym), Qt::NoModifier, QChar(static_cast(e->key.keysym.sym))}; - // ev.setAccepted(false); - // return relay_input_event(&ev); - // } - - // default: - // return false; - // } - return false; -} - -bool GuiInputImpl::relay_input_event(QEvent *ev, bool only_if_grabbed) { - const bool logic_diff_input = this->game_logic_updater->get_thread() != QThread::currentThread(); - std::atomic processed{false}; - - emit this->input_event(&processed, ev, only_if_grabbed); - - // We have sent an event to the gui thread and want a response about collision. But the gui can be - // executing a getter that blocks the gui thread while doing something in the logic thread. - // So, if the logic thread is the same as the input thread, it should be running somehow. - // - // TODO: if/when the logic thread or input thread of the main game is made separate, give mutex or - // queue to the gui in order to replace this busy wait. - if (!logic_diff_input) - while (!processed) { - this->game_logic_updater->process_callbacks(); - QThread::usleep(1); - } - - return ev->isAccepted(); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_input_impl.h b/libopenage/gui/guisys/private/gui_input_impl.h deleted file mode 100644 index 4863b239e8..0000000000 --- a/libopenage/gui/guisys/private/gui_input_impl.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include - -namespace qtsdl { - -class GuiRenderer; -class GuiEventQueue; -class GuiEventQueueImpl; - -class GuiInputImpl : public QObject { - Q_OBJECT - -public: - explicit GuiInputImpl(GuiRenderer *renderer, GuiEventQueue *game_logic_updater); - virtual ~GuiInputImpl(); - - /** - * Returns true if the event was accepted. - */ - bool process(/* SDL_Event *e */); - -signals: - void input_event(std::atomic *processed, QEvent *ev, bool only_if_grabbed = false); - -private: - bool relay_input_event(QEvent *ev, bool only_if_grabbed = false); - - Qt::MouseButtons mouse_buttons_state; - GuiEventQueueImpl *game_logic_updater; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_renderer_impl.cpp b/libopenage/gui/guisys/private/gui_renderer_impl.cpp deleted file mode 100644 index a75974655f..0000000000 --- a/libopenage/gui/guisys/private/gui_renderer_impl.cpp +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "gui_renderer_impl.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../public/gui_renderer.h" - - -namespace qtsdl { - -namespace { -const int registration = qRegisterMetaType *>("atomic_bool_ptr"); -} - -EventHandlingQuickWindow::EventHandlingQuickWindow(QQuickRenderControl *render_control) : - QQuickWindow{render_control}, - focused_item{} { - Q_UNUSED(registration); -} - -EventHandlingQuickWindow::~EventHandlingQuickWindow() = default; - -void EventHandlingQuickWindow::on_input_event(std::atomic *processed, QEvent *event, bool only_if_grabbed) { - if (!only_if_grabbed || this->mouseGrabberItem()) { - if (this->focused_item && (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)) { - QCoreApplication::instance()->sendEvent(this->focused_item, event); - } - else { - QCoreApplication::instance()->sendEvent(this, event); - - auto change_focus = [this](QQuickItem *item) { - if (this->focused_item != item) { - if (this->focused_item) { - QFocusEvent focus_out{QEvent::FocusOut, Qt::ActiveWindowFocusReason}; - QCoreApplication::instance()->sendEvent(this->focused_item, &focus_out); - } - - if (item) { - QFocusEvent focus_in{QEvent::FocusIn, Qt::ActiveWindowFocusReason}; - QCoreApplication::instance()->sendEvent(item, &focus_in); - } - } - - this->focused_item = item; - }; - - // Loose keyboard focus when clicked outside of gui. - if (event->type() == QEvent::MouseButtonPress && !event->isAccepted()) - change_focus(nullptr); - - // Normally, the QQuickWindow would handle keyboard focus automatically, but it can't because neither QQuickWindow nor - // its target QWindow respond to requestActivate(). Which means no focus event propagation when injecting mouse clicks. - // So, the workaround is to look specifically for TextFields and give them focus directly. - // TODO: to remove when the proper focus for the foreign (that obtained from QWindow::fromWinId()) windows is implemented (Qt 5.6). - if (this->mouseGrabberItem() && this->mouseGrabberItem()->metaObject()->superClass() && this->mouseGrabberItem()->metaObject()->superClass()->className() == QString("QQuickTextInput") && (event->type() == QEvent::MouseButtonPress)) - change_focus(this->mouseGrabberItem()); - } - } - - *processed = true; -} - -void EventHandlingQuickWindow::on_resized(const QSize &size) { - this->resize(size); -} - -GuiRendererImpl::GuiRendererImpl(/* SDL_Window *window */) : - QObject{}, - gui_rendering_setup_routines{/* window */}, - need_fbo_resize{true}, - need_sync{}, - need_render{}, - gui_locked{}, - renderer_waiting_on_cond{} { - this->moveToThread(QCoreApplication::instance()->thread()); - - QObject::connect(&this->render_control, &QQuickRenderControl::renderRequested, [&]() { - this->need_render = true; - }); - - QObject::connect(&this->render_control, &QQuickRenderControl::sceneChanged, this, &GuiRendererImpl::on_scene_changed); - - this->window = std::make_unique(&this->render_control); - this->window->moveToThread(QCoreApplication::instance()->thread()); - QObject::connect(this, &GuiRendererImpl::resized, this->window.get(), &EventHandlingQuickWindow::on_resized); - // this->window->setClearBeforeRendering(true); - this->window->setColor(QColor{0, 0, 0, 0}); - - QObject::connect(&*this->window, &QQuickWindow::sceneGraphInitialized, this, [this] { - std::tie(this->new_fbo_width, this->new_fbo_height) = std::make_tuple(this->window->width(), this->window->height()); - this->need_fbo_resize = true; - }); - - QObject::connect(&*this->window, &QQuickWindow::widthChanged, [this] { this->new_fbo_width = this->window->width(); this->need_fbo_resize = true; }); - QObject::connect(&*this->window, &QQuickWindow::heightChanged, [this] { this->new_fbo_height = this->window->height(); this->need_fbo_resize = true; }); - - GuiRenderingCtxActivator activate_render(this->gui_rendering_setup_routines); - - // TODO: Make independent from OpenGL - this->window->setGraphicsDevice( - QQuickGraphicsDevice::fromOpenGLContext(this->gui_rendering_setup_routines.get_ctx())); - this->render_control.initialize(); -} - -void GuiRendererImpl::on_scene_changed() { - this->need_sync = true; - this->need_render = true; - this->render_control.polishItems(); -} - -void GuiRendererImpl::reinit_fbo_if_needed() { - assert(QThread::currentThread() == this->gui_rendering_setup_routines.get_ctx()->thread()); - - if (this->need_fbo_resize) { - this->fbo = std::make_unique(QSize(this->new_fbo_width, this->new_fbo_height), QOpenGLFramebufferObject::CombinedDepthStencil); - - // dirty workaround; texture id from our own implementation should be passed here - QQuickRenderTarget target = QQuickRenderTarget::fromOpenGLTexture(this->fbo->texture(), this->fbo->size()); - - this->window->setRenderTarget(target); - this->need_fbo_resize = false; - } - - assert(this->fbo); -} - -GuiRendererImpl::~GuiRendererImpl() { - // TODO: MAYBE: - // the this->ctx member frees the - // gl context even though that's SDL's job. - // - // the qt doc says that a native context isn't destroyed! - // but somehow it is lost or destroyed! - // https://doc.qt.io/qt-5/qopenglcontext.html#setNativeHandle -} - -GuiRendererImpl *GuiRendererImpl::impl(GuiRenderer *renderer) { - return renderer->impl.get(); -} - -GLuint GuiRendererImpl::render() { - GuiRenderingCtxActivator activate_render(this->gui_rendering_setup_routines); - - this->reinit_fbo_if_needed(); - - this->render_control.beginFrame(); - - // QQuickRenderControl::sync() must be called from the render thread while the gui thread is stopped. - if (this->need_sync) { - if (QCoreApplication::instance()->thread() != QThread::currentThread()) { - std::unique_lock lck{this->gui_guard}; - - if (this->need_sync) { - QCoreApplication::instance()->postEvent(this, new QEvent{QEvent::User}, INT_MAX); - - this->renderer_waiting_on_cond = true; - this->gui_locked_cond.wait(lck, [this] { return this->gui_locked; }); - this->renderer_waiting_on_cond = false; - - this->render_control.sync(); - - this->need_sync = false; - this->gui_locked = false; - - lck.unlock(); - this->gui_locked_cond.notify_one(); - } - } - else { - this->render_control.sync(); - } - } - - this->render_control.render(); - this->render_control.endFrame(); - - // this->window->resetOpenGLState(); - - return this->fbo->texture(); -} - -void GuiRendererImpl::make_sure_render_thread_unlocked() { - assert(QThread::currentThread() == QCoreApplication::instance()->thread()); - - if (this->need_sync && QThread::currentThread() != this->render_control.thread()) { - std::unique_lock lck{this->gui_guard}; - - if (this->renderer_waiting_on_cond) { - this->process_freeze(std::move(lck)); - QCoreApplication::instance()->removePostedEvents(this, QEvent::User); - } - } -} - -bool GuiRendererImpl::make_sure_render_thread_wont_sync() { - assert(QThread::currentThread() == QCoreApplication::instance()->thread()); - - if (this->need_sync && QThread::currentThread() != this->render_control.thread()) { - std::unique_lock lck{this->gui_guard}; - - if (this->renderer_waiting_on_cond) { - this->process_freeze(std::move(lck)); - QCoreApplication::instance()->removePostedEvents(this, QEvent::User); - assert(!this->need_sync); - } - else { - assert(this->need_sync); - this->need_sync = false; - return true; - } - } - - return false; -} - -void GuiRendererImpl::demand_sync() { - assert(QThread::currentThread() == QCoreApplication::instance()->thread()); - this->need_sync = true; -} - -bool GuiRendererImpl::event(QEvent *e) { - if (e->type() == QEvent::User) { - std::unique_lock lck{this->gui_guard}; - this->process_freeze(std::move(lck)); - return true; - } - else { - return this->QObject::event(e); - } -} - -void GuiRendererImpl::process_freeze(std::unique_lock lck) { - this->gui_locked = true; - - lck.unlock(); - this->gui_locked_cond.notify_one(); - - lck.lock(); - this->gui_locked_cond.wait(lck, [this] { return !this->gui_locked; }); -} - -EventHandlingQuickWindow *GuiRendererImpl::get_window() { - return &*this->window; -} - -void GuiRendererImpl::resize(const QSize &size) { - emit this->resized(size); -} - -TemporaryDisableGuiRendererSync::TemporaryDisableGuiRendererSync(GuiRendererImpl &renderer) : - renderer{renderer}, - need_sync{renderer.make_sure_render_thread_wont_sync()} { -} - -TemporaryDisableGuiRendererSync::~TemporaryDisableGuiRendererSync() { - if (this->need_sync) - renderer.demand_sync(); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_renderer_impl.h b/libopenage/gui/guisys/private/gui_renderer_impl.h deleted file mode 100644 index 45186f08c3..0000000000 --- a/libopenage/gui/guisys/private/gui_renderer_impl.h +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#ifndef __APPLE__ -#ifdef _MSC_VER -#define NOMINMAX -#include -#endif //_MSC_VER -#include -#else // __APPLE__ -#include -#endif - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "gui_rendering_setup_routines.h" - -QT_FORWARD_DECLARE_CLASS(QOpenGLFramebufferObject) - -namespace qtsdl { - -class GuiRenderer; - -class EventHandlingQuickWindow : public QQuickWindow { - Q_OBJECT - -public: - explicit EventHandlingQuickWindow(QQuickRenderControl *render_control); - virtual ~EventHandlingQuickWindow(); - -public slots: - void on_input_event(std::atomic *processed, QEvent *event, bool only_if_grabbed); - void on_resized(const QSize &size); - -private: - // TODO: to remove when the proper focus for the foreign (that obtained from QWindow::fromWinId()) windows is implemented (Qt 5.6). - QQuickItem *focused_item; -}; - -/** - * Passes the native graphic context to Qt. - */ -class GuiRendererImpl : public QObject { - Q_OBJECT - -public: - explicit GuiRendererImpl(/* SDL_Window *window */); - ~GuiRendererImpl(); - - static GuiRendererImpl *impl(GuiRenderer *renderer); - - /** - * @return texture ID where GUI was rendered - */ - GLuint render(); - - void resize(const QSize &size); - - EventHandlingQuickWindow *get_window(); - - /** - * When render thread is locked waiting for the gui thread to finish its current event and - * go to the high-priority 'freeze' event; but the gui thread can't finish the current event - * because it's going to lock the game-logic thread that will lock the render thread somehow. - * - * In this situation the gui thread should call this function to immediately process the 'freeze' - * event handler inside current event and remove the event from the gui queue. - * - * 'GuiRendererImpl::need_sync' is only set from the gui thread, so after the calling this function, - * we are fine for entire duration of the processing of the current event. - * - * If 'GuiRendererImpl::need_sync' is set, this function blocks until the render thread comes around - * to do the 'QQuickRenderControl::sync()'. If it's not good enough, it's possible to implement two - * separate functions to set 'GuiRendererImpl::need_sync' to false and then back to true. - */ - void make_sure_render_thread_unlocked(); - - /** - * Assures that the render thread won't try to stop the gui thread for syncing. - * - * Must be called from the gui thread. - * - * @return true if need_sync was set to false (you should restore it with the demand_sync()) - */ - bool make_sure_render_thread_wont_sync(); - - /** - * Sets 'GuiRendererImpl::need_sync' to true. - * - * Must be called from the gui thread. - */ - void demand_sync(); - -signals: - void resized(const QSize &size); - -private: - virtual bool event(QEvent *e) override; - - void process_freeze(std::unique_lock lck); - -private slots: - void on_scene_changed(); - -private: - /** - * If size changes, then create a new FBO for GUI rendering - */ - void reinit_fbo_if_needed(); - - /** - * Contains rendering context - * Use GuiRenderingCtxActivator to enable it - */ - GuiRenderingSetupRoutines gui_rendering_setup_routines; - - /** - * Contains scene graph of the GUI - */ - std::unique_ptr window; - - /** - * Object for sending render command to Qt - */ - QQuickRenderControl render_control; - - /** - * FBO where the GUI is rendered - */ - std::unique_ptr fbo; - - std::atomic new_fbo_width; - std::atomic new_fbo_height; - std::atomic need_fbo_resize; - - std::atomic need_sync; - std::atomic need_render; - - bool gui_locked; - std::mutex gui_guard; - std::condition_variable gui_locked_cond; - bool renderer_waiting_on_cond; -}; - -class TemporaryDisableGuiRendererSync { -public: - explicit TemporaryDisableGuiRendererSync(GuiRendererImpl &renderer); - ~TemporaryDisableGuiRendererSync(); - -private: - TemporaryDisableGuiRendererSync(const TemporaryDisableGuiRendererSync &) = delete; - TemporaryDisableGuiRendererSync &operator=(const TemporaryDisableGuiRendererSync &) = delete; - - GuiRendererImpl &renderer; - const bool need_sync; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_rendering_setup_routines.cpp b/libopenage/gui/guisys/private/gui_rendering_setup_routines.cpp deleted file mode 100644 index 059cc3f7b2..0000000000 --- a/libopenage/gui/guisys/private/gui_rendering_setup_routines.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2017-2023 the openage authors. See copying.md for legal info. - -#include "gui_rendering_setup_routines.h" - -#include - -#include - -#include "gui_ctx_setup.h" - -namespace qtsdl { - -GuiRenderingSetupRoutines::GuiRenderingSetupRoutines(/* SDL_Window *window */) { - try { - this->ctx_extraction_mode = std::make_unique(/* window */); - } - catch (const CtxExtractionException &) { - qInfo() << "Falling back to separate render context for GUI"; - - try { - this->ctx_extraction_mode = std::make_unique(/* window */); - } - catch (const CtxExtractionException &) { - assert(false && "setting up context for GUI failed"); - } - } -} - -GuiRenderingSetupRoutines::~GuiRenderingSetupRoutines() = default; - -QOpenGLContext *GuiRenderingSetupRoutines::get_ctx() { - return this->ctx_extraction_mode->get_ctx(); -} - -void GuiRenderingSetupRoutines::pre_render() { - this->ctx_extraction_mode->pre_render(); -} - -void GuiRenderingSetupRoutines::post_render() { - this->ctx_extraction_mode->post_render(); -} - -GuiRenderingCtxActivator::GuiRenderingCtxActivator(GuiRenderingSetupRoutines &rendering_setup_routines) : - rendering_setup_routines{&rendering_setup_routines} { - this->rendering_setup_routines->pre_render(); -} - -GuiRenderingCtxActivator::~GuiRenderingCtxActivator() { - if (this->rendering_setup_routines) - this->rendering_setup_routines->post_render(); -} - -GuiRenderingCtxActivator::GuiRenderingCtxActivator(GuiRenderingCtxActivator &&o) : - rendering_setup_routines{o.rendering_setup_routines} { - o.rendering_setup_routines = nullptr; -} - -GuiRenderingCtxActivator &GuiRenderingCtxActivator::operator=(GuiRenderingCtxActivator &&o) { - this->rendering_setup_routines = o.rendering_setup_routines; - o.rendering_setup_routines = nullptr; - return *this; -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_rendering_setup_routines.h b/libopenage/gui/guisys/private/gui_rendering_setup_routines.h deleted file mode 100644 index a262228c25..0000000000 --- a/libopenage/gui/guisys/private/gui_rendering_setup_routines.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2017-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include - -QT_FORWARD_DECLARE_CLASS(QOpenGLContext) - -namespace qtsdl { - -class CtxExtractionMode; - -class GuiRenderingCtxActivator; - -/** - * Returns a GL context usable by Qt classes. - * Provides pre- and post-rendering functions to make the context usable for GUI rendering. - */ -class GuiRenderingSetupRoutines { -public: - explicit GuiRenderingSetupRoutines(/* SDL_Window *window */); - ~GuiRenderingSetupRoutines(); - - QOpenGLContext *get_ctx(); - -private: - friend class GuiRenderingCtxActivator; - void pre_render(); - void post_render(); - - std::unique_ptr ctx_extraction_mode; -}; - -/** - * Prepares the context for rendering the GUI for one frame. - * Activator must be destroyed as soon as the GUI has executed its frame render call. - */ -class GuiRenderingCtxActivator { -public: - explicit GuiRenderingCtxActivator(GuiRenderingSetupRoutines &rendering_setup_routines); - ~GuiRenderingCtxActivator(); - - GuiRenderingCtxActivator(GuiRenderingCtxActivator &&o); - GuiRenderingCtxActivator &operator=(GuiRenderingCtxActivator &&o); - -private: - GuiRenderingCtxActivator(const GuiRenderingCtxActivator &) = delete; - GuiRenderingCtxActivator &operator=(const GuiRenderingCtxActivator &) = delete; - - GuiRenderingSetupRoutines *rendering_setup_routines; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_subtree_impl.cpp b/libopenage/gui/guisys/private/gui_subtree_impl.cpp deleted file mode 100644 index 5bfcb73fa9..0000000000 --- a/libopenage/gui/guisys/private/gui_subtree_impl.cpp +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "gui_subtree_impl.h" -#include "gui_renderer_impl.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gui_engine_impl.h" -#include "../link/gui_item.h" -#include "../public/gui_subtree.h" -#include "gui_event_queue_impl.h" - -namespace qtsdl { - - -GuiSubtreeImpl::GuiSubtreeImpl(GuiRenderer *renderer, - GuiEventQueue *game_logic_updater, - GuiEngine *engine, - const QString &source, - const QString &rootdir) - : - QObject{}, - renderer{}, - engine{}, - root{} { - - QObject::connect( - &this->game_logic_callback, - &GuiCallback::process_blocking, - this, - &GuiSubtreeImpl::on_process_game_logic_callback_blocking, - Qt::DirectConnection - ); - - QObject::connect( - this, - &GuiSubtreeImpl::process_game_logic_callback_blocking, - &this->game_logic_callback, - &GuiCallback::process, - (QCoreApplication::instance()->thread() != QThread::currentThread() - ? Qt::BlockingQueuedConnection - : Qt::DirectConnection) - ); - - this->moveToThread(QCoreApplication::instance()->thread()); - this->attach_to(GuiEventQueueImpl::impl(game_logic_updater)); - this->attach_to(GuiRendererImpl::impl(renderer)); - this->attach_to(GuiEngineImpl::impl(engine), rootdir); - - // Should now be initialized by the engine-attaching - assert(this->root_component); - - // Need to queue the loading because some underlying game logic elements - // require the loop to be running (maybe some things that are created after - // the gui). - QMetaObject::invokeMethod(this->root_component.get(), - "loadUrl", Qt::QueuedConnection, - Q_ARG(QUrl, QUrl::fromLocalFile(source))); -} - -GuiSubtreeImpl::~GuiSubtreeImpl() = default; - -void GuiSubtreeImpl::onEngineReloaded() { - const QUrl source = this->root_component->url(); - - this->destroy_root(); - - this->root_component = std::make_unique(this->engine.get_qml_engine()); - - QObject::connect( - this->root_component.get(), - &QQmlComponent::statusChanged, - this, - &GuiSubtreeImpl::component_status_changed - ); - - this->root_component->loadUrl(source); -} - -void GuiSubtreeImpl::attach_to(GuiEventQueueImpl *game_logic_updater) { - this->game_logic_callback.moveToThread(game_logic_updater->get_thread()); -} - -void GuiSubtreeImpl::attach_to(GuiRendererImpl *renderer) { - assert(renderer); - - if (this->renderer) - QObject::disconnect(this->renderer, nullptr, this, nullptr); - - this->renderer = renderer; - - QObject::connect( - this->renderer, - &GuiRendererImpl::resized, - this, - &GuiSubtreeImpl::on_resized - ); - this->reparent_root(); -} - -void GuiSubtreeImpl::attach_to(GuiEngineImpl *engine_impl, const QString &root_dir) { - if (this->engine.has_subtree()) { - this->destroy_root(); - this->engine = GuiEngineImplConnection{}; - } - - this->root_component = std::make_unique(engine_impl->get_qml_engine()); - - QObject::connect( - this->root_component.get(), - &QQmlComponent::statusChanged, - this, - &GuiSubtreeImpl::component_status_changed - ); - - // operator = && - this->engine = GuiEngineImplConnection{this, engine_impl, root_dir}; - - this->root_component->moveToThread(QCoreApplication::instance()->thread()); -} - -void GuiSubtreeImpl::component_status_changed(QQmlComponent::Status status) { - if (QQmlComponent::Error == status) { - qCritical("%s", qUtf8Printable(this->root_component->errorString())); - return; - } - - if (QQmlComponent::Ready == status) { - assert(!this->root); - - this->root = qobject_cast(this->root_component->beginCreate(this->engine.rootContext())); - assert(this->root); - - this->init_persistent_items(); - - this->root_component->completeCreate(); - - this->reparent_root(); - } -} - -void GuiSubtreeImpl::on_resized(const QSize &size) { - if (this->root) - this->root->setSize(size); -} - -void GuiSubtreeImpl::on_process_game_logic_callback_blocking(const std::function &f) { - TemporaryDisableGuiRendererSync {*this->renderer}; - emit this->process_game_logic_callback_blocking(f); -} - -void GuiSubtreeImpl::init_persistent_items() { - auto persistent = this->root->findChildren(); - - for (auto ap : persistent) - ap->get_attachee()->set_game_logic_callback(&this->game_logic_callback); - - this->reloader.init_persistent_items(persistent); -} - -void GuiSubtreeImpl::reparent_root() { - if (this->root) { - QQuickWindow *window = this->renderer->get_window(); - - this->root->setParentItem(window->contentItem()); - this->root->setSize(QSize{window->width(), window->height()}); - } -} - -void GuiSubtreeImpl::destroy_root() { - if (this->root) { - this->root->setParent(nullptr); - this->root->setParentItem(nullptr); - this->root->deleteLater(); - this->root = nullptr; - } -} - -GuiEngineImplConnection::GuiEngineImplConnection() - : - subtree{}, - engine{} { -} - -GuiEngineImplConnection::GuiEngineImplConnection(GuiSubtreeImpl *subtree, - GuiEngineImpl *engine, - QString root_dir) - : - subtree{subtree}, - engine{engine}, - root_dir{std::move(root_dir)} { - - assert(this->subtree); - assert(this->engine); - - QObject::connect( - this->engine, - &GuiEngineImpl::reload, - this->subtree, - &GuiSubtreeImpl::onEngineReloaded - ); - - // add the directory so it can be watched for changes. - this->engine->add_root_dir_path(this->root_dir); -} - -GuiEngineImplConnection::~GuiEngineImplConnection() { - this->disconnect(); -} - -void GuiEngineImplConnection::disconnect() { - if (this->has_subtree()) { - assert(this->engine); - - QObject::disconnect( - this->engine, - &GuiEngineImpl::reload, - this->subtree, - &GuiSubtreeImpl::onEngineReloaded - ); - - if (not this->root_dir.isEmpty()) { - this->engine->remove_root_dir_path(this->root_dir); - } - } -} - -GuiEngineImplConnection::GuiEngineImplConnection(GuiEngineImplConnection &&cnx) noexcept - : - subtree{cnx.subtree}, - engine{cnx.engine} { - - cnx.subtree = nullptr; - cnx.engine = nullptr; -} - -GuiEngineImplConnection& GuiEngineImplConnection::operator=(GuiEngineImplConnection &&cnx) noexcept { - this->disconnect(); - - this->subtree = cnx.subtree; - this->engine = cnx.engine; - - cnx.subtree = nullptr; - cnx.engine = nullptr; - - return *this; -} - -bool GuiEngineImplConnection::has_subtree() const { - return this->subtree != nullptr; -} - -QQmlContext* GuiEngineImplConnection::rootContext() const { - assert(this->subtree); - assert(this->engine); - return this->engine->get_qml_engine()->rootContext(); -} - -QQmlEngine* GuiEngineImplConnection::get_qml_engine() const { - assert(this->subtree); - assert(this->engine); - return this->engine->get_qml_engine(); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/gui_subtree_impl.h b/libopenage/gui/guisys/private/gui_subtree_impl.h deleted file mode 100644 index 6c737c11f1..0000000000 --- a/libopenage/gui/guisys/private/gui_subtree_impl.h +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include - -#include -#include - -#include "gui_callback.h" -#include "livereload/gui_live_reloader.h" - -QT_FORWARD_DECLARE_CLASS(QQuickItem) - -namespace qtsdl { - -class GuiRenderer; -class GuiRendererImpl; -class GuiEventQueue; -class GuiEventQueueImpl; -class GuiEngine; -class GuiEngineImpl; -class GuiSubtreeImpl; - -class GuiEngineImplConnection { -public: - GuiEngineImplConnection(); - explicit GuiEngineImplConnection(GuiSubtreeImpl *subtree, - GuiEngineImpl *engine, - QString root_dir); - ~GuiEngineImplConnection(); - - GuiEngineImplConnection(GuiEngineImplConnection &&cnx) noexcept; - GuiEngineImplConnection& operator=(GuiEngineImplConnection &&cnx) noexcept; - - bool has_subtree() const; - - QQmlContext* rootContext() const; - QQmlEngine* get_qml_engine() const; - -private: - GuiEngineImplConnection(const GuiEngineImplConnection &cnx) = delete; - GuiEngineImplConnection& operator=(const GuiEngineImplConnection &cnx) = delete; - - void disconnect(); - - GuiSubtreeImpl *subtree; - GuiEngineImpl *engine; - QString root_dir; -}; - - -class GuiSubtreeImpl : public QObject { - Q_OBJECT - -public: - explicit GuiSubtreeImpl(GuiRenderer *renderer, - GuiEventQueue *game_logic_updater, - GuiEngine *engine, - const QString &source, - const QString &rootdir); - virtual ~GuiSubtreeImpl(); - -public slots: - void onEngineReloaded(); - - void attach_to(GuiEventQueueImpl *game_logic_updater); - void attach_to(GuiRendererImpl *renderer); - void attach_to(GuiEngineImpl *engine, const QString &source); - -private slots: - void component_status_changed(QQmlComponent::Status status); - void on_resized(const QSize &size); - void on_process_game_logic_callback_blocking(const std::function &f); - -signals: - void process_game_logic_callback_blocking(const std::function &f); - -private: - void init_persistent_items(); - - void reparent_root(); - void destroy_root(); - - GuiRendererImpl *renderer; - GuiEngineImplConnection engine; - GuiLiveReloader reloader; - - GuiCallback game_logic_callback; - - std::unique_ptr root_component; - QQuickItem *root; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/livereload/recursive_directory_watcher.cpp b/libopenage/gui/guisys/private/livereload/recursive_directory_watcher.cpp deleted file mode 100644 index 6e3422dc0c..0000000000 --- a/libopenage/gui/guisys/private/livereload/recursive_directory_watcher.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#include "recursive_directory_watcher.h" - -#include -#include - -#include "recursive_directory_watcher_worker.h" - -namespace qtsdl { - -RecursiveDirectoryWatcher::RecursiveDirectoryWatcher(QObject *parent) - : - QObject{parent} { - - QSemaphore wait_worker_started; - - this->worker = std::async(std::launch::async, [this, &wait_worker_started] { - QEventLoop loop; - QObject::connect(this, &RecursiveDirectoryWatcher::quit, &loop, &QEventLoop::quit); - - RecursiveDirectoryWatcherWorker watcher; - QObject::connect(&watcher, &RecursiveDirectoryWatcherWorker::changeDetected, this, &RecursiveDirectoryWatcher::changeDetected); - QObject::connect(this, &RecursiveDirectoryWatcher::rootDirsPathsChanged, &watcher, &RecursiveDirectoryWatcherWorker::onRootDirsPathsChanged); - - wait_worker_started.release(); - - loop.exec(); - }); - - wait_worker_started.acquire(); -} - -RecursiveDirectoryWatcher::~RecursiveDirectoryWatcher() { - emit this->quit(); - this->worker.wait(); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/livereload/recursive_directory_watcher.h b/libopenage/gui/guisys/private/livereload/recursive_directory_watcher.h deleted file mode 100644 index d55e7b8f99..0000000000 --- a/libopenage/gui/guisys/private/livereload/recursive_directory_watcher.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include -#include - -namespace qtsdl { - -/** - * Emits a signal when anything changes in the directories. - */ -class RecursiveDirectoryWatcher : public QObject { - Q_OBJECT - -public: - explicit RecursiveDirectoryWatcher(QObject *parent = nullptr); - virtual ~RecursiveDirectoryWatcher(); - -signals: - void changeDetected(); - void rootDirsPathsChanged(const QStringList&); - void quit(); - -private: - std::future worker; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/livereload/recursive_directory_watcher_worker.cpp b/libopenage/gui/guisys/private/livereload/recursive_directory_watcher_worker.cpp deleted file mode 100644 index ff8e9f7242..0000000000 --- a/libopenage/gui/guisys/private/livereload/recursive_directory_watcher_worker.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#include "recursive_directory_watcher_worker.h" - -#include - -#include -#include - -namespace qtsdl { - -namespace { -const int batch_ms = 100; -} - -RecursiveDirectoryWatcherWorker::RecursiveDirectoryWatcherWorker() - : - QObject{} { - - this->batching_timer.setInterval(batch_ms); - this->batching_timer.setSingleShot(true); - QObject::connect(&this->batching_timer, &QTimer::timeout, this, &RecursiveDirectoryWatcherWorker::changeDetected); - QObject::connect(&this->batching_timer, &QTimer::timeout, this, &RecursiveDirectoryWatcherWorker::restartWatching); -} - -void RecursiveDirectoryWatcherWorker::onRootDirsPathsChanged(const QStringList &root_dirs_paths) { - if (this->root_dirs_paths != root_dirs_paths) { - this->root_dirs_paths = root_dirs_paths; - this->restartWatching(); - } -} - -namespace { -QStringList collect_entries_to_watch(const QStringList &root_dirs_paths) { - QStringList root_dirs_paths_no_duplicates = root_dirs_paths; - root_dirs_paths_no_duplicates.removeDuplicates(); - - QStringList entries_to_watch; - - std::for_each(std::begin(root_dirs_paths_no_duplicates), std::end(root_dirs_paths_no_duplicates), [&entries_to_watch] (const QString& root_dir_path) { - QDirIterator it{root_dir_path, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks}; - - while (it.hasNext()) { - entries_to_watch.append(it.next()); - } - }); - - return entries_to_watch; -} -} - -void RecursiveDirectoryWatcherWorker::restartWatching() { - this->restart_watching(collect_entries_to_watch(this->root_dirs_paths)); -} - -void RecursiveDirectoryWatcherWorker::restart_watching(const QStringList &entries_to_watch) { - this->watcher.reset(); - this->watcher = std::make_unique(); - - QObject::connect(&*this->watcher, &QFileSystemWatcher::directoryChanged, this, &RecursiveDirectoryWatcherWorker::onEntryChanged); - - if (entries_to_watch.empty()) - qWarning() << "RecursiveDirectoryWatcheWorker hasn't found any files to watch."; - else - this->watcher->addPaths(entries_to_watch); -} - -void RecursiveDirectoryWatcherWorker::onEntryChanged() { - if (!this->batching_timer.isActive()) - this->batching_timer.start(); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/livereload/recursive_directory_watcher_worker.h b/libopenage/gui/guisys/private/livereload/recursive_directory_watcher_worker.h deleted file mode 100644 index 88af26d97d..0000000000 --- a/libopenage/gui/guisys/private/livereload/recursive_directory_watcher_worker.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include -#include -#include - -namespace qtsdl { - -/** - * Emits a signal when anything changes in the directories. - */ -class RecursiveDirectoryWatcherWorker : public QObject { - Q_OBJECT - -public: - RecursiveDirectoryWatcherWorker(); - -signals: - void changeDetected(); - -public slots: - void onRootDirsPathsChanged(const QStringList &root_dirs_paths); - void restartWatching(); - -private slots: - void onEntryChanged(); - -private: - void restart_watching(const QStringList &entries_to_watch); - - /** - * Actual watcher. - * Its event processing and destruction has to be in the same separate thread. - */ - std::unique_ptr watcher; - - /** - * Waits to glue multiple changes into one event. - */ - QTimer batching_timer; - - QStringList root_dirs_paths; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/opengl_debug_logger.cpp b/libopenage/gui/guisys/private/opengl_debug_logger.cpp deleted file mode 100644 index b61bc58f20..0000000000 --- a/libopenage/gui/guisys/private/opengl_debug_logger.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2017-2023 the openage authors. See copying.md for legal info. - -#include "opengl_debug_logger.h" - -#include -#include -#include - -#ifdef __APPLE__ -// from https://www.khronos.org/registry/OpenGL/api/GL/glext.h -#define GL_DEBUG_CALLBACK_FUNCTION 0x8244 -#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 -#define GL_DEBUG_TYPE_ERROR 0x824C -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E -#endif - -namespace qtsdl { - -gl_debug_parameters get_current_opengl_debug_parameters(QOpenGLContext ¤t_source_context) { - gl_debug_parameters params{}; - - if (QOpenGLVersionFunctionsFactory::get(¤t_source_context)) - if ((params.is_debug = current_source_context.format().options().testFlag(QSurfaceFormat::DebugContext))) { - glGetPointerv(GL_DEBUG_CALLBACK_FUNCTION, ¶ms.callback); - params.synchronous = glIsEnabled(GL_DEBUG_OUTPUT_SYNCHRONOUS); - } - - return params; -} - -void apply_opengl_debug_parameters(gl_debug_parameters params, QOpenGLContext ¤t_dest_context) { - if (params.is_debug && params.callback) { - if (auto functions = QOpenGLVersionFunctionsFactory::get(¤t_dest_context)) { - functions->initializeOpenGLFunctions(); - - functions->glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_FALSE); - - functions->glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_ERROR, GL_DONT_CARE, 0, nullptr, GL_TRUE); - functions->glDebugMessageControl(GL_DONT_CARE, GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR, GL_DONT_CARE, 0, nullptr, GL_TRUE); - - functions->glDebugMessageCallback((GLDEBUGPROC)params.callback, nullptr); - - if (params.synchronous) - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - } - } -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/opengl_debug_logger.h b/libopenage/gui/guisys/private/opengl_debug_logger.h deleted file mode 100644 index 7fda1cad80..0000000000 --- a/libopenage/gui/guisys/private/opengl_debug_logger.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2017-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -QT_FORWARD_DECLARE_CLASS(QOpenGLContext) - -namespace qtsdl { -struct gl_debug_parameters { - /** - * True if the GL context is a debug context - */ - bool is_debug; - - /** - * Function that GL context uses to report debug messages - */ - GLvoid *callback; - - /** - * True if debug callback calling method is chosen to be synchronous - */ - bool synchronous; -}; - -/** - * Get debugging settings of the current GL context - * - * @param current_source_context current GL context - * @return debugging settings - */ -gl_debug_parameters get_current_opengl_debug_parameters(QOpenGLContext ¤t_source_context); - -/** - * Create a GL logger in the current GL context - * - * @param params debugging settings - * @param current_dest_context current GL context to which parameters will be applied - */ -void apply_opengl_debug_parameters(gl_debug_parameters params, QOpenGLContext ¤t_dest_context); - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/platforms/context_extraction.h b/libopenage/gui/guisys/private/platforms/context_extraction.h deleted file mode 100644 index 7bbf515d8b..0000000000 --- a/libopenage/gui/guisys/private/platforms/context_extraction.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -#include -#include - -namespace qtsdl { - -/** - * @return current context (or null) and id of the window - */ -// std::tuple extract_native_context(SDL_Window *window); - -/** - * @return current context (or null) and function to get it back to the window - */ -// std::tuple> extract_native_context_and_switchback_func(SDL_Window *window); - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/platforms/context_extraction_cocoa.mm b/libopenage/gui/guisys/private/platforms/context_extraction_cocoa.mm deleted file mode 100644 index 076924d8af..0000000000 --- a/libopenage/gui/guisys/private/platforms/context_extraction_cocoa.mm +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2015-2017 the openage authors. See copying.md for legal info. - -#include - -#include "context_extraction.h" - -#include - -#include "SDL_syswm.h" -#import - -namespace qtsdl { - -std::tuple extract_native_context(SDL_Window *window) { - - assert(window); - - NSOpenGLContext *current_context = [NSOpenGLContext currentContext]; - assert(current_context); - - NSView *view = nullptr; - - SDL_SysWMinfo wm_info; - SDL_VERSION(&wm_info.version); - - - if (SDL_GetWindowWMInfo(window, &wm_info)) { - NSWindow *ns_window = wm_info.info.cocoa.window; - view = [ns_window contentView]; - assert(view); - } - return std::make_tuple(QVariant::fromValue(QCocoaNativeContext(current_context)), reinterpret_cast(view)); -} - -std::tuple> extract_native_context_and_switchback_func(SDL_Window *window) { - assert(window); - - NSOpenGLContext *current_context = [NSOpenGLContext currentContext]; - assert(current_context); - - NSView *view = nullptr; - - SDL_SysWMinfo wm_info; - SDL_VERSION(&wm_info.version); - - if (SDL_GetWindowWMInfo(window, &wm_info)) { - NSWindow *ns_window = wm_info.info.cocoa.window; - view = [ns_window contentView]; - assert(view); - - return std::make_tuple(QVariant::fromValue(QCocoaNativeContext(current_context)), [current_context] { - [current_context makeCurrentContext]; - }); - } - - return std::tuple>{}; -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/platforms/context_extraction_win32.cpp b/libopenage/gui/guisys/private/platforms/context_extraction_win32.cpp deleted file mode 100644 index 1c413ff926..0000000000 --- a/libopenage/gui/guisys/private/platforms/context_extraction_win32.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include - -#include "context_extraction.h" -#include - -#include -// #include -#include - -namespace qtsdl { - -// std::tuple extract_native_context(/* SDL_Window *window */) { -// assert(window); - -// HGLRC current_context; -// SDL_SysWMinfo wm_info; -// SDL_VERSION(&wm_info.version); -// if (SDL_GetWindowWMInfo(window, &wm_info)) { -// current_context = wglGetCurrentContext(); -// assert(current_context); -// } -// QWGLNativeContext nativeContext(current_context, wm_info.info.win.window); -// return {QVariant::fromValue(nativeContext), reinterpret_cast(wm_info.info.win.window)}; -// } - -// std::tuple> extract_native_context_and_switchback_func(/* SDL_Window *window */) { -// assert(window); - -// HGLRC current_context; -// SDL_SysWMinfo wm_info; -// SDL_VERSION(&wm_info.version); -// if (SDL_GetWindowWMInfo(window, &wm_info)) { -// current_context = wglGetCurrentContext(); -// assert(current_context); - -// return std::make_tuple(QVariant::fromValue(QWGLNativeContext(current_context, wm_info.info.win.window)), [wm_info, current_context] { -// wglMakeCurrent(wm_info.info.win.hdc, current_context); -// }); -// } - -// return std::tuple>{}; -// } - - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/private/platforms/context_extraction_x11.cpp b/libopenage/gui/guisys/private/platforms/context_extraction_x11.cpp deleted file mode 100644 index 333307c1f9..0000000000 --- a/libopenage/gui/guisys/private/platforms/context_extraction_x11.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include - -#include "context_extraction.h" - -// #include -#include -// #include - -// DO NOT INCLUDE ANYTHING HERE, X11 HEADERS BREAK STUFF - -namespace qtsdl { - -// std::tuple extract_native_context(SDL_Window *window) { -// assert(window); - -// GLXContext current_context = nullptr; -// SDL_SysWMinfo wm_info; -// SDL_VERSION(&wm_info.version); - -// if (SDL_GetWindowWMInfo(window, &wm_info)) { -// assert(wm_info.info.x11.display); - -// current_context = glXGetCurrentContext(); -// assert(current_context); - -// return std::make_tuple( -// QVariant::fromValue( -// QGLXNativeContext(current_context, -// wm_info.info.x11.display, -// wm_info.info.x11.window)), -// wm_info.info.x11.window -// ); -// } - -// return std::tuple{}; -// } - -// std::tuple> extract_native_context_and_switchback_func(SDL_Window *window) { -// assert(window); - -// GLXContext current_context; -// SDL_SysWMinfo wm_info; -// SDL_VERSION(&wm_info.version); - -// if (SDL_GetWindowWMInfo(window, &wm_info)) { -// assert(wm_info.info.x11.display); - -// current_context = glXGetCurrentContext(); -// assert(current_context); - -// return std::make_tuple(QVariant::fromValue(QGLXNativeContext(current_context, wm_info.info.x11.display, wm_info.info.x11.window)), [wm_info, current_context] { -// glXMakeCurrent(wm_info.info.x11.display, wm_info.info.x11.window, current_context); -// }); -// } - -// return std::tuple>{}; -// } - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_application.cpp b/libopenage/gui/guisys/public/gui_application.cpp deleted file mode 100644 index 1b7a511095..0000000000 --- a/libopenage/gui/guisys/public/gui_application.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include - -#include "../public/gui_application.h" - -#include "../private/gui_application_impl.h" - -namespace qtsdl { - -GuiApplication::GuiApplication() - : - application{GuiApplicationImpl::get()} { -} - -GuiApplication::GuiApplication(std::shared_ptr application) - : - application{application} { -} - -GuiApplication::~GuiApplication() = default; - -void GuiApplication::processEvents() { - this->application->processEvents(); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_application.h b/libopenage/gui/guisys/public/gui_application.h deleted file mode 100644 index 6b64e6b111..0000000000 --- a/libopenage/gui/guisys/public/gui_application.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -namespace qtsdl { - -class GuiApplicationImpl; - -/** - * Houses gui logic event queue. - */ -class GuiApplication { -public: - GuiApplication(); - GuiApplication(std::shared_ptr application); - ~GuiApplication(); - - void processEvents(); - -private: - std::shared_ptr application; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_engine.cpp b/libopenage/gui/guisys/public/gui_engine.cpp deleted file mode 100644 index 689a4ff87f..0000000000 --- a/libopenage/gui/guisys/public/gui_engine.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "../public/gui_engine.h" - -#include "../private/gui_engine_impl.h" - -namespace qtsdl { - -GuiEngine::GuiEngine(GuiRenderer *renderer, const std::vector &image_providers, GuiSingletonItemsInfo *singleton_items_info) - : - impl{std::make_unique(renderer, image_providers, singleton_items_info)} { -} - -GuiEngine::~GuiEngine() = default; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_engine.h b/libopenage/gui/guisys/public/gui_engine.h deleted file mode 100644 index 153ceb11ab..0000000000 --- a/libopenage/gui/guisys/public/gui_engine.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -namespace qtsdl { - -class GuiRenderer; -class GuiImageProvider; -class GuiEngineImpl; -class GuiSingletonItemsInfo; - -/** - * Represents one QML execution environment. - */ -class GuiEngine { -public: - explicit GuiEngine(GuiRenderer *renderer, - const std::vector &image_providers = std::vector(), - GuiSingletonItemsInfo *singleton_items_info = nullptr); - ~GuiEngine(); - -private: - friend class GuiEngineImpl; - std::unique_ptr impl; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_event_queue.cpp b/libopenage/gui/guisys/public/gui_event_queue.cpp deleted file mode 100644 index 4b9866c1a9..0000000000 --- a/libopenage/gui/guisys/public/gui_event_queue.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "../public/gui_event_queue.h" - -#include "../private/gui_event_queue_impl.h" - -namespace qtsdl { - -GuiEventQueue::GuiEventQueue() - : - impl{std::make_unique()} { -} - -GuiEventQueue::~GuiEventQueue() = default; - -void GuiEventQueue::process_callbacks() { - this->impl->process_callbacks(); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_event_queue.h b/libopenage/gui/guisys/public/gui_event_queue.h deleted file mode 100644 index d7b6076e9a..0000000000 --- a/libopenage/gui/guisys/public/gui_event_queue.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -namespace qtsdl { - -class GuiEventQueueImpl; - -/** - * Provides synchronization with some game thread. - */ -class GuiEventQueue { -public: - explicit GuiEventQueue(); - ~GuiEventQueue(); - - void process_callbacks(); - -private: - friend class GuiEventQueueImpl; - std::unique_ptr impl; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_image_provider.cpp b/libopenage/gui/guisys/public/gui_image_provider.cpp deleted file mode 100644 index 961a0f3c20..0000000000 --- a/libopenage/gui/guisys/public/gui_image_provider.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "../public/gui_image_provider.h" - -#include "../private/gui_image_provider_impl.h" - -namespace qtsdl { - -GuiImageProvider::GuiImageProvider(std::unique_ptr impl) - : - impl{impl.release(), std::default_delete()} { -} - -GuiImageProvider::~GuiImageProvider() = default; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_image_provider.h b/libopenage/gui/guisys/public/gui_image_provider.h deleted file mode 100644 index 6a5e074769..0000000000 --- a/libopenage/gui/guisys/public/gui_image_provider.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -namespace qtsdl { - -class GuiImageProviderImpl; - -class GuiImageProvider { -public: - explicit GuiImageProvider(std::unique_ptr impl); - ~GuiImageProvider(); - -private: - friend class GuiImageProviderImpl; - std::unique_ptr> impl; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_input.cpp b/libopenage/gui/guisys/public/gui_input.cpp deleted file mode 100644 index 861e6a5f6e..0000000000 --- a/libopenage/gui/guisys/public/gui_input.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "../public/gui_input.h" - -#include "../private/gui_input_impl.h" - -namespace qtsdl { - -GuiInput::GuiInput(GuiRenderer *renderer, GuiEventQueue *game_logic_updater) : - impl{std::make_unique(renderer, game_logic_updater)} { -} - -GuiInput::~GuiInput() = default; - -bool GuiInput::process(/* SDL_Event *event */) { - return this->impl->process(/* event */); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_input.h b/libopenage/gui/guisys/public/gui_input.h deleted file mode 100644 index 1a46b227be..0000000000 --- a/libopenage/gui/guisys/public/gui_input.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -namespace qtsdl { - -class GuiRenderer; -class GuiEventQueue; -class GuiInputImpl; - -/** - * Converts SDL input events into Qt events. - */ -class GuiInput { -public: - explicit GuiInput(GuiRenderer *renderer, GuiEventQueue *game_logic_updater); - ~GuiInput(); - - /** - * Returns true if the event was accepted. - */ - bool process(/* SDL_Event *event */); - -private: - friend class GuiInputImpl; - std::unique_ptr impl; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_property_map.cpp b/libopenage/gui/guisys/public/gui_property_map.cpp deleted file mode 100644 index b52b3a31b3..0000000000 --- a/libopenage/gui/guisys/public/gui_property_map.cpp +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "gui_property_map.h" - -#include -#include -#include -#include - -#include -#include - -#include - -#include "../link/gui_property_map_impl.h" - -namespace qtsdl { - -GuiPropertyMap::GuiPropertyMap() : - impl{std::make_unique()} { - assert(QCoreApplication::instance()); -} - -GuiPropertyMap::~GuiPropertyMap() = default; - -namespace { -template -T getter(const QObject &map, const char *name) { - auto v = map.property(name); - - if (!v.isValid()) - return T(); - - using namespace std::string_literals; - - if (!v.canConvert()) - throw std::runtime_error("Can't interpret a property '"s + name + "' of type '"s + v.typeName() + "' as '"s + typeid(T).name() + "'."s); - - return v.value(); -} - -template -void setter(QObject &map, const char *name, T v) { - map.setProperty(name, QVariant::fromValue(v)); -} - -template <> -void setter(QObject &map, const char *name, const char *v) { - map.setProperty(name, v); -} - -std::vector strings_to_vector(const QStringList &strings) { - std::vector result(strings.size()); - std::transform(std::begin(strings), std::end(strings), std::begin(result), [](const QString &s) { return s.toStdString(); }); - - return result; -} - -QStringList vector_to_strings(const std::vector &v) { - QStringList strings; - std::transform(std::begin(v), std::end(v), std::back_inserter(strings), [](const std::string &s) { return QString::fromStdString(s); }); - - return strings; -} -} // namespace - -template <> -bool GuiPropertyMap::getv(const char *name) const { - return getter(*this->impl, name); -} - -template <> -void GuiPropertyMap::setv(const char *name, bool v) { - setter(*this->impl, name, v); -} - -template <> -int GuiPropertyMap::getv(const char *name) const { - return getter(*this->impl, name); -} - -template <> -void GuiPropertyMap::setv(const char *name, int v) { - setter(*this->impl, name, v); -} - -template <> -double GuiPropertyMap::getv(const char *name) const { - return getter(*this->impl, name); -} - -template <> -void GuiPropertyMap::setv(const char *name, double v) { - setter(*this->impl, name, v); -} - -template <> -std::string GuiPropertyMap::getv(const char *name) const { - return getter(*this->impl, name).toStdString(); -} - -template <> -void GuiPropertyMap::setv(const char *name, const std::string &v) { - setter(*this->impl, name, QString::fromStdString(v)); -} - -template <> -void GuiPropertyMap::setv(const char *name, const char *v) { - setter(*this->impl, name, v); -} - -template <> -std::vector GuiPropertyMap::getv>(const char *name) const { - return strings_to_vector(getter(*this->impl, name)); -} - -template <> -void GuiPropertyMap::setv &>(const char *name, const std::vector &v) { - setter(*this->impl, name, vector_to_strings(v)); -} - -template <> -QString GuiPropertyMap::getv(const char *name) const { - return getter(*this->impl, name); -} - -template <> -void GuiPropertyMap::setv(const char *name, const QString &v) { - setter(*this->impl, name, v); -} - -template <> -QStringList GuiPropertyMap::getv(const char *name) const { - return getter(*this->impl, name); -} - -template <> -void GuiPropertyMap::setv(const char *name, const QStringList &v) { - setter(*this->impl, name, v); -} - -void GuiPropertyMap::setv(const char *name, const std::string &v) { - this->setv(name, v); -} - -void GuiPropertyMap::setv(const std::string &name, const std::string &v) { - this->setv(name.c_str(), v); -} - -void GuiPropertyMap::setv(const char *name, const std::vector &v) { - this->setv &>(name, v); -} - -void GuiPropertyMap::setv(const std::string &name, const std::vector &v) { - this->setv &>(name.c_str(), v); -} - -std::vector GuiPropertyMap::get_csv(const char *name) const { - return strings_to_vector(getter(*this->impl, name).split(QRegularExpression("\\s*,\\s*"))); -} - -void GuiPropertyMap::set_csv(const char *name, const std::vector &v) { - setter(*this->impl, name, vector_to_strings(v).join(", ")); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_property_map.h b/libopenage/gui/guisys/public/gui_property_map.h deleted file mode 100644 index 7c67238027..0000000000 --- a/libopenage/gui/guisys/public/gui_property_map.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include - -namespace qtsdl { - -class GuiPropertyMapImpl; - -struct GuiPropertyMap { - GuiPropertyMap(); - ~GuiPropertyMap(); - - template - T getv(const char *name) const; - - template - T getv(const std::string &name) const { - return this->getv(name.c_str()); - } - - std::vector get_csv(const char *name) const; - - std::vector get_csv(const std::string &name) const { - return this->get_csv(name.c_str()); - } - - template - void setv(const char *name, T v); - - template - void setv(const std::string &name, T v) { - this->setv(name.c_str(), v); - } - - void set_csv(const char *name, const std::vector &v); - - void set_csv(const std::string &name, const std::vector &v) { - this->set_csv(name.c_str(), v); - } - - void setv(const char *name, const std::string &v); - void setv(const std::string &name, const std::string &v); - - void setv(const char *name, const std::vector &v); - void setv(const std::string &name, const std::vector &v); - - std::unique_ptr impl; -}; - -template<> -bool GuiPropertyMap::getv(const char *name) const; - -template<> -void GuiPropertyMap::setv(const char *name, bool v); - -template<> -int GuiPropertyMap::getv(const char *name) const; - -template<> -void GuiPropertyMap::setv(const char *name, int v); - -template<> -double GuiPropertyMap::getv(const char *name) const; - -template<> -void GuiPropertyMap::setv(const char *name, double v); - -template<> -std::string GuiPropertyMap::getv(const char *name) const; - -template<> -void GuiPropertyMap::setv(const char *name, const std::string &v); - -template<> -void GuiPropertyMap::setv(const char *name, const char *v); - -template<> -std::vector GuiPropertyMap::getv>(const char *name) const; - -template<> -void GuiPropertyMap::setv&>(const char *name, const std::vector &v); - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_renderer.cpp b/libopenage/gui/guisys/public/gui_renderer.cpp deleted file mode 100644 index a11063e7e5..0000000000 --- a/libopenage/gui/guisys/public/gui_renderer.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "../public/gui_renderer.h" - -#include - -#include "../private/gui_renderer_impl.h" - -namespace qtsdl { - -GuiRenderer::GuiRenderer(/* SDL_Window *window */) : - impl{std::make_unique(/* window */)} { -} - -GuiRenderer::~GuiRenderer() = default; - -GLuint GuiRenderer::render() { - return this->impl->render(); -} - -void GuiRenderer::resize(int w, int h) { - this->impl->resize(QSize{w, h}); -} - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_renderer.h b/libopenage/gui/guisys/public/gui_renderer.h deleted file mode 100644 index bc8e93dd99..0000000000 --- a/libopenage/gui/guisys/public/gui_renderer.h +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#ifndef __APPLE__ -#ifdef _MSC_VER -#define NOMINMAX -#include -#endif //_MSC_VER -#include -#else // __APPLE__ -#include -#endif - -namespace qtsdl { - -class GuiRendererImpl; - -/** - * Passes the native graphic context to Qt. - */ -class GuiRenderer { -public: - // TODO: allow FBO variant - explicit GuiRenderer(/* SDL_Window *window */); - ~GuiRenderer(); - - GLuint render(); - void resize(int w, int h); - -private: - friend class GuiRendererImpl; - std::unique_ptr impl; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_singleton_items_info.h b/libopenage/gui/guisys/public/gui_singleton_items_info.h deleted file mode 100644 index 1889b4c2c0..0000000000 --- a/libopenage/gui/guisys/public/gui_singleton_items_info.h +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2015-2017 the openage authors. See copying.md for legal info. - -#pragma once - -namespace qtsdl { - -/** - * Accessible during creation of any singleton QML item. - */ -class GuiSingletonItemsInfo { -}; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_subtree.cpp b/libopenage/gui/guisys/public/gui_subtree.cpp deleted file mode 100644 index 00abcedab1..0000000000 --- a/libopenage/gui/guisys/public/gui_subtree.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "gui_subtree.h" - -#include "../private/gui_subtree_impl.h" - -namespace qtsdl { - -GuiSubtree::GuiSubtree(GuiRenderer *renderer, - GuiEventQueue *game_logic_updater, - GuiEngine *engine, - const std::string &source, - const std::string &rootdir) - : - impl{std::make_unique( - renderer, - game_logic_updater, - engine, - QString::fromStdString(source), - QString::fromStdString(rootdir) - )} {} - -GuiSubtree::~GuiSubtree() = default; - -} // namespace qtsdl diff --git a/libopenage/gui/guisys/public/gui_subtree.h b/libopenage/gui/guisys/public/gui_subtree.h deleted file mode 100644 index ffd4141b2a..0000000000 --- a/libopenage/gui/guisys/public/gui_subtree.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2015-2017 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - - -namespace qtsdl { - -class GuiRenderer; -class GuiEventQueue; -class GuiEngine; -class GuiSubtreeImpl; - - -/** - * A root item that loads its code from source url. - * - * rootdir is the qml file root folder which is watched for changes. - */ -class GuiSubtree { -public: - explicit GuiSubtree(GuiRenderer *renderer, - GuiEventQueue *game_logic_updater, - GuiEngine *engine, - const std::string &source, - const std::string &rootdir); - - ~GuiSubtree(); - -private: - friend class GuiSubtreeImpl; - std::unique_ptr impl; -}; - -} // namespace qtsdl diff --git a/libopenage/gui/integration/CMakeLists.txt b/libopenage/gui/integration/CMakeLists.txt deleted file mode 100644 index 0bb272b5c5..0000000000 --- a/libopenage/gui/integration/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_subdirectory("private") -add_subdirectory("public") diff --git a/libopenage/gui/integration/private/CMakeLists.txt b/libopenage/gui/integration/private/CMakeLists.txt deleted file mode 100644 index 88be5e9db6..0000000000 --- a/libopenage/gui/integration/private/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_sources(libopenage - gui_filled_texture_handles.cpp - gui_image_provider_link.cpp - gui_log.cpp - gui_make_standalone_subtexture.cpp - gui_standalone_subtexture.cpp - gui_texture.cpp - gui_texture_handle.cpp -) diff --git a/libopenage/gui/integration/private/gui_image_provider_link.cpp b/libopenage/gui/integration/private/gui_image_provider_link.cpp deleted file mode 100644 index a770c0f552..0000000000 --- a/libopenage/gui/integration/private/gui_image_provider_link.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "gui_image_provider_link.h" - -#include - -#include - -#include "../../../error/error.h" - -#include "../../guisys/link/qml_engine_with_singleton_items_info.h" -#include "../../guisys/link/qtsdl_checked_static_cast.h" - -namespace openage::gui { - -GuiImageProviderLink::GuiImageProviderLink(QObject *parent) : - QObject{parent} { -} - -GuiImageProviderLink::~GuiImageProviderLink() = default; - -QObject *GuiImageProviderLink::provider(QQmlEngine *engine, const char *id) { - qtsdl::QmlEngineWithSingletonItemsInfo *engine_with_singleton_items_info = qtsdl::checked_static_cast(engine); - auto image_providers = engine_with_singleton_items_info->get_image_providers(); - - auto found_it = std::find_if(std::begin(image_providers), std::end(image_providers), [id](qtsdl::GuiImageProviderImpl *image_provider) { - return image_provider->get_id() == id; - }); - - ENSURE(found_it != std::end(image_providers), "The image provider '" << id << "' wasn't created or wasn't passed to the QML engine creation function."); - - // owned by the QML engine - return nullptr; -} - -} // namespace openage::gui diff --git a/libopenage/gui/integration/private/gui_image_provider_link.h b/libopenage/gui/integration/private/gui_image_provider_link.h deleted file mode 100644 index 5090edcf2c..0000000000 --- a/libopenage/gui/integration/private/gui_image_provider_link.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include -#include - -QT_FORWARD_DECLARE_CLASS(QQmlEngine) -QT_FORWARD_DECLARE_CLASS(QJSEngine) - -namespace openage { - -namespace gui { - -class GuiImageProviderLink : public QObject { - Q_OBJECT - -public: - explicit GuiImageProviderLink(QObject *parent); - virtual ~GuiImageProviderLink(); - - static QObject *provider(QQmlEngine *, const char *id); -}; - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/integration/private/gui_log.cpp b/libopenage/gui/integration/private/gui_log.cpp deleted file mode 100644 index 481374f9de..0000000000 --- a/libopenage/gui/integration/private/gui_log.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "../../integration/private/gui_log.h" - -#include - -#include "../../../log/log.h" -#include "log/message.h" - - -namespace openage { -namespace gui { - -void gui_log(QtMsgType type, const QMessageLogContext &context, const QString &msg) { - log::level msg_lvl; - - switch (type) { - case QtDebugMsg: - msg_lvl = log::level::dbg; - break; - case QtInfoMsg: - msg_lvl = log::level::info; - break; - case QtWarningMsg: - msg_lvl = log::level::warn; - break; - case QtCriticalMsg: - msg_lvl = log::level::err; - break; - case QtFatalMsg: - msg_lvl = log::level::crit; - break; - default: - msg_lvl = log::level::warn; - break; - } - - log::MessageBuilder builder{ - context.file != nullptr ? context.file : "", - static_cast(context.line), - context.function != nullptr ? context.function : "", - msg_lvl}; - - // TODO: maybe it's not UTF-8 - // TODO: Qt should become a LogSource - log::log(builder << msg.toUtf8().data()); - - if (type == QtFatalMsg) - abort(); -} - -} // namespace gui -} // namespace openage diff --git a/libopenage/gui/integration/private/gui_log.h b/libopenage/gui/integration/private/gui_log.h deleted file mode 100644 index 4966f5e182..0000000000 --- a/libopenage/gui/integration/private/gui_log.h +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -namespace openage { -namespace gui { - -void gui_log(QtMsgType type, const QMessageLogContext &context, const QString &msg); - -}} // namespace openage::gui diff --git a/libopenage/gui/integration/private/gui_make_standalone_subtexture.cpp b/libopenage/gui/integration/private/gui_make_standalone_subtexture.cpp deleted file mode 100644 index 854f5a65bc..0000000000 --- a/libopenage/gui/integration/private/gui_make_standalone_subtexture.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#include "gui_make_standalone_subtexture.h" -#include "gui_standalone_subtexture.h" - -namespace openage { -namespace gui { - -std::unique_ptr make_standalone_subtexture(GLuint id, const QSize &size) { - return std::make_unique(id, size); -} - -}} // namespace openage::gui diff --git a/libopenage/gui/integration/public/CMakeLists.txt b/libopenage/gui/integration/public/CMakeLists.txt deleted file mode 100644 index 4acda98465..0000000000 --- a/libopenage/gui/integration/public/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_sources(libopenage - gui_application_with_logger.cpp -) diff --git a/libopenage/gui/integration/public/gui_application_with_logger.cpp b/libopenage/gui/integration/public/gui_application_with_logger.cpp deleted file mode 100644 index 0b845f42fc..0000000000 --- a/libopenage/gui/integration/public/gui_application_with_logger.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. - -#include "gui_application_with_logger.h" - -#include "../../guisys/private/gui_application_impl.h" -#include "../private/gui_log.h" - -namespace openage::gui { - -namespace { -std::shared_ptr create() { - qInstallMessageHandler(gui_log); - return qtsdl::GuiApplicationImpl::get(); -} -} - -GuiApplicationWithLogger::GuiApplicationWithLogger() - : - GuiApplication{create()} { -} - -GuiApplicationWithLogger::~GuiApplicationWithLogger() = default; - -} // namespace openage::gui diff --git a/libopenage/gui/integration/public/gui_application_with_logger.h b/libopenage/gui/integration/public/gui_application_with_logger.h deleted file mode 100644 index 69a074a196..0000000000 --- a/libopenage/gui/integration/public/gui_application_with_logger.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. - -#pragma once - -#include "../../guisys/public/gui_application.h" - -namespace openage { -namespace gui { - -/** - * Houses gui logic event queue and attaches to game logger. - */ -class GuiApplicationWithLogger : public qtsdl::GuiApplication { -public: - GuiApplicationWithLogger(); - ~GuiApplicationWithLogger(); -}; - -}} // namespace openage::gui diff --git a/libopenage/gui/registrations.cpp b/libopenage/gui/registrations.cpp deleted file mode 100644 index d3325f9416..0000000000 --- a/libopenage/gui/registrations.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2017-2017 the openage authors. See copying.md for legal info. - -#include "registrations.h" - -#include - -namespace openage { -namespace gui { - -const int reg_path = qRegisterMetaType("util::Path"); - -}} // openage::gui diff --git a/libopenage/gui/registrations.h b/libopenage/gui/registrations.h deleted file mode 100644 index 2bc595ceb9..0000000000 --- a/libopenage/gui/registrations.h +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017-2017 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "../util/path.h" - -namespace openage { -namespace gui { - - -}} // openage::gui - -Q_DECLARE_METATYPE(openage::util::Path) diff --git a/libopenage/presenter/presenter.cpp b/libopenage/presenter/presenter.cpp index 925d2d650d..06498e51c6 100644 --- a/libopenage/presenter/presenter.cpp +++ b/libopenage/presenter/presenter.cpp @@ -18,7 +18,6 @@ #include "renderer/camera/camera.h" #include "renderer/gui/gui.h" #include "renderer/gui/integration/public/gui_application_with_logger.h" -#include "renderer/gui/qml_info.h" #include "renderer/render_factory.h" #include "renderer/resources/assets/asset_manager.h" #include "renderer/resources/shader_source.h" diff --git a/libopenage/renderer/gui/CMakeLists.txt b/libopenage/renderer/gui/CMakeLists.txt index a0a61a9b62..fdddb92d06 100644 --- a/libopenage/renderer/gui/CMakeLists.txt +++ b/libopenage/renderer/gui/CMakeLists.txt @@ -1,7 +1,5 @@ add_sources(libopenage - engine_link.cpp gui.cpp - qml_info.cpp ) add_subdirectory("guisys") diff --git a/libopenage/renderer/gui/engine_link.cpp b/libopenage/renderer/gui/engine_link.cpp deleted file mode 100644 index b4045a583c..0000000000 --- a/libopenage/renderer/gui/engine_link.cpp +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "engine_link.h" - -#include - -#include "error/error.h" - -#include "gamestate/simulation.h" - -#include "gui/guisys/link/qml_engine_with_singleton_items_info.h" -#include "gui/guisys/link/qtsdl_checked_static_cast.h" -#include "renderer/gui/qml_info.h" - -namespace openage::renderer::gui { - -namespace { -// this pushes the EngineLink in the QML engine. -// a qml engine calls the static provider() to obtain a handle. -const int registration = qmlRegisterSingletonType("yay.sfttech.openage", 1, 0, "Engine", &EngineLink::provider); -} // namespace - - -EngineLink::EngineLink(QObject *parent, gamestate::GameSimulation *engine) : - GuiSingletonItem{parent}, - core{engine} { - Q_UNUSED(registration); - - // ENSURE(!unwrap(this)->gui_link, "Sharing singletons between QML engines is not supported for now."); - - // when the engine announces that the global key bindings - // changed, update the display. - // QObject::connect( - // &unwrap(this)->gui_signals, - // &EngineSignals::global_binds_changed, - // this, - // &EngineLink::on_global_binds_changed); - - // trigger the engine signal, - // which then triggers this->on_global_binds_changed. - // unwrap(this)->announce_global_binds(); -} - -EngineLink::~EngineLink() { - // unwrap(this)->gui_link = nullptr; -} - -// a qml engine requests a handle to the engine link with that static -// method we do this by extracting the per-qmlengine singleton from the -// engine (the qmlenginewithsingletoninfo), then just return the new link -// instance -QObject *EngineLink::provider(QQmlEngine *engine, QJSEngine *) { - // cast the engine to our specialization - qtsdl::QmlEngineWithSingletonItemsInfo *engine_with_singleton_items_info = qtsdl::checked_static_cast(engine); - - // get the singleton container out of the custom qml engine - auto info = static_cast( - engine_with_singleton_items_info->get_singleton_items_info()); - ENSURE(info, "qml-globals were lost or not passed to the gui subsystem"); - - // owned by the QML engine - // this handle contains the pointer to the openage engine, - // obtained through the qmlengine - return new EngineLink{nullptr, info->engine}; -} - -QStringList EngineLink::get_global_binds() const { - return this->global_binds; -} - -void EngineLink::stop() { - this->core->stop(); -} - -void EngineLink::on_global_binds_changed(const std::vector &global_binds) { - QStringList new_global_binds; - - // create the qstring list from the std string list - // which is then displayed in the ui - std::transform( - std::begin(global_binds), - std::end(global_binds), - std::back_inserter(new_global_binds), - [](const std::string &s) { - return QString::fromStdString(s); - }); - - new_global_binds.sort(); - - if (this->global_binds != new_global_binds) { - this->global_binds = new_global_binds; - emit this->global_binds_changed(); - } -} - -} // namespace openage::renderer::gui diff --git a/libopenage/renderer/gui/engine_link.h b/libopenage/renderer/gui/engine_link.h deleted file mode 100644 index 9b0b7089cf..0000000000 --- a/libopenage/renderer/gui/engine_link.h +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include - -#include "gui/guisys/link/gui_singleton_item.h" -#include "util/path.h" - -QT_FORWARD_DECLARE_CLASS(QQmlEngine) -QT_FORWARD_DECLARE_CLASS(QJSEngine) - -namespace openage { - -namespace gamestate { -class GameSimulation; -} - -namespace renderer::gui { -class EngineLink; -} // namespace renderer::gui -} // namespace openage - -namespace qtsdl { -template <> -struct Wrap { - using Type = openage::renderer::gui::EngineLink; -}; - -template <> -struct Unwrap { - using Type = openage::gamestate::GameSimulation; -}; - -} // namespace qtsdl - -namespace openage { -namespace renderer { -namespace gui { - -class EngineLink : public qtsdl::GuiSingletonItem { - Q_OBJECT - - /** - * The text list of global key bindings. - * displayed so one can see what keys are active. - */ - Q_PROPERTY(QStringList globalBinds - READ get_global_binds - NOTIFY global_binds_changed) - -public: - explicit EngineLink(QObject *parent, gamestate::GameSimulation *engine); - virtual ~EngineLink(); - - static QObject *provider(QQmlEngine *, QJSEngine *); - - template - U *get() const { - return core; - } - - QStringList get_global_binds() const; - - Q_INVOKABLE void stop(); - -signals: - void global_binds_changed(); - -private slots: - void on_global_binds_changed(const std::vector &global_binds); - -private: - gamestate::GameSimulation *core; - - QStringList global_binds; -}; - -} // namespace gui -} // namespace renderer -} // namespace openage diff --git a/libopenage/renderer/gui/gui.cpp b/libopenage/renderer/gui/gui.cpp index c877c4a537..f51320c24c 100644 --- a/libopenage/renderer/gui/gui.cpp +++ b/libopenage/renderer/gui/gui.cpp @@ -6,7 +6,6 @@ #include "renderer/gui/guisys/public/gui_input.h" #include "renderer/gui/guisys/public/gui_renderer.h" #include "renderer/gui/integration/public/gui_application_with_logger.h" -#include "renderer/gui/qml_info.h" #include "renderer/opengl/context.h" #include "renderer/renderer.h" #include "renderer/resources/shader_source.h" @@ -24,8 +23,6 @@ GUI::GUI(std::shared_ptr app, const util::Path &assetdir, const std::shared_ptr &renderer) : application{app}, - render_updater{}, - game_logic_updater{}, gui_renderer{std::make_shared(window)}, gui_input{std::make_shared(gui_renderer)}, engine{std::make_shared(gui_renderer)}, diff --git a/libopenage/renderer/gui/gui.h b/libopenage/renderer/gui/gui.h index dc8b0fcfdc..1cecfb7bd6 100644 --- a/libopenage/renderer/gui/gui.h +++ b/libopenage/renderer/gui/gui.h @@ -6,7 +6,6 @@ #include #include -#include "gui/guisys/public/gui_event_queue.h" #include "renderer/gui/guisys/public/gui_subtree.h" namespace qtgui { @@ -30,8 +29,6 @@ class UniformInput; namespace gui { -class QMLInfo; - /** * Interface (= HUD) of the game. * @@ -99,15 +96,6 @@ class GUI { */ std::shared_ptr application; - /** - * TODO - */ - qtsdl::GuiEventQueue render_updater; - /** - * TODO - */ - qtsdl::GuiEventQueue game_logic_updater; - /** * Qt-based renderer for the GUI texture. Draws into * \p gui_texture. diff --git a/libopenage/renderer/gui/guisys/CMakeLists.txt b/libopenage/renderer/gui/guisys/CMakeLists.txt index d4f5349e29..3b454bfec5 100644 --- a/libopenage/renderer/gui/guisys/CMakeLists.txt +++ b/libopenage/renderer/gui/guisys/CMakeLists.txt @@ -1,4 +1,13 @@ +list(APPEND QT_SDL_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/link/gui_item.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/link/gui_list_model.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/link/gui_property_map_impl.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/link/gui_singleton_item.cpp +) + list(APPEND QTGUI_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/private/livereload/deferred_initial_constant_property_values.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/private/livereload/gui_live_reloader.cpp ${CMAKE_CURRENT_SOURCE_DIR}/private/livereload/recursive_directory_watcher_worker.cpp ${CMAKE_CURRENT_SOURCE_DIR}/private/livereload/recursive_directory_watcher.cpp ) diff --git a/libopenage/renderer/gui/guisys/link/gui_item.cpp b/libopenage/renderer/gui/guisys/link/gui_item.cpp new file mode 100644 index 0000000000..20bbb7c8c0 --- /dev/null +++ b/libopenage/renderer/gui/guisys/link/gui_item.cpp @@ -0,0 +1,20 @@ +// Copyright 2015-2023 the openage authors. See copying.md for legal info. + +#include "gui_item.h" + + +namespace qtgui { + + +QString name_tidier(const char *name) { + QString cleaner_name = QString::fromLatin1(name); + cleaner_name.remove(QRegularExpression("qtgui|PersistentCoreHolder")); + return cleaner_name; +} + +GuiItemQObject::GuiItemQObject(QObject *parent) : + QObject{parent}, + GuiItemBase{} { +} + +} // namespace qtgui diff --git a/libopenage/gui/guisys/link/gui_item.h b/libopenage/renderer/gui/guisys/link/gui_item.h similarity index 62% rename from libopenage/gui/guisys/link/gui_item.h rename to libopenage/renderer/gui/guisys/link/gui_item.h index 00d252dba3..450d3dc796 100644 --- a/libopenage/gui/guisys/link/gui_item.h +++ b/libopenage/renderer/gui/guisys/link/gui_item.h @@ -1,26 +1,25 @@ -// Copyright 2015-2021 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once -#include #include #include +#include #include #include #include -#include +#include #include +#include #include -#include -#include "../private/game_logic_caller.h" -#include "../private/livereload/deferred_initial_constant_property_values.h" -#include "qtsdl_checked_static_cast.h" -#include "gui_item_link.h" +#include "renderer/gui/guisys/link/gui_item_link.h" +#include "renderer/gui/guisys/link/qtsdl_checked_static_cast.h" +#include "renderer/gui/guisys/private/livereload/deferred_initial_constant_property_values.h" -namespace qtsdl { +namespace qtgui { /** * Cleans a text from unneeded content like "qtsdl". @@ -43,17 +42,15 @@ class PersistentCoreHolderBase { virtual void adopt_shell(GuiItemLink *link) = 0; }; -template +template class PersistentCoreHolder : public PersistentCoreHolderBase { public: - PersistentCoreHolder(std::unique_ptr core) - : + PersistentCoreHolder(std::unique_ptr core) : PersistentCoreHolderBase{}, core{std::move(core)} { } - explicit PersistentCoreHolder() - : + explicit PersistentCoreHolder() : PersistentCoreHolderBase{} { } @@ -74,13 +71,13 @@ class GuiItemBase : public DeferredInitialConstantPropertyValues { friend class GuiLiveReloader; friend class GuiSubtreeImpl; - template + template friend class GuiItemMethods; - template + template friend class GuiItemCoreInstantiator; - template + template friend class GuiItemListModel; /** @@ -109,26 +106,18 @@ class GuiItemBase : public DeferredInitialConstantPropertyValues { virtual void on_core_adopted() { } - /** - * Set up signal to be able to run code in the game logic thread. - */ - void set_game_logic_callback(GuiCallback *game_logic_callback) { - this->game_logic_caller.set_game_logic_callback(game_logic_callback); - } - protected: - GameLogicCaller game_logic_caller; std::function()> instantiate_core_func; - std::function do_adopt_core_func; + std::function do_adopt_core_func; std::function on_core_adopted_func; }; -template +template class GuiItemOrigin { - template + template friend class GuiItemMethods; - template + template friend class GuiItemCoreInstantiator; /** @@ -140,10 +129,9 @@ class GuiItemOrigin { /** * Member function of the GuiPersistentItem */ -template +template class GuiItemMethods { public: - #ifndef NDEBUG virtual ~GuiItemMethods() { } @@ -152,12 +140,13 @@ class GuiItemMethods { /** * Get core. */ - template - U* get() const { - if (checked_static_cast(this)->holder->core) { - assert(checked_static_cast(checked_static_cast(this)->holder->core.get())); - return checked_static_cast(checked_static_cast(this)->holder->core.get()); - } else { + template + U *get() const { + if (checked_static_cast(this)->holder->core) { + assert(checked_static_cast(checked_static_cast(this)->holder->core.get())); + return checked_static_cast(checked_static_cast(this)->holder->core.get()); + } + else { return nullptr; } } @@ -165,12 +154,13 @@ class GuiItemMethods { /** * Get core. */ - template - U* get() { - if (checked_static_cast(this)->holder->core) { - assert(checked_static_cast(checked_static_cast(this)->holder->core.get())); - return checked_static_cast(checked_static_cast(this)->holder->core.get()); - } else { + template + U *get() { + if (checked_static_cast(this)->holder->core) { + assert(checked_static_cast(checked_static_cast(this)->holder->core.get())); + return checked_static_cast(checked_static_cast(this)->holder->core.get()); + } + else { return nullptr; } } @@ -178,21 +168,16 @@ class GuiItemMethods { /** * Invoke a function in the logic thread (the thread of the core of this object). */ - template - void i(F f, Args&& ... args) { - GuiItemBase *base = checked_static_cast(checked_static_cast(this)); - - emit base->game_logic_caller.in_game_logic_thread([=, this] { - static_assert_about_unwrapping(this))), decltype(unwrap_if_can(args))...>(); - f(unwrap(checked_static_cast(this)), unwrap_if_can(args)...); - }); + template + void i(F f, Args &&...args) { + GuiItemBase *base = checked_static_cast(checked_static_cast(this)); } protected: /** * Set property. */ - template + template void s(F f, P &p, A &&arg) { if (p != arg) { p = std::forward(arg); @@ -203,7 +188,7 @@ class GuiItemMethods { /** * Set property even if it's the same. */ - template + template void sf(F f, P &p, A &&arg) { p = std::forward(arg); this->assign_while_catching_constant_properies_inits(f, p); @@ -213,38 +198,32 @@ class GuiItemMethods { /** * Static QML properties assignments during the init phase are stored for a batch assignment at the end of the init phase. */ - template + template void assign_while_catching_constant_properies_inits(F f, A &&arg) { - GuiItemBase *base = checked_static_cast(checked_static_cast(this)); + GuiItemBase *base = checked_static_cast(checked_static_cast(this)); - static_assert_about_unwrapping(this))), decltype(unwrap_if_can(arg))>(); - - if (base->init_over) - emit base->game_logic_caller.in_game_logic_thread([=, this] {f(unwrap(checked_static_cast(this)), unwrap_if_can(arg));}); - else - base->static_properties_assignments.push_back([=, this] { - emit base->game_logic_caller.in_game_logic_thread([=, this] {f(unwrap(checked_static_cast(this)), unwrap_if_can(arg));}); - }); + static_assert_about_unwrapping(this))), decltype(unwrap_if_can(arg))>(); } }; -class GuiItemQObject : public QObject, public GuiItemBase, public GuiItemLink { +class GuiItemQObject : public QObject + , public GuiItemBase + , public GuiItemLink { Q_OBJECT public: - explicit GuiItemQObject(QObject *parent=nullptr); + explicit GuiItemQObject(QObject *parent = nullptr); }; -template +template class GuiItemCoreInstantiator : public GuiItemMethods { public: /** * Sets up a factory for the type T. */ - explicit GuiItemCoreInstantiator(GuiItemBase *item_base) - : - GuiItemMethods{} { - + explicit GuiItemCoreInstantiator(GuiItemBase *item_base) : + GuiItemMethods {} + { using namespace std::placeholders; item_base->instantiate_core_func = std::bind(&GuiItemCoreInstantiator::instantiate_core, this); @@ -256,11 +235,12 @@ class GuiItemCoreInstantiator : public GuiItemMethods { * Creates and returns a core object of type Unwrap::Type inside a holder. */ std::unique_ptr instantiate_core() { - T *origin = checked_static_cast(this); + T *origin = checked_static_cast(this); if (origin->holder) { return std::unique_ptr(); - } else { + } + else { auto core = std::make_unique::Type>(origin); return std::make_uniqueholder)>::type>(std::move(core)); } @@ -272,11 +252,12 @@ class GuiItemCoreInstantiator : public GuiItemMethods { void do_adopt_core(PersistentCoreHolderBase *holder, const QString &tag) { assert(holder); - T *origin = checked_static_cast(this); + T *origin = checked_static_cast(this); if (origin->holder) { qFatal("Error in QML code: GuiLiveReloader was asked to use same tag '%s' for multiple objects.", qUtf8Printable(tag)); - } else { + } + else { if (typeid(decltype(*origin->holder)) != typeid(*holder)) { qFatal( "Error in QML code: GuiLiveReloader was asked " @@ -284,17 +265,17 @@ class GuiItemCoreInstantiator : public GuiItemMethods { "using tag '%s'.", qUtf8Printable(name_tidier(typeid(decltype(*origin->holder)).name())), qUtf8Printable(name_tidier(typeid(*holder).name())), - qUtf8Printable(tag) - ); - } else { + qUtf8Printable(tag)); + } + else { origin->holder = checked_static_castholder)>(holder); origin->holder->adopt_shell(origin); } } } - GuiItemCoreInstantiator(const GuiItemCoreInstantiator&) = delete; - GuiItemCoreInstantiator& operator=(const GuiItemCoreInstantiator&) = delete; + GuiItemCoreInstantiator(const GuiItemCoreInstantiator &) = delete; + GuiItemCoreInstantiator &operator=(const GuiItemCoreInstantiator &) = delete; }; /** @@ -308,26 +289,30 @@ class GuiItemCoreInstantiator : public GuiItemMethods { * * @tparam T type of the concrete shell class (pass the descendant class) */ -template -class GuiItem : public GuiItemOrigin, public GuiItemCoreInstantiator { +template +class GuiItem : public GuiItemOrigin + , public GuiItemCoreInstantiator { public: /** * Creates an empty QObject shell for a core that is wrappable into a type *T. */ - explicit GuiItem(GuiItemBase *item_base) - : + explicit GuiItem(GuiItemBase *item_base) : GuiItemOrigin{}, - GuiItemCoreInstantiator{item_base} { + GuiItemCoreInstantiator { + item_base + } + { } }; -template -class GuiItemInterface : public GuiItemOrigin, public GuiItemMethods { +template +class GuiItemInterface : public GuiItemOrigin + , public GuiItemMethods { public: - explicit GuiItemInterface() - : + explicit GuiItemInterface() : GuiItemOrigin{}, - GuiItemMethods{} { + GuiItemMethods {} + { } }; @@ -335,16 +320,15 @@ namespace { class NullClass { NullClass() = delete; }; -} +} // namespace /** * Shadows inherited member functions. */ -template -class Shadow: public T { +template +class Shadow : public T { public: - Shadow(QObject *parent=nullptr) - : + Shadow(QObject *parent = nullptr) : T{parent} { } @@ -357,8 +341,9 @@ class Shadow: public T { /** * Switches the factory to production of the instances of the derived class. */ -template -class Inherits: public Shadow, public GuiItemCoreInstantiator

{ +template +class Inherits : public Shadow + , public GuiItemCoreInstantiator

{ public: using Shadow::get; using GuiItemCoreInstantiator

::get; @@ -369,14 +354,16 @@ class Inherits: public Shadow, public GuiItemCoreInstantiator

{ using Shadow::sf; using GuiItemCoreInstantiator

::sf; - Inherits(QObject *parent=nullptr) - : + Inherits(QObject *parent = nullptr) : Shadow{parent}, - GuiItemCoreInstantiator

{this} { + GuiItemCoreInstantiator

{ + this + } + { } virtual ~Inherits() { } }; -} // namespace qtsdl +} // namespace qtgui diff --git a/libopenage/gui/guisys/link/gui_item_link.h b/libopenage/renderer/gui/guisys/link/gui_item_link.h similarity index 97% rename from libopenage/gui/guisys/link/gui_item_link.h rename to libopenage/renderer/gui/guisys/link/gui_item_link.h index 60cc7e5572..0bd7b8d61f 100644 --- a/libopenage/gui/guisys/link/gui_item_link.h +++ b/libopenage/renderer/gui/guisys/link/gui_item_link.h @@ -5,9 +5,10 @@ #include #include -#include "qtsdl_checked_static_cast.h" +#include "renderer/gui/guisys/link/qtsdl_checked_static_cast.h" -namespace qtsdl { + +namespace qtgui { /** * Base for QObject wrapper of the domain-specific classes. @@ -119,4 +120,4 @@ constexpr void static_assert_about_unwrapping() { static_assert(can_call{}, "One of possible causes: if you're passing SomethingLink*, then don't forget to #include \"something_link.h\"."); } -} // namespace qtsdl +} // namespace qtgui diff --git a/libopenage/gui/guisys/link/gui_item_list_model.h b/libopenage/renderer/gui/guisys/link/gui_item_list_model.h similarity index 68% rename from libopenage/gui/guisys/link/gui_item_list_model.h rename to libopenage/renderer/gui/guisys/link/gui_item_list_model.h index 38e902d4d3..7158247ccd 100644 --- a/libopenage/gui/guisys/link/gui_item_list_model.h +++ b/libopenage/renderer/gui/guisys/link/gui_item_list_model.h @@ -1,27 +1,29 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once #include -#include "gui_item.h" -#include "gui_property_map_impl.h" -#include "gui_list_model.h" +#include "renderer/gui/guisys/link/gui_item.h" +#include "renderer/gui/guisys/link/gui_list_model.h" +#include "renderer/gui/guisys/link/gui_property_map_impl.h" -namespace qtsdl { + +namespace qtgui { /** * A shell object fir cores inherited from GuiPropertyMap * * Core can use a key-value interface while in QML it looks like a ListModel. */ -template +template class GuiItemListModel : public GuiItem { public: - explicit GuiItemListModel(GuiItemBase *item_base) - : - GuiItem{item_base} { - + explicit GuiItemListModel(GuiItemBase *item_base) : + GuiItem { + item_base + } + { item_base->on_core_adopted_func = std::bind(&GuiItemListModel::on_core_adopted, this); } @@ -33,9 +35,9 @@ class GuiItemListModel : public GuiItem { } void establish_from_gui_propagation() { - auto _this = checked_static_cast(this); + auto _this = checked_static_cast(this); - QObject::connect(_this, &GuiListModel::changed_from_gui, [_this] (const QByteArray &name, const QVariant &value) { + QObject::connect(_this, &GuiListModel::changed_from_gui, [_this](const QByteArray &name, const QVariant &value) { emit _this->game_logic_caller.in_game_logic_thread_blocking([&] { unwrap(_this)->impl->setProperty(name, value); }); @@ -43,14 +45,14 @@ class GuiItemListModel : public GuiItem { } void establish_to_gui_propagation() { - auto _this = checked_static_cast(this); + auto _this = checked_static_cast(this); auto properties = unwrap(_this)->impl.get(); QObject::connect(properties, &GuiPropertyMapImpl::property_changed, _this, &GuiListModel::on_property_changed); } void do_initial_to_gui_propagation() { - auto _this = checked_static_cast(this); + auto _this = checked_static_cast(this); auto properties = unwrap(_this)->impl.get(); auto property_names = properties->dynamicPropertyNames(); @@ -58,7 +60,7 @@ class GuiItemListModel : public GuiItem { std::vector> values; values.reserve(property_names.size()); - std::transform(std::begin(property_names), std::end(property_names), std::back_inserter(values), [properties] (const QByteArray &name) { + std::transform(std::begin(property_names), std::end(property_names), std::back_inserter(values), [properties](const QByteArray &name) { return std::make_tuple(name, properties->property(name)); }); @@ -66,4 +68,4 @@ class GuiItemListModel : public GuiItem { } }; -} // namespace qtsdl +} // namespace qtgui diff --git a/libopenage/gui/guisys/link/gui_list_model.cpp b/libopenage/renderer/gui/guisys/link/gui_list_model.cpp similarity index 85% rename from libopenage/gui/guisys/link/gui_list_model.cpp rename to libopenage/renderer/gui/guisys/link/gui_list_model.cpp index 72bbf20663..467468020b 100644 --- a/libopenage/gui/guisys/link/gui_list_model.cpp +++ b/libopenage/renderer/gui/guisys/link/gui_list_model.cpp @@ -1,13 +1,13 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include "gui_list_model.h" #include -namespace qtsdl { -GuiListModel::GuiListModel(QObject *parent) - : +namespace qtgui { + +GuiListModel::GuiListModel(QObject *parent) : QAbstractListModel{parent} { } @@ -20,7 +20,7 @@ void GuiListModel::set(const std::vector> &valu } void GuiListModel::on_property_changed(const QByteArray &name, const QVariant &value) { - auto foundIt = std::find_if(std::begin(this->values), std::end(this->values), [&name] (std::tuple& p) { + auto foundIt = std::find_if(std::begin(this->values), std::end(this->values), [&name](std::tuple &p) { return std::get(p) == name; }); @@ -33,14 +33,15 @@ void GuiListModel::on_property_changed(const QByteArray &name, const QVariant &v auto i = this->index(std::distance(std::begin(this->values), foundIt)); emit this->dataChanged(i, i, {Qt::EditRole}); } - } else { + } + else { this->beginInsertRows(QModelIndex(), this->values.size(), this->values.size()); this->values.emplace(std::end(this->values), name, value); this->endInsertRows(); } } -int GuiListModel::rowCount(const QModelIndex&) const { +int GuiListModel::rowCount(const QModelIndex &) const { return values.size(); } @@ -71,4 +72,4 @@ bool GuiListModel::setData(const QModelIndex &index, const QVariant &value, int return false; } -} // namespace qtsdl +} // namespace qtgui diff --git a/libopenage/gui/guisys/link/gui_list_model.h b/libopenage/renderer/gui/guisys/link/gui_list_model.h similarity index 58% rename from libopenage/gui/guisys/link/gui_list_model.h rename to libopenage/renderer/gui/guisys/link/gui_list_model.h index 6f93ce48b2..3a3b85c52e 100644 --- a/libopenage/gui/guisys/link/gui_list_model.h +++ b/libopenage/renderer/gui/guisys/link/gui_list_model.h @@ -1,24 +1,27 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once -#include #include +#include #include -#include "gui_item.h" +#include "renderer/gui/guisys/link/gui_item.h" + -namespace qtsdl { +namespace qtgui { /** * Adapts core that uses a property map to QAbstractListModel interface. */ -class GuiListModel : public QAbstractListModel, public GuiItemBase, public GuiItemLink { +class GuiListModel : public QAbstractListModel + , public GuiItemBase + , public GuiItemLink { Q_OBJECT public: - GuiListModel(QObject *parent=nullptr); + GuiListModel(QObject *parent = nullptr); virtual ~GuiListModel(); void set(const std::vector> &values); @@ -30,12 +33,12 @@ public slots: void changed_from_gui(const char *name, const QVariant &value); private: - virtual int rowCount(const QModelIndex&) const override; + virtual int rowCount(const QModelIndex &) const override; virtual Qt::ItemFlags flags(const QModelIndex &index) const override; - virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override; - virtual bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole) override; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; std::vector> values; }; -} // namespace qtsdl +} // namespace qtgui diff --git a/libopenage/gui/guisys/link/gui_property_map_impl.cpp b/libopenage/renderer/gui/guisys/link/gui_property_map_impl.cpp similarity index 66% rename from libopenage/gui/guisys/link/gui_property_map_impl.cpp rename to libopenage/renderer/gui/guisys/link/gui_property_map_impl.cpp index 885589c38b..1a8e8b7db3 100644 --- a/libopenage/gui/guisys/link/gui_property_map_impl.cpp +++ b/libopenage/renderer/gui/guisys/link/gui_property_map_impl.cpp @@ -1,16 +1,16 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include "gui_property_map_impl.h" #include #include -#include "qtsdl_checked_static_cast.h" +#include "renderer/gui/guisys/link/qtsdl_checked_static_cast.h" -namespace qtsdl { -GuiPropertyMapImpl::GuiPropertyMapImpl() - : +namespace qtgui { + +GuiPropertyMapImpl::GuiPropertyMapImpl() : QObject{} { } @@ -18,7 +18,7 @@ GuiPropertyMapImpl::~GuiPropertyMapImpl() = default; bool GuiPropertyMapImpl::event(QEvent *e) { if (e->type() == QEvent::DynamicPropertyChange) { - auto property_name = checked_static_cast(e)->propertyName(); + auto property_name = checked_static_cast(e)->propertyName(); emit this->property_changed(property_name, this->property(property_name)); return true; } @@ -26,4 +26,4 @@ bool GuiPropertyMapImpl::event(QEvent *e) { return this->QObject::event(e); } -} // namespace qtsdl +} // namespace qtgui diff --git a/libopenage/gui/guisys/link/gui_property_map_impl.h b/libopenage/renderer/gui/guisys/link/gui_property_map_impl.h similarity index 74% rename from libopenage/gui/guisys/link/gui_property_map_impl.h rename to libopenage/renderer/gui/guisys/link/gui_property_map_impl.h index a7054345be..d0118f4c58 100644 --- a/libopenage/gui/guisys/link/gui_property_map_impl.h +++ b/libopenage/renderer/gui/guisys/link/gui_property_map_impl.h @@ -1,10 +1,11 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once #include -namespace qtsdl { + +namespace qtgui { class GuiPropertyMapImpl : public QObject { Q_OBJECT @@ -20,4 +21,4 @@ class GuiPropertyMapImpl : public QObject { virtual bool event(QEvent *e) override; }; -} // namespace qtsdl +} // namespace qtgui diff --git a/libopenage/renderer/gui/guisys/link/gui_singleton_item.cpp b/libopenage/renderer/gui/guisys/link/gui_singleton_item.cpp new file mode 100644 index 0000000000..dc01d27e4e --- /dev/null +++ b/libopenage/renderer/gui/guisys/link/gui_singleton_item.cpp @@ -0,0 +1,15 @@ +// Copyright 2015-2023 the openage authors. See copying.md for legal info. + +#include "gui_singleton_item.h" + + +namespace qtgui { + +GuiSingletonItem::GuiSingletonItem(QObject *parent) : + QObject{parent}, + GuiItemLink{} { +} + +GuiSingletonItem::~GuiSingletonItem() = default; + +} // namespace qtgui diff --git a/libopenage/renderer/gui/guisys/link/gui_singleton_item.h b/libopenage/renderer/gui/guisys/link/gui_singleton_item.h new file mode 100644 index 0000000000..8024ecf032 --- /dev/null +++ b/libopenage/renderer/gui/guisys/link/gui_singleton_item.h @@ -0,0 +1,21 @@ +// Copyright 2015-2023 the openage authors. See copying.md for legal info. + +#pragma once + +#include + +#include "renderer/gui/guisys/link/gui_item_link.h" + + +namespace qtgui { + +class GuiSingletonItem : public QObject + , public GuiItemLink { + Q_OBJECT + +public: + explicit GuiSingletonItem(QObject *parent = nullptr); + virtual ~GuiSingletonItem(); +}; + +} // namespace qtgui diff --git a/libopenage/renderer/gui/guisys/link/qtsdl_checked_static_cast.h b/libopenage/renderer/gui/guisys/link/qtsdl_checked_static_cast.h new file mode 100644 index 0000000000..7b51a89e03 --- /dev/null +++ b/libopenage/renderer/gui/guisys/link/qtsdl_checked_static_cast.h @@ -0,0 +1,16 @@ +// Copyright 2015-2023 the openage authors. See copying.md for legal info. + +#pragma once + +#include + + +namespace qtgui { + +template +T checked_static_cast(U *u) { + assert(dynamic_cast(u)); + return static_cast(u); +} + +} // namespace qtgui diff --git a/libopenage/renderer/gui/guisys/private/gui_ctx_setup.cpp b/libopenage/renderer/gui/guisys/private/gui_ctx_setup.cpp index d5c32b56e4..49b05af242 100644 --- a/libopenage/renderer/gui/guisys/private/gui_ctx_setup.cpp +++ b/libopenage/renderer/gui/guisys/private/gui_ctx_setup.cpp @@ -4,10 +4,11 @@ #include +#include #include #include +#include -#include "gui/guisys/private/platforms/context_extraction.h" #include "renderer/gui/guisys/private/opengl_debug_logger.h" #include "renderer/opengl/context.h" #include "renderer/opengl/window.h" diff --git a/libopenage/gui/guisys/private/livereload/deferred_initial_constant_property_values.cpp b/libopenage/renderer/gui/guisys/private/livereload/deferred_initial_constant_property_values.cpp similarity index 84% rename from libopenage/gui/guisys/private/livereload/deferred_initial_constant_property_values.cpp rename to libopenage/renderer/gui/guisys/private/livereload/deferred_initial_constant_property_values.cpp index 932ca20791..f17f7f2a0e 100644 --- a/libopenage/gui/guisys/private/livereload/deferred_initial_constant_property_values.cpp +++ b/libopenage/renderer/gui/guisys/private/livereload/deferred_initial_constant_property_values.cpp @@ -1,11 +1,10 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include "deferred_initial_constant_property_values.h" -namespace qtsdl { +namespace qtgui { -DeferredInitialConstantPropertyValues::DeferredInitialConstantPropertyValues() - : +DeferredInitialConstantPropertyValues::DeferredInitialConstantPropertyValues() : init_over{} { } @@ -27,4 +26,4 @@ bool DeferredInitialConstantPropertyValues::is_init_over() const { return this->init_over; } -} // namespace qtsdl +} // namespace qtgui diff --git a/libopenage/gui/guisys/private/livereload/deferred_initial_constant_property_values.h b/libopenage/renderer/gui/guisys/private/livereload/deferred_initial_constant_property_values.h similarity index 88% rename from libopenage/gui/guisys/private/livereload/deferred_initial_constant_property_values.h rename to libopenage/renderer/gui/guisys/private/livereload/deferred_initial_constant_property_values.h index 699c9ed64c..1add8b41e1 100644 --- a/libopenage/gui/guisys/private/livereload/deferred_initial_constant_property_values.h +++ b/libopenage/renderer/gui/guisys/private/livereload/deferred_initial_constant_property_values.h @@ -1,11 +1,11 @@ -// Copyright 2015-2016 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once -#include #include +#include -namespace qtsdl { +namespace qtgui { /** * Stores static properties during initialization to be able to assign them after all 'liveReloadTag' properties are set. @@ -36,4 +36,4 @@ class DeferredInitialConstantPropertyValues { std::vector> static_properties_assignments; }; -} // namespace qtsdl +} // namespace qtgui diff --git a/libopenage/gui/guisys/private/livereload/gui_live_reloader.cpp b/libopenage/renderer/gui/guisys/private/livereload/gui_live_reloader.cpp similarity index 98% rename from libopenage/gui/guisys/private/livereload/gui_live_reloader.cpp rename to libopenage/renderer/gui/guisys/private/livereload/gui_live_reloader.cpp index 474de95dc9..142ec7892e 100644 --- a/libopenage/gui/guisys/private/livereload/gui_live_reloader.cpp +++ b/libopenage/renderer/gui/guisys/private/livereload/gui_live_reloader.cpp @@ -8,7 +8,7 @@ #include "../../link/gui_item.h" #include "deferred_initial_constant_property_values.h" -namespace qtsdl { +namespace qtgui { namespace { const int registration = qmlRegisterUncreatableType("yay.sfttech.livereload", 1, 0, "LR", "LR is non-instantiable. It provides the 'LR.tag' attached property."); @@ -88,4 +88,4 @@ void GuiLiveReloader::init_persistent_items(const QList -#include #include +#include +#include -#include #include #include +#include #include #include // since qt 5.14, the std::hash of q* types are included in qt #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0) namespace std { -template<> +template <> struct hash { - size_t operator()(const QString& val) const noexcept { + size_t operator()(const QString &val) const noexcept { return qHash(val); } }; -} +} // namespace std #endif -namespace qtsdl { +namespace qtgui { class GuiItemBase; @@ -39,7 +39,7 @@ class GuiLiveReloaderAttachedProperty : public QObject { public: explicit GuiLiveReloaderAttachedProperty(QObject *object); - GuiItemBase* get_attachee() const; + GuiItemBase *get_attachee() const; QString get_tag() const; void set_tag(const QString &tag); @@ -60,7 +60,7 @@ class GuiLiveReloaderAttachedPropertyProvider : public QObject { Q_OBJECT public: - static GuiLiveReloaderAttachedProperty* qmlAttachedProperties(QObject*); + static GuiLiveReloaderAttachedProperty *qmlAttachedProperties(QObject *); }; class PersistentCoreHolderBase; @@ -69,15 +69,14 @@ class PersistentCoreHolderBase; * Stores objects that need to be kept alive across GUI reloads. */ class GuiLiveReloader { - public: - void init_persistent_items(const QList &items); + void init_persistent_items(const QList &items); private: using TagToPreservableMap = std::unordered_map>; TagToPreservableMap preservable; }; -} // namespace qtsdl +} // namespace qtgui -QML_DECLARE_TYPEINFO(qtsdl::GuiLiveReloaderAttachedPropertyProvider, QML_HAS_ATTACHED_PROPERTIES) +QML_DECLARE_TYPEINFO(qtgui::GuiLiveReloaderAttachedPropertyProvider, QML_HAS_ATTACHED_PROPERTIES) diff --git a/libopenage/renderer/gui/integration/private/CMakeLists.txt b/libopenage/renderer/gui/integration/private/CMakeLists.txt index 1ef1a3946a..3457b62e3a 100644 --- a/libopenage/renderer/gui/integration/private/CMakeLists.txt +++ b/libopenage/renderer/gui/integration/private/CMakeLists.txt @@ -1,3 +1,8 @@ add_sources(libopenage - gui_log.cpp + gui_filled_texture_handles.cpp + gui_log.cpp + gui_make_standalone_subtexture.cpp + gui_standalone_subtexture.cpp + gui_texture.cpp + gui_texture_handle.cpp ) diff --git a/libopenage/gui/integration/private/gui_filled_texture_handles.cpp b/libopenage/renderer/gui/integration/private/gui_filled_texture_handles.cpp similarity index 70% rename from libopenage/gui/integration/private/gui_filled_texture_handles.cpp rename to libopenage/renderer/gui/integration/private/gui_filled_texture_handles.cpp index 20df907316..db664516b4 100644 --- a/libopenage/gui/integration/private/gui_filled_texture_handles.cpp +++ b/libopenage/renderer/gui/integration/private/gui_filled_texture_handles.cpp @@ -1,12 +1,13 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include "gui_filled_texture_handles.h" #include -#include "gui_texture_handle.h" +#include "renderer/gui/integration/private/gui_texture_handle.h" -namespace openage::gui { + +namespace openage::renderer::gui { GuiFilledTextureHandles::GuiFilledTextureHandles() = default; @@ -19,39 +20,38 @@ void GuiFilledTextureHandles::add_texture_handle(const QString &id, const QSize void GuiFilledTextureHandles::free_texture_handle(SizedTextureHandle *filled_handle) { std::unique_lock lck{this->handles_mutex}; - this->handles.erase(std::remove_if(std::begin(this->handles), std::end(this->handles), [filled_handle] (const std::tuple& handle) { - return std::get(handle) == filled_handle; - }), std::end(this->handles)); + this->handles.erase(std::remove_if(std::begin(this->handles), std::end(this->handles), [filled_handle](const std::tuple &handle) { + return std::get(handle) == filled_handle; + }), + std::end(this->handles)); } void GuiFilledTextureHandles::fill_all_handles_with_texture(const TextureHandle &texture) { std::unique_lock lck{this->handles_mutex}; - std::for_each(std::begin(this->handles), std::end(this->handles), [&texture] (std::tuple& handle) { - auto filled_handle = std::get(handle); + std::for_each(std::begin(this->handles), std::end(this->handles), [&texture](std::tuple &handle) { + auto filled_handle = std::get(handle); *filled_handle = {texture, textureSize(*filled_handle)}; }); } -void GuiFilledTextureHandles::refresh_all_handles_with_texture(const std::function& refresher) { +void GuiFilledTextureHandles::refresh_all_handles_with_texture(const std::function &refresher) { std::unique_lock lck{this->handles_mutex}; std::vector refreshed_handles(this->handles.size()); - std::transform(std::begin(this->handles), std::end(this->handles), std::begin(refreshed_handles), [refresher] (const std::tuple& handle) { + std::transform(std::begin(this->handles), std::end(this->handles), std::begin(refreshed_handles), [refresher](const std::tuple &handle) { SizedTextureHandle refreshed_handles; refresher(std::get(handle), std::get(handle), &refreshed_handles); return refreshed_handles; }); for (std::size_t i = 0, e = refreshed_handles.size(); i != e; ++i) - *std::get(this->handles[i]) = refreshed_handles[i]; + *std::get(this->handles[i]) = refreshed_handles[i]; } -GuiFilledTextureHandleUser::GuiFilledTextureHandleUser(std::shared_ptr texture_handles, const QString &id, const QSize &requested_size, SizedTextureHandle *filled_handle) - : +GuiFilledTextureHandleUser::GuiFilledTextureHandleUser(std::shared_ptr texture_handles, const QString &id, const QSize &requested_size, SizedTextureHandle *filled_handle) : texture_handles{std::move(texture_handles)}, filled_handle{filled_handle} { - this->texture_handles->add_texture_handle(id, requested_size, filled_handle); } @@ -60,4 +60,4 @@ GuiFilledTextureHandleUser::~GuiFilledTextureHandleUser() { texture_handles->free_texture_handle(filled_handle); } -} // namespace openage::gui +} // namespace openage::renderer::gui diff --git a/libopenage/gui/integration/private/gui_filled_texture_handles.h b/libopenage/renderer/gui/integration/private/gui_filled_texture_handles.h similarity index 74% rename from libopenage/gui/integration/private/gui_filled_texture_handles.h rename to libopenage/renderer/gui/integration/private/gui_filled_texture_handles.h index 8d88a7d688..afca15e1c2 100644 --- a/libopenage/gui/integration/private/gui_filled_texture_handles.h +++ b/libopenage/renderer/gui/integration/private/gui_filled_texture_handles.h @@ -1,17 +1,16 @@ -// Copyright 2015-2019 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once -#include -#include -#include #include +#include +#include +#include -#include #include +#include -namespace openage { -namespace gui { +namespace openage::renderer::gui { class TextureHandle; class SizedTextureHandle; @@ -31,7 +30,7 @@ class GuiFilledTextureHandles { void free_texture_handle(SizedTextureHandle *filled_handle); void fill_all_handles_with_texture(const TextureHandle &texture); - void refresh_all_handles_with_texture(const std::function& refresher); + void refresh_all_handles_with_texture(const std::function &refresher); private: /** @@ -40,7 +39,7 @@ class GuiFilledTextureHandles { * It's not a proper Qt usage, so the live reload of the game assets for the gui may break in future Qt releases. * When it breaks, this feature should be implemented via the recreation of the qml engine. */ - std::vector> handles; + std::vector> handles; std::mutex handles_mutex; }; @@ -49,14 +48,14 @@ class GuiFilledTextureHandleUser { GuiFilledTextureHandleUser(std::shared_ptr texture_handles, const QString &id, const QSize &requested_size, SizedTextureHandle *filled_handle); ~GuiFilledTextureHandleUser(); - GuiFilledTextureHandleUser(GuiFilledTextureHandleUser&&) noexcept = default; + GuiFilledTextureHandleUser(GuiFilledTextureHandleUser &&) noexcept = default; private: - GuiFilledTextureHandleUser(const GuiFilledTextureHandleUser&) = delete; - GuiFilledTextureHandleUser& operator=(const GuiFilledTextureHandleUser&) = delete; + GuiFilledTextureHandleUser(const GuiFilledTextureHandleUser &) = delete; + GuiFilledTextureHandleUser &operator=(const GuiFilledTextureHandleUser &) = delete; std::shared_ptr texture_handles; SizedTextureHandle *filled_handle; }; -}} // namespace openage::gui +} // namespace openage::renderer::gui diff --git a/libopenage/renderer/gui/integration/private/gui_make_standalone_subtexture.cpp b/libopenage/renderer/gui/integration/private/gui_make_standalone_subtexture.cpp new file mode 100644 index 0000000000..5151a3934a --- /dev/null +++ b/libopenage/renderer/gui/integration/private/gui_make_standalone_subtexture.cpp @@ -0,0 +1,14 @@ +// Copyright 2015-2023 the openage authors. See copying.md for legal info. + +#include "gui_make_standalone_subtexture.h" + +#include "renderer/gui/integration/private/gui_standalone_subtexture.h" + + +namespace openage::renderer::gui { + +std::unique_ptr make_standalone_subtexture(GLuint id, const QSize &size) { + return std::make_unique(id, size); +} + +} // namespace openage::renderer::gui diff --git a/libopenage/gui/integration/private/gui_make_standalone_subtexture.h b/libopenage/renderer/gui/integration/private/gui_make_standalone_subtexture.h similarity index 87% rename from libopenage/gui/integration/private/gui_make_standalone_subtexture.h rename to libopenage/renderer/gui/integration/private/gui_make_standalone_subtexture.h index e971f478c1..1a74659582 100644 --- a/libopenage/gui/integration/private/gui_make_standalone_subtexture.h +++ b/libopenage/renderer/gui/integration/private/gui_make_standalone_subtexture.h @@ -8,8 +8,7 @@ #include -namespace openage { -namespace gui { +namespace openage::renderer::gui { /* * Reason for this is to resolve epoxy header clash that occur @@ -20,5 +19,4 @@ namespace gui { */ std::unique_ptr make_standalone_subtexture(GLuint id, const QSize &size); -} // namespace gui -} // namespace openage +} // namespace openage::renderer::gui diff --git a/libopenage/gui/integration/private/gui_standalone_subtexture.cpp b/libopenage/renderer/gui/integration/private/gui_standalone_subtexture.cpp similarity index 91% rename from libopenage/gui/integration/private/gui_standalone_subtexture.cpp rename to libopenage/renderer/gui/integration/private/gui_standalone_subtexture.cpp index 3f55d77bc3..63ca492169 100644 --- a/libopenage/gui/integration/private/gui_standalone_subtexture.cpp +++ b/libopenage/renderer/gui/integration/private/gui_standalone_subtexture.cpp @@ -2,8 +2,7 @@ #include "gui_standalone_subtexture.h" -namespace openage { -namespace gui { +namespace openage::renderer::gui { GuiStandaloneSubtexture::GuiStandaloneSubtexture(GLuint id, const QSize &size) : id(id), @@ -43,5 +42,4 @@ QSize GuiStandaloneSubtexture::textureSize() const { return this->size; } -} // namespace gui -} // namespace openage +} // namespace openage::renderer::gui diff --git a/libopenage/gui/integration/private/gui_standalone_subtexture.h b/libopenage/renderer/gui/integration/private/gui_standalone_subtexture.h similarity index 89% rename from libopenage/gui/integration/private/gui_standalone_subtexture.h rename to libopenage/renderer/gui/integration/private/gui_standalone_subtexture.h index 3512d2d066..462e82f370 100644 --- a/libopenage/gui/integration/private/gui_standalone_subtexture.h +++ b/libopenage/renderer/gui/integration/private/gui_standalone_subtexture.h @@ -5,8 +5,7 @@ #include #include -namespace openage { -namespace gui { +namespace openage::renderer::gui { class GuiStandaloneSubtexture : public QSGTexture { Q_OBJECT @@ -30,5 +29,4 @@ class GuiStandaloneSubtexture : public QSGTexture { const QSize size; }; -} // namespace gui -} // namespace openage +} // namespace openage::renderer::gui diff --git a/libopenage/gui/integration/private/gui_texture.cpp b/libopenage/renderer/gui/integration/private/gui_texture.cpp similarity index 84% rename from libopenage/gui/integration/private/gui_texture.cpp rename to libopenage/renderer/gui/integration/private/gui_texture.cpp index 8c6de0746a..c61b1ffe1b 100644 --- a/libopenage/gui/integration/private/gui_texture.cpp +++ b/libopenage/renderer/gui/integration/private/gui_texture.cpp @@ -4,10 +4,11 @@ #include -#include "gui_make_standalone_subtexture.h" -#include "gui_texture.h" +#include "renderer/gui/integration/private/gui_make_standalone_subtexture.h" +#include "renderer/gui/integration/private/gui_texture.h" -namespace openage::gui { + +namespace openage::renderer::gui { GuiTexture::GuiTexture(const SizedTextureHandle &texture_handle) : QSGTexture{}, @@ -35,7 +36,7 @@ bool GuiTexture::hasMipmaps() const { } bool GuiTexture::isAtlasTexture() const { - return openage::gui::isAtlasTexture(this->texture_handle); + return openage::renderer::gui::isAtlasTexture(this->texture_handle); } namespace { @@ -82,7 +83,7 @@ int GuiTexture::textureId() const { } QSize GuiTexture::textureSize() const { - return openage::gui::textureSize(this->texture_handle); + return openage::renderer::gui::textureSize(this->texture_handle); } -} // namespace openage::gui +} // namespace openage::renderer::gui diff --git a/libopenage/gui/integration/private/gui_texture.h b/libopenage/renderer/gui/integration/private/gui_texture.h similarity index 91% rename from libopenage/gui/integration/private/gui_texture.h rename to libopenage/renderer/gui/integration/private/gui_texture.h index aa84a0c10e..1972822763 100644 --- a/libopenage/gui/integration/private/gui_texture.h +++ b/libopenage/renderer/gui/integration/private/gui_texture.h @@ -8,8 +8,7 @@ #include "gui_texture_handle.h" -namespace openage { -namespace gui { +namespace openage::renderer::gui { class GuiTexture : public QSGTexture { Q_OBJECT @@ -35,5 +34,4 @@ class GuiTexture : public QSGTexture { mutable std::unique_ptr standalone; }; -} // namespace gui -} // namespace openage +} // namespace openage::renderer::gui diff --git a/libopenage/gui/integration/private/gui_texture_handle.cpp b/libopenage/renderer/gui/integration/private/gui_texture_handle.cpp similarity index 94% rename from libopenage/gui/integration/private/gui_texture_handle.cpp rename to libopenage/renderer/gui/integration/private/gui_texture_handle.cpp index efe9da7fb8..07a840dbf1 100644 --- a/libopenage/gui/integration/private/gui_texture_handle.cpp +++ b/libopenage/renderer/gui/integration/private/gui_texture_handle.cpp @@ -5,8 +5,7 @@ #include -namespace openage { -namespace gui { +namespace openage::renderer::gui { SizedTextureHandle::SizedTextureHandle() : TextureHandle{0}, @@ -44,5 +43,4 @@ QSize aspect_fit_size(const TextureHandle &texture_handle, const QSize &requeste } } -} // namespace gui -} // namespace openage +} // namespace openage::renderer::gui diff --git a/libopenage/gui/integration/private/gui_texture_handle.h b/libopenage/renderer/gui/integration/private/gui_texture_handle.h similarity index 92% rename from libopenage/gui/integration/private/gui_texture_handle.h rename to libopenage/renderer/gui/integration/private/gui_texture_handle.h index 5d943a1358..f9cdf59686 100644 --- a/libopenage/gui/integration/private/gui_texture_handle.h +++ b/libopenage/renderer/gui/integration/private/gui_texture_handle.h @@ -4,9 +4,7 @@ #include -namespace openage { - -namespace gui { +namespace openage::renderer::gui { class TextureHandle { public: @@ -33,5 +31,4 @@ QSize native_size(const TextureHandle &texture_handle); */ QSize aspect_fit_size(const TextureHandle &texture_handle, const QSize &requested_size); -} // namespace gui -} // namespace openage +} // namespace openage::renderer::gui diff --git a/libopenage/renderer/gui/qml_info.cpp b/libopenage/renderer/gui/qml_info.cpp deleted file mode 100644 index 16e03f333b..0000000000 --- a/libopenage/renderer/gui/qml_info.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2017-2023 the openage authors. See copying.md for legal info. - -#include "qml_info.h" - -namespace openage { -namespace renderer { -namespace gui { - -QMLInfo::QMLInfo(gamestate::GameSimulation *engine, const util::Path &asset_dir) : - engine{engine}, - asset_dir{asset_dir} {} - -} // namespace gui -} // namespace renderer -} // namespace openage diff --git a/libopenage/renderer/gui/qml_info.h b/libopenage/renderer/gui/qml_info.h deleted file mode 100644 index a5a668a086..0000000000 --- a/libopenage/renderer/gui/qml_info.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2017-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include "gui/guisys/public/gui_singleton_items_info.h" -#include "util/path.h" - -namespace openage { - -namespace gamestate { -class GameSimulation; -} - -namespace presenter { -class Presenter; -} - -namespace renderer { -namespace gui { - -class QMLInfo : public qtsdl::GuiSingletonItemsInfo { -public: - QMLInfo(gamestate::GameSimulation *engine, const util::Path &asset_dir); - - /** - * The openage engine, so it can be "used" in QML as a "QML Singleton". - * With this pointer, all of QML can find back to the engine. - */ - gamestate::GameSimulation *engine; - - /** - * The openage display. - */ - presenter::Presenter *display; - - /** - * Search path for finding assets n stuff. - */ - util::Path asset_dir; -}; - - -} // namespace gui -} // namespace renderer -} // namespace openage diff --git a/libopenage/renderer/opengl/window.cpp b/libopenage/renderer/opengl/window.cpp index daedbf7537..68ac012ed1 100644 --- a/libopenage/renderer/opengl/window.cpp +++ b/libopenage/renderer/opengl/window.cpp @@ -2,18 +2,18 @@ #include "window.h" +#include +#include +#include +#include + #include "error/error.h" -#include "gui/guisys/public/gui_application.h" #include "log/log.h" + #include "renderer/opengl/context.h" #include "renderer/opengl/renderer.h" #include "renderer/window_event_handler.h" -#include -#include -#include -#include - namespace openage::renderer::opengl { From eaeb1f89b6edccc2e9a0a59ac20e0aa4bebeb358 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 5 Nov 2023 02:21:11 +0100 Subject: [PATCH 56/95] renderer: Organize terrain into chunks. --- .../renderer/stages/terrain/CMakeLists.txt | 1 + .../renderer/stages/terrain/terrain_chunk.cpp | 122 ++++++++++++++++++ .../renderer/stages/terrain/terrain_chunk.h | 106 +++++++++++++++ .../renderer/stages/terrain/terrain_model.cpp | 111 +++------------- .../renderer/stages/terrain/terrain_model.h | 29 ++--- .../stages/terrain/terrain_renderer.cpp | 43 +++--- 6 files changed, 277 insertions(+), 135 deletions(-) create mode 100644 libopenage/renderer/stages/terrain/terrain_chunk.cpp create mode 100644 libopenage/renderer/stages/terrain/terrain_chunk.h diff --git a/libopenage/renderer/stages/terrain/CMakeLists.txt b/libopenage/renderer/stages/terrain/CMakeLists.txt index 6da55d3490..f3d10e1354 100644 --- a/libopenage/renderer/stages/terrain/CMakeLists.txt +++ b/libopenage/renderer/stages/terrain/CMakeLists.txt @@ -1,4 +1,5 @@ add_sources(libopenage + terrain_chunk.cpp terrain_mesh.cpp terrain_model.cpp terrain_render_entity.cpp diff --git a/libopenage/renderer/stages/terrain/terrain_chunk.cpp b/libopenage/renderer/stages/terrain/terrain_chunk.cpp new file mode 100644 index 0000000000..73109cd2c4 --- /dev/null +++ b/libopenage/renderer/stages/terrain/terrain_chunk.cpp @@ -0,0 +1,122 @@ +// Copyright 2023-2023 the openage authors. See copying.md for legal info. + +#include "terrain_chunk.h" + +#include "renderer/resources/assets/asset_manager.h" +#include "renderer/resources/mesh_data.h" +#include "renderer/stages/terrain/terrain_mesh.h" +#include "renderer/stages/terrain/terrain_render_entity.h" + + +namespace openage::renderer::terrain { + +TerrainChunk::TerrainChunk(const std::shared_ptr &asset_manager, + const util::Vector2s size, + const util::Vector2s offset) : + size{size}, + offset{offset}, + asset_manager{asset_manager} {} + +void TerrainChunk::set_render_entity(const std::shared_ptr &entity) { + this->render_entity = entity; +} + +void TerrainChunk::fetch_updates(const time::time_t &time) { + // TODO: Don't create model if render entity is not set + if (not this->render_entity) { + return; + } + + // Check render entity for updates + if (not this->render_entity->is_changed()) { + return; + } + // TODO: Change mesh instead of recreating it + // TODO: Multiple meshes + auto new_mesh = this->create_mesh(); + this->meshes.clear(); + this->meshes.push_back(new_mesh); + + // Indicate to the render entity that its updates have been processed. + this->render_entity->clear_changed_flag(); +} + +void TerrainChunk::update_uniforms(const time::time_t &time) { + for (auto &mesh : this->meshes) { + mesh->update_uniforms(time); + } +} + +const std::vector> &TerrainChunk::get_meshes() const { + return this->meshes; +} + +std::shared_ptr TerrainChunk::create_mesh() { + // Update mesh + auto size = this->render_entity->get_size(); + auto src_verts = this->render_entity->get_vertices(); + + // dst_verts places vertices in order + // (left to right, bottom to top) + std::vector dst_verts{}; + dst_verts.reserve(src_verts.size() * 5); + for (auto v : src_verts) { + // Transform to scene coords + auto v_vec = v.to_world_space(); + dst_verts.push_back(v_vec[0]); + dst_verts.push_back(v_vec[1]); + dst_verts.push_back(v_vec[2]); + // TODO: Texture scaling + dst_verts.push_back((v.ne / 10).to_float()); + dst_verts.push_back((v.se / 10).to_float()); + } + + // split the grid into triangles using an index array + std::vector idxs; + idxs.reserve((size[0] - 1) * (size[1] - 1) * 6); + // iterate over all tiles in the grid by columns, i.e. starting + // from the left corner to the bottom corner if you imagine it from + // the camera's point of view + for (size_t i = 0; i < size[0] - 1; ++i) { + for (size_t j = 0; j < size[1] - 1; ++j) { + // since we are working on tiles, we split each tile into two triangles + // with counter-clockwise vertex order + idxs.push_back(j + i * size[1]); // bottom left + idxs.push_back(j + 1 + i * size[1]); // bottom right + idxs.push_back(j + size[1] + i * size[1]); // top left + idxs.push_back(j + 1 + i * size[1]); // bottom right + idxs.push_back(j + size[1] + 1 + i * size[1]); // top right + idxs.push_back(j + size[1] + i * size[1]); // top left + } + } + + resources::VertexInputInfo info{ + {resources::vertex_input_t::V3F32, resources::vertex_input_t::V2F32}, + resources::vertex_layout_t::AOS, + resources::vertex_primitive_t::TRIANGLES, + resources::index_t::U16}; + + auto const vert_data_size = dst_verts.size() * sizeof(float); + std::vector vert_data(vert_data_size); + std::memcpy(vert_data.data(), reinterpret_cast(dst_verts.data()), vert_data_size); + + auto const idx_data_size = idxs.size() * sizeof(uint16_t); + std::vector idx_data(idx_data_size); + std::memcpy(idx_data.data(), reinterpret_cast(idxs.data()), idx_data_size); + + resources::MeshData meshdata{std::move(vert_data), std::move(idx_data), info}; + + // Update textures + auto tex_manager = this->asset_manager->get_texture_manager(); + + // TODO: Support multiple textures per terrain + + auto terrain_mesh = std::make_shared( + this->asset_manager, + this->render_entity->get_terrain_path(), + std::move(meshdata)); + + return terrain_mesh; +} + +} // namespace openage::renderer::terrain diff --git a/libopenage/renderer/stages/terrain/terrain_chunk.h b/libopenage/renderer/stages/terrain/terrain_chunk.h new file mode 100644 index 0000000000..7158ea1a90 --- /dev/null +++ b/libopenage/renderer/stages/terrain/terrain_chunk.h @@ -0,0 +1,106 @@ +// Copyright 2023-2023 the openage authors. See copying.md for legal info. + +#pragma once + +#include +#include +#include + +#include "time/time.h" +#include "util/vector.h" + + +namespace openage::renderer { + +namespace resources { +class AssetManager; +} + +namespace terrain { +class TerrainRenderMesh; +class TerrainRenderEntity; + +const size_t MAX_CHUNK_WIDTH = 16; +const size_t MAX_CHUNK_HEIGHT = 16; + + +class TerrainChunk { +public: + /** + * Create a new terrain chunk. + * + * @param asset_manager Asset manager for loading textures. + */ + TerrainChunk(const std::shared_ptr &asset_manager, + const util::Vector2s size, + const util::Vector2s offset); + + ~TerrainChunk() = default; + + /** + * Set the terrain render entity for vertex updates of this mesh. + * + * @param entity New terrain render entity. + */ + void set_render_entity(const std::shared_ptr &entity); + + /** + * Fetch updates from the render entity. + * + * @param time Current simulation time. + */ + void fetch_updates(const time::time_t &time = 0.0); + + /** + * Update the uniforms of the meshes. + * + * @param time Current simulation time. + */ + void update_uniforms(const time::time_t &time = 0.0); + + /** + * Get the meshes composing the terrain. + * + * @return Vector of terrain meshes. + */ + const std::vector> &get_meshes() const; + +private: + /** + * Create a terrain mesh from the data provided by the render entity. + * + * @return New terrain mesh. + */ + std::shared_ptr create_mesh(); + + /** + * Size of the chunk in tiles (width x height). + */ + util::Vector2s size; + + /** + * Offset of the chunk from origin in tiles (x, y). + */ + util::Vector2s offset; + + /** + * Meshes composing the terrain. Each mesh represents a drawable vertex surface + * and a texture. + */ + std::vector> meshes; + + /** + * Asset manager for central accessing and loading textures. + */ + std::shared_ptr asset_manager; + + /** + * Source for ingame terrain coordinates. These coordinates are translated into + * our render vertex mesh when \p update() is called. + */ + std::shared_ptr render_entity; +}; + + +} // namespace terrain +} // namespace openage::renderer diff --git a/libopenage/renderer/stages/terrain/terrain_model.cpp b/libopenage/renderer/stages/terrain/terrain_model.cpp index 4b73b556c9..f557934850 100644 --- a/libopenage/renderer/stages/terrain/terrain_model.cpp +++ b/libopenage/renderer/stages/terrain/terrain_model.cpp @@ -12,7 +12,7 @@ #include "coord/scene.h" #include "renderer/resources/assets/asset_manager.h" #include "renderer/resources/mesh_data.h" -#include "renderer/stages/terrain/terrain_mesh.h" +#include "renderer/stages/terrain/terrain_chunk.h" #include "renderer/stages/terrain/terrain_render_entity.h" #include "util/fixed_point.h" #include "util/vector.h" @@ -21,117 +21,38 @@ namespace openage::renderer::terrain { TerrainRenderModel::TerrainRenderModel(const std::shared_ptr &asset_manager) : - meshes{}, + chunks{}, camera{nullptr}, - asset_manager{asset_manager}, - render_entity{nullptr} { + asset_manager{asset_manager} { } void TerrainRenderModel::set_render_entity(const std::shared_ptr &entity) { - this->render_entity = entity; - this->fetch_updates(); + // ASDF: Set chunk size and offset from parameters + auto chunk = std::make_shared(this->asset_manager, util::Vector2s{10, 10}, util::Vector2s{0, 0}); + chunk->set_render_entity(entity); + chunk->fetch_updates(); + + this->chunks.push_back(chunk); } void TerrainRenderModel::set_camera(const std::shared_ptr &camera) { this->camera = camera; } -void TerrainRenderModel::fetch_updates() { - // TODO: Don't create model if render entity is not set - if (not this->render_entity) { - return; - } - - // Check render entity for updates - if (not this->render_entity->is_changed()) { - return; +void TerrainRenderModel::fetch_updates(const time::time_t &time) { + for (auto &chunk : this->chunks) { + chunk->fetch_updates(time); } - // TODO: Change mesh instead of recreating it - // TODO: Multiple meshes - auto new_mesh = this->create_mesh(); - this->meshes.clear(); - this->meshes.push_back(new_mesh); - - // Indicate to the render entity that its updates have been processed. - this->render_entity->clear_changed_flag(); } void TerrainRenderModel::update_uniforms(const time::time_t &time) { - for (auto &mesh : this->meshes) { - mesh->update_uniforms(time); + for (auto &chunk : this->chunks) { + chunk->update_uniforms(time); } } -const std::vector> &TerrainRenderModel::get_meshes() const { - return this->meshes; -} - -std::shared_ptr TerrainRenderModel::create_mesh() { - // Update mesh - auto size = this->render_entity->get_size(); - auto src_verts = this->render_entity->get_vertices(); - - // dst_verts places vertices in order - // (left to right, bottom to top) - std::vector dst_verts{}; - dst_verts.reserve(src_verts.size() * 5); - for (auto v : src_verts) { - // Transform to scene coords - auto v_vec = v.to_world_space(); - dst_verts.push_back(v_vec[0]); - dst_verts.push_back(v_vec[1]); - dst_verts.push_back(v_vec[2]); - // TODO: Texture scaling - dst_verts.push_back((v.ne / 10).to_float()); - dst_verts.push_back((v.se / 10).to_float()); - } - - // split the grid into triangles using an index array - std::vector idxs; - idxs.reserve((size[0] - 1) * (size[1] - 1) * 6); - // iterate over all tiles in the grid by columns, i.e. starting - // from the left corner to the bottom corner if you imagine it from - // the camera's point of view - for (size_t i = 0; i < size[0] - 1; ++i) { - for (size_t j = 0; j < size[1] - 1; ++j) { - // since we are working on tiles, we split each tile into two triangles - // with counter-clockwise vertex order - idxs.push_back(j + i * size[1]); // bottom left - idxs.push_back(j + 1 + i * size[1]); // bottom right - idxs.push_back(j + size[1] + i * size[1]); // top left - idxs.push_back(j + 1 + i * size[1]); // bottom right - idxs.push_back(j + size[1] + 1 + i * size[1]); // top right - idxs.push_back(j + size[1] + i * size[1]); // top left - } - } - - resources::VertexInputInfo info{ - {resources::vertex_input_t::V3F32, resources::vertex_input_t::V2F32}, - resources::vertex_layout_t::AOS, - resources::vertex_primitive_t::TRIANGLES, - resources::index_t::U16}; - - auto const vert_data_size = dst_verts.size() * sizeof(float); - std::vector vert_data(vert_data_size); - std::memcpy(vert_data.data(), reinterpret_cast(dst_verts.data()), vert_data_size); - - auto const idx_data_size = idxs.size() * sizeof(uint16_t); - std::vector idx_data(idx_data_size); - std::memcpy(idx_data.data(), reinterpret_cast(idxs.data()), idx_data_size); - - resources::MeshData meshdata{std::move(vert_data), std::move(idx_data), info}; - - // Update textures - auto tex_manager = this->asset_manager->get_texture_manager(); - - // TODO: Support multiple textures per terrain - - auto terrain_mesh = std::make_shared( - this->asset_manager, - this->render_entity->get_terrain_path(), - std::move(meshdata)); - - return terrain_mesh; +const std::vector> &TerrainRenderModel::get_chunks() const { + return this->chunks; } } // namespace openage::renderer::terrain diff --git a/libopenage/renderer/stages/terrain/terrain_model.h b/libopenage/renderer/stages/terrain/terrain_model.h index 4a1ec15aed..9b94213a12 100644 --- a/libopenage/renderer/stages/terrain/terrain_model.h +++ b/libopenage/renderer/stages/terrain/terrain_model.h @@ -21,6 +21,7 @@ class AssetManager; namespace terrain { class TerrainRenderEntity; class TerrainRenderMesh; +class TerrainChunk; /** * 3D model of the whole terrain. Combines the individual meshes @@ -47,8 +48,10 @@ class TerrainRenderModel { /** * Fetch updates from the render entity. + * + * @param time Current simulation time. */ - void fetch_updates(); + void fetch_updates(const time::time_t &time = 0.0); /** * Update the uniforms of the renderable associated with this object. @@ -58,25 +61,17 @@ class TerrainRenderModel { void update_uniforms(const time::time_t &time = 0.0); /** - * Get the meshes composing the terrain. + * Get the chunks composing the terrain. * - * @return Vector of terrain meshes. + * @return Chunks of the terrain. */ - const std::vector> &get_meshes() const; + const std::vector> &get_chunks() const; private: /** - * Create a terrain mesh from the data provided by the render entity. - * - * @return New terrain mesh. - */ - std::shared_ptr create_mesh(); - - /** - * Meshes composing the terrain. Each mesh represents a drawable vertex surface - * and a texture. + * Chunks composing the terrain. */ - std::vector> meshes; + std::vector> chunks; /** * Camera for view and projection uniforms. @@ -87,12 +82,6 @@ class TerrainRenderModel { * Asset manager for central accessing and loading textures. */ std::shared_ptr asset_manager; - - /** - * Source for ingame terrain coordinates. These coordinates are translated into - * our render vertex mesh when \p update() is called. - */ - std::shared_ptr render_entity; }; } // namespace terrain diff --git a/libopenage/renderer/stages/terrain/terrain_renderer.cpp b/libopenage/renderer/stages/terrain/terrain_renderer.cpp index 62b7de8207..008600c19e 100644 --- a/libopenage/renderer/stages/terrain/terrain_renderer.cpp +++ b/libopenage/renderer/stages/terrain/terrain_renderer.cpp @@ -8,6 +8,7 @@ #include "renderer/resources/shader_source.h" #include "renderer/resources/texture_info.h" #include "renderer/shader_program.h" +#include "renderer/stages/terrain/terrain_chunk.h" #include "renderer/stages/terrain/terrain_mesh.h" #include "renderer/stages/terrain/terrain_model.h" #include "renderer/window.h" @@ -56,26 +57,28 @@ void TerrainRenderer::set_render_entity(const std::shared_ptrmodel->fetch_updates(); auto current_time = this->clock->get_real_time(); - for (auto &mesh : this->model->get_meshes()) { - if (mesh->requires_renderable()) [[unlikely]] { /*probably doesn't happen that often?*/ - // TODO: Update uniforms and geometry individually, depending on what changed - // TODO: Update existing renderable instead of recreating it - auto geometry = this->renderer->add_mesh_geometry(mesh->get_mesh()); - auto transform_unifs = this->display_shader->create_empty_input(); - - Renderable display_obj{ - transform_unifs, - geometry, - true, - true, // it's a 3D object, so we need depth testing - }; - - // TODO: Remove old renderable instead of clearing everything - this->render_pass->clear_renderables(); - this->render_pass->add_renderables(display_obj); - mesh->clear_requires_renderable(); - - mesh->set_uniforms(transform_unifs); + for (auto &chunk : this->model->get_chunks()) { + for (auto &mesh : chunk->get_meshes()) { + if (mesh->requires_renderable()) [[unlikely]] { /*probably doesn't happen that often?*/ + // TODO: Update uniforms and geometry individually, depending on what changed + // TODO: Update existing renderable instead of recreating it + auto geometry = this->renderer->add_mesh_geometry(mesh->get_mesh()); + auto transform_unifs = this->display_shader->create_empty_input(); + + Renderable display_obj{ + transform_unifs, + geometry, + true, + true, // it's a 3D object, so we need depth testing + }; + + // TODO: Remove old renderable instead of clearing everything + this->render_pass->clear_renderables(); + this->render_pass->add_renderables(display_obj); + mesh->clear_requires_renderable(); + + mesh->set_uniforms(transform_unifs); + } } } this->model->update_uniforms(current_time); From 330f40e6c4a4b42ce47a33cd0eb6afa14b17cb25 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 5 Nov 2023 15:43:56 +0100 Subject: [PATCH 57/95] gamestate: Terrain chunks. --- libopenage/gamestate/terrain.cpp | 17 +++++- libopenage/gamestate/terrain.h | 24 +++++++-- libopenage/gamestate/terrain_chunk.cpp | 36 ++++++++++++- libopenage/gamestate/terrain_chunk.h | 53 +++++++++++++++++++ .../renderer/stages/terrain/terrain_chunk.h | 4 -- 5 files changed, 121 insertions(+), 13 deletions(-) diff --git a/libopenage/gamestate/terrain.cpp b/libopenage/gamestate/terrain.cpp index 247b457251..09a9d7cf6b 100644 --- a/libopenage/gamestate/terrain.cpp +++ b/libopenage/gamestate/terrain.cpp @@ -6,6 +6,7 @@ #include #include +#include "gamestate/terrain_chunk.h" #include "renderer/stages/terrain/terrain_render_entity.h" namespace openage::gamestate { @@ -25,7 +26,7 @@ Terrain::Terrain(const std::string &texture_path) : } } -void Terrain::push_to_render() { +void Terrain::render_update() { if (this->render_entity != nullptr) { this->render_entity->update(this->size, this->height_map, @@ -36,7 +37,19 @@ void Terrain::push_to_render() { void Terrain::set_render_entity(const std::shared_ptr &entity) { this->render_entity = entity; - this->push_to_render(); + this->render_update(); +} + +const std::vector> &Terrain::get_chunks() const { + return this->chunks; +} + +void Terrain::generate() { + auto chunk = std::make_shared(util::Vector2s{10, 10}, util::Vector2s{0, 0}); + chunk->set_render_entity(this->render_entity); + chunk->render_update(time::time_t::zero(), this->texture_path); + + this->chunks.push_back(chunk); } } // namespace openage::gamestate diff --git a/libopenage/gamestate/terrain.h b/libopenage/gamestate/terrain.h index 1e1aef9846..c1df66d415 100644 --- a/libopenage/gamestate/terrain.h +++ b/libopenage/gamestate/terrain.h @@ -14,6 +14,7 @@ class TerrainRenderEntity; } namespace gamestate { +class TerrainChunk; /** * Entity for managing the map terrain of a game. @@ -30,19 +31,32 @@ class Terrain { */ void set_render_entity(const std::shared_ptr &entity); + const std::vector> &get_chunks() const; + + // TODO: This should be an event + void generate(); + private: // test connection to renderer - void push_to_render(); + void render_update(); - // size of the map - // origin is the left corner - // x = top left edge; y = top right edge + /** + * Total size of the map + * origin is the left corner + * x = top left edge; y = top right edge + */ util::Vector2s size; + + /** + * Subdivision of the main terrain entity. + */ + std::vector> chunks; + + // ASDF: Move these members into terrain chunk // Heights of the terrain grid std::vector height_map; // path to a texture std::string texture_path; - // render entity for pushing updates to std::shared_ptr render_entity; }; diff --git a/libopenage/gamestate/terrain_chunk.cpp b/libopenage/gamestate/terrain_chunk.cpp index d434a7a921..1d5ef1f76f 100644 --- a/libopenage/gamestate/terrain_chunk.cpp +++ b/libopenage/gamestate/terrain_chunk.cpp @@ -1,8 +1,40 @@ -// Copyright 2018-2018 the openage authors. See copying.md for legal info. +// Copyright 2018-2023 the openage authors. See copying.md for legal info. #include "terrain_chunk.h" namespace openage::gamestate { -} // openage::gamestate +TerrainChunk::TerrainChunk(const util::Vector2s size, + const util::Vector2s offset) : + size{size}, + offset{offset}, + height_map{} { + if (this->size[0] > MAX_CHUNK_WIDTH || this->size[1] > MAX_CHUNK_HEIGHT) { + throw Error(MSG(err) << "Terrain chunk size exceeds maximum size: " + << this->size[0] << "x" << this->size[1] << " > " + << MAX_CHUNK_WIDTH << "x" << MAX_CHUNK_HEIGHT); + } + + // fill the terrain grid with height values + this->height_map.reserve(this->size[0] * this->size[1]); + for (size_t i = 0; i < this->size[0] * this->size[1]; ++i) { + this->height_map.push_back(0.0f); + } +} + +void TerrainChunk::set_render_entity(const std::shared_ptr &entity) { + this->render_entity = entity; +} + +void TerrainChunk::render_update(const time::time_t &time, + const std::string &terrain_path) { + if (this->render_entity != nullptr) { + this->render_entity->update(this->size, + this->height_map, + terrain_path, + time); + } +} + +} // namespace openage::gamestate diff --git a/libopenage/gamestate/terrain_chunk.h b/libopenage/gamestate/terrain_chunk.h index 784aec7c9e..b4b2f2d48f 100644 --- a/libopenage/gamestate/terrain_chunk.h +++ b/libopenage/gamestate/terrain_chunk.h @@ -2,13 +2,66 @@ #pragma once +#include + +#include "renderer/stages/terrain/terrain_render_entity.h" +#include "time/time.h" +#include "util/vector.h" + namespace openage::gamestate { +const size_t MAX_CHUNK_WIDTH = 16; +const size_t MAX_CHUNK_HEIGHT = 16; + + /** * Subdivision of the main terrain entity. */ class TerrainChunk { +public: + TerrainChunk(const util::Vector2s size, + const util::Vector2s offset); + ~TerrainChunk() = default; + + /** + * Set the current render entity of the terrain. + * + * @param entity New render entity. + */ + void set_render_entity(const std::shared_ptr &entity); + + /** + * Update the render entity. + * + * @param time Simulation time of the update. + * @param terrain_path Path to the terrain definition used at \p time. + */ + void render_update(const time::time_t &time, + const std::string &terrain_path); + +private: + /** + * Size of the terrain chunk. + * Origin is the left corner. + * x = top left edge; y = top right edge. + */ + util::Vector2s size; + + /** + * Offset of the terrain chunk to the origin. + */ + util::Vector2s offset; + + /** + * Height map of the terrain chunk. + */ + std::vector height_map; + + /** + * Render entity for pushing updates to the renderer. Can be \p nullptr. + */ + std::shared_ptr render_entity; }; } // namespace openage::gamestate diff --git a/libopenage/renderer/stages/terrain/terrain_chunk.h b/libopenage/renderer/stages/terrain/terrain_chunk.h index 7158ea1a90..88e2d70bdc 100644 --- a/libopenage/renderer/stages/terrain/terrain_chunk.h +++ b/libopenage/renderer/stages/terrain/terrain_chunk.h @@ -20,10 +20,6 @@ namespace terrain { class TerrainRenderMesh; class TerrainRenderEntity; -const size_t MAX_CHUNK_WIDTH = 16; -const size_t MAX_CHUNK_HEIGHT = 16; - - class TerrainChunk { public: /** From 542ec29ed43e82f94f5efa059d58207fbd6a21a0 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 5 Nov 2023 16:47:38 +0100 Subject: [PATCH 58/95] gamestate: Move terrain render updates to terrain chunk. --- libopenage/gamestate/CMakeLists.txt | 1 + libopenage/gamestate/game.cpp | 19 +++++- libopenage/gamestate/game.h | 13 +++- libopenage/gamestate/game_entity.h | 2 +- libopenage/gamestate/game_state.cpp | 12 +++- libopenage/gamestate/game_state.h | 24 ++++++- libopenage/gamestate/simulation.cpp | 7 ++- libopenage/gamestate/simulation.h | 6 ++ libopenage/gamestate/terrain.cpp | 44 +++++-------- libopenage/gamestate/terrain.h | 53 +++++++++------- libopenage/gamestate/terrain_factory.cpp | 44 +++++++++++++ libopenage/gamestate/terrain_factory.h | 79 ++++++++++++++++++++++++ libopenage/gamestate/universe.cpp | 7 --- libopenage/gamestate/universe.h | 2 + 14 files changed, 245 insertions(+), 68 deletions(-) create mode 100644 libopenage/gamestate/terrain_factory.cpp create mode 100644 libopenage/gamestate/terrain_factory.h diff --git a/libopenage/gamestate/CMakeLists.txt b/libopenage/gamestate/CMakeLists.txt index dddf843136..c7cdaebee2 100644 --- a/libopenage/gamestate/CMakeLists.txt +++ b/libopenage/gamestate/CMakeLists.txt @@ -8,6 +8,7 @@ add_sources(libopenage player.cpp simulation.cpp terrain_chunk.cpp + terrain_factory.cpp terrain.cpp types.cpp world.cpp diff --git a/libopenage/gamestate/game.cpp b/libopenage/gamestate/game.cpp index d31310945d..dae9f02528 100644 --- a/libopenage/gamestate/game.cpp +++ b/libopenage/gamestate/game.cpp @@ -13,6 +13,8 @@ #include "assets/modpack.h" #include "gamestate/entity_factory.h" #include "gamestate/game_state.h" +#include "gamestate/terrain.h" +#include "gamestate/terrain_factory.h" #include "gamestate/universe.h" #include "util/path.h" #include "util/strings.h" @@ -22,7 +24,8 @@ namespace openage::gamestate { Game::Game(const std::shared_ptr &event_loop, const std::shared_ptr &mod_manager, - const std::shared_ptr &entity_factory) : + const std::shared_ptr &entity_factory, + const std::shared_ptr &terrain_factory) : db{nyan::Database::create()}, state{std::make_shared(this->db, event_loop)}, universe{std::make_shared(state)} { @@ -39,6 +42,8 @@ Game::Game(const std::shared_ptr &event_loop, // This can be removed when we spawn based on game logic rather than // hardcoded entity types. this->state->set_mod_manager(mod_manager); + + this->generate_terrain(terrain_factory); } const std::shared_ptr &Game::get_state() const { @@ -47,6 +52,7 @@ const std::shared_ptr &Game::get_state() const { void Game::attach_renderer(const std::shared_ptr &render_factory) { this->universe->attach_renderer(render_factory); + this->state->get_terrain()->attach_renderer(render_factory); } void Game::load_data(const std::shared_ptr &mod_manager) { @@ -119,4 +125,15 @@ void Game::load_path(const util::Path &base_dir, } } +void Game::generate_terrain(const std::shared_ptr &terrain_factory) { + auto terrain = terrain_factory->add_terrain(); + + auto chunk0 = terrain_factory->add_chunk(util::Vector2s{10, 10}, util::Vector2s{0, 0}); + auto chunk1 = terrain_factory->add_chunk(util::Vector2s{10, 10}, util::Vector2s{10, 0}); + terrain->add_chunk(chunk0); + terrain->add_chunk(chunk1); + + this->state->set_terrain(terrain); +} + } // namespace openage::gamestate diff --git a/libopenage/gamestate/game.h b/libopenage/gamestate/game.h index aecfd3bd72..139c4e87fa 100644 --- a/libopenage/gamestate/game.h +++ b/libopenage/gamestate/game.h @@ -30,6 +30,7 @@ class Path; namespace gamestate { class GameState; class EntityFactory; +class TerrainFactory; class Universe; /** @@ -53,7 +54,8 @@ class Game { */ Game(const std::shared_ptr &event_loop, const std::shared_ptr &mod_manager, - const std::shared_ptr &entity_factory); + const std::shared_ptr &entity_factory, + const std::shared_ptr &terrain_factory); ~Game() = default; /** @@ -93,6 +95,15 @@ class Game { const std::string &search, bool recursive = false); + /** + * Generate the terrain for the current game. + * + * TODO: Use a real map generator. + * + * @param terrain_factory Factory for creating terrain objects. + */ + void generate_terrain(const std::shared_ptr &terrain_factory); + /** * Nyan game data database. */ diff --git a/libopenage/gamestate/game_entity.h b/libopenage/gamestate/game_entity.h index a79f167e7f..d4b61202e9 100644 --- a/libopenage/gamestate/game_entity.h +++ b/libopenage/gamestate/game_entity.h @@ -103,7 +103,7 @@ class GameEntity { * Update the render entity. * * @param time Simulation time of the update. - * @param animation_path Animation path used at \p time. + * @param animation_path Path to the animation definition used at \p time. */ void render_update(const time::time_t &time, const std::string &animation_path); diff --git a/libopenage/gamestate/game_state.cpp b/libopenage/gamestate/game_state.cpp index 9cda363379..fba3826779 100644 --- a/libopenage/gamestate/game_state.cpp +++ b/libopenage/gamestate/game_state.cpp @@ -23,20 +23,24 @@ const std::shared_ptr &GameState::get_db_view() { return this->db_view; } -void GameState::add_game_entity(const std::shared_ptr &entity) { +void GameState::add_game_entity(const std::shared_ptr entity) { if (this->game_entities.contains(entity->get_id())) [[unlikely]] { throw Error(MSG(err) << "Game entity with ID " << entity->get_id() << " already exists"); } this->game_entities[entity->get_id()] = entity; } -void GameState::add_player(const std::shared_ptr &player) { +void GameState::add_player(const std::shared_ptr player) { if (this->players.contains(player->get_id())) [[unlikely]] { throw Error(MSG(err) << "Player with ID " << player->get_id() << " already exists"); } this->players[player->get_id()] = player; } +void GameState::set_terrain(const std::shared_ptr terrain) { + this->terrain = terrain; +} + const std::shared_ptr &GameState::get_game_entity(entity_id_t id) const { if (!this->game_entities.contains(id)) [[unlikely]] { throw Error(MSG(err) << "Game entity with ID " << id << " does not exist"); @@ -55,6 +59,10 @@ const std::shared_ptr &GameState::get_player(player_id_t id) const { return this->players.at(id); } +const std::shared_ptr &GameState::get_terrain() const { + return this->terrain; +} + const std::shared_ptr &GameState::get_mod_manager() const { return this->mod_manager; } diff --git a/libopenage/gamestate/game_state.h b/libopenage/gamestate/game_state.h index d252acaadc..6cce1b09b1 100644 --- a/libopenage/gamestate/game_state.h +++ b/libopenage/gamestate/game_state.h @@ -27,6 +27,7 @@ class EventLoop; namespace gamestate { class GameEntity; class Player; +class Terrain; /** * State of the game. @@ -59,14 +60,21 @@ class GameState : public openage::event::State { * * @param entity New game entity. */ - void add_game_entity(const std::shared_ptr &entity); + void add_game_entity(const std::shared_ptr entity); /** * Add a new player to the index. * * @param player New player. */ - void add_player(const std::shared_ptr &player); + void add_player(const std::shared_ptr player); + + /** + * Set the terrain of the current game. + * + * @param terrain Terrain object. + */ + void set_terrain(const std::shared_ptr terrain); /** * Get a game entity by its ID. @@ -93,6 +101,13 @@ class GameState : public openage::event::State { */ const std::shared_ptr &get_player(player_id_t id) const; + /** + * Get the terrain of the current game. + * + * @return Terrain object. + */ + const std::shared_ptr &get_terrain() const; + /** * TODO: Only for testing. */ @@ -115,6 +130,11 @@ class GameState : public openage::event::State { */ std::unordered_map> players; + /** + * Terrain of the current game. + */ + std::shared_ptr terrain; + /** * TODO: Only for testing */ diff --git a/libopenage/gamestate/simulation.cpp b/libopenage/gamestate/simulation.cpp index c925888815..4af77d2815 100644 --- a/libopenage/gamestate/simulation.cpp +++ b/libopenage/gamestate/simulation.cpp @@ -9,6 +9,7 @@ #include "gamestate/event/send_command.h" #include "gamestate/event/spawn_entity.h" #include "gamestate/event/wait.h" +#include "gamestate/terrain_factory.h" #include "time/clock.h" #include "time/time_loop.h" @@ -27,6 +28,7 @@ GameSimulation::GameSimulation(const util::Path &root_dir, time_loop{time_loop}, event_loop{std::make_shared()}, entity_factory{std::make_shared()}, + terrain_factory{std::make_shared()}, mod_manager{std::make_shared(this->root_dir / "assets" / "converted")}, spawner{std::make_shared(this->event_loop)}, commander{std::make_shared(this->event_loop)} { @@ -54,9 +56,11 @@ void GameSimulation::start() { this->init_event_handlers(); + // TODO: wait for presenter to initialize before starting? this->game = std::make_shared(event_loop, this->mod_manager, - this->entity_factory); + this->entity_factory, + this->terrain_factory); this->running = true; @@ -114,6 +118,7 @@ void GameSimulation::attach_renderer(const std::shared_ptrgame->attach_renderer(render_factory); this->entity_factory->attach_renderer(render_factory); + this->terrain_factory->attach_renderer(render_factory); } void GameSimulation::set_modpacks(const std::vector &modpacks) { diff --git a/libopenage/gamestate/simulation.h b/libopenage/gamestate/simulation.h index aab81c524e..fe2de8257c 100644 --- a/libopenage/gamestate/simulation.h +++ b/libopenage/gamestate/simulation.h @@ -31,6 +31,7 @@ class TimeLoop; namespace gamestate { class EntityFactory; class Game; +class TerrainFactory; namespace event { class Commander; @@ -178,6 +179,11 @@ class GameSimulation final { */ std::shared_ptr entity_factory; + /** + * Factory for creating terrain. + */ + std::shared_ptr terrain_factory; + /** * Mod manager. */ diff --git a/libopenage/gamestate/terrain.cpp b/libopenage/gamestate/terrain.cpp index 09a9d7cf6b..2633d1a710 100644 --- a/libopenage/gamestate/terrain.cpp +++ b/libopenage/gamestate/terrain.cpp @@ -7,49 +7,33 @@ #include #include "gamestate/terrain_chunk.h" -#include "renderer/stages/terrain/terrain_render_entity.h" +#include "renderer/render_factory.h" + namespace openage::gamestate { -Terrain::Terrain(const std::string &texture_path) : +Terrain::Terrain() : size{0, 0}, - height_map{}, - texture_path{texture_path}, - render_entity{nullptr} { - // TODO: Actual terrain generation code - this->size = util::Vector2s{10, 10}; - - // fill the terrain grid with height values - this->height_map.reserve(this->size[0] * this->size[1]); - for (size_t i = 0; i < this->size[0] * this->size[1]; ++i) { - this->height_map.push_back(0.0f); - } -} - -void Terrain::render_update() { - if (this->render_entity != nullptr) { - this->render_entity->update(this->size, - this->height_map, - this->texture_path); - } + chunks{} { + // TODO: Get actual size of terrain. } -void Terrain::set_render_entity(const std::shared_ptr &entity) { - this->render_entity = entity; - - this->render_update(); +void Terrain::add_chunk(const std::shared_ptr chunk) { + this->chunks.push_back(chunk); } const std::vector> &Terrain::get_chunks() const { return this->chunks; } -void Terrain::generate() { - auto chunk = std::make_shared(util::Vector2s{10, 10}, util::Vector2s{0, 0}); - chunk->set_render_entity(this->render_entity); - chunk->render_update(time::time_t::zero(), this->texture_path); +void Terrain::attach_renderer(const std::shared_ptr &render_factory) { + for (auto &chunk : this->get_chunks()) { + auto render_entity = render_factory->add_terrain_render_entity(); + chunk->set_render_entity(render_entity); - this->chunks.push_back(chunk); + chunk->render_update(time::time_t::zero(), + "../test/textures/test_terrain.terrain"); + } } } // namespace openage::gamestate diff --git a/libopenage/gamestate/terrain.h b/libopenage/gamestate/terrain.h index c1df66d415..71f0bd63d7 100644 --- a/libopenage/gamestate/terrain.h +++ b/libopenage/gamestate/terrain.h @@ -9,9 +9,9 @@ #include "util/vector.h" namespace openage { -namespace renderer::terrain { -class TerrainRenderEntity; -} +namespace renderer { +class RenderFactory; +} // namespace renderer namespace gamestate { class TerrainChunk; @@ -21,27 +21,42 @@ class TerrainChunk; */ class Terrain { public: - Terrain(const std::string &texture_path); + /** + * Create a new terrain. + */ + Terrain(); ~Terrain() = default; /** - * Set the current render entity of the terrain. - * - * @param entity New render entity. - */ - void set_render_entity(const std::shared_ptr &entity); + * Add a chunk to the terrain. + * + * @param chunk New chunk. + */ + void add_chunk(const std::shared_ptr chunk); + /** + * Get the chunks of the terrain. + * + * @return Terrain chunks. + */ const std::vector> &get_chunks() const; - // TODO: This should be an event - void generate(); + /** + * Attach a renderer which enables graphical display. + * + * TODO: We currently have to do attach this here too in addition to the terrain + * factory because the renderer gets attached AFTER the terrain is + * already created. In the future, the game should wait for the renderer + * before creating the terrain. + * + * @param render_factory Factory for creating connector objects for gamestate->renderer + * communication. + */ + void attach_renderer(const std::shared_ptr &render_factory); private: - // test connection to renderer - void render_update(); - /** - * Total size of the map + * Total size of the map * origin is the left corner * x = top left edge; y = top right edge */ @@ -51,14 +66,6 @@ class Terrain { * Subdivision of the main terrain entity. */ std::vector> chunks; - - // ASDF: Move these members into terrain chunk - // Heights of the terrain grid - std::vector height_map; - // path to a texture - std::string texture_path; - // render entity for pushing updates to - std::shared_ptr render_entity; }; } // namespace gamestate diff --git a/libopenage/gamestate/terrain_factory.cpp b/libopenage/gamestate/terrain_factory.cpp new file mode 100644 index 0000000000..e7a0d284a0 --- /dev/null +++ b/libopenage/gamestate/terrain_factory.cpp @@ -0,0 +1,44 @@ +// Copyright 2023-2023 the openage authors. See copying.md for legal info. + +#include "terrain_factory.h" + +#include + +#include "gamestate/terrain.h" +#include "gamestate/terrain_chunk.h" +#include "renderer/render_factory.h" +#include "renderer/stages/terrain/terrain_render_entity.h" +#include "time/time.h" + + +namespace openage::gamestate { + +std::shared_ptr TerrainFactory::add_terrain() { + // TODO: Replace this with a proper terrain generator. + auto terrain = std::make_shared(); + + return terrain; +} + +std::shared_ptr TerrainFactory::add_chunk(const util::Vector2s size, + const util::Vector2s offset) { + auto chunk = std::make_shared(size, offset); + + if (this->render_factory) { + auto render_entity = this->render_factory->add_terrain_render_entity(); + chunk->set_render_entity(render_entity); + + chunk->render_update(time::time_t::zero(), + "../test/textures/test_terrain.terrain"); + } + + return chunk; +} + +void TerrainFactory::attach_renderer(const std::shared_ptr &render_factory) { + std::unique_lock lock{this->mutex}; + + this->render_factory = render_factory; +} + +} // namespace openage::gamestate diff --git a/libopenage/gamestate/terrain_factory.h b/libopenage/gamestate/terrain_factory.h new file mode 100644 index 0000000000..a60456819b --- /dev/null +++ b/libopenage/gamestate/terrain_factory.h @@ -0,0 +1,79 @@ +// Copyright 2023-2023 the openage authors. See copying.md for legal info. + +#pragma once + +#include +#include + +#include "util/vector.h" + + +namespace openage { + +namespace renderer { +class RenderFactory; +} + +namespace gamestate { +class GameState; +class Terrain; +class TerrainChunk; + +/** + * Creates terrain data (tiles, chunks, etc.) to generate a map. + */ +class TerrainFactory { +public: + /** + * Create a new terrain factory. + */ + TerrainFactory() = default; + ~TerrainFactory() = default; + + /** + * Create a new empty terrain object. + * + * @return New terrain object. + */ + std::shared_ptr add_terrain(); + + /** + * Create a new empty terrain chunk. + * + * @param size Size of the chunk. + * @param offset Offset of the chunk. + * + * @return New terrain chunk. + */ + std::shared_ptr add_chunk(const util::Vector2s size, + const util::Vector2s offset); + + // TODO: Add tiles + // std::shared_ptr add_tile(const std::shared_ptr &loop, + // const std::shared_ptr &state, + // const nyan::fqon_t &nyan_entity); + + /** + * Attach a render factory for graphical display. + * + * This enables rendering for all created terrain chunks. + * + * @param render_factory Factory for creating connector objects for gamestate->renderer + * communication. + */ + void attach_renderer(const std::shared_ptr &render_factory); + +private: + /** + * Factory for creating connector objects to the renderer which make game entities displayable. + */ + std::shared_ptr render_factory; + + /** + * Mutex for thread safety. + */ + std::shared_mutex mutex; +}; + +} // namespace gamestate +} // namespace openage diff --git a/libopenage/gamestate/universe.cpp b/libopenage/gamestate/universe.cpp index 6299296734..cf44782e7d 100644 --- a/libopenage/gamestate/universe.cpp +++ b/libopenage/gamestate/universe.cpp @@ -10,9 +10,6 @@ namespace openage::gamestate { Universe::Universe(const std::shared_ptr &state) : world{std::make_shared(state)} { - // TODO - auto texpath = "../test/textures/test_terrain.terrain"; - this->terrain = std::make_shared(texpath); } std::shared_ptr Universe::get_world() { @@ -26,10 +23,6 @@ std::shared_ptr Universe::get_terrain() { void Universe::attach_renderer(const std::shared_ptr &render_factory) { this->render_factory = render_factory; - // TODO: Notify entities somwhere else? - auto terrain_render_entity = this->render_factory->add_terrain_render_entity(); - this->terrain->set_render_entity(terrain_render_entity); - this->world->attach_renderer(render_factory); } diff --git a/libopenage/gamestate/universe.h b/libopenage/gamestate/universe.h index ed77f84095..7e33a83765 100644 --- a/libopenage/gamestate/universe.h +++ b/libopenage/gamestate/universe.h @@ -18,6 +18,8 @@ class World; /** * Entity for managing the "physical" game world entities (units, buildings, etc.) as well as * conceptual entities (players, resources, ...). + * + * TODO: Remove Universe and other subclasses. */ class Universe { public: From c1e73d0f8bc094050c7721108c172f38305b4c92 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 5 Nov 2023 17:45:35 +0100 Subject: [PATCH 59/95] renderer: Render individual terrain chunks. --- libopenage/gamestate/terrain.cpp | 3 ++- libopenage/gamestate/terrain_chunk.cpp | 8 ++++++++ libopenage/gamestate/terrain_chunk.h | 14 ++++++++++++++ libopenage/gamestate/terrain_factory.cpp | 2 +- libopenage/renderer/demo/demo_3.cpp | 7 ++++--- libopenage/renderer/demo/stresstest_0.cpp | 7 ++++--- libopenage/renderer/render_factory.cpp | 5 +++-- libopenage/renderer/render_factory.h | 12 +++++++++++- .../renderer/stages/terrain/terrain_chunk.cpp | 11 ++++++++++- .../renderer/stages/terrain/terrain_chunk.h | 16 ++++++++++++++++ .../renderer/stages/terrain/terrain_mesh.cpp | 9 +++++---- .../renderer/stages/terrain/terrain_mesh.h | 14 ++++++++++---- .../renderer/stages/terrain/terrain_model.cpp | 7 ++++--- .../renderer/stages/terrain/terrain_model.h | 11 ++++++++--- .../renderer/stages/terrain/terrain_renderer.cpp | 7 ++++--- .../renderer/stages/terrain/terrain_renderer.h | 10 ++++++++-- 16 files changed, 112 insertions(+), 31 deletions(-) diff --git a/libopenage/gamestate/terrain.cpp b/libopenage/gamestate/terrain.cpp index 2633d1a710..f2b790e0a7 100644 --- a/libopenage/gamestate/terrain.cpp +++ b/libopenage/gamestate/terrain.cpp @@ -28,7 +28,8 @@ const std::vector> &Terrain::get_chunks() const { void Terrain::attach_renderer(const std::shared_ptr &render_factory) { for (auto &chunk : this->get_chunks()) { - auto render_entity = render_factory->add_terrain_render_entity(); + auto render_entity = render_factory->add_terrain_render_entity(chunk->get_size(), + chunk->get_offset()); chunk->set_render_entity(render_entity); chunk->render_update(time::time_t::zero(), diff --git a/libopenage/gamestate/terrain_chunk.cpp b/libopenage/gamestate/terrain_chunk.cpp index 1d5ef1f76f..8053d7e324 100644 --- a/libopenage/gamestate/terrain_chunk.cpp +++ b/libopenage/gamestate/terrain_chunk.cpp @@ -37,4 +37,12 @@ void TerrainChunk::render_update(const time::time_t &time, } } +const util::Vector2s &TerrainChunk::get_size() const { + return this->size; +} + +const util::Vector2s &TerrainChunk::get_offset() const { + return this->offset; +} + } // namespace openage::gamestate diff --git a/libopenage/gamestate/terrain_chunk.h b/libopenage/gamestate/terrain_chunk.h index b4b2f2d48f..6bc9c7ba64 100644 --- a/libopenage/gamestate/terrain_chunk.h +++ b/libopenage/gamestate/terrain_chunk.h @@ -40,6 +40,20 @@ class TerrainChunk { void render_update(const time::time_t &time, const std::string &terrain_path); + /** + * Get the size of this terrain chunk. + * + * @return Size of the terrain chunk (in tiles). + */ + const util::Vector2s &get_size() const; + + /** + * Get the offset of this terrain chunk to the terrain origin. + * + * @return Offset of the terrain chunk (in tiles). + */ + const util::Vector2s &get_offset() const; + private: /** * Size of the terrain chunk. diff --git a/libopenage/gamestate/terrain_factory.cpp b/libopenage/gamestate/terrain_factory.cpp index e7a0d284a0..178bf6c541 100644 --- a/libopenage/gamestate/terrain_factory.cpp +++ b/libopenage/gamestate/terrain_factory.cpp @@ -25,7 +25,7 @@ std::shared_ptr TerrainFactory::add_chunk(const util::Vector2s siz auto chunk = std::make_shared(size, offset); if (this->render_factory) { - auto render_entity = this->render_factory->add_terrain_render_entity(); + auto render_entity = this->render_factory->add_terrain_render_entity(size, offset); chunk->set_render_entity(render_entity); chunk->render_update(time::time_t::zero(), diff --git a/libopenage/renderer/demo/demo_3.cpp b/libopenage/renderer/demo/demo_3.cpp index 6e0dc1f5ca..94aac2ff36 100644 --- a/libopenage/renderer/demo/demo_3.cpp +++ b/libopenage/renderer/demo/demo_3.cpp @@ -113,9 +113,6 @@ void renderer_demo_3(const util::Path &path) { // Create some entities to populate the scene auto render_factory = std::make_shared(terrain_renderer, world_renderer); - // Terrain - auto terrain0 = render_factory->add_terrain_render_entity(); - // Fill a 10x10 terrain grid with height values auto terrain_size = util::Vector2s{10, 10}; std::vector height_map{}; @@ -124,6 +121,10 @@ void renderer_demo_3(const util::Path &path) { height_map.push_back(0.0f); } + // Create entity for terrain rendering + auto terrain0 = render_factory->add_terrain_render_entity(terrain_size, + util::Vector2s{0, 0}); + // Create "test bumps" in the terrain to check if rendering works height_map[11] = 1.0f; height_map[23] = 2.3f; diff --git a/libopenage/renderer/demo/stresstest_0.cpp b/libopenage/renderer/demo/stresstest_0.cpp index 77b8f0f33b..b9f6c02a96 100644 --- a/libopenage/renderer/demo/stresstest_0.cpp +++ b/libopenage/renderer/demo/stresstest_0.cpp @@ -116,9 +116,6 @@ void renderer_stresstest_0(const util::Path &path) { // Create some entities to populate the scene auto render_factory = std::make_shared(terrain_renderer, world_renderer); - // Terrain - auto terrain0 = render_factory->add_terrain_render_entity(); - // Fill a 10x10 terrain grid with height values auto terrain_size = util::Vector2s{10, 10}; std::vector height_map{}; @@ -127,6 +124,10 @@ void renderer_stresstest_0(const util::Path &path) { height_map.push_back(0.0f); } + // Create entity for terrain rendering + auto terrain0 = render_factory->add_terrain_render_entity(terrain_size, + util::Vector2s{0, 0}); + // send the terrain data to the terrain renderer terrain0->update(terrain_size, height_map, diff --git a/libopenage/renderer/render_factory.cpp b/libopenage/renderer/render_factory.cpp index 463cb09d4a..6f42af5a67 100644 --- a/libopenage/renderer/render_factory.cpp +++ b/libopenage/renderer/render_factory.cpp @@ -14,9 +14,10 @@ RenderFactory::RenderFactory(const std::shared_ptr ter world_renderer{world_renderer} { } -std::shared_ptr RenderFactory::add_terrain_render_entity() { +std::shared_ptr RenderFactory::add_terrain_render_entity(const util::Vector2s chunk_size, + const util::Vector2s chunk_offset) { auto entity = std::make_shared(); - this->terrain_renderer->set_render_entity(entity); + this->terrain_renderer->add_render_entity(entity, chunk_size, chunk_offset); return entity; } diff --git a/libopenage/renderer/render_factory.h b/libopenage/renderer/render_factory.h index 84f2b6eb39..c90704bf5a 100644 --- a/libopenage/renderer/render_factory.h +++ b/libopenage/renderer/render_factory.h @@ -4,6 +4,9 @@ #include +#include "util/vector.h" + + namespace openage::renderer { namespace terrain { class TerrainRenderer; @@ -35,9 +38,16 @@ class RenderFactory { /** * Create a new terrain render entity and register it at the terrain renderer. * + * Render entities for terrain are associated with chunks, so a new render entity + * will result in the creation of a new chunk in the renderer. + * + * Size/offset of the chunk in the game simulation should match size/offset + * in the renderer. + * * @return Render entity for pushing terrain updates. */ - std::shared_ptr add_terrain_render_entity(); + std::shared_ptr add_terrain_render_entity(const util::Vector2s chunk_size, + const util::Vector2s chunk_offset); /** * Create a new world render entity and register it at the world renderer. diff --git a/libopenage/renderer/stages/terrain/terrain_chunk.cpp b/libopenage/renderer/stages/terrain/terrain_chunk.cpp index 73109cd2c4..95b48b4f64 100644 --- a/libopenage/renderer/stages/terrain/terrain_chunk.cpp +++ b/libopenage/renderer/stages/terrain/terrain_chunk.cpp @@ -34,6 +34,7 @@ void TerrainChunk::fetch_updates(const time::time_t &time) { // TODO: Change mesh instead of recreating it // TODO: Multiple meshes auto new_mesh = this->create_mesh(); + new_mesh->create_model_matrix(this->offset); this->meshes.clear(); this->meshes.push_back(new_mesh); @@ -109,7 +110,7 @@ std::shared_ptr TerrainChunk::create_mesh() { // Update textures auto tex_manager = this->asset_manager->get_texture_manager(); - // TODO: Support multiple textures per terrain + // TODO: Support multiple textures per chunk auto terrain_mesh = std::make_shared( this->asset_manager, @@ -119,4 +120,12 @@ std::shared_ptr TerrainChunk::create_mesh() { return terrain_mesh; } +util::Vector2s &TerrainChunk::get_size() { + return this->size; +} + +util::Vector2s &TerrainChunk::get_offset() { + return this->offset; +} + } // namespace openage::renderer::terrain diff --git a/libopenage/renderer/stages/terrain/terrain_chunk.h b/libopenage/renderer/stages/terrain/terrain_chunk.h index 88e2d70bdc..f9764615ba 100644 --- a/libopenage/renderer/stages/terrain/terrain_chunk.h +++ b/libopenage/renderer/stages/terrain/terrain_chunk.h @@ -37,6 +37,8 @@ class TerrainChunk { * Set the terrain render entity for vertex updates of this mesh. * * @param entity New terrain render entity. + * @param size Size of the chunk in tiles. + * @param offset Offset of the chunk from origin in tiles. */ void set_render_entity(const std::shared_ptr &entity); @@ -61,6 +63,20 @@ class TerrainChunk { */ const std::vector> &get_meshes() const; + /** + * Get the size of the chunk in tiles. + * + * @return Size of the chunk (in tiles). + */ + util::Vector2s &get_size(); + + /** + * Get the offset of the chunk from origin in tiles. + * + * @return Offset of the chunk (in tiles). + */ + util::Vector2s &get_offset(); + private: /** * Create a terrain mesh from the data provided by the render entity. diff --git a/libopenage/renderer/stages/terrain/terrain_mesh.cpp b/libopenage/renderer/stages/terrain/terrain_mesh.cpp index 1085e315d4..6d05836518 100644 --- a/libopenage/renderer/stages/terrain/terrain_mesh.cpp +++ b/libopenage/renderer/stages/terrain/terrain_mesh.cpp @@ -70,7 +70,7 @@ void TerrainRenderMesh::update_uniforms(const time::time_t &time) { } // local space -> world space - this->uniforms->update("model", this->get_model_matrix()); + this->uniforms->update("model", this->model_matrix); auto tex_info = this->terrain_info.get(time)->get_texture(0); auto tex_manager = this->asset_manager->get_texture_manager(); @@ -97,10 +97,11 @@ const std::shared_ptr &TerrainRenderMesh::get_uniforms() return this->uniforms; } -Eigen::Matrix4f TerrainRenderMesh::get_model_matrix() { +void TerrainRenderMesh::create_model_matrix(util::Vector2s &offset) { // TODO: Needs input from engine - auto transform = Eigen::Affine3f::Identity(); - return transform.matrix(); + auto model = Eigen::Affine3f::Identity(); + model.translate(Eigen::Vector3f{offset[0], offset[1], 0.0f}); + this->model_matrix = model.matrix(); } bool TerrainRenderMesh::is_changed() { diff --git a/libopenage/renderer/stages/terrain/terrain_mesh.h b/libopenage/renderer/stages/terrain/terrain_mesh.h index a571007204..f337853a10 100644 --- a/libopenage/renderer/stages/terrain/terrain_mesh.h +++ b/libopenage/renderer/stages/terrain/terrain_mesh.h @@ -10,6 +10,7 @@ #include "curve/discrete.h" #include "renderer/resources/mesh_data.h" #include "time/time.h" +#include "util/vector.h" namespace openage::renderer { @@ -110,11 +111,11 @@ class TerrainRenderMesh { void clear_requires_renderable(); /** - * Get the model transformation matrix for rendering. - * - * @return Model matrix. + * Create the model transformation matrix for rendering. + * + * @param offset Offset of the terrain mesh to the scene origin. */ - Eigen::Matrix4f get_model_matrix(); + void create_model_matrix(util::Vector2s &offset); /** * Check whether the mesh or texture were changed. @@ -159,6 +160,11 @@ class TerrainRenderMesh { * Pre-transformation vertices for the terrain model. */ renderer::resources::MeshData mesh; + + /** + * Transformation matrix for the terrain model. + */ + Eigen::Matrix4f model_matrix; }; } // namespace terrain } // namespace openage::renderer diff --git a/libopenage/renderer/stages/terrain/terrain_model.cpp b/libopenage/renderer/stages/terrain/terrain_model.cpp index f557934850..18f6fa31f8 100644 --- a/libopenage/renderer/stages/terrain/terrain_model.cpp +++ b/libopenage/renderer/stages/terrain/terrain_model.cpp @@ -26,9 +26,10 @@ TerrainRenderModel::TerrainRenderModel(const std::shared_ptr &entity) { - // ASDF: Set chunk size and offset from parameters - auto chunk = std::make_shared(this->asset_manager, util::Vector2s{10, 10}, util::Vector2s{0, 0}); +void TerrainRenderModel::add_chunk(const std::shared_ptr &entity, + const util::Vector2s size, + const util::Vector2s offset) { + auto chunk = std::make_shared(this->asset_manager, size, offset); chunk->set_render_entity(entity); chunk->fetch_updates(); diff --git a/libopenage/renderer/stages/terrain/terrain_model.h b/libopenage/renderer/stages/terrain/terrain_model.h index 9b94213a12..b2575c725d 100644 --- a/libopenage/renderer/stages/terrain/terrain_model.h +++ b/libopenage/renderer/stages/terrain/terrain_model.h @@ -6,6 +6,7 @@ #include #include "time/time.h" +#include "util/vector.h" namespace openage::renderer { @@ -33,11 +34,15 @@ class TerrainRenderModel { ~TerrainRenderModel() = default; /** - * Set the terrain render entity for vertex updates of this mesh. + * Add a new chunk to the terrain model. * - * @param entity New terrain render entity. + * @param entity Render entity of the chunk. + * @param chunk_size Size of the chunk in tiles. + * @param chunk_offset Offset of the chunk from origin in tiles. */ - void set_render_entity(const std::shared_ptr &entity); + void add_chunk(const std::shared_ptr &entity, + const util::Vector2s chunk_size, + const util::Vector2s chunk_offset); /** * Set the current camera of the scene. diff --git a/libopenage/renderer/stages/terrain/terrain_renderer.cpp b/libopenage/renderer/stages/terrain/terrain_renderer.cpp index 008600c19e..adf1c43496 100644 --- a/libopenage/renderer/stages/terrain/terrain_renderer.cpp +++ b/libopenage/renderer/stages/terrain/terrain_renderer.cpp @@ -46,11 +46,13 @@ std::shared_ptr TerrainRenderer::get_render_pass() { return this->render_pass; } -void TerrainRenderer::set_render_entity(const std::shared_ptr entity) { +void TerrainRenderer::add_render_entity(const std::shared_ptr entity, + const util::Vector2s chunk_size, + const util::Vector2s chunk_offset) { std::unique_lock lock{this->mutex}; this->render_entity = entity; - this->model->set_render_entity(this->render_entity); + this->model->add_chunk(this->render_entity, chunk_size, chunk_offset); this->update(); } @@ -73,7 +75,6 @@ void TerrainRenderer::update() { }; // TODO: Remove old renderable instead of clearing everything - this->render_pass->clear_renderables(); this->render_pass->add_renderables(display_obj); mesh->clear_requires_renderable(); diff --git a/libopenage/renderer/stages/terrain/terrain_renderer.h b/libopenage/renderer/stages/terrain/terrain_renderer.h index 286567c34a..94bfdc0c05 100644 --- a/libopenage/renderer/stages/terrain/terrain_renderer.h +++ b/libopenage/renderer/stages/terrain/terrain_renderer.h @@ -6,6 +6,8 @@ #include #include "util/path.h" +#include "util/vector.h" + namespace openage { @@ -54,11 +56,15 @@ class TerrainRenderer { std::shared_ptr get_render_pass(); /** - * Set the current render entity of the terrain renderer. + * Add a new render entity to the terrain renderer. + * + * This creates a new terrain chunk and add it to the model. * * @param render_entity New render entity. */ - void set_render_entity(const std::shared_ptr entity); + void add_render_entity(const std::shared_ptr entity, + const util::Vector2s chunk_size, + const util::Vector2s chunk_offset); /** * Update the terrain mesh and texture information. From ac89eac1dada1fc3bb04d49733ce9eed1f438b11 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 5 Nov 2023 18:24:10 +0100 Subject: [PATCH 60/95] terrain: Change chunk offsets to scene coordinate types. --- libopenage/coord/tile.cpp | 8 ++++++++ libopenage/coord/tile.h | 4 ++++ libopenage/gamestate/game.cpp | 5 +++-- libopenage/gamestate/terrain_chunk.cpp | 4 ++-- libopenage/gamestate/terrain_chunk.h | 7 ++++--- libopenage/gamestate/terrain_factory.cpp | 2 +- libopenage/gamestate/terrain_factory.h | 3 ++- libopenage/renderer/demo/demo_3.cpp | 4 +++- libopenage/renderer/demo/stresstest_0.cpp | 3 ++- libopenage/renderer/render_factory.cpp | 5 +++-- libopenage/renderer/render_factory.h | 3 ++- libopenage/renderer/stages/terrain/terrain_chunk.cpp | 4 ++-- libopenage/renderer/stages/terrain/terrain_chunk.h | 7 ++++--- libopenage/renderer/stages/terrain/terrain_mesh.cpp | 4 ++-- libopenage/renderer/stages/terrain/terrain_mesh.h | 3 ++- libopenage/renderer/stages/terrain/terrain_model.cpp | 2 +- libopenage/renderer/stages/terrain/terrain_model.h | 3 ++- .../renderer/stages/terrain/terrain_render_entity.h | 2 +- libopenage/renderer/stages/terrain/terrain_renderer.cpp | 2 +- libopenage/renderer/stages/terrain/terrain_renderer.h | 3 ++- 20 files changed, 51 insertions(+), 27 deletions(-) diff --git a/libopenage/coord/tile.cpp b/libopenage/coord/tile.cpp index b89f1e9578..2ccbcf0ce1 100644 --- a/libopenage/coord/tile.cpp +++ b/libopenage/coord/tile.cpp @@ -49,4 +49,12 @@ phys3 tile3::to_phys3() const { } +phys2_delta tile_delta::to_phys2() const { + return phys2_delta(this->ne, this->se); +} + +phys3_delta tile_delta::to_phys3(tile_t up) const { + return phys3_delta(this->ne, this->se, up); +} + } // namespace openage::coord diff --git a/libopenage/coord/tile.h b/libopenage/coord/tile.h index df08045e21..5cb3f2475d 100644 --- a/libopenage/coord/tile.h +++ b/libopenage/coord/tile.h @@ -22,6 +22,9 @@ namespace coord { struct tile_delta : CoordNeSeRelative { using CoordNeSeRelative::CoordNeSeRelative; + + phys2_delta to_phys2() const; + phys3_delta to_phys3(tile_t up = 0) const; }; struct tile : CoordNeSeAbsolute { @@ -48,6 +51,7 @@ struct tile3_delta : CoordNeSeUpRelative { constexpr tile_delta to_tile() const { return tile_delta{this->ne, this->se}; } + phys3_delta to_phys3() const; }; struct tile3 : CoordNeSeUpAbsolute { diff --git a/libopenage/gamestate/game.cpp b/libopenage/gamestate/game.cpp index dae9f02528..ae85a67171 100644 --- a/libopenage/gamestate/game.cpp +++ b/libopenage/gamestate/game.cpp @@ -19,6 +19,7 @@ #include "util/path.h" #include "util/strings.h" +#include "coord/tile.h" namespace openage::gamestate { @@ -128,8 +129,8 @@ void Game::load_path(const util::Path &base_dir, void Game::generate_terrain(const std::shared_ptr &terrain_factory) { auto terrain = terrain_factory->add_terrain(); - auto chunk0 = terrain_factory->add_chunk(util::Vector2s{10, 10}, util::Vector2s{0, 0}); - auto chunk1 = terrain_factory->add_chunk(util::Vector2s{10, 10}, util::Vector2s{10, 0}); + auto chunk0 = terrain_factory->add_chunk(util::Vector2s{10, 10}, coord::tile_delta{0, 0}); + auto chunk1 = terrain_factory->add_chunk(util::Vector2s{10, 10}, coord::tile_delta{10, 0}); terrain->add_chunk(chunk0); terrain->add_chunk(chunk1); diff --git a/libopenage/gamestate/terrain_chunk.cpp b/libopenage/gamestate/terrain_chunk.cpp index 8053d7e324..6ba3338d7b 100644 --- a/libopenage/gamestate/terrain_chunk.cpp +++ b/libopenage/gamestate/terrain_chunk.cpp @@ -6,7 +6,7 @@ namespace openage::gamestate { TerrainChunk::TerrainChunk(const util::Vector2s size, - const util::Vector2s offset) : + const coord::tile_delta offset) : size{size}, offset{offset}, height_map{} { @@ -41,7 +41,7 @@ const util::Vector2s &TerrainChunk::get_size() const { return this->size; } -const util::Vector2s &TerrainChunk::get_offset() const { +const coord::tile_delta &TerrainChunk::get_offset() const { return this->offset; } diff --git a/libopenage/gamestate/terrain_chunk.h b/libopenage/gamestate/terrain_chunk.h index 6bc9c7ba64..191ee8f185 100644 --- a/libopenage/gamestate/terrain_chunk.h +++ b/libopenage/gamestate/terrain_chunk.h @@ -4,6 +4,7 @@ #include +#include "coord/tile.h" #include "renderer/stages/terrain/terrain_render_entity.h" #include "time/time.h" #include "util/vector.h" @@ -21,7 +22,7 @@ const size_t MAX_CHUNK_HEIGHT = 16; class TerrainChunk { public: TerrainChunk(const util::Vector2s size, - const util::Vector2s offset); + const coord::tile_delta offset); ~TerrainChunk() = default; /** @@ -52,7 +53,7 @@ class TerrainChunk { * * @return Offset of the terrain chunk (in tiles). */ - const util::Vector2s &get_offset() const; + const coord::tile_delta &get_offset() const; private: /** @@ -65,7 +66,7 @@ class TerrainChunk { /** * Offset of the terrain chunk to the origin. */ - util::Vector2s offset; + coord::tile_delta offset; /** * Height map of the terrain chunk. diff --git a/libopenage/gamestate/terrain_factory.cpp b/libopenage/gamestate/terrain_factory.cpp index 178bf6c541..57c2fe121c 100644 --- a/libopenage/gamestate/terrain_factory.cpp +++ b/libopenage/gamestate/terrain_factory.cpp @@ -21,7 +21,7 @@ std::shared_ptr TerrainFactory::add_terrain() { } std::shared_ptr TerrainFactory::add_chunk(const util::Vector2s size, - const util::Vector2s offset) { + const coord::tile_delta offset) { auto chunk = std::make_shared(size, offset); if (this->render_factory) { diff --git a/libopenage/gamestate/terrain_factory.h b/libopenage/gamestate/terrain_factory.h index a60456819b..88a86c4fe0 100644 --- a/libopenage/gamestate/terrain_factory.h +++ b/libopenage/gamestate/terrain_factory.h @@ -5,6 +5,7 @@ #include #include +#include "coord/tile.h" #include "util/vector.h" @@ -46,7 +47,7 @@ class TerrainFactory { * @return New terrain chunk. */ std::shared_ptr add_chunk(const util::Vector2s size, - const util::Vector2s offset); + const coord::tile_delta offset); // TODO: Add tiles // std::shared_ptr add_tile(const std::shared_ptr &loop, diff --git a/libopenage/renderer/demo/demo_3.cpp b/libopenage/renderer/demo/demo_3.cpp index 94aac2ff36..1cfec155b8 100644 --- a/libopenage/renderer/demo/demo_3.cpp +++ b/libopenage/renderer/demo/demo_3.cpp @@ -5,6 +5,7 @@ #include #include +#include "coord/tile.h" #include "renderer/camera/camera.h" #include "renderer/gui/integration/public/gui_application_with_logger.h" #include "renderer/opengl/window.h" @@ -21,6 +22,7 @@ #include "renderer/uniform_buffer.h" #include "time/clock.h" + namespace openage::renderer::tests { void renderer_demo_3(const util::Path &path) { @@ -123,7 +125,7 @@ void renderer_demo_3(const util::Path &path) { // Create entity for terrain rendering auto terrain0 = render_factory->add_terrain_render_entity(terrain_size, - util::Vector2s{0, 0}); + coord::tile_delta{0, 0}); // Create "test bumps" in the terrain to check if rendering works height_map[11] = 1.0f; diff --git a/libopenage/renderer/demo/stresstest_0.cpp b/libopenage/renderer/demo/stresstest_0.cpp index b9f6c02a96..39b0ba0931 100644 --- a/libopenage/renderer/demo/stresstest_0.cpp +++ b/libopenage/renderer/demo/stresstest_0.cpp @@ -4,6 +4,7 @@ #include +#include "coord/tile.h" #include "renderer/camera/camera.h" #include "renderer/gui/integration/public/gui_application_with_logger.h" #include "renderer/opengl/window.h" @@ -126,7 +127,7 @@ void renderer_stresstest_0(const util::Path &path) { // Create entity for terrain rendering auto terrain0 = render_factory->add_terrain_render_entity(terrain_size, - util::Vector2s{0, 0}); + coord::tile_delta{0, 0}); // send the terrain data to the terrain renderer terrain0->update(terrain_size, diff --git a/libopenage/renderer/render_factory.cpp b/libopenage/renderer/render_factory.cpp index 6f42af5a67..c40cc46508 100644 --- a/libopenage/renderer/render_factory.cpp +++ b/libopenage/renderer/render_factory.cpp @@ -2,6 +2,7 @@ #include "render_factory.h" +#include "coord/phys.h" #include "renderer/stages/terrain/terrain_render_entity.h" #include "renderer/stages/terrain/terrain_renderer.h" #include "renderer/stages/world/world_render_entity.h" @@ -15,9 +16,9 @@ RenderFactory::RenderFactory(const std::shared_ptr ter } std::shared_ptr RenderFactory::add_terrain_render_entity(const util::Vector2s chunk_size, - const util::Vector2s chunk_offset) { + const coord::tile_delta chunk_offset) { auto entity = std::make_shared(); - this->terrain_renderer->add_render_entity(entity, chunk_size, chunk_offset); + this->terrain_renderer->add_render_entity(entity, chunk_size, chunk_offset.to_phys2().to_scene2()); return entity; } diff --git a/libopenage/renderer/render_factory.h b/libopenage/renderer/render_factory.h index c90704bf5a..5a2a36de59 100644 --- a/libopenage/renderer/render_factory.h +++ b/libopenage/renderer/render_factory.h @@ -4,6 +4,7 @@ #include +#include "coord/tile.h" #include "util/vector.h" @@ -47,7 +48,7 @@ class RenderFactory { * @return Render entity for pushing terrain updates. */ std::shared_ptr add_terrain_render_entity(const util::Vector2s chunk_size, - const util::Vector2s chunk_offset); + const coord::tile_delta chunk_offset); /** * Create a new world render entity and register it at the world renderer. diff --git a/libopenage/renderer/stages/terrain/terrain_chunk.cpp b/libopenage/renderer/stages/terrain/terrain_chunk.cpp index 95b48b4f64..8ca1b8970a 100644 --- a/libopenage/renderer/stages/terrain/terrain_chunk.cpp +++ b/libopenage/renderer/stages/terrain/terrain_chunk.cpp @@ -12,7 +12,7 @@ namespace openage::renderer::terrain { TerrainChunk::TerrainChunk(const std::shared_ptr &asset_manager, const util::Vector2s size, - const util::Vector2s offset) : + const coord::scene2_delta offset) : size{size}, offset{offset}, asset_manager{asset_manager} {} @@ -124,7 +124,7 @@ util::Vector2s &TerrainChunk::get_size() { return this->size; } -util::Vector2s &TerrainChunk::get_offset() { +coord::scene2_delta &TerrainChunk::get_offset() { return this->offset; } diff --git a/libopenage/renderer/stages/terrain/terrain_chunk.h b/libopenage/renderer/stages/terrain/terrain_chunk.h index f9764615ba..4e96619865 100644 --- a/libopenage/renderer/stages/terrain/terrain_chunk.h +++ b/libopenage/renderer/stages/terrain/terrain_chunk.h @@ -6,6 +6,7 @@ #include #include +#include "coord/scene.h" #include "time/time.h" #include "util/vector.h" @@ -29,7 +30,7 @@ class TerrainChunk { */ TerrainChunk(const std::shared_ptr &asset_manager, const util::Vector2s size, - const util::Vector2s offset); + const coord::scene2_delta offset); ~TerrainChunk() = default; @@ -75,7 +76,7 @@ class TerrainChunk { * * @return Offset of the chunk (in tiles). */ - util::Vector2s &get_offset(); + coord::scene2_delta &get_offset(); private: /** @@ -93,7 +94,7 @@ class TerrainChunk { /** * Offset of the chunk from origin in tiles (x, y). */ - util::Vector2s offset; + coord::scene2_delta offset; /** * Meshes composing the terrain. Each mesh represents a drawable vertex surface diff --git a/libopenage/renderer/stages/terrain/terrain_mesh.cpp b/libopenage/renderer/stages/terrain/terrain_mesh.cpp index 6d05836518..88b471c22f 100644 --- a/libopenage/renderer/stages/terrain/terrain_mesh.cpp +++ b/libopenage/renderer/stages/terrain/terrain_mesh.cpp @@ -97,10 +97,10 @@ const std::shared_ptr &TerrainRenderMesh::get_uniforms() return this->uniforms; } -void TerrainRenderMesh::create_model_matrix(util::Vector2s &offset) { +void TerrainRenderMesh::create_model_matrix(const coord::scene2_delta &offset) { // TODO: Needs input from engine auto model = Eigen::Affine3f::Identity(); - model.translate(Eigen::Vector3f{offset[0], offset[1], 0.0f}); + model.translate(Eigen::Vector3f{offset.ne.to_float(), offset.se.to_float(), 0.0f}); this->model_matrix = model.matrix(); } diff --git a/libopenage/renderer/stages/terrain/terrain_mesh.h b/libopenage/renderer/stages/terrain/terrain_mesh.h index f337853a10..e2c7545ff8 100644 --- a/libopenage/renderer/stages/terrain/terrain_mesh.h +++ b/libopenage/renderer/stages/terrain/terrain_mesh.h @@ -7,6 +7,7 @@ #include +#include "coord/scene.h" #include "curve/discrete.h" #include "renderer/resources/mesh_data.h" #include "time/time.h" @@ -115,7 +116,7 @@ class TerrainRenderMesh { * * @param offset Offset of the terrain mesh to the scene origin. */ - void create_model_matrix(util::Vector2s &offset); + void create_model_matrix(const coord::scene2_delta &offset); /** * Check whether the mesh or texture were changed. diff --git a/libopenage/renderer/stages/terrain/terrain_model.cpp b/libopenage/renderer/stages/terrain/terrain_model.cpp index 18f6fa31f8..329968f858 100644 --- a/libopenage/renderer/stages/terrain/terrain_model.cpp +++ b/libopenage/renderer/stages/terrain/terrain_model.cpp @@ -28,7 +28,7 @@ TerrainRenderModel::TerrainRenderModel(const std::shared_ptr &entity, const util::Vector2s size, - const util::Vector2s offset) { + const coord::scene2_delta offset) { auto chunk = std::make_shared(this->asset_manager, size, offset); chunk->set_render_entity(entity); chunk->fetch_updates(); diff --git a/libopenage/renderer/stages/terrain/terrain_model.h b/libopenage/renderer/stages/terrain/terrain_model.h index b2575c725d..6677f3c4c5 100644 --- a/libopenage/renderer/stages/terrain/terrain_model.h +++ b/libopenage/renderer/stages/terrain/terrain_model.h @@ -5,6 +5,7 @@ #include #include +#include "coord/scene.h" #include "time/time.h" #include "util/vector.h" @@ -42,7 +43,7 @@ class TerrainRenderModel { */ void add_chunk(const std::shared_ptr &entity, const util::Vector2s chunk_size, - const util::Vector2s chunk_offset); + const coord::scene2_delta chunk_offset); /** * Set the current camera of the scene. diff --git a/libopenage/renderer/stages/terrain/terrain_render_entity.h b/libopenage/renderer/stages/terrain/terrain_render_entity.h index 2d074e2590..5e95896a11 100644 --- a/libopenage/renderer/stages/terrain/terrain_render_entity.h +++ b/libopenage/renderer/stages/terrain/terrain_render_entity.h @@ -81,7 +81,7 @@ class TerrainRenderEntity { bool changed; /** - * Terrain dimensions (width x height). + * Chunk dimensions (width x height). */ util::Vector2s size; diff --git a/libopenage/renderer/stages/terrain/terrain_renderer.cpp b/libopenage/renderer/stages/terrain/terrain_renderer.cpp index adf1c43496..92b5933d4f 100644 --- a/libopenage/renderer/stages/terrain/terrain_renderer.cpp +++ b/libopenage/renderer/stages/terrain/terrain_renderer.cpp @@ -48,7 +48,7 @@ std::shared_ptr TerrainRenderer::get_render_pass() { void TerrainRenderer::add_render_entity(const std::shared_ptr entity, const util::Vector2s chunk_size, - const util::Vector2s chunk_offset) { + const coord::scene2_delta chunk_offset) { std::unique_lock lock{this->mutex}; this->render_entity = entity; diff --git a/libopenage/renderer/stages/terrain/terrain_renderer.h b/libopenage/renderer/stages/terrain/terrain_renderer.h index 94bfdc0c05..4986509c95 100644 --- a/libopenage/renderer/stages/terrain/terrain_renderer.h +++ b/libopenage/renderer/stages/terrain/terrain_renderer.h @@ -5,6 +5,7 @@ #include #include +#include "coord/scene.h" #include "util/path.h" #include "util/vector.h" @@ -64,7 +65,7 @@ class TerrainRenderer { */ void add_render_entity(const std::shared_ptr entity, const util::Vector2s chunk_size, - const util::Vector2s chunk_offset); + const coord::scene2_delta chunk_offset); /** * Update the terrain mesh and texture information. From bd554c8f31fa83891eec173e7babb3bb3639ab74 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 5 Nov 2023 23:05:14 +0100 Subject: [PATCH 61/95] gamestate: Use terrain texture from modpacks is available. --- libopenage/gamestate/api/CMakeLists.txt | 1 + libopenage/gamestate/api/terrain.cpp | 22 +++++ libopenage/gamestate/api/terrain.h | 35 ++++++++ libopenage/gamestate/event/spawn_entity.cpp | 93 ++++++++++---------- libopenage/gamestate/game.cpp | 8 +- libopenage/gamestate/terrain_factory.cpp | 95 ++++++++++++++++++++- libopenage/gamestate/terrain_factory.h | 3 +- 7 files changed, 209 insertions(+), 48 deletions(-) create mode 100644 libopenage/gamestate/api/terrain.cpp create mode 100644 libopenage/gamestate/api/terrain.h diff --git a/libopenage/gamestate/api/CMakeLists.txt b/libopenage/gamestate/api/CMakeLists.txt index e235b05137..f079f11be3 100644 --- a/libopenage/gamestate/api/CMakeLists.txt +++ b/libopenage/gamestate/api/CMakeLists.txt @@ -6,6 +6,7 @@ add_sources(libopenage player_setup.cpp property.cpp sound.cpp + terrain.cpp types.cpp util.cpp ) diff --git a/libopenage/gamestate/api/terrain.cpp b/libopenage/gamestate/api/terrain.cpp new file mode 100644 index 0000000000..bfedb59e4c --- /dev/null +++ b/libopenage/gamestate/api/terrain.cpp @@ -0,0 +1,22 @@ +// Copyright 2023-2023 the openage authors. See copying.md for legal info. + +#include "terrain.h" + +#include + + +namespace openage::gamestate::api { + +bool APITerrain::is_terrain(const nyan::Object &obj) { + nyan::fqon_t immediate_parent = obj.get_parents()[0]; + return immediate_parent == "engine.util.terrain.Terrain"; +} + +const std::string APITerrain::get_terrain_path(const nyan::Object &terrain) { + nyan::Object terrain_texture_obj = terrain.get_object("Terrain.terrain_graphic"); + std::string sprite_path = terrain_texture_obj.get_text("TerrainTexture.sprite"); + + return sprite_path; +} + +} // namespace openage::gamestate::api diff --git a/libopenage/gamestate/api/terrain.h b/libopenage/gamestate/api/terrain.h new file mode 100644 index 0000000000..ef4ca357a8 --- /dev/null +++ b/libopenage/gamestate/api/terrain.h @@ -0,0 +1,35 @@ +// Copyright 2023-2023 the openage authors. See copying.md for legal info. + +#pragma once + +#include + +#include + + +namespace openage::gamestate::api { + +class APITerrain { +public: + /** + * Check if a nyan object is a terrain (type == \p engine.util.terrain.Terrain). + * + * @param obj nyan object handle. + * + * @return true if the object is a terrain, else false. + */ + static bool is_terrain(const nyan::Object &obj); + + /** + * Get the terrain path of a terrain. + * + * The path is relative to the directory the modpack is mounted in. + * + * @param terrain \p Terrain nyan object (type == \p engine.util.terrain.Terrain). + * + * @return Relative path to the terrain file. + */ + static const std::string get_terrain_path(const nyan::Object &terrain); +}; + +} // namespace openage::gamestate::api diff --git a/libopenage/gamestate/event/spawn_entity.cpp b/libopenage/gamestate/event/spawn_entity.cpp index 5cc1cf27df..0cea3cf631 100644 --- a/libopenage/gamestate/event/spawn_entity.cpp +++ b/libopenage/gamestate/event/spawn_entity.cpp @@ -76,6 +76,51 @@ static const std::vector trial_test_entities = { "trial_base.data.game_entity.generic.barracks.barracks.Barracks", }; +// TODO: Remove hardcoded test entity references +static std::vector test_entities; // declared static so we only have to do this once + + +void build_test_entities(const std::shared_ptr &gstate) { + auto modpack_ids = gstate->get_mod_manager()->get_load_order(); + for (auto &modpack_id : modpack_ids) { + if (modpack_id == "aoe1_base") { + test_entities.insert(test_entities.end(), + aoe1_test_entities.begin(), + aoe1_test_entities.end()); + } + else if (modpack_id == "de1_base") { + test_entities.insert(test_entities.end(), + de1_test_entities.begin(), + de1_test_entities.end()); + } + else if (modpack_id == "aoe2_base") { + test_entities.insert(test_entities.end(), + aoe2_test_entities.begin(), + aoe2_test_entities.end()); + } + else if (modpack_id == "de2_base") { + test_entities.insert(test_entities.end(), + de2_test_entities.begin(), + de2_test_entities.end()); + } + else if (modpack_id == "hd_base") { + test_entities.insert(test_entities.end(), + hd_test_entities.begin(), + hd_test_entities.end()); + } + else if (modpack_id == "swgb_base") { + test_entities.insert(test_entities.end(), + swgb_test_entities.begin(), + swgb_test_entities.end()); + } + else if (modpack_id == "trial_base") { + test_entities.insert(test_entities.end(), + trial_test_entities.begin(), + trial_test_entities.end()); + } + } +} + Spawner::Spawner(const std::shared_ptr &loop) : EventEntity(loop) { @@ -113,52 +158,14 @@ void SpawnEntityHandler::invoke(openage::event::EventLoop & /* loop */, auto game_entities = nyan_db->get_obj_children_all("engine.util.game_entity.GameEntity"); - // TODO: Remove hardcoded test entity references - static std::vector test_entities; // declared static so we only have to do this once if (test_entities.empty()) { - auto modpack_ids = gstate->get_mod_manager()->get_load_order(); - for (auto &modpack_id : modpack_ids) { - if (modpack_id == "aoe1_base") { - test_entities.insert(test_entities.end(), - aoe1_test_entities.begin(), - aoe1_test_entities.end()); - } - else if (modpack_id == "de1_base") { - test_entities.insert(test_entities.end(), - de1_test_entities.begin(), - de1_test_entities.end()); - } - else if (modpack_id == "aoe2_base") { - test_entities.insert(test_entities.end(), - aoe2_test_entities.begin(), - aoe2_test_entities.end()); - } - else if (modpack_id == "de2_base") { - test_entities.insert(test_entities.end(), - de2_test_entities.begin(), - de2_test_entities.end()); - } - else if (modpack_id == "hd_base") { - test_entities.insert(test_entities.end(), - hd_test_entities.begin(), - hd_test_entities.end()); - } - else if (modpack_id == "swgb_base") { - test_entities.insert(test_entities.end(), - swgb_test_entities.begin(), - swgb_test_entities.end()); - } - else if (modpack_id == "trial_base") { - test_entities.insert(test_entities.end(), - trial_test_entities.begin(), - trial_test_entities.end()); - } + build_test_entities(gstate); + + // Do nothing if there are no test entities + if (test_entities.empty()) { + return; } } - if (test_entities.empty()) { - // Do nothing because we don't have anything to spawn - return; - } static uint8_t index = 0; nyan::fqon_t nyan_entity = test_entities.at(index); diff --git a/libopenage/gamestate/game.cpp b/libopenage/gamestate/game.cpp index ae85a67171..dfe25b10b5 100644 --- a/libopenage/gamestate/game.cpp +++ b/libopenage/gamestate/game.cpp @@ -129,8 +129,12 @@ void Game::load_path(const util::Path &base_dir, void Game::generate_terrain(const std::shared_ptr &terrain_factory) { auto terrain = terrain_factory->add_terrain(); - auto chunk0 = terrain_factory->add_chunk(util::Vector2s{10, 10}, coord::tile_delta{0, 0}); - auto chunk1 = terrain_factory->add_chunk(util::Vector2s{10, 10}, coord::tile_delta{10, 0}); + auto chunk0 = terrain_factory->add_chunk(this->state, + util::Vector2s{10, 10}, + coord::tile_delta{0, 0}); + auto chunk1 = terrain_factory->add_chunk(this->state, + util::Vector2s{10, 10}, + coord::tile_delta{10, 0}); terrain->add_chunk(chunk0); terrain->add_chunk(chunk1); diff --git a/libopenage/gamestate/terrain_factory.cpp b/libopenage/gamestate/terrain_factory.cpp index 57c2fe121c..2c78d7da83 100644 --- a/libopenage/gamestate/terrain_factory.cpp +++ b/libopenage/gamestate/terrain_factory.cpp @@ -4,15 +4,41 @@ #include +#include + +#include "gamestate/api/terrain.h" #include "gamestate/terrain.h" #include "gamestate/terrain_chunk.h" #include "renderer/render_factory.h" #include "renderer/stages/terrain/terrain_render_entity.h" #include "time/time.h" +#include "assets/mod_manager.h" +#include "gamestate/game_state.h" + namespace openage::gamestate { +static const std::vector aoe1_test_terrain = {}; +static const std::vector de1_test_terrain = {}; +static const std::vector aoe2_test_terrain = { + "aoe2_base.data.terrain.foundation.Foundation", + "aoe2_base.data.terrain.grass.Grass", + "aoe2_base.data.terrain.dirt.Dirt", +}; +static const std::vector de2_test_terrain = {}; +static const std::vector hd_test_terrain = { + "hd_base.data.terrain.foundation.Foundation", + "hd_base.data.terrain.grass.Grass", + "hd_base.data.terrain.dirt.Dirt", +}; +static const std::vector swgb_test_terrain = { + "swgb_base.data.terrain.desert0.Desert0", + "swgb_base.data.terrain.grass2.Grass2", + "swgb_base.data.terrain.foundation.Foundation", +}; +static const std::vector trial_test_terrain = {}; + std::shared_ptr TerrainFactory::add_terrain() { // TODO: Replace this with a proper terrain generator. auto terrain = std::make_shared(); @@ -20,7 +46,53 @@ std::shared_ptr TerrainFactory::add_terrain() { return terrain; } -std::shared_ptr TerrainFactory::add_chunk(const util::Vector2s size, +// TODO: Remove hardcoded test texture references +static std::vector test_terrains; // declare static so we only have to do this once + +void build_test_terrains(const std::shared_ptr &gstate) { + auto modpack_ids = gstate->get_mod_manager()->get_load_order(); + for (auto &modpack_id : modpack_ids) { + if (modpack_id == "aoe1_base") { + test_terrains.insert(test_terrains.end(), + aoe1_test_terrain.begin(), + aoe1_test_terrain.end()); + } + else if (modpack_id == "de1_base") { + test_terrains.insert(test_terrains.end(), + de1_test_terrain.begin(), + de1_test_terrain.end()); + } + else if (modpack_id == "aoe2_base") { + test_terrains.insert(test_terrains.end(), + aoe2_test_terrain.begin(), + aoe2_test_terrain.end()); + } + else if (modpack_id == "de2_base") { + test_terrains.insert(test_terrains.end(), + de2_test_terrain.begin(), + de2_test_terrain.end()); + } + else if (modpack_id == "hd_base") { + test_terrains.insert(test_terrains.end(), + hd_test_terrain.begin(), + hd_test_terrain.end()); + } + else if (modpack_id == "swgb_base") { + test_terrains.insert(test_terrains.end(), + swgb_test_terrain.begin(), + swgb_test_terrain.end()); + } + else if (modpack_id == "trial_base") { + test_terrains.insert(test_terrains.end(), + trial_test_terrain.begin(), + trial_test_terrain.end()); + } + } +} + + +std::shared_ptr TerrainFactory::add_chunk(const std::shared_ptr &gstate, + const util::Vector2s size, const coord::tile_delta offset) { auto chunk = std::make_shared(size, offset); @@ -28,8 +100,27 @@ std::shared_ptr TerrainFactory::add_chunk(const util::Vector2s siz auto render_entity = this->render_factory->add_terrain_render_entity(size, offset); chunk->set_render_entity(render_entity); + std::string test_texture_path = "../test/textures/test_terrain.terrain"; + + // TODO: Remove test texture references + static size_t test_terrain_index = 0; + if (test_terrains.empty()) { + build_test_terrains(gstate); + + // use one of the modpack terrain textures + if (not test_terrains.empty()) { + if (test_terrain_index >= test_terrains.size()) { + test_terrain_index = 0; + } + auto terrain_obj = gstate->get_db_view()->get_object(test_terrains[test_terrain_index]); + test_texture_path = api::APITerrain::get_terrain_path(terrain_obj); + + test_terrain_index += 1; + } + } + chunk->render_update(time::time_t::zero(), - "../test/textures/test_terrain.terrain"); + test_texture_path); } return chunk; diff --git a/libopenage/gamestate/terrain_factory.h b/libopenage/gamestate/terrain_factory.h index 88a86c4fe0..32f804257f 100644 --- a/libopenage/gamestate/terrain_factory.h +++ b/libopenage/gamestate/terrain_factory.h @@ -46,7 +46,8 @@ class TerrainFactory { * * @return New terrain chunk. */ - std::shared_ptr add_chunk(const util::Vector2s size, + std::shared_ptr add_chunk(const std::shared_ptr &gstate, + const util::Vector2s size, const coord::tile_delta offset); // TODO: Add tiles From 045c59355b7535e7d26a5b374d62435f39bef808 Mon Sep 17 00:00:00 2001 From: heinezen Date: Mon, 6 Nov 2023 01:11:48 +0100 Subject: [PATCH 62/95] assets: Use float values for scalefactor. --- assets/test/textures/test_animation.sprite | 2 +- assets/test/textures/test_missing.sprite | 2 +- assets/test/textures/test_terrain.terrain | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/test/textures/test_animation.sprite b/assets/test/textures/test_animation.sprite index 26481ff896..9f96f91b65 100644 --- a/assets/test/textures/test_animation.sprite +++ b/assets/test/textures/test_animation.sprite @@ -5,7 +5,7 @@ version 2 texture 0 "test_texture.texture" -scalefactor 1 +scalefactor 1.0 layer 0 mode=loop position=20 time_per_frame=0.125 diff --git a/assets/test/textures/test_missing.sprite b/assets/test/textures/test_missing.sprite index 00a166e27f..84b7b66676 100644 --- a/assets/test/textures/test_missing.sprite +++ b/assets/test/textures/test_missing.sprite @@ -5,7 +5,7 @@ version 2 texture 0 "test_missing.texture" -scalefactor 1 +scalefactor 1.0 layer 0 mode=once diff --git a/assets/test/textures/test_terrain.terrain b/assets/test/textures/test_terrain.terrain index bbcc8dcd7c..7588a69194 100644 --- a/assets/test/textures/test_terrain.terrain +++ b/assets/test/textures/test_terrain.terrain @@ -5,7 +5,7 @@ version 2 texture 0 "test_terrain.texture" -scalefactor 1 +scalefactor 1.0 layer 0 From 7fd1a6edf1806c7e9bc5a940573d07c72ca0abbd Mon Sep 17 00:00:00 2001 From: heinezen Date: Mon, 6 Nov 2023 01:12:16 +0100 Subject: [PATCH 63/95] convert: Export .terrain definitions. --- .../export/formats/terrain_metadata.py | 15 ++- .../entity_object/export/metadata_export.py | 97 ++++++++++++++++++- .../conversion/aoc/media_subprocessor.py | 48 ++++++++- .../conversion/hd/media_subprocessor.py | 51 +++++++++- 4 files changed, 195 insertions(+), 16 deletions(-) diff --git a/openage/convert/entity_object/export/formats/terrain_metadata.py b/openage/convert/entity_object/export/formats/terrain_metadata.py index 956b44d11e..46ba96b259 100644 --- a/openage/convert/entity_object/export/formats/terrain_metadata.py +++ b/openage/convert/entity_object/export/formats/terrain_metadata.py @@ -158,7 +158,9 @@ def dump(self) -> str: output_str += "\n" # blendtable reference - output_str += f"blendtable {self.blendtable['table_id']} {self.blendtable['filename']}\n\n" + if self.blendtable: + output_str += (f"blendtable {self.blendtable['table_id']} " + "{self.blendtable['filename']}\n\n") # scale factor output_str += f"scalefactor {self.scalefactor}\n\n" @@ -185,7 +187,16 @@ def dump(self) -> str: # frame definitions for frame in self.frames: - output_str += f'frame {" ".join(str(param) for param in frame.values())}\n' + frame_attributes = list(frame.values()) + output_str += f'frame {" ".join(str(param) for param in frame_attributes[:4])}' + + if frame["priority"]: + output_str += f" priority={frame['priority']}" + + if frame["blend_mode"]: + output_str += f" blend_mode={frame['blend_mode']}" + + output_str += "\n" return output_str diff --git a/openage/convert/entity_object/export/metadata_export.py b/openage/convert/entity_object/export/metadata_export.py index a4d2fd35ed..b07b8da2e3 100644 --- a/openage/convert/entity_object/export/metadata_export.py +++ b/openage/convert/entity_object/export/metadata_export.py @@ -11,10 +11,12 @@ from ....util.observer import Observer from .formats.sprite_metadata import SpriteMetadata from .formats.texture_metadata import TextureMetadata +from .formats.terrain_metadata import TerrainMetadata if typing.TYPE_CHECKING: from openage.util.observer import Observable - from openage.convert.entity_object.export.formats.sprite_metadata import LayerMode + from openage.convert.entity_object.export.formats.sprite_metadata import LayerMode as SpriteLayerMode + from openage.convert.entity_object.export.formats.terrain_metadata import LayerMode as TerrainLayerMode class MetadataExport(Observer): @@ -50,7 +52,7 @@ def add_graphics_metadata( self, img_filename: str, tex_filename: str, - layer_mode: LayerMode, + layer_mode: SpriteLayerMode, layer_pos: int, frame_rate: float, replay_delay: float, @@ -62,12 +64,28 @@ def add_graphics_metadata( """ Add metadata from the GenieGraphic object. + :param img_filename: Filename of the exported PNG file. :param tex_filename: Filename of the .texture file. + :param layer_mode: Animation mode (off, once, loop). + :param layer_pos: Layer position. + :param frame_rate: Time spent on each frame. + :param replay_delay: Time delay before replaying the animation. + :param frame_count: Number of frames per angle in the animation. + :param angle_count: Number of angles in the animation. + :param mirror_mode: Mirroring mode (0, 1). If 1, angles above 180 degrees are mirrored. :param start_angle: Angle used for the first frame in the .texture file. """ - self.graphics_metadata[img_filename] = (tex_filename, layer_mode, layer_pos, frame_rate, - replay_delay, frame_count, angle_count, mirror_mode, - start_angle) + self.graphics_metadata[img_filename] = ( + tex_filename, + layer_mode, + layer_pos, + frame_rate, + replay_delay, + frame_count, + angle_count, + mirror_mode, + start_angle + ) def dump(self) -> str: """ @@ -191,3 +209,72 @@ def update(self, observable: Observable, message: dict = None): texture_metadata = message[self.imagefile] self.size = texture_metadata["size"] self.subtex_metadata = texture_metadata["subtex_metadata"] + + +class TerrainMetadataExport(MetadataExport): + """ + Export requests for texture definition files. + """ + + def __init__(self, targetdir, target_filename): + super().__init__(targetdir, target_filename) + + self.graphics_metadata: dict[int, tuple] = {} + self.subtex_count: dict[str, int] = {} + + def add_graphics_metadata( + self, + img_filename: str, + tex_filename: str, + layer_mode: TerrainLayerMode, + layer_pos: int, + frame_rate: float, + replay_delay: float, + frame_count: int, + ): + """ + Add metadata from the GenieGraphic object. + + :param img_filename: Filename of the exported PNG file. + :param tex_filename: Filename of the .texture file. + :param layer_mode: Animation mode (off, loop). + :param layer_pos: Layer position. + :param frame_rate: Time spent on each frame. + :param replay_delay: Time delay before replaying the animation. + :param frame_count: Number of frames in the animation. + """ + self.graphics_metadata[img_filename] = ( + tex_filename, + layer_mode, + layer_pos, + frame_rate, + replay_delay, + frame_count + ) + + def dump(self) -> str: + """ + Creates a human-readable string that can be written to a file. + """ + terrain_file = TerrainMetadata(self.targetdir, self.filename) + + tex_index = 0 + for _, metadata in self.graphics_metadata.items(): + tex_filename = metadata[0] + terrain_file.add_texture(tex_index, tex_filename) + terrain_file.add_layer(tex_index, *metadata[1:5]) + + frame_count = metadata[5] + + for frame_idx in range(frame_count): + subtex_index = frame_idx + terrain_file.add_frame( + frame_idx, + tex_index, + tex_index, + subtex_index + ) + + tex_index += 1 + + return terrain_file.dump() diff --git a/openage/convert/processor/conversion/aoc/media_subprocessor.py b/openage/convert/processor/conversion/aoc/media_subprocessor.py index 360a13b4f7..bb2326e367 100644 --- a/openage/convert/processor/conversion/aoc/media_subprocessor.py +++ b/openage/convert/processor/conversion/aoc/media_subprocessor.py @@ -10,10 +10,12 @@ from openage.convert.value_object.read.media_types import MediaType -from ....entity_object.export.formats.sprite_metadata import LayerMode +from ....entity_object.export.formats.sprite_metadata import LayerMode as SpriteLayerMode +from ....entity_object.export.formats.terrain_metadata import LayerMode as TerrainLayerMode from ....entity_object.export.media_export_request import MediaExportRequest from ....entity_object.export.metadata_export import SpriteMetadataExport from ....entity_object.export.metadata_export import TextureMetadataExport +from ....entity_object.export.metadata_export import TerrainMetadataExport from ....value_object.read.media_types import MediaType if typing.TYPE_CHECKING: @@ -82,13 +84,13 @@ def create_graphics_requests(full_data_set: GenieObjectContainer) -> None: # Add metadata from graphics to animation metadata sequence_type = graphic["sequence_type"].value if sequence_type == 0x00: - layer_mode = LayerMode.OFF + layer_mode = SpriteLayerMode.OFF elif sequence_type & 0x08: - layer_mode = LayerMode.ONCE + layer_mode = SpriteLayerMode.ONCE else: - layer_mode = LayerMode.LOOP + layer_mode = SpriteLayerMode.LOOP layer_pos = graphic["layer"].value frame_rate = round(graphic["frame_rate"].value, ndigits=6) @@ -132,6 +134,44 @@ def create_graphics_requests(full_data_set: GenieObjectContainer) -> None: target_filename) full_data_set.graphics_exports.update({slp_id: export_request}) + texture_meta_filename = f"{texture.get_filename()}.texture" + texture_meta_export = TextureMetadataExport(targetdir, + texture_meta_filename) + full_data_set.metadata_exports.append(texture_meta_export) + + # Add texture image filename to texture metadata + texture_meta_export.add_imagefile(target_filename) + texture_meta_export.update( + None, + { + f"{target_filename}": { + "size": (481, 481), # TODO: Get actual size = sqrt(slp_frame_count) + "subtex_metadata": [ + { + "x": 0, + "y": 0, + "w": 481, + "h": 481, + "cx": 0, + "cy": 0, + } + ] + }} + ) + + terrain_meta_filename = f"{texture.get_filename()}.terrain" + terrain_meta_export = TerrainMetadataExport(targetdir, + terrain_meta_filename) + full_data_set.metadata_exports.append(terrain_meta_export) + + terrain_meta_export.add_graphics_metadata(target_filename, + texture_meta_filename, + TerrainLayerMode.OFF, + 0, + 0.0, + 0.0, + 1) + @staticmethod def create_blend_requests(full_data_set: GenieObjectContainer) -> None: """ diff --git a/openage/convert/processor/conversion/hd/media_subprocessor.py b/openage/convert/processor/conversion/hd/media_subprocessor.py index 935643efa0..74d4c5350d 100644 --- a/openage/convert/processor/conversion/hd/media_subprocessor.py +++ b/openage/convert/processor/conversion/hd/media_subprocessor.py @@ -9,9 +9,12 @@ from __future__ import annotations import typing -from ....entity_object.export.formats.sprite_metadata import LayerMode +from ....entity_object.export.formats.sprite_metadata import LayerMode as SpriteLayerMode +from ....entity_object.export.formats.terrain_metadata import LayerMode as TerrainLayerMode from ....entity_object.export.media_export_request import MediaExportRequest -from ....entity_object.export.metadata_export import SpriteMetadataExport, TextureMetadataExport +from ....entity_object.export.metadata_export import SpriteMetadataExport +from ....entity_object.export.metadata_export import TextureMetadataExport +from ....entity_object.export.metadata_export import TerrainMetadataExport from ....value_object.read.media_types import MediaType if typing.TYPE_CHECKING: @@ -77,13 +80,13 @@ def create_graphics_requests(full_data_set: GenieObjectContainer) -> None: # Add metadata from graphics to animation metadata sequence_type = graphic["sequence_type"].value if sequence_type == 0x00: - layer_mode = LayerMode.OFF + layer_mode = SpriteLayerMode.OFF elif sequence_type & 0x08: - layer_mode = LayerMode.ONCE + layer_mode = SpriteLayerMode.ONCE else: - layer_mode = LayerMode.LOOP + layer_mode = SpriteLayerMode.LOOP layer_pos = graphic["layer"].value frame_rate = round(graphic["frame_rate"].value, ndigits=6) @@ -128,6 +131,44 @@ def create_graphics_requests(full_data_set: GenieObjectContainer) -> None: target_filename) full_data_set.graphics_exports.update({slp_id: export_request}) + texture_meta_filename = f"{texture.get_filename()}.texture" + texture_meta_export = TextureMetadataExport(targetdir, + texture_meta_filename) + full_data_set.metadata_exports.append(texture_meta_export) + + # Add texture image filename to texture metadata + texture_meta_export.add_imagefile(target_filename) + texture_meta_export.update( + None, + { + f"{target_filename}": { + "size": (512, 512), + "subtex_metadata": [ + { + "x": 0, + "y": 0, + "w": 512, + "h": 512, + "cx": 0, + "cy": 0, + } + ] + }} + ) + + terrain_meta_filename = f"{texture.get_filename()}.terrain" + terrain_meta_export = TerrainMetadataExport(targetdir, + terrain_meta_filename) + full_data_set.metadata_exports.append(terrain_meta_export) + + terrain_meta_export.add_graphics_metadata(target_filename, + texture_meta_filename, + TerrainLayerMode.OFF, + 0, + 0.0, + 0.0, + 1) + @staticmethod def create_sound_requests(full_data_set: GenieObjectContainer) -> None: """ From 46acfce7e31d3099ba0deaa0a352810855e8a237 Mon Sep 17 00:00:00 2001 From: heinezen Date: Mon, 6 Nov 2023 01:16:45 +0100 Subject: [PATCH 64/95] gamestate: Fix getting terrain path from modpack. --- libopenage/gamestate/api/terrain.cpp | 6 ++- libopenage/gamestate/game.cpp | 2 +- libopenage/gamestate/terrain.cpp | 3 +- libopenage/gamestate/terrain_chunk.cpp | 13 ++++++ libopenage/gamestate/terrain_chunk.h | 13 ++++++ libopenage/gamestate/terrain_factory.cpp | 56 ++++++++++++------------ 6 files changed, 61 insertions(+), 32 deletions(-) diff --git a/libopenage/gamestate/api/terrain.cpp b/libopenage/gamestate/api/terrain.cpp index bfedb59e4c..e69edee5fc 100644 --- a/libopenage/gamestate/api/terrain.cpp +++ b/libopenage/gamestate/api/terrain.cpp @@ -4,6 +4,8 @@ #include +#include "gamestate/api/util.h" + namespace openage::gamestate::api { @@ -14,9 +16,9 @@ bool APITerrain::is_terrain(const nyan::Object &obj) { const std::string APITerrain::get_terrain_path(const nyan::Object &terrain) { nyan::Object terrain_texture_obj = terrain.get_object("Terrain.terrain_graphic"); - std::string sprite_path = terrain_texture_obj.get_text("TerrainTexture.sprite"); + std::string terrain_path = terrain_texture_obj.get_file("Terrain.sprite"); - return sprite_path; + return resolve_file_path(terrain, terrain_path); } } // namespace openage::gamestate::api diff --git a/libopenage/gamestate/game.cpp b/libopenage/gamestate/game.cpp index dfe25b10b5..edad807607 100644 --- a/libopenage/gamestate/game.cpp +++ b/libopenage/gamestate/game.cpp @@ -105,7 +105,7 @@ void Game::load_path(const util::Path &base_dir, }; // file loading - if (search_path.is_file() && search_path.get_suffix() == ".nyan") { + if (search_path.is_file() and search_path.get_suffix() == ".nyan") { auto loc = mod_dir + "/" + search; this->db->load(loc, fileload_func); return; diff --git a/libopenage/gamestate/terrain.cpp b/libopenage/gamestate/terrain.cpp index f2b790e0a7..6a733a86d7 100644 --- a/libopenage/gamestate/terrain.cpp +++ b/libopenage/gamestate/terrain.cpp @@ -32,8 +32,7 @@ void Terrain::attach_renderer(const std::shared_ptr &re chunk->get_offset()); chunk->set_render_entity(render_entity); - chunk->render_update(time::time_t::zero(), - "../test/textures/test_terrain.terrain"); + chunk->render_update(time::time_t::zero()); } } diff --git a/libopenage/gamestate/terrain_chunk.cpp b/libopenage/gamestate/terrain_chunk.cpp index 6ba3338d7b..d8adb2ccd0 100644 --- a/libopenage/gamestate/terrain_chunk.cpp +++ b/libopenage/gamestate/terrain_chunk.cpp @@ -45,4 +45,17 @@ const coord::tile_delta &TerrainChunk::get_offset() const { return this->offset; } +void TerrainChunk::set_terrain_path(const std::string &terrain_path) { + this->terrain_path = terrain_path; +} + +void TerrainChunk::render_update(const time::time_t &time) { + if (this->render_entity != nullptr) { + this->render_entity->update(this->size, + this->height_map, + this->terrain_path, + time); + } +} + } // namespace openage::gamestate diff --git a/libopenage/gamestate/terrain_chunk.h b/libopenage/gamestate/terrain_chunk.h index 191ee8f185..4b51fa6d6d 100644 --- a/libopenage/gamestate/terrain_chunk.h +++ b/libopenage/gamestate/terrain_chunk.h @@ -55,6 +55,16 @@ class TerrainChunk { */ const coord::tile_delta &get_offset() const; + // TODO: Remove test texture references + + // Set the terrain path of this terrain chunk. + // TODO: Remove later + void set_terrain_path(const std::string &terrain_path); + + // Send the current texture to the renderer. + // TODO: Replace later with render_update(time, terrain_path) + void render_update(const time::time_t &time); + private: /** * Size of the terrain chunk. @@ -77,6 +87,9 @@ class TerrainChunk { * Render entity for pushing updates to the renderer. Can be \p nullptr. */ std::shared_ptr render_entity; + + // TODO: Remove test texture references + std::string terrain_path; }; } // namespace openage::gamestate diff --git a/libopenage/gamestate/terrain_factory.cpp b/libopenage/gamestate/terrain_factory.cpp index 2c78d7da83..5801ed1892 100644 --- a/libopenage/gamestate/terrain_factory.cpp +++ b/libopenage/gamestate/terrain_factory.cpp @@ -22,20 +22,20 @@ namespace openage::gamestate { static const std::vector aoe1_test_terrain = {}; static const std::vector de1_test_terrain = {}; static const std::vector aoe2_test_terrain = { - "aoe2_base.data.terrain.foundation.Foundation", - "aoe2_base.data.terrain.grass.Grass", - "aoe2_base.data.terrain.dirt.Dirt", + "aoe2_base.data.terrain.foundation.foundation.Foundation", + "aoe2_base.data.terrain.grass.grass.Grass", + "aoe2_base.data.terrain.dirt.dirt.Dirt", }; static const std::vector de2_test_terrain = {}; static const std::vector hd_test_terrain = { - "hd_base.data.terrain.foundation.Foundation", - "hd_base.data.terrain.grass.Grass", - "hd_base.data.terrain.dirt.Dirt", + "hd_base.data.terrain.foundation.foundation.Foundation", + "hd_base.data.terrain.grass.grass.Grass", + "hd_base.data.terrain.dirt.dirt.Dirt", }; static const std::vector swgb_test_terrain = { - "swgb_base.data.terrain.desert0.Desert0", - "swgb_base.data.terrain.grass2.Grass2", - "swgb_base.data.terrain.foundation.Foundation", + "swgb_base.data.terrain.desert0.desert0.Desert0", + "swgb_base.data.terrain.grass2.grass2.Grass2", + "swgb_base.data.terrain.foundation.foundation.Foundation", }; static const std::vector trial_test_terrain = {}; @@ -96,33 +96,35 @@ std::shared_ptr TerrainFactory::add_chunk(const std::shared_ptr(size, offset); + // TODO: Remove test texture references + std::string test_texture_path = "../test/textures/test_terrain.terrain"; + if (this->render_factory) { auto render_entity = this->render_factory->add_terrain_render_entity(size, offset); chunk->set_render_entity(render_entity); - std::string test_texture_path = "../test/textures/test_terrain.terrain"; - - // TODO: Remove test texture references - static size_t test_terrain_index = 0; - if (test_terrains.empty()) { - build_test_terrains(gstate); - - // use one of the modpack terrain textures - if (not test_terrains.empty()) { - if (test_terrain_index >= test_terrains.size()) { - test_terrain_index = 0; - } - auto terrain_obj = gstate->get_db_view()->get_object(test_terrains[test_terrain_index]); - test_texture_path = api::APITerrain::get_terrain_path(terrain_obj); + chunk->render_update(time::time_t::zero(), + test_texture_path); + } - test_terrain_index += 1; - } + // TODO: Remove test texture references + if (test_terrains.empty()) { + build_test_terrains(gstate); + } + static size_t test_terrain_index = 0; + if (not test_terrains.empty()) { + // use one of the modpack terrain textures + if (test_terrain_index >= test_terrains.size()) { + test_terrain_index = 0; } + auto terrain_obj = gstate->get_db_view()->get_object(test_terrains[test_terrain_index]); + test_texture_path = api::APITerrain::get_terrain_path(terrain_obj); - chunk->render_update(time::time_t::zero(), - test_texture_path); + test_terrain_index += 1; } + chunk->set_terrain_path(test_texture_path); + return chunk; } From cb669af4d8286d4884e8bf9cba28127af3d4ba4d Mon Sep 17 00:00:00 2001 From: heinezen Date: Mon, 6 Nov 2023 22:35:58 +0100 Subject: [PATCH 65/95] input: Fix error when selection callback is missing. --- libopenage/gamestate/event/spawn_entity.cpp | 2 +- libopenage/input/controller/game/binding.h | 3 ++- libopenage/input/controller/game/controller.cpp | 16 ++++++++-------- libopenage/input/controller/game/controller.h | 3 ++- libopenage/input/input_manager.cpp | 6 +++--- libopenage/input/input_manager.h | 8 ++++---- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/libopenage/gamestate/event/spawn_entity.cpp b/libopenage/gamestate/event/spawn_entity.cpp index 0cea3cf631..9558cba2a3 100644 --- a/libopenage/gamestate/event/spawn_entity.cpp +++ b/libopenage/gamestate/event/spawn_entity.cpp @@ -197,7 +197,7 @@ void SpawnEntityHandler::invoke(openage::event::EventLoop & /* loop */, // TODO: Select the unit when it's created // very dumb but it gets the job done - auto select_cb = params.get("select_cb", std::function{}); + auto select_cb = params.get("select_cb", std::function{[](entity_id_t /* id */) {}}); select_cb(entity->get_id()); gstate->add_game_entity(entity); diff --git a/libopenage/input/controller/game/binding.h b/libopenage/input/controller/game/binding.h index abddb2385f..8b94dd8875 100644 --- a/libopenage/input/controller/game/binding.h +++ b/libopenage/input/controller/game/binding.h @@ -3,6 +3,7 @@ #pragma once #include +#include #include #include "event/event.h" @@ -14,7 +15,7 @@ class Controller; using binding_flags_t = std::unordered_map; using binding_func_t = std::function(const event_arguments &, - const Controller &)>; + const std::shared_ptr)>; /** diff --git a/libopenage/input/controller/game/controller.cpp b/libopenage/input/controller/game/controller.cpp index d12f7e1135..7a17de186a 100644 --- a/libopenage/input/controller/game/controller.cpp +++ b/libopenage/input/controller/game/controller.cpp @@ -60,7 +60,8 @@ bool Controller::process(const event_arguments &ev_args, const std::shared_ptrlookup(ev_args.e); - auto game_event = bind.transform(ev_args, *this); + auto controller = this->shared_from_this(); + auto game_event = bind.transform(ev_args, controller); switch (bind.action_type) { case forward_action_t::SEND: @@ -90,15 +91,14 @@ void setup_defaults(const std::shared_ptr &ctx, const std::shared_ptr &simulation, const std::shared_ptr &camera) { binding_func_t create_entity_event{[&](const event_arguments &args, - const Controller &controller) { + const std::shared_ptr controller) { auto mouse_pos = args.mouse.to_phys3(camera); event::EventHandler::param_map::map_t params{ {"position", mouse_pos}, - {"owner", controller.get_controlled()}, + {"owner", controller->get_controlled()}, // TODO: Remove - {"select_cb", std::function{[&controller](gamestate::entity_id_t id) { - auto &mut_controller = const_cast(controller); - mut_controller.set_selected({id}); + {"select_cb", std::function{[controller](gamestate::entity_id_t id) { + controller->set_selected({id}); }}}, }; @@ -117,12 +117,12 @@ void setup_defaults(const std::shared_ptr &ctx, ctx->bind(ev_mouse_lmb, create_entity_action); binding_func_t move_entity{[&](const event_arguments &args, - const Controller &controller) { + const std::shared_ptr controller) { auto mouse_pos = args.mouse.to_phys3(camera); event::EventHandler::param_map::map_t params{ {"type", gamestate::component::command::command_t::MOVE}, {"target", mouse_pos}, - {"entity_ids", controller.get_selected()}, + {"entity_ids", controller->get_selected()}, }; auto event = simulation->get_event_loop()->create_event( diff --git a/libopenage/input/controller/game/controller.h b/libopenage/input/controller/game/controller.h index 2ef4439087..847a5999f5 100644 --- a/libopenage/input/controller/game/controller.h +++ b/libopenage/input/controller/game/controller.h @@ -2,6 +2,7 @@ #pragma once +#include #include #include @@ -32,7 +33,7 @@ class BindingContext; * * TODO: Connection to engine */ -class Controller { +class Controller : public std::enable_shared_from_this { public: Controller(const std::unordered_set &controlled_factions, size_t active_faction_id); diff --git a/libopenage/input/input_manager.cpp b/libopenage/input/input_manager.cpp index 47ff5c1834..f9d729b9ba 100644 --- a/libopenage/input/input_manager.cpp +++ b/libopenage/input/input_manager.cpp @@ -19,15 +19,15 @@ InputManager::InputManager() : gui_input{nullptr} { } -void InputManager::set_gui(const std::shared_ptr &gui_input) { +void InputManager::set_gui(const std::shared_ptr gui_input) { this->gui_input = gui_input; } -void InputManager::set_camera_controller(const std::shared_ptr &controller) { +void InputManager::set_camera_controller(const std::shared_ptr controller) { this->camera_controller = controller; } -void InputManager::set_engine_controller(const std::shared_ptr &controller) { +void InputManager::set_engine_controller(const std::shared_ptr controller) { this->engine_controller = controller; } diff --git a/libopenage/input/input_manager.h b/libopenage/input/input_manager.h index 7b6403eeaa..17e66a28be 100644 --- a/libopenage/input/input_manager.h +++ b/libopenage/input/input_manager.h @@ -24,7 +24,7 @@ class Controller; namespace game { class Controller; -} // namespace engine +} // namespace game class InputContext; @@ -43,21 +43,21 @@ class InputManager { * * @param gui_input GUI input handler. */ - void set_gui(const std::shared_ptr &gui_input); + void set_gui(const std::shared_ptr gui_input); /** * Set the controller for the camera. * * @param controller Camera controller. */ - void set_camera_controller(const std::shared_ptr &controller); + void set_camera_controller(const std::shared_ptr controller); /** * Set the controller for the engine. * * @param controller Engine controller. */ - void set_engine_controller(const std::shared_ptr &controller); + void set_engine_controller(const std::shared_ptr controller); /** * returns the global keybind context. From 83b16daa262782265ffe7f9aa186bb2ba5d63b4f Mon Sep 17 00:00:00 2001 From: heinezen Date: Mon, 6 Nov 2023 22:42:53 +0100 Subject: [PATCH 66/95] gui: Remove remaining mentions of SDL. --- doc/code/gui.md | 12 +++++------ .../renderer/gui/guisys/link/gui_item.h | 4 ++-- .../renderer/gui/guisys/link/gui_item_link.h | 2 +- .../gui/guisys/link/gui_property_map_impl.cpp | 2 +- ...tic_cast.h => qtgui_checked_static_cast.h} | 0 .../guisys/private/gui_application_impl.cpp | 20 +++++++++---------- .../gui/guisys/private/gui_application_impl.h | 8 ++++---- .../gui/guisys/private/opengl_debug_logger.h | 2 +- .../gui/guisys/public/gui_application.cpp | 8 +++----- 9 files changed, 27 insertions(+), 31 deletions(-) rename libopenage/renderer/gui/guisys/link/{qtsdl_checked_static_cast.h => qtgui_checked_static_cast.h} (100%) diff --git a/doc/code/gui.md b/doc/code/gui.md index 6c548c2b65..3f1a4afb17 100644 --- a/doc/code/gui.md +++ b/doc/code/gui.md @@ -51,7 +51,7 @@ qmlRegisterType("yay.sfttech.openage", 1, 0, "ResourceAmount 2. Specializations `struct Wrap` and `struct Unwrap` must be defined: ```cpp -namespace qtsdl { +namespace qtgui { template<> struct Wrap { using Type = ResourceAmountLink; @@ -61,13 +61,13 @@ template<> struct Unwrap { using Type = ResourceAmount; }; -} // namespace qtsdl +} // namespace qtgui ``` 3. Also ResourceAmount needs a public member to be added: ```cpp public: - qtsdl::GuiItemLink *gui_link + qtgui::GuiItemLink *gui_link ``` 4. Declare and implement needed properties and signals in the `ResourceAmountLink` using Qt property syntax. @@ -78,7 +78,7 @@ There is a class `GeneratorParameters` in `libopenage/` directory. It has a big list of parameters of different types like `generation_seed`, `player_radius`, `player_names`, etc. So, we're not going to write a Qt property for each one: -1. `GeneratorParameters` must derive from the `qtsdl::GuiPropertyMap`. +1. `GeneratorParameters` must derive from the `qtgui::GuiPropertyMap`. 2. `GeneratorParameters` should set its initial values like so: ```cpp @@ -96,7 +96,7 @@ qmlRegisterType("yay.sfttech.openage", 1, 0, "Generator 4. Specializations `struct Wrap` and `struct Unwrap` must be defined: ```cpp -namespace qtsdl { +namespace qtgui { template<> struct Wrap { using Type = GeneratorParametersLink; @@ -106,7 +106,7 @@ template<> struct Unwrap { using Type = GeneratorParameters; }; -} // namespace qtsdl +} // namespace qtgui ``` That results into a `ListModel`-like QML type with `display` and `edit` roles. diff --git a/libopenage/renderer/gui/guisys/link/gui_item.h b/libopenage/renderer/gui/guisys/link/gui_item.h index 450d3dc796..9f8a5bd59f 100644 --- a/libopenage/renderer/gui/guisys/link/gui_item.h +++ b/libopenage/renderer/gui/guisys/link/gui_item.h @@ -15,14 +15,14 @@ #include #include "renderer/gui/guisys/link/gui_item_link.h" -#include "renderer/gui/guisys/link/qtsdl_checked_static_cast.h" +#include "renderer/gui/guisys/link/qtgui_checked_static_cast.h" #include "renderer/gui/guisys/private/livereload/deferred_initial_constant_property_values.h" namespace qtgui { /** - * Cleans a text from unneeded content like "qtsdl". + * Cleans a text from unneeded content like "qtgui". */ QString name_tidier(const char *name); diff --git a/libopenage/renderer/gui/guisys/link/gui_item_link.h b/libopenage/renderer/gui/guisys/link/gui_item_link.h index 0bd7b8d61f..0965aa2b4d 100644 --- a/libopenage/renderer/gui/guisys/link/gui_item_link.h +++ b/libopenage/renderer/gui/guisys/link/gui_item_link.h @@ -5,7 +5,7 @@ #include #include -#include "renderer/gui/guisys/link/qtsdl_checked_static_cast.h" +#include "renderer/gui/guisys/link/qtgui_checked_static_cast.h" namespace qtgui { diff --git a/libopenage/renderer/gui/guisys/link/gui_property_map_impl.cpp b/libopenage/renderer/gui/guisys/link/gui_property_map_impl.cpp index 1a8e8b7db3..d6204ae719 100644 --- a/libopenage/renderer/gui/guisys/link/gui_property_map_impl.cpp +++ b/libopenage/renderer/gui/guisys/link/gui_property_map_impl.cpp @@ -5,7 +5,7 @@ #include #include -#include "renderer/gui/guisys/link/qtsdl_checked_static_cast.h" +#include "renderer/gui/guisys/link/qtgui_checked_static_cast.h" namespace qtgui { diff --git a/libopenage/renderer/gui/guisys/link/qtsdl_checked_static_cast.h b/libopenage/renderer/gui/guisys/link/qtgui_checked_static_cast.h similarity index 100% rename from libopenage/renderer/gui/guisys/link/qtsdl_checked_static_cast.h rename to libopenage/renderer/gui/guisys/link/qtgui_checked_static_cast.h diff --git a/libopenage/renderer/gui/guisys/private/gui_application_impl.cpp b/libopenage/renderer/gui/guisys/private/gui_application_impl.cpp index c0ef0dd1b7..fb8674b69e 100644 --- a/libopenage/renderer/gui/guisys/private/gui_application_impl.cpp +++ b/libopenage/renderer/gui/guisys/private/gui_application_impl.cpp @@ -2,12 +2,12 @@ #include "gui_application_impl.h" -#include #include +#include #include -#include #include +#include namespace qtgui { @@ -41,22 +41,20 @@ void GuiApplicationImpl::processEvents() { } namespace { - int argc = 1; - char arg[] = "qtsdl"; - char *argv = &arg[0]; -} +int argc = 1; +char arg[] = "qtgui"; +char *argv = &arg[0]; +} // namespace -GuiApplicationImpl::GuiApplicationImpl() - : +GuiApplicationImpl::GuiApplicationImpl() : #ifndef NDEBUG owner{std::this_thread::get_id()}, #endif - app{argc, &argv} -{ + app{argc, &argv} { // Set locale back to POSIX for the decimal point parsing (see qcoreapplication.html#locale-settings). std::locale::global(std::locale().combine>(std::locale::classic())); qInfo() << "Compiled with Qt" << QT_VERSION_STR << "and run with Qt" << qVersion(); } -} // namespace qtsdl +} // namespace qtgui diff --git a/libopenage/renderer/gui/guisys/private/gui_application_impl.h b/libopenage/renderer/gui/guisys/private/gui_application_impl.h index 7294cf8827..f772c77a0f 100644 --- a/libopenage/renderer/gui/guisys/private/gui_application_impl.h +++ b/libopenage/renderer/gui/guisys/private/gui_application_impl.h @@ -2,8 +2,8 @@ #pragma once -#include #include +#include #include @@ -12,7 +12,7 @@ namespace qtgui { /** * Houses gui logic event queue. * - * To launch it in a dedicated thread, use qtsdl::GuiDedicatedThread instead. + * To launch it in a dedicated thread, use qtgui::GuiDedicatedThread instead. */ class GuiApplicationImpl { public: @@ -25,8 +25,8 @@ class GuiApplicationImpl { private: GuiApplicationImpl(); - GuiApplicationImpl(const GuiApplicationImpl&) = delete; - GuiApplicationImpl& operator=(const GuiApplicationImpl&) = delete; + GuiApplicationImpl(const GuiApplicationImpl &) = delete; + GuiApplicationImpl &operator=(const GuiApplicationImpl &) = delete; #ifndef NDEBUG const std::thread::id owner; diff --git a/libopenage/renderer/gui/guisys/private/opengl_debug_logger.h b/libopenage/renderer/gui/guisys/private/opengl_debug_logger.h index f2763c96e7..3c297e197f 100644 --- a/libopenage/renderer/gui/guisys/private/opengl_debug_logger.h +++ b/libopenage/renderer/gui/guisys/private/opengl_debug_logger.h @@ -40,4 +40,4 @@ gl_debug_parameters get_current_opengl_debug_parameters(QOpenGLContext ¤t_ */ void apply_opengl_debug_parameters(gl_debug_parameters params, QOpenGLContext ¤t_dest_context); -} // namespace qtsdl +} // namespace qtgui diff --git a/libopenage/renderer/gui/guisys/public/gui_application.cpp b/libopenage/renderer/gui/guisys/public/gui_application.cpp index 08a93aa42d..80cba97bd2 100644 --- a/libopenage/renderer/gui/guisys/public/gui_application.cpp +++ b/libopenage/renderer/gui/guisys/public/gui_application.cpp @@ -8,13 +8,11 @@ namespace qtgui { -GuiApplication::GuiApplication() - : +GuiApplication::GuiApplication() : application{GuiApplicationImpl::get()} { } -GuiApplication::GuiApplication(std::shared_ptr application) - : +GuiApplication::GuiApplication(std::shared_ptr application) : application{application} { } @@ -24,4 +22,4 @@ void GuiApplication::process_events() { this->application->processEvents(); } -} // namespace qtsdl +} // namespace qtgui From 9d6a038b8f200428955eb7991114df937fb7f06f Mon Sep 17 00:00:00 2001 From: heinezen Date: Tue, 7 Nov 2023 01:46:16 +0100 Subject: [PATCH 67/95] engine: Fix capture of argument in thread function. --- libopenage/engine/engine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libopenage/engine/engine.cpp b/libopenage/engine/engine.cpp index 9af6d4fe89..fa2c251b4d 100644 --- a/libopenage/engine/engine.cpp +++ b/libopenage/engine/engine.cpp @@ -55,7 +55,7 @@ Engine::Engine(mode mode, // if presenter is used, run it in a separate thread if (this->run_mode == mode::FULL) { - this->threads.emplace_back([&]() { + this->threads.emplace_back([&, debug_graphics]() { this->presenter->run(debug_graphics); // Make sure that the presenter gets destructed in the same thread From eb84b4c78e98de93935e201374931d208999ce53 Mon Sep 17 00:00:00 2001 From: heinezen Date: Fri, 10 Nov 2023 22:37:01 +0100 Subject: [PATCH 68/95] renderer: Use correct world space transformation for terrain model. --- libopenage/gamestate/game.cpp | 8 ++++++++ libopenage/renderer/stages/terrain/terrain_mesh.cpp | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/libopenage/gamestate/game.cpp b/libopenage/gamestate/game.cpp index edad807607..121bef4f56 100644 --- a/libopenage/gamestate/game.cpp +++ b/libopenage/gamestate/game.cpp @@ -135,8 +135,16 @@ void Game::generate_terrain(const std::shared_ptr &terrain_facto auto chunk1 = terrain_factory->add_chunk(this->state, util::Vector2s{10, 10}, coord::tile_delta{10, 0}); + auto chunk2 = terrain_factory->add_chunk(this->state, + util::Vector2s{10, 10}, + coord::tile_delta{0, 10}); + auto chunk3 = terrain_factory->add_chunk(this->state, + util::Vector2s{10, 10}, + coord::tile_delta{10, 10}); terrain->add_chunk(chunk0); terrain->add_chunk(chunk1); + terrain->add_chunk(chunk2); + terrain->add_chunk(chunk3); this->state->set_terrain(terrain); } diff --git a/libopenage/renderer/stages/terrain/terrain_mesh.cpp b/libopenage/renderer/stages/terrain/terrain_mesh.cpp index 88b471c22f..b02f867050 100644 --- a/libopenage/renderer/stages/terrain/terrain_mesh.cpp +++ b/libopenage/renderer/stages/terrain/terrain_mesh.cpp @@ -100,7 +100,7 @@ const std::shared_ptr &TerrainRenderMesh::get_uniforms() void TerrainRenderMesh::create_model_matrix(const coord::scene2_delta &offset) { // TODO: Needs input from engine auto model = Eigen::Affine3f::Identity(); - model.translate(Eigen::Vector3f{offset.ne.to_float(), offset.se.to_float(), 0.0f}); + model.translate(offset.to_world_space()); this->model_matrix = model.matrix(); } From fd7f28a4c4b56e4acde4bdccaf81f64d99f1af7f Mon Sep 17 00:00:00 2001 From: heinezen Date: Fri, 10 Nov 2023 22:40:27 +0100 Subject: [PATCH 69/95] doc: Update run instructions. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 00d3715d85..db9b9a4a82 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ Quickstart ``` * **I compiled everything. Now how do I run it?** - * Execute `./bin/run`. + * Execute `cd bin && ./run main`. * [The convert script](/doc/media_convert.md) will transform original assets into openage formats, which are a lot saner and more moddable. * Use your brain and react to the things you'll see. From e1eee5e2211af49219b4255f3ae3f0ed4469bec2 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 11 Nov 2023 20:33:54 +0100 Subject: [PATCH 70/95] gamestate: Terrain tile definition. --- libopenage/gamestate/CMakeLists.txt | 1 + libopenage/gamestate/terrain_tile.cpp | 7 ++++++ libopenage/gamestate/terrain_tile.h | 31 +++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 libopenage/gamestate/terrain_tile.cpp create mode 100644 libopenage/gamestate/terrain_tile.h diff --git a/libopenage/gamestate/CMakeLists.txt b/libopenage/gamestate/CMakeLists.txt index c7cdaebee2..a94cd93514 100644 --- a/libopenage/gamestate/CMakeLists.txt +++ b/libopenage/gamestate/CMakeLists.txt @@ -9,6 +9,7 @@ add_sources(libopenage simulation.cpp terrain_chunk.cpp terrain_factory.cpp + terrain_tile.cpp terrain.cpp types.cpp world.cpp diff --git a/libopenage/gamestate/terrain_tile.cpp b/libopenage/gamestate/terrain_tile.cpp new file mode 100644 index 0000000000..945c848d73 --- /dev/null +++ b/libopenage/gamestate/terrain_tile.cpp @@ -0,0 +1,7 @@ +// Copyright 2023-2023 the openage authors. See copying.md for legal info. + +#include "terrain_tile.h" + + +namespace openage::gamestate { +} diff --git a/libopenage/gamestate/terrain_tile.h b/libopenage/gamestate/terrain_tile.h new file mode 100644 index 0000000000..b2b8e2dcc3 --- /dev/null +++ b/libopenage/gamestate/terrain_tile.h @@ -0,0 +1,31 @@ +// Copyright 2023-2023 the openage authors. See copying.md for legal info. + +#pragma once + +#include + +#include + +#include "util/fixed_point.h" + + +namespace openage::gamestate { + +using terrain_elevation_t = util::FixedPoint; + +/** + * A single terrain tile. + */ +struct TerrainTile { + /** + * Terrain definition used by this tile. + */ + nyan::Object terrain; + + /** + * Height of this tile on the terrain. + */ + terrain_elevation_t elevation; +}; + +} // namespace openage::gamestate From 1f7ea144536fe817c1b6b7e430f1fd744daca290 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 11 Nov 2023 21:57:52 +0100 Subject: [PATCH 71/95] gamestate: Replace terrain height map with tiles. --- libopenage/gamestate/terrain_chunk.cpp | 31 +++++++------ libopenage/gamestate/terrain_chunk.h | 6 ++- libopenage/gamestate/terrain_factory.cpp | 35 +++++++++------ libopenage/gamestate/terrain_tile.cpp | 5 ++- libopenage/gamestate/terrain_tile.h | 12 +++++- libopenage/renderer/demo/demo_3.cpp | 34 +++++++-------- libopenage/renderer/demo/stresstest_0.cpp | 10 ++--- .../stages/terrain/terrain_render_entity.cpp | 43 +++++++++++++++---- .../stages/terrain/terrain_render_entity.h | 34 +++++++++++---- 9 files changed, 140 insertions(+), 70 deletions(-) diff --git a/libopenage/gamestate/terrain_chunk.cpp b/libopenage/gamestate/terrain_chunk.cpp index d8adb2ccd0..a6d10251b1 100644 --- a/libopenage/gamestate/terrain_chunk.cpp +++ b/libopenage/gamestate/terrain_chunk.cpp @@ -6,21 +6,16 @@ namespace openage::gamestate { TerrainChunk::TerrainChunk(const util::Vector2s size, - const coord::tile_delta offset) : + const coord::tile_delta offset, + const std::vector &&tiles) : size{size}, offset{offset}, - height_map{} { + tiles{tiles} { if (this->size[0] > MAX_CHUNK_WIDTH || this->size[1] > MAX_CHUNK_HEIGHT) { throw Error(MSG(err) << "Terrain chunk size exceeds maximum size: " << this->size[0] << "x" << this->size[1] << " > " << MAX_CHUNK_WIDTH << "x" << MAX_CHUNK_HEIGHT); } - - // fill the terrain grid with height values - this->height_map.reserve(this->size[0] * this->size[1]); - for (size_t i = 0; i < this->size[0] * this->size[1]; ++i) { - this->height_map.push_back(0.0f); - } } void TerrainChunk::set_render_entity(const std::shared_ptr &entity) { @@ -30,9 +25,15 @@ void TerrainChunk::set_render_entity(const std::shared_ptrrender_entity != nullptr) { + // TODO: Update individual tiles instead of the whole chunk + std::vector> tiles; + tiles.reserve(this->tiles.size()); + for (const auto &tile : this->tiles) { + tiles.emplace_back(tile.elevation, terrain_path); + } + this->render_entity->update(this->size, - this->height_map, - terrain_path, + tiles, time); } } @@ -51,9 +52,15 @@ void TerrainChunk::set_terrain_path(const std::string &terrain_path) { void TerrainChunk::render_update(const time::time_t &time) { if (this->render_entity != nullptr) { + // TODO: Update individual tiles instead of the whole chunk + std::vector> tiles; + tiles.reserve(this->tiles.size()); + for (const auto &tile : this->tiles) { + tiles.emplace_back(tile.elevation, terrain_path); + } + this->render_entity->update(this->size, - this->height_map, - this->terrain_path, + tiles, time); } } diff --git a/libopenage/gamestate/terrain_chunk.h b/libopenage/gamestate/terrain_chunk.h index 4b51fa6d6d..df9091a321 100644 --- a/libopenage/gamestate/terrain_chunk.h +++ b/libopenage/gamestate/terrain_chunk.h @@ -5,6 +5,7 @@ #include #include "coord/tile.h" +#include "gamestate/terrain_tile.h" #include "renderer/stages/terrain/terrain_render_entity.h" #include "time/time.h" #include "util/vector.h" @@ -22,7 +23,8 @@ const size_t MAX_CHUNK_HEIGHT = 16; class TerrainChunk { public: TerrainChunk(const util::Vector2s size, - const coord::tile_delta offset); + const coord::tile_delta offset, + const std::vector &&tiles); ~TerrainChunk() = default; /** @@ -81,7 +83,7 @@ class TerrainChunk { /** * Height map of the terrain chunk. */ - std::vector height_map; + std::vector tiles; /** * Render entity for pushing updates to the renderer. Can be \p nullptr. diff --git a/libopenage/gamestate/terrain_factory.cpp b/libopenage/gamestate/terrain_factory.cpp index 5801ed1892..a3abd0cb42 100644 --- a/libopenage/gamestate/terrain_factory.cpp +++ b/libopenage/gamestate/terrain_factory.cpp @@ -94,34 +94,45 @@ void build_test_terrains(const std::shared_ptr &gstate) { std::shared_ptr TerrainFactory::add_chunk(const std::shared_ptr &gstate, const util::Vector2s size, const coord::tile_delta offset) { - auto chunk = std::make_shared(size, offset); - // TODO: Remove test texture references std::string test_texture_path = "../test/textures/test_terrain.terrain"; - if (this->render_factory) { - auto render_entity = this->render_factory->add_terrain_render_entity(size, offset); - chunk->set_render_entity(render_entity); - - chunk->render_update(time::time_t::zero(), - test_texture_path); - } - // TODO: Remove test texture references + // ========== + std::optional terrain_obj; if (test_terrains.empty()) { build_test_terrains(gstate); } + static size_t test_terrain_index = 0; if (not test_terrains.empty()) { // use one of the modpack terrain textures if (test_terrain_index >= test_terrains.size()) { test_terrain_index = 0; } - auto terrain_obj = gstate->get_db_view()->get_object(test_terrains[test_terrain_index]); - test_texture_path = api::APITerrain::get_terrain_path(terrain_obj); + terrain_obj = gstate->get_db_view()->get_object(test_terrains[test_terrain_index]); + test_texture_path = api::APITerrain::get_terrain_path(terrain_obj.value()); test_terrain_index += 1; } + // ========== + + // fill the chunk with tiles + std::vector tiles{}; + tiles.reserve(size[0] * size[1]); + for (size_t i = 0; i < size[0] * size[1]; ++i) { + tiles.emplace_back(terrain_obj, test_texture_path, 0.0f); + } + + auto chunk = std::make_shared(size, offset, std::move(tiles)); + + if (this->render_factory) { + auto render_entity = this->render_factory->add_terrain_render_entity(size, offset); + chunk->set_render_entity(render_entity); + + chunk->render_update(time::time_t::zero(), + test_texture_path); + } chunk->set_terrain_path(test_texture_path); diff --git a/libopenage/gamestate/terrain_tile.cpp b/libopenage/gamestate/terrain_tile.cpp index 945c848d73..0fcb157d06 100644 --- a/libopenage/gamestate/terrain_tile.cpp +++ b/libopenage/gamestate/terrain_tile.cpp @@ -4,4 +4,7 @@ namespace openage::gamestate { -} + +// This file is intentionally empty. + +} // namespace openage::gamestate diff --git a/libopenage/gamestate/terrain_tile.h b/libopenage/gamestate/terrain_tile.h index b2b8e2dcc3..e2a046bb07 100644 --- a/libopenage/gamestate/terrain_tile.h +++ b/libopenage/gamestate/terrain_tile.h @@ -3,6 +3,7 @@ #pragma once #include +#include #include @@ -19,8 +20,17 @@ using terrain_elevation_t = util::FixedPoint; struct TerrainTile { /** * Terrain definition used by this tile. + * + * TODO: Make this non-optional once all modpacks support terrain graphics. */ - nyan::Object terrain; + std::optional terrain; + + /** + * Path to the terrain asset used by this tile. + * + * TODO: Remove this and fetch the asset path from the terrain definition. + */ + std::string terrain_asset_path; /** * Height of this tile on the terrain. diff --git a/libopenage/renderer/demo/demo_3.cpp b/libopenage/renderer/demo/demo_3.cpp index 1cfec155b8..9dbaa9b93e 100644 --- a/libopenage/renderer/demo/demo_3.cpp +++ b/libopenage/renderer/demo/demo_3.cpp @@ -117,10 +117,10 @@ void renderer_demo_3(const util::Path &path) { // Fill a 10x10 terrain grid with height values auto terrain_size = util::Vector2s{10, 10}; - std::vector height_map{}; - height_map.reserve(terrain_size[0] * terrain_size[1]); + std::vector> tiles{}; + tiles.reserve(terrain_size[0] * terrain_size[1]); for (size_t i = 0; i < terrain_size[0] * terrain_size[1]; ++i) { - height_map.push_back(0.0f); + tiles.emplace_back(0.0f, "./textures/test_terrain.terrain"); } // Create entity for terrain rendering @@ -128,25 +128,23 @@ void renderer_demo_3(const util::Path &path) { coord::tile_delta{0, 0}); // Create "test bumps" in the terrain to check if rendering works - height_map[11] = 1.0f; - height_map[23] = 2.3f; - height_map[42] = 4.2f; - height_map[69] = 6.9f; // nice + tiles[11].first = 1.0f; + tiles[23].first = 2.3f; + tiles[42].first = 4.2f; + tiles[69].first = 6.9f; // nice // A hill - height_map[55] = 3.0f; // center - height_map[45] = 2.0f; // bottom left slope - height_map[35] = 1.0f; - height_map[56] = 1.0f; // bottom right slope (little steeper) - height_map[65] = 2.0f; // top right slope - height_map[75] = 1.0f; - height_map[54] = 2.0f; // top left slope - height_map[53] = 1.0f; + tiles[55].first = 3.0f; // center + tiles[45].first = 2.0f; // bottom left slope + tiles[35].first = 1.0f; + tiles[56].first = 1.0f; // bottom right slope (little steeper) + tiles[65].first = 2.0f; // top right slope + tiles[75].first = 1.0f; + tiles[54].first = 2.0f; // top left slope + tiles[53].first = 1.0f; // send the terrain data to the terrain renderer - terrain0->update(terrain_size, - height_map, - "./textures/test_terrain.terrain"); + terrain0->update(terrain_size, tiles); // World entities auto world0 = render_factory->add_world_render_entity(); diff --git a/libopenage/renderer/demo/stresstest_0.cpp b/libopenage/renderer/demo/stresstest_0.cpp index 39b0ba0931..b33abb9685 100644 --- a/libopenage/renderer/demo/stresstest_0.cpp +++ b/libopenage/renderer/demo/stresstest_0.cpp @@ -119,10 +119,10 @@ void renderer_stresstest_0(const util::Path &path) { // Fill a 10x10 terrain grid with height values auto terrain_size = util::Vector2s{10, 10}; - std::vector height_map{}; - height_map.reserve(terrain_size[0] * terrain_size[1]); + std::vector> tiles{}; + tiles.reserve(terrain_size[0] * terrain_size[1]); for (size_t i = 0; i < terrain_size[0] * terrain_size[1]; ++i) { - height_map.push_back(0.0f); + tiles.emplace_back(0.0f, "./textures/test_terrain.terrain"); } // Create entity for terrain rendering @@ -130,9 +130,7 @@ void renderer_stresstest_0(const util::Path &path) { coord::tile_delta{0, 0}); // send the terrain data to the terrain renderer - terrain0->update(terrain_size, - height_map, - "./textures/test_terrain.terrain"); + terrain0->update(terrain_size, tiles); // World entities std::vector> render_entities{}; diff --git a/libopenage/renderer/stages/terrain/terrain_render_entity.cpp b/libopenage/renderer/stages/terrain/terrain_render_entity.cpp index a142461cb0..2d83b018f7 100644 --- a/libopenage/renderer/stages/terrain/terrain_render_entity.cpp +++ b/libopenage/renderer/stages/terrain/terrain_render_entity.cpp @@ -16,13 +16,38 @@ TerrainRenderEntity::TerrainRenderEntity() : terrain_path{nullptr, 0} { } -void TerrainRenderEntity::update(util::Vector2s size, - std::vector height_map, - const std::string terrain_path, +void TerrainRenderEntity::update_tile(const util::Vector2s size, + const coord::tile &pos, + const terrain_elevation_t elevation, + const std::string terrain_path, + const time::time_t time) { + std::unique_lock lock{this->mutex}; + + if (this->vertices.empty()) { + throw Error(MSG(err) << "Cannot update tile: Vertices have not been initialized yet."); + } + + // find the postion of the tile in the vertex array + auto left_corner = pos.ne * size[0] + pos.se; + + // update the 4 vertices of the tile + this->vertices[left_corner].up = elevation.to_float(); + this->vertices[left_corner + 1].up = elevation.to_float(); // bottom corner + this->vertices[left_corner + (size[0] + 1)].up = elevation.to_float(); // top corner + this->vertices[left_corner + (size[0] + 2)].up = elevation.to_float(); // right corner + + // set texture path + this->terrain_path.set_last(time, terrain_path); + + this->changed = true; +} + +void TerrainRenderEntity::update(const util::Vector2s size, + const tiles_t tiles, const time::time_t time) { std::unique_lock lock{this->mutex}; - // increase by 1 in every dimension because height_map + // increase by 1 in every dimension because tiles // size is number of tiles, but we want number of vertices util::Vector2i tile_size{size[0], size[1]}; this->size = util::Vector2s{size[0] + 1, size[1] + 1}; @@ -36,16 +61,16 @@ void TerrainRenderEntity::update(util::Vector2s size, // for each vertex, compare the surrounding tiles std::vector surround{}; if (j - 1 >= 0 and i - 1 >= 0) { - surround.push_back(height_map[(i - 1) * size[1] + j - 1]); + surround.push_back(tiles[(i - 1) * size[1] + j - 1].first.to_float()); } if (j < tile_size[1] and i - 1 >= 0) { - surround.push_back(height_map[(i - 1) * size[1] + j]); + surround.push_back(tiles[(i - 1) * size[1] + j].first.to_float()); } if (j < tile_size[1] and i < tile_size[0]) { - surround.push_back(height_map[i * size[1] + j]); + surround.push_back(tiles[i * size[1] + j].first.to_float()); } if (j - 1 >= 0 and i < tile_size[0]) { - surround.push_back(height_map[i * size[1] + j - 1]); + surround.push_back(tiles[i * size[1] + j - 1].first.to_float()); } // select the height of the highest surrounding tile auto max_height = *std::max_element(surround.begin(), surround.end()); @@ -59,7 +84,7 @@ void TerrainRenderEntity::update(util::Vector2s size, } // set texture path - this->terrain_path.set_last(time, terrain_path); + this->terrain_path.set_last(time, tiles[0].second); this->changed = true; } diff --git a/libopenage/renderer/stages/terrain/terrain_render_entity.h b/libopenage/renderer/stages/terrain/terrain_render_entity.h index 5e95896a11..a7b044b874 100644 --- a/libopenage/renderer/stages/terrain/terrain_render_entity.h +++ b/libopenage/renderer/stages/terrain/terrain_render_entity.h @@ -8,32 +8,49 @@ #include #include "coord/scene.h" +#include "coord/tile.h" #include "curve/discrete.h" #include "time/time.h" #include "util/vector.h" -namespace openage::renderer { +namespace openage::renderer::terrain { -namespace terrain { class TerrainRenderEntity { public: TerrainRenderEntity(); ~TerrainRenderEntity() = default; + using terrain_elevation_t = util::FixedPoint; + using tiles_t = std::vector>; + /** - * Update the render entity with information from the + * Update a single tile of the displayed terrain (chunk) with information from the * gamestate. * * @param size Size of the terrain in tiles (width x length) - * @param height_map Height of terrain tiles. + * @param pos Position of the tile in the chunk. + * @param elevation Height of terrain tile. * @param terrain_path Path to the terrain definition. * @param time Simulation time of the update. */ - void update(util::Vector2s size, - std::vector height_map, - const std::string terrain_path, + void update_tile(const util::Vector2s size, + const coord::tile &pos, + const terrain_elevation_t elevation, + const std::string terrain_path, + const time::time_t time = 0.0); + + /** + * Update the full grid of the displayed terrain (chunk) with information from the + * gamestate. + * + * @param size Size of the terrain in tiles (width x length) + * @param tiles Animation data for each tile (elevation, terrain path). + * @param time Simulation time of the update. + */ + void update(const util::Vector2s size, + const tiles_t tiles, const time::time_t time = 0.0); /** @@ -102,5 +119,4 @@ class TerrainRenderEntity { */ std::shared_mutex mutex; }; -} // namespace terrain -} // namespace openage::renderer +} // namespace openage::renderer::terrain From 520ca99600a5ff08febc3b9d0d8ea84cc2a6f417 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 11 Nov 2023 22:03:19 +0100 Subject: [PATCH 72/95] terrain: Remove old terrain code. --- libopenage/CMakeLists.txt | 1 - libopenage/coord/phys.cpp | 1 - libopenage/coord/tile.cpp | 4 +- libopenage/pathfinding/a_star.cpp | 1 - libopenage/pathfinding/path.cpp | 1 - libopenage/terrain/CMakeLists.txt | 4 - libopenage/terrain/terrain.cpp | 640 --------------------------- libopenage/terrain/terrain.h | 372 ---------------- libopenage/terrain/terrain_chunk.cpp | 186 -------- libopenage/terrain/terrain_chunk.h | 107 ----- 10 files changed, 3 insertions(+), 1314 deletions(-) delete mode 100644 libopenage/terrain/CMakeLists.txt delete mode 100644 libopenage/terrain/terrain.cpp delete mode 100644 libopenage/terrain/terrain.h delete mode 100644 libopenage/terrain/terrain_chunk.cpp delete mode 100644 libopenage/terrain/terrain_chunk.h diff --git a/libopenage/CMakeLists.txt b/libopenage/CMakeLists.txt index 12ddac7899..eb54fd8bf2 100644 --- a/libopenage/CMakeLists.txt +++ b/libopenage/CMakeLists.txt @@ -349,7 +349,6 @@ add_subdirectory("presenter") add_subdirectory("pyinterface") add_subdirectory("renderer") add_subdirectory("rng") -add_subdirectory("terrain") add_subdirectory("testing") add_subdirectory("time") add_subdirectory("util") diff --git a/libopenage/coord/phys.cpp b/libopenage/coord/phys.cpp index 2daf15ab20..250709e2b2 100644 --- a/libopenage/coord/phys.cpp +++ b/libopenage/coord/phys.cpp @@ -5,7 +5,6 @@ #include "coord/pixel.h" #include "coord/scene.h" #include "coord/tile.h" -#include "terrain/terrain.h" #include "util/math.h" #include "util/math_constants.h" diff --git a/libopenage/coord/tile.cpp b/libopenage/coord/tile.cpp index 2ccbcf0ce1..e20868ff98 100644 --- a/libopenage/coord/tile.cpp +++ b/libopenage/coord/tile.cpp @@ -2,7 +2,9 @@ #include "tile.h" -#include "../terrain/terrain.h" +#include "chunk.h" +#include "phys.h" + namespace openage::coord { diff --git a/libopenage/pathfinding/a_star.cpp b/libopenage/pathfinding/a_star.cpp index 7d9d9275cb..b53aed88f4 100644 --- a/libopenage/pathfinding/a_star.cpp +++ b/libopenage/pathfinding/a_star.cpp @@ -16,7 +16,6 @@ #include "../datastructure/pairing_heap.h" #include "../log/log.h" -#include "../terrain/terrain.h" #include "../util/strings.h" #include "heuristics.h" #include "path.h" diff --git a/libopenage/pathfinding/path.cpp b/libopenage/pathfinding/path.cpp index c3f5e91eff..f1da51af78 100644 --- a/libopenage/pathfinding/path.cpp +++ b/libopenage/pathfinding/path.cpp @@ -2,7 +2,6 @@ #include -#include "../terrain/terrain.h" #include "path.h" namespace openage::path { diff --git a/libopenage/terrain/CMakeLists.txt b/libopenage/terrain/CMakeLists.txt deleted file mode 100644 index 753cf4249a..0000000000 --- a/libopenage/terrain/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -add_sources(libopenage - terrain.cpp - terrain_chunk.cpp -) diff --git a/libopenage/terrain/terrain.cpp b/libopenage/terrain/terrain.cpp deleted file mode 100644 index 7ad26a0899..0000000000 --- a/libopenage/terrain/terrain.cpp +++ /dev/null @@ -1,640 +0,0 @@ -// Copyright 2013-2023 the openage authors. See copying.md for legal info. - -#include "terrain.h" - -#include -#include -#include -#include - -#include "../coord/chunk.h" -#include "../coord/pixel.h" -#include "../coord/tile.h" -#include "../error/error.h" -#include "../log/log.h" -#include "../util/misc.h" -#include "../util/strings.h" - -#include "terrain_chunk.h" - -namespace openage { - -TileContent::TileContent() : - terrain_id{0} { -} - -TileContent::~TileContent() = default; - -Terrain::Terrain(terrain_meta *meta, bool is_infinite) : - infinite{is_infinite}, - meta{meta} { - // TODO: - //this->limit_positive = - //this->limit_negative = - - // maps chunk position to chunks - this->chunks = std::unordered_map{}; -} - -Terrain::~Terrain() { - log::log(MSG(dbg) << "Cleanup terrain"); - - for (auto &chunk : this->chunks) { - // this chunk was autogenerated, so clean it up - if (chunk.second->manually_created == false) { - delete chunk.second; - } - } -} - -std::vector Terrain::used_chunks() const { - std::vector result; - for (auto &c : chunks) { - result.push_back(c.first); - } - return result; -} - -bool Terrain::fill(const int *data, const coord::tile_delta &size) { - bool was_cut = false; - - coord::tile pos = {0, 0}; - for (; pos.ne < size.ne; pos.ne++) { - for (pos.se = 0; pos.se < size.se; pos.se++) { - if (this->check_tile(pos) == tile_state::invalid) { - was_cut = true; - continue; - } - int terrain_id = data[pos.ne * size.ne + pos.se]; - TerrainChunk *chunk = this->get_create_chunk(pos); - chunk->get_data(pos)->terrain_id = terrain_id; - } - } - return was_cut; -} - -void Terrain::attach_chunk(TerrainChunk *new_chunk, - const coord::chunk &position, - bool manually_created) { - new_chunk->set_terrain(this); - new_chunk->manually_created = manually_created; - log::log(MSG(dbg) << "Inserting new chunk at (" << position.ne << "," << position.se << ")"); - this->chunks[position] = new_chunk; - - struct chunk_neighbors neigh = this->get_chunk_neighbors(position); - for (int i = 0; i < 8; i++) { - TerrainChunk *neighbor = neigh.neighbor[i]; - if (neighbor != nullptr) { - //set the new chunks neighbor to the neighbor chunk - new_chunk->neighbors.neighbor[i] = neighbor; - - //set the neighbors neighbor on the opposite direction - //to the new chunk - neighbor->neighbors.neighbor[(i + 4) % 8] = new_chunk; - - log::log(MSG(dbg) << "Neighbor " << i << " gets notified of new neighbor."); - } - else { - log::log(MSG(dbg) << "Neighbor " << i << " not found."); - } - } -} - -TerrainChunk *Terrain::get_chunk(const coord::chunk &position) { - auto iter = this->chunks.find(position); - - if (iter == this->chunks.end()) { - return nullptr; - } - else { - return iter->second; - } -} - -TerrainChunk *Terrain::get_chunk(const coord::tile &position) { - return this->get_chunk(position.to_chunk()); -} - -TerrainChunk *Terrain::get_create_chunk(const coord::chunk &position) { - TerrainChunk *res = this->get_chunk(position); - if (res == nullptr) { - res = new TerrainChunk(); - this->attach_chunk(res, position, false); - } - return res; -} - -TerrainChunk *Terrain::get_create_chunk(const coord::tile &position) { - return this->get_create_chunk(position.to_chunk()); -} - -TileContent *Terrain::get_data(const coord::tile &position) { - TerrainChunk *c = this->get_chunk(position.to_chunk()); - if (c == nullptr) { - return nullptr; - } - else { - return c->get_data(position.get_pos_on_chunk()); - } -} - -bool Terrain::validate_terrain(terrain_t terrain_id) { - if (terrain_id >= static_cast(this->meta->terrain_id_count)) { - throw Error(MSG(err) << "Requested terrain_id is out of range: " << terrain_id); - } - else { - return true; - } -} - -bool Terrain::validate_mask(ssize_t mask_id) { - if (mask_id >= static_cast(this->meta->blendmode_count)) { - throw Error(MSG(err) << "Requested mask_id is out of range: " << mask_id); - } - else { - return true; - } -} - -int Terrain::priority(terrain_t terrain_id) { - this->validate_terrain(terrain_id); - return this->meta->terrain_id_priority_map[terrain_id]; -} - -int Terrain::blendmode(terrain_t terrain_id) { - this->validate_terrain(terrain_id); - return this->meta->terrain_id_blendmode_map[terrain_id]; -} - -unsigned Terrain::get_subtexture_id(const coord::tile &pos, unsigned atlas_size) { - unsigned result = 0; - - result += util::mod(pos.se, atlas_size); - result *= atlas_size; - result += util::mod(pos.ne, atlas_size); - - return result; -} - -struct chunk_neighbors Terrain::get_chunk_neighbors(const coord::chunk &position) { - struct chunk_neighbors ret; - - for (int i = 0; i < 8; i++) { - coord::chunk tmp{ - position.ne + (coord::chunk_t)neigh_offsets[i].ne, - position.se + (coord::chunk_t)neigh_offsets[i].se}; - ret.neighbor[i] = this->get_chunk(tmp); - } - - return ret; -} - -int Terrain::get_blending_mode(terrain_t base_id, terrain_t neighbor_id) { - /* - * this function may require much more code, but this simple - * magnitude comparison seems to do the job. - * feel free to confirm or fix the behavior. - * - * my guess is that the blending mode encodes another information - * not publicly noticed yet: the overlay priority. - * the higher the blendmode id, the higher the mode priority. - * this may also be the reason why there are mask duplicates - * in blendomatic.dat - * - * funny enough, just using the modes in the dat file lead - * to a totally wrong render. the convert script reassigns the - * blending modes with a simple key=>val mapping, - * and after that, it looks perfect. - */ - - int base_mode = this->blendmode(base_id); - int neighbor_mode = this->blendmode(neighbor_id); - - if (neighbor_mode > base_mode) { - return neighbor_mode; - } - else { - return base_mode; - } -} - -tile_state Terrain::check_tile(const coord::tile &position) { - if (!this->check_tile_position(position)) { - return tile_state::invalid; - } - else { - TerrainChunk *chunk = this->get_chunk(position); - if (chunk == nullptr) { - return tile_state::creatable; - } - else { - return tile_state::existing; - } - } -} - -bool Terrain::check_tile_position(const coord::tile & /*pos*/) { - if (this->infinite) { - return true; - } - else { - throw Error(ERR << "non-infinite terrains are not supported yet"); - } -} - - -struct terrain_render_data Terrain::create_draw_advice(const coord::tile &ab, - const coord::tile &cd, - const coord::tile &ef, - const coord::tile &gh, - bool blending_enabled) { - /* - * The passed parameters define the screen corners. - * - * ne, se coordinates - * o = screen corner, where the tile coordinates can be queried. - * x = corner of the rhombus that will be drawn, calculated by all o. - * - * cb - * x - * . . - * . . - * ab o===========o cd - * . = visible = . - * gb x = screen = x cf - * . = = . - * gh o===========o ef - * . . - * . . - * x - * gf - * - * The rendering area may be optimized further in the future, - * to exactly fit the visible screen. - * For now, we are drawing the big rhombus. - */ - - // procedure: find all the tiles to be drawn - // and store them to a tile drawing instruction structure - struct terrain_render_data data; - - // vector of tiles to be drawn - std::vector *tiles = &data.tiles; - - // ordered set of objects on the terrain (buildings.) - // it's ordered by the visibility layers. - // auto objects = &data.objects; - - coord::tile gb = {gh.ne, ab.se}; - coord::tile cf = {cd.ne, ef.se}; - - // hint the vector about the number of tiles it will contain - size_t tiles_count = std::abs(cf.ne - gb.ne) * std::abs(cf.se - gb.se); - tiles->reserve(tiles_count); - - // sweep the whole rhombus area - for (coord::tile tilepos = gb; tilepos.ne <= cf.ne; tilepos.ne++) { - for (tilepos.se = gb.se; tilepos.se <= cf.se; tilepos.se++) { - // get the terrain tile drawing data - auto tile = this->create_tile_advice(tilepos, blending_enabled); - tiles->push_back(tile); - - // get the object standing on the tile - // TODO: make the terrain independent of objects standing on it. - TileContent *tile_content = this->get_data(tilepos); - if (tile_content != nullptr) { - // for (auto obj_item : tile_content->obj) { - // objects->insert(obj_item); - // } - } - } - } - - return data; -} - - -struct tile_draw_data Terrain::create_tile_advice(coord::tile position, bool blending_enabled) { - // this struct will be filled with all tiles and overlays to draw. - struct tile_draw_data tile; - tile.count = 0; - - TileContent *base_tile_content = this->get_data(position); - - // chunk of this tile does not exist - if (base_tile_content == nullptr) { - return tile; - } - - struct tile_data base_tile_data; - - // the base terrain id of the tile - base_tile_data.terrain_id = base_tile_content->terrain_id; - - // the base terrain is not existant. - if (base_tile_data.terrain_id < 0) { - return tile; - } - - this->validate_terrain(base_tile_data.terrain_id); - - base_tile_data.state = tile_state::existing; - base_tile_data.pos = position; - base_tile_data.priority = this->priority(base_tile_data.terrain_id); - base_tile_data.subtexture_id = 0; - base_tile_data.blend_mode = -1; - base_tile_data.mask_id = -1; - - tile.data[tile.count] = base_tile_data; - tile.count += 1; - - // blendomatic!!111 - // see doc/media/blendomatic for the idea behind this. - if (blending_enabled) { - // the neighbors of the base tile - struct neighbor_tile neigh_data[8]; - - // get all neighbor tiles around position, reset the influence directions. - this->get_neighbors(position, neigh_data, this->meta->influences_buf.get()); - - // create influence list (direction, priority) - // strip and order influences, get the final influence data structure - struct influence_group influence_group = this->calculate_influences( - &base_tile_data, - neigh_data, - this->meta->influences_buf.get()); - - // create the draw_masks from the calculated influences - this->calculate_masks(position, &tile, &influence_group); - } - - return tile; -} - -void Terrain::get_neighbors(coord::tile basepos, - neighbor_tile *neigh_data, - influence *influences_by_terrain_id) { - // walk over all given neighbor tiles and store them to the influence list, - // group them by terrain id. - - for (int neigh_id = 0; neigh_id < 8; neigh_id++) { - // the current neighbor - auto neighbor = &neigh_data[neigh_id]; - - // calculate the pos of the neighbor tile - coord::tile neigh_pos = basepos + neigh_offsets[neigh_id]; - - // get the neighbor data - TileContent *neigh_content = this->get_data(neigh_pos); - - // chunk for neighbor or single tile is not existant - if (neigh_content == nullptr || neigh_content->terrain_id < 0) { - neighbor->state = tile_state::missing; - } - else { - neighbor->terrain_id = neigh_content->terrain_id; - neighbor->state = tile_state::existing; - neighbor->priority = this->priority(neighbor->terrain_id); - - // reset influence directions for this tile - influences_by_terrain_id[neighbor->terrain_id].direction = 0; - } - } -} - -struct influence_group Terrain::calculate_influences(struct tile_data *base_tile, - struct neighbor_tile *neigh_data, - struct influence *influences_by_terrain_id) { - // influences to actually draw (-> maximum 8) - struct influence_group influences {}; - influences.count = 0; - - // process adjacent neighbors first, - // then add diagonal influences, if no adjacent influence was found - constexpr int neigh_id_lookup[] = {1, 3, 5, 7, 0, 2, 4, 6}; - - for (int i = 0; i < 8; i++) { - // diagonal neighbors: (neigh_id % 2) == 0 - // adjacent neighbors: (neigh_id % 2) == 1 - - int neigh_id = neigh_id_lookup[i]; - bool is_adjacent_neighbor = neigh_id % 2 == 1; - bool is_diagonal_neighbor = not is_adjacent_neighbor; - - // the current neighbor_tile. - auto neighbor = &neigh_data[neigh_id]; - - // neighbor is nonexistant - if (neighbor->state == tile_state::missing) { - continue; - } - - // neighbor only interesting if it's a different terrain than the base. - // if it is the same id, the priorities are equal. - // neighbor draws over the base if it's priority is greater. - if (neighbor->priority > base_tile->priority) { - // get influence storage for the neighbor terrain id - // to group influences by id - auto influence = &influences_by_terrain_id[neighbor->terrain_id]; - - // check if diagonal influence is valid - if (is_diagonal_neighbor) { - // get the adjacent neighbors to the current diagonal - // influence - // (a & 0x07) == (a % 8) - uint8_t adj_neigh_0 = (neigh_id - 1) & 0x07; - uint8_t adj_neigh_1 = (neigh_id + 1) & 0x07; - - uint8_t neigh_mask = (1 << adj_neigh_0) | (1 << adj_neigh_1); - - // the adjacent neigbors are already influencing - // the current tile, therefore don't apply the diagonal mask - if ((influence->direction & neigh_mask) != 0) { - continue; - } - } - - // this terrain id hasn't had influence so far: - // add it to the list of influences. - if (influence->direction == 0) { - influences.terrain_ids[influences.count] = neighbor->terrain_id; - influences.count += 1; - } - - // as tile i has influence for this priority - // => bit i is set to 1 by 2^i - influence->direction |= 1 << neigh_id; - influence->priority = neighbor->priority; - influence->terrain_id = neighbor->terrain_id; - } - } - - // influences_by_terrain_id will be merged in the following, - // unused terrain ids will be dropped now. - - // shrink the big influence buffer that had entries for all terrains - // by copying the possible (max 8) influences to a separate buffer. - for (int k = 0; k < influences.count; k++) { - int relevant_id = influences.terrain_ids[k]; - influences.data[k] = influences_by_terrain_id[relevant_id]; - } - - // order the influences by their priority - for (int k = 1; k < influences.count; k++) { - struct influence tmp_influence = influences.data[k]; - - int l = k - 1; - while (l >= 0 && influences.data[l].priority > tmp_influence.priority) { - influences.data[l + 1] = influences.data[l]; - l -= 1; - } - - influences.data[l + 1] = tmp_influence; - } - - return influences; -} - - -void Terrain::calculate_masks(coord::tile position, - struct tile_draw_data *tile_data, - struct influence_group *influences) { - // influences are grouped by terrain id. - // the direction member has each bit set to 1 that is an influence from that direction. - // create a mask for this direction combination. - - // the base tile is stored at position 0 of the draw_mask - terrain_t base_terrain_id = tile_data->data[0].terrain_id; - - // iterate over all neighbors (with different terrain_ids) that have influence - for (ssize_t i = 0; i < influences->count; i++) { - // neighbor id of the current influence - char direction_bits = influences->data[i].direction; - - // all bits are 0 -> no influence directions stored. - // => no influence can be ignored. - if (direction_bits == 0) { - continue; - } - - terrain_t neighbor_terrain_id = influences->data[i].terrain_id; - int adjacent_mask_id = -1; - - /* neighbor ids: - 0 - 7 1 => 8 neighbors that can have influence on - 6 @ 2 the mask id selection. - 5 3 - 4 - */ - - // filter adjacent and diagonal influences neighbor_id: 76543210 - uint8_t direction_bits_adjacent = direction_bits & 0xAA; //0b10101010 - uint8_t direction_bits_diagonal = direction_bits & 0x55; //0b01010101 - - switch (direction_bits_adjacent) { - case 0x08: //0b00001000 - adjacent_mask_id = 0; //0..3 - break; - case 0x02: //0b00000010 - adjacent_mask_id = 4; //4..7 - break; - case 0x20: //0b00100000 - adjacent_mask_id = 8; //8..11 - break; - case 0x80: //0b10000000 - adjacent_mask_id = 12; //12..15 - break; - case 0x22: //0b00100010 - adjacent_mask_id = 20; - break; - case 0x88: //0b10001000 - adjacent_mask_id = 21; - break; - case 0xA0: //0b10100000 - adjacent_mask_id = 22; - break; - case 0x82: //0b10000010 - adjacent_mask_id = 23; - break; - case 0x28: //0b00101000 - adjacent_mask_id = 24; - break; - case 0x0A: //0b00001010 - adjacent_mask_id = 25; - break; - case 0x2A: //0b00101010 - adjacent_mask_id = 26; - break; - case 0xA8: //0b10101000 - adjacent_mask_id = 27; - break; - case 0xA2: //0b10100010 - adjacent_mask_id = 28; - break; - case 0x8A: //0b10001010 - adjacent_mask_id = 29; - break; - case 0xAA: //0b10101010 - adjacent_mask_id = 30; - break; - } - - // if it's the linear adjacent mask, cycle the 4 possible masks. - // e.g. long shorelines don't look the same then. - // maskid == 0x08 0x02 0x80 0x20 for that. - if (adjacent_mask_id <= 12 && adjacent_mask_id % 4 == 0) { - //we have 4 = 2^2 anti redundancy masks, so keep the last 2 bits - uint8_t anti_redundancy_offset = (position.ne + position.se) & 0x03; - adjacent_mask_id += anti_redundancy_offset; - } - - // get the blending mode (the mask selection) for this transition - // the mode is dependent on the two meeting terrain types - int blend_mode = this->get_blending_mode(base_terrain_id, neighbor_terrain_id); - - // append the mask for the adjacent blending - if (adjacent_mask_id >= 0) { - struct tile_data *overlay = &tile_data->data[tile_data->count]; - overlay->pos = position; - overlay->mask_id = adjacent_mask_id; - overlay->blend_mode = blend_mode; - overlay->terrain_id = neighbor_terrain_id; - overlay->subtexture_id = 0; - overlay->state = tile_state::existing; - - tile_data->count += 1; - } - - // append the mask for the diagonal blending - if (direction_bits_diagonal > 0) { - for (int l = 0; l < 4; l++) { - // generate one mask for each influencing diagonal neighbor id. - // even if they all have the same terrain_id, - // because we don't have combined diagonal influence masks. - - // l == 0: pos = 0b000000001, mask = 18 - // l == 1: pos = 0b000000100, mask = 16 - // l == 2: pos = 0b000010000, mask = 17 - // l == 3: pos = 0b001000000, mask = 19 - - int current_direction_bit = 1 << (l * 2); - constexpr int diag_mask_id_map[4] = {18, 16, 17, 19}; - - if (direction_bits_diagonal & current_direction_bit) { - struct tile_data *overlay = &tile_data->data[tile_data->count]; - overlay->pos = position; - overlay->mask_id = diag_mask_id_map[l]; - overlay->blend_mode = blend_mode; - overlay->terrain_id = neighbor_terrain_id; - overlay->subtexture_id = 0; - overlay->state = tile_state::existing; - - tile_data->count += 1; - } - } - } - } -} - -} // namespace openage diff --git a/libopenage/terrain/terrain.h b/libopenage/terrain/terrain.h deleted file mode 100644 index 02ceba1cae..0000000000 --- a/libopenage/terrain/terrain.h +++ /dev/null @@ -1,372 +0,0 @@ -// Copyright 2013-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "../coord/chunk.h" -#include "../coord/phys.h" -#include "../coord/pixel.h" -#include "../coord/tile.h" -#include "../util/misc.h" - -namespace openage { - -class RenderOptions; -class TerrainChunk; - -/** - * type that for terrain ids. - * it's signed so that -1 can indicate a missing tile. - * TODO: get rid of the signedness. - */ -using terrain_t = int; - -/** - * hashing for chunk coordinates. - * - * this allows storage of chunk coords as keys in an unordered map. - */ -struct coord_chunk_hash { - size_t operator()(const coord::chunk &input) const { - constexpr int half_size_t_bits = sizeof(size_t) * 4; - - return ((size_t)input.ne << half_size_t_bits) | input.se; - } -}; - - -/** - * describes the properties of one terrain tile. - * - * this includes the terrain_id (ice, water, grass, ...) - * and the list of objects which have a bounding box overlapping the tile - */ -class TileContent { -public: - TileContent(); - ~TileContent(); - terrain_t terrain_id; -}; - - -/** - * coordinate offsets for getting tile neighbors by their id. - */ -constexpr coord::tile_delta const neigh_offsets[] = { - {1, -1}, - {1, 0}, - {1, 1}, - {0, 1}, - {-1, 1}, - {-1, 0}, - {-1, -1}, - {0, -1}}; - - -/** - * describes the state of a terrain tile. - */ -enum class tile_state { - missing, //!< tile is not created yet - existing, //!< tile is already existing - creatable, //!< tile does not exist but can be created - invalid, //!< tile does not exist and can not be created -}; - - -/** - * storage for influences by neighbor tiles. - */ -struct influence { - uint8_t direction; //!< bitmask for influence directions, bit 0 = neighbor 0, etc. - int priority; //!< the blending priority for this influence - terrain_t terrain_id; //!< the terrain id of the influence -}; - -/** - * influences for one tile. - * as a tile has 8 adjacent and diagonal neighbors, - * the maximum number of influences is 8. - */ -struct influence_group { - int count; - terrain_t terrain_ids[8]; - struct influence data[8]; -}; - -/** - * one influence on another tile. - */ -struct neighbor_tile { - terrain_t terrain_id; - tile_state state; - int priority; -}; - -/** - * storage data for a single terrain tile. - */ -struct tile_data { - terrain_t terrain_id; - coord::tile pos{0, 0}; - int subtexture_id; - int priority; - int mask_id; - int blend_mode; - tile_state state; -}; - -/** - * collection of drawing data for a single tile. - * because of influences, a maximum of 8+1 draws - * could be requested. - */ -struct tile_draw_data { - ssize_t count; - struct tile_data data[9]; -}; - -/** - * the complete render instruction collection for the terrain. - * this is passed to the renderer and will be drawn on screen. - */ -struct terrain_render_data { - std::vector tiles; -}; - -/** - * specification for all available - * tile types and blending data - */ -struct terrain_meta { - size_t terrain_id_count; - size_t blendmode_count; - - std::unique_ptr terrain_id_priority_map; - std::unique_ptr terrain_id_blendmode_map; - - std::unique_ptr influences_buf; -}; - -/** - * the terrain class is the main top-management interface - * for dealing with cost-benefit analysis to maximize company profits. - * - * actually this is just the entrypoint and container for the terrain chunks. - */ -class Terrain { -public: - Terrain(terrain_meta *meta, bool is_infinite); - ~Terrain(); - - bool infinite; //!< chunks are automagically created as soon as they are referenced - - // TODO: finite terrain limits - // TODO: non-square shaped terrain bounds - - /** - * returns a list of all referenced chunks - */ - std::vector used_chunks() const; - - /** - * fill the terrain with given terrain_id values. - * @returns whether the data filled on the terrain was cut because of - * the terrains size limit. - */ - bool fill(const int *data, const coord::tile_delta &size); - - /** - * Attach a chunk to the terrain, to a given position. - * - * @param new_chunk The chunk to be attached - * @param position The chunk position where the chunk will be placed - * @param manually_created Was this chunk created manually? If true, it will not be free'd automatically - */ - void attach_chunk(TerrainChunk *new_chunk, const coord::chunk &position, bool manual = true); - - /** - * get a terrain chunk by a given chunk position. - * - * @return the chunk if exists, nullptr else - */ - TerrainChunk *get_chunk(const coord::chunk &position); - - /** - * get a terrain chunk by a given tile position. - * - * @return the chunk it exists, nullptr else - */ - TerrainChunk *get_chunk(const coord::tile &position); - - /** - * get or create a terrain chunk for a given chunk position. - * - * @return the (maybe newly created) chunk - */ - TerrainChunk *get_create_chunk(const coord::chunk &position); - - /** - * get or create a terrain chunk for a given tile position. - * - * @return the (maybe newly created) chunk - */ - TerrainChunk *get_create_chunk(const coord::tile &position); - - /** - * return tile data for the given position. - * - * the only reason the chunks exist, is because of this data. - */ - TileContent *get_data(const coord::tile &position); - - /** - * get the neighbor chunks of a given chunk. - * - * - * chunk neighbor ids: - * 0 / <- ne - * 7 1 - * 6 @ 2 - * 5 3 - * 4 \ <- se - * - * ne se - * 0: 1 -1 - * 1: 1 0 - * 2: 1 1 - * 3: 0 1 - * 4: -1 1 - * 5: -1 0 - * 6: -1 -1 - * 7: 0 -1 - * - * @param position: the position of the center chunk. - */ - struct chunk_neighbors get_chunk_neighbors(const coord::chunk &position); - - /** - * return the subtexture offset id for a given tile position. - * the maximum offset is determined by the atlas size. - * - * this function returns always the right value, so that neighbor tiles - * of the same terrain (like grass-grass) are matching (without blendomatic). - * -> e.g. grass only map. - */ - unsigned get_subtexture_id(const coord::tile &pos, unsigned atlas_size); - - /** - * checks the creation state and premissions of a given tile position. - */ - tile_state check_tile(const coord::tile &position); - - /** - * checks whether the given tile position is allowed to exist on this terrain. - */ - // TODO: rename to is_tile_position_valid - bool check_tile_position(const coord::tile &position); - - /** - * validate whether the given terrain id is available. - */ - bool validate_terrain(terrain_t terrain_id); - - /** - * validate whether the given mask id is available. - */ - bool validate_mask(ssize_t mask_id); - - /** - * return the blending priority for a given terrain id. - */ - int priority(terrain_t terrain_id); - - /** - * return the blending mode/blendomatic mask set for a given terrain id. - */ - int blendmode(terrain_t terrain_id); - - /** - * return the blending mode id for two given neighbor ids. - */ - int get_blending_mode(terrain_t base_id, terrain_t neighbor_id); - - /** - * create the drawing instruction data. - * - * created draw data according to the given tile boundaries. - * - * - * @param ab: upper left tile - * @param cd: upper right tile - * @param ef: lower right tile - * @param gh: lower left tile - * - * @returns a drawing instruction struct that contains all information for rendering - */ - struct terrain_render_data create_draw_advice(const coord::tile &ab, - const coord::tile &cd, - const coord::tile &ef, - const coord::tile &gh, - bool blending_enabled); - - /** - * create rendering and blending information for a single tile on the terrain. - */ - struct tile_draw_data create_tile_advice(coord::tile position, bool blending_enabled); - - /** - * gather neighbors of a given base tile. - * - * @param basepos: the base position, around which the neighbors will be fetched - * @param neigh_tiles: the destination buffer where the neighbors will be stored - * @param influences_by_terrain_id: influence buffer that is reset in the same step - */ - void get_neighbors(coord::tile basepos, - struct neighbor_tile *neigh_tiles, - struct influence *influences_by_terrain_id); - - /** - * look at neighbor tiles around the base_tile, and store the influence bits. - * - * @param base_tile: the base tile for which influences are calculated - * @param neigh_tiles: the neigbors of base_tile - * @param influences_by_terrain_id: influences will be stored to this buffer, as bitmasks - * @returns an influence group that describes the maximum 8 possible influences on the base_tile - */ - struct influence_group calculate_influences(struct tile_data *base_tile, - struct neighbor_tile *neigh_tiles, - struct influence *influences_by_terrain_id); - - /** - * calculate blending masks for a given tile position. - * - * @param position: the base tile position, for which the masks are calculated - * @param tile_data: the buffer where the created drawing layers will be stored in - * @param influences: the buffer where calculated influences were stored to - * - * @see calculate_influences - */ - void calculate_masks(coord::tile position, - struct tile_draw_data *tile_data, - struct influence_group *influences); - -private: - /** - * terrain meta data - */ - terrain_meta *meta; - - /** - * maps chunk coordinates to chunks. - */ - std::unordered_map chunks; -}; - -} // namespace openage diff --git a/libopenage/terrain/terrain_chunk.cpp b/libopenage/terrain/terrain_chunk.cpp deleted file mode 100644 index 0fd77923dc..0000000000 --- a/libopenage/terrain/terrain_chunk.cpp +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2013-2023 the openage authors. See copying.md for legal info. - -#include "terrain_chunk.h" - -#include - -#include "../coord/phys.h" -#include "../coord/pixel.h" -#include "../coord/tile.h" -#include "../error/error.h" -#include "../log/log.h" -#include "../util/misc.h" - -#include "terrain.h" - -namespace openage { - - -TerrainChunk::TerrainChunk() : - manually_created{true} { - this->tile_count = std::pow(chunk_size, 2); - - // the data array for this chunk. - // each element describes the tile data. - this->data = new TileContent[this->tile_count]; - - // initialize all neighbors as nonexistant - for (int i = 0; i < 8; i++) { - this->neighbors.neighbor[i] = nullptr; - } - - log::log(MSG(dbg) << "Terrain chunk created: " - << "size=" << chunk_size << ", " - << "tiles=" << this->tile_count); -} - - -TerrainChunk::~TerrainChunk() { - delete[] this->data; -} - -TileContent *TerrainChunk::get_data(coord::tile abspos) { - return this->get_data(abspos.get_pos_on_chunk()); -} - -TileContent *TerrainChunk::get_data(coord::tile_delta pos) { - return this->get_data(this->tile_position(pos)); -} - -TileContent *TerrainChunk::get_data(size_t pos) { - return &this->data[pos]; -} - -TileContent *TerrainChunk::get_data_neigh(coord::tile_delta pos) { - // determine the neighbor id by the given position - int neighbor_id = this->neighbor_id_by_pos(pos); - - // if the location is not on the current chunk, the neighbor id is != -1 - if (neighbor_id != -1) { - // get the chunk where the requested neighbor tile lies on. - TerrainChunk *neigh_chunk = this->neighbors.neighbor[neighbor_id]; - - // this neighbor does not exist, so the tile does not exist. - if (neigh_chunk == nullptr) { - return nullptr; - } - - // get position of tile on neighbor - size_t pos_on_neighbor = this->tile_position_neigh(pos); - - return neigh_chunk->get_data(pos_on_neighbor); - } - // the position lies on the current chunk. - else { - return this->get_data(pos); - } -} - -/* - * get the chunk neighbor id by a given position not lying on this chunk. - * - * neighbor ids: - * - * ne - * -- - * /| - * 0 - * 7 1 - * 6 @ 2 - * 5 3 - * 4 - * \| - * -- - * se - */ -int TerrainChunk::neighbor_id_by_pos(coord::tile_delta pos) { - int neigh_id = -1; - - if (pos.ne < 0) { - if (pos.se < 0) { - neigh_id = 6; - } - else if (pos.se >= (ssize_t)chunk_size) { - neigh_id = 4; - } - else { - neigh_id = 5; - } - } - else if (pos.ne >= (ssize_t)chunk_size) { - if (pos.se < 0) { - neigh_id = 0; - } - else if (pos.se >= (ssize_t)chunk_size) { - neigh_id = 2; - } - else { - neigh_id = 1; - } - } - else { - if (pos.se < 0) { - neigh_id = 7; - } - else if (pos.se >= (ssize_t)chunk_size) { - neigh_id = 3; - } - else { - neigh_id = -1; - } - } - return neigh_id; -} - -/* - * calculates the memory position of a given tile location. - * - * give this function isometric coordinates, it returns the tile index. - * - * # is a single terrain tile: - * - * 3 - * 2 # - * 1 # # - * ne= 0 # * # - * # # # # - * se= 0 # # # - * 1 # # - * 2 # - * 3 - * - * for example, * is at position (2, 1) - * the returned index would be 6 (count for each ne row, starting at se=0) - */ -size_t TerrainChunk::tile_position(coord::tile_delta pos) { - if (this->neighbor_id_by_pos(pos) != -1) { - throw Error(MSG(err) << "Tile " - "(" - << pos.ne << ", " << pos.se << ") " - "has been requested, but is not part of this chunk."); - } - - return pos.se * chunk_size + pos.ne; -} - -size_t TerrainChunk::tile_position_neigh(coord::tile_delta pos) { - // get position of tile on neighbor - pos.ne = util::mod(pos.ne); - pos.se = util::mod(pos.se); - - return pos.se * chunk_size + pos.ne; -} - -size_t TerrainChunk::get_tile_count() { - return this->tile_count; -} - -size_t TerrainChunk::get_size() { - return chunk_size; -} - -void TerrainChunk::set_terrain(Terrain *parent) { - this->terrain = parent; -} - -} // namespace openage diff --git a/libopenage/terrain/terrain_chunk.h b/libopenage/terrain/terrain_chunk.h deleted file mode 100644 index 683d46c0fd..0000000000 --- a/libopenage/terrain/terrain_chunk.h +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2013-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include - -#include "../coord/pixel.h" -#include "../coord/tile.h" -#include "../util/file.h" - -namespace openage { - -class Terrain; -class TerrainChunk; -class TileContent; - - -/** -the number of tiles per direction on a chunk -*/ -constexpr size_t chunk_size = 16; - -/** -adjacent neighbors of a chunk. - -neighbor ids: - 0 - 7 1 - 6 @ 2 - 5 3 - 4 -*/ -struct chunk_neighbors { - TerrainChunk *neighbor[8]; -}; - -/** -terrain chunk class represents one chunk of the the drawn terrain. -*/ -class TerrainChunk { -public: - TerrainChunk(); - ~TerrainChunk(); - - /** - * stores the length for one chunk side. - */ - size_t size; - - /** - * number of tiles on that chunk (this->size^2) - */ - size_t tile_count; - - /** - * stores the chunk data, one tile_content struct for each tile. - */ - TileContent *data; - - /** - * the terrain to which this chunk belongs to. - */ - Terrain *terrain; - - /** - * the 8 neighbors this chunk has. - */ - chunk_neighbors neighbors; - - /** - * get tile data by absolute coordinates. - */ - TileContent *get_data(coord::tile abspos); - - /** - * get tile data by coordinates that are releative to this chunk. - */ - TileContent *get_data(coord::tile_delta pos); - - /** - * get tile data by memory position. - */ - TileContent *get_data(size_t pos); - - /** - * get the tile data a given tile position relative to this chunk. - * - * also queries neighbors if the position is not on this chunk. - */ - TileContent *get_data_neigh(coord::tile_delta pos); - - int neighbor_id_by_pos(coord::tile_delta pos); - - size_t tile_position(coord::tile_delta pos); - size_t tile_position_neigh(coord::tile_delta pos); - size_t get_tile_count(); - - size_t tiles_in_row(unsigned int row); - size_t get_size(); - - void set_terrain(Terrain *parent); - - bool manually_created; -}; - -} // namespace openage From 1718b672ce14c880aa2221ab1af77e6958c2fb83 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 11 Nov 2023 22:09:48 +0100 Subject: [PATCH 73/95] util: Remove CSV reader. --- libopenage/util/CMakeLists.txt | 1 - libopenage/util/csv.cpp | 69 ----------- libopenage/util/csv.h | 216 --------------------------------- 3 files changed, 286 deletions(-) delete mode 100644 libopenage/util/csv.cpp delete mode 100644 libopenage/util/csv.h diff --git a/libopenage/util/CMakeLists.txt b/libopenage/util/CMakeLists.txt index 841a00757f..1a2bee51e7 100644 --- a/libopenage/util/CMakeLists.txt +++ b/libopenage/util/CMakeLists.txt @@ -2,7 +2,6 @@ add_sources(libopenage color.cpp compiler.cpp constinit_vector.cpp - csv.cpp enum.cpp enum_test.cpp externalprofiler.cpp diff --git a/libopenage/util/csv.cpp b/libopenage/util/csv.cpp deleted file mode 100644 index e0bf825c3b..0000000000 --- a/libopenage/util/csv.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2013-2023 the openage authors. See copying.md for legal info. - -#include "csv.h" - -#include - -#include "file.h" -#include "../error/error.h" -#include "../log/log.h" - - -namespace openage { -namespace util { - - -CSVCollection::CSVCollection(const Path &entryfile_path) { - - auto file = entryfile_path.open(); - log::log(DBG << "Loading csv collection: " << file); - - // The file format is defined in: - // openage/convert/dataformat/data_definition.py - // example: - // - // ### some/folder/and/filename.docx - // # irrelevant - // # comments - // data,stuff,moar,bla - - // store the currently read file name - std::string current_file; - - for (auto &line : file.get_lines()) { - // a new file starts: - if (line[0] == '#' and - line[1] == '#' and - line[2] == '#' and - line[3] == ' ') { - - // remove the "### " - current_file = (line.erase(0, 4)); - - // create a vector to put lines in - this->data.emplace(current_file, std::vector{}); - } - else { - if (line.empty() or line[0] == '#') { - continue; - } - - if (current_file.size() > 0) [[likely]] { - // add line to the current file linelist - this->data.at(current_file).push_back(line); - } - else { - throw Error{ - ERR << "csv collection content encountered " - << "without known target in " << entryfile_path - << ", linedata: " << line - }; - } - } - } - - log::log(INFO << "Loaded multi-csv file: " - << this->data.size() << " sub-files"); -} - -}} // openage::util diff --git a/libopenage/util/csv.h b/libopenage/util/csv.h deleted file mode 100644 index 88d5ea0322..0000000000 --- a/libopenage/util/csv.h +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright 2013-2017 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "../error/error.h" -#include "compiler.h" -#include "fslike/native.h" -#include "path.h" - - -namespace openage { -namespace util { - - -/** - * Collection of multiple csv files. - * Read from a packed csv that contains all the data. - * - * Then, data can be read recursively. - */ -class CSVCollection { -public: - - /** - * Type for storing csv data: - * {filename: [line, ...]}. - */ - using csv_file_map_t = std::unordered_map>; - - /** - * Initialize the collection by reading the given file. - * This file must contain the data that this collection is made up of. - */ - explicit CSVCollection(const Path &entryfile); - virtual ~CSVCollection() = default; - - - /** - * This function is the entry point to load the whole file tree recursively. - * - * Should be called again from the .recurse() method of the struct. - * - * The internal flow is as follows: - * * read entries of the given files - * (call to the generated field parsers (the fill function)) - * * then, recurse into referenced subdata entries - * (this implementation is generated) - * * from there, reach this function again to read each subdata entry. - * - */ - template - std::vector read(const std::string &filename) const { - - // first read the content from the data - auto result = this->get_data(filename); - - std::string dir = dirname(filename); - - size_t line_count = 0; - - // then recurse into each subdata entry. - for (auto &entry : result) { - line_count += 1; - - if (not entry.recurse(*this, dir)) { - throw Error{ - MSG(err) - << "Failed to read follow-up files for " - << filename << ":" << line_count - }; - } - } - - return result; - } - - - /** - * Parse the data from one file in the map. - */ - template - std::vector get_data(const std::string &filename) const { - - size_t line_count = 0; - - std::vector ret; - - // locate the data in the collection - auto it = this->data.find(filename); - - if (it != std::end(this->data)) { - const std::vector &lines = it->second; - - for (auto &line : lines) { - line_count += 1; - lineformat current_line_data; - - // use the line copy to fill the current line struct. - int error_column = current_line_data.fill(line); - if (error_column != -1) { - throw Error{ - ERR - << "Failed to read CSV file: " - << filename << ":" << line_count << ":" << error_column - << ": error parsing " << line - }; - } - - ret.push_back(current_line_data); - } - } - else { - throw Error{ - ERR << "File was not found in csv cache: '" - << filename << "'" - }; - } - - return ret; - } - -protected: - csv_file_map_t data; -}; - - -/** - * Referenced file tree structure. - * - * Used for storing information for subtype members - * that need to be recursed. - */ -template -struct csv_subdata { - /** - * File where to read subdata from. - * This name is relative to the file that defined the subdata! - */ - std::string filename; - - /** - * Data that was read from the file with this->filename. - */ - std::vector data; - - /** - * Read the data of the lineformat from the collection. - * Can descend recursively into dependencies. - */ - bool read(const CSVCollection &collection, const std::string &basedir) { - std::string next_file = basedir; - if (basedir.size() > 0) { - next_file += fslike::PATHSEP; - } - next_file += this->filename; - - this->data = collection.read(next_file); - return true; - } - - /** - * Convenience operator to access data - */ - const lineformat &operator [](size_t idx) const { - return this->data[idx]; - } -}; - - -/** - * read a single csv file. - * call the destination struct .fill() method for actually storing line data - */ -template -std::vector read_csv_file(const Path &path) { - - File csv = path.open(); - - std::vector ret; - size_t line_count = 0; - - for (auto &line : csv.get_lines()) { - line_count += 1; - - // ignore comments and empty lines - if (line.empty() || line[0] == '#') { - continue; - } - - lineformat current_line_data; - - // use the line copy to fill the current line struct. - int error_column = current_line_data.fill(line); - if (error_column != -1) { - throw Error{ - ERR - << "Failed to read CSV file: " - << csv << ":" << line_count << ":" << error_column - << ": error parsing " << line - }; - } - - ret.push_back(current_line_data); - } - - return ret; -} - -}} // openage::util From 040ead866b682780d1b18816a75cdfd280f14b8a Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 11 Nov 2023 22:13:42 +0100 Subject: [PATCH 74/95] renderer: Remove unused animation class. --- libopenage/renderer/CMakeLists.txt | 1 - libopenage/renderer/animation.cpp | 14 ------------- libopenage/renderer/animation.h | 33 ------------------------------ 3 files changed, 48 deletions(-) delete mode 100644 libopenage/renderer/animation.cpp delete mode 100644 libopenage/renderer/animation.h diff --git a/libopenage/renderer/CMakeLists.txt b/libopenage/renderer/CMakeLists.txt index b6578cd128..756e9e4d98 100644 --- a/libopenage/renderer/CMakeLists.txt +++ b/libopenage/renderer/CMakeLists.txt @@ -1,5 +1,4 @@ add_sources(libopenage - animation.cpp color.cpp definitions.cpp geometry.cpp diff --git a/libopenage/renderer/animation.cpp b/libopenage/renderer/animation.cpp deleted file mode 100644 index a9b0a54e37..0000000000 --- a/libopenage/renderer/animation.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2021-2021 the openage authors. See copying.md for legal info. - -#include "animation.h" - -namespace openage::renderer { - -Animation2d::Animation2d(const resources::Animation2dInfo &info) : - info{info} {} - -const resources::Animation2dInfo &Animation2d::get_info() const { - return this->info; -} - -} // namespace openage::renderer diff --git a/libopenage/renderer/animation.h b/libopenage/renderer/animation.h deleted file mode 100644 index aa5e27f8cf..0000000000 --- a/libopenage/renderer/animation.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2021-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include "renderer/resources/animation/animation_info.h" - -namespace openage::renderer { - -class Animation2d { -public: - Animation2d() = default; - ~Animation2d() = default; - - /** - * Get the animation information. - * - * @return Animation information. - */ - const resources::Animation2dInfo &get_info() const; - -protected: - /** - * Creates a 2D animation. - */ - Animation2d(const resources::Animation2dInfo &info); - - /** - * Information about the animation layers, angles and frames. - */ - resources::Animation2dInfo info; -}; - -} // namespace openage::renderer From 0462af27a5e11125ced2bcd8825db51e064d2212 Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 11 Nov 2023 22:19:18 +0100 Subject: [PATCH 75/95] Fix CI complaints. --- .../renderer/gui/guisys/private/gui_application_impl.h | 2 +- libopenage/renderer/gui/guisys/public/gui_application.cpp | 2 +- openage/convert/entity_object/export/metadata_export.py | 6 ++++-- .../convert/processor/conversion/aoc/media_subprocessor.py | 2 +- .../convert/processor/conversion/hd/media_subprocessor.py | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libopenage/renderer/gui/guisys/private/gui_application_impl.h b/libopenage/renderer/gui/guisys/private/gui_application_impl.h index f772c77a0f..7af12c0fa4 100644 --- a/libopenage/renderer/gui/guisys/private/gui_application_impl.h +++ b/libopenage/renderer/gui/guisys/private/gui_application_impl.h @@ -1,4 +1,4 @@ -// Copyright 2015-2022 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #pragma once diff --git a/libopenage/renderer/gui/guisys/public/gui_application.cpp b/libopenage/renderer/gui/guisys/public/gui_application.cpp index 80cba97bd2..cd07289f87 100644 --- a/libopenage/renderer/gui/guisys/public/gui_application.cpp +++ b/libopenage/renderer/gui/guisys/public/gui_application.cpp @@ -1,4 +1,4 @@ -// Copyright 2015-2022 the openage authors. See copying.md for legal info. +// Copyright 2015-2023 the openage authors. See copying.md for legal info. #include diff --git a/openage/convert/entity_object/export/metadata_export.py b/openage/convert/entity_object/export/metadata_export.py index b07b8da2e3..d01e1d53f5 100644 --- a/openage/convert/entity_object/export/metadata_export.py +++ b/openage/convert/entity_object/export/metadata_export.py @@ -15,8 +15,10 @@ if typing.TYPE_CHECKING: from openage.util.observer import Observable - from openage.convert.entity_object.export.formats.sprite_metadata import LayerMode as SpriteLayerMode - from openage.convert.entity_object.export.formats.terrain_metadata import LayerMode as TerrainLayerMode + from openage.convert.entity_object.export.formats.sprite_metadata import LayerMode\ + as SpriteLayerMode + from openage.convert.entity_object.export.formats.terrain_metadata import LayerMode\ + as TerrainLayerMode class MetadataExport(Observer): diff --git a/openage/convert/processor/conversion/aoc/media_subprocessor.py b/openage/convert/processor/conversion/aoc/media_subprocessor.py index bb2326e367..90af7ad297 100644 --- a/openage/convert/processor/conversion/aoc/media_subprocessor.py +++ b/openage/convert/processor/conversion/aoc/media_subprocessor.py @@ -1,6 +1,6 @@ # Copyright 2019-2023 the openage authors. See copying.md for legal info. # -# pylint: disable=too-many-locals,too-few-public-methods +# pylint: disable=too-many-locals,too-few-public-methods,too-many-statements """ Convert media information to metadata definitions and export requests. Subroutine of the main AoC processor. diff --git a/openage/convert/processor/conversion/hd/media_subprocessor.py b/openage/convert/processor/conversion/hd/media_subprocessor.py index 74d4c5350d..62dc1dd719 100644 --- a/openage/convert/processor/conversion/hd/media_subprocessor.py +++ b/openage/convert/processor/conversion/hd/media_subprocessor.py @@ -1,6 +1,6 @@ # Copyright 2021-2023 the openage authors. See copying.md for legal info. # -# pylint: disable=too-many-locals +# pylint: disable=too-many-locals,too-many-statements """ Convert media information to metadata definitions and export From 547a5f270e419942c2ed18ea0f418a02d16a25ae Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 11 Nov 2023 22:31:48 +0100 Subject: [PATCH 76/95] Fix clang complaints. --- libopenage/curve/map_filter_iterator.h | 2 -- libopenage/gamestate/game.cpp | 2 +- libopenage/gamestate/terrain_factory.cpp | 3 +- .../gui/integration/private/gui_texture.cpp | 36 +++++++++---------- .../private/gui_texture_handle.cpp | 2 +- libopenage/renderer/opengl/window.cpp | 2 +- 6 files changed, 23 insertions(+), 24 deletions(-) diff --git a/libopenage/curve/map_filter_iterator.h b/libopenage/curve/map_filter_iterator.h index e514330f67..5e71c0789f 100644 --- a/libopenage/curve/map_filter_iterator.h +++ b/libopenage/curve/map_filter_iterator.h @@ -32,8 +32,6 @@ class MapFilterIterator : public CurveIterator { const time::time_t &to) : CurveIterator(base, container, from, to) {} - MapFilterIterator(const MapFilterIterator &) = default; - using CurveIterator::operator=; virtual bool valid() const override { diff --git a/libopenage/gamestate/game.cpp b/libopenage/gamestate/game.cpp index 121bef4f56..8e3497bfbc 100644 --- a/libopenage/gamestate/game.cpp +++ b/libopenage/gamestate/game.cpp @@ -96,7 +96,7 @@ void Game::load_path(const util::Path &base_dir, auto base_path = base_dir.resolve_native_path(); auto search_path = base_dir / mod_dir / search; - auto fileload_func = [&base_path, &mod_dir](const std::string &filename) { + auto fileload_func = [&base_path](const std::string &filename) { // nyan wants a string filepath, so we have to construct it from the // path and subpath parameters log::log(INFO << "Loading .nyan file: " << filename); diff --git a/libopenage/gamestate/terrain_factory.cpp b/libopenage/gamestate/terrain_factory.cpp index a3abd0cb42..3a46773429 100644 --- a/libopenage/gamestate/terrain_factory.cpp +++ b/libopenage/gamestate/terrain_factory.cpp @@ -9,6 +9,7 @@ #include "gamestate/api/terrain.h" #include "gamestate/terrain.h" #include "gamestate/terrain_chunk.h" +#include "gamestate/terrain_tile.h" #include "renderer/render_factory.h" #include "renderer/stages/terrain/terrain_render_entity.h" #include "time/time.h" @@ -121,7 +122,7 @@ std::shared_ptr TerrainFactory::add_chunk(const std::shared_ptr tiles{}; tiles.reserve(size[0] * size[1]); for (size_t i = 0; i < size[0] * size[1]; ++i) { - tiles.emplace_back(terrain_obj, test_texture_path, 0.0f); + tiles.push_back({terrain_obj, test_texture_path, terrain_elevation_t::zero()}); } auto chunk = std::make_shared(size, offset, std::move(tiles)); diff --git a/libopenage/renderer/gui/integration/private/gui_texture.cpp b/libopenage/renderer/gui/integration/private/gui_texture.cpp index c61b1ffe1b..d1c568eae6 100644 --- a/libopenage/renderer/gui/integration/private/gui_texture.cpp +++ b/libopenage/renderer/gui/integration/private/gui_texture.cpp @@ -40,33 +40,33 @@ bool GuiTexture::isAtlasTexture() const { } namespace { -GLuint create_compatible_texture(GLuint texture_id, GLsizei w, GLsizei h) { - glBindTexture(GL_TEXTURE_2D, texture_id); +// GLuint create_compatible_texture(GLuint texture_id, GLsizei w, GLsizei h) { +// glBindTexture(GL_TEXTURE_2D, texture_id); - GLint min_filter; - GLint mag_filter; - GLint iformat; +// GLint min_filter; +// GLint mag_filter; +// GLint iformat; - glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &min_filter); - glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &mag_filter); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &iformat); +// glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &min_filter); +// glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &mag_filter); +// glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &iformat); - GLuint new_texture_id; - glGenTextures(1, &new_texture_id); - glBindTexture(GL_TEXTURE_2D, new_texture_id); +// GLuint new_texture_id; +// glGenTextures(1, &new_texture_id); +// glBindTexture(GL_TEXTURE_2D, new_texture_id); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); - glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); +// glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - glBindTexture(GL_TEXTURE_2D, 0); +// glBindTexture(GL_TEXTURE_2D, 0); - return new_texture_id; -} +// return new_texture_id; +// } } // namespace -QSGTexture *GuiTexture::removedFromAtlas(QRhiResourceUpdateBatch *resourceUpdates /* = nullptr */) const { +QSGTexture *GuiTexture::removedFromAtlas(QRhiResourceUpdateBatch * /* resourceUpdates */ /* = nullptr */) const { if (this->isAtlasTexture()) { return this->standalone.get(); } diff --git a/libopenage/renderer/gui/integration/private/gui_texture_handle.cpp b/libopenage/renderer/gui/integration/private/gui_texture_handle.cpp index 07a840dbf1..1174d933b3 100644 --- a/libopenage/renderer/gui/integration/private/gui_texture_handle.cpp +++ b/libopenage/renderer/gui/integration/private/gui_texture_handle.cpp @@ -25,7 +25,7 @@ QSize textureSize(const SizedTextureHandle &texture_handle) { return texture_handle.size; } -QSize native_size(const TextureHandle &texture_handle) { +QSize native_size(const TextureHandle & /* texture_handle */) { return QSize(0, 0); } diff --git a/libopenage/renderer/opengl/window.cpp b/libopenage/renderer/opengl/window.cpp index 68ac012ed1..d169bff00b 100644 --- a/libopenage/renderer/opengl/window.cpp +++ b/libopenage/renderer/opengl/window.cpp @@ -146,7 +146,7 @@ std::shared_ptr GlWindow::make_renderer() { auto renderer = std::make_shared(this->get_context(), this->size * this->scale_dpr); - this->add_resize_callback([this, renderer](size_t w, size_t h, double scale) { + this->add_resize_callback([renderer](size_t w, size_t h, double scale) { // this up-scales all the default framebuffer to the "bigger" highdpi window. renderer->resize_display_target(w * scale, h * scale); }); From 5f0865e2fbd0152e853336ba2c9ad4fc26377e7a Mon Sep 17 00:00:00 2001 From: heinezen Date: Sat, 11 Nov 2023 22:45:58 +0100 Subject: [PATCH 77/95] util: Make type hint Python 3.9 compliant. --- openage/util/fslike/path.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openage/util/fslike/path.py b/openage/util/fslike/path.py index 422b9f176b..ccdf8cc2b8 100644 --- a/openage/util/fslike/path.py +++ b/openage/util/fslike/path.py @@ -4,7 +4,7 @@ Provides Path, which is analogous to pathlib.Path, and the type of FSLikeObject.root. """ -from typing import NoReturn +from typing import NoReturn, Union from io import UnsupportedOperation, TextIOWrapper import os @@ -35,7 +35,7 @@ class Path: # lower. # pylint: disable=too-many-public-methods - def __init__(self, fsobj, parts: str | bytes | bytearray | list | tuple = None): + def __init__(self, fsobj, parts: Union[str, bytes, bytearray, list, tuple] = None): if isinstance(parts, str): parts = parts.encode() From 252076e787d72df8d982b5720a5bdc731d3487fd Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 13 Dec 2023 01:56:04 +0100 Subject: [PATCH 78/95] console: Fix comment formatting. --- libopenage/console/console.cpp | 208 +++++++++++++++++---------------- libopenage/console/draw.cpp | 136 ++++++++++----------- 2 files changed, 175 insertions(+), 169 deletions(-) diff --git a/libopenage/console/console.cpp b/libopenage/console/console.cpp index 274cbc087e..a07d42b898 100644 --- a/libopenage/console/console.cpp +++ b/libopenage/console/console.cpp @@ -44,79 +44,83 @@ Console::Console(/* presenter::LegacyDisplay *display */) : Console::~Console() {} -// void Console::load_colors(std::vector &colortable) { -// for (auto &c : colortable) { -// this->termcolors.emplace_back(c); -// } +/* +void Console::load_colors(std::vector &colortable) { + for (auto &c : colortable) { + this->termcolors.emplace_back(c); + } -// if (termcolors.size() != 256) { -// throw Error(MSG(err) << "Exactly 256 terminal colors are required."); -// } -// } + if (termcolors.size() != 256) { + throw Error(MSG(err) << "Exactly 256 terminal colors are required."); + } +} +*/ void Console::register_to_engine() { // TODO: Use new renderer + /* + this->display->register_input_action(this); + this->display->register_tick_action(this); + this->display->register_drawhud_action(this); + this->display->register_resize_action(this); + + Bind the console toggle key globally + auto &action = this->display->get_action_manager(); + auto &global = this->display->get_input_manager().get_global_context(); + + global.bind(action.get("TOGGLE_CONSOLE"), [this](const input::legacy::action_arg_t &) { + this->set_visible(!this->visible); + }); + - // this->display->register_input_action(this); - // this->display->register_tick_action(this); - // this->display->register_drawhud_action(this); - // this->display->register_resize_action(this); - - // Bind the console toggle key globally - // auto &action = this->display->get_action_manager(); - // auto &global = this->display->get_input_manager().get_global_context(); - - // global.bind(action.get("TOGGLE_CONSOLE"), [this](const input::legacy::action_arg_t &) { - // this->set_visible(!this->visible); - // }); - - - // TODO: bind any needed input to InputContext - - // toggle console will take highest priority - // this->input_context.bind(action.get("TOGGLE_CONSOLE"), [this](const input::legacy::action_arg_t &) { - // this->set_visible(false); - // }); - // this->input_context.bind(input::legacy::event_class::UTF8, [this](const input::legacy::action_arg_t &arg) { - // // a single char typed into the console - // std::string utf8 = arg.e.as_utf8(); - // this->buf.write(utf8.c_str()); - // command += utf8; - // return true; - // }); - // this->input_context.bind(input::legacy::event_class::NONPRINT, [this](const input::legacy::action_arg_t &arg) { - // switch (arg.e.as_char()) { - // case 8: // remove a single UTF-8 character - // if (this->command.size() > 0) { - // util::utf8_pop_back(this->command); - // this->buf.pop_last_char(); - // } - // return true; - - // case 13: // interpret command - // this->buf.write('\n'); - // this->interpret(this->command); - // this->command = ""; - // return true; - - // default: - // return false; - // } - // }); - // this->input_context.utf8_mode = true; + TODO: bind any needed input to InputContext + + toggle console will take highest priority + this->input_context.bind(action.get("TOGGLE_CONSOLE"), [this](const input::legacy::action_arg_t &) { + this->set_visible(false); + }); + this->input_context.bind(input::legacy::event_class::UTF8, [this](const input::legacy::action_arg_t &arg) { + // a single char typed into the console + std::string utf8 = arg.e.as_utf8(); + this->buf.write(utf8.c_str()); + command += utf8; + return true; + }); + this->input_context.bind(input::legacy::event_class::NONPRINT, [this](const input::legacy::action_arg_t &arg) { + switch (arg.e.as_char()) { + case 8: // remove a single UTF-8 character + if (this->command.size() > 0) { + util::utf8_pop_back(this->command); + this->buf.pop_last_char(); + } + return true; + + case 13: // interpret command + this->buf.write('\n'); + this->interpret(this->command); + this->command = ""; + return true; + + default: + return false; + } + }); + this->input_context.utf8_mode = true; + */ } void Console::set_visible(bool /* make_visible */) { // TODO: Use new renderer - - // if (make_visible) { - // this->display->get_input_manager().push_context(&this->input_context); - // this->visible = true; - // } - // else { - // this->display->get_input_manager().remove_context(&this->input_context); - // this->visible = false; - // } + /* + if (make_visible) { + this->display->get_input_manager().push_context(&this->input_context); + this->visible = true; + } + else { + this->display->get_input_manager().remove_context(&this->input_context); + this->visible = false; + } + */ } void Console::write(const char *text) { @@ -159,55 +163,55 @@ void Console::interpret(const std::string &command) { } } } +/* +bool Console::on_tick() { + if (!this->visible) { + return true; + } -// bool Console::on_tick() { -// if (!this->visible) { -// return true; -// } - -// // TODO: handle stuff such as cursor blinking, -// // repeating held-down keys -// return true; -// } - -// bool Console::on_drawhud() { -// if (!this->visible) { -// return true; -// } + // TODO: handle stuff such as cursor blinking, + // repeating held-down keys + return true; +} -// // TODO: Use new renderer +bool Console::on_drawhud() { + if (!this->visible) { + return true; + } -// // draw::to_opengl(this->display, this); + // TODO: Use new renderer -// return true; -// } + // draw::to_opengl(this->display, this); -// bool Console::on_input(SDL_Event *e) { -// // only handle inputs if the console is visible -// if (!this->visible) { -// return true; -// } + return true; +} -// switch (e->type) { -// case SDL_KEYDOWN: -// //TODO handle key inputs +bool Console::on_input(SDL_Event *e) { + // only handle inputs if the console is visible + if (!this->visible) { + return true; + } -// //do not allow anyone else to handle this input -// return false; -// } + switch (e->type) { + case SDL_KEYDOWN: + //TODO handle key inputs -// return true; -// } + //do not allow anyone else to handle this input + return false; + } -// bool Console::on_resize(coord::viewport_delta new_size) { -// coord::pixel_t w = this->buf.get_dims().x * this->charsize.x; -// coord::pixel_t h = this->buf.get_dims().y * this->charsize.y; + return true; +} -// this->bottomleft = {(new_size.x - w) / 2, (new_size.y - h) / 2}; -// this->topright = {this->bottomleft.x + w, this->bottomleft.y - h}; +bool Console::on_resize(coord::viewport_delta new_size) { + coord::pixel_t w = this->buf.get_dims().x * this->charsize.x; + coord::pixel_t h = this->buf.get_dims().y * this->charsize.y; -// return true; -// } + this->bottomleft = {(new_size.x - w) / 2, (new_size.y - h) / 2}; + this->topright = {this->bottomleft.x + w, this->bottomleft.y - h}; + return true; +} +*/ } // namespace console } // namespace openage diff --git a/libopenage/console/draw.cpp b/libopenage/console/draw.cpp index c8835d5bcc..ba5b4588c9 100644 --- a/libopenage/console/draw.cpp +++ b/libopenage/console/draw.cpp @@ -17,73 +17,75 @@ namespace openage { namespace console { namespace draw { -// void to_opengl(presenter::LegacyDisplay *engine, Console *console) { -// coord::camhud topleft{ -// console->bottomleft.x, -// // TODO This should probably just be console->topright.y -// console->bottomleft.y + console->charsize.y * console->buf.dims.y}; -// coord::pixel_t ascender = static_cast(console->font.get_ascender()); - -// renderer::TextRenderer *text_renderer = engine->get_text_renderer(); -// text_renderer->set_font(&console->font); - -// int64_t monotime = timing::get_monotonic_time(); - -// bool fastblinking_visible = (monotime % 600000000 < 300000000); -// bool slowblinking_visible = (monotime % 300000000 < 150000000); - -// for (coord::term_t x = 0; x < console->buf.dims.x; x++) { -// coord::camhud chartopleft{topleft.x + console->charsize.x * x, 0}; - -// for (coord::term_t y = 0; y < console->buf.dims.y; y++) { -// chartopleft.y = topleft.y - console->charsize.y * y; -// buf_char p = *(console->buf.chrdataptr({x, y - console->buf.scrollback_pos})); - -// int fgcolid, bgcolid; - -// bool cursor_visible_at_current_pos = (console->buf.cursorpos == coord::term{x, y - console->buf.scrollback_pos}); - -// cursor_visible_at_current_pos &= console->buf.cursor_visible; - -// if (((p.flags & CHR_NEGATIVE) != 0) xor cursor_visible_at_current_pos) { -// bgcolid = p.fgcol; -// fgcolid = p.bgcol; -// } -// else { -// bgcolid = p.bgcol; -// fgcolid = p.fgcol; -// } - -// if ((p.flags & CHR_INVISIBLE) -// or (p.flags & CHR_BLINKING and not slowblinking_visible) -// or (p.flags & CHR_BLINKINGFAST and not fastblinking_visible)) { -// fgcolid = bgcolid; -// } - -// console->termcolors[bgcolid].use(0.8); - -// glBegin(GL_QUADS); -// { -// glVertex3f(chartopleft.x, chartopleft.y, 0); -// glVertex3f(chartopleft.x, chartopleft.y - console->charsize.y, 0); -// glVertex3f(chartopleft.x + console->charsize.x, chartopleft.y - console->charsize.y, 0); -// glVertex3f(chartopleft.x + console->charsize.x, chartopleft.y, 0); -// } -// glEnd(); - -// console->termcolors[fgcolid].use(1); - -// char utf8buf[5]; -// if (util::utf8_encode(p.cp, utf8buf) == 0) { -// //unrepresentable character (question mark in black rhombus) -// text_renderer->draw(chartopleft.x, chartopleft.y - ascender, "\uFFFD"); -// } -// else { -// text_renderer->draw(chartopleft.x, chartopleft.y - ascender, utf8buf); -// } -// } -// } -// } +/* +void to_opengl(presenter::LegacyDisplay *engine, Console *console) { + coord::camhud topleft{ + console->bottomleft.x, + // TODO This should probably just be console->topright.y + console->bottomleft.y + console->charsize.y * console->buf.dims.y}; + coord::pixel_t ascender = static_cast(console->font.get_ascender()); + + renderer::TextRenderer *text_renderer = engine->get_text_renderer(); + text_renderer->set_font(&console->font); + + int64_t monotime = timing::get_monotonic_time(); + + bool fastblinking_visible = (monotime % 600000000 < 300000000); + bool slowblinking_visible = (monotime % 300000000 < 150000000); + + for (coord::term_t x = 0; x < console->buf.dims.x; x++) { + coord::camhud chartopleft{topleft.x + console->charsize.x * x, 0}; + + for (coord::term_t y = 0; y < console->buf.dims.y; y++) { + chartopleft.y = topleft.y - console->charsize.y * y; + buf_char p = *(console->buf.chrdataptr({x, y - console->buf.scrollback_pos})); + + int fgcolid, bgcolid; + + bool cursor_visible_at_current_pos = (console->buf.cursorpos == coord::term{x, y - console->buf.scrollback_pos}); + + cursor_visible_at_current_pos &= console->buf.cursor_visible; + + if (((p.flags & CHR_NEGATIVE) != 0) xor cursor_visible_at_current_pos) { + bgcolid = p.fgcol; + fgcolid = p.bgcol; + } + else { + bgcolid = p.bgcol; + fgcolid = p.fgcol; + } + + if ((p.flags & CHR_INVISIBLE) + or (p.flags & CHR_BLINKING and not slowblinking_visible) + or (p.flags & CHR_BLINKINGFAST and not fastblinking_visible)) { + fgcolid = bgcolid; + } + + console->termcolors[bgcolid].use(0.8); + + glBegin(GL_QUADS); + { + glVertex3f(chartopleft.x, chartopleft.y, 0); + glVertex3f(chartopleft.x, chartopleft.y - console->charsize.y, 0); + glVertex3f(chartopleft.x + console->charsize.x, chartopleft.y - console->charsize.y, 0); + glVertex3f(chartopleft.x + console->charsize.x, chartopleft.y, 0); + } + glEnd(); + + console->termcolors[fgcolid].use(1); + + char utf8buf[5]; + if (util::utf8_encode(p.cp, utf8buf) == 0) { + //unrepresentable character (question mark in black rhombus) + text_renderer->draw(chartopleft.x, chartopleft.y - ascender, "\uFFFD"); + } + else { + text_renderer->draw(chartopleft.x, chartopleft.y - ascender, utf8buf); + } + } + } +} +*/ void to_terminal(Buf *buf, util::FD *fd, bool clear) { //move cursor, draw top left corner From 7b2b1fe2411fbf2f33d5a28bc8dfe5021a6ae455 Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 13 Dec 2023 01:56:23 +0100 Subject: [PATCH 79/95] buildsys: Remove obsolte comment. --- libopenage/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/libopenage/CMakeLists.txt b/libopenage/CMakeLists.txt index eb54fd8bf2..030231baf7 100644 --- a/libopenage/CMakeLists.txt +++ b/libopenage/CMakeLists.txt @@ -63,7 +63,6 @@ find_package(Threads REQUIRED) set(QT_VERSION_REQ "6.2") find_package(Qt6 ${QT_VERSION_REQ} REQUIRED COMPONENTS Core Quick Multimedia) -# find_package(Qt6Multimedia ${QT_VERSION_REQ} REQUIRED) if(WANT_BACKTRACE) find_package(GCCBacktrace) From be76f5439dc999a98bb5de4a35a95dcaeed0006b Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 13 Dec 2023 02:04:20 +0100 Subject: [PATCH 80/95] gamestate: Fix comment about static test entities. --- libopenage/gamestate/event/spawn_entity.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libopenage/gamestate/event/spawn_entity.cpp b/libopenage/gamestate/event/spawn_entity.cpp index 9558cba2a3..c2934ed58c 100644 --- a/libopenage/gamestate/event/spawn_entity.cpp +++ b/libopenage/gamestate/event/spawn_entity.cpp @@ -77,7 +77,8 @@ static const std::vector trial_test_entities = { }; // TODO: Remove hardcoded test entity references -static std::vector test_entities; // declared static so we only have to do this once +// declared static so we only have to init the vector once +static std::vector test_entities; void build_test_entities(const std::shared_ptr &gstate) { From 7f4706e9d4ef80458d3b64b973028d0b7840ff80 Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 13 Dec 2023 02:26:52 +0100 Subject: [PATCH 81/95] gamestate: Pass game entity ptr by reference. --- libopenage/gamestate/event/spawn_entity.cpp | 2 +- libopenage/gamestate/game_state.cpp | 6 +++--- libopenage/gamestate/game_state.h | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libopenage/gamestate/event/spawn_entity.cpp b/libopenage/gamestate/event/spawn_entity.cpp index c2934ed58c..155441445f 100644 --- a/libopenage/gamestate/event/spawn_entity.cpp +++ b/libopenage/gamestate/event/spawn_entity.cpp @@ -77,7 +77,7 @@ static const std::vector trial_test_entities = { }; // TODO: Remove hardcoded test entity references -// declared static so we only have to init the vector once +// declared static so we only have to build the vector once static std::vector test_entities; diff --git a/libopenage/gamestate/game_state.cpp b/libopenage/gamestate/game_state.cpp index fba3826779..9de7c69bff 100644 --- a/libopenage/gamestate/game_state.cpp +++ b/libopenage/gamestate/game_state.cpp @@ -23,21 +23,21 @@ const std::shared_ptr &GameState::get_db_view() { return this->db_view; } -void GameState::add_game_entity(const std::shared_ptr entity) { +void GameState::add_game_entity(const std::shared_ptr &entity) { if (this->game_entities.contains(entity->get_id())) [[unlikely]] { throw Error(MSG(err) << "Game entity with ID " << entity->get_id() << " already exists"); } this->game_entities[entity->get_id()] = entity; } -void GameState::add_player(const std::shared_ptr player) { +void GameState::add_player(const std::shared_ptr &player) { if (this->players.contains(player->get_id())) [[unlikely]] { throw Error(MSG(err) << "Player with ID " << player->get_id() << " already exists"); } this->players[player->get_id()] = player; } -void GameState::set_terrain(const std::shared_ptr terrain) { +void GameState::set_terrain(const std::shared_ptr &terrain) { this->terrain = terrain; } diff --git a/libopenage/gamestate/game_state.h b/libopenage/gamestate/game_state.h index 6cce1b09b1..401070780c 100644 --- a/libopenage/gamestate/game_state.h +++ b/libopenage/gamestate/game_state.h @@ -60,21 +60,21 @@ class GameState : public openage::event::State { * * @param entity New game entity. */ - void add_game_entity(const std::shared_ptr entity); + void add_game_entity(const std::shared_ptr &entity); /** * Add a new player to the index. * * @param player New player. */ - void add_player(const std::shared_ptr player); + void add_player(const std::shared_ptr &player); /** * Set the terrain of the current game. * * @param terrain Terrain object. */ - void set_terrain(const std::shared_ptr terrain); + void set_terrain(const std::shared_ptr &terrain); /** * Get a game entity by its ID. From 892ceb757d4b37ec45923c4fab3d2fa45d78a05a Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 13 Dec 2023 02:29:11 +0100 Subject: [PATCH 82/95] gamestate: Make 'Player' moveable. --- libopenage/gamestate/player.cpp | 11 ++++++++++ libopenage/gamestate/player.h | 37 ++++++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/libopenage/gamestate/player.cpp b/libopenage/gamestate/player.cpp index e57c4d8a35..cb7aeed3ea 100644 --- a/libopenage/gamestate/player.cpp +++ b/libopenage/gamestate/player.cpp @@ -13,6 +13,13 @@ Player::Player(player_id_t id, db_view{db_view} { } +std::shared_ptr Player::copy(entity_id_t id) { + auto copy = std::shared_ptr(new Player(*this)); + copy->set_id(id); + + return copy; +} + player_id_t Player::get_id() const { return this->id; } @@ -21,4 +28,8 @@ const std::shared_ptr &Player::get_db_view() const { return this->db_view; } +void Player::set_id(entity_id_t id) { + this->id = id; +} + } // namespace openage::gamestate diff --git a/libopenage/gamestate/player.h b/libopenage/gamestate/player.h index d9bdbe3bd2..a7eb5bac4d 100644 --- a/libopenage/gamestate/player.h +++ b/libopenage/gamestate/player.h @@ -27,15 +27,20 @@ class Player { Player(player_id_t id, const std::shared_ptr &db_view); - // players can't be copied to prevent duplicate IDs - Player(const Player &) = delete; - Player(Player &&) = delete; - - Player &operator=(const Player &) = delete; - Player &operator=(Player &&) = delete; + Player(Player &&) = default; + Player &operator=(Player &&) = default; ~Player() = default; + /** + * Copy this player. + * + * @param id Unique identifier. + * + * @return Copy of this player. + */ + std::shared_ptr copy(entity_id_t id); + /** * Get the unique ID of the player. * @@ -50,11 +55,29 @@ class Player { */ const std::shared_ptr &get_db_view() const; +protected: + /** + * A player cannot be default copied because of their unique ID. + * + * \p copy() must be used instead. + */ + Player(const Player &) = default; + Player &operator=(const Player &) = default; + private: + /** + * Set the unique identifier of this player. + * + * Only called by \p copy(). + * + * @param id New ID. + */ + void set_id(entity_id_t id); + /** * Player ID. Must be unique. */ - const player_id_t id; + player_id_t id; /** * Player view of the nyan game data database. From 9d4c3ba6786d0dc973369e10ac67d30a25859d46 Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 13 Dec 2023 02:38:28 +0100 Subject: [PATCH 83/95] gamestate: Pass terrain chunk by reference. --- libopenage/gamestate/terrain.cpp | 2 +- libopenage/gamestate/terrain.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libopenage/gamestate/terrain.cpp b/libopenage/gamestate/terrain.cpp index 6a733a86d7..f31fc648b8 100644 --- a/libopenage/gamestate/terrain.cpp +++ b/libopenage/gamestate/terrain.cpp @@ -18,7 +18,7 @@ Terrain::Terrain() : // TODO: Get actual size of terrain. } -void Terrain::add_chunk(const std::shared_ptr chunk) { +void Terrain::add_chunk(const std::shared_ptr &chunk) { this->chunks.push_back(chunk); } diff --git a/libopenage/gamestate/terrain.h b/libopenage/gamestate/terrain.h index 71f0bd63d7..d91a432a02 100644 --- a/libopenage/gamestate/terrain.h +++ b/libopenage/gamestate/terrain.h @@ -32,7 +32,7 @@ class Terrain { * * @param chunk New chunk. */ - void add_chunk(const std::shared_ptr chunk); + void add_chunk(const std::shared_ptr &chunk); /** * Get the chunks of the terrain. From d63518944bba935cec6fb209870ae5952f7aec3b Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 13 Dec 2023 02:41:32 +0100 Subject: [PATCH 84/95] gamestate: Fix missing std::move. --- libopenage/gamestate/terrain_chunk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libopenage/gamestate/terrain_chunk.cpp b/libopenage/gamestate/terrain_chunk.cpp index a6d10251b1..9fc5422b65 100644 --- a/libopenage/gamestate/terrain_chunk.cpp +++ b/libopenage/gamestate/terrain_chunk.cpp @@ -10,7 +10,7 @@ TerrainChunk::TerrainChunk(const util::Vector2s size, const std::vector &&tiles) : size{size}, offset{offset}, - tiles{tiles} { + tiles{std::move(tiles)} { if (this->size[0] > MAX_CHUNK_WIDTH || this->size[1] > MAX_CHUNK_HEIGHT) { throw Error(MSG(err) << "Terrain chunk size exceeds maximum size: " << this->size[0] << "x" << this->size[1] << " > " From 8d779ed9ca500357af365d69b9c3bfe1f2f82ba2 Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 13 Dec 2023 02:45:17 +0100 Subject: [PATCH 85/95] input: Pass controllers by reference. --- libopenage/input/input_manager.cpp | 6 +++--- libopenage/input/input_manager.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/libopenage/input/input_manager.cpp b/libopenage/input/input_manager.cpp index f9d729b9ba..47ff5c1834 100644 --- a/libopenage/input/input_manager.cpp +++ b/libopenage/input/input_manager.cpp @@ -19,15 +19,15 @@ InputManager::InputManager() : gui_input{nullptr} { } -void InputManager::set_gui(const std::shared_ptr gui_input) { +void InputManager::set_gui(const std::shared_ptr &gui_input) { this->gui_input = gui_input; } -void InputManager::set_camera_controller(const std::shared_ptr controller) { +void InputManager::set_camera_controller(const std::shared_ptr &controller) { this->camera_controller = controller; } -void InputManager::set_engine_controller(const std::shared_ptr controller) { +void InputManager::set_engine_controller(const std::shared_ptr &controller) { this->engine_controller = controller; } diff --git a/libopenage/input/input_manager.h b/libopenage/input/input_manager.h index 17e66a28be..f81a5a5bc4 100644 --- a/libopenage/input/input_manager.h +++ b/libopenage/input/input_manager.h @@ -43,21 +43,21 @@ class InputManager { * * @param gui_input GUI input handler. */ - void set_gui(const std::shared_ptr gui_input); + void set_gui(const std::shared_ptr &gui_input); /** * Set the controller for the camera. * * @param controller Camera controller. */ - void set_camera_controller(const std::shared_ptr controller); + void set_camera_controller(const std::shared_ptr &controller); /** * Set the controller for the engine. * * @param controller Engine controller. */ - void set_engine_controller(const std::shared_ptr controller); + void set_engine_controller(const std::shared_ptr &controller); /** * returns the global keybind context. From 0e70ea89356dc7284b018dd6731a574b7311eb5c Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 13 Dec 2023 02:47:53 +0100 Subject: [PATCH 86/95] pathing: Remove obsolete method. --- libopenage/pathfinding/a_star.cpp | 15 --------------- libopenage/pathfinding/a_star.h | 7 ------- 2 files changed, 22 deletions(-) diff --git a/libopenage/pathfinding/a_star.cpp b/libopenage/pathfinding/a_star.cpp index b53aed88f4..f80879eb91 100644 --- a/libopenage/pathfinding/a_star.cpp +++ b/libopenage/pathfinding/a_star.cpp @@ -37,21 +37,6 @@ Path to_point(coord::phys3 start, return a_star(start, valid_end, heuristic, passable); } - -// Path to_object(openage::TerrainObject *to_move, -// openage::TerrainObject *end, -// coord::phys_t rad) { -// coord::phys3 start = to_move->pos.draw; -// auto valid_end = [&](const coord::phys3 &pos) -> bool { -// return end->from_edge(pos) < rad; -// }; -// auto heuristic = [&](const coord::phys3 &pos) -> cost_t { -// return (end->from_edge(pos) - to_move->min_axis() / 2L).to_float(); -// }; -// return a_star(start, valid_end, heuristic, to_move->passable); -// } - - Path find_nearest(coord::phys3 start, std::function valid_end, std::function passable) { diff --git a/libopenage/pathfinding/a_star.h b/libopenage/pathfinding/a_star.h index a7cc5aa75e..23d3e76747 100644 --- a/libopenage/pathfinding/a_star.h +++ b/libopenage/pathfinding/a_star.h @@ -18,13 +18,6 @@ Path to_point(coord::phys3 start, coord::phys3 end, std::function passable); -/** - * path between 2 objects, with how close to come to end point - */ -// Path to_object(TerrainObject *to_move, -// TerrainObject *end, -// coord::phys_t rad); - /** * path to nearest object with lambda */ From 21cffdb07a9c538da2758352e4ba4b88e6706836 Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 13 Dec 2023 02:54:05 +0100 Subject: [PATCH 87/95] gui: Remove obsolete method. --- .../gui/integration/private/gui_texture.cpp | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/libopenage/renderer/gui/integration/private/gui_texture.cpp b/libopenage/renderer/gui/integration/private/gui_texture.cpp index d1c568eae6..daa6f4020a 100644 --- a/libopenage/renderer/gui/integration/private/gui_texture.cpp +++ b/libopenage/renderer/gui/integration/private/gui_texture.cpp @@ -39,33 +39,6 @@ bool GuiTexture::isAtlasTexture() const { return openage::renderer::gui::isAtlasTexture(this->texture_handle); } -namespace { -// GLuint create_compatible_texture(GLuint texture_id, GLsizei w, GLsizei h) { -// glBindTexture(GL_TEXTURE_2D, texture_id); - -// GLint min_filter; -// GLint mag_filter; -// GLint iformat; - -// glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &min_filter); -// glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &mag_filter); -// glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &iformat); - -// GLuint new_texture_id; -// glGenTextures(1, &new_texture_id); -// glBindTexture(GL_TEXTURE_2D, new_texture_id); - -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); -// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); - -// glTexImage2D(GL_TEXTURE_2D, 0, iformat, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - -// glBindTexture(GL_TEXTURE_2D, 0); - -// return new_texture_id; -// } -} // namespace - QSGTexture *GuiTexture::removedFromAtlas(QRhiResourceUpdateBatch * /* resourceUpdates */ /* = nullptr */) const { if (this->isAtlasTexture()) { return this->standalone.get(); From 11075b0ad88771bf2f1a5a3a7fe91dee99825a57 Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 13 Dec 2023 02:55:53 +0100 Subject: [PATCH 88/95] renderer: Remove specific command hint. --- libopenage/renderer/opengl/error.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libopenage/renderer/opengl/error.cpp b/libopenage/renderer/opengl/error.cpp index 790847fccc..c47bf5a85d 100644 --- a/libopenage/renderer/opengl/error.cpp +++ b/libopenage/renderer/opengl/error.cpp @@ -61,10 +61,11 @@ void gl_check_error() { // unknown error state errormsg = "unknown error"; } - throw Error(MSG(err) << "OpenGL error state after running draw method: " << glerrorstate << "\n" - "\t" + throw Error(MSG(err) << "OpenGL error state after running draw method: " + << glerrorstate << "\n" + "\t" << errormsg << "\n" - << "Run the game with --gl-debug to get more information: './run game --gl-debug'."); + << "Run the engine with --gl-debug to get more information."); } } From ca35303965dc6d77a3fcfa3eff0e17c3e8e96aaf Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 13 Dec 2023 03:07:46 +0100 Subject: [PATCH 89/95] renderer: Remove reinterpret cast from memcpy operations. --- libopenage/renderer/demo/demo_5.cpp | 2 +- libopenage/renderer/resources/mesh_data.cpp | 2 +- libopenage/renderer/stages/terrain/terrain_chunk.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libopenage/renderer/demo/demo_5.cpp b/libopenage/renderer/demo/demo_5.cpp index b8adc896e3..afea99a30b 100644 --- a/libopenage/renderer/demo/demo_5.cpp +++ b/libopenage/renderer/demo/demo_5.cpp @@ -78,7 +78,7 @@ void renderer_demo_5(const util::Path &path) { auto const vert_data_size = verts.size() * sizeof(float); std::vector vert_data(vert_data_size); - std::memcpy(vert_data.data(), reinterpret_cast(verts.data()), vert_data_size); + std::memcpy(vert_data.data(), verts.data(), vert_data_size); resources::MeshData meshdata{std::move(vert_data), info}; diff --git a/libopenage/renderer/resources/mesh_data.cpp b/libopenage/renderer/resources/mesh_data.cpp index 74fb72b629..98c5d7dbdb 100644 --- a/libopenage/renderer/resources/mesh_data.cpp +++ b/libopenage/renderer/resources/mesh_data.cpp @@ -123,7 +123,7 @@ MeshData create_float_mesh(const std::array &src) { auto const data_size = size * sizeof(float); std::vector verts(data_size); - std::memcpy(verts.data(), reinterpret_cast(src.data()), data_size); + std::memcpy(verts.data(), src.data(), data_size); VertexInputInfo info{ {vertex_input_t::V2F32, vertex_input_t::V2F32}, diff --git a/libopenage/renderer/stages/terrain/terrain_chunk.cpp b/libopenage/renderer/stages/terrain/terrain_chunk.cpp index 8ca1b8970a..1dfa77b5c0 100644 --- a/libopenage/renderer/stages/terrain/terrain_chunk.cpp +++ b/libopenage/renderer/stages/terrain/terrain_chunk.cpp @@ -99,11 +99,11 @@ std::shared_ptr TerrainChunk::create_mesh() { auto const vert_data_size = dst_verts.size() * sizeof(float); std::vector vert_data(vert_data_size); - std::memcpy(vert_data.data(), reinterpret_cast(dst_verts.data()), vert_data_size); + std::memcpy(vert_data.data(), dst_verts.data(), vert_data_size); auto const idx_data_size = idxs.size() * sizeof(uint16_t); std::vector idx_data(idx_data_size); - std::memcpy(idx_data.data(), reinterpret_cast(idxs.data()), idx_data_size); + std::memcpy(idx_data.data(), idxs.data(), idx_data_size); resources::MeshData meshdata{std::move(vert_data), std::move(idx_data), info}; From 5ae997bd33c2d54e1a51b01e949f5a148ad4e120 Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 13 Dec 2023 03:17:25 +0100 Subject: [PATCH 90/95] util: Remove obsolete classes. --- libopenage/util/CMakeLists.txt | 1 - libopenage/util/profiler.cpp | 202 --------------------------------- libopenage/util/profiler.h | 125 -------------------- 3 files changed, 328 deletions(-) delete mode 100644 libopenage/util/profiler.cpp delete mode 100644 libopenage/util/profiler.h diff --git a/libopenage/util/CMakeLists.txt b/libopenage/util/CMakeLists.txt index 1a2bee51e7..d278f4b427 100644 --- a/libopenage/util/CMakeLists.txt +++ b/libopenage/util/CMakeLists.txt @@ -21,7 +21,6 @@ add_sources(libopenage misc_test.cpp os.cpp path.cpp - profiler.cpp quaternion.cpp quaternion_test.cpp repr.cpp diff --git a/libopenage/util/profiler.cpp b/libopenage/util/profiler.cpp deleted file mode 100644 index 95ebd85af7..0000000000 --- a/libopenage/util/profiler.cpp +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#include "profiler.h" -#include "../renderer/color.h" -#include "misc.h" - -#include -#include -#include -#include - -namespace openage::util { - -// Profiler::Profiler() : -// {} - - -// Profiler::~Profiler() { -// this->unregister_all(); -// } - -// void Profiler::register_component(const std::string &com, color component_color) { -// if (this->registered(com)) { -// return; -// } - -// component_time_data cdt; -// cdt.display_name = com; -// cdt.drawing_color = component_color; - -// for (auto &val : cdt.history) { -// val = 0; -// } - -// this->components[com] = cdt; -// } - -// void Profiler::unregister_component(const std::string &com) { -// if (not this->registered(com)) { -// return; -// } - -// this->components.erase(com); -// } - -// void Profiler::unregister_all() { -// std::vector registered_components = this->registered_components(); - -// for (auto com : registered_components) { -// this->unregister_component(com); -// } -// } - -// std::vector Profiler::registered_components() { -// std::vector registered_components; -// for (auto &pair : this->components) { -// registered_components.push_back(pair.first); -// } - -// return registered_components; -// } - -// void Profiler::start_measure(const std::string &com, color component_color) { -// if (not this->engine_in_debug_mode()) { -// return; -// } - -// if (not this->registered(com)) { -// this->register_component(com, component_color); -// } - -// this->components[com].start = std::chrono::high_resolution_clock::now(); -// } - -// void Profiler::end_measure(const std::string &com) { -// if (not this->engine_in_debug_mode()) { -// return; -// } - -// if (this->registered(com)) { -// std::chrono::high_resolution_clock::time_point end = std::chrono::high_resolution_clock::now(); -// this->components[com].duration = end - this->components[com].start; -// } -// } - -// void Profiler::draw_component_performance(const std::string &com) { -// color rgb = this->components[com].drawing_color; -// glColor4f(rgb.r, rgb.g, rgb.b, 1.0); - -// glLineWidth(1.0); -// glBegin(GL_LINE_STRIP); -// float x_offset = 0.0; -// float offset_factor = static_cast(PROFILER_CANVAS_WIDTH) / static_cast(MAX_DURATION_HISTORY); -// float percentage_factor = static_cast(PROFILER_CANVAS_HEIGHT) / 100.0; - -// for (auto i = this->insert_pos; mod(i, MAX_DURATION_HISTORY) != mod(this->insert_pos - 1, MAX_DURATION_HISTORY); ++i) { -// i = mod(i, MAX_DURATION_HISTORY); - -// auto percentage = this->components[com].history.at(i); -// glVertex3f(PROFILER_CANVAS_POSITION_X + x_offset, PROFILER_CANVAS_POSITION_Y + percentage * percentage_factor, 0.0); -// x_offset += offset_factor; -// } -// glEnd(); - -// // reset color -// glColor4f(1.0, 1.0, 1.0, 1.0); -// } - -// void Profiler::show(bool debug_mode) { -// if (debug_mode) { -// this->show(); -// } -// } - -// // void Profiler::show() { -// // this->draw_canvas(); -// // this->draw_legend(); - -// // for (auto com : this->components) { -// // this->draw_component_performance(com.first); -// // } -// // } - -// bool Profiler::registered(const std::string &com) const { -// return this->components.find(com) != this->components.end(); -// } - -// unsigned Profiler::size() const { -// return this->components.size(); -// } - -// void Profiler::start_frame_measure() { -// if (this->engine_in_debug_mode()) { -// this->frame_start = std::chrono::high_resolution_clock::now(); -// } -// } - -// void Profiler::end_frame_measure() { -// if (not this->engine_in_debug_mode()) { -// return; -// } - -// auto frame_end = std::chrono::high_resolution_clock::now(); -// this->frame_duration = frame_end - this->frame_start; - -// for (auto com : this->registered_components()) { -// double percentage = this->duration_to_percentage(this->components[com].duration); -// this->append_to_history(com, percentage); -// } - -// this->insert_pos++; -// } - -// // void Profiler::draw_canvas() { -// // glColor4f(0.2, 0.2, 0.2, PROFILER_CANVAS_ALPHA); -// // glRecti(PROFILER_CANVAS_POSITION_X, -// // PROFILER_CANVAS_POSITION_Y, -// // PROFILER_CANVAS_POSITION_X + PROFILER_CANVAS_WIDTH, -// // PROFILER_CANVAS_POSITION_Y + PROFILER_CANVAS_HEIGHT); -// // } - -// // void Profiler::draw_legend() { -// // int offset = 0; -// // for (auto com : this->components) { -// // glColor4f(com.second.drawing_color.r, com.second.drawing_color.g, com.second.drawing_color.b, 1.0); -// // int box_x = PROFILER_CANVAS_POSITION_X + 2; -// // int box_y = PROFILER_CANVAS_POSITION_Y - PROFILER_COM_BOX_HEIGHT - 2 - offset; -// // glRecti(box_x, box_y, box_x + PROFILER_COM_BOX_WIDTH, box_y + PROFILER_COM_BOX_HEIGHT); - -// // glColor4f(0.2, 0.2, 0.2, 1); -// // coord::viewport position = coord::viewport{box_x + PROFILER_COM_BOX_WIDTH + 2, box_y + 2}; -// // // this->display->render_text(position, 12, renderer::Colors::WHITE, "%s", com.second.display_name.c_str()); - -// // offset += PROFILER_COM_BOX_HEIGHT + 2; -// // } -// // } - -// double Profiler::duration_to_percentage(std::chrono::high_resolution_clock::duration duration) { -// double dur = std::chrono::duration_cast(duration).count(); -// double ref = std::chrono::duration_cast(this->frame_duration).count(); -// double percentage = dur / ref * 100; -// return percentage; -// } - -// void Profiler::append_to_history(const std::string &com, double percentage) { -// if (this->insert_pos == MAX_DURATION_HISTORY) { -// this->insert_pos = 0; -// } -// this->components[com].history[this->insert_pos] = percentage; -// } - -// bool Profiler::engine_in_debug_mode() { -// // if (this->display->drawing_debug_overlay.value) { -// // return true; -// // } -// // else { -// // return false; -// // } -// return true; -// } - -} // namespace openage::util diff --git a/libopenage/util/profiler.h b/libopenage/util/profiler.h deleted file mode 100644 index 1b3641d576..0000000000 --- a/libopenage/util/profiler.h +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2015-2023 the openage authors. See copying.md for legal info. - -#pragma once - -#include -#include -#include -#include -#include - -constexpr int MAX_DURATION_HISTORY = 100; -constexpr int PROFILER_CANVAS_WIDTH = 250; -constexpr int PROFILER_CANVAS_HEIGHT = 120; -constexpr int PROFILER_CANVAS_POSITION_X = 0; -constexpr int PROFILER_CANVAS_POSITION_Y = 300; -constexpr float PROFILER_CANVAS_ALPHA = 0.6f; -constexpr int PROFILER_COM_BOX_WIDTH = 30; -constexpr int PROFILER_COM_BOX_HEIGHT = 15; - -namespace openage { - -namespace util { - -struct color { - float r, g, b; -}; - -struct component_time_data { - std::string display_name; - color drawing_color; - std::chrono::high_resolution_clock::time_point start; - std::chrono::high_resolution_clock::duration duration; - std::array history; -}; - -// class Profiler { -// public: -// Profiler(); -// ~Profiler(); - -// /** -// * registers a component -// * @param com the identifier to distinguish the components -// * @param component_color color of the plotted line -// */ -// void register_component(const std::string &com, color component_color); - -// /** -// * unregisters an individual component -// * @param com component name which should be unregistered -// */ -// void unregister_component(const std::string &com); - -// /** -// * unregisters all remaining components -// */ -// void unregister_all(); - -// /** -// *returns a vector of registered component names -// */ -// std::vector registered_components(); - -// /* -// * starts a measurement for the component com. If com is not yet -// * registered, its getting registered and the profiler uses the color -// * information given by component_color. The default value is white. -// */ -// void start_measure(const std::string &com, color component_color = {1.0, 1.0, 1.0}); - -// /* -// * stops the measurement for the component com. If com is not yet -// * registered it does nothing. -// */ -// void end_measure(const std::string &com); - -// /* -// * draws the profiler gui if debug_mode is set -// */ -// void show(bool debug_mode); - -// /* -// * draws the profiler gui -// */ -// void show(); - -// /* -// * true if the component com is already registered, otherwise false -// */ -// bool registered(const std::string &com) const; - -// /* -// * returns the number of registered components -// */ -// unsigned size() const; - -// /** -// * sets the start point for the actual frame which is used as a reference -// * value for the registered components -// */ -// void start_frame_measure(); - -// /** -// * sets the end point for the reference time used to compute the portions -// * of the components. Each recorded measurement for the registered components -// * get appended to their history complete the measurement. -// */ -// void end_frame_measure(); - -// private: -// // void draw_canvas(); -// // void draw_legend(); -// void draw_component_performance(const std::string &com); -// double duration_to_percentage(std::chrono::high_resolution_clock::duration duration); -// void append_to_history(const std::string &com, double percentage); -// bool engine_in_debug_mode(); - -// std::chrono::high_resolution_clock::time_point frame_start; -// std::chrono::high_resolution_clock::duration frame_duration; -// std::unordered_map components; -// int insert_pos = 0; -// }; - -} // namespace util -} // namespace openage From d07c4606b72d038562af78220b8cb0734f516bd0 Mon Sep 17 00:00:00 2001 From: heinezen Date: Wed, 13 Dec 2023 03:18:19 +0100 Subject: [PATCH 91/95] renderer: Comment out currently unused param. --- libopenage/renderer/stages/terrain/terrain_chunk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libopenage/renderer/stages/terrain/terrain_chunk.cpp b/libopenage/renderer/stages/terrain/terrain_chunk.cpp index 1dfa77b5c0..dcea61585e 100644 --- a/libopenage/renderer/stages/terrain/terrain_chunk.cpp +++ b/libopenage/renderer/stages/terrain/terrain_chunk.cpp @@ -21,7 +21,7 @@ void TerrainChunk::set_render_entity(const std::shared_ptr this->render_entity = entity; } -void TerrainChunk::fetch_updates(const time::time_t &time) { +void TerrainChunk::fetch_updates(const time::time_t & /* time */) { // TODO: Don't create model if render entity is not set if (not this->render_entity) { return; From 10bc91da5a562d8b06063b332da60edb31bfda39 Mon Sep 17 00:00:00 2001 From: heinezen Date: Fri, 15 Dec 2023 15:55:26 +0100 Subject: [PATCH 92/95] fix comment indent with tabs. --- libopenage/gamestate/terrain.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libopenage/gamestate/terrain.h b/libopenage/gamestate/terrain.h index d91a432a02..c84b926d9a 100644 --- a/libopenage/gamestate/terrain.h +++ b/libopenage/gamestate/terrain.h @@ -43,11 +43,11 @@ class Terrain { /** * Attach a renderer which enables graphical display. - * - * TODO: We currently have to do attach this here too in addition to the terrain - * factory because the renderer gets attached AFTER the terrain is - * already created. In the future, the game should wait for the renderer - * before creating the terrain. + * + * TODO: We currently have to do attach this here too in addition to the terrain + * factory because the renderer gets attached AFTER the terrain is + * already created. In the future, the game should wait for the renderer + * before creating the terrain. * * @param render_factory Factory for creating connector objects for gamestate->renderer * communication. From ece991d72bb96dbcc5445d1b6cec406e91dbefbf Mon Sep 17 00:00:00 2001 From: heinezen Date: Sun, 17 Dec 2023 16:55:31 +0100 Subject: [PATCH 93/95] ci: Overwrite exsting packages on macOS. --- .github/workflows/macosx-ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/macosx-ci.yml b/.github/workflows/macosx-ci.yml index e38c9e3e6e..eba3c5fd98 100644 --- a/.github/workflows/macosx-ci.yml +++ b/.github/workflows/macosx-ci.yml @@ -43,7 +43,7 @@ jobs: - name: Install clang / LLVM 15.0.0 run: | set -x - brew install wget + brew install --force wget mkdir -p /tmp/clang cd /tmp/clang wget https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.0/clang+llvm-15.0.0-x86_64-apple-darwin.tar.xz -O clang-15.0.0.tar.xz @@ -53,15 +53,15 @@ jobs: mv clang+llvm-15.0.0-x86_64-apple-darwin clang-15.0.0 ~/clang-15.0.0/bin/clang++ --version - name: Brew install DeJaVu fonts - run: brew tap homebrew/cask-fonts && brew install font-dejavu + run: brew tap homebrew/cask-fonts && brew install --force font-dejavu - name: Remove python's 2to3 link so that 'brew link' does not fail run: rm /usr/local/bin/2to3* && rm /usr/local/bin/idle3* - name: Install environment helpers with homebrew - run: brew install ccache + run: brew install --force ccache - name: Install dependencies with homebrew - run: brew install libepoxy freetype fontconfig harfbuzz opus opusfile qt6 libogg libpng toml11 eigen + run: brew install --force libepoxy freetype fontconfig harfbuzz opus opusfile qt6 libogg libpng toml11 eigen - name: Install nyan dependencies with homebrew - run: brew install flex make + run: brew install --force flex make - name: Install python3 packages # cython, numpy and pygments are in homebrew, # but "cython is keg-only, which means it was not symlinked into /usr/local" From 5e656c4b6eb3c36b3f9d1554155e74bd0bdef2c7 Mon Sep 17 00:00:00 2001 From: heinezen Date: Fri, 15 Dec 2023 19:54:51 +0100 Subject: [PATCH 94/95] doc: Changelog for release 0.5.3. --- doc/changelogs/engine/v0.5.3.md | 50 +++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 doc/changelogs/engine/v0.5.3.md diff --git a/doc/changelogs/engine/v0.5.3.md b/doc/changelogs/engine/v0.5.3.md new file mode 100644 index 0000000000..23b72afe58 --- /dev/null +++ b/doc/changelogs/engine/v0.5.3.md @@ -0,0 +1,50 @@ +# [0.5.3] - 2023-12-15 +All notable changes for version [0.5.3] 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]. + +## Added + +- Temporary file/directory support for Python files +- More debug info in converter +- More fixed-point math functions +- `setuptools` is now conditional dependency for Python >= 3.12 && Cython < 3.1 + +## Changed + +- Make `main` the default entrypoint command for openage binary + +## Removed + +- Legacy subsystem code + - Asset management (yes, there were 3 deprecated asset managers) + - `openage::AssetManager` + - `openage::LegacyAssetManager` + - `openage::presenter::AssetManager` + - Deprecated Coordinate types (`libopenage/coord`) + - CoordManager + - Deprecated transformations between types + - Gamedata dummy classes (`libopenage/gamedata`) + - Old gamestate + - Game logic (`libopenage/gamestate/old`) + - Unit handling (`libopenage/unit`) + - Old input system (`libopenage/input/legacy`) + - Old GUI (`libopenage/gui`) + - Old renderer + - Logic (`libopenage/presenter/legacy`) + - Data classes (texure, etc.) + - Old Terrain (`libopenage/terrain`) + +## Fixed + +- Version tag format without `--long` crashes on tagged commits +- Dangling reference in modpack info file loading +- No graphics visible on Wayland +- Wrong anchor positions when sprite is mirrored +- Several typos in documentation + + +## Full commit log + +https://github.com/SFTtech/openage/compare/v0.5.2...v0.5.3 From 298e09d12b500458e779debd4eff3df13d21eeae Mon Sep 17 00:00:00 2001 From: heinezen Date: Fri, 15 Dec 2023 19:57:22 +0100 Subject: [PATCH 95/95] Bump version to 0.5.3 --- openage_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openage_version b/openage_version index cb0c939a93..be14282b7f 100644 --- a/openage_version +++ b/openage_version @@ -1 +1 @@ -0.5.2 +0.5.3