events.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. #include "events.h"
  2. #include "move.h"
  3. #include "game.h"
  4. //-----------------------------------------------------------------------------
  5. void events_for_selection(InputEvent* event, Game* game) {
  6. if((event->type == InputTypePress) || (event->type == InputTypeRepeat)) {
  7. if(game->solutionMode) {
  8. end_solution(game);
  9. return;
  10. }
  11. switch(event->key) {
  12. case InputKeyLeft:
  13. find_movable_left(&game->movables, &game->currentMovable);
  14. break;
  15. case InputKeyRight:
  16. find_movable_right(&game->movables, &game->currentMovable);
  17. break;
  18. case InputKeyUp:
  19. find_movable_up(&game->movables, &game->currentMovable);
  20. break;
  21. case InputKeyDown:
  22. find_movable_down(&game->movables, &game->currentMovable);
  23. break;
  24. case InputKeyOk:
  25. click_selected(game);
  26. break;
  27. case InputKeyBack:
  28. game->menuPausedPos = (game->undoMovable == MOVABLE_NOT_FOUND) ? 4 : 0;
  29. game->state = PAUSED;
  30. break;
  31. default:
  32. break;
  33. }
  34. }
  35. }
  36. //-----------------------------------------------------------------------------
  37. void events_for_direction(InputEvent* event, Game* game) {
  38. if((event->type == InputTypePress) || (event->type == InputTypeRepeat)) {
  39. switch(event->key) {
  40. case InputKeyLeft:
  41. start_move(game, MOVABLE_LEFT);
  42. break;
  43. case InputKeyRight:
  44. start_move(game, MOVABLE_RIGHT);
  45. break;
  46. case InputKeyUp:
  47. case InputKeyDown:
  48. case InputKeyBack:
  49. case InputKeyOk:
  50. game->state = SELECT_BRICK;
  51. break;
  52. default:
  53. break;
  54. }
  55. }
  56. }
  57. //-----------------------------------------------------------------------------
  58. void events_for_paused(InputEvent* event, Game* game) {
  59. if((event->type == InputTypePress) || (event->type == InputTypeRepeat)) {
  60. switch(event->key) {
  61. case InputKeyLeft:
  62. game->menuPausedPos =
  63. (game->menuPausedPos + MENU_PAUSED_COUNT - 1) % MENU_PAUSED_COUNT;
  64. if((game->menuPausedPos == 0) && (game->undoMovable == MOVABLE_NOT_FOUND)) {
  65. game->menuPausedPos =
  66. (game->menuPausedPos + MENU_PAUSED_COUNT - 1) % MENU_PAUSED_COUNT;
  67. }
  68. break;
  69. case InputKeyRight:
  70. game->menuPausedPos = (game->menuPausedPos + 1) % MENU_PAUSED_COUNT;
  71. if((game->menuPausedPos == 0) && (game->undoMovable == MOVABLE_NOT_FOUND)) {
  72. game->menuPausedPos = (game->menuPausedPos + 1) % MENU_PAUSED_COUNT;
  73. }
  74. break;
  75. case InputKeyUp:
  76. game->menuPausedPos =
  77. (game->menuPausedPos + MENU_PAUSED_COUNT - 2) % MENU_PAUSED_COUNT;
  78. if((game->menuPausedPos == 0) && (game->undoMovable == MOVABLE_NOT_FOUND)) {
  79. game->menuPausedPos =
  80. (game->menuPausedPos + MENU_PAUSED_COUNT - 2) % MENU_PAUSED_COUNT;
  81. }
  82. break;
  83. case InputKeyDown:
  84. game->menuPausedPos = (game->menuPausedPos + 2) % MENU_PAUSED_COUNT;
  85. if((game->menuPausedPos == 0) && (game->undoMovable == MOVABLE_NOT_FOUND)) {
  86. game->menuPausedPos = (game->menuPausedPos + 2) % MENU_PAUSED_COUNT;
  87. }
  88. break;
  89. case InputKeyOk:
  90. switch(game->menuPausedPos) {
  91. case 0: // undo
  92. undo(game);
  93. break;
  94. case 1: // restart
  95. refresh_level(game);
  96. break;
  97. case 2: // menu
  98. game->mainMenuMode = CUSTOM;
  99. game->mainMenuBtn = MODE_BTN;
  100. game->state = MAIN_MENU;
  101. break;
  102. case 3: // skip
  103. start_game_at_level(game, game->currentLevel + 1);
  104. break;
  105. case 4: // count
  106. game->state = HISTOGRAM;
  107. break;
  108. case 5: // solve
  109. if(solution_will_have_penalty(game)) {
  110. game->state = SOLUTION_PROMPT;
  111. } else {
  112. start_solution(game);
  113. }
  114. break;
  115. default:
  116. break;
  117. }
  118. break;
  119. case InputKeyBack:
  120. game->state = SELECT_BRICK;
  121. break;
  122. default:
  123. break;
  124. }
  125. }
  126. }
  127. //-----------------------------------------------------------------------------
  128. void events_for_game_over(InputEvent* event, Game* game) {
  129. if((event->type == InputTypePress) || (event->type == InputTypeRepeat)) {
  130. switch(event->key) {
  131. case InputKeyBack:
  132. undo(game);
  133. break;
  134. case InputKeyOk:
  135. game->mainMenuMode = (game->hasContinue) ? CONTINUE : NEW_GAME;
  136. game->mainMenuBtn = MODE_BTN;
  137. game->state = MAIN_MENU;
  138. break;
  139. case InputKeyLeft:
  140. refresh_level(game);
  141. break;
  142. case InputKeyRight:
  143. case InputKeyUp:
  144. case InputKeyDown:
  145. default:
  146. break;
  147. }
  148. }
  149. }
  150. //-----------------------------------------------------------------------------
  151. void events_for_level_finished(InputEvent* event, Game* game) {
  152. if((event->type == InputTypePress) || (event->type == InputTypeRepeat)) {
  153. switch(event->key) {
  154. case InputKeyLeft:
  155. case InputKeyRight:
  156. case InputKeyUp:
  157. case InputKeyDown:
  158. case InputKeyBack:
  159. game->mainMenuMode = CONTINUE;
  160. game->mainMenuBtn = MODE_BTN;
  161. game->state = MAIN_MENU;
  162. break;
  163. case InputKeyOk:
  164. start_game_at_level(game, game->currentLevel + 1);
  165. break;
  166. default:
  167. break;
  168. }
  169. }
  170. }
  171. //-----------------------------------------------------------------------------
  172. void events_for_histogram(InputEvent* event, Game* game) {
  173. if((event->type == InputTypePress) || (event->type == InputTypeRepeat)) {
  174. switch(event->key) {
  175. case InputKeyLeft:
  176. case InputKeyRight:
  177. case InputKeyUp:
  178. case InputKeyDown:
  179. case InputKeyBack:
  180. case InputKeyOk:
  181. game->state = SELECT_BRICK;
  182. break;
  183. default:
  184. break;
  185. }
  186. }
  187. }
  188. //-----------------------------------------------------------------------------
  189. void events_for_main_menu(InputEvent* event, Game* game) {
  190. if((event->type == InputTypePress) || (event->type == InputTypeRepeat)) {
  191. switch(event->key) {
  192. case InputKeyOk:
  193. switch(game->mainMenuMode) {
  194. case NEW_GAME:
  195. if(game->hasContinue) {
  196. game->state = RESET_PROMPT;
  197. } else {
  198. new_game(game);
  199. }
  200. break;
  201. case CUSTOM:
  202. switch(game->mainMenuBtn) {
  203. case LEVELSET_BTN:
  204. case LEVELNO_BTN:
  205. if(game->mainMenuInfo) {
  206. game->mainMenuInfo = false;
  207. load_gameset_if_needed(game, game->selectedSet);
  208. start_game_at_level(game, game->selectedLevel);
  209. } else {
  210. game->mainMenuInfo = true;
  211. }
  212. break;
  213. default:
  214. case MODE_BTN:
  215. load_gameset_if_needed(game, game->selectedSet);
  216. start_game_at_level(game, game->selectedLevel);
  217. break;
  218. }
  219. break;
  220. case CONTINUE:
  221. default:
  222. load_gameset_if_needed(game, game->continueSet);
  223. start_game_at_level(game, game->continueLevel + 1);
  224. break;
  225. }
  226. break;
  227. case InputKeyLeft:
  228. if(game->mainMenuInfo) return;
  229. switch(game->mainMenuBtn) {
  230. case LEVELSET_BTN:
  231. game->setPos = (game->setPos > 0) ? game->setPos - 1 : game->setCount - 1;
  232. furi_string_set(game->selectedSet, level_on_pos(game, game->setPos));
  233. load_gameset_if_needed(game, game->selectedSet);
  234. game->selectedLevel = 0;
  235. break;
  236. case LEVELNO_BTN:
  237. game->selectedLevel = (game->selectedLevel > 0) ? game->selectedLevel - 1 :
  238. game->levelSet->maxLevel - 1;
  239. break;
  240. case MODE_BTN:
  241. default:
  242. if(game->mainMenuMode == CUSTOM) {
  243. game->mainMenuMode = game->hasContinue ? CONTINUE : NEW_GAME;
  244. } else if(game->mainMenuMode == CONTINUE) {
  245. game->mainMenuMode = NEW_GAME;
  246. } else {
  247. game->mainMenuMode = CUSTOM;
  248. }
  249. break;
  250. }
  251. break;
  252. case InputKeyRight:
  253. if(game->mainMenuInfo) return;
  254. switch(game->mainMenuBtn) {
  255. case LEVELSET_BTN:
  256. game->setPos = (game->setPos < game->setCount - 1) ? game->setPos + 1 : 0;
  257. furi_string_set(game->selectedSet, level_on_pos(game, game->setPos));
  258. load_gameset_if_needed(game, game->selectedSet);
  259. game->selectedLevel = 0;
  260. break;
  261. case LEVELNO_BTN:
  262. game->selectedLevel = (game->selectedLevel < (game->levelSet->maxLevel - 1)) ?
  263. game->selectedLevel + 1 :
  264. 0;
  265. break;
  266. case MODE_BTN:
  267. default:
  268. if(game->mainMenuMode == NEW_GAME) {
  269. game->mainMenuMode = game->hasContinue ? CONTINUE : CUSTOM;
  270. } else if(game->mainMenuMode == CONTINUE) {
  271. game->mainMenuMode = CUSTOM;
  272. } else {
  273. game->mainMenuMode = NEW_GAME;
  274. }
  275. }
  276. break;
  277. case InputKeyUp:
  278. if(game->mainMenuInfo) return;
  279. if(game->mainMenuMode == CUSTOM) {
  280. game->mainMenuBtn = (game->mainMenuBtn - 1 + MAIN_MENU_COUNT) % MAIN_MENU_COUNT;
  281. }
  282. break;
  283. case InputKeyDown:
  284. if(game->mainMenuInfo) return;
  285. if(game->mainMenuMode == CUSTOM) {
  286. game->mainMenuBtn = (game->mainMenuBtn + 1 + MAIN_MENU_COUNT) % MAIN_MENU_COUNT;
  287. }
  288. break;
  289. case InputKeyBack:
  290. if(game->mainMenuInfo) {
  291. game->mainMenuInfo = false;
  292. } else {
  293. game->state = ABOUT;
  294. }
  295. default:
  296. break;
  297. }
  298. }
  299. }
  300. //-----------------------------------------------------------------------------
  301. void events_for_intro(InputEvent* event, Game* game) {
  302. if((event->type == InputTypePress) || (event->type == InputTypeRepeat)) {
  303. switch(event->key) {
  304. case InputKeyOk:
  305. case InputKeyLeft:
  306. case InputKeyRight:
  307. case InputKeyUp:
  308. case InputKeyDown:
  309. case InputKeyBack:
  310. game->state = MAIN_MENU;
  311. default:
  312. break;
  313. }
  314. }
  315. }
  316. //-----------------------------------------------------------------------------
  317. void events_for_about(InputEvent* event, Game* game) {
  318. if((event->type == InputTypePress) || (event->type == InputTypeRepeat)) {
  319. switch(event->key) {
  320. case InputKeyOk:
  321. // handled on root level - exit
  322. // see: game_vexed.c
  323. break;
  324. case InputKeyLeft:
  325. case InputKeyRight:
  326. case InputKeyUp:
  327. case InputKeyDown:
  328. case InputKeyBack:
  329. game->state = MAIN_MENU;
  330. default:
  331. break;
  332. }
  333. }
  334. }
  335. //-----------------------------------------------------------------------------
  336. void events_for_solution_prompt(InputEvent* event, Game* game) {
  337. if((event->type == InputTypePress) || (event->type == InputTypeRepeat)) {
  338. switch(event->key) {
  339. case InputKeyOk:
  340. start_solution(game);
  341. break;
  342. case InputKeyLeft:
  343. case InputKeyRight:
  344. case InputKeyUp:
  345. case InputKeyDown:
  346. case InputKeyBack:
  347. game->state = SELECT_BRICK;
  348. default:
  349. break;
  350. }
  351. }
  352. }
  353. //-----------------------------------------------------------------------------
  354. void events_for_solution_select(InputEvent* event, Game* game) {
  355. if((event->type == InputTypePress) || (event->type == InputTypeRepeat)) {
  356. switch(event->key) {
  357. case InputKeyUp:
  358. case InputKeyDown:
  359. break;
  360. case InputKeyOk:
  361. case InputKeyLeft:
  362. case InputKeyRight:
  363. case InputKeyBack:
  364. end_solution(game);
  365. default:
  366. break;
  367. }
  368. }
  369. }
  370. //-----------------------------------------------------------------------------
  371. void events_for_reset(InputEvent* event, Game* game) {
  372. if((event->type == InputTypePress) || (event->type == InputTypeRepeat)) {
  373. switch(event->key) {
  374. case InputKeyOk:
  375. new_game(game);
  376. break;
  377. case InputKeyLeft:
  378. case InputKeyRight:
  379. case InputKeyUp:
  380. case InputKeyDown:
  381. case InputKeyBack:
  382. game->state = MAIN_MENU;
  383. default:
  384. break;
  385. }
  386. }
  387. }
  388. //-----------------------------------------------------------------------------
  389. void events_for_invalid(InputEvent* event, Game* game) {
  390. if((event->type == InputTypePress) || (event->type == InputTypeRepeat)) {
  391. switch(event->key) {
  392. case InputKeyOk:
  393. case InputKeyLeft:
  394. case InputKeyRight:
  395. case InputKeyUp:
  396. case InputKeyDown:
  397. case InputKeyBack:
  398. game->state = MAIN_MENU;
  399. default:
  400. break;
  401. }
  402. }
  403. }
  404. //-----------------------------------------------------------------------------
  405. void events_for_game(InputEvent* event, Game* game) {
  406. switch(game->state) {
  407. case MAIN_MENU:
  408. events_for_main_menu(event, game);
  409. break;
  410. case ABOUT:
  411. events_for_about(event, game);
  412. break;
  413. case RESET_PROMPT:
  414. events_for_reset(event, game);
  415. break;
  416. case INVALID_PROMPT:
  417. events_for_invalid(event, game);
  418. break;
  419. case INTRO:
  420. events_for_intro(event, game);
  421. break;
  422. case SELECT_BRICK:
  423. events_for_selection(event, game);
  424. break;
  425. case SELECT_DIRECTION:
  426. events_for_direction(event, game);
  427. break;
  428. case PAUSED:
  429. events_for_paused(event, game);
  430. break;
  431. case HISTOGRAM:
  432. events_for_histogram(event, game);
  433. break;
  434. case SOLUTION_PROMPT:
  435. events_for_solution_prompt(event, game);
  436. break;
  437. case SOLUTION_SELECT:
  438. events_for_solution_select(event, game);
  439. break;
  440. case GAME_OVER:
  441. events_for_game_over(event, game);
  442. break;
  443. case LEVEL_FINISHED:
  444. events_for_level_finished(event, game);
  445. break;
  446. case MOVE_SIDES:
  447. case MOVE_GRAVITY:
  448. case EXPLODE:
  449. if(game->solutionMode) {
  450. events_for_solution_select(event, game);
  451. }
  452. default:
  453. break;
  454. }
  455. }