settings_scene.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. #include "../minesweeper.h"
  2. #include "../views/minesweeper_game_screen.h"
  3. typedef enum {
  4. MineSweeperSettingsScreenDifficultyTypeEasy,
  5. MineSweeperSettingsScreenDifficultyTypeMedium,
  6. MineSweeperSettingsScreenDifficultyTypeHard,
  7. MineSweeperSettingsScreenDifficultyTypeNum,
  8. } MineSweeperSettingsScreenDifficultyType;
  9. typedef enum {
  10. MineSweeperSettingsScreenIndexDifficulty,
  11. MineSweeperSettingsScreenIndexWidth,
  12. MineSweeperSettingsScreenIndexHeight,
  13. MineSweeperSettingsScreenIndexNum,
  14. } MineSweeperSettingsScreenIndex;
  15. typedef enum {
  16. MineSweeperSettingsScreenEventDifficultyChange,
  17. MineSweeperSettingsScreenEventWidthChange,
  18. MineSweeperSettingsScreenEventHeightChange,
  19. MineSweeperSettingsScreenEventSolvableChange,
  20. MineSweeperSettingsScreenEventInfoChange,
  21. } MineSweeperSettingsScreenEvent;
  22. static const char* settings_screen_difficulty_text[MineSweeperSettingsScreenDifficultyTypeNum] = {
  23. "Easy",
  24. "Medium",
  25. "Hard",
  26. };
  27. static const char* settings_screen_verifier_text[2] = {
  28. "False",
  29. "True",
  30. };
  31. static void minesweeper_scene_settings_screen_set_difficulty(VariableItem* item) {
  32. furi_assert(item);
  33. MineSweeperApp* app = variable_item_get_context(item);
  34. app->t_settings_info.difficulty_item = item;
  35. uint8_t index = variable_item_get_current_value_index(app->t_settings_info.difficulty_item);
  36. app->t_settings_info.difficulty = index;
  37. variable_item_set_current_value_text(
  38. app->t_settings_info.difficulty_item,
  39. settings_screen_difficulty_text[index]);
  40. view_dispatcher_send_custom_event(app->view_dispatcher, MineSweeperSettingsScreenEventDifficultyChange);
  41. }
  42. static void minesweeper_scene_settings_screen_set_width(VariableItem* item) {
  43. char source[5];
  44. uint8_t index = 0;
  45. uint8_t curr_board_height = 7;
  46. bool is_over_max_tiles = false;
  47. furi_assert(item);
  48. MineSweeperApp* app = variable_item_get_context(item);
  49. app->t_settings_info.width_item = item;
  50. index = variable_item_get_current_value_index(app->t_settings_info.width_item);
  51. app->t_settings_info.board_width = index+16;
  52. curr_board_height = app->t_settings_info.board_height;
  53. is_over_max_tiles = (app->t_settings_info.board_width * curr_board_height) > MINESWEEPER_BOARD_MAX_TILES;
  54. if (is_over_max_tiles) {
  55. do {
  56. is_over_max_tiles = (app->t_settings_info.board_width * --curr_board_height) > MINESWEEPER_BOARD_MAX_TILES;
  57. } while (is_over_max_tiles);
  58. app->t_settings_info.board_height = curr_board_height;
  59. snprintf(source, 5, "%" PRIu8, curr_board_height);
  60. source[4] = '\0';
  61. furi_string_set_strn(app->t_settings_info.height_str, source, 5);
  62. variable_item_set_current_value_index(
  63. app->t_settings_info.height_item,
  64. app->t_settings_info.board_height-7);
  65. variable_item_set_current_value_text(app->t_settings_info.height_item, furi_string_get_cstr(app->t_settings_info.height_str));
  66. }
  67. snprintf(source, 5, "%" PRIu8, index+16);
  68. source[4] = '\0';
  69. furi_string_set_strn(app->t_settings_info.width_str, source, 5);
  70. variable_item_set_current_value_text(app->t_settings_info.width_item, furi_string_get_cstr(app->t_settings_info.width_str));
  71. view_dispatcher_send_custom_event(app->view_dispatcher, MineSweeperSettingsScreenEventHeightChange);
  72. }
  73. static void minesweeper_scene_settings_screen_set_height(VariableItem* item) {
  74. char source[5];
  75. uint8_t index = 0;
  76. uint8_t curr_board_width = 16;
  77. bool is_over_max_tiles = false;
  78. furi_assert(item);
  79. MineSweeperApp* app = variable_item_get_context(item);
  80. app->t_settings_info.height_item = item;
  81. index = variable_item_get_current_value_index(app->t_settings_info.height_item);
  82. app->t_settings_info.board_height = index+7;
  83. curr_board_width = app->t_settings_info.board_width;
  84. is_over_max_tiles = (app->t_settings_info.board_height * curr_board_width) > MINESWEEPER_BOARD_MAX_TILES;
  85. if (is_over_max_tiles) {
  86. do {
  87. is_over_max_tiles = (app->t_settings_info.board_height * --curr_board_width) > MINESWEEPER_BOARD_MAX_TILES;
  88. } while (is_over_max_tiles);
  89. app->t_settings_info.board_width = curr_board_width;
  90. snprintf(source, 5, "%" PRIu8, curr_board_width);
  91. source[4] = '\0';
  92. furi_string_set_strn(app->t_settings_info.width_str, source, 5);
  93. variable_item_set_current_value_index(
  94. app->t_settings_info.width_item,
  95. app->t_settings_info.board_width-16);
  96. variable_item_set_current_value_text(app->t_settings_info.width_item, furi_string_get_cstr(app->t_settings_info.width_str));
  97. }
  98. snprintf(source, 5, "%" PRIu8, index+7);
  99. source[4] = '\0';
  100. furi_string_set_strn(app->t_settings_info.height_str, source, 5);
  101. variable_item_set_current_value_text(app->t_settings_info.height_item, furi_string_get_cstr(app->t_settings_info.height_str));
  102. view_dispatcher_send_custom_event(app->view_dispatcher, MineSweeperSettingsScreenEventWidthChange);
  103. }
  104. static void minesweeper_scene_settings_screen_set_solvable(VariableItem* item) {
  105. furi_assert(item);
  106. MineSweeperApp* app = variable_item_get_context(item);
  107. uint8_t index = variable_item_get_current_value_index(app->t_settings_info.solvable_item);
  108. app->t_settings_info.ensure_solvable_board = (index == 1) ? true : false;
  109. variable_item_set_current_value_text(item, settings_screen_verifier_text[index]);
  110. view_dispatcher_send_custom_event(app->view_dispatcher, MineSweeperSettingsScreenEventSolvableChange);
  111. }
  112. static void minesweeper_scene_settings_screen_set_info(VariableItem* item) {
  113. furi_assert(item);
  114. MineSweeperApp* app = variable_item_get_context(item);
  115. view_dispatcher_send_custom_event(app->view_dispatcher, MineSweeperSettingsScreenEventInfoChange);
  116. }
  117. void minesweeper_scene_settings_screen_on_enter(void* context) {
  118. furi_assert(context);
  119. MineSweeperApp* app = (MineSweeperApp*)context;
  120. VariableItemList* va = app->settings_screen;
  121. VariableItem* item;
  122. // If we are accessing the scene and have not changed the settings
  123. if (!app->is_settings_changed) {
  124. // Set temp setting buffer to current state
  125. app->t_settings_info = app->settings_info;
  126. }
  127. // Set Difficulty Item
  128. item = variable_item_list_add(
  129. va,
  130. "Difficulty",
  131. MineSweeperSettingsScreenDifficultyTypeNum,
  132. minesweeper_scene_settings_screen_set_difficulty,
  133. app);
  134. app->t_settings_info.difficulty_item = item;
  135. variable_item_set_current_value_index(
  136. item,
  137. app->t_settings_info.difficulty);
  138. variable_item_set_current_value_text(
  139. item,
  140. settings_screen_difficulty_text[app->t_settings_info.difficulty]);
  141. // Set Width Item
  142. item = variable_item_list_add(
  143. va,
  144. "Board Width",
  145. 33-16,
  146. minesweeper_scene_settings_screen_set_width,
  147. app);
  148. app->t_settings_info.width_item = item;
  149. variable_item_set_current_value_index(
  150. item,
  151. app->t_settings_info.board_width-16);
  152. char source[5];
  153. snprintf(source, 5, "%" PRIu8, app->t_settings_info.board_width);
  154. source[4] = '\0';
  155. furi_string_set_strn(app->t_settings_info.width_str, source, 5);
  156. variable_item_set_current_value_text(
  157. item,
  158. furi_string_get_cstr(app->t_settings_info.width_str));
  159. // Set Height Item
  160. item = variable_item_list_add(
  161. va,
  162. "Board Height",
  163. 33-7,
  164. minesweeper_scene_settings_screen_set_height,
  165. app);
  166. app->t_settings_info.height_item = item;
  167. variable_item_set_current_value_index(
  168. item,
  169. app->t_settings_info.board_height-7);
  170. snprintf(source, 5, "%" PRIu8, app->t_settings_info.board_height);
  171. source[4] = '\0';
  172. furi_string_set_strn(app->t_settings_info.height_str, source, 5);
  173. variable_item_set_current_value_text(
  174. item,
  175. furi_string_get_cstr(app->t_settings_info.height_str));
  176. // Set solvable item
  177. item = variable_item_list_add(
  178. va,
  179. "Ensure Solvable",
  180. 2,
  181. minesweeper_scene_settings_screen_set_solvable,
  182. app);
  183. app->t_settings_info.solvable_item = item;
  184. uint8_t idx = (app->t_settings_info.ensure_solvable_board) ? 1 : 0;
  185. variable_item_set_current_value_index(
  186. item,
  187. idx);
  188. variable_item_set_current_value_text(
  189. item,
  190. settings_screen_verifier_text[idx]);
  191. // Set info item
  192. item = variable_item_list_add(
  193. va,
  194. "Right For Info",
  195. 2,
  196. minesweeper_scene_settings_screen_set_info,
  197. app);
  198. variable_item_set_current_value_index(
  199. item,
  200. 0);
  201. variable_item_set_current_value_text(
  202. item,
  203. "-------");
  204. view_dispatcher_switch_to_view(app->view_dispatcher, MineSweeperSettingsView);
  205. }
  206. bool minesweeper_scene_settings_screen_on_event(void* context, SceneManagerEvent event) {
  207. furi_assert(context);
  208. MineSweeperApp* app = context;
  209. bool consumed = false;
  210. if (event.type == SceneManagerEventTypeCustom) {
  211. app->is_settings_changed = (app->settings_info.board_width != app->t_settings_info.board_width ||
  212. app->settings_info.board_height != app->t_settings_info.board_height ||
  213. app->settings_info.difficulty != app->t_settings_info.difficulty ||
  214. app->settings_info.ensure_solvable_board != app->t_settings_info.ensure_solvable_board);
  215. switch (event.event) {
  216. case MineSweeperSettingsScreenEventDifficultyChange :
  217. break;
  218. case MineSweeperSettingsScreenEventWidthChange :
  219. break;
  220. case MineSweeperSettingsScreenEventHeightChange :
  221. break;
  222. case MineSweeperSettingsScreenEventSolvableChange :
  223. break;
  224. case MineSweeperSettingsScreenEventInfoChange :
  225. scene_manager_next_scene(app->scene_manager, MineSweeperSceneInfoScreen);
  226. break;
  227. default :
  228. break;
  229. };
  230. consumed = true;
  231. } else if (event.type == SceneManagerEventTypeBack) {
  232. // If there are changes in the width, height, or difficulty go to confirmation scren
  233. if (app->is_settings_changed) {
  234. scene_manager_next_scene(app->scene_manager, MineSweeperSceneConfirmationScreen);
  235. } else {
  236. memset(&app->t_settings_info, 0, sizeof(app->t_settings_info));
  237. if (!scene_manager_search_and_switch_to_previous_scene(
  238. app->scene_manager, MineSweeperSceneMenuScreen)) {
  239. scene_manager_stop(app->scene_manager);
  240. view_dispatcher_stop(app->view_dispatcher);
  241. }
  242. }
  243. consumed = true;
  244. }
  245. return consumed;
  246. }
  247. void minesweeper_scene_settings_screen_on_exit(void* context) {
  248. furi_assert(context);
  249. MineSweeperApp* app = (MineSweeperApp*)context;
  250. VariableItemList* va = app->settings_screen;
  251. variable_item_list_reset(va);
  252. }