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

331 lines
9.4 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/keyboard-config-menu.hpp"
  20. #include "game/state/controls-menu.hpp"
  21. #include "application.hpp"
  22. #include "scene/text.hpp"
  23. #include "debug/log.hpp"
  24. #include "resources/resource-manager.hpp"
  25. #include "game/menu.hpp"
  26. #include "game/controls.hpp"
  27. #include "game/strings.hpp"
  28. #include "utility/hash/fnv1a.hpp"
  29. using namespace hash::literals;
  30. namespace game {
  31. namespace state {
  32. keyboard_config_menu::keyboard_config_menu(game::context& ctx):
  33. game::state::base(ctx)
  34. {
  35. debug::log::trace("Entering keyboard config menu state...");
  36. // Add camera control menu items
  37. add_control_item("move_forward");
  38. add_control_item("move_back");
  39. add_control_item("move_left");
  40. add_control_item("move_right");
  41. add_control_item("move_up");
  42. add_control_item("move_down");
  43. // Add application control menu items
  44. add_control_item("toggle_fullscreen");
  45. add_control_item("screenshot");
  46. // Construct menu item texts
  47. scene::text* back_text = new scene::text();
  48. // Build list of menu item texts
  49. ctx.menu_item_texts.push_back({back_text, nullptr});
  50. // Set content of menu item texts
  51. back_text->set_content(get_string(ctx, "back"_fnv1a32));
  52. // Init menu item index
  53. game::menu::init_menu_item_index(ctx, "keyboard_config");
  54. game::menu::update_text_color(ctx);
  55. game::menu::update_text_font(ctx);
  56. game::menu::align_text(ctx);
  57. game::menu::update_text_tweens(ctx);
  58. game::menu::add_text_to_ui(ctx);
  59. game::menu::setup_animations(ctx);
  60. // Construct menu item callbacks
  61. auto select_back_callback = [&ctx]()
  62. {
  63. // Disable controls
  64. game::menu::clear_controls(ctx);
  65. game::menu::fade_out
  66. (
  67. ctx,
  68. [&ctx]()
  69. {
  70. // Queue change to controls menu state
  71. ctx.function_queue.push
  72. (
  73. [&ctx]()
  74. {
  75. ctx.state_machine.pop();
  76. ctx.state_machine.emplace(new game::state::controls_menu(ctx));
  77. }
  78. );
  79. }
  80. );
  81. };
  82. // Build list of menu select callbacks
  83. ctx.menu_select_callbacks.push_back(select_back_callback);
  84. // Build list of menu left callbacks
  85. ctx.menu_left_callbacks.push_back(nullptr);
  86. // Build list of menu right callbacks
  87. ctx.menu_right_callbacks.push_back(nullptr);
  88. // Set menu back callback
  89. ctx.menu_back_callback = select_back_callback;
  90. // Queue menu control setup
  91. ctx.function_queue.push(std::bind(game::menu::setup_controls, std::ref(ctx)));
  92. // Fade in menu
  93. game::menu::fade_in(ctx, nullptr);
  94. debug::log::trace("Entered keyboard config menu state");
  95. }
  96. keyboard_config_menu::~keyboard_config_menu()
  97. {
  98. debug::log::trace("Exiting keyboard config menu state...");
  99. // Destruct menu
  100. game::menu::clear_controls(ctx);
  101. game::menu::clear_callbacks(ctx);
  102. game::menu::delete_animations(ctx);
  103. game::menu::remove_text_from_ui(ctx);
  104. game::menu::delete_text(ctx);
  105. // Save control profile
  106. game::save_control_profile(ctx);
  107. debug::log::trace("Exited keyboard config menu state...");
  108. }
  109. std::string keyboard_config_menu::get_binding_string(input::control* control)
  110. {
  111. std::string binding_string;
  112. /*
  113. auto mappings = ctx.input_event_router->get_mappings(control);
  114. for (input::mapping* mapping: *mappings)
  115. {
  116. std::string mapping_string;
  117. switch (mapping->get_type())
  118. {
  119. case input::mapping_type::key:
  120. {
  121. const input::key_mapping* key_mapping = static_cast<const input::key_mapping*>(mapping);
  122. const char* scancode_name = input::keyboard::get_scancode_name(key_mapping->scancode);
  123. mapping_string = scancode_name;
  124. break;
  125. }
  126. case input::mapping_type::mouse_wheel:
  127. {
  128. const input::mouse_wheel_mapping* wheel_mapping = static_cast<const input::mouse_wheel_mapping*>(mapping);
  129. switch (wheel_mapping->axis)
  130. {
  131. case input::mouse_wheel_axis::negative_x:
  132. mapping_string = (*ctx.strings)["mouse_wheel_left"];
  133. break;
  134. case input::mouse_wheel_axis::positive_x:
  135. mapping_string = (*ctx.strings)["mouse_wheel_right"];
  136. break;
  137. case input::mouse_wheel_axis::negative_y:
  138. mapping_string = (*ctx.strings)["mouse_wheel_down"];
  139. break;
  140. case input::mouse_wheel_axis::positive_y:
  141. mapping_string = (*ctx.strings)["mouse_wheel_up"];
  142. break;
  143. default:
  144. break;
  145. }
  146. break;
  147. }
  148. case input::mapping_type::mouse_button:
  149. {
  150. const input::mouse_button_mapping* button_mapping = static_cast<const input::mouse_button_mapping*>(mapping);
  151. if (button_mapping->button == 1)
  152. {
  153. mapping_string = (*ctx.strings)["mouse_button_left"];
  154. }
  155. else if (button_mapping->button == 2)
  156. {
  157. mapping_string = (*ctx.strings)["mouse_button_middle"];
  158. }
  159. else if (button_mapping->button == 3)
  160. {
  161. mapping_string = (*ctx.strings)["mouse_button_right"];
  162. }
  163. else
  164. {
  165. const std::string& format = (*ctx.strings)["mouse_button_n"];
  166. char buffer[64];
  167. std::snprintf(buffer, 64, format.c_str(), button_mapping->button);
  168. mapping_string = buffer;
  169. }
  170. break;
  171. }
  172. default:
  173. break;
  174. }
  175. if (!mapping_string.empty())
  176. {
  177. if (binding_string.empty())
  178. {
  179. binding_string = mapping_string;
  180. }
  181. else
  182. {
  183. binding_string += " " + mapping_string;
  184. }
  185. }
  186. }
  187. */
  188. return binding_string;
  189. }
  190. void keyboard_config_menu::add_control_item(const std::string& control_name)
  191. {
  192. // Get pointer to control
  193. //input::control* control = ctx.controls[control_name];
  194. // Construct texts
  195. scene::text* name_text = new scene::text();
  196. scene::text* value_text = new scene::text();
  197. // Add texts to list of menu item texts
  198. ctx.menu_item_texts.push_back({name_text, value_text});
  199. // Set content of name text
  200. name_text->set_content(control_name);
  201. // Set content of value text
  202. //value_text->set_content(get_binding_string( control));
  203. auto select_callback = [this, &ctx = this->ctx, value_text]()
  204. {
  205. // Clear binding string from value text
  206. value_text->set_content(get_string(ctx, "ellipsis"_fnv1a32));
  207. game::menu::align_text(ctx);
  208. game::menu::update_text_tweens(ctx);
  209. // Disable controls
  210. game::menu::clear_controls(ctx);
  211. /*
  212. // Remove keyboard and mouse event mappings from control
  213. ctx.input_event_router->remove_mappings(control, input::mapping_type::key);
  214. ctx.input_event_router->remove_mappings(control, input::mapping_type::mouse_motion);
  215. ctx.input_event_router->remove_mappings(control, input::mapping_type::mouse_wheel);
  216. ctx.input_event_router->remove_mappings(control, input::mapping_type::mouse_button);
  217. // Setup input binding listener
  218. ctx.input_listener->set_callback
  219. (
  220. [this, &ctx, control, value_text](const event_base& event)
  221. {
  222. auto id = event.get_event_type_id();
  223. if (id == key_pressed_event::event_type_id)
  224. {
  225. // Map key pressed event to control
  226. const key_pressed_event& key_event = static_cast<const key_pressed_event&>(event);
  227. if (key_event.scancode != input::scancode::escape && key_event.scancode != input::scancode::backspace)
  228. ctx.input_event_router->add_mapping(input::key_mapping(control, key_event.keyboard, key_event.scancode));
  229. }
  230. else if (id == mouse_wheel_scrolled_event::event_type_id)
  231. {
  232. // Map mouse wheel scrolled event to control
  233. const mouse_wheel_scrolled_event& wheel_event = static_cast<const mouse_wheel_scrolled_event&>(event);
  234. input::mouse_wheel_axis axis;
  235. if (wheel_event.x < 0)
  236. axis = input::mouse_wheel_axis::negative_x;
  237. else if (wheel_event.x > 0)
  238. axis = input::mouse_wheel_axis::positive_x;
  239. else if (wheel_event.y < 0)
  240. axis = input::mouse_wheel_axis::negative_y;
  241. else if (wheel_event.y > 0)
  242. axis = input::mouse_wheel_axis::positive_y;
  243. else
  244. return;
  245. ctx.input_event_router->add_mapping(input::mouse_wheel_mapping(control, wheel_event.mouse, axis));
  246. }
  247. else if (id == mouse_button_pressed_event::event_type_id)
  248. {
  249. // Map mouse button pressed event to control
  250. const mouse_button_pressed_event& button_event = static_cast<const mouse_button_pressed_event&>(event);
  251. ctx.input_event_router->add_mapping(input::mouse_button_mapping(control, button_event.mouse, button_event.button));
  252. }
  253. else
  254. {
  255. return;
  256. }
  257. // Update menu text
  258. value_text->set_content(this->get_binding_string(control));
  259. game::menu::align_text(ctx);
  260. game::menu::update_text_tweens(ctx);
  261. // Disable input listener
  262. ctx.input_listener->set_enabled(false);
  263. ctx.input_listener->set_callback(nullptr);
  264. // Queue menu control setup
  265. ctx.function_queue.push(std::bind(game::menu::setup_controls, std::ref(ctx)));
  266. }
  267. );
  268. ctx.input_listener->set_enabled(true);
  269. */
  270. };
  271. // Register menu item callbacks
  272. ctx.menu_select_callbacks.push_back(select_callback);
  273. ctx.menu_left_callbacks.push_back(nullptr);
  274. ctx.menu_right_callbacks.push_back(nullptr);
  275. }
  276. } // namespace state
  277. } // namespace game