chiark / gitweb /
Patch from James H to add keyboard control in Sixteen and Netslide
authorSimon Tatham <anakin@pobox.com>
Mon, 26 Jan 2009 19:14:44 +0000 (19:14 +0000)
committerSimon Tatham <anakin@pobox.com>
Mon, 26 Jan 2009 19:14:44 +0000 (19:14 +0000)
(and also belatedly document the keyboard support in Unequal).

[originally from svn r8432]

misc.c
netslide.c
puzzles.but
puzzles.h
sixteen.c

diff --git a/misc.c b/misc.c
index 81aa011a2fa153892520544faae1065b65037ad9..11c842cd42c429274598a5df3cb312c207cbbec5 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -280,6 +280,35 @@ int c2pos(int w, int h, int cx, int cy)
     return -1; /* not reached */
 }
 
+int c2diff(int w, int h, int cx, int cy, int button)
+{
+    int diff = 0;
+
+    assert(IS_CURSOR_MOVE(button));
+
+    /* Obvious moves around edge. */
+    if (cy == -1)
+        diff = (button == CURSOR_RIGHT) ? +1 : (button == CURSOR_LEFT) ? -1 : diff;
+    if (cy == h)
+        diff = (button == CURSOR_RIGHT) ? -1 : (button == CURSOR_LEFT) ? +1 : diff;
+    if (cx == -1)
+        diff = (button == CURSOR_UP) ? +1 : (button == CURSOR_DOWN) ? -1 : diff;
+    if (cx == w)
+        diff = (button == CURSOR_UP) ? -1 : (button == CURSOR_DOWN) ? +1 : diff;
+
+    if (button == CURSOR_LEFT && cx == w && (cy == 0 || cy == h-1))
+        diff = (cy == 0) ? -1 : +1;
+    if (button == CURSOR_RIGHT && cx == -1 && (cy == 0 || cy == h-1))
+        diff = (cy == 0) ? +1 : -1;
+    if (button == CURSOR_DOWN && cy == -1 && (cx == 0 || cx == w-1))
+        diff = (cx == 0) ? -1 : +1;
+    if (button == CURSOR_UP && cy == h && (cx == 0 || cx == w-1))
+        diff = (cx == 0) ? +1 : -1;
+
+    debug(("cx,cy = %d,%d; w%d h%d, diff = %d", cx, cy, w, h, diff));
+    return diff;
+}
+
 void pos2c(int w, int h, int pos, int *cx, int *cy)
 {
     int max = w+h+w+h;
index f96086550844ca18dda9953de51fe507cf5b56b4..99eb6e13620f87cb5aeb347daabe8693bc3d0224 100644 (file)
@@ -159,15 +159,15 @@ static game_params *default_params(void)
 
 static const struct { int x, y, wrap, bprob; const char* desc; }
 netslide_presets[] = {
-    {3, 3, FALSE, 1.0, " easy"},
-    {3, 3, FALSE, 0.0, " medium"},
-    {3, 3, TRUE,  0.0, " hard"},
-    {4, 4, FALSE, 1.0, " easy"},
-    {4, 4, FALSE, 0.0, " medium"},
-    {4, 4, TRUE,  0.0, " hard"},
-    {5, 5, FALSE, 1.0, " easy"},
-    {5, 5, FALSE, 0.0, " medium"},
-    {5, 5, TRUE,  0.0, " hard"},
+    {3, 3, FALSE, 1, " easy"},
+    {3, 3, FALSE, 0, " medium"},
+    {3, 3, TRUE,  0, " hard"},
+    {4, 4, FALSE, 1, " easy"},
+    {4, 4, FALSE, 0, " medium"},
+    {4, 4, TRUE,  0, " hard"},
+    {5, 5, FALSE, 1, " easy"},
+    {5, 5, FALSE, 0, " medium"},
+    {5, 5, TRUE,  0, " hard"},
 };
 
 static int game_fetch_preset(int i, char **name, game_params **params)
@@ -182,7 +182,7 @@ static int game_fetch_preset(int i, char **name, game_params **params)
     ret->width = netslide_presets[i].x;
     ret->height = netslide_presets[i].y;
     ret->wrapping = netslide_presets[i].wrap;
-    ret->barrier_probability = netslide_presets[i].bprob;
+    ret->barrier_probability = (float)netslide_presets[i].bprob;
     ret->movetarget = 0;
 
     sprintf(str, "%dx%d%s", ret->width, ret->height, netslide_presets[i].desc);
@@ -221,7 +221,7 @@ static void decode_params(game_params *ret, char const *string)
         if ( (ret->wrapping = (*p == 'w')) != 0 )
             p++;
         if (*p == 'b') {
-            ret->barrier_probability = atof(++p);
+            ret->barrier_probability = (float)atof(++p);
             while (*p && (isdigit((unsigned char)*p) || *p == '.')) p++;
         }
         if (*p == 'm') {
@@ -979,8 +979,8 @@ struct game_ui {
 static game_ui *new_ui(game_state *state)
 {
     game_ui *ui = snew(game_ui);
-    ui->cur_x = state->width / 2;
-    ui->cur_y = state->height / 2;
+    ui->cur_x = 0;
+    ui->cur_y = -1;
     ui->cur_visible = FALSE;
 
     return ui;
@@ -1052,6 +1052,7 @@ struct game_drawstate {
     int width, height;
     int tilesize;
     unsigned char *visible;
+    int cur_x, cur_y;
 };
 
 static char *interpret_move(game_state *state, game_ui *ui,
@@ -1063,11 +1064,37 @@ static char *interpret_move(game_state *state, game_ui *ui,
 
     button &= ~MOD_MASK;
 
-    if (button != LEFT_BUTTON && button != RIGHT_BUTTON)
-        return NULL;
+    if (IS_CURSOR_MOVE(button)) {
+        int cpos, diff = 0;
+        cpos = c2pos(state->width, state->height, ui->cur_x, ui->cur_y);
+        diff = c2diff(state->width, state->height, ui->cur_x, ui->cur_y, button);
+
+        if (diff != 0) {
+            do { /* we might have to do this more than once to skip missing arrows */
+                cpos += diff;
+                pos2c(state->width, state->height, cpos, &ui->cur_x, &ui->cur_y);
+            } while (ui->cur_x == state->cx || ui->cur_y == state->cy);
+        }
+
+        ui->cur_visible = 1;
+        return "";
+    }
 
-    cx = (x - (BORDER + WINDOW_OFFSET + TILE_BORDER) + 2*TILE_SIZE) / TILE_SIZE - 2;
-    cy = (y - (BORDER + WINDOW_OFFSET + TILE_BORDER) + 2*TILE_SIZE) / TILE_SIZE - 2;
+    if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
+        cx = (x - (BORDER + WINDOW_OFFSET + TILE_BORDER) + 2*TILE_SIZE) / TILE_SIZE - 2;
+        cy = (y - (BORDER + WINDOW_OFFSET + TILE_BORDER) + 2*TILE_SIZE) / TILE_SIZE - 2;
+        ui->cur_visible = 0;
+    } else if (IS_CURSOR_SELECT(button)) {
+        if (ui->cur_visible) {
+            cx = ui->cur_x;
+            cy = ui->cur_y;
+        } else {
+            /* 'click' when cursor is invisible just makes cursor visible. */
+            ui->cur_visible = 1;
+            return "";
+        }
+    } else
+        return NULL;
 
     if (cy >= 0 && cy < state->height && cy != state->cy)
     {
@@ -1187,6 +1214,7 @@ static game_drawstate *game_new_drawstate(drawing *dr, game_state *state)
     ds->visible = snewn(state->width * state->height, unsigned char);
     ds->tilesize = 0;                  /* not decided yet */
     memset(ds->visible, 0xFF, state->width * state->height);
+    ds->cur_x = ds->cur_y = -1;
 
     return ds;
 }
@@ -1351,8 +1379,8 @@ static void draw_barrier(drawing *dr, game_drawstate *ds,
 static void draw_tile(drawing *dr, game_drawstate *ds, game_state *state,
                       int x, int y, int tile, float xshift, float yshift)
 {
-    int bx = BORDER + WINDOW_OFFSET + TILE_SIZE * x + (xshift * TILE_SIZE);
-    int by = BORDER + WINDOW_OFFSET + TILE_SIZE * y + (yshift * TILE_SIZE);
+    int bx = BORDER + WINDOW_OFFSET + TILE_SIZE * x + (int)(xshift * TILE_SIZE);
+    int by = BORDER + WINDOW_OFFSET + TILE_SIZE * y + (int)(yshift * TILE_SIZE);
     float cx, cy, ex, ey;
     int dir, col;
 
@@ -1509,7 +1537,7 @@ static void draw_tile_barriers(drawing *dr, game_drawstate *ds,
 }
 
 static void draw_arrow(drawing *dr, game_drawstate *ds,
-                       int x, int y, int xdx, int xdy)
+                       int x, int y, int xdx, int xdy, int cur)
 {
     int coords[14];
     int ydy = -xdx, ydx = xdy;
@@ -1529,7 +1557,29 @@ static void draw_arrow(drawing *dr, game_drawstate *ds,
     POINT(5, 3 * TILE_SIZE / 8, TILE_SIZE / 2);   /* left concave */
     POINT(6,     TILE_SIZE / 4, TILE_SIZE / 2);   /* left corner */
 
-    draw_polygon(dr, coords, 7, COL_LOWLIGHT, COL_TEXT);
+    draw_polygon(dr, coords, 7, cur ? COL_POWERED : COL_LOWLIGHT, COL_TEXT);
+}
+
+static void draw_arrow_for_cursor(drawing *dr, game_drawstate *ds,
+                                  int cur_x, int cur_y, int cur)
+{
+    if (cur_x == -1 && cur_y == -1)
+        return; /* 'no cursur here */
+    else if (cur_x == -1) /* LH column. */
+        draw_arrow(dr, ds, 0, cur_y+1, 0, -1, cur);
+    else if (cur_x == ds->width) /* RH column */
+        draw_arrow(dr, ds, ds->width, cur_y, 0, +1, cur);
+    else if (cur_y == -1) /* Top row */
+        draw_arrow(dr, ds, cur_x, 0, +1, 0, cur);
+    else if (cur_y == ds->height) /* Bottom row */
+        draw_arrow(dr, ds, cur_x+1, ds->height, -1, 0, cur);
+    else
+        assert(!"Invalid cursor position");
+
+    draw_update(dr,
+                cur_x * TILE_SIZE + BORDER + WINDOW_OFFSET,
+                cur_y * TILE_SIZE + BORDER + WINDOW_OFFSET,
+                TILE_SIZE, TILE_SIZE);
 }
 
 static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
@@ -1539,6 +1589,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
     unsigned char *active;
     float xshift = 0.0;
     float yshift = 0.0;
+    int cur_x = -1, cur_y = -1;
 
     /*
      * Clear the screen and draw the exterior barrier lines if this
@@ -1595,15 +1646,26 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
          */
         for (x = 0; x < ds->width; x++) {
             if (x == state->cx) continue;
-            draw_arrow(dr, ds, x, 0, +1, 0);
-            draw_arrow(dr, ds, x+1, ds->height, -1, 0);
+            draw_arrow(dr, ds, x, 0, +1, 0, 0);
+            draw_arrow(dr, ds, x+1, ds->height, -1, 0, 0);
         }
         for (y = 0; y < ds->height; y++) {
             if (y == state->cy) continue;
-            draw_arrow(dr, ds, ds->width, y, 0, +1);
-            draw_arrow(dr, ds, 0, y+1, 0, -1);
+            draw_arrow(dr, ds, ds->width, y, 0, +1, 0);
+            draw_arrow(dr, ds, 0, y+1, 0, -1, 0);
         }
     }
+    if (ui->cur_visible) {
+        cur_x = ui->cur_x; cur_y = ui->cur_y;
+    }
+    if (cur_x != ds->cur_x || cur_y != ds->cur_y) {
+        /* Cursor has changed; redraw two (prev and curr) arrows. */
+        assert(cur_x != state->cx && cur_y != state->cy);
+
+        draw_arrow_for_cursor(dr, ds, cur_x, cur_y, 1);
+        draw_arrow_for_cursor(dr, ds, ds->cur_x, ds->cur_y, 0);
+        ds->cur_x = cur_x; ds->cur_y = cur_y;
+    }
 
     /* Check if this is an undo.  If so, we will need to run any animation
      * backwards.
@@ -1622,9 +1684,9 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
          * state->last_move_pos, in direction
          * state->last_move_dir
          */
-        xshift = state->last_move_row == -1 ? 0.0 :
+        xshift = state->last_move_row == -1 ? 0.0F :
                 (1 - t / ANIM_TIME) * state->last_move_dir;
-        yshift = state->last_move_col == -1 ? 0.0 :
+        yshift = state->last_move_col == -1 ? 0.0F :
                 (1 - t / ANIM_TIME) * state->last_move_dir;
     }
     
@@ -1678,8 +1740,8 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
                 index(state, ds->visible, x, y) == 0xFF ||
                 (x == state->last_move_col || y == state->last_move_row))
             {
-                float xs = (y == state->last_move_row ? xshift : 0.0);
-                float ys = (x == state->last_move_col ? yshift : 0.0);
+                float xs = (y == state->last_move_row ? xshift : (float)0.0);
+                float ys = (x == state->last_move_col ? yshift : (float)0.0);
 
                 draw_tile(dr, ds, state, x, y, c, xs, ys);
                 if (xs < 0 && x == 0)
@@ -1820,3 +1882,5 @@ const struct game thegame = {
     FALSE, game_timing_state,
     0,                                /* flags */
 };
+
+/* vim: set shiftwidth=4 tabstop=8: */
index 990d7449bf17051da301b948f9d3c3b57d957ce7..2e998f221f8b92837601ff6941e25b8e308e3013 100644 (file)
@@ -646,9 +646,13 @@ rather than just engineering.
 
 \H{sixteen-controls} \I{controls, for Sixteen}Sixteen controls
 
-This game is played with the mouse. Left-clicking on an arrow will
-move the appropriate row or column in the direction indicated.
-Right-clicking will move it in the opposite direction.
+Left-clicking on an arrow will move the appropriate row or column in
+the direction indicated.  Right-clicking will move it in the opposite
+direction.
+
+Alternatively, use the cursor keys to move the position indicator
+around the edge of the grid, and use the return key to move the
+row/column in the direction indicated. 
 
 (All the actions described in \k{common-actions} are also available.)
 
@@ -833,8 +837,8 @@ movement of Sixteen (see \k{sixteen}): you have a Net grid, but
 instead of rotating tiles back into place you have to slide them
 into place by moving a whole row at a time. 
 
-As in Sixteen, \I{controls, for Netslide}control is with the mouse.
-See \k{sixteen-controls}.
+As in Sixteen, \I{controls, for Netslide}control is with the mouse or
+cursor keys. See \k{sixteen-controls}.
 
 \I{parameters, for Netslide}The available game parameters have similar
 meanings to those in Net (see \k{net-params}) and Sixteen (see
@@ -2210,7 +2214,8 @@ Space to clear it again (or use the Undo feature).
 
 If you \e{right}-click in a square and then type a number, that
 number will be entered in the square as a \q{pencil mark}. You can
-have pencil marks for multiple numbers in the same square.
+have pencil marks for multiple numbers in the same square. Squares
+containing filled-in numbers cannot also contain pencil marks.
 
 The game pays no attention to pencil marks, so exactly what you use
 them for is up to you: you can use them as reminders that a
@@ -2227,7 +2232,14 @@ pressing space will also erase pencil marks.
 
 As for Solo, the cursor keys can be used in conjunction with the digit
 keys to set numbers or pencil marks. You can also use the 'M' key to
-auto-fill every numeric hint, ready for removal as required. 
+auto-fill every numeric hint, ready for removal as required, or the 'H'
+key to do the same but also to remove all obvious hints. 
+
+Alternatively, use the cursor keys to move the mark around the grid.
+Pressing the return key toggles the mark (from a normal mark to a
+pencil mark), and typing a number in is entered in the square in the
+appropriate way; typing in a 0 or using the space bar will clear a
+filled square. 
 
 (All the actions described in \k{common-actions} are also available.)
 
index b375c3b905a9172e538ba9532d8837ad2429fb41..a1acadaba30344a9f865a013e6896aa127d7b6ec 100644 (file)
--- a/puzzles.h
+++ b/puzzles.h
@@ -306,6 +306,7 @@ void move_cursor(int button, int *x, int *y, int maxw, int maxh, int wrap);
 
 /* Used in netslide.c and sixteen.c for cursor movement around edge. */
 int c2pos(int w, int h, int cx, int cy);
+int c2diff(int w, int h, int cx, int cy, int button);
 void pos2c(int w, int h, int pos, int *cx, int *cy);
 
 /* Draws text with an 'outline' formed by offsetting the text
index ac3191c899d7baff1eaa9f8ead707d283bba4273..f77b993f1eb31fab827cdd0d480aeadf11b5ed3f 100644 (file)
--- a/sixteen.c
+++ b/sixteen.c
@@ -553,13 +553,24 @@ static char *game_text_format(game_state *state)
     return ret;
 }
 
+struct game_ui {
+    int cur_x, cur_y;
+    int cur_visible;
+};
+
 static game_ui *new_ui(game_state *state)
 {
-    return NULL;
+    game_ui *ui = snew(game_ui);
+    ui->cur_x = 0;
+    ui->cur_y = -1;
+    ui->cur_visible = FALSE;
+
+    return ui;
 }
 
 static void free_ui(game_ui *ui)
 {
+  sfree(ui);
 }
 
 static char *encode_ui(game_ui *ui)
@@ -581,20 +592,47 @@ struct game_drawstate {
     int w, h, bgcolour;
     int *tiles;
     int tilesize;
+    int cur_x, cur_y;
 };
 
 static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
                            int x, int y, int button)
 {
-    int cx, cy, dx, dy;
+    int cx = -1, cy = -1, dx, dy;
     char buf[80];
 
     button &= ~MOD_MASK;
-    if (button != LEFT_BUTTON && button != RIGHT_BUTTON)
-        return NULL;
 
-    cx = FROMCOORD(x);
-    cy = FROMCOORD(y);
+    if (IS_CURSOR_MOVE(button)) {
+        /* right/down rotates cursor clockwise,
+         * left/up rotates anticlockwise. */
+        int cpos, diff;
+        cpos = c2pos(state->w, state->h, ui->cur_x, ui->cur_y);
+        diff = c2diff(state->w, state->h, ui->cur_x, ui->cur_y, button);
+
+        cpos += diff;
+        pos2c(state->w, state->h, cpos, &ui->cur_x, &ui->cur_y);
+
+        ui->cur_visible = 1;
+        return "";
+    }
+
+    if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
+        cx = FROMCOORD(x);
+        cy = FROMCOORD(y);
+        ui->cur_visible = 0;
+    } else if (IS_CURSOR_SELECT(button)) {
+        if (ui->cur_visible) {
+            cx = ui->cur_x;
+            cy = ui->cur_y;
+        } else {
+            ui->cur_visible = 1;
+            return "";
+        }
+    } else {
+       return NULL;
+    }
+
     if (cx == -1 && cy >= 0 && cy < state->h)
         dx = -1, dy = 0;
     else if (cx == state->w && cy >= 0 && cy < state->h)
@@ -604,10 +642,10 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
     else if (cy == state->h && cx >= 0 && cx < state->w)
         dy = +1, dx = 0;
     else
-        return NULL;                   /* invalid click location */
+        return "";                   /* invalid click location */
 
     /* reverse direction if right hand button is pressed */
-    if (button == RIGHT_BUTTON) {
+    if (button == RIGHT_BUTTON || button == CURSOR_SELECT2) {
         dx = -dx;
         dy = -dy;
     }
@@ -731,6 +769,7 @@ static game_drawstate *game_new_drawstate(drawing *dr, game_state *state)
     ds->tilesize = 0;                  /* haven't decided yet */
     for (i = 0; i < ds->w*ds->h; i++)
         ds->tiles[i] = -1;
+    ds->cur_x = ds->cur_y = -1;
 
     return ds;
 }
@@ -777,7 +816,7 @@ static void draw_tile(drawing *dr, game_drawstate *ds,
 }
 
 static void draw_arrow(drawing *dr, game_drawstate *ds,
-                       int x, int y, int xdx, int xdy)
+                       int x, int y, int xdx, int xdy, int cur)
 {
     int coords[14];
     int ydy = -xdx, ydx = xdy;
@@ -794,7 +833,27 @@ static void draw_arrow(drawing *dr, game_drawstate *ds,
     POINT(5, 3 * TILE_SIZE / 8, TILE_SIZE / 2);   /* left concave */
     POINT(6,     TILE_SIZE / 4, TILE_SIZE / 2);   /* left corner */
 
-    draw_polygon(dr, coords, 7, COL_LOWLIGHT, COL_TEXT);
+    draw_polygon(dr, coords, 7, cur ? COL_HIGHLIGHT : COL_LOWLIGHT, COL_TEXT);
+}
+
+static void draw_arrow_for_cursor(drawing *dr, game_drawstate *ds,
+                                  int cur_x, int cur_y, int cur)
+{
+    if (cur_x == -1 && cur_y == -1)
+        return; /* 'no cursur here */
+    else if (cur_x == -1) /* LH column. */
+        draw_arrow(dr, ds, COORD(0), COORD(cur_y+1), 0, -1, cur);
+    else if (cur_x == ds->w) /* RH column */
+        draw_arrow(dr, ds, COORD(ds->w), COORD(cur_y), 0, +1, cur);
+    else if (cur_y == -1) /* Top row */
+        draw_arrow(dr, ds, COORD(cur_x), COORD(0), +1, 0, cur);
+    else if (cur_y == ds->h) /* Bottom row */
+        draw_arrow(dr, ds, COORD(cur_x+1), COORD(ds->h), -1, 0, cur);
+    else
+        assert(!"Invalid cursor position");
+
+    draw_update(dr, COORD(cur_x), COORD(cur_y),
+                TILE_SIZE, TILE_SIZE);
 }
 
 static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
@@ -802,6 +861,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
                  float animtime, float flashtime)
 {
     int i, bgcolour;
+    int cur_x = -1, cur_y = -1;
 
     if (flashtime > 0) {
         int frame = (int)(flashtime / FLASH_FRAME);
@@ -842,16 +902,28 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
          * Arrows for making moves.
          */
         for (i = 0; i < state->w; i++) {
-            draw_arrow(dr, ds, COORD(i), COORD(0), +1, 0);
-            draw_arrow(dr, ds, COORD(i+1), COORD(state->h), -1, 0);
+            draw_arrow(dr, ds, COORD(i), COORD(0), +1, 0, 0);
+            draw_arrow(dr, ds, COORD(i+1), COORD(state->h), -1, 0, 0);
         }
         for (i = 0; i < state->h; i++) {
-            draw_arrow(dr, ds, COORD(state->w), COORD(i), 0, +1);
-            draw_arrow(dr, ds, COORD(0), COORD(i+1), 0, -1);
+            draw_arrow(dr, ds, COORD(state->w), COORD(i), 0, +1, 0);
+            draw_arrow(dr, ds, COORD(0), COORD(i+1), 0, -1, 0);
         }
 
         ds->started = TRUE;
     }
+    /*
+     * Cursor (highlighted arrow around edge)
+     */
+    if (ui->cur_visible) {
+        cur_x = ui->cur_x; cur_y = ui->cur_y;
+    }
+    if (cur_x != ds->cur_x || cur_y != ds->cur_y) {
+        /* Cursor has changed; redraw two (prev and curr) arrows. */
+        draw_arrow_for_cursor(dr, ds, cur_x, cur_y, 1);
+        draw_arrow_for_cursor(dr, ds, ds->cur_x, ds->cur_y, 0);
+        ds->cur_x = cur_x; ds->cur_y = cur_y;
+    }
 
     /*
      * Now draw each tile.
@@ -1054,3 +1126,5 @@ const struct game thegame = {
     FALSE, game_timing_state,
     0,                                /* flags */
 };
+
+/* vim: set shiftwidth=4 tabstop=8: */