#define TILE_SIZE (ds->sz6*6)
#define BORDER (TILE_SIZE/8)
-#define BORDER_WIDTH (max(TILE_SIZE / 32, 1))
+#define LINE_THICK (TILE_SIZE/16)
+#define GRID_LINE_TL (ds->grid_line_tl)
+#define GRID_LINE_BR (ds->grid_line_br)
+#define GRID_LINE_ALL (ds->grid_line_all)
#define COORD(x) ( (x+1) * TILE_SIZE + BORDER )
#define CENTERED_COORD(x) ( COORD(x) + TILE_SIZE/2 )
#define DS_CSHIFT 20 /* R/U/L/D shift, for cursor-on-edge */
struct game_drawstate {
- int sz6;
+ int sz6, grid_line_all, grid_line_tl, grid_line_br;
int started;
int w, h, sz;
int sz6;
} ads, *ds = &ads;
ads.sz6 = tilesize/6;
-
*x = (params->w+2) * TILE_SIZE + 2 * BORDER;
*y = (params->h+2) * TILE_SIZE + 2 * BORDER;
}
const game_params *params, int tilesize)
{
ds->sz6 = tilesize/6;
+ ds->grid_line_all = max(LINE_THICK, 1);
+ ds->grid_line_br = ds->grid_line_all / 2;
+ ds->grid_line_tl = ds->grid_line_all - ds->grid_line_br;
}
enum {
COL_GRID, COL_CLUE, COL_CURSOR,
COL_TRACK, COL_TRACK_CLUE, COL_SLEEPER,
COL_DRAGON, COL_DRAGOFF,
- COL_ERROR, COL_FLASH,
+ COL_ERROR, COL_FLASH, COL_ERROR_BACKGROUND,
NCOLOURS
};
game_mkhighlight(fe, ret, COL_BACKGROUND, COL_HIGHLIGHT, COL_LOWLIGHT);
for (i = 0; i < 3; i++) {
- ret[COL_TRACK_CLUE * 3 + i] = 0.0F;
- ret[COL_TRACK * 3 + i] = 0.5F;
- ret[COL_CLUE * 3 + i] = 0.0F;
- ret[COL_GRID * 3 + i] = 0.75F;
- ret[COL_CURSOR * 3 + i] = 0.6F;
+ ret[COL_TRACK_CLUE * 3 + i] = 0.0F;
+ ret[COL_TRACK * 3 + i] = 0.5F;
+ ret[COL_CLUE * 3 + i] = 0.0F;
+ ret[COL_GRID * 3 + i] = 0.75F;
+ ret[COL_CURSOR * 3 + i] = 0.6F;
+ ret[COL_ERROR_BACKGROUND * 3 + i] = 1.0F;
}
ret[COL_SLEEPER * 3 + 0] = 0.5F;
/* Clip to the grid square. */
clip(dr, ox, oy, TILE_SIZE, TILE_SIZE);
- /* Clear the square. */
+ /* Clear the square so that it's got an appropriately-sized border
+ * in COL_GRID and a central area in the right background colour. */
best_bits((flags & DS_TRACK) == DS_TRACK,
(flags_drag & DS_TRACK) == DS_TRACK, &bg);
- draw_rect(dr, ox, oy, TILE_SIZE, TILE_SIZE, bg);
-
- /* Draw outline of grid square */
- draw_line(dr, ox, oy, COORD(x+1), oy, COL_GRID);
- draw_line(dr, ox, oy, ox, COORD(y+1), COL_GRID);
+ draw_rect(dr, ox, oy, TILE_SIZE, TILE_SIZE, COL_GRID);
+ draw_rect(dr, ox + GRID_LINE_TL, oy + GRID_LINE_TL,
+ TILE_SIZE - GRID_LINE_ALL, TILE_SIZE - GRID_LINE_ALL, bg);
/* More outlines for clue squares. */
if (flags & DS_CURSOR) {
(flags_drag & DS_NOTRACK) == DS_NOTRACK, &c);
if (flags_best) {
off = HALFSZ/2;
- draw_line(dr, cx - off, cy - off, cx + off, cy + off, c);
- draw_line(dr, cx - off, cy + off, cx + off, cy - off, c);
+ draw_thick_line(dr, LINE_THICK, cx - off, cy - off, cx + off, cy + off, c);
+ draw_thick_line(dr, LINE_THICK, cx - off, cy + off, cx + off, cy - off, c);
}
c = COL_TRACK;
cx += (d == R) ? t2 : (d == L) ? -t2 : 0;
cy += (d == D) ? t2 : (d == U) ? -t2 : 0;
- draw_line(dr, cx - off, cy - off, cx + off, cy + off, c);
- draw_line(dr, cx - off, cy + off, cx + off, cy - off, c);
+ draw_thick_line(dr, LINE_THICK, cx - off, cy - off, cx + off, cy + off, c);
+ draw_thick_line(dr, LINE_THICK, cx - off, cy + off, cx + off, cy - off, c);
}
}
draw_update(dr, ox, oy, TILE_SIZE, TILE_SIZE);
}
-static void draw_clue(drawing *dr, game_drawstate *ds, int w, int clue, int i, int col)
+static void draw_clue(drawing *dr, game_drawstate *ds, int w, int clue, int i, int col, int bg)
{
int cx, cy, tsz = TILE_SIZE/2;
char buf[20];
cy = CENTERED_COORD(i-w);
}
- draw_rect(dr, cx - tsz + BORDER, cy - tsz + BORDER,
- TILE_SIZE - BORDER, TILE_SIZE - BORDER, COL_BACKGROUND);
+ draw_rect(dr, cx - tsz + GRID_LINE_TL, cy - tsz + GRID_LINE_TL,
+ TILE_SIZE - GRID_LINE_ALL, TILE_SIZE - GRID_LINE_ALL,
+ bg);
sprintf(buf, "%d", clue);
draw_text(dr, cx, cy, FONT_VARIABLE, tsz, ALIGN_VCENTRE|ALIGN_HCENTRE,
col, buf);
- draw_update(dr, cx - tsz, cy - tsz, TILE_SIZE, TILE_SIZE);
+ draw_update(dr, cx - tsz + GRID_LINE_TL, cy - tsz + GRID_LINE_TL,
+ TILE_SIZE - GRID_LINE_ALL, TILE_SIZE - GRID_LINE_ALL);
}
static void draw_loop_ends(drawing *dr, game_drawstate *ds,
draw_loop_ends(dr, ds, state, COL_CLUE);
- draw_line(dr, COORD(ds->w), COORD(0), COORD(ds->w), COORD(ds->h), COL_GRID);
- draw_line(dr, COORD(0), COORD(ds->h), COORD(ds->w), COORD(ds->h), COL_GRID);
+ draw_rect(dr, COORD(0) - GRID_LINE_BR, COORD(0) - GRID_LINE_BR,
+ ds->w * TILE_SIZE + GRID_LINE_ALL,
+ ds->h * TILE_SIZE + GRID_LINE_ALL, COL_GRID);
draw_update(dr, 0, 0, (w+2)*TILE_SIZE + 2*BORDER, (h+2)*TILE_SIZE + 2*BORDER);
if (force || (state->num_errors[i] != ds->num_errors[i])) {
ds->num_errors[i] = state->num_errors[i];
draw_clue(dr, ds, w, state->numbers->numbers[i], i,
- ds->num_errors[i] ? COL_ERROR : COL_CLUE);
+ ds->num_errors[i] ? COL_ERROR : COL_CLUE,
+ ds->num_errors[i] ? COL_ERROR_BACKGROUND : COL_BACKGROUND);
}
}
/* clue numbers, and loop ends */
for (i = 0; i < w+h; i++)
- draw_clue(dr, ds, w, state->numbers->numbers[i], i, black);
+ draw_clue(dr, ds, w, state->numbers->numbers[i], i,
+ black, COL_BACKGROUND);
draw_loop_ends(dr, ds, state, black);
/* clue tracks / solution */
const struct game thegame = {
"Train Tracks", "games.tracks", "tracks",
default_params,
- game_fetch_preset,
+ game_fetch_preset, NULL,
decode_params,
encode_params,
free_params,