Adonthell 0.4
|
00001 // $Id: animation.cc,v 1.10 2002/06/28 12:15:20 gnurou Exp $ 00002 00003 /* 00004 Copyright (C) 1999/2000/2001 The Adonthell Project 00005 Part of the Adonthell Project http://adonthell.linuxgames.com 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License. 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY. 00011 See the COPYING file for more details. 00012 00013 This file is a part of the Adonthell project. 00014 */ 00015 00016 00017 00018 /** 00019 * @file animation.cc 00020 * @author Alexandre Courbot <alexandrecourbot@linuxgames.com> 00021 * 00022 * @brief Defines the animationframe and animation classes. 00023 * 00024 * 00025 */ 00026 00027 00028 #include "animation.h" 00029 00030 00031 using namespace std; 00032 00033 00034 00035 // animationframe class. 00036 00037 00038 // Public methods. 00039 00040 00041 animationframe::animationframe () 00042 { 00043 clear (); 00044 } 00045 00046 animationframe::~animationframe () 00047 { 00048 } 00049 00050 void animationframe::clear () 00051 { 00052 imagenbr = 0; 00053 is_masked_ = false; 00054 set_alpha (255); 00055 gapx = 0; 00056 gapy = 0; 00057 delay_ = 0; 00058 nextframe_ = 0; 00059 } 00060 00061 s_int8 animationframe::get (igzstream& file) 00062 { 00063 imagenbr << file; 00064 is_masked_ << file; 00065 alpha_ << file; 00066 set_alpha (alpha_); 00067 gapx << file; 00068 gapy << file; 00069 delay_ << file; 00070 nextframe_ << file; 00071 00072 return (0); 00073 } 00074 00075 s_int8 animationframe::put (ogzstream& file) const 00076 { 00077 image_nbr () >> file; 00078 is_masked () >> file; 00079 alpha () >> file; 00080 offx () >> file; 00081 offy () >> file; 00082 delay () >> file; 00083 nextframe () >> file; 00084 00085 return (0); 00086 } 00087 00088 00089 00090 00091 // animation class. 00092 00093 00094 // Public methods. 00095 00096 00097 animation::animation () : drawable () 00098 { 00099 clear (); 00100 } 00101 00102 void animation::clear () 00103 { 00104 vector <image *>::iterator i; 00105 for (i = t_frame.begin (); i != t_frame.end (); i++) 00106 delete (*i); 00107 t_frame.clear (); 00108 frame.clear (); 00109 currentframe_ = 0; 00110 speedcounter = 0; 00111 play_flag = STOP; 00112 xoffset_ = 0; 00113 yoffset_ = 0; 00114 set_length (0); 00115 set_height (0); 00116 } 00117 00118 animation::~animation () 00119 { 00120 clear (); 00121 } 00122 00123 00124 bool animation::update () 00125 { 00126 if ((!play_flag) || (!nbr_of_frames ())) 00127 return true; 00128 if (frame[currentframe ()].delay () == 0) 00129 return true; 00130 if (nbr_of_frames () <= 1) 00131 return true; 00132 00133 speedcounter++; 00134 if (speedcounter >= frame[currentframe ()].delay ()) 00135 next_frame (); 00136 00137 return true; 00138 } 00139 00140 void animation::next_frame () 00141 { 00142 currentframe_ = frame[currentframe ()].nextframe (); 00143 speedcounter = 0; 00144 } 00145 00146 void animation::draw (s_int16 x, s_int16 y, const drawing_area * da_opt, 00147 surface *target) const 00148 { 00149 t_frame[frame[currentframe ()].image_nbr ()]-> 00150 set_mask (frame[currentframe ()].is_masked ()); 00151 t_frame[frame[currentframe ()].image_nbr ()]-> 00152 set_alpha (frame[currentframe ()].alpha ()); 00153 00154 t_frame[frame[currentframe ()].image_nbr ()]->draw (x + xoffset () + 00155 frame[currentframe ()].offx (), 00156 y + yoffset () + frame[currentframe ()].offy (), da_opt, 00157 target); 00158 } 00159 00160 s_int8 animation::get (igzstream& file) 00161 { 00162 u_int16 i; 00163 u_int16 nbr_images; 00164 u_int16 nbr_frames; 00165 u_int16 t_xoffset, t_yoffset; 00166 00167 clear (); 00168 00169 t_xoffset << file; 00170 t_yoffset << file; 00171 00172 00173 // TODO: Remove this! (length and height are calculated later) 00174 u_int16 dummy; 00175 dummy << file; 00176 dummy << file; 00177 00178 // Read images 00179 nbr_images << file; 00180 for (i = 0; i < nbr_images; i++) 00181 { 00182 t_frame.push_back (new image); 00183 t_frame.back ()->get_raw (file); 00184 } 00185 00186 // Read frames 00187 nbr_frames << file; 00188 animationframe aftemp; 00189 00190 for (i = 0; i < nbr_frames; i++) 00191 { 00192 frame.push_back (aftemp); 00193 frame.back ().get (file); 00194 } 00195 00196 currentframe_ = 0; 00197 00198 set_offset (t_xoffset, t_yoffset); 00199 00200 calculate_dimensions (); 00201 00202 return (0); 00203 } 00204 00205 s_int8 animation::load (string fname) 00206 { 00207 igzstream file (fname); 00208 u_int8 retvalue; 00209 00210 if (!file.is_open ()) 00211 return (-1); 00212 retvalue = get (file); 00213 file.close (); 00214 return (retvalue); 00215 } 00216 00217 s_int8 animation::put (ogzstream& file) const 00218 { 00219 u_int16 i; 00220 00221 xoffset () >> file; 00222 yoffset () >> file; 00223 00224 00225 // TODO: Remove this! (length and height are calculated later) 00226 u_int16 dummy = 0; 00227 dummy >> file; 00228 dummy >> file; 00229 00230 // Write images 00231 nbr_of_images () >> file; 00232 00233 for (i = 0; i < nbr_of_images (); i++) 00234 { 00235 t_frame[i]->put_raw (file); 00236 } 00237 00238 // Write frames 00239 nbr_of_frames () >> file; 00240 00241 for (i = 0; i < nbr_of_frames (); i++) 00242 { 00243 frame[i].put (file); 00244 } 00245 00246 return (0); 00247 } 00248 00249 s_int8 animation::save (string fname) const 00250 { 00251 ogzstream file (fname); 00252 u_int8 retvalue; 00253 00254 if (!file.is_open ()) 00255 return (-1); 00256 retvalue = put (file); 00257 file.close (); 00258 return (retvalue); 00259 } 00260 00261 s_int8 animation::insert_image (const image * im, u_int16 pos) 00262 { 00263 vector <image *>::iterator i; 00264 vector <animationframe>::iterator j; 00265 00266 if (pos > nbr_of_images ()) 00267 return -2; 00268 00269 i = t_frame.begin (); 00270 while (pos--) 00271 i++; 00272 00273 t_frame.insert (i, (image *) im); 00274 00275 for (j = frame.begin (); j != frame.end (); j++) 00276 if (j->image_nbr () >= pos) 00277 j->set_image_nbr (j->image_nbr () + 1); 00278 00279 return 0; 00280 } 00281 00282 s_int8 animation::delete_image (u_int16 pos) 00283 { 00284 vector <image *>::iterator i; 00285 vector <animationframe>::iterator j; 00286 00287 if (pos > nbr_of_images () - 1) 00288 return -2; 00289 00290 i = t_frame.begin (); 00291 while (pos--) 00292 i++; 00293 00294 delete (*i); 00295 t_frame.erase (i); 00296 00297 for (j = frame.begin (); j != frame.end (); j++) 00298 if (j->image_nbr () >= pos) 00299 j->set_image_nbr (j->image_nbr () - 1); 00300 00301 return 0; 00302 } 00303 00304 s_int8 animation::insert_frame (const animationframe af, u_int16 pos) 00305 { 00306 vector <animationframe>::iterator i; 00307 00308 if (pos > nbr_of_frames ()) 00309 return -2; 00310 00311 i = frame.begin (); 00312 while (pos--) 00313 i++; 00314 00315 frame.insert (i, af); 00316 00317 for (i = frame.begin (); i != frame.end (); i++) 00318 if (i->nextframe () >= pos) 00319 i->set_nextframe (i->nextframe () + 1); 00320 00321 return 0; 00322 } 00323 00324 s_int8 animation::delete_frame (u_int16 pos) 00325 { 00326 vector <animationframe>::iterator i; 00327 00328 if (pos > nbr_of_frames () - 1) 00329 return -2; 00330 00331 for (i = frame.begin (); i != frame.end (); i++) 00332 if (i->nextframe () >= pos) 00333 i->set_nextframe (frame[i->nextframe ()].nextframe ()); 00334 00335 i = frame.begin (); 00336 while (pos--) 00337 i++; 00338 00339 frame.erase (i); 00340 00341 if (!nbr_of_frames ()) 00342 currentframe_ = 0; 00343 00344 return 0; 00345 } 00346 00347 void animation::zoom (u_int16 sx, u_int16 sy, const animation * src) 00348 { 00349 static u_int16 i; 00350 00351 clear (); 00352 for (i = 0; i < src->nbr_of_images (); i++) 00353 { 00354 image *im = new image; 00355 00356 im->resize ((src->t_frame[i]->length () * sx) / src->length (), 00357 (src->t_frame[i]->height () * sy) / src->height ()); 00358 im->zoom ((*src->t_frame[i])); 00359 t_frame.push_back (im); 00360 } 00361 00362 for (i = 0; i < src->nbr_of_frames (); i++) 00363 { 00364 frame.push_back (src->frame[i]); 00365 frame.back ().set_offset ((src->frame[i].offx () * sx) / src->length (), 00366 (src->frame[i].offy () * sy) / src->height ()); 00367 } 00368 } 00369 00370 animation& animation::operator = (const animation & src) 00371 { 00372 clear (); 00373 (drawable&) (*this) = (drawable&) src; 00374 00375 // Copy images 00376 vector <image *>::iterator imit; 00377 for (imit = src.t_frame.begin (); imit != src.t_frame.end (); imit++) 00378 { 00379 image * im = new image; 00380 *im = *(*imit); 00381 t_frame.push_back (im); 00382 } 00383 00384 // Copy frames 00385 vector <animationframe>::iterator frit; 00386 for (frit = src.frame.begin (); frit != src.frame.end (); frit++) 00387 { 00388 frame.push_back (*frit); 00389 } 00390 00391 // Copy properties 00392 currentframe_ = src.currentframe_; 00393 speedcounter = src.speedcounter; 00394 play_flag = src.play_flag; 00395 00396 set_length (src.length ()); 00397 set_height (src.height ()); 00398 set_offset (src.xoffset (), src.yoffset ()); 00399 return *this; 00400 } 00401 00402 00403 00404 // Private methods 00405 00406 00407 void animation::calculate_dimensions () 00408 { 00409 for (u_int16 i = 0; i < nbr_of_frames (); i++) 00410 { 00411 u_int16 tl, th; 00412 00413 if ((tl = 00414 t_frame[frame[i].image_nbr ()]->length () + frame[i].offx ()) > 00415 length ()) 00416 set_length (tl + xoffset ()); 00417 00418 if ((th = 00419 t_frame[frame[i].image_nbr ()]->height () + frame[i].offy ()) > 00420 height ()) 00421 set_height (th + yoffset ()); 00422 } 00423 }