source: abuse/trunk/src/collide.cpp @ 682

Last change on this file since 682 was 555, checked in by Sam Hocevar, 8 years ago

ps3: make everything compile on the PS3. Of course, nothing links yet
because so much support is missing.

File size: 5.7 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 1995 Crack dot Com
4 *  Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
5 *
6 *  This software was released into the Public Domain. As with most public
7 *  domain software, no warranty is made or implied by Crack dot Com, by
8 *  Jonathan Clark, or by Sam Hocevar.
9 */
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include "common.h"
16
17#include "level.h"
18#include "intsect.h"
19
20class collide_patch
21{
22  public :
23  int32_t total,x1,y1,x2,y2;
24  game_object **touch;
25  collide_patch *next;
26  collide_patch(int32_t X1, int32_t Y1, int32_t X2, int32_t Y2, collide_patch *Next)
27  {
28    x1=X1; y1=Y1; x2=X2; y2=Y2;
29    next=Next;
30    total=0;
31    touch=NULL;
32  }
33  void add_collide(int32_t X1, int32_t Y1, int32_t X2, int32_t Y2, game_object *who);
34  collide_patch *copy(collide_patch *Next);
35  ~collide_patch() { if (total) free(touch); }
36} ;
37
38
39collide_patch *collide_patch::copy(collide_patch *Next)
40{
41  collide_patch *p=new collide_patch(x1,y1,x2,y2,Next);
42  p->total=total;
43  if (total)
44  {
45    p->touch=(game_object **)malloc(total*sizeof(game_object *));
46    memcpy(p->touch,touch,total*(sizeof(game_object *)));
47  }
48  else
49    p->touch=NULL;
50  return p;
51}
52
53
54void add_collide(collide_patch *&first, int32_t x1, int32_t y1, int32_t x2, int32_t y2,
55                game_object *who)
56{
57  collide_patch *next;
58  for (collide_patch *p=first; p; p=next)
59  {
60    next=p->next;
61    // first see if light patch we are adding is enclosed entirely by another patch
62    if (x1>=p->x1 && y1>=p->y1 && x2<=p->x2 && y2<=p->y2)
63    {
64      if (x1>p->x1)
65      {
66    first=p->copy(first);
67    first->x2=x1-1;
68      }
69      if (x2<p->x2)
70      {
71    first=p->copy(first);
72    first->x1=x2+1;
73      }
74      if (y1>p->y1)
75      {
76    first=p->copy(first);
77    first->x1=x1;
78    first->x2=x2;
79    first->y2=y1-1;
80      }
81      if (y2<p->y2)
82      {
83    first=p->copy(first);
84    first->x1=x1;
85    first->x2=x2;
86    first->y1=y2+1;
87      }
88      p->x1=x1; p->y1=y1; p->x2=x2; p->y2=y2;
89
90      p->total++;
91      p->touch=(game_object **)realloc(p->touch,sizeof(game_object *)*p->total);
92      p->touch[p->total-1]=who;
93      return ;
94    }
95
96    // see if the patch completly covers another patch.
97    if (x1<=p->x1 && y1<=p->y1 && x2>=p->x2 && y2>=p->y2)
98    {
99      if (x1<p->x1)
100        add_collide(first,x1,y1,p->x1-1,y2,who);
101      if (x2>p->x2)
102        add_collide(first,p->x2+1,y1,x2,y2,who);
103      if (y1<p->y1)
104        add_collide(first,p->x1,y1,p->x2,p->y1-1,who);
105      if (y2>p->y2)
106        add_collide(first,p->x1,p->y2+1,p->x2,y2,who);
107      p->total++;
108      p->touch=(game_object **)realloc(p->touch,sizeof(game_object *)*p->total);
109      p->touch[p->total-1]=who;
110      return ;
111    }
112
113    // see if we intersect another rect
114    if (!(x2<p->x1 || y2<p->y1 || x1>p->x2 || y1>p->y2))
115    {
116      int ax1,ay1,ax2,ay2;
117      if (x1<p->x1)
118      {
119        add_collide(first,x1,Max(y1,p->y1),p->x1-1,Min(y2,p->y2),who);
120    ax1=p->x1;
121      } else
122    ax1=x1;
123
124      if (x2>p->x2)
125      {
126        add_collide(first,p->x2+1,Max(y1,p->y1),x2,Min(y2,p->y2),who);
127    ax2=p->x2;
128      }
129      else
130    ax2=x2;
131
132      if (y1<p->y1)
133      {
134        add_collide(first,x1,y1,x2,p->y1-1,who);
135    ay1=p->y1;
136      } else
137    ay1=y1;
138
139      if (y2>p->y2)
140      {
141        add_collide(first,x1,p->y2+1,x2,y2,who);
142    ay2=p->y2;
143      } else
144    ay2=y2;
145
146
147      add_collide(first,ax1,ay1,ax2,ay2,who);
148
149      return ;
150    }
151
152  }
153
154  first=new collide_patch(x1,y1,x2,y2,first);
155  first->total=1;
156  first->touch=(game_object **)malloc(sizeof(game_object *)*1);
157  first->touch[0]=who;
158}
159
160
161
162
163void level::check_collisions()
164{
165  game_object *target,*rec,*subject;
166  int32_t sx1,sy1,sx2,sy2,tx1,ty1,tx2,ty2,hitx=0,hity=0,t_centerx;
167
168  for (int l=0; l<attack_total; l++)
169  {
170    subject=attack_list[l];
171    subject->picture_space(sx1,sy1,sx2,sy2);
172    rec=NULL;
173
174
175    for (int j=0; j<target_total && !rec; j++)
176    {
177      target=target_list[j];
178      target->picture_space(tx1,ty1,tx2,ty2);
179      if (!(sx2<tx1 || sy2<ty1 || sx1>tx2 || sy1>ty2))  // check to see if picture spaces collide
180      {
181
182    try_pushback(subject,target);
183
184    if (subject->can_hurt(target))    // see if we can hurt him before calculating
185    {
186      t_centerx=target->x_center();
187      point_list *s_hit,*t_damage;
188
189      s_hit=subject->current_figure()->hit;
190
191      if (target->direction>0)
192        t_damage=target->current_figure()->f_damage;
193      else
194        t_damage=target->current_figure()->b_damage;
195
196      unsigned char *s_dat=s_hit->data,*t_dat;
197      int i,j;
198      for (i=(int)s_hit->tot-1; i>0 && !rec; i--)
199      {
200        for (t_dat=t_damage->data,j=(int)t_damage->tot-1; j>0 && !rec; j--)
201        {
202          int32_t x1,y1,x2,y2,          // define the two line segments to check
203          xp1,yp1,xp2,yp2;
204
205          xp1=target->x+target->tx(*t_dat);  t_dat++;
206          yp1=target->y+target->ty(*t_dat);  t_dat++;
207          xp2=target->x+target->tx(*t_dat);
208          yp2=target->y+target->ty(t_dat[1]);
209
210          x1=subject->x+subject->tx(s_dat[0]);
211          y1=subject->y+subject->ty(s_dat[1]);
212          x2=subject->x+subject->tx(s_dat[2]);
213          y2=subject->y+subject->ty(s_dat[3]);
214
215
216          // ok, now we know which line segemnts to check for intersection
217          // now check to see if (x1,y1-x2,y2) intercest with (xp1,yp1-xp2,yp2)
218          int32_t _x2=x2,_y2=y2;
219          setback_intersect(x1, y1, x2, y2, xp1, yp1, xp2, yp2,0);
220
221
222          if (x2!=_x2 || _y2!=y2)
223          {
224        rec=target;
225        hitx=((x1+x2)/2+(xp1+xp2)/2)/2;
226        hity=((y1+y1)/2+(yp1+yp2)/2)/2;
227          }
228        }
229        s_dat+=2;
230      }
231    }
232      }
233    }
234    if (rec)
235    {
236      rec->do_damage((int)subject->current_figure()->hit_damage,subject,hitx,hity,0,0);
237      subject->note_attack(rec);
238    }
239  }
240}
241
Note: See TracBrowser for help on using the repository browser.