[Scummvm-git-logs] scummvm master -> 20c3bec6ef298b4f7f2d1ef5738d562dc2195997

kelmer44 noreply at scummvm.org
Fri Sep 26 10:00:24 UTC 2025


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .

Summary:
20c3bec6ef TOT: Add keymapper support


Commit: 20c3bec6ef298b4f7f2d1ef5738d562dc2195997
    https://github.com/scummvm/scummvm/commit/20c3bec6ef298b4f7f2d1ef5738d562dc2195997
Author: kelmer (kelmer at gmail.com)
Date: 2025-09-26T11:59:57+02:00

Commit Message:
TOT: Add keymapper support

Changed paths:
  A engines/tot/events.cpp
  A engines/tot/events.h
    engines/tot/anims.cpp
    engines/tot/chrono.cpp
    engines/tot/cutscenes.cpp
    engines/tot/dialog.cpp
    engines/tot/engine.cpp
    engines/tot/graphics.cpp
    engines/tot/metaengine.cpp
    engines/tot/metaengine.h
    engines/tot/module.mk
    engines/tot/saveload.cpp
    engines/tot/sound.cpp
    engines/tot/statics.h
    engines/tot/tot.cpp
    engines/tot/tot.h
    engines/tot/types.h
    engines/tot/util.cpp
    engines/tot/util.h


diff --git a/engines/tot/anims.cpp b/engines/tot/anims.cpp
index acbfd198ce5..06ce57484f2 100644
--- a/engines/tot/anims.cpp
+++ b/engines/tot/anims.cpp
@@ -836,12 +836,9 @@ void handleFlcEvent(byte eventNumber, uint loopNumber, byte frameCount) {
 
 static void exitProcedure(bool &exitLoop, bool isSkipAllowed) {
 	exitLoop = false;
-	Common::Event e;
-	while (g_system->getEventManager()->pollEvent(e)) {
-		changeGameSpeed(e);
-		if (isSkipAllowed && (e.type == Common::EVENT_KEYDOWN || (e.type == Common::EVENT_LBUTTONUP))) {
-			exitLoop = true;
-		}
+	g_engine->_events->pollEvent();
+	if (isSkipAllowed && (g_engine->_events->_keyPressed || g_engine->_events->_leftMouseButton)) {
+		exitLoop = true;
 	}
 }
 
diff --git a/engines/tot/chrono.cpp b/engines/tot/chrono.cpp
index bc3b514568e..9e4bbe3011d 100644
--- a/engines/tot/chrono.cpp
+++ b/engines/tot/chrono.cpp
@@ -59,11 +59,10 @@ void ChronoManager::changeSpeed() {
 
 void ChronoManager::delay(uint32 ms) {
 	uint32 delayStart = g_system->getMillis();
-	Common::Event e;
+
 	ms = ms / _speedMultiplier;
 	while ((g_system->getMillis() - delayStart) < ms && !g_engine->shouldQuit()) {
-		while (g_system->getEventManager()->pollEvent(e)) {
-		}
+		g_engine->_events->pollEvent();
 		g_engine->_screen->update();
 	}
 }
diff --git a/engines/tot/cutscenes.cpp b/engines/tot/cutscenes.cpp
index d840f434b6b..978eb7c4ea9 100644
--- a/engines/tot/cutscenes.cpp
+++ b/engines/tot/cutscenes.cpp
@@ -180,18 +180,12 @@ void scrollCredit(
 	}
 
 	g_engine->_graphics->setPalette(&g_engine->_graphics->_pal[16 * 3 + 0], 16, 240);
-	Common::Event e;
-	bool keyPressed = false;
-
 	// Loops an image from the bottom of the screen to the top
 	for (int i = 199; i >= minHeight; i--) {
-		while (g_system->getEventManager()->pollEvent(e)) {
-			if (e.type == Common::EVENT_KEYDOWN) {
-				keyPressed = true;
-			}
-		}
+		g_engine->_events->pollEvent();
+
 		putCreditsImg(85, i, g_engine->_sceneBackground, background, !withFade);
-		if (keyPressed) {
+		if (g_engine->_events->_keyPressed) {
 			exit = true;
 			break;
 		}
@@ -224,10 +218,8 @@ void scrollSingleCredit(
 
 void removeTitle(byte *&background2) {
 	uint i2, j2;
-	Common::Event e;
 	for (int i1 = 1; i1 <= 15000; i1++) {
-		while (g_system->getEventManager()->pollEvent(e)) {
-		}
+		g_engine->_events->pollEvent();
 		i2 = g_engine->getRandomNumber(318);
 		j2 = getRandom(58);
 		byte *src = background2 + 4 + (j2 * 320) + i2;
@@ -258,9 +250,9 @@ void removeTitle(byte *&background2) {
 }
 
 inline bool keyPressed() {
-	Common::Event e;
-	g_system->getEventManager()->pollEvent(e);
-	return e.type == Common::EVENT_KEYDOWN;
+
+	g_engine->_events->pollEvent();
+	return g_engine->_events->_keyPressed;
 }
 
 void TotEngine::credits() {
@@ -403,9 +395,8 @@ void TotEngine::introduction() {
 
 	do {
 		_chrono->updateChrono();
-		Common::Event e;
-		g_system->getEventManager()->pollEvent(e);
-		if (e.type == Common::EVENT_KEYDOWN || e.type == Common::EVENT_LBUTTONUP) {
+		g_engine->_events->pollEvent();
+		if (g_engine->_events->_keyPressed || g_engine->_events->_leftMouseButton) {
 			goto LexitIntro;
 		}
 
diff --git a/engines/tot/dialog.cpp b/engines/tot/dialog.cpp
index 55247c1746c..5756222a0c5 100644
--- a/engines/tot/dialog.cpp
+++ b/engines/tot/dialog.cpp
@@ -337,24 +337,19 @@ void showDialogueLine(
 	euroText(6, 173, conversationMatrix[3], 255);
 	euroText(6, 184, conversationMatrix[4], 255);
 	g_engine->_mouse->show();
-	Common::Event e;
+
 	do {
 		bool lMouseClicked = false;
 		bool rMouseClicked = false;
 		do {
 			g_engine->_chrono->updateChrono();
 			g_engine->_mouse->animateMouseIfNeeded();
+			g_engine->_events->pollEvent();
 
-			while (g_system->getEventManager()->pollEvent(e)) {
-				if (e.type == Common::EVENT_LBUTTONUP) {
-					lMouseClicked = true;
-					g_engine->_mouse->mouseClickX = e.mouse.x;
-					g_engine->_mouse->mouseClickY = e.mouse.y;
-				} else if (e.type == Common::EVENT_RBUTTONUP) {
-					rMouseClicked = true;
-					g_engine->_mouse->mouseClickX = e.mouse.x;
-					g_engine->_mouse->mouseClickY = e.mouse.y;
-				}
+			if (g_engine->_events->_leftMouseButton) {
+				lMouseClicked = true;
+			} else if (g_engine->_events->_rightMouseButton) {
+				rMouseClicked = true;
 			}
 
 			if (g_engine->_chrono->_gameTick) {
diff --git a/engines/tot/engine.cpp b/engines/tot/engine.cpp
index cc31e0c2f6f..34e673194ca 100644
--- a/engines/tot/engine.cpp
+++ b/engines/tot/engine.cpp
@@ -642,7 +642,7 @@ void TotEngine::animatedSequence(uint numSequence) {
 			}
 		}
 		animIndex = _mainCharAnimation.depth;
-		_mainCharAnimation.depth = 30;		
+		_mainCharAnimation.depth = 30;
 		if (g_engine->_screenLayers[12]) {
 			free(g_engine->_screenLayers[12]);
 		}
@@ -1031,12 +1031,10 @@ void TotEngine::goToObject(byte zone1, byte zone2) {
 
 		_mouse->hide();
 		calculateRoute(zone1, zone2, true, barredZone);
-		Common::Event e;
+
 		do {
 			_chrono->updateChrono();
-			while (g_system->getEventManager()->pollEvent(e)) {
-				changeGameSpeed(e);
-			}
+			g_engine->_events->pollEvent();
 			advanceAnimations(barredZone, false);
 			_screen->update();
 			g_system->delayMillis(10);
@@ -4013,17 +4011,13 @@ void TotEngine::sayLine(
 
 		talkAnimIndex = 0;
 		bool mouseClicked = false;
-		Common::Event e;
+
 		// Plays talk cycle if needed
 		do {
 			_chrono->updateChrono();
-			while (g_system->getEventManager()->pollEvent(e)) {
-				if (isMouseEvent(e)) {
-					if (e.type == Common::EVENT_LBUTTONUP || e.type == Common::EVENT_RBUTTONUP) {
-						mouseClicked = true;
-					}
-				}
-				changeGameSpeed(e);
+			g_engine->_events->pollEvent();
+			if (g_engine->_events->_leftMouseButton || g_engine->_events->_rightMouseButton) {
+				mouseClicked = true;
 			}
 			if (_chrono->_gameTick) {
 				_chrono->_gameTick = false;
@@ -4635,17 +4629,11 @@ void TotEngine::generateDiploma(Common::String &photoName) {
 	_graphics->totalFadeOut(0);
 	loadDiploma(photoName, key);
 
-	Common::Event e;
-	bool keyPressed = false;
 	do {
 		_screen->update();
-		while (g_system->getEventManager()->pollEvent(e)) {
-			if (e.type == Common::EVENT_KEYDOWN) {
-				keyPressed = true;
-			}
-		}
+		g_engine->_events->pollEvent();
 		g_system->delayMillis(10);
-	} while (!keyPressed && !shouldQuit());
+	} while (!g_engine->_events->_keyPressed && !shouldQuit());
 	saveDiploma(photoName, key);
 	_mouse->show();
 }
@@ -5266,7 +5254,7 @@ void TotEngine::soundControls() {
 	_mouse->hide();
 
 	soundControlsSize = imagesize(50, 10, 270, 120);
-	//What was on the screen before blitting sound controls
+	// What was on the screen before blitting sound controls
 	byte *soundControlsBackground = (byte *)malloc(soundControlsSize);
 	_graphics->getImg(50, 10, 270, 120, soundControlsBackground);
 
@@ -5303,22 +5291,23 @@ void TotEngine::soundControls() {
 	_mouse->warpMouse(1, _mouse->mouseX, _mouse->mouseY);
 	bool keyPressed = false;
 	bool mouseClicked = false;
-	Common::Event e;
 	do {
 		_chrono->updateChrono();
 		do {
 			_chrono->updateChrono();
 			_mouse->animateMouseIfNeeded();
-			while (g_system->getEventManager()->pollEvent(e)) {
-				if (e.type == Common::EVENT_KEYDOWN) {
-					keyPressed = true;
-				}
-				if (e.type == Common::EVENT_LBUTTONDOWN) {
-					mouseClicked = true;
-					_mouse->mouseClickX = e.mouse.x;
-					_mouse->mouseClickY = e.mouse.y;
-				}
+			g_engine->_events->pollEvent(true);
+
+			if (g_engine->_events->_keyPressed) {
+				keyPressed = true;
 			}
+			if (g_engine->_events->_leftMouseButton) {
+				debug("Mouse clicked!");
+				mouseClicked = true;
+				_mouse->mouseClickX = g_engine->_events->_mouseX;
+				_mouse->mouseClickY = g_engine->_events->_mouseY;
+			}
+
 			_screen->update();
 		} while ((!keyPressed && !mouseClicked) && !shouldQuit());
 
@@ -5328,20 +5317,20 @@ void TotEngine::soundControls() {
 			exitSoundControls = true;
 		}
 		if (mouseClicked) {
+
 			if (_mouse->mouseClickY >= 22 && _mouse->mouseClickY <= 37) {
 				_mouse->hide();
 				xfade = 86 + sfxVol;
 				bool mouseReleased = false;
 				do {
-
 					oldxfade = xfade;
-					while (g_system->getEventManager()->pollEvent(e)) {
-						if (e.type == Common::EVENT_LBUTTONUP) {
-							mouseReleased = true;
-						} else if (e.type == Common::EVENT_MOUSEMOVE) {
-							xfade = e.mouse.x;
-						}
+					g_engine->_events->pollEvent(true);
+					if (g_engine->_events->_leftMouseButton == 0) {
+						mouseReleased = true;
+					} else {
+						xfade = g_engine->_events->_mouseX;
 					}
+
 					if (xfade < 86) {
 						xfade = 86;
 					} else if (xfade > 226) {
@@ -5354,7 +5343,6 @@ void TotEngine::soundControls() {
 						// This yields a volume between 0 and 140
 						sfxVol = xfade - 86;
 
-						debug("volumefx=%d", sfxVol);
 						ConfMan.setInt("sfx_volume", sfxVol * 256 / 140);
 						g_engine->syncSoundSettings();
 					}
@@ -5369,12 +5357,12 @@ void TotEngine::soundControls() {
 				do {
 
 					oldxfade = xfade;
-					while (g_system->getEventManager()->pollEvent(e)) {
-						if (e.type == Common::EVENT_LBUTTONUP) {
-							mouseReleased = true;
-						} else if (e.type == Common::EVENT_MOUSEMOVE) {
-							xfade = e.mouse.x;
-						}
+					g_engine->_events->pollEvent(true);
+
+					if (g_engine->_events->_leftMouseButton == 0) {
+						mouseReleased = true;
+					} else {
+						xfade = g_engine->_events->_mouseX;
 					}
 					if (xfade < 86) {
 						xfade = 86;
@@ -5386,7 +5374,6 @@ void TotEngine::soundControls() {
 						_graphics->putImg(86, 76, sliderBackground2);
 						_graphics->putImg(xfade, 76, slider);
 						musicVol = xfade - 86;
-						debug("musicvol=%d", musicVol);
 						ConfMan.setInt("music_volume", musicVol * 256 / 140);
 						g_engine->syncSoundSettings();
 					}
@@ -5415,7 +5402,6 @@ void TotEngine::soundControls() {
 
 	if (_cpCounter > 7)
 		showError(274);
-
 	_mouse->setMouseArea(Common::Rect(0, 0, 305, 185));
 }
 
diff --git a/engines/tot/events.cpp b/engines/tot/events.cpp
new file mode 100644
index 00000000000..af2ecbf7304
--- /dev/null
+++ b/engines/tot/events.cpp
@@ -0,0 +1,140 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "tot/events.h"
+#include "events.h"
+#include "tot/util.h"
+
+namespace Tot {
+
+TotEventManager::TotEventManager() {
+}
+
+void TotEventManager::pollEvent(bool allowDrag) {
+
+	Common::EventManager *eventMan = g_engine->_system->getEventManager();
+
+	zeroEvents(allowDrag);
+	while (eventMan->pollEvent(_event)) {
+		if (isMouseEvent(_event)) {
+			g_engine->_mouse->warpMouse(_event.mouse);
+			g_engine->_mouse->mouseX = _event.mouse.x;
+			g_engine->_mouse->mouseY = _event.mouse.y;
+		}
+		switch (_event.type) {
+		case Common::EVENT_QUIT:
+		case Common::EVENT_RETURN_TO_LAUNCHER:
+			return;
+
+		case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
+			// handle action
+			handleKey(_event);
+			break;
+
+		case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
+			break;
+		case Common::EVENT_KEYDOWN:
+			changeGameSpeed(_event);
+			_keyPressed = true;
+			_lastChar = _event.kbd.ascii;
+			// _keyState[(byte)toupper(_event.kbd.ascii)] = true;
+			return;
+		case Common::EVENT_KEYUP:
+			// _keyState[(byte)toupper(_event.kbd.ascii)] = false;
+			return;
+		case Common::EVENT_MOUSEMOVE:
+			_mouseX = _event.mouse.x;
+			_mouseY = _event.mouse.y;
+			break;
+		case Common::EVENT_LBUTTONDOWN:
+			_leftMouseButton = 1;
+			g_engine->_mouse->mouseClickX = _event.mouse.x;
+			g_engine->_mouse->mouseClickY = _event.mouse.y;
+			break;
+		case Common::EVENT_LBUTTONUP:
+			_leftMouseButton = 0;
+			break;
+		case Common::EVENT_RBUTTONDOWN:
+			_rightMouseButton = 0;
+			g_engine->_mouse->mouseClickX = _event.mouse.x;
+			g_engine->_mouse->mouseClickY = _event.mouse.y;
+			break;
+		case Common::EVENT_RBUTTONUP:
+			_rightMouseButton = 1;
+			break;
+		default:
+			break;
+		}
+	}
+}
+
+void TotEventManager::zeroEvents(bool allowDrag) {
+	if (!allowDrag) {
+		_leftMouseButton = 0;
+		_rightMouseButton = 0;
+	}
+	_escKeyFl = false;
+	_gameKey = KEY_NONE;
+	_keyPressed = 0;
+	_lastChar = '\0';
+}
+
+void TotEventManager::waitForPress() {
+	bool waitForKey = false;
+	while (!waitForKey && !g_engine->shouldQuit()) {
+		g_engine->_events->pollEvent();
+		if (g_engine->_events->_keyPressed) {
+			waitForKey = true;
+		}
+
+		g_engine->_screen->update();
+		g_system->delayMillis(10);
+	}
+}
+
+void TotEventManager::handleKey(const Common::Event &event) {
+	if (event.customType == kActionVolume)
+		_gameKey = KEY_VOLUME;
+	else if (event.customType == kActionSaveLoad)
+		_gameKey = KEY_SAVELOAD;
+	else if (event.customType == kActionTalk)
+		_gameKey = KEY_TALK;
+	else if (event.customType == kActionPickup)
+		_gameKey = KEY_PICKUP;
+	else if (event.customType == kActionLookAt)
+		_gameKey = KEY_LOOKAT;
+	else if (event.customType == kActionUse)
+		_gameKey = KEY_USE;
+	else if (event.customType == kActionOpen)
+		_gameKey = KEY_OPEN;
+	else if (event.customType == kActionClose)
+		_gameKey = KEY_CLOSE;
+	else if (event.customType == kActionYes)
+		_gameKey = KEY_YES;
+	else if (event.customType == kActionNo)
+		_gameKey = KEY_NO;
+	else if (event.customType == kActionEscape) {
+		_gameKey = KEY_ESCAPE;
+		_escKeyFl = true;
+	}
+}
+
+} // End of namespace Tot
diff --git a/engines/tot/events.h b/engines/tot/events.h
new file mode 100644
index 00000000000..7aa1adfa513
--- /dev/null
+++ b/engines/tot/events.h
@@ -0,0 +1,68 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+#ifndef TOT_EVENTS_H
+#define TOT_EVENTS_H
+
+#include "common/events.h"
+#include "common/scummsys.h"
+
+namespace Tot {
+
+enum GAME_KEY {
+	KEY_TALK = 0,
+	KEY_PICKUP = 1,
+	KEY_LOOKAT = 2,
+	KEY_USE = 3,
+	KEY_OPEN = 4,
+	KEY_CLOSE = 5,
+	KEY_YES = 6,
+	KEY_NO = 7,
+	KEY_SAVELOAD = 8,
+	KEY_VOLUME = 9,
+	KEY_ESCAPE = 10,
+	KEY_NONE = -1
+};
+
+class TotEventManager {
+private:
+	Common::Event _event;
+
+    void handleKey(const Common::Event &event);
+public:
+	bool _escKeyFl = false;
+	bool _keyPressed = false;
+	GAME_KEY _gameKey = KEY_NONE;
+    bool _leftMouseButton = 0;
+    bool _rightMouseButton = 0;
+    int16 _mouseX = 0;
+    int16 _mouseY = 0;
+	uint16 _lastChar = '\0';
+
+	TotEventManager();
+
+	void pollEvent(bool allowDrag = false);
+	void zeroEvents(bool allowDrag = false);
+	void waitForPress();
+
+};
+
+} // End of namespace Tot
+#endif
diff --git a/engines/tot/graphics.cpp b/engines/tot/graphics.cpp
index ba5db3f117d..6818b69f962 100644
--- a/engines/tot/graphics.cpp
+++ b/engines/tot/graphics.cpp
@@ -480,9 +480,7 @@ void GraphicsManager::sceneTransition(bool fadeToBlack, byte *scene) {
 }
 
 void updateScreenIfNeeded(uint32 &targetTime) {
-	Common::Event e;
-	while (g_system->getEventManager()->pollEvent(e)) {
-	}
+	g_engine->_events->pollEvent();
 	if (g_system->getMillis() > targetTime) {
 		g_engine->_graphics->updateSceneArea();
 		targetTime = g_system->getMillis() + 10;
diff --git a/engines/tot/metaengine.cpp b/engines/tot/metaengine.cpp
index 58d122199e0..a345dd29d49 100644
--- a/engines/tot/metaengine.cpp
+++ b/engines/tot/metaengine.cpp
@@ -18,10 +18,15 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
+#include "backends/keymapper/action.h"
+#include "backends/keymapper/keymapper.h"
+#include "backends/keymapper/standard-actions.h"
+
 #include "common/translation.h"
 
 #include "tot/metaengine.h"
 #include "tot/detection.h"
+#include "tot/statics.h"
 #include "tot/tot.h"
 
 static const ADExtraGuiOptionsMap optionsList[] = {
@@ -87,8 +92,100 @@ bool TotMetaEngine::hasFeature(MetaEngineFeature f) const {
 }
 
 const ADExtraGuiOptionsMap *TotMetaEngine::getAdvancedExtraGuiOptions() const {
-		return optionsList;
-	}
+	return optionsList;
+}
+
+Common::KeymapArray TotMetaEngine::initKeymaps(const char *target) const {
+	using namespace Common;
+	using namespace Tot;
+
+	Keymap *engineKeyMap = new Keymap(Keymap::kKeymapTypeGame, "tot-default", _("Default keymappings"));
+	Keymap *gameKeyMap = new Keymap(Keymap::kKeymapTypeGame, "game-shortcuts", _("Game keymappings"));
+	Keymap *quitDialogKeyMap = new Keymap(Keymap::kKeymapTypeGame, "quit-dialog", _("Quit dialog keymappings"));
+
+	Common::Language lang = Common::parseLanguage(ConfMan.get("language", target));
+
+	static const char *const *defaultTotKeys = (lang == ES_ESP) ? keys[0] : keys[1];
+
+	Action *act;
+
+	act = new Action(kStandardActionLeftClick, _("Move / Interact"));
+	act->setLeftClickEvent();
+	act->addDefaultInputMapping("MOUSE_LEFT");
+	act->addDefaultInputMapping("JOY_A");
+	engineKeyMap->addAction(act);
+
+	act = new Action(kStandardActionRightClick, _("Default action"));
+	act->setRightClickEvent();
+	act->addDefaultInputMapping("MOUSE_RIGHT");
+	act->addDefaultInputMapping("JOY_B");
+	engineKeyMap->addAction(act);
+
+	act = new Action("TALK", _("Talk"));
+	act->setCustomEngineActionEvent(kActionTalk);
+	act->addDefaultInputMapping(defaultTotKeys[KEY_TALK]);
+	gameKeyMap->addAction(act);
+
+	act = new Action("PICK", _("Pick"));
+	act->setCustomEngineActionEvent(kActionPickup);
+	act->addDefaultInputMapping(defaultTotKeys[KEY_PICKUP]);
+	gameKeyMap->addAction(act);
+
+	act = new Action("LOOK", _("Look"));
+	act->setCustomEngineActionEvent(kActionLookAt);
+	act->addDefaultInputMapping(defaultTotKeys[KEY_LOOKAT]);
+	gameKeyMap->addAction(act);
+
+	act = new Action("USE", _("Use"));
+	act->setCustomEngineActionEvent(kActionUse);
+	act->addDefaultInputMapping(defaultTotKeys[KEY_USE]);
+	gameKeyMap->addAction(act);
+
+	act = new Action("OPEN", _("Open"));
+	act->setCustomEngineActionEvent(kActionOpen);
+	act->addDefaultInputMapping(defaultTotKeys[KEY_OPEN]);
+	gameKeyMap->addAction(act);
+
+	act = new Action("CLOSE", _("Close"));
+	act->setCustomEngineActionEvent(kActionClose);
+	act->addDefaultInputMapping(defaultTotKeys[KEY_CLOSE]);
+	gameKeyMap->addAction(act);
+
+	act = new Action("SAVELOAD", _("Save and load game"));
+	act->setCustomEngineActionEvent(kActionSaveLoad);
+	act->addDefaultInputMapping("F2");
+	gameKeyMap->addAction(act);
+
+	act = new Action("VOLCONTROLS", _("Volume controls"));
+	act->setCustomEngineActionEvent(kActionVolume);
+	act->addDefaultInputMapping("F1");
+	gameKeyMap->addAction(act);
+
+	act = new Action("MAINMENU", _("Main menu/Exit"));
+	act->setCustomEngineActionEvent(kActionEscape);
+	act->addDefaultInputMapping("ESCAPE");
+	gameKeyMap->addAction(act);
+
+	act = new Action("QUITCONFIRM", _("Confirm quit"));
+	act->setCustomEngineActionEvent(kActionYes);
+	act->addDefaultInputMapping(defaultTotKeys[KEY_YES]);
+	act->addDefaultInputMapping("JOY_RIGHT_TRIGGER");
+	quitDialogKeyMap->addAction(act);
+
+	act = new Action("QUITCANCEL", _("Cancel quit"));
+	act->setCustomEngineActionEvent(kActionNo);
+	act->addDefaultInputMapping(defaultTotKeys[KEY_NO]);
+	act->addDefaultInputMapping("JOY_KEFT_TRIGGER");
+	quitDialogKeyMap->addAction(act);
+
+	KeymapArray keymaps(3);
+
+	keymaps[0] = engineKeyMap;
+	keymaps[1] = gameKeyMap;
+	keymaps[2] = quitDialogKeyMap;
+
+	return keymaps;
+}
 
 #if PLUGIN_ENABLED_DYNAMIC(TOT)
 REGISTER_PLUGIN_DYNAMIC(TOT, PLUGIN_TYPE_ENGINE, TotMetaEngine);
diff --git a/engines/tot/metaengine.h b/engines/tot/metaengine.h
index c97cbff3baf..32cc1c99402 100644
--- a/engines/tot/metaengine.h
+++ b/engines/tot/metaengine.h
@@ -37,7 +37,7 @@ public:
 	 */
 	bool hasFeature(MetaEngineFeature f) const override;
 	const ADExtraGuiOptionsMap *getAdvancedExtraGuiOptions() const override;
-
+	Common::KeymapArray initKeymaps(const char *target) const override;
 };
 
 #endif // TOT_METAENGINE_H
diff --git a/engines/tot/module.mk b/engines/tot/module.mk
index 0400b425d08..6cce2e78d98 100644
--- a/engines/tot/module.mk
+++ b/engines/tot/module.mk
@@ -9,6 +9,7 @@ MODULE_OBJS = \
 	decoder/TotFlicDecoder.o \
 	dialog.o \
 	engine.o \
+	events.o \
 	forest.o \
 	graphics.o \
 	metaengine.o \
diff --git a/engines/tot/saveload.cpp b/engines/tot/saveload.cpp
index cb40808a5cf..42e5aaf0a81 100644
--- a/engines/tot/saveload.cpp
+++ b/engines/tot/saveload.cpp
@@ -571,7 +571,6 @@ Common::String drawAndSelectSaves(Common::StringArray saves, uint selectedGame)
 	const char *availableText = getHardcodedTextsByCurrentLanguage()[11];
 	uint size = saves.size();
 	for (uint i = 0; i < 6; i++) {
-
 		int color = i == selectedGame ? 255 : 253;
 		if (i < size) {
 			Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(saves[i]);
@@ -594,7 +593,7 @@ Common::String drawAndSelectSaves(Common::StringArray saves, uint selectedGame)
 
 void TotEngine::originalSaveLoadScreen() {
 	uint oldMouseX, oldMouseY;
-	uint selectedGame = -1;
+	uint selectedGame = 0;
 	bool modified = false;
 	Common::String saveName = "";
 
@@ -628,7 +627,6 @@ void TotEngine::originalSaveLoadScreen() {
 	_mouse->warpMouse(1, 150, 60);
 
 	do {
-		Common::Event e;
 		bool mouseClicked = false;
 		bool keyPressed = false;
 		char lastInputChar = '\0';
@@ -637,21 +635,12 @@ void TotEngine::originalSaveLoadScreen() {
 			if (_chrono->_gameTick) {
 				_mouse->animateMouseIfNeeded();
 			}
-			while (g_system->getEventManager()->pollEvent(e)) {
-				if (isMouseEvent(e)) {
-					_mouse->warpMouse(e.mouse);
-					_mouse->mouseX = e.mouse.x;
-					_mouse->mouseY = e.mouse.y;
-				}
-
-				if (e.type == Common::EVENT_LBUTTONUP || e.type == Common::EVENT_RBUTTONUP) {
-					mouseClicked = true;
-					_mouse->mouseClickX = e.mouse.x;
-					_mouse->mouseClickY = e.mouse.y;
-				} else if (e.type == Common::EVENT_KEYDOWN) {
-					keyPressed = true;
-					lastInputChar = e.kbd.ascii;
-				}
+			g_engine->_events->pollEvent();
+			if (g_engine->_events->_leftMouseButton || g_engine->_events->_rightMouseButton) {
+				mouseClicked = true;
+			} else if (g_engine->_events->_keyPressed) {
+				keyPressed = true;
+				lastInputChar = g_engine->_events->_lastChar;
 			}
 
 			g_engine->_screen->update();
@@ -740,7 +729,7 @@ void TotEngine::originalSaveLoadScreen() {
 			}
 		}
 
-		if (selectedGame && keyPressed && _saveAllowed) {
+		if (keyPressed && _saveAllowed) {
 			_mouse->hide();
 			byte ytext = 29 + (selectedGame * 15);
 			readAlphaGraphSmall(saveName, 30, 65, ytext, 251, 254, lastInputChar);
diff --git a/engines/tot/sound.cpp b/engines/tot/sound.cpp
index ecf101f8385..c80c57ad21e 100644
--- a/engines/tot/sound.cpp
+++ b/engines/tot/sound.cpp
@@ -113,9 +113,8 @@ void SoundManager::stopVoc() {
 }
 
 void SoundManager::waitForSoundEnd() {
-	Common::Event e;
 	do {
-		while (g_system->getEventManager()->pollEvent(e)) { }
+		g_engine->_events->pollEvent();
 		g_engine->_chrono->updateChrono();
 		g_engine->_screen->update();
 		g_system->delayMillis(10);
diff --git a/engines/tot/statics.h b/engines/tot/statics.h
index 21eb6d7861b..86dd3960123 100644
--- a/engines/tot/statics.h
+++ b/engines/tot/statics.h
@@ -1145,42 +1145,45 @@ static const char *const hardcodedTexts_EN[] = {
 	"Search in row %d and column %d"
 };
 
-static const Common::KeyCode hotkeys[2][8]{
+static const char *const keys[2][8]{
 	// Spanish
 	{// TALK
-	 Common::KEYCODE_h,
+	 "h",
 	 // PICKUP
-	 Common::KEYCODE_c,
+	 "c",
 	 // LOOKAT
-	 Common::KEYCODE_m,
+	 "m",
 	 // USE
-	 Common::KEYCODE_u,
+	 "u",
 	 // OPEN
-	 Common::KEYCODE_a,
+	 "a",
 	 // CLOSE
-	 Common::KEYCODE_e,
+	 "e",
 	 // YES
-	 Common::KEYCODE_s,
+	 "s",
 	 // NO
-	 Common::KEYCODE_n},
+	 "n"
+	},
 
 	// English
 	{// TALK
-	 Common::KEYCODE_t,
+	 "t",
 	 // PICKUP
-	 Common::KEYCODE_a,
+	 "a",
 	 // LOOKAT
-	 Common::KEYCODE_l,
+	 "l",
 	 // USE
-	 Common::KEYCODE_u,
+	 "u",
 	 // OPEN
-	 Common::KEYCODE_o,
+	 "o",
 	 // CLOSE
-	 Common::KEYCODE_c,
+	 "c",
 	 // YES
-	 Common::KEYCODE_y,
+	 "y",
 	 // NO
-	 Common::KEYCODE_n}};
+	 "n"
+	}
+	};
 
 const int FONT_LITT_OFFSET_ES = 153584;
 const int FONT_EURO_OFFSET_ES = 159681;
diff --git a/engines/tot/tot.cpp b/engines/tot/tot.cpp
index 5a24d935ff8..c5fcef1ef50 100644
--- a/engines/tot/tot.cpp
+++ b/engines/tot/tot.cpp
@@ -33,6 +33,7 @@
 #include "tot/detection.h"
 #include "tot/debug.h"
 #include "tot/dialog.h"
+#include "tot/events.h"
 #include "tot/sound.h"
 #include "tot/tot.h"
 #include "tot/util.h"
@@ -57,6 +58,7 @@ TotEngine::~TotEngine() {
 	delete _sound;
 	delete _chrono;
 	delete _mouse;
+	delete _events;
 }
 
 uint32 TotEngine::getFeatures() const {
@@ -79,6 +81,7 @@ Common::Error TotEngine::run() {
 	_sound = new SoundManager(_mixer);
 	_chrono = new ChronoManager();
 	_mouse = new MouseManager();
+	_events = new TotEventManager();
 
 	_sound->init();
 	syncSoundSettings();
@@ -146,6 +149,257 @@ void TotEngine::resumeGame() {
 	loadGameState(getMetaEngine()->getAutosaveSlot());
 }
 
+void TotEngine::processEvents(bool &escapePressed) {
+	_events->pollEvent();
+	if (_events->_escKeyFl) {
+		escapePressed = true;
+	} else if (_events->_gameKey == KEY_VOLUME) {
+		soundControls();
+		g_engine->_events->zeroEvents();
+	} else if (_events->_gameKey == KEY_SAVELOAD) {
+		if (ConfMan.getBool("original_save_load_screen"))
+			originalSaveLoadScreen();
+		else
+			openMainMenuDialog();
+
+		g_engine->_events->zeroEvents();
+	} else if (_events->_gameKey == KEY_OPEN) {
+		_actionCode = 5;
+		action();
+		_oldGridX = 0;
+		_oldGridY = 0;
+	} else if (_events->_gameKey == KEY_CLOSE) {
+		_actionCode = 6;
+		action();
+		_oldGridX = 0;
+		_oldGridY = 0;
+	} else if (_events->_gameKey == KEY_PICKUP) {
+		_actionCode = 2;
+		action();
+		_oldGridX = 0;
+		_oldGridY = 0;
+	} else if (_events->_gameKey == KEY_TALK) {
+		_actionCode = 1;
+		action();
+		_oldGridX = 0;
+		_oldGridY = 0;
+	} else if (_events->_gameKey == KEY_LOOKAT) {
+		_actionCode = 3;
+		action();
+		_oldGridX = 0;
+		_oldGridY = 0;
+	} else if (_events->_gameKey == KEY_USE) {
+		_actionCode = 4;
+		action();
+		_oldGridX = 0;
+		_oldGridY = 0;
+	} else if (_events->_gameKey == KEY_NONE && _events->_keyPressed) {
+		_actionCode = 0; // go to
+		action();
+	}
+
+	if (_events->_leftMouseButton == 1) {
+		_mouse->mouseClickX = _events->_mouseX;
+		_mouse->mouseClickY = _events->_mouseY;
+		if (_mouse->mouseClickY > 0 && _mouse->mouseClickY < 131) {
+			switch (_actionCode) {
+			case 0: // go to
+				_cpCounter2 = _cpCounter;
+				// gets the zone where the character is now standing. Zone is calculated using xframe,yframe plus some adjustments to get the center of the feet
+				_currentZone = _currentRoomData->walkAreasGrid[(_characterPosX + kCharacterCorrectionX) / kXGridCount][(_characterPosY + kCharacerCorrectionY) / kYGridCount];
+				if (_currentZone < 10) {
+					_xframe2 = _mouse->mouseClickX + 7;
+					_yframe2 = _mouse->mouseClickY + 7;
+					// obtains the target zone from the clicked coordinates
+					_targetZone = _currentRoomData->walkAreasGrid[_xframe2 / kXGridCount][_yframe2 / kYGridCount];
+					if (_currentRoomData->code == 21 && _currentRoomData->animationFlag) {
+						if ((_targetZone >= 1 && _targetZone <= 5) ||
+							(_targetZone >= 9 && _targetZone <= 13) ||
+							(_targetZone >= 18 && _targetZone <= 21) ||
+							_targetZone == 24 || _targetZone == 25) {
+
+							_targetZone = 7;
+							_mouse->mouseClickX = 232;
+							_mouse->mouseClickY = 75;
+
+							_xframe2 = _mouse->mouseClickX + 7;
+							_yframe2 = _mouse->mouseClickY + 7;
+						}
+					}
+
+					if (_oldTargetZone != _targetZone || _targetZone < 10) {
+						_oldTargetZone = _targetZone;
+						// Resets the entire route
+						calculateRoute(_currentZone, _targetZone);
+
+						_doorIndex = 0;
+						_roomChange = false;
+
+						for (_doorIndex = 0; _doorIndex < 5; _doorIndex++) {
+							if (_currentRoomData->doors[_doorIndex].doorcode == _targetZone) {
+
+								if (_currentRoomData->doors[_doorIndex].openclosed == 1) {
+									_roomChange = true;
+									break;
+								} else if ((_currentRoomData->code == 5 && _targetZone == 27) || (_currentRoomData->code == 6 && _targetZone == 21)) {
+									;
+								} else {
+									_trajectorySteps -= 1;
+								}
+							}
+						}
+						// Sets xframe2 again due to the substraction when closed doors
+						_xframe2 = _trajectorySteps;
+					} else
+						_xframe2 = 0;
+				}
+				break;
+			case 1: // talk
+				_roomChange = false;
+				_actionCode = 0;
+				talkToSceneObject();
+				_cpCounter2 = _cpCounter;
+				break;
+			case 2: // pick up
+				_roomChange = false;
+				_actionCode = 0;
+				pickupScreenObject();
+				_cpCounter = _cpCounter2;
+				break;
+			case 3: // look at
+				_roomChange = false;
+				_destinationX = _mouse->getClickCoordsWithinGrid().x;
+				_destinationY = _mouse->getClickCoordsWithinGrid().y;
+				if (_currentRoomData->screenObjectIndex[_currentRoomData->mouseGrid[_destinationX][_destinationY]]->fileIndex > 0) {
+					goToObject(
+						_currentRoomData->walkAreasGrid[(_characterPosX + kCharacterCorrectionX) / kXGridCount][(_characterPosY + kCharacerCorrectionY) / kYGridCount],
+						_currentRoomData->walkAreasGrid[_destinationX][_destinationY]);
+					if (_currentRoomData->screenObjectIndex[_currentRoomData->mouseGrid[_destinationX][_destinationY]]->fileIndex == 562)
+
+						switch (_currentRoomData->code) {
+						case 20:
+							if (_niche[0][_niche[0][3]] > 0)
+								readObject(_niche[0][_niche[0][3]]);
+							else
+								readObject(562);
+							break;
+						case 24:
+							if (_niche[1][_niche[1][3]] > 0)
+								readObject(_niche[1][_niche[1][3]]);
+							else
+								readObject(562);
+							break;
+						}
+					else
+						readObject(_currentRoomData->screenObjectIndex[_currentRoomData->mouseGrid[_destinationX][_destinationY]]->fileIndex);
+					if (_curObject.lookAtTextRef > 0)
+						drawText(_curObject.lookAtTextRef);
+					_actionCode = 0;
+				}
+				break;
+			case 4: // use
+				_roomChange = false;
+				_actionCode = 0;
+				useScreenObject();
+				_cpCounter = _cpCounter2;
+				break;
+			case 5: // open
+				_roomChange = false;
+				_actionCode = 0;
+				openScreenObject();
+				break;
+			case 6: { // close
+				_roomChange = false;
+				_actionCode = 0;
+				closeScreenObject();
+				_cpCounter = _cpCounter2;
+			} break;
+			}
+		} else if (_mouse->mouseClickY > 148 && _mouse->mouseClickY < 158) {
+			if (_mouse->mouseClickX >= 3 && _mouse->mouseClickX <= 53) {
+				_actionCode = 1;
+				action();
+			} else if (_mouse->mouseClickX >= 58 && _mouse->mouseClickX <= 103) {
+				_actionCode = 2;
+				action();
+			} else if (_mouse->mouseClickX >= 108 && _mouse->mouseClickX <= 153) {
+				_actionCode = 3;
+				action();
+			} else if (_mouse->mouseClickX >= 158 && _mouse->mouseClickX <= 198) {
+				_actionCode = 4;
+				action();
+			} else if (_mouse->mouseClickX >= 203 && _mouse->mouseClickX <= 248) {
+				_actionCode = 5;
+				action();
+			} else if (_mouse->mouseClickX >= 253 && _mouse->mouseClickX <= 311) {
+				_actionCode = 6;
+				action();
+			} else {
+				_actionCode = 0;
+				action();
+				_cpCounter2 = _cpCounter;
+			}
+		} else if (_mouse->mouseClickY > 166 && _mouse->mouseClickY < 199) {
+			if (_mouse->mouseClickX >= 3 && _mouse->mouseClickX <= 19) {
+				drawInventory(0, 33);
+			} else if (_mouse->mouseClickX >= 26 && _mouse->mouseClickX <= 65) {
+				handleAction(_inventoryPosition);
+			} else if (_mouse->mouseClickX >= 70 && _mouse->mouseClickX <= 108) {
+				handleAction(_inventoryPosition + 1);
+			} else if (_mouse->mouseClickX >= 113 && _mouse->mouseClickX <= 151) {
+				handleAction(_inventoryPosition + 2);
+			} else if (_mouse->mouseClickX >= 156 && _mouse->mouseClickX <= 194) {
+				handleAction(_inventoryPosition + 3);
+			} else if (_mouse->mouseClickX >= 199 && _mouse->mouseClickX <= 237) {
+				handleAction(_inventoryPosition + 4);
+			} else if (_mouse->mouseClickX >= 242 && _mouse->mouseClickX <= 280) {
+				handleAction(_inventoryPosition + 5);
+			} else if (_mouse->mouseClickX >= 290 && _mouse->mouseClickX <= 311) {
+				drawInventory(1, 33);
+			} else {
+				_actionCode = 0;
+				action();
+			}
+		}
+	} else if (_events->_rightMouseButton) {
+		_mouse->mouseClickX = _events->_mouseX;
+		_mouse->mouseClickY = _events->_mouseY;
+		Common::Point p = _mouse->getClickCoordsWithinGrid();
+		_destinationX = p.x;
+		_destinationY = p.y;
+		_cpCounter2 = _cpCounter;
+		if (_destinationY < 28) {
+			RoomObjectListEntry obj = *_currentRoomData->screenObjectIndex[_currentRoomData->mouseGrid[_destinationX][_destinationY]];
+			if (obj.fileIndex > 0) {
+
+				drawLookAtItem(obj);
+				goToObject(_currentRoomData->walkAreasGrid[(_characterPosX + kCharacterCorrectionX) / kXGridCount][(_characterPosY + kCharacerCorrectionY) / kYGridCount], _currentRoomData->walkAreasGrid[_destinationX][_destinationY]);
+				if (obj.fileIndex == 562)
+
+					switch (_currentRoomData->code) {
+					case 20:
+						if (_niche[0][_niche[0][3]] > 0)
+							readObject(_niche[0][_niche[0][3]]);
+						else
+							readObject(562);
+						break;
+					case 24:
+						if (_niche[1][_niche[1][3]] > 0)
+							readObject(_niche[1][_niche[1][3]]);
+						else
+							readObject(562);
+						break;
+					}
+				else
+					readObject(obj.fileIndex);
+				if (_curObject.lookAtTextRef > 0)
+					drawText(_curObject.lookAtTextRef);
+				_actionCode = 0;
+			}
+		}
+	}
+}
+
 int TotEngine::startGame() {
 	_sound->fadeOutMusic();
 	switch (_gamePart) {
@@ -160,301 +414,12 @@ int TotEngine::startGame() {
 	_sound->fadeInMusic();
 	_inGame = true;
 
-	Common::Event e;
-	const char hotKeyOpen = hotKeyFor(OPEN);
-	const char hotKeyClose = hotKeyFor(CLOSE);
-	const char hotKeyPickup = hotKeyFor(PICKUP);
-	const char hotKeyTalk = hotKeyFor(TALK);
-	const char hotKeyLook = hotKeyFor(LOOKAT);
-	const char hotKeyUse = hotKeyFor(USE);
-
 	while (!_shouldQuitGame && !shouldQuit()) {
 		bool escapePressed = false;
 		_chrono->updateChrono();
 		_mouse->animateMouseIfNeeded();
-		// debug
-		while (g_system->getEventManager()->pollEvent(e)) {
-			if (isMouseEvent(e)) {
-				_mouse->warpMouse(e.mouse);
-				_mouse->mouseX = e.mouse.x;
-				_mouse->mouseY = e.mouse.y;
-			}
-			if (e.type == Common::EVENT_KEYDOWN) {
-				changeGameSpeed(e);
-
-				switch (e.kbd.keycode) {
-
-				case Common::KEYCODE_UP:
-					_sound->fadeInMusic();
-					break;
-
-				case Common::KEYCODE_DOWN:
-					_sound->fadeOutMusic();
-					break;
-
-				case Common::KEYCODE_ESCAPE:
-					escapePressed = true;
-					break;
-				case Common::KEYCODE_F1:
-					soundControls();
-					break;
-				case Common::KEYCODE_F2:
-					if(ConfMan.getBool("original_save_load_screen"))
-						originalSaveLoadScreen();
-					else
-						openMainMenuDialog();
-					break;
-				default:
-					if (e.kbd.keycode == hotKeyOpen) {
-						_actionCode = 5;
-						action();
-						_oldGridX = 0;
-						_oldGridY = 0;
-					} else if (e.kbd.keycode == hotKeyClose) {
-						_actionCode = 6;
-						action();
-						_oldGridX = 0;
-						_oldGridY = 0;
-					} else if (e.kbd.keycode == hotKeyPickup) {
-						_actionCode = 2;
-						action();
-						_oldGridX = 0;
-						_oldGridY = 0;
-					} else if (e.kbd.keycode == hotKeyTalk) {
-						_actionCode = 1;
-						action();
-						_oldGridX = 0;
-						_oldGridY = 0;
-					} else if (e.kbd.keycode == hotKeyLook) {
-						_actionCode = 3;
-						action();
-						_oldGridX = 0;
-						_oldGridY = 0;
-					} else if (e.kbd.keycode == hotKeyUse) {
-						_actionCode = 4;
-						action();
-						_oldGridX = 0;
-						_oldGridY = 0;
-					} else {
-						_actionCode = 0; // go to
-					}
-				}
-			} else if (e.type == Common::EVENT_LBUTTONUP) {
-				_mouse->mouseClickX = e.mouse.x;
-				_mouse->mouseClickY = e.mouse.y;
-				if (_mouse->mouseClickY > 0 && _mouse->mouseClickY < 131) {
-					switch (_actionCode) {
-					case 0: // go to
-						_cpCounter2 = _cpCounter;
-						// gets the zone where the character is now standing. Zone is calculated using xframe,yframe plus some adjustments to get the center of the feet
-						_currentZone = _currentRoomData->walkAreasGrid[(_characterPosX + kCharacterCorrectionX) / kXGridCount][(_characterPosY + kCharacerCorrectionY) / kYGridCount];
-						if (_currentZone < 10) {
-							_xframe2 = _mouse->mouseClickX + 7;
-							_yframe2 = _mouse->mouseClickY + 7;
-							// obtains the target zone from the clicked coordinates
-							_targetZone = _currentRoomData->walkAreasGrid[_xframe2 / kXGridCount][_yframe2 / kYGridCount];
-							if (_currentRoomData->code == 21 && _currentRoomData->animationFlag) {
-								if ((_targetZone >= 1 && _targetZone <= 5) ||
-									(_targetZone >= 9 && _targetZone <= 13) ||
-									(_targetZone >= 18 && _targetZone <= 21) ||
-									_targetZone == 24 || _targetZone == 25) {
-
-									_targetZone = 7;
-									_mouse->mouseClickX = 232;
-									_mouse->mouseClickY = 75;
-
-									_xframe2 = _mouse->mouseClickX + 7;
-									_yframe2 = _mouse->mouseClickY + 7;
-								}
-							}
-
-							if (_oldTargetZone != _targetZone || _targetZone < 10) {
-								_oldTargetZone = _targetZone;
-								// Resets the entire route
-								calculateRoute(_currentZone, _targetZone);
-
-								_doorIndex = 0;
-								_roomChange = false;
-
-								for (_doorIndex = 0; _doorIndex < 5; _doorIndex++) {
-									if (_currentRoomData->doors[_doorIndex].doorcode == _targetZone) {
-
-										if (_currentRoomData->doors[_doorIndex].openclosed == 1) {
-											_roomChange = true;
-											break;
-										} else if ((_currentRoomData->code == 5 && _targetZone == 27) || (_currentRoomData->code == 6 && _targetZone == 21)) {
-											;
-										} else {
-											_trajectorySteps -= 1;
-										}
-									}
-								}
-								// Sets xframe2 again due to the substraction when closed doors
-								_xframe2 = _trajectorySteps;
-							} else
-								_xframe2 = 0;
-						}
-						break;
-					case 1: // talk
-						_roomChange = false;
-						_actionCode = 0;
-						talkToSceneObject();
-						_cpCounter2 = _cpCounter;
-						break;
-					case 2: // pick up
-						_roomChange = false;
-						_actionCode = 0;
-						pickupScreenObject();
-						_cpCounter = _cpCounter2;
-						break;
-					case 3: // look at
-						_roomChange = false;
-						_destinationX = _mouse->getClickCoordsWithinGrid().x;
-						_destinationY =  _mouse->getClickCoordsWithinGrid().y;
-						if (_currentRoomData->screenObjectIndex[_currentRoomData->mouseGrid[_destinationX][_destinationY]]->fileIndex > 0) {
-							goToObject(
-								_currentRoomData->walkAreasGrid[(_characterPosX + kCharacterCorrectionX) / kXGridCount][(_characterPosY + kCharacerCorrectionY) / kYGridCount],
-								_currentRoomData->walkAreasGrid[_destinationX][_destinationY]);
-							if (_currentRoomData->screenObjectIndex[_currentRoomData->mouseGrid[_destinationX][_destinationY]]->fileIndex == 562)
-
-								switch (_currentRoomData->code) {
-								case 20:
-									if (_niche[0][_niche[0][3]] > 0)
-										readObject(_niche[0][_niche[0][3]]);
-									else
-										readObject(562);
-									break;
-								case 24:
-									if (_niche[1][_niche[1][3]] > 0)
-										readObject(_niche[1][_niche[1][3]]);
-									else
-										readObject(562);
-									break;
-								}
-							else
-								readObject(_currentRoomData->screenObjectIndex[_currentRoomData->mouseGrid[_destinationX][_destinationY]]->fileIndex);
-							if (_curObject.lookAtTextRef > 0)
-								drawText(_curObject.lookAtTextRef);
-							_actionCode = 0;
-						}
-						break;
-					case 4: // use
-						_roomChange = false;
-						_actionCode = 0;
-						useScreenObject();
-						_cpCounter = _cpCounter2;
-						break;
-					case 5: // open
-						_roomChange = false;
-						_actionCode = 0;
-						openScreenObject();
-						break;
-					case 6: { // close
-						_roomChange = false;
-						_actionCode = 0;
-						closeScreenObject();
-						_cpCounter = _cpCounter2;
-					} break;
-					}
-				} else if (_mouse->mouseClickY > 148 && _mouse->mouseClickY < 158) {
-					if (_mouse->mouseClickX >= 3 && _mouse->mouseClickX <= 53) {
-						_actionCode = 1;
-						action();
-						break;
-					} else if (_mouse->mouseClickX >= 58 && _mouse->mouseClickX <= 103) {
-						_actionCode = 2;
-						action();
-						break;
-					} else if (_mouse->mouseClickX >= 108 && _mouse->mouseClickX <= 153) {
-						_actionCode = 3;
-						action();
-						break;
-					} else if (_mouse->mouseClickX >= 158 && _mouse->mouseClickX <= 198) {
-						_actionCode = 4;
-						action();
-						break;
-					} else if (_mouse->mouseClickX >= 203 && _mouse->mouseClickX <= 248) {
-						_actionCode = 5;
-						action();
-						break;
-					} else if (_mouse->mouseClickX >= 253 && _mouse->mouseClickX <= 311) {
-						_actionCode = 6;
-						action();
-						break;
-					} else {
-						_actionCode = 0;
-						action();
-						_cpCounter2 = _cpCounter;
-					}
-				} else if (_mouse->mouseClickY > 166 && _mouse->mouseClickY < 199) {
-					if (_mouse->mouseClickX >= 3 && _mouse->mouseClickX <= 19) {
-						drawInventory(0, 33);
-						break;
-					} else if (_mouse->mouseClickX >= 26 && _mouse->mouseClickX <= 65) {
-						handleAction(_inventoryPosition);
-						break;
-					} else if (_mouse->mouseClickX >= 70 && _mouse->mouseClickX <= 108) {
-						handleAction(_inventoryPosition + 1);
-						break;
-					} else if (_mouse->mouseClickX >= 113 && _mouse->mouseClickX <= 151) {
-						handleAction(_inventoryPosition + 2);
-						break;
-					} else if (_mouse->mouseClickX >= 156 && _mouse->mouseClickX <= 194) {
-						handleAction(_inventoryPosition + 3);
-						break;
-					} else if (_mouse->mouseClickX >= 199 && _mouse->mouseClickX <= 237) {
-						handleAction(_inventoryPosition + 4);
-						break;
-					} else if (_mouse->mouseClickX >= 242 && _mouse->mouseClickX <= 280) {
-						handleAction(_inventoryPosition + 5);
-						break;
-					} else if (_mouse->mouseClickX >= 290 && _mouse->mouseClickX <= 311) {
-						drawInventory(1, 33);
-						break;
-					} else {
-						_actionCode = 0;
-						action();
-					}
-				}
-			} else if (e.type == Common::EVENT_RBUTTONUP) {
-				_mouse->mouseClickX = e.mouse.x;
-				_mouse->mouseClickY = e.mouse.y;
-				Common::Point p = _mouse->getClickCoordsWithinGrid();
-				_destinationX = p.x;
-				_destinationY = p.y;
-				_cpCounter2 = _cpCounter;
-				if (_destinationY < 28) {
-					RoomObjectListEntry obj = *_currentRoomData->screenObjectIndex[_currentRoomData->mouseGrid[_destinationX][_destinationY]];
-					if (obj.fileIndex > 0) {
-
-						drawLookAtItem(obj);
-						goToObject(_currentRoomData->walkAreasGrid[(_characterPosX + kCharacterCorrectionX) / kXGridCount][(_characterPosY + kCharacerCorrectionY) / kYGridCount], _currentRoomData->walkAreasGrid[_destinationX][_destinationY]);
-						if (obj.fileIndex == 562)
-
-							switch (_currentRoomData->code) {
-							case 20:
-								if (_niche[0][_niche[0][3]] > 0)
-									readObject(_niche[0][_niche[0][3]]);
-								else
-									readObject(562);
-								break;
-							case 24:
-								if (_niche[1][_niche[1][3]] > 0)
-									readObject(_niche[1][_niche[1][3]]);
-								else
-									readObject(562);
-								break;
-							}
-						else
-							readObject(obj.fileIndex);
-						if (_curObject.lookAtTextRef > 0)
-							drawText(_curObject.lookAtTextRef);
-						_actionCode = 0;
-					}
-				}
-			}
-		}
 
+		processEvents(escapePressed);
 		checkMouseGrid();
 		advanceAnimations(false, true);
 
@@ -958,7 +923,7 @@ void TotEngine::changeRoom() {
 		_mouse->show();
 	}
 	}
-	
+
 	if (_currentRoomData->doors[_doorIndex].nextScene != 255) {
 		_oldGridX = 0;
 		_oldGridY = 0;
@@ -1197,7 +1162,7 @@ void TotEngine::clearVars() {
 	if (_currentRoomData) {
 		delete _currentRoomData;
 	}
-	
+
 	clearScreenLayers();
 
 	for (int i = 0; i < kInventoryIconCount; i++) {
@@ -1245,65 +1210,58 @@ void TotEngine::mainMenu(bool fade) {
 	_mouse->mouseMaskIndex = 1;
 	_mouse->warpMouse(_mouse->mouseMaskIndex, _mouse->mouseX, _mouse->mouseY);
 	_mouse->show();
-	Common::Event e;
 	do {
 		_chrono->updateChrono();
 		_mouse->animateMouseIfNeeded();
-		while (g_system->getEventManager()->pollEvent(e)) {
-			if (isMouseEvent(e)) {
-				_mouse->warpMouse(e.mouse);
-			}
-			if (e.type == Common::EVENT_KEYDOWN) {
-				if (e.kbd.keycode == Common::KEYCODE_ESCAPE) {
-					exitToDOS();
+		_events->pollEvent();
+
+		if (_events->_escKeyFl) {
+			exitToDOS();
+		}
+		if (_events->_leftMouseButton) {
+			uint x = _events->_mouseX + 7;
+			uint y = _events->_mouseY + 7;
+			if (y > 105 && y < 120) {
+				if (x > 46 && x < 145) {
+					_startNewGame = true;
+					_continueGame = false;
+					validOption = true;
+				} else if (x > 173 && x < 267) {
+					credits();
+					if (!g_engine->shouldQuit()) {
+						drawFlc(0, 0, offset, 0, 9, 0, true, false, false, bar);
+					}
 				}
-			}
-			if (e.type == Common::EVENT_LBUTTONUP) {
-				uint x = e.mouse.x + 7;
-				uint y = e.mouse.y + 7;
-				if (y > 105 && y < 120) {
-					if (x > 46 && x < 145) {
-						_startNewGame = true;
-						_continueGame = false;
-						validOption = true;
-					} else if (x > 173 && x < 267) {
-						credits();
-						if(!g_engine->shouldQuit()) {
-							drawFlc(0, 0, offset, 0, 9, 0, true, false, false, bar);
-						}
+			} else if (y > 140 && y < 155) {
+				if (x > 173 && x < 292) {
+					_graphics->totalFadeOut(0);
+					_screen->clear();
+					introduction();
+					if (!g_engine->shouldQuit()) {
+						drawFlc(0, 0, offset, 0, 9, 0, true, false, false, bar);
 					}
-				} else if (y > 140 && y < 155) {
-					if (x > 173 && x < 292) {
-						_graphics->totalFadeOut(0);
-						_screen->clear();
-						introduction();
-						if(!g_engine->shouldQuit()) {
-							drawFlc(0, 0, offset, 0, 9, 0, true, false, false, bar);
-						}
-					} else if (x >= 18 && x <= 145) {
-						_isSavingDisabled = true;
-						if(ConfMan.getBool("original_save_load_screen")) {
-							originalSaveLoadScreen();
+				} else if (x >= 18 && x <= 145) {
+					_isSavingDisabled = true;
+					if (ConfMan.getBool("original_save_load_screen")) {
+						originalSaveLoadScreen();
+						validOption = true;
+					} else {
+						bool result = loadGameDialog();
+						if (result) {
 							validOption = true;
 						}
-						else {
-							bool result = loadGameDialog();
-							if(result) {
-								validOption = true;
-							}
-						}
-						_startNewGame = false;
-						_continueGame = false;
-						_isSavingDisabled = false;
-					}
-				} else if (y > 174 && y < 190) {
-					if (x > 20 && x < 145) {
-						_startNewGame = false;
-						validOption = true;
-						_continueGame = true;
-					} else if (x > 173 && y < 288) {
-						exitToDOS();
 					}
+					_startNewGame = false;
+					_continueGame = false;
+					_isSavingDisabled = false;
+				}
+			} else if (y > 174 && y < 190) {
+				if (x > 20 && x < 145) {
+					_startNewGame = false;
+					validOption = true;
+					_continueGame = true;
+				} else if (x > 173 && y < 288) {
+					exitToDOS();
 				}
 			}
 		}
@@ -1324,7 +1282,6 @@ void TotEngine::clearGame() {
 }
 
 void TotEngine::exitToDOS() {
-	debug("Exit to dos!");
 	uint oldMousePosX, oldMousePosY, dialogSize;
 	byte oldMouseMask;
 	char exitChar;
@@ -1344,36 +1301,28 @@ void TotEngine::exitToDOS() {
 
 	_mouse->setMouseArea(Common::Rect(115, 80, 190, 100));
 	_mouse->warpMouse(_mouse->mouseMaskIndex, _mouse->mouseX, _mouse->mouseY);
-	Common::Event e;
-	const char hotKeyYes = hotKeyFor(YES);
-	const char hotKeyNo = hotKeyFor(NO);
 	exitChar = '@';
 	do {
 		_chrono->updateChrono();
 		_mouse->animateMouseIfNeeded();
+		_events->pollEvent();
+		if (_events->_escKeyFl) {
+			exitChar = '\33';
+		} else if (_events->_gameKey == KEY_YES) {
+			debug("would exit game now");
+			free(dialogBackground);
+			exitGame();
+		} else if (_events->_gameKey == KEY_NO) {
+			exitChar = '\33';
+		}
 
-		while (g_system->getEventManager()->pollEvent(e)) {
-			if (isMouseEvent(e)) {
-				_mouse->warpMouse(e.mouse);
-			}
-			if (e.type == Common::EVENT_KEYDOWN) {
-				if (e.kbd.keycode == Common::KEYCODE_ESCAPE) {
-					exitChar = '\33';
-				} else if (e.kbd.keycode == hotKeyYes) {
-					debug("would exit game now");
-					free(dialogBackground);
-					exitGame();
-				} else if (e.kbd.keycode == hotKeyNo) {
-					exitChar = '\33';
-				}
-			} else if (e.type == Common::EVENT_LBUTTONUP) {
-				uint x = e.mouse.x;
-				if (x < 145) {
-					free(dialogBackground);
-					g_system->quit();
-				} else if (x > 160) {
-					exitChar = '\33';
-				}
+		if (_events->_leftMouseButton) {
+			uint x = g_engine->_mouse->mouseClickX;
+			if (x < 145) {
+				free(dialogBackground);
+				g_system->quit();
+			} else if (x > 160) {
+				exitChar = '\33';
 			}
 		}
 		_screen->update();
diff --git a/engines/tot/tot.h b/engines/tot/tot.h
index c54b32ff73f..a6cd91c6e5f 100644
--- a/engines/tot/tot.h
+++ b/engines/tot/tot.h
@@ -38,6 +38,7 @@
 
 #include "tot/chrono.h"
 #include "tot/detection.h"
+#include "tot/events.h"
 #include "tot/graphics.h"
 #include "tot/mouse.h"
 #include "tot/sound.h"
@@ -47,6 +48,20 @@ namespace Tot {
 
 struct TotGameDescription;
 
+enum TotAction {
+	kActionEscape,
+	kActionVolume,
+	kActionSaveLoad,
+	kActionTalk,
+	kActionPickup,
+	kActionLookAt,
+	kActionUse,
+	kActionOpen,
+	kActionClose,
+	kActionYes,
+	kActionNo
+};
+
 class TotEngine : public Engine {
 
 private:
@@ -164,6 +179,8 @@ private:
 	void resetGameState();
 	void clearVars();
 
+	void processEvents(bool &escapePressed);
+	void oldProcessEvents(bool &escapePressed);
 protected:
 	// Engine APIs
 	Common::Error run() override;
@@ -171,10 +188,11 @@ protected:
 
 public:
 	Graphics::Screen *_screen = nullptr;
-	Tot::GraphicsManager *_graphics = nullptr;
+	GraphicsManager *_graphics = nullptr;
 	SoundManager *_sound = nullptr;
 	MouseManager *_mouse = nullptr;
 	ChronoManager *_chrono = nullptr;
+	Tot::TotEventManager *_events = nullptr;
 
 	bool _showMouseGrid = false;
 	bool _showScreenGrid = false;
diff --git a/engines/tot/types.h b/engines/tot/types.h
index 77af95dd618..040d1743771 100644
--- a/engines/tot/types.h
+++ b/engines/tot/types.h
@@ -285,17 +285,6 @@ struct SavedGame {
 
 typedef byte Palette[768];
 
-enum HOTKEYS {
-    TALK = 0,
-    PICKUP = 1,
-    LOOKAT = 2,
-    USE = 3,
-    OPEN = 4,
-    CLOSE = 5,
-    YES = 6,
-    NO = 7
-};
-
 } // End of namespace Tot
 
 #endif
diff --git a/engines/tot/util.cpp b/engines/tot/util.cpp
index 67dd6f72667..822826a6ea8 100644
--- a/engines/tot/util.cpp
+++ b/engines/tot/util.cpp
@@ -480,33 +480,12 @@ void emptyLoop2() {
 	} while (!g_engine->_chrono->_gameTickHalfSpeed);
 }
 
-void waitForKey() {
-	bool waitForKey = false;
-	Common::Event e;
-	debug("Waiting for key!");
-	while (!waitForKey && !g_engine->shouldQuit()) {
-		while (g_system->getEventManager()->pollEvent(e)) {
-			if (e.type == Common::EVENT_KEYDOWN) {
-				waitForKey = true;
-			}
-		}
-
-		g_engine->_screen->update();
-		g_system->delayMillis(10);
-	}
-}
-
 int getRandom(int range) { return g_engine->getRandomNumber(range - 1); }
 
 Common::String getObjectName(int idx) {
 	return g_engine->_lang == Common::ES_ESP ? hardcodedTexts_ES[idx] : hardcodedTexts_EN[idx];
 }
 
-Common::KeyCode hotKeyFor(HOTKEYS hotkey) {
-	const Common::KeyCode *selectedHotkeys = (g_engine->_lang == Common::ES_ESP)? hotkeys[0]: hotkeys[1];
-	return selectedHotkeys[hotkey];
-};
-
 Common::String getActionLineText(int idx) {
 	return g_engine->_lang == Common::ES_ESP ? actionLine_ES[idx] : actionLine_EN[idx];
 }
diff --git a/engines/tot/util.h b/engines/tot/util.h
index 880430df71c..84183b699fa 100644
--- a/engines/tot/util.h
+++ b/engines/tot/util.h
@@ -58,8 +58,6 @@ void emptyLoop();
 
 void emptyLoop2();
 
-void waitForKey();
-
 void changeGameSpeed(Common::Event e);
 
 inline bool odd(int32 i) { return i % 2 != 0; }
@@ -68,8 +66,6 @@ int getRandom(int range);
 
 Common::String getObjectName(int idx);
 
-Common::KeyCode hotKeyFor(HOTKEYS hotkey);
-
 Common::String getActionLineText(int idx);
 
 const char *const *getFullScreenMessagesByCurrentLanguage();




More information about the Scummvm-git-logs mailing list