summaryrefslogtreecommitdiffstats
path: root/BiomeVisualiser
diff options
context:
space:
mode:
authormadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2013-02-03 21:37:13 +0100
committermadmaxoft@gmail.com <madmaxoft@gmail.com@0a769ca7-a7f5-676a-18bf-c427514a06d6>2013-02-03 21:37:13 +0100
commit2c214603e29f728804cd88522a1097de803ab321 (patch)
treea44010a49f1ef59b727982344c04aa8935d97564 /BiomeVisualiser
parentAdded a GetClassStatic function to all entities, as well as cFurnaceEntity, cChestEntity and cWorld (diff)
downloadcuberite-2c214603e29f728804cd88522a1097de803ab321.tar
cuberite-2c214603e29f728804cd88522a1097de803ab321.tar.gz
cuberite-2c214603e29f728804cd88522a1097de803ab321.tar.bz2
cuberite-2c214603e29f728804cd88522a1097de803ab321.tar.lz
cuberite-2c214603e29f728804cd88522a1097de803ab321.tar.xz
cuberite-2c214603e29f728804cd88522a1097de803ab321.tar.zst
cuberite-2c214603e29f728804cd88522a1097de803ab321.zip
Diffstat (limited to '')
-rw-r--r--BiomeVisualiser/BiomeCache.cpp333
-rw-r--r--BiomeVisualiser/BiomeCache.h96
-rw-r--r--BiomeVisualiser/BiomeRenderer.cpp147
-rw-r--r--BiomeVisualiser/BiomeRenderer.h50
-rw-r--r--BiomeVisualiser/BiomeSource.h37
-rw-r--r--BiomeVisualiser/BiomeViewWnd.cpp190
-rw-r--r--BiomeVisualiser/BiomeViewWnd.h46
-rw-r--r--BiomeVisualiser/BiomeVisualiser.cpp52
-rw-r--r--BiomeVisualiser/BiomeVisualiser.h31
-rw-r--r--BiomeVisualiser/BiomeVisualiser.sln23
-rw-r--r--BiomeVisualiser/BiomeVisualiser.vcproj483
-rw-r--r--BiomeVisualiser/GeneratorBiomeSource.h42
-rw-r--r--BiomeVisualiser/Pixmap.cpp120
-rw-r--r--BiomeVisualiser/Pixmap.h39
-rw-r--r--BiomeVisualiser/Timer.h40
-rw-r--r--BiomeVisualiser/WndProcThunk.h143
-rw-r--r--BiomeVisualiser/profile_run.cmd70
17 files changed, 1942 insertions, 0 deletions
diff --git a/BiomeVisualiser/BiomeCache.cpp b/BiomeVisualiser/BiomeCache.cpp
new file mode 100644
index 000000000..962f4a3f0
--- /dev/null
+++ b/BiomeVisualiser/BiomeCache.cpp
@@ -0,0 +1,333 @@
+
+// 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(MAXINT),
+ m_BaseZ(MAXINT),
+ 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 = MAXINT;
+ m_BaseZ = MAXINT;
+ 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)
+{
+ 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/BiomeVisualiser/BiomeCache.h b/BiomeVisualiser/BiomeCache.h
new file mode 100644
index 000000000..86602a19d
--- /dev/null
+++ b/BiomeVisualiser/BiomeCache.h
@@ -0,0 +1,96 @@
+
+// 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 "../source/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<pItem> 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<cThread *> 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/BiomeVisualiser/BiomeRenderer.cpp b/BiomeVisualiser/BiomeRenderer.cpp
new file mode 100644
index 000000000..00d6d684d
--- /dev/null
+++ b/BiomeVisualiser/BiomeRenderer.cpp
@@ -0,0 +1,147 @@
+
+// BiomeRenderer.cpp
+
+// Implements the cBiomeRenderer class representing the rendering engine
+
+#include "Globals.h"
+#include "BiomeRenderer.h"
+#include "Pixmap.h"
+#include "Timer.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 = MAXINT32;
+ int CurChunkZ = MAXINT32;
+ 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] = (EMCSBiome)-1;
+ }
+ 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 > biMaxBiome))
+ {
+ return 0xcfcfcf; // LtGray for unknown biomes
+ }
+
+ static int BiomeColor[] =
+ {
+ // RGB:
+ 0x0000ff, /* Ocean */
+ 0x00cf3f, /* Plains */
+ 0xffff00, /* Desert */
+ 0x7f7f7f, /* Extreme Hills */
+ 0x00cf00, /* Forest */
+ 0x007f3f, /* Taiga */
+ 0x3f7f00, /* Swampland */
+ 0x003fff, /* River */
+ 0x7f0000, /* Hell */
+ 0x007fff, /* Sky */
+ 0x3f3fff, /* Frozen Ocean */
+ 0x3f3fff, /* Frozen River */
+ 0x7fffcf, /* Ice Plains */
+ 0x3fcf7f, /* Ice Mountains */
+ 0xcf00cf, /* Mushroom Island */
+ 0x7f00ff, /* Mushroom Island Shore */
+ 0xffff3f, /* Beach */
+ 0xcfcf00, /* Desert Hills */
+ 0x00cf3f, /* Forest Hills */
+ 0x006f1f, /* Taiga Hills */
+ 0x7f8f7f, /* Extreme Hills Edge */
+ 0x004f00, /* Jungle */
+ 0x003f00, /* Jungle Hills */
+ } ;
+
+ return BiomeColor[a_Biome];
+}
+
+
+
+
+
+void cBiomeRenderer::MoveViewBy(int a_OffsX, int a_OffsY)
+{
+ m_OriginX += a_OffsX;
+ m_OriginY += a_OffsY;
+}
+
+
+
+
diff --git a/BiomeVisualiser/BiomeRenderer.h b/BiomeVisualiser/BiomeRenderer.h
new file mode 100644
index 000000000..369c0f114
--- /dev/null
+++ b/BiomeVisualiser/BiomeRenderer.h
@@ -0,0 +1,50 @@
+
+// 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);
+
+protected:
+ cBiomeCache m_Cache;
+
+ int m_OriginX;
+ int m_OriginY;
+ int m_Zoom;
+} ;
+
+
+
+
diff --git a/BiomeVisualiser/BiomeSource.h b/BiomeVisualiser/BiomeSource.h
new file mode 100644
index 000000000..e09242d04
--- /dev/null
+++ b/BiomeVisualiser/BiomeSource.h
@@ -0,0 +1,37 @@
+
+// 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/BiomeVisualiser/BiomeViewWnd.cpp b/BiomeVisualiser/BiomeViewWnd.cpp
new file mode 100644
index 000000000..cb634034c
--- /dev/null
+++ b/BiomeVisualiser/BiomeViewWnd.cpp
@@ -0,0 +1,190 @@
+
+// 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);
+
+ // 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);
+
+ cIniFile IniFile;
+ cBiomeGen * BioGen = new cBioGenMultiStepMap(0);
+ BioGen->Initialize(IniFile);
+ m_Renderer.SetSource(new cGeneratorBiomeSource(BioGen));
+
+ return true;
+}
+
+
+
+
+
+
+LRESULT cBiomeViewWnd::WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (a_Msg)
+ {
+ 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::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);
+ if (m_Renderer.Render(m_Pixmap))
+ {
+ SetTimer(m_Wnd, TIMER_RERENDER, 200, NULL);
+ }
+ m_MouseDown = pnt;
+ InvalidateRect(m_Wnd, NULL, FALSE);
+ 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/BiomeVisualiser/BiomeViewWnd.h b/BiomeVisualiser/BiomeViewWnd.h
new file mode 100644
index 000000000..d8ad8d182
--- /dev/null
+++ b/BiomeVisualiser/BiomeViewWnd.h
@@ -0,0 +1,46 @@
+
+// BiomeViewWnd.h
+
+// Declares the cBiomeViewWnd class representing the window that displays biomes
+
+#include "WndProcThunk.h"
+#include "BiomeRenderer.h"
+#include "BiomeCache.h"
+#include "Pixmap.h"
+
+
+
+
+
+class cBiomeViewWnd
+{
+public:
+ cBiomeViewWnd(void);
+
+ bool Create(HWND a_ParentWnd, LPCTSTR a_Title);
+
+protected:
+ HWND m_Wnd;
+ CWndProcThunk<cBiomeViewWnd> m_Thunk;
+
+ cBiomeRenderer m_Renderer;
+ cPixmap m_Pixmap;
+
+ bool m_IsLButtonDown;
+ POINT m_MouseDown;
+
+ LRESULT WndProc(HWND a_Wnd, UINT a_Msg, WPARAM wParam, LPARAM lParam);
+
+ // Message handlers:
+ 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/BiomeVisualiser/BiomeVisualiser.cpp b/BiomeVisualiser/BiomeVisualiser.cpp
new file mode 100644
index 000000000..dc1d490e8
--- /dev/null
+++ b/BiomeVisualiser/BiomeVisualiser.cpp
@@ -0,0 +1,52 @@
+
+// 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(Printf("BiomeVisualiser_%08x", 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/BiomeVisualiser/BiomeVisualiser.h b/BiomeVisualiser/BiomeVisualiser.h
new file mode 100644
index 000000000..4788bb7ea
--- /dev/null
+++ b/BiomeVisualiser/BiomeVisualiser.h
@@ -0,0 +1,31 @@
+
+// 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/BiomeVisualiser/BiomeVisualiser.sln b/BiomeVisualiser/BiomeVisualiser.sln
new file mode 100644
index 000000000..b10d65f2f
--- /dev/null
+++ b/BiomeVisualiser/BiomeVisualiser.sln
@@ -0,0 +1,23 @@
+
+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/BiomeVisualiser/BiomeVisualiser.vcproj b/BiomeVisualiser/BiomeVisualiser.vcproj
new file mode 100644
index 000000000..45eb337e3
--- /dev/null
+++ b/BiomeVisualiser/BiomeVisualiser.vcproj
@@ -0,0 +1,483 @@
+<?xml version="1.0" encoding="windows-1250"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="BiomeVisualiser"
+ ProjectGUID="{6DF3D88B-AD47-45B6-B831-1BDE74F86B5C}"
+ RootNamespace="BiomeVisualiser"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../source"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="Globals.h"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ AdditionalIncludeDirectories="../source"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ EnableEnhancedInstructionSet="2"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="Globals.h"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release profiled|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ AdditionalIncludeDirectories="../source"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ EnableEnhancedInstructionSet="2"
+ UsePrecompiledHeader="2"
+ PrecompiledHeaderThrough="Globals.h"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="ws2_32.lib"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="2"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ Profile="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\BiomeCache.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BiomeCache.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BiomeRenderer.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BiomeRenderer.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BiomeSource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BiomeViewWnd.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BiomeViewWnd.h"
+ >
+ </File>
+ <File
+ RelativePath=".\BiomeVisualiser.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\BiomeVisualiser.h"
+ >
+ </File>
+ <File
+ RelativePath=".\GeneratorBiomeSource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Pixmap.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\Pixmap.h"
+ >
+ </File>
+ <File
+ RelativePath=".\Timer.h"
+ >
+ </File>
+ <File
+ RelativePath=".\WndProcThunk.h"
+ >
+ </File>
+ <Filter
+ Name="Shared"
+ >
+ <File
+ RelativePath="..\source\BlockID.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\source\BlockID.h"
+ >
+ </File>
+ <File
+ RelativePath="..\source\ChunkDef.h"
+ >
+ </File>
+ <File
+ RelativePath="..\source\Globals.cpp"
+ >
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release profiled|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ UsePrecompiledHeader="1"
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\source\Globals.h"
+ >
+ </File>
+ <File
+ RelativePath="..\source\Log.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\source\Log.h"
+ >
+ </File>
+ <File
+ RelativePath="..\source\MCLogger.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\source\MCLogger.h"
+ >
+ </File>
+ <File
+ RelativePath="..\source\Noise.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\source\Noise.h"
+ >
+ </File>
+ <File
+ RelativePath="..\source\Noise.inc"
+ >
+ </File>
+ <File
+ RelativePath="..\source\StringUtils.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\source\StringUtils.h"
+ >
+ </File>
+ <Filter
+ Name="OSSupport"
+ >
+ <File
+ RelativePath="..\source\OSSupport\CriticalSection.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\source\OSSupport\CriticalSection.h"
+ >
+ </File>
+ <File
+ RelativePath="..\source\OSSupport\Event.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\source\OSSupport\Event.h"
+ >
+ </File>
+ <File
+ RelativePath="..\source\OSSupport\File.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\source\OSSupport\File.h"
+ >
+ </File>
+ <File
+ RelativePath="..\source\OSSupport\IsThread.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\source\OSSupport\IsThread.h"
+ >
+ </File>
+ <File
+ RelativePath="..\source\OSSupport\MakeDir.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\source\OSSupport\MakeDir.h"
+ >
+ </File>
+ <File
+ RelativePath="..\source\OSSupport\Sleep.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Generating"
+ >
+ <File
+ RelativePath="..\source\Generating\BioGen.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\source\Generating\BioGen.h"
+ >
+ </File>
+ <File
+ RelativePath="..\source\Generating\ComposableGenerator.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="iniFile"
+ >
+ <File
+ RelativePath="..\iniFile\iniFile.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\iniFile\iniFile.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/BiomeVisualiser/GeneratorBiomeSource.h b/BiomeVisualiser/GeneratorBiomeSource.h
new file mode 100644
index 000000000..34970491e
--- /dev/null
+++ b/BiomeVisualiser/GeneratorBiomeSource.h
@@ -0,0 +1,42 @@
+
+// GeneratorBiomeSource.h
+
+// Declares the cGeneratorBiomeSource that adapts a cBiomeGen into a cBiomeSource
+
+#include "../source/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/BiomeVisualiser/Pixmap.cpp b/BiomeVisualiser/Pixmap.cpp
new file mode 100644
index 000000000..39a015b9c
--- /dev/null
+++ b/BiomeVisualiser/Pixmap.cpp
@@ -0,0 +1,120 @@
+
+// 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/BiomeVisualiser/Pixmap.h b/BiomeVisualiser/Pixmap.h
new file mode 100644
index 000000000..d0159a886
--- /dev/null
+++ b/BiomeVisualiser/Pixmap.h
@@ -0,0 +1,39 @@
+
+// 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/BiomeVisualiser/Timer.h b/BiomeVisualiser/Timer.h
new file mode 100644
index 000000000..b18d37cb7
--- /dev/null
+++ b/BiomeVisualiser/Timer.h
@@ -0,0 +1,40 @@
+
+// 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/BiomeVisualiser/WndProcThunk.h b/BiomeVisualiser/WndProcThunk.h
new file mode 100644
index 000000000..6f33b5c3f
--- /dev/null
+++ b/BiomeVisualiser/WndProcThunk.h
@@ -0,0 +1,143 @@
+
+// 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 W> class CWndProcThunk;
+
+
+
+
+
+#ifndef WNDPROCTHUNK_H_INCLUDED
+#define WNDPROCTHUNK_H_INCLUDED
+
+
+
+
+template<typename To, typename From> 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 W> 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<char *>(proc) - reinterpret_cast<char *>(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 W> 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<char *>(proc) - reinterpret_cast<char *>(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/BiomeVisualiser/profile_run.cmd b/BiomeVisualiser/profile_run.cmd
new file mode 100644
index 000000000..753ff18fb
--- /dev/null
+++ b/BiomeVisualiser/profile_run.cmd
@@ -0,0 +1,70 @@
+@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