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/video.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; the original engine had special-purpose "infocheck"
40 // functions, two per character ID, which were used to evaluate those conditions. We replace that with
41 // the data bundled inside nancy.dat (see devtools/create_nancy).
43 public:
45  virtual ~ConversationSound();
46 
47  void init() override;
48  void readData(Common::SeekableReadStream &stream) override;
49  void execute() override;
50 
51  virtual bool isVideoDonePlaying() { return true; }
52  bool isViewportRelative() const override { return true; }
53 
54 protected:
56  byte type;
57  FlagDescription flag;
58  byte orFlag;
59 
60  void read(Common::SeekableReadStream &stream);
61  bool isSatisfied() const;
62  void set() const;
63  };
64 
66  Common::Array<ConversationFlag> conditionFlags;
67 
68  void read(Common::SeekableReadStream &stream);
69  bool isSatisfied() const;
70  };
71 
72  struct ResponseStruct {
73  enum AddRule { kAddIfNotFound, kRemoveAndAddToEnd, kRemove };
74 
75  ConversationFlags conditionFlags;
76  Common::String text;
77  Common::String soundName;
78  byte addRule = kAddIfNotFound;
79  SceneChangeDescription sceneChange;
80  FlagDescription flagDesc;
81 
82  bool isOnScreen = false;
83  };
84 
85  struct FlagsStruct {
86  ConversationFlags conditions;
87  ConversationFlag flagToSet;
88  };
89 
91  ConversationFlags conditions;
92  SceneChangeDescription sceneChange;
93  };
94 
95  static const byte kDefaultNextSceneEnabled = 1;
96  static const byte kDefaultNextSceneDisabled = 2;
97 
98  static const byte kPopNextScene = 1;
99  static const byte kNoPopNextScene = 2;
100 
101  Common::String getRecordTypeName() const override { return "ConversationSound"; }
102 
103  // Functions for reading captions are virtual to allow easier support for the terse Conversation variants
104  virtual void readCaptionText(Common::SeekableReadStream &stream);
105  virtual void readResponseText(Common::SeekableReadStream &stream, ResponseStruct &response);
106 
107  // Used in subclasses
108  void readTerseData(Common::SeekableReadStream &stream);
109  void readTerseCaptionText(Common::SeekableReadStream &stream);
110  void readTerseResponseText(Common::SeekableReadStream &stream, ResponseStruct &response);
111 
112  // Functions for handling the built-in dialogue responses found in the executable
113  void addConditionalDialogue();
114  void addGoodbye();
115 
116  Common::String _text;
117 
118  SoundDescription _sound;
119  SoundDescription _responseGenericSound;
120 
121  byte _conditionalResponseCharacterID;
122  byte _goodbyeResponseCharacterID;
123  byte _defaultNextScene = kDefaultNextSceneEnabled;
124  byte _popNextScene = kNoPopNextScene;
125  SceneChangeDescription _sceneChange;
126 
128  Common::Array<FlagsStruct> _flagsStructs;
129  Common::Array<SceneBranchStruct> _sceneBranchStructs;
130 
131  bool _hasDrawnTextbox;
132  int16 _pickedResponse;
133 
134  const byte _noResponse;
135 };
136 
137 // Conversation with an AVF video. Originally called PlayPrimaryVideoChan0
139 public:
140  void init() override;
141  void updateGraphics() override;
142  void onPause(bool pause) override;
143 
144  void readData(Common::SeekableReadStream &stream) override;
145 
146  bool isVideoDonePlaying() override;
147 
148 protected:
149  Common::String getRecordTypeName() const override;
150 
151  Common::String _videoName;
152  Common::Path _paletteName;
153  uint _videoFormat = kLargeVideoFormat;
154  uint16 _firstFrame = 0;
155  int16 _lastFrame = 0;
156  AVFDecoder _decoder;
157 };
158 
159 class ConversationCelLoader;
160 
161 // Conversation with separate cels for the body and head of the character.
162 // Cels are separate images bundled inside a .cal file
164 public:
165  ConversationCel() {}
166  virtual ~ConversationCel();
167 
168  void init() override;
169  void registerGraphics() override;
170  void updateGraphics() override;
171 
172  void readData(Common::SeekableReadStream &stream) override;
173 
174  bool load();
175  uint getCurFrame() const { return _curFrame; }
176 
177 protected:
178  Common::String getRecordTypeName() const override { return "ConversationCel"; }
179 
180  struct Cel {
182  Common::Rect src;
183  Common::Rect dest;
184  };
185 
186  class RenderedCel : public RenderObject {
187  public:
188  RenderedCel() : RenderObject(9) {}
189  bool isViewportRelative() const override { return true; }
190  };
191 
192  static const byte kCelOverrideTreeRectsOff = 1;
193  static const byte kCelOverrideTreeRectsOn = 2;
194 
195  bool isVideoDonePlaying() override;
196  Cel &loadCel(const Common::Path &name, const Common::String &treeName);
197 
198  void readXSheet(Common::SeekableReadStream &stream, const Common::String &xsheetName);
199 
202 
203  uint16 _frameTime = 0;
204  uint _videoFormat = kLargeVideoFormat;
205  uint16 _firstFrame = 0;
206  uint16 _lastFrame = 0;
207 
208  Common::Array<byte> _drawingOrder;
209  Common::Array<byte> _overrideTreeRects;
210 
211  Common::Array<Common::Rect> _overrideRectSrcs;
212  Common::Array<Common::Rect> _overrideRectDests;
213 
214  uint _curFrame = 0;
215  uint32 _nextFrameTime = 0;
216 
217  Common::Array<RenderedCel> _celRObjects;
218 
221 };
222 
223 // A ConversationSound without embedded text; uses the CONVO chunk instead
225 protected:
226  Common::String getRecordTypeName() const override { return "ConversationSoundT"; }
227 
228  void readCaptionText(Common::SeekableReadStream &stream) override { readTerseCaptionText(stream); }
229  void readResponseText(Common::SeekableReadStream &stream, ResponseStruct &response) override { readTerseResponseText(stream, response); }
230 };
231 
232 // A ConversationCel without embedded text; uses the CONVO chunk instead
234 protected:
235  Common::String getRecordTypeName() const override { return "ConversationCelT"; }
236 
237  void readCaptionText(Common::SeekableReadStream &stream) override { readTerseCaptionText(stream); }
238  void readResponseText(Common::SeekableReadStream &stream, ResponseStruct &response) override { readTerseResponseText(stream, response); }
239 };
240 
241 // A ConversationSound with a much smaller data footprint
243 public:
244  void readData(Common::SeekableReadStream &stream) override;
245 
246 protected:
247  Common::String getRecordTypeName() const override { return "ConversationSoundTerse"; }
248 };
249 
250 // A ConversationCel with a much smaller data footprint
252 public:
253  void readData(Common::SeekableReadStream &stream) override;
254 
255 protected:
256  Common::String getRecordTypeName() const override { return "ConversationCelTerse"; }
257 };
258 
259 } // End of namespace Action
260 } // End of namespace Nancy
261 
262 #endif // NANCY_ACTION_CONVERSATION_H
Definition: managed_surface.h:51
Definition: str.h:59
Definition: conversation.h:180
Definition: commontypes.h:152
Definition: array.h:52
Definition: conversation.h:138
Definition: rect.h:524
Definition: path.h:52
Definition: stream.h:745
Definition: conversation.h:42
Definition: actionrecord.h:152
Definition: renderobject.h:36
Definition: conversation.h:242
Definition: hashmap.h:85
Definition: conversation.h:251
Definition: video.h:41
Definition: conversation.h:163
Definition: conversation.h:186
Definition: commontypes.h:255
Definition: conversation.h:224
Definition: conversation.h:233
Definition: commontypes.h:167
Definition: actionmanager.h:32