Dateien hochladen nach „“

added most of the menu functions. the Drums_Pan func is still buggy
pull/59/head
positionhigh 3 years ago
parent d89cea4480
commit cf10692898
  1. 387
      UI.hpp
  2. 12
      UI_FX_T4.h
  3. 8
      UI_NO_FX.h

387
UI.hpp

@ -67,6 +67,7 @@ extern char receive_bank_filename[FILENAME_LEN];
extern uint8_t seq_data[4][16];
extern uint8_t seq_patternchain[4][4];
extern uint8_t seq_step_timer;
extern uint8_t seq_chain_lenght;
extern bool seq_running;
extern bool seq_recording;
uint8_t seq_active_function = 99;
@ -74,11 +75,11 @@ uint8_t activesample;
extern uint8_t seq_active_track;
extern elapsedMillis seq_millis_timer;
extern uint8_t seq_menu;
extern bool seq_button_r;
extern uint8_t seq_chain_select_menu;
extern uint8_t seq_chain_active_menu;
extern uint8_t seq_chain_active_chainstep; //for editor
extern uint8_t seq_chain_active_step;
extern int seq_transpose;
#if NUM_DRUMS > 0
#include "drums.h"
extern drum_config_t drum_config[DRUM_MAX_INSTRUMENTS + 1];
@ -135,6 +136,10 @@ const char accepted_chars[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-abcdefghijk
uint8_t active_perform_page = 1;
uint8_t orig_attack_values[2][7];
uint8_t orig_release_values[2][7];
int temp_int;
bool menu_select_toggle;
float32_t temp_float;
#ifdef I2C_DISPLAY
#include <LiquidCrystal_I2C.h>
@ -224,6 +229,7 @@ void UI_func_delay_level(uint8_t param);
void UI_func_reverb_send(uint8_t param);
void UI_func_filter_cutoff(uint8_t param);
void UI_func_filter_resonance(uint8_t param);
void UI_func_drum_reverb_send(uint8_t param);
#endif
void UI_func_transpose(uint8_t param);
void UI_func_tune(uint8_t param);
@ -256,6 +262,8 @@ void UI_func_portamento_time(uint8_t param);
void UI_handle_OP(uint8_t param);
void UI_func_information(uint8_t param);
void UI_func_sequencer(uint8_t param);
void UI_func_seq_live_transpose_oct(uint8_t param);
void UI_func_seq_lenght(uint8_t param);
void UI_func_seq_pat_chain(uint8_t param);
void UI_func_volume(uint8_t param);
void UI_func_load_performance(uint8_t param);
@ -301,6 +309,10 @@ void locate_previous_favorite();
void locate_next_favorite();
void locate_next_non_favorite();
void locate_random_non_favorite();
void UI_func_drum_main_volume(uint8_t param);
void UI_func_drum_volume(uint8_t param);
void UI_func_drum_pan(uint8_t param);
// normal menu
LCDMenuLib2_menu LCDML_0(255, 0, 0, NULL, NULL); // normal root menu element (do not change)
@ -647,7 +659,6 @@ void lcdml_menu_control(void)
Serial.println(F("ENC-R short"));
#endif
encoderDir[ENC_R].ButtonShort(true);
seq_button_r = true;
LCDML.BT_enter();
}
@ -3543,12 +3554,272 @@ void UI_handle_OP(uint8_t param)
}
}
void UI_func_drum_reverb_send(uint8_t param)
{
char displayname[8] = {0, 0, 0, 0, 0, 0, 0};
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print("Drum Rev. Send");
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if (menu_select_toggle == false) {
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()))
{
if (LCDML.BT_checkDown())
{
activesample = constrain(activesample + ENCODER[ENC_R].speed(), 0, num_drums - 2);
}
else if (LCDML.BT_checkUp())
{
activesample = constrain(activesample - ENCODER[ENC_R].speed(), 0, num_drums - 2);
}
}
} else {
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()))
{
if (LCDML.BT_checkDown())
{
temp_int = constrain(temp_int + ENCODER[ENC_R].speed(), 0, REVERB_SEND_MAX);
}
else if (LCDML.BT_checkUp())
{
temp_int = constrain(temp_int - ENCODER[ENC_R].speed(), 0, REVERB_SEND_MAX);
}
}
}
if (LCDML.BT_checkEnter())
{
if (menu_select_toggle) {
menu_select_toggle = false;
} else
{ menu_select_toggle = true;
temp_int = (int)(drum_config[activesample].reverb_send * 100);
}
}
if (menu_select_toggle == false) {
lcd.setCursor(11, 1);
lcd.print(" ");
lcd.setCursor(15, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("[");
lcd.setCursor(3, 1);
lcd.print("]");
lcd.setCursor(1, 1);
sprintf(displayname, "%02d", activesample);
lcd.print(displayname);
lcd.setCursor(4, 1);
strncpy(displayname, drum_config[activesample].filename + 5, 7);
lcd.print(displayname);
sprintf(displayname, "%03d", (int)(drum_config[activesample].reverb_send * 100) );
lcd.setCursor(12, 1);
lcd.print(displayname);
} else {
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(3, 1);
lcd.print(" ");
lcd.setCursor(11, 1);
lcd.print("[");
lcd.setCursor(15, 1);
lcd.print("]");
sprintf(displayname, "%03d", temp_int);
lcd.setCursor(12, 1);
lcd.print(displayname);
drum_config[activesample].reverb_send = mapfloat(temp_int, 0, 100, 0.0, 1.0);
}
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
encoderDir[ENC_R].reset();
}
}
void UI_func_drum_main_volume(uint8_t param)
{
;
}
void UI_func_drum_volume(uint8_t param)
{
char displayname[8] = {0, 0, 0, 0, 0, 0, 0};
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print("DrumSmp. Volume");
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if (menu_select_toggle == false) {
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()))
{
if (LCDML.BT_checkDown())
{
activesample = constrain(activesample + ENCODER[ENC_R].speed(), 0, num_drums - 2);
}
else if (LCDML.BT_checkUp())
{
activesample = constrain(activesample - ENCODER[ENC_R].speed(), 0, num_drums - 2);
}
}
} else {
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()))
{
if (LCDML.BT_checkDown())
{
temp_int = constrain(temp_int + ENCODER[ENC_R].speed(), 0, 100);
}
else if (LCDML.BT_checkUp())
{
temp_int = constrain(temp_int - ENCODER[ENC_R].speed(), 0, 100);
}
}
}
if (LCDML.BT_checkEnter())
{
if (menu_select_toggle) {
menu_select_toggle = false;
} else
{ menu_select_toggle = true;
temp_int = (int)(drum_config[activesample].vol_max * 100);
}
}
if (menu_select_toggle == false) {
lcd.setCursor(11, 1);
lcd.print(" ");
lcd.setCursor(15, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("[");
lcd.setCursor(3, 1);
lcd.print("]");
lcd.setCursor(1, 1);
sprintf(displayname, "%02d", activesample);
lcd.print(displayname);
lcd.setCursor(4, 1);
strncpy(displayname, drum_config[activesample].filename + 5, 7);
lcd.print(displayname);
sprintf(displayname, "%03d", (int)(drum_config[activesample].vol_max * 100) );
lcd.setCursor(12, 1);
lcd.print(displayname);
} else {
temp_float = mapfloat(temp_int, 0, 100, 0.0, 1.0);
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(3, 1);
lcd.print(" ");
lcd.setCursor(11, 1);
lcd.print("[");
lcd.setCursor(15, 1);
lcd.print("]");
sprintf(displayname, "%03d", temp_int);
lcd.setCursor(12, 1);
lcd.print(displayname);
drum_config[activesample].vol_max = temp_float;
}
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
encoderDir[ENC_R].reset();
}
}
void UI_func_drum_pan(uint8_t param)
{
char displayname[8] = {0, 0, 0, 0, 0, 0, 0};
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print("DrmSmp. Panorama");
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if (menu_select_toggle == false) {
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()))
{
if (LCDML.BT_checkDown())
{
activesample = constrain(activesample + ENCODER[ENC_R].speed(), 0, num_drums - 2);
}
else if (LCDML.BT_checkUp())
{
activesample = constrain(activesample - ENCODER[ENC_R].speed(), 0, num_drums - 2);
}
}
} else {
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()))
{
if (LCDML.BT_checkDown())
{
temp_int = constrain(temp_int + ENCODER[ENC_R].speed(), -99, 99);
}
else if (LCDML.BT_checkUp())
{
temp_int = constrain(temp_int - ENCODER[ENC_R].speed(), -99, 99);
}
}
}
if (LCDML.BT_checkEnter())
{
if (menu_select_toggle) {
menu_select_toggle = false;
} else
{ menu_select_toggle = true;
// if (drum_config[activesample].pan>0.00)
//temp_int=drum_config[activesample].pan*100;
//else
//temp_int=drum_config[activesample].pan*-100;
}
}
if (menu_select_toggle == false) {
lcd.setCursor(11, 1);
lcd.print(" ");
lcd.setCursor(15, 1);
lcd.print(" ");
lcd.setCursor(0, 1);
lcd.print("[");
lcd.setCursor(3, 1);
lcd.print("]");
lcd.setCursor(1, 1);
sprintf(displayname, "%02d", activesample);
lcd.print(displayname);
lcd.setCursor(4, 1);
strncpy(displayname, drum_config[activesample].filename + 5, 7);
lcd.print(displayname);
sprintf(displayname, "%+f", drum_config[activesample].pan);
lcd.setCursor(12, 1);
lcd.print(displayname);
} else {
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.setCursor(3, 1);
lcd.print(" ");
lcd.setCursor(11, 1);
lcd.print("[");
lcd.setCursor(15, 1);
lcd.print("]");
sprintf(displayname, "%+03d", temp_int);
lcd.setCursor(12, 1);
lcd.print(displayname);
drum_config[activesample].pan = mapfloat(temp_int, -99, 99, -1.0, 1.0);
}
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
encoderDir[ENC_R].reset();
}
}
const char* seq_find_shortname(uint8_t sstep)
{
const char* shortname = " ";
bool found = false;
if (seq_active_track < 3) {
for (uint8_t d = 0; d < num_drums - 1; d++)
{
@ -3560,11 +3831,9 @@ const char* seq_find_shortname(uint8_t sstep)
}
}
if (found == false) shortname = "-";
} else
{
if (seq_data[ seq_patternchain[seq_chain_active_step][seq_active_track] ][sstep] > 0) shortname = "*"; else shortname = "-";
}
return shortname;
}
@ -3585,6 +3854,84 @@ const char* seq_find_shortname(uint8_t sstep)
// }
//}
void UI_func_seq_live_transpose_oct(uint8_t param)
{ //Select octave for live transpose of sequencer instrument track. Should be one of the lowest octaves available on the keyboard.
//Allowed range: C1-C5 to not restrict too much, even for very unusual user setups/configurations.
char note_name[4];
char note_name2[4];
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
getNoteName(note_name, seq_transpose);
getNoteName(note_name2, seq_transpose + 12);
lcd.setCursor(0, 0);
lcd.print(F("Live Transp.Oct."));
lcd.setCursor(0, 1);
lcd.print(F("["));
lcd.print(note_name);
lcd.print(F("] - "));
lcd.print(("["));
lcd.print(note_name2);
lcd.print(("]"));
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()))
{
if (LCDML.BT_checkDown())
seq_transpose = constrain(seq_transpose + ENCODER[ENC_R].speed(), 24, 60);
else if (LCDML.BT_checkUp())
seq_transpose = constrain(seq_transpose - ENCODER[ENC_R].speed(), 24, 60);
}
getNoteName(note_name, seq_transpose);
getNoteName(note_name2, seq_transpose + 12);
lcd.setCursor(0, 1);
lcd.print(F("["));
lcd.print(note_name);
lcd.print(F("] - "));
lcd.print(("["));
lcd.print(note_name2);
lcd.print(("]"));
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
encoderDir[ENC_R].reset();
}
}
void UI_func_seq_lenght(uint8_t param)
{
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print(" Seq. lenght ");
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()))
{
if (LCDML.BT_checkDown())
seq_chain_lenght = constrain(seq_chain_lenght + ENCODER[ENC_R].speed(), 0, 3);
else if (LCDML.BT_checkUp())
seq_chain_lenght = constrain(seq_chain_lenght - ENCODER[ENC_R].speed(), 0, 3);
}
lcd.setCursor(3, 1);
lcd.print((seq_chain_lenght + 1) * 16 );
lcd.setCursor(7, 1);
lcd.print("Steps");
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
encoderDir[ENC_R].reset();
}
}
void UI_func_sequencer(uint8_t param)
{
@ -3593,7 +3940,6 @@ void UI_func_sequencer(uint8_t param)
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
seq_button_r = false;
seq_note_in = 0;
// setup function
lcd.setCursor(1, 0);
@ -3647,9 +3993,8 @@ void UI_func_sequencer(uint8_t param)
seq_active_track = constrain(seq_active_track - 1, 0, 8);
}
}
if (seq_button_r) //handle button presses during menu >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
if (LCDML.BT_checkEnter()) //handle button presses during menu >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
{
seq_button_r = false;
if ( seq_menu == 0 && seq_active_function == 99)
{
seq_active_function = 0;
@ -3817,13 +4162,13 @@ void UI_func_seq_pat_chain(uint8_t param)
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
// setup function
seq_button_r = false;
lcd.setCursor( 12, 0);
lcd.print(seq_chain_active_chainstep + 1);
lcd.setCursor( 13, 0);
lcd.print("/4");
lcd.print("/");
lcd.setCursor( 14, 0);
lcd.print(seq_chain_lenght + 1);
lcd.setCursor(0 , 0);
lcd.print("D");
lcd.setCursor(2 , 0);
@ -3859,9 +4204,9 @@ void UI_func_seq_pat_chain(uint8_t param)
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()))
{
if (LCDML.BT_checkDown())
seq_chain_active_chainstep = constrain(seq_chain_active_chainstep + 1, 0, 3);
seq_chain_active_chainstep = constrain(seq_chain_active_chainstep + 1, 0, seq_chain_lenght);
else if (LCDML.BT_checkUp())
seq_chain_active_chainstep = constrain(seq_chain_active_chainstep - 1, 0, 3);
seq_chain_active_chainstep = constrain(seq_chain_active_chainstep - 1, 0, seq_chain_lenght);
}
}
else if (seq_chain_active_menu < 4) {
@ -3937,7 +4282,11 @@ void UI_func_seq_pat_chain(uint8_t param)
lcd.setCursor( 12, 0);
lcd.print(seq_chain_active_chainstep + 1);
lcd.setCursor( 13, 0);
lcd.print("/4]");
lcd.print("/");
lcd.setCursor( 14, 0);
lcd.print(seq_chain_lenght + 1);
lcd.setCursor( 15, 0);
lcd.print("]");
} else if (seq_chain_select_menu == 4 && seq_chain_active_menu == 4) // Chainselect modify
{
lcd.setCursor( 11, 0);
@ -3945,7 +4294,11 @@ void UI_func_seq_pat_chain(uint8_t param)
lcd.setCursor( 12, 0);
lcd.print(seq_chain_active_chainstep + 1);
lcd.setCursor( 13, 0);
lcd.print("/4]");
lcd.print("/");
lcd.setCursor( 14, 0);
lcd.print(seq_chain_lenght + 1);
lcd.setCursor( 15, 0);
lcd.print("]");
lcd.setCursor(2 , 0);
lcd.print( seq_patternchain[seq_chain_active_chainstep][0]);
@ -3976,9 +4329,8 @@ void UI_func_seq_pat_chain(uint8_t param)
lcd.print( seq_patternchain[seq_chain_active_chainstep][3]);
}
if (seq_button_r) //handle button presses during menu >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
if (LCDML.BT_checkEnter()) //handle button presses during menu >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
{
seq_button_r = false;
if (seq_chain_active_menu == seq_chain_select_menu) {
seq_chain_active_menu = 99;
} else
@ -3993,7 +4345,6 @@ void UI_func_seq_pat_chain(uint8_t param)
}
}
void UI_func_information(uint8_t param)
{
if (LCDML.FUNC_setup()) // ****** SETUP *********

@ -113,16 +113,16 @@ LCDML_add(79, LCDML_0_3_5, 1, "MIDI Recv Bank", UI_func_sysex_receive_bank);
LCDML_add(80, LCDML_0_3_5, 2, "MIDI Snd Bank", UI_func_sysex_send_bank);
LCDML_add(81, LCDML_0_3_5, 3, "MIDI Snd Voice", UI_func_sysex_send_voice);
LCDML_add(82, LCDML_0, 4, "Drum Settings", NULL);
LCDML_add(83, LCDML_0_4, 1, "Drums Main Vol", NULL);
LCDML_add(84, LCDML_0_4, 2, "Drum Volumes", NULL);
LCDML_add(85, LCDML_0_4, 3, "Drum Pan", NULL);
LCDML_add(86, LCDML_0_4, 4, "Drum Rev.Send", NULL);
LCDML_add(83, LCDML_0_4, 1, "Drums Main Vol", UI_func_drum_main_volume);
LCDML_add(84, LCDML_0_4, 2, "Drum Volumes", UI_func_drum_volume);
LCDML_add(85, LCDML_0_4, 3, "Drum Pan", UI_func_drum_pan);
LCDML_add(86, LCDML_0_4, 4, "Drum Rev.Send", UI_func_drum_reverb_send);
LCDML_add(87, LCDML_0, 5, "Sequencer Set.", NULL);
LCDML_add(88, LCDML_0_5, 1, "Sequencer", UI_func_sequencer);
LCDML_add(89, LCDML_0_5, 2, "Pattern Chain", UI_func_seq_pat_chain);
LCDML_add(90, LCDML_0_5, 3, "Seq. Length", NULL);
LCDML_add(90, LCDML_0_5, 3, "Seq. Length", UI_func_seq_lenght);
LCDML_add(91, LCDML_0_5, 4, "Tempo", NULL);
LCDML_add(92, LCDML_0_5, 5, "Live-Trp.Key", NULL);
LCDML_add(92, LCDML_0_5, 5, "L.Transp.Key", UI_func_seq_live_transpose_oct);
LCDML_add(93, LCDML_0_5, 6, "L.Trp.Offset", NULL);
LCDML_add(94, LCDML_0_5, 7, "Pattern load", NULL);
LCDML_add(95, LCDML_0_5, 8, "Pattern save", NULL);

@ -86,15 +86,15 @@ LCDML_add(52, LCDML_0_2_4, 1, "MIDI Recv Bank", UI_func_sysex_receive_bank);
LCDML_add(53, LCDML_0_2_4, 2, "MIDI Snd Bank", UI_func_sysex_send_bank);
LCDML_add(54, LCDML_0_2_4, 3, "MIDI Snd Voice", UI_func_sysex_send_voice);
LCDML_add(55, LCDML_0, 3, "Drum Settings", NULL);
LCDML_add(56, LCDML_0_3, 1, "Drums Main Vol", NULL);
LCDML_add(57, LCDML_0_3, 2, "Drum Volumes", NULL);
LCDML_add(58, LCDML_0_3, 3, "Drum Pan", NULL);
LCDML_add(56, LCDML_0_3, 1, "Drums Main Vol", UI_func_drum_main_volume);
LCDML_add(57, LCDML_0_3, 2, "Drum Volumes", UI_func_drum_volume);
LCDML_add(58, LCDML_0_3, 3, "Drum Pan", UI_func_drum_pan);
LCDML_add(59, LCDML_0, 4, "Sequencer Set.", NULL);
LCDML_add(60, LCDML_0_4, 1, "Sequencer", UI_func_sequencer);
LCDML_add(61, LCDML_0_4, 2, "Pattern Chain", UI_func_seq_pat_chain);
LCDML_add(62, LCDML_0_4, 3, "Seq. Length", NULL);
LCDML_add(63, LCDML_0_4, 4, "Tempo", NULL);
LCDML_add(64, LCDML_0_4, 5, "Live-Transp.Key", NULL);
LCDML_add(64, LCDML_0_4, 5, "L.Transp.Key", UI_func_seq_live_transpose_oct);
LCDML_add(65, LCDML_0_4, 6, "Live-Tr.Offset", NULL);
LCDML_add(66, LCDML_0_4, 7, "Pattern load", NULL);
LCDML_add(67, LCDML_0_4, 8, "Pattern save", NULL);

Loading…
Cancel
Save