From 008dc2144b02c0aad33312d430d3f17890cd4ac9 Mon Sep 17 00:00:00 2001 From: Nero Date: Fri, 16 Jun 2023 15:28:01 -0400 Subject: [PATCH] v2.0.1 Minor bug fixes, check log --- library.properties | 2 +- src/BMC-Api.h | 12 +- src/BMC-Version.h | 8 +- src/BMC.cpp | 2 + src/BMC.debug.cpp | 72 +- src/BMC.editor.cpp | 1 + src/BMC.events.cpp | 1579 +++++++++++------- src/BMC.h | 16 +- src/BMC.hardware.buttons.cpp | 627 +------ src/BMC.hardware.cpp | 27 +- src/BMC.hardware.encoders.cpp | 10 + src/BMC.layers.cpp | 51 +- src/display/BMC-Display-ILI9341Block.h | 358 +++- src/display/BMC-Display-OLED.h | 374 ++++- src/display/BMC-Display.h | 607 +++++-- src/editor/BMC-Editor.h | 64 +- src/editor/onBoard/BMC-OBEDef.h | 133 +- src/editor/onBoard/BMC-OBEMain.h | 418 +++-- src/editor/onBoard/handlers/BMC-OBEDevices.h | 299 ++-- src/editor/onBoard/handlers/BMC-OBEEvents.h | 307 +++- src/hardware/BMC-Encoder.h | 15 +- src/hardware/BMC-Led.h | 1 - src/hardware/BMC-Pixels.h | 1 - src/utility/BMC-Def.h | 8 + src/utility/BMC-Globals.h | 94 +- src/utility/BMC-Presets.h | 99 +- src/utility/BMC-SetLists.h | 121 +- src/utility/BMC-Settings.h | 12 +- src/utility/BMC-Structs.h | 174 +- src/utility/BMC-Tools.h | 50 + 30 files changed, 3529 insertions(+), 2013 deletions(-) diff --git a/library.properties b/library.properties index d79036b..b59e5d4 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=BMC -version=2.0.0 +version=2.0.1 author=Nero Rox maintainer=Nero Rox sentence=Fully featured MIDI Controller Library with a Companion Editor App for 32-bit Teensy boards, Requires Teensyduino. diff --git a/src/BMC-Api.h b/src/BMC-Api.h index 7362f1b..f0bb0f7 100644 --- a/src/BMC-Api.h +++ b/src/BMC-Api.h @@ -678,7 +678,7 @@ void getDeviceName(uint8_t deviceType, uint16_t index, char* str){ // otherwise once the last setlist is reached BMC will // ignore this function void setListNext(bool t_wrap){ - setLists.scrollSet(BMC_NEXT, t_wrap, 1); + setLists.scrollSet(BMC_NEXT, t_wrap, 1, 0, BMC_MAX_SETLISTS-1); } // * GROUP: SETLISTS // go to the previous setlist @@ -687,7 +687,7 @@ void getDeviceName(uint8_t deviceType, uint16_t index, char* str){ // otherwise once the first setlist is reached BMC will // ignore this function void setListPrevious(bool t_wrap){ - setLists.scrollSet(BMC_PREV, t_wrap, 1); + setLists.scrollSet(BMC_PREV, t_wrap, 1, 0, BMC_MAX_SETLISTS-1); } // * GROUP: SETLISTS // returns the current song number in the setlist @@ -706,7 +706,7 @@ void getDeviceName(uint8_t deviceType, uint16_t index, char* str){ // otherwise once the last song is reached BMC will // ignore this function void setListSongNext(bool t_wrap){ - setLists.scrollSong(BMC_NEXT, t_wrap, 1); + setLists.scrollSong(BMC_NEXT, t_wrap, 1, 0, BMC_MAX_SETLISTS_SONGS-1); } // * GROUP: SETLISTS // go to previous song in the list @@ -715,7 +715,7 @@ void getDeviceName(uint8_t deviceType, uint16_t index, char* str){ // otherwise once the first song is reached BMC will // ignore this function void setListSongPrevious(bool t_wrap){ - setLists.scrollSong(BMC_PREV, t_wrap, 1); + setLists.scrollSong(BMC_PREV, t_wrap, 1, 0, BMC_MAX_SETLISTS_SONGS-1); } // * GROUP: SETLISTS // get the current song number in the setlist @@ -734,7 +734,7 @@ void getDeviceName(uint8_t deviceType, uint16_t index, char* str){ // otherwise once the last song is reached BMC will // ignore this function void setListSongPartNext(bool t_wrap){ - setLists.scrollPart(BMC_NEXT, t_wrap, 1); + setLists.scrollPart(BMC_NEXT, t_wrap, 1, 0, BMC_MAX_SETLISTS_SONG_PARTS-1); } // * GROUP: SETLISTS // go to previous song in the list @@ -743,7 +743,7 @@ void getDeviceName(uint8_t deviceType, uint16_t index, char* str){ // otherwise once the first song is reached BMC will // ignore this function void setListSongPartPrevious(bool t_wrap){ - setLists.scrollPart(BMC_PREV, t_wrap, 1); + setLists.scrollPart(BMC_PREV, t_wrap, 1, 0, BMC_MAX_SETLISTS_SONG_PARTS-1); } // * GROUP: SETLISTS // move a song within a setlist, you can move the song up or down diff --git a/src/BMC-Version.h b/src/BMC-Version.h index 7a4a6af..cf9581f 100644 --- a/src/BMC-Version.h +++ b/src/BMC-Version.h @@ -21,9 +21,11 @@ */ // BMC Version stored in EEPROM (for editor usage) -#define BMC_VERSION_MAJ 2 -#define BMC_VERSION_MIN 0 -#define BMC_VERSION_PATCH 0 +#define BMC_VERSION_MAJ 2 +#define BMC_VERSION_MIN 0 +#define BMC_VERSION_PATCH 1 + +#define BMC_VERSION_STR "2.0.1" //16 bits unsigned, LSB byte is minor, MSB byte is major #define BMC_VERSION ((BMC_VERSION_MAJ<<8) | BMC_VERSION_MIN) diff --git a/src/BMC.cpp b/src/BMC.cpp index a0cf4c6..391a530 100644 --- a/src/BMC.cpp +++ b/src/BMC.cpp @@ -194,6 +194,7 @@ void BMC::update(){ } oneSecondTimer = 0; oneMilliSecondtimer = 0; + BMC_PRINTLN(""); BMC_PRINTLN("FIRST loop() complete"); } if(globals.reloadLayer()){ @@ -279,6 +280,7 @@ void BMC::update(){ } #if BMC_MAX_SETLISTS > 0 // used to re-trigger current preset + setLists.update(); if(globals.triggerSetListChange()){ setLists.set(setLists.get()); } else if(globals.triggerSongChange()){ diff --git a/src/BMC.debug.cpp b/src/BMC.debug.cpp index 202cddb..fc122a6 100644 --- a/src/BMC.debug.cpp +++ b/src/BMC.debug.cpp @@ -20,10 +20,10 @@ void BMC::setupDebug(){ "line '#define BMC_DEBUG' from your config" ); printBoardInfo(); - BMC_PRINTLN(""); -#ifdef BMC_USE_DAW_LC + #ifdef BMC_USE_DAW_LC BMC_PRINTLN(">>>>> BMC_USE_DAW_LC <<<<<"); #endif + BMC_PRINTLN(""); } void BMC::printDebugHeader(char* str){ BMC_PRINTLN(""); @@ -48,6 +48,8 @@ void BMC::readDebug(){ BMC_PRINTLN("board = Print Board Info"); BMC_PRINTLN("eeprom = Displays EEPROM.length()"); BMC_PRINTLN("objects = Displays the sizes of many objects used by BMC"); + BMC_PRINTLN("sync = Displays the Sync Features Available"); + #ifdef BMC_HAS_HARDWARE BMC_PRINTLN("pins = Displays the pins for buttons/leds/pots/encoders"); @@ -138,6 +140,13 @@ void BMC::readDebug(){ printBoardInfo(); printDebugHeader(debugInput); + } else if(BMC_STR_MATCH(debugInput,"sync")){ + printDebugHeader(debugInput); + printSyncInfo(); + printDebugHeader(debugInput); + + + #if BMC_MAX_BUTTONS > 0 || BMC_MAX_GLOBAL_BUTTONS> 0 } else if(BMC_STR_MATCH(debugInput,"buttons")){ @@ -222,7 +231,7 @@ void BMC::readDebug(){ } else if(BMC_STR_MATCH(debugInput,"version")){ printDebugHeader(debugInput); - BMC_PRINTLNNS("BMC Library Version \"",BMC_VERSION_MAJ,".",BMC_VERSION_MIN,".",BMC_VERSION_PATCH,"\""); + BMC_PRINTLN("BMC Library Version", BMC_VERSION_STR); BMC_PRINTLNNS("BMC Library Version stored in EEPROM ",'"',BMC_GET_BYTE(1,store.version),".",BMC_GET_BYTE(0,store.version),'"'); printDebugHeader(debugInput); @@ -230,45 +239,18 @@ void BMC::readDebug(){ printDebugHeader(debugInput); BMC_PRINTLN("EEPROM size",editor.getEepromSize(),"bytes."); + BMC_PRINTLN("Store:", sizeof(bmcStore),"Bytes"); printDebugHeader(debugInput); } else if(BMC_STR_MATCH(debugInput,"build")){ printDebugHeader(debugInput); - BMC_PRINTLN("BMC_DEVICE_NAME",BMC_DEVICE_NAME); - BMC_PRINT("BMC_EDITOR_SYSEX_ID",BMC_EDITOR_SYSEX_ID); + BMC_PRINTLN("BMC_DEVICE_NAME:",BMC_DEVICE_NAME); + BMC_PRINT("BMC_EDITOR_SYSEX_ID:",BMC_EDITOR_SYSEX_ID); BMC_PRINTNS("0x"); BMC_PRINT_HEX(BMC_EDITOR_SYSEX_ID); BMC_PRINTLN(""); - BMC_PRINTLN(""); - BMC_PRINTLN("*** GLOBAL ***"); - BMC_PRINTLN("BMC_MAX_PRESETS", BMC_MAX_PRESETS); - BMC_PRINTLN("BMC_MAX_PRESET_ITEMS", BMC_MAX_PRESET_ITEMS); - BMC_PRINTLN("BMC_MAX_CUSTOM_SYSEX", BMC_MAX_CUSTOM_SYSEX); - BMC_PRINTLN("BMC_MAX_TRIGGERS", BMC_MAX_TRIGGERS); - BMC_PRINTLN("BMC_MAX_TIMED_EVENTS", BMC_MAX_TIMED_EVENTS); - BMC_PRINTLN("BMC_MAX_TEMPO_TO_TAP", BMC_MAX_TEMPO_TO_TAP); - BMC_PRINTLN("BMC_MAX_SKETCH_BYTES", BMC_MAX_SKETCH_BYTES); - BMC_PRINTLN("BMC_MAX_GLOBAL_BUTTONS", BMC_MAX_GLOBAL_BUTTONS); - BMC_PRINTLN("BMC_MAX_BUTTON_EVENTS", BMC_MAX_BUTTON_EVENTS); - BMC_PRINTLN("BMC_MAX_GLOBAL_ENCODERS", BMC_MAX_GLOBAL_ENCODERS); - BMC_PRINTLN("BMC_MAX_GLOBAL_POTS", BMC_MAX_GLOBAL_POTS); - BMC_PRINTLN("BMC_MAX_GLOBAL_LEDS", BMC_MAX_GLOBAL_LEDS); - BMC_PRINTLN("BMC_MAX_NL_RELAYS", BMC_MAX_NL_RELAYS); - BMC_PRINTLN("BMC_MAX_L_RELAYS", BMC_MAX_L_RELAYS); - BMC_PRINTLN(""); - BMC_PRINTLN("*** LAYERS ***"); - BMC_PRINTLN("BMC_MAX_LAYERS", BMC_MAX_LAYERS); - BMC_PRINTLN("BMC_MAX_BUTTONS", BMC_MAX_BUTTONS); - BMC_PRINTLN("BMC_MAX_BUTTON_EVENTS", BMC_MAX_BUTTON_EVENTS); - BMC_PRINTLN("BMC_MAX_ENCODERS", BMC_MAX_ENCODERS); - BMC_PRINTLN("BMC_MAX_POTS", BMC_MAX_POTS); - BMC_PRINTLN("BMC_MAX_LEDS", BMC_MAX_LEDS); - BMC_PRINTLN("BMC_MAX_ENCODERS", BMC_MAX_ENCODERS); - BMC_PRINTLN("BMC_MAX_POTS", BMC_MAX_POTS); - BMC_PRINTLN("BMC_MAX_PIXELS", BMC_MAX_PIXELS); - BMC_PRINTLN("BMC_MAX_RGB_PIXELS", BMC_MAX_RGB_PIXELS); - + editor.printDevicesInfo(); BMC_PRINTLN(""); printDebugHeader(debugInput); #ifdef BMC_HAS_HARDWARE @@ -545,10 +527,32 @@ void BMC::printBoardInfo(){ BMC_PRINTLNNS("Teensy ", BMC_TEENSY_MODEL_STR," @ ",F_CPU/1000000.0,"MHz (",F_CPU,")"); BMC_PRINTLN("RAM:", BMC_TEENSY_RAM_SIZE,"Bytes"); BMC_PRINTLN("EEPROM:", BMC_TEENSY_EEPROM_SIZE,"Bytes"); + BMC_PRINTLN("Store:", sizeof(bmcStore),"Bytes"); BMC_PRINTLN("USB Host:", BMC_TEENSY_HAS_USB_HOST?"Yes":"No"); BMC_PRINTLN("SD Card:", BMC_TEENSY_HAS_SD_CARD?"Yes":"No"); BMC_PRINTLN("Hardware Serial Ports:", BMC_TEENSY_TOTAL_SERIAL_PORTS); } +void BMC::printSyncInfo(){ + #if defined(BMC_USE_SYNC) + #if defined(BMC_USE_DAW_LC) + BMC_PRINTLN("DAW SYNC ENABLED"); + #endif + #if defined(BMC_USE_FAS) + BMC_PRINTLN("FAS SYNC ENABLED"); + #endif + #if defined(BMC_USE_HELIX) + BMC_PRINTLN("HELIX SYNC ENABLED"); + #endif + #if defined(BMC_USE_BEATBUDDY) + BMC_PRINTLN("BEATBUDDY SYNC ENABLED"); + #endif + #if defined(BMC_USE_KEMPER) + BMC_PRINTLN("KEMPER SYNC ENABLED"); + #endif + #else + BMC_PRINTLN("SYNC UNAVAILABLE"); + #endif +} void BMC::midiInDebug(BMCMidiMessage message){ if(!globals.getMidiInDebug() || message.getStatus()==BMC_NONE){ return; diff --git a/src/BMC.editor.cpp b/src/BMC.editor.cpp index 34b06b6..855de19 100644 --- a/src/BMC.editor.cpp +++ b/src/BMC.editor.cpp @@ -69,6 +69,7 @@ void BMC::assignStoreData(){ } void BMC::assignSettings(){ // Set the global settings + globals.offset = settings.getDisplayOffset()?0:1; midiClock.setMaster(settings.getMasterClock()); midiActiveSense.setOutputPorts(settings.getListenerPorts()); midi.setListenerEnable(settings.getIncomingListenerEnabled()); diff --git a/src/BMC.events.cpp b/src/BMC.events.cpp index bbbd409..d78e41c 100644 --- a/src/BMC.events.cpp +++ b/src/BMC.events.cpp @@ -10,23 +10,34 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, uint16_t deviceIndex, uint16_t eventIndex, uint8_t value, uint8_t dat){ // Process Events - // Check if we should render a display's name + + + BMCDataContainer data; + data.index = deviceIndex; + data.offset = globals.offset; + data.useOffset = true; + #if defined(BMC_HAS_DISPLAY) + // Check if we should render a display's name if(eventIndex == 0 && group == BMC_DEVICE_GROUP_DISPLAY){ + data.oled = (deviceId == BMC_DEVICE_ID_OLED); if(settings.getDisplayNames()){ #if BMC_MAX_OLED > 0 - if(deviceId == BMC_DEVICE_ID_OLED && store.layers[layer].oled[deviceIndex].name == 0){ + if(data.oled && store.layers[layer].oled[deviceIndex].name == 0){ return false; } #endif #if BMC_MAX_ILI9341_BLOCKS > 0 - if(deviceId == BMC_DEVICE_ID_ILI && store.layers[layer].ili[deviceIndex].name == 0){ + if(!data.oled && store.layers[layer].ili[deviceIndex].name == 0){ return false; } #endif bmcStoreName t; editor.getDeviceNameText(deviceId, deviceIndex, t.name); - display.renderText(deviceIndex, (deviceId == BMC_DEVICE_ID_OLED), 254, t.name, ""); + data.crc = 254; + strcpy(data.str, t.name); + display.renderText(data); + // display.renderText(deviceIndex, data.oled, 254, t.name, ""); } return false; } @@ -40,176 +51,176 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, if(e.type == BMC_NONE){ return false; } - globals.offset = settings.getDisplayOffset()?0:1; + uint32_t event = e.event; - uint8_t byteA = BMC_GET_BYTE(0, event); - uint8_t byteB = BMC_GET_BYTE(1, event); - uint8_t byteC = BMC_GET_BYTE(2, event); - uint8_t byteD = BMC_GET_BYTE(3, event); - BMCEventScrollData scroll(e.settings, value, deviceId==BMC_DEVICE_GROUP_ENCODER); + data.type = e.type; + data.byteA = BMC_GET_BYTE(0, event); + data.byteB = BMC_GET_BYTE(1, event); + data.byteC = BMC_GET_BYTE(2, event); + data.byteD = BMC_GET_BYTE(3, event); + data.setScroll(e.settings, value, group==BMC_DEVICE_GROUP_ENCODER); + + // uint8_t data.byteA = BMC_GET_BYTE(0, event); + // uint8_t data.byteB = BMC_GET_BYTE(1, event); + // uint8_t data.byteC = BMC_GET_BYTE(2, event); + // uint8_t data.byteD = BMC_GET_BYTE(3, event); + + // BMCEventScrollData scroll(e.settings, value, group==BMC_DEVICE_GROUP_ENCODER); #if defined(BMC_HAS_DISPLAY) - bool isOled = (deviceId == BMC_DEVICE_ID_OLED); - uint8_t displaySettings = 0; if(group == BMC_DEVICE_GROUP_DISPLAY){ + data.oled = (deviceId == BMC_DEVICE_ID_OLED); #if BMC_MAX_OLED > 0 - if(deviceId == BMC_DEVICE_ID_OLED){ - displaySettings = store.layers[layer].oled[deviceIndex].settings[0]; + if(data.oled){ + data.settings = store.layers[layer].oled[deviceIndex].settings[0]+0; } #endif #if BMC_MAX_ILI9341_BLOCKS > 0 - if(deviceId == BMC_DEVICE_ID_ILI){ - displaySettings = store.layers[layer].ili[deviceIndex].settings[0]; + if(!data.oled){ + data.settings = store.layers[layer].ili[deviceIndex].settings[0]+0; } #endif } #endif - switch(e.type){ +#if BMC_MAX_ENCODERS > 0 + if(deviceId == BMC_DEVICE_ID_ENCODER){ + data.setNoScroll(bitRead(store.layers[layer].encoders[deviceIndex].settings[0], 0)); + } +#endif +#if BMC_MAX_GLOBAL_ENCODERS > 0 + if(deviceId == BMC_DEVICE_ID_GLOBAL_ENCODER){ + data.setNoScroll(bitRead(store.global.encoders[deviceIndex].settings[0], 0)); + } +#endif + + switch(data.type){ case BMC_EVENT_TYPE_MIDI_PROGRAM_CHANGE: { - uint8_t channel = BMC_TO_MIDI_CHANNEL(byteA); - uint8_t currentPC = midi.getLocalProgram(channel); - uint8_t min = 0; - uint8_t max = 127; - uint8_t outVal = byteB; - if(byteC > 0){ - // scrolling max or toggle enabled - if((byteC-1) > byteB){ - min = byteB; - max = byteC-1; - } else if((byteC-1) != byteB){ - max = byteB; - min = byteC-1; - } - - if(!scroll.enabled){ - outVal = currentPC != byteB ? byteB : (byteC-1); - } - } + uint8_t currentPC = midi.getLocalProgram(data.getChannel()); + uint8_t outVal = data.setMinMax(currentPC, 0, 127, data.byteB, data.byteC); + if(group==BMC_DEVICE_GROUP_BUTTON || group==BMC_DEVICE_GROUP_ENCODER){ // if scroll is enabled or if it's an encoder use scrolling by default - if(scroll.enabled){ - outVal = midi.scrollPC(e.ports, channel, scroll.amount, scroll.direction, scroll.endless, min, max); - streamMidi(BMC_MIDI_PROGRAM_CHANGE, channel, outVal); + if(data.scrollEnabled()){ + outVal = midi.scrollPC(e.ports, data.getChannel(), data.scrollAmount(), data.scrollDirection(), data.scrollWrap(), data.min, data.max); + streamMidi(BMC_MIDI_PROGRAM_CHANGE, data.getChannel(), outVal); } else { - midi.sendProgramChange(e.ports, channel, outVal); - streamMidi(BMC_MIDI_PROGRAM_CHANGE, channel, outVal); + midi.sendProgramChange(e.ports, data.getChannel(), outVal); + streamMidi(BMC_MIDI_PROGRAM_CHANGE, data.getChannel(), outVal); } } else if(group==BMC_DEVICE_GROUP_POT){ - midi.sendProgramChange(e.ports, channel, value); - streamMidi(BMC_MIDI_PROGRAM_CHANGE, channel, value); + midi.sendProgramChange(e.ports, data.getChannel(), value); + streamMidi(BMC_MIDI_PROGRAM_CHANGE, data.getChannel(), value); } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ return map(currentPC, 0, 127, 0, 100); } else if(group == BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - if(bitRead(displaySettings, 2)){ // selected - display.renderProgramChangeValue(deviceIndex, isOled, e.type, channel, currentPC, false); - } else { - display.renderProgramChangeValue(deviceIndex, isOled, e.type, channel, byteB, false); + strcpy(data.label, "PC"); + if(data.useSelected()){ + data.byteB = currentPC; } + display.renderProgramChangeValue(data); #endif } else { - return currentPC == (byteB & 0x7F); + return currentPC == (data.byteB & 0x7F); } } break; case BMC_EVENT_TYPE_MIDI_CONTROL_CHANGE: { - uint8_t channel = BMC_TO_MIDI_CHANNEL(byteA); - uint8_t currentCC = midi.getLocalControl(channel, byteB); - uint8_t min = 0; - uint8_t max = 127; - uint8_t outVal = byteC; - if(byteD > 0){ - // scrolling max or toggle enabled - if((byteD-1) > byteC){ - min = byteC; - max = byteD-1; - } else if((byteD-1) != byteC){ - max = byteC; - min = byteD-1; - } - if(!scroll.enabled){ - outVal = currentCC != byteC ? byteC : (byteD-1); - } - } + data.useOffset = false; + uint8_t currentCC = midi.getLocalControl(data.getChannel(), data.byteB); + uint8_t outVal = data.setMinMax(currentCC, 0, 127, data.byteC, data.byteD); + + if(group==BMC_DEVICE_GROUP_BUTTON || group==BMC_DEVICE_GROUP_ENCODER){ - if(scroll.enabled){ - outVal = midi.scrollCC(e.ports, channel, byteB, scroll.amount, scroll.direction, scroll.endless, min, max); - streamMidi(BMC_MIDI_CONTROL_CHANGE, channel, byteB, outVal); + if(data.scrollEnabled()){ + outVal = midi.scrollCC(e.ports, data.getChannel(), data.byteB, data.scrollAmount(), data.scrollDirection(), data.scrollWrap(), data.min, data.max); + streamMidi(BMC_MIDI_CONTROL_CHANGE, data.getChannel(), data.byteB, outVal); } else { - midi.sendControlChange(e.ports, channel, byteB, outVal); - streamMidi(BMC_MIDI_CONTROL_CHANGE, channel, byteB, outVal); + midi.sendControlChange(e.ports, data.getChannel(), data.byteB, outVal); + streamMidi(BMC_MIDI_CONTROL_CHANGE, data.getChannel(), data.byteB, outVal); } } else if(group==BMC_DEVICE_GROUP_POT){ - midi.sendControlChange(e.ports, channel, byteB, value); - streamMidi(BMC_MIDI_CONTROL_CHANGE, channel, byteB, value); + midi.sendControlChange(e.ports, data.getChannel(), data.byteB, value); + streamMidi(BMC_MIDI_CONTROL_CHANGE, data.getChannel(), data.byteB, value); } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ return map(currentCC, 0, 127, 0, 100); } else if(group == BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - if(bitRead(displaySettings, 2)){ // selected - display.renderControlChangeValue(deviceIndex, isOled, e.type, channel, byteB, currentCC, false); - } else { - display.renderControlChangeValue(deviceIndex, isOled, e.type, channel, byteB, byteC, false); + sprintf(data.label, "CC#%u", data.byteB); + if(data.useSelected()){ + data.byteC = currentCC; } + display.renderControlChangeValue(data); #endif } else { - return currentCC == (byteC & 0x7F); + return currentCC == (data.byteC & 0x7F); } } break; case BMC_EVENT_TYPE_MIDI_NOTE_ON: - if(group==BMC_DEVICE_GROUP_BUTTON){ - midi.sendNoteOn(e.ports, BMC_TO_MIDI_CHANNEL(byteA), byteB, byteC); - streamMidi(BMC_MIDI_CONTROL_CHANGE, BMC_TO_MIDI_CHANNEL(byteA), byteB, byteC); - - } else if(group==BMC_DEVICE_GROUP_POT){ - midi.sendNoteOn(e.ports, BMC_TO_MIDI_CHANNEL(byteA), byteB, value); - streamMidi(BMC_MIDI_CONTROL_CHANGE, BMC_TO_MIDI_CHANNEL(byteA), byteB, value); - - } else if(group == BMC_DEVICE_GROUP_MAGIC_ENCODER){ - return map(byteC, 0, 127, 0, 100); - - } else if(group==BMC_DEVICE_GROUP_DISPLAY){ -#if defined(BMC_HAS_DISPLAY) - display.renderNoteValue(deviceIndex, isOled, e.type, BMC_TO_MIDI_CHANNEL(byteA), byteB, byteC, false); -#endif + { + data.useOffset = false; + if(group==BMC_DEVICE_GROUP_BUTTON){ + midi.sendNoteOn(e.ports, data.getChannel(), data.byteB, data.byteC); + streamMidi(BMC_MIDI_CONTROL_CHANGE, data.getChannel(), data.byteB, data.byteC); + + } else if(group==BMC_DEVICE_GROUP_POT){ + midi.sendNoteOn(e.ports, data.getChannel(), data.byteB, value); + streamMidi(BMC_MIDI_CONTROL_CHANGE, data.getChannel(), data.byteB, value); + + } else if(group == BMC_DEVICE_GROUP_MAGIC_ENCODER){ + return map(data.byteC, 0, 127, 0, 100); + + } else if(group==BMC_DEVICE_GROUP_DISPLAY){ + #if defined(BMC_HAS_DISPLAY) + // display.renderNoteValue(deviceIndex, data.oled, data.type, data.getChannel(), data.byteB, data.byteC, false); + display.renderNoteValue(data); + #endif + } } + break; case BMC_EVENT_TYPE_MIDI_NOTE_OFF: - if(group==BMC_DEVICE_GROUP_BUTTON){ - midi.sendNoteOff(e.ports, BMC_TO_MIDI_CHANNEL(byteA), byteB, byteC); - streamMidi(BMC_MIDI_CONTROL_CHANGE, BMC_TO_MIDI_CHANNEL(byteA), byteB, byteC); - - } else if(group==BMC_DEVICE_GROUP_POT){ - midi.sendNoteOff(e.ports, BMC_TO_MIDI_CHANNEL(byteA), byteB, value); - streamMidi(BMC_MIDI_CONTROL_CHANGE, BMC_TO_MIDI_CHANNEL(byteA), byteB, value); - - } else if(group == BMC_DEVICE_GROUP_MAGIC_ENCODER){ - return map(byteC, 0, 127, 0, 100); - + { + data.useOffset = false; + if(group==BMC_DEVICE_GROUP_BUTTON){ + midi.sendNoteOff(e.ports, data.getChannel(), data.byteB, data.byteC); + streamMidi(BMC_MIDI_CONTROL_CHANGE, data.getChannel(), data.byteB, data.byteC); + + } else if(group==BMC_DEVICE_GROUP_POT){ + midi.sendNoteOff(e.ports, data.getChannel(), data.byteB, value); + streamMidi(BMC_MIDI_CONTROL_CHANGE, data.getChannel(), data.byteB, value); + + } else if(group == BMC_DEVICE_GROUP_MAGIC_ENCODER){ + return map(data.byteC, 0, 127, 0, 100); + - } else if(group==BMC_DEVICE_GROUP_DISPLAY){ -#if defined(BMC_HAS_DISPLAY) - display.renderNoteValue(deviceIndex, isOled, e.type, BMC_TO_MIDI_CHANNEL(byteA), byteB, byteC, false); -#endif + } else if(group==BMC_DEVICE_GROUP_DISPLAY){ + #if defined(BMC_HAS_DISPLAY) + // display.renderNoteValue(deviceIndex, data.oled, data.type, data.getChannel(), data.byteB, data.byteC, false); + display.renderNoteValue(data); + #endif + } } + break; + case BMC_EVENT_TYPE_MIDI_PITCH_BEND: if(group==BMC_DEVICE_GROUP_POT){ - uint8_t channel = BMC_TO_MIDI_CHANNEL(byteA); - if(byteB==0){ + uint8_t channel = data.getChannel(); + if(data.byteB==0){ int8_t pitch = midi.getLocalPitch(channel); if(value<59){ // pitch down @@ -224,7 +235,7 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, midi.sendPitchBend(e.ports, channel, 0); midi.setLocalPitch(channel, 0); } - } else if(byteB==1){ + } else if(data.byteB==1){ // leave the first 10 values of the pot as a buffer for a flat pitch if(value>9){ // move pitch up @@ -248,57 +259,77 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "PITCH"); + data.useOffset = false; + strcpy(data.label, "PITCH"); + if(data.useMeter()){ + uint8_t pitch = midi.getLocalPitch(data.getChannel()); + uint8_t newPitch = map(pitch, 0, 127, 0, 100); + data.value = newPitch; + data.min = 0; + data.min = 100; + // display.renderSlider(deviceIndex, data.oled, data.type, newPitch, 0, 100, data.label); + display.renderSlider(data); + } else { + // display.renderText(deviceIndex, data.oled, data.type, data.label); + strcpy(data.str, data.label); + display.renderText(data); + } #endif } break; case BMC_EVENT_TYPE_MIDI_AFTER_TOUCH_POLY: if(group==BMC_DEVICE_GROUP_BUTTON){ - midi.sendAfterTouchPoly(e.ports, BMC_TO_MIDI_CHANNEL(byteA), byteB, byteC); - streamMidi(BMC_MIDI_AFTER_TOUCH_POLY, BMC_TO_MIDI_CHANNEL(byteA), byteB, byteC); + midi.sendAfterTouchPoly(e.ports, data.getChannel(), data.byteB, data.byteC); + streamMidi(BMC_MIDI_AFTER_TOUCH_POLY, data.getChannel(), data.byteB, data.byteC); } else if(group == BMC_DEVICE_GROUP_MAGIC_ENCODER){ - return map(byteC, 0, 127, 0, 100); + return map(data.byteC, 0, 127, 0, 100); } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "A.T. POLY"); + data.useOffset = false; + strcpy(data.str, "A.T. POLY"); + display.renderText(data); + // display.renderText(deviceIndex, data.oled, data.type, "A.T. POLY"); #endif } return false; case BMC_EVENT_TYPE_MIDI_AFTER_TOUCH: if(group==BMC_DEVICE_GROUP_BUTTON){ - midi.sendAfterTouch(e.ports, BMC_TO_MIDI_CHANNEL(byteA), byteB, byteC); - streamMidi(BMC_MIDI_AFTER_TOUCH, BMC_TO_MIDI_CHANNEL(byteA), byteB, byteC); + midi.sendAfterTouch(e.ports, data.getChannel(), data.byteB, data.byteC); + streamMidi(BMC_MIDI_AFTER_TOUCH, data.getChannel(), data.byteB, data.byteC); } else if(group == BMC_DEVICE_GROUP_MAGIC_ENCODER){ - return map(byteC, 0, 127, 0, 100); + return map(data.byteC, 0, 127, 0, 100); } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "A.T."); + data.useOffset = false; + strcpy(data.str, "A.T."); + display.renderText(data); + // display.renderText(deviceIndex, data.oled, data.type, "A.T."); #endif } return false; case BMC_EVENT_TYPE_PROGRAM_BANKING_SET: { - uint8_t min = 0; - uint8_t max = 127; - uint8_t outVal = byteB; - if(byteC > 0){ + data.min = 0; + data.max = 127; + uint8_t outVal = data.byteB; + if(data.byteC > 0){ // scrolling max or toggle enabled - if(max > min){ - min = byteB; - max = byteC; + if(data.max > data.min){ + data.min = data.byteB; + data.max = data.byteC; } - if(!scroll.enabled){ - outVal = programBank != byteB ? byteB : byteC; + if(!data.scrollEnabled()){ + outVal = (programBank != data.byteB) ? data.byteB : data.byteC; } } if(group==BMC_DEVICE_GROUP_BUTTON || group==BMC_DEVICE_GROUP_ENCODER){ - if(scroll.enabled){ - midiProgramBankScroll(scroll.direction, scroll.endless, scroll.amount, byteB, byteC); + if(data.scrollEnabled()){ + midiProgramBankScroll(data.scrollDirection(), data.scrollWrap(), data.scrollAmount(), data.byteB, data.byteC); } else { programBank = outVal; } @@ -309,11 +340,14 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - if(bitRead(displaySettings, 2)){ // selected - display.renderNumber(deviceIndex, isOled, e.type, programBank, "%03u", "PROGRAM"); - } else { - display.renderNumber(deviceIndex, isOled, e.type, byteB, "%03u", "PROGRAM"); - } + data.value = (data.useSelected()) ? programBank : data.byteB; + strcpy(data.label, "PROGRAM"); + display.renderNumber(data); + // if(data.useSelected()){ // selected + // display.renderNumber(deviceIndex, data.oled, data.type, programBank, "%03u", "PROGRAM"); + // } else { + // display.renderNumber(deviceIndex, data.oled, data.type, data.byteB, "%03u", "PROGRAM"); + // } #endif } @@ -321,36 +355,38 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, break; case BMC_EVENT_TYPE_PROGRAM_BANKING_TRIGGER: if(group==BMC_DEVICE_GROUP_BUTTON || group==BMC_DEVICE_GROUP_ENCODER){ - midiProgramBankTrigger(BMC_TO_MIDI_CHANNEL(byteA), e.ports); + midiProgramBankTrigger(data.getChannel(), e.ports); } else if(group == BMC_DEVICE_GROUP_MAGIC_ENCODER){ return map(programBank, 0, 127, 0, 100); } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "TRIGGER"); + // display.renderText(deviceIndex, data.oled, data.type, "TRIGGER"); + strcpy(data.str, "TRIGGER"); + display.renderText(data); #endif } break; case BMC_EVENT_TYPE_MIDI_REAL_TIME_BLOCK: if(group==BMC_DEVICE_GROUP_BUTTON){ - if(byteA==0){ - if(byteB >= 2){ + if(data.byteA==0){ + if(data.byteB >= 2){ midi.toggleRealTimeBlockInput(); } else { - midi.setRealTimeBlockInput(byteB==1); + midi.setRealTimeBlockInput(data.byteB==1); } } else { - if(byteB>=2){ + if(data.byteB>=2){ midi.toggleRealTimeBlockOutput(); } else { - midi.setRealTimeBlockOutput(byteB==1); + midi.setRealTimeBlockOutput(data.byteB==1); } } } else if(group == BMC_DEVICE_GROUP_MAGIC_ENCODER){ - if(byteA==0){ + if(data.byteA==0){ return midi.getRealTimeBlockInput() ? 100 : 0; } @@ -358,10 +394,12 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "R.T. BLOCK"); + // display.renderText(deviceIndex, data.oled, data.type, "R.T. BLOCK"); + strcpy(data.str, "R.T. BLOCK"); + display.renderText(data); #endif } else { - if(byteA==0){ + if(data.byteA==0){ return midi.getRealTimeBlockInput(); } return midi.getRealTimeBlockOutput(); @@ -369,60 +407,71 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, break; case BMC_EVENT_TYPE_BANK_LSB_PROGRAM: if(group==BMC_DEVICE_GROUP_BUTTON){ - uint8_t channel = BMC_TO_MIDI_CHANNEL(byteA); - midi.sendControlChange(e.ports, channel, 0, byteB & 0x7F); - midi.sendProgramChange(e.ports, channel, byteC & 0x7F); + uint8_t channel = data.getChannel(); + midi.sendControlChange(e.ports, channel, 0, data.byteB & 0x7F); + midi.sendProgramChange(e.ports, channel, data.byteC & 0x7F); } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "LSB PGM"); + // display.renderText(deviceIndex, data.oled, data.type, "LSB PGM"); + strcpy(data.str, "LSB PGM"); + display.renderText(data); #endif } break; case BMC_EVENT_TYPE_BANK_MSB_PROGRAM: if(group==BMC_DEVICE_GROUP_BUTTON){ - uint8_t channel = BMC_TO_MIDI_CHANNEL(byteA); - midi.sendControlChange(e.ports, channel, 32, byteB & 0x7F); - midi.sendProgramChange(e.ports, channel, byteC & 0x7F); + uint8_t channel = data.getChannel(); + midi.sendControlChange(e.ports, channel, 32, data.byteB & 0x7F); + midi.sendProgramChange(e.ports, channel, data.byteC & 0x7F); } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "MSB PGM"); + // display.renderText(deviceIndex, data.oled, data.type, "MSB PGM"); + strcpy(data.str, "MSB PGM"); + display.renderText(data); #endif } break; case BMC_EVENT_TYPE_BANK_MSB_LSB: if(group==BMC_DEVICE_GROUP_BUTTON){ - uint8_t channel = BMC_TO_MIDI_CHANNEL(byteA); - midi.sendControlChange(e.ports, channel, 0, byteB & 0x7F); - midi.sendControlChange(e.ports, channel, 32, byteC & 0x7F); + uint8_t channel = data.getChannel(); + midi.sendControlChange(e.ports, channel, 0, data.byteB & 0x7F); + midi.sendControlChange(e.ports, channel, 32, data.byteC & 0x7F); } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "MSB LSB"); + // display.renderText(deviceIndex, data.oled, data.type, "MSB LSB"); + strcpy(data.str, "MSB LSB"); + display.renderText(data); #endif } break; case BMC_EVENT_TYPE_BANK_MSB_LSB_PROGRAM: if(group==BMC_DEVICE_GROUP_BUTTON){ - uint8_t channel = BMC_TO_MIDI_CHANNEL(byteA); - midi.sendControlChange(e.ports, channel, 0, byteB & 0x7F); - midi.sendControlChange(e.ports, channel, 32, byteC & 0x7F); - midi.sendProgramChange(e.ports, channel, byteD & 0x7F); + uint8_t channel = data.getChannel(); + midi.sendControlChange(e.ports, channel, 0, data.byteB & 0x7F); + midi.sendControlChange(e.ports, channel, 32, data.byteC & 0x7F); + midi.sendProgramChange(e.ports, channel, data.byteD & 0x7F); } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "MSB LSB PGM"); + // display.renderText(deviceIndex, data.oled, data.type, "MSB LSB PGM"); + strcpy(data.str, "MSB LSB PGM"); + display.renderText(data); #endif } break; // SYSTEM case BMC_EVENT_TYPE_SYSTEM_ACTIVE_SENSE: if(group==BMC_DEVICE_GROUP_BUTTON){ - midiActiveSense.command(byteA); + midiActiveSense.command(data.byteA); } else if(group == BMC_DEVICE_GROUP_MAGIC_ENCODER){ return midiActiveSense.active() ? 100 : 0; } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "ACTIVE SENSE", "",midiActiveSense.active()); + // display.renderText(deviceIndex, data.oled, data.type, "ACTIVE SENSE", "", midiActiveSense.active()); + strcpy(data.str, "ACTIVE SENSE"); + data.highlight = midiActiveSense.active(); + display.renderText(data); #endif } else { return midiActiveSense.active(); @@ -437,7 +486,10 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderNumber(deviceIndex, isOled, e.type, midiClock.getBpm(), "%u", "BPM"); + // display.renderNumber(deviceIndex, data.oled, data.type, midiClock.getBpm(), "%u", "BPM"); + data.value = midiClock.getBpm(); + strcpy(data.label, "BPM"); + display.renderNumber(data); #endif } else { return BMC_IGNORE_LED_EVENT; @@ -448,7 +500,9 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, midiClock.tap(); } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "TAP"); + // display.renderText(deviceIndex, data.oled, data.type, "TAP"); + strcpy(data.str, "TAP"); + display.renderText(data); #endif } else { return BMC_IGNORE_LED_EVENT; @@ -456,7 +510,7 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, break; case BMC_EVENT_TYPE_SYSTEM_STATUS: if(group == BMC_DEVICE_GROUP_LED){ - switch(byteA){ + switch(data.byteA){ case BMC_LED_STATUS_ALWAYS_ON: return true; case BMC_LED_STATUS_BMC: @@ -484,39 +538,72 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, } } else if(group == BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - switch(byteA){ + switch(data.byteA){ case BMC_LED_STATUS_ALWAYS_ON: case BMC_LED_STATUS_BMC: - display.renderText(deviceIndex, isOled, e.type, "BMC"); + // display.renderText(deviceIndex, data.oled, data.type, "BMC"); + strcpy(data.str, "BMC"); + display.renderText(data); return 1; case BMC_LED_STATUS_EDITOR_CONNECTED: - display.renderText(deviceIndex, isOled, e.type, "EDITOR","STATUS",globals.editorConnected()); + // display.renderText(deviceIndex, data.oled, data.type, "EDITOR","STATUS",globals.editorConnected()); + strcpy(data.str, "EDITOR"); + strcpy(data.label, "STATUS"); + data.highlight = globals.editorConnected(); + display.renderText(data); return 1; case BMC_LED_STATUS_HOST_CONNECTED: - display.renderText(deviceIndex, isOled, e.type, "HOST","STATUS",globals.hostConnected()); + // display.renderText(deviceIndex, data.oled, data.type, "HOST","STATUS",globals.hostConnected()); + strcpy(data.str, "HOST"); + strcpy(data.label, "STATUS"); + data.highlight = globals.hostConnected(); + display.renderText(data); return 1; case BMC_LED_STATUS_BLE_CONNECTED: - display.renderText(deviceIndex, isOled, e.type, "BLE","STATUS",globals.bleConnected()); + // display.renderText(deviceIndex, data.oled, data.type, "BLE","STATUS",globals.bleConnected()); + strcpy(data.str, "BLE"); + strcpy(data.label, "STATUS"); + data.highlight = globals.bleConnected(); + display.renderText(data); return 1; case BMC_LED_STATUS_ACTIVE_SENSE_SENDING: - display.renderText(deviceIndex, isOled, e.type, "A.S. SEND","STATUS", midiActiveSense.active()); + // display.renderText(deviceIndex, data.oled, data.type, "A.S. SEND","STATUS", midiActiveSense.active()); + strcpy(data.str, "A.S. SEND"); + strcpy(data.label, "STATUS"); + data.highlight = midiActiveSense.active(); + display.renderText(data); return 1; case BMC_LED_STATUS_ACTIVE_SENSE_READING: - display.renderText(deviceIndex, isOled, e.type, "A.S. READ","STATUS", midiActiveSense.reading()); + // display.renderText(deviceIndex, data.oled, data.type, "A.S. READ","STATUS", midiActiveSense.reading()); + strcpy(data.str, "A.S. READ"); + strcpy(data.label, "STATUS"); + data.highlight = midiActiveSense.reading(); + display.renderText(data); return 1; case BMC_LED_STATUS_MIDI_REAL_TIME_BLOCK_INPUT: - display.renderText(deviceIndex, isOled, e.type, "R.T. IN","STATUS", midi.getRealTimeBlockInput()); + // display.renderText(deviceIndex, data.oled, data.type, "R.T. IN","STATUS", midi.getRealTimeBlockInput()); + strcpy(data.str, "R.T. IN"); + strcpy(data.label, "STATUS"); + data.highlight = midi.getRealTimeBlockInput(); + display.renderText(data); return 1; case BMC_LED_STATUS_MIDI_REAL_TIME_BLOCK_OUTPUT: - display.renderText(deviceIndex, isOled, e.type, "R.T. OUT","STATUS", midi.getRealTimeBlockOutput()); + // display.renderText(deviceIndex, data.oled, data.type, "R.T. OUT","STATUS", midi.getRealTimeBlockOutput()); + strcpy(data.str, "R.T. OUT"); + strcpy(data.label, "STATUS"); + data.highlight = midi.getRealTimeBlockOutput(); + display.renderText(data); return 1; case BMC_LED_STATUS_STOPWATCH_ACTIVE: case BMC_LED_STATUS_STOPWATCH_STATE: case BMC_LED_STATUS_STOPWATCH_COMPLETE: { - char str[13] = ""; - sprintf(str, "%02u:%02u", stopwatch.hours, stopwatch.minutes); - display.renderText(deviceIndex, isOled, e.type, str, "STOPWATCH"); + sprintf(data.str, "%02u:%02u", stopwatch.hours, stopwatch.minutes); + strcpy(data.label, "STOPWATCH"); + display.renderText(data); + // char str[13] = ""; + // sprintf(str, "%02u:%02u", stopwatch.hours, stopwatch.minutes); + // display.renderText(deviceIndex, data.oled, data.type, str, "STOPWATCH"); } return 1; } @@ -525,10 +612,12 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, break; case BMC_EVENT_TYPE_SYSTEM_MIDI_ACTIVITY: if(group == BMC_DEVICE_GROUP_LED){ - return globals.hasMidiActivity(byteA) ? BMC_PULSE_LED_EVENT : BMC_IGNORE_LED_EVENT; + return globals.hasMidiActivity(data.byteA) ? BMC_PULSE_LED_EVENT : BMC_IGNORE_LED_EVENT; } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "MIDI IO"); + // display.renderText(deviceIndex, data.oled, data.type, "MIDI IO"); + strcpy(data.str, "MIDI IO"); + display.renderText(data); #endif } @@ -541,7 +630,10 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, } } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "SAVE EEPROM"); + // display.renderText(deviceIndex, data.oled, data.type, "SAVE EEPROM"); + strcpy(data.str, "SAVE EEPROM"); + display.renderText(data); + #endif } @@ -549,36 +641,52 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, #if defined(BMC_USE_ON_BOARD_EDITOR) case BMC_EVENT_TYPE_SYSTEM_MENU: if(group == BMC_DEVICE_GROUP_BUTTON){ - obe.menuCommand(byteA); + obe.menuCommand(data.byteA); } else if(group == BMC_DEVICE_GROUP_ENCODER){ - uint8_t menCmd = scroll.direction ? BMC_MENU_NEXT : BMC_MENU_PREV; + uint8_t menCmd = data.scrollDirection() ? BMC_MENU_NEXT : BMC_MENU_PREV; obe.menuCommand(menCmd, true); } else if(group == BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - switch(byteA){ + switch(data.byteA){ case BMC_MENU_TOGGLE: - display.renderText(deviceIndex, isOled, e.type, "TOGGLE"); + // display.renderText(deviceIndex, data.oled, data.type, "TOGGLE"); + strcpy(data.str, "TOGGLE"); + display.renderText(data); return 1; case BMC_MENU_SELECT: - display.renderText(deviceIndex, isOled, e.type, "SELECT"); + // display.renderText(deviceIndex, data.oled, data.type, "SELECT"); + strcpy(data.str, "SELECT"); + display.renderText(data); return 1; case BMC_MENU_BACK: - display.renderText(deviceIndex, isOled, e.type, "BACK"); + // display.renderText(deviceIndex, data.oled, data.type, "BACK"); + strcpy(data.str, "BACK"); + display.renderText(data); return 1; case BMC_MENU_PREV: - display.renderText(deviceIndex, isOled, e.type, "PREV"); + // display.renderText(deviceIndex, data.oled, data.type, "PREV"); + strcpy(data.str, "PREV"); + display.renderText(data); return 1; case BMC_MENU_NEXT: - display.renderText(deviceIndex, isOled, e.type, "NEXT"); + // display.renderText(deviceIndex, data.oled, data.type, "NEXT"); + strcpy(data.str, "NEXT"); + display.renderText(data); return 1; case BMC_MENU_SHIFT: - display.renderText(deviceIndex, isOled, e.type, "SHIFT"); + // display.renderText(deviceIndex, data.oled, data.type, "SHIFT"); + strcpy(data.str, "SHIFT"); + display.renderText(data); return 1; case BMC_MENU_CANCEL: - display.renderText(deviceIndex, isOled, e.type, "CANCEL"); + // display.renderText(deviceIndex, data.oled, data.type, "CANCEL"); + strcpy(data.str, "CANCEL"); + display.renderText(data); return 1; case BMC_MENU_SAVE: - display.renderText(deviceIndex, isOled, e.type, "SAVE"); + // display.renderText(deviceIndex, data.oled, data.type, "SAVE"); + strcpy(data.str, "SAVE"); + display.renderText(data); return 1; } #endif @@ -587,7 +695,7 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, #endif case BMC_EVENT_TYPE_SYSTEM_TYPER: if(group == BMC_DEVICE_GROUP_BUTTON){ - uint8_t cmd = valueTyper.cmd(byteA, byteB); + uint8_t cmd = valueTyper.cmd(data.byteA, data.byteB); if(cmd > 10){// cmd 10 is Clear // HANDLED BY TYPER CLASS // 10 is clear @@ -653,38 +761,42 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, } } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - char str[16] = ""; - uint8_t cmd = byteA; - if(bitRead(displaySettings, 3)){ // Name + // char str[16] = ""; + uint8_t cmd = data.byteA; + if(data.useName()){ // Name if(cmd < 10){ - sprintf(str, "%u", cmd); + sprintf(data.str, "%u", cmd); } else { switch(cmd){ - case 10: strcpy(str, "CLEAR"); break; - case 11: strcpy(str, "<"); break; - case 12: strcpy(str, ">"); break; - case 13: strcpy(str, "DEC"); break; - case 14: strcpy(str, "INC"); break; - case 15: strcpy(str, "CUSTOM"); break; - case 16: strcpy(str, "LAYER"); break; + case 10: strcpy(data.str, "CLEAR"); break; + case 11: strcpy(data.str, "<"); break; + case 12: strcpy(data.str, ">"); break; + case 13: strcpy(data.str, "DEC"); break; + case 14: strcpy(data.str, "INC"); break; + case 15: strcpy(data.str, "CUSTOM"); break; + case 16: strcpy(data.str, "LAYER"); break; #if BMC_MAX_PRESETS > 0 - case 17: strcpy(str, "PRESET"); break; + case 17: strcpy(data.str, "PRESET"); break; #endif #if defined(BMC_USE_FAS) - case 18: strcpy(str, "FAS PRESET"); break; + case 18: strcpy(data.str, "FAS PRESET"); break; case 19: - case 20: strcpy(str, "FAS SCENE"); break; + case 20: strcpy(data.str, "FAS SCENE"); break; #endif - case 21: strcpy(str, "PROGRAM"); break; - case 22: strcpy(str, "CONTROL"); break; + case 21: strcpy(data.str, "PROGRAM"); break; + case 22: strcpy(data.str, "CONTROL"); break; } } } else { - sprintf(str, "%03u", valueTyper.getOutput()); - display.setSelChar(deviceIndex, isOled, valueTyper.getSelChar()); + sprintf(data.str, "%03u", valueTyper.getOutput()); + display.setSelChar(deviceIndex, data.oled, valueTyper.getSelChar()); } - display.renderText(deviceIndex, isOled, e.type, str, "TYPER"); + // display.renderText(deviceIndex, data.oled, data.type, str, "TYPER"); + + // strcpy(data.str, "SAVE"); + strcpy(data.label, "TYPER"); + display.renderText(data); #endif } @@ -696,7 +808,11 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, } else { if(group == BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "BLE","STATUS",globals.bleConnected()); + // display.renderText(deviceIndex, data.oled, data.type, "BLE","STATUS",globals.bleConnected()); + strcpy(data.str, "BLE"); + strcpy(data.label, "STATUS"); + data.highlight = globals.bleConnected(); + display.renderText(data); #endif } else { return globals.bleConnected(); @@ -706,16 +822,19 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, #endif case BMC_EVENT_TYPE_SYSTEM_STOPWATCH: if(group == BMC_DEVICE_GROUP_BUTTON){ - stopwatchCmd(byteA, byteB, byteC, byteD); + stopwatchCmd(data.byteA, data.byteB, data.byteC, data.byteD); } else if(group == BMC_DEVICE_GROUP_MAGIC_ENCODER){ return (stopwatch.getState() == 1) ? 100 : 0; } else if(group == BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - char str[13] = ""; - sprintf(str, "%02u:%02u", stopwatch.hours, stopwatch.minutes); - display.renderText(deviceIndex, isOled, e.type, str, "STOPWATCH"); + // char str[13] = ""; + sprintf(data.str, "%02u:%02u", stopwatch.hours, stopwatch.minutes); + // display.renderText(deviceIndex, data.oled, data.type, str, "STOPWATCH"); + // strcpy(data.str, "BLE"); + strcpy(data.label, "STOPWATCH"); + display.renderText(data); #endif } else { return (stopwatch.getState() == 1); @@ -723,64 +842,60 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, } break; case BMC_EVENT_TYPE_SYSTEM_LFO: - if(byteA >= BMC_MAX_LFO){ + if(data.byteA >= BMC_MAX_LFO){ return 0; } if(group == BMC_DEVICE_GROUP_BUTTON){ - if(byteB==0){ - lfo[byteA].toggle(); - } else if(byteB==1){ - lfo[byteA].start(); - } else if(byteB==2){ - lfo[byteA].stop(); + if(data.byteB==0){ + lfo[data.byteA].toggle(); + } else if(data.byteB==1){ + lfo[data.byteA].start(); + } else if(data.byteB==2){ + lfo[data.byteA].stop(); } } else if(group == BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - char str[10] = ""; - sprintf(str, "LFO %u", byteA+globals.offset); - display.renderText(deviceIndex, isOled, e.type, str, "", lfo[byteA].isEnabled()); + // char str[10] = ""; + sprintf(data.str, "LFO %u", data.byteA+data.offset); + // display.renderText(deviceIndex, data.oled, data.type, str, "", lfo[data.byteA].isEnabled()); + data.highlight = lfo[data.byteA].isEnabled(); + display.renderText(data); + #endif } else { - return lfo[byteA].isEnabled(); + return lfo[data.byteA].isEnabled(); } break; // SKETCH BYTES case BMC_EVENT_TYPE_SKETCH_BYTE: #if BMC_MAX_SKETCH_BYTES > 0 - if(byteA >= BMC_MAX_SKETCH_BYTES){ + if(data.byteA >= BMC_MAX_SKETCH_BYTES){ return 0; } if(group==BMC_DEVICE_GROUP_BUTTON || group==BMC_DEVICE_GROUP_ENCODER){ - BMCSketchByteData data = BMCBuildData::getSketchByteData(byteA); - uint8_t tmp = getSketchByte(byteA); - if(scroll.enabled){ - BMCScroller scroller(data.min, data.max); - tmp = scroller.scroll(data.step, scroll.direction, scroll.endless, tmp, data.min, data.max); + BMCSketchByteData sbData = BMCBuildData::getSketchByteData(data.byteA); + uint8_t tmp = getSketchByte(data.byteA); + if(data.scrollEnabled()){ + BMCScroller scroller(sbData.min, sbData.max); + tmp = scroller.scroll(sbData.step, data.scrollDirection(), data.scrollWrap(), tmp, sbData.min, sbData.max); } else { - tmp = constrain(byteB, data.min, data.max); + tmp = constrain(data.byteB, sbData.min, sbData.max); } - streamToSketch(BMC_DEVICE_ID_SKETCH_BYTE, tmp, data.name); - setSketchByte(byteA, tmp); + streamToSketch(BMC_DEVICE_ID_SKETCH_BYTE, tmp, sbData.name); + setSketchByte(data.byteA, tmp); if(callback.storeUpdated){ callback.storeUpdated(); } - // } else if(group==BMC_DEVICE_GROUP_ENCODER){ - // BMCSketchByteData data = BMCBuildData::getSketchByteData(byteA); - // uint8_t tmp = getSketchByte(byteA); - // BMCScroller scroller(data.min, data.max); - // tmp = scroller.scroll(data.step, scroll.direction, scroll.endless, tmp, data.min, data.max); - // streamToSketch(BMC_DEVICE_ID_SKETCH_BYTE, tmp, data.name); - // setSketchByte(byteA, tmp); - // if(callback.storeUpdated){ - // callback.storeUpdated(); - // } } else if(group==BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - char str[26] = ""; - BMCSketchByteData data = BMCBuildData::getSketchByteData(byteA); - BMCTools::getSketchByteFormat(str, byteA, getSketchByte(byteA)); + // char str[26] = ""; + BMCSketchByteData sbData = BMCBuildData::getSketchByteData(data.byteA); + BMCTools::getSketchByteFormat(data.str, data.byteA, getSketchByte(data.byteA)); // getSketchByteFormat(char* str, uint8_t n, uint8_t value) - display.renderText(deviceIndex, isOled, e.type, str, data.name); + // display.renderText(deviceIndex, data.oled, data.type, str, sbData.name); + + strcpy(data.label, sbData.name); + display.renderText(data); #endif } #endif @@ -788,200 +903,375 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, // LAYERS case BMC_EVENT_TYPE_LAYER: - if(group == BMC_DEVICE_GROUP_BUTTON){ - if(scroll.enabled){ - scrollLayer(scroll.direction, scroll.endless, scroll.amount); - } else { - setLayer(byteA); - } - - } else if(group == BMC_DEVICE_GROUP_ENCODER){ - scrollLayer(scroll.direction, scroll.endless, scroll.amount); + { + // data.min = 0; + // data.max = BMC_MAX_LAYERS-1; + // uint8_t outVal = data.byteA; + // if(data.byteB > 0){ + // // scrolling max or toggle enabled + // if((data.byteB-1) > data.byteA){ + // data.min = data.byteA; + // data.max = data.byteB-1; + // } else if((data.byteB-1) != data.byteA){ + // data.max = data.byteA; + // data.min = data.byteB-1; + // } + + // if(!data.scrollEnabled()){ + // outVal = layer != data.byteA ? data.byteA : (data.byteB-1); + // } + // } + uint8_t outVal = data.setMinMax(layer, 0, BMC_MAX_LAYERS-1, data.byteA, data.byteB); + if(group == BMC_DEVICE_GROUP_BUTTON || group == BMC_DEVICE_GROUP_ENCODER){ + if(data.scrollEnabled()){ + scrollLayer(data.scrollDirection(), data.scrollWrap(), data.min, data.max, data.scrollAmount()); + } else { + setLayer(outVal); + } + } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ + return map(layer, 0, BMC_MAX_LAYERS-1, 0, 100); - } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ - return map(layer, 0, BMC_MAX_LAYERS-1, 0, 100); + } else if(group == BMC_DEVICE_GROUP_DISPLAY){ + + #if defined(BMC_HAS_DISPLAY) + if(data.byteA < BMC_MAX_LAYERS && data.byteB <= BMC_MAX_LAYERS){ + data.highlight = (layer == data.byteA); + if(!data.useSelected()){ // selected + data.highlight = false; + } + strcpy(data.label, "LAYER"); + if(data.useMeter()){ + data.value = layer; + display.renderSlider(data); + // display.renderSlider(deviceIndex, data.oled, data.type, layer, data.min, data.max, data.label); + } else { + bmcStoreName t; + if(data.useName()){ // name + t = (data.useSelected()) ? getLayerName() : getLayerName(data.byteA); + } else { + t = (data.useSelected()) ? getLayerStr() : getLayerStr(data.byteA); + } + // display.renderText(deviceIndex, data.oled, data.type, t.name, data.label, highlight); + strcpy(data.str, t.name); + display.renderText(data); - } else if(group == BMC_DEVICE_GROUP_DISPLAY){ - -#if defined(BMC_HAS_DISPLAY) - uint16_t selLayer = (event & 0x3FFF); - bool highlight = layer==(event & 0x3FFF); - if(bitRead(displaySettings, 2)){ // selected - selLayer = layer; - highlight = false; - } - if(selLayer < BMC_MAX_LAYERS){ - if(bitRead(displaySettings, 3)){ // name - bmcStoreName t = globals.getDeviceName(store.layers[selLayer].events[0].name); - if(BMC_STR_MATCH(t.name, "")){ - sprintf(t.name, "L %u", selLayer+globals.offset); } - display.renderText(deviceIndex, isOled, e.type, t.name, "LAYER"); - } else { - display.renderNumber(deviceIndex, isOled, e.type, selLayer+globals.offset, "%u", "LAYER", highlight); } + #endif + } else { + return (event & 0x3FFF) == layer; } -#endif - } else { - return (event & 0x3FFF) == layer; } break; // PRESETS #if BMC_MAX_PRESETS > 0 case BMC_EVENT_TYPE_PRESET: - // don't run this event if it's being triggered by a preset - if(flags.read(BMC_FLAGS_BLOCK_PRESETS)){ - return false; - } - if(group == BMC_DEVICE_GROUP_BUTTON){ - if(scroll.enabled){ - presets.scrollPreset(scroll.direction, scroll.endless, scroll.amount); - } else { - presets.setPreset(byteA); + { + data.min = 0; + data.max = BMC_MAX_PRESETS_PER_BANK-1; + uint8_t outVal = data.byteA; + if(data.byteB > 0){ + // scrolling max or toggle enabled + if((data.byteB-1) > data.byteA){ + data.min = data.byteA; + data.max = data.byteB-1; + } else if((data.byteB-1) != data.byteA){ + data.max = data.byteA; + data.min = data.byteB-1; + } + + if(!data.scrollEnabled()){ + outVal = presets.get() != data.byteA ? data.byteA : (data.byteB-1); + } + } + if(data.byteC == 1){ + data.min = 0; + data.max = BMC_MAX_PRESETS-1; + } + // don't run this event if it's being triggered by a preset + if(flags.read(BMC_FLAGS_BLOCK_PRESETS)){ + return false; } + if(group == BMC_DEVICE_GROUP_BUTTON || group == BMC_DEVICE_GROUP_ENCODER){ + if(data.scrollEnabled()){ + if(data.byteC == 1){ + presets.scrollPresetList(data.scrollDirection(), data.scrollWrap(), data.scrollAmount(), 0, 0); + } else { + presets.scrollPreset(data.scrollDirection(), data.scrollWrap(), data.scrollAmount(), data.min, data.max); + } + } else { + presets.setPreset(outVal); + } - } else if(group == BMC_DEVICE_GROUP_ENCODER){ - presets.scrollPreset(scroll.direction, scroll.endless, scroll.amount); + } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ + return map(presets.get(), data.min, data.max, 0, 100); - } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ - return map(presets.get(), 0, BMC_MAX_PRESETS_PER_BANK-1, 0, 100); + } else if(group == BMC_DEVICE_GROUP_DISPLAY){ - } else if(group == BMC_DEVICE_GROUP_DISPLAY){ + #if defined(BMC_HAS_DISPLAY) + if(data.byteA < BMC_MAX_PRESETS_PER_BANK){ + strcpy(data.label, "PRESET"); + if(data.useMeter()){ + // display.renderSlider(deviceIndex, data.oled, data.type, presets.get(), data.min, data.max, data.label); -#if defined(BMC_HAS_DISPLAY) - if(byteA < BMC_MAX_PRESETS){ - bmcStoreName t; - if(bitRead(displaySettings, 3)){ // name - t = (bitRead(displaySettings, 2)) ? presets.getName() : presets.getName(byteA); - } else { - t = (bitRead(displaySettings, 2)) ? presets.getPresetStr() : presets.getPresetStr(byteA); + // BMCTools::getPresetLabelNoName(presets.getBank(), presets.get(), data.str); + if(data.byteC == 1){ + data.value = presets.getIndex(); + } else { + data.value = presets.get(); + } + + data.byteD = presets.getBank(); + display.renderSlider(data); + } else { + bmcStoreName t; + if(data.useName()){ // name + t = (data.useSelected()) ? presets.getName() : presets.getName(data.byteA); + } else { + t = (data.useSelected()) ? presets.getPresetStr() : presets.getPresetStr(data.byteA); + } + // display.renderText(deviceIndex, data.oled, data.type, t.name, data.label); + strcpy(data.str, t.name); + display.renderText(data); + } } - display.renderText(deviceIndex, isOled, e.type, t.name, "PRESET"); + #endif + } else { + return data.byteA == presets.get(); } -#endif - } else { - return byteA == presets.get(); } break; case BMC_EVENT_TYPE_BANK: - // don't run this event if it's being triggered by a preset - if(flags.read(BMC_FLAGS_BLOCK_PRESETS)){ - return false; - } - if(group == BMC_DEVICE_GROUP_BUTTON){ - if(scroll.enabled){ - presets.scrollBank(scroll.direction, scroll.endless, scroll.amount); - } else { - presets.setBank(byteA); - } + { + data.min = 0; + data.max = BMC_MAX_PRESET_BANKS-1; + uint8_t outVal = data.byteA; + if(data.byteB > 0){ + // scrolling max or toggle enabled + if((data.byteB-1) > data.byteA){ + data.min = data.byteA; + data.max = data.byteB-1; + } else if((data.byteB-1) != data.byteA){ + data.max = data.byteA; + data.min = data.byteB-1; + } - } else if(group == BMC_DEVICE_GROUP_ENCODER){ - presets.scrollBank(scroll.direction, scroll.endless, scroll.amount); + if(!data.scrollEnabled()){ + outVal = presets.getBank() != data.byteA ? data.byteA : (data.byteB-1); + } + } + // don't run this event if it's being triggered by a preset + if(flags.read(BMC_FLAGS_BLOCK_PRESETS)){ + return false; + } + if(group == BMC_DEVICE_GROUP_BUTTON || group == BMC_DEVICE_GROUP_ENCODER){ + if(data.scrollEnabled()){ + presets.scrollBank(data.scrollDirection(), data.scrollWrap(), data.scrollAmount(), data.min, data.max); + } else { + presets.setBank(outVal); + } - } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ - return map(presets.getBank(), 0, BMC_MAX_PRESET_BANKS-1, 0, 100); - - } else if(group == BMC_DEVICE_GROUP_DISPLAY){ -#if defined(BMC_HAS_DISPLAY) - bmcStoreName t = (bitRead(displaySettings, 2)) ? presets.getBankStr() : presets.getBankStr(byteA); - display.renderText(deviceIndex, isOled, e.type, t.name, "BANK"); -#endif - } else { - return byteA == presets.getBank(); + } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ + return map(presets.getBank(), 0, BMC_MAX_PRESET_BANKS-1, 0, 100); + + } else if(group == BMC_DEVICE_GROUP_DISPLAY){ + #if defined(BMC_HAS_DISPLAY) + + strcpy(data.label, "BANK"); + if(data.useMeter()){ + data.value = presets.getBank(); + display.renderSlider(data); + // display.renderSlider(deviceIndex, data.oled, data.type, presets.getBank(), data.min, data.max, data.label); + } else { + bmcStoreName t = (data.useSelected()) ? presets.getBankStr() : presets.getBankStr(data.byteA); + // display.renderText(deviceIndex, data.oled, data.type, t.name, data.label); + strcpy(data.str, t.name); + display.renderText(data); + } + #endif + } else { + return data.byteA == presets.getBank(); + } } break; #endif #if BMC_MAX_SETLISTS > 0 - // SETLISTS + case BMC_EVENT_TYPE_SETLIST: - if(group == BMC_DEVICE_GROUP_BUTTON){ - if(scroll.enabled){ - setLists.scrollSet(scroll.direction, scroll.endless, scroll.amount); - } else { - setLists.set(byteA); - } + { + data.min = 0; + data.max = BMC_MAX_SETLISTS-1; + uint8_t outVal = data.byteA; + if(data.byteB > 0){ + // scrolling max or toggle enabled + if((data.byteB-1) > data.byteA){ + data.min = data.byteA; + data.max = data.byteB-1; + } else if((data.byteB-1) != data.byteA){ + data.max = data.byteA; + data.min = data.byteB-1; + } - } else if(group == BMC_DEVICE_GROUP_ENCODER){ - setLists.scrollSet(scroll.direction, scroll.endless, scroll.amount); + if(!data.scrollEnabled()){ + outVal = setLists.get() != data.byteA ? data.byteA : (data.byteB-1); + } + } + if(group == BMC_DEVICE_GROUP_BUTTON || group == BMC_DEVICE_GROUP_ENCODER){ + if(data.scrollEnabled()){ + setLists.scrollSet(data.scrollDirection(), data.scrollWrap(), data.scrollAmount(), data.min, data.max); + } else { + setLists.set(outVal); + } - } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ - return map(setLists.get(), 0, BMC_MAX_SETLISTS-1, 0, 100); - - } else if(group == BMC_DEVICE_GROUP_DISPLAY){ -#if defined(BMC_HAS_DISPLAY) - if(byteA < BMC_MAX_SETLISTS){ - bmcStoreName t; - if(bitRead(displaySettings, 3)){ // display name - t = (bitRead(displaySettings, 2)) ? setLists.getSetName() : setLists.getSetName(byteA); - } else { // display number - t = (bitRead(displaySettings, 2)) ? setLists.getSetStr() : setLists.getSetStr(byteA); + } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ + return map(setLists.get(), 0, BMC_MAX_SETLISTS-1, 0, 100); + + } else if(group == BMC_DEVICE_GROUP_DISPLAY){ + #if defined(BMC_HAS_DISPLAY) + if(data.byteA < BMC_MAX_SETLISTS){ + strcpy(data.label, "SET"); + if(data.useMeter()){ + data.value = setLists.get(); + display.renderSlider(data); + // display.renderSlider(deviceIndex, data.oled, data.type, setLists.get(), data.min, data.max, data.label); + } else { + bmcStoreName t; + if(data.useName()){ // display name + t = (data.useSelected()) ? setLists.getSetName() : setLists.getSetName(data.byteA); + } else { // display number + t = (data.useSelected()) ? setLists.getSetStr() : setLists.getSetStr(data.byteA); + } + // display.renderText(deviceIndex, data.oled, data.type, t.name, data.label); + strcpy(data.str, t.name); + display.renderText(data); + } } - display.renderText(deviceIndex, isOled, e.type, t.name, "SET"); + #endif + } else { + return (data.byteA == setLists.get()); } -#endif - } else { - return (byteA == setLists.get()); } break; + + case BMC_EVENT_TYPE_SONG: - if(group == BMC_DEVICE_GROUP_BUTTON){ - if(scroll.enabled){ - setLists.scrollSong(scroll.direction, scroll.endless, scroll.amount); - } else { - setLists.setSong(byteA); + { + data.min = 0; + data.max = BMC_MAX_SETLISTS_SONGS-1; + uint8_t outVal = data.byteA; + if(data.byteB > 0){ + // scrolling max or toggle enabled + if((data.byteB-1) > data.byteA){ + data.min = data.byteA; + data.max = data.byteB-1; + } else if((data.byteB-1) != data.byteA){ + data.max = data.byteA; + data.min = data.byteB-1; + } + + if(!data.scrollEnabled()){ + outVal = setLists.getSong() != data.byteA ? data.byteA : (data.byteB-1); + } } + if(group == BMC_DEVICE_GROUP_BUTTON){ + if(data.scrollEnabled()){ + setLists.scrollSong(data.scrollDirection(), data.scrollWrap(), data.scrollAmount(), data.min, data.max); + } else { + setLists.setSong(outVal); + } - } else if(group == BMC_DEVICE_GROUP_ENCODER){ - setLists.scrollSong(scroll.direction, scroll.endless, scroll.amount); + } else if(group == BMC_DEVICE_GROUP_ENCODER){ + setLists.scrollSong(data.scrollDirection(), data.scrollWrap(), data.scrollAmount(), data.min, data.max); - } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ - return map(setLists.getSong(), 0, BMC_MAX_SETLISTS_SONGS-1, 0, 100); - - } else if(group == BMC_DEVICE_GROUP_DISPLAY){ -#if defined(BMC_HAS_DISPLAY) - if(byteA < BMC_MAX_SETLISTS_SONGS){ - bmcStoreName t; - if(bitRead(displaySettings, 3)){ // display name - t = (bitRead(displaySettings, 2)) ? setLists.getSongName() : setLists.getSongName(byteA); - } else { // display number - t = (bitRead(displaySettings, 2)) ? setLists.getSongStr() : setLists.getSongStr(byteA); + } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ + return map(setLists.getSong(), 0, BMC_MAX_SETLISTS_SONGS-1, 0, 100); + + } else if(group == BMC_DEVICE_GROUP_DISPLAY){ + #if defined(BMC_HAS_DISPLAY) + if(data.byteA < BMC_MAX_SETLISTS_SONGS){ + strcpy(data.label, "SONG"); + if(data.useMeter()){ + data.value = setLists.getSong(); + display.renderSlider(data); + // display.renderSlider(deviceIndex, data.oled, data.type, setLists.getSong(), data.min, data.max, data.label); + } else { + bmcStoreName t; + if(data.useName()){ // display name + t = (data.useSelected()) ? setLists.getSongName() : setLists.getSongName(data.byteA); + } else { // display number + t = (data.useSelected()) ? setLists.getSongStr() : setLists.getSongStr(data.byteA); + } + // display.renderText(deviceIndex, data.oled, data.type, t.name, data.label); + strcpy(data.str, t.name); + display.renderText(data); + } + } - display.renderText(deviceIndex, isOled, e.type, t.name, "SONG"); - } -#endif - } else { - return (byteA == setLists.getSong()); + #endif + } else { + return (data.byteA == setLists.getSong()); + } } break; + + case BMC_EVENT_TYPE_PART: - if(group == BMC_DEVICE_GROUP_BUTTON){ - if(scroll.enabled){ - setLists.scrollPart(scroll.direction, scroll.endless, scroll.amount); - } else { - setLists.setPart(byteA); - } - } else if(group == BMC_DEVICE_GROUP_ENCODER){ - setLists.scrollPart(scroll.direction, scroll.endless, scroll.amount); - - } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ - return map(setLists.getPart(), 0, BMC_MAX_SETLISTS_SONG_PARTS-1, 0, 100); + { + data.min = 0; + data.max = BMC_MAX_SETLISTS_SONG_PARTS-1; + uint8_t outVal = data.byteA; + if(data.byteB > 0){ + // scrolling max or toggle enabled + if((data.byteB-1) > data.byteA){ + data.min = data.byteA; + data.max = data.byteB-1; + } else if((data.byteB-1) != data.byteA){ + data.max = data.byteA; + data.min = data.byteB-1; + } - } else if(group == BMC_DEVICE_GROUP_DISPLAY){ -#if defined(BMC_HAS_DISPLAY) - if(byteA < BMC_MAX_SETLISTS_SONG_PARTS){ - bmcStoreName t; - if(bitRead(displaySettings, 3)){ // display name - t = (bitRead(displaySettings, 2)) ? setLists.getPartName() : setLists.getPartName(byteA); - } else { // display number - t = (bitRead(displaySettings, 2)) ? setLists.getPartStr() : setLists.getPartStr(byteA); + if(!data.scrollEnabled()){ + outVal = setLists.getPart() != data.byteA ? data.byteA : (data.byteB-1); } - display.renderText(deviceIndex, isOled, e.type, t.name, "PART"); } -#endif - } else { - return (byteA == setLists.getPart()); + if(group == BMC_DEVICE_GROUP_BUTTON){ + if(data.scrollEnabled()){ + setLists.scrollPart(data.scrollDirection(), data.scrollWrap(), data.scrollAmount(), data.min, data.max); + } else { + setLists.setPart(outVal); + } + } else if(group == BMC_DEVICE_GROUP_ENCODER){ + setLists.scrollPart(data.scrollDirection(), data.scrollWrap(), data.scrollAmount(), data.min, data.max); + + } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ + return map(setLists.getPart(), 0, BMC_MAX_SETLISTS_SONG_PARTS-1, 0, 100); + + } else if(group == BMC_DEVICE_GROUP_DISPLAY){ + #if defined(BMC_HAS_DISPLAY) + if(data.byteA < BMC_MAX_SETLISTS_SONG_PARTS){ + strcpy(data.label, "PART"); + if(data.useMeter()){ + data.value = setLists.getPart(); + display.renderSlider(data); + // display.renderSlider(deviceIndex, data.oled, data.type, setLists.getPart(), data.min, data.max, data.label); + } else { + bmcStoreName t; + if(data.useName()){ // display name + t = (data.useSelected()) ? setLists.getPartName() : setLists.getPartName(data.byteA); + } else { // display number + t = (data.useSelected()) ? setLists.getPartStr() : setLists.getPartStr(data.byteA); + } + // display.renderText(deviceIndex, data.oled, data.type, t.name, data.label); + strcpy(data.str, t.name); + display.renderText(data); + } + } + #endif + } else { + return (data.byteA == setLists.getPart()); + } } break; #endif @@ -990,10 +1280,10 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, // PIXELS case BMC_EVENT_TYPE_PIXEL_PROGRAM: if(group == BMC_DEVICE_GROUP_BUTTON || group == BMC_DEVICE_GROUP_ENCODER){ - if(scroll.enabled){ - pixelPrograms.scroll(scroll.direction, scroll.endless); + if(data.scrollEnabled()){ + pixelPrograms.scroll(data.scrollDirection(), data.scrollWrap()); } else { - pixelPrograms.setProgram(byteA); + pixelPrograms.setProgram(data.byteA); } } else if(deviceId==BMC_DEVICE_ID_PIXEL || deviceId==BMC_DEVICE_ID_GLOBAL_PIXEL){ @@ -1010,36 +1300,39 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, // HARDWARE #if BMC_MAX_AUX_JACKS > 0 case BMC_EVENT_TYPE_AUX_JACK: - if(byteA >= BMC_MAX_AUX_JACKS){ + if(data.byteA >= BMC_MAX_AUX_JACKS){ return 0; } if(group == BMC_DEVICE_GROUP_LED){ - if(byteB == 0){ - return auxJacks[byteA].isConnected(); - } else if(byteB == 1){ - return auxJacks[byteA].isPotMode(); - } else if(byteB == 2){ - return !auxJacks[byteA].isPotMode(); + if(data.byteB == 0){ + return auxJacks[data.byteA].isConnected(); + } else if(data.byteB == 1){ + return auxJacks[data.byteA].isPotMode(); + } else if(data.byteB == 2){ + return !auxJacks[data.byteA].isPotMode(); } } else if(group==BMC_DEVICE_GROUP_MAGIC_ENCODER){ - if(byteB == 0){ - return auxJacks[byteA].isConnected() ? 100 : 0; - } else if(byteB == 1){ - return auxJacks[byteA].isPotMode() ? 100 : 0; - } else if(byteB == 2){ - return !auxJacks[byteA].isPotMode() ? 100 : 0; + if(data.byteB == 0){ + return auxJacks[data.byteA].isConnected() ? 100 : 0; + } else if(data.byteB == 1){ + return auxJacks[data.byteA].isPotMode() ? 100 : 0; + } else if(data.byteB == 2){ + return !auxJacks[data.byteA].isPotMode() ? 100 : 0; } } else if(group == BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - char str[13] = ""; - if(auxJacks[byteA].isPotMode()){ - sprintf(str, "Exp %u", byteA+globals.offset); + // char str[13] = ""; + if(auxJacks[data.byteA].isPotMode()){ + sprintf(data.str, "Exp %u", data.byteA+data.offset); } else { - sprintf(str, "Ctrl %u", byteA+globals.offset); + sprintf(data.str, "Ctrl %u", data.byteA+data.offset); } - display.renderText(deviceIndex, isOled, e.type, str, "AUX JACK", auxJacks[byteA].isConnected()); + // display.renderText(deviceIndex, data.oled, data.type, str, "AUX JACK", auxJacks[data.byteA].isConnected()); + strcpy(data.label, "AUX JACK"); + data.highlight = auxJacks[data.byteA].isConnected(); + display.renderText(data); #endif } break; @@ -1049,8 +1342,11 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, case BMC_EVENT_TYPE_DEVICE_NAME: if(group == BMC_DEVICE_GROUP_DISPLAY){ bmcStoreName t; - editor.getDeviceNameText(byteA, BMC_GET_BYTE_2(1, event), t.name); - display.renderText(deviceIndex, isOled, e.type, t.name, "NAME"); + editor.getDeviceNameText(data.byteA, BMC_GET_BYTE_2(1, event), t.name); + // display.renderText(deviceIndex, data.oled, data.type, t.name, "NAME"); + strcpy(data.str, t.name); + strcpy(data.label, "NAME"); + display.renderText(data); } break; #endif @@ -1060,50 +1356,51 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, // handled by BMC::handleButton if(group == BMC_DEVICE_GROUP_BUTTON){ - sync.daw.sendButtonCommand(byteA, byteB, false); + sync.daw.sendButtonCommand(data.byteA, data.byteB, false); } else if(group == BMC_DEVICE_GROUP_LED){ - return sync.daw.getLedState(byteA, byteB); + return sync.daw.getLedState(data.byteA, data.byteB); } else if(group == BMC_DEVICE_GROUP_ENCODER){ - sync.daw.sendEncoderScrolling(byteA, byteB, scroll.direction, scroll.amount); + sync.daw.sendEncoderScrolling(data.byteA, data.byteB, data.scrollDirection(), data.scrollAmount()); } else if(group == BMC_DEVICE_GROUP_MAGIC_ENCODER){ - if(byteA == BMC_DAW_CMD_VPOT_SELECT || (byteA >= BMC_DAW_CMD_VPOT_LED_1 && byteA <= BMC_DAW_CMD_VPOT_LED_CENTER)){ - return sync.daw.getVPotValuePercentage(byteB); - } else if(byteA >= BMC_DAW_CMD_METER_LED_PEAK && byteA <= BMC_DAW_CMD_METER_LED_12){ - return sync.daw.getMeterValuePercentage(byteB); - } else if(byteA >= BMC_DAW_CMD_FADER_TOUCH){ - return sync.daw.getFaderValuePercentage(byteB); + if(data.byteA == BMC_DAW_CMD_VPOT_SELECT || (data.byteA >= BMC_DAW_CMD_VPOT_LED_1 && data.byteA <= BMC_DAW_CMD_VPOT_LED_CENTER)){ + return sync.daw.getVPotValuePercentage(data.byteB); + } else if(data.byteA >= BMC_DAW_CMD_METER_LED_PEAK && data.byteA <= BMC_DAW_CMD_METER_LED_12){ + return sync.daw.getMeterValuePercentage(data.byteB); + } else if(data.byteA >= BMC_DAW_CMD_FADER_TOUCH){ + return sync.daw.getFaderValuePercentage(data.byteB); } else { - return sync.daw.getLedState(byteA, byteB)>0 ? 100 : 0; + return sync.daw.getLedState(data.byteA, data.byteB)>0 ? 100 : 0; } } break; case BMC_EVENT_TYPE_DAW_DISPLAY: #if defined(BMC_HAS_DISPLAY) && defined(BMC_USE_DAW_LC) if(group == BMC_DEVICE_GROUP_DISPLAY){ - if(byteA==0){ + if(data.byteA==0){ #if BMC_MAX_ILI9341_BLOCKS > 0 if(deviceId==BMC_DEVICE_ID_ILI){ display.updateDawMeters(); } #endif - } else if(byteA == 1){ + } else if(data.byteA == 1){ #if BMC_MAX_ILI9341_BLOCKS > 0 if(deviceId==BMC_DEVICE_ID_ILI){ display.updateDawChannels(); } #endif - } else if(byteA == 2){ - display.updateDawChannelInfo(byteB); - } else if(byteA == 3){ - char str[3] = ""; - sync.daw.getTwoDigitDisplay(str); - display.renderText(deviceIndex, isOled, e.type, str); + } else if(data.byteA == 2){ + display.updateDawChannelInfo(data.byteB); + } else if(data.byteA == 3){ + // char str[3] = ""; + sync.daw.getTwoDigitDisplay(data.str); + // display.renderText(deviceIndex, data.oled, data.type, str); + display.renderText(data); } } #endif @@ -1113,10 +1410,10 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, #ifdef BMC_USE_BEATBUDDY case BMC_EVENT_TYPE_BEATBUDDY: if(group == BMC_DEVICE_GROUP_BUTTON){ - if(scroll.enabled){ - if(byteA>=BMC_BEATBUDDY_CMD_TRANS_PART_1 && byteA<=BMC_BEATBUDDY_CMD_TRANS_PART_125){ + if(data.scrollEnabled()){ + if(data.byteA>=BMC_BEATBUDDY_CMD_TRANS_PART_1 && data.byteA<=BMC_BEATBUDDY_CMD_TRANS_PART_125){ uint8_t s = sync.beatBuddy.getSongPart(); - if(scroll.direction){ + if(data.scrollDirection()){ if(s >= 124){ s = 0; } else { @@ -1133,12 +1430,12 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, return 0; } } - sync.beatBuddy.sendCommand(byteA, byteB); + sync.beatBuddy.sendCommand(data.byteA, data.byteB); } else if(group == BMC_DEVICE_GROUP_ENCODER){ - if(byteA>=BMC_BEATBUDDY_CMD_TRANS_PART_1 && byteA<=BMC_BEATBUDDY_CMD_TRANS_PART_125){ + if(data.byteA>=BMC_BEATBUDDY_CMD_TRANS_PART_1 && data.byteA<=BMC_BEATBUDDY_CMD_TRANS_PART_125){ uint8_t s = sync.beatBuddy.getSongPart(); - if(scroll.direction){ + if(data.scrollDirection()){ if(s >= 124){ s = 0; } else { @@ -1154,21 +1451,21 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, sync.beatBuddy.sendCommand(BMC_BEATBUDDY_CMD_TRANS_PART_1+s); return 0; } - switch(byteA){ + switch(data.byteA){ case BMC_BEATBUDDY_CMD_BPM_DEC: case BMC_BEATBUDDY_CMD_BPM_INC: - sync.beatBuddy.tempoControl(scroll.amount, scroll.direction); + sync.beatBuddy.tempoControl(data.scrollAmount(), data.scrollDirection()); break; case BMC_BEATBUDDY_CMD_SONG_SCROLL_DOWN: case BMC_BEATBUDDY_CMD_SONG_SCROLL_UP: - sync.beatBuddy.sendCommand((scroll.direction)?BMC_BEATBUDDY_CMD_SONG_SCROLL_UP:BMC_BEATBUDDY_CMD_SONG_SCROLL_DOWN); + sync.beatBuddy.sendCommand((data.scrollDirection())?BMC_BEATBUDDY_CMD_SONG_SCROLL_UP:BMC_BEATBUDDY_CMD_SONG_SCROLL_DOWN); break; } } else if(group == BMC_DEVICE_GROUP_LED){ - if(byteA>=BMC_BEATBUDDY_CMD_TRANS_PART_1 && byteA<=BMC_BEATBUDDY_CMD_TRANS_PART_125){ - return sync.beatBuddy.isSongPart(byteA-BMC_BEATBUDDY_CMD_TRANS_PART_1); + if(data.byteA>=BMC_BEATBUDDY_CMD_TRANS_PART_1 && data.byteA<=BMC_BEATBUDDY_CMD_TRANS_PART_125){ + return sync.beatBuddy.isSongPart(data.byteA-BMC_BEATBUDDY_CMD_TRANS_PART_1); } - switch(byteA){ + switch(data.byteA){ case BMC_BEATBUDDY_CMD_START: case BMC_BEATBUDDY_CMD_STOP: return sync.beatBuddy.isPlaying(); @@ -1186,7 +1483,7 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, break; } } else if(group == BMC_DEVICE_GROUP_POT){ - switch(byteA){ + switch(data.byteA){ case BMC_BEATBUDDY_CMD_BPM_DEC: case BMC_BEATBUDDY_CMD_BPM_INC: sync.beatBuddy.tempoExpression(value); @@ -1200,131 +1497,135 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, } } else if(group == BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - char str[24] = ""; - bool highlight = false; - if(byteA>=BMC_BEATBUDDY_CMD_TRANS_PART_1 && byteA<=BMC_BEATBUDDY_CMD_TRANS_PART_125){ - if(bitRead(displaySettings, 2)){ // selected + + if(data.byteA>=BMC_BEATBUDDY_CMD_TRANS_PART_1 && data.byteA<=BMC_BEATBUDDY_CMD_TRANS_PART_125){ + if(data.useSelected()){ // selected uint8_t s = sync.beatBuddy.getSongPart(); - sprintf(str,"PT %u", s+globals.offset); - highlight = true; + sprintf(data.str,"PT %u", s+data.offset); + data.highlight = true; } else { - sprintf(str,"PT %u",(byteA-BMC_BEATBUDDY_CMD_TRANS_PART_1)+globals.offset); - highlight = sync.beatBuddy.isSongPart(byteA-BMC_BEATBUDDY_CMD_TRANS_PART_1); + sprintf(data.str,"PT %u",(data.byteA-BMC_BEATBUDDY_CMD_TRANS_PART_1)+data.offset); + data.highlight = sync.beatBuddy.isSongPart(data.byteA-BMC_BEATBUDDY_CMD_TRANS_PART_1); } } else { - switch(byteA){ + switch(data.byteA){ case BMC_BEATBUDDY_CMD_START: - strcpy(str, "Start"); - highlight = sync.beatBuddy.isPlaying(); + strcpy(data.str, "Start"); + data.highlight = sync.beatBuddy.isPlaying(); break; case BMC_BEATBUDDY_CMD_STOP: - strcpy(str, "Stop"); - highlight = !sync.beatBuddy.isPlaying(); + strcpy(data.str, "Stop"); + data.highlight = !sync.beatBuddy.isPlaying(); break; case BMC_BEATBUDDY_CMD_BPM_DEC: - strcpy(str, "BPM Dec"); + strcpy(data.str, "BPM Dec"); break; case BMC_BEATBUDDY_CMD_BPM_INC: - strcpy(str, "BPM Inc"); + strcpy(data.str, "BPM Inc"); break; case BMC_BEATBUDDY_CMD_PAUSE: - strcpy(str, "Pause"); + strcpy(data.str, "Pause"); break; case BMC_BEATBUDDY_CMD_UNPAUSE: - strcpy(str, "Unpause"); + strcpy(data.str, "Unpause"); break; case BMC_BEATBUDDY_CMD_PAUSE_TOGGLE: - strcpy(str, "Pause Toggle"); + strcpy(data.str, "Pause Toggle"); break; case BMC_BEATBUDDY_CMD_DRUM_FILL: - strcpy(str, "Drum Fill"); + strcpy(data.str, "Drum Fill"); break; case BMC_BEATBUDDY_CMD_TAP: - strcpy(str, "Tap"); + strcpy(data.str, "Tap"); break; case BMC_BEATBUDDY_CMD_OUTRO: - strcpy(str, "Outtro"); + strcpy(data.str, "Outtro"); break; case BMC_BEATBUDDY_CMD_MIX_VOL: - strcpy(str, "Mix Vol"); + strcpy(data.str, "Mix Vol"); break; case BMC_BEATBUDDY_CMD_HP_VOL: - strcpy(str, "HP Vol"); + strcpy(data.str, "HP Vol"); break; case BMC_BEATBUDDY_CMD_ACCENT_HIT: - strcpy(str, "Accent Hit"); + strcpy(data.str, "Accent Hit"); break; case BMC_BEATBUDDY_CMD_DRUMSET_SELECT: - strcpy(str, "Drumset Sel"); + strcpy(data.str, "Drumset Sel"); break; case BMC_BEATBUDDY_CMD_NORMAL_TIME: - strcpy(str, "Normal Time"); - highlight = !sync.beatBuddy.isHalfTime() && !sync.beatBuddy.isDoubleTime(); + strcpy(data.str, "Normal Time"); + data.highlight = !sync.beatBuddy.isHalfTime() && !sync.beatBuddy.isDoubleTime(); break; case BMC_BEATBUDDY_CMD_HALF_TIME: - highlight = sync.beatBuddy.isHalfTime(); - strcpy(str, "Half Time"); + data.highlight = sync.beatBuddy.isHalfTime(); + strcpy(data.str, "Half Time"); break; case BMC_BEATBUDDY_CMD_HALF_TIME_TOGGLE: - highlight = sync.beatBuddy.isHalfTime(); - strcpy(str, "Half Time Tggle"); + data.highlight = sync.beatBuddy.isHalfTime(); + strcpy(data.str, "Half Time Tggle"); break; case BMC_BEATBUDDY_CMD_DOUBLE_TIME: - highlight = sync.beatBuddy.isDoubleTime(); - strcpy(str, "Double Time"); + data.highlight = sync.beatBuddy.isDoubleTime(); + strcpy(data.str, "Double Time"); break; case BMC_BEATBUDDY_CMD_DOUBLE_TIME_TOGGLE: - highlight = sync.beatBuddy.isDoubleTime(); - strcpy(str, "Dble Time Tggle"); + data.highlight = sync.beatBuddy.isDoubleTime(); + strcpy(data.str, "Dble Time Tggle"); break; case BMC_BEATBUDDY_CMD_FOLDER_ENTER: - strcpy(str, "Folder Enter"); + strcpy(data.str, "Folder Enter"); break; case BMC_BEATBUDDY_CMD_SONG_SCROLL_DOWN: - strcpy(str, "Song Scroll Down"); + strcpy(data.str, "Song Scroll Down"); break; case BMC_BEATBUDDY_CMD_SONG_SCROLL_UP: - strcpy(str, "Song Scroll Up"); + strcpy(data.str, "Song Scroll Up"); break; case BMC_BEATBUDDY_CMD_TRANS_END: - strcpy(str, "Trans End"); + strcpy(data.str, "Trans End"); break; case BMC_BEATBUDDY_CMD_TRANS_PREV: - strcpy(str, "Trans Prev"); + strcpy(data.str, "Trans Prev"); break; case BMC_BEATBUDDY_CMD_TRANS_NEXT: - strcpy(str, "Trans Next"); + strcpy(data.str, "Trans Next"); break; } } - display.renderText(deviceIndex, isOled, e.type, str, "BEATBUDDY", highlight); + // display.renderText(deviceIndex, data.oled, data.type, str, "BEATBUDDY", highlight); + strcpy(data.label, "BEATBUDDY"); + display.renderText(data); #endif } break; case BMC_EVENT_TYPE_BEATBUDDY_BPM: if(group == BMC_DEVICE_GROUP_BUTTON || group == BMC_DEVICE_GROUP_ENCODER){ - if(scroll.enabled){ - sync.beatBuddy.tempoControl(scroll.amount, scroll.direction); + if(data.scrollEnabled()){ + sync.beatBuddy.tempoControl(data.scrollAmount(), data.scrollDirection()); } else { sync.beatBuddy.tempo(event & 0x1FF); } } else if(group == BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - display.renderText(deviceIndex, isOled, e.type, "BB BPM", "BEATBUDDY"); + // display.renderText(deviceIndex, data.oled, data.type, "BB BPM", "BEATBUDDY"); + strcpy(data.str, "BB BPM"); + strcpy(data.label, "BEATBUDDY"); + display.renderText(data); #endif } break; // case BMC_EVENT_TYPE_BEATBUDDY_FOLDER: // if(group == BMC_DEVICE_GROUP_BUTTON){ - // sync.beatBuddy.songSelect(event & 0x3FFF, byteB); + // sync.beatBuddy.songSelect(event & 0x3FFF, data.byteB); // } // break; #endif #ifdef BMC_USE_FAS case BMC_EVENT_TYPE_FAS: if(group == BMC_DEVICE_GROUP_LED){ - switch(byteA){ + switch(data.byteA){ case BMC_FAS_CMD_CONNECTION: return sync.fas.connected(); case BMC_FAS_CMD_TUNER_ON: return sync.fas.isTunerActive(); case BMC_FAS_CMD_TUNER_OFF: return !sync.fas.isTunerActive(); @@ -1346,7 +1647,7 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, case BMC_FAS_CMD_TAP: return 0; // tap tempo } } else if(group == BMC_DEVICE_GROUP_ENCODER){ - switch(byteA){ + switch(data.byteA){ case BMC_FAS_CMD_CONNECTION:break; case BMC_FAS_CMD_TUNER_ON: sync.fas.tunerOn(); @@ -1367,7 +1668,7 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, break; } } else if(group == BMC_DEVICE_GROUP_BUTTON){ - switch(byteA){ + switch(data.byteA){ case BMC_FAS_CMD_CONNECTION: if(sync.fas.connected()){ sync.fas.disconnect(); @@ -1402,9 +1703,12 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, } } else if(group == BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - switch(byteA){ + switch(data.byteA){ case BMC_FAS_CMD_CONNECTION: - display.renderText(deviceIndex, isOled, e.type, "FAS", "", sync.fas.connected()); + // display.renderText(deviceIndex, data.oled, data.type, "FAS", "", sync.fas.connected()); + strcpy(data.str, "FAS"); + data.highlight = sync.fas.connected(); + display.renderText(data); break; case BMC_FAS_CMD_TUNER_ON: case BMC_FAS_CMD_TUNER_OFF: @@ -1420,25 +1724,50 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, display.updateFasTuner(); break; case BMC_FAS_CMD_LOOPER_PLAY: - display.renderText(deviceIndex, isOled, e.type, "PLAY","LOOPER",sync.fas.looperPlaying()); + // display.renderText(deviceIndex, data.oled, data.type, "PLAY","LOOPER",sync.fas.looperPlaying()); + strcpy(data.str, "PLAY"); + strcpy(data.label, "LOOPER"); + data.highlight = sync.fas.connected(); + display.renderText(data); break; case BMC_FAS_CMD_LOOPER_REC: - display.renderText(deviceIndex, isOled, e.type, "REC","LOOPER",sync.fas.looperRecording()); + // display.renderText(deviceIndex, data.oled, data.type, "REC","LOOPER",sync.fas.looperRecording()); + strcpy(data.str, "PLARECY"); + strcpy(data.label, "LOOPER"); + data.highlight = sync.fas.looperRecording(); + display.renderText(data); break; case BMC_FAS_CMD_LOOPER_DUB: - display.renderText(deviceIndex, isOled, e.type, "DUB","LOOPER",sync.fas.looperDubbing()); + // display.renderText(deviceIndex, data.oled, data.type, "DUB","LOOPER",sync.fas.looperDubbing()); + strcpy(data.str, "DUB"); + strcpy(data.label, "LOOPER"); + data.highlight = sync.fas.looperDubbing(); + display.renderText(data); break; case BMC_FAS_CMD_LOOPER_REV: - display.renderText(deviceIndex, isOled, e.type, "REVERSE","LOOPER",sync.fas.looperReversed()); + // display.renderText(deviceIndex, data.oled, data.type, "REVERSE","LOOPER",sync.fas.looperReversed()); + strcpy(data.str, "REVERSE"); + strcpy(data.label, "LOOPER"); + data.highlight = sync.fas.looperReversed(); + display.renderText(data); break; case BMC_FAS_CMD_LOOPER_HALF: - display.renderText(deviceIndex, isOled, e.type, "HALF","LOOPER",sync.fas.looperHalf()); + // display.renderText(deviceIndex, data.oled, data.type, "HALF","LOOPER",sync.fas.looperHalf()); + strcpy(data.str, "HALF"); + strcpy(data.label, "LOOPER"); + data.highlight = sync.fas.looperHalf(); + display.renderText(data); break; case BMC_FAS_CMD_LOOPER_UNDO: - display.renderText(deviceIndex, isOled, e.type, "UNDO","LOOPER"); + // display.renderText(deviceIndex, data.oled, data.type, "UNDO","LOOPER"); + strcpy(data.str, "UNDO"); + strcpy(data.label, "LOOPER"); + display.renderText(data); break; case BMC_FAS_CMD_TAP: - display.renderText(deviceIndex, isOled, e.type, "TAP"); + // display.renderText(deviceIndex, data.oled, data.type, "TAP"); + strcpy(data.str, "TAP"); + display.renderText(data); break; } #endif @@ -1446,72 +1775,93 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, break; case BMC_EVENT_TYPE_FAS_SCENE: if(group==BMC_DEVICE_GROUP_BUTTON){ - if(byteB > 0){ - if(sync.fas.getSceneNumber() != byteA){ - sync.fas.setSceneNumber(byteA, bitRead(event, 16)); + if(data.byteB > 0){ + if(sync.fas.getSceneNumber() != data.byteA){ + sync.fas.setSceneNumber(data.byteA, bitRead(event, 16)); } else { - sync.fas.setSceneNumber(byteB-1, bitRead(event, 16)); + sync.fas.setSceneNumber(data.byteB-1, bitRead(event, 16)); } } else { - sync.fas.setSceneNumber(byteA, bitRead(event, 16)); + sync.fas.setSceneNumber(data.byteA, bitRead(event, 16)); } } else if(group == BMC_DEVICE_GROUP_ENCODER){ - sync.fas.sceneScroll(scroll.direction, scroll.endless, bitRead(event, 16), 0, 7); + sync.fas.sceneScroll(data.scrollDirection(), data.scrollWrap(), bitRead(event, 16), 0, 7); } else if(group == BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - char str[12] = ""; - bool highlight = sync.fas.getSceneNumber() == byteA; + // char str[12] = ""; + data.highlight = sync.fas.getSceneNumber() == data.byteA; // display the selected scene number - if(bitRead(displaySettings, 2)){ // selected - highlight = true; - sprintf(str, "S %u", (sync.fas.getSceneNumber()+globals.offset)); + if(data.useSelected()){ // selected + data.highlight = true; + sprintf(data.str, "S %u", (sync.fas.getSceneNumber()+data.offset)); } else { - sprintf(str, "S %u", (byteA+globals.offset)); + sprintf(data.str, "S %u", (data.byteA+data.offset)); } - display.renderText(deviceIndex, isOled, e.type, str, "SCENE", highlight); + // display.renderText(deviceIndex, data.oled, data.type, str, "SCENE", highlight); + strcpy(data.label, "SCENE"); + display.renderText(data); #endif } else { - return sync.fas.getSceneNumber() == byteA; + return sync.fas.getSceneNumber() == data.byteA; } break; case BMC_EVENT_TYPE_FAS_PRESET: - if(group==BMC_DEVICE_GROUP_BUTTON){ - sync.fas.setPreset(event & 0x3FF); - - } else if(group == BMC_DEVICE_GROUP_ENCODER){ - sync.fas.presetScroll(scroll.direction, scroll.endless, 0, sync.fas.getMaxPresets()); - - } else if(group == BMC_DEVICE_GROUP_DISPLAY){ -#if defined(BMC_HAS_DISPLAY) - char str[32] = ""; + { + data.min = 0; + data.max = sync.fas.getMaxPresets()-1; uint16_t p1 = BMC_GET_BYTE_2(0, event) & 0x3FF; - uint16_t p2 = BMC_GET_BYTE_2(2, event) & 0x3FF; - bool highlight = sync.fas.getPresetNumber() == p1; + uint16_t p2 = BMC_GET_BYTE_2(2, event) & 0x7FF; + uint16_t outVal = p1; if(p2 > 0){ - // if p2 is more than 0 we are in toggle mode - highlight = false; - uint16_t current = sync.fas.getPresetNumber(); - sprintf(str, "P %u", ((current != p1) ? p1 : (p2-1))+globals.offset); - } else { - if(bitRead(displaySettings, 2)){ // selected - highlight = true; - if(bitRead(displaySettings, 3)){ // name - sync.fas.getPresetName(str); + // scrolling max or toggle enabled + if((p2 - 1) > p1){ + data.min = p1; + data.max = p2 - 1; + } else if((p2 - 1) != p1){ + data.max = p1; + data.min = p2 - 1; + } + if(!data.scrollEnabled()){ + outVal = sync.fas.getPresetNumber() != p1 ? p1: (p2 - 1); + } + } + if(group==BMC_DEVICE_GROUP_BUTTON || group == BMC_DEVICE_GROUP_ENCODER){ + if(data.scrollEnabled()){ + sync.fas.presetScroll(data.scrollDirection(), data.scrollWrap(), data.min, data.max); + } else { + sync.fas.setPreset(outVal); + } + } else if(group == BMC_DEVICE_GROUP_DISPLAY){ + #if defined(BMC_HAS_DISPLAY) + data.highlight = sync.fas.getPresetNumber() == p1; + if(p2 > 0){ + // if p2 is more than 0 we are in toggle mode + data.highlight = false; + uint16_t current = sync.fas.getPresetNumber(); + sprintf(data.str, "P %u", ((current != p1) ? p1 : (p2-1))+data.offset); + } else { + if(data.useSelected()){ // selected + data.highlight = true; + if(data.useName()){ // name + sync.fas.getPresetName(data.str); + } else { + sprintf(data.str, "P %u", sync.fas.getPresetNumber() + data.offset); + } } else { - sprintf(str, "P %u", sync.fas.getPresetNumber() + globals.offset); + sprintf(data.str, "P %u", (uint16_t)(p1 + data.offset)); } - } else { - sprintf(str, "P %u", (uint16_t)(p1 + globals.offset)); } + // display.renderText(deviceIndex, data.oled, data.type, str, "PRESET", highlight); + strcpy(data.label, "PRESET"); + display.renderText(data); + #endif + } else { + return sync.fas.getPresetNumber() == p1; } - display.renderText(deviceIndex, isOled, e.type, str, "PRESET", highlight); -#endif - } else { - return sync.fas.getPresetNumber()==(event & 0x3FF); } break; case BMC_EVENT_TYPE_FAS_BLOCK: @@ -1519,66 +1869,68 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, if(!sync.fas.connected()){ return 0; } - switch(byteA){ + switch(data.byteA){ case 0: - sync.fas.setBlockBypass(byteB); // bypass block + sync.fas.setBlockBypass(data.byteB); // bypass block break; case 1: - sync.fas.setBlockEngage(byteB); // engage block + sync.fas.setBlockEngage(data.byteB); // engage block break; case 2: - sync.fas.toggleBlockState(byteB); // toggle bypass block + sync.fas.toggleBlockState(data.byteB); // toggle bypass block break; case 3: - sync.fas.setBlockX(byteB); // set block to X + sync.fas.setBlockX(data.byteB); // set block to X break; case 4: - sync.fas.setBlockY(byteB); // set block to Y + sync.fas.setBlockY(data.byteB); // set block to Y break; case 5: - sync.fas.toggleBlockXY(byteB); // toggle XY block + sync.fas.toggleBlockXY(data.byteB); // toggle XY block break; } return 1; } else if(group == BMC_DEVICE_GROUP_LED){ - switch(byteA){ + switch(data.byteA){ case 0: - return sync.fas.isBlockBypassed(byteB); // block bypass state + return sync.fas.isBlockBypassed(data.byteB); // block bypass state case 1: case 2: - return sync.fas.isBlockEngaged(byteB); // block bypass state + return sync.fas.isBlockEngaged(data.byteB); // block bypass state case 3: - return sync.fas.isBlockX(byteB); // block x/y state + return sync.fas.isBlockX(data.byteB); // block x/y state case 4: case 5: - return sync.fas.isBlockY(byteB); // block x/y state + return sync.fas.isBlockY(data.byteB); // block x/y state } } else if(group == BMC_DEVICE_GROUP_MAGIC_ENCODER){ - switch(byteA){ + switch(data.byteA){ case 0: - return sync.fas.isBlockBypassed(byteB) ? 100 : 0; // block bypass state + return sync.fas.isBlockBypassed(data.byteB) ? 100 : 0; // block bypass state case 1: case 2: - return sync.fas.isBlockEngaged(byteB) ? 100 : 0; // block bypass state + return sync.fas.isBlockEngaged(data.byteB) ? 100 : 0; // block bypass state case 3: - return sync.fas.isBlockX(byteB) ? 100 : 0; // block x/y state + return sync.fas.isBlockX(data.byteB) ? 100 : 0; // block x/y state case 4: case 5: - return sync.fas.isBlockY(byteB) ? 100 : 0; // block x/y state + return sync.fas.isBlockY(data.byteB) ? 100 : 0; // block x/y state } } else if(group == BMC_DEVICE_GROUP_DISPLAY){ if(!sync.fas.connected()){ return 0; } - bool blockState = sync.fas.isBlockEngaged(byteB); + data.highlight = sync.fas.isBlockEngaged(data.byteB); char blockName[5] = ""; char blockXY[5] = ""; - char str[10] = ""; + // char str[10] = ""; - sync.fas.getBlockName(byteB, blockName); - sprintf(blockXY, "%s", sync.fas.isBlockX(byteB)?"x":"y"); - sprintf(str, "%s %s", blockName, blockXY); - display.renderText(deviceIndex, isOled, e.type, str, "BLOCK", blockState); + sync.fas.getBlockName(data.byteB, blockName); + sprintf(blockXY, "%s", sync.fas.isBlockX(data.byteB)?"x":"y"); + sprintf(data.str, "%s %s", blockName, blockXY); + // display.renderText(deviceIndex, data.oled, data.type, str, "BLOCK", blockState); + strcpy(data.label, "BLOCK"); + display.renderText(data); } break; case BMC_EVENT_TYPE_FAS_BLOCK_PARAM: @@ -1587,48 +1939,51 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, #ifdef BMC_USE_HELIX case BMC_EVENT_TYPE_HELIX: if(group==BMC_DEVICE_GROUP_BUTTON || group==BMC_DEVICE_GROUP_ENCODER){ - if(scroll.enabled){ - if(byteC > 0){ - sync.helix.snapshotScroll(scroll.direction, byteB, byteC); + if(data.scrollEnabled()){ + if(data.byteC > 0){ + sync.helix.snapshotScroll(data.scrollDirection(), data.byteB, data.byteC); } else { - sync.helix.snapshotScroll(scroll.direction); + sync.helix.snapshotScroll(data.scrollDirection()); } } else { - if(byteC > 0){ - sync.helix.command(BMC_HELIX_CMD_SNAPSHOT_TOGGLE, byteB, byteC); + if(data.byteC > 0){ + sync.helix.command(BMC_HELIX_CMD_SNAPSHOT_TOGGLE, data.byteB, data.byteC); } else { - sync.helix.command(byteA, byteB, byteC); + sync.helix.command(data.byteA, data.byteB, data.byteC); } } } else if(group == BMC_DEVICE_GROUP_DISPLAY){ #if defined(BMC_HAS_DISPLAY) - char str[12] = ""; - if(bitRead(displaySettings, 3)){ // display name - switch(byteA){ + // char str[12] = ""; + if(data.useName()){ // display name + switch(data.byteA){ case BMC_HELIX_CMD_TAP: - strcpy(str, "HX TAP"); + strcpy(data.str, "HX TAP"); break; case BMC_HELIX_CMD_TUNER: - strcpy(str, "HX TUNNER"); + strcpy(data.str, "HX TUNNER"); break; case BMC_HELIX_CMD_SNAPSHOT: - sprintf(str, "SN %u", byteB+globals.offset); + sprintf(data.str, "SN %u", data.byteB+data.offset); break; case BMC_HELIX_CMD_SNAPSHOT_TOGGLE: - sprintf(str, "SN %u %u", byteB+globals.offset, byteC+globals.offset); + sprintf(data.str, "SN %u %u", data.byteB+data.offset, data.byteC+data.offset); break; } } else { // display number - if(bitRead(displaySettings, 2)){// selected - sprintf(str, "SN %u", sync.helix.getSnapshot()+globals.offset); + if(data.useSelected()){// selected + sprintf(data.str, "SN %u", sync.helix.getSnapshot()+data.offset); } else { - sprintf(str, "SN %u", byteB+globals.offset); + sprintf(data.str, "SN %u", data.byteB+data.offset); } } - display.renderText(deviceIndex, isOled, e.type, str, "HELIX", sync.helix.isSnapshot(byteB)); + // display.renderText(deviceIndex, data.oled, data.type, str, "HELIX", sync.helix.isSnapshot(data.byteB)); + strcpy(data.label, "HELIX"); + data.highlight = sync.helix.isSnapshot(data.byteB); + display.renderText(data); #endif } else { - return sync.helix.isSnapshot(byteB); + return sync.helix.isSnapshot(data.byteB); } @@ -1637,10 +1992,10 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, #if BMC_MAX_CUSTOM_SYSEX > 0 case BMC_EVENT_TYPE_CUSTOM_SYSEX: if(group==BMC_DEVICE_GROUP_BUTTON){ - // byteA = send mode, 0, 1 or 2 - // byteB = index of the 1st custom sysex item to send - // byteC = index of the 2nd custom sysex item to send - customSysEx.send((byteA & 0x03), e.ports, byteB, byteC); + // data.byteA = send mode, 0, 1 or 2 + // data.byteB = index of the 1st custom sysex item to send + // data.byteC = index of the 2nd custom sysex item to send + customSysEx.send((data.byteA & 0x03), e.ports, data.byteB, data.byteC); } break; #endif @@ -1650,20 +2005,20 @@ uint8_t BMC::processEvent(uint8_t group, uint8_t deviceId, if(group == BMC_DEVICE_GROUP_BUTTON){ // dat1 has the press type // dat2 is unused - callback.customActivity(deviceId, deviceIndex, byteA, dat, 0); + callback.customActivity(deviceId, deviceIndex, data.byteA, dat, 0); } else if(group == BMC_DEVICE_GROUP_ENCODER){ // dat1 has the direction // dat2 has the number of ticks - callback.customActivity(deviceId, deviceIndex, byteA, bitRead(value, 7), value & 0x7F); + callback.customActivity(deviceId, deviceIndex, data.byteA, bitRead(value, 7), value & 0x7F); } else if(group == BMC_DEVICE_GROUP_POT){ // dat1 has the pot value - callback.customActivity(deviceId, deviceIndex, byteA, value, 0); + callback.customActivity(deviceId, deviceIndex, data.byteA, value, 0); } else if(group == BMC_DEVICE_GROUP_LED){ // for rgb pixles dat1 is the color index, 0=r, 1=g, 2=b // same applies to bi and tri leds, where dat is the index of the color // for leds and pixels this function must return true or false, where // true will turn (and keep) the led on and false will turn it off - return callback.customActivity(deviceId, deviceIndex, byteA, dat, 0); + return callback.customActivity(deviceId, deviceIndex, data.byteA, dat, 0); } } break; @@ -1675,9 +2030,9 @@ void BMC::handleClockLeds(){ #if BMC_MAX_LEDS > 0 for(uint8_t index = 0; index < BMC_MAX_LEDS; index++){ bmcStoreDevice <1, 1>& device = store.layers[layer].leds[index]; - bmcStoreEvent data = globals.getDeviceEventType(device.events[0]); + bmcStoreEvent cData = globals.getDeviceEventType(device.events[0]); // first bit is always the "blink" state - if(BMCTools::isMidiClockLedEvent(data.type)){ + if(BMCTools::isMidiClockLedEvent(cData.type)){ // last 4 bits are always the color leds[index].pulse(); } @@ -1692,9 +2047,9 @@ void BMC::handleClockLeds(){ #if BMC_MAX_GLOBAL_LEDS > 0 for(uint8_t index = 0; index < BMC_MAX_GLOBAL_LEDS; index++){ bmcStoreDevice <1, 1>& device = store.global.leds[index]; - bmcStoreEvent data = globals.getDeviceEventType(device.events[0]); + bmcStoreEvent cData = globals.getDeviceEventType(device.events[0]); // first bit is always the "blink" state - if(BMCTools::isMidiClockLedEvent(data.type)){ + if(BMCTools::isMidiClockLedEvent(cData.type)){ // last 4 bits are always the color globalLeds[index].pulse(); } @@ -1705,9 +2060,9 @@ void BMC::handleClockLeds(){ #if BMC_MAX_PIXELS > 0 for(uint8_t index = 0; index < BMC_MAX_PIXELS; index++){ bmcStoreDevice <1, 1>& device = store.layers[layer].pixels[index]; - bmcStoreEvent data = globals.getDeviceEventType(device.events[0]); + bmcStoreEvent cData = globals.getDeviceEventType(device.events[0]); // first bit is always the "blink" state - if(BMCTools::isMidiClockLedEvent(data.type)){ + if(BMCTools::isMidiClockLedEvent(cData.type)){ // last 4 bits are always the color pixels.pulse(index, device.settings[0]); } @@ -1719,9 +2074,9 @@ void BMC::handleClockLeds(){ bmcStoreDevice <1, 3>& device = store.layers[layer].rgbPixels[index]; for(uint8_t e = 0; e < 3; e++){ - bmcStoreEvent data = globals.getDeviceEventType(device.events[e]); + bmcStoreEvent cData = globals.getDeviceEventType(device.events[e]); // first bit is always the "blink" state - if(BMCTools::isMidiClockLedEvent(data.type)){ + if(BMCTools::isMidiClockLedEvent(cData.type)){ // last 4 bits are always the color pixels.pulseRgb(index, e); } diff --git a/src/BMC.h b/src/BMC.h index 1f5d7a8..1974a3a 100644 --- a/src/BMC.h +++ b/src/BMC.h @@ -155,6 +155,12 @@ class BMC { // code @ BMC.layer.cpp // get the current layer number uint8_t getLayer(); + // layer name + bmcStoreName getLayerName(); + bmcStoreName getLayerName(uint8_t n); + bmcStoreName getLayerStr(); + bmcStoreName getLayerStr(uint8_t n); + // go to a new layer // @reassignSettings if true will reassign all global settings void setLayer(uint8_t layer, bool reassignSettings=false, bool forced=false); @@ -296,6 +302,7 @@ class BMC { void runLayerChanged(){ #if defined(BMC_HAS_DISPLAY) && BMC_MAX_ILI9341_BLOCKS > 0 + globals.setRenderDisplayList(BMC_DEVICE_ID_LAYER); display.renderLayerBanner(); #endif @@ -315,6 +322,7 @@ class BMC { void runPresetChanged(){ #if BMC_MAX_PRESETS > 0 #if defined(BMC_HAS_DISPLAY) && BMC_MAX_ILI9341_BLOCKS > 0 + globals.setRenderDisplayList(BMC_DEVICE_ID_PRESET); display.renderPresetBanner(); #endif @@ -352,6 +360,7 @@ class BMC { } void runBankChanged(){ #if BMC_MAX_PRESETS > 0 + globals.setRenderDisplayList(BMC_DEVICE_ID_PRESET); if(callback.presetBankChanged){ callback.presetBankChanged(presets.getBank()); } @@ -359,9 +368,12 @@ class BMC { } void runSetListChanged(){ #if BMC_MAX_SETLISTS > 0 - #if defined(BMC_HAS_DISPLAY) && BMC_MAX_ILI9341_BLOCKS > 0 + #if BMC_MAX_ILI9341_BLOCKS > 0 + globals.setRenderDisplayList(BMC_DEVICE_ID_SETLIST); display.renderSetListBanner(); #endif + + /* char setListName[30] = ""; @@ -376,6 +388,7 @@ class BMC { void runSongChanged(){ #if BMC_MAX_SETLISTS > 0 #if defined(BMC_HAS_DISPLAY) && BMC_MAX_ILI9341_BLOCKS > 0 + globals.setRenderDisplayList(BMC_DEVICE_ID_SETLIST); display.renderSongBanner(); #endif @@ -659,6 +672,7 @@ class BMC { void setupDebug(); void readDebug(); void printBoardInfo(); + void printSyncInfo(); void printButtonTrigger(uint8_t n, uint8_t t_trigger, bool t_global=false); void printDebugHeader(char* str); void midiInDebug(BMCMidiMessage midiMessage); diff --git a/src/BMC.hardware.buttons.cpp b/src/BMC.hardware.buttons.cpp index 0a736f5..f1d32d9 100644 --- a/src/BMC.hardware.buttons.cpp +++ b/src/BMC.hardware.buttons.cpp @@ -134,12 +134,17 @@ void BMC::readButtons(){ } template -void BMC::handleButton(bmcStoreDevice& device, uint8_t deviceType, - uint16_t index, uint8_t t_trigger){ +void BMC::handleButton(bmcStoreDevice& device, uint8_t deviceType, uint16_t index, uint8_t t_trigger){ + #if defined(BMC_USE_ON_BOARD_EDITOR) + if(obe.checkDeviceAssignment(deviceType, index, t_trigger)){ + return; + } + #endif for(uint8_t e = 0; e < BMC_MAX_BUTTON_EVENTS; e++){ bmcStoreEvent data = globals.getDeviceEventType(device.events[e]); uint8_t type = data.type; uint8_t trigger = (device.settings[e] & 0x0F) == t_trigger ? t_trigger : BMC_NONE; + if(type == BMC_NONE || trigger == BMC_NONE){ continue; } @@ -163,621 +168,3 @@ void BMC::handleButton(bmcStoreDevice& device, uint8_t deviceType, #endif - -#if BMC_MAX_BUTTONS > 0 || BMC_MAX_GLOBAL_BUTTONS > 0 -/* - void BMC::handleButtonEvent(uint8_t type, bmcStoreEvent data){ - - #if defined(BMC_ENABLE_ENCODER_BUTTON_FILTERING) - encoderFixTimer.start(BMC_ENCODER_BUTTON_DEBOUNCE_TIME); - #endif - uint32_t event = data.event; - uint8_t ports = data.ports; - uint8_t byteA = BMC_GET_BYTE(1, event); - uint8_t byteB = BMC_GET_BYTE(2, event); - uint8_t byteC = BMC_GET_BYTE(3, event); - switch(parseMidiEventType(type)){ - case BMC_BUTTON_EVENT_TYPE_MASTER_CLOCK_TAP: - midiClock.tap(); - break; - case BMC_BUTTON_EVENT_TYPE_MASTER_CLOCK_SET: - midiClock.setBpm((event >> 8) & 0x1FF); - break; - - case BMC_EVENT_TYPE_CUSTOM: - // this is a standard custom event for all hardware the value is 127 - // it's meant to be used by your sketch - break; - case BMC_MIDI_RT_START: - case BMC_MIDI_RT_CONTINUE: - case BMC_MIDI_RT_STOP: - case BMC_MIDI_SONG_SELECT: - case BMC_MIDI_RT_SYSTEM_RESET: - midi.send(ports, event);// standard midi event - break; - case BMC_MIDI_NOTE_OFF: - case BMC_MIDI_NOTE_ON: - case BMC_MIDI_CONTROL_CHANGE: - midi.send(ports, event);// standard midi event - streamMidi(type & 0xF0, BMC_TO_MIDI_CHANNEL(type), byteA, byteB); - break; - case BMC_MIDI_PROGRAM_CHANGE: - midi.send(ports, event);// standard midi event - streamMidi(type & 0xF0, BMC_TO_MIDI_CHANNEL(type), byteA); - break; - case BMC_MIDI_PITCH_BEND: - { - // the pitch value stored in the event must be in a range - // from -100 to 100 which is then mapped to -8192 to 8191 - int pitch = (int) map((int8_t) byteA, -100, 100, -8192, 8191); - midi.sendPitchBend(ports, BMC_TO_MIDI_CHANNEL(type), pitch); - } - break; - - #if BMC_MAX_LAYERS > 1 - case BMC_BUTTON_EVENT_TYPE_LAYER: - setLayer(byteA); - break; - case BMC_BUTTON_EVENT_TYPE_LAYER_SCROLL: - // byteA = flags, bit-0 direction, bit-1 endless - // byteB = min layer - // byteC = max layer - scrollLayer(byteA, byteB, byteC, 1); - break; - #endif - case BMC_BUTTON_EVENT_TYPE_PROGRAM_SCROLL: - // byteA (bits 0-3) = Channel (0 to 15) - // byteA (bits 4-7) = flags, bit-0 direction, bit-1 endless - // byteB = min program - // byteC = max program - { - uint8_t val = midi.scrollPC(ports, BMC_TO_MIDI_CHANNEL(byteA), (byteA>>4), byteB, byteC); - streamMidiProgram(BMC_TO_MIDI_CHANNEL(byteA), val); - } - - break; - case BMC_BUTTON_EVENT_TYPE_CONTROL_SCROLL: - // byteA (bits 0-3) = Channel (0 to 15) - // byteA (bits 4-7) = flags, bit-0 direction, bit-1 endless - // byteB = Control Number - { - uint8_t val = midi.scrollCC(ports, BMC_TO_MIDI_CHANNEL(byteA), byteB, (byteA>>4)); - streamMidiControl(BMC_TO_MIDI_CHANNEL(byteA), byteB, val); - } - - break; - case BMC_BUTTON_EVENT_TYPE_CONTROL_TOGGLE: - // Toggle a CC value between 0 and 127, if current value is more than 0 - // it will be set to 0 - // byteA = channel - // byteB = control number - { - uint8_t val = midi.toggleCC(ports, BMC_TO_MIDI_CHANNEL(byteA), byteB); - streamMidiControl(BMC_TO_MIDI_CHANNEL(byteA), byteB, val); - } - break; - case BMC_BUTTON_EVENT_TYPE_CONTROL_TOGGLE_2: - // Toggle a CC value between 2 different values other than 0 - // BMC_BUTTON_EVENT_TYPE_CONTROL_TOGGLE toggles you between 0 and 127 - // this aims to toggle between different values than those 2 - // we got 24-bits to work with after removing the type from the event - // 4-bits for channel - // 7-bits for CC# - // 7-bits for min - // 7-bits for max - // in other words not enough bits!!! so we gotta sacrifice one bit - // since the channel and CC# are required the bit will have to come - // out of the min/max values, since the max should be a higher value - // we can take the bit from the min making the min value between 0-63 - // 4-bits for channel (bits 8-11) - // 7-bits for CC# (bits 12-18) - // 6-bits for min (19-24) - // 7-bits for max (25-31) - { - uint8_t channel = BMC_TO_MIDI_CHANNEL((event>>8)); - uint8_t cc = ((event>>12) & 0x7F); - uint8_t min = ((event>>19) & 0x3F); - uint8_t max = ((event>>25) & 0x7F); - uint8_t currentValue = midi.getLocalControl(channel, cc); - if(currentValue==min){ - // if the current value is the same as the min go to the max - currentValue = max; - } else { - // otherwise go to the min - currentValue = min; - } - // we use the currentValue variable to store the value will be sending - midi.sendControlChange(ports, channel, cc, currentValue); - streamMidiControl(channel, cc, currentValue); - } - break; -#if BMC_MAX_PIXEL_PROGRAMS > 0 - case BMC_BUTTON_EVENT_TYPE_PIXEL_PROGRAM: - if(byteA>0){ - pixelPrograms.setProgram(byteA-1); - } else { - pixelPrograms.toggleBlackout(); - } - break; - case BMC_BUTTON_EVENT_TYPE_PIXEL_PROGRAM_SCROLL: - // byteA flags, 0: dir, 1: limit - // byteB min - // byteC max - pixelPrograms.scroll(bitRead(byteA, 0), bitRead(byteA, 1), byteB, byteC); - break; -#endif - case BMC_BUTTON_EVENT_TYPE_ACTIVE_SENSE: - // byteA = command, 0 stop, 1 start, 2 toggle - // see utility/BMC-Def.h for list - // all prefixed with "BMC_ACTIVE_SENSE_" - // ports = where the Active sense will be sent to - // if ports are not specified the default listener ports are used - midiActiveSense.command(byteA); - break; - - case BMC_BUTTON_EVENT_TYPE_STOPWATCH: - stopwatchCmd(byteA&0x07, ((byteA>>3)&0x1F), byteB, byteC); - break; - - #ifdef BMC_MIDI_BLE_ENABLED - case BMC_BUTTON_EVENT_TYPE_BLE_DISCONNECT: - midi.disconnectBLE(); - break; - #endif - - #if BMC_MAX_NL_RELAYS > 0 - case BMC_BUTTON_EVENT_TYPE_NL_RELAY_CONTROL: - if(byteA < BMC_MAX_NL_RELAYS){ - relaysNL[byteA].command(byteB); - } - break; - #if BMC_MAX_NL_RELAYS > 1 - case BMC_BUTTON_EVENT_TYPE_NL_RELAY_CONTROL_TOGGLE: - if(byteA < BMC_MAX_NL_RELAYS && byteB < BMC_MAX_NL_RELAYS){ - if(relaysNL[byteA].getState()){ - relaysNL[byteA].command(BMC_RELAY_NO); - relaysNL[byteB].command(BMC_RELAY_NC); - } else { - relaysNL[byteA].command(BMC_RELAY_NC); - relaysNL[byteB].command(BMC_RELAY_NO); - } - } - break; - #endif - #endif - - #if BMC_MAX_L_RELAYS > 0 - case BMC_BUTTON_EVENT_TYPE_L_RELAY_CONTROL: - if(byteA < BMC_MAX_L_RELAYS){ - relaysL[byteA].command(byteB); - } - break; - #if BMC_MAX_L_RELAYS > 1 - case BMC_BUTTON_EVENT_TYPE_L_RELAY_CONTROL_TOGGLE: - if(byteA < BMC_MAX_L_RELAYS && byteB < BMC_MAX_L_RELAYS){ - if(relaysL[byteA].getState()){ - relaysL[byteA].command(BMC_RELAY_NO); - relaysL[byteB].command(BMC_RELAY_NC); - } else { - relaysL[byteA].command(BMC_RELAY_NC); - relaysL[byteB].command(BMC_RELAY_NO); - } - } - break; - #endif - #endif - - #if BMC_MAX_SKETCH_BYTES > 0 - case BMC_BUTTON_EVENT_TYPE_SKETCH_BYTE_SET: - { - byteA = constrain(byteA, 0, BMC_MAX_SKETCH_BYTES); - BMCSketchByteData data = BMCBuildData::getSketchByteData(byteA); - byteB = constrain(byteB, data.min, data.max); - streamToSketch(BMC_DEVICE_ID_SKETCH_BYTES, byteB, data.name); - setSketchByte(byteA, byteB); - if(callback.storeUpdated){ - callback.storeUpdated(); - } - } - break; - case BMC_BUTTON_EVENT_TYPE_SKETCH_BYTE_SCROLL: - { - uint8_t n = (byteA >> 2) & 0x3F; - n = constrain(n, 0, BMC_MAX_SKETCH_BYTES); - - BMCSketchByteData data = BMCBuildData::getSketchByteData(n); - - byteB = constrain(byteB, data.min, data.max); - byteC = constrain(byteC, data.min, data.max); - - uint8_t tmp = getSketchByte(n); - - BMCScroller scroller(data.min, data.max); - tmp = scroller.scroll(data.step, bitRead(byteA,0), bitRead(byteA,1), tmp, byteB, byteC); - streamToSketch(BMC_DEVICE_ID_SKETCH_BYTES, tmp, data.name); - - setSketchByte(n, tmp); - if(callback.storeUpdated){ - callback.storeUpdated(); - } - } - break; - case BMC_BUTTON_EVENT_TYPE_SKETCH_BYTE_TOGGLE: - { - byteA = constrain(byteA, 0, BMC_MAX_SKETCH_BYTES); - BMCSketchByteData data = BMCBuildData::getSketchByteData(byteA); - byteB = constrain(byteB, data.min, data.max); - byteC = constrain(byteC, data.min, data.max); - uint8_t tmp = getSketchByte(byteA); - if(tmp!=byteB){ - setSketchByte(byteA, byteB); - streamToSketch(BMC_DEVICE_ID_SKETCH_BYTES, byteB, data.name); - } else { - setSketchByte(byteA, byteC); - streamToSketch(BMC_DEVICE_ID_SKETCH_BYTES, byteC, data.name); - } - streamToSketch(0, byteB, data.name); - if(callback.storeUpdated){ - callback.storeUpdated(); - } - } - break; - #endif - - #if BMC_MAX_LEDS > 0 - case BMC_BUTTON_EVENT_TYPE_LED_TEMP_BLINK: - if(byteA 0 - case BMC_BUTTON_EVENT_TYPE_GLOBAL_LED_TEMP_BLINK: - if(byteA> 8) & 0x1FF); - break; - case BMC_BUTTON_EVENT_TYPE_BEATBUDDY_CMD: - // byteA = beatbuddy command - // see utility/BMC-Def.h for list - // all prefixed with "BMC_BEATBUDDY_CMD_" - sync.beatBuddy.sendCommand(byteA, byteB); - break; - case BMC_BUTTON_EVENT_TYPE_BEATBUDDY_FOLDER_SONG: - // event (bits 8 to 23) = folder number (0 to 16,383) - sync.beatBuddy.songSelect((event >> 8) & 0x3FFF, byteC); - break; - #endif - case BMC_BUTTON_EVENT_TYPE_MENU: - if(callback.menuCommand){ - callback.menuCommand(byteA); - } - break; - - #ifdef BMC_USE_CLICK_TRACK - case BMC_BUTTON_EVENT_TYPE_CLICK_TRACK: - // byteA = Command id, see utility/ClickTrack.h for possible commands - midiClock.clickTrackCommand(byteA); - break; - #endif - - case BMC_BUTTON_EVENT_TYPE_BANK_MSB_PROGRAM: - // byteA = channel - // byteB = control 0 value - // byteC = program number - midi.sendControlChange(ports, BMC_TO_MIDI_CHANNEL(byteA), 0, byteB & 0x7F); - midi.sendProgramChange(ports, BMC_TO_MIDI_CHANNEL(byteA), byteC & 0x7F); - break; - case BMC_BUTTON_EVENT_TYPE_BANK_LSB_PROGRAM: - // byteA = channel - // byteB = control 32 value - // byteC = program number - midi.sendControlChange(ports, BMC_TO_MIDI_CHANNEL(byteA), 32, byteB & 0x7F); - midi.sendProgramChange(ports, BMC_TO_MIDI_CHANNEL(byteA), byteC & 0x7F); - break; - case BMC_BUTTON_EVENT_TYPE_BANK_MSB_LSB: - // byteA = channel - // byteB = control 0 value - // byteC = control 32 value - midi.sendControlChange(ports, BMC_TO_MIDI_CHANNEL(byteA), 0, byteB & 0x7F); - midi.sendControlChange(ports, BMC_TO_MIDI_CHANNEL(byteA), 32, byteC & 0x7F); - break; - - #ifdef BMC_USE_HELIX - case BMC_BUTTON_EVENT_TYPE_HELIX_CMD: - sync.helix.command(byteA, byteB, byteC); - break; - #endif - - #ifdef BMC_USE_FAS - case BMC_BUTTON_EVENT_TYPE_FAS_COMMAND: - if(byteA==0){ - sync.fas.tapTempo(); - } else if(byteA==1){ - sync.fas.toggleTuner(); - } else if(byteA==2){ - sync.fas.disconnect(); - } else if(byteA==3){ - sync.fas.connect(); - } else if(byteA==4){ - if(sync.fas.connected()){ - sync.fas.disconnect(); - } else { - sync.fas.connect(); - } - } else if(byteA>=5){// looper - sync.fas.looperControl(byteA-5); - } - break; - case BMC_BUTTON_EVENT_TYPE_FAS_PRESET: - sync.fas.setPreset(byteA | (byteB<<8)); - break; - case BMC_BUTTON_EVENT_TYPE_FAS_PRESET_SCROLL: - { - bool dir = bitRead(byteA,0); - bool endless = bitRead(byteA,1); - uint16_t min = (event >> 10) & 0x3FF; - uint16_t max = (event >> 20) & 0x3FF; - sync.fas.presetScroll(dir, endless, min, max); - } - break; - case BMC_BUTTON_EVENT_TYPE_FAS_SCENE: - sync.fas.setSceneNumber(byteA, byteB); - break; - case BMC_BUTTON_EVENT_TYPE_FAS_SCENE_SCROLL: - // byteA (flags) = bit-0 scroll direction, down (0), up (1) - // byteA (flags) = bit-1 limit, limited (0), endless (1) - // byteA (flags) = bit-2 revert, no-revert (0), revert (1) - // byteB = minimum scene for scrolling - // byteC = maximum scene for scrolling - sync.fas.sceneScroll(bitRead(byteA,0), bitRead(byteA,1), bitRead(byteA,2), byteB, byteC); - break; - case BMC_BUTTON_EVENT_TYPE_FAS_BLOCK_STATE: - if(byteA==0){ - // bypass block - sync.fas.setBlockBypass(byteB); - } else if(byteA==1){ - // engage block - sync.fas.setBlockEngage(byteB); - } else if(byteA==2){ - // toggle bypass block - sync.fas.toggleBlockState(byteB); - } else if(byteA==3){ - // set block to X - sync.fas.setBlockX(byteB); - } else if(byteA==4){ - // set block to Y - sync.fas.setBlockY(byteB); - } else if(byteA==5){ - // toggle XY block - sync.fas.toggleBlockXY(byteB); - } - break; - case BMC_BUTTON_EVENT_TYPE_FAS_BLOCK_PARAM: - { - uint16_t value = sync.fas.getSyncedParameterValue(byteB); - if(byteA==0){ // parameter min - if(value>0){ - sync.fas.sendChangeSyncedParameter(byteB, 0); - } - } else if(byteA==1){ // parameter max - if(value==0){ - sync.fas.sendChangeSyncedParameter(byteB, 65534); - } - } else if(byteA==2){ // parameter toggle - BMC_PRINTLN("value:", value); - if(value==0){ - sync.fas.sendChangeSyncedParameter(byteB, 65534); - } else { - sync.fas.sendChangeSyncedParameter(byteB, 0); - } - } - } - break; - #endif - - case BMC_BUTTON_EVENT_TYPE_MIDI_REAL_TIME_BLOCK: - // ignored any incoming/Outgoing MIDI real time messages - // byteA: 0=input, 1=output - // byteB: 0=allowed, 1=ignored, 2>= toggle - if(byteA==0){ - if(byteB>=2){ - midi.toggleRealTimeBlockInput(); - } else { - midi.setRealTimeBlockInput(byteB==1); - } - } else { - if(byteB>=2){ - midi.toggleRealTimeBlockOutput(); - } else { - midi.setRealTimeBlockOutput(byteB==1); - } - } - break; - case BMC_BUTTON_EVENT_TYPE_PROGRAM_BANKING_SCROLL: - // byteA = flags, bit-0 direction, bit-1 endless - midiProgramBankScroll(bitRead(byteA, 0), bitRead(byteA, 1), (byteA>>2)+1, byteB, byteC); - break; - case BMC_BUTTON_EVENT_TYPE_PROGRAM_BANKING_TRIGGER: - // byteA = Amount - // byteB = Channel - midiProgramBankTrigger(byteA, byteB, ports); - break; - case BMC_BUTTON_EVENT_TYPE_TYPER_CMD: - { - uint8_t cmd = valueTyper.cmd(byteA, byteB); - if(cmd > 10){// cmd 10 is Clear - if(cmd==12){// layer - setLayer(valueTyper.getRawOutput()); - } else if(cmd==13){// preset -#if BMC_MAX_PRESETS > 0 - presets.set(valueTyper.getRawOutput()); -#endif - } else if(cmd==14){// fas preset -#if defined(BMC_USE_FAS) - sync.fas.setPreset(valueTyper.getRawOutput()); -#endif - } else if(cmd==15){// fas scene -#if defined(BMC_USE_FAS) - sync.fas.setSceneNumber(valueTyper.getRawOutput(), false); -#endif - } else if(cmd==16){// fas scene revert -#if defined(BMC_USE_FAS) - sync.fas.setSceneNumber(valueTyper.getRawOutput(), true); -#endif - } else if(cmd==17){// set typer channel for midi modes - // channel - uint8_t ch = valueTyper.getRawOutput(); - if(ch>=0 && ch<=15){ - typerChannel = ch+1; - } - } else if(cmd==18){ - // program - uint8_t pc = valueTyper.getRawOutput(); - midi.sendProgramChange(ports, typerChannel, pc); - streamMidiProgram(typerChannel, pc); - } else if(cmd==19){ - // control 0 value - uint8_t val = valueTyper.getRawOutput(); - midi.sendControlChange(ports, typerChannel, 0, val); - streamMidiControl(typerChannel, 0, val); - } else if(cmd==20){ - // control toggle - uint8_t cc = valueTyper.getRawOutput(); - uint8_t val = midi.toggleCC(ports, typerChannel, cc); - midi.sendControlChange(ports, typerChannel, cc, val); - streamMidiControl(typerChannel, cc, val); - } - } - } - break; - - #if BMC_MAX_CUSTOM_SYSEX > 0 - case BMC_BUTTON_EVENT_TYPE_CUSTOM_SYSEX: - // byteA = send mode, 0, 1 or 2 - // byteB = index of the 1st custom sysex item to send - // byteC = index of the 2nd custom sysex item to send - customSysEx.send((byteA & 0x03), ports, byteB, byteC); - break; - #endif - - #if BMC_MAX_TIMED_EVENTS > 0 - case BMC_BUTTON_EVENT_TYPE_TIMED_EVENT: - // byteA = timed event Index - timedEvents.trigger(byteA); - break; - #endif - - - - #if BMC_MAX_PRESETS > 0 - case BMC_BUTTON_EVENT_TYPE_PRESET: - // byteA = index of preset to send - // byteB = if 0 use send each library item of the preset to it's ports - // if 1 or more, override all ports - presets.set(BMC_EVENT_TO_PRESET_NUM(event>>8), (byteC > 0), ports); - break; - case BMC_BUTTON_EVENT_TYPE_PRESET_SCROLL: - // byteA (flags) = bit-0 scroll direction, down (0), up (1) - // byteA (flags) = bit-1 limit, limited (0), endless (1) - // byteB = maximum preset for scrolling - // byteC = maximum preset for scrolling - presets.scroll(1, byteA, 0, BMC_EVENT_TO_PRESET_NUM(event>>16)); - break; - case BMC_BUTTON_EVENT_TYPE_PRESET_IN_BANK: - // byteA = index of preset to send - // byteB = if 0 use send each library item of the preset to it's ports - // if 1 or more, override all ports - presets.setInBank(byteA, (byteB > 0), ports); - break; - case BMC_BUTTON_EVENT_TYPE_PRESET_IN_BANK_SCROLL: - // byteA (flags) = bit-0 scroll direction, down (0), up (1) - // byteA (flags) = bit-1 limit, limited (0), endless (1) - // byteB = minimum bank for scrolling - // byteC = maximum bank for scrolling - presets.scrollInBank(1, byteA, byteB, byteC); - break; - case BMC_BUTTON_EVENT_TYPE_PRESETS_SET_BANK: - // byteA = index of bank to switch to - presets.setBank(byteA); - break; - case BMC_BUTTON_EVENT_TYPE_PRESETS_BANK_SCROLL: - // byteA (flags) = bit-0 scroll direction, down (0), up (1) - // byteA (flags) = bit-1 limit, limited (0), endless (1) - // byteB = minimum preset for scrolling - // byteC = maximum preset for scrolling - presets.bankScroll(1, byteA, byteB, byteC); - break; - #endif // BMC_MAX_PRESETS > 0 && BMC_MAX_PRESET_ITEMS > 0 - - #if BMC_MAX_PRESETS > 0 && BMC_MAX_SETLISTS > 0 && BMC_MAX_SETLISTS_SONGS > 0 - case BMC_BUTTON_EVENT_TYPE_SETLIST: - // byteA = index of setList to send - // byteB = switch to first song of selected setlist is value is 1 - setLists.set(byteA, (byteB > 0)); - break; - case BMC_BUTTON_EVENT_TYPE_SETLIST_SCROLL: - // byteA (flags) = bit-0 scroll direction, down (0), up (1) - // byteA (flags) = bit-1 limit, limited (0), endless (1) - // byteB = minimum setList for scrolling - // byteC = maximum setList for scrolling - setLists.scroll(1, byteA, byteB, byteC); - break; - case BMC_BUTTON_EVENT_TYPE_SETLIST_SONG: - // byteA = index of setList to send - setLists.setSong(byteA); - break; - case BMC_BUTTON_EVENT_TYPE_SETLIST_SONG_SCROLL: - // scroll thru currently selected setlist songs - // byteA (flags) = bit-0 scroll direction, down (0), up (1) - // byteA (flags) = bit-1 limit, limited (0), endless (1) - // byteB = minimum song for scrolling - // byteC = maximum song for scrolling - setLists.scrollSong(1, byteA, byteB, byteC); - break; - case BMC_BUTTON_EVENT_TYPE_SETLIST_SONG_PART: - // byteA = index of setList to send - setLists.setPart(byteA); - break; - case BMC_BUTTON_EVENT_TYPE_SETLIST_SONG_PART_SCROLL: - // scroll thru currently selected setlist songs - // byteA (flags) = bit-0 scroll direction, down (0), up (1) - // byteA (flags) = bit-1 limit, limited (0), endless (1) - // byteB = minimum song for scrolling - // byteC = maximum song for scrolling - setLists.scrollPart(1, byteA, byteB, byteC); - break; - #endif // BMC_MAX_SETLISTS > 0 && BMC_MAX_SETLISTS_SONGS > 0 - - #ifdef BMC_USE_DAW_LC - case BMC_EVENT_TYPE_DAW_COMMAND: break;// handled in the press type handler - #endif - - case BMC_BUTTON_EVENT_TYPE_USER_1: - case BMC_BUTTON_EVENT_TYPE_USER_2: - case BMC_BUTTON_EVENT_TYPE_USER_3: - case BMC_BUTTON_EVENT_TYPE_USER_4: - case BMC_BUTTON_EVENT_TYPE_USER_5: - case BMC_BUTTON_EVENT_TYPE_USER_6: - case BMC_BUTTON_EVENT_TYPE_USER_7: - case BMC_BUTTON_EVENT_TYPE_USER_8: - if(callback.userEventButtons){ - callback.userEventButtons(parseUserEventType(type), event, ports, data.settings); - } - break; - } - } -*/ -#endif diff --git a/src/BMC.hardware.cpp b/src/BMC.hardware.cpp index 1597cf4..f8e0632 100644 --- a/src/BMC.hardware.cpp +++ b/src/BMC.hardware.cpp @@ -128,19 +128,32 @@ void BMC::readHardware(){ #if BMC_MAX_OLED > 0 || BMC_MAX_ILI9341_BLOCKS > 0 if(oneMillisecondPassed()){ + if(globals.offset == 0){ + BMC_PRINTLN("???????????????"); + } + #if BMC_MAX_ILI9341_BLOCKS > 0 + if(!globals.pauseIli()){ + for(uint8_t index = 0 ; index < BMC_MAX_ILI9341_BLOCKS ; index++){ + uint16_t eIndex = store.layers[layer].ili[index].events[0]; + processEvent(BMC_DEVICE_GROUP_DISPLAY, BMC_DEVICE_ID_ILI, index, eIndex); + } + } + #if (BMC_MAX_SETLISTS > 0 || BMC_MAX_LAYERS > 1 || BMC_MAX_PRESETS > 0) + if(globals.getRenderDisplayList()){ + display.renderDisplayLists(); + } else if(globals.displayListsComplete()){ + globals.exitDisplayListMode(); + display.reassign(); + } + #endif + #endif + #if BMC_MAX_OLED > 0 for(uint8_t index = 0 ; index < BMC_MAX_OLED ; index++){ uint16_t eIndex = store.layers[layer].oled[index].events[0]; processEvent(BMC_DEVICE_GROUP_DISPLAY, BMC_DEVICE_ID_OLED, index, eIndex); } #endif - - #if BMC_MAX_ILI9341_BLOCKS > 0 - for(uint8_t index = 0 ; index < BMC_MAX_ILI9341_BLOCKS ; index++){ - uint16_t eIndex = store.layers[layer].ili[index].events[0]; - processEvent(BMC_DEVICE_GROUP_DISPLAY, BMC_DEVICE_ID_ILI, index, eIndex); - } - #endif } #endif diff --git a/src/BMC.hardware.encoders.cpp b/src/BMC.hardware.encoders.cpp index c11f1af..ae23f18 100644 --- a/src/BMC.hardware.encoders.cpp +++ b/src/BMC.hardware.encoders.cpp @@ -52,6 +52,11 @@ void BMC::readEncoders(){ if(encoders[i].update()){ bool increased = encoders[i].increased(); uint8_t ticks = encoders[i].getTicks(); + #if defined(BMC_USE_ON_BOARD_EDITOR) + if(obe.checkDeviceAssignment(BMC_DEVICE_ID_ENCODER, i, increased, ticks)){ + break; + } + #endif processEvent(BMC_DEVICE_GROUP_ENCODER, BMC_DEVICE_ID_ENCODER, i, @@ -86,6 +91,11 @@ void BMC::readEncoders(){ if(globalEncoders[i].update()){ bool increased = globalEncoders[i].increased(); uint8_t ticks = globalEncoders[i].getTicks(); + #if defined(BMC_USE_ON_BOARD_EDITOR) + if(obe.checkDeviceAssignment(BMC_DEVICE_ID_GLOBAL_ENCODER, i, increased, ticks)){ + break; + } + #endif processEvent(BMC_DEVICE_GROUP_ENCODER, BMC_DEVICE_ID_GLOBAL_ENCODER, i, diff --git a/src/BMC.layers.cpp b/src/BMC.layers.cpp index ee37545..b43bb23 100644 --- a/src/BMC.layers.cpp +++ b/src/BMC.layers.cpp @@ -33,7 +33,11 @@ void BMC::setLayer(uint8_t t_layer, bool reassignSettings, bool forced){ #endif #if defined(BMC_HAS_DISPLAY) - display.reassign(); + if(!globals.displayListsActive()){ + // display.midi.globals.exitDisplayListMode(); + display.reassign(); + } + #endif #if defined(BMC_USE_BEATBUDDY) @@ -57,13 +61,40 @@ bool BMC::layerChangedPeek(){ uint8_t BMC::getLayer(){ return layer; } +bmcStoreName BMC::getLayerName(){ + bmcStoreName t = globals.getDeviceName(store.layers[layer].events[0].name); + if(BMC_STR_MATCH(t.name, "")){ + sprintf(t.name, "L %u", layer+globals.offset); + } + return t; +} +bmcStoreName BMC::getLayerName(uint8_t n){ + bmcStoreName t = globals.getDeviceName(store.layers[n].events[0].name); + if(BMC_STR_MATCH(t.name, "")){ + sprintf(t.name, "L %u", n+globals.offset); + } + return t; +} + +bmcStoreName BMC::getLayerStr(){ + bmcStoreName t; + sprintf(t.name, "%u", layer+midi.globals.offset); + return t; +} +bmcStoreName BMC::getLayerStr(uint8_t n){ + bmcStoreName t; + sprintf(t.name, "%u", n+midi.globals.offset); + return t; +} void BMC::nextLayer(){ - BMCScroller scroller(0, BMC_MAX_LAYERS-1); - setLayer(scroller.scroll(1, true, true, layer, 0, BMC_MAX_LAYERS-1)); + // BMCScroller scroller(0, BMC_MAX_LAYERS-1); + // setLayer(scroller.scroll(1, true, true, layer, 0, BMC_MAX_LAYERS-1)); + scrollLayer(BMC_NEXT, BMC_WRAP, 1); } void BMC::prevLayer(){ - BMCScroller scroller(0, BMC_MAX_LAYERS-1); - setLayer(scroller.scroll(1, false, true, layer, 0, BMC_MAX_LAYERS-1)); + // BMCScroller scroller(0, BMC_MAX_LAYERS-1); + // setLayer(scroller.scroll(1, false, true, layer, 0, BMC_MAX_LAYERS-1)); + scrollLayer(BMC_PREV, BMC_WRAP, 1); } void BMC::scrollLayer(bool t_dir, bool t_endless, uint8_t t_amount){ scrollLayer(t_dir, t_endless, 0, BMC_MAX_LAYERS-1, t_amount); @@ -78,6 +109,16 @@ void BMC::scrollLayer(uint8_t t_flags, uint8_t t_min, uint8_t t_max, uint8_t t_a scrollLayer((bitRead(t_flags,0)),bitRead(t_flags,1),t_min,t_max,t_amount); } void BMC::scrollLayer(bool t_dir, bool t_endless, uint8_t t_min, uint8_t t_max, uint8_t t_amount){ + // if(!globals.onBoardEditorActive()){ + // if(settings.getDisplayListMode() && !globals.displayListsActive()){ + // globals.setRenderDisplayList(BMC_DEVICE_ID_LAYER); + // return; + // } + // } + if(globals.setRenderDisplayList(BMC_DEVICE_ID_LAYER)){ + return; + } BMCScroller scroller(0, BMC_MAX_LAYERS-1); setLayer(scroller.scroll(t_amount, t_dir, t_endless, layer, t_min, t_max)); } + diff --git a/src/display/BMC-Display-ILI9341Block.h b/src/display/BMC-Display-ILI9341Block.h index 4fa00b7..ff5546b 100644 --- a/src/display/BMC-Display-ILI9341Block.h +++ b/src/display/BMC-Display-ILI9341Block.h @@ -70,6 +70,8 @@ class BMC_ILI9341_BLOCK { } void reassign(BMC_TFT& tft, uint16_t t_settings, bool highlight=false){ selChar = -1; + meterPixelValue = 0xFFFF; + meterValue = 0xFFFF; clear(tft, t_settings, highlight); } void clear(BMC_TFT& tft, uint16_t t_settings, bool highlight=false){ @@ -85,14 +87,14 @@ class BMC_ILI9341_BLOCK { tft.drawRect(xBound, yBound, wBound, hBound, highlight ? background : color); } } - void drawHorizontalMeter(BMC_TFT& tft, uint8_t t_value, uint16_t t_w, uint16_t t_min, uint16_t t_max, uint16_t t_x, uint16_t t_y){ - uint16_t width = t_w - 4; - uint16_t height = 8; - uint16_t fill = map(t_value, t_min, t_max, 0, width-4); - tft.drawRect(t_x, t_y, width, height, color); - tft.drawRect(t_x+1, t_y+1, width-2, height-2, background); - tft.drawRect(t_x+2, t_y+2, fill, height-4, color); - } + // void drawHorizontalMeter(BMC_TFT& tft, uint8_t t_value, uint16_t t_w, uint16_t t_min, uint16_t t_max, uint16_t t_x, uint16_t t_y){ + // uint16_t width = t_w - 4; + // uint16_t height = 8; + // uint16_t fill = map(t_value, t_min, t_max, 0, width-4); + // tft.drawRect(t_x, t_y, width, height, color); + // tft.drawRect(t_x+1, t_y+1, width-2, height-2, background); + // tft.drawRect(t_x+2, t_y+2, fill, height-4, color); + // } void print(BMC_TFT& tft, uint8_t t_crc, const char* str, const char* label="", bool highlight=false){ // add one extra character for the EOL uint8_t len = strlen(str)+1; @@ -235,37 +237,343 @@ class BMC_ILI9341_BLOCK { #endif return fontHeight | ((fontPadding*2)<<8); } - void printPC(BMC_TFT& tft, uint8_t t_crc, uint8_t t_ch, uint8_t t_d1, uint8_t t_settings, bool highlight=false){ - printMIDI(tft, t_crc, BMC_MIDI_PROGRAM_CHANGE, t_ch, t_d1, -1, t_settings, highlight); + uint16_t fitStrInWidth(BMC_TFT& tft, char* buff, uint16_t t_width){ + if(strlen(buff) < 2){ + return BMC_TFT_STR_LEN(tft, buff); + } + uint16_t pixLen = 0; + uint8_t len = strlen(buff)-1; + for(int i = len; i --> 0; ){ + pixLen = BMC_TFT_STR_LEN(tft, buff); + if(pixLen > t_width){ + buff[i] = 0; + } else { + return pixLen; + } + } + return pixLen; + } + + + + + + + + // drawKnobFace & drawKnobPosition + // based on code from this sketch: + // https://github.com/rydepier/Arduino-OLED-Clock/blob/master/Arduino-OLED-Clock%20using%20ADAfruit%20libraries.ino + void drawKnobFace(BMC_TFT& tft, uint16_t t_x, uint16_t t_y, uint16_t t_r){ + tft.fillRect(t_x, t_y, t_r, t_r, background); + tft.drawCircle(t_x, t_y, t_r-12, color); + uint8_t outterR = 5; + for(int z = 0 ; z < 360 ; z += 30){ + if(z == 180){ + continue; + } + float angle = z; + angle = (angle / 57.29577951) ; + int x1 = (t_x + (sin(angle) * (t_r-outterR))); + int y1 = (t_y - (cos(angle) * (t_r-outterR))); + tft.fillCircle(x1, y1, 1, color); + } + } + void drawKnobPositionDot(BMC_TFT& tft, uint16_t t_value, uint16_t t_x, uint16_t t_y, uint16_t t_r, uint16_t t_color){ + uint8_t outterR = 19; + int z = map(t_value, 0, 100, 210, 510); + // Begin at 0° and stop at 360° + float angle = z; + if(z > 360){ + angle = z - 360; + } + angle = (angle / 57.29577951) ; //Convert degrees to radians + int x1 = (t_x + (sin(angle) * (t_r-outterR))); + int y1 = (t_y - (cos(angle) * (t_r-outterR))); + tft.fillCircle(x1, y1, 2, t_color); + } + void drawKnobPositionLine(BMC_TFT& tft, uint16_t t_value, uint16_t t_x, uint16_t t_y, uint16_t t_r, uint16_t t_color){ + uint8_t outterR = 18; + uint8_t innerR = 28; + int z = map(t_value, 0, 100, 210, 510); + //Begin at 0° and stop at 360° + float angle = z; + if(z > 360){ + angle = z - 360; + } + angle = (angle / 57.29577951) ; //Convert degrees to radians + int x1 = (t_x + (sin(angle) * (t_r-outterR))); + int y1 = (t_y - (cos(angle) * (t_r-outterR))); + int x2 = (t_x + (sin(angle) * (t_r-innerR))); + int y2 = (t_y - (cos(angle) * (t_r-innerR))); + + tft.drawLine(x1, y1, x2, y2, t_color); + } + void printKnob(BMC_TFT& tft, BMCDataContainer d){ + bool showLabel = d.showLabel() && wBound > 120; + uint16_t wPos = xBound + (showLabel ? (wBound/4) : (wBound/2)); + uint16_t hPos = yBound + (hBound/2); + uint16_t rPos = ((hBound/2)-2); + uint16_t pixelValue = map(d.value, d.min, d.max, 0, 100); + uint16_t strL = 0; + uint16_t blockW = (wBound/2); + uint16_t txtX = 0; + + + if(showLabel){ + tft.setFont(BMCLiberationSansNarrow_16); + tft.setTextWrap(false); + uint16_t txtY = yBound + (BMC_TFT_STR_LEN(tft, d.label)==0 ? hBound : 40); + char outStr[32] = ""; + // display the last value but in the background color + + BMCTools::formatKnobValue(d, meterValue, outStr); + strL = fitStrInWidth(tft, outStr, blockW); + if(strL > blockW){ + txtX = xBound + blockW+5; + } else { + txtX = xBound + blockW + ((blockW - strL)/2); + } + + tft.setTextColor(background); + tft.setCursor(txtX, txtY); + tft.print(outStr); + + BMCTools::formatKnobValue(d, d.value, outStr); + strL = fitStrInWidth(tft, outStr, blockW); + if(strL > blockW){ + txtX = xBound + blockW+5; + } else { + txtX = xBound + blockW + ((blockW - strL)/2); + } + + tft.setTextColor(color); + tft.setCursor(txtX, txtY); + tft.print(outStr); + } + if(meterPixelValue == 0xFFFF){ + if(showLabel){ + // strL = BMC_TFT_STR_LEN(tft, d.label); + strL = fitStrInWidth(tft, d.label, blockW); + if(strL > blockW){ + txtX = xBound + blockW + 5; + } else { + txtX = xBound + blockW + ((blockW - strL)/2); + } + tft.setCursor(txtX, yBound+17); + tft.print(d.label); + } + drawKnobFace(tft, wPos, hPos, rPos); + drawKnobPositionDot(tft, pixelValue, wPos, hPos, rPos, color); + + } else { + drawKnobPositionDot(tft, meterPixelValue, wPos, hPos, rPos, background); + drawKnobPositionDot(tft, pixelValue, wPos, hPos, rPos, color); + } + meterPixelValue = pixelValue; + meterValue = d.value; + } + + + void drawSwitchRect(BMC_TFT& tft, uint16_t pos){ + uint16_t pos2 = pos*2; + tft.drawRect(xBound+pos, yBound+pos, wBound-pos2, hBound-pos2, color); + } + + void drawSwitch(BMC_TFT& tft, uint16_t pos, bool value){ + // hBound = 32; + uint16_t pos2 = pos*2; + uint16_t centerX = wBound/2; + + tft.setFont(BMCLiberationSansNarrow_16); + tft.setTextWrap(false); + + if(!value){ + tft.fillRect(xBound+centerX, yBound+pos, centerX-pos, hBound-pos2, background); + tft.fillRect(xBound+pos, yBound+pos, centerX-pos, hBound-pos2, color); + uint16_t txtX = xBound+(pos + ((wBound-pos2)*0.75)) - (18); + tft.setTextColor(color); + tft.setCursor(txtX, yBound+(hBound/2)-8); + tft.print("OFF"); + } else { + tft.fillRect(xBound+pos, yBound+pos, centerX-pos, hBound-pos2, background); + tft.fillRect(xBound+centerX, yBound+pos, centerX-pos, hBound-pos2, color); + + uint16_t txtX = xBound+(pos + ((wBound-pos2)*0.25)) - (12); + tft.setTextColor(color); + tft.setCursor(txtX, yBound+(hBound/2)-8); + tft.print("ON"); + } + } + void printSwitch(BMC_TFT& tft, BMCDataContainer d){ + // 2 pixel wide box + // drawSwitchRect(4); + // drawSwitchRect(5); + // switch border with 5px padding + + uint16_t pixelValue = d.value == d.max ? 1 : 0; + uint8_t startPoint = 10; + + if(meterPixelValue == 0xFFFF){ + drawSwitchRect(tft, startPoint); + drawSwitchRect(tft, startPoint+1); + } + if(pixelValue != meterPixelValue){ + drawSwitch(tft, startPoint+2, pixelValue); + } + meterPixelValue = pixelValue; + meterValue = d.value; + } + + + + + + + + + + + + + + void printSlider(BMC_TFT& tft, BMCDataContainer d){ + if(crc == d.crc){ + return; + } + // set crc after clear() + crc = d.crc; + + + if(hBound == 80 && wBound >= 80){ + if(d.useOnOffSwitch()){ + printSwitch(tft, d); + } else { + printKnob(tft, d); + } + return; + } + + uint8_t padding = (hBound == 80) ? 4 : 2; + uint16_t h = hBound; + uint16_t x = xBound + padding; + uint16_t frameH = ((hBound == 80) ? (h / 2) : (h / 3)) - padding; + uint16_t frameW = wBound - (padding * 2); + uint16_t frameYC = yBound + ((h-frameH)/2); + uint16_t y = frameYC; + uint16_t fillH = frameH-(padding*4); + uint16_t fillW = frameW-(padding*4); + uint16_t txtY = (h == 80) ? yBound+10 : yBound+5; + uint16_t pixelValue = map(d.value, d.min, d.max, (d.useOffset ? d.offset : 0), fillW); + bool addLabel = d.showLabel() && wBound > 120; + + tft.setFont(BMCLiberationSansNarrow_16); + + uint16_t txtX = 0; + char outStr[32] = ""; + // display the last value but in the background color + sprintf(outStr, "%u", meterValue+(d.useOffset ? d.offset : 0)); + + if(addLabel){ + txtX = ((xBound + wBound) - BMC_TFT_STR_LEN(tft, outStr))-padding; + } else { + txtX = xBound + ((wBound - BMC_TFT_STR_LEN(tft, outStr))/2); + } + tft.setTextColor(background); + tft.setCursor(txtX, txtY); + tft.print(outStr); + + // display the new value but in the foreground color + sprintf(outStr, "%u", d.value+(d.useOffset ? d.offset : 0)); + if(addLabel){ + txtX = ((xBound + wBound) - BMC_TFT_STR_LEN(tft, outStr))-padding; + } else { + txtX = xBound + ((wBound - BMC_TFT_STR_LEN(tft, outStr))/2); + } + tft.setTextColor(color); + tft.setCursor(txtX, txtY); + tft.print(outStr); + y = ((yBound+hBound)-frameH)-2; + + uint16_t fillX = x+(padding*2); + uint16_t fillY = y+(padding*2); + + if(meterPixelValue == 0xFFFF){ + tft.drawRect(x, y, frameW, frameH, color); + tft.fillRect(fillX, fillY, fillW, fillH, background); + tft.fillRect(fillX, fillY, pixelValue, fillH, color); + if(addLabel){ + tft.setTextColor(color); + tft.setCursor(xBound+padding, txtY); + tft.print(d.label); + } + } else if(pixelValue != meterPixelValue){ + if(pixelValue > meterPixelValue){ + tft.fillRect(fillX, fillY, pixelValue, fillH, color); + } else { + tft.fillRect(fillX+pixelValue, fillY, fillW-pixelValue, fillH, background); + } + + // if(pixelValue > meterPixelValue){ + // tft.fillRect(fillX+meterPixelValue, fillY, pixelValue-meterPixelValue, fillH, color); + // } else { + // tft.fillRect(fillX+pixelValue, fillY, meterPixelValue-pixelValue, fillH, background); + // } + } + + meterPixelValue = pixelValue; + meterValue = d.value; + } + + void printPC(BMC_TFT& tft, BMCDataContainer d){ + if(d.useMeter(wBound >= 120)){ + // display dial + printSlider(tft, d); + return; + } + d.byteC = 0xFF; + d.type = BMC_MIDI_PROGRAM_CHANGE; + printMIDI(tft, d); } - void printCC(BMC_TFT& tft, uint8_t t_crc, uint8_t t_ch, uint8_t t_d1, uint8_t t_d2, uint8_t t_settings, bool highlight=false){ - printMIDI(tft, t_crc, BMC_MIDI_CONTROL_CHANGE, t_ch, t_d1, t_d2, t_settings, highlight); + void printCC(BMC_TFT& tft, BMCDataContainer d){ + if(d.useMeter(wBound >= 120)){ + // display dial + printSlider(tft, d); + return; + } + d.type = BMC_MIDI_CONTROL_CHANGE; + printMIDI(tft, d); } - void printNote(BMC_TFT& tft, uint8_t t_crc, uint8_t t_ch, uint8_t t_d1, uint8_t t_d2, uint8_t t_settings, bool highlight=false){ - printMIDI(tft, t_crc, BMC_MIDI_NOTE_ON, t_ch, t_d1, t_d2, t_settings, highlight); + void printNote(BMC_TFT& tft, BMCDataContainer d){ + d.type = BMC_MIDI_NOTE_ON; + printMIDI(tft, d); } - void printMIDI(BMC_TFT& tft, uint8_t t_crc, uint8_t t_type, uint8_t t_ch, uint8_t t_d1, int16_t t_d2, uint8_t t_settings, bool highlight=false){ - if(crc == t_crc || wBound < 120){ + void printMIDI(BMC_TFT& tft, BMCDataContainer d){ + if(crc == d.crc || wBound < 120){ return; } - clear(tft, t_settings, highlight); - tft.setTextColor(highlight ? background : color); + clear(tft, d.settings, d.highlight); + tft.setTextColor(d.highlight ? background : color); // set crc after clear() - crc = t_crc; + crc = d.crc; char strChTitle[4] = "CH"; char strD1Title[4] = ""; char strD2Title[4] = ""; char strCH[4] = ""; char strD1[4] = ""; char strD2[4] = ""; + uint8_t t_ch = d.byteA; + uint8_t t_d1 = d.byteB; + uint8_t t_d2 = d.byteC; t_ch = constrain(t_ch, 1, 16); t_d1 = constrain(t_d1, 0, 127); sprintf(strCH, "%02u", t_ch); - sprintf(strD1, "%03u", t_d1); - if(t_d2 != -1){ + if(t_d2 != 0xFF){ + sprintf(strD1, "%03u", t_d1); t_d2 = constrain(t_d2, 0, 127); - sprintf(strD2, "%03u", t_d2); + sprintf(strD2, "%03u", t_d2+(d.useOffset ? (uint8_t)d.offset : 0)); + } else { + sprintf(strD1, "%03u", t_d1+(d.useOffset ? (uint8_t)d.offset : 0)); } // wBound kept at 120 pixels instead of block width uint16_t t_wBound = 120; @@ -273,7 +581,7 @@ class BMC_ILI9341_BLOCK { uint16_t y1 = (hBound == 40) ? 2 : 16; uint16_t y2 = (hBound == 40) ? 22 : 48; - switch(t_type){ + switch(d.type){ case BMC_MIDI_PROGRAM_CHANGE: strcpy(strD1Title, "PC"); bW = (t_wBound/2); @@ -290,7 +598,7 @@ class BMC_ILI9341_BLOCK { } tft.setFont(BMCLiberationSansNarrow_16); printMidiLabelAndValue(tft, strChTitle, strCH, y1, y2, bW, 0); - if(t_d2 < 0){ + if(t_d2 == 0xFF){ printMidiLabelAndValue(tft, strD1Title, strD1, y1, y2, bW, bW); } else { printMidiLabelAndValue(tft, strD1Title, strD1, y1, y2, bW, bW); @@ -340,6 +648,8 @@ class BMC_ILI9341_BLOCK { uint8_t settings = 0; uint8_t crc = 0; int8_t selChar = -1; + uint16_t meterPixelValue = 0xFFFF; + uint16_t meterValue = 0xFFFF; }; #endif diff --git a/src/display/BMC-Display-OLED.h b/src/display/BMC-Display-OLED.h index 1ae1afe..8c53320 100644 --- a/src/display/BMC-Display-OLED.h +++ b/src/display/BMC-Display-OLED.h @@ -29,15 +29,19 @@ class BMC_OLED { public: - uint8_t w = 0; - uint8_t h = 0; - uint8_t maxLines = 3; + // uint8_t w = 0; + // uint8_t h = 0; + uint8_t wBound = 0; + uint8_t hBound = 0; int8_t selChar = -1; + uint16_t meterPixelValue = 0xFFFF; + uint16_t meterValue = 0xFFFF; BMC_SSD1306 display; BMC_OLED(uint8_t _w=128, uint8_t _h=BMC_OLED_HEIGHT):display(_w, _h){ - w = _w; - h = _h; - maxLines = (h == 64) ? 3 : 2; + // w = _w; + // h = _h; + wBound = _w; + hBound = _h; } bool begin(uint8_t switchvcc=BMC_SSD1306_SWITCHCAPVCC, uint8_t i2caddr=0, uint8_t rotation=0, uint8_t n=0){ if(!display.begin(switchvcc, i2caddr)){ @@ -49,11 +53,11 @@ class BMC_OLED { display.setTextColor(BMC_OLED_WHITE); display.setTextSize(4); - display.setCursor((n < 10) ? 54 : 42, (h == 32) ? 34 : 50); + display.setCursor((n < 10) ? 54 : 42, (hBound == 32) ? 34 : 50); display.print(n); //drawIcon(1); - display.drawRect(0, 0, w, h, BMC_OLED_WHITE); + display.drawRect(0, 0, wBound, hBound, BMC_OLED_WHITE); display.display(); display.setTextSize(2); @@ -70,6 +74,8 @@ class BMC_OLED { } void reassign(uint8_t t_settings){ selChar = -1; + meterPixelValue = 0xFFFF; + meterValue = 0xFFFF; clear(t_settings); } void clear(uint8_t t_settings){ @@ -80,22 +86,27 @@ class BMC_OLED { // bit 3 use name instead of number display.clearDisplay(); if(bitRead(t_settings, 1)){ - display.drawRect(0, 0, w, h, BMC_OLED_WHITE); + display.drawRect(0, 0, wBound, hBound, BMC_OLED_WHITE); } display.display(); } - void printPC(uint8_t t_ch, uint8_t t_d1, uint8_t t_settings, bool highlight=false){ - printMIDI(BMC_MIDI_PROGRAM_CHANGE, t_ch, t_d1, -1, t_settings, highlight); + // BMCDataContainer d + void printPC(BMCDataContainer d){ + d.type = BMC_MIDI_PROGRAM_CHANGE; + d.byteC = 0xFF; + printMIDI(d); } - void printCC(uint8_t t_ch, uint8_t t_d1, uint8_t t_d2, uint8_t t_settings, bool highlight=false){ - printMIDI(BMC_MIDI_CONTROL_CHANGE, t_ch, t_d1, t_d2, t_settings, highlight); + void printCC(BMCDataContainer d){ + d.type = BMC_MIDI_CONTROL_CHANGE; + printMIDI(d); } - void printNote(uint8_t t_ch, uint8_t t_d1, uint8_t t_d2, uint8_t t_settings, bool highlight=false){ - printMIDI(BMC_MIDI_NOTE_ON, t_ch, t_d1, t_d2, t_settings, highlight); + void printNote(BMCDataContainer d){ + d.type = BMC_MIDI_NOTE_ON; + printMIDI(d); } - void printMIDI(uint8_t t_type, uint8_t t_ch, uint8_t t_d1, int16_t t_d2, uint8_t t_settings, bool highlight=false){ - if(highlight){ - display.fillRect(0, 0, w, h, BMC_OLED_WHITE); + void printMIDI(BMCDataContainer d){ + if(d.highlight){ + display.fillRect(0, 0, wBound, hBound, BMC_OLED_WHITE); display.setTextColor(BMC_OLED_BLACK); } else { display.clearDisplay(); @@ -109,21 +120,23 @@ class BMC_OLED { char strD1[4] = ""; char strD2[4] = ""; - t_ch = constrain(t_ch, 1, 16); - t_d1 = constrain(t_d1, 0, 127); - sprintf(strCH, "%02u", t_ch); - sprintf(strD1, "%03u", t_d1); - if(t_d2 != -1){ - t_d2 = constrain(t_d2, 0, 127); - sprintf(strD2, "%03u", t_d2); + d.byteA = constrain(d.byteA, 1, 16); + d.byteB = constrain(d.byteB, 0, 127); + sprintf(strCH, "%02u", d.byteA); + if(d.byteC != 0xFF){ + sprintf(strD1, "%03u", d.byteB); + d.byteC = constrain(d.byteC, 0, 127); + sprintf(strD2, "%03u", d.byteC+(d.useOffset ? (uint8_t)d.offset : 0)); + } else { + sprintf(strD1, "%03u", d.byteB+(d.useOffset ? (uint8_t)d.offset : 0)); } uint16_t t_wBound = 128; uint16_t bW = (t_wBound/3); - uint16_t y1 = (h == 32) ? 16 : 28; - uint16_t y2 = (h == 32) ? 34 : 52; + uint16_t y1 = (hBound == 32) ? 16 : 28; + uint16_t y2 = (hBound == 32) ? 34 : 52; - switch(t_type){ + switch(d.type){ case BMC_MIDI_PROGRAM_CHANGE: strcpy(strD1Title, "PC"); bW = (t_wBound/2); @@ -141,7 +154,7 @@ class BMC_OLED { display.setTextSize(2); printMidiLabelAndValue(strChTitle, strCH, y1, y2, bW, 0); - if(t_d2 < 0){ + if(d.byteC == 0xFF){ printMidiLabelAndValue(strD1Title, strD1, y1, y2, bW, bW); } else { printMidiLabelAndValue(strD1Title, strD1, y1, y2, bW, bW); @@ -149,7 +162,7 @@ class BMC_OLED { } display.display(); } - + void printMidiLabelAndValue(char * t_label, char * t_value, uint8_t y1, uint8_t y2, uint16_t bW, uint16_t bW2){ uint16_t x = bW2 + ((bW - (strlen(t_label)*12)) / 2); display.setCursor(x, y1); @@ -169,7 +182,7 @@ class BMC_OLED { void print(char * str, uint8_t t_settings, bool highlight=false){ if(highlight){ - display.fillRect(0, 0, w, h, BMC_OLED_WHITE); + display.fillRect(0, 0, wBound, hBound, BMC_OLED_WHITE); } else { display.clearDisplay(); } @@ -191,7 +204,7 @@ class BMC_OLED { // start by looking for spaces, use the spaces to split a long line in 2 // figure out how many lines to print - if(h==32 && len <= 10){ + if(hBound==32 && len <= 10){ // on a 128x32 display we keep the maximum font size at 2 // with that we can fit up to 10 characters in one line // if we have a single line and we are using the 128x32 display @@ -211,7 +224,7 @@ class BMC_OLED { } } } - if(h==32){ + if(hBound==32){ if(totalSpaces == 2){ uint8_t t1 = len - (spaceIndex+1); // 9 uint8_t t2 = len - (spaceIndex2+1); // 4 @@ -262,7 +275,7 @@ class BMC_OLED { renderLine(str, 0, 1, 0, len); } if(bitRead(t_settings, 1)){ - display.drawRect(0, 0, w, h, BMC_OLED_WHITE); + display.drawRect(0, 0, wBound, hBound, BMC_OLED_WHITE); } display.display(); } @@ -275,20 +288,20 @@ class BMC_OLED { } void printLeftBox(char * str){ uint8_t len = strlen(str); - uint8_t textSize = (h == 64) ? 2 : 1; + uint8_t textSize = (hBound == 64) ? 2 : 1; uint8_t charH = 8 * textSize; - uint8_t x = h==64 ? 5 : 7; - uint8_t y = (((h - (charH*len))/2)+charH)+textSize; + uint8_t x = hBound==64 ? 5 : 7; + uint8_t y = (((hBound - (charH*len))/2)+charH)+textSize; if(len>4 || len<2){ return; } if(len==0){ - display.fillRect(0, 0, 20, h, BMC_OLED_BLACK); + display.fillRect(0, 0, 20, hBound, BMC_OLED_BLACK); display.display(); return; } display.setTextColor(BMC_OLED_BLACK); - display.fillRect(0, 0, 20, h, BMC_OLED_WHITE); + display.fillRect(0, 0, 20, hBound, BMC_OLED_WHITE); display.setTextSize(textSize); for(uint8_t i=0;i 360){ + angle = z - 360; + } + angle = (angle / 57.29577951) ; //Convert degrees to radians + int x1 = (t_x + (sin(angle) * (t_r-outterR))); + int y1 = (t_y - (cos(angle) * (t_r-outterR))); + display.fillCircle(x1, y1, 2, t_color); + } + void drawKnobPositionLine(uint16_t t_value, uint16_t t_x, uint16_t t_y, uint16_t t_r, uint16_t t_color){ + uint8_t outterR = 18; + uint8_t innerR = 28; + int z = map(t_value, 0, 100, 210, 510); + //Begin at 0° and stop at 360° + float angle = z; + if(z > 360){ + angle = z - 360; + } + angle = (angle / 57.29577951) ; //Convert degrees to radians + int x1 = (t_x + (sin(angle) * (t_r-outterR))); + int y1 = (t_y - (cos(angle) * (t_r-outterR))); + int x2 = (t_x + (sin(angle) * (t_r-innerR))); + int y2 = (t_y - (cos(angle) * (t_r-innerR))); + + display.drawLine(x1, y1, x2, y2, t_color); + } + void printKnob(BMCDataContainer d){ + uint16_t wPos = d.showLabel()?(wBound/4):(wBound/2); + uint16_t hPos = hBound/2; + uint16_t rPos = (hBound/2)-2; + uint16_t pixelValue = map(d.value, d.min, d.max, 0, 100); + uint16_t strL = 0; + uint16_t blockW = wBound/2; + uint16_t txtX = 0; + + if(d.showLabel()){ + display.setTextSize(2); + display.setTextWrap(false); + uint16_t txtY = strlen(d.label)==0 ? hBound : 40; + char outStr[32] = ""; + BMCTools::formatKnobValue(d, meterValue, outStr); + + strL = (12*strlen(outStr))-2; + if(strL > blockW){ + txtX = blockW+5; + } else { + txtX = blockW + ((blockW - strL)/2); + } + display.setTextColor(BMC_OLED_BLACK); + display.setCursor(txtX, txtY); + display.print(outStr); + + // display the new value but in the foreground color + BMCTools::formatKnobValue(d, d.value, outStr); + strL = (12*strlen(outStr))-2; + if(strL > blockW){ + txtX = blockW+5; + } else { + txtX = blockW + ((blockW - strL)/2); + } + + display.setTextColor(BMC_OLED_WHITE); + display.setCursor(txtX, txtY); + display.print(outStr); + } + if(meterPixelValue == 0xFFFF){ + if(d.showLabel()){ + uint8_t tPos = 17; + strL = (12*strlen(d.label))-2; + if(strL > blockW){ + txtX = blockW+5; + } else { + txtX = blockW + ((blockW - strL)/2); + } + display.setCursor(txtX, tPos); + display.print(d.label); + } + drawKnobFace(wPos, hPos, rPos, BMC_OLED_WHITE, BMC_OLED_BLACK); + drawKnobPositionDot(pixelValue, wPos, hPos, rPos, BMC_OLED_WHITE); + + } else { + drawKnobPositionDot(meterPixelValue, wPos, hPos, rPos, BMC_OLED_BLACK); + drawKnobPositionDot(pixelValue, wPos, hPos, rPos, BMC_OLED_WHITE); + } + display.display(); + meterPixelValue = pixelValue; + meterValue = d.value; + } + void drawSwitchRect(uint16_t pos){ + uint16_t pos2 = pos*2; + display.drawRect(pos, pos, wBound-pos2, hBound-pos2, BMC_OLED_WHITE); + } + + void drawSwitch(uint16_t pos, bool value){ + // hBound = 32; + uint16_t pos2 = pos*2; + uint16_t centerX = wBound/2; + + display.setTextSize(2); + display.setTextWrap(false); + + if(!value){ + display.fillRect(centerX, pos, centerX-pos, hBound-pos2, BMC_OLED_BLACK); + display.fillRect(pos, pos, centerX-pos, hBound-pos2, BMC_OLED_WHITE); + uint16_t txtX = (pos + ((wBound-pos2)*0.75)) - (18); + display.setTextColor(BMC_OLED_WHITE); + display.setCursor(txtX, (hBound/2)+8); + display.print("OFF"); + } else { + display.fillRect(pos, pos, centerX-pos, hBound-pos2, BMC_OLED_BLACK); + display.fillRect(centerX, pos, centerX-pos, hBound-pos2, BMC_OLED_WHITE); + + uint16_t txtX = (pos + ((wBound-pos2)*0.25)) - (12); + display.setTextColor(BMC_OLED_WHITE); + display.setCursor(txtX, (hBound/2)+8); + display.print("ON"); + } + } + void printSwitch(BMCDataContainer d){ + // 2 pixel wide box + // drawSwitchRect(4); + // drawSwitchRect(5); + // switch border with 5px padding + + uint16_t pixelValue = d.value == d.max ? 1 : 0; + uint8_t startPoint = hBound == 64 ? 10 : 0; + + if(meterPixelValue == 0xFFFF){ + drawSwitchRect(startPoint); + drawSwitchRect(startPoint+1); + } + if(pixelValue != meterPixelValue){ + drawSwitch(startPoint+2, pixelValue); + } + display.display(); + meterPixelValue = pixelValue; + meterValue = d.value; + } + void printSlider(BMCDataContainer d){ + if(d.useOnOffSwitch()){ + printSwitch(d); + return; + } else if(hBound == 64){ + printKnob(d); + return; + } + + // set crc after clear() + uint8_t padding = (hBound == 64) ? 4 : 1; + uint16_t x = padding; + uint16_t frameH = (hBound == 64 ? hBound / 2 : (hBound/2)-4) - padding; + uint16_t frameW = wBound - (padding * 2); + uint16_t frameYC = (hBound-frameH)/2; + uint16_t y = frameYC; + uint16_t fillH = frameH-(padding*4); + uint16_t fillW = frameW-(padding*4); + uint16_t txtY = (hBound == 64) ? 27 : 17; + uint16_t pixelValue = map(d.value, d.min, d.max, (d.useOffset ? d.offset : 0), fillW); + + display.setTextSize(2); + display.setTextWrap(false); + + uint16_t txtX = 0; + char outStr[32] = ""; + // display the last value but in the background color + sprintf(outStr, "%u", meterValue+(d.useOffset ? d.offset : 0)); + + txtX = ((wBound - (12*strlen(outStr)))/2); + + display.setTextColor(BMC_OLED_BLACK); + display.setCursor(txtX, txtY); + display.print(outStr); + + // display the new value but in the foreground color + sprintf(outStr, "%u", d.value+(d.useOffset ? d.offset : 0)); + + txtX = ((wBound - (12*strlen(outStr)))/2); + + display.setTextColor(BMC_OLED_WHITE); + display.setCursor(txtX, txtY); + display.print(outStr); + y = (hBound-frameH)-2; + + uint16_t fillX = x+(padding*2); + uint16_t fillY = y+(padding*2); + + if(meterPixelValue == 0xFFFF){ + display.drawRect(x, y, frameW, frameH, BMC_OLED_WHITE); + display.fillRect(fillX, fillY, fillW, fillH, BMC_OLED_BLACK); + display.fillRect(fillX, fillY, pixelValue, fillH, BMC_OLED_WHITE); + } else if(pixelValue != meterPixelValue){ + if(pixelValue > meterPixelValue){ + display.fillRect(fillX, fillY, pixelValue, fillH, BMC_OLED_WHITE); + } else { + display.fillRect(fillX+pixelValue, fillY, fillW-pixelValue, fillH, BMC_OLED_BLACK); + } + } + display.display(); + + meterPixelValue = pixelValue; + meterValue = d.value; + } + + + + + + + + void drawHorizontalMeter(uint8_t t_value, uint16_t t_w, uint16_t t_min, uint16_t t_max, uint16_t t_x, uint16_t t_y){ uint16_t width = t_w - 4; uint16_t height = 8; @@ -309,9 +554,9 @@ class BMC_OLED { display.drawRect(t_x+2, t_y+2, fill, height-4, BMC_OLED_WHITE); } void printHorizontalMeter(uint8_t value){ - uint8_t y = (h == 64) ? 10 : 0; - uint8_t meterH = (h == 64) ? 16 : 12; - uint8_t textSize = (h == 64) ? 3 : 2; + uint8_t y = (hBound == 64) ? 10 : 0; + uint8_t meterH = (hBound == 64) ? 16 : 12; + uint8_t textSize = (hBound == 64) ? 3 : 2; uint8_t charW = 6 * textSize; uint8_t charH = 8 * textSize; value = constrain(value, 0, 100); @@ -324,11 +569,11 @@ class BMC_OLED { display.setTextSize(textSize); uint8_t x = 0; if(value < 10){ - x = (w - (charW * 2)) / 2; // 2 chars + % + x = (wBound - (charW * 2)) / 2; // 2 chars + % } else if(value < 100){ - x = (w - (charW * 3)) / 2; // 3 chars + % + x = (wBound - (charW * 3)) / 2; // 3 chars + % } else { - x = (w - (charW * 4)) / 2; // 4 chars + % + x = (wBound - (charW * 4)) / 2; // 4 chars + % } char str[5]; sprintf(str, "%u%%", value); @@ -336,22 +581,6 @@ class BMC_OLED { display.print(str); display.display(); } - void printMIDI(bool pc, uint8_t ch, uint8_t value){ - display.fillRect(0, 0, 128, 18, BMC_OLED_WHITE); - display.setTextColor(BMC_OLED_BLACK); - display.setTextSize(2); - char str[11]; - if(pc){ - display.setCursor(5, 18); - sprintf(str, "PC | CH %02u",ch); - } else { - display.setCursor(11, 18); - sprintf(str, "CC %02u/%03u",ch,value); - } - display.print(str); - display.display(); - display.setTextColor(BMC_OLED_WHITE); - } private: const char icon[BMC_OLED_ICON_LENGTH] = { @@ -377,25 +606,25 @@ class BMC_OLED { } void drawIcon(uint8_t n, int8_t n2=-1, bool t_show=false){ - uint8_t textSize = h>>3; + uint8_t textSize = hBound>>3; uint8_t charW = 6 * textSize; - uint8_t xStart = (w - charW) / 2; + uint8_t xStart = (wBound - charW) / 2; display.clearDisplay(); if(n2 == -1){ n = constrain(n, 0, (BMC_OLED_ICON_LENGTH-1)); - display.drawChar(xStart, h, icon[n], BMC_OLED_WHITE, BMC_OLED_BLACK, textSize); + display.drawChar(xStart, hBound, icon[n], BMC_OLED_WHITE, BMC_OLED_BLACK, textSize); } else { n = constrain(n, 0, (BMC_OLED_ICON_LENGTH-1)); n2 = constrain(n2, 0, (BMC_OLED_ICON_LENGTH-1)); - display.drawChar(xStart-(charW/2), h, icon[n], BMC_OLED_WHITE, BMC_OLED_BLACK, textSize); - display.drawChar(xStart+charW, h, icon[n2], BMC_OLED_WHITE, BMC_OLED_BLACK, textSize); + display.drawChar(xStart-(charW/2), hBound, icon[n], BMC_OLED_WHITE, BMC_OLED_BLACK, textSize); + display.drawChar(xStart+charW, hBound, icon[n2], BMC_OLED_WHITE, BMC_OLED_BLACK, textSize); } if(t_show){ display.display(); } } void renderLine(const char * str, uint8_t lineNumber, uint8_t totalLines, uint8_t start, uint8_t end){ - uint8_t height = h / totalLines; + uint8_t height = hBound / totalLines; uint8_t font = 2; uint8_t len = end - start; // trim line @@ -408,12 +637,12 @@ class BMC_OLED { } } len = constrain(len, 0, 10); - if((h==64 && totalLines == 2) || (h==32 && totalLines==1)){ + if((hBound==64 && totalLines == 2) || (hBound==32 && totalLines==1)){ switch(len){ case 1: case 2: case 3: case 4: case 5: font = 4; break; case 6: case 7: font = 3; break; } - } else if(h==64 && totalLines==1){ + } else if(hBound==64 && totalLines==1){ switch(len){ case 1: case 2: font = 8; break; case 3: font = 6; break; @@ -423,12 +652,12 @@ class BMC_OLED { } } - uint8_t x = (w - (((font * 6) * len) - font)) / 2; + uint8_t x = (wBound - (((font * 6) * len) - font)) / 2; uint8_t y = ceil((height - (font * 7)) / 2.0) + (height * lineNumber) + ((8*font)); - if((h==32 && totalLines == 2)){ + if((hBound==32 && totalLines == 2)){ y = (lineNumber == 0) ? 16 : 34; } else if(totalLines==2){ - if(h==32){ + if(hBound==32){ if(lineNumber==0){ y += font; } else { @@ -438,7 +667,6 @@ class BMC_OLED { } } - //display.drawRect(0, 0, w, h,BMC_OLED_WHITE); display.setTextSize(font); display.setCursor(x, y); for(uint8_t i = start, e = 0 ; e < len ; i++, e++){ diff --git a/src/display/BMC-Display.h b/src/display/BMC-Display.h index 2ea5e43..36915a9 100644 --- a/src/display/BMC-Display.h +++ b/src/display/BMC-Display.h @@ -1,6 +1,6 @@ /* See https://www.RoxXxtar.com/bmc for more details - Copyright (c) 2022 RoxXxtar.com + Copyright (c) 2023 RoxXxtar.com Licensed under the MIT license. See LICENSE file in the project root for full license information. */ @@ -17,6 +17,7 @@ #include "display/BMC-DisplayTouchCalibration.h" #endif + // lighter gray 0x39C7 #define BMC_ILI9341_VU_GREY BMC_ILI9341_GRAY_7 #define BMC_ILI9341_FADER_CAP_COLOR BMC_ILI9341_GRAY_24 @@ -24,9 +25,6 @@ // values for the DAW VU Meters and other 8 channel display events // these are use no matter the screen dimensions - - - // For meters #define BMC_ILI9341_VU_METER_S 6 // blank space between meter blocks @@ -71,11 +69,15 @@ class BMCDisplay { public: + BMCDisplay(BMCMidi& t_midi #ifdef BMC_USE_SYNC ,BMCSync& t_sync #endif - ):midi(t_midi) + ):midi(t_midi), + globals(t_midi.globals), + store(t_midi.globals.store), + settings(t_midi.globals.settings) #ifdef BMC_USE_SYNC ,sync(t_sync) #endif @@ -140,22 +142,44 @@ class BMCDisplay { void initILI9341Blocks(){ #if defined(BMC_HAS_TOUCH_SCREEN) bmcStoreTouchSettings cal; - cal.xM = midi.globals.settings.getTouchTftCalibration(0); - cal.xC = midi.globals.settings.getTouchTftCalibration(1); - cal.yM = midi.globals.settings.getTouchTftCalibration(2); - cal.yC = midi.globals.settings.getTouchTftCalibration(3); - uint16_t blockWidth = BMC_TFT_WIDTH/4; - - touchPrev.begin(0, BMC_TFT_HEIGHT-80, blockWidth, 80); - touchToggle.begin(blockWidth, BMC_TFT_HEIGHT-80, blockWidth, 80); - touchSelect.begin(blockWidth*2, BMC_TFT_HEIGHT-80, blockWidth, 80); - touchNext.begin(blockWidth*3, BMC_TFT_HEIGHT-80, blockWidth, 80); + cal.xM = settings.getTouchTftCalibration(0); + cal.xC = settings.getTouchTftCalibration(1); + cal.yM = settings.getTouchTftCalibration(2); + cal.yC = settings.getTouchTftCalibration(3); + + uint16_t blockWidth = BMC_TFT_WIDTH/BMC_OBE_TOOLBAR_BUTTON_COUNT; + // uint16_t blockPadding = 10; + uint16_t blockPadding = (blockWidth-54)/2; + uint16_t blockHeight = 120; + uint16_t blockY = BMC_TFT_HEIGHT-blockHeight; + uint16_t paddedBlockWidth = blockWidth-(blockPadding*2); + uint16_t paddedBlockWidthEdges = blockWidth-blockPadding; + + // begin(int16_t t_x, int16_t t_y, uint16_t w, uint16_t h) + touchHeader.begin(0, 0, BMC_OBE_W, 60); + + touchPrev.begin(0, blockY, paddedBlockWidthEdges, blockHeight); + #if BMC_OBE_TOOLBAR_BUTTON_COUNT == 4 + touchToggle.begin(blockWidth+blockPadding, blockY, paddedBlockWidth, blockHeight); + touchSelect.begin((blockWidth*2)+blockPadding, blockY, paddedBlockWidth, blockHeight); + #else + touchToggle.begin(blockWidth+blockPadding, blockY, paddedBlockWidth, blockHeight); + touchBack.begin((blockWidth*2)+blockPadding, blockY, paddedBlockWidth, blockHeight); + touchSelect.begin((blockWidth*3)+blockPadding, blockY, paddedBlockWidth, blockHeight); + #endif + touchNext.begin((blockWidth*(BMC_OBE_TOOLBAR_BUTTON_COUNT-1))+blockPadding, blockY, paddedBlockWidthEdges, blockHeight); + // used to confirm saving changes touchCancel.begin(BMC_OBE_CANCEL_BTN_X, BMC_OBE_SAVE_BTN_Y, BMC_OBE_SAVE_BTN_W, BMC_OBE_SAVE_BTN_H); touchSave.begin(BMC_OBE_SAVE_BTN_X, BMC_OBE_SAVE_BTN_Y, BMC_OBE_SAVE_BTN_W, BMC_OBE_SAVE_BTN_H); + // enter into the menu touchEnter.begin(0, 0, BMC_TFT_WIDTH, BMC_TFT_HEIGHT); - + + touchHeader.setCalibrationData(cal.xM, cal.xC, cal.yM, cal.yC); touchPrev.setCalibrationData(cal.xM, cal.xC, cal.yM, cal.yC); touchToggle.setCalibrationData(cal.xM, cal.xC, cal.yM, cal.yC); + #if BMC_OBE_TOOLBAR_BUTTON_COUNT == 5 + touchBack.setCalibrationData(cal.xM, cal.xC, cal.yM, cal.yC); + #endif touchSelect.setCalibrationData(cal.xM, cal.xC, cal.yM, cal.yC); touchNext.setCalibrationData(cal.xM, cal.xC, cal.yM, cal.yC); touchCancel.setCalibrationData(cal.xM, cal.xC, cal.yM, cal.yC); @@ -185,13 +209,216 @@ class BMCDisplay { } char line1[33] = ""; char line2[33] = ""; - sprintf(line1, "Layer %u", midi.globals.layer+midi.globals.offset); - bmcName_t n = midi.globals.store.layers[midi.globals.layer].events[0].name; + sprintf(line1, "Layer %u", globals.layer+globals.offset); + bmcName_t n = store.layers[globals.layer].events[0].name; if(n > 0 && n <= BMC_MAX_NAMES_LIBRARY){ - strcpy(line2, midi.globals.store.global.names[n-1].name); + strcpy(line2, store.global.names[n-1].name); } renderTempBanner(line1, line2); } + void renderDisplayLists(){ +#if BMC_MAX_SETLISTS > 0 || BMC_MAX_LAYERS > 1 || BMC_MAX_PRESETS > 0 + if(globals.onBoardEditorActive()){ + return; + } + uint8_t listModeValue = settings.getDisplayListMode(); + if(listModeValue==0){ + globals.exitDisplayListMode(); + return; + } + uint8_t listId = globals.getDisplayListId(); + + // if(!globals.displayListsActive()){ + // entering list mode + // assign the list id + // listId = globals.getDisplayListId(); + // } else if(listId != globals.getDisplayListId()){ + // return; + // } + if(listId == 0){ + globals.exitDisplayListMode(); + return; + } + + uint8_t listCount = BMC_TFT_HEIGHT==240 ? 4 : 6; + uint16_t listCurrentValue = 0; + uint16_t maxListCount = 0; + uint8_t listItemHeight = BMC_TFT_HEIGHT==240 ? 52 : 48; + uint8_t headerHeight = 30; + uint8_t yPadding = BMC_TFT_HEIGHT==240 ? 10 : 8; + char deviceName[16] = ""; + + // BMC_PRINTLN("renderDisplayLists", globals.getDisplayListId()); + + #if BMC_MAX_LAYERS > 0 + if(listId == BMC_DEVICE_ID_LAYER){ + strcpy(deviceName, "LAYERS"); + listCurrentValue = globals.layer; + maxListCount = BMC_MAX_LAYERS; + } + #else + return; + #endif + + #if BMC_MAX_PRESETS > 0 + if(listId == BMC_DEVICE_ID_PRESET){ + strcpy(deviceName, "PRESETS"); + listCurrentValue = globals.presetIndex; + maxListCount = BMC_MAX_PRESETS; + } + + #if BMC_MAX_SETLISTS > 0 + if(listId == BMC_DEVICE_ID_SETLIST){ + strcpy(deviceName, "SETLISTS"); + listCurrentValue = globals.setList; + maxListCount = BMC_MAX_SETLISTS; + } + if(listId == BMC_DEVICE_ID_SETLIST_SONG){ + strcpy(deviceName, "SONGS"); + listCurrentValue = globals.song; + maxListCount = BMC_MAX_SETLISTS_SONGS; + } + #else + return; + #endif + + #else + return; + #endif + + // BMC_PRINTLN("listCurrentValue",listCurrentValue); + + + if(!globals.displayListsActive()){ + + tft.display.setFont(BMCLiberationSansNarrow_24_Bold); + tft.display.fillRect(0, 0, BMC_TFT_WIDTH, headerHeight, BMC_ILI9341_YELLOW); + uint16_t x = (BMC_TFT_WIDTH - BMC_TFT_STR_LEN(tft.display, deviceName))/2; + x = x < 4 ? 4 : x; + tft.display.setCursor(x, 3); + tft.display.setTextColor(BMC_ILI9341_BLACK); + tft.display.print(deviceName); + tft.display.fillRect(0, headerHeight, BMC_TFT_WIDTH, BMC_TFT_HEIGHT-headerHeight, BMC_ILI9341_BLACK); + listPageCurrent = (uint16_t) floor(listCurrentValue / (listCount+0.0)); + } + + tft.display.setTextColor(BMC_ILI9341_WHITE); + tft.display.setFont(BMCLiberationSansNarrow_32); + + // uint8_t pageTotal = (uint8_t) (BMC_MAX_SETLISTS / listCount); + // uint8_t pageTotal = pageTotal + listCount; + uint16_t pageCurrent = (uint16_t) floor(listCurrentValue / (listCount+0.0)); + // BMC_PRINTLN("*********",listCurrentValue, pageCurrent); + if(listPageCurrent != pageCurrent){ + // BMC_PRINTLN("********* CHANGED PAGE"); + listPageCurrent = pageCurrent; + tft.display.fillRect(0, headerHeight, BMC_TFT_WIDTH, BMC_TFT_HEIGHT-headerHeight, BMC_ILI9341_BLACK); + } + + // listCurrentValue + + for(uint16_t i = 0, e = (pageCurrent*listCount) ; i < listCount; i++, e++){ + if(i >= listCount){ + break; + } + /* + if(e == listLastSelection || globals.setList == e){ + // fill a black area for the list item + // but only do it for the last selection and the current selection + // tft.display.fillRect(0, (headerHeight + (i*listItemHeight))+1, BMC_TFT_WIDTH, listItemHeight-2, BMC_ILI9341_BLACK); + } + */ + if(e < maxListCount){ + if(listCurrentValue == e){ + // selected + tft.display.setTextColor(BMC_ILI9341_YELLOW); + listLastSelection = e; + } else { + tft.display.setTextColor(BMC_ILI9341_WHITE); + } + tft.display.setCursor(10, headerHeight + ((i*listItemHeight) + yPadding)); + + + bmcName_t nameIndex = 0; + + #if BMC_MAX_LAYERS > 0 + if(listId == BMC_DEVICE_ID_LAYER){ + nameIndex = store.layers[e].events[0].name; + } + #endif + #if BMC_MAX_PRESETS > 0 + if(listId == BMC_DEVICE_ID_PRESET){ + nameIndex = store.global.presets[e].name; + } + #endif + #if BMC_MAX_SETSLISTS > 0 + if(listId == BMC_DEVICE_ID_SETLIST){ + nameIndex = store.global.setLists[e].name; + } else if(listId == BMC_DEVICE_ID_SETLIST_SONG){ + // get the id of the song + uint8_t currentSetlist = globals.setList; + uint16_t songId = store.global.setLists[currentSetlist].events[e]; + nameIndex = store.global.songList[songId].name; + } + + #endif + + if(nameIndex>0){ + #if BMC_MAX_PRESETS > 0 + if(listId == BMC_DEVICE_ID_PRESET){ + char bankLetter[3] = ""; + BMCTools::getBankLetter(((e >> BMC_PRESET_BANK_MASK) & 0x1F), bankLetter); + tft.display.print(bankLetter); + tft.display.print((e & (BMC_MAX_PRESETS_PER_BANK-1))+globals.offset); + continue; + } else { + tft.display.print("#"); + tft.display.print(e + globals.offset); + tft.display.print(" "); + } + #else + tft.display.print("#"); + tft.display.print(e + globals.offset); + tft.display.print(" "); + #endif + + bmcStoreName nameData = globals.getDeviceName(nameIndex); + tft.display.print(nameData.name); + } else { + // no name just write Set # + + #if BMC_MAX_LAYERS > 0 + if(listId == BMC_DEVICE_ID_LAYER){ + tft.display.print("Layer #"); + } + #endif + #if BMC_MAX_PRESETS > 0 + if(listId == BMC_DEVICE_ID_PRESET){ + char bankLetter[3] = ""; + BMCTools::getBankLetter(((e >> BMC_PRESET_BANK_MASK) & 0x1F), bankLetter); + tft.display.print(bankLetter); + tft.display.print((e & (BMC_MAX_PRESETS_PER_BANK-1))+globals.offset); + continue; + } + #endif + #if BMC_MAX_SETSLISTS > 0 + if(listId == BMC_DEVICE_ID_SETLIST){ + tft.display.print("Set #"); + } else if(listId == BMC_DEVICE_ID_SETLIST_SONG){ + tft.display.print("Song #"); + } + #endif + tft.display.print(e + globals.offset); + } + + } + // add a divider line + tft.display.drawFastHLine(0, headerHeight + ((i+1)*listItemHeight), BMC_TFT_WIDTH, (e < BMC_MAX_SETLISTS) ? BMC_ILI9341_VU_GREY : BMC_ILI9341_BLACK); + } + + globals.enterDisplayListMode(500+(listModeValue*500)); +#endif + } void renderStoreClearedBanner(){ if(!allowBanner()){ return; @@ -202,7 +429,7 @@ class BMCDisplay { } void renderImportBanner(){ #if defined(BMC_USE_ON_BOARD_EDITOR) - if(midi.globals.onBoardEditorActive()){ + if(globals.onBoardEditorActive()){ return; } #endif @@ -215,17 +442,17 @@ class BMCDisplay { return; } #if BMC_MAX_PRESETS > 0 - if(midi.globals.bank>=32 || midi.globals.presetIndex >= BMC_MAX_PRESETS){ + if(globals.bank>=32 || globals.presetIndex >= BMC_MAX_PRESETS){ return; } char line1[33] = ""; char line2[33] = ""; - uint16_t p = midi.globals.preset+midi.globals.offset; - char b = midi.globals.alph[midi.globals.bank]; + uint16_t p = globals.preset+globals.offset; + char b = globals.alph[globals.bank]; sprintf(line1, "Preset %c%u", b, p); - bmcName_t n = midi.globals.store.global.presets[midi.globals.presetIndex].name; + bmcName_t n = store.global.presets[globals.presetIndex].name; if(n > 0 && n <= BMC_MAX_NAMES_LIBRARY){ - strcpy(line2, midi.globals.store.global.names[n-1].name); + strcpy(line2, store.global.names[n-1].name); } renderTempBanner(line1, line2); #endif @@ -235,15 +462,15 @@ class BMCDisplay { return; } #if BMC_MAX_SETLISTS > 0 - if(midi.globals.setList >= BMC_MAX_SETLISTS){ + if(globals.setList >= BMC_MAX_SETLISTS){ return; } char line1[33] = ""; char line2[33] = ""; - sprintf(line1, "Set List %u", midi.globals.setList+midi.globals.offset); - bmcName_t n = midi.globals.store.global.setLists[midi.globals.setList].name; + sprintf(line1, "Set List %u", globals.setList+globals.offset); + bmcName_t n = store.global.setLists[globals.setList].name; if(n > 0 && n <= BMC_MAX_NAMES_LIBRARY){ - strcpy(line2, midi.globals.store.global.names[n-1].name); + strcpy(line2, store.global.names[n-1].name); } renderTempBanner(line1, line2); #endif @@ -253,15 +480,15 @@ class BMCDisplay { return; } #if BMC_MAX_SETLISTS > 0 - if(midi.globals.songInLibrary >= BMC_MAX_SETLISTS_SONGS){ + if(globals.songInLibrary >= BMC_MAX_SETLISTS_SONGS){ return; } char line1[33] = ""; char line2[33] = ""; - sprintf(line1, "Song %u", midi.globals.song+midi.globals.offset); - bmcName_t n = midi.globals.store.global.songLibrary[midi.globals.songInLibrary].name; + sprintf(line1, "Song %u", globals.song+globals.offset); + bmcName_t n = store.global.songLibrary[globals.songInLibrary].name; if(n > 0 && n <= BMC_MAX_NAMES_LIBRARY){ - strcpy(line2, midi.globals.store.global.names[n-1].name); + strcpy(line2, store.global.names[n-1].name); } renderTempBanner(line1, line2); #endif @@ -271,32 +498,30 @@ class BMCDisplay { return; } #if BMC_MAX_SETLISTS > 0 - if(midi.globals.songPart >= BMC_MAX_SETLISTS_SONG_PARTS){ + if(globals.songPart >= BMC_MAX_SETLISTS_SONG_PARTS){ return; } - if(midi.globals.songInLibrary >= BMC_MAX_SETLISTS_SONGS){ + if(globals.songInLibrary >= BMC_MAX_SETLISTS_SONGS){ return; } char line1[33] = ""; char line2[33] = ""; - sprintf(line1, "Part %u", midi.globals.songPart+midi.globals.offset); - uint16_t songPart = midi.globals.store.global.songLibrary[midi.globals.songInLibrary].events[midi.globals.songPart]; + sprintf(line1, "Part %u", globals.songPart+globals.offset); + uint16_t songPart = store.global.songLibrary[globals.songInLibrary].events[globals.songPart]; if(songPart > 0){ - bmcName_t n = midi.globals.store.global.presets[songPart-1].name; + bmcName_t n = store.global.presets[songPart-1].name; if(n > 0 && n <= BMC_MAX_NAMES_LIBRARY){ - strcpy(line2, midi.globals.store.global.names[n-1].name); + strcpy(line2, store.global.names[n-1].name); } } renderTempBanner(line1, line2); #endif } bool allowBanner(){ -#if defined(BMC_USE_ON_BOARD_EDITOR) - if(midi.globals.onBoardEditorActive()){ + if(globals.onBoardEditorActive() || globals.displayListsActive()){ return false; } -#endif - return (midi.globals.settings.getDisplayBannerTimeout()>0); + return (settings.getDisplayBannerTimeout()>0); } void renderTempBanner(const char* line1, const char* line2, bool timeout=true){ char s1[strlen(line1)+1] = ""; @@ -306,7 +531,7 @@ class BMCDisplay { renderTempBanner(s1, s2, timeout); } void renderTempBanner(char* line1, char* line2, bool timeout=true){ - midi.globals.setDisplayRenderDisable(true); + globals.setDisplayRenderDisable(true); tft.display.fillRect(0, BMC_DISPLAY_BANNER_Y, BMC_TFT_WIDTH, 120, BMC_ILI9341_BLACK); tft.display.setFont(BMCLiberationSansNarrow_40_Bold); @@ -331,14 +556,14 @@ class BMCDisplay { tft.display.drawRect(0, BMC_DISPLAY_BANNER_Y, BMC_TFT_WIDTH, 120, 0xfe60); tft.display.drawRect(1, BMC_DISPLAY_BANNER_Y+1, BMC_TFT_WIDTH-2, 118, 0xfe60); if(timeout){ - tempTimer.start(midi.globals.settings.getDisplayBannerTimeout()*500); + tempTimer.start(settings.getDisplayBannerTimeout()*500); } } #endif #if BMC_MAX_OLED > 0 void initOled(){ - + BMC_PRINTLN("BMCDisplay::initOled()"); #if BMC_MAX_OLED > 1 Wire.begin(); #endif @@ -357,13 +582,13 @@ class BMCDisplay { memset(last, 0, sizeof(last[0])*BMC_MAX_OLED); clearOleds(); - uint16_t layer = midi.globals.layer; + uint16_t layer = globals.layer; for(uint8_t i = 0 ; i < BMC_MAX_OLED ; i++){ - if(midi.globals.store.layers[layer].oled[i].events[0] == BMC_NONE){ + if(store.layers[layer].oled[i].events[0] == BMC_NONE){ continue; } #if defined(BMC_USE_DAW_LC) || defined(BMC_USE_FAS) - bmcStoreEvent e = BMCTools::getDeviceEventType(midi.globals.store, midi.globals.store.layers[layer].oled[i].events[0]); + bmcStoreEvent e = BMCTools::getDeviceEventType(globals.store, store.layers[layer].oled[i].events[0]); #endif #if defined(BMC_USE_DAW_LC) @@ -423,12 +648,12 @@ class BMCDisplay { clearIliBlocks(); - uint16_t layer = midi.globals.layer; + uint16_t layer = globals.layer; for(uint8_t i = 0 ; i < BMC_MAX_ILI9341_BLOCKS ; i++){ - if(midi.globals.store.layers[layer].ili[i].events[0] == 0){ + if(store.layers[layer].ili[i].events[0] == 0){ continue; } - bmcStoreEvent e = BMCTools::getDeviceEventType(midi.globals.store, midi.globals.store.layers[layer].ili[i].events[0]); + bmcStoreEvent e = BMCTools::getDeviceEventType(globals.store, store.layers[layer].ili[i].events[0]); #if defined(BMC_USE_DAW_LC) if(e.type == BMC_EVENT_TYPE_DAW_DISPLAY){ uint16_t blockW = block[i].getWidth(); @@ -480,7 +705,7 @@ class BMCDisplay { #endif } void reassign(){ - BMC_PRINTLN("display reassign()"); + // BMC_PRINTLN("display reassign()"); for(uint8_t i=0;i<9;i++){ #if defined(BMC_USE_DAW_LC) chInfo[i].reset(); @@ -500,7 +725,7 @@ class BMCDisplay { if(!allowRendering() || dawMetersBlock==-1){ return; } - BMC_PRINTLN("************ initDawMeters"); + // BMC_PRINTLN("************ initDawMeters"); uint16_t x = block[dawMetersBlock].getX(); uint16_t y = block[dawMetersBlock].getY(); uint16_t w = block[dawMetersBlock].getWidth(); @@ -583,7 +808,7 @@ class BMCDisplay { if(!allowRendering() || dawChannelsBlock == -1){ return; } - BMC_PRINTLN("************ initDawChannels"); + // BMC_PRINTLN("************ initDawChannels"); // make background black uint16_t x = block[dawChannelsBlock].getX(); uint16_t y = block[dawChannelsBlock].getY(); @@ -921,7 +1146,7 @@ class BMCDisplay { #if defined(BMC_USE_FAS) // available to both oled and ili displays void initFasTuner(bool isOled, uint8_t n){ - BMC_PRINTLN("initFasTuner", fasTuner.index); + // BMC_PRINTLN("initFasTuner", fasTuner.index); if(fasTuner.index >= 0){ return; } @@ -1034,7 +1259,7 @@ class BMCDisplay { oled[index].display.setTextSize(2); oled[index].display.setTextColor(BMC_OLED_WHITE); oled[index].display.setCursor(116, y+16); - oled[index].display.print(currentTuner.stringNumber+midi.globals.offset); + oled[index].display.print(currentTuner.stringNumber+globals.offset); show = true; } tunerData = currentTuner; @@ -1118,11 +1343,11 @@ class BMCDisplay { tft.display.setCursor(x+(w-16), y1); tft.display.setTextColor(BMC_ILI9341_BLACK); - tft.display.print(tunerData.stringNumber+midi.globals.offset); + tft.display.print(tunerData.stringNumber+globals.offset); tft.display.setCursor(x+(w-16), y1); tft.display.setTextColor(BMC_ILI9341_WHITE); - tft.display.print(currentTuner.stringNumber+midi.globals.offset); + tft.display.print(currentTuner.stringNumber+globals.offset); } tunerData = currentTuner; } @@ -1139,8 +1364,8 @@ class BMCDisplay { #if BMC_MAX_OLED > 1 selectMux(i); #endif - uint8_t settings = midi.globals.store.layers[midi.globals.layer].oled[i].settings[0]; - oled[i].reassign(settings); + uint8_t t_settings = store.layers[globals.layer].oled[i].settings[0]; + oled[i].reassign(t_settings); } #endif } @@ -1150,8 +1375,8 @@ class BMCDisplay { return; } for(uint8_t i = 0 ; i < BMC_MAX_ILI9341_BLOCKS ; i++){ - uint8_t settings = midi.globals.store.layers[midi.globals.layer].ili[i].settings[0]; - block[i].reassign(tft.display, settings); + uint8_t t_settings = store.layers[globals.layer].ili[i].settings[0]; + block[i].reassign(tft.display, t_settings); } #endif } @@ -1161,15 +1386,43 @@ class BMCDisplay { touchCommand = 0; if(touchTimer.complete()){ touchPoint = touchScreen.getPoint(); - if(!midi.globals.onBoardEditorActive()){ + if(!globals.onBoardEditorActive()){ if(touchEnter.isTouched(touchPoint.x, touchPoint.y)){ touchCommand = BMC_MENU_TOGGLE; } } else { + // bool isHeader = touchPrev.isTouched(touchPoint.x, touchPoint.y); + // bool isPrev = touchPrev.isTouched(touchPoint.x, touchPoint.y); + // bool isToggle = touchPrev.isTouched(touchPoint.x, touchPoint.y); + // bool isSelect = touchPrev.isTouched(touchPoint.x, touchPoint.y); + // bool isNext = touchPrev.isTouched(touchPoint.x, touchPoint.y); + // bool isCancel = touchPrev.isTouched(touchPoint.x, touchPoint.y); + // bool isSave = touchPrev.isTouched(touchPoint.x, touchPoint.y); + + // if(isPrev){ + // touchCommand = BMC_MENU_PREV; + // } else if(isToggle || isHeader){ + // touchCommand = BMC_MENU_TOGGLE; + // } else if(isSelect){ + // touchCommand = BMC_MENU_SELECT; + // } else if(isNext){ + // touchCommand = BMC_MENU_NEXT; + // } else if(isCancel){ + // touchCommand = BMC_MENU_CANCEL; + // } else if(isSave){ + // touchCommand = BMC_MENU_SAVE; + // } + if(touchPrev.isTouched(touchPoint.x, touchPoint.y)){ touchCommand = BMC_MENU_PREV; } else if(touchToggle.isTouched(touchPoint.x, touchPoint.y)){ touchCommand = BMC_MENU_TOGGLE; + } else if(touchHeader.isTouched(touchPoint.x, touchPoint.y)){ + touchCommand = BMC_MENU_BACK; + #if BMC_OBE_TOOLBAR_BUTTON_COUNT == 5 + } else if(touchBack.isTouched(touchPoint.x, touchPoint.y)){ + touchCommand = BMC_MENU_BACK; + #endif } else if(touchSelect.isTouched(touchPoint.x, touchPoint.y)){ touchCommand = BMC_MENU_SELECT; } else if(touchNext.isTouched(touchPoint.x, touchPoint.y)){ @@ -1190,13 +1443,13 @@ class BMCDisplay { #endif #if defined(BMC_USE_ON_BOARD_EDITOR) - if(midi.globals.onBoardEditorActive()){ + if(globals.onBoardEditorActive()){ tempTimer.stop(); return; } #endif if(tempTimer.complete()){ - midi.globals.setDisplayRenderDisable(false); + globals.setDisplayRenderDisable(false); tft.display.fillScreen(BMC_ILI9341_BLACK); reassignIliBlocks(); } @@ -1239,31 +1492,38 @@ class BMCDisplay { } } #endif - -void renderNumber(uint8_t n, bool isOled, uint8_t type, uint16_t value, const char * format, const char* label="", bool highlight=false){ - char str[10] = ""; - if(value<10){ - sprintf(str, "%01u", value); - } else if(value<100){ - sprintf(str, "%02u", value); - } else if(value<1000){ - sprintf(str, "%03u", value); +void renderNumber(BMCDataContainer d){ + if(d.value<10){ + sprintf(d.str, "%01u", d.value); + } else if(d.value<100){ + sprintf(d.str, "%02u", d.value); + } else if(d.value<1000){ + sprintf(d.str, "%03u", d.value); } else { - sprintf(str, "%04u", value); + sprintf(d.str, "%04u", d.value); } - renderText(n, isOled, type, str, label, highlight); -} -void renderChar(uint8_t n, bool isOled, uint8_t type, char str){ - char c[2] = {str, 0}; - //strncpy(c, str, 1); - renderText(n, isOled, type, c); -} -void renderText(uint8_t n, bool isOled, uint8_t type, const char* str, const char* label="", bool highlight=false){ - char c[strlen(str)+1] = ""; - // strncpy(c, str, len-1); - strcpy(c, str); - renderText(n, isOled, type, c, label, highlight); + renderText(d); } +// void renderNumber(uint8_t n, bool isOled, uint8_t type, uint16_t value, const char * format, const char* label="", bool highlight=false){ +// char str[10] = ""; +// if(value<10){ +// sprintf(str, "%01u", value); +// } else if(value<100){ +// sprintf(str, "%02u", value); +// } else if(value<1000){ +// sprintf(str, "%03u", value); +// } else { +// sprintf(str, "%04u", value); +// } +// renderText(n, isOled, type, str, label, highlight); +// } + +// void renderChar(uint8_t n, bool isOled, uint8_t type, char str){ +// char c[2] = {str, 0}; +// //strncpy(c, str, 1); +// renderText(n, isOled, type, c); +// } + void setSelChar(uint8_t n, bool isOled, uint8_t selChar){ #if BMC_MAX_OLED > 0 if(isOled){ @@ -1275,14 +1535,17 @@ void setSelChar(uint8_t n, bool isOled, uint8_t selChar){ } #endif - #if BMC_MAX_ILI9341_BLOCKS > 0 if(!isOled){ block[n].setSelChar(selChar); } #endif } -void renderText(uint8_t n, bool isOled, uint8_t type, char* t_str, const char* label="", bool highlight=false){ + +void renderText(BMCDataContainer d){ + renderText(d.index, d.oled, d.type, d.str, d.label, d.highlight); +} +void renderText(uint8_t n, bool isOled, uint8_t type, const char* t_str, const char* label="", bool highlight=false){ #if BMC_MAX_OLED > 1 if(isOled){ selectMux(n); @@ -1297,14 +1560,13 @@ void renderText(uint8_t n, bool isOled, uint8_t type, char* t_str, const char* l if(isOled){ if(last[n] != crc){ last[n] = crc; - uint8_t settings = midi.globals.store.layers[midi.globals.layer].oled[n].settings[0]; - oled[n].print(str, settings, highlight); + uint8_t t_settings = store.layers[globals.layer].oled[n].settings[0]; + oled[n].print(str, t_settings, highlight); } return; } #endif - #if BMC_MAX_ILI9341_BLOCKS > 0 if(!isOled){ if(allowRendering()){ @@ -1314,52 +1576,97 @@ void renderText(uint8_t n, bool isOled, uint8_t type, char* t_str, const char* l #endif } -void renderProgramChangeValue(uint8_t n, bool isOled, uint8_t type, uint8_t ch, uint8_t pc, bool highlight=false){ +void renderSlider(BMCDataContainer d){ #if BMC_MAX_OLED > 1 - if(isOled){ - selectMux(n); + if(d.oled){ + selectMux(d.index); } #endif + char crcStr[32] = ""; + sprintf(crcStr, "sli%u/%u/%u", d.value, d.min, d.max); + d.crc = checkLast(d.type, crcStr); + #if BMC_MAX_OLED > 0 + if(d.oled){ + if(last[d.index] != d.crc){ + last[d.index] = d.crc; + // oled[d.index].printSlider(d.value, d.min, d.max, d.settings, d.label); + oled[d.index].printSlider(d); + } + return; + } + #endif + + #if BMC_MAX_ILI9341_BLOCKS > 0 + if(!d.oled){ + if(allowRendering()){ + block[d.index].printSlider(tft.display, d); + } + } + #endif +} +void renderProgramChangeValue(BMCDataContainer d){ +#if BMC_MAX_OLED > 1 + if(d.oled){ + selectMux(d.index); + } +#endif + char crcStr[12] = ""; + uint8_t ch = d.byteA; + uint8_t pc = d.byteB; + sprintf(crcStr, "PC%u/%u", ch, pc); + d.crc = (uint8_t) (checkLast(d.type, crcStr)+d.highlight); - char str[12] = ""; - sprintf(str, "PC%u/%u", ch, pc); - uint8_t crc = checkLast(type, str)+highlight; #if BMC_MAX_OLED > 0 - if(isOled){ - if(last[n] != crc){ - last[n] = crc; - uint8_t settings = midi.globals.store.layers[midi.globals.layer].oled[n].settings[0]; - oled[n].printPC(ch, pc, settings, highlight); + if(d.oled){ + if(last[d.index] != d.crc){ + last[d.index] = d.crc; + if(d.useMeter()){ + // display dial + d.value = d.byteB; + oled[d.index].printSlider(d); + } else { + // oled[d.index].printPC(ch, pc, d.settings, d.highlight); + oled[d.index].printPC(d); + } + } return; } #endif #if BMC_MAX_ILI9341_BLOCKS > 0 - if(!isOled){ + if(!d.oled){ if(allowRendering()){ - uint8_t settings = midi.globals.store.layers[midi.globals.layer].ili[n].settings[0]; - block[n].printPC(tft.display, crc, ch, pc, settings, highlight); + d.value = d.byteB; + block[d.index].printPC(tft.display, d); } } #endif } -void renderControlChangeValue(uint8_t n, bool isOled, uint8_t type, uint8_t ch, uint8_t cc, uint8_t vv, bool highlight=false){ +void renderControlChangeValue(BMCDataContainer d){ #if BMC_MAX_OLED > 1 - if(isOled){ - selectMux(n); + if(d.oled){ + selectMux(d.index); } #endif - char str[16] = ""; - sprintf(str, "CC%u/%u/%u", ch, cc, vv); - uint8_t crc = checkLast(type, str)+highlight; + char crcStr[16] = ""; + uint8_t ch = d.byteA; + uint8_t cc = d.byteB; + uint8_t vv = d.byteC; + sprintf(crcStr, "CC%u/%u/%u", ch, cc, vv); + d.crc = checkLast(d.type, crcStr)+d.highlight; #if BMC_MAX_OLED > 0 - if(isOled){ - if(last[n] != crc){ - last[n] = crc; - uint8_t settings = midi.globals.store.layers[midi.globals.layer].oled[n].settings[0]; - oled[n].printCC(ch, cc, vv, settings, highlight); + if(d.oled){ + if(last[d.index] != d.crc){ + last[d.index] = d.crc; + if(bitRead(d.settings, 4)){ + d.value = d.byteC; + oled[d.index].printSlider(d); + } else { + // oled[d.index].printCC(ch, cc, vv, d.settings, d.highlight); + oled[d.index].printCC(d); + } } return; } @@ -1367,49 +1674,55 @@ void renderControlChangeValue(uint8_t n, bool isOled, uint8_t type, uint8_t ch, #if BMC_MAX_ILI9341_BLOCKS > 0 - if(!isOled){ + if(!d.oled){ if(allowRendering()){ - uint8_t settings = midi.globals.store.layers[midi.globals.layer].ili[n].settings[0]; - block[n].printCC(tft.display, crc, ch, cc, vv, settings, highlight); + d.value = d.byteC; + block[d.index].printCC(tft.display, d); } } #endif } -void renderNoteValue(uint8_t n, bool isOled, uint8_t type, uint8_t ch, uint8_t nn, uint8_t vv, bool highlight=false){ +void renderNoteValue(BMCDataContainer d){ #if BMC_MAX_OLED > 1 - if(isOled){ - selectMux(n); + if(d.oled){ + selectMux(d.index); } #endif - char str[16] = ""; - sprintf(str, "NN%u/%u/%u", ch, nn, vv); - uint8_t crc = checkLast(type, str)+highlight; -#if BMC_MAX_OLED > 0 - if(isOled){ - if(last[n] != crc){ - last[n] = crc; - uint8_t settings = midi.globals.store.layers[midi.globals.layer].oled[n].settings[0]; - oled[n].printNote(ch, nn, vv, settings, highlight); + + char crcStr[16] = ""; + uint8_t ch = d.byteA; + uint8_t nn = d.byteB; + uint8_t vv = d.byteC; + sprintf(crcStr, "NN%u/%u/%u", ch, nn, vv); + d.crc = checkLast(d.type, crcStr)+d.highlight; + #if BMC_MAX_OLED > 0 + if(d.oled){ + if(last[d.index] != d.crc){ + last[d.index] = d.crc; + // oled[d.index].printNote(ch, nn, vv, d.settings, d.highlight); + oled[d.index].printNote(d); } return; } -#endif -#if BMC_MAX_ILI9341_BLOCKS > 0 - if(!isOled){ + #endif + + + #if BMC_MAX_ILI9341_BLOCKS > 0 + if(!d.oled){ if(allowRendering()){ - uint8_t settings = midi.globals.store.layers[midi.globals.layer].ili[n].settings[0]; - block[n].printNote(tft.display, crc, ch, nn, vv, settings, highlight); + block[d.index].printNote(tft.display, d); } } -#endif + #endif } - - public: BMCMidi& midi; + BMCGlobals& globals; + bmcStore& store; + BMCSettings& settings; #if defined(BMC_USE_SYNC) BMCSync& sync; #endif @@ -1428,8 +1741,13 @@ void renderNoteValue(uint8_t n, bool isOled, uint8_t type, uint8_t ch, uint8_t n XPT2046_Touchscreen touchScreen = XPT2046_Touchscreen(BMC_ILI_TOUCH_CS, BMC_ILI_TOUCH_IRQ); TS_Point touchPoint; BMCTimer touchTimer; + + bmcTouchArea touchHeader; bmcTouchArea touchPrev; bmcTouchArea touchToggle; + #if BMC_OBE_TOOLBAR_BUTTON_COUNT == 5 + bmcTouchArea touchBack; + #endif bmcTouchArea touchSelect; bmcTouchArea touchNext; bmcTouchArea touchEnter; @@ -1487,6 +1805,11 @@ void renderNoteValue(uint8_t n, bool isOled, uint8_t type, uint8_t ch, uint8_t n "LEAD", "BANK", }; +#if BMC_MAX_SETLISTS > 0 || BMC_MAX_PRESETS > 0 || BMC_MAX_LAYERS > 1 + // uint8_t listId = 0; + uint16_t listPageCurrent = 0; + uint16_t listLastSelection = 0; +#endif void renderIcon(uint8_t n, bool isOled, uint8_t type, uint8_t value){ #if BMC_MAX_OLED > 0 @@ -1501,7 +1824,7 @@ void renderNoteValue(uint8_t n, bool isOled, uint8_t type, uint8_t ch, uint8_t n #endif } bool allowRendering(){ - return !midi.globals.displayRenderDisabled(); + return !globals.displayRenderDisabled(); } uint8_t checkLast(uint8_t type, char * str){ diff --git a/src/editor/BMC-Editor.h b/src/editor/BMC-Editor.h index 998c161..4e8cade 100644 --- a/src/editor/BMC-Editor.h +++ b/src/editor/BMC-Editor.h @@ -783,8 +783,42 @@ class BMCEditor { break; } } +#if defined(BMC_DEBUG) + void printDevicesInfo(){ + Serial.println(""); + Serial.println("----------------------------"); + Serial.println(" DEVICES DATA "); + Serial.println("----------------------------"); + for(uint8_t i = 0 ; i < totalDevices ; i++){ + if(devicesData[i].id == 0){ + break; + } + Serial.print(devicesData[i].length); + Serial.print(" "); + if(devicesData[i].hardware){ + Serial.print("*"); + } + if(devicesData[i].global && devicesData[i].hardware){ + Serial.print("Global "); + } + if(devicesData[i].length > 1){ + char buff[20] = ""; + strcpy(buff, devicesData[i].label); + BMCTools::makePlural(buff); + Serial.print(buff); + } else { + Serial.print(devicesData[i].label); + } + Serial.println(""); + } + Serial.println("----------------------------"); + Serial.println("* is hardware"); + Serial.println("----------------------------"); + } + #endif + const uint8_t totalDevices = 40; const BMCDeviceData devicesData[40] = { - {BMC_DEVICE_ID_LAYER, "Layer", -1, 1, false, false, 0, BMC_MAX_LAYER_EVENTS}, + {BMC_DEVICE_ID_LAYER, "Layer", -1, BMC_MAX_LAYERS, false, false, 0, BMC_MAX_LAYER_EVENTS}, {BMC_DEVICE_ID_EVENT, "Event", -1, BMC_MAX_EVENTS_LIBRARY, true, false, 0, 0}, {BMC_DEVICE_ID_NAME, "Name", -1, BMC_MAX_NAMES_LIBRARY, true, false, 0, 0}, #if BMC_MAX_BUTTONS > 0 @@ -792,7 +826,7 @@ class BMCEditor { #endif #if BMC_MAX_GLOBAL_BUTTONS > 0 - {BMC_DEVICE_ID_GLOBAL_BUTTON, "Global Button", 1, BMC_MAX_GLOBAL_BUTTONS, true, true, BMC_MAX_BUTTON_EVENTS, BMC_MAX_BUTTON_EVENTS}, + {BMC_DEVICE_ID_GLOBAL_BUTTON, "Button", 1, BMC_MAX_GLOBAL_BUTTONS, true, true, BMC_MAX_BUTTON_EVENTS, BMC_MAX_BUTTON_EVENTS}, #endif #if BMC_MAX_LEDS > 0 @@ -800,7 +834,7 @@ class BMCEditor { #endif #if BMC_MAX_GLOBAL_LEDS > 0 - {BMC_DEVICE_ID_GLOBAL_LED, "Global Led", 2, BMC_MAX_GLOBAL_LEDS, true, true, 1, 1}, + {BMC_DEVICE_ID_GLOBAL_LED, "Led", 2, BMC_MAX_GLOBAL_LEDS, true, true, 1, 1}, #endif #if BMC_MAX_BI_LEDS > 0 @@ -808,7 +842,7 @@ class BMCEditor { #endif #if BMC_MAX_GLOBAL_BI_LEDS > 0 - {BMC_DEVICE_ID_GLOBAL_BI_LED, "Global Bi Led", 2, BMC_MAX_GLOBAL_BI_LEDS, true, true, 2, 2}, + {BMC_DEVICE_ID_GLOBAL_BI_LED, "Bi Led", 2, BMC_MAX_GLOBAL_BI_LEDS, true, true, 2, 2}, #endif #if BMC_MAX_TRI_LEDS > 0 @@ -816,15 +850,15 @@ class BMCEditor { #endif #if BMC_MAX_GLOBAL_TRI_LEDS > 0 - {BMC_DEVICE_ID_GLOBAL_TRI_LED, "Global Tri Led", 2, BMC_MAX_GLOBAL_TRI_LEDS, true, true, 3, 3}, + {BMC_DEVICE_ID_GLOBAL_TRI_LED, "Tri Led", 2, BMC_MAX_GLOBAL_TRI_LEDS, true, true, 3, 3}, #endif #if BMC_MAX_ENCODERS > 0 - {BMC_DEVICE_ID_ENCODER, "Encoder", 3, BMC_MAX_ENCODERS, false, true, 0, 1}, + {BMC_DEVICE_ID_ENCODER, "Encoder", 3, BMC_MAX_ENCODERS, false, true, 1, 1}, #endif #if BMC_MAX_GLOBAL_ENCODERS > 0 - {BMC_DEVICE_ID_GLOBAL_ENCODER, "Global Encoder", 3, BMC_MAX_GLOBAL_ENCODERS, true, true, 0, 1}, + {BMC_DEVICE_ID_GLOBAL_ENCODER, "Encoder", 3, BMC_MAX_GLOBAL_ENCODERS, true, true, 1, 1}, #endif #if BMC_MAX_POTS > 0 @@ -832,11 +866,11 @@ class BMCEditor { #endif #if BMC_MAX_GLOBAL_POTS > 0 - {BMC_DEVICE_ID_GLOBAL_POT, "Global Pot", 4, BMC_MAX_GLOBAL_POTS, true, true, 1, 3}, + {BMC_DEVICE_ID_GLOBAL_POT, "Pot", 4, BMC_MAX_GLOBAL_POTS, true, true, 1, 3}, #endif #if BMC_TOTAL_POTS_AUX_JACKS > 0 - {BMC_DEVICE_ID_POT_CALIBRATION, "Analog Calibration", -1, BMC_TOTAL_POTS_AUX_JACKS, true, true, 0, 2}, + {BMC_DEVICE_ID_POT_CALIBRATION, "Calibration", -1, BMC_TOTAL_POTS_AUX_JACKS, true, true, 0, 2}, #endif #if BMC_MAX_PIXELS > 0 @@ -844,7 +878,7 @@ class BMCEditor { #endif #if BMC_MAX_GLOBAL_PIXELS > 0 - {BMC_DEVICE_ID_GLOBAL_PIXEL, "Global Pixel", 2, BMC_MAX_GLOBAL_PIXELS, true, true, 1, 1}, + {BMC_DEVICE_ID_GLOBAL_PIXEL, "Pixel", 2, BMC_MAX_GLOBAL_PIXELS, true, true, 1, 1}, #endif #if BMC_MAX_RGB_PIXELS > 0 @@ -852,7 +886,7 @@ class BMCEditor { #endif #if BMC_MAX_GLOBAL_RGB_PIXELS > 0 - {BMC_DEVICE_ID_GLOBAL_RGB_PIXEL, "Global RGB Pixel", 2, BMC_MAX_GLOBAL_RGB_PIXELS, true, true, 0, 3}, + {BMC_DEVICE_ID_GLOBAL_RGB_PIXEL, "RGB Pixel", 2, BMC_MAX_GLOBAL_RGB_PIXELS, true, true, 0, 3}, #endif #if BMC_MAX_PIXEL_STRIP > 0 @@ -860,11 +894,11 @@ class BMCEditor { #endif #if BMC_MAX_NL_RELAYS > 0 - {BMC_DEVICE_ID_NL_RELAY, "Non-Latching Relay", 6, BMC_MAX_NL_RELAYS, true, true, 1, 1}, + {BMC_DEVICE_ID_NL_RELAY, "NoLatch Relay", 6, BMC_MAX_NL_RELAYS, true, true, 1, 1}, #endif #if BMC_MAX_L_RELAYS > 0 - {BMC_DEVICE_ID_L_RELAY, "Latching Relay", 6, BMC_MAX_L_RELAYS, true, true, 1, 1}, + {BMC_DEVICE_ID_L_RELAY, "Latch Relay", 6, BMC_MAX_L_RELAYS, true, true, 1, 1}, #endif #if BMC_MAX_AUX_JACKS > 0 @@ -888,7 +922,7 @@ class BMCEditor { #endif #if BMC_MAX_GLOBAL_MAGIC_ENCODERS > 0 - {BMC_DEVICE_ID_GLOBAL_MAGIC_ENCODER, "Gbl Magic Encoder", 5, BMC_MAX_GLOBAL_MAGIC_ENCODERS, true, true, 3, 3}, + {BMC_DEVICE_ID_GLOBAL_MAGIC_ENCODER, "Magic Encoder", 5, BMC_MAX_GLOBAL_MAGIC_ENCODERS, true, true, 3, 3}, #endif #if BMC_MAX_PRESETS > 0 @@ -908,7 +942,7 @@ class BMCEditor { #endif #if BMC_MAX_TEMPO_TO_TAP > 0 - {BMC_DEVICE_ID_TEMPO_TO_TAP, "Tempo to Tap", -1, BMC_MAX_TEMPO_TO_TAP, true, false, 0, 1}, + {BMC_DEVICE_ID_TEMPO_TO_TAP, "Tempo 2 Tap", -1, BMC_MAX_TEMPO_TO_TAP, true, false, 0, 1}, #endif #if BMC_MAX_CUSTOM_SYSEX > 0 diff --git a/src/editor/onBoard/BMC-OBEDef.h b/src/editor/onBoard/BMC-OBEDef.h index c00d2c1..78dd305 100644 --- a/src/editor/onBoard/BMC-OBEDef.h +++ b/src/editor/onBoard/BMC-OBEDef.h @@ -55,6 +55,8 @@ #define BMC_OBE_HEAD_FONT Arial_20_Bold // y coordinate of text inside each list item #define BMC_OBE_ROW_TEXT_Y 16 + // toolbar button count + #define BMC_OBE_TOOLBAR_BUTTON_COUNT 4 #else #define BMC_OBE_ROW_HEAD_H 60 // y coordinate of header text @@ -63,6 +65,8 @@ #define BMC_OBE_HEAD_FONT Arial_20_Bold // y coordinate of text inside each list item #define BMC_OBE_ROW_TEXT_Y 16 + // toolbar button count + #define BMC_OBE_TOOLBAR_BUTTON_COUNT 5 #endif @@ -169,58 +173,61 @@ #define BMC_OBE_DEVICE_OPT_CUSTOM_EDITOR_MODE 12 // main -#define BMC_OBE_ID_GO_TO 1 +#define BMC_OBE_ID_GO_TO 1 // main > change layer -#define BMC_OBE_ID_CP_GO_TO_LAYER 2 -#define BMC_OBE_ID_CP_GO_TO_BANK 3 -#define BMC_OBE_ID_CP_GO_TO_PRESET 4 -#define BMC_OBE_ID_CP_GO_TO_SETLIST 5 -#define BMC_OBE_ID_CP_GO_TO_SONG 6 -#define BMC_OBE_ID_CP_GO_TO_PART 7 +#define BMC_OBE_ID_CP_GO_TO_LAYER 2 +#define BMC_OBE_ID_CP_GO_TO_BANK 3 +#define BMC_OBE_ID_CP_GO_TO_PRESET 4 +#define BMC_OBE_ID_CP_GO_TO_SETLIST 5 +#define BMC_OBE_ID_CP_GO_TO_SONG 6 +#define BMC_OBE_ID_CP_GO_TO_PART 7 +// edit +#define BMC_OBE_ID_EDIT 8 // main -#define BMC_OBE_ID_SETTINGS 8 +#define BMC_OBE_ID_SETTINGS 9 // main > settings -#define BMC_OBE_ID_SETTINGS_GENERAL 9 +#define BMC_OBE_ID_SETTINGS_GENERAL 10 // main > settings > general -#define BMC_OBE_ID_S_BTN_HOLD_TIME 10 -#define BMC_OBE_ID_S_TYPER_CHANNEL 11 -#define BMC_OBE_ID_S_DISPLAY_OFFSET 12 -#define BMC_OBE_ID_S_DISPLAY_BANNERS 13 -#define BMC_OBE_ID_S_DISPLAY_NAMES 14 -#define BMC_OBE_ID_S_PREPEND_PRESET 15 -#define BMC_OBE_ID_S_PREPEND_BANK 16 -#define BMC_OBE_ID_S_DIM_LEDS 17 -#define BMC_OBE_ID_S_STARTUP_PRESET 18 -#define BMC_OBE_ID_S_TRIG_1ST_SONG 19 -#define BMC_OBE_ID_S_TRIG_1ST_PART 20 -#define BMC_OBE_ID_S_TOUCH_CALIBRATED 21 +#define BMC_OBE_ID_S_BTN_HOLD_TIME 11 +#define BMC_OBE_ID_S_TYPER_CHANNEL 12 +#define BMC_OBE_ID_S_DISPLAY_OFFSET 13 +#define BMC_OBE_ID_S_DISPLAY_BANNERS 14 +#define BMC_OBE_ID_S_DISPLAY_NAMES 15 +#define BMC_OBE_ID_S_PREPEND_PRESET 16 +#define BMC_OBE_ID_S_PREPEND_BANK 17 +#define BMC_OBE_ID_S_DIM_LEDS 18 +#define BMC_OBE_ID_S_STARTUP_PRESET 19 +#define BMC_OBE_ID_S_TRIG_1ST_SONG 20 +#define BMC_OBE_ID_S_TRIG_1ST_PART 21 +#define BMC_OBE_ID_S_DISPLAY_LIST_MODE 22 +#define BMC_OBE_ID_S_TOUCH_CALIBRATED 23 // main > settings -#define BMC_OBE_ID_SETTINGS_MIDI 22 +#define BMC_OBE_ID_SETTINGS_MIDI 24 // main > settings > general -#define BMC_OBE_ID_S_IN_CTRL 23 -#define BMC_OBE_ID_S_IN_CTRL_CH 24 -#define BMC_OBE_ID_S_IN_CTRL_ACTION 25 -#define BMC_OBE_ID_S_CLOCK_IN_PORT 26 -#define BMC_OBE_ID_S_MASTER_CLOCK 27 -#define BMC_OBE_ID_S_ACTIVE_SENSE 28 -#define BMC_OBE_ID_S_BLOCK_RT_IN 29 -#define BMC_OBE_ID_S_BLOCK_RT_OUT 30 +#define BMC_OBE_ID_S_IN_CTRL 25 +#define BMC_OBE_ID_S_IN_CTRL_CH 26 +#define BMC_OBE_ID_S_IN_CTRL_ACTION 27 +#define BMC_OBE_ID_S_CLOCK_IN_PORT 28 +#define BMC_OBE_ID_S_MASTER_CLOCK 29 +#define BMC_OBE_ID_S_ACTIVE_SENSE 30 +#define BMC_OBE_ID_S_BLOCK_RT_IN 31 +#define BMC_OBE_ID_S_BLOCK_RT_OUT 32 // main -#define BMC_OBE_ID_GLOBAL 31 +#define BMC_OBE_ID_GLOBAL 33 // main > global -#define BMC_OBE_ID_GLOBAL_ITEMS 32 +#define BMC_OBE_ID_GLOBAL_ITEMS 34 // main > global > items -#define BMC_OBE_ID_G_ITEM_LIST 33 +#define BMC_OBE_ID_G_ITEM_LIST 35 // main > global > items > editor -#define BMC_OBE_ID_G_ITEM_EDIT 34 +#define BMC_OBE_ID_G_ITEM_EDIT 36 // main -#define BMC_OBE_ID_LAYERS 35 +#define BMC_OBE_ID_LAYERS 37 // main > layers -#define BMC_OBE_ID_LAYERS_ITEMS 36 +#define BMC_OBE_ID_LAYERS_ITEMS 38 // main > layers > items -#define BMC_OBE_ID_P_ITEM_LIST 37 +#define BMC_OBE_ID_P_ITEM_LIST 39 // main > layers > items > editor -#define BMC_OBE_ID_P_ITEM_EDIT 38 +#define BMC_OBE_ID_P_ITEM_EDIT 40 class bmcRenderButton { @@ -267,15 +274,28 @@ class bmcRenderTouchButtons { uint16_t y = (BMC_TFT_HEIGHT-h)-1; char l = type==0 ? BMC_OBE_SEL_CHAR_ARROW_UP : BMC_OBE_SEL_CHAR_ARROW_LEFT; char r = type==0 ? BMC_OBE_SEL_CHAR_ARROW_DOWN : BMC_OBE_SEL_CHAR_ARROW_RIGHT; - uint16_t space = (BMC_TFT_WIDTH-(w*4))/3; + uint16_t space = (BMC_TFT_WIDTH-(w*BMC_OBE_TOOLBAR_BUTTON_COUNT))/(BMC_OBE_TOOLBAR_BUTTON_COUNT-1); + // add a 5th button on larger displays 480x320 tft.fillRect(0, BMC_OBE_H-BMC_OBE_ROW_H, BMC_OBE_W, BMC_OBE_ROW_H, BMC_ILI9341_BLACK); + // arrow up button.render(tft, 0, y, w, h, l, BMC_OBE_BUTTON_COLOR); - // exit - button.render(tft, space+w, y, w, h, 120, BMC_ILI9341_RED); - // enter - button.render(tft, (space*2)+(w*2), y, w, h, BMC_OBE_SEL_CHAR_CARET_RIGHT, BMC_ILI9341_GREEN); + + #if BMC_OBE_TOOLBAR_BUTTON_COUNT == 4 + // exit + button.render(tft, space+w, y, w, h, 120, BMC_ILI9341_RED); + // enter + button.render(tft, (space*2)+(w*2), y, w, h, BMC_OBE_SEL_CHAR_CARET_RIGHT, BMC_ILI9341_GREEN); + #else + // exit + button.render(tft, space+w, y, w, h, 120, BMC_ILI9341_RED); + // back + button.render(tft, (space*2)+(w*2), y, w, h, BMC_OBE_SEL_CHAR_ARROW_LEFT, BMC_ILI9341_BLUE); + // enter + button.render(tft, (space*3)+(w*3), y, w, h, BMC_OBE_SEL_CHAR_CARET_RIGHT, BMC_ILI9341_GREEN); + #endif + // arrow down button.render(tft, BMC_TFT_WIDTH-52, y, 52, h, r, BMC_OBE_BUTTON_COLOR); } @@ -317,20 +337,28 @@ struct BMCOBEMenuItem { uint16_t max = 0; uint8_t steps = 0; }; +struct BMCOBEAssignments { + uint8_t type = 0; + uint16_t index = 0; +}; class BMCOBEData { public: BMCOBEData(){} BMCDeviceData activeDevice; BMCTimer encoderQueue; uint8_t queueAction = 0; - char headerTitle[40] = ""; + // char headerTitle[40] = ""; + // char selectionText[40] = ""; + uint16_t level[BMC_OBE_MAX_LEVELS]; int16_t lastRowPage[BMC_OBE_MAX_LEVELS]; //int16_t lastMaxRowPages[BMC_OBE_MAX_LEVELS]; int8_t lastActiveRow[BMC_OBE_MAX_LEVELS]; + uint8_t breadcrumbs[BMC_OBE_MAX_LEVELS]; uint16_t visibleRowId[BMC_OBE_ROWS_PER_PAGE]; uint8_t visibleRowIdLength = 0; bool eventEditorEditMode = false; + uint16_t rowEditValue = 0; uint8_t deviceType = 0; uint16_t deviceIndex = 0; @@ -348,14 +376,8 @@ class BMCOBEData { bool namesEditorActive = false; bool eventsEditorActive = false; bool triggerHeaderRender = false; - const char onOffLabels[2][4] = { - "Off", - "On" - }; - const char yesNoLabels[2][4] = { - "No", - "Yes" - }; + const char onOffLabels[2][4] = {"Off", "On"}; + const char yesNoLabels[2][4] = {"No", "Yes"}; void begin(){ availablePortsData[availablePorts++] = BMC_MIDI_PORT_USB_BIT; #if defined(BMC_MIDI_SERIAL_A_ENABLED) @@ -457,6 +479,9 @@ class BMCOBEData { } } else { activeRow = visibleRowIdLength; + if(rowPage == maxRowPages-1){ + activeRow = 3; + } if(rowPage > 0){ rowPage--; } else { @@ -506,7 +531,9 @@ class BMCOBEData { // return true when it's not the main menu bool setNextMenuLevel(){ uint16_t currentLevel = level[0]; - if(currentLevel==0){ + breadcrumbs[currentLevel] = getActiveVisibleRow()-1; + // BMC_PRINTLN("getActiveVisibleRow()", getActiveVisibleRow()-1, activeRow, activeRow-1); + if(currentLevel == 0){ level[0]++; level[1] = activeRow-1; lastRowPage[0] = 0; diff --git a/src/editor/onBoard/BMC-OBEMain.h b/src/editor/onBoard/BMC-OBEMain.h index 3d404a6..ee0acf5 100644 --- a/src/editor/onBoard/BMC-OBEMain.h +++ b/src/editor/onBoard/BMC-OBEMain.h @@ -19,6 +19,10 @@ #include "editor/onBoard/BMC-OBEDef.h" #include "editor/onBoard/handlers/BMC-OBEDevices.h" +// #define Globals display.midi.globals +// #define Store Globals.store +// #define Settings Globals.settings + #define BMC_OBE_FLAGS_SHIFT 0 #define BMC_OBE_FLAGS_ROW_EDIT 1 #define BMC_OBE_FLAGS_ROW_EDIT_ACTIVE 2 @@ -30,26 +34,35 @@ // #define BMC_OBE_DISPLAY_ROW_ID +// index of OBE CUSTOM ASSIGNMENT is +// BMC_MENU_SELECT +// BMC_MENU_BACK +// BMC_MENU_PREV +// BMC_MENU_NEXT +// BMC_MENU_SHIFT +// #define BMC_OBE_CUSTOM_ASSIGNMENT {{BMC_DEVICE_ID_BUTTON, 18}, {BMC_DEVICE_ID_BUTTON, 12}, {BMC_DEVICE_ID_ENCODER, 4}, {BMC_DEVICE_ID_ENCODER, 6}, {BMC_DEVICE_ID_BUTTON, 15}} + class BMCOBE { public: BMCOBE(BMCEditor& t_editor, BMCDisplay& t_display): editor(t_editor), display(t_display), + globals(t_display.midi.globals), + store(t_display.midi.globals.store), + settings(t_display.midi.globals.settings), tft(display.tft.display), devicesEditor(editor, display, data){ } void begin(){ - // BMC_PRINTLN("BMC_OBE_ROWS_PER_PAGE", BMC_OBE_ROWS_PER_PAGE); data.begin(); devicesEditor.begin(); - BMC_PRINTLN("*****BMC_OBE_ROWS_PER_PAGE",BMC_OBE_ROWS_PER_PAGE); } void update(){ #if defined(BMC_HAS_TOUCH_SCREEN) menuCommand(display.getTouchCommand()); #endif - if(!display.midi.globals.onBoardEditorActive()){ + if(!globals.onBoardEditorActive()){ return; } devicesEditor.update(); @@ -65,12 +78,72 @@ class BMCOBE { break; } if(data.renderHead()){ - renderHeader(data.headerTitle); + renderHeader(); } } + bool checkDeviceAssignment(uint8_t t_type, uint16_t t_n, uint8_t t_dir, uint8_t t_ticks=1){ +#if defined(BMC_OBE_CUSTOM_ASSIGNMENT) + if(!globals.onBoardEditorActive()){ + return false; + } + for(uint8_t i = 0; i < 5 ; i++){ + // BMC_MENU_SELECT + // BMC_MENU_BACK + // BMC_MENU_PREV + // BMC_MENU_NEXT + // BMC_MENU_SHIFT + if(deviceAssignments[i].type == 0){ + continue; + } + if(deviceAssignments[i].type == t_type && deviceAssignments[i].index == t_n){ + if(t_type == BMC_DEVICE_ID_BUTTON || t_type == BMC_DEVICE_ID_GLOBAL_BUTTON){ + if(t_dir == BMC_BUTTON_PRESS_TYPE_PRESS){ + // allowed + } else if((i==2 || i==3) && (t_dir == BMC_BUTTON_PRESS_TYPE_HOLD || t_dir == BMC_BUTTON_PRESS_TYPE_CONTINUOUS)){ + // allowed + } else { + continue; + } + switch(i){ + case 0: // select + menuCommand(BMC_MENU_SELECT); + return true; + case 1: // back + menuCommand(BMC_MENU_BACK); + return true; + case 2: // prev + menuCommand(BMC_MENU_PREV); + return true; + case 3: // next + menuCommand(BMC_MENU_NEXT); + return true; + case 4: // shift + menuCommand(BMC_MENU_SHIFT); + return true; + default: + break; + } + } else if(t_type == BMC_DEVICE_ID_ENCODER || t_type == BMC_DEVICE_ID_GLOBAL_ENCODER){ + switch(i){ + case 2: // prev + case 3: // next + if(t_dir == BMC_INC){ + data.queueNext(); + } else { + data.queuePrev(); + } + return true; + default: + break; + } + } + } + } +#endif + return false; + } void render(){ - renderHeader("BMC Editor"); - //renderHeader(""); + // renderHeader(); data.totalRows = 0; data.visibleRowIdLength = 0; flags.off(BMC_OBE_FLAGS_ROW_EDIT); @@ -228,6 +301,7 @@ class BMCOBE { } continueToRenderRows: { + renderHeader(); if(data.activeRow > data.visibleRowIdLength){ data.activeRow = data.visibleRowIdLength; } @@ -334,14 +408,9 @@ class BMCOBE { case BMC_OBE_ID_LAYERS_ITEMS: { BMCDeviceData dd = editor.getDeviceData(id+1); - // BMC_PRINTLN("renderRow()", id+1, dd.label); if(dd.id != 0){ + BMCTools::makePlural(dd.label); tft.print(dd.label); - uint8_t strL = strlen(dd.label); - char lastChar = dd.label[strL-1]; - if(lastChar!='s' && lastChar!='x' && lastChar!='p'){ - tft.print("s"); - } renderCaret(y, color, background); tft.setFont(BMC_OBE_ROW_FONT); } @@ -349,8 +418,7 @@ class BMCOBE { break; case BMC_OBE_ID_G_ITEM_LIST: case BMC_OBE_ID_P_ITEM_LIST: - uint8_t offset = display.midi.globals.settings.getDisplayOffset() ? 0 : 1; - strcpy(data.headerTitle, data.activeDevice.label); + uint8_t offset = settings.getDisplayOffset() ? 0 : 1; tft.print("#"); tft.print(id + offset); @@ -420,13 +488,13 @@ class BMCOBE { } void updateRows(){ if(data.isHeaderSelected()){ - renderHeader(data.headerTitle); + renderHeader(); } else { renderRow(data.activeRow-1); } if(!isEditModeActive() && data.updatePreviousRow()){ if(data.activeRowPrev==0){ - renderHeader(data.headerTitle); + renderHeader(); } else { renderRow(data.activeRowPrev-1); } @@ -457,23 +525,45 @@ class BMCOBE { tft.drawChar(BMC_OBE_CARET_CHAR_X , y+17, BMC_OBE_SEL_CHAR_CARET_RIGHT, color, background, 2, 2); #endif } - void renderHeader(const char* title){ - char buff[strlen(title)+1]; - strcpy(buff, title); - renderHeader(buff); - } - void renderHeader(char* title){ + // void renderHeader(const char* title){ + // char buff[strlen(title)+1]; + // strcpy(buff, title); + // renderHeader(buff); + // } + // void renderHeader(char* title){ + void renderHeader(){ data.triggerHeaderRender = false; - if(strlen(title) > 0){ - strcpy(data.headerTitle, title); - } - - char buff[strlen(title)+1]; - strcpy(buff, title); + char buff[40] = ""; + uint16_t level = data.level[0]; if(data.isHeaderSelected()){ - strcpy(buff, (data.level[0] == 0) ? "Exit Menu" : "Back"); - } else if(data.level[0] == 0){ - strcpy(buff, "BMC Editor"); + if(level == 0){ + strcpy(buff, "Exit Menu"); + } else { + strcpy(buff, "< Back"); + } + } else if(level > 0){ + + bool useDefaultHeader = true; + if(isDynamicList() && data.activeDevice.id != 0){ + uint16_t uid = items[data.dynamicListIndex].id; + if(uid != BMC_OBE_ID_GLOBAL_ITEMS && uid != BMC_OBE_ID_LAYERS_ITEMS){ + strcpy(buff, data.activeDevice.label); + BMCTools::makePlural(buff); + useDefaultHeader = false; + } + } + if(isDynamicEdit() && useDefaultHeader){ + sprintf(buff, "%s #%u", data.activeDevice.label, data.deviceIndex); + useDefaultHeader = false; + } + if(useDefaultHeader){ + uint8_t itemLevel = data.breadcrumbs[level-1]; + if(itemLevel < totalMenuItems){ + strcpy(buff, items[itemLevel].label); + } + } + } else { + sprintf(buff, "BMC v%s", BMC_VERSION_STR); } tft.setFont(BMC_OBE_HEAD_FONT); uint16_t x = getCenteredX(buff); @@ -487,15 +577,13 @@ class BMCOBE { tft.setTextColor(color); tft.setCursor(x, BMC_OBE_HEAD_TXT_Y); tft.print(buff); - - - #if defined(BMC_HAS_TOUCH_SCREEN) // render a footer with controls bmcRenderTouchButtons buttons; buttons.renderV(tft); #endif } + // @queue is used for encoders to avoid the values being unstable void menuCommand(uint8_t cmd, bool queue=false){ if(cmd==0){ @@ -506,23 +594,23 @@ class BMCOBE { exitEditor(); return; } - if(display.midi.globals.editorConnected()){ + if(globals.editorConnected()){ display.renderUnavailableBanner("Unavailable","While Editor App in Use"); return; } - display.midi.globals.toggleOnBoardEditor(); - if(display.midi.globals.onBoardEditorActive()){ + globals.toggleOnBoardEditor(); + if(globals.onBoardEditorActive()){ enterEditor(); } else { exitEditor(); } return; } else if(cmd==BMC_MENU_SELECT){ - if(!display.midi.globals.onBoardEditorActive()){ + if(!globals.onBoardEditorActive()){ menuCommand(BMC_MENU_TOGGLE); return; } - } else if(!display.midi.globals.onBoardEditorActive()){ + } else if(!globals.onBoardEditorActive()){ return; } switch(cmd){ @@ -609,7 +697,6 @@ class BMCOBE { case BMC_OBE_ID_GLOBAL_ITEMS: case BMC_OBE_ID_LAYERS_ITEMS: { - strcpy(data.headerTitle, items[data.dynamicListIndex].label); uint16_t id = data.getActiveVisibleListItem(); data.activeDevice = editor.getDeviceData(id); data.deviceType = data.activeDevice.id; @@ -632,7 +719,7 @@ class BMCOBE { return; } if(flags.read(BMC_OBE_FLAGS_DYNAMIC_EDIT_LIST)){ - if(devicesEditor.isCompatible()){ + if(devicesEditor.isCompatible() && data.activeRow > 0){ if(devicesEditor.hasCustomEditor(0)){ setChangesMade(devicesEditor.setOptionValue()); } @@ -641,6 +728,7 @@ class BMCOBE { } data.setPreviousMenuLevel(); flags.off(BMC_OBE_FLAGS_ROW_EDIT_ACTIVE); + render(); } void cursorPrev(){ @@ -676,17 +764,15 @@ class BMCOBE { steps = items[id].steps; } - if((int)(data.rowEditValue-steps) < min){ data.rowEditValue = max; } else { data.rowEditValue -= steps; } - BMC_PRINTLN("PREV", id, min, max, steps, data.rowEditValue); updateRows(); return; } - if(devicesEditor.isCompatible()){ + if(devicesEditor.isCompatible() && data.activeRow > 0){ if(devicesEditor.handleCustomRowScroller(false, shiftActive())){ return; } @@ -781,19 +867,23 @@ class BMCOBE { return flags.toggleIfTrue(BMC_OBE_FLAGS_SHIFT); } bool active(){ - return display.midi.globals.onBoardEditorActive(); + return globals.onBoardEditorActive(); } private: BMCEditor& editor; BMCDisplay& display; + BMCGlobals& globals; + bmcStore& store; + BMCSettings& settings; BMC_TFT& tft; // BMC_ILI9341& tft; // all variables live here BMCOBEData data; BMCOBEDevices devicesEditor; BMCFlags flags; - const uint16_t totalMenuItems = 38; - const BMCOBEMenuItem items[38] = { + const uint8_t totalMenuItems = 40; + const BMCOBEMenuItem items[40] = { + // keep the main page at 3 items. {{0}, BMC_OBE_ID_GO_TO, "Go To", BMC_OBE_MENU_LIST}, {{1,0}, BMC_OBE_ID_CP_GO_TO_LAYER, "Layer", BMC_OBE_EDIT_LIST, 0, BMC_MAX_LAYERS-1, 1}, {{1,0}, BMC_OBE_ID_CP_GO_TO_BANK, "Bank", BMC_OBE_EDIT_LIST, 0, BMC_MAX_PRESETS > 0?(BMC_MAX_PRESET_BANKS-1):0, 1}, @@ -801,38 +891,47 @@ class BMCOBE { {{1,0}, BMC_OBE_ID_CP_GO_TO_SETLIST, "Setlist", BMC_OBE_EDIT_LIST, 0, BMC_MAX_SETLISTS > 0?(BMC_MAX_SETLISTS-1):0, 1}, {{1,0}, BMC_OBE_ID_CP_GO_TO_SONG, "Song", BMC_OBE_EDIT_LIST, 0, BMC_MAX_SETLISTS > 0?(BMC_MAX_SETLISTS_SONGS-1):0, 1}, {{1,0}, BMC_OBE_ID_CP_GO_TO_PART, "Song Part", BMC_OBE_EDIT_LIST, 0, BMC_MAX_SETLISTS > 0?(BMC_MAX_SETLISTS_SONG_PARTS-1):0, 1}, - {{0}, BMC_OBE_ID_SETTINGS, "Settings", BMC_OBE_MENU_LIST}, - {{1,1}, BMC_OBE_ID_SETTINGS_GENERAL, "General", BMC_OBE_MENU_LIST}, - {{2,1,0}, BMC_OBE_ID_S_BTN_HOLD_TIME, "Button Hold Time", BMC_OBE_EDIT_LIST, 0, 15, 1}, - {{2,1,0}, BMC_OBE_ID_S_TYPER_CHANNEL, "Typer Channel", BMC_OBE_EDIT_LIST, 0, 15, 1}, - {{2,1,0}, BMC_OBE_ID_S_DISPLAY_OFFSET, "Display Offset to 0", BMC_OBE_EDIT_LIST, 0, 1, 1}, - {{2,1,0}, BMC_OBE_ID_S_DISPLAY_BANNERS, "Display Banner", BMC_OBE_EDIT_LIST, 0, 3, 1}, - {{2,1,0}, BMC_OBE_ID_S_DISPLAY_NAMES, "Display Names", BMC_OBE_EDIT_LIST, 0, 1, 1}, - {{2,1,0}, BMC_OBE_ID_S_PREPEND_PRESET, "Prepend Preset", BMC_OBE_EDIT_LIST, 0, 1, 1}, - {{2,1,0}, BMC_OBE_ID_S_PREPEND_BANK, "Prepend Bank", BMC_OBE_EDIT_LIST, 0, 1, 1}, - {{2,1,0}, BMC_OBE_ID_S_DIM_LEDS, "Dim Off LEDs", BMC_OBE_EDIT_LIST, 0, 1, 1}, - {{2,1,0}, BMC_OBE_ID_S_STARTUP_PRESET, "Startup Preset", BMC_OBE_EDIT_LIST, 0, BMC_MAX_PRESETS-1, 1}, - {{2,1,0}, BMC_OBE_ID_S_TRIG_1ST_SONG, "Trigger 1st Song", BMC_OBE_EDIT_LIST, 0, 1, 1}, - {{2,1,0}, BMC_OBE_ID_S_TRIG_1ST_PART, "Trigger 1st Song Part", BMC_OBE_EDIT_LIST, 0, 1, 1}, - {{2,1,0}, BMC_OBE_ID_S_TOUCH_CALIBRATED, "Touch Calibrated", BMC_OBE_EDIT_LIST, 0, 1, 1}, - {{1,1}, BMC_OBE_ID_SETTINGS_MIDI, "MIDI", BMC_OBE_MENU_LIST}, - {{2,1,1}, BMC_OBE_ID_S_IN_CTRL, "MIDI In Control", BMC_OBE_EDIT_LIST, 0, 1, 1}, - {{2,1,1}, BMC_OBE_ID_S_IN_CTRL_CH, "MIDI In Ctrl Channel", BMC_OBE_EDIT_LIST, 0, 16, 1}, - {{2,1,1}, BMC_OBE_ID_S_IN_CTRL_ACTION, "MIDI In Ctrl Action", BMC_OBE_EDIT_LIST, 0, 2, 1}, - {{2,1,1}, BMC_OBE_ID_S_CLOCK_IN_PORT, "MIDI Clock Input Port", BMC_OBE_EDIT_LIST, 0, BMC_TOTAL_AVAILABLE_PORTS-1, 1}, - {{2,1,1}, BMC_OBE_ID_S_MASTER_CLOCK, "MIDI Master Clock", BMC_OBE_EDIT_LIST, 0, 1, 1}, - {{2,1,1}, BMC_OBE_ID_S_ACTIVE_SENSE, "MIDI Active Sense", BMC_OBE_EDIT_LIST, 0, 1, 1}, - {{2,1,1}, BMC_OBE_ID_S_BLOCK_RT_IN, "MIDI Block RT In", BMC_OBE_EDIT_LIST, 0, 1, 1}, - {{2,1,1}, BMC_OBE_ID_S_BLOCK_RT_OUT, "MIDI Block RT Out", BMC_OBE_EDIT_LIST, 0, 1, 1}, - {{0}, BMC_OBE_ID_GLOBAL, "Global", BMC_OBE_MENU_LIST}, - {{1,2}, BMC_OBE_ID_GLOBAL_ITEMS, "Global Devices", BMC_OBE_MENU_DYNAMIC_LIST, 0, 40, 1}, - {{2,2}, BMC_OBE_ID_G_ITEM_LIST, "Global List", BMC_OBE_MENU_DYNAMIC_LIST, 0, 0xFFFF, 1}, - {{3,2}, BMC_OBE_ID_G_ITEM_EDIT, "Global Edit", BMC_OBE_MENU_DYNAMIC_EDIT, 0, 0xFFFF, 1}, - {{0}, BMC_OBE_ID_LAYERS, "Layers", BMC_OBE_MENU_LIST}, - {{1,3}, BMC_OBE_ID_LAYERS_ITEMS, "Layers Devices", BMC_OBE_MENU_DYNAMIC_LIST, 0, 40, 1}, - {{2,3}, BMC_OBE_ID_P_ITEM_LIST, "Layers List", BMC_OBE_MENU_DYNAMIC_LIST, 0, 0xFFFF, 1}, - {{3,3}, BMC_OBE_ID_P_ITEM_EDIT, "Layers Edit", BMC_OBE_MENU_DYNAMIC_EDIT, 0, 0xFFFF, 1} + + {{0}, BMC_OBE_ID_EDIT, "Editor", BMC_OBE_MENU_LIST}, + + {{1,1}, BMC_OBE_ID_SETTINGS, "Settings", BMC_OBE_MENU_LIST}, + {{2,1,0}, BMC_OBE_ID_SETTINGS_GENERAL, "General", BMC_OBE_MENU_LIST}, + {{3,1,0,0}, BMC_OBE_ID_S_BTN_HOLD_TIME, "Button Hold Time", BMC_OBE_EDIT_LIST, 0, 15, 1}, + {{3,1,0,0}, BMC_OBE_ID_S_TYPER_CHANNEL, "Typer Channel", BMC_OBE_EDIT_LIST, 0, 15, 1}, + {{3,1,0,0}, BMC_OBE_ID_S_DISPLAY_OFFSET, "Display Offset to 0", BMC_OBE_EDIT_LIST, 0, 1, 1}, + {{3,1,0,0}, BMC_OBE_ID_S_DISPLAY_BANNERS, "Display Banner", BMC_OBE_EDIT_LIST, 0, 3, 1}, + {{3,1,0,0}, BMC_OBE_ID_S_DISPLAY_NAMES, "Display Names", BMC_OBE_EDIT_LIST, 0, 1, 1}, + {{3,1,0,0}, BMC_OBE_ID_S_PREPEND_PRESET, "Prepend Preset", BMC_OBE_EDIT_LIST, 0, 1, 1}, + {{3,1,0,0}, BMC_OBE_ID_S_PREPEND_BANK, "Prepend Bank", BMC_OBE_EDIT_LIST, 0, 1, 1}, + {{3,1,0,0}, BMC_OBE_ID_S_DIM_LEDS, "Dim Off LEDs", BMC_OBE_EDIT_LIST, 0, 1, 1}, + {{3,1,0,0}, BMC_OBE_ID_S_STARTUP_PRESET, "Startup Preset", BMC_OBE_EDIT_LIST, 0, BMC_MAX_PRESETS-1, 1}, + {{3,1,0,0}, BMC_OBE_ID_S_TRIG_1ST_SONG, "Trigger 1st Song", BMC_OBE_EDIT_LIST, 0, 1, 1}, + {{3,1,0,0}, BMC_OBE_ID_S_TRIG_1ST_PART, "Trigger 1st Song Part", BMC_OBE_EDIT_LIST, 0, 1, 1}, + {{3,1,0,0}, BMC_OBE_ID_S_DISPLAY_LIST_MODE, "Display List Mode", BMC_OBE_EDIT_LIST, 0, 7, 1}, + {{3,1,0,0}, BMC_OBE_ID_S_TOUCH_CALIBRATED, "Touch Calibrated", BMC_OBE_EDIT_LIST, 0, 1, 1}, + {{2,1,0}, BMC_OBE_ID_SETTINGS_MIDI, "MIDI", BMC_OBE_MENU_LIST}, + {{3,1,0,1}, BMC_OBE_ID_S_IN_CTRL, "MIDI In Control", BMC_OBE_EDIT_LIST, 0, 1, 1}, + {{3,1,0,1}, BMC_OBE_ID_S_IN_CTRL_CH, "MIDI In Ctrl Channel", BMC_OBE_EDIT_LIST, 0, 16, 1}, + {{3,1,0,1}, BMC_OBE_ID_S_IN_CTRL_ACTION, "MIDI In Ctrl Action", BMC_OBE_EDIT_LIST, 0, 2, 1}, + {{3,1,0,1}, BMC_OBE_ID_S_CLOCK_IN_PORT, "MIDI Clock Input Port", BMC_OBE_EDIT_LIST, 0, BMC_TOTAL_AVAILABLE_PORTS-1, 1}, + {{3,1,0,1}, BMC_OBE_ID_S_MASTER_CLOCK, "MIDI Master Clock", BMC_OBE_EDIT_LIST, 0, 1, 1}, + {{3,1,0,1}, BMC_OBE_ID_S_ACTIVE_SENSE, "MIDI Active Sense", BMC_OBE_EDIT_LIST, 0, 1, 1}, + {{3,1,0,1}, BMC_OBE_ID_S_BLOCK_RT_IN, "MIDI Block RT In", BMC_OBE_EDIT_LIST, 0, 1, 1}, + {{3,1,0,1}, BMC_OBE_ID_S_BLOCK_RT_OUT, "MIDI Block RT Out", BMC_OBE_EDIT_LIST, 0, 1, 1}, + + {{1,1}, BMC_OBE_ID_GLOBAL, "Global", BMC_OBE_MENU_LIST}, + {{2,1,1}, BMC_OBE_ID_GLOBAL_ITEMS, "Global Devices", BMC_OBE_MENU_DYNAMIC_LIST, 0, 40, 1}, + {{3,1,1,0}, BMC_OBE_ID_G_ITEM_LIST, "Global List", BMC_OBE_MENU_DYNAMIC_LIST, 0, 0xFFFF, 1}, + {{4,1,1,0,0}, BMC_OBE_ID_G_ITEM_EDIT, "Global Edit", BMC_OBE_MENU_DYNAMIC_EDIT, 0, 0xFFFF, 1}, + + {{1,1}, BMC_OBE_ID_LAYERS, "Layers", BMC_OBE_MENU_LIST}, + {{2,1,2}, BMC_OBE_ID_LAYERS_ITEMS, "Layers Devices", BMC_OBE_MENU_DYNAMIC_LIST, 0, 40, 1}, + {{3,1,2,0}, BMC_OBE_ID_P_ITEM_LIST, "Layers List", BMC_OBE_MENU_DYNAMIC_LIST, 0, 0xFFFF, 1}, + {{4,1,2,0,0}, BMC_OBE_ID_P_ITEM_EDIT, "Layers Edit", BMC_OBE_MENU_DYNAMIC_EDIT, 0, 0xFFFF, 1} }; +#if defined(BMC_OBE_CUSTOM_ASSIGNMENT) + const BMCOBEAssignments deviceAssignments[5] = BMC_OBE_CUSTOM_ASSIGNMENT; +#endif uint16_t getEditorValue(uint16_t id){ char str[40] = ""; return editorValueHandler(id, str, false, false); @@ -854,34 +953,34 @@ class BMCOBE { } switch(id){ case BMC_OBE_ID_S_BTN_HOLD_TIME: - originalValue = display.midi.globals.settings.getButtonHoldThreshold(); + originalValue = settings.getButtonHoldThreshold(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setButtonHoldThreshold(value); + settings.setButtonHoldThreshold(value); } sprintf(str, "%u ms", (value+2)*250); return value; case BMC_OBE_ID_S_TYPER_CHANNEL: - originalValue = display.midi.globals.settings.getTyperChannel(); + originalValue = settings.getTyperChannel(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setTyperChannel(value); + settings.setTyperChannel(value); } sprintf(str, "%u", value+1); return value; case BMC_OBE_ID_S_DISPLAY_OFFSET: - originalValue = display.midi.globals.settings.getDisplayOffset(); + originalValue = settings.getDisplayOffset(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setDisplayOffset(value); + settings.setDisplayOffset(value); } strcpy(str, data.yesNoLabels[value]); return value; case BMC_OBE_ID_S_DISPLAY_BANNERS: - originalValue = display.midi.globals.settings.getDisplayBannerTimeout(); + originalValue = settings.getDisplayBannerTimeout(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setDisplayBannerTimeout(value); + settings.setDisplayBannerTimeout(value); } if(value == 0){ strcpy(str, "Disabled"); @@ -890,88 +989,100 @@ class BMCOBE { } return value; case BMC_OBE_ID_S_DISPLAY_NAMES: - originalValue = display.midi.globals.settings.getDisplayNames(); + originalValue = settings.getDisplayNames(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setDisplayNames(value); + settings.setDisplayNames(value); } strcpy(str, data.yesNoLabels[value]); return value; case BMC_OBE_ID_S_PREPEND_PRESET: - originalValue = display.midi.globals.settings.getAppendPresetNumberToPresetName(); + originalValue = settings.getAppendPresetNumberToPresetName(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setAppendPresetNumberToPresetName(value); + settings.setAppendPresetNumberToPresetName(value); } strcpy(str, data.yesNoLabels[value]); return value; case BMC_OBE_ID_S_PREPEND_BANK: - originalValue = display.midi.globals.settings.getDisplayBankWithPreset(); + originalValue = settings.getDisplayBankWithPreset(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setDisplayBankWithPreset(value); + settings.setDisplayBankWithPreset(value); } strcpy(str, data.yesNoLabels[value]); return value; case BMC_OBE_ID_S_DIM_LEDS: - originalValue = display.midi.globals.settings.getPwmDimWhenOff(); + originalValue = settings.getPwmDimWhenOff(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setPwmDimWhenOff(value); + settings.setPwmDimWhenOff(value); } strcpy(str, data.yesNoLabels[value]); return value; case BMC_OBE_ID_S_STARTUP_PRESET: - originalValue = display.midi.globals.settings.getStartupPreset(); + originalValue = settings.getStartupPreset(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setStartupPreset(value); + settings.setStartupPreset(value); } if(value==0){ strcpy(str, "None"); } else { - BMCTools::getPresetLabel((value-1), str, display.midi.globals.store.global); + BMCTools::getPresetLabel((value-1), str, store.global); } return value; case BMC_OBE_ID_S_TRIG_1ST_SONG: - originalValue = display.midi.globals.settings.getSetListTriggerFirstSong(); + originalValue = settings.getSetListTriggerFirstSong(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setSetListTriggerFirstSong(value); + settings.setSetListTriggerFirstSong(value); } strcpy(str, data.yesNoLabels[value]); return value; case BMC_OBE_ID_S_TRIG_1ST_PART: - originalValue = display.midi.globals.settings.getSetListTriggerFirstSongPart(); + originalValue = settings.getSetListTriggerFirstSongPart(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setSetListTriggerFirstSongPart(value); + settings.setSetListTriggerFirstSongPart(value); } strcpy(str, data.yesNoLabels[value]); return value; + case BMC_OBE_ID_S_DISPLAY_LIST_MODE: + originalValue = settings.getDisplayListMode(); + value = (!active) ? originalValue : value; + if(setValue && setChangesMade(originalValue, value)){ + settings.setDisplayListMode(value); + } + if(value == 0){ + strcpy(str, "OFF"); + } else { + sprintf(str, "%ums", (500 + (value*500))); + } + return value; case BMC_OBE_ID_S_TOUCH_CALIBRATED: - originalValue = display.midi.globals.settings.getTouchScreenIsCalibrated(); + originalValue = settings.getTouchScreenIsCalibrated(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setTouchScreenIsCalibrated(value); + settings.setTouchScreenIsCalibrated(value); } strcpy(str, data.yesNoLabels[value]); return value; // MIDI MENU case BMC_OBE_ID_S_IN_CTRL: // - originalValue = display.midi.globals.settings.getIncomingListenerEnabled(); + originalValue = settings.getIncomingListenerEnabled(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setIncomingListenerEnabled(value); + settings.setIncomingListenerEnabled(value); } strcpy(str, data.onOffLabels[value]); return value; case BMC_OBE_ID_S_IN_CTRL_CH: - originalValue = display.midi.globals.settings.getListenerChannel(); + originalValue = settings.getListenerChannel(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setListenerChannel(value); + settings.setListenerChannel(value); } if(value==0){ strcpy(str, "Omni"); @@ -980,10 +1091,10 @@ class BMCOBE { } return value; case BMC_OBE_ID_S_IN_CTRL_ACTION: - originalValue = display.midi.globals.settings.getIncomingProgramType(); + originalValue = settings.getIncomingProgramType(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setIncomingProgramType(value); + settings.setIncomingProgramType(value); } switch(value){ case 0: strcpy(str, "None"); break; @@ -992,10 +1103,10 @@ class BMCOBE { } return value; case BMC_OBE_ID_S_CLOCK_IN_PORT: - originalValue = display.midi.globals.settings.getClockInputPortBit(); + originalValue = settings.getClockInputPortBit(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setClockInputPortBit(value); + settings.setClockInputPortBit(value); } switch(data.availablePortsData[value]){ case BMC_MIDI_PORT_USB_BIT: strcpy(str, "USB"); break; @@ -1008,61 +1119,61 @@ class BMCOBE { } return value; case BMC_OBE_ID_S_MASTER_CLOCK: - originalValue = display.midi.globals.settings.getMasterClock(); + originalValue = settings.getMasterClock(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setMasterClock(value); + settings.setMasterClock(value); } strcpy(str, data.onOffLabels[value]); return value; case BMC_OBE_ID_S_ACTIVE_SENSE: - originalValue = display.midi.globals.settings.getActiveSenseAtStartup(); + originalValue = settings.getActiveSenseAtStartup(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setActiveSenseAtStartup(value); + settings.setActiveSenseAtStartup(value); } strcpy(str, data.onOffLabels[value]); return value; case BMC_OBE_ID_S_BLOCK_RT_IN: - originalValue = display.midi.globals.settings.getMidiRealTimeBlockInput(); + originalValue = settings.getMidiRealTimeBlockInput(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setMidiRealTimeBlockInput(value); + settings.setMidiRealTimeBlockInput(value); } strcpy(str, data.yesNoLabels[value]); return value; case BMC_OBE_ID_S_BLOCK_RT_OUT: - originalValue = display.midi.globals.settings.getMidiRealTimeBlockOutput(); + originalValue = settings.getMidiRealTimeBlockOutput(); value = (!active) ? originalValue : value; if(setValue && setChangesMade(originalValue, value)){ - display.midi.globals.settings.setMidiRealTimeBlockOutput(value); + settings.setMidiRealTimeBlockOutput(value); } strcpy(str, data.yesNoLabels[value]); return value; // change layers case BMC_OBE_ID_CP_GO_TO_LAYER: { - originalValue = display.midi.globals.layer; + originalValue = globals.layer; value = (!active) ? originalValue : value; if(setValue && originalValue != value){ - display.midi.globals.layer = value; - display.midi.globals.setReloadLayer(true); + globals.layer = value; + globals.setReloadLayer(true); forceExitEditor(); return value; } char buff[BMC_MAX_NAMES_LENGTH] = ""; editor.getDeviceNameText(BMC_DEVICE_ID_LAYER, value, buff); - sprintf(str, "#%u %s", value+(display.midi.globals.settings.getDisplayOffset()?0:1), buff); + sprintf(str, "#%u %s", value+(settings.getDisplayOffset()?0:1), buff); return value; } case BMC_OBE_ID_CP_GO_TO_BANK: #if BMC_MAX_PRESETS > 0 { - originalValue = display.midi.globals.bank; + originalValue = globals.bank; value = (!active) ? originalValue : value; if(setValue && originalValue != value){ - display.midi.globals.bank = value; - display.midi.globals.setTriggerBank(true); + globals.bank = value; + globals.setTriggerBank(true); return value; } char buff[3] = ""; @@ -1076,17 +1187,17 @@ class BMCOBE { case BMC_OBE_ID_CP_GO_TO_PRESET: #if BMC_MAX_PRESETS > 0 { - originalValue = display.midi.globals.preset; + originalValue = globals.preset; value = (!active) ? originalValue : value; if(setValue && originalValue != value){ - display.midi.globals.preset = value; - display.midi.globals.setTriggerPreset(true); + globals.preset = value; + globals.setTriggerPreset(true); return value; } char buff[BMC_MAX_NAMES_LENGTH] = ""; - uint16_t p = BMCTools::toPresetIndex(display.midi.globals.preset, value); + uint16_t p = BMCTools::toPresetIndex(globals.preset, value); editor.getDeviceNameText(BMC_DEVICE_ID_PRESET, p, buff); - sprintf(str, "#%u %s", value+(display.midi.globals.settings.getDisplayOffset()?0:1), buff); + sprintf(str, "#%u %s", value+(settings.getDisplayOffset()?0:1), buff); return value; } #else @@ -1095,16 +1206,16 @@ class BMCOBE { case BMC_OBE_ID_CP_GO_TO_SETLIST: #if BMC_MAX_SETLISTS > 0 { - originalValue = display.midi.globals.setList; + originalValue = globals.setList; value = (!active) ? originalValue : value; if(setValue && originalValue != value){ - display.midi.globals.setList = value; - display.midi.globals.setTriggerSetList(true); + globals.setList = value; + globals.setTriggerSetList(true); return value; } char buff[BMC_MAX_NAMES_LENGTH] = ""; editor.getDeviceNameText(BMC_DEVICE_ID_SETLIST, value, buff); - sprintf(str, "#%u %s", value+(display.midi.globals.settings.getDisplayOffset()?0:1), buff); + sprintf(str, "#%u %s", value+(settings.getDisplayOffset()?0:1), buff); return value; } #else @@ -1113,21 +1224,21 @@ class BMCOBE { case BMC_OBE_ID_CP_GO_TO_SONG: #if BMC_MAX_SETLISTS > 0 { - originalValue = display.midi.globals.song; + originalValue = globals.song; value = (!active) ? originalValue : value; if(setValue && originalValue != value){ - display.midi.globals.song = value; - display.midi.globals.setTriggerSong(true); + globals.song = value; + globals.setTriggerSong(true); return value; } char buff[BMC_MAX_NAMES_LENGTH] = ""; - uint16_t s = display.midi.globals.store.global.setLists[display.midi.globals.setList].events[value]; + uint16_t s = store.global.setLists[globals.setList].events[value]; if(s > 0){ editor.getDeviceNameText(BMC_DEVICE_ID_SETLIST_SONG_LIBRARY, s, buff); } else { strcpy(buff, "*empty"); } - sprintf(str, "#%u %s", value+(display.midi.globals.settings.getDisplayOffset()?0:1), buff); + sprintf(str, "#%u %s", value+(settings.getDisplayOffset()?0:1), buff); return value; } #else @@ -1136,21 +1247,21 @@ class BMCOBE { case BMC_OBE_ID_CP_GO_TO_PART: #if BMC_MAX_SETLISTS > 0 { - originalValue = display.midi.globals.songPart; + originalValue = globals.songPart; value = (!active) ? originalValue : value; if(setValue && originalValue != value){ - display.midi.globals.songPart = value; - display.midi.globals.setTriggerPart(true); + globals.songPart = value; + globals.setTriggerPart(true); return value; } char buff[BMC_MAX_NAMES_LENGTH] = ""; - uint16_t p = display.midi.globals.store.global.songLibrary[display.midi.globals.songInLibrary].events[value]; + uint16_t p = store.global.songLibrary[globals.songInLibrary].events[value]; if(p > 0){ editor.getDeviceNameText(BMC_DEVICE_ID_PRESET, p, buff); } else { strcpy(buff, "*empty"); } - sprintf(str, "#%u %s", value+(display.midi.globals.settings.getDisplayOffset()?0:1), buff); + sprintf(str, "#%u %s", value+(settings.getDisplayOffset()?0:1), buff); return value; } #else @@ -1201,8 +1312,10 @@ class BMCOBE { data.reset(); } void enterEditor(){ - display.midi.globals.setDisplayRenderDisable(true); - display.midi.globals.setOnBoardEditorActive(true); + BMC_PRINTLN("Enter Editor"); + globals.exitDisplayListMode(); + globals.setDisplayRenderDisable(true); + globals.setOnBoardEditorActive(true); tft.setFont(BMC_OBE_ROW_FONT); tft.fillRect(0, 0, BMC_OBE_W, BMC_OBE_H, BMC_ILI9341_BLACK); render(); @@ -1216,7 +1329,6 @@ class BMCOBE { exitEditor(); } void exitEditor(){ - BMC_PRINTLN("Exit Editor"); if(confirmSave()){ if(!waitingForConfirmation()){ flags.on(BMC_OBE_FLAGS_WAITING_FOR_CONFIRM); @@ -1225,14 +1337,14 @@ class BMCOBE { renderConfirmSave(); return; } - display.midi.globals.setDisplayRenderDisable(false); - display.midi.globals.setOnBoardEditorActive(false); + BMC_PRINTLN("Exit Editor"); + globals.setDisplayRenderDisable(false); + globals.setOnBoardEditorActive(false); reset(); - // tft.setFontAdafruit(); - // tft.setFont(BMCLiberationSansNarrow_16); tft.setFont(BMCLiberationSansNarrow_24); tft.fillRect(0, 0, BMC_OBE_W, BMC_OBE_H, BMC_ILI9341_BLACK); display.reassign(); + } void renderConfirmSave(){ @@ -1262,7 +1374,7 @@ class BMCOBE { } else { editor.reloadPreviouslySavedStore(); } - display.midi.globals.setAssignStoreData(true); + globals.setAssignStoreData(true); flags.off(BMC_OBE_FLAGS_ROW_EDIT_CHANGED); flags.off(BMC_OBE_FLAGS_WAITING_FOR_CONFIRM); exitEditor(); diff --git a/src/editor/onBoard/handlers/BMC-OBEDevices.h b/src/editor/onBoard/handlers/BMC-OBEDevices.h index db021d7..234f662 100644 --- a/src/editor/onBoard/handlers/BMC-OBEDevices.h +++ b/src/editor/onBoard/handlers/BMC-OBEDevices.h @@ -19,6 +19,9 @@ #include "editor/onBoard/BMC-OBEDef.h" #include "editor/onBoard/handlers/BMC-OBEEvents.h" +// #define Globals display.midi.globals +// #define Store Globals.store +// #define Settings Globals.settings class BMCOBEDevices { @@ -26,6 +29,9 @@ class BMCOBEDevices { BMCOBEDevices(BMCEditor& t_editor, BMCDisplay& t_display, BMCOBEData& t_data): editor(t_editor), display(t_display), + globals(t_display.midi.globals), + store(t_display.midi.globals.store), + settings(t_display.midi.globals.settings), tft(display.tft.display), data(t_data), eventsData(editor, display, offset){ @@ -43,7 +49,7 @@ class BMCOBEDevices { shiftActive = false; } bool isCompatible(uint16_t t_id=0xFFFF){ - uint8_t id = (t_id==0xFFFF) ? data.activeDevice.id : t_id; + uint16_t id = (t_id==0xFFFF) ? data.activeDevice.id : t_id; switch(id){ case BMC_NONE: // case BMC_DEVICE_ID_EVENT: @@ -63,19 +69,17 @@ class BMCOBEDevices { void getEventStatusName(char * str, uint8_t id){ strcpy(str, ""); if(id < BMC_MAX_EVENTS_LIBRARY){ - uint8_t status = display.midi.globals.store.global.events[id].type; + uint8_t status = store.global.events[id].type; eventsData.getEventStatusName(str, status); } } void setTotalRows(){ switch(data.activeDevice.id){ case BMC_DEVICE_ID_LAYER: - // data.totalRows = 1; - // break; - // case BMC_DEVICE_ID_LAYER_EVENT: data.totalRows = 1; data.totalRows += data.activeDevice.settings; data.totalRows += data.activeDevice.events; + break; case BMC_DEVICE_ID_EVENT: case BMC_DEVICE_ID_NAME: data.totalRows = data.activeDevice.length-1; @@ -131,13 +135,15 @@ class BMCOBEDevices { break; case BMC_DEVICE_ID_ENCODER: case BMC_DEVICE_ID_GLOBAL_ENCODER: + data.totalRows = 3;// name, event, 1 setting bit + break; case BMC_DEVICE_ID_TEMPO_TO_TAP: // for all devices that only have a name and single event data.totalRows = 2;// one for name and one for event break; case BMC_DEVICE_ID_OLED: case BMC_DEVICE_ID_ILI: - data.totalRows = 6; + data.totalRows = 7; break; case BMC_DEVICE_ID_LFO: data.totalRows = 1; @@ -260,61 +266,61 @@ class BMCOBEDevices { return getOptionLabel(data.activeRow-1, BMC_OBE_DEVICE_OPT_POST_SAVE); } uint16_t getOptionLabel(uint16_t index, uint8_t valueType=BMC_OBE_DEVICE_OPT_LABEL){ - offset = display.midi.globals.settings.getDisplayOffset()?0:1; + // if(index > 512){ + // index = 0; + // } + offset = settings.getDisplayOffset()?0:1; uint16_t dIndex = data.deviceIndex-1; switch(data.activeDevice.id){ case BMC_DEVICE_ID_LAYER: - // return getLayerNameOption(index, valueType); - return getLayerEventOption<0,BMC_MAX_LAYER_EVENTS>(display.midi.globals.store.layers[display.midi.globals.layer].events[dIndex], index, valueType); + return getLayerEventOption<0,BMC_MAX_LAYER_EVENTS>(store.layers[globals.layer].events[dIndex], index, valueType); case BMC_DEVICE_ID_EVENT: - return getEventsEditor(display.midi.globals.store.global.events[dIndex], index, valueType); + return getEventsEditor(store.global.events[dIndex], index, valueType); case BMC_DEVICE_ID_NAME: - return getNamesEditor(display.midi.globals.store.global.names[dIndex], index, valueType); - // case BMC_DEVICE_ID_LAYER_EVENT: - // return getLayerEventOption<0,BMC_MAX_LAYER_EVENTS>(display.midi.globals.store.layers[display.midi.globals.layer].events[dIndex], index, valueType); + return getNamesEditor(store.global.names[dIndex], index, valueType); case BMC_DEVICE_ID_SKETCH_BYTE: #if BMC_MAX_SKETCH_BYTES > 0 - return getSketchByteOption<0, BMC_MAX_SKETCH_BYTES, uint8_t>(display.midi.globals.store.global.sketchBytes[0], dIndex, index, valueType); + return getSketchByteOption<0, BMC_MAX_SKETCH_BYTES, uint8_t>(store.global.sketchBytes[0], dIndex, index, valueType); #endif break; case BMC_DEVICE_ID_BUTTON: #if BMC_MAX_BUTTONS > 0 - return getButtonOption(display.midi.globals.store.layers[display.midi.globals.layer].buttons[dIndex], index, valueType); + return getButtonOption(store.layers[globals.layer].buttons[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_GLOBAL_BUTTON: #if BMC_MAX_GLOBAL_BUTTONS > 0 - return getButtonOption(display.midi.globals.store.global.buttons[dIndex], index, valueType); + return getButtonOption(store.global.buttons[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_LED: #if BMC_MAX_LEDS > 0 - return getLedOption<1, 1>(display.midi.globals.store.layers[display.midi.globals.layer].leds[dIndex], index, valueType); + return getLedOption<1, 1>(store.layers[globals.layer].leds[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_GLOBAL_LED: #if BMC_MAX_GLOBAL_LEDS > 0 - return getLedOption<1, 1>(display.midi.globals.store.global.leds[dIndex], index, valueType); + return getLedOption<1, 1>(store.global.leds[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_BI_LED: #if BMC_MAX_BI_LEDS > 0 - return getBiLedOption<2, 2>(display.midi.globals.store.layers[display.midi.globals.layer].biLeds[dIndex], index, valueType); + return getBiLedOption<2, 2>(store.layers[globals.layer].biLeds[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_GLOBAL_BI_LED: #if BMC_MAX_GLOBAL_BI_LEDS > 0 - return getBiLedOption<2, 2>(display.midi.globals.store.global.biLeds[dIndex], index, valueType); + return getBiLedOption<2, 2>(store.global.biLeds[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_TRI_LED: #if BMC_MAX_TRI_LEDS > 0 - return getTriLedOption<3, 3>(display.midi.globals.store.layers[display.midi.globals.layer].triLeds[dIndex], index, valueType); + return getTriLedOption<3, 3>(store.layers[globals.layer].triLeds[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_GLOBAL_TRI_LED: #if BMC_MAX_GLOBAL_TRI_LEDS > 0 - return getTriLedOption<3, 3>(display.midi.globals.store.global.triLeds[dIndex], index, valueType); + return getTriLedOption<3, 3>(store.global.triLeds[dIndex], index, valueType); #endif break; @@ -323,85 +329,85 @@ class BMCOBEDevices { case BMC_DEVICE_ID_ENCODER: #if BMC_MAX_ENCODERS > 0 - return getSingleEventDeviceOption<1,1>(display.midi.globals.store.layers[display.midi.globals.layer].encoders[dIndex], index, valueType); + return getEncoderOption<1,1>(store.layers[globals.layer].encoders[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_GLOBAL_ENCODER: #if BMC_MAX_GLOBAL_ENCODERS > 0 - return getSingleEventDeviceOption<1,1>(display.midi.globals.store.global.encoders[dIndex], index, valueType); + return getEncoderOption<1,1>(store.global.encoders[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_OLED: #if BMC_MAX_OLED > 0 - // return getSingleEventDeviceOption<1,1>(display.midi.globals.store.layers[display.midi.globals.layer].oled[dIndex], index, valueType); - return getDisplayOption<1,1>(display.midi.globals.store.layers[display.midi.globals.layer].oled[dIndex], index, valueType); + // return getSingleEventDeviceOption<1,1>(store.layers[globals.layer].oled[dIndex], index, valueType); + return getDisplayOption<1,1>(store.layers[globals.layer].oled[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_ILI: #if BMC_MAX_ILI9341_BLOCKS > 0 - return getDisplayOption<1,1>(display.midi.globals.store.layers[display.midi.globals.layer].ili[dIndex], index, valueType); + return getDisplayOption<1,1>(store.layers[globals.layer].ili[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_PIXEL: #if BMC_MAX_PIXELS > 0 - return getPixelOption<1,1>(display.midi.globals.store.layers[display.midi.globals.layer].pixels[dIndex], index, valueType); + return getPixelOption<1,1>(store.layers[globals.layer].pixels[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_GLOBAL_PIXEL: #if BMC_MAX_GLOBAL_PIXELS > 0 - return getPixelOption<1,1>(display.midi.globals.store.global.pixels[dIndex], index, valueType); + return getPixelOption<1,1>(store.global.pixels[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_RGB_PIXEL: #if BMC_MAX_RGB_PIXELS > 0 - return getRgbPixelOption<1,3>(display.midi.globals.store.layers[display.midi.globals.layer].rgbPixels[dIndex], index, valueType); + return getRgbPixelOption<1,3>(store.layers[globals.layer].rgbPixels[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_GLOBAL_RGB_PIXEL: #if BMC_MAX_GLOBAL_RGB_PIXELS > 0 - return getRgbPixelOption<1,3>(display.midi.globals.store.global.rgbPixels[dIndex], index, valueType); + return getRgbPixelOption<1,3>(store.global.rgbPixels[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_PIXEL_STRIP: #if BMC_MAX_PIXEL_STRIP > 0 - return getPixelOption<1,1>(display.midi.globals.store.layers[display.midi.globals.layer].pixelStrip[dIndex], index, valueType); + return getPixelOption<1,1>(store.layers[globals.layer].pixelStrip[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_NL_RELAY: #if BMC_MAX_NL_RELAYS > 0 - return getRelayOption<1,1>(display.midi.globals.store.global.relaysNL[dIndex], index, valueType); + return getRelayOption<1,1>(store.global.relaysNL[dIndex], index, valueType); #endif case BMC_DEVICE_ID_L_RELAY: #if BMC_MAX_L_RELAYS > 0 - return getRelayOption<1,1>(display.midi.globals.store.global.relaysL[dIndex], index, valueType); + return getRelayOption<1,1>(store.global.relaysL[dIndex], index, valueType); #endif case BMC_DEVICE_ID_MAGIC_ENCODER: #if BMC_MAX_MAGIC_ENCODERS > 0 - return getMagicEncoderOption<3,3>(display.midi.globals.store.layers[display.midi.globals.layer].magicEncoders[dIndex], index, valueType); + return getMagicEncoderOption<3,3>(store.layers[globals.layer].magicEncoders[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_GLOBAL_MAGIC_ENCODER: #if BMC_MAX_GLOBAL_MAGIC_ENCODERS > 0 - return getMagicEncoderOption<3,3>(display.midi.globals.store.global.magicEncoders[dIndex], index, valueType); + return getMagicEncoderOption<3,3>(store.global.magicEncoders[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_LFO: #if BMC_MAX_LFO > 0 - return getLfoOption<3, 5, uint8_t>(display.midi.globals.store.global.lfo[dIndex], index, valueType); + return getLfoOption<3, 5, uint8_t>(store.global.lfo[dIndex], index, valueType); #endif case BMC_DEVICE_ID_TRIGGER: #if BMC_MAX_TRIGGERS > 0 - return getTriggerOption<1, 2, uint8_t>(display.midi.globals.store.global.triggers[dIndex], index, valueType); + return getTriggerOption<1, 2, uint8_t>(store.global.triggers[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_TEMPO_TO_TAP: #if BMC_MAX_TEMPO_TO_TAP > 0 - return getSingleEventDeviceOption<1,1>(display.midi.globals.store.global.tempoToTap[dIndex], index, valueType); + return getSingleEventDeviceOption<1,1>(store.global.tempoToTap[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_TIMED_EVENT: #if BMC_MAX_TIMED_EVENTS > 0 - return getTimedEventOption<2,1>(display.midi.globals.store.global.timedEvents[dIndex], index, valueType); + return getTimedEventOption<2,1>(store.global.timedEvents[dIndex], index, valueType); #endif break; case BMC_DEVICE_ID_PRESET: @@ -425,7 +431,7 @@ class BMCOBEDevices { #endif break; case BMC_DEVICE_ID_PORT_PRESET: - return getPortPresetsOption<0, 1, uint8_t>(display.midi.globals.store.global.portPresets[dIndex], index, valueType); + return getPortPresetsOption<0, 1, uint8_t>(store.global.portPresets[dIndex], index, valueType); break; /* #if BMC_MAX_AUX_JACKS > 0 @@ -445,16 +451,16 @@ class BMCOBEDevices { memset(list, 0, BMC_MAX_PRESET_ITEMS); uint8_t counter = 0; for(uint8_t i = 0 ; i < BMC_MAX_PRESET_ITEMS ; i++){ - if(display.midi.globals.store.global.presets[deviceIndex].events[i]>0){ - list[counter++] = display.midi.globals.store.global.presets[deviceIndex].events[i]; + if(store.global.presets[deviceIndex].events[i]>0){ + list[counter++] = store.global.presets[deviceIndex].events[i]; } // empty the entire preset - display.midi.globals.store.global.presets[deviceIndex].events[i] = 0; + store.global.presets[deviceIndex].events[i] = 0; } // set the length - display.midi.globals.store.global.presets[deviceIndex].settings[0] = counter; + store.global.presets[deviceIndex].settings[0] = counter; for(uint8_t i = 0 ; i < counter ; i++){ - display.midi.globals.store.global.presets[deviceIndex].events[i] = list[i]; + store.global.presets[deviceIndex].events[i] = list[i]; } return 1; } @@ -462,10 +468,10 @@ class BMCOBEDevices { for(uint8_t i = 0, n = data.totalRows ; i < n ; i++){ if(i==0){ if(optionId == 0){ - return getNameField<1,BMC_MAX_PRESET_ITEMS>(display.midi.globals.store.global.presets[deviceIndex], valueType); + return getNameField<1,BMC_MAX_PRESET_ITEMS>(store.global.presets[deviceIndex], valueType); } } else if(i == optionId){ - return getEventField<1,BMC_MAX_PRESET_ITEMS>(display.midi.globals.store.global.presets[deviceIndex], "Event", i-1, 1, valueType); + return getEventField<1,BMC_MAX_PRESET_ITEMS>(store.global.presets[deviceIndex], "Event", i-1, 1, valueType); } } #endif @@ -479,16 +485,16 @@ class BMCOBEDevices { memset(list, 0, BMC_MAX_SETLISTS_SONGS); uint8_t counter = 0; for(uint8_t i = 0 ; i < BMC_MAX_SETLISTS_SONGS ; i++){ - if(display.midi.globals.store.global.setLists[deviceIndex].events[i]>0){ - list[counter++] = display.midi.globals.store.global.setLists[deviceIndex].events[i]; + if(store.global.setLists[deviceIndex].events[i]>0){ + list[counter++] = store.global.setLists[deviceIndex].events[i]; } // empty the entire preset - display.midi.globals.store.global.setLists[deviceIndex].events[i] = 0; + store.global.setLists[deviceIndex].events[i] = 0; } // set the length - display.midi.globals.store.global.setLists[deviceIndex].settings[0] = counter; + store.global.setLists[deviceIndex].settings[0] = counter; for(uint8_t i = 0 ; i < counter ; i++){ - display.midi.globals.store.global.setLists[deviceIndex].events[i] = list[i]; + store.global.setLists[deviceIndex].events[i] = list[i]; } return 1; } @@ -496,10 +502,10 @@ class BMCOBEDevices { for(uint8_t i = 0, n = data.totalRows ; i < n ; i++){ if(i==0){ if(optionId == 0){ - return getNameField<1,BMC_MAX_SETLISTS_SONGS>(display.midi.globals.store.global.setLists[deviceIndex], valueType); + return getNameField<1,BMC_MAX_SETLISTS_SONGS>(store.global.setLists[deviceIndex], valueType); } } else if(i == optionId){ - return getPartField<1,BMC_MAX_SETLISTS_SONGS>(display.midi.globals.store.global.setLists[deviceIndex], "Song", i-1, 1, valueType); + return getPartField<1,BMC_MAX_SETLISTS_SONGS>(store.global.setLists[deviceIndex], "Song", i-1, 1, valueType); } } #endif @@ -645,16 +651,16 @@ class BMCOBEDevices { memset(list, 0, BMC_MAX_SETLISTS_SONG_PARTS); uint8_t counter = 0; for(uint8_t i = 0 ; i < BMC_MAX_SETLISTS_SONG_PARTS ; i++){ - if(display.midi.globals.store.global.songLibrary[deviceIndex].events[i]>0){ - list[counter++] = display.midi.globals.store.global.songLibrary[deviceIndex].events[i]; + if(store.global.songLibrary[deviceIndex].events[i]>0){ + list[counter++] = store.global.songLibrary[deviceIndex].events[i]; } // empty the entire preset - display.midi.globals.store.global.songLibrary[deviceIndex].events[i] = 0; + store.global.songLibrary[deviceIndex].events[i] = 0; } // set the length - display.midi.globals.store.global.songLibrary[deviceIndex].settings[0] = counter; + store.global.songLibrary[deviceIndex].settings[0] = counter; for(uint8_t i = 0 ; i < counter ; i++){ - display.midi.globals.store.global.songLibrary[deviceIndex].events[i] = list[i]; + store.global.songLibrary[deviceIndex].events[i] = list[i]; } return 1; } @@ -662,10 +668,10 @@ class BMCOBEDevices { for(uint8_t i = 0, n = data.totalRows ; i < n ; i++){ if(i==0){ if(optionId == 0){ - return getNameField<1,BMC_MAX_SETLISTS_SONG_PARTS>(display.midi.globals.store.global.songLibrary[deviceIndex], valueType); + return getNameField<1,BMC_MAX_SETLISTS_SONG_PARTS>(store.global.songLibrary[deviceIndex], valueType); } } else if(i == optionId){ - return getSongField<1,BMC_MAX_SETLISTS_SONG_PARTS>(display.midi.globals.store.global.songLibrary[deviceIndex], "Part", i-1, 1, valueType); + return getSongField<1,BMC_MAX_SETLISTS_SONG_PARTS>(store.global.songLibrary[deviceIndex], "Part", i-1, 1, valueType); } } #endif @@ -866,6 +872,7 @@ class BMCOBEDevices { uint16_t getNamesEditor(bmcStoreName& item, uint16_t index, uint8_t valueType=0){ strcpy(str,""); + switch(valueType){ case BMC_OBE_DEVICE_OPT_CUSTOM_EDITOR: // render @@ -877,7 +884,7 @@ class BMCOBEDevices { charPage = 0; charPerPage = 0; memset(nameBuff, ' ', BMC_MAX_NAMES_LENGTH-1); - strcpy(nameBuff, display.midi.globals.store.global.names[data.deviceIndex].name); + strcpy(nameBuff, store.global.names[data.deviceIndex-1].name); for(uint8_t i = 0 ; i < BMC_MAX_NAMES_LENGTH-1 ; i++){ if(nameBuff[i] == 0){ nameBuff[i] = ' '; @@ -918,7 +925,7 @@ class BMCOBEDevices { buff.trim(); memset(nameBuff, 0, BMC_MAX_NAMES_LENGTH-1); buff.toCharArray(nameBuff, BMC_MAX_NAMES_LENGTH-1); - bmcStoreName& nameObj = display.midi.globals.store.global.names[data.deviceIndex]; + bmcStoreName& nameObj = store.global.names[data.deviceIndex-1]; if(strlen(nameBuff) != strlen(nameObj.name) || !BMC_STR_MATCH(nameBuff, nameObj.name)){ strcpy(nameObj.name, nameBuff); return 1; @@ -1161,7 +1168,7 @@ class BMCOBEDevices { if(BMC_IS_EVEN(index)){ switch(valueType){ case BMC_OBE_DEVICE_OPT_LABEL: - sprintf(str, "Mode # %u", e+offset); + sprintf(str, "Trigger # %u", e+offset); return 0; case BMC_OBE_DEVICE_OPT_VALUE: case BMC_OBE_DEVICE_OPT_EDITED_VALUE: @@ -1213,7 +1220,7 @@ class BMCOBEDevices { case BMC_OBE_DEVICE_OPT_VALUE: case BMC_OBE_DEVICE_OPT_EDITED_VALUE: { - uint8_t value = (valueType==BMC_OBE_DEVICE_OPT_VALUE) ? display.midi.globals.store.layers[display.midi.globals.layer].events[0].name : data.rowEditValue; + uint8_t value = (valueType==BMC_OBE_DEVICE_OPT_VALUE) ? store.layers[globals.layer].events[0].name : data.rowEditValue; if(value==0){ strcpy(str, "None"); } else { @@ -1228,8 +1235,8 @@ class BMCOBEDevices { case BMC_OBE_DEVICE_OPT_MIN: return 0; case BMC_OBE_DEVICE_OPT_MAX: return BMC_MAX_NAMES_LIBRARY-1; case BMC_OBE_DEVICE_OPT_CHANGED: - if(display.midi.globals.store.layers[display.midi.globals.layer].name != data.rowEditValue){ - display.midi.globals.store.layers[display.midi.globals.layer].name = data.rowEditValue; + if(store.layers[globals.layer].name != data.rowEditValue){ + store.layers[globals.layer].name = data.rowEditValue; return 1; } return 0; @@ -1247,7 +1254,6 @@ class BMCOBEDevices { for(uint8_t i = 0 ; i < BMC_MAX_SKETCH_BYTES ; i++){ if(optionId == i){ BMCSketchByteData sb = BMCBuildData::getSketchByteData(i); - BMC_PRINTLN(i, "getSketchByteOption min max", sb.min, sb.max, data.rowEditValue); switch(valueType){ case BMC_OBE_DEVICE_OPT_LABEL: strcpy(str, sb.name); @@ -1281,13 +1287,14 @@ class BMCOBEDevices { uint16_t getLayerEventOption(bmcStoreDevice& item, uint16_t index, uint8_t valueType=0){ strcpy(str,""); uint16_t optionId = data.visibleRowId[index]-1; - switch(optionId){ - case 0: - return getNameField(item, valueType); - case 1: - return getEventField(item, 0, 0, valueType); - default: - break; + for(uint8_t i = 0, n = data.totalRows ; i < n ; i++){ + if(i==0){ + if(optionId == 0){ + return getNameField(item, valueType); + } + } else if(i == optionId){ + return getEventField(item, i-1, 1, valueType); + } } return 0; } @@ -1511,7 +1518,7 @@ class BMCOBEDevices { } template uint16_t getPortPresetsOption(bmcStoreDevice& item, uint16_t index, uint8_t valueType=0){ - //display.midi.globals.store.global.portPresets[deviceIndex] + //store.global.portPresets[deviceIndex] strcpy(str,""); uint16_t optionId = data.visibleRowId[index]-1; if(optionId == 0){ @@ -1820,6 +1827,45 @@ class BMCOBEDevices { return 0; } template + uint16_t getEncoderOption(bmcStoreDevice& item, uint16_t index, uint8_t valueType=0){ + strcpy(str,""); + uint16_t optionId = data.visibleRowId[index]-1; + switch(optionId){ + case 0: + return getNameField(item, valueType); + case 1: + return getEventField(item, 0, 0, valueType); + case 2: + switch(valueType){ + case BMC_OBE_DEVICE_OPT_LABEL: + strcpy(str, "Toggle"); + return 0; + case BMC_OBE_DEVICE_OPT_VALUE: + case BMC_OBE_DEVICE_OPT_EDITED_VALUE: + { + uint8_t value = (valueType==BMC_OBE_DEVICE_OPT_VALUE) ? bitRead(item.settings[0],0) : data.rowEditValue; + strcpy(str, data.yesNoLabels[value]); + return value; + } + break; + case BMC_OBE_DEVICE_OPT_MIN: return 0; + case BMC_OBE_DEVICE_OPT_MAX: return 1; + case BMC_OBE_DEVICE_OPT_CHANGED: + if(bitRead(item.settings[0], 0) != data.rowEditValue){ + bitWrite(item.settings[0], 0, data.rowEditValue); + return 1; + } + return 0; + default: + return 0; + } + break; + default: + break; + } + return 0; + } + template uint16_t getDisplayOption(bmcStoreDevice& item, uint16_t index, uint8_t valueType=0){ strcpy(str,""); uint16_t optionId = data.visibleRowId[index]-1; @@ -1927,6 +1973,56 @@ class BMCOBEDevices { return 0; } break; + case 6: + switch(valueType){ + case BMC_OBE_DEVICE_OPT_LABEL: + strcpy(str, "Value Knob"); + return 0; + case BMC_OBE_DEVICE_OPT_VALUE: + case BMC_OBE_DEVICE_OPT_EDITED_VALUE: + { + uint8_t value = (valueType==BMC_OBE_DEVICE_OPT_VALUE) ? bitRead(item.settings[0], 4) : data.rowEditValue; + strcpy(str, data.yesNoLabels[value]); + return value; + } + break; + case BMC_OBE_DEVICE_OPT_MIN: return 0; + case BMC_OBE_DEVICE_OPT_MAX: return 1; + case BMC_OBE_DEVICE_OPT_CHANGED: + if(bitRead(item.settings[0], 4) != data.rowEditValue){ + bitWrite(item.settings[0], 4, data.rowEditValue); + return 1; + } + return 0; + default: + return 0; + } + break; + case 7: + switch(valueType){ + case BMC_OBE_DEVICE_OPT_LABEL: + strcpy(str, "On/Off"); + return 0; + case BMC_OBE_DEVICE_OPT_VALUE: + case BMC_OBE_DEVICE_OPT_EDITED_VALUE: + { + uint8_t value = (valueType==BMC_OBE_DEVICE_OPT_VALUE) ? bitRead(item.settings[0], 5) : data.rowEditValue; + strcpy(str, data.yesNoLabels[value]); + return value; + } + break; + case BMC_OBE_DEVICE_OPT_MIN: return 0; + case BMC_OBE_DEVICE_OPT_MAX: return 1; + case BMC_OBE_DEVICE_OPT_CHANGED: + if(bitRead(item.settings[0], 5) != data.rowEditValue){ + bitWrite(item.settings[0], 5, data.rowEditValue); + return 1; + } + return 0; + default: + return 0; + } + break; default: break; } @@ -2008,26 +2104,6 @@ class BMCOBEDevices { } return 0; } - - - - - - - - - - - - - - - - - - - - template uint16_t getNameField(bmcStoreDevice& item, uint8_t valueType=0){ @@ -2042,10 +2118,11 @@ class BMCOBEDevices { if(value==0){ strcpy(str, "None"); } else { - sprintf(str, "#%u ", (value-1)+offset); - char nameStr[40] = ""; - editor.getDeviceNameText(data.activeDevice.id, (value-1), nameStr); - strcat(str, nameStr); + if(strlen(store.global.names[value-1].name) > 0){ + sprintf(str, "#%u %s", (value-1)+offset, store.global.names[value-1].name); + } else { + sprintf(str, "#%u ...", (value-1)+offset); + } } return value; } @@ -2230,7 +2307,7 @@ class BMCOBEDevices { if(appendIndex==0){ strcpy(str, "Event"); } else if(appendIndex==1){ - sprintf(str, "Event # %u", eventIndex+offset); + sprintf(str, "Event #%u", eventIndex+offset); } else { strcpy(str, t_str); } @@ -2242,7 +2319,20 @@ class BMCOBEDevices { if(value==0){ strcpy(str, "None"); } else { - sprintf(str, "Event # %u", (value-1)+offset); + // eventsData + bmcName_t name = store.global.events[value-1].name; + if(name != 0 && strlen(store.global.names[name-1].name)>0){ + sprintf(str, "#%u %s", (value-1)+offset, store.global.names[name-1].name); + } else { + uint8_t status = store.global.events[value-1].type; + if(status == 0){ + sprintf(str, "#%u N/A", (value-1)+offset); + } else { + char eText[32] = ""; + eventsData.getEventStatusName(eText, status); + sprintf(str, "#%u [%s]", (value-1)+offset, eText); + } + } } return value; } @@ -2334,6 +2424,9 @@ class BMCOBEDevices { // Reference to the store from BMC.h BMCEditor& editor; BMCDisplay& display; + BMCGlobals& globals; + bmcStore& store; + BMCSettings& settings; BMC_TFT& tft; BMCOBEData& data; BMCOBEEvents eventsData; diff --git a/src/editor/onBoard/handlers/BMC-OBEEvents.h b/src/editor/onBoard/handlers/BMC-OBEEvents.h index b43b64b..e732988 100644 --- a/src/editor/onBoard/handlers/BMC-OBEEvents.h +++ b/src/editor/onBoard/handlers/BMC-OBEEvents.h @@ -592,7 +592,7 @@ class BMCOBEEvents { case BMC_EVENT_TYPE_LAYER: if(request==0){ /* available */ return BMC_MAX_LAYERS > 1; } - else if(request==1){ /* fields */ return 4; } + else if(request==1){ /* fields */ return 5; } else if(request==2){ /* scroll */ return true; } else if(request==3){ /* ports */ return false; } else if(request==4){ /* name */ strcpy(str, "Layer #"); return 1;} @@ -601,7 +601,7 @@ class BMCOBEEvents { case BMC_EVENT_TYPE_PRESET: if(request==0){ /* available */ return BMC_MAX_PRESETS > 0; } - else if(request==1){ /* fields */ return 4; } + else if(request==1){ /* fields */ return 6; } else if(request==2){ /* scroll */ return true; } else if(request==3){ /* ports */ return false; } else if(request==4){ /* name */ strcpy(str, "Preset #"); return 1;} @@ -610,7 +610,7 @@ class BMCOBEEvents { case BMC_EVENT_TYPE_BANK: if(request==0){ /* available */ return BMC_MAX_PRESETS > 0; } - else if(request==1){ /* fields */ return 4; } + else if(request==1){ /* fields */ return 5; } else if(request==2){ /* scroll */ return true; } else if(request==3){ /* ports */ return false; } else if(request==4){ /* name */ strcpy(str, "Bank #"); return 1;} @@ -621,7 +621,7 @@ class BMCOBEEvents { if(request==0){ /* available */ return BMC_MAX_SETLISTS > 0; } else if(request==1){ /* fields */ return 5; } else if(request==2){ /* scroll */ return true; } - else if(request==3){ /* ports */ return true; } + else if(request==3){ /* ports */ return false; } else if(request==4){ /* name */ strcpy(str, "SetList #"); return 1;} else if(request==5){ /* field */ return eventBmcEventTypeSetlist(str, fieldRequest, field);} break; @@ -630,7 +630,7 @@ class BMCOBEEvents { if(request==0){ /* available */ return BMC_MAX_SETLISTS > 0; } else if(request==1){ /* fields */ return 5; } else if(request==2){ /* scroll */ return true; } - else if(request==3){ /* ports */ return true; } + else if(request==3){ /* ports */ return false; } else if(request==4){ /* name */ strcpy(str, "Song #"); return 1;} else if(request==5){ /* field */ return eventBmcEventTypeSong(str, fieldRequest, field);} break; @@ -639,7 +639,7 @@ class BMCOBEEvents { if(request==0){ /* available */ return BMC_MAX_SETLISTS > 0; } else if(request==1){ /* fields */ return 5; } else if(request==2){ /* scroll */ return true; } - else if(request==3){ /* ports */ return true; } + else if(request==3){ /* ports */ return false; } else if(request==4){ /* name */ strcpy(str, "Song Part #"); return 1;} else if(request==5){ /* field */ return eventBmcEventTypePart(str, fieldRequest, field);} break; @@ -1460,25 +1460,44 @@ class BMCOBEEvents { case 0: return eventNameField(str, fieldRequest, field); case 1: - return eventGetField16BitValueRange(str, "Layer", fieldRequest, 0, 0, BMC_MAX_LAYERS-1, true); + return eventGetField8BitValueRange(str, "Layer", fieldRequest, 0, 0, BMC_MAX_LAYERS-1, true); case 2: - return eventGetScrollEnableField(str, fieldRequest); + switch(fieldRequest){ + case 0: strcpy(str, "Layer B"); return 1; /* label */ + case 1: return 0; /* min */ + case 2: return BMC_MAX_LAYERS; /* max */ + case 3: /* get stored value */ + return BMC_GET_BYTE(1, tempEvent.event); + case 4: /* set stored value */ + BMC_WRITE_BITS(tempEvent.event, tempValue, 0xFF, 8); + return 1; + case 5: /* formatted value */ + if(BMC_GET_BYTE(1, tempEvent.event) == 0){ + strcpy(str, "OFF"); + } else { + sprintf(str, "%u", (uint16_t)((BMC_GET_BYTE(1, tempEvent.event)-1)+offset)); + } + return 1; + } + break; case 3: - return eventGetScrollDirectionField(str, fieldRequest); + return eventGetScrollEnableField(str, fieldRequest); case 4: + return eventGetScrollDirectionField(str, fieldRequest); + case 5: return eventGetScrollWrapField(str, fieldRequest); } return 0; } - uint16_t eventBmcEventTypeLayerName(char* str, uint8_t fieldRequest, uint8_t field){ - switch(field){ - case 0: - return eventNameField(str, fieldRequest, field); - case 1: - return eventGetField16BitValueRange(str, "Layer", fieldRequest, 0, 0, BMC_MAX_LAYERS-1, true); - } - return 0; - } + // uint16_t eventBmcEventTypeLayerName(char* str, uint8_t fieldRequest, uint8_t field){ + // switch(field){ + // case 0: + // return eventNameField(str, fieldRequest, field); + // case 1: + // return eventGetField16BitValueRange(str, "Layer", fieldRequest, 0, 0, BMC_MAX_LAYERS-1, true); + // } + // return 0; + // } uint16_t eventBmcEventTypePreset(char* str, uint8_t fieldRequest, uint8_t field){ switch(field){ case 0: @@ -1486,34 +1505,109 @@ class BMCOBEEvents { case 1: return eventGetField8BitValueRange(str, "Preset", fieldRequest, 0, 0, BMC_MAX_PRESETS_PER_BANK-1, true); case 2: - return eventGetScrollEnableField(str, fieldRequest); + switch(fieldRequest){ + case 0: strcpy(str, "Preset B"); return 1; /* label */ + case 1: return 0; /* min */ + case 2: return BMC_MAX_PRESETS_PER_BANK; /* max */ + case 3: /* get stored value */ + return BMC_GET_BYTE(1, tempEvent.event); + case 4: /* set stored value */ + BMC_WRITE_BITS(tempEvent.event, tempValue, 0xFF, 8); + return 1; + case 5: /* formatted value */ + if(BMC_GET_BYTE(1, tempEvent.event) == 0){ + strcpy(str, "OFF"); + } else { + sprintf(str, "%u", (uint16_t)((BMC_GET_BYTE(1, tempEvent.event)-1)+offset)); + } + return 1; + } + break; + case 3: - return eventGetScrollDirectionField(str, fieldRequest); + switch(fieldRequest){ + case 0: strcpy(str, "Scroll ALL"); return 1; /* label */ + case 1: return 0; /* min */ + case 2: return 1; /* max */ + case 3: /* get stored value */ + return BMC_GET_BYTE(2, tempEvent.event); + case 4: /* set stored value */ + BMC_WRITE_BITS(tempEvent.event, tempValue, 0xFF, 2); + return 1; + case 5: /* formatted value */ + switch(BMC_GET_BYTE(2, tempEvent.event)){ + case 0: strcpy(str, "OFF"); return 1; + case 1: strcpy(str, "ON"); return 1; + } + return 1; + } + break; case 4: + return eventGetScrollEnableField(str, fieldRequest); + case 5: + return eventGetScrollDirectionField(str, fieldRequest); + case 6: return eventGetScrollWrapField(str, fieldRequest); } return 0; } - uint16_t eventBmcEventTypePresetName(char* str, uint8_t fieldRequest, uint8_t field){ - switch(field){ - case 0: - return eventNameField(str, fieldRequest, field); - case 1: - return eventGetField8BitValueRange(str, "Preset", fieldRequest, 0, 0, BMC_MAX_PRESETS_PER_BANK-1, true); - } - return 0; - } + // uint16_t eventBmcEventTypePresetName(char* str, uint8_t fieldRequest, uint8_t field){ + // switch(field){ + // case 0: + // return eventNameField(str, fieldRequest, field); + // case 1: + // return eventGetField8BitValueRange(str, "Preset", fieldRequest, 0, 0, BMC_MAX_PRESETS_PER_BANK-1, true); + // } + // return 0; + // } uint16_t eventBmcEventTypeBank(char* str, uint8_t fieldRequest, uint8_t field){ switch(field){ case 0: return eventNameField(str, fieldRequest, field); + // case 1: + // return eventGetField8BitValueRange(str, "Bank", fieldRequest, 0, 0, BMC_MAX_PRESET_BANKS-1, true); case 1: - return eventGetField8BitValueRange(str, "Bank", fieldRequest, 0, 0, BMC_MAX_PRESET_BANKS-1, true); + switch(fieldRequest){ + case 0: strcpy(str, "Bank"); return 1; /* label */ + case 1: return 0; /* min */ + case 2: return BMC_MAX_PRESET_BANKS-1; /* max */ + case 3: /* get stored value */ + return BMC_GET_BYTE(0, tempEvent.event); + case 4: /* set stored value */ + BMC_WRITE_BITS(tempEvent.event, tempValue, 0xFF, 0); + return 1; + case 5: /* formatted value */ + // char letter[3] = ""; + BMCTools::getBankLetter(BMC_GET_BYTE(0, tempEvent.event), str); + // sprintf(str, "%s", letter); + return 1; + } + break; case 2: - return eventGetScrollEnableField(str, fieldRequest); + switch(fieldRequest){ + case 0: strcpy(str, "Bank B"); return 1; /* label */ + case 1: return 0; /* min */ + case 2: return BMC_MAX_PRESET_BANKS; /* max */ + case 3: /* get stored value */ + return BMC_GET_BYTE(1, tempEvent.event); + case 4: /* set stored value */ + BMC_WRITE_BITS(tempEvent.event, tempValue, 0xFF, 8); + return 1; + case 5: /* formatted value */ + if(BMC_GET_BYTE(1, tempEvent.event) == 0){ + strcpy(str, "OFF"); + } else { + // sprintf(str, "%u", (uint16_t)((BMC_GET_BYTE(1, tempEvent.event)-1)+offset)); + BMCTools::getBankLetter(BMC_GET_BYTE(1, tempEvent.event)-1, str); + } + return 1; + } + break; case 3: - return eventGetScrollDirectionField(str, fieldRequest); + return eventGetScrollEnableField(str, fieldRequest); case 4: + return eventGetScrollDirectionField(str, fieldRequest); + case 5: return eventGetScrollWrapField(str, fieldRequest); } return 0; @@ -1525,34 +1619,51 @@ class BMCOBEEvents { case 1: return eventGetField8BitValueRange(str, "SetList", fieldRequest, 0, 0, BMC_MAX_SETLISTS-1, true); case 2: - return eventGetScrollEnableField(str, fieldRequest); + switch(fieldRequest){ + case 0: strcpy(str, "Setlist B"); return 1; /* label */ + case 1: return 0; /* min */ + case 2: return BMC_MAX_SETLISTS; /* max */ + case 3: /* get stored value */ + return BMC_GET_BYTE(1, tempEvent.event); + case 4: /* set stored value */ + BMC_WRITE_BITS(tempEvent.event, tempValue, 0xFF, 8); + return 1; + case 5: /* formatted value */ + if(BMC_GET_BYTE(1, tempEvent.event) == 0){ + strcpy(str, "OFF"); + } else { + sprintf(str, "%u", (uint16_t)((BMC_GET_BYTE(1, tempEvent.event)-1)+offset)); + } + return 1; + } + break; case 3: - return eventGetScrollDirectionField(str, fieldRequest); + return eventGetScrollEnableField(str, fieldRequest); case 4: - return eventGetScrollWrapField(str, fieldRequest); + return eventGetScrollDirectionField(str, fieldRequest); case 5: - return eventGetPortsField(str, fieldRequest, field); - } - return 0; - } - uint16_t eventBmcEventTypeSetlistName(char* str, uint8_t fieldRequest, uint8_t field){ - switch(field){ - case 0: - return eventNameField(str, fieldRequest, field); - case 1: - return eventGetField8BitValueRange(str, "SetList", fieldRequest, 0, 0, BMC_MAX_SETLISTS-1, true); - } - return 0; - } - uint16_t eventBmcEventTypeSetlistSelectedName(char* str, uint8_t fieldRequest, uint8_t field){ - switch(field){ - case 0: - return eventNameField(str, fieldRequest, field); - case 1: - return eventGetField8BitValueRange(str, "SetList", fieldRequest, 0, 0, BMC_MAX_SETLISTS-1, true); + return eventGetScrollWrapField(str, fieldRequest); } return 0; } + // uint16_t eventBmcEventTypeSetlistName(char* str, uint8_t fieldRequest, uint8_t field){ + // switch(field){ + // case 0: + // return eventNameField(str, fieldRequest, field); + // case 1: + // return eventGetField8BitValueRange(str, "SetList", fieldRequest, 0, 0, BMC_MAX_SETLISTS-1, true); + // } + // return 0; + // } + // uint16_t eventBmcEventTypeSetlistSelectedName(char* str, uint8_t fieldRequest, uint8_t field){ + // switch(field){ + // case 0: + // return eventNameField(str, fieldRequest, field); + // case 1: + // return eventGetField8BitValueRange(str, "SetList", fieldRequest, 0, 0, BMC_MAX_SETLISTS-1, true); + // } + // return 0; + // } uint16_t eventBmcEventTypeSong(char* str, uint8_t fieldRequest, uint8_t field){ switch(field){ case 0: @@ -1560,25 +1671,42 @@ class BMCOBEEvents { case 1: return eventGetField8BitValueRange(str, "Song", fieldRequest, 0, 0, BMC_MAX_SETLISTS_SONGS-1, true); case 2: - return eventGetScrollEnableField(str, fieldRequest); + switch(fieldRequest){ + case 0: strcpy(str, "Song B"); return 1; /* label */ + case 1: return 0; /* min */ + case 2: return BMC_MAX_SETLISTS_SONGS; /* max */ + case 3: /* get stored value */ + return BMC_GET_BYTE(1, tempEvent.event); + case 4: /* set stored value */ + BMC_WRITE_BITS(tempEvent.event, tempValue, 0xFF, 8); + return 1; + case 5: /* formatted value */ + if(BMC_GET_BYTE(1, tempEvent.event) == 0){ + strcpy(str, "OFF"); + } else { + sprintf(str, "%u", (uint16_t)((BMC_GET_BYTE(1, tempEvent.event)-1)+offset)); + } + return 1; + } + break; case 3: - return eventGetScrollDirectionField(str, fieldRequest); + return eventGetScrollEnableField(str, fieldRequest); case 4: - return eventGetScrollWrapField(str, fieldRequest); + return eventGetScrollDirectionField(str, fieldRequest); case 5: - return eventGetPortsField(str, fieldRequest, field); - } - return 0; - } - uint16_t eventBmcEventTypeSongName(char* str, uint8_t fieldRequest, uint8_t field){ - switch(field){ - case 0: - return eventNameField(str, fieldRequest, field); - case 1: - return eventGetField8BitValueRange(str, "Song", fieldRequest, 0, 0, BMC_MAX_SETLISTS_SONGS-1, true); + return eventGetScrollWrapField(str, fieldRequest); } return 0; } + // uint16_t eventBmcEventTypeSongName(char* str, uint8_t fieldRequest, uint8_t field){ + // switch(field){ + // case 0: + // return eventNameField(str, fieldRequest, field); + // case 1: + // return eventGetField8BitValueRange(str, "Song", fieldRequest, 0, 0, BMC_MAX_SETLISTS_SONGS-1, true); + // } + // return 0; + // } uint16_t eventBmcEventTypePart(char* str, uint8_t fieldRequest, uint8_t field){ switch(field){ case 0: @@ -1586,25 +1714,42 @@ class BMCOBEEvents { case 1: return eventGetField8BitValueRange(str, "Part", fieldRequest, 0, 0, BMC_MAX_SETLISTS_SONG_PARTS-1, true); case 2: - return eventGetScrollEnableField(str, fieldRequest); + switch(fieldRequest){ + case 0: strcpy(str, "Part B"); return 1; /* label */ + case 1: return 0; /* min */ + case 2: return BMC_MAX_SETLISTS_SONG_PARTS; /* max */ + case 3: /* get stored value */ + return BMC_GET_BYTE(1, tempEvent.event); + case 4: /* set stored value */ + BMC_WRITE_BITS(tempEvent.event, tempValue, 0xFF, 8); + return 1; + case 5: /* formatted value */ + if(BMC_GET_BYTE(1, tempEvent.event) == 0){ + strcpy(str, "OFF"); + } else { + sprintf(str, "%u", (uint16_t)((BMC_GET_BYTE(1, tempEvent.event)-1)+offset)); + } + return 1; + } + break; case 3: - return eventGetScrollDirectionField(str, fieldRequest); + return eventGetScrollEnableField(str, fieldRequest); case 4: - return eventGetScrollWrapField(str, fieldRequest); + return eventGetScrollDirectionField(str, fieldRequest); case 5: - return eventGetPortsField(str, fieldRequest, field); - } - return 0; - } - uint16_t eventBmcEventTypePartName(char* str, uint8_t fieldRequest, uint8_t field){ - switch(field){ - case 0: - return eventNameField(str, fieldRequest, field); - case 1: - return eventGetField8BitValueRange(str, "Part", fieldRequest, 0, 0, BMC_MAX_SETLISTS_SONG_PARTS-1, true); + return eventGetScrollWrapField(str, fieldRequest); } return 0; } + // uint16_t eventBmcEventTypePartName(char* str, uint8_t fieldRequest, uint8_t field){ + // switch(field){ + // case 0: + // return eventNameField(str, fieldRequest, field); + // case 1: + // return eventGetField8BitValueRange(str, "Part", fieldRequest, 0, 0, BMC_MAX_SETLISTS_SONG_PARTS-1, true); + // } + // return 0; + // } uint16_t eventBmcEventTypeNlRelay(char* str, uint8_t fieldRequest, uint8_t field){ switch(field){ case 0: @@ -2072,7 +2217,7 @@ class BMCOBEEvents { return value; // return (tempEvent.event >> 16) & 0x3FF; case 4: /* set stored value */ - BMC_WRITE_BITS(tempEvent.event, tempValue, 0x3FF, 16); + BMC_WRITE_BITS(tempEvent.event, tempValue, 0x7FF, 16); return 1; case 5: /* formatted value */ if(value == 0){ diff --git a/src/hardware/BMC-Encoder.h b/src/hardware/BMC-Encoder.h index ca77887..1ef6471 100644 --- a/src/hardware/BMC-Encoder.h +++ b/src/hardware/BMC-Encoder.h @@ -136,10 +136,18 @@ class BMCEncoder { if(output != 0){ //BMC_PRINTLN(output, readB(), readA()); flags.on(BMC_ENCODER_FLAG_ACTIVITY); + // encoders reading can be tricky, you may turn the knob clockwise + // and sometimes it will also trigger a counter-clockwise reading + // and vice-versa to avoid this noise BMC will ignore the very + // first turn in the oposite direction, if you turn the encoder right + // and the last turn was to the right BMC will read it as usual + // if the the last turn was to the left BMC will ignore that reading + // however the next time you rotate left BMC will continue to read as usual. + bool allowReading = false; flags.write(BMC_ENCODER_FLAG_INCREASED,(output>0)); uint16_t currentTurn = millis()&0xFFFF; uint16_t subs = (currentTurn-lastTurn); - if(lastTurnDirection==flags.read(BMC_ENCODER_FLAG_INCREASED)){ + if(bitRead(lastTurnDirection, 0) == flags.read(BMC_ENCODER_FLAG_INCREASED)){ if(subs < 10){ ticks = 6; } else if(subs < 20){ @@ -149,10 +157,11 @@ class BMCEncoder { } else if(subs < 40){ ticks = 2; } + allowReading = true; } - lastTurnDirection = (output>0)?1:0; + bitWrite(lastTurnDirection, 0, (output>0)); lastTurn = millis()&0xFFFF; - return true; + return allowReading; } if((millis()&0xFFFF)-lastTurn>50){ lastTurn = 0; diff --git a/src/hardware/BMC-Led.h b/src/hardware/BMC-Led.h index 202f11d..f34c233 100644 --- a/src/hardware/BMC-Led.h +++ b/src/hardware/BMC-Led.h @@ -191,7 +191,6 @@ class BMCLed { reset(); setBlinkMode(t_settings > 0); setBlinkSpeed(t_settings); - BMC_PRINTLN("LED reassign", t_settings); } // set weather the LED will blink when on void setBlinkMode(bool t_mode){ diff --git a/src/hardware/BMC-Pixels.h b/src/hardware/BMC-Pixels.h index b4a974e..9bde043 100644 --- a/src/hardware/BMC-Pixels.h +++ b/src/hardware/BMC-Pixels.h @@ -107,7 +107,6 @@ class BMCPixels { BMCUIData ui = BMCBuildData::getUIData(BMC_DEVICE_ID_PIXEL, i); setDimColor(i, ui.style); #if !defined(BMC_NO_LED_TEST_AT_LAUNCH) - BMC_PRINTLN("test pixel", i); test(BMC_DEVICE_ID_PIXEL, i, true); #endif } diff --git a/src/utility/BMC-Def.h b/src/utility/BMC-Def.h index 9b51fdf..eaa926f 100644 --- a/src/utility/BMC-Def.h +++ b/src/utility/BMC-Def.h @@ -359,6 +359,10 @@ const char bmcAlphabet[26] = {'A','B','C','D','E','F','G','H','I','J','K','L','M #define BMC_UP 1 #define BMC_PREV BMC_DOWN #define BMC_NEXT BMC_UP + +#define BMC_DEC BMC_DOWN +#define BMC_INC BMC_UP + #define BMC_SCROLL_DOWN BMC_DOWN #define BMC_SCROLL_UP BMC_UP #define BMC_SCROLL_PREV BMC_DOWN @@ -366,6 +370,10 @@ const char bmcAlphabet[26] = {'A','B','C','D','E','F','G','H','I','J','K','L','M #define BMC_SCROLL_LIMITED BMC_DOWN #define BMC_SCROLL_ENDLESS BMC_UP +#define BMC_NO_WRAP BMC_UP +#define BMC_WRAP BMC_UP + + // for menu #define BMC_MENU_TOGGLE 1 #define BMC_MENU_SELECT 2 diff --git a/src/utility/BMC-Globals.h b/src/utility/BMC-Globals.h index ab9d058..4699fe2 100644 --- a/src/utility/BMC-Globals.h +++ b/src/utility/BMC-Globals.h @@ -32,6 +32,8 @@ #define BMC_GLOBALS_FLAG_TRIGGER_SETLIST 12 #define BMC_GLOBALS_FLAG_TRIGGER_SONG 13 #define BMC_GLOBALS_FLAG_TRIGGER_SONG_PART 14 +#define BMC_GLOBALS_FLAG_PAUSE_ILI 15 +#define BMC_GLOBALS_FLAG_RENDER_DISPLAY_LIST 16 #define BMC_GLOBALS_DEBUG_FLAG_STORAGE 0 @@ -147,10 +149,16 @@ class BMCGlobals { return flags.toggle(BMC_GLOBALS_FLAG_ON_BOARD_EDITOR_ACTIVE); } bool onBoardEditorActive(){ +#if defined(BMC_USE_ON_BOARD_EDITOR) return flags.read(BMC_GLOBALS_FLAG_ON_BOARD_EDITOR_ACTIVE); +#else + return false; +#endif } void setDisplayRenderDisable(bool state){ +#if defined(BMC_USE_ON_BOARD_EDITOR) flags.write(BMC_GLOBALS_FLAG_DISABLE_DISPLAY_RENDER, state); +#endif } bool displayRenderDisabled(){ return flags.read(BMC_GLOBALS_FLAG_DISABLE_DISPLAY_RENDER); @@ -299,6 +307,83 @@ bool getButtonStateBit(bool isGlobal, uint16_t n){ return 0; } + +bool pauseIli(){ + return flags.read(BMC_GLOBALS_FLAG_PAUSE_ILI); +} +bool pauseIli(bool value){ + flags.write(BMC_GLOBALS_FLAG_PAUSE_ILI, value); + return value; +} +bool getRenderDisplayList(){ + return flags.toggleIfTrue(BMC_GLOBALS_FLAG_RENDER_DISPLAY_LIST); +} +bool setRenderDisplayList(uint8_t id){ + if(onBoardEditorActive() || !settings.getDisplayListMode()){ + return false; + } +#if BMC_MAX_ILI9341_BLOCKS > 0 && (BMC_MAX_SETLISTS > 0 || BMC_MAX_LAYERS > 1 || BMC_MAX_PRESETS > 0) + // if(!displayListsActive() && !flags.read(BMC_GLOBALS_FLAG_RENDER_DISPLAY_LIST)){ + + // } + if(displayListsActive() && !flags.read(BMC_GLOBALS_FLAG_RENDER_DISPLAY_LIST)){ + flags.on(BMC_GLOBALS_FLAG_RENDER_DISPLAY_LIST); + return false; + } else if(!displayListsActive() && !flags.read(BMC_GLOBALS_FLAG_RENDER_DISPLAY_LIST)){ + displayListId = id; + flags.on(BMC_GLOBALS_FLAG_RENDER_DISPLAY_LIST); + return true; + } +#endif + return false; +} + +uint8_t getDisplayListId(){ +#if BMC_MAX_ILI9341_BLOCKS > 0 && (BMC_MAX_SETLISTS > 0 || BMC_MAX_LAYERS > 1 || BMC_MAX_PRESETS > 0) + return displayListId; +#else + return 0; +#endif +} + +bool displayListsActive(){ +#if BMC_MAX_ILI9341_BLOCKS > 0 && (BMC_MAX_SETLISTS > 0 || BMC_MAX_LAYERS > 1 || BMC_MAX_PRESETS > 0) + return displayListsTimer.active(); +#else + return false; +#endif +} +bool displayListsComplete(){ + #if BMC_MAX_ILI9341_BLOCKS > 0 && (BMC_MAX_SETLISTS > 0 || BMC_MAX_LAYERS > 1 || BMC_MAX_PRESETS > 0) + return displayListsTimer.complete(); + #else + return false; + #endif +} +// bool displayListsActive(){ +// #if BMC_MAX_ILI9341_BLOCKS > 0 && (BMC_MAX_SETLISTS > 0 || BMC_MAX_LAYERS > 1 || BMC_MAX_PRESETS > 0) +// return displayListsTimer.active(); +// #else +// return false; +// #endif +// } +void enterDisplayListMode(uint16_t value){ +#if BMC_MAX_ILI9341_BLOCKS > 0 && (BMC_MAX_SETLISTS > 0 || BMC_MAX_LAYERS > 1 || BMC_MAX_PRESETS > 0) + BMC_PRINTLN("*** Enter Display List Mode"); + displayListsTimer.start(value); + pauseIli(true); +#endif +} +void exitDisplayListMode(){ +#if BMC_MAX_ILI9341_BLOCKS > 0 && (BMC_MAX_SETLISTS > 0 || BMC_MAX_LAYERS > 1 || BMC_MAX_PRESETS > 0) + BMC_PRINTLN("*** Exit Display List Mode"); + displayListsTimer.stop(); + displayListId = 0; + pauseIli(false); +#endif +} + + bmcStoreEvent getDeviceEventType(uint16_t n){ bmcStoreEvent e; if(n > 0 && n <= BMC_MAX_EVENTS_LIBRARY){ @@ -404,12 +489,19 @@ bmcStoreName getDeviceName(uint16_t n){ BMCBitStates auxJackStates; #endif +#if BMC_MAX_ILI9341_BLOCKS > 0 && (BMC_MAX_SETLISTS > 0 || BMC_MAX_LAYERS > 1 || BMC_MAX_PRESETS > 0) + BMCTimer displayListsTimer; + uint8_t displayListId = 0; +#endif + private: - BMCFlags flags; + BMCFlags flags; #ifdef BMC_DEBUG BMCFlags debugFlags; #endif + + uint32_t loopsPerSecond = 0; uint32_t lastLoopsPerSecond = 0; void reset(){ diff --git a/src/utility/BMC-Presets.h b/src/utility/BMC-Presets.h index 5bfad2f..aec8621 100644 --- a/src/utility/BMC-Presets.h +++ b/src/utility/BMC-Presets.h @@ -23,8 +23,10 @@ class BMCPresets { { } void setByIndex(uint16_t t_presetAndBank, bool forced=false){ - uint8_t t_bank = (t_presetAndBank >> BMC_PRESET_BANK_MASK) & 0x1F; - uint8_t t_preset = t_presetAndBank & (BMC_MAX_PRESETS_PER_BANK-1); + // uint8_t t_bank = (t_presetAndBank >> BMC_PRESET_BANK_MASK) & 0x1F; + // uint8_t t_preset = t_presetAndBank & (BMC_MAX_PRESETS_PER_BANK-1); + uint8_t t_bank = getBankFromPresetIndex(t_presetAndBank); + uint8_t t_preset = getPresetInBankFromPresetIndex(t_presetAndBank); set(t_bank, t_preset, forced); } void setPreset(uint8_t t_preset, bool forced = false){ @@ -46,17 +48,94 @@ class BMCPresets { BMC_PRINTLN("Switch Preset, Bank:", t_bank, "Preset:", t_preset, "presetIndex:", presetIndex); } } - uint8_t scrollPreset(bool t_direction, bool t_wrap, uint8_t amount=1){ + uint16_t scrollPresetList(bool t_direction, bool t_wrap, uint8_t amount=1, uint8_t t_min=0, uint8_t t_max=0){ + // if(!midi.globals.onBoardEditorActive()){ + // if(midi.globals.settings.getDisplayListMode() && !midi.globals.displayListsActive()){ + // midi.globals.setRenderDisplayList(BMC_DEVICE_ID_PRESET); + // return presetIndex; + // } + // } + if(midi.globals.setRenderDisplayList(BMC_DEVICE_ID_PRESET)){ + return presetIndex; + } + if(t_min > t_max){ + uint8_t t_min2 = t_min; + t_min = t_max; + t_max = t_min2; + } else if(t_min == t_max){ + t_min = 0; + t_max = BMC_MAX_PRESETS-1; + } + if(t_max > BMC_MAX_PRESETS-1){ + t_max = BMC_MAX_PRESETS-1; + } + if(t_min > BMC_MAX_PRESETS-1){ + t_min = 0; + } + amount = (amount >= BMC_MAX_PRESETS || amount==0) ? 1 : amount; + BMCScroller scroller(0, BMC_MAX_PRESETS-1); + uint16_t value = scroller.scroll(amount, t_direction, t_wrap, presetIndex, t_min, t_max); + setByIndex(value, false); + return value; + } + uint8_t scrollPreset(bool t_direction, bool t_wrap, uint8_t amount=1, uint8_t t_min=0, uint8_t t_max=0){ + // if(!midi.globals.onBoardEditorActive()){ + // if(midi.globals.settings.getDisplayListMode() && !midi.globals.displayListsActive()){ + // midi.globals.setRenderDisplayList(BMC_DEVICE_ID_PRESET); + // return preset; + // } + // } + if(midi.globals.setRenderDisplayList(BMC_DEVICE_ID_PRESET)){ + return preset; + } + BMC_PRINTLN("*************** SCROLL PRESET ***************"); + if(t_min > t_max){ + uint8_t t_min2 = t_min; + t_min = t_max; + t_max = t_min2; + } else if(t_min == t_max){ + t_min = 0; + t_max = BMC_MAX_PRESETS_PER_BANK-1; + } + if(t_max > BMC_MAX_PRESETS_PER_BANK-1){ + t_max = BMC_MAX_PRESETS_PER_BANK-1; + } + if(t_min > BMC_MAX_PRESETS_PER_BANK-1){ + t_min = 0; + } amount = (amount >= BMC_MAX_PRESETS_PER_BANK || amount==0) ? 1 : amount; BMCScroller scroller(0, BMC_MAX_PRESETS_PER_BANK-1); - uint8_t value = scroller.scroll(amount, t_direction, t_wrap, preset, 0, BMC_MAX_PRESETS_PER_BANK-1); + uint8_t value = scroller.scroll(amount, t_direction, t_wrap, preset, t_min, t_max); set(bank, value); return value; } - uint8_t scrollBank(bool t_direction, bool t_wrap, uint8_t amount=1){ + uint8_t scrollBank(bool t_direction, bool t_wrap, uint8_t amount=1, uint8_t t_min=0, uint8_t t_max=0){ + // if(!midi.globals.onBoardEditorActive()){ + // if(midi.globals.settings.getDisplayListMode() && !midi.globals.displayListsActive()){ + // midi.globals.setRenderDisplayList(BMC_DEVICE_ID_PRESET); + // return bank; + // } + // } + if(midi.globals.setRenderDisplayList(BMC_DEVICE_ID_PRESET)){ + return bank; + } + if(t_min > t_max){ + uint8_t t_min2 = t_min; + t_min = t_max; + t_max = t_min2; + } else if(t_min == t_max){ + t_min = 0; + t_max = BMC_MAX_PRESET_BANKS-1; + } + if(t_max > BMC_MAX_PRESET_BANKS-1){ + t_max = BMC_MAX_PRESET_BANKS-1; + } + if(t_min > BMC_MAX_PRESET_BANKS-1){ + t_min = 0; + } amount = (amount >= BMC_MAX_PRESET_BANKS || amount==0) ? 1 : amount; BMCScroller scroller(0, BMC_MAX_PRESET_BANKS-1); - uint8_t value = scroller.scroll(amount, t_direction, t_wrap, bank, 0, BMC_MAX_PRESET_BANKS-1); + uint8_t value = scroller.scroll(amount, t_direction, t_wrap, bank, t_min, t_max); set(value, preset); return value; } @@ -147,6 +226,14 @@ class BMCPresets { } return p; } + uint8_t getBankFromPresetIndex(uint16_t t_presetAndBank){ + return ((t_presetAndBank >> BMC_PRESET_BANK_MASK) & 0x1F); + + } + uint8_t getPresetInBankFromPresetIndex(uint16_t t_presetAndBank){ + return (t_presetAndBank & (BMC_MAX_PRESETS_PER_BANK-1)); + } + public: BMCMidi& midi; diff --git a/src/utility/BMC-SetLists.h b/src/utility/BMC-SetLists.h index 27e0c42..4d0b57d 100644 --- a/src/utility/BMC-SetLists.h +++ b/src/utility/BMC-SetLists.h @@ -33,11 +33,16 @@ class BMCSetLists { { } - void set(uint8_t n=0, bool firstSong=false){ + void update(){ + + } + void set(uint8_t n){ if(n >= BMC_MAX_SETLISTS){ return; } - if(presets.midi.globals.store.global.setLists[n].settings[0] > 0){ + + // allow switching to setlist that has no songs assigned + if(setList != n){ setList = n; BMC_PRINTLN("Set SetList #", n); flags.on(BMC_FLAG_SETLISTS_CHANGED); @@ -46,31 +51,28 @@ class BMCSetLists { } } } - void setSong(uint8_t n=0){ + void setSong(uint8_t n){ if(n >= BMC_MAX_SETLISTS_SONGS){ return; } - if(presets.midi.globals.store.global.setLists[setList].settings[0] > n){ + // allow switching to song without parts + if(song != n || flags.read(BMC_FLAG_SETLISTS_CHANGED)){ + flags.on(BMC_FLAG_SETLISTS_SONG_CHANGED); song = n; songInLibrary = presets.midi.globals.store.global.setLists[setList].events[song]; - if(setHasSong(n)){ - songEmpty(false); // song has parts - if(autoTriggerFirstPart()){ - // trigger first part - setPart(0); - } - } else { - songEmpty(true); + songEmpty(setHasSong(n)); // song has parts + if(autoTriggerFirstPart()){ + // trigger first part + setPart(0); } BMC_PRINTLN("Song #", n); - flags.on(BMC_FLAG_SETLISTS_SONG_CHANGED); } } - void setPart(uint8_t n=0){ + void setPart(uint8_t n){ if(n >= BMC_MAX_SETLISTS_SONG_PARTS){ return; } - if(presets.midi.globals.store.global.songLibrary[songInLibrary].settings[0] > n){ + if(songPart != n || flags.read(BMC_FLAG_SETLISTS_SONG_CHANGED)){ songPart = n; if(songHasPart(songPart)){ partEmpty(false); @@ -128,27 +130,78 @@ class BMCSetLists { } return 0; } - void scrollSet(bool t_direction, bool t_wrap, uint8_t t_amount, bool firstSong=true){ - uint8_t t_max = BMC_MAX_SETLISTS-1; - //uint8_t t_max = presets.midi.globals.store.global.setLists[n].settings[0]; - BMCScroller scroller(0, t_max); - set(scroller.scroll(t_amount, t_direction, t_wrap, setList, 0, t_max), firstSong); - } - void scrollSong(bool t_direction, bool t_wrap, uint8_t t_amount){ - uint8_t len = presets.midi.globals.store.global.setLists[setList].settings[0]; + void scrollSet(bool t_direction, bool t_wrap, uint8_t t_amount, uint8_t t_min, uint8_t t_max){ + // if(!presets.midi.globals.onBoardEditorActive()){ + // if(presets.midi.globals.settings.getDisplayListMode() && !presets.midi.globals.displayListsActive()){ + // presets.midi.globals.setRenderDisplayList(BMC_DEVICE_ID_SETLIST); + // return; + // } + // } + if(presets.midi.globals.setRenderDisplayList(BMC_DEVICE_ID_SETLIST)){ + return; + } + if(t_min > t_max){ + uint8_t t_min2 = t_min; + t_min = t_max; + t_max = t_min2; + } else if(t_min == t_max){ + t_min = 0; + t_max = BMC_MAX_SETLISTS-1; + } + if(t_max > BMC_MAX_SETLISTS-1){ + t_max = BMC_MAX_SETLISTS-1; + } + if(t_min > BMC_MAX_SETLISTS-1){ + t_min = 0; + } + BMCScroller scroller(t_min, t_max); + set(scroller.scroll(t_amount, t_direction, t_wrap, setList, t_min, t_max)); + } + void scrollSong(bool t_direction, bool t_wrap, uint8_t t_amount, uint8_t t_min, uint8_t t_max){ + // if(!presets.midi.globals.onBoardEditorActive()){ + // if(presets.midi.globals.settings.getDisplayListMode() && !presets.midi.globals.displayListsActive()){ + // presets.midi.globals.setRenderDisplayList(BMC_DEVICE_ID_SETLIST_SONG); + // return; + // } + // } + if(presets.midi.globals.setRenderDisplayList(BMC_DEVICE_ID_SETLIST_SONG)){ + return; + } + if(t_min > t_max){ + uint8_t t_min2 = t_min; + t_min = t_max; + t_max = t_min2; + } else if(t_min == t_max){ + t_min = 0; + t_max = BMC_MAX_SETLISTS_SONGS-1; + } + if(t_max > BMC_MAX_SETLISTS_SONGS-1){ + t_max = BMC_MAX_SETLISTS_SONGS-1; + } + if(t_min > BMC_MAX_SETLISTS_SONGS-1){ + t_min = 0; + } - if(len > 1){ - //uint8_t t_max = BMC_MAX_SETLISTS_SONGS-1; - uint8_t t_max = presets.midi.globals.store.global.setLists[setList].settings[0]-1; - BMCScroller scroller(0, t_max); - setSong(scroller.scroll(t_amount, t_direction, t_wrap, song, 0, t_max)); + BMCScroller scroller(t_min, t_max); + setSong(scroller.scroll(t_amount, t_direction, t_wrap, song, t_min, t_max)); + } + void scrollPart(bool t_direction, bool t_wrap, uint8_t t_amount, uint8_t t_min, uint8_t t_max){ + if(t_min > t_max){ + uint8_t t_min2 = t_min; + t_min = t_max; + t_max = t_min2; + } else if(t_min == t_max){ + t_min = 0; + t_max = BMC_MAX_SETLISTS_SONG_PARTS-1; } - } - void scrollPart(bool t_direction, bool t_wrap, uint8_t t_amount){ - //uint8_t t_max = BMC_MAX_SETLISTS_SONG_PARTS-1; - uint8_t t_max = presets.midi.globals.store.global.songLibrary[songInLibrary].settings[0]-1; - BMCScroller scroller(0, t_max); - setPart(scroller.scroll(t_amount, t_direction, t_wrap, song, 0, t_max)); + if(t_max > BMC_MAX_SETLISTS_SONG_PARTS-1){ + t_max = BMC_MAX_SETLISTS_SONG_PARTS-1; + } + if(t_min > BMC_MAX_SETLISTS_SONG_PARTS-1){ + t_min = 0; + } + BMCScroller scroller(t_min, t_max); + setPart(scroller.scroll(t_amount, t_direction, t_wrap, song, t_min, t_max)); } bool autoTriggerFirstSong(){ return presets.midi.globals.settings.getSetListTriggerFirstSong(); diff --git a/src/utility/BMC-Settings.h b/src/utility/BMC-Settings.h index 5991664..7178fc3 100644 --- a/src/utility/BMC-Settings.h +++ b/src/utility/BMC-Settings.h @@ -65,6 +65,7 @@ bits 04-04 Trigger first song bits 05-05 Trigger first song part bits 06-09 Typer Channel + bits 10-12 DisplayListMode [3]: *Reserved for future updates* [4]: *Reserved for future updates* @@ -409,13 +410,13 @@ class BMCSettings { return bitRead(settings.data[2], 4); } void setSetListTriggerFirstSong(uint8_t value){ - bitWrite(settings.data[2], value, 4); + bitWrite(settings.data[2], 4, value); } uint8_t getSetListTriggerFirstSongPart(){ return bitRead(settings.data[2], 5); } void setSetListTriggerFirstSongPart(uint8_t value){ - bitWrite(settings.data[2], value, 5); + bitWrite(settings.data[2], 5, value); } uint8_t getTyperChannel(){ return (settings.data[2]>>6) & 0x0F; @@ -423,6 +424,13 @@ class BMCSettings { void setTyperChannel(uint8_t value){ BMC_WRITE_BITS(settings.data[2],value, 0x0F, 6); //0-3 } + uint8_t getDisplayListMode(){ + return (settings.data[2]>>12) & 0x07; + } + void setDisplayListMode(uint8_t value){ + BMC_WRITE_BITS(settings.data[2],value, 0x07, 12); //0-3 + } + // tft touch calibration float getTouchTftCalibration(uint8_t n){ #ifdef BMC_HAS_TOUCH_SCREEN diff --git a/src/utility/BMC-Structs.h b/src/utility/BMC-Structs.h index e818b1f..6241194 100644 --- a/src/utility/BMC-Structs.h +++ b/src/utility/BMC-Structs.h @@ -37,19 +37,152 @@ struct __attribute__ ((packed)) BMCDeviceData { uint8_t settings = 0; uint8_t events = 0; }; -struct __attribute__ ((packed)) BMCEventData { - uint8_t type = BMC_NONE; - char label[35] = ""; - bool available = false; - bool scroll = false; - bool ports = false; - uint8_t fields = 0; -}; + +// struct __attribute__ ((packed)) BMCEventData { +// uint8_t type = BMC_NONE; +// char label[35] = ""; +// bool available = false; +// bool scroll = false; +// bool ports = false; +// uint8_t fields = 0; +// }; struct bmcXY { int16_t x = 0; int16_t y = 0; }; +struct BMCEventScrollData { + bool enabled = false; + bool direction = false; + bool wrap = true; + uint8_t amount = 1; + void set(uint8_t settings, uint8_t ticks, bool forceEnable=false){ + enabled = bitRead(settings, 0); + direction = bitRead(settings, 1); + wrap = bitRead(settings, 2); + if(forceEnable){ + if(!enabled){ + wrap = true; + } + enabled = true; + } + if(ticks > 0 || forceEnable){ + direction = bitRead(ticks, 7); + } + amount = ticks & 0x7F; + if(amount == 0){ + amount = 1; + } + } + // BMCEventScrollData(uint8_t settings, uint8_t ticks, bool forceEnable=false){ + // enabled = bitRead(settings, 0); + // direction = bitRead(settings, 1); + // wrap = bitRead(settings, 2); + // if(forceEnable){ + // if(!enabled){ + // wrap = true; + // } + // enabled = true; + // } + // if(ticks > 0){ + // direction = bitRead(ticks, 7); + // } + // amount = ticks & 0x7F; + // if(amount==0){ + // amount = 1; + // } + // } +}; +struct __attribute__ ((packed)) BMCDataContainer { + uint8_t index = 0; + uint8_t crc = 0; + uint8_t settings = 0; + uint8_t type = 0; + uint8_t byteA = 0; + uint8_t byteB = 0; + uint8_t byteC = 0; + uint8_t byteD = 0; + uint8_t value = 0; + uint16_t min = 0; + uint16_t max = 0; + + bool highlight = false; + bool oled = false; + bool useOffset = true; + bool noScroll = false; + bool offset = 0; + + char str[32] = ""; + char label[32] = ""; + BMCEventScrollData scroll; + uint16_t setMinMax(uint16_t t_currentValue, uint16_t t_min, uint16_t t_max, uint16_t t_min2, uint16_t t_max2){ + min = t_min; + max = t_max; + uint16_t outVal = t_min2; + if(t_max2 > 0){ + // scrolling max or toggle enabled + min = t_min2; + max = t_max2-1; + if(min > max){ + max = t_min2; + min = t_max2-1; + } else if(min == max){ + min = t_min; + max = t_max-1; + } + if(!scroll.enabled){ + outVal = t_currentValue != min ? min : max; + } + } + if(noScroll){ + outVal = scroll.direction ? max : min; + scroll.enabled = false; + } + return outVal; + } + void setNoScroll(bool t_value){ + noScroll = t_value; + } + uint8_t getChannel(){ + return BMC_TO_MIDI_CHANNEL(byteA); + } + bool showLabel(){ + return bitRead(settings, 0); + } + bool showBorder(){ + return bitRead(settings, 1); + } + bool useSelected(){ + return bitRead(settings, 2); + } + bool useName(){ + return bitRead(settings, 3); + } + bool useMeter(bool additionalCheck=true){ + return bitRead(settings, 4) && additionalCheck; + } + bool useOnOffSwitch(){ + return bitRead(settings, 4) && bitRead(settings, 5); + } + void setScroll(uint8_t t_settings, uint8_t t_ticks, bool t_forceEnable=false){ + scroll.set(t_settings, t_ticks, t_forceEnable); + } + bool scrollEnabled(){ + return scroll.enabled; + } + bool scrollDirection(){ + return scroll.direction; + } + bool scrollWrap(){ + return scroll.wrap; + } + bool scrollAmount(){ + return scroll.amount; + } +}; + + + #if defined(BMC_HAS_TOUCH_SCREEN) struct bmcTouchArea { int16_t x = 0; @@ -151,30 +284,7 @@ struct BMCLinkData { uint8_t index4 = 0; }; -struct BMCEventScrollData { - bool enabled = false; - bool direction = false; - bool endless = true; - uint8_t amount = 1; - BMCEventScrollData(uint8_t settings, uint8_t ticks, bool forceEnable=false){ - enabled = bitRead(settings, 0); - direction = bitRead(settings, 1); - endless = bitRead(settings, 2); - if(forceEnable){ - enabled = true; - } - if(ticks > 0){ - direction = bitRead(ticks, 7); - } - if(!enabled){ - endless = true; - } - amount = ticks & 0x7F; - if(amount==0){ - amount = 1; - } - } -}; + template struct BMCBitStates { uint16_t value[((len >> 4) & 0x0F)+1]; diff --git a/src/utility/BMC-Tools.h b/src/utility/BMC-Tools.h index 1249d7c..4178e06 100644 --- a/src/utility/BMC-Tools.h +++ b/src/utility/BMC-Tools.h @@ -413,6 +413,7 @@ class BMCTools { strcpy(str, buff); } } + static void getBankLetter(uint8_t n, char* buff){ strcpy(buff, ""); if(n < 32){ @@ -427,6 +428,55 @@ class BMCTools { } return p; } + + static void formatKnobValue(BMCDataContainer d, uint16_t t_value, char * buff){ + if(d.type == BMC_EVENT_TYPE_BANK){ + char letter[3] = ""; + BMCTools::getBankLetter(t_value, letter); + sprintf(buff, "%s", letter); + } else if(d.type == BMC_EVENT_TYPE_PRESET && d.byteC == 1){ + char letter[3] = ""; + // all presets + BMCTools::getPresetLabelNoName(t_value, letter, d.offset); + sprintf(buff, "%s", letter); + } else { + sprintf(buff, "%u", t_value+(d.useOffset ? d.offset : 0)); + } + } + static void makePlural(char * buff){ + uint8_t strL = strlen(buff); + char lastChar = buff[strL-1]; + if(lastChar!='s' && lastChar!='x' && lastChar!='p'){ + buff[strL] = 's'; + } + } + + + + + static void getPresetLabelNoName(uint8_t t_bank, uint8_t t_preset, char * str, bool offset=false){ + uint16_t t_presetAndBank = toPresetIndex(t_bank, t_preset); + getPresetLabelNoName(t_presetAndBank, str, offset); + } + static void getPresetLabelNoName(uint16_t t_presetAndBank, char * str, bool offset=false){ + if(t_presetAndBank < BMC_MAX_PRESETS){ +#if BMC_MAX_PRESETS > 0 + char bankStr[2] = ""; + getBankLetter(getBankFromPresetIndex(t_presetAndBank), bankStr); + sprintf(str, "%s%u", bankStr, getPresetInBankFromPresetIndex(t_presetAndBank)+offset); +#endif + } + } + static uint8_t getBankFromPresetIndex(uint16_t t_presetAndBank){ + return ((t_presetAndBank >> BMC_PRESET_BANK_MASK) & 0x1F); + + } + static uint8_t getPresetInBankFromPresetIndex(uint16_t t_presetAndBank){ + return (t_presetAndBank & (BMC_MAX_PRESETS_PER_BANK-1)); + } + + + static void getPresetLabel(uint8_t t_bank, uint8_t t_preset, char * str, bmcStoreGlobal& t_store){ uint16_t t_presetAndBank = toPresetIndex(t_bank, t_preset); if(t_presetAndBank < BMC_MAX_PRESETS){