ScummVM API documentation
records.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 NANCY_SCRIPT_RECORDS_H
23 #define NANCY_SCRIPT_RECORDS_H
24 
25 #include "common/array.h"
26 #include "common/rect.h"
27 
28 #include "engines/nancy/commontypes.h"
29 #include "engines/nancy/movieplayer.h"
30 #include "engines/nancy/renderobject.h"
31 
32 #include "engines/nancy/script/record.h"
33 
34 #include "engines/nancy/ui/ndui/element.h"
35 
36 namespace Nancy {
37 
38 namespace UI {
39 class Viewport;
40 }
41 
42 namespace Script {
43 
44 struct RefImage;
45 
46 // The kinds of records a script can make, in the order of the names below
47 enum RecordKind {
48  kRecordNavLogic = 0,
49  kRecordSummary = 1,
50  kRecordOverlay = 2,
51  kRecordMovie = 3,
52  kRecordSound = 4,
53  kRecordVideoConvo = 5,
54  kRecordSoundConvo = 6,
55  kRecordText = 7,
56  kRecordOverride = 8,
57  kRecordParticle = 9,
58  kRecordAnimOverlay = 10,
59 
60  kNumRecordKinds = 11
61 };
62 
63 // What scripts call the kind ("NavLogic"), and the type of its objects ("ND.NavLogic")
64 const char *getRecordKindName(RecordKind kind);
65 const char *getRecordTypeName(RecordKind kind);
66 
67 // Returns null for the kinds that are not supported
68 Record *makeRecord(RecordKind kind, SceneContext &context);
69 
70 // What the "Draw" object of the scripts draws on: the record whose "Render"
71 // function is running. Null at any other time.
72 Graphics::ManagedSurface *getDrawTarget();
73 
74 // What a record draws. Records are placed in the coordinates of the viewport.
75 class RecordGraphic : public RenderObject {
76 public:
77  RecordGraphic() : RenderObject(0) {}
78  virtual ~RecordGraphic() {}
79 
80  // Scripts order what they draw with numbers of their own
81  void setScriptZ(double z, int32 streamZOffset);
82 
83 protected:
84  bool isViewportRelative() const override { return true; }
85 };
86 
87 // The first record of every scene, which names the area the scene belongs to
88 // and its background. A background with more than one frame is a node the
89 // player can turn around in.
90 // The area has a set of music themes. One of them starts with the scene when
91 // no theme is playing, and a scene can ask for another one once it is over.
92 // TODO: Handle the modColor field.
93 class SummaryRecord : public Record {
94 public:
95  SummaryRecord(SceneContext &context) : Record(context, "ND.Summary") {}
96 
97  const Common::String &getEnvironment() const { return _environment; }
98  const Common::String &getBackgroundName() const { return _backgroundName; }
99 
100  // The viewport that shows the background, once it has been loaded
101  void setBackground(UI::Viewport *background);
102 
103 protected:
104  void readTable(int tableIndex) override;
105  void runOnce() override;
106  void run(double sceneTime, double elapsedTime) override;
107  bool hasTransform() const override { return true; }
108  bool getField(const Common::String &key) override;
109 
110  void onMouseMove(const ScriptPoint &point, bool inViewport) override;
111  bool getCursor(const ScriptPoint &point, bool inViewport, uint &cursorType, bool &isHot) override;
112  bool onMouseEvent(RecordEvent event, const ScriptPoint &point, bool inViewport) override;
113 
114 private:
115  enum Turn { kNoTurn, kTurnLeft, kTurnRight, kTurnAround };
116 
117  // The side of the node the mouse is on
118  Turn getTurnAt(const ScriptPoint &point, bool inViewport) const;
119  void setFrame(uint frame);
120  void playTheme();
121  void updateTheme(double sceneTime);
122 
123  Common::String _environment;
124  Common::String _backgroundName;
125 
126  bool _loopsTheme = false;
127  double _themePause = 0.0; // the seconds of silence between two themes
128  double _themeEndTime = 0.0; // when the theme was found to be over; 0 while one plays
129  double _lastThemeCheck = 0.0;
130 
131  UI::Viewport *_background = nullptr;
132  uint _numFrames = 0;
133  uint _frame = 0;
134 
135  Turn _turn = kNoTurn;
136  bool _isTurningFast = false;
137  double _lastTurnTime = 0.0;
138  double _sceneTime = 0.0;
139 };
140 
141 // Changes the scene and sets flags, either right away or when its hotspot gets clicked
142 class NavLogicRecord : public Record {
143 public:
144  NavLogicRecord(SceneContext &context) : Record(context, "ND.NavLogic") {}
145 
146 protected:
147  void readTable(int tableIndex) override;
148  void run(double sceneTime, double elapsedTime) override;
149  bool prepareReset() override { return true; }
150  bool hasTransform() const override { return true; }
151  bool getField(const Common::String &key) override;
152  bool setField(const Common::String &key) override;
153 
154  void onMouseMove(const ScriptPoint &point, bool inViewport) override;
155  bool getCursor(const ScriptPoint &point, bool inViewport, uint &cursorType, bool &isHot) override;
156  bool onMouseEvent(RecordEvent event, const ScriptPoint &point, bool inViewport) override;
157 
158 private:
159  struct Flag {
160  Common::String name;
161  bool value = false;
162  };
163 
164  void readScene(int valueIndex);
165  void readCursor(int valueIndex);
166  void readRef(int valueIndex);
167  bool isOver(const ScriptPoint &point) const;
168  void trigger();
169 
170  Common::String _sceneName;
171  Common::String _streamName;
172  int _frame = 0;
173 
174  ScriptRect _hotspot;
175  bool _hasCursor = false;
176  uint _cursorType = 0;
177  bool _cursorIsHot = false;
178 
179  // Nancy20 can take the shape of the hotspot from a Ref image: where it isn't
180  // transparent, or where it has the given color. The part of the image named
181  // by the source is laid over the hotspot; without both, the image covers
182  // the viewport.
183  const RefImage *_ref = nullptr;
184  bool _hasRefColor = false;
185  uint32 _refColor = 0;
186  ScriptRect _source;
187 
188  bool _isRightClick = false; // Nancy20: the right button clicks it, not the left
189  bool _isMouseOver = false;
190 
191  Common::Array<Flag> _flags;
192 };
193 
194 // A record that only does what the functions a script gave it do
195 // TODO: Call RenderAttachment and OnLoad, and handle Send.
196 class OverrideRecord : public Record {
197 public:
198  OverrideRecord(SceneContext &context) : Record(context, "ND.OverrideAR") {}
199  virtual ~OverrideRecord();
200 
201  void updateGraphics() override;
202  void onSave() override { callFunction("OnSave"); }
203  void onDie() override { callFunction("OnDie"); }
204  bool hasMessagingName(const Common::String &name) override;
205 
206 protected:
207  void readTable(int tableIndex) override;
208  bool prepareReset() override { return true; }
209  bool isScripted() const override { return true; }
210  void onActivation() override { callFunction("OnActivation"); }
211  void onDeactivation() override { callFunction("OnDeactivation"); }
212  void onZChanged() override;
213  bool getField(const Common::String &key) override;
214  bool setField(const Common::String &key) override;
215 
216 private:
217  // What the "Render" function draws on, for the records that have one
218  RecordGraphic *_canvas = nullptr;
219 };
220 
221 // Shows a part of an image
222 class OverlayRecord : public Record {
223 public:
224  OverlayRecord(SceneContext &context) : Record(context, "ND.Overlay") {}
225 
226  void updateGraphics() override;
227 
228 protected:
229  void readTable(int tableIndex) override;
230  void onZChanged() override;
231  bool hasTransform() const override { return true; }
232  void onTransformChanged() override { applyRects(); }
233  void renderNow() override;
234  bool getField(const Common::String &key) override;
235  bool setField(const Common::String &key) override;
236 
237 private:
238  void applyRects();
239 
241  ScriptRect _source;
242  ScriptRect _dest;
243  uint32 _modColor = 0xFFFFFFFF; // what the colors of the picture get multiplied with
244  bool _hasPicture = false;
245  RecordGraphic _graphic;
246 
247  // The picture as a script had it drawn by itself, which lasts for a frame
248  RecordGraphic _attachment;
249  bool _hasAttachment = false;
250  bool _isAttachmentDrawn = false;
251 };
252 
253 // Shows the parts of an image one after the other
254 class AnimOverlayRecord : public Record {
255 public:
256  AnimOverlayRecord(SceneContext &context) : Record(context, "ND.AnimOvlAR") {}
257 
258  void updateGraphics() override;
259 
260  void setPaused(bool isPaused) { _isPaused = isPaused; }
261 
262 protected:
263  void readTable(int tableIndex) override;
264  void runOnce() override;
265  void run(double sceneTime, double elapsedTime) override;
266  void onZChanged() override;
267  bool prepareReset() override;
268  bool hasTransform() const override { return true; }
269  void onTransformChanged() override { applyFrame(); }
270  bool getField(const Common::String &key) override;
271  bool setField(const Common::String &key) override;
272 
273 private:
274  // Frames are counted from 1
275  int getFirstFrame() const { return _firstFrame > 0 ? _firstFrame : 1; }
276  int getLastFrame() const { return _lastFrame > 0 ? _lastFrame : (int)_sources.size(); }
277  void setFrame(int frame);
278  void applyFrame();
279  void beginLoop();
280 
282  Common::Array<ScriptRect> _sources;
283  ScriptRect _dest;
284  uint32 _modColor = 0xFFFFFFFF;
285  bool _hasPicture = false;
286  RecordGraphic _graphic;
287 
288  int _firstFrame = -1;
289  int _lastFrame = -1;
290  int _frame = 1;
291  double _framesPerSecond = 15.0;
292  double _progress = 0.0; // through the frames, from 0 to 1
293  double _endTime = 0.0;
294 
295  int _numLoops = 1; // 0 loops forever
296  int _numLoopsDone = 0;
297  bool _pausesOnLastFrame = false;
298  bool _isPaused = false;
299  bool _isVisible = true;
300 };
301 
302 // Plays a sound, picked at random when it has several
303 class SoundRecord : public Record {
304 public:
305  SoundRecord(SceneContext &context) : Record(context, "ND.SoundAR") {}
306 
307  void onSkip() override;
308 
309 protected:
310  void readTable(int tableIndex) override;
311  void runOnce() override;
312  void run(double sceneTime, double elapsedTime) override;
313  bool prepareReset() override;
314  bool getField(const Common::String &key) override;
315 
316 private:
318  uint16 _channel = 14;
319  double _volume = 1.0;
320  bool _isLooping = false;
321  bool _usesCaption = true;
322 
323  SoundDescription _sound;
324  Common::String _caption; // what the sound says, while it is the one on screen
325  bool _isPlaying = false;
326  bool _wasPreempted = false;
327  double _endTime = 0.0;
328 };
329 
330 // Shows a text in the viewport, in one of the fonts and font colors of the game.
331 // The text is the key of one of the game's texts, unless the record says
332 // otherwise. It can be shown a letter at a time, and can move up or down.
333 // TODO: Handle the useBackground, bg and frame fields.
334 class TextRecord : public Record {
335 public:
336  TextRecord(SceneContext &context) : Record(context, "ND.TextAR") {}
337 
338  void updateGraphics() override;
339 
340  // Shows the next letter of a text that isn't shown at once, along with the
341  // markup in front of it. Returns false when there is nothing left to show.
342  bool revealNext();
343 
344 protected:
345  void readTable(int tableIndex) override;
346  void run(double sceneTime, double elapsedTime) override;
347  void onZChanged() override;
348  bool prepareReset() override;
349  bool getField(const Common::String &key) override;
350  bool setField(const Common::String &key) override;
351 
352 private:
353  void setText(const Common::String &text);
354  void applyDest();
355 
356  UI::NDUI::Element _element;
357  RecordGraphic _graphic;
358  bool _isDirty = true;
359 
360  ScriptRect _dest;
361  double _yOffset = 0.0;
362  double _yVelocity = 0.0; // per second
363 
364  // What the record goes back to when it starts over
365  ScriptRect _initialDest;
366  double _initialYOffset = 0.0;
367  double _initialYVelocity = 0.0;
368 
369  bool _usesAutotext = true;
370  bool _revealsAll = true;
371  Common::String _text;
372  Common::String _shownText;
373  uint _numRevealed = 0;
374 };
375 
376 // Plays a movie in the viewport
377 // TODO: Handle the source, volume, loop and modColor fields.
378 class MovieRecord : public Record {
379 public:
380  MovieRecord(SceneContext &context) : Record(context, "ND.Movie") {}
381 
382  void updateGraphics() override;
383  bool isSkippable() const override;
384 
385  void setPaused(bool isPaused) { _isPaused = isPaused; }
386 
387 protected:
388  void readTable(int tableIndex) override;
389  void runOnce() override;
390  void run(double sceneTime, double elapsedTime) override;
391  void onZChanged() override;
392  bool prepareReset() override;
393  bool hasTransform() const override { return true; }
394  void onTransformChanged() override { applyPosition(); }
395  bool getField(const Common::String &key) override;
396  bool setField(const Common::String &key) override;
397 
398 private:
399  void drawFrame();
400  void applyPosition();
401 
402  Common::String _name;
403  MoviePlayer _player;
404  RecordGraphic _graphic;
405  ScriptRect _dest;
406 
407  int _firstFrame = 0;
408  int _lastFrame = 0;
409  bool _pausesOnLastFrame = false;
410  bool _hasCalledOnPause = false;
411  bool _isPaused = false;
412  bool _isVisible = true;
413  double _endTime = 0.0;
414 };
415 
416 } // End of namespace Script
417 } // End of namespace Nancy
418 
419 #endif // NANCY_SCRIPT_RECORDS_H
Definition: managed_surface.h:51
Definition: str.h:59
Definition: viewport.h:42
Definition: records.h:378
Definition: types.h:39
Definition: movieplayer.h:56
Definition: records.h:75
Definition: records.h:222
Definition: scenecontext.h:52
Definition: soundequalizerpuzzle.h:27
Definition: renderobject.h:36
Definition: element.h:43
Definition: record.h:71
Definition: records.h:334
Definition: types.h:62
Definition: commontypes.h:306
Definition: records.h:142
Definition: ref.h:41
Definition: records.h:254
Definition: records.h:303
Definition: records.h:93
Definition: records.h:196
Definition: actionmanager.h:32