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

258 lines
8.9 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/state/sound-menu.hpp"
  20. #include "game/state/options-menu.hpp"
  21. #include "application.hpp"
  22. #include "scene/text.hpp"
  23. #include "debug/log.hpp"
  24. #include "game/menu.hpp"
  25. #include "game/strings.hpp"
  26. #include "utility/hash/fnv1a.hpp"
  27. using namespace hash::literals;
  28. namespace game {
  29. namespace state {
  30. sound_menu::sound_menu(game::context& ctx):
  31. game::state::base(ctx)
  32. {
  33. debug::log::trace("Entering sound menu state...");
  34. // Construct menu item texts
  35. scene::text* master_volume_name_text = new scene::text();
  36. scene::text* master_volume_value_text = new scene::text();
  37. scene::text* ambience_volume_name_text = new scene::text();
  38. scene::text* ambience_volume_value_text = new scene::text();
  39. scene::text* effects_volume_name_text = new scene::text();
  40. scene::text* effects_volume_value_text = new scene::text();
  41. scene::text* mono_audio_name_text = new scene::text();
  42. scene::text* mono_audio_value_text = new scene::text();
  43. scene::text* captions_name_text = new scene::text();
  44. scene::text* captions_value_text = new scene::text();
  45. scene::text* captions_size_name_text = new scene::text();
  46. scene::text* captions_size_value_text = new scene::text();
  47. scene::text* back_text = new scene::text();
  48. // Build list of menu item texts
  49. ctx.menu_item_texts.push_back({master_volume_name_text, master_volume_value_text});
  50. ctx.menu_item_texts.push_back({ambience_volume_name_text, ambience_volume_value_text});
  51. ctx.menu_item_texts.push_back({effects_volume_name_text, effects_volume_value_text});
  52. ctx.menu_item_texts.push_back({mono_audio_name_text, mono_audio_value_text});
  53. ctx.menu_item_texts.push_back({captions_name_text, captions_value_text});
  54. ctx.menu_item_texts.push_back({captions_size_name_text, captions_size_value_text});
  55. ctx.menu_item_texts.push_back({back_text, nullptr});
  56. // Set content of menu item texts
  57. master_volume_name_text->set_content(get_string(ctx, "sound_menu_master_volume"_fnv1a32));
  58. ambience_volume_name_text->set_content(get_string(ctx, "sound_menu_ambience_volume"_fnv1a32));
  59. effects_volume_name_text->set_content(get_string(ctx, "sound_menu_effects_volume"_fnv1a32));
  60. mono_audio_name_text->set_content(get_string(ctx, "sound_menu_mono_audio"_fnv1a32));
  61. captions_name_text->set_content(get_string(ctx, "sound_menu_captions"_fnv1a32));
  62. captions_size_name_text->set_content(get_string(ctx, "sound_menu_captions_size"_fnv1a32));
  63. back_text->set_content(get_string(ctx, "back"_fnv1a32));
  64. update_value_text_content();
  65. // Init menu item index
  66. game::menu::init_menu_item_index(ctx, "sound");
  67. game::menu::update_text_color(ctx);
  68. game::menu::update_text_font(ctx);
  69. game::menu::align_text(ctx);
  70. game::menu::update_text_tweens(ctx);
  71. game::menu::add_text_to_ui(ctx);
  72. game::menu::setup_animations(ctx);
  73. // Construct menu item callbacks
  74. auto increase_volume_callback = [this, &ctx](float* volume)
  75. {
  76. // Increase volume
  77. if (ctx.menu_modifier_control.is_active())
  78. *volume += 0.01f;
  79. else
  80. *volume += 0.1f;
  81. // Limit volume
  82. if (*volume > 1.0f)
  83. *volume = 1.0f;
  84. this->update_value_text_content();
  85. game::menu::align_text(ctx);
  86. game::menu::update_text_tweens(ctx);
  87. };
  88. auto decrease_volume_callback = [this, &ctx](float* volume)
  89. {
  90. // Decrease volume
  91. if (ctx.menu_modifier_control.is_active())
  92. *volume -= 0.01f;
  93. else
  94. *volume -= 0.1f;
  95. // Limit volume
  96. if (*volume < 0.0f)
  97. *volume = 0.0f;
  98. this->update_value_text_content();
  99. game::menu::align_text(ctx);
  100. game::menu::update_text_tweens(ctx);
  101. };
  102. auto toggle_mono_audio_callback = [this, &ctx]()
  103. {
  104. ctx.mono_audio = !ctx.mono_audio;
  105. this->update_value_text_content();
  106. game::menu::align_text(ctx);
  107. game::menu::update_text_tweens(ctx);
  108. };
  109. auto toggle_captions_callback = [this, &ctx]()
  110. {
  111. ctx.captions = !ctx.captions;
  112. this->update_value_text_content();
  113. game::menu::align_text(ctx);
  114. game::menu::update_text_tweens(ctx);
  115. };
  116. auto increase_captions_size_callback = [this, &ctx]()
  117. {
  118. // Increase size
  119. if (ctx.menu_modifier_control.is_active())
  120. ctx.captions_size += 0.01f;
  121. else
  122. ctx.captions_size += 0.1f;
  123. // Limit size
  124. if (ctx.captions_size > 2.0f)
  125. ctx.captions_size = 2.0f;
  126. this->update_value_text_content();
  127. game::menu::align_text(ctx);
  128. game::menu::update_text_tweens(ctx);
  129. };
  130. auto decrease_captions_size_callback = [this, &ctx]()
  131. {
  132. // Decrease size
  133. if (ctx.menu_modifier_control.is_active())
  134. ctx.captions_size -= 0.01f;
  135. else
  136. ctx.captions_size -= 0.1f;
  137. // Limit size
  138. if (ctx.captions_size < 0.1f)
  139. ctx.captions_size = 0.1f;
  140. this->update_value_text_content();
  141. game::menu::align_text(ctx);
  142. game::menu::update_text_tweens(ctx);
  143. };
  144. auto select_back_callback = [&ctx]()
  145. {
  146. // Disable controls
  147. game::menu::clear_controls(ctx);
  148. game::menu::fade_out
  149. (
  150. ctx,
  151. [&ctx]()
  152. {
  153. // Queue change to options menu state
  154. ctx.function_queue.push
  155. (
  156. [&ctx]()
  157. {
  158. ctx.state_machine.pop();
  159. ctx.state_machine.emplace(new game::state::options_menu(ctx));
  160. }
  161. );
  162. }
  163. );
  164. };
  165. // Build list of menu select callbacks
  166. ctx.menu_select_callbacks.push_back(std::bind(increase_volume_callback, &ctx.master_volume));
  167. ctx.menu_select_callbacks.push_back(std::bind(increase_volume_callback, &ctx.ambience_volume));
  168. ctx.menu_select_callbacks.push_back(std::bind(increase_volume_callback, &ctx.effects_volume));
  169. ctx.menu_select_callbacks.push_back(toggle_mono_audio_callback);
  170. ctx.menu_select_callbacks.push_back(toggle_captions_callback);
  171. ctx.menu_select_callbacks.push_back(increase_captions_size_callback);
  172. ctx.menu_select_callbacks.push_back(select_back_callback);
  173. // Build list of menu left callbacks
  174. ctx.menu_left_callbacks.push_back(std::bind(decrease_volume_callback, &ctx.master_volume));
  175. ctx.menu_left_callbacks.push_back(std::bind(decrease_volume_callback, &ctx.ambience_volume));
  176. ctx.menu_left_callbacks.push_back(std::bind(decrease_volume_callback, &ctx.effects_volume));
  177. ctx.menu_left_callbacks.push_back(toggle_mono_audio_callback);
  178. ctx.menu_left_callbacks.push_back(toggle_captions_callback);
  179. ctx.menu_left_callbacks.push_back(decrease_captions_size_callback);
  180. ctx.menu_left_callbacks.push_back(nullptr);
  181. // Build list of menu right callbacks
  182. ctx.menu_right_callbacks.push_back(std::bind(increase_volume_callback, &ctx.master_volume));
  183. ctx.menu_right_callbacks.push_back(std::bind(increase_volume_callback, &ctx.ambience_volume));
  184. ctx.menu_right_callbacks.push_back(std::bind(increase_volume_callback, &ctx.effects_volume));
  185. ctx.menu_right_callbacks.push_back(toggle_mono_audio_callback);
  186. ctx.menu_right_callbacks.push_back(toggle_captions_callback);
  187. ctx.menu_right_callbacks.push_back(increase_captions_size_callback);
  188. ctx.menu_right_callbacks.push_back(nullptr);
  189. // Set menu back callback
  190. ctx.menu_back_callback = select_back_callback;
  191. // Queue menu control setup
  192. ctx.function_queue.push(std::bind(game::menu::setup_controls, std::ref(ctx)));
  193. // Fade in menu
  194. game::menu::fade_in(ctx, nullptr);
  195. debug::log::trace("Entered sound menu state");
  196. }
  197. sound_menu::~sound_menu()
  198. {
  199. debug::log::trace("Exiting sound menu state...");
  200. // Destruct menu
  201. game::menu::clear_controls(ctx);
  202. game::menu::clear_callbacks(ctx);
  203. game::menu::delete_animations(ctx);
  204. game::menu::remove_text_from_ui(ctx);
  205. game::menu::delete_text(ctx);
  206. debug::log::trace("Exited sound menu state");
  207. }
  208. void sound_menu::update_value_text_content()
  209. {
  210. const std::string string_on = get_string(ctx, "on"_fnv1a32);
  211. const std::string string_off = get_string(ctx, "off"_fnv1a32);
  212. std::get<1>(ctx.menu_item_texts[0])->set_content(std::to_string(static_cast<int>(std::round(ctx.master_volume * 100.0f))) + "%");
  213. std::get<1>(ctx.menu_item_texts[1])->set_content(std::to_string(static_cast<int>(std::round(ctx.ambience_volume * 100.0f))) + "%");
  214. std::get<1>(ctx.menu_item_texts[2])->set_content(std::to_string(static_cast<int>(std::round(ctx.effects_volume * 100.0f))) + "%");
  215. std::get<1>(ctx.menu_item_texts[3])->set_content((ctx.mono_audio) ? string_on : string_off);
  216. std::get<1>(ctx.menu_item_texts[4])->set_content((ctx.captions) ? string_on : string_off);
  217. std::get<1>(ctx.menu_item_texts[5])->set_content(std::to_string(static_cast<int>(std::round(ctx.captions_size * 100.0f))) + "%");
  218. }
  219. } // namespace state
  220. } // namespace game