diff --git a/src/ChunkData.cpp b/src/ChunkData.cpp index 098f436f8..162803292 100644 --- a/src/ChunkData.cpp +++ b/src/ChunkData.cpp @@ -2,7 +2,235 @@ #include "Globals.h" #include "ChunkData.h" -cChunkData cChunkData::Copy() const +cChunkData::cChunkData() +#if __cplusplus < 201103L + // auto_ptr style interface for memory management + : IsOwner(true) +#endif +{ + memset(m_Sections, 0, sizeof(m_Sections)); +} + + +cChunkData::~cChunkData() +{ + #if __cplusplus < 201103L + // auto_ptr style interface for memory management + if (!IsOwner) + { + return; + } + #endif + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + if (m_Sections[i] == NULL) Free(m_Sections[i]);; + } +} + +#if __cplusplus < 201103L + // auto_ptr style interface for memory management + cChunkData::cChunkData(const cChunkData& other) : + IsOwner(true) + { + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + m_Sections[i] = other.m_Sections[i]; + } + other.IsOwner = false; + } + + cChunkData::cChunkData& operator=(const cChunkData& other) + { + if (&other != this) + { + if (IsOwner) + { + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + if (m_Sections[i]) Free(m_Sections[i]);; + } + } + IsOwner = true; + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + m_Sections[i] = other.m_Sections[i]; + } + other.IsOwner = false; + } + return *this; + + } +#else + // unique_ptr style interface for memory management + cChunkData::cChunkData(cChunkData&& other) + { + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + m_Sections[i] = other.m_Sections[i]; + other.m_Sections[i] = NULL; + } + } + + cChunkData::cChunkData& operator=(cChunkData&& other) + { + if (&other != this) + { + for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) + { + Free(m_Sections[i]);; + m_Sections[i] = other.m_Sections[i]; + other.m_Sections[i] = NULL; + } + } + return *this; + } +#endif + +BLOCKTYPE cChunkData::GetBlock(int a_X, int a_Y, int a_Z) const +{ + ASSERT((a_X >= 0) && (a_X < cChunkDef::Width)); + ASSERT((a_Y >= 0) && (a_Y < cChunkDef::Height)); + ASSERT((a_Z >= 0) && (a_Z < cChunkDef::Width)); + int Section = a_Y / CHUNK_SECTION_HEIGHT; + if (m_Sections[Section] != NULL) + { + int Index = cChunkDef::MakeIndexNoCheck(a_X, a_Y - (Section * CHUNK_SECTION_HEIGHT), a_Z); + return m_Sections[Section]->m_BlockTypes[Index]; + } + else + { + return 0; + } +} + +void cChunkData::SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Block) +{ + if ( + (a_RelX >= cChunkDef::Width) || (a_RelX < 0) || + (a_RelY >= cChunkDef::Height) || (a_RelY < 0) || + (a_RelZ >= cChunkDef::Width) || (a_RelZ < 0) + ) + { + ASSERT(!"cChunkData::SetMeta(): index out of range!"); + return; + } + + int Section = a_RelY / CHUNK_SECTION_HEIGHT; + if (m_Sections[Section] == NULL) + { + if (a_Block == 0x00) + { + return; + } + m_Sections[Section] = Allocate(); + if (m_Sections[Section] == NULL) + { + ASSERT(!"Failed to allocate a new section in Chunkbuffer"); + return; + } + ZeroSection(m_Sections[Section]); + } + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + m_Sections[Section]->m_BlockTypes[Index] = a_Block; +} + +NIBBLETYPE cChunkData::GetMeta(int a_RelX, int a_RelY, int a_RelZ) const +{ + if ( + (a_RelX < cChunkDef::Width) && (a_RelX > -1) && + (a_RelY < cChunkDef::Height) && (a_RelY > -1) && + (a_RelZ < cChunkDef::Width) && (a_RelZ > -1)) + { + int Section = a_RelY / CHUNK_SECTION_HEIGHT; + if (m_Sections[Section] != NULL) + { + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + return (m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4)) & 0x0f; + } + else + { + return 0; + } + } + ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!"); + return 0; +} + +bool cChunkData::SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble) +{ + if ( + (a_RelX >= cChunkDef::Width) || (a_RelX < 0) || + (a_RelY >= cChunkDef::Height) || (a_RelY < 0) || + (a_RelZ >= cChunkDef::Width) || (a_RelZ < 0) + ) + { + ASSERT(!"cChunkData::SetMeta(): index out of range!"); + return false; + } + + int Section = a_RelY / CHUNK_SECTION_HEIGHT; + if (m_Sections[Section] == NULL) + { + if ((a_Nibble & 0xf) == 0x00) + { + return false; + } + m_Sections[Section] = Allocate(); + if (m_Sections[Section] == NULL) + { + ASSERT(!"Failed to allocate a new section in Chunkbuffer"); + return false; + } + ZeroSection(m_Sections[Section]); + } + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + NIBBLETYPE oldval = m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4) & 0xf; + m_Sections[Section]->m_BlockMeta[Index / 2] = static_cast( + (m_Sections[Section]->m_BlockMeta[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble + ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set + ); + return oldval == a_Nibble; +} + +NIBBLETYPE cChunkData::GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const +{ + if ((a_RelX < cChunkDef::Width) && (a_RelX > -1) && (a_RelY < cChunkDef::Height) && (a_RelY > -1) && (a_RelZ < cChunkDef::Width) && (a_RelZ > -1)) + { + int Section = a_RelY / CHUNK_SECTION_HEIGHT; + if (m_Sections[Section] != NULL) + { + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; + } + else + { + return 0; + } + } + ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!"); + return 0; +} + +NIBBLETYPE cChunkData::GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const +{ + if ((a_RelX < cChunkDef::Width) && (a_RelX > -1) && (a_RelY < cChunkDef::Height) && (a_RelY > -1) && (a_RelZ < cChunkDef::Width) && (a_RelZ > -1)) + { + int Section = a_RelY / CHUNK_SECTION_HEIGHT; + if (m_Sections[Section] != NULL) + { + int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); + return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; + } + else + { + return 0xF; + } + } + ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!"); + return 0; +} + +cChunkData cChunkData::cChunkData::Copy() const { cChunkData copy; for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) diff --git a/src/ChunkData.h b/src/ChunkData.h index 5a149f95f..16fcc4d37 100644 --- a/src/ChunkData.h +++ b/src/ChunkData.h @@ -20,231 +20,28 @@ class cChunkData { public: - cChunkData() - #if __cplusplus < 201103L - // auto_ptr style interface for memory management - : IsOwner(true) - #endif - { - memset(m_Sections, 0, sizeof(m_Sections)); - } - ~cChunkData() - { - #if __cplusplus < 201103L - // auto_ptr style interface for memory management - if (!IsOwner) - { - return; - } - #endif - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) - { - if (m_Sections[i] == NULL) Free(m_Sections[i]);; - } - } + cChunkData(); + ~cChunkData(); #if __cplusplus < 201103L // auto_ptr style interface for memory management - cChunkData(const cChunkData& other) : - IsOwner(true) - { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) - { - m_Sections[i] = other.m_Sections[i]; - } - other.IsOwner = false; - } - - cChunkData& operator=(const cChunkData& other) - { - if (&other != this) - { - if (IsOwner) - { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) - { - if (m_Sections[i]) Free(m_Sections[i]);; - } - } - IsOwner = true; - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) - { - m_Sections[i] = other.m_Sections[i]; - } - other.IsOwner = false; - } - return *this; - - } + cChunkData(const cChunkData& other); + cChunkData& operator=(const cChunkData& other); #else // unique_ptr style interface for memory management - cChunkData(cChunkData&& other) - { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) - { - m_Sections[i] = other.m_Sections[i]; - other.m_Sections[i] = NULL; - } - } - - cChunkData& operator=(cChunkData&& other) - { - if (&other != this) - { - for (size_t i = 0; i < CHUNK_SECTION_COUNT; i++) - { - Free(m_Sections[i]);; - m_Sections[i] = other.m_Sections[i]; - other.m_Sections[i] = NULL; - } - } - return *this; - } + cChunkData(cChunkData&& other); + cChunkData& operator=(cChunkData&& other); #endif - BLOCKTYPE GetBlock(int a_X, int a_Y, int a_Z) const - { - ASSERT((a_X >= 0) && (a_X < cChunkDef::Width)); - ASSERT((a_Y >= 0) && (a_Y < cChunkDef::Height)); - ASSERT((a_Z >= 0) && (a_Z < cChunkDef::Width)); - int Section = a_Y / CHUNK_SECTION_HEIGHT; - if (m_Sections[Section] != NULL) - { - int Index = cChunkDef::MakeIndexNoCheck(a_X, a_Y - (Section * CHUNK_SECTION_HEIGHT), a_Z); - return m_Sections[Section]->m_BlockTypes[Index]; - } - else - { - return 0; - } - } - - void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Block) - { - if ( - (a_RelX >= cChunkDef::Width) || (a_RelX < 0) || - (a_RelY >= cChunkDef::Height) || (a_RelY < 0) || - (a_RelZ >= cChunkDef::Width) || (a_RelZ < 0) - ) - { - ASSERT(!"cChunkData::SetMeta(): index out of range!"); - return; - } + BLOCKTYPE GetBlock(int a_X, int a_Y, int a_Z) const; + void SetBlock(int a_RelX, int a_RelY, int a_RelZ, BLOCKTYPE a_Block); - int Section = a_RelY / CHUNK_SECTION_HEIGHT; - if (m_Sections[Section] == NULL) - { - if (a_Block == 0x00) - { - return; - } - m_Sections[Section] = Allocate(); - if (m_Sections[Section] == NULL) - { - ASSERT(!"Failed to allocate a new section in Chunkbuffer"); - return; - } - ZeroSection(m_Sections[Section]); - } - int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); - m_Sections[Section]->m_BlockTypes[Index] = a_Block; - } - - NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const - { - if ( - (a_RelX < cChunkDef::Width) && (a_RelX > -1) && - (a_RelY < cChunkDef::Height) && (a_RelY > -1) && - (a_RelZ < cChunkDef::Width) && (a_RelZ > -1)) - { - int Section = a_RelY / CHUNK_SECTION_HEIGHT; - if (m_Sections[Section] != NULL) - { - int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); - return (m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4)) & 0x0f; - } - else - { - return 0; - } - } - ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!"); - return 0; - } + NIBBLETYPE GetMeta(int a_RelX, int a_RelY, int a_RelZ) const; + bool SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble); - bool SetMeta(int a_RelX, int a_RelY, int a_RelZ, NIBBLETYPE a_Nibble) - { - if ( - (a_RelX >= cChunkDef::Width) || (a_RelX < 0) || - (a_RelY >= cChunkDef::Height) || (a_RelY < 0) || - (a_RelZ >= cChunkDef::Width) || (a_RelZ < 0) - ) - { - ASSERT(!"cChunkData::SetMeta(): index out of range!"); - return false; - } - - int Section = a_RelY / CHUNK_SECTION_HEIGHT; - if (m_Sections[Section] == NULL) - { - if ((a_Nibble & 0xf) == 0x00) - { - return false; - } - m_Sections[Section] = Allocate(); - if (m_Sections[Section] == NULL) - { - ASSERT(!"Failed to allocate a new section in Chunkbuffer"); - return false; - } - ZeroSection(m_Sections[Section]); - } - int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); - NIBBLETYPE oldval = m_Sections[Section]->m_BlockMeta[Index / 2] >> ((Index & 1) * 4) & 0xf; - m_Sections[Section]->m_BlockMeta[Index / 2] = static_cast( - (m_Sections[Section]->m_BlockMeta[Index / 2] & (0xf0 >> ((Index & 1) * 4))) | // The untouched nibble - ((a_Nibble & 0x0f) << ((Index & 1) * 4)) // The nibble being set - ); - return oldval == a_Nibble; - } + NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const; - NIBBLETYPE GetBlockLight(int a_RelX, int a_RelY, int a_RelZ) const - { - if ((a_RelX < cChunkDef::Width) && (a_RelX > -1) && (a_RelY < cChunkDef::Height) && (a_RelY > -1) && (a_RelZ < cChunkDef::Width) && (a_RelZ > -1)) - { - int Section = a_RelY / CHUNK_SECTION_HEIGHT; - if (m_Sections[Section] != NULL) - { - int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); - return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; - } - else - { - return 0; - } - } - ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!"); - return 0; - } - - NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const - { - if ((a_RelX < cChunkDef::Width) && (a_RelX > -1) && (a_RelY < cChunkDef::Height) && (a_RelY > -1) && (a_RelZ < cChunkDef::Width) && (a_RelZ > -1)) - { - int Section = a_RelY / CHUNK_SECTION_HEIGHT; - if (m_Sections[Section] != NULL) - { - int Index = cChunkDef::MakeIndexNoCheck(a_RelX, a_RelY - (Section * CHUNK_SECTION_HEIGHT), a_RelZ); - return (m_Sections[Section]->m_BlockLight[Index / 2] >> ((Index & 1) * 4)) & 0x0f; - } - else - { - return 0xF; - } - } - ASSERT(!"cChunkData::GetMeta(): coords out of chunk range!"); - return 0; - } + NIBBLETYPE GetSkyLight(int a_RelX, int a_RelY, int a_RelZ) const; cChunkData Copy() const; void CopyBlocks (BLOCKTYPE * a_dest, size_t a_Idx = 0, size_t length = cChunkDef::NumBlocks) const;