reman3/Rayman_X/cpa/tempgrp/INO/Specif/Keyboard.c

1247 lines
35 KiB
C
Raw Blame History

/***************************************************************************/
/* Description: Keyboard.c Part of CPA INO */
/* */
/* Author: F. Jentey */
/* Last Update: 05/03/97 */
/* 30/07/97 Direct Input */
/***************************************************************************/
#include <locale.h>
#include "INOInit.h"
#include "Keyboard.h"
#define C_wMaxSimultanousKey 10
#define C_wDemoSize 5000
/* Define the executing mode */
#define C_wKbNormalMode 0
#define C_wKbDemoPlayingMode 1
#define C_wKbDemoRecordingMode 2
#define C_ucKeyToggled 0x01
/******************************************************************************
tdsKbHistoryRecord : keyboard history information record
We suppose that there can't have more than 10 pressed keys simultanously.
******************************************************************************/
typedef struct _td_stKbHistoryRecord
{
short m_wKeyCode[C_wMaxSimultanousKey];
u_long m_ulRecordTimeCount;
u_short m_uwKeyPressedNumber;
} td_stKbHistoryRecord;
typedef struct _td_stKbDemoRecord
{
short m_wPressedKeyCount;
short m_wPressedKeyTab[C_wMaxSimultanousKey];
} td_stKbDemoRecord;
/**************************************************************************
Globale vars
***************************************************************************/
/* Keyboard device interface*/
LPDIRECTINPUTDEVICE INO_g_p_stKeyboardInterface;
short INO_g_wKeyboardAcquired = 0;
/* Keyboard config variables : get the country keyboard config */
char KbLib_LayoutName[KL_NAMELENGTH];
HKL KbLib_LayoutHandle;
/* Buffers for the keyboard state */
BYTE KbLib_acTabKey[2][256];
u_short KbLib_uwCurrentTab;
/* Table for virtual key code use for ASCII conversion */
/* KbLib_acDikToVirtual is used for the numeric pad, coz */
/* MapVirtualKeyEx() doesn't Verr Num state. */
BYTE KbLib_acVirtualKeyCodeTab[256];
BYTE KbLib_acDikToVirtual[256];
/* Store the key use in the game */
u_short ActiveKey[128];
u_short ActiveKeyNumber;
/* Variable to handle the history */
td_stKbHistoryRecord KbLib_H[16];
u_short KbLib_uwHSize;
u_short KbLib_uwHHead;
u_short KbLib_uwHValidEntries;
u_short KbLib_uwKbOk = 0;
/* Info variables */
u_long KbLib_ulCounter;
short KbLib_wLastKey;
short KbLib_wLastASCII;
short StateHasChanged;
char CurrentString[20];
short CurrentStringLength;
u_long ulKbErrorCode;
/* Demo mode support */
short KbLib_wCurrentMode;
short KbDemoRecordCount, KbDemoRecordCurrent;
td_stKbDemoRecord KbDemoRecordTab[C_wDemoSize];
FILE *KbDataDemoFile;
short ExitDemoKeyTab[16];
short ExitDemoKeyCount;
char KbDemoFileHeader[] = "KeyboardSequence";
char KbErrorString[10][100] =
{
"You must initialize the keyboard.lib first, see fn_wKbInitKeyboard.",
"Wrong key code.",
"This function can only be called in demo recording mode.",
"You are currently in demo recording or playing mode.",
"This function can only be called in demo playing mode.",
"Unrecognize file format.",
"The function can't open or read the demo file.",
"The index in the historic tab is out of range.",
"The application has lost the input focus.",
"Direct input error."
};
char g_cIsAzerty;
/*********************************************************************
INITIALISATION
*********************************************************************/
/*
This function must be called one time when the game is launched. The
parameter HistorySize is the number of previous status conserve.
*/
short fn_wKbASCIICode(short wKeyCode);
short INO_fn_wInitKeyboard(short wHistorySize, HINSTANCE hInstance, HWND hWindow)
{
#ifdef INO_USE_DIRECT_INPUT
GUID guid = GUID_SysKeyboard;
HRESULT DInputErr;
#endif
u_short i;
short wASCIIForKeyA;
if (KbLib_uwKbOk == 1) return (0);
/*===================================*/
/*============= DInput ==============*/
#ifdef INO_USE_DIRECT_INPUT
if (!INO_fn_wInitDirectInput(hInstance,hWindow)) return(C_wKbError);
DInputErr = INO_g_p_stDInputInterface->lpVtbl->CreateDevice(
INO_g_p_stDInputInterface,
&guid,
&INO_g_p_stKeyboardInterface,
NULL
);
switch (DInputErr)
{
case DI_OK:
break;
case DIERR_INVALIDPARAM:
case DIERR_OUTOFMEMORY:
case DIERR_NOINTERFACE:
case DIERR_DEVICENOTREG:
INO_fn_vReleaseDirectInput();
return(C_wKbError);
}
/* Make sure the keyboard noit acquire before calling setDataFormat and */
/* SetCooperativeLevel. Return always OK */
DInputErr = INO_g_p_stKeyboardInterface->lpVtbl->Unacquire(INO_g_p_stKeyboardInterface);
INO_g_wKeyboardAcquired = 0;
/* Tell DirectInput that we want to receive data in keyboard format */
DInputErr = INO_g_p_stKeyboardInterface->lpVtbl->SetDataFormat(
INO_g_p_stKeyboardInterface,
&c_dfDIKeyboard
);
switch (DInputErr)
{
case DI_OK:
break;
case DIERR_INVALIDPARAM:
case DIERR_ACQUIRED:
INO_g_p_stKeyboardInterface->lpVtbl->Release(INO_g_p_stKeyboardInterface);
INO_fn_vReleaseDirectInput();
return(C_wKbError);
break;
}
/* Set cooperative level */
DInputErr = INO_g_p_stKeyboardInterface->lpVtbl->SetCooperativeLevel(
INO_g_p_stKeyboardInterface,
hWindow,
DISCL_NONEXCLUSIVE | DISCL_FOREGROUND
);
switch (DInputErr)
{
case DI_OK:
break;
case DIERR_INVALIDPARAM:
INO_g_p_stKeyboardInterface->lpVtbl->Release(INO_g_p_stKeyboardInterface);
INO_fn_vReleaseDirectInput();
return(C_wKbError);
}
/* Try to acquire the keyboard */
DInputErr = INO_g_p_stKeyboardInterface->lpVtbl->Acquire(INO_g_p_stKeyboardInterface);
switch (DInputErr)
{
case DI_OK:
case S_FALSE: /* Already acquired, OK */
INO_g_wKeyboardAcquired = 1;
break;
case DIERR_INPUTLOST:
INO_g_wKeyboardAcquired = 0;
break;
case DIERR_INVALIDPARAM:
INO_g_wKeyboardAcquired = 0;
INO_g_p_stKeyboardInterface->lpVtbl->Release(INO_g_p_stKeyboardInterface);
INO_fn_vReleaseDirectInput();
return(C_wKbError);
}
#else
/*===================================*/
/*========= Without DInput ==========*/
INO_g_wKeyboardAcquired = 1;
#endif
/*===================================*/
/*===================================*/
memset(KbLib_H,0,sizeof(td_stKbHistoryRecord)*16);
memset(KbLib_acTabKey,0,sizeof(BYTE)*256*2);
memset(ActiveKey,0,sizeof(u_short)*128);
memset(CurrentString,0,17);
KbLib_uwHHead = 0;
KbLib_uwHSize = 16; /* wHistorySize */
KbLib_uwHValidEntries = 0;
KbLib_ulCounter = 0;
ActiveKeyNumber = 0;
KbLib_uwCurrentTab = 0;
/* For ASCII conversion */
GetKeyboardLayoutName(KbLib_LayoutName);
KbLib_LayoutHandle = LoadKeyboardLayout(KbLib_LayoutName,KLF_ACTIVATE);
/* Keyboard OK */
KbLib_uwKbOk = 1;
/* Set the default active Key (All keys) */
for ( i=0x01 ; i<0x58 ; i++ ) INO_fn_wAddActiveKey(i);
INO_fn_wAddActiveKey(0x69); /* Pause */
INO_fn_wAddActiveKey(0x9c);
INO_fn_wAddActiveKey(0x9d);
INO_fn_wAddActiveKey(0xb5);
INO_fn_wAddActiveKey(0xb7);
INO_fn_wAddActiveKey(0xb8);
INO_fn_wAddActiveKey(0xc7);
INO_fn_wAddActiveKey(0xc5); /* Num Lock */
INO_fn_wAddActiveKey(0xc8);
INO_fn_wAddActiveKey(0xc9);
INO_fn_wAddActiveKey(0xcb);
INO_fn_wAddActiveKey(0xcd);
INO_fn_wAddActiveKey(0xcf);
INO_fn_wAddActiveKey(0xd0);
INO_fn_wAddActiveKey(0xd1);
INO_fn_wAddActiveKey(0xd2);
INO_fn_wAddActiveKey(0xd3);
INO_fn_wAddActiveKey(0xdb);
INO_fn_wAddActiveKey(0xdc);
INO_fn_wAddActiveKey(0xdd);
/* Fill the Dik to Virtual key code translation table */
/* for numeric pad (Vk when Verr Num is ON) */
KbLib_acDikToVirtual[C_ucKey_PAD_0] = VK_NUMPAD0;
KbLib_acDikToVirtual[C_ucKey_PAD_1] = VK_NUMPAD1;
KbLib_acDikToVirtual[C_ucKey_PAD_2] = VK_NUMPAD2;
KbLib_acDikToVirtual[C_ucKey_PAD_3] = VK_NUMPAD3;
KbLib_acDikToVirtual[C_ucKey_PAD_4] = VK_NUMPAD4;
KbLib_acDikToVirtual[C_ucKey_PAD_5] = VK_NUMPAD5;
KbLib_acDikToVirtual[C_ucKey_PAD_6] = VK_NUMPAD6;
KbLib_acDikToVirtual[C_ucKey_PAD_7] = VK_NUMPAD7;
KbLib_acDikToVirtual[C_ucKey_PAD_8] = VK_NUMPAD8;
KbLib_acDikToVirtual[C_ucKey_PAD_9] = VK_NUMPAD9;
KbLib_acDikToVirtual[C_ucKey_PAD_DIV] = VK_DIVIDE;
KbLib_acDikToVirtual[C_ucKey_PAD_MUL] = VK_MULTIPLY;
KbLib_acDikToVirtual[C_ucKey_PAD_SUB] = VK_SUBTRACT;
KbLib_acDikToVirtual[C_ucKey_PAD_ADD] = VK_ADD;
KbLib_acDikToVirtual[C_ucKey_PAD_POINT] = VK_DECIMAL;
/*===================================*/
/*========= Without DInput ==========*/
#ifndef INO_USE_DIRECT_INPUT
for (i=0; i<ActiveKeyNumber; i++)
{
if ( ((ActiveKey[i]<0x47) || (ActiveKey[i]>0x53)) && (ActiveKey[i]!=0xb5) )
KbLib_acDikToVirtual[ActiveKey[i]] = MapVirtualKeyEx(ActiveKey[i], 1, KbLib_LayoutHandle);
}
KbLib_acDikToVirtual[C_ucKey_UP] = VK_UP;
KbLib_acDikToVirtual[C_ucKey_DOWN] = VK_DOWN;
KbLib_acDikToVirtual[C_ucKey_LEFT] = VK_LEFT;
KbLib_acDikToVirtual[C_ucKey_RIGHT] = VK_RIGHT;
KbLib_acDikToVirtual[C_ucKey_INS] = VK_INSERT;
KbLib_acDikToVirtual[C_ucKey_DEL] = VK_DELETE;
KbLib_acDikToVirtual[C_ucKey_HOME] = VK_HOME;
KbLib_acDikToVirtual[C_ucKey_END] = VK_END;
KbLib_acDikToVirtual[C_ucKey_PRIOR] = VK_PRIOR;
KbLib_acDikToVirtual[C_ucKey_NEXT] = VK_NEXT;
#endif
/*===================================*/
/*===================================*/
/* Demo mode initialization */
KbLib_wCurrentMode = C_wKbNormalMode;
ExitDemoKeyCount = 1;
fn_wKbAddExitDemoKey(C_ucKey_ESC);
CurrentStringLength = 0;
/* Find keyboard type (Azerty / Qwerty) */
/* wASCIIForKeyA = INO_fn_wDikToAscii(C_ucKey_A,hDev) & 0xFF;*/
wASCIIForKeyA = fn_wKbASCIICode( C_ucKey_A )& 0xFF;
if ((wASCIIForKeyA == 'a') || (wASCIIForKeyA == 'A'))
g_cIsAzerty = 1;
else
g_cIsAzerty = 0;
return (0);
}
/*
Reinitialization of the keyboard. The history is clear.
*/
short INO_fn_wResetKeyboard(void)
{
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
/* TO DO */
return (0);
}
/*
This function free memory and release keyboard ressource.
*/
short INO_fn_wFreeKeyboard(void)
{
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
/*===================================*/
/*============= DInput ==============*/
#ifdef INO_USE_DIRECT_INPUT
if (INO_g_wKeyboardAcquired)
INO_g_p_stKeyboardInterface->lpVtbl->Unacquire(INO_g_p_stKeyboardInterface);
INO_g_p_stKeyboardInterface->lpVtbl->Release(INO_g_p_stKeyboardInterface);
INO_fn_vReleaseDirectInput();
#endif
/*===================================*/
/*===================================*/
INO_g_wKeyboardAcquired = 0;
KbLib_uwKbOk = 0;
return (0);
}
/*
This function returns the number of keys of the keyboard.
*/
short INO_fn_wGetNumberOfKey()
{
int result;
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
result = GetKeyboardType(0);
switch(result)
{
case 1: /* IBM<42> PC/XT<58> ( ) or compatible (83-key) keyboard */
return(83);
case 2: /* Olivetti<74> "ICO" (102-key) keyboard */
return(102);
case 3: /* IBM PC/AT<41> (84-key) or similar keyboard */
return(84);
case 4: /* IBM enhanced (101- or 102-key) keyboard */
return(102);
}
/* TO DO: error message */
return (C_wKbError);
}
/********************************************************************
Configuration functions
********************************************************************/
/*
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)
{
u_short i, j;
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
for ( i=0 ; i <ActiveKeyNumber ; i++ )
{
if ( ActiveKey[i] == wKeyCode )
{
for ( j=i+1 ; j < ActiveKeyNumber ; j++ )
ActiveKey[j-1] = ActiveKey[j];
ActiveKeyNumber--;
return (0);
}
}
return (C_wKbError);
}
/*
Add a key to be managed. There is an error if the specified key is
already active.
*/
short INO_fn_wAddActiveKey( short wKeyCode )
{
u_short i;
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
if ( ActiveKeyNumber > 127 )
{
/* TO DO: error message */
return (C_wKbError);
}
/* Test if key is already active */
for ( i=0 ; i<ActiveKeyNumber ; i++ )
{
if ( ActiveKey[i] == wKeyCode )
return (0);
}
ActiveKey[ActiveKeyNumber] = wKeyCode;
ActiveKeyNumber++;
return (0);
}
/*
This function must be called at regular interval, for example each VBL.
It Update the informations about the keyboard.
*/
short INO_fn_wReadKeyboard()
{
#ifdef INO_USE_DIRECT_INPUT
HRESULT DInputErr;
#endif
u_short i, j;
short DownKey[C_wMaxSimultanousKey];
short DownKeyNumber;
short LastKeyHasChanged;
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
/* Increase the internal frame counter */
KbLib_ulCounter++;
/* Flip the keyboard state buffer */
KbLib_uwCurrentTab = 1 - KbLib_uwCurrentTab;
/* Try to acquire the keyboard if not done */
/*===================================*/
/*============= DInput ==============*/
#ifdef INO_USE_DIRECT_INPUT
if (!INO_g_wKeyboardAcquired)
{
DInputErr = INO_g_p_stKeyboardInterface->lpVtbl->Acquire(INO_g_p_stKeyboardInterface);
switch (DInputErr)
{
case DI_OK:
case S_FALSE:
INO_g_wKeyboardAcquired = 1;
break;
case DIERR_INPUTLOST:
ulKbErrorCode = C_ErrFocusLost;
return (C_wKbError);
case DIERR_INVALIDPARAM:
INO_g_wKeyboardAcquired = 0;
ulKbErrorCode = C_ErrDirectInputError;
return (C_wKbError);
default:
break;
}
}
/* Read all key */
DInputErr = INO_g_p_stKeyboardInterface->lpVtbl->GetDeviceState(
INO_g_p_stKeyboardInterface,
sizeof(BYTE)*256,
KbLib_acTabKey[KbLib_uwCurrentTab]
);
switch (DInputErr)
{
case DI_OK:
INO_g_wKeyboardAcquired = 1;
break;
case E_PENDING:
break;
case DIERR_INPUTLOST:
/*case DIERR_NOTACQUIRED:*/
INO_g_wKeyboardAcquired = 0;
ulKbErrorCode = C_ErrFocusLost;
return (C_wKbError);
case DIERR_INVALIDPARAM:
INO_g_wKeyboardAcquired = 0;
ulKbErrorCode = C_ErrDirectInputError;
return(C_wKbError);
default:
break;
}
#else
/*===================================*/
/*========= Without DInput ==========*/
for ( i=0 ; i<ActiveKeyNumber ; i++ )
{
j = KbLib_acDikToVirtual[ActiveKey[i]];
if ( (GetAsyncKeyState(j) & 0x8000) != 0 )
KbLib_acTabKey[KbLib_uwCurrentTab][ActiveKey[i]] = C_ucKeyPressed;
else
KbLib_acTabKey[KbLib_uwCurrentTab][ActiveKey[i]] = 0;
}
#endif
/*===================================*/
/*===================================*/
/* If current mode is C_wKbDemoPlayingMode, then overwrite the keyboard state tab */
if (KbLib_wCurrentMode == C_wKbDemoPlayingMode)
{
/* Sortie du mode playing par une touche du clavier ou si buffer plein */
StateHasChanged = C_wKbFalse;
for ( i=0 ; i<ActiveKeyNumber ; i++ )
{
j = ActiveKey[i];
if ( (KbLib_acTabKey[KbLib_uwCurrentTab][j] & C_ucKeyPressed) != 0 )
break;
}
if ( (KbDemoRecordCurrent >= KbDemoRecordCount) || (i < ActiveKeyNumber) )
fn_wKbExitDemoPlaying();
else
{
memset(KbLib_acTabKey[KbLib_uwCurrentTab],0,sizeof(BYTE)*256);
for ( i=0 ; i<KbDemoRecordTab[KbDemoRecordCurrent].m_wPressedKeyCount ; i++ )
KbLib_acTabKey[KbLib_uwCurrentTab][KbDemoRecordTab[KbDemoRecordCurrent].m_wPressedKeyTab[i]] = C_ucKeyPressed;
KbDemoRecordCurrent++;
}
}
/* 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 = C_wKbFalse;
LastKeyHasChanged = C_wKbFalse;
DownKeyNumber = 0;
for ( i=0 ; i<ActiveKeyNumber ; i++ )
{
j = ActiveKey[i];
if ( KbLib_acTabKey[KbLib_uwCurrentTab][j] != KbLib_acTabKey[1-KbLib_uwCurrentTab][j] )
{
StateHasChanged = C_wKbTrue;
if ( (KbLib_acTabKey[KbLib_uwCurrentTab][j] & C_ucKeyPressed) != 0 )
{
LastKeyHasChanged = C_wKbTrue;
KbLib_wLastKey = j;
}
}
if ( (DownKeyNumber < C_wMaxSimultanousKey) &&
((KbLib_acTabKey[KbLib_uwCurrentTab][j] & C_ucKeyPressed) != 0) )
{
DownKey[DownKeyNumber] = j;
DownKeyNumber++;
}
}
if ( LastKeyHasChanged == C_wKbTrue )
{
/* Update last ASCII code */
KbLib_wLastASCII = fn_wKbASCIICode(KbLib_wLastKey);
/* Update the current string */
if ( KbLib_wLastASCII != C_wKbError )
{
if ( CurrentStringLength == 16)
{
for ( i = 0 ; i < 15 ; i++ )
CurrentString[i] = CurrentString[i+1];
CurrentString[15] = (char)KbLib_wLastASCII;
}
else
{
CurrentString[CurrentStringLength] = (char)KbLib_wLastASCII;
CurrentStringLength++;
}
}
}
else
KbLib_wLastASCII = C_wKbError;
/* If current mode is C_wKbDemoRedordingMode then store info in the demo buffer */
if ( KbLib_wCurrentMode == C_wKbDemoRecordingMode )
{
/* First, test if an exit demo mode key is down */
for ( i=0 ; i<ExitDemoKeyCount ; i++ )
{
if ( (KbLib_acTabKey[KbLib_uwCurrentTab][ExitDemoKeyTab[i]] & C_ucKeyPressed) != 0 )
{
fn_wKbExitDemoRecording();
break;
}
}
if ( i == ExitDemoKeyCount )
{
KbDemoRecordTab[KbDemoRecordCount].m_wPressedKeyCount = DownKeyNumber;
for ( i=0 ; i<DownKeyNumber ; i++ )
KbDemoRecordTab[KbDemoRecordCount].m_wPressedKeyTab[i] = DownKey[i];
KbDemoRecordCount++;
}
}
/* Update history. */
/* Test if it's the first call of the fn_wJKbReadKeyboard */
if ( KbLib_uwHValidEntries == 0 )
{
KbLib_H[0].m_ulRecordTimeCount = KbLib_ulCounter;
KbLib_H[0].m_uwKeyPressedNumber = 0;
KbLib_uwHValidEntries = 1;
StateHasChanged = C_wKbFalse;
}
/* If not, update the history if keyboard state has changed */
else
{
if ( StateHasChanged == C_wKbTrue )
{
KbLib_uwHHead++;
if ( KbLib_uwHHead == KbLib_uwHSize ) KbLib_uwHHead = 0;
if ( KbLib_uwHValidEntries != KbLib_uwHSize )
KbLib_uwHValidEntries++;
KbLib_H[KbLib_uwHHead].m_ulRecordTimeCount = KbLib_ulCounter;
KbLib_H[KbLib_uwHHead].m_uwKeyPressedNumber = 0;
for ( i=0 ; i<DownKeyNumber ; i++ )
KbLib_H[KbLib_uwHHead].m_wKeyCode[i] = DownKey[i];
KbLib_H[KbLib_uwHHead].m_uwKeyPressedNumber = DownKeyNumber;
}
}
return (0);
}
/*
Retrun C_wKbTrue if the application has the keyboard focus
*/
short INO_fn_wIsKeyboardAcquired(void)
{
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
if (INO_g_wKeyboardAcquired)
return(C_wKbTrue);
else
return(C_wKbFalse);
}
/*
This function return c_wKbTrue if the keyboard state has changed since
the last
*/
short INO_fn_wKeyboardStateHasChanged(void)
{
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
return (StateHasChanged);
}
/*
Return the code of the last pressed key.
*/
short INO_fn_wGetLastKey(void)
{
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
return (KbLib_wLastKey);
}
/*
Return the ASCII code corresponding of the current keyboard state.
*/
short INO_fn_wGetLastASCIICode(void)
{
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
return (KbLib_wLastASCII);
}
/*
This function returns C_wKbTrue if the specified key is down else the result
is C_wKbFalse.
*/
short INO_fn_wKeyDown(short wKeyCode)
{
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
if ( (KbLib_acTabKey[KbLib_uwCurrentTab][wKeyCode] & C_ucKeyPressed) != 0 )
return (C_wKbTrue);
else
return (C_wKbFalse);
}
/*
This function returns C_wKbTrue if the specified key has just been pressed.
(it wasn't pressed after the previous call of fn_wKbReadKeyboard and it is
pressed after the last call of this fonction).
*/
short INO_fn_wKeyJustDown(short wKeyCode)
{
u_short PrevTab;
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
PrevTab = 1 - KbLib_uwCurrentTab;
if ( (KbLib_acTabKey[KbLib_uwCurrentTab][wKeyCode] & C_ucKeyPressed) != 0 )
{
if ( (KbLib_acTabKey[PrevTab][wKeyCode] & C_ucKeyPressed) == 0 )
return (C_wKbTrue);
}
return (C_wKbFalse);
}
/*
This function returns C_wKbTrue if the specified key has just been released.
( it was pressed after the previous call of fn_wKbReadKeyboard and it isn't
yet).
*/
short INO_fn_wKeyJustUp(short wKeyCode)
{
u_short PrevTab;
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
PrevTab = 1 - KbLib_uwCurrentTab;
if ( (KbLib_acTabKey[KbLib_uwCurrentTab][wKeyCode] & C_ucKeyPressed) == 0 )
if ( (KbLib_acTabKey[PrevTab][wKeyCode] & C_ucKeyPressed) != 0 ) return (C_wKbTrue);
return (C_wKbFalse);
}
/*
This function return C_wKbTrue if the selected key was down in the
specified previous state.
*/
short INO_fn_wKeyWasDown(short wKeyCode, short wHistoryIndex)
{
short index, i;
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
if ( wHistoryIndex > KbLib_uwHValidEntries - 1 )
{
ulKbErrorCode =C_ErrHistoricOverflow;
return (C_wKbError);
}
else
{
index = KbLib_uwHHead - wHistoryIndex;
if ( index < 0 ) index += KbLib_uwHSize;
for ( i=0 ; i<KbLib_H[index].m_uwKeyPressedNumber ; i++ )
if (KbLib_H[index].m_wKeyCode[i] == wKeyCode ) return (C_wKbTrue);
}
return (C_wKbFalse);
}
/*
If not C_wJoyError, the result is the elapsed time of inactivity
of the keyboard.
*/
short INO_fn_wGetKeyboardInactivityTime(u_long *p_ulCount)
{
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
*p_ulCount = KbLib_ulCounter - KbLib_H[KbLib_uwHHead].m_ulRecordTimeCount;
return (0);
}
/*
If not C_wJoyError, the result is the elapsed time since the
specified previous state.
*/
short INO_fn_wKbElapsedTime(short wHistoryIndex, u_long *p_ulCount)
{
short index;
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
if ( wHistoryIndex > KbLib_uwHValidEntries-1 )
{
ulKbErrorCode =C_ErrHistoricOverflow;
return (C_wKbError);
}
index = KbLib_uwHHead - wHistoryIndex;
if ( index < 0 ) index += KbLib_uwHSize;
*p_ulCount = KbLib_H[KbLib_uwHHead].m_ulRecordTimeCount - KbLib_H[index].m_ulRecordTimeCount;
return (0);
}
/*
This function compares the string pointed by the p_szTestString with the
string formed with the last pressed key.
*/
short INO_fn_wCompareWithCurrentString(char *p_szTestString)
{
short l, i;
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
l = strlen(p_szTestString);
if ( l > 16 ) return (C_wKbFalse);
if ( l > CurrentStringLength ) return (C_wKbFalse);
for ( i = 0 ; i < l ; i++ )
if ( p_szTestString[l-i-1] != CurrentString[CurrentStringLength-i-1] ) break;
if ( i == l ) return (C_wKbTrue);
return (C_wKbFalse);
}
/*
This function returns a pointer to the last error message string.
*/
short INO_fn_wGetErrorString(char **pp_szErrorString)
{
u_long i;
i = ulKbErrorCode - C_FirstErrorKeyboard;
*pp_szErrorString = KbErrorString[i];
return (0);
}
/*
This function returns a last error code.
*/
u_long INO_fn_ulGetLastErrorCode(void)
{
return(ulKbErrorCode);
}
/*********************************************************************
DEMO MODE SUPPORT FUNCTION
*********************************************************************/
/*
DEFINE THE KEYS TO STOP THE DEMO RECORDING MODE.
OF COURSE, THE DEFINE HERE SHOULDN'T BE USED IN THE GAME.
DEFAULT IS ESC.
*/
short INO_fn_wAddStopRecordingKey(short wKeyCode)
{
int i;
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
for ( i=0 ; i<ExitDemoKeyCount ; i++ )
if ( ExitDemoKeyTab[i] == wKeyCode ) break;
if ( i == ExitDemoKeyCount )
ExitDemoKeyTab[i] = wKeyCode;
ExitDemoKeyCount++;
return (0);
}
/*
REMOVE A KEY FROM THE EXIT DEMO KEY LIST.
*/
short INO_fn_wRemoveStopRecordingKey(short wKeyCode)
{
int i, j;
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
for ( i=0 ; i <ExitDemoKeyCount ; i++ )
{
if ( ExitDemoKeyTab[i] == wKeyCode )
{
for ( j=i+1 ; j < ExitDemoKeyCount ; j++ )
ExitDemoKeyTab[j-1] = ExitDemoKeyTab[j];
ExitDemoKeyCount--;
return (0);
}
}
return (0);
}
/*
STARTS THE DEMO RECORDING MODE. A FILE IS CREATE WITH THE NAME INDICATED BY
p_szFileName.
*/
short INO_fn_wStartRecordingKeyboard(char *p_szFileName)
{
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
if ( KbLib_wCurrentMode != C_wKbNormalMode )
{
ulKbErrorCode = C_ErrNotInNormalMode;
return (C_wKbError);
}
KbDataDemoFile = fopen(p_szFileName,"wb");
if ( KbDataDemoFile == NULL )
{
ulKbErrorCode = C_ErrDemoFileError;
return (C_wKbError);
}
KbDemoRecordCount = 0;
KbLib_wCurrentMode = C_wKbDemoRecordingMode;
return (0);
}
/*
Quit the demo recording mode. The data of the demo sequence are stored in the file
open in the fn_wKbStartDemoRecordMode.
*/
short INO_fn_wStopRecordingKeyboard(void)
{
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
if ( KbLib_wCurrentMode != C_wKbDemoRecordingMode )
{
ulKbErrorCode = C_ErrNotInRecordingMode;
return (C_wKbError);
}
fwrite(KbDemoFileHeader,1,16,KbDataDemoFile);
fwrite(KbDemoRecordTab,sizeof(td_stKbDemoRecord),KbDemoRecordCount,KbDataDemoFile);
fclose(KbDataDemoFile);
KbLib_wCurrentMode = C_wKbNormalMode;
return (0);
}
/*
THIS FUNCTION RETURNS THE NUMBER OF FRAME OF THE DEMO SEQUENCE.
*/
short INO_fn_wGetKeyboardDemoFrameCount(void)
{
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
return (KbDemoRecordCount);
}
/*
THIS FUNCTION START THE DEMO PLAYING MODE.
*/
short INO_fn_wStartKeyboardDemo(char *p_szFileName)
{
char header[18];
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
if ( KbLib_wCurrentMode != C_wKbNormalMode )
{
ulKbErrorCode = C_ErrNotInNormalMode;
return (C_wKbError);
}
memset(header,0,20);
KbDataDemoFile = fopen(p_szFileName,"rb");
if ( KbDataDemoFile == NULL )
{
ulKbErrorCode = C_ErrDemoFileError;
return (C_wKbError);
}
fread(header,1,16,KbDataDemoFile);
if ( strncmp(header,KbDemoFileHeader,16) != 0 )
{
ulKbErrorCode = C_ErrDemoBadFileFormat;
fclose(KbDataDemoFile);
return (C_wKbError);
}
KbDemoRecordCount = fread(KbDemoRecordTab,sizeof(td_stKbDemoRecord),C_wDemoSize,KbDataDemoFile);
if ( KbDemoRecordCount == 0 )
{
ulKbErrorCode = C_ErrDemoFileError;
KbDataDemoFile = NULL;
KbDemoRecordCount = 0;
fclose(KbDataDemoFile);
return (C_wKbError);
}
fclose(KbDataDemoFile);
KbDemoRecordCurrent = 0;
KbLib_wCurrentMode = C_wKbDemoPlayingMode;
return (0);
}
/*
THIS FUNCTION QUIT THE DEMO PLAYING MODE.
YOU QUIT THE DEMO PLAYING MODE BY CALLING THIS FUNCTION OR BY PUSHING
ANY KEY.
*/
short INO_fn_wStopKeyboardDemo(void)
{
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
if ( KbLib_wCurrentMode != C_wKbDemoPlayingMode)
{
ulKbErrorCode = C_ErrNotInPlayingMode;
return (C_wKbError);
}
KbLib_wCurrentMode = C_wKbNormalMode;
return (0);
}
/*
THIS FUNCTION RETURN THE CURRENT KEYBOARD MODE.(NORMAL, DEMO RECORDING
OR DEMO PLAYING).
*/
short INO_fn_wGetKeyboardCurrentMode(void)
{
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
return (KbLib_wCurrentMode);
}
/************************************************/
/************************************************/
/* PRIVATE FUNCTIONS */
/************************************************/
/************************************************/
/* This fonction returns the ASCII code corresponding to a key code if this key */
/* is printable. */
short fn_wKbASCIICode(short wKeyCode)
{
u_long VirtualKeyCode;
int iResult;
u_short a_ucASCIICode[2];
if (KbLib_uwKbOk == 0)
{
ulKbErrorCode = C_ErrKeyboardNotInitialized;
return (C_wKbError);
}
/* 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) & C_ucKeyToggled) )
VirtualKeyCode = KbLib_acDikToVirtual[wKeyCode];
else
VirtualKeyCode = MapVirtualKeyEx(wKeyCode, 1, KbLib_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 (C_wKbError);
/* Fill the KbLib_acVirtualKeyCodeTab array with SHIFT, ALT and CTRL state */
KbLib_acVirtualKeyCodeTab[VK_SHIFT] = C_ucKeyPressed &
( KbLib_acTabKey[KbLib_uwCurrentTab][C_ucKey_LSHIFT] |
KbLib_acTabKey[KbLib_uwCurrentTab][C_ucKey_RSHIFT] );
KbLib_acVirtualKeyCodeTab[VK_CONTROL] = C_ucKeyPressed &
( KbLib_acTabKey[KbLib_uwCurrentTab][C_ucKey_LCTRL] |
KbLib_acTabKey[KbLib_uwCurrentTab][C_ucKey_RCTRL] );
KbLib_acVirtualKeyCodeTab[VK_MENU] = C_ucKeyPressed &
( KbLib_acTabKey[KbLib_uwCurrentTab][C_ucKey_LALT] |
KbLib_acTabKey[KbLib_uwCurrentTab][C_ucKey_RALT] );
/* Add CAPS LOCK state, (useless for Verr Num, ignored by ToAsciiEx() */
KbLib_acVirtualKeyCodeTab[VK_CAPITAL] = GetKeyState(VK_CAPITAL) & C_ucKeyToggled;
/* deuxieme modif qui tue - Elie*/
KbLib_acVirtualKeyCodeTab[VK_NUMLOCK] = GetKeyState(VK_NUMLOCK) & C_ucKeyToggled;
iResult = ToAsciiEx(VirtualKeyCode, wKeyCode, KbLib_acVirtualKeyCodeTab, a_ucASCIICode,0 , KbLib_LayoutHandle);
switch (iResult)
{
case 0:
return (C_wKbError);
break;
case 1:
iResult = a_ucASCIICode[0] & 0xff;
if (!isprint(iResult) /*&& iswprint(iResult)*/) return (C_wKbError);
break;
case 2:
return (C_wKbError);
break;
}
return (a_ucASCIICode[0]);
}
short valid()
{
return(KbLib_uwHValidEntries);
}
short head()
{
return (KbLib_uwHHead);
}
short numKey()
{
short index;
index = KbLib_uwHHead-1;
if ( index<0 ) index +=KbLib_uwHSize;
return (KbLib_H[index].m_uwKeyPressedNumber );
}
char * CS(void)
{
return (CurrentString);
}