source: abuse/tags/pd/macabuse/src/items.c @ 604

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