Up to Main Index Up to Journal for May, 2012 JOURNAL FOR WEDNESDAY 30TH MAY, 2012 ______________________________________________________________________________ SUBJECT: TELNET ANSI colours and folding DATE: Wed May 30 18:56:18 BST 2012 Today I sat down with two aims in mind - one simple and one harder. The simple task was to add the colour handling code. TELNET uses ANSI colour codes. Specifically the ANSI escape sequences as used by a VT100 terminal and now known as the ECMA-48 standard or ISO/IEC 6429. There is a PDF file here: https://www.ecma-international.org/publications/standards/Ecma-048.htm Colour codes are on page 62. Alternatively if you are on a *nix type box try: man console_codes. Originally when creating the Java version I used the programmer card from my VT220 - which I still have. There is also a manual I found which is a mine of handy information: https://vt100.net/docs/vt220-rm/ Colours are basically set by sending "ESC [" - also known as CSI or control sequence inducer. This is followed by the colour code and finally an "m" - known also as SGR or Set attributes. Putting it all together we get: ESC [ cc m Where cc is the foreground colour code 30-37. This is probably familiar to users who have experimented with colours in their shell's prompt. So after 10 minutes work I had colour working ;) It's a simple lookup table and a search and replace function. So now colour works the same as it did in the Java version. You can type: [CYAN]This is a test[WHITE] Becomes: \033[36mThis is a test\033[37m Which prints as "This is a test" in cyan. The ESC is sent as \033 octal - or as 0x1B hex or as Ctrl-[ even. Now you can do annoying things like: [RED]C[GREEN]o[YELLOW]l[BLUE]o[MAGENTA]u[CYAN]r[WHITE] Here is a sample screen shot of colours in action colours.png If you look carefully at the screenshot you will see what my next aim was - to implement word wrapping. This was more than 10 minutes work. For a start you have to take into consideration the fact that the colour escapes are zero width. So taking: [RED]C[GREEN]o[YELLOW]l[BLUE]o[MAGENTA]u[CYAN]r[WHITE] This becomes: \033[31mC\033[32mo\033[33ml\033[34mo\033[35mu\033[36mr\033[37m Which is actually 41 bytes - \033 is only a single byte. However when calculating the width of the word it's only 6 characters - 'Colour'. Anyway WolfMUD now has colours and word wrapping on whitespace and the prototype release is just a little closer. As you can see in the screenshot it's quit capable already. The sneeze? An interesting addition not in the Java version and for testing broadcasts really. It will display: You sneeze. Aaahhhccchhhooo! :To the sneezing player You see Diddymus sneeze. :To others in the same location You hear a loud sneeze. :To others in the world but not here Sounds horribly nasty and complex doesn't it? It is! I was slaving away long into the night, hour after hour after ... OK 30 seconds to implement ;) func (p *Player) sneeze(cmd *command.Command) (handled bool) { cmd.Respond("You sneeze. Aaahhhccchhhooo!") p.Locate().Broadcast( []thing.Interface{p}, "You see %s sneeze.", cmd.Issuer.Name(), ) p.world.Broadcast(p.Locate().List(), "You hear a loud sneeze.") return true } -- Diddymus Up to Main Index Up to Journal for May, 2012