mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
Add an even more evil (!) game mode, in which it's not made
immediately obvious which element of the group is the identity - at least two elements including the identity have their rows and columns completely blanked. [originally from svn r8810]
This commit is contained in:
@ -24,17 +24,6 @@
|
|||||||
* (e.g. a group of order divisible by 5 must contain an
|
* (e.g. a group of order divisible by 5 must contain an
|
||||||
* element of order 5), but I think in fact this is probably
|
* element of order 5), but I think in fact this is probably
|
||||||
* silly.
|
* silly.
|
||||||
*
|
|
||||||
* - a mode which shuffles the identity element into the mix
|
|
||||||
* instead of keeping it clearly shown for you?
|
|
||||||
* * shuffle more fully during table generation
|
|
||||||
* * start clue removal by clearing the identity row and column
|
|
||||||
* completely, or else it'll be totally obvious where it is
|
|
||||||
* * have to print the group elements outside the grid
|
|
||||||
* * new_ui should start the cursor at 0,0 not 1,1, and cursor
|
|
||||||
* should not be constrained to x,y >= 1
|
|
||||||
* * get rid of the COL_IDENTITY highlights
|
|
||||||
* * will we need more checks in check_errors?
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -68,7 +57,6 @@ static char const group_diffchars[] = DIFFLIST(ENCODE);
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
COL_BACKGROUND,
|
COL_BACKGROUND,
|
||||||
COL_IDENTITY,
|
|
||||||
COL_GRID,
|
COL_GRID,
|
||||||
COL_USER,
|
COL_USER,
|
||||||
COL_HIGHLIGHT,
|
COL_HIGHLIGHT,
|
||||||
@ -84,7 +72,7 @@ enum {
|
|||||||
#define TOCHAR(c) ((c)>=10 ? (c)-10+'a' : (c)+'0')
|
#define TOCHAR(c) ((c)>=10 ? (c)-10+'a' : (c)+'0')
|
||||||
|
|
||||||
struct game_params {
|
struct game_params {
|
||||||
int w, diff;
|
int w, diff, id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct game_state {
|
struct game_state {
|
||||||
@ -101,13 +89,19 @@ static game_params *default_params(void)
|
|||||||
|
|
||||||
ret->w = 6;
|
ret->w = 6;
|
||||||
ret->diff = DIFF_NORMAL;
|
ret->diff = DIFF_NORMAL;
|
||||||
|
ret->id = TRUE;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
const static struct game_params group_presets[] = {
|
const static struct game_params group_presets[] = {
|
||||||
{ 4, DIFF_NORMAL },
|
{ 6, DIFF_NORMAL, TRUE },
|
||||||
{ 6, DIFF_NORMAL },
|
{ 6, DIFF_NORMAL, FALSE },
|
||||||
|
{ 6, DIFF_HARD, TRUE },
|
||||||
|
{ 6, DIFF_HARD, FALSE },
|
||||||
|
{ 8, DIFF_NORMAL, TRUE },
|
||||||
|
{ 8, DIFF_NORMAL, FALSE },
|
||||||
|
{ 12, DIFF_NORMAL, TRUE },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int game_fetch_preset(int i, char **name, game_params **params)
|
static int game_fetch_preset(int i, char **name, game_params **params)
|
||||||
@ -121,7 +115,8 @@ static int game_fetch_preset(int i, char **name, game_params **params)
|
|||||||
ret = snew(game_params);
|
ret = snew(game_params);
|
||||||
*ret = group_presets[i]; /* structure copy */
|
*ret = group_presets[i]; /* structure copy */
|
||||||
|
|
||||||
sprintf(buf, "%dx%d %s", ret->w, ret->w, group_diffnames[ret->diff]);
|
sprintf(buf, "%dx%d %s%s", ret->w, ret->w, group_diffnames[ret->diff],
|
||||||
|
ret->id ? "" : ", identity hidden");
|
||||||
|
|
||||||
*name = dupstr(buf);
|
*name = dupstr(buf);
|
||||||
*params = ret;
|
*params = ret;
|
||||||
@ -146,7 +141,10 @@ static void decode_params(game_params *params, char const *string)
|
|||||||
|
|
||||||
params->w = atoi(p);
|
params->w = atoi(p);
|
||||||
while (*p && isdigit((unsigned char)*p)) p++;
|
while (*p && isdigit((unsigned char)*p)) p++;
|
||||||
|
params->diff = DIFF_NORMAL;
|
||||||
|
params->id = TRUE;
|
||||||
|
|
||||||
|
while (*p) {
|
||||||
if (*p == 'd') {
|
if (*p == 'd') {
|
||||||
int i;
|
int i;
|
||||||
p++;
|
p++;
|
||||||
@ -158,6 +156,9 @@ static void decode_params(game_params *params, char const *string)
|
|||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
} else if (*p == 'i') {
|
||||||
|
params->id = FALSE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,6 +169,8 @@ static char *encode_params(game_params *params, int full)
|
|||||||
sprintf(ret, "%d", params->w);
|
sprintf(ret, "%d", params->w);
|
||||||
if (full)
|
if (full)
|
||||||
sprintf(ret + strlen(ret), "d%c", group_diffchars[params->diff]);
|
sprintf(ret + strlen(ret), "d%c", group_diffchars[params->diff]);
|
||||||
|
if (!params->id)
|
||||||
|
sprintf(ret + strlen(ret), "i");
|
||||||
|
|
||||||
return dupstr(ret);
|
return dupstr(ret);
|
||||||
}
|
}
|
||||||
@ -177,7 +180,7 @@ static config_item *game_configure(game_params *params)
|
|||||||
config_item *ret;
|
config_item *ret;
|
||||||
char buf[80];
|
char buf[80];
|
||||||
|
|
||||||
ret = snewn(3, config_item);
|
ret = snewn(4, config_item);
|
||||||
|
|
||||||
ret[0].name = "Grid size";
|
ret[0].name = "Grid size";
|
||||||
ret[0].type = C_STRING;
|
ret[0].type = C_STRING;
|
||||||
@ -190,10 +193,15 @@ static config_item *game_configure(game_params *params)
|
|||||||
ret[1].sval = DIFFCONFIG;
|
ret[1].sval = DIFFCONFIG;
|
||||||
ret[1].ival = params->diff;
|
ret[1].ival = params->diff;
|
||||||
|
|
||||||
ret[2].name = NULL;
|
ret[2].name = "Show identity";
|
||||||
ret[2].type = C_END;
|
ret[2].type = C_BOOLEAN;
|
||||||
ret[2].sval = NULL;
|
ret[2].sval = NULL;
|
||||||
ret[2].ival = 0;
|
ret[2].ival = params->id;
|
||||||
|
|
||||||
|
ret[3].name = NULL;
|
||||||
|
ret[3].type = C_END;
|
||||||
|
ret[3].sval = NULL;
|
||||||
|
ret[3].ival = 0;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -204,6 +212,7 @@ static game_params *custom_params(config_item *cfg)
|
|||||||
|
|
||||||
ret->w = atoi(cfg[0].sval);
|
ret->w = atoi(cfg[0].sval);
|
||||||
ret->diff = cfg[1].ival;
|
ret->diff = cfg[1].ival;
|
||||||
|
ret->id = cfg[2].ival;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -642,23 +651,43 @@ done
|
|||||||
}
|
}
|
||||||
/* That's got the canonical table. Now shuffle it. */
|
/* That's got the canonical table. Now shuffle it. */
|
||||||
for (i = 0; i < w; i++)
|
for (i = 0; i < w; i++)
|
||||||
grid[i] = i+1;
|
soln2[i] = i;
|
||||||
shuffle(grid+1, w-1, sizeof(*grid), rs);
|
if (params->id) /* do we shuffle in the identity? */
|
||||||
for (i = 1; i < w; i++)
|
shuffle(soln2+1, w-1, sizeof(*soln2), rs);
|
||||||
for (j = 0; j < w; j++)
|
else
|
||||||
grid[(grid[i]-1)*w+(grid[j]-1)] = grid[soln[i*w+j]-1];
|
shuffle(soln2, w, sizeof(*soln2), rs);
|
||||||
for (i = 0; i < w; i++)
|
for (i = 0; i < w; i++)
|
||||||
grid[i] = i+1;
|
for (j = 0; j < w; j++)
|
||||||
|
grid[(soln2[i])*w+(soln2[j])] = soln2[soln[i*w+j]-1]+1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Remove entries one by one while the puzzle is still
|
* Remove entries one by one while the puzzle is still
|
||||||
* soluble at the appropriate difficulty level.
|
* soluble at the appropriate difficulty level.
|
||||||
*/
|
*/
|
||||||
memcpy(soln, grid, a);
|
memcpy(soln, grid, a);
|
||||||
|
if (!params->id) {
|
||||||
|
/*
|
||||||
|
* Start by blanking the entire identity row and column,
|
||||||
|
* and also another row and column so that the player
|
||||||
|
* can't trivially determine which element is the
|
||||||
|
* identity.
|
||||||
|
*/
|
||||||
|
|
||||||
|
j = 1 + random_upto(rs, w-1); /* pick a second row/col to blank */
|
||||||
|
for (i = 0; i < w; i++) {
|
||||||
|
grid[(soln2[0])*w+i] = grid[i*w+(soln2[0])] = 0;
|
||||||
|
grid[(soln2[j])*w+i] = grid[i*w+(soln2[j])] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(soln2, grid, a);
|
||||||
|
if (solver(w, soln2, diff) > diff)
|
||||||
|
continue; /* go round again if that didn't work */
|
||||||
|
}
|
||||||
|
|
||||||
k = 0;
|
k = 0;
|
||||||
for (i = 1; i < w; i++)
|
for (i = (params->id ? 1 : 0); i < w; i++)
|
||||||
for (j = 1; j < w; j++)
|
for (j = (params->id ? 1 : 0); j < w; j++)
|
||||||
|
if (grid[i*w+j])
|
||||||
indices[k++] = i*w+j;
|
indices[k++] = i*w+j;
|
||||||
shuffle(indices, k, sizeof(*indices), rs);
|
shuffle(indices, k, sizeof(*indices), rs);
|
||||||
|
|
||||||
@ -933,7 +962,7 @@ static game_ui *new_ui(game_state *state)
|
|||||||
{
|
{
|
||||||
game_ui *ui = snew(game_ui);
|
game_ui *ui = snew(game_ui);
|
||||||
|
|
||||||
ui->hx = ui->hy = 1;
|
ui->hx = ui->hy = 0;
|
||||||
ui->hpencil = ui->hshow = ui->hcursor = 0;
|
ui->hpencil = ui->hshow = ui->hcursor = 0;
|
||||||
|
|
||||||
return ui;
|
return ui;
|
||||||
@ -972,9 +1001,10 @@ static void game_changed_state(game_ui *ui, game_state *oldstate,
|
|||||||
#define PREFERRED_TILESIZE 48
|
#define PREFERRED_TILESIZE 48
|
||||||
#define TILESIZE (ds->tilesize)
|
#define TILESIZE (ds->tilesize)
|
||||||
#define BORDER (TILESIZE / 2)
|
#define BORDER (TILESIZE / 2)
|
||||||
|
#define LEGEND (TILESIZE)
|
||||||
#define GRIDEXTRA max((TILESIZE / 32),1)
|
#define GRIDEXTRA max((TILESIZE / 32),1)
|
||||||
#define COORD(x) ((x)*TILESIZE + BORDER)
|
#define COORD(x) ((x)*TILESIZE + BORDER + LEGEND)
|
||||||
#define FROMCOORD(x) (((x)+(TILESIZE-BORDER)) / TILESIZE - 1)
|
#define FROMCOORD(x) (((x)+(TILESIZE-BORDER-LEGEND)) / TILESIZE - 1)
|
||||||
|
|
||||||
#define FLASH_TIME 0.4F
|
#define FLASH_TIME 0.4F
|
||||||
|
|
||||||
@ -1090,7 +1120,7 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
|
|||||||
tx = FROMCOORD(x);
|
tx = FROMCOORD(x);
|
||||||
ty = FROMCOORD(y);
|
ty = FROMCOORD(y);
|
||||||
|
|
||||||
if (tx > 0 && tx < w && ty > 0 && ty < w) {
|
if (tx >= 0 && tx < w && ty >= 0 && ty < w) {
|
||||||
if (button == LEFT_BUTTON) {
|
if (button == LEFT_BUTTON) {
|
||||||
if (tx == ui->hx && ty == ui->hy &&
|
if (tx == ui->hx && ty == ui->hy &&
|
||||||
ui->hshow && ui->hpencil == 0) {
|
ui->hshow && ui->hpencil == 0) {
|
||||||
@ -1126,9 +1156,7 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IS_CURSOR_MOVE(button)) {
|
if (IS_CURSOR_MOVE(button)) {
|
||||||
ui->hx--; ui->hy--;
|
move_cursor(button, &ui->hx, &ui->hy, w, w, 0);
|
||||||
move_cursor(button, &ui->hx, &ui->hy, w-1, w-1, 0);
|
|
||||||
ui->hx++; ui->hy++;
|
|
||||||
ui->hshow = ui->hcursor = 1;
|
ui->hshow = ui->hcursor = 1;
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -1236,7 +1264,7 @@ static game_state *execute_move(game_state *from, char *move)
|
|||||||
* Drawing routines.
|
* Drawing routines.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SIZE(w) ((w) * TILESIZE + 2*BORDER)
|
#define SIZE(w) ((w) * TILESIZE + 2*BORDER + LEGEND)
|
||||||
|
|
||||||
static void game_compute_size(game_params *params, int tilesize,
|
static void game_compute_size(game_params *params, int tilesize,
|
||||||
int *x, int *y)
|
int *x, int *y)
|
||||||
@ -1264,10 +1292,6 @@ static float *game_colours(frontend *fe, int *ncolours)
|
|||||||
ret[COL_GRID * 3 + 1] = 0.0F;
|
ret[COL_GRID * 3 + 1] = 0.0F;
|
||||||
ret[COL_GRID * 3 + 2] = 0.0F;
|
ret[COL_GRID * 3 + 2] = 0.0F;
|
||||||
|
|
||||||
ret[COL_IDENTITY * 3 + 0] = 0.89F * ret[COL_BACKGROUND * 3 + 0];
|
|
||||||
ret[COL_IDENTITY * 3 + 1] = 0.89F * ret[COL_BACKGROUND * 3 + 1];
|
|
||||||
ret[COL_IDENTITY * 3 + 2] = 0.89F * ret[COL_BACKGROUND * 3 + 2];
|
|
||||||
|
|
||||||
ret[COL_USER * 3 + 0] = 0.0F;
|
ret[COL_USER * 3 + 0] = 0.0F;
|
||||||
ret[COL_USER * 3 + 1] = 0.6F * ret[COL_BACKGROUND * 3 + 1];
|
ret[COL_USER * 3 + 1] = 0.6F * ret[COL_BACKGROUND * 3 + 1];
|
||||||
ret[COL_USER * 3 + 2] = 0.0F;
|
ret[COL_USER * 3 + 2] = 0.0F;
|
||||||
@ -1324,8 +1348,8 @@ static void draw_tile(drawing *dr, game_drawstate *ds, int x, int y, long tile,
|
|||||||
int cx, cy, cw, ch;
|
int cx, cy, cw, ch;
|
||||||
char str[64];
|
char str[64];
|
||||||
|
|
||||||
tx = BORDER + x * TILESIZE + 1;
|
tx = BORDER + LEGEND + x * TILESIZE + 1;
|
||||||
ty = BORDER + y * TILESIZE + 1;
|
ty = BORDER + LEGEND + y * TILESIZE + 1;
|
||||||
|
|
||||||
cx = tx;
|
cx = tx;
|
||||||
cy = ty;
|
cy = ty;
|
||||||
@ -1336,8 +1360,7 @@ static void draw_tile(drawing *dr, game_drawstate *ds, int x, int y, long tile,
|
|||||||
|
|
||||||
/* background needs erasing */
|
/* background needs erasing */
|
||||||
draw_rect(dr, cx, cy, cw, ch,
|
draw_rect(dr, cx, cy, cw, ch,
|
||||||
(tile & DF_HIGHLIGHT) ? COL_HIGHLIGHT :
|
(tile & DF_HIGHLIGHT) ? COL_HIGHLIGHT : COL_BACKGROUND);
|
||||||
(x == 0 || y == 0) ? COL_IDENTITY : COL_BACKGROUND);
|
|
||||||
|
|
||||||
/* pencil-mode highlight */
|
/* pencil-mode highlight */
|
||||||
if (tile & DF_HIGHLIGHT_PENCIL) {
|
if (tile & DF_HIGHLIGHT_PENCIL) {
|
||||||
@ -1492,6 +1515,21 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
|
|||||||
w*TILESIZE+1+GRIDEXTRA*2, w*TILESIZE+1+GRIDEXTRA*2,
|
w*TILESIZE+1+GRIDEXTRA*2, w*TILESIZE+1+GRIDEXTRA*2,
|
||||||
COL_GRID);
|
COL_GRID);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Table legend.
|
||||||
|
*/
|
||||||
|
for (x = 0; x < w; x++) {
|
||||||
|
char str[2];
|
||||||
|
str[1] = '\0';
|
||||||
|
str[0] = TOCHAR(x+1);
|
||||||
|
draw_text(dr, COORD(x) + TILESIZE/2, BORDER + TILESIZE/2,
|
||||||
|
FONT_VARIABLE, TILESIZE/2,
|
||||||
|
ALIGN_VCENTRE | ALIGN_HCENTRE, COL_GRID, str);
|
||||||
|
draw_text(dr, BORDER + TILESIZE/2, COORD(x) + TILESIZE/2,
|
||||||
|
FONT_VARIABLE, TILESIZE/2,
|
||||||
|
ALIGN_VCENTRE | ALIGN_HCENTRE, COL_GRID, str);
|
||||||
|
}
|
||||||
|
|
||||||
draw_update(dr, 0, 0, SIZE(w), SIZE(w));
|
draw_update(dr, 0, 0, SIZE(w), SIZE(w));
|
||||||
|
|
||||||
ds->started = TRUE;
|
ds->started = TRUE;
|
||||||
@ -1571,41 +1609,48 @@ static void game_print(drawing *dr, game_state *state, int tilesize)
|
|||||||
{
|
{
|
||||||
int w = state->par.w;
|
int w = state->par.w;
|
||||||
int ink = print_mono_colour(dr, 0);
|
int ink = print_mono_colour(dr, 0);
|
||||||
int ehighlight = print_grey_colour(dr, 0.90F);
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
/* Ick: fake up `ds->tilesize' for macro expansion purposes */
|
/* Ick: fake up `ds->tilesize' for macro expansion purposes */
|
||||||
game_drawstate ads, *ds = &ads;
|
game_drawstate ads, *ds = &ads;
|
||||||
game_set_size(dr, ds, NULL, tilesize);
|
game_set_size(dr, ds, NULL, tilesize);
|
||||||
|
|
||||||
/*
|
|
||||||
* Highlight the identity row and column.
|
|
||||||
*/
|
|
||||||
for (x = 1; x < w; x++)
|
|
||||||
draw_rect(dr, BORDER + x*TILESIZE, BORDER,
|
|
||||||
TILESIZE, TILESIZE, ehighlight);
|
|
||||||
for (y = 0; y < w; y++)
|
|
||||||
draw_rect(dr, BORDER, BORDER + y*TILESIZE,
|
|
||||||
TILESIZE, TILESIZE, ehighlight);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Border.
|
* Border.
|
||||||
*/
|
*/
|
||||||
print_line_width(dr, 3 * TILESIZE / 40);
|
print_line_width(dr, 3 * TILESIZE / 40);
|
||||||
draw_rect_outline(dr, BORDER, BORDER, w*TILESIZE, w*TILESIZE, ink);
|
draw_rect_outline(dr, BORDER + LEGEND, BORDER + LEGEND,
|
||||||
|
w*TILESIZE, w*TILESIZE, ink);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Legend on table.
|
||||||
|
*/
|
||||||
|
for (x = 0; x < w; x++) {
|
||||||
|
char str[2];
|
||||||
|
str[1] = '\0';
|
||||||
|
str[0] = TOCHAR(x+1);
|
||||||
|
draw_text(dr, BORDER+LEGEND + x*TILESIZE + TILESIZE/2,
|
||||||
|
BORDER + TILESIZE/2,
|
||||||
|
FONT_VARIABLE, TILESIZE/2,
|
||||||
|
ALIGN_VCENTRE | ALIGN_HCENTRE, ink, str);
|
||||||
|
draw_text(dr, BORDER + TILESIZE/2,
|
||||||
|
BORDER+LEGEND + x*TILESIZE + TILESIZE/2,
|
||||||
|
FONT_VARIABLE, TILESIZE/2,
|
||||||
|
ALIGN_VCENTRE | ALIGN_HCENTRE, ink, str);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Main grid.
|
* Main grid.
|
||||||
*/
|
*/
|
||||||
for (x = 1; x < w; x++) {
|
for (x = 1; x < w; x++) {
|
||||||
print_line_width(dr, TILESIZE / 40);
|
print_line_width(dr, TILESIZE / 40);
|
||||||
draw_line(dr, BORDER+x*TILESIZE, BORDER,
|
draw_line(dr, BORDER+LEGEND+x*TILESIZE, BORDER+LEGEND,
|
||||||
BORDER+x*TILESIZE, BORDER+w*TILESIZE, ink);
|
BORDER+LEGEND+x*TILESIZE, BORDER+LEGEND+w*TILESIZE, ink);
|
||||||
}
|
}
|
||||||
for (y = 1; y < w; y++) {
|
for (y = 1; y < w; y++) {
|
||||||
print_line_width(dr, TILESIZE / 40);
|
print_line_width(dr, TILESIZE / 40);
|
||||||
draw_line(dr, BORDER, BORDER+y*TILESIZE,
|
draw_line(dr, BORDER+LEGEND, BORDER+LEGEND+y*TILESIZE,
|
||||||
BORDER+w*TILESIZE, BORDER+y*TILESIZE, ink);
|
BORDER+LEGEND+w*TILESIZE, BORDER+LEGEND+y*TILESIZE, ink);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1617,8 +1662,8 @@ static void game_print(drawing *dr, game_state *state, int tilesize)
|
|||||||
char str[2];
|
char str[2];
|
||||||
str[1] = '\0';
|
str[1] = '\0';
|
||||||
str[0] = TOCHAR(state->grid[y*w+x]);
|
str[0] = TOCHAR(state->grid[y*w+x]);
|
||||||
draw_text(dr, BORDER + x*TILESIZE + TILESIZE/2,
|
draw_text(dr, BORDER+LEGEND + x*TILESIZE + TILESIZE/2,
|
||||||
BORDER + y*TILESIZE + TILESIZE/2,
|
BORDER+LEGEND + y*TILESIZE + TILESIZE/2,
|
||||||
FONT_VARIABLE, TILESIZE/2,
|
FONT_VARIABLE, TILESIZE/2,
|
||||||
ALIGN_VCENTRE | ALIGN_HCENTRE, ink, str);
|
ALIGN_VCENTRE | ALIGN_HCENTRE, ink, str);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user