I can post the three files concerned by the problem:
main.cpp
// BB LIBRARY
#include <globals.h>
#include <assetsBmps.h>
#include <modesHelper.h>
#include <formulaHelper.h>
#include <sdHelper.h>
#include <visualizerHelper.h>
#include <interfaceHelper.h>
#include <displayHelper.h>
// #include <samplerHelper.h>
#include <midiHelper.h>
// LIBRARIES
#include <TimerTC3.h>
#define USE_TIMER_TC3 // use TimerTc3
#define TIMER_TIME 125 // 1/8000 Hz = 125 micro seconds
#define TIMER TimerTc3
#define DAC_PIN 0 // pin of the XIAO DAC
// TIMERS && INTERRUPTS
void GenerateAudioStream();
void setup()
{
beginDebug();
debugln(F("Set up starting"));
// sd::configure();
// sd::importFormulas(formula::savedFormulas);
interface::configure();
display::configure();
midi::configure();
pinMode(DAC_PIN, OUTPUT);
TIMER.initialize(TIMER_TIME);
TIMER.attachInterrupt(GenerateAudioStream);
debugln(F("Set up completed"));
}
void loop()
{
interface::checkButtons();
midi::readMidi();
formula::compileFormula();
display::updateDisplay();
// static int i = 0;
// if (i++ == 150)
// interface::doubleClickFunc();
}
void GenerateAudioStream()
{
if (formula::compileFlag)
{
static int prescaler = 0;
static int prescalerCounter = 0;
if (++prescalerCounter < prescaler)
{
return;
}
prescalerCounter = 0;
formula::byteBeatResult = te_eval((te_expr *)formula::expr);
if (formula::resultResolution == 0)
{
analogWrite(DAC_PIN, (uint8_t)formula::byteBeatResult);
}
else if (formula::resultResolution == 1)
{
analogWrite(DAC_PIN, (uint16_t)formula::byteBeatResult);
}
else if (formula::resultResolution == 2)
{
analogWrite(DAC_PIN, (uint32_t)formula::byteBeatResult);
}
else
{
}
}
else
{
analogWrite(DAC_PIN, 0);
}
if (formula::modeT)
{
formula::t += formula::tIncrement;
}
else
{
formula::t -= formula::tIncrement;
}
}
displayHelper.h
#ifndef DISPLAY_HELPER_H
#define DISPLAY_HELPER_H
#define I2C_ADDRESS 0x3c
namespace display
{
Adafruit_SH1106G display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void configure();
void displayCursor(int);
void displaySettings(int);
void displayMenuState(int);
void displayCompileFlagState(bool);
void displaySavedFormulas();
void displayCurrentFile();
void displayLiveMode();
void updateDisplay();
void configure()
{
display.setTextSize(1); // Normal 1:1 pixel scale
display.setTextColor(SH110X_WHITE); // Draw white text
// display.cp437(true);
display.begin(I2C_ADDRESS);
// if (!display.begin(I2C_ADDRESS, 0x3C))
// { // Address 0x3C for 128x64
// Serial.println(F("SSD1306 allocation failed"));
// for (;;)
// ; // Don't proceed, loop forever
// }
display.clearDisplay();
display.display();
}
void displaySavedFormulas()
{
display.drawBitmap(0, 0, assetsBmp::FORMULAS_BMP, 128, 64, SH110X_WHITE);
int cursorX = 44;
int cursorY = 12;
display.setCursor(cursorX, cursorY);
display.setTextWrap(0);
int page = interface::savedFormulasIndex / 6;
for (int i = 0; i < 6; i++)
{
byte index = i + (page * 6);
char buffer[4];
snprintf(buffer, sizeof(buffer), "%02d", index + 1);
if (index == interface::savedFormulasIndex)
{
display.fillRect(cursorX - 1, cursorY - 1, (CHAR_WIDTH * 2) + 1, CHAR_HEIGHT + 1, SH110X_WHITE);
display.setTextColor(SH110X_BLACK);
}
display.print(buffer);
if (index == interface::savedFormulasIndex)
{
display.setTextColor(SH110X_WHITE);
}
display.print(" ");
display.print(formula::savedFormulas[index]);
cursorY += CHAR_HEIGHT;
display.setCursor(cursorX, cursorY);
}
display.setTextWrap(1);
}
void displaySettings(int settingsCursorState)
{
display.drawBitmap(0, 0, assetsBmp::SETTINGS_BMP, 128, 64, SH110X_WHITE);
if (settingsCursorState == 0)
{
display.drawBitmap(48, 16, assetsBmp::SETTINGS_CURSOR_SELECTED_BMP, 10, 10, SH110X_WHITE);
}
else if (settingsCursorState == 1)
{
display.drawBitmap(48, 43, assetsBmp::SETTINGS_CURSOR_SELECTED_BMP, 10, 10, SH110X_WHITE);
}
display.drawBitmap(56, 50, assetsBmp::SETTINGS_WAVEFORM_SINE_NO_SELECTED, 15, 10, SH110X_WHITE);
display.drawBitmap(96, 50, assetsBmp::SETTINGS_WAVEFORM_SQR_NO_SELECTED, 15, 10, SH110X_WHITE);
}
void displayExprMode()
{
display.setCursor(34, 1);
display.setTextColor(SH110X_BLACK);
if (interface::exprModeIndex == interface::SYMBOLS)
{
display.print(F("+-x"));
}
else if (interface::exprModeIndex == interface::NUMBERS)
{
display.print(F("123"));
}
else if (interface::exprModeIndex == interface::FUNCTIONS)
{
display.drawTriangle(34, 6, 34, 1, 40, 6, SH110X_BLACK);
}
display.setTextColor(SH110X_WHITE);
}
void displayLiveMode()
{
display.setCursor(58, 1);
display.setTextColor(SH110X_BLACK);
if (formula::liveMode)
{
display.print(F("live"));
}
else
{
display.print(F("hold"));
}
display.setTextColor(SH110X_WHITE);
}
void displayCompileFlagState(bool compileFlag)
{
if (compileFlag == 1)
{
display.drawBitmap(114, 1, assetsBmp::YES_COMPILE_BMP, 7, 7, SH110X_WHITE);
}
else
{
display.drawBitmap(114, 1, assetsBmp::NO_COMPILE_BMP, 7, 7, SH110X_WHITE);
}
}
void displayMenuState(int symbolsState)
{
display.setTextColor(SH110X_BLACK);
display.setCursor(50, 2);
if (symbolsState == 0)
{
display.print(F("+ - x"));
}
else if (symbolsState == 1)
{
display.print(F("1 2 3"));
}
else
{
display.drawTriangle(50, 6, 64, 6, 50, 1, SH110X_BLACK);
}
display.setTextColor(SH110X_WHITE);
}
void displayCursor(int indexFormula)
{
int underlineY = indexFormula / LINE_CHAR_WIDTH;
int underlineX = indexFormula;
for (int i = 0; i < underlineY; i++)
{
underlineX = underlineX - LINE_CHAR_WIDTH;
}
underlineX = underlineX * CHAR_WIDTH;
underlineY = (((underlineY + 1) * CHAR_HEIGHT) + (CHAR_HEIGHT + 2)) - 1;
display.drawFastHLine(underlineX, underlineY, CHAR_WIDTH, 1);
}
void displayPreview()
{
display.setCursor(7 * CHAR_WIDTH, 0);
display.print("PREVIEW");
display.setCursor(0, 8);
display.print(formula::savedFormulas[interface::savedFormulasIndex]);
}
void displayStatusBar()
{
displayCurrentFile();
displayExprMode();
displayLiveMode();
}
void displayCurrentFile()
{
char buffer[4];
snprintf(buffer, sizeof(buffer), "%03d", interface::currentFileIndex);
display.setCursor(8, 0);
display.print(buffer);
}
void displayChaosMode()
{
int x = display.getCursorX();
int y = display.getCursorY();
if (modes::bytebeatMode == modes::bytebeat_modes::CHAOS)
{
display.setCursor(87, 1);
display.setTextColor(SH110X_BLACK);
display.print("666");
display.setTextColor(SH110X_WHITE);
}
display.setCursor(x, y);
}
void displayEditor(int prevY)
{
display.drawBitmap(0, 0, assetsBmp::STATUSBAR_BMP, 128, 9, SH110X_WHITE);
displayStatusBar();
displayChaosMode();
displayCompileFlagState(formula::compileFlag);
displayCursor(interface::indexFormula);
display.setCursor(0, 10);
display.print((const char *)formula::formula);
display.setCursor(interface::indexFormula * CHAR_WIDTH, prevY);
}
bool needClear()
{
return !(modes::bytebeatMode == modes::VISUALIZER) && !(modes::bytebeatMode == modes::POPUP);
}
void updateDisplay()
{
if (interface::needDisplay)
{
if (!(modes::bytebeatMode == modes::VISUALIZER) && !(modes::bytebeatMode == modes::POPUP))
{
display.clearDisplay();
}
switch (modes::bytebeatMode)
{
case modes::bytebeat_modes::CHAOS:
case modes::bytebeat_modes::EDITOR:
{
int prevY = display.getCursorY();
display.clearDisplay();
display.setCursor(0, 0);
displayEditor(prevY);
break;
}
case modes::bytebeat_modes::VISUALIZER:
{
visualizer::displayVisualizer(display);
break;
}
case modes::bytebeat_modes::POPUP:
{
display.drawBitmap(24, 24, assetsBmp::SAVE_POPUP_BMP, 81, 35, SH110X_WHITE);
break;
}
case modes::bytebeat_modes::CONFIG:
{
if (interface::tabMenuState == 0)
{
if (interface::funcState == 1)
{
displayPreview();
}
else
{
displaySavedFormulas();
}
}
else if (interface::tabMenuState == 999)
{
displaySettings(interface::settingsIndex);
}
break;
}
default:
{
break;
}
}
display.display();
interface::needDisplay = 0;
}
}
}
#endif
interfaceHelper.h
#ifndef INTERFACE_HELPER_H
#define INTERFACE_HELPER_H
using namespace ace_button;
// Boutton function séparé pour permettre la combinaison de touches
AceButton button(PIN_DIGITAL_2);
// bouttons regroupés sur la pin analogue 1
static const uint8_t NUM_BUTTONS = 7;
static AceButton b0(nullptr, 0);
static AceButton b1(nullptr, 1);
static AceButton b2(nullptr, 2);
static AceButton b3(nullptr, 3);
static AceButton b4(nullptr, 4);
static AceButton b5(nullptr, 5);
static AceButton b6(nullptr, 6);
static AceButton *const BUTTONS[NUM_BUTTONS] = {
&b0, &b1, &b2, &b3, &b4, &b5, &b6};
// Define the ADC voltage levels for each button.
// For 4 buttons, we need 5 levels.
static const uint8_t NUM_LEVELS = NUM_BUTTONS + 1;
static const uint16_t LEVELS[NUM_LEVELS] = {
0,
130,
250,
370,
460,
530,
620,
1023};
// The LadderButtonConfig constructor binds the AceButton to the
// LadderButtonConfig.
static LadderButtonConfig buttonsConfig(
PIN_ANALOG_1, NUM_LEVELS, LEVELS, NUM_BUTTONS, BUTTONS);
namespace interface
{
const static int SYMBOLS = 0;
const static int NUMBERS = 1;
const static int FUNCTIONS = 2;
const int EXPR_MODES_SIZE = 3;
const int exprModes[EXPR_MODES_SIZE] = {SYMBOLS, NUMBERS, FUNCTIONS};
int exprModeIndex = 0;
modes::bytebeat_modes previousSamplerMode = modes::bytebeatMode;
int cursorMenuState = 0;
int tabMenuState = 0;
int indexFormula = 0;
int currentFileIndex = 0;
int settingsIndex = 0;
int savedFormulasIndex = 0;
bool funcState = 0;
const int NUMBER_ARRAY_SIZE = 10;
const char numberArray[NUMBER_ARRAY_SIZE] PROGMEM = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
int numberArrayIndex = 0;
const int PSI_ARRAY_SIZE = 11;
const char psiArray[PSI_ARRAY_SIZE] PROGMEM = {'%', '^', '&', '|', '>', '<', '!', '/', '+', '-', '*'};
int psiArrayIndex = 0;
// TODO rajouter la PROGMEM pour ce tableau aussi
const int TRIGO_ARRAY_SIZE = 3;
const char *trigoArray[TRIGO_ARRAY_SIZE] = {"sin(", "cos(", "tan("};
int trigoArrayIndex = 0;
bool needDisplay = 1;
void configure();
void pressedFunc();
void handleEventButton(AceButton *, uint8_t, uint8_t);
void pressedDown();
void pressedUp();
void pressedLeft();
void pressedRight();
void pressedMenu();
void pressedYes();
void pressedNo();
void repeatPressLeft();
void repeatPressRight();
void longPressNo();
void checkButtons();
void handleEventButtons(AceButton *, uint8_t, uint8_t);
bool isBeforeAFunc(const char *, int);
bool isAfterAFunc(const char *, int);
void eraseNextFourChar(volatile char *, int);
void configure()
{
pinMode(PIN_ANALOG_1, INPUT);
pinMode(PIN_DIGITAL_2, INPUT_PULLUP);
modes::setBytebeatMode(modes::EDITOR);
ButtonConfig *buttonConfig = button.getButtonConfig();
buttonConfig->setEventHandler(handleEventButton);
buttonConfig->setFeature(ButtonConfig::kFeatureDoubleClick);
// Configure the ButtonConfig with the event handler, and enable all higher
// level events.
buttonsConfig.setEventHandler(handleEventButtons);
buttonsConfig.setFeature(ButtonConfig::kFeatureClick);
buttonsConfig.setFeature(ButtonConfig::kFeatureLongPress);
buttonsConfig.setFeature(ButtonConfig::kFeatureRepeatPress);
}
void pressedFunc()
{
funcState = 1;
return;
}
void releaseFunc()
{
funcState = 0;
return;
}
void doubleClickFunc()
{
needDisplay = 1;
if (modes::bytebeatMode != modes::VISUALIZER)
{
modes::setBytebeatMode(modes::VISUALIZER);
}
else
{
interface::needDisplay = 1;
modes::setBytebeatMode(modes::EDITOR);
}
}
void handleEventButton(AceButton *button, uint8_t eventType, uint8_t buttonState)
{
switch (eventType)
{
case AceButton::kEventPressed:
pressedFunc();
break;
case AceButton::kEventReleased:
releaseFunc();
break;
case AceButton::kEventDoubleClicked:
doubleClickFunc();
break;
}
}
// The buttonConfig.checkButtons() should be called every 4-5ms or faster, if
// the debouncing time is ~20ms. On ESP8266, analogRead() must be called *no*
// faster than 4-5ms to avoid a bug which disconnects the WiFi connection.
void checkButtons()
{
static unsigned long prev = millis();
unsigned long now = millis();
if (now - prev > 4)
{
button.check();
buttonsConfig.checkButtons();
prev = now;
}
}
void pressedLeft()
{
switch (modes::bytebeatMode)
{
case modes::EDITOR:
{
if (funcState)
{
formula::insertAt("(", indexFormula);
return;
}
if (indexFormula != 0 && isAfterAFunc((const char *)formula::formula, indexFormula))
{
indexFormula -= 4;
}
else if (--indexFormula < 0)
{
indexFormula = 0;
}
return;
}
case modes::CHAOS:
{
for (int i = 0; i < formula::FORMULA_SIZE; i++)
{
for (int j = 0; j < PSI_ARRAY_SIZE; j++)
{
bool isNotForbiddenSymbol = formula::formula[i] != '(' && formula::formula[i] != ')' && formula::formula[i] != 't';
if (formula::formula[i] == pgm_read_byte(psiArray + j) && isNotForbiddenSymbol)
{
int index = j;
if (index <= 0)
{
index = PSI_ARRAY_SIZE - 1;
}
if (pgm_read_byte(psiArray + (index - 1)) == 't')
{
index = PSI_ARRAY_SIZE - 1;
}
else
{
index -= 1;
}
formula::formula[i] = pgm_read_word_near(psiArray + index);
break;
}
}
}
return;
}
// case modes::CONFIG:
// {
// if (--tabMenuState < 0)
// {
// tabMenuState = 0;
// }
// return;
// }
// case modes::READING:
// {
// if (funcState)
// {
// sampler::agrandirByRight(8);
// }
// else
// {
// sampler::trimByRight(8);
// }
// return;
// }
default:
return;
}
}
void repeatPressLeft()
{
switch (modes::bytebeatMode)
{
case modes::EDITOR:
{
if (indexFormula != 0 && isAfterAFunc((const char *)formula::formula, indexFormula))
{
indexFormula -= 4;
}
else if (--indexFormula < 0)
{
indexFormula = 0;
}
break;
}
// case modes::READING:
// {
// if (funcState)
// {
// sampler::agrandirByRight(8);
// }
// else
// {
// sampler::trimByRight(8);
// }
// return;
// }
default:
return;
}
}
void pressedRight()
{
switch (modes::bytebeatMode)
{
case modes::EDITOR:
{
if (funcState)
{
formula::insertAt(")", indexFormula);
return;
}
if (indexFormula != formula::FORMULA_SIZE - 3 && isBeforeAFunc((const char *)formula::formula, indexFormula))
{
indexFormula += 4;
}
else if (++indexFormula >= formula::FORMULA_SIZE - 1)
{
indexFormula = formula::FORMULA_SIZE - 1;
}
return;
}
case modes::CHAOS:
{
for (int i = 0; i < formula::FORMULA_SIZE; i++)
{
for (int j = 0; j < PSI_ARRAY_SIZE; j++)
{
bool isNotForbiddenSymbol = formula::formula[i] != '(' && formula::formula[i] != ')' && formula::formula[i] != 't';
if (formula::formula[i] == pgm_read_byte(psiArray + j) && isNotForbiddenSymbol)
{
int index = j;
if (index >= PSI_ARRAY_SIZE - 1)
{
index = 0;
}
if (pgm_read_byte(psiArray + (index + 1)) == 't')
{
index += 2;
}
else
{
index += 1;
}
formula::formula[i] = pgm_read_byte(psiArray + index);
break;
}
}
}
return;
}
// case modes::CONFIG:
// {
// if (++tabMenuState > 1)
// {
// tabMenuState = 1;
// }
// return;
// }
// case modes::READING:
// {
// if (funcState)
// {
// agrandirByLeft(8);
// }
// else
// {
// trimByLeft(8);
// }
// return;
// }
default:
return;
}
}
void repeatPressRight()
{
switch (modes::bytebeatMode)
{
case modes::EDITOR:
{
if (indexFormula != formula::FORMULA_SIZE - 3 && isBeforeAFunc((const char *)formula::formula, indexFormula))
{
indexFormula += 4;
}
else if (++indexFormula >= formula::FORMULA_SIZE - 1)
{
indexFormula = formula::FORMULA_SIZE - 1;
}
return;
}
// case modes::READING:
// {
// if (funcState)
// {
// agrandirByLeft(8);
// }
// else
// {
// trimByLeft(8);
// }
// return;
// }
default:
return;
}
}
void pressedDown()
{
switch (modes::bytebeatMode)
{
case modes::EDITOR:
{
if (funcState)
{
formula::insertAt(" ", indexFormula);
return;
}
switch (exprModes[exprModeIndex])
{
case SYMBOLS:
if (--psiArrayIndex < 0)
{
psiArrayIndex = PSI_ARRAY_SIZE - 1;
}
if (isBeforeAFunc((const char *)formula::formula, indexFormula))
{
eraseNextFourChar(formula::formula, indexFormula);
if (--indexFormula < 0)
indexFormula = 0;
}
formula::formula[indexFormula] = pgm_read_word_near(psiArray + psiArrayIndex);
break;
case NUMBERS:
if (--numberArrayIndex < 0)
{
numberArrayIndex = NUMBER_ARRAY_SIZE - 1;
}
if (indexFormula != 0 && isBeforeAFunc((const char *)formula::formula, indexFormula))
{
eraseNextFourChar(formula::formula, indexFormula);
if (--indexFormula < 0)
indexFormula = 0;
}
formula::formula[indexFormula] = pgm_read_word_near(numberArray + numberArrayIndex);
break;
case FUNCTIONS:
if (--trigoArrayIndex < 0)
{
trigoArrayIndex = TRIGO_ARRAY_SIZE - 1;
}
const char *insert = trigoArray[trigoArrayIndex];
if (isBeforeAFunc((const char *)formula::formula, indexFormula))
{
formula::formula[indexFormula] = insert[0];
formula::formula[indexFormula + 1] = insert[1];
formula::formula[indexFormula + 2] = insert[2];
formula::formula[indexFormula + 3] = insert[3];
}
else
{
if (indexFormula < formula::FORMULA_SIZE - 4)
{
formula::insertAt(insert, indexFormula);
}
}
break;
}
return;
}
case modes::CHAOS:
{
for (int i = 0; i < formula::FORMULA_SIZE; i++)
{
for (int j = 0; j < NUMBER_ARRAY_SIZE; j++)
{
bool isNotForbiddenSymbol = formula::formula[i] != ' ';
if (formula::formula[i] == pgm_read_byte(numberArray + j) && isNotForbiddenSymbol)
{
int index = j;
if (index <= 0)
{
index = NUMBER_ARRAY_SIZE - 1;
}
else
{
index -= 1;
}
formula::formula[i] = pgm_read_byte(numberArray + index);
break;
}
}
}
return;
}
case modes::VISUALIZER:
{
visualizer::incrementVisualizersIndex();
return;
}
case modes::CONFIG:
{
if (tabMenuState == 1)
{
if (++settingsIndex > 1)
{
settingsIndex = 1;
// bbConfig.setPrescaler(4);
}
// bbConfig.setPrescaler(prescaler);
// bbConfig.configSave();
}
else if (tabMenuState == 0)
{
++savedFormulasIndex;
}
return;
}
default:
return;
}
}
void pressedUp()
{
switch (modes::bytebeatMode)
{
case modes::EDITOR:
{
if (funcState)
{
formula::insertAt("t", indexFormula);
return;
}
switch (exprModes[exprModeIndex])
{
case SYMBOLS:
if (++psiArrayIndex > PSI_ARRAY_SIZE - 1)
{
psiArrayIndex = 0;
}
if (indexFormula != 0 && isBeforeAFunc((const char *)formula::formula, indexFormula))
{
eraseNextFourChar(formula::formula, indexFormula);
}
formula::formula[indexFormula] = pgm_read_word_near(psiArray + psiArrayIndex);
break;
case NUMBERS:
if (++numberArrayIndex > NUMBER_ARRAY_SIZE - 1)
{
numberArrayIndex = 0;
}
if (indexFormula != 0 && isBeforeAFunc((const char *)formula::formula, indexFormula))
{
eraseNextFourChar(formula::formula, indexFormula);
}
formula::formula[indexFormula] = pgm_read_word_near(numberArray + numberArrayIndex);
break;
case FUNCTIONS:
if (++trigoArrayIndex > TRIGO_ARRAY_SIZE - 1)
{
trigoArrayIndex = 0;
}
const char *insert = trigoArray[trigoArrayIndex];
if (isBeforeAFunc((const char *)formula::formula, indexFormula))
{
formula::formula[indexFormula] = insert[0];
formula::formula[indexFormula + 1] = insert[1];
formula::formula[indexFormula + 2] = insert[2];
formula::formula[indexFormula + 3] = insert[3];
}
else
{
if (indexFormula < formula::FORMULA_SIZE - 4)
{
formula::insertAt(insert, indexFormula);
}
}
break;
}
return;
}
case modes::CHAOS:
{
for (int i = 0; i < formula::FORMULA_SIZE; i++)
{
for (int j = 0; j < NUMBER_ARRAY_SIZE; j++)
{
bool isNotForbiddenSymbol = formula::formula[i] != ' ';
if (formula::formula[i] == pgm_read_byte(numberArray + j) && isNotForbiddenSymbol)
{
int index = j;
if (index >= NUMBER_ARRAY_SIZE - 1)
{
index = 0;
}
else
{
index += 1;
}
formula::formula[i] = pgm_read_byte(numberArray + index);
break;
}
}
}
return;
}
case modes::VISUALIZER:
{
visualizer::decrementVisualizersIndex();
return;
}
case modes::CONFIG:
{
if (tabMenuState == 1)
{
if (--settingsIndex < 0)
{
settingsIndex = 0;
}
// bbConfig.setPrescaler(prescaler);
// bbConfig.configSave();
}
else if (tabMenuState == 0)
{
if (--savedFormulasIndex < 0)
savedFormulasIndex = 5;
}
return;
}
default:
return;
}
}
void pressedMenu()
{
switch (modes::bytebeatMode)
{
case modes::CHAOS:
case modes::EDITOR:
{
if (funcState)
{
formula::compileFlag = 0;
strcpy(formula::holdedFormula, (const char *)formula::formula);
formula::compileFlag = 1;
formula::liveMode = !(formula::liveMode);
// modes::setBytebeatMode(modes::SAMPLING;
}
else
{
modes::setBytebeatMode(modes::CONFIG);
}
return;
}
case modes::CONFIG:
{
modes::setBytebeatMode(modes::EDITOR);
return;
}
case modes::SAMPLING:
{
modes::setBytebeatMode(modes::SAMPLED);
return;
}
case modes::READING:
{
modes::setBytebeatMode(modes::SAMPLING);
return;
}
default:
return;
}
}
void pressedYes()
{
switch (modes::bytebeatMode)
{
case modes::CHAOS:
case modes::EDITOR:
{
if (funcState)
{
modes::setBytebeatMode(modes::POPUP);
return;
}
if (++exprModeIndex >= EXPR_MODES_SIZE)
{
exprModeIndex = 0;
}
return;
}
case modes::POPUP:
{
if (!funcState)
{
if (currentFileIndex > 6)
{
// sd::saveFormula(currentFileIndex);
}
modes::setBytebeatMode(modes::EDITOR);
}
return;
}
case modes::CONFIG:
{
if (tabMenuState == 0)
{
strncpy((char *)formula::formula, formula::savedFormulas[savedFormulasIndex], formula::FORMULA_SIZE - 1);
currentFileIndex = savedFormulasIndex + 1;
modes::setBytebeatMode(modes::EDITOR);
}
return;
}
default:
return;
}
}
void pressedNo()
{
switch (modes::bytebeatMode)
{
case modes::EDITOR:
{
if (funcState)
{
modes::setBytebeatMode(modes::CHAOS);
return;
}
if (indexFormula != 0 && isBeforeAFunc((const char *)formula::formula, indexFormula))
{
eraseNextFourChar(formula::formula, indexFormula);
if (isAfterAFunc((const char *)formula::formula, indexFormula))
{
indexFormula -= 4;
}
else
{
--(indexFormula);
}
}
else if (indexFormula == 0 && isBeforeAFunc((const char *)formula::formula, indexFormula))
{
eraseNextFourChar(formula::formula, indexFormula);
}
else
{
formula::formula[indexFormula] = ' ';
if (indexFormula > 0)
{
if (isAfterAFunc((const char *)formula::formula, indexFormula))
{
indexFormula -= 4;
}
else
{
--(indexFormula);
}
}
}
return;
}
case modes::CHAOS:
case modes::VISUALIZER:
case modes::CONFIG:
case modes::POPUP:
case modes::SAMPLING:
case modes::SAMPLED:
case modes::READING:
{
modes::setBytebeatMode(modes::EDITOR);
return;
}
default:
return;
}
}
void longPressedNo()
{
switch (modes::bytebeatMode)
{
case modes::EDITOR:
{
strncpy((char *)formula::formula, "", formula::FORMULA_SIZE);
indexFormula = 0;
}
default:
return;
}
}
bool isBeforeAFunc(const char *formula, int indexFormula)
{
bool isTrigo = formula[indexFormula] == 'c' || formula[indexFormula] == 's' || ((formula[indexFormula] == 't' && formula[indexFormula + 1] == 'a'));
return isTrigo;
}
bool isAfterAFunc(const char *formula, int indexFormula)
{
bool isTrigo = formula[indexFormula - 2] == 's' || formula[indexFormula - 2] == 'n';
return isTrigo;
}
void eraseNextFourChar(volatile char *formula, int indexFormula)
{
formula[indexFormula] = ' ';
formula[indexFormula + 1] = ' ';
formula[indexFormula + 2] = ' ';
formula[indexFormula + 3] = ' ';
}
void button0Handler(AceButton *button, uint8_t eventType, uint8_t buttonState)
{
switch (eventType)
{
case AceButton::kEventPressed:
pressedYes();
break;
case AceButton::kEventLongPressed:;
break;
}
}
void button1Handler(AceButton *button, uint8_t eventType, uint8_t buttonState)
{
switch (eventType)
{
case AceButton::kEventPressed:
pressedUp();
break;
case AceButton::kEventLongPressed:;
break;
}
}
void button2Handler(AceButton *button, uint8_t eventType, uint8_t buttonState)
{
switch (eventType)
{
case AceButton::kEventPressed:
pressedNo();
break;
case AceButton::kEventLongPressed:
longPressedNo();
break;
}
}
void button3Handler(AceButton *button, uint8_t eventType, uint8_t buttonState)
{
switch (eventType)
{
case AceButton::kEventPressed:
pressedLeft();
break;
case AceButton::kEventRepeatPressed:
repeatPressLeft();
break;
}
}
void button4Handler(AceButton *button, uint8_t eventType, uint8_t buttonState)
{
switch (eventType)
{
case AceButton::kEventPressed:
pressedDown();
break;
case AceButton::kEventLongPressed:;
break;
}
}
void button5Handler(AceButton *button, uint8_t eventType, uint8_t buttonState)
{
switch (eventType)
{
case AceButton::kEventPressed:
pressedRight();
break;
case AceButton::kEventRepeatPressed:
repeatPressRight();
break;
}
}
void button6Handler(AceButton *button, uint8_t eventType, uint8_t buttonState)
{
switch (eventType)
{
case AceButton::kEventPressed:
pressedMenu();
break;
case AceButton::kEventLongPressed:;
break;
}
}
// The event handler for the button.
void handleEventButtons(AceButton *button, uint8_t eventType, uint8_t buttonState)
{
needDisplay = 1;
switch (button->getPin())
{
case 0:
button0Handler(button, eventType, buttonState);
break;
case 1:
button1Handler(button, eventType, buttonState);
break;
case 2:
button2Handler(button, eventType, buttonState);
break;
case 3:
button3Handler(button, eventType, buttonState);
break;
case 4:
button4Handler(button, eventType, buttonState);
break;
case 5:
button5Handler(button, eventType, buttonState);
break;
case 6:
button6Handler(button, eventType, buttonState);
break;
}
}
}
#endif
The part that I'm talking about is the if l227-228 in displayHelper.h, the variable needDisplay is updated in interfaceHelper when a button is pressed