source: abuse/trunk/src/items.cpp @ 494

Last change on this file since 494 was 494, checked in by Sam Hocevar, 11 years ago

style: remove trailing spaces, fix copyright statements.

File size: 7.0 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 or
8 *  Jonathan Clark.
9 */
10
11#include "config.h"
12
13#include "items.h"
14#include "lisp.h"
15#include "dev.h"
16
17
18extern palette *pal;
19
20boundary::boundary(bFILE *fp, char const *er_name) : point_list(fp)
21{
22  int x1,y1,x2,y2,checkx,checky,i;
23  if (tot)
24  {
25    if (!(data[0]==data[(tot-1)*2] &&
26      data[1]==data[tot*2-1]))
27    {
28      printf("%s : Endpoints of foretile do not match start points\n",er_name);
29      exit(0);
30    }
31
32    inside=(uint8_t *)malloc(tot);
33  }
34
35  uint8_t *point_on;
36
37  for (i=0,point_on=data; i<tot-1; i++)
38  {
39    x1=*(point_on++);
40    y1=*(point_on++);
41    x2=point_on[0];
42    y2=point_on[1];
43
44    checkx=(x1+x2)/2;
45    checky=(y1+y2)/2;
46
47    int j,xp1,yp1,xp2,yp2,maxx,maxy,minx,miny;
48    uint8_t *point2,segs_left=0,segs_right=0,segs_down=0;
49    int skip_next=0;
50    int check_left=0,check_right=0,check_down=0;
51
52
53    if (y1==y2) check_down=1;
54    else if (x1==x2) check_left=1;
55    else
56    {
57      check_down=1;
58      if (x1<x2)
59        if (y1<y2) check_left=1;
60        else check_right=1;
61      else if (y1<y2) check_right=1;
62      else check_left=1;
63    }
64
65    maxx=Max(x1,x2);
66    maxy=Max(y1,y2);
67    minx=Min(x1,x2);
68    miny=Min(y1,y2);
69
70    if (skip_next)
71      skip_next=0;
72    else
73    {
74      for (j=0,point2=data; j<tot-1; j++,point2+=2)
75      {
76    if (skip_next)
77      skip_next=0;
78    else
79    {
80      if (j!=i)           // make sure we are not looking at ourself
81      {
82        xp1=point2[0];
83        yp1=point2[1];
84        xp2=point2[2];
85        yp2=point2[3];
86
87        if ((checkx>=xp1 && checkx<=xp2) || (checkx>=xp2 &&  checkx<=xp1))
88            {
89            if (check_down && (yp1>miny && yp2>miny))
90        segs_down++;
91          if (checkx==xp2) skip_next=1;
92        } else if ((checky>=yp1 && checky<=yp2) || (checky>=yp2 &&  checky<=yp1))
93        {
94          if (check_left && xp1<maxx && xp2<maxx)
95        segs_left++;
96          if (check_right && xp1>minx && xp2>minx)
97            segs_right++;
98          if (checky==yp2) skip_next=1;
99        }
100      }
101    }
102      }
103    }
104    if (!check_down) segs_down=1;
105    if (!check_right) segs_right=1;
106    if (!check_left) segs_left=1;
107
108    inside[i]=!(((segs_left&1)&&(segs_right&1)&&(segs_down&1)));
109  }
110}
111
112boundary::boundary(boundary *p) : point_list(p->tot,p->data)
113{
114  int x1,y1,x2,y2,checkx,checky,i;
115  uint8_t *point_on;
116  if (tot)
117  {
118    inside=(uint8_t *)malloc(tot);
119  } else inside=NULL;
120  for (i=0,point_on=data; i<tot-1; i++)
121  {
122    x1=*(point_on++);
123    y1=*(point_on++);
124    x2=point_on[0];
125    y2=point_on[1];
126
127    checkx=(x1+x2)/2;
128    checky=(y1+y2)/2;
129
130    int j,xp1,yp1,xp2,yp2,maxx,maxy,minx,miny;
131    uint8_t *point2,segs_left=0,segs_right=0,segs_down=0;
132    int skip_next=0;
133    int check_left=0,check_right=0,check_down=0;
134
135
136    if (y1==y2) check_down=1;
137    else if (x1==x2) check_right=1;
138    else
139    {
140      check_down=1;
141      if (x1<x2)
142        if (y1<y2) check_left=1;
143        else check_right=1;
144      else if (y1<y2) check_right=1;
145      else check_left=1;
146    }
147
148
149
150    maxx=Max(x1,x2);
151    maxy=Max(y1,y2);
152    minx=Min(x1,x2);
153    miny=Min(y1,y2);
154
155    if (skip_next)
156      skip_next=0;
157    else
158    {
159      for (j=0,point2=data; j<tot-1; j++,point2+=2)
160      {
161    if (skip_next)
162      skip_next=0;
163    else
164    {
165      if (j!=i)           // make sure we are not looking at ourself
166      {
167        xp1=point2[0];
168        yp1=point2[1];
169        xp2=point2[2];
170        yp2=point2[3];
171
172        if ((checkx>=xp1 && checkx<=xp2) || (checkx>=xp2 &&  checkx<=xp1))
173            {
174            if (check_down && (yp1>miny && yp2>miny))
175        segs_down++;
176          if (checkx==xp2) skip_next=1;
177        } else if ((checky>=yp1 && checky<=yp2) || (checky>=yp2 &&  checky<=yp1))
178        {
179          if (check_left && xp1<maxx && xp2<maxx)
180        segs_left++;
181          if (check_right && xp1>minx && xp2>minx)
182            segs_right++;
183          if (checky==yp2) skip_next=1;
184        }
185      }
186    }
187      }
188    }
189    if (!check_down) segs_down=1;
190    if (!check_right) segs_right=1;
191    if (!check_left) segs_left=1;
192
193    inside[i]=!(((segs_left&1)&&(segs_right&1)&&(segs_down&1)));
194  }
195}
196
197backtile::backtile(bFILE *fp)
198{
199  im=load_image(fp);
200  next=fp->read_uint16();
201}
202
203backtile::backtile(spec_entry *e, bFILE *fp)
204{
205  im=load_image(e,fp);
206  next=fp->read_uint16();
207}
208
209foretile::foretile(bFILE *fp)
210{
211    uint8_t *sl;
212    image *img = load_image(fp);
213
214    // create the micro image of the fore tile by averaging the color values
215    // in 2×2 space and storing the closest match
216
217    //uint8_t *buffer=(uint8_t *)&micro_image;
218    int x, y, w = img->width(), h = img->height(), l;
219    int r[AUTOTILE_WIDTH * AUTOTILE_HEIGHT],
220        g[AUTOTILE_WIDTH * AUTOTILE_HEIGHT],
221        b[AUTOTILE_WIDTH * AUTOTILE_HEIGHT],
222        t[AUTOTILE_WIDTH * AUTOTILE_HEIGHT];
223    memset(t, 0, AUTOTILE_WIDTH * AUTOTILE_HEIGHT * sizeof(int));
224    memset(r, 0, AUTOTILE_WIDTH * AUTOTILE_HEIGHT * sizeof(int));
225    memset(g, 0, AUTOTILE_WIDTH * AUTOTILE_HEIGHT * sizeof(int));
226    memset(b, 0, AUTOTILE_WIDTH * AUTOTILE_HEIGHT * sizeof(int));
227
228  if (!pal)
229  {
230    lbreak("Palette has no been defined\nuse load_palette before load_tiles");
231    exit(0);
232  }
233
234  if (!color_table)
235  {
236    lbreak("color filter has no been defined\nuse load_color_filter before load_tiles");
237    exit(0);
238  }
239
240  for (y=0; y<h; y++)
241  {
242    sl=img->scan_line(y);
243    for (x=0; x<w; x++,sl++)
244    {
245      l=(y*AUTOTILE_HEIGHT/h)*AUTOTILE_WIDTH +  x*AUTOTILE_WIDTH/w;
246      r[l]+=pal->red(*sl);
247      g[l]+=pal->green(*sl);
248      b[l]+=pal->blue(*sl);
249      t[l]++;
250    }
251  }
252  micro_image=new image(AUTOTILE_WIDTH,AUTOTILE_HEIGHT);
253
254  for (l=0; l<AUTOTILE_WIDTH*AUTOTILE_HEIGHT; l++)
255    micro_image->putpixel(  l%AUTOTILE_WIDTH , l/AUTOTILE_WIDTH,
256       color_table->lookup_color((r[l]/(t[l]*4/5))>>3,
257                 (g[l]/(t[l]*4/5))>>3,
258                 (b[l]/(t[l]*4/5))>>3));
259
260
261  im=new trans_image(img,"foretile");
262  delete img;
263
264  next=fp->read_uint16();
265  fp->read(&damage,1);
266
267
268  points=new boundary(fp,"foretile boundry");
269
270
271}
272
273int figure::size()
274{
275  return forward->size()+backward->size()+
276  hit->size()+
277  f_damage->size()+
278  b_damage->size()+sizeof(figure);
279}
280
281
282figure::figure(bFILE *fp, int type)
283{
284  image *im=load_image(fp);
285  forward=new trans_image(im,"figure data");
286  im->flip_x();
287  backward=new trans_image(im,"figure backward data");
288  delete im;
289
290  fp->read(&hit_damage,1);
291
292  fp->read(&xcfg,1);
293  xcfg=xcfg*scale_mult/scale_div;
294
295  if (type==SPEC_CHARACTER)
296  {
297    point_list p(fp);
298    advance=0;
299  } else advance=fp->read_uint8();
300
301  f_damage=new boundary(fp,"fig bound");
302  b_damage=new boundary(f_damage);
303  hit=new point_list(fp);
304}
305
306
307char_tint::char_tint(bFILE *fp)  // se should be a palette entry
308{
309  palette *p=new palette(fp);
310  uint8_t *t=data,*p_addr=(uint8_t *)p->addr();
311  for (int i=0; i<256; i++,t++,p_addr+=3)
312    *t=pal->find_closest(*p_addr,p_addr[1],p_addr[2]);
313
314  delete p;
315}
316
317
318
319
Note: See TracBrowser for help on using the repository browser.