diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Chunk.cpp | 12 | ||||
-rw-r--r-- | src/Chunk.h | 8 | ||||
-rw-r--r-- | src/ChunkDef.h | 65 |
3 files changed, 52 insertions, 33 deletions
diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 97a8ba88b..652f56905 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -241,21 +241,21 @@ void cChunk::GetAllData(cChunkDataCallback & a_Callback) a_Callback.HeightMap (&m_HeightMap); a_Callback.BiomeData (&m_BiomeMap); - std::vector<BLOCKTYPE> Blocks = m_BlockTypes; + COMPRESSED_BLOCKTYPE Blocks = m_BlockTypes; Blocks.resize(NumBlocks); a_Callback.BlockTypes (&Blocks[0]); - std::vector<NIBBLETYPE> Metas = m_BlockMeta; + COMPRESSED_NIBBLETYPE Metas = m_BlockMeta; Metas.resize(NumBlocks / 2); a_Callback.BlockMeta (&Metas[0]); a_Callback.LightIsValid (m_IsLightValid); - std::vector<NIBBLETYPE> BlockLights = m_BlockLight; + COMPRESSED_NIBBLETYPE BlockLights = m_BlockLight; BlockLights.resize(NumBlocks / 2); a_Callback.BlockLight (&BlockLights[0]); - std::vector<NIBBLETYPE> BlockSkyLights = m_BlockSkyLight; + COMPRESSED_NIBBLETYPE BlockSkyLights = m_BlockSkyLight; BlockSkyLights.resize(NumBlocks / 2, 0xff); a_Callback.BlockSkyLight(&BlockSkyLights[0]); @@ -1579,7 +1579,7 @@ void cChunk::FastSetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_BlockT MarkDirty(); - if (m_BlockTypes.empty() || ((size_t)index >= m_BlockTypes.size())) + if ((size_t)index >= m_BlockTypes.size()) { m_BlockTypes.resize(index + 1); } @@ -2524,7 +2524,7 @@ BLOCKTYPE cChunk::GetBlock(int a_BlockIdx) const return 0; } - if (m_BlockTypes.empty() || ((size_t)a_BlockIdx >= m_BlockTypes.size())) + if ((size_t)a_BlockIdx >= m_BlockTypes.size()) { return E_BLOCK_AIR; } diff --git a/src/Chunk.h b/src/Chunk.h index 9100eec58..a9c9be861 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -421,10 +421,10 @@ private: cChunkMap * m_ChunkMap; // TODO: Make these pointers and don't allocate what isn't needed - std::vector<BLOCKTYPE> m_BlockTypes; - std::vector<NIBBLETYPE> m_BlockMeta; - std::vector<NIBBLETYPE> m_BlockLight; - std::vector<NIBBLETYPE> m_BlockSkyLight; + COMPRESSED_BLOCKTYPE m_BlockTypes; + COMPRESSED_NIBBLETYPE m_BlockMeta; + COMPRESSED_NIBBLETYPE m_BlockLight; + COMPRESSED_NIBBLETYPE m_BlockSkyLight; cChunkDef::HeightMap m_HeightMap; cChunkDef::BiomeMap m_BiomeMap; diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 1b3dd3ee0..054168bdd 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -77,13 +77,19 @@ public: idx = x + Width * z // Need to verify this with the protocol spec, currently unknown! */ typedef EMCSBiome BiomeMap[Width * Width]; - + /// The type used for block type operations and storage, AXIS_ORDER ordering typedef BLOCKTYPE BlockTypes[NumBlocks]; - + /// The type used for block data in nibble format, AXIS_ORDER ordering typedef NIBBLETYPE BlockNibbles[NumBlocks / 2]; + /** The storage wrapper used for compressed blockdata residing in RAMz */ + typedef std::vector<BLOCKTYPE> COMPRESSED_BLOCKTYPE; + + /** The storage wrapper used for compressed nibbledata residing in RAMz */ + typedef std::vector<NIBBLETYPE> COMPRESSED_NIBBLETYPE; + /// Converts absolute block coords into relative (chunk + block) coords: inline static void AbsoluteToRelative(/* in-out */ int & a_X, int & a_Y, int & a_Z, /* out */ int & a_ChunkX, int & a_ChunkZ ) @@ -221,11 +227,11 @@ public: } - static NIBBLETYPE GetNibble(const std::vector<NIBBLETYPE> & a_Buffer, int a_BlockIdx, bool a_IsSkyLightNibble = false) + static NIBBLETYPE GetNibble(const COMPRESSED_NIBBLETYPE & a_Buffer, int a_BlockIdx, bool a_IsSkyLightNibble = false) { if ((a_BlockIdx > -1) && (a_BlockIdx < NumBlocks)) { - if (a_Buffer.empty() || ((size_t)(a_BlockIdx / 2) >= a_Buffer.size())) + if ((size_t)(a_BlockIdx / 2) >= a_Buffer.size()) { return (a_IsSkyLightNibble ? 0xff : 0); } @@ -236,16 +242,16 @@ public: } - static NIBBLETYPE GetNibble(const std::vector<NIBBLETYPE> & a_Buffer, int x, int y, int z, bool a_IsSkyLightNibble = false) + static NIBBLETYPE GetNibble(const COMPRESSED_NIBBLETYPE & a_Buffer, int x, int y, int z, bool a_IsSkyLightNibble = false) { if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1)) { int Index = MakeIndexNoCheck(x, y, z); - if (a_Buffer.empty() || ((size_t)(Index / 2) >= a_Buffer.size())) + if ((size_t)(Index / 2) >= a_Buffer.size()) { return (a_IsSkyLightNibble ? 0xff : 0); } - return (a_Buffer[(size_t)(Index / 2)] >> ((Index & 1) * 4)) & 0x0f; + return ExpandNibble(a_Buffer, Index); } ASSERT(!"cChunkDef::GetNibble(): coords out of chunk range!"); return 0; @@ -257,54 +263,67 @@ public: if ((x < Width) && (x > -1) && (y < Height) && (y > -1) && (z < Width) && (z > -1)) { int Index = MakeIndexNoCheck(x, y, z); - return (a_Buffer[Index / 2] >> ((Index & 1) * 4)) & 0x0f; + return (a_Buffer[(size_t)(Index / 2)] >> ((Index & 1) * 4)) & 0x0f; } ASSERT(!"cChunkDef::GetNibble(): coords out of chunk range!"); return 0; } - static void SetNibble(std::vector<NIBBLETYPE> & a_Buffer, int a_BlockIdx, NIBBLETYPE a_Nibble) + static void SetNibble(COMPRESSED_NIBBLETYPE & a_Buffer, int a_BlockIdx, NIBBLETYPE a_Nibble) { if ((a_BlockIdx < 0) || (a_BlockIdx >= NumBlocks)) { ASSERT(!"cChunkDef::SetNibble(): index out of range!"); return; } - if (a_Buffer.empty() || ((size_t)(a_BlockIdx / 2) >= a_Buffer.size())) + if ((size_t)(a_BlockIdx / 2) >= a_Buffer.size()) { a_Buffer.resize((size_t)((a_BlockIdx / 2) + 1)); } - a_Buffer[(size_t)(a_BlockIdx / 2)] = static_cast<NIBBLETYPE>( - (a_Buffer[a_BlockIdx / 2] & (0xf0 >> ((a_BlockIdx & 1) * 4))) | // The untouched nibble - ((a_Nibble & 0x0f) << ((a_BlockIdx & 1) * 4)) // The nibble being set - ); + a_Buffer[(size_t)(a_BlockIdx / 2)] = PackNibble(a_Buffer, a_BlockIdx, a_Nibble); } - static void SetNibble(std::vector<NIBBLETYPE> & a_Buffer, int x, int y, int z, NIBBLETYPE a_Nibble) + static void SetNibble(COMPRESSED_NIBBLETYPE & a_Buffer, int x, int y, int z, NIBBLETYPE a_Nibble) { if ( - (x >= Width) || (x < 0) || + (x >= Width) || (x < 0) || (y >= Height) || (y < 0) || - (z >= Width) || (z < 0) - ) + (z >= Width) || (z < 0) + ) { ASSERT(!"cChunkDef::SetNibble(): index out of range!"); return; } int Index = MakeIndexNoCheck(x, y, z); - if (a_Buffer.empty() || ((size_t)(Index / 2) >= a_Buffer.size())) + if ((size_t)(Index / 2) >= a_Buffer.size()) { a_Buffer.resize((size_t)((Index / 2) + 1)); } - a_Buffer[(size_t)(Index / 2)] = static_cast<NIBBLETYPE>( - (a_Buffer[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble - ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set - ); + a_Buffer[(size_t)(Index / 2)] = PackNibble(a_Buffer, Index, a_Nibble); + } + + +private: + + + inline static NIBBLETYPE PackNibble(const COMPRESSED_NIBBLETYPE & a_Buffer, int a_Index, NIBBLETYPE a_Nibble) + { + return static_cast<NIBBLETYPE>( + (a_Buffer[a_Index / 2] & (0xf0 >> ((a_Index & 1) * 4))) | // The untouched nibble + ((a_Nibble & 0x0f) << ((a_Index & 1) * 4)) // The nibble being set + ); } + + inline static NIBBLETYPE ExpandNibble(const COMPRESSED_NIBBLETYPE & a_Buffer, int a_Index) + { + return (a_Buffer[a_Index / 2] >> ((a_Index & 1) * 4)) & 0x0f; + } + + } ; |