ScummVM API documentation
conversations.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 MADS_CONVERSATIONS_H
23 #define MADS_CONVERSATIONS_H
24 
25 #include "common/scummsys.h"
26 #include "common/array.h"
27 #include "common/str-array.h"
28 #include "mads/nebular/core/screen.h"
29 #include "mads/nebular/core/dialogs.h"
30 
31 namespace MADS {
32 namespace Nebular {
33 
34 #define MAX_CONVERSATIONS 5
35 #define MAX_SPEAKERS 5
36 
37 enum ConversationMode {
38  CONVMODE_NONE = -1,
39  CONVMODE_NEXT = 0,
40  CONVMODE_WAIT_AUTO = 1,
41  CONVMODE_WAIT_ENTRY = 2,
42  CONVMODE_EXECUTE = 3,
43  CONVMODE_REPLY = 4,
44  CONVMODE_5 = 5,
45  CONVMODE_6 = 6,
46  CONVMODE_7 = 7,
47  CONVMODE_8 = 8,
48  CONVMODE_9 = 9,
49  CONVMODE_STOP = 10
50 };
51 
52 enum DialogCommand {
53  CMD_END = 0,
54  CMD_1 = 1,
55  CMD_HIDE = 2,
56  CMD_UNHIDE = 3,
57  CMD_MESSAGE1 = 4,
58  CMD_MESSAGE2 = 5,
59  CMD_ERROR = 6,
60  CMD_NODE = 7,
61  CMD_GOTO = 8,
62  CMD_ASSIGN = 9,
63  CMD_DIALOG_END = 255
64 };
65 
66 enum ConvEntryFlag {
67  ENTRYFLAG_2 = 2,
68  ENTRYFLAG_4000 = 0x4000,
69  ENTRYFLAG_8000 = 0x8000
70 };
71 
72 enum ConditionalOperation {
73  CONDOP_NONE = 0xff,
74  CONDOP_VALUE = 0,
75  CONDOP_ADD = 1,
76  CONDOP_SUBTRACT = 2,
77  CONDOP_MULTIPLY = 3,
78  CONDOP_DIVIDE = 4,
79  CONDOP_MODULUS = 5,
80  CONDOP_LTEQ = 6,
81  CONDOP_GTEQ = 7,
82  CONDOP_LT = 8,
83  CONDOP_GT = 9,
84  CONDOP_NEQ = 10,
85  CONDOP_EQ = 11,
86  CONDOP_AND = 12,
87  CONDOP_OR = 13,
88  CONDOP_ABORT = 0xff
89 };
90 
91 class RexNebularEngine;
92 
94  bool _isPtr;
95  int _val;
96  int *_valPtr;
97 
101  ConversationVar() : _isPtr(false), _val(0), _valPtr(nullptr) {
102  }
103 
107  void setValue(int val);
108 
112  void setValue(int *val);
113 
117  int *getValue() {
118  return _isPtr ? _valPtr : &_val;
119  }
120 
124  bool isPtr() const {
125  return _isPtr;
126  }
127 
131  bool isNumeric() const {
132  return !_isPtr;
133  }
134 };
135 
136 struct ScriptEntry {
137  struct Conditional {
139  bool _isVariable;
140  int _val;
141 
145  CondtionalParamEntry() : _isVariable(false), _val(0) {
146  }
147  };
148 
149  static Common::Array<ConversationVar> *_vars;
150  ConditionalOperation _operation;
151  CondtionalParamEntry _param1;
152  CondtionalParamEntry _param2;
153 
157  Conditional() : _operation(CONDOP_NONE) {
158  }
159 
163  void load(Common::SeekableReadStream &s);
164 
168  int get(int paramNum) const;
169 
173  int evaluate() const;
174  };
175 
176  struct MessageEntry {
177  int _size;
178  int _v2;
179 
180  MessageEntry() : _size(0), _v2(0) {
181  }
182  };
183 
184  DialogCommand _command;
185  Conditional _conditionals[3];
186 
187  // Extra parameters for different opcodes
188  int _index;
189  Common::Array<int> _entries;
190  Common::Array<MessageEntry> _entries2;
191 
195  ScriptEntry() : _command(CMD_END), _index(0) {
196  }
197 
201  void load(Common::SeekableReadStream &s);
202 };
203 
207 class DialogScript : public Common::Array<ScriptEntry> {
208 public:
212  void load(Common::SeekableReadStream &s, uint startingOffset);
213 };
214 
218 struct ConvDialog {
219  struct ScriptEntry {
220  DialogCommand _command;
221  };
222 
223  int16 _textLineIndex; // 0-based
224  int16 _speechIndex; // 1-based
225  uint16 _scriptOffset; // offset of script entry
226  uint16 _scriptSize; // size of script entry
227 
228  DialogScript _script;
229 };
230 
234 struct ConvNode {
235  uint16 _index;
236  uint16 _dialogCount;
237  int16 _unk1;
238  bool _active;
239  int16 _unk3;
240 
241  Common::Array<ConvDialog> _dialogs;
242 };
243 
247 struct ConvMessage {
248  uint _stringIndex;
249  uint _count;
250 
251  ConvMessage() : _stringIndex(0), _count(0) {
252  }
253 };
254 
259  uint16 _nodeCount; // conversation nodes, each one containing several dialog options and messages
260  uint16 _dialogCount; // messages (non-selectable) + texts (selectable)
261  uint16 _messageCount; // messages (non-selectable)
262  uint16 _textLineCount;
263  uint16 _unk2;
264  uint16 _maxImports;
265  uint16 _speakerCount;
266  int _textSize;
267  int _commandsSize;
268 
269  Common::Path _portraits[MAX_SPEAKERS];
270  int _speakerFrame[MAX_SPEAKERS];
271  Common::Path _speechFile;
272  Common::Array<ConvMessage> _messages;
273  Common::StringArray _textLines;
275  Common::Array<ConvDialog> _dialogs;
276 
280  void load(const Common::Path &filename);
281 };
282 
287  Common::Array<uint> _importVariables;
288  Common::Array<uint> _entryFlags;
290  int _numImports;
291 
292  int _currentNode;
293  Common::Array<int> _playerMessageList;
294  Common::Array<int> _actorMessageList;
295  Common::Array<int> _playerSpeechList;
296  Common::Array<int> _actorSpeechList;
297 
302 
306  void load(const Common::Path &filename);
307 };
308 
313  int _convId;
314  ConversationData _data;
316 };
317 
318 class MADSEngine;
319 
324 private:
325  RexNebularEngine *_vm;
326  ConversationEntry _conversations[MAX_CONVERSATIONS];
327  bool _speakerActive[MAX_SPEAKERS];
328  int _speakerSeries[MAX_SPEAKERS];
329  int _speakerFrame[MAX_SPEAKERS];
330  int _popupX[MAX_SPEAKERS];
331  int _popupY[MAX_SPEAKERS];
332  int _popupMaxLen[MAX_SPEAKERS];
333  InputMode _inputMode;
334  bool _popupVisible;
335  ConversationMode _currentMode;
336  ConversationMode _priorMode;
337  int _verbId;
338  int _speakerVal;
339  int _heroTrigger;
340  TriggerMode _heroTriggerMode;
341  int _interlocutorTrigger;
342  TriggerMode _interlocutorTriggerMode;
343  ConversationEntry *_runningConv;
344  int _restoreRunning;
345  bool _playerEnabled;
346  uint32 _startFrameNumber;
347  ConversationVar *_vars;
348  ConversationVar *_nextStartNode;
349  int _currentNode;
350  int _dialogNodeOffset, _dialogNodeSize;
351  int _personSpeaking;
352  TextDialog *_dialog;
353  bool _dialogAltFlag;
354 
358  ConversationEntry *getConv(int convId);
359 
363  void start();
364 
368  void removeActiveWindow();
369 
373  void flagEntry(DialogCommand mode, int entryIndex);
374 
378  ConversationMode generateMenu();
379 
383  void generateText(int textLineIndex, Common::Array<int> &messages);
384 
388  void generateMessage(Common::Array<int> &messageList, Common::Array<int> &voiecList);
389 
393  bool nextNode();
394 
398  int executeEntry(int index);
399 
403  void scriptMessage(ScriptEntry &scrEntry);
404 
408  bool scriptNode(ScriptEntry &scrEntry);
409 public:
414 
418  virtual ~GameConversations();
419 
424  void load(int id);
425 
430  void run(int id);
431 
435  void setVariable(uint idx, int val);
436 
440  void setVariable(uint idx, int *val);
441 
445  void setStartNode(uint nodeIndex);
446 
450  void setHeroTrigger(int val);
451 
455  void setInterlocutorTrigger(int val);
456 
461  int *getVariable(int idx);
462 
466  void hold();
467 
471  void release();
472 
476  void stop();
477 
481  void exportPointer(int *ptr);
482 
486  void exportValue(int val);
487 
488  void reset(int id);
489 
493  void update(bool flag);
494 
498  bool active() const {
499  return _runningConv != nullptr;
500  }
501 
505  int activeConvId() const {
506  return !active() ? -1 : _runningConv->_convId;
507  }
508 
512  int restoreRunning() const {
513  return _restoreRunning;
514  }
515 
519  ConversationMode currentMode() const {
520  return _currentMode;
521  }
522 };
523 
524 } // namespace Nebular
525 } // namespace MADS
526 
527 #endif
bool isNumeric() const
Definition: conversations.h:131
int * getValue()
Definition: conversations.h:117
Definition: nebular.h:51
Conditional()
Definition: conversations.h:157
CondtionalParamEntry()
Definition: conversations.h:145
Definition: array.h:52
Definition: path.h:52
int restoreRunning() const
Definition: conversations.h:512
Definition: conversations.h:258
Definition: conversations.h:136
Definition: stream.h:745
Definition: conversations.h:218
Definition: conversations.h:93
ConversationVar()
Definition: conversations.h:101
ScriptEntry()
Definition: conversations.h:195
Definition: conversations.h:247
Definition: conversations.h:138
ConversationMode currentMode() const
Definition: conversations.h:519
bool active() const
Definition: conversations.h:498
Definition: conversations.h:234
Definition: conversations.h:219
Definition: dialogs.h:104
Definition: conversations.h:312
Definition: mads.h:68
Definition: conversations.h:176
Definition: conversations.h:286
Definition: mps_installer.h:31
Definition: conversations.h:207
int activeConvId() const
Definition: conversations.h:505
Definition: conversations.h:323
bool isPtr() const
Definition: conversations.h:124
Definition: conversations.h:137