diff options
Diffstat (limited to 'loader')
-rw-r--r-- | loader/atlas.cpp | 10 | ||||
-rw-r--r-- | loader/impl.cpp | 1 | ||||
-rw-r--r-- | loader/impl.hpp | 42 | ||||
-rw-r--r-- | loader/json.cpp | 5 | ||||
-rw-r--r-- | loader/loader.cpp | 2 | ||||
-rw-r--r-- | loader/loader.hpp | 17 | ||||
-rw-r--r-- | loader/vobj-info.hpp | 2 | ||||
-rw-r--r-- | loader/vobj.cpp | 6 | ||||
-rw-r--r-- | loader/wall-atlas.cpp | 99 | ||||
-rw-r--r-- | loader/wall-info.hpp | 15 |
10 files changed, 173 insertions, 26 deletions
diff --git a/loader/atlas.cpp b/loader/atlas.cpp index 2afd4d2e..3fd30e80 100644 --- a/loader/atlas.cpp +++ b/loader/atlas.cpp @@ -55,12 +55,12 @@ std::shared_ptr<tile_atlas> loader_impl::tile_atlas(StringView name, Vector2ub s char buf[FILENAME_MAX]; auto path = make_atlas_path(buf, IMAGE_PATH, name); - auto atlas = std::make_shared<struct tile_atlas>(path, name, texture(""_s, path), size, pass); + auto atlas = std::make_shared<class tile_atlas>(path, name, texture(""_s, path), size, pass); tile_atlas_map[atlas->name()] = atlas; return atlas; } -std::shared_ptr<struct tile_atlas> loader_impl::tile_atlas(StringView filename) noexcept(false) +std::shared_ptr<class tile_atlas> loader_impl::tile_atlas(StringView filename) noexcept(false) { fm_assert(!tile_atlas_map.empty()); auto it = tile_atlas_map.find(filename); @@ -120,7 +120,7 @@ std::shared_ptr<anim_atlas> loader_impl::anim_atlas(StringView name, StringView const auto width = size[1], height = size[0]; fm_soft_assert(anim_info.pixel_size[0] == width && anim_info.pixel_size[1] == height); - auto atlas = std::make_shared<struct anim_atlas>(path, tex, std::move(anim_info)); + auto atlas = std::make_shared<class anim_atlas>(path, tex, std::move(anim_info)); return anim_atlas_map[atlas->name()] = atlas; } } @@ -132,11 +132,13 @@ void loader_impl::get_anim_atlas_list() constexpr auto flags = f::SkipDirectories | f::SkipDotAndDotDot | f::SkipSpecial | f::SortAscending; if (const auto list = Path::list(ANIM_PATH, flags); list) { - anim_atlases.reserve(list->size()*2); + anim_atlases.reserve(list->size()); for (StringView str : *list) if (str.hasSuffix(".json")) anim_atlases.emplace_back(str.exceptSuffix(std::size(".json")-1)); } + anim_atlases.shrink_to_fit(); + fm_assert(!anim_atlases.empty()); } } // namespace floormat::loader_detail diff --git a/loader/impl.cpp b/loader/impl.cpp index 02493089..029f96a6 100644 --- a/loader/impl.cpp +++ b/loader/impl.cpp @@ -2,6 +2,7 @@ #include "compat/assert.hpp" #include "loader/scenery.hpp" #include "loader/vobj-info.hpp" +#include "loader/wall-info.hpp" #include <Corrade/Containers/Pair.h> #include <Magnum/Trade/ImageData.h> diff --git a/loader/impl.hpp b/loader/impl.hpp index f5975d0e..525a5ecc 100644 --- a/loader/impl.hpp +++ b/loader/impl.hpp @@ -10,22 +10,36 @@ #include <Corrade/PluginManager/PluginManager.h> #include <Magnum/Trade/AbstractImporter.h> -namespace floormat { struct anim_def; } +namespace floormat { +struct anim_def; +struct wall_info; +} namespace floormat::loader_detail { struct loader_impl final : loader_ { +// <-----< resources <-----< Optional<Utility::Resource> shader_res; Optional<PluginManager::Manager<Trade::AbstractImporter>> importer_plugins; Containers::Pointer<Trade::AbstractImporter> image_importer; Containers::Pointer<Trade::AbstractImporter> tga_importer; +// >-----> resources >-----> - tsl::robin_map<StringView, std::shared_ptr<struct tile_atlas>> tile_atlas_map; - tsl::robin_map<StringView, std::shared_ptr<struct anim_atlas>> anim_atlas_map; - tsl::robin_map<StringView, const struct vobj_info*> vobj_atlas_map; +// <-----< walls <-----< + struct wall_index { uint32_t val = (uint32_t)-1; }; + tsl::robin_map<StringView, const wall_info*> wall_atlas_map; + std::vector<wall_info> wall_atlas_array; + + const wall_info& wall_atlas(StringView name, StringView dir) override; + ArrayView<const wall_info> wall_atlas_list() override; + void get_wall_atlas_list(); + std::shared_ptr<class wall_atlas> get_wall_atlas(StringView pathname); +// >-----> walls >-----> + + tsl::robin_map<StringView, std::shared_ptr<class tile_atlas>> tile_atlas_map; + tsl::robin_map<StringView, std::shared_ptr<class anim_atlas>> anim_atlas_map; std::vector<String> anim_atlases; - std::vector<struct vobj_info> vobjs; std::vector<serialized_scenery> sceneries_array; tsl::robin_map<StringView, const serialized_scenery*> sceneries_map; @@ -34,21 +48,27 @@ struct loader_impl final : loader_ StringView shader(StringView filename) noexcept override; Trade::ImageData2D texture(StringView prefix, StringView filename) noexcept(false) override; - std::shared_ptr<struct tile_atlas> tile_atlas(StringView filename, Vector2ub size, Optional<pass_mode> pass) noexcept(false) override; - std::shared_ptr<struct tile_atlas> tile_atlas(StringView filename) noexcept(false) override; + std::shared_ptr<class tile_atlas> tile_atlas(StringView filename, Vector2ub size, Optional<pass_mode> pass) noexcept(false) override; + std::shared_ptr<class tile_atlas> tile_atlas(StringView filename) noexcept(false) override; ArrayView<const String> anim_atlas_list() override; - std::shared_ptr<struct anim_atlas> anim_atlas(StringView name, StringView dir) noexcept(false) override; + std::shared_ptr<class anim_atlas> anim_atlas(StringView name, StringView dir) noexcept(false) override; const std::vector<serialized_scenery>& sceneries() override; const scenery_proto& scenery(StringView name) noexcept(false) override; void get_anim_atlas_list(); void get_scenery_list(); - static anim_def deserialize_anim(StringView filename); - void get_vobj_list(); - std::shared_ptr<struct anim_atlas> make_vobj_anim_atlas(StringView name, StringView image_filename); +// <-----< vobjs <-----< + tsl::robin_map<StringView, const struct vobj_info*> vobj_atlas_map; + std::vector<struct vobj_info> vobjs; + + std::shared_ptr<class anim_atlas> make_vobj_anim_atlas(StringView name, StringView image_filename); const struct vobj_info& vobj(StringView name) override; ArrayView<const struct vobj_info> vobj_list() override; + void get_vobj_list(); +// >-----> vobjs >-----> + + static anim_def deserialize_anim(StringView filename); void set_application_working_directory(); StringView startup_directory() noexcept override; diff --git a/loader/json.cpp b/loader/json.cpp index 7e6aae68..007bafeb 100644 --- a/loader/json.cpp +++ b/loader/json.cpp @@ -29,6 +29,7 @@ void loader_impl::get_scenery_list() fm_abort("duplicate scenery name '%s'", s.name.data()); sceneries_map[s.name] = &s; } + fm_assert(!sceneries_map.empty()); } const std::vector<serialized_scenery>& loader_impl::sceneries() @@ -53,9 +54,9 @@ const scenery_proto& loader_impl::scenery(StringView name) noexcept(false) namespace floormat { -std::vector<std::shared_ptr<struct tile_atlas>> loader_::tile_atlases(StringView filename, pass_mode p) +std::vector<std::shared_ptr<class tile_atlas>> loader_::tile_atlases(StringView filename, pass_mode p) { - auto vec = json_helper::from_json<std::vector<std::shared_ptr<struct tile_atlas>>>( + auto vec = json_helper::from_json<std::vector<std::shared_ptr<class tile_atlas>>>( Path::join(loader_::IMAGE_PATH, filename)); for (auto& x : vec) if (!x->pass_mode()) diff --git a/loader/loader.cpp b/loader/loader.cpp index 7d95da0e..a89cadab 100644 --- a/loader/loader.cpp +++ b/loader/loader.cpp @@ -32,6 +32,8 @@ StringView loader_::strip_prefix(StringView name) return name.exceptPrefix(SCENERY_PATH.size()); if (name.hasPrefix(VOBJ_PATH)) return name.exceptPrefix(VOBJ_PATH.size()); + if (name.hasPrefix(WALL_TILESET_PATH)) + return name.exceptPrefix(WALL_TILESET_PATH.size()); return name; } diff --git a/loader/loader.hpp b/loader/loader.hpp index 181688fc..390f020c 100644 --- a/loader/loader.hpp +++ b/loader/loader.hpp @@ -17,23 +17,28 @@ using ImageData2D = ImageData<2>; namespace floormat { -struct tile_atlas; -struct anim_atlas; +class tile_atlas; +class anim_atlas; +class wall_atlas; struct scenery_proto; struct vobj_info; +struct wall_info; struct loader_ { virtual StringView shader(StringView filename) noexcept = 0; virtual Trade::ImageData2D texture(StringView prefix, StringView filename) noexcept(false) = 0; // todo remove Optional when wall_atlas is fully implemented -sh 20231122 - virtual std::shared_ptr<struct tile_atlas> tile_atlas(StringView filename, Vector2ub size, Optional<pass_mode> pass) noexcept(false) = 0; - virtual std::shared_ptr<struct tile_atlas> tile_atlas(StringView filename) noexcept(false) = 0; + virtual std::shared_ptr<class tile_atlas> tile_atlas(StringView filename, Vector2ub size, Optional<pass_mode> pass) noexcept(false) = 0; + virtual std::shared_ptr<class tile_atlas> tile_atlas(StringView filename) noexcept(false) = 0; virtual ArrayView<const String> anim_atlas_list() = 0; - virtual std::shared_ptr<struct anim_atlas> anim_atlas(StringView name, StringView dir = ANIM_PATH) noexcept(false) = 0; + virtual std::shared_ptr<class anim_atlas> anim_atlas(StringView name, StringView dir = ANIM_PATH) noexcept(false) = 0; + virtual const wall_info& wall_atlas(StringView name, StringView dir = WALL_TILESET_PATH) = 0; + virtual ArrayView<const wall_info> wall_atlas_list() = 0; static void destroy(); static loader_& default_loader() noexcept; - static std::vector<std::shared_ptr<struct tile_atlas>> tile_atlases(StringView filename, pass_mode p); + // todo move to ArrayView later, make non-static, and remove pass_mode + static std::vector<std::shared_ptr<class tile_atlas>> tile_atlases(StringView filename, pass_mode p); virtual const std::vector<serialized_scenery>& sceneries() = 0; virtual const scenery_proto& scenery(StringView name) noexcept(false) = 0; virtual StringView startup_directory() noexcept = 0; diff --git a/loader/vobj-info.hpp b/loader/vobj-info.hpp index 8bc7d189..75ace811 100644 --- a/loader/vobj-info.hpp +++ b/loader/vobj-info.hpp @@ -4,7 +4,7 @@ namespace floormat { -struct anim_atlas; +class anim_atlas; struct vobj_info final { diff --git a/loader/vobj.cpp b/loader/vobj.cpp index 1f8f5207..aa3be207 100644 --- a/loader/vobj.cpp +++ b/loader/vobj.cpp @@ -48,7 +48,7 @@ namespace floormat::loader_detail { #pragma GCC diagnostic ignored "-Wmissing-field-initializers" #endif -std::shared_ptr<struct anim_atlas> loader_impl::make_vobj_anim_atlas(StringView name, StringView image_filename) +std::shared_ptr<class anim_atlas> loader_impl::make_vobj_anim_atlas(StringView name, StringView image_filename) { auto tex = texture(VOBJ_PATH, image_filename); anim_def def; @@ -65,7 +65,7 @@ std::shared_ptr<struct anim_atlas> loader_impl::make_vobj_anim_atlas(StringView .size = def.pixel_size }} }}; - auto atlas = std::make_shared<struct anim_atlas>(name, tex, std::move(def)); + auto atlas = std::make_shared<class anim_atlas>(name, tex, std::move(def)); return atlas; } @@ -87,6 +87,8 @@ void loader_impl::get_vobj_list() const auto& x = vobjs.back(); vobj_atlas_map[x.atlas->name()] = &x; } + + fm_assert(!vobjs.empty()); } ArrayView<const vobj_info> loader_impl::vobj_list() diff --git a/loader/wall-atlas.cpp b/loader/wall-atlas.cpp new file mode 100644 index 00000000..10f3524d --- /dev/null +++ b/loader/wall-atlas.cpp @@ -0,0 +1,99 @@ +#include "loader/impl.hpp" +#include "wall-info.hpp" +#include "compat/assert.hpp" +#include "compat/exception.hpp" +#include "src/wall-atlas.hpp" +#include "serialize/wall-atlas.hpp" +#include "wall-info.hpp" +#include "serialize/json-helper.hpp" +#include "serialize/corrade-string.hpp" +#include <Corrade/Containers/Array.h> +#include <Corrade/Containers/ArrayViewStl.h> +#include <Corrade/Utility/Path.h> +#include <Magnum/Trade/ImageData.h> +#include <vector> + +namespace floormat { +NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(wall_info, name, descr) +} // namespace floormat + +namespace floormat::loader_detail { + +std::shared_ptr<wall_atlas> loader_impl::get_wall_atlas(StringView filename) +{ + using namespace floormat::Wall; + using namespace floormat::Wall::detail; + + const auto jroot = json_helper::from_json_(filename); + auto header = read_info_header(jroot); + auto frames = read_all_frames(jroot); + + size_t direction_count = 0; + for (const auto& [str, curdir] : wall_atlas::directions) + if (jroot.contains(std::string_view{str.data(), str.size()})) + direction_count++; + fm_soft_assert(direction_count > 0); + fm_debug_assert(direction_count <= (size_t)Direction_::COUNT); + + auto directions = Array<Direction>{direction_count}; + std::array<DirArrayIndex, 4> dir_array_indexes{}; + + uint8_t dir_idx = 0; + for (const auto& [str, curdir] : wall_atlas::directions) + { + if (!jroot.contains(std::string_view{str.data(), str.size()})) + continue; + auto i = (size_t)curdir; + fm_debug_assert(dir_idx < direction_count); + dir_array_indexes[i] = { .val = dir_idx }; + directions[dir_idx++] = read_direction_metadata(jroot, curdir); + } + fm_debug_assert(dir_idx == direction_count); + + auto atlas = std::make_shared<class wall_atlas>(); + return atlas; +} + +const wall_info& loader_impl::wall_atlas(StringView name, StringView dir) +{ + fm_soft_assert(check_atlas_name(name)); + char buf[FILENAME_MAX]; + auto path = make_atlas_path(buf, dir, name); + + auto it = wall_atlas_map.find(path); + if (it == wall_atlas_map.end()) + fm_throw("no such wall atlas '{}'"_cf, fmt::string_view{path.data(), path.size()}); + fm_assert(it->second != nullptr); + if (!it->second->atlas) + { + const_cast<wall_info*>(it->second)->atlas = get_wall_atlas(path); + } + return *it->second; +} + +void loader_impl::get_wall_atlas_list() +{ + wall_atlas_array = json_helper::from_json<std::vector<wall_info>>(Path::join(WALL_TILESET_PATH, "walls.json"_s)); + wall_atlas_array.shrink_to_fit(); + wall_atlas_map.clear(); + wall_atlas_map.reserve(wall_atlas_array.size()*2); + + for (const auto& x : wall_atlas_array) + { + fm_soft_assert(check_atlas_name(x.name)); + StringView name = x.name; + wall_atlas_map[name] = &x; + fm_debug_assert(name.data() == wall_atlas_map[name]->name.data()); + } + + fm_assert(!wall_atlas_map.empty()); +} + +ArrayView<const wall_info> loader_impl::wall_atlas_list() +{ + if (wall_atlas_map.empty()) + get_wall_atlas_list(); + return wall_atlas_array; +} + +} // namespace floormat::loader_detail diff --git a/loader/wall-info.hpp b/loader/wall-info.hpp new file mode 100644 index 00000000..570f436d --- /dev/null +++ b/loader/wall-info.hpp @@ -0,0 +1,15 @@ +#pragma once +#include <memory> +#include <Corrade/Containers/String.h> + +namespace floormat { + +class wall_atlas; + +struct wall_info +{ + String name, descr; + std::shared_ptr<wall_atlas> atlas; +}; + +} // namespace floormat |