+ struct preset_menu *menu = snew(struct preset_menu);
+ menu->n_entries = 0;
+ menu->entries_size = 0;
+ menu->entries = NULL;
+ return menu;
+}
+
+static struct preset_menu_entry *preset_menu_add(struct preset_menu *menu,
+ char *title)
+{
+ struct preset_menu_entry *toret;
+ if (menu->n_entries >= menu->entries_size) {
+ menu->entries_size = menu->n_entries * 5 / 4 + 10;
+ menu->entries = sresize(menu->entries, menu->entries_size,
+ struct preset_menu_entry);
+ }
+ toret = &menu->entries[menu->n_entries++];
+ toret->title = title;
+ toret->params = NULL;
+ toret->submenu = NULL;
+ return toret;
+}
+
+struct preset_menu *preset_menu_add_submenu(struct preset_menu *parent,
+ char *title)
+{
+ struct preset_menu_entry *entry = preset_menu_add(parent, title);
+ entry->submenu = preset_menu_new();
+ return entry->submenu;
+}
+
+void preset_menu_add_preset(struct preset_menu *parent,
+ char *title, game_params *params)
+{
+ struct preset_menu_entry *entry = preset_menu_add(parent, title);
+ entry->params = params;
+}
+
+game_params *preset_menu_lookup_by_id(struct preset_menu *menu, int id)
+{
+ int i;
+ game_params *retd;
+
+ for (i = 0; i < menu->n_entries; i++) {
+ if (id == menu->entries[i].id)
+ return menu->entries[i].params;
+ if (menu->entries[i].submenu &&
+ (retd = preset_menu_lookup_by_id(
+ menu->entries[i].submenu, id)) != NULL)
+ return retd;
+ }
+
+ return NULL;
+}
+
+static char *preset_menu_add_from_user_env(
+ midend *me, struct preset_menu *menu, char *p, int top_level)
+{
+ while (*p) {
+ char *name, *val;