summaryrefslogtreecommitdiffhomepage
path: root/loader
diff options
context:
space:
mode:
Diffstat (limited to 'loader')
-rw-r--r--loader/atlas.cpp10
-rw-r--r--loader/impl.cpp1
-rw-r--r--loader/impl.hpp42
-rw-r--r--loader/json.cpp5
-rw-r--r--loader/loader.cpp2
-rw-r--r--loader/loader.hpp17
-rw-r--r--loader/vobj-info.hpp2
-rw-r--r--loader/vobj.cpp6
-rw-r--r--loader/wall-atlas.cpp99
-rw-r--r--loader/wall-info.hpp15
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