Initial commit

This commit is contained in:
yenatch 2016-09-06 23:50:47 -04:00
commit 2246ead5a8
33 changed files with 3961 additions and 0 deletions

59
asm.cpp Executable file
View file

@ -0,0 +1,59 @@
#include "asm.h"
Asm::Asm()
{
}
void Asm::strip_comment(QString *line) {
bool in_string = false;
for (int i = 0; i < line->length(); i++) {
if (line->at(i) == '"') {
in_string = !in_string;
} else if (line->at(i) == '@') {
if (!in_string) {
line->truncate(i);
break;
}
}
}
}
QList<QStringList>* Asm::parse(QString text) {
QList<QStringList> *parsed = new QList<QStringList>;
QStringList lines = text.split('\n');
for (QString line : lines) {
QString label;
//QString macro;
//QStringList *params;
strip_comment(&line);
if (line.isEmpty()) {
} else if (line.contains(':')) {
label = line.left(line.indexOf(':'));
QStringList *list = new QStringList;
list->append(".label"); // This is not a real keyword. It's used only to make the output more regular.
list->append(label);
parsed->append(*list);
// There should not be anything else on the line.
// gas will raise a syntax error if there is.
} else {
line = line.trimmed();
//parsed->append(line.split(QRegExp("\\s*,\\s*")));
QString macro;
QStringList params;
int index = line.indexOf(QRegExp("\\s+"));
macro = line.left(index);
params = line.right(line.length() - index).trimmed().split(QRegExp("\\s*,\\s*"));
params.prepend(macro);
parsed->append(params);
}
//if (macro != NULL) {
// if (macros->contains(macro)) {
// void* function = macros->value(macro);
// if (function != NULL) {
// std::function function(params);
// }
// }
//}
}
return parsed;
}

15
asm.h Executable file
View file

@ -0,0 +1,15 @@
#ifndef ASM_H
#define ASM_H
#include <QString>
#include <QList>
class Asm
{
public:
Asm();
void strip_comment(QString*);
QList<QStringList>* parse(QString);
};
#endif // ASM_H

29
block.cpp Executable file
View file

@ -0,0 +1,29 @@
#include "block.h"
Block::Block() {
}
Block::Block(uint16_t word)
{
tile = word & 0x3ff;
collision = (word >> 10) & 0x3;
elevation = (word >> 12) & 0xf;
}
Block::Block(const Block &block) {
tile = block.tile;
collision = block.collision;
elevation = block.elevation;
}
uint16_t Block::rawValue() {
return (tile & 0x3ff) + ((collision & 0x3) << 10) + ((elevation & 0xf) << 12);
}
bool Block::operator ==(Block other) {
return (tile == other.tile) && (collision == other.collision) && (elevation == other.elevation);
}
bool Block::operator !=(Block other) {
return !(operator ==(other));
}

20
block.h Executable file
View file

@ -0,0 +1,20 @@
#ifndef BLOCK_H
#define BLOCK_H
#include <QObject>
class Block
{
public:
Block();
Block(uint16_t);
Block(const Block&);
bool operator ==(Block);
bool operator !=(Block);
uint16_t tile:10;
uint16_t collision:2;
uint16_t elevation:4;
uint16_t rawValue();
};
#endif // BLOCK_H

39
blockdata.cpp Executable file
View file

@ -0,0 +1,39 @@
#include "blockdata.h"
Blockdata::Blockdata(QObject *parent) : QObject(parent)
{
blocks = new QList<Block>;
}
void Blockdata::addBlock(uint16_t word) {
Block block(word);
blocks->append(block);
}
void Blockdata::addBlock(Block block) {
blocks->append(block);
}
QByteArray Blockdata::serialize() {
QByteArray data;
for (int i = 0; i < blocks->length(); i++) {
Block block = blocks->value(i);
uint16_t word = block.rawValue();
data.append(word & 0xff);
data.append((word >> 8) & 0xff);
}
return data;
}
void Blockdata::copyFrom(Blockdata* other) {
blocks->clear();
for (int i = 0; i < other->blocks->length(); i++) {
addBlock(other->blocks->value(i));
}
}
Blockdata* Blockdata::copy() {
Blockdata* blockdata = new Blockdata;
blockdata->copyFrom(this);
return blockdata;
}

28
blockdata.h Executable file
View file

@ -0,0 +1,28 @@
#ifndef BLOCKDATA_H
#define BLOCKDATA_H
#include "block.h"
#include <QObject>
#include <QByteArray>
class Blockdata : public QObject
{
Q_OBJECT
public:
explicit Blockdata(QObject *parent = 0);
public:
QList<Block> *blocks;
void addBlock(uint16_t);
void addBlock(Block);
QByteArray serialize();
void copyFrom(Blockdata*);
Blockdata* copy();
signals:
public slots:
};
#endif // BLOCKDATA_H

324
editor.cpp Executable file
View file

@ -0,0 +1,324 @@
#include "editor.h"
Editor::Editor()
{
}
void Editor::saveProject() {
if (project) {
project->saveAllMaps();
}
}
void Editor::save() {
if (project && map) {
project->saveMap(map);
}
}
void Editor::undo() {
if (current_view) {
((MapPixmapItem*)current_view)->undo();
}
}
void Editor::redo() {
if (current_view) {
((MapPixmapItem*)current_view)->redo();
}
}
void Editor::setEditingMap() {
current_view = map_item;
map_item->draw();
map_item->setVisible(true);
map_item->setEnabled(true);
collision_item->setVisible(false);
objects_group->setVisible(false);
}
void Editor::setEditingCollision() {
current_view = collision_item;
collision_item->draw();
collision_item->setVisible(true);
map_item->setVisible(false);
objects_group->setVisible(false);
}
void Editor::setEditingObjects() {
objects_group->setVisible(true);
map_item->setVisible(true);
map_item->setEnabled(false);
collision_item->setVisible(false);
}
void Editor::setMap(QString map_name) {
if (map_name.isNull()) {
return;
}
map = project->getMap(map_name);
displayMap();
}
void Editor::displayMap() {
scene = new QGraphicsScene;
map_item = new MapPixmapItem(map);
map_item->draw();
scene->addItem(map_item);
collision_item = new CollisionPixmapItem(map);
collision_item->draw();
scene->addItem(collision_item);
objects_group = new QGraphicsItemGroup;
scene->addItem(objects_group);
map_item->setVisible(false);
collision_item->setVisible(false);
objects_group->setVisible(false);
int tw = 16;
int th = 16;
scene->setSceneRect(
-6 * tw,
-6 * th,
map_item->pixmap().width() + 12 * tw,
map_item->pixmap().height() + 12 * th
);
displayMetatiles();
displayCollisionMetatiles();
displayElevationMetatiles();
displayMapObjects();
displayMapConnections();
displayMapBorder();
}
void Editor::displayMetatiles() {
scene_metatiles = new QGraphicsScene;
metatiles_item = new MetatilesPixmapItem(map);
metatiles_item->draw();
scene_metatiles->addItem(metatiles_item);
}
void Editor::displayCollisionMetatiles() {
scene_collision_metatiles = new QGraphicsScene;
collision_metatiles_item = new CollisionMetatilesPixmapItem(map);
collision_metatiles_item->draw();
scene_collision_metatiles->addItem(collision_metatiles_item);
}
void Editor::displayElevationMetatiles() {
scene_elevation_metatiles = new QGraphicsScene;
elevation_metatiles_item = new ElevationMetatilesPixmapItem(map);
elevation_metatiles_item->draw();
scene_elevation_metatiles->addItem(elevation_metatiles_item);
}
void Editor::displayMapObjects() {
for (QGraphicsItem *child : objects_group->childItems()) {
objects_group->removeFromGroup(child);
}
project->loadObjectPixmaps(map->object_events);
for (int i = 0; i < map->object_events.length(); i++) {
ObjectEvent *object_event = map->object_events.value(i);
DraggablePixmapItem *object = new DraggablePixmapItem(object_event);
objects_group->addToGroup(object);
}
objects_group->setFiltersChildEvents(false);
}
void Editor::displayMapConnections() {
for (Connection *connection : map->connections) {
if (connection->direction == "dive" || connection->direction == "emerge") {
continue;
}
Map *connected_map = project->getMap(connection->map_name);
QPixmap pixmap = connected_map->renderConnection(*connection);
int offset = connection->offset.toInt(nullptr, 0);
int x, y;
if (connection->direction == "up") {
x = offset * 16;
y = -pixmap.height();
} else if (connection->direction == "down") {
x = offset * 16;
y = map->getHeight() * 16;
} else if (connection->direction == "left") {
x = -pixmap.width();
y = offset * 16;
} else if (connection->direction == "right") {
x = map->getWidth() * 16;
y = offset * 16;
}
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
item->setX(x);
item->setY(y);
scene->addItem(item);
}
}
void Editor::displayMapBorder() {
QPixmap pixmap = map->renderBorder();
for (int y = -6; y < map->getHeight() + 6; y += 2)
for (int x = -6; x < map->getWidth() + 6; x += 2) {
QGraphicsPixmapItem *item = new QGraphicsPixmapItem(pixmap);
item->setX(x * 16);
item->setY(y * 16);
item->setZValue(-1);
scene->addItem(item);
}
}
void MetatilesPixmapItem::draw() {
setPixmap(map->renderMetatiles());
}
void MetatilesPixmapItem::pick(uint tile) {
map->paint_tile = tile;
draw();
}
void MetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
QPointF pos = event->pos();
int x = ((int)pos.x()) / 16;
int y = ((int)pos.y()) / 16;
//qDebug() << QString("(%1, %2)").arg(x).arg(y);
int width = pixmap().width() / 16;
int height = pixmap().height() / 16;
if ((x >= 0 && x < width) && (y >=0 && y < height)) {
pick(y * width + x);
}
}
void MetatilesPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
mousePressEvent(event);
}
void MapPixmapItem::paint(QGraphicsSceneMouseEvent *event) {
if (map) {
QPointF pos = event->pos();
int x = (int)(pos.x()) / 16;
int y = (int)(pos.y()) / 16;
Block *block = map->getBlock(x, y);
if (block) {
block->tile = map->paint_tile;
map->setBlock(x, y, *block);
}
draw();
}
}
void MapPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) {
if (map) {
QPointF pos = event->pos();
int x = (int)(pos.x()) / 16;
int y = (int)(pos.y()) / 16;
map->floodFill(x, y, map->paint_tile);
draw();
}
}
void MapPixmapItem::draw() {
setPixmap(map->render());
}
void MapPixmapItem::undo() {
map->undo();
draw();
}
void MapPixmapItem::redo() {
map->redo();
draw();
}
void MapPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
active = true;
if (event->button() == Qt::RightButton) {
right_click = true;
floodFill(event);
} else {
right_click = false;
paint(event);
}
}
void MapPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
if (active) {
if (right_click) {
floodFill(event);
} else {
paint(event);
}
}
}
void MapPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
active = false;
}
void CollisionPixmapItem::draw() {
setPixmap(map->renderCollision());
}
void CollisionPixmapItem::paint(QGraphicsSceneMouseEvent *event) {
if (map) {
QPointF pos = event->pos();
int x = (int)(pos.x()) / 16;
int y = (int)(pos.y()) / 16;
Block *block = map->getBlock(x, y);
if (block) {
if (map->paint_collision >= 0) {
block->collision = map->paint_collision;
}
if (map->paint_elevation >= 0) {
block->elevation = map->paint_elevation;
}
map->setBlock(x, y, *block);
}
draw();
}
}
void CollisionPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) {
if (map) {
QPointF pos = event->pos();
int x = (int)(pos.x()) / 16;
int y = (int)(pos.y()) / 16;
bool collision = map->paint_collision >= 0;
bool elevation = map->paint_elevation >= 0;
if (collision && elevation) {
map->floodFillCollisionElevation(x, y, map->paint_collision, map->paint_elevation);
} else if (collision) {
map->floodFillCollision(x, y, map->paint_collision);
} else if (elevation) {
map->floodFillElevation(x, y, map->paint_elevation);
}
draw();
}
}
void DraggablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) {
active = true;
last_x = mouse->pos().x() / 16;
last_y = mouse->pos().y() / 16;
qDebug() << event->x_ + ", " + event->y_;
}
void DraggablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouse) {
if (active) {
int x = mouse->pos().x() / 16;
int y = mouse->pos().y() / 16;
if (x != last_x || y != last_y) {
event->setX(event->x() + x - last_x);
event->setY(event->y() + y - last_y);
update();
}
}
}
void DraggablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouse) {
active = false;
}

155
editor.h Executable file
View file

@ -0,0 +1,155 @@
#ifndef EDITOR_H
#define EDITOR_H
#include <QGraphicsScene>
#include <QGraphicsItemGroup>
#include <QGraphicsSceneMouseEvent>
#include "project.h"
class DraggablePixmapItem : public QGraphicsPixmapItem {
public:
DraggablePixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) {
}
Event *event;
DraggablePixmapItem(Event *event_) : QGraphicsPixmapItem(event_->pixmap) {
event = event_;
update();
}
bool active;
bool right_click;
int last_x;
int last_y;
void update() {
int x = event->x() * 16;
int y = event->y() * 16;
x -= pixmap().width() / 32 * 16;
y -= pixmap().height() - 16;
setX(x);
setY(y);
setZValue(event->y());
}
protected:
void mousePressEvent(QGraphicsSceneMouseEvent*);
void mouseMoveEvent(QGraphicsSceneMouseEvent*);
void mouseReleaseEvent(QGraphicsSceneMouseEvent*);
};
class MapPixmapItem : public QGraphicsPixmapItem {
public:
MapPixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) {
}
Map *map;
MapPixmapItem(Map *map_) {
map = map_;
}
bool active;
bool right_click;
virtual void paint(QGraphicsSceneMouseEvent*);
virtual void floodFill(QGraphicsSceneMouseEvent*);
virtual void undo();
virtual void redo();
virtual void draw();
protected:
void mousePressEvent(QGraphicsSceneMouseEvent*);
void mouseMoveEvent(QGraphicsSceneMouseEvent*);
void mouseReleaseEvent(QGraphicsSceneMouseEvent*);
};
class CollisionPixmapItem : public MapPixmapItem {
public:
CollisionPixmapItem(QPixmap pixmap): MapPixmapItem(pixmap) {
}
CollisionPixmapItem(Map *map_): MapPixmapItem(map_) {
}
public:
virtual void paint(QGraphicsSceneMouseEvent*);
virtual void floodFill(QGraphicsSceneMouseEvent*);
virtual void draw();
};
class MetatilesPixmapItem : public QGraphicsPixmapItem {
public:
MetatilesPixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) {
}
MetatilesPixmapItem(Map *map_) {
map = map_;
}
Map* map;
virtual void pick(uint);
virtual void draw();
protected:
void mousePressEvent(QGraphicsSceneMouseEvent*);
void mouseReleaseEvent(QGraphicsSceneMouseEvent*);
};
class CollisionMetatilesPixmapItem : public MetatilesPixmapItem {
public:
CollisionMetatilesPixmapItem(Map *map_): MetatilesPixmapItem(map_) {
}
virtual void pick(uint collision) {
map->paint_collision = collision;
draw();
}
virtual void draw() {
setPixmap(map->renderCollisionMetatiles());
}
};
class ElevationMetatilesPixmapItem : public MetatilesPixmapItem {
public:
ElevationMetatilesPixmapItem(Map *map_): MetatilesPixmapItem(map_) {
}
virtual void pick(uint elevation) {
map->paint_elevation = elevation;
draw();
}
virtual void draw() {
setPixmap(map->renderElevationMetatiles());
}
};
class Editor
{
public:
Editor();
public:
Project *project;
Map *map;
void saveProject();
void save();
void undo();
void redo();
void setMap(QString map_name);
void displayMap();
void displayMetatiles();
void displayCollisionMetatiles();
void displayElevationMetatiles();
void displayMapObjects();
void displayMapConnections();
void displayMapBorder();
void setEditingMap();
void setEditingCollision();
void setEditingObjects();
QGraphicsScene *scene;
QGraphicsPixmapItem *current_view;
MapPixmapItem *map_item;
CollisionPixmapItem *collision_item;
QGraphicsItemGroup *objects_group;
QGraphicsScene *scene_metatiles;
QGraphicsScene *scene_collision_metatiles;
QGraphicsScene *scene_elevation_metatiles;
MetatilesPixmapItem *metatiles_item;
CollisionMetatilesPixmapItem *collision_metatiles_item;
ElevationMetatilesPixmapItem *elevation_metatiles_item;
};
#endif // EDITOR_H

52
event.cpp Executable file
View file

@ -0,0 +1,52 @@
#include "event.h"
Event::Event()
{
}
ObjectEvent::ObjectEvent()
{
}
Warp::Warp()
{
}
CoordEvent::CoordEvent()
{
}
BGEvent::BGEvent()
{
}
Sign::Sign()
{
}
Sign::Sign(const BGEvent &bg)
{
x_ = bg.x_;
y_ = bg.y_;
elevation_ = bg.elevation_;
type = bg.type;
}
HiddenItem::HiddenItem()
{
}
HiddenItem::HiddenItem(const BGEvent &bg)
{
x_ = bg.x_;
y_ = bg.y_;
elevation_ = bg.elevation_;
type = bg.type;
}

100
event.h Executable file
View file

@ -0,0 +1,100 @@
#ifndef EVENT_H
#define EVENT_H
#include <QString>
#include <QPixmap>
class Event
{
public:
Event();
public:
int x() {
return x_.toInt(nullptr, 0);
}
int y() {
return y_.toInt(nullptr, 0);
}
int elevation() {
return elevation_.toInt(nullptr, 0);
}
void setX(int x) {
x_ = QString("%1").arg(x);
}
void setY(int y) {
y_ = QString("%1").arg(y);
}
QString x_;
QString y_;
QString elevation_;
QPixmap pixmap;
};
class ObjectEvent : public Event {
public:
ObjectEvent();
public:
QString sprite;
QString replacement; // ????
QString behavior;
QString radius_x;
QString radius_y;
QString property;
QString sight_radius;
QString script_label;
QString event_flag;
};
class Warp : public Event {
public:
Warp();
public:
QString destination_warp;
QString destination_map;
};
class CoordEvent : public Event {
public:
CoordEvent();
public:
QString unknown1;
QString unknown2;
QString unknown3;
QString unknown4;
QString script_label;
};
class BGEvent : public Event {
public:
BGEvent();
public:
bool is_item() {
return type.toInt(nullptr, 0) >= 5;
}
QString type;
};
class Sign : public BGEvent {
public:
Sign();
Sign(const BGEvent&);
public:
QString script_label;
};
class HiddenItem : public BGEvent {
public:
HiddenItem();
HiddenItem(const BGEvent&);
public:
QString item;
QString unknown5;
QString unknown6;
};
#endif // EVENT_H

11
main.cpp Executable file
View file

@ -0,0 +1,11 @@
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

370
mainwindow.cpp Executable file
View file

@ -0,0 +1,370 @@
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "project.h"
#include <QDebug>
#include <QFileDialog>
#include <QStandardItemModel>
#include <QShortcut>
#include <QSettings>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
QCoreApplication::setOrganizationName("pret");
QCoreApplication::setApplicationName("pretmap");
editor = new Editor;
new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z), this, SLOT(redo()));
ui->setupUi(this);
QSettings settings;
QString key = "recent_projects";
if (settings.contains(key)) {
QString default_dir = settings.value(key).toStringList().last();
openProject(default_dir);
}
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::openProject(QString dir) {
bool already_open = (editor->project != NULL) && (editor->project->root == dir);
if (!already_open) {
editor->project = new Project;
editor->project->root = dir;
populateMapList();
setMap(getDefaultMap());
} else {
populateMapList();
}
}
QString MainWindow::getDefaultMap() {
QSettings settings;
QString key = "project:" + editor->project->root;
if (settings.contains(key)) {
QMap<QString, QVariant> qmap = settings.value(key).toMap();
if (qmap.contains("recent_map")) {
QString map_name = qmap.value("recent_map").toString();
return map_name;
}
}
// Failing that, just get the first map in the list.
for (int i = 0; i < editor->project->groupedMapNames->length(); i++) {
QStringList *list = editor->project->groupedMapNames->value(i);
if (list->length()) {
return list->value(0);
}
}
return NULL;
}
QString MainWindow::getExistingDirectory(QString dir) {
return QFileDialog::getExistingDirectory(this, "Open Directory", dir, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
}
void MainWindow::on_action_Open_Project_triggered()
{
QSettings settings;
QString key = "recent_projects";
QString recent = ".";
if (settings.contains(key)) {
recent = settings.value(key).toStringList().last();
}
QString dir = getExistingDirectory(recent);
if (!dir.isEmpty()) {
QStringList recents;
if (settings.contains(key)) {
recents = settings.value(key).toStringList();
}
recents.removeAll(dir);
recents.append(dir);
settings.setValue(key, recents);
openProject(dir);
}
}
void MainWindow::setMap(QString map_name) {
if (map_name.isNull()) {
return;
}
editor->setMap(map_name);
if (ui->tabWidget->currentIndex() == 1) {
editor->setEditingObjects();
} else {
if (ui->tabWidget_2->currentIndex() == 1) {
editor->setEditingCollision();
} else {
editor->setEditingMap();
}
}
ui->graphicsView_Map->setScene(editor->scene);
ui->graphicsView_Map->setSceneRect(editor->scene->sceneRect());
ui->graphicsView_Map->setFixedSize(editor->scene->width() + 2, editor->scene->height() + 2);
ui->graphicsView_Objects_Map->setScene(editor->scene);
ui->graphicsView_Objects_Map->setSceneRect(editor->scene->sceneRect());
ui->graphicsView_Objects_Map->setFixedSize(editor->scene->width() + 2, editor->scene->height() + 2);
ui->graphicsView_Metatiles->setScene(editor->scene_metatiles);
//ui->graphicsView_Metatiles->setSceneRect(editor->scene_metatiles->sceneRect());
ui->graphicsView_Metatiles->setFixedSize(editor->metatiles_item->pixmap().width() + 2, editor->metatiles_item->pixmap().height() + 2);
ui->graphicsView_Collision->setScene(editor->scene_collision_metatiles);
//ui->graphicsView_Collision->setSceneRect(editor->scene_collision_metatiles->sceneRect());
ui->graphicsView_Collision->setFixedSize(editor->collision_metatiles_item->pixmap().width() + 2, editor->collision_metatiles_item->pixmap().height() + 2);
ui->graphicsView_Elevation->setScene(editor->scene_elevation_metatiles);
//ui->graphicsView_Elevation->setSceneRect(editor->scene_elevation_metatiles->sceneRect());
ui->graphicsView_Elevation->setFixedSize(editor->elevation_metatiles_item->pixmap().width() + 2, editor->elevation_metatiles_item->pixmap().height() + 2);
displayMapProperties();
setRecentMap(map_name);
updateMapList();
}
void MainWindow::setRecentMap(QString map_name) {
QSettings settings;
QString key = "project:" + editor->project->root;
QMap<QString, QVariant> qmap;
if (settings.contains(key)) {
qmap = settings.value(key).toMap();
}
qmap.insert("recent_map", map_name);
settings.setValue(key, qmap);
}
void MainWindow::displayMapProperties() {
Map *map = editor->map;
Project *project = editor->project;
QStringList songs = project->getSongNames();
ui->comboBox_Song->clear();
ui->comboBox_Song->addItems(songs);
QString song = map->song;
if (!songs.contains(song)) {
song = project->getSongName(song.toInt());
}
ui->comboBox_Song->setCurrentText(song);
ui->comboBox_Location->clear();
ui->comboBox_Location->addItems(project->getLocations());
ui->comboBox_Location->setCurrentText(map->location);
ui->comboBox_Visibility->clear();
ui->comboBox_Visibility->addItems(project->getVisibilities());
ui->comboBox_Visibility->setCurrentText(map->visibility);
ui->comboBox_Weather->clear();
ui->comboBox_Weather->addItems(project->getWeathers());
ui->comboBox_Weather->setCurrentText(map->weather);
ui->comboBox_Type->clear();
ui->comboBox_Type->addItems(project->getMapTypes());
ui->comboBox_Type->setCurrentText(map->type);
ui->comboBox_BattleScene->clear();
ui->comboBox_BattleScene->addItems(project->getBattleScenes());
ui->comboBox_BattleScene->setCurrentText(map->battle_scene);
ui->checkBox_ShowLocation->setChecked(map->show_location.toInt() > 0 || map->show_location == "TRUE");
}
void MainWindow::on_comboBox_Song_activated(const QString &song)
{
editor->map->song = song;
}
void MainWindow::on_comboBox_Location_activated(const QString &location)
{
editor->map->location = location;
}
void MainWindow::on_comboBox_Visibility_activated(const QString &visibility)
{
editor->map->visibility = visibility;
}
void MainWindow::on_comboBox_Weather_activated(const QString &weather)
{
editor->map->weather = weather;
}
void MainWindow::on_comboBox_Type_activated(const QString &type)
{
editor->map->type = type;
}
void MainWindow::on_comboBox_BattleScene_activated(const QString &battle_scene)
{
editor->map->battle_scene = battle_scene;
}
void MainWindow::on_checkBox_ShowLocation_clicked(bool checked)
{
if (checked) {
editor->map->show_location = "TRUE";
} else {
editor->map->show_location = "FALSE";
}
}
void MainWindow::populateMapList() {
Project *project = editor->project;
QIcon mapFolderIcon;
mapFolderIcon.addFile(QStringLiteral(":/icons/folder_closed_map.ico"), QSize(), QIcon::Normal, QIcon::Off);
mapFolderIcon.addFile(QStringLiteral(":/icons/folder_map.ico"), QSize(), QIcon::Normal, QIcon::On);
QIcon folderIcon;
folderIcon.addFile(QStringLiteral(":/icons/folder_closed.ico"), QSize(), QIcon::Normal, QIcon::Off);
QIcon mapIcon;
mapIcon.addFile(QStringLiteral(":/icons/map.ico"), QSize(), QIcon::Normal, QIcon::Off);
mapIcon.addFile(QStringLiteral(":/icons/image.ico"), QSize(), QIcon::Normal, QIcon::On);
QStandardItemModel *model = new QStandardItemModel;
QStandardItem *entry = new QStandardItem;
entry->setText(project->getProjectTitle());
entry->setIcon(folderIcon);
entry->setEditable(false);
model->appendRow(entry);
QStandardItem *maps = new QStandardItem;
maps->setText("maps");
maps->setIcon(folderIcon);
maps->setEditable(false);
entry->appendRow(maps);
project->readMapGroups();
for (int i = 0; i < project->groupNames->length(); i++) {
QString group_name = project->groupNames->value(i);
QStandardItem *group = new QStandardItem;
group->setText(group_name);
group->setIcon(mapFolderIcon);
group->setEditable(false);
maps->appendRow(group);
QStringList *names = project->groupedMapNames->value(i);
for (int j = 0; j < names->length(); j++) {
QString map_name = names->value(j);
QStandardItem *map = new QStandardItem;
map->setText(QString("[%1.%2] ").arg(i).arg(j, 2, 10, QLatin1Char('0')) + map_name);
map->setIcon(mapIcon);
map->setEditable(false);
map->setData(map_name, Qt::UserRole);
group->appendRow(map);
//ui->mapList->setExpanded(model->indexFromItem(map), false); // redundant
}
}
ui->mapList->setModel(model);
ui->mapList->setUpdatesEnabled(true);
ui->mapList->expandToDepth(2);
ui->mapList->repaint();
}
void MainWindow::on_mapList_activated(const QModelIndex &index)
{
QVariant data = index.data(Qt::UserRole);
if (!data.isNull()) {
setMap(data.toString());
}
updateMapList();
}
void MainWindow::markAllEdited(QAbstractItemModel *model) {
QList<QModelIndex> list;
list.append(QModelIndex());
while (list.length()) {
QModelIndex parent = list.takeFirst();
for (int i = 0; i < model->rowCount(parent); i++) {
QModelIndex index = model->index(i, 0, parent);
if (model->hasChildren(index)) {
list.append(index);
}
markEdited(index);
}
}
}
void MainWindow::markEdited(QModelIndex index) {
QVariant data = index.data(Qt::UserRole);
if (!data.isNull()) {
QString map_name = data.toString();
if (editor->project) {
if (editor->project->map_cache->contains(map_name)) {
// Just mark anything that's been opened for now.
// TODO if (project->getMap()->saved)
ui->mapList->setExpanded(index, true);
}
}
}
}
void MainWindow::updateMapList() {
QAbstractItemModel *model = ui->mapList->model();
markAllEdited(model);
}
void MainWindow::on_action_Save_Project_triggered()
{
editor->saveProject();
updateMapList();
}
void MainWindow::undo() {
editor->undo();
}
void MainWindow::redo() {
editor->redo();
}
void MainWindow::on_action_Save_triggered() {
editor->save();
}
void MainWindow::on_tabWidget_2_currentChanged(int index)
{
if (index == 0) {
editor->setEditingMap();
} else if (index == 1) {
editor->setEditingCollision();
}
}
void MainWindow::on_action_Exit_triggered()
{
QApplication::quit();
}
void MainWindow::on_tabWidget_currentChanged(int index)
{
if (index == 0) {
on_tabWidget_2_currentChanged(ui->tabWidget_2->currentIndex());
} else if (index == 1) {
editor->setEditingObjects();
}
}
void MainWindow::on_actionUndo_triggered()
{
undo();
}
void MainWindow::on_actionRedo_triggered()
{
redo();
}

69
mainwindow.h Executable file
View file

@ -0,0 +1,69 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QString>
#include <QModelIndex>
#include <QMainWindow>
#include <QGraphicsPixmapItem>
#include <QGraphicsItemGroup>
#include <QGraphicsSceneMouseEvent>
#include <QAbstractItemModel>
#include "project.h"
#include "map.h"
#include "editor.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_action_Open_Project_triggered();
void on_mapList_activated(const QModelIndex &index);
void on_action_Save_Project_triggered();
void undo();
void redo();
void on_action_Save_triggered();
void on_tabWidget_2_currentChanged(int index);
void on_action_Exit_triggered();
void on_comboBox_Song_activated(const QString &arg1);
void on_comboBox_Location_activated(const QString &arg1);
void on_comboBox_Visibility_activated(const QString &arg1);
void on_comboBox_Weather_activated(const QString &arg1);
void on_comboBox_Type_activated(const QString &arg1);
void on_comboBox_BattleScene_activated(const QString &arg1);
void on_checkBox_ShowLocation_clicked(bool checked);
void on_tabWidget_currentChanged(int index);
void on_actionUndo_triggered();
void on_actionRedo_triggered();
private:
Ui::MainWindow *ui;
Editor *editor;
void setMap(QString);
void populateMapList();
QString getExistingDirectory(QString);
void openProject(QString dir);
QString getDefaultMap();
void setRecentMap(QString map_name);
void markAllEdited(QAbstractItemModel *model);
void markEdited(QModelIndex index);
void updateMapList();
void displayMapProperties();
};
#endif // MAINWINDOW_H

938
mainwindow.ui Executable file
View file

@ -0,0 +1,938 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1019</width>
<height>666</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTreeView" name="mapList">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>0</height>
</size>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectItems</enum>
</property>
<attribute name="headerVisible">
<bool>false</bool>
</attribute>
</widget>
<widget class="QTabWidget" name="tabWidget">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="currentIndex">
<number>1</number>
</property>
<property name="tabsClosable">
<bool>false</bool>
</property>
<property name="movable">
<bool>false</bool>
</property>
<widget class="QWidget" name="tab_Map">
<attribute name="icon">
<iconset resource="resources/images.qrc">
<normaloff>:/icons/map.ico</normaloff>:/icons/map.ico</iconset>
</attribute>
<attribute name="title">
<string>Map</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QSplitter" name="splitter_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QScrollArea" name="scrollArea">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>571</width>
<height>564</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="1" column="0">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>166</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>16</width>
<height>166</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>166</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>16</width>
<height>166</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QGraphicsView" name="graphicsView_Map">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QTabWidget" name="tabWidget_2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>156</width>
<height>0</height>
</size>
</property>
<property name="currentIndex">
<number>1</number>
</property>
<widget class="QWidget" name="tab_blocks">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<attribute name="title">
<string>Blocks</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QScrollArea" name="scrollArea_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAsNeeded</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>81</width>
<height>28</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout_5" rowstretch="0" columnstretch="0">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QGraphicsView" name="graphicsView_Metatiles">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_collision">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<attribute name="title">
<string>Collision</string>
</attribute>
<widget class="Line" name="line">
<property name="geometry">
<rect>
<x>20</x>
<y>60</y>
<width>111</width>
<height>20</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>0</x>
<y>80</y>
<width>151</width>
<height>101</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>47</width>
<height>13</height>
</rect>
</property>
<property name="text">
<string>Elevation</string>
</property>
</widget>
<widget class="QGraphicsView" name="graphicsView_Elevation">
<property name="geometry">
<rect>
<x>10</x>
<y>30</y>
<width>131</width>
<height>61</height>
</rect>
</property>
</widget>
</widget>
<widget class="QFrame" name="frame_2">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>151</width>
<height>61</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>47</width>
<height>13</height>
</rect>
</property>
<property name="text">
<string>Collision</string>
</property>
</widget>
<widget class="QGraphicsView" name="graphicsView_Collision">
<property name="geometry">
<rect>
<x>40</x>
<y>30</y>
<width>66</width>
<height>18</height>
</rect>
</property>
</widget>
</widget>
</widget>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_Objects">
<property name="enabled">
<bool>true</bool>
</property>
<attribute name="title">
<string>Objects</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_10">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QSplitter" name="splitter_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QScrollArea" name="scrollArea_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents_4">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>571</width>
<height>564</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="1" column="2">
<spacer name="horizontalSpacer_6">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>166</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>166</width>
<height>16</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>16</width>
<height>166</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>16</width>
<height>166</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QGraphicsView" name="graphicsView_Objects_Map">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QFrame" name="frame_3">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>156</width>
<height>0</height>
</size>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Selected</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QFrame" name="frame_4">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>32</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QToolButton" name="toolButton">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>31</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>New</string>
</property>
</widget>
<widget class="QToolButton" name="toolButton_2">
<property name="geometry">
<rect>
<x>100</x>
<y>0</y>
<width>31</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Delete</string>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_Attributes">
<attribute name="title">
<string>Attributes</string>
</attribute>
<widget class="QFrame" name="frame_3">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>301</width>
<height>251</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>47</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Song</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>20</x>
<y>60</y>
<width>47</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Location</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>20</x>
<y>90</y>
<width>47</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Visibility</string>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>20</x>
<y>120</y>
<width>47</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Weather</string>
</property>
</widget>
<widget class="QLabel" name="label_7">
<property name="geometry">
<rect>
<x>20</x>
<y>150</y>
<width>47</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Type</string>
</property>
</widget>
<widget class="QLabel" name="label_8">
<property name="geometry">
<rect>
<x>20</x>
<y>180</y>
<width>101</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Show location name</string>
</property>
</widget>
<widget class="QLabel" name="label_9">
<property name="geometry">
<rect>
<x>20</x>
<y>210</y>
<width>81</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string>Battle scene</string>
</property>
</widget>
<widget class="QComboBox" name="comboBox_Location">
<property name="geometry">
<rect>
<x>80</x>
<y>60</y>
<width>211</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="comboBox_Visibility">
<property name="geometry">
<rect>
<x>80</x>
<y>90</y>
<width>211</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="comboBox_Song">
<property name="geometry">
<rect>
<x>80</x>
<y>30</y>
<width>211</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="comboBox_Weather">
<property name="geometry">
<rect>
<x>80</x>
<y>120</y>
<width>211</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="comboBox_Type">
<property name="geometry">
<rect>
<x>80</x>
<y>150</y>
<width>211</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="comboBox_BattleScene">
<property name="geometry">
<rect>
<x>90</x>
<y>210</y>
<width>201</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QCheckBox" name="checkBox_ShowLocation">
<property name="geometry">
<rect>
<x>130</x>
<y>180</y>
<width>161</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_10">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>47</width>
<height>13</height>
</rect>
</property>
<property name="text">
<string>Header</string>
</property>
</widget>
</widget>
</widget>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1019</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuFile">
<property name="title">
<string>File</string>
</property>
<addaction name="action_Open_Project"/>
<addaction name="action_Save"/>
<addaction name="action_Save_Project"/>
<addaction name="separator"/>
<addaction name="action_Exit"/>
</widget>
<widget class="QMenu" name="menuEdit">
<property name="title">
<string>Edit</string>
</property>
<addaction name="actionUndo"/>
<addaction name="actionRedo"/>
</widget>
<addaction name="menuFile"/>
<addaction name="menuEdit"/>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
<action name="action_Save_Project">
<property name="text">
<string>Save All</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+S</string>
</property>
</action>
<action name="action_Exit">
<property name="text">
<string>Exit</string>
</property>
<property name="shortcut">
<string>Ctrl+Q</string>
</property>
</action>
<action name="action_Open_Project">
<property name="text">
<string>Open Project...</string>
</property>
<property name="shortcut">
<string>Ctrl+O</string>
</property>
</action>
<action name="action_Save">
<property name="text">
<string>Save</string>
</property>
<property name="shortcut">
<string>Ctrl+S</string>
</property>
</action>
<action name="actionUndo">
<property name="text">
<string>Undo</string>
</property>
<property name="shortcut">
<string>Ctrl+Z</string>
</property>
</action>
<action name="actionRedo">
<property name="text">
<string>Redo</string>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="shortcut">
<string>Ctrl+Y</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="resources/images.qrc"/>
</resources>
<connections/>
</ui>

600
map.cpp Executable file
View file

@ -0,0 +1,600 @@
#include "map.h"
#include <QTime>
#include <QDebug>
#include <QPainter>
Map::Map(QObject *parent) : QObject(parent)
{
cached_blockdata = new Blockdata;
cached_collision = new Blockdata;
cached_border = new Blockdata;
paint_tile = 1;
paint_collision = 0;
paint_elevation = 3;
}
int Map::getWidth() {
return width.toInt(nullptr, 0);
}
int Map::getHeight() {
return height.toInt(nullptr, 0);
}
Tileset* Map::getBlockTileset(uint metatile_index) {
uint primary_size = 0x200;//tileset_primary->metatiles->length();
if (metatile_index < primary_size) {
return tileset_primary;
} else {
return tileset_secondary;
}
}
QImage Map::getMetatileTile(uint tile) {
uint primary_size = 0x200;//tileset_primary->metatiles->length();
if (tile < primary_size) {
return tileset_primary->tiles->value(tile);
} else {
return tileset_secondary->tiles->value(tile - primary_size);
}
}
Metatile* Map::getMetatile(uint index) {
uint primary_size = 0x200;//tileset_primary->metatiles->length();
if (index < primary_size) {
return tileset_primary->metatiles->value(index);
} else {
//qDebug() << QString("secondary tileset: %1").arg(index - primary_size, 0, 16);
return tileset_secondary->metatiles->value(index - primary_size);
}
}
QImage Map::getCollisionMetatileImage(Block block) {
return getCollisionMetatileImage(block.collision);
}
QImage Map::getCollisionMetatileImage(int collision) {
QImage metatile_image(16, 16, QImage::Format_RGBA8888);
QColor color;
if (collision == 0) {
color.setGreen(0xff);
} else if (collision == 1) {
color.setRed(0xff);
} else if (collision == 2) {
color.setBlue(0xff);
} else if (collision == 3) {
// black
}
metatile_image.fill(color);
return metatile_image;
}
QImage Map::getElevationMetatileImage(Block block) {
return getElevationMetatileImage(block.elevation);
}
QImage Map::getElevationMetatileImage(int elevation) {
QImage metatile_image(16, 16, QImage::Format_RGBA8888);
QColor color;
if (elevation < 15) {
uint saturation = (elevation + 1) * 16 + 15;
color.setGreen(saturation);
color.setRed(saturation);
color.setBlue(saturation);
} else {
color.setGreen(0xd0);
color.setBlue(0xd0);
color.setRed(0);
}
metatile_image.fill(color);
//QPainter painter(&metatile_image);
//painter.end();
return metatile_image;
}
QImage Map::getMetatileImage(uint tile) {
QImage metatile_image(16, 16, QImage::Format_RGBA8888);
Metatile* metatile = getMetatile(tile);
if (metatile == NULL) {
metatile_image.fill(0xffffffff);
return metatile_image;
}
Tileset* blockTileset = getBlockTileset(tile);
for (int layer = 0; layer < 2; layer++)
for (int y = 0; y < 2; y++)
for (int x = 0; x < 2; x++) {
//qDebug() << QString("x=%1 y=%2 layer=%3").arg(x).arg(y).arg(layer);
Tile tile = metatile->tiles->value((y * 2) + x + (layer * 4));
QImage tile_image = getMetatileTile(tile.tile);
QList<QRgb> palette = blockTileset->palettes->value(tile.palette);
for (int j = 0; j < palette.length(); j++) {
tile_image.setColor(j, palette.value(j));
}
//QVector<QRgb> vector = palette.toVector();
//tile_image.setColorTable(vector);
if (layer > 0) {
QColor color(tile_image.color(15));
color.setAlpha(0);
tile_image.setColor(15, color.rgba());
}
QPainter metatile_painter(&metatile_image);
QPoint origin = QPoint(x*8, y*8);
metatile_painter.drawImage(origin, tile_image.mirrored(tile.xflip == 1, tile.yflip == 1));
metatile_painter.end();
}
return metatile_image;
}
bool Map::blockChanged(int i, Blockdata *cache) {
if (cache->blocks->length() <= i) {
return true;
}
return blockdata->blocks->value(i) != cache->blocks->value(i);
}
void Map::cacheBorder() {
cached_border = new Blockdata;
for (int i = 0; i < border->blocks->length(); i++) {
Block block = border->blocks->value(i);
cached_border->blocks->append(block);
}
}
void Map::cacheBlockdata() {
cached_blockdata = new Blockdata;
for (int i = 0; i < blockdata->blocks->length(); i++) {
Block block = blockdata->blocks->value(i);
cached_blockdata->blocks->append(block);
}
}
void Map::cacheCollision() {
cached_collision = new Blockdata;
for (int i = 0; i < blockdata->blocks->length(); i++) {
Block block = blockdata->blocks->value(i);
cached_collision->blocks->append(block);
}
}
QPixmap Map::renderCollision() {
bool changed_any = false;
int width_ = getWidth();
int height_ = getHeight();
if (
collision_image.isNull()
|| collision_image.width() != width_ * 16
|| collision_image.height() != height_ * 16
) {
collision_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
changed_any = true;
}
QPainter painter(&collision_image);
for (int i = 0; i < blockdata->blocks->length(); i++) {
if (!blockChanged(i, cached_collision)) {
continue;
}
changed_any = true;
Block block = blockdata->blocks->value(i);
QImage metatile_image = getMetatileImage(block.tile);
QImage collision_metatile_image = getCollisionMetatileImage(block);
QImage elevation_metatile_image = getElevationMetatileImage(block);
int map_y = i / width_;
int map_x = i % width_;
QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);
painter.setOpacity(1);
painter.drawImage(metatile_origin, metatile_image);
painter.save();
if (block.elevation == 15) {
painter.setOpacity(0.5);
} else if (block.elevation == 0) {
painter.setOpacity(0);
} else {
painter.setOpacity(1);//(block.elevation / 16.0) * 0.8);
painter.setCompositionMode(QPainter::CompositionMode_Overlay);
}
painter.drawImage(metatile_origin, elevation_metatile_image);
painter.restore();
painter.save();
if (block.collision == 0) {
painter.setOpacity(0.1);
} else {
painter.setOpacity(0.4);
}
painter.drawImage(metatile_origin, collision_metatile_image);
painter.restore();
painter.save();
painter.setOpacity(0.6);
painter.setPen(QColor(255, 255, 255, 192));
painter.setFont(QFont("Helvetica", 8));
painter.drawText(QPoint(metatile_origin.x(), metatile_origin.y() + 8), QString("%1").arg(block.elevation));
painter.restore();
}
painter.end();
cacheCollision();
if (changed_any) {
collision_pixmap = collision_pixmap.fromImage(collision_image);
}
return collision_pixmap;
}
QPixmap Map::render() {
bool changed_any = false;
int width_ = getWidth();
int height_ = getHeight();
if (
image.isNull()
|| image.width() != width_ * 16
|| image.height() != height_ * 16
) {
image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
changed_any = true;
}
QPainter painter(&image);
for (int i = 0; i < blockdata->blocks->length(); i++) {
if (!blockChanged(i, cached_blockdata)) {
continue;
}
changed_any = true;
Block block = blockdata->blocks->value(i);
QImage metatile_image = getMetatileImage(block.tile);
int map_y = i / width_;
int map_x = i % width_;
QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);
painter.drawImage(metatile_origin, metatile_image);
}
painter.end();
if (changed_any) {
cacheBlockdata();
pixmap = pixmap.fromImage(image);
}
return pixmap;
}
QPixmap Map::renderBorder() {
bool changed_any = false;
int width_ = 2;
int height_ = 2;
if (border_image.isNull()) {
border_image = QImage(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
changed_any = true;
}
QPainter painter(&border_image);
for (int i = 0; i < border->blocks->length(); i++) {
if (!blockChanged(i, cached_border)) {
continue;
}
changed_any = true;
Block block = border->blocks->value(i);
QImage metatile_image = getMetatileImage(block.tile);
int map_y = i / width_;
int map_x = i % width_;
painter.drawImage(QPoint(map_x * 16, map_y * 16), metatile_image);
}
painter.end();
if (changed_any) {
cacheBorder();
border_pixmap = border_pixmap.fromImage(border_image);
}
return border_pixmap;
}
QPixmap Map::renderConnection(Connection connection) {
render();
int x, y, w, h;
if (connection.direction == "up") {
x = 0;
y = getHeight() - 6;
w = getWidth();
h = 6;
} else if (connection.direction == "down") {
x = 0;
y = 0;
w = getWidth();
h = 6;
} else if (connection.direction == "left") {
x = getWidth() - 6;
y = 0;
w = 6;
h = getHeight();
} else if (connection.direction == "right") {
x = 0;
y = 0;
w = 6;
h = getHeight();
} else {
// this should not happen
x = 0;
y = 0;
w = getWidth();
h = getHeight();
}
QImage connection_image = image.copy(x * 16, y * 16, w * 16, h * 16);
//connection_image = connection_image.convertToFormat(QImage::Format_Grayscale8);
return QPixmap::fromImage(connection_image);
}
QPixmap Map::renderCollisionMetatiles() {
int length_ = 4;
int height_ = 1;
int width_ = length_ / height_;
QImage image(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
QPainter painter(&image);
for (int i = 0; i < length_; i++) {
int y = i / width_;
int x = i % width_;
QPoint origin(x * 16, y * 16);
QImage metatile_image = getCollisionMetatileImage(i);
painter.drawImage(origin, metatile_image);
}
drawSelection(paint_collision, width_, &painter);
painter.end();
return QPixmap::fromImage(image);
}
QPixmap Map::renderElevationMetatiles() {
int length_ = 16;
int height_ = 2;
int width_ = length_ / height_;
QImage image(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
QPainter painter(&image);
for (int i = 0; i < length_; i++) {
int y = i / width_;
int x = i % width_;
QPoint origin(x * 16, y * 16);
QImage metatile_image = getElevationMetatileImage(i);
painter.drawImage(origin, metatile_image);
}
drawSelection(paint_elevation, width_, &painter);
painter.end();
return QPixmap::fromImage(image);
}
void Map::drawSelection(int i, int w, QPainter *painter) {
int x = i % w;
int y = i / w;
painter->save();
painter->setPen(QColor(0xff, 0xff, 0xff));
painter->drawRect(x * 16, y * 16, 15, 15);
painter->setPen(QColor(0, 0, 0));
painter->drawRect(x * 16 - 1, y * 16 - 1, 17, 17);
painter->drawRect(x * 16 + 1, y * 16 + 1, 13, 13);
painter->restore();
}
QPixmap Map::renderMetatiles() {
int primary_length = tileset_primary->metatiles->length();
int length_ = primary_length + tileset_secondary->metatiles->length();
int width_ = 8;
int height_ = length_ / width_;
QImage image(width_ * 16, height_ * 16, QImage::Format_RGBA8888);
QPainter painter(&image);
for (int i = 0; i < length_; i++) {
uint tile = i;
if (i >= primary_length) {
tile += 0x200 - primary_length;
}
QImage metatile_image = getMetatileImage(tile);
int map_y = i / width_;
int map_x = i % width_;
QPoint metatile_origin = QPoint(map_x * 16, map_y * 16);
painter.drawImage(metatile_origin, metatile_image);
}
drawSelection(paint_tile, width_, &painter);
painter.end();
return QPixmap::fromImage(image);
}
Block* Map::getBlock(int x, int y) {
if (x >= 0 && x < getWidth())
if (y >= 0 && y < getHeight()) {
int i = y * getWidth() + x;
return new Block(blockdata->blocks->value(i));
}
return NULL;
}
void Map::_setBlock(int x, int y, Block block) {
int i = y * getWidth() + x;
blockdata->blocks->replace(i, block);
}
void Map::_floodFill(int x, int y, uint tile) {
QList<QPoint> todo;
todo.append(QPoint(x, y));
while (todo.length()) {
QPoint point = todo.takeAt(0);
x = point.x();
y = point.y();
Block *block = getBlock(x, y);
if (block == NULL) {
continue;
}
uint old_tile = block->tile;
if (old_tile == tile) {
continue;
}
block->tile = tile;
_setBlock(x, y, *block);
if ((block = getBlock(x + 1, y)) && block->tile == old_tile) {
todo.append(QPoint(x + 1, y));
}
if ((block = getBlock(x - 1, y)) && block->tile == old_tile) {
todo.append(QPoint(x - 1, y));
}
if ((block = getBlock(x, y + 1)) && block->tile == old_tile) {
todo.append(QPoint(x, y + 1));
}
if ((block = getBlock(x, y - 1)) && block->tile == old_tile) {
todo.append(QPoint(x, y - 1));
}
}
}
void Map::_floodFillCollision(int x, int y, uint collision) {
QList<QPoint> todo;
todo.append(QPoint(x, y));
while (todo.length()) {
QPoint point = todo.takeAt(0);
x = point.x();
y = point.y();
Block *block = getBlock(x, y);
if (block == NULL) {
continue;
}
uint old_coll = block->collision;
if (old_coll == collision) {
continue;
}
block->collision = collision;
_setBlock(x, y, *block);
if ((block = getBlock(x + 1, y)) && block->collision == old_coll) {
todo.append(QPoint(x + 1, y));
}
if ((block = getBlock(x - 1, y)) && block->collision == old_coll) {
todo.append(QPoint(x - 1, y));
}
if ((block = getBlock(x, y + 1)) && block->collision == old_coll) {
todo.append(QPoint(x, y + 1));
}
if ((block = getBlock(x, y - 1)) && block->collision == old_coll) {
todo.append(QPoint(x, y - 1));
}
}
}
void Map::_floodFillElevation(int x, int y, uint elevation) {
QList<QPoint> todo;
todo.append(QPoint(x, y));
while (todo.length()) {
QPoint point = todo.takeAt(0);
x = point.x();
y = point.y();
Block *block = getBlock(x, y);
if (block == NULL) {
continue;
}
uint old_z = block->elevation;
if (old_z == elevation) {
continue;
}
Block block_(*block);
block_.elevation = elevation;
_setBlock(x, y, block_);
if ((block = getBlock(x + 1, y)) && block->elevation == old_z) {
todo.append(QPoint(x + 1, y));
}
if ((block = getBlock(x - 1, y)) && block->elevation == old_z) {
todo.append(QPoint(x - 1, y));
}
if ((block = getBlock(x, y + 1)) && block->elevation == old_z) {
todo.append(QPoint(x, y + 1));
}
if ((block = getBlock(x, y - 1)) && block->elevation == old_z) {
todo.append(QPoint(x, y - 1));
}
}
}
void Map::_floodFillCollisionElevation(int x, int y, uint collision, uint elevation) {
QList<QPoint> todo;
todo.append(QPoint(x, y));
while (todo.length()) {
QPoint point = todo.takeAt(0);
x = point.x();
y = point.y();
Block *block = getBlock(x, y);
if (block == NULL) {
continue;
}
uint old_coll = block->collision;
uint old_elev = block->elevation;
if (old_coll == collision && old_elev == elevation) {
continue;
}
block->collision = collision;
block->elevation = elevation;
_setBlock(x, y, *block);
if ((block = getBlock(x + 1, y)) && block->collision == old_coll && block->elevation == old_elev) {
todo.append(QPoint(x + 1, y));
}
if ((block = getBlock(x - 1, y)) && block->collision == old_coll && block->elevation == old_elev) {
todo.append(QPoint(x - 1, y));
}
if ((block = getBlock(x, y + 1)) && block->collision == old_coll && block->elevation == old_elev) {
todo.append(QPoint(x, y + 1));
}
if ((block = getBlock(x, y - 1)) && block->collision == old_coll && block->elevation == old_elev) {
todo.append(QPoint(x, y - 1));
}
}
}
void Map::undo() {
Blockdata *commit = history.pop();
if (commit != NULL) {
blockdata->copyFrom(commit);
}
}
void Map::redo() {
Blockdata *commit = history.next();
if (commit != NULL) {
blockdata->copyFrom(commit);
}
}
void Map::commit() {
Blockdata* commit = blockdata->copy();
history.push(commit);
}
void Map::setBlock(int x, int y, Block block) {
Block *old_block = getBlock(x, y);
if (old_block && (*old_block) != block) {
_setBlock(x, y, block);
commit();
}
}
void Map::floodFill(int x, int y, uint tile) {
Block *block = getBlock(x, y);
if (block && block->tile != tile) {
_floodFill(x, y, tile);
commit();
}
}
void Map::floodFillCollision(int x, int y, uint collision) {
Block *block = getBlock(x, y);
if (block && block->collision != collision) {
_floodFillCollision(x, y, collision);
commit();
}
}
void Map::floodFillElevation(int x, int y, uint elevation) {
Block *block = getBlock(x, y);
if (block && block->elevation != elevation) {
_floodFillElevation(x, y, elevation);
commit();
}
}
void Map::floodFillCollisionElevation(int x, int y, uint collision, uint elevation) {
Block *block = getBlock(x, y);
if (block && (block->collision != collision || block->elevation != elevation)) {
_floodFillCollisionElevation(x, y, collision, elevation);
commit();
}
}

165
map.h Executable file
View file

@ -0,0 +1,165 @@
#ifndef MAP_H
#define MAP_H
#include "tileset.h"
#include "blockdata.h"
#include "event.h"
#include <QPixmap>
#include <QObject>
#include <QDebug>
template <typename T>
class History {
public:
QList<T> history;
int head;
History() {
head = -1;
}
T pop() {
if (head > 0) {
return history.at(--head);
}
return NULL;
}
T next() {
if (head + 1 < history.length()) {
return history.at(++head);
}
return NULL;
}
void push(T commit) {
while (head + 1 < history.length()) {
history.removeLast();
}
history.append(commit);
head++;
}
};
class Connection {
public:
Connection() {
}
public:
QString direction;
QString offset;
QString map_name;
};
class Map : public QObject
{
Q_OBJECT
public:
explicit Map(QObject *parent = 0);
public:
QString name;
QString attributes_label;
QString events_label;
QString scripts_label;
QString connections_label;
QString song;
QString index;
QString location;
QString visibility;
QString weather;
QString type;
QString unknown;
QString show_location;
QString battle_scene;
QString width;
QString height;
QString border_label;
QString blockdata_label;
QString tileset_primary_label;
QString tileset_secondary_label;
Tileset *tileset_primary;
Tileset *tileset_secondary;
Blockdata* blockdata;
public:
int getWidth();
int getHeight();
Tileset* getBlockTileset(uint);
Metatile* getMetatile(uint);
QImage getMetatileImage(uint);
QImage getMetatileTile(uint);
QPixmap render();
QPixmap renderMetatiles();
QPixmap renderCollision();
QImage collision_image;
QPixmap collision_pixmap;
QImage getCollisionMetatileImage(Block);
QImage getElevationMetatileImage(Block);
QImage getCollisionMetatileImage(int);
QImage getElevationMetatileImage(int);
QPixmap renderCollisionMetatiles();
QPixmap renderElevationMetatiles();
void drawSelection(int i, int w, QPainter *painter);
bool blockChanged(int, Blockdata*);
Blockdata* cached_blockdata;
void cacheBlockdata();
Blockdata* cached_collision;
void cacheCollision();
QImage image;
QPixmap pixmap;
QList<QImage> metatile_images;
int paint_tile;
int paint_collision;
int paint_elevation;
Block *getBlock(int x, int y);
void setBlock(int x, int y, Block block);
void _setBlock(int x, int y, Block block);
void floodFill(int x, int y, uint tile);
void _floodFill(int x, int y, uint tile);
void floodFillCollision(int x, int y, uint collision);
void _floodFillCollision(int x, int y, uint collision);
void floodFillElevation(int x, int y, uint elevation);
void _floodFillElevation(int x, int y, uint elevation);
void floodFillCollisionElevation(int x, int y, uint collision, uint elevation);
void _floodFillCollisionElevation(int x, int y, uint collision, uint elevation);
History<Blockdata*> history;
void undo();
void redo();
void commit();
QString object_events_label;
QString warps_label;
QString coord_events_label;
QString bg_events_label;
QList<ObjectEvent*> object_events;
QList<Warp*> warps;
QList<CoordEvent*> coord_events;
QList<Sign*> signs;
QList<HiddenItem*> hidden_items;
QList<Connection*> connections;
QPixmap renderConnection(Connection);
QImage border_image;
QPixmap border_pixmap;
Blockdata *border;
Blockdata *cached_border;
QPixmap renderBorder();
void cacheBorder();
signals:
public slots:
};
#endif // MAP_H

6
metatile.cpp Executable file
View file

@ -0,0 +1,6 @@
#include "metatile.h"
Metatile::Metatile()
{
tiles = new QList<Tile>;
}

16
metatile.h Executable file
View file

@ -0,0 +1,16 @@
#ifndef METATILE_H
#define METATILE_H
#include "tile.h"
#include <QList>
class Metatile
{
public:
Metatile();
public:
QList<Tile> *tiles;
int attr;
};
#endif // METATILE_H

43
pretmap.pro Executable file
View file

@ -0,0 +1,43 @@
#-------------------------------------------------
#
# Project created by QtCreator 2016-08-31T15:19:13
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = pretmap
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
project.cpp \
asm.cpp \
map.cpp \
blockdata.cpp \
block.cpp \
tileset.cpp \
metatile.cpp \
tile.cpp \
event.cpp \
editor.cpp
HEADERS += mainwindow.h \
project.h \
asm.h \
map.h \
blockdata.h \
block.h \
tileset.h \
metatile.h \
tile.h \
event.h \
editor.h
FORMS += mainwindow.ui
RESOURCES += \
resources/images.qrc

787
project.cpp Executable file
View file

@ -0,0 +1,787 @@
#include "asm.h"
#include "project.h"
#include "tile.h"
#include "tileset.h"
#include "metatile.h"
#include "event.h"
#include <QDebug>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QRegularExpression>
Project::Project()
{
groupNames = new QStringList;
groupedMapNames = new QList<QStringList*>;
map_cache = new QMap<QString, Map*>;
tileset_cache = new QMap<QString, Tileset*>;
}
QString Project::getProjectTitle() {
return root.section('/', -1);
}
Map* Project::loadMap(QString map_name) {
Map *map = new Map;
map->name = map_name;
readMapHeader(map);
readMapAttributes(map);
getTilesets(map);
loadBlockdata(map);
loadMapBorder(map);
readMapEvents(map);
loadMapConnections(map);
map->commit();
map_cache->insert(map_name, map);
return map;
}
void Project::loadMapConnections(Map *map) {
map->connections.clear();
if (!map->connections_label.isNull()) {
QString path = root + QString("/data/maps/%1/connections.s").arg(map->name);
QString text = readTextFile(path);
if (text != NULL) {
QList<QStringList> *commands = parse(text);
QStringList *list = getLabelValues(commands, map->connections_label);
//// Avoid using this value. It ought to be generated instead.
//int num_connections = list->value(0).toInt(nullptr, 0);
QString connections_list_label = list->value(1);
QList<QStringList> *connections = getLabelMacros(commands, connections_list_label);
for (QStringList command : *connections) {
QString macro = command.value(0);
if (macro == "connection") {
Connection *connection = new Connection;
connection->direction = command.value(1);
connection->offset = command.value(2);
connection->map_name = command.value(3);
map->connections.append(connection);
}
}
}
}
}
QList<QStringList>* Project::getLabelMacros(QList<QStringList> *list, QString label) {
bool in_label = false;
QList<QStringList> *new_list = new QList<QStringList>;
for (int i = 0; i < list->length(); i++) {
QStringList params = list->value(i);
QString macro = params.value(0);
if (macro == ".label") {
if (params.value(1) == label) {
in_label = true;
} else if (in_label) {
// If nothing has been read yet, assume the label
// we're looking for is in a stack of labels.
if (new_list->length() > 0) {
break;
}
}
} else if (in_label) {
new_list->append(params);
}
}
return new_list;
}
// For if you don't care about filtering by macro,
// and just want all values associated with some label.
QStringList* Project::getLabelValues(QList<QStringList> *list, QString label) {
list = getLabelMacros(list, label);
QStringList *values = new QStringList;
for (int i = 0; i < list->length(); i++) {
QStringList params = list->value(i);
QString macro = params.value(0);
// Ignore .align
if (macro == ".align") {
continue;
}
for (int j = 1; j < params.length(); j++) {
values->append(params.value(j));
}
}
return values;
}
void Project::readMapHeader(Map* map) {
QString label = map->name;
Asm *parser = new Asm;
QString header_text = readTextFile(root + "/data/maps/" + label + "/header.s");
QStringList *header = getLabelValues(parser->parse(header_text), label);
map->attributes_label = header->value(0);
map->events_label = header->value(1);
map->scripts_label = header->value(2);
map->connections_label = header->value(3);
map->song = header->value(4);
map->index = header->value(5);
map->location = header->value(6);
map->visibility = header->value(7);
map->weather = header->value(8);
map->type = header->value(9);
map->unknown = header->value(10);
map->show_location = header->value(11);
map->battle_scene = header->value(12);
}
void Project::saveMapHeader(Map *map) {
QString label = map->name;
QString header_path = root + "/data/maps/" + label + "/header.s";
QString text = "";
text += QString("%1::\n").arg(label);
text += QString("\t.4byte %1\n").arg(map->attributes_label);
text += QString("\t.4byte %1\n").arg(map->events_label);
text += QString("\t.4byte %1\n").arg(map->scripts_label);
text += QString("\t.4byte %1\n").arg(map->connections_label);
text += QString("\t.2byte %1\n").arg(map->song);
text += QString("\t.2byte %1\n").arg(map->index);
text += QString("\t.byte %1\n").arg(map->location);
text += QString("\t.byte %1\n").arg(map->visibility);
text += QString("\t.byte %1\n").arg(map->weather);
text += QString("\t.byte %1\n").arg(map->type);
text += QString("\t.2byte %1\n").arg(map->unknown);
text += QString("\t.byte %1\n").arg(map->show_location);
text += QString("\t.byte %1\n").arg(map->battle_scene);
saveTextFile(header_path, text);
}
void Project::readMapAttributes(Map* map) {
Asm *parser = new Asm;
QString assets_text = readTextFile(root + "/data/maps/_assets.s");
QStringList *attributes = getLabelValues(parser->parse(assets_text), map->attributes_label);
map->width = attributes->value(0);
map->height = attributes->value(1);
map->border_label = attributes->value(2);
map->blockdata_label = attributes->value(3);
map->tileset_primary_label = attributes->value(4);
map->tileset_secondary_label = attributes->value(5);
}
void Project::getTilesets(Map* map) {
map->tileset_primary = getTileset(map->tileset_primary_label);
map->tileset_secondary = getTileset(map->tileset_secondary_label);
}
Tileset* Project::loadTileset(QString label) {
Asm *parser = new Asm;
QString headers_text = readTextFile(root + "/data/tilesets/headers.s");
QStringList *values = getLabelValues(parser->parse(headers_text), label);
Tileset *tileset = new Tileset;
tileset->name = label;
tileset->is_compressed = values->value(0);
tileset->is_secondary = values->value(1);
tileset->padding = values->value(2);
tileset->tiles_label = values->value(3);
tileset->palettes_label = values->value(4);
tileset->metatiles_label = values->value(5);
tileset->metatile_attrs_label = values->value(6);
tileset->callback_label = values->value(7);
loadTilesetAssets(tileset);
tileset_cache->insert(label, tileset);
return tileset;
}
QString Project::getBlockdataPath(Map* map) {
QString text = readTextFile(root + "/data/maps/_assets.s");
QStringList *values = getLabelValues(parse(text), map->blockdata_label);
QString path;
if (!values->isEmpty()) {
path = root + "/" + values->value(0).section('"', 1, 1);
} else {
path = root + "/data/maps/" + map->name + "/map.bin";
}
return path;
}
QString Project::getMapBorderPath(Map *map) {
QString text = readTextFile(root + "/data/maps/_assets.s");
QStringList *values = getLabelValues(parse(text), map->border_label);
QString path;
if (!values->isEmpty()) {
path = root + "/" + values->value(0).section('"', 1, 1);
} else {
path = root + "/data/maps/" + map->name + "/border.bin";
}
return path;
}
void Project::loadBlockdata(Map* map) {
QString path = getBlockdataPath(map);
map->blockdata = readBlockdata(path);
}
void Project::loadMapBorder(Map *map) {
QString path = getMapBorderPath(map);
map->border = readBlockdata(path);
}
void Project::saveBlockdata(Map* map) {
QString path = getBlockdataPath(map);
writeBlockdata(path, map->blockdata);
}
void Project::writeBlockdata(QString path, Blockdata *blockdata) {
QFile file(path);
if (file.open(QIODevice::WriteOnly)) {
QByteArray data = blockdata->serialize();
file.write(data);
}
}
void Project::saveAllMaps() {
QList<QString> keys = map_cache->keys();
for (int i = 0; i < keys.length(); i++) {
QString key = keys.value(i);
Map* map = map_cache->value(key);
saveMap(map);
}
}
void Project::saveMap(Map *map) {
saveBlockdata(map);
saveMapHeader(map);
}
void Project::loadTilesetAssets(Tileset* tileset) {
Asm* parser = new Asm;
QString category = (tileset->is_secondary == "TRUE") ? "secondary" : "primary";
QString dir_path = root + "/data/tilesets/" + category + "/" + tileset->name.replace("gTileset_", "").toLower();
QString graphics_text = readTextFile(root + "/data/tilesets/graphics.s");
QList<QStringList> *graphics = parser->parse(graphics_text);
QStringList *tiles_values = getLabelValues(graphics, tileset->tiles_label);
QStringList *palettes_values = getLabelValues(graphics, tileset->palettes_label);
QString tiles_path;
if (!tiles_values->isEmpty()) {
tiles_path = root + "/" + tiles_values->value(0).section('"', 1, 1);
} else {
tiles_path = dir_path + "/tiles.4bpp";
if (tileset->is_compressed == "TRUE") {
tiles_path += ".lz";
}
}
QStringList *palette_paths = new QStringList;
if (!palettes_values->isEmpty()) {
for (int i = 0; i < palettes_values->length(); i++) {
QString value = palettes_values->value(i);
palette_paths->append(root + "/" + value.section('"', 1, 1));
}
} else {
QString palettes_dir_path = dir_path + "/palettes";
for (int i = 0; i < 16; i++) {
palette_paths->append(palettes_dir_path + "/" + QString("%1").arg(i, 2, 10, QLatin1Char('0')) + ".gbapal");
}
}
QString metatiles_path;
QString metatile_attrs_path;
QString metatiles_text = readTextFile(root + "/data/tilesets/metatiles.s");
QList<QStringList> *metatiles_macros = parser->parse(metatiles_text);
QStringList *metatiles_values = getLabelValues(metatiles_macros, tileset->metatiles_label);
if (!metatiles_values->isEmpty()) {
metatiles_path = root + "/" + metatiles_values->value(0).section('"', 1, 1);
} else {
metatiles_path = dir_path + "/metatiles.bin";
}
QStringList *metatile_attrs_values = getLabelValues(metatiles_macros, tileset->metatile_attrs_label);
if (!metatile_attrs_values->isEmpty()) {
metatile_attrs_path = root + "/" + metatile_attrs_values->value(0).section('"', 1, 1);
} else {
metatile_attrs_path = dir_path + "/metatile_attributes.bin";
}
// tiles
tiles_path = fixGraphicPath(tiles_path);
QImage *image = new QImage(tiles_path);
//image->setColor(0, qRgb(0xff, 0, 0)); // debug
QList<QImage> *tiles = new QList<QImage>;
int w = 8;
int h = 8;
for (int y = 0; y < image->height(); y += h)
for (int x = 0; x < image->width(); x += w) {
QImage tile = image->copy(x, y, w, h);
tiles->append(tile);
}
tileset->tiles = tiles;
// metatiles
//qDebug() << metatiles_path;
QFile metatiles_file(metatiles_path);
if (metatiles_file.open(QIODevice::ReadOnly)) {
QByteArray data = metatiles_file.readAll();
int num_metatiles = data.length() / 16;
int num_layers = 2;
QList<Metatile*> *metatiles = new QList<Metatile*>;
for (int i = 0; i < num_metatiles; i++) {
Metatile *metatile = new Metatile;
int index = i * 16;
for (int j = 0; j < 4 * num_layers; j++) {
uint16_t word = data[index++] & 0xff;
word += (data[index++] & 0xff) << 8;
Tile tile;
tile.tile = word & 0x3ff;
tile.xflip = (word >> 10) & 1;
tile.yflip = (word >> 11) & 1;
tile.palette = (word >> 12) & 0xf;
metatile->tiles->append(tile);
}
metatiles->append(metatile);
}
tileset->metatiles = metatiles;
}
QFile attrs_file(metatile_attrs_path);
//qDebug() << metatile_attrs_path;
if (attrs_file.open(QIODevice::ReadOnly)) {
QByteArray data = attrs_file.readAll();
int num_metatiles = data.length() / 2;
for (int i = 0; i < num_metatiles; i++) {
uint16_t word = data[i*2] & 0xff;
word += (data[i*2 + 1] & 0xff) << 8;
tileset->metatiles->value(i)->attr = word;
}
}
// palettes
QList<QList<QRgb>> *palettes = new QList<QList<QRgb>>;
for (int i = 0; i < palette_paths->length(); i++) {
QString path = palette_paths->value(i);
// the palettes are not compressed. this should never happen. it's only a precaution.
path = path.replace(QRegExp("\\.lz$"), "");
// TODO default to .pal (JASC-PAL)
// just use .gbapal for now
QFile file(path);
QList<QRgb> palette;
if (file.open(QIODevice::ReadOnly)) {
QByteArray data = file.readAll();
for (int j = 0; j < 16; j++) {
uint16_t word = data[j*2] & 0xff;
word += (data[j*2 + 1] & 0xff) << 8;
int red = word & 0x1f;
int green = (word >> 5) & 0x1f;
int blue = (word >> 10) & 0x1f;
QRgb color = qRgb(red * 8, green * 8, blue * 8);
palette.prepend(color);
}
}
//qDebug() << path;
palettes->append(palette);
}
tileset->palettes = palettes;
}
Blockdata* Project::readBlockdata(QString path) {
Blockdata *blockdata = new Blockdata;
//qDebug() << path;
QFile file(path);
if (file.open(QIODevice::ReadOnly)) {
QByteArray data = file.readAll();
for (int i = 0; (i + 1) < data.length(); i += 2) {
uint16_t word = (data[i] & 0xff) + ((data[i + 1] & 0xff) << 8);
blockdata->addBlock(word);
}
}
return blockdata;
}
Map* Project::getMap(QString map_name) {
if (map_cache->contains(map_name)) {
return map_cache->value(map_name);
} else {
Map *map = loadMap(map_name);
return map;
}
}
Tileset* Project::getTileset(QString label) {
if (tileset_cache->contains(label)) {
return tileset_cache->value(label);
} else {
Tileset *tileset = loadTileset(label);
return tileset;
}
}
QString Project::readTextFile(QString path) {
QFile file(path);
if (!file.open(QIODevice::ReadOnly)) {
//QMessageBox::information(0, "Error", QString("Could not open '%1': ").arg(path) + file.errorString());
return NULL;
}
QTextStream in(&file);
QString text = "";
while (!in.atEnd()) {
text += in.readLine() + "\n";
}
return text;
}
void Project::saveTextFile(QString path, QString text) {
QFile file(path);
if (file.open(QIODevice::WriteOnly)) {
file.write(text.toUtf8());
}
}
void Project::readMapGroups() {
QString text = readTextFile(root + "/data/maps/_groups.s");
if (text == NULL) {
return;
}
Asm *parser = new Asm;
QList<QStringList> *commands = parser->parse(text);
bool in_group_pointers = false;
QStringList *groups = new QStringList;
for (int i = 0; i < commands->length(); i++) {
QStringList params = commands->value(i);
QString macro = params.value(0);
if (macro == ".label") {
if (in_group_pointers) {
break;
}
if (params.value(1) == "gMapGroups") {
in_group_pointers = true;
}
} else if (macro == ".4byte") {
if (in_group_pointers) {
for (int j = 1; j < params.length(); j++) {
groups->append(params.value(j));
}
}
}
}
QList<QStringList*> *maps = new QList<QStringList*>;
for (int i = 0; i < groups->length(); i++) {
QStringList *list = new QStringList;
maps->append(list);
}
int group = -1;
for (int i = 0; i < commands->length(); i++) {
QStringList params = commands->value(i);
QString macro = params.value(0);
if (macro == ".label") {
group = groups->indexOf(params.value(1));
} else if (macro == ".4byte") {
if (group != -1) {
for (int j = 1; j < params.length(); j++) {
QStringList *list = maps->value(group);
list->append(params.value(j));
}
}
}
}
groupNames = groups;
groupedMapNames = maps;
}
QList<QStringList>* Project::parse(QString text) {
Asm *parser = new Asm;
return parser->parse(text);
}
QStringList Project::getLocations() {
// TODO
QStringList names;
for (int i = 0; i < 88; i++) {
names.append(QString("%1").arg(i));
}
return names;
}
QStringList Project::getVisibilities() {
// TODO
QStringList names;
for (int i = 0; i < 16; i++) {
names.append(QString("%1").arg(i));
}
return names;
}
QStringList Project::getWeathers() {
// TODO
QStringList names;
for (int i = 0; i < 16; i++) {
names.append(QString("%1").arg(i));
}
return names;
}
QStringList Project::getMapTypes() {
// TODO
QStringList names;
for (int i = 0; i < 16; i++) {
names.append(QString("%1").arg(i));
}
return names;
}
QStringList Project::getBattleScenes() {
// TODO
QStringList names;
for (int i = 0; i < 16; i++) {
names.append(QString("%1").arg(i));
}
return names;
}
QStringList Project::getSongNames() {
QStringList names;
QString text = readTextFile(root + "/constants/songs.s");
if (text != NULL) {
QList<QStringList> *commands = parse(text);
for (int i = 0; i < commands->length(); i++) {
QStringList params = commands->value(i);
QString macro = params.value(0);
if (macro == ".equiv") {
names.append(params.value(1));
}
}
}
return names;
}
QString Project::getSongName(int value) {
QStringList names;
QString text = readTextFile(root + "/constants/songs.s");
if (text != NULL) {
QList<QStringList> *commands = parse(text);
for (int i = 0; i < commands->length(); i++) {
QStringList params = commands->value(i);
QString macro = params.value(0);
if (macro == ".equiv") {
if (value == ((QString)(params.value(2))).toInt(nullptr, 0)) {
return params.value(1);
}
}
}
}
return "";
}
QMap<QString, int> Project::getMapObjGfxConstants() {
QMap<QString, int> constants;
QString text = readTextFile(root + "/constants/map_object_constants.s");
if (text != NULL) {
QList<QStringList> *commands = parse(text);
for (int i = 0; i < commands->length(); i++) {
QStringList params = commands->value(i);
QString macro = params.value(0);
if (macro == ".set") {
QString constant = params.value(1);
if (constant.startsWith("MAP_OBJ_GFX_")) {
int value = params.value(2).toInt(nullptr, 0);
constants.insert(constant, value);
}
}
}
}
return constants;
}
QString Project::fixGraphicPath(QString path) {
path = path.replace(QRegExp("\\.lz$"), "");
path = path.replace(QRegExp("\\.[1248]bpp$"), ".png");
return path;
}
void Project::loadObjectPixmaps(QList<ObjectEvent*> objects) {
bool needs_update = false;
for (ObjectEvent *object : objects) {
if (object->pixmap.isNull()) {
needs_update = true;
break;
}
}
if (!needs_update) {
return;
}
QMap<QString, int> constants = getMapObjGfxConstants();
QString pointers_path = root + "/data/graphics/field_objects/map_object_graphics_info_pointers.s";
QString pointers_text = readTextFile(pointers_path);
if (pointers_text == NULL) {
return;
}
QString info_path = root + "/data/graphics/field_objects/map_object_graphics_info.s";
QString info_text = readTextFile(info_path);
if (info_text == NULL) {
return;
}
QString pic_path = root + "/data/graphics/field_objects/map_object_pic_tables.s";
QString pic_text = readTextFile(pic_path);
if (pic_text == NULL) {
return;
}
QString assets_path = root + "/data/graphics/field_objects/map_object_graphics.s";
QString assets_text = readTextFile(assets_path);
if (assets_text == NULL) {
return;
}
QStringList *pointers = getLabelValues(parse(pointers_text), "gMapObjectGraphicsInfoPointers");
QList<QStringList> *info_commands = parse(info_text);
QList<QStringList> *asset_commands = parse(assets_text);
QList<QStringList> *pic_commands = parse(pic_text);
for (ObjectEvent *object : objects) {
if (!object->pixmap.isNull()) {
continue;
}
int id = constants.value(object->sprite);
QString info_label = pointers->value(id);
QStringList *info = getLabelValues(info_commands, info_label);
QString pic_label = info->value(12);
QList<QStringList> *pic = getLabelMacros(pic_commands, pic_label);
for (int i = 0; i < pic->length(); i++) {
QStringList command = pic->value(i);
QString macro = command.value(0);
if (macro == "obj_frame_tiles") {
QString label = command.value(1);
QStringList *incbins = getLabelValues(asset_commands, label);
QString path = incbins->value(0).section('"', 1, 1);
path = fixGraphicPath(path);
QPixmap pixmap(root + "/" + path);
object->pixmap = pixmap;
break;
}
}
}
}
void Project::readMapEvents(Map *map) {
// lazy
QString path = root + QString("/data/maps/events/%1.s").arg(map->name);
QString text = readTextFile(path);
QStringList *labels = getLabelValues(parse(text), map->events_label);
map->object_events_label = labels->value(0);
map->warps_label = labels->value(1);
map->coord_events_label = labels->value(2);
map->bg_events_label = labels->value(3);
QList<QStringList> *object_events = getLabelMacros(parse(text), map->object_events_label);
map->object_events.clear();
for (QStringList command : *object_events) {
if (command.value(0) == "object_event") {
ObjectEvent *object = new ObjectEvent;
// This macro is not fixed as of writing, but it should take fewer args.
bool old_macro = false;
if (command.length() >= 20) {
command.removeAt(19);
command.removeAt(18);
command.removeAt(15);
command.removeAt(13);
command.removeAt(11);
command.removeAt(7);
command.removeAt(5);
command.removeAt(1); // id. not 0, but is just the index in the list of objects
old_macro = true;
}
int i = 1;
object->sprite = command.value(i++);
object->replacement = command.value(i++);
object->x_ = command.value(i++);
object->y_ = command.value(i++);
object->elevation_ = command.value(i++);
object->behavior = command.value(i++);
if (old_macro) {
int radius = command.value(i++).toInt(nullptr, 0);
object->radius_x = QString("%1").arg(radius & 0xf);
object->radius_y = QString("%1").arg((radius >> 4) & 0xf);
} else {
object->radius_x = command.value(i++);
object->radius_y = command.value(i++);
}
object->property = command.value(i++);
object->sight_radius = command.value(i++);
object->script_label = command.value(i++);
object->event_flag = command.value(i++);
map->object_events.append(object);
}
}
QList<QStringList> *warps = getLabelMacros(parse(text), map->warps_label);
map->warps.clear();
for (QStringList command : *warps) {
if (command.value(0) == "warp_def") {
Warp *warp = new Warp;
int i = 1;
warp->x_ = command.value(i++);
warp->y_ = command.value(i++);
warp->elevation_ = command.value(i++);
warp->destination_warp = command.value(i++);
warp->destination_map = command.value(i++);
map->warps.append(warp);
}
}
QList<QStringList> *coords = getLabelMacros(parse(text), map->coord_events_label);
map->coord_events.clear();
for (QStringList command : *coords) {
if (command.value(0) == "coord_event") {
CoordEvent *coord = new CoordEvent;
bool old_macro = false;
if (command.length() >= 9) {
command.removeAt(7);
command.removeAt(6);
command.removeAt(4);
old_macro = true;
}
int i = 1;
coord->x_ = command.value(i++);
coord->y_ = command.value(i++);
coord->elevation_ = command.value(i++);
coord->unknown1 = command.value(i++);
coord->script_label = command.value(i++);
map->coord_events.append(coord);
}
}
QList<QStringList> *bgs = getLabelMacros(parse(text), map->warps_label);
map->hidden_items.clear();
map->signs.clear();
for (QStringList command : *bgs) {
if (command.value(0) == "bg_event") {
BGEvent *bg = new BGEvent;
int i = 1;
bg->x_ = command.value(i++);
bg->y_ = command.value(i++);
bg->elevation_ = command.value(i++);
bg->type = command.value(i++);
i++;
if (bg->is_item()) {
HiddenItem *item = new HiddenItem(*bg);
item->item = command.value(i++);
item->unknown5 = command.value(i++);
item->unknown6 = command.value(i++);
map->hidden_items.append(item);
} else {
Sign *sign = new Sign(*bg);
sign->script_label = command.value(i++);
map->signs.append(sign);
}
}
}
}

69
project.h Executable file
View file

@ -0,0 +1,69 @@
#ifndef PROJECT_H
#define PROJECT_H
#include "map.h"
#include "blockdata.h"
#include <QStringList>
#include <QList>
class Project
{
public:
Project();
QString root;
QStringList *groupNames;
QList<QStringList*> *groupedMapNames;
QMap<QString, Map*> *map_cache;
Map* loadMap(QString);
Map* getMap(QString);
QMap<QString, Tileset*> *tileset_cache;
Tileset* loadTileset(QString);
Tileset* getTileset(QString);
Blockdata* readBlockdata(QString);
void loadBlockdata(Map*);
QString readTextFile(QString path);
void saveTextFile(QString path, QString text);
void readMapGroups();
QString getProjectTitle();
QList<QStringList>* getLabelMacros(QList<QStringList>*, QString);
QStringList* getLabelValues(QList<QStringList>*, QString);
void readMapHeader(Map*);
void readMapAttributes(Map*);
void getTilesets(Map*);
void loadTilesetAssets(Tileset*);
QString getBlockdataPath(Map*);
void saveBlockdata(Map*);
void writeBlockdata(QString, Blockdata*);
void saveAllMaps();
void saveMap(Map*);
void saveMapHeader(Map*);
QList<QStringList>* parse(QString text);
QStringList getSongNames();
QString getSongName(int);
QStringList getLocations();
QStringList getVisibilities();
QStringList getWeathers();
QStringList getMapTypes();
QStringList getBattleScenes();
void loadObjectPixmaps(QList<ObjectEvent*> objects);
QMap<QString, int> getMapObjGfxConstants();
QString fixGraphicPath(QString path);
void readMapEvents(Map *map);
void loadMapConnections(Map *map);
void loadMapBorder(Map *map);
QString getMapBorderPath(Map *map);
};
#endif // PROJECT_H

BIN
resources/icons/folder.ico Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
resources/icons/folder_closed.ico Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
resources/icons/folder_image.ico Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
resources/icons/folder_map.ico Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
resources/icons/image.ico Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
resources/icons/map.ico Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

11
resources/images.qrc Executable file
View file

@ -0,0 +1,11 @@
<RCC>
<qresource prefix="/">
<file>icons/folder.ico</file>
<file>icons/folder_closed.ico</file>
<file>icons/folder_closed_map.ico</file>
<file>icons/folder_image.ico</file>
<file>icons/folder_map.ico</file>
<file>icons/image.ico</file>
<file>icons/map.ico</file>
</qresource>
</RCC>

6
tile.cpp Executable file
View file

@ -0,0 +1,6 @@
#include "tile.h"
Tile::Tile()
{
}

16
tile.h Executable file
View file

@ -0,0 +1,16 @@
#ifndef TILE_H
#define TILE_H
class Tile
{
public:
Tile();
public:
int tile;
int xflip;
int yflip;
int palette;
};
#endif // TILE_H

6
tileset.cpp Executable file
View file

@ -0,0 +1,6 @@
#include "tileset.h"
Tileset::Tileset()
{
}

27
tileset.h Executable file
View file

@ -0,0 +1,27 @@
#ifndef TILESET_H
#define TILESET_H
#include "metatile.h"
#include <QImage>
class Tileset
{
public:
Tileset();
public:
QString name;
QString is_compressed;
QString is_secondary;
QString padding;
QString tiles_label;
QString palettes_label;
QString metatiles_label;
QString callback_label;
QString metatile_attrs_label;
QList<QImage> *tiles;
QList<Metatile*> *metatiles;
QList<QList<QRgb>> *palettes;
};
#endif // TILESET_H