ScummVM API documentation
secondarymovie.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_ACTION_SECONDARYMOVIE_H
23 #define NANCY_ACTION_SECONDARYMOVIE_H
24 
25 #include "common/ptr.h"
26 
27 #include "engines/nancy/action/actionrecord.h"
28 
29 namespace Video {
30 class VideoDecoder;
31 }
32 
33 namespace Nancy {
34 namespace Action {
35 
36 class InteractiveVideo;
37 
38 // Plays an AVF or Bink video. Optionally supports:
39 // - playing a sound;
40 // - reverse playback;
41 // - moving with the scene's background frame;
42 // - hiding of player cursor (and thus, disabling input);
43 // - setting event flags on a specific frame, as well as at the end of the video;
44 // - changing the scene after playback ends
45 // Mostly used for cinematics, with some occasional uses for background animations.
46 //
47 // Construct with `isRandom = true` for Nancy 11's AT_PLAY_RANDOM_MOVIE (AR 45):
48 // the chunk holds a list of sequences and one is picked at readData() time.
50 public:
51  static const byte kMovieSceneChange = 5;
52  static const byte kMovieNoSceneChange = 6;
53 
54  static const byte kPlayerCursorAllowed = 1;
55  static const byte kNoPlayerCursorAllowed = 2;
56 
57  static const byte kPlayMovieForward = 1;
58  static const byte kPlayMovieReverse = 2;
59 
60  struct FlagAtFrame {
61  int16 frameID;
62  FlagDescription flagDesc;
63  };
64 
65  // Name of the next sequence to chain to once the current one finishes,
66  // plus its selection weight in the weighted random pick.
67  struct NextSequenceRef {
68  Common::Path name;
69  uint16 weight = 0;
70  };
71 
72  // `name` is both the sequence id and the movie filename.
73  struct RandomSequence {
74  Common::Path name;
75  uint16 startFrame = 0;
76  uint16 lastFrame = 0;
77  int32 minPauseMs = 0;
78  int32 maxPauseMs = 0;
79  // Weight assigned to "stay on this sequence" in the weighted random
80  // pick. A roll inside [0, stayWeight) means "don't transition";
81  // instead pause for [minPauseMs, maxPauseMs] and re-roll.
82  uint16 stayWeight = 0;
83  Common::Array<NextSequenceRef> nextSequences;
84  };
85 
86  PlaySecondaryMovie(bool isRandom = false);
87  virtual ~PlaySecondaryMovie();
88 
89  void init() override;
90  void onPause(bool pause) override;
91 
92  void readData(Common::SeekableReadStream &stream) override;
93  void execute() override;
94 
95  bool getIsFinished() const { return _isFinished; }
96 
97  Common::Path _videoName;
98  Common::Path _paletteName;
99  Common::Path _bitmapOverlayName;
100 
101  uint16 _videoType = kVideoPlaytypeAVF;
102  uint16 _videoFormat = kLargeVideoFormat;
103  uint16 _videoSceneChange = kMovieNoSceneChange;
104  byte _playerCursorAllowed = kPlayerCursorAllowed;
105  byte _playDirection = kPlayMovieForward;
106  uint16 _firstFrame = 0;
107  uint16 _lastFrame = 0;
108  Common::Array<FlagAtFrame> _frameFlags;
109  MultiEventFlagDescription _triggerFlags;
110  FlagDescription _videoStartFlag;
111 
112  SoundDescription _sound;
113 
114  SceneChangeDescription _sceneChange;
116 
118 
119  // Random-movie state (only populated when _isRandom).
120  bool _isRandom = false;
121  // "RandomMovie" picks any sequence; otherwise it names the starting one.
122  Common::String _startingSequenceName;
123  uint16 _randomPlayerCursorAllowed = kPlayerCursorAllowed;
125 
126  // Chain state. After a sequence's movie finishes the engine rolls a
127  // weighted pick: "stay" -> enter pause for a random duration and
128  // re-roll; valid next-sequence -> swap to that sequence's movie.
129  enum RandomChainState { kRandomPlaying, kRandomPaused };
130  int _activeSequenceIndex = -1;
131  RandomChainState _randomChainState = kRandomPlaying;
132  uint32 _randomPauseEndTime = 0;
133  bool _randomStopRequested = false;
134 
135  // Called by PlayRandomMovieControl::execute() to wind down the AR.
136  void stopRandom() { _randomStopRequested = true; }
137 
138  // Pick & start a fresh random sequence. No-op when not a random AR.
139  void playRandomSequence();
140 
141  bool isViewportRelative() const override { return true; }
142 
143  bool isPersistentAcrossScenes() const override {
144  return _isRandom && !_isDone && !_randomStopRequested;
145  }
146 
147 protected:
148  Common::String getRecordTypeName() const override {
149  return _isRandom ? "PlayRandomMovie" : "PlaySecondaryMovie";
150  }
151 
152  // `ser` and `stream` must wrap the same input; `stream` is only
153  // needed for SecondaryVideoDescription::readData.
154  void readRandomMovieData(Common::Serializer &ser, Common::SeekableReadStream &stream);
155  void readRandomSequence(Common::Serializer &ser, RandomSequence &seq);
156 
157  // (Re)create _decoder as an AVFDecoder or BinkDecoder matching _videoType.
158  void resetDecoder();
159 
160  // Apply a RandomSequence's playback config to the PSM flat fields
161  // and reload the decoder. Returns true on success.
162  bool activateRandomSequence(int index);
163 
164  // Pick the next sequence (or "stay") per the weighted random rules.
165  // Returns -1 if "stay" was picked (and sets up the pause state),
166  // or the chosen sequence index otherwise.
167  int rollNextSequence();
168 
169  Graphics::ManagedSurface _fullFrame;
170  int _curViewportFrame = -1;
171  bool _isFinished = false;
172 };
173 
174 // Companion AR for the random-movie variant of PlaySecondaryMovie. When
175 // executed it stops the currently-active random PlaySecondaryMovie and
176 // optionally performs a scene change / event-flag set.
178 public:
180 
181  void readData(Common::SeekableReadStream &stream) override;
182  void execute() override;
183 
184  enum RandomMovieControlMode : byte {
185  kStopNow = 0,
186  kStopAfterSequence = 1,
187  kResume = 2
188  };
189 
190 protected:
191  Common::String getRecordTypeName() const override { return "PlayRandomMovieControl"; }
192 
193  byte _mode = kStopNow;
194  SceneChangeWithFlag _sceneChange;
195 };
196 
197 } // End of namespace Action
198 } // End of namespace Nancy
199 
200 #endif // NANCY_ACTION_SECONDARYMOVIE_H
Definition: managed_surface.h:51
Definition: commontypes.h:200
Definition: str.h:59
Definition: commontypes.h:152
Definition: array.h:52
Definition: path.h:52
Definition: stream.h:745
Definition: secondarymovie.h:49
Definition: serializer.h:80
Definition: commontypes.h:172
Definition: actionrecord.h:152
Definition: secondarymovie.h:60
Definition: actionrecord.h:97
Definition: commontypes.h:255
Definition: secondarymovie.h:177
Definition: animation.h:37
Definition: commontypes.h:167
Definition: actionmanager.h:32