aseprite/src/doc/handle_anidir.cpp
2016-03-03 19:18:46 -03:00

101 lines
2.0 KiB
C++

// Aseprite Document Library
// Copyright (c) 2001-2016 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "doc/handle_anidir.h"
#include "base/base.h"
#include "doc/frame.h"
#include "doc/frame_tag.h"
#include "doc/sprite.h"
namespace doc {
frame_t calculate_next_frame(
const Sprite* sprite,
frame_t frame,
frame_t frameDelta,
const FrameTag* tag,
bool& pingPongForward)
{
if (frameDelta == 0)
return frame;
frame_t first = frame_t(0);
frame_t last = sprite->lastFrame();
AniDir aniDir = AniDir::FORWARD;
if (tag) {
frame_t loopFrom, loopTo;
loopFrom = tag->fromFrame();
loopTo = tag->toFrame();
loopFrom = MID(first, loopFrom, last);
loopTo = MID(first, loopTo, last);
first = loopFrom;
last = loopTo;
aniDir = tag->aniDir();
}
frame_t frameRange = (last - first + 1);
switch (aniDir) {
case AniDir::REVERSE:
frameDelta = -frameDelta;
case AniDir::FORWARD:
frame += frameDelta;
while (frame > last) frame -= frameRange;
while (frame < first) frame += frameRange;
break;
case AniDir::PING_PONG: {
bool invertPingPong;
if (frameDelta < 0) {
frameDelta = -frameDelta;
pingPongForward = !pingPongForward;
invertPingPong = true;
}
else
invertPingPong = false;
while (--frameDelta >= 0) {
if (pingPongForward) {
++frame;
if (frame > last) {
frame = last-1;
if (frame < first)
frame = first;
pingPongForward = false;
}
}
else {
--frame;
if (frame < first) {
frame = first+1;
if (frame > last)
frame = last;
pingPongForward = true;
}
}
}
if (invertPingPong)
pingPongForward = !pingPongForward;
break;
}
}
return frame;
}
} // namespace doc