diff --git a/data/pref.xml b/data/pref.xml
index cc8c0c94d..3cd2a70f1 100644
--- a/data/pref.xml
+++ b/data/pref.xml
@@ -18,11 +18,6 @@
-
-
-
-
-
@@ -137,7 +132,7 @@
-
+
diff --git a/docs/files/ase.txt b/docs/files/ase.txt
index 366eea432..a16bae2fa 100644
--- a/docs/files/ase.txt
+++ b/docs/files/ase.txt
@@ -231,10 +231,17 @@ Frame Tags Chunk (0x2018)
----------------------------------------
WORD Number of tags
+ BYTE[8] For future (set to zero)
+ For each tag
WORD From frame
WORD To frame
+ BYTE Loop animation direction
+ 0 - Forward
+ 1 - Reverse
+ 2 - Ping-pong
+ BYTE[8] For future (set to zero)
BYTE[3] RGB values of the tag color
+ BYTE Extra byte (zero)
STRING Tag name
diff --git a/src/app/file/ase_format.cpp b/src/app/file/ase_format.cpp
index 4c576d653..df6fb6522 100644
--- a/src/app/file/ase_format.cpp
+++ b/src/app/file/ase_format.cpp
@@ -1277,12 +1277,23 @@ static void ase_file_write_mask_chunk(FILE* f, ASE_FrameHeader* frame_header, Ma
static void ase_file_read_frame_tags_chunk(FILE* f, FrameTags* frameTags)
{
size_t tags = fgetw(f);
+
+ fgetl(f); // 8 reserved bytes
+ fgetl(f);
+
for (size_t c=0; csize(), f);
+
+ fputl(0, f); // 8 reserved bytes
+ fputl(0, f);
+
for (FrameTag* tag : *frameTags) {
fputw(tag->fromFrame(), f);
fputw(tag->toFrame(), f);
+ fputc((int)tag->aniDir(), f);
+
+ fputl(0, f); // 8 reserved bytes
+ fputl(0, f);
+
fputc(doc::rgba_getr(tag->color()), f);
fputc(doc::rgba_getg(tag->color()), f);
fputc(doc::rgba_getb(tag->color()), f);
+ fputc(0, f);
+
ase_file_write_string(f, tag->name().c_str());
}
}
diff --git a/src/app/handle_anidir.cpp b/src/app/handle_anidir.cpp
index c7c4f5888..5c320014d 100644
--- a/src/app/handle_anidir.cpp
+++ b/src/app/handle_anidir.cpp
@@ -37,19 +37,19 @@ doc::frame_t calculate_next_frame(
switch (docPref.loop.aniDir()) {
- case app::gen::AniDir::FORWARD:
+ case doc::AniDir::FORWARD:
++frame;
if (frame > last)
frame = first;
break;
- case app::gen::AniDir::REVERSE:
+ case doc::AniDir::REVERSE:
--frame;
if (frame < first)
frame = last;
break;
- case app::gen::AniDir::PING_PONG:
+ case doc::AniDir::PING_PONG:
if (pingPongForward) {
++frame;
if (frame > last) {
diff --git a/src/app/ui/configure_timeline_popup.cpp b/src/app/ui/configure_timeline_popup.cpp
index 1eed6b1ad..45bd77dbf 100644
--- a/src/app/ui/configure_timeline_popup.cpp
+++ b/src/app/ui/configure_timeline_popup.cpp
@@ -61,9 +61,9 @@ ConfigureTimelinePopup::ConfigureTimelinePopup()
m_resetOnionskin->Click.connect(Bind(&ConfigureTimelinePopup::onResetOnionskin, this));
m_setLoopSection->Click.connect(Bind(&ConfigureTimelinePopup::onSetLoopSection, this));
m_resetLoopSection->Click.connect(Bind(&ConfigureTimelinePopup::onResetLoopSection, this));
- m_normalDir->Click.connect(Bind(&ConfigureTimelinePopup::onAniDir, this, app::gen::AniDir::FORWARD));
- m_reverseDir->Click.connect(Bind(&ConfigureTimelinePopup::onAniDir, this, app::gen::AniDir::REVERSE));
- m_pingPongDir->Click.connect(Bind(&ConfigureTimelinePopup::onAniDir, this, app::gen::AniDir::PING_PONG));
+ m_normalDir->Click.connect(Bind(&ConfigureTimelinePopup::onAniDir, this, doc::AniDir::FORWARD));
+ m_reverseDir->Click.connect(Bind(&ConfigureTimelinePopup::onAniDir, this, doc::AniDir::REVERSE));
+ m_pingPongDir->Click.connect(Bind(&ConfigureTimelinePopup::onAniDir, this, doc::AniDir::PING_PONG));
}
DocumentPreferences& ConfigureTimelinePopup::docPref()
@@ -98,13 +98,13 @@ void ConfigureTimelinePopup::updateWidgetsFromCurrentSettings()
}
switch (docPref.loop.aniDir()) {
- case app::gen::AniDir::FORWARD:
+ case doc::AniDir::FORWARD:
m_normalDir->setSelected(true);
break;
- case app::gen::AniDir::REVERSE:
+ case doc::AniDir::REVERSE:
m_reverseDir->setSelected(true);
break;
- case app::gen::AniDir::PING_PONG:
+ case doc::AniDir::PING_PONG:
m_pingPongDir->setSelected(true);
break;
}
@@ -170,7 +170,7 @@ void ConfigureTimelinePopup::onResetLoopSection()
docPref().loop.visible(false);
}
-void ConfigureTimelinePopup::onAniDir(app::gen::AniDir aniDir)
+void ConfigureTimelinePopup::onAniDir(doc::AniDir aniDir)
{
docPref().loop.aniDir(aniDir);
}
diff --git a/src/app/ui/configure_timeline_popup.h b/src/app/ui/configure_timeline_popup.h
index 7cdc325ae..6cdd421dc 100644
--- a/src/app/ui/configure_timeline_popup.h
+++ b/src/app/ui/configure_timeline_popup.h
@@ -10,6 +10,7 @@
#pragma once
#include "app/pref/preferences.h"
+#include "doc/anidir.h"
#include "ui/popup_window.h"
namespace ui {
@@ -33,7 +34,7 @@ namespace app {
void onResetOnionskin();
void onSetLoopSection();
void onResetLoopSection();
- void onAniDir(app::gen::AniDir aniDir);
+ void onAniDir(doc::AniDir aniDir);
private:
void updateWidgetsFromCurrentSettings();
diff --git a/src/doc/anidir.h b/src/doc/anidir.h
new file mode 100644
index 000000000..e459f4aea
--- /dev/null
+++ b/src/doc/anidir.h
@@ -0,0 +1,21 @@
+// Aseprite Document Library
+// Copyright (c) 2001-2015 David Capello
+//
+// This file is released under the terms of the MIT license.
+// Read LICENSE.txt for more information.
+
+#ifndef DOC_ANIDIR_H_INCLUDED
+#define DOC_ANIDIR_H_INCLUDED
+#pragma once
+
+namespace doc {
+
+ enum class AniDir {
+ FORWARD = 0,
+ REVERSE = 1,
+ PING_PONG = 2,
+ };
+
+} // namespace doc
+
+#endif // DOC_ANIDIR_H_INCLUDED
diff --git a/src/doc/frame_tag.cpp b/src/doc/frame_tag.cpp
index 8df479b00..71ce50e4a 100644
--- a/src/doc/frame_tag.cpp
+++ b/src/doc/frame_tag.cpp
@@ -37,4 +37,9 @@ void FrameTag::setColor(color_t color)
m_color = color;
}
+void FrameTag::setAniDir(AniDir aniDir)
+{
+ m_aniDir = aniDir;
+}
+
} // namespace doc
diff --git a/src/doc/frame_tag.h b/src/doc/frame_tag.h
index 80320785c..090d81417 100644
--- a/src/doc/frame_tag.h
+++ b/src/doc/frame_tag.h
@@ -9,6 +9,7 @@
#pragma once
#include "base/disable_copying.h"
+#include "doc/anidir.h"
#include "doc/color.h"
#include "doc/frame.h"
#include "doc/object.h"
@@ -25,15 +26,18 @@ namespace doc {
frame_t toFrame() const { return m_to; }
const std::string& name() const { return m_name; }
color_t color() const { return m_color; }
+ AniDir aniDir() const { return m_aniDir; }
void setFrameRange(frame_t from, frame_t to);
void setName(const std::string& name);
void setColor(color_t color);
+ void setAniDir(AniDir aniDir);
public:
frame_t m_from, m_to;
color_t m_color;
std::string m_name;
+ AniDir m_aniDir;
DISABLE_COPYING(FrameTag);
};
diff --git a/src/gen/pref_types.cpp b/src/gen/pref_types.cpp
index 2d6a5e900..b76fc8efe 100644
--- a/src/gen/pref_types.cpp
+++ b/src/gen/pref_types.cpp
@@ -186,6 +186,7 @@ void gen_pref_header(TiXmlDocument* doc, const std::string& inputFn)
<< "\n"
<< "#include \"app/color.h\"\n"
<< "#include \"app/pref/option.h\"\n"
+ << "#include \"doc/anidir.h\"\n"
<< "#include \"doc/frame.h\"\n"
<< "#include \"gfx/rect.h\"\n"
<< "#include \"filters/tiled_mode.h\"\n"