2014-09-13 19:32:00 -04:00
|
|
|
#include "Globals.h"
|
|
|
|
#include "BiomeView.h"
|
|
|
|
#include <QPainter>
|
|
|
|
#include <QResizeEvent>
|
2014-10-27 18:58:09 -04:00
|
|
|
#include "Region.h"
|
2014-09-13 19:32:00 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-09-14 16:20:16 -04:00
|
|
|
static const int DELTA_STEP = 120; // The normal per-notch wheel delta
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-10-28 15:52:04 -04:00
|
|
|
/** Map for converting biome values to colors. Initialized from biomeColors[]. */
|
|
|
|
static uchar biomeToColor[256 * 4];
|
|
|
|
|
2017-12-23 07:49:08 -05:00
|
|
|
/** Map for converting biome values to colors. Used to initialize biomeToColor[]. */
|
2014-10-28 15:52:04 -04:00
|
|
|
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 }, },
|
2017-12-23 07:49:08 -05:00
|
|
|
{ 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 }, },
|
2014-10-28 15:52:04 -04:00
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// BiomeView:
|
|
|
|
|
2014-09-13 19:32:00 -04:00
|
|
|
BiomeView::BiomeView(QWidget * parent) :
|
|
|
|
super(parent),
|
|
|
|
m_X(0),
|
|
|
|
m_Z(0),
|
2014-09-14 16:20:16 -04:00
|
|
|
m_Zoom(1),
|
|
|
|
m_IsMouseDragging(false),
|
|
|
|
m_MouseWheelDelta(0)
|
2014-09-13 19:32:00 -04:00
|
|
|
{
|
|
|
|
// 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:
|
2014-10-27 18:58:09 -04:00
|
|
|
connect(&m_Cache, SIGNAL(regionAvailable(int, int)), this, SLOT(regionAvailable(int, int)));
|
2014-09-14 16:05:10 -04:00
|
|
|
|
2014-10-03 13:41:42 -04:00
|
|
|
// Allow mouse and keyboard interaction:
|
2014-09-14 16:05:10 -04:00
|
|
|
setFocusPolicy(Qt::StrongFocus);
|
2014-10-03 13:41:42 -04:00
|
|
|
setMouseTracking(true);
|
2014-09-13 19:32:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QSize BiomeView::minimumSizeHint() const
|
|
|
|
{
|
|
|
|
return QSize(300, 300);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QSize BiomeView::sizeHint() const
|
|
|
|
{
|
|
|
|
return QSize(800, 600);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void BiomeView::setChunkSource(std::shared_ptr<ChunkSource> a_ChunkSource)
|
|
|
|
{
|
|
|
|
// Replace the source in the cache:
|
|
|
|
m_Cache.setChunkSource(a_ChunkSource);
|
|
|
|
|
|
|
|
// Redraw with the new source:
|
|
|
|
redraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-10-03 06:33:03 -04:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-09-13 19:32:00 -04:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-10-27 18:58:09 -04:00
|
|
|
void BiomeView::regionAvailable(int a_RegionX, int a_RegionZ)
|
2014-09-13 19:32:00 -04:00
|
|
|
{
|
2014-10-27 18:58:09 -04:00
|
|
|
for (int z = 0; z < 32; z++)
|
|
|
|
{
|
|
|
|
for (int x = 0; x < 32; x++)
|
|
|
|
{
|
|
|
|
drawChunk(a_RegionX * 32 + x, a_RegionZ * 32 + z);
|
|
|
|
}
|
|
|
|
}
|
2014-09-13 19:32:00 -04:00
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-09-15 11:29:34 -04:00
|
|
|
void BiomeView::reload()
|
|
|
|
{
|
|
|
|
if (!hasData())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
m_Cache.reload();
|
|
|
|
|
|
|
|
redraw();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-09-13 19:32:00 -04:00
|
|
|
void BiomeView::drawChunk(int a_ChunkX, int a_ChunkZ)
|
|
|
|
{
|
|
|
|
if (!hasData())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-10-27 18:58:09 -04:00
|
|
|
// Fetch the region:
|
|
|
|
int regionX;
|
|
|
|
int regionZ;
|
|
|
|
Region::chunkToRegion(a_ChunkX, a_ChunkZ, regionX, regionZ);
|
|
|
|
RegionPtr region = m_Cache.fetch(regionX, regionZ);
|
2014-09-13 19:32:00 -04:00
|
|
|
|
|
|
|
// 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;
|
2017-12-23 07:49:08 -05:00
|
|
|
// centerx, centery now points to the top left corner of the center chunk
|
|
|
|
// so now calculate our x, y in relation
|
2014-09-13 19:32:00 -04:00
|
|
|
double chunksize = 16 * m_Zoom;
|
|
|
|
centerx += (a_ChunkX - centerchunkx) * chunksize;
|
|
|
|
centery += (a_ChunkZ - centerchunkz) * chunksize;
|
|
|
|
|
|
|
|
uchar * bits = m_Image.bits();
|
|
|
|
int imgstride = m_Image.bytesPerLine();
|
|
|
|
|
2014-10-28 15:52:04 -04:00
|
|
|
int skipx = 0, skipy = 0;
|
2014-09-13 19:32:00 -04:00
|
|
|
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:
|
2014-10-28 15:52:04 -04:00
|
|
|
const short * src = m_EmptyChunkBiomes;
|
2014-10-27 18:58:09 -04:00
|
|
|
if (region.get() != nullptr)
|
2014-09-13 19:32:00 -04:00
|
|
|
{
|
2014-10-27 18:58:09 -04:00
|
|
|
int relChunkX = a_ChunkX - regionX * 32;
|
|
|
|
int relChunkZ = a_ChunkZ - regionZ * 32;
|
|
|
|
Chunk & chunk = region->getRelChunk(relChunkX, relChunkZ);
|
|
|
|
if (chunk.isValid())
|
|
|
|
{
|
2014-10-28 15:52:04 -04:00
|
|
|
src = chunk.getBiomes();
|
2014-10-27 18:58:09 -04:00
|
|
|
}
|
2014-09-13 19:32:00 -04:00
|
|
|
}
|
|
|
|
|
2014-10-28 15:52:04 -04:00
|
|
|
// Scale-blit the image:
|
2014-09-13 19:32:00 -04:00
|
|
|
for (int z = skipy; z < blockheight; z++, imgoffset += imgstride)
|
|
|
|
{
|
2014-10-28 15:52:04 -04:00
|
|
|
size_t srcoffset = static_cast<size_t>(std::floor((double)z / m_Zoom)) * 16;
|
|
|
|
int imgxoffset = imgoffset;
|
|
|
|
for (int x = skipx; x < blockwidth; x++)
|
2014-09-13 19:32:00 -04:00
|
|
|
{
|
2014-10-28 15:52:04 -04:00
|
|
|
short biome = src[srcoffset + static_cast<size_t>(std::floor((double)x / m_Zoom))];
|
|
|
|
const uchar * color;
|
|
|
|
if (biome < 0)
|
2014-09-13 19:32:00 -04:00
|
|
|
{
|
2014-10-28 15:52:04 -04:00
|
|
|
static const uchar emptyBiome1[] = { 0x44, 0x44, 0x44, 0xff };
|
|
|
|
static const uchar emptyBiome2[] = { 0x88, 0x88, 0x88, 0xff };
|
|
|
|
color = ((x & 8) ^ (z & 8)) ? emptyBiome1 : emptyBiome2;
|
2014-09-13 19:32:00 -04:00
|
|
|
}
|
2014-10-28 15:52:04 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if (biome * 4 >= ARRAYCOUNT(biomeToColor))
|
|
|
|
{
|
|
|
|
static const uchar errorImage[] = { 0xff, 0x00, 0x00, 0xff };
|
|
|
|
color = errorImage;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
color = biomeToColor + biome * 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bits[imgxoffset] = color[0];
|
|
|
|
bits[imgxoffset + 1] = color[1];
|
|
|
|
bits[imgxoffset + 2] = color[2];
|
|
|
|
bits[imgxoffset + 3] = color[3];
|
|
|
|
imgxoffset += 4;
|
|
|
|
} // for x
|
|
|
|
} // for z
|
2014-09-13 19:32:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-09-14 16:05:10 -04:00
|
|
|
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)
|
|
|
|
{
|
2014-10-03 13:41:42 -04:00
|
|
|
// If there's no data displayed, bail out:
|
|
|
|
if (!hasData())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-09-14 16:05:10 -04:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-10-03 13:41:42 -04:00
|
|
|
// 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);
|
2014-10-27 18:58:09 -04:00
|
|
|
int regionX, regionZ;
|
|
|
|
Region::blockToRegion(blockX, blockZ, regionX, regionZ);
|
|
|
|
int relX = blockX - regionX * 512;
|
|
|
|
int relZ = blockZ - regionZ * 512;
|
|
|
|
auto region = m_Cache.fetch(regionX, regionZ);
|
|
|
|
int biome = (region.get() != nullptr) ? region->getRelBiome(relX, relZ) : biInvalidBiome;
|
2014-10-03 13:41:42 -04:00
|
|
|
emit hoverChanged(blockX, blockZ, biome);
|
2014-09-14 16:05:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void BiomeView::mouseReleaseEvent(QMouseEvent *)
|
|
|
|
{
|
|
|
|
m_IsMouseDragging = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void BiomeView::wheelEvent(QWheelEvent * a_Event)
|
|
|
|
{
|
2014-09-14 16:20:16 -04:00
|
|
|
m_MouseWheelDelta += a_Event->delta();
|
|
|
|
while (m_MouseWheelDelta >= DELTA_STEP)
|
|
|
|
{
|
2014-10-03 06:33:03 -04:00
|
|
|
emit wheelUp();
|
2014-09-14 16:20:16 -04:00
|
|
|
m_MouseWheelDelta -= DELTA_STEP;
|
|
|
|
}
|
|
|
|
while (m_MouseWheelDelta <= -DELTA_STEP)
|
|
|
|
{
|
2014-10-03 06:33:03 -04:00
|
|
|
emit wheelDown();
|
2014-09-14 16:20:16 -04:00
|
|
|
m_MouseWheelDelta += DELTA_STEP;
|
|
|
|
}
|
2014-09-14 16:05:10 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void BiomeView::keyPressEvent(QKeyEvent * a_Event)
|
2014-09-13 19:32:00 -04:00
|
|
|
{
|
2014-09-14 16:05:10 -04:00
|
|
|
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:
|
|
|
|
{
|
2014-10-03 06:33:03 -04:00
|
|
|
emit increaseZoom();
|
2014-09-14 16:05:10 -04:00
|
|
|
break;
|
|
|
|
}
|
2014-09-13 19:32:00 -04:00
|
|
|
|
2014-09-14 16:05:10 -04:00
|
|
|
case Qt::Key_PageDown:
|
|
|
|
case Qt::Key_E:
|
|
|
|
{
|
2014-10-03 06:33:03 -04:00
|
|
|
emit decreaseZoom();
|
2014-09-14 16:05:10 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2014-09-13 19:32:00 -04:00
|
|
|
}
|