diff options
Diffstat (limited to 'extension/src/openvic-extension/singletons/AssetManager.cpp')
-rw-r--r-- | extension/src/openvic-extension/singletons/AssetManager.cpp | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/extension/src/openvic-extension/singletons/AssetManager.cpp b/extension/src/openvic-extension/singletons/AssetManager.cpp new file mode 100644 index 0000000..b50cae8 --- /dev/null +++ b/extension/src/openvic-extension/singletons/AssetManager.cpp @@ -0,0 +1,152 @@ +#include "AssetManager.hpp" + +#include <godot_cpp/variant/utility_functions.hpp> + +#include "openvic-extension/singletons/GameSingleton.hpp" +#include "openvic-extension/utility/ClassBindings.hpp" +#include "openvic-extension/utility/Utilities.hpp" + +using namespace godot; +using namespace OpenVic; + +using OpenVic::Utilities::godot_to_std_string; +using OpenVic::Utilities::std_to_godot_string; + +void AssetManager::_bind_methods() { + OV_BIND_METHOD(AssetManager::get_image, { "path" }); + OV_BIND_METHOD(AssetManager::get_texture, { "path" }); + + OV_BIND_SMETHOD(AssetManager::make_icon, { "texture", "frame", "frame_count" }); + OV_BIND_METHOD(AssetManager::get_icon, { "texture", "frame", "frame_count" }); + + OV_BIND_METHOD(AssetManager::get_texture_or_icon, { "path", "frame", "frame_count" }); + OV_BIND_METHOD(AssetManager::get_font, { "name" }); +} + +AssetManager* AssetManager::get_singleton() { + return _singleton; +} + +AssetManager::AssetManager() { + ERR_FAIL_COND(_singleton != nullptr); + _singleton = this; +} + +AssetManager::~AssetManager() { + ERR_FAIL_COND(_singleton != this); + _singleton = nullptr; +} + +AssetManager::image_asset_map_t::iterator AssetManager::_get_image_asset(StringName path) { + const image_asset_map_t::iterator it = image_assets.find(path); + if (it != image_assets.end()) { + return it; + } + GameSingleton* game_singleton = GameSingleton::get_singleton(); + ERR_FAIL_NULL_V(game_singleton, image_assets.end()); + const String lookedup_path = + std_to_godot_string(game_singleton->get_dataloader().lookup_image_file_or_dds(godot_to_std_string(path)).string()); + if (lookedup_path.is_empty()) { + UtilityFunctions::push_error("Failed to look up image: ", path); + return image_assets.end(); + } + const Ref<Image> image = Utilities::load_godot_image(lookedup_path); + if (image.is_null() || image->is_empty()) { + UtilityFunctions::push_error("Failed to load image: ", lookedup_path, " (looked up from ", path, ")"); + return image_assets.end(); + } + return image_assets.emplace(std::move(path), AssetManager::image_asset_t { image, nullptr }).first; +} + +Ref<Image> AssetManager::get_image(StringName path) { + const image_asset_map_t::const_iterator it = _get_image_asset(path); + if (it != image_assets.end()) { + return it->second.image; + } else { + return nullptr; + } +} + +Ref<ImageTexture> AssetManager::get_texture(StringName path) { + const image_asset_map_t::iterator it = _get_image_asset(path); + if (it != image_assets.end()) { + if (it->second.texture.is_null()) { + it->second.texture = ImageTexture::create_from_image(it->second.image); + if (it->second.texture.is_null()) { + UtilityFunctions::push_error("Failed to turn image into texture: ", path); + } + } + return it->second.texture; + } else { + return nullptr; + } +} + +Ref<AtlasTexture> AssetManager::make_icon(Ref<Texture2D> texture, GFX::frame_t frame, GFX::frame_t frame_count) { + ERR_FAIL_NULL_V(texture, nullptr); + + if (frame_count <= GFX::NO_FRAMES) { + UtilityFunctions::push_warning("No frames!"); + frame_count = 1; + } + if (frame <= GFX::NO_FRAMES || frame > frame_count) { + UtilityFunctions::push_warning("Invalid frame index ", frame, " out of count ", frame_count); + frame = frame_count; + } + frame--; + const Vector2i size = texture->get_size(); + const Rect2i region { frame * size.x / frame_count, 0, size.x / frame_count, size.y }; + + Ref<AtlasTexture> atlas; + atlas.instantiate(); + ERR_FAIL_NULL_V(atlas, nullptr); + atlas->set_atlas(texture); + atlas->set_region(region); + return atlas; +} + +Ref<AtlasTexture> AssetManager::get_icon(StringName path, GFX::frame_t frame, GFX::frame_t frame_count) { + Ref<ImageTexture> texture = get_texture(path); + ERR_FAIL_NULL_V(texture, nullptr); + return make_icon(texture, frame, frame_count); +} + +Ref<Texture2D> AssetManager::get_texture_or_icon(StringName path, GFX::frame_t frame, GFX::frame_t frame_count) { + if (frame_count < 2) { + if (frame > frame_count) { + UtilityFunctions::push_warning("Invalid frame index ", frame, " out of count ", frame_count); + } + return get_texture(path); + } else { + return get_icon(path, frame, frame_count); + } +} + +Ref<Font> AssetManager::get_font(StringName name) { + const font_map_t::const_iterator it = fonts.find(name); + if (it != fonts.end()) { + return it->second; + } + + static const String font_dir = "gfx/fonts/"; + static const String font_ext = ".fnt"; + static const String image_ext = ".tga"; + + const String image_path = font_dir + name + image_ext; + const Ref<Image> image = get_image(image_path); + if (image.is_null()) { + UtilityFunctions::push_error("Failed to load font image: ", image_path, " for the font named ", name); + return nullptr; + } + GameSingleton* game_singleton = GameSingleton::get_singleton(); + ERR_FAIL_NULL_V(game_singleton, nullptr); + const String lookedup_font_path = + std_to_godot_string(game_singleton->get_dataloader().lookup_file(godot_to_std_string(font_dir + name + font_ext)).string()); + const Ref<Font> font = Utilities::load_godot_font(lookedup_font_path, image); + if (font.is_null()) { + UtilityFunctions::push_error("Failed to load font file ", lookedup_font_path, " for the font named ", name); + return nullptr; + } + fonts.emplace(std::move(name), font); + return font; +} |