mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 22:48:18 +00:00
Merge pull request #1589 from Dune-jr/feature-complexbinds
Implement composed binds (Ctrl, Shift, Alt); adapt controls menus.
This commit is contained in:
commit
bb544ca3ae
|
@ -4,7 +4,7 @@
|
||||||
#include <engine/shared/config.h>
|
#include <engine/shared/config.h>
|
||||||
#include "binds.h"
|
#include "binds.h"
|
||||||
|
|
||||||
const int CBinds::s_aDefaultBindKeys[] = {
|
const int CBinds::s_aDefaultBindKeys[] = { // only simple binds
|
||||||
KEY_F1, KEY_F2, KEY_TAB, 'u', KEY_F10,
|
KEY_F1, KEY_F2, KEY_TAB, 'u', KEY_F10,
|
||||||
'a', 'd',
|
'a', 'd',
|
||||||
KEY_SPACE, KEY_MOUSE_1, KEY_MOUSE_2, KEY_LSHIFT, KEY_RSHIFT, KEY_RIGHT, KEY_LEFT,
|
KEY_SPACE, KEY_MOUSE_1, KEY_MOUSE_2, KEY_LSHIFT, KEY_RSHIFT, KEY_RIGHT, KEY_LEFT,
|
||||||
|
@ -25,82 +25,156 @@ const char CBinds::s_aaDefaultBindValues[][32] = {
|
||||||
"ready_change",
|
"ready_change",
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CBinds::CBindsSpecial::OnInput(IInput::CEvent Event)
|
|
||||||
{
|
|
||||||
// don't handle invalid events and keys that arn't set to anything
|
|
||||||
if(((Event.m_Key >= KEY_F1 && Event.m_Key <= KEY_F12) || (Event.m_Key >= KEY_F13 && Event.m_Key <= KEY_F24)) && m_pBinds->m_aaKeyBindings[Event.m_Key][0] != 0)
|
|
||||||
{
|
|
||||||
int Stroke = 0;
|
|
||||||
if(Event.m_Flags&IInput::FLAG_PRESS)
|
|
||||||
Stroke = 1;
|
|
||||||
|
|
||||||
m_pBinds->GetConsole()->ExecuteLineStroked(Stroke, m_pBinds->m_aaKeyBindings[Event.m_Key]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CBinds::CBinds()
|
CBinds::CBinds()
|
||||||
{
|
{
|
||||||
mem_zero(m_aaKeyBindings, sizeof(m_aaKeyBindings));
|
mem_zero(m_aaaKeyBindings, sizeof(m_aaaKeyBindings));
|
||||||
m_SpecialBinds.m_pBinds = this;
|
m_SpecialBinds.m_pBinds = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBinds::Bind(int KeyID, const char *pStr)
|
void CBinds::Bind(int KeyID, int Modifier, const char *pStr)
|
||||||
{
|
{
|
||||||
if(KeyID < 0 || KeyID >= KEY_LAST)
|
if(KeyID < 0 || KeyID >= KEY_LAST)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
str_copy(m_aaKeyBindings[KeyID], pStr, sizeof(m_aaKeyBindings[KeyID]));
|
str_copy(m_aaaKeyBindings[KeyID][Modifier], pStr, sizeof(m_aaaKeyBindings[KeyID][Modifier]));
|
||||||
char aBuf[256];
|
char aBuf[256];
|
||||||
if(!m_aaKeyBindings[KeyID][0])
|
if(!m_aaaKeyBindings[KeyID][Modifier][0])
|
||||||
str_format(aBuf, sizeof(aBuf), "unbound %s (%d)", Input()->KeyName(KeyID), KeyID);
|
str_format(aBuf, sizeof(aBuf), "unbound %s%s (%d)", GetModifierName(Modifier),Input()->KeyName(KeyID), KeyID);
|
||||||
else
|
else
|
||||||
str_format(aBuf, sizeof(aBuf), "bound %s (%d) = %s", Input()->KeyName(KeyID), KeyID, m_aaKeyBindings[KeyID]);
|
str_format(aBuf, sizeof(aBuf), "bound %s%s (%d) = %s", GetModifierName(Modifier),Input()->KeyName(KeyID), KeyID, m_aaaKeyBindings[KeyID][Modifier]);
|
||||||
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf);
|
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CBinds::GetModifierMask(IInput *i)
|
||||||
bool CBinds::OnInput(IInput::CEvent e)
|
|
||||||
{
|
{
|
||||||
// don't handle invalid events and keys that arn't set to anything
|
int Mask = 0;
|
||||||
if(e.m_Key <= 0 || e.m_Key >= KEY_LAST || m_aaKeyBindings[e.m_Key][0] == 0)
|
// since we only handle one modifier, when doing ctrl+q and shift+q, execute both
|
||||||
|
Mask |= i->KeyIsPressed(KEY_LSHIFT) << CBinds::MODIFIER_SHIFT;
|
||||||
|
Mask |= i->KeyIsPressed(KEY_RSHIFT) << CBinds::MODIFIER_SHIFT;
|
||||||
|
Mask |= i->KeyIsPressed(KEY_LCTRL) << CBinds::MODIFIER_CTRL;
|
||||||
|
Mask |= i->KeyIsPressed(KEY_RCTRL) << CBinds::MODIFIER_CTRL;
|
||||||
|
Mask |= i->KeyIsPressed(KEY_LALT) << CBinds::MODIFIER_ALT;
|
||||||
|
if(Mask == 0)
|
||||||
|
return 1; // if no modifier, flag with MODIFIER_NONE
|
||||||
|
return Mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CBinds::GetModifierMaskOfKey(int Key)
|
||||||
|
{
|
||||||
|
switch(Key)
|
||||||
|
{
|
||||||
|
case KEY_LSHIFT:
|
||||||
|
case KEY_RSHIFT:
|
||||||
|
return 1 << CBinds::MODIFIER_SHIFT;
|
||||||
|
case KEY_LCTRL:
|
||||||
|
case KEY_RCTRL:
|
||||||
|
return 1 << CBinds::MODIFIER_CTRL;
|
||||||
|
case KEY_LALT:
|
||||||
|
return 1 << CBinds::MODIFIER_ALT;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBinds::ModifierMatchesKey(int Modifier, int Key)
|
||||||
|
{
|
||||||
|
switch(Modifier)
|
||||||
|
{
|
||||||
|
case MODIFIER_SHIFT:
|
||||||
|
return Key == KEY_LSHIFT || Key == KEY_RSHIFT;
|
||||||
|
case MODIFIER_CTRL:
|
||||||
|
return Key == KEY_LCTRL || Key == KEY_RCTRL;
|
||||||
|
case MODIFIER_ALT:
|
||||||
|
return Key == KEY_LALT;
|
||||||
|
case MODIFIER_NONE:
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBinds::CBindsSpecial::OnInput(IInput::CEvent Event)
|
||||||
|
{
|
||||||
|
int Mask = GetModifierMask(Input());
|
||||||
|
|
||||||
|
// don't handle anything but FX and composed FX binds
|
||||||
|
if(/*Mask == 1 && */!(Event.m_Key >= KEY_F1 && Event.m_Key <= KEY_F12) && !(Event.m_Key >= KEY_F13 && Event.m_Key <= KEY_F24))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(e.m_Flags&IInput::FLAG_PRESS)
|
bool rtn = false;
|
||||||
Console()->ExecuteLineStroked(1, m_aaKeyBindings[e.m_Key]);
|
for(int m = 0; m < MODIFIER_COUNT; m++)
|
||||||
if(e.m_Flags&IInput::FLAG_RELEASE)
|
{
|
||||||
Console()->ExecuteLineStroked(0, m_aaKeyBindings[e.m_Key]);
|
if((Mask&(1 << m)) && m_pBinds->m_aaaKeyBindings[Event.m_Key][m][0] != 0)
|
||||||
return true;
|
{
|
||||||
|
if(Event.m_Flags&IInput::FLAG_PRESS)
|
||||||
|
m_pBinds->GetConsole()->ExecuteLineStroked(1, m_pBinds->m_aaaKeyBindings[Event.m_Key][m]);
|
||||||
|
if(Event.m_Flags&IInput::FLAG_RELEASE)
|
||||||
|
m_pBinds->GetConsole()->ExecuteLineStroked(0, m_pBinds->m_aaaKeyBindings[Event.m_Key][m]);
|
||||||
|
rtn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CBinds::OnInput(IInput::CEvent Event)
|
||||||
|
{
|
||||||
|
// don't handle invalid events and keys that aren't set to anything
|
||||||
|
if(Event.m_Key <= 0 || Event.m_Key >= KEY_LAST)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int Mask = GetModifierMask(Input());
|
||||||
|
int KeyModifierMask = GetModifierMaskOfKey(Event.m_Key); // returns 0 if m_Key is not a modifier
|
||||||
|
if(KeyModifierMask)
|
||||||
|
{
|
||||||
|
// avoid to have e.g. key press "lshift" be treated as "shift+lshift"
|
||||||
|
Mask -= KeyModifierMask;
|
||||||
|
if(!Mask)
|
||||||
|
Mask = 1 << MODIFIER_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rtn = false;
|
||||||
|
for(int m = 0; m < MODIFIER_COUNT; m++)
|
||||||
|
{
|
||||||
|
if((Mask&(1 << m)) && m_aaaKeyBindings[Event.m_Key][m][0] != 0)
|
||||||
|
{
|
||||||
|
if(Event.m_Flags&IInput::FLAG_PRESS)
|
||||||
|
Console()->ExecuteLineStroked(1, m_aaaKeyBindings[Event.m_Key][m]);
|
||||||
|
if(Event.m_Flags&IInput::FLAG_RELEASE)
|
||||||
|
Console()->ExecuteLineStroked(0, m_aaaKeyBindings[Event.m_Key][m]);
|
||||||
|
rtn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBinds::UnbindAll()
|
void CBinds::UnbindAll()
|
||||||
{
|
{
|
||||||
for(int i = 0; i < KEY_LAST; i++)
|
for(int i = 0; i < KEY_LAST; i++)
|
||||||
m_aaKeyBindings[i][0] = 0;
|
for(int m = 0; m < MODIFIER_COUNT; m++)
|
||||||
|
m_aaaKeyBindings[i][m][0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *CBinds::Get(int KeyID)
|
const char *CBinds::Get(int KeyID, int Modifier)
|
||||||
{
|
{
|
||||||
if(KeyID > 0 && KeyID < KEY_LAST)
|
if(KeyID > 0 && KeyID < KEY_LAST)
|
||||||
return m_aaKeyBindings[KeyID];
|
return m_aaaKeyBindings[KeyID][Modifier];
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *CBinds::GetKey(const char *pBindStr)
|
void CBinds::GetKey(const char *pBindStr, char aBuf[64], unsigned BufSize)
|
||||||
{
|
{
|
||||||
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
|
aBuf[0] = 0;
|
||||||
|
for(int KeyID = 0; KeyID < KEY_LAST; KeyID++)
|
||||||
{
|
{
|
||||||
const char *pBind = Get(KeyId);
|
for(int m = 0; m < MODIFIER_COUNT; m++)
|
||||||
|
{
|
||||||
|
const char *pBind = Get(KeyID, m);
|
||||||
if(!pBind[0])
|
if(!pBind[0])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(str_comp(pBind, pBindStr) == 0)
|
if(str_comp(pBind, pBindStr) == 0)
|
||||||
return Input()->KeyName(KeyId);
|
str_format(aBuf, BufSize, "key %s%s not found", Input()->KeyName(KeyID), GetModifierName(m));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBinds::SetDefaults()
|
void CBinds::SetDefaults()
|
||||||
|
@ -110,7 +184,7 @@ void CBinds::SetDefaults()
|
||||||
const int count = sizeof(s_aDefaultBindKeys)/sizeof(int);
|
const int count = sizeof(s_aDefaultBindKeys)/sizeof(int);
|
||||||
dbg_assert(count == sizeof(s_aaDefaultBindValues)/32, "the count of bind keys differs from that of bind values!");
|
dbg_assert(count == sizeof(s_aaDefaultBindValues)/32, "the count of bind keys differs from that of bind values!");
|
||||||
for(int i = 0; i < count; i++)
|
for(int i = 0; i < count; i++)
|
||||||
Bind(s_aDefaultBindKeys[i], s_aaDefaultBindValues[i]);
|
Bind(s_aDefaultBindKeys[i], MODIFIER_NONE, s_aaDefaultBindValues[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBinds::OnConsoleInit()
|
void CBinds::OnConsoleInit()
|
||||||
|
@ -133,7 +207,8 @@ void CBinds::ConBind(IConsole::IResult *pResult, void *pUserData)
|
||||||
{
|
{
|
||||||
CBinds *pBinds = (CBinds *)pUserData;
|
CBinds *pBinds = (CBinds *)pUserData;
|
||||||
const char *pKeyName = pResult->GetString(0);
|
const char *pKeyName = pResult->GetString(0);
|
||||||
int id = pBinds->GetKeyID(pKeyName);
|
int Modifier;
|
||||||
|
int id = pBinds->DecodeBindString(pKeyName, &Modifier);
|
||||||
|
|
||||||
if(!id)
|
if(!id)
|
||||||
{
|
{
|
||||||
|
@ -143,7 +218,7 @@ void CBinds::ConBind(IConsole::IResult *pResult, void *pUserData)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pBinds->Bind(id, pResult->GetString(1));
|
pBinds->Bind(id, Modifier, pResult->GetString(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -151,7 +226,8 @@ void CBinds::ConUnbind(IConsole::IResult *pResult, void *pUserData)
|
||||||
{
|
{
|
||||||
CBinds *pBinds = (CBinds *)pUserData;
|
CBinds *pBinds = (CBinds *)pUserData;
|
||||||
const char *pKeyName = pResult->GetString(0);
|
const char *pKeyName = pResult->GetString(0);
|
||||||
int id = pBinds->GetKeyID(pKeyName);
|
int Modifier;
|
||||||
|
int id = pBinds->DecodeBindString(pKeyName, &Modifier);
|
||||||
|
|
||||||
if(!id)
|
if(!id)
|
||||||
{
|
{
|
||||||
|
@ -161,7 +237,7 @@ void CBinds::ConUnbind(IConsole::IResult *pResult, void *pUserData)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pBinds->Bind(id, "");
|
pBinds->Bind(id, Modifier, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -178,15 +254,40 @@ void CBinds::ConDumpBinds(IConsole::IResult *pResult, void *pUserData)
|
||||||
char aBuf[1024];
|
char aBuf[1024];
|
||||||
for(int i = 0; i < KEY_LAST; i++)
|
for(int i = 0; i < KEY_LAST; i++)
|
||||||
{
|
{
|
||||||
if(pBinds->m_aaKeyBindings[i][0] == 0)
|
for(int m = 0; m < MODIFIER_COUNT; m++)
|
||||||
|
{
|
||||||
|
if(pBinds->m_aaaKeyBindings[i][m][0] == 0)
|
||||||
continue;
|
continue;
|
||||||
str_format(aBuf, sizeof(aBuf), "%s (%d) = %s", pBinds->Input()->KeyName(i), i, pBinds->m_aaKeyBindings[i]);
|
str_format(aBuf, sizeof(aBuf), "%s%s (%d) = %s", GetModifierName(m), pBinds->Input()->KeyName(i), i, pBinds->m_aaaKeyBindings[i][m]);
|
||||||
pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf);
|
pBinds->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "binds", aBuf);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int CBinds::GetKeyID(const char *pKeyName)
|
int CBinds::DecodeBindString(const char *pKeyName, int* pModifier)
|
||||||
{
|
{
|
||||||
|
// check for modifier of type xxx+xxx
|
||||||
|
char aBuf[64];
|
||||||
|
str_copy(aBuf, pKeyName, sizeof(aBuf));
|
||||||
|
const char* pStr = str_find(aBuf, "+");
|
||||||
|
*pModifier = 0;
|
||||||
|
if(pStr && *(pStr+1)) // make sure the '+' isn't the last character
|
||||||
|
{
|
||||||
|
aBuf[pStr-aBuf] = 0; // *pStr=0 (split the string where the + is)
|
||||||
|
char* pModifierStr = aBuf;
|
||||||
|
if(str_comp(pModifierStr, "shift") == 0)
|
||||||
|
*pModifier = MODIFIER_SHIFT;
|
||||||
|
else if(str_comp(pModifierStr, "ctrl") == 0)
|
||||||
|
*pModifier = MODIFIER_CTRL;
|
||||||
|
else if(str_comp(pModifierStr, "alt") == 0)
|
||||||
|
*pModifier = MODIFIER_ALT;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
pKeyName = pStr + 1;
|
||||||
|
if(!pKeyName)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// check for numeric
|
// check for numeric
|
||||||
if(pKeyName[0] == '&')
|
if(pKeyName[0] == '&')
|
||||||
{
|
{
|
||||||
|
@ -205,6 +306,24 @@ int CBinds::GetKeyID(const char *pKeyName)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *CBinds::GetModifierName(int m)
|
||||||
|
{
|
||||||
|
switch(m)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "";
|
||||||
|
case MODIFIER_SHIFT:
|
||||||
|
return "shift+";
|
||||||
|
case MODIFIER_CTRL:
|
||||||
|
return "ctrl+";
|
||||||
|
case MODIFIER_ALT:
|
||||||
|
return "alt+";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CBinds::ConfigSaveCallback(IConfig *pConfig, void *pUserData)
|
void CBinds::ConfigSaveCallback(IConfig *pConfig, void *pUserData)
|
||||||
{
|
{
|
||||||
CBinds *pSelf = (CBinds *)pUserData;
|
CBinds *pSelf = (CBinds *)pUserData;
|
||||||
|
@ -213,13 +332,15 @@ void CBinds::ConfigSaveCallback(IConfig *pConfig, void *pUserData)
|
||||||
char *pEnd = aBuffer+sizeof(aBuffer)-8;
|
char *pEnd = aBuffer+sizeof(aBuffer)-8;
|
||||||
for(int i = 0; i < KEY_LAST; i++)
|
for(int i = 0; i < KEY_LAST; i++)
|
||||||
{
|
{
|
||||||
if(pSelf->m_aaKeyBindings[i][0] == 0)
|
for(int m = 0; m < MODIFIER_COUNT; m++)
|
||||||
|
{
|
||||||
|
if(pSelf->m_aaaKeyBindings[i][m][0] == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
str_format(aBuffer, sizeof(aBuffer), "bind %s ", pSelf->Input()->KeyName(i));
|
str_format(aBuffer, sizeof(aBuffer), "bind %s%s ", GetModifierName(m), pSelf->Input()->KeyName(i));
|
||||||
|
|
||||||
// process the string. we need to escape some characters
|
// process the string. we need to escape some characters
|
||||||
const char *pSrc = pSelf->m_aaKeyBindings[i];
|
const char *pSrc = pSelf->m_aaaKeyBindings[i][m];
|
||||||
char *pDst = aBuffer + str_length(aBuffer);
|
char *pDst = aBuffer + str_length(aBuffer);
|
||||||
*pDst++ = '"';
|
*pDst++ = '"';
|
||||||
while(*pSrc && pDst < pEnd)
|
while(*pSrc && pDst < pEnd)
|
||||||
|
@ -233,11 +354,13 @@ void CBinds::ConfigSaveCallback(IConfig *pConfig, void *pUserData)
|
||||||
|
|
||||||
pConfig->WriteLine(aBuffer);
|
pConfig->WriteLine(aBuffer);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// default binds can only be non-composed right now, so only check for that
|
||||||
for(unsigned j = 0; j < sizeof(s_aDefaultBindKeys)/sizeof(int); j++)
|
for(unsigned j = 0; j < sizeof(s_aDefaultBindKeys)/sizeof(int); j++)
|
||||||
{
|
{
|
||||||
const int i = s_aDefaultBindKeys[j];
|
const int i = s_aDefaultBindKeys[j];
|
||||||
if(pSelf->m_aaKeyBindings[i][0] == 0)
|
if(pSelf->m_aaaKeyBindings[i][0][0] == 0)
|
||||||
{
|
{
|
||||||
// explicitly unbind keys that were unbound by the user
|
// explicitly unbind keys that were unbound by the user
|
||||||
str_format(aBuffer, sizeof(aBuffer), "unbind %s ", pSelf->Input()->KeyName(i));
|
str_format(aBuffer, sizeof(aBuffer), "unbind %s ", pSelf->Input()->KeyName(i));
|
||||||
|
|
|
@ -7,9 +7,7 @@
|
||||||
|
|
||||||
class CBinds : public CComponent
|
class CBinds : public CComponent
|
||||||
{
|
{
|
||||||
char m_aaKeyBindings[KEY_LAST][128];
|
int DecodeBindString(const char *pKeyName, int* pModifier);
|
||||||
|
|
||||||
int GetKeyID(const char *pKeyName);
|
|
||||||
|
|
||||||
static void ConBind(IConsole::IResult *pResult, void *pUserData);
|
static void ConBind(IConsole::IResult *pResult, void *pUserData);
|
||||||
static void ConUnbind(IConsole::IResult *pResult, void *pUserData);
|
static void ConUnbind(IConsole::IResult *pResult, void *pUserData);
|
||||||
|
@ -29,18 +27,32 @@ public:
|
||||||
virtual bool OnInput(IInput::CEvent Event);
|
virtual bool OnInput(IInput::CEvent Event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MODIFIER_NONE=0,
|
||||||
|
MODIFIER_SHIFT,
|
||||||
|
MODIFIER_CTRL,
|
||||||
|
MODIFIER_ALT,
|
||||||
|
MODIFIER_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
CBindsSpecial m_SpecialBinds;
|
CBindsSpecial m_SpecialBinds;
|
||||||
|
|
||||||
void Bind(int KeyID, const char *pStr);
|
void Bind(int KeyID, int Modifier, const char *pStr);
|
||||||
void SetDefaults();
|
void SetDefaults();
|
||||||
void UnbindAll();
|
void UnbindAll();
|
||||||
const char *Get(int KeyID);
|
const char *Get(int KeyID, int Modifier);
|
||||||
const char *GetKey(const char *pBindStr);
|
void GetKey(const char *pBindStr, char aBuf[64], unsigned BufSize);
|
||||||
|
static const char *GetModifierName(int m);
|
||||||
|
static int GetModifierMask(IInput *i);
|
||||||
|
static int GetModifierMaskOfKey(int Key);
|
||||||
|
static bool ModifierMatchesKey(int Modifier, int Key);
|
||||||
|
|
||||||
virtual void OnConsoleInit();
|
virtual void OnConsoleInit();
|
||||||
virtual bool OnInput(IInput::CEvent Event);
|
virtual bool OnInput(IInput::CEvent Event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
char m_aaaKeyBindings[KEY_LAST][MODIFIER_COUNT][128];
|
||||||
static const int s_aDefaultBindKeys[];
|
static const int s_aDefaultBindKeys[];
|
||||||
static const char s_aaDefaultBindValues[][32];
|
static const char s_aaDefaultBindValues[][32];
|
||||||
};
|
};
|
||||||
|
|
|
@ -450,13 +450,14 @@ void CHud::RenderVoting()
|
||||||
CUIRect Base = {5, 88, 100, 4};
|
CUIRect Base = {5, 88, 100, 4};
|
||||||
m_pClient->m_pVoting->RenderBars(Base, false);
|
m_pClient->m_pVoting->RenderBars(Base, false);
|
||||||
|
|
||||||
const char *pYesKey = m_pClient->m_pBinds->GetKey("vote yes");
|
char aBufYes[64], aBufNo[64];
|
||||||
const char *pNoKey = m_pClient->m_pBinds->GetKey("vote no");
|
m_pClient->m_pBinds->GetKey("vote yes", aBufYes, sizeof(aBufYes));
|
||||||
str_format(aBuf, sizeof(aBuf), "%s - %s", pYesKey, Localize("Vote yes"));
|
m_pClient->m_pBinds->GetKey("vote no", aBufNo, sizeof(aBufNo));
|
||||||
|
str_format(aBuf, sizeof(aBuf), "%s - %s", aBufYes, Localize("Vote yes"));
|
||||||
Base.y += Base.h+1;
|
Base.y += Base.h+1;
|
||||||
UI()->DoLabel(&Base, aBuf, 6.0f, CUI::ALIGN_LEFT);
|
UI()->DoLabel(&Base, aBuf, 6.0f, CUI::ALIGN_LEFT);
|
||||||
|
|
||||||
str_format(aBuf, sizeof(aBuf), "%s - %s", Localize("Vote no"), pNoKey);
|
str_format(aBuf, sizeof(aBuf), "%s - %s", Localize("Vote no"), aBufNo);
|
||||||
UI()->DoLabel(&Base, aBuf, 6.0f, CUI::ALIGN_RIGHT);
|
UI()->DoLabel(&Base, aBuf, 6.0f, CUI::ALIGN_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <generated/protocol.h>
|
#include <generated/protocol.h>
|
||||||
|
|
||||||
#include <generated/client_data.h>
|
#include <generated/client_data.h>
|
||||||
|
#include <game/client/components/binds.h>
|
||||||
#include <game/client/components/camera.h>
|
#include <game/client/components/camera.h>
|
||||||
#include <game/client/components/console.h>
|
#include <game/client/components/console.h>
|
||||||
#include <game/client/components/sounds.h>
|
#include <game/client/components/sounds.h>
|
||||||
|
@ -1021,7 +1022,7 @@ int CMenus::UiDoListboxEnd(CListBoxState* pState, bool *pItemActivated)
|
||||||
return pState->m_ListBoxNewSelected;
|
return pState->m_ListBoxNewSelected;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CMenus::DoKeyReader(CButtonContainer *pBC, const CUIRect *pRect, int Key)
|
int CMenus::DoKeyReader(CButtonContainer *pBC, const CUIRect *pRect, int Key, int Modifier, int* NewModifier)
|
||||||
{
|
{
|
||||||
// process
|
// process
|
||||||
static const void *pGrabbedID = 0;
|
static const void *pGrabbedID = 0;
|
||||||
|
@ -1029,6 +1030,7 @@ int CMenus::DoKeyReader(CButtonContainer *pBC, const CUIRect *pRect, int Key)
|
||||||
static int ButtonUsed = 0;
|
static int ButtonUsed = 0;
|
||||||
int Inside = UI()->MouseInside(pRect) && UI()->MouseInsideClip();
|
int Inside = UI()->MouseInside(pRect) && UI()->MouseInsideClip();
|
||||||
int NewKey = Key;
|
int NewKey = Key;
|
||||||
|
*NewModifier = Modifier;
|
||||||
|
|
||||||
if(!UI()->MouseButton(0) && !UI()->MouseButton(1) && pGrabbedID == pBC->GetID())
|
if(!UI()->MouseButton(0) && !UI()->MouseButton(1) && pGrabbedID == pBC->GetID())
|
||||||
MouseReleased = true;
|
MouseReleased = true;
|
||||||
|
@ -1039,7 +1041,10 @@ int CMenus::DoKeyReader(CButtonContainer *pBC, const CUIRect *pRect, int Key)
|
||||||
{
|
{
|
||||||
// abort with escape key
|
// abort with escape key
|
||||||
if(m_Binder.m_Key.m_Key != KEY_ESCAPE)
|
if(m_Binder.m_Key.m_Key != KEY_ESCAPE)
|
||||||
|
{
|
||||||
NewKey = m_Binder.m_Key.m_Key;
|
NewKey = m_Binder.m_Key.m_Key;
|
||||||
|
*NewModifier = m_Binder.m_Modifier;
|
||||||
|
}
|
||||||
m_Binder.m_GotKey = false;
|
m_Binder.m_GotKey = false;
|
||||||
UI()->SetActiveItem(0);
|
UI()->SetActiveItem(0);
|
||||||
MouseReleased = false;
|
MouseReleased = false;
|
||||||
|
@ -1084,7 +1089,11 @@ int CMenus::DoKeyReader(CButtonContainer *pBC, const CUIRect *pRect, int Key)
|
||||||
if(Key == 0)
|
if(Key == 0)
|
||||||
DoButton_KeySelect(pBC, "", 0, pRect);
|
DoButton_KeySelect(pBC, "", 0, pRect);
|
||||||
else
|
else
|
||||||
DoButton_KeySelect(pBC, Input()->KeyName(Key), 0, pRect);
|
{
|
||||||
|
char aBuf[64];
|
||||||
|
str_format(aBuf, sizeof(aBuf), "%s%s", CBinds::GetModifierName(*NewModifier), Input()->KeyName(Key));
|
||||||
|
DoButton_KeySelect(pBC, aBuf, 0, pRect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return NewKey;
|
return NewKey;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ class CMenusKeyBinder : public CComponent
|
||||||
public:
|
public:
|
||||||
bool m_TakeKey;
|
bool m_TakeKey;
|
||||||
bool m_GotKey;
|
bool m_GotKey;
|
||||||
|
int m_Modifier;
|
||||||
IInput::CEvent m_Key;
|
IInput::CEvent m_Key;
|
||||||
CMenusKeyBinder();
|
CMenusKeyBinder();
|
||||||
virtual bool OnInput(IInput::CEvent Event);
|
virtual bool OnInput(IInput::CEvent Event);
|
||||||
|
@ -91,7 +92,7 @@ private:
|
||||||
float DoScrollbarV(const void *pID, const CUIRect *pRect, float Current);
|
float DoScrollbarV(const void *pID, const CUIRect *pRect, float Current);
|
||||||
float DoScrollbarH(const void *pID, const CUIRect *pRect, float Current);
|
float DoScrollbarH(const void *pID, const CUIRect *pRect, float Current);
|
||||||
void DoButton_KeySelect(CButtonContainer *pBC, const char *pText, int Checked, const CUIRect *pRect);
|
void DoButton_KeySelect(CButtonContainer *pBC, const char *pText, int Checked, const CUIRect *pRect);
|
||||||
int DoKeyReader(CButtonContainer *pPC, const CUIRect *pRect, int Key);
|
int DoKeyReader(CButtonContainer *pPC, const CUIRect *pRect, int Key, int Modifier, int* NewModifier);
|
||||||
|
|
||||||
//static int ui_do_key_reader(void *id, const CUIRect *rect, int key);
|
//static int ui_do_key_reader(void *id, const CUIRect *rect, int key);
|
||||||
void UiDoGetButtons(int Start, int Stop, CUIRect View, float ButtonHeight, float Spacing);
|
void UiDoGetButtons(int Start, int Stop, CUIRect View, float ButtonHeight, float Spacing);
|
||||||
|
|
|
@ -10,40 +10,41 @@ typedef struct
|
||||||
CLocConstString m_Name;
|
CLocConstString m_Name;
|
||||||
const char *m_pCommand;
|
const char *m_pCommand;
|
||||||
int m_KeyId;
|
int m_KeyId;
|
||||||
|
int m_Modifier;
|
||||||
CMenus::CButtonContainer m_BC;
|
CMenus::CButtonContainer m_BC;
|
||||||
} CKeyInfo;
|
} CKeyInfo;
|
||||||
|
|
||||||
static CKeyInfo gs_aKeys[] =
|
static CKeyInfo gs_aKeys[] =
|
||||||
{
|
{
|
||||||
{ "Move left", "+left", 0}, // Localize - these strings are localized within CLocConstString
|
{ "Move left", "+left", 0, 0}, // Localize - these strings are localized within CLocConstString
|
||||||
{ "Move right", "+right", 0 },
|
{ "Move right", "+right", 0, 0},
|
||||||
{ "Jump", "+jump", 0 },
|
{ "Jump", "+jump", 0, 0},
|
||||||
{ "Fire", "+fire", 0 },
|
{ "Fire", "+fire", 0, 0},
|
||||||
{ "Hook", "+hook", 0 },
|
{ "Hook", "+hook", 0, 0},
|
||||||
{ "Hammer", "+weapon1", 0 },
|
{ "Hammer", "+weapon1", 0, 0},
|
||||||
{ "Pistol", "+weapon2", 0 },
|
{ "Pistol", "+weapon2", 0, 0},
|
||||||
{ "Shotgun", "+weapon3", 0 },
|
{ "Shotgun", "+weapon3", 0, 0},
|
||||||
{ "Grenade", "+weapon4", 0 },
|
{ "Grenade", "+weapon4", 0, 0},
|
||||||
{ "Laser", "+weapon5", 0 },
|
{ "Laser", "+weapon5", 0, 0},
|
||||||
{ "Next weapon", "+nextweapon", 0 },
|
{ "Next weapon", "+nextweapon", 0, 0},
|
||||||
{ "Prev. weapon", "+prevweapon", 0 },
|
{ "Prev. weapon", "+prevweapon", 0, 0},
|
||||||
{ "Vote yes", "vote yes", 0 },
|
{ "Vote yes", "vote yes", 0, 0},
|
||||||
{ "Vote no", "vote no", 0 },
|
{ "Vote no", "vote no", 0, 0},
|
||||||
{ "Chat", "chat all", 0 },
|
{ "Chat", "chat all", 0, 0},
|
||||||
{ "Team chat", "chat team", 0 },
|
{ "Team chat", "chat team", 0, 0},
|
||||||
{ "Whisper", "chat whisper", 0 },
|
{ "Whisper", "chat whisper", 0, 0},
|
||||||
{ "Show chat", "+show_chat", 0 },
|
{ "Show chat", "+show_chat", 0, 0},
|
||||||
{ "Emoticon", "+emote", 0 },
|
{ "Emoticon", "+emote", 0, 0},
|
||||||
{ "Spectator mode", "+spectate", 0 },
|
{ "Spectator mode", "+spectate", 0, 0},
|
||||||
{ "Spectate next", "spectate_next", 0 },
|
{ "Spectate next", "spectate_next", 0, 0},
|
||||||
{ "Spectate previous", "spectate_previous", 0 },
|
{ "Spectate previous", "spectate_previous", 0, 0},
|
||||||
{ "Console", "toggle_local_console", 0 },
|
{ "Console", "toggle_local_console", 0, 0},
|
||||||
{ "Remote console", "toggle_remote_console", 0 },
|
{ "Remote console", "toggle_remote_console", 0, 0},
|
||||||
{ "Screenshot", "screenshot", 0 },
|
{ "Screenshot", "screenshot", 0, 0},
|
||||||
{ "Scoreboard", "+scoreboard", 0 },
|
{ "Scoreboard", "+scoreboard", 0, 0},
|
||||||
{ "Respawn", "kill", 0 },
|
{ "Respawn", "kill", 0, 0},
|
||||||
{ "Ready", "ready_change", 0 },
|
{ "Ready", "ready_change", 0, 0},
|
||||||
{ "Add demo marker", "add_demomarker", 0},
|
{ "Add demo marker", "add_demomarker", 0, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This is for scripts/update_localization.py to work, don't remove!
|
/* This is for scripts/update_localization.py to work, don't remove!
|
||||||
|
@ -74,14 +75,14 @@ void CMenus::UiDoGetButtons(int Start, int Stop, CUIRect View, float ButtonHeigh
|
||||||
|
|
||||||
Label.y += 2.0f;
|
Label.y += 2.0f;
|
||||||
UI()->DoLabelScaled(&Label, aBuf, 13.0f, CUI::ALIGN_CENTER);
|
UI()->DoLabelScaled(&Label, aBuf, 13.0f, CUI::ALIGN_CENTER);
|
||||||
int OldId = Key.m_KeyId;
|
int OldId = Key.m_KeyId, OldModifier = Key.m_Modifier, NewModifier;
|
||||||
int NewId = DoKeyReader(&gs_aKeys[i].m_BC, &Button, OldId);
|
int NewId = DoKeyReader(&gs_aKeys[i].m_BC, &Button, OldId, OldModifier, &NewModifier);
|
||||||
if(NewId != OldId)
|
if(NewId != OldId || NewModifier != OldModifier)
|
||||||
{
|
{
|
||||||
if(OldId != 0 || NewId == 0)
|
if(OldId != 0 || NewId == 0)
|
||||||
m_pClient->m_pBinds->Bind(OldId, "");
|
m_pClient->m_pBinds->Bind(OldId, OldModifier, "");
|
||||||
if(NewId != 0)
|
if(NewId != 0)
|
||||||
m_pClient->m_pBinds->Bind(NewId, gs_aKeys[i].m_pCommand);
|
m_pClient->m_pBinds->Bind(NewId, NewModifier, gs_aKeys[i].m_pCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,11 +93,16 @@ float CMenus::RenderSettingsControlsMovement(CUIRect View, void *pUser)
|
||||||
|
|
||||||
// this is kinda slow, but whatever
|
// this is kinda slow, but whatever
|
||||||
for(int i = 0; i < g_KeyCount; i++)
|
for(int i = 0; i < g_KeyCount; i++)
|
||||||
|
{
|
||||||
gs_aKeys[i].m_KeyId = 0;
|
gs_aKeys[i].m_KeyId = 0;
|
||||||
|
gs_aKeys[i].m_Modifier = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
|
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
|
||||||
{
|
{
|
||||||
const char *pBind = pSelf->m_pClient->m_pBinds->Get(KeyId);
|
for(int m = 0; m < CBinds::MODIFIER_COUNT; m++)
|
||||||
|
{
|
||||||
|
const char *pBind = pSelf->m_pClient->m_pBinds->Get(KeyId, m);
|
||||||
if(!pBind[0])
|
if(!pBind[0])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -104,9 +110,11 @@ float CMenus::RenderSettingsControlsMovement(CUIRect View, void *pUser)
|
||||||
if(str_comp(pBind, gs_aKeys[i].m_pCommand) == 0)
|
if(str_comp(pBind, gs_aKeys[i].m_pCommand) == 0)
|
||||||
{
|
{
|
||||||
gs_aKeys[i].m_KeyId = KeyId;
|
gs_aKeys[i].m_KeyId = KeyId;
|
||||||
|
gs_aKeys[i].m_Modifier = m;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int NumOptions = 6;
|
int NumOptions = 6;
|
||||||
float ButtonHeight = 20.0f;
|
float ButtonHeight = 20.0f;
|
||||||
|
@ -132,11 +140,16 @@ float CMenus::RenderSettingsControlsWeapon(CUIRect View, void *pUser)
|
||||||
|
|
||||||
// this is kinda slow, but whatever
|
// this is kinda slow, but whatever
|
||||||
for(int i = 0; i < g_KeyCount; i++)
|
for(int i = 0; i < g_KeyCount; i++)
|
||||||
|
{
|
||||||
gs_aKeys[i].m_KeyId = 0;
|
gs_aKeys[i].m_KeyId = 0;
|
||||||
|
gs_aKeys[i].m_Modifier = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
|
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
|
||||||
{
|
{
|
||||||
const char *pBind = pSelf->m_pClient->m_pBinds->Get(KeyId);
|
for(int m = 0; m < CBinds::MODIFIER_COUNT; m++)
|
||||||
|
{
|
||||||
|
const char *pBind = pSelf->m_pClient->m_pBinds->Get(KeyId, m);
|
||||||
if(!pBind[0])
|
if(!pBind[0])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -144,9 +157,11 @@ float CMenus::RenderSettingsControlsWeapon(CUIRect View, void *pUser)
|
||||||
if(str_comp(pBind, gs_aKeys[i].m_pCommand) == 0)
|
if(str_comp(pBind, gs_aKeys[i].m_pCommand) == 0)
|
||||||
{
|
{
|
||||||
gs_aKeys[i].m_KeyId = KeyId;
|
gs_aKeys[i].m_KeyId = KeyId;
|
||||||
|
gs_aKeys[i].m_Modifier = m;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int NumOptions = 7;
|
int NumOptions = 7;
|
||||||
float ButtonHeight = 20.0f;
|
float ButtonHeight = 20.0f;
|
||||||
|
@ -167,11 +182,16 @@ float CMenus::RenderSettingsControlsVoting(CUIRect View, void *pUser)
|
||||||
|
|
||||||
// this is kinda slow, but whatever
|
// this is kinda slow, but whatever
|
||||||
for(int i = 0; i < g_KeyCount; i++)
|
for(int i = 0; i < g_KeyCount; i++)
|
||||||
|
{
|
||||||
gs_aKeys[i].m_KeyId = 0;
|
gs_aKeys[i].m_KeyId = 0;
|
||||||
|
gs_aKeys[i].m_Modifier = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
|
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
|
||||||
{
|
{
|
||||||
const char *pBind = pSelf->m_pClient->m_pBinds->Get(KeyId);
|
for(int m = 0; m < CBinds::MODIFIER_COUNT; m++)
|
||||||
|
{
|
||||||
|
const char *pBind = pSelf->m_pClient->m_pBinds->Get(KeyId, m);
|
||||||
if(!pBind[0])
|
if(!pBind[0])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -179,9 +199,11 @@ float CMenus::RenderSettingsControlsVoting(CUIRect View, void *pUser)
|
||||||
if(str_comp(pBind, gs_aKeys[i].m_pCommand) == 0)
|
if(str_comp(pBind, gs_aKeys[i].m_pCommand) == 0)
|
||||||
{
|
{
|
||||||
gs_aKeys[i].m_KeyId = KeyId;
|
gs_aKeys[i].m_KeyId = KeyId;
|
||||||
|
gs_aKeys[i].m_Modifier = m;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int NumOptions = 2;
|
int NumOptions = 2;
|
||||||
float ButtonHeight = 20.0f;
|
float ButtonHeight = 20.0f;
|
||||||
|
@ -202,11 +224,16 @@ float CMenus::RenderSettingsControlsChat(CUIRect View, void *pUser)
|
||||||
|
|
||||||
// this is kinda slow, but whatever
|
// this is kinda slow, but whatever
|
||||||
for(int i = 0; i < g_KeyCount; i++)
|
for(int i = 0; i < g_KeyCount; i++)
|
||||||
|
{
|
||||||
gs_aKeys[i].m_KeyId = 0;
|
gs_aKeys[i].m_KeyId = 0;
|
||||||
|
gs_aKeys[i].m_Modifier = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
|
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
|
||||||
{
|
{
|
||||||
const char *pBind = pSelf->m_pClient->m_pBinds->Get(KeyId);
|
for(int m = 0; m < CBinds::MODIFIER_COUNT; m++)
|
||||||
|
{
|
||||||
|
const char *pBind = pSelf->m_pClient->m_pBinds->Get(KeyId, m);
|
||||||
if(!pBind[0])
|
if(!pBind[0])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -214,9 +241,11 @@ float CMenus::RenderSettingsControlsChat(CUIRect View, void *pUser)
|
||||||
if(str_comp(pBind, gs_aKeys[i].m_pCommand) == 0)
|
if(str_comp(pBind, gs_aKeys[i].m_pCommand) == 0)
|
||||||
{
|
{
|
||||||
gs_aKeys[i].m_KeyId = KeyId;
|
gs_aKeys[i].m_KeyId = KeyId;
|
||||||
|
gs_aKeys[i].m_Modifier = m;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int NumOptions = 4;
|
int NumOptions = 4;
|
||||||
float ButtonHeight = 20.0f;
|
float ButtonHeight = 20.0f;
|
||||||
|
@ -237,11 +266,16 @@ float CMenus::RenderSettingsControlsMisc(CUIRect View, void *pUser)
|
||||||
|
|
||||||
// this is kinda slow, but whatever
|
// this is kinda slow, but whatever
|
||||||
for(int i = 0; i < g_KeyCount; i++)
|
for(int i = 0; i < g_KeyCount; i++)
|
||||||
|
{
|
||||||
gs_aKeys[i].m_KeyId = 0;
|
gs_aKeys[i].m_KeyId = 0;
|
||||||
|
gs_aKeys[i].m_Modifier = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
|
for(int KeyId = 0; KeyId < KEY_LAST; KeyId++)
|
||||||
{
|
{
|
||||||
const char *pBind = pSelf->m_pClient->m_pBinds->Get(KeyId);
|
for(int m = 0; m < CBinds::MODIFIER_COUNT; m++)
|
||||||
|
{
|
||||||
|
const char *pBind = pSelf->m_pClient->m_pBinds->Get(KeyId, m);
|
||||||
if(!pBind[0])
|
if(!pBind[0])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -249,9 +283,11 @@ float CMenus::RenderSettingsControlsMisc(CUIRect View, void *pUser)
|
||||||
if(str_comp(pBind, gs_aKeys[i].m_pCommand) == 0)
|
if(str_comp(pBind, gs_aKeys[i].m_pCommand) == 0)
|
||||||
{
|
{
|
||||||
gs_aKeys[i].m_KeyId = KeyId;
|
gs_aKeys[i].m_KeyId = KeyId;
|
||||||
|
gs_aKeys[i].m_Modifier = m;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int NumOptions = 11;
|
int NumOptions = 11;
|
||||||
int StartOption = 18;
|
int StartOption = 18;
|
||||||
|
|
|
@ -37,11 +37,23 @@ bool CMenusKeyBinder::OnInput(IInput::CEvent Event)
|
||||||
{
|
{
|
||||||
if(m_TakeKey)
|
if(m_TakeKey)
|
||||||
{
|
{
|
||||||
if(Event.m_Flags&IInput::FLAG_PRESS)
|
int TriggeringEvent = (Event.m_Key == KEY_MOUSE_1) ? IInput::FLAG_PRESS : IInput::FLAG_RELEASE;
|
||||||
|
if(Event.m_Flags&TriggeringEvent) // delay to RELEASE to support composed binds
|
||||||
{
|
{
|
||||||
m_Key = Event;
|
m_Key = Event;
|
||||||
m_GotKey = true;
|
m_GotKey = true;
|
||||||
m_TakeKey = false;
|
m_TakeKey = false;
|
||||||
|
|
||||||
|
int Mask = CBinds::GetModifierMask(Input()); // always > 0
|
||||||
|
m_Modifier = 0;
|
||||||
|
while(!(Mask&1)) // this computes a log2, we take the first modifier flag in mask.
|
||||||
|
{
|
||||||
|
Mask >>= 1;
|
||||||
|
m_Modifier++;
|
||||||
|
}
|
||||||
|
// prevent from adding e.g. a control modifier to lctrl
|
||||||
|
if(CBinds::ModifierMatchesKey(m_Modifier, Event.m_Key))
|
||||||
|
m_Modifier = 0;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,6 +184,7 @@ void CGameClient::OnConsoleInit()
|
||||||
m_All.Add(m_pEffects); // doesn't render anything, just updates effects
|
m_All.Add(m_pEffects); // doesn't render anything, just updates effects
|
||||||
m_All.Add(m_pParticles); // doesn't render anything, just updates all the particles
|
m_All.Add(m_pParticles); // doesn't render anything, just updates all the particles
|
||||||
m_All.Add(m_pBinds);
|
m_All.Add(m_pBinds);
|
||||||
|
m_All.Add(&m_pBinds->m_SpecialBinds);
|
||||||
m_All.Add(m_pControls);
|
m_All.Add(m_pControls);
|
||||||
m_All.Add(m_pCamera);
|
m_All.Add(m_pCamera);
|
||||||
m_All.Add(m_pSounds);
|
m_All.Add(m_pSounds);
|
||||||
|
@ -208,6 +209,7 @@ void CGameClient::OnConsoleInit()
|
||||||
m_All.Add(&gs_Scoreboard);
|
m_All.Add(&gs_Scoreboard);
|
||||||
m_All.Add(m_pMotd);
|
m_All.Add(m_pMotd);
|
||||||
m_All.Add(m_pMenus);
|
m_All.Add(m_pMenus);
|
||||||
|
m_All.Add(&m_pMenus->m_Binder);
|
||||||
m_All.Add(m_pGameConsole);
|
m_All.Add(m_pGameConsole);
|
||||||
|
|
||||||
// build the input stack
|
// build the input stack
|
||||||
|
|
Loading…
Reference in a new issue