/*  VIDSAVER.C
 *
 *   VIDSAVER is a sample screen saver application. It moves a
 *   playing .AVI file around the screen.  It provides a variety of
 *   options for controlling movement and sound.
 *
 *   (C) Copyright Ron Wodaski 1992-1993.  All rights reserved.
 *
 *   This application was written and compiled using Microsoft C/C++
 *   version 7.0.
 * 
 *   You have a royalty-free right to use, modify, reproduce and 
 *   distribute the sample files (and/or any modified version) in 
 *   any way you find useful, provided that you agree that 
 *   the author, Ron Wodaski has no warranty obligations or liability 
 *   for any sample application files which are modified. 
 */

#include <windows.h> 
#include <mmsystem.h>
#include "vidsaver.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

/* Global used by SCRNSAVE.LIB. Required for all screen savers.
 */
char szAppName[40];


/* Globals specific to VIDSAVER.
 */
char szDIBName[] = "VideoDIB";
char szSpeedName[] = "Speed";
char szDelayName[] = "Delay between file play";
char szSDelayName[] = "Delay between moves";
char szMagnifyName[] = "Magnification";
char szChangeName[] = "Change frequency";
char szBlankitName[] = "Blank Screen";
char szMuteName[]= "Mute Audio";
char szRepeatName[]= "Repeat Play";
char szPlayFileName[]= "Filename to Play";
char szName[]="Bounce a Video";
char szSoundName[] = "Sound";

/* Externals defined in SCRNSAVE.LIB. Required for all screen savers.
 */
HINSTANCE _cdecl hMainInstance;
HWND _cdecl hMainWindow;
char _cdecl szName[TITLEBARNAMELEN];
char _cdecl szIsPassword[22];
char _cdecl szIniFile[MAXFILELEN];
char _cdecl szScreenSaver[22];
char _cdecl szPassword[16];
char _cdecl szDifferentPW[BUFFLEN];
char _cdecl szChangePW[30];
char _cdecl szBadOldPW[BUFFLEN];
char _cdecl szHelpFile[MAXFILELEN];
char _cdecl szNoHelpMemory[BUFFLEN];
UINT _cdecl MyHelpMessage;
HOOKPROC _cdecl fpMessageFilter;

BOOL bPassword;       // password protected?

WORD wMaxSpeed=25;					// Maximum # pixels per window move
int ChangeFreq=100;					// Determines how often change num pixels
char szReturnString[STRLEN];		// buffer for messages from mciSendString
char szWindowHandle[16];			// buffer for string of window handle
char szCommandString[STRLEN];		// buffer for MCI command strings
char szProgName[]="VideoSaver";	// Program name

char szFileToPlay[STRLEN];	 // Buffer for name of file to play.
char szWinTitle[STRLEN];	 // Buffer for playback window caption
char szPlayWidth[8];			 // Buffer for playback window width
char szPlayHeight[8];		 // Buffer for playback window height
long  wPlayWidth;				 // Playback window width
long  wPlayHeight;			 // Playback window height
WORD wMagnification=200;	 // Magnification factor
BOOL bMuteAudio=0;			 // Toggle for muting audio
BOOL bRepeatPlay=0;			 // Toggle for Continuous repeat
BOOL bBlankScreen=1;			 // Toggle for blanking screen
int wAdjWidth, wAdjHeight;	 // Difference between window/client area sizes
int wTop=0, wLeft=0;			 // X,Y coordinates for playback window create

HWND temp;
HWND hScrWnd;					// Handle for playback window
WNDCLASS wcScrApp;			// Class for playback window
FILE *FileOpen;				// File open pointer for fopen call
RECT lpScreen;					// For screen rectangle
RECT lpWindowSize;			// For playback window rectangle
RECT lpClientSize;			// For playback window client area rectangle
long wWidth, wHeight;		// Initial size of playback window

WORD wTimerShort;          // timer id for interval on window move
int ShortTime=100;			// default length of timer
WORD wTimerLong;           // timer id for interval on file play
int DelayTime=250;			// default length of timer
UINT PlayingTime=0;				// Length of AVI file in ms
HBITMAP hbmImage;                   // image handle
HANDLE hresWave;                    // handle to sound resource
LPSTR lpWave;                       // pointer to wave resource

/* Toggle for repainting during calls to MoveWindow() */
static BOOL RepaintToggle=FALSE;


/* ScreenSaverProc - Main entry point for screen saver messages.
 *  This function is required for all screen savers.
 *
 * Params:  Standard window message handler parameters.
 *
 * Return:  The return value depends on the message.
 *
 *  Note that all messages go to the DefScreenSaverProc(), except
 *  for ones we process.
 */
LONG FAR PASCAL ScreenSaverProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    RECT rc;						  // Rectangle for erasing background

    switch (msg)
    {
        case WM_CREATE:
        {
            /* Load the strings from the STRINGTABLE */
            GetIniEntries();

            /* Load the initial bounce settings. */
            GetIniSettings();

				srand((unsigned)time(NULL));  // Seed random # generation.

				/* Make default window size one-fourth screen size.  */
				GetWindowRect(GetDesktopWindow(),&lpScreen);
				wWidth  = (long)(lpScreen.right-lpScreen.left)/4;
				wHeight = (long)(lpScreen.bottom-lpScreen.top)/4;

				/* Create window class for playback. */
				wcScrApp.lpszClassName=szProgName;
				wcScrApp.hInstance    =hMainInstance;
				wcScrApp.lpfnWndProc  =WndProc;
				wcScrApp.hCursor      =LoadCursor(NULL,IDC_ARROW);
				wcScrApp.hIcon        =NULL;
				wcScrApp.lpszMenuName =NULL;
				wcScrApp.hbrBackground=CreateSolidBrush(RGB(255,255,255));
				wcScrApp.style        =CS_HREDRAW|CS_VREDRAW;
				wcScrApp.cbClsExtra   =0;
				wcScrApp.cbWndExtra   =0;
				if (!RegisterClass (&wcScrApp))
   				return FALSE;

				/* Create playback window. */
				hScrWnd=CreateWindow(szProgName,"VidSaver 0.1c",
                       (WS_POPUP), wLeft, wTop,
                       (int)wWidth,(int)wHeight, hWnd,(HMENU)NULL,
                       (HANDLE)hMainInstance,(LPSTR)NULL);

				/* Get sizes of Window & Client area for later calculations. */
				GetWindowRect(hScrWnd,&lpWindowSize);
				GetClientRect(hScrWnd,&lpClientSize);

				/* Setup for playback. */
				PlayingTime = SetupPlayback(hWnd, szFileToPlay);

				/* Set a timer for interval between playback window moves. */
	         wTimerShort=SetTimer(hWnd, ID_TIMER, ShortTime, NULL);

				if (FileOpen)
					{
		         MovePlayerRandom(hScrWnd);
					ShowWindow(hScrWnd,SW_SHOWNORMAL);

					/* Set a timer for the length of the file plus delay time * 10. */
		         wTimerLong=SetTimer(hScrWnd,ID_TIMER,PlayingTime+DelayTime*10, NULL);

					/* Play the AVI file! */
	   	      PlayFile(hScrWnd);
					}
	         return 0L;
        }

        case WM_TIMER:

				/* Short timer went off; move window to new location. */
				if (FileOpen)
			      MovePlayer(hScrWnd);
				else
					MovePlayer(temp);
		      return 0L;

        case WM_DESTROY:

				/* Clean up; we're out of here. */
				if (FileOpen)
					mciExecute("close AVIFile"); 
				/* Kill timer. */
		      if(wTimerShort) KillTimer(hWnd,ID_TIMER);
				/* Destroy window. */
				if (hScrWnd) DestroyWindow(hScrWnd);
				if (temp) DestroyWindow(temp);

            if( hbmImage ) DeleteObject(hbmImage);
            if( lpWave )   UnlockResource(hresWave);
            if( hresWave ) FreeResource(hresWave);
            sndPlaySound(NULL, 0);
            break;

        case WM_ERASEBKGND:
				if (bBlankScreen)
					{
	            GetClientRect(hWnd,&rc);
   	         FillRect((HDC)wParam,&rc,(HBRUSH)GetStockObject(BLACK_BRUSH));
					}
            return 0L;

        default:
            break;
        }
	/* If we don't handle message, pass it to default procedure. */
   return DefScreenSaverProc(hWnd, msg, wParam, lParam);
}

/* RegisterDialogClasses -- Entry point for registering window
 * classes required by configuration dialog box.
 *
 * Params:  hWnd -- Handle to window
 *
 * Return:  None
 */
BOOL RegisterDialogClasses(HINSTANCE hInst)
{
    return TRUE;
}


/* ScreenSaverConfigureDialog -- Dialog box function for configuration
 * dialog.
 *
 * Params:  hWnd -- Handle to window
 *
 * Return:  None
 */
BOOL FAR PASCAL ScreenSaverConfigureDialog(HWND hDlg,UINT msg,WPARAM wParam,LPARAM lParam)
{
  static HWND hIDOK;
  static HWND hSetPassword;

    switch (msg)
    {
        case WM_INITDIALOG:
            GetIniEntries();		// Load strings from table.
            GetIniSettings();		// Read from CONTROL.INI

				/* Set values in dialog box. */
            SetDlgItemInt(hDlg, ID_SPEED,   wMaxSpeed,      FALSE);
            SetDlgItemInt(hDlg, ID_BDELAY,  DelayTime,      TRUE );
            SetDlgItemInt(hDlg, ID_MDELAY,  ShortTime,      TRUE );
            SetDlgItemInt(hDlg, ID_MAGNIFY, wMagnification, TRUE );
            SetDlgItemInt(hDlg, ID_CLEVEL,  ChangeFreq,     TRUE );
			   SetDlgItemText(hDlg,ID_FNAME,    szFileToPlay);
            SendDlgItemMessage(hDlg, ID_BLANKIT, BM_SETCHECK, bBlankScreen, NULL);
            SendDlgItemMessage(hDlg, ID_MUTE,    BM_SETCHECK, bMuteAudio,   NULL);
            SendDlgItemMessage(hDlg, ID_CONT,    BM_SETCHECK, bRepeatPlay,  NULL);
            SendDlgItemMessage(hDlg, ID_PASSWORDPROTECTED, BM_SETCHECK,
                bPassword, NULL);
            hSetPassword=GetDlgItem(hDlg, ID_SETPASSWORD);
            EnableWindow(hSetPassword, bPassword);
            hIDOK=GetDlgItem(hDlg, IDOK);
            return TRUE;

        case WM_COMMAND:
            switch (wParam)
            {
                case IDOK:
						  /* User clicked OK button; put values into variables. */
                    wMaxSpeed      = GetDlgItemInt(hDlg, ID_SPEED,   NULL, FALSE );
                    DelayTime      = GetDlgItemInt(hDlg, ID_BDELAY,  NULL, TRUE  );
                    ShortTime      = GetDlgItemInt(hDlg, ID_MDELAY,  NULL, TRUE  );
                    wMagnification = GetDlgItemInt(hDlg, ID_MAGNIFY, NULL, TRUE  );
                    ChangeFreq     = GetDlgItemInt(hDlg, ID_CLEVEL,  NULL, TRUE  );
                    GetDlgItemText(hDlg,ID_FNAME,    szFileToPlay,   STRLEN);
                    bBlankScreen   = IsDlgButtonChecked(hDlg, ID_BLANKIT         );
                    bRepeatPlay    = IsDlgButtonChecked(hDlg, ID_CONT            );
                    bMuteAudio     = IsDlgButtonChecked(hDlg, ID_MUTE            );
                    bPassword      = IsDlgButtonChecked(hDlg, ID_PASSWORDPROTECTED);

						  /* Check the values we just loaded! */
						  VerifyIniSettings();

						  /* Put values into CONTROL.INI. */
                    WriteProfileInt(szAppName, szSpeedName,   wMaxSpeed      );
                    WriteProfileInt(szAppName, szDelayName,   DelayTime      );
                    WriteProfileInt(szAppName, szSDelayName,  ShortTime      );
                    WriteProfileInt(szAppName, szMagnifyName, wMagnification );
                    WriteProfileInt(szAppName, szChangeName,  ChangeFreq     );

						  WritePrivateProfileString(szAppName, szPlayFileName, szFileToPlay,
								 szIniFile);

                    WriteProfileInt(szAppName, szBlankitName, bBlankScreen   );
                    WriteProfileInt(szAppName, szMuteName,    bMuteAudio     );
                    WriteProfileInt(szAppName, szRepeatName,  bRepeatPlay     );
                    WriteProfileInt(szAppName, szIsPassword,  bPassword      );

						  /* Close dialog box. */
                    EndDialog(hDlg, TRUE);
                    return TRUE;

                case IDCANCEL:
						  /* Cancelling dialog box.  Save nothing and close. */
                    EndDialog(hDlg, FALSE);
                    return TRUE;

                case ID_SETPASSWORD:
                {
                    FARPROC fpDialog;
						  /* Get and set password. */
                	  if((fpDialog = MakeProcInstance(DlgChangePassword,hMainInstance)) == NULL)
                        return FALSE;
                    DialogBox(hMainInstance, MAKEINTRESOURCE(DLG_CHANGEPASSWORD), 
                              hDlg, fpDialog);
                    FreeProcInstance(fpDialog);
                    SendMessage(hDlg, WM_NEXTDLGCTL, hIDOK, 1l);
                    break;
                }

                case ID_PASSWORDPROTECTED:

						  /* Password protection enabled. */
                    bPassword ^= 1;
                    CheckDlgButton(hDlg, wParam, bPassword);
                    EnableWindow(hSetPassword, bPassword);
                    break;

                case ID_HELP:
DoHelp:
#if 0
                    bHelpActive=WinHelp(hDlg, szHelpFile, HELP_CONTEXT, IDH_DLG_BOUNCER);
                    if (!bHelpActive)
                        MessageBox(hDlg, szNoHelpMemory, szName, MB_OK);
#else
                    MessageBox(hDlg, "Insert your call to WinHelp() here.",
                        szName, MB_OK);
#endif
                    break;
            }
            break;
        default:
            if (msg==MyHelpMessage)     // Context sensitive help msg.
                goto DoHelp;
    }
    return FALSE;
}


/* GetIniSettings -- Get initial bounce settings from WIN.INI
 *
 * Params:  hWnd -- Handle to window
 *
 * Return:  None
 */
static void GetIniSettings()
{
	 /* Load initialization settings from CONTROL.INI. */
    wMaxSpeed = GetPrivateProfileInt(szAppName,szSpeedName,DEF_SPEED,szIniFile);
    DelayTime = GetPrivateProfileInt(szAppName,szDelayName,DEF_INIT_BDELAY,szIniFile);
    ShortTime = GetPrivateProfileInt(szAppName,szSDelayName,DEF_INIT_MDELAY,szIniFile);
    wMagnification = GetPrivateProfileInt(szAppName,szMagnifyName,DEF_INIT_MAGNIFY,
									 szIniFile);
    ChangeFreq = GetPrivateProfileInt(szAppName,szChangeName,DEF_INIT_CLEVEL,szIniFile);
    GetPrivateProfileString(szAppName, szPlayFileName, DEF_FNAME,szFileToPlay,  
									STRLEN, szIniFile);
    bBlankScreen = GetPrivateProfileInt(szAppName, szBlankitName,  DEF_BLANKIT,szIniFile);
    bMuteAudio = GetPrivateProfileInt(szAppName, szMuteName,     DEF_MUTE,szIniFile);
    bRepeatPlay = GetPrivateProfileInt(szAppName, szRepeatName,   DEF_CONT,szIniFile);
    bPassword = GetPrivateProfileInt(szAppName, szIsPassword,   FALSE, szIniFile);

	/* Check the values we just loaded! */
	VerifyIniSettings();
}

/* WriteProfileInt - Write an unsigned integer value to CONTROL.INI.
 *
 * Params:  name - szSection - [section] name in .INI file
 *                 szKey     - key= in .INI file
 *                 i         - value for key above
 *
 * Return:  None
 */
static void WriteProfileInt(LPSTR szSection, LPSTR szKey, int i) 
{
    char achBuf[40];

    /* write out as unsigned because GetPrivateProfileInt() can't
     * cope with signed values!
     */
    wsprintf(achBuf, "%u", i);
    WritePrivateProfileString(szSection, szKey, achBuf, szIniFile);
}

void GetIniEntries(void)
{
  //Load Common Strings from stringtable...
  LoadString(hMainInstance, idsIsPassword,   szIsPassword,   22        );
  LoadString(hMainInstance, idsIniFile,      szIniFile,      MAXFILELEN);
  LoadString(hMainInstance, idsScreenSaver,  szScreenSaver,  22        );
  LoadString(hMainInstance, idsPassword,     szPassword,     16        );
  LoadString(hMainInstance, idsDifferentPW,  szDifferentPW,  BUFFLEN   );
  LoadString(hMainInstance, idsChangePW,     szChangePW,     30        );
  LoadString(hMainInstance, idsBadOldPW,     szBadOldPW,     255       );
  LoadString(hMainInstance, idsHelpFile,     szHelpFile,     MAXFILELEN);
  LoadString(hMainInstance, idsNoHelpMemory, szNoHelpMemory, BUFFLEN   );
}

/* PlayFile - Play the AVI file.
 *
 * Params:  hWnd - Window used for playback. 
 *
 * Return:  None
 */
static void PlayFile(HWND hWnd)
{
	/* See if the file is open for playing. */
	if (FileOpen)
		{
		/* Go to first frame in file.
		mciExecute("seek AVIFile to 0"); 

		/* Construct a "put" command string for window and execute it. */
		strcpy(szReturnString,"put AVIFIle window at 0 0 ");
		strcat(szReturnString,szPlayWidth);
		strcat(szReturnString," ");
		strcat(szReturnString,szPlayHeight);
		mciExecute(szReturnString); 

		/* Construct a "put" command string for destination and execute it. */
		strcpy(szReturnString,"put AVIFIle destination at 0 0 ");
		strcat(szReturnString,szPlayWidth);
		strcat(szReturnString," ");
		strcat(szReturnString,szPlayHeight);
		mciExecute(szReturnString); 

		/* Play the file, either continuously or one time. */
		if (bRepeatPlay)
			mciExecute("play AVIFile window repeat"); 
		else
			mciExecute("play AVIFile from 0"); 
		}
}

/* MovePlayer - Move player (called when short timer goes off).
 *
 * Params:  hWnd - Window used for playback. 
 *
 * Return:  None
 */

/* Default values for horizontal and vertical increments for moves. */
static UINT Vinc=1;
static UINT Hinc=1;

static void MovePlayer(HWND hWindow)
{
	int Temp;			// Holder for temporary values.

	/* Toggles for defining current direction. */
	static BOOL Horizontal=TRUE, Vertical=TRUE;

	/* Get a random number. */
	Temp = rand();
	/* If mod zero, time to change direction. */
	if (Temp % ChangeFreq == 0)
		{
		/* Change vectors. */
		Horizontal = !Horizontal;
		Temp = rand();
		Hinc = (Temp % wMaxSpeed)+1;
		}
	/* Get a random number. */
	Temp = rand();
	/* If mod zero, time to change direction. */
	if (Temp % ChangeFreq == 0)
		{
		/* Change vectors. */
		Vertical = !Vertical;
		Temp = rand();
		Vinc = (Temp % wMaxSpeed)+1;
		}

	/* Now that we have established direction and amount, apply them! */
	if (Vertical)
		wTop += Vinc;
	else
		wTop -= Vinc;
	if (Horizontal)
		wLeft += Hinc;
	else
		wLeft -= Hinc;

	/* Make sure we haven't wandered off of the screen. */
	if (wLeft <= 0)
		{
		wLeft = 1;
		Horizontal = !Horizontal;
		}
	if (wTop <= 0)
		{
		wTop = 1;
		Vertical = !Vertical;
		}

	if (wTop  > (lpScreen.bottom-((int)wPlayHeight+wAdjHeight)))
		{
		wTop = lpScreen.bottom-((int)wPlayHeight+wAdjHeight);
		Vertical = !Vertical;
		}
	if (wLeft > (lpScreen.right-((int)wPlayWidth+wAdjWidth)))
		{
		Horizontal = !Horizontal;
		wLeft = lpScreen.right-((int)wPlayWidth+wAdjWidth);
		}

	/* Are we working with a blank screen or not? */
	if (bBlankScreen)
		SetWindowPos(hWindow,HWND_TOP,wLeft,wTop,(int)wPlayWidth+wAdjWidth,(int)wPlayHeight+
							 wAdjHeight,SWP_NOSIZE|SWP_NOZORDER);
	else
		MoveWindow(hWindow,wLeft,wTop,(int)wPlayWidth+wAdjWidth,(int)wPlayHeight+wAdjHeight, 
								RepaintToggle);
}

/* MovePlayerRandom - Move player to a random screen location.
 *
 * Params:  hWnd - Window used for playback. 
 *
 * Return:  None
 */
static void MovePlayerRandom(HWND hWindow)
{
	/* Get new coordinates. */
	wTop = rand();
	wLeft = rand();

	/* Check to see if new coordinates are within screen; do again if not. */
	while (wTop  > (lpScreen.bottom-(int)wPlayHeight-45))
		wTop = rand();
	while (wLeft > (lpScreen.right-(int)wPlayWidth-25)) 
		wLeft = rand();

	/* Move Window; method depends on whether we are blanking screen. */
	if (bBlankScreen)
		SetWindowPos(hWindow,HWND_TOP,wLeft,wTop,(int)wPlayWidth+wAdjWidth,(int)wPlayHeight+
				wAdjHeight,SWP_NOZORDER);
	else
		MoveWindow(hWindow,wLeft,wTop,(int)wPlayWidth+wAdjWidth,(int)wPlayHeight+wAdjHeight,
				RepaintToggle);

}

/* WndProc - Default procedure for playback window.
 *
 */
LONG FAR PASCAL WndProc(HWND hWindow,UINT messg,
                        WPARAM wParam,LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;
	TEXTMETRIC tm;

	char szMessage[]="File not found:";
	static short CharHeight;

	switch (messg)
	{
		case WM_CREATE:
			hdc = GetDC(hWindow);
			GetTextMetrics(hdc, &tm);
			CharHeight = tm.tmHeight;
			ReleaseDC(hWindow, hdc);
			break;

		case WM_PAINT:
			hdc=BeginPaint(hWindow,&ps);

			// Put anything you want to display here.

			if (!FileOpen)
				{
				PlaceBitmap(hWindow);
				PlaySoundResource();
				
				SetTextAlign(hdc,TA_CENTER);

				TextOut(hdc, 160, 187, szMessage, strlen(szMessage));
				TextOut(hdc, 160, 187+CharHeight, szFileToPlay, strlen(szFileToPlay));
				}

			ValidateRect(hWindow,NULL);
			EndPaint(hWindow,&ps);
			break;

		case WM_TIMER:
			if (!bRepeatPlay)
				/* Timer went off; play AVI file again. */
				PlayFile(hScrWnd);
	      return 0L;
			break;

    case WM_DESTROY:
	      if(wTimerLong)  KillTimer(hScrWnd,ID_TIMER);
      	PostQuitMessage(0);
      	break;
    default:
      	return(DefWindowProc(hWindow,messg,wParam,lParam));
  }
  return(0L);
}

// HDC hDC                            // Handle to our window DC

void PlaceBitmap (HWND hWindow)
{
	HDC hDC;
	HDC hMemDC;                         // Handle to a memory DC
	BITMAP bm;                          // Bitmap info
	HBITMAP hbmOld;

	hDC = GetDC(hWindow);
	hbmImage = LoadBitmap(hMainInstance, szDIBName);

	/* Get bitmap size
	 */
	GetObject(hbmImage, sizeof(bm), (LPSTR)&bm);

	hMemDC = CreateCompatibleDC(hDC);
	hbmOld = SelectObject(hMemDC, hbmImage);

	if(hbmOld)
		{
		/* Blit the image in the new position
		 */
		BitBlt(hDC,                        // dest DC
			0,0,                        // dest origin
			bm.bmWidth,bm.bmHeight,     // dest extents
			hMemDC,                     // src DC
			0,0,                        // src origin
			SRCCOPY );                  // ROP code

		SelectObject(hMemDC, hbmOld);
		DeleteDC(hMemDC);
   	ReleaseDC(hWindow, hDC);
		}

}

void PlaySoundResource(void)
{
   /* Load, lock, and play the sound resource
    */
   HANDLE hResInfo;

   if( hResInfo = FindResource(hMainInstance, "Sound", "WAVE") )
   {
       if( hresWave = LoadResource(hMainInstance, hResInfo) )
       {
           lpWave = LockResource(hresWave);
			  if (lpWave)
				  sndPlaySound(lpWave, SND_ASYNC | SND_MEMORY);
       }
   }
}

/* SetupPlayback - Set up the Playback window and perform file housekeeping.
 *
 * Params:  AVIFile - name of AVI file to open and set up.
 *
 * Return:  Unsigned integer - Playing time in milliseconds.
 */
UINT SetupPlayback(HWND hWnd, char * AVIFile)
{
	DWORD Result;
	UINT FrameRate, FrameTotal;
	char *tempchar;
	char szMessage[]="  AVI playback file not found:  ";

	/* Verify that file exists. */
	FileOpen = fopen(AVIFile, "r");

	if (FileOpen)
		{
		fclose(FileOpen);

		/* Get string copy of window handle. */
		_itoa(hScrWnd, szWindowHandle, 10);
	
		/* Get file info. */
		strcpy(szCommandString,"open ");
		strcat(szCommandString,AVIFile);
		strcat(szCommandString," style child parent ");
		strcat(szCommandString,szWindowHandle);
		strcat(szCommandString," alias AVIFile");
		mciExecute(szCommandString);
		mciExecute("set AVIFile time format frames");
		if (bMuteAudio)
			mciExecute("setaudio AVIFile off");
		
		/* Get size of frame. */
		Result = mciSendString("where AVIFile window",szReturnString,1024,0);
		tempchar = strtok(szReturnString," ");
		tempchar = strtok(NULL," ");
		tempchar = strtok(NULL," ");
		strcpy(szPlayWidth,tempchar);
		tempchar = strtok(NULL," ");
		strcpy(szPlayHeight,tempchar);

		/* Put width and height into integers. */
		wPlayWidth  = atol(szPlayWidth);
		wPlayHeight = atol(szPlayHeight);

		/* Apply magnification factor. */
		wPlayWidth  = (wPlayWidth  * wMagnification)/100;
		wPlayHeight = (wPlayHeight * wMagnification)/100;

		/* Check to make sure image isn't too big for screen! */
		if (wPlayWidth > (wWidth * 3))
			wPlayWidth = wWidth * 3;
		if (wPlayHeight > wHeight * 3)
			wPlayHeight = wHeight * 3;

		/* Put width and hieght back into strings. */
		_ltoa(wPlayWidth,  szPlayWidth, 10);
		_ltoa(wPlayHeight, szPlayHeight, 10);

		/* Resize window to fit frame size. */
		wAdjWidth = (lpWindowSize.right-lpWindowSize.left) - (lpClientSize.right-
				lpClientSize.left);
		wAdjHeight = (lpWindowSize.bottom-lpWindowSize.top) - (lpClientSize.bottom-
				lpClientSize.top);

		mciSendString("status AVIFile length",szReturnString,1024,0);
		FrameTotal = (UINT)atoi(szReturnString);
	
		mciSendString("status AVIFile nominal frame rate",szReturnString,1024,0);
		FrameRate = (UINT)(atoi(szReturnString))/1000;
		return (UINT)(FrameTotal/FrameRate)*1000;

		}
	else
		{

		wPlayWidth  = 320L;
		wPlayHeight = 240L;
		RepaintToggle = TRUE;

		/* Create new playback window as overlapped. */
		temp=CreateWindow(szProgName,"Video Saver Error",
					(WS_OVERLAPPED), wLeft, wTop,
					(int)wPlayWidth, (int)wPlayHeight, hWnd, (HMENU)NULL,
					(HANDLE)hMainInstance, (LPSTR)NULL);

		/* Get sizes of Window & Client area for later calculations. */
		GetWindowRect(temp,&lpWindowSize);
		GetClientRect(temp,&lpClientSize);
		wAdjWidth = (lpWindowSize.right-lpWindowSize.left) - (lpClientSize.right-
				lpClientSize.left);
		wAdjHeight = (lpWindowSize.bottom-lpWindowSize.top) - (lpClientSize.bottom-
				lpClientSize.top);

		/* Setup for playback. */
		MovePlayerRandom(temp);
		ShowWindow(temp,SW_SHOWNORMAL);
		return 1;
		}
}

void VerifyIniSettings(void)
{
	/* Make sure that all settings have valid values. */
	if (wMagnification < 10)
		wMagnification = 100;
	if (wMaxSpeed < 1 || wMaxSpeed > 25)
		wMaxSpeed = 5;
	if (ShortTime < 10)
		ShortTime = 10;
	if (DelayTime < 5)
		DelayTime = 5;
	if (ChangeFreq < 5)
		ChangeFreq = 25;
}
