Sorry for the title i couldnt think of any thing to explain it better than that
i am working through a book called " the Zen of direct3d game programming" which i have recently brought but i havent got the CD. i have got to a chapter on layers i have copied the code and as far as i can see it is the same as the books.
the structure of the code is very bad and as i dont have the CD i cant compare it to see if i have done it wrong. I have worked through many bugs but now i have a working demo of layers but it runs very very slowly.
i just wondered if anyone could spot any obvious problems or point me in the right direction.
again the code is quite long and not very well structured so i do appologise for that.
Main
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <stdlib.h>
#include "Engine.h"
#include <MMSystem.h>
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pstCmdLine, int iCmdShow)
{
wc.cbSize = sizeof( WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH);
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon( NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor( NULL, IDC_ARROW);
wc.lpszMenuName = NULL;
wc.lpszClassName = strAppName;
RegisterClassEx( &wc);
hWnd = CreateWindowEx( NULL, strAppName, strAppName, WS_OVERLAPPED | WS_CAPTION |
WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, NULL, NULL, hInstance, NULL);
g_hWndMain = hWnd;
ShowWindow( hWnd, iCmdShow);
UpdateWindow( hWnd);
if(FAILED(GameInit()))
{
SetError( "init failed");
GameShutdown();
return E_FAIL;
}
while( TRUE)
{
if(PeekMessage( &msg,NULL, 0, 0, PM_REMOVE))
{
if(msg.message == WM_QUIT)
break;
TranslateMessage( &msg);
DispatchMessage( &msg);
}
else
{
GameLoop();
}
}
GameShutdown();
return msg.wParam;
}
Engine.h
#include <Windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <D3D9Types.h>
#pragma once
#define RENDER_GDI 2
#define RENDER_D3D 1
#define RENDER_BOTH 0
class CLayer
{
public:
CLayer();
~CLayer();
public:
void SetColorKey( D3DCOLOR ColorKey);
D3DCOLOR GetColorKey(){ return m_ColorKey;}
void SetVelocity(int vx, int vy){ m_VelocityX = vx; m_VelocityY = vy;}
void GetVelocity( int* pvx, int* pvy){ *pvx = m_VelocityX; *pvy = m_VelocityY;}
void SetPosition( int x, int y){ m_x = x; m_y = y;}
void GetPosition( int* px, int* py){*px = m_x; *py =m_y;}
void Update();
HRESULT Initialize( char* strPathName, BOOL vTransparent);
HRESULT Render( LPDIRECT3DSURFACE9 pTargetSurface);
void Shutdown();
protected:
LPDIRECT3DSURFACE9 m_pLayerSurface;
BOOL m_bTransparent;
D3DCOLOR m_ColorKey;
int m_x, m_y;
int m_VelocityX;
int m_VelocityY;
int m_SurfaceWidth;
int m_SurfaceHeight;
enum MOVEMENT{ NONE, HORIZONTAL, VERTICAL, BOTH} m_MoveDirection;
};
class CSprite
{
public:
CSprite();
~CSprite();
protected:
LPDIRECT3DSURFACE9 m_pSpriteSurface;
LPDIRECT3DSURFACE9 m_pActiveSurface;
BOOL m_bInitialized;
D3DCOLOR m_ColorKey;
int m_x, m_y;
int m_VelocityX;
int m_VelocityY;
CSprite* m_pNext;
public:
HRESULT Initialize( char* strPathName, int SpriteWidth, int SpriteHeight, int NumSprites);
HRESULT Initialize( LPDIRECT3DSURFACE9 pSourceSurface, int SpriteWidth,
int SpriteHeight, int NumSprites);
void Shutdown();
HRESULT SelectActiveSprite( int SpriteNum);
HRESULT Render( LPDIRECT3DSURFACE9 pDestSurface);
void SetColorKey( D3DCOLOR ColorKey);
D3DCOLOR GetColorKey() { return m_ColorKey;}
void SetPosition( int x, int y){ m_x = x; m_y = y;}
void GetPosition( int* px, int* py){ *px = m_x; *py = m_y;}
void GetBounds( RECT* pRect);
BOOL CheckForCollisionWith( CSprite * pOtherSprite);
void SetVelocity( int vx, int vy)
{
m_VelocityX;
m_VelocityY;
}
void GetVelocity( int* pvx, int*pvy)
{
*pvx = m_VelocityX;
*pvy = m_VelocityY;
}
void SetNext( CSprite* pNext){ m_pNext = pNext;}
CSprite* GetNext(){ return m_pNext;}
void Update();
public:
int m_SurfaceWidth;
int m_SurfaceHeight;
int m_SpriteWidth;
int m_SpriteHeight;
int m_NumSprites;
BOOL m_bTransparent;
int m_State;
};
CSprite g_RingSprite;
CLayer g_Layer;
int g_AlphabetWidth =0;
int g_AlphabetHeight =0;
int g_AlphabetLetterWidth =0;
int g_AlphabetLetterHeight =0;
int g_AlphabetLettersPerRow =0;
INT64 g_FrameRate;
INT64 g_FrameCount;
HWND hWnd ;
MSG msg;
WNDCLASSEX wc;
static char strAppName[] = "Zong!! - the game of the great ones";
HDC g_phGDIBitmapDC;
HDC g_hDC = NULL;
HWND g_hWndMain ;
LPDIRECT3D9 g_pD3D = 0;
LPDIRECT3DDEVICE9 g_pDevice = 0;
int g_DeviceHeight;
int g_DeviceWidth;
D3DPRESENT_PARAMETERS g_SavedPresParams;
int g_RenderMode =0;
LPDIRECT3DSURFACE9 g_pBackSurface =0;
LPDIRECT3DSURFACE9 g_pD3DBitmapSurf =0;
HBITMAP g_hGDIBitmap =0;
HDC g_hGDIBitmapDC =0;
INT64 g_Frequency =0;
BOOL g_bAlphabetLoaded = FALSE;
LPDIRECT3DSURFACE9 g_pAlphabetSurface =0;
void PrintFrameRate( int x, int y, BOOL bTransparent, D3DCOLOR ColorKey, DWORD* pDestData, int DestPitch);
void PrintChar( int x, int y, char Character, BOOL bTransparent, D3DCOLOR ColorKey,
DWORD* pDestData, int DestPitch);
void PrintString( int x, int y, char* String, BOOL bTransparent, D3DCOLOR ColorKey,
DWORD* pDestData, int DestPitch);
HRESULT UnloadAlphabet();
HRESULT LoadAlphabet( char* strPathName, int LetterWidth, int LetterHeight);
void FrameCount();
float GetNumTicksPerMs();
void Pause( int Milliseconds);
HRESULT InitTiming();
HRESULT CopySurfaceToSurface( RECT* pSourceRect, LPDIRECT3DSURFACE9 pSourceSurf, POINT* pDestPoint,
LPDIRECT3DSURFACE9 pDestSurf, BOOL bTransparent, D3DCOLOR ColorKey);
HRESULT RestoreGraphics();
HRESULT ValidateDevice();
int GameInit();
int GameLoop();
int GameShutdown();
long CALLBACK WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam);
void SetError( char* string);
int InitDirect3DDevice( HWND hWndTarget, int Width, int Height, BOOL bWindowed,
D3DFORMAT FullScreenFormat, LPDIRECT3D9 pD3D,
LPDIRECT3DDEVICE9* ppDevice);
int Render();
HRESULT CopyDCToSurface( LPDIRECT3DSURFACE9 pDestSurf, POINT* pDestPoint,
HDC hDCSource, HBITMAP hDibSection, RECT* pSrcRect, COLORREF ColorKey);
void DeleteD3DCompatibleDC( HDC hDC, HBITMAP hDibSection);
HDC CreateCompatibleDC( int Width, int Height, HBITMAP* phDibSection);
////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT ValidateDevice()
{
HRESULT r =0;
r = g_pDevice->TestCooperativeLevel();
if( FAILED( r))
{
if( r == D3DERR_DEVICELOST)
return E_FAIL;
if( r == D3DERR_DEVICENOTRESET)
{
g_pBackSurface->Release();
r = g_pDevice->Reset( &g_SavedPresParams);
if( FAILED( r))
{
SetError( "Could not reset device");
PostQuitMessage( E_FAIL);
return E_FAIL;
}
r = g_pDevice->GetBackBuffer( 0, 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;
}
void SetError( char* string)
{
OutputDebugString(string);
OutputDebugString("\n");
}
HRESULT CopyDCToSurface( LPDIRECT3DSURFACE9 pDestSurf, POINT* pDestPoint,
HDC hDCSource, HBITMAP hDibSection, RECT* pSrcRect, COLORREF ColorKey)
{
HRESULT r;
RECT SourceRect;
POINT DestPoint;
DIBSECTION DibSection;
D3DLOCKED_RECT LockedRect;
GetObject( hDibSection, sizeof( DIBSECTION), &DibSection);
int SrcTotalWidth = DibSection.dsBm.bmWidth;
int SrcTotalHeight = DibSection.dsBm.bmHeight;
if(!pSrcRect)
SetRect( &SourceRect, 0, 0, SrcTotalWidth, SrcTotalHeight);
else
SourceRect = *(pSrcRect);
if( !pDestPoint)
DestPoint.x = DestPoint.y = 0;
else
DestPoint = *(pDestPoint);
if( !pDestSurf)
return E_FAIL;
if( !hDCSource)
return E_FAIL;
r = pDestSurf->LockRect(&LockedRect, 0, 0);
if( FAILED( r))
{
SetError( "unable to lock the surface for GDI transfer");
return E_FAIL;
}
DWORD* pSrcData = (DWORD*)(DibSection.dsBm.bmBits);
DWORD* pDestData = (DWORD*)(LockedRect.pBits);
int Pitch32 = LockedRect.Pitch / 4;
int SrcHeight = SourceRect.bottom - SourceRect.top;
int SrcWidth = SourceRect.right - SourceRect.left;
DWORD SrcOffset = SourceRect.top * SrcTotalWidth + SourceRect.left;
DWORD DestOffset = DestPoint.y * Pitch32 + DestPoint.x;
if( ColorKey == -1)
{
for( int y =0; y < SrcHeight; y++)
{
memcpy( (void*)&(pDestData[ DestOffset]),(void*)&(pSrcData[SrcOffset]), SrcWidth*4);
DestOffset += Pitch32;
SrcOffset +=SrcTotalWidth;
}
}
else
{
for( int y =0; y< SrcHeight; y++)
{
for( int x =0; x< SrcWidth; x++)
{
if( pSrcData[ SrcOffset] != ColorKey)
pDestData[DestOffset] = pSrcData[ SrcOffset];
SrcOffset++;
DestOffset++;
}
}
}
pDestSurf->UnlockRect();
return S_OK;
}
void DeleteD3DCompatibleDC( HDC hDC, HBITMAP hDibSection)
{
DeleteObject( hDibSection);
DeleteDC( hDC);
}
HDC CreateD3DCompatibleDC( int Width, int Height, HBITMAP* phDibSection)
{
HDC hDC = CreateCompatibleDC(0);
void* pDibSection = 0;
BITMAPINFO bi;
ZeroMemory( &bi, sizeof( BITMAPINFO));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = Width;
bi.bmiHeader.biHeight = Height;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
HBITMAP hDibSection = CreateDIBSection( hDC, &bi, DIB_RGB_COLORS, &pDibSection, NULL, NULL);
SelectObject( hDC, hDibSection);
*phDibSection = hDibSection;
return hDC;
}
long CALLBACK WndProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
switch( uMessage)
{
case WM_CREATE:
{
return 0;
}
case WM_KEYDOWN:
{
switch( wParam)
{
case VK_SPACE:
{
g_RenderMode++;
if( g_RenderMode > 2)
g_RenderMode =0;
break;
}
default:
break;
}
}
case WM_PAINT:
{
ValidateRect( hWnd, NULL);
return 0;
}
case WM_DESTROY:
{
PostQuitMessage( 0);
return 0;
}
default:
{
return DefWindowProc( hWnd, uMessage, wParam, lParam);
}
}
}
int InitDirect3DDevice( HWND hWndTarget, int Width, int Height, BOOL bWindowed,
D3DFORMAT FullScreenFormat, LPDIRECT3D9 pD3D,
LPDIRECT3DDEVICE9* ppDevice)
{
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE d3ddm;
HRESULT r = 0;
if( *ppDevice)
(*ppDevice)->Release();
ZeroMemory( &d3dpp, sizeof( D3DPRESENT_PARAMETERS));
r = pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm);
if(FAILED( r))
{
SetError( " Could not get display adapter information" );
return E_FAIL;
}
d3dpp.BackBufferWidth = Width;
d3dpp.BackBufferHeight = Height;
d3dpp.BackBufferFormat = bWindowed ? d3ddm.Format : FullScreenFormat;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWndTarget;
d3dpp.Windowed = bWindowed;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.FullScreen_RefreshRateInHz = 0;
d3dpp.PresentationInterval = bWindowed ? 0 : D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
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;
}
g_DeviceHeight = Height;
g_DeviceWidth = Width;
g_SavedPresParams = d3dpp;
return S_OK;
}
int Render()
{
//Pause(1000);
HRESULT r = 0;
g_pDevice->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 0, 0, 0),10.f, 0);
if(!g_pDevice)
{
SetError( "cannot render because there is no device");
return E_FAIL;
}
//r = ValidateDevice();
//if( FAILED( r));
//{
// return E_FAIL;
//}
D3DLOCKED_RECT Locked;
g_pBackSurface->LockRect(&Locked, 0,0) ;
//g_Layer.Render(g_pBackSurface);
PrintFrameRate( 500, 400, TRUE, D3DCOLOR_ARGB( 0, 255, 0, 255), (DWORD*)Locked.pBits, Locked.Pitch);
g_pBackSurface->UnlockRect();
g_Layer.Render(g_pBackSurface);
g_pDevice->Present( NULL, NULL, NULL, NULL);
g_Layer.Update();
return S_OK;
}
int GameInit()
{
HRESULT r = 0;
g_pD3D = Direct3DCreate9( D3D_SDK_VERSION);
if( g_pD3D == NULL)
{
SetError( " Could not create IDIRECT3D9 object");
return E_FAIL;
}
r = InitDirect3DDevice( g_hWndMain, 640, 480, FALSE, D3DFMT_A8R8G8B8, g_pD3D, &g_pDevice);
if( FAILED( r))
{
SetError( "Init of the device failed");
return E_FAIL;
}
g_pDevice->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 0, 0, 0),10.f, 0);
r = g_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &g_pBackSurface);
if( FAILED( r))
{
SetError( "Couldnt get backbuffer");
return E_FAIL;
}
LoadAlphabet( "alpha1632.bmp", 16, 32);
g_Layer.Initialize( "layer.bmp", TRUE);
g_Layer.SetVelocity(20,20);
g_Layer.Update();
srand( GetTickCount());
InitTiming();
return S_OK;
}
int GameLoop()
{
FrameCount();
Render();
g_Layer.Update();
if(GetAsyncKeyState(VK_ESCAPE))
{
PostQuitMessage(0);
return S_OK;
}
}
int GameShutdown()
{
UnloadAlphabet();
if( g_pBackSurface)
g_pBackSurface->Release();
if( g_pD3DBitmapSurf)
g_pD3DBitmapSurf->Release();
if( g_pDevice)
g_pDevice->Release();
if( g_pD3D)
g_pD3D->Release();
return S_OK;
}
HRESULT CopySurfaceToSurface( RECT* pSourceRect, LPDIRECT3DSURFACE9 pSourceSurf, POINT* pDestPoint,
LPDIRECT3DSURFACE9 pDestSurf, BOOL bTransparent, D3DCOLOR ColorKey)
{
HRESULT r =0;
D3DLOCKED_RECT LockedSource;
D3DLOCKED_RECT LockedDest;
if( !pSourceSurf)
return E_FAIL;
if( !pDestSurf)
return E_FAIL;
RECT SourceRect;
POINT DestPoint;
D3DSURFACE_DESC d3dsdSource;
pSourceSurf->GetDesc( &d3dsdSource);
D3DSURFACE_DESC d3dsdDest;
pDestSurf->GetDesc( &d3dsdDest);
if( pSourceRect)
SourceRect = *pSourceRect;
else
SetRect( &SourceRect, 0, 0, d3dsdSource.Width, d3dsdSource.Height);
if( pDestPoint)
DestPoint = *pDestPoint;
else
{
DestPoint.x = DestPoint.y = 0;
}
r = pSourceSurf->LockRect( &LockedSource, 0, D3DLOCK_READONLY);
if( FAILED( r))
return E_FAIL;
r = pDestSurf->LockRect( &LockedDest, 0, 0);
if( FAILED( r))
{
pSourceSurf->UnlockRect();
return E_FAIL;
}
LockedSource.Pitch /= 4;
LockedDest.Pitch /= 4;
DWORD* pSourceData = (DWORD*) LockedSource.pBits;
DWORD* pDestData = (DWORD*) LockedDest.pBits;
int SourceOffset = SourceRect.top * LockedSource.Pitch + SourceRect.left;
int DestOffset = DestPoint.y * LockedDest.Pitch + DestPoint.x;
for( int y = 0; y < SourceRect.bottom; y++)
{
for( int x = 0; x < SourceRect.right; x++)
{
if( bTransparent)
{
if( pSourceData[ SourceOffset] != ColorKey)
{
pDestData[DestOffset] = pSourceData[SourceOffset];
}
}
else
{
pDestData[DestOffset] = pSourceData[SourceOffset];
}
DestOffset++;
SourceOffset++;
}
SourceOffset += LockedSource.Pitch - SourceRect.right;
DestOffset += LockedDest.Pitch - SourceRect.right;
}
pSourceSurf->UnlockRect();
pDestSurf->UnlockRect();
return S_OK;
}
HRESULT InitTiming()
{
QueryPerformanceFrequency( (LARGE_INTEGER*)&g_Frequency);
if( g_Frequency == 0)
{
SetError( "The system does not support high resolution timing");
return E_FAIL;
}
return S_OK;
}
void Pause( int Milliseconds)
{
INT64 SecondsDelay = (INT64)Milliseconds * 1000;
INT64 StartTime;
INT64 CurrentTime;
QueryPerformanceCounter( (LARGE_INTEGER*)&StartTime);
while( TRUE)
{
QueryPerformanceCounter( (LARGE_INTEGER*)&CurrentTime);
if( (CurrentTime - StartTime) > (INT64)SecondsDelay)
break;
}
}
float GetNumTicksPerMs()
{
return( (float)g_Frequency / 1000.0f);
}
void FrameCount()
{
INT64 NewCount =0;
static INT64 LastCount =0;
INT64 Difference =0;
QueryPerformanceCounter( (LARGE_INTEGER*)&NewCount);
if( NewCount == 0)
{
SetError( " the system does not support high res timing");
}
g_FrameCount++;
Difference = NewCount - LastCount;
if( Difference >= g_Frequency)
{
g_FrameRate = g_FrameCount;
g_FrameCount =0;
LastCount = NewCount;
}
}
CSprite::CSprite()
{
m_SurfaceWidth = 0;
m_SurfaceHeight = 0;
m_SpriteWidth = 0;
m_SpriteHeight = 0;
m_NumSprites = 0;
m_bTransparent = TRUE;
m_State = 0;
m_pSpriteSurface = 0;
m_pActiveSurface = 0;
m_bInitialized = FALSE;
m_ColorKey = D3DCOLOR_ARGB( 0, 255, 0, 255);
m_x = 0;
m_y = 0;
m_VelocityX = 0;
m_VelocityY = 0;
m_pNext = 0;
}
HRESULT CSprite::Initialize( char* strPathName, int SpriteWidth,
int SpriteHeight, int NumSprites)
{
if( m_pSpriteSurface)
{
m_pSpriteSurface->Release();
m_pSpriteSurface = 0;
}
if( m_pActiveSurface)
{
m_pActiveSurface->Release();
m_pActiveSurface = 0;
}
HRESULT r = 0;
NumSprites--;
D3DXIMAGE_INFO SrcInfo;
D3DXGetImageInfoFromFile( strPathName, &SrcInfo);
g_pDevice->CreateOffscreenPlainSurface( SrcInfo.Width, SrcInfo.Height, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT ,&m_pSpriteSurface, NULL);
r = D3DXLoadSurfaceFromFile( m_pSpriteSurface, NULL, NULL, strPathName, NULL,
D3DX_FILTER_NONE, 0, NULL);
if(FAILED( r))
{
return E_FAIL;
}
m_SpriteWidth = SpriteWidth;
m_SpriteHeight = SpriteHeight;
m_NumSprites = NumSprites;
D3DSURFACE_DESC d3dsd;
m_pSpriteSurface->GetDesc( &d3dsd);
m_SurfaceWidth = d3dsd.Width;
m_SurfaceHeight = d3dsd.Height;
r = g_pDevice->CreateOffscreenPlainSurface( m_SpriteWidth, m_SpriteHeight, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT, &m_pActiveSurface, 0);
if( FAILED( r))
{
Shutdown();
return E_FAIL;
}
RECT SpriteRect = { 0, 0, SpriteWidth, SpriteHeight};
RECT SpritePoint = { 0, 0, SpriteWidth, SpriteHeight};
g_pDevice->StretchRect( m_pSpriteSurface, &SpriteRect, m_pActiveSurface, &SpritePoint, D3DTEXF_NONE);
m_bInitialized = TRUE;
return S_OK;
}
HRESULT CSprite::Initialize( LPDIRECT3DSURFACE9 pSourceSurface, int SpriteWidth,
int SpriteHeight, int NumSprites)
{
if( m_pSpriteSurface)
{
m_pSpriteSurface->Release();
m_pSpriteSurface = 0;
}
if( m_pActiveSurface)
{
m_pActiveSurface->Release();
m_pActiveSurface = 0;
}
HRESULT r = 0;
NumSprites--;
if( !pSourceSurface)
{
SetError( " Invalid Source surface");
return E_FAIL;
}
m_pSpriteSurface = pSourceSurface;
pSourceSurface->AddRef();
m_SpriteWidth = SpriteWidth;
m_SpriteHeight = SpriteHeight;
m_NumSprites = NumSprites;
D3DSURFACE_DESC d3dsd;
m_pSpriteSurface->GetDesc( &d3dsd);
m_SurfaceWidth = d3dsd.Width;
m_SurfaceHeight = d3dsd.Height;
r = g_pDevice->CreateOffscreenPlainSurface( m_SpriteWidth, m_SpriteHeight, D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT, &m_pSpriteSurface, 0);
if( FAILED( r))
{
Shutdown();
return E_FAIL;
}
RECT SpriteRect = { 0, 0, SpriteWidth, SpriteHeight};
RECT SpritePoint = { 0, 0, 0, 0};
g_pDevice->StretchRect( m_pSpriteSurface, &SpriteRect, m_pActiveSurface, &SpritePoint, D3DTEXF_NONE);
m_bInitialized = TRUE;
return S_OK;
}
void CSprite::Shutdown()
{
if( m_pSpriteSurface)
{
m_pSpriteSurface->Release();
m_pSpriteSurface = 0;
}
if( m_pActiveSurface)
{
m_pActiveSurface->Release();
m_pActiveSurface = 0;
}
m_SpriteWidth = 0;
m_SpriteHeight = 0;
m_NumSprites = 0;
m_pSpriteSurface = 0;
m_SurfaceWidth = 0;
m_SurfaceHeight = 0;
m_bInitialized = FALSE;
}
HRESULT CSprite::Render( LPDIRECT3DSURFACE9 pDestSurface)
{
if( !pDestSurface)
return E_FAIL;
HRESULT r = 0;
RECT SourceRect = { 0, 0, m_SpriteWidth, m_SpriteHeight};
RECT DestRect = { m_x, m_y, 0, 0};
POINT DestPoint = { m_x, m_y};
if( m_bTransparent)
r = CopySurfaceToSurface( &SourceRect, m_pActiveSurface, &DestPoint,
pDestSurface, TRUE, m_ColorKey);
else
r = g_pDevice->StretchRect( m_pSpriteSurface, &SourceRect, m_pActiveSurface,
&DestRect, D3DTEXF_NONE);
return r;
}
void CSprite::GetBounds( RECT* pRect)
{
SetRect( pRect, m_x, m_y, m_SpriteWidth + m_x, m_SpriteHeight + m_y);
return;
}
HRESULT CSprite::SelectActiveSprite( int SpriteNum)
{
HRESULT r = 0;
div_t Result;
int OffsetX = 0;
int OffsetY = 0;
int SpritesPerRow = m_SurfaceWidth / m_SpriteWidth;
if( SpriteNum > m_NumSprites)
return E_FAIL;
Result = div( SpriteNum, SpritesPerRow);
OffsetX = Result.rem * m_SpriteWidth;
OffsetY = Result.quot * m_SpriteHeight;
if( OffsetX > m_SurfaceWidth)
return E_FAIL;
if( OffsetY > m_SurfaceHeight)
return E_FAIL;
RECT SpriteRect = { OffsetX, OffsetY, OffsetX + m_SpriteWidth, OffsetY + m_SpriteHeight};
RECT DestPoint = { 0, 0, 128, 128};
g_pDevice->StretchRect( m_pSpriteSurface, &SpriteRect, m_pActiveSurface, &DestPoint, D3DTEXF_NONE);
return S_OK;
}
void CSprite::Update()
{
m_x += m_VelocityX;
m_y += m_VelocityY;
}
BOOL CSprite::CheckForCollisionWith( CSprite * pOtherSprite)
{
if( !pOtherSprite)
return 0;
RECT ThisRect, OtherRect, TempRect;
GetBounds( &ThisRect);
pOtherSprite->GetBounds( &OtherRect);
if( IntersectRect( &TempRect, &ThisRect, &OtherRect))
return TRUE;
else
return FALSE;
}
HRESULT LoadAlphabet( char* strPathName, int LetterWidth, int LetterHeight)
{
if( !strPathName)
return E_FAIL;
if( !LetterWidth || !LetterHeight)
return E_FAIL;
HRESULT r =0;
///////////////////////////////////////////////////////////////////////
r = g_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &g_pBackSurface);
if( FAILED( r))
{
SetError( "Couldnt get backbuffer");
return E_FAIL;
}
r = g_pDevice->CreateOffscreenPlainSurface( 160, 320, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT ,&g_pAlphabetSurface, 0);
if( FAILED( r))
{
SetError( "Couldnt get anything!!!AlphaBet");
return E_FAIL;
}
r = D3DXLoadSurfaceFromFile( g_pAlphabetSurface, NULL, NULL, strPathName, NULL,
D3DX_FILTER_NONE, 0, NULL);
if( FAILED( r))
{
SetError( "Couldnt get anything!!!backbuffer");
return E_FAIL;
}
//r = LoadBitmapToSurface( strPathName, &g_pAlphabetSurface, g_pDevice);
///////////////////////////////////////////////////////////////////////
if( FAILED( r))
{
SetError( "unable to load alphabet bitmap");
return E_FAIL;
}
D3DSURFACE_DESC d3dsd;
g_pAlphabetSurface->GetDesc( &d3dsd);
g_AlphabetWidth = d3dsd.Width;
g_AlphabetHeight = d3dsd.Height;
g_AlphabetLetterWidth = LetterWidth;
g_AlphabetLetterHeight = LetterHeight;
g_AlphabetLettersPerRow = g_AlphabetWidth / g_AlphabetLetterWidth;
g_bAlphabetLoaded = TRUE;
return S_OK;
}
HRESULT UnloadAlphabet()
{
if( g_pAlphabetSurface->Release())
{
g_pAlphabetSurface =0;
g_bAlphabetLoaded = FALSE;
}
return S_OK;
}
void PrintChar( int x, int y, char Character, BOOL bTransparent, D3DCOLOR ColorKey,
DWORD* pDestData, int DestPitch)
{
HRESULT r =0;
div_t Result;
int OffsetX = 0, OffsetY = 0;
POINT LetterDestPoint = { 0, 0};
RECT LetterRect = { 0, 0, 0, 0};
if( !g_bAlphabetLoaded)
return;
Character -=32;
Result = div( Character, g_AlphabetLettersPerRow);
OffsetX = Result.rem * g_AlphabetLetterWidth;
OffsetY = Result.quot * g_AlphabetLetterHeight;
SetRect( &LetterRect, OffsetX, OffsetY, OffsetX + g_AlphabetLetterWidth,
OffsetY + g_AlphabetLetterHeight);
LetterDestPoint.x = x;
LetterDestPoint.y = y;
D3DLOCKED_RECT LockedAlphabet;
r = g_pAlphabetSurface->LockRect( &LockedAlphabet, 0, D3DLOCK_READONLY);
if( FAILED( r))
{
SetError( "couldnt lock alphabet surface for printchar()");
return;
}
DWORD* pAlphaData = (DWORD*)LockedAlphabet.pBits;
LockedAlphabet.Pitch /= 4;
DestPitch /= 4;
int AlphaOffset = OffsetY * LockedAlphabet.Pitch + OffsetX;
int DestOffset = y * DestPitch +x;
for( int cy = 0; cy < g_AlphabetLetterWidth; cy++)
{
for( int cx =0; cx < g_AlphabetLetterWidth; cx++)
{
if( bTransparent)
{
if( pAlphaData[AlphaOffset] !=ColorKey)
{
pDestData[DestOffset] = pAlphaData[AlphaOffset];
}
}
else
{
pDestData[DestOffset] = pAlphaData[AlphaOffset];
}
AlphaOffset++;
DestOffset++;
}
DestOffset += DestPitch - g_AlphabetLetterWidth;
AlphaOffset += LockedAlphabet.Pitch - g_AlphabetLetterWidth;
}
g_pAlphabetSurface->UnlockRect();
}
void PrintString( int x, int y, char* String, BOOL bTransparent, D3DCOLOR ColorKey,
DWORD* pDestData, int DestPitch)
{
for( UINT i = 0; i < strlen( String); i++)
{
PrintChar( x + (g_AlphabetLetterWidth * i), y, String,
bTransparent, ColorKey, pDestData, DestPitch);
}
}
void PrintFrameRate( int x, int y, BOOL bTransparent, D3DCOLOR ColorKey, DWORD* pDestData, int DestPitch)
{
char String[4];
ZeroMemory( &String, sizeof( String));
itoa( g_FrameRate, String, 10);
PrintString( x, y, String, bTransparent, ColorKey, pDestData, DestPitch);
}
CSprite::~CSprite()
{
}
CLayer::CLayer()
{
m_pLayerSurface = 0;
m_bTransparent = TRUE;
m_ColorKey = D3DCOLOR_ARGB( 0, 255, 0, 255);
m_x = m_y = 0;
m_VelocityX = 0;
m_VelocityY = 0;
m_SurfaceWidth = 0;
m_SurfaceHeight = 0;
m_MoveDirection = NONE;
}
CLayer::~CLayer()
{
if( m_pLayerSurface)
{
m_pLayerSurface->Release();
m_pLayerSurface = 0;
}
}
HRESULT CLayer::Initialize( char* strPathName, BOOL bTransparent)
{
if( m_pLayerSurface)
{
m_pLayerSurface->Release();
m_pLayerSurface = 0;
}
HRESULT r = 0;
r = g_pDevice->CreateOffscreenPlainSurface( 640, 480, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT ,&m_pLayerSurface, 0);
if( FAILED( r))
{
SetError( "Couldnt get anything!!!Layer");
return E_FAIL;
}
r = D3DXLoadSurfaceFromFile( m_pLayerSurface, NULL, NULL, strPathName, NULL,
D3DX_FILTER_NONE, 0, NULL);
if( FAILED( r))
{
SetError( "Couldnt get anything!!!LoadLayer");
return E_FAIL;
}
m_bTransparent = bTransparent;
D3DSURFACE_DESC d3dsd;
m_pLayerSurface->GetDesc( &d3dsd);
m_SurfaceWidth = d3dsd.Width;
m_SurfaceHeight = d3dsd.Height;
return S_OK;
}
HRESULT CLayer::Render( LPDIRECT3DSURFACE9 pTargetSurface)
{
HRESULT r = 0;
if( !pTargetSurface)
return E_FAIL;
D3DSURFACE_DESC d3dsd;
pTargetSurface->GetDesc( &d3dsd);
int OffsetX = m_x;
int OffsetY = m_y;
if( OffsetX < 0)
{
OffsetX = d3dsd.Width + m_x;
}
if( OffsetY < 0)
{
OffsetY = m_SurfaceHeight + OffsetY;
}
switch( m_MoveDirection)
{
case NONE:
{
r = CopySurfaceToSurface( 0, m_pLayerSurface, 0, pTargetSurface,
m_bTransparent, m_ColorKey);
if( FAILED( r))
{
SetError("stopppppp failing NOT MOVING");
}
return S_OK;
}break;
case HORIZONTAL:
{
RECT RectL, RectR;
POINT DestPointR = { OffsetX, OffsetY};
POINT DestPointL = { 0, OffsetY};
SetRect( &RectR, 0, 0, m_SurfaceWidth - OffsetX, m_SurfaceHeight);
SetRect( &RectL, m_SurfaceWidth - OffsetX, 0, OffsetX, m_SurfaceHeight);
r = CopySurfaceToSurface( &RectR, m_pLayerSurface, &DestPointR, pTargetSurface,
m_bTransparent, m_ColorKey);
if( FAILED( r))
{
SetError("stopppppp failing rect L");
return E_FAIL;
}
r = CopySurfaceToSurface( &RectL, m_pLayerSurface, &DestPointL, pTargetSurface,
m_bTransparent, m_ColorKey);
if( FAILED( r))
{
SetError("stopppppp failing rect R");
return E_FAIL;
}
}break;
case VERTICAL:
{
RECT RectT, RectB;
POINT DestPointT = { OffsetX, 0};
POINT DestPointB = { OffsetX, OffsetY};
SetRect( &RectT, 0, m_SurfaceHeight - OffsetY, m_SurfaceWidth, OffsetY );
SetRect( &RectB, 0, 0, m_SurfaceWidth, m_SurfaceHeight - OffsetY);
r = CopySurfaceToSurface( &RectT, m_pLayerSurface, &DestPointT, pTargetSurface,
m_bTransparent, m_ColorKey);
if( FAILED( r))
{
SetError("stopppppp failing rect T");
return E_FAIL;
}
r = CopySurfaceToSurface( &RectB, m_pLayerSurface, &DestPointB, pTargetSurface,
m_bTransparent, m_ColorKey);
if( FAILED( r))
{
SetError("stopppppp failing rect B");
return E_FAIL;
}
}break;
case BOTH:
{
RECT Rect0, Rect1, Rect2, Rect3;
POINT DestPoint0 = {OffsetX, OffsetY},
DestPoint1 = { OffsetX, 0},
DestPoint2 = { 0, OffsetY},
DestPoint3 = { 0, 0};
SetRect( &Rect0, 0, 0, m_SurfaceWidth - OffsetX, m_SurfaceHeight - OffsetY);
SetRect( &Rect1, 0, m_SurfaceHeight - OffsetY, m_SurfaceWidth - OffsetX, OffsetY);
SetRect( &Rect2, m_SurfaceWidth - OffsetX, 0, OffsetX, m_SurfaceHeight - OffsetY);
SetRect( &Rect3, m_SurfaceWidth - OffsetX, m_SurfaceHeight - OffsetY, OffsetX, OffsetY);
r = CopySurfaceToSurface( &Rect0, m_pLayerSurface, &DestPoint0, pTargetSurface,
m_bTransparent, m_ColorKey);
if( FAILED( r))
{
SetError("stopppppp failing rect0");
return E_FAIL;
}
r = CopySurfaceToSurface( &Rect1, m_pLayerSurface, &DestPoint1, pTargetSurface,
m_bTransparent, m_ColorKey);
if( FAILED( r))
{
SetError("stopppppp failing rect1");
return E_FAIL;
}
r = CopySurfaceToSurface( &Rect2, m_pLayerSurface, &DestPoint2, pTargetSurface,
m_bTransparent, m_ColorKey);
if( FAILED( r))
{
SetError("stopppppp failing rect2");
return E_FAIL;
}
r = CopySurfaceToSurface( &Rect3, m_pLayerSurface, &DestPoint3, pTargetSurface,
m_bTransparent, m_ColorKey);
if( FAILED( r))
{
SetError("stopppppp failing rect3");
return E_FAIL;
}
}break;
}
return S_OK;
}
void CLayer::Update()
{
if( m_VelocityX != 0 && m_VelocityY == 0)
m_MoveDirection = HORIZONTAL;
else if( m_VelocityY != 0 && m_VelocityX == 0)
m_MoveDirection = VERTICAL;
else if( m_VelocityX != 0 && m_VelocityY != 0)
m_MoveDirection = BOTH;
else if( m_VelocityX == 0 && m_VelocityY == 0)
{
m_MoveDirection = NONE;
return;
}
m_x += m_VelocityX;
m_y += m_VelocityY;
if( m_x >= g_DeviceWidth)
m_x = m_x - g_DeviceWidth;
if( m_x <= -g_DeviceWidth)
m_x = m_x + g_DeviceWidth;
if( m_y >= g_DeviceHeight)
m_y = m_y - g_DeviceHeight;
if( m_y <= -g_DeviceHeight)
m_y = m_y + g_DeviceHeight;
}
i have tried to figure this out and i think it may be because i have tried to change the code from dx8 to dx9 but i cant find the problem, any help is appreciate thanks in advance