summaryrefslogtreecommitdiffstats
path: root/Tools/QtBiomeVisualiser
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/QtBiomeVisualiser')
-rw-r--r--Tools/QtBiomeVisualiser/BiomeView.cpp97
-rw-r--r--Tools/QtBiomeVisualiser/BiomeView.h26
-rw-r--r--Tools/QtBiomeVisualiser/ChunkSource.cpp143
-rw-r--r--Tools/QtBiomeVisualiser/MainWindow.cpp132
-rw-r--r--Tools/QtBiomeVisualiser/MainWindow.h31
-rw-r--r--Tools/QtBiomeVisualiser/QtChunk.cpp159
-rw-r--r--Tools/QtBiomeVisualiser/QtChunk.h15
7 files changed, 397 insertions, 206 deletions
diff --git a/Tools/QtBiomeVisualiser/BiomeView.cpp b/Tools/QtBiomeVisualiser/BiomeView.cpp
index ce5a870cd..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);
}
@@ -80,6 +81,27 @@ void BiomeView::setChunkSource(std::shared_ptr<ChunkSource> 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())
@@ -275,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:
@@ -286,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);
}
@@ -307,12 +343,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 +396,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 +412,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..40d8b96ae 100644
--- a/Tools/QtBiomeVisualiser/BiomeView.h
+++ b/Tools/QtBiomeVisualiser/BiomeView.h
@@ -25,7 +25,27 @@ public:
The entire view is then invalidated and regenerated. */
void setChunkSource(std::shared_ptr<ChunkSource> 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();
+
+ /** 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. */
@@ -86,12 +106,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/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 eb45690c1..63d72f992 100644
--- a/Tools/QtBiomeVisualiser/MainWindow.cpp
+++ b/Tools/QtBiomeVisualiser/MainWindow.cpp
@@ -7,6 +7,7 @@
#include <QFileDialog>
#include <QSettings>
#include <QDirIterator>
+#include <QStatusBar>
#include "inifile/iniFile.h"
#include "ChunkSource.h"
#include "src/Generating/BioGen.h"
@@ -18,6 +19,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 +36,20 @@ 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_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());
@@ -36,6 +60,8 @@ MainWindow::MainWindow(QWidget * parent) :
createActions();
createMenus();
+
+ connect(m_BiomeView, SIGNAL(hoverChanged(int, int, int)), this, SLOT(hoverChanged(int, int, int)));
}
@@ -129,6 +155,79 @@ 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<QAction *>(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::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
@@ -147,6 +246,7 @@ void MainWindow::initMinecraftPath()
void MainWindow::createActions()
{
+ // Map menu:
createWorldActions();
m_actNewGen = new QAction(tr("&New generator"), this);
@@ -173,6 +273,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,11 +340,12 @@ void MainWindow::createWorldActions()
void MainWindow::createMenus()
{
+ // Map menu:
QMenu * file = menuBar()->addMenu(tr("&Map"));
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())
{
@@ -235,6 +356,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..27faae7a8 100644
--- a/Tools/QtBiomeVisualiser/MainWindow.h
+++ b/Tools/QtBiomeVisualiser/MainWindow.h
@@ -4,6 +4,7 @@
#include <QList>
#include <QMainWindow>
#include <QHBoxLayout>
+#include <QLabel>
#include "BiomeView.h"
@@ -39,13 +40,33 @@ 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();
+
+ /** 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];
+
// 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<QAction *> m_WorldActions;
@@ -62,9 +83,19 @@ 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;
+ /** 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();
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<Chunk> ChunkPtr;