💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

203 lines
6.6 KiB

  1. /*
  2. * Copyright (C) 2023 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "game/states/splash-state.hpp"
  20. #include "game/game.hpp"
  21. #include "game/states/main-menu-state.hpp"
  22. #include <engine/animation/animation.hpp>
  23. #include <engine/animation/animator.hpp>
  24. #include <engine/animation/ease.hpp>
  25. #include <engine/animation/screen-transition.hpp>
  26. #include <engine/debug/log.hpp>
  27. #include <engine/math/vector.hpp>
  28. #include <engine/render/material-flags.hpp>
  29. #include <engine/resources/resource-manager.hpp>
  30. #include <engine/gl/pipeline.hpp>
  31. splash_state::splash_state(::game& ctx):
  32. game_state(ctx)
  33. {
  34. debug::log_trace("Entering splash state...");
  35. const math::fvec2 viewport_size = math::fvec2(ctx.window->get_viewport_size());
  36. const math::fvec2 viewport_center = viewport_size * 0.5f;
  37. // Load splash texture
  38. auto splash_texture = ctx.resource_manager->load<gl::texture_2d>("splash.tex");
  39. // Get splash texture dimensions
  40. const auto& splash_dimensions = splash_texture->get_image_view()->get_image()->get_dimensions();
  41. // Construct splash billboard material
  42. splash_billboard_material = std::make_shared<render::material>();
  43. splash_billboard_material->set_blend_mode(render::material_blend_mode::translucent);
  44. splash_billboard_material->set_shader_template(ctx.resource_manager->load<gl::shader_template>("ui-element-textured.glsl"));
  45. splash_billboard_material->set_variable("background", std::make_shared<render::matvar_texture_2d>(1, splash_texture));
  46. auto splash_tint = std::make_shared<render::matvar_fvec4>(1, math::fvec4{1, 1, 1, 0});
  47. splash_billboard_material->set_variable("tint", splash_tint);
  48. // Construct splash billboard
  49. splash_billboard.set_material(splash_billboard_material);
  50. splash_billboard.set_scale({static_cast<float>(splash_dimensions[0]) * 0.5f, static_cast<float>(splash_dimensions[1]) * 0.5f, 1.0f});
  51. splash_billboard.set_translation({std::round(viewport_center.x()), std::round(viewport_center.y()), 0.0f});
  52. // Add splash billboard to UI scene
  53. ctx.ui_scene->add_object(splash_billboard);
  54. // Load animation timing configuration
  55. const float splash_fade_in_duration = 0.5;
  56. const float splash_duration = 2.0;
  57. const float splash_fade_out_duration = 0.5;
  58. // Construct splash fade in animation
  59. splash_fade_in_animation.set_interpolator(ease<float>::out_cubic);
  60. animation_channel<float>* splash_fade_in_opacity_channel = splash_fade_in_animation.add_channel(0);
  61. splash_fade_in_opacity_channel->insert_keyframe({0.0f, 0.0f});
  62. splash_fade_in_opacity_channel->insert_keyframe({splash_fade_in_duration, 1.0f});
  63. splash_fade_in_opacity_channel->insert_keyframe({splash_fade_in_duration + splash_duration, 1.0f});
  64. // Build splash fade out animation
  65. splash_fade_out_animation.set_interpolator(ease<float>::out_cubic);
  66. animation_channel<float>* splash_fade_out_opacity_channel = splash_fade_out_animation.add_channel(0);
  67. splash_fade_out_opacity_channel->insert_keyframe({0.0f, 1.0f});
  68. splash_fade_out_opacity_channel->insert_keyframe({splash_fade_out_duration, 0.0f});
  69. // Setup animation frame callbacks
  70. auto set_splash_opacity = [splash_tint](int channel, const float& opacity)
  71. {
  72. splash_tint->set(math::fvec4{1, 1, 1, opacity});
  73. };
  74. splash_fade_in_animation.set_frame_callback(set_splash_opacity);
  75. splash_fade_out_animation.set_frame_callback(set_splash_opacity);
  76. // Trigger splash fade out animation when splash fade in animation ends
  77. splash_fade_in_animation.set_end_callback
  78. (
  79. [this]()
  80. {
  81. this->splash_fade_out_animation.play();
  82. }
  83. );
  84. // Trigger a state change when the splash fade out animation ends
  85. splash_fade_out_animation.set_end_callback
  86. (
  87. [&ctx]()
  88. {
  89. // Queue change to main menu state
  90. ctx.function_queue.push
  91. (
  92. [&ctx]()
  93. {
  94. ctx.state_machine.pop();
  95. ctx.state_machine.emplace(std::make_unique<main_menu_state>(ctx, true));
  96. }
  97. );
  98. }
  99. );
  100. // Add splash fade animations to animator
  101. ctx.animator->add_animation(&splash_fade_in_animation);
  102. ctx.animator->add_animation(&splash_fade_out_animation);
  103. // Start splash fade in animation
  104. splash_fade_in_animation.play();
  105. // Setup window resized callback
  106. window_resized_subscription = ctx.window->get_resized_channel().subscribe
  107. (
  108. [&](const auto& event)
  109. {
  110. const math::fvec2 viewport_size = math::fvec2(event.window->get_viewport_size());
  111. const math::fvec2 viewport_center = viewport_size * 0.5f;
  112. splash_billboard.set_translation({std::round(viewport_center.x()), std::round(viewport_center.y()), 0.0f});
  113. }
  114. );
  115. // Construct splash skip function
  116. auto skip = [&](const auto& event)
  117. {
  118. ctx.function_queue.emplace
  119. (
  120. [&]()
  121. {
  122. // Black out screen
  123. ctx.window->get_graphics_pipeline().clear_attachments(gl::color_clear_bit, {{0.0f, 0.0f, 0.0f, 0.0f}});
  124. ctx.window->swap_buffers();
  125. // Change to main menu state
  126. ctx.state_machine.pop();
  127. ctx.state_machine.emplace(std::make_unique<main_menu_state>(ctx, true));
  128. }
  129. );
  130. };
  131. // Set up splash skippers
  132. input_mapped_subscriptions.emplace_back
  133. (
  134. ctx.input_mapper.get_gamepad_button_mapped_channel().subscribe
  135. (
  136. skip
  137. )
  138. );
  139. input_mapped_subscriptions.emplace_back
  140. (
  141. ctx.input_mapper.get_key_mapped_channel().subscribe
  142. (
  143. skip
  144. )
  145. );
  146. input_mapped_subscriptions.emplace_back
  147. (
  148. ctx.input_mapper.get_mouse_button_mapped_channel().subscribe
  149. (
  150. skip
  151. )
  152. );
  153. // Enable splash skippers next frame
  154. ctx.function_queue.push
  155. (
  156. [&]()
  157. {
  158. ctx.input_mapper.connect(ctx.input_manager->get_event_dispatcher());
  159. }
  160. );
  161. debug::log_trace("Entered splash state");
  162. }
  163. splash_state::~splash_state()
  164. {
  165. debug::log_trace("Exiting splash state...");
  166. // Disable splash skippers
  167. ctx.input_mapper.disconnect();
  168. input_mapped_subscriptions.clear();
  169. // Remove splash fade animations from animator
  170. ctx.animator->remove_animation(&splash_fade_in_animation);
  171. ctx.animator->remove_animation(&splash_fade_out_animation);
  172. // Remove splash billboard from UI scene
  173. ctx.ui_scene->remove_object(splash_billboard);
  174. debug::log_trace("Exited splash state");
  175. }