OpenClonk
C4KeyboardInput Class Reference

#include <C4KeyboardInput.h>

Public Member Functions

 C4KeyboardInput ()
 
 ~C4KeyboardInput ()
 
void Clear ()
 
void RegisterKey (C4CustomKey *pRegKey)
 
void UnregisterKey (const StdStrBuf &rsName)
 
void UnregisterKeyBinding (C4CustomKey *pKey)
 
bool DoInput (const C4KeyCodeEx &InKey, C4KeyEventType InEvent, DWORD InScope, int32_t iStrength)
 
void CompileFunc (StdCompiler *pComp)
 
bool LoadCustomConfig ()
 
C4CustomKeyGetKeyByName (const char *szKeyName)
 
StdStrBuf GetKeyCodeNameByKeyName (const char *szKeyName, bool fShort=false, int32_t iIndex=0)
 
const C4KeyEventDataGetLastKeyExtraData () const
 
void SetLastKeyExtraData (const C4KeyEventData &data)
 

Static Public Attributes

static bool IsValid = false
 

Detailed Description

Definition at line 488 of file C4KeyboardInput.h.

Constructor & Destructor Documentation

◆ C4KeyboardInput()

C4KeyboardInput::C4KeyboardInput ( )
inline

Definition at line 507 of file C4KeyboardInput.h.

507 { IsValid = true; }
static bool IsValid

◆ ~C4KeyboardInput()

C4KeyboardInput::~C4KeyboardInput ( )
inline

Definition at line 508 of file C4KeyboardInput.h.

References C4KeyCodeEx::CompileFunc().

508 { Clear(); IsValid = false; }
static bool IsValid
Here is the call graph for this function:

Member Function Documentation

◆ Clear()

void C4KeyboardInput::Clear ( )

Definition at line 764 of file C4KeyboardInput.cpp.

References C4CustomKey::GetCodes().

Referenced by C4Game::Clear(), and C4Game::InitKeyboard().

765 {
766  LastKeyExtraData = C4KeyEventData();
767  // release all keys - name map is guarantueed to contain them all
768  for (KeyNameMap::const_iterator i = KeysByName.begin(); i != KeysByName.end(); ++i)
769  i->second->Deref();
770  // clear maps
771  KeysByCode.clear();
772  KeysByName.clear();
773 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CompileFunc()

void C4KeyboardInput::CompileFunc ( StdCompiler pComp)

Definition at line 941 of file C4KeyboardInput.cpp.

References StdCompiler::isDeserializer(), StdCompiler::Name(), StdCompiler::NameEnd(), and StdCompiler::Value().

942 {
943  // compile all keys that are already defined
944  // no definition of new keys with current compiler...
945  pComp->Name("Keys");
946  try
947  {
948  for (KeyNameMap::const_iterator i = KeysByName.begin(); i != KeysByName.end(); ++i)
949  {
950  // naming done in C4CustomKey, because default is determined by key only
951  C4CustomKey::CodeList OldCodes = i->second->GetCodes();
952  pComp->Value(*i->second);
953  // resort in secondary map if key changed
954  if (pComp->isDeserializer())
955  {
956  const C4CustomKey::CodeList &rNewCodes = i->second->GetCodes();
957  if (!(OldCodes == rNewCodes)) UpdateKeyCodes(i->second, OldCodes, rNewCodes);
958  }
959  }
960  }
961  catch (StdCompiler::Exception *pEx)
962  {
963  pComp->NameEnd(true);
964  throw pEx;
965  }
966  pComp->NameEnd();
967 }
virtual bool Name(const char *szName)
Definition: StdCompiler.h:77
std::vector< C4KeyCodeEx > CodeList
void Value(const T &rStruct)
Definition: StdCompiler.h:161
virtual bool isDeserializer()
Definition: StdCompiler.h:53
virtual void NameEnd(bool fBreak=false)
Definition: StdCompiler.h:78
Here is the call graph for this function:

◆ DoInput()

bool C4KeyboardInput::DoInput ( const C4KeyCodeEx InKey,
C4KeyEventType  InEvent,
DWORD  InScope,
int32_t  iStrength 
)

Definition at line 875 of file C4KeyboardInput.cpp.

References C4KeyCodeEx::dwShift, C4CustomKey::Execute(), C4CustomKey::GetPriority(), C4CustomKey::GetScope(), C4CustomKey::IsCodeMatched(), C4CustomKey::IsDown(), C4KeyCodeEx::Key, KEY_Any, KEY_CONTROLLER_AnyButton, KEY_Gamepad(), Key_IsGamepadAxis(), Key_IsGamepadButton(), KEYEV_Up, C4KeyEventData::KeyPos_None, C4CustomKey::PRIO_MoreThanMax, and C4CustomKey::PRIO_None.

Referenced by C4Game::DoKeyboardInput().

876 {
877  // store last-key-info
878  LastKeyExtraData.iStrength = (iStrength >= 0) ? iStrength : ((InEvent != KEYEV_Up) * 100);
879  LastKeyExtraData.game_x = LastKeyExtraData.game_y = LastKeyExtraData.vp_x = LastKeyExtraData.vp_y = C4KeyEventData::KeyPos_None;
880  // check all key events generated by this key: First the keycode itself, then any more generic key events like KEY_Any
881  const int32_t iKeyRangeMax = 5;
882  int32_t iKeyRangeCnt=0, j;
883  C4KeyCode FallbackKeys[iKeyRangeMax];
884  FallbackKeys[iKeyRangeCnt++] = InKey.Key;
885  if (Key_IsGamepadButton(InKey.Key))
886  {
887  // "any gamepad button"-event
888  FallbackKeys[iKeyRangeCnt++] = KEY_Gamepad(KEY_CONTROLLER_AnyButton);
889  }
890  else if (Key_IsGamepadAxis(InKey.Key))
891  {
892  // TODO: do we need "any axis" events?
893  }
894  if (InKey.Key != KEY_Any) FallbackKeys[iKeyRangeCnt++] = KEY_Any;
895  // now get key ranges for fallback chain
896  std::pair<KeyCodeMap::iterator, KeyCodeMap::iterator> KeyRanges[iKeyRangeMax];
897  assert(iKeyRangeCnt <= iKeyRangeMax);
898  for (int32_t i = 0; i<iKeyRangeCnt; ++i)
899  {
900  KeyRanges[i] = KeysByCode.equal_range(FallbackKeys[i]);
901  }
902  // check all assigned keys
903  // exec from highest to lowest priority
904  unsigned int uiLastPrio = C4CustomKey::PRIO_MoreThanMax;
905  for (;;)
906  {
907  KeyCodeMap::const_iterator i;
908  // get priority to exec
909  unsigned int uiExecPrio = C4CustomKey::PRIO_None, uiCurr;
910  for (j = 0; j < iKeyRangeCnt; ++j)
911  for (i = KeyRanges[j].first; i != KeyRanges[j].second; ++i)
912  {
913  uiCurr = i->second->GetPriority();
914  if (uiCurr > uiExecPrio && uiCurr < uiLastPrio) uiExecPrio = uiCurr;
915  }
916  // nothing with correct priority set left?
917  if (uiExecPrio == C4CustomKey::PRIO_None) break;
918  // exec all of this priority
919  for (j = 0; j < iKeyRangeCnt; ++j)
920  for (i = KeyRanges[j].first; i != KeyRanges[j].second; ++i)
921  {
922  C4CustomKey *pKey = i->second;
923  assert(pKey);
924  // check priority
925  if (pKey->GetPriority() == uiExecPrio)
926  // check scope and modifier
927  // (not on release of a key that has been down, because a key release might happen with a different modifier or in different scope than its pressing!)
928  if ((InEvent == KEYEV_Up && pKey->IsDown())
929  || ((pKey->GetScope() & InScope) && pKey->IsCodeMatched(C4KeyCodeEx(FallbackKeys[j], C4KeyShiftState(InKey.dwShift)))))
930  // exec it
931  if (pKey->Execute(InEvent, InKey))
932  return true;
933  }
934  // nothing found in this priority: exec next
935  uiLastPrio = uiExecPrio;
936  }
937  // no key matched or all returned false in Execute: Not processed
938  return false;
939 }
bool IsCodeMatched(const C4KeyCodeEx &key) const
C4KeyShiftState
bool IsDown() const
C4KeyScope GetScope() const
bool Key_IsGamepadButton(C4KeyCode key)
C4KeyCode KEY_Gamepad(uint8_t idButton)
C4KeyCode Key
unsigned int GetPriority() const
bool Key_IsGamepadAxis(C4KeyCode key)
const C4KeyCode KEY_Any
const C4KeyCode KEY_CONTROLLER_AnyButton
bool Execute(C4KeyEventType eEv, C4KeyCodeEx key)
unsigned long C4KeyCode
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetKeyByName()

C4CustomKey * C4KeyboardInput::GetKeyByName ( const char *  szKeyName)

Definition at line 983 of file C4KeyboardInput.cpp.

984 {
985  KeyNameMap::const_iterator i = KeysByName.find(szKeyName);
986  if (i == KeysByName.end()) return nullptr; else return (*i).second;
987 }

◆ GetKeyCodeNameByKeyName()

StdStrBuf C4KeyboardInput::GetKeyCodeNameByKeyName ( const char *  szKeyName,
bool  fShort = false,
int32_t  iIndex = 0 
)

Definition at line 989 of file C4KeyboardInput.cpp.

References C4CustomKey::GetCodes(), and C4KeyCodeEx::ToString().

Referenced by GetKeyboardInputName(), and C4FullScreen::ViewportCheck().

990 {
991  C4CustomKey *pKey = GetKeyByName(szKeyName);
992  if (pKey)
993  {
994  const C4CustomKey::CodeList &codes = pKey->GetCodes();
995  if ((size_t)iIndex < codes.size())
996  {
997  C4KeyCodeEx code = codes[iIndex];
998  return code.ToString(true, fShort);
999  }
1000  }
1001  // Error
1002  return StdStrBuf();
1003 }
C4CustomKey * GetKeyByName(const char *szKeyName)
std::vector< C4KeyCodeEx > CodeList
const CodeList & GetCodes() const
StdStrBuf ToString(bool fHumanReadable, bool fShort) const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetLastKeyExtraData()

const C4KeyEventData& C4KeyboardInput::GetLastKeyExtraData ( ) const
inline

Definition at line 528 of file C4KeyboardInput.h.

Referenced by C4PlayerControl::CompileFunc().

528 { return LastKeyExtraData; }
Here is the caller graph for this function:

◆ LoadCustomConfig()

bool C4KeyboardInput::LoadCustomConfig ( )

Definition at line 969 of file C4KeyboardInput.cpp.

References C4CFN_Extra, C4CFN_KeyConfig, DirSep, StdBuf::getData(), C4Group::LoadEntry(), LoadResStr(), LogF(), and C4Group::Open().

Referenced by C4Game::InitKeyboard().

970 {
971  // load from INI file (2do: load from registry)
972  C4Group GrpExtra;
973  if (!GrpExtra.Open(C4CFN_Extra)) return false;
974  StdBuf sFileContents;
975  if (!GrpExtra.LoadEntry(C4CFN_KeyConfig, &sFileContents)) return false;
976  StdStrBuf sFileContentsString((const char *) sFileContents.getData());
977  if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(*this, sFileContentsString, "Custom keys from" C4CFN_Extra DirSep C4CFN_KeyConfig))
978  return false;
979  LogF(LoadResStr("IDS_PRC_LOADEDKEYCONF"), C4CFN_Extra DirSep C4CFN_KeyConfig);
980  return true;
981 }
#define C4CFN_Extra
Definition: C4Components.h:31
Definition: StdBuf.h:29
bool LoadEntry(const char *szEntryName, char **lpbpBuf, size_t *ipSize=nullptr, int iAppendZeros=0)
Definition: C4Group.cpp:1893
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
bool Open(const char *szGroupName, bool fCreate=false)
Definition: C4Group.cpp:514
const void * getData() const
Definition: StdBuf.h:99
#define C4CFN_KeyConfig
Definition: C4Components.h:139
#define DirSep
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:260
Here is the call graph for this function:
Here is the caller graph for this function:

◆ RegisterKey()

void C4KeyboardInput::RegisterKey ( C4CustomKey pRegKey)

Definition at line 802 of file C4KeyboardInput.cpp.

References C4CustomKey::Deref(), C4CustomKey::GetCodes(), StdStrBuf::getData(), C4CustomKey::GetName(), C4CustomKey::Ref(), and C4CustomKey::Update().

Referenced by C4KeyBinding::C4KeyBinding(), and C4Game::InitKeyboard().

803 {
804  assert(pRegKey); if (!pRegKey) return;
805  // key will be added: ref it
806  pRegKey->Ref();
807  // search key of same name first
808  C4CustomKey *pDupKey = KeysByName[pRegKey->GetName().getData()];
809  if (pDupKey)
810  {
811  // key of this name exists: Merge them (old codes copied cuz they'll be overwritten)
812  C4CustomKey::CodeList OldCodes = pDupKey->GetCodes();
813  const C4CustomKey::CodeList &rNewCodes = pRegKey->GetCodes();
814  pDupKey->Update(pRegKey);
815  // update access map if key changed
816  if (!(OldCodes == rNewCodes)) UpdateKeyCodes(pDupKey, OldCodes, rNewCodes);
817  // key to be registered no longer used
818  pRegKey->Deref();
819  }
820  else
821  {
822  // new unique key: Insert into map
823  KeysByName[pRegKey->GetName().getData()] = pRegKey;
824  for (C4CustomKey::CodeList::const_iterator i = pRegKey->GetCodes().begin(); i != pRegKey->GetCodes().end(); ++i)
825  {
826  KeysByCode.insert(std::make_pair((*i).Key, pRegKey));
827  }
828  }
829 }
void Update(const C4CustomKey *pByKey)
std::vector< C4KeyCodeEx > CodeList
const StdStrBuf & GetName() const
const CodeList & GetCodes() const
const char * getData() const
Definition: StdBuf.h:442
Here is the call graph for this function:
Here is the caller graph for this function:

◆ SetLastKeyExtraData()

void C4KeyboardInput::SetLastKeyExtraData ( const C4KeyEventData data)
inline

Definition at line 529 of file C4KeyboardInput.h.

References C4KeyboardInput_Init().

Referenced by C4PlayerControl::DoMouseInput().

529 { LastKeyExtraData=data; }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ UnregisterKey()

void C4KeyboardInput::UnregisterKey ( const StdStrBuf rsName)

Definition at line 831 of file C4KeyboardInput.cpp.

References C4CustomKey::Deref(), C4CustomKey::GetCodes(), and StdStrBuf::getData().

832 {
833  // kill from name map
834  KeyNameMap::iterator in = KeysByName.find(rsName.getData());
835  if (in == KeysByName.end()) return;
836  C4CustomKey *pKey = in->second;
837  KeysByName.erase(in);
838  // kill all key bindings from key map
839  for (C4CustomKey::CodeList::const_iterator iCode = pKey->GetCodes().begin(); iCode != pKey->GetCodes().end(); ++iCode)
840  {
841  std::pair<KeyCodeMap::iterator, KeyCodeMap::iterator> KeyRange = KeysByCode.equal_range((*iCode).Key);
842  for (KeyCodeMap::iterator i = KeyRange.first; i != KeyRange.second; ++i)
843  if (i->second == pKey)
844  {
845  KeysByCode.erase(i);
846  break;
847  }
848  }
849  // release reference to key
850  pKey->Deref();
851 }
const CodeList & GetCodes() const
const char * getData() const
Definition: StdBuf.h:442
Here is the call graph for this function:

◆ UnregisterKeyBinding()

void C4KeyboardInput::UnregisterKeyBinding ( C4CustomKey pKey)

Definition at line 853 of file C4KeyboardInput.cpp.

References C4CustomKey::C4CustomKey(), StdStrBuf::getData(), C4CustomKey::GetName(), and C4CustomKey::KillCallbacks().

Referenced by C4KeyBinding::~C4KeyBinding().

854 {
855  // find key in name map
856  KeyNameMap::iterator in = KeysByName.find(pUnregKey->GetName().getData());
857  if (in == KeysByName.end()) return;
858  C4CustomKey *pKey = in->second;
859  // is this key in the map?
860  if (pKey != pUnregKey)
861  {
862  // Other key is in the list: Just remove the callbacks
863  pKey->KillCallbacks(pUnregKey);
864  return;
865  }
866  // this key is in the list: Replace by a duplicate...
867  C4CustomKey *pNewKey = new C4CustomKey(*pUnregKey, true);
868  // ...without the own callbacks
869  pNewKey->KillCallbacks(pUnregKey);
870  // and replace current key by duplicate
871  UnregisterKey(pUnregKey->GetName());
872  RegisterKey(pNewKey);
873 }
void KillCallbacks(const C4CustomKey *pOfKey)
void UnregisterKey(const StdStrBuf &rsName)
void RegisterKey(C4CustomKey *pRegKey)
Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ IsValid

bool C4KeyboardInput::IsValid = false
static

Definition at line 505 of file C4KeyboardInput.h.

Referenced by C4KeyBinding::~C4KeyBinding().


The documentation for this class was generated from the following files: