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

377 lines
11 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/gamepad-config-menu.hpp"
  20. #include "game/state/controls-menu.hpp"
  21. #include "game/context.hpp"
  22. #include "application.hpp"
  23. #include "scene/text.hpp"
  24. #include "debug/log.hpp"
  25. #include "resources/resource-manager.hpp"
  26. #include "game/menu.hpp"
  27. #include "game/controls.hpp"
  28. #include "game/strings.hpp"
  29. #include "utility/hash/fnv1a.hpp"
  30. using namespace hash::literals;
  31. namespace game {
  32. namespace state {
  33. gamepad_config_menu::gamepad_config_menu(game::context& ctx):
  34. game::state::base(ctx)
  35. {
  36. debug::log::trace("Entering gamepad config menu state...");
  37. // Add camera control menu items
  38. add_control_item("move_forward");
  39. add_control_item("move_back");
  40. add_control_item("move_left");
  41. add_control_item("move_right");
  42. add_control_item("move_up");
  43. add_control_item("move_down");
  44. // Add application control menu items
  45. add_control_item("toggle_fullscreen");
  46. add_control_item("screenshot");
  47. // Construct menu item texts
  48. scene::text* back_text = new scene::text();
  49. // Build list of menu item texts
  50. ctx.menu_item_texts.push_back({back_text, nullptr});
  51. // Set content of menu item texts
  52. back_text->set_content(get_string(ctx, "back"_fnv1a32));
  53. // Init menu item index
  54. game::menu::init_menu_item_index(ctx, "gamepad_config");
  55. game::menu::update_text_color(ctx);
  56. game::menu::update_text_font(ctx);
  57. game::menu::align_text(ctx);
  58. game::menu::update_text_tweens(ctx);
  59. game::menu::add_text_to_ui(ctx);
  60. game::menu::setup_animations(ctx);
  61. // Construct menu item callbacks
  62. auto select_back_callback = [&ctx]()
  63. {
  64. // Disable controls
  65. game::menu::clear_controls(ctx);
  66. game::menu::fade_out
  67. (
  68. ctx,
  69. [&ctx]()
  70. {
  71. // Queue change to controls menu state
  72. ctx.function_queue.push
  73. (
  74. [&ctx]()
  75. {
  76. ctx.state_machine.pop();
  77. ctx.state_machine.emplace(new game::state::controls_menu(ctx));
  78. }
  79. );
  80. }
  81. );
  82. };
  83. // Build list of menu select callbacks
  84. ctx.menu_select_callbacks.push_back(select_back_callback);
  85. // Build list of menu left callbacks
  86. ctx.menu_left_callbacks.push_back(nullptr);
  87. // Build list of menu right callbacks
  88. ctx.menu_right_callbacks.push_back(nullptr);
  89. // Set menu back callback
  90. ctx.menu_back_callback = select_back_callback;
  91. // Queue menu control setup
  92. ctx.function_queue.push(std::bind(game::menu::setup_controls, std::ref(ctx)));
  93. // Fade in menu
  94. game::menu::fade_in(ctx, nullptr);
  95. debug::log::trace("Entered gamepad config menu state");
  96. }
  97. gamepad_config_menu::~gamepad_config_menu()
  98. {
  99. debug::log::trace("Exiting gamepad config menu state...");
  100. // Destruct menu
  101. game::menu::clear_controls(ctx);
  102. game::menu::clear_callbacks(ctx);
  103. game::menu::delete_animations(ctx);
  104. game::menu::remove_text_from_ui(ctx);
  105. game::menu::delete_text(ctx);
  106. // Save control profile
  107. game::save_control_profile(ctx);
  108. debug::log::trace("Exited gamepad config menu state");
  109. }
  110. std::string gamepad_config_menu::get_binding_string(input::control* control)
  111. {
  112. std::string binding_string;
  113. /*
  114. auto mappings = ctx.input_event_router->get_mappings(control);
  115. for (input::mapping* mapping: *mappings)
  116. {
  117. std::string mapping_string;
  118. switch (mapping->get_type())
  119. {
  120. case input::mapping_type::gamepad_axis:
  121. {
  122. const input::gamepad_axis_mapping* axis_mapping = static_cast<const input::gamepad_axis_mapping*>(mapping);
  123. switch (axis_mapping->axis)
  124. {
  125. case input::gamepad_axis::left_x:
  126. if (axis_mapping->negative)
  127. mapping_string = (*ctx.strings)["gamepad_left_stick_left"];
  128. else
  129. mapping_string = (*ctx.strings)["gamepad_left_stick_right"];
  130. break;
  131. case input::gamepad_axis::left_y:
  132. if (axis_mapping->negative)
  133. mapping_string = (*ctx.strings)["gamepad_left_stick_up"];
  134. else
  135. mapping_string = (*ctx.strings)["gamepad_left_stick_down"];
  136. break;
  137. case input::gamepad_axis::right_x:
  138. if (axis_mapping->negative)
  139. mapping_string = (*ctx.strings)["gamepad_right_stick_left"];
  140. else
  141. mapping_string = (*ctx.strings)["gamepad_right_stick_right"];
  142. break;
  143. case input::gamepad_axis::right_y:
  144. if (axis_mapping->negative)
  145. mapping_string = (*ctx.strings)["gamepad_right_stick_up"];
  146. else
  147. mapping_string = (*ctx.strings)["gamepad_right_stick_down"];
  148. break;
  149. case input::gamepad_axis::left_trigger:
  150. mapping_string = (*ctx.strings)["gamepad_left_trigger"];
  151. break;
  152. case input::gamepad_axis::right_trigger:
  153. mapping_string = (*ctx.strings)["gamepad_right_trigger"];
  154. break;
  155. default:
  156. break;
  157. }
  158. break;
  159. }
  160. case input::mapping_type::gamepad_button:
  161. {
  162. const input::gamepad_button_mapping* button_mapping = static_cast<const input::gamepad_button_mapping*>(mapping);
  163. switch (button_mapping->button)
  164. {
  165. case input::gamepad_button::a:
  166. mapping_string = (*ctx.strings)["gamepad_button_a"];
  167. break;
  168. case input::gamepad_button::b:
  169. mapping_string = (*ctx.strings)["gamepad_button_b"];
  170. break;
  171. case input::gamepad_button::x:
  172. mapping_string = (*ctx.strings)["gamepad_button_x"];
  173. break;
  174. case input::gamepad_button::y:
  175. mapping_string = (*ctx.strings)["gamepad_button_y"];
  176. break;
  177. case input::gamepad_button::back:
  178. mapping_string = (*ctx.strings)["gamepad_button_back"];
  179. break;
  180. case input::gamepad_button::guide:
  181. mapping_string = (*ctx.strings)["gamepad_button_guide"];
  182. break;
  183. case input::gamepad_button::start:
  184. mapping_string = (*ctx.strings)["gamepad_button_start"];
  185. break;
  186. case input::gamepad_button::left_stick:
  187. mapping_string = (*ctx.strings)["gamepad_button_left_stick"];
  188. break;
  189. case input::gamepad_button::right_stick:
  190. mapping_string = (*ctx.strings)["gamepad_button_right_stick"];
  191. break;
  192. case input::gamepad_button::left_shoulder:
  193. mapping_string = (*ctx.strings)["gamepad_button_left_shoulder"];
  194. break;
  195. case input::gamepad_button::right_shoulder:
  196. mapping_string = (*ctx.strings)["gamepad_button_right_shoulder"];
  197. break;
  198. case input::gamepad_button::dpad_up:
  199. mapping_string = (*ctx.strings)["gamepad_button_dpad_up"];
  200. break;
  201. case input::gamepad_button::dpad_down:
  202. mapping_string = (*ctx.strings)["gamepad_button_dpad_down"];
  203. break;
  204. case input::gamepad_button::dpad_left:
  205. mapping_string = (*ctx.strings)["gamepad_button_dpad_left"];
  206. break;
  207. case input::gamepad_button::dpad_right:
  208. mapping_string = (*ctx.strings)["gamepad_button_dpad_right"];
  209. break;
  210. default:
  211. break;
  212. }
  213. break;
  214. }
  215. default:
  216. break;
  217. }
  218. if (!mapping_string.empty())
  219. {
  220. if (binding_string.empty())
  221. {
  222. binding_string = mapping_string;
  223. }
  224. else
  225. {
  226. binding_string += " " + mapping_string;
  227. }
  228. }
  229. }
  230. */
  231. return binding_string;
  232. }
  233. void gamepad_config_menu::add_control_item(const std::string& control_name)
  234. {
  235. // Get pointer to control
  236. //input::control* control = ctx.controls[control_name];
  237. // Construct texts
  238. scene::text* name_text = new scene::text();
  239. scene::text* value_text = new scene::text();
  240. // Add texts to list of menu item texts
  241. ctx.menu_item_texts.push_back({name_text, value_text});
  242. // Set content of name text
  243. name_text->set_content(control_name);
  244. // Set content of value text
  245. //value_text->set_content(get_binding_string(control));
  246. auto select_callback = [this, &ctx = this->ctx, value_text]()
  247. {
  248. // Clear binding string from value text
  249. value_text->set_content(get_string(ctx, "ellipsis"_fnv1a32));
  250. game::menu::align_text(ctx);
  251. game::menu::update_text_tweens(ctx);
  252. // Disable controls
  253. game::menu::clear_controls(ctx);
  254. /*
  255. // Remove gamepad event mappings from control
  256. ctx.input_event_router->remove_mappings(control, input::mapping_type::gamepad_axis);
  257. ctx.input_event_router->remove_mappings(control, input::mapping_type::gamepad_button);
  258. // Setup input binding listener
  259. ctx.input_listener->set_callback
  260. (
  261. [this, &ctx, control, value_text](const event_base& event)
  262. {
  263. auto id = event.get_event_type_id();
  264. if (id == gamepad_axis_moved_event::event_type_id)
  265. {
  266. // Map gamepad axis event to control
  267. const gamepad_axis_moved_event& axis_event = static_cast<const gamepad_axis_moved_event&>(event);
  268. if (std::abs(axis_event.value) < 0.5f)
  269. return;
  270. ctx.input_event_router->add_mapping(input::gamepad_axis_mapping(control, nullptr, axis_event.axis, (axis_event.value < 0)));
  271. }
  272. else if (id == gamepad_button_pressed_event::event_type_id)
  273. {
  274. // Map gamepad button event to control
  275. const gamepad_button_pressed_event& button_event = static_cast<const gamepad_button_pressed_event&>(event);
  276. ctx.input_event_router->add_mapping(input::gamepad_button_mapping(control, nullptr, button_event.button));
  277. }
  278. else if (id == key_pressed_event::event_type_id)
  279. {
  280. // Map key pressed event to control
  281. const key_pressed_event& key_event = static_cast<const key_pressed_event&>(event);
  282. if (key_event.scancode != input::scancode::escape && key_event.scancode != input::scancode::backspace)
  283. return;
  284. }
  285. else
  286. {
  287. return;
  288. }
  289. // Update menu text
  290. value_text->set_content(this->get_binding_string(control));
  291. game::menu::align_text(ctx);
  292. game::menu::update_text_tweens(ctx);
  293. // Disable input listener
  294. ctx.input_listener->set_enabled(false);
  295. ctx.input_listener->set_callback(nullptr);
  296. // Queue menu control setup
  297. ctx.function_queue.push(std::bind(game::menu::setup_controls, std::ref(ctx)));
  298. }
  299. );
  300. ctx.input_listener->set_enabled(true);
  301. */
  302. };
  303. // Register menu item callbacks
  304. ctx.menu_select_callbacks.push_back(select_callback);
  305. ctx.menu_left_callbacks.push_back(nullptr);
  306. ctx.menu_right_callbacks.push_back(nullptr);
  307. }
  308. } // namespace state
  309. } // namespace game