#include "macs.hpp" #include "particle.hpp" #include "view.hpp" #include "lisp.hpp" #include "cache.hpp" #include "jrand.hpp" static int total_pseqs=0; static part_sequence **pseqs=NULL; static part_animation *first_anim=NULL,*last_anim=NULL; void free_pframes() { for (int i=0;i=0 && idnext=pan; last_anim=pan; } } void delete_panims() { while (first_anim) { last_anim=first_anim; first_anim=first_anim->next; delete last_anim; } last_anim=NULL; } int defun_pseq(void *args) { lisp_symbol *sym=(lisp_symbol *)lcar(args); if (item_type(sym)!=L_SYMBOL) { lprint(args); printf("expecting first arg to def-particle to be a symbol!\n"); exit(0); } int sp=current_space; current_space=PERM_SPACE; set_symbol_number(sym,total_pseqs); // set the symbol value to the object number current_space=sp; pseqs=(part_sequence **)jrealloc(pseqs,sizeof(part_sequence *)*(total_pseqs+1),"particle seq array"); args=lcdr(args); pseqs[total_pseqs]=new part_sequence(args); total_pseqs++; return total_pseqs; } extern int total_files_open; part_sequence::part_sequence(void *args) { char *fn=lstring_value(lcar(args)); bFILE *fp=open_file(fn,"rb"); if (fp->open_failure()) { delete fp; lprint(args); fprintf(stderr,"\nparticle sequence : Unable to open %s for reading\n",fn); fprintf(stderr,"total files open=%d\n",total_files_open); FILE *fp=fopen(fn,"rb"); printf("convet = %d\n",fp!=NULL); exit(1); } // count how many frames are in the file spec_directory sd(fp); delete fp; tframes=0; int i=0; for (;itype==SPEC_PARTICLE) tframes++; frames=(int *)jmalloc(sizeof(int)*tframes,"part_frame id list\n"); int on=0; for (i=0;itype==SPEC_PARTICLE) frames[on++]=cash.reg(fn,sd.entries[i]->name,SPEC_PARTICLE,1); } part_frame::part_frame(bFILE *fp) { t=fp->read_long(); data=(part *)jmalloc(sizeof(part)*t,"particle frame"); x1=y1=100000; x2=y2=-100000; for (int i=0;iread_short(); short y=fp->read_short(); if (xx2) x2=x; if (y>y2) y2=x; data[i].x=x; data[i].y=y; data[i].color=fp->read_byte(); } } void tick_panims() { part_animation *last=NULL; for (part_animation *p=first_anim;p;) { p->frame++; if (p->frame>=p->seq->tframes) { if (last) last->next=p->next; else first_anim=first_anim->next; if (last_anim==p) last_anim=last; part_animation *d=p; p=p->next; delete d; } else { last=p; p=p->next; } } } void draw_panims(view *v) { for (part_animation *p=first_anim;p;p=p->next) { cash.part(p->seq->frames[p->frame])->draw(screen,p->x-v->xoff()+v->cx1,p->y-v->yoff()+v->cy1,p->dir); } } void part_frame::draw(image *screen, int x, int y, int dir) { short cx1,cy1,cx2,cy2; screen->get_clip(cx1,cy1,cx2,cy2); if (x+x1>cx2 || x+x2cy2 || y+y2y0) { while (i && pon->y<=cy2) { long dx=x-pon->x; if (dx>=cx1 && dx<=cx2) *(screen->scan_line(pon->y+y)+dx)=pon->color; i--; pon++; } } else { while (i && pon->y<=cy2) { long dx=pon->x+x; if (dx>=cx1 && dx<=cx2) *(screen->scan_line(pon->y+y)+dx)=pon->color; i--; pon++; } } } void scatter_line(int x1, int y1, int x2, int y2, int c, int s) { short cx1, cy1, cx2, cy2; screen->get_clip( cx1, cy1, cx2, cy2 ); int t = abs( x2 - x1 ) > abs( y2 - y1 ) ? abs( x2 - x1 ) + 1 : abs( y2 - y1 ) + 1; long xo = x1 << 16, yo = y1 << 16, dx = ( ( x2 - x1 ) << 16 ) / t, dy = ( ( y2 - y1 ) << 16 ) / t, x, y; int xm = ( 1 << s ); int ym = ( 1 << s ); s = ( 15 - s ); while( t-- ) { x = ( xo >> 16 ) + ( jrand() >> s ) - xm; y = ( yo >> 16 ) + ( jrand() >> s ) - ym; if( !( x < cx1 || y < cy1 || x > cx2 || y > cy2 ) ) { *(screen->scan_line( y ) + x ) = c; } xo += dx; yo += dy; } } void ascatter_line(int x1, int y1, int x2, int y2, int c1, int c2, int s) { short cx1, cy1, cx2, cy2; screen->get_clip( cx1, cy1, cx2, cy2 ); int t = abs( x2 - x1 ) > abs( y2 - y1 ) ? abs( x2 - x1 ) + 1 : abs( y2 - y1 ) + 1; long xo = x1 << 16, yo = y1 << 16, dx = ( ( x2 - x1 ) << 16 ) / t, dy = ( ( y2 - y1 ) <<16 ) / t, x, y; int xm = ( 1 << s ); int ym = ( 1 << s ); s = ( 15 - s ); int w = screen->width(); uchar *addr; while( t-- ) { x = ( xo >> 16 ) + ( jrand() >> s ) - xm; y = ( yo >> 16 ) + ( jrand() >> s ) - ym; if( !( x <= cx1 || y <= cy1 || x >= cx2 || y >= cy2 ) ) { addr = screen->scan_line( y ) + x; *addr = c1; *(addr + w) = c2; *(addr - w) = c2; *(addr - 1) = c2; *(addr + 1) = c2; } xo += dx; yo += dy; } }