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

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

imlib: use vec2i for image::size and unroll all necessary changes
everywhere else in the code.

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