mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-22 00:15:46 -07:00
Keyboard control patch for Pattern, from James H.
[originally from svn r8435]
This commit is contained in:
109
pattern.c
109
pattern.c
@ -18,6 +18,7 @@ enum {
|
|||||||
COL_TEXT,
|
COL_TEXT,
|
||||||
COL_UNKNOWN,
|
COL_UNKNOWN,
|
||||||
COL_GRID,
|
COL_GRID,
|
||||||
|
COL_CURSOR,
|
||||||
NCOLOURS
|
NCOLOURS
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -745,6 +746,7 @@ struct game_ui {
|
|||||||
int drag_end_x;
|
int drag_end_x;
|
||||||
int drag_end_y;
|
int drag_end_y;
|
||||||
int drag, release, state;
|
int drag, release, state;
|
||||||
|
int cur_x, cur_y, cur_visible;
|
||||||
};
|
};
|
||||||
|
|
||||||
static game_ui *new_ui(game_state *state)
|
static game_ui *new_ui(game_state *state)
|
||||||
@ -753,6 +755,7 @@ static game_ui *new_ui(game_state *state)
|
|||||||
|
|
||||||
ret = snew(game_ui);
|
ret = snew(game_ui);
|
||||||
ret->dragging = FALSE;
|
ret->dragging = FALSE;
|
||||||
|
ret->cur_x = ret->cur_y = ret->cur_visible = 0;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -781,6 +784,7 @@ struct game_drawstate {
|
|||||||
int w, h;
|
int w, h;
|
||||||
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, game_drawstate *ds,
|
static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
|
||||||
@ -824,6 +828,7 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
|
|||||||
|
|
||||||
ui->drag_start_x = ui->drag_end_x = x;
|
ui->drag_start_x = ui->drag_end_x = x;
|
||||||
ui->drag_start_y = ui->drag_end_y = y;
|
ui->drag_start_y = ui->drag_end_y = y;
|
||||||
|
ui->cur_visible = 0;
|
||||||
|
|
||||||
return ""; /* UI activity occurred */
|
return ""; /* UI activity occurred */
|
||||||
}
|
}
|
||||||
@ -884,6 +889,35 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
|
|||||||
return ""; /* UI activity occurred */
|
return ""; /* UI activity occurred */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_CURSOR_MOVE(button)) {
|
||||||
|
move_cursor(button, &ui->cur_x, &ui->cur_y, state->w, state->h, 0);
|
||||||
|
ui->cur_visible = 1;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (IS_CURSOR_SELECT(button)) {
|
||||||
|
int currstate = state->grid[ui->cur_y * state->w + ui->cur_x];
|
||||||
|
int newstate;
|
||||||
|
char buf[80];
|
||||||
|
|
||||||
|
if (!ui->cur_visible) {
|
||||||
|
ui->cur_visible = 1;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (button == CURSOR_SELECT2)
|
||||||
|
newstate = currstate == GRID_UNKNOWN ? GRID_EMPTY :
|
||||||
|
currstate == GRID_EMPTY ? GRID_FULL : GRID_UNKNOWN;
|
||||||
|
else
|
||||||
|
newstate = currstate == GRID_UNKNOWN ? GRID_FULL :
|
||||||
|
currstate == GRID_FULL ? GRID_EMPTY : GRID_UNKNOWN;
|
||||||
|
|
||||||
|
sprintf(buf, "%c%d,%d,%d,%d",
|
||||||
|
(char)(newstate == GRID_FULL ? 'F' :
|
||||||
|
newstate == GRID_EMPTY ? 'E' : 'U'),
|
||||||
|
ui->cur_x, ui->cur_y, 1, 1);
|
||||||
|
return dupstr(buf);
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -982,28 +1016,20 @@ static void game_set_size(drawing *dr, game_drawstate *ds,
|
|||||||
static float *game_colours(frontend *fe, int *ncolours)
|
static float *game_colours(frontend *fe, int *ncolours)
|
||||||
{
|
{
|
||||||
float *ret = snewn(3 * NCOLOURS, float);
|
float *ret = snewn(3 * NCOLOURS, float);
|
||||||
|
int i;
|
||||||
|
|
||||||
frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
|
frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]);
|
||||||
|
|
||||||
ret[COL_GRID * 3 + 0] = 0.3F;
|
for (i = 0; i < 3; i++) {
|
||||||
ret[COL_GRID * 3 + 1] = 0.3F;
|
ret[COL_GRID * 3 + i] = 0.3F;
|
||||||
ret[COL_GRID * 3 + 2] = 0.3F;
|
ret[COL_UNKNOWN * 3 + i] = 0.5F;
|
||||||
|
ret[COL_TEXT * 3 + i] = 0.0F;
|
||||||
ret[COL_UNKNOWN * 3 + 0] = 0.5F;
|
ret[COL_FULL * 3 + i] = 0.0F;
|
||||||
ret[COL_UNKNOWN * 3 + 1] = 0.5F;
|
ret[COL_EMPTY * 3 + i] = 1.0F;
|
||||||
ret[COL_UNKNOWN * 3 + 2] = 0.5F;
|
}
|
||||||
|
ret[COL_CURSOR * 3 + 0] = 1.0F;
|
||||||
ret[COL_TEXT * 3 + 0] = 0.0F;
|
ret[COL_CURSOR * 3 + 1] = 0.25F;
|
||||||
ret[COL_TEXT * 3 + 1] = 0.0F;
|
ret[COL_CURSOR * 3 + 2] = 0.25F;
|
||||||
ret[COL_TEXT * 3 + 2] = 0.0F;
|
|
||||||
|
|
||||||
ret[COL_FULL * 3 + 0] = 0.0F;
|
|
||||||
ret[COL_FULL * 3 + 1] = 0.0F;
|
|
||||||
ret[COL_FULL * 3 + 2] = 0.0F;
|
|
||||||
|
|
||||||
ret[COL_EMPTY * 3 + 0] = 1.0F;
|
|
||||||
ret[COL_EMPTY * 3 + 1] = 1.0F;
|
|
||||||
ret[COL_EMPTY * 3 + 2] = 1.0F;
|
|
||||||
|
|
||||||
*ncolours = NCOLOURS;
|
*ncolours = NCOLOURS;
|
||||||
return ret;
|
return ret;
|
||||||
@ -1030,9 +1056,9 @@ static void game_free_drawstate(drawing *dr, game_drawstate *ds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void grid_square(drawing *dr, game_drawstate *ds,
|
static void grid_square(drawing *dr, game_drawstate *ds,
|
||||||
int y, int x, int state)
|
int y, int x, int state, int cur)
|
||||||
{
|
{
|
||||||
int xl, xr, yt, yb;
|
int xl, xr, yt, yb, dx, dy, dw, dh;
|
||||||
|
|
||||||
draw_rect(dr, TOCOORD(ds->w, x), TOCOORD(ds->h, y),
|
draw_rect(dr, TOCOORD(ds->w, x), TOCOORD(ds->h, y),
|
||||||
TILE_SIZE, TILE_SIZE, COL_GRID);
|
TILE_SIZE, TILE_SIZE, COL_GRID);
|
||||||
@ -1042,10 +1068,18 @@ static void grid_square(drawing *dr, game_drawstate *ds,
|
|||||||
xr = (x % 5 == 4 || x == ds->w-1 ? 1 : 0);
|
xr = (x % 5 == 4 || x == ds->w-1 ? 1 : 0);
|
||||||
yb = (y % 5 == 4 || y == ds->h-1 ? 1 : 0);
|
yb = (y % 5 == 4 || y == ds->h-1 ? 1 : 0);
|
||||||
|
|
||||||
draw_rect(dr, TOCOORD(ds->w, x) + 1 + xl, TOCOORD(ds->h, y) + 1 + yt,
|
dx = TOCOORD(ds->w, x) + 1 + xl;
|
||||||
TILE_SIZE - xl - xr - 1, TILE_SIZE - yt - yb - 1,
|
dy = TOCOORD(ds->h, y) + 1 + yt;
|
||||||
|
dw = TILE_SIZE - xl - xr - 1;
|
||||||
|
dh = TILE_SIZE - yt - yb - 1;
|
||||||
|
|
||||||
|
draw_rect(dr, dx, dy, dw, dh,
|
||||||
(state == GRID_FULL ? COL_FULL :
|
(state == GRID_FULL ? COL_FULL :
|
||||||
state == GRID_EMPTY ? COL_EMPTY : COL_UNKNOWN));
|
state == GRID_EMPTY ? COL_EMPTY : COL_UNKNOWN));
|
||||||
|
if (cur) {
|
||||||
|
draw_rect_outline(dr, dx, dy, dw, dh, COL_CURSOR);
|
||||||
|
draw_rect_outline(dr, dx+1, dy+1, dw-2, dh-2, COL_CURSOR);
|
||||||
|
}
|
||||||
|
|
||||||
draw_update(dr, TOCOORD(ds->w, x), TOCOORD(ds->h, y),
|
draw_update(dr, TOCOORD(ds->w, x), TOCOORD(ds->h, y),
|
||||||
TILE_SIZE, TILE_SIZE);
|
TILE_SIZE, TILE_SIZE);
|
||||||
@ -1100,6 +1134,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
|
|||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
int x1, x2, y1, y2;
|
int x1, x2, y1, y2;
|
||||||
|
int cx, cy, cmoved;
|
||||||
|
|
||||||
if (!ds->started) {
|
if (!ds->started) {
|
||||||
/*
|
/*
|
||||||
@ -1136,13 +1171,20 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
|
|||||||
x1 = x2 = y1 = y2 = -1; /* placate gcc warnings */
|
x1 = x2 = y1 = y2 = -1; /* placate gcc warnings */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ui->cur_visible) {
|
||||||
|
cx = ui->cur_x; cy = ui->cur_y;
|
||||||
|
} else {
|
||||||
|
cx = cy = -1;
|
||||||
|
}
|
||||||
|
cmoved = (cx != ds->cur_x || cy != ds->cur_y);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now draw any grid squares which have changed since last
|
* Now draw any grid squares which have changed since last
|
||||||
* redraw.
|
* redraw.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < ds->h; i++) {
|
for (i = 0; i < ds->h; i++) {
|
||||||
for (j = 0; j < ds->w; j++) {
|
for (j = 0; j < ds->w; j++) {
|
||||||
int val;
|
int val, cc = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Work out what state this square should be drawn in,
|
* Work out what state this square should be drawn in,
|
||||||
@ -1153,6 +1195,13 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
|
|||||||
else
|
else
|
||||||
val = state->grid[i * state->w + j];
|
val = state->grid[i * state->w + j];
|
||||||
|
|
||||||
|
if (cmoved) {
|
||||||
|
/* the cursor has moved; if we were the old or
|
||||||
|
* the new cursor position we need to redraw. */
|
||||||
|
if (j == cx && i == cy) cc = 1;
|
||||||
|
if (j == ds->cur_x && i == ds->cur_y) cc = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Briefly invert everything twice during a completion
|
* Briefly invert everything twice during a completion
|
||||||
* flash.
|
* flash.
|
||||||
@ -1162,12 +1211,14 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
|
|||||||
val != GRID_UNKNOWN)
|
val != GRID_UNKNOWN)
|
||||||
val = (GRID_FULL ^ GRID_EMPTY) ^ val;
|
val = (GRID_FULL ^ GRID_EMPTY) ^ val;
|
||||||
|
|
||||||
if (ds->visible[i * ds->w + j] != val) {
|
if (ds->visible[i * ds->w + j] != val || cc) {
|
||||||
grid_square(dr, ds, i, j, val);
|
grid_square(dr, ds, i, j, val,
|
||||||
|
(j == cx && i == cy));
|
||||||
ds->visible[i * ds->w + j] = val;
|
ds->visible[i * ds->w + j] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ds->cur_x = cx; ds->cur_y = cy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static float game_anim_length(game_state *oldstate,
|
static float game_anim_length(game_state *oldstate,
|
||||||
@ -1198,8 +1249,8 @@ static void game_print_size(game_params *params, float *x, float *y)
|
|||||||
* I'll use 5mm squares by default.
|
* I'll use 5mm squares by default.
|
||||||
*/
|
*/
|
||||||
game_compute_size(params, 500, &pw, &ph);
|
game_compute_size(params, 500, &pw, &ph);
|
||||||
*x = pw / 100.0;
|
*x = pw / 100.0F;
|
||||||
*y = ph / 100.0;
|
*y = ph / 100.0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void game_print(drawing *dr, game_state *state, int tilesize)
|
static void game_print(drawing *dr, game_state *state, int tilesize)
|
||||||
@ -1379,3 +1430,5 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* vim: set shiftwidth=4 tabstop=8: */
|
||||||
|
@ -884,6 +884,10 @@ a vertical or horizontal line of squares black or white at a time
|
|||||||
with Shift held down, you can colour a whole rectangle of squares
|
with Shift held down, you can colour a whole rectangle of squares
|
||||||
grey.
|
grey.
|
||||||
|
|
||||||
|
You can also move around the grid with the cursor keys. Pressing the
|
||||||
|
return key will cycle the current cell through empty --> black -->
|
||||||
|
white --> empty, and the space bar does the same cycle in reverse.
|
||||||
|
|
||||||
(All the actions described in \k{common-actions} are also available.)
|
(All the actions described in \k{common-actions} are also available.)
|
||||||
|
|
||||||
\H{pattern-parameters} \I{parameters, for Pattern}Pattern parameters
|
\H{pattern-parameters} \I{parameters, for Pattern}Pattern parameters
|
||||||
|
Reference in New Issue
Block a user