keyboard.cpp

来自「Visual C++ 游戏开发与设计实例 源代码(所有)」· C++ 代码 · 共 166 行

CPP
166
字号
/*******************************************************************
 *         Advanced 3D Game Programming using DirectX 7.0
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *   Title: Keyboard.cpp
 *    Desc: Wrapper of a DirectInput keyboard object
 *          
 * copyright (c) 1999 by Adrian Perez
 * See license.txt for modification and distribution information
 ******************************************************************/
#include <windows.h>
#include "GameErrors.h"
#include "InputLayer.h"

#include <stack>
using namespace std;
#include "Keyboard.h"


cKeyboard::cKeyboard( HWND hWnd )
{
	m_pTarget = NULL;
	
	HRESULT hr;

	/**
	 * Get the DInput interface pointer
	 */
	LPDIRECTINPUT8 pDI = Input()->GetDInput();

	/**
	 * Create the keyboard device
	 */
    hr = pDI->CreateDevice(
		GUID_SysKeyboard,
		&m_pDevice, 
		NULL); 
    if( FAILED(hr) )
    { 
        throw cGameError("Keyboard could not be created\n");
    } 
 
	/**
	 * Set the keyboard data format
	 */
    hr = m_pDevice->SetDataFormat(&c_dfDIKeyboard); 
    if( FAILED(hr) )
    { 
		SafeRelease( m_pDevice );
        throw cGameError("Keyboard could not be created\n");
    } 
 
    /**
	 * Set the cooperative level 
	 */
    hr = m_pDevice->SetCooperativeLevel(
		hWnd,
		DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); 
    if( FAILED(hr) )
    { 
		SafeRelease( m_pDevice );
        throw cGameError("Keyboard coop level could not be changed\n");
    } 

	// CHANGE: we used to grab the keyboard here, but this would cause
	// a crash if the app didn't have focus when it started up.  This is,
	// of course, an undesirable trait :)

	memset( m_keyState, 0, 256*sizeof(bool) );	
}

cKeyboard::~cKeyboard()
{
	if( m_pDevice )
	{
		m_pDevice->Unacquire();
		SafeRelease( m_pDevice );
	}
}



void cKeyboard::SetReceiver( iKeyboardReceiver* pTarget )
{
	// Set the new target.
	m_pTarget = pTarget;
}


bool cKeyboard::Poll( int key )
{
	// stuff goes in here.
	if( m_keyState[key] & 0x80 )
		return true;
	return false;
}


eResult cKeyboard::Update()
{
	char     newState[256]; 
    HRESULT  hr; 
 
	// CHANGE: Polling can't hurt, but it can help.
    hr = m_pDevice->Poll(); 
    hr = m_pDevice->GetDeviceState(sizeof(newState),(LPVOID)&newState); 

    if( FAILED(hr) )
    { 
		hr = m_pDevice->Acquire();
		if( FAILED( hr ) )
		{
			return resFailed;
		}

	    hr = m_pDevice->Poll(); 
	    hr = m_pDevice->GetDeviceState(sizeof(newState),(LPVOID)&newState); 
		if( FAILED( hr ) )
		{
			return resFailed;
		}
    } 


	if( m_pTarget )
	{
		int i;
		for( i=0; i< 256; i++ )
		{
			if( m_keyState[i] != newState[i] )
			{
				// Something happened to this key since the last time we checked
				if( !(newState[i] & 0x80) )
				{
					// It was Released
					m_pTarget->KeyUp( i );
				}
				else
				{
					// Do nothing; it was just pressed, it'll get a keydown 
					// in a bit, and we dont' want to send the signal to the 
					// input target twice
				}
			}

			// copy the state over (we could do a memcpy at the end, but this
			// will have better cache performance)
			m_keyState[i] = newState[i];

			if( Poll( i ) )
			{
				// It was pressed
				m_pTarget->KeyDown( i );
			}
		}
	}
	else
	{
		// copy the new states over.
		memcpy( m_keyState, newState, 256 );
	}
 
	return resAllGood;
}


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?