summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-04-08 22:20:20 +0200
committerStanislaw Halik <sthalik@misaki.pl>2023-04-08 22:20:20 +0200
commite301c700764f2eca2498c5e95e5cc44dab2f5b5c (patch)
treec0ae2582392799f294745933cb2858e6121c3bd4
parent9cca30206a8de348bde4bddfa8ae10bd35ea8b66 (diff)
serialize/save: add RLE for empty tiles
-rw-r--r--serialize/world-impl.hpp5
-rw-r--r--serialize/world-reader.cpp9
-rw-r--r--serialize/world-writer.cpp18
3 files changed, 31 insertions, 1 deletions
diff --git a/serialize/world-impl.hpp b/serialize/world-impl.hpp
index a869e022..ea7e8792 100644
--- a/serialize/world-impl.hpp
+++ b/serialize/world-impl.hpp
@@ -23,6 +23,7 @@
* 8) Entity subtypes.
* 9) Interned strings.
* 10) Chunk Z level.
+ * 11) RLE empty tiles.
*/
namespace floormat {
@@ -49,7 +50,7 @@ constexpr inline auto null_atlas = (atlasid)-1LL;
constexpr inline size_t character_name_max = 128;
constexpr inline size_t string_max = 512;
-constexpr inline proto_t proto_version = 10;
+constexpr inline proto_t proto_version = 11;
constexpr inline proto_t min_proto_version = 1;
constexpr inline auto chunk_magic = (uint16_t)~0xc0d3;
constexpr inline auto scenery_magic = (uint16_t)~0xb00b;
@@ -76,6 +77,8 @@ enum : tilemeta {
meta_ground = 1 << 2,
meta_wall_n = 1 << 3,
meta_wall_w = 1 << 4,
+ meta_rle = 1 << 7,
+
meta_short_atlasid_ = 1 << 5,
meta_short_variant_ = 1 << 6,
meta_scenery_ = 1 << 7,
diff --git a/serialize/world-reader.cpp b/serialize/world-reader.cpp
index 05add388..90b040f3 100644
--- a/serialize/world-reader.cpp
+++ b/serialize/world-reader.cpp
@@ -184,6 +184,15 @@ void reader_state::read_chunks(reader_t& s)
{
SET_CHUNK_SIZE();
const tilemeta flags = s.read<tilemeta>();
+
+ if (PROTO >= 11) [[likely]]
+ if (flags & meta_rle)
+ {
+ auto j = flags & 0x7fuz;
+ i += j;
+ continue;
+ }
+
tile_ref t = c[i];
using uchar = uint8_t;
const auto make_atlas = [&]() -> tile_image_proto {
diff --git a/serialize/world-writer.cpp b/serialize/world-writer.cpp
index ee955c47..8ffe1883 100644
--- a/serialize/world-writer.cpp
+++ b/serialize/world-writer.cpp
@@ -422,6 +422,24 @@ void writer_state::serialize_chunk(const chunk& c, chunk_coords_ coord)
auto img_n = maybe_intern_atlas(wall_north);
auto img_w = maybe_intern_atlas(wall_west);
+ if (img_g == null_atlas && img_n == null_atlas && img_w == null_atlas)
+ {
+ size_t j, max = std::min(TILE_COUNT, i + 0x80);
+ for (j = i+1; j < max; j++)
+ {
+ auto tile = c[j];
+ if (tile.ground_atlas || tile.wall_north_atlas || tile.wall_west_atlas)
+ break;
+ }
+ j -= i + 1;
+ fm_assert(j == (j & 0x7fuz));
+ i += j;
+ tilemeta flags = meta_rle | (tilemeta)j;
+ s << flags;
+
+ continue;
+ }
+
tilemeta flags = {};
flags |= meta_ground * (img_g != null_atlas);
flags |= meta_wall_n * (img_n != null_atlas);