From 9439dc76d2197dc4791b6724a990500a23e4714c Mon Sep 17 00:00:00 2001 From: Marcus Huderle Date: Tue, 19 Jan 2021 20:21:15 -0600 Subject: [PATCH] Only include relevant frames in the timelapse animation --- include/core/editcommands.h | 21 ++++++++------ include/ui/mapimageexporter.h | 1 + src/core/editcommands.cpp | 42 +++++++++++++++++++++++++++- src/ui/mapimageexporter.cpp | 52 ++++++++++++++++++++++++++++++++--- 4 files changed, 103 insertions(+), 13 deletions(-) diff --git a/include/core/editcommands.h b/include/core/editcommands.h index cbc98415..8ff606f0 100644 --- a/include/core/editcommands.h +++ b/include/core/editcommands.h @@ -13,7 +13,7 @@ class DraggablePixmapItem; class Editor; enum CommandId { - ID_PaintMetatile, + ID_PaintMetatile = 0, ID_BucketFillMetatile, ID_MagicFillMetatile, ID_ShiftMetatiles, @@ -30,7 +30,11 @@ enum CommandId { ID_EventDuplicate, }; - +#define IDMask_EventType_Object (1 << 8) +#define IDMask_EventType_Warp (1 << 9) +#define IDMask_EventType_BG (1 << 10) +#define IDMask_EventType_Trigger (1 << 11) +#define IDMask_EventType_Heal (1 << 12) /// Implements a command to commit metatile paint actions /// onto the map using the pencil tool. @@ -240,7 +244,7 @@ public: void redo() override; bool mergeWith(const QUndoCommand *command) override; - int id() const override { return CommandId::ID_EventMove; } + int id() const override; private: QList events; @@ -259,8 +263,9 @@ public: int deltaX, int deltaY, unsigned actionId, QUndoCommand *parent = nullptr); ~EventShift(); - - int id() const override { return CommandId::ID_EventShift; } + int id() const override; +private: + QList events; }; @@ -277,7 +282,7 @@ public: void redo() override; bool mergeWith(const QUndoCommand *) override { return false; } - int id() const override { return CommandId::ID_EventCreate; } + int id() const override; private: Map *map; @@ -300,7 +305,7 @@ public: void redo() override; bool mergeWith(const QUndoCommand *) override { return false; } - int id() const override { return CommandId::ID_EventDelete; } + int id() const override; private: Editor *editor; @@ -322,7 +327,7 @@ public: void redo() override; bool mergeWith(const QUndoCommand *) override { return false; } - int id() const override { return CommandId::ID_EventDuplicate; } + int id() const override; private: Map *map; diff --git a/include/ui/mapimageexporter.h b/include/ui/mapimageexporter.h index 3ab482c7..6d8ae643 100644 --- a/include/ui/mapimageexporter.h +++ b/include/ui/mapimageexporter.h @@ -53,6 +53,7 @@ private: void saveImage(); QPixmap getStitchedImage(QProgressDialog *progress, bool includeBorder); QPixmap getFormattedMapPixmap(Map *map, bool ignoreBorder); + bool historyItemAppliesToFrame(const QUndoCommand *command); private slots: void on_checkBox_Objects_stateChanged(int state); diff --git a/src/core/editcommands.cpp b/src/core/editcommands.cpp index ba765908..05ecc22a 100644 --- a/src/core/editcommands.cpp +++ b/src/core/editcommands.cpp @@ -6,7 +6,26 @@ #include - +int getEventTypeMask(QList events) { + int eventTypeMask = 0; + for (auto event : events) { + if (event->get("event_type") == EventType::Object) { + eventTypeMask |= IDMask_EventType_Object; + } else if (event->get("event_type") == EventType::Warp) { + eventTypeMask |= IDMask_EventType_Warp; + } else if (event->get("event_type") == EventType::Trigger || + event->get("event_type") == EventType::WeatherTrigger) { + eventTypeMask |= IDMask_EventType_Trigger; + } else if (event->get("event_type") == EventType::Sign || + event->get("event_type") == EventType::HiddenItem || + event->get("event_type") == EventType::SecretBase) { + eventTypeMask |= IDMask_EventType_BG; + } else if (event->get("event_type") == EventType::HealLocation) { + eventTypeMask |= IDMask_EventType_Heal; + } + } + return eventTypeMask; +} void renderMapBlocks(Map *map, bool ignoreCache = false) { map->mapItem->draw(ignoreCache); @@ -305,6 +324,10 @@ bool EventMove::mergeWith(const QUndoCommand *command) { return true; } +int EventMove::id() const { + return CommandId::ID_EventMove | getEventTypeMask(events); +} + /****************************************************************************** ************************************************************************ ******************************************************************************/ @@ -313,11 +336,16 @@ EventShift::EventShift(QList events, int deltaX, int deltaY, unsigned actionId, QUndoCommand *parent) : EventMove(events, deltaX, deltaY, actionId, parent) { + this->events = events; setText("Shift Events"); } EventShift::~EventShift() {} +int EventShift::id() const { + return CommandId::ID_EventShift | getEventTypeMask(events); +} + /****************************************************************************** ************************************************************************ ******************************************************************************/ @@ -360,6 +388,10 @@ void EventCreate::undo() { QUndoCommand::undo(); } +int EventCreate::id() const { + return CommandId::ID_EventCreate | getEventTypeMask(QList({this->event})); +} + /****************************************************************************** ************************************************************************ ******************************************************************************/ @@ -418,6 +450,10 @@ void EventDelete::undo() { QUndoCommand::undo(); } +int EventDelete::id() const { + return CommandId::ID_EventDelete | getEventTypeMask(this->selectedEvents); +} + /****************************************************************************** ************************************************************************ ******************************************************************************/ @@ -471,6 +507,10 @@ void EventDuplicate::undo() { QUndoCommand::undo(); } +int EventDuplicate::id() const { + return CommandId::ID_EventDuplicate | getEventTypeMask(this->selectedEvents); +} + /****************************************************************************** ************************************************************************ ******************************************************************************/ diff --git a/src/ui/mapimageexporter.cpp b/src/ui/mapimageexporter.cpp index 9ee69ce0..afcfeb7f 100644 --- a/src/ui/mapimageexporter.cpp +++ b/src/ui/mapimageexporter.cpp @@ -1,6 +1,7 @@ #include "mapimageexporter.h" #include "ui_mapimageexporter.h" #include "qgifimage.h" +#include "editcommands.h" #include #include @@ -99,8 +100,8 @@ void MapImageExporter::saveImage() { int maxWidth = this->map->getWidth() * 16; int maxHeight = this->map->getHeight() * 16; if (showBorder) { - maxWidth += STITCH_MODE_BORDER_DISTANCE * 16; - maxHeight += STITCH_MODE_BORDER_DISTANCE * 16; + maxWidth += 2 * STITCH_MODE_BORDER_DISTANCE * 16; + maxHeight += 2 * STITCH_MODE_BORDER_DISTANCE * 16; } // Rewind to the specified start of the map edit history. int i = 0; @@ -110,8 +111,8 @@ void MapImageExporter::saveImage() { int width = this->map->getWidth() * 16; int height = this->map->getHeight() * 16; if (showBorder) { - width += STITCH_MODE_BORDER_DISTANCE * 16; - height += STITCH_MODE_BORDER_DISTANCE * 16; + width += 2 * STITCH_MODE_BORDER_DISTANCE * 16; + height += 2 * STITCH_MODE_BORDER_DISTANCE * 16; } if (width > maxWidth) { maxWidth = width; @@ -136,6 +137,11 @@ void MapImageExporter::saveImage() { } return; } + while (this->map->editHistory.canRedo() && + !historyItemAppliesToFrame(this->map->editHistory.command(this->map->editHistory.index()))) { + i--; + this->map->editHistory.redo(); + } progress.setValue(progress.maximum() - i); QPixmap pixmap = this->getFormattedMapPixmap(this->map, !this->showBorder); if (pixmap.width() < maxWidth || pixmap.height() < maxHeight) { @@ -151,6 +157,11 @@ void MapImageExporter::saveImage() { if (i > 0) { i--; this->map->editHistory.redo(); + while (this->map->editHistory.canRedo() && + !historyItemAppliesToFrame(this->map->editHistory.command(this->map->editHistory.index()))) { + i--; + this->map->editHistory.redo(); + } } } } @@ -165,6 +176,39 @@ void MapImageExporter::saveImage() { } } +bool MapImageExporter::historyItemAppliesToFrame(const QUndoCommand *command) { + switch (command->id() & 0xFF) { + case CommandId::ID_PaintMetatile: + case CommandId::ID_BucketFillMetatile: + case CommandId::ID_MagicFillMetatile: + case CommandId::ID_ShiftMetatiles: + case CommandId::ID_ResizeMap: + case CommandId::ID_ScriptEditMap: + return true; + case CommandId::ID_PaintCollision: + case CommandId::ID_BucketFillCollision: + case CommandId::ID_MagicFillCollision: + return this->showCollision; + case CommandId::ID_PaintBorder: + return this->showBorder; + case CommandId::ID_EventMove: + case CommandId::ID_EventShift: + case CommandId::ID_EventCreate: + case CommandId::ID_EventDelete: + case CommandId::ID_EventDuplicate: { + bool eventTypeIsApplicable = + (this->showObjects && (command->id() & IDMask_EventType_Object) != 0) + || (this->showWarps && (command->id() & IDMask_EventType_Warp) != 0) + || (this->showBGs && (command->id() & IDMask_EventType_BG) != 0) + || (this->showTriggers && (command->id() & IDMask_EventType_Trigger) != 0) + || (this->showHealSpots && (command->id() & IDMask_EventType_Heal) != 0); + return eventTypeIsApplicable; + } + default: + return false; + } +} + struct StitchedMap { int x; int y;