💿🐜 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.

280 lines
8.0 KiB

  1. /*
  2. * Copyright (C) 2021 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/state/main-menu.hpp"
  20. #include "game/state/options-menu.hpp"
  21. #include "game/state/extras-menu.hpp"
  22. #include "game/state/forage.hpp"
  23. #include "game/state/nuptial-flight.hpp"
  24. #include "game/menu.hpp"
  25. #include "render/passes/clear-pass.hpp"
  26. #include "resources/resource-manager.hpp"
  27. #include "render/model.hpp"
  28. #include "animation/animation.hpp"
  29. #include "animation/animator.hpp"
  30. #include "animation/screen-transition.hpp"
  31. #include "animation/ease.hpp"
  32. #include "application.hpp"
  33. #include <limits>
  34. namespace game {
  35. namespace state {
  36. main_menu::main_menu(game::context& ctx, bool fade_in):
  37. game::state::base(ctx)
  38. {
  39. ctx.logger->push_task("Entering main menu state");
  40. ctx.ui_clear_pass->set_cleared_buffers(true, true, false);
  41. // Construct title text
  42. title_text.set_material(&ctx.title_font_material);
  43. title_text.set_color({1.0f, 1.0f, 1.0f, (fade_in) ? 1.0f : 0.0f});
  44. title_text.set_font(&ctx.title_font);
  45. title_text.set_content((*ctx.strings)["title_antkeeper"]);
  46. // Align title text
  47. const auto& title_aabb = static_cast<const geom::aabb<float>&>(title_text.get_local_bounds());
  48. float title_w = title_aabb.max_point.x - title_aabb.min_point.x;
  49. float title_h = title_aabb.max_point.y - title_aabb.min_point.y;
  50. title_text.set_translation({std::round(-title_w * 0.5f), std::round(-title_h * 0.5f + (ctx.app->get_viewport_dimensions().y / 3.0f) / 2.0f), 0.0f});
  51. title_text.update_tweens();
  52. // Add title text to UI
  53. ctx.ui_scene->add_object(&title_text);
  54. // Construct title fade animation
  55. title_fade_animation.set_interpolator(ease<float>::out_cubic);
  56. animation_channel<float>* opacity_channel = title_fade_animation.add_channel(0);
  57. title_fade_animation.set_frame_callback
  58. (
  59. [this, &ctx](int channel, const float& opacity)
  60. {
  61. float4 color = this->title_text.get_color();
  62. color[3] = opacity;
  63. this->title_text.set_color(color);
  64. }
  65. );
  66. ctx.animator->add_animation(&title_fade_animation);
  67. // Construct menu item texts
  68. scene::text* start_text = new scene::text();
  69. scene::text* options_text = new scene::text();
  70. scene::text* extras_text = new scene::text();
  71. scene::text* quit_text = new scene::text();
  72. // Build list of menu item texts
  73. ctx.menu_item_texts.push_back({start_text, nullptr});
  74. ctx.menu_item_texts.push_back({options_text, nullptr});
  75. ctx.menu_item_texts.push_back({extras_text, nullptr});
  76. ctx.menu_item_texts.push_back({quit_text, nullptr});
  77. // Set content of menu item texts
  78. start_text->set_content((*ctx.strings)["main_menu_start"]);
  79. options_text->set_content((*ctx.strings)["main_menu_options"]);
  80. extras_text->set_content((*ctx.strings)["main_menu_extras"]);
  81. quit_text->set_content((*ctx.strings)["main_menu_quit"]);
  82. // Init menu item index
  83. game::menu::init_menu_item_index(ctx, "main");
  84. game::menu::update_text_color(ctx);
  85. game::menu::update_text_font(ctx);
  86. game::menu::align_text(ctx, true, false, (-ctx.app->get_viewport_dimensions().y / 3.0f) / 2.0f);
  87. game::menu::update_text_tweens(ctx);
  88. game::menu::add_text_to_ui(ctx);
  89. game::menu::setup_animations(ctx);
  90. auto select_start_callback = [this, &ctx]()
  91. {
  92. // Disable controls and menu callbacks
  93. game::menu::clear_controls(ctx);
  94. game::menu::clear_callbacks(ctx);
  95. // Create change state function
  96. auto change_state_nuptial_flight = [&ctx]()
  97. {
  98. // Queue change to nuptial state
  99. ctx.function_queue.push
  100. (
  101. [&ctx]()
  102. {
  103. ctx.state_machine.pop();
  104. ctx.state_machine.emplace(new game::state::nuptial_flight(ctx));
  105. }
  106. );
  107. };
  108. // Fade out title
  109. this->fade_out_title();
  110. // Fade out menu
  111. game::menu::fade_out(ctx, nullptr);
  112. // Start fade out to white
  113. ctx.fade_transition_color->set_value({1, 1, 1});
  114. ctx.fade_transition->transition(1.0f, false, ease<float>::out_cubic, false, change_state_nuptial_flight);
  115. };
  116. auto select_options_callback = [this, &ctx]()
  117. {
  118. game::menu::clear_controls(ctx);
  119. // Fade out title
  120. this->fade_out_title();
  121. // Fade out menu
  122. game::menu::fade_out
  123. (
  124. ctx,
  125. [&ctx]()
  126. {
  127. // Queue change to options menu state
  128. ctx.function_queue.push
  129. (
  130. [&ctx]()
  131. {
  132. ctx.state_machine.pop();
  133. ctx.state_machine.emplace(new game::state::options_menu(ctx));
  134. }
  135. );
  136. }
  137. );
  138. };
  139. auto select_extras_callback = [this, &ctx]()
  140. {
  141. // Disable controls
  142. game::menu::clear_controls(ctx);
  143. // Fade out title
  144. this->fade_out_title();
  145. // Fade out menu
  146. game::menu::fade_out
  147. (
  148. ctx,
  149. [&ctx]()
  150. {
  151. // Queue change to extras menu state
  152. ctx.function_queue.push
  153. (
  154. [&ctx]()
  155. {
  156. ctx.state_machine.pop();
  157. ctx.state_machine.emplace(new game::state::extras_menu(ctx));
  158. }
  159. );
  160. }
  161. );
  162. };
  163. auto select_quit_callback = [this, &ctx]()
  164. {
  165. // Disable controls
  166. game::menu::clear_controls(ctx);
  167. // Fade out title
  168. this->fade_out_title();
  169. // Fade out menu
  170. game::menu::fade_out(ctx, nullptr);
  171. // Fade to black then quit
  172. ctx.fade_transition->transition(0.5f, false, ease<float>::out_cubic, false, std::bind(&application::close, ctx.app));
  173. };
  174. // Build list of menu select callbacks
  175. ctx.menu_select_callbacks.push_back(select_start_callback);
  176. ctx.menu_select_callbacks.push_back(select_options_callback);
  177. ctx.menu_select_callbacks.push_back(select_extras_callback);
  178. ctx.menu_select_callbacks.push_back(select_quit_callback);
  179. // Build list of menu left callbacks
  180. ctx.menu_left_callbacks.push_back(nullptr);
  181. ctx.menu_left_callbacks.push_back(nullptr);
  182. ctx.menu_left_callbacks.push_back(nullptr);
  183. ctx.menu_left_callbacks.push_back(nullptr);
  184. // Build list of menu right callbacks
  185. ctx.menu_right_callbacks.push_back(nullptr);
  186. ctx.menu_right_callbacks.push_back(nullptr);
  187. ctx.menu_right_callbacks.push_back(nullptr);
  188. ctx.menu_right_callbacks.push_back(nullptr);
  189. // Set menu back callback
  190. ctx.menu_back_callback = select_quit_callback;
  191. // Queue menu control setup
  192. ctx.function_queue.push(std::bind(game::menu::setup_controls, std::ref(ctx)));
  193. if (fade_in)
  194. {
  195. // Fade in from black
  196. ctx.fade_transition->transition(0.5f, true, ease<float>::out_cubic);
  197. }
  198. else
  199. {
  200. // Fade in text
  201. fade_in_title();
  202. game::menu::fade_in(ctx, nullptr);
  203. }
  204. ctx.logger->pop_task(EXIT_SUCCESS);
  205. }
  206. main_menu::~main_menu()
  207. {
  208. ctx.logger->push_task("Exiting main menu state");
  209. // Destruct menu
  210. game::menu::clear_controls(ctx);
  211. game::menu::clear_callbacks(ctx);
  212. game::menu::delete_animations(ctx);
  213. game::menu::remove_text_from_ui(ctx);
  214. game::menu::delete_text(ctx);
  215. // Destruct title animation
  216. ctx.animator->remove_animation(&title_fade_animation);
  217. // Destruct title text
  218. ctx.ui_scene->remove_object(&title_text);
  219. ctx.logger->pop_task(EXIT_SUCCESS);
  220. }
  221. void main_menu::fade_in_title()
  222. {
  223. animation_channel<float>* opacity_channel = title_fade_animation.get_channel(0);
  224. opacity_channel->remove_keyframes();
  225. opacity_channel->insert_keyframe({0.0, 0.0f});
  226. opacity_channel->insert_keyframe({game::menu::fade_in_duration, 1.0f});
  227. title_fade_animation.stop();
  228. title_fade_animation.play();
  229. }
  230. void main_menu::fade_out_title()
  231. {
  232. animation_channel<float>* opacity_channel = title_fade_animation.get_channel(0);
  233. opacity_channel->remove_keyframes();
  234. opacity_channel->insert_keyframe({0.0, 1.0f});
  235. opacity_channel->insert_keyframe({game::menu::fade_out_duration, 0.0f});
  236. title_fade_animation.stop();
  237. title_fade_animation.play();
  238. }
  239. } // namespace state
  240. } // namespace game