/* ** File : sprlst.c ** Author: D Smethurst ** Desc. : Utilities to manipulate the list of sprites. ** Version: 0.1 */ #include #include #include #include #include "sprite.h" /* SprLstAdd: input : s - sprite to add into list l - sprite list to sprite to output: new spritelist or null if error occurs */ lpspritelist SprLstAdd( lpSprite s, lpspritelist l ) { /* new spritelist entry */ lpspritelist lnew; /* Assert only in debug */ assert( s != NULL ); /* Check that s is not null */ if( s == NULL ) { return NULL; } /* Check to see if the list is null */ if( l == NULL ) { /* Allocate memory */ l = (lpspritelist)malloc( sizeof( spritelist ) ); /* Error */ if( l == NULL ) { mystrerror = SPR_NO_MEM; return NULL; } /* Attach the sprite */ l->s = s; /* Setup the pointers to NULL */ l->next = NULL; l->prev = NULL; /* Return the new list */ return l; } /* Allocate memory for new entry */ lnew = (lpspritelist)malloc( sizeof( spritelist )); /* Check to make sure the memory has been allocated */ if( lnew == NULL ) { mystrerror = SPR_NO_MEM; return NULL; } /* Attach the sprite */ lnew->s = s; /* Set the pointers up to the list */ lnew->next = l; l->prev = lnew; lnew->prev = NULL; /* Return the new list */ return lnew; } /* SprLstRemove: input : s - sprite to remove l - spritelist to remove sprite from output: true/false if the sprite is remove or if it isn't found */ BOOL SprLstRemove( lpSprite s, lpspritelist l ) { /* temp pointer to the list */ lpspritelist ltmp; ltmp = l; /* Assert only in debug */ assert( s != NULL ); /* Check that s is not null */ if( s == NULL ) { /* Shouldn't really get here so we return true */ return TRUE; } /* Loop through the list */ while( ltmp != NULL ) { /* Check to see if we have found the sprite */ if( ltmp->s == s ) { /* Check to see if there is another entry in the list */ if( ltmp->next != NULL ) ltmp->next->prev = ltmp->prev; /* Check to see if we are in the middle of the list */ if( ltmp->prev != NULL ) ltmp->prev->next = ltmp->next; /* If it's the head then re-assign it */ if( ltmp == l ) *l = *l->next; /* Free up the memory */ free( ltmp ); /* Return sucess */ return TRUE; } /* Move down the list */ ltmp = ltmp->next; } /* If we get to the end then return failure */ return FALSE; } /* SprLstCollision: input : s - sprite to check for collision l - list to check against output: pointer to sprite that s collides with in l first. */ lpSprite SprLstCollision( lpSprite s, lpspritelist l ) { /* Temporary pointer used to walk through list */ lpspritelist ltmp; ltmp = l; /* Assert only in debug */ assert( s != NULL ); /* Make sure that s is not null */ if( s == NULL ) { return NULL; } while( ltmp != NULL ) { /* Simple x,y collision detection between two sprites using their x,y,w & h values. For best effect this should be used with sprites that take up all of the w & h of the image. Not really up to pixel perfect collision. */ if( ( ( s->x >= ltmp->s->x && s->x <= ltmp->s->x + ltmp->s->w ) || ( s->x <= ltmp->s->x && s->x + s->w >= ltmp->s->x ) ) && ( ( s->y >= ltmp->s->y && s->y <= ltmp->s->y + ltmp->s->h ) || ( s->y <= ltmp->s->y && s->y + s->h >= ltmp->s->y ) ) ) { /* We got a collision so return */ return ltmp->s; } /* loop down the list */ ltmp = ltmp->next; } /* If we get to here nothing collided */ return NULL; } /* ** SprLstDraw ** Input : l - list of sprites to draw ** dtoOT - OT to insert sprites into ** Output: nothing */ void SprLstDraw( lpspritelist l, GsOT dtoOT ) { lpspritelist tmp; tmp = l; while( l ) { /* Use either SortFast or Sort to put the ** sprite into the OT depending on wether it's ** rotated or not. */ if( tmp->s->spr.rotate > 0 ) GsSortSprite( &tmp->s->spr, &dtoOT, 0 ); else { /* ** Inserted this check just to make sure that we don't get ** a 'jumping sprite' situation. Since GsSortFast ignores the ** values stored in spr.mx and spr.my it will seem to jump ** if the rotation value is 0. (email me if you want to ** understand this better or read the description of ** GsSortFastSprite in the library reference on page 140 ** - Dave ) */ if( tmp->s->spr.mx == 0 && tmp->s->spr.my == 0 ) GsSortFastSprite( &tmp->s->spr, &dtoOT, 0 ); else GsSortSprite( &tmp->s->spr, &dtoOT, 0 ); } /* Move down the list */ l = l->next; } }