corrade-lsl-templates – Blame information for rev 5

Subversion Repositories:
Rev:
Rev Author Line No. Line
4 office 1 ////////////////////////////////////////////
2 // XyzzyText v2.1(10-Char) by Thraxis Epsilon
3 // XyzzyText v2.1 Script (Set Line Color) by Huney Jewell
4 // XyzzyText v2.0 Script (5 Face, Single Texture)
5 //
6 // Edited trivially by Joel Cloquet on 1/2011 to use the (relatively)
7 // new llSetLinkPrimitiveParamsFast function, thereby removing the need in
8 // some cases to use the slave script.
9 //
10 // Heavily Modified by Thraxis Epsilon, Gigs Taggart 5/2007 and Strife Onizuka 8/2007
11 // Rewrite to allow one-script-per-object operation w/ optional slaves
12 // Enable prim-label functionality
13 // Enabled Banking
14 // Enabled 10-char per prim
15 //
16 // Modified by Kermitt Quirk 19/01/2006
17 // To add support for 5 face prim instead of 3
18 //
19 // Core XyText Originally Written by Xylor Baysklef
20 //
21 //
22 ////////////////////////////////////////////
23  
24 /////////////// CONSTANTS ///////////////////
25 // XyText Message Map.
26 integer DISPLAY_STRING = 204000;
27 integer DISPLAY_EXTENDED = 204001;
28 integer REMAP_INDICES = 204002;
29 integer RESET_INDICES = 204003;
30 integer SET_FADE_OPTIONS = 204004;
31 integer SET_FONT_TEXTURE = 204005;
32 integer SET_LINE_COLOR = 204006;
33 integer SET_COLOR = 204007;
34 integer RESCAN_LINKSET = 204008;
35  
36 //internal API
37 integer REGISTER_SLAVE = 205000;
38 integer SLAVE_RECOGNIZED = 205001;
39 integer SLAVE_DISPLAY = 205003;
40 integer SLAVE_DISPLAY_EXTENDED = 205004;
41 integer SLAVE_RESET = 205005;
42  
43 // This is an extended character escape sequence.
44 string ESCAPE_SEQUENCE = "\\e";
45  
46 // This is used to get an index for the extended character.
47 string EXTENDED_INDEX = "123456789abcdef";
48  
49  
50 // Face numbers.
51 integer FACE_1 = 3;
52 integer FACE_2 = 7;
53 integer FACE_3 = 4;
54 integer FACE_4 = 6;
55 integer FACE_5 = 1;
56  
57 // Used to hide the text after a fade-out.
58 key TRANSPARENT = "701917a8-d614-471f-13dd-5f4644e36e3c";
59 key null_key = NULL_KEY;
60  
61 // This is a list of textures for all 2-character combinations.
62 list CHARACTER_GRID = [
63 "00e9f9f7-0669-181c-c192-7f8e67678c8d",
64 "347a5cb6-0031-7ec0-2fcf-f298eebf3c0e",
65 "4e7e689e-37f1-9eca-8596-a958bbd23963",
66 "19ea9c21-67ba-8f6f-99db-573b1b877eb1",
67 "dde7b412-cda1-652f-6fc2-73f4641f96e1",
68 "af6fa3bb-3a6c-9c4f-4bf5-d1c126c830da",
69 "a201d3a2-364b-43b6-8686-5881c0f82a94",
70 "b674dec8-fead-99e5-c28d-2db8e4c51540",
71 "366e05f3-be6b-e5cf-c33b-731dff649caa",
72 "75c4925c-0427-dc0c-c71c-e28674ff4d27",
73 "dcbe166b-6a97-efb2-fc8e-e5bc6a8b1be6",
74 "0dca2feb-fc66-a762-db85-89026a4ecd68",
75 "a0fca76f-503a-946b-9336-0a918e886f7a",
76 "67fb375d-89a1-5a4f-8c7a-0cd1c066ffc4",
77 "300470b2-da34-5470-074c-1b8464ca050c",
78 "d1f8e91c-ce2b-d85e-2120-930d3b630946",
79 "2a190e44-7b29-dadb-0bff-c31adaf5a170",
80 "75d55e71-f6f8-9835-e746-a45f189f30a1",
81 "300fac33-2b30-3da3-26bc-e2d70428ec19",
82 "0747c776-011a-53ce-13ee-8b5bb9e87c1e",
83 "85a855c3-a94f-01ca-33e0-7dde92e727e2",
84 "cbc1dab2-2d61-2986-1949-7a5235c954e1",
85 "f7aef047-f266-9596-16df-641010edd8e1",
86 "4c34ebf7-e5e1-2e1a-579f-e224d9d5e71b",
87 "4a69e98c-26a5-ad05-e92e-b5b906ad9ef9",
88 "462a9226-2a97-91ac-2d89-57ab33334b78",
89 "20b24b3a-8c57-82ee-c6ed-555003f5dbcd",
90 "9b481daa-9ea8-a9fa-1ee4-ab9a0d38e217",
91 "c231dbdc-c842-15b0-7aa6-6da14745cfdc",
92 "c97e3cbb-c9a3-45df-a0ae-955c1f4bf9cf",
93 "f1e7d030-ff80-a242-cb69-f6951d4eae3b",
94 "ed32d6c4-d733-c0f1-f242-6df1d222220d",
95 "88f96a30-dccf-9b20-31ef-da0dfeb23c72",
96 "252f2595-58b8-4bcc-6515-fa274d0cfb65",
97 "f2838c4f-de80-cced-dff8-195dfdf36b2c",
98 "cc2594fe-add2-a3df-cdb3-a61711badf53",
99 "e0ce2972-da00-955c-129e-3289b3676776",
100 "3e0d336d-321f-ddfa-5c1b-e26131766f6a",
101 "d43b1dc4-6b51-76a7-8b90-38865b82bf06",
102 "06d16cbb-1868-fd1d-5c93-eae42164a37d",
103 "dd5d98cf-273e-3fd0-f030-48be58ee3a0b",
104 "0e47c89e-de4a-6233-a2da-cb852aad1b00",
105 "fb9c4a55-0e13-495b-25c4-f0b459dc06de",
106 "e3ce8def-312c-735b-0e48-018b6799c883",
107 "2f713216-4e71-d123-03ed-9c8554710c6b",
108 "4a417d8a-1f4f-404b-9783-6672f8527911",
109 "ca5e21ec-5b20-5909-4c31-3f90d7316b33",
110 "06a4fcc3-e1c4-296d-8817-01f88fbd7367",
111 "130ac084-6f3c-95de-b5b6-d25c80703474",
112 "59d540a0-ae9d-3606-5ae0-4f2842b64cfa",
113 "8612ae9a-f53c-5bf4-2899-8174d7abc4fd",
114 "12467401-e979-2c49-34e0-6ac761542797",
115 "d53c3eaa-0404-3860-0675-3e375596c3e3",
116 "9f5b26bd-81d3-b25e-62fe-5b671d1e3e79",
117 "f57f0b64-a050-d617-ee00-c8e9e3adc9cb",
118 "beff166a-f5f3-f05e-e020-98f2b00e27ed",
119 "02278a65-94ba-6d5e-0d2b-93f2e4f4bf70",
120 "a707197d-449e-5b58-846c-0c850c61f9d6",
121 "021d4b1a-9503-a44f-ee2b-976eb5d80e68",
122 "0ae2ffae-7265-524d-cb76-c2b691992706"];
123 list CHARACTER_GRID2 = [
124 "f6e41cf2-1104-bd0b-0190-dffad1bac813",
125 "2b4bb15e-956d-56ae-69f5-d26a20de0ce7",
126 "f816da2c-51f1-612a-2029-a542db7db882",
127 "345fea05-c7be-465c-409f-9dcb3bd2aa07",
128 "b3017e02-c063-5185-acd5-1ef5f9d79b89",
129 "4dcff365-1971-3c2b-d73c-77e1dc54242a"
130 ];
131  
132 ///////////// END CONSTANTS ////////////////
133  
134 ///////////// GLOBAL VARIABLES ///////////////
135 // All displayable characters. Default to ASCII order.
136 string gCharIndex;
137 // This is the channel to listen on while acting
138 // as a cell in a larger display.
139 integer gCellChannel = -1;
140 // This is the starting character position in the cell channel message
141 // to render.
142 integer gCellCharPosition = 0;
143 // This is whether or not to use the fade in/out special effect.
144 integer gCellUseFading = FALSE;
145 // This is how long to display the text before fading out (if using
146 // fading special effect).
147 // Note: < 0 means don't fade out.
148 float gCellHoldDelay = 1.0;
149  
150 integer gSlaveRegistered;
151 list gSlaveNames;
152  
153 integer BANK_STRIDE=3; //offset, length, highest_dirty
154 list gBankingData;
155  
156 /////////// END GLOBAL VARIABLES ////////////
157  
158 ResetCharIndex() {
159 gCharIndex = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`";
160 // \" <-- Fixes LSL syntax highlighting bug.
161 gCharIndex += "abcdefghijklmnopqrstuvwxyz{|}~";
162 gCharIndex += "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
163 }
164  
165 vector GetGridPos(integer index1, integer index2) {
166 // There are two ways to use the lookup table...
167 integer Col;
168 integer Row;
169 if (index1 >= index2) {
170 // In this case, the row is the index of the first character:
171 Row = index1;
172 // And the col is the index of the second character (x2)
173 Col = index2 * 2;
174 }
175 else { // Index1 < Index2
176 // In this case, the row is the index of the second character:
177 Row = index2;
178 // And the col is the index of the first character, x2, offset by 1.
179 Col = index1 * 2 + 1;
180 }
181 return <Col, Row, 0>;
182 }
183  
184 string GetGridTexture(vector grid_pos) {
185 // Calculate the texture in the grid to use.
186 integer GridCol = llRound(grid_pos.x) / 20;
187 integer GridRow = llRound(grid_pos.y) / 10;
188  
189 // Lookup the texture.
190 key Texture = llList2Key(CHARACTER_GRID, GridRow * (GridRow + 1) / 2 + GridCol);
191 return Texture;
192 }
193  
194 vector GetGridOffset(vector grid_pos) {
195 // Zoom in on the texture showing our character pair.
196 integer Col = llRound(grid_pos.x) % 20;
197 integer Row = llRound(grid_pos.y) % 10;
198  
199 // Return the offset in the texture.
200 return <-0.45 + 0.05 * Col, 0.45 - 0.1 * Row, 0.0>;
201 }
202  
203 ShowChars(integer link,vector grid_pos1, vector grid_pos2, vector grid_pos3, vector grid_pos4, vector grid_pos5) {
204 // Set the primitive textures directly.
205  
206  
207 llSetLinkPrimitiveParamsFast( link , [
208 PRIM_TEXTURE, FACE_1, GetGridTexture(grid_pos1), <0.25, 0.1, 0>, GetGridOffset(grid_pos1) + <0.075, 0, 0>, 0.0,
209 PRIM_TEXTURE, FACE_2, GetGridTexture(grid_pos2), <0.1, 0.1, 0>, GetGridOffset(grid_pos2), 0.0,
210 PRIM_TEXTURE, FACE_3, GetGridTexture(grid_pos3), <-1.48, 0.1, 0>, GetGridOffset(grid_pos3)+ <0.37, 0, 0>, 0.0,
211 PRIM_TEXTURE, FACE_4, GetGridTexture(grid_pos4), <0.1, 0.1, 0>, GetGridOffset(grid_pos4), 0.0,
212 PRIM_TEXTURE, FACE_5, GetGridTexture(grid_pos5), <0.25, 0.1, 0>, GetGridOffset(grid_pos5) - <0.075, 0, 0>, 0.0
213 ]);
214 }
215  
216 RenderString(integer link, string str) {
217 // Get the grid positions for each pair of characters.
218 vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)),
219 llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) );
220 vector GridPos2 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)),
221 llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) );
222 vector GridPos3 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)),
223 llSubStringIndex(gCharIndex, llGetSubString(str, 5, 5)) );
224 vector GridPos4 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 6, 6)),
225 llSubStringIndex(gCharIndex, llGetSubString(str, 7, 7)) );
226 vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)),
227 llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) );
228  
229 // Use these grid positions to display the correct textures/offsets.
230 ShowChars(link,GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);
231 }
232  
233 //RenderWithEffects(integer link, string str) {
234 // // Get the grid positions for each pair of characters.
235 // vector GridPos1 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 0, 0)),
236 // llSubStringIndex(gCharIndex, llGetSubString(str, 1, 1)) );
237 // vector GridPos2 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 2, 2)),
238 // llSubStringIndex(gCharIndex, llGetSubString(str, 3, 3)) );
239 // vector GridPos3 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 4, 4)),
240 // llSubStringIndex(gCharIndex, llGetSubString(str, 5, 5)) );
241 // vector GridPos4 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 6, 6)),
242 // llSubStringIndex(gCharIndex, llGetSubString(str, 7, 7)) );
243 // vector GridPos5 = GetGridPos( llSubStringIndex(gCharIndex, llGetSubString(str, 8, 8)),
244 // llSubStringIndex(gCharIndex, llGetSubString(str, 9, 9)) ); //
245 //
246 // // First set the alpha to the lowest possible.
247 // llSetAlpha(0.05, ALL_SIDES);
248 //
249 // // Use these grid positions to display the correct textures/offsets.
250 // ShowChars(link,GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);
251 //
252 // float Alpha = 0.10;
253 // for (; Alpha <= 1.0; Alpha += 0.05)
254 // llSetAlpha(Alpha, ALL_SIDES);
255 // // See if we want to fade out as well.
256 // if (gCellHoldDelay < 0.0)
257 // // No, bail out. (Just keep showing the string at full strength).
258 // return;
259 // // Hold the text for a while.
260 // llSleep(gCellHoldDelay);
261 // // Now fade out.
262 // for (Alpha = 0.95; Alpha >= 0.05; Alpha -= 0.05)
263 // llSetAlpha(Alpha, ALL_SIDES);
264 // // Make the text transparent to fully hide it.
265 // llSetTexture(TRANSPARENT, ALL_SIDES);
266 //}
267  
268 integer RenderExtended(integer link, string str,integer render) {
269 // Look for escape sequences.
270 integer length = 0;
271 list Parsed = llParseString2List(str, [], (list)ESCAPE_SEQUENCE);
272 integer ParsedLen = llGetListLength(Parsed);
273  
274 // Create a list of index values to work with.
275 list Indices;
276 // We start with room for 6 indices.
277 integer IndicesLeft = 10;
278  
279 string Token;
280 integer Clipped;
281 integer LastWasEscapeSequence = FALSE;
282 // Work from left to right.
283 integer i=0;
284 for (; i < ParsedLen && IndicesLeft > 0; ++i) {
285 Token = llList2String(Parsed, i);
286  
287 // If this is an escape sequence, just set the flag and move on.
288 if (Token == ESCAPE_SEQUENCE) {
289 LastWasEscapeSequence = TRUE;
290 }
291 else { // Token != ESCAPE_SEQUENCE
292 // Otherwise this is a normal token. Check its length.
293 Clipped = FALSE;
294 integer TokenLength = llStringLength(Token);
295 // Clip if necessary.
296 if (TokenLength > IndicesLeft) {
297 TokenLength = llStringLength(Token = llGetSubString(Token, 0, IndicesLeft - 1));
298 IndicesLeft = 0;
299 Clipped = TRUE;
300 }
301 else
302 IndicesLeft -= TokenLength;
303  
304 // Was the previous token an escape sequence?
305 if (LastWasEscapeSequence) {
306 // Yes, the first character is an escape character, the rest are normal.
307 length += 2 + TokenLength;
308 if (render)
309 {
310 // This is the extended character.
311 Indices += [llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95];
312  
313 // These are the normal characters.
314 integer j=1;
315 for (; j < TokenLength; ++j)
316 {
317 Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];
318 }
319 }
320 }
321 else { // Normal string.
322 // Just add the characters normally.
323 length += TokenLength;
324 if(render)
325 {
326 integer j=0;
327 for (; j < TokenLength; ++j)
328 {
329 Indices += [llSubStringIndex(gCharIndex, llGetSubString(Token, j, j))];
330 }
331 }
332 }
333  
334 // Unset this flag, since this was not an escape sequence.
335 LastWasEscapeSequence = FALSE;
336 }
337 }
338  
339 if(render)
340 {
341 // Use the indices to create grid positions.
342 vector GridPos1 = GetGridPos( llList2Integer(Indices, 0), llList2Integer(Indices, 1) );
343 vector GridPos2 = GetGridPos( llList2Integer(Indices, 2), llList2Integer(Indices, 3) );
344 vector GridPos3 = GetGridPos( llList2Integer(Indices, 4), llList2Integer(Indices, 5) );
345 vector GridPos4 = GetGridPos( llList2Integer(Indices, 6), llList2Integer(Indices, 7) );
346 vector GridPos5 = GetGridPos( llList2Integer(Indices, 8), llList2Integer(Indices, 9) );
347  
348 // Use these grid positions to display the correct textures/offsets.
349 ShowChars(link,GridPos1, GridPos2, GridPos3, GridPos4, GridPos5);
350 }
351 return length;
352 }
353  
354  
355 integer ConvertIndex(integer index) {
356 // This converts from an ASCII based index to our indexing scheme.
357 if (index >= 32) // ' ' or higher
358 index -= 32;
359 else { // index < 32
360 // Quick bounds check.
361 if (index > 15)
362 index = 15;
363  
364 index += 94; // extended characters
365 }
366  
367 return index;
368 }
369  
370  
371 PassToRender(integer render,string message, integer bank)
372 {
373 float time;
374 integer extendedlen = 0;
375 integer link;
376  
377 integer i = 0;
378 integer msgLen = llStringLength(message);
379 string TextToRender;
380 integer num_slaves=llGetListLength(gSlaveNames);
381 string slave_name; //avoids unnecessary casts, keeping it as a string
382  
383  
384 //get the bank offset and length
385 integer bank_offset=llList2Integer(gBankingData, (bank * BANK_STRIDE));
386 integer bank_length=llList2Integer(gBankingData, (bank * BANK_STRIDE) + 1);
387 integer bank_highest_dirty=llList2Integer(gBankingData, (bank * BANK_STRIDE) + 2);
388  
389 integer x=0;
390 for (;x < msgLen;x = x + 10)
391 {
392  
393 if (i >= bank_length) //we don't want to run off the end of the bank
394 {
395 //set the dirty to max, and bail out, we're done
396 gBankingData=llListReplaceList(gBankingData, [bank_length], (bank * BANK_STRIDE) + 2, (bank * BANK_STRIDE) + 2);
397 return;
398 }
399  
400 link = unpack(gXyTextPrims,(i + bank_offset));
401 TextToRender = llGetSubString(message, x, x + 20);
402  
403 if(gSlaveRegistered && (link % (num_slaves +1)))
404 {
405 slave_name=llList2String(gSlaveNames, (link % (num_slaves + 1)) - 1);
406 if (render == 1)
407 llMessageLinked(LINK_THIS, SLAVE_DISPLAY, TextToRender, (key)((string)link + "," + slave_name));
408 if (render == 2)
409 {
410 if(llSubStringIndex(TextToRender,"\e")>x+10)
411 {
412 extendedlen = 10;
413 }
414 else
415 {
416 extendedlen = RenderExtended(link,TextToRender,0);
417 }
418  
419 if(extendedlen>10)
420 {
421 x += extendedlen-10;
422 }
423  
424 llMessageLinked(LINK_THIS,SLAVE_DISPLAY_EXTENDED,TextToRender,(key)((string)link+","+slave_name));
425 }
426 }
427 else
428 {
429 if (render == 1)
430 RenderString(link,TextToRender);
431 if (render == 2)
432 {
433 extendedlen = RenderExtended(link,TextToRender,1);
434 if(extendedlen>10)
435 {
436 x += extendedlen-10;
437 }
438 }
439  
440 // if (render == 3)
441 // RenderWithEffects(link,TextToRender);
442 }
443 ++i;
444 }
445  
446 if (bank_highest_dirty==0)
447 bank_highest_dirty=bank_length;
448  
449 integer current_highest_dirty=i;
450 while (i < bank_highest_dirty)
451 {
452 link = unpack(gXyTextPrims,(i + bank_offset));
453  
454 if(gSlaveRegistered && (link % (num_slaves+1) != 0))
455 {
456 slave_name=llList2String(gSlaveNames, (link % (num_slaves + 1)) - 1);
457 llMessageLinked(LINK_THIS, SLAVE_DISPLAY, " ", (key)((string)link + "," + slave_name));
458 //sorry, no fade effect with slave
459 }
460 else
461 {
462 RenderString(link," ");
463 }
464 ++i;
465 }
466 gBankingData=llListReplaceList(gBankingData, [current_highest_dirty], (bank * BANK_STRIDE) + 2, (bank * BANK_STRIDE) + 2);
467 }
468  
469 // Bitwise Voodoo by Gigs Taggart and optimized by Strife Onizuka
470 list gXyTextPrims;
471  
472  
473 integer get_number_of_prims()
474 {//ignores avatars.
475 integer a = llGetNumberOfPrims();
476 while(llGetAgentSize(llGetLinkKey(a)))
477 --a;
478 return a;
479 }
480  
481 //functions to pack 8-bit shorts into ints
482 list pack_and_insert(list in_list, integer pos, integer value)
483 {
484 // //figure out the bitpack position
485 // integer pack = pos & 3; //4 bytes per int
486 // pos=pos >> 2;
487 // integer shifted = value << (pack << 3);
488 // integer old_value = llList2Integer(in_list, pos);
489 // shifted = old_value | shifted;
490 // in_list = llListReplaceList(in_list, (list)shifted, pos, pos);
491 // return in_list;
492 //Safe optimized version
493 integer index = pos >> 2;
494 return llListReplaceList(in_list, (list)(llList2Integer(in_list, index) | (value << ((pos & 3) << 3))), index, index);
495 }
496  
497 integer unpack(list in_list, integer pos)
498 {
499 return (llList2Integer(in_list, pos >> 2) >> ((pos & 3) << 3)) & 0x000000FF;//unsigned
500 // return (llList2Integer(in_list, pos >> 2) << (((~pos) & 3) << 3)) >> 24;//signed
501 }
502  
503  
504 change_color(vector color)
505 {
506 integer num_prims=llGetListLength(gXyTextPrims) << 2;
507  
508 integer i = 0;
509  
510 for (; i<=num_prims; ++i)
511 {
512 integer link = unpack(gXyTextPrims,i);
513 if (!link)
514 return;
515  
516 llSetLinkPrimitiveParamsFast( link,[
517 PRIM_COLOR, FACE_1, color, 1.0,
518 PRIM_COLOR, FACE_2, color, 1.0,
519 PRIM_COLOR, FACE_3, color, 1.0,
520 PRIM_COLOR, FACE_4, color, 1.0,
521 PRIM_COLOR, FACE_5, color, 1.0
522 ]);
523 }
524 }
525  
526 change_line_color(integer bank, vector color)
527 {
528  
529 //get the bank offset and length
530 integer i = llList2Integer(gBankingData, (bank * BANK_STRIDE));
531 integer bank_end = i + llList2Integer(gBankingData, (bank * BANK_STRIDE) + 1);
532  
533 for (; i < bank_end; ++i)
534 {
535 integer link = unpack(gXyTextPrims,i);
536 if (!link)
537 return;
538  
539 llSetLinkPrimitiveParamsFast( link,[
540 PRIM_COLOR, FACE_1, color, 1.0,
541 PRIM_COLOR, FACE_2, color, 1.0,
542 PRIM_COLOR, FACE_3, color, 1.0,
543 PRIM_COLOR, FACE_4, color, 1.0,
544 PRIM_COLOR, FACE_5, color, 1.0
545 ]);
546 }
547 }
548  
549 init()
550 {
551 integer num_prims=get_number_of_prims();
552  
553 string link_name;
554 integer bank=0;
555 integer bank_empty=FALSE;
556 integer prims_pointer=0; //"pointer" to the next entry to be used in the gXyTextPrims list.
557  
558 list temp_bank=[];
559 integer temp_bank_stride=2;
560  
561 // moving this before the prim scan so that the slaves properly configure themseves before
562 // any requests to display
563 llMessageLinked(LINK_THIS, SLAVE_RESET, "" , null_key);
564  
565 gXyTextPrims=[];
566 integer x=0;
567 for (;x<64;++x)
568 {
569 gXyTextPrims= (gXyTextPrims = []) + gXyTextPrims + [0]; //we need to pad out the list to make it easier to add things in any order later
570 }
571  
572 gBankingData = [];
573 @loop;
574 {
575 //loop over all prims, looking for ones in the current bank
576 for(x=0;x<=num_prims;++x)
577 {
578 link_name=llGetLinkName(x);
579 list tmp = llParseString2List(link_name, ["-"], []);
580 if(llList2String(tmp,0)== "xyzzytext")
581 {
582 integer prims_bank=llList2Integer(tmp,1);
583 if (llList2Integer(tmp,1)==bank)
584 {
585 temp_bank+=llList2Integer(tmp,2) + (list)x;
586 }
587 }
588  
589 }
590  
591  
592 if (temp_bank!=[])
593 {
594 //sort the current bank
595 temp_bank=llListSort(temp_bank, temp_bank_stride, TRUE);
596  
597 integer temp_len=llGetListLength(temp_bank);
598  
599 //store metadata
600 gBankingData+=[prims_pointer,temp_len/temp_bank_stride,0];
601  
602 //repack the bank into the prim list
603 for (x=0; x < temp_len; x+=temp_bank_stride)
604 {
605 gXyTextPrims = pack_and_insert(gXyTextPrims, prims_pointer, llList2Integer(temp_bank, x+1));
606 ++prims_pointer;
607 }
608 ++bank;
609 temp_bank=[];
610 jump loop;
611 }
612 }
613 }
614  
615 default {
616 state_entry() {
617 // Initialize the character index.
618 ResetCharIndex();
619 init();
620 }
621  
622 on_rez(integer num)
623 {
624 llResetScript();
625 }
626  
627 link_message(integer sender, integer channel, string data, key id) {
628 if(id == null_key)
629 id="0";
630  
631 if (channel == DISPLAY_STRING) {
632 PassToRender(1,data, (integer)((string)id));
633 return;
634 }
635 else if (channel == DISPLAY_EXTENDED) {
636 PassToRender(2,data, (integer)((string)id));
637 return;
638 }
639 else if (channel == REMAP_INDICES) {
640 // Parse the message, splitting it up into index values.
641 list Parsed = llCSV2List(data);
642 integer i;
643 // Go through the list and swap each pair of indices.
644 for (i = 0; i < llGetListLength(Parsed); i += 2) {
645 integer Index1 = ConvertIndex( llList2Integer(Parsed, i) );
646 integer Index2 = ConvertIndex( llList2Integer(Parsed, i + 1) );
647  
648 // Swap these index values.
649 string Value1 = llGetSubString(gCharIndex, Index1, Index1);
650 string Value2 = llGetSubString(gCharIndex, Index2, Index2);
651  
652 gCharIndex = llDeleteSubString(gCharIndex, Index1, Index1);
653 gCharIndex = llInsertString(gCharIndex, Index1, Value2);
654  
655 gCharIndex = llDeleteSubString(gCharIndex, Index2, Index2);
656 gCharIndex = llInsertString(gCharIndex, Index2, Value1);
657 }
658 return;
659 }
660 else if (channel == RESET_INDICES) {
661 // Restore the character index back to default settings.
662 ResetCharIndex();
663 return;
664 }
665 else if (channel == RESCAN_LINKSET)
666 {
667 init();
668 }
669 else if (channel == SET_COLOR) {
670 change_color((vector)data);
671 }
672 else if (channel == SET_LINE_COLOR) {
673 change_line_color((integer)((string)id), (vector)data);
674 }
675 else if (channel == REGISTER_SLAVE)
676 {
677 if(!~llListFindList(gSlaveNames, (list)data))
678 {//isn't registered yet
679 gSlaveNames += data;
680 gSlaveRegistered=TRUE;
681 //llOwnerSay((string)llGetListLength(gSlaveNames) + " Slave(s) Recognized: " + data);
682 }
683 // else
684 // {//it already exists
685 // llOwnerSay((string)llGetListLength(gSlaveNames) + " Slave, Existing Slave Recognized: " + data);
686 // }
687 llMessageLinked(LINK_THIS, SLAVE_RECOGNIZED, data , null_key);
688 }
689 }
690  
691 changed(integer change)
692 {
693 if(change&CHANGED_INVENTORY)
694 {
695 if(gSlaveRegistered)
696 {
697 //by using negative indexes they don't need to be adjusted when an entry is deleted.
698 integer x = ~llGetListLength(gSlaveNames);
699 while(++x)
700 {
701 if (!~llGetInventoryType(llList2String(gSlaveNames, x)))
702 {
703 //llOwnerSay("Slave Removed: " + llList2String(gSlaveNames, x));
704 gSlaveNames = llDeleteSubList(gSlaveNames, x, x);
705 }
706 }
707 gSlaveRegistered = !(gSlaveNames == []);
708 }
709 }
710 }
711 }