354 lines
8.7 KiB
C++
354 lines
8.7 KiB
C++
// DisplayHandler.cpp
|
|
#include "pico/stdlib.h"
|
|
#include "DisplayHandler.h"
|
|
#include "globals.h"
|
|
#include <string>
|
|
#include <cstdlib>
|
|
|
|
#include "hardware/i2c.h"
|
|
#include "pico-ssd1306/ssd1306.h"
|
|
#include "pico-ssd1306/shapeRenderer/ShapeRenderer.h"
|
|
#include "pico-ssd1306/textRenderer/TextRenderer.h"
|
|
|
|
|
|
pico_ssd1306::SSD1306* display = nullptr;
|
|
extern void update_BPM(bool up);
|
|
|
|
|
|
DisplayHandler::DisplayHandler(Gate* outputs[]) {
|
|
this->outputs = outputs;
|
|
currentScreen = 0;
|
|
currentOut = -1;
|
|
updateScreen = 1;
|
|
cursorPosition = 0;
|
|
mainMaxCursorPosition = 10;
|
|
outMaxCursorPosition = std::size(out_pages) - 1;
|
|
cursorClick = 0;
|
|
}
|
|
|
|
|
|
void DisplayHandler::setup() {
|
|
i2c_init(i2c1, 400 * 1000);
|
|
|
|
gpio_set_function(SCREEN_SDA_PIN, GPIO_FUNC_I2C);
|
|
gpio_set_function(SCREEN_SCL_PIN, GPIO_FUNC_I2C);
|
|
|
|
gpio_pull_up(SCREEN_SDA_PIN);
|
|
gpio_pull_up(SCREEN_SCL_PIN);
|
|
|
|
display = new pico_ssd1306::SSD1306(i2c1, 0x3C, pico_ssd1306::Size::W128xH64);
|
|
display->setOrientation(0);
|
|
}
|
|
|
|
|
|
void DisplayHandler::moveCursor(bool dir) {
|
|
if (onOutScreen) {
|
|
if (cursorClick == 0) {
|
|
if (dir == 1) {
|
|
cursorPosition++;
|
|
currentScreen++;
|
|
} else {
|
|
cursorPosition--;
|
|
currentScreen--;
|
|
}
|
|
|
|
if (cursorPosition > outMaxCursorPosition) {
|
|
cursorPosition = 0;
|
|
currentScreen = 0;
|
|
}
|
|
|
|
if (cursorPosition < 0) {
|
|
cursorPosition = outMaxCursorPosition;
|
|
currentScreen = outMaxCursorPosition;
|
|
}
|
|
} else { // click = 1
|
|
if (currentScreen == 1) { // mod screen
|
|
outputs[currentOut]->editing = 1;
|
|
if (dir == 1) {
|
|
outputs[currentOut]->modifierSelectionIndex++;
|
|
} else {
|
|
outputs[currentOut]->modifierSelectionIndex--;
|
|
}
|
|
|
|
if (outputs[currentOut]->modifierSelectionIndex < 0) {
|
|
outputs[currentOut]->modifierSelectionIndex = 0;
|
|
}
|
|
|
|
if (outputs[currentOut]->modifierSelectionIndex > std::size(MOD_TYPES) - 1) {
|
|
outputs[currentOut]->modifierSelectionIndex = std::size(MOD_TYPES) - 1;
|
|
}
|
|
|
|
} else if (currentScreen == 2) { // shape control
|
|
int currentShape = (int)outputs[currentOut]->shape;
|
|
|
|
if (dir == 1) {
|
|
currentShape++;
|
|
} else {
|
|
currentShape--;
|
|
}
|
|
|
|
if (currentShape >= SHAPE_COUNT) {
|
|
currentShape = 0;
|
|
}
|
|
|
|
if (currentShape < 0) {
|
|
currentShape = SHAPE_COUNT - 1;
|
|
}
|
|
|
|
outputs[currentOut]->shape = (WaveShape)currentShape;
|
|
outputs[currentOut]->writeAnalog(0);
|
|
|
|
} else if (currentScreen == 3) { // level control
|
|
outputs[currentOut]->editing = 1;
|
|
if (dir == 1) {
|
|
outputs[currentOut]->level++;
|
|
} else {
|
|
outputs[currentOut]->level--;
|
|
}
|
|
|
|
if (outputs[currentOut]->level > 100) {
|
|
outputs[currentOut]->level = 100;
|
|
}
|
|
|
|
if (outputs[currentOut]->level < 1) {
|
|
outputs[currentOut]->level = 1;
|
|
}
|
|
|
|
} else if (currentScreen == 4) { // width control
|
|
outputs[currentOut]->editing = 1;
|
|
if (dir == 1) {
|
|
outputs[currentOut]->width++;
|
|
} else {
|
|
outputs[currentOut]->width--;
|
|
}
|
|
|
|
if (outputs[currentOut]->width > 100) {
|
|
outputs[currentOut]->width = 100;
|
|
}
|
|
|
|
if (outputs[currentOut]->width < 1) {
|
|
outputs[currentOut]->width = 1;
|
|
}
|
|
|
|
outputs[currentOut]->setWidth(outputs[currentOut]->width);
|
|
|
|
} else if (currentScreen == 5) { // SWING
|
|
|
|
outputs[currentOut]->editing = 1;
|
|
if (dir == 1) {
|
|
outputs[currentOut]->swing++;
|
|
} else {
|
|
outputs[currentOut]->swing--;
|
|
}
|
|
|
|
if (outputs[currentOut]->swing > 100) {
|
|
outputs[currentOut]->swing = 100;
|
|
}
|
|
|
|
if (outputs[currentOut]->swing < 50) {
|
|
outputs[currentOut]->swing = 50;
|
|
}
|
|
} else if (currentScreen == 6) { // PROBABILITY
|
|
|
|
outputs[currentOut]->editing = 1;
|
|
if (dir == 1) {
|
|
outputs[currentOut]->p++;
|
|
} else {
|
|
outputs[currentOut]->p--;
|
|
}
|
|
|
|
if (outputs[currentOut]->p > 100) {
|
|
outputs[currentOut]->p = 100;
|
|
}
|
|
|
|
if (outputs[currentOut]->p < 0) {
|
|
outputs[currentOut]->p = 0;
|
|
}
|
|
} else if (currentScreen == 7) { // STICKY
|
|
outputs[currentOut]->sticky ^= true;
|
|
|
|
} else if (currentScreen == 8) { // MUTE
|
|
|
|
outputs[currentOut]->editing = 1;
|
|
outputs[currentOut]->isEnabled ^= true;
|
|
|
|
}
|
|
}
|
|
|
|
} else {
|
|
if (cursorPosition == 0 && cursorClick == 1) { // Engage BPM on Main Screen
|
|
update_BPM(dir);
|
|
} else {
|
|
if (dir == 1) {
|
|
cursorPosition++;
|
|
} else {
|
|
cursorPosition--;
|
|
}
|
|
|
|
if (cursorPosition > mainMaxCursorPosition) {
|
|
cursorPosition = 0;
|
|
}
|
|
|
|
if (cursorPosition < 0) {
|
|
cursorPosition = mainMaxCursorPosition;
|
|
}
|
|
}
|
|
}
|
|
|
|
updateScreen = 1;
|
|
}
|
|
|
|
|
|
void DisplayHandler::handleClick() {
|
|
cursorClick ^= true;
|
|
|
|
if (onOutScreen) {
|
|
if (currentScreen == 0) { // exit screen
|
|
cursorPosition = currentOut + 1;
|
|
currentOut = -1;
|
|
currentScreen = 0;
|
|
onOutScreen = 0;
|
|
cursorClick = false;
|
|
}
|
|
|
|
if (currentScreen == 1 && outputs[currentOut]->editing == 1) {
|
|
outputs[currentOut]->setDiv(outputs[currentOut]->modifierSelectionIndex);
|
|
outputs[currentOut]->editing = 0;
|
|
cursorClick = false;
|
|
}
|
|
} else {
|
|
|
|
if (currentScreen == 0) { // on main screen
|
|
if (cursorPosition == 0) { // Change BPM
|
|
|
|
} else if (cursorPosition > 0 && cursorPosition < 9) { // go to out screen
|
|
currentOut = cursorPosition - 1;
|
|
cursorPosition = 1;
|
|
currentScreen = 1;
|
|
onOutScreen = 1;
|
|
cursorClick = 0;
|
|
} else if (cursorPosition == 9) { // PLAY/PAUSE BUTTON
|
|
PLAY ^= true;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
updateScreen = 1;
|
|
}
|
|
|
|
|
|
void DisplayHandler::render() {
|
|
if (updateScreen) {
|
|
display->clear();
|
|
|
|
if (currentScreen == 0 && currentOut == -1) { // main screen
|
|
renderMainPage();
|
|
} else if (currentOut != -1) {
|
|
renderOutPage();
|
|
}
|
|
|
|
display->sendBuffer();
|
|
|
|
updateScreen = 0;
|
|
}
|
|
}
|
|
|
|
|
|
void DisplayHandler::renderMainPage() {
|
|
std::string bpm_string = "BPM: " + std::to_string(BPM);
|
|
|
|
if (cursorPosition == 0) {
|
|
if (cursorClick == 1) {
|
|
pico_ssd1306::fillRect(display, 0, 0, 100, 18);
|
|
pico_ssd1306::drawText(display, font_12x16, bpm_string.c_str(), 1, 2, pico_ssd1306::WriteMode::SUBTRACT);
|
|
|
|
} else {
|
|
pico_ssd1306::drawRect(display, 0, 0, 100, 18, pico_ssd1306::WriteMode::ADD);
|
|
pico_ssd1306::drawText(display, font_12x16, bpm_string.c_str(), 1, 2);
|
|
|
|
}
|
|
} else {
|
|
pico_ssd1306::drawText(display, font_12x16, bpm_string.c_str(), 1, 2);
|
|
|
|
}
|
|
|
|
uint8_t cursor_x = 2;
|
|
uint8_t cursor_y = 25;
|
|
|
|
for (uint8_t i = 1; i < 9; i++) {
|
|
if (i == 5) {
|
|
cursor_x = 2;
|
|
cursor_y += 20;
|
|
}
|
|
|
|
if (cursorPosition == i) {
|
|
pico_ssd1306::drawRect(display, cursor_x - 2, cursor_y - 4, cursor_x + 14, cursor_y + 16, pico_ssd1306::WriteMode::ADD);
|
|
|
|
}
|
|
pico_ssd1306::drawText(display, font_12x16, std::to_string(i).c_str(), cursor_x, cursor_y);
|
|
cursor_x += 30;
|
|
}
|
|
|
|
|
|
if (cursorPosition == 9) { // PLAY BUTTON
|
|
pico_ssd1306::fillRect(display, 120, 8, 130, 18, pico_ssd1306::WriteMode::ADD);
|
|
pico_ssd1306::drawText(display, font_8x8, PLAY ? ">" : "#", 120, 10, pico_ssd1306::WriteMode::SUBTRACT);
|
|
} else {
|
|
pico_ssd1306::drawText(display, font_8x8, PLAY ? ">" : "#", 120, 10);
|
|
}
|
|
|
|
if (cursorPosition == 10) { // OPTIONS BUTTON
|
|
pico_ssd1306::fillRect(display, 120, 28, 130, 38, pico_ssd1306::WriteMode::ADD);
|
|
pico_ssd1306::drawText(display, font_8x8, "*", 120, 30, pico_ssd1306::WriteMode::SUBTRACT);
|
|
} else {
|
|
pico_ssd1306::drawText(display, font_8x8, "*", 120, 30);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void DisplayHandler::renderOutPage() {
|
|
uint8_t visualOut = currentOut + 1;
|
|
std::string title = std::to_string(visualOut) + "| " + out_pages[currentScreen];
|
|
pico_ssd1306::drawText(display, font_12x16, title.c_str(), 1, 2);
|
|
|
|
std::string param_string;
|
|
|
|
if (currentScreen == 0) { // exit screen
|
|
param_string = "<--";
|
|
|
|
} else if (currentScreen == 1) { // modifier screen
|
|
uint8_t modifier_selection_index = outputs[currentOut]->modifierSelectionIndex;
|
|
param_string = MODIFIER_STRINGS[modifier_selection_index];
|
|
|
|
} else if (currentScreen == 2) { // shape screen
|
|
param_string = waveShapeToString(outputs[currentOut]->shape);
|
|
|
|
} else if (currentScreen == 3) { // level screen
|
|
param_string = std::to_string(outputs[currentOut]->level) + "%";
|
|
|
|
} else if (currentScreen == 4) { // Width screen
|
|
param_string = std::to_string(outputs[currentOut]->width) + "%";
|
|
|
|
} else if (currentScreen == 5) { // Swing screen
|
|
param_string = std::to_string(outputs[currentOut]->swing) + "%";
|
|
|
|
} else if (currentScreen == 6) { // Probability screen
|
|
param_string = std::to_string(outputs[currentOut]->p) + "%";
|
|
|
|
} else if (currentScreen == 7) { // STICKY Screen
|
|
param_string = outputs[currentOut]->sticky ? "ON" : "OFF";
|
|
|
|
} else if (currentScreen == 8) { // Mute Screen
|
|
param_string = outputs[currentOut]->isEnabled ? "ON" : "OFF";
|
|
}
|
|
|
|
if (cursorClick) {
|
|
pico_ssd1306::fillRect(display, 1, 42, 50, 60);
|
|
pico_ssd1306::drawText(display, font_12x16, param_string.c_str(), 1, 45, pico_ssd1306::WriteMode::SUBTRACT);
|
|
} else {
|
|
pico_ssd1306::drawText(display, font_12x16, param_string.c_str(), 1, 45);
|
|
}
|
|
|
|
}
|