X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/puzzles/blobdiff_plain/2705d3741495f136d9d092d873f9b1c803ba1d8f..0b119fd7d6d58c9cb8210477fa8c4573744c69d8:/tents.c diff --git a/tents.c b/tents.c index 869ba5e..6f6e343 100644 --- a/tents.c +++ b/tents.c @@ -1369,6 +1369,11 @@ static char *solve_game(game_state *state, game_state *currstate, } } +static int game_can_format_as_text_now(game_params *params) +{ + return TRUE; +} + static char *game_text_format(game_state *state) { int w = state->p.w, h = state->p.h; @@ -1409,6 +1414,8 @@ struct game_ui { int dex, dey; /* coords of drag end */ int drag_button; /* -1 for none, or a button code */ 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) @@ -1418,6 +1425,7 @@ static game_ui *new_ui(game_state *state) ui->dex = ui->dey = -1; ui->drag_button = -1; ui->drag_ok = FALSE; + ui->cx = ui->cy = ui->cdisp = 0; return ui; } @@ -1445,6 +1453,7 @@ struct game_drawstate { int started; game_params p; char *drawn; + int cx, cy; /* last-drawn cursor pos, or (-1,-1) if absent. */ }; #define PREFERRED_TILESIZE 32 @@ -1509,6 +1518,7 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds, int x, int y, int button) { int w = state->p.w, h = state->p.h; + char tmpbuf[80]; if (button == LEFT_BUTTON || button == RIGHT_BUTTON) { x = FROMCOORD(x); @@ -1520,13 +1530,14 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds, ui->dsx = ui->dex = x; ui->dsy = ui->dey = y; ui->drag_ok = TRUE; + ui->cdisp = 0; return ""; /* ui updated */ } if ((IS_MOUSE_DRAG(button) || IS_MOUSE_RELEASE(button)) && ui->drag_button > 0) { int xmin, ymin, xmax, ymax; - char *buf, *sep, tmpbuf[80]; + char *buf, *sep; int buflen, bufsize, tmplen; x = FROMCOORD(x); @@ -1603,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; } @@ -1798,7 +1842,8 @@ static void game_compute_size(game_params *params, int tilesize, int *x, int *y) { /* fool the macros */ - struct dummy { int tilesize; } dummy = { tilesize }, *ds = &dummy; + struct dummy { int tilesize; } dummy, *ds = &dummy; + dummy.tilesize = tilesize; *x = TLBORDER + BRBORDER + TILESIZE * params->w; *y = TLBORDER + BRBORDER + TILESIZE * params->h; @@ -1810,7 +1855,7 @@ static void game_set_size(drawing *dr, game_drawstate *ds, ds->tilesize = tilesize; } -static float *game_colours(frontend *fe, game_state *state, int *ncolours) +static float *game_colours(frontend *fe, int *ncolours) { float *ret = snewn(3 * NCOLOURS, float); @@ -1850,6 +1895,7 @@ static game_drawstate *game_new_drawstate(drawing *dr, game_state *state) ds->p = state->p; /* structure copy */ ds->drawn = snewn(w*h, char); memset(ds->drawn, MAGIC, w*h); + ds->cx = ds->cy = -1; return ds; } @@ -1861,7 +1907,7 @@ static void game_free_drawstate(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 cx = tx + TILESIZE/2, cy = ty + TILESIZE/2; @@ -1905,6 +1951,12 @@ static void draw_tile(drawing *dr, game_drawstate *ds, 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); draw_update(dr, tx+1, ty+1, TILESIZE-1, TILESIZE-1); } @@ -1918,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 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) { @@ -1969,6 +2028,7 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate, for (y = 0; y < h; y++) for (x = 0; x < w; x++) { int v = state->grid[y*w+x]; + int credraw = 0; /* * We deliberately do not take drag_ok into account @@ -1976,18 +2036,24 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate, * marginally nicer not to have the drag effects * flickering on and off disconcertingly. */ - if (ui->drag_button >= 0) + if (ui && ui->drag_button >= 0) v = drag_xform(ui, x, y, v); if (flashing && (v == TREE || v == TENT)) v = NONTENT; - if (printing || ds->drawn[y*w+x] != v) { - draw_tile(dr, ds, x, y, v, printing); + if (cmoved) { + 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) 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, @@ -2013,11 +2079,6 @@ static float game_flash_length(game_state *oldstate, game_state *newstate, return 0.0F; } -static int game_wants_statusbar(void) -{ - return FALSE; -} - static int game_timing_state(game_state *state, game_ui *ui) { return TRUE; @@ -2031,8 +2092,8 @@ static void game_print_size(game_params *params, float *x, float *y) * I'll use 6mm squares by default. */ game_compute_size(params, 600, &pw, &ph); - *x = pw / 100.0; - *y = ph / 100.0; + *x = pw / 100.0F; + *y = ph / 100.0F; } static void game_print(drawing *dr, game_state *state, int tilesize) @@ -2058,7 +2119,7 @@ static void game_print(drawing *dr, game_state *state, int tilesize) #endif const struct game thegame = { - "Tents", "games.tents", + "Tents", "games.tents", "tents", default_params, game_fetch_preset, decode_params, @@ -2073,7 +2134,7 @@ const struct game thegame = { dup_game, free_game, TRUE, solve_game, - FALSE, game_text_format, + FALSE, game_can_format_as_text_now, game_text_format, new_ui, free_ui, encode_ui, @@ -2089,9 +2150,9 @@ const struct game thegame = { game_anim_length, game_flash_length, TRUE, FALSE, game_print_size, game_print, - game_wants_statusbar, + FALSE, /* wants_statusbar */ FALSE, game_timing_state, - 0, /* flags */ + REQUIRE_RBUTTON, /* flags */ }; #ifdef STANDALONE_SOLVER @@ -2184,3 +2245,5 @@ int main(int argc, char **argv) } #endif + +/* vim: set shiftwidth=4 tabstop=8: */