r4493@vps: verhaegs | 2007-04-19 14:44:00 -0400
[AROS.git] / rom / graphics / docollision.c
blobbe9d5b153c38b83dd025724fccce8599501525b7
1 /*
2 Copyright © 1995-2004, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Graphics function DoCollision()
6 Lang: english
7 */
8 #include <graphics/rastport.h>
9 #include <graphics/gels.h>
11 /*****************************************************************************
13 NAME */
14 #include <proto/graphics.h>
16 AROS_LH1(void, DoCollision,
18 /* SYNOPSIS */
19 AROS_LHA(struct RastPort *, rp, A1),
21 /* LOCATION */
22 struct GfxBase *, GfxBase, 18, Graphics)
24 /* FUNCTION
25 Tests each gel in gel list for boundary and gel-to-gel collisions.
26 If a collision happens the collision handling routine is called.
27 The gel list must be sorted by y,x order.
29 INPUTS
30 rp - pointer to RastPort
32 RESULT
34 NOTES
36 EXAMPLE
38 BUGS
40 SEE ALSO
42 INTERNALS
44 HISTORY
47 ******************************************************************************/
49 AROS_LIBFUNC_INIT
50 AROS_LIBBASE_EXT_DECL(struct GfxBase *,GfxBase)
52 struct VSprite * CurVSprite, * _CurVSprite;
53 int shift, _shift;
55 if (NULL != rp->GelsInfo)
57 CurVSprite = rp->GelsInfo->gelHead->NextVSprite;
58 if (CurVSprite->Flags & VSPRITE)
59 shift = 1;
60 else
61 shift = 4;
63 while (NULL != CurVSprite->NextVSprite)
65 _CurVSprite = CurVSprite->NextVSprite;
68 * As long as they can overlap vertically..
70 while (NULL != _CurVSprite &&
71 (CurVSprite->Y + CurVSprite->Height - 1) >= _CurVSprite->Y)
74 * Do these two overlap horizontally ???
76 if (_CurVSprite->Flags & VSPRITE)
77 _shift = 1;
78 else
79 _shift = 4;
81 if (!
82 ((CurVSprite->X>_CurVSprite->X+(_CurVSprite->Width<<_shift)-1) ||
83 (CurVSprite->X+(CurVSprite->Width<<shift)-1<_CurVSprite->X))
87 * Must test the collision masks!!
88 * Phew, this is not going to be easy.
90 int collision = FALSE;
91 int dy = _CurVSprite->Y - CurVSprite->Y;
92 UWORD * collmask = CurVSprite->CollMask;
93 UWORD * _collmask = _CurVSprite->CollMask;
94 unsigned short wordsperline;
95 unsigned short _wordsperline;
96 int i = 0, _i = 0;
97 int offset , _offset = 0;
98 int _scroll = 0;
99 int line = 0;
101 * I will hold the CurVSprite's collision mask still
102 * and adjust/shift the collision mask of _CurVSprite.
103 * If any and'ing results with non-zero, there is a
104 * collision.
106 if (CurVSprite->Flags & VSPRITE)
107 wordsperline = CurVSprite->Width >> 4; // should be 1
108 else
109 wordsperline = CurVSprite->Width;
111 if (_CurVSprite->Flags & VSPRITE)
112 _wordsperline = _CurVSprite->Width >> 4; // should be 1
113 else
114 _wordsperline = _CurVSprite->Width;
116 if (dy > 0)
119 * _CurVSprite is lower than CurVSprite
121 i = wordsperline * dy;
122 line = _CurVSprite->Y;
124 else
126 _i = _wordsperline * dy;
127 line = CurVSprite->Y;
130 offset = _CurVSprite->X - CurVSprite->X;
131 if (offset < 0)
133 _offset = (-offset) >> 4;
134 _scroll = (-offset) & 0xf;
135 offset = 0;
137 else
140 * _CurVSprite is further to the right than
141 * CurVSprite.
143 _scroll = -(offset & 0xf);
144 offset >>= 4;
148 * _scroll > 0 means shift the bits to the RIGHT!
150 while ((line < ( CurVSprite->Height+ CurVSprite->Y)) &&
151 (line < (_CurVSprite->Height+_CurVSprite->Y)) )
153 int curindex = offset;
154 int _curindex = _offset;
155 while ( curindex < wordsperline &&
156 _curindex < _wordsperline)
158 if (_scroll > 0)
160 if (collmask[curindex+i] & (_collmask[_curindex+_i] >> _scroll) )
162 collision = TRUE;
163 break;
165 curindex++;
166 if (curindex > wordsperline)
167 break;
169 if (collmask[curindex+i] & (_collmask[_curindex+_i] << (16-_scroll)))
171 collision = TRUE;
172 break;
174 _curindex++;
176 else
177 if (0 == _scroll)
179 if (collmask[curindex+i] & _collmask[_curindex+_i])
181 collision = TRUE;
182 break;
184 _curindex++;
185 curindex++;
187 else
189 if (collmask[curindex+i] & (_collmask[_curindex+_i] << (-_scroll)))
191 collision = TRUE;
192 break;
194 _curindex++;
195 if (_curindex > _wordsperline)
196 break;
198 if (collmask[curindex+i] & (_collmask[_curindex+_i] >> (16+_scroll)))
200 collision = TRUE;
201 break;
203 curindex++;
206 i+= wordsperline;
207 _i+=_wordsperline;
208 line++;
211 if (TRUE == collision)
213 UWORD mask = CurVSprite->MeMask & _CurVSprite->HitMask;
214 int i = 0;
215 while (i < 16 && 0 != mask)
217 if (mask & 0x01)
219 if (rp->GelsInfo->collHandler &&
220 rp->GelsInfo->collHandler->collPtrs[i])
221 rp->GelsInfo->collHandler->collPtrs[i]( CurVSprite,
222 _CurVSprite);
223 break;
225 i++;
226 mask >>= 1;
230 _CurVSprite = _CurVSprite->NextVSprite;
232 CurVSprite = CurVSprite->NextVSprite;
236 AROS_LIBFUNC_EXIT
237 } /* DoCollision */