Patch from James H to add keyboard control in Sixteen and Netslide

(and also belatedly document the keyboard support in Unequal).

[originally from svn r8432]
This commit is contained in:
Simon Tatham
2009-01-26 19:14:44 +00:00
parent d2b0d8cf3f
commit cc0f957d82
5 changed files with 230 additions and 50 deletions

29
misc.c
View File

@ -280,6 +280,35 @@ int c2pos(int w, int h, int cx, int cy)
return -1; /* not reached */ 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) void pos2c(int w, int h, int pos, int *cx, int *cy)
{ {
int max = w+h+w+h; int max = w+h+w+h;

View File

@ -159,15 +159,15 @@ static game_params *default_params(void)
static const struct { int x, y, wrap, bprob; const char* desc; } static const struct { int x, y, wrap, bprob; const char* desc; }
netslide_presets[] = { netslide_presets[] = {
{3, 3, FALSE, 1.0, " easy"}, {3, 3, FALSE, 1, " easy"},
{3, 3, FALSE, 0.0, " medium"}, {3, 3, FALSE, 0, " medium"},
{3, 3, TRUE, 0.0, " hard"}, {3, 3, TRUE, 0, " hard"},
{4, 4, FALSE, 1.0, " easy"}, {4, 4, FALSE, 1, " easy"},
{4, 4, FALSE, 0.0, " medium"}, {4, 4, FALSE, 0, " medium"},
{4, 4, TRUE, 0.0, " hard"}, {4, 4, TRUE, 0, " hard"},
{5, 5, FALSE, 1.0, " easy"}, {5, 5, FALSE, 1, " easy"},
{5, 5, FALSE, 0.0, " medium"}, {5, 5, FALSE, 0, " medium"},
{5, 5, TRUE, 0.0, " hard"}, {5, 5, TRUE, 0, " hard"},
}; };
static int game_fetch_preset(int i, char **name, game_params **params) 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->width = netslide_presets[i].x;
ret->height = netslide_presets[i].y; ret->height = netslide_presets[i].y;
ret->wrapping = netslide_presets[i].wrap; ret->wrapping = netslide_presets[i].wrap;
ret->barrier_probability = netslide_presets[i].bprob; ret->barrier_probability = (float)netslide_presets[i].bprob;
ret->movetarget = 0; ret->movetarget = 0;
sprintf(str, "%dx%d%s", ret->width, ret->height, netslide_presets[i].desc); 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 ) if ( (ret->wrapping = (*p == 'w')) != 0 )
p++; p++;
if (*p == 'b') { if (*p == 'b') {
ret->barrier_probability = atof(++p); ret->barrier_probability = (float)atof(++p);
while (*p && (isdigit((unsigned char)*p) || *p == '.')) p++; while (*p && (isdigit((unsigned char)*p) || *p == '.')) p++;
} }
if (*p == 'm') { if (*p == 'm') {
@ -979,8 +979,8 @@ struct game_ui {
static game_ui *new_ui(game_state *state) static game_ui *new_ui(game_state *state)
{ {
game_ui *ui = snew(game_ui); game_ui *ui = snew(game_ui);
ui->cur_x = state->width / 2; ui->cur_x = 0;
ui->cur_y = state->height / 2; ui->cur_y = -1;
ui->cur_visible = FALSE; ui->cur_visible = FALSE;
return ui; return ui;
@ -1052,6 +1052,7 @@ struct game_drawstate {
int width, height; int width, height;
int tilesize; int tilesize;
unsigned char *visible; unsigned char *visible;
int cur_x, cur_y;
}; };
static char *interpret_move(game_state *state, game_ui *ui, 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; button &= ~MOD_MASK;
if (button != LEFT_BUTTON && button != RIGHT_BUTTON) if (IS_CURSOR_MOVE(button)) {
return NULL; 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 "";
}
if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
cx = (x - (BORDER + WINDOW_OFFSET + TILE_BORDER) + 2*TILE_SIZE) / TILE_SIZE - 2; 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; 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) 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->visible = snewn(state->width * state->height, unsigned char);
ds->tilesize = 0; /* not decided yet */ ds->tilesize = 0; /* not decided yet */
memset(ds->visible, 0xFF, state->width * state->height); memset(ds->visible, 0xFF, state->width * state->height);
ds->cur_x = ds->cur_y = -1;
return ds; 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, static void draw_tile(drawing *dr, game_drawstate *ds, game_state *state,
int x, int y, int tile, float xshift, float yshift) int x, int y, int tile, float xshift, float yshift)
{ {
int bx = BORDER + WINDOW_OFFSET + TILE_SIZE * x + (xshift * TILE_SIZE); int bx = BORDER + WINDOW_OFFSET + TILE_SIZE * x + (int)(xshift * TILE_SIZE);
int by = BORDER + WINDOW_OFFSET + TILE_SIZE * y + (yshift * TILE_SIZE); int by = BORDER + WINDOW_OFFSET + TILE_SIZE * y + (int)(yshift * TILE_SIZE);
float cx, cy, ex, ey; float cx, cy, ex, ey;
int dir, col; 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, 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 coords[14];
int ydy = -xdx, ydx = xdy; 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(5, 3 * TILE_SIZE / 8, TILE_SIZE / 2); /* left concave */
POINT(6, TILE_SIZE / 4, TILE_SIZE / 2); /* left corner */ 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, 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; unsigned char *active;
float xshift = 0.0; float xshift = 0.0;
float yshift = 0.0; float yshift = 0.0;
int cur_x = -1, cur_y = -1;
/* /*
* Clear the screen and draw the exterior barrier lines if this * 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++) { for (x = 0; x < ds->width; x++) {
if (x == state->cx) continue; if (x == state->cx) continue;
draw_arrow(dr, ds, x, 0, +1, 0); draw_arrow(dr, ds, x, 0, +1, 0, 0);
draw_arrow(dr, ds, x+1, ds->height, -1, 0); draw_arrow(dr, ds, x+1, ds->height, -1, 0, 0);
} }
for (y = 0; y < ds->height; y++) { for (y = 0; y < ds->height; y++) {
if (y == state->cy) continue; if (y == state->cy) continue;
draw_arrow(dr, ds, ds->width, y, 0, +1); draw_arrow(dr, ds, ds->width, y, 0, +1, 0);
draw_arrow(dr, ds, 0, y+1, 0, -1); 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 /* Check if this is an undo. If so, we will need to run any animation
* backwards. * 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_pos, in direction
* state->last_move_dir * 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; (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; (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 || index(state, ds->visible, x, y) == 0xFF ||
(x == state->last_move_col || y == state->last_move_row)) (x == state->last_move_col || y == state->last_move_row))
{ {
float xs = (y == state->last_move_row ? xshift : 0.0); float xs = (y == state->last_move_row ? xshift : (float)0.0);
float ys = (x == state->last_move_col ? yshift : 0.0); float ys = (x == state->last_move_col ? yshift : (float)0.0);
draw_tile(dr, ds, state, x, y, c, xs, ys); draw_tile(dr, ds, state, x, y, c, xs, ys);
if (xs < 0 && x == 0) if (xs < 0 && x == 0)
@ -1820,3 +1882,5 @@ const struct game thegame = {
FALSE, game_timing_state, FALSE, game_timing_state,
0, /* flags */ 0, /* flags */
}; };
/* vim: set shiftwidth=4 tabstop=8: */

View File

@ -646,9 +646,13 @@ rather than just engineering.
\H{sixteen-controls} \I{controls, for Sixteen}Sixteen controls \H{sixteen-controls} \I{controls, for Sixteen}Sixteen controls
This game is played with the mouse. Left-clicking on an arrow will Left-clicking on an arrow will move the appropriate row or column in
move the appropriate row or column in the direction indicated. the direction indicated. Right-clicking will move it in the opposite
Right-clicking will move it in the opposite direction. 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.) (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 instead of rotating tiles back into place you have to slide them
into place by moving a whole row at a time. into place by moving a whole row at a time.
As in Sixteen, \I{controls, for Netslide}control is with the mouse. As in Sixteen, \I{controls, for Netslide}control is with the mouse or
See \k{sixteen-controls}. cursor keys. See \k{sixteen-controls}.
\I{parameters, for Netslide}The available game parameters have similar \I{parameters, for Netslide}The available game parameters have similar
meanings to those in Net (see \k{net-params}) and Sixteen (see 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 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 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 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 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 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 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.) (All the actions described in \k{common-actions} are also available.)

View File

@ -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. */ /* Used in netslide.c and sixteen.c for cursor movement around edge. */
int c2pos(int w, int h, int cx, int cy); 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); void pos2c(int w, int h, int pos, int *cx, int *cy);
/* Draws text with an 'outline' formed by offsetting the text /* Draws text with an 'outline' formed by offsetting the text

View File

@ -553,13 +553,24 @@ static char *game_text_format(game_state *state)
return ret; return ret;
} }
struct game_ui {
int cur_x, cur_y;
int cur_visible;
};
static game_ui *new_ui(game_state *state) 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) static void free_ui(game_ui *ui)
{ {
sfree(ui);
} }
static char *encode_ui(game_ui *ui) static char *encode_ui(game_ui *ui)
@ -581,20 +592,47 @@ struct game_drawstate {
int w, h, bgcolour; int w, h, bgcolour;
int *tiles; int *tiles;
int tilesize; int tilesize;
int cur_x, cur_y;
}; };
static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds, static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
int x, int y, int button) int x, int y, int button)
{ {
int cx, cy, dx, dy; int cx = -1, cy = -1, dx, dy;
char buf[80]; char buf[80];
button &= ~MOD_MASK; button &= ~MOD_MASK;
if (button != LEFT_BUTTON && button != RIGHT_BUTTON)
return NULL;
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); cx = FROMCOORD(x);
cy = FROMCOORD(y); 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) if (cx == -1 && cy >= 0 && cy < state->h)
dx = -1, dy = 0; dx = -1, dy = 0;
else if (cx == state->w && cy >= 0 && cy < state->h) 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) else if (cy == state->h && cx >= 0 && cx < state->w)
dy = +1, dx = 0; dy = +1, dx = 0;
else else
return NULL; /* invalid click location */ return ""; /* invalid click location */
/* reverse direction if right hand button is pressed */ /* reverse direction if right hand button is pressed */
if (button == RIGHT_BUTTON) { if (button == RIGHT_BUTTON || button == CURSOR_SELECT2) {
dx = -dx; dx = -dx;
dy = -dy; dy = -dy;
} }
@ -731,6 +769,7 @@ static game_drawstate *game_new_drawstate(drawing *dr, game_state *state)
ds->tilesize = 0; /* haven't decided yet */ ds->tilesize = 0; /* haven't decided yet */
for (i = 0; i < ds->w*ds->h; i++) for (i = 0; i < ds->w*ds->h; i++)
ds->tiles[i] = -1; ds->tiles[i] = -1;
ds->cur_x = ds->cur_y = -1;
return ds; return ds;
} }
@ -777,7 +816,7 @@ static void draw_tile(drawing *dr, game_drawstate *ds,
} }
static void draw_arrow(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 coords[14];
int ydy = -xdx, ydx = xdy; 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(5, 3 * TILE_SIZE / 8, TILE_SIZE / 2); /* left concave */
POINT(6, TILE_SIZE / 4, TILE_SIZE / 2); /* left corner */ 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, 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) float animtime, float flashtime)
{ {
int i, bgcolour; int i, bgcolour;
int cur_x = -1, cur_y = -1;
if (flashtime > 0) { if (flashtime > 0) {
int frame = (int)(flashtime / FLASH_FRAME); 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. * Arrows for making moves.
*/ */
for (i = 0; i < state->w; i++) { for (i = 0; i < state->w; i++) {
draw_arrow(dr, ds, COORD(i), COORD(0), +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); draw_arrow(dr, ds, COORD(i+1), COORD(state->h), -1, 0, 0);
} }
for (i = 0; i < state->h; i++) { for (i = 0; i < state->h; i++) {
draw_arrow(dr, ds, COORD(state->w), COORD(i), 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); draw_arrow(dr, ds, COORD(0), COORD(i+1), 0, -1, 0);
} }
ds->started = TRUE; 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. * Now draw each tile.
@ -1054,3 +1126,5 @@ const struct game thegame = {
FALSE, game_timing_state, FALSE, game_timing_state,
0, /* flags */ 0, /* flags */
}; };
/* vim: set shiftwidth=4 tabstop=8: */