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