Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

spriteloader.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                           spriteloader.cpp  -  description
00003                              -------------------
00004     begin                : Thu Apr 10 2003
00005     copyright            : (C) 2003 by Tyler Montbriand
00006     email                : tsm@accesscomm.ca
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU General Public License as published by  *
00013  *   the Free Software Foundation; either version 2 of the License, or     *
00014  *   (at your option) any later version.                                   *
00015  *                                                                         *
00016  ***************************************************************************/
00023 
00024 #include <stdio.h>
00025 #include <ctype.h>
00026 #include "toyparse.h"
00027 #include "sprite.h"
00028 #include "spriteloader.h"
00029 
00030 extern "C" int isblankstr(const char *str);
00031 
00033 const char *Type_Param[]  ={  "IMAGE"       ,
00034                               "FRAMES"      ,
00035                               "FRAMERATE"   ,
00036                               "DRAWLAYER"   ,
00037                               "COLLAYER"    ,
00038                               "TRANSCOLOR"  ,
00039                               "BITMASK"     ,
00040                               NULL            };
00042 const char *Type_Comment[]={ "#", "#%s", NULL};                              
00044 const char *Type_Integer[]={  "%u",   NULL    };
00046 const char *Type_String[] ={  "\"%s", NULL    };
00048 const char **Types[]      ={  Type_Comment  ,
00049                               Type_Param    ,
00050                               Type_Integer  ,
00051                               Type_String   ,
00052                               NULL            };
00053 
00054 typedef enum SpriteLoaderTypes
00055 {
00056   SLT_COMMENT = 0 ,
00057   SLT_PARAM       ,
00058   SLT_INTEGER     ,
00059   SLT_STRING
00060 } SpriteLoaderTypes;
00061 
00062 typedef enum SpriteParam
00063 {
00064   SP_IMAGE=0    ,
00065   SP_FRAME      ,
00066   SP_FRAMERATE  ,
00067   SP_DRAWLAYER  ,
00068   SP_COLLAYER   ,
00069   SP_TRANSCOLOR ,
00070   SP_BITMASK  
00071 } SpriteParam;
00072 
00073 SpriteLoader::SpriteLoader()
00074 {
00075   r=b=244;
00076   g=0;
00077   xframes=yframes=0;
00078   framerate=0;
00079   bmask=NULL;
00080   image=NULL;
00081   drawlayer=colindex=colmask=0;
00082   good=loadbitmask=false;
00083   imagename[0]='\0';
00084 }
00085 
00091 bool SpriteLoader::ProcessLine(const char *buf)
00092 {
00093   TokenType *tokens=NULL;
00094 
00095   if(isblankstr(buf))
00096     return(true);
00097 
00098   tokens=LineToTypes(buf,Types);
00099   if(tokens==NULL)
00100     return(true);
00101 
00102   switch(tokens[0].type)
00103   {
00104   case SLT_PARAM:
00105     switch(tokens[0].subtype)
00106     {
00107     int val;
00108     case SP_BITMASK:
00109       loadbitmask=true;
00110       break;
00111       
00112     case SP_TRANSCOLOR:
00113       if(CheckLineSyntax(tokens+1,SLT_INTEGER,-1,SLT_INTEGER,-1,
00114                                   SLT_INTEGER,-1,TYPE_ENDCLOSE)<0)
00115         return(false);
00116 
00117       if(sscanf(tokens[1].token,"%d",&r)!=1) return(false);
00118       if(sscanf(tokens[2].token,"%d",&g)!=1) return(false);
00119       if(sscanf(tokens[3].token,"%d",&b)!=1) return(false);
00120       
00121       r&=0xff;
00122       g&=0xff;
00123       b&=0xff;
00124       break;
00125       
00126     case SP_DRAWLAYER:
00127       if(CheckLineSyntax(tokens+1,SLT_INTEGER,-1,TYPE_ENDCLOSE)<0)
00128         return(false);
00129 
00130       if(sscanf(tokens[1].token,"%d",&drawlayer)!=1) return(false);        
00131       break;
00132       
00133     case SP_COLLAYER:
00134       if(CheckLineSyntax(tokens+1,SLT_INTEGER,-1,SLT_INTEGER,-1,TYPE_ENDOPEN)<0)
00135         return(false);
00136       
00137       if(sscanf(tokens[1].token,"%d",&colindex)!=1) return(false);
00138 
00139       colindex=COL_LAYER(colindex);
00140       
00141       for(val=2; tokens[val].token!=NULL; val++)
00142       {
00143         int layer=0;
00144         if(sscanf(tokens[val].token,"%d",&layer)!=1)  return(false);
00145         colmask|=COL_LAYER(layer);
00146       }
00147 
00148       colindex&=0xff;
00149       break;
00150       
00151     case SP_FRAMERATE:
00152       if(CheckLineSyntax(tokens+1,SLT_INTEGER,-1,TYPE_ENDCLOSE)<0)
00153         return(false);
00154       
00155       if(sscanf(tokens[1].token,"%d",&framerate)!=1)  return false;
00156             
00157       break;
00158 
00159     case SP_IMAGE:
00160       if(CheckLineSyntax(tokens+1,SLT_STRING,-1,TYPE_ENDCLOSE)<0)
00161         return(false);
00162 
00163       if(sscanf(tokens[1].token+1,"%s",imagename)!=1) return false;
00164       break;
00165       
00166     case SP_FRAME:
00167       if(CheckLineSyntax(tokens+1,SLT_INTEGER,-1,SLT_INTEGER,-1,TYPE_ENDCLOSE)<0)
00168         return(false);
00169 
00170       if(sscanf(tokens[1].token,"%d",&xframes)!=1) return false;
00171       if(sscanf(tokens[2].token,"%d",&yframes)!=1) return false;
00172       break;
00173 
00174     default:
00175       return(false);
00176       break;
00177     }
00178     break;
00179 
00180   case SLT_COMMENT:
00181     break;
00182 
00183   default:
00184     return(false);
00185     break;
00186   }
00187 
00188   return(true);
00189 }
00190 
00194 SpriteLoader::SpriteLoader(const char *fname, const char *path)
00195 {
00196   r=b=244;
00197   g=0;
00198   xframes=yframes=0;
00199   framerate=0;
00200   bmask=NULL;
00201   image=NULL;
00202   drawlayer=colindex=colmask=0;
00203   good=loadbitmask=false;
00204   imagename[0]='\0';
00205   
00206   if(!SDL_WasInit(SDL_INIT_VIDEO))
00207   {
00208     if(SDL_Init(SDL_INIT_VIDEO)<0)
00209     {
00210       fprintf(stderr,"SpriteLoader::SpriteLoader(\"%s\",\"%s\")\n",fname,path);
00211       fprintf(stderr,"Couldn't initialize SDL video subsystem\n");
00212       return;
00213     }    
00214   }
00215   
00216   Load(fname,path);
00217 }
00221 SpriteLoader::~SpriteLoader()
00222 {
00223   Reset();
00224 }
00225 
00230 bool SpriteLoader::Good()
00231 {
00232   return(good);
00233 }
00234 
00239 Sprite *SpriteLoader::GetSprite(Sprite *sprite)
00240 {  
00241   if(!Good())
00242     return(NULL);
00243   
00244   if(sprite==NULL)
00245   {
00246     sprite=new Sprite();
00247     sprite->SetFlags(SPRITE_DELETEABLE);    
00248   }  
00249   
00250   sprite->Init_Surface(image,false);
00251   sprite->Init_Layers(drawlayer);  
00252   sprite->Init_Collision(colindex,colmask);
00253   sprite->Init_Frames(xframes,yframes);
00254   sprite->Init_Bitmask(loadbitmask,bmask);
00255   sprite->SetFrameRate(framerate);
00256   
00257   return(sprite);
00258 }
00259 
00263 extern "C" int isblankstr(const char *str)
00264 {
00265   int n=-1;
00266 
00267   if(str==NULL) return(1);
00268 
00269   for(n=0; str[n]!='\0'; n++)
00270   {
00271     if(!isspace(str[n]))
00272     {
00273       return(0);
00274     }
00275   }
00276 
00277   return(1);
00278 }
00279 
00283 bool SpriteLoader::Load(const char *fname, const char *path)
00284 {
00285   char buf[300];
00286   int line=0;
00287   FILE *fp=NULL;
00288   buf[0]='\0';
00289 
00290   Reset();
00291 
00292   SprMakePath(fname,path,buf);
00293   
00294   /* Attempt to open configuration file */
00295   fp=fopen(buf,"r");
00296   if(fp==NULL)
00297   {
00298     fprintf(stderr,"SpriteLoader::Load() - couldn't open \"%s\"\n",buf);
00299     return(false);
00300   }
00301 
00302   buf[0]='\0';  /* Clear buffer */
00303 
00304   while((fgets(buf,299,fp)!=NULL)&&(!feof(fp)))
00305   {
00306     line++;
00307     if(!ProcessLine(buf))
00308       fprintf(stderr,"Syntax error in line %d:  %s",line,buf);
00309 
00310     buf[0]='\0';
00311   }
00312 
00313   /* Minimum required parameter is image */
00314   if(!isblankstr(imagename))
00315   {
00316     char buf[300];
00317     SprMakePath(imagename,path,buf);
00318     image=LoadConvertBMP(buf,r,g,b);
00319         
00320     if(image==NULL)
00321     {
00322       fprintf(stderr,"Error!  Can't load %s\n",imagename);
00323       good=false;
00324       return(false);
00325     }
00326     
00327     good=true;
00328 
00329     if(loadbitmask)
00330     {
00331       int n=-1;
00332       Rect r(0,0,image->w/xframes,image->h/yframes);
00333             
00334       bmask=(bitmask **)malloc(sizeof(bitmask *)*xframes*yframes);
00335       for(n=0; n<(xframes*yframes); n++)
00336       {
00337         int xf=(n%xframes);
00338         int yf=(n/xframes)%yframes;
00339         r.x=xf*r.w;
00340         r.y=yf*r.h;
00341                 
00342         bmask[n]=MakeBitMask(image,r);
00343         
00344         if(bmask[n]==NULL)
00345           fprintf(stderr,"Warning!  Can't create bitmask for %s\n",imagename);
00346           
00347       }
00348     }
00349     else
00350     {
00351       bmask=NULL;
00352     }
00353   }  
00354   else
00355   {
00356     fprintf(stderr,"Error!  Can't load %s\n",fname);
00357     good=false;
00358   }
00359 
00360   return(good);
00361 }
00362 
00366 void SpriteLoader::Reset()
00367 {
00368   if(bmask!=NULL) /* Free collision bitmasks  */
00369   {
00370     int n;
00371     for(n=0; n<(xframes*yframes); n++)
00372     {
00373       if(bmask[n]!=NULL)
00374       {
00375         bitmask_free(bmask[n]);
00376         bmask[n]=NULL;
00377       }
00378     }
00379     free(bmask);
00380     bmask=NULL;
00381   }
00382 
00383   if(image!=NULL) /* Free image  */
00384   {
00385     SDL_FreeSurface(image);
00386     image=NULL;
00387   }
00388   /* Resets variables */
00389   r           =255;
00390   g           =  0;
00391   b           =255;
00392   xframes     =  1;
00393   yframes     =  1;
00394   drawlayer   =  0;
00395   colindex    =  0;
00396   colmask     =  0;
00397   framerate   =  0;
00398   imagename[0]='\0';
00399   good        =false;
00400   loadbitmask =false;
00401 }
00402 
00406 char lastchar(const char *str)
00407 {
00408   int len=0;
00409   if(str==NULL) return('\0');
00410 
00411   len=strlen(str);
00412   if(len==0) return('\0');
00413   else return(str[len-1]);  
00414 }
00415 
00419 char * SprMakePath(const char *filename, const char *path, char *buf)
00420 {
00421   char *slash=SLASH;
00422   if(buf==NULL) return(NULL);
00423   buf[0]='\0';
00424 
00425   if(path!=NULL)
00426   if(strlen(path))
00427   {
00428     strcpy(buf,path);
00429     if(lastchar(path)!=slash[0])  strcat(buf,SLASH);    
00430   }
00431 
00432   if(filename!=NULL)  strcat(buf,filename);
00433   
00434   return(buf);    
00435 }

Generated on Sat Oct 11 13:19:26 2003 for Spritelib by doxygen 1.3.4