Adonthell  0.4
animation.cc
Go to the documentation of this file.
1 // $Id: animation.cc,v 1.10 2002/06/28 12:15:20 gnurou Exp $
2 
3 /*
4  Copyright (C) 1999/2000/2001 The Adonthell Project
5  Part of the Adonthell Project http://adonthell.linuxgames.com
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.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11  See the COPYING file for more details.
12 
13  This file is a part of the Adonthell project.
14 */
15 
16 
17 
18 /**
19  * @file animation.cc
20  * @author Alexandre Courbot <alexandrecourbot@linuxgames.com>
21  *
22  * @brief Defines the animationframe and animation classes.
23  *
24  *
25  */
26 
27 
28 #include "animation.h"
29 
30 
31 using namespace std;
32 
33 
34 
35 // animationframe class.
36 
37 
38 // Public methods.
39 
40 
42 {
43  clear ();
44 }
45 
47 {
48 }
49 
51 {
52  imagenbr = 0;
53  is_masked_ = false;
54  set_alpha (255);
55  gapx = 0;
56  gapy = 0;
57  delay_ = 0;
58  nextframe_ = 0;
59 }
60 
62 {
63  imagenbr << file;
64  is_masked_ << file;
65  alpha_ << file;
66  set_alpha (alpha_);
67  gapx << file;
68  gapy << file;
69  delay_ << file;
70  nextframe_ << file;
71 
72  return (0);
73 }
74 
76 {
77  image_nbr () >> file;
78  is_masked () >> file;
79  alpha () >> file;
80  offx () >> file;
81  offy () >> file;
82  delay () >> file;
83  nextframe () >> file;
84 
85  return (0);
86 }
87 
88 
89 
90 
91 // animation class.
92 
93 
94 // Public methods.
95 
96 
98 {
99  clear ();
100 }
101 
103 {
104  vector <image *>::iterator i;
105  for (i = t_frame.begin (); i != t_frame.end (); i++)
106  delete (*i);
107  t_frame.clear ();
108  frame.clear ();
109  currentframe_ = 0;
110  speedcounter = 0;
111  play_flag = STOP;
112  xoffset_ = 0;
113  yoffset_ = 0;
114  set_length (0);
115  set_height (0);
116 }
117 
119 {
120  clear ();
121 }
122 
123 
125 {
126  if ((!play_flag) || (!nbr_of_frames ()))
127  return true;
128  if (frame[currentframe ()].delay () == 0)
129  return true;
130  if (nbr_of_frames () <= 1)
131  return true;
132 
133  speedcounter++;
134  if (speedcounter >= frame[currentframe ()].delay ())
135  next_frame ();
136 
137  return true;
138 }
139 
141 {
142  currentframe_ = frame[currentframe ()].nextframe ();
143  speedcounter = 0;
144 }
145 
146 void animation::draw (s_int16 x, s_int16 y, const drawing_area * da_opt,
147  surface *target) const
148 {
149  t_frame[frame[currentframe ()].image_nbr ()]->
150  set_mask (frame[currentframe ()].is_masked ());
151  t_frame[frame[currentframe ()].image_nbr ()]->
152  set_alpha (frame[currentframe ()].alpha ());
153 
154  t_frame[frame[currentframe ()].image_nbr ()]->draw (x + xoffset () +
155  frame[currentframe ()].offx (),
156  y + yoffset () + frame[currentframe ()].offy (), da_opt,
157  target);
158 }
159 
161 {
162  u_int16 i;
163  u_int16 nbr_images;
164  u_int16 nbr_frames;
165  u_int16 t_xoffset, t_yoffset;
166 
167  clear ();
168 
169  t_xoffset << file;
170  t_yoffset << file;
171 
172 
173  // TODO: Remove this! (length and height are calculated later)
174  u_int16 dummy;
175  dummy << file;
176  dummy << file;
177 
178  // Read images
179  nbr_images << file;
180  for (i = 0; i < nbr_images; i++)
181  {
182  t_frame.push_back (new image);
183  t_frame.back ()->get_raw (file);
184  }
185 
186  // Read frames
187  nbr_frames << file;
188  animationframe aftemp;
189 
190  for (i = 0; i < nbr_frames; i++)
191  {
192  frame.push_back (aftemp);
193  frame.back ().get (file);
194  }
195 
196  currentframe_ = 0;
197 
198  set_offset (t_xoffset, t_yoffset);
199 
200  calculate_dimensions ();
201 
202  return (0);
203 }
204 
205 s_int8 animation::load (string fname)
206 {
207  igzstream file (fname);
208  u_int8 retvalue;
209 
210  if (!file.is_open ())
211  return (-1);
212  retvalue = get (file);
213  file.close ();
214  return (retvalue);
215 }
216 
218 {
219  u_int16 i;
220 
221  xoffset () >> file;
222  yoffset () >> file;
223 
224 
225  // TODO: Remove this! (length and height are calculated later)
226  u_int16 dummy = 0;
227  dummy >> file;
228  dummy >> file;
229 
230  // Write images
231  nbr_of_images () >> file;
232 
233  for (i = 0; i < nbr_of_images (); i++)
234  {
235  t_frame[i]->put_raw (file);
236  }
237 
238  // Write frames
239  nbr_of_frames () >> file;
240 
241  for (i = 0; i < nbr_of_frames (); i++)
242  {
243  frame[i].put (file);
244  }
245 
246  return (0);
247 }
248 
249 s_int8 animation::save (string fname) const
250 {
251  ogzstream file (fname);
252  u_int8 retvalue;
253 
254  if (!file.is_open ())
255  return (-1);
256  retvalue = put (file);
257  file.close ();
258  return (retvalue);
259 }
260 
262 {
263  vector <image *>::iterator i;
264  vector <animationframe>::iterator j;
265 
266  if (pos > nbr_of_images ())
267  return -2;
268 
269  i = t_frame.begin ();
270  while (pos--)
271  i++;
272 
273  t_frame.insert (i, (image *) im);
274 
275  for (j = frame.begin (); j != frame.end (); j++)
276  if (j->image_nbr () >= pos)
277  j->set_image_nbr (j->image_nbr () + 1);
278 
279  return 0;
280 }
281 
283 {
284  vector <image *>::iterator i;
285  vector <animationframe>::iterator j;
286 
287  if (pos > nbr_of_images () - 1)
288  return -2;
289 
290  i = t_frame.begin ();
291  while (pos--)
292  i++;
293 
294  delete (*i);
295  t_frame.erase (i);
296 
297  for (j = frame.begin (); j != frame.end (); j++)
298  if (j->image_nbr () >= pos)
299  j->set_image_nbr (j->image_nbr () - 1);
300 
301  return 0;
302 }
303 
305 {
306  vector <animationframe>::iterator i;
307 
308  if (pos > nbr_of_frames ())
309  return -2;
310 
311  i = frame.begin ();
312  while (pos--)
313  i++;
314 
315  frame.insert (i, af);
316 
317  for (i = frame.begin (); i != frame.end (); i++)
318  if (i->nextframe () >= pos)
319  i->set_nextframe (i->nextframe () + 1);
320 
321  return 0;
322 }
323 
325 {
326  vector <animationframe>::iterator i;
327 
328  if (pos > nbr_of_frames () - 1)
329  return -2;
330 
331  for (i = frame.begin (); i != frame.end (); i++)
332  if (i->nextframe () >= pos)
333  i->set_nextframe (frame[i->nextframe ()].nextframe ());
334 
335  i = frame.begin ();
336  while (pos--)
337  i++;
338 
339  frame.erase (i);
340 
341  if (!nbr_of_frames ())
342  currentframe_ = 0;
343 
344  return 0;
345 }
346 
347 void animation::zoom (u_int16 sx, u_int16 sy, const animation * src)
348 {
349  static u_int16 i;
350 
351  clear ();
352  for (i = 0; i < src->nbr_of_images (); i++)
353  {
354  image *im = new image;
355 
356  im->resize ((src->t_frame[i]->length () * sx) / src->length (),
357  (src->t_frame[i]->height () * sy) / src->height ());
358  im->zoom ((*src->t_frame[i]));
359  t_frame.push_back (im);
360  }
361 
362  for (i = 0; i < src->nbr_of_frames (); i++)
363  {
364  frame.push_back (src->frame[i]);
365  frame.back ().set_offset ((src->frame[i].offx () * sx) / src->length (),
366  (src->frame[i].offy () * sy) / src->height ());
367  }
368 }
369 
371 {
372  clear ();
373  (drawable&) (*this) = (drawable&) src;
374 
375  // Copy images
376  vector <image *>::iterator imit;
377  for (imit = src.t_frame.begin (); imit != src.t_frame.end (); imit++)
378  {
379  image * im = new image;
380  *im = *(*imit);
381  t_frame.push_back (im);
382  }
383 
384  // Copy frames
385  vector <animationframe>::iterator frit;
386  for (frit = src.frame.begin (); frit != src.frame.end (); frit++)
387  {
388  frame.push_back (*frit);
389  }
390 
391  // Copy properties
392  currentframe_ = src.currentframe_;
393  speedcounter = src.speedcounter;
394  play_flag = src.play_flag;
395 
396  set_length (src.length ());
397  set_height (src.height ());
398  set_offset (src.xoffset (), src.yoffset ());
399  return *this;
400 }
401 
402 
403 
404 // Private methods
405 
406 
407 void animation::calculate_dimensions ()
408 {
409  for (u_int16 i = 0; i < nbr_of_frames (); i++)
410  {
411  u_int16 tl, th;
412 
413  if ((tl =
414  t_frame[frame[i].image_nbr ()]->length () + frame[i].offx ()) >
415  length ())
416  set_length (tl + xoffset ());
417 
418  if ((th =
419  t_frame[frame[i].image_nbr ()]->height () + frame[i].offy ()) >
420  height ())
421  set_height (th + yoffset ());
422  }
423 }