summaryrefslogtreecommitdiffhomepage
path: root/serialize
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-01-12 05:20:08 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-01-12 05:20:48 +0100
commit749753cefb36b72911d806b0c125eba43df3a1db (patch)
tree60972a7450eb5dcd55f9496fe644d2806f747f6b /serialize
parenta504671200d27508636bfaea023f3a8dc3d19805 (diff)
a
Diffstat (limited to 'serialize')
-rw-r--r--serialize/world-impl.hpp10
-rw-r--r--serialize/world-reader.cpp22
-rw-r--r--serialize/world-writer.cpp16
3 files changed, 31 insertions, 17 deletions
diff --git a/serialize/world-impl.hpp b/serialize/world-impl.hpp
index d4b2feaa..5efd9bbc 100644
--- a/serialize/world-impl.hpp
+++ b/serialize/world-impl.hpp
@@ -50,7 +50,7 @@ template<typename T> constexpr inline T int_max = std::numeric_limits<T>::max();
#define file_magic ".floormat.save"
-constexpr inline proto_t proto_version = 18;
+constexpr inline proto_t proto_version = 19;
constexpr inline size_t atlas_name_max = 128;
constexpr inline auto null_atlas = (atlasid)-1LL;
@@ -70,10 +70,10 @@ constexpr inline auto highbits = (T(1) << N)-1 << sizeof(T)*8-N-off;
template<size_t N, typename T = uint8_t>
constexpr T lowbits = T((T{1} << N)-T{1});
-constexpr inline atlasid meta_short_scenery_bit_ = highbits<atlasid, 1, 0>;
-constexpr inline atlasid meta_rotation_bits_ = highbits<atlasid, rotation_BITS, 1>;
-constexpr inline atlasid scenery_id_flag_mask_ = meta_short_scenery_bit_ | meta_rotation_bits_;
-constexpr inline atlasid scenery_id_max_ = int_max<atlasid> & ~scenery_id_flag_mask_;
+constexpr inline uint8_t meta_short_scenery_bit = highbits<uint8_t, 1, 0>;
+constexpr inline uint8_t meta_rotation_bits = highbits<uint8_t, rotation_BITS, 1>;
+constexpr inline uint8_t scenery_id_flag_mask = meta_short_scenery_bit | meta_rotation_bits;
+constexpr inline uint8_t scenery_id_max = int_max<uint8_t> & ~scenery_id_flag_mask;
} // namespace
diff --git a/serialize/world-reader.cpp b/serialize/world-reader.cpp
index 324a0d19..6bfcaa47 100644
--- a/serialize/world-reader.cpp
+++ b/serialize/world-reader.cpp
@@ -20,6 +20,11 @@ namespace {
using namespace floormat;
using namespace floormat::Serialize;
+constexpr inline atlasid meta_short_scenery_bit_ = highbits<atlasid, 1, 0>;
+constexpr inline atlasid meta_rotation_bits_ = highbits<atlasid, rotation_BITS, 1>;
+constexpr inline atlasid scenery_id_flag_mask_ = meta_short_scenery_bit_ | meta_rotation_bits_;
+constexpr inline atlasid scenery_id_max_ = int_max<atlasid> & ~scenery_id_flag_mask_;
+
struct reader_state final {
explicit reader_state(world& world) noexcept;
void deserialize_world(ArrayView<const char> buf);
@@ -330,9 +335,20 @@ void reader_state::read_chunks(reader_t& s)
}
case object_type::scenery: {
atlasid id; id << s;
- const bool exact = id & meta_short_scenery_bit_;
- const auto r = rotation(id >> sizeof(id)*8-1-rotation_BITS & rotation_MASK);
- id &= ~scenery_id_flag_mask_;
+ bool exact;
+ rotation r;
+ if (PROTO >= 19) [[likely]]
+ {
+ uint8_t bits; bits << s;
+ exact = bits & meta_short_scenery_bit;
+ r = rotation(bits >> sizeof(bits)*8-1-rotation_BITS & rotation_MASK);
+ }
+ else
+ {
+ exact = id & meta_short_scenery_bit_;
+ r = rotation(id >> sizeof(id)*8-1-rotation_BITS & rotation_MASK);
+ id &= ~scenery_id_flag_mask_;
+ }
auto sc = lookup_scenery(id);
sc.offset = offset;
(void)sc.atlas->group(r);
diff --git a/serialize/world-writer.cpp b/serialize/world-writer.cpp
index 3d16505c..23381ab8 100644
--- a/serialize/world-writer.cpp
+++ b/serialize/world-writer.cpp
@@ -244,8 +244,8 @@ constexpr auto atlasbuf_size1 = sizeof(uint8_t) + atlasbuf_size0*int_max<uint8_t
void writer_state::serialize_scenery_names()
{
- fm_assert(scenery_map_size < scenery_id_max_);
const size_t sz = scenery_map_size;
+ fm_assert(sz == (atlasid)sz);
std::vector<interned_scenery> vec; vec.reserve(scenery_map_size);
for (const auto& x : scenery_map)
for (const auto& s : x.second)
@@ -269,7 +269,6 @@ void writer_state::serialize_scenery_names()
auto s = binary_writer{scenery_buf.begin()};
s << uint16_t{scenery_magic};
- fm_assert(sz < scenery_id_max_);
s << (atlasid)sz;
StringView last;
@@ -358,7 +357,7 @@ void writer_state::serialize_scenery(const chunk& c, writer_t& s)
const auto sc_exact =
C.bbox_offset.isZero() &&
C.bbox_size == def_char_bbox_size;
- id |= meta_short_scenery_bit_ * sc_exact;
+ id |= meta_short_scenery_bit * sc_exact;
id |= static_cast<decltype(id)>(C.r) << sizeof(id)*8-1-rotation_BITS;
s << id;
write_object_flags(s, C);
@@ -384,12 +383,11 @@ void writer_state::serialize_scenery(const chunk& c, writer_t& s)
sc.interactive == ss->interactive &&
sc.delta == 0 && sc.frame == ss->frame;
fm_assert(img_s != null_atlas);
- atlasid id = img_s;
- static_assert(rotation_BITS == 3);
- fm_assert(id == (id & lowbits<16-3-1, atlasid>));
- id |= meta_short_scenery_bit_ * sc_exact;
- id |= static_cast<decltype(id)>(sc.r) << sizeof(id)*8-1-rotation_BITS;
- s << id;
+ s << img_s;
+ uint8_t bits = 0;
+ bits |= meta_short_scenery_bit * sc_exact;
+ bits |= std::to_underlying(sc.r) << sizeof(bits)*8-1-rotation_BITS;
+ s << bits;
if (!sc_exact)
{
write_object_flags(s, sc);