Adonthell  0.4
animation.cc
Go to the documentation of this file.
1 /*
2  Copyright (C) 1999/2000/2001 The Adonthell Project
3  Part of the Adonthell Project <http://adonthell.nongnu.org>
4 
5  Adonthell is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  Adonthell is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with Adonthell. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 
20 
21 /**
22  * @file animation.cc
23  * @author Alexandre Courbot <alexandrecourbot@linuxgames.com>
24  *
25  * @brief Defines the animationframe and animation classes.
26  *
27  *
28  */
29 
30 
31 #include "animation.h"
32 
33 
34 using namespace std;
35 
36 
37 
38 // animationframe class.
39 
40 
41 // Public methods.
42 
43 
45 {
46  clear ();
47 }
48 
50 {
51 }
52 
54 {
55  imagenbr = 0;
56  is_masked_ = false;
57  set_alpha (255);
58  gapx = 0;
59  gapy = 0;
60  delay_ = 0;
61  nextframe_ = 0;
62 }
63 
65 {
66  imagenbr << file;
67  is_masked_ << file;
68  alpha_ << file;
69  set_alpha (alpha_);
70  gapx << file;
71  gapy << file;
72  delay_ << file;
73  nextframe_ << file;
74 
75  return (0);
76 }
77 
79 {
80  image_nbr () >> file;
81  is_masked () >> file;
82  alpha () >> file;
83  offx () >> file;
84  offy () >> file;
85  delay () >> file;
86  nextframe () >> file;
87 
88  return (0);
89 }
90 
91 
92 
93 
94 // animation class.
95 
96 
97 // Public methods.
98 
99 
101 {
102  clear ();
103 }
104 
106 {
107  vector <image *>::iterator i;
108  for (i = t_frame.begin (); i != t_frame.end (); i++)
109  delete (*i);
110  t_frame.clear ();
111  frame.clear ();
112  currentframe_ = 0;
113  speedcounter = 0;
114  play_flag = STOP;
115  xoffset_ = 0;
116  yoffset_ = 0;
117  set_length (0);
118  set_height (0);
119 }
120 
122 {
123  clear ();
124 }
125 
126 
128 {
129  if ((!play_flag) || (!nbr_of_frames ()))
130  return true;
131  if (frame[currentframe ()].delay () == 0)
132  return true;
133  if (nbr_of_frames () <= 1)
134  return true;
135 
136  speedcounter++;
137  if (speedcounter >= frame[currentframe ()].delay ())
138  next_frame ();
139 
140  return true;
141 }
142 
144 {
145  currentframe_ = frame[currentframe ()].nextframe ();
146  speedcounter = 0;
147 }
148 
149 void animation::draw (s_int16 x, s_int16 y, const drawing_area * da_opt,
150  surface *target) const
151 {
152  t_frame[frame[currentframe ()].image_nbr ()]->
153  set_mask (frame[currentframe ()].is_masked ());
154  t_frame[frame[currentframe ()].image_nbr ()]->
155  set_alpha (frame[currentframe ()].alpha ());
156 
157  t_frame[frame[currentframe ()].image_nbr ()]->draw (x + xoffset () +
158  frame[currentframe ()].offx (),
159  y + yoffset () + frame[currentframe ()].offy (), da_opt,
160  target);
161 }
162 
164 {
165  u_int16 i;
166  u_int16 nbr_images;
167  u_int16 nbr_frames;
168  u_int16 t_xoffset, t_yoffset;
169 
170  clear ();
171 
172  t_xoffset << file;
173  t_yoffset << file;
174 
175 
176  // TODO: Remove this! (length and height are calculated later)
177  u_int16 dummy;
178  dummy << file;
179  dummy << file;
180 
181  // Read images
182  nbr_images << file;
183  for (i = 0; i < nbr_images; i++)
184  {
185  t_frame.push_back (new image);
186  t_frame.back ()->get_raw (file);
187  }
188 
189  // Read frames
190  nbr_frames << file;
191  animationframe aftemp;
192 
193  for (i = 0; i < nbr_frames; i++)
194  {
195  frame.push_back (aftemp);
196  frame.back ().get (file);
197  }
198 
199  currentframe_ = 0;
200 
201  set_offset (t_xoffset, t_yoffset);
202 
203  calculate_dimensions ();
204 
205  return (0);
206 }
207 
208 s_int8 animation::load (string fname)
209 {
210  igzstream file (fname);
211  u_int8 retvalue;
212 
213  if (!file.is_open ())
214  return (-1);
215  retvalue = get (file);
216  file.close ();
217  return (retvalue);
218 }
219 
221 {
222  u_int16 i;
223 
224  xoffset () >> file;
225  yoffset () >> file;
226 
227 
228  // TODO: Remove this! (length and height are calculated later)
229  u_int16 dummy = 0;
230  dummy >> file;
231  dummy >> file;
232 
233  // Write images
234  nbr_of_images () >> file;
235 
236  for (i = 0; i < nbr_of_images (); i++)
237  {
238  t_frame[i]->put_raw (file);
239  }
240 
241  // Write frames
242  nbr_of_frames () >> file;
243 
244  for (i = 0; i < nbr_of_frames (); i++)
245  {
246  frame[i].put (file);
247  }
248 
249  return (0);
250 }
251 
252 s_int8 animation::save (string fname) const
253 {
254  ogzstream file (fname);
255  u_int8 retvalue;
256 
257  if (!file.is_open ())
258  return (-1);
259  retvalue = put (file);
260  file.close ();
261  return (retvalue);
262 }
263 
265 {
266  vector <image *>::iterator i;
267  vector <animationframe>::iterator j;
268 
269  if (pos > nbr_of_images ())
270  return -2;
271 
272  i = t_frame.begin ();
273  while (pos--)
274  i++;
275 
276  t_frame.insert (i, (image *) im);
277 
278  for (j = frame.begin (); j != frame.end (); j++)
279  if (j->image_nbr () >= pos)
280  j->set_image_nbr (j->image_nbr () + 1);
281 
282  return 0;
283 }
284 
286 {
287  vector <image *>::iterator i;
288  vector <animationframe>::iterator j;
289 
290  if (pos > nbr_of_images () - 1)
291  return -2;
292 
293  i = t_frame.begin ();
294  while (pos--)
295  i++;
296 
297  delete (*i);
298  t_frame.erase (i);
299 
300  for (j = frame.begin (); j != frame.end (); j++)
301  if (j->image_nbr () >= pos)
302  j->set_image_nbr (j->image_nbr () - 1);
303 
304  return 0;
305 }
306 
308 {
309  vector <animationframe>::iterator i;
310 
311  if (pos > nbr_of_frames ())
312  return -2;
313 
314  i = frame.begin ();
315  while (pos--)
316  i++;
317 
318  frame.insert (i, af);
319 
320  for (i = frame.begin (); i != frame.end (); i++)
321  if (i->nextframe () >= pos)
322  i->set_nextframe (i->nextframe () + 1);
323 
324  return 0;
325 }
326 
328 {
329  vector <animationframe>::iterator i;
330 
331  if (pos > nbr_of_frames () - 1)
332  return -2;
333 
334  for (i = frame.begin (); i != frame.end (); i++)
335  if (i->nextframe () >= pos)
336  i->set_nextframe (frame[i->nextframe ()].nextframe ());
337 
338  i = frame.begin ();
339  while (pos--)
340  i++;
341 
342  frame.erase (i);
343 
344  if (!nbr_of_frames ())
345  currentframe_ = 0;
346 
347  return 0;
348 }
349 
350 void animation::zoom (u_int16 sx, u_int16 sy, const animation * src)
351 {
352  static u_int16 i;
353 
354  clear ();
355  for (i = 0; i < src->nbr_of_images (); i++)
356  {
357  image *im = new image;
358 
359  im->resize ((src->t_frame[i]->length () * sx) / src->length (),
360  (src->t_frame[i]->height () * sy) / src->height ());
361  im->zoom ((*src->t_frame[i]));
362  t_frame.push_back (im);
363  }
364 
365  for (i = 0; i < src->nbr_of_frames (); i++)
366  {
367  frame.push_back (src->frame[i]);
368  frame.back ().set_offset ((src->frame[i].offx () * sx) / src->length (),
369  (src->frame[i].offy () * sy) / src->height ());
370  }
371 }
372 
374 {
375  clear ();
376  (drawable&) (*this) = (drawable&) src;
377 
378  // Copy images
379  vector <image *>::iterator imit;
380  for (imit = src.t_frame.begin (); imit != src.t_frame.end (); imit++)
381  {
382  image * im = new image;
383  *im = *(*imit);
384  t_frame.push_back (im);
385  }
386 
387  // Copy frames
388  vector <animationframe>::iterator frit;
389  for (frit = src.frame.begin (); frit != src.frame.end (); frit++)
390  {
391  frame.push_back (*frit);
392  }
393 
394  // Copy properties
395  currentframe_ = src.currentframe_;
396  speedcounter = src.speedcounter;
397  play_flag = src.play_flag;
398 
399  set_length (src.length ());
400  set_height (src.height ());
401  set_offset (src.xoffset (), src.yoffset ());
402  return *this;
403 }
404 
405 
406 
407 // Private methods
408 
409 
410 void animation::calculate_dimensions ()
411 {
412  for (u_int16 i = 0; i < nbr_of_frames (); i++)
413  {
414  u_int16 tl, th;
415 
416  if ((tl =
417  t_frame[frame[i].image_nbr ()]->length () + frame[i].offx ()) >
418  length ())
419  set_length (tl + xoffset ());
420 
421  if ((th =
422  t_frame[frame[i].image_nbr ()]->height () + frame[i].offy ()) >
423  height ())
424  set_height (th + yoffset ());
425  }
426 }
animation::put
s_int8 put(ogzstream &file) const
Saves an animation into an opened file, in game format, with alpha and mask values.
Definition: animation.cc:220
animationframe::clear
void clear()
Resets an animationframe to it's initial (i.e post-constructor) state.
Definition: animation.cc:53
animation::delete_frame
s_int8 delete_frame(u_int16 pos)
Removes a frame at a given position.
Definition: animation.cc:327
animationframe
Handles images properties in an animation.
Definition: animation.h:52
animation.h
Declares the animationframe and animation classes.
animation::yoffset
s_int16 yoffset() const
Returns the global Y offset of the animation.
Definition: animation.h:555
animation::delete_image
s_int8 delete_image(u_int16 pos)
Removes an image at a given position.
Definition: animation.cc:285
animation::zoom
void zoom(u_int16 sx, u_int16 sy, const animation *src)
Zooms an animation.
Definition: animation.cc:350
animation::draw
void draw(s_int16 x, s_int16 y, const drawing_area *da_opt=NULL, surface *target=NULL) const
Draw the object on the screen.
Definition: animation.cc:149
surface
Class where drawables can actually be drawn to.
Definition: surface.h:85
drawable::height
u_int16 height() const
Returns the height of the drawable.
Definition: drawable.h:91
igzstream
Class to read data from a Gzip compressed file.
Definition: fileops.h:135
animation::load
s_int8 load(string fname)
Loads an animation from it's filename.
Definition: animation.cc:208
drawable::set_height
void set_height(u_int16 h)
Sets the height of the drawable.
Definition: drawable.h:139
animation::clear
void clear()
Clears an animation, that is put it back into the original (constructor) state.
Definition: animation.cc:105
animationframe::get
s_int8 get(igzstream &file)
Loads an animationframe from an opened file.
Definition: animation.cc:64
image::resize
void resize(u_int16 l, u_int16 h)
Resize this image.
Definition: image.cc:63
drawable
Abstract class for drawable objects manipulation.
Definition: drawable.h:59
drawable::set_length
void set_length(u_int16 l)
Sets the length of the drawable.
Definition: drawable.h:129
ogzstream
Class to write data from a Gzip compressed file.
Definition: fileops.h:227
u_int8
#define u_int8
8 bits long unsigned integer
Definition: types.h:35
s_int16
#define s_int16
16 bits long signed integer
Definition: types.h:47
animation::animation
animation()
Default constructor.
Definition: animation.cc:100
gz_file::is_open
bool is_open()
Returns whether the file is opened or not.
Definition: fileops.h:103
gz_file::close
void close()
Close the file that was opened.
Definition: fileops.cc:63
drawable::length
u_int16 length() const
Returns the length of the drawable.
Definition: drawable.h:80
animationframe::~animationframe
~animationframe()
Destructor.
Definition: animation.cc:49
s_int8
#define s_int8
8 bits long signed integer
Definition: types.h:44
animation::nbr_of_frames
u_int16 nbr_of_frames() const
Returns the number of frames in this animation.
Definition: animation.h:500
animation::currentframe
u_int16 currentframe() const
Returns the index of the currently displayed frame.
Definition: animation.h:522
animation::nbr_of_images
u_int16 nbr_of_images() const
Returns the number of images in this animation.
Definition: animation.h:511
animation::insert_image
s_int8 insert_image(const image *im, u_int16 pos)
Inserts an image at a given position of the image array.
Definition: animation.cc:264
image
Image manipulation class.
Definition: image.h:45
drawing_area
Implements "drawing zones" for drawing operations.
Definition: drawing_area.h:54
animationframe::put
s_int8 put(ogzstream &file) const
Saves an animationframe into an opened file.
Definition: animation.cc:78
animation::update
bool update()
Updates the animation state.
Definition: animation.cc:127
u_int16
#define u_int16
16 bits long unsigned integer
Definition: types.h:38
animation::set_offset
void set_offset(s_int16 x, s_int16 y)
Set the global offsets of this animation.
Definition: animation.h:566
animation::~animation
~animation()
Destructor.
Definition: animation.cc:121
image::zoom
void zoom(const surface &src)
Zooms a surface.
Definition: image.h:265
animation::next_frame
void next_frame()
Directly jumps to the next frame.
Definition: animation.cc:143
animation::insert_frame
s_int8 insert_frame(const animationframe af, u_int16 pos)
Inserts a frame at a given position of the animationframe array.
Definition: animation.cc:307
animationframe::animationframe
animationframe()
Default constructor.
Definition: animation.cc:44
animation::operator=
animation & operator=(const animation &src)
Animation copy (similar to copy ()).
Definition: animation.cc:373
animation::xoffset
s_int16 xoffset() const
Returns the global X offset of the animation.
Definition: animation.h:544
animation::save
s_int8 save(string fname) const
Saves an animation into an file, in game format, with alpha and mask values.
Definition: animation.cc:252
animation::get
s_int8 get(igzstream &file)
Loads an animation from an opened file.
Definition: animation.cc:163
animation
Class that handles animated elements, their update and their playback.
Definition: animation.h:312