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

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