From 871943d6a90bdb92b3cc495d4d927199611f8c6b Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Thu, 4 Feb 2021 20:45:18 -0500 Subject: 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. --- src/message_system.cpp | 153 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) (limited to 'src/message_system.cpp') 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 @@ #include "message_system.h" +#include "game.h" +#include "util.h" + +const int CHARS_TO_REVEAL = 1; +const int CHARS_PER_BEEP = 10; void MessageSystem::tick(double dt) { if (barsState_ == BarsState::Opening || barsState_ == BarsState::Closing) { @@ -11,6 +16,53 @@ void MessageSystem::tick(double dt) { barsState_ = BarsState::Closed; } } + } else if (barsState_ == BarsState::Open) { + if (!linesToShow_.empty()) { + textAdvTimer_.accumulate(dt); + while (textAdvTimer_.step()) { + // Try to advance text on the first line that isn't totally revealed yet. + bool advancedChars = false; + for (MessageLine& line : linesToShow_) { + if (line.charsRevealed < line.text.size()) { + // Every so often play a beep. + if (line.charsRevealed % CHARS_PER_BEEP == 0) { + if (speaker_ == SpeakerType::Man) { + game_.getMixer().playSound("../res/speaking_man.wav"); + } else if (speaker_ == SpeakerType::Woman) { + game_.getMixer().playSound("../res/speaking_woman.wav"); + } else if (speaker_ == SpeakerType::Boy) { + game_.getMixer().playSound("../res/speaking_boy.wav"); + } else if (speaker_ == SpeakerType::Girl) { + game_.getMixer().playSound("../res/speaking_girl.wav"); + } else if (speaker_ == SpeakerType::Nonhuman) { + game_.getMixer().playSound("../res/speaking_nonhuman.wav"); + } + } + + line.charsRevealed += CHARS_TO_REVEAL; + if (line.charsRevealed > line.text.size()) { + line.charsRevealed = line.text.size(); + } + advancedChars = true; + break; + } + } + + if (!advancedChars) { + // If both lines are totally revealed, see if we can scroll up a line. + // This is doable as long as the next line isn't the sentinel value that + // means an A press is required. + if (!lines_.empty() && lines_.front() != "\n") { + if (linesToShow_.size() == 2) { + linesToShow_.pop_front(); + } + + linesToShow_.push_back(MessageLine { .text = lines_.front() }); + lines_.pop_front(); + } + } + } + } } } @@ -24,6 +76,107 @@ void MessageSystem::hideCutsceneBars() { barsState_ = BarsState::Closing; } +void MessageSystem::displayMessage(std::string_view msg, SpeakerType speaker) { + if (!(barsState_ == BarsState::Opening || barsState_ == BarsState::Open)) { + displayCutsceneBars(); + } + + speaker_ = speaker; + + auto lineChunks = splitStr>(std::string(msg), "\n"); + for (const std::string& text : lineChunks) { + auto words = splitStr>(text, " "); + + std::string curLine; + int curWidth = 0; + bool firstWord = true; + bool shouldAddBlank = false; + + // I'm gonna be frank and admit it: I'm not gonna take hyphenation into + // consideration. Please don't write any words that are wider than the + // textbox. + for (const std::string& word : words) { + int wordWidth = 0; + bool firstChar = true; + for (int i=0; i MESSAGE_TEXT_WIDTH) { + lines_.push_back(curLine); + curLine = word; + curWidth = wordWidth + game_.getFont().getCharacterWidth(' '); + + if (shouldAddBlank) { + shouldAddBlank = false; + lines_.push_back("\n"); + } else { + shouldAddBlank = true; + } + } else { + curWidth = nextWidth; + if (!firstWord) { + curLine.append(" "); + } + curLine.append(word); + } + + firstWord = false; + } + + lines_.push_back(curLine); + lines_.push_back("\n"); + } + + if (linesToShow_.empty()) { + linesToShow_.push_back(MessageLine { .text = lines_.front() }); + lines_.pop_front(); + + if (lines_.front() != "\n") { + linesToShow_.push_back(MessageLine { .text = lines_.front() }); + lines_.pop_front(); + } + } +} + +void MessageSystem::advanceText() { + if (barsState_ != BarsState::Open) { + return; + } + + for (const MessageLine& line : linesToShow_) { + if (line.charsRevealed != line.text.size()) { + return; + } + } + + if (lines_.empty()) { + linesToShow_.clear(); + return; + } + + if (lines_.front() != "\n") { + return; + } + + lines_.pop_front(); + + if (lines_.empty()) { + linesToShow_.clear(); + } +} + double MessageSystem::getCutsceneBarsProgress() const { switch (barsState_) { case BarsState::Closed: return 0.0; -- cgit 1.4.1