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 "twine/input.h"
24 #include "backends/keymapper/keymapper.h"
25 #include "common/events.h"
26 #include "common/keyboard.h"
27 #include "common/system.h"
28 #include "twine/scene/actor.h"
29 #include "twine/twine.h"
30
31 namespace TwinE {
32
33 const char *mainKeyMapId = "mainKeyMap";
34 const char *uiKeyMapId = "uiKeyMap";
35 const char *cutsceneKeyMapId = "cutsceneKeyMap";
36 const char *holomapKeyMapId = "holomapKeyMap";
37
ScopedKeyMap(TwinEEngine * engine,const char * id)38 ScopedKeyMap::ScopedKeyMap(TwinEEngine* engine, const char *id) : _engine(engine) {
39 _changed = _engine->_input->enableAdditionalKeyMap(id, true);
40 _keymap = id;
41 }
42
~ScopedKeyMap()43 ScopedKeyMap::~ScopedKeyMap() {
44 if (_changed) {
45 _engine->_input->enableAdditionalKeyMap(_keymap.c_str(), false);
46 }
47 }
48
Input(TwinEEngine * engine)49 Input::Input(TwinEEngine *engine) : _engine(engine) {}
50
isActionActive(TwinEActionType actionType,bool onlyFirstTime) const51 bool Input::isActionActive(TwinEActionType actionType, bool onlyFirstTime) const {
52 if (onlyFirstTime) {
53 return _actionStates[actionType] == 1;
54 }
55 return _actionStates[actionType] > 0;
56 }
57
toggleActionIfActive(TwinEActionType actionType)58 bool Input::toggleActionIfActive(TwinEActionType actionType) {
59 if (_actionStates[actionType] > 0) {
60 _actionStates[actionType] = 0;
61 return true;
62 }
63 return false;
64 }
65
toggleAbortAction()66 bool Input::toggleAbortAction() {
67 bool abortState = false;
68 abortState |= toggleActionIfActive(TwinEActionType::CutsceneAbort);
69 abortState |= toggleActionIfActive(TwinEActionType::UIAbort);
70 abortState |= toggleActionIfActive(TwinEActionType::Escape);
71 abortState |= toggleActionIfActive(TwinEActionType::HolomapAbort);
72 return abortState;
73 }
74
isQuickBehaviourActionActive() const75 bool Input::isQuickBehaviourActionActive() const {
76 return isActionActive(TwinEActionType::QuickBehaviourNormal) || isActionActive(TwinEActionType::QuickBehaviourAthletic) || isActionActive(TwinEActionType::QuickBehaviourAggressive) || isActionActive(TwinEActionType::QuickBehaviourDiscreet);
77 }
78
isMoveOrTurnActionActive() const79 bool Input::isMoveOrTurnActionActive() const {
80 return isActionActive(TwinEActionType::TurnLeft) || isActionActive(TwinEActionType::TurnRight) || isActionActive(TwinEActionType::MoveBackward) || isActionActive(TwinEActionType::MoveForward);
81 }
82
isHeroActionActive() const83 bool Input::isHeroActionActive() const {
84 return isActionActive(TwinEActionType::ExecuteBehaviourAction) || isActionActive(TwinEActionType::SpecialAction);
85 }
86
resetHeroActions()87 bool Input::resetHeroActions() {
88 return toggleActionIfActive(TwinEActionType::ExecuteBehaviourAction) || toggleActionIfActive(TwinEActionType::SpecialAction);
89 }
90
enableAdditionalKeyMap(const char * id,bool enable)91 bool Input::enableAdditionalKeyMap(const char *id, bool enable) {
92 Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper();
93 Common::Keymap *keymap = keymapper->getKeymap(id);
94 if (keymap == nullptr) {
95 return false;
96 }
97 const bool changed = keymap->isEnabled() != enable;
98 keymap->setEnabled(enable);
99 return changed;
100 }
101
enableKeyMap(const char * id)102 void Input::enableKeyMap(const char *id) {
103 if (_currentKeyMap == id) {
104 return;
105 }
106
107 Common::Keymapper *keymapper = g_system->getEventManager()->getKeymapper();
108 const Common::KeymapArray &keymaps = keymapper->getKeymaps();
109 for (Common::Keymap *keymap : keymaps) {
110 const Common::String& keymapId = keymap->getId();
111 if (keymapId == mainKeyMapId || keymapId == uiKeyMapId || keymapId == cutsceneKeyMapId || keymapId == holomapKeyMapId) {
112 keymap->setEnabled(keymapId == id);
113 }
114 }
115 _currentKeyMap = id;
116 debug("enable keymap %s", id);
117 }
118
processCustomEngineEventStart(const Common::Event & event)119 void Input::processCustomEngineEventStart(const Common::Event &event) {
120 if (!_engine->_cfgfile.Debug) {
121 switch (event.customType) {
122 case TwinEActionType::DebugGridCameraPressUp:
123 case TwinEActionType::DebugGridCameraPressDown:
124 case TwinEActionType::DebugGridCameraPressLeft:
125 case TwinEActionType::DebugGridCameraPressRight:
126 case TwinEActionType::DebugPlaceActorAtCenterOfScreen:
127 case TwinEActionType::DebugMenu:
128 case TwinEActionType::DebugMenuActivate:
129 case TwinEActionType::NextRoom:
130 case TwinEActionType::PreviousRoom:
131 case TwinEActionType::ApplyCellingGrid:
132 case TwinEActionType::IncreaseCellingGridIndex:
133 case TwinEActionType::DecreaseCellingGridIndex:
134 break;
135 default:
136 _actionStates[event.customType] = 1 + event.kbdRepeat;
137 break;
138 }
139 } else {
140 _actionStates[event.customType] = 1 + event.kbdRepeat;
141 }
142 debug(3, "twine custom event type start: %i", event.customType);
143 }
144
processCustomEngineEventEnd(const Common::Event & event)145 void Input::processCustomEngineEventEnd(const Common::Event &event) {
146 _actionStates[event.customType] = 0;
147 debug(3, "twine custom event type end: %i", event.customType);
148 }
149
readKeys()150 void Input::readKeys() {
151 Common::Event event;
152 while (g_system->getEventManager()->pollEvent(event)) {
153 switch (event.type) {
154 case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
155 processCustomEngineEventEnd(event);
156 break;
157 case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
158 processCustomEngineEventStart(event);
159 break;
160 default:
161 break;
162 }
163 }
164 }
165
getMousePositions() const166 Common::Point Input::getMousePositions() const {
167 return g_system->getEventManager()->getMousePos();
168 }
169
isMouseHovering(const Common::Rect & rect) const170 bool Input::isMouseHovering(const Common::Rect &rect) const {
171 if (!_engine->_cfgfile.Mouse) {
172 return false;
173 }
174 const Common::Point &point = getMousePositions();
175 return rect.contains(point);
176 }
177
178 } // namespace TwinE
179