diff --git a/desktop_version/src/Game.cpp b/desktop_version/src/Game.cpp index fa64f1e2..54582aa0 100644 --- a/desktop_version/src/Game.cpp +++ b/desktop_version/src/Game.cpp @@ -361,6 +361,9 @@ void Game::init(void) old_skip_message_timer = 0; skip_message_timer = 0; + old_mode_indicator_timer = 0; + mode_indicator_timer = 0; + setdefaultcontrollerbuttons(); } diff --git a/desktop_version/src/Game.h b/desktop_version/src/Game.h index 48752127..1248d1aa 100644 --- a/desktop_version/src/Game.h +++ b/desktop_version/src/Game.h @@ -589,6 +589,9 @@ public: int old_skip_message_timer; int skip_message_timer; + + int old_mode_indicator_timer; + int mode_indicator_timer; }; #ifndef GAME_DEFINITION diff --git a/desktop_version/src/Render.cpp b/desktop_version/src/Render.cpp index 9592aafa..f0bf6a9c 100644 --- a/desktop_version/src/Render.cpp +++ b/desktop_version/src/Render.cpp @@ -2175,6 +2175,87 @@ static const char* interact_prompt( return buffer; } +static void mode_indicator_text(const int alpha) +{ + const int flags = PR_BRIGHTNESS(alpha) | PR_BOR | PR_RTL_XFLIP; + const int r = 220 - help.glow; + const int g = 220 - help.glow; + const int b = 255 - help.glow/2; + const int x = 5; + const int spacing = font::height(flags) + 2; + int y = 5; + if (game.advancetext) + { + /* Prevent clashing */ + y += 15; + } + + /* FIXME: Some strings have not yet been translated. In order to not have + * English text in other languages, they are substituted with existing + * ones. Remove all substitute text when they're fully translated. */ + + if (map.invincibility) + { + const char* english = "Invincibility mode enabled"; + const char* text = loc::gettext(english); + if (loc::lang != "en" && SDL_strcmp(english, text) == 0) + { + /* Substitute text */ + text = loc::gettext("Invincibility"); + } + font::print(flags, x, y, text, r, g, b); + y += spacing; + } + + enum GlitchrunnerMode mode = GlitchrunnerMode_get(); + if (mode != GlitchrunnerNone) + { + char buffer[SCREEN_WIDTH_CHARS + 1]; + const char* english = "Glitchrunner mode enabled ({version})"; + const char* text = loc::gettext(english); + if (loc::lang != "en" && SDL_strcmp(english, text) == 0) + { + /* Substitute text */ + SDL_strlcpy(buffer, loc::gettext("Glitchrunner Mode"), sizeof(buffer)); + } + else + { + const char* mode_string = loc::gettext(GlitchrunnerMode_enum_to_string(mode)); + vformat_buf(buffer, sizeof(buffer), text, "version:str", mode_string); + } + font::print(flags, x, y, buffer, r, g, b); + y += spacing; + } + + if (graphics.flipmode) + { + const char* english = "Flip Mode enabled"; + const char* text = loc::gettext(english); + if (loc::lang != "en" && SDL_strcmp(english, text) == 0) + { + /* Substitute text */ + text = loc::gettext("Flip Mode"); + } + font::print(flags, x, y, text, r, g, b); + y += spacing; + } + + switch (game.slowdown) + { + case 24: + font::print(flags, x, y, loc::gettext("Game speed is at 80%"), r, g, b); + y += spacing; + break; + case 18: + font::print(flags, x, y, loc::gettext("Game speed is at 60%"), r, g, b); + y += spacing; + break; + case 12: + font::print(flags, x, y, loc::gettext("Game speed is at 40%"), r, g, b); + y += spacing; + } +} + void gamerender(void) { graphics.set_render_target(graphics.gameplayTexture); @@ -2232,6 +2313,11 @@ void gamerender(void) draw_return_editor_text = return_editor_alpha > 100; } + int mode_indicator_alpha = graphics.lerp( + game.old_mode_indicator_timer, game.mode_indicator_timer + ); + bool draw_mode_indicator_text = mode_indicator_alpha > 100; + if (graphics.fademode == FADE_NONE && !game.intimetrial && !game.isingamecompletescreen() @@ -2239,7 +2325,8 @@ void gamerender(void) && game.showingametimer && !roomname_translator::enabled && (!game.swnmode || game.swngame != SWN_START_GRAVITRON_STEP_3) - && !draw_return_editor_text) + && !draw_return_editor_text + && !draw_mode_indicator_text) { const char* tempstring = loc::gettext("TIME:"); int label_len = font::len(0, tempstring); @@ -2302,6 +2389,11 @@ void gamerender(void) graphics.drawgui(); + if (draw_mode_indicator_text && !draw_return_editor_text) + { + mode_indicator_text(mode_indicator_alpha); + } + graphics.set_render_target(graphics.gameTexture); graphics.copy_texture(graphics.gameplayTexture, NULL, NULL); diff --git a/desktop_version/src/RenderFixed.cpp b/desktop_version/src/RenderFixed.cpp index b2ca3e6c..c68f484d 100644 --- a/desktop_version/src/RenderFixed.cpp +++ b/desktop_version/src/RenderFixed.cpp @@ -137,6 +137,12 @@ void gamerenderfixed(void) ed.return_message_timer -= 15; } + game.old_mode_indicator_timer = game.mode_indicator_timer; + if (game.mode_indicator_timer > 0) + { + game.mode_indicator_timer -= 15; + } + // Editor ghosts! if (game.ghostsenabled) { diff --git a/desktop_version/src/Script.cpp b/desktop_version/src/Script.cpp index 8207f7ac..6573a924 100644 --- a/desktop_version/src/Script.cpp +++ b/desktop_version/src/Script.cpp @@ -2694,6 +2694,21 @@ void scriptclass::startgamemode(const enum StartMode mode) font::set_level_font_interface(); } + /* Indicate invincibility, glitchrunner, etc. for all modes except these */ + switch (mode) + { + case Start_EDITOR: + case Start_CUTSCENETEST: + break; + case Start_QUIT: + VVV_unreachable(); + + default: + /* If there's editor return text, make this show up after it */ + game.mode_indicator_timer = ed.return_message_timer + 2000; + game.old_mode_indicator_timer = game.mode_indicator_timer; + } + game.jumpheld = true; switch (mode)