Support reading/displaying custom border sizes

This commit is contained in:
GriffinR 2020-03-13 02:23:47 -04:00
parent a5c47b6333
commit 629abd3c06
9 changed files with 95 additions and 19 deletions

View file

@ -109,6 +109,8 @@ public:
void setUsePoryScript(bool usePoryScript);
bool getUsePoryScript();
void setProjectDir(QString projectDir);
void setUseCustomBorderSize(bool enable);
bool getUseCustomBorderSize();
protected:
QString getConfigFilepath();
void parseConfigKeyValue(QString key, QString value);
@ -119,6 +121,7 @@ private:
QString projectDir;
bool useEncounterJson;
bool usePoryScript;
bool useCustomBorderSize;
};
extern ProjectConfig projectConfig;

View file

@ -14,6 +14,9 @@
#include <QGraphicsPixmapItem>
#include <math.h>
#define DEFAULT_BORDER_WIDTH 2
#define DEFAULT_BORDER_HEIGHT 2
class Map : public QObject
{
Q_OBJECT
@ -58,6 +61,8 @@ public:
static QString bgEventsLabelFromName(QString mapName);
int getWidth();
int getHeight();
int getBorderWidth();
int getBorderHeight();
QPixmap render(bool ignoreCache, MapLayout * fromLayout = nullptr);
QPixmap renderCollision(qreal opacity, bool ignoreCache);
bool blockChanged(int, Blockdata*);

View file

@ -15,6 +15,8 @@ public:
QString name;
QString width;
QString height;
QString border_width;
QString border_height;
QString border_path;
QString blockdata_path;
QString tileset_primary_label;

View file

@ -356,12 +356,18 @@ void ProjectConfig::parseConfigKeyValue(QString key, QString value) {
if (!ok) {
logWarn(QString("Invalid config value for use_encounter_json: '%1'. Must be 0 or 1.").arg(value));
}
} else if(key == "use_poryscript") {
} else if (key == "use_poryscript") {
bool ok;
this->usePoryScript = value.toInt(&ok);
if(!ok) {
if (!ok) {
logWarn(QString("Invalid config value for use_poryscript: '%1'. Must be 0 or 1.").arg(value));
}
} else if (key == "use_custom_border_size") {
bool ok;
this->useCustomBorderSize = value.toInt(&ok);
if (!ok) {
logWarn(QString("Invalid config value for use_custom_border_size: '%1'. Must be 0 or 1.").arg(value));
}
} else {
logWarn(QString("Invalid config key found in config file %1: '%2'").arg(this->getConfigFilepath()).arg(key));
}
@ -372,6 +378,7 @@ QMap<QString, QString> ProjectConfig::getKeyValueMap() {
map.insert("base_game_version", baseGameVersionMap.value(this->baseGameVersion));
map.insert("use_encounter_json", QString::number(this->useEncounterJson));
map.insert("use_poryscript", QString::number(this->usePoryScript));
map.insert("use_custom_border_size", QString::number(this->useCustomBorderSize));
return map;
}
@ -401,6 +408,7 @@ void ProjectConfig::onNewConfigFileCreated() {
this->baseGameVersion = static_cast<BaseGameVersion>(baseGameVersionComboBox->currentData().toInt());
}
}
this->useCustomBorderSize = this->baseGameVersion == BaseGameVersion::pokefirered;
this->useEncounterJson = true;
this->usePoryScript = false;
}
@ -435,3 +443,12 @@ void ProjectConfig::setUsePoryScript(bool usePoryScript) {
bool ProjectConfig::getUsePoryScript() {
return this->usePoryScript;
}
void ProjectConfig::setUseCustomBorderSize(bool enable) {
this->useCustomBorderSize = enable;
this->save();
}
bool ProjectConfig::getUseCustomBorderSize() {
return this->useCustomBorderSize;
}

View file

@ -59,6 +59,14 @@ int Map::getHeight() {
return layout->height.toInt(nullptr, 0);
}
int Map::getBorderWidth() {
return layout->border_width.toInt(nullptr, 0);
}
int Map::getBorderHeight() {
return layout->border_height.toInt(nullptr, 0);
}
bool Map::blockChanged(int i, Blockdata *cache) {
if (!cache)
return true;
@ -197,8 +205,8 @@ QPixmap Map::render(bool ignoreCache = false, MapLayout * fromLayout) {
QPixmap Map::renderBorder() {
bool changed_any = false;
int width_ = 2;
int height_ = 2;
int width_ = getBorderWidth();
int height_ = getBorderHeight();
if (layout->border_image.isNull()) {
layout->border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
changed_any = true;

View file

@ -1335,8 +1335,8 @@ void Editor::displayMapBorder() {
borderItems.clear();
QPixmap pixmap = map->renderBorder();
for (int y = -6; y < map->getHeight() + 6; y += 2)
for (int x = -6; x < map->getWidth() + 6; x += 2) {
for (int y = -6; y < map->getHeight() + 6; y += map->getBorderHeight())
for (int x = -6; x < map->getWidth() + 6; x += map->getBorderWidth()) {
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
item->setX(x * 16);
item->setY(y * 16);

View file

@ -8,6 +8,7 @@
#include "tile.h"
#include "tileset.h"
#include "imageexport.h"
#include "map.h"
#include <QDir>
#include <QJsonArray>
@ -489,6 +490,11 @@ bool Project::readMapLayouts() {
"border_filepath",
"blockdata_filepath",
};
bool useCustomBorderSize = projectConfig.getUseCustomBorderSize();
if (useCustomBorderSize) {
requiredFields.append("border_width");
requiredFields.append("border_height");
}
for (int i = 0; i < layouts.size(); i++) {
QJsonObject layoutObj = layouts[i].toObject();
if (layoutObj.isEmpty())
@ -520,6 +526,23 @@ bool Project::readMapLayouts() {
return false;
}
layout->height = QString::number(lheight);
if (useCustomBorderSize) {
int bwidth = layoutObj["border_width"].toInt();
if (bwidth <= 0) { // 0 is an expected border width/height that should be handled, GF used it for the RS layouts in FRLG
logWarn(QString("Invalid layout 'border_width' value '%1' on layout %2 in %3. Must be greater than 0. Using default (%4) instead.").arg(bwidth).arg(i).arg(layoutsFilepath).arg(DEFAULT_BORDER_WIDTH));
bwidth = DEFAULT_BORDER_WIDTH;
}
layout->border_width = QString::number(bwidth);
int bheight = layoutObj["border_height"].toInt();
if (bheight <= 0) {
logWarn(QString("Invalid layout 'border_height value '%1' on layout %2 in %3. Must be greater than 0. Using default (%4) instead.").arg(bheight).arg(i).arg(layoutsFilepath).arg(DEFAULT_BORDER_HEIGHT));
bheight = DEFAULT_BORDER_HEIGHT;
}
layout->border_height = QString::number(bheight);
} else {
layout->border_width = QString::number(DEFAULT_BORDER_WIDTH);
layout->border_height = QString::number(DEFAULT_BORDER_HEIGHT);
}
layout->tileset_primary_label = layoutObj["primary_tileset"].toString();
if (layout->tileset_primary_label.isEmpty()) {
logError(QString("Missing 'primary_tileset' value on layout %1 in %2").arg(i).arg(layoutsFilepath));
@ -536,7 +559,7 @@ bool Project::readMapLayouts() {
return false;
}
layout->blockdata_path = layoutObj["blockdata_filepath"].toString();
if (layout->border_path.isEmpty()) {
if (layout->blockdata_path.isEmpty()) {
logError(QString("Missing 'blockdata_filepath' value on layout %1 in %2").arg(i).arg(layoutsFilepath));
return false;
}
@ -563,6 +586,7 @@ void Project::saveMapLayouts() {
QJsonObject layoutsObj;
layoutsObj["layouts_table_label"] = layoutsLabel;
bool useCustomBorderSize = projectConfig.getUseCustomBorderSize();
QJsonArray layoutsArr;
for (QString layoutId : mapLayoutsTableMaster) {
MapLayout *layout = mapLayouts.value(layoutId);
@ -571,6 +595,10 @@ void Project::saveMapLayouts() {
layoutObj["name"] = layout->name;
layoutObj["width"] = layout->width.toInt(nullptr, 0);
layoutObj["height"] = layout->height.toInt(nullptr, 0);
if (useCustomBorderSize) {
layoutObj["border_width"] = layout->border_width.toInt(nullptr, 0);
layoutObj["border_height"] = layout->border_height.toInt(nullptr, 0);
}
layoutObj["primary_tileset"] = layout->tileset_primary_label;
layoutObj["secondary_tileset"] = layout->tileset_secondary_label;
layoutObj["border_filepath"] = layout->border_path;
@ -1034,7 +1062,7 @@ bool Project::loadMapBorder(Map *map) {
QString path = QString("%1/%2").arg(root).arg(map->layout->border_path);
map->layout->border = readBlockdata(path);
int borderLength = 4;
int borderLength = map->getBorderWidth() * map->getBorderHeight();
if (map->layout->border->blocks->count() != borderLength) {
logWarn(QString("Layout border blockdata length %1 must be %2. Resizing border blockdata.")
.arg(map->layout->border->blocks->count())
@ -1046,10 +1074,17 @@ bool Project::loadMapBorder(Map *map) {
void Project::setNewMapBorder(Map *map) {
Blockdata *blockdata = new Blockdata;
blockdata->addBlock(qint16(0x01D4));
blockdata->addBlock(qint16(0x01D5));
blockdata->addBlock(qint16(0x01DC));
blockdata->addBlock(qint16(0x01DD));
if (projectConfig.getBaseGameVersion() == BaseGameVersion::pokefirered) {
blockdata->addBlock(qint16(0x0014));
blockdata->addBlock(qint16(0x0015));
blockdata->addBlock(qint16(0x001C));
blockdata->addBlock(qint16(0x001D));
} else {
blockdata->addBlock(qint16(0x01D4));
blockdata->addBlock(qint16(0x01D5));
blockdata->addBlock(qint16(0x01DC));
blockdata->addBlock(qint16(0x01DD));
}
map->layout->border = blockdata;
}
@ -1136,6 +1171,10 @@ void Project::saveMap(Map *map) {
newLayoutObj["name"] = map->layout->name;
newLayoutObj["width"] = map->layout->width.toInt();
newLayoutObj["height"] = map->layout->height.toInt();
if (projectConfig.getUseCustomBorderSize()) {
newLayoutObj["border_width"] = map->layout->border_width.toInt();
newLayoutObj["border_height"] = map->layout->border_height.toInt();
}
newLayoutObj["primary_tileset"] = map->layout->tileset_primary_label;
newLayoutObj["secondary_tileset"] = map->layout->tileset_secondary_label;
newLayoutObj["border_filepath"] = map->layout->border_path;

View file

@ -9,9 +9,9 @@ void BorderMetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
int x = static_cast<int>(pos.x()) / 16;
int y = static_cast<int>(pos.y()) / 16;
for (int i = 0; i < selectionDimensions.x() && (i + x) < 2; i++) {
for (int j = 0; j < selectionDimensions.y() && (j + y) < 2; j++) {
int blockIndex = (j + y) * 2 + (i + x);
for (int i = 0; i < selectionDimensions.x() && (i + x) < map->getBorderWidth(); i++) {
for (int j = 0; j < selectionDimensions.y() && (j + y) < map->getBorderHeight(); j++) {
int blockIndex = (j + y) * map->getBorderWidth() + (i + x);
uint16_t tile = selectedMetatiles->at(j * selectionDimensions.x() + i);
(*map->layout->border->blocks)[blockIndex].tile = tile;
}
@ -22,15 +22,15 @@ void BorderMetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
}
void BorderMetatilesPixmapItem::draw() {
QImage image(32, 32, QImage::Format_RGBA8888);
QImage image(16 * map->getBorderWidth(), 16 * map->getBorderHeight(), QImage::Format_RGBA8888);
QPainter painter(&image);
QVector<Block> *blocks = map->layout->border->blocks;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
for (int i = 0; i < map->getBorderWidth(); i++) {
for (int j = 0; j < map->getBorderHeight(); j++) {
int x = i * 16;
int y = j * 16;
int index = j * 2 + i;
int index = j * map->getBorderWidth() + i;
QImage metatile_image = getMetatileImage(blocks->value(index).tile, map->layout->tileset_primary, map->layout->tileset_secondary);
QPoint metatile_origin = QPoint(x, y);
painter.drawImage(metatile_origin, metatile_image);

View file

@ -154,6 +154,8 @@ void NewMapPopup::on_pushButton_NewMap_Accept_clicked() {
layout->name = QString("%1_Layout").arg(newMap->name);
layout->width = QString::number(this->ui->spinBox_NewMap_Width->value());
layout->height = QString::number(this->ui->spinBox_NewMap_Height->value());
layout->border_width = QString::number(DEFAULT_BORDER_WIDTH);
layout->border_height = QString::number(DEFAULT_BORDER_HEIGHT);
layout->tileset_primary_label = this->ui->comboBox_NewMap_Primary_Tileset->currentText();
layout->tileset_secondary_label = this->ui->comboBox_NewMap_Secondary_Tileset->currentText();
layout->border_path = QString("data/layouts/%1/border.bin").arg(newMapName);