From 79c3462396fd4e1dcb7d1c9a2ef7bad741afa3e3 Mon Sep 17 00:00:00 2001 From: hop311 Date: Fri, 22 Mar 2024 23:28:28 +0000 Subject: GFX objectTypes loading framework + Actor loading --- src/openvic-simulation/interface/GFX.cpp | 133 -------------- src/openvic-simulation/interface/GFX.hpp | 192 --------------------- src/openvic-simulation/interface/GFXObject.cpp | 144 ++++++++++++++++ src/openvic-simulation/interface/GFXObject.hpp | 81 +++++++++ src/openvic-simulation/interface/GFXSprite.cpp | 133 ++++++++++++++ src/openvic-simulation/interface/GFXSprite.hpp | 192 +++++++++++++++++++++ src/openvic-simulation/interface/GUI.hpp | 2 +- src/openvic-simulation/interface/UI.cpp | 14 +- src/openvic-simulation/interface/UI.hpp | 2 + .../types/fixed_point/FixedPoint.hpp | 12 +- 10 files changed, 577 insertions(+), 328 deletions(-) delete mode 100644 src/openvic-simulation/interface/GFX.cpp delete mode 100644 src/openvic-simulation/interface/GFX.hpp create mode 100644 src/openvic-simulation/interface/GFXObject.cpp create mode 100644 src/openvic-simulation/interface/GFXObject.hpp create mode 100644 src/openvic-simulation/interface/GFXSprite.cpp create mode 100644 src/openvic-simulation/interface/GFXSprite.hpp (limited to 'src') diff --git a/src/openvic-simulation/interface/GFX.cpp b/src/openvic-simulation/interface/GFX.cpp deleted file mode 100644 index 06d4cd3..0000000 --- a/src/openvic-simulation/interface/GFX.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include "GFX.hpp" - -using namespace OpenVic; -using namespace OpenVic::GFX; -using namespace OpenVic::NodeTools; - -Font::Font( - std::string_view new_identifier, colour_argb_t new_colour, std::string_view new_fontname, std::string_view new_charset, - uint32_t new_height -) : HasIdentifierAndAlphaColour { new_identifier, new_colour, false }, fontname { new_fontname }, charset { new_charset }, - height { new_height } {} - -node_callback_t Sprite::expect_sprites(length_callback_t length_callback, callback_t&&> callback) { - return expect_dictionary_keys_and_length( - length_callback, - "spriteType", ZERO_OR_MORE, _expect_instance(callback), - "progressbartype", ZERO_OR_MORE, _expect_instance(callback), - "PieChartType", ZERO_OR_MORE, _expect_instance(callback), - "LineChartType", ZERO_OR_MORE, _expect_instance(callback), - "textSpriteType", ZERO_OR_MORE, _expect_instance(callback), - "maskedShieldType", ZERO_OR_MORE, _expect_instance(callback), - "tileSpriteType", ZERO_OR_MORE, _expect_instance(callback), - "corneredTileSpriteType", ZERO_OR_MORE, _expect_instance(callback), - - /* Each only has one vanilla instance which isn't used anywhere. */ - "BarChartType", ZERO_OR_MORE, success_callback, - "scrollingSprite", ZERO_OR_MORE, success_callback - ); -} - -TextureSprite::TextureSprite() : texture_file {} {} - -bool TextureSprite::_fill_key_map(case_insensitive_key_map_t& key_map) { - bool ret = Sprite::_fill_key_map(key_map); - ret &= add_key_map_entries(key_map, - "texturefile", ZERO_OR_ONE, expect_string(assign_variable_callback_string(texture_file)), - - "norefcount", ZERO_OR_ONE, success_callback, - "allwaystransparent", ZERO_OR_ONE, success_callback, - "loadType", ZERO_OR_ONE, success_callback - ); - return ret; -} - -IconTextureSprite::IconTextureSprite() : no_of_frames { NO_FRAMES } {} - -bool IconTextureSprite::_fill_key_map(case_insensitive_key_map_t& key_map) { - bool ret = TextureSprite::_fill_key_map(key_map); - ret &= add_key_map_entries(key_map, - "noOfFrames", ZERO_OR_ONE, expect_uint(assign_variable_callback(no_of_frames)), - - "effectFile", ZERO_OR_ONE, success_callback, - "transparencecheck", ZERO_OR_ONE, success_callback, - "clicksound", ZERO_OR_ONE, success_callback - ); - return ret; -} - -TileTextureSprite::TileTextureSprite() : size {} {} - -bool TileTextureSprite::_fill_key_map(case_insensitive_key_map_t& key_map) { - bool ret = TextureSprite::_fill_key_map(key_map); - ret &= add_key_map_entries(key_map, - "size", ONE_EXACTLY, expect_ivec2(assign_variable_callback(size)) - ); - return ret; -} - -CorneredTileTextureSprite::CorneredTileTextureSprite() : size {}, border_size {} {} - -bool CorneredTileTextureSprite::_fill_key_map(case_insensitive_key_map_t& key_map) { - bool ret = TextureSprite::_fill_key_map(key_map); - ret &= add_key_map_entries(key_map, - "size", ONE_EXACTLY, expect_ivec2(assign_variable_callback(size)), - "borderSize", ONE_EXACTLY, expect_ivec2(assign_variable_callback(border_size)) - ); - return ret; -} - -ProgressBar::ProgressBar() : back_colour {}, back_texture_file {}, progress_colour {}, progress_texture_file {}, size {} {} - -bool ProgressBar::_fill_key_map(case_insensitive_key_map_t& key_map) { - bool ret = Sprite::_fill_key_map(key_map); - ret &= add_key_map_entries(key_map, - "color", ONE_EXACTLY, expect_colour(assign_variable_callback(progress_colour)), - "colortwo", ONE_EXACTLY, expect_colour(assign_variable_callback(back_colour)), - "textureFile1", ZERO_OR_ONE, expect_string(assign_variable_callback_string(progress_texture_file)), - "textureFile2", ZERO_OR_ONE, expect_string(assign_variable_callback_string(back_texture_file)), - "size", ONE_EXACTLY, expect_ivec2(assign_variable_callback(size)), - - "effectFile", ONE_EXACTLY, success_callback, - "allwaystransparent", ZERO_OR_ONE, success_callback, - "loadType", ZERO_OR_ONE, success_callback, - "horizontal", ZERO_OR_ONE, success_callback - ); - return ret; -} - -PieChart::PieChart() : size {} {} - -bool PieChart::_fill_key_map(case_insensitive_key_map_t& key_map) { - bool ret = Sprite::_fill_key_map(key_map); - ret &= add_key_map_entries(key_map, "size", ONE_EXACTLY, expect_uint(assign_variable_callback(size))); - return ret; -} - -LineChart::LineChart() : size {}, linewidth {} {} - -bool LineChart::_fill_key_map(case_insensitive_key_map_t& key_map) { - bool ret = Sprite::_fill_key_map(key_map); - ret &= add_key_map_entries(key_map, - "size", ONE_EXACTLY, expect_ivec2(assign_variable_callback(size)), - "linewidth", ONE_EXACTLY, expect_uint(assign_variable_callback(linewidth)), - - "allwaystransparent", ZERO_OR_ONE, success_callback - ); - return ret; -} - -MaskedFlag::MaskedFlag() : overlay_file {}, mask_file {} {} - -bool MaskedFlag::_fill_key_map(case_insensitive_key_map_t& key_map) { - bool ret = Sprite::_fill_key_map(key_map); - ret &= add_key_map_entries(key_map, - "textureFile1", ONE_EXACTLY, expect_string(assign_variable_callback_string(overlay_file)), - "textureFile2", ONE_EXACTLY, expect_string(assign_variable_callback_string(mask_file)), - - "effectFile", ONE_EXACTLY, success_callback, - "allwaystransparent", ZERO_OR_ONE, success_callback, - "flipv", ZERO_OR_ONE, success_callback - ); - return ret; -} diff --git a/src/openvic-simulation/interface/GFX.hpp b/src/openvic-simulation/interface/GFX.hpp deleted file mode 100644 index 49691c1..0000000 --- a/src/openvic-simulation/interface/GFX.hpp +++ /dev/null @@ -1,192 +0,0 @@ -#pragma once - -#include "openvic-simulation/interface/LoadBase.hpp" - -namespace OpenVic { - class UIManager; -} - -namespace OpenVic::GFX { - - struct Font : HasIdentifierAndAlphaColour { - friend class OpenVic::UIManager; - - private: - std::string PROPERTY(fontname); - std::string PROPERTY(charset); - uint32_t PROPERTY(height); - - // TODO - colorcodes, effect - - Font( - std::string_view new_identifier, colour_argb_t new_colour, std::string_view new_fontname, - std::string_view new_charset, uint32_t new_height - ); - - public: - Font(Font&&) = default; - }; - - using frame_t = int32_t; /* Keep this as int32_t to simplify interfacing with Godot */ - static constexpr frame_t NO_FRAMES = 0; - - class Sprite : public Named<> { - protected: - Sprite() = default; - - public: - Sprite(Sprite&&) = default; - virtual ~Sprite() = default; - - OV_DETAIL_GET_BASE_TYPE(Sprite) - OV_DETAIL_GET_TYPE - - static NodeTools::node_callback_t expect_sprites( - NodeTools::length_callback_t length_callback, NodeTools::callback_t&&> callback - ); - }; - - class TextureSprite : public Sprite { - std::string PROPERTY(texture_file); - - protected: - TextureSprite(); - - bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; - - public: - TextureSprite(TextureSprite&&) = default; - virtual ~TextureSprite() = default; - - OV_DETAIL_GET_BASE_TYPE(TextureSprite) - OV_DETAIL_GET_TYPE - }; - - class IconTextureSprite final : public TextureSprite { - friend std::unique_ptr std::make_unique(); - - frame_t PROPERTY(no_of_frames); - - protected: - IconTextureSprite(); - - bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; - - public: - IconTextureSprite(IconTextureSprite&&) = default; - virtual ~IconTextureSprite() = default; - - OV_DETAIL_GET_TYPE - }; - - class TileTextureSprite final : public TextureSprite { - friend std::unique_ptr std::make_unique(); - - ivec2_t PROPERTY(size); - - protected: - TileTextureSprite(); - - bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; - - public: - TileTextureSprite(TileTextureSprite&&) = default; - virtual ~TileTextureSprite() = default; - - OV_DETAIL_GET_TYPE - }; - - class CorneredTileTextureSprite final : public TextureSprite { - friend std::unique_ptr std::make_unique(); - - ivec2_t PROPERTY(size); - ivec2_t PROPERTY(border_size); - - protected: - CorneredTileTextureSprite(); - - bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; - - public: - CorneredTileTextureSprite(CorneredTileTextureSprite&&) = default; - virtual ~CorneredTileTextureSprite() = default; - - OV_DETAIL_GET_TYPE - }; - - class ProgressBar final : public Sprite { - friend std::unique_ptr std::make_unique(); - - colour_t PROPERTY(back_colour); - std::string PROPERTY(back_texture_file); - colour_t PROPERTY(progress_colour); - std::string PROPERTY(progress_texture_file); - ivec2_t PROPERTY(size); - - // TODO - effectFile - - protected: - ProgressBar(); - - bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; - - public: - ProgressBar(ProgressBar&&) = default; - virtual ~ProgressBar() = default; - - OV_DETAIL_GET_TYPE - }; - - class PieChart final : public Sprite { - friend std::unique_ptr std::make_unique(); - - uint32_t PROPERTY(size); - - protected: - PieChart(); - - bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; - - public: - PieChart(PieChart&&) = default; - virtual ~PieChart() = default; - - OV_DETAIL_GET_TYPE - }; - - class LineChart final : public Sprite { - friend std::unique_ptr std::make_unique(); - - ivec2_t PROPERTY(size); - uint32_t PROPERTY(linewidth); - - protected: - LineChart(); - - bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; - - public: - LineChart(LineChart&&) = default; - virtual ~LineChart() = default; - - OV_DETAIL_GET_TYPE - }; - - class MaskedFlag final : public Sprite { - friend std::unique_ptr std::make_unique(); - - std::string PROPERTY(overlay_file); - std::string PROPERTY(mask_file); - - protected: - MaskedFlag(); - - bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; - - public: - MaskedFlag(MaskedFlag&&) = default; - virtual ~MaskedFlag() = default; - - OV_DETAIL_GET_TYPE - }; -} diff --git a/src/openvic-simulation/interface/GFXObject.cpp b/src/openvic-simulation/interface/GFXObject.cpp new file mode 100644 index 0000000..d873db1 --- /dev/null +++ b/src/openvic-simulation/interface/GFXObject.cpp @@ -0,0 +1,144 @@ +#include "GFXObject.hpp" + +using namespace OpenVic; +using namespace OpenVic::GFX; +using namespace OpenVic::NodeTools; + +node_callback_t Object::expect_objects(length_callback_t length_callback, callback_t&&> callback) { + return expect_dictionary_keys_and_length( + length_callback, + + "EMFXActorType", ZERO_OR_MORE, _expect_instance(callback), + + /* arrows.gfx */ + "arrowType", ZERO_OR_MORE, expect_dictionary_keys( + "name", ONE_EXACTLY, success_callback, + "size", ONE_EXACTLY, success_callback, + "textureFile", ONE_EXACTLY, success_callback, + "bodytexture", ONE_EXACTLY, success_callback, + "color", ONE_EXACTLY, success_callback, + "colortwo", ONE_EXACTLY, success_callback, + "endAt", ONE_EXACTLY, success_callback, + "height", ONE_EXACTLY, success_callback, + "type", ONE_EXACTLY, success_callback, + "heading", ONE_EXACTLY, success_callback, + "effect", ONE_EXACTLY, success_callback + ), + + /* battlearrow.gfx */ + "battlearrow", ZERO_OR_MORE, expect_dictionary_keys( + "name", ONE_EXACTLY, success_callback, + "textureFile", ONE_EXACTLY, success_callback, + "textureFile1", ONE_EXACTLY, success_callback, + "start", ONE_EXACTLY, success_callback, + "stop", ONE_EXACTLY, success_callback, + "x", ONE_EXACTLY, success_callback, + "y", ONE_EXACTLY, success_callback, + "font", ONE_EXACTLY, success_callback, + "scale", ONE_EXACTLY, success_callback, + "nofade", ZERO_OR_ONE, success_callback, + "textureloop", ZERO_OR_ONE, success_callback + ), + "mapinfo", ZERO_OR_MORE, expect_dictionary_keys( + "name", ONE_EXACTLY, success_callback, + "textureFile", ZERO_OR_ONE, success_callback, + "scale", ZERO_OR_ONE, success_callback + ), + + /* mapitems.gfx */ + "projectionType", ZERO_OR_MORE, success_callback, + "progressbar3dType", ZERO_OR_MORE, expect_dictionary_keys( + "name", ONE_EXACTLY, success_callback, + "color", ONE_EXACTLY, success_callback, + "colortwo", ONE_EXACTLY, success_callback, + "size", ONE_EXACTLY, success_callback, + "effectFile", ONE_EXACTLY, success_callback + ), + "billboardType", ZERO_OR_MORE, expect_dictionary_keys( + "name", ONE_EXACTLY, success_callback, + "texturefile", ONE_EXACTLY, success_callback, + "noOfFrames", ZERO_OR_ONE, success_callback, + "scale", ONE_EXACTLY, success_callback, + "font_size", ZERO_OR_ONE, success_callback, + "offset2", ZERO_OR_ONE, success_callback, + "font", ZERO_OR_ONE, success_callback + ), + + "unitstatsBillboardType", ZERO_OR_MORE, expect_dictionary_keys( + "name", ONE_EXACTLY, success_callback, + "textureFile", ONE_EXACTLY, success_callback, + "mask", ONE_EXACTLY, success_callback, + "effectFile", ONE_EXACTLY, success_callback, + "scale", ONE_EXACTLY, success_callback, + "noOfFrames", ONE_EXACTLY, success_callback, + "font_size", ONE_EXACTLY, success_callback, + "font", ONE_EXACTLY, success_callback + ), + + /* core.gfx */ + "animatedmaptext", ZERO_OR_MORE, expect_dictionary_keys( + "name", ONE_EXACTLY, success_callback, + "speed", ONE_EXACTLY, success_callback, + "position", ZERO_OR_ONE, success_callback, + "scale", ZERO_OR_ONE, success_callback, + "textblock", ONE_EXACTLY, expect_dictionary_keys( + "text", ONE_EXACTLY, success_callback, + "color", ONE_EXACTLY, success_callback, + "font", ONE_EXACTLY, success_callback, + "position", ONE_EXACTLY, success_callback, + "size", ONE_EXACTLY, success_callback, + "format", ONE_EXACTLY, success_callback + ) + ), + "flagType", ZERO_OR_MORE, expect_dictionary_keys( + "name", ONE_EXACTLY, success_callback, + "size", ONE_EXACTLY, success_callback + ), + "provinceType", ZERO_OR_ONE, success_callback, + "provinceWaterType", ZERO_OR_ONE, success_callback, + "mapTextType", ZERO_OR_MORE, success_callback, + "meshType", ZERO_OR_MORE, success_callback + ); +} + +Actor::Attachment::Attachment() : node {}, attach_id { 0 } {} + +bool Actor::Attachment::_fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) { + bool ret = Named::_fill_key_map(key_map); + ret &= add_key_map_entries(key_map, + "node", ONE_EXACTLY, expect_string(assign_variable_callback_string(node)), + "attachId", ONE_EXACTLY, expect_uint(assign_variable_callback(attach_id)) + ); + return ret; +} + +Actor::Animation::Animation() : file {}, default_time { 0 } {} + +bool Actor::Animation::_fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) { + bool ret = Named::_fill_key_map(key_map); + ret &= add_key_map_entries(key_map, + "file", ONE_EXACTLY, expect_string(assign_variable_callback_string(file)), + "defaultAnimationTime", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(default_time)) + ); + return ret; +} + +Actor::Actor() : model_file {}, idle_animation_file {}, move_animation_file {}, attack_animation_file {}, scale { 1 } {} + +bool Actor::_fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) { + bool ret = Object::_fill_key_map(key_map); + ret &= add_key_map_entries(key_map, + "actorfile", ONE_EXACTLY, expect_string(assign_variable_callback_string(model_file)), + "idle", ZERO_OR_ONE, expect_string(assign_variable_callback_string(idle_animation_file)), + "move", ZERO_OR_ONE, expect_string(assign_variable_callback_string(move_animation_file)), + "attack", ZERO_OR_ONE, expect_string(assign_variable_callback_string(attack_animation_file)), + "scale", ONE_EXACTLY, expect_fixed_point(assign_variable_callback(scale)), + "attach", ZERO_OR_MORE, Attachment::_expect_value([this](Attachment&& attachment) -> bool { + return attachments.add_item(std::move(attachment)); + }), + "animation", ZERO_OR_MORE, Animation::_expect_value([this](Animation&& animation) -> bool { + return animations.add_item(std::move(animation)); + }) + ); + return ret; +} diff --git a/src/openvic-simulation/interface/GFXObject.hpp b/src/openvic-simulation/interface/GFXObject.hpp new file mode 100644 index 0000000..840e4a9 --- /dev/null +++ b/src/openvic-simulation/interface/GFXObject.hpp @@ -0,0 +1,81 @@ +#pragma once + +#include "openvic-simulation/interface/LoadBase.hpp" + +namespace OpenVic::GFX { + + class Object : public Named<> { + protected: + Object() = default; + + public: + Object(Object&&) = default; + virtual ~Object() = default; + + OV_DETAIL_GET_BASE_TYPE(Object) + OV_DETAIL_GET_TYPE + + static NodeTools::node_callback_t expect_objects( + NodeTools::length_callback_t length_callback, NodeTools::callback_t&&> callback + ); + }; + + class Actor final : public Object { + friend std::unique_ptr std::make_unique(); + + public: + class Attachment : public Named<> { + friend class LoadBase; + + private: + std::string PROPERTY(node); + int32_t PROPERTY(attach_id); + + protected: + Attachment(); + + bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; + + public: + Attachment(Attachment&&) = default; + virtual ~Attachment() = default; + }; + + class Animation : public Named<> { + friend class LoadBase; + + std::string PROPERTY(file); + fixed_point_t PROPERTY(default_time); + + protected: + Animation(); + + bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; + + public: + Animation(Animation&&) = default; + virtual ~Animation() = default; + }; + + private: + std::string PROPERTY(model_file); + std::string PROPERTY(idle_animation_file); + std::string PROPERTY(move_animation_file); + std::string PROPERTY(attack_animation_file); + fixed_point_t PROPERTY(scale); + + NamedRegistry IDENTIFIER_REGISTRY(attachment); + NamedRegistry IDENTIFIER_REGISTRY(animation); + + protected: + Actor(); + + bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; + + public: + Actor(Actor&&) = default; + virtual ~Actor() = default; + + OV_DETAIL_GET_TYPE + }; +} diff --git a/src/openvic-simulation/interface/GFXSprite.cpp b/src/openvic-simulation/interface/GFXSprite.cpp new file mode 100644 index 0000000..992a1ff --- /dev/null +++ b/src/openvic-simulation/interface/GFXSprite.cpp @@ -0,0 +1,133 @@ +#include "GFXSprite.hpp" + +using namespace OpenVic; +using namespace OpenVic::GFX; +using namespace OpenVic::NodeTools; + +Font::Font( + std::string_view new_identifier, colour_argb_t new_colour, std::string_view new_fontname, std::string_view new_charset, + uint32_t new_height +) : HasIdentifierAndAlphaColour { new_identifier, new_colour, false }, fontname { new_fontname }, charset { new_charset }, + height { new_height } {} + +node_callback_t Sprite::expect_sprites(length_callback_t length_callback, callback_t&&> callback) { + return expect_dictionary_keys_and_length( + length_callback, + "spriteType", ZERO_OR_MORE, _expect_instance(callback), + "progressbartype", ZERO_OR_MORE, _expect_instance(callback), + "PieChartType", ZERO_OR_MORE, _expect_instance(callback), + "LineChartType", ZERO_OR_MORE, _expect_instance(callback), + "textSpriteType", ZERO_OR_MORE, _expect_instance(callback), + "maskedShieldType", ZERO_OR_MORE, _expect_instance(callback), + "tileSpriteType", ZERO_OR_MORE, _expect_instance(callback), + "corneredTileSpriteType", ZERO_OR_MORE, _expect_instance(callback), + + /* Each only has one vanilla instance which isn't used anywhere. */ + "BarChartType", ZERO_OR_MORE, success_callback, + "scrollingSprite", ZERO_OR_MORE, success_callback + ); +} + +TextureSprite::TextureSprite() : texture_file {} {} + +bool TextureSprite::_fill_key_map(case_insensitive_key_map_t& key_map) { + bool ret = Sprite::_fill_key_map(key_map); + ret &= add_key_map_entries(key_map, + "texturefile", ZERO_OR_ONE, expect_string(assign_variable_callback_string(texture_file)), + + "norefcount", ZERO_OR_ONE, success_callback, + "allwaystransparent", ZERO_OR_ONE, success_callback, + "loadType", ZERO_OR_ONE, success_callback + ); + return ret; +} + +IconTextureSprite::IconTextureSprite() : no_of_frames { NO_FRAMES } {} + +bool IconTextureSprite::_fill_key_map(case_insensitive_key_map_t& key_map) { + bool ret = TextureSprite::_fill_key_map(key_map); + ret &= add_key_map_entries(key_map, + "noOfFrames", ZERO_OR_ONE, expect_uint(assign_variable_callback(no_of_frames)), + + "effectFile", ZERO_OR_ONE, success_callback, + "transparencecheck", ZERO_OR_ONE, success_callback, + "clicksound", ZERO_OR_ONE, success_callback + ); + return ret; +} + +TileTextureSprite::TileTextureSprite() : size {} {} + +bool TileTextureSprite::_fill_key_map(case_insensitive_key_map_t& key_map) { + bool ret = TextureSprite::_fill_key_map(key_map); + ret &= add_key_map_entries(key_map, + "size", ONE_EXACTLY, expect_ivec2(assign_variable_callback(size)) + ); + return ret; +} + +CorneredTileTextureSprite::CorneredTileTextureSprite() : size {}, border_size {} {} + +bool CorneredTileTextureSprite::_fill_key_map(case_insensitive_key_map_t& key_map) { + bool ret = TextureSprite::_fill_key_map(key_map); + ret &= add_key_map_entries(key_map, + "size", ONE_EXACTLY, expect_ivec2(assign_variable_callback(size)), + "borderSize", ONE_EXACTLY, expect_ivec2(assign_variable_callback(border_size)) + ); + return ret; +} + +ProgressBar::ProgressBar() : back_colour {}, back_texture_file {}, progress_colour {}, progress_texture_file {}, size {} {} + +bool ProgressBar::_fill_key_map(case_insensitive_key_map_t& key_map) { + bool ret = Sprite::_fill_key_map(key_map); + ret &= add_key_map_entries(key_map, + "color", ONE_EXACTLY, expect_colour(assign_variable_callback(progress_colour)), + "colortwo", ONE_EXACTLY, expect_colour(assign_variable_callback(back_colour)), + "textureFile1", ZERO_OR_ONE, expect_string(assign_variable_callback_string(progress_texture_file)), + "textureFile2", ZERO_OR_ONE, expect_string(assign_variable_callback_string(back_texture_file)), + "size", ONE_EXACTLY, expect_ivec2(assign_variable_callback(size)), + + "effectFile", ONE_EXACTLY, success_callback, + "allwaystransparent", ZERO_OR_ONE, success_callback, + "loadType", ZERO_OR_ONE, success_callback, + "horizontal", ZERO_OR_ONE, success_callback + ); + return ret; +} + +PieChart::PieChart() : size {} {} + +bool PieChart::_fill_key_map(case_insensitive_key_map_t& key_map) { + bool ret = Sprite::_fill_key_map(key_map); + ret &= add_key_map_entries(key_map, "size", ONE_EXACTLY, expect_uint(assign_variable_callback(size))); + return ret; +} + +LineChart::LineChart() : size {}, linewidth {} {} + +bool LineChart::_fill_key_map(case_insensitive_key_map_t& key_map) { + bool ret = Sprite::_fill_key_map(key_map); + ret &= add_key_map_entries(key_map, + "size", ONE_EXACTLY, expect_ivec2(assign_variable_callback(size)), + "linewidth", ONE_EXACTLY, expect_uint(assign_variable_callback(linewidth)), + + "allwaystransparent", ZERO_OR_ONE, success_callback + ); + return ret; +} + +MaskedFlag::MaskedFlag() : overlay_file {}, mask_file {} {} + +bool MaskedFlag::_fill_key_map(case_insensitive_key_map_t& key_map) { + bool ret = Sprite::_fill_key_map(key_map); + ret &= add_key_map_entries(key_map, + "textureFile1", ONE_EXACTLY, expect_string(assign_variable_callback_string(overlay_file)), + "textureFile2", ONE_EXACTLY, expect_string(assign_variable_callback_string(mask_file)), + + "effectFile", ONE_EXACTLY, success_callback, + "allwaystransparent", ZERO_OR_ONE, success_callback, + "flipv", ZERO_OR_ONE, success_callback + ); + return ret; +} diff --git a/src/openvic-simulation/interface/GFXSprite.hpp b/src/openvic-simulation/interface/GFXSprite.hpp new file mode 100644 index 0000000..49691c1 --- /dev/null +++ b/src/openvic-simulation/interface/GFXSprite.hpp @@ -0,0 +1,192 @@ +#pragma once + +#include "openvic-simulation/interface/LoadBase.hpp" + +namespace OpenVic { + class UIManager; +} + +namespace OpenVic::GFX { + + struct Font : HasIdentifierAndAlphaColour { + friend class OpenVic::UIManager; + + private: + std::string PROPERTY(fontname); + std::string PROPERTY(charset); + uint32_t PROPERTY(height); + + // TODO - colorcodes, effect + + Font( + std::string_view new_identifier, colour_argb_t new_colour, std::string_view new_fontname, + std::string_view new_charset, uint32_t new_height + ); + + public: + Font(Font&&) = default; + }; + + using frame_t = int32_t; /* Keep this as int32_t to simplify interfacing with Godot */ + static constexpr frame_t NO_FRAMES = 0; + + class Sprite : public Named<> { + protected: + Sprite() = default; + + public: + Sprite(Sprite&&) = default; + virtual ~Sprite() = default; + + OV_DETAIL_GET_BASE_TYPE(Sprite) + OV_DETAIL_GET_TYPE + + static NodeTools::node_callback_t expect_sprites( + NodeTools::length_callback_t length_callback, NodeTools::callback_t&&> callback + ); + }; + + class TextureSprite : public Sprite { + std::string PROPERTY(texture_file); + + protected: + TextureSprite(); + + bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; + + public: + TextureSprite(TextureSprite&&) = default; + virtual ~TextureSprite() = default; + + OV_DETAIL_GET_BASE_TYPE(TextureSprite) + OV_DETAIL_GET_TYPE + }; + + class IconTextureSprite final : public TextureSprite { + friend std::unique_ptr std::make_unique(); + + frame_t PROPERTY(no_of_frames); + + protected: + IconTextureSprite(); + + bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; + + public: + IconTextureSprite(IconTextureSprite&&) = default; + virtual ~IconTextureSprite() = default; + + OV_DETAIL_GET_TYPE + }; + + class TileTextureSprite final : public TextureSprite { + friend std::unique_ptr std::make_unique(); + + ivec2_t PROPERTY(size); + + protected: + TileTextureSprite(); + + bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; + + public: + TileTextureSprite(TileTextureSprite&&) = default; + virtual ~TileTextureSprite() = default; + + OV_DETAIL_GET_TYPE + }; + + class CorneredTileTextureSprite final : public TextureSprite { + friend std::unique_ptr std::make_unique(); + + ivec2_t PROPERTY(size); + ivec2_t PROPERTY(border_size); + + protected: + CorneredTileTextureSprite(); + + bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; + + public: + CorneredTileTextureSprite(CorneredTileTextureSprite&&) = default; + virtual ~CorneredTileTextureSprite() = default; + + OV_DETAIL_GET_TYPE + }; + + class ProgressBar final : public Sprite { + friend std::unique_ptr std::make_unique(); + + colour_t PROPERTY(back_colour); + std::string PROPERTY(back_texture_file); + colour_t PROPERTY(progress_colour); + std::string PROPERTY(progress_texture_file); + ivec2_t PROPERTY(size); + + // TODO - effectFile + + protected: + ProgressBar(); + + bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; + + public: + ProgressBar(ProgressBar&&) = default; + virtual ~ProgressBar() = default; + + OV_DETAIL_GET_TYPE + }; + + class PieChart final : public Sprite { + friend std::unique_ptr std::make_unique(); + + uint32_t PROPERTY(size); + + protected: + PieChart(); + + bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; + + public: + PieChart(PieChart&&) = default; + virtual ~PieChart() = default; + + OV_DETAIL_GET_TYPE + }; + + class LineChart final : public Sprite { + friend std::unique_ptr std::make_unique(); + + ivec2_t PROPERTY(size); + uint32_t PROPERTY(linewidth); + + protected: + LineChart(); + + bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; + + public: + LineChart(LineChart&&) = default; + virtual ~LineChart() = default; + + OV_DETAIL_GET_TYPE + }; + + class MaskedFlag final : public Sprite { + friend std::unique_ptr std::make_unique(); + + std::string PROPERTY(overlay_file); + std::string PROPERTY(mask_file); + + protected: + MaskedFlag(); + + bool _fill_key_map(NodeTools::case_insensitive_key_map_t& key_map) override; + + public: + MaskedFlag(MaskedFlag&&) = default; + virtual ~MaskedFlag() = default; + + OV_DETAIL_GET_TYPE + }; +} diff --git a/src/openvic-simulation/interface/GUI.hpp b/src/openvic-simulation/interface/GUI.hpp index d839188..74afbd1 100644 --- a/src/openvic-simulation/interface/GUI.hpp +++ b/src/openvic-simulation/interface/GUI.hpp @@ -1,6 +1,6 @@ #pragma once -#include "openvic-simulation/interface/GFX.hpp" +#include "openvic-simulation/interface/GFXSprite.hpp" namespace OpenVic { class UIManager; diff --git a/src/openvic-simulation/interface/UI.cpp b/src/openvic-simulation/interface/UI.cpp index 2646bb7..479948d 100644 --- a/src/openvic-simulation/interface/UI.cpp +++ b/src/openvic-simulation/interface/UI.cpp @@ -83,9 +83,21 @@ bool UIManager::load_gfx_file(ast::NodeCPtr root) { return sprites.add_item(std::move(sprite), duplicate_warning_callback); } ), + "bitmapfonts", ZERO_OR_ONE, _load_fonts("bitmapfont"), "fonts", ZERO_OR_ONE, _load_fonts("font"), - "objectTypes", ZERO_OR_ONE, success_callback, + + "objectTypes", ZERO_OR_ONE, Object::expect_objects( + NodeTools::reserve_length_callback(objects), + [this](std::unique_ptr&& object) -> bool { + /* There are various models with the same name but slight differences, e.g. Prussian and German variants + * of PrussianGCCavalry (the latter added in a spritepack). Currently we default to using the first loaded + * model of each name, but we may want to switch to using the last loaded or allow multiple models per name + * (e.g. by grouping them per gfx file). */ + return objects.add_item(std::move(object), duplicate_warning_callback); + } + ), + "lightTypes", ZERO_OR_ONE, success_callback )(root); } diff --git a/src/openvic-simulation/interface/UI.hpp b/src/openvic-simulation/interface/UI.hpp index c8ffa98..ada540a 100644 --- a/src/openvic-simulation/interface/UI.hpp +++ b/src/openvic-simulation/interface/UI.hpp @@ -1,5 +1,6 @@ #pragma once +#include "openvic-simulation/interface/GFXObject.hpp" #include "openvic-simulation/interface/GUI.hpp" namespace OpenVic { @@ -8,6 +9,7 @@ namespace OpenVic { NamedInstanceRegistry IDENTIFIER_REGISTRY(sprite); NamedInstanceRegistry IDENTIFIER_REGISTRY(scene); IdentifierRegistry IDENTIFIER_REGISTRY(font); + NamedInstanceRegistry IDENTIFIER_REGISTRY(object); bool _load_font(ast::NodeCPtr node); NodeTools::NodeCallback auto _load_fonts(std::string_view font_key); diff --git a/src/openvic-simulation/types/fixed_point/FixedPoint.hpp b/src/openvic-simulation/types/fixed_point/FixedPoint.hpp index 9ad7966..84d2b70 100644 --- a/src/openvic-simulation/types/fixed_point/FixedPoint.hpp +++ b/src/openvic-simulation/types/fixed_point/FixedPoint.hpp @@ -341,7 +341,7 @@ namespace OpenVic { } // Deterministic - static constexpr fixed_point_t parse(char const* str, char const* const end, bool* successful = nullptr) { + static constexpr fixed_point_t parse(char const* str, char const* end, bool* successful = nullptr) { if (successful != nullptr) { *successful = false; } @@ -360,6 +360,16 @@ namespace OpenVic { } } + { + const char last_char = *(end - 1); + if (last_char == 'f' || last_char == 'F') { + --end; + if (str == end) { + return _0(); + } + } + } + char const* dot_pointer = str; while (*dot_pointer != '.' && ++dot_pointer != end) {} -- cgit v1.2.3-56-ga3b1