summary refs log tree commit diff stats
path: root/src/message_system.cpp
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2021-02-04 20:45:18 -0500
committerKelly Rauchenberger <fefferburbia@gmail.com>2021-02-04 20:45:18 -0500
commit871943d6a90bdb92b3cc495d4d927199611f8c6b (patch)
tree9be125438747f7370cfa56e3f3e42f8c68982852 /src/message_system.cpp
parent138e0a8f83e82c6109bfc387ac7417d4f41711b4 (diff)
downloadtanetane-871943d6a90bdb92b3cc495d4d927199611f8c6b.tar.gz
tanetane-871943d6a90bdb92b3cc495d4d927199611f8c6b.tar.bz2
tanetane-871943d6a90bdb92b3cc495d4d927199611f8c6b.zip
Added text boxes
Text now reveals itself and scrolls! Yay! It even plays speaker beeps.

TODO: the arror indicating an A press is needed. Bullets on lines that need bullets. The header that says who the speaker is, if relevant.
Diffstat (limited to 'src/message_system.cpp')
-rw-r--r--src/message_system.cpp153
1 files changed, 153 insertions, 0 deletions
diff --git a/src/message_system.cpp b/src/message_system.cpp index 71e8a5a..5abb4b3 100644 --- a/src/message_system.cpp +++ b/src/message_system.cpp
@@ -1,4 +1,9 @@
1#include "message_system.h" 1#include "message_system.h"
2#include "game.h"
3#include "util.h"
4
5const int CHARS_TO_REVEAL = 1;
6const int CHARS_PER_BEEP = 10;
2 7
3void MessageSystem::tick(double dt) { 8void MessageSystem::tick(double dt) {
4 if (barsState_ == BarsState::Opening || barsState_ == BarsState::Closing) { 9 if (barsState_ == BarsState::Opening || barsState_ == BarsState::Closing) {
@@ -11,6 +16,53 @@ void MessageSystem::tick(double dt) {
11 barsState_ = BarsState::Closed; 16 barsState_ = BarsState::Closed;
12 } 17 }
13 } 18 }
19 } else if (barsState_ == BarsState::Open) {
20 if (!linesToShow_.empty()) {
21 textAdvTimer_.accumulate(dt);
22 while (textAdvTimer_.step()) {
23 // Try to advance text on the first line that isn't totally revealed yet.
24 bool advancedChars = false;
25 for (MessageLine& line : linesToShow_) {
26 if (line.charsRevealed < line.text.size()) {
27 // Every so often play a beep.
28 if (line.charsRevealed % CHARS_PER_BEEP == 0) {
29 if (speaker_ == SpeakerType::Man) {
30 game_.getMixer().playSound("../res/speaking_man.wav");
31 } else if (speaker_ == SpeakerType::Woman) {
32 game_.getMixer().playSound("../res/speaking_woman.wav");
33 } else if (speaker_ == SpeakerType::Boy) {
34 game_.getMixer().playSound("../res/speaking_boy.wav");
35 } else if (speaker_ == SpeakerType::Girl) {
36 game_.getMixer().playSound("../res/speaking_girl.wav");
37 } else if (speaker_ == SpeakerType::Nonhuman) {
38 game_.getMixer().playSound("../res/speaking_nonhuman.wav");
39 }
40 }
41
42 line.charsRevealed += CHARS_TO_REVEAL;
43 if (line.charsRevealed > line.text.size()) {
44 line.charsRevealed = line.text.size();
45 }
46 advancedChars = true;
47 break;
48 }
49 }
50
51 if (!advancedChars) {
52 // If both lines are totally revealed, see if we can scroll up a line.
53 // This is doable as long as the next line isn't the sentinel value that
54 // means an A press is required.
55 if (!lines_.empty() && lines_.front() != "\n") {
56 if (linesToShow_.size() == 2) {
57 linesToShow_.pop_front();
58 }
59
60 linesToShow_.push_back(MessageLine { .text = lines_.front() });
61 lines_.pop_front();
62 }
63 }
64 }
65 }
14 } 66 }
15} 67}
16 68
@@ -24,6 +76,107 @@ void MessageSystem::hideCutsceneBars() {
24 barsState_ = BarsState::Closing; 76 barsState_ = BarsState::Closing;
25} 77}
26 78
79void MessageSystem::displayMessage(std::string_view msg, SpeakerType speaker) {
80 if (!(barsState_ == BarsState::Opening || barsState_ == BarsState::Open)) {
81 displayCutsceneBars();
82 }
83
84 speaker_ = speaker;
85
86 auto lineChunks = splitStr<std::list<std::string>>(std::string(msg), "\n");
87 for (const std::string& text : lineChunks) {
88 auto words = splitStr<std::list<std::string>>(text, " ");
89
90 std::string curLine;
91 int curWidth = 0;
92 bool firstWord = true;
93 bool shouldAddBlank = false;
94
95 // I'm gonna be frank and admit it: I'm not gonna take hyphenation into
96 // consideration. Please don't write any words that are wider than the
97 // textbox.
98 for (const std::string& word : words) {
99 int wordWidth = 0;
100 bool firstChar = true;
101 for (int i=0; i<word.size(); i++) {
102 if (firstChar) {
103 firstChar = false;
104 } else {
105 wordWidth++;
106 }
107
108 wordWidth += game_.getFont().getCharacterWidth(word[i]);
109 }
110
111 int nextWidth = curWidth + wordWidth;
112 if (!firstWord) {
113 nextWidth += game_.getFont().getCharacterWidth(' ');
114 }
115
116 if (nextWidth > MESSAGE_TEXT_WIDTH) {
117 lines_.push_back(curLine);
118 curLine = word;
119 curWidth = wordWidth + game_.getFont().getCharacterWidth(' ');
120
121 if (shouldAddBlank) {
122 shouldAddBlank = false;
123 lines_.push_back("\n");
124 } else {
125 shouldAddBlank = true;
126 }
127 } else {
128 curWidth = nextWidth;
129 if (!firstWord) {
130 curLine.append(" ");
131 }
132 curLine.append(word);
133 }
134
135 firstWord = false;
136 }
137
138 lines_.push_back(curLine);
139 lines_.push_back("\n");
140 }
141
142 if (linesToShow_.empty()) {
143 linesToShow_.push_back(MessageLine { .text = lines_.front() });
144 lines_.pop_front();
145
146 if (lines_.front() != "\n") {
147 linesToShow_.push_back(MessageLine { .text = lines_.front() });
148 lines_.pop_front();
149 }
150 }
151}
152
153void MessageSystem::advanceText() {
154 if (barsState_ != BarsState::Open) {
155 return;
156 }
157
158 for (const MessageLine& line : linesToShow_) {
159 if (line.charsRevealed != line.text.size()) {
160 return;
161 }
162 }
163
164 if (lines_.empty()) {
165 linesToShow_.clear();
166 return;
167 }
168
169 if (lines_.front() != "\n") {
170 return;
171 }
172
173 lines_.pop_front();
174
175 if (lines_.empty()) {
176 linesToShow_.clear();
177 }
178}
179
27double MessageSystem::getCutsceneBarsProgress() const { 180double MessageSystem::getCutsceneBarsProgress() const {
28 switch (barsState_) { 181 switch (barsState_) {
29 case BarsState::Closed: return 0.0; 182 case BarsState::Closed: return 0.0;