Created
February 6, 2025 13:57
-
-
Save lycis/5cc245dacdbc644fde4bd7047d639cc9 to your computer and use it in GitHub Desktop.
ANSI True Color Support in SilberlandLD mudlib (vs. Tamedhon base)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// file: /secure/simul_efun.c | |
// ... | |
/// This function maps an RGB value (each 0..255) to the nearest ANSI color. | |
string rgb_to_ansi(int r, int g, int b) { | |
// Define an array of mappings. | |
// The RGB values here are chosen as “representatives” of the ANSI colors. | |
// You can adjust these if you have a different idea of what each ANSI code should represent. | |
mapping *colors = ({ | |
([ "ansi": ANSI_BLACK, "r": 0, "g": 0, "b": 0 ]), | |
([ "ansi": ANSI_RED, "r": 128, "g": 0, "b": 0 ]), | |
([ "ansi": ANSI_GREEN, "r": 0, "g": 128, "b": 0 ]), | |
([ "ansi": ANSI_BROWN, "r": 128, "g": 128, "b": 0 ]), // brown/dark yellow | |
([ "ansi": ANSI_BLUE, "r": 0, "g": 0, "b": 128 ]), | |
([ "ansi": ANSI_PURPLE, "r": 128, "g": 0, "b": 128 ]), | |
([ "ansi": ANSI_CYAN, "r": 0, "g": 128, "b": 128 ]), | |
([ "ansi": ANSI_GREY, "r": 192, "g": 192, "b": 192 ]), | |
([ "ansi": ANSI_WHITE, "r": 255, "g": 255, "b": 255 ]) | |
}); | |
// We'll use the squared Euclidean distance for comparison | |
int best_dist = 1<<30; // a very high value | |
string best_ansi = ANSI_WHITE; // default fallback | |
foreach(mapping col in colors) { | |
int dr = r - col["r"]; | |
int dg = g - col["g"]; | |
int db = b - col["b"]; | |
int dist = dr * dr + dg * dg + db * db; | |
if(dist < best_dist) { | |
best_dist = dist; | |
best_ansi = col["ansi"]; | |
} | |
} | |
return best_ansi; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// file: /std/player/base.c | |
// ... | |
void create() { | |
// ... | |
Set(P_ANSI_TRUE_COLOR, SAVE, F_MODE_AS); | |
// ... | |
} | |
// ... | |
// The rainbow is divided into 6 segments of 10 steps each. | |
// For simplicity some boundary colors are repeated. | |
#define ANSI_RAINBOW \ | |
/* Segment 1: Red -> Yellow */ \ | |
ANSI_TRUE_COLOR(255,0,0) + "█" + \ | |
ANSI_TRUE_COLOR(255,28,0) + "█" + \ | |
ANSI_TRUE_COLOR(255,57,0) + "█" + \ | |
ANSI_TRUE_COLOR(255,85,0) + "█" + \ | |
ANSI_TRUE_COLOR(255,113,0) + "█" + \ | |
ANSI_TRUE_COLOR(255,142,0) + "█" + \ | |
ANSI_TRUE_COLOR(255,170,0) + "█" + \ | |
ANSI_TRUE_COLOR(255,198,0) + "█" + \ | |
ANSI_TRUE_COLOR(255,227,0) + "█" + \ | |
ANSI_TRUE_COLOR(255,255,0) + "█" + \ | |
/* Segment 2: Yellow -> Green */ \ | |
ANSI_TRUE_COLOR(255,255,0) + "█" + \ | |
ANSI_TRUE_COLOR(227,255,0) + "█" + \ | |
ANSI_TRUE_COLOR(198,255,0) + "█" + \ | |
ANSI_TRUE_COLOR(170,255,0) + "█" + \ | |
ANSI_TRUE_COLOR(142,255,0) + "█" + \ | |
ANSI_TRUE_COLOR(113,255,0) + "█" + \ | |
ANSI_TRUE_COLOR(85,255,0) + "█" + \ | |
ANSI_TRUE_COLOR(57,255,0) + "█" + \ | |
ANSI_TRUE_COLOR(28,255,0) + "█" + \ | |
ANSI_TRUE_COLOR(0,255,0) + "█" + \ | |
/* Segment 3: Green -> Cyan */ \ | |
ANSI_TRUE_COLOR(0,255,0) + "█" + \ | |
ANSI_TRUE_COLOR(0,255,28) + "█" + \ | |
ANSI_TRUE_COLOR(0,255,57) + "█" + \ | |
ANSI_TRUE_COLOR(0,255,85) + "█" + \ | |
ANSI_TRUE_COLOR(0,255,113) + "█" + \ | |
ANSI_TRUE_COLOR(0,255,142) + "█" + \ | |
ANSI_TRUE_COLOR(0,255,170) + "█" + \ | |
ANSI_TRUE_COLOR(0,255,198) + "█" + \ | |
ANSI_TRUE_COLOR(0,255,227) + "█" + \ | |
ANSI_TRUE_COLOR(0,255,255) + "█" + \ | |
/* Segment 4: Cyan -> Blue */ \ | |
ANSI_TRUE_COLOR(0,255,255) + "█" + \ | |
ANSI_TRUE_COLOR(0,227,255) + "█" + \ | |
ANSI_TRUE_COLOR(0,198,255) + "█" + \ | |
ANSI_TRUE_COLOR(0,170,255) + "█" + \ | |
ANSI_TRUE_COLOR(0,142,255) + "█" + \ | |
ANSI_TRUE_COLOR(0,113,255) + "█" + \ | |
ANSI_TRUE_COLOR(0,85,255) + "█" + \ | |
ANSI_TRUE_COLOR(0,57,255) + "█" + \ | |
ANSI_TRUE_COLOR(0,28,255) + "█" + \ | |
ANSI_TRUE_COLOR(0,0,255) + "█" + \ | |
/* Segment 5: Blue -> Magenta */ \ | |
ANSI_TRUE_COLOR(0,0,255) + "█" + \ | |
ANSI_TRUE_COLOR(28,0,255) + "█" + \ | |
ANSI_TRUE_COLOR(57,0,255) + "█" + \ | |
ANSI_TRUE_COLOR(85,0,255) + "█" + \ | |
ANSI_TRUE_COLOR(113,0,255) + "█" + \ | |
ANSI_TRUE_COLOR(142,0,255) + "█" + \ | |
ANSI_TRUE_COLOR(170,0,255) + "█" + \ | |
ANSI_TRUE_COLOR(198,0,255) + "█" + \ | |
ANSI_TRUE_COLOR(227,0,255) + "█" + \ | |
ANSI_TRUE_COLOR(255,0,255) + "█" + \ | |
/* Segment 6: Magenta -> Red */ \ | |
ANSI_TRUE_COLOR(255,0,255) + "█" + \ | |
ANSI_TRUE_COLOR(255,0,227) + "█" + \ | |
ANSI_TRUE_COLOR(255,0,198) + "█" + \ | |
ANSI_TRUE_COLOR(255,0,170) + "█" + \ | |
ANSI_TRUE_COLOR(255,0,142) + "█" + \ | |
ANSI_TRUE_COLOR(255,0,113) + "█" + \ | |
ANSI_TRUE_COLOR(255,0,85) + "█" + \ | |
ANSI_TRUE_COLOR(255,0,57) + "█" + \ | |
ANSI_TRUE_COLOR(255,0,28) + "█" + \ | |
ANSI_TRUE_COLOR(255,0,0) + "█" + \ | |
ANSI_PLAIN | |
static int stty(string str) | |
{ | |
if (str!=TTY_DUMB&&str!=TTY_VT100&&str!=TTY_ANSI&&str!="reset"&&str!="truecolor") | |
{ | |
write("Syntax: stty dumb|vt100|ansi oder reset\n"); | |
write("Wenn du 'ansi' verwendest kannst du mit 'stty truecolor' den ANSI True Color Modus ein- oder ausschalten.\n"); | |
} | |
if(str == "reset") { | |
printf("\e[30;47m\e[0mDieser Text sollte lesbar sein!\n"); | |
return 1; | |
} | |
if(str == "truecolor") { | |
if(Query(P_TTY) != "ansi") { | |
write("ANSI True Color benötigt 'stty ansi' aktiviert."); | |
return 1; | |
} | |
SetProp(P_ANSI_TRUE_COLOR, !QueryProp(P_ANSI_TRUE_COLOR)); | |
int tc = QueryProp(P_ANSI_TRUE_COLOR); | |
write("ANSI True Color: "+(tc?"ein":"aus")+"\n"); | |
if(tc) { | |
write("\nTrueColor Support aktiviert:\n" + ANSI_RAINBOW + "\n" + "Wenn du die Farben sehen kannst, dann unterstützt dein Terminal TrueColor.\n"); | |
} | |
return 1; | |
} | |
write("TTY steht jetzt auf "+SetProp(P_TTY,str)+".\n"); | |
if(str == "ansi" || str == "vt100") { | |
printf("Terminal Test:\n"); | |
printf("VT100: \e[1mfett\e[0m \e[4munterstrichen\e[0m "+ | |
"\e[5mblinkend\e[0m \e[7minvers\e[0m\n"); | |
if(str == "ansi") { | |
int fg, bg; | |
printf("ANSI Farben und VT100 Attribute:\n"); | |
for(fg = 30; fg <= 37; fg++) { | |
for(bg = 40; bg <= 47; bg++) { | |
printf("\e[%d;%dm\e[1m@\e[0m", fg, bg); | |
printf("\e[%d;%dm\e[4m@\e[0m", fg, bg); | |
printf("\e[%d;%dm\e[5m@\e[0m", fg, bg); | |
printf("\e[%d;%dm\e[7m@\e[0m", fg, bg); | |
} | |
printf("\n"); | |
} | |
printf("Sollte dieser Text hier nicht richtig lesbar\n" | |
"sein, benutze das Kommando stty reset!\n"); | |
} else { | |
SetProp(P_ANSI_TRUE_COLOR, 0); // immer ausschalten, wenn kein ansi terminal | |
} | |
} | |
return 1; | |
} | |
// ... | |
string _query_color(object ob, string prop) | |
{ | |
mixed s1; | |
if (!interactive(ob)) return ""; | |
s1=ob->QueryProp(prop); | |
// true color support | |
if(pointerp(s1)) { | |
if(sizeof(s1) != 3) { | |
tell_object(this_object(), "Warnung: Ungültige Farbeinstellung für "+prop+" zurückgesetzt auf 'plain'.\n"); | |
return ANSI_PLAIN; | |
} | |
int r = s1[0]; | |
int g = s1[1]; | |
int b = s1[2]; | |
if(QueryProp(P_ANSI_TRUE_COLOR)) { | |
return ANSI_TRUE_COLOR(s1[0], s1[1], s1[2]); | |
} else { | |
return rgb_to_ansi(r, g, b); | |
} | |
} | |
// ... | |
} | |
// ... | |
int *hex_to_rgb(string hex) { | |
int r, g, b; | |
// Validate input | |
if (!stringp(hex) || strlen(hex) != 7 || hex[0] != '#') { | |
return 0; // Invalid format | |
} | |
// Convert hex to decimal values | |
r = to_int("0x" + hex[1..2]); | |
g = to_int("0x" + hex[3..4]); | |
b = to_int("0x" + hex[5..6]); | |
return ({ r, g, b }); | |
} | |
/* Setzt Farbe fuer Properties P_COLOR_EXIT, | |
* P_COLOR_COMMUNICATION, P_COLOR_INFORM | |
*/ | |
static void setcolor(string farbe, string prop, string name) { | |
if(farbe[0..0] == "#") { | |
int *hexcol = hex_to_rgb(farbe); | |
if(!pointerp(hexcol)) { | |
write(sprintf("Ungültige hex-Farbe. Format: #rrggbb\n", hexcol)); | |
return; | |
} | |
// true color support | |
SetProp(prop, hexcol); | |
} else { | |
switch(farbe){ | |
case "schwarz": SetProp(prop, 1);break; | |
case "rot": SetProp(prop, 2);break; | |
case "grün": SetProp(prop, 3);break; | |
// ... | |
default: write("Farbe "+farbe+" nicht erkannt.\n"); | |
farbliste(); | |
return; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// file: /sys/ansi.h | |
//... | |
#ifndef __ANSI__H_ | |
#define __ANSI__H_ | |
// ... | |
// True Color support | |
#define ANSI_TRUE_COLOR(r,g,b) "\e[38;2;"+r+";"+g+";"+b+"m" // Select RGB foreground color | |
#define ANSI_TRUE_COLOR_BG(r,g,b) "\e[48;"+r+";"+g+";"+b+"m" // Select RGB background color | |
// TTY constants | |
#define TTY_DUMB "dumb" | |
#define TTY_VT100 "vt100" | |
#define TTY_ANSI "ansi" | |
#define P_ANSI_TRUE_COLOR "tty_ansi_true_color" // 1 = ansi true color support enabled | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment