Difference between revisions of "XyText 1.5"

From Second Life Wiki
Jump to navigation Jump to search
m (<lsl> tag to <source>)
 
(18 intermediate revisions by 14 users not shown)
Line 1: Line 1:
{{LSL Header}}
{{LSL Header|ml=*}}
This is a variation of XyText allowing up to 10 characters on a prim. All scripts are included.
 
<br>
Scripting tools to allow display of text on a prim: [[XyText 1.5]] , [[XyzzyText]], [[XyyyyzText]], [[XyzzyText-UTF8]], [[ZZText]], [[VariText]]
 
 
 
'''XyText 1.5''' is a variation of XyText allowing up to 10 characters on a prim. All scripts are included.
 
'''Also see [[XyzzyText]] for a much more efficient alternative for larger displays.'''
 
'''Additionally refer to [[ZZText]] and [[XyzzyText-UTF8]] for using International characters in your boards.'''
 
'''For a 1 texture numbers only refer to [[NumPad]].'''
 
==XyText Setup==
The prim size script:
The prim size script:
<pre>
<source lang="lsl2">
////////////////////////////////////////////
////////////////////////////////////////////
// XyText v1.0.3 Prim Setup Script (5 Face, Multi Texture)
// XyText v1.0.3 Prim Setup Script (5 Face, Multi Texture)
Line 18: Line 30:
     state_entry()
     state_entry()
     {
     {
         llSetPrimitiveParams([
         llSetLinkPrimitiveParamsFast(LINK_THIS, [
          PRIM_TYPE, PRIM_TYPE_PRISM, PRIM_HOLE_SQUARE, <0.199, 0.8, 0.0>, 0.30,
            PRIM_TYPE, PRIM_TYPE_PRISM, PRIM_HOLE_SQUARE, <0.199, 0.8, 0.0>, 0.30,
             ZERO_VECTOR, <1.0, 1.0, 0.0>, ZERO_VECTOR,
             ZERO_VECTOR, <1.0, 1.0, 0.0>, ZERO_VECTOR,
           
          // display a default face texture
          PRIM_TEXTURE, 1, FACE_TEXTURE, <2.48, 1.0, 0.0>, <-0.740013, 0.0, 0.0>, 0.0,
          PRIM_TEXTURE, 6, FACE_TEXTURE, <1.0, 1.0, 0.0>, <0.0, 0.0, 0.0>, 0.0,
          PRIM_TEXTURE, 4, FACE_TEXTURE, <-14.75, 1.0, 0.0>, <0.130009, 0.0, 0.0>, 0.0,
          PRIM_TEXTURE, 7, FACE_TEXTURE, <1.0, 1.0, 0.0>, <0.0, 0.0, 0.0>, 0.0,
          PRIM_TEXTURE, 3, FACE_TEXTURE, <2.48, 1.0, 0.0>, <-0.255989, 0.0, 0.0>, 0.0,


          // show transparent textures for the other sides
            // display a default face texture
          PRIM_TEXTURE, 0, TRANSPARENT, <0.1, 0.1, 0>, ZERO_VECTOR, 0.0,
            PRIM_TEXTURE, 1, FACE_TEXTURE, <2.48, 1.0, 0.0>, <-0.740013, 0.0, 0.0>, 0.0,
          PRIM_TEXTURE, 2, TRANSPARENT, <0.1, 0.1, 0>, ZERO_VECTOR, 0.0,
            PRIM_TEXTURE, 6, FACE_TEXTURE, <1.0, 1.0, 0.0>, <0.0, 0.0, 0.0>, 0.0,
          PRIM_TEXTURE, 5, TRANSPARENT, <0.1, 0.1, 0>, ZERO_VECTOR, 0.0,
            PRIM_TEXTURE, 4, FACE_TEXTURE, <-14.75, 1.0, 0.0>, <0.130009, 0.0, 0.0>, 0.0,
            PRIM_TEXTURE, 7, FACE_TEXTURE, <1.0, 1.0, 0.0>, <0.0, 0.0, 0.0>, 0.0,
            PRIM_TEXTURE, 3, FACE_TEXTURE, <2.48, 1.0, 0.0>, <-0.255989, 0.0, 0.0>, 0.0,
 
            // show transparent textures for the other sides
            PRIM_TEXTURE, 0, TRANSPARENT, <0.1, 0.1, 0.0>, ZERO_VECTOR, 0.0,
            PRIM_TEXTURE, 2, TRANSPARENT, <0.1, 0.1, 0.0>, ZERO_VECTOR, 0.0,
            PRIM_TEXTURE, 5, TRANSPARENT, <0.1, 0.1, 0.0>, ZERO_VECTOR, 0.0,


          PRIM_SIZE, <0.03, 2.89, 0.5>
            PRIM_SIZE, <0.03, 2.89, 0.5>]);
        ]);


         // Remove ourselves from inventory.
         // Remove ourselves from inventory.
Line 41: Line 52:
     }
     }
}
}
</pre>
</source>
<br>
 
The modified xyText cell script (written by Xylor Baysklef):
==XyText==
<pre>
The modified XyText cell script (written by Xylor Baysklef)
<source lang="lsl2">
////////////////////////////////////////////
////////////////////////////////////////////
// XyText v1.0.3 Script (5 Face, Multi Texture)
// XyText v1.0.3 Script (5 Face, Multi Texture)
Line 55: Line 67:
//
//
////////////////////////////////////////////
////////////////////////////////////////////
 
/////////////// CONSTANTS ///////////////////
/////////////// CONSTANTS ///////////////////
// XyText Message Map.
// XyText Message Map.
Line 65: Line 77:
integer SET_THICKNESS      = 204006;
integer SET_THICKNESS      = 204006;
integer SET_COLOR          = 204007;
integer SET_COLOR          = 204007;
 
// This is an extended character escape sequence.
// This is an extended character escape sequence.
string  ESCAPE_SEQUENCE = "\\e";
string  ESCAPE_SEQUENCE = "\\e";
 
// This is used to get an index for the extended character.
// This is used to get an index for the extended character.
string  EXTENDED_INDEX  = "123456789abcdef";
string  EXTENDED_INDEX  = "123456789abcdef";
 
// Face numbers.
// Face numbers.
integer FACE_1          = 3;
integer FACE_1          = 3;
Line 78: Line 90:
integer FACE_4          = 6;
integer FACE_4          = 6;
integer FACE_5          = 1;
integer FACE_5          = 1;
 
// Used to hide the text after a fade-out.
// Used to hide the text after a fade-out.
key     TRANSPARENT    = "701917a8-d614-471f-13dd-5f4644e36e3c";
key TRANSPARENT    = "701917a8-d614-471f-13dd-5f4644e36e3c";
// This is a list of textures for all 2-character combinations.
// This is a list of textures for all 2-character combinations.
list   CHARACTER_GRID  = [
list CHARACTER_GRID  = [
         "00e9f9f7-0669-181c-c192-7f8e67678c8d",
         "00e9f9f7-0669-181c-c192-7f8e67678c8d",
         "347a5cb6-0031-7ec0-2fcf-f298eebf3c0e",
         "347a5cb6-0031-7ec0-2fcf-f298eebf3c0e",
Line 149: Line 161:
         "b3017e02-c063-5185-acd5-1ef5f9d79b89",
         "b3017e02-c063-5185-acd5-1ef5f9d79b89",
         "4dcff365-1971-3c2b-d73c-77e1dc54242a"
         "4dcff365-1971-3c2b-d73c-77e1dc54242a"
          ];
        ];
 
///////////// END CONSTANTS ////////////////
///////////// END CONSTANTS ////////////////
 
///////////// GLOBAL VARIABLES ///////////////
///////////// GLOBAL VARIABLES ///////////////
// All displayable characters.  Default to ASCII order.
// All displayable characters.  Default to ASCII order.
Line 169: Line 181:
float  gCellHoldDelay      = 1.0;
float  gCellHoldDelay      = 1.0;
/////////// END GLOBAL VARIABLES ////////////
/////////// END GLOBAL VARIABLES ////////////
 
ResetCharIndex() {
ResetCharIndex()
{
     gCharIndex  = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`";
     gCharIndex  = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`";
     // \" <-- Fixes LSL syntax highlighting bug.
     // \" <-- Fixes LSL syntax highlighting bug.
Line 176: Line 189:
     gCharIndex += "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
     gCharIndex += "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
}
}
 
vector GetGridPos(integer index1, integer index2) {
vector GetGridPos(integer index1, integer index2)
{
     // There are two ways to use the lookup table...
     // There are two ways to use the lookup table...
     integer Col;
     integer Col;
     integer Row;
     integer Row;
     if (index1 >= index2) {
     if (index1 >= index2)
    {
         // In this case, the row is the index of the first character:
         // In this case, the row is the index of the first character:
         Row = index1;
         Row = index1;
Line 187: Line 202:
         Col = index2 * 2;
         Col = index2 * 2;
     }
     }
     else { // Index1 < Index2
     // Index1 < Index2
    else
    {
         // In this case, the row is the index of the second character:
         // In this case, the row is the index of the second character:
         Row = index2;
         Row = index2;
Line 195: Line 212:
     return <Col, Row, 0>;
     return <Col, Row, 0>;
}
}
 
string GetGridTexture(vector grid_pos) {
string GetGridTexture(vector grid_pos)
{
     // Calculate the texture in the grid to use.
     // Calculate the texture in the grid to use.
     integer GridCol = llRound(grid_pos.x) / 20;
     integer GridCol = llRound(grid_pos.x) / 20;
     integer GridRow = llRound(grid_pos.y) / 10;
     integer GridRow = llRound(grid_pos.y) / 10;
 
     // Lookup the texture.
     // Lookup the texture.
     key Texture = llList2Key(CHARACTER_GRID, GridRow * (GridRow + 1) / 2 + GridCol);
     key Texture = llList2Key(CHARACTER_GRID, GridRow * (GridRow + 1) / 2 + GridCol);
     return Texture;
     return Texture;
}
}
 
vector GetGridOffset(vector grid_pos) {
vector GetGridOffset(vector grid_pos)
{
     // Zoom in on the texture showing our character pair.
     // Zoom in on the texture showing our character pair.
     integer Col = llRound(grid_pos.x) % 20;
     integer Col = llRound(grid_pos.x) % 20;
     integer Row = llRound(grid_pos.y) % 10;
     integer Row = llRound(grid_pos.y) % 10;
 
     // Return the offset in the texture.
     // Return the offset in the texture.
     return <-0.45 + 0.05 * Col, 0.45 - 0.1 * Row, 0.0>;
     return <-0.45 + 0.05 * Col, 0.45 - 0.1 * Row, 0.0>;
}
}
 
ShowChars(vector grid_pos1, vector grid_pos2, vector grid_pos3, vector grid_pos4, vector grid_pos5) {
ShowChars(vector grid_pos1, vector grid_pos2, vector grid_pos3, vector grid_pos4, vector grid_pos5)
{
   // Set the primitive textures directly.
   // Set the primitive textures directly.
   
             
  llSetPrimitiveParams( [
    llSetLinkPrimitiveParamsFast(LINK_THIS, [
         PRIM_TEXTURE, FACE_1, GetGridTexture(grid_pos1), <0.25, 0.1, 0>, GetGridOffset(grid_pos1) + <0.075, 0, 0>, 0.0,
         PRIM_TEXTURE, FACE_1, GetGridTexture(grid_pos1), <0.25, 0.1, 0>, GetGridOffset(grid_pos1) + <0.075, 0, 0>, 0.0,
         PRIM_TEXTURE, FACE_2, GetGridTexture(grid_pos2), <0.1, 0.1, 0>, GetGridOffset(grid_pos2), 0.0,
         PRIM_TEXTURE, FACE_2, GetGridTexture(grid_pos2), <0.1, 0.1, 0>, GetGridOffset(grid_pos2), 0.0,
         PRIM_TEXTURE, FACE_3, GetGridTexture(grid_pos3), <-1.48, 0.1, 0>, GetGridOffset(grid_pos3)+ <0.37, 0, 0>, 0.0,
         PRIM_TEXTURE, FACE_3, GetGridTexture(grid_pos3), <-1.48, 0.1, 0>, GetGridOffset(grid_pos3)+ <0.37, 0, 0>, 0.0,
         PRIM_TEXTURE, FACE_4, GetGridTexture(grid_pos4), <0.1, 0.1, 0>, GetGridOffset(grid_pos4), 0.0,
         PRIM_TEXTURE, FACE_4, GetGridTexture(grid_pos4), <0.1, 0.1, 0>, GetGridOffset(grid_pos4), 0.0,
         PRIM_TEXTURE, FACE_5, GetGridTexture(grid_pos5), <0.25, 0.1, 0>, GetGridOffset(grid_pos5) - <0.075, 0, 0>, 0.0
         PRIM_TEXTURE, FACE_5, GetGridTexture(grid_pos5), <0.25, 0.1, 0>, GetGridOffset(grid_pos5) - <0.075, 0, 0>, 0.0]);
        ]);
}
}
 
RenderString(string str) {
RenderString(string str)
{
     // Get the grid positions for each pair of characters.
     // Get the grid positions for each pair of characters.
     vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)),
     vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)),
Line 240: Line 260:
     vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)),
     vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)),
                                   llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) );                                   
                                   llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) );                                   
 
     // Use these grid positions to display the correct textures/offsets.
     // Use these grid positions to display the correct textures/offsets.
     ShowChars(GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);
     ShowChars(GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);
}
}
 
RenderWithEffects(string str) {
RenderWithEffects(string str)
{
     // Get the grid positions for each pair of characters.
     // Get the grid positions for each pair of characters.
     vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)),
     vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)),
Line 257: Line 278:
     vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)),
     vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)),
                                   llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) );                                   
                                   llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) );                                   
 
       // First set the alpha to the lowest possible.
       // First set the alpha to the lowest possible.
  llSetAlpha(0.05, ALL_SIDES);
    llSetAlpha(0.05, ALL_SIDES);
 
     // Use these grid positions to display the correct textures/offsets.
     // Use these grid positions to display the correct textures/offsets.
     ShowChars(GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);
     ShowChars(GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);
 
     float Alpha;
     float Alpha;
     for (Alpha = 0.10; Alpha <= 1.0; Alpha += 0.05)
     for (Alpha = 0.10; Alpha <= 1.0; Alpha += 0.05)
    {
       llSetAlpha(Alpha, ALL_SIDES);
       llSetAlpha(Alpha, ALL_SIDES);
          // See if we want to fade out as well.
    }
  if (gCellHoldDelay < 0.0)
    // See if we want to fade out as well.
    if (gCellHoldDelay < 0.0)
    {
       // No, bail out. (Just keep showing the string at full strength).
       // No, bail out. (Just keep showing the string at full strength).
       return;
       return;
          // Hold the text for a while.
    }
  llSleep(gCellHoldDelay);
    // Hold the text for a while.
      // Now fade out.
    llSleep(gCellHoldDelay);
  for (Alpha = 0.95; Alpha >= 0.05; Alpha -= 0.05)
    // Now fade out.
      llSetAlpha(Alpha, ALL_SIDES);
    for (Alpha = 0.95; Alpha >= 0.05; Alpha -= 0.05)
          // Make the text transparent to fully hide it.
    {
  llSetTexture(TRANSPARENT, ALL_SIDES);
        llSetAlpha(Alpha, ALL_SIDES);
    }
    // Make the text transparent to fully hide it.
    llSetTexture(TRANSPARENT, ALL_SIDES);
}
}
 
RenderExtended(string str) {
RenderExtended(string str)
{
     // Look for escape sequences.
     // Look for escape sequences.
     list Parsed      = llParseString2List(str, [], [ESCAPE_SEQUENCE]);
     list Parsed      = llParseString2List(str, [], [ESCAPE_SEQUENCE]);
     integer ParsedLen = llGetListLength(Parsed);
     integer ParsedLen = llGetListLength(Parsed);
 
     // Create a list of index values to work with.
     // Create a list of index values to work with.
     list Indices;
     list Indices;
     // We start with room for 6 indices.
     // We start with room for 6 indices.
     integer IndicesLeft = 10;
     integer IndicesLeft = 10;
 
     integer i;
     integer i;
     string Token;
     string Token;
Line 295: Line 323:
     integer LastWasEscapeSequence = FALSE;
     integer LastWasEscapeSequence = FALSE;
     // Work from left to right.
     // Work from left to right.
     for (i = 0; i < ParsedLen && IndicesLeft > 0; i++) {
     for (i = 0; i < ParsedLen && IndicesLeft > 0; i++)
    {
         Token = llList2String(Parsed, i);
         Token = llList2String(Parsed, i);
 
         // If this is an escape sequence, just set the flag and move on.
         // If this is an escape sequence, just set the flag and move on.
         if (Token == ESCAPE_SEQUENCE) {
         if (Token == ESCAPE_SEQUENCE)
        {
             LastWasEscapeSequence = TRUE;
             LastWasEscapeSequence = TRUE;
         }
         }
         else { // Token != ESCAPE_SEQUENCE
         // Token != ESCAPE_SEQUENCE
        else
        {
             // Otherwise this is a normal token.  Check its length.
             // Otherwise this is a normal token.  Check its length.
             Clipped = FALSE;
             Clipped = FALSE;
             integer TokenLength = llStringLength(Token);
             integer TokenLength = llStringLength(Token);
             // Clip if necessary.
             // Clip if necessary.
             if (TokenLength > IndicesLeft) {
             if (TokenLength > IndicesLeft)
            {
                 Token = llGetSubString(Token, 0, IndicesLeft - 1);
                 Token = llGetSubString(Token, 0, IndicesLeft - 1);
                 TokenLength = llStringLength(Token);
                 TokenLength = llStringLength(Token);
Line 315: Line 348:
             else
             else
                 IndicesLeft -= TokenLength;
                 IndicesLeft -= TokenLength;
 
             // Was the previous token an escape sequence?
             // Was the previous token an escape sequence?
             if (LastWasEscapeSequence) {
             if (LastWasEscapeSequence)
            {
                 // Yes, the first character is an escape character, the rest are normal.
                 // Yes, the first character is an escape character, the rest are normal.
 
                 // This is the extended character.
                 // This is the extended character.
                 Indices += [llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95];
                 Indices += [llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95];
 
                 // These are the normal characters.
                 // These are the normal characters.
                 integer j;
                 integer j;
Line 328: Line 362:
                     Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];
                     Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];
             }
             }
             else { // Normal string.
             // Normal string.
            else
            {
                 // Just add the characters normally.
                 // Just add the characters normally.
                 integer j;
                 integer j;
                 for (j = 0; j < TokenLength; j++)
                 for (j = 0; j < TokenLength; j++)
                {
                     Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];
                     Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];
                }
             }
             }
 
             // Unset this flag, since this was not an escape sequence.
             // Unset this flag, since this was not an escape sequence.
             LastWasEscapeSequence = FALSE;
             LastWasEscapeSequence = FALSE;
         }
         }
     }
     }
 
     // Use the indices to create grid positions.
     // Use the indices to create grid positions.
     vector GridPos1 = GetGridPos( llList2Integer(Indices, 0), llList2Integer(Indices, 1) );
     vector GridPos1 = GetGridPos( llList2Integer(Indices, 0), llList2Integer(Indices, 1) );
Line 346: Line 384:
     vector GridPos4 = GetGridPos( llList2Integer(Indices, 6), llList2Integer(Indices, 7) );
     vector GridPos4 = GetGridPos( llList2Integer(Indices, 6), llList2Integer(Indices, 7) );
     vector GridPos5 = GetGridPos( llList2Integer(Indices, 8), llList2Integer(Indices, 9) );     
     vector GridPos5 = GetGridPos( llList2Integer(Indices, 8), llList2Integer(Indices, 9) );     
 
     // Use these grid positions to display the correct textures/offsets.
     // Use these grid positions to display the correct textures/offsets.
     ShowChars(GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);
     ShowChars(GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);
}
}
 
integer ConvertIndex(integer index) {
integer ConvertIndex(integer index)
{
     // This converts from an ASCII based index to our indexing scheme.
     // This converts from an ASCII based index to our indexing scheme.
     if (index >= 32) // ' ' or higher
     if (index >= 32) // ' ' or higher
         index -= 32;
         index -= 32;
     else { // index < 32
     // index < 32
    else
    {
         // Quick bounds check.
         // Quick bounds check.
         if (index > 15)
         if (index > 15)
             index = 15;
             index = 15;
 
         index += 94; // extended characters
         index += 94; // extended characters
     }
     }
 
     return index;
     return index;
}
}
 
default {
default
     state_entry() {
{
     state_entry()
    {
         // Initialize the character index.
         // Initialize the character index.
         ResetCharIndex();
         ResetCharIndex();
 
         //llSay(0, "Free Memory: " + (string) llGetFreeMemory());
         //llSay(0, "Free Memory: " + (string) llGetFreeMemory());
     }
     }
 
     link_message(integer sender, integer channel, string data, key id) {
     link_message(integer sender, integer channel, string data, key id)
         if (channel == DISPLAY_STRING) {
    {
         if (channel == DISPLAY_STRING)
        {
             RenderString(data);
             RenderString(data);
             return;
             return;
         }
         }
         if (channel == DISPLAY_EXTENDED) {
         if (channel == DISPLAY_EXTENDED)
        {
             RenderExtended(data);
             RenderExtended(data);
             return;
             return;
         }
         }
         if (channel == gCellChannel) {
         if (channel == gCellChannel)
        {
             // Extract the characters we are interested in, and use those to render.
             // Extract the characters we are interested in, and use those to render.
             string TextToRender = llGetSubString(data, gCellCharPosition, gCellCharPosition + 9);
             string TextToRender = llGetSubString(data, gCellCharPosition, gCellCharPosition + 9);
Line 392: Line 439:
             return;
             return;
         }
         }
         if (channel == REMAP_INDICES) {
         if (channel == REMAP_INDICES)
        {
             // Parse the message, splitting it up into index values.
             // Parse the message, splitting it up into index values.
             list Parsed = llCSV2List(data);
             list Parsed = llCSV2List(data);
             integer i;
             integer i;
             // Go through the list and swap each pair of indices.
             // Go through the list and swap each pair of indices.
             for (i = 0; i < llGetListLength(Parsed); i += 2) {
             for (i = 0; i < llGetListLength(Parsed); i += 2)
            {
                 integer Index1 = ConvertIndex( llList2Integer(Parsed, i) );
                 integer Index1 = ConvertIndex( llList2Integer(Parsed, i) );
                 integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) );
                 integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) );
 
                 // Swap these index values.
                 // Swap these index values.
                 string Value1 = llGetSubString(gCharIndex, Index1, Index1);
                 string Value1 = llGetSubString(gCharIndex, Index1, Index1);
                 string Value2 = llGetSubString(gCharIndex, Index2, Index2);
                 string Value2 = llGetSubString(gCharIndex, Index2, Index2);
 
                 gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1);
                 gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1);
                 gCharIndex = llInsertString(gCharIndex, Index1, Value2);
                 gCharIndex = llInsertString(gCharIndex, Index1, Value2);
 
                 gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2);
                 gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2);
                 gCharIndex = llInsertString(gCharIndex, Index2, Value1);
                 gCharIndex = llInsertString(gCharIndex, Index2, Value1);
Line 413: Line 462:
             return;
             return;
         }
         }
         if (channel == RESET_INDICES) {
         if (channel == RESET_INDICES)
        {
             // Restore the character index back to default settings.
             // Restore the character index back to default settings.
             ResetCharIndex();
             ResetCharIndex();
             return;
             return;
         }
         }
         if (channel == SET_CELL_INFO) {
         if (channel == SET_CELL_INFO)
        {
             // Change the channel we listen to for cell commands, and the
             // Change the channel we listen to for cell commands, and the
             // starting character position to extract from.
             // starting character position to extract from.
Line 424: Line 475:
             gCellChannel        = (integer) llList2String(Parsed, 0);
             gCellChannel        = (integer) llList2String(Parsed, 0);
             gCellCharPosition  = (integer) llList2String(Parsed, 1);
             gCellCharPosition  = (integer) llList2String(Parsed, 1);
          gCellUseFading      = (integer) llList2String(Parsed, 2);
            gCellUseFading      = (integer) llList2String(Parsed, 2);
          gCellHoldDelay      = (float)  llList2String(Parsed, 3);             
            gCellHoldDelay      = (float)  llList2String(Parsed, 3);             
             return;
             return;
         }
         }
         if (channel == SET_THICKNESS) {
         if (channel == SET_THICKNESS)
          // Set our z scale to thickness, while staying fixed
        {
          // in position relative the prim below us.
            // Set our z scale to thickness, while staying fixed
          vector Scale    = llGetScale();
            // in position relative the prim below us.
          float Thickness = (float) data;
            vector Scale    = llGetScale();
                      // Reposition only if this isn't the root prim.
            float Thickness = (float) data;
          integer ThisLink = llGetLinkNumber();
            // Reposition only if this isn't the root prim.
          if (ThisLink != 0 || ThisLink != 1) {
            integer ThisLink = llGetLinkNumber();
              // This is not the root prim.
            if (ThisLink != 0 || ThisLink != 1) {
              vector Up = llRot2Up(llGetLocalRot());
                // This is not the root prim.
              float DistanceToMove = Thickness / 2.0 - Scale.z / 2.0;
                vector Up = llRot2Up(llGetLocalRot());
              vector Pos = llGetLocalPos();
                float DistanceToMove = Thickness / 2.0 - Scale.z / 2.0;
              llSetPos(Pos + DistanceToMove * Up);
                vector Pos = llGetLocalPos();
          }
                llSetPos(Pos + DistanceToMove * Up);
          // Apply the new thickness.
            }
          Scale.z = Thickness;
            // Apply the new thickness.
          llSetScale(Scale);
            Scale.z = Thickness;
          return;
            llSetScale(Scale);
            return;
         }
         }
         if (channel == SET_COLOR) {
         if (channel == SET_COLOR)
        {
           vector newColor = (vector)data;
           vector newColor = (vector)data;
           llSetColor(newColor, ALL_SIDES);
           llSetColor(newColor, ALL_SIDES);
         }        
         }
     }
     }
}
}
</pre>
</source>
<br>
 
The last script is the script that I tweaked to allow up to 500 characters on 50 cells. It WILL work with a lower amount of cells though. The script:
==XyText Board Control==
<pre>
This last script is a script that allows an unlimited number of cells to be used together. The script:
<source lang="lsl2">
////////////////////////////////////////////
////////////////////////////////////////////
//  
// XyText Board Control
//
//
// Written by Tdub Dowler
// Written by Tdub Dowler
// Modified by Awsoonn Rawley
// Refactored by Strife Onizuka
////////////////////////////////////////////
////////////////////////////////////////////
 
/////////////// CONSTANTS ///////////////////
/////////////// CONSTANTS /////////////////
// XyText Message Map.
// XyText Message Map.
integer SET_LINE_CHANNEL = 100100;
integer SET_LINE_CHANNEL   = 100100;
integer DISPLAY_STRING      = 204000;
integer DISPLAY_STRING      = 204000;
integer DISPLAY_EXTENDED    = 204001;
integer DISPLAY_EXTENDED    = 204001;
Line 471: Line 528:
integer RESET_INDICES      = 204003;
integer RESET_INDICES      = 204003;
integer SET_CELL_INFO      = 204004;
integer SET_CELL_INFO      = 204004;
string  MSG                = "Testing, 1,2,3";
string  LOAD_MSG            = "Loading...";
///////////// END CONSTANTS ////////////////
///////////// END CONSTANTS ////////////////
 
integer prims;
SetText(string msg)
{
    llMessageLinked(LINK_SET, SET_LINE_CHANNEL, msg, "");
}
XytstOrder()
{
    // Fills each cell of the board with it's number.
    string  str = "";
    integer i = 0;
    do
    {
        str += llGetSubString("          " + (string)i,-10,-1);
        llSetText("Generating Pattern: " + (string)i, <0,1,0>, 1.0);
    }while(++i < prims);
    llSetText("Displaying Order Test...", <0,1,0>, 1.0);
    // Send the message
    llMessageLinked(LINK_SET, SET_LINE_CHANNEL, str, "");
    llSetText("", ZERO_VECTOR, 0.0);
}
default
default
{
{
Line 480: Line 563:
         llResetScript();
         llResetScript();
     }
     }
     state_entry()
     state_entry()
     {
     {
         integer ThisLink = llGetLinkNumber();
         // Determin the number of prims.
        llMessageLinked(LINK_SET, DISPLAY_STRING, "", "");
        prims = llGetNumberOfPrims();
         //Now time to set the cell info
         llMessageLinked(ThisLink , SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 0]), "");
         // Clear the screen.
        llMessageLinked(ThisLink + 1, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 10]), "");
         llMessageLinked(LINK_SET, DISPLAY_STRING, LOAD_MSG, "");
         llMessageLinked(ThisLink + 2, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 20]), "");
        llMessageLinked(ThisLink + 3, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 30]), "");
         integer StartLink = llGetLinkNumber() + 1;
         llMessageLinked(ThisLink + 4, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 40]), "");
         // Configure the board.
         llMessageLinked(ThisLink + 5, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 50]), "");
         integer i = 0;
        llMessageLinked(ThisLink + 6, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 60]), "");
         do
         llMessageLinked(ThisLink + 7, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 70]), "");
            llMessageLinked(StartLink + i, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, i * 10]), "");
        llMessageLinked(ThisLink + 8, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 80]), "");
         while( ++i < prims );
        llMessageLinked(ThisLink + 9, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 90]), "");
        llMessageLinked(ThisLink + 10, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 100]), "");
         // Build this script in world to reveal the secret message!
        llMessageLinked(ThisLink + 11, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 110]), "");
         SetText( llBase64ToString("SXMgdGhhdCBub3QgY29vbCBvciB3aGF0PyA6KQ==") );
        llMessageLinked(ThisLink + 12, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 120]), "");
    }
         llMessageLinked(ThisLink + 13, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 130]), "");
        llMessageLinked(ThisLink + 14, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 140]), "");
    touch_end(integer num)
        llMessageLinked(ThisLink + 15, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 150]), "");
    {
         llMessageLinked(ThisLink + 16, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 160]), "");
         // This can be used to help find mislinked prims. Its not required at all.
         llMessageLinked(ThisLink + 17, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 170]), "");
         XytstOrder();  
        llMessageLinked(ThisLink + 18, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 180]), "");
        llMessageLinked(ThisLink + 19, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 190]), "");
        llMessageLinked(ThisLink + 20, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 200]), "");
        llMessageLinked(ThisLink + 21, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 210]), "");
        llMessageLinked(ThisLink + 22, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 220]), "");
        llMessageLinked(ThisLink + 23, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 230]), "");
        llMessageLinked(ThisLink + 24, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 240]), "");
        llMessageLinked(ThisLink + 25, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 250]), "");
        llMessageLinked(ThisLink + 26, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 260]), "");
        llMessageLinked(ThisLink + 27, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 270]), "");
        llMessageLinked(ThisLink + 28, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 280]), "");
        llMessageLinked(ThisLink + 29, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 290]), "");
        llMessageLinked(ThisLink + 30, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 300]), "");
        llMessageLinked(ThisLink + 31, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 310]), "");
        llMessageLinked(ThisLink + 32, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 320]), "");
        llMessageLinked(ThisLink + 33, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 340]), "");
        llMessageLinked(ThisLink + 34, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 350]), "");
        llMessageLinked(ThisLink + 35, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 360]), "");
        llMessageLinked(ThisLink + 36, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 370]), "");
        llMessageLinked(ThisLink + 37, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 380]), "");
        llMessageLinked(ThisLink + 38, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 390]), "");
        llMessageLinked(ThisLink + 39, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 400]), "");
        llMessageLinked(ThisLink + 40, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 410]), "");
        llMessageLinked(ThisLink + 41, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 420]), "");
        llMessageLinked(ThisLink + 42, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 430]), "");
        llMessageLinked(ThisLink + 43, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 440]), "");
        llMessageLinked(ThisLink + 44, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 450]), "");
        llMessageLinked(ThisLink + 45, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 460]), "");
        llMessageLinked(ThisLink + 46, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 470]), "");
        llMessageLinked(ThisLink + 47, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, 480]), "");
        llSleep(1);
         //Send the message
         llMessageLinked(LINK_SET, SET_LINE_CHANNEL, MSG, "");
     }
     }
}
}
</pre>
</source>
<br>
<br>
'''Note:''' For new scripters/builders: Text for this script is displayed in the reverse order by which objects were linked. Breaks in the lines for multiline scripts are possible using the '\n' for newline, but a multiline linked object does not detect this. Theoretically, adding a message which communicates relative axis information (traditionally, z axis) could be used to allow for line breaks.
=Example Use=
<source lang="lsl2">
// XyText Message Map.
integer SET_LINE_CHANNEL    = 100100; //for multi-cell spanning text
integer DISPLAY_STRING      = 204000;
integer DISPLAY_EXTENDED    = 204001;
integer REMAP_INDICES      = 204002;
integer RESET_INDICES      = 204003;
integer SET_CELL_INFO      = 204004;
llMessageLinked(LINK_SET, DISPLAY_STRING, "text to display", "");
</source>
Many thanks to Xylor Baysklef and Kermitt Quick.
Many thanks to Xylor Baysklef and Kermitt Quick.
{{#vardefine:sort|Key Pad Door}}{{LSLC|Library}}{{LSLC|Examples}}
 
 
{{LSLC|Library}}
{{#vardefine:sort|Key Pad Door}}

Latest revision as of 09:26, 25 January 2015

Scripting tools to allow display of text on a prim: XyText 1.5 , XyzzyText, XyyyyzText, XyzzyText-UTF8, ZZText, VariText


XyText 1.5 is a variation of XyText allowing up to 10 characters on a prim. All scripts are included.

Also see XyzzyText for a much more efficient alternative for larger displays.

Additionally refer to ZZText and XyzzyText-UTF8 for using International characters in your boards.

For a 1 texture numbers only refer to NumPad.

XyText Setup

The prim size script:

////////////////////////////////////////////
// XyText v1.0.3 Prim Setup Script (5 Face, Multi Texture)
//
// Rewritten by Tdub Dowler
//
////////////////////////////////////////////

string FACE_TEXTURE = "09b04244-9569-d21f-6de0-4bbcf5552222";
string  TRANSPARENT = "701917a8-d614-471f-13dd-5f4644e36e3c";

default
{
    state_entry()
    {
        llSetLinkPrimitiveParamsFast(LINK_THIS, [
            PRIM_TYPE, PRIM_TYPE_PRISM, PRIM_HOLE_SQUARE, <0.199, 0.8, 0.0>, 0.30,
            ZERO_VECTOR, <1.0, 1.0, 0.0>, ZERO_VECTOR,

            // display a default face texture
            PRIM_TEXTURE, 1, FACE_TEXTURE, <2.48, 1.0, 0.0>, <-0.740013, 0.0, 0.0>, 0.0,
            PRIM_TEXTURE, 6, FACE_TEXTURE, <1.0, 1.0, 0.0>, <0.0, 0.0, 0.0>, 0.0,
            PRIM_TEXTURE, 4, FACE_TEXTURE, <-14.75, 1.0, 0.0>, <0.130009, 0.0, 0.0>, 0.0,
            PRIM_TEXTURE, 7, FACE_TEXTURE, <1.0, 1.0, 0.0>, <0.0, 0.0, 0.0>, 0.0,
            PRIM_TEXTURE, 3, FACE_TEXTURE, <2.48, 1.0, 0.0>, <-0.255989, 0.0, 0.0>, 0.0,

            // show transparent textures for the other sides
            PRIM_TEXTURE, 0, TRANSPARENT, <0.1, 0.1, 0.0>, ZERO_VECTOR, 0.0,
            PRIM_TEXTURE, 2, TRANSPARENT, <0.1, 0.1, 0.0>, ZERO_VECTOR, 0.0,
            PRIM_TEXTURE, 5, TRANSPARENT, <0.1, 0.1, 0.0>, ZERO_VECTOR, 0.0,

            PRIM_SIZE, <0.03, 2.89, 0.5>]);

        // Remove ourselves from inventory.
        llRemoveInventory(llGetScriptName());
    }
}

XyText

The modified XyText cell script (written by Xylor Baysklef)

////////////////////////////////////////////
// XyText v1.0.3 Script (5 Face, Multi Texture)
//
// Written by Xylor Baysklef
//
// Modified by Thraxis Epsilon January 20, 2006
// Added Support for 5 Face Prim, based on modification
// of XyText v1.1.1 by Kermitt Quick for Single Texture.
//
////////////////////////////////////////////
 
/////////////// CONSTANTS ///////////////////
// XyText Message Map.
integer DISPLAY_STRING      = 204000;
integer DISPLAY_EXTENDED    = 204001;
integer REMAP_INDICES       = 204002;
integer RESET_INDICES       = 204003;
integer SET_CELL_INFO       = 204004;
integer SET_THICKNESS       = 204006;
integer SET_COLOR           = 204007;
 
// This is an extended character escape sequence.
string  ESCAPE_SEQUENCE = "\\e";
 
// This is used to get an index for the extended character.
string  EXTENDED_INDEX  = "123456789abcdef";
 
// Face numbers.
integer FACE_1          = 3;
integer FACE_2          = 7;
integer FACE_3          = 4;
integer FACE_4          = 6;
integer FACE_5          = 1;
 
// Used to hide the text after a fade-out.
key		TRANSPARENT     = "701917a8-d614-471f-13dd-5f4644e36e3c";
// This is a list of textures for all 2-character combinations.
list	CHARACTER_GRID  = [
        "00e9f9f7-0669-181c-c192-7f8e67678c8d",
        "347a5cb6-0031-7ec0-2fcf-f298eebf3c0e",
        "4e7e689e-37f1-9eca-8596-a958bbd23963",
        "19ea9c21-67ba-8f6f-99db-573b1b877eb1",
        "dde7b412-cda1-652f-6fc2-73f4641f96e1",
        "af6fa3bb-3a6c-9c4f-4bf5-d1c126c830da",
        "a201d3a2-364b-43b6-8686-5881c0f82a94",
        "b674dec8-fead-99e5-c28d-2db8e4c51540",
        "366e05f3-be6b-e5cf-c33b-731dff649caa",
        "75c4925c-0427-dc0c-c71c-e28674ff4d27",
        "dcbe166b-6a97-efb2-fc8e-e5bc6a8b1be6",
        "0dca2feb-fc66-a762-db85-89026a4ecd68",
        "a0fca76f-503a-946b-9336-0a918e886f7a",
        "67fb375d-89a1-5a4f-8c7a-0cd1c066ffc4",
        "300470b2-da34-5470-074c-1b8464ca050c",
        "d1f8e91c-ce2b-d85e-2120-930d3b630946",
        "2a190e44-7b29-dadb-0bff-c31adaf5a170",
        "75d55e71-f6f8-9835-e746-a45f189f30a1",
        "300fac33-2b30-3da3-26bc-e2d70428ec19",
        "0747c776-011a-53ce-13ee-8b5bb9e87c1e",
        "85a855c3-a94f-01ca-33e0-7dde92e727e2",
        "cbc1dab2-2d61-2986-1949-7a5235c954e1",
        "f7aef047-f266-9596-16df-641010edd8e1",
        "4c34ebf7-e5e1-2e1a-579f-e224d9d5e71b",
        "4a69e98c-26a5-ad05-e92e-b5b906ad9ef9",
        "462a9226-2a97-91ac-2d89-57ab33334b78",
        "20b24b3a-8c57-82ee-c6ed-555003f5dbcd",
        "9b481daa-9ea8-a9fa-1ee4-ab9a0d38e217",
        "c231dbdc-c842-15b0-7aa6-6da14745cfdc",
        "c97e3cbb-c9a3-45df-a0ae-955c1f4bf9cf",
        "f1e7d030-ff80-a242-cb69-f6951d4eae3b",
        "ed32d6c4-d733-c0f1-f242-6df1d222220d",
        "88f96a30-dccf-9b20-31ef-da0dfeb23c72",
        "252f2595-58b8-4bcc-6515-fa274d0cfb65",
        "f2838c4f-de80-cced-dff8-195dfdf36b2c",
        "cc2594fe-add2-a3df-cdb3-a61711badf53",
        "e0ce2972-da00-955c-129e-3289b3676776",
        "3e0d336d-321f-ddfa-5c1b-e26131766f6a",
        "d43b1dc4-6b51-76a7-8b90-38865b82bf06",
        "06d16cbb-1868-fd1d-5c93-eae42164a37d",
        "dd5d98cf-273e-3fd0-f030-48be58ee3a0b",
        "0e47c89e-de4a-6233-a2da-cb852aad1b00",
        "fb9c4a55-0e13-495b-25c4-f0b459dc06de",
        "e3ce8def-312c-735b-0e48-018b6799c883",
        "2f713216-4e71-d123-03ed-9c8554710c6b",
        "4a417d8a-1f4f-404b-9783-6672f8527911",
        "ca5e21ec-5b20-5909-4c31-3f90d7316b33",
        "06a4fcc3-e1c4-296d-8817-01f88fbd7367",
        "130ac084-6f3c-95de-b5b6-d25c80703474",
        "59d540a0-ae9d-3606-5ae0-4f2842b64cfa",
        "8612ae9a-f53c-5bf4-2899-8174d7abc4fd",
        "12467401-e979-2c49-34e0-6ac761542797",
        "d53c3eaa-0404-3860-0675-3e375596c3e3",
        "9f5b26bd-81d3-b25e-62fe-5b671d1e3e79",
        "f57f0b64-a050-d617-ee00-c8e9e3adc9cb",
        "beff166a-f5f3-f05e-e020-98f2b00e27ed",
        "02278a65-94ba-6d5e-0d2b-93f2e4f4bf70",
        "a707197d-449e-5b58-846c-0c850c61f9d6",
        "021d4b1a-9503-a44f-ee2b-976eb5d80e68",
        "0ae2ffae-7265-524d-cb76-c2b691992706",
        "f6e41cf2-1104-bd0b-0190-dffad1bac813",
        "2b4bb15e-956d-56ae-69f5-d26a20de0ce7",
        "f816da2c-51f1-612a-2029-a542db7db882",
        "345fea05-c7be-465c-409f-9dcb3bd2aa07",
        "b3017e02-c063-5185-acd5-1ef5f9d79b89",
        "4dcff365-1971-3c2b-d73c-77e1dc54242a"
        ];
 
///////////// END CONSTANTS ////////////////
 
///////////// GLOBAL VARIABLES ///////////////
// All displayable characters.  Default to ASCII order.
string gCharIndex;
// This is the channel to listen on while acting
// as a cell in a larger display.
integer gCellChannel      = -1;
// This is the starting character position in the cell channel message
// to render.
integer gCellCharPosition = 0;
// This is whether or not to use the fade in/out special effect.
integer gCellUseFading      = FALSE;
// This is how long to display the text before fading out (if using
// fading special effect).
// Note: < 0  means don't fade out.
float   gCellHoldDelay      = 1.0;
/////////// END GLOBAL VARIABLES ////////////
 
ResetCharIndex()
{
    gCharIndex  = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`";
    // \" <-- Fixes LSL syntax highlighting bug.
    gCharIndex += "abcdefghijklmnopqrstuvwxyz{|}~";
    gCharIndex += "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
}
 
vector GetGridPos(integer index1, integer index2)
{
    // There are two ways to use the lookup table...
    integer Col;
    integer Row;
    if (index1 >= index2)
    {
        // In this case, the row is the index of the first character:
        Row = index1;
        // And the col is the index of the second character (x2)
        Col = index2 * 2;
    }
    // Index1 < Index2
    else
    {
        // In this case, the row is the index of the second character:
        Row = index2;
        // And the col is the index of the first character, x2, offset by 1.
        Col = index1 * 2 + 1;
    }
    return <Col, Row, 0>;
}
 
string GetGridTexture(vector grid_pos)
{
    // Calculate the texture in the grid to use.
    integer GridCol = llRound(grid_pos.x) / 20;
    integer GridRow = llRound(grid_pos.y) / 10;
 
    // Lookup the texture.
    key Texture = llList2Key(CHARACTER_GRID, GridRow * (GridRow + 1) / 2 + GridCol);
    return Texture;
}
 
vector GetGridOffset(vector grid_pos)
{
    // Zoom in on the texture showing our character pair.
    integer Col = llRound(grid_pos.x) % 20;
    integer Row = llRound(grid_pos.y) % 10;
 
    // Return the offset in the texture.
    return <-0.45 + 0.05 * Col, 0.45 - 0.1 * Row, 0.0>;
}
 
ShowChars(vector grid_pos1, vector grid_pos2, vector grid_pos3, vector grid_pos4, vector grid_pos5)
{
   // Set the primitive textures directly.
 
 
    llSetLinkPrimitiveParamsFast(LINK_THIS, [
        PRIM_TEXTURE, FACE_1, GetGridTexture(grid_pos1), <0.25, 0.1, 0>, GetGridOffset(grid_pos1) + <0.075, 0, 0>, 0.0,
        PRIM_TEXTURE, FACE_2, GetGridTexture(grid_pos2), <0.1, 0.1, 0>, GetGridOffset(grid_pos2), 0.0,
        PRIM_TEXTURE, FACE_3, GetGridTexture(grid_pos3), <-1.48, 0.1, 0>, GetGridOffset(grid_pos3)+ <0.37, 0, 0>, 0.0,
        PRIM_TEXTURE, FACE_4, GetGridTexture(grid_pos4), <0.1, 0.1, 0>, GetGridOffset(grid_pos4), 0.0,
        PRIM_TEXTURE, FACE_5, GetGridTexture(grid_pos5), <0.25, 0.1, 0>, GetGridOffset(grid_pos5) - <0.075, 0, 0>, 0.0]);
}
 
RenderString(string str)
{
    // Get the grid positions for each pair of characters.
    vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)),
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) );
    vector GridPos2 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)),
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) );
    vector GridPos3 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)),
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 5, 5)) );
    vector GridPos4 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 6, 6)),
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 7, 7)) );
    vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)),
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) );                                   
 
    // Use these grid positions to display the correct textures/offsets.
    ShowChars(GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);
}
 
RenderWithEffects(string str)
{
    // Get the grid positions for each pair of characters.
    vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)),
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) );
    vector GridPos2 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)),
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) );
    vector GridPos3 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)),
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 5, 5)) );
    vector GridPos4 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 6, 6)),
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 7, 7)) );
    vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)),
                                  llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) );                                   
 
      // First set the alpha to the lowest possible.
    llSetAlpha(0.05, ALL_SIDES);
 
    // Use these grid positions to display the correct textures/offsets.
    ShowChars(GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);
 
    float Alpha;
    for (Alpha = 0.10; Alpha <= 1.0; Alpha += 0.05)
    {
       llSetAlpha(Alpha, ALL_SIDES);
    }
    // See if we want to fade out as well.
    if (gCellHoldDelay < 0.0)
    {
       // No, bail out. (Just keep showing the string at full strength).
       return;
    }
    // Hold the text for a while.
    llSleep(gCellHoldDelay);
    // Now fade out.
    for (Alpha = 0.95; Alpha >= 0.05; Alpha -= 0.05)
    {
        llSetAlpha(Alpha, ALL_SIDES);
    }
    // Make the text transparent to fully hide it.
    llSetTexture(TRANSPARENT, ALL_SIDES);
}
 
RenderExtended(string str)
{
    // Look for escape sequences.
    list Parsed       = llParseString2List(str, [], [ESCAPE_SEQUENCE]);
    integer ParsedLen = llGetListLength(Parsed);
 
    // Create a list of index values to work with.
    list Indices;
    // We start with room for 6 indices.
    integer IndicesLeft = 10;
 
    integer i;
    string Token;
    integer Clipped;
    integer LastWasEscapeSequence = FALSE;
    // Work from left to right.
    for (i = 0; i < ParsedLen && IndicesLeft > 0; i++)
    {
        Token = llList2String(Parsed, i);
 
        // If this is an escape sequence, just set the flag and move on.
        if (Token == ESCAPE_SEQUENCE)
        {
            LastWasEscapeSequence = TRUE;
        }
        // Token != ESCAPE_SEQUENCE
        else
        {
            // Otherwise this is a normal token.  Check its length.
            Clipped = FALSE;
            integer TokenLength = llStringLength(Token);
            // Clip if necessary.
            if (TokenLength > IndicesLeft)
            {
                Token = llGetSubString(Token, 0, IndicesLeft - 1);
                TokenLength = llStringLength(Token);
                IndicesLeft = 0;
                Clipped = TRUE;
            }
            else
                IndicesLeft -= TokenLength;
 
            // Was the previous token an escape sequence?
            if (LastWasEscapeSequence)
            {
                // Yes, the first character is an escape character, the rest are normal.
 
                // This is the extended character.
                Indices += [llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95];
 
                // These are the normal characters.
                integer j;
                for (j = 1; j < TokenLength; j++)
                    Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];
            }
            // Normal string.
            else
            {
                // Just add the characters normally.
                integer j;
                for (j = 0; j < TokenLength; j++)
                {
                    Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];
                }
            }
 
            // Unset this flag, since this was not an escape sequence.
            LastWasEscapeSequence = FALSE;
        }
    }
 
    // Use the indices to create grid positions.
    vector GridPos1 = GetGridPos( llList2Integer(Indices, 0), llList2Integer(Indices, 1) );
    vector GridPos2 = GetGridPos( llList2Integer(Indices, 2), llList2Integer(Indices, 3) );
    vector GridPos3 = GetGridPos( llList2Integer(Indices, 4), llList2Integer(Indices, 5) );
    vector GridPos4 = GetGridPos( llList2Integer(Indices, 6), llList2Integer(Indices, 7) );
    vector GridPos5 = GetGridPos( llList2Integer(Indices, 8), llList2Integer(Indices, 9) );     
 
    // Use these grid positions to display the correct textures/offsets.
    ShowChars(GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);
}
 
integer ConvertIndex(integer index)
{
    // This converts from an ASCII based index to our indexing scheme.
    if (index >= 32) // ' ' or higher
        index -= 32;
    // index < 32
    else
    {
        // Quick bounds check.
        if (index > 15)
            index = 15;
 
        index += 94; // extended characters
    }
 
    return index;
}
 
default
{
    state_entry()
    {
        // Initialize the character index.
        ResetCharIndex();
 
        //llSay(0, "Free Memory: " + (string) llGetFreeMemory());
    }
 
    link_message(integer sender, integer channel, string data, key id)
    {
        if (channel == DISPLAY_STRING)
        {
            RenderString(data);
            return;
        }
        if (channel == DISPLAY_EXTENDED)
        {
            RenderExtended(data);
            return;
        }
        if (channel == gCellChannel)
        {
            // Extract the characters we are interested in, and use those to render.
            string TextToRender = llGetSubString(data, gCellCharPosition, gCellCharPosition + 9);
            if (gCellUseFading)
               RenderWithEffects( TextToRender );
            else // !gCellUseFading
                RenderString( TextToRender );
            return;
        }
        if (channel == REMAP_INDICES)
        {
            // Parse the message, splitting it up into index values.
            list Parsed = llCSV2List(data);
            integer i;
            // Go through the list and swap each pair of indices.
            for (i = 0; i < llGetListLength(Parsed); i += 2)
            {
                integer Index1 = ConvertIndex( llList2Integer(Parsed, i) );
                integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) );
 
                // Swap these index values.
                string Value1 = llGetSubString(gCharIndex, Index1, Index1);
                string Value2 = llGetSubString(gCharIndex, Index2, Index2);
 
                gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1);
                gCharIndex = llInsertString(gCharIndex, Index1, Value2);
 
                gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2);
                gCharIndex = llInsertString(gCharIndex, Index2, Value1);
            }
            return;
        }
        if (channel == RESET_INDICES)
        {
            // Restore the character index back to default settings.
            ResetCharIndex();
            return;
        }
        if (channel == SET_CELL_INFO)
        {
            // Change the channel we listen to for cell commands, and the
            // starting character position to extract from.
            list Parsed = llCSV2List(data);
            gCellChannel        = (integer) llList2String(Parsed, 0);
            gCellCharPosition   = (integer) llList2String(Parsed, 1);
            gCellUseFading      = (integer) llList2String(Parsed, 2);
            gCellHoldDelay      = (float)   llList2String(Parsed, 3);             
            return;
        }
        if (channel == SET_THICKNESS)
        {
            // Set our z scale to thickness, while staying fixed
            // in position relative the prim below us.
            vector Scale    = llGetScale();
            float Thickness = (float) data;
            // Reposition only if this isn't the root prim.
            integer ThisLink = llGetLinkNumber();
            if (ThisLink != 0 || ThisLink != 1) {
                // This is not the root prim.
                vector Up = llRot2Up(llGetLocalRot());
                float DistanceToMove = Thickness / 2.0 - Scale.z / 2.0;
                vector Pos = llGetLocalPos();
                llSetPos(Pos + DistanceToMove * Up);
            }
            // Apply the new thickness.
            Scale.z = Thickness;
            llSetScale(Scale);
            return;
        }
        if (channel == SET_COLOR)
        {
           vector newColor = (vector)data;
           llSetColor(newColor, ALL_SIDES);
        }
    }
}

XyText Board Control

This last script is a script that allows an unlimited number of cells to be used together. The script:

////////////////////////////////////////////
// XyText Board Control
//
// Written by Tdub Dowler
// Modified by Awsoonn Rawley
// Refactored by Strife Onizuka
////////////////////////////////////////////
 
 
/////////////// CONSTANTS /////////////////
// XyText Message Map.
integer SET_LINE_CHANNEL    = 100100;
integer DISPLAY_STRING      = 204000;
integer DISPLAY_EXTENDED    = 204001;
integer REMAP_INDICES       = 204002;
integer RESET_INDICES       = 204003;
integer SET_CELL_INFO       = 204004;
string  LOAD_MSG            = "Loading...";
///////////// END CONSTANTS ////////////////
integer prims;
 
SetText(string msg)
{
    llMessageLinked(LINK_SET, SET_LINE_CHANNEL, msg, "");
}
 
XytstOrder()
{ 
    // Fills each cell of the board with it's number.
    string  str = "";
    integer i = 0;
    do
    {
        str += llGetSubString("          " + (string)i,-10,-1);
        llSetText("Generating Pattern: " + (string)i, <0,1,0>, 1.0);
    }while(++i < prims);
 
    llSetText("Displaying Order Test...", <0,1,0>, 1.0);
 
    // Send the message
    llMessageLinked(LINK_SET, SET_LINE_CHANNEL, str, "");
 
    llSetText("", ZERO_VECTOR, 0.0);
}
 
 
default
{
    on_rez(integer start)
    {
        llResetScript();
    }
 
    state_entry()
    {
        // Determin the number of prims.
        prims = llGetNumberOfPrims();
 
        // Clear the screen.
        llMessageLinked(LINK_SET, DISPLAY_STRING, LOAD_MSG, "");
 
        integer StartLink = llGetLinkNumber() + 1;
        // Configure the board.
        integer i = 0;
        do
            llMessageLinked(StartLink + i, SET_CELL_INFO, llList2CSV([SET_LINE_CHANNEL, i * 10]), "");
        while( ++i < prims );
 
        // Build this script in world to reveal the secret message!
        SetText( llBase64ToString("SXMgdGhhdCBub3QgY29vbCBvciB3aGF0PyA6KQ==") );
    }
 
    touch_end(integer num)
    {
        // This can be used to help find mislinked prims. Its not required at all.
        XytstOrder(); 
    }
}


Note: For new scripters/builders: Text for this script is displayed in the reverse order by which objects were linked. Breaks in the lines for multiline scripts are possible using the '\n' for newline, but a multiline linked object does not detect this. Theoretically, adding a message which communicates relative axis information (traditionally, z axis) could be used to allow for line breaks.

Example Use

// XyText Message Map.
integer SET_LINE_CHANNEL    = 100100; //for multi-cell spanning text
integer DISPLAY_STRING      = 204000;
integer DISPLAY_EXTENDED    = 204001;
integer REMAP_INDICES       = 204002;
integer RESET_INDICES       = 204003;
integer SET_CELL_INFO       = 204004;


llMessageLinked(LINK_SET, DISPLAY_STRING, "text to display", "");


Many thanks to Xylor Baysklef and Kermitt Quick.