00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00024
00025
00026 #define USE_SDL_IMAGE
00027
00028 #include <malloc.h>
00029 #include "Fxp.h"
00030 #include "rect.h"
00031 #include "sprite.h"
00032 #include "bitmask.h"
00033
00038 Sprite::Sprite()
00039 {
00040 Init_List();
00041 Init_Flags();
00042 Init_Layers();
00043 Init_Surface();
00044 Init_Frames();
00045 Init_Collision();
00046 Init_Bitmask();
00047 }
00048
00049
00053 void Sprite::Event(int code, void *data1, void *data2)
00054 {
00055 }
00056
00061 Sprite *Sprite::Clone()
00062 {
00063 Sprite *spr=new Sprite();
00064
00065 (*spr)=(*this);
00066 spr->ClearFlags(SPRITE_OWNSURFACE|SPRITE_OWNBITMASK);
00067 return(spr);
00068 }
00069
00074 void Sprite::OnCollide(const Sprite *spr, ColType index)
00075 {
00076 }
00077
00083 int Sprite::GetFrame()
00084 {
00085 return(FROM_SFXP(frame));
00086 }
00087
00091 void Sprite::Init_Collision(ColType c_index, ColType c_layer)
00092 {
00093 cindex=c_index;
00094 clayer=c_layer;
00095 }
00096
00101 void Sprite::Update(Sint32 dtick)
00102 {
00103
00104 if((surface!=NULL)&&(framerate!=0))
00105 {
00106 int of,newf;
00107
00108 of=FROM_SFXP(frame);
00109
00110
00111 if(framerate<0)
00112 {
00113 while((framerate*dtick)< -frame)
00114 frame+=TO_SFXP(frames.x*frames.y);
00115 }
00116
00117 frame+=(framerate*dtick);
00118
00119
00120 newf=FROM_SFXP(frame);
00121
00122
00123 if(of!=newf)
00124 {
00125
00126 CalcFrame();
00127
00128 Tag();
00129 }
00130 }
00131
00132
00133 if((dtick!=0)&&(vel.Nonzero()))
00134 {
00135
00136 SfxpCoord dpos=vel;
00137
00138 dpos.IntScalar(dtick);
00139
00140
00141 pos+=dpos;
00142
00143
00144 if(!pos.MajorDigitsEqual(prevpos))
00145 {
00146
00147 Tag();
00148 }
00149 }
00150 }
00151
00155 void Sprite::Init_Frames(int xframes, int yframes)
00156 {
00157 frame=framerate=0;
00158
00159 if((xframes<=0)||(yframes<=0))
00160 frames.x=frames.y=1;
00161 else
00162 {
00163 frames.x=xframes;
00164 frames.y=yframes;
00165 }
00166
00167 if(surface==NULL)
00168 frames.w=frames.h=0;
00169 else
00170 {
00171 frames.w=surface->w/frames.x;
00172 frames.h=surface->h/frames.y;
00173 }
00174
00175 CalcFrame();
00176 }
00177
00181 void Sprite::Init_Flags(SpriteFlag flags)
00182 {
00183 flag=flags|SPRITE_WAIT;
00184 }
00185
00189 void Sprite::Init_Surface(SDL_Surface *surf, bool os_in)
00190 {
00191 if(surf==NULL)
00192 {
00193 surface=NULL;
00194 srcrect.Set(0,0,0,0);
00195 }
00196 else
00197 {
00198 surface=surf;
00199 srcrect.Set(0,0,surface->w,surface->h);
00200
00201 if(os_in)
00202 SetFlags(SPRITE_OWNSURFACE);
00203 else
00204 ClearFlags(SPRITE_OWNSURFACE);
00205 }
00206 }
00207
00211 void Sprite::Init_List(Sprite *previn, Sprite *nextin)
00212 {
00213 prev=previn;
00214 next=nextin;
00215 }
00216
00220 void Sprite::Init_Bitmask(bool enable, bitmask **bmask_in)
00221 {
00222 if(enable)
00223 {
00224 if(bmask_in!=NULL)
00225 {
00226 bmask=bmask_in;
00227 ClearFlags(SPRITE_OWNBITMASK);
00228 }
00229 else
00230 {
00231 int n=-1;
00232
00233 bmask =(bitmask **)malloc(sizeof(bitmask)*frames.x*frames.y);
00234 if(bmask==NULL) return;
00235
00236 for(n=0; n<(frames.x*frames.y); n++)
00237 {
00238 frame=TO_SFXP(n);
00239 CalcFrame();
00240
00241 bmask[n]=MakeBitMask(surface,srcrect);
00242 }
00243
00244 SetFlags(SPRITE_OWNBITMASK);
00245
00246 frame=0;
00247 CalcFrame();
00248 }
00249 }
00250 else
00251 {
00252 bmask=NULL;
00253 ClearFlags(SPRITE_OWNBITMASK);
00254 }
00255 }
00256
00260 void Sprite::Init_Layers(Sint16 layer)
00261 {
00262 drawlayer=layer;
00263 }
00264
00268 Sprite::~Sprite()
00269 {
00270 int n=-1;
00271
00272 if((bmask!=NULL)&&OwnBitmask())
00273 {
00274 for(n=0; n<(frames.x*frames.y); n++)
00275 {
00276 if(bmask[n]!=NULL)
00277 {
00278 bitmask_free(bmask[n]);
00279 bmask[n]=NULL;
00280 }
00281 }
00282 free(bmask);
00283 bmask=NULL;
00284 }
00285
00286 if((surface!=NULL)&&OwnSurface())
00287 {
00288 SDL_FreeSurface(surface);
00289 surface=NULL;
00290 }
00291 }
00292
00297 void Sprite::Draw(SDL_Surface *screen, Rect portion)
00298 {
00299 Rect dstrect(pos.X(),pos.Y(),srcrect.w,srcrect.h);
00300
00301
00302 if(portion.Intersect(portion,dstrect))
00303 {
00304 Rect src=srcrect;
00305 Rect tmp=portion;
00306 tmp-=pos;
00307
00308
00309 src.x+=tmp.x;
00310 src.y+=tmp.y;
00311 src.w-=tmp.x;
00312 src.h-=tmp.y;
00313
00314 SDL_BlitSurface(surface,&src,screen,&portion);
00315 }
00316 }
00317
00321 void Sprite::Draw(SDL_Surface *screen)
00322 {
00323 if(screen==NULL) return;
00324 if(surface==NULL) return;
00325
00326 Rect dstrect(pos.X(),pos.Y(),srcrect.w,srcrect.h);
00327
00328 SDL_BlitSurface(surface,&srcrect,screen,&dstrect);
00329 }
00330
00334 bitmask *Sprite::GetBitmask()
00335 {
00336 if(bmask==NULL) return(NULL);
00337
00338 int f=GetFrame()%(frames.x*frames.y);
00339
00340 return(bmask[f]);
00341 }
00342
00347 bitmask *MakeBitMask(SDL_Surface *surf, Rect rect)
00348 {
00349 bitmask *bmask=NULL;
00350 Uint32 colorkey=0;
00351 int x=-1,y=-1;
00352
00353
00354 if(surf==NULL) return(NULL);
00355 if(!(surf->flags&SDL_SRCCOLORKEY))
00356 {
00357 fprintf(stderr,"MakeBitMask()-Can't make bitmask - no colorkey\n");
00358 return(NULL);
00359 }
00360 if(rect.x+rect.w>surf->w) return(NULL);
00361 else if(rect.y+rect.h>surf->h) return(NULL);
00362
00363 colorkey=surf->format->colorkey;
00364
00365 bmask=bitmask_create(rect.w,rect.h);
00366 if(bmask==NULL) return(NULL);
00367
00368 SDL_LockSurface(surf);
00369
00370 for(y=0; y<rect.h; y++)
00371 {
00372 for(x=0; x<rect.w; x++)
00373 {
00374 Uint32 pixel=getpixel(surf,x+rect.x,y+rect.y);
00375 if(pixel==colorkey)
00376 bitmask_clearbit(bmask,x,y);
00377 else
00378 bitmask_setbit(bmask,x,y);
00379 }
00380 }
00381
00382 SDL_UnlockSurface(surf);
00383
00384 return(bmask);
00385 }
00386
00390 SDL_Surface *LoadConvertBMP(const char *fname, Uint8 tr, Uint8 tg, Uint8 tb)
00391 {
00392 SDL_Surface *s1=NULL,*s2=NULL;
00393
00394 if(fname==NULL) return(NULL);
00395
00396 #ifdef USE_SDL_IMAGE
00397 s1=IMG_Load(fname);
00398 #else
00399 s1=SDL_LoadBMP(fname);
00400 #endif
00401
00402 if(s1==NULL) return(NULL);
00403 s2=SDL_DisplayFormat(s1);
00404
00405 if(s2!=NULL)
00406 {
00407 SDL_FreeSurface(s1);
00408 s1=NULL;
00409 }
00410 else
00411 {
00412 fprintf(stderr,"LoadConvertBMP() - couldn't convert\n"
00413 "\"%s\"\n"
00414 "to display format\n\n",fname);
00415 s2=s1;
00416 s1=NULL;
00417 }
00418
00419 if(s2==NULL)
00420 {
00421 fprintf(stderr,"LoadConvertBmp() - couldn't load %s\n",fname);
00422 return(NULL);
00423 }
00424 else
00425 {
00426 SDL_SetColorKey(s2,SDL_SRCCOLORKEY,SDL_MapRGB(s2->format,tr,tg,tb));
00427 return(s2);
00428 }
00429 }