1
/*
2
 *  The Mana World
3
 *  Copyright (C) 2004  The Mana World Development Team
4
 *
5
 *  This file is part of The Mana World.
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program; if not, write to the Free Software
19
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 */
21
22
#include "graphics.h"
23
#include "log.h"
24
#include "simpleanimation.h"
25
26
#include "resources/animation.h"
27
#include "resources/image.h"
28
#include "resources/imageset.h"
29
#include "resources/resourcemanager.h"
30
31
SimpleAnimation::SimpleAnimation(Animation *animation):
32
    mAnimation(animation),
33
    mAnimationTime(0),
34
    mAnimationPhase(0),
35
    mCurrentFrame(mAnimation->getFrame(0))
36
{
37
}
38
39
SimpleAnimation::SimpleAnimation(xmlNodePtr animationNode):
40
    mAnimationTime(0),
41
    mAnimationPhase(0)
42
{
43
    mAnimation = new Animation;
44
45
    ImageSet *imageset = ResourceManager::getInstance()->getImageSet(
46
        XML::getProperty(animationNode, "imageset", ""),
47
        XML::getProperty(animationNode, "width", 0),
48
        XML::getProperty(animationNode, "height", 0)
49
    );
50
51
    // Get animation frames
52
    for (   xmlNodePtr frameNode = animationNode->xmlChildrenNode;
53
            frameNode;
54
            frameNode = frameNode->next)
55
    {
56
        int delay = XML::getProperty(frameNode, "delay", 0);
57
        int offsetX = XML::getProperty(frameNode, "offsetX", 0);
58
        int offsetY = XML::getProperty(frameNode, "offsetY", 0);
59
        offsetY -= imageset->getHeight() - 32;
60
        offsetX -= imageset->getWidth() / 2 - 16;
61
62
        if (xmlStrEqual(frameNode->name, BAD_CAST "frame"))
63
        {
64
            int index = XML::getProperty(frameNode, "index", -1);
65
66
            if (index < 0)
67
            {
68
                logger->log("No valid value for 'index'");
69
                continue;
70
            }
71
72
            Image *img = imageset->get(index);
73
74
            if (!img)
75
            {
76
                logger->log("No image at index %d", index);
77
                continue;
78
            }
79
80
            mAnimation->addFrame(img, delay, offsetX, offsetY);
81
        }
82
        else if (xmlStrEqual(frameNode->name, BAD_CAST "sequence"))
83
        {
84
            int start = XML::getProperty(frameNode, "start", -1);
85
            int end = XML::getProperty(frameNode, "end", -1);
86
87
            if (start < 0 || end < 0)
88
            {
89
                logger->log("No valid value for 'start' or 'end'");
90
                continue;
91
            }
92
93
            while (end >= start)
94
            {
95
                Image *img = imageset->get(start);
96
97
                if (!img)
98
                {
99
                    logger->log("No image at index %d", start);
100
                    continue;
101
                }
102
103
                mAnimation->addFrame(img, delay, offsetX, offsetY);
104
                start++;
105
            }
106
        }
107
        else if (xmlStrEqual(frameNode->name, BAD_CAST "end"))
108
        {
109
            mAnimation->addTerminator();
110
        }
111
    }
112
113
    mCurrentFrame = mAnimation->getFrame(0);
114
}
115
116
bool SimpleAnimation::draw(Graphics* graphics, int posX, int posY) const
117
{
118
    if (!mCurrentFrame || !mCurrentFrame->image)
119
        return false;
120
121
    return graphics->drawImage(mCurrentFrame->image,
122
                               posX + mCurrentFrame->offsetX,
123
                               posY + mCurrentFrame->offsetY);
124
}
125
126
void SimpleAnimation::reset()
127
{
128
    mAnimationTime = 0;
129
    mAnimationPhase = 0;
130
}
131
132
void SimpleAnimation::setFrame(int frame)
133
{
134
    if (frame < 0)
135
        frame = 0;
136
    if (frame >= mAnimation->getLength())
137
        frame = mAnimation->getLength() - 1;
138
    mAnimationPhase = frame;
139
    mCurrentFrame = mAnimation->getFrame(mAnimationPhase);
140
}
141
142
void SimpleAnimation::update(int timePassed)
143
{
144
    mAnimationTime += timePassed;
145
146
    while (mAnimationTime > mCurrentFrame->delay && mCurrentFrame->delay > 0)
147
    {
148
        mAnimationTime -= mCurrentFrame->delay;
149
        mAnimationPhase++;
150
151
        if (mAnimationPhase >= mAnimation->getLength())
152
            mAnimationPhase = 0;
153
154
        mCurrentFrame = mAnimation->getFrame(mAnimationPhase);
155
    }
156
}
157
158
int SimpleAnimation::getLength() const
159
{
160
    return mAnimation->getLength();
161
}
162
163
Image *SimpleAnimation::getCurrentImage() const
164
{
165
    return mCurrentFrame->image;
166
}
167
168
SimpleAnimation::~SimpleAnimation()
169
{
170
    delete mAnimation;
171
}