ocarina.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. #include <furi.h>
  2. #include <furi_hal.h>
  3. #include <gui/gui.h>
  4. #include <input/input.h>
  5. #include <stdlib.h>
  6. #define NOTE_UP 587.33f
  7. #define NOTE_LEFT 493.88f
  8. #define NOTE_RIGHT 440.00f
  9. #define NOTE_DOWN 349.23
  10. #define NOTE_OK 293.66f
  11. typedef struct {
  12. FuriMutex* model_mutex;
  13. FuriMessageQueue* event_queue;
  14. ViewPort* view_port;
  15. Gui* gui;
  16. } Ocarina;
  17. void draw_callback(Canvas* canvas, void* ctx) {
  18. Ocarina* ocarina = ctx;
  19. furi_check(furi_mutex_acquire(ocarina->model_mutex, FuriWaitForever) == FuriStatusOk);
  20. //canvas_draw_box(canvas, ocarina->model->x, ocarina->model->y, 4, 4);
  21. canvas_draw_frame(canvas, 0, 0, 128, 64);
  22. canvas_draw_str(canvas, 50, 10, "Ocarina");
  23. canvas_draw_str(canvas, 30, 20, "OK button for A");
  24. furi_mutex_release(ocarina->model_mutex);
  25. }
  26. void input_callback(InputEvent* input, void* ctx) {
  27. Ocarina* ocarina = ctx;
  28. // Puts input onto event queue with priority 0, and waits until completion.
  29. furi_message_queue_put(ocarina->event_queue, input, FuriWaitForever);
  30. }
  31. Ocarina* ocarina_alloc() {
  32. Ocarina* instance = malloc(sizeof(Ocarina));
  33. instance->model_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
  34. instance->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
  35. instance->view_port = view_port_alloc();
  36. view_port_draw_callback_set(instance->view_port, draw_callback, instance);
  37. view_port_input_callback_set(instance->view_port, input_callback, instance);
  38. instance->gui = furi_record_open("gui");
  39. gui_add_view_port(instance->gui, instance->view_port, GuiLayerFullscreen);
  40. return instance;
  41. }
  42. void ocarina_free(Ocarina* instance) {
  43. view_port_enabled_set(instance->view_port, false); // Disabsles our ViewPort
  44. gui_remove_view_port(instance->gui, instance->view_port); // Removes our ViewPort from the Gui
  45. furi_record_close("gui"); // Closes the gui record
  46. view_port_free(instance->view_port); // Frees memory allocated by view_port_alloc
  47. furi_message_queue_free(instance->event_queue);
  48. furi_mutex_free(instance->model_mutex);
  49. furi_hal_speaker_stop();
  50. free(instance);
  51. }
  52. int32_t ocarina_app(void* p) {
  53. UNUSED(p);
  54. Ocarina* ocarina = ocarina_alloc();
  55. InputEvent event;
  56. for(bool processing = true; processing;) {
  57. // Pops a message off the queue and stores it in `event`.
  58. // No message priority denoted by NULL, and 100 ticks of timeout.
  59. FuriStatus status = furi_message_queue_get(ocarina->event_queue, &event, 100);
  60. furi_check(furi_mutex_acquire(ocarina->model_mutex, FuriWaitForever) == FuriStatusOk);
  61. float volume = 1.0f;
  62. if(status == FuriStatusOk) {
  63. if(event.type == InputTypePress) {
  64. switch(event.key) {
  65. case InputKeyUp:
  66. furi_hal_speaker_start(NOTE_UP, volume);
  67. break;
  68. case InputKeyDown:
  69. furi_hal_speaker_start(NOTE_DOWN, volume);
  70. break;
  71. case InputKeyLeft:
  72. furi_hal_speaker_start(NOTE_LEFT, volume);
  73. break;
  74. case InputKeyRight:
  75. furi_hal_speaker_start(NOTE_RIGHT, volume);
  76. break;
  77. case InputKeyOk:
  78. furi_hal_speaker_start(NOTE_OK, volume);
  79. break;
  80. case InputKeyBack:
  81. processing = false;
  82. break;
  83. }
  84. } else if (event.type == InputTypeRelease) {
  85. furi_hal_speaker_stop();
  86. }
  87. }
  88. furi_mutex_release(ocarina->model_mutex);
  89. view_port_update(ocarina->view_port); // signals our draw callback
  90. }
  91. ocarina_free(ocarina);
  92. return 0;
  93. }