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

Last change on this file since 682 was 682, checked in by Sam Hocevar, 9 years ago

core: rename vec2i to ivec2 and update matrix.h from Lol Engine.

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