Properly support painting tiles from secondary tileset

This commit is contained in:
Marcus Huderle 2018-03-13 20:07:16 -07:00
parent aa6949237f
commit 69c84a68e3
4 changed files with 50 additions and 31 deletions

View file

@ -322,7 +322,7 @@ void MetatilesPixmapItem::updateSelection(QPointF pos, Qt::MouseButton button) {
if ((x >= 0 && x < width) && (y >=0 && y < height)) { if ((x >= 0 && x < width) && (y >=0 && y < height)) {
int baseTileX = x < map->paint_metatile_initial_x ? x : map->paint_metatile_initial_x; int baseTileX = x < map->paint_metatile_initial_x ? x : map->paint_metatile_initial_x;
int baseTileY = y < map->paint_metatile_initial_y ? y : map->paint_metatile_initial_y; int baseTileY = y < map->paint_metatile_initial_y ? y : map->paint_metatile_initial_y;
map->paint_tile = baseTileY * 8 + baseTileX; map->paint_tile_index = baseTileY * 8 + baseTileX;
map->paint_tile_width = abs(map->paint_metatile_initial_x - x) + 1; map->paint_tile_width = abs(map->paint_metatile_initial_x - x) + 1;
map->paint_tile_height = abs(map->paint_metatile_initial_y - y) + 1; map->paint_tile_height = abs(map->paint_metatile_initial_y - y) + 1;
map->smart_paths_enabled = button == Qt::RightButton map->smart_paths_enabled = button == Qt::RightButton
@ -411,7 +411,7 @@ void MapPixmapItem::paintNormal(int x, int y) {
int actualY = j + y; int actualY = j + y;
Block *block = map->getBlock(actualX, actualY); Block *block = map->getBlock(actualX, actualY);
if (block) { if (block) {
block->tile = map->paint_tile + i + (j * 8); block->tile = map->getSelectedBlockIndex(map->paint_tile_index + i + (j * 8));
map->_setBlock(actualX, actualY, *block); map->_setBlock(actualX, actualY, *block);
} }
} }
@ -439,32 +439,38 @@ QList<int> MapPixmapItem::smartPathTable = QList<int>({
8 + 1, // 1111 8 + 1, // 1111
}); });
#define IS_SMART_PATH_TILE(block) ((block->tile >= map->paint_tile && block->tile < map->paint_tile + 3) \ #define IS_SMART_PATH_TILE(block) ((map->getDisplayedBlockIndex(block->tile) >= map->paint_tile_index && map->getDisplayedBlockIndex(block->tile) < map->paint_tile_index + 3) \
|| (block->tile >= map->paint_tile + 8 && block->tile < map->paint_tile + 11) \ || (map->getDisplayedBlockIndex(block->tile) >= map->paint_tile_index + 8 && map->getDisplayedBlockIndex(block->tile) < map->paint_tile_index + 11) \
|| (block->tile >= map->paint_tile + 16 && block->tile < map->paint_tile + 19)) || (map->getDisplayedBlockIndex(block->tile) >= map->paint_tile_index + 16 && map->getDisplayedBlockIndex(block->tile) < map->paint_tile_index + 19))
void MapPixmapItem::paintSmartPath(int x, int y) { void MapPixmapItem::paintSmartPath(int x, int y) {
// Smart path should never be enabled without a 3x3 block selection. // Smart path should never be enabled without a 3x3 block selection.
if (map->paint_tile_width != 3 || map->paint_tile_height != 3) return; if (map->paint_tile_width != 3 || map->paint_tile_height != 3) return;
// Shift to the middle tile of the smart path selection. // Shift to the middle tile of the smart path selection.
int openTile = map->paint_tile + 8 + 1; int openTile = map->paint_tile_index + 8 + 1;
// Fill the region with the open tile. // Fill the region with the open tile.
for (int i = -1; i <= 1 && i + x < map->getWidth() && i + x >= 0; i++) for (int i = -1; i <= 1; i++)
for (int j = -1; j <= 1 && j + y < map->getHeight() && j + y >= 0; j++) { for (int j = -1; j <= 1; j++) {
// Check if in map bounds.
if (!(i + x < map->getWidth() && i + x >= 0 && j + y < map->getHeight() && j + y >= 0))
continue;
int actualX = i + x; int actualX = i + x;
int actualY = j + y; int actualY = j + y;
Block *block = map->getBlock(actualX, actualY); Block *block = map->getBlock(actualX, actualY);
if (block) { if (block) {
block->tile = openTile; block->tile = map->getSelectedBlockIndex(openTile);
map->_setBlock(actualX, actualY, *block); map->_setBlock(actualX, actualY, *block);
} }
} }
// Go back and resolve the edge tiles // Go back and resolve the edge tiles
for (int i = -2; i <= 2 && i + x < map->getWidth() && i + x >= 0; i++) for (int i = -2; i <= 2; i++)
for (int j = -2; j <= 2 && j + y < map->getHeight() && j + y >= 0; j++) { for (int j = -2; j <= 2; j++) {
// Check if in map bounds.
if (!(i + x < map->getWidth() && i + x >= 0 && j + y < map->getHeight() && j + y >= 0))
continue;
// Ignore the corners, which can't possible be affected by the smart path. // Ignore the corners, which can't possible be affected by the smart path.
if ((i == -2 && j == -2) || (i == 2 && j == -2) || if ((i == -2 && j == -2) || (i == 2 && j == -2) ||
(i == -2 && j == 2) || (i == 2 && j == 2)) (i == -2 && j == 2) || (i == 2 && j == 2))
@ -494,11 +500,7 @@ void MapPixmapItem::paintSmartPath(int x, int y) {
if (left && IS_SMART_PATH_TILE(left)) if (left && IS_SMART_PATH_TILE(left))
id += 8; id += 8;
if (block) { block->tile = map->getSelectedBlockIndex(map->paint_tile_index + smartPathTable[id]);
qDebug() << "tile: " << block->tile << "base: " << map->paint_tile << "id: " << id;
}
block->tile = map->paint_tile + smartPathTable[id];;
map->_setBlock(actualX, actualY, *block); map->_setBlock(actualX, actualY, *block);
} }
} }
@ -508,7 +510,7 @@ void MapPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) {
QPointF pos = event->pos(); QPointF pos = event->pos();
int x = (int)(pos.x()) / 16; int x = (int)(pos.x()) / 16;
int y = (int)(pos.y()) / 16; int y = (int)(pos.y()) / 16;
map->floodFill(x, y, map->paint_tile); map->floodFill(x, y, map->getSelectedBlockIndex(map->paint_tile_index));
draw(); draw();
} }
} }
@ -519,7 +521,7 @@ void MapPixmapItem::pick(QGraphicsSceneMouseEvent *event) {
int y = (int)(pos.y()) / 16; int y = (int)(pos.y()) / 16;
Block *block = map->getBlock(x, y); Block *block = map->getBlock(x, y);
if (block) { if (block) {
map->paint_tile = block->tile; map->paint_tile_index = map->getDisplayedBlockIndex(block->tile);
map->paint_tile_width = 1; map->paint_tile_width = 1;
map->paint_tile_height = 1; map->paint_tile_height = 1;
emit map->paintTileChanged(map); emit map->paintTileChanged(map);

View file

@ -243,8 +243,6 @@ protected:
class MetatilesPixmapItem : public QObject, public QGraphicsPixmapItem { class MetatilesPixmapItem : public QObject, public QGraphicsPixmapItem {
Q_OBJECT Q_OBJECT
public: public:
MetatilesPixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) {
}
MetatilesPixmapItem(Map *map_) { MetatilesPixmapItem(Map *map_) {
map = map_; map = map_;
setAcceptHoverEvents(true); setAcceptHoverEvents(true);

35
map.cpp
View file

@ -12,7 +12,7 @@ Map::Map(QObject *parent) : QObject(parent)
cached_blockdata = new Blockdata; cached_blockdata = new Blockdata;
cached_collision = new Blockdata; cached_collision = new Blockdata;
cached_border = new Blockdata; cached_border = new Blockdata;
paint_tile = 1; paint_tile_index = 1;
paint_collision = 0; paint_collision = 0;
paint_elevation = 3; paint_elevation = 3;
} }
@ -72,6 +72,22 @@ int Map::getBlockIndex(int index) {
} }
} }
int Map::getSelectedBlockIndex(int index) {
if (index < tileset_primary->metatiles->length()) {
return index;
} else {
return 0x200 + (index - tileset_primary->metatiles->length());
}
}
int Map::getDisplayedBlockIndex(int index) {
if (index < tileset_primary->metatiles->length()) {
return index;
} else {
return index - 0x200 + tileset_primary->metatiles->length();
}
}
QImage Map::getMetatileTile(int tile) { QImage Map::getMetatileTile(int tile) {
Tileset *tileset = getBlockTileset(tile); Tileset *tileset = getBlockTileset(tile);
int local_index = getBlockIndex(tile); int local_index = getBlockIndex(tile);
@ -426,7 +442,7 @@ QPixmap Map::renderCollisionMetatiles() {
QImage metatile_image = getCollisionMetatileImage(i); QImage metatile_image = getCollisionMetatileImage(i);
painter.drawImage(origin, metatile_image); painter.drawImage(origin, metatile_image);
} }
drawSelection(paint_collision, width_, &painter); drawSelection(paint_collision, width_, 1, 1, &painter);
painter.end(); painter.end();
return QPixmap::fromImage(image); return QPixmap::fromImage(image);
} }
@ -444,20 +460,20 @@ QPixmap Map::renderElevationMetatiles() {
QImage metatile_image = getElevationMetatileImage(i); QImage metatile_image = getElevationMetatileImage(i);
painter.drawImage(origin, metatile_image); painter.drawImage(origin, metatile_image);
} }
drawSelection(paint_elevation, width_, &painter); drawSelection(paint_elevation, width_, 1, 1, &painter);
painter.end(); painter.end();
return QPixmap::fromImage(image); return QPixmap::fromImage(image);
} }
void Map::drawSelection(int i, int w, QPainter *painter) { void Map::drawSelection(int i, int w, int selectionWidth, int selectionHeight, QPainter *painter) {
int x = i % w; int x = i % w;
int y = i / w; int y = i / w;
painter->save(); painter->save();
QColor penColor = smart_paths_enabled ? QColor(0xff, 0x0, 0xff) : QColor(0xff, 0xff, 0xff); QColor penColor = smart_paths_enabled ? QColor(0xff, 0x0, 0xff) : QColor(0xff, 0xff, 0xff);
painter->setPen(penColor); painter->setPen(penColor);
int rectWidth = paint_tile_width * 16; int rectWidth = selectionWidth * 16;
int rectHeight = paint_tile_height * 16; int rectHeight = selectionHeight * 16;
painter->drawRect(x * 16, y * 16, rectWidth - 1, rectHeight -1); painter->drawRect(x * 16, y * 16, rectWidth - 1, rectHeight -1);
painter->setPen(QColor(0, 0, 0)); painter->setPen(QColor(0, 0, 0));
painter->drawRect(x * 16 - 1, y * 16 - 1, rectWidth + 1, rectHeight + 1); painter->drawRect(x * 16 - 1, y * 16 - 1, rectWidth + 1, rectHeight + 1);
@ -487,7 +503,7 @@ QPixmap Map::renderMetatiles() {
painter.drawImage(metatile_origin, metatile_image); painter.drawImage(metatile_origin, metatile_image);
} }
drawSelection(paint_tile, width_, &painter); drawSelection(paint_tile_index, width_, paint_tile_width, paint_tile_height, &painter);
painter.end(); painter.end();
return QPixmap::fromImage(image); return QPixmap::fromImage(image);
@ -750,9 +766,10 @@ void Map::clearHoveredTile() {
emit statusBarMessage(QString("")); emit statusBarMessage(QString(""));
} }
void Map::hoveredMetatileChanged(int block) { void Map::hoveredMetatileChanged(int blockIndex) {
int tile = getSelectedBlockIndex(blockIndex);
emit statusBarMessage(QString("Block: 0x%1") emit statusBarMessage(QString("Block: 0x%1")
.arg(QString("%1").arg(block, 3, 16, QChar('0')).toUpper())); .arg(QString("%1").arg(tile, 3, 16, QChar('0')).toUpper()));
} }
void Map::clearHoveredMetatile() { void Map::clearHoveredMetatile() {

6
map.h
View file

@ -112,6 +112,8 @@ public:
int getHeight(); int getHeight();
Tileset* getBlockTileset(int); Tileset* getBlockTileset(int);
int getBlockIndex(int index); int getBlockIndex(int index);
int getSelectedBlockIndex(int index);
int getDisplayedBlockIndex(int index);
Metatile* getMetatile(int); Metatile* getMetatile(int);
QImage getMetatileImage(int); QImage getMetatileImage(int);
QImage getMetatileTile(int); QImage getMetatileTile(int);
@ -128,7 +130,7 @@ public:
QPixmap renderCollisionMetatiles(); QPixmap renderCollisionMetatiles();
QPixmap renderElevationMetatiles(); QPixmap renderElevationMetatiles();
void drawSelection(int i, int w, QPainter *painter); void drawSelection(int i, int w, int selectionWidth, int selectionHeight, QPainter *painter);
bool blockChanged(int, Blockdata*); bool blockChanged(int, Blockdata*);
Blockdata* cached_blockdata = NULL; Blockdata* cached_blockdata = NULL;
@ -141,7 +143,7 @@ public:
bool smart_paths_enabled = false; bool smart_paths_enabled = false;
int paint_metatile_initial_x; int paint_metatile_initial_x;
int paint_metatile_initial_y; int paint_metatile_initial_y;
int paint_tile; int paint_tile_index;
int paint_tile_width = 1; int paint_tile_width = 1;
int paint_tile_height = 1; int paint_tile_height = 1;
int paint_tile_initial_x; int paint_tile_initial_x;