home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / wps / mmpm2 / tracker / main.c < prev    next >
Text File  |  1993-12-19  |  22KB  |  774 lines

  1. /* main.c (formerly str32.c) */
  2.  
  3. /* modified (rewritten) by David Nichols for PM MOD player */
  4.  
  5. /* original authors:
  6.  * Authors  : Liam Corner - zenith@dcs.warwick.ac.uk
  7.  *            Marc Espie - espie@dmi.ens.fr
  8.  *            Steve Haehnichen - shaehnic@ucsd.edu
  9. */
  10.  
  11. #include <stdio.h>
  12.  
  13. #define INCL_DOS
  14. #define INCL_WIN
  15. #define INCL_GPI
  16.  
  17. #include <os2.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <ctype.h>
  21.  
  22. /* #include "sblast_user.h"  RKG */
  23. #define  INCL_OS2MM   /* RKG */
  24. #include <os2me.h>    /* RKG */
  25.  
  26.  
  27. #include "defs.h"
  28. #include "os2defs.h"
  29. #include "tracker.h"
  30. #include "easyfont.h"
  31.  
  32.  
  33. /* MMPM/2 R.Garcia (RKG) 11/93 prototype additions ---------------------- */
  34.  
  35. MRESULT EXPENTRY MM_MCINOTIFY_Handle( USHORT msg, MPARAM mp1, MPARAM mp2 );
  36. void MM_Set_Host( HWND hwnd );
  37.  
  38. /* ---------------------------------------------------------------------- */
  39.  
  40.  
  41.  
  42.  
  43.  
  44. #define LCID_MYFONT 1
  45.  
  46. HWND hwndControl;
  47. HWND hwndSong;
  48. HWND hwndTime;
  49. HWND hwndName;
  50. HWND hwndQueue;
  51. HWND hwndChan1, hwndChan2, hwndChan3, hwndChan4;
  52.  
  53. HPS hpsSong;
  54. HPS hpsTime;
  55. HPS hpsName;
  56. HPS hpsQueue;
  57. HPS hpsChan1, hpsChan2, hpsChan3, hpsChan4;
  58.  
  59. RECTL rclTime, rclSong, rclName, rclQueue,
  60.     rclChan1, rclChan2, rclChan3, rclChan4;
  61.  
  62. HAB hab;
  63. HMQ hmq;
  64.  
  65. HSWITCH hSwitch;                /* Switch entry handle        */
  66.  
  67. int quiet = 0;                  /* Global flag for no text output */
  68. int suspended = 0;              /* flag for pause mode */
  69. int abortsong = 0;                  /* abort flag */
  70. int blink;
  71. int pauseack = 0;
  72. int terminate = 0;
  73. int iconic = 0;
  74.  
  75. struct pref pref;               /* Global user preferences */
  76.  
  77. int error_flag = 0;
  78.  
  79. int priority = 0;
  80.  
  81. /* global variable to catch various types of errors
  82.  * and achieve the desired flow of control
  83.  */
  84. int error;
  85. /* small hack for transposing songs on the fly */
  86. static int transpose;
  87.  
  88. char *msong[MAXSONGS];
  89.  
  90. int numsongs = 0,
  91.    songnum = 0,
  92.    frequency, 
  93.    oversample;
  94.  
  95. int fwidth, fheight;
  96.  
  97. USHORT DMAbuffersize = 63;
  98.  
  99. char playermode[32] = " ";
  100.  
  101. char title[] = "Tracker/PM";
  102. char paused[] = " (paused)";
  103.  
  104. char progname[128] = "Tracker";
  105.  
  106. char programpath[256];
  107. char currentdisk[3] = "c:";
  108. char currentdir[256];
  109.  
  110. char usage[] = \
  111.   "usage: %s [-][options] filename [filename [...]]\n"
  112.   "-h: Help; display usage information\n"
  113.   "-i: Iconic; start as an icon\n"
  114.   "-m: Mono; select single audio channel output\n"
  115.   "-s: Stereo; select dual audio channel output\n"
  116.   "-n: New; select new MOD type for mod playing\n"
  117.   "-o: Old; select old MOD type for mod playing\n"
  118.   "-b: Both; select both MOD types to try (default is -both)\n"
  119.   "-T: Terminate; terminate after playing all MODs\n"
  120.   "-L: Low priority; sets tracker to normal low priority (default)\n"
  121.   "-M: Middle priority; sets tracker to \"foregroundserver\" priority\n" 
  122.   "-H: Highest priority; sets tracker to \"timecritical\" priority\n"
  123.   "-dnum: DMA buffer size; set DMA buffer size in K.\n"
  124.   "-fnum: Frequency; sets playback frequency to <num> Hz.\n"
  125.   "-tnum: Transpose all notes up <num> half-steps\n"
  126.   "-rnum: Repeat; repeats <num> number of repeats (0 is forever) (default 1)\n"
  127.   "-Bnum: Blend; sets percent of channel mixing to <num>. (0=spatial, 100=mono)\n"
  128.   "-Onum: Oversample; set oversampling to <num> times.\n"
  129.   "-Snum: Speed; set song speed to <speed>.  Some songs want 60 (default 50)\n"
  130.   "%s: OS/2 2.0 32bit MOD player\n";
  131.  
  132. FILE *debug;
  133. int logerrors = 1;
  134.  
  135. void quit(int rv)
  136. {
  137.    restoreparams();
  138.    close_audio();
  139.    WinDestroyWindow(hwndControl);
  140.    WinDestroyMsgQueue(hmq);
  141.    WinTerminate(hab);
  142.    exit(rv);
  143. }
  144.  
  145. void trackerror(int err, char *txt, int errtype)
  146. {
  147.    if (logerrors) fprintf(debug, "ERROR %d: %s\n", err, txt);
  148.    if (errtype == FATAL_ERROR) quit(err);
  149. }
  150.  
  151. struct song *do_read_song(char *s, int type)
  152. {
  153.   struct song *song;
  154.   FILE *fp;
  155.  
  156.   fp = fopen (s, "rb");
  157.   if (fp == NULL)
  158.     {
  159.       trackerror(1, "Unable to open tune file", NONFATAL_ERROR);
  160.       return NULL;
  161.     }
  162.   song = read_song (fp, type, transpose);
  163.   fclose (fp);
  164.   
  165.   return song;
  166. }
  167.  
  168. char *strtolower(wordv)
  169. char *wordv;
  170. {
  171.    int loop = 0;
  172.  
  173.    while(wordv[loop])
  174.    {
  175.       if (isupper(wordv[loop])) wordv[loop] = tolower(wordv[loop]);
  176.       loop++;
  177.    }
  178.    return wordv;
  179. }
  180.  
  181. void checkext(char *fn)
  182. {
  183.    int l;
  184.  
  185.    strtolower(fn);
  186.    l = strlen(fn);
  187.    if ((l < 5)||(strcmp(&fn[l-4],".mod"))) 
  188.       if (fn[l] != '.') strcat(fn, ".mod");
  189. }
  190.  
  191. void getpname(char *argv[])
  192. {
  193.    int cp;
  194.    char t[2] = { '\0', '\0' };
  195.  
  196.    programpath[0] = '\0';
  197.    cp = strlen(argv[0]);
  198.    if (cp)
  199.    {
  200.       while (cp && (argv[0][cp] != '\\') && (argv[0][cp] != ':')) cp--;
  201.       if (cp)
  202.       {
  203.          t[0] = argv[0][cp];
  204.      argv[0][cp] = '\0';
  205.          cp++;
  206.       }
  207.       strcpy(progname, &argv[0][cp]);
  208.       strtolower(progname);
  209.       cp = strlen(progname);
  210.       while (cp && (progname[cp] != '.')) cp--;
  211.       if (progname[cp] == '.') progname[cp] = '\0';
  212.       strcpy(programpath, argv[0]);
  213.       strcat(programpath, t);
  214.    }
  215. }
  216.  
  217.  
  218. void fixfn(char *fn)
  219. {
  220.    int cp;
  221.    static char buf[256]; /* buf[strlen(fn)]; RKG 931020 */
  222.  
  223.    cp = strlen(fn);
  224.    if (cp)
  225.    {
  226.       while (cp && (fn[cp] != '\\') && (fn[cp] != ':')) cp--;
  227.       strcpy(buf, &fn[cp+1]);
  228.       strcpy(fn, buf);
  229.    }
  230. }
  231.  
  232. void gotodir(char *path)
  233. {
  234.    int cp;
  235.    static char buf[256]; /* buf[strlen(path)+1]; RKG 931020 */
  236.    char *p;
  237.  
  238.    strcpy(buf, path);
  239.    p = buf;
  240.    if (p[1] == ':')
  241.    {
  242.       if (islower(p[0])) p[0] = toupper(p[0]);
  243.       if (isupper(p[0])) 
  244.       {
  245. /*     DosSetDefaultDisk(p[0]-'A'); */
  246.      currentdisk[0] = p[0];
  247.       }
  248.       p += 2;
  249.    }
  250.    cp = strlen(p);
  251.    if (cp)
  252.    {
  253.       while (cp && (p[cp] != '\\') && (p[cp] != ':')) cp--;
  254.       p[cp+1] = '\0';
  255.       strcpy(currentdir, p);
  256. /*      DosSetCurrentDir(p); */
  257.    }   
  258. }
  259.  
  260. int OpenDlg(HWND hwndOwner)
  261. {
  262.    FILEDLG fild;         /* File dialog structure. */
  263.  
  264.    memset(&fild, 0, sizeof(FILEDLG));
  265.    fild.cbSize     = sizeof(FILEDLG);
  266.    fild.fl         = FDS_OPEN_DIALOG|FDS_CENTER;
  267.    fild.pszIDrive  = currentdisk;
  268.    strcpy(fild.szFullFile, currentdir);
  269.    strcat(fild.szFullFile, "*.mod");
  270.    fild.pszTitle = "Queue Song";
  271.    fild.pszOKButton = "Queue";
  272.    WinFileDlg(HWND_DESKTOP, hwndOwner, &fild);
  273.    if (fild.lReturn == DID_OK)
  274.    {
  275.       DosAllocMem((PVOID) &msong[numsongs], strlen(fild.szFullFile)+1,
  276.           PAG_READ|PAG_WRITE|PAG_COMMIT);
  277. /*    msong[numsongs] = (char *)malloc(strlen(fild.szFullFile)+1); */
  278.       strcpy(msong[numsongs], fild.szFullFile);
  279.       gotodir(msong[numsongs]);
  280.       numsongs++;
  281.       PrintSong(NULL);
  282.       return 1;
  283.    }
  284.    return 0;
  285. }
  286.  
  287. /* EXPENTRY added RKG */
  288. MRESULT EXPENTRY AboutDlgProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  289. {
  290.    switch(msg)
  291.    {
  292.       case WM_INITDLG:
  293.      break;
  294.  
  295.       case WM_COMMAND:
  296.       switch(SHORT1FROMMP(mp1))
  297.        {
  298.         case MBID_OK:
  299.                break;
  300.      }
  301.      break;
  302.    }
  303.    return WinDefDlgProc(hwnd, msg, mp1, mp2);
  304. }
  305.  
  306. MRESULT EXPENTRY ControlDlgProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
  307. {
  308.    static TID tid;
  309.    static THREADPARAMS tp;
  310.    static struct song *song = NULL;
  311.    static char buf[256];
  312.    static HRGN hrgnSong;
  313.    static HRGN hrgnTime;
  314.    static HRGN hrgnName;
  315.    static HRGN hrgnQueue;
  316.    static HRGN hrgnChan1;
  317.    static HRGN hrgnChan2;
  318.    static HRGN hrgnChan3;
  319.    static HRGN hrgnChan4;
  320.    static HRGN hrgnTemp;
  321.    static int x;
  322.    static FONTMETRICS fm;
  323.    static REAL_SWCNTRL SwitchData;        /* Switch control data block  */
  324.  
  325.    switch (msg)
  326.    {
  327.       case WM_INITDLG:
  328.          DosCreateEventSem("\\sem32\\done", &tp.hevDone, 0, (BOOL32) FALSE);
  329.      DosCreateEventSem("\\sem32\\pause", &tp.hevPause, 0, (BOOL32) FALSE);
  330.      tp.fPlaying = FALSE;
  331.      hwndSong = WinWindowFromID(hwnd, ID_SONGRECT);
  332.      hwndTime = WinWindowFromID(hwnd, ID_TIMERECT);
  333.      hwndName = WinWindowFromID(hwnd, ID_NAMERECT);
  334.      hwndQueue = WinWindowFromID(hwnd, ID_QUEUERECT);
  335.      hwndChan1 = WinWindowFromID(hwnd, ID_CHAN1RECT);
  336.      hwndChan2 = WinWindowFromID(hwnd, ID_CHAN2RECT);
  337.      hwndChan3 = WinWindowFromID(hwnd, ID_CHAN3RECT);
  338.      hwndChan4 = WinWindowFromID(hwnd, ID_CHAN4RECT);
  339.      hpsSong = WinGetPS(hwndSong);
  340.      hpsTime = WinGetPS(hwndTime);
  341.      hpsName = WinGetPS(hwndName);
  342.      hpsQueue = WinGetPS(hwndQueue);
  343.      hpsChan1 = WinGetPS(hwndChan1);
  344.      hpsChan2 = WinGetPS(hwndChan2);
  345.      hpsChan3 = WinGetPS(hwndChan3);
  346.      hpsChan4 = WinGetPS(hwndChan4);
  347.      WinQueryWindowRect(hwndSong, &rclSong);
  348.      WinQueryWindowRect(hwndTime, &rclTime);
  349.      WinQueryWindowRect(hwndName, &rclName);
  350.      WinQueryWindowRect(hwndQueue, &rclQueue);
  351.      WinQueryWindowRect(hwndChan1, &rclChan1);
  352.      WinQueryWindowRect(hwndChan2, &rclChan2);
  353.      WinQueryWindowRect(hwndChan3, &rclChan3);
  354.      WinQueryWindowRect(hwndChan4, &rclChan4);
  355.      hrgnSong = GpiCreateRegion(hpsSong, 1, &rclSong);
  356.      hrgnTime = GpiCreateRegion(hpsTime, 1, &rclTime);
  357.      hrgnName = GpiCreateRegion(hpsName, 1, &rclName);
  358.      hrgnQueue = GpiCreateRegion(hpsQueue, 1, &rclQueue);
  359.      hrgnChan1 = GpiCreateRegion(hpsChan1, 1, &rclChan1);
  360.      hrgnChan2 = GpiCreateRegion(hpsChan2, 1, &rclChan2);
  361.      hrgnChan3 = GpiCreateRegion(hpsChan3, 1, &rclChan3);
  362.      hrgnChan4 = GpiCreateRegion(hpsChan4, 1, &rclChan4);
  363.      GpiSetClipRegion(hpsSong, hrgnSong, &hrgnTemp);
  364.      GpiSetClipRegion(hpsTime, hrgnTime, &hrgnTemp);
  365.      GpiSetClipRegion(hpsName, hrgnName, &hrgnTemp);
  366.      GpiSetClipRegion(hpsQueue, hrgnQueue, &hrgnTemp);
  367.      GpiSetClipRegion(hpsChan1, hrgnChan1, &hrgnTemp);
  368.      GpiSetClipRegion(hpsChan2, hrgnChan2, &hrgnTemp);
  369.      GpiSetClipRegion(hpsChan3, hrgnChan3, &hrgnTemp);
  370.      GpiSetClipRegion(hpsChan4, hrgnChan4, &hrgnTemp);
  371.          GpiCreateLogColorTable(hpsSong, LCOL_PURECOLOR, LCOLF_RGB,
  372.                 0L, 0L, NULL);
  373.          GpiCreateLogColorTable(hpsTime, LCOL_PURECOLOR, LCOLF_RGB,
  374.                 0L, 0L, NULL);
  375.          GpiCreateLogColorTable(hpsName, LCOL_PURECOLOR, LCOLF_RGB,
  376.                 0L, 0L, NULL);
  377.          GpiCreateLogColorTable(hpsQueue, LCOL_PURECOLOR, LCOLF_RGB,
  378.                 0L, 0L, NULL);
  379.          GpiCreateLogColorTable(hpsChan1, LCOL_PURECOLOR, LCOLF_RGB,
  380.                 0L, 0L, NULL);
  381.          GpiCreateLogColorTable(hpsChan2, LCOL_PURECOLOR, LCOLF_RGB,
  382.                 0L, 0L, NULL);
  383.          GpiCreateLogColorTable(hpsChan3, LCOL_PURECOLOR, LCOLF_RGB,
  384.                 0L, 0L, NULL);
  385.          GpiCreateLogColorTable(hpsChan4, LCOL_PURECOLOR, LCOLF_RGB,
  386.                 0L, 0L, NULL);
  387.      EzfQueryFonts(hpsSong);
  388.      EzfQueryFonts(hpsName);
  389.          EzfCreateLogFont(hpsSong, LCID_MYFONT, FONTFACE_TIMES, 
  390.                                  FONTSIZE_10, 0) ;         
  391.          EzfCreateLogFont(hpsName, LCID_MYFONT, FONTFACE_TIMES, 
  392.                                  FONTSIZE_10, 0) ;         
  393.      GpiSetCharSet(hpsSong, LCID_MYFONT);
  394.      GpiSetCharSet(hpsName, LCID_MYFONT);
  395.      strcpy(buf, programpath);
  396.      strcat(buf, "lcd.fon");
  397.      if (!GpiLoadFonts(hab, buf)) trackerror(1, "can't load font", FATAL_ERROR);
  398.      EzfQueryFonts(hpsTime);
  399.      EzfQueryFonts(hpsQueue);
  400.          EzfCreateLogFont(hpsTime, LCID_MYFONT, FONTFACE_SYSTEM,
  401.                                  FONTSIZE_10, 0) ;         
  402.          EzfCreateLogFont(hpsQueue, LCID_MYFONT, FONTFACE_SYSTEM,
  403.                                  FONTSIZE_10, 0) ;         
  404.      GpiSetCharSet(hpsTime, LCID_MYFONT);
  405.      GpiSetCharSet(hpsQueue, LCID_MYFONT);
  406.      GpiQueryFontMetrics(hpsSong, sizeof(FONTMETRICS), &fm);
  407.      fwidth = (USHORT)(1.2*fm.lAveCharWidth);
  408.          fheight= (USHORT)(fm.lExternalLeading+fm.lMaxBaselineExt);
  409.      playermode[0] = PLAYER_STOP;
  410.  
  411.      if (numsongs) WinPostMsg(hwnd,WM_COMMAND,MPFROM2SHORT(IDM_PLAY,0),0);
  412.  
  413.      break;
  414.  
  415. /* ---------------------------------------------- RKG MMPM/2 */
  416.       case MM_MCINOTIFY:
  417.       case MM_MCIPLAYLISTMESSAGE:
  418.          return MM_MCINOTIFY_Handle( msg, mp1, mp2 );
  419. /* --------------------------------------------------------- */
  420.  
  421.  
  422.       case WM_SHOW:
  423.       case WM_ENABLE:
  424.       case WM_ACTIVATE:
  425.          DosEnterCritSec();
  426.  
  427. /*     WinQueryWindowRect(hwndSong, &rclSong);
  428.      WinFillRect(hpsSong, &rclSong, CLR_BLACK);
  429.      WinQueryWindowRect(hwndName, &rclName);
  430.      WinFillRect(hpsName, &rclName, CLR_BLACK);
  431.      WinQueryWindowRect(hwndTime, &rclTime);
  432.      WinFillRect(hpsTime, &rclTime, CLR_BLACK); 
  433. */
  434.  
  435.      if (tp.fPlaying) PrintSong(tp.fn);
  436.      else PrintSong(NULL);
  437.      
  438.      DosExitCritSec();
  439.      break;
  440.        
  441.       case WM_CLOSE:
  442.             if (tp.fPlaying) WinSendMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_STOP,0), 0);
  443.      return WinDefWindowProc(hwnd, msg, mp1, mp2);
  444.  
  445.       case WM_DESTROY:
  446.          WinReleasePS(hpsSong);
  447.      WinReleasePS(hpsTime);
  448.      WinReleasePS(hpsName);
  449.      WinReleasePS(hpsQueue);
  450.      WinReleasePS(hpsChan1);
  451.      WinReleasePS(hpsChan2);
  452.      WinReleasePS(hpsChan3);
  453.      WinReleasePS(hpsChan4);
  454.      return 0;
  455.  
  456.       case WM_COMMAND:
  457.      switch (SHORT1FROMMP (mp1))
  458.      {
  459.         case IDM_OPEN:
  460.            if (OpenDlg(hwnd)&&!suspended) WinSendMsg(hwnd,WM_COMMAND,MPFROM2SHORT(IDM_PLAY,0),0);
  461.            return 0;
  462.  
  463.         case IDM_PAUSE:
  464.            if (suspended) WinSendMsg(hwnd,WM_COMMAND,MPFROM2SHORT(IDM_PLAY,0),0);
  465.            else if (tp.fPlaying)
  466.            {
  467.           blink = 1;
  468.           DosResetEventSem(tp.hevPause, &x);
  469.           pauseack = 1;
  470.           WinQuerySwitchEntry(hSwitch, (PSWCNTRL) &SwitchData);
  471.           strcpy(buf, title);
  472.           strcat(buf, " - ");
  473.           strcat(buf, tp.fn);
  474.           strcat(buf, paused);
  475.           strcpy(SwitchData.szSwtitle, buf);
  476.           WinChangeSwitchEntry(hSwitch, (PSWCNTRL) &SwitchData);
  477.           WinSetWindowText(hwndControl, buf);
  478.            }
  479.            return 0;
  480.  
  481.         case IDM_FF:
  482.         case IDM_FR:
  483.  
  484.         case IDM_PREV:
  485.         case IDM_NEXT:
  486.            if (SHORT1FROMMP(mp1)==IDM_PREV)
  487.            {
  488.           songnum -= 2;
  489.           if (songnum < 0) songnum = 0;
  490.           if (tp.fPlaying)
  491.           {
  492.              playermode[0] = PLAYER_REWIND;
  493.              PrintSong(NULL);
  494.            }
  495.            }
  496.            else if (tp.fPlaying)
  497.            {
  498.               playermode[0] = PLAYER_FASTFORWARD;
  499.           PrintSong(NULL);
  500.            }
  501.            if (tp.fPlaying) WinSendMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_STOP,0), 0);
  502.            WinSendMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_PLAY,0), 0);
  503.            return 0;
  504.  
  505.             case IDM_RESTART:
  506.            if (tp.fPlaying)
  507.            {
  508.               WinSendMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_STOP,0), 0);
  509.           songnum--;
  510.               WinSendMsg(hwnd, WM_COMMAND, MPFROM2SHORT(IDM_PLAY,0), 0);
  511.            }
  512.            return 0;
  513.  
  514.         case IDM_STOP:
  515.            if (tp.fPlaying)
  516.            {
  517.           blink = TRUE;
  518.           abortsong = TRUE;
  519.           tp.fTerminate = TRUE;
  520.           if (suspended) 
  521.           {
  522.              DosPostEventSem(tp.hevPause);
  523. /*             DosResumeThread(tid); */
  524.              WinQuerySwitchEntry(hSwitch, (PSWCNTRL) &SwitchData); 
  525.              strcpy(SwitchData.szSwtitle, title);
  526.              WinChangeSwitchEntry(hSwitch, (PSWCNTRL) &SwitchData);
  527.              WinSetWindowText(hwndControl,title);
  528.              suspended = 0;
  529.           }
  530.           DosWaitEventSem(tp.hevDone, SEM_INDEFINITE_WAIT);
  531.            }
  532.            return 0;
  533.  
  534.         case IDM_PLAY:
  535.            if (tp.fPlaying)
  536.           if (suspended)
  537.           {
  538.              DosPostEventSem(tp.hevPause);
  539. /*             DosResumeThread(tid); */
  540.              WinQuerySwitchEntry(hSwitch, (PSWCNTRL) &SwitchData); 
  541.              strcpy(buf,title);
  542.              strcat(buf, " - ");
  543.              strcat(buf, tp.fn);
  544.              strcpy(SwitchData.szSwtitle, buf);
  545.              WinChangeSwitchEntry(hSwitch, (PSWCNTRL) &SwitchData);
  546.              WinSetWindowText(hwnd,buf);
  547.              suspended = 0;
  548.              playermode[0] = PLAYER_PLAY;
  549.              PrintSong(NULL);
  550.              return 0;
  551.           }
  552.               else return 0;
  553.            if (songnum < numsongs)
  554.            {
  555.           switch (pref.type)
  556.           {
  557.              case BOTH:
  558.                 song = do_read_song(msong[songnum], NEW);
  559.                 if (!song) song = do_read_song (msong[songnum], OLD);
  560.                 break;
  561.              case OLD:
  562.                 song = do_read_song (msong[songnum], pref.type);
  563.                 break;
  564.              case NEW:
  565.                 song = do_read_song (msong[songnum], NEW_NO_CHECK);
  566.                 break;
  567.           }
  568.           if (song != NULL)
  569.           {
  570.              DosResetEventSem(tp.hevDone, &x);
  571.              tp.fTerminate = FALSE;
  572.              tp.song = song;
  573.              tp.pref = &pref;
  574.              tp.fPlaying = TRUE;
  575.              tp.hwndControl = hwnd;
  576.              DosAllocMem((PVOID) &tp.fn, strlen(msong[songnum])+1,
  577.                  PAG_READ|PAG_WRITE|PAG_COMMIT);
  578.              strcpy(tp.fn, msong[songnum]);
  579.              fixfn(tp.fn);
  580.              playermode[0] = PLAYER_PLAY;
  581.              PrintSong(NULL);
  582.              /* DosCreateThread(&tid, PlaySong, (ULONG)&tp, 0, 0x4000); */
  583.                      tid = (TID)_beginthread( PlaySong, 0, 8192, (PVOID)&tp ); /* RKG 931202 */
  584.              if (priority) DosSetPriority(PRTYS_THREAD,priority,0,tid);
  585.              WinQuerySwitchEntry(hSwitch, (PSWCNTRL) &SwitchData); 
  586.              strcpy(buf,title);
  587.              strcat(buf, " - ");
  588.              strcat(buf, tp.fn);
  589.              strcpy(SwitchData.szSwtitle, buf);
  590.              WinChangeSwitchEntry(hSwitch, (PSWCNTRL) &SwitchData);
  591.              WinSetWindowText(hwnd,buf);
  592.           }
  593.           songnum++;
  594.            }
  595.            else
  596.            {
  597.           playermode[0] = PLAYER_STOP;
  598.           PrintSong(NULL);
  599.              if (terminate) WinSendMsg(hwnd, WM_CLOSE, 0, 0);
  600.            }
  601.            return 0;
  602.  
  603.         case IDM_EXIT:
  604.            WinSendMsg (hwnd, WM_CLOSE, 0L, 0L);
  605.            return 0;
  606.  
  607.             case IDM_ABOUT:
  608.            DosEnterCritSec();
  609.  
  610.                WinLoadDlg(HWND_DESKTOP, hwnd, AboutDlgProc, NULL, IDM_ABOUT, NULL);
  611.  
  612.            DosExitCritSec();
  613.                return 0;
  614.      }
  615.      break;
  616.    }
  617.    return WinDefDlgProc(hwnd, msg, mp1, mp2);
  618. }
  619.  
  620. void getcd(char *cdfile)
  621. {
  622.    FILE *cdf;
  623.    char buf[256];
  624.  
  625.    if ((cdf = fopen(cdfile, "rt")) == NULL) return;
  626.    while (!feof(cdf))
  627.    {
  628.       fscanf(cdf, "%s", buf);
  629.       msong[numsongs] = (char *)malloc(strlen(buf)+5);
  630.       strcpy(msong[numsongs], buf);
  631.       checkext(msong[numsongs]);
  632.       numsongs++;
  633.    }
  634.    fclose(cdf);
  635. }
  636.  
  637. int checkcd(char *fn)
  638. {
  639.    int x;
  640.    char buf[4];
  641.  
  642.    if ((x = strlen(fn)) < 4) return 0;
  643.    strcpy(buf, &fn[x-3]);
  644.    strtolower(buf);
  645.    return !strcmp(buf, ".cd");
  646. }
  647.  
  648. void parsecommandline(int argc, char *argv[])
  649. {
  650.    int i, j, count;
  651.  
  652.    if (argc) for (i=1; i<argc; i++)
  653.       {
  654.      if (argv[i][0] == '@') getcd(&argv[i][1]);
  655.      else if (checkcd(argv[i])) getcd(argv[i]);
  656.      else if (argv[i][0] != '-') 
  657.      {
  658.         msong[numsongs] = (char *)malloc(strlen(argv[i])+5);
  659.         strcpy(msong[numsongs], argv[i]);
  660.         checkext(msong[numsongs]);
  661.         numsongs++;
  662.      }
  663.      else
  664.      {
  665.         count = strlen(argv[i]);
  666.         for(j=1;j<count;j++)
  667.         {
  668.            switch (argv[i][j])
  669.            {
  670. /*          case 'h': help(); break; */
  671.           case 'i': iconic = TRUE; break;
  672.           case 'p': pref.tolerate = 0; break; /* tolerate faults */
  673.           case 'n': pref.type = NEW; break; /* new mod type */
  674.                case 'o': pref.type = OLD; break; /* old mod type */
  675.           case 'b': pref.type = BOTH; break; /* try both types */
  676.           case 'm': pref.stereo = 0; break; /* mono */
  677.           case 's': pref.stereo = 1; break; /* stereo */
  678.           case 'd': DMAbuffersize = atoi(&argv[i][j+1]); break;
  679.           case 'T': terminate = 1; break;
  680.           case 'f': frequency = atoi(&argv[i][j+1]); break; /* frequency */
  681.           case 't': transpose = atoi(&argv[i][j+1]); break;
  682.           case 'r': pref.repeats = atoi(&argv[i][j+1]); break;
  683.           case 'O': oversample = atoi(&argv[i][j+1]); break;
  684.           case 'S': pref.speed = atoi(&argv[i][j+1]); break;
  685.           case 'B': set_mix(atoi(&argv[i][j+1])); break;
  686.           case 'L': priority = 0; break;
  687.           case 'M': priority = PRTYC_FOREGROUNDSERVER; break;
  688.           case 'H': priority = PRTYC_TIMECRITICAL; break;
  689.           default: error_flag++; break;
  690.            }
  691.         }
  692.      }
  693.       }
  694. }
  695.  
  696. void main(int argc, char *argv[])
  697. {
  698.    static char szClientClass[] = "form.child";
  699.    QMSG qmsg;
  700.    REAL_SWCNTRL SwitchData;
  701.    HPOINTER hptr;
  702.    HACCEL haccel;
  703.   
  704.    if (logerrors)
  705.    {
  706.       debug = fopen("debug", "w");
  707.       fprintf(debug, "error log file opened\n");
  708.    }
  709.    getpname(argv);
  710.    pref.stereo = DEFAULT_CHANNELS - 1;
  711.    pref.type = BOTH;
  712.    pref.repeats = 1;
  713.    pref.speed = 50;
  714.    pref.tolerate = 2;
  715.    pref.verbose = 0;
  716.    pref.stereo = 1;
  717.    frequency = 20000;
  718.    oversample = 1;
  719.    transpose = 0;
  720.  
  721.    set_mix (DEFAULT_MIX);        /* 0 = full stereo, 100 = mono */
  722.    parsecommandline(argc, argv);
  723.  
  724.    if (numsongs) gotodir(msong[numsongs-1]);
  725.    error_flag = 0;
  726. /* ************* RKG 931202 open and init were here */
  727.  
  728.    hab = WinInitialize (0) ;
  729.    hmq = WinCreateMsgQueue (hab, 0) ;
  730.  
  731.    WinRegisterClass (hab, szClientClass, ControlDlgProc,
  732.                  CS_SIZEREDRAW, 0);
  733.  
  734.    hwndControl = WinLoadDlg(HWND_DESKTOP, NULL, ControlDlgProc, NULL, IDM_CONTROL, NULL);
  735.  
  736.  
  737. /* *************************************************** */
  738. /* RKG 931202 the following stmts were moved/added here because we need to
  739.    create the host dialog before we initialize the audio device */
  740.  
  741.    WinShowWindow( hwndControl, TRUE );
  742.    MM_Set_Host( hwndControl ); /* RKG added */
  743.  
  744.    frequency = open_audio(frequency, DMAbuffersize);
  745.    init_player(oversample, frequency);
  746.  
  747. /* *************************************************** */
  748.  
  749.    SwitchData.hwnd = hwndControl;
  750.    SwitchData.hwndIcon = NULL;
  751.    SwitchData.hprog = NULL;
  752.    SwitchData.idProcess = 0;
  753.    SwitchData.idSession = 0;
  754.    SwitchData.uchVisibility = SWL_VISIBLE;
  755.    SwitchData.fbJump = SWL_JUMPABLE;
  756.    SwitchData.bProgType = PROG_PM;
  757.  
  758.    strcpy(SwitchData.szSwtitle,title);
  759.  
  760.    hSwitch = WinCreateSwitchEntry(hab, (PSWCNTRL)&SwitchData);
  761.  
  762.    hptr = WinLoadPointer(HWND_DESKTOP, NULL, ID_TRACKER);
  763.    WinPostMsg(hwndControl, WM_SETICON, (MPARAM)hptr, NULL); /* MPARAM :RKG */
  764.    haccel = WinLoadAccelTable(hab, NULL, ID_TRACKER);
  765.    WinSetAccelTable(hab, haccel, hwndControl);
  766.  
  767.    PrintSong(NULL);
  768.  
  769.    while (WinGetMsg (hab, &qmsg, NULL, 0, 0))
  770.        WinDispatchMsg (hab, &qmsg);
  771.  
  772.    quit(0);
  773. }
  774.