2018-09-25 01:12:29 +01:00
|
|
|
#include "tileset.h"
|
|
|
|
#include "metatile.h"
|
2018-09-23 00:47:28 +01:00
|
|
|
#include "project.h"
|
2019-03-21 23:50:50 +00:00
|
|
|
#include "log.h"
|
2020-04-20 18:28:56 +01:00
|
|
|
#include "config.h"
|
2018-09-23 00:47:28 +01:00
|
|
|
|
|
|
|
#include <QPainter>
|
|
|
|
#include <QImage>
|
|
|
|
|
2018-10-03 01:01:15 +01:00
|
|
|
|
2021-03-08 00:17:17 +00:00
|
|
|
Tileset::Tileset(const Tileset &other)
|
|
|
|
: name(other.name),
|
|
|
|
is_compressed(other.is_compressed),
|
|
|
|
is_secondary(other.is_secondary),
|
|
|
|
padding(other.padding),
|
|
|
|
tiles_label(other.tiles_label),
|
|
|
|
palettes_label(other.palettes_label),
|
|
|
|
metatiles_label(other.metatiles_label),
|
|
|
|
metatiles_path(other.metatiles_path),
|
|
|
|
callback_label(other.callback_label),
|
|
|
|
metatile_attrs_label(other.metatile_attrs_label),
|
|
|
|
metatile_attrs_path(other.metatile_attrs_path),
|
|
|
|
tilesImagePath(other.tilesImagePath),
|
|
|
|
tilesImage(other.tilesImage),
|
|
|
|
palettePaths(other.palettePaths),
|
|
|
|
tiles(other.tiles),
|
|
|
|
palettes(other.palettes),
|
|
|
|
palettePreviews(other.palettePreviews)
|
|
|
|
{
|
|
|
|
for (auto *metatile : other.metatiles) {
|
|
|
|
metatiles.append(new Metatile(*metatile));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Tileset &Tileset::operator=(const Tileset &other) {
|
|
|
|
name = other.name;
|
|
|
|
is_compressed = other.is_compressed;
|
|
|
|
is_secondary = other.is_secondary;
|
|
|
|
padding = other.padding;
|
|
|
|
tiles_label = other.tiles_label;
|
|
|
|
palettes_label = other.palettes_label;
|
|
|
|
metatiles_label = other.metatiles_label;
|
|
|
|
metatiles_path = other.metatiles_path;
|
|
|
|
callback_label = other.callback_label;
|
|
|
|
metatile_attrs_label = other.metatile_attrs_label;
|
|
|
|
metatile_attrs_path = other.metatile_attrs_path;
|
|
|
|
tilesImagePath = other.tilesImagePath;
|
|
|
|
tilesImage = other.tilesImage;
|
|
|
|
palettePaths = other.palettePaths;
|
|
|
|
tiles = other.tiles;
|
|
|
|
palettes = other.palettes;
|
|
|
|
palettePreviews = other.palettePreviews;
|
|
|
|
|
|
|
|
metatiles.clear();
|
|
|
|
for (auto *metatile : other.metatiles) {
|
|
|
|
metatiles.append(new Metatile(*metatile));
|
|
|
|
}
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2022-01-04 02:35:15 +00:00
|
|
|
Tileset* Tileset::getTileTileset(int tileId, Tileset *primaryTileset, Tileset *secondaryTileset) {
|
|
|
|
if (tileId < Project::getNumTilesPrimary()) {
|
2018-09-23 00:47:28 +01:00
|
|
|
return primaryTileset;
|
2022-01-04 02:35:15 +00:00
|
|
|
} else if (tileId < Project::getNumTilesTotal()) {
|
|
|
|
return secondaryTileset;
|
2018-09-23 00:47:28 +01:00
|
|
|
} else {
|
2022-01-04 02:35:15 +00:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Tileset* Tileset::getMetatileTileset(int metatileId, Tileset *primaryTileset, Tileset *secondaryTileset) {
|
|
|
|
if (metatileId < Project::getNumMetatilesPrimary()) {
|
|
|
|
return primaryTileset;
|
|
|
|
} else if (metatileId < Project::getNumMetatilesTotal()) {
|
2018-09-23 00:47:28 +01:00
|
|
|
return secondaryTileset;
|
2022-01-04 02:35:15 +00:00
|
|
|
} else {
|
|
|
|
return nullptr;
|
2018-09-23 00:47:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-04 02:35:15 +00:00
|
|
|
Metatile* Tileset::getMetatile(int metatileId, Tileset *primaryTileset, Tileset *secondaryTileset) {
|
|
|
|
Tileset *tileset = Tileset::getMetatileTileset(metatileId, primaryTileset, secondaryTileset);
|
|
|
|
int index = Metatile::getIndexInTileset(metatileId);
|
2021-02-17 02:45:54 +00:00
|
|
|
if (!tileset) {
|
2018-09-23 00:47:28 +01:00
|
|
|
return nullptr;
|
|
|
|
}
|
2022-01-04 02:35:15 +00:00
|
|
|
return tileset->metatiles.value(index, nullptr);
|
2018-09-23 00:47:28 +01:00
|
|
|
}
|
|
|
|
|
2020-04-09 20:12:52 +01:00
|
|
|
bool Tileset::metatileIsValid(uint16_t metatileId, Tileset *primaryTileset, Tileset *secondaryTileset) {
|
|
|
|
if (metatileId >= Project::getNumMetatilesTotal())
|
|
|
|
return false;
|
|
|
|
|
2021-02-17 02:45:54 +00:00
|
|
|
if (metatileId < Project::getNumMetatilesPrimary() && metatileId >= primaryTileset->metatiles.length())
|
2020-04-09 20:12:52 +01:00
|
|
|
return false;
|
|
|
|
|
2021-02-17 02:45:54 +00:00
|
|
|
if (metatileId >= Project::getNumMetatilesPrimary() + secondaryTileset->metatiles.length())
|
2020-04-09 20:12:52 +01:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-05-03 16:31:44 +01:00
|
|
|
QList<QList<QRgb>> Tileset::getBlockPalettes(Tileset *primaryTileset, Tileset *secondaryTileset, bool useTruePalettes) {
|
2018-09-23 00:47:28 +01:00
|
|
|
QList<QList<QRgb>> palettes;
|
2020-05-03 16:31:44 +01:00
|
|
|
auto primaryPalettes = useTruePalettes ? primaryTileset->palettes : primaryTileset->palettePreviews;
|
2018-09-23 00:47:28 +01:00
|
|
|
for (int i = 0; i < Project::getNumPalettesPrimary(); i++) {
|
2021-02-17 02:45:54 +00:00
|
|
|
palettes.append(primaryPalettes.at(i));
|
2018-09-23 00:47:28 +01:00
|
|
|
}
|
2020-05-03 16:31:44 +01:00
|
|
|
auto secondaryPalettes = useTruePalettes ? secondaryTileset->palettes : secondaryTileset->palettePreviews;
|
2018-09-23 00:47:28 +01:00
|
|
|
for (int i = Project::getNumPalettesPrimary(); i < Project::getNumPalettesTotal(); i++) {
|
2021-02-17 02:45:54 +00:00
|
|
|
palettes.append(secondaryPalettes.at(i));
|
2018-09-23 00:47:28 +01:00
|
|
|
}
|
|
|
|
return palettes;
|
|
|
|
}
|
2018-09-30 20:54:38 +01:00
|
|
|
|
2020-05-03 16:31:44 +01:00
|
|
|
QList<QRgb> Tileset::getPalette(int paletteId, Tileset *primaryTileset, Tileset *secondaryTileset, bool useTruePalettes) {
|
2018-09-30 20:54:38 +01:00
|
|
|
QList<QRgb> paletteTable;
|
|
|
|
Tileset *tileset = paletteId < Project::getNumPalettesPrimary()
|
|
|
|
? primaryTileset
|
|
|
|
: secondaryTileset;
|
2020-05-03 16:31:44 +01:00
|
|
|
auto palettes = useTruePalettes ? tileset->palettes : tileset->palettePreviews;
|
2021-02-17 02:45:54 +00:00
|
|
|
for (int i = 0; i < palettes.at(paletteId).length(); i++) {
|
|
|
|
paletteTable.append(palettes.at(paletteId).at(i));
|
2018-09-30 20:54:38 +01:00
|
|
|
}
|
|
|
|
return paletteTable;
|
|
|
|
}
|
2019-03-21 23:50:50 +00:00
|
|
|
|
|
|
|
bool Tileset::appendToHeaders(QString headerFile, QString friendlyName){
|
|
|
|
QFile file(headerFile);
|
|
|
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) {
|
|
|
|
logError(QString("Could not write to file \"%1\"").arg(headerFile));
|
|
|
|
return false;
|
|
|
|
}
|
2019-03-22 02:33:53 +00:00
|
|
|
QString dataString = "\n\t.align 2\n";
|
|
|
|
dataString.append(QString("%1::\n").arg(this->name));
|
|
|
|
dataString.append(QString("\t.byte %1 @ is compressed\n").arg(this->is_compressed));
|
|
|
|
dataString.append(QString("\t.byte %1 @ is secondary\n").arg(this->is_secondary));
|
2019-03-23 14:17:44 +00:00
|
|
|
dataString.append(QString("\t.2byte %1\n").arg(this->padding));
|
2019-03-22 02:33:53 +00:00
|
|
|
dataString.append(QString("\t.4byte gTilesetTiles_%1\n").arg(friendlyName));
|
|
|
|
dataString.append(QString("\t.4byte gTilesetPalettes_%1\n").arg(friendlyName));
|
|
|
|
dataString.append(QString("\t.4byte gMetatiles_%1\n").arg(friendlyName));
|
2020-04-20 18:28:56 +01:00
|
|
|
if (projectConfig.getBaseGameVersion() == BaseGameVersion::pokefirered) {
|
|
|
|
dataString.append("\t.4byte NULL\n");
|
|
|
|
dataString.append(QString("\t.4byte gMetatileAttributes_%1\n").arg(friendlyName));
|
|
|
|
} else {
|
|
|
|
dataString.append(QString("\t.4byte gMetatileAttributes_%1\n").arg(friendlyName));
|
|
|
|
dataString.append("\t.4byte NULL\n");
|
|
|
|
}
|
2019-03-21 23:50:50 +00:00
|
|
|
file.write(dataString.toUtf8());
|
|
|
|
file.flush();
|
|
|
|
file.close();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Tileset::appendToGraphics(QString graphicsFile, QString friendlyName, bool primary) {
|
|
|
|
QString primaryString = primary ? "primary" : "secondary";
|
|
|
|
QFile file(graphicsFile);
|
|
|
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) {
|
|
|
|
logError(QString("Could not write to file \"%1\"").arg(graphicsFile));
|
|
|
|
return false;
|
|
|
|
}
|
2019-03-22 02:33:53 +00:00
|
|
|
QString dataString = "\n\t.align 2\n";
|
|
|
|
dataString.append(QString("gTilesetPalettes_%1::\n").arg(friendlyName));
|
2019-03-22 00:56:00 +00:00
|
|
|
for(int i = 0; i < Project::getNumPalettesTotal(); ++i) {
|
2020-08-27 01:42:42 +01:00
|
|
|
QString paletteString = QString("%1.gbapal").arg(i, 2, 10, QLatin1Char('0'));
|
2019-03-22 02:33:53 +00:00
|
|
|
dataString.append(QString("\t.incbin \"data/tilesets/%1/%2/palettes/%3\"\n").arg(primaryString, friendlyName.toLower(), paletteString));
|
2019-03-21 23:50:50 +00:00
|
|
|
|
|
|
|
}
|
2019-03-22 02:33:53 +00:00
|
|
|
dataString.append("\n\t.align 2\n");
|
|
|
|
dataString.append(QString("gTilesetTiles_%1::\n").arg(friendlyName));
|
|
|
|
dataString.append(QString("\t.incbin \"data/tilesets/%1/%2/tiles.4bpp.lz\"\n").arg(primaryString, friendlyName.toLower()));
|
2019-03-21 23:50:50 +00:00
|
|
|
file.write(dataString.toUtf8());
|
|
|
|
file.flush();
|
|
|
|
file.close();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Tileset::appendToMetatiles(QString metatileFile, QString friendlyName, bool primary) {
|
|
|
|
QString primaryString = primary ? "primary" : "secondary";
|
|
|
|
QFile file(metatileFile);
|
|
|
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) {
|
|
|
|
logError(QString("Could not write to file \"%1\"").arg(metatileFile));
|
|
|
|
return false;
|
|
|
|
}
|
2019-03-22 02:33:53 +00:00
|
|
|
QString dataString = "\n\t.align 1\n";
|
|
|
|
dataString.append(QString("gMetatiles_%1::\n").arg(friendlyName));
|
|
|
|
dataString.append(QString("\t.incbin \"data/tilesets/%1/%2/metatiles.bin\"\n").arg(primaryString, friendlyName.toLower()));
|
|
|
|
dataString.append(QString("\n\t.align 1\n"));
|
|
|
|
dataString.append(QString("gMetatileAttributes_%1::\n").arg(friendlyName));
|
2022-03-30 15:31:36 +01:00
|
|
|
dataString.append(QString("\t.incbin \"data/tilesets/%1/%2/metatile_attributes.bin\"\n").arg(primaryString, friendlyName.toLower()));
|
2019-03-21 23:50:50 +00:00
|
|
|
file.write(dataString.toUtf8());
|
|
|
|
file.flush();
|
|
|
|
file.close();
|
|
|
|
return true;
|
|
|
|
}
|