diff options
-rw-r--r-- | serialize/world-writer.cpp | 112 |
1 files changed, 60 insertions, 52 deletions
diff --git a/serialize/world-writer.cpp b/serialize/world-writer.cpp index 801657e5..4bf7315f 100644 --- a/serialize/world-writer.cpp +++ b/serialize/world-writer.cpp @@ -48,10 +48,13 @@ struct writer_state final { fm_DECLARE_DEPRECATED_COPY_ASSIGNMENT(writer_state); 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); scenery_pair intern_scenery(const scenery& sc, bool create); + void serialize_new_scenery(const chunk& c, writer_t& s); void serialize_chunk(const chunk& c, chunk_coords coord); void serialize_atlases(); void serialize_scenery(); @@ -285,58 +288,8 @@ void writer_state::serialize_scenery() const auto def_char_bbox_size = character_proto{}.bbox_size; const auto def_char_pass = character_proto{}.pass; -void writer_state::serialize_chunk(const chunk& c, chunk_coords coord) +void writer_state::serialize_new_scenery(const chunk& c, writer_t& s) { - fm_assert(chunk_buf.empty()); - const auto es_size = sizeof(uint32_t) + entity_size*c.entities().size(); - chunk_buf.resize(chunkbuf_size + es_size); - - auto s = binary_writer{chunk_buf.begin()}; - - s << chunk_magic << coord.x << coord.y; - - for (auto i = 0_uz; i < TILE_COUNT; i++) - { - 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; - - 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); - - 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); - s << flags; - - constexpr auto check_atlas = [](const tile_image_proto& x) { - fm_assert(!x.atlas || x.variant < x.atlas->num_tiles()); - }; - check_atlas(ground); - check_atlas(wall_north); - check_atlas(wall_west); - - if (img_g != null_atlas) - { - s << img_g; - s << ground.variant; - } - if (img_n != null_atlas) - { - s << img_n; - s << wall_north.variant; - } - if (img_w != null_atlas) - { - s << img_w; - s << wall_west.variant; - } - } - const auto entity_count = (uint32_t)c.entities().size(); s << entity_count; fm_assert(entity_count == c.entities().size()); @@ -380,7 +333,7 @@ void writer_state::serialize_chunk(const chunk& c, chunk_coords coord) s << C.offset_frac[0]; s << C.offset_frac[1]; fm_assert(C.name.size() < character_name_max); - s.write_asciiz_string(C.name); + s << intern_string(C.name); if (!sc_exact) write_offsets(s, C); break; @@ -414,6 +367,61 @@ void writer_state::serialize_chunk(const chunk& c, chunk_coords coord) } } } +} + +void writer_state::serialize_chunk(const chunk& c, chunk_coords coord) +{ + fm_assert(chunk_buf.empty()); + const auto es_size = sizeof(uint32_t) + entity_size*c.entities().size(); + chunk_buf.resize(chunkbuf_size + es_size); + + auto s = binary_writer{chunk_buf.begin()}; + + s << chunk_magic << coord.x << coord.y; + + for (auto i = 0_uz; i < TILE_COUNT; i++) + { + 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; + + 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); + + 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); + s << flags; + + constexpr auto check_atlas = [](const tile_image_proto& x) { + fm_assert(!x.atlas || x.variant < x.atlas->num_tiles()); + }; + check_atlas(ground); + check_atlas(wall_north); + check_atlas(wall_west); + + if (img_g != null_atlas) + { + s << img_g; + s << ground.variant; + } + if (img_n != null_atlas) + { + s << img_n; + s << wall_north.variant; + } + if (img_w != null_atlas) + { + s << img_w; + s << wall_west.variant; + } + } + + serialize_new_scenery(c, s); const auto nbytes = s.bytes_written(); fm_assert(nbytes <= chunkbuf_size); |