#include "supmorph.hpp" #include "specs.hpp" #include "timage.hpp" #include "timing.hpp" #include "filter.hpp" #include "video.hpp" #include "jrand.hpp" #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(trans_image *hint1, trans_image *hint2, int aneal_steps, void (*stat_fun)(int)) { int x,y,w1=hint1->width(), h1=hint1->height(), w2=hint2->width(), h2=hint2->height(); 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->t_data(); for (y=0;yt_data(); 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 *)jmalloc(t*4,"morph movers"); /**************** Now scan the images again setup hints *********************/ dp=hint1->t_data(); for (y=0;yt_data(); for (y=0;ymovers,*paddr=(unsigned char *)pal->addr(),*pa; stepper *p; p=steps=(stepper *)jmalloc(sizeof(stepper)*m->t,"smorph steps"); 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 *)jmalloc(w*h,"hole image"); } int smorph_player::show(image *screen, int x, int y, color_filter *fil, palette *pal, int blur_threshold) { if (f_left) { int i,px,py,ix,iy; short x1,y1,x2,y2; screen->get_clip(x1,y1,x2,y2); screen->add_dirty(x,y,x+w-1,y+h-1); 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_color(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_color(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_color((r/t)>>3,(g/t)>>3,(b/t)>>3); } } ll+=2; tl+=2; nl+=2; } return 1; } else return 0; } /*void free_up_memory() { dprintf("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; trans_image *hh1=new trans_image(h1,"hint1"),*hh2=new trans_image(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; dprintf("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(); }*/