Etterna 0.74.4
Loading...
Searching...
No Matches
InputMapper.h
1#ifndef INPUT_MAPPER_H
2#define INPUT_MAPPER_H
3
4#include <utility>
5
6#include <utility>
7
8#include "Etterna/Models/Misc/GameInput.h"
9#include "Etterna/Models/Misc/PlayerNumber.h"
10#include "RageUtil/Misc/RageInputDevice.h"
11struct Game;
12
13// five device inputs may map to one game input
14const int NUM_GAME_TO_DEVICE_SLOTS = 5;
15// three device inputs are shown to the player
16const int NUM_SHOWN_GAME_TO_DEVICE_SLOTS = 3;
17// two are allowed to be bound by the player
18const int NUM_USER_GAME_TO_DEVICE_SLOTS = 2;
19extern const std::string DEVICE_INPUT_SEPARATOR;
20
22{
23 AutoMappingEntry(int i, DeviceButton db, GameButton gb, bool b)
24 : m_iSlotIndex(i)
25 , m_deviceButton(db)
26 , m_gb(gb)
27 , m_bSecondController(b)
28 {
29 }
30 AutoMappingEntry() = default;
31
32 [[nodiscard]] auto IsEmpty() const -> bool
33 {
34 return m_deviceButton == DeviceButton_Invalid &&
35 m_gb == GameButton_Invalid;
36 }
37
38 int m_iSlotIndex{ -1 };
39 DeviceButton m_deviceButton{ DeviceButton_Invalid };
40 GameButton m_gb{
41 GameButton_Invalid
42 }; // GameButton_Invalid means unmap this button
43 /* If this is true, this is an auxilliary mapping assigned to the second
44 * player. If two of the same device are found, and the device has secondary
45 * entries, the later entries take precedence. This way, if a Pump pad is
46 * found, it'll map P1 to the primary pad and P2 to the secondary pad. (We
47 * can't tell if a slave pad is actually there.) Then, if a second primary
48 * is found (DEVICE_PUMP2), 2P will be mapped to it. */
49 bool m_bSecondController{ false };
50};
51
53{
54 AutoMappings(std::string s1,
55 std::string s2,
56 std::string s3,
97 : m_sGame(std::move(std::move(s1)))
98 , m_sDriverRegex(std::move(std::move(s2)))
99 , m_sControllerName(std::move(std::move(s3)))
100 {
101#define PUSH(im) \
102 if (!(im).IsEmpty()) \
103 m_vMaps.push_back(im);
104 PUSH(im0);
105 PUSH(im1);
106 PUSH(im2);
107 PUSH(im3);
108 PUSH(im4);
109 PUSH(im5);
110 PUSH(im6);
111 PUSH(im7);
112 PUSH(im8);
113 PUSH(im9);
114 PUSH(im10);
115 PUSH(im11);
116 PUSH(im12);
117 PUSH(im13);
118 PUSH(im14);
119 PUSH(im15);
120 PUSH(im16);
121 PUSH(im17);
122 PUSH(im18);
123 PUSH(im19);
124 PUSH(im20);
125 PUSH(im21);
126 PUSH(im22);
127 PUSH(im23);
128 PUSH(im24);
129 PUSH(im25);
130 PUSH(im26);
131 PUSH(im27);
132 PUSH(im28);
133 PUSH(im29);
134 PUSH(im30);
135 PUSH(im31);
136 PUSH(im32);
137 PUSH(im33);
138 PUSH(im34);
139 PUSH(im35);
140 PUSH(im36);
141 PUSH(im37);
142 PUSH(im38);
143 PUSH(im39);
144#undef PUSH
145 }
146
147 // Strings used by automatic joystick mappings.
148 std::string m_sGame; // only used
149 std::string m_sDriverRegex; // reported by InputHandler
150 std::string m_sControllerName; // the product name of the controller
151
152 std::vector<AutoMappingEntry> m_vMaps;
153};
154
156{
157 public:
158 const char* m_szName;
159 int m_iButtonsPerController;
161 {
162 const char* m_szName; // The name used by the button graphics system.
163 // e.g. "left", "right", "middle C", "snare"
164 GameButton m_SecondaryMenuButton;
165 };
166 // Data for each Game-specific GameButton. This starts at GAME_BUTTON_NEXT.
167 GameButtonInfo m_GameButtonInfo[NUM_GameButton];
168 const AutoMappings* m_pAutoMappings;
169
170 [[nodiscard]] auto ButtonNameToIndex(const std::string& sButtonName) const
171 -> GameButton;
172 [[nodiscard]] auto GameButtonToMenuButton(GameButton gb) const
173 -> GameButton;
174 void MenuButtonToGameInputs(GameButton MenuI,
175 PlayerNumber pn,
176 std::vector<GameInput>& GameIout) const;
177 void MenuButtonToGameButtons(GameButton MenuI,
178 std::vector<GameButton>& aGameButtons) const;
179 [[nodiscard]] auto GetGameButtonInfo(GameButton gb) const
180 -> const GameButtonInfo*;
181 [[nodiscard]] auto GetGameButtonName(GameButton gb) const -> const char*;
182};
184#define FOREACH_GameButtonInScheme(s, var) \
185 for (GameButton var = (GameButton)0; (var) < (s)->m_iButtonsPerController; \
186 enum_add<GameButton>(var, +1))
187
189{
190 public:
191 // only filled for automappings
192 std::string m_sDeviceRegex;
193 std::string m_sDescription;
194
195 // map from a GameInput to multiple DeviceInputs
196 DeviceInput m_GItoDI[NUM_GameController][NUM_GameButton]
197 [NUM_GAME_TO_DEVICE_SLOTS];
198
199 void Clear();
200 void Unmap(InputDevice id);
201 void WriteMappings(const InputScheme* pInputScheme,
202 const std::string& sFilePath);
203 void ReadMappings(const InputScheme* pInputScheme,
204 const std::string& sFilePath,
205 bool bIsAutoMapping);
206 void SetInputMap(const DeviceInput& DeviceI,
207 const GameInput& GameI,
208 int iSlotIndex);
209
210 void ClearFromInputMap(const DeviceInput& DeviceI);
211 auto ClearFromInputMap(const GameInput& GameI, int iSlotIndex) -> bool;
212};
215{
216 public:
217 InputMapper();
218 ~InputMapper();
219 void PushSelf(lua_State* L);
220
221 void SetInputScheme(const InputScheme* pInputScheme);
222 [[nodiscard]] auto GetInputScheme() const -> const InputScheme*;
223 void SetJoinControllers(PlayerNumber pn);
224
225 void ReadMappingsFromDisk();
226 void SaveMappingsToDisk();
227 void ResetMappingsToDefault();
228 void CheckButtonAndAddToReason(GameButton menu,
229 std::vector<std::string>& full_reason,
230 std::string const& sub_reason);
231 void SanityCheckMappings(std::vector<std::string>& reason);
232
233 void ClearAllMappings();
234
235 void SetInputMap(const DeviceInput& DeviceI,
236 const GameInput& GameI,
237 int iSlotIndex);
238 void ClearFromInputMap(const DeviceInput& DeviceI);
239 auto ClearFromInputMap(const GameInput& GameI, int iSlotIndex) -> bool;
240
241 void AddDefaultMappingsForCurrentGameIfUnmapped();
242 void AutoMapJoysticksForCurrentGame();
243 auto CheckForChangedInputDevicesAndRemap(std::string& sMessageOut) -> bool;
244
245 [[nodiscard]] auto IsMapped(const DeviceInput& DeviceI) const -> bool;
246
247 auto DeviceToGame(const DeviceInput& DeviceI, GameInput& GameI) const
248 -> bool; // return true if there is a mapping from device to pad
249 auto GameToDevice(const GameInput& GameI,
250 int iSlotNum,
251 DeviceInput& DeviceI) const
252 -> bool; // return true if there is a mapping from pad to device
253
254 [[nodiscard]] auto GameButtonToMenuButton(GameButton gb) const
255 -> GameButton;
256 void MenuToGame(GameButton MenuI,
257 PlayerNumber pn,
258 std::vector<GameInput>& GameIout) const;
259 [[nodiscard]] auto ControllerToPlayerNumber(GameController controller) const
260 -> PlayerNumber;
261
262 [[nodiscard]] auto GetSecsHeld(const GameInput& GameI,
263 MultiPlayer mp = MultiPlayer_Invalid) const
264 -> float;
265 [[nodiscard]] auto GetSecsHeld(GameButton MenuI, PlayerNumber pn) const
266 -> float;
267
268 auto IsBeingPressed(const GameInput& GameI,
269 MultiPlayer mp = MultiPlayer_Invalid,
270 const DeviceInputList* pButtonState = nullptr) const
271 -> bool;
272 [[nodiscard]] auto IsBeingPressed(GameButton MenuI, PlayerNumber pn) const
273 -> bool;
274 auto IsBeingPressed(const std::vector<GameInput>& GameI,
275 MultiPlayer mp = MultiPlayer_Invalid,
276 const DeviceInputList* pButtonState = nullptr) const
277 -> bool;
278
279 void ResetKeyRepeat(const GameInput& GameI);
280 void ResetKeyRepeat(GameButton MenuI, PlayerNumber pn);
281
282 void RepeatStopKey(const GameInput& GameI);
283 void RepeatStopKey(GameButton MenuI, PlayerNumber pn);
284
285 [[nodiscard]] auto GetLevel(const GameInput& GameI) const -> float;
286 [[nodiscard]] auto GetLevel(GameButton MenuI, PlayerNumber pn) const
287 -> float;
288
289 static auto MultiPlayerToInputDevice(MultiPlayer mp) -> InputDevice;
290 static auto InputDeviceToMultiPlayer(InputDevice id) -> MultiPlayer;
291
292 void Unmap(InputDevice device);
293 void ApplyMapping(const std::vector<AutoMappingEntry>& vMmaps,
294 GameController gc,
295 InputDevice id);
296
297 protected:
298 InputMappings m_mappings;
299
300 void UpdateTempDItoGI();
301 const InputScheme* m_pInputScheme;
302
303 private:
304 InputMapper(const InputMapper& rhs);
305 auto operator=(const InputMapper& rhs) -> InputMapper&;
306};
307
308extern InputMapper*
309 INPUTMAPPER; // global and accessible from anywhere in our program
310
311#endif
Holds user-chosen input preferences and saves it between sessions.
Definition InputMapper.h:215
Definition InputMapper.h:189
Definition InputMapper.h:156
Definition InputMapper.h:22
Definition InputMapper.h:53
Definition RageInputDevice.h:390
An input event specific to an InputScheme defined by a logical controller and button.
Definition GameInput.h:191
Holds information about a particular style of a game (e.g. "single", "double").
Definition Game.h:33
Definition InputMapper.h:161