ref: cc545532268b04e05005bf65f53f0a1ba39335ba
parent: 46fa25240e2e1609c4431a639f6e9c4bb6f50b39
author: Simon Tatham <anakin@pobox.com>
date: Mon Jan 17 08:48:57 EST 2005
Rather than each game backend file exporting a whole load of functions and a couple of variables, now each one exports a single structure containing a load of function pointers and said variables. This should make it easy to support platforms on which it's sensible to compile all the puzzles into a single monolithic application. The two existing platforms are still one-binary-per-game. [originally from svn r5126]
--- a/cube.c
+++ b/cube.c
@@ -11,10 +11,6 @@
#include "puzzles.h"
-const char *const game_name = "Cube";
-const char *const game_winhelp_topic = "games.cube";
-const int game_can_configure = TRUE;
-
#define MAXVERTICES 20
#define MAXFACES 20
#define MAXORDER 4
@@ -215,7 +211,7 @@
int movecount;
};
-game_params *default_params(void)
+static game_params *default_params(void)
{
game_params *ret = snew(game_params);
@@ -226,7 +222,7 @@
return ret;
}
-int game_fetch_preset(int i, char **name, game_params **params)
+static int game_fetch_preset(int i, char **name, game_params **params)
{
game_params *ret = snew(game_params);
char *str;
@@ -266,12 +262,12 @@
return TRUE;
}
-void free_params(game_params *params)
+static void free_params(game_params *params)
{
sfree(params);
}
-game_params *dup_params(game_params *params)
+static game_params *dup_params(game_params *params)
{
game_params *ret = snew(game_params);
*ret = *params; /* structure copy */
@@ -278,7 +274,7 @@
return ret;
}
-game_params *decode_params(char const *string)
+static game_params *decode_params(char const *string)
{
game_params *ret = default_params();
@@ -299,7 +295,7 @@
return ret;
}
-char *encode_params(game_params *params)
+static char *encode_params(game_params *params)
{
char data[256];
@@ -477,7 +473,7 @@
return d1*d1 + d2*d2 + 4*d1*d2;
}
-config_item *game_configure(game_params *params)
+static config_item *game_configure(game_params *params)
{
config_item *ret = snewn(4, config_item);
char buf[80];
@@ -507,7 +503,7 @@
return ret;
}
-game_params *custom_params(config_item *cfg)
+static game_params *custom_params(config_item *cfg)
{
game_params *ret = snew(game_params);
@@ -533,7 +529,7 @@
classes[thisclass]++;
}
-char *validate_params(game_params *params)
+static char *validate_params(game_params *params)
{
int classes[5];
int i;
@@ -593,7 +589,7 @@
data->squareindex++;
}
-char *new_game_seed(game_params *params, random_state *rs)
+static char *new_game_seed(game_params *params, random_state *rs)
{
struct grid_data data;
int i, j, k, m, area, facesperclass;
@@ -842,7 +838,7 @@
return ret;
}
-char *validate_seed(game_params *params, char *seed)
+static char *validate_seed(game_params *params, char *seed)
{
int area = grid_area(params->d1, params->d2, solids[params->solid]->order);
int i, j;
@@ -870,7 +866,7 @@
return NULL;
}
-game_state *new_game(game_params *params, char *seed)
+static game_state *new_game(game_params *params, char *seed)
{
game_state *state = snew(game_state);
int area;
@@ -949,7 +945,7 @@
return state;
}
-game_state *dup_game(game_state *state)
+static game_state *dup_game(game_state *state)
{
game_state *ret = snew(game_state);
@@ -978,21 +974,22 @@
return ret;
}
-void free_game(game_state *state)
+static void free_game(game_state *state)
{
sfree(state);
}
-game_ui *new_ui(game_state *state)
+static game_ui *new_ui(game_state *state)
{
return NULL;
}
-void free_ui(game_ui *ui)
+static void free_ui(game_ui *ui)
{
}
-game_state *make_move(game_state *from, game_ui *ui, int x, int y, int button)
+static game_state *make_move(game_state *from, game_ui *ui,
+ int x, int y, int button)
{
int direction;
int pkey[2], skey[2], dkey[2];
@@ -1309,7 +1306,7 @@
return bb;
}
-void game_size(game_params *params, int *x, int *y)
+static void game_size(game_params *params, int *x, int *y)
{
struct bbox bb = find_bbox(params);
*x = (int)((bb.r - bb.l + 2*solids[params->solid]->border) * GRID_SCALE);
@@ -1316,7 +1313,7 @@
*y = (int)((bb.d - bb.u + 2*solids[params->solid]->border) * GRID_SCALE);
}
-float *game_colours(frontend *fe, game_state *state, int *ncolours)
+static float *game_colours(frontend *fe, game_state *state, int *ncolours)
{
float *ret = snewn(3 * NCOLOURS, float);
@@ -1334,7 +1331,7 @@
return ret;
}
-game_drawstate *game_new_drawstate(game_state *state)
+static game_drawstate *game_new_drawstate(game_state *state)
{
struct game_drawstate *ds = snew(struct game_drawstate);
struct bbox bb = find_bbox(&state->params);
@@ -1345,12 +1342,12 @@
return ds;
}
-void game_free_drawstate(game_drawstate *ds)
+static void game_free_drawstate(game_drawstate *ds)
{
sfree(ds);
}
-void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
+static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
game_state *state, int dir, game_ui *ui,
float animtime, float flashtime)
{
@@ -1512,17 +1509,52 @@
}
}
-float game_anim_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_anim_length(game_state *oldstate,
+ game_state *newstate, int dir)
{
return ROLLTIME;
}
-float game_flash_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_flash_length(game_state *oldstate,
+ game_state *newstate, int dir)
{
return 0.0F;
}
-int game_wants_statusbar(void)
+static int game_wants_statusbar(void)
{
return TRUE;
}
+
+#ifdef COMBINED
+#define thegame cube
+#endif
+
+const struct game thegame = {
+ "Cube", "games.cube", TRUE,
+ default_params,
+ game_fetch_preset,
+ decode_params,
+ encode_params,
+ free_params,
+ dup_params,
+ game_configure,
+ custom_params,
+ validate_params,
+ new_game_seed,
+ validate_seed,
+ new_game,
+ dup_game,
+ free_game,
+ new_ui,
+ free_ui,
+ make_move,
+ game_size,
+ game_colours,
+ game_new_drawstate,
+ game_free_drawstate,
+ game_redraw,
+ game_anim_length,
+ game_flash_length,
+ game_wants_statusbar,
+};
--- a/fifteen.c
+++ b/fifteen.c
@@ -11,10 +11,6 @@
#include "puzzles.h"
-const char *const game_name = "Fifteen";
-const char *const game_winhelp_topic = "games.fifteen";
-const int game_can_configure = TRUE;
-
#define TILE_SIZE 48
#define BORDER (TILE_SIZE / 2)
#define HIGHLIGHT_WIDTH (TILE_SIZE / 20)
@@ -48,7 +44,7 @@
int movecount;
};
-game_params *default_params(void)
+static game_params *default_params(void)
{
game_params *ret = snew(game_params);
@@ -57,17 +53,17 @@
return ret;
}
-int game_fetch_preset(int i, char **name, game_params **params)
+static int game_fetch_preset(int i, char **name, game_params **params)
{
return FALSE;
}
-void free_params(game_params *params)
+static void free_params(game_params *params)
{
sfree(params);
}
-game_params *dup_params(game_params *params)
+static game_params *dup_params(game_params *params)
{
game_params *ret = snew(game_params);
*ret = *params; /* structure copy */
@@ -74,7 +70,7 @@
return ret;
}
-game_params *decode_params(char const *string)
+static game_params *decode_params(char const *string)
{
game_params *ret = default_params();
@@ -88,7 +84,7 @@
return ret;
}
-char *encode_params(game_params *params)
+static char *encode_params(game_params *params)
{
char data[256];
@@ -97,7 +93,7 @@
return dupstr(data);
}
-config_item *game_configure(game_params *params)
+static config_item *game_configure(game_params *params)
{
config_item *ret;
char buf[80];
@@ -124,7 +120,7 @@
return ret;
}
-game_params *custom_params(config_item *cfg)
+static game_params *custom_params(config_item *cfg)
{
game_params *ret = snew(game_params);
@@ -134,7 +130,7 @@
return ret;
}
-char *validate_params(game_params *params)
+static char *validate_params(game_params *params)
{
if (params->w < 2 && params->h < 2)
return "Width and height must both be at least two";
@@ -142,7 +138,7 @@
return NULL;
}
-int perm_parity(int *perm, int n)
+static int perm_parity(int *perm, int n)
{
int i, j, ret;
@@ -156,7 +152,7 @@
return ret;
}
-char *new_game_seed(game_params *params, random_state *rs)
+static char *new_game_seed(game_params *params, random_state *rs)
{
int gap, n, i, x;
int x1, x2, p1, p2, parity;
@@ -271,7 +267,7 @@
return ret;
}
-char *validate_seed(game_params *params, char *seed)
+static char *validate_seed(game_params *params, char *seed)
{
char *p, *err;
int i, area;
@@ -322,7 +318,7 @@
return err;
}
-game_state *new_game(game_params *params, char *seed)
+static game_state *new_game(game_params *params, char *seed)
{
game_state *state = snew(game_state);
int i;
@@ -353,7 +349,7 @@
return state;
}
-game_state *dup_game(game_state *state)
+static game_state *dup_game(game_state *state)
{
game_state *ret = snew(game_state);
@@ -369,21 +365,22 @@
return ret;
}
-void free_game(game_state *state)
+static void free_game(game_state *state)
{
sfree(state);
}
-game_ui *new_ui(game_state *state)
+static game_ui *new_ui(game_state *state)
{
return NULL;
}
-void free_ui(game_ui *ui)
+static void free_ui(game_ui *ui)
{
}
-game_state *make_move(game_state *from, game_ui *ui, int x, int y, int button)
+static game_state *make_move(game_state *from, game_ui *ui,
+ int x, int y, int button)
{
int gx, gy, dx, dy, ux, uy, up, p;
game_state *ret;
@@ -457,13 +454,13 @@
int *tiles;
};
-void game_size(game_params *params, int *x, int *y)
+static void game_size(game_params *params, int *x, int *y)
{
*x = TILE_SIZE * params->w + 2 * BORDER;
*y = TILE_SIZE * params->h + 2 * BORDER;
}
-float *game_colours(frontend *fe, game_state *state, int *ncolours)
+static float *game_colours(frontend *fe, game_state *state, int *ncolours)
{
float *ret = snewn(3 * NCOLOURS, float);
int i;
@@ -494,7 +491,7 @@
return ret;
}
-game_drawstate *game_new_drawstate(game_state *state)
+static game_drawstate *game_new_drawstate(game_state *state)
{
struct game_drawstate *ds = snew(struct game_drawstate);
int i;
@@ -510,7 +507,7 @@
return ds;
}
-void game_free_drawstate(game_drawstate *ds)
+static void game_free_drawstate(game_drawstate *ds)
{
sfree(ds->tiles);
sfree(ds);
@@ -552,7 +549,7 @@
draw_update(fe, x, y, TILE_SIZE, TILE_SIZE);
}
-void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
+static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
game_state *state, int dir, game_ui *ui,
float animtime, float flashtime)
{
@@ -702,12 +699,14 @@
}
}
-float game_anim_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_anim_length(game_state *oldstate,
+ game_state *newstate, int dir)
{
return ANIM_TIME;
}
-float game_flash_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_flash_length(game_state *oldstate,
+ game_state *newstate, int dir)
{
if (!oldstate->completed && newstate->completed)
return 2 * FLASH_FRAME;
@@ -715,7 +714,40 @@
return 0.0F;
}
-int game_wants_statusbar(void)
+static int game_wants_statusbar(void)
{
return TRUE;
}
+
+#ifdef COMBINED
+#define thegame fifteen
+#endif
+
+const struct game thegame = {
+ "Fifteen", "games.fifteen", TRUE,
+ default_params,
+ game_fetch_preset,
+ decode_params,
+ encode_params,
+ free_params,
+ dup_params,
+ game_configure,
+ custom_params,
+ validate_params,
+ new_game_seed,
+ validate_seed,
+ new_game,
+ dup_game,
+ free_game,
+ new_ui,
+ free_ui,
+ make_move,
+ game_size,
+ game_colours,
+ game_new_drawstate,
+ game_free_drawstate,
+ game_redraw,
+ game_anim_length,
+ game_flash_length,
+ game_wants_statusbar,
+};
--- a/gtk.c
+++ b/gtk.c
@@ -783,7 +783,7 @@
fe = snew(frontend);
- fe->me = midend_new(fe);
+ fe->me = midend_new(fe, &thegame);
if (game_id) {
*error = midend_game_id(fe->me, game_id, FALSE);
if (*error) {
@@ -795,7 +795,7 @@
midend_new_game(fe->me);
fe->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(fe->window), game_name);
+ gtk_window_set_title(GTK_WINDOW(fe->window), thegame.name);
#if 0
gtk_window_set_resizable(GTK_WINDOW(fe->window), FALSE);
#else
@@ -827,7 +827,7 @@
GTK_SIGNAL_FUNC(menu_config_event), fe);
gtk_widget_show(menuitem);
- if ((n = midend_num_presets(fe->me)) > 0 || game_can_configure) {
+ if ((n = midend_num_presets(fe->me)) > 0 || thegame.can_configure) {
GtkWidget *submenu;
int i;
@@ -852,7 +852,7 @@
gtk_widget_show(menuitem);
}
- if (game_can_configure) {
+ if (thegame.can_configure) {
menuitem = gtk_menu_item_new_with_label("Custom...");
gtk_object_set_data(GTK_OBJECT(menuitem), "user-data",
GPOINTER_TO_INT(CFG_SETTINGS));
--- a/midend.c
+++ b/midend.c
@@ -14,6 +14,7 @@
struct midend_data {
frontend *frontend;
random_state *random;
+ const game *ourgame;
char *seed;
int fresh_seed;
@@ -40,7 +41,7 @@
} \
} while (0)
-midend_data *midend_new(frontend *fe)
+midend_data *midend_new(frontend *fe, const game *ourgame)
{
midend_data *me = snew(midend_data);
void *randseed;
@@ -49,10 +50,11 @@
get_random_seed(&randseed, &randseedsize);
me->frontend = fe;
+ me->ourgame = ourgame;
me->random = random_init(randseed, randseedsize);
me->nstates = me->statesize = me->statepos = 0;
me->states = NULL;
- me->params = default_params();
+ me->params = ourgame->default_params();
me->seed = NULL;
me->fresh_seed = FALSE;
me->drawstate = NULL;
@@ -74,53 +76,53 @@
{
sfree(me->states);
sfree(me->seed);
- free_params(me->params);
+ me->ourgame->free_params(me->params);
sfree(me);
}
void midend_size(midend_data *me, int *x, int *y)
{
- game_size(me->params, x, y);
+ me->ourgame->size(me->params, x, y);
}
void midend_set_params(midend_data *me, game_params *params)
{
- free_params(me->params);
- me->params = dup_params(params);
+ me->ourgame->free_params(me->params);
+ me->params = me->ourgame->dup_params(params);
}
void midend_new_game(midend_data *me)
{
while (me->nstates > 0)
- free_game(me->states[--me->nstates]);
+ me->ourgame->free_game(me->states[--me->nstates]);
if (me->drawstate)
- game_free_drawstate(me->drawstate);
+ me->ourgame->free_drawstate(me->drawstate);
assert(me->nstates == 0);
if (!me->fresh_seed) {
sfree(me->seed);
- me->seed = new_game_seed(me->params, me->random);
+ me->seed = me->ourgame->new_seed(me->params, me->random);
} else
me->fresh_seed = FALSE;
ensure(me);
- me->states[me->nstates++] = new_game(me->params, me->seed);
+ me->states[me->nstates++] = me->ourgame->new_game(me->params, me->seed);
me->statepos = 1;
- me->drawstate = game_new_drawstate(me->states[0]);
+ me->drawstate = me->ourgame->new_drawstate(me->states[0]);
if (me->ui)
- free_ui(me->ui);
- me->ui = new_ui(me->states[0]);
+ me->ourgame->free_ui(me->ui);
+ me->ui = me->ourgame->new_ui(me->states[0]);
}
void midend_restart_game(midend_data *me)
{
while (me->nstates > 1)
- free_game(me->states[--me->nstates]);
+ me->ourgame->free_game(me->states[--me->nstates]);
me->statepos = me->nstates;
- free_ui(me->ui);
- me->ui = new_ui(me->states[0]);
+ me->ourgame->free_ui(me->ui);
+ me->ui = me->ourgame->new_ui(me->states[0]);
}
static int midend_undo(midend_data *me)
@@ -148,10 +150,10 @@
float flashtime;
if (me->oldstate || me->statepos > 1) {
- flashtime = game_flash_length(me->oldstate ? me->oldstate :
- me->states[me->statepos-2],
- me->states[me->statepos-1],
- me->oldstate ? me->dir : +1);
+ flashtime = me->ourgame->flash_length(me->oldstate ? me->oldstate :
+ me->states[me->statepos-2],
+ me->states[me->statepos-1],
+ me->oldstate ? me->dir : +1);
if (flashtime > 0) {
me->flash_pos = 0.0F;
me->flash_time = flashtime;
@@ -159,7 +161,7 @@
}
if (me->oldstate)
- free_game(me->oldstate);
+ me->ourgame->free_game(me->oldstate);
me->oldstate = NULL;
me->anim_pos = me->anim_time = 0;
me->dir = 0;
@@ -180,7 +182,7 @@
int midend_process_key(midend_data *me, int x, int y, int button)
{
- game_state *oldstate = dup_game(me->states[me->statepos - 1]);
+ game_state *oldstate = me->ourgame->dup_game(me->states[me->statepos - 1]);
float anim_time;
if (button == 'n' || button == 'N' || button == '\x0E') {
@@ -203,11 +205,11 @@
if (!midend_redo(me))
return 1;
} else if (button == 'q' || button == 'Q' || button == '\x11') {
- free_game(oldstate);
+ me->ourgame->free_game(oldstate);
return 0;
} else {
- game_state *s = make_move(me->states[me->statepos-1], me->ui,
- x, y, button);
+ game_state *s = me->ourgame->make_move(me->states[me->statepos-1],
+ me->ui, x, y, button);
if (s == me->states[me->statepos-1]) {
/*
@@ -220,13 +222,13 @@
} else if (s) {
midend_stop_anim(me);
while (me->nstates > me->statepos)
- free_game(me->states[--me->nstates]);
+ me->ourgame->free_game(me->states[--me->nstates]);
ensure(me);
me->states[me->nstates] = s;
me->statepos = ++me->nstates;
me->dir = +1;
} else {
- free_game(oldstate);
+ me->ourgame->free_game(oldstate);
return 1;
}
}
@@ -234,7 +236,8 @@
/*
* See if this move requires an animation.
*/
- anim_time = game_anim_length(oldstate, me->states[me->statepos-1], me->dir);
+ anim_time = me->ourgame->anim_length(oldstate, me->states[me->statepos-1],
+ me->dir);
me->oldstate = oldstate;
if (anim_time > 0) {
@@ -259,13 +262,13 @@
if (me->oldstate && me->anim_time > 0 &&
me->anim_pos < me->anim_time) {
assert(me->dir != 0);
- game_redraw(me->frontend, me->drawstate, me->oldstate,
- me->states[me->statepos-1], me->dir,
- me->ui, me->anim_pos, me->flash_pos);
+ me->ourgame->redraw(me->frontend, me->drawstate, me->oldstate,
+ me->states[me->statepos-1], me->dir,
+ me->ui, me->anim_pos, me->flash_pos);
} else {
- game_redraw(me->frontend, me->drawstate, NULL,
- me->states[me->statepos-1], +1 /*shrug*/,
- me->ui, 0.0, me->flash_pos);
+ me->ourgame->redraw(me->frontend, me->drawstate, NULL,
+ me->states[me->statepos-1], +1 /*shrug*/,
+ me->ui, 0.0, me->flash_pos);
}
end_draw(me->frontend);
}
@@ -294,16 +297,16 @@
float *ret;
if (me->nstates == 0) {
- char *seed = new_game_seed(me->params, me->random);
- state = new_game(me->params, seed);
+ char *seed = me->ourgame->new_seed(me->params, me->random);
+ state = me->ourgame->new_game(me->params, seed);
sfree(seed);
} else
state = me->states[0];
- ret = game_colours(me->frontend, state, ncolours);
+ ret = me->ourgame->colours(me->frontend, state, ncolours);
if (me->nstates == 0)
- free_game(state);
+ me->ourgame->free_game(state);
return ret;
}
@@ -314,7 +317,7 @@
char *name;
game_params *preset;
- while (game_fetch_preset(me->npresets, &name, &preset)) {
+ while (me->ourgame->fetch_preset(me->npresets, &name, &preset)) {
if (me->presetsize <= me->npresets) {
me->presetsize = me->npresets + 10;
me->presets = sresize(me->presets, me->presetsize,
@@ -342,7 +345,7 @@
int midend_wants_statusbar(midend_data *me)
{
- return game_wants_statusbar();
+ return me->ourgame->wants_statusbar();
}
config_item *midend_get_config(midend_data *me, int which, char **wintitle)
@@ -350,15 +353,15 @@
char *titlebuf, *parstr;
config_item *ret;
- titlebuf = snewn(40 + strlen(game_name), char);
+ titlebuf = snewn(40 + strlen(me->ourgame->name), char);
switch (which) {
case CFG_SETTINGS:
- sprintf(titlebuf, "%s configuration", game_name);
+ sprintf(titlebuf, "%s configuration", me->ourgame->name);
*wintitle = dupstr(titlebuf);
- return game_configure(me->params);
+ return me->ourgame->configure(me->params);
case CFG_SEED:
- sprintf(titlebuf, "%s game selection", game_name);
+ sprintf(titlebuf, "%s game selection", me->ourgame->name);
*wintitle = dupstr(titlebuf);
ret = snewn(2, config_item);
@@ -371,7 +374,7 @@
* parameters, plus a colon, plus the game seed. This is a
* full game ID.
*/
- parstr = encode_params(me->params);
+ parstr = me->ourgame->encode_params(me->params);
ret[0].sval = snewn(strlen(parstr) + strlen(me->seed) + 2, char);
sprintf(ret[0].sval, "%s:%s", parstr, me->seed);
sfree(parstr);
@@ -417,18 +420,18 @@
}
if (par) {
- params = decode_params(par);
- error = validate_params(params);
+ params = me->ourgame->decode_params(par);
+ error = me->ourgame->validate_params(params);
if (error) {
- free_params(params);
+ me->ourgame->free_params(params);
return error;
}
- free_params(me->params);
+ me->ourgame->free_params(me->params);
me->params = params;
}
if (seed) {
- error = validate_seed(me->params, seed);
+ error = me->ourgame->validate_seed(me->params, seed);
if (error)
return error;
@@ -447,15 +450,15 @@
switch (which) {
case CFG_SETTINGS:
- params = custom_params(cfg);
- error = validate_params(params);
+ params = me->ourgame->custom_params(cfg);
+ error = me->ourgame->validate_params(params);
if (error) {
- free_params(params);
+ me->ourgame->free_params(params);
return error;
}
- free_params(me->params);
+ me->ourgame->free_params(me->params);
me->params = params;
break;
--- a/net.c
+++ b/net.c
@@ -12,10 +12,6 @@
#include "puzzles.h"
#include "tree234.h"
-const char *const game_name = "Net";
-const char *const game_winhelp_topic = "games.net";
-const int game_can_configure = TRUE;
-
#define PI 3.141592653589793238462643383279502884197169399
#define MATMUL(xr,yr,m,x,y) do { \
@@ -127,7 +123,7 @@
/* ----------------------------------------------------------------------
* Manage game parameters.
*/
-game_params *default_params(void)
+static game_params *default_params(void)
{
game_params *ret = snew(game_params);
@@ -139,7 +135,7 @@
return ret;
}
-int game_fetch_preset(int i, char **name, game_params **params)
+static int game_fetch_preset(int i, char **name, game_params **params)
{
game_params *ret;
char str[80];
@@ -173,12 +169,12 @@
return TRUE;
}
-void free_params(game_params *params)
+static void free_params(game_params *params)
{
sfree(params);
}
-game_params *dup_params(game_params *params)
+static game_params *dup_params(game_params *params)
{
game_params *ret = snew(game_params);
*ret = *params; /* structure copy */
@@ -185,7 +181,7 @@
return ret;
}
-game_params *decode_params(char const *string)
+static game_params *decode_params(char const *string)
{
game_params *ret = default_params();
char const *p = string;
@@ -207,7 +203,7 @@
return ret;
}
-char *encode_params(game_params *params)
+static char *encode_params(game_params *params)
{
char ret[400];
int len;
@@ -223,7 +219,7 @@
return dupstr(ret);
}
-config_item *game_configure(game_params *params)
+static config_item *game_configure(game_params *params)
{
config_item *ret;
char buf[80];
@@ -261,7 +257,7 @@
return ret;
}
-game_params *custom_params(config_item *cfg)
+static game_params *custom_params(config_item *cfg)
{
game_params *ret = snew(game_params);
@@ -273,7 +269,7 @@
return ret;
}
-char *validate_params(game_params *params)
+static char *validate_params(game_params *params)
{
if (params->width <= 0 && params->height <= 0)
return "Width and height must both be greater than zero";
@@ -294,7 +290,7 @@
* Randomly select a new game seed.
*/
-char *new_game_seed(game_params *params, random_state *rs)
+static char *new_game_seed(game_params *params, random_state *rs)
{
/*
* The full description of a Net game is far too large to
@@ -312,7 +308,7 @@
return dupstr(buf);
}
-char *validate_seed(game_params *params, char *seed)
+static char *validate_seed(game_params *params, char *seed)
{
/*
* Since any string at all will suffice to seed the RNG, there
@@ -325,7 +321,7 @@
* Construct an initial game state, given a seed and parameters.
*/
-game_state *new_game(game_params *params, char *seed)
+static game_state *new_game(game_params *params, char *seed)
{
random_state *rs;
game_state *state;
@@ -676,7 +672,7 @@
return state;
}
-game_state *dup_game(game_state *state)
+static game_state *dup_game(game_state *state)
{
game_state *ret;
@@ -696,7 +692,7 @@
return ret;
}
-void free_game(game_state *state)
+static void free_game(game_state *state)
{
sfree(state->tiles);
sfree(state->barriers);
@@ -770,7 +766,7 @@
random_state *rs; /* used for jumbling */
};
-game_ui *new_ui(game_state *state)
+static game_ui *new_ui(game_state *state)
{
void *seed;
int seedsize;
@@ -785,7 +781,7 @@
return ui;
}
-void free_ui(game_ui *ui)
+static void free_ui(game_ui *ui)
{
random_free(ui->rs);
sfree(ui);
@@ -794,7 +790,8 @@
/* ----------------------------------------------------------------------
* Process a move.
*/
-game_state *make_move(game_state *state, game_ui *ui, int x, int y, int button)
+static game_state *make_move(game_state *state, game_ui *ui,
+ int x, int y, int button)
{
game_state *ret, *nullret;
int tx, ty, orig;
@@ -951,7 +948,7 @@
unsigned char *visible;
};
-game_drawstate *game_new_drawstate(game_state *state)
+static game_drawstate *game_new_drawstate(game_state *state)
{
game_drawstate *ds = snew(game_drawstate);
@@ -964,19 +961,19 @@
return ds;
}
-void game_free_drawstate(game_drawstate *ds)
+static void game_free_drawstate(game_drawstate *ds)
{
sfree(ds->visible);
sfree(ds);
}
-void game_size(game_params *params, int *x, int *y)
+static void game_size(game_params *params, int *x, int *y)
{
*x = WINDOW_OFFSET * 2 + TILE_SIZE * params->width + TILE_BORDER;
*y = WINDOW_OFFSET * 2 + TILE_SIZE * params->height + TILE_BORDER;
}
-float *game_colours(frontend *fe, game_state *state, int *ncolours)
+static float *game_colours(frontend *fe, game_state *state, int *ncolours)
{
float *ret;
@@ -1284,7 +1281,7 @@
draw_update(fe, bx, by, TILE_SIZE+TILE_BORDER, TILE_SIZE+TILE_BORDER);
}
-void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
+static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
game_state *state, int dir, game_ui *ui, float t, float ft)
{
int x, y, tx, ty, frame, last_rotate_dir;
@@ -1436,7 +1433,8 @@
sfree(active);
}
-float game_anim_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_anim_length(game_state *oldstate,
+ game_state *newstate, int dir)
{
int x, y, last_rotate_dir;
@@ -1462,7 +1460,8 @@
return 0.0F;
}
-float game_flash_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_flash_length(game_state *oldstate,
+ game_state *newstate, int dir)
{
/*
* If the game has just been completed, we display a completion
@@ -1485,7 +1484,40 @@
return 0.0F;
}
-int game_wants_statusbar(void)
+static int game_wants_statusbar(void)
{
return TRUE;
}
+
+#ifdef COMBINED
+#define thegame net
+#endif
+
+const struct game thegame = {
+ "Net", "games.net", TRUE,
+ default_params,
+ game_fetch_preset,
+ decode_params,
+ encode_params,
+ free_params,
+ dup_params,
+ game_configure,
+ custom_params,
+ validate_params,
+ new_game_seed,
+ validate_seed,
+ new_game,
+ dup_game,
+ free_game,
+ new_ui,
+ free_ui,
+ make_move,
+ game_size,
+ game_colours,
+ game_new_drawstate,
+ game_free_drawstate,
+ game_redraw,
+ game_anim_length,
+ game_flash_length,
+ game_wants_statusbar,
+};
--- a/netslide.c
+++ b/netslide.c
@@ -13,10 +13,6 @@
#include "puzzles.h"
#include "tree234.h"
-const char *const game_name = "Netslide";
-const char *const game_winhelp_topic = "games.netslide";
-const int game_can_configure = TRUE;
-
#define PI 3.141592653589793238462643383279502884197169399
#define MATMUL(xr,yr,m,x,y) do { \
@@ -139,13 +135,13 @@
return xyd;
}
-void slide_col(game_state *state, int dir, int col);
-void slide_row(game_state *state, int dir, int row);
+static void slide_col(game_state *state, int dir, int col);
+static void slide_row(game_state *state, int dir, int row);
/* ----------------------------------------------------------------------
* Manage game parameters.
*/
-game_params *default_params(void)
+static game_params *default_params(void)
{
game_params *ret = snew(game_params);
@@ -157,7 +153,7 @@
return ret;
}
-int game_fetch_preset(int i, char **name, game_params **params)
+static int game_fetch_preset(int i, char **name, game_params **params)
{
game_params *ret;
char str[80];
@@ -190,12 +186,12 @@
return TRUE;
}
-void free_params(game_params *params)
+static void free_params(game_params *params)
{
sfree(params);
}
-game_params *dup_params(game_params *params)
+static game_params *dup_params(game_params *params)
{
game_params *ret = snew(game_params);
*ret = *params; /* structure copy */
@@ -202,7 +198,7 @@
return ret;
}
-game_params *decode_params(char const *string)
+static game_params *decode_params(char const *string)
{
game_params *ret = default_params();
char const *p = string;
@@ -227,7 +223,7 @@
return ret;
}
-char *encode_params(game_params *params)
+static char *encode_params(game_params *params)
{
char ret[400];
int len;
@@ -243,7 +239,7 @@
return dupstr(ret);
}
-config_item *game_configure(game_params *params)
+static config_item *game_configure(game_params *params)
{
config_item *ret;
char buf[80];
@@ -281,7 +277,7 @@
return ret;
}
-game_params *custom_params(config_item *cfg)
+static game_params *custom_params(config_item *cfg)
{
game_params *ret = snew(game_params);
@@ -293,7 +289,7 @@
return ret;
}
-char *validate_params(game_params *params)
+static char *validate_params(game_params *params)
{
if (params->width <= 1 && params->height <= 1)
return "Width and height must both be greater than one";
@@ -312,7 +308,7 @@
* Randomly select a new game seed.
*/
-char *new_game_seed(game_params *params, random_state *rs)
+static char *new_game_seed(game_params *params, random_state *rs)
{
/*
* The full description of a Net game is far too large to
@@ -330,7 +326,7 @@
return dupstr(buf);
}
-char *validate_seed(game_params *params, char *seed)
+static char *validate_seed(game_params *params, char *seed)
{
/*
* Since any string at all will suffice to seed the RNG, there
@@ -343,7 +339,7 @@
* Construct an initial game state, given a seed and parameters.
*/
-game_state *new_game(game_params *params, char *seed)
+static game_state *new_game(game_params *params, char *seed)
{
random_state *rs;
game_state *state;
@@ -714,7 +710,7 @@
return state;
}
-game_state *dup_game(game_state *state)
+static game_state *dup_game(game_state *state)
{
game_state *ret;
@@ -737,7 +733,7 @@
return ret;
}
-void free_game(game_state *state)
+static void free_game(game_state *state)
{
sfree(state->tiles);
sfree(state->barriers);
@@ -815,7 +811,7 @@
int cur_visible;
};
-game_ui *new_ui(game_state *state)
+static game_ui *new_ui(game_state *state)
{
game_ui *ui = snew(game_ui);
ui->cur_x = state->width / 2;
@@ -825,7 +821,7 @@
return ui;
}
-void free_ui(game_ui *ui)
+static void free_ui(game_ui *ui)
{
sfree(ui);
}
@@ -834,7 +830,7 @@
* Process a move.
*/
-void slide_row(game_state *state, int dir, int row)
+static void slide_row(game_state *state, int dir, int row)
{
int x = dir > 0 ? -1 : state->width;
int tx = x + dir;
@@ -848,7 +844,7 @@
state->tiles[T(state, tx, row)] = endtile;
}
-void slide_col(game_state *state, int dir, int col)
+static void slide_col(game_state *state, int dir, int col)
{
int y = dir > 0 ? -1 : state->height;
int ty = y + dir;
@@ -862,7 +858,8 @@
state->tiles[T(state, col, ty)] = endtile;
}
-game_state *make_move(game_state *state, game_ui *ui, int x, int y, int button)
+static game_state *make_move(game_state *state, game_ui *ui,
+ int x, int y, int button)
{
int cx, cy;
int n, dx, dy;
@@ -945,7 +942,7 @@
unsigned char *visible;
};
-game_drawstate *game_new_drawstate(game_state *state)
+static game_drawstate *game_new_drawstate(game_state *state)
{
game_drawstate *ds = snew(game_drawstate);
@@ -958,19 +955,19 @@
return ds;
}
-void game_free_drawstate(game_drawstate *ds)
+static void game_free_drawstate(game_drawstate *ds)
{
sfree(ds->visible);
sfree(ds);
}
-void game_size(game_params *params, int *x, int *y)
+static void game_size(game_params *params, int *x, int *y)
{
*x = BORDER * 2 + WINDOW_OFFSET * 2 + TILE_SIZE * params->width + TILE_BORDER;
*y = BORDER * 2 + WINDOW_OFFSET * 2 + TILE_SIZE * params->height + TILE_BORDER;
}
-float *game_colours(frontend *fe, game_state *state, int *ncolours)
+static float *game_colours(frontend *fe, game_state *state, int *ncolours)
{
float *ret;
@@ -1286,7 +1283,7 @@
draw_polygon(fe, coords, 7, FALSE, COL_TEXT);
}
-void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
+static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
game_state *state, int dir, game_ui *ui, float t, float ft)
{
int x, y, tx, ty, frame;
@@ -1481,12 +1478,14 @@
sfree(active);
}
-float game_anim_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_anim_length(game_state *oldstate,
+ game_state *newstate, int dir)
{
return ANIM_TIME;
}
-float game_flash_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_flash_length(game_state *oldstate,
+ game_state *newstate, int dir)
{
/*
* If the game has just been completed, we display a completion
@@ -1509,7 +1508,40 @@
return 0.0F;
}
-int game_wants_statusbar(void)
+static int game_wants_statusbar(void)
{
return TRUE;
}
+
+#ifdef COMBINED
+#define thegame netslide
+#endif
+
+const struct game thegame = {
+ "Netslide", "games.netslide", TRUE,
+ default_params,
+ game_fetch_preset,
+ decode_params,
+ encode_params,
+ free_params,
+ dup_params,
+ game_configure,
+ custom_params,
+ validate_params,
+ new_game_seed,
+ validate_seed,
+ new_game,
+ dup_game,
+ free_game,
+ new_ui,
+ free_ui,
+ make_move,
+ game_size,
+ game_colours,
+ game_new_drawstate,
+ game_free_drawstate,
+ game_redraw,
+ game_anim_length,
+ game_flash_length,
+ game_wants_statusbar,
+};
--- a/nullgame.c
+++ b/nullgame.c
@@ -20,10 +20,6 @@
#include "puzzles.h"
-const char *const game_name = "Null Game";
-const char *const game_winhelp_topic = NULL;
-const int game_can_configure = FALSE;
-
enum {
COL_BACKGROUND,
NCOLOURS
@@ -37,7 +33,7 @@
int FIXME;
};
-game_params *default_params(void)
+static game_params *default_params(void)
{
game_params *ret = snew(game_params);
@@ -46,17 +42,17 @@
return ret;
}
-int game_fetch_preset(int i, char **name, game_params **params)
+static int game_fetch_preset(int i, char **name, game_params **params)
{
return FALSE;
}
-void free_params(game_params *params)
+static void free_params(game_params *params)
{
sfree(params);
}
-game_params *dup_params(game_params *params)
+static game_params *dup_params(game_params *params)
{
game_params *ret = snew(game_params);
*ret = *params; /* structure copy */
@@ -63,7 +59,7 @@
return ret;
}
-game_params *decode_params(char const *string)
+static game_params *decode_params(char const *string)
{
game_params *ret = snew(game_params);
@@ -72,37 +68,37 @@
return ret;
}
-char *encode_params(game_params *params)
+static char *encode_params(game_params *params)
{
return dupstr("FIXME");
}
-config_item *game_configure(game_params *params)
+static config_item *game_configure(game_params *params)
{
return NULL;
}
-game_params *custom_params(config_item *cfg)
+static game_params *custom_params(config_item *cfg)
{
return NULL;
}
-char *validate_params(game_params *params)
+static char *validate_params(game_params *params)
{
return NULL;
}
-char *new_game_seed(game_params *params, random_state *rs)
+static char *new_game_seed(game_params *params, random_state *rs)
{
return dupstr("FIXME");
}
-char *validate_seed(game_params *params, char *seed)
+static char *validate_seed(game_params *params, char *seed)
{
return NULL;
}
-game_state *new_game(game_params *params, char *seed)
+static game_state *new_game(game_params *params, char *seed)
{
game_state *state = snew(game_state);
@@ -111,7 +107,7 @@
return state;
}
-game_state *dup_game(game_state *state)
+static game_state *dup_game(game_state *state)
{
game_state *ret = snew(game_state);
@@ -120,21 +116,22 @@
return ret;
}
-void free_game(game_state *state)
+static void free_game(game_state *state)
{
sfree(state);
}
-game_ui *new_ui(game_state *state)
+static game_ui *new_ui(game_state *state)
{
return NULL;
}
-void free_ui(game_ui *ui)
+static void free_ui(game_ui *ui)
{
}
-game_state *make_move(game_state *from, game_ui *ui, int x, int y, int button)
+static game_state *make_move(game_state *from, game_ui *ui, int x, int y,
+ int button)
{
return NULL;
}
@@ -147,12 +144,12 @@
int FIXME;
};
-void game_size(game_params *params, int *x, int *y)
+static void game_size(game_params *params, int *x, int *y)
{
*x = *y = 200; /* FIXME */
}
-float *game_colours(frontend *fe, game_state *state, int *ncolours)
+static float *game_colours(frontend *fe, game_state *state, int *ncolours)
{
float *ret = snewn(3 * NCOLOURS, float);
@@ -162,7 +159,7 @@
return ret;
}
-game_drawstate *game_new_drawstate(game_state *state)
+static game_drawstate *game_new_drawstate(game_state *state)
{
struct game_drawstate *ds = snew(struct game_drawstate);
@@ -171,14 +168,14 @@
return ds;
}
-void game_free_drawstate(game_drawstate *ds)
+static void game_free_drawstate(game_drawstate *ds)
{
sfree(ds);
}
-void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
- game_state *state, int dir, game_ui *ui,
- float animtime, float flashtime)
+static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
+ game_state *state, int dir, game_ui *ui,
+ float animtime, float flashtime)
{
/*
* The initial contents of the window are not guaranteed and
@@ -189,17 +186,52 @@
draw_rect(fe, 0, 0, 200, 200, COL_BACKGROUND);
}
-float game_anim_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_anim_length(game_state *oldstate, game_state *newstate,
+ int dir)
{
return 0.0F;
}
-float game_flash_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_flash_length(game_state *oldstate, game_state *newstate,
+ int dir)
{
return 0.0F;
}
-int game_wants_statusbar(void)
+static int game_wants_statusbar(void)
{
return FALSE;
}
+
+#ifdef COMBINED
+#define thegame nullgame
+#endif
+
+const struct game thegame = {
+ "Null Game", NULL, FALSE,
+ default_params,
+ game_fetch_preset,
+ decode_params,
+ encode_params,
+ free_params,
+ dup_params,
+ game_configure,
+ custom_params,
+ validate_params,
+ new_game_seed,
+ validate_seed,
+ new_game,
+ dup_game,
+ free_game,
+ new_ui,
+ free_ui,
+ make_move,
+ game_size,
+ game_colours,
+ game_new_drawstate,
+ game_free_drawstate,
+ game_redraw,
+ game_anim_length,
+ game_flash_length,
+ game_wants_statusbar,
+};
--- a/pattern.c
+++ b/pattern.c
@@ -18,10 +18,6 @@
#define max(x,y) ( (x)>(y) ? (x):(y) )
#define min(x,y) ( (x)<(y) ? (x):(y) )
-const char *const game_name = "Pattern";
-const char *const game_winhelp_topic = "games.pattern";
-const int game_can_configure = TRUE;
-
enum {
COL_BACKGROUND,
COL_EMPTY,
@@ -61,7 +57,7 @@
#define FLASH_TIME 0.13F
-game_params *default_params(void)
+static game_params *default_params(void)
{
game_params *ret = snew(game_params);
@@ -70,7 +66,7 @@
return ret;
}
-int game_fetch_preset(int i, char **name, game_params **params)
+static int game_fetch_preset(int i, char **name, game_params **params)
{
game_params *ret;
char str[80];
@@ -96,12 +92,12 @@
return TRUE;
}
-void free_params(game_params *params)
+static void free_params(game_params *params)
{
sfree(params);
}
-game_params *dup_params(game_params *params)
+static game_params *dup_params(game_params *params)
{
game_params *ret = snew(game_params);
*ret = *params; /* structure copy */
@@ -108,7 +104,7 @@
return ret;
}
-game_params *decode_params(char const *string)
+static game_params *decode_params(char const *string)
{
game_params *ret = default_params();
char const *p = string;
@@ -126,7 +122,7 @@
return ret;
}
-char *encode_params(game_params *params)
+static char *encode_params(game_params *params)
{
char ret[400];
int len;
@@ -138,7 +134,7 @@
return dupstr(ret);
}
-config_item *game_configure(game_params *params)
+static config_item *game_configure(game_params *params)
{
config_item *ret;
char buf[80];
@@ -165,7 +161,7 @@
return ret;
}
-game_params *custom_params(config_item *cfg)
+static game_params *custom_params(config_item *cfg)
{
game_params *ret = snew(game_params);
@@ -175,7 +171,7 @@
return ret;
}
-char *validate_params(game_params *params)
+static char *validate_params(game_params *params)
{
if (params->w <= 0 && params->h <= 0)
return "Width and height must both be greater than zero";
@@ -315,7 +311,7 @@
sfree(fgrid);
}
-int compute_rowdata(int *ret, unsigned char *start, int len, int step)
+static int compute_rowdata(int *ret, unsigned char *start, int len, int step)
{
int i, n;
@@ -443,7 +439,7 @@
return grid;
}
-char *new_game_seed(game_params *params, random_state *rs)
+static char *new_game_seed(game_params *params, random_state *rs)
{
unsigned char *grid;
int i, j, max, rowlen, *rowdata;
@@ -507,7 +503,7 @@
return seed;
}
-char *validate_seed(game_params *params, char *seed)
+static char *validate_seed(game_params *params, char *seed)
{
int i, n, rowspace;
char *p;
@@ -549,7 +545,7 @@
return NULL;
}
-game_state *new_game(game_params *params, char *seed)
+static game_state *new_game(game_params *params, char *seed)
{
int i;
char *p;
@@ -584,7 +580,7 @@
return state;
}
-game_state *dup_game(game_state *state)
+static game_state *dup_game(game_state *state)
{
game_state *ret = snew(game_state);
@@ -607,7 +603,7 @@
return ret;
}
-void free_game(game_state *state)
+static void free_game(game_state *state)
{
sfree(state->rowdata);
sfree(state->rowlen);
@@ -624,7 +620,7 @@
int drag, release, state;
};
-game_ui *new_ui(game_state *state)
+static game_ui *new_ui(game_state *state)
{
game_ui *ret;
@@ -634,12 +630,13 @@
return ret;
}
-void free_ui(game_ui *ui)
+static void free_ui(game_ui *ui)
{
sfree(ui);
}
-game_state *make_move(game_state *from, game_ui *ui, int x, int y, int button)
+static game_state *make_move(game_state *from, game_ui *ui,
+ int x, int y, int button)
{
game_state *ret;
@@ -775,13 +772,13 @@
unsigned char *visible;
};
-void game_size(game_params *params, int *x, int *y)
+static void game_size(game_params *params, int *x, int *y)
{
*x = SIZE(params->w);
*y = SIZE(params->h);
}
-float *game_colours(frontend *fe, game_state *state, int *ncolours)
+static float *game_colours(frontend *fe, game_state *state, int *ncolours)
{
float *ret = snewn(3 * NCOLOURS, float);
@@ -807,7 +804,7 @@
return ret;
}
-game_drawstate *game_new_drawstate(game_state *state)
+static game_drawstate *game_new_drawstate(game_state *state)
{
struct game_drawstate *ds = snew(struct game_drawstate);
@@ -820,7 +817,7 @@
return ds;
}
-void game_free_drawstate(game_drawstate *ds)
+static void game_free_drawstate(game_drawstate *ds)
{
sfree(ds->visible);
sfree(ds);
@@ -848,7 +845,7 @@
TILE_SIZE, TILE_SIZE);
}
-void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
+static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
game_state *state, int dir, game_ui *ui,
float animtime, float flashtime)
{
@@ -957,12 +954,14 @@
}
}
-float game_anim_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_anim_length(game_state *oldstate,
+ game_state *newstate, int dir)
{
return 0.0F;
}
-float game_flash_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_flash_length(game_state *oldstate,
+ game_state *newstate, int dir)
{
if (!oldstate->completed && newstate->completed)
return FLASH_TIME;
@@ -969,7 +968,40 @@
return 0.0F;
}
-int game_wants_statusbar(void)
+static int game_wants_statusbar(void)
{
return FALSE;
}
+
+#ifdef COMBINED
+#define thegame pattern
+#endif
+
+const struct game thegame = {
+ "Pattern", "games.pattern", TRUE,
+ default_params,
+ game_fetch_preset,
+ decode_params,
+ encode_params,
+ free_params,
+ dup_params,
+ game_configure,
+ custom_params,
+ validate_params,
+ new_game_seed,
+ validate_seed,
+ new_game,
+ dup_game,
+ free_game,
+ new_ui,
+ free_ui,
+ make_move,
+ game_size,
+ game_colours,
+ game_new_drawstate,
+ game_free_drawstate,
+ game_redraw,
+ game_anim_length,
+ game_flash_length,
+ game_wants_statusbar,
+};
--- a/puzzles.h
+++ b/puzzles.h
@@ -44,6 +44,7 @@
typedef struct game_state game_state;
typedef struct game_ui game_ui;
typedef struct game_drawstate game_drawstate;
+typedef struct game game;
#define ALIGN_VNORMAL 0x000
#define ALIGN_VCENTRE 0x100
@@ -111,7 +112,7 @@
/*
* midend.c
*/
-midend_data *midend_new(frontend *fe);
+midend_data *midend_new(frontend *fe, const game *ourgame);
void midend_free(midend_data *me);
void midend_set_params(midend_data *me, game_params *params);
void midend_size(midend_data *me, int *x, int *y);
@@ -158,37 +159,52 @@
void random_free(random_state *state);
/*
- * Game-specific routines
+ * Data structure containing the function calls and data specific
+ * to a particular game. This is enclosed in a data structure so
+ * that a particular platform can choose, if it wishes, to compile
+ * all the games into a single combined executable rather than
+ * having lots of little ones.
*/
-extern const char *const game_name;
-extern const char *const game_winhelp_topic;
-const int game_can_configure;
-game_params *default_params(void);
-int game_fetch_preset(int i, char **name, game_params **params);
-game_params *decode_params(char const *string);
-char *encode_params(game_params *);
-void free_params(game_params *params);
-game_params *dup_params(game_params *params);
-config_item *game_configure(game_params *params);
-game_params *custom_params(config_item *cfg);
-char *validate_params(game_params *params);
-char *new_game_seed(game_params *params, random_state *rs);
-char *validate_seed(game_params *params, char *seed);
-game_state *new_game(game_params *params, char *seed);
-game_state *dup_game(game_state *state);
-void free_game(game_state *state);
-game_ui *new_ui(game_state *state);
-void free_ui(game_ui *ui);
-game_state *make_move(game_state *from, game_ui *ui, int x, int y, int button);
-void game_size(game_params *params, int *x, int *y);
-float *game_colours(frontend *fe, game_state *state, int *ncolours);
-game_drawstate *game_new_drawstate(game_state *state);
-void game_free_drawstate(game_drawstate *ds);
-void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
- game_state *newstate, int dir, game_ui *ui, float anim_time,
- float flash_time);
-float game_anim_length(game_state *oldstate, game_state *newstate, int dir);
-float game_flash_length(game_state *oldstate, game_state *newstate, int dir);
-int game_wants_statusbar(void);
+struct game {
+ const char *name;
+ const char *winhelp_topic;
+ int can_configure;
+ game_params *(*default_params)(void);
+ int (*fetch_preset)(int i, char **name, game_params **params);
+ game_params *(*decode_params)(char const *string);
+ char *(*encode_params)(game_params *);
+ void (*free_params)(game_params *params);
+ game_params *(*dup_params)(game_params *params);
+ config_item *(*configure)(game_params *params);
+ game_params *(*custom_params)(config_item *cfg);
+ char *(*validate_params)(game_params *params);
+ char *(*new_seed)(game_params *params, random_state *rs);
+ char *(*validate_seed)(game_params *params, char *seed);
+ game_state *(*new_game)(game_params *params, char *seed);
+ game_state *(*dup_game)(game_state *state);
+ void (*free_game)(game_state *state);
+ game_ui *(*new_ui)(game_state *state);
+ void (*free_ui)(game_ui *ui);
+ game_state *(*make_move)(game_state *from, game_ui *ui, int x, int y,
+ int button);
+ void (*size)(game_params *params, int *x, int *y);
+ float *(*colours)(frontend *fe, game_state *state, int *ncolours);
+ game_drawstate *(*new_drawstate)(game_state *state);
+ void (*free_drawstate)(game_drawstate *ds);
+ void (*redraw)(frontend *fe, game_drawstate *ds, game_state *oldstate,
+ game_state *newstate, int dir, game_ui *ui, float anim_time,
+ float flash_time);
+ float (*anim_length)(game_state *oldstate, game_state *newstate, int dir);
+ float (*flash_length)(game_state *oldstate, game_state *newstate, int dir);
+ int (*wants_statusbar)(void);
+};
+
+/*
+ * For one-game-at-a-time platforms, there's a single structure
+ * like the above, under a fixed name.
+ */
+#ifndef COMBINED
+extern const game thegame;
+#endif
#endif /* PUZZLES_PUZZLES_H */
--- a/rect.c
+++ b/rect.c
@@ -39,10 +39,6 @@
#include "puzzles.h"
-const char *const game_name = "Rectangles";
-const char *const game_winhelp_topic = "games.rectangles";
-const int game_can_configure = TRUE;
-
enum {
COL_BACKGROUND,
COL_CORRECT,
@@ -89,7 +85,7 @@
int completed;
};
-game_params *default_params(void)
+static game_params *default_params(void)
{
game_params *ret = snew(game_params);
@@ -99,7 +95,7 @@
return ret;
}
-int game_fetch_preset(int i, char **name, game_params **params)
+static int game_fetch_preset(int i, char **name, game_params **params)
{
game_params *ret;
int w, h;
@@ -122,12 +118,12 @@
return TRUE;
}
-void free_params(game_params *params)
+static void free_params(game_params *params)
{
sfree(params);
}
-game_params *dup_params(game_params *params)
+static game_params *dup_params(game_params *params)
{
game_params *ret = snew(game_params);
*ret = *params; /* structure copy */
@@ -134,7 +130,7 @@
return ret;
}
-game_params *decode_params(char const *string)
+static game_params *decode_params(char const *string)
{
game_params *ret = default_params();
@@ -154,7 +150,7 @@
return ret;
}
-char *encode_params(game_params *params)
+static char *encode_params(game_params *params)
{
char data[256];
@@ -163,7 +159,7 @@
return dupstr(data);
}
-config_item *game_configure(game_params *params)
+static config_item *game_configure(game_params *params)
{
config_item *ret;
char buf[80];
@@ -196,7 +192,7 @@
return ret;
}
-game_params *custom_params(config_item *cfg)
+static game_params *custom_params(config_item *cfg)
{
game_params *ret = snew(game_params);
@@ -207,7 +203,7 @@
return ret;
}
-char *validate_params(game_params *params)
+static char *validate_params(game_params *params)
{
if (params->w <= 0 && params->h <= 0)
return "Width and height must both be greater than zero";
@@ -390,7 +386,7 @@
}
#endif
-char *new_game_seed(game_params *params, random_state *rs)
+static char *new_game_seed(game_params *params, random_state *rs)
{
int *grid, *numbers;
struct rectlist *list;
@@ -902,7 +898,7 @@
return seed;
}
-char *validate_seed(game_params *params, char *seed)
+static char *validate_seed(game_params *params, char *seed)
{
int area = params->w * params->h;
int squares = 0;
@@ -930,7 +926,7 @@
return NULL;
}
-game_state *new_game(game_params *params, char *seed)
+static game_state *new_game(game_params *params, char *seed)
{
game_state *state = snew(game_state);
int x, y, i, area;
@@ -973,7 +969,7 @@
return state;
}
-game_state *dup_game(game_state *state)
+static game_state *dup_game(game_state *state)
{
game_state *ret = snew(game_state);
@@ -993,7 +989,7 @@
return ret;
}
-void free_game(game_state *state)
+static void free_game(game_state *state)
{
sfree(state->grid);
sfree(state->vedge);
@@ -1118,7 +1114,7 @@
int dragged;
};
-game_ui *new_ui(game_state *state)
+static game_ui *new_ui(game_state *state)
{
game_ui *ui = snew(game_ui);
ui->drag_start_x = -1;
@@ -1129,12 +1125,12 @@
return ui;
}
-void free_ui(game_ui *ui)
+static void free_ui(game_ui *ui)
{
sfree(ui);
}
-void coord_round(float x, float y, int *xr, int *yr)
+static void coord_round(float x, float y, int *xr, int *yr)
{
float xs, ys, xv, yv, dx, dy, dist;
@@ -1265,7 +1261,8 @@
}
}
-game_state *make_move(game_state *from, game_ui *ui, int x, int y, int button)
+static game_state *make_move(game_state *from, game_ui *ui,
+ int x, int y, int button)
{
int xc, yc;
int startdrag = FALSE, enddrag = FALSE, active = FALSE;
@@ -1374,13 +1371,13 @@
unsigned int *visible;
};
-void game_size(game_params *params, int *x, int *y)
+static void game_size(game_params *params, int *x, int *y)
{
*x = params->w * TILE_SIZE + 2*BORDER + 1;
*y = params->h * TILE_SIZE + 2*BORDER + 1;
}
-float *game_colours(frontend *fe, game_state *state, int *ncolours)
+static float *game_colours(frontend *fe, game_state *state, int *ncolours)
{
float *ret = snewn(3 * NCOLOURS, float);
@@ -1410,7 +1407,7 @@
return ret;
}
-game_drawstate *game_new_drawstate(game_state *state)
+static game_drawstate *game_new_drawstate(game_state *state)
{
struct game_drawstate *ds = snew(struct game_drawstate);
int i;
@@ -1425,13 +1422,13 @@
return ds;
}
-void game_free_drawstate(game_drawstate *ds)
+static void game_free_drawstate(game_drawstate *ds)
{
sfree(ds->visible);
sfree(ds);
}
-void draw_tile(frontend *fe, game_state *state, int x, int y,
+static void draw_tile(frontend *fe, game_state *state, int x, int y,
unsigned char *hedge, unsigned char *vedge,
unsigned char *corners, int correct)
{
@@ -1487,7 +1484,7 @@
draw_update(fe, cx, cy, TILE_SIZE+1, TILE_SIZE+1);
}
-void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
+static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
game_state *state, int dir, game_ui *ui,
float animtime, float flashtime)
{
@@ -1579,12 +1576,14 @@
sfree(correct);
}
-float game_anim_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_anim_length(game_state *oldstate,
+ game_state *newstate, int dir)
{
return 0.0F;
}
-float game_flash_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_flash_length(game_state *oldstate,
+ game_state *newstate, int dir)
{
if (!oldstate->completed && newstate->completed)
return FLASH_TIME;
@@ -1591,7 +1590,40 @@
return 0.0F;
}
-int game_wants_statusbar(void)
+static int game_wants_statusbar(void)
{
return FALSE;
}
+
+#ifdef COMBINED
+#define thegame rect
+#endif
+
+const struct game thegame = {
+ "Rectangles", "games.rectangles", TRUE,
+ default_params,
+ game_fetch_preset,
+ decode_params,
+ encode_params,
+ free_params,
+ dup_params,
+ game_configure,
+ custom_params,
+ validate_params,
+ new_game_seed,
+ validate_seed,
+ new_game,
+ dup_game,
+ free_game,
+ new_ui,
+ free_ui,
+ make_move,
+ game_size,
+ game_colours,
+ game_new_drawstate,
+ game_free_drawstate,
+ game_redraw,
+ game_anim_length,
+ game_flash_length,
+ game_wants_statusbar,
+};
--- a/sixteen.c
+++ b/sixteen.c
@@ -13,10 +13,6 @@
#include "puzzles.h"
-const char *const game_name = "Sixteen";
-const char *const game_winhelp_topic = "games.sixteen";
-const int game_can_configure = TRUE;
-
#define TILE_SIZE 48
#define BORDER TILE_SIZE /* big border to fill with arrows */
#define HIGHLIGHT_WIDTH (TILE_SIZE / 20)
@@ -50,7 +46,7 @@
int last_movement_sense;
};
-game_params *default_params(void)
+static game_params *default_params(void)
{
game_params *ret = snew(game_params);
@@ -59,7 +55,7 @@
return ret;
}
-int game_fetch_preset(int i, char **name, game_params **params)
+static int game_fetch_preset(int i, char **name, game_params **params)
{
game_params *ret;
int w, h;
@@ -82,12 +78,12 @@
return TRUE;
}
-void free_params(game_params *params)
+static void free_params(game_params *params)
{
sfree(params);
}
-game_params *dup_params(game_params *params)
+static game_params *dup_params(game_params *params)
{
game_params *ret = snew(game_params);
*ret = *params; /* structure copy */
@@ -94,7 +90,7 @@
return ret;
}
-game_params *decode_params(char const *string)
+static game_params *decode_params(char const *string)
{
game_params *ret = default_params();
@@ -108,7 +104,7 @@
return ret;
}
-char *encode_params(game_params *params)
+static char *encode_params(game_params *params)
{
char data[256];
@@ -117,7 +113,7 @@
return dupstr(data);
}
-config_item *game_configure(game_params *params)
+static config_item *game_configure(game_params *params)
{
config_item *ret;
char buf[80];
@@ -144,7 +140,7 @@
return ret;
}
-game_params *custom_params(config_item *cfg)
+static game_params *custom_params(config_item *cfg)
{
game_params *ret = snew(game_params);
@@ -154,7 +150,7 @@
return ret;
}
-char *validate_params(game_params *params)
+static char *validate_params(game_params *params)
{
if (params->w < 2 && params->h < 2)
return "Width and height must both be at least two";
@@ -162,7 +158,7 @@
return NULL;
}
-int perm_parity(int *perm, int n)
+static int perm_parity(int *perm, int n)
{
int i, j, ret;
@@ -176,7 +172,7 @@
return ret;
}
-char *new_game_seed(game_params *params, random_state *rs)
+static char *new_game_seed(game_params *params, random_state *rs)
{
int stop, n, i, x;
int x1, x2, p1, p2;
@@ -283,7 +279,7 @@
}
-char *validate_seed(game_params *params, char *seed)
+static char *validate_seed(game_params *params, char *seed)
{
char *p, *err;
int i, area;
@@ -334,7 +330,7 @@
return err;
}
-game_state *new_game(game_params *params, char *seed)
+static game_state *new_game(game_params *params, char *seed)
{
game_state *state = snew(game_state);
int i;
@@ -362,7 +358,7 @@
return state;
}
-game_state *dup_game(game_state *state)
+static game_state *dup_game(game_state *state)
{
game_state *ret = snew(game_state);
@@ -378,21 +374,22 @@
return ret;
}
-void free_game(game_state *state)
+static void free_game(game_state *state)
{
sfree(state);
}
-game_ui *new_ui(game_state *state)
+static game_ui *new_ui(game_state *state)
{
return NULL;
}
-void free_ui(game_ui *ui)
+static void free_ui(game_ui *ui)
{
}
-game_state *make_move(game_state *from, game_ui *ui, int x, int y, int button)
+static game_state *make_move(game_state *from, game_ui *ui,
+ int x, int y, int button)
{
int cx, cy;
int dx, dy, tx, ty, n;
@@ -458,13 +455,13 @@
int *tiles;
};
-void game_size(game_params *params, int *x, int *y)
+static void game_size(game_params *params, int *x, int *y)
{
*x = TILE_SIZE * params->w + 2 * BORDER;
*y = TILE_SIZE * params->h + 2 * BORDER;
}
-float *game_colours(frontend *fe, game_state *state, int *ncolours)
+static float *game_colours(frontend *fe, game_state *state, int *ncolours)
{
float *ret = snewn(3 * NCOLOURS, float);
int i;
@@ -495,7 +492,7 @@
return ret;
}
-game_drawstate *game_new_drawstate(game_state *state)
+static game_drawstate *game_new_drawstate(game_state *state)
{
struct game_drawstate *ds = snew(struct game_drawstate);
int i;
@@ -511,7 +508,7 @@
return ds;
}
-void game_free_drawstate(game_drawstate *ds)
+static void game_free_drawstate(game_drawstate *ds)
{
sfree(ds->tiles);
sfree(ds);
@@ -574,7 +571,7 @@
draw_polygon(fe, coords, 7, FALSE, COL_TEXT);
}
-void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
+static void game_redraw(frontend *fe, game_drawstate *ds, game_state *oldstate,
game_state *state, int dir, game_ui *ui,
float animtime, float flashtime)
{
@@ -752,12 +749,14 @@
}
}
-float game_anim_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_anim_length(game_state *oldstate,
+ game_state *newstate, int dir)
{
return ANIM_TIME;
}
-float game_flash_length(game_state *oldstate, game_state *newstate, int dir)
+static float game_flash_length(game_state *oldstate,
+ game_state *newstate, int dir)
{
if (!oldstate->completed && newstate->completed)
return 2 * FLASH_FRAME;
@@ -765,7 +764,36 @@
return 0.0F;
}
-int game_wants_statusbar(void)
+static int game_wants_statusbar(void)
{
return TRUE;
}
+
+const struct game thegame = {
+ "Sixteen", "games.sixteen", TRUE,
+ default_params,
+ game_fetch_preset,
+ decode_params,
+ encode_params,
+ free_params,
+ dup_params,
+ game_configure,
+ custom_params,
+ validate_params,
+ new_game_seed,
+ validate_seed,
+ new_game,
+ dup_game,
+ free_game,
+ new_ui,
+ free_ui,
+ make_move,
+ game_size,
+ game_colours,
+ game_new_drawstate,
+ game_free_drawstate,
+ game_redraw,
+ game_anim_length,
+ game_flash_length,
+ game_wants_statusbar,
+};
--- a/windows.c
+++ b/windows.c
@@ -1,5 +1,14 @@
/*
* windows.c: Windows front end for my puzzle collection.
+ *
+ * TODO:
+ *
+ * - Figure out what to do if a puzzle requests a size bigger than
+ * the screen will take. In principle we could put scrollbars in
+ * the window, although that would be pretty horrid. Another
+ * option is to detect in advance that this will be a problem -
+ * we can probably tell this using midend_size() before actually
+ * generating the puzzle - and simply refuse to do it.
*/
#include <windows.h>
@@ -363,7 +372,7 @@
fe = snew(frontend);
- fe->me = midend_new(fe);
+ fe->me = midend_new(fe, &thegame);
if (game_id) {
*error = midend_game_id(fe->me, game_id, FALSE);
@@ -412,7 +421,7 @@
(WS_THICKFRAME | WS_MAXIMIZEBOX | WS_OVERLAPPED),
TRUE, 0);
- fe->hwnd = CreateWindowEx(0, game_name, game_name,
+ fe->hwnd = CreateWindowEx(0, thegame.name, thegame.name,
WS_OVERLAPPEDWINDOW &~
(WS_THICKFRAME | WS_MAXIMIZEBOX),
CW_USEDEFAULT, CW_USEDEFAULT,
@@ -429,7 +438,7 @@
AppendMenu(menu, MF_ENABLED, IDM_SEED, "Specific...");
if ((fe->npresets = midend_num_presets(fe->me)) > 0 ||
- game_can_configure) {
+ thegame.can_configure) {
HMENU sub = CreateMenu();
int i;
@@ -450,7 +459,7 @@
AppendMenu(sub, MF_ENABLED, IDM_PRESETS + 0x10 * i, name);
}
- if (game_can_configure) {
+ if (thegame.can_configure) {
AppendMenu(sub, MF_ENABLED, IDM_CONFIG, "Custom...");
}
}
@@ -464,11 +473,11 @@
HMENU hmenu = CreateMenu();
AppendMenu(bar, MF_ENABLED|MF_POPUP, (UINT)hmenu, "Help");
AppendMenu(hmenu, MF_ENABLED, IDM_HELPC, "Contents");
- if (game_winhelp_topic) {
+ if (thegame.winhelp_topic) {
char *item;
- assert(game_name);
- item = snewn(9+strlen(game_name), char); /*ick*/
- sprintf(item, "Help on %s", game_name);
+ assert(thegame.name);
+ item = snewn(9+strlen(thegame.name), char); /*ick*/
+ sprintf(item, "Help on %s", thegame.name);
AppendMenu(hmenu, MF_ENABLED, IDM_GAMEHELP, item);
sfree(item);
}
@@ -911,10 +920,10 @@
break;
case IDM_GAMEHELP:
assert(fe->help_path);
- assert(game_winhelp_topic);
+ assert(thegame.winhelp_topic);
{
- char *cmd = snewn(10+strlen(game_winhelp_topic), char); /*ick*/
- sprintf(cmd, "JI(`',`%s')", game_winhelp_topic);
+ char *cmd = snewn(10+strlen(thegame.winhelp_topic), char);
+ sprintf(cmd, "JI(`',`%s')", thegame.winhelp_topic);
WinHelp(hwnd, fe->help_path, HELP_COMMAND, (DWORD)cmd);
sfree(cmd);
}
@@ -1107,7 +1116,7 @@
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = NULL;
- wndclass.lpszClassName = game_name;
+ wndclass.lpszClassName = thegame.name;
RegisterClass(&wndclass);
}
@@ -1117,7 +1126,7 @@
if (!new_window(inst, *cmdline ? cmdline : NULL, &error)) {
char buf[128];
- sprintf(buf, "%.100s Error", game_name);
+ sprintf(buf, "%.100s Error", thegame.name);
MessageBox(NULL, error, buf, MB_OK|MB_ICONERROR);
return 1;
}