void nds_config_key() { int prev_held = 0; int held = 0; nds_cmd_t cmd; char buf[BUFSZ]; u16 key; char command[INPUT_BUFFER_SIZE]; nds_flush(0); nds_draw_prompt("Press the key to modify."); while (1) { swiWaitForVBlank(); scanKeys(); prev_held = held; held = nds_keysHeld(); /* We don't let the user configure these */ if ((prev_held & chord_keys) && (held == 0) && (nds_count_bits(prev_held) == 1)) { key = prev_held; break; } else if ((held & cmd_key) || ((held & ~chord_keys) == 0)) { continue; } else if (held) { key = held; break; } } nds_clear_prompt(); cmd = nds_get_config_cmd(key); if (cmd.f_char < 0) { return; } command[0] = cmd.f_char; command[1] = '\0'; if (! nds_input_buffer_is_empty()) { strcat(command, nds_input_buffer_shiftall()); DEBUG_PRINT("cmd: %s\n", command); sprintf(buf, "Mapped %s to %s x%s.", nds_key_to_string(key), cmd.name, command); } else { sprintf(buf, "Mapped %s to %s.", nds_key_to_string(key), cmd.name); } nds_add_keymap_entry(key, command); clear_nhwindow(WIN_MESSAGE); putstr(WIN_MESSAGE, ATR_NONE, buf); nds_save_key_config(); nds_flush(0); }
/* * Generic yes/no function. 'def' is the default (returned by space or * return; 'esc' returns 'q', or 'n', or the default, depending on * what's in the string. The 'query' string is printed before the user * is asked about the string. * If resp is NULL, any single character is accepted and returned. * If not-NULL, only characters in it are allowed (exceptions: the * quitchars are always allowed, and if it contains '#' then digits * are allowed); if it includes an <esc>, anything beyond that won't * be shown in the prompt to the user but will be acceptable as input. */ char nds_yn_function(const char *ques, const char *cstr, CHAR_P def) { char buffer[INPUT_BUFFER_SIZE]; char *choices; ANY_P header_id; ANY_P *ids; winid win; menu_item *sel = NULL; int ret; int yn = 0; int ynaq = 0; char *direction_keys = nds_get_direction_keys(); if ((strstr(ques, "In what direction") != NULL) || (strstr(ques, "in what direction") != NULL)) { /* * We're going to use nh_poskey to get a command from the user. However, * we must handle clicks specially. Unlike normal movement, you can't * just click anywhere to pick a direction. Instead, the user will be * expected to click in one of the adjacent squares around the player, * and the click will then be translated into a movement character. */ while (1) { int x, y, mod; int sym; nds_draw_prompt("Tap an adjacent square or press a direction key."); nds_flush(0); sym = nds_get_input(&x, &y, &mod); nds_clear_prompt(); if (mod == CLICK_1) { if ((x == u.ux - 1) && (y == u.uy - 1)) { return direction_keys[DIR_UP_LEFT]; } else if ((x == u.ux) && (y == u.uy - 1)) { return direction_keys[DIR_UP]; } else if ((x == u.ux + 1) && (y == u.uy - 1)) { return direction_keys[DIR_UP_RIGHT]; } else if ((x == u.ux - 1) && (y == u.uy)) { return direction_keys[DIR_LEFT]; } else if ((x == u.ux) && (y == u.uy)) { return direction_keys[DIR_WAIT]; } else if ((x == u.ux + 1) && (y == u.uy)) { return direction_keys[DIR_RIGHT]; } else if ((x == u.ux - 1) && (y == u.uy + 1)) { return direction_keys[DIR_DOWN_LEFT]; } else if ((x == u.ux) && (y == u.uy + 1)) { return direction_keys[DIR_DOWN]; } else if ((x == u.ux + 1) && (y == u.uy + 1)) { return direction_keys[DIR_DOWN_RIGHT]; } } else if (mod == CLICK_2) { if ((x == u.ux) && (y == u.uy)) { return '>'; } } else { return sym; } } } else if (! iflags.cmdwindow) { return nds_prompt_char(ques, cstr, 0); } else if (strstr(ques, "Adjust letter to what") != NULL) { return nds_prompt_char(ques, cstr, 0); } else if (strstr(ques, "What command?") != NULL) { nds_cmd_t cmd; nds_draw_prompt("Select a command."); nds_flush(0); cmd = nds_cmd_loop(CMDLOOP_WHATDOES); nds_clear_prompt(); return cmd.f_char; } else if (strstr(ques, "What do you look for?") != NULL) { return nds_prompt_char(ques, cstr, 0); } else if (strstr(ques, "adjust?") != NULL) { cstr = ynchars; } if ((index(ques, '[') == NULL) && (cstr == NULL)) { nds_draw_prompt(ques); return '*'; } win = create_nhwindow(NHW_MENU); start_menu(win); if ((cstr != NULL) && ((strcasecmp(cstr, ynchars) == 0) || (strcasecmp(cstr, ynqchars) == 0) || ((ynaq = strcasecmp(cstr, ynaqchars)) == 0))) { ids = (ANY_P *)malloc(sizeof(ANY_P) * 2); yn = 1; ids[0].a_int = 'y'; ids[1].a_int = 'n'; add_menu(win, NO_GLYPH, &(ids[0]), 0, 0, 0, "Yes", 0); add_menu(win, NO_GLYPH, &(ids[1]), 0, 0, 0, "No", 0); if (ynaq) { ids[2].a_int = 'a'; add_menu(win, NO_GLYPH, &(ids[2]), 0, 0, 0, "All", 0); } } else if ((cstr != NULL) && (strcasecmp(cstr, "rl") == 0)) { ids = (ANY_P *)malloc(sizeof(ANY_P) * 2); ids[0].a_int = 'r'; ids[1].a_int = 'l'; add_menu(win, NO_GLYPH, &(ids[0]), 0, 0, 0, "Right Hand", 0); add_menu(win, NO_GLYPH, &(ids[1]), 0, 0, 0, "Left Hand", 0); } else { int i; char curclass = -1; choices = _nds_parse_choices(ques); ids = (ANY_P *)malloc(sizeof(ANY_P) * strlen(choices)); header_id.a_int = 0; for (i = 0; i < strlen(choices); i++) { ids[i].a_int = choices[i]; if (choices[i] == ' ') { add_menu(win, NO_GLYPH, &(header_id), 0, 0, 0, "Other", 0); } else if (choices[i] == '*') { add_menu(win, NO_GLYPH, &(ids[i]), 0, 0, 0, "Something from your inventory", 0); } else if ((choices[i] == '-') || (choices[i] == '.')) { add_menu(win, NO_GLYPH, &(ids[i]), 0, 0, 0, "Nothing/your finger", 0); } else if (choices[i] == '?') { continue; } else { int oclass; char oname[BUFSZ]; if (choices[i] == '$') { oclass = COIN_CLASS; sprintf(oname, "%ld gold piece%s", u.ugold, plur(u.ugold)); } else { struct obj *otmp = obj_for_let(choices[i]); oclass = otmp->oclass; strcpy(oname, doname(otmp)); } if (oclass != curclass) { add_menu(win, NO_GLYPH, &(header_id), 0, 0, 0, let_to_name(oclass, FALSE), 0); curclass = oclass; } add_menu(win, NO_GLYPH, &(ids[i]), 0, 0, 0, oname, 0); } } } end_menu(win, ques); int mode = ((cstr == NULL) || (index(cstr, '#') != NULL)) ? PICK_ONE_TYPE : PICK_ONE; int cnt = select_menu(win, mode, &sel); if (cnt <= 0) { ret = yn ? 'n' : '\033'; } else if ((mode == PICK_ONE) || (sel->count < 0)) { ret = sel->item.a_int; } else if (mode == PICK_ONE_TYPE) { sprintf(buffer, "%d%c", sel->count, sel->item.a_int); nds_input_buffer_append(buffer + 1); ret = *buffer; } if (sel != NULL) { free(sel); } free(ids); destroy_nhwindow(win); return ret; }
nds_cmd_t nds_get_config_cmd(u16 key) { winid win; menu_item *sel; ANY_P ids[15]; nds_cmd_t cmd; char tmp[BUFSZ]; int res; win = create_nhwindow(NHW_MENU); start_menu(win); ids[0].a_int = 1; ids[1].a_int = 2; ids[2].a_int = 3; ids[3].a_int = 4; ids[4].a_int = 5; add_menu(win, NO_GLYPH, &(ids[0]), 0, 0, 0, "Movement", 0); add_menu(win, NO_GLYPH, &(ids[1]), 0, 0, 0, "Game Command", 0); add_menu(win, NO_GLYPH, &(ids[2]), 0, 0, 0, "Toggle Option", 0); add_menu(win, NO_GLYPH, &(ids[3]), 0, 0, 0, "Map Panning", 0); add_menu(win, NO_GLYPH, &(ids[4]), 0, 0, 0, "No Command", 0); sprintf(tmp, "What do you want to assign to %s?", nds_key_to_string(key)); end_menu(win, tmp); res = select_menu(win, PICK_ONE, &sel); destroy_nhwindow(win); if (res <= 0) { cmd.f_char = -1; cmd.name = NULL; } else { switch (sel->item.a_int) { case 1: cmd = nds_get_direction(); break; case 2: nds_flush(0); cmd = nds_cmd_loop(CMDLOOP_CONFIG); break; case 3: { const char *tmp = nds_get_bool_option(); if (tmp != NULL) { cmd.f_char = CMD_OPT_TOGGLE; cmd.name = "Toggle Option"; nds_input_buffer_append((char *)tmp); } else { cmd.f_char = -1; cmd.name = NULL; } } break; case 4: cmd = nds_get_pan_direction(); break; case 5: nds_flush(0); cmd.f_char = 0; cmd.name = NULL; break; } } NULLFREE(sel); return cmd; }