summaryrefslogtreecommitdiffstats
path: root/Tools/AnvilStats/HeightMap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/AnvilStats/HeightMap.cpp')
-rw-r--r--Tools/AnvilStats/HeightMap.cpp530
1 files changed, 265 insertions, 265 deletions
diff --git a/Tools/AnvilStats/HeightMap.cpp b/Tools/AnvilStats/HeightMap.cpp
index 9f52c2109..662ddf493 100644
--- a/Tools/AnvilStats/HeightMap.cpp
+++ b/Tools/AnvilStats/HeightMap.cpp
@@ -1,265 +1,265 @@
-
-// HeightMap.cpp
-
-// Implements the cHeightMap class representing a cCallback descendant that draws a B&W map of heights for the world
-
-#include "Globals.h"
-#include "HeightMap.h"
-
-
-
-
-static const unsigned char g_BMPHeader[] =
-{
- 0x42, 0x4D, 0x36, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-} ;
-
-
-
-
-
-cHeightMap::cHeightMap(void) :
- m_CurrentRegionX(0),
- m_CurrentRegionZ(0),
- m_IsCurrentRegionValid(false)
-{
-}
-
-
-
-
-
-void cHeightMap::Finish(void)
-{
- if (m_IsCurrentRegionValid)
- {
- StartNewRegion(0, 0);
- }
-}
-
-
-
-
-
-bool cHeightMap::OnNewChunk(int a_ChunkX, int a_ChunkZ)
-{
- int RegionX = (a_ChunkX < 0) ? (a_ChunkX - 31) / 32 : a_ChunkX / 32;
- int RegionZ = (a_ChunkZ < 0) ? (a_ChunkZ - 31) / 32 : a_ChunkZ / 32;
- if ((RegionX != m_CurrentRegionX) || (RegionZ != m_CurrentRegionZ))
- {
- if (m_IsCurrentRegionValid)
- {
- StartNewRegion(RegionX, RegionZ);
- }
- m_CurrentRegionX = RegionX;
- m_CurrentRegionZ = RegionZ;
- }
- m_IsCurrentRegionValid = true;
- m_CurrentChunkX = a_ChunkX;
- m_CurrentChunkZ = a_ChunkZ;
- m_CurrentChunkOffX = m_CurrentChunkX - m_CurrentRegionX * 32;
- m_CurrentChunkOffZ = m_CurrentChunkZ - m_CurrentRegionZ * 32;
- memset(m_BlockTypes, 0, sizeof(m_BlockTypes));
- return false;
-}
-
-
-
-
-
-bool cHeightMap::OnHeightMap(const int * a_HeightMapBE)
-{
- ASSERT(m_CurrentChunkOffX >= 0);
- ASSERT(m_CurrentChunkOffX < 32);
- ASSERT(m_CurrentChunkOffZ >= 0);
- ASSERT(m_CurrentChunkOffZ < 32);
- int * BaseHeight = m_Height + m_CurrentChunkOffZ * 16 * 512 + m_CurrentChunkOffX * 16;
- for (int z = 0; z < 16; z++)
- {
- int * Row = BaseHeight + z * 512;
- for (int x = 0; x < 16; x++)
- {
- Row[x] = ntohl(a_HeightMapBE[z * 16 + x]);
- }
- } // for z
- return false; // Still want blockdata to remove trees from the heightmap
-}
-
-
-
-
-
-bool cHeightMap::OnSection(
- unsigned char a_Y,
- const BLOCKTYPE * a_BlockTypes,
- const NIBBLETYPE * a_BlockAdditional,
- const NIBBLETYPE * a_BlockMeta,
- const NIBBLETYPE * a_BlockLight,
- const NIBBLETYPE * a_BlockSkyLight
-)
-{
- // Copy the section data into the appropriate place in the internal buffer
- memcpy(m_BlockTypes + a_Y * 16 * 16 * 16, a_BlockTypes, 16 * 16 * 16);
- return false;
-}
-
-
-
-
-
-bool cHeightMap::OnSectionsFinished(void)
-{
- // Remove trees from the heightmap:
- for (int z = 0; z < 16; z++)
- {
- for (int x = 0; x < 16; x++)
- {
- for (int y = m_Height[512 * (16 * m_CurrentChunkOffZ + z) + 16 * m_CurrentChunkOffX + x]; y >= 0; y--)
- {
- if (IsGround(m_BlockTypes[256 * y + 16 * z + x]))
- {
- m_Height[512 * (16 * m_CurrentChunkOffZ + z) + 16 * m_CurrentChunkOffX + x] = y;
- break; // for y
- }
- } // for y
- } // for x
- } // for z
- return true;
-}
-
-
-
-
-
-void cHeightMap::StartNewRegion(int a_RegionX, int a_RegionZ)
-{
- AString FileName;
- Printf(FileName, "Height.%d.%d.bmp", m_CurrentRegionX, m_CurrentRegionZ);
- cFile f;
- if (!f.Open(FileName, cFile::fmWrite))
- {
- LOG("Cannot open file \"%s\" for writing the height map. Data for this region lost.", FileName.c_str());
- }
- else
- {
- f.Write(g_BMPHeader, sizeof(g_BMPHeader));
- for (int z = 0; z < 512; z++)
- {
- int RowData[512];
- int * HeightRow = m_Height + z * 512;
- for (int x = 0; x < 512; x++)
- {
- RowData[x] = std::max(std::min(HeightRow[x], 255), 0) * 0x010101;
- }
- f.Write(RowData, sizeof(RowData));
- } // for z
- }
-
- memset(m_Height, 0, sizeof(m_Height));
- m_CurrentRegionX = a_RegionX;
- m_CurrentRegionZ = a_RegionZ;
-}
-
-
-
-
-
-bool cHeightMap::IsGround(BLOCKTYPE a_BlockType)
-{
- // Name all blocks that are NOT ground, return false for them:
- switch (a_BlockType)
- {
- case E_BLOCK_AIR:
- case E_BLOCK_BED:
- case E_BLOCK_BREWING_STAND:
- case E_BLOCK_BROWN_MUSHROOM:
- case E_BLOCK_CACTUS:
- case E_BLOCK_CAKE:
- case E_BLOCK_CARROTS:
- case E_BLOCK_CAULDRON:
- case E_BLOCK_CHEST:
- case E_BLOCK_COBBLESTONE_WALL:
- case E_BLOCK_COBWEB:
- case E_BLOCK_COCOA_POD:
- case E_BLOCK_CROPS:
- case E_BLOCK_DEAD_BUSH:
- case E_BLOCK_DETECTOR_RAIL:
- case E_BLOCK_DIRT:
- case E_BLOCK_DRAGON_EGG:
- case E_BLOCK_END_PORTAL:
- case E_BLOCK_ENDER_CHEST:
- case E_BLOCK_FENCE:
- case E_BLOCK_FENCE_GATE:
- case E_BLOCK_FIRE:
- case E_BLOCK_FLOWER_POT:
- case E_BLOCK_HEAD:
- case E_BLOCK_IRON_BARS:
- case E_BLOCK_LADDER:
- case E_BLOCK_LAVA:
- case E_BLOCK_LEAVES:
- case E_BLOCK_LEVER:
- case E_BLOCK_LILY_PAD:
- case E_BLOCK_LOG: // NOTE: This block is actually solid, but we don't want it because it's the thing that trees are made of, and we're getting rid of trees
- case E_BLOCK_MELON:
- case E_BLOCK_MELON_STEM:
- case E_BLOCK_NETHER_BRICK_FENCE:
- case E_BLOCK_NETHER_PORTAL:
- case E_BLOCK_POWERED_RAIL:
- case E_BLOCK_PUMPKIN:
- case E_BLOCK_PUMPKIN_STEM:
- case E_BLOCK_RAIL:
- case E_BLOCK_RED_ROSE:
- case E_BLOCK_RED_MUSHROOM:
- case E_BLOCK_REDSTONE_REPEATER_OFF:
- case E_BLOCK_REDSTONE_REPEATER_ON:
- case E_BLOCK_REDSTONE_TORCH_OFF:
- case E_BLOCK_REDSTONE_TORCH_ON:
- case E_BLOCK_REDSTONE_WIRE:
- case E_BLOCK_REEDS:
- case E_BLOCK_SAPLING:
- case E_BLOCK_SIGN_POST:
- case E_BLOCK_SNOW:
- case E_BLOCK_STATIONARY_LAVA:
- case E_BLOCK_STATIONARY_WATER:
- case E_BLOCK_STONE_BUTTON:
- case E_BLOCK_STONE_PRESSURE_PLATE:
- case E_BLOCK_TALL_GRASS:
- case E_BLOCK_TORCH:
- case E_BLOCK_TRIPWIRE:
- case E_BLOCK_TRIPWIRE_HOOK:
- case E_BLOCK_VINES:
- case E_BLOCK_WALLSIGN:
- case E_BLOCK_WATER:
- case E_BLOCK_WOODEN_BUTTON:
- case E_BLOCK_WOODEN_PRESSURE_PLATE:
- case E_BLOCK_YELLOW_FLOWER:
- {
- return false;
- }
- }
- return true;
-}
-
-
-
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-// cHeightMapFactory:
-
-cHeightMapFactory::~cHeightMapFactory()
-{
- // Force all threads to save their last regions:
- for (cCallbacks::iterator itr = m_Callbacks.begin(), end = m_Callbacks.end(); itr != end; ++itr)
- {
- ((cHeightMap *)(*itr))->Finish();
- }
- // TODO: Join all the files into one giant image file
-}
-
-
-
-
+
+// HeightMap.cpp
+
+// Implements the cHeightMap class representing a cCallback descendant that draws a B&W map of heights for the world
+
+#include "Globals.h"
+#include "HeightMap.h"
+
+
+
+
+static const unsigned char g_BMPHeader[] =
+{
+ 0x42, 0x4D, 0x36, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x13, 0x0B, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+} ;
+
+
+
+
+
+cHeightMap::cHeightMap(void) :
+ m_CurrentRegionX(0),
+ m_CurrentRegionZ(0),
+ m_IsCurrentRegionValid(false)
+{
+}
+
+
+
+
+
+void cHeightMap::Finish(void)
+{
+ if (m_IsCurrentRegionValid)
+ {
+ StartNewRegion(0, 0);
+ }
+}
+
+
+
+
+
+bool cHeightMap::OnNewChunk(int a_ChunkX, int a_ChunkZ)
+{
+ int RegionX = (a_ChunkX < 0) ? (a_ChunkX - 31) / 32 : a_ChunkX / 32;
+ int RegionZ = (a_ChunkZ < 0) ? (a_ChunkZ - 31) / 32 : a_ChunkZ / 32;
+ if ((RegionX != m_CurrentRegionX) || (RegionZ != m_CurrentRegionZ))
+ {
+ if (m_IsCurrentRegionValid)
+ {
+ StartNewRegion(RegionX, RegionZ);
+ }
+ m_CurrentRegionX = RegionX;
+ m_CurrentRegionZ = RegionZ;
+ }
+ m_IsCurrentRegionValid = true;
+ m_CurrentChunkX = a_ChunkX;
+ m_CurrentChunkZ = a_ChunkZ;
+ m_CurrentChunkOffX = m_CurrentChunkX - m_CurrentRegionX * 32;
+ m_CurrentChunkOffZ = m_CurrentChunkZ - m_CurrentRegionZ * 32;
+ memset(m_BlockTypes, 0, sizeof(m_BlockTypes));
+ return false;
+}
+
+
+
+
+
+bool cHeightMap::OnHeightMap(const int * a_HeightMapBE)
+{
+ ASSERT(m_CurrentChunkOffX >= 0);
+ ASSERT(m_CurrentChunkOffX < 32);
+ ASSERT(m_CurrentChunkOffZ >= 0);
+ ASSERT(m_CurrentChunkOffZ < 32);
+ int * BaseHeight = m_Height + m_CurrentChunkOffZ * 16 * 512 + m_CurrentChunkOffX * 16;
+ for (int z = 0; z < 16; z++)
+ {
+ int * Row = BaseHeight + z * 512;
+ for (int x = 0; x < 16; x++)
+ {
+ Row[x] = ntohl(a_HeightMapBE[z * 16 + x]);
+ }
+ } // for z
+ return false; // Still want blockdata to remove trees from the heightmap
+}
+
+
+
+
+
+bool cHeightMap::OnSection(
+ unsigned char a_Y,
+ const BLOCKTYPE * a_BlockTypes,
+ const NIBBLETYPE * a_BlockAdditional,
+ const NIBBLETYPE * a_BlockMeta,
+ const NIBBLETYPE * a_BlockLight,
+ const NIBBLETYPE * a_BlockSkyLight
+)
+{
+ // Copy the section data into the appropriate place in the internal buffer
+ memcpy(m_BlockTypes + a_Y * 16 * 16 * 16, a_BlockTypes, 16 * 16 * 16);
+ return false;
+}
+
+
+
+
+
+bool cHeightMap::OnSectionsFinished(void)
+{
+ // Remove trees from the heightmap:
+ for (int z = 0; z < 16; z++)
+ {
+ for (int x = 0; x < 16; x++)
+ {
+ for (int y = m_Height[512 * (16 * m_CurrentChunkOffZ + z) + 16 * m_CurrentChunkOffX + x]; y >= 0; y--)
+ {
+ if (IsGround(m_BlockTypes[256 * y + 16 * z + x]))
+ {
+ m_Height[512 * (16 * m_CurrentChunkOffZ + z) + 16 * m_CurrentChunkOffX + x] = y;
+ break; // for y
+ }
+ } // for y
+ } // for x
+ } // for z
+ return true;
+}
+
+
+
+
+
+void cHeightMap::StartNewRegion(int a_RegionX, int a_RegionZ)
+{
+ AString FileName;
+ Printf(FileName, "Height.%d.%d.bmp", m_CurrentRegionX, m_CurrentRegionZ);
+ cFile f;
+ if (!f.Open(FileName, cFile::fmWrite))
+ {
+ LOG("Cannot open file \"%s\" for writing the height map. Data for this region lost.", FileName.c_str());
+ }
+ else
+ {
+ f.Write(g_BMPHeader, sizeof(g_BMPHeader));
+ for (int z = 0; z < 512; z++)
+ {
+ int RowData[512];
+ int * HeightRow = m_Height + z * 512;
+ for (int x = 0; x < 512; x++)
+ {
+ RowData[x] = std::max(std::min(HeightRow[x], 255), 0) * 0x010101;
+ }
+ f.Write(RowData, sizeof(RowData));
+ } // for z
+ }
+
+ memset(m_Height, 0, sizeof(m_Height));
+ m_CurrentRegionX = a_RegionX;
+ m_CurrentRegionZ = a_RegionZ;
+}
+
+
+
+
+
+bool cHeightMap::IsGround(BLOCKTYPE a_BlockType)
+{
+ // Name all blocks that are NOT ground, return false for them:
+ switch (a_BlockType)
+ {
+ case E_BLOCK_AIR:
+ case E_BLOCK_BED:
+ case E_BLOCK_BREWING_STAND:
+ case E_BLOCK_BROWN_MUSHROOM:
+ case E_BLOCK_CACTUS:
+ case E_BLOCK_CAKE:
+ case E_BLOCK_CARROTS:
+ case E_BLOCK_CAULDRON:
+ case E_BLOCK_CHEST:
+ case E_BLOCK_COBBLESTONE_WALL:
+ case E_BLOCK_COBWEB:
+ case E_BLOCK_COCOA_POD:
+ case E_BLOCK_CROPS:
+ case E_BLOCK_DEAD_BUSH:
+ case E_BLOCK_DETECTOR_RAIL:
+ case E_BLOCK_DIRT:
+ case E_BLOCK_DRAGON_EGG:
+ case E_BLOCK_END_PORTAL:
+ case E_BLOCK_ENDER_CHEST:
+ case E_BLOCK_FENCE:
+ case E_BLOCK_FENCE_GATE:
+ case E_BLOCK_FIRE:
+ case E_BLOCK_FLOWER_POT:
+ case E_BLOCK_HEAD:
+ case E_BLOCK_IRON_BARS:
+ case E_BLOCK_LADDER:
+ case E_BLOCK_LAVA:
+ case E_BLOCK_LEAVES:
+ case E_BLOCK_LEVER:
+ case E_BLOCK_LILY_PAD:
+ case E_BLOCK_LOG: // NOTE: This block is actually solid, but we don't want it because it's the thing that trees are made of, and we're getting rid of trees
+ case E_BLOCK_MELON:
+ case E_BLOCK_MELON_STEM:
+ case E_BLOCK_NETHER_BRICK_FENCE:
+ case E_BLOCK_NETHER_PORTAL:
+ case E_BLOCK_POWERED_RAIL:
+ case E_BLOCK_PUMPKIN:
+ case E_BLOCK_PUMPKIN_STEM:
+ case E_BLOCK_RAIL:
+ case E_BLOCK_RED_ROSE:
+ case E_BLOCK_RED_MUSHROOM:
+ case E_BLOCK_REDSTONE_REPEATER_OFF:
+ case E_BLOCK_REDSTONE_REPEATER_ON:
+ case E_BLOCK_REDSTONE_TORCH_OFF:
+ case E_BLOCK_REDSTONE_TORCH_ON:
+ case E_BLOCK_REDSTONE_WIRE:
+ case E_BLOCK_REEDS:
+ case E_BLOCK_SAPLING:
+ case E_BLOCK_SIGN_POST:
+ case E_BLOCK_SNOW:
+ case E_BLOCK_STATIONARY_LAVA:
+ case E_BLOCK_STATIONARY_WATER:
+ case E_BLOCK_STONE_BUTTON:
+ case E_BLOCK_STONE_PRESSURE_PLATE:
+ case E_BLOCK_TALL_GRASS:
+ case E_BLOCK_TORCH:
+ case E_BLOCK_TRIPWIRE:
+ case E_BLOCK_TRIPWIRE_HOOK:
+ case E_BLOCK_VINES:
+ case E_BLOCK_WALLSIGN:
+ case E_BLOCK_WATER:
+ case E_BLOCK_WOODEN_BUTTON:
+ case E_BLOCK_WOODEN_PRESSURE_PLATE:
+ case E_BLOCK_YELLOW_FLOWER:
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// cHeightMapFactory:
+
+cHeightMapFactory::~cHeightMapFactory()
+{
+ // Force all threads to save their last regions:
+ for (cCallbacks::iterator itr = m_Callbacks.begin(), end = m_Callbacks.end(); itr != end; ++itr)
+ {
+ ((cHeightMap *)(*itr))->Finish();
+ }
+ // TODO: Join all the files into one giant image file
+}
+
+
+
+