Manual color for Circlemud 3.1, version 2 This is a slight remake of the old manual_color snippet by renx (renx@writeme.com). Any comments on this implementation should be made to Welcor (welcor@dune.net). NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE This version has fixed some serious bugs in the version named 'manual_color_3.1.txt'. Use this one instead!!! NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE It works on strings of arbitrary size, and can both strip and parse color codes. - Welcor Adding the stuff below should cause all color codes starting with & being replaced with according ANSI codes. Colors are: &n - normal &d - black &D - gray &0 - background black &b - blue &B - bright blue &1 - background blue &g - green &G - bright green &2 - background green &c - cyan &C - bright cyan &3 - background cyan &r - red &R - bright red &4 - background red &m - magneta &M - bright magneta &5 - background magneta &y - yellow &Y - bright yellow &6 - background yellow &w - white &W - bright white &7 - background white Extra codes: &l - blink &o - bold &u - underline &e - reverse video && - single & ------------------------------------------------------------------------------- The snippet alters only one file, namely comm.c: Somewhere above vwrite_to_output(), add this function: ------------------------------------------------------------------------------- #define COLOR_ON(ch) (!IS_NPC(ch) ? (PRF_FLAGGED((ch), PRF_COLOR_1 | PRF_COLOR_2) ? 1 : 0) : 0) /* Color replacement arrays. Renx -- 011100 */ #define A "\x1B[" const char *ANSI[] = { "&", A"0m",A"0;30m",A"0;34m",A"0;32m",A"0;36m",A"0;31m", A"0;35m",A"0;33m",A"0;37m",A"1;30m",A"1;34m",A"1;32m",A"1;36m",A"1;31m", A"1;35m",A"1;33m",A"1;37m",A"40m",A"44m",A"42m",A"46m",A"41m",A"45m", A"43m",A"47m",A"5m",A"4m",A"1m",A"7m" ,"!"}; #undef A const char CCODE[] = "&ndbgcrmywDBGCRMYW01234567luoe!"; #define NEW_STRING_LENGTH (size_t)(dest_char-save_pos) size_t proc_colors(char *txt, size_t maxlen, int parse) { char *dest_char, *source_char, *color_char, *save_pos; int i; size_t wanted; if (!txt || !strchr(txt, '&')) /* skip out if no color codes */ return strlen(txt); source_char = txt; CREATE(dest_char, char, maxlen); save_pos = dest_char; for( ; *source_char && (NEW_STRING_LENGTH < maxlen); ) { /* no color code - just copy */ if (*source_char != '&') { *dest_char++ = *source_char++; continue; } /* if we get here we have a color code */ source_char++; /* source_char now points to the code */ if (*source_char == '\0') { /* string was terminated with color code - just put it in */ *dest_char++ = '&'; /* source_char will now point to '\0' in the for() check */ continue; } if (!parse) { /* not parsing, just skip the code, unless it's && */ if (*source_char == '&') { *dest_char++ = '&'; } source_char++; /* skip to next (non-colorcode) char */ continue; } /* parse the color code */ for (i = 0; CCODE[i] != '!'; i++) { /* do we find it ? */ if ((*source_char) == CCODE[i]) { /* if so :*/ if ( NEW_STRING_LENGTH + strlen(ANSI[i]) < maxlen) { /* only substitute if there's room for the whole code */ /* color_char now points to the first char in color code*/ for(color_char = (char *)ANSI[i] ; *color_char ; ) *dest_char++ = *color_char++; } break; } } /* If we couldn't find any correct color code, or we found it and * substituted above, let's just process the next character. * - Welcor */ source_char++; } /* for loop */ /* make sure output is NULL - terminated */ *dest_char = '\0'; wanted = strlen(source_char); /* see if we wanted more space */ strncpy(txt, save_pos, maxlen-1); free(save_pos); /* plug memory leak */ return NEW_STRING_LENGTH+wanted; } #undef NEW_STRING_LENGTH ------------------------------------------------------------------------------- Then in vwrite_to_output(), add the two lines below. ------------------------------------------------------------------------------- /* if we're in the overflow state already, ignore this new output */ if (t->bufptr < 0) return (0); wantsize = size = vsnprintf(txt, sizeof(txt), format, args); + if (t->character) + wantsize = size = proc_colors(txt, sizeof(txt), COLOR_ON(t->character)); /* If exceeding the size of the buffer, truncate it for the overflow message */ if (size < 0 || wantsize >= sizeof(txt)) size = sizeof(txt) - 1; -------------------------------------------------------------------------------