00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
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
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';
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
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)
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)
00384 {
00385 SDL_FreeSurface(image);
00386 image=NULL;
00387 }
00388
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 }