home *** CD-ROM | disk | FTP | other *** search
/ Mega A/V / mega_av.zip / mega_av / SOUNDUTL / MUSIQUE.ZIP / SOURCE.ZIP / MUSIQUE.C < prev    next >
C/C++ Source or Header  |  1991-09-06  |  17KB  |  576 lines

  1. /* Warning! This C source contains extended characters! */
  2.  
  3. #include <stdio.h>
  4. #include <dir.h>
  5. #include <dos.h>
  6. #include <string.h>
  7. #include <bios.h>
  8. #include <process.h>
  9. #include <conio.h>
  10. #include <time.h>
  11. #include <stdlib.h>
  12. #include <musique.h>
  13. #include <musique.e>
  14.  
  15. void bellit(void)
  16. /* short bell */
  17. {
  18.   sound(SNDFREQ);
  19.   delay(SNDLENGTH);
  20.   nosound();
  21. }
  22.  
  23. void myresetmode(PARAMETERTYPE *parameter)
  24. /* Turbo-C doesn't like extended or non-text modes */
  25. /* resets the video mode iff necessary */
  26. /* does not rely on knowing the screen size since no clear screen done */
  27. /* some incomplete BIOSes may force complete reset all the time */
  28. {
  29.   union REGS regs;
  30.  
  31.   regs.h.ah=(unsigned)'\xF'; /* get current video mode */
  32.   int86(0x10,®s,®s);
  33.   if (regs.h.al!=(unsigned char)parameter->videomode) {
  34.     regs.h.ah=(unsigned)'\x0'; /* reset video mode */
  35.     regs.h.al=(unsigned char)parameter->videomode;
  36.     int86(0x10,®s,®s);
  37.   }
  38. }
  39.  
  40. void setborder(int color)
  41. /* sets the border color */
  42. /* color is in high 4 nibbles */
  43. {
  44.   union REGS regs;
  45.  
  46.   /* CGA EGA VGA */
  47.   regs.h.bl=(unsigned char)(color>>4);
  48.   regs.h.bh=(unsigned)'\x0';
  49.   regs.x.ax=(unsigned)0xB00;
  50.   int86(0x10,®s,®s);
  51. }
  52.  
  53. void highbackground(void)
  54. /* disables blinking/enables high intensity background */
  55. {
  56.   union REGS regs;
  57.   int addr;
  58.   unsigned char data;
  59.  
  60.   /* MDA CGA */
  61.   addr=peek((unsigned)0x40,(unsigned)0x63)+0x4;
  62.   data=(unsigned)(peekb((unsigned)0x40,(unsigned)0x65) & '\xDF');
  63.   outportb(addr,data);
  64.   /* MCGA EGA VGA */
  65.   regs.h.bl=(unsigned)'\x0';
  66.   regs.x.ax=(unsigned)0x1003;
  67.   int86(0x10,®s,®s);
  68. }
  69.  
  70. void myclrscr(PARAMETERTYPE *parameter, int color)
  71. /* Turbo-C doesn't like extended or non-text modes */
  72. /* clear screen, sets border, and enables high intensity background */
  73. /* color is is high 4 nibbles */
  74. {
  75.   union REGS regs;
  76.  
  77.   regs.x.ax=(unsigned)0x700; /* scroll whole screen */
  78.   regs.h.bh=(unsigned char)color;
  79.   regs.x.cx=(unsigned)0x0;
  80.   regs.h.dl=(unsigned char)(parameter->maxcolumn-1);
  81.   regs.h.dh=(unsigned char)(parameter->maxline-1);
  82.   int86(0x10,®s,®s);
  83.   regs.h.ah=(unsigned)'\x2'; /* cursor in upper-left corner */
  84.   regs.h.bh=(unsigned)'\x0';
  85.   regs.x.dx=(unsigned)0x0;
  86.   int86(0x10,®s,®s);
  87.   highbackground();
  88.   setborder(color);
  89. }
  90.  
  91. void mysetmode(PARAMETERTYPE *parameter)
  92. /* Turbo-C doesn't like extended or non-text modes */
  93. /* sets the video mode and border, enables high intensity background */
  94. /* avoids a complete video mode reset when possible */
  95. /* some incomplete BIOSes may force complete reset all the time */
  96. {
  97.   union REGS regs;
  98.  
  99.   regs.h.ah=(unsigned)'\xF'; /* get current video mode */
  100.   int86(0x10,®s,®s);
  101.   if (regs.h.al!=(unsigned char)parameter->videomode) {
  102.     regs.h.ah=(unsigned)'\x0'; /* reset video mode */
  103.     regs.h.al=(unsigned char)parameter->videomode;
  104.     int86(0x10,®s,®s);
  105.   }
  106.   myclrscr(parameter,colorborder); /* always set screen attributes to border */
  107. }
  108.  
  109. void blankstring(char target[], int targetlength)
  110. /* creates a string full of spaces */
  111. {
  112.   int ptr;
  113.  
  114.   for (ptr=0 ; ptr<targetlength ; ptr++) target[ptr]=' ';
  115.   target[targetlength]='\0';
  116. }
  117.  
  118. void initialize(SONGSTYPE *songs, PARAMETERTYPE *parameter, char menuname[])
  119. {
  120.   language=FRENCH;
  121.   coloroutline=DEFAULTOUTLINE;
  122.   colortitle=DEFAULTTITLE;
  123.   coloritem=DEFAULTITEM;
  124.   colorcurrent=DEFAULTCURRENT;
  125.   colorpicked=DEFAULTPICKED;
  126.   colorcursor=DEFAULTCURSOR;
  127.   colorborder=DEFAULTBORDER;
  128.   songs->songnumber=0;
  129.   songs->songcorner=songs->songcurrent=1;
  130.   songs->songpath[0]='\0';
  131.   songs->songpathoffset=1;
  132.   /* used for overwriting items to erase them on the screen */
  133.   blankstring(songs->song[0].diskname,DISKNAMELENGTH);
  134.   blankstring(songs->song[0].score,SCORELENGTH);
  135.   blankstring(songs->song[0].DOSname,DOSNAMELENGTH);
  136.   blankstring(songs->song[0].songname,SONGNAMELENGTH);
  137.   songs->song[0].picked=0;
  138.   songs->song[0].DOSpath=songs->songpath;
  139.   strcpy(menuname,DEFAULTMENU);
  140.   strcpy(parameter->speed,DEFAULTSPEED);
  141.   parameter->tempdrive=ODDDRIVE;
  142.   parameter->ports[0]=ODDPORTS;
  143.   parameter->videomode=ODDMODE;
  144.   parameter->A=parameter->B=parameter->C=FALSE;
  145.   parameter->verbose=FALSE;
  146.   parameter->DOS=FALSE;
  147.   parameter->pause=FALSE;
  148.   parameter->mouse=FALSE;
  149.   parameter->rawvideo=TRUE;
  150.   switch (peek((unsigned)0x40,(unsigned)0x63)) {
  151.     case 0x3B4:parameter->videosegment=0xB000;
  152.                break;
  153.     case 0x3D4:parameter->videosegment=0xB800;
  154.                break;
  155.     default:error(34);
  156.   }
  157. }
  158.  
  159. void busyfloppy(void)
  160. /* waits until floppy shuts off */
  161. {
  162. while ((0xF & (int)peekb((unsigned)0x40,(unsigned)0x3F))!=0) ;
  163. }
  164.  
  165. void cuttail(char text[])
  166. /* cuts the tail of spaces */
  167. {
  168.   int scanner;
  169.  
  170.   scanner=strlen(text);
  171.   while ((text[--scanner]==' ') && (scanner>=0)) text[scanner]='\0';
  172. }
  173.  
  174. int locateasong(SONGTYPE *song, PARAMETERTYPE *parameter)
  175. /* checks that a module exists and maybe asks for the correct floppy */
  176. /* looks for .MOD first, then for .ZIP (iff PKUNZIP.EXE located) */
  177. /* returns -1 if not found, 0-1-2 for .MOD, and 3-4-5 for .ZIP */
  178. /* looks in: temporary drive-path supplied(if not .)-current drive */
  179. /* uses normal, read-only, hidden, system, archive bits for looking */
  180. {
  181.   struct ffblk fff;
  182.   char filename[LINELENGTH+LINELENGTH]; /* path could be long */
  183.   int notfound;
  184.   char currenttext[3];
  185.  
  186.   strcpy(currenttext,"A:");
  187.   currenttext[0]+=(char)parameter->currentdrive;
  188.   /* look on temporary drive for .MOD */
  189.   strcpy(filename,(*song).DOSname);
  190.   cuttail(filename);
  191.   strcat(filename,MPENDING);
  192.   notfound=findfirst(filename,&fff,39); 
  193.   if (notfound) {
  194.     if (parameter->pkunzipfound) {
  195.       /* look on temporary drive for .ZIP */
  196.       strcpy(filename,(*song).DOSname);
  197.       cuttail(filename);
  198.       strcat(filename,PKENDING);
  199.       notfound=findfirst(filename,&fff,39); 
  200.     }
  201.     if (notfound) {
  202.       if (strcmp((*song).DOSpath,ODDPATH)!=0) {
  203.         /* look on menu path for .MOD */
  204.         strcpy(filename,(*song).DOSpath);
  205.         strcat(filename,(*song).DOSname);
  206.         cuttail(filename);
  207.         strcat(filename,MPENDING);
  208.         notfound=findfirst(filename,&fff,39); 
  209.       }
  210.       if (notfound) {
  211.         if (parameter->pkunzipfound) 
  212.           if (strcmp((*song).DOSpath,ODDPATH)!=0) {
  213.             /* look on menu path for .ZIP */
  214.             strcpy(filename,(*song).DOSpath);
  215.             strcat(filename,(*song).DOSname);
  216.             cuttail(filename);
  217.             strcat(filename,PKENDING);
  218.             notfound=findfirst(filename,&fff,39); 
  219.         }
  220.         if (notfound)
  221.           do {
  222.             /* look on current drive for .MOD */
  223.             strcpy(filename,currenttext);
  224.             strcat(filename,(*song).DOSname);
  225.             cuttail(filename);
  226.             strcat(filename,MPENDING);
  227.             notfound=findfirst(filename,&fff,39); 
  228.             if (notfound) {
  229.               if (parameter->pkunzipfound) {
  230.                 /* look on current drive for .ZIP */
  231.                 strcpy(filename,currenttext);
  232.                 strcat(filename,(*song).DOSname);
  233.                 cuttail(filename);
  234.                 strcat(filename,PKENDING);
  235.                 notfound=findfirst(filename,&fff,39); 
  236.               }
  237.               if (notfound)
  238.                 if (parameter->currentdrive<=1) {
  239.                   /* song on floppy; ask user */
  240.                   bellit();
  241.                   message(23);
  242.                   printf("%s\n",(*song).diskname);
  243.                   message(22);
  244.                   switch (bioskey(0)) {
  245.                     case KEYESC:return(-1); /* aborted */
  246.                     default:break;
  247.                   }
  248.                 } 
  249.                 else {
  250.                   /* song not on floppy; give up */
  251.                   printf("<%s>\n",(*song).songname);
  252.                   message(24);
  253.                   if (parameter->pause) {
  254.                     message(25);
  255.                     bellit();
  256.                     bioskey(0);
  257.                   }
  258.                   else {
  259.                     bellit();
  260.                     delay(NOTFOUNDDELAY);
  261.                     bellit();
  262.                     delay(NOTFOUNDDELAY);
  263.                     bellit();
  264.                     delay(NOTFOUNDDELAY);
  265.                     bellit();
  266.                     delay(NOTFOUNDDELAY);
  267.                     bellit();
  268.                   }
  269.                   return(-1); /* not found */
  270.                 }
  271.               else {
  272.                 message(35);
  273.                 return(5); /* .ZIP under current drive */
  274.               }
  275.             }
  276.             else {
  277.               message(32);
  278.               return(2); /* .MOD under current drive */
  279.             }
  280.           } while (TRUE);
  281.         else {
  282.           message(34);
  283.           return(4); /* .ZIP under path */
  284.         }
  285.       }
  286.       else {
  287.         message(31);
  288.         return(1); /* .MOD under path */
  289.       }
  290.     }
  291.     else {
  292.       message(33);
  293.       return(3); /* .ZIP under temporary drive */
  294.     }
  295.   }
  296.   else {
  297.     message(36);
  298.     return(0); /* .MOD under temporary drive */
  299.   }
  300. }
  301.  
  302. void checkasong(char DOSname[])
  303. /* checks that a module exists */
  304. {
  305.   struct ffblk fff;
  306.   char filename[LINELENGTH];
  307.  
  308.   strcpy(filename,DOSname);
  309.   cuttail(filename);
  310.   strcat(filename,MPENDING);
  311.   /* normal, read-only, hidden, system, archive */
  312.   if (findfirst(filename,&fff,39)) error(18);
  313. }
  314.  
  315. void deleteasong(char DOSname[])
  316. /* deletes a song */
  317. {
  318.   char filename[LINELENGTH];
  319.   int errorint;
  320.  
  321.   message(40);
  322.   strcpy(filename,DOSname);
  323.   cuttail(filename);
  324.   strcat(filename,MPENDING);
  325.   errorint=unlink(filename);
  326.   if (errorint==-1) error(19);
  327. }
  328.  
  329. void shutup(int port)
  330. /* turns off gradually a parallel port */
  331. {
  332.   int value;
  333.  
  334.   value=(int)inportb(port);
  335.   while (value>0) {
  336.     value--;
  337.     outportb(port,(unsigned char)value);
  338.     delay(SHUTUPDELAY);
  339.   }  
  340. }
  341.  
  342. void movemodule(SONGTYPE *song, int found, PARAMETERTYPE *parameter)
  343. /* moves a module onto the temporary drive */
  344. /* because the module must be in the current directory for ModPlay */
  345. /* this is simpler than to look at DOSpath and to be clever with logged drive */
  346. /* found=1 is from path, found=2 is from current drive */
  347. {
  348.   char buffer[BUFFERSIZE];
  349.   char filename[LINELENGTH+LINELENGTH]; /* path could be long */
  350.   FILE *source,*target;
  351.   int errorint,tomove,moved;
  352.   char temporarytext[3];
  353.   char currenttext[3];
  354.  
  355.   message(38);
  356.   strcpy(temporarytext,"A:");
  357.   strcpy(currenttext,"A:");
  358.   temporarytext[0]+=(char)parameter->tempdrive;
  359.   currenttext[0]+=(char)parameter->currentdrive;
  360.   if (found==1) strcpy(filename,(*song).DOSpath);
  361.   else strcpy(filename,currenttext);
  362.   strcat(filename,(*song).DOSname);
  363.   cuttail(filename);
  364.   strcat(filename,MPENDING);
  365.   source=fopen(filename,"rb");
  366.   if (source==NULL) error(25);
  367.   strcpy(filename,temporarytext);
  368.   strcat(filename,(*song).DOSname);
  369.   cuttail(filename);
  370.   strcat(filename,MPENDING);
  371.   target=fopen(filename,"wb");
  372.   if (target==NULL) error(26);
  373.   tomove=(int)fread(buffer,(unsigned)1,(unsigned)BUFFERSIZE,source);
  374.   while (tomove!=0) {
  375.     moved=(int)fwrite(buffer,(unsigned)1,(unsigned)tomove,target);
  376.     if (moved!=tomove) error(27);
  377.     tomove=(int)fread(buffer,(unsigned)1,(unsigned)BUFFERSIZE,source);
  378.   }
  379.   errorint=fclose(source);
  380.   if (errorint==EOF) error(28);
  381.   errorint=fclose(target);
  382.   if (errorint==EOF) error(29);
  383. }
  384.  
  385. void playasong(SONGTYPE *song, PARAMETERTYPE *parameter)
  386. /*finds, maybe decompresses, waits, plays, shuts off, and maybe deletes a song*/
  387. {
  388.   char command[LINELENGTH+LINELENGTH]; /* path could be long */
  389.   char currenttext[3];
  390.   int found,errorint;
  391.  
  392.   strcpy(currenttext,"A:");
  393.   currenttext[0]+=(char)parameter->currentdrive;
  394.   /* look for MOD or ZIP under temporary drive, menu path, and current drive */
  395.   found=locateasong(song,parameter);
  396.   if (found>=0) {
  397.     /* song found */
  398.     if (found>=3) {
  399.       /* must be decompressed on the temporary drive known clear */
  400.       message(37);
  401.       /* known on the temporary drive */
  402.       strcpy(command,PKUNZIP0);
  403.       strcat(command," ");
  404.       if (found==4) strcat(command,(*song).DOSpath);
  405.       else
  406.         if (found==5) strcat(command,currenttext);
  407.       strcat(command,(*song).DOSname);
  408.       cuttail(command);
  409.       message(43);
  410.       printf("%s\n",command);
  411.       if (parameter->pause) {
  412.         bellit();
  413.         message(22);
  414.         switch (bioskey(0)) {
  415.           case KEYESC:error(9); /* aborted */
  416.           default:break;
  417.         }
  418.       }
  419.       errorint=system(command);
  420.       printf("\n");
  421.       if (errorint==-1) error(20);
  422.       checkasong((*song).DOSname);
  423.     }
  424.     else 
  425.       /* if temporary drive is clear, move module there */
  426.       if (found>=1) movemodule(song,found,parameter);
  427.     message(39);
  428.     /* known on the temporary drive */
  429.     strcpy(command,MODPLAY0);
  430.     strcat(command," ");
  431.     strcat(command,parameter->ports);
  432.     strcat(command," ");
  433.     strcat(command,parameter->speed);
  434.     strcat(command," ");
  435.     strcat(command,(*song).DOSname);
  436.     cuttail(command);
  437.     message(43);
  438.     printf("%s\n",command);
  439.     if (parameter->pause) {
  440.       bellit();
  441.       message(22);
  442.       switch (bioskey(0)) {
  443.         case KEYESC:error(9); /* aborted */
  444.         default:break;
  445.       }
  446.     }
  447.     busyfloppy();
  448.     errorint=system(command);
  449.     if (errorint==-1) error(20);
  450.     if (parameter->A) {
  451.       message(29);
  452.       shutup(PORT1);
  453.     }
  454.     if (parameter->B) {
  455.       message(29);
  456.       shutup(PORT2);
  457.     }
  458.     if (parameter->C) {
  459.       message(29);
  460.       shutup(PORT3);
  461.     }
  462.     /* if .MOD was copied/created, it must be deleted since not there before */
  463.     if (found>=1) deleteasong((*song).DOSname);
  464.   }
  465. }
  466.  
  467. void cleanup(PARAMETERTYPE *parameter)
  468. /* deletes temporary programs on the temporary drive */
  469. {
  470.   int errorint;
  471.  
  472.   if (parameter->pkunzipcopied || parameter->modplaycopied) {
  473.     message(6);
  474.     if (parameter->modplaycopied) {
  475.       errorint=unlink(MODPLAY1);
  476.       if (errorint==-1) {
  477.         errorint=unlink(MODPLAY2);
  478.         if (errorint==-1) {
  479.           errorint=unlink(MODPLAY3);
  480.           if (errorint==-1) error(21);
  481.         }
  482.       }
  483.     }
  484.     if (parameter->pkunzipcopied) {
  485.       errorint=unlink(PKUNZIP1);
  486.       if (errorint==-1) error(21);
  487.     }
  488.   }
  489. }
  490.  
  491. void playbatch(SONGSTYPE *songs, PARAMETERTYPE *parameter)
  492. /* plays the current batch of modules and Escape aborts */
  493. {
  494.   int songptr;
  495.   int priority;
  496.   int songcancel;
  497.  
  498.   songcancel=FALSE;
  499.   for (priority=1 ; priority<=songs->songpriority ; priority++) 
  500.     if (!songcancel) {
  501.       for (songptr=1 ; songptr<=songs->songnumber ; songptr++)
  502.         if (songs->song[songptr].picked==priority) {  
  503.           songs->song[songptr].picked=0; 
  504.           playasong(&(songs->song[songptr]),parameter);
  505.           break;
  506.         }
  507.       while (bioskey(1)) 
  508.         if (bioskey(0)==KEYESC) songcancel=TRUE;
  509.         else bellit();
  510.     }
  511.   if (songcancel)
  512.     for (songptr=1 ; songptr<=songs->songnumber ; songptr++)
  513.       songs->song[songptr].picked=0; 
  514. }
  515.  
  516. int main(int argc, char *argv[])
  517. {
  518.   char menuname[LINELENGTH];
  519.   FILE *menufile;
  520.   SONGSTYPE songs;
  521.   PARAMETERTYPE parameter;
  522.   MOUSETYPE mousedata;
  523.   int errorint;
  524.   int songabort; /* TRUE indicates terminate MUSIQUE */
  525.  
  526.   directvideo=0; /* safety for extended color text modes */ 
  527.   delay(1); /* solves initial delay() bug(?) */
  528.   srand((unsigned)time(NULL));
  529.   initialize(&songs,¶meter,menuname);
  530.   scanarguments(argc,argv,menuname,¶meter);
  531.   if (parameter.videomode!=ODDMODE) myresetmode(¶meter);
  532.   /* Copyright notice so Borland is happy */
  533.   message(1);
  534.   message(2);
  535.   printf("%s\n",menuname);
  536.   menufile=fopen(menuname,"rt");
  537.   if (menufile==NULL) {
  538.     strcat(menuname,MENUENDING);
  539.     message(2);
  540.     printf("%s\n",menuname);
  541.     menufile=fopen(menuname,"rt");
  542.     if (menufile==NULL) error(2);
  543.   }
  544.   message(3);
  545.   readmenu(menufile,&songs);
  546.   message(4);
  547.   printf("%s\n",menuname);
  548.   errorint=fclose(menufile);
  549.   if (errorint==EOF) error(3);
  550.   message(5);
  551.   readparameter(¶meter,&mousedata,songs.songnumber);
  552.   myclrscr(¶meter,colorborder); /* clear screen, set border & high stuff */
  553.   setdisk(parameter.tempdrive);
  554.   if (getdisk()!=parameter.tempdrive) error(32);
  555.   do {
  556.     /* screen already cleared here */
  557.     printoutline(¶meter);
  558.     if (parameter.mouse)
  559.       mouseshow(mousedata.x,mousedata.y,&(mousedata.c),&(mousedata.color));
  560.     printsongs(&songs,¶meter,&mousedata);
  561.     songabort=picksongs(&songs,¶meter,&mousedata);
  562.     if (parameter.mouse)
  563.       mousehide(mousedata.x,mousedata.y,mousedata.c,mousedata.color);
  564.     myclrscr(¶meter,7);
  565.     if (!songabort) {
  566.       playbatch(&songs,¶meter);
  567.       mysetmode(¶meter); /* reset mode/clear screen, border & high stuff */
  568.     }
  569.   } while (!songabort);
  570.   /* screen already cleared here */
  571.   cleanup(¶meter);
  572.   setdisk(parameter.currentdrive);
  573.   if (getdisk()!=parameter.currentdrive) error(33);
  574.   return(0);
  575. }
  576.