From 6bf41392635dc1141752f9dd373df6970ae2829d Mon Sep 17 00:00:00 2001 From: Luxferre Date: Fri, 23 Oct 2026 15:30:29 +0300 Subject: [PATCH] fix(games): complete font (U/W + A-Z), fix Tetris gravity, frame + center overlays - Font: add missing glyphs (U, W and complete A-Z) to both Snake and Tetris 5x7 bitmap fonts so PAUSE/RESUME/NEW GAME render correctly. - Tetris: the gravity loop never advanced nextTick after a step, so the piece dropped almost instantly every frame. Advance nextTick by speed after each step (matching Snake) so gravity honours the configured rate. - Both: draw a 1px frame around the whole 240x296 window (right/bottom edges were previously absent) and clear the playfield to black behind PAUSE/GAME OVER text for contrast. - Both: fix centering of overlay labels (GAME OVER, 5 RESUME, 5 NEW GAME). --- overlay/rootfs/usr/bin/snake | Bin 13672 -> 13672 bytes overlay/rootfs/usr/bin/tetris | Bin 13668 -> 13668 bytes prebuilt/games/usr/bin/snake | Bin 13672 -> 13672 bytes prebuilt/games/usr/bin/tetris | Bin 13668 -> 13668 bytes src/games/snake.cpp | 20 ++++++++++++++++---- src/games/tetris.cpp | 30 +++++++++++++++++++++++------- 6 files changed, 39 insertions(+), 11 deletions(-) diff --git a/overlay/rootfs/usr/bin/snake b/overlay/rootfs/usr/bin/snake index 6207e5fbf01d831085ea095fbd8356597690276a..8b4621c83f9298570e2b058c4ac5a7952a0b0a5f 100755 GIT binary patch delta 1091 zcmYL}ZA@EL7{{M;+cI7{ysd*y3Z*ZAyqHy5HKi;Wu$zvxWwlNrGy#Dr+#HsahgH0g-Mh7f}>@r!}27>&##)vUGF%NM=d#9N<&FDLose@^nx z^K#xYLPnT$l)Y;L*k!8Qr%K`?IrUNEz*pXvSKjz}d9`)+kHyQ0dx`7o`_9BeB&r}| z@w>|LGD71oR=!n2JXBTn=>wx$fM*b;9pEtPBS_Q+@GD)fvXUrORnL;e_y^TG!Z^$6 zXF40X7tiag3~8ZtH8gTn1u*B{UZAl#FEoX@%bvNu3GU|LdG4Z+%P`fLcEhR8hkc^qFU7sxNh{-IY80O7>=3!=%X(v;}32&3mEq~ElkWT&Q z%!n{!cdciE-7@-#gLE*HWNOdk&G`KBo~rN7fnsu5x^(>;!Yl#`$GPH?_a(n;D(-wn8-ae!9T)(NIou?M+WBFDP_P&UptAI&cxLpQ zEZB(ExTeV6Jjdj2oE>DH9)sf~%b3Tx$_}8G(Sr1zj4qNEoGy}E8-v_x(B?hf%T92W z?OiOqa}bNXAkW=qte5@`Gv;&+vaO!S9LL%J!-VA~Y}6OnYxV2jU>d_RX}Vln6*(=} z_TtJE;?lxyl1VHkNX(jUwtIiO0W&-ykKUH0*Tta*fKVgeO8{`7Uchw?>LTh0Vp9Or zA`LkI)&ihK{n89DgYz&0@Ep>MsF7+Um2YZGIr0y7rt-}dseFsR)kDm|h1X)^oYK^c z7x3uaRO?D!S+SBY(NA!%S{nKqd%wss+Vfn9v(Pu|bQS%7y>PnS#k*ulP3P-$O$O2D zFX0Zj?Od1(Jg@N-&qnpn*^sr8Sa3;}v?ATEGnzAI>;mDDp5kl6u6B$7WC50!GNdbb zEbcTI7^9oPq1CESR%$ewD((IO6daX9^^CHVW$Wpnar4p5UkZ`=Bdt;8?}Z4#KtD-^ zNbHI#diW0Ne0g-IsMoa7jXzPZs-jnR&=(&w9Z^&Dp@;A(cO3eVp!{eJD99b!XRlWU l4FEwpX1A0_aaQD@g1&DzsCNGd`nlbrTE((g<5_!z{0;fyn|=TQ delta 1026 zcmYL|ZA@Eb6vxkV`=VtV-ZDEJg|07jl(Ll3GE?ja%e<-3mXXCboP5|;mfW_J6}B1D z*0q{xOne#ej4w`?Oh5QC4b@6CvKMul>?64PMF&NexHh%BMA19ad9SBn;*3DkRq4LmzN-$P5mCAT?r8y5k+c)w6Z(^`op`Bg+c`3py|AsG zFh6VP*Y!^FcD7vK&fxD&4Kx)|0ZjT=W@u(I80RJfN$$o#u6Q5&UPRApY5xi+WRWer z8AxykcxF=16ABif%i&z{ej! zgu>9K`^6mH@c$+l`NQE`^eMew`-c$gPjRz6wAmJp?E~vE`jTExuF!Y&t)A<`EPrwD z&6|Tk&8LHYqbbSRd~q%mmBdj2ril4ggfT7gvZ$5ck3!o63s0h_>X5|4lr(N_lBB-= zeZdr$_uHf zeFJ$&0l*-s9t>)bRSSRvb=eGXngNI*Pa_RTGmp z;FPA;Anbf>EpNY8R&KghR_l}8%NA?j&Ytg!Ox=sz7}wl;XQ+EX!>cCnU5WWn=#b;c za7Y$U{xj?t>hSSCNpuQuzJE1-92r$q)PFA&83GnbR(;wG@CEV~PEfVo9#k>|S1%WcH}*Jgtgmd`U|{H1#-%;plAM};)Se#t zOHL6yD_WN4pjhstKam!=~wON|%5s@!Ghd6z-8KH~ISmqiuB%3|4~D@FbV%`JW| diff --git a/overlay/rootfs/usr/bin/tetris b/overlay/rootfs/usr/bin/tetris index e434bbe439bccc790eba1bbde0598930a71bb9e8..d893b1fa2909db5f1f27f9dcc452cdcfc2e0402f 100755 GIT binary patch delta 4870 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 delta 4759 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 delta 1026 zcmYL|ZA@Eb6vxkV`=VtV-ZDEJg|07jl(Ll3GE?ja%e<-3mXXCboP5|;mfW_J6}B1D z*0q{xOne#ej4w`?Oh5QC4b@6CvKMul>?64PMF&NexHh%BMA19ad9SBn;*3DkRq4LmzN-$P5mCAT?r8y5k+c)w6Z(^`op`Bg+c`3py|AsG zFh6VP*Y!^FcD7vK&fxD&4Kx)|0ZjT=W@u(I80RJfN$$o#u6Q5&UPRApY5xi+WRWer z8AxykcxF=16ABif%i&z{ej! zgu>9K`^6mH@c$+l`NQE`^eMew`-c$gPjRz6wAmJp?E~vE`jTExuF!Y&t)A<`EPrwD z&6|Tk&8LHYqbbSRd~q%mmBdj2ril4ggfT7gvZ$5ck3!o63s0h_>X5|4lr(N_lBB-= zeZdr$_uHf zeFJ$&0l*-s9t>)bRSSRvb=eGXngNI*Pa_RTGmp z;FPA;Anbf>EpNY8R&KghR_l}8%NA?j&Ytg!Ox=sz7}wl;XQ+EX!>cCnU5WWn=#b;c za7Y$U{xj?t>hSSCNpuQuzJE1-92r$q)PFA&83GnbR(;wG@CEV~PEfVo9#k>|S1%WcH}*Jgtgmd`U|{H1#-%;plAM};)Se#t zOHL6yD_WN4pjhstKam!=~wON|%5s@!Ghd6z-8KH~ISmqiuB%3|4~D@FbV%`JW| diff --git a/prebuilt/games/usr/bin/tetris b/prebuilt/games/usr/bin/tetris index e434bbe439bccc790eba1bbde0598930a71bb9e8..d893b1fa2909db5f1f27f9dcc452cdcfc2e0402f 100755 GIT binary patch delta 4870 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 delta 4759 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 0) { XSetForeground(dpy, gc, C_FOOD); @@ -233,14 +241,18 @@ static void render() { draw_text(gx0 + gw - 11 * 6, 2, 1, C_DIM, buf); } + if (state == PAUSED || state == GAMEOVER) { + XSetForeground(dpy, gc, C_BG); + XFillRectangle(dpy, back, gc, 0, 0, winW, winH); + } if (state == PAUSED) { - draw_text(winW / 2 - 3 * 6 * 2, winH / 2 - 7 * 2, 2, C_FG, "PAUSE"); - draw_text(winW / 2 - 5 * 6, winH / 2 + 7 * 2, 1, C_DIM, "5 RESUME"); + draw_text(winW / 2 - 5 * 6, winH / 2 - 7 * 2, 2, C_FG, "PAUSE"); + draw_text(winW / 2 - 4 * 6, winH / 2 + 7 * 2, 1, C_DIM, "5 RESUME"); } else if (state == GAMEOVER) { - draw_text(winW / 2 - 4 * 6 * 2, winH / 2 - 14, 2, C_FG, "GAME OVER"); + draw_text(winW / 2 - 9 * 6, winH / 2 - 14, 2, C_FG, "GAME OVER"); snprintf(buf, sizeof(buf), "SCORE %d", score); draw_text(winW / 2 - 5 * 6, winH / 2 + 4, 1, C_DIM, buf); - draw_text(winW / 2 - 9 * 6, winH / 2 + 4 + 9, 1, C_DIM, "5 NEW GAME"); + draw_text(winW / 2 - 5 * 6, winH / 2 + 4 + 9, 1, C_DIM, "5 NEW GAME"); } XCopyArea(dpy, back, win, gc, 0, 0, winW, winH, 0, 0); diff --git a/src/games/tetris.cpp b/src/games/tetris.cpp index d72015c..cd130a1 100644 --- a/src/games/tetris.cpp +++ b/src/games/tetris.cpp @@ -27,7 +27,7 @@ static const int WIN_W = 240; static const int WIN_H = 296; static const int PCOLS = 10; static const int PROWS = 20; -static const int CELL = 12; +static const int CELL = 14; // ---- 5x7 bitmap font ---- struct Glyph { char ch; unsigned char r[7]; }; @@ -56,6 +56,13 @@ static const Glyph GLYPHS[] = { {'V', {0b10001,0b10001,0b10001,0b10001,0b10001,0b01010,0b00100}}, {'X', {0b10001,0b10001,0b01010,0b00100,0b01010,0b10001,0b10001}}, {'Y', {0b10001,0b10001,0b01010,0b00100,0b00100,0b00100,0b00100}}, + {'D', {0b11110,0b10001,0b10001,0b10001,0b10001,0b10001,0b01110}}, + {'J', {0b00010,0b00010,0b00010,0b00010,0b10010,0b10010,0b01100}}, + {'K', {0b10001,0b10010,0b10100,0b11000,0b10100,0b10010,0b10001}}, + {'Q', {0b01110,0b10001,0b10001,0b10001,0b10101,0b10010,0b01101}}, + {'U', {0b10001,0b10001,0b10001,0b10001,0b10001,0b10001,0b01110}}, + {'W', {0b10001,0b10001,0b10001,0b10101,0b10101,0b11011,0b10001}}, + {'Z', {0b11111,0b00010,0b00100,0b01000,0b10000,0b10000,0b11111}}, {'0', {0b01110,0b10011,0b10101,0b10101,0b11001,0b10001,0b01110}}, {'1', {0b00100,0b01100,0b00100,0b00100,0b00100,0b00100,0b01110}}, {'2', {0b01110,0b10001,0b00001,0b00110,0b01000,0b10000,0b11111}}, @@ -101,7 +108,7 @@ static int board[PCOLS][PROWS]; // 0 empty, else type+1 static int curType = 0, curRot = 0, curX = 3, curY = 0; static int nextType = 0; static int score = 0, best = 0, lines = 0, level = 1; -static int speed = 800; // ms per gravity step +static int speed = 1000; // ms per gravity step static unsigned long nextTick = 0; static bool running = true; @@ -176,7 +183,7 @@ static void lock_piece() { score += pts[cleared] * level; if (score > best) best = score; int nl = 1 + lines / 10; - if (nl != level) { level = nl; speed = 800 - (level - 1) * 40; if (speed < 250) speed = 250; } + if (nl != level) { level = nl; speed = 1000 - (level - 1) * 40; if (speed < 300) speed = 300; } } spawn(); } @@ -250,6 +257,10 @@ static void render() { XSetForeground(dpy, gc, C_DIM); XDrawRectangle(dpy, back, gc, px0 - 1, py0 - 1, PCOLS * CELL + 2, PROWS * CELL + 2); + // frame the whole window (right/bottom edges too) + XSetForeground(dpy, gc, C_DIM); + XDrawRectangle(dpy, back, gc, 0, 0, winW - 1, winH - 1); + // settled blocks for (int x = 0; x < PCOLS; x++) for (int y = 0; y < PROWS; y++) @@ -298,13 +309,17 @@ static void render() { snprintf(buf, sizeof(buf), "LEVEL %d", level); draw_text(sx, ty + 18, 1, C_DIM, buf); if (best > 0) { snprintf(buf, sizeof(buf), "BEST %d", best); draw_text(sx, ty + 27, 1, C_DIM, buf); } + if (state == PAUSED || state == GAMEOVER) { + XSetForeground(dpy, gc, C_BG); + XFillRectangle(dpy, back, gc, 0, 0, winW, winH); + } if (state == PAUSED) { - draw_text(winW / 2 - 3 * 6 * 2, winH / 2 - 7, 2, C_FG, "PAUSE"); - draw_text(winW / 2 - 5 * 6, winH / 2 + 10, 1, C_DIM, "5 RESUME"); + draw_text(winW / 2 - 5 * 6, winH / 2 - 7, 2, C_FG, "PAUSE"); + draw_text(winW / 2 - 4 * 6, winH / 2 + 10, 1, C_DIM, "5 RESUME"); } else if (state == GAMEOVER) { - draw_text(winW / 2 - 5 * 6 * 2, winH / 2 - 14, 2, C_FG, "GAME OVER"); + draw_text(winW / 2 - 9 * 6, winH / 2 - 14, 2, C_FG, "GAME OVER"); snprintf(buf, sizeof(buf), "SCORE %d", score); draw_text(winW / 2 - 5 * 6, winH / 2 + 4, 1, C_DIM, buf); - draw_text(winW / 2 - 9 * 6, winH / 2 + 13, 1, C_DIM, "5 NEW GAME"); + draw_text(winW / 2 - 5 * 6, winH / 2 + 13, 1, C_DIM, "5 NEW GAME"); } XCopyArea(dpy, back, win, gc, 0, 0, winW, winH, 0, 0); @@ -441,6 +456,7 @@ int main() { } if (running && now_ms() >= nextTick) { if (state == PLAYING) step(); + if (state == PLAYING) nextTick = now_ms() + speed; else nextTick = now_ms() + 80; render(); }