X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/puzzles/blobdiff_plain/ab53eb64790d5bee44525c3a50a420a6816e2495..375c9b4d4c8b128dfd09125f4b61f6a00d8af104:/rect.c?ds=sidebyside diff --git a/rect.c b/rect.c index 0448958..95d1d8c 100644 --- a/rect.c +++ b/rect.c @@ -60,8 +60,9 @@ struct game_params { #define HRANGE(state,x,y) CRANGE(state,x,y,0,1) #define VRANGE(state,x,y) CRANGE(state,x,y,1,0) -#define TILE_SIZE 24 -#define BORDER 18 +#define PREFERRED_TILE_SIZE 24 +#define TILE_SIZE (ds->tilesize) +#define BORDER (TILE_SIZE * 3 / 4) #define CORNER_TOLERANCE 0.15F #define CENTRE_TOLERANCE 0.15F @@ -2034,6 +2035,14 @@ struct game_ui { * treated as a small drag rather than a click. */ int dragged; + /* + * These are the co-ordinates of the top-left and bottom-right squares + * in the drag box, respectively, or -1 otherwise. + */ + int x1; + int y1; + int x2; + int y2; }; static game_ui *new_ui(game_state *state) @@ -2044,6 +2053,10 @@ static game_ui *new_ui(game_state *state) ui->drag_end_x = -1; ui->drag_end_y = -1; ui->dragged = FALSE; + ui->x1 = -1; + ui->y1 = -1; + ui->x2 = -1; + ui->y2 = -1; return ui; } @@ -2139,20 +2152,11 @@ static void coord_round(float x, float y, int *xr, int *yr) static void ui_draw_rect(game_state *state, game_ui *ui, unsigned char *hedge, unsigned char *vedge, int c) { - int x1, x2, y1, y2, x, y, t; - - x1 = ui->drag_start_x; - x2 = ui->drag_end_x; - if (x2 < x1) { t = x1; x1 = x2; x2 = t; } - - y1 = ui->drag_start_y; - y2 = ui->drag_end_y; - if (y2 < y1) { t = y1; y1 = y2; y2 = t; } - - x1 = x1 / 2; /* rounds down */ - x2 = (x2+1) / 2; /* rounds up */ - y1 = y1 / 2; /* rounds down */ - y2 = (y2+1) / 2; /* rounds up */ + int x, y; + int x1 = ui->x1; + int y1 = ui->y1; + int x2 = ui->x2; + int y2 = ui->y2; /* * Draw horizontal edges of rectangles. @@ -2183,6 +2187,17 @@ static void ui_draw_rect(game_state *state, game_ui *ui, } } +static void game_changed_state(game_ui *ui, game_state *oldstate, + game_state *newstate) +{ +} + +struct game_drawstate { + int started; + int w, h, tilesize; + unsigned long *visible; +}; + static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds, int x, int y, int button) { int xc, yc; @@ -2211,10 +2226,26 @@ static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds, } if (xc != ui->drag_end_x || yc != ui->drag_end_y) { + int t; + ui->drag_end_x = xc; ui->drag_end_y = yc; ui->dragged = TRUE; active = TRUE; + + ui->x1 = ui->drag_start_x; + ui->x2 = ui->drag_end_x; + if (ui->x2 < ui->x1) { t = ui->x1; ui->x1 = ui->x2; ui->x2 = t; } + + ui->y1 = ui->drag_start_y; + ui->y2 = ui->drag_end_y; + if (ui->y2 < ui->y1) { t = ui->y1; ui->y1 = ui->y2; ui->y2 = t; } + + ui->x1 = ui->x1 / 2; /* rounds down */ + ui->x2 = (ui->x2+1) / 2; /* rounds up */ + ui->y1 = ui->y1 / 2; /* rounds down */ + ui->y2 = (ui->y2+1) / 2; /* rounds up */ + } ret = NULL; @@ -2266,6 +2297,10 @@ static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds, ui->drag_start_y = -1; ui->drag_end_x = -1; ui->drag_end_y = -1; + ui->x1 = -1; + ui->y1 = -1; + ui->x2 = -1; + ui->y2 = -1; ui->dragged = FALSE; active = TRUE; } @@ -2287,14 +2322,26 @@ static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds, #define COLOUR(k) ( (k)==1 ? COL_LINE : COL_DRAG ) #define MAX4(x,y,z,w) ( max(max(x,y),max(z,w)) ) -struct game_drawstate { - int started; - int w, h; - unsigned long *visible; -}; - -static void game_size(game_params *params, int *x, int *y) +static void game_size(game_params *params, game_drawstate *ds, + int *x, int *y, int expand) { + int tsx, tsy, ts; + /* + * Each window dimension equals the tile size times 1.5 more + * than the grid dimension (the border is 3/4 the width of the + * tiles). + * + * We must cast to unsigned before multiplying by two, because + * *x might be INT_MAX. + */ + tsx = 2 * (unsigned)*x / (2 * params->w + 3); + tsy = 2 * (unsigned)*y / (2 * params->h + 3); + ts = min(tsx, tsy); + if (expand) + ds->tilesize = ts; + else + ds->tilesize = min(ts, PREFERRED_TILE_SIZE); + *x = params->w * TILE_SIZE + 2*BORDER + 1; *y = params->h * TILE_SIZE + 2*BORDER + 1; } @@ -2338,6 +2385,7 @@ static game_drawstate *game_new_drawstate(game_state *state) ds->w = state->w; ds->h = state->h; ds->visible = snewn(ds->w * ds->h, unsigned long); + ds->tilesize = 0; /* not decided yet */ for (i = 0; i < ds->w * ds->h; i++) ds->visible[i] = 0xFFFF; @@ -2350,9 +2398,9 @@ static void game_free_drawstate(game_drawstate *ds) sfree(ds); } -static void draw_tile(frontend *fe, game_state *state, int x, int y, - unsigned char *hedge, unsigned char *vedge, - unsigned char *corners, int correct) +static void draw_tile(frontend *fe, game_drawstate *ds, game_state *state, + int x, int y, unsigned char *hedge, unsigned char *vedge, + unsigned char *corners, int correct) { int cx = COORD(x), cy = COORD(y); char str[80]; @@ -2485,16 +2533,36 @@ static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate, c |= CORRECT; if (index(ds,ds->visible,x,y) != c) { - draw_tile(fe, state, x, y, hedge, vedge, corners, + draw_tile(fe, ds, state, x, y, hedge, vedge, corners, (c & CORRECT) ? 1 : 0); index(ds,ds->visible,x,y) = c; } } + { + char buf[256]; + + if (ui->x1 >= 0 && ui->y1 >= 0 && + ui->x2 >= 0 && ui->y2 >= 0) { + sprintf(buf, "%dx%d ", + ui->x2-ui->x1, + ui->y2-ui->y1); + } else { + buf[0] = '\0'; + } + + if (state->cheated) + strcat(buf, "Auto-solved."); + else if (state->completed) + strcat(buf, "COMPLETED!"); + + status_bar(fe, buf); + } + if (hedge != state->hedge) { sfree(hedge); sfree(vedge); - } + } sfree(corners); sfree(correct); @@ -2517,7 +2585,7 @@ static float game_flash_length(game_state *oldstate, static int game_wants_statusbar(void) { - return FALSE; + return TRUE; } static int game_timing_state(game_state *state) @@ -2549,6 +2617,7 @@ const struct game thegame = { TRUE, game_text_format, new_ui, free_ui, + game_changed_state, make_move, game_size, game_colours,