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

References IsValid.

◆ ~C4KeyboardInput()

C4KeyboardInput::~C4KeyboardInput ( )
inline

Definition at line 508 of file C4KeyboardInput.h.

508 { Clear(); IsValid = false; }

References Clear(), and IsValid.

Here is the call graph for this function:

Member Function Documentation

◆ Clear()

void C4KeyboardInput::Clear ( )

Definition at line 759 of file C4KeyboardInput.cpp.

760 {
761  LastKeyExtraData = C4KeyEventData();
762  // release all keys - name map is guarantueed to contain them all
763  for (KeyNameMap::const_iterator i = KeysByName.begin(); i != KeysByName.end(); ++i)
764  i->second->Deref();
765  // clear maps
766  KeysByCode.clear();
767  KeysByName.clear();
768 }

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

Here is the caller graph for this function:

◆ CompileFunc()

void C4KeyboardInput::CompileFunc ( StdCompiler pComp)

Definition at line 936 of file C4KeyboardInput.cpp.

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

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

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 870 of file C4KeyboardInput.cpp.

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

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

Referenced by C4Game::DoKeyboardInput().

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 978 of file C4KeyboardInput.cpp.

979 {
980  KeyNameMap::const_iterator i = KeysByName.find(szKeyName);
981  if (i == KeysByName.end()) return nullptr; else return (*i).second;
982 }

Referenced by GetKeyCodeNameByKeyName().

Here is the caller graph for this function:

◆ GetKeyCodeNameByKeyName()

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

Definition at line 984 of file C4KeyboardInput.cpp.

985 {
986  C4CustomKey *pKey = GetKeyByName(szKeyName);
987  if (pKey)
988  {
989  const C4CustomKey::CodeList &codes = pKey->GetCodes();
990  if ((size_t)iIndex < codes.size())
991  {
992  C4KeyCodeEx code = codes[iIndex];
993  return code.ToString(true, fShort);
994  }
995  }
996  // Error
997  return StdStrBuf();
998 }
const CodeList & GetCodes() const
C4CustomKey * GetKeyByName(const char *szKeyName)
StdStrBuf ToString(bool fHumanReadable, bool fShort) const

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

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

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.

528 { return LastKeyExtraData; }

◆ LoadCustomConfig()

bool C4KeyboardInput::LoadCustomConfig ( )

Definition at line 964 of file C4KeyboardInput.cpp.

965 {
966  // load from INI file (2do: load from registry)
967  C4Group GrpExtra;
968  if (!GrpExtra.Open(C4CFN_Extra)) return false;
969  StdBuf sFileContents;
970  if (!GrpExtra.LoadEntry(C4CFN_KeyConfig, &sFileContents)) return false;
971  StdStrBuf sFileContentsString((const char *) sFileContents.getData());
972  if (!CompileFromBuf_LogWarn<StdCompilerINIRead>(*this, sFileContentsString, "Custom keys from" C4CFN_Extra DirSep C4CFN_KeyConfig))
973  return false;
974  LogF(LoadResStr("IDS_PRC_LOADEDKEYCONF"), C4CFN_Extra DirSep C4CFN_KeyConfig);
975  return true;
976 }
#define C4CFN_Extra
Definition: C4Components.h:31
#define C4CFN_KeyConfig
Definition: C4Components.h:139
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:262
#define DirSep
bool LoadEntry(const char *entry_name, char **buffer, size_t *size_info=nullptr, int zeros_to_append=0)
Definition: C4Group.cpp:2375
bool Open(const char *group_name, bool do_create=false)
Definition: C4Group.cpp:660
Definition: StdBuf.h:30
const void * getData() const
Definition: StdBuf.h:99

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

Referenced by C4Game::InitKeyboard().

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 797 of file C4KeyboardInput.cpp.

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

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

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

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.

529 { LastKeyExtraData=data; }

Referenced by C4PlayerControl::DoMouseInput().

Here is the caller graph for this function:

◆ UnregisterKey()

void C4KeyboardInput::UnregisterKey ( const StdStrBuf rsName)

Definition at line 826 of file C4KeyboardInput.cpp.

827 {
828  // kill from name map
829  KeyNameMap::iterator in = KeysByName.find(rsName.getData());
830  if (in == KeysByName.end()) return;
831  C4CustomKey *pKey = in->second;
832  KeysByName.erase(in);
833  // kill all key bindings from key map
834  for (C4CustomKey::CodeList::const_iterator iCode = pKey->GetCodes().begin(); iCode != pKey->GetCodes().end(); ++iCode)
835  {
836  std::pair<KeyCodeMap::iterator, KeyCodeMap::iterator> KeyRange = KeysByCode.equal_range((*iCode).Key);
837  for (KeyCodeMap::iterator i = KeyRange.first; i != KeyRange.second; ++i)
838  if (i->second == pKey)
839  {
840  KeysByCode.erase(i);
841  break;
842  }
843  }
844  // release reference to key
845  pKey->Deref();
846 }

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

Referenced by UnregisterKeyBinding().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ UnregisterKeyBinding()

void C4KeyboardInput::UnregisterKeyBinding ( C4CustomKey pKey)

Definition at line 848 of file C4KeyboardInput.cpp.

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

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

Referenced by C4KeyBinding::~C4KeyBinding().

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

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