From be780b380ee91f5de27eecb3d8809506d4198534 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 10 Aug 2014 20:10:47 +0100 Subject: Fixed Tools to work with new logging framework --- Tools/MCADefrag/CMakeLists.txt | 6 ++---- Tools/MCADefrag/MCADefrag.cpp | 16 ++++++++++++++-- Tools/ProtoProxy/CMakeLists.txt | 6 ++---- 3 files changed, 18 insertions(+), 10 deletions(-) (limited to 'Tools') diff --git a/Tools/MCADefrag/CMakeLists.txt b/Tools/MCADefrag/CMakeLists.txt index 2a021049f..e237b6429 100644 --- a/Tools/MCADefrag/CMakeLists.txt +++ b/Tools/MCADefrag/CMakeLists.txt @@ -39,14 +39,12 @@ set_exe_flags() set(SHARED_SRC ../../src/StringCompression.cpp ../../src/StringUtils.cpp - ../../src/Log.cpp - ../../src/MCLogger.cpp + ../../src/Listeners.cpp + ../../src/LogDispacher.cpp ) set(SHARED_HDR ../../src/ByteBuffer.h ../../src/StringUtils.h - ../../src/Log.h - ../../src/MCLogger.h ) flatten_files(SHARED_SRC) flatten_files(SHARED_HDR) diff --git a/Tools/MCADefrag/MCADefrag.cpp b/Tools/MCADefrag/MCADefrag.cpp index a2de7f957..702b04ebf 100644 --- a/Tools/MCADefrag/MCADefrag.cpp +++ b/Tools/MCADefrag/MCADefrag.cpp @@ -5,7 +5,8 @@ #include "Globals.h" #include "MCADefrag.h" -#include "MCLogger.h" +#include "LogDispacher.h" +#include "Listeners.h" #include "zlib/zlib.h" @@ -21,7 +22,13 @@ static const Byte g_Zeroes[4096] = {0}; int main(int argc, char ** argv) { - new cMCLogger(Printf("Defrag_%08x.log", time(NULL))); + Logger::cLoggerListener * consoleLogListener = Logger::MakeConsoleListener(); + Logger::cLoggerListener * fileLogListener = new Logger::cFileListener(); + Logger::GetInstance().AttachListener(consoleLogListener); + Logger::GetInstance().AttachListener(fileLogListener); + + Logger::InitiateMultithreading(); + cMCADefrag Defrag; if (!Defrag.Init(argc, argv)) { @@ -30,6 +37,11 @@ int main(int argc, char ** argv) Defrag.Run(); + Logger::GetInstance().DetachListener(consoleLogListener); + delete consoleLogListener; + Logger::GetInstance().DetachListener(fileLogListener); + delete fileLogListener; + return 0; } diff --git a/Tools/ProtoProxy/CMakeLists.txt b/Tools/ProtoProxy/CMakeLists.txt index f0796363c..16c59bb43 100644 --- a/Tools/ProtoProxy/CMakeLists.txt +++ b/Tools/ProtoProxy/CMakeLists.txt @@ -34,20 +34,18 @@ set_exe_flags() set(SHARED_SRC ../../src/ByteBuffer.cpp ../../src/StringUtils.cpp - ../../src/Log.cpp - ../../src/MCLogger.cpp ../../src/PolarSSL++/AesCfb128Decryptor.cpp ../../src/PolarSSL++/AesCfb128Encryptor.cpp ../../src/PolarSSL++/CryptoKey.cpp ../../src/PolarSSL++/CtrDrbgContext.cpp ../../src/PolarSSL++/EntropyContext.cpp ../../src/PolarSSL++/RsaPrivateKey.cpp + ../../src/Listeners.cpp + ../../src/LogDispacher.cpp ) set(SHARED_HDR ../../src/ByteBuffer.h ../../src/StringUtils.h - ../../src/Log.h - ../../src/MCLogger.h ../../src/PolarSSL++/AesCfb128Decryptor.h ../../src/PolarSSL++/AesCfb128Encryptor.h ../../src/PolarSSL++/CryptoKey.h -- cgit v1.2.3 From 98443682671d0c39b19f86098f7bc900b7529b72 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 12 Aug 2014 16:05:04 +0100 Subject: Renamed Loggers --- Tools/MCADefrag/CMakeLists.txt | 4 ++-- Tools/MCADefrag/MCADefrag.cpp | 18 +++++++++--------- Tools/ProtoProxy/CMakeLists.txt | 4 ++-- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'Tools') diff --git a/Tools/MCADefrag/CMakeLists.txt b/Tools/MCADefrag/CMakeLists.txt index e237b6429..42b42018b 100644 --- a/Tools/MCADefrag/CMakeLists.txt +++ b/Tools/MCADefrag/CMakeLists.txt @@ -39,8 +39,8 @@ set_exe_flags() set(SHARED_SRC ../../src/StringCompression.cpp ../../src/StringUtils.cpp - ../../src/Listeners.cpp - ../../src/LogDispacher.cpp + ../../src/LoggerListeners.cpp + ../../src/Logger.cpp ) set(SHARED_HDR ../../src/ByteBuffer.h diff --git a/Tools/MCADefrag/MCADefrag.cpp b/Tools/MCADefrag/MCADefrag.cpp index 702b04ebf..d5d233fd2 100644 --- a/Tools/MCADefrag/MCADefrag.cpp +++ b/Tools/MCADefrag/MCADefrag.cpp @@ -5,8 +5,8 @@ #include "Globals.h" #include "MCADefrag.h" -#include "LogDispacher.h" -#include "Listeners.h" +#include "Logger.h" +#include "LoggerListeners.h" #include "zlib/zlib.h" @@ -22,12 +22,12 @@ static const Byte g_Zeroes[4096] = {0}; int main(int argc, char ** argv) { - Logger::cLoggerListener * consoleLogListener = Logger::MakeConsoleListener(); - Logger::cLoggerListener * fileLogListener = new Logger::cFileListener(); - Logger::GetInstance().AttachListener(consoleLogListener); - Logger::GetInstance().AttachListener(fileLogListener); + cLogger::cListener * consoleLogListener = MakeConsoleListener(); + cLogger::cListener * fileLogListener = new cFileListener(); + cLogger::GetInstance().AttachListener(consoleLogListener); + cLogger::GetInstance().AttachListener(fileLogListener); - Logger::InitiateMultithreading(); + cLogger::InitiateMultithreading(); cMCADefrag Defrag; if (!Defrag.Init(argc, argv)) @@ -37,9 +37,9 @@ int main(int argc, char ** argv) Defrag.Run(); - Logger::GetInstance().DetachListener(consoleLogListener); + cLogger::GetInstance().DetachListener(consoleLogListener); delete consoleLogListener; - Logger::GetInstance().DetachListener(fileLogListener); + cLogger::GetInstance().DetachListener(fileLogListener); delete fileLogListener; return 0; diff --git a/Tools/ProtoProxy/CMakeLists.txt b/Tools/ProtoProxy/CMakeLists.txt index 16c59bb43..bc3923d90 100644 --- a/Tools/ProtoProxy/CMakeLists.txt +++ b/Tools/ProtoProxy/CMakeLists.txt @@ -40,8 +40,8 @@ set(SHARED_SRC ../../src/PolarSSL++/CtrDrbgContext.cpp ../../src/PolarSSL++/EntropyContext.cpp ../../src/PolarSSL++/RsaPrivateKey.cpp - ../../src/Listeners.cpp - ../../src/LogDispacher.cpp + ../../src/LoggerListeners.cpp + ../../src/Logger.cpp ) set(SHARED_HDR ../../src/ByteBuffer.h -- cgit v1.2.3 From 24a092d9cb5013d55a85b5df022e4e905141e069 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 27 Aug 2014 09:05:43 +0200 Subject: AnvilStats: Rewritten to use CMake. --- Tools/AnvilStats/.gitignore | 4 + Tools/AnvilStats/AnvilStats.sln | 55 ----- Tools/AnvilStats/AnvilStats.vcproj | 468 ------------------------------------- Tools/AnvilStats/CMakeLists.txt | 122 ++++++++++ 4 files changed, 126 insertions(+), 523 deletions(-) delete mode 100644 Tools/AnvilStats/AnvilStats.sln delete mode 100644 Tools/AnvilStats/AnvilStats.vcproj create mode 100644 Tools/AnvilStats/CMakeLists.txt (limited to 'Tools') diff --git a/Tools/AnvilStats/.gitignore b/Tools/AnvilStats/.gitignore index 96210cfc9..afd34cdda 100644 --- a/Tools/AnvilStats/.gitignore +++ b/Tools/AnvilStats/.gitignore @@ -1,3 +1,7 @@ +*.vcproj +*.vcxproj +*.sln +*.user .xls Statistics.txt *.bmp diff --git a/Tools/AnvilStats/AnvilStats.sln b/Tools/AnvilStats/AnvilStats.sln deleted file mode 100644 index 46bed8969..000000000 --- a/Tools/AnvilStats/AnvilStats.sln +++ /dev/null @@ -1,55 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Express 2013 for Windows Desktop -VisualStudioVersion = 12.0.21005.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AnvilStats", "AnvilStats.vcxproj", "{CF996A5E-0A86-4004-9710-682B06B5AEBA}" - ProjectSection(ProjectDependencies) = postProject - {B61007AC-B557-4B67-A765-E468C0C3A821} = {B61007AC-B557-4B67-A765-E468C0C3A821} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\..\lib\zlib\zlib.vcxproj", "{B61007AC-B557-4B67-A765-E468C0C3A821}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - DebugProfile|Win32 = DebugProfile|Win32 - MinSizeRel|Win32 = MinSizeRel|Win32 - Release profiled|Win32 = Release profiled|Win32 - Release|Win32 = Release|Win32 - ReleaseProfile|Win32 = ReleaseProfile|Win32 - RelWithDebInfo|Win32 = RelWithDebInfo|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CF996A5E-0A86-4004-9710-682B06B5AEBA}.Debug|Win32.ActiveCfg = Debug|Win32 - {CF996A5E-0A86-4004-9710-682B06B5AEBA}.Debug|Win32.Build.0 = Debug|Win32 - {CF996A5E-0A86-4004-9710-682B06B5AEBA}.DebugProfile|Win32.ActiveCfg = Debug|Win32 - {CF996A5E-0A86-4004-9710-682B06B5AEBA}.DebugProfile|Win32.Build.0 = Debug|Win32 - {CF996A5E-0A86-4004-9710-682B06B5AEBA}.MinSizeRel|Win32.ActiveCfg = Release|Win32 - {CF996A5E-0A86-4004-9710-682B06B5AEBA}.MinSizeRel|Win32.Build.0 = Release|Win32 - {CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release profiled|Win32.ActiveCfg = Release profiled|Win32 - {CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release profiled|Win32.Build.0 = Release profiled|Win32 - {CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release|Win32.ActiveCfg = Release|Win32 - {CF996A5E-0A86-4004-9710-682B06B5AEBA}.Release|Win32.Build.0 = Release|Win32 - {CF996A5E-0A86-4004-9710-682B06B5AEBA}.ReleaseProfile|Win32.ActiveCfg = Release|Win32 - {CF996A5E-0A86-4004-9710-682B06B5AEBA}.ReleaseProfile|Win32.Build.0 = Release|Win32 - {CF996A5E-0A86-4004-9710-682B06B5AEBA}.RelWithDebInfo|Win32.ActiveCfg = Release|Win32 - {CF996A5E-0A86-4004-9710-682B06B5AEBA}.RelWithDebInfo|Win32.Build.0 = Release|Win32 - {B61007AC-B557-4B67-A765-E468C0C3A821}.Debug|Win32.ActiveCfg = Debug|Win32 - {B61007AC-B557-4B67-A765-E468C0C3A821}.Debug|Win32.Build.0 = Debug|Win32 - {B61007AC-B557-4B67-A765-E468C0C3A821}.DebugProfile|Win32.ActiveCfg = DebugProfile|Win32 - {B61007AC-B557-4B67-A765-E468C0C3A821}.DebugProfile|Win32.Build.0 = DebugProfile|Win32 - {B61007AC-B557-4B67-A765-E468C0C3A821}.MinSizeRel|Win32.ActiveCfg = MinSizeRel|Win32 - {B61007AC-B557-4B67-A765-E468C0C3A821}.MinSizeRel|Win32.Build.0 = MinSizeRel|Win32 - {B61007AC-B557-4B67-A765-E468C0C3A821}.Release profiled|Win32.ActiveCfg = Release|Win32 - {B61007AC-B557-4B67-A765-E468C0C3A821}.Release profiled|Win32.Build.0 = Release|Win32 - {B61007AC-B557-4B67-A765-E468C0C3A821}.Release|Win32.ActiveCfg = Release|Win32 - {B61007AC-B557-4B67-A765-E468C0C3A821}.Release|Win32.Build.0 = Release|Win32 - {B61007AC-B557-4B67-A765-E468C0C3A821}.ReleaseProfile|Win32.ActiveCfg = ReleaseProfile|Win32 - {B61007AC-B557-4B67-A765-E468C0C3A821}.ReleaseProfile|Win32.Build.0 = ReleaseProfile|Win32 - {B61007AC-B557-4B67-A765-E468C0C3A821}.RelWithDebInfo|Win32.ActiveCfg = RelWithDebInfo|Win32 - {B61007AC-B557-4B67-A765-E468C0C3A821}.RelWithDebInfo|Win32.Build.0 = RelWithDebInfo|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Tools/AnvilStats/AnvilStats.vcproj b/Tools/AnvilStats/AnvilStats.vcproj deleted file mode 100644 index c7a2e9390..000000000 --- a/Tools/AnvilStats/AnvilStats.vcproj +++ /dev/null @@ -1,468 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/AnvilStats/CMakeLists.txt b/Tools/AnvilStats/CMakeLists.txt new file mode 100644 index 000000000..8cbcf6be4 --- /dev/null +++ b/Tools/AnvilStats/CMakeLists.txt @@ -0,0 +1,122 @@ + +cmake_minimum_required (VERSION 2.8.3) + +project (AnvilStats) + +include(../../SetFlags.cmake) + +set_flags() +set_lib_flags() + + +# Set include paths to the used libraries: +include_directories("../../lib") +include_directories("../../src") + + + +function(flatten_files arg1) + set(res "") + foreach(f ${${arg1}}) + get_filename_component(f ${f} ABSOLUTE) + list(APPEND res ${f}) + endforeach() + set(${arg1} "${res}" PARENT_SCOPE) +endfunction() + +add_subdirectory(../../lib/zlib ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/lib/zlib) + +set_exe_flags() + +# Include the shared files: +set(SHARED_SRC + ../../src/ByteBuffer.cpp + ../../src/StringUtils.cpp + ../../src/LoggerListeners.cpp + ../../src/Logger.cpp + ../../src/WorldStorage/FastNBT.cpp + ../BiomeVisualiser/BiomeColors.cpp +) + +set(SHARED_HDR + ../../src/ByteBuffer.h + ../../src/StringUtils.h + ../../src/LoggerListeners.h + ../../src/Logger.h + ../../src/WorldStorage/FastNBT.h + ../BiomeVisualiser/BiomeColors.h +) + +set(SHARED_OSS_SRC + ../../src/OSSupport/CriticalSection.cpp + ../../src/OSSupport/Event.cpp + ../../src/OSSupport/File.cpp + ../../src/OSSupport/GZipFile.cpp + ../../src/OSSupport/IsThread.cpp + ../../src/OSSupport/Timer.cpp +) + +set(SHARED_OSS_HDR + ../../src/OSSupport/CriticalSection.h + ../../src/OSSupport/Event.h + ../../src/OSSupport/File.h + ../../src/OSSupport/GZipFile.h + ../../src/OSSupport/IsThread.h + ../../src/OSSupport/Timer.h +) + +flatten_files(SHARED_SRC) +flatten_files(SHARED_HDR) +flatten_files(SHARED_OSS_SRC) +flatten_files(SHARED_OSS_HDR) +source_group("Shared" FILES ${SHARED_SRC} ${SHARED_HDR}) +source_group("Shared\\OSSupport" FILES ${SHARED_OSS_SRC} ${SHARED_OSS_HDR}) + + + +# Include the main source files: +set(SOURCES + AnvilStats.cpp + BiomeMap.cpp + ChunkExtract.cpp + Globals.cpp + HeightBiomeMap.cpp + HeightMap.cpp + ImageComposingCallback.cpp + Processor.cpp + SpringStats.cpp + Statistics.cpp + Utils.cpp +) + +set(HEADERS + BiomeMap.h + Callback.h + ChunkExtract.h + Globals.h + HeightBiomeMap.h + HeightMap.h + ImageComposingCallback.h + Processor.h + SpringStats.h + Statistics.h + Utils.h + + AnvilStats.txt +) + +source_group("" FILES ${SOURCES} ${HEADERS}) + +add_definitions(-DNBT_RESERVE_SIZE=10000) + +add_executable(AnvilStats + ${SOURCES} + ${HEADERS} + ${SHARED_SRC} + ${SHARED_HDR} + ${SHARED_OSS_SRC} + ${SHARED_OSS_HDR} +) + +target_link_libraries(AnvilStats zlib) + -- cgit v1.2.3 From d783753cb5050e3a16363cd8a2bfb4b361c130c0 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 27 Aug 2014 09:46:59 +0200 Subject: AnvilStats: initial per-height blocktype implementation (WIP). --- Tools/AnvilStats/Globals.h | 11 ++++++ Tools/AnvilStats/Statistics.cpp | 87 ++++++++++++++++++++++++++++++++++++++--- Tools/AnvilStats/Statistics.h | 3 ++ 3 files changed, 96 insertions(+), 5 deletions(-) (limited to 'Tools') diff --git a/Tools/AnvilStats/Globals.h b/Tools/AnvilStats/Globals.h index df1430cc4..21d54739a 100644 --- a/Tools/AnvilStats/Globals.h +++ b/Tools/AnvilStats/Globals.h @@ -241,6 +241,17 @@ public: +/** Clamp value to the specified range. */ +template +T Clamp(T a_Value, T a_Min, T a_Max) +{ + return (a_Value < a_Min) ? a_Min : ((a_Value > a_Max) ? a_Max : a_Value); +} + + + + + // Common headers (part 2, with macros): #include "../../src/ChunkDef.h" #include "../../src/BlockID.h" diff --git a/Tools/AnvilStats/Statistics.cpp b/Tools/AnvilStats/Statistics.cpp index f7519fd37..11b9f09c5 100644 --- a/Tools/AnvilStats/Statistics.cpp +++ b/Tools/AnvilStats/Statistics.cpp @@ -26,9 +26,11 @@ cStatistics::cStats::cStats(void) : m_MinChunkZ(0x7fffffff), m_MaxChunkZ(0x80000000) { - memset(m_BiomeCounts, 0, sizeof(m_BiomeCounts)); - memset(m_BlockCounts, 0, sizeof(m_BlockCounts)); - memset(m_SpawnerEntity, 0, sizeof(m_SpawnerEntity)); + memset(m_BiomeCounts, 0, sizeof(m_BiomeCounts)); + memset(m_BlockCounts, 0, sizeof(m_BlockCounts)); + memset(m_PerHeightBlockCounts, 0, sizeof(m_PerHeightBlockCounts)); + memset(m_PerHeightSpawners, 0, sizeof(m_PerHeightSpawners)); + memset(m_SpawnerEntity, 0, sizeof(m_SpawnerEntity)); } @@ -46,6 +48,11 @@ void cStatistics::cStats::Add(const cStatistics::cStats & a_Stats) for (int j = 0; j <= 255; j++) { m_BlockCounts[i][j] += a_Stats.m_BlockCounts[i][j]; + m_PerHeightBlockCounts[i][j] += a_Stats.m_PerHeightBlockCounts[i][j]; + } + for (int j = 0; j < ARRAYCOUNT(m_PerHeightSpawners[0]); j++) + { + m_PerHeightSpawners[i][j] += a_Stats.m_PerHeightSpawners[i][j]; } } for (int i = 0; i < ARRAYCOUNT(m_SpawnerEntity); i++) @@ -149,6 +156,7 @@ bool cStatistics::OnSection for (int y = 0; y < 16; y++) { + int Height = (int)a_Y * 16 + y; for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) @@ -156,6 +164,7 @@ bool cStatistics::OnSection unsigned char Biome = m_BiomeData[x + 16 * z]; // Cannot use cChunkDef, different datatype unsigned char BlockType = cChunkDef::GetBlock(a_BlockTypes, x, y, z); m_Stats.m_BlockCounts[Biome][BlockType] += 1; + m_Stats.m_PerHeightBlockCounts[Height][BlockType] += 1; } } } @@ -259,16 +268,27 @@ bool cStatistics::OnTileTick( void cStatistics::OnSpawner(cParsedNBT & a_NBT, int a_TileEntityTag) { + // Get the spawned entity type: int EntityIDTag = a_NBT.FindChildByName(a_TileEntityTag, "EntityId"); if ((EntityIDTag < 0) || (a_NBT.GetType(EntityIDTag) != TAG_String)) { return; } eEntityType Ent = GetEntityType(a_NBT.GetString(EntityIDTag)); - if (Ent < ARRAYCOUNT(m_Stats.m_SpawnerEntity)) + if (Ent >= ARRAYCOUNT(m_Stats.m_SpawnerEntity)) + { + return; + } + m_Stats.m_SpawnerEntity[Ent] += 1; + + // Get the spawner pos: + int PosYTag = a_NBT.FindChildByName(a_TileEntityTag, "y"); + if ((PosYTag < 0) || (a_NBT.GetType(PosYTag) != TAG_Int)) { - m_Stats.m_SpawnerEntity[Ent] += 1; + return; } + int BlockY = Clamp(a_NBT.GetInt(PosYTag), 0, 255); + m_Stats.m_PerHeightSpawners[BlockY][Ent] += 1; } @@ -316,6 +336,8 @@ cStatisticsFactory::~cStatisticsFactory() SaveBiomes(); LOG(" BlockTypes.xls"); SaveBlockTypes(); + LOG(" PerHeightBlockTypes.xls"); + SavePerHeightBlockTypes(); LOG(" BiomeBlockTypes.xls"); SaveBiomeBlockTypes(); LOG(" Spawners.xls"); @@ -395,6 +417,61 @@ void cStatisticsFactory::SaveBlockTypes(void) +void cStatisticsFactory::SavePerHeightBlockTypes(void) +{ + // Export as two tables: biomes 0-127 and 128-255, because OpenOffice doesn't support more than 256 columns + + cFile f; + if (!f.Open("PerHeightBlockTypes.xls", cFile::fmWrite)) + { + LOG("Cannot write to file PerHeightBlockTypes.xls. Statistics not written."); + return; + } + + // Write header: + f.Printf("Blocks 0 - 127:\nHeight\t"); + for (int i = 0; i < 128; i++) + { + f.Printf("\t%s(%d)", GetBlockTypeString(i), i); + } + f.Printf("\n"); + + // Write first half: + for (int y = 0; y < 256; y++) + { + f.Printf("%d", y); + for (int BlockType = 0; BlockType < 128; BlockType++) + { + f.Printf("\t%d", m_CombinedStats.m_PerHeightBlockCounts[y][BlockType]); + } // for BlockType + f.Printf("\n"); + } // for y - height (0 - 127) + f.Printf("\n"); + + // Write second header: + f.Printf("Blocks 128 - 255:\nHeight\t"); + for (int i = 128; i < 256; i++) + { + f.Printf("\t%s(%d)", GetBlockTypeString(i), i); + } + f.Printf("\n"); + + // Write second half: + for (int y = 0; y < 256; y++) + { + f.Printf("%d", y); + for (int BlockType = 128; BlockType < 256; BlockType++) + { + f.Printf("\t%d", m_CombinedStats.m_PerHeightBlockCounts[y][BlockType]); + } // for BlockType + f.Printf("\n"); + } // for y - height (0 - 127) +} + + + + + void cStatisticsFactory::SaveBiomeBlockTypes(void) { // Export as two tables: biomes 0-127 and 128-255, because OpenOffice doesn't support more than 256 columns diff --git a/Tools/AnvilStats/Statistics.h b/Tools/AnvilStats/Statistics.h index 53e353f22..f6165edd9 100644 --- a/Tools/AnvilStats/Statistics.h +++ b/Tools/AnvilStats/Statistics.h @@ -31,6 +31,8 @@ public: UInt64 m_NumEntities; UInt64 m_NumTileEntities; UInt64 m_NumTileTicks; + UInt64 m_PerHeightBlockCounts[256][256]; // First dimension is the height, second dimension is BlockType + UInt64 m_PerHeightSpawners[256][entMax + 1]; // First dimension is the height, second dimension is spawned entity type int m_MinChunkX, m_MaxChunkX; // X coords range int m_MinChunkZ, m_MaxChunkZ; // Z coords range @@ -128,6 +130,7 @@ protected: void JoinResults(void); void SaveBiomes(void); void SaveBlockTypes(void); + void SavePerHeightBlockTypes(void); void SaveBiomeBlockTypes(void); void SaveStatistics(void); void SaveSpawners(void); -- cgit v1.2.3 From ccaa51f9132a1427a82e24a5d6eaf5d1992f7df9 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 27 Aug 2014 11:52:54 +0300 Subject: AnvilStats: Fixed Win64 compilation. --- Tools/AnvilStats/Utils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Tools') diff --git a/Tools/AnvilStats/Utils.cpp b/Tools/AnvilStats/Utils.cpp index baa87bd69..d7543cb4c 100644 --- a/Tools/AnvilStats/Utils.cpp +++ b/Tools/AnvilStats/Utils.cpp @@ -272,7 +272,7 @@ extern const char * GetEntityTypeString(eEntityType a_EntityType) int GetNumCores(void) { // Get number of cores by querying the system process affinity mask (Windows-specific) - DWORD Affinity, ProcAffinity; + DWORD_PTR Affinity, ProcAffinity; GetProcessAffinityMask(GetCurrentProcess(), &ProcAffinity, &Affinity); int NumCores = 0; while (Affinity > 0) -- cgit v1.2.3 From b361e994ef4aac5e2f5672a291d4abf1a3714bc6 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 27 Aug 2014 11:53:46 +0300 Subject: AnvilStats: Added cmake directive for larger executable stack. This fixes runtime "stack overflow" errors caused by large stack-allocated arrays used for decompression. --- Tools/AnvilStats/CMakeLists.txt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'Tools') diff --git a/Tools/AnvilStats/CMakeLists.txt b/Tools/AnvilStats/CMakeLists.txt index 8cbcf6be4..557a4c17a 100644 --- a/Tools/AnvilStats/CMakeLists.txt +++ b/Tools/AnvilStats/CMakeLists.txt @@ -118,5 +118,27 @@ add_executable(AnvilStats ${SHARED_OSS_HDR} ) + target_link_libraries(AnvilStats zlib) + + + + +# Under MSVC we need to enlarge the default stack size for the executable: +if (MSVC) + get_target_property(TEMP AnvilStats LINK_FLAGS) + if (TEMP STREQUAL "TEMP-NOTFOUND") + SET(TEMP "") # set to empty string + message("LINKER_FLAGS not found") + else () + SET(TEMP "${TEMP} ") # a space to cleanly separate from existing content + message("LINKER_FLAGS: ${LINKER_FLAGS}") + endif () + # append our values + SET(TEMP "${TEMP}/STACK:16777216") + set_target_properties(AnvilStats PROPERTIES LINK_FLAGS ${TEMP}) +endif () + + + -- cgit v1.2.3 From 751d345c59bbaf265393c5306f181ee3654a35a6 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 27 Aug 2014 11:54:22 +0300 Subject: AnvilStats: Ignoring output XLS files. --- Tools/AnvilStats/.gitignore | 1 + 1 file changed, 1 insertion(+) (limited to 'Tools') diff --git a/Tools/AnvilStats/.gitignore b/Tools/AnvilStats/.gitignore index afd34cdda..f093bbe7d 100644 --- a/Tools/AnvilStats/.gitignore +++ b/Tools/AnvilStats/.gitignore @@ -11,3 +11,4 @@ Profiling *.png world/ *.html +*.xls -- cgit v1.2.3 From af47b5ece2bfe274e305f0602dff8e7a74ae0360 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 27 Aug 2014 12:24:56 +0300 Subject: AnvilStats: Added per-height spawner stats. --- Tools/AnvilStats/Statistics.cpp | 48 +++++++++++++++++++++++++++++++++++++---- Tools/AnvilStats/Statistics.h | 3 +++ 2 files changed, 47 insertions(+), 4 deletions(-) (limited to 'Tools') diff --git a/Tools/AnvilStats/Statistics.cpp b/Tools/AnvilStats/Statistics.cpp index 11b9f09c5..c8a98b488 100644 --- a/Tools/AnvilStats/Statistics.cpp +++ b/Tools/AnvilStats/Statistics.cpp @@ -342,6 +342,8 @@ cStatisticsFactory::~cStatisticsFactory() SaveBiomeBlockTypes(); LOG(" Spawners.xls"); SaveSpawners(); + LOG(" PerHeightSpawners.xls"); + SavePerHeightSpawners(); } @@ -429,7 +431,7 @@ void cStatisticsFactory::SavePerHeightBlockTypes(void) } // Write header: - f.Printf("Blocks 0 - 127:\nHeight\t"); + f.Printf("Blocks 0 - 127:\nHeight"); for (int i = 0; i < 128; i++) { f.Printf("\t%s(%d)", GetBlockTypeString(i), i); @@ -442,14 +444,14 @@ void cStatisticsFactory::SavePerHeightBlockTypes(void) f.Printf("%d", y); for (int BlockType = 0; BlockType < 128; BlockType++) { - f.Printf("\t%d", m_CombinedStats.m_PerHeightBlockCounts[y][BlockType]); + f.Printf("\t%llu", m_CombinedStats.m_PerHeightBlockCounts[y][BlockType]); } // for BlockType f.Printf("\n"); } // for y - height (0 - 127) f.Printf("\n"); // Write second header: - f.Printf("Blocks 128 - 255:\nHeight\t"); + f.Printf("Blocks 128 - 255:\nHeight"); for (int i = 128; i < 256; i++) { f.Printf("\t%s(%d)", GetBlockTypeString(i), i); @@ -462,7 +464,7 @@ void cStatisticsFactory::SavePerHeightBlockTypes(void) f.Printf("%d", y); for (int BlockType = 128; BlockType < 256; BlockType++) { - f.Printf("\t%d", m_CombinedStats.m_PerHeightBlockCounts[y][BlockType]); + f.Printf("\t%llu", m_CombinedStats.m_PerHeightBlockCounts[y][BlockType]); } // for BlockType f.Printf("\n"); } // for y - height (0 - 127) @@ -598,3 +600,41 @@ void cStatisticsFactory::SaveSpawners(void) + +void cStatisticsFactory::SavePerHeightSpawners(void) +{ + cFile f; + if (!f.Open("PerHeightSpawners.xls", cFile::fmWrite)) + { + LOG("Cannot write to file PerHeightSpawners.xls. Statistics not written."); + return; + } + + // Write header: + f.Printf("Height\tTotal"); + for (int i = 0; i < entMax; i++) + { + f.Printf("\t%s", GetEntityTypeString((eEntityType)i)); + } + f.Printf("\n"); + + // Write individual lines: + for (int y = 0; y < 256; y++) + { + UInt64 Total = 0; + for (int i = 0; i < entMax; i++) + { + Total += m_CombinedStats.m_PerHeightSpawners[y][i]; + } + f.Printf("%d\t%llu", y, Total); + for (int i = 0; i < entMax; i++) + { + f.Printf("\t%llu", m_CombinedStats.m_PerHeightSpawners[y][i]); + } + f.Printf("\n"); + } +} + + + + diff --git a/Tools/AnvilStats/Statistics.h b/Tools/AnvilStats/Statistics.h index f6165edd9..1b012e283 100644 --- a/Tools/AnvilStats/Statistics.h +++ b/Tools/AnvilStats/Statistics.h @@ -76,6 +76,8 @@ protected: virtual bool OnEmptySection(unsigned char a_Y) override; + virtual bool OnSectionsFinished(void) override { return false; } // continue processing + virtual bool OnEntity( const AString & a_EntityType, double a_PosX, double a_PosY, double a_PosZ, @@ -134,6 +136,7 @@ protected: void SaveBiomeBlockTypes(void); void SaveStatistics(void); void SaveSpawners(void); + void SavePerHeightSpawners(void); } ; -- cgit v1.2.3 From cde195c1569f22027306adf12e0e3e520d69b9f8 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Wed, 27 Aug 2014 12:29:57 +0300 Subject: AnvilStats: Fixed thread start race condition. The whole program would sometimes fail to process anything because the threads were waited-for before they were started. --- Tools/AnvilStats/Processor.cpp | 24 ++++++++++++++++-------- Tools/AnvilStats/Processor.h | 10 ++++++++-- 2 files changed, 24 insertions(+), 10 deletions(-) (limited to 'Tools') diff --git a/Tools/AnvilStats/Processor.cpp b/Tools/AnvilStats/Processor.cpp index a16f78c18..6c4bb0ad5 100644 --- a/Tools/AnvilStats/Processor.cpp +++ b/Tools/AnvilStats/Processor.cpp @@ -28,6 +28,7 @@ cProcessor::cThread::cThread(cCallback & a_Callback, cProcessor & a_ParentProces m_Callback(a_Callback), m_ParentProcessor(a_ParentProcessor) { + LOG("Created a new thread: %p", this); super::Start(); } @@ -35,11 +36,20 @@ cProcessor::cThread::cThread(cCallback & a_Callback, cProcessor & a_ParentProces +void cProcessor::cThread::WaitForStart(void) +{ + m_HasStarted.Wait(); +} + + + + + void cProcessor::cThread::Execute(void) { - LOG("Started a new thread: %d", cIsThread::GetCurrentID()); + LOG("Started a new thread: %p, ID %d", this, cIsThread::GetCurrentID()); - m_ParentProcessor.m_ThreadsHaveStarted.Set(); + m_HasStarted.Set(); for (;;) { @@ -52,7 +62,7 @@ void cProcessor::cThread::Execute(void) ProcessFile(FileName); } // for-ever - LOG("Thread %d terminated", cIsThread::GetCurrentID()); + LOG("Thread %p (ID %d) terminated", this, cIsThread::GetCurrentID()); } @@ -522,20 +532,18 @@ void cProcessor::ProcessWorld(const AString & a_WorldFolder, cCallbackFactory & #endif // _DEBUG //*/ + // Start all the threads: for (int i = 0; i < NumThreads; i++) { cCallback * Callback = a_CallbackFactory.GetNewCallback(); m_Threads.push_back(new cThread(*Callback, *this)); } - // Wait for the first thread to start processing: - m_ThreadsHaveStarted.Wait(); - - // Wait for all threads to finish - // simply by calling each thread's destructor sequentially + // Wait for all threads to finish: LOG("Waiting for threads to finish"); for (cThreads::iterator itr = m_Threads.begin(), end = m_Threads.end(); itr != end; ++itr) { + (*itr)->WaitForStart(); delete *itr; } // for itr - m_Threads[] LOG("Processor finished"); diff --git a/Tools/AnvilStats/Processor.h b/Tools/AnvilStats/Processor.h index 72fea3081..db50ec619 100644 --- a/Tools/AnvilStats/Processor.h +++ b/Tools/AnvilStats/Processor.h @@ -30,6 +30,7 @@ class cProcessor cCallback & m_Callback; cProcessor & m_ParentProcessor; + cEvent m_HasStarted; // cIsThread override: virtual void Execute(void) override; @@ -48,6 +49,9 @@ class cProcessor public: cThread(cCallback & a_Callback, cProcessor & a_ParentProcessor); + + /** Waits until the thread starts processing the callback code. */ + void WaitForStart(void); } ; typedef std::vector cThreads; @@ -65,10 +69,12 @@ protected: AStringList m_FileQueue; cThreads m_Threads; - cEvent m_ThreadsHaveStarted; // This is signalled by each thread to notify the parent thread that it can start waiting for those threads - + + + /** Populates m_FileQueue with Anvil files from the specified folder. */ void PopulateFileQueue(const AString & a_WorldFolder); + /** Returns one filename from m_FileQueue, and removes the name from the queue. */ AString GetOneFileName(void); } ; -- cgit v1.2.3 From e3a2dc5a1391d8aaaa3fdb83e946838540a07e75 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 14 Sep 2014 01:32:00 +0200 Subject: Added new Qt-based biome visualiser. Compile with Qt 5.1+ --- Tools/.gitignore | 1 + Tools/BiomeVisualiser/.gitignore | 4 - Tools/BiomeVisualiser/BiomeCache.cpp | 338 ----------------- Tools/BiomeVisualiser/BiomeCache.h | 96 ----- Tools/BiomeVisualiser/BiomeColors.cpp | 114 ------ Tools/BiomeVisualiser/BiomeColors.h | 15 - Tools/BiomeVisualiser/BiomeRenderer.cpp | 119 ------ Tools/BiomeVisualiser/BiomeRenderer.h | 55 --- Tools/BiomeVisualiser/BiomeSource.h | 37 -- Tools/BiomeVisualiser/BiomeViewWnd.cpp | 247 ------------ Tools/BiomeVisualiser/BiomeViewWnd.h | 69 ---- Tools/BiomeVisualiser/BiomeVisualiser.cpp | 52 --- Tools/BiomeVisualiser/BiomeVisualiser.h | 31 -- Tools/BiomeVisualiser/BiomeVisualiser.sln | 23 -- Tools/BiomeVisualiser/BiomeVisualiser.vcproj | 527 -------------------------- Tools/BiomeVisualiser/GeneratorBiomeSource.h | 42 -- Tools/BiomeVisualiser/Pixmap.cpp | 120 ------ Tools/BiomeVisualiser/Pixmap.h | 39 -- Tools/BiomeVisualiser/Timer.h | 40 -- Tools/BiomeVisualiser/WndProcThunk.h | 143 ------- Tools/BiomeVisualiser/profile_run.cmd | 70 ---- Tools/QtBiomeVisualiser/.gitignore | 2 + Tools/QtBiomeVisualiser/BiomeView.cpp | 246 ++++++++++++ Tools/QtBiomeVisualiser/BiomeView.h | 65 ++++ Tools/QtBiomeVisualiser/Chunk.cpp | 36 ++ Tools/QtBiomeVisualiser/Chunk.h | 40 ++ Tools/QtBiomeVisualiser/ChunkCache.cpp | 110 ++++++ Tools/QtBiomeVisualiser/ChunkCache.h | 68 ++++ Tools/QtBiomeVisualiser/ChunkLoader.cpp | 29 ++ Tools/QtBiomeVisualiser/ChunkLoader.h | 43 +++ Tools/QtBiomeVisualiser/ChunkSource.cpp | 164 ++++++++ Tools/QtBiomeVisualiser/ChunkSource.h | 60 +++ Tools/QtBiomeVisualiser/Globals.h | 386 +++++++++++++++++++ Tools/QtBiomeVisualiser/MainWindow.cpp | 104 +++++ Tools/QtBiomeVisualiser/MainWindow.h | 46 +++ Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro | 62 +++ Tools/QtBiomeVisualiser/main.cpp | 20 + 37 files changed, 1482 insertions(+), 2181 deletions(-) create mode 100644 Tools/.gitignore delete mode 100644 Tools/BiomeVisualiser/.gitignore delete mode 100644 Tools/BiomeVisualiser/BiomeCache.cpp delete mode 100644 Tools/BiomeVisualiser/BiomeCache.h delete mode 100644 Tools/BiomeVisualiser/BiomeColors.cpp delete mode 100644 Tools/BiomeVisualiser/BiomeColors.h delete mode 100644 Tools/BiomeVisualiser/BiomeRenderer.cpp delete mode 100644 Tools/BiomeVisualiser/BiomeRenderer.h delete mode 100644 Tools/BiomeVisualiser/BiomeSource.h delete mode 100644 Tools/BiomeVisualiser/BiomeViewWnd.cpp delete mode 100644 Tools/BiomeVisualiser/BiomeViewWnd.h delete mode 100644 Tools/BiomeVisualiser/BiomeVisualiser.cpp delete mode 100644 Tools/BiomeVisualiser/BiomeVisualiser.h delete mode 100644 Tools/BiomeVisualiser/BiomeVisualiser.sln delete mode 100644 Tools/BiomeVisualiser/BiomeVisualiser.vcproj delete mode 100644 Tools/BiomeVisualiser/GeneratorBiomeSource.h delete mode 100644 Tools/BiomeVisualiser/Pixmap.cpp delete mode 100644 Tools/BiomeVisualiser/Pixmap.h delete mode 100644 Tools/BiomeVisualiser/Timer.h delete mode 100644 Tools/BiomeVisualiser/WndProcThunk.h delete mode 100644 Tools/BiomeVisualiser/profile_run.cmd create mode 100644 Tools/QtBiomeVisualiser/.gitignore create mode 100644 Tools/QtBiomeVisualiser/BiomeView.cpp create mode 100644 Tools/QtBiomeVisualiser/BiomeView.h create mode 100644 Tools/QtBiomeVisualiser/Chunk.cpp create mode 100644 Tools/QtBiomeVisualiser/Chunk.h create mode 100644 Tools/QtBiomeVisualiser/ChunkCache.cpp create mode 100644 Tools/QtBiomeVisualiser/ChunkCache.h create mode 100644 Tools/QtBiomeVisualiser/ChunkLoader.cpp create mode 100644 Tools/QtBiomeVisualiser/ChunkLoader.h create mode 100644 Tools/QtBiomeVisualiser/ChunkSource.cpp create mode 100644 Tools/QtBiomeVisualiser/ChunkSource.h create mode 100644 Tools/QtBiomeVisualiser/Globals.h create mode 100644 Tools/QtBiomeVisualiser/MainWindow.cpp create mode 100644 Tools/QtBiomeVisualiser/MainWindow.h create mode 100644 Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro create mode 100644 Tools/QtBiomeVisualiser/main.cpp (limited to 'Tools') diff --git a/Tools/.gitignore b/Tools/.gitignore new file mode 100644 index 000000000..f240e723e --- /dev/null +++ b/Tools/.gitignore @@ -0,0 +1 @@ +Debug/ diff --git a/Tools/BiomeVisualiser/.gitignore b/Tools/BiomeVisualiser/.gitignore deleted file mode 100644 index cfbc9164c..000000000 --- a/Tools/BiomeVisualiser/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -Debug/ -logs/ -Release/ -Release profiled/ diff --git a/Tools/BiomeVisualiser/BiomeCache.cpp b/Tools/BiomeVisualiser/BiomeCache.cpp deleted file mode 100644 index 7d9301d8f..000000000 --- a/Tools/BiomeVisualiser/BiomeCache.cpp +++ /dev/null @@ -1,338 +0,0 @@ - -// BiomeCache.cpp - -// Implements the cBiomeCache class representing a biome source that caches data from the underlying biome source - -#include "Globals.h" -#include "BiomeCache.h" -#include "Timer.h" - - - - - -static int GetNumCores(void) -{ - // Get number of cores by querying the system process affinity mask - DWORD Affinity, ProcAffinity; - GetProcessAffinityMask(GetCurrentProcess(), &ProcAffinity, &Affinity); - int NumCores = 0; - while (Affinity > 0) - { - if ((Affinity & 1) == 1) - { - NumCores++; - } - Affinity >>= 1; - } // while (Affinity > 0) - return NumCores; -} - - - - - -cBiomeCache::cBiomeCache(void) : - m_Source(NULL), - m_BaseX(-100000), - m_BaseZ(-100000), - m_Available(NULL), - m_IsTerminatingThreads(false) -{ - int NumThreads = GetNumCores(); - NumThreads--; // One core should be left for the system to run on ;) - for (int i = NumThreads; i > 0; i--) - { - cThread * Thread = new cThread(*this); - m_Threads.push_back(Thread); - Thread->Start(); - } -} - - - - -cBiomeCache::~cBiomeCache() -{ - m_IsTerminatingThreads = true; - for (cThreads::iterator itr = m_Threads.begin(), end = m_Threads.end(); itr != end; ++itr) - { - m_evtQueued.Set(); - } - for (cThreads::iterator itr = m_Threads.begin(), end = m_Threads.end(); itr != end; ++itr) - { - delete *itr; - } - m_Threads.clear(); - - SetSource(NULL); -} - - - - - -cBiomeSource::eAvailability cBiomeCache::GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) -{ - if (m_Source == NULL) - { - return baNever; - } - - // Look up using the cache: - int x = a_ChunkX - m_BaseX; - int z = a_ChunkZ - m_BaseZ; - if ((x < 0) || (x >= m_Width) || (z < 0) || (z >= m_Height)) - { - // Outside the cached region - return baNever; - } - - cCSLock Lock(m_CS); - cItem * Item = m_Available[x + m_Width * z]; - if (Item == NULL) - { - // Item hasn't been processed yet - return baLater; - } - if (Item->m_IsValid) - { - memcpy(a_Biomes, Item->m_Biomes, sizeof(a_Biomes)); - return baNow; - } - - // Item has been processed, but the underlying source refused to give the data to us - return baNever; -} - - - - - -void cBiomeCache::HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) -{ - cTimer Timer("Cache: HintViewArea"); - - if ( - (a_MinChunkX == m_BaseX) && - (a_MaxChunkX == m_BaseX + m_Width - 1) && - (a_MinChunkZ == m_BaseZ) && - (a_MaxChunkZ == m_BaseZ + m_Height - 1) - ) - { - // The same set of parameters, bail out - return; - } - - if (m_Source != NULL) - { - m_Source->HintViewArea(a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ); - } - - int NewWidth = a_MaxChunkX - a_MinChunkX + 1; - int NewHeight = a_MaxChunkZ - a_MinChunkZ + 1; - - // Make a new empty cache table: - pItem * NewAvailable = new pItem[NewWidth * NewHeight]; - for (int i = NewWidth * NewHeight - 1; i >= 0; --i) - { - NewAvailable[i] = NULL; - } - - // Move the common contents of the old table into the new table: - cCSLock Lock(m_CS); - for (int z = 0; z < NewHeight; z++) - { - int OldZ = z + a_MinChunkZ - m_BaseZ; - if ((OldZ < 0) || (OldZ >= m_Height)) - { - continue; - } - for (int x = 0; x < NewWidth; x++) - { - int OldX = x + a_MinChunkX - m_BaseX; - if ((OldX < 0) || (OldX >= m_Width)) - { - continue; - } - NewAvailable[x + NewWidth * z] = m_Available[OldX + m_Width * OldZ]; - m_Available[OldX + m_Width * OldZ] = NULL; - } // for x - } // for z - - // All items that aren't common go into the pool: - for (int idx = 0, z = 0; z < m_Height; z++) - { - for (int x = 0; x < m_Width; ++x, ++idx) - { - if (m_Available[idx] != NULL) - { - m_Pool.push_back(m_Available[idx]); - m_Available[idx] = NULL; - } - } - } - - // Replace the cache table: - delete m_Available; - m_Available = NewAvailable; - m_Width = NewWidth; - m_Height = NewHeight; - m_BaseX = a_MinChunkX; - m_BaseZ = a_MinChunkZ; - - // Remove all items outside the coords: - FilterOutItems(m_Queue, a_MinChunkX, a_MaxChunkX, a_MinChunkZ, a_MaxChunkZ); - - // Queue all items from inside the coords into m_Queue: - for (int z = 0; z < NewHeight; z++) - { - for (int x = 0; x < NewWidth; x++) - { - if (m_Available[x + m_Width * z] != NULL) - { - // Already calculated, skip - continue; - } - - if (m_Pool.empty()) - { - m_Pool.push_back(new cItem(x + a_MinChunkX, z + a_MinChunkZ)); - } - ASSERT(!m_Pool.empty()); - m_Pool.back()->m_ChunkX = x + a_MinChunkX; - m_Pool.back()->m_ChunkZ = z + a_MinChunkZ; - m_Queue.push_back(m_Pool.back()); - m_Pool.pop_back(); - m_evtQueued.Set(); - } // for x - } // for z -} - - - - - -void cBiomeCache::SetSource(cBiomeSource * a_Source) -{ - // TODO: Stop all threads, so that they don't use the source anymore! - - delete m_Source; - m_Source = a_Source; - - // Invalidate cache contents: - cCSLock Lock(m_CS); - m_BaseX = -10000; - m_BaseZ = -10000; - m_Pool.splice(m_Pool.end(), m_Queue); -} - - - - - -void cBiomeCache::FilterOutItems(cItems & a_Items, int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) -{ - for (cItems::iterator itr = a_Items.begin(); itr != a_Items.end();) - { - if ( - ((*itr)->m_ChunkX < a_MinChunkX) || - ((*itr)->m_ChunkX > a_MaxChunkX) || - ((*itr)->m_ChunkX < a_MinChunkX) || - ((*itr)->m_ChunkX > a_MaxChunkX) - ) - { - m_Pool.push_back(*itr); - itr = a_Items.erase(itr); - } - else - { - ++itr; - } - } -} - - - - - -void cBiomeCache::thrProcessQueueItem(void) -{ - if (m_Source == NULL) - { - return; - } - - cItem * Item = NULL; - { - cCSLock Lock(m_CS); - if (m_Queue.empty()) - { - cCSUnlock Unlock(Lock); - m_evtQueued.Wait(); - } - if (m_IsTerminatingThreads || m_Queue.empty()) - { - // We've been woken up only to die / spurious wakeup - return; - } - Item = m_Queue.back(); - m_Queue.pop_back(); - } - - // Process the item: - Item->m_IsValid = (m_Source->GetBiome(Item->m_ChunkX, Item->m_ChunkZ, Item->m_Biomes) == baNow); - - // Store result: - cCSLock Lock(m_CS); - int x = Item->m_ChunkX - m_BaseX; - int z = Item->m_ChunkZ - m_BaseZ; - if ((x < 0) || (x >= m_Width) || (z < 0) || (z >= m_Height)) - { - // The cache rectangle has changed under our fingers, drop this chunk - return; - } - m_Available[x + m_Width * z] = Item; -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cBiomeCache::cItem: - -cBiomeCache::cItem::cItem(int a_ChunkX, int a_ChunkZ) : - m_ChunkX(a_ChunkX), - m_ChunkZ(a_ChunkZ) -{ -} - - - - - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// cBiomeCache::cThread: - -cBiomeCache::cThread::cThread(cBiomeCache & a_Parent) : - super("Biome cache thread"), - m_Parent(a_Parent) -{ -} - - - - - -void cBiomeCache::cThread::Execute(void) -{ - while (!m_ShouldTerminate && !m_Parent.m_IsTerminatingThreads) - { - m_Parent.thrProcessQueueItem(); - } -} - - - - diff --git a/Tools/BiomeVisualiser/BiomeCache.h b/Tools/BiomeVisualiser/BiomeCache.h deleted file mode 100644 index da4d6c761..000000000 --- a/Tools/BiomeVisualiser/BiomeCache.h +++ /dev/null @@ -1,96 +0,0 @@ - -// BiomeCache.h - -// Declares the cBiomeCache class representing a biome source that caches data from the underlying biome source - -/* -This cache works a bit differently than regular caches. -It first receives the hint of area that it will need to provide. -The Cache uses several threads to request biomes from the underlying source to fill that area. -While the area is being filled, requests for biomes may already come, such requests are answered with baLater if no data yet. -*/ - -#pragma once - - - - - -#include "BiomeSource.h" -#include "../src/OSSupport/IsThread.h" - - - - - -class cBiomeCache : - public cBiomeSource -{ -public: - cBiomeCache(void); - ~cBiomeCache(); - - // cBiomeSource overrides: - virtual eAvailability GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) override; - virtual void HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) override; - - void SetSource(cBiomeSource * a_Source); // Takes ownership of the source ptr - -protected: - class cItem - { - public: - cItem(int a_ChunkX, int a_ChunkZ); - - int m_ChunkX; - int m_ChunkZ; - bool m_IsValid; - cChunkDef::BiomeMap m_Biomes; - } ; - - typedef cItem * pItem; - typedef std::list cItems; - - class cThread : - public cIsThread - { - typedef cIsThread super; - - public: - cThread(cBiomeCache & a_Parent); - - // cIsThread overrides: - virtual void Execute(void) override; - - protected: - cBiomeCache & m_Parent; - } ; - - typedef std::list cThreads; - - cBiomeSource * m_Source; - - cCriticalSection m_CS; - int m_BaseX; ///< MinChunkX for the m_Available rectangle - int m_BaseZ; ///< MinChunkZ for the m_Available rectangle - int m_Width; ///< Width of the m_Available rectangle - int m_Height; ///< Height of the m_Available rectangle - pItem * m_Available; ///< Items that have already been processed (baNow or baNever), [x + m_Width * z] - cItems m_Queue; ///< Items that are queued for processing (baLater) - cItems m_Pool; ///< Items that are not needed anymore, can be reused for other coords - - cEvent m_evtQueued; // Triggerred when an item is added to m_Queue - - cThreads m_Threads; // Threads that update the cache. - bool m_IsTerminatingThreads; // Set to true to indicate to all threads that they should exit - - /// Removes from a_Items all items that are outside of the given coords, moves those into m_Pool - void FilterOutItems(cItems & a_Items, int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ); - - /// Processes one item from m_Queue into m_Available. Blocks if m_Queue is empty; respects m_IsTerminatingThreads - void thrProcessQueueItem(void); -} ; - - - - diff --git a/Tools/BiomeVisualiser/BiomeColors.cpp b/Tools/BiomeVisualiser/BiomeColors.cpp deleted file mode 100644 index 1fd0cb7a0..000000000 --- a/Tools/BiomeVisualiser/BiomeColors.cpp +++ /dev/null @@ -1,114 +0,0 @@ - -// BiomeColors.cpp - -// Implements the g_BiomeColors[] array preparation based on a stored biome-to-color map - -#include "Globals.h" -#include "BiomeColors.h" - - - - - -int g_BiomeColors[256]; - - - - - -static struct -{ - EMCSBiome Biome; - int Color; -} g_BiomeColorMap[] = -{ - { biOcean, 0x000070 }, - { biPlains, 0x8db360 }, - { biDesert, 0xfa9418 }, - { biExtremeHills, 0x606060 }, - { biForest, 0x056621 }, - { biTaiga, 0x0b6659 }, - { biSwampland, 0x2fffda }, - { biRiver, 0x3030af }, - { biHell, 0x7f0000 }, - { biSky, 0x007fff }, - { biFrozenOcean, 0xa0a0df }, - { biFrozenRiver, 0xa0a0ff }, - { biIcePlains, 0xffffff }, - { biIceMountains, 0xa0a0a0 }, - { biMushroomIsland, 0xff00ff }, - { biMushroomShore, 0xa000ff }, - { biBeach, 0xfade55 }, - { biDesertHills, 0xd25f12 }, - { biForestHills, 0x22551c }, - { biTaigaHills, 0x163933 }, - { biExtremeHillsEdge, 0x7f8f7f }, - { biJungle, 0x537b09 }, - { biJungleHills, 0x2c4205 }, - - { biJungleEdge, 0x628b17 }, - { biDeepOcean, 0x000030 }, - { biStoneBeach, 0xa2a284 }, - { biColdBeach, 0xfaf0c0 }, - { biBirchForest, 0x307444 }, - { biBirchForestHills, 0x1f5f32 }, - { biRoofedForest, 0x40511a }, - { biColdTaiga, 0x31554a }, - { biColdTaigaHills, 0x597d72 }, - { biMegaTaiga, 0x596651 }, - { biMegaTaigaHills, 0x596659 }, - { biExtremeHillsPlus, 0x507050 }, - { biSavanna, 0xbdb25f }, - { biSavannaPlateau, 0xa79d64 }, - { biMesa, 0xd94515 }, - { biMesaPlateauF, 0xb09765 }, - { biMesaPlateau, 0xca8c65 }, - - // M variants: - { biSunflowerPlains, 0xb5db88 }, - { biDesertM, 0xffbc40 }, - { biExtremeHillsM, 0x888888 }, - { biFlowerForest, 0x2d8e49 }, - { biTaigaM, 0x338e81 }, - { biSwamplandM, 0x07f9b2 }, - { biIcePlainsSpikes, 0xb4dcdc }, - { biJungleM, 0x7ba331 }, - { biJungleEdgeM, 0x628b17 }, - { biBirchForestM, 0x589c6c }, - { biBirchForestHillsM, 0x47875a }, - { biRoofedForestM, 0x687942 }, - { biColdTaigaM, 0x243f36 }, - { biMegaSpruceTaiga, 0x454f3e }, - { biMegaSpruceTaigaHills, 0x454f4e }, - { biExtremeHillsPlusM, 0x789878 }, - { biSavannaM, 0xe5da87 }, - { biSavannaPlateauM, 0xa79d74 }, - { biMesaBryce, 0xff6d3d }, - { biMesaPlateauFM, 0xd8bf8d }, - { biMesaPlateauM, 0xf2b48d }, -} ; - - - - - -static class cBiomeColorsInitializer -{ -public: - cBiomeColorsInitializer(void) - { - // Reset all colors to gray: - for (size_t i = 0; i < ARRAYCOUNT(g_BiomeColors); i++) - { - g_BiomeColors[i] = 0x7f7f7f; - } - for (size_t i = 0; i < ARRAYCOUNT(g_BiomeColorMap); i++) - { - g_BiomeColors[g_BiomeColorMap[i].Biome] = g_BiomeColorMap[i].Color; - } - } -} g_Initializer; - - - - diff --git a/Tools/BiomeVisualiser/BiomeColors.h b/Tools/BiomeVisualiser/BiomeColors.h deleted file mode 100644 index 0cb0f578c..000000000 --- a/Tools/BiomeVisualiser/BiomeColors.h +++ /dev/null @@ -1,15 +0,0 @@ - -// BiomeColors.h - -// Declares the g_BiomeColors[] array used for biome color lookup - - - - - -extern int g_BiomeColors[256]; - - - - - diff --git a/Tools/BiomeVisualiser/BiomeRenderer.cpp b/Tools/BiomeVisualiser/BiomeRenderer.cpp deleted file mode 100644 index c0123c08a..000000000 --- a/Tools/BiomeVisualiser/BiomeRenderer.cpp +++ /dev/null @@ -1,119 +0,0 @@ - -// BiomeRenderer.cpp - -// Implements the cBiomeRenderer class representing the rendering engine - -#include "Globals.h" -#include "BiomeRenderer.h" -#include "Pixmap.h" -#include "Timer.h" -#include "BiomeColors.h" - - - - - -cBiomeRenderer::cBiomeRenderer(void) : - m_OriginX(160), - m_OriginY(160), - m_Zoom(1) -{ -} - - - - -void cBiomeRenderer::SetSource(cBiomeSource * a_Source) -{ - m_Cache.SetSource(a_Source); -} - - - - - -bool cBiomeRenderer::Render(cPixmap & a_Pixmap) -{ - cTimer Timer("cBiomeRenderer::Render"); - - int Wid = a_Pixmap.GetWidth(); - int Hei = a_Pixmap.GetHeight(); - - // Hint the approximate view area to the biome source so that it can adjust its caches: - int MinBlockX = ( - m_OriginX) * m_Zoom; - int MaxBlockX = (Wid - m_OriginX) * m_Zoom; - int MinBlockZ = ( - m_OriginY) * m_Zoom; - int MaxBlockZ = (Hei - m_OriginY) * m_Zoom; - m_Cache.HintViewArea(MinBlockX / 16 - 1, MaxBlockX / 16 + 1, MinBlockZ / 16 - 1, MaxBlockZ / 16 + 1); - - // Hold one current chunk of biome data: - int CurChunkX = -10000; - int CurChunkZ = -10000; - cChunkDef::BiomeMap CurBiomes; - - bool res = false; - - for (int y = 0; y < Hei; y++) - { - int BlockZ = (y - m_OriginY) * m_Zoom; - int ChunkZ = (BlockZ >= 0) ? (BlockZ / 16) : ((BlockZ + 1) / 16 - 1); - int RelZ = BlockZ - ChunkZ * 16; - for (int x = 0; x < Wid; x++) - { - int BlockX = (x - m_OriginX) * m_Zoom; - int ChunkX = (BlockX >= 0) ? (BlockX / 16) : ((BlockX + 1) / 16 - 1); - int RelX = BlockX - ChunkX * 16; - if ((ChunkZ != CurChunkZ) || (ChunkX != CurChunkX)) - { - CurChunkX = ChunkX; - CurChunkZ = ChunkZ; - switch (m_Cache.GetBiome(CurChunkX, CurChunkZ, CurBiomes)) - { - case cBiomeSource::baLater: - { - res = true; - // fallthrough: - } - case cBiomeSource::baNever: - { - for (int i = 0; i < ARRAYCOUNT(CurBiomes); i++) - { - CurBiomes[i] = biInvalidBiome; - } - break; - } - } // switch (Biome availability) - } - EMCSBiome Biome = cChunkDef::GetBiome(CurBiomes, RelX, RelZ); - a_Pixmap.SetPixel(x, y, GetBiomeColor(Biome)); - } // for x - } // for y - return res; -} - - - - - -int cBiomeRenderer::GetBiomeColor(EMCSBiome a_Biome) -{ - if ((a_Biome < 0) || (a_Biome >= ARRAYCOUNT(g_BiomeColors))) - { - return 0xff0000; - } - return g_BiomeColors[a_Biome]; -} - - - - - -void cBiomeRenderer::MoveViewBy(int a_OffsX, int a_OffsY) -{ - m_OriginX += a_OffsX; - m_OriginY += a_OffsY; -} - - - - diff --git a/Tools/BiomeVisualiser/BiomeRenderer.h b/Tools/BiomeVisualiser/BiomeRenderer.h deleted file mode 100644 index 752b61811..000000000 --- a/Tools/BiomeVisualiser/BiomeRenderer.h +++ /dev/null @@ -1,55 +0,0 @@ - -// BiomeRenderer.h - -// Declares the cBiomeRenderer class representing the rendering engine - - - - - -#pragma once - -#include "BiomeCache.h" - - - - - -// fwd: Pixmap.h -class cPixmap; - - - - - -class cBiomeRenderer -{ -public: - cBiomeRenderer(void); - - void SetSource(cBiomeSource * a_Source); // Takes ownership of the source - - /// Renders the biomes into the given pixmap. Returns true if some biome data was missing and can be retrieved later - bool Render(cPixmap & a_Pixmap); - - /// Returns the RGB color value for the specified biome - int GetBiomeColor(EMCSBiome a_Biome); - - void MoveViewBy(int a_OffsX, int a_OffsY); - - void SetZoom(int a_NewZoom) - { - m_Zoom = a_NewZoom; - } - -protected: - cBiomeCache m_Cache; - - int m_OriginX; - int m_OriginY; - int m_Zoom; -} ; - - - - diff --git a/Tools/BiomeVisualiser/BiomeSource.h b/Tools/BiomeVisualiser/BiomeSource.h deleted file mode 100644 index 4a5153457..000000000 --- a/Tools/BiomeVisualiser/BiomeSource.h +++ /dev/null @@ -1,37 +0,0 @@ - -// BiomeSource.h - -// Declares the cBiomeSource abstract class used as an interface for getting biomes from any source - -#pragma once - - - - - -#include "ChunkDef.h" - - - - - -class cBiomeSource abstract -{ -public: - enum eAvailability - { - baNow, // Data returned now - baLater, // Data not returned, but will be available later, try again after a while - baNever, // Data not returned, will not be available at all - } ; - - /// Fills a_Biomes with the biomes for the chunk specified - virtual eAvailability GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) = 0; - - /// Used to inform the source about the view area that will be queried in the near future. - virtual void HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) = 0; -} ; - - - - diff --git a/Tools/BiomeVisualiser/BiomeViewWnd.cpp b/Tools/BiomeVisualiser/BiomeViewWnd.cpp deleted file mode 100644 index 7fb61c062..000000000 --- a/Tools/BiomeVisualiser/BiomeViewWnd.cpp +++ /dev/null @@ -1,247 +0,0 @@ - -// BiomeViewWnd.cpp - -// Implements the cBiomeViewWnd class representing the window that displays biomes - -#include "Globals.h" -#include "BiomeViewWnd.h" -#include "BiomeCache.h" -#include "GeneratorBiomeSource.h" -#include "iniFile/iniFile.h" - - - - - -const int TIMER_RERENDER = 1200; - - - - - -cBiomeViewWnd::cBiomeViewWnd(void) : - m_Wnd(NULL), - m_Thunk(&cBiomeViewWnd::WndProc, this), - m_IsLButtonDown(false) -{ -} - - - - - -bool cBiomeViewWnd::Create(HWND a_ParentWnd, LPCTSTR a_Title) -{ - ASSERT(m_Wnd == NULL); - - InitBiomeView(); - - // Create a regular STATIC window, then override its window procedure with our own. No need for obnoxious RegisterWindowClass() stuff. - m_Wnd = CreateWindow("STATIC", a_Title, WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 400, 300, a_ParentWnd, NULL, GetModuleHandle(NULL), NULL); - if (m_Wnd == NULL) - { - LOGERROR("Cannot create main window: %d", GetLastError()); - return false; - } - SetWindowLongPtr(m_Wnd, GWLP_WNDPROC, m_Thunk); - - return true; -} - - - - - -void cBiomeViewWnd::InitBiomeView(void) -{ - cIniFile IniFile; - IniFile.ReadFile("world.ini"); - int Seed = IniFile.GetValueSetI("Generator", "Seed", 0); - bool CacheOffByDefault = false; - m_BiomeGen = cBiomeGen::CreateBiomeGen(IniFile, Seed, CacheOffByDefault); - m_Renderer.SetSource(new cGeneratorBiomeSource(m_BiomeGen)); - IniFile.WriteFile("world.ini"); -} - - - - - -void cBiomeViewWnd::SetZoom(int a_NewZoom) -{ - m_Renderer.SetZoom(a_NewZoom); - Redraw(); -} - - - - - -void cBiomeViewWnd::Redraw(void) -{ - if (m_Renderer.Render(m_Pixmap)) - { - SetTimer(m_Wnd, TIMER_RERENDER, 200, NULL); - } - InvalidateRect(m_Wnd, NULL, FALSE); -} - - - - - -LRESULT cBiomeViewWnd::WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam) -{ - switch (a_Msg) - { - case WM_CHAR: return OnChar (wParam, lParam); - case WM_CLOSE: return OnClose (); - case WM_COMMAND: return OnCommand (wParam, lParam); - case WM_LBUTTONDOWN: return OnLButtonDown(wParam, lParam); - case WM_LBUTTONUP: return OnLButtonUp (wParam, lParam); - case WM_MOUSEMOVE: return OnMouseMove (wParam, lParam); - case WM_PAINT: return OnPaint (); - case WM_TIMER: return OnTimer (wParam); - } - return ::DefWindowProc(a_Wnd, a_Msg, wParam, lParam); -} - - - - - -LRESULT cBiomeViewWnd::OnChar(WPARAM wParam, LPARAM lParam) -{ - switch (wParam) - { - case '1': SetZoom(1); break; - case '2': SetZoom(2); break; - case '3': SetZoom(3); break; - case '4': SetZoom(4); break; - case '5': SetZoom(5); break; - case '6': SetZoom(6); break; - case '7': SetZoom(7); break; - case '8': SetZoom(8); break; - case 27: - { - // Esc pressed, exit - PostQuitMessage(0); - break; - } - } - return 0; -} - - - - - -LRESULT cBiomeViewWnd::OnClose(void) -{ - PostQuitMessage(0); - return 0; -} - - - - - -LRESULT cBiomeViewWnd::OnCommand(WPARAM wParam, LPARAM lParam) -{ - // TODO: Handle menu commands, when we get menu - return 0; -} - - - - - -LRESULT cBiomeViewWnd::OnLButtonDown(WPARAM wParam, LPARAM lParam) -{ - m_IsLButtonDown = true; - GetCursorPos(&m_MouseDown); - return 0; -} - - - - - -LRESULT cBiomeViewWnd::OnMouseMove(WPARAM wParam, LPARAM lParam) -{ - if (!m_IsLButtonDown) - { - return 0; - } - POINT pnt; - GetCursorPos(&pnt); - m_Renderer.MoveViewBy(pnt.x - m_MouseDown.x, pnt.y - m_MouseDown.y); - m_MouseDown = pnt; - Redraw(); - return 0; -} - - - - - -LRESULT cBiomeViewWnd::OnLButtonUp(WPARAM wParam, LPARAM lParam) -{ - OnMouseMove(wParam, lParam); // Last movement - if the mouse move hasn't been reported due to speed - m_IsLButtonDown = false; - InvalidateRect(m_Wnd, NULL, FALSE); - return 0; -} - - - - - -LRESULT cBiomeViewWnd::OnPaint(void) -{ - PAINTSTRUCT ps; - HDC DC = BeginPaint(m_Wnd, &ps); - - RECT rc; - GetClientRect(m_Wnd, &rc); - int Wid = rc.right - rc.left; - int Hei = rc.bottom - rc.top; - if ((m_Pixmap.GetWidth() != Wid) || (m_Pixmap.GetHeight() != Hei)) - { - m_Pixmap.SetSize(Wid, Hei); - if (m_Renderer.Render(m_Pixmap)) - { - SetTimer(m_Wnd, TIMER_RERENDER, 200, NULL); - } - } - - m_Pixmap.DrawToDC(DC, 0, 0); - - EndPaint(m_Wnd, &ps); - return 0; -} - - - - - -LRESULT cBiomeViewWnd::OnTimer(WPARAM wParam) -{ - switch (wParam) - { - case TIMER_RERENDER: - { - if (!m_Renderer.Render(m_Pixmap)) - { - KillTimer(m_Wnd, TIMER_RERENDER); - } - InvalidateRect(m_Wnd, NULL, FALSE); - break; - } - } - return 0; -} - - - - diff --git a/Tools/BiomeVisualiser/BiomeViewWnd.h b/Tools/BiomeVisualiser/BiomeViewWnd.h deleted file mode 100644 index 70c5e38f2..000000000 --- a/Tools/BiomeVisualiser/BiomeViewWnd.h +++ /dev/null @@ -1,69 +0,0 @@ - -// BiomeViewWnd.h - -// Declares the cBiomeViewWnd class representing the window that displays biomes - - - - - -#pragma once - -#include "WndProcThunk.h" -#include "BiomeRenderer.h" -#include "BiomeCache.h" -#include "Pixmap.h" - - - - - -// fwd: -class cBiomeGen; - - - - - -class cBiomeViewWnd -{ -public: - cBiomeViewWnd(void); - - bool Create(HWND a_ParentWnd, LPCTSTR a_Title); - -protected: - HWND m_Wnd; - CWndProcThunk m_Thunk; - - cBiomeRenderer m_Renderer; - cPixmap m_Pixmap; - - /// The generator that is to be visualised - cBiomeGen * m_BiomeGen; - - bool m_IsLButtonDown; - POINT m_MouseDown; - - - void InitBiomeView(void); - - void SetZoom(int a_NewZoom); - void Redraw(void); - - LRESULT WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam); - - // Message handlers: - LRESULT OnChar (WPARAM wParam, LPARAM lParam); - LRESULT OnClose (void); - LRESULT OnCommand (WPARAM wParam, LPARAM lParam); - LRESULT OnLButtonDown(WPARAM wParam, LPARAM lParam); - LRESULT OnMouseMove (WPARAM wParam, LPARAM lParam); - LRESULT OnLButtonUp (WPARAM wParam, LPARAM lParam); - LRESULT OnPaint (void); - LRESULT OnTimer (WPARAM wParam); -} ; - - - - diff --git a/Tools/BiomeVisualiser/BiomeVisualiser.cpp b/Tools/BiomeVisualiser/BiomeVisualiser.cpp deleted file mode 100644 index a36111d77..000000000 --- a/Tools/BiomeVisualiser/BiomeVisualiser.cpp +++ /dev/null @@ -1,52 +0,0 @@ - -// BiomeVisualiser.cpp - -// Implements the cBiomeVisualiser class representing the entire app. Also implements the WinMain() entrypoint - -#include "Globals.h" -#include "time.h" -#include "BiomeVisualiser.h" - - - - - -int WINAPI WinMain(HINSTANCE a_Instance, HINSTANCE a_PrevInstance, LPSTR a_CmdLine, int a_ShowCmd) -{ - cBiomeVisualiser App; - return App.Run(); -} - - - - - -cBiomeVisualiser::cBiomeVisualiser(void) : - m_Logger(new cMCLogger(Printf("BiomeVisualiser_%08x.log", time(NULL)))) -{ -} - - - - - -int cBiomeVisualiser::Run(void) -{ - if (!m_MainWnd.Create(GetDesktopWindow(), TEXT("BiomeVisualiser"))) - { - LOGERROR("Cannot create main window: %d", GetLastError()); - return 1; - } - - MSG msg; - while (GetMessage(&msg, NULL, 0, 0)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } // while (GetMessage) - return msg.lParam; -} - - - - diff --git a/Tools/BiomeVisualiser/BiomeVisualiser.h b/Tools/BiomeVisualiser/BiomeVisualiser.h deleted file mode 100644 index 4f8ce7513..000000000 --- a/Tools/BiomeVisualiser/BiomeVisualiser.h +++ /dev/null @@ -1,31 +0,0 @@ - -// BiomeVisualiser.h - -// Declares the cBiomeVisualiser class representing the entire application - - - - - -#include "BiomeViewWnd.h" - - - - - -class cBiomeVisualiser -{ -public: - cBiomeVisualiser(void); - - int Run(void); - -protected: - cBiomeViewWnd m_MainWnd; - - cMCLogger * m_Logger; -} ; - - - - diff --git a/Tools/BiomeVisualiser/BiomeVisualiser.sln b/Tools/BiomeVisualiser/BiomeVisualiser.sln deleted file mode 100644 index bdfb586b1..000000000 --- a/Tools/BiomeVisualiser/BiomeVisualiser.sln +++ /dev/null @@ -1,23 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 10.00 -# Visual C++ Express 2008 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BiomeVisualiser", "BiomeVisualiser.vcproj", "{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release profiled|Win32 = Release profiled|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Debug|Win32.ActiveCfg = Debug|Win32 - {6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Debug|Win32.Build.0 = Debug|Win32 - {6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release profiled|Win32.ActiveCfg = Release profiled|Win32 - {6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release profiled|Win32.Build.0 = Release profiled|Win32 - {6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release|Win32.ActiveCfg = Release|Win32 - {6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/Tools/BiomeVisualiser/BiomeVisualiser.vcproj b/Tools/BiomeVisualiser/BiomeVisualiser.vcproj deleted file mode 100644 index 3de564ad4..000000000 --- a/Tools/BiomeVisualiser/BiomeVisualiser.vcproj +++ /dev/null @@ -1,527 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Tools/BiomeVisualiser/GeneratorBiomeSource.h b/Tools/BiomeVisualiser/GeneratorBiomeSource.h deleted file mode 100644 index 751aed245..000000000 --- a/Tools/BiomeVisualiser/GeneratorBiomeSource.h +++ /dev/null @@ -1,42 +0,0 @@ - -// GeneratorBiomeSource.h - -// Declares the cGeneratorBiomeSource that adapts a cBiomeGen into a cBiomeSource - -#include "../src/Generating/BioGen.h" -#include "BiomeSource.h" - - - - - -class cGeneratorBiomeSource : - public cBiomeSource -{ -public: - cGeneratorBiomeSource(cBiomeGen * a_Generator) : m_Generator(a_Generator) {} // Takes ownership of the generator ptr - - ~cGeneratorBiomeSource() - { - delete m_Generator; - } - - // cBiomeSource overrides: - virtual eAvailability GetBiome(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap & a_Biomes) override - { - m_Generator->GenBiomes(a_ChunkX, a_ChunkZ, a_Biomes); - return baNow; - } - - virtual void HintViewArea(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ) override - { - // Nothing needed - } - -protected: - cBiomeGen * m_Generator; -} ; - - - - diff --git a/Tools/BiomeVisualiser/Pixmap.cpp b/Tools/BiomeVisualiser/Pixmap.cpp deleted file mode 100644 index 1a80cf465..000000000 --- a/Tools/BiomeVisualiser/Pixmap.cpp +++ /dev/null @@ -1,120 +0,0 @@ - -// Pixmap.cpp - -// Implements the cPixmap class that represents a RGB pixmap and allows simple operations on it - -#include "Globals.h" -#include "Pixmap.h" - - - - - -cPixmap::cPixmap(void) : - m_Width(0), - m_Height(0), - m_Stride(0), - m_Pixels(NULL) -{ -} - - - - - -cPixmap::cPixmap(int a_Width, int a_Height) : - m_Width(0), - m_Height(0), - m_Stride(0), - m_Pixels(NULL) -{ - SetSize(a_Width, a_Height); -} - - - - - -cPixmap::~cPixmap() -{ - delete m_Pixels; -} - - - - - -void cPixmap::SetSize(int a_Width, int a_Height) -{ - delete m_Pixels; - m_Pixels = new int[a_Width * a_Height]; - m_Width = a_Width; - m_Height = a_Height; - m_Stride = m_Width; // Currently we don't need a special stride value, but let's support it for the future :) -} - - - - - -void cPixmap::SetPixel(int a_X, int a_Y, int a_Color) -{ - ASSERT(a_X >= 0); - ASSERT(a_X < m_Width); - ASSERT(a_Y >= 0); - ASSERT(a_Y < m_Height); - - m_Pixels[a_X + a_Y * m_Stride] = a_Color; -} - - - - - -int cPixmap::GetPixel(int a_X, int a_Y) const -{ - ASSERT(a_X >= 0); - ASSERT(a_X < m_Width); - ASSERT(a_Y >= 0); - ASSERT(a_Y < m_Height); - - return m_Pixels[a_X + a_Y * m_Stride]; -} - - - - - -void cPixmap::Fill(int a_Color) -{ - int NumElements = m_Height * m_Stride; - for (int i = 0; i < NumElements; i++) - { - m_Pixels[i] = a_Color; - } -} - - - - - -void cPixmap::DrawToDC(HDC a_DC, int a_OriginX, int a_OriginY) -{ - BITMAPINFO bmi; - bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); - bmi.bmiHeader.biWidth = m_Width; - bmi.bmiHeader.biHeight = -m_Height; // Negative, we are top-down, unlike BMPs - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = m_Stride * m_Height * 4; - bmi.bmiHeader.biXPelsPerMeter = 1440; - bmi.bmiHeader.biYPelsPerMeter = 1440; - bmi.bmiHeader.biClrUsed = 0; - bmi.bmiHeader.biClrImportant = 0; - SetDIBitsToDevice(a_DC, a_OriginX, a_OriginY, m_Width, m_Height, 0, 0, 0, m_Height, m_Pixels, &bmi, DIB_RGB_COLORS); -} - - - - diff --git a/Tools/BiomeVisualiser/Pixmap.h b/Tools/BiomeVisualiser/Pixmap.h deleted file mode 100644 index e50f6e946..000000000 --- a/Tools/BiomeVisualiser/Pixmap.h +++ /dev/null @@ -1,39 +0,0 @@ - -// Pixmap.h - -// Declares a cPixmap class that represents a RGB pixmap and allows simple operations on it - -#pragma once - - - - - -class cPixmap -{ -public: - cPixmap(void); - cPixmap(int a_Width, int a_Height); - ~cPixmap(); - - void SetSize(int a_Width, int a_Height); - - int GetWidth (void) const { return m_Width; } - int GetHeight(void) const { return m_Height; } - - void SetPixel(int a_X, int a_Y, int a_Color); - int GetPixel(int a_X, int a_Y) const; - void Fill(int a_Color); - - void DrawToDC(HDC a_DC, int a_OriginX, int a_OriginY); - -protected: - int m_Width; - int m_Height; - int m_Stride; - int * m_Pixels; -} ; - - - - diff --git a/Tools/BiomeVisualiser/Timer.h b/Tools/BiomeVisualiser/Timer.h deleted file mode 100644 index 78c4b42c7..000000000 --- a/Tools/BiomeVisualiser/Timer.h +++ /dev/null @@ -1,40 +0,0 @@ - -// Timer.h - -// Declares the cTimer class representing a RAII class that measures time from its creation till its destruction - - - - - -#pragma once - -#include "time.h" - - - - - -class cTimer -{ -public: - cTimer(const AString & a_Title) : - m_Title(a_Title), - m_StartTime(clock()) - { - } - - ~cTimer() - { - clock_t NumTicks = clock() - m_StartTime; - LOG("%s took %d ticks (%.02f sec)", m_Title.c_str(), NumTicks, (double)NumTicks / CLOCKS_PER_SEC); - } - -protected: - AString m_Title; - clock_t m_StartTime; -} ; - - - - diff --git a/Tools/BiomeVisualiser/WndProcThunk.h b/Tools/BiomeVisualiser/WndProcThunk.h deleted file mode 100644 index da995eb5f..000000000 --- a/Tools/BiomeVisualiser/WndProcThunk.h +++ /dev/null @@ -1,143 +0,0 @@ - -// WndProcThunk.h - -// Interfaces to the CWndProcThunk class responsible for WNDPROC class-thunking -// For details, see http://www.hackcraft.net/cpp/windowsThunk/thiscall/ -// Also available is a CDlgProcThunk class doing the same work for DIALOGPROC - -// MD: Made NX-compat by allocating the code structure using VirtualAlloc(..., PAGE_EXECUTE_READWRITE) - - - - - -// fwd: -template class CWndProcThunk; - - - - - -#ifndef WNDPROCTHUNK_H_INCLUDED -#define WNDPROCTHUNK_H_INCLUDED - - - - -template inline To union_cast(From fr) throw() -{ - union - { - From f; - To t; - } uc; - uc.f = fr; - return uc.t; -} - - - - - -#pragma warning(push) -#pragma warning(disable : 4355) - -#if defined(_M_IX86) - -#pragma pack(push,1) - -template class CWndProcThunk -{ - typedef ::LRESULT (W::* WndProc)(::HWND, ::UINT, ::WPARAM, ::LPARAM); - typedef CWndProcThunk ThisClass; - - struct SCode - { - BYTE m_mov; // mov ECX, m_this - W * m_this; // - BYTE m_jmp; // jmp m_relproc - ptrdiff_t m_relproc; // relative jmp - }; - - SCode * Code; - -public: - ThisClass(WndProc proc, W * obj) - { - Code = (SCode *)VirtualAlloc(NULL, sizeof(SCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE); - Code->m_mov = 0xB9, - Code->m_this = obj, - Code->m_jmp = 0xE9, - Code->m_relproc = union_cast(proc) - reinterpret_cast(Code) - sizeof(*Code); - ::FlushInstructionCache(::GetCurrentProcess(), Code, sizeof(*Code)); - } - - virtual ~CWndProcThunk() - { - VirtualFree(Code, sizeof(*Code), MEM_RELEASE); - Code = NULL; - } - - operator ::WNDPROC() const {return reinterpret_cast<::WNDPROC>(Code); } - operator ::LONG_PTR() const {return reinterpret_cast<::LONG_PTR>(Code); } -} ; - - - - - -template class CDlgProcThunk -{ - typedef ::BOOL (W::* DlgProc)(::HWND, ::UINT, ::WPARAM, ::LPARAM); - typedef CDlgProcThunk ThisClass; - - struct SCode - { - BYTE m_mov; // mov ECX, m_this - W * m_this; // - BYTE m_jmp; // jmp m_relproc - ptrdiff_t m_relproc; // relative jmp - }; - - SCode * Code; - -public: - CDlgProcThunk(DlgProc proc, W * obj) - { - Code = (SCode *)VirtualAlloc(NULL, sizeof(SCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE); - Code->m_mov = 0xB9, - Code->m_this = obj, - Code->m_jmp = 0xE9, - Code->m_relproc = union_cast(proc) - reinterpret_cast(Code) - sizeof(*Code); - ::FlushInstructionCache(::GetCurrentProcess(), Code, sizeof(*Code)); - } - - virtual ~CDlgProcThunk() - { - VirtualFree(Code, sizeof(*Code), MEM_RELEASE); - Code = NULL; - } - - operator ::DLGPROC() const {return reinterpret_cast<::DLGPROC>(Code); } - operator ::LONG_PTR() const {return reinterpret_cast<::LONG_PTR>(Code); } -} ; - - - - - - #pragma pack(pop) - -#else // _M_IX86 - #error Only X86 supported -#endif - - - - - -#endif // WNDPROCTHUNK_H_INCLUDED - - - - diff --git a/Tools/BiomeVisualiser/profile_run.cmd b/Tools/BiomeVisualiser/profile_run.cmd deleted file mode 100644 index d4826d06a..000000000 --- a/Tools/BiomeVisualiser/profile_run.cmd +++ /dev/null @@ -1,70 +0,0 @@ -@echo off -:: -:: Profiling using a MSVC standalone profiler -:: -:: See http://www.codeproject.com/Articles/144643/Profiling-of-C-Applications-in-Visual-Studio-for-F for details -:: - - - - -set pt="C:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Performance Tools" -set appdir="Release profiled" -set app="Release profiled\BiomeVisualiser.exe" -set args="" - -:: outputdir is relative to appdir! -set outputdir=Profiling -set output=profile.vsp - - - - - -::Create the output directory, if it didn't exist -mkdir %outputdir% - - - - - -:: Start the profiler -%pt%\vsperfcmd /start:sample /output:%outputdir%\%output% -if errorlevel 1 goto haderror - -:: Launch the application via the profiler -%pt%\vsperfcmd /launch:%app% /args:%args% -if errorlevel 1 goto haderror - -:: Shut down the profiler (this command waits, until the application is terminated) -%pt%\vsperfcmd /shutdown -if errorlevel 1 goto haderror - - - - - -:: cd to outputdir, so that the reports are generated there -cd %outputdir% - -:: generate the report files (.csv) -%pt%\vsperfreport /summary:all %output% /symbolpath:"srv*C:\Programovani\Symbols*http://msdl.microsoft.com/download/symbols" -if errorlevel 1 goto haderror - - - - - -goto finished - - - - -:haderror -echo An error was encountered -pause - - - - -:finished diff --git a/Tools/QtBiomeVisualiser/.gitignore b/Tools/QtBiomeVisualiser/.gitignore new file mode 100644 index 000000000..c1b62a8a7 --- /dev/null +++ b/Tools/QtBiomeVisualiser/.gitignore @@ -0,0 +1,2 @@ +*.pro.user +*.pro.user.* diff --git a/Tools/QtBiomeVisualiser/BiomeView.cpp b/Tools/QtBiomeVisualiser/BiomeView.cpp new file mode 100644 index 000000000..be01fd104 --- /dev/null +++ b/Tools/QtBiomeVisualiser/BiomeView.cpp @@ -0,0 +1,246 @@ +#include "Globals.h" +#include "BiomeView.h" +#include "Chunk.h" +#include +#include + + + + + +BiomeView::BiomeView(QWidget * parent) : + super(parent), + m_X(0), + m_Z(0), + m_Zoom(1) +{ + // Create the image used for undefined chunks: + int offset = 0; + for (int y = 0; y < 16; y++) + { + for (int x = 0; x < 16; x++) + { + uchar color = (((x & 8) ^ (y & 8)) == 0) ? 0x44 : 0x88; + m_EmptyChunkImage[offset++] = color; + m_EmptyChunkImage[offset++] = color; + m_EmptyChunkImage[offset++] = color; + m_EmptyChunkImage[offset++] = 0xff; + } + } + + // Create the startup image: + redraw(); + + // Add a chunk-update callback mechanism: + connect(&m_Cache, SIGNAL(chunkAvailable(int, int)), this, SLOT(chunkAvailable(int, int))); +} + + + + +QSize BiomeView::minimumSizeHint() const +{ + return QSize(300, 300); +} + + + + + +QSize BiomeView::sizeHint() const +{ + return QSize(800, 600); +} + + + + + +void BiomeView::setChunkSource(std::shared_ptr a_ChunkSource) +{ + // Replace the source in the cache: + m_Cache.setChunkSource(a_ChunkSource); + + // Redraw with the new source: + redraw(); +} + + + + + +void BiomeView::redraw() +{ + if (!hasData()) + { + // No data means no image is displayed, no need to compose: + update(); + return; + } + + int chunksize = 16 * m_Zoom; + + // first find the center block position + int centerchunkx = floor(m_X / 16); + int centerchunkz = floor(m_Z / 16); + // and the center of the screen + int centerx = m_Image.width() / 2; + int centery = m_Image.height() / 2; + // and align for panning + centerx -= (m_X - centerchunkx * 16) * m_Zoom; + centery -= (m_Z - centerchunkz * 16) * m_Zoom; + // now calculate the topleft block on the screen + int startx = centerchunkx - centerx / chunksize - 1; + int startz = centerchunkz - centery / chunksize - 1; + // and the dimensions of the screen in blocks + int blockswide = m_Image.width() / chunksize + 3; + int blockstall = m_Image.height() / chunksize + 3; + + for (int z = startz; z < startz + blockstall; z++) + { + for (int x = startx; x < startx + blockswide; x++) + { + drawChunk(x, z); + } + } + update(); +} + + + + + +void BiomeView::chunkAvailable(int a_ChunkX, int a_ChunkZ) +{ + drawChunk(a_ChunkX, a_ChunkZ); + update(); +} + + + + + +void BiomeView::drawChunk(int a_ChunkX, int a_ChunkZ) +{ + if (!hasData()) + { + return; + } + + //fetch the chunk: + ChunkPtr chunk = m_Cache.fetch(a_ChunkX, a_ChunkZ); + + // Figure out where on the screen this chunk should be drawn: + // first find the center chunk + int centerchunkx = floor(m_X / 16); + int centerchunkz = floor(m_Z / 16); + // and the center chunk screen coordinates + int centerx = m_Image.width() / 2; + int centery = m_Image.height() / 2; + // which need to be shifted to account for panning inside that chunk + centerx -= (m_X - centerchunkx * 16) * m_Zoom; + centery -= (m_Z - centerchunkz * 16) * m_Zoom; + // centerx,y now points to the top left corner of the center chunk + // so now calculate our x,y in relation + double chunksize = 16 * m_Zoom; + centerx += (a_ChunkX - centerchunkx) * chunksize; + centery += (a_ChunkZ - centerchunkz) * chunksize; + + int srcoffset = 0; + uchar * bits = m_Image.bits(); + int imgstride = m_Image.bytesPerLine(); + + int skipx = 0,skipy = 0; + int blockwidth = chunksize, blockheight = chunksize; + // now if we're off the screen we need to crop + if (centerx < 0) + { + skipx = -centerx; + centerx = 0; + } + if (centery < 0) + { + skipy = -centery; + centery = 0; + } + // or the other side, we need to trim + if (centerx + blockwidth > m_Image.width()) + { + blockwidth = m_Image.width() - centerx; + } + if (centery + blockheight > m_Image.height()) + { + blockheight = m_Image.height() - centery; + } + if ((blockwidth <= 0) || (skipx >= blockwidth)) + { + return; + } + int imgoffset = centerx * 4 + centery * imgstride; + + // If the chunk is valid, use its data; otherwise use the empty placeholder: + const uchar * src = m_EmptyChunkImage; + if (chunk.get() != nullptr) + { + src = chunk->getImage(); + } + + // Blit or scale-blit the image: + for (int z = skipy; z < blockheight; z++, imgoffset += imgstride) + { + srcoffset = floor((double)z / m_Zoom) * 16 * 4; + if (m_Zoom == 1.0) + { + memcpy(bits + imgoffset, src + srcoffset + skipx * 4, (blockwidth - skipx) * 4); + } + else + { + int xofs = 0; + for (int x = skipx; x < blockwidth; x++, xofs +=4) + { + memcpy(bits + imgoffset + xofs, src + srcoffset + (int)floor((double)x / m_Zoom) * 4, 4); + } + } + } +} + + + + + +void BiomeView::resizeEvent(QResizeEvent * a_Event) +{ + m_Image = QImage(a_Event->size(), QImage::Format_RGB32); + redraw(); +} + + + + + +void BiomeView::paintEvent(QPaintEvent * a_Event) +{ + QPainter p(this); + if (hasData()) + { + p.drawImage(QPoint(0, 0), m_Image); + } + else + { + p.drawText(a_Event->rect(), Qt::AlignCenter, "No chunk source selected"); + } + p.end(); +} + + + + + +void BiomeView::queueChunkRender(ChunkPtr a_Chunk) +{ + +} + + + + diff --git a/Tools/QtBiomeVisualiser/BiomeView.h b/Tools/QtBiomeVisualiser/BiomeView.h new file mode 100644 index 000000000..c54c66491 --- /dev/null +++ b/Tools/QtBiomeVisualiser/BiomeView.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include "ChunkCache.h" +#include "ChunkSource.h" + + + + + +class BiomeView : + public QWidget +{ + typedef QWidget super; + Q_OBJECT + +public: + explicit BiomeView(QWidget * parent = NULL); + + QSize minimumSizeHint() const; + QSize sizeHint() const; + + /** Replaces the chunk source used by the biome view to get the chunk biome data. + The entire view is then invalidated and regenerated. */ + void setChunkSource(std::shared_ptr a_ChunkSource); + +signals: + +public slots: + /** Redraw the entire widget area. */ + void redraw(); + + /** A specified chunk has become available, redraw it. */ + void chunkAvailable(int a_ChunkX, int a_ChunkZ); + +protected: + double m_X, m_Z; + int m_Zoom; + ChunkCache m_Cache; + QImage m_Image; + + /** Data used for rendering a chunk that hasn't been loaded yet */ + uchar m_EmptyChunkImage[16 * 16 * 4]; + + + /** Draws the specified chunk into m_Image */ + void drawChunk(int a_ChunkX, int a_ChunkZ); + + /** Returns true iff the biome view has been initialized to contain proper biome data. */ + bool hasData(void) const { return m_Cache.hasData(); } + + /** Called when the widget is resized */ + virtual void resizeEvent(QResizeEvent *) override; + + /** Paints the entire widget */ + virtual void paintEvent(QPaintEvent *) override; + + /** Queues the chunk for rendering. */ + void queueChunkRender(ChunkPtr a_Chunk); +}; + + + + + diff --git a/Tools/QtBiomeVisualiser/Chunk.cpp b/Tools/QtBiomeVisualiser/Chunk.cpp new file mode 100644 index 000000000..d3419af9c --- /dev/null +++ b/Tools/QtBiomeVisualiser/Chunk.cpp @@ -0,0 +1,36 @@ +#include "Globals.h" +#include "Globals.h" +#include "Chunk.h" + + + + + +Chunk::Chunk() : + m_IsValid(false) +{ +} + + + + + +const uchar * Chunk::getImage(void) const +{ + ASSERT(m_IsValid); + return m_Image; +} + + + + + +void Chunk::setImage(const Image & a_Image) +{ + memcpy(m_Image, a_Image, sizeof(a_Image)); + m_IsValid = true; +} + + + + diff --git a/Tools/QtBiomeVisualiser/Chunk.h b/Tools/QtBiomeVisualiser/Chunk.h new file mode 100644 index 000000000..03e7bd1b3 --- /dev/null +++ b/Tools/QtBiomeVisualiser/Chunk.h @@ -0,0 +1,40 @@ +#pragma once + +#include + + + + + +class Chunk +{ +public: + /** The type used for storing image data for a chunk. */ + typedef uchar Image[16 * 16 * 4]; + + + Chunk(void); + + /** Returns true iff the chunk data is valid - loaded or generated. */ + bool isValid(void) const { return m_IsValid; } + + /** Returns the image of the chunk's biomes. Assumes that the chunk is valid. */ + const uchar * getImage(void) const; + + /** Sets the image data for this chunk. */ + void setImage(const Image & a_Image); + +protected: + /** Flag that specifies if the chunk data is valid - loaded or generated. */ + bool m_IsValid; + + /** Cached rendered image of this chunk's biomes. Updated in render(). */ + Image m_Image; +}; + +typedef std::shared_ptr ChunkPtr; + + + + + diff --git a/Tools/QtBiomeVisualiser/ChunkCache.cpp b/Tools/QtBiomeVisualiser/ChunkCache.cpp new file mode 100644 index 000000000..b2230def0 --- /dev/null +++ b/Tools/QtBiomeVisualiser/ChunkCache.cpp @@ -0,0 +1,110 @@ +#include "Globals.h" +#include "ChunkCache.h" +#include +#include +#include "ChunkSource.h" +#include "ChunkLoader.h" + + + + + +ChunkCache::ChunkCache(QObject * parent) : + super(parent) +{ + m_Cache.setMaxCost(1024 * 1024 * 1024); // 1 GiB of memory for the cache +} + + + + + +ChunkPtr ChunkCache::fetch(int a_ChunkX, int a_ChunkZ) +{ + // Retrieve from the cache: + quint32 hash = getChunkHash(a_ChunkX, a_ChunkZ); + ChunkPtr * res; + { + QMutexLocker lock(&m_Mtx); + res = m_Cache[hash]; + // If succesful and chunk loaded, return the retrieved value: + if ((res != nullptr) && (*res)->isValid()) + { + return *res; + } + } + + // If the chunk is in cache but not valid, it means it has been already queued for rendering, do nothing now: + if (res != nullptr) + { + return ChunkPtr(nullptr); + } + + // There's no such item in the cache, create it now: + res = new ChunkPtr(new Chunk); + if (res == nullptr) + { + return ChunkPtr(nullptr); + } + { + QMutexLocker lock(&m_Mtx); + m_Cache.insert(hash, res, sizeof(Chunk)); + } + + // Queue the chunk for rendering: + queueChunkRender(a_ChunkX, a_ChunkZ, *res); + + // Return failure, the chunk is not yet rendered: + return ChunkPtr(nullptr); +} + + + + + +void ChunkCache::setChunkSource(std::shared_ptr a_ChunkSource) +{ + // Replace the chunk source: + m_ChunkSource = a_ChunkSource; + + // Clear the cache: + QMutexLocker lock(&m_Mtx); + m_Cache.clear(); +} + + + + + +void ChunkCache::gotChunk(int a_ChunkX, int a_ChunkZ) +{ + emit chunkAvailable(a_ChunkX, a_ChunkZ); +} + + + + + +quint32 ChunkCache::getChunkHash(int a_ChunkX, int a_ChunkZ) +{ + // Simply join the two coords into a single int + // The coords will never be larger than 16-bits, so we can do this safely + return (((static_cast(a_ChunkX) & 0xffff) << 16) | (static_cast(a_ChunkZ) & 0xffff)); +} + + + + + +void ChunkCache::queueChunkRender(int a_ChunkX, int a_ChunkZ, ChunkPtr & a_Chunk) +{ + // Create a new loader task: + ChunkLoader * loader = new ChunkLoader(a_ChunkX, a_ChunkZ, a_Chunk, m_ChunkSource); + connect(loader, SIGNAL(loaded(int, int)), this, SLOT(gotChunk(int, int))); + + QThreadPool::globalInstance()->start(loader); +} + + + + diff --git a/Tools/QtBiomeVisualiser/ChunkCache.h b/Tools/QtBiomeVisualiser/ChunkCache.h new file mode 100644 index 000000000..0efa7fc39 --- /dev/null +++ b/Tools/QtBiomeVisualiser/ChunkCache.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include +#include + + + + + +class Chunk; +typedef std::shared_ptr ChunkPtr; + +class ChunkSource; + + + + + +/** Caches chunk data for reuse */ +class ChunkCache : + public QObject +{ + typedef QObject super; + Q_OBJECT + +public: + explicit ChunkCache(QObject * parent = NULL); + + /** Retrieves the specified chunk from the cache. + Only returns valid chunks; if the chunk is invalid, queues it for rendering and returns an empty ptr. */ + ChunkPtr fetch(int a_ChunkX, int a_ChunkZ); + + /** Replaces the chunk source used by the biome view to get the chunk biome data. + The cache is then invalidated. */ + void setChunkSource(std::shared_ptr a_ChunkSource); + + /** Returns true iff the chunk source has been initialized. */ + bool hasData(void) const { return (m_ChunkSource.get() != nullptr); } + +signals: + void chunkAvailable(int a_ChunkX, int a_ChunkZ); + +protected slots: + void gotChunk(int a_ChunkX, int a_ChunkZ); + +protected: + /** The cache of the chunks */ + QCache m_Cache; + + /** Locks te cache against multithreaded access */ + QMutex m_Mtx; + + /** The source used to get the biome data. */ + std::shared_ptr m_ChunkSource; + + + /** Returns the hash used by the chunk in the cache */ + quint32 getChunkHash(int a_ChunkX, int a_ChunkZ); + + /** Queues the specified chunk for rendering by m_ChunkSource. */ + void queueChunkRender(int a_ChunkX, int a_ChunkZ, ChunkPtr & a_Chunk); +}; + + + + + diff --git a/Tools/QtBiomeVisualiser/ChunkLoader.cpp b/Tools/QtBiomeVisualiser/ChunkLoader.cpp new file mode 100644 index 000000000..3d0123b23 --- /dev/null +++ b/Tools/QtBiomeVisualiser/ChunkLoader.cpp @@ -0,0 +1,29 @@ +#include "Globals.h" +#include "ChunkLoader.h" +#include "ChunkSource.h" + + + + + +ChunkLoader::ChunkLoader(int a_ChunkX, int a_ChunkZ, ChunkPtr a_Chunk, ChunkSourcePtr a_ChunkSource) : + m_ChunkX(a_ChunkX), + m_ChunkZ(a_ChunkZ), + m_Chunk(a_Chunk), + m_ChunkSource(a_ChunkSource) +{ +} + + + + + +void ChunkLoader::run() +{ + m_ChunkSource->getChunkBiomes(m_ChunkX, m_ChunkZ, m_Chunk); + emit loaded(m_ChunkX, m_ChunkZ); +} + + + + diff --git a/Tools/QtBiomeVisualiser/ChunkLoader.h b/Tools/QtBiomeVisualiser/ChunkLoader.h new file mode 100644 index 000000000..3565434b9 --- /dev/null +++ b/Tools/QtBiomeVisualiser/ChunkLoader.h @@ -0,0 +1,43 @@ +#pragma once +#include +#include + + + + +// fwd: +class Chunk; +typedef std::shared_ptr ChunkPtr; + +class ChunkSource; +typedef std::shared_ptr ChunkSourcePtr; + + + + + +class ChunkLoader : + public QObject, + public QRunnable +{ + Q_OBJECT + +public: + ChunkLoader(int a_ChunkX, int a_ChunkZ, ChunkPtr a_Chunk, ChunkSourcePtr a_ChunkSource); + virtual ~ChunkLoader() {} + +signals: + void loaded(int a_ChunkX, int a_ChunkZ); + +protected: + virtual void run() override; + +private: + int m_ChunkX, m_ChunkZ; + ChunkPtr m_Chunk; + ChunkSourcePtr m_ChunkSource; +}; + + + + diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp new file mode 100644 index 000000000..44dcf1fa7 --- /dev/null +++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp @@ -0,0 +1,164 @@ +#include "Globals.h" +#include "ChunkSource.h" +#include "Generating/BioGen.h" + + + + + +/** Map for converting biome values to colors. Initialized from biomeColors[]. */ +static uchar biomeToColor[256 * 4]; + +/** Map for converting biome values to colors. Used to initialize biomeToColor[].*/ +static struct +{ + EMCSBiome m_Biome; + uchar m_Color[3]; +} biomeColors[] = +{ + { biOcean, { 0x00, 0x00, 0x70 }, }, + { biPlains, { 0x8d, 0xb3, 0x60 }, }, + { biDesert, { 0xfa, 0x94, 0x18 }, }, + { biExtremeHills, { 0x60, 0x60, 0x60 }, }, + { biForest, { 0x05, 0x66, 0x21 }, }, + { biTaiga, { 0x0b, 0x66, 0x59 }, }, + { biSwampland, { 0x2f, 0xff, 0xda }, }, + { biRiver, { 0x30, 0x30, 0xaf }, }, + { biHell, { 0x7f, 0x00, 0x00 }, }, + { biSky, { 0x00, 0x7f, 0xff }, }, + { biFrozenOcean, { 0xa0, 0xa0, 0xdf }, }, + { biFrozenRiver, { 0xa0, 0xa0, 0xff }, }, + { biIcePlains, { 0xff, 0xff, 0xff }, }, + { biIceMountains, { 0xa0, 0xa0, 0xa0 }, }, + { biMushroomIsland, { 0xff, 0x00, 0xff }, }, + { biMushroomShore, { 0xa0, 0x00, 0xff }, }, + { biBeach, { 0xfa, 0xde, 0x55 }, }, + { biDesertHills, { 0xd2, 0x5f, 0x12 }, }, + { biForestHills, { 0x22, 0x55, 0x1c }, }, + { biTaigaHills, { 0x16, 0x39, 0x33 }, }, + { biExtremeHillsEdge, { 0x7f, 0x8f, 0x7f }, }, + { biJungle, { 0x53, 0x7b, 0x09 }, }, + { biJungleHills, { 0x2c, 0x42, 0x05 }, }, + + { biJungleEdge, { 0x62, 0x8b, 0x17 }, }, + { biDeepOcean, { 0x00, 0x00, 0x30 }, }, + { biStoneBeach, { 0xa2, 0xa2, 0x84 }, }, + { biColdBeach, { 0xfa, 0xf0, 0xc0 }, }, + { biBirchForest, { 0x30, 0x74, 0x44 }, }, + { biBirchForestHills, { 0x1f, 0x5f, 0x32 }, }, + { biRoofedForest, { 0x40, 0x51, 0x1a }, }, + { biColdTaiga, { 0x31, 0x55, 0x4a }, }, + { biColdTaigaHills, { 0x59, 0x7d, 0x72 }, }, + { biMegaTaiga, { 0x59, 0x66, 0x51 }, }, + { biMegaTaigaHills, { 0x59, 0x66, 0x59 }, }, + { biExtremeHillsPlus, { 0x50, 0x70, 0x50 }, }, + { biSavanna, { 0xbd, 0xb2, 0x5f }, }, + { biSavannaPlateau, { 0xa7, 0x9d, 0x64 }, }, + { biMesa, { 0xd9, 0x45, 0x15 }, }, + { biMesaPlateauF, { 0xb0, 0x97, 0x65 }, }, + { biMesaPlateau, { 0xca, 0x8c, 0x65 }, }, + + // M variants: + { biSunflowerPlains, { 0xb5, 0xdb, 0x88 }, }, + { biDesertM, { 0xff, 0xbc, 0x40 }, }, + { biExtremeHillsM, { 0x88, 0x88, 0x88 }, }, + { biFlowerForest, { 0x2d, 0x8e, 0x49 }, }, + { biTaigaM, { 0x33, 0x8e, 0x81 }, }, + { biSwamplandM, { 0x07, 0xf9, 0xb2 }, }, + { biIcePlainsSpikes, { 0xb4, 0xdc, 0xdc }, }, + { biJungleM, { 0x7b, 0xa3, 0x31 }, }, + { biJungleEdgeM, { 0x62, 0x8b, 0x17 }, }, + { biBirchForestM, { 0x58, 0x9c, 0x6c }, }, + { biBirchForestHillsM, { 0x47, 0x87, 0x5a }, }, + { biRoofedForestM, { 0x68, 0x79, 0x42 }, }, + { biColdTaigaM, { 0x24, 0x3f, 0x36 }, }, + { biMegaSpruceTaiga, { 0x45, 0x4f, 0x3e }, }, + { biMegaSpruceTaigaHills, { 0x45, 0x4f, 0x4e }, }, + { biExtremeHillsPlusM, { 0x78, 0x98, 0x78 }, }, + { biSavannaM, { 0xe5, 0xda, 0x87 }, }, + { biSavannaPlateauM, { 0xa7, 0x9d, 0x74 }, }, + { biMesaBryce, { 0xff, 0x6d, 0x3d }, }, + { biMesaPlateauFM, { 0xd8, 0xbf, 0x8d }, }, + { biMesaPlateauM, { 0xf2, 0xb4, 0x8d }, }, +} ; + + + + + +static class BiomeColorsInitializer +{ +public: + BiomeColorsInitializer(void) + { + // Reset all colors to gray: + for (size_t i = 0; i < ARRAYCOUNT(biomeToColor); i++) + { + biomeToColor[i] = 0x7f; + } + + // Set known biomes to their colors: + for (size_t i = 0; i < ARRAYCOUNT(biomeColors); i++) + { + uchar * color = &biomeToColor[4 * biomeColors[i].m_Biome]; + color[0] = biomeColors[i].m_Color[0]; + color[1] = biomeColors[i].m_Color[1]; + color[2] = biomeColors[i].m_Color[2]; + color[3] = 0xff; + } + } +} biomeColorInitializer; + + + + + +/** Converts biomes in an array into the chunk image data. */ +static void biomesToImage(cChunkDef::BiomeMap & a_Biomes, Chunk::Image & a_Image) +{ + // Make sure the two arrays are of the same size, compile-time. + // Note that a_Image is actually 4 items per pixel, so the array is 4 times bigger: + static const char Check1[4 * ARRAYCOUNT(a_Biomes) - ARRAYCOUNT(a_Image) + 1]; + static const char Check2[ARRAYCOUNT(a_Image) - 4 * ARRAYCOUNT(a_Biomes) + 1]; + + // Convert the biomes into color: + for (size_t i = 0; i < ARRAYCOUNT(a_Biomes); i++) + { + a_Image[4 * i + 0] = biomeToColor[4 * a_Biomes[i] + 0]; + a_Image[4 * i + 1] = biomeToColor[4 * a_Biomes[i] + 1]; + a_Image[4 * i + 2] = biomeToColor[4 * a_Biomes[i] + 2]; + a_Image[4 * i + 3] = biomeToColor[4 * a_Biomes[i] + 3]; + } +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// BioGenSource: + +BioGenSource::BioGenSource(cBiomeGen * a_BiomeGen) : + m_BiomeGen(a_BiomeGen) +{ +} + + + + + +void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) +{ + // TODO: To make use of multicore machines, we need multiple copies of the biomegen + // Right now we have only one, so we can let only one thread use it (hence the mutex) + QMutexLocker lock(&m_Mtx); + cChunkDef::BiomeMap biomes; + m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, biomes); + Chunk::Image img; + biomesToImage(biomes, img); + a_DestChunk->setImage(img); +} + + + + diff --git a/Tools/QtBiomeVisualiser/ChunkSource.h b/Tools/QtBiomeVisualiser/ChunkSource.h new file mode 100644 index 000000000..d6eb2e3cb --- /dev/null +++ b/Tools/QtBiomeVisualiser/ChunkSource.h @@ -0,0 +1,60 @@ +#pragma once +#include "Chunk.h" + + + + + +// fwd: +class cBiomeGen; + + + + + +/** Abstract interface for getting biome data for chunks. */ +class ChunkSource +{ +public: + virtual ~ChunkSource() {} + + /** Fills the a_DestChunk with the biomes for the specified coords. + It is expected to be thread-safe and re-entrant. Usually QThread::idealThreadCount() threads are used. */ + virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) = 0; +}; + + + + + + +class BioGenSource : + public ChunkSource +{ +public: + /** Constructs a new BioGenSource based on the biome generator given. + Takes ownership of a_BiomeGen */ + BioGenSource(cBiomeGen * a_BiomeGen); + + virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override; + +protected: + std::shared_ptr m_BiomeGen; + QMutex m_Mtx; +}; + + + + +class AnvilSource : + public ChunkSource +{ +public: + // TODO + + virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override; +}; + + + + diff --git a/Tools/QtBiomeVisualiser/Globals.h b/Tools/QtBiomeVisualiser/Globals.h new file mode 100644 index 000000000..d3c7f0675 --- /dev/null +++ b/Tools/QtBiomeVisualiser/Globals.h @@ -0,0 +1,386 @@ +#pragma once + + + + + +// Compiler-dependent stuff: +#if defined(_MSC_VER) + // MSVC produces warning C4481 on the override keyword usage, so disable the warning altogether + #pragma warning(disable:4481) + + // Disable some warnings that we don't care about: + #pragma warning(disable:4100) // Unreferenced formal parameter + + // Useful warnings from warning level 4: + #pragma warning(3 : 4127) // Conditional expression is constant + #pragma warning(3 : 4189) // Local variable is initialized but not referenced + #pragma warning(3 : 4245) // Conversion from 'type1' to 'type2', signed/unsigned mismatch + #pragma warning(3 : 4310) // Cast truncates constant value + #pragma warning(3 : 4389) // Signed/unsigned mismatch + #pragma warning(3 : 4505) // Unreferenced local function has been removed + #pragma warning(3 : 4701) // Potentially unitialized local variable used + #pragma warning(3 : 4702) // Unreachable code + #pragma warning(3 : 4706) // Assignment within conditional expression + + // Disabling this warning, because we know what we're doing when we're doing this: + #pragma warning(disable: 4355) // 'this' used in initializer list + + // Disabled because it's useless: + #pragma warning(disable: 4512) // 'class': assignment operator could not be generated - reported for each class that has a reference-type member + + // 2014_01_06 xoft: Disabled this warning because MSVC is stupid and reports it in obviously wrong places + // #pragma warning(3 : 4244) // Conversion from 'type1' to 'type2', possible loss of data + + #define OBSOLETE __declspec(deprecated) + + // No alignment needed in MSVC + #define ALIGN_8 + #define ALIGN_16 + + #define FORMATSTRING(formatIndex, va_argsIndex) + + // MSVC has its own custom version of zu format + #define SIZE_T_FMT "%Iu" + #define SIZE_T_FMT_PRECISION(x) "%" #x "Iu" + #define SIZE_T_FMT_HEX "%Ix" + + #define NORETURN __declspec(noreturn) + +#elif defined(__GNUC__) + + // TODO: Can GCC explicitly mark classes as abstract (no instances can be created)? + #define abstract + + // override is part of c++11 + #if __cplusplus < 201103L + #define override + #endif + + #define OBSOLETE __attribute__((deprecated)) + + #define ALIGN_8 __attribute__((aligned(8))) + #define ALIGN_16 __attribute__((aligned(16))) + + // Some portability macros :) + #define stricmp strcasecmp + + #define FORMATSTRING(formatIndex, va_argsIndex) __attribute__((format (printf, formatIndex, va_argsIndex))) + + #if defined(_WIN32) + // We're compiling on MinGW, which uses an old MSVCRT library that has no support for size_t printfing. + // We need direct size formats: + #if defined(_WIN64) + #define SIZE_T_FMT "%I64u" + #define SIZE_T_FMT_PRECISION(x) "%" #x "I64u" + #define SIZE_T_FMT_HEX "%I64x" + #else + #define SIZE_T_FMT "%u" + #define SIZE_T_FMT_PRECISION(x) "%" #x "u" + #define SIZE_T_FMT_HEX "%x" + #endif + #else + // We're compiling on Linux, so we can use libc's size_t printf format: + #define SIZE_T_FMT "%zu" + #define SIZE_T_FMT_PRECISION(x) "%" #x "zu" + #define SIZE_T_FMT_HEX "%zx" + #endif + + #define NORETURN __attribute((__noreturn__)) + +#else + + #error "You are using an unsupported compiler, you might need to #define some stuff here for your compiler" + + /* + // Copy and uncomment this into another #elif section based on your compiler identification + + // Explicitly mark classes as abstract (no instances can be created) + #define abstract + + // Mark virtual methods as overriding (forcing them to have a virtual function of the same signature in the base class) + #define override + + // Mark functions as obsolete, so that their usage results in a compile-time warning + #define OBSOLETE + + // Mark types / variables for alignment. Do the platforms need it? + #define ALIGN_8 + #define ALIGN_16 + */ + +#endif + + +#ifdef _DEBUG + #define NORETURNDEBUG NORETURN +#else + #define NORETURNDEBUG +#endif + + +#include + + +// Integral types with predefined sizes: +typedef long long Int64; +typedef int Int32; +typedef short Int16; + +typedef unsigned long long UInt64; +typedef unsigned int UInt32; +typedef unsigned short UInt16; + +typedef unsigned char Byte; + + +// If you get an error about specialization check the size of integral types +template +class SizeChecker; + +template +class SizeChecker +{ + T v; +}; + +template class SizeChecker; +template class SizeChecker; +template class SizeChecker; + +template class SizeChecker; +template class SizeChecker; +template class SizeChecker; + +// A macro to disallow the copy constructor and operator = functions +// This should be used in the private: declarations for any class that shouldn't allow copying itself +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName &); \ + void operator =(const TypeName &) + +// A macro that is used to mark unused function parameters, to avoid pedantic warnings in gcc +#define UNUSED(X) (void)(X) + + + + +// OS-dependent stuff: +#ifdef _WIN32 + #define WIN32_LEAN_AND_MEAN + + #define _WIN32_WINNT 0x501 // We want to target WinXP and higher + + #include + #include + #include // IPv6 stuff + + // Windows SDK defines min and max macros, messing up with our std::min and std::max usage + #undef min + #undef max + + // Windows SDK defines GetFreeSpace as a constant, probably a Win16 API remnant + #ifdef GetFreeSpace + #undef GetFreeSpace + #endif // GetFreeSpace +#else + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include +#endif + +#if defined(ANDROID_NDK) + #define FILE_IO_PREFIX "/sdcard/mcserver/" +#else + #define FILE_IO_PREFIX "" +#endif + + + + + +// CRT stuff: +#include +#include +#include +#include +#include + + + + + +// STL stuff: +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#ifndef TEST_GLOBALS + // Common headers (part 1, without macros): + #include "StringUtils.h" + #include "OSSupport/Sleep.h" + #include "OSSupport/CriticalSection.h" + #include "OSSupport/Semaphore.h" + #include "OSSupport/Event.h" + #include "OSSupport/Thread.h" + #include "OSSupport/File.h" + #include "Logger.h" +#else + // Logging functions +void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); + +void inline LOGERROR(const char* a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + vprintf(a_Format, argList); + va_end(argList); +} +#endif + + + + + +// Common definitions: + +/// Evaluates to the number of elements in an array (compile-time!) +#define ARRAYCOUNT(X) (sizeof(X) / sizeof(*(X))) + +/// 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) - (((x) < 0) ? ((div) - 1) : 0)) / (div)) + +// Own version of assert() that writes failed assertions to the log for review +#ifdef TEST_GLOBALS + + class cAssertFailure + { + }; + + #ifdef _WIN32 + #if (defined(_MSC_VER) && defined(_DEBUG)) + #define DBG_BREAK _CrtDbgBreak() + #else + #define DBG_BREAK + #endif + #define REPORT_ERROR(FMT, ...) \ + { \ + AString msg = Printf(FMT, __VA_ARGS__); \ + puts(msg.c_str()); \ + fflush(stdout); \ + OutputDebugStringA(msg.c_str()); \ + DBG_BREAK; \ + } + #else + #define REPORT_ERROR(FMT, ...) \ + { \ + AString msg = Printf(FMT, __VA_ARGS__); \ + puts(msg.c_str()); \ + fflush(stdout); \ + } + #endif + #define ASSERT(x) do { if (!(x)) { throw cAssertFailure();} } while (0) + #define testassert(x) do { if (!(x)) { REPORT_ERROR("Test failure: %s, file %s, line %d\n", #x, __FILE__, __LINE__); exit(1); } } while (0) + #define CheckAsserts(x) do { try {x} catch (cAssertFailure) { break; } REPORT_ERROR("Test failure: assert didn't fire for %s, file %s, line %d\n", #x, __FILE__, __LINE__); exit(1); } while (0) + +#else + #ifdef _DEBUG + #define ASSERT( x) ( !!(x) || ( LOGERROR("Assertion failed: %s, file %s, line %i", #x, __FILE__, __LINE__), assert(0), 0)) + #else + #define ASSERT(x) ((void)(x)) + #endif +#endif + +// Pretty much the same as ASSERT() but stays in Release builds +#define VERIFY( x) ( !!(x) || ( LOGERROR("Verification failed: %s, file %s, line %i", #x, __FILE__, __LINE__), exit(1), 0)) + +// Same as assert but in all Self test builds +#ifdef SELF_TEST + #define assert_test(x) ( !!(x) || (assert(!#x), exit(1), 0)) +#endif + +// Allow both Older versions of MSVC and newer versions of everything use a shared_ptr: +// Note that we cannot typedef, because C++ doesn't allow (partial) templates to be typedeffed. +#if (defined(_MSC_VER) && (_MSC_VER < 1600)) + // MSVC before 2010 doesn't have std::shared_ptr, but has std::tr1::shared_ptr, defined in included earlier + #define SharedPtr std::tr1::shared_ptr +#elif (defined(_MSC_VER) || (__cplusplus >= 201103L)) + // C++11 has std::shared_ptr in , included earlier + #define SharedPtr std::shared_ptr +#else + // C++03 has std::tr1::shared_ptr in + #include + #define SharedPtr std::tr1::shared_ptr +#endif + + + + + +/** A generic interface used mainly in ForEach() functions */ +template class cItemCallback +{ +public: + virtual ~cItemCallback() {} + + /** Called for each item in the internal list; return true to stop the loop, or false to continue enumerating */ + virtual bool Item(Type * a_Type) = 0; +} ; + + + + +/** Clamp X to the specified range. */ +template +T Clamp(T a_Value, T a_Min, T a_Max) +{ + return (a_Value < a_Min) ? a_Min : ((a_Value > a_Max) ? a_Max : a_Value); +} + + + + + +#ifndef TOLUA_TEMPLATE_BIND + #define TOLUA_TEMPLATE_BIND(x) +#endif + + + + + +// Common headers (part 2, with macros): +#include "ChunkDef.h" +#include "BiomeDef.h" +#include "BlockID.h" +#include "BlockInfo.h" + + + + + diff --git a/Tools/QtBiomeVisualiser/MainWindow.cpp b/Tools/QtBiomeVisualiser/MainWindow.cpp new file mode 100644 index 000000000..8b98c0b0e --- /dev/null +++ b/Tools/QtBiomeVisualiser/MainWindow.cpp @@ -0,0 +1,104 @@ +#include "Globals.h" +#include "MainWindow.h" +#include +#include +#include +#include +#include +#include "inifile/iniFile.h" +#include "ChunkSource.h" +#include "Generating/BioGen.h" + + + + + +MainWindow::MainWindow(QWidget * parent) : + QMainWindow(parent) +{ + createActions(); + createMenus(); + + m_BiomeView = new BiomeView(this); + setCentralWidget(m_BiomeView); +} + + + + + +MainWindow::~MainWindow() +{ + +} + + + + + +void MainWindow::generate() +{ + QString worldIni = QFileDialog::getOpenFileName(this, tr("Open world.ini"), QString(), tr("world.ini (world.ini)")); + cIniFile ini; + if (!ini.ReadFile(worldIni.toStdString())) + { + return; + } + int seed = ini.GetValueSetI("Seed", "Seed", 0); + bool unused = false; + cBiomeGen * biomeGen = cBiomeGen::CreateBiomeGen(ini, seed, unused); + if (biomeGen == nullptr) + { + return; + } + m_BiomeView->setChunkSource(std::shared_ptr(new BioGenSource(biomeGen))); + m_BiomeView->redraw(); +} + + + + + +void MainWindow::open() +{ + // TODO +} + + + + + +void MainWindow::createActions() +{ + m_actGen = new QAction(tr("&Generate..."), this); + m_actGen->setShortcut(tr("Ctrl+N")); + m_actGen->setStatusTip(tr("Open a generator INI file and display the generated biomes")); + connect(m_actGen, SIGNAL(triggered()), this, SLOT(generate())); + + m_actOpen = new QAction(tr("&Open world..."), this); + m_actOpen->setShortcut(tr("Ctrl+O")); + m_actOpen->setStatusTip(tr("Open an existing world and display its biomes")); + connect(m_actOpen, SIGNAL(triggered()), this, SLOT(open())); + + m_actExit = new QAction(tr("E&xit"), this); + m_actExit->setShortcut(tr("Alt+X")); + m_actExit->setStatusTip(tr("Exit %1").arg(QApplication::instance()->applicationName())); + connect(m_actExit, SIGNAL(triggered()), this, SLOT(close())); +} + + + + + +void MainWindow::createMenus() +{ + QMenu * mFile = menuBar()->addMenu(tr("&World")); + mFile->addAction(m_actGen); + mFile->addAction(m_actOpen); + mFile->addSeparator(); + mFile->addAction(m_actExit); +} + + + + diff --git a/Tools/QtBiomeVisualiser/MainWindow.h b/Tools/QtBiomeVisualiser/MainWindow.h new file mode 100644 index 000000000..f6028aff1 --- /dev/null +++ b/Tools/QtBiomeVisualiser/MainWindow.h @@ -0,0 +1,46 @@ +#pragma once + +#include +#include "BiomeView.h" + + + + + +class MainWindow : + public QMainWindow +{ + Q_OBJECT + + BiomeView * m_BiomeView; + +public: + MainWindow(QWidget *parent = 0); + ~MainWindow(); + +private slots: + /** Opens a generator definition and generates the biomes based on that. */ + void generate(); + + /** Opens an existing world and displays the loaded biomes. */ + void open(); + +protected: + // Actions: + QAction * m_actGen; + QAction * m_actOpen; + QAction * m_actExit; + + + /** Creates the actions that the UI supports. */ + void createActions(); + + /** Creates the menu bar and connects its events. */ + void createMenus(); +}; + + + + + + diff --git a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro new file mode 100644 index 000000000..0329d5607 --- /dev/null +++ b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro @@ -0,0 +1,62 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2014-09-11T15:22:43 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = QtBiomeVisualiser +TEMPLATE = app + + +SOURCES += main.cpp\ + MainWindow.cpp \ + BiomeView.cpp \ + ../../src/Generating/BioGen.cpp \ + ../../src/VoronoiMap.cpp \ + ../../src/Noise.cpp \ + ../../src/StringUtils.cpp \ + ../../src/LoggerListeners.cpp \ + ../../src/Logger.cpp \ + ../../lib/inifile/iniFile.cpp \ + ../../src/OSSupport/File.cpp \ + ../../src/OSSupport/CriticalSection.cpp \ + ../../src/OSSupport/IsThread.cpp \ + ../../src/BiomeDef.cpp \ + ChunkCache.cpp \ + Chunk.cpp \ + ChunkSource.cpp \ + ChunkLoader.cpp + +HEADERS += MainWindow.h \ + Globals.h \ + BiomeView.h \ + ../../src/Generating/BioGen.h \ + ../../src/VoronoiMap.h \ + ../../src/Noise.h \ + ../../src/StringUtils.h \ + ../../src/LoggerListeners.h \ + ../../src/Logger.h \ + ../../lib/inifile/iniFile.h \ + ../../src/OSSupport/File.h \ + ../../src/OSSupport/CriticalSection.h \ + ../../src/OSSupport/IsThread.h \ + ../../src/BiomeDef.h \ + ChunkCache.h \ + Chunk.h \ + ChunkSource.h \ + ChunkLoader.h + +INCLUDEPATH += $$_PRO_FILE_PWD_ \ + $$_PRO_FILE_PWD_/../../src \ + $$_PRO_FILE_PWD_/../../lib + + +CONFIG += STATIC + + + + diff --git a/Tools/QtBiomeVisualiser/main.cpp b/Tools/QtBiomeVisualiser/main.cpp new file mode 100644 index 000000000..f41cdcfb2 --- /dev/null +++ b/Tools/QtBiomeVisualiser/main.cpp @@ -0,0 +1,20 @@ +#include "Globals.h" +#include "MainWindow.h" +#include + + + + + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + + return a.exec(); +} + + + + -- cgit v1.2.3 From 2a020e47f1c9167b933fab2662c827365d2f6b5d Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 14 Sep 2014 20:09:11 +0200 Subject: QtBiomeVisualiser: Removed build-specific variables. These should be set in the project configuration instead, passed directly to qmake. --- Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro | 3 --- 1 file changed, 3 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro index 0329d5607..0b42f076d 100644 --- a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro +++ b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro @@ -55,8 +55,5 @@ INCLUDEPATH += $$_PRO_FILE_PWD_ \ $$_PRO_FILE_PWD_/../../lib -CONFIG += STATIC - - -- cgit v1.2.3 From 69b46aeb27ecfbf87fec5945993a9a441cb89fc7 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 14 Sep 2014 22:05:10 +0200 Subject: QtBiomeVisualiser: Added mouse and keyboard view control. Mouse dragging or WASD pans view, mouse wheel or QE zooms. --- Tools/QtBiomeVisualiser/BiomeView.cpp | 113 +++++++++++++++++++++++++++++++++- Tools/QtBiomeVisualiser/BiomeView.h | 28 ++++++++- 2 files changed, 137 insertions(+), 4 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/BiomeView.cpp b/Tools/QtBiomeVisualiser/BiomeView.cpp index be01fd104..3d24ed126 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.cpp +++ b/Tools/QtBiomeVisualiser/BiomeView.cpp @@ -33,6 +33,9 @@ BiomeView::BiomeView(QWidget * parent) : // Add a chunk-update callback mechanism: connect(&m_Cache, SIGNAL(chunkAvailable(int, int)), this, SLOT(chunkAvailable(int, int))); + + // Allow keyboard interaction: + setFocusPolicy(Qt::StrongFocus); } @@ -236,9 +239,117 @@ void BiomeView::paintEvent(QPaintEvent * a_Event) -void BiomeView::queueChunkRender(ChunkPtr a_Chunk) +void BiomeView::mousePressEvent(QMouseEvent * a_Event) +{ + m_LastX = a_Event->x(); + m_LastY = a_Event->y(); + m_IsMouseDragging = true; +} + + + + + +void BiomeView::mouseMoveEvent(QMouseEvent * a_Event) +{ + if (m_IsMouseDragging) + { + // The user is dragging the mouse, move the view around: + m_X += (m_LastX - a_Event->x()) / m_Zoom; + m_Z += (m_LastY - a_Event->y()) / m_Zoom; + m_LastX = a_Event->x(); + m_LastY = a_Event->y(); + redraw(); + return; + } + + // TODO: Update the status bar info for the biome currently pointed at +} + + + + + +void BiomeView::mouseReleaseEvent(QMouseEvent *) +{ + m_IsMouseDragging = false; +} + + + + + +void BiomeView::wheelEvent(QWheelEvent * a_Event) +{ + m_Zoom += floor(a_Event->delta() / 90.0); + m_Zoom = Clamp(m_Zoom, 1.0, 20.0); + redraw(); +} + + + + + +void BiomeView::keyPressEvent(QKeyEvent * a_Event) { + switch (a_Event->key()) + { + case Qt::Key_Up: + case Qt::Key_W: + { + m_Z -= 10.0 / m_Zoom; + redraw(); + break; + } + + case Qt::Key_Down: + case Qt::Key_S: + { + m_Z += 10.0 / m_Zoom; + redraw(); + break; + } + + case Qt::Key_Left: + case Qt::Key_A: + { + m_X -= 10.0 / m_Zoom; + redraw(); + break; + } + + case Qt::Key_Right: + case Qt::Key_D: + { + m_X += 10.0 / m_Zoom; + redraw(); + break; + } + + case Qt::Key_PageUp: + case Qt::Key_Q: + { + m_Zoom++; + if (m_Zoom > 20.0) + { + m_Zoom = 20.0; + } + redraw(); + break; + } + case Qt::Key_PageDown: + case Qt::Key_E: + { + m_Zoom--; + if (m_Zoom < 1.0) + { + m_Zoom = 1.0; + } + redraw(); + break; + } + } } diff --git a/Tools/QtBiomeVisualiser/BiomeView.h b/Tools/QtBiomeVisualiser/BiomeView.h index c54c66491..8aae43df0 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.h +++ b/Tools/QtBiomeVisualiser/BiomeView.h @@ -35,10 +35,20 @@ public slots: protected: double m_X, m_Z; - int m_Zoom; + double m_Zoom; + + /** Cache for the loaded chunk data. */ ChunkCache m_Cache; + + /** The entire view's contents in an offscreen image. */ QImage m_Image; + /** Coords of the mouse for the previous position, used while dragging. */ + int m_LastX, m_LastY; + + /** Set to true when the user has a mouse button depressed, and is dragging the view. */ + bool m_IsMouseDragging; + /** Data used for rendering a chunk that hasn't been loaded yet */ uchar m_EmptyChunkImage[16 * 16 * 4]; @@ -55,8 +65,20 @@ protected: /** Paints the entire widget */ virtual void paintEvent(QPaintEvent *) override; - /** Queues the chunk for rendering. */ - void queueChunkRender(ChunkPtr a_Chunk); + /** Called when the user presses any mouse button. */ + virtual void mousePressEvent(QMouseEvent * a_Event); + + /** Called when the user moves the mouse. */ + virtual void mouseMoveEvent(QMouseEvent * a_Event); + + /** Called when the user releases a previously held mouse button. */ + virtual void mouseReleaseEvent(QMouseEvent * a_Event) override; + + /** Called when the user rotates the mouse wheel. */ + virtual void wheelEvent(QWheelEvent * a_Event) override; + + /** Called when the user presses a key. */ + virtual void keyPressEvent(QKeyEvent * a_Event) override; }; -- cgit v1.2.3 From ddf130f849f81670254ea2baf79fd06adcc0f302 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Sun, 14 Sep 2014 22:20:16 +0200 Subject: QtBiomeVisualiser: Extended zoom down below 100%. --- Tools/QtBiomeVisualiser/BiomeView.cpp | 87 ++++++++++++++++++++++++++++------- Tools/QtBiomeVisualiser/BiomeView.h | 9 ++++ 2 files changed, 80 insertions(+), 16 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/BiomeView.cpp b/Tools/QtBiomeVisualiser/BiomeView.cpp index 3d24ed126..671942440 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.cpp +++ b/Tools/QtBiomeVisualiser/BiomeView.cpp @@ -8,11 +8,19 @@ +static const int DELTA_STEP = 120; // The normal per-notch wheel delta + + + + + BiomeView::BiomeView(QWidget * parent) : super(parent), m_X(0), m_Z(0), - m_Zoom(1) + m_Zoom(1), + m_IsMouseDragging(false), + m_MouseWheelDelta(0) { // Create the image used for undefined chunks: int offset = 0; @@ -281,9 +289,17 @@ void BiomeView::mouseReleaseEvent(QMouseEvent *) void BiomeView::wheelEvent(QWheelEvent * a_Event) { - m_Zoom += floor(a_Event->delta() / 90.0); - m_Zoom = Clamp(m_Zoom, 1.0, 20.0); - redraw(); + m_MouseWheelDelta += a_Event->delta(); + while (m_MouseWheelDelta >= DELTA_STEP) + { + increaseZoom(); + m_MouseWheelDelta -= DELTA_STEP; + } + while (m_MouseWheelDelta <= -DELTA_STEP) + { + decreaseZoom(); + m_MouseWheelDelta += DELTA_STEP; + } } @@ -329,24 +345,14 @@ void BiomeView::keyPressEvent(QKeyEvent * a_Event) case Qt::Key_PageUp: case Qt::Key_Q: { - m_Zoom++; - if (m_Zoom > 20.0) - { - m_Zoom = 20.0; - } - redraw(); + increaseZoom(); break; } case Qt::Key_PageDown: case Qt::Key_E: { - m_Zoom--; - if (m_Zoom < 1.0) - { - m_Zoom = 1.0; - } - redraw(); + decreaseZoom(); break; } } @@ -355,3 +361,52 @@ void BiomeView::keyPressEvent(QKeyEvent * a_Event) + +void BiomeView::decreaseZoom() +{ + if (m_Zoom > 1.001) + { + m_Zoom--; + if (m_Zoom < 1.0) + { + // Just crossed the 100%, fixate the 100% threshold: + m_Zoom = 1.0; + } + } + else if (m_Zoom > 0.01) + { + m_Zoom = m_Zoom / 2; + } + redraw(); +} + + + + + +void BiomeView::increaseZoom() +{ + if (m_Zoom > 0.99) + { + if (m_Zoom > 20.0) + { + // Zoom too large + return; + } + m_Zoom++; + } + else + { + m_Zoom = m_Zoom * 2; + if (m_Zoom > 1.0) + { + // Just crossed the 100%, fixate the 100% threshold: + m_Zoom = 1.0; + } + } + redraw(); +} + + + + diff --git a/Tools/QtBiomeVisualiser/BiomeView.h b/Tools/QtBiomeVisualiser/BiomeView.h index 8aae43df0..61bda45c2 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.h +++ b/Tools/QtBiomeVisualiser/BiomeView.h @@ -49,6 +49,9 @@ protected: /** Set to true when the user has a mouse button depressed, and is dragging the view. */ bool m_IsMouseDragging; + /** Accumulator for the mouse wheel's delta. When the accumulator hits a threshold, the view zooms. */ + int m_MouseWheelDelta; + /** Data used for rendering a chunk that hasn't been loaded yet */ uchar m_EmptyChunkImage[16 * 16 * 4]; @@ -79,6 +82,12 @@ protected: /** Called when the user presses a key. */ virtual void keyPressEvent(QKeyEvent * a_Event) override; + + /** Decreases the zoom level and queues a redraw. */ + void decreaseZoom(); + + /** Increases the zoom level and queues a redraw. */ + void increaseZoom(); }; -- cgit v1.2.3 From d772bc032f12bceac2d974ad9165597edabe5b0a Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 15 Sep 2014 16:50:40 +0200 Subject: QtBiomeVisualiser: Added multithreading. For some reason this makes the UI less responsive. --- Tools/QtBiomeVisualiser/ChunkSource.cpp | 74 ++++++++++++++++++++++++++++++--- Tools/QtBiomeVisualiser/ChunkSource.h | 37 +++++++++++++++-- Tools/QtBiomeVisualiser/MainWindow.cpp | 14 +------ 3 files changed, 102 insertions(+), 23 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp index 44dcf1fa7..5658198f4 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.cpp +++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp @@ -1,6 +1,8 @@ #include "Globals.h" #include "ChunkSource.h" +#include #include "Generating/BioGen.h" +#include "inifile/iniFile.h" @@ -138,9 +140,12 @@ static void biomesToImage(cChunkDef::BiomeMap & a_Biomes, Chunk::Image & a_Image //////////////////////////////////////////////////////////////////////////////// // BioGenSource: -BioGenSource::BioGenSource(cBiomeGen * a_BiomeGen) : - m_BiomeGen(a_BiomeGen) +BioGenSource::BioGenSource(QString a_WorldIniPath) : + m_WorldIniPath(a_WorldIniPath), + m_WorldIni(new cIniFile), + m_Mtx(QMutex::Recursive) { + reload(); } @@ -149,11 +154,14 @@ BioGenSource::BioGenSource(cBiomeGen * a_BiomeGen) : void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) { - // TODO: To make use of multicore machines, we need multiple copies of the biomegen - // Right now we have only one, so we can let only one thread use it (hence the mutex) - QMutexLocker lock(&m_Mtx); + cBiomeGenPtr biomeGen; + { + QMutexLocker lock(&m_Mtx); + biomeGen = getBiomeGen(); + } cChunkDef::BiomeMap biomes; - m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, biomes); + biomeGen->GenBiomes(a_ChunkX, a_ChunkZ, biomes); + releaseBiomeGen(biomeGen); Chunk::Image img; biomesToImage(biomes, img); a_DestChunk->setImage(img); @@ -162,3 +170,57 @@ void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChu + +void BioGenSource::reload() +{ + { + QMutexLocker lock(&m_Mtx); + if (!m_WorldIni->ReadFile(m_WorldIniPath.toStdString())) + { + return; + } + m_AvailableGens.clear(); + } +} + + + + +cBiomeGenPtr BioGenSource::getBiomeGen() +{ + QMutexLocker lock(&m_Mtx); + + // Return a generator from the cache, if available: + if (!m_AvailableGens.empty()) + { + cBiomeGenPtr res = m_AvailableGens.back(); + m_AvailableGens.pop_back(); + return res; + } + + // No generator in cache available, create a new one: + int seed = m_WorldIni->GetValueSetI("Seed", "Seed", 0); + bool unused = false; + return cBiomeGenPtr(cBiomeGen::CreateBiomeGen(*m_WorldIni, seed, unused)); +} + + + + + +void BioGenSource::releaseBiomeGen(cBiomeGenPtr a_BiomeGen) +{ + QMutexLocker lock(&m_Mtx); + m_AvailableGens.push_back(a_BiomeGen); + + // Trim the cache if there are too many gens: + int wantedNumGens = QThread::idealThreadCount(); + if (m_AvailableGens.size() > (size_t)(4 * wantedNumGens)) + { + m_AvailableGens.resize(wantedNumGens); + } +} + + + + diff --git a/Tools/QtBiomeVisualiser/ChunkSource.h b/Tools/QtBiomeVisualiser/ChunkSource.h index d6eb2e3cb..7bbdda276 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.h +++ b/Tools/QtBiomeVisualiser/ChunkSource.h @@ -1,4 +1,5 @@ #pragma once +#include #include "Chunk.h" @@ -7,6 +8,8 @@ // fwd: class cBiomeGen; +typedef std::shared_ptr cBiomeGenPtr; +class cIniFile; @@ -21,6 +24,9 @@ public: /** Fills the a_DestChunk with the biomes for the specified coords. It is expected to be thread-safe and re-entrant. Usually QThread::idealThreadCount() threads are used. */ virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) = 0; + + /** Forces a fresh reload of the source. Useful mainly for the generator, whose underlying definition file may have been changed. */ + virtual void reload() = 0; }; @@ -32,15 +38,36 @@ class BioGenSource : public ChunkSource { public: - /** Constructs a new BioGenSource based on the biome generator given. - Takes ownership of a_BiomeGen */ - BioGenSource(cBiomeGen * a_BiomeGen); + /** Constructs a new BioGenSource based on the biome generator that is defined in the specified world.ini file. */ + BioGenSource(QString a_WorldIniPath); + // ChunkSource overrides: virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override; + virtual void reload(void) override; protected: - std::shared_ptr m_BiomeGen; + /** Path to the world.ini file from which the m_WorldIni is regenerated on reload requests. */ + QString m_WorldIniPath; + + /** Parsed contents of the world.ini file from which the biome generators are initialized. + Locked by m_Mtx to avoid multithreaded access. */ + std::unique_ptr m_WorldIni; + + /** List of cBiomeGen instances that are "free" - aren't doing any generating at this moment. + Locked by m_Mtx to avoid multithreaded access. */ + std::vector m_AvailableGens; + + /** Guards m_AvailableGens and m_WorldIni against multithreaded access. */ QMutex m_Mtx; + + + /** Returns a cBiomeGen that can generate a new chunk's biomes. + Uses m_AvailableGens as a cache before creating a new generator. */ + cBiomeGenPtr BioGenSource::getBiomeGen(); + + /** Puts the specified BiomeGen back to m_AvailableGens to make it available for next getBiomeGen() request. + Truncates m_AvailableGens if there are too many instances in there. */ + void releaseBiomeGen(cBiomeGenPtr a_BiomeGen); }; @@ -52,7 +79,9 @@ class AnvilSource : public: // TODO + // ChunkSource overrides: virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override; + virtual void reload() override {} }; diff --git a/Tools/QtBiomeVisualiser/MainWindow.cpp b/Tools/QtBiomeVisualiser/MainWindow.cpp index 8b98c0b0e..21fb1a0c0 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.cpp +++ b/Tools/QtBiomeVisualiser/MainWindow.cpp @@ -39,19 +39,7 @@ MainWindow::~MainWindow() void MainWindow::generate() { QString worldIni = QFileDialog::getOpenFileName(this, tr("Open world.ini"), QString(), tr("world.ini (world.ini)")); - cIniFile ini; - if (!ini.ReadFile(worldIni.toStdString())) - { - return; - } - int seed = ini.GetValueSetI("Seed", "Seed", 0); - bool unused = false; - cBiomeGen * biomeGen = cBiomeGen::CreateBiomeGen(ini, seed, unused); - if (biomeGen == nullptr) - { - return; - } - m_BiomeView->setChunkSource(std::shared_ptr(new BioGenSource(biomeGen))); + m_BiomeView->setChunkSource(std::shared_ptr(new BioGenSource(worldIni))); m_BiomeView->redraw(); } -- cgit v1.2.3 From 84947a22ad2c2ccb91733e171566433731eb0f48 Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 15 Sep 2014 17:20:54 +0200 Subject: QtBiomeVisualiser: removed multithreading. It was slowing things down, the granularity is too fine. --- Tools/QtBiomeVisualiser/ChunkSource.cpp | 55 +++++---------------------------- Tools/QtBiomeVisualiser/ChunkSource.h | 20 ++---------- 2 files changed, 10 insertions(+), 65 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp index 5658198f4..7da36c39b 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.cpp +++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp @@ -142,7 +142,6 @@ static void biomesToImage(cChunkDef::BiomeMap & a_Biomes, Chunk::Image & a_Image BioGenSource::BioGenSource(QString a_WorldIniPath) : m_WorldIniPath(a_WorldIniPath), - m_WorldIni(new cIniFile), m_Mtx(QMutex::Recursive) { reload(); @@ -154,14 +153,11 @@ BioGenSource::BioGenSource(QString a_WorldIniPath) : void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) { - cBiomeGenPtr biomeGen; + cChunkDef::BiomeMap biomes; { QMutexLocker lock(&m_Mtx); - biomeGen = getBiomeGen(); + m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, biomes); } - cChunkDef::BiomeMap biomes; - biomeGen->GenBiomes(a_ChunkX, a_ChunkZ, biomes); - releaseBiomeGen(biomeGen); Chunk::Image img; biomesToImage(biomes, img); a_DestChunk->setImage(img); @@ -173,52 +169,15 @@ void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChu void BioGenSource::reload() { + cIniFile ini; + if (!ini.ReadFile(m_WorldIniPath.toStdString())) { - QMutexLocker lock(&m_Mtx); - if (!m_WorldIni->ReadFile(m_WorldIniPath.toStdString())) - { - return; - } - m_AvailableGens.clear(); - } -} - - - - -cBiomeGenPtr BioGenSource::getBiomeGen() -{ - QMutexLocker lock(&m_Mtx); - - // Return a generator from the cache, if available: - if (!m_AvailableGens.empty()) - { - cBiomeGenPtr res = m_AvailableGens.back(); - m_AvailableGens.pop_back(); - return res; + return; } - - // No generator in cache available, create a new one: - int seed = m_WorldIni->GetValueSetI("Seed", "Seed", 0); + int seed = ini.GetValueSetI("Seed", "Seed", 0); bool unused = false; - return cBiomeGenPtr(cBiomeGen::CreateBiomeGen(*m_WorldIni, seed, unused)); -} - - - - - -void BioGenSource::releaseBiomeGen(cBiomeGenPtr a_BiomeGen) -{ QMutexLocker lock(&m_Mtx); - m_AvailableGens.push_back(a_BiomeGen); - - // Trim the cache if there are too many gens: - int wantedNumGens = QThread::idealThreadCount(); - if (m_AvailableGens.size() > (size_t)(4 * wantedNumGens)) - { - m_AvailableGens.resize(wantedNumGens); - } + m_BiomeGen.reset(cBiomeGen::CreateBiomeGen(ini, seed, unused)); } diff --git a/Tools/QtBiomeVisualiser/ChunkSource.h b/Tools/QtBiomeVisualiser/ChunkSource.h index 7bbdda276..a485e473a 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.h +++ b/Tools/QtBiomeVisualiser/ChunkSource.h @@ -49,25 +49,11 @@ protected: /** Path to the world.ini file from which the m_WorldIni is regenerated on reload requests. */ QString m_WorldIniPath; - /** Parsed contents of the world.ini file from which the biome generators are initialized. - Locked by m_Mtx to avoid multithreaded access. */ - std::unique_ptr m_WorldIni; + /** The generator used for generating biomes. */ + std::unique_ptr m_BiomeGen; - /** List of cBiomeGen instances that are "free" - aren't doing any generating at this moment. - Locked by m_Mtx to avoid multithreaded access. */ - std::vector m_AvailableGens; - - /** Guards m_AvailableGens and m_WorldIni against multithreaded access. */ + /** Guards m_BiomeGen against multithreaded access. */ QMutex m_Mtx; - - - /** Returns a cBiomeGen that can generate a new chunk's biomes. - Uses m_AvailableGens as a cache before creating a new generator. */ - cBiomeGenPtr BioGenSource::getBiomeGen(); - - /** Puts the specified BiomeGen back to m_AvailableGens to make it available for next getBiomeGen() request. - Truncates m_AvailableGens if there are too many instances in there. */ - void releaseBiomeGen(cBiomeGenPtr a_BiomeGen); }; -- cgit v1.2.3 From 21b70f17c264de4f7c216cfca580e8254df5cbee Mon Sep 17 00:00:00 2001 From: Mattes D Date: Mon, 15 Sep 2014 17:29:34 +0200 Subject: QtBiomeVisualiser: Added reloading. --- Tools/QtBiomeVisualiser/BiomeView.cpp | 15 +++++++++++++++ Tools/QtBiomeVisualiser/BiomeView.h | 3 +++ Tools/QtBiomeVisualiser/ChunkCache.cpp | 16 ++++++++++++++++ Tools/QtBiomeVisualiser/ChunkCache.h | 5 ++++- Tools/QtBiomeVisualiser/MainWindow.cpp | 13 ++++++++++--- Tools/QtBiomeVisualiser/MainWindow.h | 1 + 6 files changed, 49 insertions(+), 4 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/BiomeView.cpp b/Tools/QtBiomeVisualiser/BiomeView.cpp index 671942440..bbaccb369 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.cpp +++ b/Tools/QtBiomeVisualiser/BiomeView.cpp @@ -131,6 +131,21 @@ void BiomeView::chunkAvailable(int a_ChunkX, int a_ChunkZ) +void BiomeView::reload() +{ + if (!hasData()) + { + return; + } + m_Cache.reload(); + + redraw(); +} + + + + + void BiomeView::drawChunk(int a_ChunkX, int a_ChunkZ) { if (!hasData()) diff --git a/Tools/QtBiomeVisualiser/BiomeView.h b/Tools/QtBiomeVisualiser/BiomeView.h index 61bda45c2..86af8bcaf 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.h +++ b/Tools/QtBiomeVisualiser/BiomeView.h @@ -33,6 +33,9 @@ public slots: /** A specified chunk has become available, redraw it. */ void chunkAvailable(int a_ChunkX, int a_ChunkZ); + /** Reloads the current chunk source and redraws the entire workspace. */ + void reload(); + protected: double m_X, m_Z; double m_Zoom; diff --git a/Tools/QtBiomeVisualiser/ChunkCache.cpp b/Tools/QtBiomeVisualiser/ChunkCache.cpp index b2230def0..05c267d30 100644 --- a/Tools/QtBiomeVisualiser/ChunkCache.cpp +++ b/Tools/QtBiomeVisualiser/ChunkCache.cpp @@ -76,6 +76,22 @@ void ChunkCache::setChunkSource(std::shared_ptr a_ChunkSource) +void ChunkCache::reload() +{ + assert(m_ChunkSource.get() != nullptr); + + // Reload the chunk source: + m_ChunkSource->reload(); + + // Clear the cache: + QMutexLocker lock(&m_Mtx); + m_Cache.clear(); +} + + + + + void ChunkCache::gotChunk(int a_ChunkX, int a_ChunkZ) { emit chunkAvailable(a_ChunkX, a_ChunkZ); diff --git a/Tools/QtBiomeVisualiser/ChunkCache.h b/Tools/QtBiomeVisualiser/ChunkCache.h index 0efa7fc39..0134bc7af 100644 --- a/Tools/QtBiomeVisualiser/ChunkCache.h +++ b/Tools/QtBiomeVisualiser/ChunkCache.h @@ -36,7 +36,10 @@ public: void setChunkSource(std::shared_ptr a_ChunkSource); /** Returns true iff the chunk source has been initialized. */ - bool hasData(void) const { return (m_ChunkSource.get() != nullptr); } + bool hasData() const { return (m_ChunkSource.get() != nullptr); } + + /** Reloads the current chunk source. */ + void reload(); signals: void chunkAvailable(int a_ChunkX, int a_ChunkZ); diff --git a/Tools/QtBiomeVisualiser/MainWindow.cpp b/Tools/QtBiomeVisualiser/MainWindow.cpp index 21fb1a0c0..65d0ccf5e 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.cpp +++ b/Tools/QtBiomeVisualiser/MainWindow.cpp @@ -16,11 +16,11 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent) { - createActions(); - createMenus(); - m_BiomeView = new BiomeView(this); setCentralWidget(m_BiomeView); + + createActions(); + createMenus(); } @@ -68,6 +68,11 @@ void MainWindow::createActions() m_actOpen->setStatusTip(tr("Open an existing world and display its biomes")); connect(m_actOpen, SIGNAL(triggered()), this, SLOT(open())); + m_actReload = new QAction(tr("&Reload"), this); + m_actReload->setShortcut(tr("F5")); + m_actReload->setStatusTip(tr("Open an existing world and display its biomes")); + connect(m_actReload, SIGNAL(triggered()), m_BiomeView, SLOT(reload())); + m_actExit = new QAction(tr("E&xit"), this); m_actExit->setShortcut(tr("Alt+X")); m_actExit->setStatusTip(tr("Exit %1").arg(QApplication::instance()->applicationName())); @@ -84,6 +89,8 @@ void MainWindow::createMenus() mFile->addAction(m_actGen); mFile->addAction(m_actOpen); mFile->addSeparator(); + mFile->addAction(m_actReload); + mFile->addSeparator(); mFile->addAction(m_actExit); } diff --git a/Tools/QtBiomeVisualiser/MainWindow.h b/Tools/QtBiomeVisualiser/MainWindow.h index f6028aff1..b37bf4120 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.h +++ b/Tools/QtBiomeVisualiser/MainWindow.h @@ -29,6 +29,7 @@ protected: // Actions: QAction * m_actGen; QAction * m_actOpen; + QAction * m_actReload; QAction * m_actExit; -- cgit v1.2.3 From 18743540bc5122a42d24148a273ce04717057ed3 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 15 Sep 2014 21:45:35 +0200 Subject: QtBiomeVisualiser: Fixed colors and read failures. --- Tools/QtBiomeVisualiser/ChunkSource.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp index 7da36c39b..9e0ea5751 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.cpp +++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp @@ -103,9 +103,9 @@ public: for (size_t i = 0; i < ARRAYCOUNT(biomeColors); i++) { uchar * color = &biomeToColor[4 * biomeColors[i].m_Biome]; - color[0] = biomeColors[i].m_Color[0]; + color[0] = biomeColors[i].m_Color[2]; color[1] = biomeColors[i].m_Color[1]; - color[2] = biomeColors[i].m_Color[2]; + color[2] = biomeColors[i].m_Color[0]; color[3] = 0xff; } } @@ -170,14 +170,13 @@ void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChu void BioGenSource::reload() { cIniFile ini; - if (!ini.ReadFile(m_WorldIniPath.toStdString())) - { - return; - } + ini.ReadFile(m_WorldIniPath.toStdString()); int seed = ini.GetValueSetI("Seed", "Seed", 0); bool unused = false; QMutexLocker lock(&m_Mtx); m_BiomeGen.reset(cBiomeGen::CreateBiomeGen(ini, seed, unused)); + lock.unlock(); + ini.WriteFile(m_WorldIniPath.toStdString()); } -- cgit v1.2.3 From 98f4588ed3af39af0554687b84944f12c49e87db Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 18 Sep 2014 10:24:52 +0200 Subject: QtBiomeVisualiser: Fixed linux compilation. --- Tools/QtBiomeVisualiser/BiomeView.h | 1 + Tools/QtBiomeVisualiser/ChunkCache.h | 1 + Tools/QtBiomeVisualiser/ChunkLoader.h | 2 ++ Tools/QtBiomeVisualiser/ChunkSource.h | 1 + Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro | 1 + 5 files changed, 6 insertions(+) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/BiomeView.h b/Tools/QtBiomeVisualiser/BiomeView.h index 86af8bcaf..f0521571d 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.h +++ b/Tools/QtBiomeVisualiser/BiomeView.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "ChunkCache.h" #include "ChunkSource.h" diff --git a/Tools/QtBiomeVisualiser/ChunkCache.h b/Tools/QtBiomeVisualiser/ChunkCache.h index 0134bc7af..8d198f02f 100644 --- a/Tools/QtBiomeVisualiser/ChunkCache.h +++ b/Tools/QtBiomeVisualiser/ChunkCache.h @@ -3,6 +3,7 @@ #include #include #include +#include diff --git a/Tools/QtBiomeVisualiser/ChunkLoader.h b/Tools/QtBiomeVisualiser/ChunkLoader.h index 3565434b9..4d026a45e 100644 --- a/Tools/QtBiomeVisualiser/ChunkLoader.h +++ b/Tools/QtBiomeVisualiser/ChunkLoader.h @@ -1,6 +1,8 @@ #pragma once + #include #include +#include diff --git a/Tools/QtBiomeVisualiser/ChunkSource.h b/Tools/QtBiomeVisualiser/ChunkSource.h index a485e473a..868e4a144 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.h +++ b/Tools/QtBiomeVisualiser/ChunkSource.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include "Chunk.h" diff --git a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro index 0b42f076d..e6b65e628 100644 --- a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro +++ b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro @@ -55,5 +55,6 @@ INCLUDEPATH += $$_PRO_FILE_PWD_ \ $$_PRO_FILE_PWD_/../../lib +CONFIG += C++11 -- cgit v1.2.3 From 09c67bddf75a2ed244b274462305136da08b20f3 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Thu, 18 Sep 2014 10:26:28 +0200 Subject: QtBiomeVisualiser: More gcc fixes. --- Tools/QtBiomeVisualiser/ChunkSource.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp index 9e0ea5751..2235816bc 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.cpp +++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp @@ -120,8 +120,8 @@ static void biomesToImage(cChunkDef::BiomeMap & a_Biomes, Chunk::Image & a_Image { // Make sure the two arrays are of the same size, compile-time. // Note that a_Image is actually 4 items per pixel, so the array is 4 times bigger: - static const char Check1[4 * ARRAYCOUNT(a_Biomes) - ARRAYCOUNT(a_Image) + 1]; - static const char Check2[ARRAYCOUNT(a_Image) - 4 * ARRAYCOUNT(a_Biomes) + 1]; + static const char Check1[4 * ARRAYCOUNT(a_Biomes) - ARRAYCOUNT(a_Image) + 1] = {}; + static const char Check2[ARRAYCOUNT(a_Image) - 4 * ARRAYCOUNT(a_Biomes) + 1] = {}; // Convert the biomes into color: for (size_t i = 0; i < ARRAYCOUNT(a_Biomes); i++) -- cgit v1.2.3 From 66ef05c765a7e66ec3d77cd1a1eaff4f03b28688 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 20 Sep 2014 18:41:21 +0200 Subject: QtBiomeVisualiser: Added support for loading Anvil worlds. --- Tools/QtBiomeVisualiser/ChunkSource.cpp | 241 ++++++++++++++++++++++++++ Tools/QtBiomeVisualiser/ChunkSource.h | 34 +++- Tools/QtBiomeVisualiser/MainWindow.cpp | 12 +- Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro | 38 +++- 4 files changed, 320 insertions(+), 5 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp index 2235816bc..54da2afe5 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.cpp +++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp @@ -3,6 +3,8 @@ #include #include "Generating/BioGen.h" #include "inifile/iniFile.h" +#include "StringCompression.h" +#include "WorldStorage/FastNBT.h" @@ -182,3 +184,242 @@ void BioGenSource::reload() + +//////////////////////////////////////////////////////////////////////////////// +// AnvilSource::AnvilFile + +class AnvilSource::AnvilFile +{ +public: + /** Coordinates of the region file. */ + int m_RegionX, m_RegionZ; + + /** True iff the file contains proper data. */ + bool m_IsValid; + + + + /** Creates a new instance with the specified region coords. Reads the file header. */ + AnvilFile(int a_RegionX, int a_RegionZ, const AString & a_WorldPath) : + m_RegionX(a_RegionX), + m_RegionZ(a_RegionZ), + m_IsValid(false) + { + readFile(Printf("%s/r.%d.%d.mca", a_WorldPath.c_str(), a_RegionX, a_RegionZ)); + } + + + + /** Returns the compressed data of the specified chunk. + Returns an empty string when chunk not present. */ + AString getChunkData(int a_ChunkX, int a_ChunkZ) + { + if (!m_IsValid) + { + return ""; + } + + // Translate to local coords: + int RelChunkX = a_ChunkX - m_RegionX * 32; + int RelChunkZ = a_ChunkZ - m_RegionZ * 32; + ASSERT((RelChunkX >= 0) && (RelChunkX < 32)); + ASSERT((RelChunkZ >= 0) && (RelChunkZ < 32)); + + // Get the chunk data location: + UInt32 chunkOffset = m_Header[RelChunkX + 32 * RelChunkZ] >> 8; + UInt32 numChunkSectors = m_Header[RelChunkX + 32 * RelChunkZ] & 0xff; + if ((chunkOffset < 2) || (numChunkSectors == 0)) + { + return ""; + } + + // Get the real data size: + const char * chunkData = m_FileData.data() + chunkOffset * 4096; + UInt32 chunkSize = GetBEInt(chunkData); + if ((chunkSize < 2) || (chunkSize / 4096 > numChunkSectors)) + { + // Bad data, bail out + return ""; + } + + // Check the compression method: + if (chunkData[4] != 2) + { + // Chunk is in an unknown compression + return ""; + } + chunkSize--; + + // Read the chunk data: + return m_FileData.substr(chunkOffset * 4096 + 5, chunkSize); + } + +protected: + AString m_FileData; + UInt32 m_Header[2048]; + + + /** Reads the whole specified file contents and parses the header. */ + void readFile(const AString & a_FileName) + { + // Read the entire file: + m_FileData = cFile::ReadWholeFile(a_FileName); + if (m_FileData.size() < sizeof(m_Header)) + { + return; + } + + // Parse the header - change endianness: + const char * hdr = m_FileData.data(); + for (size_t i = 0; i < ARRAYCOUNT(m_Header); i++) + { + m_Header[i] = GetBEInt(hdr + 4 * i); + } + m_IsValid = true; + } +}; + + + + + +//////////////////////////////////////////////////////////////////////////////// +// AnvilSource: + +AnvilSource::AnvilSource(QString a_WorldRegionFolder) : + m_WorldRegionFolder(a_WorldRegionFolder) +{ +} + + + + + +void AnvilSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) +{ + // Load the compressed data: + AString compressedChunkData = getCompressedChunkData(a_ChunkX, a_ChunkZ); + if (compressedChunkData.empty()) + { + return; + } + + // Uncompress the chunk data: + AString uncompressed; + int res = InflateString(compressedChunkData.data(), compressedChunkData.size(), uncompressed); + if (res != Z_OK) + { + return; + } + + // Parse the NBT data: + cParsedNBT nbt(uncompressed.data(), uncompressed.size()); + if (!nbt.IsValid()) + { + return; + } + + // Get the biomes out of the NBT: + int Level = nbt.FindChildByName(0, "Level"); + if (Level < 0) + { + return; + } + cChunkDef::BiomeMap biomeMap; + int mcsBiomes = nbt.FindChildByName(Level, "MCSBiomes"); + if ((mcsBiomes >= 0) && (nbt.GetDataLength(mcsBiomes) == sizeof(biomeMap))) + { + // Convert the biomes from BigEndian to platform native numbers: + const char * beBiomes = nbt.GetData(mcsBiomes); + for (size_t i = 0; i < ARRAYCOUNT(biomeMap); i++) + { + biomeMap[i] = (EMCSBiome)GetBEInt(beBiomes + 4 * i); + } + // Render the biomes: + Chunk::Image img; + biomesToImage(biomeMap, img); + a_DestChunk->setImage(img); + return; + } + + // MCS biomes not found, load Vanilla biomes instead: + int biomes = nbt.FindChildByName(Level, "Biomes"); + if ((biomes < 0) || (nbt.GetDataLength(biomes) != ARRAYCOUNT(biomeMap))) + { + return; + } + // Convert the biomes from Vanilla to EMCSBiome: + const char * vanillaBiomes = nbt.GetData(biomes); + for (size_t i = 0; i < ARRAYCOUNT(biomeMap); i++) + { + biomeMap[i] = EMCSBiome(vanillaBiomes[i]); + } + // Render the biomes: + Chunk::Image img; + biomesToImage(biomeMap, img); + a_DestChunk->setImage(img); +} + + + + + +void AnvilSource::reload() +{ + // Remove all files from the cache: + QMutexLocker lock(&m_Mtx); + m_Files.clear(); +} + + + + + +void AnvilSource::chunkToRegion(int a_ChunkX, int a_ChunkZ, int & a_RegionX, int & a_RegionZ) +{ + a_RegionX = a_ChunkX >> 5; + a_RegionZ = a_ChunkZ >> 5; +} + + + + + +AString AnvilSource::getCompressedChunkData(int a_ChunkX, int a_ChunkZ) +{ + return getAnvilFile(a_ChunkX, a_ChunkZ)->getChunkData(a_ChunkX, a_ChunkZ); +} + + + + + +AnvilSource::AnvilFilePtr AnvilSource::getAnvilFile(int a_ChunkX, int a_ChunkZ) +{ + int RegionX, RegionZ; + chunkToRegion(a_ChunkX, a_ChunkZ, RegionX, RegionZ); + + // Search the cache for the file: + QMutexLocker lock(&m_Mtx); + for (auto itr = m_Files.cbegin(), end = m_Files.cend(); itr != end; ++itr) + { + if (((*itr)->m_RegionX == RegionX) && ((*itr)->m_RegionZ == RegionZ)) + { + // Found the file in the cache, move it to front and return it: + AnvilFilePtr file(*itr); + m_Files.erase(itr); + m_Files.push_front(file); + return file; + } + } + + // File not in cache, create it: + AnvilFilePtr file(new AnvilFile(RegionX, RegionZ, m_WorldRegionFolder.toStdString())); + m_Files.push_front(file); + return file; +} + + + + + diff --git a/Tools/QtBiomeVisualiser/ChunkSource.h b/Tools/QtBiomeVisualiser/ChunkSource.h index 868e4a144..a5612da01 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.h +++ b/Tools/QtBiomeVisualiser/ChunkSource.h @@ -1,4 +1,5 @@ #pragma once +#include "Globals.h" #include #include #include "Chunk.h" @@ -64,11 +65,40 @@ class AnvilSource : public ChunkSource { public: - // TODO + /** Constructs a new AnvilSource based on the world path. */ + AnvilSource(QString a_WorldRegionFolder); // ChunkSource overrides: virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override; - virtual void reload() override {} + virtual void reload() override; + +protected: + class AnvilFile; + typedef std::shared_ptr AnvilFilePtr; + + + /** Folder where the individual Anvil Region files are located. */ + QString m_WorldRegionFolder; + + /** List of currently loaded files. Acts as a cache so that a file is not opened and closed over and over again. + Protected against multithreaded access by m_Mtx. */ + std::list m_Files; + + /** Guards m_Files agains multithreaded access. */ + QMutex m_Mtx; + + + /** Converts chunk coords to region coords. */ + void chunkToRegion(int a_ChunkX, int a_ChunkZ, int & a_RegionX, int & a_RegionZ); + + /** Returns the compressed data of the specified chunk. + Returns an empty string if the chunk is not available. */ + AString getCompressedChunkData(int a_ChunkX, int a_ChunkZ); + + /** Returns the file object that contains the specified chunk. + The file is taken from the cache if available there, otherwise it is created anew. */ + AnvilFilePtr getAnvilFile(int a_ChunkX, int a_ChunkZ); + }; diff --git a/Tools/QtBiomeVisualiser/MainWindow.cpp b/Tools/QtBiomeVisualiser/MainWindow.cpp index 65d0ccf5e..b6db806f9 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.cpp +++ b/Tools/QtBiomeVisualiser/MainWindow.cpp @@ -39,6 +39,10 @@ MainWindow::~MainWindow() void MainWindow::generate() { QString worldIni = QFileDialog::getOpenFileName(this, tr("Open world.ini"), QString(), tr("world.ini (world.ini)")); + if (worldIni.isEmpty()) + { + return; + } m_BiomeView->setChunkSource(std::shared_ptr(new BioGenSource(worldIni))); m_BiomeView->redraw(); } @@ -49,7 +53,13 @@ void MainWindow::generate() void MainWindow::open() { - // TODO + QString regionFolder = QFileDialog::getExistingDirectory(this, tr("Select the region folder"), QString()); + if (regionFolder.isEmpty()) + { + return; + } + m_BiomeView->setChunkSource(std::shared_ptr(new AnvilSource(regionFolder))); + m_BiomeView->redraw(); } diff --git a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro index e6b65e628..283e180f8 100644 --- a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro +++ b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro @@ -29,7 +29,24 @@ SOURCES += main.cpp\ ChunkCache.cpp \ Chunk.cpp \ ChunkSource.cpp \ - ChunkLoader.cpp + ChunkLoader.cpp \ + ../../src/StringCompression.cpp \ + ../../src/WorldStorage/FastNBT.cpp \ + ../../lib/zlib/adler32.c \ + ../../lib/zlib/compress.c \ + ../../lib/zlib/crc32.c \ + ../../lib/zlib/deflate.c \ + ../../lib/zlib/gzclose.c \ + ../../lib/zlib/gzlib.c \ + ../../lib/zlib/gzread.c \ + ../../lib/zlib/gzwrite.c \ + ../../lib/zlib/infback.c \ + ../../lib/zlib/inffast.c \ + ../../lib/zlib/inflate.c \ + ../../lib/zlib/inftrees.c \ + ../../lib/zlib/trees.c \ + ../../lib/zlib/uncompr.c \ + ../../lib/zlib/zutil.c HEADERS += MainWindow.h \ Globals.h \ @@ -48,7 +65,20 @@ HEADERS += MainWindow.h \ ChunkCache.h \ Chunk.h \ ChunkSource.h \ - ChunkLoader.h + ChunkLoader.h \ + ../../src/StringCompression.h \ + ../../src/WorldStorage/FastNBT.h \ + ../../lib/zlib/crc32.h \ + ../../lib/zlib/deflate.h \ + ../../lib/zlib/gzguts.h \ + ../../lib/zlib/inffast.h \ + ../../lib/zlib/inffixed.h \ + ../../lib/zlib/inflate.h \ + ../../lib/zlib/inftrees.h \ + ../../lib/zlib/trees.h \ + ../../lib/zlib/zconf.h \ + ../../lib/zlib/zlib.h \ + ../../lib/zlib/zutil.h INCLUDEPATH += $$_PRO_FILE_PWD_ \ $$_PRO_FILE_PWD_/../../src \ @@ -57,4 +87,8 @@ INCLUDEPATH += $$_PRO_FILE_PWD_ \ CONFIG += C++11 +OTHER_FILES += \ + ../../lib/zlib/example.c.txt \ + ../../lib/zlib/minigzip.c.txt + -- cgit v1.2.3 From 14123c6d1653b79b6c58e7766dc97e5d06bf1fc9 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 20 Sep 2014 23:03:13 +0200 Subject: QtBiomeVisualiser: Added list of vanilla worlds. --- Tools/QtBiomeVisualiser/MainWindow.cpp | 132 +++++++++++++++++++++++++++++++-- Tools/QtBiomeVisualiser/MainWindow.h | 20 +++++ 2 files changed, 145 insertions(+), 7 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/MainWindow.cpp b/Tools/QtBiomeVisualiser/MainWindow.cpp index b6db806f9..c56cf8bc2 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.cpp +++ b/Tools/QtBiomeVisualiser/MainWindow.cpp @@ -5,9 +5,13 @@ #include #include #include +#include +#include #include "inifile/iniFile.h" #include "ChunkSource.h" #include "Generating/BioGen.h" +#include "StringCompression.h" +#include "WorldStorage/FastNBT.h" @@ -16,6 +20,8 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent) { + initMinecraftPath(); + m_BiomeView = new BiomeView(this); setCentralWidget(m_BiomeView); @@ -66,8 +72,41 @@ void MainWindow::open() +void MainWindow::openVanillaWorld() +{ + QAction * action = qobject_cast(sender()); + if (action == nullptr) + { + return; + } + m_BiomeView->setChunkSource(std::shared_ptr(new AnvilSource(action->data().toString()))); + m_BiomeView->redraw(); +} + + + + + +void MainWindow::initMinecraftPath() +{ + #ifdef Q_OS_MAC + m_MinecraftPath = QDir::homePath() + QDir::toNativeSeparators("/Library/Application Support/minecraft"); + #elif defined Q_OS_WIN32 + QSettings ini(QSettings::IniFormat, QSettings::UserScope, ".minecraft", "minecraft1"); + m_MinecraftPath = QFileInfo(ini.fileName()).absolutePath(); + #else + m_MinecraftPath = QDir::homePath() + QDir::toNativeSeparators("/.minecraft"); + #endif +} + + + + + void MainWindow::createActions() { + createWorldActions(); + m_actGen = new QAction(tr("&Generate..."), this); m_actGen->setShortcut(tr("Ctrl+N")); m_actGen->setStatusTip(tr("Open a generator INI file and display the generated biomes")); @@ -93,15 +132,94 @@ void MainWindow::createActions() +void MainWindow::createWorldActions() +{ + QDir mc(m_MinecraftPath); + if (!mc.cd("saves")) + { + return; + } + + QDirIterator it(mc); + int key = 1; + while (it.hasNext()) + { + it.next(); + if (!it.fileInfo().isDir()) + { + continue; + } + QString name = getWorldName(it.filePath().toStdString()); + if (name.isEmpty()) + { + continue; + } + QAction * w = new QAction(this); + w->setText(name); + w->setData(it.filePath() + "/region"); + if (key < 10) + { + w->setShortcut("Ctrl+" + QString::number(key)); + key++; + } + connect(w, SIGNAL(triggered()), this, SLOT(openVanillaWorld())); + m_WorldActions.append(w); + } +} + + + + + void MainWindow::createMenus() { - QMenu * mFile = menuBar()->addMenu(tr("&World")); - mFile->addAction(m_actGen); - mFile->addAction(m_actOpen); - mFile->addSeparator(); - mFile->addAction(m_actReload); - mFile->addSeparator(); - mFile->addAction(m_actExit); + QMenu * file = menuBar()->addMenu(tr("&Map")); + file->addAction(m_actGen); + file->addSeparator(); + QMenu * worlds = file->addMenu(tr("Open existing")); + worlds->addActions(m_WorldActions); + if (m_WorldActions.empty()) + { + worlds->setEnabled(false); + } + file->addAction(m_actOpen); + file->addSeparator(); + file->addAction(m_actReload); + file->addSeparator(); + file->addAction(m_actExit); +} + + + + + +QString MainWindow::getWorldName(const AString & a_Path) +{ + AString levelData = cFile::ReadWholeFile(a_Path + "/level.dat"); + if (levelData.empty()) + { + // No such file / no data + return QString(); + } + + AString uncompressed; + if (UncompressStringGZIP(levelData.data(), levelData.size(), uncompressed) != Z_OK) + { + return QString(); + } + cParsedNBT nbt(uncompressed.data(), uncompressed.size()); + if (!nbt.IsValid()) + { + return QString(); + } + AString name = nbt.GetName(1); + OutputDebugStringA(name.c_str()); + int levelNameTag = nbt.FindTagByPath(nbt.GetRoot(), "Data\\LevelName"); + if ((levelNameTag <= 0) || (nbt.GetType(levelNameTag) != TAG_String)) + { + return QString(); + } + return QString::fromStdString(nbt.GetString(levelNameTag)); } diff --git a/Tools/QtBiomeVisualiser/MainWindow.h b/Tools/QtBiomeVisualiser/MainWindow.h index b37bf4120..997d7a5d2 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.h +++ b/Tools/QtBiomeVisualiser/MainWindow.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include "BiomeView.h" @@ -25,6 +26,9 @@ private slots: /** Opens an existing world and displays the loaded biomes. */ void open(); + /** Opens a vanilla world that is specified by the calling action. */ + void openVanillaWorld(); + protected: // Actions: QAction * m_actGen; @@ -32,12 +36,28 @@ protected: QAction * m_actReload; QAction * m_actExit; + /** List of actions that open the specific vanilla world. */ + QList m_WorldActions; + + /** Path to the vanilla folder. */ + QString m_MinecraftPath; + + + /** Initializes the m_MinecraftPath based on the proper MC path */ + void initMinecraftPath(); /** Creates the actions that the UI supports. */ void createActions(); + /** Creates the actions that open a specific vanilla world. Iterates over the minecraft saves folder. */ + void createWorldActions(); + /** Creates the menu bar and connects its events. */ void createMenus(); + + /** Returns the name of the vanilla world in the specified path. + Reads the level.dat file for the name. Returns an empty string on failure. */ + QString getWorldName(const AString & a_Path); }; -- cgit v1.2.3 From dda66ea6efaa1ae3305dae97a9ab9bdb4254cf46 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 21 Sep 2014 22:58:09 +0200 Subject: QtBiomeVisualiser: Added the base for INI editting. --- Tools/QtBiomeVisualiser/GeneratorSetupDlg.cpp | 125 ++++++++++++++++++++++++++ Tools/QtBiomeVisualiser/GeneratorSetupDlg.h | 53 +++++++++++ Tools/QtBiomeVisualiser/MainWindow.cpp | 77 +++++++++++++--- Tools/QtBiomeVisualiser/MainWindow.h | 25 ++++-- Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro | 6 +- 5 files changed, 266 insertions(+), 20 deletions(-) create mode 100644 Tools/QtBiomeVisualiser/GeneratorSetupDlg.cpp create mode 100644 Tools/QtBiomeVisualiser/GeneratorSetupDlg.h (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/GeneratorSetupDlg.cpp b/Tools/QtBiomeVisualiser/GeneratorSetupDlg.cpp new file mode 100644 index 000000000..e6037fa9b --- /dev/null +++ b/Tools/QtBiomeVisualiser/GeneratorSetupDlg.cpp @@ -0,0 +1,125 @@ +#include "Globals.h" +#include "GeneratorSetupDlg.h" +#include +#include +#include "Generating/BioGen.h" +#include "inifile/iniFile.h" + + + + + +static const QString s_GeneratorNames[] = +{ + QString("Checkerboard"), + QString("Constant"), + QString("DistortedVoronoi"), + QString("MultiStepMap"), + QString("TwoLevel"), + QString("Voronoi"), +}; + + + + + +GeneratorSetupDlg::GeneratorSetupDlg(const AString & a_IniFileName, QWidget * a_Parent) : + super(a_Parent), + m_IniFile(new cIniFile()) +{ + // The generator name is in a separate form layout at the top, always present: + m_cbGenerator = new QComboBox(); + m_cbGenerator->setMinimumWidth(300); + for (size_t i = 0; i < ARRAYCOUNT(s_GeneratorNames); i++) + { + m_cbGenerator->addItem(s_GeneratorNames[i]); + } + QFormLayout * nameLayout = new QFormLayout(); + nameLayout->addRow(new QLabel(tr("Generator")), m_cbGenerator); + + // The rest of the controls are in a dynamically created form layout: + m_FormLayout = new QFormLayout(); + + // The main layout joins these two vertically: + m_MainLayout = new QVBoxLayout(); + m_MainLayout->addLayout(nameLayout); + m_MainLayout->addLayout(m_FormLayout); + setLayout(m_MainLayout); + + // Load the INI file, if specified, otherwise set defaults: + if (!a_IniFileName.empty() && m_IniFile->ReadFile(a_IniFileName)) + { + m_cbGenerator->setCurrentText(QString::fromStdString(m_IniFile->GetValue("Generator", "BiomeGen"))); + } + else + { + m_IniFile->SetValue("Generator", "Generator", "Composable"); + m_IniFile->SetValue("Generator", "BiomeGen", m_cbGenerator->currentText().toStdString()); + bool dummy; + delete cBiomeGen::CreateBiomeGen(*m_IniFile, m_Seed, dummy); + } + updateFromIni(); + + // Connect the combo change even only after the data has been loaded: + connect(m_cbGenerator, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(generatorChanged(QString))); +} + + + + + +void GeneratorSetupDlg::generatorChanged(const QString & a_NewName) +{ + // Clear the current contents of the form layout by assigning it to a stack temporary: + { + m_MainLayout->takeAt(1); + QWidget().setLayout(m_FormLayout); + } + + // Re-create the layout: + m_FormLayout = new QFormLayout(); + m_MainLayout->addLayout(m_FormLayout); + + // Recreate the INI file: + m_IniFile->Clear(); + m_IniFile->SetValue("Generator", "Generator", "Composable"); + m_IniFile->SetValue("Generator", "BiomeGen", a_NewName.toStdString()); + + // Create a dummy biome gen from the INI file, this will create the defaults in the INI file: + bool dummy; + delete cBiomeGen::CreateBiomeGen(*m_IniFile, m_Seed, dummy); + + // Read all values from the INI file and put them into the form layout: + updateFromIni(); +} + + + + + +void GeneratorSetupDlg::updateFromIni() +{ + int keyID = m_IniFile->FindKey("Generator"); + if (keyID <= -1) + { + return; + } + int numItems = m_IniFile->GetNumValues(keyID); + for (int i = 0; i < numItems; i++) + { + AString itemName = m_IniFile->GetValueName(keyID, i); + AString itemValue = m_IniFile->GetValue(keyID, i); + if ((itemName == "Generator") || (itemName == "BiomeGen")) + { + // These special cases are not to be added + continue; + } + QLineEdit * edit = new QLineEdit(); + edit->setText(QString::fromStdString(itemValue)); + m_FormLayout->addRow(new QLabel(QString::fromStdString(itemName)), edit); + } // for i - INI values[] +} + + + + diff --git a/Tools/QtBiomeVisualiser/GeneratorSetupDlg.h b/Tools/QtBiomeVisualiser/GeneratorSetupDlg.h new file mode 100644 index 000000000..d7070e331 --- /dev/null +++ b/Tools/QtBiomeVisualiser/GeneratorSetupDlg.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include +#include +#include + + + + + +class cIniFile; + + + + + +class GeneratorSetupDlg : + public QDialog +{ + typedef QDialog super; + + Q_OBJECT + +public: + /** Creates the dialog and loads the contents of the INI file, if not empty. */ + explicit GeneratorSetupDlg(const std::string & a_IniFileName, QWidget * parent = nullptr); + +signals: + +public slots: + /** Called when the user selects a different generator from the top combobox. + Re-creates m_IniFile and updates the form layout. */ + void generatorChanged(const QString & a_NewName); + +protected: + QComboBox * m_cbGenerator; + QVBoxLayout * m_MainLayout; + QFormLayout * m_FormLayout; + + std::unique_ptr m_IniFile; + + int m_Seed; + + + /** Updates the form layout with the values from m_IniFile. */ + void updateFromIni(); +}; + + + + diff --git a/Tools/QtBiomeVisualiser/MainWindow.cpp b/Tools/QtBiomeVisualiser/MainWindow.cpp index c56cf8bc2..d2c1ae2c1 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.cpp +++ b/Tools/QtBiomeVisualiser/MainWindow.cpp @@ -12,6 +12,7 @@ #include "Generating/BioGen.h" #include "StringCompression.h" #include "WorldStorage/FastNBT.h" +#include "GeneratorSetupDlg.h" @@ -42,13 +43,37 @@ MainWindow::~MainWindow() -void MainWindow::generate() +void MainWindow::newGenerator() { + // TODO + + // (Re-)open the generator setup dialog: + m_GeneratorSetupDlg.reset(new GeneratorSetupDlg("")); + m_GeneratorSetupDlg->show(); + m_GeneratorSetupDlg->raise(); + + // TODO +} + + + + + +void MainWindow::openGenerator() +{ + // Let the user specify the world.ini file: QString worldIni = QFileDialog::getOpenFileName(this, tr("Open world.ini"), QString(), tr("world.ini (world.ini)")); if (worldIni.isEmpty()) { return; } + + // (Re-)open the generator setup dialog: + m_GeneratorSetupDlg.reset(new GeneratorSetupDlg(worldIni.toStdString())); + m_GeneratorSetupDlg->show(); + m_GeneratorSetupDlg->raise(); + + // Set the chunk source: m_BiomeView->setChunkSource(std::shared_ptr(new BioGenSource(worldIni))); m_BiomeView->redraw(); } @@ -57,13 +82,23 @@ void MainWindow::generate() -void MainWindow::open() +void MainWindow::openWorld() { + // Let the user specify the world: QString regionFolder = QFileDialog::getExistingDirectory(this, tr("Select the region folder"), QString()); if (regionFolder.isEmpty()) { return; } + + // Remove the generator setup dialog, if open: + if (m_GeneratorSetupDlg.get() != nullptr) + { + m_GeneratorSetupDlg->hide(); + m_GeneratorSetupDlg.reset(nullptr); + } + + // Set the chunk source: m_BiomeView->setChunkSource(std::shared_ptr(new AnvilSource(regionFolder))); m_BiomeView->redraw(); } @@ -74,11 +109,21 @@ void MainWindow::open() void MainWindow::openVanillaWorld() { + // The world is stored in the sender action's data, retrieve it: QAction * action = qobject_cast(sender()); if (action == nullptr) { return; } + + // Remove the generator setup dialog, if open: + if (m_GeneratorSetupDlg.get() != nullptr) + { + m_GeneratorSetupDlg->hide(); + m_GeneratorSetupDlg.reset(nullptr); + } + + // Set the chunk source: m_BiomeView->setChunkSource(std::shared_ptr(new AnvilSource(action->data().toString()))); m_BiomeView->redraw(); } @@ -107,19 +152,24 @@ void MainWindow::createActions() { createWorldActions(); - m_actGen = new QAction(tr("&Generate..."), this); - m_actGen->setShortcut(tr("Ctrl+N")); - m_actGen->setStatusTip(tr("Open a generator INI file and display the generated biomes")); - connect(m_actGen, SIGNAL(triggered()), this, SLOT(generate())); + m_actNewGen = new QAction(tr("&New generator"), this); + m_actNewGen->setShortcut(tr("Ctrl+N")); + m_actNewGen->setStatusTip(tr("Open a generator INI file and display the generated biomes")); + connect(m_actNewGen, SIGNAL(triggered()), this, SLOT(newGenerator())); + + m_actOpenGen = new QAction(tr("&Open generator..."), this); + m_actOpenGen->setShortcut(tr("Ctrl+G")); + m_actOpenGen->setStatusTip(tr("Open a generator INI file and display the generated biomes")); + connect(m_actOpenGen, SIGNAL(triggered()), this, SLOT(openGenerator())); - m_actOpen = new QAction(tr("&Open world..."), this); - m_actOpen->setShortcut(tr("Ctrl+O")); - m_actOpen->setStatusTip(tr("Open an existing world and display its biomes")); - connect(m_actOpen, SIGNAL(triggered()), this, SLOT(open())); + m_actOpenWorld = new QAction(tr("&Open world..."), this); + m_actOpenWorld->setShortcut(tr("Ctrl+O")); + m_actOpenWorld->setStatusTip(tr("Open an existing world and display its biomes")); + connect(m_actOpenWorld, SIGNAL(triggered()), this, SLOT(openWorld())); m_actReload = new QAction(tr("&Reload"), this); m_actReload->setShortcut(tr("F5")); - m_actReload->setStatusTip(tr("Open an existing world and display its biomes")); + m_actReload->setStatusTip(tr("Clear the view cache and force a reload of all the data")); connect(m_actReload, SIGNAL(triggered()), m_BiomeView, SLOT(reload())); m_actExit = new QAction(tr("E&xit"), this); @@ -174,7 +224,8 @@ void MainWindow::createWorldActions() void MainWindow::createMenus() { QMenu * file = menuBar()->addMenu(tr("&Map")); - file->addAction(m_actGen); + file->addAction(m_actNewGen); + file->addAction(m_actOpenGen); file->addSeparator(); QMenu * worlds = file->addMenu(tr("Open existing")); worlds->addActions(m_WorldActions); @@ -182,7 +233,7 @@ void MainWindow::createMenus() { worlds->setEnabled(false); } - file->addAction(m_actOpen); + file->addAction(m_actOpenWorld); file->addSeparator(); file->addAction(m_actReload); file->addSeparator(); diff --git a/Tools/QtBiomeVisualiser/MainWindow.h b/Tools/QtBiomeVisualiser/MainWindow.h index 997d7a5d2..840e01b0f 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.h +++ b/Tools/QtBiomeVisualiser/MainWindow.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include "BiomeView.h" @@ -8,6 +9,13 @@ +// fwd: +class GeneratorSetupDlg; + + + + + class MainWindow : public QMainWindow { @@ -16,23 +24,27 @@ class MainWindow : BiomeView * m_BiomeView; public: - MainWindow(QWidget *parent = 0); + MainWindow(QWidget * parent = nullptr); ~MainWindow(); private slots: + /** Creates a generator definition from scratch, lets user modify generator params in realtime. */ + void newGenerator(); + /** Opens a generator definition and generates the biomes based on that. */ - void generate(); + void openGenerator(); /** Opens an existing world and displays the loaded biomes. */ - void open(); + void openWorld(); /** Opens a vanilla world that is specified by the calling action. */ void openVanillaWorld(); protected: // Actions: - QAction * m_actGen; - QAction * m_actOpen; + QAction * m_actNewGen; + QAction * m_actOpenGen; + QAction * m_actOpenWorld; QAction * m_actReload; QAction * m_actExit; @@ -42,6 +54,9 @@ protected: /** Path to the vanilla folder. */ QString m_MinecraftPath; + /** The dialog for setting up the generator. */ + std::unique_ptr m_GeneratorSetupDlg; + /** Initializes the m_MinecraftPath based on the proper MC path */ void initMinecraftPath(); diff --git a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro index 283e180f8..7171562bb 100644 --- a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro +++ b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro @@ -46,7 +46,8 @@ SOURCES += main.cpp\ ../../lib/zlib/inftrees.c \ ../../lib/zlib/trees.c \ ../../lib/zlib/uncompr.c \ - ../../lib/zlib/zutil.c + ../../lib/zlib/zutil.c \ + GeneratorSetupDlg.cpp HEADERS += MainWindow.h \ Globals.h \ @@ -78,7 +79,8 @@ HEADERS += MainWindow.h \ ../../lib/zlib/trees.h \ ../../lib/zlib/zconf.h \ ../../lib/zlib/zlib.h \ - ../../lib/zlib/zutil.h + ../../lib/zlib/zutil.h \ + GeneratorSetupDlg.h INCLUDEPATH += $$_PRO_FILE_PWD_ \ $$_PRO_FILE_PWD_/../../src \ -- cgit v1.2.3 From 10c5d5056691f0a03798c7e9439138126da30b8a Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 22 Sep 2014 18:26:35 +0200 Subject: QtBiomeVisualiser: Moved the generator setup into a side-pane. --- Tools/QtBiomeVisualiser/GeneratorSetup.cpp | 135 ++++++++++++++++++++++++++ Tools/QtBiomeVisualiser/GeneratorSetup.h | 57 +++++++++++ Tools/QtBiomeVisualiser/GeneratorSetupDlg.cpp | 125 ------------------------ Tools/QtBiomeVisualiser/GeneratorSetupDlg.h | 53 ---------- Tools/QtBiomeVisualiser/MainWindow.cpp | 69 +++++++++---- Tools/QtBiomeVisualiser/MainWindow.h | 24 ++++- Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro | 4 +- 7 files changed, 262 insertions(+), 205 deletions(-) create mode 100644 Tools/QtBiomeVisualiser/GeneratorSetup.cpp create mode 100644 Tools/QtBiomeVisualiser/GeneratorSetup.h delete mode 100644 Tools/QtBiomeVisualiser/GeneratorSetupDlg.cpp delete mode 100644 Tools/QtBiomeVisualiser/GeneratorSetupDlg.h (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/GeneratorSetup.cpp b/Tools/QtBiomeVisualiser/GeneratorSetup.cpp new file mode 100644 index 000000000..d512d2b90 --- /dev/null +++ b/Tools/QtBiomeVisualiser/GeneratorSetup.cpp @@ -0,0 +1,135 @@ +#include "Globals.h" +#include "GeneratorSetup.h" +#include +#include +#include "Generating/BioGen.h" +#include "inifile/iniFile.h" + + + + + +static const QString s_GeneratorNames[] = +{ + QString("Checkerboard"), + QString("Constant"), + QString("DistortedVoronoi"), + QString("MultiStepMap"), + QString("TwoLevel"), + QString("Voronoi"), +}; + + + + + +GeneratorSetup::GeneratorSetup(const AString & a_IniFileName, QWidget * a_Parent) : + super(a_Parent), + m_IniFile(new cIniFile()) +{ + // The generator name is in a separate form layout at the top, always present: + m_cbGenerator = new QComboBox(); + m_cbGenerator->setMinimumWidth(120); + for (size_t i = 0; i < ARRAYCOUNT(s_GeneratorNames); i++) + { + m_cbGenerator->addItem(s_GeneratorNames[i]); + } + QFormLayout * nameLayout = new QFormLayout(); + nameLayout->addRow(new QLabel(tr("Generator")), m_cbGenerator); + + // The rest of the controls are in a dynamically created form layout: + m_FormLayout = new QFormLayout(); + + // The main layout joins these two vertically: + m_MainLayout = new QVBoxLayout(); + m_MainLayout->addLayout(nameLayout); + m_MainLayout->addLayout(m_FormLayout); + m_MainLayout->addStretch(); + setLayout(m_MainLayout); + + // Load the INI file, if specified, otherwise set defaults: + if (!a_IniFileName.empty() && m_IniFile->ReadFile(a_IniFileName)) + { + m_cbGenerator->setCurrentText(QString::fromStdString(m_IniFile->GetValue("Generator", "BiomeGen"))); + } + else + { + m_IniFile->SetValue("Generator", "Generator", "Composable"); + m_IniFile->SetValue("Generator", "BiomeGen", m_cbGenerator->currentText().toStdString()); + bool dummy; + delete cBiomeGen::CreateBiomeGen(*m_IniFile, m_Seed, dummy); + } + updateFromIni(); + + // Connect the combo change even only after the data has been loaded: + connect(m_cbGenerator, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(generatorChanged(QString))); +} + + + + + +void GeneratorSetup::generatorChanged(const QString & a_NewName) +{ + // Clear the current contents of the form layout by assigning it to a stack temporary: + { + m_MainLayout->takeAt(1); + QWidget().setLayout(m_FormLayout); + } + + // Re-create the layout: + m_FormLayout = new QFormLayout(); + m_MainLayout->insertLayout(1, m_FormLayout); + + // Recreate the INI file: + m_IniFile->Clear(); + m_IniFile->SetValue("Generator", "Generator", "Composable"); + m_IniFile->SetValue("Generator", "BiomeGen", a_NewName.toStdString()); + + // Create a dummy biome gen from the INI file, this will create the defaults in the INI file: + bool dummy; + delete cBiomeGen::CreateBiomeGen(*m_IniFile, m_Seed, dummy); + + // Read all values from the INI file and put them into the form layout: + updateFromIni(); +} + + + + + +void GeneratorSetup::updateFromIni() +{ + int keyID = m_IniFile->FindKey("Generator"); + if (keyID <= -1) + { + return; + } + int numItems = m_IniFile->GetNumValues(keyID); + AString generatorName = m_IniFile->GetValue("Generator", "BiomeGen"); + size_t generatorNameLen = generatorName.length(); + for (int i = 0; i < numItems; i++) + { + AString itemName = m_IniFile->GetValueName(keyID, i); + AString itemValue = m_IniFile->GetValue(keyID, i); + if ((itemName == "Generator") || (itemName == "BiomeGen")) + { + // These special cases are not to be added + continue; + } + + // Remove the generator name prefix from the item name, for clarity purposes: + if (NoCaseCompare(itemName.substr(0, generatorNameLen), generatorName) == 0) + { + itemName.erase(0, generatorNameLen); + } + + QLineEdit * edit = new QLineEdit(); + edit->setText(QString::fromStdString(itemValue)); + m_FormLayout->addRow(new QLabel(QString::fromStdString(itemName)), edit); + } // for i - INI values[] +} + + + + diff --git a/Tools/QtBiomeVisualiser/GeneratorSetup.h b/Tools/QtBiomeVisualiser/GeneratorSetup.h new file mode 100644 index 000000000..0594e1998 --- /dev/null +++ b/Tools/QtBiomeVisualiser/GeneratorSetup.h @@ -0,0 +1,57 @@ +#pragma once + +#include +#include +#include +#include +#include + + + + + +class cIniFile; +typedef std::shared_ptr cIniFilePtr; + + + + + +class GeneratorSetup : + public QWidget +{ + typedef QWidget super; + + Q_OBJECT + +public: + /** Creates the widget and loads the contents of the INI file, if not empty. */ + explicit GeneratorSetup(const std::string & a_IniFileName, QWidget * parent = nullptr); + + /** Returns the cIniFile instance that is being edited by this widget. */ + cIniFilePtr getIniFile() { return m_IniFile; } + +signals: + +public slots: + /** Called when the user selects a different generator from the top combobox. + Re-creates m_IniFile and updates the form layout. */ + void generatorChanged(const QString & a_NewName); + +protected: + QComboBox * m_cbGenerator; + QVBoxLayout * m_MainLayout; + QFormLayout * m_FormLayout; + + cIniFilePtr m_IniFile; + + int m_Seed; + + + /** Updates the form layout with the values from m_IniFile. */ + void updateFromIni(); +}; + + + + diff --git a/Tools/QtBiomeVisualiser/GeneratorSetupDlg.cpp b/Tools/QtBiomeVisualiser/GeneratorSetupDlg.cpp deleted file mode 100644 index e6037fa9b..000000000 --- a/Tools/QtBiomeVisualiser/GeneratorSetupDlg.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#include "Globals.h" -#include "GeneratorSetupDlg.h" -#include -#include -#include "Generating/BioGen.h" -#include "inifile/iniFile.h" - - - - - -static const QString s_GeneratorNames[] = -{ - QString("Checkerboard"), - QString("Constant"), - QString("DistortedVoronoi"), - QString("MultiStepMap"), - QString("TwoLevel"), - QString("Voronoi"), -}; - - - - - -GeneratorSetupDlg::GeneratorSetupDlg(const AString & a_IniFileName, QWidget * a_Parent) : - super(a_Parent), - m_IniFile(new cIniFile()) -{ - // The generator name is in a separate form layout at the top, always present: - m_cbGenerator = new QComboBox(); - m_cbGenerator->setMinimumWidth(300); - for (size_t i = 0; i < ARRAYCOUNT(s_GeneratorNames); i++) - { - m_cbGenerator->addItem(s_GeneratorNames[i]); - } - QFormLayout * nameLayout = new QFormLayout(); - nameLayout->addRow(new QLabel(tr("Generator")), m_cbGenerator); - - // The rest of the controls are in a dynamically created form layout: - m_FormLayout = new QFormLayout(); - - // The main layout joins these two vertically: - m_MainLayout = new QVBoxLayout(); - m_MainLayout->addLayout(nameLayout); - m_MainLayout->addLayout(m_FormLayout); - setLayout(m_MainLayout); - - // Load the INI file, if specified, otherwise set defaults: - if (!a_IniFileName.empty() && m_IniFile->ReadFile(a_IniFileName)) - { - m_cbGenerator->setCurrentText(QString::fromStdString(m_IniFile->GetValue("Generator", "BiomeGen"))); - } - else - { - m_IniFile->SetValue("Generator", "Generator", "Composable"); - m_IniFile->SetValue("Generator", "BiomeGen", m_cbGenerator->currentText().toStdString()); - bool dummy; - delete cBiomeGen::CreateBiomeGen(*m_IniFile, m_Seed, dummy); - } - updateFromIni(); - - // Connect the combo change even only after the data has been loaded: - connect(m_cbGenerator, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(generatorChanged(QString))); -} - - - - - -void GeneratorSetupDlg::generatorChanged(const QString & a_NewName) -{ - // Clear the current contents of the form layout by assigning it to a stack temporary: - { - m_MainLayout->takeAt(1); - QWidget().setLayout(m_FormLayout); - } - - // Re-create the layout: - m_FormLayout = new QFormLayout(); - m_MainLayout->addLayout(m_FormLayout); - - // Recreate the INI file: - m_IniFile->Clear(); - m_IniFile->SetValue("Generator", "Generator", "Composable"); - m_IniFile->SetValue("Generator", "BiomeGen", a_NewName.toStdString()); - - // Create a dummy biome gen from the INI file, this will create the defaults in the INI file: - bool dummy; - delete cBiomeGen::CreateBiomeGen(*m_IniFile, m_Seed, dummy); - - // Read all values from the INI file and put them into the form layout: - updateFromIni(); -} - - - - - -void GeneratorSetupDlg::updateFromIni() -{ - int keyID = m_IniFile->FindKey("Generator"); - if (keyID <= -1) - { - return; - } - int numItems = m_IniFile->GetNumValues(keyID); - for (int i = 0; i < numItems; i++) - { - AString itemName = m_IniFile->GetValueName(keyID, i); - AString itemValue = m_IniFile->GetValue(keyID, i); - if ((itemName == "Generator") || (itemName == "BiomeGen")) - { - // These special cases are not to be added - continue; - } - QLineEdit * edit = new QLineEdit(); - edit->setText(QString::fromStdString(itemValue)); - m_FormLayout->addRow(new QLabel(QString::fromStdString(itemName)), edit); - } // for i - INI values[] -} - - - - diff --git a/Tools/QtBiomeVisualiser/GeneratorSetupDlg.h b/Tools/QtBiomeVisualiser/GeneratorSetupDlg.h deleted file mode 100644 index d7070e331..000000000 --- a/Tools/QtBiomeVisualiser/GeneratorSetupDlg.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - - - - - -class cIniFile; - - - - - -class GeneratorSetupDlg : - public QDialog -{ - typedef QDialog super; - - Q_OBJECT - -public: - /** Creates the dialog and loads the contents of the INI file, if not empty. */ - explicit GeneratorSetupDlg(const std::string & a_IniFileName, QWidget * parent = nullptr); - -signals: - -public slots: - /** Called when the user selects a different generator from the top combobox. - Re-creates m_IniFile and updates the form layout. */ - void generatorChanged(const QString & a_NewName); - -protected: - QComboBox * m_cbGenerator; - QVBoxLayout * m_MainLayout; - QFormLayout * m_FormLayout; - - std::unique_ptr m_IniFile; - - int m_Seed; - - - /** Updates the form layout with the values from m_IniFile. */ - void updateFromIni(); -}; - - - - diff --git a/Tools/QtBiomeVisualiser/MainWindow.cpp b/Tools/QtBiomeVisualiser/MainWindow.cpp index d2c1ae2c1..f9915901d 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.cpp +++ b/Tools/QtBiomeVisualiser/MainWindow.cpp @@ -12,19 +12,27 @@ #include "Generating/BioGen.h" #include "StringCompression.h" #include "WorldStorage/FastNBT.h" -#include "GeneratorSetupDlg.h" +#include "GeneratorSetup.h" MainWindow::MainWindow(QWidget * parent) : - QMainWindow(parent) + QMainWindow(parent), + m_GeneratorSetup(nullptr), + m_LineSeparator(nullptr) { initMinecraftPath(); - m_BiomeView = new BiomeView(this); - setCentralWidget(m_BiomeView); + m_BiomeView = new BiomeView(); + m_MainLayout = new QHBoxLayout(); + m_MainLayout->addWidget(m_BiomeView); + m_MainLayout->setMenuBar(menuBar()); + m_MainLayout->setMargin(0); + QWidget * central = new QWidget(); + central->setLayout(m_MainLayout); + setCentralWidget(central); createActions(); createMenus(); @@ -48,9 +56,7 @@ void MainWindow::newGenerator() // TODO // (Re-)open the generator setup dialog: - m_GeneratorSetupDlg.reset(new GeneratorSetupDlg("")); - m_GeneratorSetupDlg->show(); - m_GeneratorSetupDlg->raise(); + openGeneratorSetup(""); // TODO } @@ -69,9 +75,7 @@ void MainWindow::openGenerator() } // (Re-)open the generator setup dialog: - m_GeneratorSetupDlg.reset(new GeneratorSetupDlg(worldIni.toStdString())); - m_GeneratorSetupDlg->show(); - m_GeneratorSetupDlg->raise(); + openGeneratorSetup(worldIni.toStdString()); // Set the chunk source: m_BiomeView->setChunkSource(std::shared_ptr(new BioGenSource(worldIni))); @@ -92,11 +96,7 @@ void MainWindow::openWorld() } // Remove the generator setup dialog, if open: - if (m_GeneratorSetupDlg.get() != nullptr) - { - m_GeneratorSetupDlg->hide(); - m_GeneratorSetupDlg.reset(nullptr); - } + closeGeneratorSetup(); // Set the chunk source: m_BiomeView->setChunkSource(std::shared_ptr(new AnvilSource(regionFolder))); @@ -117,11 +117,7 @@ void MainWindow::openVanillaWorld() } // Remove the generator setup dialog, if open: - if (m_GeneratorSetupDlg.get() != nullptr) - { - m_GeneratorSetupDlg->hide(); - m_GeneratorSetupDlg.reset(nullptr); - } + closeGeneratorSetup(); // Set the chunk source: m_BiomeView->setChunkSource(std::shared_ptr(new AnvilSource(action->data().toString()))); @@ -276,3 +272,36 @@ QString MainWindow::getWorldName(const AString & a_Path) + +void MainWindow::openGeneratorSetup(const AString & a_IniFileName) +{ + // Close any previous editor: + closeGeneratorSetup(); + + // Open up a new editor: + m_GeneratorSetup = new GeneratorSetup(a_IniFileName); + m_LineSeparator = new QWidget(); + m_LineSeparator->setFixedWidth(2); + m_LineSeparator->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + m_LineSeparator->setStyleSheet(QString("background-color: #c0c0c0;")); + m_MainLayout->addWidget(m_LineSeparator); + m_MainLayout->addWidget(m_GeneratorSetup); +} + + + + + +void MainWindow::closeGeneratorSetup() +{ + delete m_MainLayout->takeAt(2); + delete m_MainLayout->takeAt(1); + delete m_GeneratorSetup; + delete m_LineSeparator; + m_GeneratorSetup = nullptr; + m_LineSeparator = nullptr; +} + + + + diff --git a/Tools/QtBiomeVisualiser/MainWindow.h b/Tools/QtBiomeVisualiser/MainWindow.h index 840e01b0f..6490a937f 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.h +++ b/Tools/QtBiomeVisualiser/MainWindow.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "BiomeView.h" @@ -10,7 +11,7 @@ // fwd: -class GeneratorSetupDlg; +class GeneratorSetup; @@ -21,8 +22,6 @@ class MainWindow : { Q_OBJECT - BiomeView * m_BiomeView; - public: MainWindow(QWidget * parent = nullptr); ~MainWindow(); @@ -54,8 +53,17 @@ protected: /** Path to the vanilla folder. */ QString m_MinecraftPath; - /** The dialog for setting up the generator. */ - std::unique_ptr m_GeneratorSetupDlg; + /** The pane for setting up the generator, available when visualising a generator. */ + GeneratorSetup * m_GeneratorSetup; + + /** The main biome display widget. */ + BiomeView * m_BiomeView; + + /** The layout for the window. */ + QHBoxLayout * m_MainLayout; + + /** The separator line between biome view and generator setup. */ + QWidget * m_LineSeparator; /** Initializes the m_MinecraftPath based on the proper MC path */ @@ -73,6 +81,12 @@ protected: /** Returns the name of the vanilla world in the specified path. Reads the level.dat file for the name. Returns an empty string on failure. */ QString getWorldName(const AString & a_Path); + + /** Opens the generator setup pane, if not already open, and loads the specified INI file to it. */ + void openGeneratorSetup(const AString & a_IniFileName); + + /** Closes and destroys the generator setup pane, if there is one. */ + void closeGeneratorSetup(); }; diff --git a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro index 7171562bb..2ed1be719 100644 --- a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro +++ b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro @@ -47,7 +47,7 @@ SOURCES += main.cpp\ ../../lib/zlib/trees.c \ ../../lib/zlib/uncompr.c \ ../../lib/zlib/zutil.c \ - GeneratorSetupDlg.cpp + GeneratorSetup.cpp HEADERS += MainWindow.h \ Globals.h \ @@ -80,7 +80,7 @@ HEADERS += MainWindow.h \ ../../lib/zlib/zconf.h \ ../../lib/zlib/zlib.h \ ../../lib/zlib/zutil.h \ - GeneratorSetupDlg.h + GeneratorSetup.h INCLUDEPATH += $$_PRO_FILE_PWD_ \ $$_PRO_FILE_PWD_/../../src \ -- cgit v1.2.3 From 583532e1b927e1b9af9782e35c7f2d089e997254 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 22 Sep 2014 18:33:18 +0200 Subject: QtBiomeVisualiser: generator source is read from generator setup ini. --- Tools/QtBiomeVisualiser/ChunkSource.cpp | 12 ++++-------- Tools/QtBiomeVisualiser/ChunkSource.h | 7 ++++--- Tools/QtBiomeVisualiser/MainWindow.cpp | 10 +++++----- 3 files changed, 13 insertions(+), 16 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp index 54da2afe5..d8cecbaa4 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.cpp +++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp @@ -142,8 +142,8 @@ static void biomesToImage(cChunkDef::BiomeMap & a_Biomes, Chunk::Image & a_Image //////////////////////////////////////////////////////////////////////////////// // BioGenSource: -BioGenSource::BioGenSource(QString a_WorldIniPath) : - m_WorldIniPath(a_WorldIniPath), +BioGenSource::BioGenSource(cIniFilePtr a_IniFile) : + m_IniFile(a_IniFile), m_Mtx(QMutex::Recursive) { reload(); @@ -171,14 +171,10 @@ void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChu void BioGenSource::reload() { - cIniFile ini; - ini.ReadFile(m_WorldIniPath.toStdString()); - int seed = ini.GetValueSetI("Seed", "Seed", 0); + int seed = m_IniFile->GetValueSetI("Seed", "Seed", 0); bool unused = false; QMutexLocker lock(&m_Mtx); - m_BiomeGen.reset(cBiomeGen::CreateBiomeGen(ini, seed, unused)); - lock.unlock(); - ini.WriteFile(m_WorldIniPath.toStdString()); + m_BiomeGen.reset(cBiomeGen::CreateBiomeGen(*m_IniFile, seed, unused)); } diff --git a/Tools/QtBiomeVisualiser/ChunkSource.h b/Tools/QtBiomeVisualiser/ChunkSource.h index a5612da01..05e8ac5de 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.h +++ b/Tools/QtBiomeVisualiser/ChunkSource.h @@ -12,6 +12,7 @@ class cBiomeGen; typedef std::shared_ptr cBiomeGenPtr; class cIniFile; +typedef std::shared_ptr cIniFilePtr; @@ -41,15 +42,15 @@ class BioGenSource : { public: /** Constructs a new BioGenSource based on the biome generator that is defined in the specified world.ini file. */ - BioGenSource(QString a_WorldIniPath); + BioGenSource(cIniFilePtr a_IniFile); // ChunkSource overrides: virtual void getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChunk) override; virtual void reload(void) override; protected: - /** Path to the world.ini file from which the m_WorldIni is regenerated on reload requests. */ - QString m_WorldIniPath; + /** The world.ini contents from which the generator is created and re-created on reload(). */ + cIniFilePtr m_IniFile; /** The generator used for generating biomes. */ std::unique_ptr m_BiomeGen; diff --git a/Tools/QtBiomeVisualiser/MainWindow.cpp b/Tools/QtBiomeVisualiser/MainWindow.cpp index f9915901d..c55d85082 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.cpp +++ b/Tools/QtBiomeVisualiser/MainWindow.cpp @@ -53,12 +53,12 @@ MainWindow::~MainWindow() void MainWindow::newGenerator() { - // TODO - - // (Re-)open the generator setup dialog: + // (Re-)open the generator setup dialog with empty settings: openGeneratorSetup(""); - // TODO + // Set the chunk source: + m_BiomeView->setChunkSource(std::shared_ptr(new BioGenSource(m_GeneratorSetup->getIniFile()))); + m_BiomeView->redraw(); } @@ -78,7 +78,7 @@ void MainWindow::openGenerator() openGeneratorSetup(worldIni.toStdString()); // Set the chunk source: - m_BiomeView->setChunkSource(std::shared_ptr(new BioGenSource(worldIni))); + m_BiomeView->setChunkSource(std::shared_ptr(new BioGenSource(m_GeneratorSetup->getIniFile()))); m_BiomeView->redraw(); } -- cgit v1.2.3 From 83588fb0aad5c8597df783792c946c27327f1a40 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 22 Sep 2014 21:51:59 +0200 Subject: QtBiomeVisualiser: Implemented live-update for the generator setup. --- Tools/QtBiomeVisualiser/ChunkSource.cpp | 2 +- Tools/QtBiomeVisualiser/GeneratorSetup.cpp | 44 +++++++++++++++++++++------ Tools/QtBiomeVisualiser/GeneratorSetup.h | 7 +++++ Tools/QtBiomeVisualiser/MainWindow.cpp | 9 ++++-- Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro | 4 +-- 5 files changed, 49 insertions(+), 17 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp index d8cecbaa4..f7174b624 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.cpp +++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp @@ -171,7 +171,7 @@ void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChu void BioGenSource::reload() { - int seed = m_IniFile->GetValueSetI("Seed", "Seed", 0); + int seed = m_IniFile->GetValueSetI("Generator", "Seed", 0); bool unused = false; QMutexLocker lock(&m_Mtx); m_BiomeGen.reset(cBiomeGen::CreateBiomeGen(*m_IniFile, seed, unused)); diff --git a/Tools/QtBiomeVisualiser/GeneratorSetup.cpp b/Tools/QtBiomeVisualiser/GeneratorSetup.cpp index d512d2b90..239965409 100644 --- a/Tools/QtBiomeVisualiser/GeneratorSetup.cpp +++ b/Tools/QtBiomeVisualiser/GeneratorSetup.cpp @@ -27,22 +27,27 @@ GeneratorSetup::GeneratorSetup(const AString & a_IniFileName, QWidget * a_Parent super(a_Parent), m_IniFile(new cIniFile()) { - // The generator name is in a separate form layout at the top, always present: + // The seed and generator name is in a separate form layout at the top, always present: + m_eSeed = new QLineEdit(); + m_eSeed->setValidator(new QIntValidator()); + m_eSeed->setText("0"); + m_eSeed->setProperty("INI.ItemName", QVariant("Seed")); m_cbGenerator = new QComboBox(); m_cbGenerator->setMinimumWidth(120); for (size_t i = 0; i < ARRAYCOUNT(s_GeneratorNames); i++) { m_cbGenerator->addItem(s_GeneratorNames[i]); } - QFormLayout * nameLayout = new QFormLayout(); - nameLayout->addRow(new QLabel(tr("Generator")), m_cbGenerator); + QFormLayout * baseLayout = new QFormLayout(); + baseLayout->addRow(new QLabel(tr("Seed")), m_eSeed); + baseLayout->addRow(new QLabel(tr("Generator")), m_cbGenerator); // The rest of the controls are in a dynamically created form layout: m_FormLayout = new QFormLayout(); // The main layout joins these two vertically: m_MainLayout = new QVBoxLayout(); - m_MainLayout->addLayout(nameLayout); + m_MainLayout->addLayout(baseLayout); m_MainLayout->addLayout(m_FormLayout); m_MainLayout->addStretch(); setLayout(m_MainLayout); @@ -51,18 +56,20 @@ GeneratorSetup::GeneratorSetup(const AString & a_IniFileName, QWidget * a_Parent if (!a_IniFileName.empty() && m_IniFile->ReadFile(a_IniFileName)) { m_cbGenerator->setCurrentText(QString::fromStdString(m_IniFile->GetValue("Generator", "BiomeGen"))); + m_eSeed->setText(QString::number(m_IniFile->GetValueI("Generator", "Seed"))); } else { m_IniFile->SetValue("Generator", "Generator", "Composable"); m_IniFile->SetValue("Generator", "BiomeGen", m_cbGenerator->currentText().toStdString()); bool dummy; - delete cBiomeGen::CreateBiomeGen(*m_IniFile, m_Seed, dummy); + delete cBiomeGen::CreateBiomeGen(*m_IniFile, 0, dummy); } updateFromIni(); - // Connect the combo change even only after the data has been loaded: - connect(m_cbGenerator, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(generatorChanged(QString))); + // Connect the change events only after the data has been loaded: + connect(m_cbGenerator, SIGNAL(currentIndexChanged(QString)), this, SLOT(generatorChanged(QString))); + connect(m_eSeed, SIGNAL(textChanged(QString)), this, SLOT(editChanged(QString))); } @@ -92,6 +99,20 @@ void GeneratorSetup::generatorChanged(const QString & a_NewName) // Read all values from the INI file and put them into the form layout: updateFromIni(); + + // Notify of the changes: + emit generatorUpdated(); +} + + + + + +void GeneratorSetup::editChanged(const QString & a_NewValue) +{ + QString itemName = sender()->property("INI.ItemName").toString(); + m_IniFile->SetValue("Generator", itemName.toStdString(), a_NewValue.toStdString()); + emit generatorUpdated(); } @@ -111,12 +132,16 @@ void GeneratorSetup::updateFromIni() for (int i = 0; i < numItems; i++) { AString itemName = m_IniFile->GetValueName(keyID, i); - AString itemValue = m_IniFile->GetValue(keyID, i); if ((itemName == "Generator") || (itemName == "BiomeGen")) { // These special cases are not to be added continue; } + AString itemValue = m_IniFile->GetValue(keyID, i); + + QLineEdit * edit = new QLineEdit(); + edit->setText(QString::fromStdString(itemValue)); + edit->setProperty("INI.ItemName", QVariant(QString::fromStdString(itemName))); // Remove the generator name prefix from the item name, for clarity purposes: if (NoCaseCompare(itemName.substr(0, generatorNameLen), generatorName) == 0) @@ -124,8 +149,7 @@ void GeneratorSetup::updateFromIni() itemName.erase(0, generatorNameLen); } - QLineEdit * edit = new QLineEdit(); - edit->setText(QString::fromStdString(itemValue)); + connect(edit, SIGNAL(textChanged(QString)), this, SLOT(editChanged(QString))); m_FormLayout->addRow(new QLabel(QString::fromStdString(itemName)), edit); } // for i - INI values[] } diff --git a/Tools/QtBiomeVisualiser/GeneratorSetup.h b/Tools/QtBiomeVisualiser/GeneratorSetup.h index 0594e1998..e72d3abbc 100644 --- a/Tools/QtBiomeVisualiser/GeneratorSetup.h +++ b/Tools/QtBiomeVisualiser/GeneratorSetup.h @@ -32,14 +32,21 @@ public: cIniFilePtr getIniFile() { return m_IniFile; } signals: + /** Emitted when the generator parameters have changed. */ + void generatorUpdated(); public slots: /** Called when the user selects a different generator from the top combobox. Re-creates m_IniFile and updates the form layout. */ void generatorChanged(const QString & a_NewName); +protected slots: + /** Called when any of the edit widgets are changed. */ + void editChanged(const QString & a_NewValue); + protected: QComboBox * m_cbGenerator; + QLineEdit * m_eSeed; QVBoxLayout * m_MainLayout; QFormLayout * m_FormLayout; diff --git a/Tools/QtBiomeVisualiser/MainWindow.cpp b/Tools/QtBiomeVisualiser/MainWindow.cpp index c55d85082..a2cfa7794 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.cpp +++ b/Tools/QtBiomeVisualiser/MainWindow.cpp @@ -27,7 +27,7 @@ MainWindow::MainWindow(QWidget * parent) : m_BiomeView = new BiomeView(); m_MainLayout = new QHBoxLayout(); - m_MainLayout->addWidget(m_BiomeView); + m_MainLayout->addWidget(m_BiomeView, 1); m_MainLayout->setMenuBar(menuBar()); m_MainLayout->setMargin(0); QWidget * central = new QWidget(); @@ -57,7 +57,8 @@ void MainWindow::newGenerator() openGeneratorSetup(""); // Set the chunk source: - m_BiomeView->setChunkSource(std::shared_ptr(new BioGenSource(m_GeneratorSetup->getIniFile()))); + cIniFilePtr iniFile = m_GeneratorSetup->getIniFile(); + m_BiomeView->setChunkSource(std::shared_ptr(new BioGenSource(iniFile))); m_BiomeView->redraw(); } @@ -260,7 +261,6 @@ QString MainWindow::getWorldName(const AString & a_Path) return QString(); } AString name = nbt.GetName(1); - OutputDebugStringA(name.c_str()); int levelNameTag = nbt.FindTagByPath(nbt.GetRoot(), "Data\\LevelName"); if ((levelNameTag <= 0) || (nbt.GetType(levelNameTag) != TAG_String)) { @@ -286,6 +286,9 @@ void MainWindow::openGeneratorSetup(const AString & a_IniFileName) m_LineSeparator->setStyleSheet(QString("background-color: #c0c0c0;")); m_MainLayout->addWidget(m_LineSeparator); m_MainLayout->addWidget(m_GeneratorSetup); + + // Connect the signals from the setup pane: + connect(m_GeneratorSetup, SIGNAL(generatorUpdated()), m_BiomeView, SLOT(reload())); } diff --git a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro index 2ed1be719..4275f73eb 100644 --- a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro +++ b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro @@ -89,8 +89,6 @@ INCLUDEPATH += $$_PRO_FILE_PWD_ \ CONFIG += C++11 -OTHER_FILES += \ - ../../lib/zlib/example.c.txt \ - ../../lib/zlib/minigzip.c.txt +OTHER_FILES += -- cgit v1.2.3 From de163f013416dc6a55f04eba5b23a7f8a9002c74 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 23 Sep 2014 12:39:09 +0200 Subject: QtBiomeVisualiser: Fixed confusion about Globals.h. --- Tools/QtBiomeVisualiser/ChunkSource.cpp | 6 +++--- Tools/QtBiomeVisualiser/GeneratorSetup.cpp | 2 +- Tools/QtBiomeVisualiser/Globals.h | 24 ++++++++++++------------ Tools/QtBiomeVisualiser/MainWindow.cpp | 6 +++--- Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro | 4 ++-- 5 files changed, 21 insertions(+), 21 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp index f7174b624..28d184615 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.cpp +++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp @@ -1,10 +1,10 @@ #include "Globals.h" #include "ChunkSource.h" #include -#include "Generating/BioGen.h" +#include "src/Generating/BioGen.h" #include "inifile/iniFile.h" -#include "StringCompression.h" -#include "WorldStorage/FastNBT.h" +#include "src/StringCompression.h" +#include "src/WorldStorage/FastNBT.h" diff --git a/Tools/QtBiomeVisualiser/GeneratorSetup.cpp b/Tools/QtBiomeVisualiser/GeneratorSetup.cpp index 239965409..f5412404c 100644 --- a/Tools/QtBiomeVisualiser/GeneratorSetup.cpp +++ b/Tools/QtBiomeVisualiser/GeneratorSetup.cpp @@ -2,7 +2,7 @@ #include "GeneratorSetup.h" #include #include -#include "Generating/BioGen.h" +#include "src/Generating/BioGen.h" #include "inifile/iniFile.h" diff --git a/Tools/QtBiomeVisualiser/Globals.h b/Tools/QtBiomeVisualiser/Globals.h index d3c7f0675..8d2e913b7 100644 --- a/Tools/QtBiomeVisualiser/Globals.h +++ b/Tools/QtBiomeVisualiser/Globals.h @@ -238,14 +238,14 @@ template class SizeChecker; #ifndef TEST_GLOBALS // Common headers (part 1, without macros): - #include "StringUtils.h" - #include "OSSupport/Sleep.h" - #include "OSSupport/CriticalSection.h" - #include "OSSupport/Semaphore.h" - #include "OSSupport/Event.h" - #include "OSSupport/Thread.h" - #include "OSSupport/File.h" - #include "Logger.h" + #include "src/StringUtils.h" + #include "src/OSSupport/Sleep.h" + #include "src/OSSupport/CriticalSection.h" + #include "src/OSSupport/Semaphore.h" + #include "src/OSSupport/Event.h" + #include "src/OSSupport/Thread.h" + #include "src/OSSupport/File.h" + #include "src/Logger.h" #else // Logging functions void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); @@ -375,10 +375,10 @@ T Clamp(T a_Value, T a_Min, T a_Max) // Common headers (part 2, with macros): -#include "ChunkDef.h" -#include "BiomeDef.h" -#include "BlockID.h" -#include "BlockInfo.h" +#include "src/ChunkDef.h" +#include "src/BiomeDef.h" +#include "src/BlockID.h" +#include "src/BlockInfo.h" diff --git a/Tools/QtBiomeVisualiser/MainWindow.cpp b/Tools/QtBiomeVisualiser/MainWindow.cpp index a2cfa7794..eb45690c1 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.cpp +++ b/Tools/QtBiomeVisualiser/MainWindow.cpp @@ -9,9 +9,9 @@ #include #include "inifile/iniFile.h" #include "ChunkSource.h" -#include "Generating/BioGen.h" -#include "StringCompression.h" -#include "WorldStorage/FastNBT.h" +#include "src/Generating/BioGen.h" +#include "src/StringCompression.h" +#include "src/WorldStorage/FastNBT.h" #include "GeneratorSetup.h" diff --git a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro index 4275f73eb..d6630bd34 100644 --- a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro +++ b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro @@ -83,8 +83,8 @@ HEADERS += MainWindow.h \ GeneratorSetup.h INCLUDEPATH += $$_PRO_FILE_PWD_ \ - $$_PRO_FILE_PWD_/../../src \ - $$_PRO_FILE_PWD_/../../lib + $$_PRO_FILE_PWD_/../../lib \ + $$_PRO_FILE_PWD_/../../ CONFIG += C++11 -- cgit v1.2.3 From 34b83656b3dc0da7deb69851f6b8239e492d2862 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Wed, 24 Sep 2014 11:21:59 +0200 Subject: QtBiomeVisualiser: Fixed MSVC path-crossing. MSVC would occasionally compile the wrong CPP file - the same name, but wrong path. --- Tools/QtBiomeVisualiser/BiomeView.cpp | 2 +- Tools/QtBiomeVisualiser/Chunk.cpp | 36 ------------------------ Tools/QtBiomeVisualiser/Chunk.h | 40 --------------------------- Tools/QtBiomeVisualiser/ChunkSource.cpp | 2 +- Tools/QtBiomeVisualiser/ChunkSource.h | 2 +- Tools/QtBiomeVisualiser/QtBiomeVisualiser.cpp | 20 ++++++++++++++ Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro | 16 +++++++---- Tools/QtBiomeVisualiser/QtChunk.cpp | 35 +++++++++++++++++++++++ Tools/QtBiomeVisualiser/QtChunk.h | 40 +++++++++++++++++++++++++++ Tools/QtBiomeVisualiser/main.cpp | 20 -------------- 10 files changed, 109 insertions(+), 104 deletions(-) delete mode 100644 Tools/QtBiomeVisualiser/Chunk.cpp delete mode 100644 Tools/QtBiomeVisualiser/Chunk.h create mode 100644 Tools/QtBiomeVisualiser/QtBiomeVisualiser.cpp create mode 100644 Tools/QtBiomeVisualiser/QtChunk.cpp create mode 100644 Tools/QtBiomeVisualiser/QtChunk.h delete mode 100644 Tools/QtBiomeVisualiser/main.cpp (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/BiomeView.cpp b/Tools/QtBiomeVisualiser/BiomeView.cpp index bbaccb369..ce5a870cd 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.cpp +++ b/Tools/QtBiomeVisualiser/BiomeView.cpp @@ -1,6 +1,6 @@ #include "Globals.h" #include "BiomeView.h" -#include "Chunk.h" +#include "QtChunk.h" #include #include diff --git a/Tools/QtBiomeVisualiser/Chunk.cpp b/Tools/QtBiomeVisualiser/Chunk.cpp deleted file mode 100644 index d3419af9c..000000000 --- a/Tools/QtBiomeVisualiser/Chunk.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "Globals.h" -#include "Globals.h" -#include "Chunk.h" - - - - - -Chunk::Chunk() : - m_IsValid(false) -{ -} - - - - - -const uchar * Chunk::getImage(void) const -{ - ASSERT(m_IsValid); - return m_Image; -} - - - - - -void Chunk::setImage(const Image & a_Image) -{ - memcpy(m_Image, a_Image, sizeof(a_Image)); - m_IsValid = true; -} - - - - diff --git a/Tools/QtBiomeVisualiser/Chunk.h b/Tools/QtBiomeVisualiser/Chunk.h deleted file mode 100644 index 03e7bd1b3..000000000 --- a/Tools/QtBiomeVisualiser/Chunk.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include - - - - - -class Chunk -{ -public: - /** The type used for storing image data for a chunk. */ - typedef uchar Image[16 * 16 * 4]; - - - Chunk(void); - - /** Returns true iff the chunk data is valid - loaded or generated. */ - bool isValid(void) const { return m_IsValid; } - - /** Returns the image of the chunk's biomes. Assumes that the chunk is valid. */ - const uchar * getImage(void) const; - - /** Sets the image data for this chunk. */ - void setImage(const Image & a_Image); - -protected: - /** Flag that specifies if the chunk data is valid - loaded or generated. */ - bool m_IsValid; - - /** Cached rendered image of this chunk's biomes. Updated in render(). */ - Image m_Image; -}; - -typedef std::shared_ptr ChunkPtr; - - - - - diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp index 28d184615..bebf89a0a 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.cpp +++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp @@ -2,9 +2,9 @@ #include "ChunkSource.h" #include #include "src/Generating/BioGen.h" -#include "inifile/iniFile.h" #include "src/StringCompression.h" #include "src/WorldStorage/FastNBT.h" +#include "inifile/iniFile.h" diff --git a/Tools/QtBiomeVisualiser/ChunkSource.h b/Tools/QtBiomeVisualiser/ChunkSource.h index 05e8ac5de..7bd1865ff 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.h +++ b/Tools/QtBiomeVisualiser/ChunkSource.h @@ -2,7 +2,7 @@ #include "Globals.h" #include #include -#include "Chunk.h" +#include "QtChunk.h" diff --git a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.cpp b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.cpp new file mode 100644 index 000000000..f41cdcfb2 --- /dev/null +++ b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.cpp @@ -0,0 +1,20 @@ +#include "Globals.h" +#include "MainWindow.h" +#include + + + + + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow w; + w.show(); + + return a.exec(); +} + + + + diff --git a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro index d6630bd34..9e5d1303c 100644 --- a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro +++ b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro @@ -12,7 +12,7 @@ TARGET = QtBiomeVisualiser TEMPLATE = app -SOURCES += main.cpp\ +SOURCES +=\ MainWindow.cpp \ BiomeView.cpp \ ../../src/Generating/BioGen.cpp \ @@ -27,7 +27,6 @@ SOURCES += main.cpp\ ../../src/OSSupport/IsThread.cpp \ ../../src/BiomeDef.cpp \ ChunkCache.cpp \ - Chunk.cpp \ ChunkSource.cpp \ ChunkLoader.cpp \ ../../src/StringCompression.cpp \ @@ -47,7 +46,9 @@ SOURCES += main.cpp\ ../../lib/zlib/trees.c \ ../../lib/zlib/uncompr.c \ ../../lib/zlib/zutil.c \ - GeneratorSetup.cpp + GeneratorSetup.cpp \ + QtBiomeVisualiser.cpp \ + QtChunk.cpp HEADERS += MainWindow.h \ Globals.h \ @@ -64,7 +65,6 @@ HEADERS += MainWindow.h \ ../../src/OSSupport/IsThread.h \ ../../src/BiomeDef.h \ ChunkCache.h \ - Chunk.h \ ChunkSource.h \ ChunkLoader.h \ ../../src/StringCompression.h \ @@ -80,13 +80,19 @@ HEADERS += MainWindow.h \ ../../lib/zlib/zconf.h \ ../../lib/zlib/zlib.h \ ../../lib/zlib/zutil.h \ - GeneratorSetup.h + GeneratorSetup.h \ + QtChunk.h INCLUDEPATH += $$_PRO_FILE_PWD_ \ $$_PRO_FILE_PWD_/../../lib \ + $$_PRO_FILE_PWD_/../../lib/jsoncpp/include \ + $$_PRO_FILE_PWD_/../../lib/polarssl/include \ + $$_PRO_FILE_PWD_/../../lib/sqlite \ + $$_PRO_FILE_PWD_/../../lib/SQLiteCpp/include \ $$_PRO_FILE_PWD_/../../ + CONFIG += C++11 OTHER_FILES += diff --git a/Tools/QtBiomeVisualiser/QtChunk.cpp b/Tools/QtBiomeVisualiser/QtChunk.cpp new file mode 100644 index 000000000..80109b2f8 --- /dev/null +++ b/Tools/QtBiomeVisualiser/QtChunk.cpp @@ -0,0 +1,35 @@ +#include "Globals.h" +#include "QtChunk.h" + + + + + +Chunk::Chunk() : + m_IsValid(false) +{ +} + + + + + +const uchar * Chunk::getImage(void) const +{ + ASSERT(m_IsValid); + return m_Image; +} + + + + + +void Chunk::setImage(const Image & a_Image) +{ + memcpy(m_Image, a_Image, sizeof(a_Image)); + m_IsValid = true; +} + + + + diff --git a/Tools/QtBiomeVisualiser/QtChunk.h b/Tools/QtBiomeVisualiser/QtChunk.h new file mode 100644 index 000000000..03e7bd1b3 --- /dev/null +++ b/Tools/QtBiomeVisualiser/QtChunk.h @@ -0,0 +1,40 @@ +#pragma once + +#include + + + + + +class Chunk +{ +public: + /** The type used for storing image data for a chunk. */ + typedef uchar Image[16 * 16 * 4]; + + + Chunk(void); + + /** Returns true iff the chunk data is valid - loaded or generated. */ + bool isValid(void) const { return m_IsValid; } + + /** Returns the image of the chunk's biomes. Assumes that the chunk is valid. */ + const uchar * getImage(void) const; + + /** Sets the image data for this chunk. */ + void setImage(const Image & a_Image); + +protected: + /** Flag that specifies if the chunk data is valid - loaded or generated. */ + bool m_IsValid; + + /** Cached rendered image of this chunk's biomes. Updated in render(). */ + Image m_Image; +}; + +typedef std::shared_ptr ChunkPtr; + + + + + diff --git a/Tools/QtBiomeVisualiser/main.cpp b/Tools/QtBiomeVisualiser/main.cpp deleted file mode 100644 index f41cdcfb2..000000000 --- a/Tools/QtBiomeVisualiser/main.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "Globals.h" -#include "MainWindow.h" -#include - - - - - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - MainWindow w; - w.show(); - - return a.exec(); -} - - - - -- cgit v1.2.3 From 576d088f38564c796277659669551494bb55d6cc Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 27 Sep 2014 22:26:56 +0200 Subject: QtBiomeVisualiser: fixed compilation. --- Tools/QtBiomeVisualiser/Globals.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/Globals.h b/Tools/QtBiomeVisualiser/Globals.h index 8d2e913b7..e2e9a9970 100644 --- a/Tools/QtBiomeVisualiser/Globals.h +++ b/Tools/QtBiomeVisualiser/Globals.h @@ -158,8 +158,17 @@ template class SizeChecker; TypeName(const TypeName &); \ void operator =(const TypeName &) +// A macro that is used to mark unused local variables, to avoid pedantic warnings in gcc / clang / MSVC +// Note that in MSVC it requires the full type of X to be known +#define UNUSED_VAR(X) (void)(X) + // A macro that is used to mark unused function parameters, to avoid pedantic warnings in gcc -#define UNUSED(X) (void)(X) +// Written so that the full type of param needn't be known +#ifdef _MSC_VER + #define UNUSED(X) +#else + #define UNUSED UNUSED_VAR +#endif -- cgit v1.2.3 From ae36ba5d33b1ce61fab33ffc310da6bba38ca316 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 28 Sep 2014 13:08:00 +0100 Subject: Compilation fix --- Tools/ProtoProxy/Connection.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Tools') diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index c5916c1ca..eaf4fab02 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -1819,8 +1819,7 @@ bool cConnection::HandleServerKick(void) Reason.append(Split[4]); Reason.push_back(0); Reason.append(Split[5]); - AString ReasonBE16; - UTF8ToRawBEUTF16(Reason.data(), Reason.size(), ReasonBE16); + AString ReasonBE16 = UTF8ToRawBEUTF16(Reason.data(), Reason.size()); AString PacketStart("\xff"); PacketStart.push_back((ReasonBE16.size() / 2) / 256); PacketStart.push_back((ReasonBE16.size() / 2) % 256); -- cgit v1.2.3 From f424a0ec60afe92b9c0a4d7f56e422cc5e921401 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 29 Sep 2014 21:20:58 +0200 Subject: QtBiomeVisualiser: Seed is read properly. --- Tools/QtBiomeVisualiser/ChunkSource.cpp | 2 +- Tools/QtBiomeVisualiser/GeneratorSetup.cpp | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp index bebf89a0a..2d180f00f 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.cpp +++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp @@ -171,7 +171,7 @@ void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChu void BioGenSource::reload() { - int seed = m_IniFile->GetValueSetI("Generator", "Seed", 0); + int seed = m_IniFile->GetValueSetI("Seed", "Seed", 0); bool unused = false; QMutexLocker lock(&m_Mtx); m_BiomeGen.reset(cBiomeGen::CreateBiomeGen(*m_IniFile, seed, unused)); diff --git a/Tools/QtBiomeVisualiser/GeneratorSetup.cpp b/Tools/QtBiomeVisualiser/GeneratorSetup.cpp index f5412404c..d6348ee00 100644 --- a/Tools/QtBiomeVisualiser/GeneratorSetup.cpp +++ b/Tools/QtBiomeVisualiser/GeneratorSetup.cpp @@ -31,6 +31,7 @@ GeneratorSetup::GeneratorSetup(const AString & a_IniFileName, QWidget * a_Parent m_eSeed = new QLineEdit(); m_eSeed->setValidator(new QIntValidator()); m_eSeed->setText("0"); + m_eSeed->setProperty("INI.SectionName", QVariant("Seed")); m_eSeed->setProperty("INI.ItemName", QVariant("Seed")); m_cbGenerator = new QComboBox(); m_cbGenerator->setMinimumWidth(120); @@ -53,12 +54,7 @@ GeneratorSetup::GeneratorSetup(const AString & a_IniFileName, QWidget * a_Parent setLayout(m_MainLayout); // Load the INI file, if specified, otherwise set defaults: - if (!a_IniFileName.empty() && m_IniFile->ReadFile(a_IniFileName)) - { - m_cbGenerator->setCurrentText(QString::fromStdString(m_IniFile->GetValue("Generator", "BiomeGen"))); - m_eSeed->setText(QString::number(m_IniFile->GetValueI("Generator", "Seed"))); - } - else + if (a_IniFileName.empty() || !m_IniFile->ReadFile(a_IniFileName)) { m_IniFile->SetValue("Generator", "Generator", "Composable"); m_IniFile->SetValue("Generator", "BiomeGen", m_cbGenerator->currentText().toStdString()); @@ -110,8 +106,9 @@ void GeneratorSetup::generatorChanged(const QString & a_NewName) void GeneratorSetup::editChanged(const QString & a_NewValue) { - QString itemName = sender()->property("INI.ItemName").toString(); - m_IniFile->SetValue("Generator", itemName.toStdString(), a_NewValue.toStdString()); + QString sectionName = sender()->property("INI.SectionName").toString(); + QString itemName = sender()->property("INI.ItemName").toString(); + m_IniFile->SetValue(sectionName.toStdString(), itemName.toStdString(), a_NewValue.toStdString()); emit generatorUpdated(); } @@ -121,6 +118,7 @@ void GeneratorSetup::editChanged(const QString & a_NewValue) void GeneratorSetup::updateFromIni() { + m_eSeed->setText(QString::number(m_IniFile->GetValueI("Seed", "Seed", 0))); int keyID = m_IniFile->FindKey("Generator"); if (keyID <= -1) { @@ -141,6 +139,7 @@ void GeneratorSetup::updateFromIni() QLineEdit * edit = new QLineEdit(); edit->setText(QString::fromStdString(itemValue)); + edit->setProperty("INI.SectionName", QVariant("Generator")); edit->setProperty("INI.ItemName", QVariant(QString::fromStdString(itemName))); // Remove the generator name prefix from the item name, for clarity purposes: -- cgit v1.2.3 From f625b33d56f6a0ce98f03a24bf6cad8b5624ce07 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 3 Oct 2014 12:33:03 +0200 Subject: QtBiomeVisualiser: Zoom is now limited and aligned to steps. --- Tools/QtBiomeVisualiser/BiomeView.cpp | 78 ++++++++---------------- Tools/QtBiomeVisualiser/BiomeView.h | 23 +++++-- Tools/QtBiomeVisualiser/MainWindow.cpp | 107 +++++++++++++++++++++++++++++++++ Tools/QtBiomeVisualiser/MainWindow.h | 20 ++++++ 4 files changed, 169 insertions(+), 59 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/BiomeView.cpp b/Tools/QtBiomeVisualiser/BiomeView.cpp index ce5a870cd..8d53c8626 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.cpp +++ b/Tools/QtBiomeVisualiser/BiomeView.cpp @@ -80,6 +80,27 @@ void BiomeView::setChunkSource(std::shared_ptr a_ChunkSource) +void BiomeView::setPosition(int a_BlockX, int a_BlockZ) +{ + m_X = a_BlockX; + m_Z = a_BlockZ; + redraw(); +} + + + + + +void BiomeView::setZoomLevel(double a_ZoomLevel) +{ + m_Zoom = a_ZoomLevel; + redraw(); +} + + + + + void BiomeView::redraw() { if (!hasData()) @@ -307,12 +328,12 @@ void BiomeView::wheelEvent(QWheelEvent * a_Event) m_MouseWheelDelta += a_Event->delta(); while (m_MouseWheelDelta >= DELTA_STEP) { - increaseZoom(); + emit wheelUp(); m_MouseWheelDelta -= DELTA_STEP; } while (m_MouseWheelDelta <= -DELTA_STEP) { - decreaseZoom(); + emit wheelDown(); m_MouseWheelDelta += DELTA_STEP; } } @@ -360,14 +381,14 @@ void BiomeView::keyPressEvent(QKeyEvent * a_Event) case Qt::Key_PageUp: case Qt::Key_Q: { - increaseZoom(); + emit increaseZoom(); break; } case Qt::Key_PageDown: case Qt::Key_E: { - decreaseZoom(); + emit decreaseZoom(); break; } } @@ -376,52 +397,3 @@ void BiomeView::keyPressEvent(QKeyEvent * a_Event) - -void BiomeView::decreaseZoom() -{ - if (m_Zoom > 1.001) - { - m_Zoom--; - if (m_Zoom < 1.0) - { - // Just crossed the 100%, fixate the 100% threshold: - m_Zoom = 1.0; - } - } - else if (m_Zoom > 0.01) - { - m_Zoom = m_Zoom / 2; - } - redraw(); -} - - - - - -void BiomeView::increaseZoom() -{ - if (m_Zoom > 0.99) - { - if (m_Zoom > 20.0) - { - // Zoom too large - return; - } - m_Zoom++; - } - else - { - m_Zoom = m_Zoom * 2; - if (m_Zoom > 1.0) - { - // Just crossed the 100%, fixate the 100% threshold: - m_Zoom = 1.0; - } - } - redraw(); -} - - - - diff --git a/Tools/QtBiomeVisualiser/BiomeView.h b/Tools/QtBiomeVisualiser/BiomeView.h index f0521571d..ae5dd2338 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.h +++ b/Tools/QtBiomeVisualiser/BiomeView.h @@ -25,7 +25,24 @@ public: The entire view is then invalidated and regenerated. */ void setChunkSource(std::shared_ptr a_ChunkSource); + /** Sets the position of the central pixel of the map to the specified point and redraws the view. */ + void setPosition(int a_BlockX, int a_BlockZ); + + /** Sets the zoom level to the specified value and redraws the view. */ + void setZoomLevel(double a_ZoomLevel); + signals: + /** Signalled when the user uses the wheel to scroll upwards. */ + void wheelUp(); + + /** Signalled when the user uses the wheel to scroll downwards. */ + void wheelDown(); + + /** Signalled when the user presses a key to increase zoom. */ + void increaseZoom(); + + /** Signalled when the user presses a key to decrease zoom. */ + void decreaseZoom(); public slots: /** Redraw the entire widget area. */ @@ -86,12 +103,6 @@ protected: /** Called when the user presses a key. */ virtual void keyPressEvent(QKeyEvent * a_Event) override; - - /** Decreases the zoom level and queues a redraw. */ - void decreaseZoom(); - - /** Increases the zoom level and queues a redraw. */ - void increaseZoom(); }; diff --git a/Tools/QtBiomeVisualiser/MainWindow.cpp b/Tools/QtBiomeVisualiser/MainWindow.cpp index eb45690c1..25a88d442 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.cpp +++ b/Tools/QtBiomeVisualiser/MainWindow.cpp @@ -18,6 +18,15 @@ +const double MainWindow::m_ViewZooms[] = +{ + 0.0625, 0.125, 0.25, 0.5, 1, 2, 4, 8, 16, 24, +}; + + + + + MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent), m_GeneratorSetup(nullptr), @@ -26,6 +35,11 @@ MainWindow::MainWindow(QWidget * parent) : initMinecraftPath(); m_BiomeView = new BiomeView(); + connect(m_BiomeView, SIGNAL(increaseZoom()), this, SLOT(increaseZoom())); + connect(m_BiomeView, SIGNAL(decreaseZoom()), this, SLOT(decreaseZoom())); + connect(m_BiomeView, SIGNAL(wheelUp()), this, SLOT(increaseZoom())); + connect(m_BiomeView, SIGNAL(wheelDown()), this, SLOT(decreaseZoom())); + m_MainLayout = new QHBoxLayout(); m_MainLayout->addWidget(m_BiomeView, 1); m_MainLayout->setMenuBar(menuBar()); @@ -129,6 +143,68 @@ void MainWindow::openVanillaWorld() +void MainWindow::centerView() +{ + m_BiomeView->setPosition(0, 0); +} + + + + + +void MainWindow::setViewZoom() +{ + // The zoom level is stored in the sender action's data, retrieve it: + QAction * action = qobject_cast(sender()); + if (action == nullptr) + { + return; + } + double newZoom = m_ViewZooms[action->data().toInt()]; + m_BiomeView->setZoomLevel(newZoom); + action->setChecked(true); +} + + + + + +void MainWindow::increaseZoom() +{ + // If already at max zoom, bail out: + if (m_CurrentZoomLevel >= ARRAYCOUNT(m_ViewZooms) - 1) + { + return; + } + + // Increase the zoom level: + m_CurrentZoomLevel += 1; + m_actViewZoom[m_CurrentZoomLevel]->setChecked(true); + m_BiomeView->setZoomLevel(m_ViewZooms[m_CurrentZoomLevel]); +} + + + + + +void MainWindow::decreaseZoom() +{ + // If already at min zoom, bail out: + if (m_CurrentZoomLevel == 0) + { + return; + } + + // Decrease the zoom level: + m_CurrentZoomLevel -= 1; + m_actViewZoom[m_CurrentZoomLevel]->setChecked(true); + m_BiomeView->setZoomLevel(m_ViewZooms[m_CurrentZoomLevel]); +} + + + + + void MainWindow::initMinecraftPath() { #ifdef Q_OS_MAC @@ -147,6 +223,7 @@ void MainWindow::initMinecraftPath() void MainWindow::createActions() { + // Map menu: createWorldActions(); m_actNewGen = new QAction(tr("&New generator"), this); @@ -173,6 +250,26 @@ void MainWindow::createActions() m_actExit->setShortcut(tr("Alt+X")); m_actExit->setStatusTip(tr("Exit %1").arg(QApplication::instance()->applicationName())); connect(m_actExit, SIGNAL(triggered()), this, SLOT(close())); + + // View menu: + m_actViewCenter = new QAction(tr("&Reset to center"), this); + m_actViewCenter->setStatusTip(tr("Scrolls the view back to the map center")); + connect(m_actViewCenter, SIGNAL(triggered()), this, SLOT(centerView())); + + QActionGroup * zoomGroup = new QActionGroup(this); + for (int i = 0; i < ARRAYCOUNT(m_ViewZooms); i++) + { + m_actViewZoom[i] = new QAction(tr("&Zoom %1%").arg(std::floor(m_ViewZooms[i] * 100)), this); + m_actViewZoom[i]->setCheckable(true); + if ((int)(m_ViewZooms[i] * 16) == 16) + { + m_actViewZoom[i]->setChecked(true); + m_CurrentZoomLevel = i; + } + m_actViewZoom[i]->setData(QVariant(i)); + zoomGroup->addAction(m_actViewZoom[i]); + connect(m_actViewZoom[i], SIGNAL(triggered()), this, SLOT(setViewZoom())); + } } @@ -220,6 +317,7 @@ void MainWindow::createWorldActions() void MainWindow::createMenus() { + // Map menu: QMenu * file = menuBar()->addMenu(tr("&Map")); file->addAction(m_actNewGen); file->addAction(m_actOpenGen); @@ -235,6 +333,15 @@ void MainWindow::createMenus() file->addAction(m_actReload); file->addSeparator(); file->addAction(m_actExit); + + // View menu: + QMenu * view = menuBar()->addMenu(tr("&View")); + view->addAction(m_actViewCenter); + view->addSeparator(); + for (size_t i = 0; i < ARRAYCOUNT(m_actViewZoom); i++) + { + view->addAction(m_actViewZoom[i]); + } } diff --git a/Tools/QtBiomeVisualiser/MainWindow.h b/Tools/QtBiomeVisualiser/MainWindow.h index 6490a937f..54a9cc6c7 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.h +++ b/Tools/QtBiomeVisualiser/MainWindow.h @@ -39,13 +39,30 @@ private slots: /** Opens a vanilla world that is specified by the calling action. */ void openVanillaWorld(); + /** Moves the view to the map's center. */ + void centerView(); + + /** Sets the zoom level specified in the triggering action. */ + void setViewZoom(); + + /** Sets a zoom level one step larger than current, if allowed. */ + void increaseZoom(); + + /** Sets a zoom level one step smaller than current, if allowed. */ + void decreaseZoom(); + protected: + /** The zoom levels */ + static const double m_ViewZooms[10]; + // Actions: QAction * m_actNewGen; QAction * m_actOpenGen; QAction * m_actOpenWorld; QAction * m_actReload; QAction * m_actExit; + QAction * m_actViewCenter; + QAction * m_actViewZoom[ARRAYCOUNT(m_ViewZooms)]; /** List of actions that open the specific vanilla world. */ QList m_WorldActions; @@ -65,6 +82,9 @@ protected: /** The separator line between biome view and generator setup. */ QWidget * m_LineSeparator; + /** Index into m_ViewZooms[] for the current zoom level. */ + size_t m_CurrentZoomLevel; + /** Initializes the m_MinecraftPath based on the proper MC path */ void initMinecraftPath(); -- cgit v1.2.3 From 0aa1b5667e0ba97101f60343323c595cc7866c6d Mon Sep 17 00:00:00 2001 From: Mattes D Date: Fri, 3 Oct 2014 19:41:42 +0200 Subject: QtBiomeVisualiser: Added mouse hover info. --- Tools/QtBiomeVisualiser/BiomeView.cpp | 19 +++- Tools/QtBiomeVisualiser/BiomeView.h | 3 + Tools/QtBiomeVisualiser/ChunkSource.cpp | 143 +--------------------------- Tools/QtBiomeVisualiser/MainWindow.cpp | 25 ++++- Tools/QtBiomeVisualiser/MainWindow.h | 11 +++ Tools/QtBiomeVisualiser/QtChunk.cpp | 159 +++++++++++++++++++++++++++++++- Tools/QtBiomeVisualiser/QtChunk.h | 15 ++- 7 files changed, 228 insertions(+), 147 deletions(-) (limited to 'Tools') diff --git a/Tools/QtBiomeVisualiser/BiomeView.cpp b/Tools/QtBiomeVisualiser/BiomeView.cpp index 8d53c8626..b44b935d7 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.cpp +++ b/Tools/QtBiomeVisualiser/BiomeView.cpp @@ -42,8 +42,9 @@ BiomeView::BiomeView(QWidget * parent) : // Add a chunk-update callback mechanism: connect(&m_Cache, SIGNAL(chunkAvailable(int, int)), this, SLOT(chunkAvailable(int, int))); - // Allow keyboard interaction: + // Allow mouse and keyboard interaction: setFocusPolicy(Qt::StrongFocus); + setMouseTracking(true); } @@ -296,6 +297,12 @@ void BiomeView::mousePressEvent(QMouseEvent * a_Event) void BiomeView::mouseMoveEvent(QMouseEvent * a_Event) { + // If there's no data displayed, bail out: + if (!hasData()) + { + return; + } + if (m_IsMouseDragging) { // The user is dragging the mouse, move the view around: @@ -307,7 +314,15 @@ void BiomeView::mouseMoveEvent(QMouseEvent * a_Event) return; } - // TODO: Update the status bar info for the biome currently pointed at + // Update the status bar info text: + int blockX = floor((a_Event->x() - width() / 2) / m_Zoom + m_X); + int blockZ = floor((a_Event->y() - height() / 2) / m_Zoom + m_Z); + int chunkX, chunkZ; + int relX = blockX, relY, relZ = blockZ; + cChunkDef::AbsoluteToRelative(relX, relY, relZ, chunkX, chunkZ); + auto chunk = m_Cache.fetch(chunkX, chunkZ); + int biome = (chunk.get() != nullptr) ? chunk->getBiome(relX, relZ) : biInvalidBiome; + emit hoverChanged(blockX, blockZ, biome); } diff --git a/Tools/QtBiomeVisualiser/BiomeView.h b/Tools/QtBiomeVisualiser/BiomeView.h index ae5dd2338..40d8b96ae 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.h +++ b/Tools/QtBiomeVisualiser/BiomeView.h @@ -44,6 +44,9 @@ signals: /** Signalled when the user presses a key to decrease zoom. */ void decreaseZoom(); + /** Emitted when the user moves the mouse, to reflect the current block under the cursor. */ + void hoverChanged(int a_BlockX, int a_BlockZ, int a_Biome); + public slots: /** Redraw the entire widget area. */ void redraw(); diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp index 2d180f00f..e5cd7a75a 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.cpp +++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp @@ -10,135 +10,6 @@ -/** Map for converting biome values to colors. Initialized from biomeColors[]. */ -static uchar biomeToColor[256 * 4]; - -/** Map for converting biome values to colors. Used to initialize biomeToColor[].*/ -static struct -{ - EMCSBiome m_Biome; - uchar m_Color[3]; -} biomeColors[] = -{ - { biOcean, { 0x00, 0x00, 0x70 }, }, - { biPlains, { 0x8d, 0xb3, 0x60 }, }, - { biDesert, { 0xfa, 0x94, 0x18 }, }, - { biExtremeHills, { 0x60, 0x60, 0x60 }, }, - { biForest, { 0x05, 0x66, 0x21 }, }, - { biTaiga, { 0x0b, 0x66, 0x59 }, }, - { biSwampland, { 0x2f, 0xff, 0xda }, }, - { biRiver, { 0x30, 0x30, 0xaf }, }, - { biHell, { 0x7f, 0x00, 0x00 }, }, - { biSky, { 0x00, 0x7f, 0xff }, }, - { biFrozenOcean, { 0xa0, 0xa0, 0xdf }, }, - { biFrozenRiver, { 0xa0, 0xa0, 0xff }, }, - { biIcePlains, { 0xff, 0xff, 0xff }, }, - { biIceMountains, { 0xa0, 0xa0, 0xa0 }, }, - { biMushroomIsland, { 0xff, 0x00, 0xff }, }, - { biMushroomShore, { 0xa0, 0x00, 0xff }, }, - { biBeach, { 0xfa, 0xde, 0x55 }, }, - { biDesertHills, { 0xd2, 0x5f, 0x12 }, }, - { biForestHills, { 0x22, 0x55, 0x1c }, }, - { biTaigaHills, { 0x16, 0x39, 0x33 }, }, - { biExtremeHillsEdge, { 0x7f, 0x8f, 0x7f }, }, - { biJungle, { 0x53, 0x7b, 0x09 }, }, - { biJungleHills, { 0x2c, 0x42, 0x05 }, }, - - { biJungleEdge, { 0x62, 0x8b, 0x17 }, }, - { biDeepOcean, { 0x00, 0x00, 0x30 }, }, - { biStoneBeach, { 0xa2, 0xa2, 0x84 }, }, - { biColdBeach, { 0xfa, 0xf0, 0xc0 }, }, - { biBirchForest, { 0x30, 0x74, 0x44 }, }, - { biBirchForestHills, { 0x1f, 0x5f, 0x32 }, }, - { biRoofedForest, { 0x40, 0x51, 0x1a }, }, - { biColdTaiga, { 0x31, 0x55, 0x4a }, }, - { biColdTaigaHills, { 0x59, 0x7d, 0x72 }, }, - { biMegaTaiga, { 0x59, 0x66, 0x51 }, }, - { biMegaTaigaHills, { 0x59, 0x66, 0x59 }, }, - { biExtremeHillsPlus, { 0x50, 0x70, 0x50 }, }, - { biSavanna, { 0xbd, 0xb2, 0x5f }, }, - { biSavannaPlateau, { 0xa7, 0x9d, 0x64 }, }, - { biMesa, { 0xd9, 0x45, 0x15 }, }, - { biMesaPlateauF, { 0xb0, 0x97, 0x65 }, }, - { biMesaPlateau, { 0xca, 0x8c, 0x65 }, }, - - // M variants: - { biSunflowerPlains, { 0xb5, 0xdb, 0x88 }, }, - { biDesertM, { 0xff, 0xbc, 0x40 }, }, - { biExtremeHillsM, { 0x88, 0x88, 0x88 }, }, - { biFlowerForest, { 0x2d, 0x8e, 0x49 }, }, - { biTaigaM, { 0x33, 0x8e, 0x81 }, }, - { biSwamplandM, { 0x07, 0xf9, 0xb2 }, }, - { biIcePlainsSpikes, { 0xb4, 0xdc, 0xdc }, }, - { biJungleM, { 0x7b, 0xa3, 0x31 }, }, - { biJungleEdgeM, { 0x62, 0x8b, 0x17 }, }, - { biBirchForestM, { 0x58, 0x9c, 0x6c }, }, - { biBirchForestHillsM, { 0x47, 0x87, 0x5a }, }, - { biRoofedForestM, { 0x68, 0x79, 0x42 }, }, - { biColdTaigaM, { 0x24, 0x3f, 0x36 }, }, - { biMegaSpruceTaiga, { 0x45, 0x4f, 0x3e }, }, - { biMegaSpruceTaigaHills, { 0x45, 0x4f, 0x4e }, }, - { biExtremeHillsPlusM, { 0x78, 0x98, 0x78 }, }, - { biSavannaM, { 0xe5, 0xda, 0x87 }, }, - { biSavannaPlateauM, { 0xa7, 0x9d, 0x74 }, }, - { biMesaBryce, { 0xff, 0x6d, 0x3d }, }, - { biMesaPlateauFM, { 0xd8, 0xbf, 0x8d }, }, - { biMesaPlateauM, { 0xf2, 0xb4, 0x8d }, }, -} ; - - - - - -static class BiomeColorsInitializer -{ -public: - BiomeColorsInitializer(void) - { - // Reset all colors to gray: - for (size_t i = 0; i < ARRAYCOUNT(biomeToColor); i++) - { - biomeToColor[i] = 0x7f; - } - - // Set known biomes to their colors: - for (size_t i = 0; i < ARRAYCOUNT(biomeColors); i++) - { - uchar * color = &biomeToColor[4 * biomeColors[i].m_Biome]; - color[0] = biomeColors[i].m_Color[2]; - color[1] = biomeColors[i].m_Color[1]; - color[2] = biomeColors[i].m_Color[0]; - color[3] = 0xff; - } - } -} biomeColorInitializer; - - - - - -/** Converts biomes in an array into the chunk image data. */ -static void biomesToImage(cChunkDef::BiomeMap & a_Biomes, Chunk::Image & a_Image) -{ - // Make sure the two arrays are of the same size, compile-time. - // Note that a_Image is actually 4 items per pixel, so the array is 4 times bigger: - static const char Check1[4 * ARRAYCOUNT(a_Biomes) - ARRAYCOUNT(a_Image) + 1] = {}; - static const char Check2[ARRAYCOUNT(a_Image) - 4 * ARRAYCOUNT(a_Biomes) + 1] = {}; - - // Convert the biomes into color: - for (size_t i = 0; i < ARRAYCOUNT(a_Biomes); i++) - { - a_Image[4 * i + 0] = biomeToColor[4 * a_Biomes[i] + 0]; - a_Image[4 * i + 1] = biomeToColor[4 * a_Biomes[i] + 1]; - a_Image[4 * i + 2] = biomeToColor[4 * a_Biomes[i] + 2]; - a_Image[4 * i + 3] = biomeToColor[4 * a_Biomes[i] + 3]; - } -} - - - - - //////////////////////////////////////////////////////////////////////////////// // BioGenSource: @@ -160,9 +31,7 @@ void BioGenSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChu QMutexLocker lock(&m_Mtx); m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, biomes); } - Chunk::Image img; - biomesToImage(biomes, img); - a_DestChunk->setImage(img); + a_DestChunk->setBiomes(biomes); } @@ -331,10 +200,7 @@ void AnvilSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChun { biomeMap[i] = (EMCSBiome)GetBEInt(beBiomes + 4 * i); } - // Render the biomes: - Chunk::Image img; - biomesToImage(biomeMap, img); - a_DestChunk->setImage(img); + a_DestChunk->setBiomes(biomeMap); return; } @@ -350,10 +216,7 @@ void AnvilSource::getChunkBiomes(int a_ChunkX, int a_ChunkZ, ChunkPtr a_DestChun { biomeMap[i] = EMCSBiome(vanillaBiomes[i]); } - // Render the biomes: - Chunk::Image img; - biomesToImage(biomeMap, img); - a_DestChunk->setImage(img); + a_DestChunk->setBiomes(biomeMap); } diff --git a/Tools/QtBiomeVisualiser/MainWindow.cpp b/Tools/QtBiomeVisualiser/MainWindow.cpp index 25a88d442..63d72f992 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.cpp +++ b/Tools/QtBiomeVisualiser/MainWindow.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "inifile/iniFile.h" #include "ChunkSource.h" #include "src/Generating/BioGen.h" @@ -40,6 +41,15 @@ MainWindow::MainWindow(QWidget * parent) : connect(m_BiomeView, SIGNAL(wheelUp()), this, SLOT(increaseZoom())); connect(m_BiomeView, SIGNAL(wheelDown()), this, SLOT(decreaseZoom())); + m_StatusBar = new QStatusBar(); + this->setStatusBar(m_StatusBar); + m_StatusBlockX = new QLabel(tr("X")); + m_StatusBlockZ = new QLabel(tr("Z")); + m_StatusBiome = new QLabel(tr("B")); + m_StatusBar->addPermanentWidget(m_StatusBlockX); + m_StatusBar->addPermanentWidget(m_StatusBlockZ); + m_StatusBar->addPermanentWidget(m_StatusBiome); + m_MainLayout = new QHBoxLayout(); m_MainLayout->addWidget(m_BiomeView, 1); m_MainLayout->setMenuBar(menuBar()); @@ -50,6 +60,8 @@ MainWindow::MainWindow(QWidget * parent) : createActions(); createMenus(); + + connect(m_BiomeView, SIGNAL(hoverChanged(int, int, int)), this, SLOT(hoverChanged(int, int, int))); } @@ -205,6 +217,17 @@ void MainWindow::decreaseZoom() +void MainWindow::hoverChanged(int a_BlockX, int a_BlockZ, int a_Biome) +{ + m_StatusBlockX->setText(tr("X: %1").arg(a_BlockX)); + m_StatusBlockZ->setText(tr("Z: %1").arg(a_BlockZ)); + m_StatusBiome->setText (tr("B: %1 (%2)").arg(BiomeToString(a_Biome).c_str()).arg(a_Biome)); +} + + + + + void MainWindow::initMinecraftPath() { #ifdef Q_OS_MAC @@ -322,7 +345,7 @@ void MainWindow::createMenus() file->addAction(m_actNewGen); file->addAction(m_actOpenGen); file->addSeparator(); - QMenu * worlds = file->addMenu(tr("Open existing")); + QMenu * worlds = file->addMenu(tr("Open &existing")); worlds->addActions(m_WorldActions); if (m_WorldActions.empty()) { diff --git a/Tools/QtBiomeVisualiser/MainWindow.h b/Tools/QtBiomeVisualiser/MainWindow.h index 54a9cc6c7..27faae7a8 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.h +++ b/Tools/QtBiomeVisualiser/MainWindow.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "BiomeView.h" @@ -51,6 +52,9 @@ private slots: /** Sets a zoom level one step smaller than current, if allowed. */ void decreaseZoom(); + /** Updates the statusbar for the specified info about the current block under the cursor. */ + void hoverChanged(int a_BlockX, int a_BlockZ, int a_Biome); + protected: /** The zoom levels */ static const double m_ViewZooms[10]; @@ -79,6 +83,13 @@ protected: /** The layout for the window. */ QHBoxLayout * m_MainLayout; + /** The status bar that displays the current hover information. */ + QStatusBar * m_StatusBar; + + QLabel * m_StatusBlockX; + QLabel * m_StatusBlockZ; + QLabel * m_StatusBiome; + /** The separator line between biome view and generator setup. */ QWidget * m_LineSeparator; diff --git a/Tools/QtBiomeVisualiser/QtChunk.cpp b/Tools/QtBiomeVisualiser/QtChunk.cpp index 80109b2f8..031aa3654 100644 --- a/Tools/QtBiomeVisualiser/QtChunk.cpp +++ b/Tools/QtBiomeVisualiser/QtChunk.cpp @@ -5,6 +5,138 @@ +/** Map for converting biome values to colors. Initialized from biomeColors[]. */ +static uchar biomeToColor[256 * 4]; + +/** Map for converting biome values to colors. Used to initialize biomeToColor[].*/ +static struct +{ + EMCSBiome m_Biome; + uchar m_Color[3]; +} biomeColors[] = +{ + { biOcean, { 0x00, 0x00, 0x70 }, }, + { biPlains, { 0x8d, 0xb3, 0x60 }, }, + { biDesert, { 0xfa, 0x94, 0x18 }, }, + { biExtremeHills, { 0x60, 0x60, 0x60 }, }, + { biForest, { 0x05, 0x66, 0x21 }, }, + { biTaiga, { 0x0b, 0x66, 0x59 }, }, + { biSwampland, { 0x2f, 0xff, 0xda }, }, + { biRiver, { 0x30, 0x30, 0xaf }, }, + { biHell, { 0x7f, 0x00, 0x00 }, }, + { biSky, { 0x00, 0x7f, 0xff }, }, + { biFrozenOcean, { 0xa0, 0xa0, 0xdf }, }, + { biFrozenRiver, { 0xa0, 0xa0, 0xff }, }, + { biIcePlains, { 0xff, 0xff, 0xff }, }, + { biIceMountains, { 0xa0, 0xa0, 0xa0 }, }, + { biMushroomIsland, { 0xff, 0x00, 0xff }, }, + { biMushroomShore, { 0xa0, 0x00, 0xff }, }, + { biBeach, { 0xfa, 0xde, 0x55 }, }, + { biDesertHills, { 0xd2, 0x5f, 0x12 }, }, + { biForestHills, { 0x22, 0x55, 0x1c }, }, + { biTaigaHills, { 0x16, 0x39, 0x33 }, }, + { biExtremeHillsEdge, { 0x7f, 0x8f, 0x7f }, }, + { biJungle, { 0x53, 0x7b, 0x09 }, }, + { biJungleHills, { 0x2c, 0x42, 0x05 }, }, + + { biJungleEdge, { 0x62, 0x8b, 0x17 }, }, + { biDeepOcean, { 0x00, 0x00, 0x30 }, }, + { biStoneBeach, { 0xa2, 0xa2, 0x84 }, }, + { biColdBeach, { 0xfa, 0xf0, 0xc0 }, }, + { biBirchForest, { 0x30, 0x74, 0x44 }, }, + { biBirchForestHills, { 0x1f, 0x5f, 0x32 }, }, + { biRoofedForest, { 0x40, 0x51, 0x1a }, }, + { biColdTaiga, { 0x31, 0x55, 0x4a }, }, + { biColdTaigaHills, { 0x59, 0x7d, 0x72 }, }, + { biMegaTaiga, { 0x59, 0x66, 0x51 }, }, + { biMegaTaigaHills, { 0x59, 0x66, 0x59 }, }, + { biExtremeHillsPlus, { 0x50, 0x70, 0x50 }, }, + { biSavanna, { 0xbd, 0xb2, 0x5f }, }, + { biSavannaPlateau, { 0xa7, 0x9d, 0x64 }, }, + { biMesa, { 0xd9, 0x45, 0x15 }, }, + { biMesaPlateauF, { 0xb0, 0x97, 0x65 }, }, + { biMesaPlateau, { 0xca, 0x8c, 0x65 }, }, + + // M variants: + { biSunflowerPlains, { 0xb5, 0xdb, 0x88 }, }, + { biDesertM, { 0xff, 0xbc, 0x40 }, }, + { biExtremeHillsM, { 0x88, 0x88, 0x88 }, }, + { biFlowerForest, { 0x2d, 0x8e, 0x49 }, }, + { biTaigaM, { 0x33, 0x8e, 0x81 }, }, + { biSwamplandM, { 0x07, 0xf9, 0xb2 }, }, + { biIcePlainsSpikes, { 0xb4, 0xdc, 0xdc }, }, + { biJungleM, { 0x7b, 0xa3, 0x31 }, }, + { biJungleEdgeM, { 0x62, 0x8b, 0x17 }, }, + { biBirchForestM, { 0x58, 0x9c, 0x6c }, }, + { biBirchForestHillsM, { 0x47, 0x87, 0x5a }, }, + { biRoofedForestM, { 0x68, 0x79, 0x42 }, }, + { biColdTaigaM, { 0x24, 0x3f, 0x36 }, }, + { biMegaSpruceTaiga, { 0x45, 0x4f, 0x3e }, }, + { biMegaSpruceTaigaHills, { 0x45, 0x4f, 0x4e }, }, + { biExtremeHillsPlusM, { 0x78, 0x98, 0x78 }, }, + { biSavannaM, { 0xe5, 0xda, 0x87 }, }, + { biSavannaPlateauM, { 0xa7, 0x9d, 0x74 }, }, + { biMesaBryce, { 0xff, 0x6d, 0x3d }, }, + { biMesaPlateauFM, { 0xd8, 0xbf, 0x8d }, }, + { biMesaPlateauM, { 0xf2, 0xb4, 0x8d }, }, +} ; + + + + + +static class BiomeColorsInitializer +{ +public: + BiomeColorsInitializer(void) + { + // Reset all colors to gray: + for (size_t i = 0; i < ARRAYCOUNT(biomeToColor); i++) + { + biomeToColor[i] = 0x7f; + } + + // Set known biomes to their colors: + for (size_t i = 0; i < ARRAYCOUNT(biomeColors); i++) + { + uchar * color = &biomeToColor[4 * biomeColors[i].m_Biome]; + color[0] = biomeColors[i].m_Color[2]; + color[1] = biomeColors[i].m_Color[1]; + color[2] = biomeColors[i].m_Color[0]; + color[3] = 0xff; + } + } +} biomeColorInitializer; + + + + + +/** Converts biomes in an array into the chunk image data. */ +static void biomesToImage(const cChunkDef::BiomeMap & a_Biomes, Chunk::Image & a_Image) +{ + // Make sure the two arrays are of the same size, compile-time. + // Note that a_Image is actually 4 items per pixel, so the array is 4 times bigger: + static const char Check1[4 * ARRAYCOUNT(a_Biomes) - ARRAYCOUNT(a_Image) + 1] = {}; + static const char Check2[ARRAYCOUNT(a_Image) - 4 * ARRAYCOUNT(a_Biomes) + 1] = {}; + + // Convert the biomes into color: + for (size_t i = 0; i < ARRAYCOUNT(a_Biomes); i++) + { + a_Image[4 * i + 0] = biomeToColor[4 * a_Biomes[i] + 0]; + a_Image[4 * i + 1] = biomeToColor[4 * a_Biomes[i] + 1]; + a_Image[4 * i + 2] = biomeToColor[4 * a_Biomes[i] + 2]; + a_Image[4 * i + 3] = biomeToColor[4 * a_Biomes[i] + 3]; + } +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// Chunk: + Chunk::Chunk() : m_IsValid(false) { @@ -24,12 +156,35 @@ const uchar * Chunk::getImage(void) const -void Chunk::setImage(const Image & a_Image) +void Chunk::setBiomes(const cChunkDef::BiomeMap & a_Biomes) { - memcpy(m_Image, a_Image, sizeof(a_Image)); + memcpy(m_Biomes, a_Biomes, sizeof(m_Biomes)); + renderBiomes(); m_IsValid = true; } + +EMCSBiome Chunk::getBiome(int a_RelX, int a_RelZ) +{ + if (!m_IsValid) + { + return biInvalidBiome; + } + return cChunkDef::GetBiome(m_Biomes, a_RelX, a_RelZ); +} + + + + + +void Chunk::renderBiomes() +{ + biomesToImage(m_Biomes, m_Image); +} + + + + diff --git a/Tools/QtBiomeVisualiser/QtChunk.h b/Tools/QtBiomeVisualiser/QtChunk.h index 03e7bd1b3..74321577a 100644 --- a/Tools/QtBiomeVisualiser/QtChunk.h +++ b/Tools/QtBiomeVisualiser/QtChunk.h @@ -21,8 +21,12 @@ public: /** Returns the image of the chunk's biomes. Assumes that the chunk is valid. */ const uchar * getImage(void) const; - /** Sets the image data for this chunk. */ - void setImage(const Image & a_Image); + /** Sets the biomes to m_Biomes and renders them into m_Image. */ + void setBiomes(const cChunkDef::BiomeMap & a_Biomes); + + /** Returns the biome at the specified relative coords, or biInvalidBiome if not valid. + Coords must be valid inside this chunk. */ + EMCSBiome getBiome(int a_RelX, int a_RelZ); protected: /** Flag that specifies if the chunk data is valid - loaded or generated. */ @@ -30,6 +34,13 @@ protected: /** Cached rendered image of this chunk's biomes. Updated in render(). */ Image m_Image; + + /** Biomes comprising the chunk, in the X + 16 * Z ordering. */ + cChunkDef::BiomeMap m_Biomes; + + + /** Renders biomes from m_Biomes into m_Image. */ + void renderBiomes(); }; typedef std::shared_ptr ChunkPtr; -- cgit v1.2.3