From 71cd0199fda68a84c5f9a5252bf63e69712b177b Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Wed, 27 Feb 2013 10:01:20 +0000 Subject: [PATCH] Made FAST_FLOOR_DIV work correctly, replaced all floorf() divisions with it. Still not perfect - chunk and region calculations can be made into a single CPU instruction - SAR - but not all compilers are known to support that (">>" operator on signed datatypes needs to perform arithmetic shift, C/C++ standard makes it implementation-specific; MSVC and GCC do what we need, LLVM unknown) git-svn-id: http://mc-server.googlecode.com/svn/trunk@1224 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/ChunkMap.cpp | 10 +++++----- source/ClientHandle.cpp | 4 ++-- source/Globals.h | 3 ++- source/WorldStorage/WSSAnvil.cpp | 5 +++-- source/WorldStorage/WSSCompact.cpp | 4 ++-- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/source/ChunkMap.cpp b/source/ChunkMap.cpp index 142a009f5..fd0d5892a 100644 --- a/source/ChunkMap.cpp +++ b/source/ChunkMap.cpp @@ -87,8 +87,8 @@ cChunkMap::cChunkLayer * cChunkMap::GetLayer(int a_LayerX, int a_LayerZ) cChunkMap::cChunkLayer * cChunkMap::FindLayerForChunk(int a_ChunkX, int a_ChunkZ) { - const int LayerX = (int)(floorf((float)a_ChunkX / (float)(LAYER_SIZE))); - const int LayerZ = (int)(floorf((float)a_ChunkZ / (float)(LAYER_SIZE))); + const int LayerX = FAST_FLOOR_DIV(a_ChunkX, LAYER_SIZE); + const int LayerZ = FAST_FLOOR_DIV(a_ChunkZ, LAYER_SIZE); return FindLayer(LayerX, LayerZ); } @@ -118,9 +118,9 @@ cChunkMap::cChunkLayer * cChunkMap::FindLayer(int a_LayerX, int a_LayerZ) cChunkMap::cChunkLayer * cChunkMap::GetLayerForChunk(int a_ChunkX, int a_ChunkZ) { - const int LayerX = (int)(floorf((float)a_ChunkX / (float)(LAYER_SIZE))); - const int LayerZ = (int)(floorf((float)a_ChunkZ / (float)(LAYER_SIZE))); - return GetLayer( LayerX, LayerZ ); + const int LayerX = FAST_FLOOR_DIV(a_ChunkX, LAYER_SIZE); + const int LayerZ = FAST_FLOOR_DIV(a_ChunkX, LAYER_SIZE); + return GetLayer(LayerX, LayerZ); } diff --git a/source/ClientHandle.cpp b/source/ClientHandle.cpp index 3bf46420e..e2a57d79e 100644 --- a/source/ClientHandle.cpp +++ b/source/ClientHandle.cpp @@ -276,8 +276,8 @@ void cClientHandle::StreamChunks(void) ASSERT(m_Player != NULL); - int ChunkPosX = FAST_FLOOR_DIV(m_Player->GetPosX(), cChunkDef::Width); - int ChunkPosZ = FAST_FLOOR_DIV(m_Player->GetPosZ(), cChunkDef::Width); + int ChunkPosX = FAST_FLOOR_DIV((int)m_Player->GetPosX(), cChunkDef::Width); + int ChunkPosZ = FAST_FLOOR_DIV((int)m_Player->GetPosZ(), cChunkDef::Width); if ((ChunkPosX == m_LastStreamedChunkX) && (ChunkPosZ == m_LastStreamedChunkZ)) { // Already streamed for this position diff --git a/source/Globals.h b/source/Globals.h index e536559dd..958c6d6ae 100644 --- a/source/Globals.h +++ b/source/Globals.h @@ -189,9 +189,10 @@ typedef unsigned short UInt16; /// Allows arithmetic expressions like "32 KiB" (but consider using parenthesis around it, "(32 KiB)" ) #define KiB * 1024 +#define MiB * 1024 * 1024 /// Faster than (int)floorf((float)x / (float)div) -#define FAST_FLOOR_DIV( x, div ) ( (x) < 0 ? (((int)x / div) - 1) : ((int)x / div) ) +#define FAST_FLOOR_DIV( x, div ) (((x) - (((x) < 0) ? ((div) - 1) : 0)) / (div)) // Own version of assert() that writes failed assertions to the log for review #ifdef _DEBUG diff --git a/source/WorldStorage/WSSAnvil.cpp b/source/WorldStorage/WSSAnvil.cpp index 1204db282..70e280a57 100644 --- a/source/WorldStorage/WSSAnvil.cpp +++ b/source/WorldStorage/WSSAnvil.cpp @@ -388,9 +388,10 @@ bool cWSSAnvil::SetChunkData(const cChunkCoords & a_Chunk, const AString & a_Dat cWSSAnvil::cMCAFile * cWSSAnvil::LoadMCAFile(const cChunkCoords & a_Chunk) { // ASSUME m_CS is locked + ASSERT(m_CS.IsLocked()); - const int RegionX = (int)(floorf((float)a_Chunk.m_ChunkX / 32.0f)); - const int RegionZ = (int)(floorf((float)a_Chunk.m_ChunkZ / 32.0f)); + const int RegionX = FAST_FLOOR_DIV(a_Chunk.m_ChunkX, 32); + const int RegionZ = FAST_FLOOR_DIV(a_Chunk.m_ChunkZ, 32); // Is it already cached? for (cMCAFiles::iterator itr = m_Files.begin(); itr != m_Files.end(); ++itr) diff --git a/source/WorldStorage/WSSCompact.cpp b/source/WorldStorage/WSSCompact.cpp index 87cf1d930..1d873add6 100644 --- a/source/WorldStorage/WSSCompact.cpp +++ b/source/WorldStorage/WSSCompact.cpp @@ -171,8 +171,8 @@ cWSSCompact::cPAKFile * cWSSCompact::LoadPAKFile(const cChunkCoords & a_Chunk) // ASSUMES that m_CS has been locked // We need to retain this weird conversion code, because some edge chunks are in the wrong PAK file - const int LayerX = (int)(floorf((float)a_Chunk.m_ChunkX / 32.0f)); - const int LayerZ = (int)(floorf((float)a_Chunk.m_ChunkZ / 32.0f)); + const int LayerX = FAST_FLOOR_DIV(a_Chunk.m_ChunkX, 32); + const int LayerZ = FAST_FLOOR_DIV(a_Chunk.m_ChunkZ, 32); // Is it already cached? for (cPAKFiles::iterator itr = m_PAKFiles.begin(); itr != m_PAKFiles.end(); ++itr)