home *** CD-ROM | disk | FTP | other *** search
/ modiromppu / modiromppu.iso / PROGRAMS / ORGPACKS / DIDO4.ZIP / SOURCE.ZIP / DIDO.C next >
C/C++ Source or Header  |  1995-06-01  |  22KB  |  668 lines

  1.  
  2. // This is the source to Dido 4.
  3. //
  4. // Lossless digital sound copy from AUDIO CD to WAV files, without crackle &
  5. // pops. No sampling involved. The best quality you can get.
  6. //
  7. // Windows 3.1 freeware by
  8. //                          Michiel Overtoom   (motoom@xs4all.nl)
  9. // Bases on work done by
  10. //                          Yeng-Chee Su       (yenchee@csie.nctu.edu.tw)
  11. // and
  12. //                          Klaas Hemstra      (hst@mh.nl)
  13. //
  14. // and of course... source available.
  15.  
  16. #include <windows.h>
  17. #include <commdlg.h>
  18. #include <dos.h>
  19. #include <stdio.h>
  20. #include <io.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <dir.h>
  24. #include <time.h>
  25. #include <mmsystem.h>            // for mciSendstring
  26. #include "dido.h"                // defines for program resources
  27.  
  28. #define HELPFILE "dido.hlp"
  29.  
  30. HINSTANCE hinst;
  31. WORD    nbuf;                    // number of low memory dos buffers (set by allocating routine)
  32. #define MAXNBUF 20                // Max. number of low mem buffers that can be allocated
  33. int     CDROM;                     // CDROM unit. 0==a, 1==b, etc
  34. int     lowest, highest;        // Lowest and highest track on the CD
  35. int        lineinc=4,pageinc=12;    // skipping factors for scrollbar (in seconds)
  36. DWORD     total_time;                // Total time on CD
  37. char     s[160],t[80],u[80];        // scratch strings
  38. char    waveditor[160]="MPLAYER.EXE";    // editor for WAV files (INI setting)
  39. BOOL     bit16=1,hz44=1,stereo=1;        // settings from recording dialog; options for
  40.                                         // thinning out the recorded sound.
  41.  
  42. #define mb(x) MessageBox(0,x,"Error",0);
  43.  
  44. #include "didod.h"        // low level cd defines/structs
  45. #include "didod.c"        // low level cd routines via DPMI
  46. #include "didologo.c"    // logo routines
  47.  
  48.  
  49. // Set all the controls in a Dialog to the same font
  50. BOOL CALLBACK EnumDialogChild(HWND hw,LPARAM font) {
  51.     SendMessage(hw,WM_SETFONT,(WPARAM)font,0);
  52.        return 1;
  53.     }
  54. void SetDialogFont(HWND dialog,HFONT font)
  55. {
  56.     EnumChildWindows(dialog,EnumDialogChild,(LPARAM)font);
  57. }
  58.  
  59.  
  60. // Center a window
  61. void CenterWindow(HWND hwnd) 
  62.     RECT r; 
  63.     GetWindowRect(hwnd, &r); 
  64.     SetWindowPos(hwnd, NULL,  
  65.        ((GetSystemMetrics(SM_CXSCREEN) - (r.right - r.left)) / 2),  
  66.        ((GetSystemMetrics(SM_CYSCREEN) - (r.bottom - r.top)) / 2),  
  67.        0, 0, SWP_NOSIZE | SWP_NOACTIVATE);  
  68.  
  69. #include "didorec.c"    // recording routine
  70.  
  71.  
  72. // Delay routine, used in initialization
  73. void delay(long ticks)
  74. {
  75.     long expire=clock()+ticks;
  76.     while(clock()<expire);
  77. }
  78.  
  79.  
  80. // Storage for track table
  81. #define MAXTRACK 100        // Have you ever seen a CD with more than 100 tracks?
  82. int   ntrack=0;                // Nr. of tracks on the CD
  83. int   tracknr[MAXTRACK];    // The track number
  84. DWORD trackloc[MAXTRACK];    // Track start in redbook format
  85. DWORD tracklen[MAXTRACK];    // Duration of track, in sectors
  86.  
  87.  
  88. // Build a table of tracks
  89. int BuildTrackTable(void)
  90. {
  91.     int i;
  92.     DWORD loc;
  93.     // Scan the tracks
  94.     ntrack=0;
  95.     for (i=lowest;i<=highest;i++) {
  96.         if (!GetTrackInfo(i,&loc)) return 0;
  97.         tracknr[ntrack]=i;
  98.         trackloc[ntrack]=loc;
  99.         ntrack++;
  100.         }
  101.     // Calculate the durations
  102.     trackloc[ntrack]=total_time;
  103.     for (i=0;i<ntrack;i++) tracklen[i]=Red2Sierra(trackloc[i+1])-Red2Sierra(trackloc[i]);
  104.     return 1;
  105. }
  106.  
  107.  
  108. // Ask for a WAV file
  109. int ChooseWavFile(HWND hwnd,char *fn)
  110. {
  111.     OPENFILENAME ofn;
  112.     char szFile[128]={0};
  113.     char szFileTitle[128]={0};
  114.     memset(&ofn, 0, sizeof(ofn));
  115.     strcpy(szFile,fn);
  116.     strcpy(szFileTitle,fn);
  117.     ofn.lStructSize = sizeof(ofn);
  118.     ofn.hwndOwner = hwnd;
  119.     ofn.lpstrFilter = "Wave audio (*.wav)\0*.wav\0";
  120.     ofn.nFilterIndex = 1;
  121.     ofn.lpstrFile= szFile;
  122.     ofn.nMaxFile = 128;
  123.     ofn.lpstrFileTitle= szFileTitle;
  124.     ofn.nMaxFileTitle = 128;
  125.     ofn.Flags = OFN_PATHMUSTEXIST|OFN_HIDEREADONLY;
  126.     if (!GetSaveFileName(&ofn)) return 0;
  127.     strcpy(fn,ofn.lpstrFile);
  128.     return 1;
  129. }
  130.  
  131.  
  132. // Get-a-value dialog proc
  133. struct values {
  134.     DWORD    val;
  135.     DWORD     from;
  136.     DWORD    to; 
  137.     };
  138. #pragma argsused
  139. BOOL CALLBACK ValueDlgProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
  140. {
  141.     char s[20];
  142.     static struct values *value; 
  143.     if (msg==WM_INITDIALOG) {
  144.         value=(struct values *)lp;
  145.         SetDialogFont(hdlg,GetStockObject(ANSI_VAR_FONT));
  146.            sprintf(s,"%ld",value->val);
  147.         SetDlgItemText(hdlg,VALUE,s);
  148.         }
  149.     if (msg==WM_COMMAND && wp==IDOK) {
  150.         GetDlgItemText(hdlg,VALUE,s,19);
  151.         value->val=atol(s);
  152.         if (value->val < value->from)
  153.             value->val=value->from;
  154.         else if (value->val > value->to)
  155.             value->val=value->to;
  156.         EndDialog(hdlg,1);
  157.         }
  158.     return 0;
  159. }
  160.  
  161.  
  162. // Wrapper for get-a-value dialog. Provides default, ranges, etc...
  163. DWORD GetValue(HWND caller,DWORD defalt,DWORD from,DWORD to)
  164. {
  165.     struct values value;
  166.     value.from=from; value.to=to; value.val=defalt;
  167.     DialogBoxParam(hinst,"ValueDlg",caller,ValueDlgProc,(LPARAM)&value);
  168.     return value.val;
  169. }
  170.  
  171.  
  172. // Record dialog
  173. #pragma argsused
  174. BOOL CALLBACK RecDlgProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
  175. {
  176.     static int restartsound=0,autorewind=1,autorepeat=1;
  177.     static int refresh=0;
  178.     static int tnr;                    // track number
  179.     static DWORD start,end;            // Start/ending recording position, redbook format
  180.     static WORD  sm,ss,sf;            // Start recording position: minute, second, frame
  181.     static WORD  em,es,ef;            // idem, End position
  182.     static DWORD sc,ec;                // Start/ending recording sectors
  183.     static char fn[80];                // Last used filename
  184.     DWORD dur;
  185.     WORD  div;
  186.  
  187.     if (msg==WM_INITDIALOG) {
  188.         // Initialize record dialog
  189.         fn[0]=0;                                              // Zap filename
  190.         tnr=(WORD)lp;                                        // Remember track number
  191.         sprintf(s,"Search (track %d)",tracknr[tnr]);        // put it also in the
  192.         SetWindowText(hdlg,s);                                // dialog title
  193.         CenterWindow(hdlg);
  194.         SetDialogFont(hdlg,GetStockObject(ANSI_VAR_FONT));
  195.         // Fill inputs with track defaults
  196.         Red2MSFC(start=trackloc[tnr],&sm,&ss,&sf,&sc);
  197.         Red2MSFC(end=trackloc[tnr+1],&em,&es,&ef,&ec);
  198.         // Set scroll bar extents en posities
  199.         SetScrollRange(GetDlgItem(hdlg,SBAR),SB_CTL,0,Red2Sierra(total_time)/75L,0);
  200.         SetScrollRange(GetDlgItem(hdlg,EBAR),SB_CTL,0,Red2Sierra(total_time)/75L,0);
  201.         SetScrollPos(GetDlgItem(hdlg,SBAR),SB_CTL,Red2Sierra(start)/75L,0);
  202.         SetScrollPos(GetDlgItem(hdlg,EBAR),SB_CTL,Red2Sierra(end)/75L,0);
  203.         // Assure all fields will be refreshed; also start playing the track
  204.         refresh=1;
  205.         restartsound=1;
  206.         }
  207.  
  208.     // Button pressed!
  209.     #define FRESH refresh=1; if (autorewind) restartsound=1
  210.     if (msg==WM_COMMAND) {
  211.         if (wp==LISTEN) restartsound=1;
  212.         if (wp==IDOK) {StopAudio(); EndDialog(hdlg,1);}
  213.         if (wp==STEREO) {stereo=1; refresh=1;}
  214.         if (wp==MONO) {stereo=0; refresh=1;}
  215.         if (wp==HZ44) {hz44=1; refresh=1;}
  216.         if (wp==HZ22) {hz44=0; refresh=1;}
  217.         if (wp==BIT16) {bit16=1; refresh=1;}
  218.         if (wp==BIT8) {bit16=0; refresh=1;}
  219.         if (wp==RECORD) {
  220.             StopAudio(); PlayAudio(start,10);            // This prevents sync errors (? beats me but it does!)
  221.             EnableWindow(hdlg,0);                        
  222.             sprintf(fn,"%d-%d-%d.wav",sm,ss,sf);        // Compose a filename using start time
  223.             if (ChooseWavFile(hdlg,fn)) {                // File selection box
  224.                 dur=Red2Sierra(end)-Red2Sierra(start);
  225.                 if (!record(fn,Red2Sierra(start),dur)) mb(error);    // record it.
  226.                 FRESH;
  227.                 }
  228.             EnableWindow(hdlg,1); SetFocus(hdlg);
  229.             }
  230.         if (wp==EDIT) {
  231.             if (access(fn,0)==0) {                        // Edit only allowed when last used
  232.                 sprintf(s,"%s %s",waveditor,fn);        // is present, and if the file exist.
  233.                 StopAudio();
  234.                 if (WinExec(s,SW_SHOWNORMAL)<32)        // Spawn the WAV editor
  235.                     MessageBox(hdlg,s,"cant execute editor",MB_OK);
  236.                 }
  237.             }
  238.         if (wp==AUTOREWIND) {autorewind=1-autorewind; refresh=1;}
  239.         if (wp==AUTOREPEAT) {autorepeat=1-autorepeat; refresh=1;}
  240.         // Adjusting start time...
  241.         if (wp==SM) {
  242.             sm=GetValue(hdlg,sm,0,99);
  243.             MSF2Red(sm,ss,sf,&start,&sc);    FRESH;
  244.             }
  245.         if (wp==SMDOWN) {
  246.             if (sm) sm--;
  247.             MSF2Red(sm,ss,sf,&start,&sc);    FRESH;
  248.             }
  249.         if (wp==SMUP)   {
  250.             sm++;
  251.             MSF2Red(sm,ss,sf,&start,&sc);   FRESH;
  252.             }
  253.         if (wp==SS) {
  254.             ss=GetValue(hdlg,ss,0,59);
  255.             MSF2Red(sm,ss,sf,&start,&sc);    FRESH;
  256.             }
  257.         if (wp==SSDOWN) {
  258.             if (ss) ss--;
  259.             else if (sm) {sm--; ss=59;}
  260.             MSF2Red(sm,ss,sf,&start,&sc);   FRESH;
  261.             }
  262.         if (wp==SSUP)   {
  263.             ss++;
  264.             if (ss>59) {ss=0; sm++;}
  265.             MSF2Red(sm,ss,sf,&start,&sc);   FRESH;
  266.             }
  267.         if (wp==SF) {
  268.             sf=GetValue(hdlg,sf,0,74);
  269.             MSF2Red(sm,ss,sf,&start,&sc);    FRESH;
  270.             }
  271.         if ((wp==SFDOWN)||(wp==SCDOWN)) {
  272.             if (sf) {
  273.                 sf--;
  274.                 }
  275.             else if (ss) {
  276.                 ss--; sf=74;
  277.                 }
  278.             else if (sm) {
  279.                 sm--; ss=59; sf=74;
  280.                 }
  281.             MSF2Red(sm,ss,sf,&start,&sc);   FRESH;
  282.             }
  283.         if ((wp==SFUP)||(wp==SCUP))   {
  284.             sf++;
  285.             if (sf>74) {
  286.                 sf=0; ss++;
  287.                 if (ss>59) {
  288.                     sm++; ss=0;
  289.                     }
  290.                 }
  291.             MSF2Red(sm,ss,sf,&start,&sc);   FRESH;
  292.             }
  293.         // Adjusting end time...
  294.         if (wp==EM) {
  295.             em=GetValue(hdlg,em,0,99);
  296.             MSF2Red(em,es,ef,&end,&ec);    FRESH;
  297.             }
  298.         if (wp==EMDOWN) {
  299.             if (em) em--;
  300.             MSF2Red(em,es,ef,&end,&ec);        FRESH;
  301.             }
  302.         if (wp==EMUP)   {
  303.             em++;
  304.             MSF2Red(em,es,ef,&end,&ec);       FRESH;
  305.             }
  306.         if (wp==ES) {
  307.             es=GetValue(hdlg,es,0,59);
  308.             MSF2Red(em,es,ef,&end,&ec);    FRESH;
  309.             }
  310.         if (wp==ESDOWN) {
  311.             if (es) es--;
  312.             else if (em) {em--; es=59;}
  313.             MSF2Red(em,es,ef,&end,&ec);        FRESH;
  314.             }
  315.         if (wp==ESUP)   {
  316.             es++;
  317.             if (es>59) {es=0; em++;}
  318.             MSF2Red(em,es,ef,&end,&ec);        FRESH;
  319.             }
  320.         if (wp==EF) {
  321.             ef=GetValue(hdlg,ef,0,74);
  322.             MSF2Red(em,es,ef,&end,&ec);    FRESH;
  323.             }
  324.         if ((wp==EFDOWN)||(wp==ECDOWN)) {
  325.             if (ef) {
  326.                 ef--;
  327.                 }
  328.             else if (es) {
  329.                 es--; ef=74;
  330.                 }
  331.             else if (em) {
  332.                 em--; es=59; ef=74;
  333.                 }
  334.             MSF2Red(em,es,ef,&end,&ec);        FRESH;
  335.             }
  336.         if ((wp==EFUP)||(wp==ECUP))   {
  337.             ef++;
  338.             if (ef>74) {
  339.                 ef=0; es++;
  340.                 if (es>59) {
  341.                     em++; es=0;
  342.                     }
  343.                 }
  344.             MSF2Red(em,es,ef,&end,&ec);        FRESH;
  345.             }
  346.         }
  347.  
  348.     // Scroll bar?
  349.     if (msg==WM_HSCROLL) { // SBAR, EBAR
  350.         BOOL isstart=0;
  351.         int sc=wp;                // Scrollcode
  352.         int pos=LOWORD(lp);        // position
  353.         if (GetDlgItem(hdlg,SBAR)==(HWND)HIWORD(lp)) isstart=1;
  354.         if (sc==SB_THUMBPOSITION || sc==SB_THUMBTRACK) {
  355.             if (isstart) 
  356.                 Red2MSFC(start=Sierra2Red(75L*pos),&sm,&ss,&sf,&sc);
  357.             else 
  358.                 Red2MSFC(end=Sierra2Red(75L*pos),&em,&es,&ef,&ec);
  359.             FRESH;
  360.             }
  361.         if (sc==SB_LINEUP) {
  362.             if (isstart) {
  363.                 long newstart=Red2Sierra(start)-75L*lineinc;
  364.                 if (newstart<0) newstart=0;
  365.                 Red2MSFC(start=Sierra2Red(newstart),&sm,&ss,&sf,&sc);
  366.                 }
  367.             else {
  368.                 long newend=Red2Sierra(end)-75L*lineinc;
  369.                 if (newend<0) newend=0;
  370.                 Red2MSFC(end=Sierra2Red(newend),&em,&es,&ef,&ec);
  371.                 }
  372.             FRESH;
  373.             }
  374.         if (sc==SB_LINEDOWN) {
  375.             if (isstart) {
  376.                 long newstart=Red2Sierra(start)+75L*lineinc;
  377.                 Red2MSFC(start=Sierra2Red(newstart),&sm,&ss,&sf,&sc);
  378.                 }
  379.             else {
  380.                 long newend=Red2Sierra(end)+75L*lineinc;
  381.                 Red2MSFC(end=Sierra2Red(newend),&em,&es,&ef,&ec);
  382.                 }
  383.             FRESH;
  384.             }
  385.         if (sc==SB_PAGEUP) {
  386.             if (isstart) {
  387.                 long newstart=Red2Sierra(start)-75L*pageinc;
  388.                 if (newstart<0) newstart=0;
  389.                 Red2MSFC(start=Sierra2Red(newstart),&sm,&ss,&sf,&sc);
  390.                 }
  391.             else {
  392.                 long newend=Red2Sierra(end)-75L*pageinc;
  393.                 if (newend<0) newend=0;
  394.                 Red2MSFC(end=Sierra2Red(newend),&em,&es,&ef,&ec);
  395.                 }
  396.             FRESH;
  397.             }
  398.         if (sc==SB_PAGEDOWN) {
  399.             if (isstart) {
  400.                 long newstart=Red2Sierra(start)+75L*pageinc;
  401.                 Red2MSFC(start=Sierra2Red(newstart),&sm,&ss,&sf,&sc);
  402.                 }
  403.             else {
  404.                 long newend=Red2Sierra(end)+75L*pageinc;
  405.                 Red2MSFC(end=Sierra2Red(newend),&em,&es,&ef,&ec);
  406.                 }
  407.             FRESH;
  408.             }
  409.         }
  410.  
  411.  
  412.     // Something needs redrawing? Well, redraw them all.
  413.     if (refresh) {
  414.         refresh=0;
  415.         // Never play outside CD tracks - may hang the driver
  416.         if (start<trackloc[0])         Red2MSFC(start=trackloc[0],&sm,&ss,&sf,&sc);
  417.         if (start>trackloc[ntrack]) Red2MSFC(start=trackloc[ntrack],&sm,&ss,&sf,&sc);
  418.         if (end<trackloc[0])         Red2MSFC(end=trackloc[0],&em,&es,&ef,&ec);
  419.         if (end>trackloc[ntrack])     Red2MSFC(end=trackloc[ntrack],&em,&es,&ef,&ec);
  420.         if (start>end)                 Red2MSFC(end=start,&em,&es,&ef,&ec);
  421.         // Update the numerals in the edit controls
  422.         Red2MSFC(start,&sm,&ss,&sf,&sc);
  423.         Red2MSFC(end,&em,&es,&ef,&ec);
  424.  
  425.         SetDlgItemInt(hdlg,SM,sm,0);    SetDlgItemInt(hdlg,SS,ss,0);
  426.         SetDlgItemInt(hdlg,SF,sf,0);
  427.         sprintf(s,"%lu",sc); SetDlgItemText(hdlg,SC,s);
  428.  
  429.         SetDlgItemInt(hdlg,EM,em,0);    SetDlgItemInt(hdlg,ES,es,0);
  430.         SetDlgItemInt(hdlg,EF,ef,0);
  431.         sprintf(s,"%lu",ec); SetDlgItemText(hdlg,EC,s);
  432.         // Update scroll bars
  433.         SetScrollPos(GetDlgItem(hdlg,SBAR),SB_CTL,Red2Sierra(start)/75L,1);
  434.         SetScrollPos(GetDlgItem(hdlg,EBAR),SB_CTL,Red2Sierra(end)/75L,1);
  435.  
  436.         // Set radiobuttons
  437.         if (!bit16) {
  438.             hz44=0; stereo=0;
  439.             EnableWindow(GetDlgItem(hdlg,HZ22),0);
  440.             EnableWindow(GetDlgItem(hdlg,HZ44),0);
  441.             EnableWindow(GetDlgItem(hdlg,MONO),0);
  442.             EnableWindow(GetDlgItem(hdlg,STEREO),0);
  443.             }
  444.         else {
  445.             EnableWindow(GetDlgItem(hdlg,HZ22),1);
  446.             EnableWindow(GetDlgItem(hdlg,HZ44),1);
  447.             EnableWindow(GetDlgItem(hdlg,MONO),1);
  448.             EnableWindow(GetDlgItem(hdlg,STEREO),1);
  449.             }
  450.         CheckRadioButton(hdlg,MONO,STEREO,stereo?STEREO:MONO);
  451.         CheckRadioButton(hdlg,HZ22,HZ44,hz44?HZ44:HZ22);
  452.         CheckRadioButton(hdlg,BIT8,BIT16,bit16?BIT16:BIT8);
  453.         CheckDlgButton(hdlg,AUTOREWIND,autorewind);
  454.         CheckDlgButton(hdlg,AUTOREPEAT,autorepeat);
  455.         if (*fn && access(fn,0)==0)
  456.             EnableWindow(GetDlgItem(hdlg,EDIT),1);
  457.         else
  458.             EnableWindow(GetDlgItem(hdlg,EDIT),0);
  459.         // Calculate projected file size and duration
  460.         dur=Red2Sierra(end)-Red2Sierra(start);
  461.         div=0; if (!stereo) div++; if (!hz44) div++; if (!bit16) div++;
  462.         sprintf(s,"%ld Kbytes",((dur*2352)>>div)/1024);
  463.         SetDlgItemText(hdlg,FSIZE,s);
  464.         sprintf(s,"%s   /  %ld sectors",Sector2MSF(dur),dur);
  465.         SetDlgItemText(hdlg,DUR,s);
  466.         }
  467.  
  468.     // Issue a play command to the CD player
  469.     if (restartsound) {
  470.         restartsound=0;
  471.         StopAudio();
  472.         PlayAudio(start,Red2Sierra(end)-Red2Sierra(start));
  473.         }
  474.     return 0;
  475. }
  476.  
  477.  
  478. // Preferences dialog proc
  479. #pragma argsused
  480. BOOL CALLBACK PrefDlgProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
  481. {
  482.     if (msg==WM_INITDIALOG) {
  483.         SetDialogFont(hdlg,GetStockObject(ANSI_VAR_FONT));
  484.         sprintf(s,"%d audio buffers allocated",nbuf);
  485.         SetDlgItemText(hdlg,BUFRESULT,s);
  486.  
  487.         if (CheckSmartdrv()) {
  488.             if (CheckCDROMCached()) 
  489.                 strcpy(s,"Smartdrv caches the CDROM");
  490.             else
  491.                 strcpy(s,"Smartdrv does not cache the CDROM");
  492.             }
  493.         else 
  494.             strcpy(s,"Smartdrv not installed");
  495.         SetDlgItemText(hdlg,CACHERESULT,s);
  496.  
  497.         SetDlgItemText(hdlg,WAVEDITOR,waveditor);
  498.         }
  499.     if (msg==WM_COMMAND && wp==IDOK) {
  500.         GetDlgItemText(hdlg,WAVEDITOR,waveditor,159);
  501.         WriteProfileString("Dido","WAVeditor",waveditor);
  502.         EndDialog(hdlg,1);
  503.         }
  504.     return 0;
  505. }
  506.  
  507. // Sync error dialog proc
  508. #pragma argsused
  509. BOOL CALLBACK SyncErrDlgProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
  510. {
  511.     if (msg==WM_INITDIALOG) SetDialogFont(hdlg,GetStockObject(ANSI_VAR_FONT));
  512.     if (msg==WM_COMMAND) {
  513.         if (wp==ABOUT) {
  514.             WinHelp(hdlg,HELPFILE,HELP_KEY,"SyncErr");
  515.             EndDialog(hdlg,1);
  516.             }
  517.         if (wp==IDCANCEL) {
  518.             EndDialog(hdlg,1);
  519.             }
  520.         }
  521.     return 0;
  522. }
  523.  
  524. // Memalloc error dialog proc
  525. #pragma argsused
  526. BOOL CALLBACK MemErrDlgProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
  527. {
  528.     if (msg==WM_INITDIALOG) SetDialogFont(hdlg,GetStockObject(ANSI_VAR_FONT));
  529.     if (msg==WM_COMMAND) {
  530.         if (wp==ABOUT) {
  531.             WinHelp(hdlg,HELPFILE,HELP_KEY,"MemErr");
  532.             EndDialog(hdlg,1);
  533.             }
  534.         if (wp==IDCANCEL) {
  535.             EndDialog(hdlg,1);
  536.             }
  537.         }
  538.     return 0;
  539. }
  540.  
  541. // Main dialog proc
  542. #pragma argsused
  543. BOOL CALLBACK MainDlgProc(HWND hdlg, UINT msg, WPARAM wp, LPARAM lp)
  544. {
  545.     int i;
  546.     if (msg==WM_INITDIALOG) {
  547.         SetDialogFont(hdlg,GetStockObject(ANSI_VAR_FONT));
  548.         // Infoheaderts at top 
  549.         SetDlgItemText(hdlg,PLAYINGTIME,Sector2MSF(Red2Sierra(total_time)));
  550.         sprintf(s,"%d",highest-lowest+1);
  551.         SetDlgItemText(hdlg,NRTRACKS,s);
  552.         // Track table
  553.         if (!BuildTrackTable()) mb("Error building the track table");
  554.         SendDlgItemMessage(hdlg,TRACKLIST,LB_RESETCONTENT,0,0);
  555.         for (i=0;i<ntrack;i++) {
  556.             strcpy(t,Red2MSF(trackloc[i]));
  557.             sprintf(s," %2d.   %s     start at %s    %ld sectors",
  558.                         tracknr[i],
  559.                         Sector2MSF(tracklen[i]),
  560.                         Red2MSF(trackloc[i]),
  561.                         tracklen[i]
  562.                         );
  563.             SendDlgItemMessage(hdlg,TRACKLIST,LB_ADDSTRING,0,(LPARAM)s);
  564.             }
  565.         }
  566.     // Some button or track line clicked?
  567.     if (msg==WM_COMMAND) {
  568.         if (HIWORD(lp)==LBN_SELCHANGE) {
  569.             int item;
  570.             if (hlogo) ToggleLogo();
  571.             item=(WORD)SendDlgItemMessage(hdlg,TRACKLIST,LB_GETCURSEL,0,0L);
  572.             if (item!=LB_ERR) {
  573.                 EnableWindow(hdlg,0);
  574.                 if (-1==DialogBoxParam(hinst,"RecDlg",0,RecDlgProc,item))
  575.                     mb("cant create record dialog");
  576.                 EnableWindow(hdlg,1); SetFocus(GetDlgItem(hdlg,TRACKLIST));
  577.                 }
  578.             }
  579.         else {
  580.             if (wp==PREFS) {
  581.                 EnableWindow(hdlg,0);
  582.                 DialogBox(hinst,"PrefDlg",0,PrefDlgProc);
  583.                 EnableWindow(hdlg,1); SetFocus(GetDlgItem(hdlg,TRACKLIST));
  584.                 }
  585.             if (wp==QUIT || wp==EJECT) {StopAudio(); EndDialog(hdlg,wp);}
  586.             if (wp==ABOUT) WinHelp(GetDesktopWindow(),HELPFILE,HELP_CONTENTS,0);
  587.             }
  588.         }
  589.     return 0;
  590. }
  591.  
  592.  
  593. // Mainprogram entry point
  594. #pragma argsused
  595. int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpszCmdLine, int cmdShow)
  596. {
  597.     MSG msg;
  598.     int try,status,result,warn;
  599.     hinst=hInstance;
  600.  
  601.     // Allocate buffers in low memory
  602.     if (!startinterfacing()) {
  603.         DialogBox(hInstance,"MemErrDlg",0,MemErrDlgProc);
  604.         return 0;
  605.         }
  606.     // Is MSCDEX installed? If not, abort.
  607.     if (!CheckMscdex()) {
  608.         mb("MSCDEX not installed");
  609.         return 0;
  610.         }
  611.     // Is there a SMARTDRV cache on the CD? Issue a warning, except when
  612.     // CDROMCachewarning=0 is specified in INI file
  613.     warn=GetProfileInt("Dido","CDROMCachewarning",1);
  614.     if (warn) {
  615.         if (CheckSmartdrv() && CheckCDROMCached()) {
  616.             warn=MessageBox(0,"You have SMARTDRV enabled on your CDROM. On some systems, this can"
  617.                          " cause Dido to lose synchronization during audio copy. If this happens"
  618.                          " to you, try to disable CDROM caching before you start Windows.      "
  619.                          "Would you like to skip this warning in the future?","Warning",MB_YESNO);
  620.             if (warn==IDYES) WriteProfileString("Dido","CDROMCachewarning","0");
  621.             }
  622.         }
  623.  
  624.     // Display logo
  625.     RegisterLogo(hinst);
  626.     ToggleLogo();
  627.     // Give some time slices so the logo will display
  628.     while (PeekMessage(&msg,0,0,0,PM_REMOVE)) {
  629.         TranslateMessage(&msg);
  630.            DispatchMessage(&msg);
  631.         }
  632.     // Wait a bit
  633.     delay(CLK_TCK*2);
  634. Rescan:
  635.     // Get global information about CD
  636.     status=GetDiskInfo(); try=0;
  637.     while (status!=0x0100) {
  638.         delay(CLK_TCK);
  639.         if (++try>=3) {
  640.             if (MessageBox(0,"Insert an audio CD in the drive","CDROM is busy",MB_RETRYCANCEL)==IDCANCEL) {
  641.                 // ieks... terminate
  642.                 stopinterfacing();
  643.                 return 0;
  644.                 }
  645.             try=0;
  646.             }
  647.         status=GetDiskInfo();
  648.         }
  649.     // Do the interaction
  650.     GetProfileString("Dido","WAVeditor",waveditor,waveditor,159);
  651.     result=DialogBox(hinst,"MainDlg",0,MainDlgProc);
  652.     if (result==EJECT) {
  653.         // Try MCI, for a change
  654.         mciSendString("SET CDAUDIO DOOR OPEN", NULL, 0, NULL ); // This one works OK on my drive...
  655.         MessageBox(0,"You can change the CD now","Dido",MB_OK);
  656.         mciSendString("SET CDAUDIO DOOR CLOSED", NULL, 0, NULL ); // This does NOT work on my drive...
  657.         delay(6*CLK_TCK);
  658.         goto Rescan;
  659.         }
  660.     WinHelp(GetDesktopWindow(),HELPFILE,HELP_QUIT,0);
  661.     // Free up
  662.     stopinterfacing();
  663.     if (hlogo) ToggleLogo();
  664.     return 0;
  665. }
  666.