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 #include "common/system.h"
24 #include "ags/events.h"
25 #include "ags/globals.h"
26 
27 namespace AGS {
28 
29 EventsManager *g_events;
30 
EventsManager()31 EventsManager::EventsManager() {
32 	g_events = this;
33 	_keys.resize(Common::KEYCODE_LAST);
34 	Common::fill(&_joystickAxis[0], &_joystickAxis[32], 0);
35 	Common::fill(&_joystickButton[0], &_joystickButton[32], 0);
36 }
37 
~EventsManager()38 EventsManager::~EventsManager() {
39 	g_events = nullptr;
40 }
41 
pollEvents()42 void EventsManager::pollEvents() {
43 	Common::Event e;
44 
45 	while (g_system->getEventManager()->pollEvent(e)) {
46 		switch (e.type) {
47 		case Common::EVENT_QUIT:
48 		case Common::EVENT_RETURN_TO_LAUNCHER:
49 			_G(want_exit) = true;
50 			_G(abort_engine) = true;
51 			_G(check_dynamic_sprites_at_exit) = false;
52 			return;
53 
54 		case Common::EVENT_JOYAXIS_MOTION:
55 			assert(e.joystick.axis < 32);
56 			_joystickAxis[e.joystick.axis] = e.joystick.position;
57 			break;
58 
59 		case Common::EVENT_JOYBUTTON_DOWN:
60 			assert(e.joystick.button < 32);
61 			_joystickButton[e.joystick.button] = true;
62 			break;
63 
64 		case Common::EVENT_JOYBUTTON_UP:
65 			assert(e.joystick.button < 32);
66 			_joystickButton[e.joystick.button] = false;
67 			break;
68 
69 		case Common::EVENT_KEYDOWN:
70 			updateKeys(e, true);
71 			_keyEvents.push(e);
72 			break;
73 
74 		case Common::EVENT_KEYUP:
75 			updateKeys(e, false);
76 			break;
77 
78 		default:
79 			if (e.type == Common::EVENT_MOUSEMOVE)
80 				_mousePos = Common::Point(e.mouse.x, e.mouse.y);
81 
82 			// Add other event types to the pending events queue. If the event is a
83 			// mouse move and the prior one was also, then discard the prior one.
84 			// This'll help prevent too many mouse move events accumulating
85 			if (e.type == Common::EVENT_MOUSEMOVE && !_pendingEvents.empty() &&
86 			        _pendingEvents.back().type == Common::EVENT_MOUSEMOVE)
87 				_pendingEvents.back() = e;
88 			else
89 				_pendingEvents.push(e);
90 			break;
91 		}
92 	}
93 }
94 
95 #if 0
96 bool EventsManager::keypressed() {
97 	pollEvents();
98 	return !_pendingKeys.empty();
99 }
100 
101 #define EXTENDED_KEY_CODE ('\0')
102 
103 Common::Event EventsManager::readKey() {
104 	pollEvents();
105 	return _pendingKeys.empty() ? Common::Event() : _pendingKeys.pop();
106 }
107 #endif
108 
readEvent()109 Common::Event EventsManager::readEvent() {
110 	pollEvents();
111 	return _pendingEvents.empty() ? Common::Event() : _pendingEvents.pop();
112 }
113 
warpMouse(const Common::Point & newPos)114 void EventsManager::warpMouse(const Common::Point &newPos) {
115 	g_system->warpMouse(newPos.x, newPos.y);
116 }
117 
isModifierKey(const Common::KeyCode & keycode) const118 bool EventsManager::isModifierKey(const Common::KeyCode &keycode) const {
119 	return keycode == Common::KEYCODE_LCTRL || keycode == Common::KEYCODE_LALT
120 	       || keycode == Common::KEYCODE_RCTRL || keycode == Common::KEYCODE_RALT
121 	       || keycode == Common::KEYCODE_LSHIFT || keycode == Common::KEYCODE_RSHIFT
122 	       || keycode == Common::KEYCODE_LSUPER || keycode == Common::KEYCODE_RSUPER
123 	       || keycode == Common::KEYCODE_CAPSLOCK || keycode == Common::KEYCODE_NUMLOCK
124 	       || keycode == Common::KEYCODE_SCROLLOCK;
125 }
126 
isExtendedKey(const Common::KeyCode & keycode) const127 bool EventsManager::isExtendedKey(const Common::KeyCode &keycode) const {
128 	const Common::KeyCode EXTENDED_KEYS[] = {
129 		Common::KEYCODE_F1, Common::KEYCODE_F2, Common::KEYCODE_F3,
130 		Common::KEYCODE_F4, Common::KEYCODE_F5, Common::KEYCODE_F6,
131 		Common::KEYCODE_F7, Common::KEYCODE_F8, Common::KEYCODE_F9,
132 		Common::KEYCODE_F10, Common::KEYCODE_F11, Common::KEYCODE_F12,
133 		Common::KEYCODE_KP0, Common::KEYCODE_KP1, Common::KEYCODE_KP2,
134 		Common::KEYCODE_KP3, Common::KEYCODE_KP4, Common::KEYCODE_KP5,
135 		Common::KEYCODE_KP6, Common::KEYCODE_KP7, Common::KEYCODE_KP8,
136 		Common::KEYCODE_KP9, Common::KEYCODE_KP_PERIOD,
137 		Common::KEYCODE_INSERT, Common::KEYCODE_DELETE,
138 		Common::KEYCODE_HOME, Common::KEYCODE_END,
139 		Common::KEYCODE_PAGEUP, Common::KEYCODE_PAGEDOWN,
140 		Common::KEYCODE_LEFT, Common::KEYCODE_RIGHT,
141 		Common::KEYCODE_UP, Common::KEYCODE_DOWN,
142 		Common::KEYCODE_INVALID
143 	};
144 
145 	for (const Common::KeyCode *kc = EXTENDED_KEYS;
146 	        *kc != Common::KEYCODE_INVALID; ++kc) {
147 		if (keycode == *kc)
148 			return true;
149 	}
150 
151 	return false;
152 }
153 
updateKeys(const Common::Event & event,bool isDown)154 void EventsManager::updateKeys(const Common::Event &event, bool isDown) {
155 	_keyModifierFlags = event.kbd.flags;
156 
157 	_keys[event.kbd.keycode] = isDown;
158 }
159 
isKeyPressed(AGS3::eAGSKeyCode key)160 bool EventsManager::isKeyPressed(AGS3::eAGSKeyCode key) {
161 	pollEvents();
162 
163 	Common::KeyCode kc[3];
164 	if (!ags_key_to_scancode(key, kc))
165 		return false;
166 
167 	return (kc[0] != Common::KEYCODE_INVALID && _keys[kc[0]]) ||
168 		(kc[1] != Common::KEYCODE_INVALID && _keys[kc[1]]) ||
169 		(kc[2] != Common::KEYCODE_INVALID && _keys[kc[2]]);
170 }
171 
ags_key_to_scancode(AGS3::eAGSKeyCode key,Common::KeyCode (& kc)[3])172 bool EventsManager::ags_key_to_scancode(AGS3::eAGSKeyCode key, Common::KeyCode(&kc)[3]) {
173 	kc[0] = Common::KEYCODE_INVALID;
174 	kc[1] = Common::KEYCODE_INVALID;
175 	kc[2] = Common::KEYCODE_INVALID;
176 	Common::KeyCode sym = Common::KEYCODE_INVALID;
177 
178 	// SDL sym codes happen to match small ASCII letters, so lowercase ours if necessary
179 	if (key >= AGS3::eAGSKeyCodeA && key <= AGS3::eAGSKeyCodeZ) {
180 		sym = static_cast<Common::KeyCode>(key - AGS3::eAGSKeyCodeA + Common::KEYCODE_a);
181 	}
182 	// Rest of the printable characters seem to match (and match ascii codes)
183 	else if (key >= AGS3::eAGSKeyCodeSpace && key <= AGS3::eAGSKeyCodeBackquote) {
184 		sym = static_cast<Common::KeyCode>(key);
185 	}
186 
187 	if (sym != Common::KEYCODE_INVALID) {
188 		kc[0] = sym;
189 		return true;
190 	}
191 
192 	// Other keys are mapped directly to scancode (based on [sonneveld]'s code)
193 	switch (key) {
194 	case AGS3::eAGSKeyCodeBackspace:
195 		kc[0] = Common::KEYCODE_BACKSPACE;
196 		return true;
197 	case AGS3::eAGSKeyCodeTab:
198 		kc[0] = Common::KEYCODE_TAB;
199 		return true;
200 	case AGS3::eAGSKeyCodeReturn:
201 		kc[0] = Common::KEYCODE_RETURN;
202 		kc[1] = Common::KEYCODE_KP_ENTER;
203 		return true;
204 	case AGS3::eAGSKeyCodeEscape:
205 		kc[0] = Common::KEYCODE_ESCAPE;
206 		return true;
207 
208 	case AGS3::eAGSKeyCodeF1:
209 		kc[0] = Common::KEYCODE_F1;
210 		return true;
211 	case AGS3::eAGSKeyCodeF2:
212 		kc[0] = Common::KEYCODE_F2;
213 		return true;
214 	case AGS3::eAGSKeyCodeF3:
215 		kc[0] = Common::KEYCODE_F3;
216 		return true;
217 	case AGS3::eAGSKeyCodeF4:
218 		kc[0] = Common::KEYCODE_F4;
219 		return true;
220 	case AGS3::eAGSKeyCodeF5:
221 		kc[0] = Common::KEYCODE_F5;
222 		return true;
223 	case AGS3::eAGSKeyCodeF6:
224 		kc[0] = Common::KEYCODE_F6;
225 		return true;
226 	case AGS3::eAGSKeyCodeF7:
227 		kc[0] = Common::KEYCODE_F7;
228 		return true;
229 	case AGS3::eAGSKeyCodeF8:
230 		kc[0] = Common::KEYCODE_F8;
231 		return true;
232 	case AGS3::eAGSKeyCodeF9:
233 		kc[0] = Common::KEYCODE_F9;
234 		return true;
235 	case AGS3::eAGSKeyCodeF10:
236 		kc[0] = Common::KEYCODE_F10;
237 		return true;
238 	case AGS3::eAGSKeyCodeF11:
239 		kc[0] = Common::KEYCODE_F11;
240 		return true;
241 	case AGS3::eAGSKeyCodeF12:
242 		kc[0] = Common::KEYCODE_F12;
243 		return true;
244 
245 	case AGS3::eAGSKeyCodeHome:
246 		kc[0] = Common::KEYCODE_KP7;
247 		kc[1] = Common::KEYCODE_HOME;
248 		return true;
249 	case AGS3::eAGSKeyCodeUpArrow:
250 		kc[0] = Common::KEYCODE_KP8;
251 		kc[1] = Common::KEYCODE_UP;
252 		return true;
253 	case AGS3::eAGSKeyCodePageUp:
254 		kc[0] = Common::KEYCODE_KP9;
255 		kc[1] = Common::KEYCODE_PAGEUP;
256 		return true;
257 	case AGS3::eAGSKeyCodeLeftArrow:
258 		kc[0] = Common::KEYCODE_KP4;
259 		kc[1] = Common::KEYCODE_LEFT;
260 		return true;
261 	case AGS3::eAGSKeyCodeNumPad5:
262 		kc[0] = Common::KEYCODE_KP5;
263 		return true;
264 	case AGS3::eAGSKeyCodeRightArrow:
265 		kc[0] = Common::KEYCODE_KP6;
266 		kc[1] = Common::KEYCODE_RIGHT;
267 		return true;
268 	case AGS3::eAGSKeyCodeEnd:
269 		kc[0] = Common::KEYCODE_KP1;
270 		kc[1] = Common::KEYCODE_END;
271 		return true;
272 	case AGS3::eAGSKeyCodeDownArrow:
273 		kc[0] = Common::KEYCODE_KP2;
274 		kc[1] = Common::KEYCODE_DOWN;
275 		return true;
276 	case AGS3::eAGSKeyCodePageDown:
277 		kc[0] = Common::KEYCODE_KP3;
278 		kc[1] = Common::KEYCODE_PAGEDOWN;
279 		return true;
280 	case AGS3::eAGSKeyCodeInsert:
281 		kc[0] = Common::KEYCODE_KP0;
282 		kc[1] = Common::KEYCODE_INSERT;
283 		return true;
284 	case AGS3::eAGSKeyCodeDelete:
285 		kc[0] = Common::KEYCODE_KP_PERIOD;
286 		kc[1] = Common::KEYCODE_DELETE;
287 		return true;
288 
289 	case AGS3::eAGSKeyCodeLShift:
290 		kc[0] = Common::KEYCODE_LSHIFT;
291 		return true;
292 	case AGS3::eAGSKeyCodeRShift:
293 		kc[0] = Common::KEYCODE_RSHIFT;
294 		return true;
295 	case AGS3::eAGSKeyCodeLCtrl:
296 		kc[0] = Common::KEYCODE_LCTRL;
297 		return true;
298 	case AGS3::eAGSKeyCodeRCtrl:
299 		kc[0] = Common::KEYCODE_RCTRL;
300 		return true;
301 	case AGS3::eAGSKeyCodeLAlt:
302 		kc[0] = Common::KEYCODE_LALT;
303 		return true;
304 	case AGS3::eAGSKeyCodeRAlt:
305 		kc[0] = Common::KEYCODE_RALT;
306 		return true;
307 
308 	default:
309 		return false;
310 	}
311 	return false;
312 }
313 
scummvm_key_to_ags_key(const Common::Event & event)314 AGS3::eAGSKeyCode EventsManager::scummvm_key_to_ags_key(const Common::Event &event) {
315 	if (event.type != Common::EVENT_KEYDOWN)
316 		return AGS3::eAGSKeyCodeNone;
317 
318 	const Common::KeyCode sym = event.kbd.keycode;
319 	const uint16 mod = event.kbd.flags;
320 
321 	// Ctrl and Alt combinations realign the letter code to certain offset
322 	if (sym >= Common::KEYCODE_a && sym <= Common::KEYCODE_z) {
323 		if ((mod & Common::KBD_CTRL) != 0) // align letters to code 1
324 			return static_cast<AGS3::eAGSKeyCode>(0 + (sym - Common::KEYCODE_a) + 1);
325 		else if ((mod & Common::KBD_ALT) != 0) // align letters to code 301
326 			return static_cast<AGS3::eAGSKeyCode>(AGS_EXT_KEY_SHIFT + (sym - Common::KEYCODE_a) + 1);
327 	}
328 
329 	if (event.kbd.ascii >= 32 && event.kbd.ascii <= 127)
330 		return static_cast<AGS3::eAGSKeyCode>(event.kbd.ascii);
331 
332 	// Remaining codes may match or not, but we use a big table anyway.
333 	// TODO: this is code by [sonneveld],
334 	// double check that we must use scan codes here, maybe can use sdl key (sym) too?
335 	switch (sym) {
336 	case Common::KEYCODE_BACKSPACE:
337 		return AGS3::eAGSKeyCodeBackspace;
338 	case Common::KEYCODE_TAB:
339 		return AGS3::eAGSKeyCodeTab;
340 	case Common::KEYCODE_RETURN:
341 	case Common::KEYCODE_KP_ENTER:
342 		return AGS3::eAGSKeyCodeReturn;
343 	case Common::KEYCODE_ESCAPE:
344 		return AGS3::eAGSKeyCodeEscape;
345 
346 	case Common::KEYCODE_F1:
347 		return AGS3::eAGSKeyCodeF1;
348 	case Common::KEYCODE_F2:
349 		return AGS3::eAGSKeyCodeF2;
350 	case Common::KEYCODE_F3:
351 		return AGS3::eAGSKeyCodeF3;
352 	case Common::KEYCODE_F4:
353 		return AGS3::eAGSKeyCodeF4;
354 	case Common::KEYCODE_F5:
355 		return AGS3::eAGSKeyCodeF5;
356 	case Common::KEYCODE_F6:
357 		return AGS3::eAGSKeyCodeF6;
358 	case Common::KEYCODE_F7:
359 		return AGS3::eAGSKeyCodeF7;
360 	case Common::KEYCODE_F8:
361 		return AGS3::eAGSKeyCodeF8;
362 	case Common::KEYCODE_F9:
363 		return AGS3::eAGSKeyCodeF9;
364 	case Common::KEYCODE_F10:
365 		return AGS3::eAGSKeyCodeF10;
366 	case Common::KEYCODE_F11:
367 		return AGS3::eAGSKeyCodeF11;
368 	case Common::KEYCODE_F12:
369 		return AGS3::eAGSKeyCodeF12;
370 
371 	case Common::KEYCODE_KP7:
372 	case Common::KEYCODE_HOME:
373 		return AGS3::eAGSKeyCodeHome;
374 	case Common::KEYCODE_KP8:
375 	case Common::KEYCODE_UP:
376 		return AGS3::eAGSKeyCodeUpArrow;
377 	case Common::KEYCODE_KP9:
378 	case Common::KEYCODE_PAGEUP:
379 		return AGS3::eAGSKeyCodePageUp;
380 	case Common::KEYCODE_KP4:
381 	case Common::KEYCODE_LEFT:
382 		return AGS3::eAGSKeyCodeLeftArrow;
383 	case Common::KEYCODE_KP5:
384 		return AGS3::eAGSKeyCodeNumPad5;
385 	case Common::KEYCODE_KP6:
386 	case Common::KEYCODE_RIGHT:
387 		return AGS3::eAGSKeyCodeRightArrow;
388 	case Common::KEYCODE_KP1:
389 	case Common::KEYCODE_END:
390 		return AGS3::eAGSKeyCodeEnd;
391 	case Common::KEYCODE_KP2:
392 	case Common::KEYCODE_DOWN:
393 		return AGS3::eAGSKeyCodeDownArrow;
394 	case Common::KEYCODE_KP3:
395 	case Common::KEYCODE_PAGEDOWN:
396 		return AGS3::eAGSKeyCodePageDown;
397 	case Common::KEYCODE_KP0:
398 	case Common::KEYCODE_INSERT:
399 		return AGS3::eAGSKeyCodeInsert;
400 	case Common::KEYCODE_KP_PERIOD:
401 	case Common::KEYCODE_DELETE:
402 		return AGS3::eAGSKeyCodeDelete;
403 
404 	default:
405 		return AGS3::eAGSKeyCodeNone;
406 	}
407 
408 	return AGS3::eAGSKeyCodeNone;
409 }
410 
411 } // namespace AGS
412