playfli.cc

Go to the documentation of this file.
00001 
00007 /*
00008 Copyright (C) 2000  Tristan Tarrant
00009 
00010 This program is free software; you can redistribute it and/or
00011 modify it under the terms of the GNU General Public License
00012 as published by the Free Software Foundation; either version 2
00013 of the License, or (at your option) any later version.
00014 
00015 This program is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 GNU General Public License for more details.
00019 
00020 You should have received a copy of the GNU General Public License
00021 along with this program; if not, write to the Free Software
00022 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00023 */
00024 
00025 #ifdef HAVE_CONFIG_H
00026 #  include <config.h>
00027 #endif
00028 
00029 #ifndef ALPHA_LINUX_CXX
00030 #  include <cstring>
00031 #endif
00032 #include <iostream>
00033 #include "databuf.h"
00034 #include "playfli.h"
00035 #include "utils.h"
00036 #include "gamewin.h"
00037 #include "palette.h"
00038 
00039 #include "SDL_timer.h"
00040 
00041 #ifndef UNDER_CE
00042 using std::ifstream;
00043 using std::memset;
00044 using std::size_t;
00045 using std::cout;
00046 using std::endl;
00047 #endif
00048 
00049 playfli::playfli(const char *fli_name)
00050 {
00051   ifstream fli_stream; 
00052   U7open(fli_stream, fli_name);
00053   fli_data = new StreamDataSource(&fli_stream);
00054 
00055   initfli();
00056 }
00057 
00058 playfli::playfli(char *buffer, size_t len): fli_data(new BufferDataSource(buffer, len))
00059 {
00060   initfli();
00061 }
00062 
00063 void playfli::initfli()
00064 {
00065   fli_size = fli_data->read4();
00066   fli_magic = fli_data->read2();
00067   fli_frames = fli_data->read2();
00068   fli_width = fli_data->read2();
00069   fli_height = fli_data->read2();
00070   fli_depth = fli_data->read2();
00071   fli_flags = fli_data->read2();
00072   fli_speed = fli_data->read2();
00073   fli_buf =  NULL; 
00074   fli_data->skip(110);
00075   streampos = streamstart = fli_data->getPos();
00076   frame = 0;
00077   palette = new Palette;
00078   thispal = -1;
00079   nextpal = 0;
00080   changepal = false;
00081 }
00082 
00083 
00084 void playfli::info(fliinfo *fi)
00085 {
00086 #ifdef DEBUG
00087   cout << "Frame count : " << fli_frames << endl;
00088   cout << "Width :       " << fli_width << endl;
00089   cout << "Height :      " << fli_height << endl;
00090   cout << "Depth :       " << fli_depth << endl;
00091   cout << "Speed :       " << fli_speed << endl;
00092 #endif    
00093   if (fi)
00094   {
00095     fi->frames = fli_frames;
00096     fi->width = fli_width;
00097     fi->height = fli_height;
00098     fi->depth = fli_depth;
00099     fi->speed = fli_speed;
00100   }
00101 }
00102 
00103 int playfli::play(Image_window *win, int first_frame, int last_frame, unsigned long ticks, int brightness)
00104 {
00105   int frame_size;
00106   int frame_magic;
00107   int frame_chunks;
00108   int chunk_size;
00109   int chunk_type;
00110   unsigned char *pixbuf;
00111   int xoffset=(win->get_width()-fli_width)/2;
00112   int yoffset=(win->get_height()-fli_height)/2;
00113   bool dont_show = false;
00114 
00115   if (!fli_buf && win) fli_buf = win->create_buffer (fli_width, fli_height);
00116 
00117   // Set up last frame
00118   if (first_frame == last_frame) dont_show = true;
00119   if (first_frame < 0) first_frame += fli_frames;
00120   if (last_frame < 0) last_frame += 1 + fli_frames;
00121   if (first_frame == last_frame) last_frame++;
00122   if (last_frame < 0 || last_frame > fli_frames) last_frame = fli_frames;
00123 
00124   if (!ticks) ticks = SDL_GetTicks();
00125 
00126   if (first_frame < frame)
00127   {
00128     nextpal = 0;
00129     frame = 0;
00130     streampos = streamstart;
00131   }
00132   pixbuf = new unsigned char[fli_width];
00133 
00134   if (brightness != palette->get_brightness())
00135   {
00136     palette->set_brightness(brightness);
00137     changepal = true;
00138   }
00139 
00140   // Play frames...
00141   for ( ; frame < last_frame; frame++)
00142   {
00143     fli_data->seek(streampos);
00144     frame_size = fli_data->read4();
00145     frame_magic = fli_data->read2();
00146     frame_chunks = fli_data->read2();
00147     fli_data->skip(8);
00148     for (int chunk = 0; chunk < frame_chunks; chunk++)
00149     {
00150       chunk_size = fli_data->read4();
00151       chunk_type = fli_data->read2();
00152 
00153       switch (chunk_type)
00154       {
00155         case 11: {
00156         int packets = fli_data->read2();
00157         unsigned char colors[3 * 256];
00158 
00159         memset(colors, 0, 3 * 256);
00160         int current = 0;
00161 
00162         for (int p_count = 0; p_count < packets;
00163             p_count++)
00164         {
00165           int skip = fli_data->read1();
00166 
00167           current += skip;
00168           int change = fli_data->read1();
00169 
00170           if (change == 0)
00171               change = 256;
00172           fli_data->read((char*)&colors[current*3], change*3);
00173         }
00174         // Set palette
00175         palette->set_palette (colors);
00176         if (thispal != nextpal)
00177         {
00178           thispal = nextpal;
00179           changepal = true;
00180         }
00181         nextpal++;
00182 
00183         } break;
00184 
00185         case 12: {
00186 
00187         int skip_lines = fli_data->read2();
00188         int change_lines = fli_data->read2();
00189         for (int line = 0; line < change_lines; line++)
00190         {
00191           int packets = fli_data->read1();
00192           int pixpos = 0;
00193           for (int p_count = 0; p_count < packets;
00194               p_count++)
00195           {
00196             int skip_count = fli_data->read1();
00197             pixpos += skip_count;
00198             uint8 size_count = fli_data->read1();
00199             if (size_count > 127)
00200             {
00201               size_count = 256 - size_count;
00202               unsigned char data = fli_data->read1();
00203               memset(pixbuf, data, size_count);
00204               if (fli_buf) fli_buf->copy8(pixbuf,size_count,1,pixpos,skip_lines+line);
00205                 pixpos += size_count;
00206             
00207             }
00208             else
00209             {
00210               fli_data->read((char*)pixbuf, size_count);
00211               if (fli_buf) fli_buf->copy8(pixbuf,size_count,1,pixpos, skip_lines+line);
00212                 pixpos += size_count;
00213             }
00214           }
00215         }
00216 
00217         } break;
00218 
00219         case 13:
00220         break;
00221       
00222         case 15: {
00223         for (int line = 0; line < fli_height; line++)
00224         {
00225           int packets = fli_data->read1();
00226           int pixpos = 0;
00227           for (int p_count = 0; p_count < packets;
00228               p_count++)
00229           {
00230             char size_count = fli_data->read1();
00231             if (size_count > 0)
00232             {
00233               unsigned char data = fli_data->read1();
00234               memset(&pixbuf[pixpos], data, size_count);
00235               pixpos += size_count;
00236             } else {
00237               fli_data->read((char*)&pixbuf[pixpos],
00238                   -size_count);
00239               pixpos -= size_count;
00240             }
00241           }
00242           if (fli_buf) fli_buf->copy8(pixbuf,fli_width,1,0,line);
00243           }
00244         } break;
00245       
00246         case 16:
00247         fli_data->skip(fli_width * fli_height);
00248         break;
00249 
00250         default:
00251         cout << "UNKNOWN FLIC FRAME" << endl;
00252         break;
00253       }
00254     }
00255 
00256     streampos += frame_size;
00257 
00258     if (changepal) palette->apply(false);
00259     changepal = false;
00260 
00261     if (frame < first_frame)
00262       continue;
00263 
00264     // Speed related frame skipping detection
00265     int skip_frame = Game_window::get_instance()->get_frame_skipping() && SDL_GetTicks() >= ticks;
00266 
00267     if(win && fli_buf) win->put (fli_buf, xoffset, yoffset);
00268 
00269     while (SDL_GetTicks() < ticks) SDL_Delay(0);
00270   
00271     ticks += fli_speed*10;
00272 
00273     if(win && !dont_show && !skip_frame)
00274       win->show();
00275   }
00276 
00277   delete[] pixbuf;
00278 
00279   return ticks;
00280 }
00281 
00282 void playfli::put_buffer(Image_window *win)
00283 {
00284   int xoffset=(win->get_width()-fli_width)/2;
00285   int yoffset=(win->get_height()-fli_height)/2;
00286 
00287   if(win && fli_buf) win->put (fli_buf, xoffset, yoffset);
00288 }
00289 
00290 playfli::~playfli()
00291 {
00292   if (fli_buf) delete fli_buf;
00293   delete fli_data;
00294   delete palette;
00295 }

Generated on Mon Jul 9 14:42:45 2007 for ExultEngine by  doxygen 1.5.1