From 5df0d0616ee3996add0b14e0fb0becd6257d04a2 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Sun, 21 Feb 2021 17:56:17 -0500 Subject: Added a debug console Open it by pressing backtick, close it by hitting escape. Pressing backtick does not open it in release builds. Current shortcomings: opening it for the first time also types a backtick for some reason, but not on subsequent times. Also, it doesn't create a coroutine, so any script function that yields is going to fail. This also added a "is gameplay paused" flag to Game, which will be useful for adding a pause menu. --- CMakeLists.txt | 2 ++ src/animation_system.cpp | 2 ++ src/behaviour_system.cpp | 2 ++ src/camera_system.cpp | 2 ++ src/character_system.cpp | 2 ++ src/effect_system.cpp | 3 +++ src/game.h | 7 ++++++ src/input_system.cpp | 44 ++++++++++++++++++++++++++++++++-- src/input_system.h | 7 ++++++ src/message_system.cpp | 2 ++ src/renderer.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ src/renderer.h | 6 +++++ src/script_system.cpp | 10 ++++++++ src/script_system.h | 2 ++ 14 files changed, 150 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b3994b2..f42260e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,6 +16,8 @@ find_package(SDL2 REQUIRED) find_package(SDL2_image REQUIRED) find_package(SDL2_mixer REQUIRED) +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DTANETANE_DEBUG") + set(ALL_LIBS ${SDL2_LIBRARY} ${SDL2_IMAGE_LIBRARIES} diff --git a/src/animation_system.cpp b/src/animation_system.cpp index c43d0ca..d23eae2 100644 --- a/src/animation_system.cpp +++ b/src/animation_system.cpp @@ -91,6 +91,8 @@ void AnimationSystem::initSprite(int spriteId, std::string_view filename) { } void AnimationSystem::tick(double dt) { + if (game_.isGameplayPaused()) return; + animTimer_.accumulate(dt); while (animTimer_.step()) { for (Sprite& sprite : game_.getSprites() | game_.spriteView()) { diff --git a/src/behaviour_system.cpp b/src/behaviour_system.cpp index 6cd0b52..2d46205 100644 --- a/src/behaviour_system.cpp +++ b/src/behaviour_system.cpp @@ -5,6 +5,8 @@ #include "direction.h" void BehaviourSystem::tick(double dt) { + if (game_.isGameplayPaused()) return; + timer_.accumulate(dt); while (timer_.step()) { for (int spriteId : game_.getSprites()) { diff --git a/src/camera_system.cpp b/src/camera_system.cpp index c46b9dd..0ef3c36 100644 --- a/src/camera_system.cpp +++ b/src/camera_system.cpp @@ -4,6 +4,8 @@ #include "map.h" void CameraSystem::tick(double dt) { + if (game_.isGameplayPaused()) return; + if (!locked_ && followingSprite_ != -1) { const Sprite& follow = game_.getSprite(followingSprite_); diff --git a/src/character_system.cpp b/src/character_system.cpp index 7b628b0..6e15eac 100644 --- a/src/character_system.cpp +++ b/src/character_system.cpp @@ -91,6 +91,8 @@ void CharacterSystem::stopDirecting(int spriteId) { } void CharacterSystem::tick(double dt) { + if (game_.isGameplayPaused()) return; + inputTimer_.accumulate(dt); while (inputTimer_.step()) { for (int spriteId : game_.getSprites()) { diff --git a/src/effect_system.cpp b/src/effect_system.cpp index 74fc8f3..aeccebb 100644 --- a/src/effect_system.cpp +++ b/src/effect_system.cpp @@ -1,6 +1,9 @@ #include "effect_system.h" +#include "game.h" void EffectSystem::tick(double dt) { + if (game_.isGameplayPaused()) return; + if (screenFade_ != screenFadeDest_) { screenFadeThus_ += dt; if (screenFadeThus_ >= screenFadeLength_) { diff --git a/src/game.h b/src/game.h index 72dd337..756ce70 100644 --- a/src/game.h +++ b/src/game.h @@ -86,6 +86,12 @@ public: std::mt19937& getRng() { return *rng_; } + void pauseGameplay() { paused_ = true; } + + void unpauseGameplay() { paused_ = false; } + + bool isGameplayPaused() const { return paused_; } + private: Mixer mixer_; @@ -101,6 +107,7 @@ private: std::unique_ptr map_; Font font_; std::mt19937* rng_; + bool paused_ = false; }; #endif /* end of include guard: GAME_H_E6F1396E */ diff --git a/src/input_system.cpp b/src/input_system.cpp index 43c59dd..1b5b56b 100644 --- a/src/input_system.cpp +++ b/src/input_system.cpp @@ -16,12 +16,42 @@ struct Input { void InputSystem::tick(double dt) { SDL_Event e; while (SDL_PollEvent(&e)) { - if (e.type == SDL_QUIT || (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE)) { + if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE) { + if (debugConsole_) { + debugConsole_ = false; + game_.unpauseGameplay(); + SDL_StopTextInput(); + debugText_.clear(); + } else { + game_.quit(); + } + } else if (e.type == SDL_QUIT) { game_.quit(); return; + } else if (e.type == SDL_TEXTINPUT) { + debugText_.append(e.text.text); } else if (e.type == SDL_KEYDOWN) { - if (e.key.keysym.sym == SDLK_LSHIFT || e.key.keysym.sym == SDLK_RSHIFT) { + if (e.key.keysym.sym == SDLK_BACKQUOTE) { +#ifdef TANETANE_DEBUG + if (!debugConsole_) { + debugConsole_ = true; + game_.pauseGameplay(); + SDL_StartTextInput(); + debugText_.clear(); + } +#endif + } else if (debugConsole_ && e.key.keysym.sym == SDLK_RETURN) { + game_.getSystem().runDebugScript(debugText_); + debugText_.clear(); + } else if (debugConsole_ && e.key.keysym.sym == SDLK_BACKSPACE) { + // Make sure to keep the backtick/heart. + if (!debugText_.empty()) { + debugText_.pop_back(); + } + } else if (e.key.keysym.sym == SDLK_LSHIFT || e.key.keysym.sym == SDLK_RSHIFT) { + if (game_.isGameplayPaused()) continue; + for (int spriteId : game_.getSprites()) { Sprite& sprite = game_.getSprite(spriteId); if (sprite.controllable) { @@ -29,6 +59,8 @@ void InputSystem::tick(double dt) { } } } else if (e.key.keysym.sym == SDLK_SPACE) { + if (game_.isGameplayPaused()) continue; + // If there is text on screen, try to advance it. if (game_.getSystem().getCutsceneBarsProgress() != 0.0) { game_.getSystem().advanceText(); @@ -75,15 +107,21 @@ void InputSystem::tick(double dt) { } } } else if (e.key.keysym.sym == SDLK_LEFT) { + if (game_.isGameplayPaused()) continue; + if (game_.getSystem().isChoiceActive()) { game_.getSystem().selectFirstChoice(); } } else if (e.key.keysym.sym == SDLK_RIGHT) { + if (game_.isGameplayPaused()) continue; + if (game_.getSystem().isChoiceActive()) { game_.getSystem().selectSecondChoice(); } } } else if (e.type == SDL_KEYUP && (e.key.keysym.sym == SDLK_LSHIFT || e.key.keysym.sym == SDLK_RSHIFT)) { + if (game_.isGameplayPaused()) continue; + for (int spriteId : game_.getSprites()) { Sprite& sprite = game_.getSprite(spriteId); if (sprite.controllable) { @@ -93,6 +131,8 @@ void InputSystem::tick(double dt) { } } + if (game_.isGameplayPaused()) return; + Input keystate; const Uint8* state = SDL_GetKeyboardState(NULL); keystate.left = state[SDL_SCANCODE_LEFT]; diff --git a/src/input_system.h b/src/input_system.h index 4e5bb22..a7757b8 100644 --- a/src/input_system.h +++ b/src/input_system.h @@ -1,6 +1,7 @@ #ifndef INPUT_SYSTEM_H_47764575 #define INPUT_SYSTEM_H_47764575 +#include #include "system.h" class Game; @@ -14,9 +15,15 @@ public: void tick(double dt) override; + bool isDebugConsoleOpen() const { return debugConsole_; } + + const std::string& getDebugText() const { return debugText_; } + private: Game& game_; + bool debugConsole_ = false; + std::string debugText_; }; #endif /* end of include guard: INPUT_SYSTEM_H_47764575 */ diff --git a/src/message_system.cpp b/src/message_system.cpp index 32ee847..1447f1e 100644 --- a/src/message_system.cpp +++ b/src/message_system.cpp @@ -6,6 +6,8 @@ const int CHARS_TO_REVEAL = 1; const int CHARS_PER_BEEP = 8; void MessageSystem::tick(double dt) { + if (game_.isGameplayPaused()) return; + if (barsState_ == BarsState::Opening || barsState_ == BarsState::Closing) { accum_ += dt; diff --git a/src/renderer.cpp b/src/renderer.cpp index 5aeb232..f8b2482 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -7,6 +7,7 @@ #include "camera_system.h" #include "message_system.h" #include "effect_system.h" +#include "input_system.h" Renderer::Renderer() { win_ = window_ptr( @@ -333,6 +334,61 @@ void Renderer::render(Game& game) { SDL_RenderFillRect(ren_.get(), nullptr); } + if (game.getSystem().isDebugConsoleOpen()) { + // Not sure why I'm supposed to copy the cached texture to the screen + // BEFORE rendering it, but we get flickering if we don't, so. + SDL_RenderCopy(ren_.get(), debugConsoleTex_.get(), nullptr, &debugDestRect_); + + if (!debugConsoleTex_ || cachedDebugText_ != game.getSystem().getDebugText()) { + cachedDebugText_ = game.getSystem().getDebugText(); + + std::vector textLines; + std::string remaining = "`" + cachedDebugText_; + + while (!remaining.empty()) { + MessageCache output; + renderMessageLine(output, remaining, game); + textLines.push_back(std::move(output.renderedTex)); + remaining = output.overflow; + + if (!remaining.empty()) { + remaining = " " + remaining; + } + } + + int height = 16 * textLines.size() + 4 + 4; + + debugConsoleTex_.reset( + SDL_CreateTexture( + ren_.get(), + SDL_PIXELFORMAT_RGBA8888, + SDL_TEXTUREACCESS_TARGET, + CANVAS_WIDTH, + height)); + + SDL_SetRenderTarget(ren_.get(), debugConsoleTex_.get()); + SDL_SetTextureBlendMode(debugConsoleTex_.get(), SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawBlendMode(ren_.get(), SDL_BLENDMODE_BLEND); + SDL_SetRenderDrawColor(ren_.get(), 30, 0, 110, 127); + //SDL_RenderFillRect(ren_.get(), nullptr); + SDL_RenderClear(ren_.get()); + + for (int i=0; i MESSAGE_TEXT_WIDTH) { + line.overflow = line.line.substr(i); + break; + } + vec2i charLoc = game.getFont().getCharacterLocation(line.line[i]); vec2i charSize = game.getFont().getCharacterSize(line.line[i]); SDL_Rect srcRect { charLoc.x(), charLoc.y(), charSize.w(), charSize.h() }; diff --git a/src/renderer.h b/src/renderer.h index 17dc038..489a7ec 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -152,6 +152,7 @@ private: texture_ptr renderedTex; std::vector charIndexToWidth; std::string line; + std::string overflow; }; void renderMessageLine(MessageCache& line, const std::string& text, Game& game); @@ -161,6 +162,11 @@ private: MessageCache speakerHeaderLine_; int advMsgArrowTex_ = -1; int choiceArrowTex_ = -1; + + // Debug console + texture_ptr debugConsoleTex_; + std::string cachedDebugText_; + SDL_Rect debugDestRect_; }; #endif /* end of include guard: RENDERER_H_6A58EC30 */ diff --git a/src/script_system.cpp b/src/script_system.cpp index 3293753..14d247e 100644 --- a/src/script_system.cpp +++ b/src/script_system.cpp @@ -190,6 +190,8 @@ ScriptSystem::ScriptSystem(Game& game) : game_(game) { } void ScriptSystem::tick(double dt) { + if (game_.isGameplayPaused()) return; + if (callable_ && *callable_) { auto result = (*callable_)(dt); if (!result.valid()) { @@ -228,3 +230,11 @@ void ScriptSystem::runScript(std::string mapName, std::string scriptName) { runner_.reset(); } } + +void ScriptSystem::runDebugScript(std::string script) { + auto result = engine_.script(script); + if (!result.valid()) { + sol::error e = result; + std::cout << e.what() << std::endl; + } +} diff --git a/src/script_system.h b/src/script_system.h index 9c901b7..686415c 100644 --- a/src/script_system.h +++ b/src/script_system.h @@ -20,6 +20,8 @@ public: void runScript(std::string mapName, std::string scriptName); + void runDebugScript(std::string script); + private: Game& game_; -- cgit 1.4.1