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

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

Fuck the history, I'm renaming all .hpp files to .h for my own sanity.

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