source: abuse/trunk/src/particle.cpp @ 129

Last change on this file since 129 was 129, checked in by Sam Hocevar, 15 years ago
  • Get rid of jmalloc and replace it with standard malloc. Modern operating systems certainly perform a lot better than this custom implementation, and we have superior tools (eg. valgrind) to debug and profile memory usage without interfering with the code itself.
File size: 5.8 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 "macs.hpp"
13#include "particle.hpp"
14#include "view.hpp"
15#include "lisp.hpp"
16#include "cache.hpp"
17#include "jrand.hpp"
18
19
20static int total_pseqs=0;
21static part_sequence **pseqs=NULL;
22static part_animation *first_anim=NULL,*last_anim=NULL;
23
24void free_pframes()
25{
26  for (int i=0;i<total_pseqs;i++)
27    delete pseqs[i];
28  if (total_pseqs)
29    free(pseqs);
30}
31
32part_frame::~part_frame()
33{
34  free(data);
35}
36
37void add_panim(int id, long x, long y, int dir)
38{
39  CONDITION(id>=0 && id<total_pseqs,"bad id for particle animation");
40  part_animation *pan=new part_animation(pseqs[id],x,y,dir,NULL);
41  if (!first_anim)
42    first_anim=last_anim=pan;
43  else
44  {
45    last_anim->next=pan;
46    last_anim=pan;
47  }
48}
49
50void delete_panims()
51{
52  while (first_anim)
53  {
54    last_anim=first_anim;
55    first_anim=first_anim->next;
56    delete last_anim;
57  }
58  last_anim=NULL;
59}
60
61int defun_pseq(void *args)
62{
63  lisp_symbol *sym=(lisp_symbol *)lcar(args);
64  if (item_type(sym)!=L_SYMBOL)
65  {
66    lprint(args);
67    printf("expecting first arg to def-particle to be a symbol!\n");
68    exit(0);
69  }
70  int sp=current_space;
71  current_space=PERM_SPACE;
72  set_symbol_number(sym,total_pseqs);   // set the symbol value to the object number
73  current_space=sp;
74  pseqs=(part_sequence **)realloc(pseqs,sizeof(part_sequence *)*(total_pseqs+1));
75
76  args=lcdr(args);
77  pseqs[total_pseqs]=new part_sequence(args);
78  total_pseqs++;
79  return total_pseqs;
80}
81
82extern int total_files_open;
83
84part_sequence::part_sequence(void *args)
85{
86  char *fn=lstring_value(lcar(args));
87  bFILE *fp=open_file(fn,"rb");
88  if (fp->open_failure())
89  {
90    delete fp;
91    lprint(args);
92    fprintf(stderr,"\nparticle sequence : Unable to open %s for reading\n",fn);
93    fprintf(stderr,"total files open=%d\n",total_files_open);
94
95    FILE *fp=fopen(fn,"rb");
96    printf("convet = %d\n",fp!=NULL);
97    exit(1);
98  }
99
100  // count how many frames are in the file
101  spec_directory sd(fp);
102  delete fp;
103  tframes=0;
104  int i=0;
105  for (;i<sd.total;i++)
106    if (sd.entries[i]->type==SPEC_PARTICLE) tframes++;
107  frames=(int *)malloc(sizeof(int)*tframes);
108
109  int on=0;
110  for (i=0;i<sd.total;i++)
111    if (sd.entries[i]->type==SPEC_PARTICLE)
112      frames[on++]=cache.reg(fn,sd.entries[i]->name,SPEC_PARTICLE,1);
113
114}
115
116part_frame::part_frame(bFILE *fp)
117{
118  t=fp->read_uint32();
119  data=(part *)malloc(sizeof(part)*t);
120  x1=y1=100000; x2=y2=-100000;
121  for (int i=0;i<t;i++)
122  {
123    int16_t x=fp->read_uint16();
124    int16_t y=fp->read_uint16();
125    if (x<x1) x1=x;
126    if (y<y1) y1=y;
127    if (x>x2) x2=x;
128    if (y>y2) y2=x;
129    data[i].x=x;
130    data[i].y=y;
131    data[i].color=fp->read_uint8();
132  }
133}
134
135void tick_panims()
136{
137  part_animation *last=NULL;
138  for (part_animation *p=first_anim;p;)
139  {
140    p->frame++;
141    if (p->frame>=p->seq->tframes)
142    {
143      if (last)
144        last->next=p->next;
145      else first_anim=first_anim->next;
146      if (last_anim==p) last_anim=last;
147      part_animation *d=p;
148      p=p->next;
149      delete d;
150    } else
151    {
152      last=p;
153      p=p->next;
154    }
155
156  }
157}
158
159void draw_panims(view *v)
160{
161  for (part_animation *p=first_anim;p;p=p->next)
162  {
163    cache.part(p->seq->frames[p->frame])->draw(screen,p->x-v->xoff()+v->cx1,p->y-v->yoff()+v->cy1,p->dir);
164  }
165}
166
167void part_frame::draw(image *screen, int x, int y, int dir)
168{
169  int16_t cx1,cy1,cx2,cy2;
170  screen->get_clip(cx1,cy1,cx2,cy2);
171  if (x+x1>cx2 || x+x2<cx1 || y+y1>cy2 || y+y2<cy1) return ;
172
173  part *pon=data;
174  cy1-=y;
175  cy2-=y;
176
177  int i=t;
178  while (i && pon->y<cy1) { pon++; i--; }
179  if (!i) return ;
180  screen->lock();
181  if (dir>0)
182  {
183    while (i && pon->y<=cy2)
184    {
185      long dx=x-pon->x;
186      if (dx>=cx1 && dx<=cx2)
187      *(screen->scan_line(pon->y+y)+dx)=pon->color;
188      i--;
189      pon++;
190    }
191  } else
192  {
193    while (i && pon->y<=cy2)
194    {
195      long dx=pon->x+x;
196      if (dx>=cx1 && dx<=cx2)
197        *(screen->scan_line(pon->y+y)+dx)=pon->color;
198      i--;
199      pon++;
200    }
201  }
202  screen->unlock();
203}
204
205void scatter_line(int x1, int y1, int x2, int y2, int c, int s)
206{
207    int16_t cx1, cy1, cx2, cy2;
208    screen->get_clip( cx1, cy1, cx2, cy2 );
209
210    int t = abs( x2 - x1 ) > abs( y2 - y1 ) ? abs( x2 - x1 ) + 1 : abs( y2 - y1 ) + 1;
211    long xo = x1 << 16, yo = y1 << 16, dx = ( ( x2 - x1 ) << 16 ) / t, dy = ( ( y2 - y1 ) << 16 ) / t, x, y;
212
213    int xm = ( 1 << s );
214    int ym = ( 1 << s );
215    s = ( 15 - s );
216
217    screen->lock();
218    while( t-- )
219    {
220        x = ( xo >> 16 ) + ( jrand() >> s ) - xm;
221        y = ( yo >> 16 ) + ( jrand() >> s ) - ym;
222        if( !( x < cx1 || y < cy1 || x > cx2 || y > cy2 ) )
223        {
224            *(screen->scan_line( y ) + x ) = c;
225        }
226        xo += dx;
227        yo += dy;
228    }
229    screen->unlock();
230}
231
232
233
234void ascatter_line(int x1, int y1, int x2, int y2, int c1, int c2, int s)
235{
236    int16_t cx1, cy1, cx2, cy2;
237    screen->get_clip( cx1, cy1, cx2, cy2 );
238
239    int t = abs( x2 - x1 ) > abs( y2 - y1 ) ? abs( x2 - x1 ) + 1 : abs( y2 - y1 ) + 1;
240    long xo = x1 << 16, yo = y1 << 16, dx = ( ( x2 - x1 ) << 16 ) / t, dy = ( ( y2 - y1 ) <<16 ) / t, x, y;
241
242    int xm = ( 1 << s );
243    int ym = ( 1 << s );
244    s = ( 15 - s );
245
246    screen->lock();
247
248    int w = screen->width();
249    uint8_t *addr;
250
251    while( t-- )
252    {
253        x = ( xo >> 16 ) + ( jrand() >> s ) - xm;
254        y = ( yo >> 16 ) + ( jrand() >> s ) - ym;
255        if( !( x <= cx1 || y <= cy1 || x >= cx2 || y >= cy2 ) )
256        {
257            addr = screen->scan_line( y ) + x;
258            *addr = c1;
259            *(addr + w) = c2;
260            *(addr - w) = c2;
261            *(addr - 1) = c2;
262            *(addr + 1) = c2;
263        }
264        xo += dx;
265        yo += dy;
266    }
267
268    screen->unlock();
269}
270
Note: See TracBrowser for help on using the repository browser.