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 XEEN_EVENTS_H
24 #define XEEN_EVENTS_H
25 
26 #include "common/scummsys.h"
27 #include "common/events.h"
28 #include "common/queue.h"
29 #include "xeen/sprites.h"
30 
31 namespace Xeen {
32 
33 #define GAME_FRAME_RATE (1000 / 50)
34 #define GAME_FRAME_TIME 50
35 #define SCREEN_UPDATE_TIME 10
36 #define MAX_PENDING_EVENTS 5
37 
38 class XeenEngine;
39 
40 struct PendingEvent {
41 	Common::KeyState _keyState;
42 	bool _leftButton;
43 	bool _rightButton;
44 
PendingEventPendingEvent45 	PendingEvent() : _leftButton(false), _rightButton(false) {}
PendingEventPendingEvent46 	PendingEvent(const Common::KeyState &keyState) : _keyState(keyState), _leftButton(false), _rightButton(false) {}
PendingEventPendingEvent47 	PendingEvent(bool leftButton, bool rightButton) : _leftButton(leftButton), _rightButton(rightButton) {}
48 
49 	/**
50 	 * Returns true if a keyboard event is pending
51 	 */
isKeyboardPendingEvent52 	bool isKeyboard() const { return _keyState.keycode != Common::KEYCODE_INVALID; }
53 
54 	/**
55 	 * Returns ture if a mouse button event is pending
56 	 */
isMousePendingEvent57 	bool isMouse() const { return _leftButton || _rightButton; }
58 };
59 
60 class EventsManager {
61 private:
62 	XeenEngine *_vm;
63 	uint32 _frameCounter;
64 	uint32 _priorFrameCounterTime;
65 	uint32 _priorScreenRefreshTime;
66 	int _lastAutosaveTime;
67 	uint32 _gameCounter;
68 	uint32 _gameCounters[6];
69 	uint32 _playTime;
70 	Common::Queue<PendingEvent> _pendingEvents;
71 	SpriteResource _sprites;
72 	bool _mousePressed;
73 
74 	/**
75 	 * Handles moving to the next game frame
76 	 */
77 	void nextFrame();
78 public:
79 	Common::Point _mousePos;
80 public:
81 	EventsManager(XeenEngine *vm);
82 	~EventsManager();
83 
84 	/*
85 	 * Set the cursor
86 	 */
87 	void setCursor(int cursorId);
88 
89 	/**
90 	 * Show the mouse cursor
91 	 */
92 	void showCursor();
93 
94 	/**
95 	 * Hide the mouse cursor
96 	 */
97 	void hideCursor();
98 
99 	/**
100 	 * Returns if the mouse cursor is visible
101 	 */
102 	bool isCursorVisible();
103 
104 	/**
105 	 * Polls the ScummVM backend for any pending events
106 	 */
107 	void pollEvents();
108 
109 	/**
110 	 * Polls for events, and wait a slight delay. This ensures the game doesn't use up 100% of the CPU
111 	 */
112 	void pollEventsAndWait();
113 
114 	/**
115 	 * Clears all pending events
116 	 */
117 	void clearEvents();
118 
119 	/**
120 	 * Waits for a mouse press to be released
121 	 */
122 	void debounceMouse();
123 
124 	/**
125 	 * Adds a keyboard event to the queue
126 	 */
127 	void addEvent(const Common::KeyState &keyState);
128 
129 	/**
130 	 * Adds a mouse button event to the queue
131 	 */
132 	void addEvent(bool leftButton, bool rightButton);
133 
134 	/**
135 	 * Returns the next pending key/mouse press, if any
136 	 */
137 	bool getEvent(PendingEvent &pe);
138 
139 	/**
140 	 * Returns true if a key or mouse event is pending
141 	 */
isEventPending()142 	bool isEventPending() const { return !_pendingEvents.empty(); }
143 
144 	/**
145 	 * Returns true if a key or mouse press is pending
146 	 */
147 	bool isKeyMousePressed();
148 
updateGameCounter()149 	void updateGameCounter() { _gameCounter = _frameCounter; }
timeMark1()150 	void timeMark1() { _gameCounters[1] = _frameCounter; }
timeMark2()151 	void timeMark2() { _gameCounters[2] = _frameCounter; }
timeMark3()152 	void timeMark3() { _gameCounters[3] = _frameCounter; }
timeMark4()153 	void timeMark4() { _gameCounters[4] = _frameCounter; }
timeMark5()154 	void timeMark5() { _gameCounters[5] = _frameCounter; }
155 
timeElapsed()156 	uint32 timeElapsed() const { return _frameCounter - _gameCounter; }
timeElapsed1()157 	uint32 timeElapsed1() const { return _frameCounter - _gameCounters[1]; }
timeElapsed2()158 	uint32 timeElapsed2() const { return _frameCounter - _gameCounters[2]; }
timeElapsed3()159 	uint32 timeElapsed3() const { return _frameCounter - _gameCounters[3]; }
timeElapsed4()160 	uint32 timeElapsed4() const { return _frameCounter - _gameCounters[4]; }
timeElapsed5()161 	uint32 timeElapsed5() const { return _frameCounter - _gameCounters[5]; }
getTicks()162 	uint32 getTicks() { return _frameCounter; }
playTime()163 	uint32 playTime() const { return _playTime; }
setPlayTime(uint32 time)164 	void setPlayTime(uint32 time) { _playTime = time; }
165 
166 	/**
167 	 * Waits for a given number of frames
168 	 * @param numFrames			Number of frames to wait
169 	 * @param interruptable		If set, aborts if the mouse or a key is pressed
170 	 * @returns		True if the wait was aborted
171 	 */
172 	bool wait(uint numFrames, bool interruptable = true);
173 
174 	/**
175 	 * Pause for a set amount
176 	 */
177 	void ipause(uint amount);
178 
179 	/**
180 	 * Pauses a set amount past the previous call to timeMark5
181 	 */
182 	void ipause5(uint amount);
183 
184 	/**
185 	 * Waits for a key or mouse press, animating the 3d view in the background
186 	 */
187 	void waitForPressAnimated();
188 
189 	/**
190 	 * Waits for a key or mouse press
191 	 */
192 	void waitForPress();
193 };
194 
195 } // End of namespace Xeen
196 
197 #endif /* XEEN_EVENTS_H */
198