Click here to Skip to main content
15,896,063 members
Articles / Desktop Programming / MFC

RaceX - A 2D racing game using DirectDraw

Rate me:
Please Sign up or sign in to vote.
4.92/5 (71 votes)
30 Aug 200214 min read 563.4K   25.1K   150  
This is a 2D racing game that uses a DirectX wrapper library. The game has single player and multiplayer support.
  • racex_src.zip
    • RaceX
      • AppLib
      • cCompetition.cpp
      • cCompetition.h
      • cRaceCar.cpp
      • cRaceCar.h
      • cRaceTrack.cpp
      • cRaceTrack.h
      • cTextWriter.cpp
      • cTextWriter.h
      • dsutil.cpp
      • dsutil.h
      • dxutil.cpp
      • dxutil.h
      • icon1.ico
      • RaceX.cpp
      • RaceX.dsp
      • RaceX.dsw
      • RaceX.h
      • racexres.rc
      • ReadMe.txt
      • res
        • Alpha.BMP
        • bmp_background1.bmp
        • bmp_background2.bmp
        • bmp_background3.bmp
        • bmp_background4.bmp
        • bmp_bigcar_blue.bmp
        • bmp_bigcar_green.bmp
        • bmp_bigcar_red.bmp
        • bmp_bigcar_yeallow.bmp
        • bmp_blackptq0.bmp
        • bmp_blackptq1.bmp
        • bmp_blackptq2.bmp
        • bmp_blackptq3.bmp
        • bmp_bluecar.bmp
        • bmp_caret.bmp
        • bmp_currentconnected_title.bmp
        • bmp_cursor.bmp
        • bmp_curveq0.bmp
        • bmp_curveq1.bmp
        • bmp_curveq2.bmp
        • bmp_curveq3.bmp
        • bmp_diagonalq0.bmp
        • bmp_diagonalq1.bmp
        • bmp_diagonalq2.bmp
        • bmp_diagonalq3.bmp
        • bmp_endcurveq0.bmp
        • bmp_endcurveq1.bmp
        • bmp_endcurveq2.bmp
        • bmp_endcurveq3.bmp
        • bmp_endmediumcurveq0p1.bmp
        • bmp_endmediumcurveq0p2.bmp
        • bmp_endmediumcurveq0p3.bmp
        • bmp_endmediumcurveq1p1.bmp
        • bmp_endmediumcurveq1p2.bmp
        • bmp_endmediumcurveq1p3.bmp
        • bmp_endmediumcurveq2p1.bmp
        • bmp_endmediumcurveq2p2.bmp
        • bmp_endmediumcurveq2p3.bmp
        • bmp_endmediumcurveq3p1.bmp
        • bmp_endmediumcurveq3p2.bmp
        • bmp_endmediumcurveq3p3.bmp
        • bmp_finishcomp_panel.bmp
        • bmp_fullroadq0.bmp
        • bmp_fullroadq1.bmp
        • bmp_fullroadq10.bmp
        • bmp_fullroadq11.bmp
        • bmp_fullroadq12.bmp
        • bmp_fullroadq13.bmp
        • bmp_fullroadq14.bmp
        • bmp_fullroadq15.bmp
        • bmp_fullroadq16.bmp
        • bmp_fullroadq17.bmp
        • bmp_fullroadq2.bmp
        • bmp_fullroadq3.bmp
        • bmp_fullroadq4.bmp
        • bmp_fullroadq5.bmp
        • bmp_fullroadq6.bmp
        • bmp_fullroadq7.bmp
        • bmp_fullroadq8.bmp
        • bmp_fullroadq9.bmp
        • bmp_greencar.bmp
        • bmp_halfroadq0.bmp
        • bmp_halfroadq1.bmp
        • bmp_halfroadq2.bmp
        • bmp_halfroadq3.bmp
        • bmp_hz_enddiagq0.bmp
        • bmp_hz_enddiagq1.bmp
        • bmp_hz_enddiagq2.bmp
        • bmp_hz_enddiagq3.bmp
        • bmp_hz_startdiagq0.bmp
        • bmp_hz_startdiagq1.bmp
        • bmp_hz_startdiagq2.bmp
        • bmp_hz_startdiagq3.bmp
        • bmp_mediumcurveq0p1.bmp
        • bmp_mediumcurveq0p2.bmp
        • bmp_mediumcurveq0p3.bmp
        • bmp_mediumcurveq1p1.bmp
        • bmp_mediumcurveq1p2.bmp
        • bmp_mediumcurveq1p3.bmp
        • bmp_mediumcurveq2p1.bmp
        • bmp_mediumcurveq2p2.bmp
        • bmp_mediumcurveq2p3.bmp
        • bmp_mediumcurveq3p1.bmp
        • bmp_mediumcurveq3p2.bmp
        • bmp_mediumcurveq3p3.bmp
        • bmp_middiagq0.bmp
        • bmp_middiagq1.bmp
        • bmp_middiagq2.bmp
        • bmp_middiagq3.bmp
        • bmp_nextraceinfo.bmp
        • bmp_positions.bmp
        • bmp_raceresults_title.bmp
        • bmp_redcar.bmp
        • bmp_sraceroadq0.bmp
        • bmp_sraceroadq1.bmp
        • bmp_sraceroadq2.bmp
        • bmp_sraceroadq3.bmp
        • bmp_startdiagq0.bmp
        • bmp_startdiagq1.bmp
        • bmp_startdiagq2.bmp
        • bmp_startdiagq3.bmp
        • bmp_titlecomp.bmp
        • bmp_vr_enddiagq0.bmp
        • bmp_vr_enddiagq1.bmp
        • bmp_vr_enddiagq2.bmp
        • bmp_vr_enddiagq3.bmp
        • bmp_vr_startdiagq0.bmp
        • bmp_vr_startdiagq1.bmp
        • bmp_vr_startdiagq2.bmp
        • bmp_vr_startdiagq3.bmp
        • bmp_yeallowcar.bmp
        • Car_Pannel.bmp
        • Car_Pannel_Competition.bmp
        • changeoption.WAV
        • COMP_STATUS_TITLE.bmp
        • completed.bmp
        • cooper_tophy.bmp
        • Digital_Small.bmp
        • engine.wav
        • explode_0_blue.bmp
        • explode_0_green.bmp
        • explode_0_red.bmp
        • explode_0_yeallow.bmp
        • explode_135_blue.bmp
        • explode_135_green.bmp
        • explode_135_red.bmp
        • explode_135_yeallow.bmp
        • explode_180_blue.bmp
        • explode_180_green.bmp
        • explode_180_red.bmp
        • explode_180_yeallow.bmp
        • explode_225_blue.bmp
        • explode_225_green.bmp
        • explode_225_red.bmp
        • explode_225_yeallow.bmp
        • explode_270_blue.bmp
        • explode_270_green.bmp
        • explode_270_red.bmp
        • explode_270_yeallow.bmp
        • explode_315_blue.bmp
        • explode_315_green.bmp
        • explode_315_red.bmp
        • explode_315_yeallow.bmp
        • explode_45_blue.bmp
        • explode_45_green.bmp
        • explode_45_red.bmp
        • explode_45_yeallow.bmp
        • explode_90_blue.bmp
        • explode_90_green.bmp
        • explode_90_red.bmp
        • explode_90_yeallow.bmp
        • explosion.wav
        • FinishedTrack.wav
        • firstlight.bmp
        • flags.bmp
        • gold_tophy.bmp
        • grass.bmp
        • helmet.bmp
        • Lap_Results.bmp
        • multiplayerstatus_title.bmp
        • none_tophy.bmp
        • Race_Results.bmp
        • Race_Stats.bmp
        • race_title.bmp
        • sand.bmp
        • Select.WAV
        • semaphore.WAV
        • silver_tophy.bmp
        • Thumbs.db
        • title.bmp
        • Toolbar.bmp
        • type.WAV
        • Verdana.BMP
      • resource.h
      • StdAfx.cpp
      • StdAfx.h
      • Thumbs.db
      • Track01.rxt
      • Track02.rxt
      • Track03.rxt
      • Track04.rxt
      • Track05.rxt
      • Track06.rxt
      • Track07.rxt
      • Track08.rxt
      • Track09.rxt
  • trackeditor_src.zip
    • TrackEditor
      • CheckPointDlg.cpp
      • CheckPointDlg.h
      • cMatrix.cpp
      • cMatrix.h
      • MainFrm.cpp
      • MainFrm.h
      • res
        • bmp_blackptq0.bmp
        • bmp_blackptq1.bmp
        • bmp_blackptq2.bmp
        • bmp_blackptq3.bmp
        • bmp_curveq0.bmp
        • bmp_curveq1.bmp
        • bmp_curveq2.bmp
        • bmp_curveq3.bmp
        • bmp_diagonalq0.bmp
        • bmp_diagonalq1.bmp
        • bmp_diagonalq2.bmp
        • bmp_diagonalq3.bmp
        • bmp_endcurveq0.bmp
        • bmp_endcurveq1.bmp
        • bmp_endcurveq2.bmp
        • bmp_endcurveq3.bmp
        • bmp_endmediumcurveq0p1.bmp
        • bmp_endmediumcurveq0p2.bmp
        • bmp_endmediumcurveq0p3.bmp
        • bmp_endmediumcurveq1p1.bmp
        • bmp_endmediumcurveq1p2.bmp
        • bmp_endmediumcurveq1p3.bmp
        • bmp_endmediumcurveq2p1.bmp
        • bmp_endmediumcurveq2p2.bmp
        • bmp_endmediumcurveq2p3.bmp
        • bmp_endmediumcurveq3p1.bmp
        • bmp_endmediumcurveq3p2.bmp
        • bmp_endmediumcurveq3p3.bmp
        • bmp_fullroadq0.bmp
        • bmp_fullroadq1.bmp
        • bmp_fullroadq10.bmp
        • bmp_fullroadq11.bmp
        • bmp_fullroadq12.bmp
        • bmp_fullroadq13.bmp
        • bmp_fullroadq14.bmp
        • bmp_fullroadq15.bmp
        • bmp_fullroadq16.bmp
        • bmp_fullroadq17.bmp
        • bmp_fullroadq2.bmp
        • bmp_fullroadq3.bmp
        • bmp_fullroadq4.bmp
        • bmp_fullroadq5.bmp
        • bmp_fullroadq6.bmp
        • bmp_fullroadq7.bmp
        • bmp_fullroadq8.bmp
        • bmp_fullroadq9.bmp
        • bmp_halfroadq0.bmp
        • bmp_halfroadq1.bmp
        • bmp_halfroadq2.bmp
        • bmp_halfroadq3.bmp
        • bmp_hz_enddiagq0.bmp
        • bmp_hz_enddiagq1.bmp
        • bmp_hz_enddiagq2.bmp
        • bmp_hz_enddiagq3.bmp
        • bmp_hz_startdiagq0.bmp
        • bmp_hz_startdiagq1.bmp
        • bmp_hz_startdiagq2.bmp
        • bmp_hz_startdiagq3.bmp
        • bmp_mediumcurveq0p1.bmp
        • bmp_mediumcurveq0p2.bmp
        • bmp_mediumcurveq0p3.bmp
        • bmp_mediumcurveq1p1.bmp
        • bmp_mediumcurveq1p2.bmp
        • bmp_mediumcurveq1p3.bmp
        • bmp_mediumcurveq2p1.bmp
        • bmp_mediumcurveq2p2.bmp
        • bmp_mediumcurveq2p3.bmp
        • bmp_mediumcurveq3p1.bmp
        • bmp_mediumcurveq3p2.bmp
        • bmp_mediumcurveq3p3.bmp
        • bmp_middiagq0.bmp
        • bmp_middiagq1.bmp
        • bmp_middiagq2.bmp
        • bmp_middiagq3.bmp
        • bmp_sraceroadq0.bmp
        • bmp_sraceroadq1.bmp
        • bmp_sraceroadq2.bmp
        • bmp_sraceroadq3.bmp
        • bmp_vr_enddiagq0.bmp
        • bmp_vr_enddiagq1.bmp
        • bmp_vr_enddiagq2.bmp
        • bmp_vr_enddiagq3.bmp
        • bmp_vr_startdiagq0.bmp
        • bmp_vr_startdiagq1.bmp
        • bmp_vr_startdiagq2.bmp
        • bmp_vr_startdiagq3.bmp
        • Thumbs.db
        • Toolbar.bmp
        • TrackEditor.ico
        • TrackEditor.rc2
        • TrackEditorDoc.ico
      • Resource.h
      • SetDimensionsDlg.cpp
      • SetDimensionsDlg.h
      • StdAfx.cpp
      • StdAfx.h
      • TrackEditor.clw
      • TrackEditor.cpp
      • TrackEditor.dsp
      • TrackEditor.dsw
      • TrackEditor.h
      • TrackEditor.rc
      • TrackEditorDoc.cpp
      • TrackEditorDoc.h
      • TrackEditorView.cpp
      • TrackEditorView.h
  • racex_demo.zip
    • RaceX.exe
    • Track01.rxt
    • Track02.rxt
    • Track03.rxt
    • Track04.rxt
    • Track05.rxt
    • Track06.rxt
    • Track07.rxt
    • Track08.rxt
    • Track09.rxt
  • trackeditor_demo.zip
    • TrackEditor.exe
// RACE X
//
// Written by Mauricio Teichmann Ritter
//
// Copyright (C) 2002, Brazil. All rights reserved.
// 
//

#include "stdafx.h"
#include "RaceX.h"
#include "cRaceTrack.h"
#include ".\applib\capplication.h"

#include <stdio.h>
#include <search.h>
#include <math.h>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

cRaceTrack::cRaceTrack()
{
	m_iCols = 0;
	m_iRows = 0;

	m_iViewX = 0;
	m_iViewY = 0;

	m_iNumCars = 0;
	
	m_pRaceCars[0] = NULL;
	m_pRaceCars[1] = NULL;
	m_pRaceCars[2] = NULL;
	m_pRaceCars[3] = NULL;

	m_iMaxCheckPoint = 0;

	m_sTrackName = NULL;

	m_iLaps = 0;

}

cRaceTrack::~cRaceTrack()
{

}

void cRaceTrack::Create(int nWidth, int nHeight)
{
	
	m_iState = 0;
	m_lStartTime = 0;


	// Create the Array that will hold the road data
	m_RoadMap.Create(nWidth,nHeight);

	// Create the Hit Checking Region
	m_hcRoadMap.CreateRectBound(nWidth * 40, nHeight * 40);

	// Initialize the width and height variables
	m_iCols = nWidth;
	m_iRows = nHeight;

	static BOOL IsLoaded = FALSE;
	if(!IsLoaded)
	{
		// Initialize the semaphore sound
		m_sndSemaphore.Create(MAKEINTRESOURCE(IDR_SEMAPHORE), DSBCAPS_CTRL3D, DS3DALG_NO_VIRTUALIZATION);
		m_sndSemaphore.m_pSoundBuffer->SetCurrentPosition( 0 );
		IsLoaded = TRUE;
	}
}

void cRaceTrack::SetTile(UINT iTile)
{
	
	// This function is used to load hte tile in its surface member variable
	m_surfTile.Create(200,200);
	switch(iTile)
	{
		case 1:
			m_surfTile.LoadBitmap(GetMainApp()->m_hInst, IDB_TILE_GRASS, 0, 0, 200, 200);
			break;
		case 2:
			m_surfTile.LoadBitmap(GetMainApp()->m_hInst, IDB_TILE_SAND, 0, 0, 200, 200);
			break;
	}
}

void cRaceTrack::Destroy(BOOL bLastDestroy)
{


	// Clean up everything

	m_surfTile.Destroy();

	m_surfDiagonalQ0.Destroy();
	m_surfDiagonalQ1.Destroy();
	m_surfDiagonalQ2.Destroy();
	m_surfDiagonalQ3.Destroy();

	m_surfMidDiagonalQ0.Destroy();
	m_surfMidDiagonalQ1.Destroy();
	m_surfMidDiagonalQ2.Destroy();
	m_surfMidDiagonalQ3.Destroy();

	m_surfBlackPointQ0.Destroy();
	m_surfBlackPointQ1.Destroy();
	m_surfBlackPointQ2.Destroy();
	m_surfBlackPointQ3.Destroy();

	m_surf_HZ_StartDiagonalQ0.Destroy();
	m_surf_HZ_StartDiagonalQ1.Destroy();
	m_surf_HZ_StartDiagonalQ2.Destroy();
	m_surf_HZ_StartDiagonalQ3.Destroy();

	m_surf_HZ_EndDiagonalQ0.Destroy();
	m_surf_HZ_EndDiagonalQ1.Destroy();
	m_surf_HZ_EndDiagonalQ2.Destroy();
	m_surf_HZ_EndDiagonalQ3.Destroy();

	m_surf_VR_StartDiagonalQ0.Destroy();
	m_surf_VR_StartDiagonalQ1.Destroy();
	m_surf_VR_StartDiagonalQ2.Destroy();
	m_surf_VR_StartDiagonalQ3.Destroy();

	m_surf_VR_EndDiagonalQ0.Destroy();
	m_surf_VR_EndDiagonalQ1.Destroy();
	m_surf_VR_EndDiagonalQ2.Destroy();
	m_surf_VR_EndDiagonalQ3.Destroy();

	m_surfSRaceRoadQ0.Destroy();
	m_surfSRaceRoadQ1.Destroy();
	m_surfSRaceRoadQ2.Destroy();
	m_surfSRaceRoadQ3.Destroy();

	m_surfHalfRoadQ0.Destroy();
	m_surfHalfRoadQ1.Destroy();
	m_surfHalfRoadQ2.Destroy();
	m_surfHalfRoadQ3.Destroy();

	m_surfCurveQ0.Destroy();
	m_surfCurveQ1.Destroy();
	m_surfCurveQ2.Destroy();
	m_surfCurveQ3.Destroy();

	m_surfEndCurveQ0.Destroy();
	m_surfEndCurveQ1.Destroy();
	m_surfEndCurveQ2.Destroy();
	m_surfEndCurveQ3.Destroy();

	m_surfFullRoadQ0.Destroy();
	m_surfFullRoadQ1.Destroy();
	m_surfFullRoadQ2.Destroy();
	m_surfFullRoadQ3.Destroy();
	m_surfFullRoadQ4.Destroy();
	m_surfFullRoadQ5.Destroy();
	m_surfFullRoadQ6.Destroy();
	m_surfFullRoadQ7.Destroy();
	m_surfFullRoadQ8.Destroy();
	m_surfFullRoadQ9.Destroy();
	m_surfFullRoadQ10.Destroy();
	m_surfFullRoadQ11.Destroy();
	m_surfFullRoadQ12.Destroy();
	m_surfFullRoadQ13.Destroy();
	m_surfFullRoadQ14.Destroy();
	m_surfFullRoadQ15.Destroy();
	m_surfFullRoadQ16.Destroy();
	m_surfFullRoadQ17.Destroy();


	m_surfMediumCurveQ0P1.Destroy();
	m_surfMediumCurveQ1P1.Destroy();
	m_surfMediumCurveQ2P1.Destroy();
	m_surfMediumCurveQ3P1.Destroy();

	m_surfMediumCurveQ0P2.Destroy();
	m_surfMediumCurveQ1P2.Destroy();
	m_surfMediumCurveQ2P2.Destroy();
	m_surfMediumCurveQ3P2.Destroy();

	m_surfMediumCurveQ0P3.Destroy();
	m_surfMediumCurveQ1P3.Destroy();
	m_surfMediumCurveQ2P3.Destroy();
	m_surfMediumCurveQ3P3.Destroy();

	m_surfEndMediumCurveQ0P1.Destroy();
	m_surfEndMediumCurveQ1P1.Destroy();
	m_surfEndMediumCurveQ2P1.Destroy();
	m_surfEndMediumCurveQ3P1.Destroy();

	m_surfEndMediumCurveQ0P2.Destroy();
	m_surfEndMediumCurveQ1P2.Destroy();
	m_surfEndMediumCurveQ2P2.Destroy();
	m_surfEndMediumCurveQ3P2.Destroy();

	m_surfEndMediumCurveQ0P3.Destroy();
	m_surfEndMediumCurveQ1P3.Destroy();
	m_surfEndMediumCurveQ2P3.Destroy();
	m_surfEndMediumCurveQ3P3.Destroy();


	//m_surfMap.Destroy();
	m_RoadMap.Destroy();

	m_sptrWait.Destroy();

	m_hcRoadMap.Destroy();

	m_surfRaceCompleted.Destroy();

	// Destroy all the cars also
	for(int i=0;i<m_iNumCars;i++)
	{
		m_pRaceCars[i]->Destroy();
	}

	if(m_sTrackName != NULL)
	{
		free(m_sTrackName);
		m_sTrackName = NULL;
	}

	m_iCols = 0;
	m_iRows = 0;

	m_iViewX = 0;
	m_iViewY = 0;

	m_iNumCars = 0;
	
	m_pRaceCars[0] = NULL;
	m_pRaceCars[1] = NULL;
	m_pRaceCars[2] = NULL;
	m_pRaceCars[3] = NULL;

	m_iMaxCheckPoint = 0;

	m_sTrackName = NULL;

	m_iLaps = 0;

	if(bLastDestroy)
		m_sndSemaphore.Destroy();

}

void cRaceTrack::Draw(int iDestX, int iDestY, int nX, int nY, int nWidth, int nHeight)
{
	// This function is used to draw the track in the screen
	
	
	// First we create to reference variables, to know in which position we�re
	// gonna draw the track

	// If we receive the nX and nY parameters we�ll draw the track using these
	// values (this is used in the select track screen)
	// If we don�t inform this values, we�ll use the current view of the player
	// that are stored in the m_iView variables
	int iRefX, iRefY;

	if(nX == -1)
	{
		iRefX = m_iViewX;
		iRefY = m_iViewY;
	}
	else
	{
		iRefX = nX;
		iRefY = nY;
	}





	#define TILE_SIZE 200
	#define ITEM_SIZE 40
	int iSizeX, iSizeY;

	int iTmpX = iDestX, iTmpY = iDestY;

	// First we�ll start drawing the tile
	// We need to draw the tile based on the current view of the iRef variables
	while(iTmpX < iDestX+nWidth)
	{
		while(iTmpY < iDestY+nHeight)
		{
			if(iTmpX+TILE_SIZE > iDestX+nWidth)
				iSizeX = TILE_SIZE - ((iTmpX+TILE_SIZE)-(iDestX+nWidth));
			else
				iSizeX = TILE_SIZE;

			if(iTmpY+TILE_SIZE > iDestY+nHeight)
				iSizeY = TILE_SIZE - ((iTmpY+TILE_SIZE)-(iDestY+nHeight));
			else
				iSizeY = TILE_SIZE;

			m_surfTile.Draw(GetMainApp()->m_pBackBuffer, iTmpX, iTmpY, iRefX % TILE_SIZE, iRefY % TILE_SIZE, iSizeX-(iRefX % TILE_SIZE), iSizeY-(iRefY % TILE_SIZE));

			iTmpY += TILE_SIZE - iRefY % TILE_SIZE;
			iRefY = 0;
		}
		iTmpX += TILE_SIZE - iRefX % TILE_SIZE;
		iTmpY = iDestY;
		if(nX == -1)
		{
			iRefY = m_iViewY;
		}
		else
		{
			iRefY = nY;
		}

		iRefX = 0;
	}

	
	int iItemX, iItemY;

	iTmpX = iDestX;
	iTmpY = iDestY;

	// Reset the iRef variables (since we use it in the loop to draw the tiles)
	if(nX == -1)
	{
		iRefX = m_iViewX;
		iRefY = m_iViewY;
	}
	else
	{
		iRefX = nX;
		iRefY = nY;
	}

	// Based on the tile matrix, we�ll identify which tiles are visible to the
	// currently view
	// The ItemX and ItemY will hold the Column and Row of the first visible
	// tile
	iItemX = iRefX / ITEM_SIZE;
	iItemY = iRefY / ITEM_SIZE;

	// The iMaxCol and iMaxRow will hold the maximum column and row that we need
	// to show to the user
	int iMaxCol = ceil((double)iRefX / ITEM_SIZE)+ceil((double)nWidth/(double)ITEM_SIZE);
	int iMaxRow = ceil((double)iRefY / ITEM_SIZE)+ceil((double)nHeight/(double)ITEM_SIZE);

	if(iMaxCol > m_iCols)
		iMaxCol = m_iCols;

	if(iMaxRow > m_iRows)
		iMaxRow = m_iRows;

	// Now we�ll loop based on the first visible Column and Row (iItemX and iItemY)
	// and based on the iMaxCol and iMaxRow
	for(int iCol = iItemX;iCol<iMaxCol;iCol++)
	{
		for(int iRow = iItemY;iRow<iMaxRow;iRow++)
		{
			// If we have a tile associated with the current position
			// of the iteration, draw it.
			if(m_RoadMap.GetValue(iCol,iRow) != 0)
			{		

				if(iTmpX+ITEM_SIZE > iDestX+nWidth)
					iSizeX = ITEM_SIZE - ((iTmpX+ITEM_SIZE)-(iDestX+nWidth));
				else
					iSizeX = ITEM_SIZE;

				if(iTmpY+ITEM_SIZE > iDestY+nHeight)
					iSizeY = ITEM_SIZE - ((iTmpY+ITEM_SIZE)-(iDestY+nHeight));
				else
					iSizeY = ITEM_SIZE;

				// The Road type is the LOWORD portion of the DWORD array
				int iType = LOWORD(m_RoadMap.GetValue(iCol,iRow));
							
				if(iSizeX > 0 && iSizeY > 0)
				{
					// Based on the Road Type, draw the tile in the correct position
					switch(iType + ID_ROADTYPE_SRACEROADQ0 - 1)
					{
					case ID_ROADTYPE_DIAGONALQ0:
						m_surfDiagonalQ0.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_DIAGONALQ1:
						m_surfDiagonalQ1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_DIAGONALQ2:
						m_surfDiagonalQ2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_DIAGONALQ3:
						m_surfDiagonalQ3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_MIDDIAGONALQ0:
						m_surfMidDiagonalQ0.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_MIDDIAGONALQ1:
						m_surfMidDiagonalQ1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_MIDDIAGONALQ2:
						m_surfMidDiagonalQ2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_MIDDIAGONALQ3:
						m_surfMidDiagonalQ3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_BLACKPOINTQ0:
						m_surfBlackPointQ0.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_BLACKPOINTQ1:
						m_surfBlackPointQ1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_BLACKPOINTQ2:
						m_surfBlackPointQ2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_BLACKPOINTQ3:
						m_surfBlackPointQ3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_HZ_STARTDIAGONALQ0:
						m_surf_HZ_StartDiagonalQ0.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_HZ_STARTDIAGONALQ1:
						m_surf_HZ_StartDiagonalQ1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_HZ_STARTDIAGONALQ2:
						m_surf_HZ_StartDiagonalQ2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_HZ_STARTDIAGONALQ3:
						m_surf_HZ_StartDiagonalQ3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_VR_STARTDIAGONALQ0:
						m_surf_VR_StartDiagonalQ0.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_VR_STARTDIAGONALQ1:
						m_surf_VR_StartDiagonalQ1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_VR_STARTDIAGONALQ2:
						m_surf_VR_StartDiagonalQ2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_VR_STARTDIAGONALQ3:
						m_surf_VR_StartDiagonalQ3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_HZ_ENDDIAGONALQ0:
						m_surf_HZ_EndDiagonalQ0.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_HZ_ENDDIAGONALQ1:
						m_surf_HZ_EndDiagonalQ1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_HZ_ENDDIAGONALQ2:
						m_surf_HZ_EndDiagonalQ2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_HZ_ENDDIAGONALQ3:
						m_surf_HZ_EndDiagonalQ3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_VR_ENDDIAGONALQ0:
						m_surf_VR_EndDiagonalQ0.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_VR_ENDDIAGONALQ1:
						m_surf_VR_EndDiagonalQ1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_VR_ENDDIAGONALQ2:
						m_surf_VR_EndDiagonalQ2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_VR_ENDDIAGONALQ3:
						m_surf_VR_EndDiagonalQ3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_SRACEROADQ0:
						m_surfSRaceRoadQ0.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_SRACEROADQ1:
			 			m_surfSRaceRoadQ1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_SRACEROADQ2:
						m_surfSRaceRoadQ2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_SRACEROADQ3:
						m_surfSRaceRoadQ3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ROADQ0:
						m_surfHalfRoadQ0.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ROADQ1:
						m_surfHalfRoadQ1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ROADQ2:
						m_surfHalfRoadQ2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ROADQ3:
						m_surfHalfRoadQ3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_CURVEQ0:
						m_surfCurveQ0.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_CURVEQ1:
						m_surfCurveQ1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_CURVEQ2:
						m_surfCurveQ2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_CURVEQ3:
						m_surfCurveQ3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDCURVEQ0:
						m_surfEndCurveQ0.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDCURVEQ1:
						m_surfEndCurveQ1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDCURVEQ2:
						m_surfEndCurveQ2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDCURVEQ3:
						m_surfEndCurveQ3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_FULLROADQ0:
						m_surfFullRoadQ0.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_FULLROADQ1:
						m_surfFullRoadQ1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_FULLROADQ2:
						m_surfFullRoadQ2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_FULLROADQ3:
						m_surfFullRoadQ3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_FULLROADQ4:
						m_surfFullRoadQ4.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_FULLROADQ5:
						m_surfFullRoadQ5.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_FULLROADQ6:
						m_surfFullRoadQ6.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_FULLROADQ7:
						m_surfFullRoadQ7.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_FULLROADQ8:
						m_surfFullRoadQ8.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_FULLROADQ9:
						m_surfFullRoadQ9.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_FULLROADQ10:
						m_surfFullRoadQ10.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_FULLROADQ11:
						m_surfFullRoadQ11.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_FULLROADQ12:
						m_surfFullRoadQ12.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_FULLROADQ13:
						m_surfFullRoadQ13.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_FULLROADQ14:
						m_surfFullRoadQ14.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_FULLROADQ15:
						m_surfFullRoadQ15.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_FULLROADQ16:
						m_surfFullRoadQ16.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_FULLROADQ17:
						m_surfFullRoadQ17.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;

					case ID_ROADTYPE_MEDIUMCURVEQ0P1:
						m_surfMediumCurveQ0P1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_MEDIUMCURVEQ0P2:
						m_surfMediumCurveQ0P2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_MEDIUMCURVEQ0P3:
						m_surfMediumCurveQ0P3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_MEDIUMCURVEQ1P1:
						m_surfMediumCurveQ1P1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_MEDIUMCURVEQ1P2:
						m_surfMediumCurveQ1P2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_MEDIUMCURVEQ1P3:
						m_surfMediumCurveQ1P3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_MEDIUMCURVEQ2P1:
						m_surfMediumCurveQ2P1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_MEDIUMCURVEQ2P2:
						m_surfMediumCurveQ2P2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_MEDIUMCURVEQ2P3:
						m_surfMediumCurveQ2P3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_MEDIUMCURVEQ3P1:
						m_surfMediumCurveQ3P1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_MEDIUMCURVEQ3P2:
						m_surfMediumCurveQ3P2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_MEDIUMCURVEQ3P3:
						m_surfMediumCurveQ3P3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDMEDIUMCURVEQ0P1:
						m_surfEndMediumCurveQ0P1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDMEDIUMCURVEQ0P2:
						m_surfEndMediumCurveQ0P2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDMEDIUMCURVEQ0P3:
						m_surfEndMediumCurveQ0P3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDMEDIUMCURVEQ1P1:
						m_surfEndMediumCurveQ1P1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDMEDIUMCURVEQ1P2:
						m_surfEndMediumCurveQ1P2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDMEDIUMCURVEQ1P3:
						m_surfEndMediumCurveQ1P3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDMEDIUMCURVEQ2P1:
						m_surfEndMediumCurveQ2P1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDMEDIUMCURVEQ2P2:
						m_surfEndMediumCurveQ2P2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDMEDIUMCURVEQ2P3:
						m_surfEndMediumCurveQ2P3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDMEDIUMCURVEQ3P1:
						m_surfEndMediumCurveQ3P1.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDMEDIUMCURVEQ3P2:
						m_surfEndMediumCurveQ3P2.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					case ID_ROADTYPE_ENDMEDIUMCURVEQ3P3:
						m_surfEndMediumCurveQ3P3.Draw(GetMainApp()->m_pBackBuffer,iTmpX, iTmpY, iRefX % ITEM_SIZE, iRefY % ITEM_SIZE, iSizeX-(iRefX % ITEM_SIZE), iSizeY-(iRefY % ITEM_SIZE) );
						break;
					}
				}
			}
			iTmpY += ITEM_SIZE - iRefY % ITEM_SIZE;
			iRefY = 0;
		}
		iTmpX += ITEM_SIZE - iRefX % ITEM_SIZE;
		iTmpY = iDestY;
		if(nX == -1)
		{
			iRefY = m_iViewY;
		}
		else
		{
			iRefY = nY;
		}
		iRefX = 0;
	}
}

void cRaceTrack::SetRoad(int iCol, int iRow, int iType)
{
	// Set something in the Road Map (just used for testing, we use track files);
	m_RoadMap.SetValue(iCol, iRow, MAKELONG(iType,0));
}

void cRaceTrack::RemoveHitRegion()
{

	// Load this bunch of surfaces
	// They are used to build the road map and each one represents
	// a road piece
	
	// Start Race Banner
	m_surfSRaceRoadQ0.Create(40,40, RGB(255,255,255));
	m_surfSRaceRoadQ0.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_SRACEROADQ0, 0, 0, 40, 40);

	m_surfSRaceRoadQ1.Create(40,40, RGB(255,255,255));
	m_surfSRaceRoadQ1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_SRACEROADQ1, 0, 0, 40, 40);

	m_surfSRaceRoadQ2.Create(40,40, RGB(255,255,255));
	m_surfSRaceRoadQ2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_SRACEROADQ2, 0, 0, 40, 40);
	
	m_surfSRaceRoadQ3.Create(40,40, RGB(255,255,255));
	m_surfSRaceRoadQ3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_SRACEROADQ3, 0, 0, 40, 40);

	// Road Halfs
	m_surfHalfRoadQ0.Create(40,40, RGB(255, 255, 255));
	m_surfHalfRoadQ0.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ROADQ0, 0, 0, 40, 40);

	m_surfHalfRoadQ1.Create(40,40, RGB(255, 255, 255));
	m_surfHalfRoadQ1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ROADQ1, 0, 0, 40, 40);

	m_surfHalfRoadQ2.Create(40,40, RGB(255, 255, 255));
	m_surfHalfRoadQ2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ROADQ2, 0, 0, 40, 40);

	m_surfHalfRoadQ3.Create(40,40, RGB(255, 255, 255));
	m_surfHalfRoadQ3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ROADQ3, 0, 0, 40, 40);

	m_surfFullRoadQ0.Create(40,40);
	m_surfFullRoadQ0.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ0, 0, 0, 40, 40);

	m_surfFullRoadQ1.Create(40,40);
	m_surfFullRoadQ1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ1, 0, 0, 40, 40);
	
	m_surfFullRoadQ2.Create(40,40);
	m_surfFullRoadQ2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ2, 0, 0, 40, 40);
	
	m_surfFullRoadQ3.Create(40,40);
	m_surfFullRoadQ3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ3, 0, 0, 40, 40);

	m_surfFullRoadQ4.Create(40,40);
	m_surfFullRoadQ4.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ4, 0, 0, 40, 40);

	m_surfFullRoadQ5.Create(40,40);
	m_surfFullRoadQ5.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ5, 0, 0, 40, 40);

	m_surfFullRoadQ6.Create(40,40);
	m_surfFullRoadQ6.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ6, 0, 0, 40, 40);
	
	m_surfFullRoadQ7.Create(40,40);
	m_surfFullRoadQ7.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ7, 0, 0, 40, 40);

	m_surfFullRoadQ8.Create(40,40);
	m_surfFullRoadQ8.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ8, 0, 0, 40, 40);

	m_surfFullRoadQ9.Create(40,40);
	m_surfFullRoadQ9.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ9, 0, 0, 40, 40);

	m_surfFullRoadQ10.Create(40,40);
	m_surfFullRoadQ10.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ10, 0, 0, 40, 40);

	m_surfFullRoadQ11.Create(40,40);
	m_surfFullRoadQ11.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ11, 0, 0, 40, 40);

	m_surfFullRoadQ12.Create(40,40);
	m_surfFullRoadQ12.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ12, 0, 0, 40, 40);

	m_surfFullRoadQ13.Create(40,40);
	m_surfFullRoadQ13.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ13, 0, 0, 40, 40);

	m_surfFullRoadQ14.Create(40,40);
	m_surfFullRoadQ14.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ14, 0, 0, 40, 40);

	m_surfFullRoadQ15.Create(40,40);
	m_surfFullRoadQ15.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ15, 0, 0, 40, 40);

	m_surfFullRoadQ16.Create(40,40);
	m_surfFullRoadQ16.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ16, 0, 0, 40, 40);

	m_surfFullRoadQ17.Create(40,40);
	m_surfFullRoadQ17.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_FULLROADQ17, 0, 0, 40, 40);

	m_surfCurveQ0.Create(40,40, RGB(255, 255, 255));
	m_surfCurveQ0.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_CURVEQ0, 0, 0, 40, 40);

	m_surfCurveQ1.Create(40,40, RGB(255, 255, 255));
	m_surfCurveQ1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_CURVEQ1, 0, 0, 40, 40);

	m_surfCurveQ2.Create(40,40, RGB(255, 255, 255));
	m_surfCurveQ2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_CURVEQ2, 0, 0, 40, 40);

	m_surfCurveQ3.Create(40,40, RGB(255, 255, 255));
	m_surfCurveQ3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_CURVEQ3, 0, 0, 40, 40);

	m_surfEndCurveQ0.Create(40,40, RGB(255, 255, 255));
	m_surfEndCurveQ0.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDCURVEQ0, 0, 0, 40, 40);

	m_surfEndCurveQ1.Create(40,40, RGB(255, 255, 255));
	m_surfEndCurveQ1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDCURVEQ1, 0, 0, 40, 40);

	m_surfEndCurveQ2.Create(40,40, RGB(255, 255, 255));
	m_surfEndCurveQ2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDCURVEQ2, 0, 0, 40, 40);

	m_surfEndCurveQ3.Create(40,40, RGB(255, 255, 255));
	m_surfEndCurveQ3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDCURVEQ3, 0, 0, 40, 40);

	m_surfMediumCurveQ0P1.Create(40,40, RGB(255, 255, 255));
	m_surfMediumCurveQ0P1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MEDIUMCURVEQ0P1, 0, 0, 40, 40);

	m_surfMediumCurveQ0P2.Create(40,40, RGB(255, 255, 255));
	m_surfMediumCurveQ0P2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MEDIUMCURVEQ0P2, 0, 0, 40, 40);

	m_surfMediumCurveQ0P3.Create(40,40, RGB(255, 255, 255));
	m_surfMediumCurveQ0P3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MEDIUMCURVEQ0P3, 0, 0, 40, 40);

	m_surfMediumCurveQ1P1.Create(40,40, RGB(255, 255, 255));
	m_surfMediumCurveQ1P1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MEDIUMCURVEQ1P1, 0, 0, 40, 40);

	m_surfMediumCurveQ1P2.Create(40,40, RGB(255, 255, 255));
	m_surfMediumCurveQ1P2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MEDIUMCURVEQ1P2, 0, 0, 40, 40);

	m_surfMediumCurveQ1P3.Create(40,40, RGB(255, 255, 255));
	m_surfMediumCurveQ1P3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MEDIUMCURVEQ1P3, 0, 0, 40, 40);

	m_surfMediumCurveQ2P1.Create(40,40, RGB(255, 255, 255));
	m_surfMediumCurveQ2P1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MEDIUMCURVEQ2P1, 0, 0, 40, 40);
	
	m_surfMediumCurveQ2P2.Create(40,40, RGB(255, 255, 255));
	m_surfMediumCurveQ2P2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MEDIUMCURVEQ2P2, 0, 0, 40, 40);
	
	m_surfMediumCurveQ2P3.Create(40,40, RGB(255, 255, 255));
	m_surfMediumCurveQ2P3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MEDIUMCURVEQ2P3, 0, 0, 40, 40);

	m_surfMediumCurveQ3P1.Create(40,40, RGB(255, 255, 255));
	m_surfMediumCurveQ3P1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MEDIUMCURVEQ3P1, 0, 0, 40, 40);

	m_surfMediumCurveQ3P2.Create(40,40, RGB(255, 255, 255));
	m_surfMediumCurveQ3P2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MEDIUMCURVEQ3P2, 0, 0, 40, 40);

	m_surfMediumCurveQ3P3.Create(40,40, RGB(255, 255, 255));
	m_surfMediumCurveQ3P3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MEDIUMCURVEQ3P3, 0, 0, 40, 40);



	m_surfEndMediumCurveQ0P1.Create(40,40, RGB(255, 255, 255));
	m_surfEndMediumCurveQ0P1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDMEDIUMCURVEQ0P1, 0, 0, 40, 40);

	m_surfEndMediumCurveQ0P2.Create(40,40, RGB(255, 255, 255));
	m_surfEndMediumCurveQ0P2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDMEDIUMCURVEQ0P2, 0, 0, 40, 40);

	m_surfEndMediumCurveQ0P3.Create(40,40, RGB(255, 255, 255));
	m_surfEndMediumCurveQ0P3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDMEDIUMCURVEQ0P3, 0, 0, 40, 40);

	m_surfEndMediumCurveQ1P1.Create(40,40, RGB(255, 255, 255));
	m_surfEndMediumCurveQ1P1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDMEDIUMCURVEQ1P1, 0, 0, 40, 40);

	m_surfEndMediumCurveQ1P2.Create(40,40, RGB(255, 255, 255));
	m_surfEndMediumCurveQ1P2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDMEDIUMCURVEQ1P2, 0, 0, 40, 40);

	m_surfEndMediumCurveQ1P3.Create(40,40, RGB(255, 255, 255));
	m_surfEndMediumCurveQ1P3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDMEDIUMCURVEQ1P3, 0, 0, 40, 40);

	m_surfEndMediumCurveQ2P1.Create(40,40, RGB(255, 255, 255));
	m_surfEndMediumCurveQ2P1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDMEDIUMCURVEQ2P1, 0, 0, 40, 40);
	
	m_surfEndMediumCurveQ2P2.Create(40,40, RGB(255, 255, 255));
	m_surfEndMediumCurveQ2P2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDMEDIUMCURVEQ2P2, 0, 0, 40, 40);
	
	m_surfEndMediumCurveQ2P3.Create(40,40, RGB(255, 255, 255));
	m_surfEndMediumCurveQ2P3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDMEDIUMCURVEQ2P3, 0, 0, 40, 40);

	m_surfEndMediumCurveQ3P1.Create(40,40, RGB(255, 255, 255));
	m_surfEndMediumCurveQ3P1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDMEDIUMCURVEQ3P1, 0, 0, 40, 40);

	m_surfEndMediumCurveQ3P2.Create(40,40, RGB(255, 255, 255));
	m_surfEndMediumCurveQ3P2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDMEDIUMCURVEQ3P2, 0, 0, 40, 40);

	m_surfEndMediumCurveQ3P3.Create(40,40, RGB(255, 255, 255));
	m_surfEndMediumCurveQ3P3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_ENDMEDIUMCURVEQ3P3, 0, 0, 40, 40);

	
	// Diagonal Roads
	m_surfDiagonalQ0.Create(40,40, RGB(255, 255, 255));
	m_surfDiagonalQ0.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_DIAGONALQ0, 0, 0, 40, 40);

	m_surfDiagonalQ1.Create(40,40, RGB(255, 255, 255));
	m_surfDiagonalQ1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_DIAGONALQ1, 0, 0, 40, 40);

	m_surfDiagonalQ2.Create(40,40, RGB(255, 255, 255));
	m_surfDiagonalQ2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_DIAGONALQ2, 0, 0, 40, 40);

	m_surfDiagonalQ3.Create(40,40, RGB(255, 255, 255));
	m_surfDiagonalQ3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_DIAGONALQ3, 0, 0, 40, 40);

	m_surfMidDiagonalQ0.Create(40,40, RGB(255, 255, 255));
	m_surfMidDiagonalQ0.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MIDDIAGONALQ0, 0, 0, 40, 40);

	m_surfMidDiagonalQ1.Create(40,40, RGB(255, 255, 255));
	m_surfMidDiagonalQ1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MIDDIAGONALQ1, 0, 0, 40, 40);

	m_surfMidDiagonalQ2.Create(40,40, RGB(255, 255, 255));
	m_surfMidDiagonalQ2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MIDDIAGONALQ2, 0, 0, 40, 40);

	m_surfMidDiagonalQ3.Create(40,40, RGB(255, 255, 255));
	m_surfMidDiagonalQ3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_MIDDIAGONALQ3, 0, 0, 40, 40);

	m_surfBlackPointQ0.Create(40,40, RGB(255, 255, 255));
	m_surfBlackPointQ0.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_BLACKPOINTQ0, 0, 0, 40, 40);

	m_surfBlackPointQ1.Create(40,40, RGB(255, 255, 255));
	m_surfBlackPointQ1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_BLACKPOINTQ1, 0, 0, 40, 40);

	m_surfBlackPointQ2.Create(40,40, RGB(255, 255, 255));
	m_surfBlackPointQ2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_BLACKPOINTQ2, 0, 0, 40, 40);

	m_surfBlackPointQ3.Create(40,40, RGB(255, 255, 255));
	m_surfBlackPointQ3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_BLACKPOINTQ3, 0, 0, 40, 40);

	m_surf_HZ_StartDiagonalQ0.Create(40,40, RGB(255, 255, 255));
	m_surf_HZ_StartDiagonalQ0.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_HZ_STARTDIAGONALQ0, 0, 0, 40, 40);

	m_surf_HZ_StartDiagonalQ1.Create(40,40, RGB(255, 255, 255));
	m_surf_HZ_StartDiagonalQ1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_HZ_STARTDIAGONALQ1, 0, 0, 40, 40);

	m_surf_HZ_StartDiagonalQ2.Create(40,40, RGB(255, 255, 255));
	m_surf_HZ_StartDiagonalQ2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_HZ_STARTDIAGONALQ2, 0, 0, 40, 40);

	m_surf_HZ_StartDiagonalQ3.Create(40,40, RGB(255, 255, 255));
	m_surf_HZ_StartDiagonalQ3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_HZ_STARTDIAGONALQ3, 0, 0, 40, 40);


	m_surf_HZ_EndDiagonalQ0.Create(40,40, RGB(255, 255, 255));
	m_surf_HZ_EndDiagonalQ0.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_HZ_ENDDIAGONALQ0, 0, 0, 40, 40);

	m_surf_HZ_EndDiagonalQ1.Create(40,40, RGB(255, 255, 255));
	m_surf_HZ_EndDiagonalQ1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_HZ_ENDDIAGONALQ1, 0, 0, 40, 40);

	m_surf_HZ_EndDiagonalQ2.Create(40,40, RGB(255, 255, 255));
	m_surf_HZ_EndDiagonalQ2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_HZ_ENDDIAGONALQ2, 0, 0, 40, 40);

	m_surf_HZ_EndDiagonalQ3.Create(40,40, RGB(255, 255, 255));
	m_surf_HZ_EndDiagonalQ3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_HZ_ENDDIAGONALQ3, 0, 0, 40, 40);


	m_surf_VR_StartDiagonalQ0.Create(40,40, RGB(255, 255, 255));
	m_surf_VR_StartDiagonalQ0.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_VR_STARTDIAGONALQ0, 0, 0, 40, 40);

	m_surf_VR_StartDiagonalQ1.Create(40,40, RGB(255, 255, 255));
	m_surf_VR_StartDiagonalQ1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_VR_STARTDIAGONALQ1, 0, 0, 40, 40);

	m_surf_VR_StartDiagonalQ2.Create(40,40, RGB(255, 255, 255));
	m_surf_VR_StartDiagonalQ2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_VR_STARTDIAGONALQ2, 0, 0, 40, 40);

	m_surf_VR_StartDiagonalQ3.Create(40,40, RGB(255, 255, 255));
	m_surf_VR_StartDiagonalQ3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_VR_STARTDIAGONALQ3, 0, 0, 40, 40);

	m_surf_VR_EndDiagonalQ0.Create(40,40, RGB(255, 255, 255));
	m_surf_VR_EndDiagonalQ0.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_VR_ENDDIAGONALQ0, 0, 0, 40, 40);

	m_surf_VR_EndDiagonalQ1.Create(40,40, RGB(255, 255, 255));
	m_surf_VR_EndDiagonalQ1.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_VR_ENDDIAGONALQ1, 0, 0, 40, 40);

	m_surf_VR_EndDiagonalQ2.Create(40,40, RGB(255, 255, 255));
	m_surf_VR_EndDiagonalQ2.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_VR_ENDDIAGONALQ2, 0, 0, 40, 40);

	m_surf_VR_EndDiagonalQ3.Create(40,40, RGB(255, 255, 255));
	m_surf_VR_EndDiagonalQ3.LoadBitmap(GetMainApp()->m_hInst, ID_ROADTYPE_VR_ENDDIAGONALQ3, 0, 0, 40, 40);

	
	// This point arrays are used to remove the polygonal regions of each tile
	// in the hit checking structure
	// When we create the race track, we create a big rectangle that consider
	// all the racetrack invalid. When we call this function, we remove the
	// polygonal regions of this big rectangle, based on 
	// the tile positions and tile types.

	POINT ptsDiagonalQ0[] = {	{2,40}, {40,40}, {40,2} };
	POINT ptsDiagonalQ1[] = {	{0,2}, {37,40}, {0,40} };
	POINT ptsDiagonalQ2[] = {	{2,0}, {41,41}, {40,0} };
	POINT ptsDiagonalQ3[] = {	{0,38}, {38,0}, {0,0} };

	POINT pts_VR_StartDiagonalQ0[] = {	{2,0}, {20,18}, {21,41}, 
										{40,41}, {40,0} };

	POINT pts_VR_StartDiagonalQ1[] = {	{0,0}, {39,0}, {19,19}, 
										{19,40}, {0,40} };

	POINT pts_VR_StartDiagonalQ2[] = {	{19,0}, {40,0}, {40,40}, 
										{0,40}, {19,20} };

	POINT pts_VR_StartDiagonalQ3[] = {	{0,0}, {19,0}, {19,20}, 
										{40,40}, {0,40} };


	POINT pts_HZ_EndDiagonalQ0[] = {	{0,40}, {22,17}, {40,17}, 
										{40,40} };

	POINT pts_HZ_EndDiagonalQ1[] = {	{0,17}, {18,17}, {40,40}, 
										{0,40} };

	POINT pts_HZ_EndDiagonalQ2[] = {	{0,0}, {40,0}, {40,18}, 
										{18,18} };

	POINT pts_HZ_EndDiagonalQ3[] = {	{0,0}, {40,0}, {21,18}, 
										{0,18} };



	POINT pts_HZ_StartDiagonalQ0[] = {	{0,17}, {23,17}, {40,0}, 
										{40,40}, {0,40} };

	POINT pts_HZ_StartDiagonalQ1[] = {	{0,0}, {18,18}, {40,18}, 
										{40,40}, {0,40} };

	POINT pts_HZ_StartDiagonalQ2[] = {	{0,0}, {40,0}, {40,40}, 
										{18,18}, {0,18} };

	POINT pts_HZ_StartDiagonalQ3[] = {	{0,0}, {40,0}, {40,18}, 
										{20,18}, {0,40} };


	POINT ptsCurveQ0[] = {	{0,16}, {12,16}, {18,11}, {19,0},
							{40,0}, {40,40}, {0,40}};

	POINT ptsCurveQ1[] = {	{0,0}, {20,0}, {21,11}, {27,17},
							{40,17}, {40,40}, {0,40}};


	POINT ptsCurveQ2[] = {	{-1,-1}, {41,-1}, {41,41}, {19,41},
							{19,26}, {12,18}, {-1,18}};

	POINT ptsCurveQ3[] = {	{-1,-1}, {40,-1}, {40,19}, {30,20},
							{20,28}, {19,41}, {-1,41}};


	POINT ptsEndCurveQ0[] = {	{40,16}, {25,17}, {19,25}, {19,40},
								{40,40}};

	POINT ptsEndCurveQ1[] = {	{0,16}, {12,17}, {20,25}, {21,40},
								{0,40}};

	POINT ptsEndCurveQ2[] = {	{18,-1}, {20,12}, {27,20}, {41,19},
								{41,-1}};

	POINT ptsEndCurveQ3[] = {	{-1,-1}, {20,-1}, {19,12}, {12,19},
								{-1,20}};
	
	POINT ptsMediumCurveQ0P1[] = {	{18,0}, {40,0}, {40,40}, {0,40},
									{11,27}, {16,13}};

	POINT ptsMediumCurveQ1P1[] = {	{-1,-1}, {21,-1}, {22,14}, {28,29},
									{38,41}, {-1,41}};

	POINT ptsMediumCurveQ2P1[] = {	{3,-1}, {41,-1}, {41,41}, {19,41},
									{18,25}, {11,11}};

	POINT ptsMediumCurveQ3P1[] = {	{-1,-1}, {36,-1}, {28,10}, {21,24},
									{21,41}, {-1,41}};

	POINT ptsMediumCurveQ0P3[] = {	{0,16}, {41,0}, {41,41}, {0,41}};
	POINT ptsMediumCurveQ1P3[] = {	{41,16}, {-1,-1}, {-1,41}, {41,41}};
	POINT ptsMediumCurveQ2P3[] = {	{-1,17}, {41,36}, {41,-1}, {-1,-1}};
	POINT ptsMediumCurveQ3P3[] = {	{-1,36}, {41,18}, {41,-1}, {-1,-1}};

	POINT ptsEndMediumCurveQ0P1[] = {	{20,40}, {20,23}, {33,0}, {40,0},
										{40,40}};

	POINT ptsEndMediumCurveQ0P3[] = {	{0,35}, {23,23}, {40,19}, {40,40},
										{0,40}};

	POINT ptsEndMediumCurveQ1P1[] = {	{5,0}, {18,20}, {19,40}, {0,40},
										{0,0}};

	POINT ptsEndMediumCurveQ1P3[] = {	{0,18}, {20,25}, {40,35}, {40,40},
										{0,40}};

	POINT ptsEndMediumCurveQ2P1[] = {	{20,0}, {21,18}, {36,40}, {40,40},
										{40,0}};

	POINT ptsEndMediumCurveQ2P3[] = {	{0,0}, {20,12}, {40,17}, {40,0},
										{0,0}};

	POINT ptsEndMediumCurveQ3P1[] = {	{20,0}, {19,15}, {5,40}, {0,40},
										{0,0}};

	POINT ptsEndMediumCurveQ3P3[] = {	{0,0}, {40,0}, {40,2}, {0,18},
										{0,0}};

	// Here we mount the race track surface using the tiles of the roads
	// we will also CUT the hit checker map so that the map will only
	// have the invalid regin of the track. If any ship goes in to this
	// region, the ship will explode.

	for(int j=0;j<m_iRows;j++)
	{
		for(int i=0;i<m_iCols;i++)
		{		
			// Get the low order value of the integer
			// The low order value represents the type of the road (tile)
			// we are using (could be a curve or a plain road). The high
			// order word is used to save the check point marks, that are
			// used check if the user completed the lap

			int iType = LOWORD(m_RoadMap.GetValue(i,j));
						
			switch(iType + ID_ROADTYPE_SRACEROADQ0 - 1)
			{
			case ID_ROADTYPE_VR_STARTDIAGONALQ0:
				m_hcRoadMap.RemovePolyFromBound(pts_VR_StartDiagonalQ0, 5, i*40, j*40);
				break;

			case ID_ROADTYPE_VR_STARTDIAGONALQ1:
				m_hcRoadMap.RemovePolyFromBound(pts_VR_StartDiagonalQ1, 5, i*40, j*40);
				break;

			case ID_ROADTYPE_VR_STARTDIAGONALQ2:
				m_hcRoadMap.RemovePolyFromBound(pts_VR_StartDiagonalQ2, 5, i*40, j*40);
				break;

			case ID_ROADTYPE_VR_STARTDIAGONALQ3:
				m_hcRoadMap.RemovePolyFromBound(pts_VR_StartDiagonalQ3, 5, i*40, j*40);
				break;

			case ID_ROADTYPE_HZ_ENDDIAGONALQ0:
				m_hcRoadMap.RemovePolyFromBound(pts_HZ_EndDiagonalQ0, 4, i*40, j*40);
				break;
			case ID_ROADTYPE_HZ_ENDDIAGONALQ1:
				m_hcRoadMap.RemovePolyFromBound(pts_HZ_EndDiagonalQ1, 4, i*40, j*40);
				break;
			case ID_ROADTYPE_HZ_ENDDIAGONALQ2:
				m_hcRoadMap.RemovePolyFromBound(pts_HZ_EndDiagonalQ2, 4, i*40, j*40);
				break;
			case ID_ROADTYPE_HZ_ENDDIAGONALQ3:
				m_hcRoadMap.RemovePolyFromBound(pts_HZ_EndDiagonalQ3, 4, i*40, j*40);
				break;


			case ID_ROADTYPE_HZ_STARTDIAGONALQ0:
				m_hcRoadMap.RemovePolyFromBound(pts_HZ_StartDiagonalQ0, 5, i*40, j*40);
				break;
			case ID_ROADTYPE_HZ_STARTDIAGONALQ1:
				m_hcRoadMap.RemovePolyFromBound(pts_HZ_StartDiagonalQ1, 5, i*40, j*40);
				break;
			case ID_ROADTYPE_HZ_STARTDIAGONALQ2:
				m_hcRoadMap.RemovePolyFromBound(pts_HZ_StartDiagonalQ2, 5, i*40, j*40);
				break;
			case ID_ROADTYPE_HZ_STARTDIAGONALQ3:
				m_hcRoadMap.RemovePolyFromBound(pts_HZ_StartDiagonalQ3, 5, i*40, j*40);
				break;

			case ID_ROADTYPE_DIAGONALQ0:
				m_hcRoadMap.RemovePolyFromBound(ptsDiagonalQ0, 3, i*40, j*40);
				break;
			case ID_ROADTYPE_DIAGONALQ1:
				m_hcRoadMap.RemovePolyFromBound(ptsDiagonalQ1, 3, i*40, j*40);
				break;
			case ID_ROADTYPE_DIAGONALQ2:
				m_hcRoadMap.RemovePolyFromBound(ptsDiagonalQ2, 3, i*40, j*40);
				break;
			case ID_ROADTYPE_DIAGONALQ3:
				m_hcRoadMap.RemovePolyFromBound(ptsDiagonalQ3, 3, i*40, j*40);
				break;


			case ID_ROADTYPE_SRACEROADQ0:
				m_hcRoadMap.RemoveRectFromBound( (i*40)+20, j*40, 21, 40);
				break;
			case ID_ROADTYPE_SRACEROADQ1:
				m_hcRoadMap.RemoveRectFromBound( (i*40), (j*40), 20, 40);
				break;
			case ID_ROADTYPE_SRACEROADQ2:
				m_hcRoadMap.RemoveRectFromBound( (i*40), (j*40)+18, 40, 20);
				break;
			case ID_ROADTYPE_SRACEROADQ3:
				m_hcRoadMap.RemoveRectFromBound( (i*40), (j*40), 40, 18);
				break;
			case ID_ROADTYPE_ROADQ0:
				m_hcRoadMap.RemoveRectFromBound( (i*40)+20, j*40, 21, 40);
				break;
			case ID_ROADTYPE_ROADQ1:
				m_hcRoadMap.RemoveRectFromBound( (i*40), (j*40), 20, 40);
				break;
			case ID_ROADTYPE_ROADQ2:
				m_hcRoadMap.RemoveRectFromBound( (i*40), (j*40)+18, 40, 22);
				break;
			case ID_ROADTYPE_ROADQ3:
				m_hcRoadMap.RemoveRectFromBound( (i*40), (j*40), 40, 20);
				break;
			case ID_ROADTYPE_CURVEQ0:
				m_hcRoadMap.RemovePolyFromBound(ptsCurveQ0, 7, i*40, j*40);
				break;
			case ID_ROADTYPE_CURVEQ1:
				m_hcRoadMap.RemovePolyFromBound(ptsCurveQ1, 7, i*40, j*40);
				break;
			case ID_ROADTYPE_CURVEQ2:
				m_hcRoadMap.RemovePolyFromBound(ptsCurveQ2, 7, i*40, j*40);
				break;
			case ID_ROADTYPE_CURVEQ3:
				m_hcRoadMap.RemovePolyFromBound(ptsCurveQ3, 7, i*40, j*40);
				break;
			case ID_ROADTYPE_ENDCURVEQ0:
				m_hcRoadMap.RemovePolyFromBound(ptsEndCurveQ0, 5, i*40, j*40);
				break;
			case ID_ROADTYPE_ENDCURVEQ1:
				m_hcRoadMap.RemovePolyFromBound(ptsEndCurveQ1, 5, i*40, j*40);
				break;
			case ID_ROADTYPE_ENDCURVEQ2:
				m_hcRoadMap.RemovePolyFromBound(ptsEndCurveQ2, 5, i*40, j*40);
				break;
			case ID_ROADTYPE_ENDCURVEQ3:
				m_hcRoadMap.RemovePolyFromBound(ptsEndCurveQ3, 5, i*40, j*40);
				break;
			case ID_ROADTYPE_MIDDIAGONALQ0:
			case ID_ROADTYPE_MIDDIAGONALQ1:
			case ID_ROADTYPE_MIDDIAGONALQ2:
			case ID_ROADTYPE_MIDDIAGONALQ3:
			case ID_ROADTYPE_FULLROADQ0:
			case ID_ROADTYPE_FULLROADQ1:
			case ID_ROADTYPE_FULLROADQ2:
			case ID_ROADTYPE_FULLROADQ3:
			case ID_ROADTYPE_FULLROADQ4:
			case ID_ROADTYPE_FULLROADQ5:
			case ID_ROADTYPE_FULLROADQ6:
			case ID_ROADTYPE_FULLROADQ7:
			case ID_ROADTYPE_FULLROADQ8:
			case ID_ROADTYPE_FULLROADQ9:
			case ID_ROADTYPE_FULLROADQ10:
			case ID_ROADTYPE_FULLROADQ11:
			case ID_ROADTYPE_FULLROADQ12:
			case ID_ROADTYPE_FULLROADQ13:
			case ID_ROADTYPE_FULLROADQ14:
			case ID_ROADTYPE_FULLROADQ15:
			case ID_ROADTYPE_FULLROADQ16:
			case ID_ROADTYPE_FULLROADQ17:
				m_hcRoadMap.RemoveRectFromBound( (i*40), (j*40), 40, 40);
				break;
			case ID_ROADTYPE_MEDIUMCURVEQ0P1:
				m_hcRoadMap.RemovePolyFromBound(ptsMediumCurveQ0P1, 6, i*40, j*40);
				break;
			case ID_ROADTYPE_MEDIUMCURVEQ0P2:
				m_hcRoadMap.RemoveRectFromBound( (i*40), (j*40), 40, 40);
				break;
			case ID_ROADTYPE_MEDIUMCURVEQ0P3:
				m_hcRoadMap.RemovePolyFromBound(ptsMediumCurveQ0P3, 4, i*40, j*40);
				break;
			case ID_ROADTYPE_MEDIUMCURVEQ1P1:
				m_hcRoadMap.RemovePolyFromBound(ptsMediumCurveQ1P1, 6, i*40, j*40);
				break;
			case ID_ROADTYPE_MEDIUMCURVEQ1P2:
				m_hcRoadMap.RemoveRectFromBound( (i*40), (j*40), 40, 40);
				break;
			case ID_ROADTYPE_MEDIUMCURVEQ1P3:
				m_hcRoadMap.RemovePolyFromBound(ptsMediumCurveQ1P3, 4, i*40, j*40);
				break;
			case ID_ROADTYPE_MEDIUMCURVEQ2P1:
				m_hcRoadMap.RemovePolyFromBound(ptsMediumCurveQ2P1, 6, i*40, j*40);
				break;
			case ID_ROADTYPE_MEDIUMCURVEQ2P2:
				m_hcRoadMap.RemoveRectFromBound( (i*40), (j*40), 40, 40);
				break;
			case ID_ROADTYPE_MEDIUMCURVEQ2P3:
				m_hcRoadMap.RemovePolyFromBound(ptsMediumCurveQ2P3, 4, i*40, j*40);
				break;
			case ID_ROADTYPE_MEDIUMCURVEQ3P1:
				m_hcRoadMap.RemovePolyFromBound(ptsMediumCurveQ3P1, 6, i*40, j*40);
				break;
			case ID_ROADTYPE_MEDIUMCURVEQ3P2:
				m_hcRoadMap.RemoveRectFromBound( (i*40), (j*40), 40, 40);
				break;
			case ID_ROADTYPE_MEDIUMCURVEQ3P3:
				m_hcRoadMap.RemovePolyFromBound(ptsMediumCurveQ3P3, 4, i*40, j*40);
				break;
			case ID_ROADTYPE_ENDMEDIUMCURVEQ0P1:
				m_hcRoadMap.RemovePolyFromBound(ptsEndMediumCurveQ0P1, 5, i*40, j*40);
				break;
			case ID_ROADTYPE_ENDMEDIUMCURVEQ0P2:
				break;
			case ID_ROADTYPE_ENDMEDIUMCURVEQ0P3:
				m_hcRoadMap.RemovePolyFromBound(ptsEndMediumCurveQ0P3, 5, i*40, j*40);
				break;
			case ID_ROADTYPE_ENDMEDIUMCURVEQ1P1:
				m_hcRoadMap.RemovePolyFromBound(ptsEndMediumCurveQ1P1, 5, i*40, j*40);
				break;
			case ID_ROADTYPE_ENDMEDIUMCURVEQ1P2:
				break;
			case ID_ROADTYPE_ENDMEDIUMCURVEQ1P3:
				m_hcRoadMap.RemovePolyFromBound(ptsEndMediumCurveQ1P3, 5, i*40, j*40);
				break;
			case ID_ROADTYPE_ENDMEDIUMCURVEQ2P1:
				m_hcRoadMap.RemovePolyFromBound(ptsEndMediumCurveQ2P1, 5, i*40, j*40);
				break;
			case ID_ROADTYPE_ENDMEDIUMCURVEQ2P2:
				break;
			case ID_ROADTYPE_ENDMEDIUMCURVEQ2P3:
				m_hcRoadMap.RemovePolyFromBound(ptsEndMediumCurveQ2P3, 5, i*40, j*40);
				break;
			case ID_ROADTYPE_ENDMEDIUMCURVEQ3P1:
				m_hcRoadMap.RemovePolyFromBound(ptsEndMediumCurveQ3P1, 5, i*40, j*40);
				break;
			case ID_ROADTYPE_ENDMEDIUMCURVEQ3P2:
				break;
			case ID_ROADTYPE_ENDMEDIUMCURVEQ3P3:
				m_hcRoadMap.RemovePolyFromBound(ptsEndMediumCurveQ3P3, 5, i*40, j*40);
				break;
			}
		}
	}

	// Create the race Completed surface
	m_surfRaceCompleted.Create(150,90,RGB(0,0,0));
	m_surfRaceCompleted.LoadBitmap(GetMainApp()->m_hInst, IDB_RACECOMPLETED);
}

BOOL cRaceTrack::ReadFromFile(char *lpszFile)
{
	// This function is used to load a race track from a race track file
	// The file have a header with the track name, the number of laps
	// and Track Dimensions.
	//
	// After the header we have an array of DWORD (based on the dimensions)
	// that have the tile information


	Destroy();

	FILE*	hFile;
	int		iCols;
	int		iRows;
	int		iTile;
	int		iValue;
	
	int		iSize;

	char	pBufferHeader[2];

	// Open the track file
	hFile = fopen(lpszFile, "rb");
	if(hFile == NULL)
		return FALSE;

	m_sFileName = lpszFile;
	

	// Read the header
	fread((void*) pBufferHeader, sizeof(char), 2, hFile);
	
	// Read the size of the track name string
	fread((void*) &iSize, sizeof(int), 1, hFile);

	m_sTrackName = (char*) malloc(iSize+1);
	memset(m_sTrackName, '\0', iSize+1);
	fread((void*) m_sTrackName, sizeof(char), iSize, hFile);

	// Read the number of laps
	fread((void*) &m_iLaps, sizeof(int), 1, hFile);

	// Read the track dimension
	fread((void*) &iCols, sizeof(int), 1, hFile);
	fread((void*) &iRows, sizeof(int), 1, hFile);

	// Read the Race Tile
	fread((void*) &iTile, sizeof(int), 1, hFile);

	
	// Now that we have the dimensions, read the DWORD array
	int iRead = 0;

	Create(iCols, iRows);
	
	SetTile(iTile);

	for(int j=0;j<iRows;j++)
	{
		for(int i=0;i<iCols;i++)
		{
			iRead = fread((void*) &iValue, sizeof(int),1,hFile);
			m_RoadMap.SetValue(i,j,iValue);
		}
	}
	
	fclose(hFile);

	// Race track is loaded, remove the polygonal regions of the cHitCheck class
	RemoveHitRegion();
	
	return TRUE;
}


void cRaceTrack::GetStartPosition(int *iX, int *iY)
{
	int i, j, iValue;

	// This function is used to search where is the Race Start Tile
	for(j=0; j<m_iRows; j++)
	{
		for(i=0; i<m_iCols; i++)
		{
			iValue = LOWORD(m_RoadMap.GetValue(i,j)) + ID_ROADTYPE_SRACEROADQ0 - 1;
			if(iValue  >= ID_ROADTYPE_SRACEROADQ0 &&
			   iValue  <= ID_ROADTYPE_SRACEROADQ3)
			{
				*iX = i*40;
				*iY = j*40;
				if(iValue == ID_ROADTYPE_SRACEROADQ0)
					*iX = (i*40)+20;
				if(iValue == ID_ROADTYPE_SRACEROADQ2)
					*iY = (j*40)+20;
				return;
			}
		}
	}

}

void cRaceTrack::AdjustView(cRaceCar *pCar)
{
	#define VIEW_RANGEX 320
	#define VIEW_RANGEY 230

	// This function will adjust the current view based on the player�s car 
	// current position
	int iX, iY;
	pCar->GetPos(&iX, &iY);

	
	if(iX + VIEW_RANGEX >= m_iViewX + 640)
	{
		m_iViewX += (iX + VIEW_RANGEX)-(m_iViewX + 640);
	}
    
	if(iY + VIEW_RANGEY > m_iViewY + 480)
	{
		m_iViewY += (iY + VIEW_RANGEY)-(m_iViewY + 480);
	}

	if(iY - VIEW_RANGEY < m_iViewY)
	{
		m_iViewY -= (m_iViewY)-(iY - VIEW_RANGEY);
	}
	
	if(iX - VIEW_RANGEX < m_iViewX)
	{
		m_iViewX -= (m_iViewX)-(iX - VIEW_RANGEX);
	}

	if(m_iViewY<0)
		m_iViewY = 0;

	if(m_iViewX<0)
		m_iViewX = 0;

	if(m_iViewX > (m_iCols * 40)-640)
		m_iViewX = (m_iCols * 40)-640;

	if(m_iViewY > (m_iRows * 40)-480)
		m_iViewY =(m_iRows * 40)-480;
}

int cRaceTrack::GetViewX()
{
	return m_iViewX;
}

int cRaceTrack::GetViewY()
{
	return m_iViewY;
}

BOOL cRaceTrack::CarHittedRoad(cRaceCar *pCar, int iX, int iY)
{
	//int iX, iY;
	if(iX == -1 && iY == -1)
		pCar->GetPos(&iX, &iY);
	
	return m_hcRoadMap.HaveHitted(&pCar->m_hcRaceCar, iX, iY, 0, 0);
}

int cRaceTrack::GetCheckPoint(int iX, int iY)
{
	// Check if have any check point in the iX and iY position
	iX = iX / 40;
	iY = iY / 40;
	
	if(iX < 0)
		return 0;

	if(iY < 0)
		return 0;

	if(iX > m_iCols-1)
		return 0;

	if(iY > m_iRows-1)
		return 0;

	int iResp = m_RoadMap.GetValue((int)iX,(int)iY);
	// The check point is the LOWER BYTE of the HIWORD of the track DWORD array
	iResp = LOBYTE(HIWORD(iResp));
	return iResp;
}

int cRaceTrack::GetMaxCheckPoint()
{
	// This function is used to get the number of the Last Check point we
	// have in the track

	if(m_iMaxCheckPoint != 0)
		return m_iMaxCheckPoint;

	for(int j=0;j<m_iRows;j++)
	{
		for(int i=0;i<m_iCols;i++)
		{
			if(LOBYTE(HIWORD(m_RoadMap.GetValue(i,j))) > m_iMaxCheckPoint)
				m_iMaxCheckPoint = LOBYTE(HIWORD(m_RoadMap.GetValue(i,j)));
		}
	}


	return m_iMaxCheckPoint;
}

int compare(const void* p1, const void* p2)
{
	// This function is used to sort the cars, so that we know
	// their position in the track
	cRaceCar *pCar1, *pCar2;

	pCar1 = *(cRaceCar**) p1;
	pCar2 = *(cRaceCar**) p2;

//	char buffer[100];

//	sprintf(buffer,"CAR1 %d CAR2 %d", pCar1->m_iLaps, pCar2->m_iLaps);
//	DXTRACE_MSG(buffer);

	if(pCar1->GetCarState() == CARSTATE_RACECOMPLETED &&
		pCar2->GetCarState() != CARSTATE_RACECOMPLETED)
		return -1;

	if(pCar1->GetCarState() == CARSTATE_RACECOMPLETED &&
		pCar2->GetCarState() != CARSTATE_RACECOMPLETED)
		return 1;

	if(pCar1->GetCarState() == CARSTATE_RACECOMPLETED &&
		pCar2->GetCarState() == CARSTATE_RACECOMPLETED)
	{
		if(pCar1->GetPosition() < pCar2->GetPosition())
			return -1;

		if(pCar1->GetPosition() > pCar2->GetPosition())
			return 1;
	}

	if(pCar1->m_iLaps < pCar2->m_iLaps)
	{
		return 1;
	}
	else
	{
		if(pCar1->m_iLaps > pCar2->m_iLaps)
		{
			return -1;
		}
		else
		{
			if(pCar1->m_iCheckPoint < pCar2->m_iCheckPoint)
			{
				return 1;
			}
			else
			{
				if(pCar1->m_iCheckPoint > pCar2->m_iCheckPoint)
					return -1;
				else
				{
					if(pCar1->GetDistanceToNextCheckPoint() > pCar2->GetDistanceToNextCheckPoint())
						return 1;
					else
						return -1;
				}	
			}
		}
	}
}

void cRaceTrack::Process()
{
	
	int		iOffset = 0, i=0;

	// This is the main function of the track
	// Here is where the game really happens. At each game iteration, we�ll call
	// this function to process the car data (including the racecars)

	int iSrcCarX, iSrcCarY, iCarX, iCarY;


	
	// The first thing we do is check if each one of the cars hit another car
	// If they hit another car then the car that hit will be slowed down
	// and the car that was hit will move forward
	// Notice that we�ll only check this if we�re on the single player mode
	// or if we�re hosting a multiplayer game. mutiplayer peers will receive
	// this information in the network package
	if(  
	   ( (GetRaceXApp()->m_bIsMultiplayer == TRUE && GetRaceXApp()->GetMultiplayer()->IsHosting())
	   || GetRaceXApp()->m_bIsMultiplayer == FALSE) && m_iState > 2
	  )
	{   
		for(i=m_iNumCars-1;i>=0;i--)
		{
			for(int j=0;j<i;j++)
			{
				if(i!=j)
				{
					m_pRaceCars[j]->GetPos(&iCarX, &iCarY);
					m_pRaceCars[i]->GetPos(&iSrcCarX, &iSrcCarY);

					if(m_pRaceCars[j]->m_hcRaceCar.HaveHitted(&m_pRaceCars[i]->m_hcRaceCar, iCarX, iCarY, iSrcCarX, iSrcCarY) == TRUE)
					{
						if(m_pRaceCars[j]->GetSpeed() != 0)
						{
							
							if(m_pRaceCars[i]->GetLastCheckPoint() < m_pRaceCars[j]->GetLastCheckPoint())
							{
								m_pRaceCars[i]->HitCar();
								m_pRaceCars[j]->MoveForward(/*m_pRaceCars[i]->GetSpeed() +*/ m_pRaceCars[j]->GetSpeed());
								m_pRaceCars[j]->Accelerate();
							}
							else if (m_pRaceCars[i]->GetLastCheckPoint() < m_pRaceCars[j]->GetLastCheckPoint())
							{
								m_pRaceCars[j]->HitCar();
								m_pRaceCars[i]->MoveForward(/*m_pRaceCars[i]->GetSpeed() +*/ m_pRaceCars[j]->GetSpeed());
								m_pRaceCars[i]->Accelerate();
							}
							else
							{
								if(m_pRaceCars[i]->GetDistanceToNextCheckPoint() > m_pRaceCars[j]->GetDistanceToNextCheckPoint())
								{
									m_pRaceCars[i]->HitCar();
									m_pRaceCars[j]->MoveForward(/*m_pRaceCars[i]->GetSpeed() +*/ m_pRaceCars[j]->GetSpeed());
									m_pRaceCars[j]->Accelerate();
								}
								else
								{
									m_pRaceCars[j]->HitCar();
									m_pRaceCars[i]->MoveForward( /*m_pRaceCars[i]->GetSpeed() +*/ m_pRaceCars[j]->GetSpeed());
									m_pRaceCars[i]->Accelerate();
								}
							}

						}
					}
				}
			}
		}
	}
	
	// In this loop we�ll process each one of the cars and set its position
	for(i=0;i<m_iNumCars;i++)
	{
		// Set the current car position (if we�re hosting a game or are in a single player game)
		if(   ( (GetRaceXApp()->m_bIsMultiplayer == TRUE && GetRaceXApp()->GetMultiplayer()->IsHosting())  || GetRaceXApp()->m_bIsMultiplayer == FALSE) )	
			m_pRaceCars[i]->SetPosition(i+1);
		
		// We�ll only process the car if the semaphore reached the "green" light
		if(m_iState > 2)
			m_pRaceCars[i]->Process(this);
		
		// Here we�ll check if the car hit the Road. If so, we change the
		// car state to CARSTATE_CRASHED_WALL
		if(   ( (GetRaceXApp()->m_bIsMultiplayer == TRUE && GetRaceXApp()->GetMultiplayer()->IsHosting())
		   || GetRaceXApp()->m_bIsMultiplayer == FALSE) 
		   )	
		{
			if(m_pRaceCars[i]->GetCarState() == CARSTATE_OK)
			{
				if(CarHittedRoad(m_pRaceCars[i]) == TRUE)
				{
					m_pRaceCars[i]->SetCarState(CARSTATE_CRASHED_WALL);
				}
			}
		}

		// After processing the car, we will adjust the car view
		if(m_pRaceCars[i]->GetControlType() == CTRL_USER || m_pRaceCars[i]->GetControlType() == CTRL_NETWORK_LOCAL)
		{
			AdjustView(m_pRaceCars[i]);
		}
	}

	// We process all the cars and adjusted the view, now draw each one of the cars
	for(i=0;i<m_iNumCars;i++)
	{

		if(	!(m_pRaceCars[i]->GetCarState() == CARSTATE_RACECOMPLETED &&
			m_pRaceCars[i]->GetLapElapseTime() > 5000)  )
			m_pRaceCars[i]->Draw(GetViewX(), GetViewY());
	
		if(m_pRaceCars[i]->GetCarState() == CARSTATE_RACECOMPLETED && 
		   (m_pRaceCars[i]->GetControlType() == CTRL_USER || m_pRaceCars[i]->GetControlType() == CTRL_NETWORK_LOCAL) )
		{
			m_surfRaceCompleted.Draw(GetMainApp()->m_pBackBuffer, 245, 190);
		}		
	}   

	// This is used to draw the semaphore on the screen
	switch(m_iState)
	{
	case 0:

		m_sptrWait.Create(GetMainApp()->GetInstHandle(), IDB_TRAFFICLIGHT, 120, 60, RGB(0,0,0), 40, 60);
		m_sptrWait.m_iAbsolutePosition = 0;
		m_sptrWait.Draw(GetMainApp()->m_pBackBuffer, 10, 10, FALSE);
		m_lStartTime = GetTickCount();
		m_iState++;
		m_sndSemaphore.Play();
		break;
	case 1:
		if(GetTickCount() - m_lStartTime > 1200)
		{
			m_sptrWait.Draw(GetMainApp()->m_pBackBuffer, 10, 10, TRUE);	
			m_lStartTime = GetTickCount();
			m_iState++;
			m_sndSemaphore.Play();
		}
		else
		{
			m_sptrWait.Draw(GetMainApp()->m_pBackBuffer, 10, 10, FALSE);
		}
		break;
	case 2:
		if(GetTickCount() - m_lStartTime > 1200)
		{
			m_sptrWait.Draw(GetMainApp()->m_pBackBuffer, 10, 10, TRUE);	
			m_lStartTime = GetTickCount();
			m_iState++;
			m_sndSemaphore.Play();
		}
		else
		{
			m_sptrWait.Draw(GetMainApp()->m_pBackBuffer, 10, 10, FALSE);
		}
		break;
	default:
		if(GetTickCount() - m_lStartTime < 1200)
		{
			m_sptrWait.Draw(GetMainApp()->m_pBackBuffer, 10, 10, FALSE);
		}
		break;
	}
	
	
	if(m_iState > 2)
		qsort(m_pRaceCars, m_iNumCars, sizeof(cRaceCar*), compare);

}

cRaceCar* cRaceTrack::GetCar(int iPos)
{
	return m_pRaceCars[iPos];
}

void cRaceTrack::AddCar(cRaceCar *pCar)
{
	// When we add the cars to the race track
	// we need to add them in the correct position
	int iX, iY;

	m_pRaceCars[m_iNumCars] = pCar;
	m_iNumCars++;

	GetStartPosition(&iX, &iY);
	
	switch(m_iNumCars-1)
	{
	case 0:
		pCar->SetPos(iX, iY);
		break;
	case 1:
		pCar->SetPos(iX+40, iY);
		break;
	case 2:
		pCar->SetPos(iX, iY+40);
		break;
	case 3:
		pCar->SetPos(iX+40, iY+40);
		break;
	}

	pCar->Backup();
	
		
}

int cRaceTrack::GetRoadType(int iX, int iY)
{
	iX = (int) iX / 40;
	iY = (int) iY / 40;
	
	if(iX < 0)
		iX = 0;

	if(iY < 0)
		iY = 0;

	if(iX > m_iCols - 1)
	{
		iX = m_iCols - 1;
	}

	if(iY > m_iRows - 1)
		iY = m_iRows - 1;

	int iValue = m_RoadMap.GetValue(iX,iY);
	if(LOWORD(iValue) <= 0)
		return LOWORD(iValue);
	else
		return LOWORD(iValue) + ID_ROADTYPE_SRACEROADQ0 - 1;
}

/*
int cRaceTrack::TurnDirection(int iX, int iY, int iAngle)
{
	int i = 0;
	int iUseX = 0;
	int iUseY = -1;

	while(1)
	{
		if((GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDCURVEQ0 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ0P3 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ0P2 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ0P1)
		   && (iAngle >=0 && iAngle < 90))
		   return TURN_RIGHT;

		if((GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDCURVEQ1 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ1P3 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ1P2 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ1P1)
		   && (iAngle == 0 || iAngle > 270))
		   return TURN_LEFT;


		if((GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDCURVEQ1 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ1P3 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ1P2 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ1P1)
		   && (iAngle >=90 && iAngle < 180))
		   return TURN_RIGHT;

		if((GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDCURVEQ3 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ3P3 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ3P2 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ3P1)
		   && (iAngle > 0 && iAngle <=90))
		   return TURN_LEFT;

		if((GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDCURVEQ2 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ2P3 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ2P2 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ2P1)
		   && (iAngle <=180 && iAngle > 90))
		   return TURN_LEFT;

		if((GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDCURVEQ3 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ3P3 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ3P2 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ3P1)
		   && (iAngle < 270 && iAngle >=180))
		   return TURN_RIGHT;

		if((GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDCURVEQ0 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ0P3 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ0P2 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ0P1)
		   && (iAngle <=270 && iAngle > 180))
		   return TURN_LEFT;

		if((GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDCURVEQ2 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ2P3 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ2P2 ||
		   GetRoadType(iX+(i*iUseX), iY+(i*iUseY)) == ID_ROADTYPE_ENDMEDIUMCURVEQ2P1)
		   && (iAngle >= 270))
		   return TURN_RIGHT;

		// I think this is the crappyest code that ever written
		// but i�m really sleppy... zzzzzz....
		
		if(i==0)
			i+=40;
		else
		{
			if(iUseX==0 || iUseY==0)
			{
				if(iUseY == -1 )
				{
					iUseY = 1;
					iUseX = 0;
				}
				else
					if(iUseY == 1)
					{
						iUseX = -1;
						iUseY = 0;
					}
					else
						if(iUseX == -1)
						{
							iUseX = 1;
							iUseY = 0;
						}
						else
						{
							//i+=40;
							iUseX = 1;
							iUseY = 1;
						}
			}
			else
				if(iUseX==1 && iUseY==1)
				{
					iUseX=-1;
					iUseY=1;
				}
				else
					if(iUseX==-1 && iUseY==1)
					{
						iUseX=1;
						iUseY=-1;
					}
					else
						if(iUseX==1 && iUseY==-1)
						{
							iUseX=-1;
							iUseY=-1;
						}
						else
						{
							iUseY = -1;
							iUseX = 0;
							i+=40;
							if(i > 300)
							   return TURN_RIGHT;

						}
		}
	} // while

	return 0;
}
*/
void cRaceTrack::GetCheckPointPosition(int *iX, int *iY, int iCheckPoint)
{
	// This function is used to get the position of an specific check point
	int i, j, iValue;

	for(j=*iY; j<m_iRows; j++)
	{
		for(i=0; i<m_iCols; i++)
		{
			if(j==*iY)
			{
				if(i<*iX)
				{
					i=*iX;
					if(i > m_iCols-1)
					{
						i = 0;
						j++;
					}
				}
			}
			iValue = LOBYTE(HIWORD(m_RoadMap.GetValue(i,j)));
			if(iValue  == iCheckPoint)
			{
				*iX = i*40;
				*iY = j*40;
				/*if(LOWORD(m_RoadMap.GetValue(i,j)) + ID_ROADTYPE_SRACEROADQ0 - 1 == ID_ROADTYPE_ROADQ0)
					*iX = (i*40)+30;
				if(LOWORD(m_RoadMap.GetValue(i,j)) + ID_ROADTYPE_SRACEROADQ0 - 1 == ID_ROADTYPE_ROADQ2)
					*iY = (j*40)+30;

				if(LOWORD(m_RoadMap.GetValue(i,j)) + ID_ROADTYPE_SRACEROADQ0 - 1 == ID_ROADTYPE_ROADQ1)
					*iX = (i*40)-30;
				if(LOWORD(m_RoadMap.GetValue(i,j)) + ID_ROADTYPE_SRACEROADQ0 - 1 == ID_ROADTYPE_ROADQ3)
					*iY = (j*40)-30;*/

				return;
			}
		}
	}

	*iX = -1;
	*iY = -1;

	return;
}


char* cRaceTrack::GetTrackName()
{
	return m_sTrackName;
}

int cRaceTrack::GetNumberOfLaps()
{
	return m_iLaps;
}

int cRaceTrack::GetNumberOfCars()
{
	return m_iNumCars;
}

int cRaceTrack::GetWidth()
{
	return m_iCols * 40;
}

int cRaceTrack::GetHeight()
{
	return m_iRows * 40;
}

char* cRaceTrack::GetFileName()
{
	return &m_sFileName[0];
}

void cRaceTrack::SetCarInfo(BYTE bID, BYTE bMask, 
							DWORD   dwElapseTime,
							BYTE	bLaps,
							int		iSpeed,
							BYTE	bCarPosition,
							DWORD	dwLastLapTime,
							unsigned short nCarX,
							unsigned short nCarY,
							BYTE	bAngle,
							BYTE	bCarState
							)
{
	
	// This function is used to set the car information
	// Its used on multiplayer game only. If the peer receive a messgae
	// from the host machine with the car information, we need to set this
	// information for each one of the cars.


	for(int i=0;i<m_iNumCars;i++)
	{
		if(m_pRaceCars[i]->GetID() == bID)
		{
			if(bMask & 0x01)
				m_pRaceCars[i]->m_iLaps = bLaps;

			if(bMask & 0x02)
				m_pRaceCars[i]->SetSpeed(iSpeed * 10);

			if(bMask & 0x04)
				m_pRaceCars[i]->SetPosition(bCarPosition);

			if(bMask & 0x08)
			{
				if(dwLastLapTime != 0)
					m_pRaceCars[i]->AddLapTime(dwLastLapTime);
			}


			int iX, iY;
			m_pRaceCars[i]->GetPos(&iX, &iY);

			if(bMask & 0x10)
				iX = nCarX;

			if(bMask & 0x20)
				iY = nCarY;

			m_pRaceCars[i]->SetPos(iX, iY);

			if(bMask & 0x40)
			{
				m_pRaceCars[i]->m_sprCar.m_iAbsolutePosition = bAngle;
				m_pRaceCars[i]->m_iAngle = bAngle * 10;
			}

			if(bMask & 0x80)
				m_pRaceCars[i]->SetCarState(bCarState);
			

			m_pRaceCars[i]->m_dwElapseTime = dwElapseTime;

			return;
		}
	}
}

int cRaceTrack::GetAngle(int iX, int iY)
{
	iX = iX / 40;
	iY = iY / 40;
	
	if(iX < 0)
		return 0;

	if(iY < 0)
		return 0;

	if(iX > m_iCols-1)
		return 0;

	if(iY > m_iRows-1)
		return 0;

	// Get the angle associated with each one of the tiles
	// The angle is used to tell the computer where to head when he is driving
	// This is used only in single player mode
	int iResp = m_RoadMap.GetValue((int)iX,(int)iY);
	iResp = HIBYTE(HIWORD(iResp)) * 10;
	return iResp;

}

void cRaceTrack::SetRemoteKeyboardStatus(BYTE bIdCar, BYTE bStatus)
{
	// When we receive the keyboard status of a peer, we set the member variable

	for(int i=0;i<m_iNumCars;i++)
	{
		if(m_pRaceCars[i]->GetID() == bIdCar)
		{
			m_pRaceCars[i]->m_bRemoteKeyboardStatus = bStatus;
			return;
		}
	}
}

BYTE cRaceTrack::GetLocalCarID()
{
	// Get the ID of the local car
	for(int i=0;i<m_iNumCars;i++)
	{
		if(m_pRaceCars[i]->GetControlType() == CTRL_NETWORK_LOCAL || 
			m_pRaceCars[i]->GetControlType() == CTRL_USER)
		{
			return m_pRaceCars[i]->m_bID;
		}
	}

	return -1;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Brazil Brazil
Mauricio Ritter lives in Brazil, in the city of Porto Alegre. He is working with software development for about 8 years, and most of his work was done at a bank, within a home and office banking system.
Mauricio also holds MCSD, MCSE, MCDBA, MCAD and MCT Microsoft certifications and work as a trainer/consultant in some MS CTEC in his city.
Mauricio also works in his own programming site, aimed to Brazilian Developers: http://www.dotnetmaniacs.com.br

In his spare time he studys korean language...

Comments and Discussions