ScummVM API documentation
conversation.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_CONVERSATION_H
23 #define NANCY_ACTION_CONVERSATION_H
24 
25 #include "engines/nancy/action/actionrecord.h"
26 #include "engines/nancy/movieplayer.h"
27 
28 namespace Nancy {
29 namespace Action {
30 
31 // The base class for conversations, with no video data. Contains the following:
32 // - a base sound for the NPC's speech and its caption (mandatory)
33 // - a list of possible player responses, also with sounds and captions (optional)
34 // Captions are displayed in the Textbox, and player responses are also selectable there.
35 // Captions are hypertext; meaning, they contain extra data related to the text (see misc/hypertext.h)
36 // A conversation will auto-advance to a next scene when no responses are available; the next scene
37 // can either be described within the Conversation data, or can be whatever's pushed onto the scene "stack".
38 // Also supports branching scenes depending on a condition, though that is only used in older games.
39 // Player responses can also be conditional. Up to Nancy11 the condition data comes from nancy.dat
40 // (see devtools/create_nancy); from Nancy12 on it lives in per-character data scenes (S<800 + charID> / S<900 + charID>).
42 public:
44  virtual ~ConversationSound();
45 
46  void init() override;
47  void readData(Common::SeekableReadStream &stream) override;
48  void execute() override;
49 
50  virtual bool isVideoDonePlaying() { return true; }
51  bool isViewportRelative() const override { return true; }
52 
53  // Enhancement: cut the currently playing line short, as if its sound and
54  // video had just finished. Any available responses still get shown.
55  void skipLine();
56 
57 protected:
59  byte type;
60  FlagDescription flag;
61  byte orFlag;
62 
63  void read(Common::SeekableReadStream &stream);
64  bool isSatisfied() const;
65  void set() const;
66  };
67 
69  Common::Array<ConversationFlag> conditionFlags;
70 
71  void read(Common::SeekableReadStream &stream);
72  bool isSatisfied() const;
73  };
74 
75  struct ResponseStruct {
76  enum AddRule { kAddIfNotFound, kRemoveAndAddToEnd, kRemove };
77 
78  ConversationFlags conditionFlags;
79  Common::String text;
80  Common::String soundName;
81  byte addRule = kAddIfNotFound;
82  SceneChangeDescription sceneChange;
83  FlagDescription flagDesc;
84 
85  bool isOnScreen = false;
86  };
87 
88  struct FlagsStruct {
89  ConversationFlags conditions;
90  ConversationFlag flagToSet;
91  };
92 
94  ConversationFlags conditions;
95  SceneChangeDescription sceneChange;
96  };
97 
98  static const byte kDefaultNextSceneEnabled = 1;
99  static const byte kDefaultNextSceneDisabled = 2;
100 
101  static const byte kPopNextScene = 1;
102  static const byte kNoPopNextScene = 2;
103 
104  Common::String getRecordTypeName() const override { return "ConversationSound"; }
105 
106  // Functions for reading captions are virtual to allow easier support for the terse Conversation variants
107  virtual void readCaptionText(Common::SeekableReadStream &stream);
108  virtual void readResponseText(Common::SeekableReadStream &stream, ResponseStruct &response);
109 
110  // Used in subclasses
111  void readTerseData(Common::SeekableReadStream &stream);
112  void readTerseCaptionText(Common::SeekableReadStream &stream);
113  void readTerseResponseText(Common::SeekableReadStream &stream, ResponseStruct &response);
114 
115  // Nancy13 compact conversation format. readCelDataNancy13 is the only
116  // per-class difference: the base skips the cel-only frame fields, while
117  // ConversationCel reads them plus the XSheet.
118  void readDataNancy13(Common::SeekableReadStream &stream);
119  virtual void readCelDataNancy13(Common::SeekableReadStream &stream);
120 
121  // Add conditional/goodbye responses: from nancy.dat up to Nancy11, from data scenes for Nancy12+
122  void addConditionalDialogue();
123  void addGoodbye();
124  void addConditionalDialogueNancy12();
125  void addGoodbyeNancy12();
126 
127  Common::String _text;
128 
129  SoundDescription _sound;
130  SoundDescription _responseGenericSound;
131 
132  byte _conditionalResponseCharacterID;
133  byte _goodbyeResponseCharacterID;
134  byte _defaultNextScene = kDefaultNextSceneEnabled;
135  byte _popNextScene = kNoPopNextScene;
136  SceneChangeDescription _sceneChange;
137 
139  Common::Array<FlagsStruct> _flagsStructs;
140  Common::Array<SceneBranchStruct> _sceneBranchStructs;
141 
142  bool _hasDrawnTextbox;
143  int16 _pickedResponse;
144  bool _isSkipped = false;
145 
146  const byte _noResponse;
147 };
148 
149 // Conversation with an AVF video. Originally called PlayPrimaryVideoChan0
151 public:
152  void init() override;
153  void updateGraphics() override;
154  void onPause(bool pause) override;
155 
156  void readData(Common::SeekableReadStream &stream) override;
157 
158  bool isVideoDonePlaying() override;
159 
160 protected:
161  Common::String getRecordTypeName() const override;
162 
163  Common::String _videoName;
164  Common::Path _paletteName;
165  uint _videoFormat = kLargeVideoFormat;
166  uint16 _firstFrame = 0;
167  int16 _lastFrame = 0;
168  MoviePlayer _decoder;
169 };
170 
171 class ConversationCelLoader;
172 
173 // Conversation with separate cels for the body and head of the character.
174 // Cels are separate images bundled inside a .cal file
176 public:
177  ConversationCel() {}
178  virtual ~ConversationCel();
179 
180  void init() override;
181  void registerGraphics() override;
182  void updateGraphics() override;
183 
184  void readData(Common::SeekableReadStream &stream) override;
185 
186  bool load();
187  uint getCurFrame() const { return _curFrame; }
188 
189 protected:
190  Common::String getRecordTypeName() const override { return "ConversationCel"; }
191 
192  struct Cel {
194  Common::Rect src;
195  Common::Rect dest;
196  };
197 
198  class RenderedCel : public RenderObject {
199  public:
200  RenderedCel() : RenderObject(9) {}
201  bool isViewportRelative() const override { return true; }
202  };
203 
204  static const byte kCelOverrideTreeRectsOff = 1;
205  static const byte kCelOverrideTreeRectsOn = 2;
206 
207  bool isVideoDonePlaying() override;
208  Cel &loadCel(const Common::Path &name, const Common::String &treeName);
209 
210  void readXSheet(Common::SeekableReadStream &stream, const Common::String &xsheetName);
211  void readCelDataNancy13(Common::SeekableReadStream &stream) override;
212 
215 
216  uint32 _frameTime = 0;
217  uint _videoFormat = kLargeVideoFormat;
218  uint16 _firstFrame = 0;
219  uint16 _lastFrame = 0;
220 
221  Common::Array<byte> _drawingOrder;
222  Common::Array<byte> _overrideTreeRects;
223 
224  Common::Array<Common::Rect> _overrideRectSrcs;
225  Common::Array<Common::Rect> _overrideRectDests;
226 
227  uint _curFrame = 0;
228  uint32 _nextFrameTime = 0;
229 
230  Common::Array<RenderedCel> _celRObjects;
231 
234 };
235 
236 // A ConversationSound without embedded text; uses the CONVO chunk instead
238 protected:
239  Common::String getRecordTypeName() const override { return "ConversationSoundT"; }
240 
241  void readCaptionText(Common::SeekableReadStream &stream) override { readTerseCaptionText(stream); }
242  void readResponseText(Common::SeekableReadStream &stream, ResponseStruct &response) override { readTerseResponseText(stream, response); }
243 };
244 
245 // A ConversationCel without embedded text; uses the CONVO chunk instead
247 protected:
248  Common::String getRecordTypeName() const override { return "ConversationCelT"; }
249 
250  void readCaptionText(Common::SeekableReadStream &stream) override { readTerseCaptionText(stream); }
251  void readResponseText(Common::SeekableReadStream &stream, ResponseStruct &response) override { readTerseResponseText(stream, response); }
252 };
253 
254 // A ConversationSound with a much smaller data footprint
256 public:
257  void readData(Common::SeekableReadStream &stream) override;
258 
259 protected:
260  Common::String getRecordTypeName() const override { return "ConversationSoundTerse"; }
261 };
262 
263 // A ConversationCel with a much smaller data footprint
265 public:
266  void readData(Common::SeekableReadStream &stream) override;
267 
268 protected:
269  Common::String getRecordTypeName() const override { return "ConversationCelTerse"; }
270 };
271 
272 // Nancy12+ conditional dialogue record (type 35), one per response, stored in scene S<800 + charID>
274 public:
275  void readData(Common::SeekableReadStream &stream) override;
276  Common::String getRecordTypeName() const override { return "ConversationInfoCheck"; }
277 
278  Common::String _soundID; // Doubles as the CONVO text key
279  uint16 _sceneID = 0;
280 };
281 
282 // Nancy12+ goodbye record (type 36), stored in scene S<900 + charID>; one sound and scene are picked at random
284 public:
285  void readData(Common::SeekableReadStream &stream) override;
286  Common::String getRecordTypeName() const override { return "ConversationGoodbye"; }
287 
289  Common::Array<uint16> _sceneIDs;
290 };
291 
292 } // End of namespace Action
293 } // End of namespace Nancy
294 
295 #endif // NANCY_ACTION_CONVERSATION_H
Definition: managed_surface.h:51
Definition: str.h:59
Definition: conversation.h:192
Definition: commontypes.h:165
Definition: movieplayer.h:56
Definition: array.h:52
Definition: conversation.h:150
Definition: rect.h:536
Definition: path.h:52
Definition: stream.h:745
Definition: conversation.h:41
Definition: actionrecord.h:161
Definition: renderobject.h:36
Definition: conversation.h:273
Definition: conversation.h:283
Definition: conversation.h:255
Definition: hashmap.h:85
Definition: actionrecord.h:98
Definition: conversation.h:264
Definition: conversation.h:175
Definition: conversation.h:198
Definition: commontypes.h:282
Definition: conversation.h:237
Definition: conversation.h:246
Definition: commontypes.h:180
Definition: actionmanager.h:32