CreditsState.cxx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #include "CreditsState.hxx"
  2. #include "GameStateManager.hxx"
  3. #include <type_traits>
  4. CreditsState::CreditsState()
  5. :font_{"kenney_pixel.ttf"}, jetbrains_ai_logo_{"jetbrains-ai-logo.png"}, kenney_logo_{"kenney-logo.png"},
  6. sdl_logo_{"SDL_logo.png"}, boost_logo_{"Boost-logo.png"}
  7. {
  8. }
  9. void CreditsState::on_enter(GameStateManager& gsm)
  10. {
  11. TTF_Font* const font = font_;
  12. scroll_y_ = 0.0;
  13. done_ = false;
  14. scroll_items_ = {
  15. "Copyright © 2024, Felix Bytow <drako@drako.guru>",
  16. External{jetbrains_ai_logo_, "with some help from JetBrains AI Assistant"},
  17. External{kenney_logo_, "Font & UI Pack from kenney.nl"},
  18. sdl_logo_,
  19. boost_logo_,
  20. };
  21. int summed_size = -ITEM_PADDING;
  22. for (auto const& item: scroll_items_) {
  23. summed_size += std::visit([font]<typename T>(T const& it) {
  24. int w, h = 0;
  25. if constexpr (std::is_same_v<T, char const*>) {
  26. TTF_SizeUTF8(font, it, &w, &h);
  27. }
  28. else if constexpr (std::is_same_v<T, External>) {
  29. int logo_h, text_h;
  30. TTF_SizeUTF8(font, it.text_, &w, &text_h);
  31. SDL_QueryTexture(it.texture_, nullptr, nullptr, &w, &logo_h);
  32. h = logo_h+INNER_ITEM_PADDING+text_h;
  33. }
  34. else if constexpr (std::is_same_v<T, SDL_Texture*>) {
  35. SDL_QueryTexture(it, nullptr, nullptr, &w, &h);
  36. }
  37. return h;
  38. }, item);
  39. summed_size += ITEM_PADDING;
  40. }
  41. scroll_size_ = static_cast<double>(summed_size);
  42. }
  43. void CreditsState::on_event(GameStateManager& gsm, SDL_Event const& event)
  44. {
  45. if (event.type==SDL_KEYUP) {
  46. switch (event.key.keysym.scancode) {
  47. default:
  48. break;
  49. case SDL_SCANCODE_ESCAPE:
  50. [[fallthrough]];
  51. case SDL_SCANCODE_RETURN:
  52. [[fallthrough]];
  53. case SDL_SCANCODE_SPACE:
  54. gsm.pop_state();
  55. break;
  56. }
  57. }
  58. else if (event.type==SDL_CONTROLLERBUTTONUP) {
  59. switch (event.cbutton.which) {
  60. default:
  61. break;
  62. case SDL_CONTROLLER_BUTTON_A:
  63. [[fallthrough]];
  64. case SDL_CONTROLLER_BUTTON_B:
  65. [[fallthrough]];
  66. case SDL_CONTROLLER_BUTTON_START:
  67. gsm.pop_state();
  68. break;
  69. }
  70. }
  71. }
  72. void CreditsState::update(GameStateManager& gsm, std::chrono::milliseconds const delta_time)
  73. {
  74. if (done_) {
  75. gsm.pop_state();
  76. }
  77. scroll_y_ += 0.05*static_cast<double>(delta_time.count());
  78. }
  79. void CreditsState::render(SDLRenderer& renderer)
  80. {
  81. TTF_Font* const font = font_;
  82. int window_width = 0, window_height = 0;
  83. SDL_GetRendererOutputSize(renderer, &window_width, &window_height);
  84. int y = window_height-static_cast<int>(scroll_y_);
  85. if (y<=-static_cast<int>(scroll_size_)) {
  86. // everything is now outside the screen at the top
  87. done_ = true;
  88. }
  89. for (auto const& item: scroll_items_) {
  90. std::visit([&renderer, &y, window_width, font]<typename T>(T const& it) {
  91. int h = 0;
  92. if constexpr (std::is_same_v<T, char const*>) {
  93. auto const surface = TTF_RenderUTF8_Solid(font, it, {255, 255, 255, SDL_ALPHA_OPAQUE});
  94. auto const texture = SDL_CreateTextureFromSurface(renderer, surface);
  95. SDL_FreeSurface(surface);
  96. int w;
  97. SDL_QueryTexture(texture, nullptr, nullptr, &w, &h);
  98. SDL_Rect const rect{.x = (window_width-w)/2, .y = y, .w = w, .h = h};
  99. SDL_RenderCopy(renderer, texture, nullptr, &rect);
  100. SDL_DestroyTexture(texture);
  101. }
  102. else if constexpr (std::is_same_v<T, External>) {
  103. int w, logo_h, text_h;
  104. SDL_QueryTexture(it.texture_, nullptr, nullptr, &w, &logo_h);
  105. SDL_Rect const logo_rect{.x = (window_width-w)/2, .y = y, .w = w, .h = logo_h};
  106. SDL_RenderCopy(renderer, it.texture_, nullptr, &logo_rect);
  107. auto const surface = TTF_RenderUTF8_Solid(font, it.text_, {255, 255, 255, SDL_ALPHA_OPAQUE});
  108. auto const texture = SDL_CreateTextureFromSurface(renderer, surface);
  109. SDL_FreeSurface(surface);
  110. SDL_QueryTexture(texture, nullptr, nullptr, &w, &text_h);
  111. SDL_Rect const text_rect{.x = (window_width-w)/2, .y = y+logo_h+INNER_ITEM_PADDING, .w = w, .h = text_h};
  112. SDL_RenderCopy(renderer, texture, nullptr, &text_rect);
  113. SDL_DestroyTexture(texture);
  114. h = logo_h+INNER_ITEM_PADDING+text_h;
  115. }
  116. else if constexpr (std::is_same_v<T, SDL_Texture*>) {
  117. int w;
  118. SDL_QueryTexture(it, nullptr, nullptr, &w, &h);
  119. SDL_Rect const rect{.x = (window_width-w)/2, .y = y, .w = w, .h = h};
  120. SDL_RenderCopy(renderer, it, nullptr, &rect);
  121. }
  122. y += h+ITEM_PADDING;
  123. }, item);
  124. }
  125. }