shithub: cflood

Download patch

ref: 4dd39471d23d01c82e86d3347decfa9448ca7fa6
parent: 172d631819e492f3392a97ea4e78e0231f475c22
author: Sigrid Solveig Haflínudóttir <248148+ftrvxmtrx@users.noreply.github.com>
date: Tue Dec 18 20:45:59 EST 2012

games/cflood: add custom mode to the menu; much faster drawing

--- a/games/cflood.c
+++ b/games/cflood.c
@@ -15,11 +15,12 @@
 	Twin,
 	Tfail,
 
+	/* cell flags & masks */
 	Flood = 1<<7,
+	Redraw = 1<<6,
 	ColorMask = 0x0f,
 
 	NumColors = 6,
-
 	ButtonSize = 32
 };
 
@@ -45,7 +46,8 @@
 	"25x25 / 35",
 	"28x28 / 50",
 	"exit",
-	0
+	nil, /* the extra for "custom" */
+	nil
 };
 
 static int inv;
@@ -62,10 +64,10 @@
 floodneighbours(uchar color, int x, int y);
 
 static void
-redraw(Image *screen)
+redraw(Image *screen, int full)
 {
+	static Point p, sp, strsize;
 	int i, x, y, w, h, csize, left;
-	Point p, sp, strsize;
 	const uchar *c;
 	Rectangle r;
 	char s[64];
@@ -72,6 +74,7 @@
 	Font *f;
 	Image *colora, *colorb;
 
+	sp.x = sp.y = 0;
 	colora = colorb = display->black;
 	if(inv)
 		colorb = display->white;
@@ -78,7 +81,8 @@
 	else
 		colora = display->white;
 
-	draw(screen, screen->r, colora, nil, ZP);
+	/* clear the old caption */
+	draw(screen, Rect(p.x, p.y, p.x+strsize.x, p.y+strsize.y), colora, nil, ZP);
 
 	if(state == Tgame)
 		sprint(s, "%d", turnsleft);
@@ -96,33 +100,41 @@
 	w = size*csize;
 	left = screen->r.min.x + (Dx(screen->r) - w)/2;
 
-	/* cells */
-	c = cells;
-	for(x = 0; x < size; x++){
-		for(y = 0; y < size; y++){
-			r.min.x = left + x*csize;
-			r.min.y = screen->r.min.y + 2 + y*csize;
-			r.max.x = r.min.x + csize;
-			r.max.y = r.min.y + csize;
-			draw(screen, r, colors[*c & ColorMask], nil, ZP);
-			c++;
+	/* buttons top */
+	y = screen->r.min.y + h + 2 + strsize.y;
+
+	if(full){
+		/* background */
+		draw(screen, screen->r, colora, nil, ZP);
+
+		/* buttons */
+		x = left + (w - NumColors*ButtonSize)/2;
+		for(i = 0; i < NumColors; i++, x += ButtonSize){
+			buttons[i] = Rect(x, y, x+ButtonSize, y+ButtonSize);
+			draw(screen, buttons[i], colors[i], nil, ZP);
 		}
 	}
 
-	/* buttons */
-	x = left + (w - NumColors*ButtonSize)/2;
-	y = screen->r.min.y + h + strsize.y;
-	for(i = 0; i < NumColors; i++, x += ButtonSize){
-		buttons[i] = Rect(x, y, x+ButtonSize, y+ButtonSize);
-		draw(screen, buttons[i], colors[i], nil, ZP);
-	}
-
 	/* caption */
 	p.x = left + w/2 - strsize.x/2;
 	p.y = y - strsize.y;
-	sp.x = sp.y = 0;
 	string(screen, p, colorb, sp, f, s);
 
+	/* cells */
+	c = cells;
+	for(x = 0; x < size; x++){
+		for(y = 0; y < size; y++, c++){
+			if((*c & Redraw) != 0 || full){
+				*c &= ~Redraw;
+				r.min.x = left + x*csize;
+				r.min.y = screen->r.min.y + 2 + y*csize;
+				r.max.x = r.min.x + csize;
+				r.max.y = r.min.y + csize;
+				draw(screen, r, colors[*c & ColorMask], nil, ZP);
+			}
+		}
+	}
+
 	flushimage(display, 1);
 }
 
@@ -132,7 +144,6 @@
 	uchar *c;
 	c = &cells[x + y*size];
 	if((*c & Flood) == 0 && (*c & ColorMask) == color){
-		*c = color | Flood;
 		floodneighbours(color, x, y);
 	}
 }
@@ -140,7 +151,7 @@
 static void
 floodneighbours(uchar color, int x, int y)
 {
-	cells[x + y*size] = color | Flood;
+	cells[x + y*size] = color|Flood|Redraw;
 
 	if(x > 0)
 		floodrecurse(color, x-1, y);
@@ -193,7 +204,7 @@
 		clickwait = 1;
 	}
 
-	redraw(screen);
+	redraw(screen, 0);
 }
 
 static void
@@ -218,9 +229,9 @@
 		*c++ = nrand(NumColors);
 	}
 
-	cells[0] |= Flood;
+	cells[0] |= Flood|Redraw;
 	reflood(cells[0]);
-	redraw(screen);
+	redraw(screen, 1);
 }
 
 void
@@ -228,7 +239,7 @@
 {
 	if(new && getwindow(display, Refnone) < 0)
 		sysfatal("can't reattach to window: %r");
-	redraw(screen);
+	redraw(screen, 1);
 }
 
 static void
@@ -240,24 +251,12 @@
 
 void main(int argc, char** argv)
 {
-	int key, p, i, oldbuttons;
+	int key, p, i, oldbuttons, sidmax;
 	Event e;
 	Mouse m;
 	Menu menu;
 	Rectangle r;
 
-	if(initdraw(0, 0, "cflood") < 0)
-		sysfatal("initdraw failed");
-
-	r = Rect(0, 0, 1, 1);
-	for(i = 0; i < NumColors; i++)
-		colors[i] = allocimage(display, r, CMAP8, 1, srccolors[i]);
-
-	einit(Emouse);
-	menu.item = mstr;
-	menu.lasthit = 0;
-	srand(time(0));
-
 	sid = Ssmall;
 	inv = 0;
 	ARGBEGIN{
@@ -280,6 +279,26 @@
 		usage();
 	}ARGEND
 
+	if(initdraw(0, 0, "cflood") < 0)
+		sysfatal("initdraw failed");
+
+	r = Rect(0, 0, 1, 1);
+	for(i = 0; i < NumColors; i++)
+		colors[i] = allocimage(display, r, CMAP8, 1, srccolors[i]);
+
+	einit(Emouse);
+	menu.item = mstr;
+	menu.lasthit = 0;
+	srand(time(0));
+
+	sidmax = (sid > Slarge) ? sid : Slarge;
+	if(sid == Scustom){
+		/* move "exit" and add "custom" size/turns */
+		sidmax = sid;
+		mstr[Scustom+1] = mstr[Scustom];
+		mstr[Scustom] = smprint("%dx%d / %d", sizes[sid], sizes[sid], turns[sid]);
+	}
+
 	newgame(sid);
 
 	for(oldbuttons = 0;;){
@@ -291,7 +310,7 @@
 
 		if(m.buttons & 4){
 			p = emenuhit(3, &m, &menu);
-			if(p >= Ssmall && p <= Slarge)
+			if(p >= Ssmall && p <= sidmax)
 				newgame(sid = p);
 			else if(p > 0)
 				break;