Optimized: Fixed point calculations
This commit is contained in:
+46
-46
@@ -465,10 +465,10 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
// Param (Freq)
|
||||
char buf[16];
|
||||
snprintf(buf, 16, "%.0f", 10.0f + cell.param*990.0f);
|
||||
snprintf(buf, 16, "%.0f", 10.0f + (cell.param / 32767.0f)*990.0f);
|
||||
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);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 0, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'O');
|
||||
} else if (cell.type == SynthEngine::GridCell::INPUT_OSCILLATOR) {
|
||||
DrawCircle(renderer, cx, cy, r);
|
||||
@@ -482,10 +482,10 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+dx, cy+dy);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
// Param (Octave)
|
||||
char buf[16]; snprintf(buf, 16, "O%d", 1 + (int)(cell.param * 4.99f));
|
||||
char buf[16]; snprintf(buf, 16, "O%d", 1 + (int)((cell.param / 32767.0f) * 4.99f));
|
||||
SDL_SetRenderDrawColor(renderer, 255, 200, 0, 255);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 200, 0);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 255, 200, 0);
|
||||
drawTypeLabel(renderer, x, y, 'I');
|
||||
} else if (cell.type == SynthEngine::GridCell::NOISE) {
|
||||
// Draw static/noise pattern
|
||||
@@ -503,10 +503,10 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
|
||||
// Param (Color)
|
||||
const char* colors[] = {"BRN", "PNK", "WHT", "YEL", "GRN"};
|
||||
int idx = (int)(cell.param * 4.99f);
|
||||
int idx = (int)((cell.param / 32767.0f) * 4.99f);
|
||||
SDL_SetRenderDrawColor(renderer, 200, 200, 200, 255);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, colors[idx]);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 200, 200, 200);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 200, 200, 200);
|
||||
drawTypeLabel(renderer, x, y, 'N');
|
||||
} else if (cell.type == SynthEngine::GridCell::LFO) {
|
||||
DrawCircle(renderer, cx, cy, r);
|
||||
@@ -520,16 +520,16 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
drawString(renderer, cx - 8, cy - 5, 12, "LFO");
|
||||
// Param (Freq)
|
||||
char buf[16]; snprintf(buf, 16, "%.1f", 0.1f + cell.param * 19.9f);
|
||||
char buf[16]; snprintf(buf, 16, "%.1f", 0.1f + (cell.param / 32767.0f) * 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);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 0, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'L');
|
||||
} else if (cell.type == SynthEngine::GridCell::GATE_INPUT) {
|
||||
SDL_Rect box = {cx - r, cy - r, r*2, r*2};
|
||||
SDL_RenderDrawRect(renderer, &box);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
if (cell.value > 0.5f) SDL_RenderFillRect(renderer, &box);
|
||||
if (cell.value > 16384) SDL_RenderFillRect(renderer, &box);
|
||||
drawString(renderer, cx - 8, cy - 5, 12, "G-IN");
|
||||
drawTypeLabel(renderer, x, y, 'K');
|
||||
} else if (cell.type == SynthEngine::GridCell::ADSR_ATTACK) {
|
||||
@@ -545,7 +545,7 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 255, 255);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 255, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'A');
|
||||
} else if (cell.type == SynthEngine::GridCell::ADSR_DECAY) {
|
||||
// Draw Ramp Down
|
||||
@@ -560,7 +560,7 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 255, 255);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 255, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'D');
|
||||
} else if (cell.type == SynthEngine::GridCell::ADSR_SUSTAIN) {
|
||||
// Draw Level
|
||||
@@ -575,7 +575,7 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 255, 255);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 255, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'S');
|
||||
} else if (cell.type == SynthEngine::GridCell::ADSR_RELEASE) {
|
||||
// Draw Ramp Down
|
||||
@@ -590,7 +590,7 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 255, 255);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 255, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'E');
|
||||
} else if (cell.type == SynthEngine::GridCell::LPF || cell.type == SynthEngine::GridCell::HPF) {
|
||||
// Box
|
||||
@@ -608,10 +608,10 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
// Param
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param);
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param / 32767.0f);
|
||||
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);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 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
|
||||
@@ -629,10 +629,10 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
// Param
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param);
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param / 32767.0f);
|
||||
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);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 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};
|
||||
@@ -648,10 +648,10 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
// Param
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param);
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param / 32767.0f);
|
||||
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);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 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};
|
||||
@@ -666,10 +666,10 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
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);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param);
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param / 32767.0f);
|
||||
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);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 255, 100, 100);
|
||||
drawTypeLabel(renderer, x, y, 'X');
|
||||
} else if (cell.type == SynthEngine::GridCell::RECTIFIER) {
|
||||
SDL_Rect box = {cx - r, cy - r, r*2, r*2};
|
||||
@@ -684,7 +684,7 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
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);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 150, 0);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 255, 150, 0);
|
||||
drawTypeLabel(renderer, x, y, '|');
|
||||
} else if (cell.type == SynthEngine::GridCell::PITCH_SHIFTER) {
|
||||
drawString(renderer, cx - 8, cy - 5, 12, "PIT");
|
||||
@@ -697,7 +697,7 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
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);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 100, 255, 100);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 100, 255, 100);
|
||||
drawTypeLabel(renderer, x, y, '^');
|
||||
} else if (cell.type == SynthEngine::GridCell::GLITCH) {
|
||||
drawString(renderer, cx - 8, cy - 5, 12, "GLT");
|
||||
@@ -711,7 +711,7 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 0, 0);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 255, 0, 0);
|
||||
drawTypeLabel(renderer, x, y, 'G');
|
||||
} else if (cell.type == SynthEngine::GridCell::FORK) {
|
||||
// Draw Y shape based on rotation
|
||||
@@ -734,10 +734,10 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
drawDirectionArrow(renderer, cx, cy, size, rDir);
|
||||
|
||||
// Param (Balance)
|
||||
char buf[16]; snprintf(buf, 16, "%.1f", cell.param);
|
||||
char buf[16]; snprintf(buf, 16, "%.1f", cell.param / 32767.0f);
|
||||
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);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 0, 255, 0);
|
||||
drawTypeLabel(renderer, x, y, 'Y');
|
||||
} else if (cell.type == SynthEngine::GridCell::DELAY) {
|
||||
// Draw D
|
||||
@@ -756,11 +756,11 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
|
||||
// Param (Delay time in ms)
|
||||
char buf[16];
|
||||
float delay_ms = cell.param * 2000.0f; // Max 2 seconds
|
||||
float delay_ms = (cell.param / 32767.0f) * 2000.0f; // Max 2 seconds
|
||||
snprintf(buf, 16, "%.0fms", delay_ms);
|
||||
SDL_SetRenderDrawColor(renderer, 255, 128, 0, 255);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 128, 0);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 255, 128, 0);
|
||||
drawTypeLabel(renderer, x, y, 'D');
|
||||
} else if (cell.type == SynthEngine::GridCell::REVERB) {
|
||||
// Draw R
|
||||
@@ -777,10 +777,10 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+odx, cy+ody);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
// Param (Strength)
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param);
|
||||
char buf[16]; snprintf(buf, 16, "%.2f", cell.param / 32767.0f);
|
||||
SDL_SetRenderDrawColor(renderer, 200, 100, 255, 255);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 200, 100, 255);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 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};
|
||||
@@ -795,7 +795,7 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
|
||||
// Draw Op Symbol
|
||||
char opChar = '?';
|
||||
int opType = (int)(cell.param * 5.99f);
|
||||
int opType = (int)((cell.param / 32767.0f) * 5.99f);
|
||||
if (opType == 0) opChar = '+';
|
||||
else if (opType == 1) opChar = '*';
|
||||
else if (opType == 2) opChar = '-';
|
||||
@@ -803,7 +803,7 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
else if (opType == 4) opChar = '<';
|
||||
else if (opType == 5) opChar = '>';
|
||||
drawChar(renderer, cx - 15, cy - 15, 12, opChar);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 255, 255, 255);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 255, 255, 255);
|
||||
drawTypeLabel(renderer, x, y, 'M');
|
||||
} else if (cell.type == SynthEngine::GridCell::WAVETABLE) {
|
||||
drawString(renderer, cx - 5, cy - 5, 12, "W");
|
||||
@@ -816,12 +816,12 @@ void drawGridCell(SDL_Renderer* renderer, int x, int y, int size, SynthEngine::G
|
||||
SDL_RenderDrawLine(renderer, cx, cy, cx+dx, cy+dy);
|
||||
drawDirectionArrow(renderer, cx, cy, size, cell.rotation);
|
||||
// Param (Wave index)
|
||||
int idx = (int)(cell.param * 7.99f);
|
||||
int idx = (int)((cell.param / 32767.0f) * 7.99f);
|
||||
char buf[4];
|
||||
snprintf(buf, 4, "%d", idx);
|
||||
SDL_SetRenderDrawColor(renderer, 128, 128, 255, 255);
|
||||
drawString(renderer, x + 5, y + size - 18, 10, buf);
|
||||
drawParamBar(renderer, x, y, size, cell.param, 128, 128, 255);
|
||||
drawParamBar(renderer, x, y, size, cell.param / 32767.0f, 128, 128, 255);
|
||||
drawTypeLabel(renderer, x, y, 'W');
|
||||
}
|
||||
}
|
||||
@@ -864,9 +864,9 @@ void randomizeGrid() {
|
||||
|
||||
c.type = (SynthEngine::GridCell::Type)(rand() % numTypes);
|
||||
c.rotation = rand() % 4;
|
||||
c.param = (float)rand() / (float)RAND_MAX;
|
||||
c.value = 0.0f;
|
||||
c.phase = 0.0f;
|
||||
c.param = rand() % 32768;
|
||||
c.value = 0;
|
||||
c.phase = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -954,7 +954,7 @@ void randomizeGrid() {
|
||||
for (int y = 0; y < SynthEngine::GRID_H; ++y) {
|
||||
if (!visited[x][y]) {
|
||||
engine.grid[x][y].type = SynthEngine::GridCell::EMPTY;
|
||||
engine.grid[x][y].param = 0.5f;
|
||||
engine.grid[x][y].param = 16384;
|
||||
engine.grid[x][y].rotation = 0;
|
||||
}
|
||||
}
|
||||
@@ -969,8 +969,8 @@ void randomizeGrid() {
|
||||
engine.setFrequency(440.0f);
|
||||
bool soundDetected = false;
|
||||
for(int i=0; i<1000; ++i) {
|
||||
float val = engine.processGridStep();
|
||||
if (fabsf(val) > 0.001f) {
|
||||
int32_t val = engine.processGridStep();
|
||||
if (abs(val) > 10) {
|
||||
soundDetected = true;
|
||||
break;
|
||||
}
|
||||
@@ -983,7 +983,7 @@ void randomizeGrid() {
|
||||
// Reset values to avoid initial pop
|
||||
for (int x = 0; x < SynthEngine::GRID_W; ++x) {
|
||||
for (int y = 0; y < SynthEngine::GRID_H; ++y) {
|
||||
engine.grid[x][y].value = 0.0f;
|
||||
engine.grid[x][y].value = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -999,7 +999,7 @@ void randomizeGrid() {
|
||||
SynthEngine::GridCell& c = engine.grid[x][y];
|
||||
if (c.type != SynthEngine::GridCell::SINK) {
|
||||
c.type = SynthEngine::GridCell::EMPTY;
|
||||
c.param = 0.5f;
|
||||
c.param = 16384;
|
||||
c.rotation = 0;
|
||||
}
|
||||
}
|
||||
@@ -1207,7 +1207,7 @@ int main(int argc, char* argv[]) {
|
||||
c.rotation = (c.rotation + 1) % 4;
|
||||
} else if (e.button.button == SDL_BUTTON_MIDDLE) {
|
||||
newType = SynthEngine::GridCell::EMPTY;
|
||||
c.param = 0.5f;
|
||||
c.param = 16384;
|
||||
c.rotation = 0;
|
||||
}
|
||||
|
||||
@@ -1291,7 +1291,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
if (mx < GRID_PANEL_WIDTH) {
|
||||
// Grid Scroll
|
||||
float step = fineTune ? 0.01f : 0.05f;
|
||||
int32_t step = fineTune ? 327 : 1638; // ~0.01 and ~0.05
|
||||
int gx = mx / CELL_SIZE;
|
||||
int gy = my / CELL_SIZE;
|
||||
if (gx >= 0 && gx < SynthEngine::GRID_W && gy >= 0 && gy < SynthEngine::GRID_H) {
|
||||
@@ -1299,8 +1299,8 @@ int main(int argc, char* argv[]) {
|
||||
SynthEngine::GridCell& c = engine.grid[gx][gy];
|
||||
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;
|
||||
if (c.param > 32767) c.param = 32767;
|
||||
if (c.param < 0) c.param = 0;
|
||||
}
|
||||
} else {
|
||||
// Synth Scroll
|
||||
|
||||
Reference in New Issue
Block a user