/* get a new value of the appropriate type for the given option */ static nh_bool get_option_value(struct win_menu *mdat, int idx) { char buf[BUFSZ], query[BUFSZ]; union nh_optvalue value; struct nh_option_desc *option, *optlist; int listid = mdat->items[idx].id >> 10; int id = mdat->items[idx].id & 0x1ff; char strbuf[BUFSZ]; int prev_optstyle = settings.optstyle; switch (listid) { case ACT_BIRTH_OPTS: optlist = nh_get_options(ACTIVE_BIRTH_OPTIONS); break; case CUR_BIRTH_OPTS: optlist = nh_get_options(CURRENT_BIRTH_OPTIONS); break; case GAME_OPTS: optlist = nh_get_options(GAME_OPTIONS); break; case UI_OPTS: optlist = curses_options; break; default: return FALSE; } option = &optlist[id]; value.s = strbuf; switch ((int)option->type) { case OPTTYPE_BOOL: select_boolean_value(&value, option); break; case OPTTYPE_INT: sprintf(query, "New value for %s (number from %d to %d)", option->name, option->i.min, option->i.max); sprintf(buf, "%d", value.i); curses_getline(query, buf); if (buf[0] == '\033') return FALSE; sscanf(buf, "%d", &value.i); break; case OPTTYPE_ENUM: select_enum_value(&value, option); break; case OPTTYPE_STRING: sprintf(query, "New value for %s (text)", option->name); curses_getline(query, value.s); if (value.s[0] == '\033') return FALSE; break; case OPTTYPE_AUTOPICKUP_RULES: show_autopickup_menu(option); return FALSE; case OPTTYPE_MSGTYPE: show_msgtype_menu(option); return FALSE; case OPTTYPE_KEYMAP: show_keymap_menu(FALSE); return FALSE; default: return FALSE; } if (!nh_set_option(option->name, value, FALSE)) { sprintf(strbuf, "new value for %s rejected", option->name); curses_msgwin(strbuf); } else print_option_string(option, mdat->items[idx].caption); /* special case: directly redo option menu appearance */ if (settings.optstyle != prev_optstyle) return TRUE; return FALSE; }
/* get a new value of the appropriate type for the given option */ static nh_bool query_new_value(struct win_menu *mdat, int idx) { struct nh_option_desc *option, *optlist; struct nh_option_desc optioncopy; struct nh_option_desc *optioncopy_p = &optioncopy; int listid = mdat->items[idx].id >> 10; int id = mdat->items[idx].id & 0x1ff; int prev_optstyle = settings.optstyle; enum nh_menupaging prev_menupaging = settings.menupaging; nh_bool prev_menuborder = settings.whichframes != FRAME_NONE; nh_bool ret = FALSE; switch (listid) { case BIRTH_OPTS: case CREATION_OPTS: case GAME_OPTS: optlist = curses_get_nh_opts(); break; case UI_OPTS: optlist = curses_options; break; default: return FALSE; } option = &optlist[id]; /* optioncopy holds the new option we're planning to set */ optioncopy = *option; switch ((int)optioncopy.type) { case OPTTYPE_BOOL: select_boolean_value(&optioncopy.value, &optioncopy); break; case OPTTYPE_INT: if (optioncopy.i.min >= -2147483647-1 && optioncopy.i.max <= 2147483647) { /* Maximum length of a number as text is 11 chars */ char query[11 + 1 + strlen(optioncopy.name) + sizeof "New value for (number from to )"]; sprintf(query, "New value for %s (number from %d to %d)", optioncopy.name, optioncopy.i.min, optioncopy.i.max); curses_getline(query, &optioncopy_p, getlin_option_callback); } break; case OPTTYPE_ENUM: select_enum_value(&optioncopy.value, option); break; case OPTTYPE_STRING: if (!strcmp(optioncopy.name, "tileset")) { select_tileset_value(&optioncopy.value, option); } else { char query[strlen(optioncopy.name) + 1 + sizeof "New value for (text)"]; sprintf(query, "New value for %s (text)", optioncopy.name); optioncopy.value.s = NULL; curses_getline(query, &optioncopy_p, getlin_option_callback); } break; case OPTTYPE_AUTOPICKUP_RULES: show_autopickup_menu(option); goto free; case OPTTYPE_KEYMAP: show_keymap_menu(FALSE); goto free; default: goto free; } /* getlin_option_callback NULLs out optioncopy_p to indicate that setting was cancelled */ if (optioncopy_p && !curses_set_option(optioncopy.name, optioncopy.value)) { char query[strlen(optioncopy.name) + 1 + sizeof "new value for rejected"]; sprintf(query, "new value for %s rejected", optioncopy.name); curses_msgwin(query, krc_notification); } else if (optioncopy_p) { if (listid != UI_OPTS) { curses_free_nh_opts(optlist); optlist = curses_get_nh_opts(); option = &optlist[id]; } print_option_string(option, mdat->items[idx].caption); } /* We need to deallocate any string that might have been allocated by the getlin callback. */ if (optioncopy.type == OPTTYPE_STRING && optioncopy.value.s) free(optioncopy.value.s); /* If we're changing the option menu appearance, or if we changed game options, we need to reload and redraw the menu. */ if (settings.optstyle != prev_optstyle || settings.menupaging != prev_menupaging || (settings.whichframes != FRAME_NONE) != prev_menuborder || (game_is_running && listid != UI_OPTS)) ret = TRUE; free: if (listid != UI_OPTS) curses_free_nh_opts(optlist); return ret; }