Skip to content

Commit

Permalink
Contextual input bindings
Browse files Browse the repository at this point in the history
Depending on the context (e.g. different UI windows) input mapping can be different.
This feature is needed for gamepads, because they have limited amount of buttons. (#943)
  • Loading branch information
Xottab-DUTY committed Aug 9, 2023
1 parent 1ef6b74 commit 5f9ca4b
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
24 changes: 19 additions & 5 deletions src/xrEngine/xr_level_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,17 +688,30 @@ bool IsGroupMatching(EKeyGroup g1, EKeyGroup g2)
return ((g1 == g2) || (g1 == _both) || (g2 == _both));
}

EGameActions GetBindedAction(int dik)
bool IsContextNotConflicted(EKeyContext c1, EKeyContext c2)
{
return c1 != c2;
}

bool IsContextMatching(EKeyContext c1, EKeyContext c2)
{
return c1 == c2 || (c1 == EKeyContext::Undefined && c2 == EKeyContext::Undefined);
}

EGameActions GetBindedAction(int dik, EKeyContext context /*= EKeyContext::Undefined*/)
{
for (int idx = 0; idx < bindings_count; ++idx)
{
key_binding* binding = &g_key_bindings[idx];

bool isGroupMatching = IsGroupMatching(binding->m_action->key_group, g_current_keygroup);

const bool isGroupMatching = IsGroupMatching(binding->m_action->key_group, g_current_keygroup);
if (!isGroupMatching)
continue;

const bool isContextMatching = IsContextMatching(binding->m_action->key_context, context);
if (!isContextMatching)
continue;

for (u8 i = 0; i < bindtypes_count && isGroupMatching; ++i)
if (binding->m_keyboard[i] && binding->m_keyboard[i]->dik == dik)
return binding->m_action->id;
Expand Down Expand Up @@ -794,10 +807,11 @@ class CCC_Bind : public IConsole_Command
if (binding == currBinding)
continue;

bool isConflict = !IsGroupNotConflicted(binding->m_action->key_group, currBinding->m_action->key_group);
const bool groupConflict = !IsGroupNotConflicted(binding->m_action->key_group, currBinding->m_action->key_group);
const bool contextConflict = !IsContextNotConflicted(binding->m_action->key_context, currBinding->m_action->key_context);

for (u8 i = 0; i < bindtypes_count; ++i)
if (binding->m_keyboard[i] == keyboard && isConflict)
if (binding->m_keyboard[i] == keyboard && (groupConflict && contextConflict))
binding->m_keyboard[i] = nullptr;
}

Expand Down
9 changes: 8 additions & 1 deletion src/xrEngine/xr_level_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ enum EGameActions : u32
kNOTBINDED
};

enum class EKeyContext
{
Undefined = 0, // default behaviour
};

constexpr char GAME_ACTION_MARK = 27; // escape symbol

struct keyboard_key
Expand All @@ -160,6 +165,7 @@ struct game_action
pcstr action_name;
EGameActions id;
EKeyGroup key_group;
EKeyContext key_context{ EKeyContext::Undefined };
};

#define bindtypes_count 3
Expand All @@ -177,6 +183,7 @@ extern ENGINE_API keyboard_key keyboards[];
extern ENGINE_API key_binding g_key_bindings[];

ENGINE_API bool IsGroupNotConflicted(EKeyGroup g1, EKeyGroup g2);
ENGINE_API bool IsContextNotConflicted(EKeyContext c1, EKeyContext c2);

ENGINE_API pcstr IdToActionName(EGameActions id);
ENGINE_API EGameActions ActionNameToId(pcstr name);
Expand All @@ -189,7 +196,7 @@ ENGINE_API keyboard_key* DikToPtr(int dik, bool safe);

ENGINE_API bool IsBinded(EGameActions action_id, int dik);
ENGINE_API int GetActionDik(EGameActions action_id, int idx = -1);
ENGINE_API EGameActions GetBindedAction(int dik);
ENGINE_API EGameActions GetBindedAction(int dik, EKeyContext context = EKeyContext::Undefined);

ENGINE_API pcstr GetActionBinding(EGameActions action);

Expand Down
5 changes: 4 additions & 1 deletion src/xrGame/ui/UIEditKeyBind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,10 @@ void CUIEditKeyBind::OnMessage(LPCSTR message)
return; // fuck

game_action* other_action = ActionNameToPtr(command);
if (IsGroupNotConflicted(m_action->key_group, other_action->key_group))

bool no_conflict = IsGroupNotConflicted(m_action->key_group, other_action->key_group);
no_conflict &= IsContextNotConflicted(m_action->key_context, other_action->key_context);
if (no_conflict)
return;

SetText("---");
Expand Down

0 comments on commit 5f9ca4b

Please sign in to comment.