/* mhl.c by Michael Thorpe 2019-08-10 */ #include #include #include #include #include #include #include #include #include #include #include #include #include "runner.h" #define DEFAULT_SPEED 113 /* 0=full speed, 113=half speed by default */ #define ONLY_MOVE_WHEN_OFF 1 /* 0=move even when dimmer!=0, 1=only when dark */ /* These are wrong, but should be kept in some form */ #if OLD_STYLE_LIGHT_BOARD #define IN_PAN 40 /* fader 48 */ #define IN_TILT 42 /* fader 47 */ #define IN_DIM 47 /* fader 46 */ #define IN_SCENE 46 /* fader 45 */ #define IN_GOBO 45 /* fader 44 */ #define IN_FOCUS 44 /* fader 43 */ #else #define IN_PAN 12 #define IN_TILT 11 #define IN_DIM 10 #define IN_SCENE 9 #define IN_GOBO 25 #define IN_FOCUS 26 #endif /* These are 0-based (i.e., one smaller than the manual says) */ #define PAN (1-1) #if FINE_MODE #define PAN2 (PAN+1) #endif #define TILT (3-!FINE_MODE-1) #if FINE_MODE #define TILT2 (TILT+1) #endif #define COLOR (5-!FINE_MODE-!FINE_MODE-1) #define RGOBO (6-!FINE_MODE-!FINE_MODE-1) #define ROTATION (7-!FINE_MODE-!FINE_MODE-1) #define FGOBO (8-!FINE_MODE-!FINE_MODE-1) #define PRISM (9-!FINE_MODE-!FINE_MODE-1) #define FOCUS (10-!FINE_MODE-!FINE_MODE-1) #define SHUTTER (11-!FINE_MODE-!FINE_MODE-1) #define DIMMER (12-!FINE_MODE-!FINE_MODE-1) #define SPEED (13-!FINE_MODE-!FINE_MODE-1) #define SPECIAL (14-!FINE_MODE-!FINE_MODE-1) #define NUM_CHANNELS (14-!FINE_MODE-!FINE_MODE) struct mhlscene { float panbase,tiltbase; float panscale,tiltscale; unsigned char gobo,focus; int color; }; int mhl_base_pos=0,mhl_last_pos=-1; static unsigned char curvals[NUM_CHANNELS]; static int curchan=0; static struct mhlscene *mhlscenes; static int nummhlscenes=0; static int curscenenum=-1; static void setval(int chan,unsigned char val) { int i=0,j,k; char line[80]; int on=-1,off=-1; assert(0<=curscenenum); assert(curscenenumfunc(curlook,IN_PAN)-128)/256.; break; case TILT: case TILT2: mhlscenes[curscenenum].tiltbase=(float)curvals[TILT]+(float)curvals[TILT2]/256.-mhlscenes[curscenenum].tiltscale*(curlook->func(curlook,IN_TILT)-128)/256.; break; #else case PAN: mhlscenes[curscenenum].panbase=val-mhlscenes[curscenenum].panscale*(curlook->func(curlook,IN_PAN)-128)/256.; break; case TILT: mhlscenes[curscenenum].tiltbase=val-mhlscenes[curscenenum].tiltscale*(curlook->func(curlook,IN_TILT)-128)/256.; break; #endif /* COLOR is handled above the value change so we can leave "unspecified" as a color */ case FGOBO: mhlscenes[curscenenum].gobo=val; break; case FOCUS: mhlscenes[curscenenum].focus=val; break; } } if(!mhlframe.h || !mhlframe.w) return; if(curchan==chan) { on=0; off=3; } switch(chan) { case PAN: #if FINE_MODE case PAN2: if(PAN==curchan) { on=0; off=3; } else if(PAN2==curchan) { on=4; off=7; } #endif k=0; i+=sprintf(line+i,"%3u",curvals[PAN]); #if FINE_MODE line[i++]='.'; i+=sprintf(line+i,"%-3u",curvals[PAN2]); #endif i+=sprintf(line+i," Pan"); break; case TILT: #if FINE_MODE case TILT2: if(TILT==curchan) { on=0; off=3; } else if(TILT2==curchan) { on=4; off=7; } #endif k=1; i+=sprintf(line+i,"%3u",curvals[TILT]); #if FINE_MODE line[i++]='.'; i+=sprintf(line+i,"%-3u",curvals[TILT2]); #endif i+=sprintf(line+i," Tilt"); break; case COLOR: k=2; i+=sprintf(line+i,"%3u Color: ",curvals[COLOR]); if(curvals[COLOR]<=13) i+=sprintf(line+i,"white"); else if(curvals[COLOR]<=27) i+=sprintf(line+i,"red"); else if(curvals[COLOR]<=41) i+=sprintf(line+i,"blue"); else if(curvals[COLOR]<=55) i+=sprintf(line+i,"green"); else if(curvals[COLOR]<=69) i+=sprintf(line+i,"yellow"); else if(curvals[COLOR]<=83) i+=sprintf(line+i,"magenta"); else if(curvals[COLOR]<=97) i+=sprintf(line+i,"orange"); else if(curvals[COLOR]<=111) i+=sprintf(line+i,"purple"); else if(curvals[COLOR]<=127) i+=sprintf(line+i,"pink"); else if(curvals[COLOR]<=187) { i+=sprintf(line+i,"forwards (%u%%)",100*(188-curvals[COLOR])/(188-128)); } else if(curvals[COLOR]<=193) i+=sprintf(line+i,"stopped"); else { i+=sprintf(line+i,"backwards (%u%%)",100*(curvals[COLOR]-193)/(255-193)); } break; case RGOBO: k=3; i+=sprintf(line+i,"%3u Rotating gobos: ",curvals[RGOBO]); if(curvals[RGOBO]<=9) i+=sprintf(line+i,"open"); else if(curvals[RGOBO]<=19) i+=sprintf(line+i,"#1 = stars"); else if(curvals[RGOBO]<=29) i+=sprintf(line+i,"#2 = phone dial"); else if(curvals[RGOBO]<=39) i+=sprintf(line+i,"#3 = sunburst"); else if(curvals[RGOBO]<=49) i+=sprintf(line+i,"#4 = spiral"); else if(curvals[RGOBO]<=59) i+=sprintf(line+i,"#5 = triangle"); else if(curvals[RGOBO]<=69) i+=sprintf(line+i,"#6 = textured"); else if(curvals[RGOBO]<=89) i+=sprintf(line+i,"#1 shake %u%%",100*(curvals[RGOBO]-69)/(89-69)); else if(curvals[RGOBO]<=109) i+=sprintf(line+i,"#2 shake %u%%",100*(curvals[RGOBO]-89)/(109-89)); else if(curvals[RGOBO]<=129) i+=sprintf(line+i,"#3 shake %u%%",100*(curvals[RGOBO]-109)/(129-109)); else if(curvals[RGOBO]<=149) i+=sprintf(line+i,"#4 shake %u%%",100*(curvals[RGOBO]-129)/(149-129)); else if(curvals[RGOBO]<=169) i+=sprintf(line+i,"#5 shake %u%%",100*(curvals[RGOBO]-149)/(169-149)); else if(curvals[RGOBO]<=189) i+=sprintf(line+i,"#6 shake %u%%",100*(curvals[RGOBO]-169)/(189-169)); else i+=sprintf(line+i,"scroll %u%%",100*(curvals[RGOBO]-189)/(255-189)); break; case ROTATION: k=4; i+=sprintf(line+i,"%3u Gobo rotation: ",curvals[ROTATION]); if(curvals[ROTATION]<=127) i+=sprintf(line+i,"indexed to %u%%",100*curvals[ROTATION]/127); else if(curvals[ROTATION]<=187) i+=sprintf(line+i,"forward %u%%",100*(188-curvals[ROTATION])/(188-128)); else if(curvals[ROTATION]<=193) i+=sprintf(line+i,"stopped"); else i+=sprintf(line+i,"backward %u%%",100*(curvals[ROTATION]-193)/(255-193)); break; case FGOBO: k=5; i+=sprintf(line+i,"%3u Fixed gobos: ",curvals[FGOBO]); if(curvals[FGOBO]<=13) i+=sprintf(line+i,"open (4/10 throw)"); else if(curvals[FGOBO]<=27) i+=sprintf(line+i,"#1 = Celtic knot"); else if(curvals[FGOBO]<=41) i+=sprintf(line+i,"#2 = apple slices/tart"); else if(curvals[FGOBO]<=55) i+=sprintf(line+i,"#3 = volleyball/BofA"); else if(curvals[FGOBO]<=69) i+=sprintf(line+i,"#4 = sunburst (.5/10 hole)"); else if(curvals[FGOBO]<=83) i+=sprintf(line+i,"#5 = film/plant (1/10 hole)"); else if(curvals[FGOBO]<=97) i+=sprintf(line+i,"#6 = Pikachutlotl (1.5/10 hole)"); else if(curvals[FGOBO]<=111) i+=sprintf(line+i,"#7 = iris (2/10 hole)"); else if(curvals[FGOBO]<=127) i+=sprintf(line+i,"#1 shake %u%%",100*(curvals[FGOBO]-111)/(127-111)); else if(curvals[FGOBO]<=143) i+=sprintf(line+i,"#2 shake %u%%",100*(curvals[FGOBO]-127)/(143-127)); else if(curvals[FGOBO]<=159) i+=sprintf(line+i,"#3 shake %u%%",100*(curvals[FGOBO]-143)/(159-143)); else if(curvals[FGOBO]<=175) i+=sprintf(line+i,"#4 shake %u%%",100*(curvals[FGOBO]-159)/(175-159)); else if(curvals[FGOBO]<=191) i+=sprintf(line+i,"#5 shake %u%%",100*(curvals[FGOBO]-175)/(191-175)); else if(curvals[FGOBO]<=207) i+=sprintf(line+i,"#6 shake %u%%",100*(curvals[FGOBO]-191)/(207-191)); else if(curvals[FGOBO]<=223) i+=sprintf(line+i,"#7 shake %u%%",100*(curvals[FGOBO]-207)/(223-207)); else i+=sprintf(line+i,"rotating %u%%",100*(curvals[FGOBO]-223)/(255-223)); break; case PRISM: k=6; i+=sprintf(line+i,"%3u Prism: ",curvals[PRISM]); if(curvals[PRISM]<=3) i+=sprintf(line+i,"open"); else if(curvals[PRISM]<=63) i+=sprintf(line+i,"forward %u%%",100*(64-curvals[PRISM])/(64-4)); else if(curvals[PRISM]<=67) i+=sprintf(line+i,"stopped"); else if(curvals[PRISM]<=127) i+=sprintf(line+i,"backward %u%%",100*(curvals[PRISM]-67)/(127-67)); else i+=sprintf(line+i,"macro %u",1+(curvals[PRISM]-128)/8); break; case FOCUS: k=7; i+=sprintf(line+i,"%3u Focus",curvals[FOCUS]); break; case SHUTTER: k=8; i+=sprintf(line+i,"%3u Shutter: ",curvals[SHUTTER]); if(curvals[SHUTTER]<=31) i+=sprintf(line+i,"closed"); else if(curvals[SHUTTER]<=63) i+=sprintf(line+i,"open"); else if(curvals[SHUTTER]<=95) i+=sprintf(line+i,"strobe %u%%",100*(curvals[SHUTTER]-63)/(95-63)); else if(curvals[SHUTTER]<=127) i+=sprintf(line+i,"open"); else if(curvals[SHUTTER]<=159) i+=sprintf(line+i,"pulse effect"); else if(curvals[SHUTTER]<=191) i+=sprintf(line+i,"open"); else if(curvals[SHUTTER]<=223) i+=sprintf(line+i,"random strobe %u%%",100*(curvals[SHUTTER]-191)/(223-191)); else i+=sprintf(line+i,"open"); break; case DIMMER: k=9; i+=sprintf(line+i,"%3u Dimmer",curvals[DIMMER]); break; case SPEED: k=10; i+=sprintf(line+i,"%3u Speed: ",curvals[SPEED]); if(curvals[SPEED]<=225) i+=sprintf(line+i,"%u%%",100*(226-curvals[SPEED])/226); else if(curvals[SPEED]<=235) i+=sprintf(line+i,"blackout by movement"); else if(curvals[SPEED]<=245) i+=sprintf(line+i,"blackout by wheel change"); else i+=sprintf(line+i,"no function"); break; case SPECIAL: k=11; i+=sprintf(line+i,"%3u Special: ",curvals[SPECIAL]); if(curvals[SPECIAL]<=19) i+=sprintf(line+i,"normal"); else if(curvals[SPECIAL]<=39) i+=sprintf(line+i,"any position"); else if(curvals[SPECIAL]<=59) i+=sprintf(line+i,"lamp on"); else if(curvals[SPECIAL]<=79) i+=sprintf(line+i,"lamp off"); else if(curvals[SPECIAL]<=99) i+=sprintf(line+i,"motor reset"); else if(curvals[SPECIAL]<=119) i+=sprintf(line+i,"internal program 1"); else if(curvals[SPECIAL]<=139) i+=sprintf(line+i,"internal program 2"); else if(curvals[SPECIAL]<=159) i+=sprintf(line+i,"internal program 3"); else if(curvals[SPECIAL]<=179) i+=sprintf(line+i,"internal program 4"); else if(curvals[SPECIAL]<=199) i+=sprintf(line+i,"internal program 5"); else if(curvals[SPECIAL]<=219) i+=sprintf(line+i,"internal program 6"); else if(curvals[SPECIAL]<=239) i+=sprintf(line+i,"internal program 7"); else i+=sprintf(line+i,"sound active"); break; } if(kfunc(curlook,IN_DIM)); pan=mhlscenes[curscenenum].panbase*256+mhlscenes[curscenenum].panscale*(curlook->func(curlook,IN_PAN)-128); tilt=mhlscenes[curscenenum].tiltbase*256+mhlscenes[curscenenum].tiltscale*(curlook->func(curlook,IN_TILT)-128); if(pan<0) pan=0; if(65535func(curlook,IN_DIM)); } void mhl_setscene(int mhlposidx) { if(-1 != mhlposidx) desiredscenenum=mhlposidx; } unsigned char mhl_output(int subchan) { if(0<=subchan && subchan