- /*
- * For C_STRING, `sval' is always dynamically allocated and
- * non-NULL. For C_BOOLEAN and C_END, `sval' is always NULL.
- * For C_CHOICES, `sval' is non-NULL, _not_ dynamically
- * allocated, and contains a set of option strings separated by
- * a delimiter. The delimeter is also the first character in
- * the string, so for example ":Foo:Bar:Baz" gives three
- * options `Foo', `Bar' and `Baz'.
- */
- char *sval;
- /*
- * For C_BOOLEAN, this is TRUE or FALSE. For C_CHOICES, it
- * indicates the chosen index from the `sval' list. In the
- * above example, 0==Foo, 1==Bar and 2==Baz.
- */
- int ival;
+ union {
+ struct { /* if type == C_STRING */
+ /* Always dynamically allocated and non-NULL */
+ char *sval;
+ } string;
+ struct { /* if type == C_CHOICES */
+ /*
+ * choicenames is non-NULL, not dynamically allocated, and
+ * contains a set of option strings separated by a
+ * delimiter. The delimiter is also the first character in
+ * the string, so for example ":Foo:Bar:Baz" gives three
+ * options `Foo', `Bar' and `Baz'.
+ */
+ const char *choicenames;
+ /*
+ * Indicates the chosen index from the options in
+ * choicenames. In the above example, 0==Foo, 1==Bar and
+ * 2==Baz.
+ */
+ int selected;
+ } choices;
+ struct {
+ /* just TRUE or FALSE */
+ int bval;
+ } boolean;
+ } u;
+};
+
+/*
+ * Structure used to communicate the presets menu from midend to
+ * frontend. In principle, it's also used to pass the same information
+ * from game to midend, though games that don't specify a menu
+ * hierarchy (i.e. most of them) will use the simpler fetch_preset()
+ * function to return an unstructured list.
+ *
+ * A tree of these structures always belongs to the midend, and only
+ * the midend should ever need to free it. The front end should treat
+ * them as read-only.
+ */
+struct preset_menu_entry {
+ char *title;
+ /* Exactly one of the next two fields is NULL, depending on
+ * whether this entry is a submenu title or an actual preset */
+ game_params *params;
+ struct preset_menu *submenu;
+ /* Every preset menu entry has a number allocated by the mid-end,
+ * so that midend_which_preset() can return a value that
+ * identifies an entry anywhere in the menu hierarchy. The values
+ * will be allocated reasonably densely from 1 upwards (so it's
+ * reasonable for the front end to use them as array indices if it
+ * needs to store GUI state per menu entry), but no other
+ * guarantee is given about their ordering.
+ *
+ * Entries containing submenus have ids too - not only the actual
+ * presets are numbered. */
+ int id;