From ff29160461ddd20a45101286f20886c41eb39662 Mon Sep 17 00:00:00 2001 From: Luxferre Date: Sat, 24 Oct 2026 09:36:38 +0300 Subject: [PATCH] games: fix input/rendering lag and missed keypresses Identified and fixed rendering/input optimization issues: - Snake: added turn queue (max 2 pending turns) so rapid key presses are never lost; filters reversals and duplicates against the last queued direction. Batched snake body rendering into a single XFillRectangles call instead of one XFillRectangle per segment. - Tetris: batched settled-block rendering into 3 XFillRectangles calls (body, highlight, shadow) instead of 5 XFillRectangle calls per cell. This reduces ~1000 X11 calls per frame to 3, fixing frame drops and input lag. - Both: non-blocking input polling before every frame (already in place) ensures no keypress is missed. --- overlay/rootfs/usr/bin/snake | Bin 13672 -> 13716 bytes overlay/rootfs/usr/bin/tetris | Bin 17764 -> 17812 bytes prebuilt/games/usr/bin/snake | Bin 13672 -> 13716 bytes prebuilt/games/usr/bin/tetris | Bin 17764 -> 17812 bytes src/games/snake.cpp | 58 ++++++++++++++++++++++++++-------- src/games/tetris.cpp | 27 ++++++++++++++-- 6 files changed, 69 insertions(+), 16 deletions(-) diff --git a/overlay/rootfs/usr/bin/snake b/overlay/rootfs/usr/bin/snake index 5eda79de33fe22c92b27880aaf808f1fced3fc11..7961641a7da94344f06e699c60f5ad26e317c4c1 100755 GIT binary patch delta 6136 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 delta 5572 zcmcgw3s6*7w%xZs(tN~jnxC{ve?a~M4I0!Wws>v%J)4v`G84<;V@x-Ygow`|5*mM# zWX6f;(G;I#N<~xn1ANAmrDGs!GLngT5P5IRM5l=;(C~m3k$VZ+_wCa_hDy~`y_%_d zw`%p;=k9&>Id`9ZZtr^z7xooY1x88(01^QpJ05=|AWZ}{xI;Ju!CYVfid!`RlQ@{1 z_rfT)D5Pi%a-bFyDqh5}B`N1DHC}tY-*qbM*jLP?N-0|pJ zF?@z&O#Hf+BYT0PW-hv*9!j zYq_vgdXXW{S?%PZ+g6e-dyzEDJbuC@nLP9g+GCJi*ZPG!JgI}fO$|&Vj)4X*GAP?< zT?i1e0>EDa5KbB66-^n}A&#;eE;3~qKoVtlfafV={0x-QHA~qGAcgX5fDFps0GX8M z0Ax|d*<@43SZ$=N1js?Q`uhTGrZ@Zm%#?9zMU(?Eg(%Mj*hV=Bpp>!-pq%nNfJ(~q z0rpZ326&gU8el(V4dxSNEx=*QI)G}*Apjpz4h1;60<7R425^Gj2nT4O9072aawI@A zt4y!iYCMg8!u1ou#5HOta!O< z*{`E+*g=1{B}b>r`E{h>@v}YenIYtso$Q_MYrUHyaF>Q`{GD*dSk9KQU6$O<0+%){ za3RA|WAS+#-?^Sur4$nz+0(WyL z%ABP2J)}2!6FDg~&mjsj_sqRPZ_j&!auw~gYW#qQz%`<4L*O!WO&zBUDXUiD1eK?| zEG9>$OyEX_a*LLub{S6buR}+3yDWLHVRYhT6QYEd3xNEW9dx-x0yj3K&a;}v5=y!( zts@EIyw|$(sab9jHB1>{M0JI&BO+0Lo@uP6q;;f5T%T_m+k(;-ad%$oSS(7h;`%(g zD0Ff(D&TnV6dYRxaQHa8ElZ7Y#yYc%2wdk-WQA|tJ-a^xks0ka{@u4sqh(uhsk|nv zEa+%M;JS!vPH@!n`M2zz-8MdR4dNZdhH{o?-^TC@+^0iyy~B2OS;9^UTp)RMPOMe- z+)h?i0a4#|*mzh|&UV^o$px-qu+#3w&}EpM+HZ$we;G!uYauSok}~#oc91!>?pFqy zWd=vw9#E$@U+r@ou<e^nH=qS$Dev*>mtl? zTWWuoEa|YA4<^f6qAIT7vsHaC&bDE~f#ZdzHGE(kMD6c5-wO`&vuamsU&rZQ(5*QI zM5a}eum{g`w($n_w3ScO611ug1$7xK&t=rg3LC#a6!+X_^kE$pH-(|PGSuV{ z;-~?*47N=hj6QA*K)rdYJGG(?HvXjVZgfL^W+>xwKiNCwCv9gV-(%yS-?z)ivy)L< zG3sb!FrNgjXwa9OSNK^g26eAV*)z%RcXUO752@Rgsk8Aglq`uJJHnnd;M zc#YhX4O{~)C!K=u1>zy%9mJ|B#Nr?CwEWNTKkRRvF~~pT_+Ra_Cinj^fuBdkG^WA` zT1S7|*p@yS?R(_U$_S=`JW;Bx9|Ymr?j9KLxnmdWI{A#&+nD+%D%bUUG2p1JJeP*s zJcs^X<5ODCrk%|wW6RlZd0D0Gkq{3NrvA^pv-o)RHde`QHj5txialyKv%4q6YR_89 zqj{3u6Ow3CfA`jF14l(BMVHsda?BIA4p^h*;t9FI@c3M%*N5UR_eYF- z>T0j{4gAu$+GMUH3%NS^aYt3Uh~~-W_j=yXC}(w++T{H9->2_n#RH#9ZV!q)SB>9u z`!IRD<2}5$3a3-TX6H;M|o@tL^eXh-g>>Y-^&<_hCy=k&d=XXI$h*}NQqdv-->EW+q~ zi_zKAd#q^Q05iurx}j;mQEA+SZ!G_(uh8LLUOLb65ArS5$<-Z~o`hQyzt5R5*-dGi zGRpjEXzgC{9tpooP8kV)>1NBid}aPGNt<7=wX{Dx{8CG}Iwuz#AB~swu64zM;JUui zlyBLCT-cQ6a+st}O%o5?6qjKPWRDmz$+_Mua9IPZ(^cBlDU7B&yOdR#1@6m!2J3+P z{m_z!<|@NnMY`Surftl)?@AEP=E`WsQ3iszhUi^hVVjoAZ}nyHHtWa zHC6+%j~w6^$cc!L@!m$nyND%-5JVP2f=ER4V14F`{3Y@jq5*Lf;f44SYq+799DoWe z>bwyw!ij}m74kLY%Lp0DqsZ?f3G|ZxCN0A`v(6$v3)_ zWdT8qldKO|tX$A9ZHB9TSZj8osugjQd=wBoyAi9-vxuXpX(w#~VYByQYd4|@?>r#S z0)nmg?E=>#c%*k{tIoTplwxsFYG<@ET$rF@`BiAiMC)XDT{Xer`?UNbs|E^^S>;EpacVPd^*hia|Hg+cZ+SuvnZ8B2nh!7KVV1)*yi8Pg37;mz}`*_hI!Fcif^WkSu42BuP{y(gC5h zNm-xH0#Sb7-=DICKDAkEwbYw&LLi!egoox%yEIQzFlz$VV^w)X;Jo|FOjh=a8KT1P zm9B-*(u@k+gpwu4EX?vV$zsD+cO81A$)^7;Zy8djo#BgshuCpb6I-Co2jXQDLUtxto{^{&_OOXhlu z_@IwjbSSTg4t&clS&xq37gY zA1=XQi%5c5Q$RzGks(fQ_i$Lze`5{C#Hu^Q1Gh^=1K)1VmM=?Rko1zAzKp$>0_iRk zxbsf5V(JT)8JU5OH({W?Sf7z9FK4~u4RSafm}C{Wqt27PqS*RrH*YR8X3Hbfmn5ai z|L*2}=R%Buu5dC6Plw(h!H1A}w+IcH}Eu&pEZi}p7Av89{HW=<{ z8;nquvgdQ6GpsSGoy^N9Gagpa?$7Wv9)^q z+w}Q9;QD}886Ji2dR5`5hlV!GYq>;NTnqfzcgC1 z>0a?kr!~2BYN?qHw`PaiRVSA?3@t>iR{Q(nV{O&q*ExQ1S0mG~cxZ@Gt-VmGHi%>T z`UPv#3XjU?p9oegq9BkLtj$fb%Da@$_*7O+P@Yv;`V{pSm=LkY1$juI$f^khXv5P0 z+NTM_M46szP;Nu^LbiAS9*O|aBN99)aGfUM0RbLI0iHvl4W4!2L4m9N#3{T{g`M%0 z0U`J^3;7dlqYLOkf1b$r{{narL9c~)D1?*6FL%^|84dBI0u%^(c!DQgF1ebVS`?-z zl>rEX@CKcl1KET8uqeSwkFKV#Z8*yRGdBFo1D>KG#*0RG`m%VCT(#2IfDekd!tse| ztm%U@L=o3VB=MDGSNs8{m?-qY9yHDrJtDG9zrfuC<3#Z~$<+r-Y1B%|KD|y_jZ!r^ zr`IWHTq$V0sbgRAgFZk?kL}FlnO^5U9m6;hkr2G70Vhati7w03g|1vz8UE5~(PhrT z2gq4KoO*w{Rr=PlV2w4 z6sJ&{gP`d_^UI68kQku2h%Gu4z3V!&B)?A#@cRr~bQ0646o>^$A6c2G^t(Po0|snh zNi(00w6qNy^dV>;wE^#+R`5OfFjcV65pTsN<@cRqO*t2-*CM-quV)A*s Pk`yhLOJB!UFKzuV_(0r{ diff --git a/overlay/rootfs/usr/bin/tetris b/overlay/rootfs/usr/bin/tetris index a1a0738aafbb59fe7ea15a1410314c13bec8bb16..770f32c32224e8e5a7c4e208adc5251590cbc6fc 100755 GIT binary patch delta 4694 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 delta 4176 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 delta 5572 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 Pk`yhLOJB!UFKzuV_(0r{ diff --git a/prebuilt/games/usr/bin/tetris b/prebuilt/games/usr/bin/tetris index a1a0738aafbb59fe7ea15a1410314c13bec8bb16..770f32c32224e8e5a7c4e208adc5251590cbc6fc 100755 GIT binary patch delta 4694 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 delta 4176 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 0) ? tqx[tqn - 1] : dirx; + int refy = (tqn > 0) ? tqy[tqn - 1] : diry; + if (dx == -refx && dy == -refy) return; // reversal + if (dx == refx && dy == refy) return; // duplicate + if (tqn < 2) { + tqx[tqn] = dx; + tqy[tqn] = dy; + tqn++; + } +} + static void step() { - // apply buffered direction (no reversing); latest keypress wins - if (!(ndirx == -dirx && ndiry == -diry) && !(ndirx == 0 && ndiry == 0)) { - dirx = ndirx; diry = ndiry; + // apply queued turn (no reversing); rapid presses are not lost + if (tqn > 0) { + int dx = tqx[0], dy = tqy[0]; + // shift queue + tqx[0] = tqx[1]; tqy[0] = tqy[1]; + tqn--; + // apply if not a reversal + if (!(dx == -dirx && dy == -diry) && !(dx == 0 && dy == 0)) { + dirx = dx; diry = dy; + } } int hx = snake[snakelen - 1][0] + dirx; int hy = snake[snakelen - 1][1] + diry; @@ -237,11 +259,21 @@ static void render() { XSetForeground(dpy, gc, C_FOOD); XFillRectangle(dpy, back, gc, gx0 + foodx * cell, gy0 + foody * cell, cell, cell); } - // snake - for (int i = 0; i < snakelen; i++) { - XSetForeground(dpy, gc, (i == snakelen - 1) ? C_HEAD : C_FG); - XFillRectangle(dpy, back, gc, gx0 + snake[i][0] * cell, gy0 + snake[i][1] * cell, cell, cell); + // snake (batched for speed) + XRectangle bodyRects[COLS * ROWS]; + int nbody = 0; + for (int i = 0; i < snakelen - 1; i++) { + bodyRects[nbody].x = gx0 + snake[i][0] * cell; + bodyRects[nbody].y = gy0 + snake[i][1] * cell; + bodyRects[nbody].width = cell; + bodyRects[nbody].height = cell; + nbody++; } + XSetForeground(dpy, gc, C_FG); + XFillRectangles(dpy, back, gc, bodyRects, nbody); + // head + XSetForeground(dpy, gc, C_HEAD); + XFillRectangle(dpy, back, gc, gx0 + snake[snakelen - 1][0] * cell, gy0 + snake[snakelen - 1][1] * cell, cell, cell); // score (top status strip, clear of the playfield border) char buf[32]; @@ -273,13 +305,13 @@ static void render() { static void handle_key(KeySym ks) { switch (ks) { case XK_Up: case XK_w: case XK_KP_Up: case XK_2: - ndirx = 0; ndiry = -1; break; + tq_push(0, -1); break; case XK_Down: case XK_s: case XK_KP_Down: case XK_8: case XK_x: - ndirx = 0; ndiry = 1; break; + tq_push(0, 1); break; case XK_Left: case XK_a: case XK_KP_Left: case XK_4: - ndirx = -1; ndiry = 0; break; + tq_push(-1, 0); break; case XK_Right: case XK_d: case XK_KP_Right: case XK_6: - ndirx = 1; ndiry = 0; break; + tq_push(1, 0); break; case XK_5: case XK_Return: case XK_KP_Enter: case XK_space: case XK_p: if (state == PLAYING) state = PAUSED; else if (state == PAUSED) { state = PLAYING; nextTick = now_ms() + speed; } diff --git a/src/games/tetris.cpp b/src/games/tetris.cpp index e517099..a7b7e1e 100644 --- a/src/games/tetris.cpp +++ b/src/games/tetris.cpp @@ -286,11 +286,32 @@ static void render() { // window edges, so it is visible on all four sides including right/bottom XSetForeground(dpy, gc, C_DIM); XDrawRectangle(dpy, back, gc, 2, 2, winW - 4, winH - 4); - // settled blocks + // settled blocks (batched for speed) + XRectangle bodies[PCOLS * PROWS], highlights[PCOLS * PROWS * 2], shadows[PCOLS * PROWS * 2]; + int nb = 0, nh = 0, ns = 0; for (int x = 0; x < PCOLS; x++) for (int y = 0; y < PROWS; y++) - if (board[x][y]) - draw_gb_cell(px0 + x * CELL, py0 + y * CELL, CELL, C_GB_MED); + if (board[x][y]) { + int bx = px0 + x * CELL, by = py0 + y * CELL; + bodies[nb].x = bx + 1; bodies[nb].y = by + 1; + bodies[nb].width = CELL - 2; bodies[nb].height = CELL - 2; + nb++; + highlights[nh].x = bx + 1; highlights[nh].y = by; + highlights[nh].width = CELL - 2; highlights[nh].height = 1; + nh++; + highlights[nh].x = bx; highlights[nh].y = by + 1; + highlights[nh].width = 1; highlights[nh].height = CELL - 2; + nh++; + shadows[ns].x = bx + 1; shadows[ns].y = by + CELL - 1; + shadows[ns].width = CELL - 2; shadows[ns].height = 1; + ns++; + shadows[ns].x = bx + CELL - 1; shadows[ns].y = by + 1; + shadows[ns].width = 1; shadows[ns].height = CELL - 2; + ns++; + } + XSetForeground(dpy, gc, C_GB_MED); XFillRectangles(dpy, back, gc, bodies, nb); + XSetForeground(dpy, gc, C_GB_PALE); XFillRectangles(dpy, back, gc, highlights, nh); + XSetForeground(dpy, gc, C_GB_DARK); XFillRectangles(dpy, back, gc, shadows, ns); // active piece if (state == PLAYING) {