New elements and fixes
This commit is contained in:
@@ -192,14 +192,35 @@ void drawChar(SDL_Renderer* renderer, int x, int y, int size, char c) {
|
||||
case '/': SDL_RenderDrawLine(renderer, x+w, y, x, y+h); break;
|
||||
case '<': SDL_RenderDrawLine(renderer, x+w, y, x, y+h2); SDL_RenderDrawLine(renderer, x, y+h2, x+w, y+h); break;
|
||||
case '>': SDL_RenderDrawLine(renderer, x, y, x+w, y+h2); SDL_RenderDrawLine(renderer, x+w, y+h2, x, y+h); break;
|
||||
case 'A': SDL_RenderDrawLine(renderer, x, y+h, x+w2, y); SDL_RenderDrawLine(renderer, x+w2, y, x+w, y+h); SDL_RenderDrawLine(renderer, x+w/4, y+h2, x+3*w/4, y+h2); break;
|
||||
case 'B': SDL_RenderDrawLine(renderer, x, y, x, y+h); SDL_RenderDrawLine(renderer, x, y, x+w2, y); SDL_RenderDrawLine(renderer, x+w2, y, x+w, y+h/4); SDL_RenderDrawLine(renderer, x+w, y+h/4, x+w2, y+h2); SDL_RenderDrawLine(renderer, x+w2, y+h2, x, y+h2); SDL_RenderDrawLine(renderer, x+w2, y+h2, x+w, y+3*h/4); SDL_RenderDrawLine(renderer, x+w, y+3*h/4, x+w2, y+h); SDL_RenderDrawLine(renderer, x+w2, y+h, x, y+h); break;
|
||||
case 'C': SDL_RenderDrawLine(renderer, x+w, y, x, y); SDL_RenderDrawLine(renderer, x, y, x, y+h); SDL_RenderDrawLine(renderer, x, y+h, x+w, y+h); break;
|
||||
case 'D': SDL_RenderDrawLine(renderer, x, y, x, y+h); SDL_RenderDrawLine(renderer, x, y, x+w2, y); SDL_RenderDrawLine(renderer, x+w2, y, x+w, y+h2); SDL_RenderDrawLine(renderer, x+w, y+h2, x+w2, y+h); SDL_RenderDrawLine(renderer, x+w2, y+h, x, y+h); break;
|
||||
case 'E': SDL_RenderDrawLine(renderer, x+w, y, x, y); SDL_RenderDrawLine(renderer, x, y, x, y+h); SDL_RenderDrawLine(renderer, x, y+h, x+w, y+h); SDL_RenderDrawLine(renderer, x, y+h2, x+w2, y+h2); break;
|
||||
case 'F': SDL_RenderDrawLine(renderer, x, y, x, y+h); SDL_RenderDrawLine(renderer, x, y, x+w, y); SDL_RenderDrawLine(renderer, x, y+h2, x+w2, y+h2); break;
|
||||
case 'G': SDL_RenderDrawLine(renderer, x+w, y, x, y); SDL_RenderDrawLine(renderer, x, y, x, y+h); SDL_RenderDrawLine(renderer, x, y+h, x+w, y+h); SDL_RenderDrawLine(renderer, x+w, y+h, x+w, y+h2); SDL_RenderDrawLine(renderer, x+w, y+h2, x+w2, y+h2); break;
|
||||
case 'H': SDL_RenderDrawLine(renderer, x, y, x, y+h); SDL_RenderDrawLine(renderer, x+w, y, x+w, y+h); SDL_RenderDrawLine(renderer, x, y+h2, x+w, y+h2); break;
|
||||
case 'I': SDL_RenderDrawLine(renderer, x+w2, y, x+w2, y+h); SDL_RenderDrawLine(renderer, x, y, x+w, y); SDL_RenderDrawLine(renderer, x, y+h, x+w, y+h); break;
|
||||
case 'K': SDL_RenderDrawLine(renderer, x, y, x, y+h); SDL_RenderDrawLine(renderer, x+w, y, x, y+h2); SDL_RenderDrawLine(renderer, x, y+h2, x+w, y+h); break;
|
||||
case 'L': SDL_RenderDrawLine(renderer, x, y, x, y+h); SDL_RenderDrawLine(renderer, x, y+h, x+w, y+h); break;
|
||||
case 'M': SDL_RenderDrawLine(renderer, x, y+h, x, y); SDL_RenderDrawLine(renderer, x, y, x+w2, y+h2); SDL_RenderDrawLine(renderer, x+w2, y+h2, x+w, y); SDL_RenderDrawLine(renderer, x+w, y, x+w, y+h); break;
|
||||
case 'N': SDL_RenderDrawLine(renderer, x, y+h, x, y); SDL_RenderDrawLine(renderer, x, y, x+w, y+h); SDL_RenderDrawLine(renderer, x+w, y+h, x+w, y); break;
|
||||
case 'O': drawChar(renderer, x, y, size, '0'); break;
|
||||
case 'P': SDL_RenderDrawLine(renderer, x, y, x, y+h); SDL_RenderDrawLine(renderer, x, y, x+w, y); SDL_RenderDrawLine(renderer, x+w, y, x+w, y+h2); SDL_RenderDrawLine(renderer, x+w, y+h2, x, y+h2); break;
|
||||
case 'Q': drawChar(renderer, x, y, size, '0'); SDL_RenderDrawLine(renderer, x+w2, y+h2, x+w, y+h); break;
|
||||
case 'R': SDL_RenderDrawLine(renderer, x, y, x, y+h); SDL_RenderDrawLine(renderer, x, y, x+w, y); SDL_RenderDrawLine(renderer, x+w, y, x+w, y+h2); SDL_RenderDrawLine(renderer, x+w, y+h2, x, y+h2); SDL_RenderDrawLine(renderer, x, y+h2, x+w, y+h); break;
|
||||
case 'S': SDL_RenderDrawLine(renderer, x+w, y, x, y); SDL_RenderDrawLine(renderer, x, y, x, y+h2); SDL_RenderDrawLine(renderer, x, y+h2, x+w, y+h2); SDL_RenderDrawLine(renderer, x+w, y+h2, x+w, y+h); SDL_RenderDrawLine(renderer, x+w, y+h, x, y+h); break;
|
||||
case 'T': SDL_RenderDrawLine(renderer, x, y, x+w, y); SDL_RenderDrawLine(renderer, x+w2, y, x+w2, y+h); break;
|
||||
case 'U': SDL_RenderDrawLine(renderer, x, y, x, y+h); SDL_RenderDrawLine(renderer, x, y+h, x+w, y+h); SDL_RenderDrawLine(renderer, x+w, y+h, x+w, y); break;
|
||||
case 'V': SDL_RenderDrawLine(renderer, x, y, x+w2, y+h); SDL_RenderDrawLine(renderer, x+w2, y+h, x+w, y); break;
|
||||
case 'W':
|
||||
SDL_RenderDrawLine(renderer, x, y, x, y+h);
|
||||
SDL_RenderDrawLine(renderer, x, y+h, x+w2, y+h2);
|
||||
SDL_RenderDrawLine(renderer, x+w2, y+h2, x+w, y+h);
|
||||
SDL_RenderDrawLine(renderer, x+w, y+h, x+w, y);
|
||||
break;
|
||||
case 'X': SDL_RenderDrawLine(renderer, x, y, x+w, y+h); SDL_RenderDrawLine(renderer, x+w, y, x, y+h); break;
|
||||
case 'Y': SDL_RenderDrawLine(renderer, x, y, x+w2, y+h2); SDL_RenderDrawLine(renderer, x+w, y, x+w2, y+h2); SDL_RenderDrawLine(renderer, x+w2, y+h2, x+w2, y+h); break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,6 +233,24 @@ void drawString(SDL_Renderer* renderer, int x, int y, int size, const char* str)
|
||||
}
|
||||
}
|
||||
|
||||
void drawParamBar(SDL_Renderer* renderer, int x, int y, int size, float value, uint8_t r, uint8_t g, uint8_t b) {
|
||||
SDL_SetRenderDrawColor(renderer, 50, 50, 50, 255);
|
||||
SDL_Rect bg = {x + 4, y + size - 6, size - 8, 4};
|
||||
SDL_RenderFillRect(renderer, &bg);
|
||||
|
||||
SDL_SetRenderDrawColor(renderer, r, g, b, 255);
|
||||
int w = (int)((size - 8) * value);
|
||||
if (w < 0) w = 0;
|
||||
if (w > size - 8) w = size - 8;
|
||||
SDL_Rect fg = {x + 4, y + size - 6, w, 4};
|
||||
SDL_RenderFillRect(renderer, &fg);
|
||||
}
|
||||
|
||||
void drawTypeLabel(SDL_Renderer* renderer, int x, int y, char c) {
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
|
||||
drawChar(renderer, x + 3, y + 3, 8, c);
|
||||
}
|
||||
|
||||
// --- Grid UI Helpers ---
|
||||
void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::GridCell& cell) {
|
||||
// Background
|
||||
@@ -230,6 +269,7 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
if (cell.type == SynthEngine::GridCell::EMPTY) {
|
||||
SDL_RenderDrawPoint(renderer, cx, cy);
|
||||
} else if (cell.type == SynthEngine::GridCell::SINK) {
|
||||
drawTypeLabel(renderer, x, y, 'S');
|
||||
SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
|
||||
SDL_Rect sinkRect = {cx - r, cy - r, r*2, r*2};
|
||||
SDL_RenderFillRect(renderer, &sinkRect);
|
||||
@@ -246,7 +286,9 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
// Param (Fading)
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
|
||||
drawString(renderer, x + 5, y + size - 15, 10, buf);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 0, 255, 0);
|
||||
drawTypeLabel(renderer, x, y, '-');
|
||||
} else if (cell.type == SynthEngine::GridCell::FIXED_OSCILLATOR) {
|
||||
DrawCircle(renderer, cx, cy, r);
|
||||
// Direction line
|
||||
@@ -260,7 +302,9 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
char buf[16];
|
||||
snprintf(buf, 16, "%.0f", 10.0f + cell.param*990.0f);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255);
|
||||
drawString(renderer, x + 5, y + size - 15, 10, buf);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 0, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'O');
|
||||
} else if (cell.type == SynthEngine::GridCell::INPUT_OSCILLATOR) {
|
||||
DrawCircle(renderer, cx, cy, r);
|
||||
DrawCircle(renderer, cx, cy, r/2); // Inner circle to distinguish
|
||||
@@ -274,7 +318,9 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
// Param (Octave)
|
||||
char buf[16]; snprintf(buf, 16, "O%d", 1 + (int)(cell.param * 4.99f));
|
||||
SDL_SetRenderDrawColor(renderer, 255, 200, 0, 255);
|
||||
drawString(renderer, x + 5, y + size - 15, 10, buf);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 200, 0);
|
||||
drawTypeLabel(renderer, x, y, 'I');
|
||||
} else if (cell.type == SynthEngine::GridCell::NOISE) {
|
||||
// Draw static/noise pattern
|
||||
for(int i=0; i<20; ++i) {
|
||||
@@ -292,7 +338,113 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
const char* colors[] = {"BRN", "PNK", "WHT", "YEL", "GRN"};
|
||||
int idx = (int)(cell.param * 4.99f);
|
||||
SDL_SetRenderDrawColor(renderer, 200, 200, 200, 255);
|
||||
drawString(renderer, x + 5, y + size - 15, 10, colors[idx]);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, colors[idx]);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 200, 200, 200);
|
||||
drawTypeLabel(renderer, x, y, 'N');
|
||||
} else if (cell.type == SynthEngine::GridCell::LFO) {
|
||||
DrawCircle(renderer, cx, cy, r);
|
||||
// Direction line
|
||||
int dx=0, dy=0;
|
||||
if (cell.rotation == 0) dy = -r;
|
||||
if (cell.rotation == 1) dx = r;
|
||||
if (cell.rotation == 2) dy = r;
|
||||
if (cell.rotation == 3) dx = -r;
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+dx, cy+dy);
|
||||
drawString(renderer, cx - 8, cy - 5, 12, "LFO");
|
||||
// Param (Freq)
|
||||
char buf[16]; snprintf(buf, 16, "%.1f", 0.1f + cell.param * 19.9f);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 255, 255, 255);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 0, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'L');
|
||||
} else if (cell.type == SynthEngine::GridCell::LPF || cell.type == SynthEngine::GridCell::HPF) {
|
||||
// Box
|
||||
SDL_Rect box = {cx - r, cy - r, r*2, r*2};
|
||||
SDL_RenderDrawRect(renderer, &box);
|
||||
// Label
|
||||
drawString(renderer, cx - 8, cy - 5, 12, cell.type == SynthEngine::GridCell::LPF ? "LPF" : "HPF");
|
||||
// I/O
|
||||
int inDir = (cell.rotation + 2) % 4;
|
||||
int idx=0, idy=0;
|
||||
if(inDir==0) idy=-r; else if(inDir==1) idx=r; else if(inDir==2) idy=r; else idx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx+idx, cy+idy, cx, cy);
|
||||
int odx=0, ody=0;
|
||||
if(cell.rotation==0) ody=-r; else if(cell.rotation==1) odx=r; else if(cell.rotation==2) ody=r; else odx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
// Param
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 0, 255, 0);
|
||||
drawTypeLabel(renderer, x, y, cell.type == SynthEngine::GridCell::LPF ? 'P' : 'H');
|
||||
} else if (cell.type == SynthEngine::GridCell::VCA) {
|
||||
// Triangle shape for Amp
|
||||
// Simplified to box with VCA text
|
||||
SDL_Rect box = {cx - r, cy - r, r*2, r*2};
|
||||
SDL_RenderDrawRect(renderer, &box);
|
||||
drawString(renderer, cx - 8, cy - 5, 12, "VCA");
|
||||
// I/O
|
||||
int inDir = (cell.rotation + 2) % 4;
|
||||
int idx=0, idy=0;
|
||||
if(inDir==0) idy=-r; else if(inDir==1) idx=r; else if(inDir==2) idy=r; else idx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx+idx, cy+idy, cx, cy);
|
||||
int odx=0, ody=0;
|
||||
if(cell.rotation==0) ody=-r; else if(cell.rotation==1) odx=r; else if(cell.rotation==2) ody=r; else odx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
// Param
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param);
|
||||
SDL_SetRenderDrawColor(renderer, 255, 255, 0, 255);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 255, 0);
|
||||
drawTypeLabel(renderer, x, y, 'A');
|
||||
} else if (cell.type == SynthEngine::GridCell::BITCRUSHER) {
|
||||
SDL_Rect box = {cx - r, cy - r, r*2, r*2};
|
||||
SDL_RenderDrawRect(renderer, &box);
|
||||
drawString(renderer, cx - 8, cy - 5, 12, "BIT");
|
||||
// I/O
|
||||
int inDir = (cell.rotation + 2) % 4;
|
||||
int idx=0, idy=0;
|
||||
if(inDir==0) idy=-r; else if(inDir==1) idx=r; else if(inDir==2) idy=r; else idx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx+idx, cy+idy, cx, cy);
|
||||
int odx=0, ody=0;
|
||||
if(cell.rotation==0) ody=-r; else if(cell.rotation==1) odx=r; else if(cell.rotation==2) ody=r; else odx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
// Param
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param);
|
||||
SDL_SetRenderDrawColor(renderer, 255, 0, 255, 255);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 0, 255);
|
||||
drawTypeLabel(renderer, x, y, 'B');
|
||||
} else if (cell.type == SynthEngine::GridCell::DISTORTION) {
|
||||
SDL_Rect box = {cx - r, cy - r, r*2, r*2};
|
||||
SDL_RenderDrawRect(renderer, &box);
|
||||
drawString(renderer, cx - 8, cy - 5, 12, "DST");
|
||||
// I/O
|
||||
int inDir = (cell.rotation + 2) % 4;
|
||||
int idx=0, idy=0;
|
||||
if(inDir==0) idy=-r; else if(inDir==1) idx=r; else if(inDir==2) idy=r; else idx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx+idx, cy+idy, cx, cy);
|
||||
int odx=0, ody=0;
|
||||
if(cell.rotation==0) ody=-r; else if(cell.rotation==1) odx=r; else if(cell.rotation==2) ody=r; else odx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param);
|
||||
SDL_SetRenderDrawColor(renderer, 255, 100, 100, 255);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 100, 100);
|
||||
drawTypeLabel(renderer, x, y, 'X');
|
||||
} else if (cell.type == SynthEngine::GridCell::GLITCH) {
|
||||
drawString(renderer, cx - 8, cy - 5, 12, "GLT");
|
||||
// I/O
|
||||
int inDir = (cell.rotation + 2) % 4;
|
||||
int idx=0, idy=0;
|
||||
if(inDir==0) idy=-r; else if(inDir==1) idx=r; else if(inDir==2) idy=r; else idx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx+idx, cy+idy, cx, cy);
|
||||
int odx=0, ody=0;
|
||||
if(cell.rotation==0) ody=-r; else if(cell.rotation==1) odx=r; else if(cell.rotation==2) ody=r; else odx=-r;
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 0, 0);
|
||||
drawTypeLabel(renderer, x, y, 'G');
|
||||
} else if (cell.type == SynthEngine::GridCell::FORK) {
|
||||
// Draw Y shape based on rotation
|
||||
// Center
|
||||
@@ -314,7 +466,9 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
// Param (Balance)
|
||||
char buf[16]; snprintf(buf, 16, "%.1f", cell.param);
|
||||
SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
|
||||
drawString(renderer, x + 5, y + size - 15, 10, buf);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 0, 255, 0);
|
||||
drawTypeLabel(renderer, x, y, 'Y');
|
||||
} else if (cell.type == SynthEngine::GridCell::DELAY) {
|
||||
// Draw D
|
||||
drawString(renderer, cx - 5, cy - 5, 12, "D");
|
||||
@@ -334,7 +488,9 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
float delay_ms = cell.param * 2000.0f; // Max 2 seconds
|
||||
snprintf(buf, 16, "%.0fms", delay_ms);
|
||||
SDL_SetRenderDrawColor(renderer, 255, 128, 0, 255);
|
||||
drawString(renderer, x + 5, y + size - 15, 10, buf);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 128, 0);
|
||||
drawTypeLabel(renderer, x, y, 'D');
|
||||
} else if (cell.type == SynthEngine::GridCell::REVERB) {
|
||||
// Draw R
|
||||
drawString(renderer, cx - 5, cy - 5, 12, "R");
|
||||
@@ -351,7 +507,9 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
// Param (Strength)
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param);
|
||||
SDL_SetRenderDrawColor(renderer, 200, 100, 255, 255);
|
||||
drawString(renderer, x + 5, y + size - 15, 10, buf);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 200, 100, 255);
|
||||
drawTypeLabel(renderer, x, y, 'R');
|
||||
} else if (cell.type == SynthEngine::GridCell::OPERATOR) {
|
||||
SDL_Rect opRect = {cx - r, cy - r, r*2, r*2};
|
||||
SDL_RenderDrawRect(renderer, &opRect);
|
||||
@@ -371,7 +529,9 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
else if (opType == 3) opChar = '/';
|
||||
else if (opType == 4) opChar = '<';
|
||||
else if (opType == 5) opChar = '>';
|
||||
drawChar(renderer, cx - 5, cy - 5, 12, opChar);
|
||||
drawChar(renderer, cx - 15, cy - 15, 12, opChar);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'M');
|
||||
} else if (cell.type == SynthEngine::GridCell::WAVETABLE) {
|
||||
drawString(renderer, cx - 5, cy - 5, 12, "W");
|
||||
// Direction line
|
||||
@@ -386,7 +546,9 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
char buf[4];
|
||||
snprintf(buf, 4, "%d", idx);
|
||||
SDL_SetRenderDrawColor(renderer, 128, 128, 255, 255);
|
||||
drawString(renderer, x + 5, y + size - 15, 10, buf);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 128, 128, 255);
|
||||
drawTypeLabel(renderer, x, y, 'W');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,7 +577,7 @@ void randomizeGrid() {
|
||||
std::lock_guard<std::mutex> lock(engine.gridMutex);
|
||||
|
||||
// Number of types to choose from (excluding SINK)
|
||||
const int numTypes = (int)SynthEngine::GridCell::SINK;
|
||||
const int numTypes = (int)SynthEngine::GridCell::SINK;
|
||||
|
||||
// 1. Clear existing buffers first
|
||||
for (int x = 0; x < 5; ++x) {
|
||||
@@ -433,9 +595,10 @@ void randomizeGrid() {
|
||||
}
|
||||
|
||||
int attempts = 0;
|
||||
bool connected = false;
|
||||
bool inputOscillatorReachable = false;
|
||||
bool visited[5][8];
|
||||
|
||||
while (!connected && attempts < 1000) {
|
||||
while (!inputOscillatorReachable && attempts < 1000) {
|
||||
attempts++;
|
||||
|
||||
// 2. Randomize (without allocation)
|
||||
@@ -452,14 +615,14 @@ void randomizeGrid() {
|
||||
|
||||
// 3. Check Connectivity
|
||||
// BFS from SINK (2,3) backwards
|
||||
bool visited[5][8] = {false};
|
||||
memset(visited, 0, sizeof(visited));
|
||||
std::vector<std::pair<int, int>> q;
|
||||
|
||||
q.push_back({2, 3});
|
||||
visited[2][3] = true;
|
||||
|
||||
int head = 0;
|
||||
while(head < (int)q.size()){
|
||||
while(head < (int)q.size()) {
|
||||
std::pair<int, int> curr = q[head++];
|
||||
int cx = curr.first;
|
||||
int cy = curr.second;
|
||||
@@ -471,9 +634,7 @@ void randomizeGrid() {
|
||||
for(int i=0; i<4; ++i) {
|
||||
int tx = cx + nx[i];
|
||||
int ty = cy + ny[i];
|
||||
|
||||
if (tx >= 0 && tx < 5 && ty >= 0 && ty < 8) {
|
||||
if (visited[tx][ty]) continue;
|
||||
if (tx >= 0 && tx < 5 && ty >= 0 && ty < 8 && !visited[tx][ty]) {
|
||||
|
||||
SynthEngine::GridCell& neighbor = engine.grid[tx][ty];
|
||||
bool pointsToCurr = false;
|
||||
@@ -506,23 +667,39 @@ void randomizeGrid() {
|
||||
}
|
||||
|
||||
if (pointsToCurr) {
|
||||
if (neighbor.type == SynthEngine::GridCell::FIXED_OSCILLATOR ||
|
||||
neighbor.type == SynthEngine::GridCell::INPUT_OSCILLATOR ||
|
||||
neighbor.type == SynthEngine::GridCell::WAVETABLE ||
|
||||
neighbor.type == SynthEngine::GridCell::NOISE) {
|
||||
connected = true;
|
||||
break;
|
||||
}
|
||||
visited[tx][ty] = true;
|
||||
q.push_back({tx, ty});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (connected) break;
|
||||
}
|
||||
|
||||
// After BFS, check if an input oscillator is reachable
|
||||
for (int x = 0; x < 5; ++x) {
|
||||
for (int y = 0; y < 8; ++y) {
|
||||
if (visited[x][y] && engine.grid[x][y].type == SynthEngine::GridCell::INPUT_OSCILLATOR) {
|
||||
inputOscillatorReachable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (inputOscillatorReachable) break;
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Allocate buffers for DELAYs
|
||||
// 4. Prune unreachable elements if a valid grid was found
|
||||
if (inputOscillatorReachable) {
|
||||
for (int x = 0; x < 5; ++x) {
|
||||
for (int y = 0; y < 8; ++y) {
|
||||
if (!visited[x][y]) {
|
||||
engine.grid[x][y].type = SynthEngine::GridCell::EMPTY;
|
||||
engine.grid[x][y].param = 0.5f;
|
||||
engine.grid[x][y].rotation = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Allocate buffers for DELAYs and REVERBs that are still present
|
||||
for (int x = 0; x < 5; ++x) {
|
||||
for (int y = 0; y < 8; ++y) {
|
||||
SynthEngine::GridCell& c = engine.grid[x][y];
|
||||
@@ -534,7 +711,7 @@ void randomizeGrid() {
|
||||
}
|
||||
}
|
||||
|
||||
printf("Randomized in %d attempts. Connected: %s\n", attempts, connected ? "YES" : "NO");
|
||||
printf("Randomized in %d attempts. Input Osc reachable: %s\n", attempts, inputOscillatorReachable ? "YES" : "NO");
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
@@ -601,6 +778,27 @@ int main(int argc, char* argv[]) {
|
||||
engine.setFilter(20.0f + filter_vals[0]*19980.0f, 20.0f + filter_vals[1]*19980.0f);
|
||||
|
||||
// --- Main Loop ---
|
||||
const SynthEngine::GridCell::Type cellTypes[] = {
|
||||
SynthEngine::GridCell::EMPTY,
|
||||
SynthEngine::GridCell::FIXED_OSCILLATOR,
|
||||
SynthEngine::GridCell::INPUT_OSCILLATOR,
|
||||
SynthEngine::GridCell::WAVETABLE,
|
||||
SynthEngine::GridCell::NOISE,
|
||||
SynthEngine::GridCell::LFO,
|
||||
SynthEngine::GridCell::FORK,
|
||||
SynthEngine::GridCell::WIRE,
|
||||
SynthEngine::GridCell::LPF,
|
||||
SynthEngine::GridCell::HPF,
|
||||
SynthEngine::GridCell::VCA,
|
||||
SynthEngine::GridCell::BITCRUSHER,
|
||||
SynthEngine::GridCell::DISTORTION,
|
||||
SynthEngine::GridCell::GLITCH,
|
||||
SynthEngine::GridCell::OPERATOR,
|
||||
SynthEngine::GridCell::DELAY,
|
||||
SynthEngine::GridCell::REVERB
|
||||
};
|
||||
const int numCellTypes = sizeof(cellTypes) / sizeof(cellTypes[0]);
|
||||
|
||||
bool quit = false;
|
||||
SDL_Event e;
|
||||
|
||||
@@ -645,17 +843,12 @@ int main(int argc, char* argv[]) {
|
||||
SynthEngine::GridCell::Type newType = oldType;
|
||||
|
||||
if (e.button.button == SDL_BUTTON_LEFT) {
|
||||
// Cycle: EMPTY -> FIXED -> INPUT -> WAVETABLE -> NOISE -> FORK -> WIRE -> OP -> DELAY -> REVERB -> EMPTY
|
||||
if (oldType == SynthEngine::GridCell::EMPTY) newType = SynthEngine::GridCell::FIXED_OSCILLATOR;
|
||||
else if (oldType == SynthEngine::GridCell::FIXED_OSCILLATOR) newType = SynthEngine::GridCell::INPUT_OSCILLATOR;
|
||||
else if (oldType == SynthEngine::GridCell::INPUT_OSCILLATOR) newType = SynthEngine::GridCell::WAVETABLE;
|
||||
else if (oldType == SynthEngine::GridCell::WAVETABLE) newType = SynthEngine::GridCell::NOISE;
|
||||
else if (oldType == SynthEngine::GridCell::NOISE) newType = SynthEngine::GridCell::FORK;
|
||||
else if (oldType == SynthEngine::GridCell::FORK) newType = SynthEngine::GridCell::WIRE;
|
||||
else if (oldType == SynthEngine::GridCell::WIRE) newType = SynthEngine::GridCell::OPERATOR;
|
||||
else if (oldType == SynthEngine::GridCell::OPERATOR) newType = SynthEngine::GridCell::DELAY;
|
||||
else if (oldType == SynthEngine::GridCell::DELAY) newType = SynthEngine::GridCell::REVERB;
|
||||
else if (oldType == SynthEngine::GridCell::REVERB) newType = SynthEngine::GridCell::EMPTY;
|
||||
for (int i = 0; i < numCellTypes; ++i) {
|
||||
if (cellTypes[i] == oldType) {
|
||||
newType = cellTypes[(i + 1) % numCellTypes];
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (e.button.button == SDL_BUTTON_RIGHT) {
|
||||
c.rotation = (c.rotation + 1) % 4;
|
||||
} else if (e.button.button == SDL_BUTTON_MIDDLE) {
|
||||
@@ -701,18 +894,22 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
}
|
||||
} else if (e.type == SDL_MOUSEWHEEL) {
|
||||
SDL_Keymod modState = SDL_GetModState();
|
||||
bool fineTune = (modState & KMOD_SHIFT);
|
||||
|
||||
int mx, my;
|
||||
SDL_GetMouseState(&mx, &my);
|
||||
|
||||
if (mx < GRID_PANEL_WIDTH) {
|
||||
// Grid Scroll
|
||||
float step = fineTune ? 0.01f : 0.05f;
|
||||
int gx = mx / 80;
|
||||
int gy = my / 80;
|
||||
if (gx >= 0 && gx < 5 && gy >= 0 && gy < 8) {
|
||||
std::lock_guard<std::mutex> lock(engine.gridMutex);
|
||||
SynthEngine::GridCell& c = engine.grid[gx][gy];
|
||||
if (e.wheel.y > 0) c.param += 0.05f;
|
||||
else c.param -= 0.05f;
|
||||
if (e.wheel.y > 0) c.param += step;
|
||||
else c.param -= step;
|
||||
if (c.param > 1.0f) c.param = 1.0f;
|
||||
if (c.param < 0.0f) c.param = 0.0f;
|
||||
}
|
||||
@@ -732,8 +929,9 @@ int main(int argc, char* argv[]) {
|
||||
engine.setFrequency(note_to_freq(current_octave, key_to_note_map[ (SDL_Scancode)current_key_scancode ]));
|
||||
}
|
||||
} else { // Right knob (volume)
|
||||
if (e.wheel.y > 0) knob_vol_val += 0.05f;
|
||||
else if (e.wheel.y < 0) knob_vol_val -= 0.05f;
|
||||
float volStep = fineTune ? 0.01f : 0.05f;
|
||||
if (e.wheel.y > 0) knob_vol_val += volStep;
|
||||
else if (e.wheel.y < 0) knob_vol_val -= volStep;
|
||||
|
||||
if (knob_vol_val > 1.0f) knob_vol_val = 1.0f;
|
||||
if (knob_vol_val < 0.0f) knob_vol_val = 0.0f;
|
||||
|
||||
Reference in New Issue
Block a user