Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compress TileMap tiles in level file #3124

Merged
merged 11 commits into from
Dec 5, 2024
6 changes: 2 additions & 4 deletions src/editor/object_option.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -711,11 +711,9 @@ TilesObjectOption::parse(const ReaderMapping& reader)
}

void
TilesObjectOption::save(Writer& write) const
TilesObjectOption::save(Writer& writer) const
{
write.write("width", m_value_pointer->get_width());
write.write("height", m_value_pointer->get_height());
write.write("tiles", m_value_pointer->get_tiles(), m_value_pointer->get_width());
m_value_pointer->write_tiles(writer);
}

std::string
Expand Down
10 changes: 9 additions & 1 deletion src/object/tilemap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ TileMap::parse_tiles(const ReaderMapping& reader)
}
else
{
reader.get("tiles", m_tiles);
reader.get_merge("tiles", m_tiles, 0);
if (m_tiles.empty())
throw std::runtime_error("No tiles in tilemap.");

Expand Down Expand Up @@ -206,6 +206,14 @@ TileMap::parse_tiles(const ReaderMapping& reader)
m_new_offset_y = 0;
}

void
TileMap::write_tiles(Writer& writer) const
{
writer.write("width", m_width);
writer.write("height", m_height);
writer.write_merge("tiles", m_tiles, 0, m_width);
}

void
TileMap::finish_construction()
{
Expand Down
5 changes: 3 additions & 2 deletions src/object/tilemap.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ class TileMap final : public LayerObject,
TileMap(const TileSet *tileset, const ReaderMapping& reader);
~TileMap() override;

void parse_tiles(const ReaderMapping& reader);

virtual void finish_construction() override;

static std::string class_name() { return "tilemap"; }
Expand All @@ -84,6 +82,9 @@ class TileMap final : public LayerObject,

virtual void on_flip(float height) override;

void parse_tiles(const ReaderMapping& reader);
void write_tiles(Writer& writer) const;

void set(int width, int height, const std::vector<unsigned int>& vec,
int z_pos, bool solid);

Expand Down
23 changes: 23 additions & 0 deletions src/util/reader_mapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,29 @@ ReaderMapping::get(const char* key, std::vector<unsigned int>& value,
GET_VALUES_MACRO("unsigned int", is_integer, as_int)
}

bool
ReaderMapping::get_merge(const char* key, std::vector<unsigned int>& value, unsigned int merge_value) const
{
const auto sx = get_item(key);
if (!sx)
return false;

assert_is_array(m_doc, *sx);
value.clear();
const auto& item = sx->as_array();
for (size_t i = 1; i < item.size(); ++i)
{
assert_is_integer(m_doc, item[i]);

const int val = item[i].as_int();
if (val < 0)
value.insert(value.end(), -val, merge_value);
else
value.emplace_back(val);
}
return true;
}

#undef GET_VALUES_MACRO

bool
Expand Down
3 changes: 3 additions & 0 deletions src/util/reader_mapping.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ class ReaderMapping final
bool get(const char* key, std::vector<std::string>& value, const std::optional<std::vector<std::string>>& default_value = std::nullopt) const;
bool get(const char* key, std::vector<unsigned int>& value, const std::optional<std::vector<unsigned int>>& default_value = std::nullopt) const;

// Reads vector by merging all negative values into "merge_value", repeated as much as the absolute value of the negative value.
bool get_merge(const char* key, std::vector<unsigned int>& value, unsigned int merge_value) const;

bool get(const char* key, std::optional<ReaderMapping>&) const;
bool get(const char* key, std::optional<ReaderCollection>&) const;

Expand Down
52 changes: 52 additions & 0 deletions src/util/writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,58 @@ Writer::write(const std::string& name, const sexp::Value& value)
*out << ")\n";
}

void
Writer::write_merge(const std::string& name, const std::vector<unsigned int>& value, unsigned int merge_value, int width)
{
indent();
*out << '(' << name;
if (width > 0)
{
*out << "\n";
indent();
}

int count = 0;
int merge_count = 0;
for (const auto& i : value)
{
const bool merge_value_match = (i == merge_value);
if (merge_value_match)
{
++merge_count;
}
else
{
if (merge_count)
{
*out << -merge_count << " ";
merge_count = 0;
}
*out << i;
}
++count;

if (width > 0 && count >= width)
{
count = 0;
if (merge_count)
{
*out << -merge_count;
merge_count = 0;
}

*out << "\n";
Vankata453 marked this conversation as resolved.
Show resolved Hide resolved
indent();
}
else if (!merge_value_match)
{
*out << " ";
}
}

*out << ")\n";
}

void
Writer::write_escaped_string(const std::string& str)
{
Expand Down
3 changes: 3 additions & 0 deletions src/util/writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ class Writer final
void write(const std::string& name, const sexp::Value& value);
// add more write-functions when needed...

// Writes vector by merging all occurences of "merge_value" into -{occurences}.
void write_merge(const std::string& name, const std::vector<unsigned int>& value, unsigned int merge_value, int width = 0);

void end_list(const std::string& listname);

private:
Expand Down
Loading