// ------------------------------------------------------------------
// $$root$$.cpp : Defines the entry point for the application.
// ------------------------------------------------------------------

// ------------------------------------------------------------------
// Generated by the CDX Application Wizard for CDX 3.0
// By: Michael Rich [mike@alphax86.com, http://www.alphax86.com]
//
// Modified: May 29, 2000 for CDX 3.0 Compatiblity
//
// With valuable help from:
//   Ioannis Karagiorgos, for the debugging help
//   Bil Simser, for the good ideas and constructive criticism
// ------------------------------------------------------------------

#define WIN32_LEAN_AND_MEAN

$$IF(DX3)
// this define is necessary to force
// CDX to use DirectX 3.0 (WinNT) interfaces
#define NTDX3

$$ENDIF
#include <windows.h>
#define CDXINCLUDEALL     // this define includes all headers, otherwise include one by one
#include <cdx.h>

#include "resource.h"

// ------------------------------------------------------------------
// Global Variables
// ------------------------------------------------------------------
char        szAppName[]     = "$$APP_TITLE$$";
char        szClassName[]   = "$$Safe_root$$WndClass";

HINSTANCE   g_hInst;			        // instance handle
HWND        g_hWnd;				        // window handle

$$IF(COOP_BOTH)
$$IF(COOP_ST_FS)
BOOL        g_bFullScreen   = TRUE;	    // running fullscreen?
$$ELIF(COOP_ST_WIN)
BOOL        g_bFullScreen   = FALSE;	// running fullscreen?
$$ENDIF
$$ENDIF
$$IF(LOOSEFOCUS)
BOOL        g_IsAppActive;			    // is the app active
$$ENDIF

// ------------------------------------------------------------------
// CDX Objects
// ------------------------------------------------------------------
CDXScreen   * Screen    = 0;	    // The screen object, every program must have one
$$IF(SPLASH)
CDXSurface  * Splash    = 0;        // splash screen surface
$$ENDIF
$$IF(MAINMENU)
CDXSurface  * MainMenu  = 0;        // Main menu object
$$ENDIF
$$IF(INPUT_CDXINPUT)
CDXInput    * Input     = 0;        // The input object
$$ENDIF

// ------------------------------------------------------------------
// Forward declarations
// ------------------------------------------------------------------
$$IF(COOP_BOTH)
static void AdjustWinStyle();
$$ENDIF
$$IF(CENTERWINDOW)
static void CenterWindow();
$$ENDIF


// ------------------------------------------------------------------
// cdx_Init - handles initialization of the CDX objects
// ------------------------------------------------------------------
BOOL cdx_Init()
{
	// Create the CDXSreen object
	Screen = new CDXScreen();
	if (Screen==NULL)
        CDXError( NULL , "Could not create CDXScreen object" );

$$IF(COOP_FS)
$$IF(TRIPLEBUFF)
	// enable triple buffering
	Screen->SetTripleBuffering(TRUE);

$$ENDIF
	// start app fullscreen
$$IF(8BIT)
	if (FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, $$BPP$$)))
        CDXError( Screen , "Could not set video mode $$WIDTH$$x$$HEIGHT$$x$$BPP$$" );
$$ENDIF
$$IF(15BIT)
    if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 15 ) == TRUE )
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 15)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x15 video mode" );
    }
    else
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 16)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x16 video mode" );
    }
$$ENDIF
$$IF(16BIT)
    if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 16 ) == TRUE )
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 16)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x16 video mode" );
    }
    else
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 15)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x15 video mode" );
    }
$$ENDIF
$$IF(24BIT)
    if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 24 ) == TRUE )
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 24)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x24 video mode" );
    }
    else
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 32)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x32 video mode" );
    }
$$ENDIF
$$IF(32BIT)
    if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 32 ) == TRUE )
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 32)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x32 video mode" );
    }
    else
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 24)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x24 video mode" );
    }
$$ENDIF
$$ELIF(COOP_WIN)
	// start app in a window
	if (FAILED(Screen->CreateWindowed(g_hWnd, $$WIDTH$$, $$HEIGHT$$)))
        CDXError( Screen , "Could not set windowed mode $$WIDTH$$x$$HEIGHT$$" );
$$ELSE
$$IF(COOP_ST_FS)
$$IF(TRIPLEBUFF)
	// enable triple buffering
	Screen->SetTripleBuffering(TRUE);

$$ENDIF
	// start app fullscreen
$$IF(8BIT)
	if (FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, $$BPP$$))) 
        CDXError( Screen , "Could not set video mode $$WIDTH$$x$$HEIGHT$$x$$BPP$$" );
$$ENDIF
$$IF(15BIT)
    if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 15 ) == TRUE )
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 15)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x15 video mode" );
    }
    else
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 16)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x16 video mode" );
    }
$$ENDIF
$$IF(16BIT)
    if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 16 ) == TRUE )
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 16)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x16 video mode" );
    }
    else
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 15)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x15 video mode" );
    }
$$ENDIF
$$IF(24BIT)
    if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 24 ) == TRUE )
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 24)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x24 video mode" );
    }
    else
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 32)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x32 video mode" );
    }
$$ENDIF
$$IF(32BIT)
    if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 32 ) == TRUE )
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 32)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x32 video mode" );
    }
    else
    {
        if(FAILED(Screen->CreateFullScreen(g_hWnd, $$WIDTH$$, $$HEIGHT$$, 24)))
            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x24 video mode" );
    }
$$ENDIF
$$ELSE
	// start app in a window
	if (FAILED(Screen->CreateWindowed(g_hWnd, $$WIDTH$$, $$HEIGHT$$))) 
        CDXError( Screen , "Could not set windowed mode $$WIDTH$$x$$HEIGHT$$" );
$$ENDIF

$$ENDIF

$$IF(SPLASH)
$$IF(8BIT)
	// use the palette as defined in the splash screen
	if(FAILED(Screen->LoadPalette("SPLASH")))
        CDXError( Screen , "Could not load palette from file SPLASH" );

$$ENDIF
	// load the splash screen
	Splash = new CDXSurface( );
    if(FAILED(Splash->Create( Screen , "SPLASH" )))
        CDXError( Screen , "Could not load file SPLASH into surface" );

$$ENDIF
$$IF(INPUT_CDXINPUT)
	// create our input object
	Input = new CDXInput( );
	if( Input  ==  NULL ) 
        CDXError( Screen , "Could not create CDXInput object" );

	// Create input devices
	if(FAILED(Input->Create( g_hInst , g_hWnd )))
        CDXError( Screen , "Could not create direct input object" );
$$ENDIF

	// TODO: Initialize your own CDX objects here
	
	return TRUE;
}



// ------------------------------------------------------------------
// cdx_DeInit - handles cleanup of CDX objects
// ------------------------------------------------------------------
void cdx_DeInit( void )
{
	// TODO: Destroy your CDX objects here

$$IF(SPLASH)
	SAFEDELETE( Splash );
$$ENDIF
$$IF(INPUT_CDXINPUT)
	SAFEDELETE( Input );	
$$ENDIF
	SAFEDELETE( Screen );
}



// ------------------------------------------------------------------
// cdx_DoFrame - performs drawing of the current frame
// ------------------------------------------------------------------
void cdx_DoFrame()
{
$$IF(INPUT_CDXINPUT)
	// read input from devices
	Input->Update();

	// handle keyboard input	

	// if Escape is pressed, close the application
	if (Input->GetKeyState(CDXKEY_ESCAPE)==CDXKEY_PRESS)
	{
		SendMessage(g_hWnd, WM_CLOSE, 0, 0);
		// return out as the code below is invalid now
		return;
	}

$$IF(COOP_BOTH)
	// Alt+Enter switches modes
	if (((Input->GetKeyState(CDXKEY_LEFTALT)==CDXKEY_PRESS ||
		Input->GetKeyState(CDXKEY_LEFTALT)==CDXKEY_REPEAT) ||
		(Input->GetKeyState(CDXKEY_RIGHTALT)==CDXKEY_PRESS ||
		Input->GetKeyState(CDXKEY_RIGHTALT)==CDXKEY_REPEAT)) &&
		(Input->GetKeyState(CDXKEY_ENTER)==CDXKEY_PRESS ||
		Input->GetKeyState(CDXKEY_ENTER)==CDXKEY_REPEAT))
	{
		g_bFullScreen = !g_bFullScreen;
		if(g_bFullScreen)
		{
			AdjustWinStyle();
			// we need to destroy and recreate the supporting CDX objects
			// that can't survive intact when we switch back to fullscreen mode
			{
				// TODO: add your own CDX objects that would have to be destroyed
				// on a mode switch (they will be recreated below)
$$IF(SPLASH)

				SAFEDELETE(Splash);
$$ENDIF
			}
$$IF(TRIPLEBUFF)
			// enable triple buffering
			Screen->SetTripleBuffering(TRUE);
$$ENDIF
$$IF(8BIT)
        	if (FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, $$BPP$$)))
                CDXError( Screen , "Could not set video mode $$WIDTH$$x$$HEIGHT$$x$$BPP$$" );
$$ENDIF
$$IF(15BIT)
            if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 15 ) == TRUE )
            {
                if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 15)))
                    CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x15 video mode" );
            }
            else
            {
                if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 16)))
                    CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x16 video mode" );
            }
$$ENDIF
$$IF(16BIT)
            if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 16 ) == TRUE )
            {
                if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 16)))
                    CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x16 video mode" );
            }
            else
            {
                if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 15)))
                    CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x15 video mode" );
            }
$$ENDIF
$$IF(24BIT)
            if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 24 ) == TRUE )
            {
                if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 24)))
                    CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x24 video mode" );
            }
            else
            {
                if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 32)))
                    CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x32 video mode" );
            }
$$ENDIF
$$IF(32BIT)
            if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 32 ) == TRUE )
            {
                if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 32)))
                    CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x32 video mode" );
            }
            else
            {
                if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 24)))
                    CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x24 video mode" );
            }
$$ENDIF
			{
				// TODO: recreate your CDX objects that were destroyed above
$$IF(SPLASH)
$$IF(8BIT)

				// load the palette back up
				if(FAILED(Screen->LoadPalette("SPLASH")))
                    CDXError( Screen , "Could not set video mode $$WIDTH$$x$$HEIGHT$$x$$BPP$$" );
$$ENDIF

				// re-load the splash screen
               	Splash = new CDXSurface( );
                if(FAILED(Splash->Create( Screen , "SPLASH" )))
                    CDXError( Screen , "Could not load file SPLASH into surface" );
$$ENDIF
			}
		}
		else
		{
			Screen->GetDD()->RestoreDisplayMode();
			AdjustWinStyle();
			// we need to destroy and recreate the supporting CDX objects
			// that can't survive intact when we switch back to windowed mode
			{
				// TODO: add your own CDX objects that would have to be destroyed
				// on a mode switch (they will be recreated below)
$$IF(SPLASH)

				SAFEDELETE(Splash);
$$ENDIF
			}
			// Zero forces windowed mode
			if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 0 )))
                CDXError( Screen , "Could not set windowed mode $$WIDTH$$x$$HEIGHT$$" );
			{
				// TODO: recreate your CDX objects that were destroyed above
$$IF(SPLASH)
$$IF(8BIT)

				// load the palette back up
				if(FAILED(Screen->LoadPalette("SPLASH")))
                    CDXError( Screen , "Could not set video mode $$WIDTH$$x$$HEIGHT$$x$$BPP$$" );

$$ENDIF

				// re-load the splash screen
               	Splash = new CDXSurface( );
                if(FAILED(Splash->Create( Screen , "SPLASH" )))
                    CDXError( Screen , "Could not load file SPLASH into surface" );
$$ENDIF
			}
$$IF(CENTERWINDOW)

			CenterWindow();
$$ENDIF
		}
		// clear any data from the keyboard
		Input->FlushKeyboardData();
	}
$$ENDIF
		
	// TODO: Add your own code to handle the Mouse
	// and the joystick

$$ENDIF

	// clear the current frame
	Screen->GetBack()->Fill(0);
$$IF(SPLASH)

	// draw the splash screen
	Splash->DrawBlk(Screen->GetBack(), 0, 0);

$$ENDIF
	// TODO: Add code to draw your objects during each frame

	Screen->Flip();	 // Flip the back buffer to the front
}
$$IF(CENTERWINDOW)

// ------------------------------------------------------------------
// CenterWindow - centers the window on the screen
// ------------------------------------------------------------------
static void CenterWindow()
{
	RECT r;
	int sx, sy;

	GetWindowRect(g_hWnd, &r);

	sx = GetSystemMetrics(SM_CXFULLSCREEN);
	sy = GetSystemMetrics(SM_CYFULLSCREEN);

	SetWindowPos(g_hWnd, NULL, (sx-(r.right-r.left))/2, (sy-(r.bottom-r.top))/2, 0,
		0, SWP_NOSIZE | SWP_NOZORDER |
		SWP_NOACTIVATE);
}
$$ENDIF
$$IF(!COOP_FS)

// ------------------------------------------------------------------
// AdjustWinStyle - adjusts the window style according to the mode
// ------------------------------------------------------------------
static void AdjustWinStyle()
{
$$IF(COOP_WIN)
	RECT        rect = {0, 0, $$WIDTH$$, $$HEIGHT$$};
	DWORD       dwStyle;

	// Change window attributes

	dwStyle = GetWindowStyle(g_hWnd);
	dwStyle &= ~WS_POPUP;
	dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU;

	SetWindowLong(g_hWnd, GWL_STYLE, dwStyle);

	// Resize the window so that the client area is $$WIDTH$$x$$HEIGHT$$

	AdjustWindowRectEx(&rect, GetWindowStyle(g_hWnd), GetMenu(g_hWnd) != NULL,
		GetWindowExStyle(g_hWnd));

	// Just in case the window was moved off the visible area of the
	// screen.

	SetWindowPos(g_hWnd, NULL, 0, 0, rect.right-rect.left,
		rect.bottom-rect.top, SWP_NOMOVE | SWP_NOZORDER |
		SWP_NOACTIVATE);

	SetWindowPos(g_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
		SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
$$ELSE
	if (g_bFullScreen)  // In fullscreen mode the window must cover the whole desktop
	{
		DWORD       dwStyle;

		// Change window attributes

		dwStyle = WS_POPUP | WS_VISIBLE;

		SetWindowLong(g_hWnd, GWL_STYLE, dwStyle);

		SetWindowPos(g_hWnd, HWND_TOPMOST, 0, 0, GetSystemMetrics(SM_CXFULLSCREEN),
			GetSystemMetrics(SM_CYFULLSCREEN), SWP_NOACTIVATE |
			SWP_NOZORDER);
	}
	else
	{
		RECT        rect = {0, 0, $$WIDTH$$, $$HEIGHT$$};
		DWORD       dwStyle;

		// Change window attributes

		dwStyle = GetWindowStyle(g_hWnd);
		dwStyle &= ~WS_POPUP;
		dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU;

		SetWindowLong(g_hWnd, GWL_STYLE, dwStyle);

		// Resize the window so that the client area is $$WIDTH$$x$$HEIGHT$$

		AdjustWindowRectEx(&rect, GetWindowStyle(g_hWnd), GetMenu(g_hWnd) != NULL,
			GetWindowExStyle(g_hWnd));

		// Just in case the window was moved off the visible area of the
		// screen.

		SetWindowPos(g_hWnd, NULL, 0, 0, rect.right-rect.left,
			rect.bottom-rect.top, SWP_NOMOVE | SWP_NOZORDER |
			SWP_NOACTIVATE);

		SetWindowPos(g_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0,
			SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
	}
$$ENDIF
}
$$ENDIF



// ------------------------------------------------------------------
// WinProc - handles application messages
// ------------------------------------------------------------------
static long PASCAL WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message)
	{
$$IF(LOOSEFOCUS)
		case WM_ACTIVATEAPP:    g_IsAppActive = wParam;     // set if app is active or not
			                    return 0;
$$ENDIF
$$IF(INPUT_KEYDOWN)

		case WM_KEYDOWN:	switch(wParam)
			                {
			                    case VK_ESCAPE:         // if ESC key is hit, quit program
				                SendMessage(hWnd, WM_CLOSE, 0, 0);
				                break;
			                }
			                return  0;
$$IF(COOP_BOTH)

		case WM_SYSKEYUP:	if (wParam == VK_RETURN)    // Alt+Enter switches modes
			                {
				                g_bFullScreen = !g_bFullScreen;
				                if( g_bFullScreen )
				                {
					                AdjustWinStyle();
					                // we need to destroy and recreate the supporting 
                                    // CDX objects that can't survive intact when 
                                    // we switch back to fullscreen mode
                                    {
						                // TODO: add your own CDX objects that would 
                                        // have to be destroyed on a mode switch 
                                        // (they will be recreated below)
$$IF(SPLASH)

						                SAFEDELETE(Splash);
$$ENDIF
					                }
$$IF(TRIPLEBUFF)
					                // enable triple buffering
					                Screen->SetTripleBuffering(TRUE);
$$ENDIF
$$IF(8BIT)
                                	if (FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, $$BPP$$)))
                                        CDXError( Screen , "Could not set video mode $$WIDTH$$x$$HEIGHT$$x$$BPP$$" );
$$ENDIF 
$$IF(15BIT)
                                    if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 15 ) == TRUE )
                                    {
                                        if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 15)))
                                            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x15 video mode" );
                                    }
                                    else
                                    {
                                        if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 16)))
                                            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x16 video mode" );
                                    }
$$ENDIF
$$IF(16BIT)
                                    if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 16 ) == TRUE )
                                    {
                                        if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 16)))
                                            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x16 video mode" );
                                    }
                                    else
                                    {
                                        if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 15)))
                                            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x15 video mode" );
                                    }
$$ENDIF
$$IF(24BIT)
                                    if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 24 ) == TRUE )
                                    {
                                        if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 24)))
                                            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x24 video mode" );
                                    }
                                    else
                                    {
                                        if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 32)))
                                            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x32 video mode" );
                                    }
$$ENDIF
$$IF(32BIT)
                                    if( Screen->CheckIfVideoModeExists( $$WIDTH$$ , $$HEIGHT$$ , 32 ) == TRUE )
                                    {
                                        if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 32)))
                                            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x32 video mode" );
                                    }
                                    else
                                    {
                                        if(FAILED(Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 24)))
                                            CDXError( Screen , "Could not set $$WIDTH$$x$$HEIGHT$$x24 video mode" );
                                    }
$$ENDIF

					                {
						                // TODO: recreate your CDX objects that
                                        // were destroyed above
$$IF(SPLASH)
$$IF(8BIT)

										// load the palette back up
										if(FAILED(Screen->LoadPalette("SPLASH")))
											CDXError( Screen , "Could not set video mode $$WIDTH$$x$$HEIGHT$$x$$BPP$$" );
$$ENDIF
										// re-load the splash screen
               							Splash = new CDXSurface( );
										if(FAILED(Splash->Create( Screen , "SPLASH" )))
											CDXError( Screen , "Could not load file SPLASH into surface" );
$$ENDIF
					                }
				                }
				                else
				                {
					                Screen->GetDD()->RestoreDisplayMode();
					                AdjustWinStyle();
					                // we need to destroy and recreate the supporting 
                                    // CDX objects that can't survive intact when 
                                    // we switch back to windowed mode
					                {
						                // TODO: add your own CDX objects that would 
                                        // have to be destroyed on a mode switch 
                                        // (they will be recreated below)
$$IF(SPLASH)
					                    SAFEDELETE(Splash);
$$ENDIF
				                    }
									// Zero forces windowed mode
				                    Screen->ChangeVideoMode($$WIDTH$$, $$HEIGHT$$, 0);
				                    {
					                    // TODO: recreate your CDX objects that 
                                        // were destroyed above
$$IF(SPLASH)
$$IF(8BIT)

										// load the palette back up
										if(FAILED(Screen->LoadPalette("SPLASH")))
											CDXError( Screen , "Could not set video mode $$WIDTH$$x$$HEIGHT$$x$$BPP$$" );
$$ENDIF
										// re-load the splash screen
               							Splash = new CDXSurface( );
										if(FAILED(Splash->Create( Screen , "SPLASH" )))
											CDXError( Screen , "Could not load file SPLASH into surface" );
$$ENDIF
				                    }
$$IF(CENTERWINDOW)

									CenterWindow();
$$ENDIF

			                    }
			                    return 0;
                            }
                            return 1;
$$ENDIF
$$ENDIF
$$IF(MOUSEON)
		
		case WM_SETCURSOR:  SetCursor(NULL);    // hide the mouse cursor
                			return 1;
$$ENDIF
		case WM_CLOSE:		cdx_DeInit();

		case WM_DESTROY:	PostQuitMessage(0);
		                    return 0;

		default:        	return DefWindowProc(hWnd, message, wParam, lParam);
	}
}



$$IF(CHGEXEDIR)
// ------------------------------------------------------------------
// ChangeToEXEDir - sets CWD to the DIR the EXE is in
// ------------------------------------------------------------------
static void ChangeToEXEDir()
{
	char buf[MAX_PATH];
	char *cptr;

	//now change the directory
	//to make sure were accessing the proper file
	GetModuleFileName(NULL, buf, MAX_PATH);

	//move pointer to end of string
	cptr = buf + lstrlen(buf);

	//find the end of the path
	do
	{
		cptr--;
	} while (*cptr != '\\');
	cptr++;
	*cptr='\0';

	//change directory
	SetCurrentDirectory(buf);
}

$$ENDIF


// ------------------------------------------------------------------
// InitApp - Create the window and the CDX objects
// ------------------------------------------------------------------
static BOOL InitApp(int nCmdShow)
{
	WNDCLASS WndClass;

	WndClass.style = CS_HREDRAW | CS_VREDRAW;
	WndClass.lpfnWndProc = WinProc;
	WndClass.cbClsExtra = 0;
	WndClass.cbWndExtra = 0;
	WndClass.hInstance = g_hInst;
	WndClass.hIcon = LoadIcon(g_hInst, "APPICON");
	WndClass.hCursor = LoadCursor(0, IDC_ARROW);
	WndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	WndClass.lpszMenuName = 0;
	WndClass.lpszClassName = szClassName;
	RegisterClass(&WndClass);

	g_hWnd = CreateWindowEx(
$$IF(COOP_FS)
		WS_EX_TOPMOST,
$$ELIF(COOP_WIN)
		0,
$$ELSE
$$IF(COOP_ST_FS)
		WS_EX_TOPMOST,
$$ELSE
		0,
$$ENDIF
$$ENDIF
		szClassName,
		szAppName,
$$IF(COOP_FS)
 		WS_POPUP,
$$ELIF(COOP_WIN)
 		WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
$$ELSE
$$IF(COOP_ST_FS)
 		WS_POPUP,
$$ELSE
 		WS_OVERLAPPED | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
$$ENDIF
$$ENDIF
		0,
		0,
$$IF(COOP_FS)
		GetSystemMetrics(SM_CXFULLSCREEN),
		GetSystemMetrics(SM_CYFULLSCREEN),
$$ELIF(COOP_WIN)
		320,
		240,
$$ELSE
$$IF(COOP_ST_FS)
		GetSystemMetrics(SM_CXFULLSCREEN),
		GetSystemMetrics(SM_CYFULLSCREEN),
$$ELSE
		320,
		240,
$$ENDIF
$$ENDIF
		NULL,
		NULL,
		g_hInst,
		NULL);

    // when hWnd = -1 there was an error creating the main window
    // CDXError needs a CDXScreen object, if there is none at this early
    // program stage, pass it NULL
	if( !g_hWnd ) 
        CDXError( NULL , "could not create the main window" );

$$IF(COOP_WIN)
	AdjustWinStyle();
$$ELIF(COOP_BOTH)
$$IF(COOP_ST_WIN)
	AdjustWinStyle();
$$ENDIF
$$ENDIF
$$IF(CENTERWINDOW)
	CenterWindow();
$$ENDIF

	ShowWindow(g_hWnd, nCmdShow);
	UpdateWindow(g_hWnd);
$$IF(CHGEXEDIR)

	ChangeToEXEDir();
$$ENDIF

	return TRUE;
}

// ------------------------------------------------------------------
// WinMain - inital function called by windows
// ------------------------------------------------------------------
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{
	MSG msg;

	// save the app instance
	g_hInst = hInstance;


	if(!InitApp(nCmdShow)) 
        CDXError( NULL , "could not initialize application" );

	if(!cdx_Init())
	{
		PostQuitMessage(0);
		return FALSE;
	}

	while(1)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
		{
			if(!GetMessage(&msg, NULL, 0, 0 )) return msg.wParam;
			TranslateMessage(&msg); 
			DispatchMessage(&msg);
		}
$$IF(LOOSEFOCUS)
		else if(g_IsAppActive)
		{
			cdx_DoFrame();
		}
		else
		{
			WaitMessage();
		}
$$ELSE
		else
		{
			cdx_DoFrame();
		}
$$ENDIF
	}
}
