Main.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:58k
- //-----------------------------------------------------------------------------
- // 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 );
-
- //在满屏模式和窗口模式下,主页面和后台页面的创建方式是不同的
- g_pDisplay = new CDisplay();
- //窗口模式
- if( bWindowed )
- {
- if( FAILED( hr = g_pDisplay->CreateWindowedDisplay( hWnd, SCREEN_WIDTH,
- SCREEN_HEIGHT ) ) )
- return hr;
-
- // 在窗口方式中添加系统菜单
- 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;
- }
-
- // 无效菜单
- SetMenu( hWnd, NULL );
-
- // 从窗口方式中删除系统菜单
- /*
- DWORD dwStyle = GetWindowLong( hWnd, GWL_STYLE );
- dwStyle &= ~WS_SYSMENU;
- SetWindowLong( hWnd, GWL_STYLE, dwStyle );
- */
- }
-
-
- // 创建一个页面,在上面绘制文本
- #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;
- // ---------------- 猪精灵----------------- //
- 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);
-
- // --------------- 兔精灵 --------------- //
- 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);
-
- // --------------- 羊精灵----------------//
- 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);
-
- // --------------- 敌人精灵--------------------//
-
- //敌人精灵管理器
- 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 %dn",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]=' ';
- 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: //Alt+回车快捷键的消息处理函数
- //这个快捷键用来切换满屏/窗口模式,这是满屏程序常用的快捷键
- 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: //Pause快捷键的消息处理函数
- g_bActive = true - g_bActive;
- return 0L;
- case IDM_EXIT: //Esc快捷键的消息处理函数
- PostMessage( hWnd, WM_CLOSE, 0, 0 );
- return 0L;
- }
- break; // Continue with default processing
-
- case WM_GETMINMAXINFO: //窗口模式下的消息
- {
- //不允许改变窗口大小,固定窗口尺寸
- 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: //窗口模式下的消息
- //移动窗口
- if( g_pDisplay )
- g_pDisplay->UpdateBounds();
- return 0L;
- case WM_SIZE: //检测游戏是否失去了窗口焦点
- if( SIZE_MAXHIDE==wParam || SIZE_MINIMIZED==wParam )
- g_bActive = FALSE;
- else
- g_bActive = TRUE;
-
- if( g_pDisplay )
- g_pDisplay->UpdateBounds();
- break;
- case WM_SETCURSOR: //光标消息
- // 在全屏模式下隐藏光标
- if( !g_bWindowed )
- {
- SetCursor( NULL );
- return TRUE;
- }
- break;
- 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: //忽略在菜单上花费的时间
- g_dwLastTick = timeGetTime();
- break;
- case WM_EXITSIZEMOVE: //忽略移动窗口的时间
- g_dwLastTick = timeGetTime();
- break;
- case WM_SYSCOMMAND: //防止全屏模式下的移动/变尺和调电
- switch( wParam )
- {
- case SC_MOVE:
- case SC_SIZE:
- case SC_MAXIMIZE:
- case SC_MONITORPOWER:
- if( !g_bWindowed )
- return TRUE;
- }
- break;
- case WM_DESTROY: //清除,结束游戏
- 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;
- }