Skip to main content
GameDev.net gamedev.net
🔒 Locked

Need Help

Started by Sabonis Jan 4, 2003 at 1:19 PM 0 replies 600+ views
Original Post
Sabonis
Sabonis
could you possibly run my code and figure out why it just quits for no reason? I figure it has something to do with the LoadAlphabet(), PrintChar(), PrintString() and UnloadAlphabet() functions. It crashes on me when i debug, forcing me to cold boot. heres the cpp file
      
#define WIN32_LEAN_AND_MEAN

// The main windows include file

#include <windows.h>
#include <mmsystem.h>

#include <d3d8.h>
#include <d3dx8.h>

#include "MustangII.h"

int GameInit();
int GameLoop();
int GameShutdown();
int Render();

#define RENDER_GDI 2 //Render with the GDI
#define RENDER_D3D 1 // Render with Direct 3D
#define RENDER_BOTH 0 //Render with both



// The window procedure to handle events

long 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_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;
		}
		case WM_KEYDOWN:
			{
				switch( wParam )
				{
				case VK_SPACE:
					{
					g_RenderMode++;
					if( g_RenderMode > 2)
						g_RenderMode = 0;
					break;
					}
				default:
					break;
				}
			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 here

int 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[] = "Direct3D Initialization FullScreen";

	// 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_OVERLAPPEDWINDOW,// 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;	// Holds return values


	
	// 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_X8R8G8B8, g_pD3D, &g_pDevice );
	
	if(FAILED(r))
	{
		SetError("Initialization of the device failed");
	return E_FAIL;
	}

	g_pDevice->Clear(0,0, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f,0);
	r = g_pDevice->GetBackBuffer( 0, D3DBACKBUFFER_TYPE_MONO, &g_pBackSurface );
	if( FAILED( r ) )
	{
		SetError( "Couldnt get backbuffer" );
		return E_FAIL;
	}	


	
	LoadAlphabet("Alphabet Small.BMP",16,32);
	
	srand(GetTickCount());
	
	return S_OK;
}


int GameLoop()
{
	Render();

	if( GetAsyncKeyState( VK_ESCAPE ) )
		PostQuitMessage(0);
		

	return S_OK;
}

LPDIRECT3DSURFACE8 g_pBackSurf = 0;

int Render()
{
	HRESULT r = 0;
	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;
	r = g_pBackSurface->LockRect( &Locked, 0, 0 );
	if(FAILED(r))
	{
		SetError("Could not lock the LOCKED surface");
	return E_FAIL;
	}
	DWORD* pLockedData = (DWORD*)Locked.pBits;
	//Locked.Pitch /=4;

	PrintString(10, 30, "The Alphabet Begins with Z!!!", TRUE, D3DCOLOR_ARGB(0, 255, 0, 255),0,0);
	//PrintFrameRate( 550, 400, TRUE, D3DCOLOR_ARGB(0,255,0,255), pLockedData, Locked.Pitch);

	g_pBackSurface->UnlockRect();
	

	g_pDevice->Present(NULL,NULL,NULL,NULL);
	return S_OK;
}



int GameShutdown()
{
	//Delete the DC and bitmap for the GDI image


	//Release the pointer back to the surface

	if( g_pBackSurf)
		g_pBackSurface->Release();
	//Release the surface holding the D3D image

	if(g_pD3DBitmapSurf)
		g_pD3DBitmapSurf->Release();

	
	// Release the pointer to IDirect3DDevice8

	if( g_pDevice )
		g_pDevice->Release();
	
	// Release the pointer to IDirect3D8

	if( g_pD3D )
		g_pD3D->Release();
	UnloadAlphabet();
	return S_OK;
}

    
and heres the .h file
        
#include <stdio.h>
D3DPRESENT_PARAMETERS g_SavedPresParams;
int g_RenderMode = 0;
LPDIRECT3D8 g_pD3D = 0;
LPDIRECT3DDEVICE8 g_pDevice = 0;
LPDIRECT3DSURFACE8 g_pBackSurface = 0;
LPDIRECT3DSURFACE8 g_pD3DBitmapSurf = 0;
HBITMAP g_hGDIBitmap = 0;
HDC g_hGDIBitmapDC = 0;
HWND g_hWndMain;
int g_DeviceWidth = 0;
int g_DeviceHeight = 0;
HRESULT RestoreGraphics();
INT64 g_Frequency = 0;
int g_AlphabetWidth = 0;
int g_AlphabetHeight = 0;
int g_AlphabetLetterWidth = 0;
int g_AlphabetLetterHeight = 0;
int g_AlphabetLettersPerRow = 0;
LPDIRECT3DSURFACE8 g_pAlphabetSurface = 0;
//has the alphabet been loaded yet?

BOOL g_bAlphabetLoaded = FALSE;
BOOL bTransparent;

int g_FrameCount;
int g_FrameRate;

// Output an error to the debug window

void SetError( char* String )
{
	OutputDebugString( "ERROR: " );
	OutputDebugString( String );
	OutputDebugString( "\n" );
}

/**************************************************************
***************************************************************

				Direct3D Initialization Code

***************************************************************
**************************************************************/

// Initializes the Direct3D device

int 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 = 0;
	
	// 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_HAL, 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 RENDERING CODE*********************************

//******************************************************************************




//Set a single pixel to a color


void SetPixel32( int x, int y, DWORD Color, int Pitch, DWORD* pData)
{
	if( x > g_DeviceWidth || x < 0)
		return;
	if(y > g_DeviceHeight || y < 0)
		return;

	pData[ ((Pitch/4) * y) + x ] = Color;
}

//Old slow way of drawing a rectangle

void Rectangle32( D3DRECT* pRect, DWORD Color, int Pitch, DWORD* pData )
{
	int y1 = pRect->y1;
	int y2 = pRect->y2;
	int x1 = pRect->x1;
	int x2 = pRect->x2;

	int Pitch4 = Pitch / 4;
	
	DWORD Offset = y1 * Pitch4 + x1;

	for( int y = y1 ; y < y2 ; y++ ) 
	{
		for( int x = x1 ; x < x2 ; x++ )
		{
			pData[ Offset + x ] = Color;			
		}

		Offset += Pitch4;
	}

}
//New good fast way to draw a rectangle

void Rectangle32Fast( D3DRECT* pRect, DWORD Color, LPDIRECT3DDEVICE8 pDevice)
{

	pDevice->Clear(1,pRect,D3DCLEAR_TARGET, Color, 0.0f, 0);

}
//Loading a bitmap to the primary surface

int LoadBitmapToSurface( char* PathName, LPDIRECT3DSURFACE8* ppSurface, LPDIRECT3DDEVICE8 pDevice)
{
	HRESULT r;
	HBITMAP hBitmap;
	BITMAP Bitmap;

	hBitmap = (HBITMAP)LoadImage(NULL, PathName, IMAGE_BITMAP,0,0,LR_LOADFROMFILE | LR_CREATEDIBSECTION);

	if(hBitmap == NULL)
	{
		SetError("Unable to load Bitmap");
		return E_FAIL;
	}

	GetObject( hBitmap, sizeof(BITMAP),&Bitmap);
	DeleteObject(hBitmap);

	r= pDevice->CreateImageSurface(Bitmap.bmWidth, Bitmap.bmHeight, D3DFMT_X8R8G8B8, ppSurface);

	if(FAILED(r))
	{
		SetError("Unable to create Surface for bitmap to load");
		return E_FAIL;
	}

	r= D3DXLoadSurfaceFromFile(*ppSurface, NULL, NULL, PathName, NULL, D3DX_FILTER_NONE, 0, NULL);

	if(FAILED(r))
	{
		SetError("Unable to load the file to surface");
		return E_FAIL;
	}


	return S_OK;
}


//Create a compatible Device context from GDI for use with DX surfaces


HDC 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));
	//Size of the stucture 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 topdown image )

	bi.bmiHeader.biHeight = -Height;
	//Obsolete  - -Just set to 1

	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;
}

//Delete the bitmap from memory


void DeleteD3DCompatibleDC( HDC hDC, HBITMAP hDibSection)
{

	// Delete the bitmap

	DeleteObject( hDibSection);
	//Delete the DC

	DeleteDC(hDC);
}

HRESULT 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 abou 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 map in the DC

	//is to be copied

	if( !pSrcRect )
		SetRect( &SourceRect, 0, 0, SrcTotalWidth, SrcTotalHeight);
	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 DC source 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;
	}
	//Conver 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 destination pointer by the pitch

			DestOffset+=Pitch32;
			//incerase 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++;
			}
		}
	}
	//Unlock the surface

	pDestSurf->UnlockRect();
	//return success

	return S_OK;
}

//Check for a valid device

HRESULT 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)
		{
			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");
				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;
}

HRESULT RestoreGraphics()
{
	return S_OK;
}

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 se the rectangle to encompass 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 become DWORD compatible

	LockedSource.Pitch /= 4;
	LockedDest.Pitch /= 4;

	//Get 32-bit pointers to the surface data

	DWORD* pSourceData = (DWORD*)LockedSource.pBits;
	DWORD* pDestData = (DWORD*)LockedDest.pBits;

	//Get the offset into the soruce surface

	int SourceOffset = SourceRect.top * LockedSource.Pitch + SourceRect.left;
	//get the offset of 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 requestec

			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 the next pixel in the source

			SourceOffset++;
		}
		//move the source offset to the next row of the image y 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;
}	

HRESULT InitTiming()
{
	//get the number of counts per second

	QueryPerformanceFrequency( (LARGE_INTEGER*) &g_Frequency );

	//if the frequency is zero then the system does not have high performance timers

	if( g_Frequency == 0)
	{
		SetError("The system does not support high resolution timers" );
		return E_FAIL;
	}

	return S_OK;
}

void Pause(int Milliseconds)
{
	//Convert the milliseconds to seconds

	INT64 SecondsDelay = (INT64)Milliseconds * 1000;
	INT64 StartTime;
	INT64 CurrentTime;

	//get the start time

	QueryPerformanceCounter((LARGE_INTEGER*)&StartTime);

	while(TRUE)
	{
		//get the current time

		QueryPerformanceCounter((LARGE_INTEGER*)&CurrentTime);
		//if enough time has passed then break from the loop

		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 difference since the last count


	//get the current count

	QueryPerformanceCounter((LARGE_INTEGER*)&NewCount);

	//if the count is 0 then the 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;
	}
}


HRESULT 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 the global surface

	r = LoadBitmapToSurface(strPathName, &g_pAlphabetSurface, g_pDevice);
	if(FAILED(r))
	{
		SetError("Unable to load the alphabet bitmap");
		return E_FAIL;
	}

	//holds information about the alphabet 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 laded flay to TRUE

	g_bAlphabetLoaded = TRUE;
	
	return S_OK;
}

//Unloads the alphabet from memory

HRESULT 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 alphabet


void 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 coy 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 Transparent, 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

		PrintChar(x + (g_AlphabetLetterWidth * i ), y, String[i], bTransparent, ColorKey, pDestData, DestPitch );
	}
}

void PrintFrameRate(int x, int y, BOOL bTransparent, D3DCOLOR ColorKey, DWORD* pDestData, int DestPitch)
{
	char string[4];
	//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 );
}
      
please try that out, and i appreciate your help, email me if ya want c_chack@yahoo.com [edited by - Sabonis on January 4, 2003 2:21:49 PM]
"Only two things are infinite, the universe and human stupidity, and I'm not sure about the former." - Albert Einstein (1879-1955) That is so very true...

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.