Fix IO memory access .. SB128 driver makes noises in VMWare - CMI is untested (Curren...
[AROS.git] / rom / graphics / docollision.c
blob59d753c8d47ea172049a53a3cc531007238a86a1
1 /*
2 Copyright © 1995-2007, 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
51 struct VSprite * CurVSprite, * _CurVSprite;
52 int shift, _shift;
54 if (NULL != rp->GelsInfo)
56 CurVSprite = rp->GelsInfo->gelHead->NextVSprite;
57 if (CurVSprite->Flags & VSPRITE)
58 shift = 1;
59 else
60 shift = 4;
62 while (NULL != CurVSprite->NextVSprite)
64 _CurVSprite = CurVSprite->NextVSprite;
67 * As long as they can overlap vertically..
69 while (NULL != _CurVSprite &&
70 (CurVSprite->Y + CurVSprite->Height - 1) >= _CurVSprite->Y)
73 * Do these two overlap horizontally ???
75 if (_CurVSprite->Flags & VSPRITE)
76 _shift = 1;
77 else
78 _shift = 4;
80 if (!
81 ((CurVSprite->X>_CurVSprite->X+(_CurVSprite->Width<<_shift)-1) ||
82 (CurVSprite->X+(CurVSprite->Width<<shift)-1<_CurVSprite->X))
86 * Must test the collision masks!!
87 * Phew, this is not going to be easy.
89 int collision = FALSE;
90 int dy = _CurVSprite->Y - CurVSprite->Y;
91 UWORD * collmask = CurVSprite->CollMask;
92 UWORD * _collmask = _CurVSprite->CollMask;
93 unsigned short wordsperline;
94 unsigned short _wordsperline;
95 int i = 0, _i = 0;
96 int offset , _offset = 0;
97 int _scroll = 0;
98 int line = 0;
100 * I will hold the CurVSprite's collision mask still
101 * and adjust/shift the collision mask of _CurVSprite.
102 * If any and'ing results with non-zero, there is a
103 * collision.
105 if (CurVSprite->Flags & VSPRITE)
106 wordsperline = CurVSprite->Width >> 4; // should be 1
107 else
108 wordsperline = CurVSprite->Width;
110 if (_CurVSprite->Flags & VSPRITE)
111 _wordsperline = _CurVSprite->Width >> 4; // should be 1
112 else
113 _wordsperline = _CurVSprite->Width;
115 if (dy > 0)
118 * _CurVSprite is lower than CurVSprite
120 i = wordsperline * dy;
121 line = _CurVSprite->Y;
123 else
125 _i = _wordsperline * dy;
126 line = CurVSprite->Y;
129 offset = _CurVSprite->X - CurVSprite->X;
130 if (offset < 0)
132 _offset = (-offset) >> 4;
133 _scroll = (-offset) & 0xf;
134 offset = 0;
136 else
139 * _CurVSprite is further to the right than
140 * CurVSprite.
142 _scroll = -(offset & 0xf);
143 offset >>= 4;
147 * _scroll > 0 means shift the bits to the RIGHT!
149 while ((line < ( CurVSprite->Height+ CurVSprite->Y)) &&
150 (line < (_CurVSprite->Height+_CurVSprite->Y)) )
152 int curindex = offset;
153 int _curindex = _offset;
154 while ( curindex < wordsperline &&
155 _curindex < _wordsperline)
157 if (_scroll > 0)
159 if (collmask[curindex+i] & (_collmask[_curindex+_i] >> _scroll) )
161 collision = TRUE;
162 break;
164 curindex++;
165 if (curindex > wordsperline)
166 break;
168 if (collmask[curindex+i] & (_collmask[_curindex+_i] << (16-_scroll)))
170 collision = TRUE;
171 break;
173 _curindex++;
175 else
176 if (0 == _scroll)
178 if (collmask[curindex+i] & _collmask[_curindex+_i])
180 collision = TRUE;
181 break;
183 _curindex++;
184 curindex++;
186 else
188 if (collmask[curindex+i] & (_collmask[_curindex+_i] << (-_scroll)))
190 collision = TRUE;
191 break;
193 _curindex++;
194 if (_curindex > _wordsperline)
195 break;
197 if (collmask[curindex+i] & (_collmask[_curindex+_i] >> (16+_scroll)))
199 collision = TRUE;
200 break;
202 curindex++;
205 i+= wordsperline;
206 _i+=_wordsperline;
207 line++;
210 if (collision)
212 UWORD mask = CurVSprite->MeMask & _CurVSprite->HitMask;
213 int i = 0;
214 while (i < 16 && 0 != mask)
216 if (mask & 0x01)
218 if (rp->GelsInfo->collHandler &&
219 rp->GelsInfo->collHandler->collPtrs[i])
220 rp->GelsInfo->collHandler->collPtrs[i]( CurVSprite,
221 _CurVSprite);
222 break;
224 i++;
225 mask >>= 1;
229 _CurVSprite = _CurVSprite->NextVSprite;
231 CurVSprite = CurVSprite->NextVSprite;
235 AROS_LIBFUNC_EXIT
236 } /* DoCollision */