home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 24 / CD_ASCQ_24_0995.iso / dos / prg / dsik205 / dsik.dat / EXAMPLES / PLAY.C < prev    next >
C/C++ Source or Header  |  1995-04-10  |  14KB  |  442 lines

  1. /****************************************************************************
  2. *
  3. *                   Digital Sound Interface Kit (DSIK)
  4. *                            Version 2.00
  5. *
  6. *                           by Carlos Hasan
  7. *
  8. * Filename:     play.c
  9. * Version:      Revision 1.0
  10. *
  11. * Language:     WATCOM C
  12. * Environment:  IBM PC (DOS/4GW)
  13. *
  14. * Description:  DSIK Module Player.
  15. *
  16. ****************************************************************************/
  17.  
  18. #include <stdio.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <process.h>
  22. #include <direct.h>
  23. #include <ctype.h>
  24. #include <conio.h>
  25. #include <i86.h>
  26. #include "audio.h"
  27. #include "import.h"
  28. #include "timer.h"
  29.  
  30. #define KB_FF       0x4D00
  31. #define KB_RW       0x4B00
  32. #define KB_ESC      0x001B
  33. #define KB_PAUSE    0x0020
  34. #define KB_SHELL    0x4200
  35. #define KB_NEXT     0x000D
  36. #define KB_PLUS     0x002B
  37. #define KB_MINUS    0x002D
  38. #define KB_INCSPD   0x007D
  39. #define KB_DECSPD   0x007B
  40. #define KB_TRACE    0x0054
  41. #define KB_NOTRACE  0x0050
  42.  
  43. char *keytable = "123456789ABCDEFG";
  44.  
  45. volatile int ticks;
  46.  
  47.  
  48. /* TheDraw C Crunched Screen Image */
  49. #define WIDTH   80
  50. #define HEIGHT  50
  51. #define IMGSIZ  962
  52. unsigned char image[] = {
  53.    "\x0F\x11 DSIK Module Player Version 2.00\x19\x0E""Copyright (C) 1"
  54.    "995 Carlos Hasan  \x18\x09\x1AO▒\x18▒╔═Song Information:\x1A\x15═"
  55.    "╗▒▒╔═Playback Device:\x1A\x0D═╗▒▒\x18▒║ Songname:\x19\x1D║░▒║\x19"
  56.    "\x1E║░▒\x18▒║ Filename:\x19\x0E""CPU used:\x19\x05║░▒╟\x1A\x1E─╢░"
  57.    "▒\x18▒╟\x1A\x27─╢░▒║\x19\x1E║░▒\x18▒║ Patt:Beat:Tick:\x19\x0ATemp"
  58.    "o:\x19\x06║░▒╟\x1A\x1E─╢░▒\x18▒║ Position:\x19\x08Pattern:\x19\x04"
  59.    "Line:\x19\x02║░▒║ I/O Port:\x19\x05IRQ:\x19\x03""DMA:\x19\x02║░▒\x18"
  60.    "▒╚\x1A\x27═╝░▒╚\x1A\x1E═╝░▒\x18▒▒\x1A)░▒▒\x1A ░▒\x18\x1AO▒\x18▒╔═"
  61.    "Song Tracks:\x1A\x1A═╗▒▒╔═VU Meters:\x1A\x13═╗▒▒\x18▒║ 01\x19$║░▒"
  62.    "║\x19\x1E║░▒\x18▒║ 02\x19$║░▒║\x19\x1E║░▒\x18▒║ 03\x19$║░▒║\x19\x1E"
  63.    "║░▒\x18▒║ 04\x19$║░▒║\x19\x1E║░▒\x18▒║ 05\x19$║░▒║\x19\x1E║░▒\x18"
  64.    "▒║ 06\x19$║░▒║\x19\x1E║░▒\x18▒║ 07\x19$║░▒║\x19\x1E║░▒\x18▒║ 08\x19"
  65.    "$║░▒║\x19\x1E║░▒\x18▒║ 09\x19$║░▒║\x19\x1E║░▒\x18▒║ 10\x19$║░▒║\x19"
  66.    "\x1E║░▒\x18▒║ 11\x19$║░▒║\x19\x1E║░▒\x18▒║ 12\x19$║░▒║\x19\x1E║░▒"
  67.    "\x18▒║ 13\x19$║░▒║\x19\x1E║░▒\x18▒║ 14\x19$║░▒║\x19\x1E║░▒\x18▒║ "
  68.    "15\x19$║░▒║\x19\x1E║░▒\x18▒║ 16\x19$║░▒║\x19\x1E║░▒\x18▒╚\x1A\x27"
  69.    "═╝░▒╚\x1A\x1E═╝░▒\x18▒▒\x1A)░▒▒\x1A ░▒\x18\x1AO▒\x18▒╔═Instrument"
  70.    " Names:\x1A""8═╗▒▒\x18▒║ 01\x19\x27""17\x19\x1D║░▒\x18▒║ 02\x19\x27"
  71.    "18\x19\x1D║░▒\x18▒║ 03\x19\x27""19\x19\x1D║░▒\x18▒║ 04\x19\x27""2"
  72.    "0\x19\x1D║░▒\x18▒║ 05\x19\x27""21\x19\x1D║░▒\x18▒║ 06\x19\x27""22"
  73.    "\x19\x1D║░▒\x18▒║ 07\x19\x27""23\x19\x1D║░▒\x18▒║ 08\x19\x27""24\x19"
  74.    "\x1D║░▒\x18▒║ 09\x19\x27""25\x19\x1D║░▒\x18▒║ 10\x19\x27""26\x19\x1D"
  75.    "║░▒\x18▒║ 11\x19\x27""27\x19\x1D║░▒\x18▒║ 12\x19\x27""28\x19\x1D║"
  76.    "░▒\x18▒║ 13\x19\x27""29\x19\x1D║░▒\x18▒║ 14\x19\x27""30\x19\x1D║░"
  77.    "▒\x18▒║ 15\x19\x27""31\x19\x1D║░▒\x18▒║ 16\x19\x27""32\x19\x1D║░▒"
  78.    "\x18▒╚\x1AJ═╝░▒\x18▒▒\x1AL░▒\x18"};
  79.  
  80.  
  81. #define VPTR(x,y) (void*)(0xb8000+2*(x)+160*(y))
  82.  
  83. void setmode80x25(void)
  84. {
  85.     union REGS r;
  86.     r.w.ax = 0x0003;
  87.     int386(0x10,&r,&r);
  88. }
  89.  
  90. void setmode80x50(void)
  91. {
  92.     union REGS r;
  93.     r.w.ax = 0x0003;
  94.     int386(0x10,&r,&r);
  95.     r.w.ax = 0x1112;
  96.     r.h.bl = 0x00;
  97.     int386(0x10,&r,&r);
  98. }
  99.  
  100. void waitvr(void)
  101. {
  102.     while (!(inp(0x3da) & 8)) ;
  103.     while (inp(0x3da) & 8) ;
  104. }
  105.  
  106. void hidecursor(void)
  107. {
  108.     outpw(0x3d4,0x100a);
  109.     outpw(0x3d4,0x100b);
  110. }
  111.  
  112. void setborder(int color)
  113. {
  114.     inp(0x3da);
  115.     outp(0x3c0,0x31);
  116.     outp(0x3c0,color);
  117. }
  118.  
  119. void drawtext(int x, int y, char *text, int color)
  120. {
  121.     short *ptr = (short*)VPTR(x,y);
  122.     color <<= 8;
  123.     while (*text) {
  124.         *ptr++ = *text++ | color;
  125.     }
  126. }
  127.  
  128. void drawchars(int x, int y, int c, int count, int color)
  129. {
  130.     short *ptr = (short*)VPTR(x,y);
  131.     c |= color << 8;
  132.     while (count--) *ptr++ = c;
  133. }
  134.  
  135. void drawimage(unsigned char *image, int len)
  136. {
  137.     unsigned char *endimage,*p,*line;
  138.     unsigned int c,a,x,y;
  139.  
  140.     a = 0;
  141.     p = line = (unsigned char *)VPTR(0,0);
  142.     endimage = image + len;
  143.     while (image < endimage) {
  144.         if ((c = *image++) >= 32) {
  145.             *p++ = c;
  146.             *p++ = a;
  147.         }
  148.         else {
  149.             if (c <= 15) {
  150.                 a = (a & 0xf0) | (c & 0x0f);
  151.             }
  152.             else if (c >= 16 && c <= 23) {
  153.                 a = (a & 0x8f) | ((c & 0x07) << 4);
  154.             }
  155.             else if (c == 24) {
  156.                 line += (WIDTH<<1);
  157.                 p = line;
  158.             }
  159.             else if (c == 25) {
  160.                 x = *image++;
  161.                 do {
  162.                     *p++ = 0x20;
  163.                     *p++ = a;
  164.                 } while (x--);
  165.             }
  166.             else if (c == 26) {
  167.                 x = *image++;
  168.                 y = *image++;
  169.                 do {
  170.                     *p++ = y;
  171.                     *p++ = a;
  172.                 } while (x--);
  173.             }
  174.             else if (c == 27) {
  175.                 a ^= 0x80;
  176.             }
  177.         }
  178.     }
  179. }
  180.  
  181. void starttimer(void)
  182. {
  183.     outp(0x61,inp(0x61) | 0x01);
  184.     outp(0x43,0xb4);
  185.     outp(0x42,0xff);
  186.     outp(0x42,0xff);
  187. }
  188.  
  189. int readtimer(void)
  190. {
  191.     int n;
  192.     outp(0x43,0xb0);
  193.     n = inp(0x42);
  194.     n += inp(0x42) << 8;
  195.     return 0x10000L - n;
  196. }
  197.  
  198. void timer(void)
  199. {
  200.     #ifdef PROFILE
  201.     setborder(15);
  202.     #endif
  203.     starttimer();
  204.     dPoll();
  205.     ticks = (ticks+readtimer())>>1;
  206.     #ifdef PROFILE
  207.     setborder(0);
  208.     #endif
  209. }
  210.  
  211. void initscreen(DSM *M, SoundCard *SC, char *path)
  212. {
  213.     char buf[40];
  214.     int i;
  215.  
  216.     setmode80x50();
  217.     hidecursor();
  218.     drawimage(image,IMGSIZ);
  219.     drawtext(13,3,M->Header.ModuleName,0x13);
  220.     drawtext(13,4,path,0x13);
  221.     drawtext(47,3,dGetDriverStruc(SC->ID)->Name,0x13);
  222.     sprintf(buf,"%d-bit %s at %d hertz",
  223.         SC->Modes & AF_16BITS ? 16 : 8,
  224.         SC->Modes & AF_STEREO ? "stereo" : "mono",
  225.         SC->SampleRate);
  226.     drawtext(47,5,buf,0x13);
  227.     sprintf(buf,"%03Xh",SC->Port);
  228.     drawtext(56,7,buf,0x13);
  229.     sprintf(buf,"%d",SC->IrqLine);
  230.     drawtext(66,7,buf,0x13);
  231.     sprintf(buf,"%d",SC->DmaChannel);
  232.     drawtext(74,7,buf,0x13);
  233.     for (i = 0; i < 16; i++) {
  234.         if (i < M->Header.NumSamples)
  235.             drawtext(6,32+i,M->Samples[i]->SampleName,0x13);
  236.         if (i+16 < M->Header.NumSamples)
  237.             drawtext(48,32+i,M->Samples[i+16]->SampleName,0x13);
  238.     }
  239. }
  240.  
  241. void donescreen(void)
  242. {
  243.     setmode80x25();
  244. }
  245.  
  246. void updatescreen(DSM *M, MHdr *P)
  247. {
  248.     static char buf[80];
  249.     static char notes[] =
  250.         "C-n\0C#n\0D-n\0D#n\0E-n\0F-n\0F#n\0G-n\0G#n\0A-n\0A#n\0B-n\0";
  251.     MTrk *Trk;
  252.     char *p;
  253.     int i,n;
  254.  
  255.     sprintf(buf,"%2d.%1d%%",(100*ticks)/TICKS(70),
  256.         ((1000*ticks)/TICKS(70))%10);
  257.     drawtext(36,4,buf,0x13);
  258.     if (P->BreakFlag != PB_JUMP) {
  259.         sprintf(buf,"%03d:%02d:%02d",P->OrderPos,P->PattRow>>4,P->PattRow&15);
  260.         drawtext(18,6,buf,0x13);
  261.         sprintf(buf,"%02d/%03d",P->Tempo,P->BPM);
  262.         drawtext(35,6,buf,0x13);
  263.         sprintf(buf,"%03d/%03d",P->OrderPos,P->OrderLen);
  264.         drawtext(12,7,buf,0x13);
  265.         sprintf(buf,"%03d",P->PattNum);
  266.         drawtext(29,7,buf,0x13);
  267.         sprintf(buf,"%02d",P->PattRow);
  268.         drawtext(39,7,buf,0x13);
  269.     }
  270.     for (i = 0, Trk = P->Tracks; i < MAXTRACKS; i++, Trk++) {
  271.         if (!(n = Trk->Note))
  272.             drawtext(6,12+i,"---",0x19);
  273.         else {
  274.             n--;
  275.             notes[4*(n % 12)+2] = '0' + (n / 12);
  276.             drawtext(6,12+i,¬es[4*(n % 12)],0x19);
  277.         }
  278.         sprintf(buf,"%02d",Trk->Volume);
  279.         drawtext(10,12+i,buf,0x19);
  280.         if (((n = Trk->Sample) != 0) && (n <= M->Header.NumSamples)) {
  281.             n--;
  282.             p = M->Samples[n]->SampleName;
  283.             n = strlen(p);
  284.             drawtext(13,12+i,p,0x19);
  285.             drawchars(13+n,12+i,0x20,28-n,0x19);
  286.         }
  287.         if ((n = (29*Trk->VUMeter)>>6) > 29) n = 29;
  288.         drawchars(47,12+i,0xfe,n,0x1b);
  289.         drawchars(47+n,12+i,0xfe,29-n,0x19);
  290.         if (Trk->Flags & AM_PAUSE) drawchars(5,12+i,0x4d,1,0x1b);
  291.         else drawchars(5,12+i, dGetVoiceStatus(i) == PS_PLAYING ? 0x07:0x20,1,0x15);
  292.     }
  293. }
  294.  
  295.  
  296. int main(int argc, char *argv[])
  297. {
  298.     SoundCard SC;
  299.     DSM *M;
  300.     MHdr *P;
  301.     DIR *d;
  302.     char path[_MAX_PATH];
  303.     char drive[_MAX_DRIVE],dir[_MAX_DIR],name[_MAX_NAME],ext[_MAX_EXT];
  304.     int i,j,c,form;
  305.  
  306.     printf("DSIK Module Player Version 2.00 (C) 1995 Carlos Hasan\n");
  307.     if (argc < 2) {
  308.         printf("Use: PLAY modfile[.mod|.nst|.s3m|.mtm|.669|.stm|.dsm]\n");
  309.         exit(EXIT_FAILURE);
  310.     }
  311.     _splitpath(argv[0],drive,dir,name,ext);
  312.     _makepath(path,drive,dir,"SETUP",".CFG");
  313.  
  314.     if (dLoadSetup(&SC,path)) {
  315.         printf("Please run SETUP.EXE to configure.\n");
  316.         exit(EXIT_FAILURE);
  317.     }
  318.     dRegisterDrivers();
  319.     printf("%s at Port %03Xh using IRQ %d on DMA channel %d\n",
  320.         dGetDriverStruc(SC.ID)->Name, SC.Port, SC.IrqLine, SC.DmaChannel);
  321.     if (dInit(&SC)) {
  322.         printf("Error initializing the sound system.\n");
  323.         exit(EXIT_FAILURE);
  324.     }
  325.     atexit((void(*)(void))dDone);
  326.  
  327.     if (dMemAvail())
  328.        printf("There are %lu free bytes on the soundcard.\n", dMemAvail());
  329.  
  330.     dInitTimer();
  331.     atexit((void(*)(void))dDoneTimer);
  332.     dStartTimer(timer,TICKS(70));
  333.  
  334.     for (i = 1; i < argc; i++) {
  335.         strupr(argv[i]);
  336.         _splitpath(argv[i],drive,dir,name,ext);
  337.         if (*ext == 0) strcpy(ext,".*");
  338.         _makepath(path,drive,dir,name,ext);
  339.         if (!(d = opendir(path)))
  340.             printf("File not found: %s\n",path);
  341.         else {
  342.             printf("Searching module file.\n");
  343.             while ((d = readdir(d)) != NULL) {
  344.                 if (!(d->d_attr & _A_ARCH)) continue;
  345.                 _makepath(path,drive,dir,d->d_name,"");
  346.                 _splitpath(path,drive,dir,name,ext);
  347.                 if (!strcmp(ext,".DSM")) form = FORM_DSM;
  348.                 else if (!strcmp(ext,".MOD")) form = FORM_MOD;
  349.                 else if (!strcmp(ext,".NST")) form = FORM_MOD;
  350.                 else if (!strcmp(ext,".S3M")) form = FORM_S3M;
  351.                 else if (!strcmp(ext,".MTM")) form = FORM_MTM;
  352.                 else if (!strcmp(ext,".669")) form = FORM_669;
  353.                 else if (!strcmp(ext,".STM")) form = FORM_STM;
  354.                 else {
  355.                     printf("Unknown file format: %s\n", path);
  356.                     exit(EXIT_FAILURE);
  357.                 }
  358.                 printf("Loading module: %s\n",path);
  359.                 if (!(M = dImportModule(path,form))) {
  360.                     printf("Error (%03d) loading %s module file: %s.\n",
  361.                         dError, path, dErrorMsg[dError]);
  362.                     exit(EXIT_FAILURE);
  363.                 }
  364.  
  365.                 initscreen(M,&SC,d->d_name);
  366.                 dSetupVoices(M->Header.NumTracks,M->Header.MasterVolume);
  367.                 dPlayMusic(M);
  368.                 P = dGetMusicStruc();
  369.                 while (dGetMusicStatus() != PS_STOPPED) {
  370.                     updatescreen(M,P);
  371.                     if (kbhit()) {
  372.                         if (!(c = toupper(getch()))) c = getch()<<8;
  373.                         if (c == KB_ESC) {
  374.                             break;
  375.                         }
  376.                         else if (c == KB_PAUSE) {
  377.                             if (dGetMusicStatus() == PS_PAUSED) dResumeMusic();
  378.                             else dPauseMusic();
  379.                         }
  380.                         else if (c == KB_FF) {
  381.                             if (P->OrderPos < P->OrderLen) (P->OrderPos)++;
  382.                             P->PattRow = 0;
  383.                             P->BreakFlag = PB_JUMP;
  384.                         }
  385.                         else if (c == KB_RW) {
  386.                             if (P->OrderPos > 0) (P->OrderPos)--;
  387.                             P->PattRow = 0;
  388.                             P->BreakFlag = PB_JUMP;
  389.                         }
  390.                         else if (c == KB_SHELL) {
  391.                             donescreen();
  392.                             spawnl(P_WAIT,getenv("COMSPEC"),getenv("COMSPEC"),NULL);
  393.                             initscreen(M,&SC,d->d_name);
  394.                         }
  395.                         else if (c == KB_NEXT) {
  396.                             break;
  397.                         }
  398.                         else if (c == KB_PLUS) {
  399.                             if (P->MusicVolume <= 251) P->MusicVolume += 4;
  400.                             else P->MusicVolume = 255;
  401.                             dSetMusicVolume(P->MusicVolume);
  402.                         }
  403.                         else if (c == KB_MINUS) {
  404.                             if (P->MusicVolume >= 4) P->MusicVolume -= 4;
  405.                             else P->MusicVolume = 0;
  406.                             dSetMusicVolume(P->MusicVolume);
  407.                         }
  408.                         else if (c == KB_INCSPD) {
  409.                             if (P->Tempo < 31) (P->Tempo)++;
  410.                         }
  411.                         else if (c == KB_DECSPD) {
  412.                             if (P->Tempo > 1) (P->Tempo)--;
  413.                         }
  414.                         else if (c == KB_TRACE) {
  415.                             P->BreakFlag = PB_TRACE;
  416.                         }
  417.                         else if (c == KB_NOTRACE) {
  418.                             P->BreakFlag = PB_NONE;
  419.                         }
  420.                         else {
  421.                             for (j = 0; j < MAXTRACKS; j++) {
  422.                                 if (c == keytable[j]) {
  423.                                     P->Tracks[j].Flags ^= AM_PAUSE;
  424.                                     dStopVoice(j);
  425.                                 }
  426.                             }
  427.                         }
  428.                     }
  429.                 }
  430.                 dStopMusic();
  431.                 donescreen();
  432.                 dFreeModule(M);
  433.                 if (c == KB_ESC) exit(EXIT_FAILURE);
  434.                 if (dMemAvail())
  435.                    printf("There are %lu free bytes on the soundcard.\n", dMemAvail());
  436.             }
  437.             closedir(d);
  438.         }
  439.     }
  440.     return 0;
  441. }
  442.