home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / GRAPHICS / MISC / STK100.ZIP / STKSRC.COM / SPR_HIT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-10-20  |  4.8 KB  |  143 lines

  1. /**********************************************************************
  2. * spr_hit.c
  3. * The sprite collision detection routines.
  4. *
  5. * Collisions may be checked only for the sprites which have been 
  6. * spr_put() since the last call to spr_next_pass().
  7. * All checks are made against the mask-bitmaps of the sprites.
  8. *
  9. **********************************************************************
  10.                     This file is part of
  11.  
  12.           STK -- The sprite toolkit -- version 1.0
  13.  
  14.               Copyright (C) Jari Karjala 1990
  15.  
  16. The sprite toolkit (STK) is a FreeWare toolkit for creating high
  17. resolution sprite graphics with PCompatible hardware. This toolkit 
  18. is provided as is without any warranty or such thing. See the file
  19. COPYING for further information.
  20.  
  21. **********************************************************************/
  22.  
  23.  
  24. #include "sprP.h"
  25.  
  26.  
  27. /**********************************************************************
  28. * Check whether the given point is inside the given sprite.
  29. * Return: 0 if no collision, negative otherwise.
  30. **********************************************************************/
  31. int spr_hit_with_point(SPRITE spr, WORD x, WORD y)
  32. {
  33.     FARMAP p;
  34.     
  35.     if (spr->x <= x && spr->y <= y && 
  36.         spr->x+spr->w*8 > x && spr->y+spr->hp > y) {
  37.             /** Possible collision, check the actual mask data **/
  38.             p = spr->data+SHAPE_OFS(spr) 
  39.                 + (y - spr->y)*spr->w*2 + ((x&0xF8) - (spr->x&0xF8))/4 + 1;
  40.             if ((*p | (0x80 >> (x & 7))) != *p)
  41.                 return -1;  /** Point hit the 0 region of the mask **/
  42.             else
  43.                 return 0;   /** No collision **/
  44.     }
  45.     else    /** Not even in the bounding box **/
  46.         return 0;
  47. }
  48.  
  49. /**********************************************************************
  50. * Check whether the given sprites collide against each other.
  51. * Return: 0 if no collision, negative otherwise.
  52. **********************************************************************/
  53. int spr_hit(SPRITE s1, SPRITE s2)
  54. {
  55.     int i,j,k;
  56.     FARMAP p1, p2;
  57.     
  58.     if (    (   (s1->x >= s2->x && s1->x < s2->x+s2->w*8)
  59.              || (s2->x >= s1->x && s2->x < s1->x+s1->w*8))
  60.          && (   (s1->y >= s2->y && s1->y < s2->y+s2->hp*8)
  61.              || (s2->y >= s1->y && s2->y < s1->y+s1->hp*8))) {
  62.             /** Possible collision, check the actual mask data **/
  63.             p1 = s1->data+SHAPE_OFS(s1);
  64.             p2 = s2->data+SHAPE_OFS(s2);
  65.             
  66.             if (s1->y < s2->y) { /** adjust pointers to the same Y level **/
  67.                 i = (s2->y - s1->y);
  68.                 p1 += i * s1->w*2;
  69.                 i = s1->hp - i;
  70.             }
  71.             else { 
  72.                 i = (s1->y - s2->y);
  73.                 p2 += i * s2->w*2;
  74.                 i = s2->hp - i;
  75.             }
  76.             
  77.             if (s1->x < s2->x) { /** adjust pointers to the same X level **/
  78.                 j = ((s2->x&0xF8) - (s1->x&0xF8)) / 4;
  79.                 p1 += j;
  80.                 j = s1->w - j/2;
  81.             }
  82.             else {
  83.                 j = ((s1->x&0xF8) - (s2->x&0xF8)) / 4;
  84.                 p2 += j;
  85.                 j = s2->w - j/2;
  86.             }
  87.             
  88.             /** test the overlapping parts **/
  89.             for( ; i>0; i--, p1+=s1->w*2, p2+=s2->w*2)
  90.                 for(k=1; k<j*2; k+=2)
  91.                     if (~*(p1+k) & ~*(p2+k))
  92.                         return -1;
  93.             return 0;
  94.     }
  95.     else    /** Not even in the bounding box **/
  96.         return 0;
  97. }
  98.  
  99. /**********************************************************************
  100. * Find the first sprite colliding the given sprite. Use spr_hit_next 
  101. * to get the next sprites.
  102. * Return: Sprite or NULL if no collision
  103. **********************************************************************/
  104. SPRITE spr_hit_first(SPRITE spr)
  105. {
  106.     SPRITE s;
  107.     
  108.     s = spr_sprites[spr_drawingpage];
  109.     while (s!=NULL) {
  110.         if (s!=spr) /** no collision with itself **/
  111.             if (spr_hit(spr, s)) {  /** found collision **/
  112.                 spr->cur_hit = s->next[spr_drawingpage];
  113.                 return s;
  114.             }
  115.         s = s->next[spr_drawingpage];
  116.     }
  117.     return NULL;
  118. }
  119.  
  120. /**********************************************************************
  121. * Find the next sprite colliding with the given sprite. 
  122. * Return: Sprite or NULL if no collision
  123. **********************************************************************/
  124. SPRITE spr_hit_next(SPRITE spr)
  125. {
  126.     SPRITE s;
  127.     
  128.     s = spr->cur_hit;
  129.     while (s!=NULL) {
  130.         if (s!=spr) /** no collision with itself **/
  131.             if (spr_hit(spr, s)) {  /** found collision **/
  132.                 spr->cur_hit = s->next[spr_drawingpage];
  133.                 return s;
  134.             }
  135.         s = s->next[spr_drawingpage];
  136.     }
  137.     return NULL;
  138. }
  139.  
  140.