|
@@ -0,0 +1,138 @@
|
|
|
+#include "CreditsState.hxx"
|
|
|
+
|
|
|
+#include "GameStateManager.hxx"
|
|
|
+
|
|
|
+#include <type_traits>
|
|
|
+
|
|
|
+CreditsState::CreditsState()
|
|
|
+ :font_{"kenney_pixel.ttf"}, jetbrains_ai_logo_{"jetbrains-ai-logo.png"}, kenney_logo_{"kenney-logo.png"},
|
|
|
+ sdl_logo_{"SDL_logo.png"}, boost_logo_{"Boost-logo.png"}
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+void CreditsState::on_enter(GameStateManager& gsm)
|
|
|
+{
|
|
|
+ TTF_Font* const font = font_;
|
|
|
+
|
|
|
+ scroll_y_ = 0.0;
|
|
|
+ done_ = false;
|
|
|
+ scroll_items_ = {
|
|
|
+ "Copyright © 2024, Felix Bytow <drako@drako.guru>",
|
|
|
+ External{jetbrains_ai_logo_, "with some help from JetBrains AI Assistant"},
|
|
|
+ External{kenney_logo_, "Font & UI Pack from kenney.nl"},
|
|
|
+ sdl_logo_,
|
|
|
+ boost_logo_,
|
|
|
+ };
|
|
|
+
|
|
|
+ int summed_size = -50;
|
|
|
+ for (auto const& item: scroll_items_) {
|
|
|
+ summed_size += std::visit([font]<typename T>(T const& it) {
|
|
|
+ int w, h = 0;
|
|
|
+ if constexpr (std::is_same_v<T, char const*>) {
|
|
|
+ TTF_SizeUTF8(font, it, &w, &h);
|
|
|
+ }
|
|
|
+ else if constexpr (std::is_same_v<T, External>) {
|
|
|
+ int logo_h, text_h;
|
|
|
+ TTF_SizeUTF8(font, it.text_, &w, &text_h);
|
|
|
+ SDL_QueryTexture(it.texture_, nullptr, nullptr, &w, &logo_h);
|
|
|
+ h = logo_h+10+text_h;
|
|
|
+ }
|
|
|
+ else if constexpr (std::is_same_v<T, SDL_Texture*>) {
|
|
|
+ SDL_QueryTexture(it, nullptr, nullptr, &w, &h);
|
|
|
+ }
|
|
|
+ return h;
|
|
|
+ }, item);
|
|
|
+ summed_size += 50;
|
|
|
+ }
|
|
|
+ scroll_size_ = static_cast<double>(summed_size);
|
|
|
+}
|
|
|
+
|
|
|
+void CreditsState::on_event(GameStateManager& gsm, SDL_Event const& event)
|
|
|
+{
|
|
|
+ if (event.type==SDL_KEYUP) {
|
|
|
+ switch (event.key.keysym.scancode) {
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ case SDL_SCANCODE_ESCAPE:
|
|
|
+ [[fallthrough]];
|
|
|
+ case SDL_SCANCODE_RETURN:
|
|
|
+ [[fallthrough]];
|
|
|
+ case SDL_SCANCODE_SPACE:
|
|
|
+ gsm.pop_state();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void CreditsState::update(GameStateManager& gsm, std::chrono::milliseconds const delta_time)
|
|
|
+{
|
|
|
+ if (done_) {
|
|
|
+ gsm.pop_state();
|
|
|
+ }
|
|
|
+
|
|
|
+ scroll_y_ += 0.05*static_cast<double>(delta_time.count());
|
|
|
+}
|
|
|
+
|
|
|
+void CreditsState::render(SDLRenderer& renderer)
|
|
|
+{
|
|
|
+ TTF_Font* const font = font_;
|
|
|
+
|
|
|
+ SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
|
|
|
+ SDL_RenderClear(renderer);
|
|
|
+
|
|
|
+ int window_width = 0, window_height = 0;
|
|
|
+ SDL_GetRendererOutputSize(renderer, &window_width, &window_height);
|
|
|
+
|
|
|
+ int y = window_height-static_cast<int>(scroll_y_);
|
|
|
+ if (y<=-static_cast<int>(scroll_size_)) {
|
|
|
+ // everything is now outside the screen at the top
|
|
|
+ done_ = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (auto const& item: scroll_items_) {
|
|
|
+ std::visit([&renderer, &y, window_width, font]<typename T>(T const& it) {
|
|
|
+ int h = 0;
|
|
|
+ if constexpr (std::is_same_v<T, char const*>) {
|
|
|
+ auto const surface = TTF_RenderUTF8_Solid(font, it, {255, 255, 255, SDL_ALPHA_OPAQUE});
|
|
|
+ auto const texture = SDL_CreateTextureFromSurface(renderer, surface);
|
|
|
+ SDL_FreeSurface(surface);
|
|
|
+
|
|
|
+ int w;
|
|
|
+ SDL_QueryTexture(texture, nullptr, nullptr, &w, &h);
|
|
|
+ SDL_Rect const rect{.x = (window_width-w)/2, .y = y, .w = w, .h = h};
|
|
|
+ SDL_RenderCopy(renderer, texture, nullptr, &rect);
|
|
|
+
|
|
|
+ SDL_DestroyTexture(texture);
|
|
|
+ }
|
|
|
+ else if constexpr (std::is_same_v<T, External>) {
|
|
|
+ int w, logo_h, text_h;
|
|
|
+
|
|
|
+ SDL_QueryTexture(it.texture_, nullptr, nullptr, &w, &logo_h);
|
|
|
+ SDL_Rect const logo_rect{.x = (window_width-w)/2, .y = y, .w = w, .h = logo_h};
|
|
|
+ SDL_RenderCopy(renderer, it.texture_, nullptr, &logo_rect);
|
|
|
+
|
|
|
+ auto const surface = TTF_RenderUTF8_Solid(font, it.text_, {255, 255, 255, SDL_ALPHA_OPAQUE});
|
|
|
+ auto const texture = SDL_CreateTextureFromSurface(renderer, surface);
|
|
|
+ SDL_FreeSurface(surface);
|
|
|
+
|
|
|
+ SDL_QueryTexture(texture, nullptr, nullptr, &w, &text_h);
|
|
|
+ SDL_Rect const text_rect{.x = (window_width-w)/2, .y = y+logo_h+10, .w = w, .h = text_h};
|
|
|
+ SDL_RenderCopy(renderer, texture, nullptr, &text_rect);
|
|
|
+
|
|
|
+ SDL_DestroyTexture(texture);
|
|
|
+
|
|
|
+ h = logo_h+10+text_h;
|
|
|
+ }
|
|
|
+ else if constexpr (std::is_same_v<T, SDL_Texture*>) {
|
|
|
+ int w;
|
|
|
+ SDL_QueryTexture(it, nullptr, nullptr, &w, &h);
|
|
|
+ SDL_Rect const rect{.x = (window_width-w)/2, .y = y, .w = w, .h = h};
|
|
|
+ SDL_RenderCopy(renderer, it, nullptr, &rect);
|
|
|
+ }
|
|
|
+
|
|
|
+ y += h+50;
|
|
|
+ }, item);
|
|
|
+ }
|
|
|
+
|
|
|
+ SDL_RenderPresent(renderer);
|
|
|
+}
|