shithub: gm4s

Download patch

ref: 781b19e0fb31b0bb5c6ee7e9a5d1c010812b5349
parent: 671299bd41eb3c05d07c923cd794562bccf48b0f
author: qwx <qwx@sciops.net>
date: Fri Aug 8 19:32:27 EDT 2025

implement srs

--- a/dat.h
+++ b/dat.h
@@ -16,6 +16,8 @@
 	Nrot,
 
 	Nside = 4,
+
+	Ntest = 5,	/* SRS */
 };
 enum{
 	Fswapped = 1<<0,
@@ -31,6 +33,7 @@
 };
 extern Current *cur;
 extern int fours[NF][Nrot];
+extern rkick[NF][Nrot][Ntest*2], lkick[NF][Nrot][Ntest*2];
 
 enum{
 	Nrow = 40,
--- a/gm4s.c
+++ b/gm4s.c
@@ -29,6 +29,21 @@
 	threadexitsall(nil);
 }
 
+static int
+rotate(int x, int y, int dir, int r)
+{
+	int *t, *te;
+
+	t = (dir == Right ? rkick : lkick)[cur->type][cur->rot];
+	for(te=t+Ntest*2; t<te; t+=2)
+		if(!collide(x + t[0], y - t[1], r)){
+			cur->x += t[0];
+			cur->y -= t[1];
+			return 1;
+		}
+	return 0;
+}
+
 static void
 kevent(ulong k)
 {
@@ -46,8 +61,8 @@
 		cur->y++;
 		moved = 1;
 	}
-	if(k & Krotl && !collide(cur->x, cur->y, (r = rr[1+cur->rot-1]))
-	|| k & Krotr && !collide(cur->x, cur->y, (r = rr[1+cur->rot+1]))){
+	if(k & Krotr && rotate(cur->x, cur->y, Right, (r = rr[1+cur->rot+1]))
+	|| k & Krotl && rotate(cur->x, cur->y, Left, (r = rr[1+cur->rot-1]))){
 		cur->rot = r;
 		moved = 1;
 	}
--- a/piece.c
+++ b/piece.c
@@ -6,9 +6,6 @@
 #include "fns.h"
 #include "/sys/src/games/eui.h"
 
-/* FIXME: srs */
-/* FIXME: z and s pieces definitely should not wobble when rotating */
-/* FIXME: stabler rotations? */
 int fours[NF][Nrot] = {
 	[FI] {
 		0b0000111100000000,
@@ -51,6 +48,85 @@
 		0b0010011001000000,
 		0b0000110001100000,
 		0b0100110010000000,
+	},
+};
+
+int rkick[NF][Nrot][Ntest*2] = {
+	[FI] {
+		{0,0, -2,0, +1,0, -2,-1, +1,+2},	/* 0->R */
+		{0,0, -1,0, +2,0, -1,+2, +2,-1},	/* R->2 */
+		{0,0, +2,0, -1,0, +2,+1, -1,-2},	/* 2->L */
+		{0,0, +1,0, -2,0, +1,-2, -2,+1},	/* L->0 */
+	},
+	[FJ] {
+		{0,0, -1,0, -1,+1, 0,-2, -1,-2},
+		{0,0, +1,0, +1,-1, 0,+2, +1,+2},
+		{0,0, +1,0, +1,+1, 0,-2, +1,-2},
+		{0,0, -1,0, -1,-1, 0,+2, -1,+2}, 
+	},
+	[FL] {
+		{0,0, -1,0, -1,+1, 0,-2, -1,-2},
+		{0,0, +1,0, +1,-1, 0,+2, +1,+2},
+		{0,0, +1,0, +1,+1, 0,-2, +1,-2},
+		{0,0, -1,0, -1,-1, 0,+2, -1,+2}, 
+	},
+	[FO] { 0 },
+	[FS] {
+		{0,0, -1,0, -1,+1, 0,-2, -1,-2},
+		{0,0, +1,0, +1,-1, 0,+2, +1,+2},
+		{0,0, +1,0, +1,+1, 0,-2, +1,-2},
+		{0,0, -1,0, -1,-1, 0,+2, -1,+2}, 
+	},
+	[FT] {
+		{0,0, -1,0, -1,+1, 0,-2, -1,-2},
+		{0,0, +1,0, +1,-1, 0,+2, +1,+2},
+		{0,0, +1,0, +1,+1, 0,-2, +1,-2},
+		{0,0, -1,0, -1,-1, 0,+2, -1,+2}, 
+	},
+	[FZ] {
+		{0,0, -1,0, -1,+1, 0,-2, -1,-2},
+		{0,0, +1,0, +1,-1, 0,+2, +1,+2},
+		{0,0, +1,0, +1,+1, 0,-2, +1,-2},
+		{0,0, -1,0, -1,-1, 0,+2, -1,+2}, 
+	},
+};
+int lkick[NF][Nrot][Ntest*2] = {
+	[FI] {
+		{0,0, -1,0, +2,0, -1,+2, +2,-1},	/* 0->L */
+		{0,0, +2,0, -1,0, +2,+1, -1,-2},	/* R->0 */
+		{0,0, +1,0, -2,0, +1,-2, -2,+1},	/* 2->R */
+		{0,0, -2,0, +1,0, -2,-1, +1,+2},	/* L->2 */
+	},
+	[FJ] {
+		{0,0, +1,0, +1,+1, 0,-2, +1,-2},
+		{0,0, +1,0, +1,-1, 0,+2, +1,+2},
+		{0,0, -1,0, -1,+1, 0,-2, -1,-2},
+		{0,0, -1,0, -1,-1, 0,+2, -1,+2},
+	},
+	[FL] {
+		{0,0, +1,0, +1,+1, 0,-2, +1,-2},
+		{0,0, +1,0, +1,-1, 0,+2, +1,+2},
+		{0,0, -1,0, -1,+1, 0,-2, -1,-2},
+		{0,0, -1,0, -1,-1, 0,+2, -1,+2},
+	},
+	[FO] { 0 },
+	[FS] {
+		{0,0, +1,0, +1,+1, 0,-2, +1,-2},
+		{0,0, +1,0, +1,-1, 0,+2, +1,+2},
+		{0,0, -1,0, -1,+1, 0,-2, -1,-2},
+		{0,0, -1,0, -1,-1, 0,+2, -1,+2},
+	},
+	[FT] {
+		{0,0, +1,0, +1,+1, 0,-2, +1,-2},
+		{0,0, +1,0, +1,-1, 0,+2, +1,+2},
+		{0,0, -1,0, -1,+1, 0,-2, -1,-2},
+		{0,0, -1,0, -1,-1, 0,+2, -1,+2},
+	},
+	[FZ] {
+		{0,0, +1,0, +1,+1, 0,-2, +1,-2},
+		{0,0, +1,0, +1,-1, 0,+2, +1,+2},
+		{0,0, -1,0, -1,+1, 0,-2, -1,-2},
+		{0,0, -1,0, -1,-1, 0,+2, -1,+2},
 	},
 };
 
--