1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #ifndef COMMON_KEYMAPPER_H
24 #define COMMON_KEYMAPPER_H
25 
26 #include "common/scummsys.h"
27 
28 #include "backends/keymapper/keymap.h"
29 
30 #include "common/array.h"
31 #include "common/config-manager.h"
32 #include "common/events.h"
33 
34 namespace Common {
35 
36 const char *const kGuiKeymapName = "gui";
37 const char *const kGlobalKeymapName = "global";
38 
39 struct Action;
40 class DelayedEventSource;
41 struct HardwareInput;
42 class HardwareInputSet;
43 class KeymapperDefaultBindings;
44 
45 class Keymapper : public Common::EventMapper {
46 public:
47 
48 	Keymapper(EventManager *eventMan);
49 	~Keymapper();
50 
51 	// EventMapper interface
52 	virtual List<Event> mapEvent(const Event &ev);
53 
54 	/**
55 	 * Registers a HardwareInputSet and platform-specific default mappings with the Keymapper
56 	 *
57 	 * Transfers ownership to the Keymapper
58 	 */
59 	void registerHardwareInputSet(HardwareInputSet *inputs, KeymapperDefaultBindings *backendDefaultBindings);
60 
61 	/**
62 	 * Add a keymap to the global domain.
63 	 * If a saved key setup exists for it in the ini file it will be used.
64 	 * Else, the key setup will be automatically mapped.
65 	 *
66 	 * Transfers ownership of the keymap to the Keymapper
67 	 */
68 	void addGlobalKeymap(Keymap *keymap);
69 
70 	/**
71 	 * Add a keymap to the game domain.
72 	 *
73 	 * Transfers ownership of the keymap to the Keymapper
74 	 *
75 	 * @see addGlobalKeyMap
76 	 * @note initGame() should be called before any game keymaps are added.
77 	 */
78 	void addGameKeymap(Keymap *keymap);
79 
80 	/**
81 	 * Should be called at end of game to tell Keymapper to deactivate and free
82 	 * any game keymaps that are loaded.
83 	 */
84 	void cleanupGameKeymaps();
85 
86 	/**
87 	 * Obtain a keymap of the given name from the keymapper.
88 	 * Game keymaps have priority over global keymaps
89 	 * @param id		name of the keymap to return
90 	 */
91 	Keymap *getKeymap(const String &id) const;
92 
93 	/**
94 	 * Obtain a list of all the keymaps registered with the keymapper
95 	 */
getKeymaps()96 	const KeymapArray &getKeymaps() const { return _keymaps; }
97 
98 	/**
99 	 * reload the mappings for all the keymaps from the configuration manager
100 	 */
101 	void reloadAllMappings();
102 
103 	/**
104 	 * Set which kind of keymap is currently used to map events
105 	 *
106 	 * Keymaps with the global type are always enabled
107 	 */
108 	void setEnabledKeymapType(Keymap::KeymapType type);
enabledKeymapType()109 	Keymap::KeymapType enabledKeymapType() const { return _enabledKeymapType; }
110 
111 	/**
112 	 * Enable/disable the keymapper
113 	 */
setEnabled(bool enabled)114 	void setEnabled(bool enabled) { _enabled = enabled; }
115 
116 	/**
117 	 * Clear all the keymaps and hardware input sets
118 	 */
119 	void clear();
120 
121 	/**
122 	 * Return a HardwareInput pointer for the given event
123 	 */
124 	HardwareInput findHardwareInput(const Event &event);
125 
126 	void initKeymap(Keymap *keymap, ConfigManager::Domain *domain);
127 	void reloadKeymapMappings(Keymap *keymap);
128 
129 private:
130 	EventManager *_eventMan;
131 	HardwareInputSet *_hardwareInputs;
132 	KeymapperDefaultBindings *_backendDefaultBindings;
133 	DelayedEventSource *_delayedEventSource;
134 
135 	enum IncomingEventType {
136 		kIncomingEventIgnored,
137 		kIncomingEventStart,
138 		kIncomingEventEnd,
139 		kIncomingEventInstant
140 	};
141 
142 	enum {
143 		kJoyAxisPressedTreshold   = Common::JOYAXIS_MAX / 2,
144 		kJoyAxisUnpressedTreshold = Common::JOYAXIS_MAX / 4
145 	};
146 
147 	bool _enabled;
148 	Keymap::KeymapType _enabledKeymapType;
149 
150 	KeymapArray _keymaps;
151 
152 	bool _joystickAxisPreviouslyPressed[6];
153 
154 	Keymap::KeymapMatch getMappedActions(const Event &event, Keymap::ActionArray &actions, Keymap::KeymapType keymapType) const;
155 	Event executeAction(const Action *act, const Event &incomingEvent);
156 	EventType convertStartToEnd(EventType eventType);
157 	IncomingEventType convertToIncomingEventType(const Event &ev) const;
158 
159 	void hardcodedEventMapping(Event ev);
160 	void resetInputState();
161 };
162 
163 /**
164  * RAII helper to temporarily enable a keymap type
165  */
166 class KeymapTypeEnabler {
167 public:
KeymapTypeEnabler(Keymapper * keymapper,Keymap::KeymapType keymapType)168 	KeymapTypeEnabler(Keymapper *keymapper, Keymap::KeymapType keymapType) :
169 			_keymapper(keymapper) {
170 		assert(keymapper);
171 		_previousKeymapType = keymapper->enabledKeymapType();
172 		keymapper->setEnabledKeymapType(keymapType);
173 	}
174 
~KeymapTypeEnabler()175 	~KeymapTypeEnabler() {
176 		_keymapper->setEnabledKeymapType(_previousKeymapType);
177 	}
178 
179 private:
180 	Keymapper *_keymapper;
181 	Keymap::KeymapType _previousKeymapType;
182 };
183 
184 class DelayedEventSource : public EventSource {
185 public:
186 	// EventSource API
187 	bool pollEvent(Event &event) override;
188 	bool allowMapping() const override;
189 
190 	/**
191 	 * Schedule an event to be produced after the specified delay
192 	 */
193 	void scheduleEvent(const Event &ev, uint32 delayMillis);
194 
195 private:
196 	struct DelayedEventsEntry {
197 		const uint32 timerOffset;
198 		const Event event;
DelayedEventsEntryDelayedEventsEntry199 		DelayedEventsEntry(const uint32 offset, const Event ev) : timerOffset(offset), event(ev) { }
200 	};
201 
202 	Queue<DelayedEventsEntry> _delayedEvents;
203 	uint32 _delayedEffectiveTime;
204 };
205 
206 } // End of namespace Common
207 
208 #endif // #ifndef COMMON_KEYMAPPER_H
209