chiark / gitweb /
Net: reference-count the barriers array.
[sgt-puzzles.git] / devel.but
index 571b960391d70008b7a1266a3c217c9578d8a896..25a6c62dfa5d3fb198a35c0432e8523cfd9993fb 100644 (file)
--- a/devel.but
+++ b/devel.but
@@ -391,8 +391,9 @@ with the default values, and returns a pointer to it.
 
 \c int (*fetch_preset)(int i, char **name, game_params **params);
 
 
 \c int (*fetch_preset)(int i, char **name, game_params **params);
 
-This function is used to populate the \q{Type} menu, which provides
-a list of conveniently accessible preset parameters for most games.
+This function is one of the two APIs a back end can provide to
+populate the \q{Type} menu, which provides a list of conveniently
+accessible preset parameters for most games.
 
 The function is called with \c{i} equal to the index of the preset
 required (numbering from zero). It returns \cw{FALSE} if that preset
 
 The function is called with \c{i} equal to the index of the preset
 required (numbering from zero). It returns \cw{FALSE} if that preset
@@ -406,9 +407,36 @@ returns \cw{TRUE}.
 If the game does not wish to support any presets at all, this
 function is permitted to return \cw{FALSE} always.
 
 If the game does not wish to support any presets at all, this
 function is permitted to return \cw{FALSE} always.
 
+If the game wants to return presets in the form of a hierarchical menu
+instead of a flat list (and, indeed, even if it doesn't), then it may
+set this function pointer to \cw{NULL}, and instead fill in the
+alternative function pointer \cw{preset_menu}
+(\k{backend-preset-menu}).
+
+\S{backend-preset-menu} \cw{preset_menu()}
+
+\c struct preset_menu *(*preset_menu)(void);
+
+This function is the more flexible of the two APIs by which a back end
+can define a collection of preset game parameters.
+
+This function simply returns a complete menu hierarchy, in the form of
+a \c{struct preset_menu} (see \k{midend-get-presets}) and further
+submenus (if it wishes) dangling off it. There are utility functions
+described in \k{utils-presets} to make it easy for the back end to
+construct this menu.
+
+If the game has no need to return a hierarchy of menus, it may instead
+opt to implement the \cw{fetch_preset()} function (see
+\k{backend-fetch-preset}).
+
+The game need not fill in the \c{id} fields in the preset menu
+structures. The mid-end will do that after it receives the structure
+from the game, and before passing it on to the front end.
+
 \S{backend-encode-params} \cw{encode_params()}
 
 \S{backend-encode-params} \cw{encode_params()}
 
-\c char *(*encode_params)(game_params *params, int full);
+\c char *(*encode_params)(const game_params *params, int full);
 
 The job of this function is to take a \c{game_params}, and encode it
 in a string form for use in game IDs. The return value must be a
 
 The job of this function is to take a \c{game_params}, and encode it
 in a string form for use in game IDs. The return value must be a
@@ -493,7 +521,7 @@ allocations contained within it.
 
 \S{backend-dup-params} \cw{dup_params()}
 
 
 \S{backend-dup-params} \cw{dup_params()}
 
-\c game_params *(*dup_params)(game_params *params);
+\c game_params *(*dup_params)(const game_params *params);
 
 This function allocates a new \c{game_params} structure and
 initialises it with an exact copy of the information in the one
 
 This function allocates a new \c{game_params} structure and
 initialises it with an exact copy of the information in the one
@@ -511,7 +539,7 @@ and \k{backend-custom-params} for more details.
 
 \S{backend-configure} \cw{configure()}
 
 
 \S{backend-configure} \cw{configure()}
 
-\c config_item *(*configure)(game_params *params);
+\c config_item *(*configure)(const game_params *params);
 
 This function is called when the user requests a dialog box for
 custom parameter configuration. It returns a newly allocated array
 
 This function is called when the user requests a dialog box for
 custom parameter configuration. It returns a newly allocated array
@@ -586,7 +614,7 @@ function is never called and need not do anything at all.
 
 \S{backend-custom-params} \cw{custom_params()}
 
 
 \S{backend-custom-params} \cw{custom_params()}
 
-\c game_params *(*custom_params)(config_item *cfg);
+\c game_params *(*custom_params)(const config_item *cfg);
 
 This function is the counterpart to \cw{configure()}
 (\k{backend-configure}). It receives as input an array of
 
 This function is the counterpart to \cw{configure()}
 (\k{backend-configure}). It receives as input an array of
@@ -611,7 +639,7 @@ function is never called and need not do anything at all.
 
 \S{backend-validate-params} \cw{validate_params()}
 
 
 \S{backend-validate-params} \cw{validate_params()}
 
-\c char *(*validate_params)(game_params *params, int full);
+\c char *(*validate_params)(const game_params *params, int full);
 
 This function takes a \c{game_params} structure as input, and checks
 that the parameters described in it fall within sensible limits. (At
 
 This function takes a \c{game_params} structure as input, and checks
 that the parameters described in it fall within sensible limits. (At
@@ -655,7 +683,7 @@ a descriptive-format game ID.
 
 \S{backend-new-desc} \cw{new_desc()}
 
 
 \S{backend-new-desc} \cw{new_desc()}
 
-\c char *(*new_desc)(game_params *params, random_state *rs,
+\c char *(*new_desc)(const game_params *params, random_state *rs,
 \c                   char **aux, int interactive);
 
 This function is where all the really hard work gets done. This is
 \c                   char **aux, int interactive);
 
 This function is where all the really hard work gets done. This is
@@ -696,7 +724,7 @@ again in the game description.
 
 \S{backend-validate-desc} \cw{validate_desc()}
 
 
 \S{backend-validate-desc} \cw{validate_desc()}
 
-\c char *(*validate_desc)(game_params *params, char *desc);
+\c char *(*validate_desc)(const game_params *params, const char *desc);
 
 This function is given a game description, and its job is to
 validate that it describes a puzzle which makes sense.
 
 This function is given a game description, and its job is to
 validate that it describes a puzzle which makes sense.
@@ -720,8 +748,8 @@ non-dynamically-allocated C string containing an error message.
 
 \S{backend-new-game} \cw{new_game()}
 
 
 \S{backend-new-game} \cw{new_game()}
 
-\c game_state *(*new_game)(midend *me, game_params *params,
-\c                         char *desc);
+\c game_state *(*new_game)(midend *me, const game_params *params,
+\c                         const char *desc);
 
 This function takes a game description as input, together with its
 accompanying \c{game_params}, and constructs a \c{game_state}
 
 This function takes a game description as input, together with its
 accompanying \c{game_params}, and constructs a \c{game_state}
@@ -749,7 +777,7 @@ game states and it had to go in one section or the other.)
 
 \S{backend-dup-game} \cw{dup_game()}
 
 
 \S{backend-dup-game} \cw{dup_game()}
 
-\c game_state *(*dup_game)(game_state *state);
+\c game_state *(*dup_game)(const game_state *state);
 
 This function allocates a new \c{game_state} structure and
 initialises it with an exact copy of the information in the one
 
 This function allocates a new \c{game_state} structure and
 initialises it with an exact copy of the information in the one
@@ -766,7 +794,7 @@ allocations contained within it.
 
 \S{backend-new-ui} \cw{new_ui()}
 
 
 \S{backend-new-ui} \cw{new_ui()}
 
-\c game_ui *(*new_ui)(game_state *state);
+\c game_ui *(*new_ui)(const game_state *state);
 
 This function allocates and returns a new \c{game_ui} structure for
 playing a particular puzzle. It is passed a pointer to the initial
 
 This function allocates and returns a new \c{game_ui} structure for
 playing a particular puzzle. It is passed a pointer to the initial
@@ -782,7 +810,7 @@ allocations contained within it.
 
 \S{backend-encode-ui} \cw{encode_ui()}
 
 
 \S{backend-encode-ui} \cw{encode_ui()}
 
-\c char *(*encode_ui)(game_ui *ui);
+\c char *(*encode_ui)(const game_ui *ui);
 
 This function encodes any \e{important} data in a \c{game_ui}
 structure in string form. It is only called when saving a
 
 This function encodes any \e{important} data in a \c{game_ui}
 structure in string form. It is only called when saving a
@@ -806,7 +834,7 @@ source.)
 
 \S{backend-decode-ui} \cw{decode_ui()}
 
 
 \S{backend-decode-ui} \cw{decode_ui()}
 
-\c void (*decode_ui)(game_ui *ui, char *encoding);
+\c void (*decode_ui)(game_ui *ui, const char *encoding);
 
 This function parses a string previously output by \cw{encode_ui()},
 and writes the decoded data back into the provided \c{game_ui}
 
 This function parses a string previously output by \cw{encode_ui()},
 and writes the decoded data back into the provided \c{game_ui}
@@ -814,8 +842,8 @@ structure.
 
 \S{backend-changed-state} \cw{changed_state()}
 
 
 \S{backend-changed-state} \cw{changed_state()}
 
-\c void (*changed_state)(game_ui *ui, game_state *oldstate,
-\c                       game_state *newstate);
+\c void (*changed_state)(game_ui *ui, const game_state *oldstate,
+\c                       const game_state *newstate);
 
 This function is called by the mid-end whenever the current game
 state changes, for any reason. Those reasons include:
 
 This function is called by the mid-end whenever the current game
 state changes, for any reason. Those reasons include:
@@ -855,8 +883,8 @@ producing new \c{game_state}s.
 
 \S{backend-interpret-move} \cw{interpret_move()}
 
 
 \S{backend-interpret-move} \cw{interpret_move()}
 
-\c char *(*interpret_move)(game_state *state, game_ui *ui,
-\c                         game_drawstate *ds,
+\c char *(*interpret_move)(const game_state *state, game_ui *ui,
+\c                         const game_drawstate *ds,
 \c                         int x, int y, int button);
 
 This function receives user input and processes it. Its input
 \c                         int x, int y, int button);
 
 This function receives user input and processes it. Its input
@@ -868,6 +896,11 @@ indicating an arrow or function key or a mouse event; when
 coordinates of the mouse pointer relative to the top left of the
 puzzle's drawing area.
 
 coordinates of the mouse pointer relative to the top left of the
 puzzle's drawing area.
 
+(The pointer to the \c{game_drawstate} is marked \c{const}, because
+\c{interpret_move} should not write to it. The normal use of that
+pointer will be to read the game's tile size parameter in order to
+divide mouse coordinates by it.)
+
 \cw{interpret_move()} may return in three different ways:
 
 \b Returning \cw{NULL} indicates that no action whatsoever occurred
 \cw{interpret_move()} may return in three different ways:
 
 \b Returning \cw{NULL} indicates that no action whatsoever occurred
@@ -970,7 +1003,7 @@ any input value.
 
 \S{backend-execute-move} \cw{execute_move()}
 
 
 \S{backend-execute-move} \cw{execute_move()}
 
-\c game_state *(*execute_move)(game_state *state, char *move);
+\c game_state *(*execute_move)(const game_state *state, char *move);
 
 This function takes an input \c{game_state} and a move string as
 output from \cw{interpret_move()}. It returns a newly allocated
 
 This function takes an input \c{game_state} and a move string as
 output from \cw{interpret_move()}. It returns a newly allocated
@@ -994,8 +1027,8 @@ not even offer the \q{Solve} menu option.
 
 \S{backend-solve} \cw{solve()}
 
 
 \S{backend-solve} \cw{solve()}
 
-\c char *(*solve)(game_state *orig, game_state *curr,
-\c                char *aux, char **error);
+\c char *(*solve)(const game_state *orig, const game_state *curr,
+\c                const char *aux, char **error);
 
 This function is called when the user selects the \q{Solve} option
 from the menu.
 
 This function is called when the user selects the \q{Solve} option
 from the menu.
@@ -1015,9 +1048,11 @@ it may return \cw{NULL}. If it does this, it must also set
 \q{Solution not known for this puzzle}); that error message is not
 expected to be dynamically allocated.
 
 \q{Solution not known for this puzzle}); that error message is not
 expected to be dynamically allocated.
 
-If this function \e{does} produce a solution, it returns a move
-string suitable for feeding to \cw{execute_move()}
-(\k{backend-execute-move}).
+If this function \e{does} produce a solution, it returns a move string
+suitable for feeding to \cw{execute_move()}
+(\k{backend-execute-move}). Like a (non-empty) string returned from
+\cw{interpret_move()}, the returned string should be dynamically
+allocated.
 
 \H{backend-drawing} Drawing the game graphics
 
 
 \H{backend-drawing} Drawing the game graphics
 
@@ -1026,7 +1061,8 @@ drawing.
 
 \S{backend-new-drawstate} \cw{new_drawstate()}
 
 
 \S{backend-new-drawstate} \cw{new_drawstate()}
 
-\c game_drawstate *(*new_drawstate)(drawing *dr, game_state *state);
+\c game_drawstate *(*new_drawstate)(drawing *dr,
+\c                                  const game_state *state);
 
 This function allocates and returns a new \c{game_drawstate}
 structure for drawing a particular puzzle. It is passed a pointer to
 
 This function allocates and returns a new \c{game_drawstate}
 structure for drawing a particular puzzle. It is passed a pointer to
@@ -1076,7 +1112,7 @@ requesting a resize if that ever gets implemented).
 
 \S{backend-compute-size} \cw{compute_size()}
 
 
 \S{backend-compute-size} \cw{compute_size()}
 
-\c void (*compute_size)(game_params *params, int tilesize,
+\c void (*compute_size)(const game_params *params, int tilesize,
 \c                      int *x, int *y);
 
 This function is passed a \c{game_params} structure and a tile size.
 \c                      int *x, int *y);
 
 This function is passed a \c{game_params} structure and a tile size.
@@ -1087,7 +1123,7 @@ at that tile size.
 \S{backend-set-size} \cw{set_size()}
 
 \c void (*set_size)(drawing *dr, game_drawstate *ds,
 \S{backend-set-size} \cw{set_size()}
 
 \c void (*set_size)(drawing *dr, game_drawstate *ds,
-\c                  game_params *params, int tilesize);
+\c                  const game_params *params, int tilesize);
 
 This function is responsible for setting up a \c{game_drawstate} to
 draw at a given tile size. Typically this will simply involve
 
 This function is responsible for setting up a \c{game_drawstate} to
 draw at a given tile size. Typically this will simply involve
@@ -1136,7 +1172,8 @@ colour allocation policy.
 
 \S{backend-anim-length} \cw{anim_length()}
 
 
 \S{backend-anim-length} \cw{anim_length()}
 
-\c float (*anim_length)(game_state *oldstate, game_state *newstate,
+\c float (*anim_length)(const game_state *oldstate,
+\c                      const game_state *newstate,
 \c                      int dir, game_ui *ui);
 
 This function is called when a move is made, undone or redone. It is
 \c                      int dir, game_ui *ui);
 
 This function is called when a move is made, undone or redone. It is
@@ -1180,7 +1217,8 @@ state.
 
 \S{backend-flash-length} \cw{flash_length()}
 
 
 \S{backend-flash-length} \cw{flash_length()}
 
-\c float (*flash_length)(game_state *oldstate, game_state *newstate,
+\c float (*flash_length)(const game_state *oldstate,
+\c                       const game_state *newstate,
 \c                       int dir, game_ui *ui);
 
 This function is called when a move is completed. (\q{Completed}
 \c                       int dir, game_ui *ui);
 
 This function is called when a move is completed. (\q{Completed}
@@ -1224,33 +1262,41 @@ a mine from the colour it uses when you complete the game. In order
 to achieve this, its \cw{flash_length()} function has to store a
 flag in the \c{game_ui} to indicate which flash type is required.)
 
 to achieve this, its \cw{flash_length()} function has to store a
 flag in the \c{game_ui} to indicate which flash type is required.)
 
-\S{backend-is-solved} \cw{is_solved()}
+\S{backend-status} \cw{status()}
 
 
-\c int (*is_solved)(game_state *state);
+\c int (*status)(const game_state *state);
 
 
-This function returns \cw{TRUE} if the game represented by \cw{state}
-is currently in a solved state. The mid-end uses this to implement
-\cw{midend_is_solved()} (\k{midend-is-solved}).
+This function returns a status value indicating whether the current
+game is still in play, or has been won, or has been conclusively lost.
+The mid-end uses this to implement \cw{midend_status()}
+(\k{midend-status}).
 
 
-Front ends may wish to use this as a cue to proactively offer the
-option of starting a new game. Therefore, back ends should consider
-returning TRUE in situations where the game is \e{lost} as well as
-won, if losing makes it unlikely that the player would play on.
+The return value should be +1 if the game has been successfully
+solved. If the game has been lost in a situation where further play is
+unlikely, the return value should be -1. If neither is true (so play
+is still ongoing), return zero.
+
+Front ends may wish to use a non-zero status as a cue to proactively
+offer the option of starting a new game. Therefore, back ends should
+not return -1 if the game has been \e{technically} lost but undoing
+and continuing is still a realistic possibility.
 
 (For instance, games with hidden information such as Guess or Mines
 
 (For instance, games with hidden information such as Guess or Mines
-might well set this flag whenever they reveal the solution, whether or
-not the player guessed it correctly, on the grounds that a player
-would be unlikely to hide the solution and continue playing after the
-answer was spoiled. On the other hand, games where you can merely get
-into a dead end such as Same Game or Inertia might choose not to, on
-the grounds that the player would quite likely press Undo and carry on
-playing.)
+might well return a non-zero status whenever they reveal the solution,
+whether or not the player guessed it correctly, on the grounds that a
+player would be unlikely to hide the solution and continue playing
+after the answer was spoiled. On the other hand, games where you can
+merely get into a dead end such as Same Game or Inertia might choose
+to return 0 in that situation, on the grounds that the player would
+quite likely press Undo and carry on playing.)
 
 \S{backend-redraw} \cw{redraw()}
 
 \c void (*redraw)(drawing *dr, game_drawstate *ds,
 
 \S{backend-redraw} \cw{redraw()}
 
 \c void (*redraw)(drawing *dr, game_drawstate *ds,
-\c                game_state *oldstate, game_state *newstate, int dir,
-\c                game_ui *ui, float anim_time, float flash_time);
+\c                const game_state *oldstate,
+\c                const game_state *newstate,
+\c                int dir, const game_ui *ui,
+\c                float anim_time, float flash_time);
 
 This function is responsible for actually drawing the contents of
 the game window, and for redrawing every time the game state or the
 
 This function is responsible for actually drawing the contents of
 the game window, and for redrawing every time the game state or the
@@ -1322,7 +1368,7 @@ ignored.
 
 \S{backend-print-size} \cw{print_size()}
 
 
 \S{backend-print-size} \cw{print_size()}
 
-\c void (*print_size)(game_params *params, float *x, float *y);
+\c void (*print_size)(const game_params *params, float *x, float *y);
 
 This function is passed a \c{game_params} structure and a tile size.
 It returns, in \c{*x} and \c{*y}, the preferred size in
 
 This function is passed a \c{game_params} structure and a tile size.
 It returns, in \c{*x} and \c{*y}, the preferred size in
@@ -1333,7 +1379,7 @@ called.
 
 \S{backend-print} \cw{print()}
 
 
 \S{backend-print} \cw{print()}
 
-\c void (*print)(drawing *dr, game_state *state, int tilesize);
+\c void (*print)(drawing *dr, const game_state *state, int tilesize);
 
 This function is called when a puzzle is to be printed out on paper.
 It should use the drawing API functions (see \k{drawing}) to print
 
 This function is called when a puzzle is to be printed out on paper.
 It should use the drawing API functions (see \k{drawing}) to print
@@ -1408,7 +1454,7 @@ and \cw{text_format()} (\k{backend-text-format}) are never called.
 
 \S{backend-can-format-as-text-now} \c{can_format_as_text_now()}
 
 
 \S{backend-can-format-as-text-now} \c{can_format_as_text_now()}
 
-\c int (*can_format_as_text_now)(game_params *params);
+\c int (*can_format_as_text_now)(const game_params *params);
 
 This function is passed a \c{game_params} and returns a boolean,
 which is \cw{TRUE} if the game can support ASCII text output for
 
 This function is passed a \c{game_params} and returns a boolean,
 which is \cw{TRUE} if the game can support ASCII text output for
@@ -1434,7 +1480,7 @@ the game can be copied to the clipboard. Only the actual visible
 
 \S{backend-text-format} \cw{text_format()}
 
 
 \S{backend-text-format} \cw{text_format()}
 
-\c char *(*text_format)(game_state *state);
+\c char *(*text_format)(const game_state *state);
 
 This function is passed a \c{game_state}, and returns a newly
 allocated C string containing an ASCII representation of that game
 
 This function is passed a \c{game_state}, and returns a newly
 allocated C string containing an ASCII representation of that game
@@ -1455,7 +1501,7 @@ them internally. (There are currently no puzzles which have a
 one-line ASCII representation, so there's no precedent yet for
 whether that should come with a newline or not.)
 
 one-line ASCII representation, so there's no precedent yet for
 whether that should come with a newline or not.)
 
-\S{backend-wants-statusbar} \cw{wants_statusbar()}
+\S{backend-wants-statusbar} \cw{wants_statusbar}
 
 \c int wants_statusbar;
 
 
 \c int wants_statusbar;
 
@@ -1475,7 +1521,7 @@ called and need not do anything.
 
 \S{backend-timing-state} \cw{timing_state()}
 
 
 \S{backend-timing-state} \cw{timing_state()}
 
-\c int (*timing_state)(game_state *state, game_ui *ui);
+\c int (*timing_state)(const game_state *state, game_ui *ui);
 
 This function is passed the current \c{game_state} and the local
 \c{game_ui}; it returns \cw{TRUE} if the game timer should currently
 
 This function is passed the current \c{game_state} and the local
 \c{game_ui}; it returns \cw{TRUE} if the game timer should currently
@@ -1882,6 +1928,9 @@ Indeed, even horizontal or vertical lines may be anti-aliased.
 
 This function may be used for both drawing and printing.
 
 
 This function may be used for both drawing and printing.
 
+If the specified thickness is less than 1.0, 1.0 is used.
+This ensures that thin lines are visible even at small scales.
+
 \S{drawing-draw-text} \cw{draw_text()}
 
 \c void draw_text(drawing *dr, int x, int y, int fonttype,
 \S{drawing-draw-text} \cw{draw_text()}
 
 \c void draw_text(drawing *dr, int x, int y, int fonttype,
@@ -2708,14 +2757,12 @@ without closing the window...)
 
 Frees a mid-end structure and all its associated data.
 
 
 Frees a mid-end structure and all its associated data.
 
-\H{midend-tilesize} 
+\H{midend-tilesize} \cw{midend_tilesize()}
 
 \c int midend_tilesize(midend *me);
 
 Returns the \cq{tilesize} parameter being used to display the
 
 \c int midend_tilesize(midend *me);
 
 Returns the \cq{tilesize} parameter being used to display the
-current puzzle.
-
-\k{backend-preferred-tilesize}
+current puzzle (\k{backend-preferred-tilesize}).
 
 \H{midend-set-params} \cw{midend_set_params()}
 
 
 \H{midend-set-params} \cw{midend_set_params()}
 
@@ -2727,8 +2774,8 @@ these parameters until further notice.
 
 The usual way in which the front end will have an actual
 \c{game_params} structure to pass to this function is if it had
 
 The usual way in which the front end will have an actual
 \c{game_params} structure to pass to this function is if it had
-previously got it from \cw{midend_fetch_preset()}
-(\k{midend-fetch-preset}). Thus, this function is usually called in
+previously got it from \cw{midend_get_presets()}
+(\k{midend-get-presets}). Thus, this function is usually called in
 response to the user making a selection from the presets menu.
 
 \H{midend-get-params} \cw{midend_get_params()}
 response to the user making a selection from the presets menu.
 
 \H{midend-get-params} \cw{midend_get_params()}
@@ -2800,6 +2847,25 @@ to use scroll bars for large puzzles), you can pass dimensions of
 \cw{INT_MAX} as input to this function. You should probably not do
 that \e{and} set the \c{user_size} flag, though!
 
 \cw{INT_MAX} as input to this function. You should probably not do
 that \e{and} set the \c{user_size} flag, though!
 
+The midend relies on the frontend calling \cw{midend_new_game()}
+(\k{midend-new-game}) before calling \cw{midend_size()}.
+
+\H{midend-reset-tilesize} \cw{midend_reset_tilesize()}
+
+\c void midend_reset_tilesize(midend *me);
+
+This function resets the midend's preferred tile size to that of the
+standard puzzle.
+
+As discussed in \k{midend-size}, puzzle resizes are typically
+'sticky', in that once the user has dragged the puzzle to a different
+window size, the resulting tile size will be remembered and used when
+the puzzle configuration changes. If you \e{don't} want that, e.g. if
+you want to provide a command to explicitly reset the puzzle size back
+to its default, then you can call this just before calling
+\cw{midend_size()} (which, in turn, you would probably call with
+\c{user_size} set to \cw{FALSE}).
+
 \H{midend-new-game} \cw{midend_new_game()}
 
 \c void midend_new_game(midend *me);
 \H{midend-new-game} \cw{midend_new_game()}
 
 \c void midend_new_game(midend *me);
@@ -2836,7 +2902,8 @@ undo list (so that an accidental restart can be undone).
 
 This function automatically causes a redraw, i.e. the front end can
 expect its drawing API to be called from \e{within} a call to this
 
 This function automatically causes a redraw, i.e. the front end can
 expect its drawing API to be called from \e{within} a call to this
-function.
+function. Some back ends require that \cw{midend_size()}
+(\k{midend-size}) is called before \cw{midend_restart_game()}.
 
 \H{midend-force-redraw} \cw{midend_force_redraw()}
 
 
 \H{midend-force-redraw} \cw{midend_force_redraw()}
 
@@ -2847,7 +2914,8 @@ discarding the current \c{game_drawstate} and creating a new one
 from scratch before calling the game's \cw{redraw()} function.
 
 The front end can expect its drawing API to be called from within a
 from scratch before calling the game's \cw{redraw()} function.
 
 The front end can expect its drawing API to be called from within a
-call to this function.
+call to this function. Some back ends require that \cw{midend_size()}
+(\k{midend-size}) is called before \cw{midend_force_redraw()}.
 
 \H{midend-redraw} \cw{midend_redraw()}
 
 
 \H{midend-redraw} \cw{midend_redraw()}
 
@@ -2858,7 +2926,8 @@ calling the game's \cw{redraw()} function. (That is, the only things
 redrawn will be things that have changed since the last redraw.)
 
 The front end can expect its drawing API to be called from within a
 redrawn will be things that have changed since the last redraw.)
 
 The front end can expect its drawing API to be called from within a
-call to this function.
+call to this function. Some back ends require that \cw{midend_size()}
+(\k{midend-size}) is called before \cw{midend_redraw()}.
 
 \H{midend-process-key} \cw{midend_process_key()}
 
 
 \H{midend-process-key} \cw{midend_process_key()}
 
@@ -2928,34 +2997,63 @@ One of the major purposes of timing in the mid-end is to perform
 move animation. Therefore, calling this function is very likely to
 result in calls back to the front end's drawing API.
 
 move animation. Therefore, calling this function is very likely to
 result in calls back to the front end's drawing API.
 
-\H{midend-num-presets} \cw{midend_num_presets()}
+\H{midend-get-presets} \cw{midend_get_presets()}
 
 
-\c int midend_num_presets(midend *me);
+\c struct preset_menu *midend_get_presets(midend *me, int *id_limit);
 
 
-Returns the number of game parameter presets supplied by this game.
-Front ends should use this function and \cw{midend_fetch_preset()}
-to configure their presets menu rather than calling the back end
-directly, since the mid-end adds standard customisation facilities.
-(At the time of writing, those customisation facilities are
-implemented hackily by means of environment variables, but it's not
-impossible that they may become more full and formal in future.)
+Returns a data structure describing this game's collection of preset
+game parameters, organised into a hierarchical structure of menus and
+submenus.
 
 
-\H{midend-fetch-preset} \cw{midend_fetch_preset()}
+The return value is a pointer to a data structure containing the
+following fields (among others, which are not intended for front end
+use):
 
 
-\c void midend_fetch_preset(midend *me, int n,
-\c                          char **name, game_params **params);
+\c struct preset_menu {
+\c     int n_entries;
+\c     struct preset_menu_entry *entries;
+\c     /* and other things */
+\e     iiiiiiiiiiiiiiiiiiiiii
+\c };
 
 
-Returns one of the preset game parameter structures for the game. On
-input \c{n} must be a non-negative integer and less than the value
-returned from \cw{midend_num_presets()}. On output, \c{*name} is set
-to an ASCII string suitable for entering in the game's presets menu,
-and \c{*params} is set to the corresponding \c{game_params}
-structure.
+Those fields describe the intended contents of one particular menu in
+the hierarchy. \cq{entries} points to an array of \cq{n_entries}
+items, each of which is a structure containing the following fields:
 
 
-Both of the two output values are dynamically allocated, but they
-are owned by the mid-end structure: the front end should not ever
-free them directly, because they will be freed automatically during
-\cw{midend_free()}.
+\c struct preset_menu_entry {
+\c     char *title;
+\c     game_params *params;
+\c     struct preset_menu *submenu;
+\c     int id;
+\c };
+
+Of these fields, \cq{title} and \cq{id} are present in every entry,
+giving (respectively) the textual name of the menu item and an integer
+identifier for it. The integer id will correspond to the one returned
+by \c{midend_which_preset} (\k{midend-which-preset}), when that preset
+is the one selected.
+
+The other two fields are mutually exclusive. Each \c{struct
+preset_menu_entry} will have one of those fields \cw{NULL} and the
+other one non-null. If the menu item is an actual preset, then
+\cq{params} will point to the set of game parameters that go with the
+name; if it's a submenu, then \cq{submenu} instead will be non-null,
+and will point at a subsidiary \c{struct preset_menu}.
+
+The complete hierarchy of these structures is owned by the mid-end,
+and will be freed when the mid-end is freed. The front end should not
+attempt to free any of it.
+
+The integer identifiers will be allocated densely from 0 upwards, so
+that it's reasonable for the front end to allocate an array which uses
+them as indices, if it needs to store information per preset menu
+item. For this purpose, the front end may pass the second parameter
+\cq{id_limit} to \cw{midend_get_presets} as the address of an \c{int}
+variable, into which \cw{midend_get_presets} will write an integer one
+larger than the largest id number actually used (i.e. the number of
+elements the front end would need in the array).
+
+Submenu-type entries also have integer identifiers.
 
 \H{midend-which-preset} \cw{midend_which_preset()}
 
 
 \H{midend-which-preset} \cw{midend_which_preset()}
 
@@ -2967,6 +3065,10 @@ no preset matches. Front ends could use this to maintain a tick
 beside one of the items in the menu (or tick the \q{Custom} option
 if the return value is less than zero).
 
 beside one of the items in the menu (or tick the \q{Custom} option
 if the return value is less than zero).
 
+The returned index value (if non-negative) will match the \c{id} field
+of the corresponding \cw{struct preset_menu_entry} returned by
+\c{midend_get_presets()} (\k{midend-get-presets}).
+
 \H{midend-wants-statusbar} \cw{midend_wants_statusbar()}
 
 \c int midend_wants_statusbar(midend *me);
 \H{midend-wants-statusbar} \cw{midend_wants_statusbar()}
 
 \c int midend_wants_statusbar(midend *me);
@@ -3076,6 +3178,17 @@ Returns a descriptive game ID (i.e. one in the form
 \cq{params:description}) describing the game currently active in the
 mid-end. The returned string is dynamically allocated.
 
 \cq{params:description}) describing the game currently active in the
 mid-end. The returned string is dynamically allocated.
 
+\H{midend-get-random-seed} \cw{midend_get_random_seed()}
+
+\c char *midend_get_random_seed(midend *me)
+
+Returns a random game ID (i.e. one in the form \cq{params#seedstring})
+describing the game currently active in the mid-end, if there is one.
+If the game was created by entering a description, no random seed will
+currently exist and this function will return \cw{NULL}.
+
+The returned string, if it is non-\cw{NULL}, is dynamically allocated.
+
 \H{midend-can-format-as-text-now} \cw{midend_can_format_as_text_now()}
 
 \c int midend_can_format_as_text_now(midend *me);
 \H{midend-can-format-as-text-now} \cw{midend_can_format_as_text_now()}
 
 \c int midend_can_format_as_text_now(midend *me);
@@ -3116,20 +3229,22 @@ user.
 
 The front end can expect its drawing API and/or
 \cw{activate_timer()} to be called from within a call to this
 
 The front end can expect its drawing API and/or
 \cw{activate_timer()} to be called from within a call to this
-function.
+function.  Some back ends require that \cw{midend_size()}
+(\k{midend-size}) is called before \cw{midend_solve()}.
 
 
-\S{midend-is-solved} \cw{midend_is_solved()}
+\H{midend-status} \cw{midend_status()}
 
 
-\c int midend_is_solved(midend *me);
+\c int midend_status(midend *me);
 
 
-This function returns \cw{TRUE} if the midend is currently displaying
-a game in a solved state, according to the back end's \cw{is_solved()}
+This function returns +1 if the midend is currently displaying a game
+in a solved state, -1 if the game is in a permanently lost state, or 0
+otherwise. This function just calls the back end's \cw{status()}
 function. Front ends may wish to use this as a cue to proactively
 offer the option of starting a new game.
 
 function. Front ends may wish to use this as a cue to proactively
 offer the option of starting a new game.
 
-(See \k{backend-is-solved} for more detail about the back end's
-\cw{is_solved()} function and discussion of what should count as
-\q{solved} anyway).
+(See \k{backend-status} for more detail about the back end's
+\cw{status()} function and discussion of what should count as which
+status code.)
 
 \H{midend-can-undo} \cw{midend_can_undo()}
 
 
 \H{midend-can-undo} \cw{midend_can_undo()}
 
@@ -3206,12 +3321,63 @@ re-think the window size using \cw{midend_size()}, and probably
 cause a refresh using \cw{midend_redraw()}.
 
 Because each mid-end is tied to a specific game back end, this
 cause a refresh using \cw{midend_redraw()}.
 
 Because each mid-end is tied to a specific game back end, this
-function will fail if you attempt to read in a save file generated
-by a different game from the one configured in this mid-end, even if
-your application is a monolithic one containing all the puzzles. (It
-would be pretty easy to write a function which would look at a save
-file and determine which game it was for; any front end implementor
-who needs such a function can probably be accommodated.)
+function will fail if you attempt to read in a save file generated by
+a different game from the one configured in this mid-end, even if your
+application is a monolithic one containing all the puzzles. See
+\k{identify-game} for a helper function which will allow you to
+identify a save file before you instantiate your mid-end in the first
+place.
+
+\H{identify-game} \cw{identify_game()}
+
+\c char *identify_game(char **name,
+\c                     int (*read)(void *ctx, void *buf, int len),
+\c                     void *rctx);
+
+This function examines a serialised midend stream, of the same kind
+used by \cw{midend_serialise()} and \cw{midend_deserialise()}, and
+returns the \cw{name} field of the game back end from which it was
+saved.
+
+You might want this if your front end was a monolithic one containing
+all the puzzles, and you wanted to be able to load an arbitrary save
+file and automatically switch to the right game. Probably your next
+step would be to iterate through \cw{gamelist} (\k{frontend-backend})
+looking for a game structure whose \cw{name} field matched the
+returned string, and give an error if you didn't find one.
+
+On success, the return value of this function is \cw{NULL}, and the
+game name string is written into \cw{*name}. The caller should free
+that string after using it.
+
+On failure, \cw{*name} is \cw{NULL}, and the return value is an error
+message (which does not need freeing at all).
+
+(This isn't strictly speaking a midend function, since it doesn't
+accept or return a pointer to a midend. You'd probably call it just
+\e{before} deciding what kind of midend you wanted to instantiate.)
+
+\H{midend-request-id-changes} \cw{midend_request_id_changes()}
+
+\c void midend_request_id_changes(midend *me,
+\c                                void (*notify)(void *), void *ctx);
+
+This function is called by the front end to request notification by
+the mid-end when the current game IDs (either descriptive or
+random-seed) change. This can occur as a result of keypresses ('n' for
+New Game, for example) or when a puzzle supersedes its game
+description (see \k{backend-supersede}). After this function is
+called, any change of the game ids will cause the mid-end to call
+\cw{notify(ctx)} after the change.
+
+This is for use by puzzles which want to present the game description
+to the user constantly (e.g. as an HTML hyperlink) instead of only
+showing it when the user explicitly requests it.
+
+This is a function I anticipate few front ends needing to implement,
+so I make it a callback rather than a static function in order to
+relieve most front ends of the need to provide an empty
+implementation.
 
 \H{frontend-backend} Direct reference to the back end structure by
 the front end
 
 \H{frontend-backend} Direct reference to the back end structure by
 the front end
@@ -3433,6 +3599,63 @@ single element (typically measured using \c{sizeof}). \c{rs} is a
 \c{random_state} used to generate all the random numbers for the
 shuffling process.
 
 \c{random_state} used to generate all the random numbers for the
 shuffling process.
 
+\H{utils-presets} Presets menu management
+
+The function \c{midend_get_presets()} (\k{midend-get-presets}) returns
+a data structure describing a menu hierarchy. Back ends can also
+choose to provide such a structure to the mid-end, if they want to
+group their presets hierarchically. To make this easy, there are a few
+utility functions to construct preset menu structures, and also one
+intended for front-end use.
+
+\S{utils-preset-menu-new} \cw{preset_menu_new()}
+
+\c struct preset_menu *preset_menu_new(void);
+
+Allocates a new \c{struct preset_menu}, and initialises it to hold no
+menu items.
+
+\S{utils-preset-menu-add_submenu} \cw{preset_menu_add_submenu()}
+
+\c struct preset_menu *preset_menu_add_submenu
+\c     (struct preset_menu *parent, char *title);
+
+Adds a new submenu to the end of an existing preset menu, and returns
+a pointer to a newly allocated \c{struct preset_menu} describing the
+submenu.
+
+The string parameter \cq{title} must be dynamically allocated by the
+caller. The preset-menu structure will take ownership of it, so the
+caller must not free it.
+
+\S{utils-preset-menu-add-preset} \cw{preset_menu_add_preset()}
+
+\c void preset_menu_add_preset
+\c     (struct preset_menu *menu, char *title, game_params *params);
+
+Adds a preset game configuration to the end of a preset menu.
+
+Both the string parameter \cq{title} and the game parameter structure
+\cq{params} itself must be dynamically allocated by the caller. The
+preset-menu structure will take ownership of it, so the caller must
+not free it.
+
+\S{utils-preset-menu-lookup-by-id} \cw{preset_menu_lookup_by_id()}
+
+\c game_params *preset_menu_lookup_by_id
+\c     (struct preset_menu *menu, int id);
+
+Given a numeric index, searches recursively through a preset menu
+hierarchy to find the corresponding menu entry, and returns a pointer
+to its existing \c{game_params} structure.
+
+This function is intended for front end use (but front ends need not
+use it if they prefer to do things another way). If a front end finds
+it inconvenient to store anything more than a numeric index alongside
+each menu item, then this function provides an easy way for the front
+end to get back the actual game parameters corresponding to a menu
+item that the user has selected.
+
 \H{utils-alloc} Memory allocation
 
 Puzzles has some central wrappers on the standard memory allocation
 \H{utils-alloc} Memory allocation
 
 Puzzles has some central wrappers on the standard memory allocation