/* * Abuse - dark 2D side-scrolling platform game * Copyright (c) 1995 Crack dot Com * Copyright (c) 2005-2011 Sam Hocevar * * This software was released into the Public Domain. As with most public * domain software, no warranty is made or implied by Crack dot Com, by * Jonathan Clark, or by Sam Hocevar. */ #if defined HAVE_CONFIG_H # include "config.h" #endif #include "common.h" #include "supmorph.h" #include "specs.h" #include "transimage.h" #include "timing.h" #include "filter.h" #include "video.h" #include "jrand.h" #define p_swap(x,y) { x^=y; y^=x; x^=y; } #define p_dist(x1,y1,x2,y2) (((int)(x1)-(int)x2)*((int)(x1)-(int)x2)+ \ ((int)(y1)-(int)y2)*((int)(y1)-(int)y2)) super_morph::super_morph(TransImage *hint1, TransImage *hint2, int aneal_steps, void (*stat_fun)(int)) { int x,y,w1=hint1->Size().x, h1=hint1->Size().y, w2=hint2->Size().x, h2=hint2->Size().y; if (w1>w2) w=w1; else w=w2; if (h1>h2) h=h1; else h=h2; unsigned char *dp; /************************ count up the number of hints ****************************/ unsigned short hints1[256],hints2[256]; memset(hints1,0,256*2); memset(hints2,0,256*2); dp=hint1->Data(); for (y=0; yData(); for (y=0; y*h2p) totals[y]=*h1p; else totals[y]=*h2p; start+=totals[y]; hint_color[total_hints++]=y; } t=start; movers=(unsigned char *)malloc(t*4); /**************** Now scan the images again setup hints *********************/ dp=hint1->Data(); for (y=0; yData(); for (y=0; ymovers,*paddr=(unsigned char *)pal->addr(),*pa; stepper *p; p=steps=(stepper *)malloc(sizeof(stepper)*m->t); f_left=frames; frames--; t=m->t; w=m->w; h=m->h; for (i=0; iscan_line(y1)+x1))*3; r1=*(pa++); g1=*(pa++); b1=*(pa++); pa=paddr+(int)(*(i2->scan_line(y2)+x2))*3; r2=*(pa++); g2=*(pa++); b2=*(pa++); p->r=r1<<16; p->g=g1<<16; p->b=b1<<16; p->dr=(long)(((int)r2-(int)r1)<<16)/frames; p->dg=(long)(((int)g2-(int)g1)<<16)/frames; p->db=(long)(((int)b2-(int)b1)<<16)/frames; if (dir<0) { x1=w-x1-1; x2=w-x2-1; } p->dx=((x2-x1)<<16)/frames; p->dy=((y2-y1)<<16)/frames; p->x=x1<<16; p->y=y1<<16; } hole=(unsigned char *)malloc(w*h); } int smorph_player::show(image *screen, int x, int y, ColorFilter *fil, palette *pal, int blur_threshold) { if (f_left) { int i,px,py,ix,iy; int x1, y1, x2, y2; screen->GetClip(x1, y1, x2, y2); screen->AddDirty(x, y, x + w, y + h); stepper *ss; memset(hole,0,w*h); unsigned char *paddr=(unsigned char *)pal->addr(); for (ss=steps,i=0; ix>>(16)); iy=(ss->y>>(16)); px=ix+x; py=iy+y; if (px>=x1 && px < x2 && py>=y1 && py < y2) { hole[ix+iy*w]=*(screen->scan_line(py)+px)=fil->Lookup(ss->r>>(19), ss->g>>(19), ss->b>>(19)); } ss->x+=ss->dx; ss->y+=ss->dy; ss->r+=ss->dr; ss->g+=ss->dg; ss->b+=ss->db; } f_left--; if (!f_left) // skip hole fills and smoothing on last frame return 1; unsigned char *ll=hole+1,*tl=hole+w+1,*nl=hole+w*2+1; for (iy=1; iy=x1 && x+ix < x2 && y+iy>=y1 && y+iy < y2) { int t=0; unsigned char *pa; int r=0,g=0,b=0; /* if (*(tl-1)) t++; if (*(tl+1)) t++; if (*ll) t++; if (*nl) t++; */ if (*(tl-1)) { t++; pa=paddr+(*(tl-1))*3; r+=*(pa++); g+=*(pa++); b+=*(pa++); } if (*(tl+1)) { t++; pa=paddr+(*(tl+1))*3; r+=*(pa++); g+=*(pa++); b+=*(pa++); } if (*(ll)) { t++; pa=paddr+(*ll)*3; r+=*(pa++); g+=*(pa++); b+=*(pa++); } if (*(nl)) { t++; pa=paddr+(*nl)*3; r+=*(pa++); g+=*(pa++); b+=*(pa++); } if (*tl) { if (t) { pa=paddr+(*tl)*3; r/=t; g/=t; b/=t; int dist=((int)(*pa)-r)*((int)(*pa)-r); pa++; dist+=((int)(*pa)-g)*((int)(*pa)-g); pa++; dist+=((int)(*pa)-b)*((int)(*pa)-b); if (dist>blur_threshold) *(tl)=*(screen->scan_line(y+iy)+x+ix)=fil->Lookup(r>>3,g>>3,b>>3); } else *(tl)=*(screen->scan_line(y+iy)+x+ix)=0; // kill single pixels } else if (t>=3) *(tl)=*(screen->scan_line(y+iy)+x+ix)=fil->Lookup((r/t)>>3,(g/t)>>3,(b/t)>>3); } } ll+=2; tl+=2; nl+=2; } return 1; } else return 0; } /*void free_up_memory() { printf("you're screwed\n"); } main(int argc, char **argv) { image_init(); jrand_init(); FILE *fp=fopen("art/mrphmask.spe","rb"); spec_directory sd(fp); image *h1=new image(sd.find("20 h"),fp), *h2=new image(sd.find("1h"),fp), *i1=new image(sd.find("20"),fp), *i2=new image(sd.find("1"),fp); palette *pal=new palette(sd.find(SPEC_PALETTE),fp); color_filter *fil=new color_filter(sd.find(SPEC_COLOR_TABLE),fp); int steps=atoi(argv[1]); if (steps<2) steps=50; TransImage *hh1=new TransImage(h1,"hint1"),*hh2=new TransImage(h2,"hint2"); time_marker time1; super_morph sm(hh1,hh2,steps); int frames=atoi(argv[2]); if (frames<2) frames=16; smorph_player sp(&sm,pal,i1,i2,frames,-1); time_marker time2; printf("time = %lf\n",time2.diff_time(&time1)); set_mode(19,argc,argv); pal->load(); i1->put_image(screen,30,30); update_dirty(screen); sleep(2); while (sp.show(screen,30,30,fil,pal)) { update_dirty(screen); screen->bar(30,30,30+sp.w,30+sp.h,0); } sleep(2); close_graphics(); }*/