game: compress delta heights for fast extra compression

This commit is contained in:
Crypto City 2021-09-06 19:04:05 +00:00
parent 7223212520
commit 8761724ac8

View File

@ -75,6 +75,19 @@ void SetTerrainCacheDirectory(const std::string &dir)
cache_dir = dir;
}
static std::shared_ptr<int16_t[]> encode_deltas(const std::shared_ptr<uint16_t[]> &data, size_t tiles)
{
uint16_t prev = 0;
std::shared_ptr<int16_t[]> deltas(new int16_t[tiles]);
for (size_t i = 0; i < tiles; ++i)
{
const uint16_t value = data[i];
deltas[i] = (int32_t)(value - prev);
prev = value;
}
return deltas;
}
void SetCachedTerrain(const std::string &tag, const std::shared_ptr<uint16_t[]> &data_ref, size_t tiles)
{
std::shared_ptr<uint16_t[]> data = data_ref;
@ -83,9 +96,10 @@ void SetCachedTerrain(const std::string &tag, const std::shared_ptr<uint16_t[]>
{
boost::system::error_code ec;
prune_terrain_files();
const std::shared_ptr<int16_t[]> deltas(encode_deltas(data, tiles));
const unsigned max_bytes = Urho3D::EstimateCompressBound(tiles * 2);
std::unique_ptr<uint8_t[]> buf(new uint8_t[max_bytes]);
const unsigned bytes = Urho3D::CompressData(buf.get(), data.get(), tiles * 2, COMPRESSION_RATIO);
const unsigned bytes = Urho3D::CompressData(buf.get(), deltas.get(), tiles * 2, COMPRESSION_RATIO);
const std::string tmp_filename = filename + ".tmp";
if (epee::file_io_utils::save_string_to_file(tmp_filename, std::string((const char*)buf.get(), bytes)))
{
@ -100,10 +114,24 @@ void SetCachedTerrain(const std::string &tag, const std::shared_ptr<uint16_t[]>
});
}
static std::shared_ptr<uint16_t[]> decode_deltas(const std::shared_ptr<int16_t[]> &deltas, size_t tiles)
{
uint16_t prev = 0;
std::shared_ptr<uint16_t[]> data(new uint16_t[tiles]);
for (size_t i = 0; i < tiles; ++i)
{
const uint16_t value = prev + deltas[i];
data[i] = value;
prev = value;
}
return data;
}
std::shared_ptr<uint16_t[]> GetCachedTerrain(const std::string &tag, size_t tiles)
{
const std::string filename = get_filename_for_tag(tag);
boost::system::error_code ec;
std::shared_ptr<int16_t[]> deltas;
std::shared_ptr<uint16_t[]> data;
std::string s;
uint64_t sz = 0;
@ -117,9 +145,9 @@ std::shared_ptr<uint16_t[]> GetCachedTerrain(const std::string &tag, size_t tile
if (!epee::file_io_utils::load_file_to_string(filename, s))
goto kill;
data.reset(new uint16_t[tiles]);
Urho3D::DecompressData(data.get(), tiles * 2, s.data(), s.size());
return data;
deltas.reset(new int16_t[tiles]);
Urho3D::DecompressData(deltas.get(), tiles * 2, s.data(), s.size());
return decode_deltas(deltas, tiles);
kill:
boost::filesystem::remove(filename, ec);