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

Last change on this file since 97 was 56, checked in by Sam Hocevar, 11 years ago
  • Add licensing terms to most C / C++ files (Ref #5).
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.hpp"
13#include "lisp.hpp"
14#include "dev.hpp"
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 *)jmalloc(tot,"Boundary point list"); 
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 *)jmalloc(tot,"Boundary point list"); 
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
214  // create the micro image of the fore tile by aveginging the color values in 2 x 2 space
215  // and storeing teh closest match
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.