/* fade.c by Michael Thorpe 2018-12-04 */ /* This file gets #include'd into scenes.c so we have those definitions */ #include #include static double fadestart; static double fadefrac; static int fadetoscenenum; extern struct look fadelook; /* C stupidly disallows extern static */ static struct dmx fadetmpdmx={len:DMX_MAXCHAN}; static struct look fadetmp={name:".fadetmp",func:storedlook,dmx:&fadetmpdmx}; static struct look *fademode=0; static void fade_setup(int newscenenum) { int i; /* If we're already fading, make a copy of where we are and fade from there. */ if(&fadelook==curlook) { /* FIXME: This still doesn't work if we're triple-fading */ fadetmpdmx.len=DMX_MAXCHAN; for(i=1;i<=fadetmpdmx.len;i++) fadetmpdmx.data[i]=fadelook.func(&fadelook,i); fadelook.subs[0]=&fadetmp; } else { fadelook.subs[0]=curlook; } fadelook.subs[1]=scenes[newscenenum].look; fadestart=gettime(); fadefrac=0; fadetoscenenum=newscenenum; curlook=&fadelook; } static void fade_update(struct look *me,double now) { double sofar=now-fadestart; if(sofar<0) sofar=0; fadefrac=sofar/scenes[fadetoscenenum].fadetime; if(fadefrac>1.) /* we're still fading */ fadefrac=1.; if(scenes[fadetoscenenum].fadetime+scenes[fadetoscenenum].followtime<=sofar) { curlook=fadelook.subs[1]; if(scenes[fadetoscenenum].followtime) { startscene(fadetoscenenum+1); scenes_redraw(); } } } static unsigned char fade_get(struct look *me,int chan) { unsigned char ca,cb; double da,db; /* the "fademode" look supports per-channel fade modes defined as follows: * 0=LINEAR // linear ramp from prev to next * 1=IMMEDIATE // jump to next immediately * 2=MIDFADE // stay on prev until halfway through fade then jump to next * 3=ENDOFFADE // stay on prev until fade is done * 4=HTP // pick max of prev and next * 5=ZERO // output 0 during fade if prev and next don't match * 6=COARSE // this is MSB of 16-bit value, next channel is LSB * 7=FINE // this is LSB of 16-bit value, prev channel is MSB */ switch((fademode && chan<=fademode->dmx->len)?fademode->dmx->data[chan]:0) { case 0: /* LINEAR */ default: db=fadelook.subs[1]->func(fadelook.subs[1],chan); if(1. != fadefrac) { da=fadelook.subs[0]->func(fadelook.subs[0],chan); db=fadefrac*db + (1-fadefrac)*da; } if(db<0.) db=0.; if(255.func(fadelook.subs[1],chan)); case 2: /* MIDFADE */ if(fadefrac<.5) return(fadelook.subs[0]->func(fadelook.subs[0],chan)); return(fadelook.subs[1]->func(fadelook.subs[1],chan)); case 3: /* ENDOFFADE */ return(fadelook.subs[0]->func(fadelook.subs[0],chan)); case 4: /* HTP */ ca=fadelook.subs[0]->func(fadelook.subs[0],chan); cb=fadelook.subs[1]->func(fadelook.subs[1],chan); if(cafunc(fadelook.subs[1],chan); db*=256; db+=fadelook.subs[1]->func(fadelook.subs[1],chan+1); if(1. != fadefrac) { da=fadelook.subs[0]->func(fadelook.subs[0],chan); da*=256; da+=fadelook.subs[0]->func(fadelook.subs[0],chan+1); db=fadefrac*db + (1-fadefrac)*da; } if(db<0.) db=0.; if(65535.>8); case 7: /* LSB */ db=(1func(fadelook.subs[1],chan-1):0; db*=256; db+=fadelook.subs[1]->func(fadelook.subs[1],chan); if(1. != fadefrac) { da=(1func(fadelook.subs[0],chan-1):0; da*=256; da+=fadelook.subs[0]->func(fadelook.subs[0],chan); db=fadefrac*db + (1-fadefrac)*da; } if(db<0.) db=0.; if(65535.