// BiomeMap.cpp // Implements the cBiomeMap class representing a cCallback descendant that draws a map of biomes for the world #include "Globals.h" #include "BiomeMap.h" #include "../BiomeVisualiser/BiomeColors.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 } ; cBiomeMap::cBiomeMap(void) : m_CurrentRegionX(0), m_CurrentRegionZ(0), m_IsCurrentRegionValid(false) { } void cBiomeMap::Finish(void) { if (m_IsCurrentRegionValid) { StartNewRegion(0, 0); } } bool cBiomeMap::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; return false; } bool cBiomeMap::OnBiomes(const unsigned char * a_BiomeData) { ASSERT(m_CurrentChunkOffX >= 0); ASSERT(m_CurrentChunkOffX < 32); ASSERT(m_CurrentChunkOffZ >= 0); ASSERT(m_CurrentChunkOffZ < 32); char * BaseBiomes = m_Biomes + m_CurrentChunkOffZ * 16 * 512 + m_CurrentChunkOffX * 16; for (int z = 0; z < 16; z++) { char * Row = BaseBiomes + z * 512; memcpy(Row, a_BiomeData + z * 16, 16); } // for z return true; } void cBiomeMap::StartNewRegion(int a_RegionX, int a_RegionZ) { AString FileName; Printf(FileName, "Biomes.%d.%d.bmp", m_CurrentRegionX, m_CurrentRegionZ); cFile f; if (!f.Open(FileName, cFile::fmWrite)) { LOG("Cannot open file \"%s\" for writing the biome 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]; unsigned char * BiomeRow = (unsigned char *)m_Biomes + z * 512; for (int x = 0; x < 512; x++) { RowData[x] = g_BiomeColors[BiomeRow[x]]; } f.Write(RowData, sizeof(RowData)); } // for z } memset(m_Biomes, 0, sizeof(m_Biomes)); m_CurrentRegionX = a_RegionX; m_CurrentRegionZ = a_RegionZ; } //////////////////////////////////////////////////////////////////////////////// // cBiomeMapFactory: cBiomeMapFactory::~cBiomeMapFactory() { // Force all threads to save their last regions: for (cCallbacks::iterator itr = m_Callbacks.begin(), end = m_Callbacks.end(); itr != end; ++itr) { ((cBiomeMap *)(*itr))->Finish(); } // TODO: Join all the files into one giant image file }