//-----------------------------------------------------------------------------
// File: Main.cpp
//
//-----------------------------------------------------------------------------
#define STRICT
#include <windows.h>
#include <ddraw.h>
#include <dshow.h>
#include <mmsystem.h>
#include <math.h>
#include <fstream>
#include <list>
#include "resource.h"
#include "DSUtil.h"
#include "ddutil.h"
#include "Maze.h"
#include "Sprite.h"
#include "SpriteManager.h"
#include "GameErrors.h"
#include "InputLayer.h"
#include "Keyboard.h"
#include "ijl.h" // Intel JPEG header file
//#define DISPLAY_STATUS
#undef DISPLAY_STATUS
//-----------------------------------------------------------------------------
// Defines, constants, and global variables
//-----------------------------------------------------------------------------
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
#define TITLE "Adventure in Abit"
#define SPLASHFILENAME "AdvInAbat.jpg"
#define CHOICEFILENAME "choose.jpg"
#define GAMEOVERBADFILENAME "GameOver.jpg"
#define GAMEOVERGOODFILENAME "Finish.jpg"
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 768
#define SCREEN_BPP 16
#define SPRITE_WIDTH 64
#define SPRITE_HEIGHT 64
#define MAZETEXTURE_WIDTH 32
#define MAZETEXTURE_HEIGHT 32
#define TYPE_PLAYER 1
#define TYPE_ENEMY1 2
#define TYPE_ENEMY2 3
#define TYPE_ENEMY3 4
#define TYPE_ENEMY4 5
#define TYPE_POO 10
#define TYPE_SPECIAL 11
#define TYPE_BULLET 12
#define ST_STAND_STILL 1
#define ST_WALK_UP 2
#define ST_WALK_DOWN 3
#define ST_WALK_LEFT 4
#define ST_WALK_RIGHT 5
#define ST_DEFAULT 6
#define ST_KEY 7
#define ST_DOOR 8
#define ST_FOOD1 9
#define ST_FOOD2 (ST_FOOD1+1)
#define ST_FOOD3 (ST_FOOD1+2)
#define ST_FOOD4 (ST_FOOD1+3)
#define ST_FOOD5 (ST_FOOD1+4)
#define ST_FOOD6 (ST_FOOD1+5)
#define GAMESTATE_SPLASHSCREEN 0
#define GAMESTATE_CHOICE 1
#define GAMESTATE_RUNNING 2
#define GAMESTATE_GAMEOVERBAD 3
#define GAMESTATE_GAMEOVERGOOD 4
#define POO_DELAY 500
#define INVULNERABLE_DELAY 200
#define NO_OF_LIFE 4
#define NO_OF_SPECIALS 5
#define GAMESTATUS_TEXT "Dead Pigs:%d Dead Enemies:%d"
char g_szGameStatus[200];
#define LIFE_LEFT_TEXT "Lives:%d"
char g_szLifeLeft[100];
#define GAMESCORE_TEXT "Score:%06d"
char g_szScore[100];
CDisplay* g_pDisplay = NULL;
#ifdef DISPLAY_STATUS
CSurface* g_pTextSurface = NULL;
#endif
CSurface* g_pLifeTextSurface = NULL;
CSurface* g_pScoreTextSurface = NULL;
CSurface* g_pLevelTextSurface = NULL;
CSurface* g_pMazeSurface = NULL;
CSurface* g_pSpriteSurface = NULL;
CSurface* g_pSplashSurface = NULL;
RECT g_rcWindow;
RECT g_rcViewport;
RECT g_rcScreen;
BOOL g_bWindowed = false;
BOOL g_bActive = FALSE;
DWORD g_dwLastTick;
CMaze g_Maze(MAKEINTRESOURCE(IDB_TEXTURE));
CSprite g_PigSprite;
CSprite g_RabbitSprite;
CSprite g_SheepSprite;
CSprite* g_pPlayerSprite = NULL;
CSprite g_Enemy1Sprite;
CSprite g_Enemy2Sprite;
CSprite g_Enemy3Sprite;
CSprite g_Enemy4Sprite;
CSprite g_Enemy5Sprite;
CSprite g_PigPooSprite;
CSprite g_RabbitPooSprite;
CSprite g_SheepPooSprite;
CSprite* g_pPooSprite= NULL;
CSprite g_SpecialSprite;
CSprite g_BulletSprite;
CSpriteManager g_EnemySpriteManager;
CSound* g_pSplashSound = NULL;
CSound* g_pPickupSound = NULL;
CSoundManager* g_pSoundManager = NULL;
int g_nGameState = GAMESTATE_SPLASHSCREEN;
int g_nPigDead = 0;
int g_nEnemyDead = 0;
long g_nPooDelay = 0;
long g_nNoOfEnemies = 10;
long g_nLivesLeft = NO_OF_LIFE;
long g_nNoOfSpecials = NO_OF_SPECIALS;
long g_nScore = 0;
struct SLEVEL {
char szLevelFile[100];
int nNoOfEnemys;
}* g_pLevel;
long g_nNoOfLevels;
long g_nCurrLevel=0;
HINSTANCE g_hInstance;
HWND g_hMainWnd;
//-----------------------------------------------------------------------------
// Function-prototypes
//-----------------------------------------------------------------------------
LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
HRESULT WinInit( HINSTANCE hInst, int nCmdShow, HWND* phWnd, HACCEL* phAccel );
HRESULT InitDirectDraw( HWND hWnd );
VOID FreeDirectDraw();
HRESULT InitDirectDrawMode( HWND hWnd, BOOL bWindowed );
HRESULT ProcessNextFrame( HWND hWnd );
HRESULT DisplayFrame();
HRESULT RestoreSurfaces();
bool LoadJPEG(bool bFromFile, LPCTSTR szName, CSurface** ppSurface);
void DisplaySplashScreen(bool bDisplay);
void InitSprites();
void InitLevel();
void MoveCharacterRelative(long dX, long dY);
struct SHandleInput: public iKeyboardReceiver
{
SHandleInput() {
cInputLayer::Create( g_hInstance, g_hMainWnd,
true, true, false );
Input()->GetKeyboard()->SetReceiver( this );
}
~SHandleInput() {
cInputLayer::Destroy();
}
void KeyUp( int key )
{
switch(g_nGameState)
{
case GAMESTATE_SPLASHSCREEN:
{
switch( key )
{
case DIK_SPACE:
{
g_nGameState=GAMESTATE_CHOICE;
g_pSplashSound->Stop();
LoadJPEG(true, CHOICEFILENAME, &g_pSplashSurface);
break;
}
}
}
break;
case GAMESTATE_CHOICE:
{
bool bKeyHit = false;
switch( key )
{
case DIK_1: g_pPlayerSprite = &g_PigSprite;
g_pPooSprite = &g_PigPooSprite;
bKeyHit = true; break;
case DIK_2: g_pPlayerSprite = &g_RabbitSprite;
g_pPooSprite = &g_RabbitPooSprite;
bKeyHit = true;break;
case DIK_3: g_pPlayerSprite = &g_SheepSprite;
g_pPooSprite = &g_SheepPooSprite;
bKeyHit = true; break;
}
if (bKeyHit) {
g_nGameState=GAMESTATE_RUNNING;
InitLevel();
}
}
break;
case GAMESTATE_RUNNING:
{
switch( key )
{
// move up
case DIK_UP:
case DIK_NUMPAD8:
// move down
case DIK_DOWN:
case DIK_NUMPAD2:
// turn right
case DIK_RIGHT:
case DIK_NUMPAD6:
// turn left
case DIK_LEFT:
case DIK_NUMPAD4:
g_pPlayerSprite->SetState(ST_STAND_STILL);
g_pPlayerSprite->m_Movement.m_dx = g_pPlayerSprite->m_Movement.m_dy =0;
break;
}
}
break;
case GAMESTATE_GAMEOVERGOOD:
case GAMESTATE_GAMEOVERBAD:
{
switch( key )
{
case DIK_SPACE:
{
g_nGameState=GAMESTATE_SPLASHSCREEN;
g_nLivesLeft = NO_OF_LIFE;
g_nScore=0;
g_nCurrLevel=0;
break;
}
}
}
break;
}
}
void KeyDown( int key )
{
switch(g_nGameState) {
case GAMESTATE_RUNNING:
{
switch( key )
{
// move up
case DIK_UP:
case DIK_NUMPAD8:
{
g_pPlayerSprite->SetState(ST_WALK_UP);
g_pPlayerSprite->m_Movement.m_dy = -2;
g_pPlayerSprite->m_Movement.m_dx = 0;
break;
}
// move down
case DIK_DOWN:
case DIK_NUMPAD2:
{
g_pPlayerSprite->SetState(ST_WALK_DOWN);
g_pPlayerSprite->m_Movement.m_dy = 2;
g_pPlayerSprite->m_Movement.m_dx = 0;
break;
}
// Shoot
case DIK_SPACE:
{
if (g_nPooDelay == 0 && g_pPlayerSprite->GetState()!= ST_KILL) {
RECT rc = g_pPlayerSprite->GetRect();
g_pPooSprite->MoveTo(rc.left,rc.top);
g_nPooDelay = POO_DELAY;
g_pPooSprite->SetState(ST_DEFAULT);
}
break;
}
// turn right
case DIK_RIGHT:
case DIK_NUMPAD6:
{
g_pPlayerSprite->SetState(ST_WALK_RIGHT);
g_pPlayerSprite->m_Movement.m_dx = 2;
g_pPlayerSprite->m_Movement.m_dy = 0;
break;
}
// turn left
case DIK_LEFT:
case DIK_NUMPAD4:
{
g_pPlayerSprite->SetState(ST_WALK_LEFT);
g_pPlayerSprite->m_Movement.m_dx = -2;
g_pPlayerSprite->m_Movement.m_dy = 0;
break;
}
}
}
}
}
} * g_pHandleInput = NULL;
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Entry point to the program. Initializes everything and calls
// UpdateFrame() when idle from the message pump.
//-----------------------------------------------------------------------------
int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, int nCmdShow )
{
MSG msg;
HWND hWnd;
HACCEL hAccel;
srand( GetTickCount() );
wsprintf((char*)g_szGameStatus, (char*)GAMESTATUS_TEXT,0,0);
wsprintf((char*)g_szLifeLeft, (char*)LIFE_LEFT_TEXT,g_nLivesLeft -1);
wsprintf((char*)g_szScore, (char*)GAMESCORE_TEXT,g_nScore);
g_hInstance = hInst;
char szName[200];
std::fstream LevelData("config.txt",std::ios::in );
LevelData.getline(szName,200);
// Read number of horizontal lines
LevelData >> g_nNoOfLevels; // Number of Horizontal rows
g_pLevel = new SLEVEL[g_nNoOfLevels];
if (g_pLevel == NULL)
return -1;
for (int nI = 0; nI < g_nNoOfLevels; nI++) {
LevelData >> g_pLevel[nI].szLevelFile;
LevelData >> g_pLevel[nI].nNoOfEnemys;
}
if( FAILED( WinInit( hInst, nCmdShow, &hWnd, &hAccel ) ) )
return FALSE;
if( FAILED( InitDirectDraw( hWnd ) ) )
{
MessageBox( hWnd, TEXT("DirectDraw init failed. ")
TEXT("The program will now exit. "), TEXT("Maze Test program"),
MB_ICONERROR | MB_OK );
return FALSE;
}
InitSprites();
g_dwLastTick = timeGetTime();
while( TRUE )
{
// Look for messages, if none are found then
// update the state and display it
if( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) )
{
if( 0 == GetMessage(&msg, NULL, 0, 0 ) )
{
// WM_QUIT was posted, so exit
FreeDirectDraw();
CoUninitialize();
delete[] g_pLevel;
return (int)msg.wParam;
}
// Translate and dispatch the message
if( 0 == TranslateAccelerator( hWnd, hAccel, &msg ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
}
else
{
if( g_bActive )
{
// Move the sprites, blt them to the back buffer, then
// flip or blt the back buffer to the primary buffer
if( FAILED( ProcessNextFrame( hWnd ) ) )
{
SAFE_DELETE( g_pDisplay );
MessageBox( hWnd, TEXT("Displaying the next frame failed. ")
TEXT("The program will now exit. "), TEXT("Adv In Abt"),
MB_ICONERROR | MB_OK );
return FALSE;
}
}
else
{
// Go to sleep if we have nothing else to do
WaitMessage();
// Ignore time spent inactive
g_dwLastTick = timeGetTime();
}
}
}
}
//-----------------------------------------------------------------------------
// Name: WinInit()
// Desc: Init the window
//-----------------------------------------------------------------------------
HRESULT WinInit( HINSTANCE hInst, int nCmdShow, HWND* phWnd, HACCEL* phAccel )
{
WNDCLASSEX wc;
HWND hWnd;
HACCEL hAccel;
// Register the window class
wc.cbSize = sizeof(wc);
wc.lpszClassName = TEXT("AdvInAbatWndClass");
wc.lpfnWndProc = MainWndProc;
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.hInstance = hInst;
wc.hIcon = LoadIcon( hInst, MAKEINTRESOURCE(IDI_MAIN) );
wc.hIconSm = LoadIcon( hInst, MAKEINTRESOURCE(IDI_MAIN) );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
wc.lpszMenuName = 0;//MAKEINTRESOURCE(IDR_MENU);
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
if( RegisterClassEx( &wc ) == 0 ) {
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
OutputDebugString( (LPCTSTR)lpMsgBuf);
// Free the buffer.
LocalFree( lpMsgBuf );
return E_FAIL;
}
// Load keyboard accelerators
hAccel = LoadAccelerators( hInst, MAKEINTRESOURCE(IDR_MAIN_ACCEL) );
// Calculate the proper size for the window given a client of 640x480
DWORD dwFrameWidth = GetSystemMetrics( SM_CXSIZEFRAME );
DWORD dwFrameHeight = GetSystemMetrics( SM_CYSIZEFRAME );
DWORD dwMenuHeight = GetSystemMetrics( SM_CYMENU );
DWORD dwCaptionHeight = GetSystemMetrics( SM_CYCAPTION );
DWORD dwWindowWidth = SCREEN_WIDTH + dwFrameWidth * 2;
DWORD dwWindowHeight = SCREEN_HEIGHT + dwFrameHeight * 2 +
dwMenuHeight + dwCaptionHeight;
// Create and show the main window
DWORD dwStyle = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX;
hWnd = CreateWindowEx( 0, TEXT("AdvInAbatWndClass"),
TEXT("Maze Test program"),
dwStyle, CW_USEDEFAULT, CW_USEDEFAULT,
dwWindowWidth, dwWindowHeight, NULL, NULL, hInst, NULL );
if( hWnd == NULL )
return E_FAIL;
ShowWindow( hWnd, nCmdShow );
UpdateWindow( hWnd );
// Save the window size/pos for switching modes
GetWindowRect( hWnd, &g_rcWindow );
*phWnd = hWnd;
*phAccel = hAccel;
g_hMainWnd = hWnd;
return S_OK;
}
HFONT GetGameFont()
{
HFONT hFont ;
LOGFONT lf ;
lf.lfHeight = 40;
lf.lfWidth = 20;
lf.lfEscapement = 0 ;
lf.lfOrientation = 0 ;
lf.lfWeight = 0 ;
lf.lfItalic = false ;
lf.lfUnderline = false;
lf.lfStrikeOut = false;
lf.lfCharSet = DEFAULT_CHARSET ;
lf.lfOutPrecision = 0 ;
lf.lfClipPrecision = 0 ;
lf.lfQuality = 0 ;
lf.lfPitchAndFamily = 0 ;
lstrcpy (lf.lfFaceName, "Times New Roman") ;
hFont = CreateFontIndirect (&lf) ;
// hfont = (HFONT)GetStockObject(ANSI_VAR_FONT);
return hFont;
}
//-----------------------------------------------------------------------------
// Name: InitDirectDraw()
// Desc: Create the DirectDraw object, and init the surfaces
//-----------------------------------------------------------------------------
HRESULT InitDirectDraw( HWND hWnd )
{
HRESULT hr;
// Initialize all the surfaces we need
if( FAILED( hr = InitDirectDrawMode( hWnd, g_bWindowed ) ) )
return hr;
// Create a static IDirectSound in the CSound class.
// Set coop level to DSSCL_PRIORITY, and set primary buffer
// format to stereo, 22kHz and 16-bit output.
g_pSoundManager = new CSoundManager();
if( FAILED(hr= g_pSoundManager->Initialize( hWnd, DSSCL_PRIORITY, 2, 22050, 16 ) ) )
{
MessageBox( 0, "Error initializing DirectSound. Game will now exit.",
"Game", MB_OK | MB_ICONERROR );
return hr;
}
g_pSoundManager->Create(&g_pPickupSound,"PickUp");
g_pHandleInput = new SHandleInput();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InitDirectDrawMode()
// Desc: Called when the user wants to toggle between full-screen and windowed
// to create all the needed DDraw surfaces and set the coop level
//-----------------------------------------------------------------------------
HRESULT InitDirectDrawMode( HWND hWnd, BOOL bWindowed )
{
HRESULT hr;
LPDIRECTDRAWPALETTE pDDPal = NULL;
// Release all existing surfaces
SAFE_DELETE( g_pMazeSurface);
#ifdef DISPLAY_STATUS
SAFE_DELETE( g_pTextSurface );
#endif
SAFE_DELETE( g_pLifeTextSurface );
SAFE_DELETE( g_pScoreTextSurface );
SAFE_DELETE( g_pLevelTextSurface );
SAFE_DELETE( g_pSpriteSurface );
SAFE_DELETE ( g_pSplashSurface);
SAFE_DELETE( g_pDisplay );
// The back buffer and primary surfaces need to be created differently
// depending on if we are in full-screen or windowed mode
g_pDisplay = new CDisplay();
if( bWindowed )
{
if( FAILED( hr = g_pDisplay->CreateWindowedDisplay( hWnd, SCREEN_WIDTH,
SCREEN_HEIGHT ) ) )
return hr;
// Add the system menu to the window's style
DWORD dwStyle = GetWindowLong( hWnd, GWL_STYLE );
dwStyle |= WS_SYSMENU;
SetWindowLong( hWnd, GWL_STYLE, dwStyle );
// Show the menu in windowed mode
#ifdef _WIN64
HINSTANCE hInst = (HINSTANCE) GetWindowLongPtr( hWnd, GWLP_HINSTANCE );
#else
HINSTANCE hInst = (HINSTANCE) GetWindowLong( hWnd, GWL_HINSTANCE );
#endif
HMENU hMenu = LoadMenu( hInst, MAKEINTRESOURCE( IDR_MENU ) );
SetMenu( hWnd, hMenu );
}
else
{
if( FAILED( hr = g_pDisplay->CreateFullScreenDisplay( hWnd, SCREEN_WIDTH,
SCREEN_HEIGHT, SCREEN_BPP ) ) )
{
MessageBox( hWnd, TEXT("This display card does not support 640x480x8. "),
TEXT("DirectDraw Sample"), MB_ICONERROR | MB_OK );
return hr;
}
// Disable the menu in full-screen
SetMenu( hWnd, NULL );
// Remove the system menu from the window's style
DWORD dwStyle = GetWindowLong( hWnd, GWL_STYLE );
dwStyle &= ~WS_SYSMENU;
SetWindowLong( hWnd, GWL_STYLE, dwStyle );
}
// Create a surface, and draw text to it.
#ifdef DISPLAY_STATUS
if( FAILED( hr = g_pDisplay->CreateSurfaceFromText( &g_pTextSurface, NULL, (char*)g_szGameStatus,
RGB(0,0,0), RGB(255, 255, 0) ) ) )
return hr;
#endif
HFONT hFont = GetGameFont();
if( FAILED( hr = g_pDisplay->CreateSurfaceFromText( &g_pLifeTextSurface, hFont, (char*)g_szLifeLeft,
RGB(0,0,0), RGB(255, 255, 0) ) ) )
return hr;
if( FAILED( hr = g_pDisplay->CreateSurfaceFromText( &g_pScoreTextSurface, hFont, (char*)g_szScore,
RGB(0,0,0), RGB(255, 255, 0) ) ) )
return hr;
// Create a surface, and draw a bitmap resource on it. The surface must
// be newly created every time the screen mode is switched since it
// uses the pixel format of the primary surface
// Create a surface, and draw text to it.
if( FAILED( hr = g_pDisplay->CreateSurface( &g_pMazeSurface, SCREEN_WIDTH, SCREEN_HEIGHT) ))
return hr;
if( FAILED( hr = g_pDisplay->CreateSurfaceFromBitmap( &g_pSpriteSurface, MAKEINTRESOURCE(IDB_SPRITE),0, 0) ))
return hr;
g_pSpriteSurface->SetColorKey(RGB(0,0,0));
g_Maze.Draw(g_pMazeSurface);
if (g_nGameState == GAMESTATE_SPLASHSCREEN) {
LoadJPEG(true, SPLASHFILENAME, &g_pSplashSurface);
}
if (g_nGameState == GAMESTATE_CHOICE) {
LoadJPEG(true, CHOICEFILENAME, &g_pSplashSurface);
}
if (g_nGameState == GAMESTATE_GAMEOVERGOOD) {
LoadJPEG(true, GAMEOVERGOODFILENAME, &g_pSplashSurface);
}
if (g_nGameState == GAMESTATE_GAMEOVERBAD) {
LoadJPEG(true, GAMEOVERBADFILENAME, &g_pSplashSurface);
}
if (g_nGameState == GAMESTATE_RUNNING){
g_pDisplay->CreateSurfaceFromText( &g_pLevelTextSurface, hFont, g_Maze.GetName(),
RGB(0,0,0), RGB(255, 255, 0) ) ;
}
DeleteObject(hFont);
return S_OK;
}
inline bool IsHit(RECT& rc)
{
return g_Maze.IsHit(rc);
}
void BulletFindPath(CSprite* pSprite)
{
pSprite->SetState(ST_KILL);
}
void FindPath(CSprite* pSprite)
{
int nH = rand()%2;
int nV = rand()%2;
int nNRnd = rand()%3;
if (nNRnd) {
if (abs(g_pPlayerSprite->m_ptLocation.x - pSprite->m_ptLocation.x) >
abs(g_pPlayerSprite->m_ptLocation.y - pSprite->m_ptLocation.y))
{
pSprite->m_Movement.m_dy = 0;
if (g_pPlayerSprite->m_ptLocation.x < pSprite->m_ptLocation.x) {
pSprite->m_Movement.m_dx= -1 * (rand()%2+1);
pSprite->SetState(ST_WALK_LEFT);
} else {
pSprite->m_Movement.m_dx= 1 * (rand()%2+1);
pSprite->SetState(ST_WALK_RIGHT);
}
} else {
pSprite->m_Movement.m_dx = 0;
if (g_pPlayerSprite->m_ptLocation.y < pSprite->m_ptLocation.y) {
pSprite->m_Movement.m_dy= -1 * (rand()%2+1);
pSprite->SetState(ST_WALK_UP);
} else {
pSprite->m_Movement.m_dy= 1 * (rand()%2+1);
pSprite->SetState(ST_WALK_DOWN);
}
}
} else {
if (nV) {
pSprite->m_Movement.m_dx = 0;
if (nH) {
pSprite->m_Movement.m_dy = 1 * (rand()%2+1);
pSprite->SetState(ST_WALK_DOWN);
} else {
pSprite->m_Movement.m_dy = -1 * (rand()%2+1);
pSprite->SetState(ST_WALK_UP);
}
} else {
pSprite->m_Movement.m_dy = 0;
if (nH) {
pSprite->m_Movement.m_dx = 1 * (rand()%2+1);
pSprite->SetState(ST_WALK_RIGHT);
} else {
pSprite->m_Movement.m_dx = -1 * (rand()%2+1);
pSprite->SetState(ST_WALK_LEFT);
}
}
}
if (pSprite->GetType() == TYPE_ENEMY4) {
if (g_BulletSprite.GetState() == ST_DEAD && pSprite->GetState() != ST_KILL
&& pSprite->GetState() != ST_DEAD) {
RECT rc = pSprite->GetRect();
g_BulletSprite.MoveTo(rc.left,rc.top);
g_BulletSprite.SetState(ST_DEFAULT);
switch (pSprite->GetState()) {
case ST_WALK_UP:
g_BulletSprite.m_Movement.m_dx =0;
g_BulletSprite.m_Movement.m_dy = -3;
break;
case ST_WALK_DOWN:
g_BulletSprite.m_Movement.m_dx =0;
g_BulletSprite.m_Movement.m_dy = 3;
break;
case ST_WALK_LEFT:
g_BulletSprite.m_Movement.m_dx =-3;
g_BulletSprite.m_Movement.m_dy = 0;
break;
case ST_WALK_RIGHT:
g_BulletSprite.m_Movement.m_dx =3;
g_BulletSprite.m_Movement.m_dy = 0;
break;
}
}
}
}
void DeadPig(CSprite* pSprite)
{
++g_nPigDead;
--g_nLivesLeft;
#ifdef DISPLAY_STATUS
wsprintf((char*)g_szGameStatus, (char*)GAMESTATUS_TEXT, g_nPigDead, g_nEnemyDead);
SAFE_DELETE( g_pTextSurface );
g_pDisplay->CreateSurfaceFromText( &g_pTextSurface, NULL, (char*)g_szGameStatus,
RGB(0,0,0), RGB(255, 255, 0) );
#endif
SAFE_DELETE( g_pLifeTextSurface );
wsprintf((char*)g_szLifeLeft, (char*)LIFE_LEFT_TEXT, g_nLivesLeft-1);
HFONT hFont = GetGameFont();
g_pDisplay->CreateSurfaceFromText( &g_pLifeTextSurface, hFont , (char*)g_szLifeLeft,
RGB(0,0,0), RGB(255, 255, 0) );
DeleteObject(hFont);
g_pPlayerSprite->MoveTo(1 * MAZETEXTURE_WIDTH, 19 * MAZETEXTURE_HEIGHT);
g_pPlayerSprite->SetState(ST_WALK_UP);
g_pPlayerSprite->m_Movement.m_nInvulnerable=INVULNERABLE_DELAY;
if (g_nLivesLeft == 0) {
g_nLivesLeft = NO_OF_LIFE;
g_nGameState = GAMESTATE_GAMEOVERBAD;
LoadJPEG(true, GAMEOVERBADFILENAME, &g_pSplashSurface);
}
}
void DeadEnemy(CSprite* pSprite)
{
++g_nEnemyDead;
#ifdef DISPLAY_STATUS
wsprintf((char*)g_szGameStatus, (char*)GAMESTATUS_TEXT, g_nPigDead, g_nEnemyDead);
SAFE_DELETE( g_pTextSurface );
g_pDisplay->CreateSurfaceFromText( &g_pTextSurface, NULL, (char*)g_szGameStatus,
RGB(0,0,0), RGB(255, 255, 0) );
#endif
g_nScore += pSprite->m_nPoints;
SAFE_DELETE( g_pScoreTextSurface );
wsprintf((char*)g_szScore, (char*)GAMESCORE_TEXT, g_nScore);
HFONT hFont = GetGameFont();
g_pDisplay->CreateSurfaceFromText( &g_pScoreTextSurface, hFont, (char*)g_szScore,
RGB(0,0,0), RGB(255, 255, 0) );
DeleteObject(hFont);
if (g_nNoOfEnemies) {
g_nNoOfEnemies--;
pSprite->SetState(ST_WALK_LEFT);
POINT pt = g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
pSprite->MoveTo(pt);
(*pSprite->m_Movement.m_pfnFindPath)(pSprite);
pSprite->m_Movement.m_nInvulnerable=INVULNERABLE_DELAY;
}
}
bool KillSpecial(CSprite* pSprite)
{
if (pSprite->GetState() == ST_DOOR) {
InitLevel();
return false;
}
return true;
}
void DeadSpecial(CSprite* pSprite)
{
static long nSpecialState = ST_FOOD1;
g_nScore += pSprite->m_nPoints;
SAFE_DELETE( g_pScoreTextSurface );
wsprintf((char*)g_szScore, (char*)GAMESCORE_TEXT, g_nScore);
HFONT hFont = GetGameFont();
g_pDisplay->CreateSurfaceFromText( &g_pScoreTextSurface, hFont, (char*)g_szScore,
RGB(0,0,0), RGB(255, 255, 0) );
DeleteObject(hFont);
if (g_nNoOfSpecials) {
pSprite->SetState(rand()%6 + ST_FOOD1);
POINT pt = g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
pSprite->MoveTo(pt);
nSpecialState = ST_FOOD1;
--g_nNoOfSpecials;
} else {
switch (nSpecialState) {
case ST_FOOD1:
pSprite->SetState(ST_KEY);
POINT pt = g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
pSprite->MoveTo(pt);
nSpecialState = ST_KEY;
break;
case ST_KEY:
pSprite->SetState(ST_DOOR);
pt = g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
pSprite->MoveTo(pt);
nSpecialState = ST_DOOR;
break;
case ST_DOOR:
InitLevel();
}
}
}
void InitSprites()
{
const int nHeight = SPRITE_HEIGHT;
const int nWidth = SPRITE_WIDTH;
POINT pt;
RECT rcBounding;
// ---------------- Pig Sprite -----------------------------------//
g_PigSprite.CreateSprite(&g_pSpriteSurface, TYPE_PLAYER, nHeight,nWidth);
pt.x = 5*64; pt.y =7*64 ;
g_PigSprite.AddState(ST_STAND_STILL, pt, 2, 60);
rcBounding.top = 0;
rcBounding.bottom = nHeight-10;
rcBounding.left = 10;
rcBounding.right= nWidth - 20;
pt.x = 6*64; pt.y =4*64;
g_PigSprite.AddState(ST_WALK_UP, pt, 3, 10,&rcBounding);
rcBounding.top = 10;
rcBounding.bottom = nHeight-10;
pt.x = 64*9;pt.y = 4*64;
g_PigSprite.AddState(ST_WALK_DOWN, pt, 3, 10,&rcBounding);
rcBounding.top = 10;
rcBounding.bottom = nHeight - 20;
rcBounding.left = 0;
rcBounding.right=nWidth - 10;
pt.x = 3*64;pt.y = 4*64;
// g_pPlayerSprite->AddState(ST_WALK_LEFT, pt, 2, 20,"WavPigWalk",true);
g_PigSprite.AddState(ST_WALK_LEFT, pt, 3, 10,&rcBounding);
pt.x = 64*0;pt.y = 4*64;
rcBounding.left = 10;
rcBounding.right=nWidth-10;
g_PigSprite.AddState(ST_WALK_RIGHT, pt, 3, 10,&rcBounding);
pt.x = 64 * 8; pt.y = 7 * 64;
g_PigSprite.AddState(ST_KILL, pt, 4, 20);
g_PigSprite.MoveTo(1 * MAZETEXTURE_WIDTH, 19 * MAZETEXTURE_HEIGHT);
g_PigSprite.m_pfnDead = DeadPig;
g_PigSprite.m_Movement.m_pfnCollision = IsHit;
g_PigPooSprite.CreateSprite(&g_pSpriteSurface, TYPE_POO, nHeight,nWidth);
rcBounding.top = rcBounding.left = 20;
rcBounding.right=rcBounding.bottom = nHeight - 40;
pt.x = 0*64;pt.y = 7*64;
g_PigPooSprite.AddState(ST_DEFAULT, pt, 3, 50,&rcBounding);
pt.x = 11*64;pt.y = 10*64;
g_PigPooSprite.AddState(ST_DEAD, pt, 3, 50,&rcBounding);
g_PigPooSprite.SetState(ST_DEFAULT);
// --------------- Rabbit Sprite -----------------------------//
g_RabbitSprite.CreateSprite(&g_pSpriteSurface, TYPE_PLAYER, nHeight,nWidth);
pt.x = 5*64; pt.y =8*64 ;
g_RabbitSprite.AddState(ST_STAND_STILL, pt, 2, 60);
rcBounding.top = 0;
rcBounding.bottom = nHeight-10;
rcBounding.left = 10;
rcBounding.right= nWidth - 20;
pt.x = 6*64; pt.y =5*64;
g_RabbitSprite.AddState(ST_WALK_UP, pt, 3, 10,&rcBounding);
rcBounding.top = 10;
rcBounding.bottom = nHeight-10;
pt.x = 64*9;pt.y = 5*64;
g_RabbitSprite.AddState(ST_WALK_DOWN, pt, 3, 10,&rcBounding);
rcBounding.top = 10;
rcBounding.bottom = nHeight - 20;
rcBounding.left = 0;
rcBounding.right=nWidth - 10;
pt.x = 3*64;pt.y = 5*64;
g_RabbitSprite.AddState(ST_WALK_LEFT, pt, 3, 10,&rcBounding);
pt.x = 64*0;pt.y = 5*64;
rcBounding.left = 10;
rcBounding.right=nWidth-10;
g_RabbitSprite.AddState(ST_WALK_RIGHT, pt, 3, 10,&rcBounding);
pt.x = 64 * 8; pt.y = 8 * 64;
g_RabbitSprite.AddState(ST_KILL, pt, 4, 20);
g_RabbitSprite.MoveTo(1 * MAZETEXTURE_WIDTH, 19 * MAZETEXTURE_HEIGHT);
g_RabbitSprite.m_pfnDead = DeadPig;
g_RabbitSprite.m_Movement.m_pfnCollision = IsHit;
g_RabbitPooSprite.CreateSprite(&g_pSpriteSurface, TYPE_POO, nHeight,nWidth);
rcBounding.top = rcBounding.left = 20;
rcBounding.right=rcBounding.bottom = nHeight - 40;
pt.x = 0*64;pt.y = 8*64;
g_RabbitPooSprite.AddState(ST_DEFAULT, pt, 3, 50,&rcBounding);
pt.x = 11*64;pt.y = 10*64;
g_RabbitPooSprite.AddState(ST_DEAD, pt, 3, 50,&rcBounding);
g_RabbitPooSprite.SetState(ST_DEFAULT);
// --------------- Sheep Sprite -----------------------------//
g_SheepSprite.CreateSprite(&g_pSpriteSurface, TYPE_PLAYER, nHeight,nWidth);
pt.x = 5*64; pt.y =9*64 ;
g_SheepSprite.AddState(ST_STAND_STILL, pt, 2, 60);
rcBounding.top = 0;
rcBounding.bottom = nHeight-10;
rcBounding.left = 10;
rcBounding.right= nWidth - 20;
pt.x = 6*64; pt.y =6*64;
g_SheepSprite.AddState(ST_WALK_UP, pt, 3, 10,&rcBounding);
rcBounding.top = 10;
rcBounding.bottom = nHeight-10;
pt.x = 64*9;pt.y = 6*64;
g_SheepSprite.AddState(ST_WALK_DOWN, pt, 3, 10,&rcBounding);
rcBounding.top = 10;
rcBounding.bottom = nHeight - 20;
rcBounding.left = 0;
rcBounding.right=nWidth - 10;
pt.x = 3*64;pt.y = 6*64;
g_SheepSprite.AddState(ST_WALK_LEFT, pt, 3, 10,&rcBounding);
pt.x = 64*0;pt.y = 6*64;
rcBounding.left = 10;
rcBounding.right=nWidth-10;
g_SheepSprite.AddState(ST_WALK_RIGHT, pt, 3, 10,&rcBounding);
pt.x = 64 * 8; pt.y = 9 * 64;
g_SheepSprite.AddState(ST_KILL, pt, 4, 20);
g_SheepSprite.MoveTo(1 * MAZETEXTURE_WIDTH, 19 * MAZETEXTURE_HEIGHT);
g_SheepSprite.m_pfnDead = DeadPig;
g_SheepSprite.m_Movement.m_pfnCollision = IsHit;
g_SheepPooSprite.CreateSprite(&g_pSpriteSurface, TYPE_POO, nHeight,nWidth);
rcBounding.top = rcBounding.left = 20;
rcBounding.right=rcBounding.bottom = nHeight - 40;
pt.x = 0*64;pt.y = 9*64;
g_SheepPooSprite.AddState(ST_DEFAULT, pt, 3, 50,&rcBounding);
pt.x = 11*64;pt.y = 10*64;
g_SheepPooSprite.AddState(ST_DEAD, pt, 3, 50,&rcBounding);
g_SheepPooSprite.SetState(ST_DEFAULT);
// --------------- Enemy Sprites -----------------------------//
g_EnemySpriteManager.SetCollAndPathFn(IsHit, FindPath);
rcBounding.left = 10;
rcBounding.top =0;
rcBounding.right = SPRITE_WIDTH - 20;
rcBounding.bottom = SPRITE_HEIGHT ;
g_Enemy1Sprite.CreateSprite(&g_pSpriteSurface, TYPE_ENEMY1, nHeight,nWidth);
pt.x = 6*64;pt.y = 0*64;
g_Enemy1Sprite.AddState(ST_WALK_UP, pt, 2, 20,&rcBounding);
pt.x = 3*64;pt.y = 0*64;
g_Enemy1Sprite.AddState(ST_WALK_LEFT, pt, 3, 20,&rcBounding);
pt.x = 0*64;pt.y = 0*64;
g_Enemy1Sprite.AddState(ST_WALK_RIGHT, pt, 3, 20,&rcBounding);
pt.x = 8*64;pt.y = 0*64;
g_Enemy1Sprite.AddState(ST_WALK_DOWN, pt, 2, 20,&rcBounding);
pt.x = 10*64;pt.y = 0*64;
g_Enemy1Sprite.AddState(ST_KILL, pt, 3, 100);
g_Enemy1Sprite.m_pfnDead= DeadEnemy;
g_Enemy1Sprite.m_nPoints = 100;
g_Enemy2Sprite.CreateSprite(&g_pSpriteSurface, TYPE_ENEMY2, nHeight,nWidth);
pt.x = 6*64;pt.y = 1*64;
g_Enemy2Sprite.AddState(ST_WALK_UP, pt, 2, 20,&rcBounding);
pt.x = 3*64;pt.y = 1*64;
g_Enemy2Sprite.AddState(ST_WALK_LEFT, pt, 3, 20,&rcBounding);
pt.x = 0*64;pt.y = 1*64;
g_Enemy2Sprite.AddState(ST_WALK_RIGHT, pt, 3, 20,&rcBounding);
pt.x = 8*64;pt.y = 1*64;
g_Enemy2Sprite.AddState(ST_WALK_DOWN, pt, 2, 20,&rcBounding);
pt.x = 10*64;pt.y = 1*64;
g_Enemy2Sprite.AddState(ST_KILL, pt, 3, 100);
g_Enemy2Sprite.m_pfnDead= DeadEnemy;
g_Enemy2Sprite.m_nPoints = 100;
g_Enemy3Sprite.CreateSprite(&g_pSpriteSurface, TYPE_ENEMY3, nHeight,nWidth);
pt.x = 6*64;pt.y = 2*64;
g_Enemy3Sprite.AddState(ST_WALK_UP, pt, 2, 20,&rcBounding);
pt.x = 3*64;pt.y = 2*64;
g_Enemy3Sprite.AddState(ST_WALK_LEFT, pt, 3, 20,&rcBounding);
pt.x = 0*64;pt.y = 2*64;
g_Enemy3Sprite.AddState(ST_WALK_RIGHT, pt, 3, 20,&rcBounding);
pt.x = 8*64;pt.y = 2*64;
g_Enemy3Sprite.AddState(ST_WALK_DOWN, pt, 2, 20,&rcBounding);
pt.x = 10*64;pt.y = 2*64;
g_Enemy3Sprite.AddState(ST_KILL, pt, 3, 100);
g_Enemy3Sprite.m_pfnDead= DeadEnemy;
g_Enemy3Sprite.m_nPoints = 100;
g_EnemySpriteManager.AddSprite(&g_Enemy3Sprite);
g_Enemy4Sprite.CreateSprite(&g_pSpriteSurface, TYPE_ENEMY4, nHeight,nWidth);
pt.x = 6*64;pt.y = 3*64;
g_Enemy4Sprite.AddState(ST_WALK_UP, pt, 2, 20,&rcBounding);
pt.x = 3*64;pt.y = 3*64;
g_Enemy4Sprite.AddState(ST_WALK_LEFT, pt, 3, 20,&rcBounding);
pt.x = 0*64;pt.y = 3*64;
g_Enemy4Sprite.AddState(ST_WALK_RIGHT, pt, 3, 20,&rcBounding);
pt.x = 8*64;pt.y = 3*64;
g_Enemy4Sprite.AddState(ST_WALK_DOWN, pt, 2, 20,&rcBounding);
pt.x = 10*64;pt.y =3*64;
g_Enemy4Sprite.AddState(ST_KILL, pt, 3, 100);
g_Enemy4Sprite.m_pfnDead= DeadEnemy;
g_Enemy4Sprite.m_nPoints = 200;
g_EnemySpriteManager.AddSprite(&g_Enemy4Sprite);
g_Enemy5Sprite.CreateSprite(&g_pSpriteSurface, TYPE_ENEMY4, nHeight,nWidth);
pt.x = 6*64;pt.y = 3*64;
g_Enemy5Sprite.AddState(ST_WALK_UP, pt, 2, 20,&rcBounding);
pt.x = 3*64;pt.y = 3*64;
g_Enemy5Sprite.AddState(ST_WALK_LEFT, pt, 3, 20,&rcBounding);
pt.x = 0*64;pt.y = 3*64;
g_Enemy5Sprite.AddState(ST_WALK_RIGHT, pt, 3, 20,&rcBounding);
pt.x = 8*64;pt.y = 3*64;
g_Enemy5Sprite.AddState(ST_WALK_DOWN, pt, 2, 20,&rcBounding);
pt.x = 10*64;pt.y =3*64;
g_Enemy5Sprite.AddState(ST_KILL, pt, 3, 100);
g_Enemy5Sprite.m_pfnDead= DeadEnemy;
g_Enemy5Sprite.m_nPoints = 200;
g_EnemySpriteManager.AddSprite(&g_Enemy5Sprite);
g_SpecialSprite.CreateSprite(&g_pSpriteSurface, TYPE_SPECIAL, nHeight,nWidth);
pt.x = 5*64;pt.y = 10*64;
g_SpecialSprite.AddState(ST_FOOD1, pt, 1, 100);
pt.x = 6*64;pt.y = 10*64;
g_SpecialSprite.AddState(ST_FOOD2, pt, 1, 100);
pt.x = 7*64;pt.y = 10*64;
g_SpecialSprite.AddState(ST_FOOD3, pt, 1, 100);
pt.x = 8*64;pt.y = 10*64;
g_SpecialSprite.AddState(ST_FOOD4, pt, 1, 100);
pt.x = 9*64;pt.y = 10*64;
g_SpecialSprite.AddState(ST_FOOD5, pt, 1, 100);
pt.x = 10*64;pt.y = 10*64;
g_SpecialSprite.AddState(ST_FOOD6, pt, 1, 100);
pt.x = 3*64;pt.y = 8*64;
g_SpecialSprite.AddState(ST_KEY, pt, 2, 50);
pt.x = 2*64;pt.y = 10*64;
g_SpecialSprite.AddState(ST_DOOR, pt, 3, 30);
pt.x = 3*64;pt.y = 7*64;
g_SpecialSprite.AddState(ST_KILL, pt, 2, 100);
g_SpecialSprite.m_nPoints = 200;
g_SpecialSprite.m_pfnDead = DeadSpecial;
g_SpecialSprite.m_pfnKill = KillSpecial;
g_BulletSprite.CreateSprite(&g_pSpriteSurface, TYPE_BULLET, nHeight,nWidth);
rcBounding.top = rcBounding.left = 20;
rcBounding.right=rcBounding.bottom = nHeight - 40;
pt.x = 0*64;pt.y = 10*64;
g_BulletSprite.AddState(ST_DEFAULT, pt, 2, 30, &rcBounding);
pt.x = 11*64;pt.y = 10*64;
g_BulletSprite.AddState(ST_KILL, pt, 1, 10);
g_BulletSprite.m_Movement.m_pfnCollision = IsHit;
g_BulletSprite.m_Movement.m_nPathFindDelay = 5000;
g_BulletSprite.m_Movement.m_pfnFindPath=BulletFindPath;
g_BulletSprite.SetState(ST_KILL);
/*
g_Enemy1Sprite.EnableBorder(true);
g_Enemy2Sprite.EnableBorder(true);
g_Enemy3Sprite.EnableBorder(true);
g_PigSprite.EnableBorder(true);
g_RabbitSprite.EnableBorder(true);
g_SheepSprite.EnableBorder(true);
g_BulletSprite.EnableBorder(true);
*/
}
void InitLevel()
{
if (g_nCurrLevel+1 > g_nNoOfLevels) {
g_nGameState = GAMESTATE_GAMEOVERGOOD;
LoadJPEG(true, GAMEOVERGOODFILENAME, &g_pSplashSurface);
return;
}
int nNoOfEnemies = g_pLevel[g_nCurrLevel].nNoOfEnemys;
g_Maze.LoadMaze(g_pLevel[g_nCurrLevel++].szLevelFile);
g_nNoOfEnemies = 10;
SAFE_DELETE( g_pScoreTextSurface );
wsprintf((char*)g_szScore, (char*)GAMESCORE_TEXT, g_nScore);
HFONT hFont = GetGameFont();
g_pDisplay->CreateSurfaceFromText( &g_pScoreTextSurface, hFont, (char*)g_szScore,
RGB(0,0,0), RGB(255, 255, 0) );
/*
OutputDebugString("\n-----------\n");
char szDebug[100];
wsprintf (szDebug,"g_nRows %d, g_nCols :%d Sizeof %d\n",g_nRows,g_nCols,sizeof(short[g_nCols][g_nRows]));
OutputDebugString(szDebug);
for (int i=0; i < g_nRows; i++) {
for(int j=0; j <g_nCols; j++) {
if (g_nPathArray[i][j] !=0)
szDebug[j]='1';
else
szDebug[j]='0';
}
szDebug[j]='\n';
szDebug[j+1]='\0';
OutputDebugString(szDebug);
}
OutputDebugString("-----------\n");
*/
g_nNoOfSpecials = NO_OF_SPECIALS;
SAFE_DELETE(g_pLevelTextSurface);
g_pDisplay->CreateSurfaceFromText( &g_pLevelTextSurface, hFont, g_Maze.GetName(),
RGB(0,0,0), RGB(255, 255, 0) ) ;
POINT pt= { 0*64, 3*64 };
g_pPlayerSprite->MoveTo(1 * MAZETEXTURE_WIDTH, 19 * MAZETEXTURE_HEIGHT);
g_pPlayerSprite->SetState(ST_WALK_UP, true);
g_pPlayerSprite->m_Movement.m_dx=0;
g_pPlayerSprite->m_Movement.m_dy=0;
g_pPlayerSprite->m_Movement.m_nInvulnerable=INVULNERABLE_DELAY;
g_pPooSprite->SetState(ST_DEAD, true);
g_EnemySpriteManager.Destroy();
if (nNoOfEnemies) {
nNoOfEnemies--;
pt= g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
g_Enemy1Sprite.MoveTo(pt);
g_Enemy1Sprite.m_Movement.m_dx = -1;
g_Enemy1Sprite.m_Movement.m_nPathFindDelay = 1000;
g_Enemy1Sprite.SetState(ST_WALK_LEFT, true);
g_EnemySpriteManager.AddSprite(&g_Enemy1Sprite);
}
if (nNoOfEnemies) {
nNoOfEnemies--;
pt= g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
g_Enemy2Sprite.MoveTo(pt);
g_Enemy2Sprite.m_Movement.m_dx = 1;
g_Enemy2Sprite.m_Movement.m_nPathFindDelay = 500;
g_Enemy2Sprite.SetState(ST_WALK_RIGHT, true);
g_EnemySpriteManager.AddSprite(&g_Enemy2Sprite);
}
if (nNoOfEnemies) {
nNoOfEnemies--;
pt= g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
g_Enemy3Sprite.MoveTo(pt);
g_Enemy3Sprite.m_Movement.m_dy = 1;
g_Enemy3Sprite.m_Movement.m_nPathFindDelay = 300;
g_Enemy3Sprite.SetState(ST_WALK_DOWN, true);
g_EnemySpriteManager.AddSprite(&g_Enemy3Sprite);
}
if (nNoOfEnemies) {
nNoOfEnemies--;
pt= g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
g_Enemy4Sprite.MoveTo(pt);
g_Enemy4Sprite.m_Movement.m_dy = -1;
g_Enemy4Sprite.m_Movement.m_nPathFindDelay = 200;
g_Enemy4Sprite.SetState(ST_WALK_UP, true);
g_EnemySpriteManager.AddSprite(&g_Enemy4Sprite);
}
if (nNoOfEnemies) {
nNoOfEnemies--;
pt= g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
g_Enemy5Sprite.MoveTo(pt);
g_Enemy5Sprite.m_Movement.m_dy = 1;
g_Enemy5Sprite.m_Movement.m_nPathFindDelay = 200;
g_Enemy5Sprite.SetState(ST_WALK_DOWN, true);
g_EnemySpriteManager.AddSprite(&g_Enemy5Sprite);
}
pt= g_Maze.GetRandDeployPoint();
pt.x *= MAZETEXTURE_WIDTH;
pt.y *= MAZETEXTURE_HEIGHT;
g_SpecialSprite.MoveTo(pt);
g_SpecialSprite.SetState(ST_FOOD1, true);
// SIZE szDim = { 64,64};
// g_Maze.DisplayGrid(true);
// g_Maze.DisplayDeployRects(szDim);
g_Maze.Draw(g_pMazeSurface);
SAFE_DELETE( g_pLifeTextSurface );
wsprintf((char*)g_szLifeLeft, (char*)LIFE_LEFT_TEXT, g_nLivesLeft - 1);
g_pDisplay->CreateSurfaceFromText( &g_pLifeTextSurface, hFont, (char*)g_szLifeLeft,
RGB(0,0,0), RGB(255, 255, 0) );
DeleteObject(hFont);
}
//-----------------------------------------------------------------------------
// Name: FreeDirectDraw()
// Desc: Release all the DirectDraw objects
//-----------------------------------------------------------------------------
VOID FreeDirectDraw()
{
#ifdef DISPLAY_STATUS
SAFE_DELETE( g_pTextSurface );
#endif
SAFE_DELETE( g_pLifeTextSurface );
SAFE_DELETE( g_pScoreTextSurface );
SAFE_DELETE( g_pLevelTextSurface );
SAFE_DELETE( g_pMazeSurface );
SAFE_DELETE( g_pSpriteSurface );
SAFE_DELETE( g_pSplashSurface);
SAFE_DELETE( g_pDisplay );
SAFE_DELETE( g_pSplashSound );
SAFE_DELETE( g_pPickupSound );
SAFE_DELETE( g_pSoundManager );
SAFE_DELETE( g_pHandleInput );
}
//-----------------------------------------------------------------------------
// Name: MainWndProc()
// Desc: The main window procedure
//-----------------------------------------------------------------------------
LRESULT CALLBACK MainWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch (msg)
{
case WM_COMMAND:
switch( LOWORD(wParam) )
{
case IDM_TOGGLEFULLSCREEN:
// Toggle the fullscreen/window mode
if( g_bWindowed )
GetWindowRect( hWnd, &g_rcWindow );
g_bWindowed = !g_bWindowed;
if( FAILED( InitDirectDrawMode( hWnd, g_bWindowed ) ) )
{
SAFE_DELETE( g_pDisplay );
MessageBox( hWnd, TEXT("InitDirectDraw() failed. ")
TEXT("The sample will now exit. "), TEXT("DirectDraw Sample"),
MB_ICONERROR | MB_OK );
PostMessage( hWnd, WM_CLOSE, 0, 0 );
}
return 0L;
case IDM_PAUSE:
g_bActive = true - g_bActive;
return 0L;
case IDM_EXIT:
// Received key/menu command to exit app
PostMessage( hWnd, WM_CLOSE, 0, 0 );
return 0L;
}
break; // Continue with default processing
case WM_GETMINMAXINFO:
{
// Don't allow resizing in windowed mode.
// Fix the size of the window to 640x480 (client size)
MINMAXINFO* pMinMax = (MINMAXINFO*) lParam;
DWORD dwFrameWidth = GetSystemMetrics( SM_CXSIZEFRAME );
DWORD dwFrameHeight = GetSystemMetrics( SM_CYSIZEFRAME );
DWORD dwMenuHeight = GetSystemMetrics( SM_CYMENU );
DWORD dwCaptionHeight = GetSystemMetrics( SM_CYCAPTION );
pMinMax->ptMinTrackSize.x = SCREEN_WIDTH + dwFrameWidth * 2;
pMinMax->ptMinTrackSize.y = SCREEN_HEIGHT + dwFrameHeight * 2 +
dwMenuHeight + dwCaptionHeight;
pMinMax->ptMaxTrackSize.x = pMinMax->ptMinTrackSize.x;
pMinMax->ptMaxTrackSize.y = pMinMax->ptMinTrackSize.y;
}
return 0L;
case WM_MOVE:
// Retrieve the window position after a move.
if( g_pDisplay )
g_pDisplay->UpdateBounds();
return 0L;
case WM_SIZE:
// Check to see if we are losing our window...
if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam )
g_bActive = FALSE;
else
g_bActive = TRUE;
if( g_pDisplay )
g_pDisplay->UpdateBounds();
break;
case WM_SETCURSOR:
// Hide the cursor if in fullscreen
if( !g_bWindowed )
{
SetCursor( NULL );
return TRUE;
}
break; // Continue with default processing
case WM_QUERYNEWPALETTE:
if( g_pDisplay && g_pDisplay->GetFrontBuffer() )
{
// If we are in windowed mode with a desktop resolution in 8 bit
// color, then the palette we created during init has changed
// since then. So get the palette back from the primary
// DirectDraw surface, and set it again so that DirectDraw
// realises the palette, then release it again.
LPDIRECTDRAWPALETTE pDDPal = NULL;
g_pDisplay->GetFrontBuffer()->GetPalette( &pDDPal );
g_pDisplay->GetFrontBuffer()->SetPalette( pDDPal );
SAFE_RELEASE( pDDPal );
}
break;
case WM_EXITMENULOOP:
// Ignore time spent in menu
g_dwLastTick = timeGetTime();
break;
case WM_EXITSIZEMOVE:
// Ignore time spent resizing
g_dwLastTick = timeGetTime();
break;
case WM_SYSCOMMAND:
// Prevent moving/sizing and power loss in fullscreen mode
switch( wParam )
{
case SC_MOVE:
case SC_SIZE:
case SC_MAXIMIZE:
case SC_MONITORPOWER:
if( !g_bWindowed )
return TRUE;
}
break;
case WM_DESTROY:
// Cleanup and close the app
FreeDirectDraw();
PostQuitMessage( 0 );
return 0L;
break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
//-----------------------------------------------------------------------------
// Name: ProcessNextFrame()
// Desc: Move the sprites, blt them to the back buffer, then
// flip or blt the back buffer to the primary buffer
//-----------------------------------------------------------------------------
HRESULT ProcessNextFrame( HWND hWnd )
{
HRESULT hr;
// Figure how much time has passed since the last time
DWORD dwCurrTick = timeGetTime();
DWORD dwTickDiff = dwCurrTick - g_dwLastTick;
// Don't update if no time has passed
if( dwTickDiff == 0 )
return S_OK;
g_dwLastTick = dwCurrTick;
dwTickDiff = 17 - dwTickDiff;
if (dwTickDiff > 0 && dwTickDiff < 17)
Sleep(dwTickDiff);
// Sleep(10);
// Check the cooperative level before rendering
if( FAILED( hr = g_pDisplay->GetDirectDraw()->TestCooperativeLevel() ) )
{
switch( hr )
{
case DDERR_EXCLUSIVEMODEALREADYSET:
case DDERR_NOEXCLUSIVEMODE:
// Do nothing because some other app has exclusive mode
Sleep(10);
return S_OK;
case DDERR_WRONGMODE:
// The display mode changed on us. Update the
// DirectDraw surfaces accordingly
return InitDirectDrawMode( hWnd, g_bWindowed );
}
return hr;
}
// Display the sprites on the screen
if( FAILED( hr = DisplayFrame() ) )
{
if( hr != DDERR_SURFACELOST )
return hr;
// The surfaces were lost so restore them
RestoreSurfaces();
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DisplayFrame()
// Desc: Blts a the sprites to the back buffer, then it blts or flips the
// back buffer onto the primary buffer.
//-----------------------------------------------------------------------------
HRESULT DisplayFrame()
{
HRESULT hr;
if( Input() )
Input()->UpdateDevices();
// Fill the back buffer with black, ignoring errors until the flip
g_pDisplay->Clear( 0 );
switch (g_nGameState)
{
case GAMESTATE_SPLASHSCREEN:
{
if (g_pSplashSound == NULL) {
g_pSoundManager->Create( &g_pSplashSound, "WavSplashScreen", 0, GUID_NULL );
}
if (g_pSplashSound->IsSoundPlaying() == false) {
g_pSplashSound->Play(0,DSBPLAY_LOOPING);
LoadJPEG(true, SPLASHFILENAME, &g_pSplashSurface);
}
g_pDisplay->Blt(0,0, g_pSplashSurface, NULL);
break;
}
case GAMESTATE_CHOICE:
{
g_pDisplay->Blt(0,0, g_pSplashSurface, NULL);
break;
}
case GAMESTATE_RUNNING:
{
LPDIRECTDRAWSURFACE7 lpdds = g_pDisplay->GetBackBuffer();
if (g_nPooDelay)
--g_nPooDelay;
else {
g_pPooSprite->SetState(ST_DEAD);
}
g_pDisplay->Blt( 0, 0, g_pMazeSurface, NULL );
// Blt the help text on the backbuffer, ignoring errors until the flip
#ifdef DISPLAY_STATUS
g_pDisplay->Blt( 10, 10, g_pTextSurface, NULL );
#endif
g_pDisplay->Blt( 10, 710, g_pLifeTextSurface, NULL );
g_pDisplay->Blt( SCREEN_WIDTH - g_pScoreTextSurface->GetSurfaceDesc().dwWidth - 10, 710, g_pScoreTextSurface, NULL );
g_pDisplay->Blt( SCREEN_WIDTH/2 - g_pLevelTextSurface->GetSurfaceDesc().dwWidth/2, 710, g_pLevelTextSurface, NULL );
g_pPooSprite->Update();
g_pPlayerSprite->Update();
g_SpecialSprite.Update();
g_EnemySpriteManager.Update();
g_BulletSprite.Update();
g_EnemySpriteManager.KillSpritesColliWith(g_pPooSprite);
if (g_pPlayerSprite->m_Movement.m_nInvulnerable == 0) {
if (g_EnemySpriteManager.IsHit(g_pPlayerSprite->GetRect()) || g_BulletSprite.IsHit(g_pPlayerSprite->GetRect())) {
g_pPlayerSprite->SetState(ST_KILL);
g_BulletSprite.SetState(ST_KILL);
g_pPlayerSprite->m_Movement.m_dx = g_pPlayerSprite->m_Movement.m_dy =0;
}
}
if (g_SpecialSprite.IsHit(g_pPlayerSprite->GetRect()) && g_SpecialSprite.GetState()!=ST_KILL) {
g_pPickupSound->Play(0,0);
g_SpecialSprite.SetState(ST_KILL);
}
g_pPooSprite->Draw(lpdds);
g_SpecialSprite.Draw(lpdds);
g_pPlayerSprite->Draw(lpdds);
g_BulletSprite.Draw(lpdds);
g_EnemySpriteManager.Draw(lpdds);
break;
}
case GAMESTATE_GAMEOVERGOOD:
case GAMESTATE_GAMEOVERBAD:
{
g_pDisplay->Blt(0,0, g_pSplashSurface, NULL);
}
}
// Flip or blt the back buffer onto the primary buffer
if( FAILED( hr = g_pDisplay->Present() ) )
return hr;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: RestoreSurfaces()
// Desc: Restore all the surfaces, and redraw the sprite surfaces.
//-----------------------------------------------------------------------------
HRESULT RestoreSurfaces()
{
HRESULT hr;
LPDIRECTDRAWPALETTE pDDPal = NULL;
if( FAILED( hr = g_pDisplay->GetDirectDraw()->RestoreAllSurfaces() ) )
return hr;
// No need to re-create the surface, just re-draw it.
#ifdef DISPLAY_STATUS
if( FAILED( hr = g_pTextSurface->DrawText( NULL, (char*)g_szGameStatus,
0, 0, RGB(0,0,0), RGB(255, 255, 0) ) ) )
return hr;
#endif
if( FAILED( hr = g_pLifeTextSurface->DrawText( NULL, (char*)g_szLifeLeft,
0, 0, RGB(0,0,0), RGB(255, 255, 0) ) ) )
return hr;
if( FAILED( hr = g_pScoreTextSurface->DrawText( NULL, (char*)g_szScore,
0, 0, RGB(0,0,0), RGB(255, 255, 0) ) ) )
return hr;
if( FAILED( hr = g_pLevelTextSurface->DrawText( NULL, g_Maze.GetName(),
0, 0, RGB(0,0,0), RGB(255, 255, 0) ) ) )
return hr;
g_Maze.Draw(g_pMazeSurface);
if( FAILED( hr = g_pSpriteSurface->DrawBitmap( "Sprite.bmp"/*MAKEINTRESOURCE( IDB_SPRITE )*/,
0, 0 ) ) )
return hr;
if (g_nGameState == GAMESTATE_SPLASHSCREEN) {
LoadJPEG(true, SPLASHFILENAME, &g_pSplashSurface);
}
if (g_nGameState == GAMESTATE_CHOICE) {
LoadJPEG(true, CHOICEFILENAME, &g_pSplashSurface);
}
if (g_nGameState == GAMESTATE_GAMEOVERGOOD) {
LoadJPEG(true, GAMEOVERGOODFILENAME, &g_pSplashSurface);
}
if (g_nGameState == GAMESTATE_GAMEOVERBAD) {
LoadJPEG(true, GAMEOVERBADFILENAME, &g_pSplashSurface);
}
return S_OK;
}
//16Bit Color conversion macros
#define RGB555(r, g, b) ((r >> 3) | ((g >> 3) << 5) | ((b >> 3) << 10))
#define RGB565(r, g, b) ((r >> 3) | ((g >> 2) << 5) | ((b >> 3) << 11))
//16Bit Color Formats
#define PF_555 1
#define PF_565 2
//Color modes
#define C16BIT 16
#define C24BIT 24
#define C32BIT 32
//*************
//* Load JPEG *
//*************
bool LoadJPEG(bool bFromFile, LPCTSTR szName, CSurface** ppSurface)
{
//Error handle
IJLERR jerr;
int nPixelFormat = PF_555;
//Create the JPEG object
JPEG_CORE_PROPERTIES jcprops;
DDPIXELFORMAT DDPixelFormat;
ZeroMemory(&DDPixelFormat, sizeof(DDPixelFormat));
DDPixelFormat.dwSize = sizeof(DDPixelFormat);
HRESULT Result = g_pDisplay->GetBackBuffer()->GetPixelFormat(&DDPixelFormat);
if(Result != DD_OK)
{
MessageBox(g_hMainWnd, "Failed to retrieve pixel format", TITLE, MB_OK);
return false;
}
//Get green bitmask and set pixel format
if((DDPixelFormat.dwGBitMask / 32) == 31)
nPixelFormat = PF_555;
else if((DDPixelFormat.dwGBitMask / 32) == 63)
nPixelFormat = PF_565;
//Initialize the JPEG object
jerr = ijlInit(&jcprops);
if (jerr != IJL_OK)
{
MessageBox(g_hMainWnd, "IJLInit problem", TITLE, MB_OK);
return false;
}
//Load from File or Resource?
if (bFromFile)
{
//Set the IJL data source as a filename
jcprops.JPGFile = szName;
//Read JPEG parameters from the file
jerr = ijlRead(&jcprops, IJL_JFILE_READPARAMS);
}
else //(Location == FROM_RESOURCE) or integer ID of resource
{
//Resource variables
BYTE* pmem;
HGLOBAL hmem;
DWORD size;
HRSRC hres;
hres = FindResource(NULL, szName, "JPEG");
if (hres)
{
size = SizeofResource(NULL, hres);
if (!size)
{
MessageBox(g_hMainWnd, "Error retrieving resource size",
TITLE, MB_OK);
return false;
}
hmem = LoadResource(NULL, hres);
if (hmem == NULL)
{
MessageBox(g_hMainWnd, "Error loading resource", TITLE, MB_OK);
return false;
}
pmem = (BYTE *)LockResource(hmem);
if (pmem == NULL)
{
MessageBox(g_hMainWnd, "Error locking resource", TITLE, MB_OK);
return false;
}
}
else
{
MessageBox(g_hMainWnd, "JPEG resource not found", TITLE, MB_OK);
return false;
}
//Set the IJL data source as the resource buffer
jcprops.JPGFile = NULL;
jcprops.JPGBytes = pmem;
jcprops.JPGSizeBytes = size;
//Read JPEG parameters from the buffer
jerr = ijlRead(&jcprops, IJL_JBUFF_READPARAMS);
}
//Make sure Parameter read was successful
if (jerr != IJL_OK)
{
MessageBox(g_hMainWnd, "Error reading JPEG parameters", TITLE, MB_OK);
return false;
}
//Prepare a 24Bit buffer to receive image data
BYTE *buffer24;
//Determine the required size
long szbuff24 = (jcprops.JPGWidth * C24BIT + 7) / 8
* jcprops.JPGHeight;
//Resize the buffer
buffer24 = new BYTE [szbuff24];
if (buffer24 == NULL)
{
MessageBox(g_hMainWnd, "Memory Allocation Error", TITLE, MB_OK);
return false;
}
//Set up the DIB specification for the JPEG decoder
jcprops.DIBWidth = jcprops.JPGWidth;
jcprops.DIBHeight = jcprops.JPGHeight; //Implies a bottom-up DIB.
jcprops.DIBChannels = 3;
jcprops.DIBColor = IJL_BGR;
jcprops.DIBPadBytes = IJL_DIB_PAD_BYTES(jcprops.JPGWidth,3);
jcprops.DIBBytes = reinterpret_cast<BYTE*>(buffer24);
//Set the JPG color space ... this will always be somewhat of an
//educated guess at best because JPEG is "color blind" (i.e.,
//nothing in the bit stream tells you what color space the data was
//encoded from. However, in this example we assume that we are
//reading JFIF files which means that 3 channel images are in the
//YCbCr color space and 1 channel images are in the Y color space.
switch(jcprops.JPGChannels)
{
case 1: jcprops.JPGColor = IJL_G;
break;
case 3: jcprops.JPGColor = IJL_YCBCR;
break;
default:
//This catches everything else, but no color twist will be
//performed by the IJL.
jcprops.DIBColor = (IJL_COLOR)IJL_OTHER;
jcprops.JPGColor = (IJL_COLOR)IJL_OTHER;
break;
}
//Read JPEG image data into our 24bit buffer
if (bFromFile)
jerr = ijlRead(&jcprops, IJL_JFILE_READWHOLEIMAGE);
else
jerr = ijlRead(&jcprops, IJL_JBUFF_READWHOLEIMAGE);
//Make sure the read was successful
if (jerr != IJL_OK)
{
MessageBox(g_hMainWnd, "Error reading JPEG image", TITLE, MB_OK);
return false;
}
HBITMAP hbm;
//Convert to current CLRMODE
if (DDPixelFormat.dwRGBBitCount == C16BIT)
{
//Create a 16bit buffer
WORD *buffer16;
long szbuff16;
//determine the size of our buffer
szbuff16 = ((jcprops.JPGWidth * C16BIT + 7) / 8)
* jcprops.JPGHeight;
//resize the buffer and make sure resize works
buffer16 = new WORD [szbuff16];
if (buffer16 == NULL)
{
MessageBox(g_hMainWnd, "Error creating 16Bit buffer", TITLE, MB_OK);
return false;
}
//Start at the beginning of the buffer
long j = 0;
//Step through the 24bit buffer
//Retrieve 3 channels at a time and convert their values to 16bit
for (long i = 0; i < szbuff24; i += 3)
{
//Check the pixel format and write the color data
//to the 16bit buffer. After the write, advance the
//16bit buffer by one.
if (nPixelFormat == PF_555)
buffer16[j++] = RGB555(buffer24[i], buffer24[i + 1],
buffer24[i + 2]);
else
buffer16[j++] = RGB565(buffer24[i], buffer24[i + 1],
buffer24[i + 2]);
}
//Create the bitmap using the new 16bit buffer
hbm = CreateBitmap (jcprops.JPGWidth, jcprops.JPGHeight, 1,
C16BIT, buffer16);
if(hbm == NULL)
{
MessageBox(g_hMainWnd, "Failed to create 16Bit Bitmap", TITLE, MB_OK);
return false;
}
//remove the new buffer
delete buffer16;
}
else if (DDPixelFormat.dwRGBBitCount == C24BIT)
{
//The data we have from the JPEG is already 24bit
//Just create the new bitmap from our buffer
hbm = CreateBitmap (jcprops.JPGWidth, jcprops.JPGHeight, 1,
C24BIT, buffer24);
if(hbm == NULL)
{
MessageBox(g_hMainWnd, "Failed to create 24Bit Bitmap", TITLE, MB_OK);
return false;
}
}
else if (DDPixelFormat.dwRGBBitCount == C32BIT)
{
//Create a 32bit buffer
BYTE *buffer32;
long szbuff32;
//determine the size of our buffer
szbuff32 = ((jcprops.JPGWidth * C32BIT + 7) / 8)
* jcprops.JPGHeight;
//resize the buffer and make sure resize works
buffer32 = new BYTE [szbuff32];
if (buffer32 == NULL)
{
MessageBox(g_hMainWnd, "Error creating 32Bit buffer", TITLE, MB_OK);
return false;
}
//Start at the beginning of the 24bit buffer
long j = 0;
//Step through the 32bit buffer, copying the 3 Channels from
//the 24bit buffer. However, at the end of each channel, we
//have to write an extra byte for the 32bit image's alpha
//channel
for (long i = 0; i < szbuff32; i += 4)
{
buffer32[i + 0] = buffer24[j++]; //Blue channel
buffer32[i + 1] = buffer24[j++]; //Green channel
buffer32[i + 2] = buffer24[j++]; //Red channel
buffer32[i + 3] = (BYTE)0x00; //Alpha channel
}
//Create the bitmap using the new 32bit buffer
hbm = CreateBitmap (jcprops.JPGWidth, jcprops.JPGHeight, 1,
C32BIT, buffer32);
if(hbm == NULL)
{
MessageBox(g_hMainWnd, "Failed to create 32Bit Bitmap",
TITLE, MB_OK);
return false;
}
//remove the 32bit buffer
delete buffer32;
}
else
{
MessageBox(g_hMainWnd,
"Palettized modes not supported. Use a 16, 24, or 32 Bit display.",
TITLE, MB_OK);
return false;
}
//remove the old buffer
delete buffer24;
//If DirectDraw Surface is NULL, create it
if (*ppSurface == NULL)
{
//Create the surface from our surface description
Result = g_pDisplay->CreateSurface(ppSurface,jcprops.JPGWidth,jcprops.JPGHeight );
if(Result != DD_OK)
{
MessageBox(g_hMainWnd, "Could not create surface", TITLE, MB_OK);
return false;
}
}
//Copy bitmap data to DirectDraw Surface
(*ppSurface)->DrawBitmap(hbm, 0, 0, 0, 0);
// clean up and destroy the JPEG Decompressor
ijlFree(&jcprops);
DeleteObject(hbm);
return true;
}