ScummVM API documentation
events.h
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 modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (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, see <http://www.gnu.org/licenses/>.
19 *
20 */
21
22#ifndef MEDIASTATION_EVENTS_H
23#define MEDIASTATION_EVENTS_H
24
25#include "common/events.h"
26#include "common/hash-ptr.h"
27#include "common/ptr.h"
28#include "common/str.h"
29#include "common/queue.h"
30
31#include "mediastation/mediascript/scriptconstants.h"
32#include "mediastation/mediascript/scriptvalue.h"
33
34namespace MediaStation {
35
36enum EventClass {
37 kEventClassInvalid = 0x00,
38 kEventClassSystem = 0x01,
39 kEventClassMouse = 0x02,
40 kEventClassKeyboard = 0x04,
41 kEventClassDisplay = 0x08,
42 kEventClassTimerService = 0x10,
43 kEventClassScriptTimer = 0x20,
44 kEventClassActor = 0x40
45};
46const char *eventClassToStr(EventClass eventClass);
47
48// This reimplementation doesn't use these values because
49// there isn't the indirection of event handler classes. We
50// just use the event class directly when deciding where to route an
51// event. However, this is still included for completeness .
52enum EventClassHandlerType {
53 kNoEventClassHandler = 0x00,
54 kStageDirectorEventClassHandler = 0x06,
55 kDisplayUpdateEventClassHandler = 0x08,
56 kTimerServiceClassHandler = 0x10,
57 kActorEventClassHandler = 0x40,
58};
59
60struct Event {
61 EventClass eventClass = kEventClassInvalid;
62 EventType type = kEventTypeInvalid;
63
64 Event(EventClass eventClass_, EventType eventType_)
65 : eventClass(eventClass_), type(eventType_) {}
66 virtual ~Event() {}
67 virtual Event *clone() const = 0;
68 virtual Common::String debugString() const;
69};
70
71struct DisplayEvent : public Event {
72 uint disableScreenAutoUpdateToken = 0;
73
74 DisplayEvent(EventType eventType_, uint token_)
75 : Event(kEventClassDisplay, eventType_), disableScreenAutoUpdateToken(token_) {}
76 Event *clone() const override { return new DisplayEvent(*this); }
77 Common::String debugString() const override;
78};
79
80// This is an event queued to tell the timer service that a timer has expired. When this event is processed,
81// an actual timer event will get sent to the actual timer event handler (actors and such).
82class TimerEntry;
84 uint32 triggerTime = 0;
85 TimerEntry *entry = nullptr;
86
87 TimerServiceAlarmEvent(TimerEntry *entry_, uint32 triggerTime_)
88 : Event(kEventClassTimerService, kTimerServiceAlarmEvent), triggerTime(triggerTime_), entry(entry_) {}
89 Event *clone() const override { return new TimerServiceAlarmEvent(*this); }
90 Common::String debugString() const override;
91};
92
93// This is actually sent to timer event handlers (actors and such).
94struct TimerEvent : public Event {
95 TimerEntry *entry = nullptr;
96
97 TimerEvent(TimerEntry *entry_)
98 : Event(kEventClassScriptTimer, kTimerScriptEvent), entry(entry_) {}
99 Event *clone() const override { return new TimerEvent(*this); }
100 Common::String debugString() const override;
101};
102
103struct ActorEvent : public Event {
104 uint actorId = 0;
105 ScriptValue arg;
106
107 ActorEvent(uint16 actorId_, EventType eventType_)
108 : Event(kEventClassActor, eventType_), actorId(actorId_) {}
109 ActorEvent(uint16 actorId_, EventType eventType_, ScriptValue arg_)
110 : Event(kEventClassActor, eventType_), actorId(actorId_), arg(arg_) {}
111 Event *clone() const override { return new ActorEvent(*this); }
112 Common::String debugString() const override;
113};
114
116 uint screenId = 0;
117 bool disableScreenAutoUpdate = false;
118
119 ScreenBranchEvent(uint16 actorId_, uint16 screenId_, bool disableScreenAutoUpdate_)
120 : ActorEvent(actorId_, kScreenBranchEvent), screenId(screenId_), disableScreenAutoUpdate(disableScreenAutoUpdate_) {}
121 Event *clone() const override { return new ScreenBranchEvent(*this); }
122 Common::String debugString() const override;
123};
124
125struct MouseEvent : public Event {
126 Common::Point position;
127
128 MouseEvent(EventType eventType_, const Common::Point &position_)
129 : Event(kEventClassMouse, eventType_), position(position_) {}
130 Event *clone() const override { return new MouseEvent(*this); }
131 Common::String debugString() const override;
132};
133
134enum SpecialCharCodes {
135 kBackspaceCharCode = 0x08,
136 kLeftArrowCharCode = 0x100,
137 kRightArrowCharCode = 0x101,
138 kUpArrowCharCode = 0x102,
139 kDownArrowCharCode = 0x103,
140 kCursorCharCode = 0x104,
141};
142
143struct KeyboardEvent : public Event {
144 Common::KeyState state;
145
146 KeyboardEvent(EventType eventType_, Common::KeyState state_)
147 : Event(kEventClassKeyboard, eventType_), state(state_) {}
148 Event *clone() const override { return new KeyboardEvent(*this); }
149 Common::String debugString() const override;
150
151 // Scripts and text actors use a 16-bit field for their char codes,
152 // which also encapsulates non-text keys like backspace and arrow keys.
153 // This converts the platform-independent ScummVM keystate into what scripts
154 // want. See MAC_App::doKeyDownEvent in the 68k disassembly.
155 uint16 getMediaStationCharCode() const;
156};
157
158enum PreDisplaySyncState {
159 kPreDisplaySyncForceScreenUpdate = 0,
160 kPreDisplaySyncNoScreenUpdateRequested = 1,
161 kPreDisplaySyncStateBlockScreenUpdate = 2
162};
163
164// Interface for clients that need to update during the pre-display sync phase.
165// Only stream movie actors seem to actually use this.
167public:
168 virtual ~PreDisplaySyncClient() {}
169 virtual PreDisplaySyncState preDisplaySync() = 0;
170
171 void registerForSyncCalls();
172 void unregisterForSyncCalls();
173};
174
175// The main event loop. In the original, much of the functionality lived in a separate
176// EventLoopSupport class (implemented by MAC_App or WIN_App), but in ScummVM there
177// is no need for that extra indirection.
179public:
180 void run();
181 void queueEvent(const Event &event);
182
183 void registerForPreDisplaySyncCalls(PreDisplaySyncClient *client);
184 void unregisterForPreDisplaySyncCalls(PreDisplaySyncClient *client);
185
186private:
189 Common::Event _queuedSystemEvent;
191
192 void dispatchImtEvents();
193 PreDisplaySyncState preDisplaySync();
194 void updateDisplay();
195
196 // The original had a separate EventDispatcher, but things are much simpler by not using
197 // the polymorphism that required this intermediate class.
198 void dispatchImtEvent(const Event &event);
199};
200
202public:
203 virtual ~TimerEventReceiver() {};
204
205 uint32 currentReceiverTime();
206 virtual void timerEvent(const TimerEvent &event) = 0;
207};
208
210public:
211 TimerEntry() = default;
212 TimerEntry(TimerEventReceiver *receiver) : _receiver(receiver) {}
213 ~TimerEntry();
214
215 void setDuration(uint32 duration) { _duration = duration; }
216 uint32 calculateFirstExpirationTime(uint32 currentTime);
217 uint32 calculateNextExpirationTime(uint32 currentTime);
218 uint32 deltaTimeAtExpiration() const;
219 uint32 expirationTime() const { return _expirationTime; }
220 bool shouldReschedule() const { return _shouldRepeat; }
221 TimerEventReceiver *getReceiver() const { return _receiver; }
222
223 bool operator==(const TimerEntry &other) const;
224 bool operator<(const TimerEntry &other) const;
225 bool operator>(const TimerEntry &other) const;
226
227private:
228 TimerEventReceiver *_receiver = nullptr;
229 uint32 _expirationTime = 0;
230 uint32 _actualExpirationTime = 0;
231 uint32 _duration = 0;
232 bool _shouldRepeat = false;
233};
234
236public:
237 // This is called to actually dispatch a timer event to the event receiver.
238 void handleEvent(const TimerServiceAlarmEvent &event);
239
240 void startTimer(TimerEntry &entry, uint32 duration);
241 void startTimer(TimerEntry &entry, double duration);
242 void stopTimer(TimerEntry &entry);
243 void queueExpiredTimerEvents();
244
245private:
247
248 void rescheduleTimerEntry(TimerEntry &entry);
249};
250
251} // End of namespace MediaStation
252
253#endif
Definition: hashmap.h:85
Definition: queue.h:42
Definition: str.h:59
Definition: events.h:178
Definition: events.h:166
Definition: scriptvalue.h:35
Definition: events.h:209
Definition: events.h:201
Definition: events.h:235
Definition: events.h:218
Definition: keyboard.h:294
Definition: rect.h:144
Definition: events.h:103
Definition: events.h:71
Definition: events.h:60
Definition: events.h:143
Definition: events.h:125
Definition: events.h:115
Definition: events.h:94