There are a number of function call interfaces within Puzzles, and
this guide will discuss each one in a chapter of its own. After
-that, there will be a section about how to design new games, with
-some general design thoughts and tips.
+that, (\k{writing}) discusses how to design new games, with some
+general design thoughts and tips.
\C{backend} Interface to the back end
\b On platforms such as MacOS X and PalmOS, which build all the
puzzles into a single monolithic binary, the game structure in each
back end must have a different name, and there's a helper module
-\c{list.c} which contains a complete list of those game structures.
+\c{list.c} (constructed automatically by the same Perl script that
+builds the \cw{Makefile}s) which contains a complete list of those
+game structures.
On the latter type of platform, source files may assume that the
preprocessor symbol \c{COMBINED} has been defined. Thus, the usual
sufficient to give the grid dimensions and the location and contents
of the clue squares. (Indeed, one might very easily type in a puzzle
out of a newspaper without \e{knowing} what its difficulty level is
-in Solo's terminology.) Therefore. Solo's \cw{encode_params()} only
+in Solo's terminology.) Therefore, Solo's \cw{encode_params()} only
encodes the difficulty level if \c{full} is set.
\S{backend-decode-params} \cw{decode_params()}
cursor, for example, can be reset to a default position on reloading
the game without impacting the user experience. If the user should
somehow manage to save a game while a mouse drag was in progress,
-then discarding that mouse drag would be an outright \e{feature},
+then discarding that mouse drag would be an outright \e{feature}.
A typical thing that \e{would} be worth encoding in this function is
the Mines death counter: it's in the \c{game_ui} rather than the
The parameter \c{dr} is a drawing object (see \k{drawing}), which is
required if a blitter needs to be allocated.
+Back ends may assume (and may enforce by assertion) that this
+function will be called at most once for any \c{game_drawstate}. If
+a puzzle needs to be redrawn at a different size, the mid-end will
+create a fresh drawstate.
+
\S{backend-colours} \cw{colours()}
-\c float *(*colours)(frontend *fe, game_state *state, int *ncolours);
+\c float *(*colours)(frontend *fe, int *ncolours);
This function is responsible for telling the front end what colours
the puzzle will need to draw itself.
and blue components of each colour respectively as numbers in the
range [0,1].
-It is passed a sample \c{game_state} in case it needs one, although
-currently no puzzle does need this. (In fact, colours are not
-reallocated when the game parameters change or a new game is
-started, so you can't reliably use this \c{game_state} to allocate a
-different number of colours depending on the game. It is probably
-actually a mistake to rely on this parameter at all. I ought to
-either remove it or fix it; probably the former.)
-
-The final parameter passed to this function is a front end handle.
+The second parameter passed to this function is a front end handle.
The only things it is permitted to do with this handle are to call
the front-end function called \cw{frontend_default_colour()} (see
\k{frontend-default-colour}) or the utility function called
the mid-end will handle them internally and never consult this
function at all. State changes as a result of Solve operations are
also not animated by default, although you can change this for a
-particular game by setting a flag in \c{mouse_priorities}
-(\k{backend-mouse-priorities}).
+particular game by setting a flag in \c{flags} (\k{backend-flags}).
The function is also passed a pointer to the local \c{game_ui}. It
may refer to information in here to help with its decision (see
\S{backend-wants-statusbar} \cw{wants_statusbar()}
-\c int (*wants_statusbar)(void);
+\c int wants_statusbar;
-This function returns \cw{TRUE} if the puzzle has a use for a
+This boolean field is set to \cw{TRUE} if the puzzle has a use for a
textual status line (to display score, completion status, currently
active tiles, etc).
-(This should probably be a static boolean field rather than a
-function. I don't remember why I did it this way. I probably ought
-to change it.)
-
\S{backend-is-timed} \c{is_timed}
\c int is_timed;
freeze the timer thereafter so that the user can undo back through
their solution process without altering their time.
-\S{backend-mouse-priorities} \c{mouse_priorities}
+\S{backend-flags} \c{flags}
-\c int mouse_priorities;
+\c int flags;
-This field is badly named. It is in fact a generic flags word. It
-consists of the bitwise OR of the following flags:
+This field contains miscellaneous per-backend flags. It consists of
+the bitwise OR of some combination of the following:
\dt \cw{BUTTON_BEATS(x,y)}
-\dd Given any \cw{x} and \cw{y} from the set (\cw{LEFT_BUTTON},
-\cw{MIDDLE_BUTTON}, \cw{RIGHT_BUTTON}), this macro evaluates to a
+\dd Given any \cw{x} and \cw{y} from the set \{\cw{LEFT_BUTTON},
+\cw{MIDDLE_BUTTON}, \cw{RIGHT_BUTTON}\}, this macro evaluates to a
bit flag which indicates that when buttons \cw{x} and \cw{y} are
both pressed simultaneously, the mid-end should consider \cw{x} to
have priority. (In the absence of any such flags, the mid-end will
If a back end needs random numbers at some point during normal play,
it can create a fresh \c{random_state} by first calling
\c{get_random_seed} (\k{frontend-get-random-seed}) and then passing
-the returned seed data to \cw{random_init()}.
+the returned seed data to \cw{random_new()}.
This is likely not to be what you want. If a puzzle needs randomness
in the middle of play, it's likely to be more sensible to store some
-sort of random state within the \e{game_state}, so that the random
+sort of random state within the \c{game_state}, so that the random
numbers are tied to the particular game state and hence the player
can't simply keep undoing their move until they get numbers they
like better.
multiple implementations of the drawing API if necessary. For
example, the Windows API supplies a printing mechanism integrated
into the same GDI which deals with drawing in windows, and therefore
-it is likely (although as yet unimplemented in Puzzles) that the
-same API implementation can handle both drawing and printing; but on
-Unix, the most common way for applications to print is by producing
-PostScript output directly, and although it would be \e{possible} to
-write a single (say) \cw{draw_rect()} function which checked a
-global flag to decide whether to do GTK drawing operations or output
-PostScript to a file, it's much nicer to have two separate functions
-and switch between them as appropriate.
+the same API implementation can handle both drawing and printing;
+but on Unix, the most common way for applications to print is by
+producing PostScript output directly, and although it would be
+\e{possible} to write a single (say) \cw{draw_rect()} function which
+checked a global flag to decide whether to do GTK drawing operations
+or output PostScript to a file, it's much nicer to have two separate
+functions and switch between them as appropriate.
When drawing, the puzzle window is indexed by pixel coordinates,
with the top left pixel defined as \cw{(0,0)} and the bottom right
\e{Puzzles' redraw functions may assume that the surface they draw
on is persistent}. It is the responsibility of every front end to
preserve the puzzle's window contents in the face of GUI window
-expose issues and similar. It is not permissible to request the back
-end redraw any part of a window that it has already drawn, unless
-something has actually changed as a result of making moves in the
-puzzle.
+expose issues and similar. It is not permissible to request that the
+back end redraw any part of a window that it has already drawn,
+unless something has actually changed as a result of making moves in
+the puzzle.
Most front ends accomplish this by having the drawing routines draw
on a stored bitmap rather than directly on the window, and copying
within the back end redraw function, so this is as good a place as
any to document it.)
+The supplied text is filtered through the mid-end for optional
+rewriting before being passed on to the front end; the mid-end will
+prepend the current game time if the game is timed (and may in
+future perform other rewriting if it seems like a good idea).
+
This function is for drawing only; it must never be called during
printing.
a more useful type. Thus, a drawing \e{object} (\c{drawing *)}
suitable for passing to the back end redraw or printing functions
is constructed by passing a \c{drawing_api} and a \cq{void *} to the
-function \cw{drawing_init()} (see \k{drawing-init}).
+function \cw{drawing_new()} (see \k{drawing-new}).
\S{drawingapi-draw-text} \cw{draw_text()}
\c void (*draw_update)(void *handle, int x, int y, int w, int h);
-This function behaves exactly like the back end \cw{draw_text()}
+This function behaves exactly like the back end \cw{draw_update()}
function; see \k{drawing-draw-text}.
An implementation of this API which only supports printing is
This function behaves exactly like the back end \cw{status_bar()}
function; see \k{drawing-status-bar}.
-Front ends implementing this function should not use the provided
-text directly; they should call \cw{midend_rewrite_statusbar()}
-(\k{midend-rewrite-statusbar}) to process it first.
-
-In a game which has a timer, this function is likely to be called
-every time the timer goes off, i.e. many times a second. It is
-therefore likely to be common that this function is called with
-precisely the same text as the last time it was called. Front ends
-may well wish to detect this common case and avoid bothering to do
-anything. If they do, however, they \e{must} perform this check on
-the value \e{returned} from \cw{midend_rewrite_statusbar()}, rather
-than the value passed in to it (because the mid-end will frequently
-update the status-bar timer without the back end's intervention).
+Front ends implementing this function need not worry about it being
+called repeatedly with the same text; the middleware code in
+\cw{status_bar()} will take care of this.
Implementations of this API which do not provide drawing services
may define this function pointer to be \cw{NULL}; it will never be
Similarly, \c{ym} and \c{yc} specify the vertical position of the
puzzle as a function of the page height: the page height times
-\c{xm}, plus \c{xc} millimetres, equals the desired distance from
+\c{ym}, plus \c{yc} millimetres, equals the desired distance from
the top of the page to the top of the puzzle.
(This unwieldy mechanism is required because not all printing
which the front end needs to \e{call}, rather than helping to
implement. They are described in this section.
-\S{drawing-init} \cw{drawing_init()}
+\S{drawing-new} \cw{drawing_new()}
-\c drawing *drawing_init(const drawing_api *api, void *handle);
+\c drawing *drawing_new(const drawing_api *api, midend *me,
+\c void *handle);
This function creates a drawing object. It is passed a
\c{drawing_api}, which is a structure containing nothing but
function pointers; and also a \cq{void *} handle. The handle is
passed back to each function pointer when it is called.
+The \c{midend} parameter is used for rewriting the status bar
+contents: \cw{status_bar()} (see \k{drawing-status-bar}) has to call
+a function in the mid-end which might rewrite the status bar text.
+If the drawing object is to be used only for printing, or if the
+game is known not to call \cw{status_bar()}, this parameter may be
+\cw{NULL}.
+
\S{drawing-free} \cw{drawing_free()}
\c void drawing_free(drawing *dr);
function \cw{colours()} (\k{backend-colours}).
The parameters \c{drapi} and \c{drhandle} are passed to
-\cw{drawing_init()} (\k{drawing-init}) to construct a drawing object
+\cw{drawing_new()} (\k{drawing-new}) to construct a drawing object
which will be passed to the back end function \cw{redraw()}
(\k{backend-redraw}). Hence, all drawing-related function pointers
defined in \c{drapi} can expect to be called with \c{drhandle} as
(\k{midend-fetch-preset}). Thus, this function is usually called in
response to the user making a selection from the presets menu.
+\H{midend-get-params} \cw{midend_get_params()}
+
+\c game_params *midend_get_params(midend *me);
+
+Returns the current game parameters stored in this mid-end.
+
+The returned value is dynamically allocated, and should be freed
+when finished with by passing it to the game's own
+\cw{free_params()} function (see \k{backend-free-params}).
+
\H{midend-size} \cw{midend_size()}
\c void midend_size(midend *me, int *x, int *y, int expand);
\cw{activate_timer()} to be called from within a call to this
function.
-\H{midend-rewrite-statusbar} \cw{midend_rewrite_statusbar()}
-
-\c char *midend_rewrite_statusbar(midend *me, char *text);
-
-The front end should call this function from within
-\cw{status_bar()} (\k{drawing-status-bar}). It should be passed the
-string that was passed by the back end to \cw{status_bar()}; it will
-return a dynamically allocated string adjusted by the mid-end.
-(Specifically, adjusted to include the timer if the game is a timed
-one.) The returned value should be placed in the actual status bar
-in place of the input value.
-
-(This is a nasty piece of architecture; I apologise for it. It would
-seem a lot more pleasant to have the back end pass its status bar
-text to the mid-end, which in turn would rewrite it and pass it on
-to the front end, so that each front end needed to do nothing
-strange. The main reason why I haven't done this is because it means
-the back end redraw function would need to be passed a mid-end
-pointer \e{as well} as a front end pointer, which seemed like an
-excessive proliferation of opaque handles. The only way to avoid
-that proliferation would be to have all the drawing API functions
-also gatewayed through the mid-end, and that seemed like an
-excessive proliferation of wrapper functions. The current setup
-isn't nice, but it has minimal impact and I'm unconvinced that any
-of the other options are an improvement.)
-
\H{midend-serialise} \cw{midend_serialise()}
\c void midend_serialise(midend *me,
\c extern const int gamecount;
\c{gamelist} will be an array of \c{gamecount} game structures,
-declared in the source module \c{list.c}. The application should
-search that array for the game it wants, probably by reaching into
-each game structure and looking at its \c{name} field.
+declared in the automatically constructed source module \c{list.c}.
+The application should search that array for the game it wants,
+probably by reaching into each game structure and looking at its
+\c{name} field.
}
\c{random_state}. One of these is managed by each mid-end, for
example, and passed to the back end to generate a game with.
-\S{utils-random-init} \cw{random_init()}
+\S{utils-random-init} \cw{random_new()}
-\c random_state *random_init(char *seed, int len);
+\c random_state *random_new(char *seed, int len);
Allocates, initialises and returns a new \c{random_state}. The input
data is used as the seed for the random number stream (i.e. using
\S{utils-truefalse} \cw{TRUE} and \cw{FALSE}
The main Puzzles header file defines the macros \cw{TRUE} and
-\cw{FALSE}, which are used throughout the code in place of 0 and 1
-to indicate that the values are in a boolean context. For code base
-consistency, I'd prefer it if submissions of new code followed this
-convention as well.
+\cw{FALSE}, which are used throughout the code in place of 1 and 0
+(respectively) to indicate that the values are in a boolean context.
+For code base consistency, I'd prefer it if submissions of new code
+followed this convention as well.
\S{utils-maxmin} \cw{max()} and \cw{min()}
created automatically by the script \c{mkfiles.pl}, from the file
called \c{Recipe}. Edit \c{Recipe}, and then re-run \c{mkfiles.pl}.
+Also, don't forget to add your puzzle to \c{list.c}: if you don't,
+then it will still run fine on platforms which build each puzzle
+separately, but Mac OS X and other monolithic platforms will not
+include your new puzzle in their single binary.
+
Once your source file is building, you can move on to the fun bit.
\S{writing-generation} Puzzle generation
\c if (x == ui->cursor_x && y == ui->cursor_y)
\c value |= CURSOR;
\c if (ds->symbol_at_position[y][x] != value) {
-\c symbol_drawing_subroutine(fe, ds, x, y, value);
+\c symbol_drawing_subroutine(dr, ds, x, y, value);
\c ds->symbol_at_position[y][x] = value;
\c }
\c }
\b In the game's \cw{set_size()} function, once you know the size of
the object you'll be dragging around the display and hence the
-required size of the blitter, actually allocate the blitter (making
-sure to free a previous one if present \dash it's possible that
-\cw{set_size()} might be called twice on the same draw state).
+required size of the blitter, actually allocate the blitter.
\b In \cw{free_drawstate()}, free the blitter if it's not \cw{NULL}.