Keyboard control patch for Slant, from James H.

[originally from svn r8417]
This commit is contained in:
Simon Tatham
2009-01-16 18:52:18 +00:00
parent 28acb0ebdc
commit 4169a54831
2 changed files with 45 additions and 10 deletions

View File

@ -1642,6 +1642,10 @@ blank, and if you right-click repeatedly the square will change from
blank to \cw{/} to \cw{\\} back to blank. (Therefore, you can play blank to \cw{/} to \cw{\\} back to blank. (Therefore, you can play
the game entirely with one button if you need to.) the game entirely with one button if you need to.)
You can also use the cursor keys to move around the grid. Pressing the
return or space keys will place a \cw{\\} or a \cw{/}, respectively,
and will then cycle them as above.
(All the actions described in \k{common-actions} are also available.) (All the actions described in \k{common-actions} are also available.)
\H{slant-parameters} \I{parameters, for Slant}Slant parameters \H{slant-parameters} \I{parameters, for Slant}Slant parameters

51
slant.c
View File

@ -39,6 +39,7 @@ enum {
COL_SLANT1, COL_SLANT1,
COL_SLANT2, COL_SLANT2,
COL_ERROR, COL_ERROR,
COL_CURSOR, COL_LOWLIGHT, /* LOWLIGHT currently not used. */
NCOLOURS NCOLOURS
}; };
@ -1594,13 +1595,20 @@ static char *game_text_format(game_state *state)
return ret; return ret;
} }
struct game_ui {
int cur_x, cur_y, 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 = ui->cur_y = ui->cur_visible = 0;
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)
@ -1648,6 +1656,7 @@ static void game_changed_state(game_ui *ui, game_state *oldstate,
#define ERR_TR 0x00008000L #define ERR_TR 0x00008000L
#define ERR_BL 0x00010000L #define ERR_BL 0x00010000L
#define ERR_BR 0x00020000L #define ERR_BR 0x00020000L
#define CURSOR 0x00040000L
struct game_drawstate { struct game_drawstate {
int tilesize; int tilesize;
@ -1660,11 +1669,11 @@ 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;
int v;
char buf[80];
enum { CLOCKWISE, ANTICLOCKWISE, NONE } action = NONE;
if (button == LEFT_BUTTON || button == RIGHT_BUTTON) { if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
int v;
char buf[80];
/* /*
* This is an utterly awful hack which I should really sort out * This is an utterly awful hack which I should really sort out
* by means of a proper configuration mechanism. One Slant * by means of a proper configuration mechanism. One Slant
@ -1687,13 +1696,29 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
button = LEFT_BUTTON; button = LEFT_BUTTON;
} }
} }
action = (button == LEFT_BUTTON) ? CLOCKWISE : ANTICLOCKWISE;
x = FROMCOORD(x); x = FROMCOORD(x);
y = FROMCOORD(y); y = FROMCOORD(y);
if (x < 0 || y < 0 || x >= w || y >= h) if (x < 0 || y < 0 || x >= w || y >= h)
return NULL; return NULL;
} else if (IS_CURSOR_SELECT(button)) {
if (!ui->cur_visible) {
ui->cur_visible = 1;
return "";
}
x = ui->cur_x;
y = ui->cur_y;
if (button == LEFT_BUTTON) { action = (button == CURSOR_SELECT2) ? ANTICLOCKWISE : CLOCKWISE;
} else if (IS_CURSOR_MOVE(button)) {
move_cursor(button, &ui->cur_x, &ui->cur_y, w, h, 0);
ui->cur_visible = 1;
return "";
}
if (action != NONE) {
if (action == CLOCKWISE) {
/* /*
* Left-clicking cycles blank -> \ -> / -> blank. * Left-clicking cycles blank -> \ -> / -> blank.
*/ */
@ -1784,7 +1809,8 @@ static float *game_colours(frontend *fe, int *ncolours)
{ {
float *ret = snewn(3 * NCOLOURS, float); float *ret = snewn(3 * NCOLOURS, float);
frontend_default_colour(fe, &ret[COL_BACKGROUND * 3]); /* CURSOR colour is a background highlight. LOWLIGHT is unused. */
game_mkhighlight(fe, ret, COL_BACKGROUND, COL_CURSOR, COL_LOWLIGHT);
ret[COL_GRID * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] * 0.7F; ret[COL_GRID * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] * 0.7F;
ret[COL_GRID * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] * 0.7F; ret[COL_GRID * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] * 0.7F;
@ -1843,7 +1869,7 @@ static void draw_clue(drawing *dr, game_drawstate *ds,
if (v < 0) if (v < 0)
return; return;
p[0] = v + '0'; p[0] = (char)v + '0';
p[1] = '\0'; p[1] = '\0';
draw_circle(dr, COORD(x), COORD(y), CLUE_RADIUS, draw_circle(dr, COORD(x), COORD(y), CLUE_RADIUS,
bg >= 0 ? bg : COL_BACKGROUND, ccol); bg >= 0 ? bg : COL_BACKGROUND, ccol);
@ -1862,7 +1888,8 @@ static void draw_tile(drawing *dr, game_drawstate *ds, game_clues *clues,
clip(dr, COORD(x), COORD(y), TILESIZE, TILESIZE); clip(dr, COORD(x), COORD(y), TILESIZE, TILESIZE);
draw_rect(dr, COORD(x), COORD(y), TILESIZE, TILESIZE, draw_rect(dr, COORD(x), COORD(y), TILESIZE, TILESIZE,
(v & FLASH) ? COL_GRID : COL_BACKGROUND); (v & FLASH) ? COL_GRID :
(v & CURSOR) ? COL_CURSOR : COL_BACKGROUND);
/* /*
* Draw the grid lines. * Draw the grid lines.
@ -2001,6 +2028,8 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
ds->todraw[(y+2)*(w+2)+(x+1)] |= ERR_T_L | ERR_C_TL; ds->todraw[(y+2)*(w+2)+(x+1)] |= ERR_T_L | ERR_C_TL;
} }
} }
if (ui->cur_visible && ui->cur_x == x && ui->cur_y == y)
ds->todraw[(y+1)*(w+2)+(x+1)] |= CURSOR;
} }
} }
@ -2056,8 +2085,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)
@ -2249,3 +2278,5 @@ int main(int argc, char **argv)
} }
#endif #endif
/* vim: set shiftwidth=4 tabstop=8: */