Direct3d opens... then closes?!?!

Started by
21 comments, last by Pirosan 20 years, 6 months ago
Well that title explains it all... I found some GREAT direct3d tutorials that had compilable code that would open, then close straight away. i checked my paths over and over again... they all check out... This same thing happened with the "Zen of D3D game programming" book''s source. The win32 programs work fine, but when he adds the d3d initialization code, i see the window come up for a brief second then it closes. I debugged the code and it sais that one of the initialization procedures failed. I tried as many things as i could, but it still wouldnt work... any ideas? This is the procedure it fails on: r = pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWndTarget, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, ppDevice ); pD3D was used before, and that procedure passed (pD3D->GetAdapterDisplayMode) so im stumped... Any help would be greatly appreciated! Chris
Bow before me... for i am l33t!
Advertisement
This may be related to drivers. I have had problems with NVIDIA Detonator drivers for the last few releases. D3D device creation always fails. If you recently upgraded the driver, revert back to the last version that worked.
A directX 9 game that didnt work on my computer worked on another of my computers, which is newer and has a far more superior graphics card. Do you think that my old laptop cant take the newest d3d versions? I think this problem only happens with directX 9...

So the driver is the problem?
Bow before me... for i am l33t!
You might want to change D3DDEVTYPE_HAL to D3DDEVTYPE_REF and see if that works. If it does, it''s a graphics card / driver issue


Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
thanks a lot... i will try that out!
Bow before me... for i am l33t!
Arg... it did the same thing... i tried D3DDEVTYPE_REF, D3DDEVTYPE_HAL and D3DDEVTYPE_SW and it still didnt work correctly...
Bow before me... for i am l33t!
And actually this is a d3d 8 program that i am having trouble with... interesting...

O and if this helps, i compile the sample program, then move it to my better, newer comp but it still doesnt work... I think its a problem in the coding but i dont know what could be wronge...

[edited by - Pirosan on October 14, 2003 7:49:59 PM]
Bow before me... for i am l33t!
Maybe you're trying to initialize Direct3D to a resolution your computer can't handle?

Try 640x480 at 16 bit colour. Or even 256 colours.

If that doesn't work, you should post some code.

[edited by - glassJAw on October 14, 2003 7:53:23 PM]
ok i have 2 source files.. the first is main.cpp:
// ////////////////////////////////////////////// // Author: Peter Walsh// 9th Dec 2000//// //#define WIN32_LEAN_AND_MEAN// The main windows include file#include <windows.h>#include <mmsystem.h>#include <d3d8.h>#include <d3dx8.h>#include "Engine.h"int GameInit();int GameLoop();int GameShutdown();int Render();CConsole Console;int ConsoleParser( CCommand* pCommand );HWND g_hWndMain;struct ZENVERTEX{	float x, y, z;	DWORD DiffuseColor;};#define CUSTOM_ZENVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)LPDIRECT3DVERTEXBUFFER8 g_pVB = 0;// The window procedure to handle eventslong CALLBACK WndProc( HWND hWnd, UINT uMessage,                                 WPARAM wParam, LPARAM lParam ){	// Switch the windows message to figure out what it is	switch( uMessage )	{		case WM_CREATE:	// The CreateWindow() function was just called		{			// One Time Initialization			return 0;		}		case WM_PAINT:	// The window needs to be redrawn		{			ValidateRect( hWnd, NULL );			return 0;		}		case WM_KEYDOWN:		{			Console.OnKeyDown( wParam );			return 0;		}		case WM_CHAR:		{			Console.OnChar( wParam );			return 0;		}				case WM_DESTROY:	// The window is about to be closed		{			// Our main window is closing.  This means we want our app to exit.			// Tell windows to put a WM_QUIT message in our message queue			PostQuitMessage( 0 );			return 0;		}		default:			// Some other message		{			// Let windows handle this message			return DefWindowProc( hWnd, uMessage, wParam, lParam );		}	}}// The windows entry point. The application will start executing hereint WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,                                     PSTR pstrCmdLine, int iCmdShow ){	HWND hWnd;		// The handle to our main window	MSG msg;		// The message windows is sending us	WNDCLASSEX wc;	// The window class used to create our window	// The name of our class and also the title to our window	static char strAppName[] = "First Windows App, Zen Style";	// Fill in the window class with the attributes for our main window	// The size of this struture in bytes	wc.cbSize			= sizeof( WNDCLASSEX );		//  The style of the window.	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	// Useless information.  Just set to zero.	wc.cbClsExtra		= 0;	// Useless information.  Just set to zero.	wc.cbWndExtra		= 0;	// The name of our event handler	wc.lpfnWndProc		= WndProc;	// A handle to the applications instance	wc.hInstance		= hInstance;	// The handle to the brush to use for the window background	wc.hbrBackground	= (HBRUSH)GetStockObject( DKGRAY_BRUSH );	// A handle to the icon to use for the window	wc.hIcon			= LoadIcon( NULL, IDI_APPLICATION );	// A handle to a smaller version of the apps icon	wc.hIconSm			= LoadIcon( NULL, IDI_APPLICATION );	// A handle to the cursor to use while the mouse is over our window	wc.hCursor			= LoadCursor( NULL, IDC_CROSS );	// A handle to the resource to use as our menu	wc.lpszMenuName		= NULL;	// The human readable name for this class	wc.lpszClassName	= strAppName;	// Register the class with windows	RegisterClassEx( &wc );	// Create the window based on the previous class	hWnd = CreateWindowEx( WS_EX_TOPMOST,	// Advanced style settings	            strAppName,			// The name of the class				strAppName,			// The window caption				WS_POPUP | WS_SYSMENU | WS_VISIBLE ,// The window style			   	CW_USEDEFAULT,		// The initial x position                 CW_USEDEFAULT,		// The initial y position			   	512, 512,			// The intiial width / height				NULL,				// Handle to parent window										NULL,				// Handle to the menu				hInstance,			// Handle to the apps instance				NULL );				// Advanced context	g_hWndMain = hWnd;	// Display the window we just created	ShowWindow( hWnd, iCmdShow );	// Draw the window contents for the first time	UpdateWindow( hWnd );	if( FAILED( GameInit() ) )	{		SetError( "Initialization Failed" );		GameShutdown();		return E_FAIL;	}	// Start the message loop	while( TRUE )	{		// Check if a message is waiting for processing		if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )		{			// Check if the message is to quit the application			if( msg.message == WM_QUIT )				// Exit the message loop				break;						// Change the format of certain messages			TranslateMessage( &msg );			// Pass the message to WndProc() for processing			DispatchMessage( &msg );		}		else		{			GameLoop();		}	}		GameShutdown();	// Return control to windows with the exit code	return msg.wParam;}int GameInit(){		HRESULT r = 0;		// Acquire a pointer to IDirect3D8	g_pD3D = Direct3DCreate8( D3D_SDK_VERSION );	if( g_pD3D == NULL )	{		SetError( "Could not create IDirect3D8 object" );		return E_FAIL;	}		// Create the device	r = InitDirect3DDevice( g_hWndMain, 640, 480, FALSE, D3DFMT_A8R8G8B8, g_pD3D, &g_pDevice );	if( FAILED( r ) )	{		SetError( "Initialization of the device failed" );		return E_FAIL;	}	CreateViewport();	SetProjectionMatrix();	D3DXMATRIX ViewMatrix;	D3DXMatrixLookAtLH( &ViewMatrix,	&D3DXVECTOR3( 0.0f, 3.0f,-5.0f ),										&D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),										&D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );		g_pDevice->SetTransform( D3DTS_VIEW, &ViewMatrix );	// Clear the back buffer	g_pDevice->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0, 0, 55 ), 1.0f, 0 );	// Get a pointer to the back buffer and save it in a global variable	r = g_pDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &g_pBackSurface );	if( FAILED( r ) )	{		SetError( "Couldnt get backbuffer" );		return E_FAIL;	}		// Load the alphabet	LoadAlphabet( "Alphabet vSmall.bmp", 8, 16 );	// Intialize timing for frame rate counters, etc	srand( GetTickCount() );		InitTiming();	// Initialize the console	Console.Initialize( g_pDevice, g_pBackSurface );	Console.SetParserCallback( ConsoleParser );	// The vertices for the triangle	ZENVERTEX ZenVertices[] =	{		{ -2.0f,-2.0f, 0.0f, D3DCOLOR_XRGB( 255, 0, 0 ), },        {  2.0f,-2.0f, 0.0f, D3DCOLOR_XRGB( 255, 255, 0 ), },        {  0.0f, 2.0f, 0.0f, D3DCOLOR_XRGB( 0, 0, 255 ), },	};	// Create the vertex buffer	r = g_pDevice->CreateVertexBuffer( sizeof(ZENVERTEX)*3, 0, CUSTOM_ZENVERTEX, D3DPOOL_DEFAULT, &g_pVB );	if( FAILED( r ) )	{		SetError( "Couldnt create the vertex buffer" );		return E_FAIL;	}    		// Pointer to the vertex buffer	BYTE* pVertices = 0;	// Lock the vertex buffer	r = g_pVB->Lock( 0, sizeof( ZenVertices ), &pVertices, 0 );	if( FAILED( r ) )	{		SetError( "Could not lock the vertex buffer" );		return E_FAIL;	}	// Turn off culling so the back of the triangle does not disapear    g_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );    // Turn off lighting because we have are own colors for the vertices    g_pDevice->SetRenderState( D3DRS_LIGHTING, FALSE );		// Fill the buffer with the vertices	CopyMemory( pVertices, &ZenVertices, sizeof( ZenVertices ) );	// Unlock the buffer	g_pVB->Unlock();	return S_OK;}int GameLoop(){	FrameCount();		Render();			if( GetAsyncKeyState( VK_ESCAPE ) )		PostQuitMessage(0);		return S_OK;}int GameShutdown(){	Console.Shutdown();	UnloadAlphabet();	if( g_pVB )		g_pVB->Release();	// Release the pointer to the back surface	if( g_pBackSurface )		g_pBackSurface->Release();		// Release the pointer to IDirect3DDevice8	if( g_pDevice )		g_pDevice->Release();		// Release the pointer to IDirect3D8	if( g_pD3D )		g_pD3D->Release();	return S_OK;}int Render(){	HRESULT r = 0;	g_pDevice->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0, 0, 100 ), 1.0f, 0 );		// Make sure the device is valid	if( !g_pDevice )	{		SetError( "Cannot render because there is no device" );		return E_FAIL;	}	// Return if the device is not ready;	r = ValidateDevice();	if( FAILED( r ) )	{		return E_FAIL;	}	D3DLOCKED_RECT Locked;		g_pBackSurface->LockRect( &Locked, 0, 0 );	// Render text	PrintFrameRate( 550, 400, TRUE, D3DCOLOR_ARGB( 255, 255, 0, 255 ), (DWORD*)Locked.pBits, Locked.Pitch );	// Unlock the back surface	g_pBackSurface->UnlockRect();	D3DXMATRIX RotationX, RotationY, WorldMatrix;	D3DXMatrixRotationY( &RotationY, timeGetTime()/200.0f );	D3DXMatrixRotationX( &RotationX, timeGetTime()/800.0f );	D3DXMatrixMultiply( &WorldMatrix, &RotationX, &RotationY );	g_pDevice->SetTransform( D3DTS_WORLD, &WorldMatrix );	// Tell Direct3D we are about to start rendering in 3D	g_pDevice->BeginScene();	// Set the rendering stream	g_pDevice->SetStreamSource( 0, g_pVB, sizeof(ZENVERTEX) );	// Set the vertex shading mode	g_pDevice->SetVertexShader( CUSTOM_ZENVERTEX );	// Draw the triangle	g_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 );	// Tell Direct3D we have finished drawing in 3D	g_pDevice->EndScene();	// Render the console	Console.Render();	// Present the back buffer to the primary surface	r = g_pDevice->Present( NULL, NULL, NULL, NULL );	return S_OK;}int ConsoleParser( CCommand* pCommand ){	char* pstrCmd = pCommand->pstrCommand;	char* pstrParams[MAX_PARAMS];	memcpy( &pstrParams, &(pCommand->pstrParams), sizeof( pstrParams ) );	int NumParams = pCommand->NumParams;		if( MATCH( pstrCmd, "exit" ) || MATCH( pstrCmd, "quit" ) )	{		PostQuitMessage(0);		return 0;	}	if( MATCH( pstrCmd, "cls" ) )	{		Console.Clear();		return 0;	}	if( MATCH( pstrCmd, "add" ) )	{		if( NumParams < 2 )			return E_FAIL;		int a = ParseStringForNumber( pstrParams[0] );		int b = ParseStringForNumber( pstrParams[1] );		int Result = a + b;		char OutputString[20];				itoa( Result, OutputString, 10 );		Console.OutputString( OutputString );		return S_OK;	}	return -1;}

Then there is the Engine.h:

////////////////////////////// Purpose: Engine Code// Author: Peter Walsh//#include <stdio.h>HRESULT RestoreGraphics();LPDIRECT3DSURFACE8 g_pBackSurface = 0;int g_DeviceWidth = 0;int g_DeviceHeight = 0;const int MAX_CHARSPERLINE = 256;#define MATCH(a, b) (!strcmp( a, b ))D3DPRESENT_PARAMETERS g_SavedPresParams;/*****************************************************************************************************************************				Generic Code*****************************************************************************************************************************/// Output an error to the debug windowvoid SetError( char* String ){	OutputDebugString( "ERROR: " );	OutputDebugString( String );	OutputDebugString( "\n" );}// This function attempts to parse the supplied string// and return an integer. It returns 0 if it is // unable to parse the string.int ParseStringForNumber( char* pString ){	// Some boolean tests	if( MATCH( pString, "on"  ) )		return 1;	if( MATCH( pString, "off" ) )		return 0;	if( MATCH( pString, "true" ) )		return 1;	if( MATCH( pString, "false" ) )		return 0;	if( MATCH( pString, "yes" ) )		return 1;	if( MATCH( pString, "no" ) )		return 0;	// Some spelled number tests	if( MATCH( pString, "zero" ) )		return 0;	if( MATCH( pString, "one" ) )		return 1;	if( MATCH( pString, "two" ) )		return 2;	if( MATCH( pString, "three" ) )		return 3;	if( MATCH( pString, "four" ) )		return 4;	if( MATCH( pString, "five" ) )		return 5;	if( MATCH( pString, "six" ) )		return 6;	if( MATCH( pString, "seven" ) )		return 7;	if( MATCH( pString, "eight" ) )		return 8;	if( MATCH( pString, "nine" ) )		return 9;	if( MATCH( pString, "ten" ) )		return 10;	// Try converting to string	return atoi( pString );}/*****************************************************************************************************************************				Direct3D Initialization Code*****************************************************************************************************************************/// Initializes the Direct3D deviceint InitDirect3DDevice( HWND hWndTarget, int Width, int Height, BOOL bWindowed, 							D3DFORMAT FullScreenFormat, LPDIRECT3D8 pD3D, 							LPDIRECT3DDEVICE8* ppDevice ){	// Structure to hold information about the rendering method	D3DPRESENT_PARAMETERS d3dpp;	// Structure to hold information about the current display mode	D3DDISPLAYMODE d3ddm;	HRESULT r = 0;		if( *ppDevice )		(*ppDevice)->Release();	// Initialize the structure to 0	ZeroMemory( &d3dpp, sizeof( D3DPRESENT_PARAMETERS ) );	// Get the settings for the current display mode	r = pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm );	if( FAILED( r ) )	{		SetError( "Could not get display adapter information" );		return E_FAIL;	}		// The width of the back buffer in pixels	d3dpp.BackBufferWidth = Width;	// The height of the buffer in pixels	d3dpp.BackBufferHeight = Height;	// The format of the back buffer	d3dpp.BackBufferFormat = bWindowed ? d3ddm.Format : FullScreenFormat;	// The number of back buffers	d3dpp.BackBufferCount = 1;	// The type of multisampling	d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;	// The swap effect	d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;		// The handle to the window that we want to render to 	d3dpp.hDeviceWindow = hWndTarget;		// Windowed or fullscreen	d3dpp.Windowed = bWindowed;	// Let Direct3D manage the depth buffer	d3dpp.EnableAutoDepthStencil = TRUE;	// Set the depth buffer format to 16 bits	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;		// Use the default refresh rate available	d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;		// Present the information as fast as possible	d3dpp.FullScreen_PresentationInterval = bWindowed ? 0 : D3DPRESENT_INTERVAL_IMMEDIATE;	// Allow the back buffer to be accessed for 2D work	d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;	// Acquire a pointer to IDirect3DDevice8	r = pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_SW, hWndTarget,							D3DCREATE_SOFTWARE_VERTEXPROCESSING, 							&d3dpp, ppDevice );	if( FAILED( r ) )	{		SetError( "Could not create the render device" );		return E_FAIL;	}	// Save global copies of the device dimensions	g_DeviceHeight = Height;	g_DeviceWidth = Width;	// Save a copy of the pres params for use in device validation later	g_SavedPresParams = d3dpp;	return S_OK;}/*****************************************************************************************************************************						2D Graphics Code*****************************************************************************************************************************/// Set a pixel to specified colorvoid SetPixel32( int x, int y, DWORD Color, int Pitch, DWORD* pData ){	// Make sure the pixel is within screen boundaries	if( x > g_DeviceWidth || x < 0 )		return;	if( y > g_DeviceHeight || y < 0 )		return;			// Set the pixel	pData[ ((Pitch/4) * y) + x ] = Color;}// Draw a rectanglevoid Rectangle32( D3DRECT* pRect, DWORD Color, int Pitch, DWORD* pData ){	// Use local variables to avoid dereferencing inside the loop	int y1 = pRect->y1;	int y2 = pRect->y2;	int x1 = pRect->x1;	int x2 = pRect->x2;	// Convert the pitch from bytes to DWORDS	int Pitch32 = Pitch / 4;		// Get the offset into the target	DWORD Offset = y1 * Pitch32 + x1;	// Loop for each row of the rectangle	for( int y = y1 ; y < y2 ; y++ )	{		// Loop for each column in the image		for( int x = x1 ; x < x2 ; x++ )		{			// Set the pixel to the correct color			pData[ Offset + x ] = Color;					}		// Increment the offset to the next row of the rectangle		Offset += Pitch32;	}}// This uses hardware accelaration to draw a rectangle.  It only works for// the back buffervoid Rectangle32Fast( D3DRECT* pRect, DWORD Color, LPDIRECT3DDEVICE8 pDevice ){	pDevice->Clear( 1, pRect, D3DCLEAR_TARGET, Color, 0.0f, 0 );}// Loads a bitmap to a surfaceint LoadBitmapToSurface( char* PathName, LPDIRECT3DSURFACE8* ppSurface, LPDIRECT3DDEVICE8 pDevice ){	HRESULT r;	HBITMAP hBitmap;	BITMAP Bitmap;		// Load the bitmap first using the GDI to get info about it	hBitmap = (HBITMAP)LoadImage( NULL, PathName, IMAGE_BITMAP, 0, 0, 									LR_LOADFROMFILE | LR_CREATEDIBSECTION );	if( hBitmap == NULL )	{		// The file probably does not exist		SetError( "Unable to load bitmap" );		return E_FAIL;	}	// Get information about the object	GetObject( hBitmap, sizeof( BITMAP ), &Bitmap );	// Unload the bitmap from memory	DeleteObject( hBitmap );	// Now create a surface using the information gained from	// the previous load	r = pDevice->CreateImageSurface( Bitmap.bmWidth, 								Bitmap.bmHeight, D3DFMT_A8R8G8B8, ppSurface );	if( FAILED( r ) )	{		SetError( "Unable to create surface for bitmap load" );		return E_FAIL;	}	// Load the image again, this time using Direct3D to load	// it directly to the new surface	r = D3DXLoadSurfaceFromFile( *ppSurface, NULL, NULL, PathName, 									NULL, D3DX_FILTER_NONE, 0, NULL );	if( FAILED( r ) )	{		SetError( "Unable to load file to surface" );		return E_FAIL;	}	return S_OK;}/*-----------------------------------------------------------------------CopySurfaceToSurface()Parameters:1) Pointer to a RECT that defines the dimensions for the source rectangle. If	set to NULL then the entire source surface is used.2) Pointer to the source surface.  Must be valid3) Pointer to a POINT that defines where the origin on the destination should	be for the source image.  If NULL then copying will start at (0, 0)	on the destination.4) Pointer to the destination surface.  Must be valid5) Flag indicating if transparency is wanted6) The colorkey to use if transparency is enabled.Notes:Call this function to copy one surface to another with transparency ifrequired.  Make sure that both surfaces are valid and NOT locked beforeyou pass them to this function, otherwise it will fail.-----------------------------------------------------------------------*/HRESULT CopySurfaceToSurface( RECT* pSourceRect, LPDIRECT3DSURFACE8 pSourceSurf, POINT* pDestPoint, 								LPDIRECT3DSURFACE8 pDestSurf, BOOL bTransparent, D3DCOLOR ColorKey ){	// Holds error return values	HRESULT r = 0;			// Holds information about the surfaces when they are locked	D3DLOCKED_RECT LockedSource;	D3DLOCKED_RECT LockedDest;	// Make sure the source surface is valid	if( !pSourceSurf )		return E_FAIL;	// Make sure the destination surface is valid	if( !pDestSurf )		return E_FAIL;	// The source rectangle	RECT SourceRect;	// The destination point	POINT DestPoint;	// Holds information about the source surface	D3DSURFACE_DESC d3dsdSource;	// Get information about the source surface	pSourceSurf->GetDesc( &d3dsdSource );	// Holds information about the destination surface	D3DSURFACE_DESC d3dsdDest;	// Get information about the destination surface	pDestSurf->GetDesc( &d3dsdDest );	// If a source rectangle was specified then copy it	// into the local RECT structure	if( pSourceRect )		SourceRect = *pSourceRect;	else		// Otherwise set the rectangle to encompas the entire source surface		SetRect( &SourceRect, 0, 0, d3dsdSource.Width, d3dsdSource.Height );		// If a destination point was specified then copy it	// to the local POINT structure	if( pDestPoint )		DestPoint = *pDestPoint;	else	{		// Otherwise set the point to (0,0)		DestPoint.x = DestPoint.y = 0;	}	// Lock the source surface.	r = pSourceSurf->LockRect( &LockedSource, 0, D3DLOCK_READONLY  );	if( FAILED( r ) )		// Fatal Error		return E_FAIL;	// Lock the destination surface	r = pDestSurf->LockRect( &LockedDest, 0, 0 );	if( FAILED( r ) )	{		// Fatal error, so unlock the source		// surface before exiting		pSourceSurf->UnlockRect();		return E_FAIL;	}	// Modify the pitch to be DWORD compatible	LockedSource.Pitch /= 4;	LockedDest.Pitch /= 4;	// Get 32bit pointers to the surface data	DWORD* pSourceData = (DWORD*)LockedSource.pBits;	DWORD* pDestData = (DWORD*)LockedDest.pBits;	// Get the offset into the source surface	int SourceOffset = SourceRect.top * LockedSource.Pitch + SourceRect.left;	// Get the offset into the destination surface	int DestOffset = DestPoint.y * LockedDest.Pitch + DestPoint.x;	// Loop for each row of the source image	for( int y = 0 ; y < SourceRect.bottom ; y++ )	{		// Loop for each column of the source image		for( int x = 0 ; x < SourceRect.right ; x++ )		{			// If transparency was requested			if( bTransparent )			{								// Then check to see if the current source pixel				// matches the color key.  If it does then do				// not copy it.				if( pSourceData[ SourceOffset ] != ColorKey )				{					// The current pixel does not match the color					// key so it is ok to copy it to the destination					pDestData[ DestOffset ] = pSourceData[ SourceOffset ];				}			}			else // Transparency was not requested			{				// Copy the source pixel to the destination				// without any comparison				pDestData[ DestOffset ] = pSourceData[ SourceOffset ];			}			// Increment to the next pixel in the destination			DestOffset++;			// Increment to the next pixel in the source			SourceOffset++;		}				// Move the source offset to the next row of the image		// by adding the pitch minus the width of the source image 		SourceOffset += LockedSource.Pitch - SourceRect.right;		// Move the destination offset to the next row of the image		DestOffset += LockedDest.Pitch - SourceRect.right;	}	// Copying is complete so unlock the surfaces	pSourceSurf->UnlockRect();	pDestSurf->UnlockRect();		// Return success	return S_OK;}/*****************************************************************************************************************************						DC to Surface Code*****************************************************************************************************************************/// Creates a GDI DC that can be copied to a surface laterHDC CreateD3DCompatibleDC( int Width, int Height, HBITMAP* phDibSection ){	// Create a new DC that is compatible with the current display mode	HDC hDC = CreateCompatibleDC(0);	// Temp pointer to the DIB data	void* pDibSection = 0;	// Structure to hold information about the bitmap	BITMAPINFO bi;	ZeroMemory( &bi, sizeof( BITMAPINFO ) );	// The size of this structure in bytes	bi.bmiHeader.biSize = sizeof( BITMAPINFOHEADER );	// The width of the new bitmap	bi.bmiHeader.biWidth = Width;	// The height of the new bitmap( negative for a top down image )	bi.bmiHeader.biHeight = -Height;	// Obselete - just set to one	bi.bmiHeader.biPlanes = 1;	// The bit depth of the surface	bi.bmiHeader.biBitCount = 32;	// The compression format.  BI_RGB indicates none	bi.bmiHeader.biCompression = BI_RGB;		// Create a new DIB	HBITMAP hDibSection = CreateDIBSection( hDC, &bi, DIB_RGB_COLORS, &pDibSection, NULL, NULL );	// Select the bitmap into the new DC	SelectObject( hDC, hDibSection );	// Update the pointer to the handle to the bitmap	*phDibSection = hDibSection;	// Return the handle to the device context	return hDC;}// Copies a GDI DC to Direct3D surfaceHRESULT CopyDCToSurface( LPDIRECT3DSURFACE8 pDestSurf, POINT* pDestPoint, 					HDC hDCSource, HBITMAP hDibSection, RECT* pSrcRect, COLORREF ColorKey ){	HRESULT r = 0;		// The source rectangle	RECT SourceRect;	// The destination origin point	POINT DestPoint;	// Holds information about the bitmap	DIBSECTION DibSection;	// Holds information about the surface when locked	D3DLOCKED_RECT LockedRect;	// Get information about the bitmap in the DC	GetObject( hDibSection, sizeof( DIBSECTION ), &DibSection );	int SrcTotalWidth = DibSection.dsBm.bmWidth;	int SrcTotalHeight = DibSection.dsBm.bmHeight;	// If no source rectangle was specified then this indicates	// that the entire bitmap in the DC is to be copied	if( !pSrcRect )		SetRect( &SourceRect, 0, 0, SrcTotalWidth, SrcTotalWidth);	else		SourceRect = *(pSrcRect);	// If no destination point was specified then the origin	// is set to (0,0)	if( !pDestPoint )		DestPoint.x = DestPoint.y = 0;	else		DestPoint = *(pDestPoint);	// Return failure if a valid destination surface was not specified	if( !pDestSurf )		return E_FAIL;	// Return failure if a valid source DC was not specified	if( !hDCSource )		return E_FAIL;	// Lock the source surface	r = pDestSurf->LockRect( &LockedRect, 0, 0  );	if( FAILED( r ) )	{		SetError( "Unable to lock the surface for GDI transfer" );		return E_FAIL;	}	D3DSURFACE_DESC d3dsd;	pDestSurf->GetDesc( &d3dsd );	if( (UINT)(SourceRect.bottom + DestPoint.y) > (UINT)d3dsd.Height )		SourceRect.bottom = d3dsd.Height;	if( (UINT)(SourceRect.right + DestPoint.x) > (UINT)d3dsd.Width )		SourceRect.right = d3dsd.Width;	// Convert the source and destination data pointers	// to DWORD( 32 bit) values	DWORD* pSrcData = (DWORD*)(DibSection.dsBm.bmBits);	DWORD* pDestData = (DWORD*)(LockedRect.pBits);	// Convert the pitch to a 32 bit value	int Pitch32 = LockedRect.Pitch/4;	// Compute the dimensions for the copy	int SrcHeight = SourceRect.bottom - SourceRect.top;	int SrcWidth = SourceRect.right - SourceRect.left;	// Compute the index into memory	DWORD SrcOffset = SourceRect.top * SrcTotalWidth + SourceRect.left;	DWORD DestOffset = DestPoint.y * Pitch32 + DestPoint.x;	// If not using a color key then a faster copy can be done	if( ColorKey == -1 )	{		// Loop for each row in the image		for( int y = 0 ; y < SrcHeight ; y++ )		{			// Copy this line of the image			memcpy( (void*)&(pDestData[ DestOffset ]), (void*)&(pSrcData[ SrcOffset ]), SrcWidth*4);			// Increase the destation pointer by the pitch			DestOffset+=Pitch32;			// Increase the source pointer by the total width			SrcOffset +=SrcTotalWidth;		}	}	else	// a color key was specified	{		// Loop for each row in the image		for( int y = 0 ; y < SrcHeight ; y++ )		{			// Loop for each column			for( int x = 0 ; x < SrcWidth ; x++ )			{										// If the source pixel is not the same as the color key				if( pSrcData[ SrcOffset ] != ColorKey )					// Then copy the pixel to the destination					pDestData[ DestOffset ] = pSrcData[ SrcOffset ];				// Move to the next pixel in the source				SrcOffset++;				// Move to the next pixel in the destination				DestOffset++;			}						DestOffset += Pitch32 - SrcWidth;		}	}	// Unlock the surface	pDestSurf->UnlockRect();	// Return success	return S_OK;}// Deletes a GDI DC that was created with CreateD3DCompatibleDC()void DeleteD3DCompatibleDC( HDC hDC, HBITMAP hDibSection ){	// Delete the bitmap	DeleteObject( hDibSection );	// Delete the DC	DeleteDC( hDC );}/*****************************************************************************************************************************						Device Validation Code*****************************************************************************************************************************/LPDIRECT3D8 g_pD3D = 0;LPDIRECT3DDEVICE8 g_pDevice = 0;// Call every frame to check if the device is valid.  If it// is not then the it is reaquired if possibleHRESULT ValidateDevice(){	HRESULT r = 0;		// Test the current state of the device	r = g_pDevice->TestCooperativeLevel();	if( FAILED( r ) )	{		// If the device is lost then return failure		if( r == D3DERR_DEVICELOST )			return E_FAIL;		// If the device is ready to be reset then attempt to do so		if( r == D3DERR_DEVICENOTRESET )		{			// Release the back surface so it can be recreated			g_pBackSurface->Release();			// Reset the device			r = g_pDevice->Reset( &g_SavedPresParams );			if( FAILED( r ) )			{				// If the device was not reset then exit				SetError( "Could not reset device" );				PostQuitMessage( E_FAIL );				return E_FAIL;			}						// Reaquire a pointer to the new back buffer			r = g_pDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &g_pBackSurface );			if( FAILED( r ) )			{				SetError( "Unable to reaquire the back buffer" );				PostQuitMessage( 0 );				return E_FAIL;			}			g_pDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 0 ), 0.0f, 0 );			RestoreGraphics();		}	}	return S_OK;}// Use this function to reinit any surfaces that were lost// when the device was lost.HRESULT RestoreGraphics(){		return S_OK;}/*****************************************************************************************************************************						Font Engine Code*****************************************************************************************************************************/int g_AlphabetWidth = 0;			// The width of the Alphabet bitmapint g_AlphabetHeight = 0;			// The height of the Alphabet bitmapint g_AlphabetLetterWidth = 0;		// The width of a letterint g_AlphabetLetterHeight = 0;		// The height of a letterint g_AlphabetLettersPerRow = 0;	// The number of letters per row// The surface holding the alphabet bitmapLPDIRECT3DSURFACE8 g_pAlphabetSurface = 0;// Has the alphabet bitmap been loaded yet?BOOL g_bAlphabetLoaded = FALSE;// Used to load an alphabet bitmap into memoryHRESULT LoadAlphabet( char* strPathName, int LetterWidth, int LetterHeight ){	// Make sure a valid path was specified	if( !strPathName )		return E_FAIL;	// Make sure the size of the letters is greater than 0	if( !LetterWidth || !LetterHeight )		return E_FAIL;	HRESULT r = 0;		// Load the bitmap into memory	r = LoadBitmapToSurface( strPathName, &g_pAlphabetSurface, g_pDevice );	if( FAILED( r ) )	{		SetError( "Unable to load alphabet bitmap" );		return E_FAIL;	}	// Holds information about the alpahbet surface	D3DSURFACE_DESC d3dsd;	// Get information about the alphabet surface	g_pAlphabetSurface->GetDesc( &d3dsd );	// Update globals with the letter dimensions	g_AlphabetWidth = d3dsd.Width;				g_AlphabetHeight = d3dsd.Height;	g_AlphabetLetterWidth = LetterWidth;	g_AlphabetLetterHeight = LetterHeight;	// Compute the number of letters in a row	g_AlphabetLettersPerRow = g_AlphabetWidth / g_AlphabetLetterWidth;	// Set the loaded flag to TRUE	g_bAlphabetLoaded = TRUE;	return S_OK;}// Unloads the alphabet from memoryHRESULT UnloadAlphabet(){	// Check if the alphabet exists	if( g_pAlphabetSurface )	{		// Release the surface		g_pAlphabetSurface->Release();		// NULL the pointer		g_pAlphabetSurface = 0;		// Set the loaded flag to FALSE		g_bAlphabetLoaded = FALSE;	}	return S_OK;}// Print a character to a surface using the loaded alphabetvoid PrintChar( int x, int y, char Character, BOOL bTransparent, 						D3DCOLOR ColorKey, DWORD* pDestData, int DestPitch ){	HRESULT r = 0;		div_t Result;	// Holds the result of divisions	// The offset into the alphabet image	int OffsetX = 0, OffsetY = 0;	POINT LetterDestPoint = { 0, 0 };	// The destination point for the letter	RECT LetterRect = { 0, 0, 0, 0 };	// The source rectangle for the letter	// If the alphabet has not been loaded yet then exit	if( !g_bAlphabetLoaded )		return;	// The characters are specified in ASCII code, which begins at 32 so	// we want to decrement this value by 32 to make it zero based	Character -= 32;	// Divide the character code by the number of letters per row.	// The quotient will help get the vertical offset and the	// remainder will help get the horizontal offset	Result = div( Character, g_AlphabetLettersPerRow );	// Get the horizontal offset by multiplying the remainder	// by the width of the Letter	OffsetX = Result.rem * g_AlphabetLetterWidth;	// Get the vertical offset by multiplying the quotient	// by the height of the letter	OffsetY = Result.quot * g_AlphabetLetterHeight;	// Fill in the source rectangle with the computed offsets	SetRect( &LetterRect, OffsetX, OffsetY, 	OffsetX + g_AlphabetLetterWidth, OffsetY + g_AlphabetLetterHeight );		// Fill in the destination point	LetterDestPoint.x = x;	LetterDestPoint.y = y;		D3DLOCKED_RECT LockedAlphabet;	// Holds info about the alphabet surface	// Lock the source surface	r = g_pAlphabetSurface->LockRect( &LockedAlphabet, 0, D3DLOCK_READONLY  );	if( FAILED( r ) )	{		SetError( "Couldnt lock alphabet surface for PrintChar()" );		return;	}		// Get a DWORD pointer to each surface	DWORD* pAlphaData = (DWORD*)LockedAlphabet.pBits;	// Convert the BYTE pitch pointer to a DWORD ptr	LockedAlphabet.Pitch /=4;	DestPitch /= 4;	// Compute the offset into the alphabet	int AlphaOffset = OffsetY * LockedAlphabet.Pitch + OffsetX;	// Compute the offset into the destination surface	int DestOffset = y * DestPitch + x;	// Loop for each row in the letter	for( int cy = 0 ; cy < g_AlphabetLetterHeight ; cy++ )	{		// Loop for each column in the letter		for( int cx = 0 ; cx < g_AlphabetLetterWidth ; cx++ )		{			if( bTransparent )			{				// If this alphabet pixel is not transparent				if( pAlphaData[ AlphaOffset ] != ColorKey )				{					// Then copy the pixel to the destination					pDestData[ DestOffset ] = pAlphaData[ AlphaOffset ];				}				// Increment the offsets to the next pixel			}			else			{				pDestData[ DestOffset ] = pAlphaData[ AlphaOffset ];			}			AlphaOffset++;			DestOffset++;		}		// Move the offsets to the start of the next row		DestOffset += DestPitch - g_AlphabetLetterWidth;		AlphaOffset += LockedAlphabet.Pitch - g_AlphabetLetterWidth;	}		// Unlock the surface	g_pAlphabetSurface->UnlockRect();	}void PrintString( int x, int y, char* String, BOOL bTransparent, 					D3DCOLOR ColorKey, DWORD* pDestData, int DestPitch ){	// Loop for each character in the string	for( UINT i = 0 ; i < strlen( String ) ; i++ )	{		// Print the current character		int cx = x + (g_AlphabetLetterWidth * i);			if( cx + g_AlphabetLetterWidth > g_DeviceWidth )			continue;		PrintChar( cx, y, String[i], 							bTransparent, ColorKey, pDestData, DestPitch );	}	}/*****************************************************************************************************************************						Timing Code*****************************************************************************************************************************/// The number of high performance ticks per secondINT64 g_Frequency = 0;// The number of elapsed frames this counting periodint g_FrameCount = 0;// The number of elapsed frames this secondint g_FrameRate = 0;HRESULT InitTiming(){	// Get the number of counts per second	QueryPerformanceFrequency( (LARGE_INTEGER*)&g_Frequency );	// If the frequency is 0 then this system does not have	// high performance timers	if( g_Frequency == 0 )	{		SetError( "The system does not support high resolution timing" );		return E_FAIL;	}	return S_OK;}void Pause( int Milliseconds ){	INT64 SecondsDelay = (INT64)Milliseconds * 1000;		INT64 StartTime;	INT64 CurrentTime;		QueryPerformanceCounter( (LARGE_INTEGER*)&StartTime );	while(1)	{		QueryPerformanceCounter( (LARGE_INTEGER*)&CurrentTime );		if( (CurrentTime - StartTime) > (INT64)SecondsDelay ) 			break;	}}float GetNumTicksPerMs(){	return ((float)g_Frequency / 1000.0f);}void FrameCount(){	INT64 NewCount = 0;			// The current count	static INT64 LastCount = 0;	// The last count	INT64 Difference = 0;		// The differnce since the last count	// Get the current count	QueryPerformanceCounter( (LARGE_INTEGER*)&NewCount );		// If the count is 0 then this system does not have	// high performance timers	if( NewCount == 0 )		SetError( "The system does not support high resolution timing" );	// Increase the frame count	g_FrameCount++;		// Compute the difference since the last count	Difference = NewCount - LastCount;		// If more than a second has passed	if( Difference >= g_Frequency )	{		// Record the number of elapsed frames		g_FrameRate = g_FrameCount;		// Reset the counter 		g_FrameCount = 0;		// Update the last count		LastCount = NewCount;	}}// Prints the frame rate to the screenvoid PrintFrameRate( int x, int y, BOOL bTransparent, D3DCOLOR ColorKey, DWORD* pDestData, int DestPitch ){	char string[4];	// String to hold the frame rate		// Zero out the string	ZeroMemory( &string, sizeof( string ) );	// Convert the frame rate to a string	itoa( g_FrameRate, string, 10 );	// Output the string to the back surface	PrintString( x, y, string, bTransparent, ColorKey, pDestData, DestPitch );}/*****************************************************************************************************************************						Console Code*****************************************************************************************************************************/// ------------------------- CEntry Class// Used to represent a row of textclass CEntry{public:	CEntry();	// The constructor	~CEntry();  // The destructor	// Variables:protected:	char* m_pstrText;	// The text buffer for this entry	CEntry* m_pNext;	// Pointer to next entry( row )	int m_VerticalPos;	// The y position to render// Functions:public:	// Returns the next entry(row)	CEntry* GetNext(){ return m_pNext; }	// Sets the next entry(row)	void SetNext( CEntry* pNext ){ m_pNext = pNext; }	// Draws the text using the GDI to the console surface	int RenderText( int NumHorzChars, DWORD* pData, int DestPitch );	// Adds a character to the text buffer	int OnChar( char Key );	// Returns the text in the buffer	int GetText( char* pstrText, int Length );	// Clears and then sets the text in the buffer	int SetText( char* pstrText );	// Returns the number of characters in the buffer	int GetTextLength(){ return strlen( m_pstrText ); }	// Sets the vertical position of this entry	void SetVerticalPos( int Pos ){ m_VerticalPos = Pos; }	// Returns the vertical position for this entry	int  GetVerticalPos(){ return m_VerticalPos; }};// ConstructorCEntry::CEntry(){	// Allocate memory for the buffer	m_pstrText = new char[MAX_CHARSPERLINE];	if( m_pstrText )		ZeroMemory( m_pstrText, sizeof( char[MAX_CHARSPERLINE] ) );	else		m_pstrText = 0;		// Zero out member variables	m_pNext = 0;	m_VerticalPos = 0;}// DestructorCEntry::~CEntry(){	// Delete the text buffer if it exists	if( m_pstrText )	{		delete m_pstrText;		m_pstrText = 0;	}}// This function copies the text in the buffer// to the supplied string variableint CEntry::GetText( char* pstrText, int Length ){	// Make sure the length doesnt overrun our buffer	if( Length > MAX_CHARSPERLINE )		Length = MAX_CHARSPERLINE;		// Copy the string	CopyMemory( pstrText, m_pstrText, Length );		return S_OK;}// This function sets the text in the bufferint CEntry::SetText( char* pstrText ){	// Clear out any text that is already there	ZeroMemory( m_pstrText, sizeof( char[MAX_CHARSPERLINE] ) );		// Make sure the supplied text doesnt overrun our buffer	int Length = strlen( pstrText );	if( Length > MAX_CHARSPERLINE )		Length = MAX_CHARSPERLINE;	// Copy the supplied text into our buffer	CopyMemory( m_pstrText, pstrText, strlen( pstrText ) );	return S_OK;}// This function draws the text to the console surface// using the GDIint CEntry::RenderText( int NumHorzChars, DWORD* pData, int DestPitch ){	// Only draw the number of characters that fit on the screen	int Length = strlen( m_pstrText );	if( Length > NumHorzChars )		Length = NumHorzChars;		PrintString( 10, m_VerticalPos, m_pstrText, TRUE, 				D3DCOLOR_ARGB( 255, 255, 0, 255 ), pData, DestPitch );	return S_OK;}// This function is called whenever a character// key is pressed that needs to be added to the bufferint CEntry::OnChar( char Key ){		// Check if the backspace key was pressed	if( Key == '\b' )	{		// Make a temporary string holder		char pstrTemp[MAX_CHARSPERLINE];		// Get the length of the buffer		int Length = strlen( m_pstrText );				// If the buffer is empty then return		if( Length == 0 )			return S_OK;		// Reduce the length of the string by one		Length--;		// Copy the string(-1) to the temp string		CopyMemory( pstrTemp, m_pstrText, Length );			// Zero out the buffer		ZeroMemory( m_pstrText, sizeof( char[MAX_CHARSPERLINE] ) );		// Copy the text back into the buffer		CopyMemory( m_pstrText, pstrTemp, Length );	}	else // A normal key was pressed	{		// Make sure the buffer has not overflowed		if( strlen( m_pstrText ) > MAX_CHARSPERLINE )			return E_FAIL;				// Append the text buffer with the character		strncat( m_pstrText, &Key, 1 );	}		return S_OK;}const int MAX_PARAMS = 25;// ------------------------- Command Class// Holds pre parsed commandsclass CCommand{public:		// Holds the main command.  eg 'SetScreenRes'	char* pstrCommand;		// Holds the number of parameters. eg 2	int NumParams;			// Holds the parameters.  eg 640 and 480	char* pstrParams[MAX_PARAMS]; 		// Constructor	CCommand()	{		// Initialize all the variables to 0		pstrCommand = 0;		NumParams = 0;				ZeroMemory( &pstrParams, sizeof( pstrParams ) );	}	// Destructor	~CCommand()	{		// Destroy the command string		// if it exists		if( pstrCommand )			delete pstrCommand;				// Destroy any parameter strings 		// if they exist		for( int i = 0 ; i < MAX_PARAMS ; i++ )		{			if( pstrParams[i] )				delete pstrParams[i];		}	}};typedef int (*CONSOLE_PARSER_CALLBACK)( CCommand* pCommand );// ------------------------- Console Class// Deals with keyboard input, visibility managment, and command parsingclass CConsole{public:	CConsole();	~CConsole();	// Functions:public:	void Shutdown();	HRESULT Initialize( LPDIRECT3DDEVICE8 pDevice, LPDIRECT3DSURFACE8 pTargetSurface );	void Render();	BOOL GetVisibility(){ return m_bVisible; }	void SetVisibility( BOOL bVisible )	{ 		// The render code will figure out when the console		// is not visible.		m_bVisible = TRUE;		// If bVisible is true then the console must be invisible		// and about to animate down.  Otherwise it will be		// animating up.		m_Animation = bVisible ? Down : Up;	}	void OutputString( char* pString );	void Clear();	int OnChar( char Key );	int OnKeyDown( WPARAM wParam );	void SetParserCallback( CONSOLE_PARSER_CALLBACK pfnCallback );	void PreParse( char* pstrText, CCommand* pCommand );protected:	void RotateEntries();		// Variables:protected:	BOOL m_bInitialized;	// Has the console been initialized?		int m_Width;	// The width of the console surface	int m_Height;	// The height of the console surface	LPDIRECT3DSURFACE8 m_pConsoleSurface; // Pointer to the console surface	LPDIRECT3DSURFACE8 m_pConsoleBackgroundSurf; // Pointer to the background bitmap surface	LPDIRECT3DSURFACE8 m_pTargetSurface;	// Pointer to the target render surface( eg back buffer )	LPDIRECT3DDEVICE8 m_pDevice;	// Pointer to the device	BOOL m_bVisible;	// Is the console visible?	// The current state of the console	enum ANIM{ Up, Down, None }m_Animation;	CEntry* m_pActiveEntry;	// The active entry(accepts key input)	CEntry* m_pEntryList;	// The list of old entries	// Pointer to an external console parser	CONSOLE_PARSER_CALLBACK m_pfnCallback;	// Is there an external parser?	BOOL m_bParserCallback;};// ConstructorCConsole::CConsole(){	m_pConsoleSurface = 0;	m_pConsoleBackgroundSurf = 0;	m_pTargetSurface = 0;	m_Width = 0;	m_Height = 0;	m_bInitialized = FALSE;	m_bVisible = FALSE;	m_Animation = None;	m_pActiveEntry = 0;	m_pEntryList = 0;	m_pfnCallback = 0;	m_bParserCallback = FALSE;}// DestructorCConsole::~CConsole(){	// Release the console surface	if( m_pConsoleSurface )	{		m_pConsoleSurface->Release();		m_pConsoleSurface = 0;	}	// Release the background bitmap surface	if( m_pConsoleBackgroundSurf )	{		m_pConsoleBackgroundSurf->Release();		m_pConsoleBackgroundSurf = 0;	}	// Release the target surface	if( m_pTargetSurface )	{		m_pTargetSurface->Release();		m_pTargetSurface = 0;	}	// Destroy all of the entries	CEntry* pEntry = m_pEntryList;	CEntry* pTemp = 0;	if( !pEntry )		return;	// Loop for each entry	while( pEntry->GetNext() )	{		// Copy the next entry into a temp pointer		pTemp = pEntry->GetNext();		// Delete the current pointer		delete pEntry;		// Set the current pointer to the next pointer		pEntry = pTemp;	}}// Shutsdown the consolevoid CConsole::Shutdown(){	if( m_pConsoleSurface )	{		m_pConsoleSurface->Release();		m_pConsoleSurface = 0;	}	if( m_pConsoleBackgroundSurf )	{		m_pConsoleBackgroundSurf->Release();		m_pConsoleBackgroundSurf = 0;	}	if( m_pTargetSurface )	{		m_pTargetSurface->Release();		m_pTargetSurface = 0;	}	// Destroy all of the entries	CEntry* pEntry = m_pEntryList;	CEntry* pTemp = 0;	if( !pEntry )		return;	// Loop for each entry	while( pEntry->GetNext() )	{		// Copy the next entry into a temp pointer		pTemp = pEntry->GetNext();		// Delete the current pointer		delete pEntry;		// Set the current pointer to the next pointer		pEntry = pTemp;	}	m_pEntryList = 0;	m_bInitialized = FALSE;}// Sets the external command parservoid CConsole::SetParserCallback( CONSOLE_PARSER_CALLBACK pfnCallback ){	// Set the function pointer	m_pfnCallback = pfnCallback;	// Set the flag to show that a parser has been specified	m_bParserCallback = TRUE;}// Clears the contents of all the entriesvoid CConsole::Clear(){	// Create a pointer to the first entry	CEntry* pEntry = m_pEntryList;	// Loop for every entry	while( pEntry->GetNext() )	{		// Set the entries text to nothing		pEntry->SetText( "" );		// Get the next entry		pEntry = pEntry->GetNext();	}}// Handles character inputint CConsole::OnChar( char Key ){	// This holds the last key pressed	static char LastKey = 0;		// If the console is not visible	// then ignore the keypress	if( !m_bVisible )		return 0;	// Ignore the enter key	if( Key == '\r' )		return 0;	// Change the tab key to a space key	if( Key == '\t' )		Key = ' ';	// Only allow one space	if( (Key == ' ') && (LastKey == ' ') )		return 0;	// Make sure the first character in a line	// is not a space	if( (Key == ' ') && (LastKey == 0 ) )		return 0;	// Only send the message to the active	// entry if the Last Key is not being	// reset	if( Key != 0 )		m_pActiveEntry->OnChar( Key );	// Update the last key pressed variable	LastKey = Key;		return 0;}// Handles non character keyboard inputint CConsole::OnKeyDown( WPARAM wParam ){	int Result = 0; // Holds result of parse operation		// Figure out which key was pressed	switch( wParam )	{		// The F11 key was pressed		case VK_F11:		{			SetVisibility( !GetVisibility() );			break;		}		// The enter key.		case VK_RETURN:		{			// Ignore if the console is not visible			if( !m_bVisible )				return 0;			// Reset the last keypressed			OnChar( 0 );						// Check if a parser has been set			if( m_bParserCallback )			{				// Create a temporary string				char* String = new char[MAX_CHARSPERLINE];				// Get the string from the active entry				m_pActiveEntry->GetText( String, MAX_CHARSPERLINE );				// If nothing was typed just ignore it				if( !MATCH( String, "" ) && !MATCH( String, " " ) )				{					// Create a new command class					CCommand Command;					// Convert the string into a command					PreParse( String, &Command );							// Send the command to the parser					Result = m_pfnCallback( &Command );					if( FAILED( Result ) )						OutputString( "-- Unknown Command --" );				}								// Destroy the temporary string				delete String;			}						// Move all the entries up			RotateEntries();			break;		}		// The left arrow key was pressed		case VK_LEFT:		{			// Treat this like a backspace press			OnChar( '\b' );			break;		}	}	return 0;}// Converts the command string into a// command and a list of parametersvoid CConsole::PreParse( char* pstrText, CCommand* pCommand ){	// The parameter separators are	// the comma and space characters	char Separators[] = " ,";	// String to hold the current parameter	char* Token;	// The number of parameters	int TokenCount = 0;	// Convert the string to lowercase	strlwr( pstrText );	// Get the command string	Token = strtok( pstrText, Separators );	// If the line was not blank...	if( Token )	{		// ...Set the command string to the token.		// Create a string in the command to hold the command string		pCommand->pstrCommand = new char[ strlen( Token ) + 1 ];		// Copy the string into the command string		strcpy( pCommand->pstrCommand, Token );	}	else // The line was blank	{		// Create a single character to hold a blank character.		// This will notify the keypress event that the line		// was empty		pCommand->pstrCommand = new char;		// Copy a blank character into a new		strcpy( pCommand->pstrCommand, " " );		// Set the number of parameters to zero		pCommand->NumParams = 0;		// Return; there is nothing left to do		return;	}	// Get the next token in the string	Token = strtok( NULL, Separators );		// Loop for the rest of the tokens	while( Token != NULL )	{		// Allocate memory in the command for this parameter		pCommand->pstrParams[TokenCount] = new char[ strlen( Token ) + 1 ];		// Copy the parameter into the allocated memory		strcpy( pCommand->pstrParams[TokenCount], Token );		// Get the next token in the string		Token = strtok( NULL, Separators );		// Increase the parameter count		TokenCount++;		// Make sure there are not too many parameters		if( TokenCount > MAX_PARAMS )			break;	}		// Set the number of parameters in command	pCommand->NumParams = TokenCount;}// Output a string to the consolevoid CConsole::OutputString( char* pString ){	// Move the entries up	RotateEntries();	// Set the new active entry to the specified string	m_pActiveEntry->SetText( pString );}// Moves the entries up one row.  The top// entry is deleted and a new one is// created for the bottomvoid CConsole::RotateEntries(){	// Get a pointer to the first entry	CEntry* pEntry = m_pEntryList;	// A temporary entry pointer	CEntry* pTempEntry = 0;	// A pointer to the new entry	CEntry* pNewEntry = 0;	// Loop for each entry	while( pEntry->GetNext() )	{		// Set the temp entry to the current entry		pTempEntry = pEntry;		// Increase the vertical position of the current entry		pEntry->SetVerticalPos( pEntry->GetVerticalPos() - g_AlphabetLetterHeight );		// Set the current entry to the next entry		pEntry = pEntry->GetNext();	}		// The pEntry variable now points to the last	// entry in the list and pTempEntry to the 2nd last.		// Delete the last entry in the list	delete pEntry;	// Get a pointer to the new last entry	pEntry = pTempEntry;	// Set the new last entries pNext pointer to zero	pEntry->SetNext( NULL );	// Create a new entry for the top of the list	pNewEntry = new CEntry;	// Set new entries pNext variable to last first entry	pNewEntry->SetNext( m_pEntryList );	// Set the start of the Entry list to the new entry	m_pEntryList = pNewEntry;	// Set the active entry to the new entry	m_pActiveEntry = pNewEntry;	// Set the vertical position of the new entry to the bottom	// of the console	m_pActiveEntry->SetVerticalPos( (m_Height-5) - g_AlphabetLetterHeight );}// Initializes the consoleHRESULT CConsole::Initialize( LPDIRECT3DDEVICE8 pDevice, LPDIRECT3DSURFACE8 pTargetSurface ){	// Make sure a valid device was specified	if( !pDevice )		return E_FAIL;	// Make sure a valid target surface was specified	if( !pTargetSurface )		return E_FAIL;	HRESULT r = 0;	// Keep a local pointer of the device	m_pDevice = pDevice;	// Keep a local copy of the target suface	m_pTargetSurface = pTargetSurface;	m_pTargetSurface->AddRef();	// Holds information about the target surface	D3DSURFACE_DESC d3dsd;	// Get information about the target surface	m_pTargetSurface->GetDesc( &d3dsd );	// Set the dimensions of the console the width and 1/2 the height of the target	m_Width = d3dsd.Width;	m_Height = d3dsd.Height / 2;	// Create a surface for the console	r = m_pDevice->CreateImageSurface( m_Width, m_Height, D3DFMT_A8R8G8B8, &m_pConsoleSurface );	if( FAILED( r ) )	{		SetError( "Unable to create image surface for console" );		Shutdown();		return E_FAIL;	}	// Load the background bitmap for the console	r = LoadBitmapToSurface( "Console Background.bmp", &m_pConsoleBackgroundSurf, m_pDevice );	if( FAILED( r ) )	{		SetError( "Unable to load console background image" );		Shutdown();		return E_FAIL;	}	m_pEntryList = new CEntry;		// Start the list with a new entry	CEntry* pEntry = m_pEntryList;	// Get a temp pointer to the new entry	m_pActiveEntry = m_pEntryList;	// Set the active entry to the start of the list	// Compute the number of visible rows of text	int VisibleRows = m_Height / g_AlphabetLetterHeight;		// Loop for each possible visible row of text	for( int i = 1 ; i < VisibleRows ; i++ )	{		// Create a new entry		pEntry->SetNext( new CEntry );		// Set its vertical position to above the previous row		pEntry->SetVerticalPos( (m_Height-5) - (i * g_AlphabetLetterHeight) );		// Get a pointer to the new entry		pEntry = pEntry->GetNext();	}	// Set the initialized flag to TRUE	m_bInitialized = TRUE;	return S_OK;}// Renders the console to the target surfacevoid CConsole::Render(){	// Make sure the console has been initialized	if( !m_bInitialized )		return;	// Holds the current vertical position of the 	// console during scrolling operations	static int CurrentY = m_Height;		// If the console is animating down then	// subtract from the current Y coord	if( m_Animation == Down )		CurrentY-=10;	// Else if the console is going up	// then add to the current Y coord	else if( m_Animation == Up )		CurrentY+=10;	// Stop the animation if the console has completely expanded	if( m_Animation == Down && CurrentY == 0 )		m_Animation = None;		// Stop the animation if the console has completely retracted	if( m_Animation == Up && CurrentY == m_Height )	{		m_bVisible = FALSE;		m_Animation = None;	}	// Set the source rectangle	RECT SourceRect = { 0, CurrentY, m_Width, m_Height };	// Set the destination point	POINT DestPoint = { 0, 0 };		// If the console is not visible then return	if( !m_bVisible )		return;	// Copy the background surface to the console surface	D3DXLoadSurfaceFromSurface( m_pConsoleSurface, NULL, NULL, m_pConsoleBackgroundSurf, NULL,									NULL, D3DX_FILTER_POINT, 0 );	// Get a pointer to the start of the entry list	CEntry* pEntry = m_pEntryList;	D3DLOCKED_RECT LockedRect;	m_pConsoleSurface->LockRect( &LockedRect, 0, 0 );	// Loop for each entry in the list	while( pEntry->GetNext() )	{		// Render this entry		pEntry->RenderText( MAX_CHARSPERLINE, (DWORD*)LockedRect.pBits, LockedRect.Pitch );		// Move to the next entry		pEntry = pEntry->GetNext();	}	m_pConsoleSurface->UnlockRect();	// Copy the console to the target surface	m_pDevice->CopyRects( m_pConsoleSurface, &SourceRect, 1, m_pTargetSurface, &DestPoint );}class CSprite{public:	CSprite();	~CSprite();// Functions:public:	HRESULT Initialize( char* strPathName, int SpriteWidth, int SpriteHeight, int NumSprites );	HRESULT Initialize( LPDIRECT3DSURFACE8 pSourceSurface, int SpriteWidth, int SpriteHeight, int NumSprites );	void Shutdown();	HRESULT SelectActiveSprite( int SpriteNum );	HRESULT Render( LPDIRECT3DSURFACE8 pDestSurface );	void SetColorKey( D3DCOLOR ColorKey );	D3DCOLOR GetColorKey(){ return m_ColorKey; }	void SetPosition( int x, int y ){ m_x = x; m_y = y; }	void GetPosition( int* px, int* py){ *px = m_x, *py = m_y; }		void GetBounds( RECT* pRect );	BOOL CheckForCollisionWith( CSprite* pOtherSprite );	void SetVelocity( int vx, int vy )	{ 		m_VelocityX = vx; 		m_VelocityY = vy; 	}	void GetVelocity( int* pvx, int* pvy )	{ 		*pvx = m_VelocityX; 		*pvy = m_VelocityY; 	}	void SetNext( CSprite* pNext ){ m_pNext = pNext; }	CSprite* GetNext(){ return m_pNext; }	void Update();protected:// Variablespublic:	int m_SurfaceWidth;	int m_SurfaceHeight;	int m_SpriteWidth;	int m_SpriteHeight;	int m_NumSprites;	BOOL m_bTransparent;	int m_State;protected:	LPDIRECT3DSURFACE8 m_pSpriteSurface;	LPDIRECT3DSURFACE8 m_pActiveSurface;	BOOL m_bInitialized;	D3DCOLOR m_ColorKey;		int m_x, m_y;	int m_VelocityX;	int m_VelocityY;	CSprite* m_pNext;};CSprite::CSprite(){	m_SurfaceWidth = 0;	m_SurfaceHeight = 0;	m_SpriteWidth = 0;	m_SpriteHeight = 0;	m_NumSprites = 0;	m_pSpriteSurface = 0;	m_pActiveSurface = 0;		m_bInitialized = FALSE;	m_ColorKey = D3DCOLOR_ARGB( 0, 255, 0, 255 );	m_bTransparent = TRUE;	m_x = m_y = 0;	m_VelocityX = 0;	m_VelocityY = 0;	m_State = 0;	m_pNext = 0;}CSprite::~CSprite(){	if( m_pSpriteSurface )	{		m_pSpriteSurface->Release();		m_pSpriteSurface = 0;	}	if( m_pActiveSurface )	{		m_pActiveSurface->Release();		m_pActiveSurface = 0;	}}void CSprite::Shutdown(){	if( m_pSpriteSurface )	{		m_pSpriteSurface->Release();		m_pSpriteSurface = 0;	}	if( m_pActiveSurface )	{		m_pActiveSurface->Release();		m_pActiveSurface = 0;	}	m_SurfaceWidth = 0;	m_SurfaceHeight = 0;	m_SpriteWidth = 0;	m_SpriteHeight = 0;	m_NumSprites = 0;	m_pSpriteSurface = 0;		m_bInitialized = FALSE;}void CSprite::Update(){	m_x += m_VelocityX;	m_y += m_VelocityY;}BOOL CSprite::CheckForCollisionWith( CSprite* pOtherSprite ){	if( !pOtherSprite )		return 0;	RECT ThisRect, OtherRect, TempRect;	GetBounds( &ThisRect );	pOtherSprite->GetBounds( &OtherRect );	if( IntersectRect( &TempRect, &ThisRect, &OtherRect ) )		return TRUE;	else		return FALSE;}void CSprite::GetBounds( RECT* pRect ){	SetRect( pRect, m_x, m_y, m_SpriteWidth + m_x, m_SpriteHeight + m_y );}HRESULT CSprite::Initialize( LPDIRECT3DSURFACE8 pSourceSurface, 							int SpriteWidth, int SpriteHeight, int NumSprites ){	if( m_pSpriteSurface )	{		m_pSpriteSurface->Release();		m_pSpriteSurface = 0;	}	if( m_pActiveSurface )	{		m_pActiveSurface->Release();		m_pActiveSurface = 0;	}	HRESULT r = 0;	NumSprites--;		if( !pSourceSurface )	{		SetError( "Invalid source sprite surface" );		return E_FAIL;	}	m_pSpriteSurface = pSourceSurface;	pSourceSurface->AddRef();	m_SpriteWidth = SpriteWidth;	m_SpriteHeight = SpriteHeight;	m_NumSprites = NumSprites;	D3DSURFACE_DESC d3dsd;	m_pSpriteSurface->GetDesc( &d3dsd );	m_SurfaceWidth = d3dsd.Width;	m_SurfaceHeight = d3dsd.Height;	r = g_pDevice->CreateImageSurface( m_SpriteWidth, m_SpriteHeight, D3DFMT_A8R8G8B8, &m_pActiveSurface );	if( FAILED( r ) )	{		Shutdown();		return E_FAIL;	}	RECT SpriteRect = { 0, 0, SpriteWidth, SpriteHeight };	POINT SpritePoint = { 0, 0 };		g_pDevice->CopyRects( m_pSpriteSurface, &SpriteRect, 1, m_pActiveSurface, &SpritePoint );	m_bInitialized = TRUE;	return S_OK;}HRESULT CSprite::Initialize( char* strPathName, int SpriteWidth, int SpriteHeight, int NumSprites ){	if( m_pSpriteSurface )	{		m_pSpriteSurface->Release();		m_pSpriteSurface = 0;	}	if( m_pActiveSurface )	{		m_pActiveSurface->Release();		m_pActiveSurface = 0;	}	HRESULT r = 0;	NumSprites--;		r = LoadBitmapToSurface( strPathName, &m_pSpriteSurface, g_pDevice );	if( FAILED( r ) )	{		return E_FAIL;	}	m_SpriteWidth = SpriteWidth;	m_SpriteHeight = SpriteHeight;	m_NumSprites = NumSprites;	D3DSURFACE_DESC d3dsd;	m_pSpriteSurface->GetDesc( &d3dsd );	m_SurfaceWidth = d3dsd.Width;	m_SurfaceHeight = d3dsd.Height;	r = g_pDevice->CreateImageSurface( m_SpriteWidth, m_SpriteHeight, D3DFMT_A8R8G8B8, &m_pActiveSurface );	if( FAILED( r ) )	{		Shutdown();		return E_FAIL;	}	RECT SpriteRect = { 0, 0, SpriteWidth, SpriteHeight };	POINT SpritePoint = { 0, 0 };		g_pDevice->CopyRects( m_pSpriteSurface, &SpriteRect, 1, m_pActiveSurface, &SpritePoint );	m_bInitialized = TRUE;	return S_OK;}HRESULT CSprite::SelectActiveSprite( int SpriteNum ){	HRESULT r = 0;	div_t Result;	int OffsetX = 0;	int OffsetY = 0;	int SpritesPerRow = m_SurfaceWidth / m_SpriteWidth;	if( SpriteNum > m_NumSprites )		SpriteNum = 0;	Result = div( SpriteNum, SpritesPerRow );	OffsetX = Result.rem * m_SpriteWidth;	OffsetY = Result.quot* m_SpriteHeight;	if( OffsetX > m_SurfaceWidth )		return E_FAIL;	if( OffsetY > m_SurfaceHeight )		return E_FAIL;	RECT SpriteRect = { OffsetX, OffsetY, OffsetX + m_SpriteWidth, OffsetY + m_SpriteHeight };	POINT DestPoint = { 0, 0 };	r = g_pDevice->CopyRects( m_pSpriteSurface, &SpriteRect, 1, m_pActiveSurface, &DestPoint );	return r;}HRESULT CSprite::Render( LPDIRECT3DSURFACE8 pDestSurface ){	if( !pDestSurface )		return E_FAIL;	HRESULT r = 0;	RECT SourceRect = { 0, 0, m_SpriteWidth, m_SpriteHeight };	POINT DestPoint = { m_x, m_y };		if( m_bTransparent )		CopySurfaceToSurface( &SourceRect, m_pActiveSurface, &DestPoint, pDestSurface, TRUE, m_ColorKey );	else		g_pDevice->CopyRects( m_pActiveSurface, &SourceRect, 1, pDestSurface, &DestPoint );	return r;}class CLayer{public:	CLayer();	~CLayer();// Functionspublic:	void SetColorKey( D3DCOLOR ColorKey );	D3DCOLOR GetColorKey(){ return m_ColorKey; }	void SetVelocity( int vx, int vy ){ m_VelocityX = vx; m_VelocityY = vy; }	void GetVelocity( int* pvx, int* pvy ){ *pvx = m_VelocityX; *pvx = m_VelocityY; }	void SetPosition( int x, int y ){ m_x = x; m_y = y; }	void GetPosition( int* px, int* py){ *px = m_x, *py = m_y; }	void Update();	HRESULT Initialize( char* strPathName, BOOL bTransparent );	HRESULT Render( LPDIRECT3DSURFACE8 pTargetSurface );	void Shutdown();	protected:	// Variablespublic:protected:	LPDIRECT3DSURFACE8 m_pLayerSurface;	BOOL m_bTransparent;	D3DCOLOR m_ColorKey;	int m_x, m_y;	int m_VelocityX;	int m_VelocityY;	int m_SurfaceWidth;	int m_SurfaceHeight;	enum MOVEMENT{ None, Horizontal, Vertical, Both }m_MoveDirection;};CLayer::CLayer(){	m_pLayerSurface = 0;	m_bTransparent = TRUE;	m_ColorKey = D3DCOLOR_ARGB( 0, 255, 0, 255 );	m_x = m_y = 0;	m_VelocityX = 0;	m_VelocityY = 0;	m_SurfaceWidth = 0;	m_SurfaceHeight = 0;	m_MoveDirection = None;}CLayer::~CLayer(){	if( m_pLayerSurface )	{		m_pLayerSurface->Release();		m_pLayerSurface = 0;	}}void CLayer::Update(){	if( m_VelocityX != 0 && m_VelocityY == 0 )		m_MoveDirection = Horizontal;	else if( m_VelocityY != 0 && m_VelocityX == 0 )		m_MoveDirection = Vertical;	else if( m_VelocityY != 0 && m_VelocityX != 0 )		m_MoveDirection = Both;	else if( m_VelocityY == 0 && m_VelocityX == 0 )	{		m_MoveDirection = None;		return;	}		m_x += m_VelocityX;	m_y += m_VelocityY;	if( m_x >= g_DeviceWidth )		m_x = m_x - g_DeviceWidth;	if( m_x <= -g_DeviceWidth )		m_x = m_x + g_DeviceWidth;	if( m_y >= g_DeviceHeight )		m_y = m_y - g_DeviceHeight;	if( m_y <= -g_DeviceHeight )		m_y = m_y + g_DeviceHeight;}void CLayer::Shutdown(){	m_pLayerSurface = 0;	m_bTransparent = TRUE;	m_ColorKey = D3DCOLOR_ARGB( 0, 255, 0, 255 );	m_x = m_y = 0;	m_VelocityX = 0;	m_VelocityY = 0;	m_SurfaceWidth = 0;	m_SurfaceHeight = 0;		if( m_pLayerSurface )	{		m_pLayerSurface->Release();		m_pLayerSurface = 0;	}}HRESULT CLayer::Initialize( char* strPathName, BOOL bTransparent ){	if( m_pLayerSurface )	{		m_pLayerSurface->Release();		m_pLayerSurface = 0;	}		HRESULT r = 0;		r = LoadBitmapToSurface( strPathName, &m_pLayerSurface, g_pDevice );	if( FAILED( r ) )		return E_FAIL;	m_bTransparent = bTransparent;	D3DSURFACE_DESC d3dsd;	m_pLayerSurface->GetDesc( &d3dsd );	m_SurfaceWidth = d3dsd.Width;	m_SurfaceHeight = d3dsd.Height;		return S_OK;	}HRESULT CLayer::Render( LPDIRECT3DSURFACE8 pTargetSurface ){		// If there is no target surface then return failure	if( !pTargetSurface )		return E_FAIL;		// Hods information about the target surface	D3DSURFACE_DESC d3dsd;	// Get information about the target surface	pTargetSurface->GetDesc( &d3dsd );		// Create local copies of the layer position for modification	int OffsetX = m_x;	int OffsetY = m_y;	// If the layers position is less than 0 then rendering	// will fail.  It turns out that moving the layer forward	// by the surface width + the negative offset creates	// the same effect.  So (-10,-10) changes to (630,470)	if( OffsetX < 0 )	{		OffsetX = d3dsd.Width + m_x;		}	if( OffsetY < 0 )	{		OffsetY = m_SurfaceHeight + OffsetY;		}		// Figure out which way the layer is moving	switch( m_MoveDirection )	{		case None:		{			// The layer is not moving so just straight copy it			CopySurfaceToSurface( 0, m_pLayerSurface, 0, pTargetSurface, m_bTransparent, m_ColorKey );			return S_OK;		}		case Horizontal:		{			// The layer is moving horizontally so it needs to			// be split into two different reagions; left and right			RECT RectL, RectR;						// The right rectangle starts at the offset			POINT DestPointR = { OffsetX, OffsetY };			// The left rectangle starts at the origin			POINT DestPointL = { 0, OffsetY };			// Fill in the source dimensions for the right			// rectangle			SetRect( &RectR,	0, 								0, 								m_SurfaceWidth - OffsetX, 								m_SurfaceHeight );			// Fill in the source dimensions for the left			// rectangle			SetRect( &RectL,	m_SurfaceWidth - OffsetX, 								0, 								OffsetX, 								m_SurfaceHeight );			// Copy the left rectangle to the destination surface			CopySurfaceToSurface( &RectL, m_pLayerSurface, &DestPointL, 											pTargetSurface, m_bTransparent, m_ColorKey );			// Copy the right rectangle to the destination surface			CopySurfaceToSurface( &RectR, m_pLayerSurface, &DestPointR, 											pTargetSurface, m_bTransparent, m_ColorKey );			return S_OK;		}		case Vertical:		{			// The layer is moving vertically so it			// needs to be split into 2 regions; top and bottom			RECT RectT, RectB;						// Fill in the destination for the top rectangle			POINT DestPointT = { OffsetX, 0 };			// Fill in the destination for the bottom rectangle			POINT DestPointB = { OffsetX, OffsetY  };					// Fill in the source dimensions for the top rectangle			SetRect( &RectT,	0, 								m_SurfaceHeight - OffsetY, 								m_SurfaceWidth,									OffsetY );						// Fill in the source dimensions for the bottom rectangle			SetRect( &RectB,	0, 								0, 								m_SurfaceWidth, 								m_SurfaceHeight - OffsetY);						// Copy the top rectangle to the destination surface			CopySurfaceToSurface( &RectT, m_pLayerSurface, &DestPointT, 											pTargetSurface, m_bTransparent, m_ColorKey );			// Copy the bottom rectangle to the destination surface			CopySurfaceToSurface( &RectB, m_pLayerSurface, &DestPointB, 											pTargetSurface, m_bTransparent, m_ColorKey );			return S_OK;		}		case Both:		{			// The layer is moving diagonally so			// it needs to be split into four regions			RECT Rect0, Rect1, Rect2, Rect3;			// Fill in the destination points for the four rectangles			POINT	DestPoint0 = { OffsetX, OffsetY }, 					DestPoint1 = { OffsetX, 0 },					DestPoint2 = { 0, OffsetY }, 					DestPoint3 = { 0, 0 };			// Fill in the dimensions for the source rectangles			SetRect( &Rect0, 0, 0, m_SurfaceWidth - OffsetX, m_SurfaceHeight - OffsetY );			SetRect( &Rect1, 0, m_SurfaceHeight - OffsetY, m_SurfaceWidth - OffsetX, OffsetY );					SetRect( &Rect2, m_SurfaceWidth - OffsetX, 0, OffsetX, m_SurfaceHeight - OffsetY );					SetRect( &Rect3, m_SurfaceWidth - OffsetX, m_SurfaceHeight - OffsetY, OffsetX, OffsetY );			// Copy the rectangles to the destination surface			CopySurfaceToSurface( &Rect0, m_pLayerSurface, &DestPoint0, 											pTargetSurface, m_bTransparent, m_ColorKey );			CopySurfaceToSurface( &Rect1, m_pLayerSurface, &DestPoint1, 											pTargetSurface, m_bTransparent, m_ColorKey );			CopySurfaceToSurface( &Rect2, m_pLayerSurface, &DestPoint2, 											pTargetSurface, m_bTransparent, m_ColorKey );			CopySurfaceToSurface( &Rect3, m_pLayerSurface, &DestPoint3, 											pTargetSurface, m_bTransparent, m_ColorKey );			return S_OK;					}	}		return S_OK;}/*****************************************************************************************************************************************						Direct3D 3D Code*****************************************************************************************************************************************/HRESULT CreateViewport(){	HRESULT r = 0;		if( !g_pDevice )		return E_FAIL;	D3DVIEWPORT8 Viewport;	Viewport.X = 0;	Viewport.Y = 0;	Viewport.Width = g_DeviceWidth;	Viewport.Height = g_DeviceHeight;	Viewport.MinZ = 0.0f;	Viewport.MaxZ = 1.0f;	r = g_pDevice->SetViewport( &Viewport );	return r;}void SetProjectionMatrix(){	D3DXMATRIX ProjectionMatrix;	ZeroMemory( &ProjectionMatrix, sizeof( D3DXMATRIX ) );		float ScreenAspect = (float)g_DeviceWidth / (float)g_DeviceHeight;	float FOV = D3DX_PI / 4;		D3DXMatrixPerspectiveFovLH( &ProjectionMatrix, FOV, ScreenAspect, 1.0f, 1000.0f );	g_pDevice->SetTransform( D3DTS_PROJECTION, &ProjectionMatrix );}


It didnt work when i changed the resolution around...

PS: YES, this isnt original code but code from the examples in "zen of d3d game programming"...

[edited by - Pirosan on October 14, 2003 8:23:05 PM]

[edited by - Pirosan on October 14, 2003 8:25:23 PM]
Bow before me... for i am l33t!
make your device type D3DDEVTYPE_REF or D3DDEVTYPE_HAL not D3DDEVTYPE_SW

This topic is closed to new replies.

Advertisement