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 
34 namespace MediaStation {
35 
36 enum 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 };
46 const 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 .
52 enum EventClassHandlerType {
53  kNoEventClassHandler = 0x00,
54  kStageDirectorEventClassHandler = 0x06,
55  kDisplayUpdateEventClassHandler = 0x08,
56  kTimerServiceClassHandler = 0x10,
57  kActorEventClassHandler = 0x40,
58 };
59 
60 struct 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 
71 struct 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).
82 class TimerEntry;
83 struct TimerServiceAlarmEvent : public Event {
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).
94 struct 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 
103 struct 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 
115 struct ScreenBranchEvent : public ActorEvent {
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 
125 struct 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 
134 enum SpecialCharCodes {
135  kBackspaceCharCode = 0x08,
136  kLeftArrowCharCode = 0x100,
137  kRightArrowCharCode = 0x101,
138  kUpArrowCharCode = 0x102,
139  kDownArrowCharCode = 0x103,
140  kCursorCharCode = 0x104,
141 };
142 
143 struct 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 
158 enum 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.
167 public:
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.
178 class EventLoop {
179 public:
180  void run();
181  void queueEvent(const Event &event);
182 
183  void registerForPreDisplaySyncCalls(PreDisplaySyncClient *client);
184  void unregisterForPreDisplaySyncCalls(PreDisplaySyncClient *client);
185 
186 private:
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 
202 public:
203  virtual ~TimerEventReceiver() {};
204 
205  uint32 currentReceiverTime();
206  virtual void timerEvent(const TimerEvent &event) = 0;
207 };
208 
209 class TimerEntry {
210 public:
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 
227 private:
228  TimerEventReceiver *_receiver = nullptr;
229  uint32 _expirationTime = 0;
230  uint32 _actualExpirationTime = 0;
231  uint32 _duration = 0;
232  bool _shouldRepeat = false;
233 };
234 
236 public:
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 
245 private:
247 
248  void rescheduleTimerEntry(TimerEntry &entry);
249 };
250 
251 } // End of namespace MediaStation
252 
253 #endif
Definition: str.h:59
Definition: actor.h:34
Definition: events.h:71
Definition: events.h:201
Definition: events.h:60
Definition: events.h:235
Definition: queue.h:42
Definition: events.h:115
Definition: events.h:103
Definition: events.h:94
Definition: events.h:209
Definition: hashmap.h:85
Definition: events.h:143
Definition: events.h:218
Definition: rect.h:144
Definition: events.h:166
Definition: events.h:125
Definition: keyboard.h:294
Definition: events.h:178
Definition: scriptvalue.h:35