/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
// plInputDevice.cpp
#include
#include "plInputMap.h"
#include "plKeyMap.h"
#include "hsUtils.h"
#include "plResMgr/plLocalization.h"
ControlEventCode plInputMap::ConvertCharToControlCode(const char* c)
{
for (int i = 0; fCmdConvert[i].fCode != END_CONTROLS; i++)
{
if (stricmp(fCmdConvert[i].fDesc, c) == 0)
return (fCmdConvert[i].fCode);
}
return (END_CONTROLS);
}
const char *plInputMap::ConvertControlCodeToString( ControlEventCode code )
{
for( int i = 0; fCmdConvert[ i ].fCode != END_CONTROLS; i++ )
{
if( fCmdConvert[ i ].fCode == code )
return fCmdConvert[ i ].fDesc;
}
return nil;
}
//
// plMouseMap
//
plMouseMap::~plMouseMap()
{
for (int i = 0; i < fMap.Count(); i++)
delete(fMap[i]);
fMap.SetCountAndZero(0);
}
int plMouseMap::AddMapping(plMouseInfo* pNfo)
{
for (int i = 0; i < fMap.Count(); i++)
{
if (fMap[i] == pNfo)
return -1;
}
fMap.Append(pNfo);
return (fMap.Count() - 1);
}
//// plKeyBinding and Smaller Classes ////////////////////////////////////////
plKeyCombo::plKeyCombo()
{
fKey = KEY_UNMAPPED;
fFlags = 0;
}
hsBool plKeyCombo::IsSatisfiedBy(const plKeyCombo &combo) const
{
if (fKey != combo.fKey)
return false;
if ((fFlags & kShift) && !(combo.fFlags & kShift))
return false;
if ((fFlags & kCtrl) && !(combo.fFlags & kCtrl))
return false;
return true;
}
// Handy konstant for plKeyCombos
plKeyCombo plKeyCombo::kUnmapped = plKeyCombo( KEY_UNMAPPED, 0 );
plKeyBinding::plKeyBinding()
{
fCode = END_CONTROLS;
fCodeFlags = 0;
fKey1 = plKeyCombo::kUnmapped;
fKey2 = plKeyCombo::kUnmapped;
fString = nil;
}
plKeyBinding::plKeyBinding( ControlEventCode code, UInt32 codeFlags, const plKeyCombo &key1, const plKeyCombo &key2, const char *string /*= nil*/ )
{
fCode = code;
fCodeFlags = codeFlags;
fKey1 = key1;
fKey2 = key2;
fString = ( string == nil ) ? nil : hsStrcpy( string );
}
plKeyBinding::~plKeyBinding()
{
delete [] fString;
}
const plKeyCombo &plKeyBinding::GetMatchingKey( plKeyDef keyDef ) const
{
if (fKey1.fKey == keyDef)
return fKey1;
if (fKey2.fKey == keyDef)
return fKey2;
return plKeyCombo::kUnmapped;
}
void plKeyBinding::SetKey1( const plKeyCombo &newCombo )
{
fKey1 = newCombo;
}
void plKeyBinding::SetKey2( const plKeyCombo &newCombo )
{
fKey2 = newCombo;
}
void plKeyBinding::ClearKeys( void )
{
fKey1 = fKey2 = plKeyCombo::kUnmapped;
}
hsBool plKeyBinding::HasUnmappedKey() const
{
return fKey1.fKey == KEY_UNMAPPED || fKey2.fKey == KEY_UNMAPPED;
}
//////////////////////////////////////////////////////////////////////////////
//// plKeyMap Implementation /////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
plKeyMap::plKeyMap()
{
}
plKeyMap::~plKeyMap()
{
ClearAll();
}
void plKeyMap::ClearAll( void )
{
UInt32 i;
for( i = 0; i < fBindings.GetCount(); i++ )
delete fBindings[ i ];
fBindings.Reset();
}
//// AddCode //////////////////////////////////////////////////////////////////////////
// Adds a given control code to the map. Once you add it, you can't change its flags.
// Returns false if the code is already present
hsBool plKeyMap::AddCode( ControlEventCode code, UInt32 codeFlags )
{
if( IFindBinding( code ) != nil )
return false;
fBindings.Append( TRACKED_NEW plKeyBinding( code, codeFlags, plKeyCombo::kUnmapped, plKeyCombo::kUnmapped ) );
return true;
}
//// AddConsoleCommand ///////////////////////////////////////////////////////
// Same but for console commands. No flags b/c console commands always use
// the same flags.
hsBool plKeyMap::AddConsoleCommand( const char *command )
{
if( IFindConsoleBinding( command ) != nil )
return false;
fBindings.Append( TRACKED_NEW plKeyBinding( B_CONTROL_CONSOLE_COMMAND,
kControlFlagDownEvent | kControlFlagNoRepeat | kControlFlagNoDeactivate,
plKeyCombo::kUnmapped, plKeyCombo::kUnmapped,
command ) );
return true;
}
//// IFindBinding ////////////////////////////////////////////////////////////
// Find the binding for a given code.
plKeyBinding *plKeyMap::IFindBinding( ControlEventCode code ) const
{
UInt32 i;
for( i = 0; i < fBindings.GetCount(); i++ )
{
if( fBindings[ i ]->GetCode() == code )
return fBindings[ i ];
}
return nil;
}
//// IFindBindingByKey ///////////////////////////////////////////////////////
// Find the binding for a given key.
plKeyBinding *plKeyMap::IFindBindingByKey( const plKeyCombo &combo ) const
{
UInt32 i;
for( i = 0; i < fBindings.GetCount(); i++ )
{
if( fBindings[ i ]->GetKey1() == combo || fBindings[ i ]->GetKey2() == combo )
return fBindings[ i ];
}
return nil;
}
// Find ALL bindings that could be triggered by this combo. Meaning that if we have multiple
// bindings for a key with different shift/ctrl combinations, we want any that are satisfied with
// the given combo.
// We guarantee that the first binding in the result array is that one with priority.
void plKeyMap::IFindAllBindingsByKey(const plKeyCombo &combo, hsTArray &result) const
{
UInt32 i;
UInt8 bestScore = 0;
for (i = 0; i < fBindings.GetCount(); i++)
{
hsBool s1, s2;
s1 = fBindings[i]->GetKey1().IsSatisfiedBy(combo);
s2 = fBindings[i]->GetKey2().IsSatisfiedBy(combo);
if (s1 || s2)
{
UInt8 myScore = 0;
if (s1)
myScore = fBindings[i]->GetKey1().fFlags;
if (s2 && (fBindings[i]->GetKey2().fFlags > myScore))
myScore = fBindings[i]->GetKey2().fFlags;
if (myScore >= bestScore)
result.Insert(0, fBindings[i]);
else
result.Append(fBindings[i]);
}
}
}
//// IFindConsoleBinding /////////////////////////////////////////////////////
// You should be able to figure this out by now.
plKeyBinding *plKeyMap::IFindConsoleBinding( const char *command ) const
{
UInt32 i;
for( i = 0; i < fBindings.GetCount(); i++ )
{
if( fBindings[ i ]->GetCode() == B_CONTROL_CONSOLE_COMMAND )
{
if( stricmp( fBindings[ i ]->GetExtendedString(), command ) == 0 )
return fBindings[ i ];
}
}
return nil;
}
//// IActuallyBind ///////////////////////////////////////////////////////////
// Does the nitty gritty of binding by pref
void plKeyMap::IActuallyBind( plKeyBinding *binding, const plKeyCombo &combo, BindPref pref )
{
// Bind according to preference
switch( pref )
{
case kNoPreference:
// Pick a free slot, or 1st one if none
if( binding->GetKey1() == plKeyCombo::kUnmapped )
binding->SetKey1( combo );
else if( binding->GetKey2() == plKeyCombo::kUnmapped )
binding->SetKey2( combo );
else
binding->SetKey1( combo );
break;
case kNoPreference2nd:
// Pick a free slot, or 2nd one if none
if( binding->GetKey1() == plKeyCombo::kUnmapped )
binding->SetKey1( combo );
else if( binding->GetKey2() == plKeyCombo::kUnmapped )
binding->SetKey2( combo );
else
binding->SetKey2( combo );
break;
case kFirstAlways:
// Always bind to the first key
binding->SetKey1( combo );
break;
case kSecondAlways:
// You get the idea
binding->SetKey2( combo );
break;
default:
hsAssert( false, "Invalid bind preference in IActuallyBind()" );
}
}
//// BindKey /////////////////////////////////////////////////////////////////
// Adds a key binding to a given code. Returns false if the code isn't in
// this map or if key is already mapped.
hsBool plKeyMap::BindKey( const plKeyCombo &combo, ControlEventCode code, BindPref pref /*= kNoPreference*/ )
{
plKeyBinding* binding = nil;
// Control combos are ok. Binding directly to control is not.
if ( combo.fKey == KEY_CTRL )
return false;
// unless we are bindind to unmappped...
if ( combo.fKey != KEY_UNMAPPED)
{
// Make sure key isn't already used
binding = IFindBindingByKey( combo );
if( binding != nil )
return false;
}
// Get binding for this code
binding = IFindBinding( code );
if( binding == nil )
return false;
IActuallyBind( binding, combo, pref );
return true;
}
//// BindKeyToConsoleCmd /////////////////////////////////////////////////////
// Console command version
hsBool plKeyMap::BindKeyToConsoleCmd( const plKeyCombo &combo, const char *command, BindPref pref /*= kNoPreference*/ )
{
plKeyBinding* binding = nil;
// Control combos are ok. Binding directly to control is not.
if ( combo.fKey == KEY_CTRL )
return false;
// unless we are bindind to unmappped...
if ( combo.fKey != KEY_UNMAPPED)
{
// Make sure key isn't already used
binding = IFindBindingByKey( combo );
if( binding != nil )
return false;
}
// Get binding for this code
binding = IFindConsoleBinding( command );
if( binding == nil )
return false;
IActuallyBind( binding, combo, pref );
return true;
}
//// FindBinding /////////////////////////////////////////////////////////////
// Searches for the binding for a given code. Returns nil if not found
const plKeyBinding *plKeyMap::FindBinding( ControlEventCode code ) const
{
return IFindBinding( code );
}
//// FindBindingByKey ////////////////////////////////////////////////////////
// Same thing but by key
const plKeyBinding *plKeyMap::FindBindingByKey( const plKeyCombo &combo ) const
{
return IFindBindingByKey( combo );
}
// Same thing, but returns multiple matches (see IFindAllBindingsByKey)
void plKeyMap::FindAllBindingsByKey( const plKeyCombo &combo, hsTArray &result ) const
{
hsTArray bindings;
IFindAllBindingsByKey( combo, bindings );
int i;
for (i = 0; i < bindings.GetCount(); i++)
result.Append(bindings[i]);
}
const plKeyBinding* plKeyMap::FindConsoleBinding( const char *command ) const
{
return IFindConsoleBinding(command);
}
//// EnsureKeysClear /////////////////////////////////////////////////////////
// Basically UnmapKey(), but for two keys at once and won't assert if you
// give it unmapped keys
void plKeyMap::EnsureKeysClear( const plKeyCombo &key1, const plKeyCombo &key2 )
{
if( key1 != plKeyCombo::kUnmapped )
UnmapKey( key1 );
if( key2 != plKeyCombo::kUnmapped )
UnmapKey( key2 );
}
//// UnmapKey ////////////////////////////////////////////////////////////////
// Unmaps the given key, no matter what binding it is in
void plKeyMap::UnmapKey( const plKeyCombo &combo )
{
if( combo == plKeyCombo::kUnmapped )
{
hsAssert( false, "Trying to unbind invalid key" );
return;
}
plKeyBinding *binding;
// Just in case we're in multiple bindings, even tho we are guarding against
// that
while( ( binding = IFindBindingByKey( combo ) ) != nil )
{
if( binding->GetKey1() == combo )
binding->SetKey1( plKeyCombo::kUnmapped );
if( binding->GetKey2() == combo )
binding->SetKey2( plKeyCombo::kUnmapped );
}
}
//// UnmapBinding ////////////////////////////////////////////////////////////
// Unmaps the keys for a single binding
void plKeyMap::UnmapBinding( ControlEventCode code )
{
plKeyBinding *binding = IFindBinding( code );
if( binding != nil )
binding->ClearKeys();
}
//// UnmapAllBindings ////////////////////////////////////////////////////////
// Unmaps all the bindings, but leaves the code records themselves
void plKeyMap::UnmapAllBindings( void )
{
UInt32 i;
for( i = 0; i < fBindings.GetCount(); i++ )
fBindings[ i ]->ClearKeys();
}
//// EraseBinding ////////////////////////////////////////////////////////////
// Erases the given code binding. Note: should never really be used, but
// provided here for completeness
void plKeyMap::EraseBinding( ControlEventCode code )
{
UInt32 i;
for( i = 0; i < fBindings.GetCount(); i++ )
{
if( fBindings[ i ]->GetCode() == code )
{
delete fBindings[ i ];
fBindings.Remove( i );
return;
}
}
}
const char* plKeyMap::ConvertVKeyToChar( UInt32 vk )
{
Win32keyConvert* keyConvert = &fKeyConversionEnglish[0];
switch (plLocalization::GetLanguage())
{
case plLocalization::kFrench:
keyConvert = &fKeyConversionFrench[0];
break;
case plLocalization::kGerman:
keyConvert = &fKeyConversionGerman[0];
break;
// case plLocalization::kSpanish:
// keyConvert = &fKeyConversionSpanish[0];
// break;
// case plLocalization::kItalian:
// keyConvert = &fKeyConversionItalian[0];
// break;
// default is English
}
for (int i = 0; keyConvert[i].fVKey != 0xffffffff; i++)
{
if (keyConvert[i].fVKey == vk)
return (keyConvert[i].fKeyName);
}
return nil;
}
plKeyDef plKeyMap::ConvertCharToVKey( const char *c )
{
Win32keyConvert* keyConvert = &fKeyConversionEnglish[0];
switch (plLocalization::GetLanguage())
{
case plLocalization::kFrench:
keyConvert = &fKeyConversionFrench[0];
break;
case plLocalization::kGerman:
keyConvert = &fKeyConversionGerman[0];
break;
// case plLocalization::kSpanish:
// keyConvert = &fKeyConversionSpanish[0];
// break;
// case plLocalization::kItalian:
// keyConvert = &fKeyConversionItalian[0];
// break;
// default is English
}
for (int i = 0; keyConvert[i].fVKey != 0xffffffff; i++)
{
if (stricmp(keyConvert[i].fKeyName, c) == 0)
return (plKeyDef)(keyConvert[i].fVKey);
}
// Is it just a single character?
if( isalnum( *c ) && strlen( c ) == 1 )
return (plKeyDef)toupper( *c );
// if we didn't find anything yet...
// ...then look thru all the other language mappings that we know about,
// ...just in case they keep switching languages on us
if ( plLocalization::GetLanguage() != plLocalization::kEnglish)
{
for (int i = 0; fKeyConversionEnglish[i].fVKey != 0xffffffff; i++)
{
if (stricmp(fKeyConversionEnglish[i].fKeyName, c) == 0)
return (plKeyDef)(fKeyConversionEnglish[i].fVKey);
}
}
if ( plLocalization::GetLanguage() != plLocalization::kFrench)
{
for (int i = 0; fKeyConversionFrench[i].fVKey != 0xffffffff; i++)
{
if (stricmp(fKeyConversionFrench[i].fKeyName, c) == 0)
return (plKeyDef)(fKeyConversionFrench[i].fVKey);
}
}
if ( plLocalization::GetLanguage() != plLocalization::kGerman)
{
for (int i = 0; fKeyConversionGerman[i].fVKey != 0xffffffff; i++)
{
if (stricmp(fKeyConversionGerman[i].fKeyName, c) == 0)
return (plKeyDef)(fKeyConversionGerman[i].fVKey);
}
}
/*
if ( plLocalization::GetLanguage() != plLocalization::kSpanish)
{
for (int i = 0; fKeyConversionSpanish[i].fVKey != 0xffffffff; i++)
{
if (stricmp(fKeyConversionSpanish[i].fKeyName, c) == 0)
return (plKeyDef)(fKeyConversionSpanish[i].fVKey);
}
}
if ( plLocalization::GetLanguage() != plLocalization::kItalian)
{
for (int i = 0; fKeyConversionItalian[i].fVKey != 0xffffffff; i++)
{
if (stricmp(fKeyConversionItalian[i].fKeyName, c) == 0)
return (plKeyDef)(fKeyConversionItalian[i].fVKey);
}
}
*/
// finally, just give up... unmapped!
return KEY_UNMAPPED;
}
const char* plKeyMap::GetStringCtrl()
{
switch (plLocalization::GetLanguage())
{
case plLocalization::kFrench:
return "Ctrl+";
break;
case plLocalization::kGerman:
return "Strg+";
break;
/* case plLocalization::kSpanish:
return "Ctrl+";
break;
case plLocalization::kItalian:
return "Ctrl+";
break;
*/
// default is English
}
return "Ctrl+";
}
const char* plKeyMap::GetStringShift()
{
switch (plLocalization::GetLanguage())
{
case plLocalization::kFrench:
return "Maj+";
break;
case plLocalization::kGerman:
return "Umschalt+";
break;
/* case plLocalization::kSpanish:
return "Mayúsculas+";
break;
case plLocalization::kItalian:
return "Shift+";
break;
*/
// default is English
}
return "Shift+";
}
const char* plKeyMap::GetStringUnmapped()
{
switch (plLocalization::GetLanguage())
{
case plLocalization::kFrench:
return "(NonDéfini)";
break;
case plLocalization::kGerman:
return "(NichtZugewiesen)";
break;
/* case plLocalization::kSpanish:
return "(SinMapear)";
break;
case plLocalization::kItalian:
return "(NonAssegnato)";
break;
*/
// default is English
}
return "(unmapped)";
}
// If the binding has one of these keys, but not the other, go and bind the other
// (if there's an unmapped space for it).
void plKeyMap::HandleAutoDualBinding(plKeyDef key1, plKeyDef key2)
{
ICheckAndBindDupe(key1, key2);
ICheckAndBindDupe(key2, key1);
}
void plKeyMap::ICheckAndBindDupe(plKeyDef origKey, plKeyDef dupeKey)
{
hsTArray bindings;
plKeyCombo combo;
combo.fKey = origKey;
IFindAllBindingsByKey(combo, bindings);
int i;
for (i = 0; i < bindings.GetCount(); i++)
{
plKeyBinding *binding = bindings[i];
if (binding->HasUnmappedKey())
{
combo = binding->GetMatchingKey(origKey);
combo.fKey = dupeKey;
if (IFindBindingByKey(combo) == nil)
IActuallyBind(binding, combo, kNoPreference);
}
}
}
Win32keyConvert plKeyMap::fKeyConversionEnglish[] =
{
{ VK_F1, "F1"},
{ VK_F2, "F2"},
{ VK_F3, "F3"},
{ VK_F4, "F4"},
{ VK_F5, "F5"},
{ VK_F6, "F6"},
{ VK_F7, "F7"},
{ VK_F8, "F8"},
{ VK_F9, "F9"},
{ VK_F10, "F10"},
{ VK_F11, "F11"},
{ VK_F12, "F12"},
{ VK_ESCAPE, "Esc"},
{ VK_TAB, "Tab"},
{ VK_UP, "UpArrow"},
{ VK_DOWN, "DownArrow"},
{ VK_LEFT, "LeftArrow"},
{ VK_RIGHT, "RightArrow"},
{ VK_BACK, "Backspace"},
{ VK_RETURN, "Enter"},
{ VK_PAUSE, "Pause"},
{ VK_CAPITAL, "CapsLock"},
{ VK_PRIOR, "PageUp"},
{ VK_NEXT, "PageDn"},
{ VK_END, "End"},
{ VK_HOME, "Home"},
{ VK_SNAPSHOT, "PrintScrn"},
{ VK_INSERT, "Insert"},
{ VK_DELETE, "Delete"},
{ VK_NUMPAD0, "NumPad0"},
{ VK_NUMPAD1, "NumPad1"},
{ VK_NUMPAD2, "NumPad2"},
{ VK_NUMPAD3, "NumPad3"},
{ VK_NUMPAD4, "NumPad4"},
{ VK_NUMPAD5, "NumPad5"},
{ VK_NUMPAD6, "NumPad6"},
{ VK_NUMPAD7, "NumPad7"},
{ VK_NUMPAD8, "NumPad8"},
{ VK_NUMPAD9, "NumPad9"},
{ VK_MULTIPLY, "NumPad*"},
{ VK_ADD, "NumPad+"},
{ VK_SUBTRACT, "NumPad-"},
{ VK_DECIMAL, "NumPad."},
{ VK_DIVIDE, "NumPad/"},
{ VK_SPACE, "SpaceBar"},
{ VK_OEM_COMMA, "Comma"},
{ VK_OEM_PERIOD,"Period"},
{ VK_OEM_MINUS, "Minus"},
{ VK_OEM_PLUS, "Plus"},
{ VK_SHIFT, "Shift" },
// not valid outside USA
{ VK_OEM_1, "Semicolon"},
{ VK_OEM_2, "ForewardSlash"},
{ VK_OEM_3, "Tilde"},
{ VK_OEM_4, "LeftBracket"},
{ VK_OEM_5, "Backslash"},
{ VK_OEM_6, "RightBracket"},
{ VK_OEM_7, "Quote"},
{ 0xffffffff, "Unused"},
};
Win32keyConvert plKeyMap::fKeyConversionFrench[] =
{
{ VK_F1, "F1"},
{ VK_F2, "F2"},
{ VK_F3, "F3"},
{ VK_F4, "F4"},
{ VK_F5, "F5"},
{ VK_F6, "F6"},
{ VK_F7, "F7"},
{ VK_F8, "F8"},
{ VK_F9, "F9"},
{ VK_F10, "F10"},
{ VK_F11, "F11"},
{ VK_F12, "F12"},
{ VK_ESCAPE, "Échap"},
{ VK_TAB, "Tab"},
{ VK_UP, "FlècheHaut"},
{ VK_DOWN, "FlècheBas"},
{ VK_LEFT, "FlècheGauche"},
{ VK_RIGHT, "FlècheDroite"},
{ VK_BACK, "Retour"},
{ VK_RETURN, "Entrée"},
{ VK_PAUSE, "Pause"},
{ VK_CAPITAL, "CapsLock"},
{ VK_PRIOR, "PagePréc"},
{ VK_NEXT, "PageSuiv"},
{ VK_END, "Fin"},
{ VK_HOME, "Origine"},
{ VK_SNAPSHOT, "ImprÉcran"},
{ VK_INSERT, "Inser"},
{ VK_DELETE, "Suppr"},
{ VK_NUMPAD0, "PavNum0"},
{ VK_NUMPAD1, "PavNum1"},
{ VK_NUMPAD2, "PavNum2"},
{ VK_NUMPAD3, "PavNum3"},
{ VK_NUMPAD4, "PavNum4"},
{ VK_NUMPAD5, "PavNum5"},
{ VK_NUMPAD6, "PavNum6"},
{ VK_NUMPAD7, "PavNum7"},
{ VK_NUMPAD8, "PavNum8"},
{ VK_NUMPAD9, "PavNum9"},
{ VK_MULTIPLY, "PavNum*"},
{ VK_ADD, "PavNum+"},
{ VK_SUBTRACT, "PavNum-"},
{ VK_DECIMAL, "PavNum."},
{ VK_DIVIDE, "PavNum/"},
{ VK_SPACE, "Espace"},
{ VK_OEM_COMMA, "Virgule"},
{ VK_OEM_PERIOD,"Point"},
{ VK_OEM_MINUS, "Moins"},
{ VK_OEM_PLUS, "Plus"},
{ VK_SHIFT, "Maj" },
// not valid outside USA
{ VK_OEM_1, "Point-virgule"},
{ VK_OEM_2, "BarreOblique"},
{ VK_OEM_3, "Tilde"},
{ VK_OEM_4, "ParenthèseG"},
{ VK_OEM_5, "BarreInverse"},
{ VK_OEM_6, "ParenthèseD"},
{ VK_OEM_7, "Guillemet"},
{ 0xffffffff, "Unused"},
};
Win32keyConvert plKeyMap::fKeyConversionGerman[] =
{
{ VK_F1, "F1"},
{ VK_F2, "F2"},
{ VK_F3, "F3"},
{ VK_F4, "F4"},
{ VK_F5, "F5"},
{ VK_F6, "F6"},
{ VK_F7, "F7"},
{ VK_F8, "F8"},
{ VK_F9, "F9"},
{ VK_F10, "F10"},
{ VK_F11, "F11"},
{ VK_F12, "F12"},
{ VK_ESCAPE, "Esc"},
{ VK_TAB, "Tab"},
{ VK_UP, "PfeilHoch"},
{ VK_DOWN, "PfeilRunter"},
{ VK_LEFT, "PfeilLinks"},
{ VK_RIGHT, "PfeilRechts"},
{ VK_BACK, "Backspace"},
{ VK_RETURN, "Enter"},
{ VK_PAUSE, "Pause"},
{ VK_CAPITAL, "Feststelltaste"},
{ VK_PRIOR, "BildHoch"},
{ VK_NEXT, "BildRunter"},
{ VK_END, "Ende"},
{ VK_HOME, "Pos1"},
{ VK_SNAPSHOT, "Druck"},
{ VK_INSERT, "Einf"},
{ VK_DELETE, "Entf"},
{ VK_NUMPAD0, "ZB0"},
{ VK_NUMPAD1, "ZB1"},
{ VK_NUMPAD2, "ZB2"},
{ VK_NUMPAD3, "ZB3"},
{ VK_NUMPAD4, "ZB4"},
{ VK_NUMPAD5, "ZB5"},
{ VK_NUMPAD6, "ZB6"},
{ VK_NUMPAD7, "ZB7"},
{ VK_NUMPAD8, "ZB8"},
{ VK_NUMPAD9, "ZB9"},
{ VK_MULTIPLY, "ZB*"},
{ VK_ADD, "ZB+"},
{ VK_SUBTRACT, "ZB-"},
{ VK_DECIMAL, "ZB."},
{ VK_DIVIDE, "ZB/"},
{ VK_SPACE, "Leertaste"},
{ VK_OEM_COMMA, "Komma"},
{ VK_OEM_PERIOD,"Punkt"},
{ VK_OEM_MINUS, "Minus"},
{ VK_OEM_PLUS, "Plus"},
{ VK_SHIFT, "Umschalt" },
// not valid outside USA
{ VK_OEM_1, "Ü"},
{ VK_OEM_2, "#"},
{ VK_OEM_3, "Ö"},
{ VK_OEM_4, "ß"},
{ VK_OEM_5, "Backslash"},
{ VK_OEM_6, "Akzent"},
{ VK_OEM_7, "Ä"},
{ 0xffffffff, "Unused"},
};
/*
Win32keyConvert plKeyMap::fKeyConversionSpanish[] =
{
{ VK_F1, "F1"},
{ VK_F2, "F2"},
{ VK_F3, "F3"},
{ VK_F4, "F4"},
{ VK_F5, "F5"},
{ VK_F6, "F6"},
{ VK_F7, "F7"},
{ VK_F8, "F8"},
{ VK_F9, "F9"},
{ VK_F10, "F10"},
{ VK_F11, "F11"},
{ VK_F12, "F12"},
{ VK_ESCAPE, "Esc"},
{ VK_TAB, "Tabulador"},
{ VK_UP, "CursorArriba"},
{ VK_DOWN, "CursorAbajo"},
{ VK_LEFT, "CursorIzquierdo"},
{ VK_RIGHT, "CursorDerecho"},
{ VK_BACK, "Retroceso"},
{ VK_RETURN, "Intro"},
{ VK_PAUSE, "Pausa"},
{ VK_CAPITAL, "BloqMayús"},
{ VK_PRIOR, "RePág"},
{ VK_NEXT, "AVPág"},
{ VK_END, "Fin"},
{ VK_HOME, "Inicio"},
{ VK_SNAPSHOT, "ImprPetSis"},
{ VK_INSERT, "Insert"},
{ VK_DELETE, "Supr"},
{ VK_NUMPAD0, "TecNum0"},
{ VK_NUMPAD1, "TecNum1"},
{ VK_NUMPAD2, "TecNum2"},
{ VK_NUMPAD3, "TecNum3"},
{ VK_NUMPAD4, "TecNum4"},
{ VK_NUMPAD5, "TecNum5"},
{ VK_NUMPAD6, "TecNum6"},
{ VK_NUMPAD7, "TecNum7"},
{ VK_NUMPAD8, "TecNum8"},
{ VK_NUMPAD9, "TecNum9"},
{ VK_MULTIPLY, "TecNum*"},
{ VK_ADD, "TecNum+"},
{ VK_SUBTRACT, "TecNum-"},
{ VK_DECIMAL, "TecNum."},
{ VK_DIVIDE, "TecNum/"},
{ VK_SPACE, "BarraEspacio"},
{ VK_OEM_COMMA, "Coma"},
{ VK_OEM_PERIOD,"Punto"},
{ VK_OEM_MINUS, "Menos"},
{ VK_OEM_PLUS, "Más"},
{ VK_SHIFT, "Mayúsculas" },
// not valid outside USA
{ VK_OEM_1, "PuntoYComa"},
{ VK_OEM_2, "Barra"},
{ VK_OEM_3, "Tilde"},
{ VK_OEM_4, "AbrirParéntesis"},
{ VK_OEM_5, "BarraInvertida"},
{ VK_OEM_6, "CerrarParéntesis"},
{ VK_OEM_7, "Comillas"},
{ 0xffffffff, "Unused"},
};
Win32keyConvert plKeyMap::fKeyConversionItalian[] =
{
{ VK_F1, "F1"},
{ VK_F2, "F2"},
{ VK_F3, "F3"},
{ VK_F4, "F4"},
{ VK_F5, "F5"},
{ VK_F6, "F6"},
{ VK_F7, "F7"},
{ VK_F8, "F8"},
{ VK_F9, "F9"},
{ VK_F10, "F10"},
{ VK_F11, "F11"},
{ VK_F12, "F12"},
{ VK_ESCAPE, "Esc"},
{ VK_TAB, "Tab"},
{ VK_UP, "FrecciaSu"},
{ VK_DOWN, "FrecciaGiù"},
{ VK_LEFT, "FrecciaSx"},
{ VK_RIGHT, "FrecciaDx"},
{ VK_BACK, "Backspace"},
{ VK_RETURN, "Invio"},
{ VK_PAUSE, "Pausa"},
{ VK_CAPITAL, "BlocMaiusc"},
{ VK_PRIOR, "PagSu"},
{ VK_NEXT, "PagGiù"},
{ VK_END, "Fine"},
{ VK_HOME, "Home"},
{ VK_SNAPSHOT, "Stamp"},
{ VK_INSERT, "Ins"},
{ VK_DELETE, "Canc"},
{ VK_NUMPAD0, "TastNum0"},
{ VK_NUMPAD1, "TastNum1"},
{ VK_NUMPAD2, "TastNum2"},
{ VK_NUMPAD3, "TastNum3"},
{ VK_NUMPAD4, "TastNum4"},
{ VK_NUMPAD5, "TastNum5"},
{ VK_NUMPAD6, "TastNum6"},
{ VK_NUMPAD7, "TastNum7"},
{ VK_NUMPAD8, "TastNum8"},
{ VK_NUMPAD9, "TastNum9"},
{ VK_MULTIPLY, "TastNum*"},
{ VK_ADD, "TastNum+"},
{ VK_SUBTRACT, "TastNum-"},
{ VK_DECIMAL, "TastNum."},
{ VK_DIVIDE, "TastNum/"},
{ VK_SPACE, "Spazio"},
{ VK_OEM_COMMA, "Virgola"},
{ VK_OEM_PERIOD,"Punto"},
{ VK_OEM_MINUS, "Meno"},
{ VK_OEM_PLUS, "QuadraDx"},
{ VK_SHIFT, "Shift" },
// not valid outside USA
{ VK_OEM_1, "QuadraSx"},
{ VK_OEM_2, "ù"},
{ VK_OEM_3, "ò"},
{ VK_OEM_4, "Apostrofo"},
{ VK_OEM_5, "\\"},
{ VK_OEM_6, "ì"},
{ VK_OEM_7, "à"},
{ 0xffffffff, "Unused"},
};
*/
CommandConvert plInputMap::fCmdConvert[] =
{
{ B_CONTROL_ACTION, "Use Key" },
{ B_CONTROL_JUMP, "Jump Key" },
{ B_CONTROL_DIVE, "Dive Key" },
{ B_CONTROL_MOVE_FORWARD, "Walk Forward" },
{ B_CONTROL_MOVE_BACKWARD, "Walk Backward" },
{ B_CONTROL_STRAFE_LEFT, "Strafe Left" },
{ B_CONTROL_STRAFE_RIGHT, "Strafe Right" },
{ B_CONTROL_MOVE_UP, "Move Up" },
{ B_CONTROL_MOVE_DOWN, "Move Down" },
{ B_CONTROL_ROTATE_LEFT, "Turn Left" },
{ B_CONTROL_ROTATE_RIGHT, "Turn Right" },
{ B_CONTROL_ROTATE_UP, "Turn Up" },
{ B_CONTROL_ROTATE_DOWN, "Turn Down" },
{ B_CONTROL_MODIFIER_FAST, "Fast Modifier" },
{ B_CONTROL_EQUIP, "PickUp Item" },
{ B_CONTROL_DROP, "Drop Item" },
{ B_TOGGLE_DRIVE_MODE, "Drive" },
{ B_CONTROL_ALWAYS_RUN, "Always Run" },
{ B_CAMERA_MOVE_FORWARD, "Camera Forward"},
{ B_CAMERA_MOVE_BACKWARD, "Camera Backward"},
{ B_CAMERA_MOVE_UP, "Camera Up"},
{ B_CAMERA_MOVE_DOWN, "Camera Down"},
{ B_CAMERA_MOVE_LEFT, "Camera Left"},
{ B_CAMERA_MOVE_RIGHT, "Camera Right"},
{ B_CAMERA_MOVE_FAST, "Camera Fast"},
{ B_CAMERA_ROTATE_RIGHT, "Camera Yaw Right"},
{ B_CAMERA_ROTATE_LEFT, "Camera Yaw Left"},
{ B_CAMERA_ROTATE_UP, "Camera Pitch Up"},
{ B_CAMERA_ROTATE_DOWN, "Camera Pitch Down"},
{ B_CAMERA_PAN_UP, "Camera Pan Up"},
{ B_CAMERA_PAN_DOWN, "Camera Pan Down"},
{ B_CAMERA_PAN_LEFT, "Camera Pan Left"},
{ B_CAMERA_PAN_RIGHT, "Camera Pan Right"},
{ B_CAMERA_PAN_TO_CURSOR, "Camera Pan To Cursor"},
{ B_CAMERA_RECENTER, "Camera Recenter"},
{ B_SET_CONSOLE_MODE, "Console"},
{ B_CAMERA_DRIVE_SPEED_UP, "Decrease Camera Drive Speed" },
{ B_CAMERA_DRIVE_SPEED_DOWN, "Increase Camera Drive Speed" },
{ S_INCREASE_MIC_VOL, "Increase Microphone Sensitivity" },
{ S_DECREASE_MIC_VOL, "Decrease Microphone Sensitivity" },
{ S_PUSH_TO_TALK, "Push to talk" },
{ S_SET_WALK_MODE, "Set Walk Mode" },
{ B_CONTROL_TURN_TO, "Turn To Click" },
{ B_CONTROL_TOGGLE_PHYSICAL, "Toggle Physical" },
{ S_SET_FIRST_PERSON_MODE, "Toggle First Person" },
{ B_CAMERA_ZOOM_IN, "Camera Zoom In" },
{ B_CAMERA_ZOOM_OUT, "Camera Zoom Out" },
{ B_CONTROL_EXIT_MODE, "Exit Mode" },
{ B_CONTROL_OPEN_KI, "Open KI" },
{ B_CONTROL_OPEN_BOOK, "Open Player Book" },
{ B_CONTROL_EXIT_GUI_MODE, "Exit GUI Mode" },
{ B_CONTROL_MODIFIER_STRAFE, "Strafe Modifier" },
{ END_CONTROLS, ""},
};