home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 June / PCFJune.iso / Xenon / XenonSource.exe / gamesystem / source / gs_keyboard.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-12  |  8.8 KB  |  305 lines

  1. //-------------------------------------------------------------
  2. //
  3. // Class:    gsCKeyboard
  4. //
  5. // Author:    John M Phillips
  6. //
  7. // Started:    12/03/00
  8. //
  9. // Base:    gsCInput
  10. //
  11. // Derived:    None
  12. //
  13. //-------------------------------------------------------------
  14.  
  15. #include "gamesystem.h"
  16.  
  17. //-------------------------------------------------------------
  18.  
  19. gsLPDIRECTINPUTDEVICE gsCKeyboard::m_keyboard_device = 0;
  20.  
  21. //-------------------------------------------------------------
  22.  
  23. char gsCKeyboard::keycode_to_lower[gsKEYBOARD_KEYCODES] = {
  24.       0, 27,'1','2','3','4','5','6','7','8','9','0','-','=',  9,  8,
  25.     'q','w','e','r','t','y','u','i','o','p','[',']', 13,  0,'a','s',
  26.     'd','f','g','h','j','k','l',';','\'','`',  0,'\\','z','x','c','v',
  27.     'b','n','m',',','.','/',    0,'*',  0,' ',  0,  0,  0,  0,  0,  0,
  28.       0,  0,  0,  0,  0,  0,  0,'7','8','9','-','4','5','6','+','1',
  29.     '2','3','0','.',  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  30.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  31.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  32.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  33.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 13,  0,  0,  0,
  34.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  35.       0,  0,  0,  0,  0,'/',  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  36.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  37.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  38.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  39.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
  40. };
  41.  
  42. char gsCKeyboard::keycode_to_upper[gsKEYBOARD_KEYCODES] = {
  43.       0, 27,'!','"','ú','$','%','^','&','*','(',')','_','+',  9,  8,
  44.     'Q','W','E','R','T','Y','U','I','O','P','{','}', 13,  0,'A','S',
  45.     'D','F','G','H','J','K','L',':','@','¼',  0,'|','Z','X','C','V',
  46.     'B','N','M','<','>','?',  0,'*',  0,' ',  0,  0,  0,  0,  0,  0,
  47.       0,  0,  0,  0,  0,  0,  0,'7','8','9','-','4','5','6','+','1',
  48.     '2','3','0','.',  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  49.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  50.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  51.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  52.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 13,  0,  0,  0,
  53.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  54.       0,  0,  0,  0,  0,'/',  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  55.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  56.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  57.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  58.       0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
  59. };
  60.  
  61. //-------------------------------------------------------------
  62.  
  63. const char *gsCKeyboard::keycode_description[gsKEYBOARD_KEYCODES] = {
  64.     0,"Escape","1","2","3","4","5","6","7","8","9","0","-","=","Backspace","Tab",
  65.     "Q","W","E","R","T","Y","U","I","O","P","(",")","Return","Left Control","A","S",
  66.     "D","F","G","H","J","K","L",";","'","`","Left Shift","\\","Z","X","C","V",
  67.     "B","N","M",",",".","/","Right Shift","Num pad *","Alt","Space","Caps Lock","F1","F2","F3","F4","F5",
  68.     "F6","F7","F8","F9","F10","Num Lock","Scroll Lock","Num pad 7",
  69.     "Num pad 8","Num pad 9","Num pad -","Num pad 4","Num pad 5","Num pad 6","Num pad +","Num pad 1",
  70.     "Num pad 2","Num pad 3","Num pad 0","Num pad .","???","F11","F12",0,0,0,0,0,0,0,
  71.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  72.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  73.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  74.     0,0,0,0,0,0,0,0,0,0,"Enter","Right Control",0,0,
  75.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  76.     0,0,0,0,0,"/",0,"SysRq","Right Alt",0,0,0,0,0,0,0,
  77.     0,0,0,0,0,"Pause",0,"Home","Up","Page Up","Left","Right",0,"End",
  78.     "Down","Page Down","Insert","Delete",0,0,0,0,0,0,0,0,0,0,0,0,
  79.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  80.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  81. };
  82.  
  83. //-------------------------------------------------------------
  84.  
  85. gsCKeyboard::gsCKeyboard()
  86. {
  87.     for (int i = 0; i < gsKEYBOARD_KEYCODES; i++) {
  88.         m_previous_key_states[i] = 0;
  89.         m_new_key_states[i] = 0;
  90.         m_key_states[i] = 0;
  91.         }
  92.  
  93.     flush();
  94. }
  95.  
  96. //-------------------------------------------------------------
  97.  
  98. gsCKeyboard::~gsCKeyboard()
  99. {
  100.     destroy();
  101. }
  102.  
  103. //-------------------------------------------------------------
  104.  
  105. void gsCKeyboard::flush()
  106. {
  107.     m_key_buffer.clear();
  108. }
  109.  
  110. //-------------------------------------------------------------
  111.  
  112. bool gsCKeyboard::create()
  113. {
  114.     if (!m_direct_input) {
  115.         gsREPORT("gsCKeyboard::create called with no direct input device");
  116.         return false;
  117.         }
  118.  
  119.     if (m_keyboard_device)
  120.         return true;
  121.  
  122.     HRESULT hr;
  123.  
  124. #ifdef gsDIRECTX_NT_COMPATIBLE
  125.  
  126.     hr = m_direct_input->CreateDevice(GUID_SysKeyboard,
  127.                                       &m_keyboard_device,
  128.                                       NULL);
  129.  
  130. #else
  131.  
  132.     hr = m_direct_input->CreateDeviceEx(GUID_SysKeyboard,
  133.                                         gsID_DIRECTINPUTDEVICE,
  134.                                         (void **) &m_keyboard_device,
  135.                                         NULL);
  136. #endif
  137.  
  138.     if (hr != DI_OK) {
  139.         gsREPORT("gsCKeyboard::create couldn't create device");
  140.         return false;
  141.         }
  142.     
  143.     hr = m_keyboard_device->SetDataFormat(&c_dfDIKeyboard);
  144.  
  145.     if (hr != DI_OK) {
  146.         gsREPORT("gsCKeyboard::create couldn't set data format");
  147.         return false;
  148.         }
  149.  
  150.     hr = m_keyboard_device->SetCooperativeLevel(gsCApplication::getWindow(),
  151.                                                 DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
  152.  
  153.     if (hr != DI_OK) {
  154.         gsREPORT("gsCKeyboard::create couldn't set co-op level");
  155.         return false;
  156.         }
  157.  
  158.     m_active_inputs.addItem(this);
  159.  
  160.     gsREPORT("gsCKeyboard device created");
  161.  
  162.     return true;
  163. }
  164.  
  165. //-------------------------------------------------------------
  166.  
  167. bool gsCKeyboard::destroy()
  168. {
  169.     if (m_keyboard_device) {
  170.  
  171.         m_active_inputs.removeItem(this);
  172.         
  173.         m_keyboard_device->Unacquire();
  174.         m_keyboard_device->Release();
  175.         m_keyboard_device = 0;
  176.  
  177.         gsREPORT("gsCKeyboard device destroyed");
  178.         }
  179.  
  180.     return true;
  181. }
  182.  
  183. //-------------------------------------------------------------
  184.  
  185. bool gsCKeyboard::acquire()
  186. {
  187.     if (!m_keyboard_device) {
  188.         gsREPORT("gsCKeyboard::acquire called with no keyboard device");
  189.         return false;
  190.         }
  191.     
  192.     HRESULT hr;
  193.     
  194.     if (gsCApplication::isActive()) {
  195.         hr = m_keyboard_device->Acquire();
  196.  
  197.         if (hr != DI_OK) {
  198.             gsREPORT("gsCKeyboard::acquire failed");
  199.             return false;
  200.             }
  201.         }
  202.     else {
  203.         hr = m_keyboard_device->Unacquire();
  204.  
  205.         if (hr != DI_OK) {
  206.             gsREPORT("gsCKeyboard::acquire unacquire failed");
  207.             return false;
  208.             }
  209.         }
  210.  
  211.     return true;
  212. }
  213.  
  214. //-------------------------------------------------------------
  215.  
  216. bool gsCKeyboard::update()
  217. {
  218.     if (m_keyboard_device) {
  219.         HRESULT hr = DIERR_INPUTLOST;
  220.  
  221.         memcpy(m_previous_key_states,m_new_key_states,gsKEYBOARD_KEYCODES);
  222.  
  223.         while (hr == DIERR_INPUTLOST) {
  224.             hr = m_keyboard_device->GetDeviceState(gsKEYBOARD_KEYCODES,&m_new_key_states);
  225.             
  226.             if (hr == DIERR_INPUTLOST) {
  227.                 gsREPORT("gsCKeyboard::update input lost");
  228.                 hr = m_keyboard_device->Acquire();
  229.                 if (hr != DI_OK) {
  230.                     gsREPORT("gsCKeyboard::update couldn't acquire device");
  231.                     return false;
  232.                     }
  233.                 }
  234.             }
  235.  
  236.         if (hr != DI_OK) {
  237.             gsREPORT("gsCKeyboard::update couldn't get device state");
  238.             return false;
  239.             }
  240.         }
  241.  
  242.     for (int i = 0; i < gsKEYBOARD_KEYCODES; i++) {
  243.         bool p = (m_previous_key_states[i] & 0x80) != 0;
  244.         bool n = (m_new_key_states[i] & 0x80) != 0;
  245.         m_key_states[i] = (gsUBYTE) ((n ? gsKEY_STATE : 0) |
  246.                                      ((n && !p) ? gsKEY_PRESSED : 0) |
  247.                                      ((!n && p) ? gsKEY_RELEASED : 0));
  248.  
  249.         if (n && !p && m_key_buffer.getSize() < gsKEYBOARD_BUFFER_SIZE) {
  250.             m_key_buffer.addItem((gsKeyCode) i);
  251.             }
  252.         }
  253.  
  254.     return true;
  255. }
  256.  
  257. //-------------------------------------------------------------
  258.  
  259. bool gsCKeyboard::isActive()
  260. {
  261.     return m_keyboard_device != 0;
  262. }
  263.  
  264. //-------------------------------------------------------------
  265.  
  266. bool gsCKeyboard::testKey(gsKeyCode keycode,gsKeyState state)
  267. {
  268.     if (m_keyboard_device)
  269.         return (m_key_states[keycode] & state) != 0;
  270.     else {
  271.         gsREPORT("gsCKeyboard::testKey called with no keyboard device");
  272.         return false;
  273.         }
  274. }
  275.  
  276. //-------------------------------------------------------------
  277.  
  278. gsKeyCode gsCKeyboard::getKey()
  279. {
  280.     gsKeyCode k = gsKEY_NONE;
  281.  
  282.     if (!m_key_buffer.isEmpty()) {
  283.         k = m_key_buffer[0];
  284.         m_key_buffer.removeIndex(0);
  285.         }
  286.  
  287.     return k;
  288. }
  289.  
  290. //-------------------------------------------------------------
  291.  
  292. char gsCKeyboard::keyCodeToAscii(gsKeyCode keycode)
  293. {
  294.     return keycode_to_lower[(int) keycode];
  295. }
  296.  
  297. //-------------------------------------------------------------
  298.  
  299. const char *gsCKeyboard::keyCodeToDescription(gsKeyCode keycode)
  300. {
  301.     return keycode_description[keycode];
  302. }
  303.  
  304. //-------------------------------------------------------------
  305.