1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3#ifndef GAME_CLIENT_COMPONENTS_BINDS_H
4#define GAME_CLIENT_COMPONENTS_BINDS_H
5
6#include <engine/console.h>
7#include <engine/keys.h>
8
9#include <game/client/component.h>
10
11#include <vector>
12
13class IConfigManager;
14
15namespace KeyModifier
16{
17 inline constexpr int32_t NONE = 0;
18 inline constexpr int32_t CTRL = 1;
19 inline constexpr int32_t ALT = 2;
20 inline constexpr int32_t SHIFT = 3;
21 inline constexpr int32_t GUI = 4;
22 inline constexpr int32_t COUNT = 5;
23 inline constexpr int32_t COMBINATION_COUNT = 1 << COUNT;
24};
25
26class CBindSlot
27{
28public:
29 int m_Key;
30 int m_ModifierMask;
31
32 constexpr CBindSlot(int Key, int ModifierMask) :
33 m_Key(Key),
34 m_ModifierMask(ModifierMask)
35 {
36 }
37
38 constexpr bool operator==(const CBindSlot &Other) const { return m_Key == Other.m_Key && m_ModifierMask == Other.m_ModifierMask; }
39 constexpr bool operator!=(const CBindSlot &Other) const { return !(*this == Other); }
40};
41
42inline constexpr CBindSlot EMPTY_BIND_SLOT = CBindSlot(KEY_UNKNOWN, KeyModifier::NONE);
43
44class CBinds : public CComponent
45{
46 static void ConBind(IConsole::IResult *pResult, void *pUserData);
47 static void ConBinds(IConsole::IResult *pResult, void *pUserData);
48 static void ConUnbind(IConsole::IResult *pResult, void *pUserData);
49 static void ConUnbindAll(IConsole::IResult *pResult, void *pUserData);
50
51 static void ConfigSaveCallback(IConfigManager *pConfigManager, void *pUserData);
52
53 CBindSlot GetBindSlot(const char *pBindString) const;
54
55 // free buffer after use
56 char *GetKeyBindCommand(int ModifierCombination, int Key) const;
57
58public:
59 CBinds();
60 ~CBinds() override;
61 int Sizeof() const override { return sizeof(*this); }
62
63 class CBindsSpecial : public CComponent
64 {
65 public:
66 CBinds *m_pBinds;
67 int Sizeof() const override { return sizeof(*this); }
68 bool OnInput(const IInput::CEvent &Event) override;
69 };
70
71 bool m_MouseOnAction;
72
73 CBindsSpecial m_SpecialBinds;
74
75 void Bind(int KeyId, const char *pStr, bool FreeOnly = false, int ModifierCombination = KeyModifier::NONE);
76 void SetDefaults();
77 void UnbindAll();
78 const char *Get(int KeyId, int ModifierCombination) const;
79 const char *Get(const CBindSlot &BindSlot) const;
80 void GetKey(const char *pBindStr, char *pBuf, size_t BufSize) const;
81 static int GetModifierMask(IInput *pInput);
82 static int GetModifierMaskOfKey(int Key);
83 static const char *GetModifierName(int Modifier);
84 void GetKeyBindName(int Key, int ModifierMask, char *pBuf, size_t BufSize) const;
85
86 void OnConsoleInit() override;
87 bool OnInput(const IInput::CEvent &Event) override;
88
89 // DDRace
90
91 void SetDDRaceBinds(bool FreeOnly);
92
93private:
94 char *m_aapKeyBindings[KeyModifier::COMBINATION_COUNT][KEY_LAST];
95 std::vector<CBindSlot> m_vActiveBinds;
96};
97#endif
98