CDirectDrawGame.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:21k
- ///////////////////////////////////////////////////////////////////////////////
- /// File: CDirectDrawGame.cpp
- /// Purpose: Implementation of CDirectDrawGame Class
- ///////////////////////////////////////////////////////////////////////////////
- /// Configuation Management
- ///
- /// Who When Description
- /// ===========================================================================
- /// R. Walter 28-Dec-2003 Initial Version/Release
- ///
- ///////////////////////////////////////////////////////////////////////////////
- /// Copyright 2003: Robert Walter All rights reserved
- ///////////////////////////////////////////////////////////////////////////////
- /// HEADER FILE INCLUDES //////////////////////////////////////////////////////
- #include "CDirectDrawGame.h"
- /// CLASS CONSTRUCTORS / DESTRUCTORS //////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: CDirectDrawGame --> default constructor
- /// Purpose: Initialize member variables
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: nothing
- ///////////////////////////////////////////////////////////////////////////////
- CDirectDrawGame::CDirectDrawGame()
- {
- m_lpdd7 = NULL;
- m_lpdds_primary = NULL;
- m_lpdds_back = NULL;
- m_lpdi8 = NULL;
- m_di_keyboard = NULL;
- m_screen_width = 640;
- m_screen_height = 480;
- m_screen_bpp = 16;
- m_frame_fps = 10;
- m_wait_ms = 0;
- m_tick_cnt = 0;
- // 16-bit color management variables
- m_num_red_bits = 0;
- m_num_green_bits = 0;
- m_num_blue_bits = 0;
- m_low_red_bit = 0;
- m_low_green_bit = 0;
- m_low_blue_bit = 0;
-
- return;
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: ~CDirectDrawGame --> class destructor
- /// Purpose: Release member variables
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: nothing
- /// Returns: nothing
- ///////////////////////////////////////////////////////////////////////////////
- CDirectDrawGame::~CDirectDrawGame()
- {
- // release the DirectX objects just incase
- ShutdownDirectInput();
- ShutdownDirectDraw();
- return;
- }
- /// CLASS MEMBER FUNCTIONS ////////////////////////////////////////////////////
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: CalculateRBGBitShift
- /// Purpose: Calculate the bit shift required to convert an RGB color to a
- /// 16-bit (DWORD) number DirectDraw understands. This function needs
- /// to be called for each color component
- /// Scope: private
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: Bitmask of color component
- /// Pointer to 8-bit (WORD) number to hold low order bit
- /// Pointer to 8-bit (WORD) number to hold number of bits to shift
- /// Returns: none
- ///////////////////////////////////////////////////////////////////////////////
- void CDirectDrawGame::CalculateRGBBitShift(DWORD p_bit_mask, WORD* p_low_bit, WORD* p_num_bits)
- {
- *p_low_bit = 0;
- *p_num_bits = 0;
- // count number of zeroes on right side of mask
- while ( !(p_bit_mask & 1) )
- {
- (*p_low_bit)++;
- p_bit_mask >>= 1;
- }
- while (p_bit_mask & 1)
- {
- (*p_num_bits)++;
- p_bit_mask >>= 1;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: DrawRectangle
- /// Purpose: Draw the passed rectangle to the back buffer
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: RECT structure of destination rectangle to BLT to the back buffer
- /// DWORD color of the rectangle to BLT
- /// Returns: true if BLT successful, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CDirectDrawGame::DrawRectangle(RECT* p_rectangle, const DWORD p_color)
- {
- DWORD dxr = 0;
- // initialize BLTFX structure
- DDBLTFX ddbfx;
- memset(&ddbfx, 0, sizeof(ddbfx));
- ddbfx.dwSize = sizeof(ddbfx);
- ddbfx.dwFillColor = p_color;
- // BLT specified color to entire back buffer
- dxr = m_lpdds_back->Blt
- (
- /* lpDestRect */ p_rectangle, // pointer to rectangle on back buffer to fill with color
- /* lpDDSrcSurface */ NULL, // source surface, NULL for a color fill
- /* lpSrcRect */ NULL, // source RECT, NULL for a color fill
- /* dwFlags */ DDBLT_COLORFILL | DDBLT_WAIT, // tell BLT to fill and wait till not busy
- /* lpDDBltFx */ &ddbfx // pointer to BLTFX struct
- );
- if (FAILED(dxr))
- {
- return(false);
- }
- return true;
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: DrawGDIText
- /// Purpose: Draw the passed text in the specified font and rectangle
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: - text to draw on the screen
- /// - red component of text color
- /// - green component of text color
- /// - blue component of text color
- /// - HFONT of font to draw
- /// - x coordinate of top left corner of text rectangle
- /// - y coordinate of top left corner of text rectangle
- /// Returns: true if DrawText successful, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CDirectDrawGame::DrawGDIText(char* p_text, DWORD p_r, DWORD p_g, DWORD p_b, HFONT p_font, int p_x, int p_y)
- {
- HFONT l_old_font = NULL;
- l_old_font = (HFONT)SelectObject(m_hdc, p_font);
- if (!l_old_font)
- {
- return(false);
- }
- SetTextColor(m_hdc, RGB(p_r,p_g,p_b));
-
- // set the background color to black
- SetBkColor(m_hdc, RGB(0,0,0));
-
- // set the transparency mode to OPAQUE
- SetBkMode(m_hdc, TRANSPARENT);
- TextOut(m_hdc, p_x, p_y, p_text, strlen(p_text));
- SelectObject(m_hdc, l_old_font);
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: EndGDIDrawing
- /// Purpose: Release the GDI variables
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: None
- /// Returns: Nothing
- ///////////////////////////////////////////////////////////////////////////////
- void CDirectDrawGame::EndGDIDrawing()
- {
- m_lpdds_back->ReleaseDC(m_hdc);
- return;
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: EndScene
- /// Purpose: Complete the scene and flip the primary surface
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: None
- /// Returns: true if flip successful, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CDirectDrawGame::EndScene()
- {
- DWORD dxr = 0;
- dxr = m_lpdds_primary->Flip(NULL, DDFLIP_WAIT);
- if (FAILED(dxr))
- {
- return(false);
- }
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: FrameRateStart
- /// Purpose: Method used to start the timing to sync the frame
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: None
- /// Returns: None
- ///////////////////////////////////////////////////////////////////////////////
- void CDirectDrawGame::FrameRateStart()
- {
- m_tick_cnt = GetTickCount();
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: FrameRateEnd
- /// Purpose: Method used to end the timing to sync the frame
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: None
- /// Returns: None
- ///////////////////////////////////////////////////////////////////////////////
- void CDirectDrawGame::FrameRateEnd()
- {
- DWORD l_wait = 0;
- l_wait = (m_wait_ms - (GetTickCount() - m_tick_cnt));
- if (l_wait > 0)
- {
- Sleep(l_wait);
- }
- //Sleep(100);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: GetKeyboardState
- /// Purpose: Method used to retrieve the keys pressed from DirectInput
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: KEYSTATE (UCHAR[256]) Array
- /// Returns: True is successfully retrieve keyboard state, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CDirectDrawGame::GetKeyboardState(UCHAR* p_keyboard)
- {
- DWORD dxr = 0;
- dxr = m_di_keyboard->GetDeviceState(256, (void*)p_keyboard);
- if (FAILED(dxr))
- {
- return(false);
- }
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: InitializeDirectDraw
- /// Purpose: Initialize all the required DirectDraw objects and interfaces
- /// Scope: private
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: None
- /// Returns: true if initialization successful, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CDirectDrawGame::InitializeDirectDraw()
- {
- DWORD dxr = 0; /** DirectX function return value **/
- ////////////////////////////////////////////////////
- /// create main DirectDraw interface object
- ////////////////////////////////////////////////////
- dxr = DirectDrawCreateEx(NULL, (void**)&m_lpdd7, IID_IDirectDraw7, NULL);
- if (FAILED(dxr))
- {
- return false;
- }
- ////////////////////////////////////////////////////
- /// set DirectDraw cooperation level with the
- /// main window
- ////////////////////////////////////////////////////
- dxr = m_lpdd7->SetCooperativeLevel(m_main_hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN |DDSCL_ALLOWREBOOT);
- if (FAILED(dxr))
- {
- return false;
- }
- ////////////////////////////////////////////////////
- /// set the display mode for DirectDraw
- ////////////////////////////////////////////////////
- dxr = m_lpdd7->SetDisplayMode(m_screen_width, m_screen_height, m_screen_bpp, 0, 0);
- if (FAILED(dxr))
- {
- return false;
- }
- ////////////////////////////////////////////////////
- /// set description of the primary surface
- ////////////////////////////////////////////////////
- DDSURFACEDESC2 ddsd;
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = (DDSD_CAPS | DDSD_BACKBUFFERCOUNT);
- ddsd.ddsCaps.dwCaps = (DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP);
- ddsd.dwBackBufferCount = 1;
-
- ////////////////////////////////////////////////////
- /// create the primary surface
- ////////////////////////////////////////////////////
- dxr = m_lpdd7->CreateSurface(&ddsd, &m_lpdds_primary, NULL);
- if (FAILED(dxr))
- {
- return false;
- }
- ////////////////////////////////////////////////////
- /// retrieve pointer to the back buffer
- ////////////////////////////////////////////////////
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
- ddsd.dwFlags = DDSD_CAPS;
- ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
- dxr = m_lpdds_primary->GetAttachedSurface(&ddsd.ddsCaps, &m_lpdds_back);
- if (FAILED(dxr))
- {
- return false;
- }
- ////////////////////////////////////////////////////
- /// determine pixel format for 16-bit color
- ////////////////////////////////////////////////////
- if (m_screen_bpp == 16)
- {
- DDPIXELFORMAT ddpf;
- memset(&ddpf, 0, sizeof(ddpf));
- ddpf.dwSize = sizeof(ddpf);
- dxr = m_lpdds_primary->GetPixelFormat(&ddpf);
- if (FAILED(dxr))
- {
- return(false);
- }
- // determine bit count and set function pointer for later transfer
- // from the bitmap to the surface
- if (ddpf.dwFlags & DDPF_RGB)
- {
- // calculate bit shift for each RGB component
- CalculateRGBBitShift(ddpf.dwRBitMask, &m_low_red_bit, &m_num_red_bits);
- CalculateRGBBitShift(ddpf.dwGBitMask, &m_low_green_bit, &m_num_green_bits);
- CalculateRGBBitShift(ddpf.dwBBitMask, &m_low_blue_bit, &m_num_blue_bits);
- }
- else
- {
- return(false);
- }
- }
- return true;
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: InitializeDirectInput
- /// Purpose: Initialize all the required DirectInput objects and interfaces
- /// Scope: private
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: None
- /// Returns: true if initialization successful, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CDirectDrawGame::InitializeDirectInput()
- {
- DWORD dxr = 0; /** DirectX function return value **/
- ////////////////////////////////////////////////////
- /// create main DirectInput interface object
- ////////////////////////////////////////////////////
- dxr = DirectInput8Create(m_instance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_lpdi8, NULL);
- if (FAILED(dxr))
- {
- return(false);
- }
- ////////////////////////////////////////////////////
- /// create keyboard device
- ////////////////////////////////////////////////////
- dxr = m_lpdi8->CreateDevice(GUID_SysKeyboard, &m_di_keyboard, NULL);
- if (FAILED(dxr))
- {
- return(false);
- }
- ////////////////////////////////////////////////////
- /// set cooperation level of the keyboard device
- ////////////////////////////////////////////////////
- dxr = m_di_keyboard->SetCooperativeLevel(m_main_hwnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
- if (FAILED(dxr))
- {
- return(false);
- }
- ////////////////////////////////////////////////////
- /// set data format of the keyboard device
- ////////////////////////////////////////////////////
- dxr = m_di_keyboard->SetDataFormat(&c_dfDIKeyboard);
- if (FAILED(dxr))
- {
- return(false);
- }
- ////////////////////////////////////////////////////
- /// last, but not least, acquire the keyboard
- ////////////////////////////////////////////////////
- dxr = m_di_keyboard->Acquire();
- if (FAILED(dxr))
- {
- return(false);
- }
- return true;
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: RGBto16BitColor
- /// Purpose: Convert a RGB Triad to a 16-bit (DWORD) color
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: DWORD for the red color
- /// DWORD for the green color
- /// DWORD for the blue color
- /// Returns: 16-bit (DWORD)
- ///////////////////////////////////////////////////////////////////////////////
- DWORD CDirectDrawGame::RGBto16BitColor(DWORD p_red, DWORD p_green, DWORD p_blue)
- {
- DWORD l_red = (p_red >> (8 - m_num_red_bits));
- DWORD l_green = (p_green >> (8 - m_num_green_bits));
- DWORD l_blue = (p_blue >> (8 - m_num_blue_bits));
- l_red <<= m_low_red_bit;
- l_green <<= m_low_green_bit;
- l_blue <<= m_low_blue_bit;
- return(l_red | l_green | l_blue);
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: SetApplicationInstance
- /// Purpose: Initialize application instance handle to be used by DirectInput
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: application instance handle
- /// Returns: None
- ///////////////////////////////////////////////////////////////////////////////
- void CDirectDrawGame::SetApplicationInstance(const HINSTANCE p_instance)
- {
- m_instance = p_instance;
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: SetFrameRate
- /// Purpose: Initialize frame rate (ie. frames per second) of the game
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: frame rate
- /// Returns: None
- ///////////////////////////////////////////////////////////////////////////////
- void CDirectDrawGame::SetFrameRate(const DWORD p_frame_fps)
- {
- m_frame_fps = p_frame_fps;
- m_wait_ms = 1000 / m_frame_fps;
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: SetScreenProperties
- /// Purpose: Initialize all screen related properties for DirectDraw
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: screen width in pixels
- /// screen height in pixels
- /// screen bpp (bits per pixel)
- /// Returns: None
- ///////////////////////////////////////////////////////////////////////////////
- void CDirectDrawGame::SetScreenProperties(const DWORD p_screen_width, const DWORD p_screen_height, const DWORD p_screen_bpp)
- {
- m_screen_width = p_screen_width;
- m_screen_height = p_screen_height;
- m_screen_bpp = p_screen_bpp;
- }
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: SetWindowHandle
- /// Purpose: Initialize main window handle to be used by DirectDraw
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: window handle
- /// Returns: None
- ///////////////////////////////////////////////////////////////////////////////
- void CDirectDrawGame::SetWindowHandle(const HWND p_hwnd)
- {
- m_main_hwnd = p_hwnd;
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: ShutdownDirectDraw
- /// Purpose: Uninitialize the allocated DirectDraw objects
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: None
- /// Returns: None
- ///////////////////////////////////////////////////////////////////////////////
- void CDirectDrawGame::ShutdownDirectDraw()
- {
- if (m_lpdds_back)
- {
- m_lpdds_back->Release();
- m_lpdds_back = NULL;
- }
- if (m_lpdds_primary)
- {
- m_lpdds_primary->Release();
- m_lpdds_primary = NULL;
- }
- if (m_lpdd7)
- {
- m_lpdd7->Release();
- m_lpdd7 = NULL;
- }
- return;
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: ShutdownDirectInput
- /// Purpose: Uninitialize the allocated DirectInput objects
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: None
- /// Returns: None
- ///////////////////////////////////////////////////////////////////////////////
- void CDirectDrawGame::ShutdownDirectInput()
- {
- if (m_di_keyboard)
- {
- m_di_keyboard->Unacquire();
- m_di_keyboard->Release();
- m_di_keyboard = NULL;
- }
- if (m_lpdi8)
- {
- m_lpdi8->Release();
- m_lpdi8 = NULL;
- }
- return;
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: StartGDIDrawing
- /// Purpose: Capture the GDI variables
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: None
- /// Returns: None
- ///////////////////////////////////////////////////////////////////////////////
- bool CDirectDrawGame::StartGDIDrawing()
- {
- DWORD dxr = 0;
- dxr = m_lpdds_back->GetDC(&m_hdc);
- if (FAILED(dxr))
- {
- return(false);
- }
- return(true);
- };
- ///////////////////////////////////////////////////////////////////////////////
- /// Method: StartScene
- /// Purpose: Erases the back buffer filling it with the passed color
- /// Scope: public
- ///////////////////////////////////////////////////////////////////////////////
- /// Receives: USHORT color to fill background
- /// Returns: true if clear successful, otherwise false
- ///////////////////////////////////////////////////////////////////////////////
- bool CDirectDrawGame::StartScene(const DWORD p_color)
- {
- DWORD dxr = 0;
- // initialize BLTFX structure
- DDBLTFX ddbfx;
- memset(&ddbfx, 0, sizeof(ddbfx));
- ddbfx.dwSize = sizeof(ddbfx);
- ddbfx.dwFillColor = p_color;
- // BLT specified color to entire back buffer
- dxr = m_lpdds_back->Blt
- (
- /* lpDestRect */ NULL, // destination RECT, NULL for whole surface
- /* lpDDSrcSurface */ NULL, // source surface, NULL for a color fill
- /* lpSrcRect */ NULL, // source RECT, NULL for whole surface
- /* dwFlags */ DDBLT_COLORFILL | DDBLT_WAIT, // tell BLT to fill and wait till not busy
- /* lpDDBltFx */ &ddbfx // pointer to BLTFX struct
- );
- if (FAILED(dxr))
- {
- return(false);
- }
- return true;
- }
- /// END OF FILE ///////////////////////////////////////////////////////////////