PageRenderTime 68ms CodeModel.GetById 38ms RepoModel.GetById 1ms app.codeStats 0ms

/adonthell-0.3.5/src/animation.cc

#
C++ | 423 lines | 284 code | 104 blank | 35 comment | 44 complexity | 33db5681be60c56a5a371b069c18dbd3 MD5 | raw file
Possible License(s): GPL-2.0
  1. // $Id: animation.cc,v 1.10 2002/06/28 12:15:20 gnurou Exp $
  2. /*
  3. Copyright (C) 1999/2000/2001 The Adonthell Project
  4. Part of the Adonthell Project http://adonthell.linuxgames.com
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY.
  9. See the COPYING file for more details.
  10. This file is a part of the Adonthell project.
  11. */
  12. /**
  13. * @file animation.cc
  14. * @author Alexandre Courbot <alexandrecourbot@linuxgames.com>
  15. *
  16. * @brief Defines the animationframe and animation classes.
  17. *
  18. *
  19. */
  20. #include "animation.h"
  21. using namespace std;
  22. // animationframe class.
  23. // Public methods.
  24. animationframe::animationframe ()
  25. {
  26. clear ();
  27. }
  28. animationframe::~animationframe ()
  29. {
  30. }
  31. void animationframe::clear ()
  32. {
  33. imagenbr = 0;
  34. is_masked_ = false;
  35. set_alpha (255);
  36. gapx = 0;
  37. gapy = 0;
  38. delay_ = 0;
  39. nextframe_ = 0;
  40. }
  41. s_int8 animationframe::get (igzstream& file)
  42. {
  43. imagenbr << file;
  44. is_masked_ << file;
  45. alpha_ << file;
  46. set_alpha (alpha_);
  47. gapx << file;
  48. gapy << file;
  49. delay_ << file;
  50. nextframe_ << file;
  51. return (0);
  52. }
  53. s_int8 animationframe::put (ogzstream& file) const
  54. {
  55. image_nbr () >> file;
  56. is_masked () >> file;
  57. alpha () >> file;
  58. offx () >> file;
  59. offy () >> file;
  60. delay () >> file;
  61. nextframe () >> file;
  62. return (0);
  63. }
  64. // animation class.
  65. // Public methods.
  66. animation::animation () : drawable ()
  67. {
  68. clear ();
  69. }
  70. void animation::clear ()
  71. {
  72. vector <image *>::iterator i;
  73. for (i = t_frame.begin (); i != t_frame.end (); i++)
  74. delete (*i);
  75. t_frame.clear ();
  76. frame.clear ();
  77. currentframe_ = 0;
  78. speedcounter = 0;
  79. play_flag = STOP;
  80. xoffset_ = 0;
  81. yoffset_ = 0;
  82. set_length (0);
  83. set_height (0);
  84. }
  85. animation::~animation ()
  86. {
  87. clear ();
  88. }
  89. bool animation::update ()
  90. {
  91. if ((!play_flag) || (!nbr_of_frames ()))
  92. return true;
  93. if (frame[currentframe ()].delay () == 0)
  94. return true;
  95. if (nbr_of_frames () <= 1)
  96. return true;
  97. speedcounter++;
  98. if (speedcounter >= frame[currentframe ()].delay ())
  99. next_frame ();
  100. return true;
  101. }
  102. void animation::next_frame ()
  103. {
  104. currentframe_ = frame[currentframe ()].nextframe ();
  105. speedcounter = 0;
  106. }
  107. void animation::draw (s_int16 x, s_int16 y, const drawing_area * da_opt,
  108. surface *target) const
  109. {
  110. t_frame[frame[currentframe ()].image_nbr ()]->
  111. set_mask (frame[currentframe ()].is_masked ());
  112. t_frame[frame[currentframe ()].image_nbr ()]->
  113. set_alpha (frame[currentframe ()].alpha ());
  114. t_frame[frame[currentframe ()].image_nbr ()]->draw (x + xoffset () +
  115. frame[currentframe ()].offx (),
  116. y + yoffset () + frame[currentframe ()].offy (), da_opt,
  117. target);
  118. }
  119. s_int8 animation::get (igzstream& file)
  120. {
  121. u_int16 i;
  122. u_int16 nbr_images;
  123. u_int16 nbr_frames;
  124. u_int16 t_xoffset, t_yoffset;
  125. clear ();
  126. t_xoffset << file;
  127. t_yoffset << file;
  128. // TODO: Remove this! (length and height are calculated later)
  129. u_int16 dummy;
  130. dummy << file;
  131. dummy << file;
  132. // Read images
  133. nbr_images << file;
  134. for (i = 0; i < nbr_images; i++)
  135. {
  136. t_frame.push_back (new image);
  137. t_frame.back ()->get_raw (file);
  138. }
  139. // Read frames
  140. nbr_frames << file;
  141. animationframe aftemp;
  142. for (i = 0; i < nbr_frames; i++)
  143. {
  144. frame.push_back (aftemp);
  145. frame.back ().get (file);
  146. }
  147. currentframe_ = 0;
  148. set_offset (t_xoffset, t_yoffset);
  149. calculate_dimensions ();
  150. return (0);
  151. }
  152. s_int8 animation::load (string fname)
  153. {
  154. igzstream file (fname);
  155. u_int8 retvalue;
  156. if (!file.is_open ())
  157. return (-1);
  158. retvalue = get (file);
  159. file.close ();
  160. return (retvalue);
  161. }
  162. s_int8 animation::put (ogzstream& file) const
  163. {
  164. u_int16 i;
  165. xoffset () >> file;
  166. yoffset () >> file;
  167. // TODO: Remove this! (length and height are calculated later)
  168. u_int16 dummy = 0;
  169. dummy >> file;
  170. dummy >> file;
  171. // Write images
  172. nbr_of_images () >> file;
  173. for (i = 0; i < nbr_of_images (); i++)
  174. {
  175. t_frame[i]->put_raw (file);
  176. }
  177. // Write frames
  178. nbr_of_frames () >> file;
  179. for (i = 0; i < nbr_of_frames (); i++)
  180. {
  181. frame[i].put (file);
  182. }
  183. return (0);
  184. }
  185. s_int8 animation::save (string fname) const
  186. {
  187. ogzstream file (fname);
  188. u_int8 retvalue;
  189. if (!file.is_open ())
  190. return (-1);
  191. retvalue = put (file);
  192. file.close ();
  193. return (retvalue);
  194. }
  195. s_int8 animation::insert_image (const image * im, u_int16 pos)
  196. {
  197. vector <image *>::iterator i;
  198. vector <animationframe>::iterator j;
  199. if (pos > nbr_of_images ())
  200. return -2;
  201. i = t_frame.begin ();
  202. while (pos--)
  203. i++;
  204. t_frame.insert (i, (image *) im);
  205. for (j = frame.begin (); j != frame.end (); j++)
  206. if (j->image_nbr () >= pos)
  207. j->set_image_nbr (j->image_nbr () + 1);
  208. return 0;
  209. }
  210. s_int8 animation::delete_image (u_int16 pos)
  211. {
  212. vector <image *>::iterator i;
  213. vector <animationframe>::iterator j;
  214. if (pos > nbr_of_images () - 1)
  215. return -2;
  216. i = t_frame.begin ();
  217. while (pos--)
  218. i++;
  219. delete (*i);
  220. t_frame.erase (i);
  221. for (j = frame.begin (); j != frame.end (); j++)
  222. if (j->image_nbr () >= pos)
  223. j->set_image_nbr (j->image_nbr () - 1);
  224. return 0;
  225. }
  226. s_int8 animation::insert_frame (const animationframe af, u_int16 pos)
  227. {
  228. vector <animationframe>::iterator i;
  229. if (pos > nbr_of_frames ())
  230. return -2;
  231. i = frame.begin ();
  232. while (pos--)
  233. i++;
  234. frame.insert (i, af);
  235. for (i = frame.begin (); i != frame.end (); i++)
  236. if (i->nextframe () >= pos)
  237. i->set_nextframe (i->nextframe () + 1);
  238. return 0;
  239. }
  240. s_int8 animation::delete_frame (u_int16 pos)
  241. {
  242. vector <animationframe>::iterator i;
  243. if (pos > nbr_of_frames () - 1)
  244. return -2;
  245. for (i = frame.begin (); i != frame.end (); i++)
  246. if (i->nextframe () >= pos)
  247. i->set_nextframe (frame[i->nextframe ()].nextframe ());
  248. i = frame.begin ();
  249. while (pos--)
  250. i++;
  251. frame.erase (i);
  252. if (!nbr_of_frames ())
  253. currentframe_ = 0;
  254. return 0;
  255. }
  256. void animation::zoom (u_int16 sx, u_int16 sy, const animation * src)
  257. {
  258. static u_int16 i;
  259. clear ();
  260. for (i = 0; i < src->nbr_of_images (); i++)
  261. {
  262. image *im = new image;
  263. im->resize ((src->t_frame[i]->length () * sx) / src->length (),
  264. (src->t_frame[i]->height () * sy) / src->height ());
  265. im->zoom ((*src->t_frame[i]));
  266. t_frame.push_back (im);
  267. }
  268. for (i = 0; i < src->nbr_of_frames (); i++)
  269. {
  270. frame.push_back (src->frame[i]);
  271. frame.back ().set_offset ((src->frame[i].offx () * sx) / src->length (),
  272. (src->frame[i].offy () * sy) / src->height ());
  273. }
  274. }
  275. animation& animation::operator = (const animation & src)
  276. {
  277. clear ();
  278. (drawable&) (*this) = (drawable&) src;
  279. // Copy images
  280. vector <image *>::iterator imit;
  281. for (imit = src.t_frame.begin (); imit != src.t_frame.end (); imit++)
  282. {
  283. image * im = new image;
  284. *im = *(*imit);
  285. t_frame.push_back (im);
  286. }
  287. // Copy frames
  288. vector <animationframe>::iterator frit;
  289. for (frit = src.frame.begin (); frit != src.frame.end (); frit++)
  290. {
  291. frame.push_back (*frit);
  292. }
  293. // Copy properties
  294. currentframe_ = src.currentframe_;
  295. speedcounter = src.speedcounter;
  296. play_flag = src.play_flag;
  297. set_length (src.length ());
  298. set_height (src.height ());
  299. set_offset (src.xoffset (), src.yoffset ());
  300. return *this;
  301. }
  302. // Private methods
  303. void animation::calculate_dimensions ()
  304. {
  305. for (u_int16 i = 0; i < nbr_of_frames (); i++)
  306. {
  307. u_int16 tl, th;
  308. if ((tl =
  309. t_frame[frame[i].image_nbr ()]->length () + frame[i].offx ()) >
  310. length ())
  311. set_length (tl + xoffset ());
  312. if ((th =
  313. t_frame[frame[i].image_nbr ()]->height () + frame[i].offy ()) >
  314. height ())
  315. set_height (th + yoffset ());
  316. }
  317. }