engine.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. #include <furi.h>
  2. #include <api-hal.h>
  3. #include "dolphin_scene/dolphin_scene.h"
  4. static SceneAppGui* scene_app_gui = NULL;
  5. static ValueMutex* scene_state_mutex = NULL;
  6. static void dolphin_engine_tick_callback(void* p) {
  7. osMessageQueueId_t event_queue = p;
  8. AppEvent event;
  9. event.type = EventTypeTick;
  10. osMessageQueuePut(event_queue, (void*)&event, 0, 0);
  11. }
  12. static void dolphin_engine_input_callback(InputEvent* input_event, void* ctx) {
  13. osMessageQueueId_t event_queue = ctx;
  14. AppEvent event;
  15. event.type = EventTypeKey;
  16. event.value.input = *input_event;
  17. osMessageQueuePut(event_queue, (void*)&event, 0, osWaitForever);
  18. }
  19. void scene_alloc() {
  20. printf("scene_alloc: start\r\n");
  21. furi_assert(scene_app_gui == NULL);
  22. furi_assert(scene_state_mutex == NULL);
  23. // SceneAppGui
  24. scene_app_gui = furi_alloc(sizeof(SceneAppGui));
  25. scene_app_gui->mqueue = osMessageQueueNew(2, sizeof(AppEvent), NULL);
  26. scene_app_gui->gui = furi_record_open("gui");
  27. scene_app_gui->view_port = view_port_alloc();
  28. scene_app_gui->timer =
  29. osTimerNew(dolphin_engine_tick_callback, osTimerPeriodic, scene_app_gui->mqueue, NULL);
  30. printf("scene_alloc: timer %p\r\n", scene_app_gui->timer);
  31. // Scene State
  32. SceneState* scene_state = furi_alloc(sizeof(SceneState));
  33. scene_state->player.y = DOLPHIN_DEFAULT_Y;
  34. scene_state->player.x = DOLPHIN_CENTER;
  35. scene_state->player_global.x = random() % WORLD_WIDTH / 4;
  36. scene_state->screen.x = scene_state->player.x;
  37. scene_state->screen.y = scene_state->player.y;
  38. scene_state_mutex = furi_alloc(sizeof(ValueMutex));
  39. furi_check(init_mutex(scene_state_mutex, scene_state, sizeof(SceneState)));
  40. // Open GUI and register fullscreen view_port
  41. view_port_draw_callback_set(scene_app_gui->view_port, dolphin_scene_redraw, scene_state_mutex);
  42. view_port_input_callback_set(
  43. scene_app_gui->view_port, dolphin_engine_input_callback, scene_app_gui->mqueue);
  44. gui_add_view_port(scene_app_gui->gui, scene_app_gui->view_port, GuiLayerMain);
  45. view_port_enabled_set(scene_app_gui->view_port, true);
  46. printf("scene_alloc: complete\r\n");
  47. }
  48. void scene_free() {
  49. printf("scene_free: start\r\n");
  50. view_port_enabled_set(scene_app_gui->view_port, false);
  51. gui_remove_view_port(scene_app_gui->gui, scene_app_gui->view_port);
  52. SceneState* scene_state = (SceneState*)acquire_mutex_block(scene_state_mutex);
  53. furi_assert(scene_state);
  54. free(scene_state);
  55. release_mutex(scene_state_mutex, scene_state);
  56. delete_mutex(scene_state_mutex);
  57. free(scene_state_mutex);
  58. scene_state_mutex = NULL;
  59. furi_check(osTimerDelete(scene_app_gui->timer) == osOK);
  60. furi_record_close("gui");
  61. view_port_free(scene_app_gui->view_port);
  62. furi_check(osMessageQueueDelete(scene_app_gui->mqueue) == osOK);
  63. free(scene_app_gui);
  64. scene_app_gui = NULL;
  65. printf("scene_free: complete\r\n");
  66. }
  67. int32_t dolphin_scene(void* p) {
  68. api_hal_power_insomnia_enter();
  69. scene_alloc();
  70. osTimerStart(scene_app_gui->timer, 40);
  71. uint32_t t = xTaskGetTickCount();
  72. uint32_t prev_t = 0;
  73. while(1) {
  74. AppEvent event;
  75. if(osMessageQueueGet(scene_app_gui->mqueue, &event, 0, osWaitForever) == osOK) {
  76. SceneState* scene_state = (SceneState*)acquire_mutex_block(scene_state_mutex);
  77. if(event.type == EventTypeTick) {
  78. t = xTaskGetTickCount();
  79. dolphin_scene_tick_handler(scene_state, t, (t - prev_t) % 1024);
  80. prev_t = t;
  81. } else if(event.type == EventTypeKey) {
  82. if(event.value.input.key == InputKeyBack &&
  83. event.value.input.type == InputTypeShort) {
  84. release_mutex(scene_state_mutex, scene_state);
  85. break;
  86. } else {
  87. dolphin_scene_handle_input(scene_state, &event.value.input);
  88. }
  89. }
  90. release_mutex(scene_state_mutex, scene_state);
  91. view_port_update(scene_app_gui->view_port);
  92. }
  93. }
  94. osTimerStop(scene_app_gui->timer);
  95. scene_free();
  96. api_hal_power_insomnia_exit();
  97. return 0;
  98. }