Difference between revisions of "Color Codes"

From WolfWiki
Jump to: navigation, search
(Crappy explanation but better than nothing.)
 
m (Oops, caret reset the output when the table was generated)
 
(7 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 
==What are they?==
 
==What are they?==
Colour codes, as the name suggests, are used to add colour to texts. They have been introduced in Quake III Arena and are available in most Q3-based games, including Enemy Territory. They can be used in most texts that get displayed ingame, such as player names, chat or notices.
+
Color codes are used to add color to text. They were introduced in Quake III Arena and are available in most Q3 engine based games, including Enemy Territory. They can be used with most text that gets displayed ingame, including player names, chat or notices.
  
'''Usage:''' a dash character ('''^''') followed by another character. Each character produces a different colour.
+
'''Usage:''' a caret character ('''^''') followed by another character. Each character produces a different colour.<br>
'''Example:''' ^1red ^2green ^4blue
+
'''Example:''' ^1red ^2green ^4blue<br>
'''Produces:''' <font color="red">red</font> <font color="green">green</font> <font color="blue">blue</font>
+
'''Produces:''' <font color="red">red</font> <font color="green">green</font> <font color="blue">blue</font><br>
==Codes list==
+
 
The image below depicts the colours the characters produce, except '''^0''' which, stands for black. Notice that some letters and digits produce the same colour.<br>
+
==What colors are available?==
http://enemy-territory.4players.de:1041/modules/Nick_Colors/colours.jpg
+
There are 32 colors available -- internally, the game has a table of all 32 colors (starting with color #0) and uses the ASCII value of the character following the caret plus 16 to determine which color to use, looping back around to color #0 after color #31.  The index lookup could be described in C code as '(*char + 16) & 31'.
 +
 
 +
The following table shows what the index of each color is, its HTML color code equivalent, and the characters that will produce the color in-game if placed after a caret:
 +
<table style="border-collapse: collapse; border: 1px dashed #aaa; background: #181818; color: #fff; font-family: monospace;">
 +
<tr><th style="padding: 0 0.5em; border: 1px dashed #aaa;">Index</th><th style="padding: 0 0.5em; border: 1px dashed #aaa;">HTML color</th><th style="padding: 0 0.5em; border: 1px dashed #aaa;">Characters</th></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">0</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #000000">#000000</span></td><td style="padding: 0 0.5em;"><span style="color: #000000">0 P p ° Ð ð </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">1</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #ff0000">#ff0000</span></td><td style="padding: 0 0.5em;"><span style="color: #ff0000">1 Q q ± Ñ ñ </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">2</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #00ff00">#00ff00</span></td><td style="padding: 0 0.5em;"><span style="color: #00ff00">2 R r ² Ò ò </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">3</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #ffff00">#ffff00</span></td><td style="padding: 0 0.5em;"><span style="color: #ffff00">3 S s ³ Ó ó </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">4</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #0000ff">#0000ff</span></td><td style="padding: 0 0.5em;"><span style="color: #0000ff">4 T t Ž Ô ô </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">5</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #00ffff">#00ffff</span></td><td style="padding: 0 0.5em;"><span style="color: #00ffff">5 U u µ Õ õ </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">6</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #ff00ff">#ff00ff</span></td><td style="padding: 0 0.5em;"><span style="color: #ff00ff">6 V v ¶ Ö ö </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">7</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #ffffff">#ffffff</span></td><td style="padding: 0 0.5em;"><span style="color: #ffffff">7 W w · × ÷ </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">8</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #ff7f00">#ff7f00</span></td><td style="padding: 0 0.5em;"><span style="color: #ff7f00">8 X x ž Ø ø </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">9</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #7f7f7f">#7f7f7f</span></td><td style="padding: 0 0.5em;"><span style="color: #7f7f7f">9 Y y ¹ Ù ù </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">10</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #bfbfbf">#bfbfbf</span></td><td style="padding: 0 0.5em;"><span style="color: #bfbfbf">: Z z º Ú ú </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">11</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #bfbfbf">#bfbfbf</span></td><td style="padding: 0 0.5em;"><span style="color: #bfbfbf">; [ { » Û û </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">12</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #007f00">#007f00</span></td><td style="padding: 0 0.5em;"><span style="color: #007f00">&lt; \ | Œ Ü ü </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">13</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #7f7f00">#7f7f00</span></td><td style="padding: 0 0.5em;"><span style="color: #7f7f00">= ] } œ Ý ý </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">14</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #00007f">#00007f</span></td><td style="padding: 0 0.5em;"><span style="color: #00007f">&gt; ^ ~ Ÿ Þ þ </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">15</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #7f0000">#7f0000</span></td><td style="padding: 0 0.5em;"><span style="color: #7f0000">? _ ¿ ß ÿ </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">16</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #7f3f00">#7f3f00</span></td><td style="padding: 0 0.5em;"><span style="color: #7f3f00">  @ `  À à </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">17</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #ff9919">#ff9919</span></td><td style="padding: 0 0.5em;"><span style="color: #ff9919">! A a ¡ Á á </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">18</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #007f7f">#007f7f</span></td><td style="padding: 0 0.5em;"><span style="color: #007f7f">&quot; B b ¢ Â â </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">19</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #7f007f">#7f007f</span></td><td style="padding: 0 0.5em;"><span style="color: #7f007f"># C c £ Ã ã </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">20</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #007fff">#007fff</span></td><td style="padding: 0 0.5em;"><span style="color: #007fff">$ D d € Ä ä </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">21</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #7f00ff">#7f00ff</span></td><td style="padding: 0 0.5em;"><span style="color: #7f00ff">% E e ¥ Å å </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">22</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #3399cc">#3399cc</span></td><td style="padding: 0 0.5em;"><span style="color: #3399cc">&amp; F f Š Æ æ </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">23</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #ccffcc">#ccffcc</span></td><td style="padding: 0 0.5em;"><span style="color: #ccffcc">' G g § Ç ç </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">24</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #006633">#006633</span></td><td style="padding: 0 0.5em;"><span style="color: #006633">( H h š È è </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">25</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #ff0033">#ff0033</span></td><td style="padding: 0 0.5em;"><span style="color: #ff0033">) I i © É é </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">26</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #b21919">#b21919</span></td><td style="padding: 0 0.5em;"><span style="color: #b21919">* J j ª Ê ê </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">27</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #993300">#993300</span></td><td style="padding: 0 0.5em;"><span style="color: #993300">+ K k « Ë ë </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">28</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #cc9933">#cc9933</span></td><td style="padding: 0 0.5em;"><span style="color: #cc9933">, L l ¬ Ì ì </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">29</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #999933">#999933</span></td><td style="padding: 0 0.5em;"><span style="color: #999933">- M m ­ Í í </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">30</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #ffffbf">#ffffbf</span></td><td style="padding: 0 0.5em;"><span style="color: #ffffbf">. N n ® Î î </span></td></tr>
 +
<tr><td style="padding: 0 0.5em; text-align: right; border-right: 1px dashed #aaa;">31</td><td style="padding: 0 0.5em; border-right: 1px dashed #aaa; text-align: center;"><span style="color: #ffff7f">#ffff7f</span></td><td style="padding: 0 0.5em;"><span style="color: #ffff7f">/ O o ¯ Ï ï </span></td></tr>
 +
</table>
 +
 
 +
==Code Examples==
 +
Here is a little php script that can be used to parse colorcodes and return the HTML formatted, colored string:
 +
<pre>// &copy;2003 Deus@pooHunter.de
 +
// This script uses the original RGB-values that were used in RtCW:OSP which I received directly from rhea.
 +
// AFAIK these RGB values did not change in ET/ETPro
 +
function parse_gamecolors($string)
 +
{
 +
$string = ereg_replace("(\^)?$", "^", $string);
 +
$string = ereg_replace("\^\^", "&#94^", $string);
 +
$string = ereg_replace("(\^)?$", "", $string);
 +
$string = ereg_replace("\^<", "^|", $string);
 +
$string = ereg_replace("\<", "&lt;", $string);
 +
$string = ereg_replace("\^>", "^^", $string);
 +
$string = ereg_replace("\>", "&gt;", $string);
 +
$string = ereg_replace("\^\^", "^>", $string);
 +
$string = "<font color=\"#FFFFFF\">".$string."</font>";
 +
 
 +
$color_def = array
 +
(
 +
0  => "#000000", 1  => "#FF0000", 2  => "#00FF00", 3  => "#FFFF00",
 +
4  => "#0000FF", 5  => "#00FFFF", 6  => "#FF00FF", 7  => "#FFFFFF",
 +
8  => "#FF7F00", 9  => "#7F7F7F", 10 => "#BFBFBF", 11 => "#007F00",
 +
12 => "#7FFF00", 13 => "#00007F", 14 => "#7F0000", 15 => "#7F4000",
 +
16 => "#FF9933", 17 => "#007F7F", 18 => "#7F007F", 19 => "#007F7F",
 +
20 => "#7F00FF", 21 => "#3399CC", 22 => "#CCFFCC", 23 => "#006633",
 +
24 => "#FF0033", 25 => "#B21919", 26 => "#993300", 27 => "#CC9933",
 +
28 => "#999933", 29 => "#FFFFBF", 30 => "#FFFF7F"
 +
);
 +
 
 +
$color_chardef = array
 +
(
 +
"#000000" => array ( 0 => "0", 1 => "P", 2 => "p" ),
 +
"#FF0000" => array ( 0 => "1", 1 => "Q", 2 => "q" ),
 +
"#00FF00" => array ( 0 => "2", 1 => "R", 2 => "r" ),
 +
"#FFFF00" => array ( 0 => "3", 1 => "S", 2 => "s" ),
 +
"#0000FF" => array ( 0 => "4", 1 => "T", 2 => "t" ),
 +
"#00FFFF" => array ( 0 => "5", 1 => "U", 2 => "u" ),
 +
"#FF00FF" => array ( 0 => "6", 1 => "V", 2 => "v" ),
 +
"#FFFFFF" => array ( 0 => "7", 1 => "W", 2 => "w" ),
 +
"#FF7F00" => array ( 0 => "8", 1 => "X", 2 => "x" ),
 +
"#7F7F7F" => array ( 0 => "9", 1 => "Y", 2 => "y" ),
 +
"#BFBFBF" => array ( 0 => ":", 1 => "Z", 2 => "z",
 +
3 => ";", 4 => "[", 5 => "{" ),
 +
"#007F00" => array ( 0 => "<", 1 => "\\", 2 => "|" ),
 +
"#7FFF00" => array ( 0 => "=", 1 => "]", 2 => "}" ),
 +
"#00007F" => array ( 0 => ">" ),
 +
"#7F0000" => array ( 0 => "?" ),
 +
"#7F4000" => array ( 0 => "@", 1 => "`" ),
 +
"#FF9933" => array ( 0 => "A", 1 => "a", 2 => "!" ),
 +
"#007F7F" => array ( 0 => "B", 1 => "b" ),
 +
"#7F007F" => array ( 0 => "C", 1 => "c", 2 => "#" ),
 +
"#007F7F" => array ( 0 => "D", 1 => "d", 2 => "$" ),
 +
"#7F00FF" => array ( 0 => "E", 1 => "e", 2 => "%" ),
 +
"#3399CC" => array ( 0 => "F", 1 => "f", 2 => "&" ),
 +
"#CCFFCC" => array ( 0 => "G", 1 => "g", 2 => "'" ),
 +
"#006633" => array ( 0 => "H", 1 => "h", 2 => "(" ),
 +
"#FF0033" => array ( 0 => "I", 1 => "i", 2 => ")" ),
 +
"#B21919" => array ( 0 => "J", 1 => "j" ),
 +
"#993300" => array ( 0 => "K", 1 => "k", 2 => "+" ),
 +
"#CC9933" => array ( 0 => "L", 1 => "l", 2 => "," ),
 +
"#999933" => array ( 0 => "M", 1 => "m", 2 => "-" ),
 +
"#FFFFBF" => array ( 0 => "N", 1 => "n", 2 => "." ),
 +
"#FFFF7F" => array ( 0 => "O", 1 => "o", 2 => "/" )
 +
);
 +
 +
for ($cd1 = 0; $cd1 < 31; $cd1++)
 +
{
 +
for ($cd2 = 0; $cd2 < count($color_chardef[$color_def[$cd1]]); $cd2++)
 +
{
 +
$string = str_replace("^". $color_chardef[$color_def[$cd1]][$cd2], "</FONT><FONT COLOR=\"" . $color_def[$cd1] . "\">", $string);
 +
}
 +
}
 +
return $string;
 +
}
 +
</pre>
 +
 
 +
Alternately, this piece of PHP uses the color indexes directly (as shown above) to achieve the same effect.  Its behavior very closely mimics the game's internal color parsing behavior.
 +
<pre>$osp_colors = array(
 +
0 => "#000000", 1 => "#ff0000", 2 => "#00ff00", 3 => "#ffff00",
 +
4 => "#0000ff", 5 => "#00ffff", 6 => "#ff00ff", 7 => "#ffffff",
 +
8 => "#ff7f00", 9 => "#7f7f7f", 10 => "#bfbfbf", 11 => "#bfbfbf",
 +
12 => "#007f00", 13 => "#7f7f00", 14 => "#00007f", 15 => "#7f0000",
 +
16 => "#7f3f00", 17 => "#ff9919", 18 => "#007f7f", 19 => "#7f007f",
 +
20 => "#007fff", 21 => "#7f00ff", 22 => "#3399cc", 23 => "#ccffcc",
 +
24 => "#006633", 25 => "#ff0033", 26 => "#b21919", 27 => "#993300",
 +
28 => "#cc9933", 29 => "#999933", 30 => "#ffffbf", 31 => "#ffff7f"
 +
);
 +
 
 +
function colorize($text)
 +
{
 +
    global $osp_colors;
 +
 
 +
    $curcolor = -1;
 +
    $nextcolor = 7;
 +
   
 +
    for ($x = 0; $x < strlen($text); $x++) {
 +
        if ($text[$x] == '^' && $text[$x + 1] != '^') {
 +
            $nextcolor = (ord($text[$x + 1]) + 16) & 31;
 +
            $x++;
 +
            continue;
 +
        }
 +
        if ($curcolor != $nextcolor) {
 +
            if ($curcolor != -1)
 +
                $buf .= "</font>";
 +
            $curcolor = $nextcolor;
 +
            $buf .= sprintf("<font color=\"%s\">", $osp_colors[$curcolor]);
 +
           
 +
        }
 +
        $buf .= htmlspecialchars($text[$x]);
 +
    }
 +
 
 +
    if ($curcolor != -1)
 +
        $buf .= "</font>";
 +
   
 +
    return $buf;
 +
}</pre>

Latest revision as of 01:58, 13 June 2007

What are they?

Color codes are used to add color to text. They were introduced in Quake III Arena and are available in most Q3 engine based games, including Enemy Territory. They can be used with most text that gets displayed ingame, including player names, chat or notices.

Usage: a caret character (^) followed by another character. Each character produces a different colour.
Example: ^1red ^2green ^4blue
Produces: red green blue

What colors are available?

There are 32 colors available -- internally, the game has a table of all 32 colors (starting with color #0) and uses the ASCII value of the character following the caret plus 16 to determine which color to use, looping back around to color #0 after color #31. The index lookup could be described in C code as '(*char + 16) & 31'.

The following table shows what the index of each color is, its HTML color code equivalent, and the characters that will produce the color in-game if placed after a caret:

IndexHTML colorCharacters
0#0000000 P p ° Ð ð
1#ff00001 Q q ± Ñ ñ
2#00ff002 R r ² Ò ò
3#ffff003 S s ³ Ó ó
4#0000ff4 T t Ž Ô ô
5#00ffff5 U u µ Õ õ
6#ff00ff6 V v ¶ Ö ö
7#ffffff7 W w · × ÷
8#ff7f008 X x ž Ø ø
9#7f7f7f9 Y y ¹ Ù ù
10#bfbfbf: Z z º Ú ú
11#bfbfbf; [ { » Û û
12#007f00< \ | Œ Ü ü
13#7f7f00= ] } œ Ý ý
14#00007f> ^ ~ Ÿ Þ þ
15#7f0000? _ ¿ ß ÿ
16#7f3f00 @ ` À à
17#ff9919! A a ¡ Á á
18#007f7f" B b ¢ Â â
19#7f007f# C c £ Ã ã
20#007fff$ D d € Ä ä
21#7f00ff% E e ¥ Å å
22#3399cc& F f Š Æ æ
23#ccffcc' G g § Ç ç
24#006633( H h š È è
25#ff0033) I i © É é
26#b21919* J j ª Ê ê
27#993300+ K k « Ë ë
28#cc9933, L l ¬ Ì ì
29#999933- M m ­ Í í
30#ffffbf. N n ® Î î
31#ffff7f/ O o ¯ Ï ï

Code Examples

Here is a little php script that can be used to parse colorcodes and return the HTML formatted, colored string:

// ©2003 Deus@pooHunter.de
// This script uses the original RGB-values that were used in RtCW:OSP which I received directly from rhea.
// AFAIK these RGB values did not change in ET/ETPro 
function parse_gamecolors($string)
{
	$string = ereg_replace("(\^)?$", "^", $string);
	$string = ereg_replace("\^\^", "&#94^", $string);
	$string = ereg_replace("(\^)?$", "", $string);
	$string = ereg_replace("\^<", "^|", $string);
	$string = ereg_replace("\<", "<", $string);
	$string = ereg_replace("\^>", "^^", $string);
	$string = ereg_replace("\>", ">", $string);
	$string = ereg_replace("\^\^", "^>", $string);
	$string = "<font color=\"#FFFFFF\">".$string."</font>";

	$color_def = array
	(
		0  => "#000000",	1  => "#FF0000",	2  => "#00FF00",	3  => "#FFFF00",
		4  => "#0000FF",	5  => "#00FFFF",	6  => "#FF00FF",	7  => "#FFFFFF",
		8  => "#FF7F00",	9  => "#7F7F7F",	10 => "#BFBFBF",	11 => "#007F00",
		12 => "#7FFF00",	13 => "#00007F",	14 => "#7F0000",	15 => "#7F4000",
		16 => "#FF9933",	17 => "#007F7F",	18 => "#7F007F",	19 => "#007F7F",
		20 => "#7F00FF",	21 => "#3399CC",	22 => "#CCFFCC",	23 => "#006633",
		24 => "#FF0033",	25 => "#B21919",	26 => "#993300",	27 => "#CC9933",
		28 => "#999933",	29 => "#FFFFBF",	30 => "#FFFF7F"
	);

	$color_chardef = array
	(
		"#000000"	=> array (	0 => "0",	1 => "P",	2 => "p"	),
		"#FF0000"	=> array (	0 => "1",	1 => "Q",	2 => "q"	),
		"#00FF00"	=> array (	0 => "2",	1 => "R",	2 => "r"	),
		"#FFFF00"	=> array (	0 => "3",	1 => "S",	2 => "s"	),
		"#0000FF"	=> array (	0 => "4",	1 => "T",	2 => "t"	),
		"#00FFFF"	=> array (	0 => "5",	1 => "U",	2 => "u"	),
		"#FF00FF"	=> array (	0 => "6",	1 => "V",	2 => "v"	),
		"#FFFFFF"	=> array (	0 => "7",	1 => "W",	2 => "w"	),
		"#FF7F00"	=> array (	0 => "8",	1 => "X",	2 => "x"	),
		"#7F7F7F"	=> array (	0 => "9",	1 => "Y",	2 => "y"	),
		"#BFBFBF"	=> array (	0 => ":",	1 => "Z",	2 => "z",
						3 => ";",	4 => "[",	5 => "{"	),
		"#007F00"	=> array (	0 => "<",	1 => "\\",	2 => "|"	),
		"#7FFF00"	=> array (	0 => "=",	1 => "]",	2 => "}"	),
		"#00007F"	=> array (	0 => ">"					),
		"#7F0000"	=> array (	0 => "?"					),
		"#7F4000"	=> array (	0 => "@",	1 => "`"			),
		"#FF9933"	=> array (	0 => "A",	1 => "a",	2 => "!"	),
		"#007F7F"	=> array (	0 => "B",	1 => "b"			),
		"#7F007F"	=> array (	0 => "C",	1 => "c",	2 => "#"	),
		"#007F7F"	=> array (	0 => "D",	1 => "d",	2 => "$"	),
		"#7F00FF"	=> array (	0 => "E",	1 => "e",	2 => "%"	),
		"#3399CC"	=> array (	0 => "F",	1 => "f",	2 => "&"	),
		"#CCFFCC"	=> array (	0 => "G",	1 => "g",	2 => "'"	),
		"#006633"	=> array (	0 => "H",	1 => "h",	2 => "("	),
		"#FF0033"	=> array (	0 => "I",	1 => "i",	2 => ")"	),
		"#B21919"	=> array (	0 => "J",	1 => "j"			),
		"#993300"	=> array (	0 => "K",	1 => "k",	2 => "+"	),
		"#CC9933"	=> array (	0 => "L",	1 => "l",	2 => ","	),
		"#999933"	=> array (	0 => "M",	1 => "m",	2 => "-"	),
		"#FFFFBF"	=> array (	0 => "N",	1 => "n",	2 => "."	),
		"#FFFF7F"	=> array (	0 => "O",	1 => "o",	2 => "/"	)
	);
		
	for ($cd1 = 0; $cd1 < 31; $cd1++)
	{
		for ($cd2 = 0; $cd2 < count($color_chardef[$color_def[$cd1]]); $cd2++)
		{
			$string = str_replace("^". $color_chardef[$color_def[$cd1]][$cd2], "</FONT><FONT COLOR=\"" . $color_def[$cd1] . "\">", $string);
		}
	}
	return $string;
}

Alternately, this piece of PHP uses the color indexes directly (as shown above) to achieve the same effect. Its behavior very closely mimics the game's internal color parsing behavior.

$osp_colors = array(
	0 => "#000000",		1 => "#ff0000",		2 => "#00ff00",		3 => "#ffff00",
	4 => "#0000ff",		5 => "#00ffff",		6 => "#ff00ff",		7 => "#ffffff",
	8 => "#ff7f00",		9 => "#7f7f7f",		10 => "#bfbfbf",	11 => "#bfbfbf",
	12 => "#007f00",	13 => "#7f7f00",	14 => "#00007f",	15 => "#7f0000",
	16 => "#7f3f00",	17 => "#ff9919",	18 => "#007f7f",	19 => "#7f007f",
	20 => "#007fff",	21 => "#7f00ff",	22 => "#3399cc",	23 => "#ccffcc",
	24 => "#006633",	25 => "#ff0033",	26 => "#b21919",	27 => "#993300",
	28 => "#cc9933",	29 => "#999933",	30 => "#ffffbf",	31 => "#ffff7f"
);

function colorize($text)
{
    global $osp_colors;

    $curcolor = -1;
    $nextcolor = 7;
    
    for ($x = 0; $x < strlen($text); $x++) {
        if ($text[$x] == '^' && $text[$x + 1] != '^') {
            $nextcolor = (ord($text[$x + 1]) + 16) & 31;
            $x++;
            continue;
        }
        if ($curcolor != $nextcolor) {
            if ($curcolor != -1)
                $buf .= "</font>";
            $curcolor = $nextcolor;
            $buf .= sprintf("<font color=\"%s\">", $osp_colors[$curcolor]);
            
        }
        $buf .= htmlspecialchars($text[$x]);
    }

    if ($curcolor != -1)
        $buf .= "</font>";
    
    return $buf;
}