revert between 56095 -> 55830 in arch
[AROS.git] / rom / graphics / docollision.c
blob7849bc7981b2a731d660f1422a922272f532ff8f
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 #include "graphics_intern.h"
13 /*****************************************************************************
15 NAME */
16 #include <proto/graphics.h>
18 AROS_LH1(void, DoCollision,
20 /* SYNOPSIS */
21 AROS_LHA(struct RastPort *, rp, A1),
23 /* LOCATION */
24 struct GfxBase *, GfxBase, 18, Graphics)
26 /* FUNCTION
27 Tests each gel in gel list for boundary and gel-to-gel collisions.
28 If a collision happens the collision handling routine is called.
29 The gel list must be sorted by y,x order.
31 INPUTS
32 rp - pointer to RastPort
34 RESULT
36 NOTES
38 EXAMPLE
40 BUGS
42 SEE ALSO
44 INTERNALS
46 HISTORY
49 ******************************************************************************/
51 AROS_LIBFUNC_INIT
53 struct VSprite * CurVSprite, * _CurVSprite;
54 int shift, _shift;
56 if (NULL != rp->GelsInfo)
58 CurVSprite = rp->GelsInfo->gelHead->NextVSprite;
59 if (CurVSprite->Flags & VSPRITE)
60 shift = 1;
61 else
62 shift = 4;
64 while (NULL != CurVSprite->NextVSprite)
66 _CurVSprite = CurVSprite->NextVSprite;
69 * As long as they can overlap vertically..
71 while (NULL != _CurVSprite &&
72 (CurVSprite->Y + CurVSprite->Height - 1) >= _CurVSprite->Y)
75 * Do these two overlap horizontally ???
77 if (_CurVSprite->Flags & VSPRITE)
78 _shift = 1;
79 else
80 _shift = 4;
82 if (!
83 ((CurVSprite->X>_CurVSprite->X+(_CurVSprite->Width<<_shift)-1) ||
84 (CurVSprite->X+(CurVSprite->Width<<shift)-1<_CurVSprite->X))
88 * Must test the collision masks!!
89 * Phew, this is not going to be easy.
91 int collision = FALSE;
92 int dy = _CurVSprite->Y - CurVSprite->Y;
93 UWORD * collmask = CurVSprite->CollMask;
94 UWORD * _collmask = _CurVSprite->CollMask;
95 unsigned short wordsperline;
96 unsigned short _wordsperline;
97 int i = 0, _i = 0;
98 int offset , _offset = 0;
99 int _scroll = 0;
100 int line = 0;
102 * I will hold the CurVSprite's collision mask still
103 * and adjust/shift the collision mask of _CurVSprite.
104 * If any and'ing results with non-zero, there is a
105 * collision.
107 if (CurVSprite->Flags & VSPRITE)
108 wordsperline = CurVSprite->Width >> 4; // should be 1
109 else
110 wordsperline = CurVSprite->Width;
112 if (_CurVSprite->Flags & VSPRITE)
113 _wordsperline = _CurVSprite->Width >> 4; // should be 1
114 else
115 _wordsperline = _CurVSprite->Width;
117 if (dy > 0)
120 * _CurVSprite is lower than CurVSprite
122 i = wordsperline * dy;
123 line = _CurVSprite->Y;
125 else
127 _i = _wordsperline * dy;
128 line = CurVSprite->Y;
131 offset = _CurVSprite->X - CurVSprite->X;
132 if (offset < 0)
134 _offset = (-offset) >> 4;
135 _scroll = (-offset) & 0xf;
136 offset = 0;
138 else
141 * _CurVSprite is further to the right than
142 * CurVSprite.
144 _scroll = -(offset & 0xf);
145 offset >>= 4;
149 * _scroll > 0 means shift the bits to the RIGHT!
151 while ((line < ( CurVSprite->Height+ CurVSprite->Y)) &&
152 (line < (_CurVSprite->Height+_CurVSprite->Y)) )
154 int curindex = offset;
155 int _curindex = _offset;
156 while ( curindex < wordsperline &&
157 _curindex < _wordsperline)
159 if (_scroll > 0)
161 if (collmask[curindex+i] & (_collmask[_curindex+_i] >> _scroll) )
163 collision = TRUE;
164 break;
166 curindex++;
167 if (curindex > wordsperline)
168 break;
170 if (collmask[curindex+i] & (_collmask[_curindex+_i] << (16-_scroll)))
172 collision = TRUE;
173 break;
175 _curindex++;
177 else
178 if (0 == _scroll)
180 if (collmask[curindex+i] & _collmask[_curindex+_i])
182 collision = TRUE;
183 break;
185 _curindex++;
186 curindex++;
188 else
190 if (collmask[curindex+i] & (_collmask[_curindex+_i] << (-_scroll)))
192 collision = TRUE;
193 break;
195 _curindex++;
196 if (_curindex > _wordsperline)
197 break;
199 if (collmask[curindex+i] & (_collmask[_curindex+_i] >> (16+_scroll)))
201 collision = TRUE;
202 break;
204 curindex++;
207 i+= wordsperline;
208 _i+=_wordsperline;
209 line++;
212 if (collision)
214 UWORD mask = CurVSprite->MeMask & _CurVSprite->HitMask;
215 int i = 0;
216 while (i < 16 && 0 != mask)
218 if (mask & 0x01)
220 if (rp->GelsInfo->collHandler &&
221 rp->GelsInfo->collHandler->collPtrs[i])
222 rp->GelsInfo->collHandler->collPtrs[i]( CurVSprite,
223 _CurVSprite);
224 break;
226 i++;
227 mask >>= 1;
231 _CurVSprite = _CurVSprite->NextVSprite;
233 CurVSprite = CurVSprite->NextVSprite;
237 AROS_LIBFUNC_EXIT
238 } /* DoCollision */