source: abuse/branches/pd/macabuse/src/particle.c @ 636

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