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;