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