afInput.cpp
上传用户:kaiguan
上传日期:2007-10-28
资源大小:1074k
文件大小:7k
源码类别:

其他游戏

开发平台:

Visual C++

  1. // afInput.cpp: implementation of the afInput class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "afInput.h"
  6. #include "afLog.h"
  7. afInput::afInput()
  8. {
  9. m_pDI = NULL;
  10. m_pDIDeviceKB = NULL;
  11. m_pDIDeviceMouse = NULL;
  12. hMouseEvent = NULL;
  13. keyBuffer = oldKeyBuffer = NULL;
  14. mouseX = mouseY = 0;
  15. mouseB = 0;
  16. windowActive = false;
  17. }
  18. bool
  19. afInput::init(int nTypes, HINSTANCE hInst, HWND hWnd)
  20. {
  21. HRESULT hr;
  22. types = nTypes;
  23. this->hInst = hInst;
  24. this->hWnd = hWnd;
  25. afLog::info("starting directinput setup...");
  26.  
  27. keyBuffer = new unsigned char[256];
  28. oldKeyBuffer = new unsigned char[256];
  29. memset(keyBuffer, 0, 256);
  30. memset(oldKeyBuffer, 0, 256);
  31. // create the directInput object
  32. //
  33. hr = DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_pDI, NULL); 
  34. if FAILED(hr)
  35. {
  36. afLog::error("creating directinput failed");
  37. return false;
  38. }
  39. if(types&KEYBOARD)
  40. {
  41. // retrieve a pointer to an IDirectInputDevice8 keyboard interface 
  42. hr = m_pDI->CreateDevice(GUID_SysKeyboard, &m_pDIDeviceKB, NULL); 
  43. if FAILED(hr) 
  44. afLog::error("creating keyboard device failed");
  45. else
  46. {
  47.   // now that we have an IDirectInputDevice8 interface, get
  48. // it ready to use
  49.   // set the data format using the predefined keyboard data 
  50. // format provided by the DirectInput object for keyboards..
  51. //
  52. hr = m_pDIDeviceKB->SetDataFormat(&c_dfDIKeyboard); 
  53. if FAILED(hr) 
  54. afLog::error("setting keyboard data format failed");
  55. {
  56. // set the cooperative level
  57. //
  58. hr = m_pDIDeviceKB->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE); 
  59. if FAILED(hr) 
  60. afLog::error("setting direct input cooperative level failed");
  61. {
  62. // get access to the input device
  63. //
  64. hr = m_pDIDeviceKB->Acquire(); 
  65. if FAILED(hr) 
  66. afLog::error("acquiring input device failed");
  67. }
  68. }
  69. }
  70. }
  71. if(types&MOUSE)
  72. {
  73. // Obtain an interface to the system mouse device.
  74. hr = m_pDI->CreateDevice(GUID_SysMouse, &m_pDIDeviceMouse, NULL);
  75.  
  76. if (FAILED(hr))
  77. afLog::error("creating mouse device failed");
  78. else
  79. {
  80. // Set the data format to "mouse format" - a predefined data format 
  81. // This tells DirectInput that we will be passing a
  82. // DIMOUSESTATE2 structure to IDirectInputDevice::GetDeviceState.
  83. hr = m_pDIDeviceMouse->SetDataFormat(&c_dfDIMouse2);
  84.  
  85. if (FAILED(hr))
  86. afLog::error("setting mouse data format failed");
  87. else
  88. {
  89. // Set the cooperativity level to let DirectInput know how
  90. // this device should interact with the system and with other
  91. // DirectInput applications.
  92. hr = m_pDIDeviceMouse->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
  93.  
  94. if (FAILED(hr))
  95. afLog::error("setting direct input cooperative level failed");
  96. }
  97. }
  98. }
  99. afLog::info("directinput setup finished");
  100. return true;
  101. }
  102. void
  103. afInput::cleanup()
  104.     if(m_pDI) 
  105.     { 
  106.         if(m_pDIDeviceKB)
  107.         {
  108. // always unacquire devices before calling Release(). 
  109. //
  110.             m_pDIDeviceKB->Unacquire(); 
  111.             m_pDIDeviceKB->Release();
  112.             m_pDIDeviceKB = NULL; 
  113.         }
  114.         if(m_pDIDeviceMouse)
  115.         { 
  116. // always unacquire devices before calling Release(). 
  117. //
  118.             m_pDIDeviceMouse->Unacquire(); 
  119.             m_pDIDeviceMouse->Release();
  120.             m_pDIDeviceMouse= NULL; 
  121.         } 
  122.         m_pDI->Release();
  123.         m_pDI = NULL;
  124.     }
  125.     if(hMouseEvent)
  126.         CloseHandle(hMouseEvent);
  127. if(keyBuffer)
  128. {
  129. delete keyBuffer;
  130. keyBuffer = NULL;
  131. }
  132. if(oldKeyBuffer)
  133. {
  134. delete oldKeyBuffer;
  135. oldKeyBuffer = NULL;
  136. }
  137. }
  138. void
  139. afInput::update()
  140. {
  141. unsigned char* tmpBuf;
  142. HRESULT hr;
  143. // check if an init was already done
  144. if(!m_pDI)
  145. return;
  146. if(m_pDIDeviceKB)
  147. {
  148. // switch the keyboard buffers
  149. //
  150. tmpBuf = oldKeyBuffer;
  151. oldKeyBuffer = keyBuffer;
  152. keyBuffer = tmpBuf;
  153. // if GetDeviceState() fails we try to reacquire
  154. // the keyboard input device
  155. if FAILED(hr = m_pDIDeviceKB->GetDeviceState(256,(LPVOID)keyBuffer)) 
  156. hr = m_pDIDeviceKB->Acquire();
  157. while( hr == DIERR_INPUTLOST ) 
  158. hr = m_pDIDeviceKB->Acquire();
  159. memset(keyBuffer, 0, 256);
  160. }
  161. }
  162. if(m_pDIDeviceMouse)
  163. {
  164. // read mouse state
  165. //
  166. DIMOUSESTATE2 dims2;
  167. ZeroMemory(&dims2, sizeof(dims2));
  168. hr = m_pDIDeviceMouse->GetDeviceState(sizeof(DIMOUSESTATE2), &dims2);
  169. if( FAILED(hr) ) 
  170. {
  171. // if we lost the device try to reacquire it
  172. //
  173. hr = m_pDIDeviceMouse->Acquire();
  174. while(hr==DIERR_INPUTLOST) 
  175. hr = m_pDIDeviceMouse->Acquire();
  176. }
  177. else
  178. {
  179. mouseX = dims2.lX;
  180. mouseY = dims2.lY;
  181. mouseB =  (dims2.rgbButtons[0]!=0) ? BUTTON_LEFT : 0;
  182. mouseB |= (dims2.rgbButtons[2]!=0) ? BUTTON_MIDDLE : 0;
  183. mouseB |= (dims2.rgbButtons[1]!=0) ? BUTTON_RIGHT : 0;
  184. keyBuffer[KEY_MOUSE_LEFT]   = (unsigned char)((dims2.rgbButtons[0]!=0) ? 0x80 : 0);
  185. keyBuffer[KEY_MOUSE_MIDDLE] = (unsigned char)((dims2.rgbButtons[2]!=0) ? 0x80 : 0);
  186. keyBuffer[KEY_MOUSE_RIGHT]  = (unsigned char)((dims2.rgbButtons[1]!=0) ? 0x80 : 0);
  187. }
  188. }
  189. }
  190. bool
  191. afInput::isKeyDown(KEY nKey) const
  192. {
  193. int k = (int)nKey;
  194. if(k<0 || k>255)
  195. return false;
  196. return ((keyBuffer[nKey] & 0x80)!=0);
  197. }
  198. bool
  199. afInput::isKeyNewDown(KEY nKey) const
  200. {
  201. int k = (int)nKey;
  202. if(k<0 || k>255)
  203. return false;
  204. return ((keyBuffer[nKey] & 0x80)!=0) && !((oldKeyBuffer[nKey] & 0x80)!=0);
  205. }
  206. void
  207. afInput::processWindowMsg(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM)
  208. {
  209. switch(uMsg) 
  210. {
  211. // Sent when window changes active state
  212. case WM_ACTIVATE:
  213. // Set exclusive mode access to the mouse based on active state
  214. windowActive = (WA_INACTIVE == wParam);
  215. updateMouseAcquire();
  216. return;
  217. case WM_ENTERMENULOOP:
  218. case WM_ENTERSIZEMOVE:
  219. // Un-acquire device when entering menu or re-sizing
  220. // Zhis will show the mouse cursor again
  221. windowActive = false;
  222. updateMouseAcquire();
  223. return;
  224. case WM_EXITSIZEMOVE:
  225. // Re-acquire device when leaving menu or re-sizing
  226. // This will show the mouse cursor again
  227. // Even though the menu is going away, the app
  228. // might have lost focus or be an icon
  229. windowActive = (GetActiveWindow()==hWnd || !IsIconic(hWnd));
  230. updateMouseAcquire();
  231. return;
  232. case WM_SYSCOMMAND:
  233.         // The WM_SYSCOMMAND might've been a WM_CLOSE, 
  234.         // in which case our window no longer exists.  
  235.         if(IsWindow(hWnd)) 
  236.             updateMouseAcquire();
  237.         return;
  238. }
  239. }
  240. void
  241. afInput::updateMouseAcquire()
  242. {
  243. // Nothing to do if g_pMouse is NULL
  244. if(m_pDIDeviceMouse == NULL)
  245. return;
  246. if(windowActive)
  247. m_pDIDeviceMouse->Acquire();
  248. else 
  249. m_pDIDeviceMouse->Unacquire();
  250. }