void macro_recorder_stop() { char *str, *macro; char buf[1024]; /* Ok we remove the last key, because it is the key to stop recording */ macro_recorder_current[strlen(macro_recorder_current) - 1] = '\0'; /* Stop the recording */ macro = macro_recorder_current; macro_recorder_current = NULL; /* Add it */ if (get_check("Are you satisfied and want to create the macro? ")) { prt("Trigger: ", 0, 0); /* Get a macro trigger */ do_cmd_macro_aux(buf, FALSE); /* Link the macro */ macro_add(buf, macro); /* Prompt */ C_MAKE(str, (strlen(macro) + 1) * 3, char); ascii_to_text(str, macro); msg_format("Added a macro '%s', if you want it to stay permanently press @ now and dump macros to a file.", str); C_FREE(str, (strlen(macro) + 1) * 3, char); }
/* * Process a keypress event * * Also appears in "main-x11.c". */ static void react_keypress(XKeyEvent *xev) { int i, n, mc, ms, mo, mx; uint ks1; XKeyEvent *ev = (XKeyEvent*)(xev); KeySym ks; char buf[128]; char msg[128]; /* Check for "normal" keypresses */ n = XLookupString(ev, buf, 125, &ks, NULL); /* Terminate */ buf[n] = '\0'; /* Hack -- Ignore "modifier keys" */ if (IsModifierKey(ks)) return; /* Hack -- convert into an unsigned int */ ks1 = (uint)(ks); /* Extract four "modifier flags" */ mc = (ev->state & ControlMask) ? TRUE : FALSE; ms = (ev->state & ShiftMask) ? TRUE : FALSE; mo = (ev->state & Mod1Mask) ? TRUE : FALSE; mx = (ev->state & Mod2Mask) ? TRUE : FALSE; /* Normal keys with no modifiers */ if (n && !mo && !mx && !IsSpecialKey(ks)) { /* Enqueue the normal key(s) */ for (i = 0; buf[i]; i++) Term_keypress(buf[i]); /* All done */ return; } /* Handle a few standard keys (bypass modifiers) XXX XXX XXX */ switch (ks1) { case XK_Escape: { Term_keypress(ESCAPE); return; } case XK_Return: { Term_keypress('\r'); return; } case XK_Tab: { Term_keypress('\t'); return; } case XK_Delete: case XK_BackSpace: { Term_keypress('\010'); return; } } /* Hack -- Use the KeySym */ if (ks) { sprintf(msg, "%c%s%s%s%s_%lX%c", 31, mc ? "N" : "", ms ? "S" : "", mo ? "O" : "", mx ? "M" : "", (unsigned long)(ks), 13); } /* Hack -- Use the Keycode */ else { sprintf(msg, "%c%s%s%s%sK_%X%c", 31, mc ? "N" : "", ms ? "S" : "", mo ? "O" : "", mx ? "M" : "", ev->keycode, 13); } /* Enqueue the "macro trigger" string */ for (i = 0; msg[i]; i++) Term_keypress(msg[i]); /* Hack -- auto-define macros as needed */ if (n && (macro_find_exact(msg) < 0)) { /* Create a macro */ macro_add(msg, buf); } }
int main(int argc, char **argv) { char *infname, *outfname; int ret = 0; enum { NONE, MACROS, MACROS_WHERE, STATS, DEPS } dump = NONE; int i; int platform_win32 = 0; int freestanding = 0; infname = outfname = NULL; current_line = 1; current_fname = FNAME_BUILTIN; macro_add_limits(); for(i = 0; initial_defs[i].nam; i++){ if(initial_defs[i].is_fn) macro_add_func(initial_defs[i].nam, initial_defs[i].val, NULL, 0, 1); else macro_add(initial_defs[i].nam, initial_defs[i].val, 0); } switch(platform_type()){ case PLATFORM_x86_64: macro_add("__LP64__", "1", 0); macro_add("__x86_64__", "1", 0); /* TODO: __i386__ for 32 bit */ break; case PLATFORM_mipsel_32: macro_add("__MIPS__", "1", 0); } if(platform_bigendian()) macro_add("__BYTE_ORDER__", "__ORDER_BIG_ENDIAN__", 0); else macro_add("__BYTE_ORDER__", "__ORDER_LITTLE_ENDIAN__", 0); switch(platform_sys()){ #define MAP(t, s) case t: macro_add(s, "1", 0); break MAP(PLATFORM_LINUX, "__linux__"); MAP(PLATFORM_FREEBSD, "__FreeBSD__"); #undef MAP case PLATFORM_DARWIN: macro_add("__DARWIN__", "1", 0); macro_add("__MACH__", "1", 0); /* TODO: proper detection for these */ macro_add("__APPLE__", "1", 0); break; case PLATFORM_CYGWIN: macro_add("__CYGWIN__", "1", 0); platform_win32 = 1; break; } macro_add("__WCHAR_TYPE__", platform_win32 ? "short" : "int", 0); macro_add_sprintf("__BIGGEST_ALIGNMENT__", "%u", platform_align_max()); current_fname = FNAME_CMDLINE; for(i = 1; i < argc && *argv[i] == '-'; i++){ if(!strcmp(argv[i]+1, "-")) break; switch(argv[i][1]){ case 'I': if(argv[i][2]) include_add_dir(argv[i]+2); else goto usage; break; case 'o': if(outfname) goto usage; if(argv[i][2]) outfname = argv[i] + 2; else if(++i < argc) outfname = argv[i]; else goto usage; break; case 'P': option_line_info = 0; break; case 'C': if(argv[i][2] == '\0') strip_comments = STRIP_EXCEPT_DIRECTIVE; else if(!strcmp(argv[i] + 2, "C")) strip_comments = STRIP_NONE; break; case 'M': if(!strcmp(argv[i] + 2, "M")){ dump = DEPS; no_output = 1; }else{ goto usage; } break; case 'D': { char *arg = argv[i] + 2; char *eq; char *directive; if(!*arg){ /* allow "-D" "arg" */ arg = argv[++i]; if(!arg) goto usage; } /* -D'yo yo' means #define yo yo 1, that is, * we literally generate the #define line */ eq = strchr(arg, '='); if(eq) *eq = '\0'; directive = ustrprintf( "define %s %s", arg, eq ? eq + 1 : "1"); parse_internal_directive(directive); free(directive); break; } case 'U': if(!argv[i][2]) goto usage; macro_remove(argv[i] + 2); break; case 'd': if(argv[i][2] && argv[i][3]) goto defaul; switch(argv[i][2]){ case 'M': case 'S': case 'W': /* list #defines */ dump = ( argv[i][2] == 'M' ? MACROS : argv[i][2] == 'S' ? STATS : MACROS_WHERE); no_output = 1; break; case '\0': option_trace = 1; break; default: goto usage; } break; case '\0': /* we've been passed "-" as a filename */ break; case 'f': if(!strcmp(argv[i]+2, "freestanding")){ freestanding = 1; }else if(!strncmp(argv[i]+2, "message-length=", 15)){ const char *p = argv[i] + 17; warning_length = atoi(p); }else{ goto usage; } break; case 'W': { int off; unsigned j; char *p = argv[i] + 2; off = !strncmp(p, "no-", 3); if(off) p += 3; ITER_WARNS(j){ if(!strcmp(p, warns[j].warn)){ if(off) wmode &= ~warns[j].or_mask; else wmode |= warns[j].or_mask; break; } } /* if not found, we ignore - it was intended for cc1 */ break; } case 'O': { switch(argv[i][2]){ case '0': break; case 's': macro_add("__OPTIMIZE_SIZE__", "1", 0); /* fallthru */ default: macro_add("__OPTIMIZE__", "1", 0); } break; } case 'w': if(!argv[i][2]){ wmode = 0; break; } /* fall */ default: defaul: if(std_from_str(argv[i], &cpp_std, NULL) == 0){ /* we have an std */ }else if(!strcmp(argv[i], "-trigraphs")){ option_trigraphs = 1; }else if(!strcmp(argv[i], "-digraphs")){ option_digraphs = 1; }else{ fprintf(stderr, "unrecognised option \"%s\"\n", argv[i]); goto usage; } } } current_fname = FNAME_BUILTIN; macro_add("__STDC_HOSTED__", freestanding ? "0" : "1", 0); switch(cpp_std){ case STD_C89: case STD_C90: /* no */ break; case STD_C99: macro_add("__STDC_VERSION__", "199901L", 0); break; case STD_C11: macro_add("__STDC_VERSION__", "201112L", 0); } if(i < argc){ infname = argv[i++]; if(i < argc){ if(outfname) goto usage; outfname = argv[i++]; if(i < argc) goto usage; } } calctime(infname); #define CHECK_FILE(var, mode, target) \ if(var && strcmp(var, "-")){ \ if(!freopen(var, mode, target)){ \ fprintf(stderr, "open: %s: ", var); \ perror(NULL); \ return 1; \ } \ } CHECK_FILE(outfname, "w", stdout) CHECK_FILE(infname, "r", stdin) if(infname){ dirname_push(udirname(infname)); }else{ infname = "<stdin>"; dirname_push(ustrdup(".")); } current_fname = infname; preprocess(); if(wmode & WUNUSED) macros_warn_unused(); switch(dump){ case NONE: break; case MACROS: case MACROS_WHERE: macros_dump(dump == MACROS_WHERE); break; case STATS: macros_stats(); break; case DEPS: deps_dump(infname); break; } free(dirname_pop()); errno = 0; fclose(stdout); if(errno) die("close():"); return ret; usage: fprintf(stderr, "Usage: %s [options] files...\n", *argv); fputs(" Options:\n" " -Idir: Add search directory\n" " -Dxyz[=abc]: Define xyz (to equal abc)\n" " -Uxyz: Undefine xyz\n" " -o output: output file\n" " -P: don't add #line directives\n" " -dM: debug output\n" " -dS: print macro usage stats\n" " -MM: generate Makefile dependencies\n" " -C: don't discard comments, except in macros\n" " -CC: don't discard comments, even in macros\n" " -trigraphs: enable trigraphs\n" " -digraphs: enable digraphs\n" , stderr); { unsigned i; ITER_WARNS(i) fprintf(stderr, " -W%s: %s\n", warns[i].warn, warns[i].desc); } return 1; }
/* * Parse a sub-file of the "extra info" (format shown below) * * Each "action" line has an "action symbol" in the first column, * followed by a colon, followed by some command specific info, * usually in the form of "tokens" separated by colons or slashes. * * Blank lines, lines starting with white space, and lines starting * with pound signs ("#") are ignored (as comments). * * Note the use of "tokenize()" to allow the use of both colons and * slashes as delimeters, while still allowing final tokens which * may contain any characters including "delimiters". * * Note the use of "strtol()" to allow all "integers" to be encoded * in decimal, hexidecimal, or octal form. * * Note that "monster zero" is used for the "player" attr/char, "object * zero" will be used for the "stack" attr/char, and "feature zero" is * used for the "nothing" attr/char. * * Specify the attr/char values for "monsters" by race index. * R:<num>:<a>/<c> * * Specify the attr/char values for "objects" by kind index. * K:<num>:<a>/<c> * * Specify the attr/char values for "features" by feature index. * F:<num>:<a>/<c> * * Specify the attr/char values for "special" things. * S:<num>:<a>/<c> * * Specify the attribute values for inventory "objects" by kind tval. * E:<tv>:<a> * * Define a macro action, given an encoded macro action. * A:<str> * * Create a macro, given an encoded macro trigger. * P:<str> * * Create a keymap, given an encoded keymap trigger. * C:<num>:<str> * * Turn an option off, given its name. * X:<str> * * Turn an option on, given its name. * Y:<str> * * Turn a window flag on or off, given a window, flag, and value. * W:<win>:<flag>:<value> * * Specify visual information, given an index, and some data. * V:<num>:<kv>:<rv>:<gv>:<bv> * * Specify colors for message-types. * M:<type>:<attr> * * Specify the attr/char values for "flavors" by flavors index. * L:<num>:<a>/<c> */ errr process_pref_file_command(char *buf) { long i; char *zz[16]; /* Skip "empty" lines */ if (!buf[0]) return (0); /* Skip "blank" lines */ if (isspace((unsigned char)buf[0])) return (0); /* Skip comments */ if (buf[0] == '#') return (0); /* Paranoia */ /* if (strlen(buf) >= 1024) return (1); */ /* Require "?:*" format */ if (buf[1] != ':') return (1); /* * Hookifying this. * Designate certain types of preference lines that are called out * to the user. * */ #ifndef AVT_HOOKIFY_PREFS /* Process "R:<num>:<a>/<c>" -- attr/char for monster races */ if (buf[0] == 'R') { if (tokenize(buf+2, 3, zz) == 3) { monster_race *r_ptr; i = strtol(zz[0], NULL, 0); n1 = strtol(zz[1], NULL, 0); n2 = strtol(zz[2], NULL, 0); if ((i < 0) || (i >= (long)z_info->r_max)) return (1); r_ptr = &r_info[i]; if (n1) r_ptr->x_attr = (byte)n1; if (n2) r_ptr->x_char = (char)n2; return (0); } } /* Process "K:<num>:<a>/<c>" -- attr/char for object kinds */ else if (buf[0] == 'K') { if (tokenize(buf+2, 3, zz) == 3) { object_kind *k_ptr; i = strtol(zz[0], NULL, 0); n1 = strtol(zz[1], NULL, 0); n2 = strtol(zz[2], NULL, 0); if ((i < 0) || (i >= (long)z_info->k_max)) return (1); k_ptr = &k_info[i]; if (n1) k_ptr->x_attr = (byte)n1; if (n2) k_ptr->x_char = (char)n2; return (0); } } /* Process "F:<num>:<a>/<c>" -- attr/char for terrain features */ else if (buf[0] == 'F') { if (tokenize(buf+2, 3, zz) == 3) { feature_type *f_ptr; i = strtol(zz[0], NULL, 0); n1 = strtol(zz[1], NULL, 0); n2 = strtol(zz[2], NULL, 0); if ((i < 0) || (i >= (long)z_info->f_max)) return (1); f_ptr = &f_info[i]; if (n1) f_ptr->x_attr = (byte)n1; if (n2) f_ptr->x_char = (char)n2; return (0); } } /* Process "L:<num>:<a>/<c>" -- attr/char for flavors */ else if (buf[0] == 'L') { if (tokenize(buf+2, 3, zz) == 3) { flavor_type *flavor_ptr; i = strtol(zz[0], NULL, 0); n1 = strtol(zz[1], NULL, 0); n2 = strtol(zz[2], NULL, 0); if ((i < 0) || (i >= (long)z_info->flavor_max)) return (1); flavor_ptr = &flavor_info[i]; if (n1) flavor_ptr->x_attr = (byte)n1; if (n2) flavor_ptr->x_char = (char)n2; return (0); } } /* Process "S:<num>:<a>/<c>" -- attr/char for special things */ else if (buf[0] == 'S') { if (tokenize(buf+2, 3, zz) == 3) { i = strtol(zz[0], NULL, 0); n1 = strtol(zz[1], NULL, 0); n2 = strtol(zz[2], NULL, 0); if ((i < 0) || (i >= (long)N_ELEMENTS(misc_to_attr))) return (1); misc_to_attr[i] = (byte)n1; misc_to_char[i] = (char)n2; return (0); } } /* Process "E:<tv>:<a>" -- attribute for inventory objects */ else if (buf[0] == 'E') { if (tokenize(buf+2, 2, zz) == 2) { i = strtol(zz[0], NULL, 0) % 128; n1 = strtol(zz[1], NULL, 0); if ((i < 0) || (i >= (long)N_ELEMENTS(tval_to_attr))) return (1); if (n1) tval_to_attr[i] = (byte)n1; return (0); } } else #endif /* AVT_HOOKIFY_PREFS */ /* Process "A:<str>" -- save an "action" for later */ if (buf[0] == 'A') { text_to_ascii(macro_buffer, sizeof(macro_buffer), buf+2); return (0); } /* Process "P:<str>" -- create macro */ #ifdef AVT_USE_MACROS else if (buf[0] == 'P') { char tmp[1024]; text_to_ascii(tmp, sizeof(tmp), buf+2); macro_add(tmp, macro_buffer); return (0); } else #endif /* Process "C:<num>:<str>" -- create keymap */ if (buf[0] == 'C') { long mode; char tmp[1024]; if (tokenize(buf+2, 2, zz) != 2) return (1); mode = strtol(zz[0], NULL, 0); if ((mode < 0) || (mode >= KEYMAP_MODES)) return (1); text_to_ascii(tmp, sizeof(tmp), zz[1]); if (!tmp[0] || tmp[1]) return (1); i = (long)tmp[0]; string_free(keymap_act[mode][i]); keymap_act[mode][i] = string_make(macro_buffer); return (0); } /* Process "V:<num>:<kv>:<rv>:<gv>:<bv>" -- visual info */ else if (buf[0] == 'V') { if (tokenize(buf+2, 5, zz) == 5) { i = strtol(zz[0], NULL, 0); if ((i < 0) || (i >= 256)) return (1); angband_color_table[i][0] = (byte)strtol(zz[1], NULL, 0); angband_color_table[i][1] = (byte)strtol(zz[2], NULL, 0); angband_color_table[i][2] = (byte)strtol(zz[3], NULL, 0); angband_color_table[i][3] = (byte)strtol(zz[4], NULL, 0); return (0); } } /* Process "X:<str>" -- turn option off */ else if (buf[0] == 'X') { /* Check non-adult options */ for (i = 0; i < OPT_ADULT; i++) { #ifndef AVT_HOOKIFY_OPTIONS if (option_text[i] && streq(option_text[i], buf + 2)) { op_ptr->opt[i] = FALSE; return (0); } #endif } } /* Process "Y:<str>" -- turn option on */ else if (buf[0] == 'Y') { /* Check non-adult options */ for (i = 0; i < OPT_ADULT; i++) { #ifndef AVT_HOOKIFY_OPTIONS if (option_text[i] && streq(option_text[i], buf + 2)) { op_ptr->opt[i] = TRUE; return (0); } #endif } } /* Process "W:<win>:<flag>:<value>" -- window flags */ else if (buf[0] == 'W') { long win, flag, value; if (tokenize(buf + 2, 3, zz) == 3) { win = strtol(zz[0], NULL, 0); flag = strtol(zz[1], NULL, 0); value = strtol(zz[2], NULL, 0); /* Ignore illegal windows */ /* Hack -- Ignore the main window */ if ((win <= 0) || (win >= ANGBAND_TERM_MAX)) return (1); /* Ignore illegal flags */ if ((flag < 0) || (flag >= 32)) return (1); #ifndef AVT_HOOKIFY_WINDOW_FLAGS /* Require a real flag */ if (window_flag_desc[flag]) { if (value) { /* Turn flag on */ op_ptr->window_flag[win] |= (1L << flag); } else { /* Turn flag off */ op_ptr->window_flag[win] &= ~(1L << flag); } } #endif /* Success */ return (0); } } /* Process "M:<type>:<attr>" -- colors for message-types */ else if (buf[0] == 'M') { if (tokenize(buf+2, 2, zz) == 2) { long type = strtol(zz[0], NULL, 0); int color = color_char_to_attr(zz[1][0]); /* Ignore illegal color */ if (color < 0) return (1); /* Store the color */ return (message_color_define((u16b)type, (byte)color)); } } #ifdef AVT_HOOKIFY_PREFS else { /* Handle any hooked prefs. Warn on anything that we can't handle. */ return 0; } #endif /* Failure */ return (1); }
/* * Interact with "macros" * * Note that the macro "action" must be defined before the trigger. * * Could use some helpful instructions on this page. XXX XXX XXX */ void do_cmd_macros(void) { s32b i; char tmp[1024]; char buf[1024]; s32b mode; /* Roguelike */ if (rogue_like_commands) { mode = KEYMAP_MODE_ROGUE; } /* Original */ else { mode = KEYMAP_MODE_ORIG; } /* Enter "icky" mode */ character_icky++; /* Save screen */ Term_save(); /* Process requests until done */ while (1) { /* Clear screen */ Term_clear(); /* Describe */ prt("Interact with Macros", 2, 0); /* Describe that action */ prt("Current action (if any) shown below:", 20, 0); /* Analyze the current action */ ascii_to_text(buf, macro__buf); /* Display the current action */ prt(buf, 22, 0); /* Selections */ prt("(1) Load a user pref file", 4, 5); #ifdef ALLOW_MACROS prt("(2) Append macros to a file", 5, 5); prt("(3) Query a macro", 6, 5); prt("(4) Create a macro", 7, 5); prt("(5) Remove a macro", 8, 5); prt("(6) Append keymaps to a file", 9, 5); prt("(7) Query a keymap", 10, 5); prt("(8) Create a keymap", 11, 5); prt("(9) Remove a keymap", 12, 5); prt("(0) Enter a new action", 13, 5); #endif /* ALLOW_MACROS */ /* Prompt */ prt("Command: ", 16, 0); /* Get a command */ i = inkey(); /* Leave */ if (i == ESCAPE) break; /* Load a 'macro' file */ else if (i == '1') { /* Prompt */ prt("Command: Load a user pref file", 16, 0); /* Prompt */ prt("File: ", 18, 0); /* Default filename */ strnfmt(tmp, 1024, "%s.prf", player_name); /* Ask for a file */ if (!askfor_aux(tmp, 80)) continue; /* Process the given filename */ if (0 != process_pref_file(tmp)) { /* Prompt */ msg_print("Could not load file!"); } } #ifdef ALLOW_MACROS /* Save macros */ else if (i == '2') { /* Prompt */ prt("Command: Append macros to a file", 16, 0); /* Prompt */ prt("File: ", 18, 0); /* Default filename */ strnfmt(tmp, 1024, "%s.prf", player_name); /* Ask for a file */ if (!askfor_aux(tmp, 80)) continue; /* Dump the macros */ (void)macro_dump(tmp); /* Prompt */ msg_print("Appended macros."); } /* Query a macro */ else if (i == '3') { s32b k; /* Prompt */ prt("Command: Query a macro", 16, 0); /* Prompt */ prt("Trigger: ", 18, 0); /* Get a macro trigger */ do_cmd_macro_aux(buf, TRUE); /* Acquire action */ k = macro_find_exact(buf); /* Nothing found */ if (k < 0) { /* Prompt */ msg_print("Found no macro."); } /* Found one */ else { /* Obtain the action */ strcpy(macro__buf, macro__act[k]); /* Analyze the current action */ ascii_to_text(buf, macro__buf); /* Display the current action */ prt(buf, 22, 0); /* Prompt */ msg_print("Found a macro."); } } /* Create a macro */ else if (i == '4') { /* Prompt */ prt("Command: Create a macro", 16, 0); /* Prompt */ prt("Trigger: ", 18, 0); /* Get a macro trigger */ do_cmd_macro_aux(buf, TRUE); /* Clear */ clear_from(20); /* Prompt */ prt("Action: ", 20, 0); /* Convert to text */ ascii_to_text(tmp, macro__buf); /* Get an encoded action */ if (askfor_aux(tmp, 80)) { /* Convert to ascii */ text_to_ascii(macro__buf, tmp); /* Link the macro */ macro_add(buf, macro__buf); /* Prompt */ msg_print("Added a macro."); } } /* Remove a macro */ else if (i == '5') { /* Prompt */ prt("Command: Remove a macro", 16, 0); /* Prompt */ prt("Trigger: ", 18, 0); /* Get a macro trigger */ do_cmd_macro_aux(buf, TRUE); /* Link the macro */ macro_add(buf, buf); /* Prompt */ msg_print("Removed a macro."); } /* Save keymaps */ else if (i == '6') { /* Prompt */ prt("Command: Append keymaps to a file", 16, 0); /* Prompt */ prt("File: ", 18, 0); /* Default filename */ strnfmt(tmp, 1024, "%s.prf", player_name); /* Ask for a file */ if (!askfor_aux(tmp, 80)) continue; /* Dump the macros */ (void)keymap_dump(tmp); /* Prompt */ msg_print("Appended keymaps."); } /* Query a keymap */ else if (i == '7') { cptr act; /* Prompt */ prt("Command: Query a keymap", 16, 0); /* Prompt */ prt("Keypress: ", 18, 0); /* Get a keymap trigger */ do_cmd_macro_aux_keymap(buf); /* Look up the keymap */ act = keymap_act[mode][(byte)(buf[0])]; /* Nothing found */ if (!act) { /* Prompt */ msg_print("Found no keymap."); } /* Found one */ else { /* Obtain the action */ strcpy(macro__buf, act); /* Analyze the current action */ ascii_to_text(buf, macro__buf); /* Display the current action */ prt(buf, 22, 0); /* Prompt */ msg_print("Found a keymap."); } } /* Create a keymap */ else if (i == '8') { /* Prompt */ prt("Command: Create a keymap", 16, 0); /* Prompt */ prt("Keypress: ", 18, 0); /* Get a keymap trigger */ do_cmd_macro_aux_keymap(buf); /* Clear */ clear_from(20); /* Prompt */ prt("Action: ", 20, 0); /* Convert to text */ ascii_to_text(tmp, macro__buf); /* Get an encoded action */ if (askfor_aux(tmp, 80)) { /* Convert to ascii */ text_to_ascii(macro__buf, tmp); /* Free old keymap */ string_free(keymap_act[mode][(byte)(buf[0])]); /* Make new keymap */ keymap_act[mode][(byte)(buf[0])] = string_make(macro__buf); /* Prompt */ msg_print("Added a keymap."); } } /* Remove a keymap */ else if (i == '9') { /* Prompt */ prt("Command: Remove a keymap", 16, 0); /* Prompt */ prt("Keypress: ", 18, 0); /* Get a keymap trigger */ do_cmd_macro_aux_keymap(buf); /* Free old keymap */ string_free(keymap_act[mode][(byte)(buf[0])]); /* Make new keymap */ keymap_act[mode][(byte)(buf[0])] = NULL; /* Prompt */ msg_print("Removed a keymap."); } /* Enter a new action */ else if (i == '0') { /* Prompt */ prt("Command: Enter a new action", 16, 0); /* Go to the correct location */ Term_gotoxy(0, 22); /* Hack -- limit the value */ tmp[80] = '\0'; /* Get an encoded action */ if (!askfor_aux(buf, 80)) continue; /* Extract an action */ text_to_ascii(macro__buf, buf); } #endif /* ALLOW_MACROS */ /* Oops */ else { /* Oops */ bell(); } /* Flush messages */ msg_print(NULL); } /* Load screen */ Term_load(); /* Leave "icky" mode */ character_icky--; }