From 9c9d02e674231dca8f9b75ea23a0efa0b28f970b Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 29 Oct 2022 02:33:29 +0200 Subject: a --- serialize/world-impl.hpp | 10 ++++++---- serialize/world-reader.cpp | 14 +++++++++----- serialize/world-writer.cpp | 27 +++++++++++++++++++++++---- 3 files changed, 38 insertions(+), 13 deletions(-) (limited to 'serialize') diff --git a/serialize/world-impl.hpp b/serialize/world-impl.hpp index 252f361e..4cff8794 100644 --- a/serialize/world-impl.hpp +++ b/serialize/world-impl.hpp @@ -10,7 +10,7 @@ namespace floormat::Serialize { namespace { using tilemeta = std::uint8_t; -using imgvar = decltype(tile_image::variant); +using varid = decltype(tile_image::variant); using atlasid = std::uint16_t; using chunksiz = std::uint16_t; using enum tile::pass_mode; @@ -29,9 +29,11 @@ constexpr inline std::underlying_type_t pass_mask = pass_blocke constexpr inline auto pass_bits = std::bit_width(pass_mask); enum : tilemeta { - meta_ground = 1 << (pass_bits + 0), - meta_wall_n = 1 << (pass_bits + 1), - meta_wall_w = 1 << (pass_bits + 2), + meta_ground = 1 << (pass_bits + 0), + meta_wall_n = 1 << (pass_bits + 1), + meta_wall_w = 1 << (pass_bits + 2), + meta_short_atlasid = 1 << (pass_bits + 3), + meta_short_variant = 1 << (pass_bits + 4), }; } // namespace diff --git a/serialize/world-reader.cpp b/serialize/world-reader.cpp index b999b5d4..6172703b 100644 --- a/serialize/world-reader.cpp +++ b/serialize/world-reader.cpp @@ -65,19 +65,23 @@ void reader_state::read_chunks(reader_t& s) for (std::size_t i = 0; i < TILE_COUNT; i++) { const tilemeta flags = s.read(); + tile& t = chunk[i]; + using uchar = std::uint8_t; const auto make_atlas = [&]() -> tile_image { - auto atlas = lookup_atlas(s.read()); - auto id = s.read(); - fm_assert(id < atlas->num_tiles()); - return { atlas, id }; + auto id = flags & meta_short_atlasid ? (atlasid)(s.read()) : s.read(); + auto v = flags & meta_short_variant ? (varid) (s.read()) : s.read(); + auto atlas = lookup_atlas(id); + fm_assert(v < atlas->num_tiles()); + return { atlas, v }; }; - tile& t = chunk[i]; + if (flags & meta_ground) t.ground = make_atlas(); if (flags & meta_wall_n) t.wall_north = make_atlas(); if (flags & meta_wall_w) t.wall_west = make_atlas(); + switch (auto x = flags & pass_mask) { case tile::pass_shoot_through: diff --git a/serialize/world-writer.cpp b/serialize/world-writer.cpp index 1739f899..8b33d35e 100644 --- a/serialize/world-writer.cpp +++ b/serialize/world-writer.cpp @@ -40,7 +40,7 @@ private: std::unordered_map tile_images; }; -constexpr auto tile_size = sizeof(tilemeta) + (sizeof(atlasid) + sizeof(imgvar))*3; +constexpr auto tile_size = sizeof(tilemeta) + (sizeof(atlasid) + sizeof(varid)) * 3; constexpr auto chunkbuf_size = sizeof(chunk_magic) + sizeof(chunk_coords) + tile_size * TILE_COUNT; @@ -100,6 +100,20 @@ void writer_state::serialize_chunk(const chunk& c, chunk_coords coord) flags |= meta_wall_n * (img_n != null_atlas); flags |= meta_wall_w * (img_w != null_atlas); + using uchar = std::uint8_t; + + constexpr auto ashortp = [](atlasid id) { + return id == null_atlas || id == (uchar)id; + }; + constexpr auto vshortp = [](const tile_image& img) { + return !img.atlas || img.variant == (uchar)img.variant; + }; + + if (flags != 0 && ashortp(img_g) && ashortp(img_n) && ashortp(img_w)) + flags |= meta_short_atlasid; + if (flags != 0 && vshortp(x.ground) && vshortp(x.wall_north) && vshortp(x.wall_west)) + flags |= meta_short_variant; + fm_debug_assert((x.passability & pass_mask) == x.passability); flags |= x.passability; @@ -115,12 +129,17 @@ void writer_state::serialize_chunk(const chunk& c, chunk_coords coord) check_atlas(x.wall_west); #endif + const auto write = [&](atlasid x, varid v) { + flags & meta_short_atlasid ? s << (uchar) x : s << x; + flags & meta_short_variant ? s << (uchar) v : s << v; + }; + if (img_g != null_atlas) - s << img_g << x.ground.variant; + write(img_g, x.ground.variant); if (img_n != null_atlas) - s << img_n << x.wall_north.variant; + write(img_n, x.wall_north.variant); if (img_w != null_atlas) - s << img_w << x.wall_west.variant; + write(img_w, x.wall_west.variant); } const auto nbytes = s.bytes_written(); -- cgit v1.2.3