1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#include "Input/BsInputConfiguration.h"
4
5namespace bs
6{
7
8 UINT32 VirtualButton::NextButtonId = 0;
9
10 Map<String, UINT32> VirtualAxis::UniqueAxisIds;
11 UINT32 VirtualAxis::NextAxisId = 0;
12
13 VIRTUAL_BUTTON_DESC::VIRTUAL_BUTTON_DESC(ButtonCode buttonCode, ButtonModifier modifiers, bool repeatable)
14 :buttonCode(buttonCode), modifiers(modifiers), repeatable(repeatable)
15 { }
16
17 VIRTUAL_AXIS_DESC::VIRTUAL_AXIS_DESC(UINT32 type)
18 :type(type)
19 { }
20
21 VirtualButton::VirtualButton(const String& name)
22 {
23 Map<String, UINT32>& uniqueButtonIds = getUniqueButtonIds();
24
25 auto findIter = uniqueButtonIds.find(name);
26
27 if(findIter != uniqueButtonIds.end())
28 buttonIdentifier = findIter->second;
29 else
30 {
31 buttonIdentifier = NextButtonId;
32 uniqueButtonIds[name] = NextButtonId++;
33 }
34 }
35
36 Map<String, UINT32>& VirtualButton::getUniqueButtonIds()
37 {
38 static Map<String, UINT32> uniqueButtonIds;
39 return uniqueButtonIds;
40 }
41
42 VirtualAxis::VirtualAxis(const String& name)
43 {
44 auto findIter = UniqueAxisIds.find(name);
45
46 if (findIter != UniqueAxisIds.end())
47 axisIdentifier = findIter->second;
48 else
49 {
50 axisIdentifier = NextAxisId;
51 UniqueAxisIds[name] = NextAxisId++;
52 }
53 }
54
55 void InputConfiguration::registerButton(const String& name, ButtonCode buttonCode, ButtonModifier modifiers, bool repeatable)
56 {
57 Vector<VirtualButtonData>& btnData = mButtons[buttonCode & 0x0000FFFF];
58
59 INT32 idx = -1;
60 for(UINT32 i = 0; i < (UINT32)btnData.size(); i++)
61 {
62 if (btnData[i].name == name)
63 {
64 idx = (INT32)i;
65 break;
66 }
67 }
68
69 if(idx == -1)
70 {
71 idx = (INT32)btnData.size();
72 btnData.push_back(VirtualButtonData());
73 }
74
75 VirtualButtonData& btn = btnData[idx];
76 btn.name = name;
77 btn.desc = VIRTUAL_BUTTON_DESC(buttonCode, modifiers, repeatable);
78 btn.button = VirtualButton(name);
79 }
80
81 void InputConfiguration::unregisterButton(const String& name)
82 {
83 Vector<UINT32> toRemove;
84
85 for(UINT32 i = 0; i < BC_Count; i++)
86 {
87 for(UINT32 j = 0; j < (UINT32)mButtons[i].size(); j++)
88 {
89 if(mButtons[i][j].name == name)
90 toRemove.push_back(j);
91 }
92
93 UINT32 numRemoved = 0;
94 for(auto& toRemoveIdx : toRemove)
95 {
96 mButtons[i].erase(mButtons[i].begin() + toRemoveIdx - numRemoved);
97
98 numRemoved++;
99 }
100
101 toRemove.clear();
102 }
103 }
104
105 void InputConfiguration::registerAxis(const String& name, const VIRTUAL_AXIS_DESC& desc)
106 {
107 VirtualAxis axis(name);
108
109 if (axis.axisIdentifier >= (UINT32)mAxes.size())
110 mAxes.resize(axis.axisIdentifier + 1);
111
112 mAxes[axis.axisIdentifier].name = name;
113 mAxes[axis.axisIdentifier].desc = desc;
114 mAxes[axis.axisIdentifier].axis = axis;
115 }
116
117 void InputConfiguration::unregisterAxis(const String& name)
118 {
119 for (UINT32 i = 0; i < (UINT32)mAxes.size(); i++)
120 {
121 if (mAxes[i].name == name)
122 {
123 mAxes.erase(mAxes.begin() + i);
124 i--;
125 }
126 }
127 }
128
129 bool InputConfiguration::_getButtons(ButtonCode code, UINT32 modifiers, Vector<VirtualButton>& btns, Vector<VIRTUAL_BUTTON_DESC>& btnDesc) const
130 {
131 const Vector<VirtualButtonData>& btnData = mButtons[code & 0x0000FFFF];
132
133 bool foundAny = false;
134 for(UINT32 i = 0; i < (UINT32)btnData.size(); i++)
135 {
136 if((((UINT32)btnData[i].desc.modifiers) & modifiers) == ((UINT32)btnData[i].desc.modifiers))
137 {
138 btns.push_back(btnData[i].button);
139 btnDesc.push_back(btnData[i].desc);
140 foundAny = true;
141 }
142 }
143
144 return foundAny;
145 }
146
147 bool InputConfiguration::_getAxis(const VirtualAxis& axis, VIRTUAL_AXIS_DESC& axisDesc) const
148 {
149 if (axis.axisIdentifier >= (UINT32)mAxes.size())
150 return false;
151
152 axisDesc = mAxes[axis.axisIdentifier].desc;
153 return true;
154 }
155}