solitaire.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. #include <furi.h>
  2. #include <notification/notification.h>
  3. #include <notification/notification_messages.h>
  4. #include "Game.h"
  5. typedef enum {
  6. EventTypeTick,
  7. EventTypeKey,
  8. } EventType;
  9. typedef struct {
  10. EventType type;
  11. InputEvent *input;
  12. } AppEvent;
  13. static FuriMutex *mutex;
  14. static void input_callback(InputEvent *input_event, FuriMessageQueue *event_queue) {
  15. furi_assert(event_queue);
  16. AppEvent event = {.type = EventTypeKey, .input = input_event};
  17. furi_message_queue_put(event_queue, &event, FuriWaitForever);
  18. }
  19. static void update_timer_callback(FuriMessageQueue *event_queue) {
  20. furi_assert(event_queue);
  21. AppEvent event = {.type = EventTypeTick, .input=nullptr};
  22. furi_message_queue_put(event_queue, &event, 0);
  23. }
  24. static void render_callback(Canvas *const canvas, void *ctx) {
  25. Game *g = (Game *) ctx;
  26. auto status = furi_mutex_acquire(mutex, 25);
  27. if (g == nullptr || status != FuriStatusOk) return;
  28. g->Render(canvas);
  29. UNUSED(canvas);
  30. UNUSED(g);
  31. furi_mutex_release(mutex);
  32. }
  33. #ifdef __cplusplus
  34. extern "C"
  35. {
  36. #endif
  37. int32_t solitaire_app(void *p) {
  38. UNUSED(p);
  39. int32_t return_code = 0;
  40. Game *game = new Game;
  41. FURI_LOG_D("LOAD", "START");
  42. FuriMessageQueue *event_queue = furi_message_queue_alloc(8, sizeof(AppEvent));
  43. FURI_LOG_D("LOAD", "QUEUE");
  44. FURI_LOG_D("LOAD", "GAME");
  45. mutex = furi_mutex_alloc(FuriMutexTypeNormal);
  46. if (mutex) {
  47. FURI_LOG_D("LOAD", "ALLOC");
  48. bool processing = true;
  49. auto *notification = static_cast<NotificationApp *>(furi_record_open(RECORD_NOTIFICATION));
  50. notification_message_block(notification, &sequence_display_backlight_enforce_on);
  51. ViewPort *view_port = view_port_alloc();
  52. view_port_draw_callback_set(view_port, render_callback, game);
  53. view_port_input_callback_set(view_port, input_callback, event_queue);
  54. FuriTimer *timer = furi_timer_alloc(update_timer_callback, FuriTimerTypePeriodic, event_queue);
  55. furi_timer_start(timer, furi_kernel_get_tick_frequency() / 30);
  56. auto gui = static_cast<Gui *>(furi_record_open("gui"));
  57. gui_add_view_port(gui, view_port, GuiLayerFullscreen);
  58. AppEvent event;
  59. game->Reset();
  60. // game->NewRound();
  61. while (processing) {
  62. FuriStatus event_status = furi_message_queue_get(event_queue, &event, 150);
  63. furi_mutex_acquire(mutex, FuriWaitForever);
  64. if (event_status == FuriStatusOk) {
  65. if (event.type == EventTypeKey) {
  66. if (event.input->type == InputTypeLong) {
  67. switch (event.input->key) {
  68. case InputKeyUp:
  69. case InputKeyDown:
  70. case InputKeyRight:
  71. case InputKeyLeft:
  72. case InputKeyOk:
  73. game->LongPress(event.input->key);
  74. break;
  75. case InputKeyBack:
  76. processing = false;
  77. return_code = 1;
  78. default:
  79. break;
  80. }
  81. } else if (event.input->type == InputTypePress) {
  82. switch (event.input->key) {
  83. case InputKeyUp:
  84. case InputKeyDown:
  85. case InputKeyRight:
  86. case InputKeyLeft:
  87. case InputKeyOk:
  88. game->Press(event.input->key);
  89. break;
  90. default:
  91. break;
  92. }
  93. }
  94. } else if (event.type == EventTypeTick) {
  95. game->Update(notification);
  96. }
  97. }
  98. view_port_update(view_port);
  99. furi_mutex_release(mutex);
  100. }
  101. notification_message_block(notification, &sequence_display_backlight_enforce_auto);
  102. furi_timer_free(timer);
  103. view_port_enabled_set(view_port, false);
  104. gui_remove_view_port(gui, view_port);
  105. furi_record_close(RECORD_GUI);
  106. furi_record_close(RECORD_NOTIFICATION);
  107. view_port_free(view_port);
  108. } else {
  109. FURI_LOG_E("APP", "cannot create mutex\r\n");
  110. return_code = 255;
  111. }
  112. delete game;
  113. furi_mutex_free(mutex);
  114. furi_message_queue_free(event_queue);
  115. return return_code;
  116. }
  117. #ifdef __cplusplus
  118. }
  119. #endif