mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
Twiddle now has an additional mode in which tile orientation
matters. This mode is hard enough to scare the wossnames out of me, but that's no reason not to put it in anyway! [originally from svn r5713]
This commit is contained in:
13
puzzles.but
13
puzzles.but
@ -392,9 +392,9 @@ containing a number, and your aim is to arrange the numbers into
|
|||||||
ascending order.
|
ascending order.
|
||||||
|
|
||||||
In basic Twiddle, your move is to rotate a square group of four
|
In basic Twiddle, your move is to rotate a square group of four
|
||||||
tiles about their common centre. (Orientation is not significant:
|
tiles about their common centre. (Orientation is not significant in
|
||||||
tiles never end up upside down!) On more advanced settings, you can
|
the basic puzzle, although you can select it.) On more advanced
|
||||||
rotate a larger square group of tiles.
|
settings, you can rotate a larger square group of tiles.
|
||||||
|
|
||||||
I first saw this type of puzzle in the GameCube game \q{Metroid
|
I first saw this type of puzzle in the GameCube game \q{Metroid
|
||||||
Prime 2}. In the Main Gyro Chamber in that game, there is a puzzle
|
Prime 2}. In the Main Gyro Chamber in that game, there is a puzzle
|
||||||
@ -432,6 +432,13 @@ are groups of identical numbers. In the simplified puzzle your aim
|
|||||||
is just to arrange all the 1s into the first row, all the 2s into
|
is just to arrange all the 1s into the first row, all the 2s into
|
||||||
the second row, and so on.
|
the second row, and so on.
|
||||||
|
|
||||||
|
\b You can configure whether the orientation of tiles matters. If
|
||||||
|
you ask for an orientable puzzle, each tile will have a yellow bar
|
||||||
|
along the side that should be at the top, and a green bar along the
|
||||||
|
side that should be at the bottom. To remind you of which way round
|
||||||
|
things go, there will be coloured bars by the sides of the grid.
|
||||||
|
Line up matching colours horizontally to complete the puzzle.
|
||||||
|
|
||||||
|
|
||||||
\C{rectangles} \i{Rectangles}
|
\C{rectangles} \i{Rectangles}
|
||||||
|
|
||||||
|
182
twiddle.c
182
twiddle.c
@ -41,16 +41,20 @@ enum {
|
|||||||
COL_HIGHLIGHT_GENTLE,
|
COL_HIGHLIGHT_GENTLE,
|
||||||
COL_LOWLIGHT,
|
COL_LOWLIGHT,
|
||||||
COL_LOWLIGHT_GENTLE,
|
COL_LOWLIGHT_GENTLE,
|
||||||
|
COL_TOP,
|
||||||
|
COL_BOTTOM,
|
||||||
NCOLOURS
|
NCOLOURS
|
||||||
};
|
};
|
||||||
|
|
||||||
struct game_params {
|
struct game_params {
|
||||||
int w, h, n;
|
int w, h, n;
|
||||||
int rowsonly;
|
int rowsonly;
|
||||||
|
int orientable;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct game_state {
|
struct game_state {
|
||||||
int w, h, n;
|
int w, h, n;
|
||||||
|
int orientable;
|
||||||
int *grid;
|
int *grid;
|
||||||
int completed;
|
int completed;
|
||||||
int movecount;
|
int movecount;
|
||||||
@ -63,7 +67,7 @@ static game_params *default_params(void)
|
|||||||
|
|
||||||
ret->w = ret->h = 3;
|
ret->w = ret->h = 3;
|
||||||
ret->n = 2;
|
ret->n = 2;
|
||||||
ret->rowsonly = FALSE;
|
ret->rowsonly = ret->orientable = FALSE;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -87,9 +91,11 @@ static int game_fetch_preset(int i, char **name, game_params **params)
|
|||||||
char *title;
|
char *title;
|
||||||
game_params params;
|
game_params params;
|
||||||
} presets[] = {
|
} presets[] = {
|
||||||
{ "3x3 rows only", { 3, 3, 2, TRUE } },
|
{ "3x3 rows only", { 3, 3, 2, TRUE, FALSE } },
|
||||||
{ "3x3 normal", { 3, 3, 2, FALSE } },
|
{ "3x3 normal", { 3, 3, 2, FALSE, FALSE } },
|
||||||
|
{ "3x3 orientable", { 3, 3, 2, FALSE, TRUE } },
|
||||||
{ "4x4 normal", { 4, 4, 2, FALSE } },
|
{ "4x4 normal", { 4, 4, 2, FALSE } },
|
||||||
|
{ "4x4 orientable", { 4, 4, 2, FALSE, TRUE } },
|
||||||
{ "4x4 radius 3", { 4, 4, 3, FALSE } },
|
{ "4x4 radius 3", { 4, 4, 3, FALSE } },
|
||||||
{ "5x5 radius 3", { 5, 5, 3, FALSE } },
|
{ "5x5 radius 3", { 5, 5, 3, FALSE } },
|
||||||
{ "6x6 radius 4", { 6, 6, 4, FALSE } },
|
{ "6x6 radius 4", { 6, 6, 4, FALSE } },
|
||||||
@ -110,7 +116,7 @@ static game_params *decode_params(char const *string)
|
|||||||
|
|
||||||
ret->w = ret->h = atoi(string);
|
ret->w = ret->h = atoi(string);
|
||||||
ret->n = 2;
|
ret->n = 2;
|
||||||
ret->rowsonly = FALSE;
|
ret->rowsonly = ret->orientable = FALSE;
|
||||||
while (*string && isdigit(*string)) string++;
|
while (*string && isdigit(*string)) string++;
|
||||||
if (*string == 'x') {
|
if (*string == 'x') {
|
||||||
string++;
|
string++;
|
||||||
@ -122,9 +128,13 @@ static game_params *decode_params(char const *string)
|
|||||||
ret->n = atoi(string);
|
ret->n = atoi(string);
|
||||||
while (*string && isdigit(*string)) string++;
|
while (*string && isdigit(*string)) string++;
|
||||||
}
|
}
|
||||||
if (*string == 'r') {
|
while (*string) {
|
||||||
|
if (*string == 'r') {
|
||||||
|
ret->rowsonly = TRUE;
|
||||||
|
} else if (*string == 'o') {
|
||||||
|
ret->orientable = TRUE;
|
||||||
|
}
|
||||||
string++;
|
string++;
|
||||||
ret->rowsonly = TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -133,8 +143,9 @@ static game_params *decode_params(char const *string)
|
|||||||
static char *encode_params(game_params *params)
|
static char *encode_params(game_params *params)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
sprintf(buf, "%dx%dn%d%s", params->w, params->h, params->n,
|
sprintf(buf, "%dx%dn%d%s%s", params->w, params->h, params->n,
|
||||||
params->rowsonly ? "r" : "");
|
params->rowsonly ? "r" : "",
|
||||||
|
params->orientable ? "o" : "");
|
||||||
return dupstr(buf);
|
return dupstr(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +154,7 @@ static config_item *game_configure(game_params *params)
|
|||||||
config_item *ret;
|
config_item *ret;
|
||||||
char buf[80];
|
char buf[80];
|
||||||
|
|
||||||
ret = snewn(4, config_item);
|
ret = snewn(6, config_item);
|
||||||
|
|
||||||
ret[0].name = "Width";
|
ret[0].name = "Width";
|
||||||
ret[0].type = C_STRING;
|
ret[0].type = C_STRING;
|
||||||
@ -168,10 +179,15 @@ static config_item *game_configure(game_params *params)
|
|||||||
ret[3].sval = NULL;
|
ret[3].sval = NULL;
|
||||||
ret[3].ival = params->rowsonly;
|
ret[3].ival = params->rowsonly;
|
||||||
|
|
||||||
ret[4].name = NULL;
|
ret[4].name = "Orientation matters";
|
||||||
ret[4].type = C_END;
|
ret[4].type = C_BOOLEAN;
|
||||||
ret[4].sval = NULL;
|
ret[4].sval = NULL;
|
||||||
ret[4].ival = 0;
|
ret[4].ival = params->orientable;
|
||||||
|
|
||||||
|
ret[5].name = NULL;
|
||||||
|
ret[5].type = C_END;
|
||||||
|
ret[5].sval = NULL;
|
||||||
|
ret[5].ival = 0;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -184,6 +200,7 @@ static game_params *custom_params(config_item *cfg)
|
|||||||
ret->h = atoi(cfg[1].sval);
|
ret->h = atoi(cfg[1].sval);
|
||||||
ret->n = atoi(cfg[2].sval);
|
ret->n = atoi(cfg[2].sval);
|
||||||
ret->rowsonly = cfg[3].ival;
|
ret->rowsonly = cfg[3].ival;
|
||||||
|
ret->orientable = cfg[4].ival;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -207,7 +224,8 @@ static char *validate_params(game_params *params)
|
|||||||
* the centre is good for a user interface, but too inconvenient to
|
* the centre is good for a user interface, but too inconvenient to
|
||||||
* use internally.)
|
* use internally.)
|
||||||
*/
|
*/
|
||||||
static void do_rotate(int *grid, int w, int h, int n, int x, int y, int dir)
|
static void do_rotate(int *grid, int w, int h, int n, int orientable,
|
||||||
|
int x, int y, int dir)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
@ -249,19 +267,38 @@ static void do_rotate(int *grid, int w, int h, int n, int x, int y, int dir)
|
|||||||
for (k = 0; k < 4; k++)
|
for (k = 0; k < 4; k++)
|
||||||
g[k] = grid[p[k]];
|
g[k] = grid[p[k]];
|
||||||
|
|
||||||
for (k = 0; k < 4; k++)
|
for (k = 0; k < 4; k++) {
|
||||||
grid[p[k]] = g[(k+dir) & 3];
|
int v = g[(k+dir) & 3];
|
||||||
|
if (orientable)
|
||||||
|
v ^= ((v+dir) ^ v) & 3; /* alter orientation */
|
||||||
|
grid[p[k]] = v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't forget the orientation on the centre square, if n is
|
||||||
|
* odd.
|
||||||
|
*/
|
||||||
|
if (orientable && (n & 1)) {
|
||||||
|
int v = grid[n/2*(w+1)];
|
||||||
|
v ^= ((v+dir) ^ v) & 3; /* alter orientation */
|
||||||
|
grid[n/2*(w+1)] = v;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int grid_complete(int *grid, int wh)
|
static int grid_complete(int *grid, int wh, int orientable)
|
||||||
{
|
{
|
||||||
int ok = TRUE;
|
int ok = TRUE;
|
||||||
int i;
|
int i;
|
||||||
for (i = 1; i < wh; i++)
|
for (i = 1; i < wh; i++)
|
||||||
if (grid[i] < grid[i-1])
|
if (grid[i] < grid[i-1])
|
||||||
ok = FALSE;
|
ok = FALSE;
|
||||||
|
if (orientable) {
|
||||||
|
for (i = 0; i < wh; i++)
|
||||||
|
if (grid[i] & 3)
|
||||||
|
ok = FALSE;
|
||||||
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +316,7 @@ static char *new_game_seed(game_params *params, random_state *rs)
|
|||||||
*/
|
*/
|
||||||
grid = snewn(wh, int);
|
grid = snewn(wh, int);
|
||||||
for (i = 0; i < wh; i++)
|
for (i = 0; i < wh; i++)
|
||||||
grid[i] = (params->rowsonly ? i/w : i) + 1;
|
grid[i] = ((params->rowsonly ? i/w : i) + 1) * 4;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shuffle it. This game is complex enough that I don't feel up
|
* Shuffle it. This game is complex enough that I don't feel up
|
||||||
@ -294,13 +331,15 @@ static char *new_game_seed(game_params *params, random_state *rs)
|
|||||||
|
|
||||||
x = random_upto(rs, w - n + 1);
|
x = random_upto(rs, w - n + 1);
|
||||||
y = random_upto(rs, h - n + 1);
|
y = random_upto(rs, h - n + 1);
|
||||||
do_rotate(grid, w, h, n, x, y, 1 + random_upto(rs, 3));
|
do_rotate(grid, w, h, n, params->orientable,
|
||||||
|
x, y, 1 + random_upto(rs, 3));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Optionally one more move in case the entire grid has
|
* Optionally one more move in case the entire grid has
|
||||||
* happened to come out solved.
|
* happened to come out solved.
|
||||||
*/
|
*/
|
||||||
if (i == total_moves - 1 && grid_complete(grid, wh))
|
if (i == total_moves - 1 && grid_complete(grid, wh,
|
||||||
|
params->orientable))
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,6 +403,7 @@ static game_state *new_game(game_params *params, char *seed)
|
|||||||
state->w = w;
|
state->w = w;
|
||||||
state->h = h;
|
state->h = h;
|
||||||
state->n = n;
|
state->n = n;
|
||||||
|
state->orientable = params->orientable;
|
||||||
state->completed = 0;
|
state->completed = 0;
|
||||||
state->movecount = 0;
|
state->movecount = 0;
|
||||||
state->lastx = state->lasty = state->lastr = -1;
|
state->lastx = state->lasty = state->lastr = -1;
|
||||||
@ -390,6 +430,7 @@ static game_state *dup_game(game_state *state)
|
|||||||
ret->w = state->w;
|
ret->w = state->w;
|
||||||
ret->h = state->h;
|
ret->h = state->h;
|
||||||
ret->n = state->n;
|
ret->n = state->n;
|
||||||
|
ret->orientable = state->orientable;
|
||||||
ret->completed = state->completed;
|
ret->completed = state->completed;
|
||||||
ret->movecount = state->movecount;
|
ret->movecount = state->movecount;
|
||||||
ret->lastx = state->lastx;
|
ret->lastx = state->lastx;
|
||||||
@ -443,7 +484,7 @@ static game_state *make_move(game_state *from, game_ui *ui, int x, int y,
|
|||||||
ret = dup_game(from);
|
ret = dup_game(from);
|
||||||
ret->movecount++;
|
ret->movecount++;
|
||||||
dir = (button == LEFT_BUTTON ? 1 : -1);
|
dir = (button == LEFT_BUTTON ? 1 : -1);
|
||||||
do_rotate(ret->grid, w, h, n, x, y, dir);
|
do_rotate(ret->grid, w, h, n, ret->orientable, x, y, dir);
|
||||||
ret->lastx = x;
|
ret->lastx = x;
|
||||||
ret->lasty = y;
|
ret->lasty = y;
|
||||||
ret->lastr = dir;
|
ret->lastr = dir;
|
||||||
@ -452,7 +493,7 @@ static game_state *make_move(game_state *from, game_ui *ui, int x, int y,
|
|||||||
* See if the game has been completed. To do this we simply
|
* See if the game has been completed. To do this we simply
|
||||||
* test that the grid contents are in increasing order.
|
* test that the grid contents are in increasing order.
|
||||||
*/
|
*/
|
||||||
if (!ret->completed && grid_complete(ret->grid, wh))
|
if (!ret->completed && grid_complete(ret->grid, wh, ret->orientable))
|
||||||
ret->completed = ret->movecount;
|
ret->completed = ret->movecount;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -504,6 +545,14 @@ static float *game_colours(frontend *fe, game_state *state, int *ncolours)
|
|||||||
ret[COL_TEXT * 3 + i] = 0.0;
|
ret[COL_TEXT * 3 + i] = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret[COL_TOP * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] * 1.3F;
|
||||||
|
ret[COL_TOP * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] * 1.3F;
|
||||||
|
ret[COL_TOP * 3 + 2] = ret[COL_BACKGROUND * 3 + 2] * 0.6F;
|
||||||
|
|
||||||
|
ret[COL_BOTTOM * 3 + 0] = ret[COL_BACKGROUND * 3 + 0] * 0.6F;
|
||||||
|
ret[COL_BOTTOM * 3 + 1] = ret[COL_BACKGROUND * 3 + 1] * 1.3F;
|
||||||
|
ret[COL_BOTTOM * 3 + 2] = ret[COL_BACKGROUND * 3 + 2] * 0.6F;
|
||||||
|
|
||||||
*ncolours = NCOLOURS;
|
*ncolours = NCOLOURS;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -601,6 +650,9 @@ static void draw_tile(frontend *fe, game_state *state, int x, int y,
|
|||||||
draw_polygon(fe, coords, 3, TRUE, rot ? rot->tc : COL_HIGHLIGHT);
|
draw_polygon(fe, coords, 3, TRUE, rot ? rot->tc : COL_HIGHLIGHT);
|
||||||
draw_polygon(fe, coords, 3, FALSE, rot ? rot->tc : COL_HIGHLIGHT);
|
draw_polygon(fe, coords, 3, FALSE, rot ? rot->tc : COL_HIGHLIGHT);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now the main blank area in the centre of the tile.
|
||||||
|
*/
|
||||||
if (rot) {
|
if (rot) {
|
||||||
coords[0] = x + HIGHLIGHT_WIDTH;
|
coords[0] = x + HIGHLIGHT_WIDTH;
|
||||||
coords[1] = y + HIGHLIGHT_WIDTH;
|
coords[1] = y + HIGHLIGHT_WIDTH;
|
||||||
@ -622,10 +674,69 @@ static void draw_tile(frontend *fe, game_state *state, int x, int y,
|
|||||||
flash_colour);
|
flash_colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Next, the colour bars for orientation.
|
||||||
|
*/
|
||||||
|
if (state->orientable) {
|
||||||
|
int xw, yw, swap;
|
||||||
|
switch (tile & 3) {
|
||||||
|
case 0:
|
||||||
|
xw = TILE_SIZE - 3 - 2*HIGHLIGHT_WIDTH;
|
||||||
|
yw = HIGHLIGHT_WIDTH;
|
||||||
|
swap = FALSE;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
xw = HIGHLIGHT_WIDTH;
|
||||||
|
yw = TILE_SIZE - 3 - 2*HIGHLIGHT_WIDTH;
|
||||||
|
swap = FALSE;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
xw = TILE_SIZE - 3 - 2*HIGHLIGHT_WIDTH;
|
||||||
|
yw = HIGHLIGHT_WIDTH;
|
||||||
|
swap = TRUE;
|
||||||
|
break;
|
||||||
|
default /* case 3 */:
|
||||||
|
xw = HIGHLIGHT_WIDTH;
|
||||||
|
yw = TILE_SIZE - 3 - 2*HIGHLIGHT_WIDTH;
|
||||||
|
swap = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
coords[0] = x + HIGHLIGHT_WIDTH + 1;
|
||||||
|
coords[1] = y + HIGHLIGHT_WIDTH + 1;
|
||||||
|
rotate(coords+0, rot);
|
||||||
|
coords[2] = x + HIGHLIGHT_WIDTH + 1 + xw;
|
||||||
|
coords[3] = y + HIGHLIGHT_WIDTH + 1;
|
||||||
|
rotate(coords+2, rot);
|
||||||
|
coords[4] = x + HIGHLIGHT_WIDTH + 1 + xw;
|
||||||
|
coords[5] = y + HIGHLIGHT_WIDTH + 1 + yw;
|
||||||
|
rotate(coords+4, rot);
|
||||||
|
coords[6] = x + HIGHLIGHT_WIDTH + 1;
|
||||||
|
coords[7] = y + HIGHLIGHT_WIDTH + 1 + yw;
|
||||||
|
rotate(coords+6, rot);
|
||||||
|
draw_polygon(fe, coords, 4, TRUE, swap ? COL_BOTTOM : COL_TOP);
|
||||||
|
draw_polygon(fe, coords, 4, FALSE, swap ? COL_BOTTOM : COL_TOP);
|
||||||
|
|
||||||
|
coords[0] = x + TILE_SIZE - 2 - HIGHLIGHT_WIDTH;
|
||||||
|
coords[1] = y + TILE_SIZE - 2 - HIGHLIGHT_WIDTH;
|
||||||
|
rotate(coords+0, rot);
|
||||||
|
coords[2] = x + TILE_SIZE - 2 - HIGHLIGHT_WIDTH - xw;
|
||||||
|
coords[3] = y + TILE_SIZE - 2 - HIGHLIGHT_WIDTH;
|
||||||
|
rotate(coords+2, rot);
|
||||||
|
coords[4] = x + TILE_SIZE - 2 - HIGHLIGHT_WIDTH - xw;
|
||||||
|
coords[5] = y + TILE_SIZE - 2 - HIGHLIGHT_WIDTH - yw;
|
||||||
|
rotate(coords+4, rot);
|
||||||
|
coords[6] = x + TILE_SIZE - 2 - HIGHLIGHT_WIDTH;
|
||||||
|
coords[7] = y + TILE_SIZE - 2 - HIGHLIGHT_WIDTH - yw;
|
||||||
|
rotate(coords+6, rot);
|
||||||
|
draw_polygon(fe, coords, 4, TRUE, swap ? COL_TOP : COL_BOTTOM);
|
||||||
|
draw_polygon(fe, coords, 4, FALSE, swap ? COL_TOP : COL_BOTTOM);
|
||||||
|
}
|
||||||
|
|
||||||
coords[0] = x + TILE_SIZE/2;
|
coords[0] = x + TILE_SIZE/2;
|
||||||
coords[1] = y + TILE_SIZE/2;
|
coords[1] = y + TILE_SIZE/2;
|
||||||
rotate(coords+0, rot);
|
rotate(coords+0, rot);
|
||||||
sprintf(str, "%d", tile);
|
sprintf(str, "%d", tile / 4);
|
||||||
draw_text(fe, coords[0], coords[1],
|
draw_text(fe, coords[0], coords[1],
|
||||||
FONT_VARIABLE, TILE_SIZE/3, ALIGN_VCENTRE | ALIGN_HCENTRE,
|
FONT_VARIABLE, TILE_SIZE/3, ALIGN_VCENTRE | ALIGN_HCENTRE,
|
||||||
COL_TEXT, str);
|
COL_TEXT, str);
|
||||||
@ -715,6 +826,33 @@ static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
|
|||||||
TILE_SIZE * state->w + 2 * BORDER,
|
TILE_SIZE * state->w + 2 * BORDER,
|
||||||
TILE_SIZE * state->h + 2 * BORDER);
|
TILE_SIZE * state->h + 2 * BORDER);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In an orientable puzzle, draw some colour bars at the
|
||||||
|
* sides as a gentle reminder of which colours need to be
|
||||||
|
* aligned where.
|
||||||
|
*/
|
||||||
|
if (state->orientable) {
|
||||||
|
int y;
|
||||||
|
for (y = 0; y < state->h; y++) {
|
||||||
|
draw_rect(fe, COORD(0) - BORDER / 2,
|
||||||
|
COORD(y) + HIGHLIGHT_WIDTH + 1,
|
||||||
|
BORDER / 2 - 2 * HIGHLIGHT_WIDTH,
|
||||||
|
HIGHLIGHT_WIDTH + 1, COL_TOP);
|
||||||
|
draw_rect(fe, COORD(state->w) + 2 * HIGHLIGHT_WIDTH,
|
||||||
|
COORD(y) + HIGHLIGHT_WIDTH + 1,
|
||||||
|
BORDER / 2 - 2 * HIGHLIGHT_WIDTH,
|
||||||
|
HIGHLIGHT_WIDTH + 1, COL_TOP);
|
||||||
|
draw_rect(fe, COORD(0) - BORDER / 2,
|
||||||
|
COORD(y) + TILE_SIZE - 2 - 2 * HIGHLIGHT_WIDTH,
|
||||||
|
BORDER / 2 - 2 * HIGHLIGHT_WIDTH,
|
||||||
|
HIGHLIGHT_WIDTH + 1, COL_BOTTOM);
|
||||||
|
draw_rect(fe, COORD(state->w) + 2 * HIGHLIGHT_WIDTH,
|
||||||
|
COORD(y) + TILE_SIZE - 2 - 2 * HIGHLIGHT_WIDTH,
|
||||||
|
BORDER / 2 - 2 * HIGHLIGHT_WIDTH,
|
||||||
|
HIGHLIGHT_WIDTH + 1, COL_BOTTOM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Recessed area containing the whole puzzle.
|
* Recessed area containing the whole puzzle.
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user