123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- #include "Chunk.h"
-
- #include <zlib.h>
- #include <stdint.h>
- #include <assert.h>
- #include <algorithm>
-
- #include "log.h"
- #include "Clock.h"
- #include "World.h"
- #include "Game.h"
-
- namespace Swan {
-
- void Chunk::compress(Cygnet::Renderer &rnd) {
- if (isCompressed())
- return;
-
- // We only need a fixed-length temp buffer;
- // if the compressed data gets too big, there's no point in compressing
- uint8_t dest[CHUNK_WIDTH * CHUNK_HEIGHT * sizeof(Tile::ID)];
-
- uLongf destlen = sizeof(dest);
- int ret = compress2(
- (Bytef *)dest, &destlen,
- (Bytef *)data_.get(), DATA_SIZE,
- Z_BEST_COMPRESSION);
-
- if (ret == Z_OK) {
- data_.reset(new uint8_t[destlen]);
- memcpy(data_.get(), dest, destlen);
-
- compressedSize_ = destlen;
-
- info
- << "Compressed chunk " << pos_ << " from "
- << DATA_SIZE << " bytes "
- << "to " << destlen << " bytes";
- } else if (ret == Z_BUF_ERROR) {
- info
- << "Didn't compress chunk " << pos_ << " "
- << "because compressing it would've made it bigger";
- } else {
- warn << "Chunk compression error: " << ret << " (Out of memory?)";
- }
-
- rnd.destroyChunk(renderChunk_);
- rnd.destroyChunkShadow(renderChunkShadow_);
- }
-
- void Chunk::decompress() {
- if (!isCompressed())
- return;
-
- auto dest = std::make_unique<uint8_t[]>(DATA_SIZE);
- uLongf destlen = DATA_SIZE;
- int ret = uncompress(
- dest.get(), &destlen,
- (Bytef *)data_.get(), compressedSize_);
-
- if (ret != Z_OK) {
- panic << "Decompressing chunk failed: " << ret;
- abort();
- }
-
- data_ = std::move(dest);
-
- info
- << "Decompressed chunk " << pos_ << " from "
- << compressedSize_ << " bytes to "
- << DATA_SIZE << " bytes.";
- compressedSize_ = -1;
-
- needChunkRender_ = true;
- }
-
- void Chunk::draw(const Context &ctx, Cygnet::Renderer &rnd) {
- if (isCompressed())
- return;
-
- if (needChunkRender_) {
- renderChunk_ = rnd.createChunk(getTileData());
- renderChunkShadow_ = rnd.createChunkShadow(getLightData());
- needChunkRender_ = false;
- needLightRender_ = false;
- } else {
- for (auto &change: changeList_) {
- rnd.modifyChunk(renderChunk_, change.first, change.second);
- }
- }
-
- if (needLightRender_) {
- rnd.modifyChunkShadow(renderChunkShadow_, getLightData());
- needLightRender_ = false;
- }
-
- Vec2 pos = (Vec2)pos_ * Vec2{CHUNK_WIDTH, CHUNK_HEIGHT};
- rnd.drawChunk(renderChunk_, pos);
- rnd.drawChunkShadow(renderChunkShadow_, pos);
- }
-
- Chunk::TickAction Chunk::tick(float dt) {
- assert(isActive());
-
- deactivateTimer_ -= dt;
- if (deactivateTimer_ <= 0) {
- if (isModified_)
- return TickAction::DEACTIVATE;
- else
- return TickAction::DELETE;
- }
-
- return TickAction::NOTHING;
- }
-
- void Chunk::keepActive() {
- deactivateTimer_ = DEACTIVATE_INTERVAL;
- decompress();
- }
-
- }
|