summaryrefslogtreecommitdiffhomepage
path: root/loader
diff options
context:
space:
mode:
Diffstat (limited to 'loader')
-rw-r--r--loader/anim-traits.cpp40
-rw-r--r--loader/atlas.cpp15
-rw-r--r--loader/loader.hpp4
3 files changed, 48 insertions, 11 deletions
diff --git a/loader/anim-traits.cpp b/loader/anim-traits.cpp
index 925fcfad..e15956e9 100644
--- a/loader/anim-traits.cpp
+++ b/loader/anim-traits.cpp
@@ -4,11 +4,15 @@
#include "src/anim-atlas.hpp"
#include "src/tile-defs.hpp"
#include "loader.hpp"
+#include "serialize/json-helper.hpp"
+#include "serialize/anim.hpp"
#include "compat/exception.hpp"
+#include <cr/Move.h>
#include <cr/StringView.h>
+#include <cr/Array.h>
+#include <cr/StridedArrayView.h>
#include <cr/Pointer.h>
#include <cr/Optional.h>
-#include <cr/Move.h>
#include <mg/ImageData.h>
#include <mg/ImageView.h>
@@ -62,9 +66,39 @@ auto anim_traits::make_invalid_atlas(Storage& s) -> Pointer<Cell>
return Pointer<anim_cell>{ InPlace, Utility::move(info) };
}
-auto anim_traits::make_atlas(StringView name, const Cell& c) -> std::shared_ptr<Atlas>
+auto anim_traits::make_atlas(StringView name, const Cell&) -> std::shared_ptr<Atlas>
{
- return {}; // todo
+ char buf[fm_FILENAME_MAX];
+ auto json_path = loader.make_atlas_path(buf, {}, name, ".json"_s);
+ auto anim_info = json_helper::from_json<struct anim_def>(json_path);
+
+ for (anim_group& group : anim_info.groups)
+ {
+ if (!group.mirror_from.isEmpty())
+ {
+ const auto *begin = anim_info.groups.data(), *end = begin + anim_info.groups.size();
+ const auto* it = std::find_if(begin, end, [&](const anim_group& x) { return x.name == group.mirror_from; });
+ if (it == end)
+ fm_throw("can't find group '{}' to mirror from '{}'"_cf, group.mirror_from, group.name);
+ group.frames = array(ArrayView<const anim_frame>{it->frames.data(), it->frames.size()});
+ for (anim_frame& f : group.frames)
+ f.ground = Vector2i((Int)f.size[0] - f.ground[0], f.ground[1]);
+ }
+ }
+
+ auto tex = loader.texture(""_s, name);
+
+ fm_soft_assert(!anim_info.object_name.isEmpty());
+ fm_soft_assert(anim_info.pixel_size.product() > 0);
+ fm_soft_assert(!anim_info.groups.isEmpty());
+ fm_soft_assert(anim_info.nframes > 0);
+ fm_soft_assert(anim_info.nframes == 1 || anim_info.fps > 0);
+ const auto size = tex.pixels().size();
+ 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<class anim_atlas>(name, tex, std::move(anim_info));
+ return atlas;
}
auto anim_traits::make_cell(StringView name) -> Optional<Cell>
diff --git a/loader/atlas.cpp b/loader/atlas.cpp
index b64efde2..b283fa87 100644
--- a/loader/atlas.cpp
+++ b/loader/atlas.cpp
@@ -14,14 +14,17 @@
namespace floormat {
-StringView loader_::make_atlas_path(char(&buf)[fm_FILENAME_MAX], StringView dir, StringView name)
+StringView loader_::make_atlas_path(char(&buf)[fm_FILENAME_MAX], StringView dir, StringView name, StringView ext)
{
fm_soft_assert(!dir || dir[dir.size()-1] == '/');
- const auto dirsiz = dir.size(), namesiz = name.size();
- fm_soft_assert(dirsiz + namesiz + 1 < fm_FILENAME_MAX);
- std::memcpy(buf, dir.data(), dirsiz);
- std::memcpy(&buf[dirsiz], name.data(), namesiz);
- auto len = dirsiz + namesiz;
+ fm_soft_assert(name);
+ fm_soft_assert(!ext || ext[0] == '.');
+ const auto dirsiz = dir.size(), namesiz = name.size(), extsiz = ext.size(),
+ len = dirsiz + namesiz + extsiz;
+ fm_soft_assert(len < fm_FILENAME_MAX);
+ std::memcpy(&buf[0], dir.data(), dirsiz );
+ std::memcpy(&buf[dirsiz], name.data(), namesiz);
+ std::memcpy(&buf[dirsiz + namesiz], ext.data(), extsiz );
buf[len] = '\0';
return StringView{buf, len, StringViewFlag::NullTerminated};
}
diff --git a/loader/loader.hpp b/loader/loader.hpp
index 60fda8b6..701f38d7 100644
--- a/loader/loader.hpp
+++ b/loader/loader.hpp
@@ -3,7 +3,7 @@
#include "src/pass-mode.hpp"
#include "loader/policy.hpp"
#include <memory>
-#include <Corrade/Containers/String.h>
+#include <cr/StringView.h>
//namespace Magnum { using Vector2ub = Math::Vector2<unsigned char>; }
namespace Magnum::Trade { template<uint32_t> class ImageData; using ImageData2D = ImageData<2>; }
@@ -44,7 +44,7 @@ struct loader_
static StringView strip_prefix(StringView name);
virtual const vobj_cell& vobj(StringView name) = 0;
virtual ArrayView<const struct vobj_cell> vobj_list() = 0;
- static StringView make_atlas_path(char(&buf)[fm_FILENAME_MAX], StringView dir, StringView name);
+ static StringView make_atlas_path(char(&buf)[fm_FILENAME_MAX], StringView dir, StringView name, StringView extension = {});
[[nodiscard]] static bool check_atlas_name(StringView name) noexcept;
virtual const wall_cell& make_invalid_wall_atlas() = 0;