Patch from James H which adds keyboard cursor support to Unequal,

and also updates the docs for both that and the Mines cursor support
in r8402.

[originally from svn r8408]
[r8402 == f20847354cb6335fd349204f16021a72e2956cce]
This commit is contained in:
Simon Tatham
2009-01-12 20:23:56 +00:00
parent f20847354c
commit 4a202808ee
2 changed files with 72 additions and 43 deletions

View File

@ -1046,6 +1046,12 @@ turn, and so on if any of them also has no surrounding mines. This
will be done for you automatically; so sometimes when you uncover a will be done for you automatically; so sometimes when you uncover a
square, a whole new area will open up to be explored. square, a whole new area will open up to be explored.
You can also use the cursor keys to move around the minefield.
Pressing the return key in a covered square uncovers it, and in an
uncovered square will clear around it (so it acts as the left button),
pressing the space bar in a covered square will place a flag
(similarly, it acts as the right button).
All the actions described in \k{common-actions} are also available. All the actions described in \k{common-actions} are also available.
Even Undo is available, although you might consider it cheating to Even Undo is available, although you might consider it cheating to
@ -2190,6 +2196,10 @@ All pencil marks in a square are erased when you left-click and type
a number, or when you left-click and press space. Right-clicking and a number, or when you left-click and press space. Right-clicking and
pressing space will also erase pencil marks. 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.
(All the actions described in \k{common-actions} are also available.) (All the actions described in \k{common-actions} are also available.)
\H{unequal-parameters} \I{parameters, for Unequal}Unequal parameters \H{unequal-parameters} \I{parameters, for Unequal}Unequal parameters

101
unequal.c
View File

@ -229,7 +229,7 @@ static char *validate_params(game_params *params, int full)
if (params->order < 3 || params->order > 32) if (params->order < 3 || params->order > 32)
return "Order must be between 3 and 32"; return "Order must be between 3 and 32";
if (params->diff >= DIFFCOUNT) if (params->diff >= DIFFCOUNT)
return "Unknown difficulty rating."; return "Unknown difficulty rating";
return NULL; return NULL;
} }
@ -1210,18 +1210,16 @@ static char *solve_game(game_state *state, game_state *currstate,
*/ */
struct game_ui { struct game_ui {
int hx, hy, hpencil; /* as for solo.c, highlight pos and type */ int hx, hy; /* as for solo.c, highlight pos */
int cx, cy; /* cursor position (-1,-1 for none) */ int hshow, hpencil, hcursor; /* show state, type, and ?cursor. */
}; };
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->hx = ui->hy = -1; ui->hx = ui->hy = 0;
ui->hpencil = 0; ui->hpencil = ui->hshow = ui->hcursor = 0;
ui->cx = ui->cy = -1;
return ui; return ui;
} }
@ -1246,9 +1244,9 @@ static void game_changed_state(game_ui *ui, game_state *oldstate,
/* See solo.c; if we were pencil-mode highlighting and /* See solo.c; if we were pencil-mode highlighting and
* somehow a square has just been properly filled, cancel * somehow a square has just been properly filled, cancel
* pencil mode. */ * pencil mode. */
if (ui->hx >= 0 && ui->hy >= 0 && ui->hpencil && if (ui->hshow && ui->hpencil && !ui->hcursor &&
GRID(newstate, nums, ui->hx, ui->hy) != 0) { GRID(newstate, nums, ui->hx, ui->hy) != 0) {
ui->hx = ui->hy = -1; ui->hshow = 0;
} }
} }
@ -1258,8 +1256,7 @@ struct game_drawstate {
unsigned char *hints; /* copy of hints, o^3 */ unsigned char *hints; /* copy of hints, o^3 */
unsigned int *flags; /* o^2 */ unsigned int *flags; /* o^2 */
int hx, hy, hpencil; int hx, hy, hshow, hpencil; /* as for game_ui. */
int cx, cy;
int hflash; int hflash;
}; };
@ -1276,28 +1273,50 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
if (button == LEFT_BUTTON) { if (button == LEFT_BUTTON) {
/* normal highlighting for non-immutable squares */ /* normal highlighting for non-immutable squares */
if (GRID(state, flags, x, y) & F_IMMUTABLE) if (GRID(state, flags, x, y) & F_IMMUTABLE)
ui->hx = ui->hy = -1; ui->hshow = 0;
else if (x == ui->hx && y == ui->hy && ui->hpencil == 0) else if (x == ui->hx && y == ui->hy &&
ui->hx = ui->hy = -1; ui->hshow && ui->hpencil == 0)
ui->hshow = 0;
else { else {
ui->hx = x; ui->hy = y; ui->hpencil = 0; ui->hx = x; ui->hy = y; ui->hpencil = 0;
ui->hshow = 1;
} }
ui->hcursor = 0;
return ""; return "";
} }
if (button == RIGHT_BUTTON) { if (button == RIGHT_BUTTON) {
/* pencil highlighting for non-filled squares */ /* pencil highlighting for non-filled squares */
if (GRID(state, nums, x, y) != 0) if (GRID(state, nums, x, y) != 0)
ui->hx = ui->hy = -1; ui->hshow = 0;
else if (x == ui->hx && y == ui->hy && ui->hpencil) else if (x == ui->hx && y == ui->hy &&
ui->hx = ui->hy = -1; ui->hshow && ui->hpencil)
ui->hshow = 0;
else { else {
ui->hx = x; ui->hy = y; ui->hpencil = 1; ui->hx = x; ui->hy = y; ui->hpencil = 1;
ui->hshow = 1;
} }
ui->hcursor = 0;
return ""; return "";
} }
} }
if (button == 'H' || button == 'h')
return dupstr("H");
if (button == 'M' || button == 'm')
return dupstr("M");
if (ui->hx != -1 && ui->hy != -1) { if (IS_CURSOR_MOVE(button)) {
move_cursor(button, &ui->hx, &ui->hy, ds->order, ds->order, 0);
ui->hshow = ui->hcursor = 1;
return "";
}
if (ui->hshow && IS_CURSOR_SELECT(button)) {
ui->hpencil = 1 - ui->hpencil;
ui->hcursor = 1;
return "";
}
if (ui->hshow) {
debug(("button %d, cbutton %d", button, (int)((char)button))); debug(("button %d, cbutton %d", button, (int)((char)button)));
n = c2n(button, state->order); n = c2n(button, state->order);
@ -1317,14 +1336,10 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
sprintf(buf, "%c%d,%d,%d", sprintf(buf, "%c%d,%d,%d",
(char)(ui->hpencil && n > 0 ? 'P' : 'R'), ui->hx, ui->hy, n); (char)(ui->hpencil && n > 0 ? 'P' : 'R'), ui->hx, ui->hy, n);
ui->hx = ui->hy = -1; if (!ui->hcursor) ui->hshow = 0;
return dupstr(buf); return dupstr(buf);
} }
if (button == 'H' || button == 'h')
return dupstr("H");
return NULL; return NULL;
} }
@ -1370,6 +1385,16 @@ static game_state *execute_move(game_state *state, char *move)
rc = check_complete(ret->nums, ret, 1); rc = check_complete(ret->nums, ret, 1);
assert(rc > 0); assert(rc > 0);
return ret; return ret;
} else if (move[0] == 'M') {
ret = dup_game(state);
for (x = 0; x < state->order; x++) {
for (y = 0; y < state->order; y++) {
for (n = 0; n < state->order; n++) {
HINT(ret, x, y, n) = 1;
}
}
}
return ret;
} else if (move[0] == 'H') { } else if (move[0] == 'H') {
return solver_hint(state, NULL, DIFF_EASY, DIFF_EASY); return solver_hint(state, NULL, DIFF_EASY, DIFF_EASY);
} }
@ -1446,8 +1471,8 @@ static game_drawstate *game_new_drawstate(drawing *dr, game_state *state)
memset(ds->hints, 0, o3); memset(ds->hints, 0, o3);
memset(ds->flags, 0, o2*sizeof(unsigned int)); memset(ds->flags, 0, o2*sizeof(unsigned int));
ds->hx = ds->hy = ds->cx = ds->cy = -1; ds->hx = ds->hy = 0;
ds->started = ds->hpencil = ds->hflash = 0; ds->started = ds->hshow = ds->hpencil = ds->hflash = 0;
return ds; return ds;
} }
@ -1497,13 +1522,12 @@ static void draw_gts(drawing *dr, game_drawstate *ds, int ox, int oy,
static void draw_furniture(drawing *dr, game_drawstate *ds, game_state *state, static void draw_furniture(drawing *dr, game_drawstate *ds, game_state *state,
game_ui *ui, int x, int y, int hflash) game_ui *ui, int x, int y, int hflash)
{ {
int ox = COORD(x), oy = COORD(y), bg, hon, con; int ox = COORD(x), oy = COORD(y), bg, hon;
unsigned int f = GRID(state, flags, x, y); unsigned int f = GRID(state, flags, x, y);
bg = hflash ? COL_HIGHLIGHT : COL_BACKGROUND; bg = hflash ? COL_HIGHLIGHT : COL_BACKGROUND;
hon = (x == ui->hx && y == ui->hy); hon = (ui->hshow && x == ui->hx && y == ui->hy);
con = (x == ui->cx && y == ui->cy);
/* Clear square. */ /* Clear square. */
draw_rect(dr, ox, oy, TILE_SIZE, TILE_SIZE, draw_rect(dr, ox, oy, TILE_SIZE, TILE_SIZE,
@ -1522,8 +1546,7 @@ static void draw_furniture(drawing *dr, game_drawstate *ds, game_state *state,
} }
/* Draw the square outline (which is the cursor, if we're the cursor). */ /* Draw the square outline (which is the cursor, if we're the cursor). */
draw_rect_outline(dr, ox, oy, TILE_SIZE, TILE_SIZE, draw_rect_outline(dr, ox, oy, TILE_SIZE, TILE_SIZE, COL_GRID);
con ? COL_GUESS : COL_GRID);
draw_update(dr, ox, oy, TILE_SIZE, TILE_SIZE); draw_update(dr, ox, oy, TILE_SIZE, TILE_SIZE);
@ -1588,7 +1611,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
game_state *state, int dir, game_ui *ui, game_state *state, int dir, game_ui *ui,
float animtime, float flashtime) float animtime, float flashtime)
{ {
int x, y, i, hchanged = 0, cchanged = 0, stale, hflash = 0; int x, y, i, hchanged = 0, stale, hflash = 0;
debug(("highlight old (%d,%d), new (%d,%d)", ds->hx, ds->hy, ui->hx, ui->hy)); debug(("highlight old (%d,%d), new (%d,%d)", ds->hx, ds->hy, ui->hx, ui->hy));
@ -1600,10 +1623,9 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
draw_rect(dr, 0, 0, DRAW_SIZE, DRAW_SIZE, COL_BACKGROUND); draw_rect(dr, 0, 0, DRAW_SIZE, DRAW_SIZE, COL_BACKGROUND);
draw_update(dr, 0, 0, DRAW_SIZE, DRAW_SIZE); draw_update(dr, 0, 0, DRAW_SIZE, DRAW_SIZE);
} }
if (ds->hx != ui->hx || ds->hy != ui->hy || ds->hpencil != ui->hpencil) if (ds->hx != ui->hx || ds->hy != ui->hy ||
ds->hshow != ui->hshow || ds->hpencil != ui->hpencil)
hchanged = 1; hchanged = 1;
if (ds->cx != ui->cx || ds->cy != ui->cy)
cchanged = 1;
for (x = 0; x < ds->order; x++) { for (x = 0; x < ds->order; x++) {
for (y = 0; y < ds->order; y++) { for (y = 0; y < ds->order; y++) {
@ -1619,11 +1641,6 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
(x == ds->hx && y == ds->hy)) (x == ds->hx && y == ds->hy))
stale = 1; stale = 1;
} }
if (cchanged) {
if ((x == ui->cx && y == ui->cy) ||
(x == ds->cx && y == ds->cy))
stale = 1;
}
if (GRID(state, nums, x, y) != GRID(ds, nums, x, y)) { if (GRID(state, nums, x, y) != GRID(ds, nums, x, y)) {
GRID(ds, nums, x, y) = GRID(state, nums, x, y); GRID(ds, nums, x, y) = GRID(state, nums, x, y);
@ -1652,8 +1669,10 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
} }
} }
} }
ds->hx = ui->hx; ds->hy = ui->hy; ds->hpencil = ui->hpencil; ds->hx = ui->hx; ds->hy = ui->hy;
ds->cx = ui->cx; ds->cy = ui->cy; ds->hshow = ui->hshow;
ds->hpencil = ui->hpencil;
ds->started = 1; ds->started = 1;
ds->hflash = hflash; ds->hflash = hflash;
} }