diff options
Diffstat (limited to 'Tools/QtBiomeVisualiser')
-rw-r--r-- | Tools/QtBiomeVisualiser/BiomeView.cpp | 185 | ||||
-rw-r--r-- | Tools/QtBiomeVisualiser/BiomeView.h | 41 | ||||
-rw-r--r-- | Tools/QtBiomeVisualiser/ChunkCache.cpp | 16 | ||||
-rw-r--r-- | Tools/QtBiomeVisualiser/ChunkCache.h | 6 | ||||
-rw-r--r-- | Tools/QtBiomeVisualiser/ChunkLoader.h | 2 | ||||
-rw-r--r-- | Tools/QtBiomeVisualiser/ChunkSource.cpp | 40 | ||||
-rw-r--r-- | Tools/QtBiomeVisualiser/ChunkSource.h | 24 | ||||
-rw-r--r-- | Tools/QtBiomeVisualiser/MainWindow.cpp | 27 | ||||
-rw-r--r-- | Tools/QtBiomeVisualiser/MainWindow.h | 1 | ||||
-rw-r--r-- | Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro | 4 |
10 files changed, 307 insertions, 39 deletions
diff --git a/Tools/QtBiomeVisualiser/BiomeView.cpp b/Tools/QtBiomeVisualiser/BiomeView.cpp index be01fd104..bbaccb369 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; @@ -33,6 +41,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); } @@ -120,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()) @@ -236,9 +262,164 @@ 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_MouseWheelDelta += a_Event->delta(); + while (m_MouseWheelDelta >= DELTA_STEP) + { + increaseZoom(); + m_MouseWheelDelta -= DELTA_STEP; + } + while (m_MouseWheelDelta <= -DELTA_STEP) + { + decreaseZoom(); + m_MouseWheelDelta += DELTA_STEP; + } +} + + + + + +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: + { + increaseZoom(); + break; + } + + case Qt::Key_PageDown: + case Qt::Key_E: + { + decreaseZoom(); + break; + } + } +} + + + + + +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 c54c66491..f0521571d 100644 --- a/Tools/QtBiomeVisualiser/BiomeView.h +++ b/Tools/QtBiomeVisualiser/BiomeView.h @@ -1,6 +1,7 @@ #pragma once #include <QWidget> +#include <memory> #include "ChunkCache.h" #include "ChunkSource.h" @@ -33,12 +34,28 @@ 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; - 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; + + /** 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]; @@ -55,8 +72,26 @@ 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; + + /** 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/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<ChunkSource> 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..8d198f02f 100644 --- a/Tools/QtBiomeVisualiser/ChunkCache.h +++ b/Tools/QtBiomeVisualiser/ChunkCache.h @@ -3,6 +3,7 @@ #include <QObject> #include <QCache> #include <QMutex> +#include <memory> @@ -36,7 +37,10 @@ public: void setChunkSource(std::shared_ptr<ChunkSource> 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/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 <QObject> #include <QRunnable> +#include <memory> diff --git a/Tools/QtBiomeVisualiser/ChunkSource.cpp b/Tools/QtBiomeVisualiser/ChunkSource.cpp index 44dcf1fa7..2235816bc 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.cpp +++ b/Tools/QtBiomeVisualiser/ChunkSource.cpp @@ -1,6 +1,8 @@ #include "Globals.h" #include "ChunkSource.h" +#include <QThread> #include "Generating/BioGen.h" +#include "inifile/iniFile.h" @@ -101,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; } } @@ -118,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++) @@ -138,9 +140,11 @@ 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_Mtx(QMutex::Recursive) { + reload(); } @@ -149,11 +153,11 @@ 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); cChunkDef::BiomeMap biomes; - m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, biomes); + { + QMutexLocker lock(&m_Mtx); + m_BiomeGen->GenBiomes(a_ChunkX, a_ChunkZ, biomes); + } Chunk::Image img; biomesToImage(biomes, img); a_DestChunk->setImage(img); @@ -162,3 +166,19 @@ 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); + bool unused = false; + QMutexLocker lock(&m_Mtx); + m_BiomeGen.reset(cBiomeGen::CreateBiomeGen(ini, seed, unused)); + lock.unlock(); + ini.WriteFile(m_WorldIniPath.toStdString()); +} + + + + diff --git a/Tools/QtBiomeVisualiser/ChunkSource.h b/Tools/QtBiomeVisualiser/ChunkSource.h index d6eb2e3cb..868e4a144 100644 --- a/Tools/QtBiomeVisualiser/ChunkSource.h +++ b/Tools/QtBiomeVisualiser/ChunkSource.h @@ -1,4 +1,6 @@ #pragma once +#include <QString> +#include <QMutex> #include "Chunk.h" @@ -7,6 +9,8 @@ // fwd: class cBiomeGen; +typedef std::shared_ptr<cBiomeGen> cBiomeGenPtr; +class cIniFile; @@ -21,6 +25,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,14 +39,21 @@ 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<cBiomeGen> m_BiomeGen; + /** Path to the world.ini file from which the m_WorldIni is regenerated on reload requests. */ + QString m_WorldIniPath; + + /** The generator used for generating biomes. */ + std::unique_ptr<cBiomeGen> m_BiomeGen; + + /** Guards m_BiomeGen against multithreaded access. */ QMutex m_Mtx; }; @@ -52,7 +66,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..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(); } @@ -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<BioGenSource>(new BioGenSource(biomeGen))); + m_BiomeView->setChunkSource(std::shared_ptr<BioGenSource>(new BioGenSource(worldIni))); m_BiomeView->redraw(); } @@ -80,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())); @@ -96,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; diff --git a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro index 0329d5607..e6b65e628 100644 --- a/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro +++ b/Tools/QtBiomeVisualiser/QtBiomeVisualiser.pro @@ -55,8 +55,6 @@ INCLUDEPATH += $$_PRO_FILE_PWD_ \ $$_PRO_FILE_PWD_/../../lib -CONFIG += STATIC - - +CONFIG += C++11 |