Keyboard.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:3k
源码类别:

游戏

开发平台:

Visual C++

  1. /*******************************************************************
  2.  *         Advanced 3D Game Programming using DirectX 7.0
  3.  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  4.  *   Title: Keyboard.cpp
  5.  *    Desc: Wrapper of a DirectInput keyboard object
  6.  *          
  7.  * copyright (c) 1999 by Adrian Perez
  8.  * See license.txt for modification and distribution information
  9.  ******************************************************************/
  10. #include <windows.h>
  11. #include "GameErrors.h"
  12. #include "InputLayer.h"
  13. #include <stack>
  14. using namespace std;
  15. #include "Keyboard.h"
  16. cKeyboard::cKeyboard( HWND hWnd )
  17. {
  18. m_pTarget = NULL;
  19. HRESULT hr;
  20. /**
  21.  * Get the DInput interface pointer
  22.  */
  23. LPDIRECTINPUT8 pDI = Input()->GetDInput();
  24. /**
  25.  * Create the keyboard device
  26.  */
  27.     hr = pDI->CreateDevice(
  28. GUID_SysKeyboard,
  29. &m_pDevice, 
  30. NULL); 
  31.     if( FAILED(hr) )
  32.     { 
  33.         throw cGameError("Keyboard could not be createdn");
  34.     } 
  35.  
  36. /**
  37.  * Set the keyboard data format
  38.  */
  39.     hr = m_pDevice->SetDataFormat(&c_dfDIKeyboard); 
  40.     if( FAILED(hr) )
  41.     { 
  42. SafeRelease( m_pDevice );
  43.         throw cGameError("Keyboard could not be createdn");
  44.     } 
  45.  
  46.     /**
  47.  * Set the cooperative level 
  48.  */
  49.     hr = m_pDevice->SetCooperativeLevel(
  50. hWnd,
  51. DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); 
  52.     if( FAILED(hr) )
  53.     { 
  54. SafeRelease( m_pDevice );
  55.         throw cGameError("Keyboard coop level could not be changedn");
  56.     } 
  57. // CHANGE: we used to grab the keyboard here, but this would cause
  58. // a crash if the app didn't have focus when it started up.  This is,
  59. // of course, an undesirable trait :)
  60. memset( m_keyState, 0, 256*sizeof(bool) );
  61. }
  62. cKeyboard::~cKeyboard()
  63. {
  64. if( m_pDevice )
  65. {
  66. m_pDevice->Unacquire();
  67. SafeRelease( m_pDevice );
  68. }
  69. }
  70. void cKeyboard::SetReceiver( iKeyboardReceiver* pTarget )
  71. {
  72. // Set the new target.
  73. m_pTarget = pTarget;
  74. }
  75. bool cKeyboard::Poll( int key )
  76. {
  77. // stuff goes in here.
  78. if( m_keyState[key] & 0x80 )
  79. return true;
  80. return false;
  81. }
  82. eResult cKeyboard::Update()
  83. {
  84. char     newState[256]; 
  85.     HRESULT  hr; 
  86.  
  87. // CHANGE: Polling can't hurt, but it can help.
  88.     hr = m_pDevice->Poll(); 
  89.     hr = m_pDevice->GetDeviceState(sizeof(newState),(LPVOID)&newState); 
  90.     if( FAILED(hr) )
  91.     { 
  92. hr = m_pDevice->Acquire();
  93. if( FAILED( hr ) )
  94. {
  95. return resFailed;
  96. }
  97.     hr = m_pDevice->Poll(); 
  98.     hr = m_pDevice->GetDeviceState(sizeof(newState),(LPVOID)&newState); 
  99. if( FAILED( hr ) )
  100. {
  101. return resFailed;
  102. }
  103.     } 
  104. if( m_pTarget )
  105. {
  106. int i;
  107. for( i=0; i< 256; i++ )
  108. {
  109. if( m_keyState[i] != newState[i] )
  110. {
  111. // Something happened to this key since the last time we checked
  112. if( !(newState[i] & 0x80) )
  113. {
  114. // It was Released
  115. m_pTarget->KeyUp( i );
  116. }
  117. else
  118. {
  119. // Do nothing; it was just pressed, it'll get a keydown 
  120. // in a bit, and we dont' want to send the signal to the 
  121. // input target twice
  122. }
  123. }
  124. // copy the state over (we could do a memcpy at the end, but this
  125. // will have better cache performance)
  126. m_keyState[i] = newState[i];
  127. if( Poll( i ) )
  128. {
  129. // It was pressed
  130. m_pTarget->KeyDown( i );
  131. }
  132. }
  133. }
  134. else
  135. {
  136. // copy the new states over.
  137. memcpy( m_keyState, newState, 256 );
  138. }
  139.  
  140. return resAllGood;
  141. }