ScummVM API documentation
dialog.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 #ifndef PELROCK_DIALOG_H
22 #define PELROCK_DIALOG_H
23 
24 #include "common/stack.h"
25 
26 #include "graphics/font.h"
27 
28 #include "pelrock/types.h"
29 
30 namespace Graphics {
31 class Screen;
32 }
33 
34 namespace Pelrock {
35 
36 class GraphicsManager;
37 class PelrockEventManager;
38 
39 // Control character codes
40 const byte kCtrlSpace = 0x20; /* ' ' */
41 const byte kCtrlSpeakerId = 0x08; /* Next byte is speaker ID (color) */
42 const byte kCtrlEndText = 0xFD; /* End of text segment */
43 const byte kCtrlTextTerminator = 0xFC; /* Text terminator */
44 const byte kCtrlDialogueMarker = 0xF1; /* Choice marker that sticks */
45 const byte kCtrlDialogueMarkerOneoff = 0xFB; /* Choice marker that disappears after use */
46 const byte kCtrlDisabledChoice = 0xFA; /* Disabled choice marker, generally only after usage */
47 const byte kCtrlPageBreakConv = 0xF9; /* Page break in conversation */
48 const byte kCtrlActionAndEnd = 0xF8; /* Action trigger and end conversation */
49 const byte kCtrlActionAndContinue = 0xEB; /* Action-and-continue: dispatch action, conversation keeps going (unlike 0xF8 which exits) */
50 const byte kCtrlEndBranch = 0xF7; /* End of branch */
51 const byte kCtrlLineContinue = 0xF6; /* Line continue/newline */
52 const byte kCtrlAltEndMarker1 = 0xF5; /* Alt end marker - do nothing */
53 const byte kCtrlEndConversation = 0xF4; /* End conversation and disable option */
54 const byte kCtrlGoBack = 0xF0; /* Go back in conversation */
55 const byte kCtrlAltSpeakerRoot = 0xFE; /* Separates conversations from different speakers */
56 
57 const int kChoiceHeight = 16; // Height of each choice line in pixels
58 const int kMaxCharsPerLine = 47; // 47 characters
59 const int kMaxLines = 5; // Maximum number of lines per page
60 
61 // Helper structures for conversation state management
63  uint32 position;
64  int currentChoiceLevel;
65  ChoiceOption lastSelectedChoice;
66  int currentRoot;
67 };
68 
70  bool shouldEnd;
71  uint32 nextPosition;
72  uint16 actionCode;
73  bool hasAction;
74 };
75 
77  const static int kArrowWidth = 8; // Width of arrow character for scroll
78  const static int kChoicePadding = 16; // padding for the choice text surface
79 private:
80  Graphics::Screen *_screen = nullptr;
81  PelrockEventManager *_events = nullptr;
82  GraphicsManager *_graphics = nullptr;
83  // Current talking sprite, to disable and replace with talking animation
84  Sprite *_curSprite = nullptr;
85 
86  // Private helper functions for conversation parsing
87  void displayDialogue(Common::Array<Common::Array<Common::String>> dialogueLines, byte speakerId);
88  void displayDialogue(Common::Array<Common::Array<Common::String>> dialogueLines, byte speakerId, int xBasePos, int yBasePos);
89  void displayDialogue(Common::String text, byte speakerId);
90  uint32 readTextBlock(const byte *data, uint32 dataSize, uint32 startPos, Common::String &outText, byte &outSpeakerId);
91  uint32 parseChoices(const byte *data, uint32 dataSize, uint32 startPos, Common::Array<ChoiceOption> *outChoices);
92  void setCurSprite(int index);
93  bool checkAllSubBranchesExhausted(const byte *data, uint32 dataSize, uint32 startPos, int currentChoiceLevel);
94 
95  uint32 skipControlBytes(const byte *data, uint32 dataSize, uint32 position);
96  uint32 peekNextMeaningfulByte(const byte *data, uint32 dataSize, uint32 position);
97  ConversationState initializeConversation(const byte *data, uint32 dataSize, byte npcIndex);
98  bool handleGoBack(const byte *data, Common::Stack<uint32> &positionStack, uint32 position, ConversationState &state);
99  uint32 readAndDisplayDialogue(const byte *data, uint32 dataSize, uint32 position);
100  ConversationEndResult checkConversationEnd(const byte *data, uint32 dataSize, uint32 position, int currentRoot = -1);
101  void addGoodbyeOptionIfNeeded(Common::Array<ChoiceOption> *choices, int currentChoiceLevel, uint originalChoiceCount);
102  uint32 processChoiceSelection(const byte *data, uint32 dataSize, Common::Array<ChoiceOption> *choices, int selectedIndex, ConversationState &state);
103  void maybeDisableChoice(Common::Array<Pelrock::ChoiceOption> *choices, int selectedIndex, const byte *data, uint32 dataSize, uint32 endPos, Pelrock::ConversationState &state);
104 
105 public:
107  ~DialogManager();
108 
109  void displayChoices(Common::Array<ChoiceOption> *choices, Graphics::ManagedSurface &compositeBuffer);
110  int selectChoice(Common::Array<Common::String> &choices, Graphics::ManagedSurface &compositeBuffer);
111  void startConversation(const byte *conversationData, uint32 dataSize, byte npcIndex, Sprite *alfredAnimSet = nullptr);
112  uint32 findRoot(int npc, int &currentRoot, uint32 position, uint32 dataSize, const byte *conversationData);
113  uint32 findSpeaker(byte npcIndex, uint32 dataSize, const byte *conversationData);
114  void sayAlfred(Description description);
115  void sayAlfred(Common::StringArray texts);
116  void say(Common::StringArray texts, byte spriteIndex = 0);
117  void say(Common::StringArray texts, int16 x, int16 y);
118  bool processColorAndTrim(Common::StringArray &lines, byte &speakerId);
119  Graphics::Surface *getDialogueSurface(Common::Array<Common::String> dialogueLines, byte speakerId, Graphics::TextAlign alignment = Graphics::kTextAlignCenter);
120 
123  Common::Array<ChoiceOption> *_currentChoices = nullptr;
124 
125  // When true, the goodbye option is suppressed for all conversations in the current room.
126  bool _goodbyeDisabled = false;
127 
128  // True while a blocking dialog or conversation is on screen.
129  bool _dialogActive = false;
130  bool _dismissDialog = false; // When true, the current dialog will be dismissed on the next iteration of the conversation loop (used for programmatically closing dialogs, e.g. when exiting a room)
131  bool _disableClickToAdvance = false;
132  bool _isNPCTalking = false;
133 
134  Common::String _leftArrow = Common::String(17);
135  Common::String _rightArrow = Common::String(16);
136 };
137 
138 } // End of namespace Pelrock
139 #endif // PELROCK_DIALOG_H
Definition: managed_surface.h:51
Center the text.
Definition: font.h:52
Definition: str.h:59
TextAlign
Definition: font.h:48
Definition: surface.h:67
Definition: array.h:52
Definition: events.h:28
Definition: actions.h:26
Definition: atari-screen.h:58
Definition: screen.h:47
Definition: dialog.h:62
Definition: graphics.h:32
Definition: types.h:357
Definition: formatinfo.h:28
Definition: dialog.h:76
Definition: graphics.h:38
Definition: types.h:289
Definition: types.h:501
Definition: dialog.h:69
Definition: stack.h:102