BuckoBrand Posted December 3, 2018 Share Posted December 3, 2018 (edited) Can we try and get some more Christmas songs programmed into the Ti, like O Christmas Tree or Jingle Bell Rock... I also like We Three Kings. Edited December 3, 2018 by BuckoBrand 1 Quote Link to comment Share on other sites More sharing options...
Opry99er Posted December 3, 2018 Share Posted December 3, 2018 Hey Buck!! I'll try to do We Three Kings before Christmas. Maybe you could get on Magellan and make a nice screen to show while the music plays? 1 Quote Link to comment Share on other sites More sharing options...
sparkdrummer Posted December 3, 2018 Share Posted December 3, 2018 See YESTERDAYS NEWS post #93, 4 disks of Christmas Music. 6 Quote Link to comment Share on other sites More sharing options...
LASooner Posted December 5, 2018 Share Posted December 5, 2018 I decided to try and get something done. Hopefully by Christmas. :-) 2 Quote Link to comment Share on other sites More sharing options...
LASooner Posted December 7, 2018 Share Posted December 7, 2018 (edited) Made this in my spare time over the last few days load and run in XB Props to Harry for making XB256 so easy to knock out something like this quickly. Apologies for the music, I had to figure out sheet music and converting it to TI sound calls. I don't think I have that quite down yet. :-) Alright, who's next? Your turn... Go! letitsnow.zip Christmas8.bin Edited December 7, 2018 by LASooner 14 Quote Link to comment Share on other sites More sharing options...
Opry99er Posted December 7, 2018 Share Posted December 7, 2018 That's awesome!!!! 1 Quote Link to comment Share on other sites More sharing options...
ti99iuc Posted December 7, 2018 Share Posted December 7, 2018 really nice LASooner thanks for sharing it 1 Quote Link to comment Share on other sites More sharing options...
Tursi Posted December 7, 2018 Share Posted December 7, 2018 Lots of pacing in that house, can't find the screwdriver to assemble Junior's gifts? Really slick work 3 Quote Link to comment Share on other sites More sharing options...
LASooner Posted December 7, 2018 Share Posted December 7, 2018 Excitedly looking out the window for Santa? Thieves cleaning it out? Swing dancing? I just wanted some activity going on in the windows. :-) 4 Quote Link to comment Share on other sites More sharing options...
geoanas Posted December 8, 2018 Share Posted December 8, 2018 Very nice! Thanks for sharing it! 1 Quote Link to comment Share on other sites More sharing options...
blakespot Posted December 20, 2018 Share Posted December 20, 2018 Reminding of my contribution to Christmas music, as I already posted three weeks ago: http://atariage.com/forums/topic/218452-99389958-discussion-forum/?p=2877365 This disk image contains my XMAS program for Geneve OS. I don't suppose a video of that Christmas demo on Geneve exists on the web does it? I'd love to add it to: http://www.bytecellar.com/2018/12/13/have-a-helping-of-8-bit-holiday-cheer-2018-edition/ bp Quote Link to comment Share on other sites More sharing options...
+mizapf Posted December 20, 2018 Share Posted December 20, 2018 Yes, go ahead. Did you already create the video, or do you suggest that I do it? Quote Link to comment Share on other sites More sharing options...
blakespot Posted December 20, 2018 Share Posted December 20, 2018 Yes, go ahead. Did you already create the video, or do you suggest that I do it? I was hoping a video existed already. I am not currently setup with MESS to emulate Geneve, I'm afraid. Would be superb if you had the ability and inclination to do so, I must say. bp Quote Link to comment Share on other sites More sharing options...
+mizapf Posted December 20, 2018 Share Posted December 20, 2018 I can create it in webm format using the tool simplescreenrecorder. How long should it be? I seem to remember it can run indefinitely, starting over after the last song has finished. Quote Link to comment Share on other sites More sharing options...
twoodland Posted December 21, 2018 Share Posted December 21, 2018 Thank you LASooner! It is EPIC! 1 Quote Link to comment Share on other sites More sharing options...
Omega-TI Posted December 21, 2018 Author Share Posted December 21, 2018 If you guys want a decent and affordable screen grabber, you might want to check << THIS ONE >> out. It's what I use. It's what I used to make that recent Dragon's Lair video if you want an example of it's output. Quote Link to comment Share on other sites More sharing options...
blakespot Posted December 21, 2018 Share Posted December 21, 2018 I can create it in webm format using the tool simplescreenrecorder. How long should it be? I seem to remember it can run indefinitely, starting over after the last song has finished. That would be swell. However long you think? Obv the full run-through and if it repeats or persists forever in some way, maybe overall 4 or 5 mins? Whatever you think. Thanks! bp Quote Link to comment Share on other sites More sharing options...
+mizapf Posted December 21, 2018 Share Posted December 21, 2018 OK, here it is: 9 Quote Link to comment Share on other sites More sharing options...
Nick99 Posted December 22, 2018 Share Posted December 22, 2018 (edited) mizapf, wonderful! This is a "never seen before" on my Geneve. Edited December 22, 2018 by Nick99 2 Quote Link to comment Share on other sites More sharing options...
+mizapf Posted December 22, 2018 Share Posted December 22, 2018 Maybe you are interested in some details about this program ... 25 years ago, I have to check for myself. I wrote it in TIC (C99 on the Geneve), also to see how easy it is to directly access devices. Each melody is defined in a DIS/VAR80 file. The SONGS file lists all songs to be played. A simple music engine plays the notes, including a "piano effect" that has a high volume first and then becomes increasingly attenuated. I drew the picture in Myart in Graphics mode 6. The raw picture is shown below. For the flame, I created several mini-frames which are loaded below the visible screen. The mini-frames are copied by using the v9938 logical block copy (bitlbc). The format of the music files: Every generator has its section, separated by "====" (at least one "="). Tempo the speed, but inverse (higher value is slower) Laenge is length of the decay of a note. Make it shorter for a staccato. Strophenzahl is number of repetitions (stanzas) For each note: xx nn tt: xx is the length (in 32nds; 16 is a half note), nn is the pitch (C-D-E-F-G-A-H plus octave number as natural and lowercase as flat; mind that H is used in Germany instead of B), tt is the attenuation (1 loud, 15 quiet) Pianoeffekt means the piano effect (loud with decay), the opposite Orgeleffekt (organ) Each of the settings can be abbreviated to the first letter. SONGS file: ALLEJAHR IHRKINDER SCHNEE TANNENBAUM KMTIHRHRTN ESIST1ROS SUESSERGL STILLENCHT ODUFROEHL (I don't know the English titles; only that STILLENCHT, "Stille Nacht", means "Silent night". And from my Ireland trip I know it is "Oiche chiuin" (yes, and I can pronounce it :-) )). ALLEJAHR: Pianoeffekt Tempo 45 Laenge 70 Strophenzahl 3 12 A3 1 4 H3 1 8 A3 1 8 G2 1 16 f2 1 16 E2 1 8 D2 1 4 E2 1 4 f2 1 8 G2 1 8 f2 1 32 E2 1 8 f2 1 8 A3 1 8 H3 1 8 A3 1 16 D3 1 8 c3 1 8 H3 1 8 A3 1 4 G2 1 4 f2 1 8 G2 1 8 A3 1 24 f2 1 8 F2 15 ============ Pianoeffekt 12 f2 1 4 G2 1 8 f2 1 8 E2 1 16 D2 1 16 c2 1 8 D2 1 4 c2 1 4 D2 1 8 E2 1 8 D2 1 32 c2 1 32 D2 1 16 H3 1 8 A3 1 8 G2 1 16 D2 1 8 H2 1 8 c2 1 24 D2 1 8 E2 15 ============= Pianoeffekt 8 D0 6 16 D1 6 8 A1 6 8 D1 6 8 A2 6 8 A1 6 8 A2 6 8 f1 6 4 E1 6 4 D1 6 8 c1 6 8 D1 6 8 A2 6 8 H2 6 4 A2 6 4 G1 6 4 f1 6 4 E1 6 8 D1 6 8 f1 6 8 G1 6 8 f1 6 8 G1 6 8 G0 6 8 D1 6 8 G1 6 8 f1 6 4 E1 6 4 D1 6 8 E1 6 8 A1 6 8 D1 6 8 A1 6 8 D0 6 8 C0 15 The program itself: /* Weihnachtsmusikprogramm -- Version 1.1 */ /* Michael Zapf, 12.12.1993 */ /* ins Englische uebersetzt am 19.12.1998 */ #include <stdio_h> #include <video_h> #define FALSE 0 #define TRUE 1 FILE disk; char filename[20],buffer[130],s[30]; char *lied[20]; int rpz[3]; int *value, *ptr, *ff, rhpos[9]; int pal[3][16]={{0,0,0},{0,0,0},{1,6,1},{3,7,3}, {1,1,7},{2,3,7},{5,1,1},{2,6,7}, {7,1,1},{7,3,3},{6,6,1},{6,6,4}, {1,4,1},{6,2,5},{5,5,5},{7,7,7}}; int zeit[3], flag[3], durchgang[3], k, l, lp, aktiv[3]; int refrain[3], piano[3], tempo, laenge, st, ende; int chk, strophen; int drvsp; char zeit1[10],zeit2[10]; char min[3],sek[3]; struct notentyp { int freq; int dauer; int laut; struct notentyp *naechste; struct notentyp *naechsteref; } *liste[3], *note, dummy, *stimme[3]; /* Toene aus E/A-Handbuch; 5 Oktaven, jeweils von A bis g */ /* Kleinbuchstaben sind jeweils einen Halbton hoeher */ /* Folge: A a H C c D d E F f G g */ int frequenz[12][5] = { {0x93F,0x03C,0xA38,0x735,0x732,0xA2F,0xF2C,0x72A,0x128,0xD25,0xB23,0xB21}, {0xC1F,0x01E,0x51C,0xC1A,0x419,0xD17,0x816,0x315,0x014,0xE12,0xD11,0xD10}, {0xE0F,0x00F,0x20E,0x60D,0xA0C,0xE0B,0x40B,0xA0A,0x00A,0x709,0xF08,0x708}, {0xF07,0x807,0x107,0xB06,0x506,0xF05,0xA05,0x505,0x005,0xC04,0x704,0x304}, {0x004,0xC03,0x903,0x503,0x203,0x003,0xD02,0xA02,0x802,0x602,0x402,0x202} }; char bez[12] = { 'A', 'a', 'H', 'C', 'c', 'D', 'd', 'E', 'F', 'f', 'G', 'g' } ; main(argc, argv) int argc; char *argv[]; { printf("\f"); locate(10,10); printf("XMAS ---- a Christmas music program"); locate(12,10); printf("programmed in Clint Pulley's TIC V1.61"); locate(13,10); printf("by Michael Zapf, December 1993"); locate(17,10); printf("CANDLE by Michael Zapf"); locate(20,10); printf("Do not modify the picture! (The program will not "); locate(21,10); printf("run any more.)"); locate(24,20); printf("Press any key."); while (!poll(0)) ; time(zeit1); if (!laden()) { ruecks(); puts("\nDidn't I tell you to leave the picture untouched?\n"); exit(7); } time(zeit2); drvsp = 23-holezeit(zeit1,zeit2)/2; if (drvsp<2) drvsp=2; if (argc==2) { if (chk=einladen(argv[1],drvsp)) play(); } else { l=holeliste(lied); chk=TRUE; while ((poll(0)!=0x1b)&&chk) for (lp=0; ((lp<l)&&(poll(0)!=0x1b)&&chk); lp++) { free(ff); if (chk=einladen(lied[lp],drvsp)) play(); } } if (chk) ruecks(); freeall(); exit(7); } /* Unterprogramme */ void ruecks() { int k; for (k=0; k<16; k++) palette(k+1,pal[k][0],pal[k][1],pal[k][2]); txtmode(); } int holezeit(zt1,zt2) char *zt1,*zt2; { int ztdr; strncpy(min,zt2+3,2); ztdr=atoi(min)*60; strncpy(min,zt1+3,2); ztdr-=atoi(min)*60; strncpy(sek,zt2+6,2); ztdr+=atoi(sek); strncpy(sek,zt1+6,2); ztdr-=atoi(sek); if (ztdr<0) ztdr+=3600; return ztdr; } int holeliste(lieder) char *lieder[20]; { int zahl; char liedname[21]; zahl=0; disk=fopen("SONGS","r"); if (disk==0) { ruecks(); puts("\nSong list SONGS not found!"); puts("\n\nYou can use XMAS <music file>.\n"); exit(7); } while ((fgets(liedname,20,disk)!=NULL)&&(zahl<20)) { lieder[zahl] = malloc(22); strcpy(lieder[zahl++], liedname); } ff = malloc(2); fclose(disk); return zahl; } void play() { int gen, weiter,str; unsigned rh,rh1; char *ton; for (str=0; str<strophen; str++) { weiter = TRUE; rh=rh1=0; for (gen=0; gen<3; gen++) { zeit[gen] = 0; flag[gen] = FALSE; aktiv[gen] = FALSE; stimme[gen] = NULL; stimme[gen] = liste[gen]; refrain[gen] = FALSE; } while (weiter) { for (gen=0; gen<3; gen++) if ((kontrolle(gen, &zeit[gen], stimme[gen]->laut)==0) &&(stimme[gen]!=NULL)) flag[gen] = tonausgabe(gen); for (k=0; k<tempo; k++) ; if (rh++>120) { rh=0; if (++rh1== rh1=0; bitlbc(220,rhpos[rh1],rpz[2],rhpos[8]+1,27,32,0,0); } weiter = flag[0]|flag[1]|flag[2]; if (poll(0)) weiter=FALSE; } ton = 0xF120; *ton = 0x9F; *ton = 0xBF; *ton = 0xDF; *ton = 0xFF; } } int tonausgabe(g) int g; { int gencode,lautst, freqcd; char *ton, *byte; if (stimme[g]->naechsteref!=NULL) { note = (refrain[g])? stimme[g]->naechste : stimme[g]->naechsteref; refrain[g] = !refrain[g]; } else note = stimme[g]->naechste; if (note!=NULL) { stimme[g] = note; freqcd = note->freq; lautst = note->laut; zeit[g] = note->dauer * tempo; ton = 0xF120; /* Tongenerator-Adresse */ gencode = (g+4) << 13 ; freqcd = freqcd | gencode; byte = &freqcd; *ton = *(byte++); *ton = *byte; lautst = (gencode+0x1000) | (lautst<<; byte = &lautst; *ton = *byte; aktiv[g] = TRUE; durchgang[g] = 0; return TRUE; } else { aktiv[g] = FALSE; return FALSE; } } int kontrolle(gn, dauer, lautstk) int gn, *dauer, lautstk; { int gencode, lautst, lw, fakt; char *ton, *byte; if (aktiv[gn]) { gencode = (gn+4)<<13; ton = 0xF120; durchgang[gn]++; lw = lautstk+durchgang[gn]/laenge; if ((!piano[gn]) && (lw>lautstk+3)) lw=lautstk+3; if ((--(*dauer)==0)||(lw>15)) lw = 15; lautst = gencode+0x1000+(lw<<; byte = &lautst; *ton = *byte; return *dauer; } } /* Einladen des Bildes */ int laden() { int i,j,zeile,spalte,z1; int laenge,reclen,rp,rp1,farbe; int unten; unsigned check; disk = fopen("CANDLE","R128"); if (disk==0) { puts("\n\nOPEN error!"); return 0; } grfmode(6,1); bitclr(); bithbc(0,0,212,0,43,512,0); check=0; reclen = fread(buffer,128,disk); value = buffer; for (i=1;i<17;i++) { j = value[i]; check+=j; palette(i,(j>>12)&15,j&15,(j>>&15); } i--; spalte=zeile=1; rp=0; rp1=0; unten=FALSE; while ((zeile < 213)||unten) { if (++i >= reclen/2) { reclen = fread(buffer,128,disk); if (reclen < 0) { txtmode(); puts("\nREAD error!"); return 0; } i = 0; } farbe = ((value[i]>>12)&15)+1; laenge = ((value[i]>>&15)*256+(value[i]&255); if (farbe==13) rhpos[rp++] = spalte; else { if (farbe==2) { rpz[rp1++] = zeile; if (rp1==1) { unten=TRUE; z1=zeile; zeile=220; spalte=rhpos[0]; } if (rp1==2) { unten=FALSE; zeile=zeile-220+z1; spalte=rhpos[0]; } if ((rp1==3)&&(rp!=0)) { rhpos[8]=spalte; rp=0; } } else line(spalte,zeile,spalte+laenge-1,zeile,farbe); } if ((spalte=spalte+laenge)>512) { zeile++; spalte=1; } check+=value[i]; } if (check!=27789) check=0; fclose(disk); return check; } /* Routine zum Einladen der Tondaten */ int einladen(name,drv) int drv; char *name; { FILE datei; char zeile[81]; char nme[81]; int gen, lng, groesse, i, j, lautst, refanf, refende; int akz, fehl, rh, rh1; struct notentyp *ref1, *ref2; if ((datei = fopen(name,"r"))==NULL) { ruecks(); puts("\nError on open!\n"); return FALSE; } gen = 0; groesse = sizeof(dummy); for (i=0; i<3; i++) { liste[i] = malloc(groesse); piano[i] = FALSE; liste[i]->naechste = NULL; liste[i]->naechsteref = NULL; } note = liste[0]; refanf = refende = FALSE; ref1 = ref2 = NULL; tempo = 100; laenge = 100; strophen = 1; akz = 0; rh=rh1=0; fehl=FALSE; while ((fgets(zeile, 81, datei)!=NULL)&&!fehl) { akz++; if (rh++>drv) { rh=0; if (++rh1== rh1=0; bitlbc(220,rhpos[rh1],rpz[2],rhpos[8]+1,27,32,0,0); } switch(zeile[0]) { case '=': if (++gen==3) { ruecks(); puts("\nToo many voices!\n"); fehl=TRUE; break; } note = liste[gen]; ref1 = ref2 = NULL; break; case 'S': sscanf(zeile,"%s %d",nme,&strophen); break; case 'P': piano[gen] = TRUE; break; case 'O': piano[gen] = FALSE; break; case 'L': sscanf(zeile, "%s %d", nme, &laenge); if (laenge>500) { ruecks(); puts("\nTone length > 500!\n"); fehl=TRUE; } break; case 'T': sscanf(zeile, "%s %d", nme, &tempo); if (tempo>1000) { ruecks(); puts("\nTempo > 1000!\n"); fehl=TRUE; } break; case 'V': case NULL: case ' ': case '*': break; case '|': refanf = TRUE; ref2 = NULL; break; case 'E': if (note==liste[gen]) { ruecks(); puts("\nRepetition error!\n"); fehl=TRUE; } else ref2 = note; break; case ':': if (ref2==NULL) note->naechsteref = ref1; else { note->naechste = ref1; ref2->naechsteref = ref2->naechste; ref2->naechste = NULL; } refende = TRUE; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': sscanf(zeile, "%d %s %d", &lng, nme, &lautst); note->naechste = malloc(groesse); if ((refanf)||(ref1==NULL)) ref1 = note->naechste; refanf = FALSE; if ((refende)&&(ref2!=NULL)) { ref2->naechste = note->naechste; note->naechste = ref1; note = ref2->naechste; } else note = note->naechste; refende = FALSE; note->dauer = lng; note->laut = lautst; note->naechste = NULL; note->naechsteref = NULL; for (i=0, j=-1; i<12; i++) if (nme[0]==bez[i]) { j=i; break; } i = ((int)nme[1])-48; note->freq = frequenz[i][j]; break; default: ruecks(); puts("\nData error!\n"); fehl=TRUE; } } fclose(datei); if (fehl) { printf("Error in line %d.\n",akz); return FALSE; } else return TRUE; } That's all. 3 Quote Link to comment Share on other sites More sharing options...
ewbray Posted December 22, 2018 Share Posted December 22, 2018 (edited) There is an excellent collection of Christmas songs (including Snoopy's Christmas) on the Genial Travler diskazine #251! http://ftp.whtech.com/genitrav/ Edited December 22, 2018 by ewbray Quote Link to comment Share on other sites More sharing options...
Nick99 Posted December 22, 2018 Share Posted December 22, 2018 (edited) Mizapf, Thanks a lot for the information, it makes me think that I should study C and try to make something myself. In Sweden, we were two Geneve owners in 1990 as far as I know, so there wasn't much activity so to speak. Thanks again for the inspire! Edited December 22, 2018 by Nick99 Quote Link to comment Share on other sites More sharing options...
+mizapf Posted December 23, 2018 Share Posted December 23, 2018 I did some renaming and reformatting, and I added some comments so that interested people may better understand the XMAS player. (It still compiles. :-) ) You can now also use the name "B" for the note between A and C (which is "H" in German, our scale is C-D-E-F-G-A-H). /* Christmas music -- Version 1.2 */ /* Michael Zapf, Dec 12, 1993 */ /* translated texts Dec 19, 1998 */ /* translated program code Dec 22, 2018 */ #include <stdio_h> #include <video_h> #define FALSE 0 #define TRUE 1 FILE disk; char filename[20],buffer[130],s[30]; char *song[20]; int rpz[3]; int *value, *ptr, *ff, rhpos[9]; int pal[3][16]={{0,0,0},{0,0,0},{1,6,1},{3,7,3}, {1,1,7},{2,3,7},{5,1,1},{2,6,7}, {7,1,1},{7,3,3},{6,6,1},{6,6,4}, {1,4,1},{6,2,5},{5,5,5},{7,7,7}}; int time[3], flag[3], pass[3], k, l, lp, active[3]; int refrain[3], piano[3], tempo, length, st, ende; int chk, stanzas; int drvsp; char time1[10],time2[10]; char min[3],sek[3]; struct notetype { int freq; int duration; int vol; struct notetype *next; struct notetype *nextref; } *list[3], *note, dummy, *voice[3]; /* Taken from the E/A manual; 5 octaves, each from A to g */ /* Lowercase letters are sharp. */ /* Sequence: A a H(B) C c D d E F f G g */ int frequency[12][5] = { {0x93F,0x03C,0xA38,0x735,0x732,0xA2F,0xF2C,0x72A,0x128,0xD25,0xB23,0xB21}, {0xC1F,0x01E,0x51C,0xC1A,0x419,0xD17,0x816,0x315,0x014,0xE12,0xD11,0xD10}, {0xE0F,0x00F,0x20E,0x60D,0xA0C,0xE0B,0x40B,0xA0A,0x00A,0x709,0xF08,0x708}, {0xF07,0x807,0x107,0xB06,0x506,0xF05,0xA05,0x505,0x005,0xC04,0x704,0x304}, {0x004,0xC03,0x903,0x503,0x203,0x003,0xD02,0xA02,0x802,0x602,0x402,0x202} }; /* B will be replaced by H automatically. */ char notename[12] = { 'A', 'a', 'H', 'C', 'c', 'D', 'd', 'E', 'F', 'f', 'G', 'g' } ; main(argc, argv) int argc; char *argv[]; { printf("\f"); locate(10,10); printf("XMAS ---- a Christmas music program"); locate(12,10); printf("programmed in Clint Pulley's TIC V1.61"); locate(13,10); printf("by Michael Zapf, December 1993"); locate(17,10); printf("CANDLE by Michael Zapf"); locate(20,10); printf("Do not modify the picture! (The program will not "); locate(21,10); printf("run anymore.)"); locate(24,20); printf("Press any key."); while (!poll(0)) ; gettime(time1); if (!loadpict()) { restoretxmode(); puts("\nDidn't I tell you to leave the picture untouched?\n"); exit(7); } gettime(time2); /* Calculate the drive speed. This is for keeping the candle animated during loading. */ drvsp = 23-gettime(time1,time2)/2; if (drvsp<2) drvsp=2; if (argc==2) { if (chk=loadmusic(argv[1],drvsp)) play(); } else { l=getlist(song); chk=TRUE; while ((poll(0)!=0x1b)&&chk) { for (lp=0; ((lp<l)&&(poll(0)!=0x1b)&&chk); lp++) { free(ff); if (chk=loadmusic(song[lp],drvsp)) play(); } } } if (chk) restoretxmode(); freeall(); exit(7); } /* Subprograms */ void restoretxmode() { int k; for (k=0; k<16; k++) palette(k+1,pal[k][0],pal[k][1],pal[k][2]); txtmode(); } int gettime(zt1,zt2) char *zt1,*zt2; { int ztdr; strncpy(min,zt2+3,2); ztdr=atoi(min)*60; strncpy(min,zt1+3,2); ztdr-=atoi(min)*60; strncpy(sek,zt2+6,2); ztdr+=atoi(sek); strncpy(sek,zt1+6,2); ztdr-=atoi(sek); if (ztdr<0) ztdr+=3600; return ztdr; } int getlist(songs) char *songs[20]; { int count; char songname[21]; count=0; disk=fopen("SONGS","r"); if (disk==0) { restoretxmode(); puts("\nSong list SONGS not found!"); puts("\n\nYou can use XMAS <music file>.\n"); exit(7); } while ((fgets(songname,20,disk)!=NULL)&&(count<20)) { songs[count] = malloc(22); strcpy(songs[count++], songname); } /* Not sure what this is used for. malloc bug remedy? */ ff = malloc(2); fclose(disk); return count; } void play() { int gen, running,str; unsigned rh,rh1; char *soundaddr; for (str=0; str<stanzas; str++) { running = TRUE; rh=rh1=0; for (gen=0; gen<3; gen++) { time[gen] = 0; flag[gen] = FALSE; active[gen] = FALSE; voice[gen] = NULL; voice[gen] = list[gen]; refrain[gen] = FALSE; } /* Main loop */ while (running) { for (gen=0; gen<3; gen++) if ((contsound(gen, &time[gen], voice[gen]->vol)==0) &&(voice[gen]!=NULL)) flag[gen] = soundout(gen); /* Busy wait for the note length */ for (k=0; k<tempo; k++) ; if (rh++>120) { /* Next frame (0..7) */ rh=0; if (++rh1== rh1=0; bitlbc(220,rhpos[rh1],rpz[2],rhpos[8]+1,27,32,0,0); } running = flag[0]|flag[1]|flag[2]; if (poll(0)) running=FALSE; } /* Turn off sound. */ soundaddr = 0xF120; *soundaddr = 0x9F; *soundaddr = 0xBF; *soundaddr = 0xDF; *soundaddr = 0xFF; } } int soundout(g) int g; { int gencode,volume, freqcd; char *soundaddr, *byte; if (voice[g]->nextref!=NULL) { note = (refrain[g])? voice[g]->next : voice[g]->nextref; refrain[g] = !refrain[g]; } else note = voice[g]->next; if (note!=NULL) { voice[g] = note; freqcd = note->freq; volume = note->vol; time[g] = note->duration * tempo; soundaddr = 0xF120; /* sound generator */ gencode = (g+4) << 13 ; freqcd = freqcd | gencode; byte = &freqcd; *soundaddr = *(byte++); *soundaddr = *byte; volume = (gencode+0x1000) | (volume<<; byte = &volume; *soundaddr = *byte; active[g] = TRUE; pass[g] = 0; return TRUE; } else { active[g] = FALSE; return FALSE; } } /* Continue the started sound. Depends on the desired effect. */ int contsound(gn, duration, volumek) int gn, *duration, volumek; { int gencode, volume, lw, fakt; char *soundaddr, *byte; if (active[gn]) { gencode = (gn+4)<<13; soundaddr = 0xF120; pass[gn]++; lw = volumek+pass[gn]/length; if ((!piano[gn]) && (lw>volumek+3)) lw=volumek+3; if ((--(*duration)==0)||(lw>15)) lw = 15; volume = gencode+0x1000+(lw<<; byte = &volume; *soundaddr = *byte; return *duration; } } /* Load the picture. Implements a Myarc format reader. */ int loadpict() { int i,j,row,column,z1; int length,reclen,rp,rp1,color; int bottom; unsigned check; disk = fopen("CANDLE","R128"); if (disk==0) { puts("\n\nOPEN error!"); return 0; } grfmode(6,1); bitclr(); bithbc(0,0,212,0,43,512,0); check=0; reclen = fread(buffer,128,disk); value = buffer; for (i=1;i<17;i++) { j = value[i]; check+=j; palette(i,(j>>12)&15,j&15,(j>>&15); } i--; column=row=1; rp=0; rp1=0; bottom=FALSE; while ((row < 213)||bottom) { if (++i >= reclen/2) { reclen = fread(buffer,128,disk); if (reclen < 0) { txtmode(); puts("\nREAD error!"); return 0; } i = 0; } color = ((value[i]>>12)&15)+1; length = ((value[i]>>&15)*256+(value[i]&255); if (color==13) rhpos[rp++] = column; else { if (color==2) { rpz[rp1++] = row; if (rp1==1) { bottom=TRUE; z1=row; row=220; column=rhpos[0]; } if (rp1==2) { bottom=FALSE; row=row-220+z1; column=rhpos[0]; } if ((rp1==3)&&(rp!=0)) { rhpos[8]=column; rp=0; } } else line(column,row,column+length-1,row,color); } if ((column=column+length)>512) { row++; column=1; } check+=value[i]; } /* Check whether the picture was changed. If you remove the next line, well ... then it won't notice. */ if (check!=27789) check=0; fclose(disk); return check; } /* Load a music file. Note that while the file is being loaded, the candle continues to burn. */ int loadmusic(name,drv) int drv; char *name; { FILE mfile; char row[81]; char nme[81]; int gen, lng, rsize, i, j, volume, refanf, refende; int akz, error, rh, rh1; struct notetype *ref1, *ref2; if ((mfile = fopen(name,"r"))==NULL) { restoretxmode(); puts("\nerror on open!\n"); return FALSE; } gen = 0; rsize = sizeof(dummy); for (i=0; i<3; i++) { list[i] = malloc(rsize); piano[i] = FALSE; list[i]->next = NULL; list[i]->nextref = NULL; } note = list[0]; refanf = refende = FALSE; ref1 = ref2 = NULL; tempo = 100; length = 100; stanzas = 1; akz = 0; rh=rh1=0; error=FALSE; /* Main load loop */ while ((fgets(row, 81, mfile)!=NULL)&&!error) { akz++; if (rh++>drv) { /* Enough time has passed to show the next candle frame. */ rh=0; if (++rh1== rh1=0; bitlbc(220,rhpos[rh1],rpz[2],rhpos[8]+1,27,32,0,0); } switch(row[0]) { case '=': if (++gen==3) { restoretxmode(); puts("\nToo many voices!\n"); error=TRUE; break; } note = list[gen]; ref1 = ref2 = NULL; break; case 'S': sscanf(row,"%s %d",nme,&stanzas); break; case 'P': piano[gen] = TRUE; break; case 'O': piano[gen] = FALSE; break; case 'L': sscanf(row, "%s %d", nme, &length); if (length>500) { restoretxmode(); puts("\nNote length > 500!\n"); error=TRUE; } break; case 'T': sscanf(row, "%s %d", nme, &tempo); if (tempo>1000) { restoretxmode(); puts("\nTempo > 1000!\n"); error=TRUE; } break; case 'V': case NULL: case ' ': case '*': break; case '|': refanf = TRUE; ref2 = NULL; break; case 'E': if (note==list[gen]) { restoretxmode(); puts("\nRepetition error!\n"); error=TRUE; } else ref2 = note; break; case ':': if (ref2==NULL) note->nextref = ref1; else { note->next = ref1; ref2->nextref = ref2->next; ref2->next = NULL; } refende = TRUE; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': sscanf(row, "%d %s %d", &lng, nme, &volume); note->next = malloc(rsize); if ((refanf)||(ref1==NULL)) ref1 = note->next; refanf = FALSE; if ((refende)&&(ref2!=NULL)) { ref2->next = note->next; note->next = ref1; note = ref2->next; } else note = note->next; refende = FALSE; note->duration = lng; note->vol = volume; note->next = NULL; note->nextref = NULL; for (i=0, j=-1; i<12; i++) { /* Translate the B to H. */ if (nme[0]=='B') nme[0]='H'; if (nme[0]==notename[i]) { j=i; break; } } i = ((int)nme[1])-48; note->freq = frequency[i][j]; break; default: restoretxmode(); puts("\nData error!\n"); error=TRUE; } } fclose(mfile); if (error) { printf("Error in line %d.\n",akz); return FALSE; } else return TRUE; } 1 Quote Link to comment Share on other sites More sharing options...
+mizapf Posted December 23, 2018 Share Posted December 23, 2018 By the way, the AA formatter removes all empty lines... here is the text file for download. xmas.tic.txt 1 Quote Link to comment Share on other sites More sharing options...
blakespot Posted December 23, 2018 Share Posted December 23, 2018 Thanks so much, mizapf! I've added this to my aforelinked christmas demo roundup blog post. Such a rare thing, that little program on that little platform. bp Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.