From ddc0f01460eeab47abb4c40b6bbbe0d0a0efee3e Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 24 Jan 2022 17:17:31 -0500 Subject: [PATCH] Stop repeated parsing of src/data/object_events --- include/core/event.h | 3 +- include/project.h | 13 +++- src/core/editcommands.cpp | 11 +-- src/core/event.cpp | 12 ++-- src/editor.cpp | 7 +- src/mainwindow.cpp | 5 +- src/project.cpp | 127 +++++++++++++++++---------------- src/ui/draggablepixmapitem.cpp | 5 +- src/ui/mapimageexporter.cpp | 2 +- 9 files changed, 95 insertions(+), 90 deletions(-) diff --git a/include/core/event.h b/include/core/event.h index 1fc6be5f..cce095d0 100644 --- a/include/core/event.h +++ b/include/core/event.h @@ -83,7 +83,7 @@ public: 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 getExpectedFields(); @@ -99,7 +99,6 @@ public: int frame = 0; bool hFlip = false; bool usingSprite; - bool inanimate; DraggablePixmapItem *pixmapItem = nullptr; void setPixmapItem(DraggablePixmapItem *item) { pixmapItem = item; } diff --git a/include/project.h b/include/project.h index b9669641..ec1ffe6b 100644 --- a/include/project.h +++ b/include/project.h @@ -18,6 +18,14 @@ #include #include +struct EventGraphics +{ + QImage spritesheet; + int spriteWidth; + int spriteHeight; + bool inanimate; +}; + static QString NONE_MAP_CONSTANT = "MAP_NONE"; static QString NONE_MAP_NAME = "None"; @@ -51,6 +59,7 @@ public: QMap mapSecToMapHoverName; QMap mapSectionNameToValue; QMap mapSectionValueToName; + QMap eventGraphicsMap; QStringList gfxNames; QStringList songNames; QStringList itemNames; @@ -176,8 +185,10 @@ public: bool readEventScriptLabels(); bool readObjEventGfxConstants(); bool readSongNames(); + bool readEventGraphics(); + + void setEventPixmap(Event * event, bool forceLoad = false); - void loadEventPixmaps(QList objects); QString fixPalettePath(QString path); QString fixGraphicPath(QString path); diff --git a/src/core/editcommands.cpp b/src/core/editcommands.cpp index be795cd9..b4c96883 100644 --- a/src/core/editcommands.cpp +++ b/src/core/editcommands.cpp @@ -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 @@ -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); } @@ -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); } diff --git a/src/core/event.cpp b/src/core/event.cpp index 9dc69845..75656fc4 100644 --- a/src/core/event.cpp +++ b/src/core/event.cpp @@ -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() @@ -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; @@ -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; diff --git a/src/editor.cpp b/src/editor.cpp index 5371e1a3..436e6955 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -1498,10 +1498,7 @@ void Editor::displayMapEvents() { QList 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); @@ -1971,7 +1968,7 @@ QList 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)); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index df6682b3..6f5bcd8b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -943,6 +943,7 @@ bool MainWindow::loadDataStructures() { && project->readWildMonData() && project->readEventScriptLabels() && project->readObjEventGfxConstants() + && project->readEventGraphics() && project->readSongNames(); return success && loadProjectCombos(); @@ -2171,8 +2172,8 @@ void MainWindow::updateSelectedObjects() { combo->addItem(value); } connect(combo, static_cast(&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); diff --git a/src/project.cpp b/src/project.cpp index 260e2cce..586687ff 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -2418,18 +2418,38 @@ QCompleter *Project::getEventScriptLabelCompleter(QStringList additionalScriptLa return &eventScriptLabelCompleter; } -void Project::loadEventPixmaps(QList 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" @@ -2437,63 +2457,50 @@ void Project::loadEventPixmaps(QList objects) { QMap pointerHash = parser.readNamedIndexCArray("src/data/object_events/object_event_graphics_info_pointers.h", "gObjectEventGraphicsInfoPointers"); - for (Event *object : objects) { - if (!object->pixmap.isNull()) { - continue; - } + qDeleteAll(eventGraphicsMap); + eventGraphicsMap.clear(); + for (QString gfxName : this->gfxNames) { + EventGraphics * eventGraphics = new EventGraphics; - 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); - } + QString info_label = pointerHash[gfxName].replace("&", ""); + QStringList gfx_info = parser.readCArray("src/data/object_events/object_event_graphics_info.h", info_label); - 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); + 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); - 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); + 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() { diff --git a/src/ui/draggablepixmapitem.cpp b/src/ui/draggablepixmapitem.cpp index 56c66209..cbc4d584 100644 --- a/src/ui/draggablepixmapitem.cpp +++ b/src/ui/draggablepixmapitem.cpp @@ -26,10 +26,7 @@ void DraggablePixmapItem::emitPositionChanged() { } void DraggablePixmapItem::updatePixmap() { - QList 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); diff --git a/src/ui/mapimageexporter.cpp b/src/ui/mapimageexporter.cpp index 24aaa66a..bd5c5bfb 100644 --- a/src/ui/mapimageexporter.cpp +++ b/src/ui/mapimageexporter.cpp @@ -368,8 +368,8 @@ QPixmap MapImageExporter::getFormattedMapPixmap(Map *map, bool ignoreBorder) { // draw events QPainter eventPainter(&pixmap); QList 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")