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

327 lines
10 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/states/graphics-menu.hpp"
  20. #include "game/states/options-menu.hpp"
  21. #include "application.hpp"
  22. #include "scene/text.hpp"
  23. #include "render/passes/clear-pass.hpp"
  24. #include "debug/logger.hpp"
  25. #include "game/fonts.hpp"
  26. #include "game/menu.hpp"
  27. #include "animation/timeline.hpp"
  28. namespace game {
  29. namespace state {
  30. namespace graphics_menu {
  31. static void update_value_text_content(game::context* ctx)
  32. {
  33. bool fullscreen = ctx->app->is_fullscreen();
  34. float resolution = ctx->render_resolution_scale;
  35. bool v_sync = ctx->app->get_v_sync();
  36. float font_size = ctx->font_size;
  37. bool dyslexia_font = ctx->dyslexia_font;
  38. const std::string string_on = (*ctx->strings)["on"];
  39. const std::string string_off = (*ctx->strings)["off"];
  40. std::get<1>(ctx->menu_item_texts[0])->set_content((fullscreen) ? string_on : string_off);
  41. std::get<1>(ctx->menu_item_texts[1])->set_content(std::to_string(static_cast<int>(std::round(resolution * 100.0f))) + "%");
  42. std::get<1>(ctx->menu_item_texts[2])->set_content((v_sync) ? string_on : string_off);
  43. std::get<1>(ctx->menu_item_texts[3])->set_content(std::to_string(static_cast<int>(std::round(font_size * 100.0f))) + "%");
  44. std::get<1>(ctx->menu_item_texts[4])->set_content((dyslexia_font) ? string_on : string_off);
  45. }
  46. void enter(game::context* ctx)
  47. {
  48. ctx->ui_clear_pass->set_cleared_buffers(true, true, false);
  49. // Construct menu item texts
  50. scene::text* fullscreen_name_text = new scene::text();
  51. scene::text* fullscreen_value_text = new scene::text();
  52. scene::text* resolution_name_text = new scene::text();
  53. scene::text* resolution_value_text = new scene::text();
  54. scene::text* v_sync_name_text = new scene::text();
  55. scene::text* v_sync_value_text = new scene::text();
  56. scene::text* font_size_name_text = new scene::text();
  57. scene::text* font_size_value_text = new scene::text();
  58. scene::text* dyslexia_font_name_text = new scene::text();
  59. scene::text* dyslexia_font_value_text = new scene::text();
  60. scene::text* back_text = new scene::text();
  61. // Build list of menu item texts
  62. ctx->menu_item_texts.push_back({fullscreen_name_text, fullscreen_value_text});
  63. ctx->menu_item_texts.push_back({resolution_name_text, resolution_value_text});
  64. ctx->menu_item_texts.push_back({v_sync_name_text, v_sync_value_text});
  65. ctx->menu_item_texts.push_back({font_size_name_text, font_size_value_text});
  66. ctx->menu_item_texts.push_back({dyslexia_font_name_text, dyslexia_font_value_text});
  67. ctx->menu_item_texts.push_back({back_text, nullptr});
  68. // Set content of menu item texts
  69. fullscreen_name_text->set_content((*ctx->strings)["graphics_menu_fullscreen"]);
  70. resolution_name_text->set_content((*ctx->strings)["graphics_menu_resolution"]);
  71. v_sync_name_text->set_content((*ctx->strings)["graphics_menu_v_sync"]);
  72. font_size_name_text->set_content((*ctx->strings)["graphics_menu_font_size"]);
  73. dyslexia_font_name_text->set_content((*ctx->strings)["graphics_menu_dyslexia_font"]);
  74. back_text->set_content((*ctx->strings)["back"]);
  75. update_value_text_content(ctx);
  76. // Init menu item index
  77. game::menu::init_menu_item_index(ctx, "graphics");
  78. game::menu::update_text_color(ctx);
  79. game::menu::update_text_font(ctx);
  80. game::menu::align_text(ctx);
  81. game::menu::update_text_tweens(ctx);
  82. game::menu::add_text_to_ui(ctx);
  83. // Construct menu item callbacks
  84. auto toggle_fullscreen_callback = [ctx]()
  85. {
  86. bool fullscreen = !ctx->app->is_fullscreen();
  87. ctx->app->set_fullscreen(fullscreen);
  88. if (!fullscreen)
  89. {
  90. int2 resolution;
  91. resolution.x = (*ctx->config)["windowed_resolution"][0].get<int>();
  92. resolution.y = (*ctx->config)["windowed_resolution"][1].get<int>();
  93. ctx->app->resize_window(resolution.x, resolution.y);
  94. }
  95. update_value_text_content(ctx);
  96. game::menu::align_text(ctx);
  97. game::menu::update_text_tweens(ctx);
  98. // Save display mode config
  99. (*ctx->config)["fullscreen"] = fullscreen;
  100. };
  101. auto increase_resolution_callback = [ctx]()
  102. {
  103. // Increase resolution
  104. if (ctx->controls["menu_modifier"]->is_active())
  105. ctx->render_resolution_scale += 0.01f;
  106. else
  107. ctx->render_resolution_scale += 0.1f;
  108. // Limit resolution
  109. if (ctx->render_resolution_scale > 2.0f)
  110. ctx->render_resolution_scale = 2.0f;
  111. update_value_text_content(ctx);
  112. game::menu::align_text(ctx);
  113. game::menu::update_text_tweens(ctx);
  114. // Update config
  115. (*ctx->config)["render_resolution"] = ctx->render_resolution_scale;
  116. };
  117. auto decrease_resolution_callback = [ctx]()
  118. {
  119. // Increase resolution
  120. if (ctx->controls["menu_modifier"]->is_active())
  121. ctx->render_resolution_scale -= 0.01f;
  122. else
  123. ctx->render_resolution_scale -= 0.1f;
  124. // Limit resolution
  125. if (ctx->render_resolution_scale < 0.1f)
  126. ctx->render_resolution_scale = 0.1f;
  127. update_value_text_content(ctx);
  128. game::menu::align_text(ctx);
  129. game::menu::update_text_tweens(ctx);
  130. // Update config
  131. (*ctx->config)["render_resolution"] = ctx->render_resolution_scale;
  132. };
  133. auto toggle_v_sync_callback = [ctx]()
  134. {
  135. bool v_sync = !ctx->app->get_v_sync();
  136. ctx->app->set_v_sync(v_sync);
  137. update_value_text_content(ctx);
  138. game::menu::align_text(ctx);
  139. game::menu::update_text_tweens(ctx);
  140. // Save v-sync config
  141. (*ctx->config)["v_sync"] = v_sync;
  142. };
  143. auto increase_font_size_callback = [ctx]()
  144. {
  145. // Increase font size
  146. if (ctx->controls["menu_modifier"]->is_active())
  147. ctx->font_size += 0.01f;
  148. else
  149. ctx->font_size += 0.1f;
  150. // Limit font size
  151. if (ctx->font_size > 2.0f)
  152. ctx->font_size = 2.0f;
  153. // Update value text
  154. update_value_text_content(ctx);
  155. // Update config
  156. (*ctx->config)["font_size"] = ctx->font_size;
  157. // Reload fonts
  158. ctx->logger->push_task("Reloading fonts");
  159. try
  160. {
  161. game::load_fonts(ctx);
  162. }
  163. catch (...)
  164. {
  165. ctx->logger->pop_task(EXIT_FAILURE);
  166. }
  167. ctx->logger->pop_task(EXIT_SUCCESS);
  168. // Refresh and realign text
  169. game::menu::refresh_text(ctx);
  170. game::menu::align_text(ctx);
  171. game::menu::update_text_tweens(ctx);
  172. };
  173. auto decrease_font_size_callback = [ctx]()
  174. {
  175. // Decrease font size
  176. if (ctx->controls["menu_modifier"]->is_active())
  177. ctx->font_size -= 0.01f;
  178. else
  179. ctx->font_size -= 0.1f;
  180. // Limit font size
  181. if (ctx->font_size < 0.1f)
  182. ctx->font_size = 0.1f;
  183. // Update value text
  184. update_value_text_content(ctx);
  185. // Update config
  186. (*ctx->config)["font_size"] = ctx->font_size;
  187. // Reload fonts
  188. ctx->logger->push_task("Reloading fonts");
  189. try
  190. {
  191. game::load_fonts(ctx);
  192. }
  193. catch (...)
  194. {
  195. ctx->logger->pop_task(EXIT_FAILURE);
  196. }
  197. ctx->logger->pop_task(EXIT_SUCCESS);
  198. // Refresh and realign text
  199. game::menu::refresh_text(ctx);
  200. game::menu::align_text(ctx);
  201. game::menu::update_text_tweens(ctx);
  202. };
  203. auto toggle_dyslexia_font_callback = [ctx]()
  204. {
  205. ctx->dyslexia_font = !ctx->dyslexia_font;
  206. // Update value text
  207. update_value_text_content(ctx);
  208. // Save dyslexia font config
  209. (*ctx->config)["dyslexia_font"] = ctx->dyslexia_font;
  210. // Reload fonts
  211. ctx->logger->push_task("Reloading fonts");
  212. try
  213. {
  214. game::load_fonts(ctx);
  215. }
  216. catch (...)
  217. {
  218. ctx->logger->pop_task(EXIT_FAILURE);
  219. }
  220. ctx->logger->pop_task(EXIT_SUCCESS);
  221. // Refresh and realign text
  222. game::menu::refresh_text(ctx);
  223. game::menu::align_text(ctx);
  224. game::menu::update_text_tweens(ctx);
  225. };
  226. auto select_back_callback = [ctx]()
  227. {
  228. application::state next_state;
  229. next_state.name = "options_menu";
  230. next_state.enter = std::bind(game::state::options_menu::enter, ctx);
  231. next_state.exit = std::bind(game::state::options_menu::exit, ctx);
  232. ctx->app->change_state(next_state);
  233. };
  234. // Build list of menu select callbacks
  235. ctx->menu_select_callbacks.push_back(toggle_fullscreen_callback);
  236. ctx->menu_select_callbacks.push_back(increase_resolution_callback);
  237. ctx->menu_select_callbacks.push_back(toggle_v_sync_callback);
  238. ctx->menu_select_callbacks.push_back(increase_font_size_callback);
  239. ctx->menu_select_callbacks.push_back(toggle_dyslexia_font_callback);
  240. ctx->menu_select_callbacks.push_back(select_back_callback);
  241. // Build list of menu left callbacks
  242. ctx->menu_left_callbacks.push_back(toggle_fullscreen_callback);
  243. ctx->menu_left_callbacks.push_back(decrease_resolution_callback);
  244. ctx->menu_left_callbacks.push_back(toggle_v_sync_callback);
  245. ctx->menu_left_callbacks.push_back(decrease_font_size_callback);
  246. ctx->menu_left_callbacks.push_back(toggle_dyslexia_font_callback);
  247. ctx->menu_left_callbacks.push_back(nullptr);
  248. // Build list of menu right callbacks
  249. ctx->menu_right_callbacks.push_back(toggle_fullscreen_callback);
  250. ctx->menu_right_callbacks.push_back(increase_resolution_callback);
  251. ctx->menu_right_callbacks.push_back(toggle_v_sync_callback);
  252. ctx->menu_right_callbacks.push_back(increase_font_size_callback);
  253. ctx->menu_right_callbacks.push_back(toggle_dyslexia_font_callback);
  254. ctx->menu_right_callbacks.push_back(nullptr);
  255. // Set menu back callback
  256. ctx->menu_back_callback = select_back_callback;
  257. // Schedule menu control setup
  258. timeline* timeline = ctx->timeline;
  259. float t = timeline->get_position();
  260. timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
  261. }
  262. void exit(game::context* ctx)
  263. {
  264. // Destruct menu
  265. game::menu::clear_controls(ctx);
  266. game::menu::clear_callbacks(ctx);
  267. game::menu::remove_text_from_ui(ctx);
  268. game::menu::delete_text(ctx);
  269. ctx->ui_clear_pass->set_cleared_buffers(false, true, false);
  270. }
  271. } // namespace graphics_menu
  272. } // namespace state
  273. } // namespace game