ref: 4a202808ee0be91d3a346076e71f45403bfa41de
parent: f20847354cb6335fd349204f16021a72e2956cce
author: Simon Tatham <[email protected]>
date: Mon Jan 12 15:23:56 EST 2009
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]
--- a/puzzles.but
+++ b/puzzles.but
@@ -1046,6 +1046,12 @@
will be done for you automatically; so sometimes when you uncover a
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.
Even Undo is available, although you might consider it cheating to
@@ -2189,6 +2195,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
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.)
--- a/unequal.c
+++ b/unequal.c
@@ -229,7 +229,7 @@
if (params->order < 3 || params->order > 32)
return "Order must be between 3 and 32";
if (params->diff >= DIFFCOUNT)
- return "Unknown difficulty rating.";
+ return "Unknown difficulty rating";
return NULL;
}
@@ -1210,8 +1210,8 @@
*/
struct game_ui {
- int hx, hy, hpencil; /* as for solo.c, highlight pos and type */
- int cx, cy; /* cursor position (-1,-1 for none) */
+ int hx, hy; /* as for solo.c, highlight pos */
+ int hshow, hpencil, hcursor; /* show state, type, and ?cursor. */
};
static game_ui *new_ui(game_state *state)
@@ -1218,11 +1218,9 @@
{
game_ui *ui = snew(game_ui);
- ui->hx = ui->hy = -1;
- ui->hpencil = 0;
+ ui->hx = ui->hy = 0;
+ ui->hpencil = ui->hshow = ui->hcursor = 0;
- ui->cx = ui->cy = -1;
-
return ui;
}
@@ -1246,20 +1244,19 @@
/* See solo.c; if we were pencil-mode highlighting and
* somehow a square has just been properly filled, cancel
* 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) {
- ui->hx = ui->hy = -1;
+ ui->hshow = 0;
}
}
struct game_drawstate {
int tilesize, order, started;
- digit *nums; /* copy of nums, o^2 */
- unsigned char *hints; /* copy of hints, o^3 */
+ digit *nums; /* copy of nums, o^2 */
+ unsigned char *hints; /* copy of hints, o^3 */
unsigned int *flags; /* o^2 */
- int hx, hy, hpencil;
- int cx, cy;
+ int hx, hy, hshow, hpencil; /* as for game_ui. */
int hflash;
};
@@ -1276,28 +1273,50 @@
if (button == LEFT_BUTTON) {
/* normal highlighting for non-immutable squares */
if (GRID(state, flags, x, y) & F_IMMUTABLE)
- ui->hx = ui->hy = -1;
- else if (x == ui->hx && y == ui->hy && ui->hpencil == 0)
- ui->hx = ui->hy = -1;
+ ui->hshow = 0;
+ else if (x == ui->hx && y == ui->hy &&
+ ui->hshow && ui->hpencil == 0)
+ ui->hshow = 0;
else {
ui->hx = x; ui->hy = y; ui->hpencil = 0;
+ ui->hshow = 1;
}
+ ui->hcursor = 0;
return "";
}
if (button == RIGHT_BUTTON) {
/* pencil highlighting for non-filled squares */
if (GRID(state, nums, x, y) != 0)
- ui->hx = ui->hy = -1;
- else if (x == ui->hx && y == ui->hy && ui->hpencil)
- ui->hx = ui->hy = -1;
+ ui->hshow = 0;
+ else if (x == ui->hx && y == ui->hy &&
+ ui->hshow && ui->hpencil)
+ ui->hshow = 0;
else {
ui->hx = x; ui->hy = y; ui->hpencil = 1;
+ ui->hshow = 1;
}
+ ui->hcursor = 0;
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)));
n = c2n(button, state->order);
@@ -1317,14 +1336,10 @@
sprintf(buf, "%c%d,%d,%d",
(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);
}
-
- if (button == 'H' || button == 'h')
- return dupstr("H");
-
return NULL;
}
@@ -1370,6 +1385,16 @@
rc = check_complete(ret->nums, ret, 1);
assert(rc > 0);
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') {
return solver_hint(state, NULL, DIFF_EASY, DIFF_EASY);
}
@@ -1446,8 +1471,8 @@
memset(ds->hints, 0, o3);
memset(ds->flags, 0, o2*sizeof(unsigned int));
- ds->hx = ds->hy = ds->cx = ds->cy = -1;
- ds->started = ds->hpencil = ds->hflash = 0;
+ ds->hx = ds->hy = 0;
+ ds->started = ds->hshow = ds->hpencil = ds->hflash = 0;
return ds;
}
@@ -1497,13 +1522,12 @@
static void draw_furniture(drawing *dr, game_drawstate *ds, game_state *state,
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);
bg = hflash ? COL_HIGHLIGHT : COL_BACKGROUND;
- hon = (x == ui->hx && y == ui->hy);
- con = (x == ui->cx && y == ui->cy);
+ hon = (ui->hshow && x == ui->hx && y == ui->hy);
/* Clear square. */
draw_rect(dr, ox, oy, TILE_SIZE, TILE_SIZE,
@@ -1522,8 +1546,7 @@
}
/* Draw the square outline (which is the cursor, if we're the cursor). */
- draw_rect_outline(dr, ox, oy, TILE_SIZE, TILE_SIZE,
- con ? COL_GUESS : COL_GRID);
+ draw_rect_outline(dr, ox, oy, TILE_SIZE, TILE_SIZE, COL_GRID);
draw_update(dr, ox, oy, TILE_SIZE, TILE_SIZE);
@@ -1588,7 +1611,7 @@
game_state *state, int dir, game_ui *ui,
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));
@@ -1600,10 +1623,9 @@
draw_rect(dr, 0, 0, DRAW_SIZE, DRAW_SIZE, COL_BACKGROUND);
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;
- if (ds->cx != ui->cx || ds->cy != ui->cy)
- cchanged = 1;
for (x = 0; x < ds->order; x++) {
for (y = 0; y < ds->order; y++) {
@@ -1619,11 +1641,6 @@
(x == ds->hx && y == ds->hy))
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)) {
GRID(ds, nums, x, y) = GRID(state, nums, x, y);
@@ -1652,8 +1669,10 @@
}
}
}
- ds->hx = ui->hx; ds->hy = ui->hy; ds->hpencil = ui->hpencil;
- ds->cx = ui->cx; ds->cy = ui->cy;
+ ds->hx = ui->hx; ds->hy = ui->hy;
+ ds->hshow = ui->hshow;
+ ds->hpencil = ui->hpencil;
+
ds->started = 1;
ds->hflash = hflash;
}