diff options
Diffstat (limited to 'serialize')
-rw-r--r-- | serialize/world-reader.cpp | 38 | ||||
-rw-r--r-- | serialize/world-writer.cpp | 50 |
2 files changed, 42 insertions, 46 deletions
diff --git a/serialize/world-reader.cpp b/serialize/world-reader.cpp index d3954b09..f90acbd6 100644 --- a/serialize/world-reader.cpp +++ b/serialize/world-reader.cpp @@ -27,7 +27,7 @@ struct reader_state final { private: using reader_t = binary_reader<decltype(ArrayView<const char>{}.cbegin())>; - const std::shared_ptr<tile_atlas>& lookup_atlas(atlasid id); + StringView lookup_atlas(atlasid id); const scenery_proto& lookup_scenery(atlasid id); StringView lookup_string(uint32_t idx); void read_atlases(reader_t& reader); @@ -38,7 +38,7 @@ private: std::vector<String> strings; std::vector<scenery_proto> sceneries; - std::vector<std::shared_ptr<tile_atlas>> atlases; + std::vector<String> atlases; world* _world; uint16_t PROTO = proto_version; @@ -59,9 +59,7 @@ void reader_state::read_atlases(reader_t& s) size[0] << s; size[1] << s; const auto& [buf, len] = s.read_asciiz_string<atlas_name_max>(); - auto atlas = loader.tile_atlas({buf, len}); - fm_soft_assert(size <= atlas->num_tiles2()); - atlases.push_back(std::move(atlas)); + atlases.push_back({buf, len}); } } @@ -136,7 +134,7 @@ void reader_state::read_strings(reader_t& s) } } -const std::shared_ptr<tile_atlas>& reader_state::lookup_atlas(atlasid id) +StringView reader_state::lookup_atlas(atlasid id) { if (id < atlases.size()) return atlases[id]; @@ -202,7 +200,7 @@ void reader_state::read_chunks(reader_t& s) tile_ref t = c[i]; using uchar = uint8_t; - const auto make_atlas = [&]() -> tile_image_proto { + const auto make_atlas = [&]<typename T>() -> image_proto_<T> { atlasid id; if (PROTO < 8) [[unlikely]] id = flags & meta_short_atlasid_ ? atlasid{s.read<uchar>()} : s.read<atlasid>(); @@ -215,21 +213,29 @@ void reader_state::read_chunks(reader_t& s) v = flags & meta_short_variant_ ? s.read<uint8_t>() : uint8_t(s.read<uint16_t>()); - auto atlas = lookup_atlas(id); - fm_soft_assert(v < atlas->num_tiles()); - return { atlas, v }; + auto name = lookup_atlas(id); + if constexpr(std::is_same_v<tile_atlas, T>) + { + auto atlas = loader.tile_atlas(name); + fm_soft_assert(v < atlas->num_tiles()); + return { atlas, v }; + } + else if (std::is_same_v<wall_atlas, T>) + { + auto atlas = loader.wall_atlas(name, true); + return { atlas, v }; + } + else + std::unreachable(); }; SET_CHUNK_SIZE(); //t.passability() = pass_mode(flags & pass_mask); if (flags & meta_ground) - t.ground() = make_atlas(); - // todo! -#if 0 + t.ground() = make_atlas.operator()<tile_atlas>(); if (flags & meta_wall_n) - t.wall_north() = make_atlas(); + t.wall_north() = make_atlas.operator()<wall_atlas>(); if (flags & meta_wall_w) - t.wall_west() = make_atlas(); -#endif + t.wall_west() = make_atlas.operator()<wall_atlas>(); if (PROTO >= 3 && PROTO < 8) [[unlikely]] if (flags & meta_scenery_) read_old_scenery(s, ch, i); diff --git a/serialize/world-writer.cpp b/serialize/world-writer.cpp index 90fcf3b4..a89f039a 100644 --- a/serialize/world-writer.cpp +++ b/serialize/world-writer.cpp @@ -1,7 +1,7 @@ #define FM_SERIALIZE_WORLD_IMPL #include "world-impl.hpp" - #include "src/tile-atlas.hpp" +#include "src/wall-atlas.hpp" #include "binary-writer.inl" #include "src/global-coords.hpp" #include "src/chunk.hpp" @@ -30,8 +30,9 @@ using namespace floormat::Serialize; namespace { struct interned_atlas final { - const tile_atlas* img; + StringView name; atlasid index; + Vector2ub num_tiles; }; struct interned_scenery { @@ -55,8 +56,7 @@ struct writer_state final { private: using writer_t = binary_writer<decltype(std::vector<char>{}.begin())>; - atlasid intern_atlas(const tile_image_proto& img); - atlasid maybe_intern_atlas(const tile_image_proto& img); + atlasid intern_atlas(const void* ptr, StringView name, Vector2ub num_tiles); scenery_pair intern_scenery(const scenery& sc, bool create); uint32_t intern_string(StringView name); @@ -97,17 +97,17 @@ uint32_t writer_state::intern_string(StringView name) return kv->second; } -atlasid writer_state::intern_atlas(const tile_image_proto& img) +atlasid writer_state::intern_atlas(const void* ptr, StringView name, Vector2ub num_tiles) { - const void* const ptr = img.atlas.get(); fm_debug_assert(ptr != nullptr); - emplacer e{[&]() -> interned_atlas { return { &*img.atlas, (atlasid)tile_images.size() }; }}; - return tile_images.try_emplace(ptr, e).first->second.index; -} - -atlasid writer_state::maybe_intern_atlas(const tile_image_proto& img) -{ - return img ? intern_atlas(img) : null_atlas; + if (auto it = tile_images.find(ptr); it != tile_images.end()) + return it->second.index; + else + { + auto aid = (atlasid)tile_images.size(); + tile_images[ptr] = { name, aid, num_tiles }; + return aid; + } } void writer_state::load_scenery_1(const serialized_scenery& s) @@ -227,14 +227,12 @@ void writer_state::serialize_atlases() return a.index < b.index; }); - for (const auto& [atlas, _] : atlases) + for (const auto& [name, aid, num_tiles] : atlases) { - const auto name = atlas->name(); const auto namesiz = name.size(); fm_debug_assert(s.bytes_written() + namesiz < atlasbuf_size); fm_assert(namesiz < atlas_name_max); - const auto sz2 = atlas->num_tiles2(); - s << sz2[0]; s << sz2[1]; + s << num_tiles[0]; s << num_tiles[1]; s.write_asciiz_string(name); } atlas_buf.resize(s.bytes_written()); @@ -464,11 +462,11 @@ void writer_state::serialize_chunk(const chunk& c, chunk_coords_ coord) 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); - // todo! - auto img_n = null_atlas, img_w = null_atlas; + auto img_g = ground.atlas ? intern_atlas(&*ground.atlas, ground.atlas->name(), ground.atlas->num_tiles2()) : null_atlas; + auto img_n = wall_north ? intern_atlas(&*wall_north.atlas, wall_north.atlas->name(), {0xff, 0xff}) : null_atlas; + auto img_w = wall_west ? intern_atlas(&*wall_west.atlas, wall_west.atlas->name(), {0xff, 0xff}) : null_atlas; + + fm_assert(!ground.atlas || ground.variant < ground.atlas->num_tiles()); if (img_g == null_atlas && img_n == null_atlas && img_w == null_atlas) { @@ -494,14 +492,6 @@ void writer_state::serialize_chunk(const chunk& c, chunk_coords_ coord) flags |= meta_wall_w * (img_w != null_atlas); s << flags; - constexpr auto check_atlas = [](const tile_image_proto& x) { - fm_assert(!x.atlas || x.variant < x.atlas->num_tiles()); - }; - check_atlas(ground); - // todo! - //check_atlas(wall_north); - //check_atlas(wall_west); - if (img_g != null_atlas) { s << img_g; |