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