Optimizations 1
This commit is contained in:
+83
-37
@@ -181,48 +181,70 @@ void handleInput() {
|
||||
|
||||
void drawUI() {
|
||||
display.clearDisplay();
|
||||
display.setTextSize(1);
|
||||
display.setTextColor(SSD1306_WHITE);
|
||||
display.setCursor(0, 0);
|
||||
|
||||
if (currentState == UI_MENU) {
|
||||
for (int i = 0; i < NUM_MENU_ITEMS; i++) {
|
||||
if (i == menuSelection) {
|
||||
display.fillRect(0, i * 10, SCREEN_WIDTH, 10, SSD1306_WHITE);
|
||||
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE);
|
||||
} else {
|
||||
display.setTextColor(SSD1306_WHITE);
|
||||
}
|
||||
display.setCursor(2, i * 10 + 1);
|
||||
display.print(MENU_ITEMS[i].label);
|
||||
display.print(": ");
|
||||
if (globalSynth) {
|
||||
// Copy grid state to local buffer to minimize lock time
|
||||
struct MiniCell {
|
||||
uint8_t type;
|
||||
uint8_t rotation;
|
||||
float value;
|
||||
};
|
||||
MiniCell gridCopy[SynthEngine::GRID_W][SynthEngine::GRID_H];
|
||||
|
||||
// Display current value
|
||||
switch (MENU_ITEMS[i].editState) {
|
||||
case UI_EDIT_SCALE_TYPE: display.print(SCALES[currentScaleIndex].name); break;
|
||||
case UI_EDIT_SCALE_KEY: display.print(KEY_NAMES[currentKeyIndex]); break;
|
||||
case UI_EDIT_WAVETABLE: display.print(WAVETABLE_NAMES[currentWavetableIndex]); break;
|
||||
default: break;
|
||||
{
|
||||
SynthLockGuard<SynthMutex> lock(globalSynth->gridMutex);
|
||||
for(int x=0; x<SynthEngine::GRID_W; ++x) {
|
||||
for(int y=0; y<SynthEngine::GRID_H; ++y) {
|
||||
gridCopy[x][y].type = (uint8_t)globalSynth->grid[x][y].type;
|
||||
gridCopy[x][y].rotation = (uint8_t)globalSynth->grid[x][y].rotation;
|
||||
gridCopy[x][y].value = globalSynth->grid[x][y].value;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// In an edit screen
|
||||
const char* title = MENU_ITEMS[menuSelection].label;
|
||||
const char* value = "";
|
||||
switch (currentState) {
|
||||
case UI_EDIT_SCALE_TYPE: value = SCALES[currentScaleIndex].name; break;
|
||||
case UI_EDIT_SCALE_KEY: value = KEY_NAMES[currentKeyIndex]; break;
|
||||
case UI_EDIT_WAVETABLE: value = WAVETABLE_NAMES[currentWavetableIndex]; break;
|
||||
default: break;
|
||||
|
||||
int cellW = 10;
|
||||
int cellH = 5;
|
||||
int marginX = (SCREEN_WIDTH - (SynthEngine::GRID_W * cellW)) / 2;
|
||||
int marginY = (SCREEN_HEIGHT - (SynthEngine::GRID_H * cellH)) / 2;
|
||||
|
||||
for(int x=0; x<SynthEngine::GRID_W; ++x) {
|
||||
for(int y=0; y<SynthEngine::GRID_H; ++y) {
|
||||
int px = marginX + x * cellW;
|
||||
int py = marginY + y * cellH;
|
||||
int cx = px + cellW / 2;
|
||||
int cy = py + cellH / 2;
|
||||
|
||||
uint8_t type = gridCopy[x][y].type;
|
||||
uint8_t rot = gridCopy[x][y].rotation;
|
||||
|
||||
if (type == SynthEngine::GridCell::EMPTY) {
|
||||
display.drawPixel(cx, cy, SSD1306_WHITE);
|
||||
} else if (type == SynthEngine::GridCell::SINK) {
|
||||
display.fillRect(px + 1, py + 1, cellW - 2, cellH - 2, SSD1306_WHITE);
|
||||
} else {
|
||||
// Draw direction line
|
||||
int dx = 0, dy = 0;
|
||||
switch(rot) {
|
||||
case 0: dy = -2; break; // N
|
||||
case 1: dx = 4; break; // E
|
||||
case 2: dy = 2; break; // S
|
||||
case 3: dx = -4; break; // W
|
||||
}
|
||||
display.drawLine(cx, cy, cx + dx, cy + dy, SSD1306_WHITE);
|
||||
|
||||
if (type == SynthEngine::GridCell::FORK) {
|
||||
if (rot == 0 || rot == 2) display.drawLine(cx - 2, cy, cx + 2, cy, SSD1306_WHITE);
|
||||
else display.drawLine(cx, cy - 2, cx, cy + 2, SSD1306_WHITE);
|
||||
} else if (type >= SynthEngine::GridCell::FIXED_OSCILLATOR && type <= SynthEngine::GridCell::GATE_INPUT) {
|
||||
// Sources: Filled rect
|
||||
display.fillRect(cx - 1, cy - 1, 3, 3, SSD1306_WHITE);
|
||||
} else if (type != SynthEngine::GridCell::WIRE) {
|
||||
// Processors: Hollow rect
|
||||
display.drawRect(cx - 1, cy - 1, 3, 3, SSD1306_WHITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
display.println(title);
|
||||
display.drawLine(0, 10, SCREEN_WIDTH, 10, SSD1306_WHITE);
|
||||
display.setCursor(10, 25);
|
||||
display.setTextSize(2);
|
||||
display.print(value);
|
||||
display.setTextSize(1);
|
||||
display.setCursor(0, 50);
|
||||
display.println(F("(Press to confirm)"));
|
||||
}
|
||||
|
||||
display.display();
|
||||
@@ -232,6 +254,8 @@ void checkSerial() {
|
||||
static int state = 0; // 0: Header, 1: Data
|
||||
static int headerIdx = 0;
|
||||
static const char* header = "NSGRID";
|
||||
static int loadHeaderIdx = 0;
|
||||
static const char* loadHeader = "NSLOAD";
|
||||
static uint8_t buffer[SynthEngine::SERIALIZED_GRID_SIZE];
|
||||
static int bufferIdx = 0;
|
||||
|
||||
@@ -244,17 +268,39 @@ void checkSerial() {
|
||||
state = 1;
|
||||
bufferIdx = 0;
|
||||
headerIdx = 0;
|
||||
loadHeaderIdx = 0;
|
||||
}
|
||||
} else {
|
||||
headerIdx = 0;
|
||||
if (b == 'N') headerIdx = 1;
|
||||
}
|
||||
|
||||
if (state == 0) {
|
||||
if (b == loadHeader[loadHeaderIdx]) {
|
||||
loadHeaderIdx++;
|
||||
if (loadHeaderIdx == 6) {
|
||||
if (globalSynth) {
|
||||
uint8_t buf[SynthEngine::SERIALIZED_GRID_SIZE];
|
||||
globalSynth->exportGrid(buf);
|
||||
Serial.write("NSGRID", 6);
|
||||
Serial.write(buf, sizeof(buf));
|
||||
Serial.flush();
|
||||
}
|
||||
loadHeaderIdx = 0;
|
||||
headerIdx = 0;
|
||||
}
|
||||
} else {
|
||||
loadHeaderIdx = 0;
|
||||
if (b == 'N') loadHeaderIdx = 1;
|
||||
}
|
||||
}
|
||||
} else if (state == 1) {
|
||||
buffer[bufferIdx++] = b;
|
||||
if (bufferIdx == SynthEngine::SERIALIZED_GRID_SIZE) {
|
||||
if (globalSynth) {
|
||||
globalSynth->importGrid(buffer);
|
||||
saveGridToEEPROM();
|
||||
Serial.println(F("OK: Grid Received"));
|
||||
}
|
||||
state = 0;
|
||||
bufferIdx = 0;
|
||||
|
||||
Reference in New Issue
Block a user