mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
Keyboard cursor support for Tents, from James H.
[originally from svn r8416]
This commit is contained in:
@ -2006,6 +2006,11 @@ blank square in the region you cover will be turned green, and no
|
|||||||
other squares will be affected. (This is useful for clearing the
|
other squares will be affected. (This is useful for clearing the
|
||||||
remainder of a row once you have placed all its tents.)
|
remainder of a row once you have placed all its tents.)
|
||||||
|
|
||||||
|
You can also use the cursor keys to move around the grid. Pressing the
|
||||||
|
return key over an empty square will place a tent, and pressing the
|
||||||
|
space bar over an empty square will colour it green; either key will
|
||||||
|
clear an occupied square.
|
||||||
|
|
||||||
(All the actions described in \k{common-actions} are also available.)
|
(All the actions described in \k{common-actions} are also available.)
|
||||||
|
|
||||||
\H{tents-parameters} \I{parameters, for Tents}Tents parameters
|
\H{tents-parameters} \I{parameters, for Tents}Tents parameters
|
||||||
|
74
tents.c
74
tents.c
@ -1414,6 +1414,8 @@ struct game_ui {
|
|||||||
int dex, dey; /* coords of drag end */
|
int dex, dey; /* coords of drag end */
|
||||||
int drag_button; /* -1 for none, or a button code */
|
int drag_button; /* -1 for none, or a button code */
|
||||||
int drag_ok; /* dragged off the window, to cancel */
|
int drag_ok; /* dragged off the window, to cancel */
|
||||||
|
|
||||||
|
int cx, cy, cdisp; /* cursor position, and ?display. */
|
||||||
};
|
};
|
||||||
|
|
||||||
static game_ui *new_ui(game_state *state)
|
static game_ui *new_ui(game_state *state)
|
||||||
@ -1423,6 +1425,7 @@ static game_ui *new_ui(game_state *state)
|
|||||||
ui->dex = ui->dey = -1;
|
ui->dex = ui->dey = -1;
|
||||||
ui->drag_button = -1;
|
ui->drag_button = -1;
|
||||||
ui->drag_ok = FALSE;
|
ui->drag_ok = FALSE;
|
||||||
|
ui->cx = ui->cy = ui->cdisp = 0;
|
||||||
return ui;
|
return ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1450,6 +1453,7 @@ struct game_drawstate {
|
|||||||
int started;
|
int started;
|
||||||
game_params p;
|
game_params p;
|
||||||
char *drawn;
|
char *drawn;
|
||||||
|
int cx, cy; /* last-drawn cursor pos, or (-1,-1) if absent. */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PREFERRED_TILESIZE 32
|
#define PREFERRED_TILESIZE 32
|
||||||
@ -1514,6 +1518,7 @@ 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 w = state->p.w, h = state->p.h;
|
int w = state->p.w, h = state->p.h;
|
||||||
|
char tmpbuf[80];
|
||||||
|
|
||||||
if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
|
if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
|
||||||
x = FROMCOORD(x);
|
x = FROMCOORD(x);
|
||||||
@ -1525,13 +1530,14 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
|
|||||||
ui->dsx = ui->dex = x;
|
ui->dsx = ui->dex = x;
|
||||||
ui->dsy = ui->dey = y;
|
ui->dsy = ui->dey = y;
|
||||||
ui->drag_ok = TRUE;
|
ui->drag_ok = TRUE;
|
||||||
|
ui->cdisp = 0;
|
||||||
return ""; /* ui updated */
|
return ""; /* ui updated */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((IS_MOUSE_DRAG(button) || IS_MOUSE_RELEASE(button)) &&
|
if ((IS_MOUSE_DRAG(button) || IS_MOUSE_RELEASE(button)) &&
|
||||||
ui->drag_button > 0) {
|
ui->drag_button > 0) {
|
||||||
int xmin, ymin, xmax, ymax;
|
int xmin, ymin, xmax, ymax;
|
||||||
char *buf, *sep, tmpbuf[80];
|
char *buf, *sep;
|
||||||
int buflen, bufsize, tmplen;
|
int buflen, bufsize, tmplen;
|
||||||
|
|
||||||
x = FROMCOORD(x);
|
x = FROMCOORD(x);
|
||||||
@ -1608,6 +1614,39 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_CURSOR_MOVE(button)) {
|
||||||
|
move_cursor(button, &ui->cx, &ui->cy, w, h, 0);
|
||||||
|
ui->cdisp = 1;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (ui->cdisp) {
|
||||||
|
char rep = 0;
|
||||||
|
int v = state->grid[ui->cy*w+ui->cx];
|
||||||
|
|
||||||
|
if (v != TREE) {
|
||||||
|
#ifdef SINGLE_CURSOR_SELECT
|
||||||
|
if (button == CURSOR_SELECT)
|
||||||
|
/* SELECT cycles T, N, B */
|
||||||
|
rep = v == BLANK ? 'T' : v == TENT ? 'N' : 'B';
|
||||||
|
#else
|
||||||
|
if (button == CURSOR_SELECT)
|
||||||
|
rep = v == BLANK ? 'T' : 'B';
|
||||||
|
else if (button == CURSOR_SELECT2)
|
||||||
|
rep = v == BLANK ? 'N' : 'B';
|
||||||
|
else if (button == 'T' || button == 'N' || button == 'B')
|
||||||
|
rep = (char)button;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rep) {
|
||||||
|
sprintf(tmpbuf, "%c%d,%d", (int)rep, ui->cx, ui->cy);
|
||||||
|
return dupstr(tmpbuf);
|
||||||
|
}
|
||||||
|
} else if (IS_CURSOR_SELECT(button)) {
|
||||||
|
ui->cdisp = 1;
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1856,6 +1895,7 @@ static game_drawstate *game_new_drawstate(drawing *dr, game_state *state)
|
|||||||
ds->p = state->p; /* structure copy */
|
ds->p = state->p; /* structure copy */
|
||||||
ds->drawn = snewn(w*h, char);
|
ds->drawn = snewn(w*h, char);
|
||||||
memset(ds->drawn, MAGIC, w*h);
|
memset(ds->drawn, MAGIC, w*h);
|
||||||
|
ds->cx = ds->cy = -1;
|
||||||
|
|
||||||
return ds;
|
return ds;
|
||||||
}
|
}
|
||||||
@ -1867,7 +1907,7 @@ static void game_free_drawstate(drawing *dr, game_drawstate *ds)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void draw_tile(drawing *dr, game_drawstate *ds,
|
static void draw_tile(drawing *dr, game_drawstate *ds,
|
||||||
int x, int y, int v, int printing)
|
int x, int y, int v, int cur, int printing)
|
||||||
{
|
{
|
||||||
int tx = COORD(x), ty = COORD(y);
|
int tx = COORD(x), ty = COORD(y);
|
||||||
int cx = tx + TILESIZE/2, cy = ty + TILESIZE/2;
|
int cx = tx + TILESIZE/2, cy = ty + TILESIZE/2;
|
||||||
@ -1911,6 +1951,12 @@ static void draw_tile(drawing *dr, game_drawstate *ds,
|
|||||||
draw_polygon(dr, coords, 3, (printing ? -1 : COL_TENT), COL_TENT);
|
draw_polygon(dr, coords, 3, (printing ? -1 : COL_TENT), COL_TENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cur) {
|
||||||
|
int coff = TILESIZE/8;
|
||||||
|
draw_rect_outline(dr, tx + coff, ty + coff,
|
||||||
|
TILESIZE - coff*2, TILESIZE - coff*2, COL_GRID);
|
||||||
|
}
|
||||||
|
|
||||||
unclip(dr);
|
unclip(dr);
|
||||||
draw_update(dr, tx+1, ty+1, TILESIZE-1, TILESIZE-1);
|
draw_update(dr, tx+1, ty+1, TILESIZE-1, TILESIZE-1);
|
||||||
}
|
}
|
||||||
@ -1924,6 +1970,13 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
|
|||||||
{
|
{
|
||||||
int w = state->p.w, h = state->p.h;
|
int w = state->p.w, h = state->p.h;
|
||||||
int x, y, flashing;
|
int x, y, flashing;
|
||||||
|
int cx = -1, cy = -1;
|
||||||
|
int cmoved = 0;
|
||||||
|
|
||||||
|
if (ui) {
|
||||||
|
if (ui->cdisp) { cx = ui->cx; cy = ui->cy; }
|
||||||
|
if (cx != ds->cx || cy != ds->cy) cmoved = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (printing || !ds->started) {
|
if (printing || !ds->started) {
|
||||||
if (!printing) {
|
if (!printing) {
|
||||||
@ -1975,6 +2028,7 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
|
|||||||
for (y = 0; y < h; y++)
|
for (y = 0; y < h; y++)
|
||||||
for (x = 0; x < w; x++) {
|
for (x = 0; x < w; x++) {
|
||||||
int v = state->grid[y*w+x];
|
int v = state->grid[y*w+x];
|
||||||
|
int credraw = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We deliberately do not take drag_ok into account
|
* We deliberately do not take drag_ok into account
|
||||||
@ -1988,12 +2042,18 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
|
|||||||
if (flashing && (v == TREE || v == TENT))
|
if (flashing && (v == TREE || v == TENT))
|
||||||
v = NONTENT;
|
v = NONTENT;
|
||||||
|
|
||||||
if (printing || ds->drawn[y*w+x] != v) {
|
if (cmoved) {
|
||||||
draw_tile(dr, ds, x, y, v, printing);
|
if ((x == cx && y == cy) ||
|
||||||
|
(x == ds->cx && y == ds->cy)) credraw = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (printing || ds->drawn[y*w+x] != v || credraw) {
|
||||||
|
draw_tile(dr, ds, x, y, v, (x == cx && y == cy), printing);
|
||||||
if (!printing)
|
if (!printing)
|
||||||
ds->drawn[y*w+x] = v;
|
ds->drawn[y*w+x] = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (cmoved) { ds->cx = cx; ds->cy = cy; }
|
||||||
}
|
}
|
||||||
|
|
||||||
static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
|
static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
|
||||||
@ -2032,8 +2092,8 @@ static void game_print_size(game_params *params, float *x, float *y)
|
|||||||
* I'll use 6mm squares by default.
|
* I'll use 6mm squares by default.
|
||||||
*/
|
*/
|
||||||
game_compute_size(params, 600, &pw, &ph);
|
game_compute_size(params, 600, &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)
|
||||||
@ -2185,3 +2245,5 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* vim: set shiftwidth=4 tabstop=8: */
|
||||||
|
Reference in New Issue
Block a user