Skip to content

Commit

Permalink
Stop repeated parsing of src/data/object_events
Browse files Browse the repository at this point in the history
  • Loading branch information
GriffinRichards authored and huderlem committed Jan 29, 2022
1 parent 366fb5c commit ddc0f01
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 92 deletions.
3 changes: 1 addition & 2 deletions include/core/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class Event
OrderedJson::object buildSignEventJSON();
OrderedJson::object buildHiddenItemEventJSON();
OrderedJson::object buildSecretBaseEventJSON();
void setPixmapFromSpritesheet(QImage, int, int, int, bool);
void setPixmapFromSpritesheet(QImage, int, int, bool);
int getPixelX();
int getPixelY();
QMap<QString, bool> getExpectedFields();
Expand All @@ -99,7 +99,6 @@ class Event
int frame = 0;
bool hFlip = false;
bool usingSprite;
bool inanimate;

DraggablePixmapItem *pixmapItem = nullptr;
void setPixmapItem(DraggablePixmapItem *item) { pixmapItem = item; }
Expand Down
13 changes: 12 additions & 1 deletion include/project.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@
#include <QVariant>
#include <QFileSystemWatcher>

struct EventGraphics
{
QImage spritesheet;
int spriteWidth;
int spriteHeight;
bool inanimate;
};

static QString NONE_MAP_CONSTANT = "MAP_NONE";
static QString NONE_MAP_NAME = "None";

Expand Down Expand Up @@ -51,6 +59,7 @@ class Project : public QObject
QMap<QString, QString> mapSecToMapHoverName;
QMap<QString, int> mapSectionNameToValue;
QMap<int, QString> mapSectionValueToName;
QMap<QString, EventGraphics*> eventGraphicsMap;
QStringList gfxNames;
QStringList songNames;
QStringList itemNames;
Expand Down Expand Up @@ -176,8 +185,10 @@ class Project : public QObject
bool readEventScriptLabels();
bool readObjEventGfxConstants();
bool readSongNames();
bool readEventGraphics();

void setEventPixmap(Event * event, bool forceLoad = false);

void loadEventPixmaps(QList<Event*> objects);
QString fixPalettePath(QString path);
QString fixGraphicPath(QString path);

Expand Down
11 changes: 3 additions & 8 deletions src/core/editcommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ void EventCreate::redo() {

map->addEvent(event);

editor->project->loadEventPixmaps(map->getAllEvents());
editor->project->setEventPixmap(event);
editor->addMapEvent(event);

// select this event
Expand Down Expand Up @@ -388,8 +388,7 @@ void EventDelete::redo() {
void EventDelete::undo() {
for (Event *event : selectedEvents) {
map->addEvent(event);

editor->project->loadEventPixmaps(map->getAllEvents());
editor->project->setEventPixmap(event);
editor->addMapEvent(event);
}

Expand Down Expand Up @@ -431,11 +430,7 @@ void EventDuplicate::redo() {

for (Event *event : selectedEvents) {
map->addEvent(event);
}

editor->project->loadEventPixmaps(map->getAllEvents());

for (Event *event : selectedEvents) {
editor->project->setEventPixmap(event);
editor->addMapEvent(event);
}

Expand Down
12 changes: 5 additions & 7 deletions src/core/event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ Event::Event(const Event& toCopy) :
spriteHeight(toCopy.spriteHeight),
frame(toCopy.frame),
hFlip(toCopy.hFlip),
usingSprite(toCopy.usingSprite),
inanimate(toCopy.inanimate)
usingSprite(toCopy.usingSprite)
{ }

Event::Event(QJsonObject obj, QString type) : Event()
Expand Down Expand Up @@ -410,13 +409,14 @@ OrderedJson::object Event::buildSecretBaseEventJSON()
return secretBaseObj;
}

void Event::setPixmapFromSpritesheet(QImage spritesheet, int spriteWidth, int spriteHeight, int frame, bool hFlip)
void Event::setPixmapFromSpritesheet(QImage spritesheet, int spriteWidth, int spriteHeight, bool inanimate)
{
// Set first palette color fully transparent.
int frame = inanimate ? 0 : this->frame;
QImage img = spritesheet.copy(frame * spriteWidth % spritesheet.width(), 0, spriteWidth, spriteHeight);
if (hFlip) {
if (this->hFlip && !inanimate) {
img = img.transformed(QTransform().scale(-1, 1));
}
// Set first palette color fully transparent.
img.setColor(0, qRgba(0, 0, 0, 0));
pixmap = QPixmap::fromImage(img);
this->spriteWidth = spriteWidth;
Expand All @@ -428,8 +428,6 @@ void Event::setFrameFromMovement(QString facingDir) {
// defaults
this->frame = 0;
this->hFlip = false;
if (this->inanimate)
return;
if (facingDir == "DIR_NORTH") {
this->frame = 1;
this->hFlip = false;
Expand Down
7 changes: 2 additions & 5 deletions src/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1498,10 +1498,7 @@ void Editor::displayMapEvents() {

QList<Event *> events = map->getAllEvents();
for (Event *event : events) {
event->setFrameFromMovement(project->facingDirections.value(event->get("movement_type")));
}
project->loadEventPixmaps(events);
for (Event *event : events) {
project->setEventPixmap(event);
addMapEvent(event);
}
//objects_group->setFiltersChildEvents(false);
Expand Down Expand Up @@ -1971,7 +1968,7 @@ QList<DraggablePixmapItem *> Editor::getObjects() {
}

void Editor::redrawObject(DraggablePixmapItem *item) {
if (item) {
if (item && item->event && !item->event->pixmap.isNull()) {
qreal opacity = item->event->usingSprite ? 1.0 : 0.7;
item->setOpacity(opacity);
item->setPixmap(item->event->pixmap.copy(item->event->frame * item->event->spriteWidth % item->event->pixmap.width(), 0, item->event->spriteWidth, item->event->spriteHeight));
Expand Down
5 changes: 3 additions & 2 deletions src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,7 @@ bool MainWindow::loadDataStructures() {
&& project->readWildMonData()
&& project->readEventScriptLabels()
&& project->readObjEventGfxConstants()
&& project->readEventGraphics()
&& project->readSongNames();

return success && loadProjectCombos();
Expand Down Expand Up @@ -2171,8 +2172,8 @@ void MainWindow::updateSelectedObjects() {
combo->addItem(value);
}
connect(combo, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentTextChanged),
this, [this, item](QString value){
item->event->setFrameFromMovement(editor->project->facingDirections.value(value));
this, [item](QString value){
item->event->put("movement_type", value);
item->updatePixmap();
});
combo->addItems(editor->project->movementTypes);
Expand Down
131 changes: 69 additions & 62 deletions src/project.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2418,82 +2418,89 @@ QCompleter *Project::getEventScriptLabelCompleter(QStringList additionalScriptLa
return &eventScriptLabelCompleter;
}

void Project::loadEventPixmaps(QList<Event*> objects) {
bool needs_update = false;
for (Event *object : objects) {
if (object->pixmap.isNull()) {
needs_update = true;
break;
}
}
if (!needs_update) {
void Project::setEventPixmap(Event * event, bool forceLoad) {
if (!event || (!event->pixmap.isNull() && !forceLoad))
return;

event->spriteWidth = 16;
event->spriteHeight = 16;
event->usingSprite = false;

QString event_type = event->get("event_type");
if (event_type == EventType::Object) {
QString gfxName = event->get("sprite");
EventGraphics * eventGfx = eventGraphicsMap.value(gfxName, nullptr);
if (!eventGfx || eventGfx->spritesheet.isNull()) {
// No sprite associated with this gfx constant.
// Use default sprite instead.
event->pixmap = QPixmap(":/images/Entities_16x16.png").copy(0, 0, 16, 16);
} else {
event->setFrameFromMovement(facingDirections.value(event->get("movement_type")));
event->setPixmapFromSpritesheet(eventGfx->spritesheet, eventGfx->spriteWidth, eventGfx->spriteHeight, eventGfx->inanimate);
}
} else if (event_type == EventType::Warp) {
event->pixmap = QPixmap(":/images/Entities_16x16.png").copy(16, 0, 16, 16);
} else if (event_type == EventType::Trigger || event_type == EventType::WeatherTrigger) {
event->pixmap = QPixmap(":/images/Entities_16x16.png").copy(32, 0, 16, 16);
} else if (event_type == EventType::Sign || event_type == EventType::HiddenItem || event_type == EventType::SecretBase) {
event->pixmap = QPixmap(":/images/Entities_16x16.png").copy(48, 0, 16, 16);
} else if (event_type == EventType::HealLocation) {
event->pixmap = QPixmap(":/images/Entities_16x16.png").copy(64, 0, 16, 16);
}
}

bool Project::readEventGraphics() {
fileWatcher.addPaths(QStringList() << root + "/" + "src/data/object_events/object_event_graphics_info_pointers.h"
<< root + "/" + "src/data/object_events/object_event_graphics_info.h"
<< root + "/" + "src/data/object_events/object_event_pic_tables.h"
<< root + "/" + "src/data/object_events/object_event_graphics.h");

QMap<QString, QString> pointerHash = parser.readNamedIndexCArray("src/data/object_events/object_event_graphics_info_pointers.h", "gObjectEventGraphicsInfoPointers");

for (Event *object : objects) {
if (!object->pixmap.isNull()) {
continue;
}

object->spriteWidth = 16;
object->spriteHeight = 16;
object->usingSprite = false;
object->inanimate = true;
QString event_type = object->get("event_type");
if (event_type == EventType::Object) {
object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(0, 0, 16, 16);
} else if (event_type == EventType::Warp) {
object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(16, 0, 16, 16);
} else if (event_type == EventType::Trigger || event_type == EventType::WeatherTrigger) {
object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(32, 0, 16, 16);
} else if (event_type == EventType::Sign || event_type == EventType::HiddenItem || event_type == EventType::SecretBase) {
object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(48, 0, 16, 16);
} else if (event_type == EventType::HealLocation) {
object->pixmap = QPixmap(":/images/Entities_16x16.png").copy(64, 0, 16, 16);
}

if (event_type == EventType::Object) {
QString info_label = pointerHash[object->get("sprite")].replace("&", "");
QStringList gfx_info = parser.readCArray("src/data/object_events/object_event_graphics_info.h", info_label);
object->inanimate = (gfx_info.value(8) == "TRUE");
QString pic_label = gfx_info.value(14);
QString dimensions_label = gfx_info.value(11);
QString subsprites_label = gfx_info.value(12);
QString gfx_label = parser.readCArray("src/data/object_events/object_event_pic_tables.h", pic_label).value(0);
gfx_label = gfx_label.section(QRegularExpression("[\\(\\)]"), 1, 1);
QString path = parser.readCIncbin("src/data/object_events/object_event_graphics.h", gfx_label);

if (!path.isNull()) {
path = fixGraphicPath(path);
QImage spritesheet(root + "/" + path);
if (!spritesheet.isNull()) {
// Infer the sprite dimensions from the OAM labels.
int spriteWidth, spriteHeight;
QRegularExpression re("\\S+_(\\d+)x(\\d+)");
QRegularExpressionMatch dimensionMatch = re.match(dimensions_label);
QRegularExpressionMatch oamTablesMatch = re.match(subsprites_label);
if (oamTablesMatch.hasMatch()) {
spriteWidth = oamTablesMatch.captured(1).toInt();
spriteHeight = oamTablesMatch.captured(2).toInt();
} else if (dimensionMatch.hasMatch()) {
spriteWidth = dimensionMatch.captured(1).toInt();
spriteHeight = dimensionMatch.captured(2).toInt();
} else {
spriteWidth = spritesheet.width();
spriteHeight = spritesheet.height();
}
object->setPixmapFromSpritesheet(spritesheet, spriteWidth, spriteHeight, object->frame, object->hFlip);
qDeleteAll(eventGraphicsMap);
eventGraphicsMap.clear();
for (QString gfxName : this->gfxNames) {
EventGraphics * eventGraphics = new EventGraphics;

QString info_label = pointerHash[gfxName].replace("&", "");
QStringList gfx_info = parser.readCArray("src/data/object_events/object_event_graphics_info.h", info_label);

eventGraphics->inanimate = (gfx_info.value(8) == "TRUE");
QString pic_label = gfx_info.value(14);
QString dimensions_label = gfx_info.value(11);
QString subsprites_label = gfx_info.value(12);

QString gfx_label = parser.readCArray("src/data/object_events/object_event_pic_tables.h", pic_label).value(0);
gfx_label = gfx_label.section(QRegularExpression("[\\(\\)]"), 1, 1);
QString path = parser.readCIncbin("src/data/object_events/object_event_graphics.h", gfx_label);

if (!path.isNull()) {
path = fixGraphicPath(path);
eventGraphics->spritesheet = QImage(root + "/" + path);
if (!eventGraphics->spritesheet.isNull()) {
// Infer the sprite dimensions from the OAM labels.
QRegularExpression re("\\S+_(\\d+)x(\\d+)");
QRegularExpressionMatch dimensionMatch = re.match(dimensions_label);
QRegularExpressionMatch oamTablesMatch = re.match(subsprites_label);
if (oamTablesMatch.hasMatch()) {
eventGraphics->spriteWidth = oamTablesMatch.captured(1).toInt();
eventGraphics->spriteHeight = oamTablesMatch.captured(2).toInt();
} else if (dimensionMatch.hasMatch()) {
eventGraphics->spriteWidth = dimensionMatch.captured(1).toInt();
eventGraphics->spriteHeight = dimensionMatch.captured(2).toInt();
} else {
eventGraphics->spriteWidth = eventGraphics->spritesheet.width();
eventGraphics->spriteHeight = eventGraphics->spritesheet.height();
}
}
} else {
eventGraphics->spritesheet = QImage();
eventGraphics->spriteWidth = 16;
eventGraphics->spriteHeight = 16;
}
eventGraphicsMap.insert(gfxName, eventGraphics);
}
return true;
}

bool Project::readSpeciesIconPaths() {
Expand Down
5 changes: 1 addition & 4 deletions src/ui/draggablepixmapitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ void DraggablePixmapItem::emitPositionChanged() {
}

void DraggablePixmapItem::updatePixmap() {
QList<Event*> objects;
objects.append(event);
event->pixmap = QPixmap();
editor->project->loadEventPixmaps(objects);
editor->project->setEventPixmap(event, true);
this->updatePosition();
editor->redrawObject(this);
emit spriteChanged(event->pixmap);
Expand Down
2 changes: 1 addition & 1 deletion src/ui/mapimageexporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,8 +368,8 @@ QPixmap MapImageExporter::getFormattedMapPixmap(Map *map, bool ignoreBorder) {
// draw events
QPainter eventPainter(&pixmap);
QList<Event*> events = map->getAllEvents();
editor->project->loadEventPixmaps(events);
for (Event *event : events) {
editor->project->setEventPixmap(event);
QString group = event->get("event_group_type");
if ((showObjects && group == "object_event_group")
|| (showWarps && group == "warp_event_group")
Expand Down

0 comments on commit ddc0f01

Please sign in to comment.