init_deinit.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. #include "init_deinit.h"
  2. #include "input_event.h"
  3. #include "diskop.h"
  4. #define AUDIO_MODES_COUNT 2
  5. TrackerView* tracker_view_alloc(FlizzerTrackerApp* tracker) {
  6. TrackerView* tracker_view = malloc(sizeof(TrackerView));
  7. tracker_view->view = view_alloc();
  8. tracker_view->context = tracker;
  9. view_set_context(tracker_view->view, tracker_view);
  10. view_allocate_model(tracker_view->view, ViewModelTypeLocking, sizeof(TrackerViewModel));
  11. view_set_draw_callback(tracker_view->view, draw_callback);
  12. view_set_input_callback(tracker_view->view, input_callback);
  13. return tracker_view;
  14. }
  15. void tracker_view_free(TrackerView* tracker_view) {
  16. furi_assert(tracker_view);
  17. view_free(tracker_view->view);
  18. free(tracker_view);
  19. }
  20. uint8_t my_value_index_bool(
  21. const bool value,
  22. const bool values[],
  23. uint8_t
  24. values_count) // why the fuck it gives unresolved symbol if I include it from toolbox???!!!
  25. {
  26. uint8_t index = 0;
  27. for(uint8_t i = 0; i < values_count; i++) {
  28. if(value == values[i]) {
  29. index = i;
  30. break;
  31. }
  32. }
  33. return index;
  34. }
  35. FlizzerTrackerApp* init_tracker(
  36. uint32_t sample_rate,
  37. uint8_t rate,
  38. bool external_audio_output,
  39. uint32_t audio_buffer_size) {
  40. FlizzerTrackerApp* tracker = malloc(sizeof(FlizzerTrackerApp));
  41. memset(tracker, 0, sizeof(FlizzerTrackerApp));
  42. tracker->external_audio = external_audio_output;
  43. sound_engine_init(
  44. &tracker->sound_engine, sample_rate, external_audio_output, audio_buffer_size);
  45. tracker_engine_init(&tracker->tracker_engine, rate, &tracker->sound_engine);
  46. tracker->tracker_engine.song = &tracker->song;
  47. tracker->current_note = MIDDLE_C;
  48. // Очередь событий на 8 элементов размера FlizzerTrackerEvent
  49. tracker->event_queue = furi_message_queue_alloc(8, sizeof(FlizzerTrackerEvent));
  50. tracker->gui = furi_record_open(RECORD_GUI);
  51. tracker->view_dispatcher = view_dispatcher_alloc();
  52. tracker->tracker_view = tracker_view_alloc(tracker);
  53. view_dispatcher_add_view(tracker->view_dispatcher, VIEW_TRACKER, tracker->tracker_view->view);
  54. view_dispatcher_attach_to_gui(
  55. tracker->view_dispatcher, tracker->gui, ViewDispatcherTypeFullscreen);
  56. with_view_model(
  57. tracker->tracker_view->view, TrackerViewModel * model, { model->tracker = tracker; }, true);
  58. tracker->storage = furi_record_open(RECORD_STORAGE);
  59. tracker->stream = file_stream_alloc(tracker->storage);
  60. tracker->text_input = text_input_alloc();
  61. view_dispatcher_add_view(
  62. tracker->view_dispatcher, VIEW_KEYBOARD, text_input_get_view(tracker->text_input));
  63. tracker->pattern_submenu = submenu_alloc();
  64. tracker->pattern_copypaste_submenu = submenu_alloc();
  65. tracker->instrument_submenu = submenu_alloc();
  66. view_set_previous_callback(submenu_get_view(tracker->pattern_submenu), submenu_exit_callback);
  67. view_set_previous_callback(
  68. submenu_get_view(tracker->pattern_copypaste_submenu), submenu_exit_callback);
  69. view_set_previous_callback(
  70. submenu_get_view(tracker->instrument_submenu), submenu_exit_callback);
  71. submenu_add_item(
  72. tracker->pattern_submenu,
  73. "Load song",
  74. SUBMENU_PATTERN_LOAD_SONG,
  75. submenu_callback,
  76. tracker);
  77. submenu_add_item(
  78. tracker->pattern_submenu,
  79. "Save song",
  80. SUBMENU_PATTERN_SAVE_SONG,
  81. submenu_callback,
  82. tracker);
  83. submenu_add_item(
  84. tracker->pattern_submenu, "Settings", SUBMENU_PATTERN_SETTINGS, submenu_callback, tracker);
  85. submenu_add_item(
  86. tracker->pattern_submenu, "Help", SUBMENU_PATTERN_HELP, submenu_callback, tracker);
  87. submenu_add_item(
  88. tracker->pattern_submenu, "Exit", SUBMENU_PATTERN_EXIT, submenu_callback, tracker);
  89. submenu_add_item(
  90. tracker->instrument_submenu,
  91. "Load instrument",
  92. SUBMENU_INSTRUMENT_LOAD,
  93. submenu_callback,
  94. tracker);
  95. submenu_add_item(
  96. tracker->instrument_submenu,
  97. "Save instrument",
  98. SUBMENU_INSTRUMENT_SAVE,
  99. submenu_callback,
  100. tracker);
  101. submenu_add_item(
  102. tracker->instrument_submenu, "Exit", SUBMENU_INSTRUMENT_EXIT, submenu_callback, tracker);
  103. submenu_add_item(
  104. tracker->pattern_copypaste_submenu,
  105. "Copy",
  106. SUBMENU_PATTERN_COPYPASTE_COPY,
  107. submenu_copypaste_callback,
  108. tracker);
  109. submenu_add_item(
  110. tracker->pattern_copypaste_submenu,
  111. "Paste",
  112. SUBMENU_PATTERN_COPYPASTE_PASTE,
  113. submenu_copypaste_callback,
  114. tracker);
  115. submenu_add_item(
  116. tracker->pattern_copypaste_submenu,
  117. "Cut",
  118. SUBMENU_PATTERN_COPYPASTE_CUT,
  119. submenu_copypaste_callback,
  120. tracker);
  121. submenu_add_item(
  122. tracker->pattern_copypaste_submenu,
  123. "Clear",
  124. SUBMENU_PATTERN_COPYPASTE_CLEAR,
  125. submenu_copypaste_callback,
  126. tracker);
  127. view_dispatcher_add_view(
  128. tracker->view_dispatcher,
  129. VIEW_SUBMENU_PATTERN,
  130. submenu_get_view(tracker->pattern_submenu));
  131. view_dispatcher_add_view(
  132. tracker->view_dispatcher,
  133. VIEW_SUBMENU_PATTERN_COPYPASTE,
  134. submenu_get_view(tracker->pattern_copypaste_submenu));
  135. view_dispatcher_add_view(
  136. tracker->view_dispatcher,
  137. VIEW_SUBMENU_INSTRUMENT,
  138. submenu_get_view(tracker->instrument_submenu));
  139. load_config(tracker);
  140. tracker->settings_list = variable_item_list_alloc();
  141. View* view = variable_item_list_get_view(tracker->settings_list);
  142. view_set_previous_callback(view, submenu_settings_exit_callback);
  143. VariableItem* item;
  144. uint8_t value_index;
  145. item = variable_item_list_add(
  146. tracker->settings_list,
  147. "Audio output",
  148. AUDIO_MODES_COUNT,
  149. audio_output_changed_callback,
  150. tracker);
  151. value_index =
  152. my_value_index_bool(tracker->external_audio, audio_modes_values, AUDIO_MODES_COUNT);
  153. variable_item_set_current_value_index(item, value_index);
  154. variable_item_set_current_value_text(item, audio_modes_text[value_index]);
  155. view_dispatcher_add_view(tracker->view_dispatcher, VIEW_SETTINGS, view);
  156. tracker->overwrite_file_widget = widget_alloc();
  157. widget_add_button_element(
  158. tracker->overwrite_file_widget,
  159. GuiButtonTypeLeft,
  160. "No",
  161. (ButtonCallback)overwrite_file_widget_no_input_callback,
  162. tracker);
  163. widget_add_button_element(
  164. tracker->overwrite_file_widget,
  165. GuiButtonTypeRight,
  166. "Yes",
  167. (ButtonCallback)overwrite_file_widget_yes_input_callback,
  168. tracker);
  169. widget_add_text_scroll_element(
  170. tracker->overwrite_file_widget,
  171. 0,
  172. 0,
  173. 128,
  174. 64,
  175. "This song file already exists,\n do you want to overwrite it?");
  176. view_dispatcher_add_view(
  177. tracker->view_dispatcher,
  178. VIEW_FILE_OVERWRITE,
  179. widget_get_view(tracker->overwrite_file_widget));
  180. tracker->overwrite_instrument_file_widget = widget_alloc();
  181. widget_add_button_element(
  182. tracker->overwrite_instrument_file_widget,
  183. GuiButtonTypeLeft,
  184. "No",
  185. (ButtonCallback)overwrite_instrument_file_widget_no_input_callback,
  186. tracker);
  187. widget_add_button_element(
  188. tracker->overwrite_instrument_file_widget,
  189. GuiButtonTypeRight,
  190. "Yes",
  191. (ButtonCallback)overwrite_instrument_file_widget_yes_input_callback,
  192. tracker);
  193. widget_add_text_scroll_element(
  194. tracker->overwrite_instrument_file_widget,
  195. 0,
  196. 0,
  197. 128,
  198. 64,
  199. "This instrument file already\nexists, do you want to\noverwrite it?");
  200. view_dispatcher_add_view(
  201. tracker->view_dispatcher,
  202. VIEW_INSTRUMENT_FILE_OVERWRITE,
  203. widget_get_view(tracker->overwrite_instrument_file_widget));
  204. tracker->notification = furi_record_open(RECORD_NOTIFICATION);
  205. notification_message(tracker->notification, &sequence_display_backlight_enforce_on);
  206. set_default_song(tracker);
  207. tracker->focus = EDIT_SONGINFO;
  208. tracker->source_pattern_index = -1;
  209. return tracker;
  210. }
  211. void deinit_tracker(FlizzerTrackerApp* tracker) {
  212. notification_message(tracker->notification, &sequence_display_backlight_enforce_auto);
  213. furi_record_close(RECORD_NOTIFICATION);
  214. // Специальная очистка памяти, занимаемой очередью
  215. furi_message_queue_free(tracker->event_queue);
  216. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_SETTINGS);
  217. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_FILE_OVERWRITE);
  218. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_SUBMENU_INSTRUMENT);
  219. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_INSTRUMENT_FILE_OVERWRITE);
  220. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_SUBMENU_PATTERN_COPYPASTE);
  221. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_SUBMENU_PATTERN);
  222. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_KEYBOARD);
  223. view_dispatcher_remove_view(tracker->view_dispatcher, VIEW_TRACKER);
  224. text_input_free(tracker->text_input);
  225. variable_item_list_free(tracker->settings_list);
  226. submenu_free(tracker->pattern_submenu);
  227. submenu_free(tracker->pattern_copypaste_submenu);
  228. submenu_free(tracker->instrument_submenu);
  229. widget_free(tracker->overwrite_file_widget);
  230. widget_free(tracker->overwrite_instrument_file_widget);
  231. view_dispatcher_free(tracker->view_dispatcher);
  232. tracker_view_free(tracker->tracker_view);
  233. furi_record_close(RECORD_GUI);
  234. stream_free(tracker->stream);
  235. furi_record_close(RECORD_STORAGE);
  236. sound_engine_deinit(&tracker->sound_engine);
  237. if(tracker->tracker_engine.song == NULL) {
  238. tracker_engine_set_song(&tracker->tracker_engine, &tracker->song);
  239. }
  240. tracker_engine_deinit(&tracker->tracker_engine, false);
  241. free(tracker);
  242. }