From bea2edb2a9b3b3db6fd734f4e53a4d60eebc3272 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Tue, 28 Oct 2014 20:52:04 +0100 Subject: QtBiomeVisualiser: Reduced memory usage. --- Tools/QtBiomeVisualiser/BiomeView.cpp | 158 +++++++++++++++++++++++++++++---- Tools/QtBiomeVisualiser/BiomeView.h | 3 + Tools/QtBiomeVisualiser/QtChunk.cpp | 159 ++-------------------------------- Tools/QtBiomeVisualiser/QtChunk.h | 18 ++-- 4 files changed, 156 insertions(+), 182 deletions(-) diff --git a/Tools/QtBiomeVisualiser/BiomeView.cpp b/Tools/QtBiomeVisualiser/BiomeView.cpp index fef2b0afd..c77b39482 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.cpp +++ b/Tools/QtBiomeVisualiser/BiomeView.cpp @@ -14,6 +14,116 @@ static const int DELTA_STEP = 120; // The normal per-notch wheel delta +/** Map for converting biome values to colors. Initialized from biomeColors[]. */ +static uchar biomeToColor[256 * 4]; + +/** Map for converting biome values to colors. Used to initialize biomeToColor[].*/ +static struct +{ + EMCSBiome m_Biome; + uchar m_Color[3]; +} biomeColors[] = +{ + { biOcean, { 0x00, 0x00, 0x70 }, }, + { biPlains, { 0x8d, 0xb3, 0x60 }, }, + { biDesert, { 0xfa, 0x94, 0x18 }, }, + { biExtremeHills, { 0x60, 0x60, 0x60 }, }, + { biForest, { 0x05, 0x66, 0x21 }, }, + { biTaiga, { 0x0b, 0x66, 0x59 }, }, + { biSwampland, { 0x2f, 0xff, 0xda }, }, + { biRiver, { 0x30, 0x30, 0xaf }, }, + { biHell, { 0x7f, 0x00, 0x00 }, }, + { biSky, { 0x00, 0x7f, 0xff }, }, + { biFrozenOcean, { 0xa0, 0xa0, 0xdf }, }, + { biFrozenRiver, { 0xa0, 0xa0, 0xff }, }, + { biIcePlains, { 0xff, 0xff, 0xff }, }, + { biIceMountains, { 0xa0, 0xa0, 0xa0 }, }, + { biMushroomIsland, { 0xff, 0x00, 0xff }, }, + { biMushroomShore, { 0xa0, 0x00, 0xff }, }, + { biBeach, { 0xfa, 0xde, 0x55 }, }, + { biDesertHills, { 0xd2, 0x5f, 0x12 }, }, + { biForestHills, { 0x22, 0x55, 0x1c }, }, + { biTaigaHills, { 0x16, 0x39, 0x33 }, }, + { biExtremeHillsEdge, { 0x7f, 0x8f, 0x7f }, }, + { biJungle, { 0x53, 0x7b, 0x09 }, }, + { biJungleHills, { 0x2c, 0x42, 0x05 }, }, + + { biJungleEdge, { 0x62, 0x8b, 0x17 }, }, + { biDeepOcean, { 0x00, 0x00, 0x30 }, }, + { biStoneBeach, { 0xa2, 0xa2, 0x84 }, }, + { biColdBeach, { 0xfa, 0xf0, 0xc0 }, }, + { biBirchForest, { 0x30, 0x74, 0x44 }, }, + { biBirchForestHills, { 0x1f, 0x5f, 0x32 }, }, + { biRoofedForest, { 0x40, 0x51, 0x1a }, }, + { biColdTaiga, { 0x31, 0x55, 0x4a }, }, + { biColdTaigaHills, { 0x59, 0x7d, 0x72 }, }, + { biMegaTaiga, { 0x59, 0x66, 0x51 }, }, + { biMegaTaigaHills, { 0x59, 0x66, 0x59 }, }, + { biExtremeHillsPlus, { 0x50, 0x70, 0x50 }, }, + { biSavanna, { 0xbd, 0xb2, 0x5f }, }, + { biSavannaPlateau, { 0xa7, 0x9d, 0x64 }, }, + { biMesa, { 0xd9, 0x45, 0x15 }, }, + { biMesaPlateauF, { 0xb0, 0x97, 0x65 }, }, + { biMesaPlateau, { 0xca, 0x8c, 0x65 }, }, + + // M variants: + { biSunflowerPlains, { 0xb5, 0xdb, 0x88 }, }, + { biDesertM, { 0xff, 0xbc, 0x40 }, }, + { biExtremeHillsM, { 0x88, 0x88, 0x88 }, }, + { biFlowerForest, { 0x2d, 0x8e, 0x49 }, }, + { biTaigaM, { 0x33, 0x8e, 0x81 }, }, + { biSwamplandM, { 0x07, 0xf9, 0xb2 }, }, + { biIcePlainsSpikes, { 0xb4, 0xdc, 0xdc }, }, + { biJungleM, { 0x7b, 0xa3, 0x31 }, }, + { biJungleEdgeM, { 0x62, 0x8b, 0x17 }, }, + { biBirchForestM, { 0x58, 0x9c, 0x6c }, }, + { biBirchForestHillsM, { 0x47, 0x87, 0x5a }, }, + { biRoofedForestM, { 0x68, 0x79, 0x42 }, }, + { biColdTaigaM, { 0x24, 0x3f, 0x36 }, }, + { biMegaSpruceTaiga, { 0x45, 0x4f, 0x3e }, }, + { biMegaSpruceTaigaHills, { 0x45, 0x4f, 0x4e }, }, + { biExtremeHillsPlusM, { 0x78, 0x98, 0x78 }, }, + { biSavannaM, { 0xe5, 0xda, 0x87 }, }, + { biSavannaPlateauM, { 0xa7, 0x9d, 0x74 }, }, + { biMesaBryce, { 0xff, 0x6d, 0x3d }, }, + { biMesaPlateauFM, { 0xd8, 0xbf, 0x8d }, }, + { biMesaPlateauM, { 0xf2, 0xb4, 0x8d }, }, +} ; + + + + + +static class BiomeColorsInitializer +{ +public: + BiomeColorsInitializer(void) + { + // Reset all colors to gray: + for (size_t i = 0; i < ARRAYCOUNT(biomeToColor); i++) + { + biomeToColor[i] = 0x7f; + } + + // Set known biomes to their colors: + for (size_t i = 0; i < ARRAYCOUNT(biomeColors); i++) + { + uchar * color = &biomeToColor[4 * biomeColors[i].m_Biome]; + color[0] = biomeColors[i].m_Color[2]; + color[1] = biomeColors[i].m_Color[1]; + color[2] = biomeColors[i].m_Color[0]; + color[3] = 0xff; + } + } +} biomeColorInitializer; + + + + + +//////////////////////////////////////////////////////////////////////////////// +// BiomeView: + BiomeView::BiomeView(QWidget * parent) : super(parent), m_X(0), @@ -203,11 +313,10 @@ void BiomeView::drawChunk(int a_ChunkX, int a_ChunkZ) centerx += (a_ChunkX - centerchunkx) * chunksize; centery += (a_ChunkZ - centerchunkz) * chunksize; - int srcoffset = 0; uchar * bits = m_Image.bits(); int imgstride = m_Image.bytesPerLine(); - int skipx = 0,skipy = 0; + int skipx = 0, skipy = 0; int blockwidth = chunksize, blockheight = chunksize; // now if we're off the screen we need to crop if (centerx < 0) @@ -236,7 +345,7 @@ void BiomeView::drawChunk(int a_ChunkX, int a_ChunkZ) int imgoffset = centerx * 4 + centery * imgstride; // If the chunk is valid, use its data; otherwise use the empty placeholder: - const uchar * src = m_EmptyChunkImage; + const short * src = m_EmptyChunkBiomes; if (region.get() != nullptr) { int relChunkX = a_ChunkX - regionX * 32; @@ -244,27 +353,44 @@ void BiomeView::drawChunk(int a_ChunkX, int a_ChunkZ) Chunk & chunk = region->getRelChunk(relChunkX, relChunkZ); if (chunk.isValid()) { - src = chunk.getImage(); + src = chunk.getBiomes(); } } - // Blit or scale-blit the image: + // Scale-blit the image: for (int z = skipy; z < blockheight; z++, imgoffset += imgstride) { - srcoffset = floor((double)z / m_Zoom) * 16 * 4; - if (m_Zoom == 1.0) + size_t srcoffset = static_cast(std::floor((double)z / m_Zoom)) * 16; + int imgxoffset = imgoffset; + for (int x = skipx; x < blockwidth; x++) { - memcpy(bits + imgoffset, src + srcoffset + skipx * 4, (blockwidth - skipx) * 4); - } - else - { - int xofs = 0; - for (int x = skipx; x < blockwidth; x++, xofs +=4) + short biome = src[srcoffset + static_cast(std::floor((double)x / m_Zoom))]; + const uchar * color; + if (biome < 0) { - memcpy(bits + imgoffset + xofs, src + srcoffset + (int)floor((double)x / m_Zoom) * 4, 4); + static const uchar emptyBiome1[] = { 0x44, 0x44, 0x44, 0xff }; + static const uchar emptyBiome2[] = { 0x88, 0x88, 0x88, 0xff }; + color = ((x & 8) ^ (z & 8)) ? emptyBiome1 : emptyBiome2; } - } - } + else + { + if (biome * 4 >= ARRAYCOUNT(biomeToColor)) + { + static const uchar errorImage[] = { 0xff, 0x00, 0x00, 0xff }; + color = errorImage; + } + else + { + color = biomeToColor + biome * 4; + } + } + bits[imgxoffset] = color[0]; + bits[imgxoffset + 1] = color[1]; + bits[imgxoffset + 2] = color[2]; + bits[imgxoffset + 3] = color[3]; + imgxoffset += 4; + } // for x + } // for z } diff --git a/Tools/QtBiomeVisualiser/BiomeView.h b/Tools/QtBiomeVisualiser/BiomeView.h index 9901b8f24..cd9c7ead9 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.h +++ b/Tools/QtBiomeVisualiser/BiomeView.h @@ -79,6 +79,9 @@ protected: /** Data used for rendering a chunk that hasn't been loaded yet */ uchar m_EmptyChunkImage[16 * 16 * 4]; + /** Data placeholder for chunks that aren't valid. */ + short m_EmptyChunkBiomes[16 * 16]; + /** Draws the specified chunk into m_Image */ void drawChunk(int a_ChunkX, int a_ChunkZ); diff --git a/Tools/QtBiomeVisualiser/QtChunk.cpp b/Tools/QtBiomeVisualiser/QtChunk.cpp index 031aa3654..f201ef220 100644 --- a/Tools/QtBiomeVisualiser/QtChunk.cpp +++ b/Tools/QtBiomeVisualiser/QtChunk.cpp @@ -5,138 +5,6 @@ -/** Map for converting biome values to colors. Initialized from biomeColors[]. */ -static uchar biomeToColor[256 * 4]; - -/** Map for converting biome values to colors. Used to initialize biomeToColor[].*/ -static struct -{ - EMCSBiome m_Biome; - uchar m_Color[3]; -} biomeColors[] = -{ - { biOcean, { 0x00, 0x00, 0x70 }, }, - { biPlains, { 0x8d, 0xb3, 0x60 }, }, - { biDesert, { 0xfa, 0x94, 0x18 }, }, - { biExtremeHills, { 0x60, 0x60, 0x60 }, }, - { biForest, { 0x05, 0x66, 0x21 }, }, - { biTaiga, { 0x0b, 0x66, 0x59 }, }, - { biSwampland, { 0x2f, 0xff, 0xda }, }, - { biRiver, { 0x30, 0x30, 0xaf }, }, - { biHell, { 0x7f, 0x00, 0x00 }, }, - { biSky, { 0x00, 0x7f, 0xff }, }, - { biFrozenOcean, { 0xa0, 0xa0, 0xdf }, }, - { biFrozenRiver, { 0xa0, 0xa0, 0xff }, }, - { biIcePlains, { 0xff, 0xff, 0xff }, }, - { biIceMountains, { 0xa0, 0xa0, 0xa0 }, }, - { biMushroomIsland, { 0xff, 0x00, 0xff }, }, - { biMushroomShore, { 0xa0, 0x00, 0xff }, }, - { biBeach, { 0xfa, 0xde, 0x55 }, }, - { biDesertHills, { 0xd2, 0x5f, 0x12 }, }, - { biForestHills, { 0x22, 0x55, 0x1c }, }, - { biTaigaHills, { 0x16, 0x39, 0x33 }, }, - { biExtremeHillsEdge, { 0x7f, 0x8f, 0x7f }, }, - { biJungle, { 0x53, 0x7b, 0x09 }, }, - { biJungleHills, { 0x2c, 0x42, 0x05 }, }, - - { biJungleEdge, { 0x62, 0x8b, 0x17 }, }, - { biDeepOcean, { 0x00, 0x00, 0x30 }, }, - { biStoneBeach, { 0xa2, 0xa2, 0x84 }, }, - { biColdBeach, { 0xfa, 0xf0, 0xc0 }, }, - { biBirchForest, { 0x30, 0x74, 0x44 }, }, - { biBirchForestHills, { 0x1f, 0x5f, 0x32 }, }, - { biRoofedForest, { 0x40, 0x51, 0x1a }, }, - { biColdTaiga, { 0x31, 0x55, 0x4a }, }, - { biColdTaigaHills, { 0x59, 0x7d, 0x72 }, }, - { biMegaTaiga, { 0x59, 0x66, 0x51 }, }, - { biMegaTaigaHills, { 0x59, 0x66, 0x59 }, }, - { biExtremeHillsPlus, { 0x50, 0x70, 0x50 }, }, - { biSavanna, { 0xbd, 0xb2, 0x5f }, }, - { biSavannaPlateau, { 0xa7, 0x9d, 0x64 }, }, - { biMesa, { 0xd9, 0x45, 0x15 }, }, - { biMesaPlateauF, { 0xb0, 0x97, 0x65 }, }, - { biMesaPlateau, { 0xca, 0x8c, 0x65 }, }, - - // M variants: - { biSunflowerPlains, { 0xb5, 0xdb, 0x88 }, }, - { biDesertM, { 0xff, 0xbc, 0x40 }, }, - { biExtremeHillsM, { 0x88, 0x88, 0x88 }, }, - { biFlowerForest, { 0x2d, 0x8e, 0x49 }, }, - { biTaigaM, { 0x33, 0x8e, 0x81 }, }, - { biSwamplandM, { 0x07, 0xf9, 0xb2 }, }, - { biIcePlainsSpikes, { 0xb4, 0xdc, 0xdc }, }, - { biJungleM, { 0x7b, 0xa3, 0x31 }, }, - { biJungleEdgeM, { 0x62, 0x8b, 0x17 }, }, - { biBirchForestM, { 0x58, 0x9c, 0x6c }, }, - { biBirchForestHillsM, { 0x47, 0x87, 0x5a }, }, - { biRoofedForestM, { 0x68, 0x79, 0x42 }, }, - { biColdTaigaM, { 0x24, 0x3f, 0x36 }, }, - { biMegaSpruceTaiga, { 0x45, 0x4f, 0x3e }, }, - { biMegaSpruceTaigaHills, { 0x45, 0x4f, 0x4e }, }, - { biExtremeHillsPlusM, { 0x78, 0x98, 0x78 }, }, - { biSavannaM, { 0xe5, 0xda, 0x87 }, }, - { biSavannaPlateauM, { 0xa7, 0x9d, 0x74 }, }, - { biMesaBryce, { 0xff, 0x6d, 0x3d }, }, - { biMesaPlateauFM, { 0xd8, 0xbf, 0x8d }, }, - { biMesaPlateauM, { 0xf2, 0xb4, 0x8d }, }, -} ; - - - - - -static class BiomeColorsInitializer -{ -public: - BiomeColorsInitializer(void) - { - // Reset all colors to gray: - for (size_t i = 0; i < ARRAYCOUNT(biomeToColor); i++) - { - biomeToColor[i] = 0x7f; - } - - // Set known biomes to their colors: - for (size_t i = 0; i < ARRAYCOUNT(biomeColors); i++) - { - uchar * color = &biomeToColor[4 * biomeColors[i].m_Biome]; - color[0] = biomeColors[i].m_Color[2]; - color[1] = biomeColors[i].m_Color[1]; - color[2] = biomeColors[i].m_Color[0]; - color[3] = 0xff; - } - } -} biomeColorInitializer; - - - - - -/** Converts biomes in an array into the chunk image data. */ -static void biomesToImage(const cChunkDef::BiomeMap & a_Biomes, Chunk::Image & a_Image) -{ - // Make sure the two arrays are of the same size, compile-time. - // Note that a_Image is actually 4 items per pixel, so the array is 4 times bigger: - static const char Check1[4 * ARRAYCOUNT(a_Biomes) - ARRAYCOUNT(a_Image) + 1] = {}; - static const char Check2[ARRAYCOUNT(a_Image) - 4 * ARRAYCOUNT(a_Biomes) + 1] = {}; - - // Convert the biomes into color: - for (size_t i = 0; i < ARRAYCOUNT(a_Biomes); i++) - { - a_Image[4 * i + 0] = biomeToColor[4 * a_Biomes[i] + 0]; - a_Image[4 * i + 1] = biomeToColor[4 * a_Biomes[i] + 1]; - a_Image[4 * i + 2] = biomeToColor[4 * a_Biomes[i] + 2]; - a_Image[4 * i + 3] = biomeToColor[4 * a_Biomes[i] + 3]; - } -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// Chunk: - Chunk::Chunk() : m_IsValid(false) { @@ -146,20 +14,12 @@ Chunk::Chunk() : -const uchar * Chunk::getImage(void) const -{ - ASSERT(m_IsValid); - return m_Image; -} - - - - - void Chunk::setBiomes(const cChunkDef::BiomeMap & a_Biomes) { - memcpy(m_Biomes, a_Biomes, sizeof(m_Biomes)); - renderBiomes(); + for (size_t idx = 0; idx < ARRAYCOUNT(a_Biomes); ++idx) + { + m_Biomes[idx] = static_cast(a_Biomes[idx]); + } m_IsValid = true; } @@ -173,16 +33,7 @@ EMCSBiome Chunk::getBiome(int a_RelX, int a_RelZ) { return biInvalidBiome; } - return cChunkDef::GetBiome(m_Biomes, a_RelX, a_RelZ); -} - - - - - -void Chunk::renderBiomes() -{ - biomesToImage(m_Biomes, m_Image); + return static_cast(m_Biomes[a_RelX + 16 * a_RelZ]); } diff --git a/Tools/QtBiomeVisualiser/QtChunk.h b/Tools/QtBiomeVisualiser/QtChunk.h index 74321577a..d806d18bb 100644 --- a/Tools/QtBiomeVisualiser/QtChunk.h +++ b/Tools/QtBiomeVisualiser/QtChunk.h @@ -18,9 +18,6 @@ public: /** Returns true iff the chunk data is valid - loaded or generated. */ bool isValid(void) const { return m_IsValid; } - /** Returns the image of the chunk's biomes. Assumes that the chunk is valid. */ - const uchar * getImage(void) const; - /** Sets the biomes to m_Biomes and renders them into m_Image. */ void setBiomes(const cChunkDef::BiomeMap & a_Biomes); @@ -28,19 +25,16 @@ public: Coords must be valid inside this chunk. */ EMCSBiome getBiome(int a_RelX, int a_RelZ); + /** Returns the raw biome data for this chunk. */ + const short * getBiomes(void) const { return m_Biomes; } + protected: /** Flag that specifies if the chunk data is valid - loaded or generated. */ bool m_IsValid; - /** Cached rendered image of this chunk's biomes. Updated in render(). */ - Image m_Image; - - /** Biomes comprising the chunk, in the X + 16 * Z ordering. */ - cChunkDef::BiomeMap m_Biomes; - - - /** Renders biomes from m_Biomes into m_Image. */ - void renderBiomes(); + /** Biomes comprising the chunk, in the X + 16 * Z ordering. + Typed as short to save on memory, converted automatically when needed. */ + short m_Biomes[16 * 16]; }; typedef std::shared_ptr ChunkPtr; -- cgit v1.2.3