diff --git a/Firmware/main/src/hello_world_main.cpp b/Firmware/main/src/hello_world_main.cpp index a6b92a0..40adb6c 100644 --- a/Firmware/main/src/hello_world_main.cpp +++ b/Firmware/main/src/hello_world_main.cpp @@ -343,10 +343,20 @@ public: // HUD int hudX = ox + bw + 16; int yHUD = oy + 9; - drawLabel(hudX, yHUD, "SCORE"); yHUD += 12; drawNumber(hudX, yHUD, score); yHUD += 19; - drawLabel(hudX, yHUD, "LEVEL"); yHUD += 12; drawNumber(hudX, yHUD, level); yHUD += 19; - drawLabel(hudX, yHUD, "LINES"); yHUD += 12; drawNumber(hudX, yHUD, lines); yHUD += 19; - drawLabel(hudX, yHUD, "NEXT"); yHUD += 7; + drawLabel(hudX, yHUD, "SCORE"); + yHUD += 12; + drawNumber(hudX, yHUD, score); + yHUD += 19; + drawLabel(hudX, yHUD, "LEVEL"); + yHUD += 12; + drawNumber(hudX, yHUD, level); + yHUD += 19; + drawLabel(hudX, yHUD, "LINES"); + yHUD += 12; + drawNumber(hudX, yHUD, lines); + yHUD += 19; + drawLabel(hudX, yHUD, "NEXT"); + yHUD += 7; const int p = cfg::CellPx; const int nx = hudX, ny = yHUD + 4; @@ -367,7 +377,8 @@ public: rect(x0, y0, p, p, true); // outer border int ix0 = x0 + 1, iy0 = y0 + 1; int w = p - 2, h = p - 2; - if (w <= 0 || h <= 0) return; + if (w <= 0 || h <= 0) + return; for (int yy = 0; yy < h; ++yy) for (int xx = 0; xx < w; ++xx) if (patternOn(type, w, h, xx, yy)) @@ -381,7 +392,8 @@ public: int p = cfg::CellPx; rect(x0, y0, p, p, true); int ix0 = x0 + 1, iy0 = y0 + 1, w = p - 2, h = p - 2; - if (w <= 0 || h <= 0) return; + if (w <= 0 || h <= 0) + return; for (int yy = 0; yy < h; ++yy) for (int xx = 0; xx < w; ++xx) if (patternOn(type, w, h, xx, yy)) @@ -401,12 +413,17 @@ private: int offset = ((w - 1) % spacing) / 2; // distributes leftover space equally return ((xx - offset) % spacing) == 0; } - case 2: return (yy < h / 2) || (xx == 0); // J - case 3: return (yy >= h / 2) || (xx == w - 1); // L - case 4: return (((xx + yy) & 1) == 0); // O - case 5: return (((xx + yy) % 3) == 0); // S - case 6: return ((((xx - yy) % 3) + 3) % 3 == 0); // Z - case 7: { // T — centered diamond (handles even dimensions without bias) + case 2: + return (yy < h / 2) || (xx == 0); // J + case 3: + return (yy >= h / 2) || (xx == w - 1); // L + case 4: + return (((xx + yy) & 1) == 0); // O + case 5: + return (((xx + yy) % 3) == 0); // S + case 6: + return ((((xx - yy) % 3) + 3) % 3 == 0); // Z + case 7: { // T — centered diamond (handles even dimensions without bias) bool evenW = (w % 2) == 0; bool evenH = (h % 2) == 0; int dx, dy, radius; @@ -433,13 +450,20 @@ private: } return (dx + dy) <= radius; } - default: return false; + default: + return false; } } void putPixel(int x, int y, bool on) { fb.drawPixel(x, y, on); } - void hline(int x, int y, int w, bool on) { for (int i = 0; i < w; ++i) putPixel(x + i, y, on); } - void vline(int x, int y, int h, bool on) { for (int i = 0; i < h; ++i) putPixel(x, y + i, on); } + void hline(int x, int y, int w, bool on) { + for (int i = 0; i < w; ++i) + putPixel(x + i, y, on); + } + void vline(int x, int y, int h, bool on) { + for (int i = 0; i < h; ++i) + putPixel(x, y + i, on); + } void rect(int x, int y, int w, int h, bool on) { hline(x, y, w, on); hline(x, y + h - 1, w, on); @@ -447,8 +471,16 @@ private: vline(x + w - 1, y, h, on); } - void dashedH(int x, int y, int w, bool on) { for (int i = 0; i < w; ++i) if ((i & 1) == 0) putPixel(x + i, y, on); } - void dashedV(int x, int y, int h, bool on) { for (int i = 0; i < h; ++i) if ((i & 1) == 0) putPixel(x, y + i, on); } + void dashedH(int x, int y, int w, bool on) { + for (int i = 0; i < w; ++i) + if ((i & 1) == 0) + putPixel(x + i, y, on); + } + void dashedV(int x, int y, int h, bool on) { + for (int i = 0; i < h; ++i) + if ((i & 1) == 0) + putPixel(x, y + i, on); + } void drawGhost(const Board& b, int px, int py, int prot, int pidx) { // Determine landing position (same as before) @@ -459,41 +491,50 @@ private: for (int xx = 0; xx < 4; ++xx) if (cell_of(TET[pidx], prot, xx, yy)) { int nx = px + xx, ny = gy + yy + 1; - if (ny >= cfg::BoardH || (ny >= 0 && nx >= 0 && nx < cfg::BoardW && b.get(nx, ny))) { col = true; break; } + if (ny >= cfg::BoardH || (ny >= 0 && nx >= 0 && nx < cfg::BoardW && b.get(nx, ny))) { + col = true; + break; + } } - if (col) break; + if (col) + break; ++gy; } // Build occupancy mask of the piece (4x4 local) bool occ[4][4] = {}; - int minCol = 4, maxCol = -1, minRow = 4, maxRow = -1; + int minCol = 4, maxCol = -1, minRow = 4, maxRow = -1; for (int yy = 0; yy < 4; ++yy) for (int xx = 0; xx < 4; ++xx) if (cell_of(TET[pidx], prot, xx, yy)) { occ[yy][xx] = true; - minCol = std::min(minCol, xx); maxCol = std::max(maxCol, xx); - minRow = std::min(minRow, yy); maxRow = std::max(maxRow, yy); + minCol = std::min(minCol, xx); + maxCol = std::max(maxCol, xx); + minRow = std::min(minRow, yy); + maxRow = std::max(maxRow, yy); } - if (maxCol < 0) return; // nothing + if (maxCol < 0) + return; // nothing int psize = cfg::CellPx; auto drawHorizRun = [&](int boardY, int boardXCellStart, int cells, bool topEdge) { - int yPix = oy + boardY * psize + (topEdge ? 0 : (psize - 1)); - int xPixStart = ox + boardXCellStart * psize; + int yPix = oy + boardY * psize + (topEdge ? 0 : (psize - 1)); + int xPixStart = ox + boardXCellStart * psize; int totalPixels = cells * psize; for (int i = 0; i < totalPixels; ++i) { int xPix = xPixStart + i; // Parity-based sparse edge: ensures corners never double-thicken - if (((xPix + yPix) & 1) == 0) putPixel(xPix, yPix, true); + if (((xPix + yPix) & 1) == 0) + putPixel(xPix, yPix, true); } }; auto drawVertRun = [&](int boardX, int boardYCellStart, int cells, bool leftEdge) { - int xPix = ox + boardX * psize + (leftEdge ? 0 : (psize - 1)); - int yPixStart = oy + boardYCellStart * psize; + int xPix = ox + boardX * psize + (leftEdge ? 0 : (psize - 1)); + int yPixStart = oy + boardYCellStart * psize; int totalPixels = cells * psize; for (int i = 0; i < totalPixels; ++i) { int yPix = yPixStart + i; - if (((xPix + yPix) & 1) == 0) putPixel(xPix, yPix, true); + if (((xPix + yPix) & 1) == 0) + putPixel(xPix, yPix, true); } }; @@ -501,66 +542,84 @@ private: for (int r = minRow; r <= maxRow; ++r) { int c = minCol; while (c <= maxCol) { - if (occ[r][c] && (r == minRow || !occ[r-1][c])) { - int runStart = c; int end = c; - while (end <= maxCol && occ[r][end] && (r == minRow || !occ[r-1][end])) ++end; + if (occ[r][c] && (r == minRow || !occ[r - 1][c])) { + int runStart = c; + int end = c; + while (end <= maxCol && occ[r][end] && (r == minRow || !occ[r - 1][end])) + ++end; drawHorizRun(gy + r, px + runStart, end - runStart, true); c = end; - } else ++c; + } else + ++c; } } // Horizontal bottom edges for (int r = minRow; r <= maxRow; ++r) { int c = minCol; while (c <= maxCol) { - if (occ[r][c] && (r == maxRow || !occ[r+1][c])) { - int runStart = c; int end = c; - while (end <= maxCol && occ[r][end] && (r == maxRow || !occ[r+1][end])) ++end; + if (occ[r][c] && (r == maxRow || !occ[r + 1][c])) { + int runStart = c; + int end = c; + while (end <= maxCol && occ[r][end] && (r == maxRow || !occ[r + 1][end])) + ++end; drawHorizRun(gy + r, px + runStart, end - runStart, false); c = end; - } else ++c; + } else + ++c; } } // Vertical left edges for (int c = minCol; c <= maxCol; ++c) { int r = minRow; while (r <= maxRow) { - if (occ[r][c] && (c == minCol || !occ[r][c-1])) { - int runStart = r; int end = r; - while (end <= maxRow && occ[end][c] && (c == minCol || !occ[end][c-1])) ++end; + if (occ[r][c] && (c == minCol || !occ[r][c - 1])) { + int runStart = r; + int end = r; + while (end <= maxRow && occ[end][c] && (c == minCol || !occ[end][c - 1])) + ++end; drawVertRun(px + c, gy + runStart, end - runStart, true); r = end; - } else ++r; + } else + ++r; } } // Vertical right edges for (int c = minCol; c <= maxCol; ++c) { int r = minRow; while (r <= maxRow) { - if (occ[r][c] && (c == maxCol || !occ[r][c+1])) { - int runStart = r; int end = r; - while (end <= maxRow && occ[end][c] && (c == maxCol || !occ[end][c+1])) ++end; + if (occ[r][c] && (c == maxCol || !occ[r][c + 1])) { + int runStart = r; + int end = r; + while (end <= maxRow && occ[end][c] && (c == maxCol || !occ[end][c + 1])) + ++end; drawVertRun(px + c, gy + runStart, end - runStart, false); r = end; - } else ++r; + } else + ++r; } } } void drawChar5x7(int x, int y, char c, bool on) { uint8_t gi = Font5x7::glyph(c); - if (gi == 255) return; + if (gi == 255) + return; for (int col = 0; col < 5; ++col) { uint8_t bits = Font5x7::data[gi][col]; for (int row = 0; row < 8; row++) - if (bits & (1u << row)) putPixel(x + col, y + row, on); + if (bits & (1u << row)) + putPixel(x + col, y + row, on); } } - void drawLabel(int x, int y, const char* s) { for (int i = 0; s[i]; ++i) drawChar5x7(x + i * 6, y, s[i], true); } + void drawLabel(int x, int y, const char* s) { + for (int i = 0; s[i]; ++i) + drawChar5x7(x + i * 6, y, s[i], true); + } void drawNumber(int x, int y, int n) { char buf[16]; int len = snprintf(buf, sizeof(buf), "%d", n); - for (int i = 0; i < len; ++i) drawChar5x7(x + i * 6, y, buf[i], true); + for (int i = 0; i < len; ++i) + drawChar5x7(x + i * 6, y, buf[i], true); } };