/* xmas.tc - lrb - 5/22/2008 /* This program plays Christmas carols. /* It's written in tiny-c/PC. The music data was taken from a /* BASIC program written by Ray Knapp around 1990. /* It requires ansi.sys (or equivalent) for color and /* highlight/lowlight screen commands to work. /* cosmetic mods - 12/11/2009 int oct(23) /* two octaves char sc(600) /* music script int speed,spd int ob /* octave base int dur /* duration of note int music /* music on / off switch char ma(2) /* music on / off array char ct(9*35) /* carol titles xmas [ /* main program oct(0)=261;oct(1)=277;oct(2)=293;oct(3)=311;oct(4)=329;oct(5)=349 oct(6)=370;oct(7)=392;oct(8)=415;oct(9)=440;oct(10)=466;oct(11)=493 oct(12)=523;oct(13)=554;oct(14)=587;oct(15)=622;oct(16)=659;oct(17)=698 oct(18)=740;oct(19)=784;oct(20)=830;oct(21)=880;oct(22)=932;oct(23)=987 strcat(ct,"We three kings ") strcat(ct,"O come, all ye faithful ") strcat(ct,"Hark! The herald angles sing ") strcat(ct,"Silent night ") strcat(ct,"O little town of Bethlehem ") strcat(ct,"Away in the manger ") strcat(ct,"The first Noel ") strcat(ct,"It came upon the midnight clear ") strcat(ct,"Joy to the world! ") char c;music=1 /* start w/ music on ma="n";char ch(1) /* holds user command character int i,j while (1) [ /* display play menu, get user command, launch it cls;i=-1 pl " ";hilo('1');ps "xmas.tc - lrb - 5/22/2008";hilo('0');pl "" while ((i=i+1)<9 ) [ /* display carol titles pl " ";pn i+1;ps ". " j=-1;while ((j=j+1)<35) putchar ct(35*i+j) ] pl "" pl " r. Random carol" pl " a. All carols" pl " m. Toggle music on / off (currently " hilo('1');ps "o";ps ma;hilo('0');ps ")" pl " x. Exit" pl "";pl " ? ";c=getchar if (c=='x') break ch(0)=c;ch(1)=0 if (index("123456789ram",12,ch,1)) lc c /* launch command if valid i=30;while (i=i-1) pause 2000 ] ] lc char c [ /* launch command if (c=='r') pc (c=random('1','9')) else if (c=='a') [ int i c='0';while ((c=c+1)<='9') [i=30;while (i=i-1) pause 2000;pc(c)] ] else if (c=='m') [ music=1-music;if (music) ma="n";else ma="ff" ] else pc c /* play carol ] pc char c [ /* play carol cls;spd=600;speed=spd/100 /* default tempo int ci;ci=c-'1' /* used as index into titles string sc(0)=0 /* clear the music script int j;j=-1;pl "";pl "" hilo('1');color(random('1','6')) while ((j=j+1)<35) putchar ct(35*ci+j);pl "" hilo('0');color('7') if (c=='1') kings else if (c=='2') ocome else if (c=='3') hark else if (c=='4') silent else if (c=='5') little else if (c=='6') away else if (c=='7') noel else if (c=='8') midnight else if (c=='9') joy int i;i=0;char wstr(7) while (music*sc(i)) [ /* play the script if music is on j=0 while (sc(i)!=' ') [ /* build the play command wstr(j)=sc(i);i=i+1;j=j+1 ] wstr(j)=0 /* null terminate it process wstr /* do the command (tempo, length, note, pause, octave) i=i+1 /* advance to next play command ] ] process char cmd(0) [ /* music command processor int w(0) if (cmd(0)=='T') [atoi(cmd+1,w);tempo(w(0))] else if (cmd(0)=='P') [atoi(cmd+1,w);pause(800*speed*w(0)/8)] else if (cmd(0)=='O') [atoi(cmd+1,w);octave(w(0)] else if (cmd(0)=='L') [atoi(cmd+1,w);length(w(0)] else if (cmd(0)=='C') pnote(0,(cmd+1)) else if (cmd(0)=='D') pnote(2,(cmd+1)) else if (cmd(0)=='E') pnote(4,(cmd+1)) else if (cmd(0)=='F') pnote(5,(cmd+1)) else if (cmd(0)=='G') pnote(7,(cmd+1)) else if (cmd(0)=='A') pnote(9,(cmd+1)) else if (cmd(0)=='B') pnote(11,(cmd+1)) ] tempo int i [speed=spd/i] octave int o [ob=(o-4)*12] length int l [dur=speed*8/l] pnote int p;char sharp(0) [ /* play the note int off /* offet if (sharp(0)=='#') off=1 if (sharp(0)=='-') off=-1 play (oct(ob+p+off),dur) ] play int f,d [beep(f,d)] pause int k [ int l;while ((l=l+1)