settings_scene.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  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, settings_screen_difficulty_text[index]);
  39. view_dispatcher_send_custom_event(
  40. 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) >
  54. MINESWEEPER_BOARD_MAX_TILES;
  55. if(is_over_max_tiles) {
  56. do {
  57. is_over_max_tiles = (app->t_settings_info.board_width * --curr_board_height) >
  58. MINESWEEPER_BOARD_MAX_TILES;
  59. } while(is_over_max_tiles);
  60. app->t_settings_info.board_height = curr_board_height;
  61. snprintf(source, 5, "%" PRIu8, curr_board_height);
  62. source[4] = '\0';
  63. furi_string_set_strn(app->t_settings_info.height_str, source, 5);
  64. variable_item_set_current_value_index(
  65. app->t_settings_info.height_item, app->t_settings_info.board_height - 7);
  66. variable_item_set_current_value_text(
  67. app->t_settings_info.height_item,
  68. furi_string_get_cstr(app->t_settings_info.height_str));
  69. }
  70. snprintf(source, 5, "%" PRIu8, index + 16);
  71. source[4] = '\0';
  72. furi_string_set_strn(app->t_settings_info.width_str, source, 5);
  73. variable_item_set_current_value_text(
  74. app->t_settings_info.width_item, furi_string_get_cstr(app->t_settings_info.width_str));
  75. view_dispatcher_send_custom_event(
  76. app->view_dispatcher, MineSweeperSettingsScreenEventHeightChange);
  77. }
  78. static void minesweeper_scene_settings_screen_set_height(VariableItem* item) {
  79. char source[5];
  80. uint8_t index = 0;
  81. uint8_t curr_board_width = 16;
  82. bool is_over_max_tiles = false;
  83. furi_assert(item);
  84. MineSweeperApp* app = variable_item_get_context(item);
  85. app->t_settings_info.height_item = item;
  86. index = variable_item_get_current_value_index(app->t_settings_info.height_item);
  87. app->t_settings_info.board_height = index + 7;
  88. curr_board_width = app->t_settings_info.board_width;
  89. is_over_max_tiles = (app->t_settings_info.board_height * curr_board_width) >
  90. MINESWEEPER_BOARD_MAX_TILES;
  91. if(is_over_max_tiles) {
  92. do {
  93. is_over_max_tiles = (app->t_settings_info.board_height * --curr_board_width) >
  94. MINESWEEPER_BOARD_MAX_TILES;
  95. } while(is_over_max_tiles);
  96. app->t_settings_info.board_width = curr_board_width;
  97. snprintf(source, 5, "%" PRIu8, curr_board_width);
  98. source[4] = '\0';
  99. furi_string_set_strn(app->t_settings_info.width_str, source, 5);
  100. variable_item_set_current_value_index(
  101. app->t_settings_info.width_item, app->t_settings_info.board_width - 16);
  102. variable_item_set_current_value_text(
  103. app->t_settings_info.width_item, furi_string_get_cstr(app->t_settings_info.width_str));
  104. }
  105. snprintf(source, 5, "%" PRIu8, index + 7);
  106. source[4] = '\0';
  107. furi_string_set_strn(app->t_settings_info.height_str, source, 5);
  108. variable_item_set_current_value_text(
  109. app->t_settings_info.height_item, furi_string_get_cstr(app->t_settings_info.height_str));
  110. view_dispatcher_send_custom_event(
  111. app->view_dispatcher, MineSweeperSettingsScreenEventWidthChange);
  112. }
  113. static void minesweeper_scene_settings_screen_set_solvable(VariableItem* item) {
  114. furi_assert(item);
  115. MineSweeperApp* app = variable_item_get_context(item);
  116. uint8_t index = variable_item_get_current_value_index(app->t_settings_info.solvable_item);
  117. app->t_settings_info.ensure_solvable_board = (index == 1) ? true : false;
  118. variable_item_set_current_value_text(item, settings_screen_verifier_text[index]);
  119. view_dispatcher_send_custom_event(
  120. app->view_dispatcher, MineSweeperSettingsScreenEventSolvableChange);
  121. }
  122. static void minesweeper_scene_settings_screen_set_info(VariableItem* item) {
  123. furi_assert(item);
  124. MineSweeperApp* app = variable_item_get_context(item);
  125. view_dispatcher_send_custom_event(
  126. app->view_dispatcher, MineSweeperSettingsScreenEventInfoChange);
  127. }
  128. void minesweeper_scene_settings_screen_on_enter(void* context) {
  129. furi_assert(context);
  130. MineSweeperApp* app = (MineSweeperApp*)context;
  131. VariableItemList* va = app->settings_screen;
  132. VariableItem* item;
  133. // If we are accessing the scene and have not changed the settings
  134. if(!app->is_settings_changed) {
  135. // Set temp setting buffer to current state
  136. app->t_settings_info = app->settings_info;
  137. }
  138. // Set Difficulty Item
  139. item = variable_item_list_add(
  140. va,
  141. "Difficulty",
  142. MineSweeperSettingsScreenDifficultyTypeNum,
  143. minesweeper_scene_settings_screen_set_difficulty,
  144. app);
  145. app->t_settings_info.difficulty_item = item;
  146. variable_item_set_current_value_index(item, app->t_settings_info.difficulty);
  147. variable_item_set_current_value_text(
  148. item, settings_screen_difficulty_text[app->t_settings_info.difficulty]);
  149. // Set Width Item
  150. item = variable_item_list_add(
  151. va, "Board Width", 33 - 16, minesweeper_scene_settings_screen_set_width, app);
  152. app->t_settings_info.width_item = item;
  153. variable_item_set_current_value_index(item, app->t_settings_info.board_width - 16);
  154. char source[5];
  155. snprintf(source, 5, "%" PRIu8, app->t_settings_info.board_width);
  156. source[4] = '\0';
  157. furi_string_set_strn(app->t_settings_info.width_str, source, 5);
  158. variable_item_set_current_value_text(
  159. item, furi_string_get_cstr(app->t_settings_info.width_str));
  160. // Set Height Item
  161. item = variable_item_list_add(
  162. va, "Board Height", 33 - 7, minesweeper_scene_settings_screen_set_height, app);
  163. app->t_settings_info.height_item = item;
  164. variable_item_set_current_value_index(item, app->t_settings_info.board_height - 7);
  165. snprintf(source, 5, "%" PRIu8, app->t_settings_info.board_height);
  166. source[4] = '\0';
  167. furi_string_set_strn(app->t_settings_info.height_str, source, 5);
  168. variable_item_set_current_value_text(
  169. item, furi_string_get_cstr(app->t_settings_info.height_str));
  170. // Set solvable item
  171. item = variable_item_list_add(
  172. va, "Ensure Solvable", 2, minesweeper_scene_settings_screen_set_solvable, app);
  173. app->t_settings_info.solvable_item = item;
  174. uint8_t idx = (app->t_settings_info.ensure_solvable_board) ? 1 : 0;
  175. variable_item_set_current_value_index(item, idx);
  176. variable_item_set_current_value_text(item, settings_screen_verifier_text[idx]);
  177. // Set info item
  178. item = variable_item_list_add(
  179. va, "Right For Info", 2, minesweeper_scene_settings_screen_set_info, app);
  180. variable_item_set_current_value_index(item, 0);
  181. variable_item_set_current_value_text(item, "-------");
  182. view_dispatcher_switch_to_view(app->view_dispatcher, MineSweeperSettingsView);
  183. }
  184. bool minesweeper_scene_settings_screen_on_event(void* context, SceneManagerEvent event) {
  185. furi_assert(context);
  186. MineSweeperApp* app = context;
  187. bool consumed = false;
  188. if(event.type == SceneManagerEventTypeCustom) {
  189. app->is_settings_changed =
  190. (app->settings_info.board_width != app->t_settings_info.board_width ||
  191. app->settings_info.board_height != app->t_settings_info.board_height ||
  192. app->settings_info.difficulty != app->t_settings_info.difficulty ||
  193. app->settings_info.ensure_solvable_board !=
  194. app->t_settings_info.ensure_solvable_board);
  195. switch(event.event) {
  196. case MineSweeperSettingsScreenEventDifficultyChange:
  197. break;
  198. case MineSweeperSettingsScreenEventWidthChange:
  199. break;
  200. case MineSweeperSettingsScreenEventHeightChange:
  201. break;
  202. case MineSweeperSettingsScreenEventSolvableChange:
  203. break;
  204. case MineSweeperSettingsScreenEventInfoChange:
  205. scene_manager_next_scene(app->scene_manager, MineSweeperSceneInfoScreen);
  206. break;
  207. default:
  208. break;
  209. };
  210. consumed = true;
  211. } else if(event.type == SceneManagerEventTypeBack) {
  212. // If there are changes in the width, height, or difficulty go to confirmation scren
  213. if(app->is_settings_changed) {
  214. scene_manager_next_scene(app->scene_manager, MineSweeperSceneConfirmationScreen);
  215. } else {
  216. memset(&app->t_settings_info, 0, sizeof(app->t_settings_info));
  217. if(!scene_manager_search_and_switch_to_previous_scene(
  218. app->scene_manager, MineSweeperSceneMenuScreen)) {
  219. scene_manager_stop(app->scene_manager);
  220. view_dispatcher_stop(app->view_dispatcher);
  221. }
  222. }
  223. consumed = true;
  224. }
  225. return consumed;
  226. }
  227. void minesweeper_scene_settings_screen_on_exit(void* context) {
  228. furi_assert(context);
  229. MineSweeperApp* app = (MineSweeperApp*)context;
  230. VariableItemList* va = app->settings_screen;
  231. variable_item_list_reset(va);
  232. }