From a1eee7be39e06207e4ec53cc2f0327ee15232b8c Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 24 May 2024 03:02:05 +0200 Subject: [PATCH 01/12] add loading screen - refactor the functionality which takes the most time, namely initializing joysticks (input manager), now it does nothing in the constructor, but we call the initialization later, while showing the loading screen, this is needed, since some thing need to be initialized, for the loading screent o work - use SDL_GetTicks64 instead of SDL_GetTicks - show the loading screen in the application --- src/application.cpp | 89 +++++++++++++++----- src/helper/clock_source.cpp | 2 +- src/input/input.cpp | 5 +- src/input/input.hpp | 4 +- src/scenes/loading_screen/loading_screen.cpp | 88 +++++++++++++++++++ src/scenes/loading_screen/loading_screen.hpp | 29 +++++++ src/scenes/loading_screen/meson.build | 4 + src/scenes/meson.build | 1 + 8 files changed, 200 insertions(+), 22 deletions(-) create mode 100644 src/scenes/loading_screen/loading_screen.cpp create mode 100644 src/scenes/loading_screen/loading_screen.hpp create mode 100644 src/scenes/loading_screen/meson.build diff --git a/src/application.cpp b/src/application.cpp index 50962edb..3d8a1b14 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -4,9 +4,12 @@ #include "helper/message_box.hpp" #include "helper/sleep.hpp" #include "input/input.hpp" +#include "scenes/loading_screen/loading_screen.hpp" #include "scenes/scene.hpp" +#include "ui/layout.hpp" #include +#include #include #include #include @@ -36,7 +39,7 @@ Application::Application(std::shared_ptr&& window, const std::vector(m_window) }, + m_input_manager{ std::make_shared() }, m_settings_manager{ this }, m_target_framerate{ m_command_line_arguments.target_fps } { initialize(); @@ -249,32 +252,80 @@ void Application::render() const { void Application::initialize() { - load_resources(); - push_scene(scenes::create_scene(*this, SceneId::MainMenu, ui::FullScreenLayout{ *m_window })); + + //TODO(Totto): is this safe?! + std::future load_everything = std::async(std::launch::async, [this] { + m_input_manager->initialize(m_window); + + load_resources(); + #ifdef DEBUG_BUILD - m_fps_text = std::make_unique( - this, "FPS: ?", font_manager().get(FontId::Default), Color::white(), - std::pair{ 0.95, 0.95 }, - ui::Alignment{ ui::AlignmentHorizontal::Middle, ui::AlignmentVertical::Center }, - ui::RelativeLayout{ window(), 0.0, 0.0, 0.1, 0.05 }, false - ); + m_fps_text = std::make_unique( + this, "FPS: ?", font_manager().get(FontId::Default), Color::white(), + std::pair{ 0.95, 0.95 }, + ui::Alignment{ ui::AlignmentHorizontal::Middle, ui::AlignmentVertical::Center }, + ui::RelativeLayout{ window(), 0.0, 0.0, 0.1, 0.05 }, false + ); #endif #if defined(_HAVE_DISCORD_SDK) - if (m_settings_manager.settings().discord) { - auto discord_instance = DiscordInstance::initialize(); - if (not discord_instance.has_value()) { - spdlog::warn( - "Error initializing the discord instance, it might not be running: {}", discord_instance.error() - ); - } else { - m_discord_instance = std::move(discord_instance.value()); - m_discord_instance->after_setup(); + if (m_settings_manager.settings().discord) { + auto discord_instance = DiscordInstance::initialize(); + if (not discord_instance.has_value()) { + spdlog::warn( + "Error initializing the discord instance, it might not be running: {}", discord_instance.error() + ); + } else { + m_discord_instance = std::move(discord_instance.value()); + m_discord_instance->after_setup(); + } } - } #endif + }); + + auto loading_screen = scenes::LoadingScreen{ this }; + + using namespace std::chrono_literals; + + const auto sleep_time = m_target_framerate.has_value() ? std::chrono::duration_cast(1s) + / m_target_framerate.value() + : 0s; + auto start_execution_time = std::chrono::steady_clock::now(); + + + bool finished_loading = false; + + while (not finished_loading) { + + loading_screen.update(); + loading_screen.render(*this); + + // present and wait (depending if vsync is on or not, this has to be done manually) + m_renderer.present(); + + if (m_target_framerate.has_value()) { + + const auto now = std::chrono::steady_clock::now(); + const auto runtime = (now - start_execution_time); + if (runtime < sleep_time) { + //TODO(totto): use SDL_DelayNS in sdl >= 3.0 + helper::sleep_nanoseconds(sleep_time - runtime); + start_execution_time = std::chrono::steady_clock::now(); + } else { + start_execution_time = now; + } + } + // end waiting + + // wait until is faster, since it just compares two time_points instead of getting now() and than adding the wait-for argument + finished_loading = + load_everything.wait_until(std::chrono::system_clock::time_point::min()) == std::future_status::ready; + } + + + push_scene(scenes::create_scene(*this, SceneId::MainMenu, ui::FullScreenLayout{ *m_window })); } void Application::load_resources() { diff --git a/src/helper/clock_source.cpp b/src/helper/clock_source.cpp index 732415bd..f003e28c 100644 --- a/src/helper/clock_source.cpp +++ b/src/helper/clock_source.cpp @@ -6,7 +6,7 @@ namespace { [[nodiscard]] double elapsed_time() { - return static_cast(SDL_GetTicks()) / 1000.0; + return static_cast(SDL_GetTicks64()) / 1000.0; } } // namespace diff --git a/src/input/input.cpp b/src/input/input.cpp index f6f4bab3..7ad33609 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -76,7 +76,10 @@ input::PointerEventHelper::PointerEventHelper(shapes::IPoint pos, PointerEvent e return m_event == event; } -input::InputManager::InputManager(const std::shared_ptr& window) { +input::InputManager::InputManager() = default; + + +void input::InputManager::initialize(const std::shared_ptr& window) { //initialize mouse input m_inputs.push_back(std::make_unique()); diff --git a/src/input/input.hpp b/src/input/input.hpp index c81afaa7..18d0e463 100644 --- a/src/input/input.hpp +++ b/src/input/input.hpp @@ -86,7 +86,9 @@ namespace input { std::vector> m_inputs; public: - explicit InputManager(const std::shared_ptr& window); + explicit InputManager(); + + void initialize(const std::shared_ptr& window); [[nodiscard]] const std::vector>& inputs() const; diff --git a/src/scenes/loading_screen/loading_screen.cpp b/src/scenes/loading_screen/loading_screen.cpp new file mode 100644 index 00000000..1a8d5323 --- /dev/null +++ b/src/scenes/loading_screen/loading_screen.cpp @@ -0,0 +1,88 @@ +#include "loading_screen.hpp" +#include "game/graphic_helpers.hpp" +#include "game/tetromino_type.hpp" +#include "graphics/point.hpp" +#include "graphics/window.hpp" +#include "helper/platform.hpp" + +#include + + +scenes::LoadingScreen::LoadingScreen(ServiceProvider* service_provider): + m_segments{ + { Mino{ Mino::GridPoint{ 0, 0 }, helper::TetrominoType::J }, 1.0 }, + { Mino{ Mino::GridPoint{ 1, 0 }, helper::TetrominoType::L }, 1.0 }, + { Mino{ Mino::GridPoint{ 2, 0 }, helper::TetrominoType::I }, 1.0 }, + { Mino{ Mino::GridPoint{ 2, 1 }, helper::TetrominoType::O }, 1.0 }, + { Mino{ Mino::GridPoint{ 2, 2 }, helper::TetrominoType::S }, 1.0 }, + { Mino{ Mino::GridPoint{ 1, 2 }, helper::TetrominoType::T }, 1.0 }, + { Mino{ Mino::GridPoint{ 0, 2 }, helper::TetrominoType::I }, 1.0 }, + { Mino{ Mino::GridPoint{ 0, 1 }, helper::TetrominoType::Z }, 1.0 }, + }, + m_tile_size{ 100, 100 } { + + const auto [total_x_tiles, total_y_tiles] = utils::get_orientation() == utils::Orientation::Landscape + ? std::pair{ 17, 9 } + : std::pair{ 9, 17 }; + + constexpr auto loading_segments_size = 3; + + const auto layout = service_provider->window().size(); + + const u32 tile_size_x = layout.x / total_x_tiles; + const u32 tile_size_y = layout.y / total_y_tiles; + + const auto tile_size = std::min(tile_size_y, tile_size_x); + + m_tile_size = { tile_size, tile_size }; + + const shapes::UPoint grid_start_offset = { (total_x_tiles - loading_segments_size) / 2, + (total_y_tiles - loading_segments_size) / 2 }; + + m_start_offset = grid_start_offset * tile_size; +} + +namespace { + [[nodiscard]] double elapsed_time() { + return static_cast(SDL_GetTicks64()) / 1000.0; + } +} // namespace + + +void scenes::LoadingScreen::update() { + + constexpr const auto paramater = 1.0; + + const auto length = static_cast(m_segments.size()); + + const auto time = elapsed_time(); + + for (size_t i = 0; i < length; ++i) { + auto& segment = m_segments.at(i); + + auto& scale = std::get<1>(segment); + + const auto offset = std::numbers::pi_v * 2.0 * static_cast(i) / length; + + scale = std::sin(time * paramater + offset); + } + // +} + +void scenes::LoadingScreen::render(const ServiceProvider& service_provider) const { + + for (const auto& [mino, scale] : m_segments) { + if (scale >= 0.0) { + helper::graphics::render_mino( + mino, service_provider, MinoTransparency::Solid, scale, + [this](const Mino::GridPoint& point) -> auto { return this->to_screen_coords(point); }, + this->m_tile_size + ); + } + } +} + + +[[nodiscard]] shapes::UPoint scenes::LoadingScreen::to_screen_coords(const Mino::GridPoint& point) const { + return m_start_offset + point.cast() * m_tile_size.x; +} diff --git a/src/scenes/loading_screen/loading_screen.hpp b/src/scenes/loading_screen/loading_screen.hpp new file mode 100644 index 00000000..f010c9d9 --- /dev/null +++ b/src/scenes/loading_screen/loading_screen.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include "game/mino.hpp" + +#include "manager/service_provider.hpp" + +#include + +namespace scenes { + + struct LoadingScreen { + private: + std::vector> m_segments{}; + + shapes::UPoint m_tile_size; + shapes::UPoint m_start_offset; + + public: + explicit LoadingScreen(ServiceProvider* service_provider); + + void update(); + + void render(const ServiceProvider& service_provider) const; + + private: + [[nodiscard]] shapes::UPoint to_screen_coords(const Mino::GridPoint& point) const; + }; + +} // namespace scenes diff --git a/src/scenes/loading_screen/meson.build b/src/scenes/loading_screen/meson.build new file mode 100644 index 00000000..f21ea09a --- /dev/null +++ b/src/scenes/loading_screen/meson.build @@ -0,0 +1,4 @@ +graphics_src_files += files( + 'loading_screen.cpp', + 'loading_screen.hpp', +) diff --git a/src/scenes/meson.build b/src/scenes/meson.build index 8eef60a4..0a329512 100644 --- a/src/scenes/meson.build +++ b/src/scenes/meson.build @@ -3,6 +3,7 @@ graphics_src_files += files('scene.cpp', 'scene.hpp', 'scene_id.hpp') subdir('about_page') subdir('main_menu') subdir('multiplayer_menu') +subdir('loading_screen') subdir('play_select_menu') subdir('recording_selector') subdir('replay_game') From b1123746c00d18e6e56d4726025c2452c0e1bd99 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 24 May 2024 03:21:25 +0200 Subject: [PATCH 02/12] - fix SDL_WUit not working, make it possible, to exit gracefully, when exiting while loading things --- src/application.cpp | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/src/application.cpp b/src/application.cpp index 3d8a1b14..cd9ef178 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -40,7 +40,7 @@ Application::Application(std::shared_ptr&& window, const std::vector() }, - m_settings_manager{ this }, + m_settings_manager{ this }, //TODO: also initiliaze in the loading thread m_target_framerate{ m_command_line_arguments.target_fps } { initialize(); } catch (const helper::GeneralError& general_error) { @@ -57,6 +57,11 @@ Application::Application(std::shared_ptr&& window, const std::vector Date: Fri, 24 May 2024 03:28:49 +0200 Subject: [PATCH 03/12] fix waiting for the thread, by just using std::exit(), it's not pretty but it's the easiest way to do the job, and the loading screen shoudln't take ages, so it likely want be cancelled all the time --- src/application.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/application.cpp b/src/application.cpp index cd9ef178..48782f7c 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -57,11 +57,6 @@ Application::Application(std::shared_ptr&& window, const std::vector Date: Fri, 24 May 2024 04:07:31 +0200 Subject: [PATCH 04/12] fix a few things regarding the loading screen: - make the animation better looking - fix the drawing by using correct parameters for the render_mino function - reset the background each frame, by overdrawing it --- src/application.cpp | 3 - src/scenes/loading_screen/loading_screen.cpp | 70 ++++++++++++-------- src/scenes/loading_screen/loading_screen.hpp | 4 +- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/src/application.cpp b/src/application.cpp index 48782f7c..fa6fff3d 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -252,14 +252,11 @@ void Application::render() const { void Application::initialize() { - - //TODO(Totto): is this safe?! std::future load_everything = std::async(std::launch::async, [this] { m_input_manager->initialize(m_window); load_resources(); - #ifdef DEBUG_BUILD m_fps_text = std::make_unique( this, "FPS: ?", font_manager().get(FontId::Default), Color::white(), diff --git a/src/scenes/loading_screen/loading_screen.cpp b/src/scenes/loading_screen/loading_screen.cpp index 1a8d5323..e0f5d430 100644 --- a/src/scenes/loading_screen/loading_screen.cpp +++ b/src/scenes/loading_screen/loading_screen.cpp @@ -2,24 +2,23 @@ #include "game/graphic_helpers.hpp" #include "game/tetromino_type.hpp" #include "graphics/point.hpp" +#include "graphics/renderer.hpp" #include "graphics/window.hpp" #include "helper/platform.hpp" #include - -scenes::LoadingScreen::LoadingScreen(ServiceProvider* service_provider): - m_segments{ - { Mino{ Mino::GridPoint{ 0, 0 }, helper::TetrominoType::J }, 1.0 }, - { Mino{ Mino::GridPoint{ 1, 0 }, helper::TetrominoType::L }, 1.0 }, - { Mino{ Mino::GridPoint{ 2, 0 }, helper::TetrominoType::I }, 1.0 }, - { Mino{ Mino::GridPoint{ 2, 1 }, helper::TetrominoType::O }, 1.0 }, - { Mino{ Mino::GridPoint{ 2, 2 }, helper::TetrominoType::S }, 1.0 }, - { Mino{ Mino::GridPoint{ 1, 2 }, helper::TetrominoType::T }, 1.0 }, - { Mino{ Mino::GridPoint{ 0, 2 }, helper::TetrominoType::I }, 1.0 }, - { Mino{ Mino::GridPoint{ 0, 1 }, helper::TetrominoType::Z }, 1.0 }, - }, - m_tile_size{ 100, 100 } { +scenes::LoadingScreen::LoadingScreen(ServiceProvider* service_provider) + : m_segments{ + { Mino{ Mino::GridPoint{ 0, 0 }, helper::TetrominoType::J }, 1.0 }, + { Mino{ Mino::GridPoint{ 1, 0 }, helper::TetrominoType::L }, 1.0 }, + { Mino{ Mino::GridPoint{ 2, 0 }, helper::TetrominoType::I }, 1.0 }, + { Mino{ Mino::GridPoint{ 2, 1 }, helper::TetrominoType::O }, 1.0 }, + { Mino{ Mino::GridPoint{ 2, 2 }, helper::TetrominoType::S }, 1.0 }, + { Mino{ Mino::GridPoint{ 1, 2 }, helper::TetrominoType::T }, 1.0 }, + { Mino{ Mino::GridPoint{ 0, 2 }, helper::TetrominoType::I }, 1.0 }, + { Mino{ Mino::GridPoint{ 0, 1 }, helper::TetrominoType::Z }, 1.0 }, +} { const auto [total_x_tiles, total_y_tiles] = utils::get_orientation() == utils::Orientation::Landscape ? std::pair{ 17, 9 } @@ -32,14 +31,12 @@ scenes::LoadingScreen::LoadingScreen(ServiceProvider* service_provider): const u32 tile_size_x = layout.x / total_x_tiles; const u32 tile_size_y = layout.y / total_y_tiles; - const auto tile_size = std::min(tile_size_y, tile_size_x); - - m_tile_size = { tile_size, tile_size }; + m_tile_size = std::min(tile_size_y, tile_size_x); const shapes::UPoint grid_start_offset = { (total_x_tiles - loading_segments_size) / 2, (total_y_tiles - loading_segments_size) / 2 }; - m_start_offset = grid_start_offset * tile_size; + m_start_offset = grid_start_offset * m_tile_size; } namespace { @@ -51,38 +48,57 @@ namespace { void scenes::LoadingScreen::update() { - constexpr const auto paramater = 1.0; + constexpr const auto speed = std::numbers::pi_v * 1.0; + constexpr const auto amplitude = 1.1; + constexpr const auto scale_offset = 1.3; - const auto length = static_cast(m_segments.size()); + const auto length = m_segments.size(); + const auto length_d = static_cast(length); const auto time = elapsed_time(); for (size_t i = 0; i < length; ++i) { + auto& segment = m_segments.at(i); auto& scale = std::get<1>(segment); - const auto offset = std::numbers::pi_v * 2.0 * static_cast(i) / length; + const auto offset = std::numbers::pi_v * 2.0 * static_cast(i) / length_d; - scale = std::sin(time * paramater + offset); + scale = std::min(amplitude * std::sin(time * speed + offset) + scale_offset, 1.0); } // } void scenes::LoadingScreen::render(const ServiceProvider& service_provider) const { + service_provider.renderer().draw_rect_filled(service_provider.window().screen_rect(), Color::black()); + + constexpr const auto scale_threshold = 0.25; + for (const auto& [mino, scale] : m_segments) { - if (scale >= 0.0) { + if (scale >= scale_threshold) { + const auto original_scale = + static_cast(m_tile_size) / static_cast(grid::original_tile_size); + + + const auto tile_size = static_cast(static_cast(m_tile_size) * scale); + helper::graphics::render_mino( - mino, service_provider, MinoTransparency::Solid, scale, - [this](const Mino::GridPoint& point) -> auto { return this->to_screen_coords(point); }, - this->m_tile_size + mino, service_provider, MinoTransparency::Solid, original_scale, + [this, tile_size](const Mino::GridPoint& point) -> auto { + return this->to_screen_coords(point, tile_size); + }, + { tile_size, tile_size } ); } } } -[[nodiscard]] shapes::UPoint scenes::LoadingScreen::to_screen_coords(const Mino::GridPoint& point) const { - return m_start_offset + point.cast() * m_tile_size.x; +[[nodiscard]] shapes::UPoint scenes::LoadingScreen::to_screen_coords(const Mino::GridPoint& point, u32 tile_size) + const { + const auto start_edge = m_start_offset + point.cast() * m_tile_size; + const auto inner_offset = m_tile_size - tile_size / 2; + return start_edge + shapes::UPoint{ inner_offset, inner_offset }; } diff --git a/src/scenes/loading_screen/loading_screen.hpp b/src/scenes/loading_screen/loading_screen.hpp index f010c9d9..29543344 100644 --- a/src/scenes/loading_screen/loading_screen.hpp +++ b/src/scenes/loading_screen/loading_screen.hpp @@ -12,7 +12,7 @@ namespace scenes { private: std::vector> m_segments{}; - shapes::UPoint m_tile_size; + u32 m_tile_size; shapes::UPoint m_start_offset; public: @@ -23,7 +23,7 @@ namespace scenes { void render(const ServiceProvider& service_provider) const; private: - [[nodiscard]] shapes::UPoint to_screen_coords(const Mino::GridPoint& point) const; + [[nodiscard]] shapes::UPoint to_screen_coords(const Mino::GridPoint& point, u32 tile_size) const; }; } // namespace scenes From f1297f8faab2ab0751f4d3b614be0c6cd62eebc9 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 24 May 2024 04:10:17 +0200 Subject: [PATCH 05/12] loading scene: make the animation go clockwise --- src/scenes/loading_screen/loading_screen.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/scenes/loading_screen/loading_screen.cpp b/src/scenes/loading_screen/loading_screen.cpp index e0f5d430..d8a1770d 100644 --- a/src/scenes/loading_screen/loading_screen.cpp +++ b/src/scenes/loading_screen/loading_screen.cpp @@ -63,7 +63,7 @@ void scenes::LoadingScreen::update() { auto& scale = std::get<1>(segment); - const auto offset = std::numbers::pi_v * 2.0 * static_cast(i) / length_d; + const auto offset = std::numbers::pi_v * 2.0 * static_cast(length - i - 1) / length_d; scale = std::min(amplitude * std::sin(time * speed + offset) + scale_offset, 1.0); } @@ -92,6 +92,8 @@ void scenes::LoadingScreen::render(const ServiceProvider& service_provider) cons { tile_size, tile_size } ); } + + //TODO: render text here, but than we need to load the fonts before this, not in the loading thread (not that they take that long) } } From a5afe870630a44714496428154f4b3eb4b1a9945 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 24 May 2024 04:33:08 +0200 Subject: [PATCH 06/12] refactor the loading_screen constructor, to only take the window --- src/application.cpp | 5 ++++- src/scenes/loading_screen/loading_screen.cpp | 4 ++-- src/scenes/loading_screen/loading_screen.hpp | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/application.cpp b/src/application.cpp index fa6fff3d..53e1e25c 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -252,6 +252,9 @@ void Application::render() const { void Application::initialize() { + // this window MUSTN'T be stored, since it is not safe + auto loading_screen = scenes::LoadingScreen{ m_window.get() }; + std::future load_everything = std::async(std::launch::async, [this] { m_input_manager->initialize(m_window); @@ -282,7 +285,6 @@ void Application::initialize() { #endif }); - auto loading_screen = scenes::LoadingScreen{ this }; using namespace std::chrono_literals; @@ -317,6 +319,7 @@ void Application::initialize() { } loading_screen.update(); + // this service_provider only guarantees the renderer + the window to be accessible without race conditions loading_screen.render(*this); // present and wait (depending if vsync is on or not, this has to be done manually) diff --git a/src/scenes/loading_screen/loading_screen.cpp b/src/scenes/loading_screen/loading_screen.cpp index d8a1770d..39653a6c 100644 --- a/src/scenes/loading_screen/loading_screen.cpp +++ b/src/scenes/loading_screen/loading_screen.cpp @@ -8,7 +8,7 @@ #include -scenes::LoadingScreen::LoadingScreen(ServiceProvider* service_provider) +scenes::LoadingScreen::LoadingScreen(Window* window) : m_segments{ { Mino{ Mino::GridPoint{ 0, 0 }, helper::TetrominoType::J }, 1.0 }, { Mino{ Mino::GridPoint{ 1, 0 }, helper::TetrominoType::L }, 1.0 }, @@ -26,7 +26,7 @@ scenes::LoadingScreen::LoadingScreen(ServiceProvider* service_provider) constexpr auto loading_segments_size = 3; - const auto layout = service_provider->window().size(); + const auto layout = window->size(); const u32 tile_size_x = layout.x / total_x_tiles; const u32 tile_size_y = layout.y / total_y_tiles; diff --git a/src/scenes/loading_screen/loading_screen.hpp b/src/scenes/loading_screen/loading_screen.hpp index 29543344..4b152a3e 100644 --- a/src/scenes/loading_screen/loading_screen.hpp +++ b/src/scenes/loading_screen/loading_screen.hpp @@ -16,7 +16,7 @@ namespace scenes { shapes::UPoint m_start_offset; public: - explicit LoadingScreen(ServiceProvider* service_provider); + explicit LoadingScreen(Window* window); void update(); From f1b674519afc8c3d43923c260fab39ae0d0f0e9b Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 24 May 2024 04:51:04 +0200 Subject: [PATCH 07/12] loading screen: - load more resources / manager in there - InputManager, go back to constructor initialization --- src/application.cpp | 32 +++++++++-------- src/application.hpp | 38 ++++++++++++-------- src/input/input.cpp | 5 +-- src/input/input.hpp | 4 +-- src/scenes/loading_screen/loading_screen.cpp | 2 +- 5 files changed, 44 insertions(+), 37 deletions(-) diff --git a/src/application.cpp b/src/application.cpp index 53e1e25c..5fc0b942 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -4,6 +4,7 @@ #include "helper/message_box.hpp" #include "helper/sleep.hpp" #include "input/input.hpp" +#include "manager/music_manager.hpp" #include "scenes/loading_screen/loading_screen.hpp" #include "scenes/scene.hpp" #include "ui/layout.hpp" @@ -38,9 +39,6 @@ Application::Application(std::shared_ptr&& window, const std::vector() }, - m_settings_manager{ this }, //TODO: also initiliaze in the loading thread m_target_framerate{ m_command_line_arguments.target_fps } { initialize(); } catch (const helper::GeneralError& general_error) { @@ -159,7 +157,7 @@ void Application::handle_event(const SDL_Event& event) { // this global event handlers (atm only one) are special cases, they receive all inputs if they are not handled by the scenes explicitly - if (m_music_manager.handle_event(m_input_manager, event)) { + if (m_music_manager->handle_event(m_input_manager, event)) { return; } } @@ -255,10 +253,16 @@ void Application::initialize() { // this window MUSTN'T be stored, since it is not safe auto loading_screen = scenes::LoadingScreen{ m_window.get() }; - std::future load_everything = std::async(std::launch::async, [this] { - m_input_manager->initialize(m_window); + const std::future load_everything = std::async(std::launch::async, [this] { + this->m_music_manager = std::make_unique(this, num_audio_channels); - load_resources(); + this->m_input_manager = std::make_shared(this->m_window); + + this->m_settings_manager = std::make_unique(this); + + this->m_font_manager = std::make_unique(); + + this->load_resources(); #ifdef DEBUG_BUILD m_fps_text = std::make_unique( @@ -270,7 +274,7 @@ void Application::initialize() { #endif #if defined(_HAVE_DISCORD_SDK) - if (m_settings_manager.settings().discord) { + if (m_settings_manager->settings().discord) { auto discord_instance = DiscordInstance::initialize(); if (not discord_instance.has_value()) { spdlog::warn( @@ -298,11 +302,11 @@ void Application::initialize() { // this is a duplicate of below in some cases, but it's just for the loading screen and can't be factored out easily // this also only uses a subset of all things, the real event loop uses, so that nothing breaks while doing multithreading - // not usable: (since accessed via the loading thread): - // - m_input_manager - // - m_fps_text - // - m_font_manager - // - m_discord_instance + // the only things usable are: (since NOT accessed (writing) via the loading thread and already initialized): + // - m_command_line_arguments + // - m_window + // - m_renderer + // - m_target_framerate while ((not finished_loading) and m_is_running #if defined(__CONSOLE__) @@ -369,7 +373,7 @@ void Application::load_resources() { }; for (const auto& [font_id, path] : fonts) { const auto font_path = utils::get_assets_folder() / "fonts" / path; - m_font_manager.load(font_id, font_path, fonts_size); + m_font_manager->load(font_id, font_path, fonts_size); } } diff --git a/src/application.hpp b/src/application.hpp index 34a713b3..c21f5ca2 100644 --- a/src/application.hpp +++ b/src/application.hpp @@ -21,16 +21,18 @@ struct Application final : public EventListener, public ServiceProvider { private: static constexpr auto num_audio_channels = u8{ 2 }; + bool m_is_running{ true }; CommandLineArguments m_command_line_arguments; std::shared_ptr m_window; Renderer m_renderer; - bool m_is_running{ true }; - MusicManager m_music_manager; - std::shared_ptr m_input_manager; - SettingsManager m_settings_manager; - FontManager m_font_manager; helper::optional m_target_framerate; + // these fields are initalized asynchronously in a separate thread + std::unique_ptr m_music_manager; + std::shared_ptr m_input_manager; + std::unique_ptr m_settings_manager; + std::unique_ptr m_font_manager; + #ifdef DEBUG_BUILD std::unique_ptr m_fps_text{ nullptr }; @@ -74,29 +76,35 @@ struct Application final : public EventListener, public ServiceProvider { } FontManager& font_manager() override { - return m_font_manager; + return *m_font_manager; } - const FontManager& font_manager() const override { - return m_font_manager; + + [[nodiscard]] const FontManager& font_manager() const override { + return *m_font_manager; } CommandLineArguments& command_line_arguments() override { return m_command_line_arguments; } - const CommandLineArguments& command_line_arguments() const override { + + [[nodiscard]] const CommandLineArguments& command_line_arguments() const override { return m_command_line_arguments; } + SettingsManager& settings_manager() override { - return m_settings_manager; + return *m_settings_manager; } - const SettingsManager& settings_manager() const override { - return m_settings_manager; + + [[nodiscard]] const SettingsManager& settings_manager() const override { + return *m_settings_manager; } + MusicManager& music_manager() override { - return m_music_manager; + return *m_music_manager; } - const MusicManager& music_manager() const override { - return m_music_manager; + + [[nodiscard]] const MusicManager& music_manager() const override { + return *m_music_manager; } [[nodiscard]] const Renderer& renderer() const override { diff --git a/src/input/input.cpp b/src/input/input.cpp index 7ad33609..f6f4bab3 100644 --- a/src/input/input.cpp +++ b/src/input/input.cpp @@ -76,10 +76,7 @@ input::PointerEventHelper::PointerEventHelper(shapes::IPoint pos, PointerEvent e return m_event == event; } -input::InputManager::InputManager() = default; - - -void input::InputManager::initialize(const std::shared_ptr& window) { +input::InputManager::InputManager(const std::shared_ptr& window) { //initialize mouse input m_inputs.push_back(std::make_unique()); diff --git a/src/input/input.hpp b/src/input/input.hpp index 18d0e463..c81afaa7 100644 --- a/src/input/input.hpp +++ b/src/input/input.hpp @@ -86,9 +86,7 @@ namespace input { std::vector> m_inputs; public: - explicit InputManager(); - - void initialize(const std::shared_ptr& window); + explicit InputManager(const std::shared_ptr& window); [[nodiscard]] const std::vector>& inputs() const; diff --git a/src/scenes/loading_screen/loading_screen.cpp b/src/scenes/loading_screen/loading_screen.cpp index 39653a6c..cce95444 100644 --- a/src/scenes/loading_screen/loading_screen.cpp +++ b/src/scenes/loading_screen/loading_screen.cpp @@ -93,7 +93,7 @@ void scenes::LoadingScreen::render(const ServiceProvider& service_provider) cons ); } - //TODO: render text here, but than we need to load the fonts before this, not in the loading thread (not that they take that long) + //TODO(Totto): render text here, but than we need to load the fonts before this, not in the loading thread (not that they take that long) } } From eb0d6ac820a2408e892c50ecf2f2f19b6d7ac485 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 24 May 2024 16:57:34 +0200 Subject: [PATCH 08/12] add oopetris logo, convert it from teh svg into a texture --- src/scenes/logo/logo.cpp | 150 ++++++++++++++++++++++++++++++++++++ src/scenes/logo/logo.hpp | 11 +++ src/scenes/logo/meson.build | 4 + src/scenes/meson.build | 3 +- 4 files changed, 167 insertions(+), 1 deletion(-) create mode 100644 src/scenes/logo/logo.cpp create mode 100644 src/scenes/logo/logo.hpp create mode 100644 src/scenes/logo/meson.build diff --git a/src/scenes/logo/logo.cpp b/src/scenes/logo/logo.cpp new file mode 100644 index 00000000..d2869d4a --- /dev/null +++ b/src/scenes/logo/logo.cpp @@ -0,0 +1,150 @@ + +#include "logo.hpp" +#include "game/graphic_helpers.hpp" +#include "game/mino.hpp" +#include "graphics/point.hpp" +#include "graphics/renderer.hpp" + +#include + + +[[nodiscard]] Texture utils::get_logo(const ServiceProvider* service_provider, double scale) { + + constexpr auto width = 32; + constexpr auto height = 5; + + constexpr const Mino::GridPoint offset_o2{ 5, 0 }; + constexpr const auto offset_p3 = offset_o2 + Mino::GridPoint{ 5, 0 }; + constexpr const auto offset_e4 = offset_p3 + Mino::GridPoint{ 4, 0 }; + constexpr const auto offset_t5 = offset_e4 + Mino::GridPoint{ 4, 0 }; + constexpr const auto offset_r6 = offset_t5 + Mino::GridPoint{ 6, 0 }; + constexpr const auto offset_i7 = offset_r6 + Mino::GridPoint{ 4, 0 }; + constexpr const auto offset_s8 = offset_i7 + Mino::GridPoint{ 2, 0 }; + + std::vector minos{ + // O + Mino{ Mino::GridPoint{ 0, 0 }, helper::TetrominoType::J }, + Mino{ Mino::GridPoint{ 1, 0 }, helper::TetrominoType::J }, + Mino{ Mino::GridPoint{ 2, 0 }, helper::TetrominoType::L }, + Mino{ Mino::GridPoint{ 3, 0 }, helper::TetrominoType::L }, + Mino{ Mino::GridPoint{ 3, 1 }, helper::TetrominoType::L }, + Mino{ Mino::GridPoint{ 3, 2 }, helper::TetrominoType::L }, + Mino{ Mino::GridPoint{ 3, 3 }, helper::TetrominoType::Z }, + Mino{ Mino::GridPoint{ 3, 4 }, helper::TetrominoType::I }, + Mino{ Mino::GridPoint{ 2, 4 }, helper::TetrominoType::I }, + Mino{ Mino::GridPoint{ 1, 4 }, helper::TetrominoType::I }, + Mino{ Mino::GridPoint{ 0, 4 }, helper::TetrominoType::I }, + Mino{ Mino::GridPoint{ 0, 3 }, helper::TetrominoType::S }, + Mino{ Mino::GridPoint{ 0, 2 }, helper::TetrominoType::J }, + Mino{ Mino::GridPoint{ 0, 1 }, helper::TetrominoType::J }, + // O + Mino{ Mino::GridPoint{ 0, 0 } + offset_o2, helper::TetrominoType::O }, + Mino{ Mino::GridPoint{ 1, 0 } + offset_o2, helper::TetrominoType::O }, + Mino{ Mino::GridPoint{ 2, 0 } + offset_o2, helper::TetrominoType::S }, + Mino{ Mino::GridPoint{ 3, 0 } + offset_o2, helper::TetrominoType::I }, + Mino{ Mino::GridPoint{ 3, 1 } + offset_o2, helper::TetrominoType::J }, + Mino{ Mino::GridPoint{ 3, 2 } + offset_o2, helper::TetrominoType::J }, + Mino{ Mino::GridPoint{ 3, 3 } + offset_o2, helper::TetrominoType::S }, + Mino{ Mino::GridPoint{ 3, 4 } + offset_o2, helper::TetrominoType::L }, + Mino{ Mino::GridPoint{ 2, 4 } + offset_o2, helper::TetrominoType::S }, + Mino{ Mino::GridPoint{ 1, 4 } + offset_o2, helper::TetrominoType::S }, + Mino{ Mino::GridPoint{ 0, 4 } + offset_o2, helper::TetrominoType::I }, + Mino{ Mino::GridPoint{ 0, 3 } + offset_o2, helper::TetrominoType::Z }, + Mino{ Mino::GridPoint{ 0, 2 } + offset_o2, helper::TetrominoType::Z }, + Mino{ Mino::GridPoint{ 0, 1 } + offset_o2, helper::TetrominoType::O }, + // P + Mino{ Mino::GridPoint{ 0, 0 } + offset_p3, helper::TetrominoType::Z }, + Mino{ Mino::GridPoint{ 1, 0 } + offset_p3, helper::TetrominoType::Z }, + Mino{ Mino::GridPoint{ 2, 0 } + offset_p3, helper::TetrominoType::I }, + Mino{ Mino::GridPoint{ 2, 1 } + offset_p3, helper::TetrominoType::Z }, + Mino{ Mino::GridPoint{ 2, 2 } + offset_p3, helper::TetrominoType::L }, + Mino{ Mino::GridPoint{ 1, 2 } + offset_p3, helper::TetrominoType::T }, + Mino{ Mino::GridPoint{ 0, 2 } + offset_p3, helper::TetrominoType::T }, + Mino{ Mino::GridPoint{ 0, 1 } + offset_p3, helper::TetrominoType::T }, + Mino{ Mino::GridPoint{ 0, 3 } + offset_p3, helper::TetrominoType::T }, + Mino{ Mino::GridPoint{ 0, 4 } + offset_p3, helper::TetrominoType::S }, + // E + Mino{ Mino::GridPoint{ 0, 0 } + offset_e4, helper::TetrominoType::O }, + Mino{ Mino::GridPoint{ 1, 0 } + offset_e4, helper::TetrominoType::O }, + Mino{ Mino::GridPoint{ 2, 0 } + offset_e4, helper::TetrominoType::Z }, + Mino{ Mino::GridPoint{ 0, 1 } + offset_e4, helper::TetrominoType::O }, + Mino{ Mino::GridPoint{ 0, 2 } + offset_e4, helper::TetrominoType::O }, + Mino{ Mino::GridPoint{ 1, 2 } + offset_e4, helper::TetrominoType::J }, + Mino{ Mino::GridPoint{ 2, 2 } + offset_e4, helper::TetrominoType::L }, + Mino{ Mino::GridPoint{ 0, 3 } + offset_e4, helper::TetrominoType::T }, + Mino{ Mino::GridPoint{ 0, 4 } + offset_e4, helper::TetrominoType::T }, + Mino{ Mino::GridPoint{ 1, 4 } + offset_e4, helper::TetrominoType::T }, + Mino{ Mino::GridPoint{ 2, 4 } + offset_e4, helper::TetrominoType::S }, + // T + Mino{ Mino::GridPoint{ 0, 0 } + offset_t5, helper::TetrominoType::L }, + Mino{ Mino::GridPoint{ 1, 0 } + offset_t5, helper::TetrominoType::L }, + Mino{ Mino::GridPoint{ 2, 0 } + offset_t5, helper::TetrominoType::Z }, + Mino{ Mino::GridPoint{ 3, 0 } + offset_t5, helper::TetrominoType::Z }, + Mino{ Mino::GridPoint{ 4, 0 } + offset_t5, helper::TetrominoType::I }, + Mino{ Mino::GridPoint{ 2, 1 } + offset_t5, helper::TetrominoType::T }, + Mino{ Mino::GridPoint{ 2, 2 } + offset_t5, helper::TetrominoType::T }, + Mino{ Mino::GridPoint{ 2, 3 } + offset_t5, helper::TetrominoType::T }, + Mino{ Mino::GridPoint{ 2, 4 } + offset_t5, helper::TetrominoType::S }, + // R + Mino{ Mino::GridPoint{ 0, 0 } + offset_r6, helper::TetrominoType::J }, + Mino{ Mino::GridPoint{ 1, 0 } + offset_r6, helper::TetrominoType::J }, + Mino{ Mino::GridPoint{ 2, 0 } + offset_r6, helper::TetrominoType::I }, + Mino{ Mino::GridPoint{ 2, 1 } + offset_r6, helper::TetrominoType::Z }, + Mino{ Mino::GridPoint{ 2, 2 } + offset_r6, helper::TetrominoType::L }, + Mino{ Mino::GridPoint{ 1, 2 } + offset_r6, helper::TetrominoType::T }, + Mino{ Mino::GridPoint{ 0, 2 } + offset_r6, helper::TetrominoType::J }, + Mino{ Mino::GridPoint{ 0, 1 } + offset_r6, helper::TetrominoType::J }, + Mino{ Mino::GridPoint{ 0, 3 } + offset_r6, helper::TetrominoType::T }, + Mino{ Mino::GridPoint{ 1, 3 } + offset_r6, helper::TetrominoType::O }, + Mino{ Mino::GridPoint{ 0, 4 } + offset_r6, helper::TetrominoType::S }, + Mino{ Mino::GridPoint{ 2, 4 } + offset_r6, helper::TetrominoType::S }, + // I + Mino{ Mino::GridPoint{ 0, 0 } + offset_i7, helper::TetrominoType::Z }, + Mino{ Mino::GridPoint{ 0, 1 } + offset_i7, helper::TetrominoType::O }, + Mino{ Mino::GridPoint{ 0, 2 } + offset_i7, helper::TetrominoType::O }, + Mino{ Mino::GridPoint{ 0, 3 } + offset_i7, helper::TetrominoType::O }, + Mino{ Mino::GridPoint{ 0, 4 } + offset_i7, helper::TetrominoType::S }, + // S + Mino{ Mino::GridPoint{ 0, 0 } + offset_s8, helper::TetrominoType::Z }, + Mino{ Mino::GridPoint{ 1, 0 } + offset_s8, helper::TetrominoType::Z }, + Mino{ Mino::GridPoint{ 2, 0 } + offset_s8, helper::TetrominoType::I }, + Mino{ Mino::GridPoint{ 2, 2 } + offset_s8, helper::TetrominoType::L }, + Mino{ Mino::GridPoint{ 1, 2 } + offset_s8, helper::TetrominoType::L }, + Mino{ Mino::GridPoint{ 0, 2 } + offset_s8, helper::TetrominoType::J }, + Mino{ Mino::GridPoint{ 0, 1 } + offset_s8, helper::TetrominoType::I }, + Mino{ Mino::GridPoint{ 2, 3 } + offset_s8, helper::TetrominoType::T }, + Mino{ Mino::GridPoint{ 0, 4 } + offset_s8, helper::TetrominoType::S }, + Mino{ Mino::GridPoint{ 1, 4 } + offset_s8, helper::TetrominoType::O }, + Mino{ Mino::GridPoint{ 2, 4 } + offset_s8, helper::TetrominoType::I }, + }; + + const auto tile_size = static_cast(static_cast(grid::original_tile_size) * scale); + + + const shapes::UPoint total_size{ tile_size * width, tile_size * height }; + + const auto original_scale = static_cast(tile_size) / static_cast(grid::original_tile_size); + + + const auto& renderer = service_provider->renderer(); + + auto texture = renderer.get_texture_for_render_target(total_size); + + + renderer.set_render_target(texture); + renderer.clear(); + + for (const auto& mino : minos) { + helper::graphics::render_mino( + mino, *service_provider, MinoTransparency::Solid, original_scale, + [tile_size](const Mino::GridPoint& point) -> auto { return point.cast() * tile_size; }, + { tile_size, tile_size } + ); + } + + + renderer.reset_render_target(); + + + return texture; +} diff --git a/src/scenes/logo/logo.hpp b/src/scenes/logo/logo.hpp new file mode 100644 index 00000000..b2c01c0b --- /dev/null +++ b/src/scenes/logo/logo.hpp @@ -0,0 +1,11 @@ +#pragma once + + +#include "graphics/texture.hpp" +#include "manager/service_provider.hpp" + + +namespace utils { + [[nodiscard]] Texture get_logo(const ServiceProvider* service_provider, double scale = 1.0); + +} diff --git a/src/scenes/logo/meson.build b/src/scenes/logo/meson.build new file mode 100644 index 00000000..65358428 --- /dev/null +++ b/src/scenes/logo/meson.build @@ -0,0 +1,4 @@ +graphics_src_files += files( + 'logo.cpp', + 'logo.hpp', +) diff --git a/src/scenes/meson.build b/src/scenes/meson.build index 0a329512..daf05632 100644 --- a/src/scenes/meson.build +++ b/src/scenes/meson.build @@ -1,9 +1,10 @@ graphics_src_files += files('scene.cpp', 'scene.hpp', 'scene_id.hpp') subdir('about_page') +subdir('loading_screen') +subdir('logo') subdir('main_menu') subdir('multiplayer_menu') -subdir('loading_screen') subdir('play_select_menu') subdir('recording_selector') subdir('replay_game') From 528be9dd6bc31a785e5bbb404c446d6af4def173 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 24 May 2024 17:21:41 +0200 Subject: [PATCH 09/12] loading screeN: - actually display the logo in the loading screen --- src/application.cpp | 3 +-- src/scenes/loading_screen/loading_screen.cpp | 26 +++++++++++++++++--- src/scenes/loading_screen/loading_screen.hpp | 7 ++++-- src/scenes/logo/logo.cpp | 7 ++---- src/scenes/logo/logo.hpp | 7 ++++-- 5 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/application.cpp b/src/application.cpp index 5fc0b942..b79069c4 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -250,8 +250,7 @@ void Application::render() const { void Application::initialize() { - // this window MUSTN'T be stored, since it is not safe - auto loading_screen = scenes::LoadingScreen{ m_window.get() }; + auto loading_screen = scenes::LoadingScreen{ this }; const std::future load_everything = std::async(std::launch::async, [this] { this->m_music_manager = std::make_unique(this, num_audio_channels); diff --git a/src/scenes/loading_screen/loading_screen.cpp b/src/scenes/loading_screen/loading_screen.cpp index cce95444..35b53046 100644 --- a/src/scenes/loading_screen/loading_screen.cpp +++ b/src/scenes/loading_screen/loading_screen.cpp @@ -2,13 +2,17 @@ #include "game/graphic_helpers.hpp" #include "game/tetromino_type.hpp" #include "graphics/point.hpp" +#include "graphics/rect.hpp" #include "graphics/renderer.hpp" #include "graphics/window.hpp" #include "helper/platform.hpp" +#include "manager/service_provider.hpp" +#include "scenes/logo/logo.hpp" +#include "ui/layout.hpp" #include -scenes::LoadingScreen::LoadingScreen(Window* window) +scenes::LoadingScreen::LoadingScreen(ServiceProvider* service_provider) : m_segments{ { Mino{ Mino::GridPoint{ 0, 0 }, helper::TetrominoType::J }, 1.0 }, { Mino{ Mino::GridPoint{ 1, 0 }, helper::TetrominoType::L }, 1.0 }, @@ -18,7 +22,7 @@ scenes::LoadingScreen::LoadingScreen(Window* window) { Mino{ Mino::GridPoint{ 1, 2 }, helper::TetrominoType::T }, 1.0 }, { Mino{ Mino::GridPoint{ 0, 2 }, helper::TetrominoType::I }, 1.0 }, { Mino{ Mino::GridPoint{ 0, 1 }, helper::TetrominoType::Z }, 1.0 }, -} { +},m_logo{logo::get_logo(service_provider)} { const auto [total_x_tiles, total_y_tiles] = utils::get_orientation() == utils::Orientation::Landscape ? std::pair{ 17, 9 } @@ -26,7 +30,9 @@ scenes::LoadingScreen::LoadingScreen(Window* window) constexpr auto loading_segments_size = 3; - const auto layout = window->size(); + const auto& window = service_provider->window(); + + const auto layout = window.size(); const u32 tile_size_x = layout.x / total_x_tiles; const u32 tile_size_y = layout.y / total_y_tiles; @@ -37,6 +43,18 @@ scenes::LoadingScreen::LoadingScreen(Window* window) (total_y_tiles - loading_segments_size) / 2 }; m_start_offset = grid_start_offset * m_tile_size; + + constexpr const auto logo_width_percentage = 0.8; + + constexpr const auto start_x = (1.0 - logo_width_percentage) / 2.0; + + const auto window_ratio = static_cast(layout.x) / static_cast(layout.y); + + const auto logo_ratio = static_cast(logo::height) / static_cast(logo::width) * window_ratio; + + const auto logo_height_percentage = logo_width_percentage * logo_ratio; + + m_logo_rect = ui::RelativeLayout(window, start_x, 0.05, logo_width_percentage, logo_height_percentage).get_rect(); } namespace { @@ -74,6 +92,8 @@ void scenes::LoadingScreen::render(const ServiceProvider& service_provider) cons service_provider.renderer().draw_rect_filled(service_provider.window().screen_rect(), Color::black()); + service_provider.renderer().draw_texture(m_logo, m_logo_rect); + constexpr const auto scale_threshold = 0.25; for (const auto& [mino, scale] : m_segments) { diff --git a/src/scenes/loading_screen/loading_screen.hpp b/src/scenes/loading_screen/loading_screen.hpp index 4b152a3e..72e9f6c3 100644 --- a/src/scenes/loading_screen/loading_screen.hpp +++ b/src/scenes/loading_screen/loading_screen.hpp @@ -1,7 +1,8 @@ #pragma once +#include "../logo/logo.hpp" #include "game/mino.hpp" - +#include "graphics/rect.hpp" #include "manager/service_provider.hpp" #include @@ -11,12 +12,14 @@ namespace scenes { struct LoadingScreen { private: std::vector> m_segments{}; + Texture m_logo; + shapes::URect m_logo_rect; u32 m_tile_size; shapes::UPoint m_start_offset; public: - explicit LoadingScreen(Window* window); + explicit LoadingScreen(ServiceProvider* service_provider); void update(); diff --git a/src/scenes/logo/logo.cpp b/src/scenes/logo/logo.cpp index d2869d4a..4a37e5c2 100644 --- a/src/scenes/logo/logo.cpp +++ b/src/scenes/logo/logo.cpp @@ -8,10 +8,7 @@ #include -[[nodiscard]] Texture utils::get_logo(const ServiceProvider* service_provider, double scale) { - - constexpr auto width = 32; - constexpr auto height = 5; +[[nodiscard]] Texture logo::get_logo(const ServiceProvider* service_provider, double scale) { constexpr const Mino::GridPoint offset_o2{ 5, 0 }; constexpr const auto offset_p3 = offset_o2 + Mino::GridPoint{ 5, 0 }; @@ -121,7 +118,7 @@ const auto tile_size = static_cast(static_cast(grid::original_tile_size) * scale); - const shapes::UPoint total_size{ tile_size * width, tile_size * height }; + const shapes::UPoint total_size{ tile_size * logo::width, tile_size * logo::height }; const auto original_scale = static_cast(tile_size) / static_cast(grid::original_tile_size); diff --git a/src/scenes/logo/logo.hpp b/src/scenes/logo/logo.hpp index b2c01c0b..1f5ea6c4 100644 --- a/src/scenes/logo/logo.hpp +++ b/src/scenes/logo/logo.hpp @@ -5,7 +5,10 @@ #include "manager/service_provider.hpp" -namespace utils { +namespace logo { + constexpr const auto width = 33; + constexpr const auto height = 5; + [[nodiscard]] Texture get_logo(const ServiceProvider* service_provider, double scale = 1.0); -} +} // namespace logo From c28059cc44ed65eadeb4aae0cfaf4820c86bd0ba Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 24 May 2024 17:33:12 +0200 Subject: [PATCH 10/12] add debug print for the load time --- src/application.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/application.cpp b/src/application.cpp index b79069c4..e50fc060 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -252,6 +252,8 @@ void Application::initialize() { auto loading_screen = scenes::LoadingScreen{ this }; + const auto start_time = SDL_GetTicks64(); + const std::future load_everything = std::async(std::launch::async, [this] { this->m_music_manager = std::make_unique(this, num_audio_channels); @@ -347,13 +349,21 @@ void Application::initialize() { load_everything.wait_until(std::chrono::system_clock::time_point::min()) == std::future_status::ready; } - // we can reach this via SDL_QUiT or (not console::inMainLoop()) + + const auto duration = std::chrono::milliseconds(SDL_GetTicks64() - start_time); + + // we can reach this via SDL_QUIT or (not console::inMainLoop()) if (not finished_loading) { + + spdlog::debug("Aborted loading after {}", duration); + // just exit immediately, without cleaning up, since than we would have to cancel the loading thread somehow, which is way rto complicated, let the OS clean up our mess we create her xD std::exit(0); } + spdlog::debug("Took {} to load", duration); + push_scene(scenes::create_scene(*this, SceneId::MainMenu, ui::FullScreenLayout{ *m_window })); } From e79bfe745f986ca240f01a5bee69a526fe9b3645 Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 24 May 2024 17:43:20 +0200 Subject: [PATCH 11/12] clang-tidy: fix errors --- src/scenes/loading_screen/loading_screen.hpp | 2 +- src/scenes/logo/logo.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scenes/loading_screen/loading_screen.hpp b/src/scenes/loading_screen/loading_screen.hpp index 72e9f6c3..5fc114c6 100644 --- a/src/scenes/loading_screen/loading_screen.hpp +++ b/src/scenes/loading_screen/loading_screen.hpp @@ -11,7 +11,7 @@ namespace scenes { struct LoadingScreen { private: - std::vector> m_segments{}; + std::vector> m_segments; Texture m_logo; shapes::URect m_logo_rect; diff --git a/src/scenes/logo/logo.cpp b/src/scenes/logo/logo.cpp index 4a37e5c2..add3a065 100644 --- a/src/scenes/logo/logo.cpp +++ b/src/scenes/logo/logo.cpp @@ -18,7 +18,7 @@ constexpr const auto offset_i7 = offset_r6 + Mino::GridPoint{ 4, 0 }; constexpr const auto offset_s8 = offset_i7 + Mino::GridPoint{ 2, 0 }; - std::vector minos{ + const std::vector minos{ // O Mino{ Mino::GridPoint{ 0, 0 }, helper::TetrominoType::J }, Mino{ Mino::GridPoint{ 1, 0 }, helper::TetrominoType::J }, From e9f91c7d0aa6a8ff0a24592c1fdc37ded171975f Mon Sep 17 00:00:00 2001 From: Totto16 Date: Fri, 24 May 2024 18:26:02 +0200 Subject: [PATCH 12/12] add header to includes explicitly, to be able to format chrono data types --- src/application.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/application.cpp b/src/application.cpp index e50fc060..74776a06 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -10,6 +10,7 @@ #include "ui/layout.hpp" #include +#include #include #include #include