/***************************************************************************/ /* Description: KeybDI.c, part of CPA INO library */ /* Keyboard specific implementation */ /* */ /* Author: F. Jentey */ /* Last Update: 05/03/97 */ /* 30/07/97 Direct Input */ /***************************************************************************/ #include #include "INO\errINO.h" #include "InitDI.h" #include "INOInit.h" #include "Keyboard.h" /************************************************************************** Globale vars ***************************************************************************/ /* Keyboard config variables : get the country keyboard config */ char INO_LayoutName[KL_NAMELENGTH]; HKL INO_LayoutHandle; /* Table for virtual key code use for ASCII conversion */ /* INO_acDikToVirtual is used for the numeric pad, coz */ /* MapVirtualKeyEx() doesn't Verr Num state. */ BYTE INO_acVirtualKeyCodeTab[256]; BYTE INO_acDikToVirtual[256]; /* Store the key use in the game */ unsigned short INO_ActiveKey[128]; unsigned short INO_ActiveKeyNumber; /**********************************************************************************/ /* This fonction returns the ASCII code corresponding to a key code if this key */ /* is printable. */ /**********************************************************************************/ short INO_fn_wDikToAscii(short wKeyCode, INO_tdhDevice hDev) { unsigned long VirtualKeyCode; long iResult; unsigned short a_uwASCIICode[2]; /* Get the VirtualKey code of the key */ /* We suppose all DIK code correspond to scan code. */ /* For numeric pad key, use the dik to virtual key */ /* code translation table. */ if ( (((wKeyCode>0x46) && (wKeyCode<0x54)) || (wKeyCode==0xb5)) && (GetKeyState(VK_NUMLOCK) & INO_C_ucKeyToggled) ) VirtualKeyCode = INO_acDikToVirtual[wKeyCode]; else VirtualKeyCode = MapVirtualKeyEx(wKeyCode, 1, INO_LayoutHandle); /* La fameuse modif qui tue - Elie */ if ( (VirtualKeyCode == 0) || (VirtualKeyCode == VK_CAPITAL) || (VirtualKeyCode == VK_SCROLL) || (VirtualKeyCode == VK_NUMLOCK) || (VirtualKeyCode == VK_SHIFT) || (VirtualKeyCode == VK_CONTROL) || (VirtualKeyCode == VK_MENU) || ((VirtualKeyCode >= VK_F1) && (VirtualKeyCode<=VK_F24)) ) return (0); /* Fill the INO_acVirtualKeyCodeTab array with SHIFT, ALT and CTRL state */ INO_acVirtualKeyCodeTab[VK_SHIFT] = INO_C_ucKeyDown & ( M_KeyState(hDev,C_ucKey_LSHIFT) | M_KeyState(hDev,C_ucKey_RSHIFT) ); INO_acVirtualKeyCodeTab[VK_CONTROL] = INO_C_ucKeyDown & ( M_KeyState(hDev,C_ucKey_LCTRL) | M_KeyState(hDev,C_ucKey_RCTRL) ); INO_acVirtualKeyCodeTab[VK_MENU] = INO_C_ucKeyDown & ( M_KeyState(hDev,C_ucKey_LALT) | M_KeyState(hDev,C_ucKey_RALT) ); INO_acVirtualKeyCodeTab[VK_CAPITAL] = GetKeyState(VK_CAPITAL) & INO_C_ucKeyToggled; /* Deuxieme modif qui tue - Elie */ /* INO_acVirtualKeyCodeTab[VK_NUMLOCK] = GetKeyState(VK_NUMLOCK) & INO_C_ucKeyToggled;*/ iResult = ToAsciiEx(VirtualKeyCode, wKeyCode, INO_acVirtualKeyCodeTab, a_uwASCIICode,0 , INO_LayoutHandle); switch (iResult) { case 0: return (0); case 1: iResult = (int)(a_uwASCIICode[0] & 0xFF); /*if (!isprint(iResult) /*&& iswprint(iResult) ) */ /* return (0);*/ break; case 2: return (0); } return ((short)iResult); } /* Remove an active key. An error occurs when the specified key isn't */ /* active.By default, all keys are active, but you can remove some keys */ /* if they aren't used to speed up the fn_wKbRead function. */ short INO_fn_wRemoveActiveKey(short wKeyCode) { short i,j; for (i=0 ;i 127) { /* TO DO: error message */ return (0); } /* Test if key is already active */ for (i=0 ;im_p_stCaps))->m_wIsAzerty = 1; else ((INO_tdstKeyboardCaps*)(hDev->m_p_stCaps))->m_wIsAzerty = 0; return (1); } /* This function must be called at regular interval, for example each VBL. */ /* It Update the informations about the keyboard. */ short INO_fn_wReadKeyboard(INO_tdhDevice hDev) { HRESULT DInputErr; unsigned short i, j; short DownKey[INO_C_wMaxKeyDown]; short DownKeyNumber; short LastKeyHasChanged, StateHasChanged; short wDev; INO_tdstKeyboardState *p_stState = M_KState(hDev); INO_tdstKeyboardRecord *p_stH = (INO_tdstKeyboardRecord*)hDev->m_pvHistoric; unsigned char *p_ucCurrentTab, *p_ucPrevTab; if (!INO_M_bIsConnected(hDev)) return (0); for (wDev=0; wDevm_ulLastTimeCount++; /* Flip the keyboard state buffer */ p_stState->m_wCurrentTab = 1 - p_stState->m_wCurrentTab; p_ucCurrentTab = p_stState->m_a_ucTabKey[p_stState->m_wCurrentTab]; p_ucPrevTab = p_stState->m_a_ucTabKey[1-p_stState->m_wCurrentTab]; /* Try to acquire the keyboard if not done */ if (!(p_stState->m_ucStatus & INO_C_ucAcquired) || (p_stState->m_ucStatus & INO_C_ucAccessError) ) { DInputErr = M_DIAcquire(wDev); switch (DInputErr) { case DI_OK: case S_FALSE: hDev->m_p_stState->m_ucStatus |= INO_C_ucAcquired; hDev->m_p_stState->m_ucStatus &= ~INO_C_ucAccessError; break; case DIERR_INPUTLOST: case DIERR_NOTACQUIRED: case DIERR_OTHERAPPHASPRIO: return (0); default: hDev->m_p_stState->m_ucStatus &= ~INO_C_ucAcquired; hDev->m_p_stState->m_ucStatus |= INO_C_ucAccessError; INO_fn_vUpdateLastError(E_uwINO_DirectInputError); return (0); } } /* Read all key */ DInputErr = M_DIGetState(wDev, sizeof(BYTE)*256, p_ucCurrentTab); switch (DInputErr) { case DI_OK: case E_PENDING: break; case DIERR_INPUTLOST: case DIERR_NOTACQUIRED: hDev->m_p_stState->m_ucStatus &= ~INO_C_ucAcquired; return (0); default: INO_fn_vUpdateLastError(E_uwINO_DirectInputError); hDev->m_p_stState->m_ucStatus |= INO_C_ucAccessError; hDev->m_p_stState->m_ucStatus &= ~INO_C_ucAcquired; return (0); } /* Check if the keyboard state has changed by comparing the current buffer with */ /* the previous one. Store the key code of the down key in the local tab */ /* ChangedKey. */ StateHasChanged = 0; LastKeyHasChanged = 0; DownKeyNumber = 0; for (i=0 ; im_wLastKey = j; } } if ((DownKeyNumber < INO_C_wMaxKeyDown) && p_ucCurrentTab[j]) DownKey[DownKeyNumber++] = j; } if (LastKeyHasChanged) { /* Update last ASCII code */ p_stState->m_wLastASCII = INO_fn_wDikToAscii(p_stState->m_wLastKey,hDev); /* Update the current string */ if (p_stState->m_wLastASCII) { if (p_stState->m_wCurrentStringLength == INO_C_wStringMaxLength) { for (i=0; im_szCurrentString[i] = p_stState->m_szCurrentString[i+1]; p_stState->m_szCurrentString[INO_C_wStringMaxLength-1] = (char)p_stState->m_wLastASCII; } else { p_stState->m_szCurrentString[p_stState->m_wCurrentStringLength] = (char)p_stState->m_wLastASCII; p_stState->m_wCurrentStringLength++; } } } else p_stState->m_wLastASCII = 0; /* Update historic. */ /* Test if it's the first call of the fn_wJKbReadKeyboard */ if (hDev->m_wRecordNumber == 0) { p_stH[0].m_ulDate = hDev->m_ulLastTimeCount; p_stH[0].m_wNbKeyDown = 0; hDev->m_wRecordNumber = 1; StateHasChanged = 0; } /* If not, update the historic if keyboard state has changed */ else { if (StateHasChanged) { hDev->m_wHistoricHead++; if (hDev->m_wHistoricHead == hDev->m_wHistoricSize) hDev->m_wHistoricHead = 0; if (hDev->m_wRecordNumber != hDev->m_wHistoricSize) hDev->m_wRecordNumber++; p_stH[hDev->m_wHistoricHead].m_ulDate = hDev->m_ulLastTimeCount; p_stH[hDev->m_wHistoricHead].m_wNbKeyDown = 0; for (i=0; im_wHistoricHead].m_wKeyDown[i] = DownKey[i]; p_stH[hDev->m_wHistoricHead].m_wNbKeyDown = DownKeyNumber; } } p_stState->m_wStateHasChanged = StateHasChanged; return (1); } /* This function return C_wKbTrue if the selected key was down in the specified previous state. */ short INO_fn_bKeyWasDown(INO_tdhDevice hDev, short wKeyCode, short wHistoricIndex) { long index, i; INO_tdstKeyboardRecord *p_stState; if (wHistoricIndex > hDev->m_wHistoricSize-1) return (0); else { index = (hDev->m_wHistoricHead - wHistoricIndex + hDev->m_wHistoricSize) % hDev->m_wHistoricSize; p_stState = &((INO_tdstKeyboardRecord*)(hDev->m_pvHistoric))[index]; for (i=0 ; im_wNbKeyDown; i++ ) if (p_stState->m_wKeyDown[i] == wKeyCode ) return (1); } return (0); } short INO_fn_wCheckCheatCode(INO_tdhDevice hDev,char *p_szTestString) { short l; char *p_szCurrentS; INO_tdstKeyboardState *p_stState = (INO_tdstKeyboardState*)(hDev->m_p_stState); l = strlen(p_szTestString); if (l > INO_C_wStringMaxLength) return (0); if (l > p_stState->m_wCurrentStringLength) return (0); p_szCurrentS = &p_stState->m_szCurrentString[p_stState->m_wCurrentStringLength-l]; return (strcmp(p_szCurrentS,p_szTestString) == 0); }