home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- * spr_hit.c
- *
- * The sprite collision detection routines.
- *
- * Collisions may be checked only for the sprites which have been
- * spr_put() since the last call to spr_next_pass().
- * All checks are made against the mask-bitmaps of the sprites.
- *
- **********************************************************************
- This file is part of
-
- STK -- The sprite toolkit -- version 1.0
-
- Copyright (C) Jari Karjala 1990
-
- The sprite toolkit (STK) is a FreeWare toolkit for creating high
- resolution sprite graphics with PCompatible hardware. This toolkit
- is provided as is without any warranty or such thing. See the file
- COPYING for further information.
-
- **********************************************************************/
-
-
- #include "sprP.h"
-
-
- /**********************************************************************
- * Check whether the given point is inside the given sprite.
- *
- * Return: 0 if no collision, negative otherwise.
- **********************************************************************/
- int spr_hit_with_point(SPRITE spr, WORD x, WORD y)
- {
- FARMAP p;
-
- if (spr->x <= x && spr->y <= y &&
- spr->x+spr->w*8 > x && spr->y+spr->hp > y) {
- /** Possible collision, check the actual mask data **/
- p = spr->data+SHAPE_OFS(spr)
- + (y - spr->y)*spr->w*2 + ((x&0xF8) - (spr->x&0xF8))/4 + 1;
- if ((*p | (0x80 >> (x & 7))) != *p)
- return -1; /** Point hit the 0 region of the mask **/
- else
- return 0; /** No collision **/
- }
- else /** Not even in the bounding box **/
- return 0;
- }
-
- /**********************************************************************
- * Check whether the given sprites collide against each other.
- *
- * Return: 0 if no collision, negative otherwise.
- **********************************************************************/
- int spr_hit(SPRITE s1, SPRITE s2)
- {
- int i,j,k;
- FARMAP p1, p2;
-
- if ( ( (s1->x >= s2->x && s1->x < s2->x+s2->w*8)
- || (s2->x >= s1->x && s2->x < s1->x+s1->w*8))
- && ( (s1->y >= s2->y && s1->y < s2->y+s2->hp*8)
- || (s2->y >= s1->y && s2->y < s1->y+s1->hp*8))) {
- /** Possible collision, check the actual mask data **/
- p1 = s1->data+SHAPE_OFS(s1);
- p2 = s2->data+SHAPE_OFS(s2);
-
- if (s1->y < s2->y) { /** adjust pointers to the same Y level **/
- i = (s2->y - s1->y);
- p1 += i * s1->w*2;
- i = s1->hp - i;
- }
- else {
- i = (s1->y - s2->y);
- p2 += i * s2->w*2;
- i = s2->hp - i;
- }
-
- if (s1->x < s2->x) { /** adjust pointers to the same X level **/
- j = ((s2->x&0xF8) - (s1->x&0xF8)) / 4;
- p1 += j;
- j = s1->w - j/2;
- }
- else {
- j = ((s1->x&0xF8) - (s2->x&0xF8)) / 4;
- p2 += j;
- j = s2->w - j/2;
- }
-
- /** test the overlapping parts **/
- for( ; i>0; i--, p1+=s1->w*2, p2+=s2->w*2)
- for(k=1; k<j*2; k+=2)
- if (~*(p1+k) & ~*(p2+k))
- return -1;
- return 0;
- }
- else /** Not even in the bounding box **/
- return 0;
- }
-
- /**********************************************************************
- * Find the first sprite colliding the given sprite. Use spr_hit_next
- * to get the next sprites.
- * Return: Sprite or NULL if no collision
- **********************************************************************/
- SPRITE spr_hit_first(SPRITE spr)
- {
- SPRITE s;
-
- s = spr_sprites[spr_drawingpage];
- while (s!=NULL) {
- if (s!=spr) /** no collision with itself **/
- if (spr_hit(spr, s)) { /** found collision **/
- spr->cur_hit = s->next[spr_drawingpage];
- return s;
- }
- s = s->next[spr_drawingpage];
- }
- return NULL;
- }
-
- /**********************************************************************
- * Find the next sprite colliding with the given sprite.
- * Return: Sprite or NULL if no collision
- **********************************************************************/
- SPRITE spr_hit_next(SPRITE spr)
- {
- SPRITE s;
-
- s = spr->cur_hit;
- while (s!=NULL) {
- if (s!=spr) /** no collision with itself **/
- if (spr_hit(spr, s)) { /** found collision **/
- spr->cur_hit = s->next[spr_drawingpage];
- return s;
- }
- s = s->next[spr_drawingpage];
- }
- return NULL;
- }
-
-