#include "CreditsState.hxx" #include "GameStateManager.hxx" #include 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 ", 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 = -ITEM_PADDING; for (auto const& item: scroll_items_) { summed_size += std::visit([font](T const& it) { int w, h = 0; if constexpr (std::is_same_v) { TTF_SizeUTF8(font, it, &w, &h); } else if constexpr (std::is_same_v) { 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+INNER_ITEM_PADDING+text_h; } else if constexpr (std::is_same_v) { SDL_QueryTexture(it, nullptr, nullptr, &w, &h); } return h; }, item); summed_size += ITEM_PADDING; } scroll_size_ = static_cast(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(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(scroll_y_); if (y<=-static_cast(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](T const& it) { int h = 0; if constexpr (std::is_same_v) { 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) { 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+INNER_ITEM_PADDING, .w = w, .h = text_h}; SDL_RenderCopy(renderer, texture, nullptr, &text_rect); SDL_DestroyTexture(texture); h = logo_h+INNER_ITEM_PADDING+text_h; } else if constexpr (std::is_same_v) { 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+ITEM_PADDING; }, item); } SDL_RenderPresent(renderer); }