OpenGTA/util/animation.cpp

117 lines
3.8 KiB
C++
Raw Normal View History

2015-12-03 00:37:37 +00:00
/************************************************************************
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
* *
* This software is provided as-is, without any express or implied *
* warranty. In no event will the authors be held liable for any *
* damages arising from the use of this software. *
* *
* Permission is granted to anyone to use this software for any purpose, *
* including commercial applications, and to alter it and redistribute *
* it freely, subject to the following restrictions: *
* *
* 1. The origin of this software must not be misrepresented; you must *
* not claim that you wrote the original software. If you use this *
* software in a product, an acknowledgment in the product documentation *
* would be appreciated but is not required. *
* *
* 2. Altered source versions must be plainly marked as such, and must *
* not be misrepresented as being the original software. *
* *
* 3. This notice may not be removed or altered from any source *
* distribution. *
************************************************************************/
2015-12-03 00:37:02 +00:00
#include <sstream>
#include "animation.h"
#include "m_exceptions.h"
namespace Util {
Animation::Animation(uint16_t num, uint16_t fps) :
callback() {
status = STOPPED;
numFrames = num;
currentFrame = 0;
delay = 1000 / fps;
lastChangeTicks = 0;
}
Animation::Animation(const Animation & other) {
status = other.status;
onDone = other.onDone;
numFrames = other.numFrames;
currentFrame = other.currentFrame;
delay = other.delay;
lastChangeTicks = other.lastChangeTicks;
callback = other.callback;
}
void Animation::update(const uint32_t & nowTicks) {
if (status == STOPPED)
return;
if (lastChangeTicks == 0)
lastChangeTicks = nowTicks;
if (nowTicks < lastChangeTicks + delay)
return;
lastChangeTicks = nowTicks;
if (status == PLAY_FORWARD)
flipFrame(true);
else if (status == PLAY_BACKWARD)
flipFrame(false);
}
void Animation::flipFrame(bool forward = true) {
switch(forward) {
case true:
if (currentFrame < numFrames - 1)
++currentFrame;
else if (currentFrame == numFrames - 1)
isDone();
break;
case false:
if (currentFrame == 0)
isDone();
else
--currentFrame;
}
}
void Animation::jumpToFrame(const uint16_t num, const Status andDo) {
if (num >= numFrames) {
std::ostringstream o;
o << num << " >= " << numFrames;
throw E_OUTOFRANGE(o.str());
}
currentFrame = num;
status = andDo;
}
void Animation::isDone() {
if (onDone == STOP) {
status = STOPPED;
return;
}
if (onDone == REVERSE) {
status = (status == PLAY_FORWARD) ? PLAY_BACKWARD : PLAY_FORWARD;
return;
}
if (onDone == LOOP) {
if (status == PLAY_FORWARD)
jumpToFrame(0, PLAY_FORWARD);
else if (status == PLAY_BACKWARD)
jumpToFrame(numFrames - 1, PLAY_BACKWARD);
return;
}
status = STOPPED;
if (onDone == FCALLBACK) {
if (callback)
callback();
else
ERROR << "Wanted to call callback, but nobody was there" << std::endl;
}
}
}
void AnimCallback() {
WARN << "EmptyAnimCallback called" << std::endl;
}