#include "input_event.h" #include "diskop.h" #include #define AUDIO_MODES_COUNT 2 void return_from_keyboard_callback(void* ctx) { FlizzerTrackerApp* tracker = (FlizzerTrackerApp*)ctx; if(!tracker->is_loading && !tracker->is_saving && !tracker->is_loading_instrument && !tracker->is_saving_instrument) { uint8_t string_length = 0; char* string = NULL; if(tracker->focus == EDIT_SONGINFO && tracker->mode == PATTERN_VIEW) { switch(tracker->selected_param) { case SI_SONGNAME: { string_length = MUS_SONG_NAME_LEN; string = (char*)&tracker->song.song_name; break; } case SI_INSTRUMENTNAME: { string_length = MUS_INST_NAME_LEN; string = (char*)&tracker->song.instrument[tracker->current_instrument]->name; break; } } } if(tracker->focus == EDIT_INSTRUMENT && tracker->mode == INST_EDITOR_VIEW) { switch(tracker->selected_param) { case INST_INSTRUMENTNAME: { string_length = MUS_INST_NAME_LEN; string = (char*)&tracker->song.instrument[tracker->current_instrument]->name; break; } } } if(string == NULL || string_length == 0) return; for(uint8_t i = 0; i < string_length; i++) // I tinyfied the font by deleting lowercase chars, and I don't like the lowercase chars of any 3x5 pixels font { string[i] = toupper(string[i]); } } view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER); if(tracker->is_saving) { stop_song(tracker); tracker->filepath = furi_string_alloc(); furi_string_cat_printf( tracker->filepath, "%s/%s%s", FLIZZER_TRACKER_FOLDER, tracker->filename, SONG_FILE_EXT); if(storage_file_exists(tracker->storage, furi_string_get_cstr(tracker->filepath))) { view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_FILE_OVERWRITE); return; } else { save_song(tracker, tracker->filepath); } } if(tracker->is_saving_instrument) { stop_song(tracker); tracker->filepath = furi_string_alloc(); furi_string_cat_printf( tracker->filepath, "%s/%s%s", FLIZZER_TRACKER_INSTRUMENTS_FOLDER, tracker->filename, INST_FILE_EXT); if(storage_file_exists(tracker->storage, furi_string_get_cstr(tracker->filepath))) { view_dispatcher_switch_to_view( tracker->view_dispatcher, VIEW_INSTRUMENT_FILE_OVERWRITE); return; } else { save_instrument(tracker, tracker->filepath); } } } void overwrite_file_widget_yes_input_callback(GuiButtonType result, InputType type, void* ctx) { UNUSED(result); FlizzerTrackerApp* tracker = (FlizzerTrackerApp*)ctx; if(type == InputTypeShort) { tracker->is_saving = true; view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER); save_song(tracker, tracker->filepath); } } void overwrite_file_widget_no_input_callback(GuiButtonType result, InputType type, void* ctx) { UNUSED(result); FlizzerTrackerApp* tracker = (FlizzerTrackerApp*)ctx; if(type == InputTypeShort) { tracker->is_saving = false; furi_string_free(tracker->filepath); view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER); } } void overwrite_instrument_file_widget_yes_input_callback( GuiButtonType result, InputType type, void* ctx) { UNUSED(result); FlizzerTrackerApp* tracker = (FlizzerTrackerApp*)ctx; if(type == InputTypeShort) { tracker->is_saving_instrument = true; view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER); // save_song(tracker, tracker->filepath); static FlizzerTrackerEvent event = { .type = EventTypeSaveInstrument, .input = {{0}}, .period = 0}; furi_message_queue_put(tracker->event_queue, &event, FuriWaitForever); } } void overwrite_instrument_file_widget_no_input_callback( GuiButtonType result, InputType type, void* ctx) { UNUSED(result); FlizzerTrackerApp* tracker = (FlizzerTrackerApp*)ctx; if(type == InputTypeShort) { tracker->is_saving_instrument = false; furi_string_free(tracker->filepath); view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER); } } uint32_t submenu_settings_exit_callback(void* context) { UNUSED(context); return VIEW_SUBMENU_PATTERN; } uint32_t submenu_exit_callback(void* context) { UNUSED(context); return VIEW_TRACKER; } void submenu_callback(void* context, uint32_t index) { FlizzerTrackerApp* tracker = (FlizzerTrackerApp*)context; switch(tracker->mode) { case PATTERN_VIEW: { switch(index) { case SUBMENU_PATTERN_EXIT: { tracker->quit = true; view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER); view_dispatcher_stop(tracker->view_dispatcher); break; } case SUBMENU_PATTERN_HELP: { tracker->showing_help = true; view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER); break; } case SUBMENU_PATTERN_SAVE_SONG: { text_input_set_header_text(tracker->text_input, "Song filename:"); memset(&tracker->filename, 0, FILE_NAME_LEN); text_input_set_result_callback( tracker->text_input, return_from_keyboard_callback, tracker, (char*)&tracker->filename, FILE_NAME_LEN, true); tracker->is_saving = true; view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_KEYBOARD); break; } case SUBMENU_PATTERN_LOAD_SONG: { view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER); stop_song(tracker); tracker->tracker_engine.sequence_position = tracker->tracker_engine.pattern_position = tracker->current_instrument = 0; tracker->dialogs = furi_record_open(RECORD_DIALOGS); tracker->is_loading = true; FuriString* path; path = furi_string_alloc(); furi_string_set(path, FLIZZER_TRACKER_FOLDER); DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options( &browser_options, SONG_FILE_EXT, &I_flizzer_tracker_module); browser_options.base_path = FLIZZER_TRACKER_FOLDER; browser_options.hide_ext = false; bool ret = dialog_file_browser_show(tracker->dialogs, path, path, &browser_options); furi_record_close(RECORD_DIALOGS); const char* cpath = furi_string_get_cstr(path); if(ret && strcmp(&cpath[strlen(cpath) - 4], SONG_FILE_EXT) == 0) { bool result = load_song_util(tracker, path); UNUSED(result); } else { furi_string_free(path); tracker->is_loading = false; } break; } case SUBMENU_PATTERN_SETTINGS: { view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_SETTINGS); break; } default: break; } break; } case INST_EDITOR_VIEW: { switch(index) { case SUBMENU_INSTRUMENT_EXIT: { tracker->quit = true; view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER); view_dispatcher_stop(tracker->view_dispatcher); break; } case SUBMENU_INSTRUMENT_SAVE: { text_input_set_header_text(tracker->text_input, "Instrument filename:"); memset(&tracker->filename, 0, FILE_NAME_LEN); text_input_set_result_callback( tracker->text_input, return_from_keyboard_callback, tracker, (char*)&tracker->filename, FILE_NAME_LEN, true); tracker->is_saving_instrument = true; view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_KEYBOARD); break; } case SUBMENU_INSTRUMENT_LOAD: { view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER); stop_song(tracker); tracker->dialogs = furi_record_open(RECORD_DIALOGS); tracker->is_loading_instrument = true; FuriString* path; path = furi_string_alloc(); furi_string_set(path, FLIZZER_TRACKER_INSTRUMENTS_FOLDER); DialogsFileBrowserOptions browser_options; dialog_file_browser_set_basic_options( &browser_options, INST_FILE_EXT, &I_flizzer_tracker_instrument); browser_options.base_path = FLIZZER_TRACKER_FOLDER; browser_options.hide_ext = false; bool ret = dialog_file_browser_show(tracker->dialogs, path, path, &browser_options); furi_record_close(RECORD_DIALOGS); const char* cpath = furi_string_get_cstr(path); if(ret && strcmp(&cpath[strlen(cpath) - 4], INST_FILE_EXT) == 0) { bool result = load_instrument_util(tracker, path); UNUSED(result); } else { furi_string_free(path); tracker->is_loading = false; } break; } default: break; } break; } default: break; } } void submenu_copypaste_callback(void* context, uint32_t index) { FlizzerTrackerApp* tracker = (FlizzerTrackerApp*)context; uint8_t sequence_position = tracker->tracker_engine.sequence_position; uint8_t current_pattern_index = tracker->tracker_engine.song->sequence.sequence_step[sequence_position] .pattern_indices[tracker->current_channel]; TrackerSongPattern* source_pattern; if(tracker->source_pattern_index >= 0) { source_pattern = &tracker->song.pattern[tracker->source_pattern_index]; } TrackerSongPattern* current_pattern = &tracker->song.pattern[current_pattern_index]; uint16_t pattern_length = tracker->tracker_engine.song->pattern_length; switch(index) { case SUBMENU_PATTERN_COPYPASTE_COPY: { tracker->source_pattern_index = current_pattern_index; tracker->cut_pattern = false; break; } case SUBMENU_PATTERN_COPYPASTE_PASTE: { if(tracker->source_pattern_index >= 0) { memcpy( current_pattern->step, source_pattern->step, sizeof(TrackerSongPatternStep) * pattern_length); if(tracker->cut_pattern) { set_empty_pattern(source_pattern, pattern_length); tracker->cut_pattern = false; } } break; } case SUBMENU_PATTERN_COPYPASTE_CUT: { tracker->source_pattern_index = current_pattern_index; tracker->cut_pattern = true; break; } case SUBMENU_PATTERN_COPYPASTE_CLEAR: { set_empty_pattern(current_pattern, pattern_length); break; } default: break; } view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER); } void audio_output_changed_callback(VariableItem* item) { FlizzerTrackerApp* tracker = (FlizzerTrackerApp*)variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); variable_item_set_current_value_text(item, audio_modes_text[(index > 1 ? 1 : index)]); if(tracker) { tracker->external_audio = (bool)index; tracker->external_audio = audio_modes_values[(index > 1 ? 1 : index)]; sound_engine_PWM_timer_init(tracker->external_audio); tracker->sound_engine.external_audio_output = tracker->external_audio; } } void cycle_focus(FlizzerTrackerApp* tracker) { switch(tracker->mode) { case PATTERN_VIEW: { tracker->focus++; if(tracker->focus > EDIT_SONGINFO) { tracker->focus = EDIT_PATTERN; } break; } case INST_EDITOR_VIEW: { tracker->focus++; if(tracker->focus > EDIT_PROGRAM) { tracker->focus = EDIT_INSTRUMENT; if(tracker->current_digit > 1) { tracker->current_digit = 1; } } break; } default: break; } } void cycle_view(FlizzerTrackerApp* tracker) { if(tracker->mode == PATTERN_VIEW) { tracker->mode = INST_EDITOR_VIEW; tracker->focus = EDIT_INSTRUMENT; tracker->selected_param = 0; tracker->current_digit = 0; return; } if(tracker->mode == INST_EDITOR_VIEW) { tracker->mode = PATTERN_VIEW; tracker->focus = EDIT_PATTERN; if(tracker->tracker_engine.song == NULL) { stop_song(tracker); tracker_engine_set_song(&tracker->tracker_engine, &tracker->song); } tracker->selected_param = 0; tracker->current_digit = 0; return; } } void process_input_event(FlizzerTrackerApp* tracker, FlizzerTrackerEvent* event) { if(event->input.key == InputKeyBack && event->input.type == InputTypeShort && tracker->showing_help) { tracker->showing_help = false; return; } if(tracker->showing_help || tracker->is_loading || tracker->is_saving || tracker->is_loading_instrument || tracker->is_saving_instrument) return; //do not react until these are finished if(event->input.key == InputKeyBack && event->input.type == InputTypeShort && event->period > 0 && event->period < 300 && !(tracker->editing)) { cycle_view(tracker); stop_song(tracker); return; } else if( event->input.key == InputKeyBack && event->input.type == InputTypeShort && !(tracker->editing)) { cycle_focus(tracker); //stop_song(tracker); return; } if(event->input.key == InputKeyBack && event->input.type == InputTypeLong) { switch(tracker->mode) { case PATTERN_VIEW: { if(tracker->focus == EDIT_PATTERN) { submenu_set_selected_item( tracker->pattern_copypaste_submenu, SUBMENU_PATTERN_COPYPASTE_COPY); view_dispatcher_switch_to_view( tracker->view_dispatcher, VIEW_SUBMENU_PATTERN_COPYPASTE); } else { submenu_set_selected_item(tracker->pattern_submenu, SUBMENU_PATTERN_LOAD_SONG); view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_SUBMENU_PATTERN); } break; } case INST_EDITOR_VIEW: { submenu_set_selected_item(tracker->instrument_submenu, SUBMENU_INSTRUMENT_LOAD); view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_SUBMENU_INSTRUMENT); break; } default: break; } return; } switch(tracker->focus) { case EDIT_PATTERN: { pattern_edit_event(tracker, event); break; } case EDIT_SEQUENCE: { sequence_edit_event(tracker, event); break; } case EDIT_SONGINFO: { songinfo_edit_event(tracker, event); break; } case EDIT_INSTRUMENT: { instrument_edit_event(tracker, event); break; } case EDIT_PROGRAM: { instrument_program_edit_event(tracker, event); break; } default: break; } }