#include "sign.h" #include #include "util.h" #include "consts.h" #include "game.h" void Sign::displayMessage(std::string text) { signDisplayState = SignInstructionState::FadingIn; signDisplayFade.start(1000); lines.clear(); auto lineChunks = splitStr>(text, "\\n"); for (std::string lineChunk : lineChunks) { auto words = splitStr>(lineChunk, " "); std::string prev = words.front(); words.pop_front(); std::string cur = prev; bool pauseLine = false; while (!words.empty()) { cur = prev + " " + words.front(); int width = 0; TTF_SizeText(font_, cur.c_str(), &width, nullptr); if (width > MESSAGE_TEXT_WIDTH) { lines.push_back({.text = prev, .pause = pauseLine}); pauseLine = !pauseLine; cur = words.front(); } else if (words.size() == 1) { lines.push_back({.text = cur, .pause = true}); cur = ""; } prev = cur; words.pop_front(); } if (!cur.empty()) { lines.push_back({.text = cur, .pause = true}); } } lines.back().pause = true; linesToShow.push_back(lines.front()); lines.pop_front(); if (!linesToShow.back().pause) { linesToShow.push_back(lines.front()); lines.pop_front(); } } void Sign::update(size_t dt, Game& game) { SDL_Event e; while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { game.quit = true; } } switch (signDisplayState) { case SignInstructionState::Hidden: { // Shouldn't happen. break; } case SignInstructionState::FadingIn: { signDisplayFade.tick(dt); if (signDisplayFade.isComplete()) { signDisplayState = SignInstructionState::Visible; } break; } case SignInstructionState::FadingOut: { signDisplayFade.tick(dt); if (signDisplayFade.isComplete()) { signDisplayState = SignInstructionState::Hidden; } break; } case SignInstructionState::Visible: { const Uint8* state = SDL_GetKeyboardState(NULL); if (state[SDL_SCANCODE_SPACE]) { bool fullyRevealed = true; for (const SignLine& line : linesToShow) { if (line.charsRevealed != line.text.size()) { fullyRevealed = false; break; } } if (fullyRevealed) { showNextArrow = false; if (linesToShow.back().pause) { linesToShow.back().pause = false; // Play a sound } if (lines.empty()) { linesToShow.clear(); signDisplayState = SignInstructionState::FadingOut; signDisplayFade.start(1000); break; } } } textAdvTimer_.accumulate(dt); while (textAdvTimer_.step()) { bool advancedChars = false; for (SignLine& line : linesToShow) { if (line.charsRevealed < line.text.size()) { if (line.charsRevealed % CHARS_PER_BEEP == 0) { // Play a sound game.muxer.playSound("textbeep"); } line.charsRevealed++; advancedChars = true; break; } } if (!advancedChars) { if (!lines.empty() && !linesToShow.back().pause) { if (linesToShow.size() == 2) { linesToShow.pop_front(); } linesToShow.push_back(lines.front()); lines.pop_front(); } else { showNextArrow = true; } } } if (showNextArrow) { nextArrowBobTimer_.accumulate(dt); while (nextArrowBobTimer_.step()) { if (nextArrowBobDown_) { nextArrowBobPos++; if (nextArrowBobPos >= 4) { nextArrowBobDown_ = false; } } else { nextArrowBobPos--; if (nextArrowBobPos <= 0) { nextArrowBobDown_ = true; } } } } break; } } }