home *** CD-ROM | disk | FTP | other *** search
/ Sound, Music & MIDI Collection 2 / SMMVOL2.bin / PROG / BWSB120A.ZIP / DEMO / CHPLAY.C next >
Encoding:
C/C++ Source or Header  |  1980-01-01  |  13.4 KB  |  420 lines

  1. /*──────────────────────────────────────────────────────────────────────────*/
  2. /*                     Bells, Whistles, and Sound Boards                    */
  3. /*       Copyright (c) 1993-95, Edward Schlunder. All Rights Reserved.      */
  4. /*══════════════════════════════════════════════════════════════════════════*/
  5. /* CHPLAY.C - Example GDM module player with channel vu bars.               */
  6. /*            Written by Edward Schlunder (1995)                            */
  7. /*                                                                          */
  8. /*──────────────────────────────────────────────────────────────────────────*/
  9.  
  10. #include <bwsb.h>
  11. #include <chantype.h>
  12.  
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <process.h>
  17. #include <ctype.h>
  18. #include <conio.h>
  19. #include <dos.h>
  20. #include <io.h>
  21. #include <fcntl.h>
  22.  
  23. typedef struct
  24. { int SoundCard;
  25.   int BaseIO;
  26.   int IRQ;
  27.   int DMA;
  28.   int SoundQuality;
  29. } MSEConfigFile;
  30.  
  31.  
  32. void textblink(char intensity);
  33.  
  34. void PrintHeader(char Dark);
  35. void DoPlayer(void);
  36.  
  37. void DiChan(int Channel);
  38. void DiPan(int Channel);
  39. void DiNote(int Channel);
  40. void DiPos(int Channel);
  41. void DiVol(int Channel);
  42. void DiVu(int Channel);
  43.  
  44. unsigned long OverLoad(char *FileName, int FileHandle);
  45.  
  46. int Channels = { 0 };
  47.  
  48. int j, ErrorFlag, Handle;
  49. ChannelType MusicChan;
  50.  
  51. char ShowChan, ShowPan, ShowNote, ShowVol, ShowPos, ShowVU;
  52. char *Note[] = { "C-","C#","D-","D#","E-","F-","F#","G-","G#","A-","A#","B-" };
  53.  
  54. char *PanPos[] = { "L               ",
  55.                    " l              ",
  56.                    "  l             ",
  57.                    "   l            ",
  58.                    "    l           ",
  59.                    "     l          ",
  60.                    "      m         ",
  61.                    "       m        ",
  62.                    "        M       ",
  63.                    "         m      ",
  64.                    "          m     ",
  65.                    "           r    ",
  66.                    "            r   ",
  67.                    "             r  ",
  68.                    "              r ",
  69.                    "               R"};
  70. GDMHeader ModHead;
  71. char modfile[80];         /* ASCIIZ filename of file to load */
  72. char *comspec;            /* Command processor name and path */
  73.  
  74. void main(int argc, char *argv[])
  75. {  long FileOff;
  76.    unsigned int BaseIO = { 0xFFFF },
  77.                 IRQ = { 0xFF },
  78.                 DMA = { 0xFF };
  79.    char Ov, *msefile[] = { "GUS.MSE", "SB1X.MSE", "SB2X.MSE",
  80.                            "SBPRO.MSE", "SB16.MSE", "PAS.MSE" },
  81.         OverTable[]    = { 16, 22, 45, 8, 11 },
  82.         *ErrorMSE[]    = { "Base I/O address autodetection failure\n",        
  83.         /* 2 */            "IRQ level autodetection failure\n",              
  84.         /* 3 */            "DMA channel autodetection failure\n",            
  85.         /* 4 */            "DMA channel not supported\n",                    
  86.         /* 5 */            "\n",                                             
  87.         /* 6 */            "Sound device does not respond\n",                
  88.         /* 7 */            "Memory control blocks destroyed\n",              
  89.         /* 8 */            "Insufficient memory for mixing buffers\n",       
  90.         /* 9 */            "Insufficient memory for MSE file\n",             
  91.         /* 10 */           "MSE has invalid identification string\n",       
  92.         /* 11 */           "MSE disk read failure\n",                        
  93.         /* 12 */           "MVSOUND.SYS not loaded (required for PAS use)\n",
  94.         /* 13 */           "Insufficient memory for volume table\n" };
  95.    MSEConfigFile MSEConfig;             /* Configuration for MSE */
  96.    char *ErrorLoad[] = {
  97.      "Module is corrupt\n",                             /* 1 */
  98.      "Could not autodetect module type\n",              /* 2 */
  99.      "Bad file format ID string\n",                     /* 3 */
  100.      "Insufficient memory to load module\n",            /* 4 */
  101.      "Can not unpack samples\n",                        /* 5 */
  102.      "AdLib instruments not supported\n" };
  103.  
  104.    union REGS regs; struct SREGS sregs;
  105.  
  106.    PrintHeader(1);
  107.  
  108.    if ((Handle = open("MSE.CFG", O_RDONLY | O_BINARY)) == -1) {
  109.    MSEError:
  110.       printf("No Sound selected in SETUP. Please run SETUP.\n");
  111.       return;
  112.    }
  113.  
  114.    read(Handle, &MSEConfig, 10); close(Handle);
  115.    if (MSEConfig.SoundCard == 0) goto MSEError;
  116.  
  117.    MSEConfig.SoundCard--;
  118.    BaseIO = MSEConfig.BaseIO;
  119.    IRQ = MSEConfig.IRQ;
  120.    DMA = MSEConfig.DMA;
  121.  
  122.    Handle = open(argv[0], O_RDONLY | O_BINARY);
  123.    OverLoad(msefile[MSEConfig.SoundCard], Handle);
  124.    FileOff = lseek(Handle, 0, SEEK_CUR);
  125.    close(Handle);
  126.  
  127.    Ov = OverTable[MSEConfig.SoundQuality];
  128.    ErrorFlag = LoadMSE(argv[0], FileOff, Ov, 4096, &BaseIO, &IRQ, &DMA);
  129.  
  130.    if (ErrorFlag >= 1 && ErrorFlag <= 13) {
  131.       printf(ErrorMSE[ErrorFlag-1]);
  132.       return;
  133.    }
  134.    atexit(FreeMSE);                     /* make sure that things get put back
  135.                                            before an abort or exit */
  136.  
  137.    /* Display name of sound device */
  138.    printf("Sound Device: %s\n", DeviceName());
  139.    printf("A:%Xh I:%d D:%d\n", BaseIO, IRQ, DMA);
  140.    ErrorFlag = EmsExist() & 1;            /* Enable EMS use if available */
  141.    if (ErrorFlag) printf("EMS Enabled\n");
  142.  
  143.    /* Ask for a module to load */
  144.    if (argc - 1) stpcpy(modfile, argv[1]);
  145.    else {   
  146.      printf("File: ");
  147.      gets(modfile);
  148.      if (strlen(modfile) == 0) return;
  149.    }
  150.  
  151.    /* Append a .GDM if no extension specified */
  152.    if (strstr(modfile, ".") == NULL) strncat(modfile, ".GDM", 80);
  153.  
  154.    printf("Loading Module: %s\n", modfile);
  155.    if ((Handle = open(modfile, O_RDONLY | O_BINARY)) == -1) {
  156.       printf("Can't find file %s\n", modfile);
  157.       return;
  158.    }
  159.  
  160.    LoadGDM(Handle, 0, &ErrorFlag, &ModHead);
  161.    close(Handle);
  162.  
  163.    if (ErrorFlag) {                /* Was there an error loading? */
  164.       printf(ErrorLoad[ErrorFlag-1]);
  165.       return;                                                          
  166.    }
  167.  
  168.    /* Scan and count number of used music channels */
  169.    /* 0xFF is an unused channel, so only inc when not = 0xFF */
  170.    for (j = 0;j < 32;j++) if (ModHead.PanMap[j] != 0xFF) Channels++;
  171.  
  172.    StartOutput(Channels, 0);       /* Enable sound output, no amplification */
  173.    StartMusic();                   /* Start playing the music */
  174.  
  175.    PrintHeader(0);
  176.    DoPlayer();
  177.  
  178.    PrintHeader(1);
  179.    _setcursortype(_NORMALCURSOR);
  180.  
  181.    StopMusic();
  182.    StopOutput();
  183.    UnloadModule();
  184.    FreeMSE();
  185. }
  186.  
  187. void PrintHeader(char Dark)
  188. {
  189.    if (Dark)
  190.    {  textattr(0x7);
  191.       clrscr();
  192.       textattr(0x1F);
  193.       textblink(1);
  194.    }
  195.    else
  196.    {  textattr(0x17);
  197.       clrscr();
  198.       textattr(0x9F);
  199.       textblink(0);
  200.    }
  201.    cprintf(" OmniPlayer/C v1.20                     Copyright (c) 1993-95, Edward Schlunder ");
  202. }
  203.  
  204. typedef struct
  205. { char FileName[12];
  206.   unsigned long FileLoc;
  207.   unsigned long FileSize;
  208. } OLHeader;
  209.  
  210. typedef struct
  211. { char ID[10];
  212.   unsigned char Entries;
  213.   unsigned long Location;
  214. } OLEnd;
  215.  
  216. unsigned long OverLoad(char *FileName, int FileHandle)
  217. { OLHeader Header;
  218.   OLEnd EndHeader;
  219.   int j;
  220.  
  221.   lseek(FileHandle, -15, SEEK_END);
  222.  
  223.   read(FileHandle, &EndHeader, sizeof(EndHeader));
  224.   if (strnicmp(EndHeader.ID, "OverLoader", 10) != 0)
  225.   {  printf("Couldn't find OverLoader ID header\n");
  226.      getch();
  227.      return(0);
  228.   }
  229.  
  230.   lseek(FileHandle, EndHeader.Location - 1, SEEK_SET);
  231.   for (j = 1; j <= EndHeader.Entries; j++)
  232.   {  read(FileHandle, &Header, sizeof(OLHeader));
  233.      if (strnicmp(Header.FileName, FileName, 12) == 0) goto FoundFile;
  234.   }
  235.  
  236.   return(0);
  237.  
  238.   FoundFile:
  239.   lseek(FileHandle, Header.FileLoc - 1, SEEK_SET);
  240.   return(Header.FileSize);
  241. }
  242.  
  243.  
  244. void DiChan(int Channel)
  245. {  textattr(0x7F);  cprintf("▌");
  246.    textattr(0x71);  cprintf("%2u", Channel);
  247.    textattr(0x78);  cprintf("▐");
  248. }
  249.  
  250. void DiPan(int Channel)
  251. {  textattr(0x7F);  cprintf("▌");
  252.    textattr(0x70);  cprintf("%s", PanPos[ChannelPan(Channel, 0xFF)]);
  253.    textattr(0x78);  cprintf("▐");
  254. }
  255.  
  256. void DiNote(Channel)
  257. {  textattr(0x7F);  cprintf("▌");
  258.  
  259.    textattr(0x70);
  260.    if (ChannelVol(Channel, 0xFF) == 0) cprintf("   ");
  261.    else cprintf("%s%u", Note[MusicChan.MusNote], MusicChan.MusOctave & 7);
  262.  
  263.    textattr(0x78);  cprintf("▐");
  264. }
  265.  
  266. void DiPos(Channel)
  267. {  textattr(0x7F);  cprintf("▌");
  268.  
  269.    textattr(0x70);
  270.    if (ChannelPos(Channel, 0xFFFF) == 0) cprintf("     ");
  271.    else cprintf("%5u", ChannelPos(Channel, 0xFFFF));
  272.  
  273.    textattr(0x78);  cprintf("▐");
  274. }
  275.  
  276. void DiVol(Channel)
  277. {  textattr(0x7F);  cprintf("▌");
  278.  
  279.    textattr(0x70);
  280.    if (ChannelVol(Channel, 0xFF) == 0) cprintf("  ");
  281.    else cprintf("%2u", ChannelVol(Channel, 0xFF));
  282.  
  283.    textattr(0x78);  cprintf("▐");
  284. }
  285.  
  286. void DiVu(Channel)
  287. {  textattr(0x7F);  cprintf("▌");
  288.    ErrorFlag = ChannelVU(Channel, ChannelVU(Channel, 0xFF)-1);
  289.  
  290.    for (Handle = 0; Handle <= 20; Handle++)
  291.    { if (Handle < ErrorFlag) textcolor(10); else textcolor(0);
  292.      cprintf("■");                                                      }
  293.    for (Handle = 21; Handle <= 30; Handle++)
  294.    { if (Handle < ErrorFlag) textcolor(12); else textcolor(0);
  295.      cprintf("■");                                                      }
  296.  
  297.    textattr(0x78);  cprintf("▐");
  298. }
  299.  
  300. void DoPlayer(void)
  301. {
  302.    directvideo = 1;
  303.    _setcursortype(_NOCURSOR);
  304.  
  305.    ShowChan = -1;
  306.    ShowPan  = -1;
  307.    ShowNote = -1;
  308.    ShowPos  = 0;
  309.    ShowVol  = -1;
  310.    ShowVU   = -1;
  311.    for (;;) {
  312.       textcolor(7); gotoxy(2, 2);
  313.       cprintf("Row: %-2u  Order:%3u/%-3u Pattern:%3u/%-3u Tempo: %2u/%-2u",
  314.                MusicRow(),
  315.                MusicOrder(0xFF), ModHead.NOO,
  316.                MusicPattern(0xFF), ModHead.NOP,
  317.                MusicTempo(0xFF), MusicBPM(0));
  318.  
  319.       for (j = 1;j <= Channels;j++) {
  320.         if (j + 2 > 25) break;
  321.         gotoxy(1, j + 2);
  322.         GetChannelTable(j, FP_SEG(&MusicChan), FP_OFF(&MusicChan));
  323.  
  324.         if (ShowChan) DiChan(j);
  325.         if (ShowPan)  DiPan (j);
  326.         if (ShowNote) DiNote(j);
  327.         if (ShowPos)  DiPos (j);
  328.         if (ShowVol)  DiVol (j);
  329.         if (ShowVU)   DiVu  (j);
  330.         textbackground(1);
  331.         clreol();
  332.       }
  333.  
  334.       if (kbhit()) {
  335.         j = toupper(getch());
  336.         switch (j) {
  337.           case 'F':  /* Ask for a module to load */
  338.                      PrintHeader(1);
  339.                      printf("\nModule file: ");
  340.                      if (gets(modfile)==NULL) return;  /* abort if nothing entered */
  341.  
  342.                      /* Append a .GDM if no extension specified */
  343.                      if (strstr(modfile, ".")==NULL) strncat(modfile, ".GDM", 80);
  344.  
  345.                   printf("Loading Module: %s\n", modfile);
  346.                   if ((Handle = open(modfile, O_RDONLY | O_BINARY)) == -1) {
  347.                      printf("Can't find file %s\n", modfile);
  348.                      return;                                                         
  349.                   }
  350.                   
  351.                   ErrorFlag = EmsExist() & 1;     /* Enable EMS use if available */
  352.                   StopMusic();
  353.                   StopOutput();
  354.                   UnloadModule();
  355.                   LoadGDM(Handle, 0, &ErrorFlag, &ModHead);  /* Load the GDM file */
  356.                   close(Handle);
  357.  
  358.                   if (ErrorFlag) {                /* Was there an error loading? */
  359.                      printf("Error while loading GDM: %u\n", ErrorFlag);
  360.                      return;                                                        
  361.                   }
  362.  
  363.                   /* Scan and count number of used music channels */
  364.                   /* 0xFF is an unused channel, so only inc when not = 0xFF */
  365.                   Channels = 0;
  366.                   for (j = 0;j < 32;j++) if (ModHead.PanMap[j] != 0xFF) Channels++;
  367.  
  368.                   StartOutput(Channels, 0);       /* Enable sound output with */
  369.                                                   /* no amplification. */
  370.                   StartMusic();                   /* Start playing the music */
  371.                   PrintHeader(0);
  372.                   break;
  373.        case 'D':  PrintHeader(1);
  374.                   _setcursortype(_NORMALCURSOR);
  375.                   printf("\nType EXIT [enter] to return..");
  376.                   if (spawnl(P_WAIT, getenv("COMSPEC"), NULL))
  377.                   {  printf("Shell Error: %u\n", errno);
  378.                      getch();
  379.                   }
  380.                   PrintHeader(0);
  381.                   _setcursortype(_NOCURSOR);
  382.                   break;
  383.        case '+':  MusicVolume(MusicVolume(0xFF) + 1);
  384.                   break;
  385.        case '-':  MusicVolume(MusicVolume(0xFF) - 1);
  386.                   break;
  387.        case '1':  ShowChan =! ShowChan;
  388.                   break;
  389.        case '2':  ShowPan  =! ShowPan;
  390.                   break;
  391.        case '3':  ShowNote =! ShowNote;
  392.                   break;
  393.        case '4':  ShowPos  =! ShowPos;
  394.                   break;
  395.        case '5':  ShowVol  =! ShowVol;
  396.                   break;
  397.        case '6':  ShowVU   =! ShowVU;
  398.                   break;
  399.        case 75:   MusicOrder(MusicOrder(0xFF) - 1);
  400.                   break;
  401.        case 77:   MusicOrder(MusicOrder(0xFF) + 1);
  402.                   break;
  403.        case 27:   return;                                              }
  404.      }
  405.    }
  406. }
  407.  
  408. void textblink(char intensity) {
  409.    if (intensity) {
  410.      asm  mov  ax, 0x1003;
  411.      asm  mov  bl, 1;
  412.      asm  int  0x10;
  413.    }
  414.    else {
  415.      asm  mov  ax, 0x1003;
  416.      asm  xor  bl, bl;
  417.      asm  int  0x10;
  418.    };
  419. }
  420.