home *** CD-ROM | disk | FTP | other *** search
/ Game.EXE 2002 May / Game.EXE_05_2002.iso / Alawar / Lib / 2D / Sequences.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2002-04-03  |  5.1 KB  |  204 lines

  1. #include "Sequences.h"
  2. #include "Scene2D.h"
  3. #include <AutoPtr.h>
  4. #include <Log/LogPtr.h>
  5. #include <Color.h>
  6. #include <Format/PictureFormatManager.h>
  7. #include "HardwarePicture2D.h"
  8. #include <algorithm>
  9. #include <safe_new.h>
  10.  
  11. void Sequences::Sequence::render_frame(Scene2D * scene, int fr, int alpha)const
  12. {
  13.     if( fr >= 0 && fr < frames.size() )
  14.         scene->blit( frames[fr].ha, alpha );
  15. }
  16. int Sequences::Sequence::get_width(int fr)const
  17. {
  18.     return (fr < 0 || fr >= frames.size()) ? 0 : frames[fr].width;
  19. }
  20. int Sequences::Sequence::get_height(int fr)const
  21. {
  22.     return (fr < 0 || fr >= frames.size()) ? 0 : frames[fr].height;
  23. }
  24. float Sequences::Sequence::get_duration(int fr)const
  25. {
  26.     return (fr < 0 || fr >= frames.size()) ? 1 : frames[fr].duration;
  27. }
  28. int Sequences::Sequence::get_frame_count()const
  29. {
  30.     return frames.size();
  31. }
  32.  
  33. std::list<Sequences *> * Sequences::sequences;
  34. int Sequences::counter = 0;
  35.  
  36. class SequncesEqPred
  37. {
  38.     const String & name;
  39. public:
  40.     SequncesEqPred(const String & name)
  41.         :    name( name )
  42.     {}
  43.     bool operator()(const Sequences * seq)
  44.     {
  45.         return seq->get_name() == name;
  46.     }
  47. };
  48.  
  49. int Sequences::cached_count()
  50. {
  51.     return sequences ? sequences->size() : 0;
  52. }
  53.  
  54. void Sequences::unload(const Sequences * seq)
  55. {
  56.     if( !sequences )
  57.     {
  58.         LogPtr()->error( String("in Sequences::unload() sequences table is already destroyed") );
  59.         return;
  60.     }
  61.     std::list<Sequences *>::iterator it = std::find( sequences->begin(), sequences->end(), seq );
  62.     if( it == sequences->end() )
  63.     {
  64.         LogPtr()->warning( String("in Sequences::unload() <") + seq->get_name() + String("> not found") );
  65.         return;
  66.     }
  67.     if( --(*it)->ref_count == 0 )
  68.     {
  69.         delete *it; *it = 0;
  70.         it = sequences->erase( it );
  71.     }
  72.     if( --counter == 0 )
  73.     {
  74.         delete sequences; sequences = 0;
  75.     }
  76. }
  77.  
  78. const Sequences * Sequences::load(const String & name, Scene2D * scene)
  79. {
  80.     if( ++counter == 1 )
  81.     {
  82.         if( sequences )
  83.         {
  84.             LogPtr()->error( String("in Sequences::load() sequences table is already created") );
  85.         }
  86.         else
  87.         {
  88.             sequences = new std::list<Sequences *>;
  89.         }
  90.     }
  91.     std::list<Sequences *>::iterator it = std::find_if( sequences->begin(), sequences->end(), SequncesEqPred( name ) );
  92.     if( it == sequences->end() )
  93.         it = sequences->insert( sequences->end(), new Sequences( name, scene ) );
  94.     ++(*it)->ref_count;
  95.     return *it;
  96. }
  97.  
  98. Sequences::Sequences(const String & name, Scene2D * scene)
  99. :    name( name ),
  100.     scene( scene ),
  101.     ref_count( 0 )
  102. {
  103.     AutoPtr<PictureFormat> pic = PictureFormatManager::create_format( name );
  104.     if( pic )
  105.     {
  106.         const Color * separator = pic->colors() + pic->get_shift( pic->width()-1, 0 );
  107.  
  108.         int start_y = 0;
  109.         int end_y;
  110.         do
  111.         {
  112.             const Color * cc = pic->colors() + pic->get_shift(0, start_y );
  113.             while( start_y < pic->height() && *cc == *separator )
  114.             {
  115.                 ++start_y;
  116.                 cc += pic->width();
  117.             }
  118.             end_y = start_y;
  119.             while( end_y < pic->height() && *cc != *separator )
  120.             {
  121.                 ++end_y;
  122.                 cc += pic->width();
  123.             }
  124.             if( end_y != start_y )
  125.             {
  126.                 data.push_back( Sequence() );
  127.                 int start_x = 0;
  128.                 int end_x;
  129.                 do
  130.                 {
  131.                     const Color * cc = pic->colors() + pic->get_shift( start_x, start_y );
  132.                     while( start_x < pic->width() && *cc == *separator )
  133.                     {
  134.                         ++start_x;
  135.                         ++cc;
  136.                     }
  137.                     end_x = start_x;
  138.                     while( end_x < pic->width() && *cc != *separator )
  139.                     {
  140.                         ++end_x;
  141.                         ++cc;
  142.                     }
  143.                     if( end_x != start_x )
  144.                     {
  145.                         // Found a frame
  146.                         const Color * address = pic->colors() + pic->get_shift( start_x, start_y );
  147.                         int sx = end_x - start_x;
  148.                         int sy = end_y - start_y;
  149.                         HardwarePicture2D * ha = scene->load_picture(
  150.                                 address, sx, sy, pic->width() );
  151.                         data.back().frames.push_back( Frame( 0.2f, sx, sy, ha ) );
  152.                     }
  153.                     start_x = end_x;
  154.                 }while( start_x < pic->width() );
  155.             }
  156.             start_y = end_y;
  157.         }while( start_y < pic->height() );
  158.     }
  159.     if( data.empty() )
  160.     {
  161.         Color dummy[4] = { Color(255,0,0), Color(0,255,0), Color(0,255,0), Color(255,0,0) };
  162.         data.push_back( Sequence() );
  163.         HardwarePicture2D * ha = scene->load_picture(
  164.                             dummy, 2, 2, 2 );
  165.         data[0].frames.push_back( Frame( 0.5f, 2, 2, ha ) );
  166.     }
  167. }
  168.  
  169. Sequences::~Sequences()
  170. {
  171.     for( int s = 0; s < data.size(); ++s )
  172.         for( int f = 0; f < data[s].frames.size(); ++f )
  173.         {
  174.             delete data[s].frames[f].ha; data[s].frames[f].ha = 0;
  175.         }
  176. }
  177.  
  178. int Sequences::get_frame_count(int seq)const
  179. {
  180.     return (seq < 0 || seq >= data.size()) ? 0 : data[seq].get_frame_count();
  181. }
  182. int Sequences::get_height(int seq, int fr)const
  183. {
  184.     return (seq < 0 || seq >= data.size()) ? 0 : data[seq].get_height( fr );
  185. }
  186. int Sequences::get_sequence_count()const
  187. {
  188.     return data.size();
  189. }
  190. int Sequences::get_width(int seq, int fr )const
  191. {
  192.     return (seq < 0 || seq >= data.size()) ? 0 : data[seq].get_width( fr );
  193. }
  194. void Sequences::render_frame(int seq, int fr, int alpha)const
  195. {
  196.     if( seq >= 0 && seq < data.size() )
  197.         data[seq].render_frame( scene, fr, alpha );
  198. }
  199.  
  200. float Sequences::get_duration(int seq, int fr)const
  201. {
  202.     return (seq < 0 || seq >= data.size()) ? 1.0 : data[seq].get_duration( fr );
  203. }
  204.