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 "titanic/events.h"
24 #include "titanic/debugger.h"
25 #include "titanic/game_manager.h"
26 #include "titanic/main_game_window.h"
27 #include "titanic/star_control/star_control.h"
28 #include "titanic/titanic.h"
29 #include "common/events.h"
30 #include "common/scummsys.h"
31 #include "common/system.h"
32 #include "engines/util.h"
33 #include "graphics/screen.h"
34
35 namespace Titanic {
36
Events(TitanicEngine * vm)37 Events::Events(TitanicEngine *vm): _vm(vm), _frameCounter(1),
38 _totalFrames(0), _priorFrameTime(0), _specialButtons(0) {
39 }
40
41 #define MOVE_CHECK if (moved) eventTarget()->mouseMove(_mousePos)
42
pollEvents()43 void Events::pollEvents() {
44 checkForNextFrameCounter();
45
46 bool moved = false;
47 Common::Event event;
48 while (!_vm->shouldQuit() && g_system->getEventManager()->pollEvent(event)) {
49 if (event.type != Common::EVENT_MOUSEMOVE) {
50 MOVE_CHECK;
51 }
52
53 switch (event.type) {
54 case Common::EVENT_MOUSEMOVE:
55 _mousePos = event.mouse;
56 moved = true;
57 break;
58 case Common::EVENT_LBUTTONDOWN:
59 _specialButtons |= MK_LBUTTON;
60 _mousePos = event.mouse;
61 eventTarget()->leftButtonDown(_mousePos);
62 return;
63 case Common::EVENT_LBUTTONUP:
64 _specialButtons &= ~MK_LBUTTON;
65 _mousePos = event.mouse;
66 eventTarget()->leftButtonUp(_mousePos);
67 return;
68 case Common::EVENT_MBUTTONDOWN:
69 _specialButtons |= MK_MBUTTON;
70 _mousePos = event.mouse;
71 eventTarget()->middleButtonDown(_mousePos);
72 return;
73 case Common::EVENT_MBUTTONUP:
74 _specialButtons &= ~MK_MBUTTON;
75 _mousePos = event.mouse;
76 eventTarget()->middleButtonUp(_mousePos);
77 return;
78 case Common::EVENT_RBUTTONDOWN:
79 _specialButtons |= MK_LBUTTON | MK_SHIFT;
80 _mousePos = event.mouse;
81 eventTarget()->leftButtonDown(_mousePos);
82 return;
83 case Common::EVENT_RBUTTONUP:
84 _specialButtons &= ~(MK_RBUTTON | MK_SHIFT);
85 _mousePos = event.mouse;
86 eventTarget()->leftButtonUp(_mousePos);
87 return;
88 case Common::EVENT_WHEELUP:
89 case Common::EVENT_WHEELDOWN:
90 _mousePos = event.mouse;
91 eventTarget()->mouseWheel(_mousePos, event.type == Common::EVENT_WHEELUP);
92 return;
93 case Common::EVENT_KEYDOWN:
94 handleKbdSpecial(event.kbd);
95 eventTarget()->keyDown(event.kbd);
96 return;
97 case Common::EVENT_KEYUP:
98 handleKbdSpecial(event.kbd);
99 eventTarget()->keyUp(event.kbd);
100 return;
101 default:
102 break;
103 }
104 }
105
106 MOVE_CHECK;
107 }
108
109 #undef MOVE_CHECK
110
pollEventsAndWait()111 void Events::pollEventsAndWait() {
112 pollEvents();
113 g_system->delayMillis(10);
114
115 CGameManager *gameManager = g_vm->_window->_gameManager;
116 if (gameManager) {
117 // Regularly update the sound mixer
118 gameManager->_sound.updateMixer();
119
120 // WORKAROUND: If in the Star Control view, update the camera
121 // frequently, to accomodate that the original had a higher
122 // draw rate than the ScummVM implementation does
123 CViewItem *view = gameManager->getView();
124 if (view->getFullViewName() == "Bridge.Node 4.N") {
125 CStarControl *starControl = dynamic_cast<CStarControl *>(
126 view->findChildInstanceOf(CStarControl::_type));
127 if (starControl && starControl->_visible)
128 starControl->updateCamera();
129 }
130 }
131 }
132
checkForNextFrameCounter()133 bool Events::checkForNextFrameCounter() {
134 // Check for next game frame
135 uint32 milli = g_system->getMillis();
136 if ((milli - _priorFrameTime) >= GAME_FRAME_TIME) {
137 ++_frameCounter;
138 ++_totalFrames;
139 _priorFrameTime = milli;
140
141 // Handle any idle updates
142 eventTarget()->onIdle();
143
144 // Give time to the debugger
145 _vm->_debugger->onFrame();
146
147 // Display the frame
148 _vm->_screen->update();
149
150 return true;
151 }
152
153 return false;
154 }
155
getTicksCount() const156 uint32 Events::getTicksCount() const {
157 return _frameCounter * GAME_FRAME_TIME;
158 }
159
getTotalPlayTicks() const160 uint32 Events::getTotalPlayTicks() const {
161 return _totalFrames;
162 }
163
setTotalPlayTicks(uint frames)164 void Events::setTotalPlayTicks(uint frames) {
165 _totalFrames = frames;
166 }
167
sleep(uint time)168 void Events::sleep(uint time) {
169 uint32 delayEnd = g_system->getMillis() + time;
170
171 while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd)
172 pollEventsAndWait();
173 }
174
waitForPress(uint expiry)175 bool Events::waitForPress(uint expiry) {
176 uint32 delayEnd = g_system->getMillis() + expiry;
177 CPressTarget pressTarget;
178 addTarget(&pressTarget);
179
180 while (!_vm->shouldQuit() && g_system->getMillis() < delayEnd && !pressTarget._pressed) {
181 pollEventsAndWait();
182 }
183
184 removeTarget();
185 return pressTarget._pressed;
186 }
187
setMousePos(const Common::Point & pt)188 void Events::setMousePos(const Common::Point &pt) {
189 g_system->warpMouse(pt.x, pt.y);
190 _mousePos = pt;
191 eventTarget()->mouseMove(_mousePos);
192 }
193
handleKbdSpecial(Common::KeyState keyState)194 void Events::handleKbdSpecial(Common::KeyState keyState) {
195 if (keyState.flags & Common::KBD_CTRL)
196 _specialButtons |= MK_CONTROL;
197 else
198 _specialButtons &= ~MK_CONTROL;
199
200 if (keyState.flags & Common::KBD_SHIFT)
201 _specialButtons |= MK_SHIFT;
202 else
203 _specialButtons &= ~MK_SHIFT;
204 }
205
206 } // End of namespace Titanic
207