ScummVM API documentation
actor.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_ACTOR_H
23 #define MEDIASTATION_ACTOR_H
24 
25 #include "common/events.h"
26 #include "common/keyboard.h"
27 
28 #include "mediastation/datafile.h"
29 #include "mediastation/events.h"
30 #include "mediastation/mediascript/scriptresponse.h"
31 #include "mediastation/mediascript/scriptconstants.h"
32 #include "mediastation/mediascript/scriptvalue.h"
33 
34 namespace MediaStation {
35 
36 class DisplayContext;
37 class SpatialEntity;
38 class StageActor;
39 
40 enum ActorType {
41  kActorTypeEmpty = 0x0000,
42  kActorTypeScreen = 0x0001, // SCR
43  kActorTypeStage = 0x0002, // STG
44  kActorTypePath = 0x0004, // PTH
45  kActorTypeSound = 0x0005, // SND
46  kActorTypeTimer = 0x0006, // TMR
47  kActorTypeImage = 0x0007, // IMG
48  kActorTypeHotspot = 0x000b, // HSP
49  kActorTypeSprite = 0x000e, // SPR
50  kActorTypeStalkingZazu = 0x000f,
51  kActorTypeDotGame = 0x0010,
52  kActorTypeDocument = 0x0011,
53  kActorTypeDiskImage = 0x001d,
54  kActorTypeCursor = 0x000c, // CSR
55  kActorTypePrinter = 0x0019, // PRT
56  kActorTypeMovie = 0x0016, // MOV
57  kActorTypePalette = 0x0017,
58  kActorTypeStreamMovieProxy = 0x18,
59  kActorTypeText = 0x001a, // TXT
60  kActorTypeFont = 0x001b, // FON
61  kActorTypeCamera = 0x001c, // CAM
62  kActorTypeCanvas = 0x001e, // CVS
63  kActorTypeXsnd = 0x001f,
64  kActorTypeXsndMidi = 0x0020,
65  kActorTypeRecorder = 0x0021,
66  kActorTypeFunction = 0x0069 // FUN
67 };
68 const char *actorTypeToStr(ActorType type);
69 
70 enum ActorHeaderSectionType {
71  kActorHeaderEmptySection = 0x0000,
72  kActorHeaderScriptResponse = 0x0017,
73  kActorHeaderChildActorId = 0x0019,
74  kActorHeaderActorId = 0x001a,
75  kActorHeaderChannelIdent = 0x001b,
76  kActorHeaderMovieAnimationChannelIdent = 0x06a4,
77  kActorHeaderMovieAudioChannelIdent = 0x06a5,
78  kActorHeaderActorReference = 0x077b,
79  kActorHeaderBoundingBox = 0x001c,
80  kActorHeaderMouseActiveArea = 0x001d,
81  kActorHeaderZIndex = 0x001e,
82  kActorHeaderStartup = 0x001f,
83  kActorHeaderTransparency = 0x0020,
84  kActorHeaderDiscardAfterUse = 0x0021,
85  kActorHeaderCursorResourceId = 0x0022,
86  kActorHeaderFrameRate = 0x0024,
87  kActorHeaderLoadType = 0x0032,
88  kActorHeaderSoundInfo = 0x0033,
89  kActorHeaderCachingEnabled = 0x0034,
90  kActorHeaderInstallType = 0x0037,
91  kActorHeaderSpriteChunkCount = 0x03e8,
92  kActorHeaderPalette = 0x05aa,
93  kActorHeaderDissolveFactor = 0x05dc,
94  kActorHeaderGetOffstageEvents = 0x05dd,
95  kActorHeaderX = 0x05de,
96  kActorHeaderY = 0x05df,
97  kActorHeaderScaleXAndY = 0x77a,
98  kActorHeaderScaleX = 0x77c,
99  kActorHeaderScaleY = 0x77d,
100  kActorHeaderActorName = 0x0bb8,
101  kStreamMovieProxyInfo = 0x06ac,
102 
103  // DISK IMAGE ACTOR FIELDS.
104  kActorHeaderDiskImageMaxStrips = 0x774,
105  kActorHeaderDiskImageStripWidth = 0x775,
106  kActorHeaderDiskImageUnk1 = 0x776,
107  kActorHeaderDiskImageMaxImages = 0x777,
108  kActorHeaderDiskImageStripInfo = 0x778,
109  kActorHeaderDiskImageUnkRect = 0x779,
110 
111  // PATH FIELDS.
112  kActorHeaderStartPoint = 0x060e,
113  kActorHeaderEndPoint = 0x060f,
114  kActorHeaderPathTotalSteps = 0x0610,
115  kActorHeaderStepRate = 0x0611,
116  kActorHeaderDuration = 0x0612,
117 
118  // CAMERA FIELDS.
119  kActorHeaderCameraViewportOrigin = 0x076f,
120  kActorHeaderCameraLensOpen = 0x0770,
121  kActorHeaderCameraImageActor = 0x77b,
122 
123  // CANVAS FIELDS.
124  kActorHeaderCanvasDissolveFactor = 0x493,
125  kActorHeaderCanvasTransparency = 0x7d0,
126 
127  // STAGE FIELDS.
128  kActorHeaderStageExtent = 0x0771,
129  kActorHeaderCylindricalX = 0x0772,
130  kActorHeaderCylindricalY = 0x0773,
131 
132  // TEXT FIELDS.
133  kActorHeaderEditable = 0x03eb,
134  kActorHeaderFontActorId = 0x0258,
135  kActorHeaderInitialText = 0x0259,
136  kActorHeaderTextMaxLength = 0x25a,
137  kActorHeaderTextJustification = 0x025b,
138  kActorHeaderTextPosition = 0x25f,
139  kActorHeaderTextCursorIsVisible = 0x262,
140  kActorHeaderTextConstrainToWidth = 0x263,
141  kActorHeaderTextOverwriteMode = 0x264,
142  kActorHeaderTextAcceptedCharRangeWithOffset = 0x265,
143  kActorHeaderTextAcceptedCharRange = 0x0266,
144 
145  // SPRITE FIELDS.
146  kActorHeaderSpriteClip = 0x03e9,
147  kActorHeaderDefaultSpriteClip = 0x03ea,
148 
149  // DOT GAME FIELDS.
150  kActorHeaderDotGameMaxDots = 0x001d,
151  kActorHeaderDotGameHelperSprite1 = 0x0514,
152  kActorHeaderDotGameHelperSprite2 = 0x0515,
153  kActorHeaderDotGameState = 0x0516,
154  kActorHeaderDotGameSpeed = 0x0517,
155  kActorHeaderDotGameLineThickness = 0x0518,
156  kActorHeaderDotGameColor = 0x0519,
157 
158  // STALKING ZAZU FIELDS.
159  kActorHeaderStalkingZazuSpriteId = 0x03ec,
160  kActorHeaderStalkingZazuDirections = 0x03ed,
161  kActorHeaderStalkingZazuField = 0x03ee,
162  kActorHeaderStalkingZazuObstacleActorId = 0x03ef,
163  kActorHeaderStalkingZazuUnkX = 0x03f0,
164  kActorHeaderStalkingZazuUnkY = 0x03f1,
165  kActorHeaderStalkingZazuUnkSound1 = 0x03f2,
166  kActorHeaderStalkingZazuUnkSound2 = 0x03f3,
167  kActorHeaderStalkingZazuAudioEnabled = 0x03f4,
168  kActorHeaderStalkingZazuObstaclesToShow = 0x03f5,
169  kActorHeaderStalkingZazuUnkPoint = 0x03f6,
170 };
171 
172 enum CylindricalWrapMode : int;
173 
175  SpatialEntity *keyDown = nullptr;
176  // There is no key up event.
177  SpatialEntity *mouseDown = nullptr;
178  SpatialEntity *mouseUp = nullptr;
179  SpatialEntity *mouseMoved = nullptr;
180  SpatialEntity *mouseExit = nullptr;
181  SpatialEntity *mouseEnter = nullptr;
182  SpatialEntity *mouseOutOfFocus = nullptr;
183 };
184 
185 enum MouseEventFlag {
186  kNoFlag = 0x00,
187  kMouseDownFlag = 0x01,
188  kMouseUpFlag = 0x02,
189  kMouseMovedFlag = 0x04,
190  kMouseExitFlag = 0x10,
191  kMouseEnterFlag = 0x08,
192  kMouseUnk1Flag = 0x20,
193  kMouseOutOfFocusFlag = 0x40,
194  kKeyDownFlag = 0x80,
195  // There is no key up event.
196 };
197 
198 class Polygon {
199 public:
200  void loadFromParameterStream(Chunk &chunk);
201  bool containsPoint(const Common::Point &pointToCheck) const;
202 
203 private:
205 };
206 
207 // Argument count validation macros for built-in script methods.
208 // For exact argument count.
209 #define ARGCOUNTCHECK(n) \
210  if (args.size() != (n)) { \
211  warning("%s: Expected %d arguments, got %d", builtInMethodToStr(methodId), (n), args.size()); \
212  }
213 
214 // For a range of valid argument counts (min to max).
215 #define ARGCOUNTRANGE(min, max) \
216  if ((int64)(min) > (int64)args.size() || (int64)args.size() > (int64)(max)) { \
217  warning("%s: Expected %d to %d arguments, got %d", builtInMethodToStr(methodId), (min), (max), args.size()); \
218  }
219 
220 // For minimum argument count (no maximum).
221 #define ARGCOUNTMIN(min) \
222  if (args.size() < (min)) { \
223  warning("%s: Expected at least %d arguments, got %d", builtInMethodToStr(methodId), (min), args.size()); \
224  }
225 
226 class Actor : public TimerEventReceiver {
227 public:
228  Actor(ActorType type) : _type(type), _timer(this) {};
229  virtual ~Actor();
230 
231  virtual void timerEvent(const TimerEvent &event) { return; }
232 
233  // Runs built-in bytecode methods.
234  virtual ScriptValue callMethod(BuiltInMethod methodId, Common::Array<ScriptValue> &args);
235  virtual void initFromParameterStream(Chunk &chunk);
236  virtual void readParameter(Chunk &chunk, ActorHeaderSectionType paramType);
237  virtual void loadIsComplete();
238 
239  virtual void onEvent(const ActorEvent &event);
240  ScriptResponse *findNextTimeScriptResponseAfter(uint32 after) const;
241  bool hasScriptResponse(EventType eventType, const ScriptValue &arg) const;
242  void runScriptResponseIfExists(EventType eventType, const ScriptValue &arg);
243  void runScriptResponseIfExists(EventType eventType);
244 
245  ActorType type() const { return _type; }
246  uint id() const { return _id; }
247  uint contextId() const { return _contextId; }
248  void setId(uint id);
249  void setContextId(uint id) { _contextId = id; }
250  virtual bool isSpatialActor() const { return false; }
251 
252  // Helper functions for the debugger.
253  virtual bool isActive() const { return true; }
254  virtual Common::String debugString() const { return "<no additional info>"; }
255  const Common::HashMap<uint, Common::Array<ScriptResponse *> > &scriptResponses() const { return _scriptResponses; }
256 
257  const char *debugName() const;
258 
259 protected:
260  ActorType _type = kActorTypeEmpty;
261  bool _loadIsComplete = false;
262  uint _id = 0;
263  uint _contextId = 0;
264  Common::String _debugName;
265 
266  uint _duration = 0;
268 
269  // The original had these fields duplicated across several actors, but it made more
270  // sense to consolidate it into the main Actor in the reimplementation.
271  TimerEntry _timer;
272  uint _startTime = 0;
273  uint _lastProcessedTime = 0;
274  bool setupNextScriptResponseTimer();
275  void triggerRemainingTimerEvents();
276  void processTimeScriptResponses();
277 };
278 
279 class SpatialEntity : public Actor {
280 public:
281  SpatialEntity(ActorType type) : Actor(type) {};
282  ~SpatialEntity();
283 
284  virtual void draw(DisplayContext &displayContext) { return; }
285  virtual ScriptValue callMethod(BuiltInMethod methodId, Common::Array<ScriptValue> &args) override;
286  virtual void readParameter(Chunk &chunk, ActorHeaderSectionType paramType) override;
287  virtual void loadIsComplete() override;
288  virtual void preload(const Common::Rect &rect, bool fireStepEvent = true) {};
289  virtual bool isRectInMemory(const Common::Rect &rect) { return true; }
290  virtual bool isReadyToDraw(DisplayContext &displayContext) { return true; }
291  virtual bool isLoading() { return false; }
292 
293  virtual bool isSpatialActor() const override { return true; }
294  virtual bool isVisible() const { return _isVisible; }
295  virtual Common::Rect getBbox() const { return _boundingBox; }
296  int zIndex() const { return _zIndex; }
297  void moveTo(int16 x, int16 y);
298  void moveToCentered(int16 x, int16 y);
299  void setZIndex(int zIndex);
300 
301  virtual void currentMousePosition(Common::Point &point);
302  virtual void invalidateMouse();
303  virtual bool interactsWithMouse() const { return false; }
304 
305  virtual uint16 findActorToAcceptMouseEvents(
306  const Common::Point &point,
307  uint16 eventMask,
308  MouseActorState &state,
309  bool clipMouseEvents) { return kNoFlag; }
310  virtual uint16 findActorToAcceptKeyboardEvents(
311  uint16 charCode,
312  uint16 eventMask,
313  MouseActorState &state) { return kNoFlag; }
314 
315  virtual void mouseDownEvent(const MouseEvent &event) { return; }
316  virtual void mouseUpEvent(const MouseEvent &event) { return; }
317  virtual void mouseEnteredEvent(const MouseEvent &event) { return; }
318  virtual void mouseExitedEvent(const MouseEvent &event) { return; }
319  virtual void mouseMovedEvent(const MouseEvent &event) { return; }
320  virtual void mouseOutOfFocusEvent(const MouseEvent &event) { return; }
321  virtual void keyboardEvent(const KeyboardEvent &event) { return; }
322 
323  void setParentStage(StageActor *parentStage) { _parentStage = parentStage; }
324  void setToNoParentStage() { _parentStage = nullptr; }
325  StageActor *getParentStage() const { return _parentStage; }
326 
327  virtual void invalidateLocalBounds();
328  virtual void setAdjustedBounds(CylindricalWrapMode wrapMode);
329 
330 protected:
331  uint _stageId = 0;
332  int _zIndex = 0;
333  double _dissolveFactor = 1.0;
334 
335  double _parallaxFactorX = 0.0;
336  double _parallaxFactorY = 0.0;
337  Common::Rect _boundingBox;
338  Common::Rect _originalBoundingBox;
339  bool _isVisible = false;
340  bool _hasTransparency = false;
341  StageActor *_parentStage = nullptr;
342 
343  void setBounds(const Common::Rect &bounds);
344  virtual void setMousePosition(int16 x, int16 y);
345 
346  virtual void setDissolveFactor(double dissolveFactor);
347  virtual void invalidateLocalZIndex();
348 };
349 
350 } // End of namespace MediaStation
351 
352 #endif
Definition: str.h:59
Definition: actor.h:174
Definition: actor.h:279
Definition: actor.h:34
Definition: events.h:201
Definition: datafile.h:99
Definition: stage.h:50
Definition: rect.h:536
Definition: graphics.h:122
Definition: events.h:103
Definition: events.h:94
Definition: events.h:209
Definition: hashmap.h:85
Definition: events.h:143
Definition: rect.h:144
Definition: scriptresponse.h:34
Definition: actor.h:198
Definition: events.h:125
Definition: actor.h:226
Definition: scriptvalue.h:35