home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 24 / CD_ASCQ_24_0995.iso / vrac / visvideo.zip / WPLAYER.C_ / WPLAYER.bin
Text File  |  1994-08-31  |  68KB  |  2,174 lines

  1. /*
  2.  * Program     :  WPLAYER.EXE
  3.  * Module      :  WPLAYER.C
  4.  * Description :  WPLAYER provides user playback Video CD, CDI-Movie and the
  5.  *                other MPEG files.
  6.  *
  7.  *                Function and Hot Ket supported --
  8.  *
  9.  *                Ctrl+Alt+Q
  10.  *                   Minimize       The MPEG Master will become an icon, at
  11.  *                                  this time, all of the Hot-Key is disabled.
  12.  *                   Always On Top  The MPEG Master control panel will be
  13.  *                                  bring to top above all the windows.
  14.  *                   Exit           The MPEG Master will be shutdown.
  15.  *
  16.  *                Ctrl+Alt+F
  17.  *                   Fast Forward.
  18.  *
  19.  *                Ctrl+Alt+L
  20.  *                   Slow Forward.
  21.  *
  22.  *                Ctrl+Alt+P
  23.  *                   Normal Play.
  24.  *
  25.  *                Ctrl+Alt+U
  26.  *                   Pause.
  27.  *
  28.  *                Ctrl+Alt+M
  29.  *                   Mute on/off audio.
  30.  *
  31.  *                Ctrl+Alt+N
  32.  *                   Skip forward 2 minutes during CDI-FMV disc playing.
  33.  *
  34.  *                Ctrl+Alt+B
  35.  *                   Skip backward 2 minutes during CDI-FMV disc playing.
  36.  *
  37.  *                Ctrl+Alt+S
  38.  *                   Stop.
  39.  *
  40.  *                Ctrl+Alt+UP Arrow key
  41.  *                   Increment Volume, Treble or Bass depends on the activate
  42.  *                   button that user selected.
  43.  *
  44.  *                Ctrl+Alt+DOWN Arrow key
  45.  *                   Decrement Volume, Treble or Bass depends on the activate
  46.  *                   button that user selected.
  47.  *
  48.  *                Ctrl+Alt+LEFT (RIGHT) Arrow key
  49.  *                   Balance volume.
  50.  *
  51.  *                Ctrl+Alt+SPACE BAR
  52.  *                   Toggle VGA/VIDEO output to VGA monitor.
  53.  *
  54.  *                Ctrl+Alt+[F2]
  55.  *                   Adjust display screen left  to 1 pixel.
  56.  *
  57.  *                Ctrl+Alt+[F3]
  58.  *                   Adjust display screen up to 1 line.
  59.  *
  60.  *                Ctrl+Alt+[F4]
  61.  *                   Adjust display screen right to 1 pixel.
  62.  *
  63.  *                Ctrl+Alt+[F5]
  64.  *                   Adjust display screen down to 1 line.
  65.  *
  66.  * Note        :  If an MCI driver activated that provided by Visionetics,
  67.  *                the WPLAYER will perform audio control function and toggle
  68.  *                VGA/VIDEO to VGA monitor only.
  69.  *
  70.  * Date:       :  August 19, 1994.
  71.  * Author      :  Visionetics Int'l / Morris Lu.
  72.  *
  73.  * Copyright (C) Visionetics Int'l, Inc. 1994.
  74.  */
  75. #include <windows.h>
  76. #include <stdio.h>
  77. #include <stdlib.h>
  78. #include <string.h>
  79. #include <math.h>
  80. #include <conio.h>
  81. #include <commdlg.h>
  82. #include "mpeg.h"
  83. #include "wplayer.h"
  84. #include "music.h"
  85. #include "keyhook.h"
  86.  
  87.  
  88. /*
  89.  * Define Hot-Key table. (ASCII/Scan code)
  90.  */
  91. #define Key_Q  0x5110
  92. #define Key_q  0x7110
  93. #define Key_F  0x4621
  94. #define Key_f  0x6621
  95. #define Key_L  0x4c26
  96. #define Key_l  0x6c26
  97. #define Key_P  0x5019
  98. #define Key_p  0x7019
  99. #define Key_U  0x5516
  100. #define Key_u  0x7516
  101. #define Key_M  0x4d32
  102. #define Key_m  0x6d32
  103. #define Key_S  0x531f
  104. #define Key_s  0x731f
  105. #define Key_N  0x4e31
  106. #define Key_n  0x6e31
  107. #define Key_B  0x4230
  108. #define Key_b  0x6230
  109. #define Key_sp 0x2039
  110. #define Key_up 0x2648
  111. #define Key_dn 0x2850
  112. #define Key_F2 0x713c
  113. #define Key_F3 0x723d
  114. #define Key_F4 0x733e
  115. #define Key_F5 0x743f
  116.  
  117. KeyTable keys = {
  118.    25,            // no of key defined
  119.    {Key_q,Key_Q,  // power off, quit application
  120.     Key_f,Key_F,  // fast forward
  121.     Key_l,Key_L,  // slow forward
  122.     Key_p,Key_P,  // normal play
  123.     Key_u,Key_U,  // pause
  124.     Key_m,Key_M,  // mute on/off toggle
  125.     Key_s,Key_S,  // stop
  126.     Key_n,Key_N,  // skip forward 2 minutes
  127.     Key_b,Key_B,  // skip backward 2 minutes
  128.     Key_up,       // increment volume
  129.     Key_dn,       // decrement volume
  130.     Key_sp,       // toggle VGA/MPEG output to VGA monitor
  131.     Key_F2,       // adjust display screen left  to 1 pixel
  132.     Key_F3,       // adjust display screen up    to 1 line
  133.     Key_F4,       // adjust display screen right to 1 pixel
  134.     Key_F5        // adjust display screen down  to 1 line
  135.    },
  136.  
  137.    // the relative message
  138.    {IDM_POWER,IDM_POWER,
  139.     IDM_FASTMOTION,IDM_FASTMOTION,
  140.     IDM_SLOWMOTION,IDM_SLOWMOTION,
  141.     IDM_PLAY,IDM_PLAY,
  142.     IDM_PAUSE,IDM_PAUSE,
  143.     IDM_MUTE,IDM_MUTE,
  144.     IDM_STOP,IDM_STOP,
  145.     IDM_NEXT_SONG,IDM_NEXT_SONG,
  146.     IDM_PRE_SONG,IDM_PRE_SONG,
  147.     IDM_UP,
  148.     IDM_DOWN,
  149.     IDM_SPACE,
  150.     IDM_SCREEN_LF,
  151.     IDM_SCREEN_UP,
  152.     IDM_SCREEN_RT,
  153.     IDM_SCREEN_DN
  154.    },
  155.    IDM_OtherKeyPressed  // message for undefined keys
  156. };
  157.  
  158.  
  159. /*
  160. ** Variable Define for Global Variable
  161. */
  162. static char    MesgStr[120];
  163. static BOOL    alwaysOnTop = FALSE;
  164. static BOOL    showVer = FALSE;
  165. static BOOL    showOnVGA = FALSE;
  166. static HMENU   hSysMenu;
  167. static BOOL    MPEGExist = FALSE;
  168. static HWND    hPanelWnd;        // Window main control panel handles
  169. static HANDLE  hAccel;           // Handle to accelerator table
  170. static HANDLE  hInst;
  171. static RECT    rcWindow;         // Current Window rectangle
  172. static RECT    rcOutline;
  173. static POINT   ptStart;          // When LBUTTON down coordinate
  174. static POINT   ptStop;           // Wneh LBUTTON up coordinate
  175. static char    szHelpFileName[EXE_NAME_MAX_SIZE+1]; // Help file name
  176. static char    szTFileName[MAXFILENAME];
  177. static char    szFileTitle[MAXFILENAME];
  178. static int     nMpegFiles;
  179. static int     nFileIndex;
  180. static int     seek = NORMAL;
  181.  
  182. static HBRUSH  hCurveBackgnd;
  183. static HBRUSH  hCurveForegnd;
  184. static BOOL    fMove  = FALSE;   // Moving the control panel
  185. static BOOL    mscdex = TRUE;    // suppose MSCDEX been installed
  186. static BOOL    cdrom  = TRUE;    // suppose CD-ROM been installed
  187. static int     selectCD;
  188. static int     cddrv_no     = 0;
  189. static int     sync         = 1;    // 0 for scsi bus, 1 for at bus
  190. static int     cdi          = 0;    // 1 for Philip CD-I, 0 otherwise
  191. static BOOL    pause        = FALSE;
  192. static BOOL    playing      = FALSE;
  193. static BOOL    theFirstPlay = TRUE;
  194. static int     motion_old;
  195. static int     motion_flg   = NPF;     // normal play
  196. static BOOL    load         = FALSE;   // not load yet
  197. static int     idTimer      = 0;
  198. static int     track_no     = 1;       // the first song
  199. static int     preTrack     = 0;       // previous song
  200. static int     preFile      = 0;       // previous file
  201. static BOOL    demostop     = FALSE;
  202. static BOOL    fMute        = FALSE;   // audio status - mute, audio
  203. static BOOL    songGray = TRUE;        // when bitstream is not Karaoke
  204. static int     cdType;                 // ALL, KARAOKE, CDIFMV
  205. static int     prvCDType;
  206. static int     defCDType;  // according to INI
  207. static BOOL    repeat = FALSE;
  208. static int     nSongs;
  209. static int     ActiveItem   = IDM_STOP;
  210. static int     OldActiveItem;
  211. static int     curWlevel;
  212. static int     curMsg[80];
  213. static HBITMAP hParentBmp;
  214. static HBITMAP hGrayBmp;
  215. static HBITMAP hGrayPlay;
  216. static HBITMAP hPreOn;
  217. static HBITMAP hPreOff;
  218. static HBITMAP hNxtOn;
  219. static HBITMAP hNxtOff;
  220. static HCURSOR hPrevCursor;
  221. static HDC     hScreenDC;
  222. static HFONT   hCurrentFont;
  223. static BOOL    theFirstFMV = TRUE;
  224. static int     startTimeSec;        // strat play time in second for CDIFMV
  225. static int     skipTimeSec;         // skip play time in second for CDIFMV
  226. static int     discTime;            // time in second of the CDIFMV disc
  227.  
  228. static int dspMode = VGA;
  229. static BOOL TimerExist = FALSE;
  230.  
  231. // Volume control
  232. static int defVolL     = 0xfc;      // default left volume, 0db
  233. static int defVolR     = 0xfc;      // default right volume, 0db
  234. static int defBass     = 0xf6;      // default bass, 0db
  235. static int defTreble   = 0xf6;      // default treble, 0db
  236.  
  237. static int nVolL;    // current left volume
  238. static int nVolR;    // current right volume
  239. static int nBass;    // current bass
  240. static int nTreble;  // current treble
  241. static int nStereo;  // current stereo
  242. static int idStereo; // current stereo id
  243. static int idVol;    // current volume id
  244.  
  245. static int minVol  = 0xda;
  246. static int maxVol  = 0xfe;
  247. static int minBass = 0xf2;
  248. static int maxBass = 0xfb;
  249. static int minTre  = 0xf2;
  250. static int maxTre  = 0xfa;
  251.  
  252. // Global variables for Audio display curve
  253. #define UP     (BOOL)TRUE     // curve upward
  254. #define DOWN   (BOOL)FALSE    // curve downward
  255. #define LEFT   (BOOL)TRUE     // left curve
  256. #define RIGHT  (BOOL)FALSE    // right curve
  257.  
  258. static int curVolLY;
  259. static int curVolRY;
  260. static int curTreLY;
  261. static int curTreRY;
  262. static int curBassLY;
  263. static int curBassRY;
  264. static BOOL done = FALSE;
  265. static ATOM mainAtom;
  266. static BOOL MPEGMCIExist = FALSE;
  267.  
  268. static TIMERPROC lpfnTimerProc;
  269. static WNDPROC   butOrgPowerProc;
  270. static HMENU     hPowerMenu = NULL;
  271. static BOOL      keyHookOn = FALSE;
  272.  
  273.  
  274. /* Function Declaration */
  275. int  PASCAL WinMain (HANDLE,HANDLE,LPSTR,int);
  276. BOOL InitApplication (HANDLE);
  277. BOOL InitInstance (HANDLE,int);
  278. long FAR PASCAL PanelWndProc (HWND,UINT,WPARAM,LPARAM);
  279. int  FAR PASCAL SelectDiscDlg (HWND,UINT,WPARAM,LPARAM);
  280. void dspCurve (int,BOOL,int,BOOL);
  281. int  MpegLoader (char *);
  282. int  initMpeg (LPSTR);
  283. int  strtoi (LPSTR);
  284. void VideoVGASwitcher (int);
  285. void getINIStr (LPSTR);
  286. UINT getINIint (LPSTR);
  287. void putINIStr (LPSTR);
  288. void saveCfg (void);
  289. void OutlineRect (HDC,RECT *);
  290. void DrawButton (int,BOOL);
  291. void MakeHelpPathName (char *);
  292. void set_to_play (void);
  293. void WriteText (int,LPSTR);
  294. int  loadTrack (void);
  295. int  selectFile (char *,char *,int);
  296. BOOL processing (void);
  297. void FAR PASCAL TimerProc (HWND,UINT,WORD,DWORD);
  298. LRESULT FAR PASCAL butPowerProc (HWND,UINT,WPARAM,LPARAM);
  299. void FreeTimer (void);
  300.  
  301.  
  302. /************************************************************************
  303. * WinMain(HANDLE,HANDLE,LPSTR,int)                                      *
  304. *                                                                       *
  305. * Procedure to accept Windows message from kernal and dispatch          *
  306. *************************************************************************/
  307. int PASCAL WinMain (HANDLE hInstance,HANDLE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
  308. {
  309.    MSG msg;
  310.    int rtn;
  311.  
  312.    if (GlobalFindAtom ((LPCSTR)"MPEGMasterMCI"))
  313.       MPEGMCIExist = TRUE;
  314.  
  315.    // check enhance mode ?
  316.    if (!(GetWinFlags () & WF_ENHANCED)){
  317.       wsprintf (MesgStr,"%s requires Windows to be running in the 386 enhanced mode !!",ProductName);
  318.       MessageBox (NULL,MesgStr,ProductName,MB_ICONSTOP);
  319.       return (FALSE);
  320.    }
  321.  
  322.    // Try to initialize the MPEG system. If error, just exit.
  323.    if (rtn = initMpeg (lpCmdLine)){
  324.       if (rtn == EVXD){
  325.          MessageBox (NULL,"VXD not installed",ProductName,MB_ICONSTOP);
  326.          return (FALSE);
  327.       }else{
  328.          wsprintf (MesgStr,"%s is not ready !!",ProductName);
  329.          MessageBox (NULL,MesgStr,ProductName,MB_ICONSTOP);
  330.          return (FALSE);
  331.       }
  332.    }
  333.  
  334.    if (hPrevInstance){
  335.       ShowWindow (hPanelWnd,SW_SHOWNORMAL);
  336.       return (FALSE);
  337.    }
  338.  
  339.    if (!InitApplication (hInstance))
  340.       return (FALSE);
  341.  
  342.    if (!InitInstance (hInstance,nCmdShow))
  343.       return (FALSE);
  344.  
  345.    if (!MPEGMCIExist)
  346.       mainAtom = GlobalAddAtom ((LPCSTR)"MPEGMasterMAIN");
  347.  
  348.    SetHook (hPanelWnd,(KeyTable far *)&keys);    // Set the Keyboard Hook
  349.    keyHookOn = TRUE;
  350.  
  351.    while (GetMessage (&msg,NULL,NULL,NULL)){
  352.       if (!TranslateAccelerator (msg.hwnd,hAccel,&msg)){
  353.          TranslateMessage( &msg );
  354.          DispatchMessage( &msg );
  355.       }
  356.    }
  357.  
  358.    if (keyHookOn)
  359.       RemoveHook ();          // Remove the Keyboard Hook
  360.  
  361.    if (!MPEGMCIExist)
  362.       GlobalDeleteAtom (mainAtom);
  363.  
  364.    return (msg.wParam);
  365. }/* WinMain */
  366.  
  367. /************************************************************************
  368. * InitApplication(HANDLE)                                               *
  369. *                                                                       *
  370. * Procedure to register window classes for the video and control panel  *
  371. * windows.                                                              *
  372. *************************************************************************/
  373. BOOL InitApplication (hInstance)
  374. HANDLE hInstance;
  375. {
  376.    WNDCLASS  wc;
  377.  
  378.    /*    Register the control panel window class. */
  379.    wc.style = CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW;
  380.    wc.lpfnWndProc = (WNDPROC)PanelWndProc;
  381.    wc.cbClsExtra = 0;
  382.    wc.cbWndExtra = 0;
  383.    wc.hInstance = hInstance;
  384.    wc.hIcon = LoadIcon (hInstance,MAKEINTRESOURCE (IDS_PANEL_ICON));
  385.    wc.hCursor = LoadCursor (NULL,IDC_ARROW);
  386.    wc.hbrBackground = NULL;
  387.    wc.lpszMenuName =  NULL;
  388.    wc.lpszClassName = IDS_PANEL_CLASS;
  389.  
  390.    return (RegisterClass (&wc));
  391. }/* InitApplication */
  392.  
  393.  
  394. /************************************************************************
  395. * InitInstance(HANDLE,int)                                              *
  396. *                                                                       *
  397. * Saves instance handle read initialization file and creates the video  *
  398. * and panel windows.                                                    *
  399. *************************************************************************/
  400. BOOL InitInstance (hInstance,nCmdShow)
  401. HANDLE hInstance;
  402. int nCmdShow;
  403. {
  404.    int i;
  405.  
  406.    hInst = hInstance;
  407.    hPanelWnd = CreateWindow (IDS_PANEL_CLASS,IDS_PANEL_TITLE,
  408.                              WS_POPUP,
  409.                              PANEL_X,PANEL_Y,
  410.                              PANEL_WIDTH,PANEL_HEIGHT,
  411.                              NULL,NULL,hInstance,NULL
  412.                             );
  413.  
  414.    if( !hPanelWnd )
  415.       return (FALSE);
  416.  
  417.    ShowWindow (hPanelWnd,nCmdShow);
  418.    UpdateWindow (hPanelWnd);
  419.  
  420.    /* Create the button controls and assign them IDs. */
  421.    for (i = 0;i < PANEL_BUTTONS;i++){
  422.       Button[i].hWnd = CreateWindow ("Button",NULL,WS_CHILD |
  423.                                      BS_OWNERDRAW | WS_VISIBLE,
  424.                                      Button[i].pos.x,
  425.                                      Button[i].pos.y,
  426.                                      Button[i].bdWidth,
  427.                                      Button[i].bdHeight,
  428.                                      hPanelWnd,Button[i].msg,
  429.                                      hInstance,NULL);
  430.    }
  431.  
  432.  
  433.    // Subclassing the button control.
  434.    butOrgPowerProc = (WNDPROC)SetWindowLong (Button[iPOWER].hWnd,GWL_WNDPROC,
  435.                                              (LONG)(WNDPROC)butPowerProc);
  436.  
  437.  
  438.    // Set init state of audio control
  439.    DrawButton (idStereo,ON);
  440.    idVol = iVOLUME;
  441.    DrawButton (idVol,ON);
  442.  
  443.    /* fill in non-variant fields of OPENFILENAME struct. */
  444.    ofn.lStructSize       = sizeof (OPENFILENAME);
  445.    ofn.hwndOwner         = hPanelWnd;
  446.    ofn.lpstrFilter       = szFilterSpec;
  447.    ofn.lpstrCustomFilter = NULL;
  448.    ofn.nMaxCustFilter    = 0;
  449.    ofn.nFilterIndex      = 1;
  450.    ofn.lpstrFile         = szTFileName;
  451.    ofn.nMaxFile          = MAXFILENAME;
  452.    ofn.lpstrInitialDir   = NULL;
  453.    ofn.lpstrFileTitle    = szFileTitle;
  454.    ofn.nMaxFileTitle     = MAXFILENAME;
  455.    ofn.lpstrTitle        = NULL;
  456.    ofn.lpstrDefExt       = "MPG";
  457.    ofn.Flags             = OFN_ALLOWMULTISELECT;
  458.  
  459.    MakeHelpPathName (szHelpFileName);
  460.  
  461.    return (TRUE);
  462. }/* InitInstance */
  463.  
  464.  
  465. /*
  466.  * butPowerProc subclasses the button control in the client area.
  467.  * It intercepts all incoming messages and monitor user action.  It
  468.  * PostMessage() to the parent window to invoke a floating popup menu.
  469.  */
  470. LRESULT FAR PASCAL butPowerProc (hWnd,Message,wParam,lParam)
  471. HWND   hWnd;
  472. UINT   Message;
  473. WPARAM wParam;
  474. LPARAM lParam;
  475. {
  476.    WORD xPos,yPos;
  477.    static BOOL fInBox;
  478.   
  479.    switch (Message){
  480.       // Set the boolean flag for the floating popup menu.
  481.       case WM_LBUTTONDOWN:
  482.            fInBox = TRUE;
  483.            break;
  484.         
  485.       // Trace whether cursor is moving outside.
  486.       case WM_MOUSEMOVE:
  487.            xPos = LOWORD (lParam);
  488.            yPos = HIWORD (lParam);
  489.            if (xPos < POWER_COL || xPos > POWER_COL + POWER_WIDTH ||
  490.              yPos < POWER_ROW || yPos > POWER_ROW + POWER_HEIGHT)
  491.               fInBox = FALSE;
  492.               break;
  493.     
  494.       // Triggle occurs!
  495.       case WM_LBUTTONUP:
  496.            if (fInBox){
  497.               PostMessage (GetParent(hWnd),WM_COMMAND,IDM_POWER,0L);
  498.               fInBox = FALSE;
  499.            }
  500.          break;
  501.    }
  502.   
  503.    // Pass messages to original window procedure and return its result.
  504.    return (CallWindowProc ((FARPROC)butOrgPowerProc,hWnd,Message,wParam,lParam));
  505. }/* butPwoerProc */
  506.  
  507.  
  508. /************************************************************************
  509. * PanelWndProc(HWND,UINT,WPARAM,LPARAM)                                 *
  510. *                                                                       *
  511. * Main panel process procedure to handle each button condition          *
  512. *************************************************************************/
  513. long FAR PASCAL PanelWndProc (hWnd,message,wParam,lParam)
  514. HWND hWnd;
  515. UINT message;
  516. WPARAM wParam;
  517. LPARAM lParam;
  518. {
  519.    LPDRAWITEMSTRUCT lpdis;
  520.    PAINTSTRUCT      ps;
  521.    FARPROC          lpSelector;
  522.    char             s[80];
  523.    static char      oldMsg[80];
  524.    HDC              hDC,hMemoryDC;
  525.    int              i,rtn;
  526.    BOOL             on,off;
  527.    HMENU            hSubMenu;
  528.    POINT            sPt;
  529.                    
  530.    switch (message){
  531.       case WM_COMMAND:
  532.          if (MPEGMCIExist && ((wParam == IDM_HELP) ||
  533.              (wParam >= IDM_LOADER && wParam <= IDM_REPEAT)))
  534.             break;
  535.          switch (wParam){
  536.             case IDM_HELP:
  537.                if (dspMode == VIDEO)
  538.                   break;
  539.  
  540.                WinHelp (hWnd,szHelpFileName,HELP_INDEX,0L);
  541.                break;
  542.  
  543.             /*
  544.              * Video Control
  545.              */
  546.             case IDM_POWER:
  547.                if (dspMode == VIDEO)
  548.                   break;
  549.  
  550.                hSubMenu = GetSubMenu (hPowerMenu,0);
  551.                sPt.x = POWER_COL;
  552.                sPt.y = POWER_ROW + POWER_HEIGHT;
  553.                ClientToScreen (hWnd,(POINT FAR *)&sPt);
  554.  
  555.                // This API does the magic.
  556.                TrackPopupMenu (hSubMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
  557.                                sPt.x,sPt.y,0,hWnd,NULL);
  558.  
  559.                 break;
  560.             
  561.             // Messages from the floating popup menu.
  562.             case IDM_ICON:
  563.                ShowWindow (hPanelWnd,SW_MINIMIZE);
  564.                RemoveHook ();          // Remove the Keyboard Hook
  565.                keyHookOn = FALSE;
  566.                break;
  567.             case IDM_TOP:
  568.                alwaysOnTop = !alwaysOnTop;
  569.                if (alwaysOnTop){
  570.                   SetWindowPos (hPanelWnd,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE |
  571.                                 SWP_NOMOVE | SWP_SHOWWINDOW);
  572.                   CheckMenuItem (hPowerMenu,IDM_TOP,MF_CHECKED);
  573.                }else{
  574.                   SetWindowPos (hPanelWnd,HWND_NOTOPMOST,0,0,0,0,
  575.                                 SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
  576.                   CheckMenuItem (hPowerMenu,IDM_TOP,MF_UNCHECKED);
  577.                }
  578.                break;
  579.             case IDM_EXIT:
  580.                DestroyWindow (hWnd);
  581.                break;
  582.             case IDM_LOADER:
  583.                if (dspMode == VIDEO)
  584.                   break;
  585.  
  586.                if (playing){
  587.                   WriteText (W1,(LPSTR)"Stop First");
  588.                   DrawButton (iLOAD,OFF);
  589.                   break;
  590.                }
  591.  
  592.                if (lParam != 0xbbL){
  593.                   prvCDType = cdType;
  594.                   lpSelector = MakeProcInstance (SelectDiscDlg,hInst);
  595.                   rtn = DialogBox (hInst,"SelectDiscDlg",hWnd,lpSelector);
  596.                   FreeProcInstance (lpSelector);
  597.                
  598.                   if (rtn <= 0)
  599.                      return (FALSE);
  600.  
  601.                   if (cdType == ALL){
  602.                      szTFileName[0] = '\0';
  603.                      if (!GetOpenFileName ((LPOPENFILENAME)&ofn)){
  604.                         cdType = prvCDType;
  605.                         return (FALSE);
  606.                      }
  607.                      nMpegFiles = selectFile (szTFileName,(char *)NULL,0);
  608.                      nFileIndex = 1;
  609.                   }
  610.                }
  611.  
  612.                prvCDType = cdType;
  613.  
  614.                if ((cdType == KARAOKE || cdType == CDIFMV)){
  615.                   if (!mscdex){
  616.                      WriteText (W1,(LPSTR)"mscdex not installed");
  617.                      load = FALSE;
  618.                      break;
  619.                   }else if (!cdrom){
  620.                      WriteText (W1,(LPSTR)"CD-ROM not installed");
  621.                      load = FALSE;
  622.                      break;
  623.                   }
  624.                }
  625.  
  626.                songGray = TRUE;
  627.                WriteText (W0,(LPSTR)"Waiting...");
  628.                if (cdType == KARAOKE || cdType == CDIFMV){      // Karaoke CD, can specify song#
  629.                   Button[iPRE].hOff = hPreOff;
  630.                   Button[iPRE].hOn = hPreOn;
  631.                   DrawButton (iPRE,OFF);
  632.  
  633.                   Button[iNEXT].hOff = hNxtOff;
  634.                   Button[iNEXT].hOn = hNxtOn;
  635.                   DrawButton (iNEXT,OFF);
  636.                   songGray = FALSE;
  637.                }else{
  638.                   Button[iPRE].hOff = hGrayBmp;
  639.                   Button[iPRE].hOn = hGrayBmp;
  640.                   DrawButton (iPRE,OFF);
  641.  
  642.                   Button[iNEXT].hOff = hGrayBmp;
  643.                   Button[iNEXT].hOn = hGrayBmp;
  644.                   DrawButton (iNEXT,OFF);
  645.                }
  646.  
  647.                hPrevCursor = SetCursor (LoadCursor (NULL,IDC_WAIT));
  648.                if (cdType == CDIFMV){  // CDI-Movie, 1 track/disc
  649.                   cdi = 1;
  650.                   if (!(discTime = WMpegGetTrackTime (cddrv_no,CDIFMV,(LPSTR)NULL))){
  651.                      MessageBox (hWnd,"Check CDI-FMV disc error !!",
  652.                                  ProductName,MB_ICONSTOP);
  653.                      break;
  654.                   }
  655.                }else
  656.                   cdi = 0;
  657.  
  658.                if (cdType == KARAOKE){
  659.                   nSongs = WMpegGetCDSongs ((WORD)cddrv_no);
  660.                   if (!nSongs){
  661.                      load = FALSE;
  662.                      WriteText (W1,(LPSTR)"Wrong Karaoke CD");
  663.                      break;
  664.                   }
  665.                }
  666.                SetCursor (hPrevCursor);
  667.  
  668.                track_no = 1;
  669.  
  670.                if (lParam != 0xbbL)
  671.                   WriteText (W0,(LPSTR)"Press PLAY to Start");
  672.  
  673.                load = TRUE;
  674.                break;
  675.             case IDM_STEP:
  676.                if (!load){
  677.                   WriteText (W1,(LPSTR)"Load First");
  678.                   DrawButton (iSTEP,OFF);
  679.                   break;
  680.                }
  681.  
  682.                if (ActiveItem != IDM_STEP)
  683.                   DrawButton (ActiveItem-BUTTON_START_ID,OFF);
  684.  
  685.                ActiveItem = IDM_STEP;
  686.                WriteText (W0,(LPSTR)"Step");
  687.  
  688.                pause = FALSE;
  689.                motion_flg = SFF;
  690.                Mute (TRUE);
  691.                WMpegCommand (SFF);
  692.                if (!playing)
  693.                   set_to_play ();
  694.                break;
  695.             case IDM_SLOWMOTION:
  696.                if (!load){
  697.                   WriteText (W1,(LPSTR)"Load First");
  698.                   DrawButton (iSLOW,OFF);
  699.                   break;
  700.                }
  701.  
  702.                DrawButton (ActiveItem-BUTTON_START_ID,OFF);
  703.                ActiveItem = IDM_SLOWMOTION;
  704.                DrawButton (iSLOW,ON);
  705.                WriteText (W0,(LPSTR)"Slow Forward");
  706.  
  707.                if (!processing ())
  708.                   break;
  709.  
  710.                pause = FALSE;
  711.                motion_flg = SMF;
  712.                Mute (TRUE);
  713.                WMpegCommand (SMF);
  714.                if (!playing)
  715.                   set_to_play ();
  716.                break;
  717.             case IDM_STOP:
  718.                // switch to console output
  719.                if (dspMode == VIDEO)
  720.                   VideoVGASwitcher (VGA);
  721.  
  722.                if (ActiveItem != IDM_STOP)
  723.                   DrawButton (ActiveItem-BUTTON_START_ID,OFF);
  724.  
  725.                ActiveItem = IDM_STOP;
  726.                WriteText (W0,(LPSTR)"Stop");
  727.  
  728.                FreeTimer ();
  729.                WMpegCommand (STP);
  730.                playing  = FALSE;
  731.                demostop = TRUE;
  732.                preTrack = 0;
  733.                preFile = 0;
  734.                theFirstFMV = TRUE;
  735.                done = TRUE;
  736.                break;
  737.             case IDM_PLAY:
  738.                if (!load){
  739.                   cdType = prvCDType;
  740.                   SendMessage (hWnd,WM_COMMAND,IDM_LOADER,0xbbL);
  741.                   if (!load)
  742.                      break;
  743.                }
  744.  
  745.                if (!processing ())
  746.                   break;
  747.  
  748.                pause = FALSE;
  749.                if (ActiveItem != IDM_PLAY)
  750.                   DrawButton (ActiveItem-BUTTON_START_ID,OFF);
  751.                DrawButton (iPLAY,ON);
  752.  
  753.                ActiveItem = IDM_PLAY;
  754.                motion_flg = NPF;
  755.                Mute ((BYTE)fMute);
  756.                WMpegCommand (NPF);
  757.  
  758.                if (cdType == KARAOKE){
  759.                   wsprintf (s,"Track %d",track_no);
  760.                   WriteText (W0,(LPSTR)s);
  761.                }else
  762.                   WriteText (W0,(LPSTR)"Play");
  763.  
  764.                if (!playing)
  765.                   set_to_play ();
  766.  
  767.                // Volume setting
  768.                if (theFirstPlay){
  769.                   Mute ((BYTE)fMute);
  770.                   VolumeLeft ((BYTE)nVolL);
  771.                   VolumeRight ((BYTE)nVolR);
  772.                   Bass ((BYTE)nBass);
  773.                   Treble ((BYTE)nTreble);
  774.                   Stereo ((BYTE)nStereo);
  775.                   theFirstPlay = FALSE;
  776.                   if (showOnVGA)
  777.                      VideoVGASwitcher (VIDEO);
  778.                }
  779.                break;
  780.             case IDM_PAUSE:
  781.                if (!load){
  782.                   WriteText (W1,(LPSTR)"Load First");
  783.                   DrawButton (iPAUSE,OFF);
  784.                   break;
  785.                }
  786.  
  787.                if (ActiveItem != IDM_PAUSE){
  788.                   DrawButton (ActiveItem-BUTTON_START_ID,OFF);
  789.                   Button[iPAUSE].bdState = ON;
  790.                   OldActiveItem = ActiveItem;
  791.                   ActiveItem = IDM_PAUSE;
  792.                   lstrcpy (oldMsg,(LPSTR)curMsg);
  793.                   WriteText (W0,(LPSTR)"Pause");
  794.                }else{
  795.                   Button[iPAUSE].bdState = OFF;
  796.                   ActiveItem = OldActiveItem;
  797.                   DrawButton (ActiveItem-BUTTON_START_ID,ON);
  798.                   WriteText (W0,(LPSTR)oldMsg);
  799.                }
  800.  
  801.                pause = !pause;
  802.  
  803.                if (pause){
  804.                   WMpegCommand (PAU);
  805.                   motion_old = motion_flg;
  806.                   motion_flg = PAU;
  807.                }else{
  808.                   motion_flg = motion_old;
  809.                   if (motion_flg != NPF)
  810.                      WMpegCommand (motion_flg);
  811.                   else
  812.                      WMpegCommand (NPF);
  813.                }
  814.                break;
  815.             case IDM_FASTMOTION:
  816.                if (!load){
  817.                   WriteText (W1,(LPSTR)"Load First");
  818.                   DrawButton (iFAST,OFF);
  819.                   break;
  820.                }
  821.  
  822.                if (ActiveItem != IDM_FASTMOTION)
  823.                   DrawButton (ActiveItem-BUTTON_START_ID,OFF);
  824.  
  825.                ActiveItem = IDM_FASTMOTION;
  826.                DrawButton (iFAST,ON);
  827.                WriteText (W0,(LPSTR)"Fast Forward");
  828.  
  829.                if (!processing ())
  830.                   break;
  831.  
  832.                pause = FALSE;
  833.                motion_flg = FMF;
  834.                Mute (TRUE);
  835.                WMpegCommand (FMF);
  836.                if (!playing)
  837.                   set_to_play ();
  838.                break;
  839.             case IDM_PRE_SONG:
  840.                if (cdType == ALL)
  841.                   break;
  842.  
  843.                if ((cdType == KARAOKE) && (songGray || dspMode == VIDEO))
  844.                   break;
  845.  
  846.                DrawButton (iPRE,OFF);
  847.  
  848.                if (cdType == KARAOKE && playing){
  849.                   WriteText (W1,(LPSTR)"Stop First");
  850.                   DrawButton (iPRE,OFF);
  851.                   break;
  852.                }
  853.  
  854.                if (cdType == KARAOKE){
  855.                   track_no = (track_no <= 1) ? nSongs : track_no - 1;
  856.                   wsprintf (s,"Track %d",track_no);
  857.                   WriteText (W0,s);
  858.                }else if (ActiveItem == IDM_PLAY){
  859.                   seek = BACKWARD;
  860.                   set_to_play ();
  861.                }
  862.                break;
  863.             case IDM_NEXT_SONG:
  864.                if (cdType == ALL)
  865.                   break;
  866.  
  867.                if ((cdType == KARAOKE) && (songGray || dspMode == VIDEO))
  868.                   break;
  869.  
  870.                DrawButton (iNEXT,OFF);
  871.  
  872.                if (cdType == KARAOKE && playing){
  873.                   WriteText (W1,(LPSTR)"Stop First");
  874.                   DrawButton (iNEXT,OFF);
  875.                   break;
  876.                }
  877.  
  878.                if (cdType == KARAOKE){
  879.                   track_no = (track_no >= nSongs) ? 1 : track_no + 1;
  880.                   wsprintf (s,"Track %d",track_no);
  881.                   WriteText (W0,s);
  882.                   break;
  883.                }else if (ActiveItem == IDM_PLAY){
  884.                   seek = FORWARD;
  885.                   set_to_play ();
  886.                }
  887.                break;
  888.             case IDM_REPEAT:
  889.                repeat = !repeat;
  890.                DrawButton (iREPEAT,repeat);
  891.                break;
  892.             case IDM_SPACE:
  893.                if (MPEGMCIExist){
  894.                   if (GetFocus () != hPanelWnd)
  895.                      break;
  896.                }
  897.                if (dspMode == VGA){
  898.                   VideoVGASwitcher (VIDEO);
  899.                   WriteText (W2,(LPSTR)"Ctrl+Alt+SPACE to return");
  900.                }else{
  901.                   VideoVGASwitcher (VGA);
  902.                   WriteText (curWlevel,(LPSTR)curMsg);
  903.                }
  904.                break;
  905.             case IDM_MousePressed:
  906.                WriteText (W2,(LPSTR)"Ctrl+Alt+SPACE to return");
  907.                break;
  908.  
  909.             /*
  910.              * Adjust display screen
  911.              */
  912.             case IDM_SCREEN_LF:
  913.                if (!playing && !MPEGMCIExist)
  914.                   break;
  915.  
  916.                WMpegAdjustScreen (SCREEN_LF);
  917.                break;
  918.             case IDM_SCREEN_UP:
  919.                if (!playing && !MPEGMCIExist)
  920.                   break;
  921.  
  922.                WMpegAdjustScreen (SCREEN_UP);
  923.                break;
  924.             case IDM_SCREEN_RT:
  925.                if (!playing && !MPEGMCIExist)
  926.                   break;
  927.  
  928.                WMpegAdjustScreen (SCREEN_RT);
  929.                break;
  930.             case IDM_SCREEN_DN:
  931.                if (!playing && !MPEGMCIExist)
  932.                   break;
  933.  
  934.                WMpegAdjustScreen (SCREEN_DN);
  935.                break;
  936.  
  937.             /*
  938.              * Audio Control
  939.              */
  940.             case IDM_SPATIAL:
  941.                nStereo = SPATIAL_STEREO;
  942.                Stereo ((BYTE)nStereo);
  943.                if (idStereo != iSPATIAL)
  944.                   DrawButton (idStereo,OFF);
  945.                DrawButton (iSPATIAL,ON);
  946.                idStereo = iSPATIAL;
  947.                break;
  948.             case IDM_LINEAR:
  949.                nStereo = LINEAR_STEREO;
  950.                Stereo ((BYTE)nStereo);
  951.                if (idStereo != iLINEAR)
  952.                   DrawButton (idStereo,OFF);
  953.                DrawButton (iLINEAR,ON);
  954.                idStereo = iLINEAR;
  955.                break;
  956.             case IDM_PSEUDO:
  957.                nStereo = PSEUDO_STEREO;
  958.                Stereo ((BYTE)nStereo);
  959.                if (idStereo != iPSEUDO)
  960.                   DrawButton (idStereo,OFF);
  961.                DrawButton (iPSEUDO,ON);
  962.                idStereo = iPSEUDO;
  963.                break;
  964.             case IDM_MONO:
  965.                nStereo = FORCED_MONO;
  966.                Stereo ((BYTE)nStereo);
  967.                if (idStereo != iMONO)
  968.                   DrawButton (idStereo,OFF);
  969.                DrawButton (iMONO,ON);
  970.                idStereo = iMONO;
  971.                break;
  972.             case IDM_VOLUME:
  973.                if (idVol != iVOLUME)
  974.                   DrawButton (idVol,OFF);
  975.                DrawButton (iVOLUME,ON);
  976.                idVol = iVOLUME;
  977.                break;
  978.             case IDM_TREBLE:
  979.                if (idVol != iTREBLE)
  980.                   DrawButton (idVol,OFF);
  981.                DrawButton (iTREBLE,ON);
  982.                idVol = iTREBLE;
  983.                break;
  984.             case IDM_BASS:
  985.                if (idVol != iBASS)
  986.                   DrawButton (idVol,OFF);
  987.                DrawButton (iBASS,ON);
  988.                idVol = iBASS;
  989.                break;
  990.             case IDM_MUTE:
  991.                fMute = !fMute;
  992.                Mute ((BYTE)fMute);
  993.                DrawButton (iMUTE,fMute);
  994.                break;
  995.             case IDM_UP:
  996.                if (MPEGMCIExist){
  997.                   if (GetFocus () != hPanelWnd)
  998.                      break;
  999.                }
  1000.                switch (idVol){
  1001.                   case iVOLUME:
  1002.                      nVolL++;
  1003.                      nVolR++;
  1004.                      nVolL = (nVolL > maxVol) ? maxVol : nVolL;
  1005.                      nVolR = (nVolR > maxVol) ? maxVol : nVolR;
  1006.                      VolumeLeft ((BYTE)nVolL);
  1007.                      VolumeRight ((BYTE)nVolR);
  1008.  
  1009.                      // draw curve
  1010.                      if ((nVolL - minVol) % 2)
  1011.                         dspCurve (iVOLUME,UP,1,LEFT);
  1012.  
  1013.                      if ((nVolR - minVol) % 2)
  1014.                         dspCurve (iVOLUME,UP,1,RIGHT);
  1015.                      break;
  1016.                   case iTREBLE:
  1017.                      nTreble++;
  1018.                      nTreble = (nTreble > maxTre) ? maxTre : nTreble;
  1019.                      Treble ((BYTE)nTreble);
  1020.                      dspCurve (iTREBLE,UP,2,LEFT);
  1021.                      dspCurve (iTREBLE,UP,2,RIGHT);
  1022.                      break;
  1023.                   case iBASS:
  1024.                      nBass++;
  1025.                      nBass = (nBass > maxBass) ? maxBass : nBass;
  1026.                      Bass ((BYTE)nBass);
  1027.                      dspCurve (iBASS,UP,2,LEFT);
  1028.                      dspCurve (iBASS,UP,2,RIGHT);
  1029.                      break;
  1030.                }
  1031.                break;
  1032.             case IDM_DOWN:
  1033.                if (MPEGMCIExist){
  1034.                   if (GetFocus () != hPanelWnd)
  1035.                      break;
  1036.                }
  1037.                switch (idVol){
  1038.                   case iVOLUME:
  1039.                      nVolL--;
  1040.                      nVolR--;
  1041.                      nVolL = (nVolL < minVol) ? minVol : nVolL;
  1042.                      nVolR = (nVolR < minVol) ? minVol : nVolR;
  1043.                      VolumeLeft ((BYTE)nVolL);
  1044.                      VolumeRight ((BYTE)nVolR);
  1045.  
  1046.                      // draw curve
  1047.                      if ((nVolL - minVol) % 2)
  1048.                         dspCurve (iVOLUME,DOWN,1,LEFT);
  1049.  
  1050.                      if ((nVolR - minVol) % 2)
  1051.                         dspCurve (iVOLUME,DOWN,1,RIGHT);
  1052.                      break;
  1053.                   case iTREBLE:
  1054.                      nTreble--;
  1055.                      nTreble = (nTreble < minTre) ? minTre : nTreble;
  1056.                      Treble ((BYTE)nTreble);
  1057.                      dspCurve (iTREBLE,DOWN,2,LEFT);
  1058.                      dspCurve (iTREBLE,DOWN,2,RIGHT);
  1059.                      break;
  1060.                   case iBASS:
  1061.                      nBass--;
  1062.                      nBass = (nBass < minBass) ? minBass : nBass;
  1063.                      Bass ((BYTE)nBass);
  1064.                      dspCurve (iBASS,DOWN,2,LEFT);
  1065.                      dspCurve (iBASS,DOWN,2,RIGHT);
  1066.                      break;
  1067.                }
  1068.                break;
  1069.             case IDM_LEFT:
  1070.                if (idVol != iVOLUME)
  1071.                   break;
  1072.                nVolL++;
  1073.                nVolR--;
  1074.                nVolL = (nVolL > maxVol) ? maxVol : nVolL;
  1075.                nVolR = (nVolR < minVol) ? minVol : nVolR;
  1076.                VolumeLeft ((BYTE)nVolL);
  1077.                VolumeRight ((BYTE)nVolR);
  1078.  
  1079.                if ((nVolL - minVol) % 2)
  1080.                   dspCurve (iVOLUME,UP,1,LEFT);
  1081.  
  1082.                if ((nVolR - minVol) % 2)
  1083.                   dspCurve (iVOLUME,DOWN,1,RIGHT);
  1084.                break;
  1085.             case IDM_RIGHT:
  1086.                if (idVol != iVOLUME)
  1087.                   break;
  1088.                nVolL--;
  1089.                nVolR++;
  1090.                nVolL = (nVolL < minVol) ? minVol : nVolL;
  1091.                nVolR = (nVolR > maxVol) ? maxVol : nVolR;
  1092.                VolumeLeft ((BYTE)nVolL);
  1093.                VolumeRight ((BYTE)nVolR);
  1094.  
  1095.                if ((nVolL - minVol) % 2)
  1096.                   dspCurve (iVOLUME,DOWN,1,LEFT);
  1097.  
  1098.                if ((nVolR - minVol) % 2)
  1099.                   dspCurve (iVOLUME,UP,1,RIGHT);
  1100.                break;
  1101.          }
  1102.          break;
  1103.       case WM_RBUTTONDOWN:
  1104.          if (dspMode == VIDEO)
  1105.             break;
  1106.  
  1107.          showVer = !showVer;
  1108.          if (showVer)
  1109.             WriteText (W2,(LPSTR)Version);
  1110.          else
  1111.             WriteText (curWlevel,(LPSTR)curMsg);
  1112.          break;
  1113.       case WM_LBUTTONDBLCLK:
  1114.          if (MPEGMCIExist)
  1115.             break;
  1116.  
  1117.          if (dspMode == VIDEO)
  1118.             break;
  1119.  
  1120.          if (playing && ActiveItem == IDM_PLAY)
  1121.             WMpegGOP ();
  1122.          break;
  1123.       case WM_CREATE:
  1124.          hPowerMenu = LoadMenu (hInst,"MPOWER");
  1125.  
  1126.          /*
  1127.           * Create a DC for the whole screen.  This will be used to display
  1128.           * the window outline when we handle the move ourselves.
  1129.           */
  1130.          hScreenDC = CreateDC ("DISPLAY",NULL,NULL,NULL);
  1131.  
  1132.          hParentBmp = LoadBitmap (hInst,MAKEINTRESOURCE (IDB_PARENT));
  1133.          hGrayBmp   = LoadBitmap (hInst,MAKEINTRESOURCE (IDB_GRAY));
  1134.  
  1135.          if (MPEGMCIExist){
  1136.             hGrayPlay = LoadBitmap (hInst,MAKEINTRESOURCE (IDB_GRAYP));
  1137.             for (i = 0;i <= iLOAD;i++){
  1138.                Button[i].hOff = LoadBitmap (hInst,MAKEINTRESOURCE (Button[i].idOff));
  1139.                Button[i].hOn = LoadBitmap (hInst,MAKEINTRESOURCE (Button[i].idOn));
  1140.             }
  1141.  
  1142.             for (i = iPRE;i <= iREPEAT;i++){
  1143.                if (i == iPLAY)
  1144.                   Button[i].hOff = Button[i].hOn = hGrayPlay;
  1145.                else
  1146.                   Button[i].hOff = Button[i].hOn = hGrayBmp;
  1147.             }
  1148.  
  1149.             for (i > iREPEAT;i < PANEL_BUTTONS;i++){
  1150.                Button[i].hOff = LoadBitmap (hInst,MAKEINTRESOURCE (Button[i].idOff));
  1151.                Button[i].hOn = LoadBitmap (hInst,MAKEINTRESOURCE (Button[i].idOn));
  1152.             }
  1153.          }else{
  1154.             for (i = 0;i < PANEL_BUTTONS;i++){
  1155.                Button[i].hOff = LoadBitmap (hInst,MAKEINTRESOURCE (Button[i].idOff));
  1156.                Button[i].hOn = LoadBitmap (hInst,MAKEINTRESOURCE (Button[i].idOn));
  1157.             }
  1158.  
  1159.             hPreOn  = Button[iPRE].hOn;
  1160.             hPreOff = Button[iPRE].hOff;
  1161.             hNxtOn  = Button[iNEXT].hOn;
  1162.             hNxtOff = Button[iNEXT].hOff;
  1163.  
  1164.             // Init Pre-Song & Next-Song to gray
  1165.             Button[iPRE].hOff  = Button[iPRE].hOn  =
  1166.             Button[iNEXT].hOff = Button[iNEXT].hOn = hGrayBmp;
  1167.          }
  1168.  
  1169.          // Create pen brush for audio display curve
  1170.          hCurveBackgnd = CreateSolidBrush (RGB (0,0,0));
  1171.          hCurveForegnd = CreateSolidBrush (RGB (0,255,0));
  1172.  
  1173.          // Get current font
  1174.          hCurrentFont = GetStockObject (ANSI_VAR_FONT);
  1175.          break;
  1176.       case WM_DRAWITEM:
  1177.          /*
  1178.           * The state of one of the buttons has changed.  Redraw the button
  1179.           * to reflect its new state.
  1180.           */
  1181.          lpdis = (DRAWITEMSTRUCT FAR*)lParam;
  1182.  
  1183.          // Abort if it is not our button
  1184.          if ((lpdis->CtlType != ODT_BUTTON) ||
  1185.              (lpdis->CtlID < BUTTON_START_ID) ||
  1186.              (lpdis->CtlID >= BUTTON_START_ID + PANEL_BUTTONS)
  1187.             )
  1188.             return (DefWindowProc (hWnd,message,wParam,lParam));
  1189.  
  1190.          // Draw every button during init
  1191.          i = lpdis->CtlID - BUTTON_START_ID;
  1192.  
  1193.          switch (lpdis->itemAction){   // Action to be taken
  1194.             case ODA_DRAWENTIRE:       // Redraw entire button
  1195.                DrawButton (i,Button[i].bdState);
  1196.                WriteText (curWlevel,(LPSTR)curMsg);
  1197.                break;
  1198.             case ODA_SELECT:     // The buttons selection status has changed
  1199.                if (i == iPOWER){ // power status is different from others
  1200.                   on = OFF;
  1201.                   off = ON;
  1202.                }else{
  1203.                   on = ON;
  1204.                   off = OFF;
  1205.                }
  1206.                if (lpdis->itemState & ODS_SELECTED) // Button is being selected
  1207.                   DrawButton (i,on);
  1208.                else{                                // Button is being deselected
  1209.                   DrawButton (i,off);
  1210.                   SetFocus (hPanelWnd);
  1211.                }
  1212.                break;
  1213.             case ODA_FOCUS:   // The buttons focus has changed
  1214.                break;
  1215.          }
  1216.          return(TRUE);
  1217.       case WM_LBUTTONDOWN:
  1218.          if (dspMode == VIDEO)
  1219.             break;
  1220.  
  1221.          fMove = TRUE;        // Moving the control panel window
  1222.          GetCursorPos (&ptStart);
  1223.          GetWindowRect (hWnd,&rcWindow);
  1224.          CopyRect (&rcOutline,&rcWindow);
  1225.          OutlineRect (hScreenDC,&rcOutline);
  1226.          SetCapture (hWnd);
  1227.          break;
  1228.       case WM_LBUTTONUP:
  1229.          if (dspMode == VIDEO)
  1230.             break;
  1231.  
  1232.          if (fMove){
  1233.             fMove = FALSE;
  1234.             OutlineRect (hScreenDC,&rcOutline); // Erase outline
  1235.             GetCursorPos (&ptStop);
  1236.             SetWindowPos (hWnd,NULL,
  1237.                           rcWindow.left + (ptStop.x - ptStart.x),
  1238.                           rcWindow.top + (ptStop.y - ptStart.y),
  1239.                           0,0,SWP_NOSIZE
  1240.                          );
  1241.             ReleaseCapture ();
  1242.          }
  1243.          break;
  1244.       case WM_MOUSEMOVE:
  1245.          if (dspMode == VIDEO)
  1246.             break;
  1247.  
  1248.          if (fMove){
  1249.             GetCursorPos (&ptStop);
  1250.             OutlineRect (hScreenDC,&rcOutline); // Erase old outline
  1251.             CopyRect (&rcOutline,&rcWindow);
  1252.             OffsetRect (&rcOutline,ptStop.x - ptStart.x,ptStop.y - ptStart.y);
  1253.             OutlineRect (hScreenDC,&rcOutline); // Draw new outline
  1254.          }
  1255.          break;
  1256.       case WM_PAINT:
  1257.          hDC = BeginPaint (hWnd,&ps);
  1258.  
  1259.          hMemoryDC = CreateCompatibleDC (hDC);
  1260.          SelectObject (hMemoryDC,hParentBmp);
  1261.          BitBlt (hDC,0,0,PANEL_WIDTH,PANEL_HEIGHT,hMemoryDC,0,0,SRCCOPY);
  1262.          ReleaseDC (hPanelWnd,hDC);
  1263.          DeleteDC (hMemoryDC);
  1264.  
  1265.          EndPaint (hWnd,&ps);
  1266.          if (!keyHookOn){
  1267.             SetHook (hPanelWnd,(KeyTable far *)&keys);
  1268.             keyHookOn = TRUE;
  1269.          }
  1270.          break;
  1271.       case WM_CLOSE:
  1272.          DestroyWindow (hWnd);
  1273.          break;
  1274.       case WM_DESTROY:
  1275.          done = TRUE;
  1276.          KillTimer (hWnd,idTimer);
  1277.          if (!MPEGExist){
  1278.             PostQuitMessage (0);
  1279.             break;
  1280.          }
  1281.  
  1282.          if (!MPEGMCIExist){
  1283.             WMpegCommand (STP);  // stop
  1284.             WMpegExit ();
  1285.             WinHelp (hWnd,szHelpFileName,HELP_QUIT,0L);
  1286.          }
  1287.  
  1288.          // Release float menu
  1289.          DestroyMenu (hPowerMenu);
  1290.  
  1291.          // Destroy buttons
  1292.          DeleteObject (hParentBmp);
  1293.          for (i = 0;i < PANEL_BUTTONS;i++){
  1294.             DestroyWindow (Button[i].hWnd);
  1295.             DeleteObject (Button[i].hOff);
  1296.             DeleteObject (Button[i].hOn);
  1297.          }
  1298.          DeleteObject (hGrayBmp);
  1299.  
  1300.          if (MPEGMCIExist)
  1301.             DeleteObject (hGrayPlay);
  1302.  
  1303.          DeleteDC (hScreenDC);
  1304.  
  1305.          // Delete solid brush
  1306.          DeleteObject (hCurveBackgnd);
  1307.          DeleteObject (hCurveForegnd);
  1308.  
  1309.          VideoVGASwitcher (VGA);
  1310.          saveCfg ();
  1311.  
  1312.          /*
  1313.           * Set to min volume, this setting must be after saveCfg function
  1314.           * such that the user specified volume status can be saved to INI
  1315.           * file.
  1316.           */
  1317.          if (!MPEGMCIExist){
  1318.             VolumeLeft ((BYTE)minVol);
  1319.             VolumeRight ((BYTE)minVol);
  1320.             Mute ((BYTE)TRUE);         // turn off audio
  1321.             WMpegAudioEnable (FALSE);  // release the audio controller
  1322.          }
  1323.  
  1324.          PostQuitMessage (0);
  1325.          break;
  1326.       default:
  1327.          return (DefWindowProc (hWnd,message,wParam,lParam));
  1328.    }
  1329.    return (FALSE);
  1330. }/* PanelWndProc */
  1331.  
  1332.  
  1333. int FAR PASCAL SelectDiscDlg (hDlg,message,wParam,lParam)
  1334. HWND hDlg;
  1335. UINT message;
  1336. WPARAM wParam;
  1337. LPARAM lParam;
  1338. {
  1339.    static int type;
  1340.    int  id;
  1341.    RECT winRect,cliRect;
  1342.  
  1343.    switch (message){
  1344.       case WM_INITDIALOG:
  1345.          GetWindowRect (hPanelWnd,(LPRECT)&winRect);
  1346.          GetWindowRect (hDlg,(LPRECT)&cliRect);
  1347.          MoveWindow (hDlg,cliRect.left,winRect.top + (winRect.bottom - winRect.top) / 2,
  1348.                      cliRect.right - cliRect.left,
  1349.                      cliRect.bottom - cliRect.top,
  1350.                      FALSE);
  1351.  
  1352.          if (!cdType)
  1353.             id = IDD_CDIFMV;
  1354.          else
  1355.             id = cdType + IDD_ALL - 1;
  1356.          CheckRadioButton (hDlg,IDD_ALL,IDD_CDIFMV,id);
  1357.          type = id - IDD_ALL + 1;
  1358.          break;
  1359.       case WM_COMMAND:
  1360.          switch (wParam){
  1361.             case IDD_ALL:
  1362.                CheckRadioButton (hDlg,IDD_ALL,IDD_CDIFMV,IDD_ALL);
  1363.                type = ALL;
  1364.                break;
  1365.             case IDD_KARAOKE:
  1366.                CheckRadioButton (hDlg,IDD_ALL,IDD_CDIFMV,IDD_KARAOKE);
  1367.                type = KARAOKE;
  1368.                break;
  1369.             case IDD_CDIFMV:
  1370.                CheckRadioButton (hDlg,IDD_ALL,IDD_CDIFMV,IDD_CDIFMV);
  1371.                type = CDIFMV;
  1372.                break;
  1373.             case IDD_OK:
  1374.                EndDialog (hDlg,TRUE);
  1375.                cdType = type;
  1376.                return (TRUE);
  1377.                break;
  1378.             case IDD_CANCEL:
  1379.                EndDialog (hDlg,FALSE);
  1380.                return (FALSE);
  1381.                break;
  1382.             default:
  1383.                break;
  1384.             break;
  1385.          }
  1386.    }
  1387.    return (FALSE);
  1388. }/* SelectDiscDlg */
  1389.  
  1390.  
  1391. void dspCurve (item,up,step,left)
  1392. int  item;
  1393. BOOL up;
  1394. int  step;
  1395. BOOL left;
  1396. {
  1397.    HBRUSH hbrOld;
  1398.    HDC    hDC;
  1399.    int    x;
  1400.    int    i;
  1401.    int    far *y;
  1402.  
  1403.    switch (item){
  1404.       case iVOLUME:
  1405.          if (left){
  1406.             x = VolLeft_X0;
  1407.             y = (int far *)&curVolLY;
  1408.          }else{
  1409.             x = VolRight_X0;
  1410.             y = (int far *)&curVolRY;
  1411.          }
  1412.          break;
  1413.       case iTREBLE:
  1414.          if (left){
  1415.             x = TreLeft_X0;
  1416.             y = (int far *)&curTreLY;
  1417.          }else{
  1418.             x = TreRight_X0;
  1419.             y = (int far *)&curTreRY;
  1420.          }
  1421.          break;
  1422.       case iBASS:
  1423.          if (left){
  1424.             x = BassLeft_X0;
  1425.             y = (int far *)&curBassLY;
  1426.          }else{
  1427.             x = BassRight_X0;
  1428.             y = (int far *)&curBassRY;
  1429.          }
  1430.          break;
  1431.       default:
  1432.          return;
  1433.    }
  1434.  
  1435.    hDC = GetDC (Button[iDSPA].hWnd);
  1436.    if (up)
  1437.       hbrOld = SelectObject (hDC,hCurveForegnd);
  1438.    else
  1439.       hbrOld = SelectObject (hDC,hCurveBackgnd);
  1440.  
  1441.    for (i = 0;i < step;i++){
  1442.       if (up){
  1443.          if (*y < TopCurveY)
  1444.             break;
  1445.          BitBlt (hDC,x,*y,CurveWidth,CurveHeight,NULL,0,0,PATCOPY);
  1446.          *y = *y - (CurveHeight + GAPY_CURVE);
  1447.       }else{
  1448.          *y = *y + (CurveHeight + GAPY_CURVE);
  1449.          if (*y > BottomCurveY){
  1450.             *y = BottomCurveY;
  1451.             break;
  1452.          }
  1453.          BitBlt (hDC,x,*y,CurveWidth,CurveHeight,NULL,0,0,PATCOPY);
  1454.       }
  1455.    }
  1456.  
  1457.    SelectObject (hDC,hbrOld);
  1458.    ReleaseDC (Button[iDSPA].hWnd,hDC);
  1459. }/* dspCurve */
  1460.  
  1461.  
  1462. #define DSPX   5
  1463. #define DSPY   15
  1464.  
  1465. /************************************************************************
  1466. * WriteText                                                              *
  1467. *                                                                       *
  1468. * Draw a string of text to display window for information               *
  1469. *************************************************************************/
  1470. void WriteText (wLevel,msg)
  1471. int wLevel;
  1472. LPSTR msg;
  1473. {
  1474.    HDC    hDC;
  1475.    HBRUSH hBrush;
  1476.    int    R,G,B;
  1477.    HFONT  hOldFont;
  1478.  
  1479.    hDC = GetDC (Button[iDSPV].hWnd);
  1480.    hBrush = SelectObject (hDC,GetStockObject (BLACK_BRUSH));
  1481.    BitBlt (hDC,2,2,136,30,NULL,0,0,PATCOPY);
  1482.    SelectObject (hDC,hBrush);
  1483.    SetBkMode (hDC,TRANSPARENT);
  1484.    SetROP2 (hDC,R2_COPYPEN);
  1485.  
  1486.    if (wLevel == W0){
  1487.       R = G = 255;
  1488.       B = 0;
  1489.    }else if (wLevel == W1){
  1490.       R = 255;
  1491.       G = B = 0;
  1492.    }else{
  1493.       R = B = 255;
  1494.       G = 0;
  1495.    }
  1496.    SetTextColor (hDC,RGB (R,G,B));
  1497.  
  1498.    hOldFont = SelectObject (hDC,hCurrentFont);
  1499.    TextOut (hDC,DSPX,DSPY,msg,lstrlen (msg));
  1500.    SelectObject (hDC,hOldFont);
  1501.  
  1502.    if (wLevel <= W1){
  1503.       curWlevel = wLevel;
  1504.       lstrcpy ((LPSTR)curMsg,msg);
  1505.    }
  1506.    ReleaseDC (Button[iDSPV].hWnd,hDC);
  1507. }/* WriteText */
  1508.  
  1509.  
  1510. /************************************************************************
  1511. * OutlineRect                                                           *
  1512. *                                                                       *
  1513. * Draw a rectangle with a line weight equal to the border width using   *
  1514. * the XOR mix mode.                                                     *
  1515. *************************************************************************/
  1516. void OutlineRect (hDC,rp)
  1517. HDC hDC;
  1518. RECT *rp;
  1519. {
  1520.    int  xWidth;
  1521.    int  yWidth;
  1522.  
  1523.    xWidth = GetSystemMetrics (SM_CXBORDER);
  1524.    yWidth = GetSystemMetrics (SM_CYBORDER);
  1525.    BitBlt (hDC,rp->left-xWidth,rp->top-yWidth, xWidth,
  1526.            rp->bottom-rp->top+yWidth,NULL,0,0,DSTINVERT);
  1527.  
  1528.    BitBlt (hDC,rp->left,rp->top-yWidth,rp->right-rp->left+xWidth,
  1529.            yWidth,NULL,0,0,DSTINVERT);
  1530.  
  1531.    BitBlt (hDC,rp->right,rp->top,xWidth,
  1532.            rp->bottom-rp->top+yWidth,NULL,0,0,DSTINVERT);
  1533.  
  1534.    BitBlt (hDC,rp->left-xWidth,rp->bottom,rp->right-rp->left+xWidth,
  1535.            yWidth,NULL,0,0,DSTINVERT);
  1536. }/* OutlineRect */
  1537.  
  1538.  
  1539. /************************************************************************
  1540. * DrawButton                                                            *
  1541. *                                                                       *
  1542. * Draw the specified button up or down and on or off.                   *
  1543. *************************************************************************/
  1544. void DrawButton (i,fOn)
  1545. int  i;     // button index
  1546. BOOL fOn;
  1547. {
  1548.    HDC hDC,hMemoryDC;
  1549.    int step;
  1550.  
  1551.    /* Create a memory DC for use in drawing buttons. */
  1552.    hDC = GetDC (Button[i].hWnd);
  1553.    hMemoryDC = CreateCompatibleDC (hDC);
  1554.  
  1555.    if (fOn)
  1556.       SelectObject (hMemoryDC,Button[i].hOn);
  1557.    else
  1558.       SelectObject (hMemoryDC,Button[i].hOff);
  1559.    BitBlt (hDC,0,0,Button[i].bdWidth,Button[i].bdHeight,hMemoryDC,0,0,SRCCOPY);
  1560.  
  1561.    ReleaseDC (Button[i].hWnd,hDC);
  1562.    DeleteDC (hMemoryDC);
  1563.    Button[i].bdState = fOn;
  1564.  
  1565.    if (i == iDSPA){  // draw music curve
  1566.       curVolLY = BottomCurveY;
  1567.       curVolRY = BottomCurveY;
  1568.       curTreLY = BottomCurveY;
  1569.       curTreRY = BottomCurveY;
  1570.       curBassLY= BottomCurveY;
  1571.       curBassRY= BottomCurveY;
  1572.  
  1573.       // draw volume left curve
  1574.       step = (nVolL - minVol) / 2;
  1575.       dspCurve (iVOLUME,UP,step,LEFT);
  1576.  
  1577.       // draw volume right curve
  1578.       step = (nVolR - minVol) / 2;
  1579.       dspCurve (iVOLUME,UP,step,RIGHT);
  1580.  
  1581.       // draw treble left and right curve
  1582.       step = (nTreble - minTre) * 2;
  1583.       dspCurve (iTREBLE,UP,step,LEFT);
  1584.       dspCurve (iTREBLE,UP,step,RIGHT);
  1585.  
  1586.       // draw bass left and right curve
  1587.       step = (nBass - minBass) * 2;
  1588.       dspCurve (iBASS,UP,step,LEFT);
  1589.       dspCurve (iBASS,UP,step,RIGHT);
  1590.    }
  1591. }/* DrawButton */
  1592.  
  1593.  
  1594. /****************************************************************************
  1595. *  FUNCTION:   MakeHelpPathName                                             *
  1596. *                                                                           *
  1597. *  PURPOSE:    HelpEx assumes that the .HLP help file is in the same        *
  1598. *              directory as the HelpEx executable.This function derives     *
  1599. *              the full path name of the help file from the path of the     *
  1600. *              executable.                                                  *
  1601. ****************************************************************************/
  1602. void MakeHelpPathName (szName)
  1603. char *szName;
  1604. {
  1605.    char *  pcFileName;
  1606.    int     nFileNameLen;
  1607.  
  1608.    nFileNameLen = GetModuleFileName (hInst,szName,EXE_NAME_MAX_SIZE);
  1609.    pcFileName = szName + nFileNameLen;
  1610.  
  1611.    while (pcFileName > szName){
  1612.       if (*pcFileName == '\\' || *pcFileName == ':'){
  1613.          *(++pcFileName) = '\0';
  1614.          break;
  1615.       }
  1616.       nFileNameLen--;
  1617.       pcFileName--;
  1618.    }
  1619.  
  1620.    if ((nFileNameLen+13) < EXE_NAME_MAX_SIZE)
  1621.          lstrcat (szName,"wplayer.hlp");
  1622.    else
  1623.          lstrcat (szName,"?");
  1624. }/* MakeHelpPathName */
  1625.  
  1626.  
  1627. /************************************************************************
  1628. * Set_to_play                                                           *
  1629. *                                                                       *
  1630. * The button is either being pressed or released.  Draw it up or down.  *
  1631. * If it is being released, send the corresponding message to the panel  *
  1632. * window.  It is being pressed, toggle the state between on and off.    *
  1633. *************************************************************************/
  1634. void set_to_play (void)
  1635. {
  1636.    int rtn;
  1637.    MSFTime timeSeek;
  1638.    int timeSec;
  1639.  
  1640.    if (cdType == CDIFMV && theFirstFMV){
  1641.       timeSec = startTimeSec;
  1642.       theFirstFMV = FALSE;
  1643.    }else if (cdType == CDIFMV){
  1644.       if (seek == FORWARD){
  1645.          timeSec = WMpegGetCurrentPTS () + skipTimeSec;
  1646.          if (timeSec >= discTime){
  1647.             PostMessage (hPanelWnd,WM_COMMAND,IDM_STOP,0L);
  1648.             return;
  1649.          }
  1650.       }else if (seek == BACKWARD){
  1651.          timeSec = WMpegGetCurrentPTS () - skipTimeSec;
  1652.          if (timeSec < 0){
  1653.             preTrack = 0;
  1654.             SendMessage (hPanelWnd,WM_COMMAND,IDM_PLAY,0L);
  1655.             timeSec = 0;
  1656.          }
  1657.       }else
  1658.          timeSec = 0;
  1659.    }else
  1660.       timeSec = 0;
  1661.  
  1662.    hPrevCursor = SetCursor (LoadCursor (NULL,IDC_WAIT));
  1663.    if (timeSec == 0)
  1664.       rtn = WMpegPlayEnable ((LPMSFTime)NULL);
  1665.    else{
  1666.       timeSeek.frm = 0;
  1667.       timeSeek.sec = (BYTE)(timeSec % 60);
  1668.       timeSeek.min = (BYTE)(timeSec / 60);
  1669.       rtn = WMpegPlayEnable ((LPMSFTime)&timeSeek);
  1670.    }
  1671.    SetCursor (hPrevCursor);
  1672.  
  1673.    if (rtn){
  1674.       WriteText (W1,(LPSTR)"Error Init DSP");
  1675.       return;
  1676.    }
  1677.  
  1678.    if (!TimerExist){
  1679.       lpfnTimerProc = MakeProcInstance ((FARPROC)TimerProc,hInst);
  1680.       idTimer = SetTimer (hPanelWnd,1,20,(FARPROC)lpfnTimerProc);
  1681.       TimerExist = TRUE;
  1682.    }
  1683.         
  1684.    demostop = FALSE;
  1685.    pause = FALSE;
  1686.    playing = TRUE;
  1687.    done = FALSE;
  1688.    seek = NORMAL;
  1689. }/* set_to_play */
  1690.  
  1691.  
  1692. BOOL processing (void)
  1693. {
  1694.    load = FALSE;
  1695.    if (cdType == KARAOKE || cdType == CDIFMV){
  1696.       if (preTrack != track_no){
  1697.          if (!loadTrack ())
  1698.             return (FALSE);
  1699.       }
  1700.    }else if (preFile != nFileIndex){
  1701.       char szFile[128];
  1702.  
  1703.       selectFile (szTFileName,szFile,nFileIndex);
  1704.       if (MpegLoader (szFile))
  1705.          return (FALSE);
  1706.    }
  1707.    load = TRUE;
  1708.    return (TRUE);
  1709. }/* processing */
  1710.  
  1711.  
  1712. int MpegLoader (name)
  1713. char *name;
  1714. {
  1715.    int rtn,media;
  1716.  
  1717.    media = 0;
  1718.    if (cdType == KARAOKE || cdType == CDIFMV)
  1719.       media = 1;
  1720.  
  1721.    hPrevCursor = SetCursor (LoadCursor (NULL,IDC_WAIT));
  1722.    rtn = WMpegLoad (media,name,(WORD)cddrv_no,sync,cdi);
  1723.    SetCursor (hPrevCursor);
  1724.    if (rtn < 0){
  1725.       switch (rtn){
  1726.          case EMPEGFile:
  1727.             WriteText (W1,(LPSTR)"Open error");
  1728.             break;
  1729.          case EBitStream:
  1730.             WriteText (W1,(LPSTR)"Unknown BitStream");
  1731.             break;
  1732.          case EVXD:
  1733.             WriteText (W1,(LPSTR)"VXD not installed");
  1734.             break;
  1735.          case EVolumeSize:
  1736.          case ESectorSize:
  1737.          case EInitCDROM:
  1738.          case ESeekTop:
  1739.          case EReadCD:
  1740.          case EGetStartSector:
  1741.          case EGetLastSector:
  1742.          case ESeek:
  1743.             WriteText (W1,(LPSTR)"Read CDROM error");
  1744.             break;
  1745.          case EInitVideo:
  1746.             WriteText (W1,(LPSTR)"Error init Video");
  1747.             break;
  1748.          case EInitAudio:
  1749.             WriteText (W1,(LPSTR)"Error init Audio");
  1750.             break;
  1751.          case EWINENH:
  1752.             WriteText (W1,(LPSTR)"Not in enhanced mode");
  1753.             break;
  1754.          case EDMA:
  1755.             WriteText (W1,(LPSTR)"Init DMA error");
  1756.             break;
  1757.          case EDecodeAudio:
  1758.             WriteText (W1,(LPSTR)"Unknown BitStream");
  1759.             break;
  1760.          case ECDReady:
  1761.             WriteText (W1,(LPSTR)"CD-ROM not ready");
  1762.             break;
  1763.          default:
  1764.             WriteText (W1,(LPSTR)"System error");
  1765.             break;
  1766.       }
  1767.       return (1);
  1768.    }
  1769.  
  1770.    track_no = rtn;
  1771.    return (0);
  1772. }/* MpegLoader */
  1773.  
  1774.  
  1775. int loadTrack (void)
  1776. {
  1777.    char szTrack[5];
  1778.  
  1779.    wsprintf (szTrack,"%d",track_no);
  1780.  
  1781.    if (MpegLoader (szTrack)){
  1782.       load = FALSE;
  1783.       selectCD = 0;
  1784.       return (0);
  1785.    }
  1786.  
  1787.    load = TRUE;
  1788.    selectCD = 1;
  1789.    preTrack = track_no;
  1790.  
  1791.    return (track_no);
  1792. }/* loadTrack */
  1793.  
  1794.  
  1795. int selectFile (fileSpec,fileRtn,index)
  1796. char *fileSpec;
  1797. char *fileRtn;
  1798. int  index;
  1799. {
  1800.    char files[256];
  1801.    char *szPtr;
  1802.    int  nfiles;
  1803.  
  1804.    lstrcpy (files,(LPSTR)fileSpec);
  1805.  
  1806.    if (!(szPtr = strtok (files," ")))      // error
  1807.       return (0);
  1808.  
  1809.    nfiles = 0;
  1810.    while (szPtr = strtok (NULL," ")){
  1811.       nfiles++;
  1812.       if (index == nfiles)
  1813.          break;
  1814.    }
  1815.  
  1816.    preFile = index;
  1817.  
  1818.    if (fileRtn != (char *)NULL)
  1819.       lstrcpy (fileRtn,(LPSTR)files);     // path
  1820.  
  1821.    if (nfiles == 0)                       // just one file selected
  1822.       return (1);
  1823.  
  1824.    if (fileRtn != (char *)NULL){
  1825.       if (fileRtn[lstrlen (fileRtn) - 1] != '\\')
  1826.          lstrcat (fileRtn,(LPSTR)"\\");
  1827.       lstrcat (fileRtn,(LPSTR)szPtr);     // full name
  1828.    }
  1829.  
  1830.    return (nfiles);
  1831. }/* selectFile */
  1832.  
  1833.  
  1834. char szCfgFileSpec[128];
  1835. char pStr[128];
  1836.  
  1837. int initMpeg (lpVideo)
  1838. LPSTR lpVideo;
  1839. {
  1840.    int VideoSource;      // NTSC,  PAL
  1841.    int rtn;
  1842.  
  1843.    GetWindowsDirectory (szCfgFileSpec,128);
  1844.    strcat (szCfgFileSpec,"\\winmpeg.ini");
  1845.  
  1846.    if (!MPEGMCIExist){
  1847.       // Get default setting from command line
  1848.       if (!lstrcmpi (lpVideo,(LPCSTR)"N"))      // force to NTSC
  1849.          VideoSource = NTSC;
  1850.       else if (!lstrcmpi (lpVideo,(LPCSTR)"P")) // force to PAL
  1851.          VideoSource = PAL;
  1852.       else
  1853.          VideoSource = 0;                       // from INI file
  1854.  
  1855.       cddrv_no = WMpegGetCDDriveID ();
  1856.       if (cddrv_no == EMSCDEX)
  1857.          mscdex = FALSE;
  1858.  
  1859.       if (cddrv_no == EDRIVE)
  1860.          cdrom = FALSE;
  1861.  
  1862.       getINIStr ("BusType");
  1863.       if (!lstrcmpi (pStr,"SCSI"))
  1864.          sync = 0;
  1865.       else
  1866.          sync = 1;
  1867.  
  1868.       getINIStr ((LPSTR)"DiscType");
  1869.       if (!lstrcmpi (pStr,"KARAOKE"))
  1870.          defCDType = KARAOKE;
  1871.       else
  1872.          defCDType = CDIFMV;
  1873.       cdType = prvCDType = defCDType;
  1874.    }
  1875.  
  1876.    getINIStr ((LPSTR)"Volume left");
  1877.    nVolL = (pStr[0] == '\0') ? defVolL : strtoi (pStr);
  1878.  
  1879.    getINIStr ((LPSTR)"Volume right");
  1880.    nVolR = (pStr[0] == '\0') ? defVolR : strtoi (pStr);
  1881.  
  1882.    getINIStr ((LPSTR)"Bass");
  1883.    nBass = (pStr[0] == '\0') ? defBass : strtoi (pStr);
  1884.  
  1885.    getINIStr ((LPSTR)"Treble");
  1886.    nTreble = (pStr[0] == '\0') ? defTreble : strtoi (pStr);
  1887.  
  1888.    getINIStr ((LPSTR)"Stereo");
  1889.    if (!lstrcmp (pStr,(LPSTR)"Spatial")){
  1890.       nStereo = SPATIAL_STEREO;
  1891.       idStereo = iSPATIAL;
  1892.    }else if (!lstrcmp (pStr,(LPSTR)"Mono")){
  1893.       nStereo = FORCED_MONO;
  1894.       idStereo = iMONO;
  1895.    }else if (!lstrcmp (pStr,(LPSTR)"Pseudo")){
  1896.       nStereo = PSEUDO_STEREO;
  1897.       idStereo = iPSEUDO;
  1898.    }else{
  1899.       nStereo = LINEAR_STEREO;
  1900.       idStereo = iLINEAR;
  1901.    }
  1902.  
  1903.    if (!MPEGMCIExist){
  1904.       getINIStr ((LPSTR)"ShowOnVGA");
  1905.       if (!lstrcmpi (pStr,(LPSTR)"yes"))
  1906.          showOnVGA = TRUE;
  1907.       else
  1908.          showOnVGA = FALSE;
  1909.  
  1910.       startTimeSec = getINIint ((LPSTR)"StartTimeSec");
  1911.       skipTimeSec = getINIint ((LPSTR)"SkipTimeSec");
  1912.  
  1913.       if (!skipTimeSec)
  1914.          skipTimeSec = 120;
  1915.  
  1916.       if (rtn = WMpegInit (VideoSource))
  1917.          return (rtn);
  1918.  
  1919.       WMpegAudioEnable (TRUE);
  1920.    }
  1921.  
  1922.    MPEGExist = TRUE;
  1923.    return (0);
  1924. }/* initMpeg */
  1925.  
  1926.  
  1927. void saveCfg (void)
  1928. {
  1929.    wsprintf (pStr,"%d",nVolL);
  1930.    putINIStr ((LPSTR)"Volume left");
  1931.  
  1932.    wsprintf (pStr,"%d",nVolR);
  1933.    putINIStr ((LPSTR)"Volume right");
  1934.  
  1935.    wsprintf (pStr,"%d",nBass);
  1936.    putINIStr ((LPSTR)"Bass");
  1937.  
  1938.    wsprintf (pStr,"%d",nTreble);
  1939.    putINIStr ((LPSTR)"Treble");
  1940.  
  1941.    switch (nStereo){
  1942.       case SPATIAL_STEREO:
  1943.          lstrcpy (pStr,(LPSTR)"Spatial");
  1944.          break;
  1945.       case PSEUDO_STEREO:
  1946.          lstrcpy (pStr,(LPSTR)"Pseudo");
  1947.          break;
  1948.       case LINEAR_STEREO:
  1949.          lstrcpy (pStr,(LPSTR)"Linear");
  1950.          break;
  1951.       case FORCED_MONO:
  1952.       default:
  1953.          lstrcpy (pStr,(LPSTR)"Mono");
  1954.          break;
  1955.    }
  1956.    putINIStr ((LPSTR)"Stereo");
  1957. }/* saveCfg */
  1958.  
  1959.  
  1960. void getINIStr (key)
  1961. LPSTR key;
  1962. {
  1963.    int  rtn;
  1964.  
  1965.    rtn = GetPrivateProfileString ((LPCSTR)"UserDef",     // Section
  1966.                                   (LPCSTR)key,           // Entry
  1967.                                   (LPCSTR)NULL,          // Default string
  1968.                                   (LPSTR)pStr,           // string returned
  1969.                                   (int)128,              // length
  1970.                                   (LPCSTR)szCfgFileSpec  // Initialize filename
  1971.                                  );
  1972.    if (!rtn)
  1973.       pStr[0] = '\0';
  1974. }/* getINIStr */
  1975.  
  1976.  
  1977. UINT getINIint (key)
  1978. LPSTR key;
  1979. {
  1980.    UINT rtn;
  1981.  
  1982.    rtn = GetPrivateProfileInt ((LPCSTR)"UserDef",     // Section
  1983.                                (LPCSTR)key,           // Entry
  1984.                                0,                     // Default value
  1985.                                (LPCSTR)szCfgFileSpec  // Initialize filename
  1986.                               );
  1987.    return (rtn);
  1988. }/* getINIStr */
  1989.  
  1990.  
  1991. void putINIStr (key)
  1992. LPSTR key;
  1993. {
  1994.    WritePrivateProfileString ((LPCSTR)"UserDef",     // Section
  1995.                               (LPCSTR)key,           // Entry
  1996.                               (LPSTR)pStr,           // string returned
  1997.                               (LPCSTR)szCfgFileSpec  // Initialize filename
  1998.                              );
  1999.    pStr[0] = '\0';
  2000. }/* putINIStr */
  2001.  
  2002.  
  2003. int strtoi (str)
  2004. LPSTR str;
  2005. {
  2006.    int hex[4] = {1,16,256,4096};
  2007.    int dec[4] = {1,10,100,1000};
  2008.    int len,i,j,numRtn = 0;
  2009.    LPSTR tmp;
  2010.    char tmp1;
  2011.    BOOL Hex = FALSE;
  2012.  
  2013.    tmp = str;
  2014.    if (tmp[0] == '0' && tmp[1] == 'x'){   // hex
  2015.       tmp += 2;
  2016.       Hex = TRUE;
  2017.    }
  2018.    len = lstrlen ((LPSTR)tmp);
  2019.    if (len > 3)                           // int may be overflow
  2020.       return (0);
  2021.  
  2022.    for (i = len-1,j = 0;(i >= 0 && j <= 3);i--,j++){
  2023.       tmp1 = *(tmp + i);
  2024.       if (tmp1 >= 0x00 && tmp1 <= 0x39)
  2025.          tmp1 -= 0x30;                       // 0 - 9
  2026.       else if (tmp1 >= 'a' && tmp1 <= 'f')
  2027.          tmp1 = (tmp1 - 'a') + 10;           // 'a' - 'f'
  2028.       else if (tmp1 >= 'A' && tmp1 <= 'F')
  2029.          tmp1 = (tmp1 - 'A') + 10;           // 'A' - 'F'
  2030.       else
  2031.          return (0);
  2032.       if (Hex)
  2033.          numRtn += tmp1 * hex[j];
  2034.       else
  2035.          numRtn += tmp1 * dec[j];
  2036.    }
  2037.    return (numRtn);
  2038. }/* strtoi */
  2039.  
  2040.  
  2041. LPSTR DecToHex (i,sz)
  2042. int i;
  2043. LPSTR sz;
  2044. {
  2045.    LPSTR szSav = sz;
  2046.    int temp,j,index;
  2047.    char hexTable[]={'0','1','2','3','4','5','6','7','8',
  2048.                     '9','A','B','C','D','E','F'};
  2049.    char tempBuffer[10];
  2050.  
  2051.    temp = i;
  2052.    index = 0;
  2053.    while (temp >= 16){
  2054.       tempBuffer[index++] = hexTable[temp % 16];
  2055.       temp = temp / 16;
  2056.    }
  2057.    if (temp > 0)
  2058.       tempBuffer[index] = hexTable[temp];
  2059.  
  2060.    for (j=index;j>=0;j--)
  2061.       *sz++ = tempBuffer[j];
  2062.    *sz = '\0';
  2063.  
  2064.    return (szSav);
  2065. }/* DecToHex */
  2066.  
  2067.  
  2068. /*
  2069.  * Control the console output (VGA monitor).
  2070.  * mode = VGA
  2071.  *    VGA output to console.
  2072.  * mode = VIDEO
  2073.  *    Video output to console.
  2074.  *    At this time, the mouse input be disabled.
  2075.  *    If any button pressed, it will switch back to VGA output and
  2076.  *    the mouse input enabled again.
  2077.  */
  2078. void VideoVGASwitcher (mode)
  2079. int mode;
  2080. {
  2081.    if (WMpegSwitcher (mode))                         // cannot switch
  2082.       return;
  2083.  
  2084.    dspMode = mode;
  2085.  
  2086.    if (dspMode == VIDEO)
  2087.       SetMouseHook (hPanelWnd,IDM_MousePressed);     // disable mouse input
  2088.    else
  2089.       RemoveMouseHook ();                            // enable mouse input
  2090. }/* VideoVGASwitcher */
  2091.  
  2092.  
  2093. void FAR PASCAL TimerProc (hWnd,iMessage,wTimerID,dwSystemTime)
  2094. HWND hWnd;
  2095. UINT iMessage;
  2096. WORD wTimerID;
  2097. DWORD dwSystemTime;
  2098. {
  2099.    int rtn;
  2100.  
  2101.    rtn = WMpegTransfer ();
  2102.    if (demostop || !rtn){
  2103.       FreeTimer ();
  2104.       playing = FALSE;
  2105.       WMpegCommand (STP);
  2106.       if (!demostop){   // normal play to end
  2107.          if (selectCD)
  2108.             track_no++;
  2109.          if ((cdType == KARAOKE) && track_no <= nSongs){
  2110.             PostMessage (hPanelWnd,WM_COMMAND,IDM_PLAY,0L);
  2111.             return;
  2112.          }
  2113.  
  2114.          if (cdType == ALL){
  2115.             if (nFileIndex < nMpegFiles){
  2116.                nFileIndex++;
  2117.                PostMessage (hPanelWnd,WM_COMMAND,IDM_PLAY,0L);
  2118.                return;
  2119.             }else{
  2120.                nFileIndex = 1;
  2121.                preFile = 0;
  2122.             }
  2123.          }
  2124.  
  2125.          if (repeat)
  2126.             PostMessage (hPanelWnd,WM_COMMAND,IDM_PLAY,0L);
  2127.          else
  2128.             PostMessage (hPanelWnd,WM_COMMAND,IDM_STOP,0L);
  2129.       }else
  2130.          PostMessage (hPanelWnd,WM_COMMAND,IDM_STOP,0L);
  2131.       return;
  2132.    }
  2133.  
  2134.    if (rtn > 1){           // fatal error on MPEG chip
  2135.       switch (rtn){
  2136.          case EM_FFERR:
  2137.             WriteText (W1,(LPSTR)"Video FIFO Error");
  2138.             break;
  2139.          case EM_HAERR:
  2140.             WriteText (W1,(LPSTR)"Host access Error");
  2141.             break;
  2142.          case EM_BSERR:
  2143.             WriteText (W1,(LPSTR)"Decoding Error");
  2144.             break;
  2145.          case EM_SBERR:
  2146.             WriteText (W1,(LPSTR)"System Bus Error");
  2147.             break;
  2148.          case EM_VSYNCERR:
  2149.             WriteText (W1,(LPSTR)"VSync Error");
  2150.             break;
  2151.          case EE_EMPTY:
  2152.             WriteText (W1,(LPSTR)"Audio FIFO Empty");
  2153.             break;
  2154.          default:
  2155.             wsprintf (MesgStr,"%s system error",ProductName);
  2156.             WriteText (W1,MesgStr);
  2157.             break;
  2158.       }
  2159.       playing = FALSE;
  2160.       WMpegCommand (STP);
  2161.       FreeTimer ();
  2162.    }
  2163. }/* TimerProc */
  2164.  
  2165.  
  2166. void FreeTimer (void)
  2167. {
  2168.    if (TimerExist){
  2169.       KillTimer (hPanelWnd,idTimer);
  2170.       FreeProcInstance (lpfnTimerProc);
  2171.       TimerExist = FALSE;
  2172.    }
  2173. }/* FreeTimer */
  2174.