game_vexed.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include <furi.h>
  2. #include <furi_hal.h>
  3. #include <furi/core/string.h>
  4. #include <gui/gui.h>
  5. #include <input/input.h>
  6. #include <stdlib.h>
  7. #include "common.h"
  8. #include "game.h"
  9. #include "utils.h"
  10. #include "load.h"
  11. #include "move.h"
  12. #include "fonts.h"
  13. #include "ui.h"
  14. #include "draw.h"
  15. #include "events.h"
  16. //-----------------------------------------------------------------------------
  17. void game_tick(void* ctx) {
  18. furi_assert(ctx);
  19. const Game* game = ctx;
  20. view_port_update(game->viewPort);
  21. }
  22. static void app_input_callback(InputEvent* input_event, void* ctx) {
  23. furi_assert(ctx);
  24. FuriMessageQueue* event_queue = ctx;
  25. furi_message_queue_put(event_queue, input_event, FuriWaitForever);
  26. }
  27. static void app_draw_callback(Canvas* canvas, void* ctx) {
  28. furi_assert(ctx);
  29. Game* game = ctx;
  30. furi_mutex_acquire(game->mutex, FuriWaitForever);
  31. draw_app(canvas, game);
  32. furi_mutex_release(game->mutex);
  33. }
  34. //-----------------------------------------------------------------------------
  35. int32_t game_vexed_app(void* p) {
  36. UNUSED(p);
  37. int error;
  38. bool running = true;
  39. bool paused = false;
  40. InputEvent event;
  41. Game* game = alloc_game_state(&error);
  42. if(error > 0) {
  43. return error;
  44. }
  45. FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
  46. // Configure view port
  47. game->viewPort = view_port_alloc();
  48. view_port_draw_callback_set(game->viewPort, app_draw_callback, game);
  49. view_port_input_callback_set(game->viewPort, app_input_callback, event_queue);
  50. // Register view port in GUI
  51. Gui* gui = furi_record_open(RECORD_GUI);
  52. gui_add_view_port(gui, game->viewPort, GuiLayerFullscreen);
  53. // Create a timer. When non-paused, it trigers UI refresh
  54. FuriTimer* timer = furi_timer_alloc(game_tick, FuriTimerTypePeriodic, game);
  55. furi_timer_start(timer, furi_kernel_get_tick_frequency() / 20);
  56. initial_load_game(game);
  57. while(running) {
  58. FuriStatus event_status = furi_message_queue_get(event_queue, &event, FuriWaitForever);
  59. if(event_status == FuriStatusOk) {
  60. furi_mutex_acquire(game->mutex, FuriWaitForever);
  61. if(((event.type == InputTypeLong) && (event.key == InputKeyBack)) ||
  62. ((game->state == ABOUT) && (event.key == InputKeyOk))) {
  63. running = false;
  64. } else {
  65. events_for_game(&event, game);
  66. }
  67. bool shouldBePaused = is_state_pause(game->state);
  68. if(paused != shouldBePaused) {
  69. paused = shouldBePaused;
  70. if(paused) {
  71. furi_timer_stop(timer);
  72. FURI_LOG_D(TAG, "PAUSE - timer stoped");
  73. } else {
  74. furi_timer_start(timer, furi_kernel_get_tick_frequency() / 20);
  75. FURI_LOG_D(TAG, "UNPAUSE - timer started");
  76. }
  77. }
  78. if(shouldBePaused) {
  79. view_port_update(game->viewPort);
  80. }
  81. furi_mutex_release(game->mutex);
  82. }
  83. }
  84. furi_timer_free(timer);
  85. view_port_enabled_set(game->viewPort, false);
  86. gui_remove_view_port(gui, game->viewPort);
  87. furi_message_queue_free(event_queue);
  88. free_game_state(game);
  89. furi_record_close(RECORD_GUI);
  90. return 0;
  91. }