summary refs log tree commit diff stats
path: root/src/sign.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sign.cpp')
-rw-r--r--src/sign.cpp130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/sign.cpp b/src/sign.cpp new file mode 100644 index 0000000..992ac3d --- /dev/null +++ b/src/sign.cpp
@@ -0,0 +1,130 @@
1#include "sign.h"
2#include <list>
3#include "util.h"
4#include "consts.h"
5#include "game.h"
6
7void Sign::displayMessage(std::string text) {
8 signDisplayState = SignInstructionState::FadingIn;
9 lines.clear();
10
11 auto lineChunks = splitStr<std::list<std::string>>(text, "\\n");
12 for (std::string lineChunk : lineChunks) {
13 auto words = splitStr<std::list<std::string>>(lineChunk, " ");
14 std::string prev = words.front();
15 words.pop_front();
16 std::string cur = prev;
17 bool pauseLine = false;
18
19 while (!words.empty()) {
20 cur = prev + " " + words.front();
21
22 int width = 0;
23 TTF_SizeText(font_, cur.c_str(), &width, nullptr);
24 if (width > MESSAGE_TEXT_WIDTH) {
25 lines.push_back({.text = prev, .pause = pauseLine});
26 pauseLine = !pauseLine;
27 cur = words.front();
28 } else if (words.size() == 1) {
29 lines.push_back({.text = cur, .pause = true});
30 }
31
32 prev = cur;
33 words.pop_front();
34 }
35 }
36
37 lines.back().pause = true;
38 linesToShow.push_back(lines.front());
39 lines.pop_front();
40
41 if (!linesToShow.back().pause) {
42 linesToShow.push_back(lines.front());
43 lines.pop_front();
44 }
45}
46
47void Sign::update(size_t dt, Game& game) {
48 SDL_Event e;
49
50 while (SDL_PollEvent(&e)) {
51 if (e.type == SDL_QUIT) {
52 game.quit = true;
53 }
54 }
55
56 switch (signDisplayState) {
57 case SignInstructionState::Hidden: {
58 // Shouldn't happen.
59 break;
60 }
61 case SignInstructionState::FadingIn: {
62 signDisplayFade.tick(dt);
63 if (signDisplayFade.isComplete()) {
64 signDisplayState = SignInstructionState::Visible;
65 }
66
67 break;
68 }
69 case SignInstructionState::FadingOut: {
70 signDisplayFade.tick(dt);
71 if (signDisplayFade.isComplete()) {
72 signDisplayState = SignInstructionState::Hidden;
73 }
74
75 break;
76 }
77 case SignInstructionState::Visible: {
78 const Uint8* state = SDL_GetKeyboardState(NULL);
79 if (state[SDL_SCANCODE_SPACE]) {
80 bool fullyRevealed = true;
81 for (const SignLine& line : linesToShow) {
82 if (line.charsRevealed != line.text.size()) {
83 fullyRevealed = false;
84 break;
85 }
86 }
87
88 if (fullyRevealed) {
89 if (linesToShow.back().pause) {
90 linesToShow.back().pause = false;
91 // Play a sound
92 }
93 if (lines.empty()) {
94 linesToShow.clear();
95 signDisplayState = SignInstructionState::FadingOut;
96 signDisplayFade.start(1000);
97 break;
98 }
99 }
100 }
101
102 textAdvTimer_.accumulate(dt);
103 while (textAdvTimer_.step()) {
104 bool advancedChars = false;
105 for (SignLine& line : linesToShow) {
106 if (line.charsRevealed < line.text.size()) {
107 if (line.charsRevealed % CHARS_PER_BEEP == 0) {
108 // Play a sound
109 game.muxer.playSound("textbeep");
110 }
111 line.charsRevealed++;
112 advancedChars = true;
113 break;
114 }
115 }
116 if (!advancedChars) {
117 if (!lines.empty() && !linesToShow.back().pause) {
118 if (linesToShow.size() == 2) {
119 linesToShow.pop_front();
120 }
121 linesToShow.push_back(lines.front());
122 lines.pop_front();
123 }
124 }
125 }
126
127 break;
128 }
129 }
130}