summaryrefslogtreecommitdiff
path: root/apps/plugins/puzzles/src/HACKING
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/puzzles/src/HACKING')
-rw-r--r--apps/plugins/puzzles/src/HACKING4661
1 files changed, 0 insertions, 4661 deletions
diff --git a/apps/plugins/puzzles/src/HACKING b/apps/plugins/puzzles/src/HACKING
deleted file mode 100644
index e877280e1c..0000000000
--- a/apps/plugins/puzzles/src/HACKING
+++ /dev/null
@@ -1,4661 +0,0 @@
1#Developer documentation for Simon Tatham's puzzle collection
2
3This is a guide to the internal structure of Simon Tatham's Portable
4Puzzle Collection (henceforth referred to simply as `Puzzles'), for
5use by anyone attempting to implement a new puzzle or port to a new
6platform.
7
8This guide is believed correct as of r6190. Hopefully it will be updated
9along with the code in future, but if not, I've at least left this
10version number in here so you can figure out what's changed by tracking
11commit comments from there onwards.
12
13#1. Introduction
14
15The Puzzles code base is divided into four parts: a set of
16interchangeable front ends, a set of interchangeable back ends, a
17universal `middle end' which acts as a buffer between the two, and a
18bunch of miscellaneous utility functions. In the following sections I
19give some general discussion of each of these parts.
20
21#1.1. Front end
22
23The front end is the non-portable part of the code: it's the bit that
24you replace completely when you port to a different platform. So it's
25responsible for all system calls, all GUI interaction, and anything else
26platform-specific.
27
28The current front ends in the main code base are for Windows, GTK and
29MacOS X; I also know of a third-party front end for PalmOS.
30
31The front end contains main() or the local platform's equivalent. Top-
32level control over the application's execution flow belongs to the front
33end (it isn't, for example, a set of functions called by a universal
34main() somewhere else).
35
36The front end has complete freedom to design the GUI for any given
37port of Puzzles. There is no centralised mechanism for maintaining the
38menu layout, for example. This has a cost in consistency (when I _do_
39want the same menu layout on more than one platform, I have to edit
40two pieces of code in parallel every time I make a change), but the
41advantage is that local GUI conventions can be conformed to and local
42constraints adapted to. For example, MacOS X has strict human interface
43guidelines which specify a different menu layout from the one I've used
44on Windows and GTK; there's nothing stopping the OS X front end from
45providing a menu layout consistent with those guidelines.
46
47Although the front end is mostly caller rather than the callee in its
48interactions with other parts of the code, it is required to implement
49a small API for other modules to call, mostly of drawing functions for
50games to use when drawing their graphics. The drawing API is documented
51in chapter 3; the other miscellaneous front end API functions are
52documented in section 4.34.
53
54#1.2. Back end
55
56A `back end', in this collection, is synonymous with a `puzzle'. Each
57back end implements a different game.
58
59At the top level, a back end is simply a data structure, containing a
60few constants (flag words, preferred pixel size) and a large number of
61function pointers. Back ends are almost invariably callee rather than
62caller, which means there's a limitation on what a back end can do on
63its own initiative.
64
65The persistent state in a back end is divided into a number of data
66structures, which are used for different purposes and therefore likely
67to be switched around, changed without notice, and otherwise updated by
68the rest of the code. It is important when designing a back end to put
69the right pieces of data into the right structures, or standard midend-
70provided features (such as Undo) may fail to work.
71
72The functions and variables provided in the back end data structure are
73documented in chapter 2.
74
75#1.3. Middle end
76
77Puzzles has a single and universal `middle end'. This code is common to
78all platforms and all games; it sits in between the front end and the
79back end and provides standard functionality everywhere.
80
81People adding new back ends or new front ends should generally not need
82to edit the middle end. On rare occasions there might be a change that
83can be made to the middle end to permit a new game to do something not
84currently anticipated by the middle end's present design; however, this
85is terribly easy to get wrong and should probably not be undertaken
86without consulting the primary maintainer (me). Patch submissions
87containing unannounced mid-end changes will be treated on their merits
88like any other patch; this is just a friendly warning that mid-end
89changes will need quite a lot of merits to make them acceptable.
90
91Functionality provided by the mid-end includes:
92
93 - Maintaining a list of game state structures and moving back and
94 forth along that list to provide Undo and Redo.
95
96 - Handling timers (for move animations, flashes on completion, and in
97 some cases actually timing the game).
98
99 - Handling the container format of game IDs: receiving them, picking
100 them apart into parameters, description and/or random seed, and
101 so on. The game back end need only handle the individual parts
102 of a game ID (encoded parameters and encoded game description);
103 everything else is handled centrally by the mid-end.
104
105 - Handling standard keystrokes and menu commands, such as `New Game',
106 `Restart Game' and `Quit'.
107
108 - Pre-processing mouse events so that the game back ends can rely on
109 them arriving in a sensible order (no missing button-release events,
110 no sudden changes of which button is currently pressed, etc).
111
112 - Handling the dialog boxes which ask the user for a game ID.
113
114 - Handling serialisation of entire games (for loading and saving a
115 half-finished game to a disk file, or for handling application
116 shutdown and restart on platforms such as PalmOS where state is
117 expected to be saved).
118
119Thus, there's a lot of work done once by the mid-end so that individual
120back ends don't have to worry about it. All the back end has to do is
121cooperate in ensuring the mid-end can do its work properly.
122
123The API of functions provided by the mid-end to be called by the front
124end is documented in chapter 4.
125
126#1.4. Miscellaneous utilities
127
128In addition to these three major structural components, the Puzzles code
129also contains a variety of utility modules usable by all of the above
130components. There is a set of functions to provide platform-independent
131random number generation; functions to make memory allocation easier;
132functions which implement a balanced tree structure to be used as
133necessary in complex algorithms; and a few other miscellaneous
134functions. All of these are documented in chapter 5.
135
136#1.5. Structure of this guide
137
138There are a number of function call interfaces within Puzzles, and this
139guide will discuss each one in a chapter of its own. After that, chapter
1406 discusses how to design new games, with some general design thoughts
141and tips.
142
143#2. Interface to the back end
144
145This chapter gives a detailed discussion of the interface that each back
146end must implement.
147
148At the top level, each back end source file exports a single global
149symbol, which is a `const struct game' containing a large number of
150function pointers and a small amount of constant data. This structure is
151called by different names depending on what kind of platform the puzzle
152set is being compiled on:
153
154 - On platforms such as Windows and GTK, which build a separate binary
155 for each puzzle, the game structure in every back end has the same
156 name, `thegame'; the front end refers directly to this name, so that
157 compiling the same front end module against a different back end
158 module builds a different puzzle.
159
160 - On platforms such as MacOS X and PalmOS, which build all the puzzles
161 into a single monolithic binary, the game structure in each back end
162 must have a different name, and there's a helper module `list.c'
163 (constructed automatically by the same Perl script that builds the
164 Makefiles) which contains a complete list of those game structures.
165
166On the latter type of platform, source files may assume that the
167preprocessor symbol `COMBINED' has been defined. Thus, the usual code to
168declare the game structure looks something like this:
169
170 #ifdef COMBINED
171 #define thegame net /* or whatever this game is called */
172 #endif
173
174 const struct game thegame = {
175 /* lots of structure initialisation in here */
176 };
177
178Game back ends must also internally define a number of data structures,
179for storing their various persistent state. This chapter will first
180discuss the nature and use of those structures, and then go on to give
181details of every element of the game structure.
182
183#2.1. Data structures
184
185Each game is required to define four separate data structures. This
186section discusses each one and suggests what sorts of things need to be
187put in it.
188
189#2.1.1. `game_params'
190
191The `game_params' structure contains anything which affects the
192automatic generation of new puzzles. So if puzzle generation is
193parametrised in any way, those parameters need to be stored in
194`game_params'.
195
196Most puzzles currently in this collection are played on a grid of
197squares, meaning that the most obvious parameter is the grid size. Many
198puzzles have additional parameters; for example, Mines allows you to
199control the number of mines in the grid independently of its size, Net
200can be wrapping or non-wrapping, Solo has difficulty levels and symmetry
201settings, and so on.
202
203A simple rule for deciding whether a data item needs to go in
204`game_params' is: would the user expect to be able to control this data
205item from either the preset-game-types menu or the `Custom' game type
206configuration? If so, it's part of `game_params'.
207
208`game_params' structures are permitted to contain pointers to subsidiary
209data if they need to. The back end is required to provide functions to
210create and destroy `game_params', and those functions can allocate and
211free additional memory if necessary. (It has not yet been necessary to
212do this in any puzzle so far, but the capability is there just in case.)
213
214`game_params' is also the only structure which the game's compute_size()
215function may refer to; this means that any aspect of the game which
216affects the size of the window it needs to be drawn in must be stored in
217`game_params'. In particular, this imposes the fundamental limitation
218that random game generation may not have a random effect on the window
219size: game generation algorithms are constrained to work by starting
220from the grid size rather than generating it as an emergent phenomenon.
221(Although this is a restriction in theory, it has not yet seemed to be a
222problem.)
223
224#2.1.2. `game_state'
225
226While the user is actually playing a puzzle, the `game_state' structure
227stores all the data corresponding to the current state of play.
228
229The mid-end keeps `game_state's in a list, and adds to the list every
230time the player makes a move; the Undo and Redo functions step back and
231forth through that list.
232
233Therefore, a good means of deciding whether a data item needs to go in
234`game_state' is: would a player expect that data item to be restored on
235undo? If so, put it in `game_state', and this will automatically happen
236without you having to lift a finger. If not - for example, the deaths
237counter in Mines is precisely something that does _not_ want to be reset
238to its previous state on an undo - then you might have found a data item
239that needs to go in `game_ui' instead.
240
241During play, `game_state's are often passed around without an
242accompanying `game_params' structure. Therefore, any information in
243`game_params' which is important during play (such as the grid size)
244must be duplicated within the `game_state'. One simple method of doing
245this is to have the `game_state' structure _contain_ a `game_params'
246structure as one of its members, although this isn't obligatory if you
247prefer to do it another way.
248
249#2.1.3. `game_drawstate'
250
251`game_drawstate' carries persistent state relating to the current
252graphical contents of the puzzle window. The same `game_drawstate'
253is passed to every call to the game redraw function, so that it can
254remember what it has already drawn and what needs redrawing.
255
256A typical use for a `game_drawstate' is to have an array mirroring the
257array of grid squares in the `game_state'; then every time the redraw
258function was passed a `game_state', it would loop over all the squares,
259and physically redraw any whose description in the `game_state' (i.e.
260what the square needs to look like when the redraw is completed) did
261not match its description in the `game_drawstate' (i.e. what the square
262currently looks like).
263
264`game_drawstate' is occasionally completely torn down and reconstructed
265by the mid-end, if the user somehow forces a full redraw. Therefore, no
266data should be stored in `game_drawstate' which is _not_ related to the
267state of the puzzle window, because it might be unexpectedly destroyed.
268
269The back end provides functions to create and destroy `game_drawstate',
270which means it can contain pointers to subsidiary allocated data if it
271needs to. A common thing to want to allocate in a `game_drawstate' is a
272`blitter'; see section 3.1.13 for more on this subject.
273
274#2.1.4. `game_ui'
275
276`game_ui' contains whatever doesn't fit into the above three structures!
277
278A new `game_ui' is created when the user begins playing a new instance
279of a puzzle (i.e. during `New Game' or after entering a game ID etc). It
280persists until the user finishes playing that game and begins another
281one (or closes the window); in particular, `Restart Game' does _not_
282destroy the `game_ui'.
283
284`game_ui' is useful for implementing user-interface state which is not
285part of `game_state'. Common examples are keyboard control (you wouldn't
286want to have to separately Undo through every cursor motion) and mouse
287dragging. See section 6.3.2 and section 6.3.3, respectively, for more
288details.
289
290Another use for `game_ui' is to store highly persistent data such as
291the Mines death counter. This is conceptually rather different: where
292the Net cursor position was _not important enough_ to preserve for the
293player to restore by Undo, the Mines death counter is _too important_ to
294permit the player to revert by Undo!
295
296A final use for `game_ui' is to pass information to the redraw function
297about recent changes to the game state. This is used in Mines, for
298example, to indicate whether a requested `flash' should be a white flash
299for victory or a red flash for defeat; see section 6.3.5.
300
301#2.2. Simple data in the back end
302
303In this section I begin to discuss each individual element in the back
304end structure. To begin with, here are some simple self-contained data
305elements.
306
307#2.2.1. `name'
308
309 const char *name;
310
311This is a simple ASCII string giving the name of the puzzle. This name
312will be used in window titles, in game selection menus on monolithic
313platforms, and anywhere else that the front end needs to know the name
314of a game.
315
316#2.2.2. `winhelp_topic'
317
318 const char *winhelp_topic;
319
320This member is used on Windows only, to provide online help. Although
321the Windows front end provides a separate binary for each puzzle, it has
322a single monolithic help file; so when a user selects `Help' from the
323menu, the program needs to open the help file and jump to the chapter
324describing that particular puzzle.
325
326Therefore, each chapter in `puzzles.but' is labelled with a _help topic_
327name, similar to this:
328
329 \cfg{winhelp-topic}{games.net}
330
331And then the corresponding game back end encodes the topic string (here
332`games.net') in the `winhelp_topic' element of the game structure.
333
334#2.3. Handling game parameter sets
335
336In this section I present the various functions which handle the
337`game_params' structure.
338
339#2.3.1. default_params()
340
341 game_params *(*default_params)(void);
342
343This function allocates a new `game_params' structure, fills it with the
344default values, and returns a pointer to it.
345
346#2.3.2. fetch_preset()
347
348 int (*fetch_preset)(int i, char **name, game_params **params);
349
350This function is one of the two APIs a back end can provide to populate
351the `Type' menu, which provides a list of conveniently accessible preset
352parameters for most games.
353
354The function is called with `i' equal to the index of the preset
355required (numbering from zero). It returns FALSE if that preset does
356not exist (if `i' is less than zero or greater than the largest preset
357index). Otherwise, it sets `*params' to point at a newly allocated
358`game_params' structure containing the preset information, sets `*name'
359to point at a newly allocated C string containing the preset title (to
360go on the `Type' menu), and returns TRUE.
361
362If the game does not wish to support any presets at all, this function
363is permitted to return FALSE always.
364
365If the game wants to return presets in the form of a hierarchical menu
366instead of a flat list (and, indeed, even if it doesn't), then it may
367set this function pointer to NULL, and instead fill in the alternative
368function pointer preset_menu (section 2.3.3).
369
370#2.3.3. preset_menu()
371
372 struct preset_menu *(*preset_menu)(void);
373
374This function is the more flexible of the two APIs by which a back end
375can define a collection of preset game parameters.
376
377This function simply returns a complete menu hierarchy, in the form
378of a `struct preset_menu' (see section 4.15) and further submenus (if
379it wishes) dangling off it. There are utility functions described in
380section 5.2 to make it easy for the back end to construct this menu.
381
382If the game has no need to return a hierarchy of menus, it may instead
383opt to implement the fetch_preset() function (see section 2.3.2).
384
385The game need not fill in the `id' fields in the preset menu structures.
386The mid-end will do that after it receives the structure from the game,
387and before passing it on to the front end.
388
389#2.3.4. encode_params()
390
391 char *(*encode_params)(const game_params *params, int full);
392
393The job of this function is to take a `game_params', and encode it in
394a string form for use in game IDs. The return value must be a newly
395allocated C string, and _must_ not contain a colon or a hash (since
396those characters are used to mark the end of the parameter section in a
397game ID).
398
399Ideally, it should also not contain any other potentially controversial
400punctuation; bear in mind when designing a string parameter format
401that it will probably be used on both Windows and Unix command lines
402under a variety of exciting shell quoting and metacharacter rules.
403Sticking entirely to alphanumerics is the safest thing; if you really
404need punctuation, you can probably get away with commas, periods or
405underscores without causing anybody any major inconvenience. If you
406venture far beyond that, you're likely to irritate _somebody_.
407
408(At the time of writing this, all existing games have purely
409alphanumeric string parameter formats. Usually these involve a letter
410denoting a parameter, followed optionally by a number giving the value
411of that parameter, with a few mandatory parts at the beginning such as
412numeric width and height separated by `x'.)
413
414If the `full' parameter is TRUE, this function should encode absolutely
415everything in the `game_params', such that a subsequent call to
416decode_params() (section 2.3.5) will yield an identical structure.
417If `full' is FALSE, however, you should leave out anything which
418is not necessary to describe a _specific puzzle instance_, i.e.
419anything which only takes effect when a new puzzle is _generated_.
420For example, the Solo `game_params' includes a difficulty rating used
421when constructing new puzzles; but a Solo game ID need not explicitly
422include the difficulty, since to describe a puzzle once generated it's
423sufficient to give the grid dimensions and the location and contents
424of the clue squares. (Indeed, one might very easily type in a puzzle
425out of a newspaper without _knowing_ what its difficulty level is in
426Solo's terminology.) Therefore, Solo's encode_params() only encodes the
427difficulty level if `full' is set.
428
429#2.3.5. decode_params()
430
431 void (*decode_params)(game_params *params, char const *string);
432
433This function is the inverse of encode_params() (section 2.3.4). It
434parses the supplied string and fills in the supplied `game_params'
435structure. Note that the structure will _already_ have been allocated:
436this function is not expected to create a _new_ `game_params', but to
437modify an existing one.
438
439This function can receive a string which only encodes a subset of the
440parameters. The most obvious way in which this can happen is if the
441string was constructed by encode_params() with its `full' parameter set
442to FALSE; however, it could also happen if the user typed in a parameter
443set manually and missed something out. Be prepared to deal with a wide
444range of possibilities.
445
446When dealing with a parameter which is not specified in the input
447string, what to do requires a judgment call on the part of the
448programmer. Sometimes it makes sense to adjust other parameters to bring
449them into line with the new ones. In Mines, for example, you would
450probably not want to keep the same mine count if the user dropped the
451grid size and didn't specify one, since you might easily end up with
452more mines than would actually fit in the grid! On the other hand,
453sometimes it makes sense to leave the parameter alone: a Solo player
454might reasonably expect to be able to configure size and difficulty
455independently of one another.
456
457This function currently has no direct means of returning an error if the
458string cannot be parsed at all. However, the returned `game_params' is
459almost always subsequently passed to validate_params() (section 2.3.11),
460so if you really want to signal parse errors, you could always have a
461`char *' in your parameters structure which stored an error message, and
462have validate_params() return it if it is non-NULL.
463
464#2.3.6. free_params()
465
466 void (*free_params)(game_params *params);
467
468This function frees a `game_params' structure, and any subsidiary
469allocations contained within it.
470
471#2.3.7. dup_params()
472
473 game_params *(*dup_params)(const game_params *params);
474
475This function allocates a new `game_params' structure and initialises it
476with an exact copy of the information in the one provided as input. It
477returns a pointer to the new duplicate.
478
479#2.3.8. `can_configure'
480
481 int can_configure;
482
483This boolean data element is set to TRUE if the back end supports
484custom parameter configuration via a dialog box. If it is TRUE, then
485the functions configure() and custom_params() are expected to work. See
486section 2.3.9 and section 2.3.10 for more details.
487
488#2.3.9. configure()
489
490 config_item *(*configure)(const game_params *params);
491
492This function is called when the user requests a dialog box for
493custom parameter configuration. It returns a newly allocated array of
494config_item structures, describing the GUI elements required in the
495dialog box. The array should have one more element than the number of
496controls, since it is terminated with a C_END marker (see below). Each
497array element describes the control together with its initial value; the
498front end will modify the value fields and return the updated array to
499custom_params() (see section 2.3.10).
500
501The config_item structure contains the following elements:
502
503 char *name;
504 int type;
505 union { /* type-specific fields */ } u;
506
507`name' is an ASCII string giving the textual label for a GUI control. It
508is _not_ expected to be dynamically allocated.
509
510`type' contains one of a small number of `enum' values defining what
511type of control is being described. The usable member of the union field
512`u' depends on `type'. The valid type values are:
513
514`C_STRING'
515
516 Describes a text input box. (This is also used for numeric input.
517 The back end does not bother informing the front end that the box is
518 numeric rather than textual; some front ends do have the capacity
519 to take this into account, but I decided it wasn't worth the extra
520 complexity in the interface.)
521
522 For controls of this type, `u.string' contains a single field
523
524 char *sval;
525
526 which stores a dynamically allocated string representing the
527 contents of the input box.
528
529`C_BOOLEAN'
530
531 Describes a simple checkbox.
532
533 For controls of this type, `u.boolean' contains a single field
534
535 int bval;
536
537 which is either TRUE or FALSE.
538
539`C_CHOICES'
540
541 Describes a drop-down list presenting one of a small number of fixed
542 choices.
543
544 For controls of this type, `u.choices' contains two fields:
545
546 const char *choicenames;
547 int selected;
548
549 `choicenames' contains a list of strings describing the choices.
550 The very first character of `sval' is used as a delimiter when
551 processing the rest (so that the strings `:zero:one:two',
552 `!zero!one!two' and `xzeroxonextwo' all define a three-element list
553 containing `zero', `one' and `two').
554
555 `selected' contains the index of the currently selected element,
556 numbering from zero (so that in the above example, 0 would mean
557 `zero' and 2 would mean `two').
558
559 Note that `u.choices.choicenames' is _not_ dynamically allocated,
560 unlike `u.string.sval'.
561
562`C_END'
563
564 Marks the end of the array of `config_item's. There is no associated
565 member of the union field `u' for this type.
566
567The array returned from this function is expected to have filled in the
568initial values of all the controls according to the input `game_params'
569structure.
570
571If the game's `can_configure' flag is set to FALSE, this function is
572never called and need not do anything at all.
573
574#2.3.10. custom_params()
575
576 game_params *(*custom_params)(const config_item *cfg);
577
578This function is the counterpart to configure() (section 2.3.9). It
579receives as input an array of `config_item's which was originally
580created by configure(), but in which the control values have since been
581changed in accordance with user input. Its function is to read the new
582values out of the controls and return a newly allocated `game_params'
583structure representing the user's chosen parameter set.
584
585(The front end will have modified the controls' _values_, but there will
586still always be the same set of controls, in the same order, as provided
587by configure(). It is not necessary to check the `name' and `type'
588fields, although you could use assert() if you were feeling energetic.)
589
590This function is not expected to (and indeed _must not_) free the input
591`config_item' array. (If the parameters fail to validate, the dialog box
592will stay open.)
593
594If the game's `can_configure' flag is set to FALSE, this function is
595never called and need not do anything at all.
596
597#2.3.11. validate_params()
598
599 const char *(*validate_params)(const game_params *params,
600 int full);
601
602This function takes a `game_params' structure as input, and checks that
603the parameters described in it fall within sensible limits. (At the very
604least, grid dimensions should almost certainly be strictly positive, for
605example.)
606
607Return value is NULL if no problems were found, or alternatively a (non-
608dynamically-allocated) ASCII string describing the error in human-
609readable form.
610
611If the `full' parameter is set, full validation should be performed: any
612set of parameters which would not permit generation of a sensible puzzle
613should be faulted. If `full' is _not_ set, the implication is that
614these parameters are not going to be used for _generating_ a puzzle; so
615parameters which can't even sensibly _describe_ a valid puzzle should
616still be faulted, but parameters which only affect puzzle generation
617should not be.
618
619(The `full' option makes a difference when parameter combinations are
620non-orthogonal. For example, Net has a boolean option controlling
621whether it enforces a unique solution; it turns out that it's impossible
622to generate a uniquely soluble puzzle with wrapping walls and width
6232, so validate_params() will complain if you ask for one. However,
624if the user had just been playing a unique wrapping puzzle of a more
625sensible width, and then pastes in a game ID acquired from somebody else
626which happens to describe a _non_-unique wrapping width-2 puzzle, then
627validate_params() will be passed a `game_params' containing the width
628and wrapping settings from the new game ID and the uniqueness setting
629from the old one. This would be faulted, if it weren't for the fact that
630`full' is not set during this call, so Net ignores the inconsistency.
631The resulting `game_params' is never subsequently used to generate a
632puzzle; this is a promise made by the mid-end when it asks for a non-
633full validation.)
634
635#2.4. Handling game descriptions
636
637In this section I present the functions that deal with a textual
638description of a puzzle, i.e. the part that comes after the colon in a
639descriptive-format game ID.
640
641#2.4.1. new_desc()
642
643 char *(*new_desc)(const game_params *params, random_state *rs,
644 char **aux, int interactive);
645
646This function is where all the really hard work gets done. This is
647the function whose job is to randomly generate a new puzzle, ensuring
648solubility and uniqueness as appropriate.
649
650As input it is given a `game_params' structure and a random state
651(see section 5.1 for the random number API). It must invent a puzzle
652instance, encode it in string form, and return a dynamically allocated C
653string containing that encoding.
654
655Additionally, it may return a second dynamically allocated string
656in `*aux'. (If it doesn't want to, then it can leave that parameter
657completely alone; it isn't required to set it to NULL, although doing
658so is harmless.) That string, if present, will be passed to solve()
659(section 2.7.4) later on; so if the puzzle is generated in such a way
660that a solution is known, then information about that solution can be
661saved in `*aux' for solve() to use.
662
663The `interactive' parameter should be ignored by almost all puzzles.
664Its purpose is to distinguish between generating a puzzle within a GUI
665context for immediate play, and generating a puzzle in a command-line
666context for saving to be played later. The only puzzle that currently
667uses this distinction (and, I fervently hope, the only one which will
668_ever_ need to use it) is Mines, which chooses a random first-click
669location when generating puzzles non-interactively, but which waits
670for the user to place the first click when interactive. If you think
671you have come up with another puzzle which needs to make use of this
672parameter, please think for at least ten minutes about whether there is
673_any_ alternative!
674
675Note that game description strings are not required to contain an
676encoding of parameters such as grid size; a game description is
677never separated from the `game_params' it was generated with, so any
678information contained in that structure need not be encoded again in the
679game description.
680
681#2.4.2. validate_desc()
682
683 const char *(*validate_desc)(const game_params *params,
684 const char *desc);
685
686This function is given a game description, and its job is to validate
687that it describes a puzzle which makes sense.
688
689To some extent it's up to the user exactly how far they take the phrase
690`makes sense'; there are no particularly strict rules about how hard the
691user is permitted to shoot themself in the foot when typing in a bogus
692game description by hand. (For example, Rectangles will not verify that
693the sum of all the numbers in the grid equals the grid's area. So a user
694could enter a puzzle which was provably not soluble, and the program
695wouldn't complain; there just wouldn't happen to be any sequence of
696moves which solved it.)
697
698The one non-negotiable criterion is that any game description which
699makes it through validate_desc() _must not_ subsequently cause a crash
700or an assertion failure when fed to new_game() and thence to the rest of
701the back end.
702
703The return value is NULL on success, or a non-dynamically-allocated C
704string containing an error message.
705
706#2.4.3. new_game()
707
708 game_state *(*new_game)(midend *me, const game_params *params,
709 const char *desc);
710
711This function takes a game description as input, together with its
712accompanying `game_params', and constructs a `game_state' describing the
713initial state of the puzzle. It returns a newly allocated `game_state'
714structure.
715
716Almost all puzzles should ignore the `me' parameter. It is required by
717Mines, which needs it for later passing to midend_supersede_game_desc()
718(see section 2.11.2) once the user has placed the first click. I
719fervently hope that no other puzzle will be awkward enough to require
720it, so everybody else should ignore it. As with the `interactive'
721parameter in new_desc() (section 2.4.1), if you think you have a reason
722to need this parameter, please try very hard to think of an alternative
723approach!
724
725#2.5. Handling game states
726
727This section describes the functions which create and destroy
728`game_state' structures.
729
730(Well, except new_game(), which is in section 2.4.3 instead of under
731here; but it deals with game descriptions _and_ game states and it had
732to go in one section or the other.)
733
734#2.5.1. dup_game()
735
736 game_state *(*dup_game)(const game_state *state);
737
738This function allocates a new `game_state' structure and initialises it
739with an exact copy of the information in the one provided as input. It
740returns a pointer to the new duplicate.
741
742#2.5.2. free_game()
743
744 void (*free_game)(game_state *state);
745
746This function frees a `game_state' structure, and any subsidiary
747allocations contained within it.
748
749#2.6. Handling `game_ui'
750
751#2.6.1. new_ui()
752
753 game_ui *(*new_ui)(const game_state *state);
754
755This function allocates and returns a new `game_ui' structure for
756playing a particular puzzle. It is passed a pointer to the initial
757`game_state', in case it needs to refer to that when setting up the
758initial values for the new game.
759
760#2.6.2. free_ui()
761
762 void (*free_ui)(game_ui *ui);
763
764This function frees a `game_ui' structure, and any subsidiary
765allocations contained within it.
766
767#2.6.3. encode_ui()
768
769 char *(*encode_ui)(const game_ui *ui);
770
771This function encodes any _important_ data in a `game_ui' structure in
772string form. It is only called when saving a half-finished game to a
773file.
774
775It should be used sparingly. Almost all data in a `game_ui' is not
776important enough to save. The location of the keyboard-controlled
777cursor, for example, can be reset to a default position on reloading
778the game without impacting the user experience. If the user should
779somehow manage to save a game while a mouse drag was in progress, then
780discarding that mouse drag would be an outright _feature_.
781
782A typical thing that _would_ be worth encoding in this function is the
783Mines death counter: it's in the `game_ui' rather than the `game_state'
784because it's too important to allow the user to revert it by using Undo,
785and therefore it's also too important to allow the user to revert it by
786saving and reloading. (Of course, the user could edit the save file by
787hand... But if the user is _that_ determined to cheat, they could just
788as easily modify the game's source.)
789
790#2.6.4. decode_ui()
791
792 void (*decode_ui)(game_ui *ui, const char *encoding);
793
794This function parses a string previously output by encode_ui(), and
795writes the decoded data back into the provided `game_ui' structure.
796
797#2.6.5. changed_state()
798
799 void (*changed_state)(game_ui *ui, const game_state *oldstate,
800 const game_state *newstate);
801
802This function is called by the mid-end whenever the current game state
803changes, for any reason. Those reasons include:
804
805 - a fresh move being made by interpret_move() and execute_move()
806
807 - a solve operation being performed by solve() and execute_move()
808
809 - the user moving back and forth along the undo list by means of the
810 Undo and Redo operations
811
812 - the user selecting Restart to go back to the initial game state.
813
814The job of changed_state() is to update the `game_ui' for consistency
815with the new game state, if any update is necessary. For example,
816Same Game stores data about the currently selected tile group in its
817`game_ui', and this data is intrinsically related to the game state it
818was derived from. So it's very likely to become invalid when the game
819state changes; thus, Same Game's changed_state() function clears the
820current selection whenever it is called.
821
822When anim_length() or flash_length() are called, you can be sure that
823there has been a previous call to changed_state(). So changed_state()
824can set up data in the `game_ui' which will be read by anim_length() and
825flash_length(), and those functions will not have to worry about being
826called without the data having been initialised.
827
828#2.7. Making moves
829
830This section describes the functions which actually make moves in
831the game: that is, the functions which process user input and end up
832producing new `game_state's.
833
834#2.7.1. interpret_move()
835
836 char *(*interpret_move)(const game_state *state, game_ui *ui,
837 const game_drawstate *ds,
838 int x, int y, int button);
839
840This function receives user input and processes it. Its input parameters
841are the current `game_state', the current `game_ui' and the current
842`game_drawstate', plus details of the input event. `button' is either
843an ASCII value or a special code (listed below) indicating an arrow or
844function key or a mouse event; when `button' is a mouse event, `x' and
845`y' contain the pixel coordinates of the mouse pointer relative to the
846top left of the puzzle's drawing area.
847
848(The pointer to the `game_drawstate' is marked `const', because
849`interpret_move' should not write to it. The normal use of that pointer
850will be to read the game's tile size parameter in order to divide mouse
851coordinates by it.)
852
853interpret_move() may return in three different ways:
854
855 - Returning NULL indicates that no action whatsoever occurred in
856 response to the input event; the puzzle was not interested in it at
857 all.
858
859 - Returning the special value UI_UPDATE indicates that the input event
860 has resulted in a change being made to the `game_ui' which will
861 require a redraw of the game window, but that no actual _move_ was
862 made (i.e. no new `game_state' needs to be created).
863
864 - Returning anything else indicates that a move was made and that
865 a new `game_state' must be created. However, instead of actually
866 constructing a new `game_state' itself, this function is required to
867 return a string description of the details of the move. This string
868 will be passed to execute_move() (section 2.7.2) to actually create
869 the new `game_state'. (Encoding moves as strings in this way means
870 that the mid-end can keep the strings as well as the game states,
871 and the strings can be written to disk when saving the game and fed
872 to execute_move() again on reloading.)
873
874The return value from interpret_move() is expected to be dynamically
875allocated if and only if it is not either NULL _or_ the special string
876constant `UI_UPDATE'.
877
878After this function is called, the back end is permitted to rely on some
879subsequent operations happening in sequence:
880
881 - execute_move() will be called to convert this move description into
882 a new `game_state'
883
884 - changed_state() will be called with the new `game_state'.
885
886This means that if interpret_move() needs to do updates to the `game_ui'
887which are easier to perform by referring to the new `game_state', it can
888safely leave them to be done in changed_state() and not worry about them
889failing to happen.
890
891(Note, however, that execute_move() may _also_ be called in other
892circumstances. It is only interpret_move() which can rely on a
893subsequent call to changed_state().)
894
895The special key codes supported by this function are:
896
897LEFT_BUTTON, MIDDLE_BUTTON, RIGHT_BUTTON
898
899 Indicate that one of the mouse buttons was pressed down.
900
901LEFT_DRAG, MIDDLE_DRAG, RIGHT_DRAG
902
903 Indicate that the mouse was moved while one of the mouse buttons was
904 still down. The mid-end guarantees that when one of these events is
905 received, it will always have been preceded by a button-down event
906 (and possibly other drag events) for the same mouse button, and no
907 event involving another mouse button will have appeared in between.
908
909LEFT_RELEASE, MIDDLE_RELEASE, RIGHT_RELEASE
910
911 Indicate that a mouse button was released. The mid-end guarantees
912 that when one of these events is received, it will always have been
913 preceded by a button-down event (and possibly some drag events) for
914 the same mouse button, and no event involving another mouse button
915 will have appeared in between.
916
917CURSOR_UP, CURSOR_DOWN, CURSOR_LEFT, CURSOR_RIGHT
918
919 Indicate that an arrow key was pressed.
920
921CURSOR_SELECT
922
923 On platforms which have a prominent `select' button alongside their
924 cursor keys, indicates that that button was pressed.
925
926In addition, there are some modifiers which can be bitwise-ORed into the
927`button' parameter:
928
929MOD_CTRL, MOD_SHFT
930
931 These indicate that the Control or Shift key was pressed alongside
932 the key. They only apply to the cursor keys, not to mouse buttons or
933 anything else.
934
935MOD_NUM_KEYPAD
936
937 This applies to some ASCII values, and indicates that the key code
938 was input via the numeric keypad rather than the main keyboard. Some
939 puzzles may wish to treat this differently (for example, a puzzle
940 might want to use the numeric keypad as an eight-way directional
941 pad), whereas others might not (a game involving numeric input
942 probably just wants to treat the numeric keypad as numbers).
943
944MOD_MASK
945
946 This mask is the bitwise OR of all the available modifiers; you can
947 bitwise-AND with ~MOD_MASK to strip all the modifiers off any input
948 value.
949
950#2.7.2. execute_move()
951
952 game_state *(*execute_move)(const game_state *state, char *move);
953
954This function takes an input `game_state' and a move string as output
955from interpret_move(). It returns a newly allocated `game_state' which
956contains the result of applying the specified move to the input game
957state.
958
959This function may return NULL if it cannot parse the move string (and
960this is definitely preferable to crashing or failing an assertion, since
961one way this can happen is if loading a corrupt save file). However, it
962must not return NULL for any move string that really was output from
963interpret_move(): this is punishable by assertion failure in the mid-
964end.
965
966#2.7.3. `can_solve'
967
968 int can_solve;
969
970This boolean field is set to TRUE if the game's solve() function does
971something. If it's set to FALSE, the game will not even offer the
972`Solve' menu option.
973
974#2.7.4. solve()
975
976 char *(*solve)(const game_state *orig, const game_state *curr,
977 const char *aux, const char **error);
978
979This function is called when the user selects the `Solve' option from
980the menu.
981
982It is passed two input game states: `orig' is the game state from the
983very start of the puzzle, and `curr' is the current one. (Different
984games find one or other or both of these convenient.) It is also passed
985the `aux' string saved by new_desc() (section 2.4.1), in case that
986encodes important information needed to provide the solution.
987
988If this function is unable to produce a solution (perhaps, for example,
989the game has no in-built solver so it can only solve puzzles it invented
990internally and has an `aux' string for) then it may return NULL. If it
991does this, it must also set `*error' to an error message to be presented
992to the user (such as `Solution not known for this puzzle'); that error
993message is not expected to be dynamically allocated.
994
995If this function _does_ produce a solution, it returns a move string
996suitable for feeding to execute_move() (section 2.7.2). Like a (non-
997empty) string returned from interpret_move(), the returned string should
998be dynamically allocated.
999
1000#2.8. Drawing the game graphics
1001
1002This section discusses the back end functions that deal with drawing.
1003
1004#2.8.1. new_drawstate()
1005
1006 game_drawstate *(*new_drawstate)(drawing *dr,
1007 const game_state *state);
1008
1009This function allocates and returns a new `game_drawstate' structure for
1010drawing a particular puzzle. It is passed a pointer to a `game_state',
1011in case it needs to refer to that when setting up any initial data.
1012
1013This function may not rely on the puzzle having been newly started; a
1014new draw state can be constructed at any time if the front end requests
1015a forced redraw. For games like Pattern, in which initial game states
1016are much simpler than general ones, this might be important to keep in
1017mind.
1018
1019The parameter `dr' is a drawing object (see chapter 3) which the
1020function might need to use to allocate blitters. (However, this isn't
1021recommended; it's usually more sensible to wait to allocate a blitter
1022until set_size() is called, because that way you can tailor it to the
1023scale at which the puzzle is being drawn.)
1024
1025#2.8.2. free_drawstate()
1026
1027 void (*free_drawstate)(drawing *dr, game_drawstate *ds);
1028
1029This function frees a `game_drawstate' structure, and any subsidiary
1030allocations contained within it.
1031
1032The parameter `dr' is a drawing object (see chapter 3), which might be
1033required if you are freeing a blitter.
1034
1035#2.8.3. `preferred_tilesize'
1036
1037 int preferred_tilesize;
1038
1039Each game is required to define a single integer parameter which
1040expresses, in some sense, the scale at which it is drawn. This is
1041described in the APIs as `tilesize', since most puzzles are on a
1042square (or possibly triangular or hexagonal) grid and hence a sensible
1043interpretation of this parameter is to define it as the size of one grid
1044tile in pixels; however, there's no actual requirement that the `tile
1045size' be proportional to the game window size. Window size is required
1046to increase monotonically with `tile size', however.
1047
1048The data element `preferred_tilesize' indicates the tile size which
1049should be used in the absence of a good reason to do otherwise (such as
1050the screen being too small, or the user explicitly requesting a resize
1051if that ever gets implemented).
1052
1053#2.8.4. compute_size()
1054
1055 void (*compute_size)(const game_params *params, int tilesize,
1056 int *x, int *y);
1057
1058This function is passed a `game_params' structure and a tile size. It
1059returns, in `*x' and `*y', the size in pixels of the drawing area that
1060would be required to render a puzzle with those parameters at that tile
1061size.
1062
1063#2.8.5. set_size()
1064
1065 void (*set_size)(drawing *dr, game_drawstate *ds,
1066 const game_params *params, int tilesize);
1067
1068This function is responsible for setting up a `game_drawstate' to draw
1069at a given tile size. Typically this will simply involve copying the
1070supplied `tilesize' parameter into a `tilesize' field inside the draw
1071state; for some more complex games it might also involve setting up
1072other dimension fields, or possibly allocating a blitter (see section
10733.1.13).
1074
1075The parameter `dr' is a drawing object (see chapter 3), which is
1076required if a blitter needs to be allocated.
1077
1078Back ends may assume (and may enforce by assertion) that this function
1079will be called at most once for any `game_drawstate'. If a puzzle needs
1080to be redrawn at a different size, the mid-end will create a fresh
1081drawstate.
1082
1083#2.8.6. colours()
1084
1085 float *(*colours)(frontend *fe, int *ncolours);
1086
1087This function is responsible for telling the front end what colours the
1088puzzle will need to draw itself.
1089
1090It returns the number of colours required in `*ncolours', and the return
1091value from the function itself is a dynamically allocated array of three
1092times that many `float's, containing the red, green and blue components
1093of each colour respectively as numbers in the range [0,1].
1094
1095The second parameter passed to this function is a front end handle.
1096The only things it is permitted to do with this handle are to call the
1097front-end function called frontend_default_colour() (see section 4.39)
1098or the utility function called game_mkhighlight() (see section 5.5.7).
1099(The latter is a wrapper on the former, so front end implementors only
1100need to provide frontend_default_colour().) This allows colours() to
1101take local configuration into account when deciding on its own colour
1102allocations. Most games use the front end's default colour as their
1103background, apart from a few which depend on drawing relief highlights
1104so they adjust the background colour if it's too light for highlights to
1105show up against it.
1106
1107Note that the colours returned from this function are for _drawing_,
1108not for printing. Printing has an entirely different colour allocation
1109policy.
1110
1111#2.8.7. anim_length()
1112
1113 float (*anim_length)(const game_state *oldstate,
1114 const game_state *newstate,
1115 int dir, game_ui *ui);
1116
1117This function is called when a move is made, undone or redone. It is
1118given the old and the new `game_state', and its job is to decide whether
1119the transition between the two needs to be animated or can be instant.
1120
1121`oldstate' is the state that was current until this call; `newstate'
1122is the state that will be current after it. `dir' specifies the
1123chronological order of those states: if it is positive, then the
1124transition is the result of a move or a redo (and so `newstate' is the
1125later of the two moves), whereas if it is negative then the transition
1126is the result of an undo (so that `newstate' is the _earlier_ move).
1127
1128If this function decides the transition should be animated, it returns
1129the desired length of the animation in seconds. If not, it returns zero.
1130
1131State changes as a result of a Restart operation are never animated; the
1132mid-end will handle them internally and never consult this function at
1133all. State changes as a result of Solve operations are also not animated
1134by default, although you can change this for a particular game by
1135setting a flag in `flags' (section 2.10.7).
1136
1137The function is also passed a pointer to the local `game_ui'. It may
1138refer to information in here to help with its decision (see section
11396.3.7 for an example of this), and/or it may _write_ information about
1140the nature of the animation which will be read later by redraw().
1141
1142When this function is called, it may rely on changed_state() having been
1143called previously, so if anim_length() needs to refer to information in
1144the `game_ui', then changed_state() is a reliable place to have set that
1145information up.
1146
1147Move animations do not inhibit further input events. If the user
1148continues playing before a move animation is complete, the animation
1149will be abandoned and the display will jump straight to the final state.
1150
1151#2.8.8. flash_length()
1152
1153 float (*flash_length)(const game_state *oldstate,
1154 const game_state *newstate,
1155 int dir, game_ui *ui);
1156
1157This function is called when a move is completed. (`Completed'
1158means that not only has the move been made, but any animation which
1159accompanied it has finished.) It decides whether the transition from
1160`oldstate' to `newstate' merits a `flash'.
1161
1162A flash is much like a move animation, but it is _not_ interrupted by
1163further user interface activity; it runs to completion in parallel with
1164whatever else might be going on on the display. The only thing which
1165will rush a flash to completion is another flash.
1166
1167The purpose of flashes is to indicate that the game has been completed.
1168They were introduced as a separate concept from move animations because
1169of Net: the habit of most Net players (and certainly me) is to rotate a
1170tile into place and immediately lock it, then move on to another tile.
1171When you make your last move, at the instant the final tile is rotated
1172into place the screen starts to flash to indicate victory - but if you
1173then press the lock button out of habit, then the move animation is
1174cancelled, and the victory flash does not complete. (And if you _don't_
1175press the lock button, the completed grid will look untidy because there
1176will be one unlocked square.) Therefore, I introduced a specific concept
1177of a `flash' which is separate from a move animation and can proceed in
1178parallel with move animations and any other display activity, so that
1179the victory flash in Net is not cancelled by that final locking move.
1180
1181The input parameters to flash_length() are exactly the same as the ones
1182to anim_length().
1183
1184Just like anim_length(), when this function is called, it may rely on
1185changed_state() having been called previously, so if it needs to refer
1186to information in the `game_ui' then changed_state() is a reliable place
1187to have set that information up.
1188
1189(Some games use flashes to indicate defeat as well as victory; Mines,
1190for example, flashes in a different colour when you tread on a mine from
1191the colour it uses when you complete the game. In order to achieve this,
1192its flash_length() function has to store a flag in the `game_ui' to
1193indicate which flash type is required.)
1194
1195#2.8.9. status()
1196
1197 int (*status)(const game_state *state);
1198
1199This function returns a status value indicating whether the current game
1200is still in play, or has been won, or has been conclusively lost. The
1201mid-end uses this to implement midend_status() (section 4.26).
1202
1203The return value should be +1 if the game has been successfully solved.
1204If the game has been lost in a situation where further play is unlikely,
1205the return value should be -1. If neither is true (so play is still
1206ongoing), return zero.
1207
1208Front ends may wish to use a non-zero status as a cue to proactively
1209offer the option of starting a new game. Therefore, back ends should
1210not return -1 if the game has been _technically_ lost but undoing and
1211continuing is still a realistic possibility.
1212
1213(For instance, games with hidden information such as Guess or Mines
1214might well return a non-zero status whenever they reveal the solution,
1215whether or not the player guessed it correctly, on the grounds that a
1216player would be unlikely to hide the solution and continue playing after
1217the answer was spoiled. On the other hand, games where you can merely
1218get into a dead end such as Same Game or Inertia might choose to return
12190 in that situation, on the grounds that the player would quite likely
1220press Undo and carry on playing.)
1221
1222#2.8.10. redraw()
1223
1224 void (*redraw)(drawing *dr, game_drawstate *ds,
1225 const game_state *oldstate,
1226 const game_state *newstate,
1227 int dir, const game_ui *ui,
1228 float anim_time, float flash_time);
1229
1230This function is responsible for actually drawing the contents of
1231the game window, and for redrawing every time the game state or the
1232`game_ui' changes.
1233
1234The parameter `dr' is a drawing object which may be passed to the
1235drawing API functions (see chapter 3 for documentation of the drawing
1236API). This function may not save `dr' and use it elsewhere; it must only
1237use it for calling back to the drawing API functions within its own
1238lifetime.
1239
1240`ds' is the local `game_drawstate', of course, and `ui' is the local
1241`game_ui'.
1242
1243`newstate' is the semantically-current game state, and is always non-
1244NULL. If `oldstate' is also non-NULL, it means that a move has recently
1245been made and the game is still in the process of displaying an
1246animation linking the old and new states; in this situation, `anim_time'
1247will give the length of time (in seconds) that the animation has already
1248been running. If `oldstate' is NULL, then `anim_time' is unused (and
1249will hopefully be set to zero to avoid confusion).
1250
1251`flash_time', if it is is non-zero, denotes that the game is in the
1252middle of a flash, and gives the time since the start of the flash. See
1253section 2.8.8 for general discussion of flashes.
1254
1255The very first time this function is called for a new `game_drawstate',
1256it is expected to redraw the _entire_ drawing area. Since this often
1257involves drawing visual furniture which is never subsequently altered,
1258it is often simplest to arrange this by having a special `first time'
1259flag in the draw state, and resetting it after the first redraw.
1260
1261When this function (or any subfunction) calls the drawing API, it is
1262expected to pass colour indices which were previously defined by the
1263colours() function.
1264
1265#2.9. Printing functions
1266
1267This section discusses the back end functions that deal with printing
1268puzzles out on paper.
1269
1270#2.9.1. `can_print'
1271
1272 int can_print;
1273
1274This flag is set to TRUE if the puzzle is capable of printing itself
1275on paper. (This makes sense for some puzzles, such as Solo, which can
1276be filled in with a pencil. Other puzzles, such as Twiddle, inherently
1277involve moving things around and so would not make sense to print.)
1278
1279If this flag is FALSE, then the functions print_size() and print() will
1280never be called.
1281
1282#2.9.2. `can_print_in_colour'
1283
1284 int can_print_in_colour;
1285
1286This flag is set to TRUE if the puzzle is capable of printing itself
1287differently when colour is available. For example, Map can actually
1288print coloured regions in different _colours_ rather than resorting to
1289cross-hatching.
1290
1291If the `can_print' flag is FALSE, then this flag will be ignored.
1292
1293#2.9.3. print_size()
1294
1295 void (*print_size)(const game_params *params, float *x, float *y);
1296
1297This function is passed a `game_params' structure and a tile size. It
1298returns, in `*x' and `*y', the preferred size in _millimetres_ of that
1299puzzle if it were to be printed out on paper.
1300
1301If the `can_print' flag is FALSE, this function will never be called.
1302
1303#2.9.4. print()
1304
1305 void (*print)(drawing *dr, const game_state *state, int tilesize);
1306
1307This function is called when a puzzle is to be printed out on paper. It
1308should use the drawing API functions (see chapter 3) to print itself.
1309
1310This function is separate from redraw() because it is often very
1311different:
1312
1313 - The printing function may not depend on pixel accuracy, since
1314 printer resolution is variable. Draw as if your canvas had infinite
1315 resolution.
1316
1317 - The printing function sometimes needs to display things in a
1318 completely different style. Net, for example, is very different as
1319 an on-screen puzzle and as a printed one.
1320
1321 - The printing function is often much simpler since it has no need to
1322 deal with repeated partial redraws.
1323
1324However, there's no reason the printing and redraw functions can't share
1325some code if they want to.
1326
1327When this function (or any subfunction) calls the drawing API, the
1328colour indices it passes should be colours which have been allocated by
1329the print_*_colour() functions within this execution of print(). This is
1330very different from the fixed small number of colours used in redraw(),
1331because printers do not have a limitation on the total number of colours
1332that may be used. Some puzzles' printing functions might wish to
1333allocate only one `ink' colour and use it for all drawing; others might
1334wish to allocate _more_ colours than are used on screen.
1335
1336One possible colour policy worth mentioning specifically is that a
1337puzzle's printing function might want to allocate the _same_ colour
1338indices as are used by the redraw function, so that code shared between
1339drawing and printing does not have to keep switching its colour indices.
1340In order to do this, the simplest thing is to make use of the fact that
1341colour indices returned from print_*_colour() are guaranteed to be in
1342increasing order from zero. So if you have declared an `enum' defining
1343three colours COL_BACKGROUND, COL_THIS and COL_THAT, you might then
1344write
1345
1346 int c;
1347 c = print_mono_colour(dr, 1); assert(c == COL_BACKGROUND);
1348 c = print_mono_colour(dr, 0); assert(c == COL_THIS);
1349 c = print_mono_colour(dr, 0); assert(c == COL_THAT);
1350
1351If the `can_print' flag is FALSE, this function will never be called.
1352
1353#2.10. Miscellaneous
1354
1355#2.10.1. `can_format_as_text_ever'
1356
1357 int can_format_as_text_ever;
1358
1359This boolean field is TRUE if the game supports formatting a game state
1360as ASCII text (typically ASCII art) for copying to the clipboard and
1361pasting into other applications. If it is FALSE, front ends will not
1362offer the `Copy' command at all.
1363
1364If this field is TRUE, the game does not necessarily have to support
1365text formatting for _all_ games: e.g. a game which can be played on
1366a square grid or a triangular one might only support copy and paste
1367for the former, because triangular grids in ASCII art are just too
1368difficult.
1369
1370If this field is FALSE, the functions can_format_as_text_now() (section
13712.10.2) and text_format() (section 2.10.3) are never called.
1372
1373#2.10.2. `can_format_as_text_now()'
1374
1375 int (*can_format_as_text_now)(const game_params *params);
1376
1377This function is passed a `game_params' and returns a boolean, which is
1378TRUE if the game can support ASCII text output for this particular game
1379type. If it returns FALSE, front ends will grey out or otherwise disable
1380the `Copy' command.
1381
1382Games may enable and disable the copy-and-paste function for different
1383game _parameters_, but are currently constrained to return the same
1384answer from this function for all game _states_ sharing the same
1385parameters. In other words, the `Copy' function may enable or disable
1386itself when the player changes game preset, but will never change during
1387play of a single game or when another game of exactly the same type is
1388generated.
1389
1390This function should not take into account aspects of the game
1391parameters which are not encoded by encode_params() (section 2.3.4)
1392when the `full' parameter is set to FALSE. Such parameters will not
1393necessarily match up between a call to this function and a subsequent
1394call to text_format() itself. (For instance, game _difficulty_ should
1395not affect whether the game can be copied to the clipboard. Only the
1396actual visible _shape_ of the game can affect that.)
1397
1398#2.10.3. text_format()
1399
1400 char *(*text_format)(const game_state *state);
1401
1402This function is passed a `game_state', and returns a newly allocated C
1403string containing an ASCII representation of that game state. It is used
1404to implement the `Copy' operation in many front ends.
1405
1406This function will only ever be called if the back end field
1407`can_format_as_text_ever' (section 2.10.1) is TRUE _and_ the function
1408can_format_as_text_now() (section 2.10.2) has returned TRUE for the
1409currently selected game parameters.
1410
1411The returned string may contain line endings (and will probably want
1412to), using the normal C internal `\n' convention. For consistency
1413between puzzles, all multi-line textual puzzle representations should
1414_end_ with a newline as well as containing them internally. (There are
1415currently no puzzles which have a one-line ASCII representation, so
1416there's no precedent yet for whether that should come with a newline or
1417not.)
1418
1419#2.10.4. wants_statusbar
1420
1421 int wants_statusbar;
1422
1423This boolean field is set to TRUE if the puzzle has a use for a textual
1424status line (to display score, completion status, currently active
1425tiles, etc).
1426
1427#2.10.5. `is_timed'
1428
1429 int is_timed;
1430
1431This boolean field is TRUE if the puzzle is time-critical. If so, the
1432mid-end will maintain a game timer while the user plays.
1433
1434If this field is FALSE, then timing_state() will never be called and
1435need not do anything.
1436
1437#2.10.6. timing_state()
1438
1439 int (*timing_state)(const game_state *state, game_ui *ui);
1440
1441This function is passed the current `game_state' and the local
1442`game_ui'; it returns TRUE if the game timer should currently be
1443running.
1444
1445A typical use for the `game_ui' in this function is to note when the
1446game was first completed (by setting a flag in changed_state() - see
1447section 2.6.5), and freeze the timer thereafter so that the user can
1448undo back through their solution process without altering their time.
1449
1450#2.10.7. `flags'
1451
1452 int flags;
1453
1454This field contains miscellaneous per-backend flags. It consists of the
1455bitwise OR of some combination of the following:
1456
1457BUTTON_BEATS(x,y)
1458
1459 Given any x and y from the set {LEFT_BUTTON, MIDDLE_BUTTON,
1460 RIGHT_BUTTON}, this macro evaluates to a bit flag which indicates
1461 that when buttons x and y are both pressed simultaneously, the mid-
1462 end should consider x to have priority. (In the absence of any such
1463 flags, the mid-end will always consider the most recently pressed
1464 button to have priority.)
1465
1466SOLVE_ANIMATES
1467
1468 This flag indicates that moves generated by solve() (section 2.7.4)
1469 are candidates for animation just like any other move. For most
1470 games, solve moves should not be animated, so the mid-end doesn't
1471 even bother calling anim_length() (section 2.8.7), thus saving some
1472 special-case code in each game. On the rare occasion that animated
1473 solve moves are actually required, you can set this flag.
1474
1475REQUIRE_RBUTTON
1476
1477 This flag indicates that the puzzle cannot be usefully played
1478 without the use of mouse buttons other than the left one. On some
1479 PDA platforms, this flag is used by the front end to enable right-
1480 button emulation through an appropriate gesture. Note that a puzzle
1481 is not required to set this just because it _uses_ the right button,
1482 but only if its use of the right button is critical to playing the
1483 game. (Slant, for example, uses the right button to cycle through
1484 the three square states in the opposite order from the left button,
1485 and hence can manage fine without it.)
1486
1487REQUIRE_NUMPAD
1488
1489 This flag indicates that the puzzle cannot be usefully played
1490 without the use of number-key input. On some PDA platforms it
1491 causes an emulated number pad to appear on the screen. Similarly to
1492 REQUIRE_RBUTTON, a puzzle need not specify this simply if its use of
1493 the number keys is not critical.
1494
1495#2.11. Things a back end may do on its own initiative
1496
1497This section describes a couple of things that a back end may choose
1498to do by calling functions elsewhere in the program, which would not
1499otherwise be obvious.
1500
1501#2.11.1. Create a random state
1502
1503If a back end needs random numbers at some point during normal play, it
1504can create a fresh `random_state' by first calling `get_random_seed'
1505(section 4.35) and then passing the returned seed data to random_new().
1506
1507This is likely not to be what you want. If a puzzle needs randomness in
1508the middle of play, it's likely to be more sensible to store some sort
1509of random state within the `game_state', so that the random numbers are
1510tied to the particular game state and hence the player can't simply keep
1511undoing their move until they get numbers they like better.
1512
1513This facility is currently used only in Net, to implement the `jumble'
1514command, which sets every unlocked tile to a new random orientation.
1515This randomness _is_ a reasonable use of the feature, because it's non-
1516adversarial - there's no advantage to the user in getting different
1517random numbers.
1518
1519#2.11.2. Supersede its own game description
1520
1521In response to a move, a back end is (reluctantly) permitted to call
1522midend_supersede_game_desc():
1523
1524 void midend_supersede_game_desc(midend *me,
1525 char *desc, char *privdesc);
1526
1527When the user selects `New Game', the mid-end calls new_desc()
1528(section 2.4.1) to get a new game description, and (as well as using
1529that to generate an initial game state) stores it for the save file
1530and for telling to the user. The function above overwrites that
1531game description, and also splits it in two. `desc' becomes the new
1532game description which is provided to the user on request, and is
1533also the one used to construct a new initial game state if the user
1534selects `Restart'. `privdesc' is a `private' game description, used to
1535reconstruct the game's initial state when reloading.
1536
1537The distinction between the two, as well as the need for this function
1538at all, comes from Mines. Mines begins with a blank grid and no
1539idea of where the mines actually are; new_desc() does almost no
1540work in interactive mode, and simply returns a string encoding the
1541`random_state'. When the user first clicks to open a tile, _then_ Mines
1542generates the mine positions, in such a way that the game is soluble
1543from that starting point. Then it uses this function to supersede the
1544random-state game description with a proper one. But it needs two: one
1545containing the initial click location (because that's what you want to
1546happen if you restart the game, and also what you want to send to a
1547friend so that they play _the same game_ as you), and one without the
1548initial click location (because when you save and reload the game, you
1549expect to see the same blank initial state as you had before saving).
1550
1551I should stress again that this function is a horrid hack. Nobody should
1552use it if they're not Mines; if you think you need to use it, think
1553again repeatedly in the hope of finding a better way to do whatever it
1554was you needed to do.
1555
1556#3. The drawing API
1557
1558The back end function redraw() (section 2.8.10) is required to draw
1559the puzzle's graphics on the window's drawing area, or on paper if the
1560puzzle is printable. To do this portably, it is provided with a drawing
1561API allowing it to talk directly to the front end. In this chapter I
1562document that API, both for the benefit of back end authors trying to
1563use it and for front end authors trying to implement it.
1564
1565The drawing API as seen by the back end is a collection of global
1566functions, each of which takes a pointer to a `drawing' structure (a
1567`drawing object'). These objects are supplied as parameters to the back
1568end's redraw() and print() functions.
1569
1570In fact these global functions are not implemented directly by the front
1571end; instead, they are implemented centrally in `drawing.c' and form a
1572small piece of middleware. The drawing API as supplied by the front end
1573is a structure containing a set of function pointers, plus a `void *'
1574handle which is passed to each of those functions. This enables a single
1575front end to switch between multiple implementations of the drawing API
1576if necessary. For example, the Windows API supplies a printing mechanism
1577integrated into the same GDI which deals with drawing in windows, and
1578therefore the same API implementation can handle both drawing and
1579printing; but on Unix, the most common way for applications to print
1580is by producing PostScript output directly, and although it would be
1581_possible_ to write a single (say) draw_rect() function which checked
1582a global flag to decide whether to do GTK drawing operations or output
1583PostScript to a file, it's much nicer to have two separate functions and
1584switch between them as appropriate.
1585
1586When drawing, the puzzle window is indexed by pixel coordinates, with
1587the top left pixel defined as (0,0) and the bottom right pixel (w-1,h-
15881), where `w' and `h' are the width and height values returned by the
1589back end function compute_size() (section 2.8.4).
1590
1591When printing, the puzzle's print area is indexed in exactly the same
1592way (with an arbitrary tile size provided by the printing module
1593`printing.c'), to facilitate sharing of code between the drawing and
1594printing routines. However, when printing, puzzles may no longer assume
1595that the coordinate unit has any relationship to a pixel; the printer's
1596actual resolution might very well not even be known at print time, so
1597the coordinate unit might be smaller or larger than a pixel. Puzzles'
1598print functions should restrict themselves to drawing geometric shapes
1599rather than fiddly pixel manipulation.
1600
1601_Puzzles' redraw functions may assume that the surface they draw on is
1602persistent_. It is the responsibility of every front end to preserve
1603the puzzle's window contents in the face of GUI window expose issues
1604and similar. It is not permissible to request that the back end redraw
1605any part of a window that it has already drawn, unless something has
1606actually changed as a result of making moves in the puzzle.
1607
1608Most front ends accomplish this by having the drawing routines draw on a
1609stored bitmap rather than directly on the window, and copying the bitmap
1610to the window every time a part of the window needs to be redrawn.
1611Therefore, it is vitally important that whenever the back end does any
1612drawing it informs the front end of which parts of the window it has
1613accessed, and hence which parts need repainting. This is done by calling
1614draw_update() (section 3.1.11).
1615
1616Persistence of old drawing is convenient. However, a puzzle should be
1617very careful about how it updates its drawing area. The problem is that
1618some front ends do anti-aliased drawing: rather than simply choosing
1619between leaving each pixel untouched or painting it a specified colour,
1620an antialiased drawing function will _blend_ the original and new
1621colours in pixels at a figure's boundary according to the proportion of
1622the pixel occupied by the figure (probably modified by some heuristic
1623fudge factors). All of this produces a smoother appearance for curves
1624and diagonal lines.
1625
1626An unfortunate effect of drawing an anti-aliased figure repeatedly
1627is that the pixels around the figure's boundary come steadily more
1628saturated with `ink' and the boundary appears to `spread out'. Worse,
1629redrawing a figure in a different colour won't fully paint over the old
1630boundary pixels, so the end result is a rather ugly smudge.
1631
1632A good strategy to avoid unpleasant anti-aliasing artifacts is to
1633identify a number of rectangular areas which need to be redrawn, clear
1634them to the background colour, and then redraw their contents from
1635scratch, being careful all the while not to stray beyond the boundaries
1636of the original rectangles. The clip() function (section 3.1.9) comes in
1637very handy here. Games based on a square grid can often do this fairly
1638easily. Other games may need to be somewhat more careful. For example,
1639Loopy's redraw function first identifies portions of the display which
1640need to be updated. Then, if the changes are fairly well localised, it
1641clears and redraws a rectangle containing each changed area. Otherwise,
1642it gives up and redraws the entire grid from scratch.
1643
1644It is possible to avoid clearing to background and redrawing from
1645scratch if one is very careful about which drawing functions one
1646uses: if a function is documented as not anti-aliasing under some
1647circumstances, you can rely on each pixel in a drawing either being left
1648entirely alone or being set to the requested colour, with no blending
1649being performed.
1650
1651In the following sections I first discuss the drawing API as seen by the
1652back end, and then the _almost_ identical function-pointer form seen by
1653the front end.
1654
1655#3.1. Drawing API as seen by the back end
1656
1657This section documents the back-end drawing API, in the form of
1658functions which take a `drawing' object as an argument.
1659
1660#3.1.1. draw_rect()
1661
1662 void draw_rect(drawing *dr, int x, int y, int w, int h,
1663 int colour);
1664
1665Draws a filled rectangle in the puzzle window.
1666
1667`x' and `y' give the coordinates of the top left pixel of the rectangle.
1668`w' and `h' give its width and height. Thus, the horizontal extent of
1669the rectangle runs from `x' to `x+w-1' inclusive, and the vertical
1670extent from `y' to `y+h-1' inclusive.
1671
1672`colour' is an integer index into the colours array returned by the back
1673end function colours() (section 2.8.6).
1674
1675There is no separate pixel-plotting function. If you want to plot a
1676single pixel, the approved method is to use draw_rect() with width and
1677height set to 1.
1678
1679Unlike many of the other drawing functions, this function is guaranteed
1680to be pixel-perfect: the rectangle will be sharply defined and not anti-
1681aliased or anything like that.
1682
1683This function may be used for both drawing and printing.
1684
1685#3.1.2. draw_rect_outline()
1686
1687 void draw_rect_outline(drawing *dr, int x, int y, int w, int h,
1688 int colour);
1689
1690Draws an outline rectangle in the puzzle window.
1691
1692`x' and `y' give the coordinates of the top left pixel of the rectangle.
1693`w' and `h' give its width and height. Thus, the horizontal extent of
1694the rectangle runs from `x' to `x+w-1' inclusive, and the vertical
1695extent from `y' to `y+h-1' inclusive.
1696
1697`colour' is an integer index into the colours array returned by the back
1698end function colours() (section 2.8.6).
1699
1700From a back end perspective, this function may be considered to be part
1701of the drawing API. However, front ends are not required to implement
1702it, since it is actually implemented centrally (in misc.c) as a wrapper
1703on draw_polygon().
1704
1705This function may be used for both drawing and printing.
1706
1707#3.1.3. draw_line()
1708
1709 void draw_line(drawing *dr, int x1, int y1, int x2, int y2,
1710 int colour);
1711
1712Draws a straight line in the puzzle window.
1713
1714`x1' and `y1' give the coordinates of one end of the line. `x2' and `y2'
1715give the coordinates of the other end. The line drawn includes both
1716those points.
1717
1718`colour' is an integer index into the colours array returned by the back
1719end function colours() (section 2.8.6).
1720
1721Some platforms may perform anti-aliasing on this function. Therefore,
1722do not assume that you can erase a line by drawing the same line over
1723it in the background colour; anti-aliasing might lead to perceptible
1724ghost artefacts around the vanished line. Horizontal and vertical lines,
1725however, are pixel-perfect and not anti-aliased.
1726
1727This function may be used for both drawing and printing.
1728
1729#3.1.4. draw_polygon()
1730
1731 void draw_polygon(drawing *dr, int *coords, int npoints,
1732 int fillcolour, int outlinecolour);
1733
1734Draws an outlined or filled polygon in the puzzle window.
1735
1736`coords' is an array of (2*npoints) integers, containing the `x' and `y'
1737coordinates of `npoints' vertices.
1738
1739`fillcolour' and `outlinecolour' are integer indices into the colours
1740array returned by the back end function colours() (section 2.8.6).
1741`fillcolour' may also be -1 to indicate that the polygon should be
1742outlined only.
1743
1744The polygon defined by the specified list of vertices is first filled in
1745`fillcolour', if specified, and then outlined in `outlinecolour'.
1746
1747`outlinecolour' may _not_ be -1; it must be a valid colour (and front
1748ends are permitted to enforce this by assertion). This is because
1749different platforms disagree on whether a filled polygon should include
1750its boundary line or not, so drawing _only_ a filled polygon would
1751have non-portable effects. If you want your filled polygon not to
1752have a visible outline, you must set `outlinecolour' to the same as
1753`fillcolour'.
1754
1755Some platforms may perform anti-aliasing on this function. Therefore, do
1756not assume that you can erase a polygon by drawing the same polygon over
1757it in the background colour. Also, be prepared for the polygon to extend
1758a pixel beyond its obvious bounding box as a result of this; if you
1759really need it not to do this to avoid interfering with other delicate
1760graphics, you should probably use clip() (section 3.1.9). You can rely
1761on horizontal and vertical lines not being anti-aliased.
1762
1763This function may be used for both drawing and printing.
1764
1765#3.1.5. draw_circle()
1766
1767 void draw_circle(drawing *dr, int cx, int cy, int radius,
1768 int fillcolour, int outlinecolour);
1769
1770Draws an outlined or filled circle in the puzzle window.
1771
1772`cx' and `cy' give the coordinates of the centre of the circle. `radius'
1773gives its radius. The total horizontal pixel extent of the circle is
1774from `cx-radius+1' to `cx+radius-1' inclusive, and the vertical extent
1775similarly around `cy'.
1776
1777`fillcolour' and `outlinecolour' are integer indices into the colours
1778array returned by the back end function colours() (section 2.8.6).
1779`fillcolour' may also be -1 to indicate that the circle should be
1780outlined only.
1781
1782The circle is first filled in `fillcolour', if specified, and then
1783outlined in `outlinecolour'.
1784
1785`outlinecolour' may _not_ be -1; it must be a valid colour (and front
1786ends are permitted to enforce this by assertion). This is because
1787different platforms disagree on whether a filled circle should include
1788its boundary line or not, so drawing _only_ a filled circle would
1789have non-portable effects. If you want your filled circle not to
1790have a visible outline, you must set `outlinecolour' to the same as
1791`fillcolour'.
1792
1793Some platforms may perform anti-aliasing on this function. Therefore, do
1794not assume that you can erase a circle by drawing the same circle over
1795it in the background colour. Also, be prepared for the circle to extend
1796a pixel beyond its obvious bounding box as a result of this; if you
1797really need it not to do this to avoid interfering with other delicate
1798graphics, you should probably use clip() (section 3.1.9).
1799
1800This function may be used for both drawing and printing.
1801
1802#3.1.6. draw_thick_line()
1803
1804 void draw_thick_line(drawing *dr, float thickness,
1805 float x1, float y1, float x2, float y2,
1806 int colour)
1807
1808Draws a line in the puzzle window, giving control over the line's
1809thickness.
1810
1811`x1' and `y1' give the coordinates of one end of the line. `x2' and `y2'
1812give the coordinates of the other end. `thickness' gives the thickness
1813of the line, in pixels.
1814
1815Note that the coordinates and thickness are floating-point: the
1816continuous coordinate system is in effect here. It's important to be
1817able to address points with better-than-pixel precision in this case,
1818because one can't otherwise properly express the endpoints of lines with
1819both odd and even thicknesses.
1820
1821Some platforms may perform anti-aliasing on this function. The precise
1822pixels affected by a thick-line drawing operation may vary between
1823platforms, and no particular guarantees are provided. Indeed, even
1824horizontal or vertical lines may be anti-aliased.
1825
1826This function may be used for both drawing and printing.
1827
1828If the specified thickness is less than 1.0, 1.0 is used. This ensures
1829that thin lines are visible even at small scales.
1830
1831#3.1.7. draw_text()
1832
1833 void draw_text(drawing *dr, int x, int y, int fonttype,
1834 int fontsize, int align, int colour,
1835 const char *text);
1836
1837Draws text in the puzzle window.
1838
1839`x' and `y' give the coordinates of a point. The relation of this point
1840to the location of the text is specified by `align', which is a bitwise
1841OR of horizontal and vertical alignment flags:
1842
1843ALIGN_VNORMAL
1844
1845 Indicates that `y' is aligned with the baseline of the text.
1846
1847ALIGN_VCENTRE
1848
1849 Indicates that `y' is aligned with the vertical centre of the
1850 text. (In fact, it's aligned with the vertical centre of normal
1851 _capitalised_ text: displaying two pieces of text with ALIGN_VCENTRE
1852 at the same y-coordinate will cause their baselines to be aligned
1853 with one another, even if one is an ascender and the other a
1854 descender.)
1855
1856ALIGN_HLEFT
1857
1858 Indicates that `x' is aligned with the left-hand end of the text.
1859
1860ALIGN_HCENTRE
1861
1862 Indicates that `x' is aligned with the horizontal centre of the
1863 text.
1864
1865ALIGN_HRIGHT
1866
1867 Indicates that `x' is aligned with the right-hand end of the text.
1868
1869`fonttype' is either FONT_FIXED or FONT_VARIABLE, for a monospaced
1870or proportional font respectively. (No more detail than that may be
1871specified; it would only lead to portability issues between different
1872platforms.)
1873
1874`fontsize' is the desired size, in pixels, of the text. This size
1875corresponds to the overall point size of the text, not to any internal
1876dimension such as the cap-height.
1877
1878`colour' is an integer index into the colours array returned by the back
1879end function colours() (section 2.8.6).
1880
1881This function may be used for both drawing and printing.
1882
1883The character set used to encode the text passed to this function is
1884specified _by the drawing object_, although it must be a superset of
1885ASCII. If a puzzle wants to display text that is not contained in ASCII,
1886it should use the text_fallback() function (section 3.1.8) to query the
1887drawing object for an appropriate representation of the characters it
1888wants.
1889
1890#3.1.8. text_fallback()
1891
1892 char *text_fallback(drawing *dr, const char *const *strings,
1893 int nstrings);
1894
1895This function is used to request a translation of UTF-8 text into
1896whatever character encoding is expected by the drawing object's
1897implementation of draw_text().
1898
1899The input is a list of strings encoded in UTF-8: nstrings gives the
1900number of strings in the list, and strings[0], strings[1], ...,
1901strings[nstrings-1] are the strings themselves.
1902
1903The returned string (which is dynamically allocated and must be freed
1904when finished with) is derived from the first string in the list that
1905the drawing object expects to be able to display reliably; it will
1906consist of that string translated into the character set expected by
1907draw_text().
1908
1909Drawing implementations are not required to handle anything outside
1910ASCII, but are permitted to assume that _some_ string will be
1911successfully translated. So every call to this function must include
1912a string somewhere in the list (presumably the last element) which
1913consists of nothing but ASCII, to be used by any front end which cannot
1914handle anything else.
1915
1916For example, if a puzzle wished to display a string including a
1917multiplication sign (U+00D7 in Unicode, represented by the bytes C3 97
1918in UTF-8), it might do something like this:
1919
1920 static const char *const times_signs[] = { "\xC3\x97", "x" };
1921 char *times_sign = text_fallback(dr, times_signs, 2);
1922 sprintf(buffer, "%d%s%d", width, times_sign, height);
1923 draw_text(dr, x, y, font, size, align, colour, buffer);
1924 sfree(buffer);
1925
1926which would draw a string with a times sign in the middle on platforms
1927that support it, and fall back to a simple ASCII `x' where there was no
1928alternative.
1929
1930#3.1.9. clip()
1931
1932 void clip(drawing *dr, int x, int y, int w, int h);
1933
1934Establishes a clipping rectangle in the puzzle window.
1935
1936`x' and `y' give the coordinates of the top left pixel of the clipping
1937rectangle. `w' and `h' give its width and height. Thus, the horizontal
1938extent of the rectangle runs from `x' to `x+w-1' inclusive, and the
1939vertical extent from `y' to `y+h-1' inclusive. (These are exactly the
1940same semantics as draw_rect().)
1941
1942After this call, no drawing operation will affect anything outside the
1943specified rectangle. The effect can be reversed by calling unclip()
1944(section 3.1.10). The clipping rectangle is pixel-perfect: pixels within
1945the rectangle are affected as usual by drawing functions; pixels outside
1946are completely untouched.
1947
1948Back ends should not assume that a clipping rectangle will be
1949automatically cleared up by the front end if it's left lying around;
1950that might work on current front ends, but shouldn't be relied upon.
1951Always explicitly call unclip().
1952
1953This function may be used for both drawing and printing.
1954
1955#3.1.10. unclip()
1956
1957 void unclip(drawing *dr);
1958
1959Reverts the effect of a previous call to clip(). After this call, all
1960drawing operations will be able to affect the entire puzzle window
1961again.
1962
1963This function may be used for both drawing and printing.
1964
1965#3.1.11. draw_update()
1966
1967 void draw_update(drawing *dr, int x, int y, int w, int h);
1968
1969Informs the front end that a rectangular portion of the puzzle window
1970has been drawn on and needs to be updated.
1971
1972`x' and `y' give the coordinates of the top left pixel of the update
1973rectangle. `w' and `h' give its width and height. Thus, the horizontal
1974extent of the rectangle runs from `x' to `x+w-1' inclusive, and the
1975vertical extent from `y' to `y+h-1' inclusive. (These are exactly the
1976same semantics as draw_rect().)
1977
1978The back end redraw function _must_ call this function to report any
1979changes it has made to the window. Otherwise, those changes may not
1980become immediately visible, and may then appear at an unpredictable
1981subsequent time such as the next time the window is covered and re-
1982exposed.
1983
1984This function is only important when drawing. It may be called when
1985printing as well, but doing so is not compulsory, and has no effect.
1986(So if you have a shared piece of code between the drawing and printing
1987routines, that code may safely call draw_update().)
1988
1989#3.1.12. status_bar()
1990
1991 void status_bar(drawing *dr, const char *text);
1992
1993Sets the text in the game's status bar to `text'. The text is copied
1994from the supplied buffer, so the caller is free to deallocate or modify
1995the buffer after use.
1996
1997(This function is not exactly a _drawing_ function, but it shares with
1998the drawing API the property that it may only be called from within the
1999back end redraw function, so this is as good a place as any to document
2000it.)
2001
2002The supplied text is filtered through the mid-end for optional rewriting
2003before being passed on to the front end; the mid-end will prepend the
2004current game time if the game is timed (and may in future perform other
2005rewriting if it seems like a good idea).
2006
2007This function is for drawing only; it must never be called during
2008printing.
2009
2010#3.1.13. Blitter functions
2011
2012This section describes a group of related functions which save and
2013restore a section of the puzzle window. This is most commonly used to
2014implement user interfaces involving dragging a puzzle element around the
2015window: at the end of each call to redraw(), if an object is currently
2016being dragged, the back end saves the window contents under that
2017location and then draws the dragged object, and at the start of the next
2018redraw() the first thing it does is to restore the background.
2019
2020The front end defines an opaque type called a `blitter', which is
2021capable of storing a rectangular area of a specified size.
2022
2023Blitter functions are for drawing only; they must never be called during
2024printing.
2025
2026#3.1.13.1. blitter_new()
2027
2028 blitter *blitter_new(drawing *dr, int w, int h);
2029
2030Creates a new blitter object which stores a rectangle of size `w' by `h'
2031pixels. Returns a pointer to the blitter object.
2032
2033Blitter objects are best stored in the `game_drawstate'. A good time to
2034create them is in the set_size() function (section 2.8.5), since it is
2035at this point that you first know how big a rectangle they will need to
2036save.
2037
2038#3.1.13.2. blitter_free()
2039
2040 void blitter_free(drawing *dr, blitter *bl);
2041
2042Disposes of a blitter object. Best called in free_drawstate(). (However,
2043check that the blitter object is not NULL before attempting to free it;
2044it is possible that a draw state might be created and freed without ever
2045having set_size() called on it in between.)
2046
2047#3.1.13.3. blitter_save()
2048
2049 void blitter_save(drawing *dr, blitter *bl, int x, int y);
2050
2051This is a true drawing API function, in that it may only be called from
2052within the game redraw routine. It saves a rectangular portion of the
2053puzzle window into the specified blitter object.
2054
2055`x' and `y' give the coordinates of the top left corner of the saved
2056rectangle. The rectangle's width and height are the ones specified when
2057the blitter object was created.
2058
2059This function is required to cope and do the right thing if `x' and `y'
2060are out of range. (The right thing probably means saving whatever part
2061of the blitter rectangle overlaps with the visible area of the puzzle
2062window.)
2063
2064#3.1.13.4. blitter_load()
2065
2066 void blitter_load(drawing *dr, blitter *bl, int x, int y);
2067
2068This is a true drawing API function, in that it may only be called from
2069within the game redraw routine. It restores a rectangular portion of the
2070puzzle window from the specified blitter object.
2071
2072`x' and `y' give the coordinates of the top left corner of the rectangle
2073to be restored. The rectangle's width and height are the ones specified
2074when the blitter object was created.
2075
2076Alternatively, you can specify both `x' and `y' as the special value
2077BLITTER_FROMSAVED, in which case the rectangle will be restored to
2078exactly where it was saved from. (This is probably what you want to do
2079almost all the time, if you're using blitters to implement draggable
2080puzzle elements.)
2081
2082This function is required to cope and do the right thing if `x' and
2083`y' (or the equivalent ones saved in the blitter) are out of range.
2084(The right thing probably means restoring whatever part of the blitter
2085rectangle overlaps with the visible area of the puzzle window.)
2086
2087If this function is called on a blitter which had previously been saved
2088from a partially out-of-range rectangle, then the parts of the saved
2089bitmap which were not visible at save time are undefined. If the blitter
2090is restored to a different position so as to make those parts visible,
2091the effect on the drawing area is undefined.
2092
2093#3.1.14. print_mono_colour()
2094
2095 int print_mono_colour(drawing *dr, int grey);
2096
2097This function allocates a colour index for a simple monochrome colour
2098during printing.
2099
2100`grey' must be 0 or 1. If `grey' is 0, the colour returned is black; if
2101`grey' is 1, the colour is white.
2102
2103#3.1.15. print_grey_colour()
2104
2105 int print_grey_colour(drawing *dr, float grey);
2106
2107This function allocates a colour index for a grey-scale colour during
2108printing.
2109
2110`grey' may be any number between 0 (black) and 1 (white); for example,
21110.5 indicates a medium grey.
2112
2113The chosen colour will be rendered to the limits of the printer's
2114halftoning capability.
2115
2116#3.1.16. print_hatched_colour()
2117
2118 int print_hatched_colour(drawing *dr, int hatch);
2119
2120This function allocates a colour index which does not represent a
2121literal _colour_. Instead, regions shaded in this colour will be hatched
2122with parallel lines. The `hatch' parameter defines what type of hatching
2123should be used in place of this colour:
2124
2125HATCH_SLASH
2126
2127 This colour will be hatched by lines slanting to the right at 45
2128 degrees.
2129
2130HATCH_BACKSLASH
2131
2132 This colour will be hatched by lines slanting to the left at 45
2133 degrees.
2134
2135HATCH_HORIZ
2136
2137 This colour will be hatched by horizontal lines.
2138
2139HATCH_VERT
2140
2141 This colour will be hatched by vertical lines.
2142
2143HATCH_PLUS
2144
2145 This colour will be hatched by criss-crossing horizontal and
2146 vertical lines.
2147
2148HATCH_X
2149
2150 This colour will be hatched by criss-crossing diagonal lines.
2151
2152Colours defined to use hatching may not be used for drawing lines or
2153text; they may only be used for filling areas. That is, they may be
2154used as the `fillcolour' parameter to draw_circle() and draw_polygon(),
2155and as the colour parameter to draw_rect(), but may not be used as the
2156`outlinecolour' parameter to draw_circle() or draw_polygon(), or with
2157draw_line() or draw_text().
2158
2159#3.1.17. print_rgb_mono_colour()
2160
2161 int print_rgb_mono_colour(drawing *dr, float r, float g,
2162 float b, float grey);
2163
2164This function allocates a colour index for a fully specified RGB colour
2165during printing.
2166
2167`r', `g' and `b' may each be anywhere in the range from 0 to 1.
2168
2169If printing in black and white only, these values will be ignored, and
2170either pure black or pure white will be used instead, according to the
2171`grey' parameter. (The fallback colour is the same as the one which
2172would be allocated by print_mono_colour(grey).)
2173
2174#3.1.18. print_rgb_grey_colour()
2175
2176 int print_rgb_grey_colour(drawing *dr, float r, float g,
2177 float b, float grey);
2178
2179This function allocates a colour index for a fully specified RGB colour
2180during printing.
2181
2182`r', `g' and `b' may each be anywhere in the range from 0 to 1.
2183
2184If printing in black and white only, these values will be ignored, and
2185a shade of grey given by the `grey' parameter will be used instead.
2186(The fallback colour is the same as the one which would be allocated by
2187print_grey_colour(grey).)
2188
2189#3.1.19. print_rgb_hatched_colour()
2190
2191 int print_rgb_hatched_colour(drawing *dr, float r, float g,
2192 float b, float hatched);
2193
2194This function allocates a colour index for a fully specified RGB colour
2195during printing.
2196
2197`r', `g' and `b' may each be anywhere in the range from 0 to 1.
2198
2199If printing in black and white only, these values will be ignored, and
2200a form of cross-hatching given by the `hatch' parameter will be used
2201instead; see section 3.1.16 for the possible values of this parameter.
2202(The fallback colour is the same as the one which would be allocated by
2203print_hatched_colour(hatch).)
2204
2205#3.1.20. print_line_width()
2206
2207 void print_line_width(drawing *dr, int width);
2208
2209This function is called to set the thickness of lines drawn during
2210printing. It is meaningless in drawing: all lines drawn by draw_line(),
2211draw_circle and draw_polygon() are one pixel in thickness. However, in
2212printing there is no clear definition of a pixel and so line widths must
2213be explicitly specified.
2214
2215The line width is specified in the usual coordinate system. Note,
2216however, that it is a hint only: the central printing system may choose
2217to vary line thicknesses at user request or due to printer capabilities.
2218
2219#3.1.21. print_line_dotted()
2220
2221 void print_line_dotted(drawing *dr, int dotted);
2222
2223This function is called to toggle the drawing of dotted lines during
2224printing. It is not supported during drawing.
2225
2226The parameter `dotted' is a boolean; TRUE means that future lines drawn
2227by draw_line(), draw_circle and draw_polygon() will be dotted, and FALSE
2228means that they will be solid.
2229
2230Some front ends may impose restrictions on the width of dotted lines.
2231Asking for a dotted line via this front end will override any line width
2232request if the front end requires it.
2233
2234#3.2. The drawing API as implemented by the front end
2235
2236This section describes the drawing API in the function-pointer form in
2237which it is implemented by a front end.
2238
2239(It isn't only platform-specific front ends which implement this API;
2240the platform-independent module `ps.c' also provides an implementation
2241of it which outputs PostScript. Thus, any platform which wants to do PS
2242printing can do so with minimum fuss.)
2243
2244The following entries all describe function pointer fields in a
2245structure called `drawing_api'. Each of the functions takes a `void *'
2246context pointer, which it should internally cast back to a more useful
2247type. Thus, a drawing _object_ (`drawing *)' suitable for passing to
2248the back end redraw or printing functions is constructed by passing a
2249`drawing_api' and a `void *' to the function drawing_new() (see section
22503.3.1).
2251
2252#3.2.1. draw_text()
2253
2254 void (*draw_text)(void *handle, int x, int y, int fonttype,
2255 int fontsize, int align, int colour,
2256 const char *text);
2257
2258This function behaves exactly like the back end draw_text() function;
2259see section 3.1.7.
2260
2261#3.2.2. draw_rect()
2262
2263 void (*draw_rect)(void *handle, int x, int y, int w, int h,
2264 int colour);
2265
2266This function behaves exactly like the back end draw_rect() function;
2267see section 3.1.1.
2268
2269#3.2.3. draw_line()
2270
2271 void (*draw_line)(void *handle, int x1, int y1, int x2, int y2,
2272 int colour);
2273
2274This function behaves exactly like the back end draw_line() function;
2275see section 3.1.3.
2276
2277#3.2.4. draw_polygon()
2278
2279 void (*draw_polygon)(void *handle, int *coords, int npoints,
2280 int fillcolour, int outlinecolour);
2281
2282This function behaves exactly like the back end draw_polygon() function;
2283see section 3.1.4.
2284
2285#3.2.5. draw_circle()
2286
2287 void (*draw_circle)(void *handle, int cx, int cy, int radius,
2288 int fillcolour, int outlinecolour);
2289
2290This function behaves exactly like the back end draw_circle() function;
2291see section 3.1.5.
2292
2293#3.2.6. draw_thick_line()
2294
2295 void draw_thick_line(drawing *dr, float thickness,
2296 float x1, float y1, float x2, float y2,
2297 int colour)
2298
2299This function behaves exactly like the back end draw_thick_line()
2300function; see section 3.1.6.
2301
2302An implementation of this API which doesn't provide high-quality
2303rendering of thick lines is permitted to define this function pointer
2304to be NULL. The middleware in drawing.c will notice and provide a low-
2305quality alternative using draw_polygon().
2306
2307#3.2.7. draw_update()
2308
2309 void (*draw_update)(void *handle, int x, int y, int w, int h);
2310
2311This function behaves exactly like the back end draw_update() function;
2312see section 3.1.11.
2313
2314An implementation of this API which only supports printing is permitted
2315to define this function pointer to be NULL rather than bothering to
2316define an empty function. The middleware in drawing.c will notice and
2317avoid calling it.
2318
2319#3.2.8. clip()
2320
2321 void (*clip)(void *handle, int x, int y, int w, int h);
2322
2323This function behaves exactly like the back end clip() function; see
2324section 3.1.9.
2325
2326#3.2.9. unclip()
2327
2328 void (*unclip)(void *handle);
2329
2330This function behaves exactly like the back end unclip() function; see
2331section 3.1.10.
2332
2333#3.2.10. start_draw()
2334
2335 void (*start_draw)(void *handle);
2336
2337This function is called at the start of drawing. It allows the front end
2338to initialise any temporary data required to draw with, such as device
2339contexts.
2340
2341Implementations of this API which do not provide drawing services may
2342define this function pointer to be NULL; it will never be called unless
2343drawing is attempted.
2344
2345#3.2.11. end_draw()
2346
2347 void (*end_draw)(void *handle);
2348
2349This function is called at the end of drawing. It allows the front end
2350to do cleanup tasks such as deallocating device contexts and scheduling
2351appropriate GUI redraw events.
2352
2353Implementations of this API which do not provide drawing services may
2354define this function pointer to be NULL; it will never be called unless
2355drawing is attempted.
2356
2357#3.2.12. status_bar()
2358
2359 void (*status_bar)(void *handle, const char *text);
2360
2361This function behaves exactly like the back end status_bar() function;
2362see section 3.1.12.
2363
2364Front ends implementing this function need not worry about it
2365being called repeatedly with the same text; the middleware code in
2366status_bar() will take care of this.
2367
2368Implementations of this API which do not provide drawing services may
2369define this function pointer to be NULL; it will never be called unless
2370drawing is attempted.
2371
2372#3.2.13. blitter_new()
2373
2374 blitter *(*blitter_new)(void *handle, int w, int h);
2375
2376This function behaves exactly like the back end blitter_new() function;
2377see section 3.1.13.1.
2378
2379Implementations of this API which do not provide drawing services may
2380define this function pointer to be NULL; it will never be called unless
2381drawing is attempted.
2382
2383#3.2.14. blitter_free()
2384
2385 void (*blitter_free)(void *handle, blitter *bl);
2386
2387This function behaves exactly like the back end blitter_free() function;
2388see section 3.1.13.2.
2389
2390Implementations of this API which do not provide drawing services may
2391define this function pointer to be NULL; it will never be called unless
2392drawing is attempted.
2393
2394#3.2.15. blitter_save()
2395
2396 void (*blitter_save)(void *handle, blitter *bl, int x, int y);
2397
2398This function behaves exactly like the back end blitter_save() function;
2399see section 3.1.13.3.
2400
2401Implementations of this API which do not provide drawing services may
2402define this function pointer to be NULL; it will never be called unless
2403drawing is attempted.
2404
2405#3.2.16. blitter_load()
2406
2407 void (*blitter_load)(void *handle, blitter *bl, int x, int y);
2408
2409This function behaves exactly like the back end blitter_load() function;
2410see section 3.1.13.4.
2411
2412Implementations of this API which do not provide drawing services may
2413define this function pointer to be NULL; it will never be called unless
2414drawing is attempted.
2415
2416#3.2.17. begin_doc()
2417
2418 void (*begin_doc)(void *handle, int pages);
2419
2420This function is called at the beginning of a printing run. It gives the
2421front end an opportunity to initialise any required printing subsystem.
2422It also provides the number of pages in advance.
2423
2424Implementations of this API which do not provide printing services may
2425define this function pointer to be NULL; it will never be called unless
2426printing is attempted.
2427
2428#3.2.18. begin_page()
2429
2430 void (*begin_page)(void *handle, int number);
2431
2432This function is called during printing, at the beginning of each page.
2433It gives the page number (numbered from 1 rather than 0, so suitable for
2434use in user-visible contexts).
2435
2436Implementations of this API which do not provide printing services may
2437define this function pointer to be NULL; it will never be called unless
2438printing is attempted.
2439
2440#3.2.19. begin_puzzle()
2441
2442 void (*begin_puzzle)(void *handle, float xm, float xc,
2443 float ym, float yc, int pw, int ph, float wmm);
2444
2445This function is called during printing, just before printing a single
2446puzzle on a page. It specifies the size and location of the puzzle on
2447the page.
2448
2449`xm' and `xc' specify the horizontal position of the puzzle on the page,
2450as a linear function of the page width. The front end is expected to
2451multiply the page width by `xm', add `xc' (measured in millimetres), and
2452use the resulting x-coordinate as the left edge of the puzzle.
2453
2454Similarly, `ym' and `yc' specify the vertical position of the puzzle as
2455a function of the page height: the page height times `ym', plus `yc'
2456millimetres, equals the desired distance from the top of the page to the
2457top of the puzzle.
2458
2459(This unwieldy mechanism is required because not all printing systems
2460can communicate the page size back to the software. The PostScript back
2461end, for example, writes out PS which determines the page size at print
2462time by means of calling `clippath', and centres the puzzles within
2463that. Thus, exactly the same PS file works on A4 or on US Letter paper
2464without needing local configuration, which simplifies matters.)
2465
2466pw and ph give the size of the puzzle in drawing API coordinates. The
2467printing system will subsequently call the puzzle's own print function,
2468which will in turn call drawing API functions in the expectation that an
2469area pw by ph units is available to draw the puzzle on.
2470
2471Finally, wmm gives the desired width of the puzzle in millimetres. (The
2472aspect ratio is expected to be preserved, so if the desired puzzle
2473height is also needed then it can be computed as wmm*ph/pw.)
2474
2475Implementations of this API which do not provide printing services may
2476define this function pointer to be NULL; it will never be called unless
2477printing is attempted.
2478
2479#3.2.20. end_puzzle()
2480
2481 void (*end_puzzle)(void *handle);
2482
2483This function is called after the printing of a specific puzzle is
2484complete.
2485
2486Implementations of this API which do not provide printing services may
2487define this function pointer to be NULL; it will never be called unless
2488printing is attempted.
2489
2490#3.2.21. end_page()
2491
2492 void (*end_page)(void *handle, int number);
2493
2494This function is called after the printing of a page is finished.
2495
2496Implementations of this API which do not provide printing services may
2497define this function pointer to be NULL; it will never be called unless
2498printing is attempted.
2499
2500#3.2.22. end_doc()
2501
2502 void (*end_doc)(void *handle);
2503
2504This function is called after the printing of the entire document is
2505finished. This is the moment to close files, send things to the print
2506spooler, or whatever the local convention is.
2507
2508Implementations of this API which do not provide printing services may
2509define this function pointer to be NULL; it will never be called unless
2510printing is attempted.
2511
2512#3.2.23. line_width()
2513
2514 void (*line_width)(void *handle, float width);
2515
2516This function is called to set the line thickness, during printing only.
2517Note that the width is a float here, where it was an int as seen by the
2518back end. This is because drawing.c may have scaled it on the way past.
2519
2520However, the width is still specified in the same coordinate system as
2521the rest of the drawing.
2522
2523Implementations of this API which do not provide printing services may
2524define this function pointer to be NULL; it will never be called unless
2525printing is attempted.
2526
2527#3.2.24. text_fallback()
2528
2529 char *(*text_fallback)(void *handle, const char *const *strings,
2530 int nstrings);
2531
2532This function behaves exactly like the back end text_fallback()
2533function; see section 3.1.8.
2534
2535Implementations of this API which do not support any characters outside
2536ASCII may define this function pointer to be NULL, in which case the
2537central code in drawing.c will provide a default implementation.
2538
2539#3.3. The drawing API as called by the front end
2540
2541There are a small number of functions provided in drawing.c which the
2542front end needs to _call_, rather than helping to implement. They are
2543described in this section.
2544
2545#3.3.1. drawing_new()
2546
2547 drawing *drawing_new(const drawing_api *api, midend *me,
2548 void *handle);
2549
2550This function creates a drawing object. It is passed a `drawing_api',
2551which is a structure containing nothing but function pointers; and also
2552a `void *' handle. The handle is passed back to each function pointer
2553when it is called.
2554
2555The `midend' parameter is used for rewriting the status bar contents:
2556status_bar() (see section 3.1.12) has to call a function in the mid-
2557end which might rewrite the status bar text. If the drawing object
2558is to be used only for printing, or if the game is known not to call
2559status_bar(), this parameter may be NULL.
2560
2561#3.3.2. drawing_free()
2562
2563 void drawing_free(drawing *dr);
2564
2565This function frees a drawing object. Note that the `void *' handle is
2566not freed; if that needs cleaning up it must be done by the front end.
2567
2568#3.3.3. print_get_colour()
2569
2570 void print_get_colour(drawing *dr, int colour, int printincolour,
2571 int *hatch, float *r, float *g, float *b)
2572
2573This function is called by the implementations of the drawing API
2574functions when they are called in a printing context. It takes a colour
2575index as input, and returns the description of the colour as requested
2576by the back end.
2577
2578`printincolour' is TRUE iff the implementation is printing in colour.
2579This will alter the results returned if the colour in question was
2580specified with a black-and-white fallback value.
2581
2582If the colour should be rendered by hatching, `*hatch' is filled with
2583the type of hatching desired. See section 3.1.15 for details of the
2584values this integer can take.
2585
2586If the colour should be rendered as solid colour, `*hatch' is given a
2587negative value, and `*r', `*g' and `*b' are filled with the RGB values
2588of the desired colour (if printing in colour), or all filled with the
2589grey-scale value (if printing in black and white).
2590
2591#4. The API provided by the mid-end
2592
2593This chapter documents the API provided by the mid-end to be called by
2594the front end. You probably only need to read this if you are a front
2595end implementor, i.e. you are porting Puzzles to a new platform. If
2596you're only interested in writing new puzzles, you can safely skip this
2597chapter.
2598
2599All the persistent state in the mid-end is encapsulated within a
2600`midend' structure, to facilitate having multiple mid-ends in any
2601port which supports multiple puzzle windows open simultaneously. Each
2602`midend' is intended to handle the contents of a single puzzle window.
2603
2604#4.1. midend_new()
2605
2606 midend *midend_new(frontend *fe, const game *ourgame,
2607 const drawing_api *drapi, void *drhandle)
2608
2609Allocates and returns a new mid-end structure.
2610
2611The `fe' argument is stored in the mid-end. It will be used when calling
2612back to functions such as activate_timer() (section 4.36), and will be
2613passed on to the back end function colours() (section 2.8.6).
2614
2615The parameters `drapi' and `drhandle' are passed to drawing_new()
2616(section 3.3.1) to construct a drawing object which will be passed to
2617the back end function redraw() (section 2.8.10). Hence, all drawing-
2618related function pointers defined in `drapi' can expect to be called
2619with `drhandle' as their first argument.
2620
2621The `ourgame' argument points to a container structure describing a game
2622back end. The mid-end thus created will only be capable of handling that
2623one game. (So even in a monolithic front end containing all the games,
2624this imposes the constraint that any individual puzzle window is tied to
2625a single game. Unless, of course, you feel brave enough to change the
2626mid-end for the window without closing the window...)
2627
2628#4.2. midend_free()
2629
2630 void midend_free(midend *me);
2631
2632Frees a mid-end structure and all its associated data.
2633
2634#4.3. midend_tilesize()
2635
2636 int midend_tilesize(midend *me);
2637
2638Returns the `tilesize' parameter being used to display the current
2639puzzle (section 2.8.3).
2640
2641#4.4. midend_set_params()
2642
2643 void midend_set_params(midend *me, game_params *params);
2644
2645Sets the current game parameters for a mid-end. Subsequent games
2646generated by midend_new_game() (section 4.8) will use these parameters
2647until further notice.
2648
2649The usual way in which the front end will have an actual `game_params'
2650structure to pass to this function is if it had previously got it from
2651midend_get_presets() (section 4.15). Thus, this function is usually
2652called in response to the user making a selection from the presets menu.
2653
2654#4.5. midend_get_params()
2655
2656 game_params *midend_get_params(midend *me);
2657
2658Returns the current game parameters stored in this mid-end.
2659
2660The returned value is dynamically allocated, and should be freed when
2661finished with by passing it to the game's own free_params() function
2662(see section 2.3.6).
2663
2664#4.6. midend_size()
2665
2666 void midend_size(midend *me, int *x, int *y, int user_size);
2667
2668Tells the mid-end to figure out its window size.
2669
2670On input, `*x' and `*y' should contain the maximum or requested size
2671for the window. (Typically this will be the size of the screen that the
2672window has to fit on, or similar.) The mid-end will repeatedly call the
2673back end function compute_size() (section 2.8.4), searching for a tile
2674size that best satisfies the requirements. On exit, `*x' and `*y' will
2675contain the size needed for the puzzle window's drawing area. (It is
2676of course up to the front end to adjust this for any additional window
2677furniture such as menu bars and window borders, if necessary. The status
2678bar is also not included in this size.)
2679
2680Use `user_size' to indicate whether `*x' and `*y' are a requested size,
2681or just a maximum size.
2682
2683If `user_size' is set to TRUE, the mid-end will treat the input size as
2684a request, and will pick a tile size which approximates it _as closely
2685as possible_, going over the game's preferred tile size if necessary to
2686achieve this. The mid-end will also use the resulting tile size as its
2687preferred one until further notice, on the assumption that this size was
2688explicitly requested by the user. Use this option if you want your front
2689end to support dynamic resizing of the puzzle window with automatic
2690scaling of the puzzle to fit.
2691
2692If `user_size' is set to FALSE, then the game's tile size will never go
2693over its preferred one, although it may go under in order to fit within
2694the maximum bounds specified by `*x' and `*y'. This is the recommended
2695approach when opening a new window at default size: the game will use
2696its preferred size unless it has to use a smaller one to fit on the
2697screen. If the tile size is shrunk for this reason, the change will not
2698persist; if a smaller grid is subsequently chosen, the tile size will
2699recover.
2700
2701The mid-end will try as hard as it can to return a size which is
2702less than or equal to the input size, in both dimensions. In extreme
2703circumstances it may fail (if even the lowest possible tile size gives
2704window dimensions greater than the input), in which case it will return
2705a size greater than the input size. Front ends should be prepared
2706for this to happen (i.e. don't crash or fail an assertion), but may
2707handle it in any way they see fit: by rejecting the game parameters
2708which caused the problem, by opening a window larger than the screen
2709regardless of inconvenience, by introducing scroll bars on the window,
2710by drawing on a large bitmap and scaling it into a smaller window, or by
2711any other means you can think of. It is likely that when the tile size
2712is that small the game will be unplayable anyway, so don't put _too_
2713much effort into handling it creatively.
2714
2715If your platform has no limit on window size (or if you're planning to
2716use scroll bars for large puzzles), you can pass dimensions of INT_MAX
2717as input to this function. You should probably not do that _and_ set the
2718`user_size' flag, though!
2719
2720The midend relies on the frontend calling midend_new_game() (section
27214.8) before calling midend_size().
2722
2723#4.7. midend_reset_tilesize()
2724
2725 void midend_reset_tilesize(midend *me);
2726
2727This function resets the midend's preferred tile size to that of the
2728standard puzzle.
2729
2730As discussed in section 4.6, puzzle resizes are typically 'sticky',
2731in that once the user has dragged the puzzle to a different window
2732size, the resulting tile size will be remembered and used when the
2733puzzle configuration changes. If you _don't_ want that, e.g. if you
2734want to provide a command to explicitly reset the puzzle size back to
2735its default, then you can call this just before calling midend_size()
2736(which, in turn, you would probably call with `user_size' set to FALSE).
2737
2738#4.8. midend_new_game()
2739
2740 void midend_new_game(midend *me);
2741
2742Causes the mid-end to begin a new game. Normally the game will be a
2743new randomly generated puzzle. However, if you have previously called
2744midend_game_id() or midend_set_config(), the game generated might be
2745dictated by the results of those functions. (In particular, you _must_
2746call midend_new_game() after calling either of those functions, or else
2747no immediate effect will be visible.)
2748
2749You will probably need to call midend_size() after calling this
2750function, because if the game parameters have been changed since the
2751last new game then the window size might need to change. (If you know
2752the parameters _haven't_ changed, you don't need to do this.)
2753
2754This function will create a new `game_drawstate', but does not actually
2755perform a redraw (since you often need to call midend_size() before
2756the redraw can be done). So after calling this function and after
2757calling midend_size(), you should then call midend_redraw(). (It is not
2758necessary to call midend_force_redraw(); that will discard the draw
2759state and create a fresh one, which is unnecessary in this case since
2760there's a fresh one already. It would work, but it's usually excessive.)
2761
2762#4.9. midend_restart_game()
2763
2764 void midend_restart_game(midend *me);
2765
2766This function causes the current game to be restarted. This is done by
2767placing a new copy of the original game state on the end of the undo
2768list (so that an accidental restart can be undone).
2769
2770This function automatically causes a redraw, i.e. the front end can
2771expect its drawing API to be called from _within_ a call to this
2772function. Some back ends require that midend_size() (section 4.6) is
2773called before midend_restart_game().
2774
2775#4.10. midend_force_redraw()
2776
2777 void midend_force_redraw(midend *me);
2778
2779Forces a complete redraw of the puzzle window, by means of discarding
2780the current `game_drawstate' and creating a new one from scratch before
2781calling the game's redraw() function.
2782
2783The front end can expect its drawing API to be called from within a call
2784to this function. Some back ends require that midend_size() (section
27854.6) is called before midend_force_redraw().
2786
2787#4.11. midend_redraw()
2788
2789 void midend_redraw(midend *me);
2790
2791Causes a partial redraw of the puzzle window, by means of simply calling
2792the game's redraw() function. (That is, the only things redrawn will be
2793things that have changed since the last redraw.)
2794
2795The front end can expect its drawing API to be called from within a call
2796to this function. Some back ends require that midend_size() (section
27974.6) is called before midend_redraw().
2798
2799#4.12. midend_process_key()
2800
2801 int midend_process_key(midend *me, int x, int y, int button);
2802
2803The front end calls this function to report a mouse or keyboard event.
2804The parameters `x', `y' and `button' are almost identical to the ones
2805passed to the back end function interpret_move() (section 2.7.1), except
2806that the front end is _not_ required to provide the guarantees about
2807mouse event ordering. The mid-end will sort out multiple simultaneous
2808button presses and changes of button; the front end's responsibility
2809is simply to pass on the mouse events it receives as accurately as
2810possible.
2811
2812(Some platforms may need to emulate absent mouse buttons by means of
2813using a modifier key such as Shift with another mouse button. This tends
2814to mean that if Shift is pressed or released in the middle of a mouse
2815drag, the mid-end will suddenly stop receiving, say, LEFT_DRAG events
2816and start receiving RIGHT_DRAGs, with no intervening button release or
2817press events. This too is something which the mid-end will sort out for
2818you; the front end has no obligation to maintain sanity in this area.)
2819
2820The front end _should_, however, always eventually send some kind of
2821button release. On some platforms this requires special effort: Windows,
2822for example, requires a call to the system API function SetCapture() in
2823order to ensure that your window receives a mouse-up event even if the
2824pointer has left the window by the time the mouse button is released.
2825On any platform that requires this sort of thing, the front end _is_
2826responsible for doing it.
2827
2828Calling this function is very likely to result in calls back to the
2829front end's drawing API and/or activate_timer() (section 4.36).
2830
2831The return value from midend_process_key() is non-zero, unless the
2832effect of the keypress was to request termination of the program. A
2833front end should shut down the puzzle in response to a zero return.
2834
2835#4.13. midend_colours()
2836
2837 float *midend_colours(midend *me, int *ncolours);
2838
2839Returns an array of the colours required by the game, in exactly
2840the same format as that returned by the back end function colours()
2841(section 2.8.6). Front ends should call this function rather than
2842calling the back end's version directly, since the mid-end adds standard
2843customisation facilities. (At the time of writing, those customisation
2844facilities are implemented hackily by means of environment variables,
2845but it's not impossible that they may become more full and formal in
2846future.)
2847
2848#4.14. midend_timer()
2849
2850 void midend_timer(midend *me, float tplus);
2851
2852If the mid-end has called activate_timer() (section 4.36) to request
2853regular callbacks for purposes of animation or timing, this is the
2854function the front end should call on a regular basis. The argument
2855`tplus' gives the time, in seconds, since the last time either this
2856function was called or activate_timer() was invoked.
2857
2858One of the major purposes of timing in the mid-end is to perform move
2859animation. Therefore, calling this function is very likely to result in
2860calls back to the front end's drawing API.
2861
2862#4.15. midend_get_presets()
2863
2864 struct preset_menu *midend_get_presets(midend *me, int *id_limit);
2865
2866Returns a data structure describing this game's collection of preset
2867game parameters, organised into a hierarchical structure of menus and
2868submenus.
2869
2870The return value is a pointer to a data structure containing the
2871following fields (among others, which are not intended for front end
2872use):
2873
2874 struct preset_menu {
2875 int n_entries;
2876 struct preset_menu_entry *entries;
2877 /* and other things */
2878 };
2879
2880Those fields describe the intended contents of one particular menu in
2881the hierarchy. `entries' points to an array of `n_entries' items, each
2882of which is a structure containing the following fields:
2883
2884 struct preset_menu_entry {
2885 char *title;
2886 game_params *params;
2887 struct preset_menu *submenu;
2888 int id;
2889 };
2890
2891Of these fields, `title' and `id' are present in every entry, giving
2892(respectively) the textual name of the menu item and an integer
2893identifier for it. The integer id will correspond to the one returned
2894by `midend_which_preset' (section 4.16), when that preset is the one
2895selected.
2896
2897The other two fields are mutually exclusive. Each
2898`struct preset_menu_entry' will have one of those fields NULL and the
2899other one non-null. If the menu item is an actual preset, then `params'
2900will point to the set of game parameters that go with the name; if it's
2901a submenu, then `submenu' instead will be non-null, and will point at a
2902subsidiary `struct preset_menu'.
2903
2904The complete hierarchy of these structures is owned by the mid-end,
2905and will be freed when the mid-end is freed. The front end should not
2906attempt to free any of it.
2907
2908The integer identifiers will be allocated densely from 0 upwards, so
2909that it's reasonable for the front end to allocate an array which uses
2910them as indices, if it needs to store information per preset menu item.
2911For this purpose, the front end may pass the second parameter `id_limit'
2912to midend_get_presets as the address of an `int' variable, into which
2913midend_get_presets will write an integer one larger than the largest id
2914number actually used (i.e. the number of elements the front end would
2915need in the array).
2916
2917Submenu-type entries also have integer identifiers.
2918
2919#4.16. midend_which_preset()
2920
2921 int midend_which_preset(midend *me);
2922
2923Returns the numeric index of the preset game parameter structure which
2924matches the current game parameters, or a negative number if no preset
2925matches. Front ends could use this to maintain a tick beside one of the
2926items in the menu (or tick the `Custom' option if the return value is
2927less than zero).
2928
2929The returned index value (if non-negative) will match the `id'
2930field of the corresponding struct preset_menu_entry returned by
2931`midend_get_presets()' (section 4.15).
2932
2933#4.17. midend_wants_statusbar()
2934
2935 int midend_wants_statusbar(midend *me);
2936
2937This function returns TRUE if the puzzle has a use for a textual status
2938line (to display score, completion status, currently active tiles, time,
2939or anything else).
2940
2941Front ends should call this function rather than talking directly to the
2942back end.
2943
2944#4.18. midend_get_config()
2945
2946 config_item *midend_get_config(midend *me, int which,
2947 char **wintitle);
2948
2949Returns a dialog box description for user configuration.
2950
2951On input, which should be set to one of three values, which select which
2952of the various dialog box descriptions is returned:
2953
2954CFG_SETTINGS
2955
2956 Requests the GUI parameter configuration box generated by the puzzle
2957 itself. This should be used when the user selects `Custom' from the
2958 game types menu (or equivalent). The mid-end passes this request on
2959 to the back end function configure() (section 2.3.9).
2960
2961CFG_DESC
2962
2963 Requests a box suitable for entering a descriptive game ID (and
2964 viewing the existing one). The mid-end generates this dialog box
2965 description itself. This should be used when the user selects
2966 `Specific' from the game menu (or equivalent).
2967
2968CFG_SEED
2969
2970 Requests a box suitable for entering a random-seed game ID (and
2971 viewing the existing one). The mid-end generates this dialog box
2972 description itself. This should be used when the user selects
2973 `Random Seed' from the game menu (or equivalent).
2974
2975The returned value is an array of config_items, exactly as described
2976in section 2.3.9. Another returned value is an ASCII string giving a
2977suitable title for the configuration window, in `*wintitle'.
2978
2979Both returned values are dynamically allocated and will need to be
2980freed. The window title can be freed in the obvious way; the config_item
2981array is a slightly complex structure, so a utility function free_cfg()
2982is provided to free it for you. See section 5.3.6.
2983
2984(Of course, you will probably not want to free the config_item array
2985until the dialog box is dismissed, because before then you will probably
2986need to pass it to midend_set_config.)
2987
2988#4.19. midend_set_config()
2989
2990 const char *midend_set_config(midend *me, int which,
2991 config_item *cfg);
2992
2993Passes the mid-end the results of a configuration dialog box. `which'
2994should have the same value which it had when midend_get_config() was
2995called; `cfg' should be the array of `config_item's returned from
2996midend_get_config(), modified to contain the results of the user's
2997editing operations.
2998
2999This function returns NULL on success, or otherwise (if the
3000configuration data was in some way invalid) an ASCII string containing
3001an error message suitable for showing to the user.
3002
3003If the function succeeds, it is likely that the game parameters will
3004have been changed and it is certain that a new game will be requested.
3005The front end should therefore call midend_new_game(), and probably also
3006re-think the window size using midend_size() and eventually perform a
3007refresh using midend_redraw().
3008
3009#4.20. midend_game_id()
3010
3011 const char *midend_game_id(midend *me, const char *id);
3012
3013Passes the mid-end a string game ID (of any of the valid forms `params',
3014`params:description' or `params#seed') which the mid-end will process
3015and use for the next generated game.
3016
3017This function returns NULL on success, or otherwise (if the
3018configuration data was in some way invalid) an ASCII string containing
3019an error message (not dynamically allocated) suitable for showing to the
3020user. In the event of an error, the mid-end's internal state will be
3021left exactly as it was before the call.
3022
3023If the function succeeds, it is likely that the game parameters will
3024have been changed and it is certain that a new game will be requested.
3025The front end should therefore call midend_new_game(), and probably
3026also re-think the window size using midend_size() and eventually case a
3027refresh using midend_redraw().
3028
3029#4.21. midend_get_game_id()
3030
3031 char *midend_get_game_id(midend *me)
3032
3033Returns a descriptive game ID (i.e. one in the form
3034`params:description') describing the game currently active in the mid-
3035end. The returned string is dynamically allocated.
3036
3037#4.22. midend_get_random_seed()
3038
3039 char *midend_get_random_seed(midend *me)
3040
3041Returns a random game ID (i.e. one in the form `params#seedstring')
3042describing the game currently active in the mid-end, if there is one.
3043If the game was created by entering a description, no random seed will
3044currently exist and this function will return NULL.
3045
3046The returned string, if it is non-NULL, is dynamically allocated.
3047
3048#4.23. midend_can_format_as_text_now()
3049
3050 int midend_can_format_as_text_now(midend *me);
3051
3052Returns TRUE if the game code is capable of formatting puzzles of the
3053currently selected game type as ASCII.
3054
3055If this returns FALSE, then midend_text_format() (section 4.24) will
3056return NULL.
3057
3058#4.24. midend_text_format()
3059
3060 char *midend_text_format(midend *me);
3061
3062Formats the current game's current state as ASCII text suitable for
3063copying to the clipboard. The returned string is dynamically allocated.
3064
3065If the game's `can_format_as_text_ever' flag is FALSE, or if its
3066can_format_as_text_now() function returns FALSE, then this function will
3067return NULL.
3068
3069If the returned string contains multiple lines (which is likely), it
3070will use the normal C line ending convention (\n only). On platforms
3071which use a different line ending convention for data in the clipboard,
3072it is the front end's responsibility to perform the conversion.
3073
3074#4.25. midend_solve()
3075
3076 const char *midend_solve(midend *me);
3077
3078Requests the mid-end to perform a Solve operation.
3079
3080On success, NULL is returned. On failure, an error message (not
3081dynamically allocated) is returned, suitable for showing to the user.
3082
3083The front end can expect its drawing API and/or activate_timer() to be
3084called from within a call to this function. Some back ends require that
3085midend_size() (section 4.6) is called before midend_solve().
3086
3087#4.26. midend_status()
3088
3089 int midend_status(midend *me);
3090
3091This function returns +1 if the midend is currently displaying a game
3092in a solved state, -1 if the game is in a permanently lost state, or 0
3093otherwise. This function just calls the back end's status() function.
3094Front ends may wish to use this as a cue to proactively offer the option
3095of starting a new game.
3096
3097(See section 2.8.9 for more detail about the back end's status()
3098function and discussion of what should count as which status code.)
3099
3100#4.27. midend_can_undo()
3101
3102 int midend_can_undo(midend *me);
3103
3104Returns TRUE if the midend is currently in a state where the undo
3105operation is meaningful (i.e. at least one position exists on the undo
3106chain before the present one). Front ends may wish to use this to
3107visually activate and deactivate an undo button.
3108
3109#4.28. midend_can_redo()
3110
3111 int midend_can_redo(midend *me);
3112
3113Returns TRUE if the midend is currently in a state where the redo
3114operation is meaningful (i.e. at least one position exists on the
3115redo chain after the present one). Front ends may wish to use this to
3116visually activate and deactivate a redo button.
3117
3118#4.29. midend_serialise()
3119
3120 void midend_serialise(midend *me,
3121 void (*write)(void *ctx, const void *buf, int len), void *wctx);
3122
3123Calling this function causes the mid-end to convert its entire internal
3124state into a long ASCII text string, and to pass that string (piece by
3125piece) to the supplied `write' function.
3126
3127Desktop implementations can use this function to save a game in any
3128state (including half-finished) to a disk file, by supplying a `write'
3129function which is a wrapper on fwrite() (or local equivalent). Other
3130implementations may find other uses for it, such as compressing the
3131large and sprawling mid-end state into a manageable amount of memory
3132when a palmtop application is suspended so that another one can run; in
3133this case write might want to write to a memory buffer rather than a
3134file. There may be other uses for it as well.
3135
3136This function will call back to the supplied `write' function a number
3137of times, with the first parameter (`ctx') equal to `wctx', and the
3138other two parameters pointing at a piece of the output string.
3139
3140#4.30. midend_deserialise()
3141
3142 const char *midend_deserialise(midend *me,
3143 int (*read)(void *ctx, void *buf, int len), void *rctx);
3144
3145This function is the counterpart to midend_serialise(). It calls the
3146supplied read function repeatedly to read a quantity of data, and
3147attempts to interpret that data as a serialised mid-end as output by
3148midend_serialise().
3149
3150The read function is called with the first parameter (`ctx') equal
3151to `rctx', and should attempt to read `len' bytes of data into the
3152buffer pointed to by `buf'. It should return FALSE on failure or TRUE
3153on success. It should not report success unless it has filled the
3154entire buffer; on platforms which might be reading from a pipe or other
3155blocking data source, `read' is responsible for looping until the whole
3156buffer has been filled.
3157
3158If the de-serialisation operation is successful, the mid-end's internal
3159data structures will be replaced by the results of the load, and NULL
3160will be returned. Otherwise, the mid-end's state will be completely
3161unchanged and an error message (typically some variation on `save file
3162is corrupt') will be returned. As usual, the error message string is not
3163dynamically allocated.
3164
3165If this function succeeds, it is likely that the game parameters will
3166have been changed. The front end should therefore probably re-think the
3167window size using midend_size(), and probably cause a refresh using
3168midend_redraw().
3169
3170Because each mid-end is tied to a specific game back end, this function
3171will fail if you attempt to read in a save file generated by a different
3172game from the one configured in this mid-end, even if your application
3173is a monolithic one containing all the puzzles. See section 4.31 for a
3174helper function which will allow you to identify a save file before you
3175instantiate your mid-end in the first place.
3176
3177#4.31. identify_game()
3178
3179 const char *identify_game(char **name,
3180 int (*read)(void *ctx, void *buf, int len), void *rctx);
3181
3182This function examines a serialised midend stream, of the same kind used
3183by midend_serialise() and midend_deserialise(), and returns the name
3184field of the game back end from which it was saved.
3185
3186You might want this if your front end was a monolithic one containing
3187all the puzzles, and you wanted to be able to load an arbitrary save
3188file and automatically switch to the right game. Probably your next step
3189would be to iterate through gamelist (section 4.33) looking for a game
3190structure whose name field matched the returned string, and give an
3191error if you didn't find one.
3192
3193On success, the return value of this function is NULL, and the game name
3194string is written into *name. The caller should free that string after
3195using it.
3196
3197On failure, *name is NULL, and the return value is an error message
3198(which does not need freeing at all).
3199
3200(This isn't strictly speaking a midend function, since it doesn't accept
3201or return a pointer to a midend. You'd probably call it just _before_
3202deciding what kind of midend you wanted to instantiate.)
3203
3204#4.32. midend_request_id_changes()
3205
3206 void midend_request_id_changes(midend *me,
3207 void (*notify)(void *), void *ctx);
3208
3209This function is called by the front end to request notification by the
3210mid-end when the current game IDs (either descriptive or random-seed)
3211change. This can occur as a result of keypresses ('n' for New Game, for
3212example) or when a puzzle supersedes its game description (see section
32132.11.2). After this function is called, any change of the game ids will
3214cause the mid-end to call notify(ctx) after the change.
3215
3216This is for use by puzzles which want to present the game description to
3217the user constantly (e.g. as an HTML hyperlink) instead of only showing
3218it when the user explicitly requests it.
3219
3220This is a function I anticipate few front ends needing to implement, so
3221I make it a callback rather than a static function in order to relieve
3222most front ends of the need to provide an empty implementation.
3223
3224#4.33. Direct reference to the back end structure by the front end
3225
3226Although _most_ things the front end needs done should be done by
3227calling the mid-end, there are a few situations in which the front end
3228needs to refer directly to the game back end structure.
3229
3230The most obvious of these is
3231
3232 - passing the game back end as a parameter to midend_new().
3233
3234There are a few other back end features which are not wrapped by the
3235mid-end because there didn't seem much point in doing so:
3236
3237 - fetching the `name' field to use in window titles and similar
3238
3239 - reading the `can_configure', `can_solve' and
3240 `can_format_as_text_ever' fields to decide whether to add those
3241 items to the menu bar or equivalent
3242
3243 - reading the `winhelp_topic' field (Windows only)
3244
3245 - the GTK front end provides a `--generate' command-line option which
3246 directly calls the back end to do most of its work. This is not
3247 really part of the main front end code, though, and I'm not sure it
3248 counts.
3249
3250In order to find the game back end structure, the front end does one of
3251two things:
3252
3253 - If the particular front end is compiling a separate binary per game,
3254 then the back end structure is a global variable with the standard
3255 name `thegame':
3256
3257 extern const game thegame;
3258
3259 - If the front end is compiled as a monolithic application containing
3260 all the puzzles together (in which case the preprocessor symbol
3261 COMBINED must be defined when compiling most of the code base), then
3262 there will be two global variables defined:
3263
3264 extern const game *gamelist[];
3265 extern const int gamecount;
3266
3267 `gamelist' will be an array of `gamecount' game structures, declared
3268 in the automatically constructed source module `list.c'. The
3269 application should search that array for the game it wants, probably
3270 by reaching into each game structure and looking at its `name'
3271 field.
3272
3273#4.34. Mid-end to front-end calls
3274
3275This section describes the small number of functions which a front end
3276must provide to be called by the mid-end or other standard utility
3277modules.
3278
3279#4.35. get_random_seed()
3280
3281 void get_random_seed(void **randseed, int *randseedsize);
3282
3283This function is called by a new mid-end, and also occasionally by game
3284back ends. Its job is to return a piece of data suitable for using as a
3285seed for initialisation of a new `random_state'.
3286
3287On exit, `*randseed' should be set to point at a newly allocated piece
3288of memory containing some seed data, and `*randseedsize' should be set
3289to the length of that data.
3290
3291A simple and entirely adequate implementation is to return a piece of
3292data containing the current system time at the highest conveniently
3293available resolution.
3294
3295#4.36. activate_timer()
3296
3297 void activate_timer(frontend *fe);
3298
3299This is called by the mid-end to request that the front end begin
3300calling it back at regular intervals.
3301
3302The timeout interval is left up to the front end; the finer it is, the
3303smoother move animations will be, but the more CPU time will be used.
3304Current front ends use values around 20ms (i.e. 50Hz).
3305
3306After this function is called, the mid-end will expect to receive calls
3307to midend_timer() on a regular basis.
3308
3309#4.37. deactivate_timer()
3310
3311 void deactivate_timer(frontend *fe);
3312
3313This is called by the mid-end to request that the front end stop calling
3314midend_timer().
3315
3316#4.38. fatal()
3317
3318 void fatal(const char *fmt, ...);
3319
3320This is called by some utility functions if they encounter a genuinely
3321fatal error such as running out of memory. It is a variadic function
3322in the style of printf(), and is expected to show the formatted error
3323message to the user any way it can and then terminate the application.
3324It must not return.
3325
3326#4.39. frontend_default_colour()
3327
3328 void frontend_default_colour(frontend *fe, float *output);
3329
3330This function expects to be passed a pointer to an array of three
3331floats. It returns the platform's local preferred background colour
3332in those three floats, as red, green and blue values (in that order)
3333ranging from 0.0 to 1.0.
3334
3335This function should only ever be called by the back end function
3336colours() (section 2.8.6). (Thus, it isn't a _midend_-to-frontend
3337function as such, but there didn't seem to be anywhere else particularly
3338good to put it. Sorry.)
3339
3340#5. Utility APIs
3341
3342This chapter documents a variety of utility APIs provided for the
3343general use of the rest of the Puzzles code.
3344
3345#5.1. Random number generation
3346
3347Platforms' local random number generators vary widely in quality and
3348seed size. Puzzles therefore supplies its own high-quality random number
3349generator, with the additional advantage of giving the same results if
3350fed the same seed data on different platforms. This allows game random
3351seeds to be exchanged between different ports of Puzzles and still
3352generate the same games.
3353
3354Unlike the ANSI C rand() function, the Puzzles random number generator
3355has an _explicit_ state object called a `random_state'. One of these
3356is managed by each mid-end, for example, and passed to the back end to
3357generate a game with.
3358
3359#5.1.1. random_new()
3360
3361 random_state *random_new(char *seed, int len);
3362
3363Allocates, initialises and returns a new `random_state'. The input data
3364is used as the seed for the random number stream (i.e. using the same
3365seed at a later time will generate the same stream).
3366
3367The seed data can be any data at all; there is no requirement to use
3368printable ASCII, or NUL-terminated strings, or anything like that.
3369
3370#5.1.2. random_copy()
3371
3372 random_state *random_copy(random_state *tocopy);
3373
3374Allocates a new `random_state', copies the contents of another
3375`random_state' into it, and returns the new state. If exactly the
3376same sequence of functions is subseqently called on both the copy and
3377the original, the results will be identical. This may be useful for
3378speculatively performing some operation using a given random state, and
3379later replaying that operation precisely.
3380
3381#5.1.3. random_free()
3382
3383 void random_free(random_state *state);
3384
3385Frees a `random_state'.
3386
3387#5.1.4. random_bits()
3388
3389 unsigned long random_bits(random_state *state, int bits);
3390
3391Returns a random number from 0 to 2^bits-1 inclusive. `bits' should be
3392between 1 and 32 inclusive.
3393
3394#5.1.5. random_upto()
3395
3396 unsigned long random_upto(random_state *state, unsigned long limit);
3397
3398Returns a random number from 0 to limit-1 inclusive.
3399
3400#5.1.6. random_state_encode()
3401
3402 char *random_state_encode(random_state *state);
3403
3404Encodes the entire contents of a `random_state' in printable ASCII.
3405Returns a dynamically allocated string containing that encoding. This
3406can subsequently be passed to random_state_decode() to reconstruct the
3407same `random_state'.
3408
3409#5.1.7. random_state_decode()
3410
3411 random_state *random_state_decode(char *input);
3412
3413Decodes a string generated by random_state_encode() and reconstructs an
3414equivalent `random_state' to the one encoded, i.e. it should produce the
3415same stream of random numbers.
3416
3417This function has no error reporting; if you pass it an invalid string
3418it will simply generate an arbitrary random state, which may turn out to
3419be noticeably non-random.
3420
3421#5.1.8. shuffle()
3422
3423 void shuffle(void *array, int nelts, int eltsize, random_state *rs);
3424
3425Shuffles an array into a random order. The interface is much like ANSI C
3426qsort(), except that there's no need for a compare function.
3427
3428`array' is a pointer to the first element of the array. `nelts' is the
3429number of elements in the array; `eltsize' is the size of a single
3430element (typically measured using `sizeof'). `rs' is a `random_state'
3431used to generate all the random numbers for the shuffling process.
3432
3433#5.2. Presets menu management
3434
3435The function `midend_get_presets()' (section 4.15) returns a data
3436structure describing a menu hierarchy. Back ends can also choose to
3437provide such a structure to the mid-end, if they want to group their
3438presets hierarchically. To make this easy, there are a few utility
3439functions to construct preset menu structures, and also one intended for
3440front-end use.
3441
3442#5.2.1. preset_menu_new()
3443
3444 struct preset_menu *preset_menu_new(void);
3445
3446Allocates a new `struct preset_menu', and initialises it to hold no menu
3447items.
3448
3449#5.2.2. preset_menu_add_submenu()
3450
3451 struct preset_menu *preset_menu_add_submenu
3452 (struct preset_menu *parent, char *title);
3453
3454Adds a new submenu to the end of an existing preset menu, and returns
3455a pointer to a newly allocated `struct preset_menu' describing the
3456submenu.
3457
3458The string parameter `title' must be dynamically allocated by the
3459caller. The preset-menu structure will take ownership of it, so the
3460caller must not free it.
3461
3462#5.2.3. preset_menu_add_preset()
3463
3464 void preset_menu_add_preset
3465 (struct preset_menu *menu, char *title, game_params *params);
3466
3467Adds a preset game configuration to the end of a preset menu.
3468
3469Both the string parameter `title' and the game parameter structure
3470`params' itself must be dynamically allocated by the caller. The preset-
3471menu structure will take ownership of it, so the caller must not free
3472it.
3473
3474#5.2.4. preset_menu_lookup_by_id()
3475
3476 game_params *preset_menu_lookup_by_id
3477 (struct preset_menu *menu, int id);
3478
3479Given a numeric index, searches recursively through a preset menu
3480hierarchy to find the corresponding menu entry, and returns a pointer to
3481its existing `game_params' structure.
3482
3483This function is intended for front end use (but front ends need not use
3484it if they prefer to do things another way). If a front end finds it
3485inconvenient to store anything more than a numeric index alongside each
3486menu item, then this function provides an easy way for the front end to
3487get back the actual game parameters corresponding to a menu item that
3488the user has selected.
3489
3490#5.3. Memory allocation
3491
3492Puzzles has some central wrappers on the standard memory allocation
3493functions, which provide compile-time type checking, and run-time error
3494checking by means of quitting the application if it runs out of memory.
3495This doesn't provide the best possible recovery from memory shortage,
3496but on the other hand it greatly simplifies the rest of the code,
3497because nothing else anywhere needs to worry about NULL returns from
3498allocation.
3499
3500#5.3.1. snew()
3501
3502 var = snew(type);
3503
3504This macro takes a single argument which is a _type name_. It allocates
3505space for one object of that type. If allocation fails it will call
3506fatal() and not return; so if it does return, you can be confident that
3507its return value is non-NULL.
3508
3509The return value is cast to the specified type, so that the compiler
3510will type-check it against the variable you assign it into. Thus, this
3511ensures you don't accidentally allocate memory the size of the wrong
3512type and assign it into a variable of the right one (or vice versa!).
3513
3514#5.3.2. snewn()
3515
3516 var = snewn(n, type);
3517
3518This macro is the array form of snew(). It takes two arguments; the
3519first is a number, and the second is a type name. It allocates space
3520for that many objects of that type, and returns a type-checked non-NULL
3521pointer just as snew() does.
3522
3523#5.3.3. sresize()
3524
3525 var = sresize(var, n, type);
3526
3527This macro is a type-checked form of realloc(). It takes three
3528arguments: an input memory block, a new size in elements, and a type.
3529It re-sizes the input memory block to a size sufficient to contain that
3530many elements of that type. It returns a type-checked non-NULL pointer,
3531like snew() and snewn().
3532
3533The input memory block can be NULL, in which case this function will
3534behave exactly like snewn(). (In principle any ANSI-compliant realloc()
3535implementation ought to cope with this, but I've never quite trusted it
3536to work everywhere.)
3537
3538#5.3.4. sfree()
3539
3540 void sfree(void *p);
3541
3542This function is pretty much equivalent to free(). It is provided with a
3543dynamically allocated block, and frees it.
3544
3545The input memory block can be NULL, in which case this function will do
3546nothing. (In principle any ANSI-compliant free() implementation ought to
3547cope with this, but I've never quite trusted it to work everywhere.)
3548
3549#5.3.5. dupstr()
3550
3551 char *dupstr(const char *s);
3552
3553This function dynamically allocates a duplicate of a C string. Like the
3554snew() functions, it guarantees to return non-NULL or not return at all.
3555
3556(Many platforms provide the function strdup(). As well as guaranteeing
3557never to return NULL, my version has the advantage of being defined
3558_everywhere_, rather than inconveniently not quite everywhere.)
3559
3560#5.3.6. free_cfg()
3561
3562 void free_cfg(config_item *cfg);
3563
3564This function correctly frees an array of `config_item's, including
3565walking the array until it gets to the end and freeing any subsidiary
3566data items in each `u' sub-union which are expected to be dynamically
3567allocated.
3568
3569(See section 2.3.9 for details of the `config_item' structure.)
3570
3571#5.4. Sorted and counted tree functions
3572
3573Many games require complex algorithms for generating random puzzles, and
3574some require moderately complex algorithms even during play. A common
3575requirement during these algorithms is for a means of maintaining sorted
3576or unsorted lists of items, such that items can be removed and added
3577conveniently.
3578
3579For general use, Puzzles provides the following set of functions which
3580maintain 2-3-4 trees in memory. (A 2-3-4 tree is a balanced tree
3581structure, with the property that all lookups, insertions, deletions,
3582splits and joins can be done in O(log N) time.)
3583
3584All these functions expect you to be storing a tree of `void *'
3585pointers. You can put anything you like in those pointers.
3586
3587By the use of per-node element counts, these tree structures have the
3588slightly unusual ability to look elements up by their numeric index
3589within the list represented by the tree. This means that they can be
3590used to store an unsorted list (in which case, every time you insert a
3591new element, you must explicitly specify the position where you wish to
3592insert it). They can also do numeric lookups in a sorted tree, which
3593might be useful for (for example) tracking the median of a changing data
3594set.
3595
3596As well as storing sorted lists, these functions can be used for storing
3597`maps' (associative arrays), by defining each element of a tree to be a
3598(key, value) pair.
3599
3600#5.4.1. newtree234()
3601
3602 tree234 *newtree234(cmpfn234 cmp);
3603
3604Creates a new empty tree, and returns a pointer to it.
3605
3606The parameter `cmp' determines the sorting criterion on the tree. Its
3607prototype is
3608
3609 typedef int (*cmpfn234)(void *, void *);
3610
3611If you want a sorted tree, you should provide a function matching this
3612prototype, which returns like strcmp() does (negative if the first
3613argument is smaller than the second, positive if it is bigger, zero if
3614they compare equal). In this case, the function addpos234() will not be
3615usable on your tree (because all insertions must respect the sorting
3616order).
3617
3618If you want an unsorted tree, pass NULL. In this case you will not be
3619able to use either add234() or del234(), or any other function such
3620as find234() which depends on a sorting order. Your tree will become
3621something more like an array, except that it will efficiently support
3622insertion and deletion as well as lookups by numeric index.
3623
3624#5.4.2. freetree234()
3625
3626 void freetree234(tree234 *t);
3627
3628Frees a tree. This function will not free the _elements_ of the tree
3629(because they might not be dynamically allocated, or you might be
3630storing the same set of elements in more than one tree); it will just
3631free the tree structure itself. If you want to free all the elements of
3632a tree, you should empty it before passing it to freetree234(), by means
3633of code along the lines of
3634
3635 while ((element = delpos234(tree, 0)) != NULL)
3636 sfree(element); /* or some more complicated free function */
3637
3638#5.4.3. add234()
3639
3640 void *add234(tree234 *t, void *e);
3641
3642Inserts a new element `e' into the tree `t'. This function expects the
3643tree to be sorted; the new element is inserted according to the sort
3644order.
3645
3646If an element comparing equal to `e' is already in the tree, then the
3647insertion will fail, and the return value will be the existing element.
3648Otherwise, the insertion succeeds, and `e' is returned.
3649
3650#5.4.4. addpos234()
3651
3652 void *addpos234(tree234 *t, void *e, int index);
3653
3654Inserts a new element into an unsorted tree. Since there is no sorting
3655order to dictate where the new element goes, you must specify where you
3656want it to go. Setting `index' to zero puts the new element right at the
3657start of the list; setting `index' to the current number of elements in
3658the tree puts the new element at the end.
3659
3660Return value is `e', in line with add234() (although this function
3661cannot fail except by running out of memory, in which case it will bomb
3662out and die rather than returning an error indication).
3663
3664#5.4.5. index234()
3665
3666 void *index234(tree234 *t, int index);
3667
3668Returns a pointer to the `index'th element of the tree, or NULL if
3669`index' is out of range. Elements of the tree are numbered from zero.
3670
3671#5.4.6. find234()
3672
3673 void *find234(tree234 *t, void *e, cmpfn234 cmp);
3674
3675Searches for an element comparing equal to `e' in a sorted tree.
3676
3677If `cmp' is NULL, the tree's ordinary comparison function will be used
3678to perform the search. However, sometimes you don't want that; suppose,
3679for example, each of your elements is a big structure containing a
3680`char *' name field, and you want to find the element with a given name.
3681You _could_ achieve this by constructing a fake element structure,
3682setting its name field appropriately, and passing it to find234(),
3683but you might find it more convenient to pass _just_ a name string to
3684find234(), supplying an alternative comparison function which expects
3685one of its arguments to be a bare name and the other to be a large
3686structure containing a name field.
3687
3688Therefore, if `cmp' is not NULL, then it will be used to compare `e' to
3689elements of the tree. The first argument passed to `cmp' will always be
3690`e'; the second will be an element of the tree.
3691
3692(See section 5.4.1 for the definition of the `cmpfn234' function pointer
3693type.)
3694
3695The returned value is the element found, or NULL if the search is
3696unsuccessful.
3697
3698#5.4.7. findrel234()
3699
3700 void *findrel234(tree234 *t, void *e, cmpfn234 cmp, int relation);
3701
3702This function is like find234(), but has the additional ability to do a
3703_relative_ search. The additional parameter `relation' can be one of the
3704following values:
3705
3706REL234_EQ
3707
3708 Find only an element that compares equal to `e'. This is exactly the
3709 behaviour of find234().
3710
3711REL234_LT
3712
3713 Find the greatest element that compares strictly less than `e'. `e'
3714 may be NULL, in which case it finds the greatest element in the
3715 whole tree (which could also be done by index234(t, count234(t)-1)).
3716
3717REL234_LE
3718
3719 Find the greatest element that compares less than or equal to `e'.
3720 (That is, find an element that compares equal to `e' if possible,
3721 but failing that settle for something just less than it.)
3722
3723REL234_GT
3724
3725 Find the smallest element that compares strictly greater than `e'.
3726 `e' may be NULL, in which case it finds the smallest element in the
3727 whole tree (which could also be done by index234(t, 0)).
3728
3729REL234_GE
3730
3731 Find the smallest element that compares greater than or equal
3732 to `e'. (That is, find an element that compares equal to `e' if
3733 possible, but failing that settle for something just bigger than
3734 it.)
3735
3736Return value, as before, is the element found or NULL if no element
3737satisfied the search criterion.
3738
3739#5.4.8. findpos234()
3740
3741 void *findpos234(tree234 *t, void *e, cmpfn234 cmp, int *index);
3742
3743This function is like find234(), but has the additional feature of
3744returning the index of the element found in the tree; that index is
3745written to `*index' in the event of a successful search (a non-NULL
3746return value).
3747
3748`index' may be NULL, in which case this function behaves exactly like
3749find234().
3750
3751#5.4.9. findrelpos234()
3752
3753 void *findrelpos234(tree234 *t, void *e, cmpfn234 cmp, int relation,
3754 int *index);
3755
3756This function combines all the features of findrel234() and
3757findpos234().
3758
3759#5.4.10. del234()
3760
3761 void *del234(tree234 *t, void *e);
3762
3763Finds an element comparing equal to `e' in the tree, deletes it, and
3764returns it.
3765
3766The input tree must be sorted.
3767
3768The element found might be `e' itself, or might merely compare equal to
3769it.
3770
3771Return value is NULL if no such element is found.
3772
3773#5.4.11. delpos234()
3774
3775 void *delpos234(tree234 *t, int index);
3776
3777Deletes the element at position `index' in the tree, and returns it.
3778
3779Return value is NULL if the index is out of range.
3780
3781#5.4.12. count234()
3782
3783 int count234(tree234 *t);
3784
3785Returns the number of elements currently in the tree.
3786
3787#5.4.13. splitpos234()
3788
3789 tree234 *splitpos234(tree234 *t, int index, int before);
3790
3791Splits the input tree into two pieces at a given position, and creates a
3792new tree containing all the elements on one side of that position.
3793
3794If `before' is TRUE, then all the items at or after position `index' are
3795left in the input tree, and the items before that point are returned in
3796the new tree. Otherwise, the reverse happens: all the items at or after
3797`index' are moved into the new tree, and those before that point are
3798left in the old one.
3799
3800If `index' is equal to 0 or to the number of elements in the input tree,
3801then one of the two trees will end up empty (and this is not an error
3802condition). If `index' is further out of range in either direction, the
3803operation will fail completely and return NULL.
3804
3805This operation completes in O(log N) time, no matter how large the tree
3806or how balanced or unbalanced the split.
3807
3808#5.4.14. split234()
3809
3810 tree234 *split234(tree234 *t, void *e, cmpfn234 cmp, int rel);
3811
3812Splits a sorted tree according to its sort order.
3813
3814`rel' can be any of the relation constants described in section 5.4.7,
3815_except_ for REL234_EQ. All the elements having that relation to `e'
3816will be transferred into the new tree; the rest will be left in the old
3817one.
3818
3819The parameter `cmp' has the same semantics as it does in find234(): if
3820it is not NULL, it will be used in place of the tree's own comparison
3821function when comparing elements to `e', in such a way that `e' itself
3822is always the first of its two operands.
3823
3824Again, this operation completes in O(log N) time, no matter how large
3825the tree or how balanced or unbalanced the split.
3826
3827#5.4.15. join234()
3828
3829 tree234 *join234(tree234 *t1, tree234 *t2);
3830
3831Joins two trees together by concatenating the lists they represent. All
3832the elements of `t2' are moved into `t1', in such a way that they appear
3833_after_ the elements of `t1'. The tree `t2' is freed; the return value
3834is `t1'.
3835
3836If you apply this function to a sorted tree and it violates the sort
3837order (i.e. the smallest element in `t2' is smaller than or equal to the
3838largest element in `t1'), the operation will fail and return NULL.
3839
3840This operation completes in O(log N) time, no matter how large the trees
3841being joined together.
3842
3843#5.4.16. join234r()
3844
3845 tree234 *join234r(tree234 *t1, tree234 *t2);
3846
3847Joins two trees together in exactly the same way as join234(), but this
3848time the combined tree is returned in `t2', and `t1' is destroyed. The
3849elements in `t1' still appear before those in `t2'.
3850
3851Again, this operation completes in O(log N) time, no matter how large
3852the trees being joined together.
3853
3854#5.4.17. copytree234()
3855
3856 tree234 *copytree234(tree234 *t, copyfn234 copyfn,
3857 void *copyfnstate);
3858
3859Makes a copy of an entire tree.
3860
3861If `copyfn' is NULL, the tree will be copied but the elements will not
3862be; i.e. the new tree will contain pointers to exactly the same physical
3863elements as the old one.
3864
3865If you want to copy each actual element during the operation, you can
3866instead pass a function in `copyfn' which makes a copy of each element.
3867That function has the prototype
3868
3869 typedef void *(*copyfn234)(void *state, void *element);
3870
3871and every time it is called, the `state' parameter will be set to the
3872value you passed in as `copyfnstate'.
3873
3874#5.5. Miscellaneous utility functions and macros
3875
3876This section contains all the utility functions which didn't sensibly
3877fit anywhere else.
3878
3879#5.5.1. TRUE and FALSE
3880
3881The main Puzzles header file defines the macros TRUE and FALSE, which
3882are used throughout the code in place of 1 and 0 (respectively) to
3883indicate that the values are in a boolean context. For code base
3884consistency, I'd prefer it if submissions of new code followed this
3885convention as well.
3886
3887#5.5.2. max() and min()
3888
3889The main Puzzles header file defines the pretty standard macros max()
3890and min(), each of which is given two arguments and returns the one
3891which compares greater or less respectively.
3892
3893These macros may evaluate their arguments multiple times. Avoid side
3894effects.
3895
3896#5.5.3. PI
3897
3898The main Puzzles header file defines a macro PI which expands to a
3899floating-point constant representing pi.
3900
3901(I've never understood why ANSI's <math.h> doesn't define this. It'd be
3902so useful!)
3903
3904#5.5.4. obfuscate_bitmap()
3905
3906 void obfuscate_bitmap(unsigned char *bmp, int bits, int decode);
3907
3908This function obscures the contents of a piece of data, by cryptographic
3909methods. It is useful for games of hidden information (such as Mines,
3910Guess or Black Box), in which the game ID theoretically reveals all the
3911information the player is supposed to be trying to guess. So in order
3912that players should be able to send game IDs to one another without
3913accidentally spoiling the resulting game by looking at them, these games
3914obfuscate their game IDs using this function.
3915
3916Although the obfuscation function is cryptographic, it cannot properly
3917be called encryption because it has no key. Therefore, anybody motivated
3918enough can re-implement it, or hack it out of the Puzzles source,
3919and strip the obfuscation off one of these game IDs to see what lies
3920beneath. (Indeed, they could usually do it much more easily than that,
3921by entering the game ID into their own copy of the puzzle and hitting
3922Solve.) The aim is not to protect against a determined attacker; the aim
3923is simply to protect people who wanted to play the game honestly from
3924_accidentally_ spoiling their own fun.
3925
3926The input argument `bmp' points at a piece of memory to be obfuscated.
3927`bits' gives the length of the data. Note that that length is in _bits_
3928rather than bytes: if you ask for obfuscation of a partial number of
3929bytes, then you will get it. Bytes are considered to be used from the
3930top down: thus, for example, setting `bits' to 10 will cover the whole
3931of bmp[0] and the _top two_ bits of bmp[1]. The remainder of a partially
3932used byte is undefined (i.e. it may be corrupted by the function).
3933
3934The parameter `decode' is FALSE for an encoding operation, and TRUE
3935for a decoding operation. Each is the inverse of the other. (There's
3936no particular reason you shouldn't obfuscate by decoding and restore
3937cleartext by encoding, if you really wanted to; it should still work.)
3938
3939The input bitmap is processed in place.
3940
3941#5.5.5. bin2hex()
3942
3943 char *bin2hex(const unsigned char *in, int inlen);
3944
3945This function takes an input byte array and converts it into an
3946ASCII string encoding those bytes in (lower-case) hex. It returns a
3947dynamically allocated string containing that encoding.
3948
3949This function is useful for encoding the result of obfuscate_bitmap() in
3950printable ASCII for use in game IDs.
3951
3952#5.5.6. hex2bin()
3953
3954 unsigned char *hex2bin(const char *in, int outlen);
3955
3956This function takes an ASCII string containing hex digits, and converts
3957it back into a byte array of length `outlen'. If there aren't enough
3958hex digits in the string, the contents of the resulting array will be
3959undefined.
3960
3961This function is the inverse of bin2hex().
3962
3963#5.5.7. game_mkhighlight()
3964
3965 void game_mkhighlight(frontend *fe, float *ret,
3966 int background, int highlight, int lowlight);
3967
3968It's reasonably common for a puzzle game's graphics to use highlights
3969and lowlights to indicate `raised' or `lowered' sections. Fifteen,
3970Sixteen and Twiddle are good examples of this.
3971
3972Puzzles using this graphical style are running a risk if they just use
3973whatever background colour is supplied to them by the front end, because
3974that background colour might be too light to see any highlights on at
3975all. (In particular, it's not unheard of for the front end to specify a
3976default background colour of white.)
3977
3978Therefore, such puzzles can call this utility function from their
3979colours() routine (section 2.8.6). You pass it your front end handle, a
3980pointer to the start of your return array, and three colour indices. It
3981will:
3982
3983 - call frontend_default_colour() (section 4.39) to fetch the front
3984 end's default background colour
3985
3986 - alter the brightness of that colour if it's unsuitable
3987
3988 - define brighter and darker variants of the colour to be used as
3989 highlights and lowlights
3990
3991 - write those results into the relevant positions in the `ret' array.
3992
3993Thus, ret[background*3] to ret[background*3+2] will be set to RGB values
3994defining a sensible background colour, and similary `highlight' and
3995`lowlight' will be set to sensible colours.
3996
3997#6. How to write a new puzzle
3998
3999This chapter gives a guide to how to actually write a new puzzle: where
4000to start, what to do first, how to solve common problems.
4001
4002The previous chapters have been largely composed of facts. This one is
4003mostly advice.
4004
4005#6.1. Choosing a puzzle
4006
4007Before you start writing a puzzle, you have to choose one. Your taste
4008in puzzle games is up to you, of course; and, in fact, you're probably
4009reading this guide because you've _already_ thought of a game you want
4010to write. But if you want to get it accepted into the official Puzzles
4011distribution, then there's a criterion it has to meet.
4012
4013The current Puzzles editorial policy is that all games should be _fair_.
4014A fair game is one which a player can only fail to complete through
4015demonstrable lack of skill - that is, such that a better player in the
4016same situation would have _known_ to do something different.
4017
4018For a start, that means every game presented to the user must have _at
4019least one solution_. Giving the unsuspecting user a puzzle which is
4020actually impossible is not acceptable. (There is an exception: if the
4021user has selected some non-default option which is clearly labelled as
4022potentially unfair, _then_ you're allowed to generate possibly insoluble
4023puzzles, because the user isn't unsuspecting any more. Same Game and
4024Mines both have options of this type.)
4025
4026Also, this actually _rules out_ games such as Klondike, or the normal
4027form of Mahjong Solitaire. Those games have the property that even if
4028there is a solution (i.e. some sequence of moves which will get from
4029the start state to the solved state), the player doesn't necessarily
4030have enough information to _find_ that solution. In both games, it is
4031possible to reach a dead end because you had an arbitrary choice to make
4032and made it the wrong way. This violates the fairness criterion, because
4033a better player couldn't have known they needed to make the other
4034choice.
4035
4036(GNOME has a variant on Mahjong Solitaire which makes it fair: there
4037is a Shuffle operation which randomly permutes all the remaining tiles
4038without changing their positions, which allows you to get out of a
4039sticky situation. Using this operation adds a 60-second penalty to your
4040solution time, so it's to the player's advantage to try to minimise
4041the chance of having to use it. It's still possible to render the game
4042uncompletable if you end up with only two tiles vertically stacked,
4043but that's easy to foresee and avoid using a shuffle operation. This
4044form of the game _is_ fair. Implementing it in Puzzles would require
4045an infrastructure change so that the back end could communicate time
4046penalties to the mid-end, but that would be easy enough.)
4047
4048Providing a _unique_ solution is a little more negotiable; it depends
4049on the puzzle. Solo would have been of unacceptably low quality if it
4050didn't always have a unique solution, whereas Twiddle inherently has
4051multiple solutions by its very nature and it would have been meaningless
4052to even _suggest_ making it uniquely soluble. Somewhere in between, Flip
4053could reasonably be made to have unique solutions (by enforcing a zero-
4054dimension kernel in every generated matrix) but it doesn't seem like a
4055serious quality problem that it doesn't.
4056
4057Of course, you don't _have_ to care about all this. There's nothing
4058stopping you implementing any puzzle you want to if you're happy to
4059maintain your puzzle yourself, distribute it from your own web site,
4060fork the Puzzles code completely, or anything like that. It's free
4061software; you can do what you like with it. But any game that you want
4062to be accepted into _my_ Puzzles code base has to satisfy the fairness
4063criterion, which means all randomly generated puzzles must have a
4064solution (unless the user has deliberately chosen otherwise) and it must
4065be possible _in theory_ to find that solution without having to guess.
4066
4067#6.2. Getting started
4068
4069The simplest way to start writing a new puzzle is to copy `nullgame.c'.
4070This is a template puzzle source file which does almost nothing, but
4071which contains all the back end function prototypes and declares the
4072back end data structure correctly. It is built every time the rest of
4073Puzzles is built, to ensure that it doesn't get out of sync with the
4074code and remains buildable.
4075
4076So start by copying `nullgame.c' into your new source file. Then you'll
4077gradually add functionality until the very boring Null Game turns into
4078your real game.
4079
4080Next you'll need to add your puzzle to the Makefiles, in order to
4081compile it conveniently. _Do not edit the Makefiles_: they are created
4082automatically by the script `mkfiles.pl', from the file called `Recipe'.
4083Edit `Recipe', and then re-run `mkfiles.pl'.
4084
4085Also, don't forget to add your puzzle to `list.c': if you don't, then it
4086will still run fine on platforms which build each puzzle separately, but
4087Mac OS X and other monolithic platforms will not include your new puzzle
4088in their single binary.
4089
4090Once your source file is building, you can move on to the fun bit.
4091
4092#6.2.1. Puzzle generation
4093
4094Randomly generating instances of your puzzle is almost certain to be
4095the most difficult part of the code, and also the task with the highest
4096chance of turning out to be completely infeasible. Therefore I strongly
4097recommend doing it _first_, so that if it all goes horribly wrong you
4098haven't wasted any more time than you absolutely had to. What I usually
4099do is to take an unmodified `nullgame.c', and start adding code to
4100new_game_desc() which tries to generate a puzzle instance and print it
4101out using printf(). Once that's working, _then_ I start connecting it up
4102to the return value of new_game_desc(), populating other structures like
4103`game_params', and generally writing the rest of the source file.
4104
4105There are many ways to generate a puzzle which is known to be soluble.
4106In this section I list all the methods I currently know of, in case any
4107of them can be applied to your puzzle. (Not all of these methods will
4108work, or in some cases even make sense, for all puzzles.)
4109
4110Some puzzles are mathematically tractable, meaning you can work out in
4111advance which instances are soluble. Sixteen, for example, has a parity
4112constraint in some settings which renders exactly half the game space
4113unreachable, but it can be mathematically proved that any position
4114not in that half _is_ reachable. Therefore, Sixteen's grid generation
4115simply consists of selecting at random from a well defined subset of the
4116game space. Cube in its default state is even easier: _every_ possible
4117arrangement of the blue squares and the cube's starting position is
4118soluble!
4119
4120Another option is to redefine what you mean by `soluble'. Black Box
4121takes this approach. There are layouts of balls in the box which are
4122completely indistinguishable from one another no matter how many beams
4123you fire into the box from which angles, which would normally be grounds
4124for declaring those layouts unfair; but fortunately, detecting that
4125indistinguishability is computationally easy. So Black Box doesn't
4126demand that your ball placements match its own; it merely demands
4127that your ball placements be _indistinguishable_ from the ones it was
4128thinking of. If you have an ambiguous puzzle, then any of the possible
4129answers is considered to be a solution. Having redefined the rules in
4130that way, any puzzle is soluble again.
4131
4132Those are the simple techniques. If they don't work, you have to get
4133cleverer.
4134
4135One way to generate a soluble puzzle is to start from the solved state
4136and make inverse moves until you reach a starting state. Then you know
4137there's a solution, because you can just list the inverse moves you made
4138and make them in the opposite order to return to the solved state.
4139
4140This method can be simple and effective for puzzles where you get to
4141decide what's a starting state and what's not. In Pegs, for example,
4142the generator begins with one peg in the centre of the board and makes
4143inverse moves until it gets bored; in this puzzle, valid inverse moves
4144are easy to detect, and _any_ state that's reachable from the solved
4145state by inverse moves is a reasonable starting position. So Pegs just
4146continues making inverse moves until the board satisfies some criteria
4147about extent and density, and then stops and declares itself done.
4148
4149For other puzzles, it can be a lot more difficult. Same Game uses
4150this strategy too, and it's lucky to get away with it at all: valid
4151inverse moves aren't easy to find (because although it's easy to insert
4152additional squares in a Same Game position, it's difficult to arrange
4153that _after_ the insertion they aren't adjacent to any other squares of
4154the same colour), so you're constantly at risk of running out of options
4155and having to backtrack or start again. Also, Same Game grids never
4156start off half-empty, which means you can't just stop when you run out
4157of moves - you have to find a way to fill the grid up _completely_.
4158
4159The other way to generate a puzzle that's soluble is to start from the
4160other end, and actually write a _solver_. This tends to ensure that a
4161puzzle has a _unique_ solution over and above having a solution at all,
4162so it's a good technique to apply to puzzles for which that's important.
4163
4164One theoretical drawback of generating soluble puzzles by using a solver
4165is that your puzzles are restricted in difficulty to those which the
4166solver can handle. (Most solvers are not fully general: many sets of
4167puzzle rules are NP-complete or otherwise nasty, so most solvers can
4168only handle a subset of the theoretically soluble puzzles.) It's been
4169my experience in practice, however, that this usually isn't a problem;
4170computers are good at very different things from humans, and what the
4171computer thinks is nice and easy might still be pleasantly challenging
4172for a human. For example, when solving Dominosa puzzles I frequently
4173find myself using a variety of reasoning techniques that my solver
4174doesn't know about; in principle, therefore, I should be able to solve
4175the puzzle using only those techniques it _does_ know about, but this
4176would involve repeatedly searching the entire grid for the one simple
4177deduction I can make. Computers are good at this sort of exhaustive
4178search, but it's been my experience that human solvers prefer to do more
4179complex deductions than to spend ages searching for simple ones. So in
4180many cases I don't find my own playing experience to be limited by the
4181restrictions on the solver.
4182
4183(This isn't _always_ the case. Solo is a counter-example; generating
4184Solo puzzles using a simple solver does lead to qualitatively easier
4185puzzles. Therefore I had to make the Solo solver rather more advanced
4186than most of them.)
4187
4188There are several different ways to apply a solver to the problem of
4189generating a soluble puzzle. I list a few of them below.
4190
4191The simplest approach is brute force: randomly generate a puzzle, use
4192the solver to see if it's soluble, and if not, throw it away and try
4193again until you get lucky. This is often a viable technique if all
4194else fails, but it tends not to scale well: for many puzzle types, the
4195probability of finding a uniquely soluble instance decreases sharply
4196as puzzle size goes up, so this technique might work reasonably fast
4197for small puzzles but take (almost) forever at larger sizes. Still, if
4198there's no other alternative it can be usable: Pattern and Dominosa
4199both use this technique. (However, Dominosa has a means of tweaking the
4200randomly generated grids to increase the _probability_ of them being
4201soluble, by ruling out one of the most common ambiguous cases. This
4202improved generation speed by over a factor of 10 on the highest preset!)
4203
4204An approach which can be more scalable involves generating a grid and
4205then tweaking it to make it soluble. This is the technique used by Mines
4206and also by Net: first a random puzzle is generated, and then the solver
4207is run to see how far it gets. Sometimes the solver will get stuck;
4208when that happens, examine the area it's having trouble with, and make
4209a small random change in that area to allow it to make more progress.
4210Continue solving (possibly even without restarting the solver), tweaking
4211as necessary, until the solver finishes. Then restart the solver from
4212the beginning to ensure that the tweaks haven't caused new problems in
4213the process of solving old ones (which can sometimes happen).
4214
4215This strategy works well in situations where the usual solver failure
4216mode is to get stuck in an easily localised spot. Thus it works well
4217for Net and Mines, whose most common failure mode tends to be that most
4218of the grid is fine but there are a few widely separated ambiguous
4219sections; but it would work less well for Dominosa, in which the way you
4220get stuck is to have scoured the whole grid and not found anything you
4221can deduce _anywhere_. Also, it relies on there being a low probability
4222that tweaking the grid introduces a new problem at the same time as
4223solving the old one; Mines and Net also have the property that most of
4224their deductions are local, so that it's very unlikely for a tweak to
4225affect something half way across the grid from the location where it was
4226applied. In Dominosa, by contrast, a lot of deductions use information
4227about half the grid (`out of all the sixes, only one is next to a
4228three', which can depend on the values of up to 32 of the 56 squares in
4229the default setting!), so this tweaking strategy would be rather less
4230likely to work well.
4231
4232A more specialised strategy is that used in Solo and Slant. These
4233puzzles have the property that they derive their difficulty from not
4234presenting all the available clues. (In Solo's case, if all the possible
4235clues were provided then the puzzle would already be solved; in Slant
4236it would still require user action to fill in the lines, but it would
4237present no challenge at all). Therefore, a simple generation technique
4238is to leave the decision of which clues to provide until the last
4239minute. In other words, first generate a random _filled_ grid with all
4240possible clues present, and then gradually remove clues for as long as
4241the solver reports that it's still soluble. Unlike the methods described
4242above, this technique _cannot_ fail - once you've got a filled grid,
4243nothing can stop you from being able to convert it into a viable puzzle.
4244However, it wouldn't even be meaningful to apply this technique to (say)
4245Pattern, in which clues can never be left out, so the only way to affect
4246the set of clues is by altering the solution.
4247
4248(Unfortunately, Solo is complicated by the need to provide puzzles at
4249varying difficulty levels. It's easy enough to generate a puzzle of
4250_at most_ a given level of difficulty; you just have a solver with
4251configurable intelligence, and you set it to a given level and apply the
4252above technique, thus guaranteeing that the resulting grid is solvable
4253by someone with at most that much intelligence. However, generating a
4254puzzle of _at least_ a given level of difficulty is rather harder; if
4255you go for _at most_ Intermediate level, you're likely to find that
4256you've accidentally generated a Trivial grid a lot of the time, because
4257removing just one number is sufficient to take the puzzle from Trivial
4258straight to Ambiguous. In that situation Solo has no remaining options
4259but to throw the puzzle away and start again.)
4260
4261A final strategy is to use the solver _during_ puzzle construction:
4262lay out a bit of the grid, run the solver to see what it allows you to
4263deduce, and then lay out a bit more to allow the solver to make more
4264progress. There are articles on the web that recommend constructing
4265Sudoku puzzles by this method (which is completely the opposite way
4266round to how Solo does it); for Sudoku it has the advantage that you
4267get to specify your clue squares in advance (so you can have them make
4268pretty patterns).
4269
4270Rectangles uses a strategy along these lines. First it generates a grid
4271by placing the actual rectangles; then it has to decide where in each
4272rectangle to place a number. It uses a solver to help it place the
4273numbers in such a way as to ensure a unique solution. It does this by
4274means of running a test solver, but it runs the solver _before_ it's
4275placed any of the numbers - which means the solver must be capable of
4276coping with uncertainty about exactly where the numbers are! It runs
4277the solver as far as it can until it gets stuck; then it narrows down
4278the possible positions of a number in order to allow the solver to make
4279more progress, and so on. Most of the time this process terminates with
4280the grid fully solved, at which point any remaining number-placement
4281decisions can be made at random from the options not so far ruled out.
4282Note that unlike the Net/Mines tweaking strategy described above, this
4283algorithm does not require a checking run after it completes: if it
4284finishes successfully at all, then it has definitely produced a uniquely
4285soluble puzzle.
4286
4287Most of the strategies described above are not 100% reliable. Each
4288one has a failure rate: every so often it has to throw out the whole
4289grid and generate a fresh one from scratch. (Solo's strategy would
4290be the exception, if it weren't for the need to provide configurable
4291difficulty levels.) Occasional failures are not a fundamental problem in
4292this sort of work, however: it's just a question of dividing the grid
4293generation time by the success rate (if it takes 10ms to generate a
4294candidate grid and 1/5 of them work, then it will take 50ms on average
4295to generate a viable one), and seeing whether the expected time taken
4296to _successfully_ generate a puzzle is unacceptably slow. Dominosa's
4297generator has a very low success rate (about 1 out of 20 candidate grids
4298turn out to be usable, and if you think _that's_ bad then go and look
4299at the source code and find the comment showing what the figures were
4300before the generation-time tweaks!), but the generator itself is very
4301fast so this doesn't matter. Rectangles has a slower generator, but
4302fails well under 50% of the time.
4303
4304So don't be discouraged if you have an algorithm that doesn't always
4305work: if it _nearly_ always works, that's probably good enough. The one
4306place where reliability is important is that your algorithm must never
4307produce false positives: it must not claim a puzzle is soluble when it
4308isn't. It can produce false negatives (failing to notice that a puzzle
4309is soluble), and it can fail to generate a puzzle at all, provided it
4310doesn't do either so often as to become slow.
4311
4312One last piece of advice: for grid-based puzzles, when writing and
4313testing your generation algorithm, it's almost always a good idea _not_
4314to test it initially on a grid that's square (i.e. w==h), because if the
4315grid is square then you won't notice if you mistakenly write `h' instead
4316of `w' (or vice versa) somewhere in the code. Use a rectangular grid for
4317testing, and any size of grid will be likely to work after that.
4318
4319#6.2.2. Designing textual description formats
4320
4321Another aspect of writing a puzzle which is worth putting some thought
4322into is the design of the various text description formats: the format
4323of the game parameter encoding, the game description encoding, and the
4324move encoding.
4325
4326The first two of these should be reasonably intuitive for a user to type
4327in; so provide some flexibility where possible. Suppose, for example,
4328your parameter format consists of two numbers separated by an `x' to
4329specify the grid dimensions (`10x10' or `20x15'), and then has some
4330suffixes to specify other aspects of the game type. It's almost always a
4331good idea in this situation to arrange that decode_params() can handle
4332the suffixes appearing in any order, even if encode_params() only ever
4333generates them in one order.
4334
4335These formats will also be expected to be reasonably stable: users will
4336expect to be able to exchange game IDs with other users who aren't
4337running exactly the same version of your game. So make them robust and
4338stable: don't build too many assumptions into the game ID format which
4339will have to be changed every time something subtle changes in the
4340puzzle code.
4341
4342#6.3. Common how-to questions
4343
4344This section lists some common things people want to do when writing a
4345puzzle, and describes how to achieve them within the Puzzles framework.
4346
4347#6.3.1. Drawing objects at only one position
4348
4349A common phenomenon is to have an object described in the `game_state'
4350or the `game_ui' which can only be at one position. A cursor - probably
4351specified in the `game_ui' - is a good example.
4352
4353In the `game_ui', it would _obviously_ be silly to have an array
4354covering the whole game grid with a boolean flag stating whether the
4355cursor was at each position. Doing that would waste space, would make
4356it difficult to find the cursor in order to do anything with it, and
4357would introduce the potential for synchronisation bugs in which you
4358ended up with two cursors or none. The obviously sensible way to store a
4359cursor in the `game_ui' is to have fields directly encoding the cursor's
4360coordinates.
4361
4362However, it is a mistake to assume that the same logic applies to the
4363`game_drawstate'. If you replicate the cursor position fields in the
4364draw state, the redraw code will get very complicated. In the draw
4365state, in fact, it _is_ probably the right thing to have a cursor flag
4366for every position in the grid. You probably have an array for the whole
4367grid in the drawstate already (stating what is currently displayed in
4368the window at each position); the sensible approach is to add a `cursor'
4369flag to each element of that array. Then the main redraw loop will look
4370something like this (pseudo-code):
4371
4372 for (y = 0; y < h; y++) {
4373 for (x = 0; x < w; x++) {
4374 int value = state->symbol_at_position[y][x];
4375 if (x == ui->cursor_x && y == ui->cursor_y)
4376 value |= CURSOR;
4377 if (ds->symbol_at_position[y][x] != value) {
4378 symbol_drawing_subroutine(dr, ds, x, y, value);
4379 ds->symbol_at_position[y][x] = value;
4380 }
4381 }
4382 }
4383
4384This loop is very simple, pretty hard to get wrong, and _automatically_
4385deals both with erasing the previous cursor and drawing the new one,
4386with no special case code required.
4387
4388This type of loop is generally a sensible way to write a redraw
4389function, in fact. The best thing is to ensure that the information
4390stored in the draw state for each position tells you _everything_ about
4391what was drawn there. A good way to ensure that is to pass precisely
4392the same information, and _only_ that information, to a subroutine that
4393does the actual drawing; then you know there's no additional information
4394which affects the drawing but which you don't notice changes in.
4395
4396#6.3.2. Implementing a keyboard-controlled cursor
4397
4398It is often useful to provide a keyboard control method in a basically
4399mouse-controlled game. A keyboard-controlled cursor is best implemented
4400by storing its location in the `game_ui' (since if it were in the
4401`game_state' then the user would have to separately undo every cursor
4402move operation). So the procedure would be:
4403
4404 - Put cursor position fields in the `game_ui'.
4405
4406 - interpret_move() responds to arrow keys by modifying the cursor
4407 position fields and returning "".
4408
4409 - interpret_move() responds to some sort of fire button by actually
4410 performing a move based on the current cursor location.
4411
4412 - You might want an additional `game_ui' field stating whether the
4413 cursor is currently visible, and having it disappear when a mouse
4414 action occurs (so that it doesn't clutter the display when not
4415 actually in use).
4416
4417 - You might also want to automatically hide the cursor in
4418 changed_state() when the current game state changes to one in
4419 which there is no move to make (which is the case in some types of
4420 completed game).
4421
4422 - redraw() draws the cursor using the technique described in section
4423 6.3.1.
4424
4425#6.3.3. Implementing draggable sprites
4426
4427Some games have a user interface which involves dragging some sort of
4428game element around using the mouse. If you need to show a graphic
4429moving smoothly over the top of other graphics, use a blitter (see
4430section 3.1.13 for the blitter API) to save the background underneath
4431it. The typical scenario goes:
4432
4433 - Have a blitter field in the `game_drawstate'.
4434
4435 - Set the blitter field to NULL in the game's new_drawstate()
4436 function, since you don't yet know how big the piece of saved
4437 background needs to be.
4438
4439 - In the game's set_size() function, once you know the size of the
4440 object you'll be dragging around the display and hence the required
4441 size of the blitter, actually allocate the blitter.
4442
4443 - In free_drawstate(), free the blitter if it's not NULL.
4444
4445 - In interpret_move(), respond to mouse-down and mouse-drag events by
4446 updating some fields in the game_ui which indicate that a drag is in
4447 progress.
4448
4449 - At the _very end_ of redraw(), after all other drawing has been
4450 done, draw the moving object if there is one. First save the
4451 background under the object in the blitter; then set a clip
4452 rectangle covering precisely the area you just saved (just in case
4453 anti-aliasing or some other error causes your drawing to go beyond
4454 the area you saved). Then draw the object, and call unclip().
4455 Finally, set a flag in the game_drawstate that indicates that the
4456 blitter needs restoring.
4457
4458 - At the very start of redraw(), before doing anything else at all,
4459 check the flag in the game_drawstate, and if it says the blitter
4460 needs restoring then restore it. (Then clear the flag, so that this
4461 won't happen again in the next redraw if no moving object is drawn
4462 this time.)
4463
4464This way, you will be able to write the rest of the redraw function
4465completely ignoring the dragged object, as if it were floating above
4466your bitmap and being completely separate.
4467
4468#6.3.4. Sharing large invariant data between all game states
4469
4470In some puzzles, there is a large amount of data which never changes
4471between game states. The array of numbers in Dominosa is a good example.
4472
4473You _could_ dynamically allocate a copy of that array in every
4474`game_state', and have dup_game() make a fresh copy of it for every new
4475`game_state'; but it would waste memory and time. A more efficient way
4476is to use a reference-counted structure.
4477
4478 - Define a structure type containing the data in question, and also
4479 containing an integer reference count.
4480
4481 - Have a field in `game_state' which is a pointer to this structure.
4482
4483 - In new_game(), when creating a fresh game state at the start of a
4484 new game, create an instance of this structure, initialise it with
4485 the invariant data, and set its reference count to 1.
4486
4487 - In dup_game(), rather than making a copy of the structure for the
4488 new game state, simply set the new game state to point at the same
4489 copy of the structure, and increment its reference count.
4490
4491 - In free_game(), decrement the reference count in the structure
4492 pointed to by the game state; if the count reaches zero, free the
4493 structure.
4494
4495This way, the invariant data will persist for only as long as it's
4496genuinely needed; _as soon_ as the last game state for a particular
4497puzzle instance is freed, the invariant data for that puzzle will
4498vanish as well. Reference counting is a very efficient form of garbage
4499collection, when it works at all. (Which it does in this instance, of
4500course, because there's no possibility of circular references.)
4501
4502#6.3.5. Implementing multiple types of flash
4503
4504In some games you need to flash in more than one different way. Mines,
4505for example, flashes white when you win, and flashes red when you tread
4506on a mine and die.
4507
4508The simple way to do this is:
4509
4510 - Have a field in the `game_ui' which describes the type of flash.
4511
4512 - In flash_length(), examine the old and new game states to decide
4513 whether a flash is required and what type. Write the type of flash
4514 to the `game_ui' field whenever you return non-zero.
4515
4516 - In redraw(), when you detect that `flash_time' is non-zero, examine
4517 the field in `game_ui' to decide which type of flash to draw.
4518
4519redraw() will never be called with `flash_time' non-zero unless
4520flash_length() was first called to tell the mid-end that a flash was
4521required; so whenever redraw() notices that `flash_time' is non-zero,
4522you can be sure that the field in `game_ui' is correctly set.
4523
4524#6.3.6. Animating game moves
4525
4526A number of puzzle types benefit from a quick animation of each move you
4527make.
4528
4529For some games, such as Fifteen, this is particularly easy. Whenever
4530redraw() is called with `oldstate' non-NULL, Fifteen simply compares the
4531position of each tile in the two game states, and if the tile is not in
4532the same place then it draws it some fraction of the way from its old
4533position to its new position. This method copes automatically with undo.
4534
4535Other games are less obvious. In Sixteen, for example, you can't just
4536draw each tile a fraction of the way from its old to its new position:
4537if you did that, the end tile would zip very rapidly past all the others
4538to get to the other end and that would look silly. (Worse, it would look
4539inconsistent if the end tile was drawn on top going one way and on the
4540bottom going the other way.)
4541
4542A useful trick here is to define a field or two in the game state that
4543indicates what the last move was.
4544
4545 - Add a `last move' field to the `game_state' (or two or more fields
4546 if the move is complex enough to need them).
4547
4548 - new_game() initialises this field to a null value for a new game
4549 state.
4550
4551 - execute_move() sets up the field to reflect the move it just
4552 performed.
4553
4554 - redraw() now needs to examine its `dir' parameter. If `dir' is
4555 positive, it determines the move being animated by looking at the
4556 last-move field in `newstate'; but if `dir' is negative, it has to
4557 look at the last-move field in `oldstate', and invert whatever move
4558 it finds there.
4559
4560Note also that Sixteen needs to store the _direction_ of the move,
4561because you can't quite determine it by examining the row or column in
4562question. You can in almost all cases, but when the row is precisely
4563two squares long it doesn't work since a move in either direction looks
4564the same. (You could argue that since moving a 2-element row left and
4565right has the same effect, it doesn't matter which one you animate; but
4566in fact it's very disorienting to click the arrow left and find the row
4567moving right, and almost as bad to undo a move to the right and find the
4568game animating _another_ move to the right.)
4569
4570#6.3.7. Animating drag operations
4571
4572In Untangle, moves are made by dragging a node from an old position to a
4573new position. Therefore, at the time when the move is initially made, it
4574should not be animated, because the node has already been dragged to the
4575right place and doesn't need moving there. However, it's nice to animate
4576the same move if it's later undone or redone. This requires a bit of
4577fiddling.
4578
4579The obvious approach is to have a flag in the `game_ui' which inhibits
4580move animation, and to set that flag in interpret_move(). The question
4581is, when would the flag be reset again? The obvious place to do so
4582is changed_state(), which will be called once per move. But it will
4583be called _before_ anim_length(), so if it resets the flag then
4584anim_length() will never see the flag set at all.
4585
4586The solution is to have _two_ flags in a queue.
4587
4588 - Define two flags in `game_ui'; let's call them `current' and `next'.
4589
4590 - Set both to FALSE in `new_ui()'.
4591
4592 - When a drag operation completes in interpret_move(), set the `next'
4593 flag to TRUE.
4594
4595 - Every time changed_state() is called, set the value of `current' to
4596 the value in `next', and then set the value of `next' to FALSE.
4597
4598 - That way, `current' will be TRUE _after_ a call to changed_state()
4599 if and only if that call to changed_state() was the result of a
4600 drag operation processed by interpret_move(). Any other call to
4601 changed_state(), due to an Undo or a Redo or a Restart or a Solve,
4602 will leave `current' FALSE.
4603
4604 - So now anim_length() can request a move animation if and only if the
4605 `current' flag is _not_ set.
4606
4607#6.3.8. Inhibiting the victory flash when Solve is used
4608
4609Many games flash when you complete them, as a visual congratulation for
4610having got to the end of the puzzle. It often seems like a good idea to
4611disable that flash when the puzzle is brought to a solved state by means
4612of the Solve operation.
4613
4614This is easily done:
4615
4616 - Add a `cheated' flag to the `game_state'.
4617
4618 - Set this flag to FALSE in new_game().
4619
4620 - Have solve() return a move description string which clearly
4621 identifies the move as a solve operation.
4622
4623 - Have execute_move() respond to that clear identification by setting
4624 the `cheated' flag in the returned `game_state'. The flag will
4625 then be propagated to all subsequent game states, even if the user
4626 continues fiddling with the game after it is solved.
4627
4628 - flash_length() now returns non-zero if `oldstate' is not completed
4629 and `newstate' is, _and_ neither state has the `cheated' flag set.
4630
4631#6.4. Things to test once your puzzle is written
4632
4633Puzzle implementations written in this framework are self-testing as far
4634as I could make them.
4635
4636Textual game and move descriptions, for example, are generated and
4637parsed as part of the normal process of play. Therefore, if you can make
4638moves in the game _at all_ you can be reasonably confident that the
4639mid-end serialisation interface will function correctly and you will
4640be able to save your game. (By contrast, if I'd stuck with a single
4641make_move() function performing the jobs of both interpret_move() and
4642execute_move(), and had separate functions to encode and decode a game
4643state in string form, then those functions would not be used during
4644normal play; so they could have been completely broken, and you'd never
4645know it until you tried to save the game - which would have meant you'd
4646have to test game saving _extensively_ and make sure to test every
4647possible type of game state. As an added bonus, doing it the way I did
4648leads to smaller save files.)
4649
4650There is one exception to this, which is the string encoding of the
4651`game_ui'. Most games do not store anything permanent in the `game_ui',
4652and hence do not need to put anything in its encode and decode
4653functions; but if there is anything in there, you do need to test game
4654loading and saving to ensure those functions work properly.
4655
4656It's also worth testing undo and redo of all operations, to ensure that
4657the redraw and the animations (if any) work properly. Failing to animate
4658undo properly seems to be a common error.
4659
4660Other than that, just use your common sense.
4661