From b6a42cc53f808c86342d1bcd400ea95e6e7f5762 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sat, 29 Oct 2022 00:54:19 +0200 Subject: serializer work --- compat/assert.hpp | 18 ++++++++++++------ loader/loader-impl.cpp | 5 +++++ serialize/binary-reader.hpp | 3 ++- serialize/binary-reader.inl | 25 +++++++++++++++++++------ serialize/world-reader.cpp | 7 ++++--- serialize/world-writer.cpp | 5 ++--- src/tile-image.hpp | 2 +- 7 files changed, 45 insertions(+), 20 deletions(-) diff --git a/compat/assert.hpp b/compat/assert.hpp index d63b30ff..58edbc15 100644 --- a/compat/assert.hpp +++ b/compat/assert.hpp @@ -25,22 +25,28 @@ namespace floormat { } // namespace floormat -#define fm_EMIT_DEBUG(pfx, ...) \ +#define fm_EMIT_DEBUG2(pfx, ...) \ do { \ if (!std::is_constant_evaluated()) { \ if constexpr (sizeof(pfx) > 1) \ std::fputs((pfx), stderr); \ - FM_KILL_WARN_double_promotion1() \ std::fprintf(stderr, __VA_ARGS__); \ - FM_KILL_WARN_double_promotion2() \ - std::fputc('\n', stderr); \ - std::fflush(stderr); \ } \ } while (false) +#define fm_EMIT_DEBUG(pfx, ...) \ + do { \ + FM_KILL_WARN_double_promotion1() \ + fm_EMIT_DEBUG2(pfx, __VA_ARGS__); \ + FM_KILL_WARN_double_promotion2() \ + std::fputc('\n', stderr); \ + std::fflush(stderr); \ + } while (false) + #define fm_abort(...) \ do { \ - fm_EMIT_DEBUG("fatal: ", __VA_ARGS__); \ + fm_EMIT_DEBUG2("fatal: ", __VA_ARGS__); \ + fm_EMIT_DEBUG("", "in %s:%d", __FILE__, __LINE__); \ ::floormat::_fm_abort(); \ } while (false) diff --git a/loader/loader-impl.cpp b/loader/loader-impl.cpp index 8c478161..9e6de31e 100644 --- a/loader/loader-impl.cpp +++ b/loader/loader-impl.cpp @@ -75,6 +75,7 @@ Trade::ImageData2D loader_impl::tile_texture(StringView filename_) static_assert(IMAGE_PATH[sizeof(IMAGE_PATH)-2] == '/'); fm_assert(filename_.size() < 4096); fm_assert(filename_.find('\\') == filename_.end()); + fm_assert(filename_.find('\0') == filename_.end()); fm_assert(tga_importer); constexpr std::size_t max_extension_length = 16; @@ -98,6 +99,10 @@ Trade::ImageData2D loader_impl::tile_texture(StringView filename_) auto ret = std::move(*img); return ret; } + else + { + fm_warn("can't open '%s'", filename); + } } const auto path = Utility::Path::currentDirectory(); filename[len] = '\0'; diff --git a/serialize/binary-reader.hpp b/serialize/binary-reader.hpp index 7eed2145..4876e0dc 100644 --- a/serialize/binary-reader.hpp +++ b/serialize/binary-reader.hpp @@ -45,7 +45,8 @@ struct binary_reader final { template T read() noexcept; template constexpr std::array read() noexcept; constexpr std::size_t bytes_read() const noexcept { return num_bytes_read; } - constexpr StringView read_asciiz_string() noexcept; + template + auto read_asciiz_string() noexcept; private: std::size_t num_bytes_read = 0; diff --git a/serialize/binary-reader.inl b/serialize/binary-reader.inl index ad2d59bc..b3d04109 100644 --- a/serialize/binary-reader.inl +++ b/serialize/binary-reader.inl @@ -84,13 +84,26 @@ binary_reader& operator>>(binary_reader& reader, T& x) noexcept } template -constexpr StringView binary_reader::read_asciiz_string() noexcept +template +auto binary_reader::read_asciiz_string() noexcept { - const It pos = it; - while (it != end) - if (char c = *it++; c == '\0') - return StringView{pos, (std::size_t)std::distance(pos, end), StringViewFlag::NullTerminated}; - fm_abort("unexpected EOF while reading a string"); + struct fixed_string final { + char buf[MAX]; + std::size_t len; + }; + + fixed_string ret; + for (std::size_t i = 0; i < MAX-1 && it != end; i++) + { + const char c = *it++; + ret.buf[i] = c; + if (c == '\0') + { + ret.len = i; + return ret; + } + } + fm_abort("can't find string terminator"); } } // namespace floormat::Serialize diff --git a/serialize/world-reader.cpp b/serialize/world-reader.cpp index 4b5d365c..4c67031e 100644 --- a/serialize/world-reader.cpp +++ b/serialize/world-reader.cpp @@ -35,7 +35,8 @@ void reader_state::read_atlases(reader_t& s) Vector2ub size; s >> size[0]; s >> size[1]; - atlases[i] = loader.tile_atlas(s.read_asciiz_string(), size); + auto str = s.read_asciiz_string(); + atlases[i] = loader.tile_atlas({str.buf, str.len}, size); } } @@ -67,9 +68,10 @@ void reader_state::read_chunks(reader_t& s) 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 }; }; - tile t; + tile& t = chunk[i]; if (flags & meta_ground) t.ground_image = make_atlas(); if (flags & meta_wall_n) @@ -86,7 +88,6 @@ void reader_state::read_chunks(reader_t& s) default: fm_abort("bad pass mode '%zu' for tile %zu", i, (std::size_t)x); } - chunk[i] = std::move(t); } } } diff --git a/serialize/world-writer.cpp b/serialize/world-writer.cpp index faf60849..e1750fb2 100644 --- a/serialize/world-writer.cpp +++ b/serialize/world-writer.cpp @@ -39,7 +39,7 @@ private: std::unordered_map tile_images; }; -constexpr auto tile_size = sizeof(tilemeta) + sizeof(atlasid)*3; +constexpr auto tile_size = sizeof(tilemeta) + (sizeof(atlasid) + sizeof(imgvar))*3; constexpr auto chunkbuf_size = sizeof(chunk_magic) + sizeof(chunk_coords) + tile_size * TILE_COUNT; @@ -88,8 +88,6 @@ void writer_state::serialize_chunk(const chunk& c, chunk_coords coord) { const tile& x = c[i]; - [[maybe_unused]] constexpr auto tile_size = sizeof(tilemeta) + (sizeof(atlasid) + sizeof(imgvar))*3; - fm_debug_assert(s.bytes_written() + tile_size <= chunkbuf_size); auto img_g = maybe_intern_atlas(x.ground_image); @@ -145,6 +143,7 @@ void writer_state::serialize_atlases() s << sz2[0]; s << sz2[1]; s.write_asciiz_string(name); } + atlas_buf.resize(s.bytes_written()); fm_assert(s.bytes_written() <= atlasbuf_size); } diff --git a/src/tile-image.hpp b/src/tile-image.hpp index 30ae7b0b..06d0cb41 100644 --- a/src/tile-image.hpp +++ b/src/tile-image.hpp @@ -10,7 +10,7 @@ struct tile_atlas; struct tile_image final { std::shared_ptr atlas; - std::uint16_t variant = (std::uint8_t)-1; + std::uint16_t variant = (std::uint16_t)-1; explicit operator bool() const noexcept { return !!atlas; } -- cgit v1.2.3