vgafile.h

Go to the documentation of this file.
00001 /*
00002  *  vgafile.h - Handle access to one of the xxx.vga files.
00003  *
00004  *  Copyright (C) 1999  Jeffrey S. Freedman
00005  *  Copyright (C) 2000-2001  The Exult Team
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 as published by
00009  *  the Free Software Foundation; either version 2 of the License, or
00010  *  (at your option) any later version.
00011  *
00012  *  This program is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *  GNU General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU General Public License
00018  *  along with this program; if not, write to the Free Software
00019  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00020  */
00021 
00022 #ifndef VGAFILE_H
00023 #define VGAFILE_H 1
00024 
00025 
00026 #include <fstream>
00027 #include <iostream>
00028 #include <cassert>
00029 #include "exult_types.h"
00030 #include "imagebuf.h"
00031 
00032 class DataSource;
00033 class StreamDataSource;
00034 class Shape;
00035 class Image_buffer8;
00036 class GL_texshape;
00037 class GL_manager;
00038 
00039 #ifdef HAVE_OPENGL
00040 #include "glshape.h"
00041 
00042 #define GLRENDER  if (glman) glman->paint(this, px, py); else
00043 #define GLRENDERTRANS if (glman) glman->paint(this, px, py, xforms, xfcnt); \
00044                 else
00045 #define GLOUTLINE if (glman) ; else
00046 #else
00047 #define GLRENDER
00048 #define GLRENDERTRANS
00049 #define GLOUTLINE
00050 #endif
00051 
00052 /*
00053  *  A shape from "shapes.vga":
00054  */
00055 class Shape_frame
00056   {
00057   bool rle;     // Run-length encoded.
00058   unsigned char *data;    // The actual data.
00059   int datalen;
00060   short xleft;      // Extent to left of origin.
00061   short xright;     // Extent to right.
00062   short yabove;     // Extent above origin.
00063   short ybelow;     // Extent below origin.
00064 #ifdef HAVE_OPENGL
00065   GL_texshape *glshape;   // OpenGL texture for painting this.
00066 #endif
00067   static GL_manager *glman; // One to rule them all.
00068   static Image_buffer8 *scrwin; // Screen window to render to.
00069 
00070   Shape_frame *reflect();   // Create new frame, reflected.
00071           // Create RLE data & store in frame.
00072   void create_rle(unsigned char *pixels, int w, int h);
00073           // Create from RLE entry.
00074   void get_rle_shape(DataSource* shapes, long filepos, long len);
00075   
00076 public:
00077   friend class Game_window;
00078   friend class Shape_manager;
00079   friend class Shape;
00080   friend class Shape_file;
00081   friend class GL_texshape;
00082   friend class GL_manager;
00083   Shape_frame() : data(0), datalen(0)
00084 #ifdef HAVE_OPENGL
00085     , glshape(0)
00086 #endif
00087     {  }
00088           // Create frame from data.
00089   Shape_frame(unsigned char *pixels, int w, int h, int xoff, int yoff,
00090                 bool setrle);
00091   static void set_to_render(Image_buffer8 *w, GL_manager *gl = 0)
00092     { scrwin = w; glman = gl; }
00093   unsigned char *get_data() { return data; }
00094   bool is_rle() const { return rle; }
00095           // Convert raw image to RLE.
00096   static unsigned char *encode_rle(unsigned char *pixels, int w, int h,
00097           int xoff, int yoff, int& datalen);
00098           // Read in shape/frame.
00099   unsigned char read(DataSource* shapes, uint32 shapeoff,
00100           uint32 shapelen, int frnum);
00101           // Paint into given buffer.
00102   void paint_rle(Image_buffer8 *win, int px, int py);
00103   void paint(Image_buffer8 *win, int px, int py);
00104   void paint_rle_translucent(Image_buffer8 *win, int px, int py,
00105           Xform_palette *xforms, int xfcnt);
00106   void paint_rle_transformed(Image_buffer8 *win, int px, int py,
00107           Xform_palette& xform);
00108   void paint_rle_outline(Image_buffer8 *win, int px, int py,
00109               unsigned char color);
00110           // Paint to screen.
00111   void paint_rle(int px, int py)
00112     { GLRENDER  paint_rle(scrwin, px, py); }
00113   void paint(int px, int py)
00114     { GLRENDER  paint(scrwin, px, py); }
00115           // ++++++GL versions of these needed:
00116   void paint_rle_translucent(int px, int py,
00117           Xform_palette *xforms, int xfcnt)
00118     { GLRENDERTRANS  paint_rle_translucent(
00119           scrwin, px, py, xforms, xfcnt); }
00120   void paint_rle_transformed(int px, int py, Xform_palette& xform)
00121     { GLRENDER  paint_rle_transformed(scrwin, px, py, xform); }
00122   void paint_rle_outline(int px, int py, unsigned char color)
00123     { GLOUTLINE  paint_rle_outline(scrwin, px, py, color); }
00124 
00125   int has_point(int x, int y);  // Is a point within the shape?
00126   int get_width() const   // Get dimensions.
00127     { return xleft + xright + 1; }
00128   int get_height() const
00129     { return yabove + ybelow + 1; }
00130   int get_xleft()
00131     { return xleft; }
00132   int get_xright()
00133     { return xright; }
00134   int get_yabove()
00135     { return yabove; }
00136   int get_ybelow()
00137     { return ybelow; }
00138   void set_offset(int new_xright, int new_ybelow);
00139   int get_size()
00140     { return datalen; }
00141   int is_empty()
00142     { return data[0] == 0 && data[1] == 0; }
00143   virtual ~Shape_frame()
00144     { delete [] data; }
00145   };
00146 
00147 /*
00148  *  A shape from a .vga file consists of one of more frames.
00149  */
00150 class Shape
00151   {
00152 protected:
00153   Shape_frame **frames;   // List of ->'s to frames.
00154   unsigned char frames_size;  // Size of 'frames' (incl. reflects).
00155   unsigned char num_frames; // # of frames (not counting reflects).
00156           // Create reflected frame.
00157   Shape_frame *reflect(DataSource* shapes, int shnum, int frnum);
00158   void enlarge(int newsize);  // Increase 'frames'.
00159   void create_frames_list(int nframes);
00160           // Read in shape/frame.
00161   Shape_frame *read(DataSource* shapes, int shnum, int frnum, 
00162     DataSource *shapes2 = 0, int count1 = -1, int count2 = -1);
00163           // Store shape that was read.
00164   Shape_frame *store_frame(Shape_frame *frame, int framenum);
00165 public:
00166   friend class Vga_file;
00167   
00168   Shape() : frames(0), frames_size(0), num_frames(0)
00169     {  }
00170   Shape(Shape_frame* fr);
00171   Shape(int n);     // Create with given #frames. 
00172   virtual ~Shape();
00173   void reset();
00174   void take(Shape *s2);   // Take frames from another shape.
00175   void load(DataSource* shape_source);
00176   void write(std::ostream& out);  // Write out.
00177   Shape_frame *get(DataSource* shapes, int shnum, int frnum, 
00178     DataSource *shapes2 = 0, int count1 = -1, int count2 = -1)
00179     { 
00180     return (frames && frnum < frames_size && frames[frnum]) ? 
00181       frames[frnum] : 
00182       read(shapes, shnum, frnum, shapes2, count1, count2); 
00183     }
00184   int get_num_frames()
00185     { return num_frames; }
00186   Shape_frame *get_frame(int framenum)
00187     { return 0 <= framenum && framenum < frames_size 
00188             ? frames[framenum] : 0L; }
00189   void resize(int newsize); // Modify #frames.
00190           // Set frame.
00191   void set_frame(Shape_frame *f, int framenum);
00192           // Add/insert frame.
00193   void add_frame(Shape_frame *f, int framenum);
00194   void del_frame(int framenum);
00195   };
00196 
00197 /*
00198  *  A shape file just has one shape with multiple frames.  They're all
00199  *  read in during construction.
00200  */
00201 class Shape_file : public Shape
00202   {
00203 public:
00204   Shape_file(const char *nm);
00205   Shape_file(Shape_frame *fr): Shape(fr) {}
00206   Shape_file(DataSource* shape_source);
00207   Shape_file();
00208   virtual ~Shape_file() {}
00209   void load(const char *nm);
00210   void load(DataSource* shape_source)
00211     { Shape::load(shape_source); }
00212   int get_size();
00213   void save(DataSource* shape_source);
00214   };
00215 
00216 /*
00217  *  A class for accessing any .vga file:
00218  */
00219 class Vga_file
00220   {
00221   std::ifstream file;
00222   DataSource *shape_source;
00223   std::ifstream file2;
00224   DataSource *shape_source2;
00225   int u7drag_type;    // # from u7drag.h, or -1.
00226   bool flex;      // This is the normal case (all .vga
00227           //   files).  If false, file is a
00228           //   single shape, like 'pointers.shp'.
00229           // In this case, all frames are pre-
00230           //   loaded.
00231 protected:
00232   int num_shapes;     // Total # of shapes.
00233   int num_shapes1;    // Total # of shapes in file 1.
00234   int num_shapes2;    // Total # of shapes in file 2.
00235   Shape *shapes;      // List of ->'s to shapes' lists
00236 public:
00237   Vga_file(const char *nm, int u7drag = -1, const char *nm2 = 0);
00238   Vga_file();
00239   int get_u7drag_type() const
00240     { return u7drag_type; }
00241   void load(const char *nm, const char *nm2 = 0);
00242   void reset();
00243   virtual ~Vga_file();
00244   int get_num_shapes() const
00245   { return num_shapes>num_shapes2?num_shapes:num_shapes2; }
00246   int is_good() const
00247     { return shapes != 0; }
00248   bool is_flex() const
00249     { return flex; }
00250           // Get shape.
00251   Shape_frame *get_shape(int shapenum, int framenum = 0)
00252     {
00253     assert(shapes!=0);  // Because if shapes is NULL
00254           // here, we won't die on the deref
00255           // but we will return rubbish.
00256     // I've put this assert in _before_ you know...
00257     // So this isn't the first time we've had trouble here
00258     Shape_frame *r=(shapes[shapenum].get(shape_source, shapenum, 
00259       framenum, shape_source2, num_shapes1, num_shapes2));
00260 #if 0 /* Occurs normally in ExultStudio. */
00261     if(!r)
00262       {
00263 #ifdef DEBUG
00264         std::cerr << "get_shape(" <<
00265           shapenum << "," <<
00266           framenum << ") -> NULL" << std::endl;
00267 #endif
00268       }
00269 #endif
00270     return r;
00271     }
00272     
00273   Shape *extract_shape(int shapenum)
00274     {
00275     assert(shapes!=0);
00276     // Load all frames into memory
00277     int count = get_num_frames(shapenum);
00278     for(int i=1; i<count; i++)
00279       get_shape(shapenum, i);
00280     return shapes+shapenum;
00281     }
00282           // Get # frames for a shape.
00283   int get_num_frames(int shapenum)
00284     {
00285     get_shape(shapenum, 0); // Force it into memory.
00286     return shapes[shapenum].num_frames;
00287     }
00288   Shape *new_shape(int shapenum); // Create new shape (or del old).
00289   };
00290   
00291 #endif  /* VGAFILE_H */

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