diff options
Diffstat (limited to 'serialize')
-rw-r--r-- | serialize/scenery.cpp | 49 | ||||
-rw-r--r-- | serialize/world-impl.hpp | 2 | ||||
-rw-r--r-- | serialize/world-reader.cpp | 47 | ||||
-rw-r--r-- | serialize/world-writer.cpp | 30 |
4 files changed, 76 insertions, 52 deletions
diff --git a/serialize/scenery.cpp b/serialize/scenery.cpp index 4eeb95f7..3cd084cd 100644 --- a/serialize/scenery.cpp +++ b/serialize/scenery.cpp @@ -80,20 +80,19 @@ void adl_serializer<rotation>::from_json(const json& j, rotation& val) val = foo_from_string(j, rotation_map, "rotation"); } -void adl_serializer<scenery_proto>::to_json(json& j, const scenery_proto& val) +void adl_serializer<scenery_proto>::to_json(json& j, const scenery_proto& f) { - fm_assert(val.atlas); - constexpr scenery default_scenery; - const scenery& f = val.frame; + fm_assert(f.atlas); + const scenery_proto default_scenery; if (f.type != default_scenery.type) j["type"] = f.type; - j["atlas-name"] = val.atlas->name(); + j["atlas-name"] = f.atlas->name(); if (f.frame != default_scenery.frame) j["frame"] = f.frame; if (f.r != default_scenery.r) j["rotation"] = f.r; - if (f.passability != default_scenery.passability) - j["pass-mode"] = f.passability; + if (f.pass != default_scenery.pass) + j["pass-mode"] = f.pass; if (f.active != default_scenery.active) j["active"] = f.active; if (f.interactive != default_scenery.interactive) @@ -106,7 +105,7 @@ void adl_serializer<scenery_proto>::to_json(json& j, const scenery_proto& val) j["bbox-size"] = Vector2ui(f.bbox_size); } -void adl_serializer<scenery_proto>::from_json(const json& j, scenery_proto& val) +void adl_serializer<scenery_proto>::from_json(const json& j, scenery_proto& f) { const auto get = [&](const StringView& name, auto& value) { @@ -117,14 +116,13 @@ void adl_serializer<scenery_proto>::from_json(const json& j, scenery_proto& val) StringView atlas_name = j["atlas-name"]; fm_soft_assert(!atlas_name.isEmpty()); - val.atlas = loader.anim_atlas(atlas_name, loader_::SCENERY_PATH); - auto& f = val.frame; f = {}; + f.atlas = loader.anim_atlas(atlas_name, loader_::SCENERY_PATH); auto type = scenery_type::generic; get("type", type); auto frame = f.frame; get("frame", frame); - auto r = val.atlas->first_rotation(); get("rotation", r); - pass_mode pass = f.passability; get("pass-mode", pass); + auto r = f.atlas->first_rotation(); get("rotation", r); + pass_mode pass = f.pass; get("pass-mode", pass); bool active = f.active; get("active", active); bool interactive = f.interactive; get("interactive", interactive); auto offset = Vector2i(f.offset); get("offset", offset); @@ -139,13 +137,30 @@ void adl_serializer<scenery_proto>::from_json(const json& j, scenery_proto& val) default: fm_throw("unhandled scenery type '{}'"_cf, (unsigned)type); case scenery_type::generic: - f = { scenery::generic, *val.atlas, r, frame, pass, - active, interactive, - Vector2b(offset), Vector2b(bbox_offset), Vector2ub(bbox_size) }; + f.type = entity_type::scenery; + f.sc_type = scenery_type::generic; + f.r = r; + f.frame = frame; + f.pass = pass; + f.active = active; + f.interactive = interactive; + f.offset = Vector2b(offset); + f.bbox_offset = Vector2b(bbox_offset); + f.bbox_size = Vector2ub(bbox_size); break; case scenery_type::door: - f = { scenery::door, *val.atlas, r, false, - Vector2b(offset), Vector2b(bbox_offset), Vector2ub(bbox_size), }; + fm_assert(f.atlas->info().fps > 0 && f.atlas->info().nframes > 0); + f.type = entity_type::scenery; + f.sc_type = scenery_type::door; + f.r = r; + f.frame = std::uint16_t(f.atlas->group(r).frames.size()-1); + f.pass = pass_mode::blocked; + f.interactive = true; + f.closing = false; + f.offset = Vector2b(offset); + f.bbox_offset = Vector2b(bbox_offset); + f.bbox_size = Vector2ub(bbox_size); + break; } } diff --git a/serialize/world-impl.hpp b/serialize/world-impl.hpp index 5a43654e..c8282141 100644 --- a/serialize/world-impl.hpp +++ b/serialize/world-impl.hpp @@ -4,6 +4,8 @@ #pragma once #include "src/tile.hpp" +#include "src/pass-mode.hpp" +#include "src/rotation.hpp" #include <bit> #include <cstddef> #include <cstdint> diff --git a/serialize/world-reader.cpp b/serialize/world-reader.cpp index 3060579f..83a77ffb 100644 --- a/serialize/world-reader.cpp +++ b/serialize/world-reader.cpp @@ -2,6 +2,7 @@ #include "world-impl.hpp" #include "binary-reader.inl" #include "src/world.hpp" +#include "src/scenery.hpp" #include "loader/loader.hpp" #include "loader/scenery.hpp" #include "src/tile-atlas.hpp" @@ -52,10 +53,10 @@ void reader_state::read_atlases(reader_t& s) } template<typename T> -bool read_scenery_flags(binary_reader<T>& s, scenery& sc) +bool read_scenery_flags(binary_reader<T>& s, scenery_proto& sc) { std::uint8_t flags; flags << s; - sc.passability = pass_mode(flags & pass_mask); + sc.pass = pass_mode(flags & pass_mask); sc.active = !!(flags & 1 << 2); sc.closing = !!(flags & 1 << 3); sc.interactive = !!(flags & 1 << 4); @@ -79,20 +80,19 @@ void reader_state::read_sceneries(reader_t& s) std::uint8_t num; num << s; fm_soft_assert(num > 0); auto str = s.read_asciiz_string<atlas_name_max>(); - const auto sc_ = loader.scenery(str); + auto sc = loader.scenery(str); for (auto n = 0_uz; n < num; n++) { atlasid id; id << s; fm_soft_assert(id < sz); fm_soft_assert(!sceneries[id]); - scenery_proto sc = sc_; - bool short_frame = read_scenery_flags(s, sc.frame); + bool short_frame = read_scenery_flags(s, sc); fm_debug_assert(sc.atlas != nullptr); if (short_frame) - sc.frame.frame = s.read<std::uint8_t>(); + sc.frame = s.read<std::uint8_t>(); else - sc.frame.frame << s; - fm_soft_assert(sc.frame.frame < sc.atlas->info().nframes); + sc.frame << s; + fm_soft_assert(sc.frame < sc.atlas->info().nframes); sceneries[id] = sc; } i += num; @@ -165,39 +165,42 @@ void reader_state::read_chunks(reader_t& s) id &= ~scenery_id_flag_mask; auto sc = lookup_scenery(id); (void)sc.atlas->group(r); - sc.frame.r = r; + sc.r = r; if (!exact) { - if (read_scenery_flags(s, sc.frame)) - sc.frame.frame = s.read<std::uint8_t>(); + if (read_scenery_flags(s, sc)) + sc.frame = s.read<std::uint8_t>(); else - sc.frame.frame << s; + sc.frame << s; if (PROTO >= 5) [[likely]] { - sc.frame.offset[0] << s; - sc.frame.offset[1] << s; + sc.offset[0] << s; + sc.offset[1] << s; } if (PROTO >= 6) [[likely]] { - sc.frame.bbox_size[0] << s; - sc.frame.bbox_size[1] << s; + sc.bbox_size[0] << s; + sc.bbox_size[1] << s; } if (PROTO >= 7) [[likely]] { - sc.frame.bbox_offset[0] << s; - sc.frame.bbox_offset[1] << s; + sc.bbox_offset[0] << s; + sc.bbox_offset[1] << s; } - if (sc.frame.active) + if (sc.active) { if (PROTO >= 4) [[likely]] - sc.frame.delta << s; + sc.delta << s; else - sc.frame.delta = (std::uint16_t)Math::clamp(int(s.read<float>() * 65535), 0, 65535); + sc.delta = (std::uint16_t)Math::clamp(int(s.read<float>() * 65535), 0, 65535); } } - t.scenery() = sc; + + auto e = _world->make_entity<scenery>({ coord, local_coords{i} }, sc); + chunk.add_entity_unsorted(e); } } + chunk.sort_entities(); } } diff --git a/serialize/world-writer.cpp b/serialize/world-writer.cpp index 2a58a51b..413a9566 100644 --- a/serialize/world-writer.cpp +++ b/serialize/world-writer.cpp @@ -115,7 +115,6 @@ void writer_state::load_scenery_1(const serialized_scenery& s) scenery_map[ptr] = { { &s, null_atlas } }; else { - fm_assert(s.proto.frame.delta == 0); auto& vec = scenery_map[ptr]; for (const auto& x : vec) if (s.proto.frame == x.s->proto.frame) @@ -140,8 +139,8 @@ scenery_pair writer_state::intern_scenery(scenery_proto s, bool create) interned_scenery *ret = nullptr, *ret2 = nullptr; for (interned_scenery& x : vec) { - fm_debug_assert(s.frame.type == x.s->proto.frame.type); - s.frame.r = x.s->proto.frame.r; + fm_debug_assert(s.type == x.s->proto.type); + s.r = x.s->proto.r; if (x.s->proto.frame == s.frame) { if (x.index != null_atlas) @@ -178,10 +177,10 @@ scenery_pair writer_state::maybe_intern_scenery(const scenery_proto& s, bool cre } template<typename T> -void write_scenery_flags(binary_writer<T>& s, const scenery& proto) +void write_scenery_flags(binary_writer<T>& s, const scenery_proto& proto) { std::uint8_t flags = 0; - flags |= pass_mode_(proto.passability) & pass_mask; + flags |= pass_mode_(proto.pass) & pass_mask; flags |= (1 << 2) * proto.active; flags |= (1 << 3) * proto.closing; flags |= (1 << 4) * proto.interactive; @@ -272,12 +271,11 @@ void writer_state::serialize_scenery() s.write_asciiz_string(sc->name); } s << idx; - const auto& fr = sc->proto.frame; - write_scenery_flags(s, sc->proto.frame); - if (sc->proto.frame.frame <= 0xff) - s << (std::uint8_t)fr.frame; + write_scenery_flags(s, sc->proto); + if (sc->proto.frame <= 0xff) + s << (std::uint8_t)sc->proto.frame; else - s << fr.frame; + s << sc->proto.frame; } scenery_buf.resize(s.bytes_written()); @@ -296,27 +294,29 @@ void writer_state::serialize_chunk(const chunk& c, chunk_coords coord) { const tile_proto x = c[i]; const auto ground = x.ground(), wall_north = x.wall_north(), wall_west = x.wall_west(); - const auto scenery = x.scenery_frame; + //const auto scenery = x.scenery_frame; fm_debug_assert(s.bytes_written() + tile_size <= chunkbuf_size); auto img_g = maybe_intern_atlas(ground); auto img_n = maybe_intern_atlas(wall_north); auto img_w = maybe_intern_atlas(wall_west); - auto [sc, img_s, sc_exact] = maybe_intern_scenery(x.scenery(), true); + //auto [sc, img_s, sc_exact] = maybe_intern_scenery(x.scenery(), true); +#if 0 if (sc_exact && sc) { sc_exact = scenery.offset == sc->proto.frame.offset && scenery.bbox_size == sc->proto.frame.bbox_size && scenery.bbox_offset == sc->proto.frame.bbox_offset; } +#endif tilemeta flags = {}; flags |= meta_ground * (img_g != null_atlas); flags |= meta_wall_n * (img_n != null_atlas); flags |= meta_wall_w * (img_w != null_atlas); - flags |= meta_scenery * (img_s != null_atlas); + //flags |= meta_scenery * (img_s != null_atlas); using uchar = std::uint8_t; @@ -353,6 +353,7 @@ void writer_state::serialize_chunk(const chunk& c, chunk_coords coord) write(img_n, wall_north.variant); if (img_w != null_atlas) write(img_w, wall_west.variant); +#if 0 if (img_s != null_atlas) { atlasid id = img_s; @@ -381,6 +382,7 @@ void writer_state::serialize_chunk(const chunk& c, chunk_coords coord) s << scenery.delta; } } +#endif } const auto nbytes = s.bytes_written(); @@ -403,9 +405,11 @@ ArrayView<const char> writer_state::serialize_world() { load_scenery(); +#if 0 for (const auto& [_, c] : _world->chunks()) for (auto [x, _k, _pt] : c) maybe_intern_scenery(x.scenery(), false); +#endif for (const auto& [pos, c] : _world->chunks()) { |