home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / progrmng / stk110.lzh / STKSRC.COM / SPR_HIT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-25  |  5.4 KB  |  165 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.1
  13.  
  14.               Copyright (C) Jari Karjala 1991
  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. #include "spr_err.h"
  26.  
  27.  
  28. /**********************************************************************
  29. * Check whether the given point is inside the given sprite.
  30. * Return: 0 if no collision, negative otherwise.
  31. **********************************************************************/
  32. int spr_hit_with_point(SPRITE spr, WORD x, WORD y)
  33. {
  34.     FARMAP p;
  35.     
  36.     if (spr->magic_number != SPR_MAGIC_NUMBER) {
  37.         spr_err("spr_hit_with_point: invalid sprite handle");
  38.         return 0;
  39.     }
  40.     
  41.     if (spr->x <= x && spr->y <= y && 
  42.         spr->x+spr->w*8 > x && spr->y+spr->hp > y) {
  43.             /** Possible collision, check the actual mask data **/
  44.             p = spr->data+SHAPE_OFS(spr) 
  45.                 + (y - spr->y)*spr->w*2 + ((x&0xF8) - (spr->x&0xF8))/4 + 1;
  46.             if ((*p | (0x80 >> (x & 7))) != *p)
  47.                 return -1;  /** Point hit the 0 region of the mask **/
  48.             else
  49.                 return 0;   /** No collision **/
  50.     }
  51.     else    /** Not even in the bounding box **/
  52.         return 0;
  53. }
  54.  
  55. /**********************************************************************
  56. * Check whether the given sprites collide against each other.
  57. * Return: 0 if no collision, negative otherwise.
  58. **********************************************************************/
  59. int spr_hit(SPRITE s1, SPRITE s2)
  60. {
  61.     int i,j,k;
  62.     FARMAP p1, p2;
  63.     
  64.     if (s1->magic_number != SPR_MAGIC_NUMBER
  65.         || s2->magic_number != SPR_MAGIC_NUMBER) {
  66.         spr_err("spr_hit: invalid sprite handle");
  67.         return 0;
  68.     }
  69.     
  70.     if (    (   (s1->x >= s2->x && s1->x < s2->x+s2->wp)
  71.              || (s2->x >= s1->x && s2->x < s1->x+s1->wp))
  72.          && (   (s1->y >= s2->y && s1->y < s2->y+s2->hp)
  73.              || (s2->y >= s1->y && s2->y < s1->y+s1->hp))) {
  74.             /** Possible collision, check the actual mask data **/
  75.             p1 = s1->data+SHAPE_OFS(s1);
  76.             p2 = s2->data+SHAPE_OFS(s2);
  77.             
  78.             if (s1->y < s2->y) { /** adjust pointers to the same Y level **/
  79.                 i = (s2->y - s1->y);
  80.                 p1 += i * s1->w*2;
  81.                 i = s1->hp - i;
  82.             }
  83.             else { 
  84.                 i = (s1->y - s2->y);
  85.                 p2 += i * s2->w*2;
  86.                 i = s2->hp - i;
  87.             }
  88.             
  89.             if (s1->x < s2->x) { /** adjust pointers to the same X level **/
  90.                 j = ((s2->x&0xF8) - (s1->x&0xF8)) / 4;
  91.                 p1 += j;
  92.                 j = s1->w - j/2;
  93.             }
  94.             else {
  95.                 j = ((s1->x&0xF8) - (s2->x&0xF8)) / 4;
  96.                 p2 += j;
  97.                 j = s2->w - j/2;
  98.             }
  99.             
  100.             /** test the overlapping parts **/
  101.             for( ; i>0; i--, p1+=s1->w*2, p2+=s2->w*2)
  102.                 for(k=1; k<j*2; k+=2)
  103.                     if (~*(p1+k) & ~*(p2+k))
  104.                         return -1;
  105.             return 0;
  106.     }
  107.     else    /** Not even in the bounding box **/
  108.         return 0;
  109. }
  110.  
  111. /**********************************************************************
  112. * Find the first sprite colliding the given sprite. Use spr_hit_next 
  113. * to get the next sprites.
  114. * Return: Sprite or NULL if no collision
  115. **********************************************************************/
  116. SPRITE spr_hit_first(SPRITE spr)
  117. {
  118.     SPRITE s;
  119.     
  120.     if (spr->magic_number != SPR_MAGIC_NUMBER) {
  121.         spr_err("spr_hit_first: invalid sprite handle");
  122.         return 0;
  123.     }
  124.     
  125.     s = spr_sprites[spr_drawingpage];
  126.     while (s!=NULL) {
  127.         if (s!=spr) /** no collision with itself **/
  128.             if (spr_hit(spr, s)) {  /** found collision **/
  129.                 spr->cur_hit = s->next[spr_drawingpage];
  130.                 return s;
  131.             }
  132.         s = s->next[spr_drawingpage];
  133.     }
  134.     return NULL;
  135. }
  136.  
  137. /**********************************************************************
  138. * Find the next sprite colliding with the given sprite. 
  139. * Return: Sprite or NULL if no collision
  140. **********************************************************************/
  141. SPRITE spr_hit_next(SPRITE spr)
  142. {
  143.     SPRITE s;
  144.     
  145.     if (spr->magic_number != SPR_MAGIC_NUMBER) {
  146.         spr_err("spr_hit_next: invalid sprite handle");
  147.         return 0;
  148.     }
  149.     
  150.     s = spr->cur_hit;
  151.     while (s!=NULL) {
  152.         if (s!=spr) /** no collision with itself **/
  153.             if (spr_hit(spr, s)) {  /** found collision **/
  154.                 spr->cur_hit = s->next[spr_drawingpage];
  155.                 return s;
  156.             }
  157.         s = s->next[spr_drawingpage];
  158.     }
  159.     return NULL;
  160. }
  161.  
  162.