mirror of
https://github.com/minetest/minetestmapper.git
synced 2025-07-05 10:00:20 +02:00
Compare commits
3 Commits
20200328
...
night_rend
Author | SHA1 | Date | |
---|---|---|---|
55e407c130 | |||
2979dc5b6b | |||
92f6b051a5 |
@ -11,20 +11,18 @@ static inline uint16_t readU16(const unsigned char *data)
|
|||||||
return data[0] << 8 | data[1];
|
return data[0] << 8 | data[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int readBlockContent(const unsigned char *mapData, u8 version, unsigned int datapos)
|
static int readBlockContent(const unsigned char *mapData, u8 contentWidth, unsigned int datapos)
|
||||||
{
|
{
|
||||||
if (version >= 24) {
|
if (contentWidth == 2) {
|
||||||
size_t index = datapos << 1;
|
size_t index = datapos << 1;
|
||||||
return (mapData[index] << 8) | mapData[index + 1];
|
return (mapData[index] << 8) | mapData[index + 1];
|
||||||
} else if (version >= 20) {
|
} else {
|
||||||
if (mapData[datapos] <= 0x80)
|
u8 param = mapData[datapos];
|
||||||
return mapData[datapos];
|
if (param <= 0x7f)
|
||||||
|
return param;
|
||||||
else
|
else
|
||||||
return (int(mapData[datapos]) << 4) | (int(mapData[datapos + 0x2000]) >> 4);
|
return (int(param) << 4) | (int(mapData[datapos + 0x2000]) >> 4);
|
||||||
}
|
}
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "Unsupported map version " << version;
|
|
||||||
throw std::runtime_error(oss.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockDecoder::BlockDecoder()
|
BlockDecoder::BlockDecoder()
|
||||||
@ -39,6 +37,7 @@ void BlockDecoder::reset()
|
|||||||
m_nameMap.clear();
|
m_nameMap.clear();
|
||||||
|
|
||||||
m_version = 0;
|
m_version = 0;
|
||||||
|
m_contentWidth = 0;
|
||||||
m_mapData = ustring();
|
m_mapData = ustring();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,16 +49,30 @@ void BlockDecoder::decode(const ustring &datastr)
|
|||||||
|
|
||||||
uint8_t version = data[0];
|
uint8_t version = data[0];
|
||||||
//uint8_t flags = data[1];
|
//uint8_t flags = data[1];
|
||||||
|
if (version < 22) {
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "Unsupported map version " << (int)version;
|
||||||
|
throw std::runtime_error(oss.str());
|
||||||
|
}
|
||||||
m_version = version;
|
m_version = version;
|
||||||
|
|
||||||
size_t dataOffset = 0;
|
size_t dataOffset = 0;
|
||||||
if (version >= 27)
|
if (version >= 27)
|
||||||
dataOffset = 6;
|
|
||||||
else if (version >= 22)
|
|
||||||
dataOffset = 4;
|
dataOffset = 4;
|
||||||
else
|
else
|
||||||
dataOffset = 2;
|
dataOffset = 2;
|
||||||
|
|
||||||
|
uint8_t contentWidth = data[dataOffset];
|
||||||
|
dataOffset++;
|
||||||
|
uint8_t paramsWidth = data[dataOffset];
|
||||||
|
dataOffset++;
|
||||||
|
if (contentWidth != 1 && contentWidth != 2)
|
||||||
|
throw std::runtime_error("unsupported map version (contentWidth)");
|
||||||
|
if (paramsWidth != 2)
|
||||||
|
throw std::runtime_error("unsupported map version (paramsWidth)");
|
||||||
|
m_contentWidth = contentWidth;
|
||||||
|
|
||||||
|
|
||||||
ZlibDecompressor decompressor(data, length);
|
ZlibDecompressor decompressor(data, length);
|
||||||
decompressor.setSeekPos(dataOffset);
|
decompressor.setSeekPos(dataOffset);
|
||||||
m_mapData = decompressor.decompress();
|
m_mapData = decompressor.decompress();
|
||||||
@ -67,8 +80,6 @@ void BlockDecoder::decode(const ustring &datastr)
|
|||||||
dataOffset = decompressor.seekPos();
|
dataOffset = decompressor.seekPos();
|
||||||
|
|
||||||
// Skip unused data
|
// Skip unused data
|
||||||
if (version <= 21)
|
|
||||||
dataOffset += 2;
|
|
||||||
if (version == 23)
|
if (version == 23)
|
||||||
dataOffset += 1;
|
dataOffset += 1;
|
||||||
if (version == 24) {
|
if (version == 24) {
|
||||||
@ -92,7 +103,7 @@ void BlockDecoder::decode(const ustring &datastr)
|
|||||||
dataOffset += 4; // Skip timestamp
|
dataOffset += 4; // Skip timestamp
|
||||||
|
|
||||||
// Read mapping
|
// Read mapping
|
||||||
if (version >= 22) {
|
{
|
||||||
dataOffset++; // mapping version
|
dataOffset++; // mapping version
|
||||||
uint16_t numMappings = readU16(data + dataOffset);
|
uint16_t numMappings = readU16(data + dataOffset);
|
||||||
dataOffset += 2;
|
dataOffset += 2;
|
||||||
@ -130,7 +141,7 @@ bool BlockDecoder::isEmpty() const
|
|||||||
std::string BlockDecoder::getNode(u8 x, u8 y, u8 z) const
|
std::string BlockDecoder::getNode(u8 x, u8 y, u8 z) const
|
||||||
{
|
{
|
||||||
unsigned int position = x + (y << 4) + (z << 8);
|
unsigned int position = x + (y << 4) + (z << 8);
|
||||||
int content = readBlockContent(m_mapData.c_str(), m_version, position);
|
int content = readBlockContent(m_mapData.c_str(), m_contentWidth, position);
|
||||||
if (content == m_blockAirId || content == m_blockIgnoreId)
|
if (content == m_blockAirId || content == m_blockIgnoreId)
|
||||||
return "";
|
return "";
|
||||||
NameMap::const_iterator it = m_nameMap.find(content);
|
NameMap::const_iterator it = m_nameMap.find(content);
|
||||||
@ -140,3 +151,10 @@ std::string BlockDecoder::getNode(u8 x, u8 y, u8 z) const
|
|||||||
}
|
}
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u8 BlockDecoder::getParam1(u8 x, u8 y, u8 z) const
|
||||||
|
{
|
||||||
|
unsigned int position = x + (y << 4) + (z << 8);
|
||||||
|
unsigned int offset = (m_contentWidth == 2) ? 0x2000 : 0x1000;
|
||||||
|
return m_mapData.c_str()[offset + position];
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
#include "TileGenerator.h"
|
#include "TileGenerator.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -331,10 +332,10 @@ void TileGenerator::openDb(const std::string &input)
|
|||||||
{
|
{
|
||||||
std::string backend = m_backend;
|
std::string backend = m_backend;
|
||||||
if (backend == "") {
|
if (backend == "") {
|
||||||
std::ifstream ifs((input + "/world.mt").c_str());
|
std::ifstream ifs(input + "/world.mt");
|
||||||
if(!ifs.good())
|
if(!ifs.good())
|
||||||
throw std::runtime_error("Failed to read world.mt");
|
throw std::runtime_error("Failed to open world.mt");
|
||||||
backend = read_setting("backend", ifs);
|
backend = read_setting_default("backend", ifs, "sqlite3");
|
||||||
ifs.close();
|
ifs.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,8 +496,6 @@ void TileGenerator::renderMap()
|
|||||||
|
|
||||||
blk.reset();
|
blk.reset();
|
||||||
blk.decode(it.second);
|
blk.decode(it.second);
|
||||||
if (blk.isEmpty())
|
|
||||||
continue;
|
|
||||||
renderMapBlock(blk, pos);
|
renderMapBlock(blk, pos);
|
||||||
|
|
||||||
// Exit out if all pixels for this MapBlock are covered
|
// Exit out if all pixels for this MapBlock are covered
|
||||||
@ -576,6 +575,28 @@ void TileGenerator::renderMap()
|
|||||||
|
|
||||||
void TileGenerator::renderMapBlock(const BlockDecoder &blk, const BlockPos &pos)
|
void TileGenerator::renderMapBlock(const BlockDecoder &blk, const BlockPos &pos)
|
||||||
{
|
{
|
||||||
|
/***/
|
||||||
|
static bool light_curve_init = false;
|
||||||
|
static float light_curve[16];
|
||||||
|
if (!light_curve_init) {
|
||||||
|
for (u8 i = 0; i < 16; i++)
|
||||||
|
light_curve[i] = expf((i - 15) / 12.0f);
|
||||||
|
light_curve_init = true;
|
||||||
|
}
|
||||||
|
/***/
|
||||||
|
auto light_at = [blk] (u8 x, u8 y, u8 z) -> u8 {
|
||||||
|
return blk.getParam1(x, y, z) >> 4; // night bank
|
||||||
|
};
|
||||||
|
static u8 m_light[16][16];
|
||||||
|
if (blk.isEmpty()) {
|
||||||
|
for (int z = 0; z < 16; ++z) {
|
||||||
|
for (int x = 0; x < 16; ++x) {
|
||||||
|
m_light[z][x] = light_at(x, 0, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int xBegin = (pos.x - m_xMin) * 16;
|
int xBegin = (pos.x - m_xMin) * 16;
|
||||||
int zBegin = (m_zMax - pos.z) * 16;
|
int zBegin = (m_zMax - pos.z) * 16;
|
||||||
int minY = (pos.y * 16 > m_yMin) ? 0 : m_yMin - pos.y * 16;
|
int minY = (pos.y * 16 > m_yMin) ? 0 : m_yMin - pos.y * 16;
|
||||||
@ -589,14 +610,25 @@ void TileGenerator::renderMapBlock(const BlockDecoder &blk, const BlockPos &pos)
|
|||||||
|
|
||||||
for (int y = maxY; y >= minY; --y) {
|
for (int y = maxY; y >= minY; --y) {
|
||||||
string name = blk.getNode(x, y, z);
|
string name = blk.getNode(x, y, z);
|
||||||
if (name == "")
|
if (name == "") {
|
||||||
|
if (y == 0) m_light[z][x] = light_at(x, 0, z);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
ColorMap::const_iterator it = m_colorMap.find(name);
|
ColorMap::const_iterator it = m_colorMap.find(name);
|
||||||
if (it == m_colorMap.end()) {
|
if (it == m_colorMap.end()) {
|
||||||
m_unknownNodes.insert(name);
|
m_unknownNodes.insert(name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const Color c = it->second.to_color();
|
Color c = it->second.to_color();
|
||||||
|
u8 light = (y == 15) ? m_light[z][x] : light_at(x, y+1, z);
|
||||||
|
if (light < 15) light = mymax(light, light_at(x, y, z));
|
||||||
|
if (1) {
|
||||||
|
float l2 = light_curve[light];
|
||||||
|
c.r = colorSafeBounds(c.r * l2);
|
||||||
|
c.g = colorSafeBounds(c.g * l2);
|
||||||
|
c.b = colorSafeBounds(c.b * l2);
|
||||||
|
} else
|
||||||
|
c = Color(light * 17, light * 17, light * 17);
|
||||||
if (m_drawAlpha) {
|
if (m_drawAlpha) {
|
||||||
if (m_color[z][x].a == 0)
|
if (m_color[z][x].a == 0)
|
||||||
m_color[z][x] = c; // first visible time, no color mixing
|
m_color[z][x] = c; // first visible time, no color mixing
|
||||||
|
@ -13,6 +13,7 @@ public:
|
|||||||
void decode(const ustring &data);
|
void decode(const ustring &data);
|
||||||
bool isEmpty() const;
|
bool isEmpty() const;
|
||||||
std::string getNode(u8 x, u8 y, u8 z) const; // returns "" for air, ignore and invalid nodes
|
std::string getNode(u8 x, u8 y, u8 z) const; // returns "" for air, ignore and invalid nodes
|
||||||
|
u8 getParam1(u8 x, u8 y, u8 z) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::unordered_map<int, std::string> NameMap;
|
typedef std::unordered_map<int, std::string> NameMap;
|
||||||
@ -20,7 +21,7 @@ private:
|
|||||||
int m_blockAirId;
|
int m_blockAirId;
|
||||||
int m_blockIgnoreId;
|
int m_blockIgnoreId;
|
||||||
|
|
||||||
u8 m_version;
|
u8 m_version, m_contentWidth;
|
||||||
ustring m_mapData;
|
ustring m_mapData;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user