Allow scaling a map to a smaller size while generating. (1/2, 1/4 .. 1/16)
Scaling will not average nodes across block boundaries, This implies that the only scale factors supported are 1:2, 1:4, 1:8 and 1:16.
This commit is contained in:
parent
045540e8f9
commit
5ce7ff4bce
@ -26,7 +26,7 @@ PixelAttributes::~PixelAttributes()
|
|||||||
freeAttributes();
|
freeAttributes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PixelAttributes::setParameters(int width, int lines, int nextY)
|
void PixelAttributes::setParameters(int width, int lines, int nextY, int scale, bool defaultEmpty)
|
||||||
{
|
{
|
||||||
freeAttributes();
|
freeAttributes();
|
||||||
m_width = width + 1; // 1px gradient calculation
|
m_width = width + 1; // 1px gradient calculation
|
||||||
@ -39,6 +39,7 @@ void PixelAttributes::setParameters(int width, int lines, int nextY)
|
|||||||
m_nextY = nextY;
|
m_nextY = nextY;
|
||||||
m_lastY = -1;
|
m_lastY = -1;
|
||||||
m_firstUnshadedY = 0;
|
m_firstUnshadedY = 0;
|
||||||
|
m_scale = scale;
|
||||||
|
|
||||||
m_pixelAttributes = new PixelAttribute *[m_lineCount];
|
m_pixelAttributes = new PixelAttribute *[m_lineCount];
|
||||||
if (!m_pixelAttributes)
|
if (!m_pixelAttributes)
|
||||||
@ -52,7 +53,10 @@ void PixelAttributes::setParameters(int width, int lines, int nextY)
|
|||||||
for (int i=0; i<m_lineCount; i++)
|
for (int i=0; i<m_lineCount; i++)
|
||||||
for (int j=0; j<m_width; j++) {
|
for (int j=0; j<m_width; j++) {
|
||||||
m_pixelAttributes[i][j].m_a=0;
|
m_pixelAttributes[i][j].m_a=0;
|
||||||
m_pixelAttributes[i][j].next16Empty = (j - 1) % 16 == 0;
|
if (defaultEmpty)
|
||||||
|
m_pixelAttributes[i][j].nextEmpty = (j - 1) % (16 / scale) == 0;
|
||||||
|
else
|
||||||
|
m_pixelAttributes[i][j].nextEmpty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,13 +112,13 @@ static inline double colorSafeBounds(double color)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PixelAttributes::renderShading(bool drawAlpha)
|
void PixelAttributes::renderShading(double emphasis, bool drawAlpha)
|
||||||
{
|
{
|
||||||
int y;
|
int y;
|
||||||
for (y = yCoord2Line(m_firstUnshadedY); y <= yCoord2Line(m_lastY); y++) {
|
for (y = yCoord2Line(m_firstUnshadedY); y <= yCoord2Line(m_lastY); y++) {
|
||||||
for (int x = 1; x < m_width; x++) {
|
for (int x = 1; x < m_width; x++) {
|
||||||
if (m_pixelAttributes[y][x].next16Empty) {
|
if (m_pixelAttributes[y][x].nextEmpty) {
|
||||||
x += 15;
|
x += 16 / m_scale - 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!m_pixelAttributes[y][x].isNormalized())
|
if (!m_pixelAttributes[y][x].isNormalized())
|
||||||
@ -136,7 +140,7 @@ void PixelAttributes::renderShading(bool drawAlpha)
|
|||||||
if (d > 3) {
|
if (d > 3) {
|
||||||
d = 3;
|
d = 3;
|
||||||
}
|
}
|
||||||
d = d * 12 / 255;
|
d = d * 12 / 255 * emphasis;
|
||||||
#define pixel (m_pixelAttributes[y][x])
|
#define pixel (m_pixelAttributes[y][x])
|
||||||
//PixelAttribute &pixel = m_pixelAttributes[y][x];
|
//PixelAttribute &pixel = m_pixelAttributes[y][x];
|
||||||
if (drawAlpha)
|
if (drawAlpha)
|
||||||
|
@ -27,11 +27,11 @@ public:
|
|||||||
AlphaMixAverage = 0x04,
|
AlphaMixAverage = 0x04,
|
||||||
};
|
};
|
||||||
static void setMixMode(AlphaMixingMode mode);
|
static void setMixMode(AlphaMixingMode mode);
|
||||||
PixelAttribute(): next16Empty(true), m_n(0), m_h(NAN), m_t(0), m_a(0), m_r(0), m_g(0), m_b(0) {};
|
PixelAttribute(): nextEmpty(true), m_n(0), m_h(NAN), m_t(0), m_a(0), m_r(0), m_g(0), m_b(0) {};
|
||||||
// PixelAttribute(const PixelAttribute &p);
|
// PixelAttribute(const PixelAttribute &p);
|
||||||
PixelAttribute(const Color &color, double height);
|
PixelAttribute(const Color &color, double height);
|
||||||
PixelAttribute(const ColorEntry &entry, double height);
|
PixelAttribute(const ColorEntry &entry, double height);
|
||||||
bool next16Empty;
|
bool nextEmpty;
|
||||||
double h(void) const { return m_h / (m_n ? m_n : 1); }
|
double h(void) const { return m_h / (m_n ? m_n : 1); }
|
||||||
double t(void) const { return m_t / (m_n ? m_n : 1); }
|
double t(void) const { return m_t / (m_n ? m_n : 1); }
|
||||||
double a(void) const { return m_a / (m_n ? m_n : 1); }
|
double a(void) const { return m_a / (m_n ? m_n : 1); }
|
||||||
@ -70,10 +70,10 @@ class PixelAttributes
|
|||||||
public:
|
public:
|
||||||
PixelAttributes();
|
PixelAttributes();
|
||||||
virtual ~PixelAttributes();
|
virtual ~PixelAttributes();
|
||||||
void setParameters(int width, int lines, int nextY);
|
void setParameters(int width, int lines, int nextY, int scale, bool defaultEmpty);
|
||||||
void scroll(int keepY);
|
void scroll(int keepY);
|
||||||
PixelAttribute &attribute(int y, int x);
|
PixelAttribute &attribute(int y, int x);
|
||||||
void renderShading(bool drawAlpha);
|
void renderShading(double emphasis, bool drawAlpha);
|
||||||
int getNextY(void) { return m_nextY; }
|
int getNextY(void) { return m_nextY; }
|
||||||
void setLastY(int y);
|
void setLastY(int y);
|
||||||
int getLastY(void) { return m_lastY; }
|
int getLastY(void) { return m_lastY; }
|
||||||
@ -94,6 +94,7 @@ private:
|
|||||||
int m_nextY;
|
int m_nextY;
|
||||||
int m_lastY;
|
int m_lastY;
|
||||||
int m_firstUnshadedY;
|
int m_firstUnshadedY;
|
||||||
|
int m_scale;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void PixelAttributes::setLastY(int y)
|
inline void PixelAttributes::setLastY(int y)
|
||||||
@ -133,13 +134,13 @@ inline PixelAttribute &PixelAttributes::attribute(int y, int x)
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
inline PixelAttribute::PixelAttribute(const Color &color, double height) :
|
inline PixelAttribute::PixelAttribute(const Color &color, double height) :
|
||||||
next16Empty(false), m_n(0), m_h(height), m_t(0), m_a(color.a/255.0),
|
nextEmpty(false), m_n(0), m_h(height), m_t(0), m_a(color.a/255.0),
|
||||||
m_r(color.r/255.0), m_g(color.g/255.0), m_b(color.b/255.0)
|
m_r(color.r/255.0), m_g(color.g/255.0), m_b(color.b/255.0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PixelAttribute::PixelAttribute(const ColorEntry &entry, double height) :
|
inline PixelAttribute::PixelAttribute(const ColorEntry &entry, double height) :
|
||||||
next16Empty(false), m_n(0), m_h(height), m_t(entry.t/255.0), m_a(entry.a/255.0),
|
nextEmpty(false), m_n(0), m_h(height), m_t(entry.t/255.0), m_a(entry.a/255.0),
|
||||||
m_r(entry.r/255.0), m_g(entry.g/255.0), m_b(entry.b/255.0)
|
m_r(entry.r/255.0), m_g(entry.g/255.0), m_b(entry.b/255.0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
* Company: LinuxOS.sk
|
* Company: LinuxOS.sk
|
||||||
* =====================================================================
|
* =====================================================================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
@ -150,6 +149,7 @@ TileGenerator::TileGenerator():
|
|||||||
m_backend(DEFAULT_BACKEND),
|
m_backend(DEFAULT_BACKEND),
|
||||||
m_shrinkGeometry(true),
|
m_shrinkGeometry(true),
|
||||||
m_blockGeometry(false),
|
m_blockGeometry(false),
|
||||||
|
m_scaleFactor(1),
|
||||||
m_sqliteCacheWorldRow(false),
|
m_sqliteCacheWorldRow(false),
|
||||||
m_chunkSize(0),
|
m_chunkSize(0),
|
||||||
m_image(0),
|
m_image(0),
|
||||||
@ -288,6 +288,11 @@ void TileGenerator::setTileCenter(int x, int y)
|
|||||||
m_tileYCentered = true;
|
m_tileYCentered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TileGenerator::setScaleFactor(int f)
|
||||||
|
{
|
||||||
|
m_scaleFactor = f;
|
||||||
|
}
|
||||||
|
|
||||||
void TileGenerator::setDrawOrigin(bool drawOrigin)
|
void TileGenerator::setDrawOrigin(bool drawOrigin)
|
||||||
{
|
{
|
||||||
m_drawOrigin = drawOrigin;
|
m_drawOrigin = drawOrigin;
|
||||||
@ -348,8 +353,8 @@ void TileGenerator::setGeometry(const NodeCoord &corner1, const NodeCoord &corne
|
|||||||
else {
|
else {
|
||||||
m_reqZMin = (corner1.y - 15) / 16;
|
m_reqZMin = (corner1.y - 15) / 16;
|
||||||
}
|
}
|
||||||
m_mapXStartNodeOffset = corner1.x - m_reqXMin * 16;
|
m_mapXStartNodeOffsetOrig = m_mapXStartNodeOffset = corner1.x - m_reqXMin * 16;
|
||||||
m_mapYEndNodeOffset = m_reqZMin * 16 - corner1.y;
|
m_mapYEndNodeOffsetOrig = m_mapYEndNodeOffset = m_reqZMin * 16 - corner1.y;
|
||||||
|
|
||||||
if (corner2.x > 0) {
|
if (corner2.x > 0) {
|
||||||
m_reqXMax = corner2.x / 16;
|
m_reqXMax = corner2.x / 16;
|
||||||
@ -363,8 +368,8 @@ void TileGenerator::setGeometry(const NodeCoord &corner1, const NodeCoord &corne
|
|||||||
else {
|
else {
|
||||||
m_reqZMax = (corner2.y - 15) / 16;
|
m_reqZMax = (corner2.y - 15) / 16;
|
||||||
}
|
}
|
||||||
m_mapXEndNodeOffset = corner2.x - (m_reqXMax * 16 + 15);
|
m_mapXEndNodeOffsetOrig = m_mapXEndNodeOffset = corner2.x - (m_reqXMax * 16 + 15);
|
||||||
m_mapYStartNodeOffset = (m_reqZMax * 16 + 15) - corner2.y;
|
m_mapYStartNodeOffsetOrig = m_mapYStartNodeOffset = (m_reqZMax * 16 + 15) - corner2.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileGenerator::setMinY(int y)
|
void TileGenerator::setMinY(int y)
|
||||||
@ -437,6 +442,42 @@ void TileGenerator::setChunkSize(int size)
|
|||||||
m_chunkSize = size;
|
m_chunkSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TileGenerator::sanitizeParameters(void)
|
||||||
|
{
|
||||||
|
if (m_scaleFactor > 1) {
|
||||||
|
int dx0 = m_mapXStartNodeOffset % m_scaleFactor;
|
||||||
|
int dx1 = -m_mapXEndNodeOffset % m_scaleFactor;
|
||||||
|
int dy0 = m_mapYStartNodeOffset % m_scaleFactor;
|
||||||
|
int dy1 = -m_mapYEndNodeOffset % m_scaleFactor;
|
||||||
|
if (dx0 || dx1 || dy0 || dy1) {
|
||||||
|
m_mapXStartNodeOffsetOrig = m_mapXStartNodeOffset;
|
||||||
|
m_mapXEndNodeOffsetOrig = m_mapXEndNodeOffset;
|
||||||
|
m_mapYStartNodeOffsetOrig = m_mapYStartNodeOffset;
|
||||||
|
m_mapYEndNodeOffsetOrig = m_mapYEndNodeOffset;
|
||||||
|
m_mapXStartNodeOffset -= dx0;
|
||||||
|
m_mapXEndNodeOffset += dx1;
|
||||||
|
m_mapYStartNodeOffset -= dy0;
|
||||||
|
m_mapYEndNodeOffset += dy1;
|
||||||
|
std::cerr << "NOTE: rounding requested map boundaries to a multiple of the scale factor"
|
||||||
|
<< "(changes -" << dx0 << ",+" << dx1 << " x -" << dy1 << ",+" << dy0 << ")" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
dx0 = dy0 = 0;
|
||||||
|
if (m_tileWidth != TILESIZE_CHUNK)
|
||||||
|
dx0 = m_tileWidth % m_scaleFactor;
|
||||||
|
if (dx0) dx0 = m_scaleFactor - dx0;
|
||||||
|
if (m_tileHeight != TILESIZE_CHUNK)
|
||||||
|
dy0 = m_tileHeight % m_scaleFactor;
|
||||||
|
if (dy0) dy0 = m_scaleFactor - dy0;
|
||||||
|
if (dx0 || dy0) {
|
||||||
|
m_tileWidth += dx0;
|
||||||
|
m_tileHeight += dy0;
|
||||||
|
std::cerr << "NOTE: rounding requested tile size up to nearest multiple of the scale factor: "
|
||||||
|
<< m_tileWidth << " x " << m_tileHeight << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TileGenerator::generate(const std::string &input, const std::string &output)
|
void TileGenerator::generate(const std::string &input, const std::string &output)
|
||||||
{
|
{
|
||||||
string input_path = input;
|
string input_path = input;
|
||||||
@ -445,6 +486,7 @@ void TileGenerator::generate(const std::string &input, const std::string &output
|
|||||||
}
|
}
|
||||||
|
|
||||||
openDb(input_path);
|
openDb(input_path);
|
||||||
|
sanitizeParameters();
|
||||||
loadBlocks();
|
loadBlocks();
|
||||||
computeMapParameters(input);
|
computeMapParameters(input);
|
||||||
createImage();
|
createImage();
|
||||||
@ -773,18 +815,20 @@ void TileGenerator::loadBlocks()
|
|||||||
long long map_blocks;
|
long long map_blocks;
|
||||||
if (verboseCoordinates >= 2) {
|
if (verboseCoordinates >= 2) {
|
||||||
bool partialBlocks = (m_mapXStartNodeOffset || m_mapXEndNodeOffset || m_mapYStartNodeOffset || m_mapYEndNodeOffset);
|
bool partialBlocks = (m_mapXStartNodeOffset || m_mapXEndNodeOffset || m_mapYStartNodeOffset || m_mapYEndNodeOffset);
|
||||||
if (partialBlocks || !m_blockGeometry) {
|
bool adjustedGeom = (m_mapXStartNodeOffsetOrig != m_mapXStartNodeOffset || m_mapYEndNodeOffsetOrig != m_mapYEndNodeOffset
|
||||||
|
|| m_mapXEndNodeOffsetOrig != m_mapXEndNodeOffset || m_mapYStartNodeOffsetOrig != m_mapYStartNodeOffsetOrig);
|
||||||
|
if (partialBlocks || !m_blockGeometry || adjustedGeom) {
|
||||||
cout
|
cout
|
||||||
<< std::setw(MESSAGE_WIDTH) << std::left
|
<< std::setw(MESSAGE_WIDTH) << std::left
|
||||||
<< (m_blockGeometry ? "Command-line Geometry:" : "Requested Geometry:")
|
<< (m_blockGeometry ? "Command-line Geometry:" : "Requested Geometry:")
|
||||||
<< std::right
|
<< std::right
|
||||||
<< std::setw(7) << m_reqXMin*16+m_mapXStartNodeOffset << ","
|
<< std::setw(7) << m_reqXMin*16+m_mapXStartNodeOffsetOrig << ","
|
||||||
<< std::setw(7) << m_reqYMin*16+m_reqYMinNode << ","
|
<< std::setw(7) << m_reqYMin*16+m_reqYMinNode << ","
|
||||||
<< std::setw(7) << m_reqZMin*16-m_mapYEndNodeOffset
|
<< std::setw(7) << m_reqZMin*16-m_mapYEndNodeOffsetOrig
|
||||||
<< " .. "
|
<< " .. "
|
||||||
<< std::setw(7) << m_reqXMax*16+15+m_mapXEndNodeOffset << ","
|
<< std::setw(7) << m_reqXMax*16+15+m_mapXEndNodeOffsetOrig << ","
|
||||||
<< std::setw(7) << m_reqYMax*16+m_reqYMaxNode << ","
|
<< std::setw(7) << m_reqYMax*16+m_reqYMaxNode << ","
|
||||||
<< std::setw(7) << m_reqZMax*16+15-m_mapYStartNodeOffset
|
<< std::setw(7) << m_reqZMax*16+15-m_mapYStartNodeOffsetOrig
|
||||||
<< " ("
|
<< " ("
|
||||||
<< std::setw(6) << m_reqXMin << ","
|
<< std::setw(6) << m_reqXMin << ","
|
||||||
<< std::setw(6) << m_reqYMin << ","
|
<< std::setw(6) << m_reqYMin << ","
|
||||||
@ -817,6 +861,28 @@ void TileGenerator::loadBlocks()
|
|||||||
<< std::setw(6) << m_reqZMax
|
<< std::setw(6) << m_reqZMax
|
||||||
<< ")\n";
|
<< ")\n";
|
||||||
}
|
}
|
||||||
|
if (!m_blockGeometry && adjustedGeom) {
|
||||||
|
cout
|
||||||
|
<< std::setw(MESSAGE_WIDTH) << std::left
|
||||||
|
<< "Adjusted Geometry:"
|
||||||
|
<< std::right
|
||||||
|
<< std::setw(7) << m_reqXMin*16+m_mapXStartNodeOffset << ","
|
||||||
|
<< std::setw(7) << m_reqYMin*16+m_reqYMinNode << ","
|
||||||
|
<< std::setw(7) << m_reqZMin*16-m_mapYEndNodeOffset
|
||||||
|
<< " .. "
|
||||||
|
<< std::setw(7) << m_reqXMax*16+15+m_mapXEndNodeOffset << ","
|
||||||
|
<< std::setw(7) << m_reqYMax*16+m_reqYMaxNode << ","
|
||||||
|
<< std::setw(7) << m_reqZMax*16+15-m_mapYStartNodeOffset
|
||||||
|
<< " ("
|
||||||
|
<< std::setw(6) << m_reqXMin << ","
|
||||||
|
<< std::setw(6) << m_reqYMin << ","
|
||||||
|
<< std::setw(6) << m_reqZMin
|
||||||
|
<< " .. "
|
||||||
|
<< std::setw(6) << m_reqXMax << ","
|
||||||
|
<< std::setw(6) << m_reqYMax << ","
|
||||||
|
<< std::setw(6) << m_reqZMax
|
||||||
|
<< ")\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (m_blockGeometry) {
|
if (m_blockGeometry) {
|
||||||
m_mapXStartNodeOffset = 0;
|
m_mapXStartNodeOffset = 0;
|
||||||
@ -993,18 +1059,59 @@ void TileGenerator::loadBlocks()
|
|||||||
#undef MESSAGE_WIDTH
|
#undef MESSAGE_WIDTH
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileGenerator::pushPixelRows(int zPosLimit) {
|
void TileGenerator::scalePixelRows(PixelAttributes &pixelAttributes, PixelAttributes &pixelAttributesScaled, int zPosLimit) {
|
||||||
if (m_shading)
|
|
||||||
m_blockPixelAttributes.renderShading(m_drawAlpha);
|
|
||||||
int y;
|
int y;
|
||||||
for (y = m_blockPixelAttributes.getNextY(); y <= m_blockPixelAttributes.getLastY() && y < worldBlockZ2StoredY(m_zMin - 1) + m_mapYEndNodeOffset; y++) {
|
for (y = pixelAttributes.getNextY(); y <= pixelAttributes.getLastY() && y < worldBlockZ2StoredY(m_zMin - 1) + m_mapYEndNodeOffset; y++) {
|
||||||
for (int x = m_mapXStartNodeOffset; x < worldBlockX2StoredX(m_xMax + 1) + m_mapXEndNodeOffset; x++) {
|
for (int x = m_mapXStartNodeOffset; x < worldBlockX2StoredX(m_xMax + 1) + m_mapXEndNodeOffset; x++) {
|
||||||
|
#define pixel pixelAttributes.attribute(y, x)
|
||||||
|
//PixelAttribute &pixel = pixelAttributes.attribute(y, x);
|
||||||
|
if (pixel.nextEmpty) {
|
||||||
|
pixelAttributesScaled.attribute(y / m_scaleFactor, x/m_scaleFactor).nextEmpty = true;
|
||||||
|
x += 15;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
int mapX = x - m_mapXStartNodeOffset;
|
int mapX = x - m_mapXStartNodeOffset;
|
||||||
int mapY = y - m_mapYStartNodeOffset;
|
int mapY = y - m_mapYStartNodeOffset;
|
||||||
#define pixel m_blockPixelAttributes.attribute(y, x)
|
{ int ix = mapX2ImageX(mapX / m_scaleFactor); assert(ix - borderLeft() >= 0 && ix - borderLeft() - borderRight() < m_pictWidth); }
|
||||||
//PixelAttribute &pixel = m_blockPixelAttributes.attribute(y, x);
|
{ int iy = mapY2ImageY(mapY / m_scaleFactor); assert(iy - borderTop() >= 0 && iy - borderTop() - borderBottom() < m_pictHeight); }
|
||||||
if (pixel.next16Empty) {
|
#endif
|
||||||
x += 15;
|
if (pixel.is_valid() || pixel.color().to_uint())
|
||||||
|
pixelAttributesScaled.attribute(y / m_scaleFactor, x / m_scaleFactor).add(pixel);
|
||||||
|
#undef pixel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (y = pixelAttributesScaled.getNextY(); y <= pixelAttributesScaled.getLastY(); y++) {
|
||||||
|
for (int x = m_mapXStartNodeOffset / m_scaleFactor; x < (worldBlockX2StoredX(m_xMax + 1) + m_mapXEndNodeOffset) / m_scaleFactor; x++) {
|
||||||
|
#define pixel pixelAttributesScaled.attribute(y, x)
|
||||||
|
if (pixel.nextEmpty) {
|
||||||
|
x += 16 / m_scaleFactor - 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pixel.is_valid() || pixel.color().to_uint())
|
||||||
|
pixel.normalize();
|
||||||
|
#undef pixel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int yLimit = worldBlockZ2StoredY(zPosLimit);
|
||||||
|
if (y <= yLimit) {
|
||||||
|
pixelAttributes.scroll(yLimit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TileGenerator::pushPixelRows(PixelAttributes &pixelAttributes, int zPosLimit) {
|
||||||
|
if (m_shading)
|
||||||
|
pixelAttributes.renderShading(m_scaleFactor < 3 ? 1 : 1 / sqrt(m_scaleFactor), m_drawAlpha);
|
||||||
|
int y;
|
||||||
|
for (y = pixelAttributes.getNextY(); y <= pixelAttributes.getLastY() && y < (worldBlockZ2StoredY(m_zMin - 1) + m_mapYEndNodeOffset) / m_scaleFactor; y++) {
|
||||||
|
for (int x = m_mapXStartNodeOffset / m_scaleFactor; x < (worldBlockX2StoredX(m_xMax + 1) + m_mapXEndNodeOffset) / m_scaleFactor; x++) {
|
||||||
|
int mapX = x - m_mapXStartNodeOffset / m_scaleFactor;
|
||||||
|
int mapY = y - m_mapYStartNodeOffset / m_scaleFactor;
|
||||||
|
#define pixel pixelAttributes.attribute(y, x)
|
||||||
|
//PixelAttribute &pixel = pixelAttributes.attribute(y, x);
|
||||||
|
//if (x < 2 && y < 2)
|
||||||
|
if (pixel.nextEmpty) {
|
||||||
|
x += 16 / m_scaleFactor - 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -1016,9 +1123,9 @@ void TileGenerator::pushPixelRows(int zPosLimit) {
|
|||||||
#undef pixel
|
#undef pixel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int yLimit = worldBlockZ2StoredY(zPosLimit);
|
int yLimit = worldBlockZ2StoredY(zPosLimit) / m_scaleFactor;
|
||||||
if (y <= yLimit) {
|
if (y <= yLimit) {
|
||||||
m_blockPixelAttributes.scroll(yLimit);
|
pixelAttributes.scroll(yLimit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1030,8 +1137,6 @@ void TileGenerator::computeTileParameters(
|
|||||||
int mapEndNodeOffset,
|
int mapEndNodeOffset,
|
||||||
int tileOrigin,
|
int tileOrigin,
|
||||||
int tileSize,
|
int tileSize,
|
||||||
// Input / Output parameters
|
|
||||||
int &pictSize,
|
|
||||||
// Output parameters
|
// Output parameters
|
||||||
int &tileBorderCount,
|
int &tileBorderCount,
|
||||||
int &tileMapStartOffset,
|
int &tileMapStartOffset,
|
||||||
@ -1072,7 +1177,6 @@ void TileGenerator::computeTileParameters(
|
|||||||
}
|
}
|
||||||
tileMapStartOffset = (tileSize - start) % tileSize;
|
tileMapStartOffset = (tileSize - start) % tileSize;
|
||||||
tileMapEndOffset = limit - ((tileBorderLimit-tileBorderStart) * tileSize);
|
tileMapEndOffset = limit - ((tileBorderLimit-tileBorderStart) * tileSize);
|
||||||
pictSize += (tileBorderLimit - tileBorderStart) * m_tileBorderSize;
|
|
||||||
tileBorderCount = tileBorderLimit - tileBorderStart;
|
tileBorderCount = tileBorderLimit - tileBorderStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1089,7 +1193,15 @@ void TileGenerator::computeMapParameters(const std::string &input)
|
|||||||
m_storedHeight = (m_zMax - m_zMin + 1) * 16;
|
m_storedHeight = (m_zMax - m_zMin + 1) * 16;
|
||||||
int mapWidth = m_storedWidth - m_mapXStartNodeOffset + m_mapXEndNodeOffset;
|
int mapWidth = m_storedWidth - m_mapXStartNodeOffset + m_mapXEndNodeOffset;
|
||||||
int mapHeight = m_storedHeight - m_mapYStartNodeOffset + m_mapYEndNodeOffset;
|
int mapHeight = m_storedHeight - m_mapYStartNodeOffset + m_mapYEndNodeOffset;
|
||||||
m_blockPixelAttributes.setParameters(m_storedWidth, 16, m_mapYStartNodeOffset);
|
#ifdef DEBUG
|
||||||
|
assert(mapWidth % m_scaleFactor == 0);
|
||||||
|
assert(mapHeight % m_scaleFactor == 0);
|
||||||
|
#else
|
||||||
|
mapWidth += mapWidth % m_scaleFactor;
|
||||||
|
mapHeight += mapHeight % m_scaleFactor;
|
||||||
|
#endif
|
||||||
|
m_blockPixelAttributes.setParameters(m_storedWidth, 16, m_mapYStartNodeOffset, 1, true);
|
||||||
|
m_blockPixelAttributesScaled.setParameters(m_storedWidth / m_scaleFactor, 16 / m_scaleFactor, m_mapYStartNodeOffset / m_scaleFactor, m_scaleFactor, false);
|
||||||
|
|
||||||
// Set special values for origin (which depend on other paramters)
|
// Set special values for origin (which depend on other paramters)
|
||||||
if (m_tileWidth) {
|
if (m_tileWidth) {
|
||||||
@ -1114,6 +1226,10 @@ void TileGenerator::computeMapParameters(const std::string &input)
|
|||||||
m_tileXOrigin -= m_tileWidth/2;
|
m_tileXOrigin -= m_tileWidth/2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (m_tileXOrigin >= 0)
|
||||||
|
m_tileXOrigin -= m_tileXOrigin % m_scaleFactor;
|
||||||
|
else
|
||||||
|
m_tileXOrigin -= -m_tileXOrigin % m_scaleFactor;
|
||||||
}
|
}
|
||||||
if (m_tileHeight) {
|
if (m_tileHeight) {
|
||||||
switch (m_tileZOrigin) {
|
switch (m_tileZOrigin) {
|
||||||
@ -1137,6 +1253,10 @@ void TileGenerator::computeMapParameters(const std::string &input)
|
|||||||
m_tileZOrigin -= m_tileHeight / 2;
|
m_tileZOrigin -= m_tileHeight / 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (m_tileXOrigin >= 0)
|
||||||
|
m_tileZOrigin -= m_tileZOrigin % m_scaleFactor;
|
||||||
|
else
|
||||||
|
m_tileZOrigin -= -m_tileZOrigin % m_scaleFactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute adjustments for tiles.
|
// Compute adjustments for tiles.
|
||||||
@ -1152,8 +1272,6 @@ void TileGenerator::computeMapParameters(const std::string &input)
|
|||||||
m_mapXEndNodeOffset,
|
m_mapXEndNodeOffset,
|
||||||
m_tileXOrigin,
|
m_tileXOrigin,
|
||||||
m_tileWidth,
|
m_tileWidth,
|
||||||
// Input / Output parameters
|
|
||||||
m_pictWidth,
|
|
||||||
// Output parameters
|
// Output parameters
|
||||||
m_tileBorderXCount,
|
m_tileBorderXCount,
|
||||||
m_tileMapXOffset,
|
m_tileMapXOffset,
|
||||||
@ -1171,8 +1289,6 @@ void TileGenerator::computeMapParameters(const std::string &input)
|
|||||||
-m_mapYStartNodeOffset,
|
-m_mapYStartNodeOffset,
|
||||||
m_tileZOrigin,
|
m_tileZOrigin,
|
||||||
m_tileHeight,
|
m_tileHeight,
|
||||||
// Input / Output parameters
|
|
||||||
m_pictHeight,
|
|
||||||
// Output parameters
|
// Output parameters
|
||||||
m_tileBorderYCount,
|
m_tileBorderYCount,
|
||||||
tileMapYEndOffset,
|
tileMapYEndOffset,
|
||||||
@ -1181,18 +1297,25 @@ void TileGenerator::computeMapParameters(const std::string &input)
|
|||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_pictWidth /= m_scaleFactor;
|
||||||
|
m_pictWidth += m_tileBorderXCount * m_tileBorderSize;
|
||||||
|
m_pictHeight /= m_scaleFactor;
|
||||||
|
m_pictHeight += m_tileBorderYCount * m_tileBorderSize;
|
||||||
|
|
||||||
// Print some useful messages in cases where it may not be possible to generate the image...
|
// Print some useful messages in cases where it may not be possible to generate the image...
|
||||||
long long pixels = static_cast<long long>(m_pictWidth + borderLeft() + borderRight()) * (m_pictHeight + borderTop() + borderBottom());
|
long long pixels = static_cast<long long>(m_pictWidth + borderLeft() + borderRight()) * (m_pictHeight + borderTop() + borderBottom());
|
||||||
// Study the libgd code to known why the maximum is the following:
|
// Study the libgd code to known why the maximum is the following:
|
||||||
long long max_pixels = INT_MAX - INT_MAX % m_pictHeight;
|
long long max_pixels = INT_MAX - INT_MAX % m_pictHeight;
|
||||||
if (pixels > max_pixels) {
|
if (pixels > max_pixels) {
|
||||||
cerr << "WARNING: Image will have " << pixels << " pixels; the PNG graphics library will refuse to handle more than approximately " << INT_MAX << std::endl;
|
cerr << "WARNING: Image will have " << pixels << " pixels; the PNG graphics library will refuse to handle more than approximately " << INT_MAX << std::endl;
|
||||||
|
cerr << " (If map generation fails, consider using --scalefactor to reduce the image size by a factor 2)" << std::endl;
|
||||||
}
|
}
|
||||||
// Estimated approximate maximum was determined by trial and error...
|
// Estimated approximate maximum was determined by trial and error...
|
||||||
// (24100x24100 succeeded; 24200x24200 failed)
|
// (24100x24100 succeeded; 24200x24200 failed)
|
||||||
#define ESTIMATED_MAX_PIXELS_32BIT (24100*24100L)
|
#define ESTIMATED_MAX_PIXELS_32BIT (24100*24100L)
|
||||||
else if (sizeof(void *) == 4 && pixels > ESTIMATED_MAX_PIXELS_32BIT) {
|
else if (sizeof(void *) == 4 && pixels > ESTIMATED_MAX_PIXELS_32BIT) {
|
||||||
cerr << "WARNING: Image will have " << pixels << " pixels; The maximum achievable on a 32-bit system is approximately " << ESTIMATED_MAX_PIXELS_32BIT << std::endl;
|
cerr << "WARNING: Image will have " << pixels << " pixels; The maximum achievable on a 32-bit system is approximately " << ESTIMATED_MAX_PIXELS_32BIT << std::endl;
|
||||||
|
cerr << " (If map generation fails, consider using --scalefactor to reduce the image size by a factor 2 or 4)" << std::endl;
|
||||||
}
|
}
|
||||||
#undef ESTIMATED_MAX_PIXELS_32BIT
|
#undef ESTIMATED_MAX_PIXELS_32BIT
|
||||||
}
|
}
|
||||||
@ -1215,9 +1338,9 @@ void TileGenerator::createImage()
|
|||||||
if (m_tileWidth && m_tileBorderSize) {
|
if (m_tileWidth && m_tileBorderSize) {
|
||||||
int borderColor = m_tileBorderColor.to_libgd();
|
int borderColor = m_tileBorderColor.to_libgd();
|
||||||
for (int i = 0; i < m_tileBorderXCount; i++) {
|
for (int i = 0; i < m_tileBorderXCount; i++) {
|
||||||
int xPos = m_tileMapXOffset + i * (m_tileWidth + m_tileBorderSize);
|
int xPos = m_tileMapXOffset / m_scaleFactor + i * (m_tileWidth / m_scaleFactor + m_tileBorderSize);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
int xPos2 = mapX2ImageX(m_tileMapXOffset + i * m_tileWidth) - borderLeft() - 1;
|
int xPos2 = mapX2ImageX(m_tileMapXOffset / m_scaleFactor + i * m_tileWidth / m_scaleFactor) - borderLeft() - 1;
|
||||||
assert(xPos == xPos2);
|
assert(xPos == xPos2);
|
||||||
#endif
|
#endif
|
||||||
gdImageFilledRectangle(m_image, xPos + borderLeft(), borderTop(), xPos + (m_tileBorderSize-1) + borderLeft(), m_pictHeight + borderTop() - 1, borderColor);
|
gdImageFilledRectangle(m_image, xPos + borderLeft(), borderTop(), xPos + (m_tileBorderSize-1) + borderLeft(), m_pictHeight + borderTop() - 1, borderColor);
|
||||||
@ -1226,9 +1349,9 @@ void TileGenerator::createImage()
|
|||||||
if (m_tileHeight && m_tileBorderSize) {
|
if (m_tileHeight && m_tileBorderSize) {
|
||||||
int borderColor = m_tileBorderColor.to_libgd();
|
int borderColor = m_tileBorderColor.to_libgd();
|
||||||
for (int i = 0; i < m_tileBorderYCount; i++) {
|
for (int i = 0; i < m_tileBorderYCount; i++) {
|
||||||
int yPos = m_tileMapYOffset + i * (m_tileHeight + m_tileBorderSize);
|
int yPos = m_tileMapYOffset / m_scaleFactor + i * (m_tileHeight / m_scaleFactor + m_tileBorderSize);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
int yPos2 = mapY2ImageY(m_tileMapYOffset + i * m_tileHeight) - borderTop() - 1;
|
int yPos2 = mapY2ImageY(m_tileMapYOffset / m_scaleFactor + i * m_tileHeight / m_scaleFactor) - borderTop() - 1;
|
||||||
assert(yPos == yPos2);
|
assert(yPos == yPos2);
|
||||||
#endif
|
#endif
|
||||||
gdImageFilledRectangle(m_image, borderLeft(), yPos + borderTop(), m_pictWidth + borderLeft() - 1, yPos + (m_tileBorderSize-1) + borderTop(), borderColor);
|
gdImageFilledRectangle(m_image, borderLeft(), yPos + borderTop(), m_pictWidth + borderLeft() - 1, yPos + (m_tileBorderSize-1) + borderTop(), borderColor);
|
||||||
@ -1350,7 +1473,14 @@ void TileGenerator::renderMap()
|
|||||||
if (currentPos.x != pos.x || currentPos.z != pos.z) {
|
if (currentPos.x != pos.x || currentPos.z != pos.z) {
|
||||||
area_rendered++;
|
area_rendered++;
|
||||||
if (currentPos.z != pos.z) {
|
if (currentPos.z != pos.z) {
|
||||||
pushPixelRows(pos.z);
|
if (m_scaleFactor > 1) {
|
||||||
|
scalePixelRows(m_blockPixelAttributes, m_blockPixelAttributesScaled, pos.z);
|
||||||
|
pushPixelRows(m_blockPixelAttributesScaled, pos.z);
|
||||||
|
m_blockPixelAttributesScaled.setLastY(((m_zMax - pos.z) * 16 + 15) / m_scaleFactor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pushPixelRows(m_blockPixelAttributes, pos.z);
|
||||||
|
}
|
||||||
m_blockPixelAttributes.setLastY((m_zMax - pos.z) * 16 + 15);
|
m_blockPixelAttributes.setLastY((m_zMax - pos.z) * 16 + 15);
|
||||||
if (progressIndicator)
|
if (progressIndicator)
|
||||||
cout << "Processing Z-coordinate: " << std::setw(6) << pos.z*16
|
cout << "Processing Z-coordinate: " << std::setw(6) << pos.z*16
|
||||||
@ -1403,8 +1533,15 @@ void TileGenerator::renderMap()
|
|||||||
throw(std::runtime_error("Too many block unpacking errors - bailing out"));
|
throw(std::runtime_error("Too many block unpacking errors - bailing out"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (currentPos.z != INT_MIN)
|
if (currentPos.z != INT_MIN) {
|
||||||
pushPixelRows(currentPos.z - 1);
|
if (m_scaleFactor > 1) {
|
||||||
|
scalePixelRows(m_blockPixelAttributes, m_blockPixelAttributesScaled, currentPos.z - 1);
|
||||||
|
pushPixelRows(m_blockPixelAttributesScaled, currentPos.z - 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pushPixelRows(m_blockPixelAttributes, currentPos.z - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (verboseStatistics) {
|
if (verboseStatistics) {
|
||||||
cout << "Statistics"
|
cout << "Statistics"
|
||||||
<< ": blocks read: " << m_db->getBlocksReadCount()
|
<< ": blocks read: " << m_db->getBlocksReadCount()
|
||||||
@ -1504,7 +1641,7 @@ inline void TileGenerator::renderMapBlock(const ustring &mapBlock, const BlockPo
|
|||||||
#undef pixel
|
#undef pixel
|
||||||
}
|
}
|
||||||
if (!rowIsEmpty)
|
if (!rowIsEmpty)
|
||||||
m_blockPixelAttributes.attribute(zBegin + 15 - z,xBegin).next16Empty = false;
|
m_blockPixelAttributes.attribute(zBegin + 15 - z,xBegin).nextEmpty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1519,7 +1656,7 @@ void TileGenerator::renderScale()
|
|||||||
string scaleText;
|
string scaleText;
|
||||||
|
|
||||||
if ((m_drawScale & DRAWSCALE_TOP)) {
|
if ((m_drawScale & DRAWSCALE_TOP)) {
|
||||||
for (int i = (m_xMin / 4) * 4; i <= m_xMax; i += 4) {
|
for (int i = (m_xMin / 4) * 4; i <= m_xMax; i += 4 * m_scaleFactor) {
|
||||||
stringstream buf1, buf2;
|
stringstream buf1, buf2;
|
||||||
buf1 << i * 16;
|
buf1 << i * 16;
|
||||||
buf2 << "(" << i << ")";
|
buf2 << "(" << i << ")";
|
||||||
@ -1534,7 +1671,7 @@ void TileGenerator::renderScale()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((m_drawScale & DRAWSCALE_LEFT)) {
|
if ((m_drawScale & DRAWSCALE_LEFT)) {
|
||||||
for (int i = (m_zMax / 4) * 4; i >= m_zMin; i -= 4) {
|
for (int i = (m_zMax / 4) * 4; i >= m_zMin; i -= 4 * m_scaleFactor) {
|
||||||
stringstream buf1, buf2;
|
stringstream buf1, buf2;
|
||||||
buf1 << i * 16;
|
buf1 << i * 16;
|
||||||
buf2 << "(" << i << ")";
|
buf2 << "(" << i << ")";
|
||||||
@ -1797,33 +1934,29 @@ void TileGenerator::printUnknown()
|
|||||||
inline int TileGenerator::mapX2ImageX(int val) const
|
inline int TileGenerator::mapX2ImageX(int val) const
|
||||||
{
|
{
|
||||||
if (m_tileWidth && m_tileBorderSize)
|
if (m_tileWidth && m_tileBorderSize)
|
||||||
val += ((val - m_tileMapXOffset + m_tileWidth) / m_tileWidth) * m_tileBorderSize + borderLeft();
|
val += ((val - m_tileMapXOffset / m_scaleFactor + m_tileWidth / m_scaleFactor) / (m_tileWidth / m_scaleFactor)) * m_tileBorderSize;
|
||||||
else
|
return val + borderLeft();
|
||||||
val += borderLeft();
|
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust map coordinate for tiles and border
|
// Adjust map coordinate for tiles and border
|
||||||
inline int TileGenerator::mapY2ImageY(int val) const
|
inline int TileGenerator::mapY2ImageY(int val) const
|
||||||
{
|
{
|
||||||
if (m_tileHeight && m_tileBorderSize)
|
if (m_tileHeight / m_scaleFactor && m_tileBorderSize)
|
||||||
val += ((val - m_tileMapYOffset + m_tileHeight) / m_tileHeight) * m_tileBorderSize + borderTop();
|
val += ((val - m_tileMapYOffset / m_scaleFactor + m_tileHeight / m_scaleFactor) / (m_tileHeight / m_scaleFactor)) * m_tileBorderSize;
|
||||||
else
|
return val + borderTop();
|
||||||
val += borderTop();
|
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert world coordinate to image coordinate
|
// Convert world coordinate to image coordinate
|
||||||
inline int TileGenerator::worldX2ImageX(int val) const
|
inline int TileGenerator::worldX2ImageX(int val) const
|
||||||
{
|
{
|
||||||
val = (val - m_xMin * 16) - m_mapXStartNodeOffset;
|
val = (val - m_xMin * 16) - m_mapXStartNodeOffset;
|
||||||
return mapX2ImageX(val);
|
return mapX2ImageX(val / m_scaleFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert world coordinate to image coordinate
|
// Convert world coordinate to image coordinate
|
||||||
inline int TileGenerator::worldZ2ImageY(int val) const
|
inline int TileGenerator::worldZ2ImageY(int val) const
|
||||||
{
|
{
|
||||||
val = (m_zMax * 16 + 15 - val) - m_mapYStartNodeOffset;
|
val = (m_zMax * 16 + 15 - val) - m_mapYStartNodeOffset;
|
||||||
return mapY2ImageY(val);
|
return mapY2ImageY(val / m_scaleFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +138,7 @@ public:
|
|||||||
void setTileSize(int width, int heigth);
|
void setTileSize(int width, int heigth);
|
||||||
void setTileOrigin(int x, int y);
|
void setTileOrigin(int x, int y);
|
||||||
void setTileCenter(int x, int y);
|
void setTileCenter(int x, int y);
|
||||||
|
void setScaleFactor(int f);
|
||||||
void enableProgressIndicator(void);
|
void enableProgressIndicator(void);
|
||||||
void parseNodeColorsFile(const std::string &fileName);
|
void parseNodeColorsFile(const std::string &fileName);
|
||||||
void parseHeightMapNodesFile(const std::string &fileName);
|
void parseHeightMapNodesFile(const std::string &fileName);
|
||||||
@ -151,6 +152,7 @@ private:
|
|||||||
std::string getWorldDatabaseBackend(const std::string &input);
|
std::string getWorldDatabaseBackend(const std::string &input);
|
||||||
int getMapChunkSize(const std::string &input);
|
int getMapChunkSize(const std::string &input);
|
||||||
void openDb(const std::string &input);
|
void openDb(const std::string &input);
|
||||||
|
void sanitizeParameters(void);
|
||||||
void loadBlocks();
|
void loadBlocks();
|
||||||
void createImage();
|
void createImage();
|
||||||
void computeMapParameters(const std::string &input);
|
void computeMapParameters(const std::string &input);
|
||||||
@ -162,8 +164,6 @@ private:
|
|||||||
int mapEndNodeOffset,
|
int mapEndNodeOffset,
|
||||||
int tileOrigin,
|
int tileOrigin,
|
||||||
int tileSize,
|
int tileSize,
|
||||||
// Input / Output parameters
|
|
||||||
int &pictSize,
|
|
||||||
// Output parameters
|
// Output parameters
|
||||||
int &tileBorderCount,
|
int &tileBorderCount,
|
||||||
int &tileMapOffset,
|
int &tileMapOffset,
|
||||||
@ -172,7 +172,8 @@ private:
|
|||||||
bool ascending);
|
bool ascending);
|
||||||
void renderMap();
|
void renderMap();
|
||||||
std::list<int> getZValueList() const;
|
std::list<int> getZValueList() const;
|
||||||
void pushPixelRows(int zPosLimit);
|
void pushPixelRows(PixelAttributes &pixelAttributes, int zPosLimit);
|
||||||
|
void scalePixelRows(PixelAttributes &pixelAttributes, PixelAttributes &pixelAttributesScaled, int zPosLimit);
|
||||||
void processMapBlock(const DB::Block &block);
|
void processMapBlock(const DB::Block &block);
|
||||||
void renderMapBlock(const ustring &mapBlock, const BlockPos &pos, int version);
|
void renderMapBlock(const ustring &mapBlock, const BlockPos &pos, int version);
|
||||||
void renderScale();
|
void renderScale();
|
||||||
@ -231,12 +232,14 @@ private:
|
|||||||
std::string m_backend;
|
std::string m_backend;
|
||||||
bool m_shrinkGeometry;
|
bool m_shrinkGeometry;
|
||||||
bool m_blockGeometry;
|
bool m_blockGeometry;
|
||||||
|
int m_scaleFactor;
|
||||||
bool m_sqliteCacheWorldRow;
|
bool m_sqliteCacheWorldRow;
|
||||||
int m_chunkSize;
|
int m_chunkSize;
|
||||||
|
|
||||||
DB *m_db;
|
DB *m_db;
|
||||||
gdImagePtr m_image;
|
gdImagePtr m_image;
|
||||||
PixelAttributes m_blockPixelAttributes;
|
PixelAttributes m_blockPixelAttributes;
|
||||||
|
PixelAttributes m_blockPixelAttributesScaled;
|
||||||
int m_xMin;
|
int m_xMin;
|
||||||
int m_xMax;
|
int m_xMax;
|
||||||
int m_zMin;
|
int m_zMin;
|
||||||
@ -257,6 +260,10 @@ private:
|
|||||||
int m_mapYStartNodeOffset;
|
int m_mapYStartNodeOffset;
|
||||||
int m_mapXEndNodeOffset;
|
int m_mapXEndNodeOffset;
|
||||||
int m_mapYEndNodeOffset;
|
int m_mapYEndNodeOffset;
|
||||||
|
int m_mapXStartNodeOffsetOrig;
|
||||||
|
int m_mapYStartNodeOffsetOrig;
|
||||||
|
int m_mapXEndNodeOffsetOrig;
|
||||||
|
int m_mapYEndNodeOffsetOrig;
|
||||||
int m_tileXOrigin;
|
int m_tileXOrigin;
|
||||||
int m_tileZOrigin;
|
int m_tileZOrigin;
|
||||||
int m_tileXCentered;
|
int m_tileXCentered;
|
||||||
|
29
mapper.cpp
29
mapper.cpp
@ -37,6 +37,7 @@ using namespace std;
|
|||||||
#define OPT_HEIGHTMAPNODESFILE 0x8b
|
#define OPT_HEIGHTMAPNODESFILE 0x8b
|
||||||
#define OPT_HEIGHTMAPCOLORSFILE 0x8c
|
#define OPT_HEIGHTMAPCOLORSFILE 0x8c
|
||||||
#define OPT_DRAWHEIGHTSCALE 0x8d
|
#define OPT_DRAWHEIGHTSCALE 0x8d
|
||||||
|
#define OPT_SCALEFACTOR 0x8e
|
||||||
|
|
||||||
// Will be replaced with the actual name and location of the executable (if found)
|
// Will be replaced with the actual name and location of the executable (if found)
|
||||||
string executableName = "minetestmapper";
|
string executableName = "minetestmapper";
|
||||||
@ -116,6 +117,7 @@ void usage()
|
|||||||
" --tiles <tilesize>[+<border>]|block|chunk\n"
|
" --tiles <tilesize>[+<border>]|block|chunk\n"
|
||||||
" --tileorigin <x>,<y>|world|map\n"
|
" --tileorigin <x>,<y>|world|map\n"
|
||||||
" --tilecenter <x>,<y>|world|map\n"
|
" --tilecenter <x>,<y>|world|map\n"
|
||||||
|
" --scalefactor 1:<n>\n"
|
||||||
" --chunksize <size>\n"
|
" --chunksize <size>\n"
|
||||||
" --verbose[=n]\n"
|
" --verbose[=n]\n"
|
||||||
" --verbose-search-colors[=n]\n"
|
" --verbose-search-colors[=n]\n"
|
||||||
@ -582,6 +584,7 @@ int main(int argc, char *argv[])
|
|||||||
{"tileorigin", required_argument, 0, 'T'},
|
{"tileorigin", required_argument, 0, 'T'},
|
||||||
{"tilecenter", required_argument, 0, 'T'},
|
{"tilecenter", required_argument, 0, 'T'},
|
||||||
{"tilebordercolor", required_argument, 0, 'B'},
|
{"tilebordercolor", required_argument, 0, 'B'},
|
||||||
|
{"scalefactor", required_argument, 0, OPT_SCALEFACTOR},
|
||||||
{"chunksize", required_argument, 0, OPT_CHUNKSIZE},
|
{"chunksize", required_argument, 0, OPT_CHUNKSIZE},
|
||||||
{"verbose", optional_argument, 0, 'v'},
|
{"verbose", optional_argument, 0, 'v'},
|
||||||
{"verbose-search-colors", optional_argument, 0, OPT_VERBOSE_SEARCH_COLORS},
|
{"verbose-search-colors", optional_argument, 0, OPT_VERBOSE_SEARCH_COLORS},
|
||||||
@ -812,6 +815,32 @@ int main(int argc, char *argv[])
|
|||||||
generator.setChunkSize(size);
|
generator.setChunkSize(size);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case OPT_SCALEFACTOR: {
|
||||||
|
istringstream arg;
|
||||||
|
arg.str(optarg);
|
||||||
|
int one;
|
||||||
|
char colon;
|
||||||
|
int factor = 1;
|
||||||
|
arg >> one >> std::ws;
|
||||||
|
if (arg.fail() || one != 1) {
|
||||||
|
std::cerr << "Invalid scale factor specification (" << optarg << ") - expected: 1:<n>" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!arg.eof()) {
|
||||||
|
arg >> colon >> factor >> std::ws;
|
||||||
|
if (arg.fail() || colon != ':' || factor<0 || !arg.eof()) {
|
||||||
|
std::cerr << "Invalid scale factor specification (" << optarg << ") - expected: 1:<n>" << std::endl;
|
||||||
|
usage();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (factor != 1 && factor != 2 && factor != 4 && factor != 8 && factor != 16) {
|
||||||
|
std::cerr << "Scale factor must be 1:1, 1:2, 1:4, 1:8 or 1:16" << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
generator.setScaleFactor(factor);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 't': {
|
case 't': {
|
||||||
istringstream tilesize;
|
istringstream tilesize;
|
||||||
tilesize.str(optarg);
|
tilesize.str(optarg);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user