corrade-lsl-templates – Blame information for rev
?pathlinks?
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 | } |