X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?a=blobdiff_plain;f=devel.but;h=25a6c62dfa5d3fb198a35c0432e8523cfd9993fb;hb=db313b3948d27244dd7c34c2609c66d6204d8931;hp=e95e1d2ded0c6b71523380e9dea92b7c290f9f52;hpb=0b93de904a98f119b1a95d3a53029f1ed4bfb9b3;p=sgt-puzzles.git diff --git a/devel.but b/devel.but index e95e1d2..25a6c62 100644 --- 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); -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 @@ -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 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()} -\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 @@ -493,7 +521,7 @@ allocations contained within it. \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 @@ -511,7 +539,7 @@ and \k{backend-custom-params} for more details. \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 @@ -586,7 +614,7 @@ function is never called and need not do anything at all. \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 @@ -611,7 +639,7 @@ function is never called and need not do anything at all. \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 @@ -696,7 +724,7 @@ again in the game description. \S{backend-validate-desc} \cw{validate_desc()} -\c char *(*validate_desc)(const 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. @@ -720,8 +748,8 @@ non-dynamically-allocated C string containing an error message. \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} @@ -749,7 +777,7 @@ game states and it had to go in one section or the other.) \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 @@ -766,7 +794,7 @@ allocations contained within it. \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 @@ -782,7 +810,7 @@ allocations contained within it. \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 @@ -806,7 +834,7 @@ source.) \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} @@ -814,8 +842,8 @@ structure. \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: @@ -855,7 +883,7 @@ producing new \c{game_state}s. \S{backend-interpret-move} \cw{interpret_move()} -\c char *(*interpret_move)(game_state *state, game_ui *ui, +\c char *(*interpret_move)(const game_state *state, game_ui *ui, \c const game_drawstate *ds, \c int x, int y, int button); @@ -975,7 +1003,7 @@ any input value. \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 @@ -999,8 +1027,8 @@ not even offer the \q{Solve} menu option. \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. @@ -1020,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. -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 @@ -1031,7 +1061,8 @@ drawing. \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 @@ -1081,7 +1112,7 @@ requesting a resize if that ever gets implemented). \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. @@ -1092,7 +1123,7 @@ at that tile size. \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 @@ -1141,7 +1172,8 @@ colour allocation policy. \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 @@ -1185,7 +1217,8 @@ state. \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} @@ -1231,7 +1264,7 @@ flag in the \c{game_ui} to indicate which flash type is required.) \S{backend-status} \cw{status()} -\c int (*status)(game_state *state); +\c int (*status)(const game_state *state); This function returns a status value indicating whether the current game is still in play, or has been won, or has been conclusively lost. @@ -1260,8 +1293,10 @@ quite likely press Undo and carry on playing.) \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 @@ -1333,7 +1368,7 @@ ignored. \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 @@ -1344,7 +1379,7 @@ called. \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 @@ -1419,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()} -\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 @@ -1445,7 +1480,7 @@ the game can be copied to the clipboard. Only the actual visible \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 @@ -1486,7 +1521,7 @@ called and need not do anything. \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 @@ -1893,6 +1928,9 @@ Indeed, even horizontal or vertical lines may be anti-aliased. 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, @@ -2736,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 -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()} @@ -2959,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. -\H{midend-num-presets} \cw{midend_num_presets()} +\H{midend-get-presets} \cw{midend_get_presets()} + +\c struct preset_menu *midend_get_presets(midend *me, int *id_limit); -\c int midend_num_presets(midend *me); +Returns a data structure describing this game's collection of preset +game parameters, organised into a hierarchical structure of menus and +submenus. -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.) +The return value is a pointer to a data structure containing the +following fields (among others, which are not intended for front end +use): -\H{midend-fetch-preset} \cw{midend_fetch_preset()} +\c struct preset_menu { +\c int n_entries; +\c struct preset_menu_entry *entries; +\c /* and other things */ +\e iiiiiiiiiiiiiiiiiiiiii +\c }; -\c void midend_fetch_preset(midend *me, int n, -\c char **name, game_params **params); +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: -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. +\c struct preset_menu_entry { +\c char *title; +\c game_params *params; +\c struct preset_menu *submenu; +\c int id; +\c }; -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()}. +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()} @@ -2998,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). +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); @@ -3528,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. +\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