2008年11月15日
メッセージボードの不思議 - 逐次解説(その4)
integer RenderExtended(integer link, string str, integer render) {-----
// Look for escape sequences.
integer length = 0;
list Parsed = llParseString2List(str, [], (list)ESCAPE_SEQUENCE);
-----
ESCAPE_SEQUENCE で 文字列 str を切り分ける
-----
integer ParsedLen = llGetListLength(Parsed);
// Create a list of index values to work with.
list Indices;
// We start with room for 5 indices.
integer IndicesLeft = 5;
string Token;
integer Clipped;
integer LastWasEscapeSequence = FALSE;
// Work from left to right.
integer i = 0;
for (; (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;
} else { // Token != ESCAPE_SEQUENCE
// Otherwise this is a normal token. Check its length.
Clipped = FALSE;
integer TokenLength = llStringLength(Token);
// Clip if necessary.
if (TokenLength > IndicesLeft) {
TokenLength = llStringLength(Token = llGetSubString(Token, 0, IndicesLeft - 1));
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.
length += 2 + TokenLength;
if (render) {
// This is the extended character.
Indices += (llSubStringIndex(EXTENDED_INDEX, llGetSubString(Token, 0, 0)) + 95);
// These are the normal characters.
integer j = 1;
for (; j < TokenLength; ++j) {
Indices += llSubStringIndex(gCharIndex, llGetSubString(Token, j, j));
}
}
} else { // Normal string.
// Just add the characters normally.
length += TokenLength;
if (render) {
integer j = 0;
for (; j < TokenLength; ++j) {
Indices += llSubStringIndex(gCharIndex, llGetSubString(Token, j, j));
}
}
}
// Unset this flag, since this was not an escape sequence.
LastWasEscapeSequence = FALSE;
}
}
-----
あれ? 何してるんだろ...
-----
エスケープ文字があった場合 EXTENDED_INDEX でマッチさせ 95 足した値を用いるということ?
-----
// Use the indices to create grid positions.
if (render) {
vector GridOffset1 = GetGridOffset(llList2Integer(Indices, 0));
vector GridOffset2 = GetGridOffset(llList2Integer(Indices, 1));
vector GridOffset3 = GetGridOffset(llList2Integer(Indices, 2));
vector GridOffset4 = GetGridOffset(llList2Integer(Indices, 3));
vector GridOffset5 = GetGridOffset(llList2Integer(Indices, 4));
// Use these grid positions to display the correct textures/offsets.
ShowChars(link, GridOffset1, GridOffset2, GridOffset3, GridOffset4, GridOffset5);
}
-----
ここは RenderString と同じ
-----
return length;
}
integer ConvertIndex(integer index) {
// This converts from an ASCII based index to our indexing scheme.
if (index >= 32) { // ' ' or higher
index -= 32;
} else { // index < 32
// Quick bounds check.
if (index > 15) {
index = 15;
}
index += 94; // extended characters
}
return index;
}
-----
REMAP_INDICES で呼ばれた場合に行うことに関係しているらしいが... ここも不明 w
-----
PassToRender(integer render, string message, integer bank) {
-----
DISPLAY_STRING で呼ばれるとここに来る
-----
// float time;
integer extendedlen = 0;
integer link;
integer i = 0;
integer msgLen = llStringLength(message);
string TextToRender;
integer num_slaves = llGetListLength(gSlaveNames);
string slave_name; // avoids unnecessary casts, keeping it as a string
// get the bank offset and length
integer bank_offset = llList2Integer(gBankingData, (bank * BANK_STRIDE));
integer bank_length = llList2Integer(gBankingData, (bank * BANK_STRIDE) + 1);
integer bank_highest_dirty = llList2Integer(gBankingData, (bank * BANK_STRIDE) + 2);
-----
bank というのは DISPLAY_STRING で読んだ時の 行? 情報?
-----
その情報をここで取り出している
-----
integer x = 0;
for (; x < msgLen; x = x + 5) {
if (i >= bank_length) { // we don't want to run off the end of the bank
// set the dirty to max, and bail out, we're done
gBankingData = llListReplaceList(gBankingData, (list)bank_length,
(bank * BANK_STRIDE) + 2, (bank * BANK_STRIDE) + 2);
return ;
}
link = unpack(gXyTextPrims, (i + bank_offset));
-----
表示する先のプリムのリンク番号はここで求めている
-----
i は この for 文の中で 1づつ増やされている
-----
TextToRender = llGetSubString(message, x, x + 15);
if (gSlaveRegistered && (link % (num_slaves + 1))) {
-----
スレーブスクリプトを用いる場合 ここを実行するようだ
-----
slave_name = llList2String(gSlaveNames, (link % (num_slaves + 1)) - 1);
if (render == 1) {
llMessageLinked(LINK_THIS, SLAVE_DISPLAY, TextToRender,
(key)((string)link + "," + slave_name));
}
if (render == 2) {
// time = llGetAndResetTime();
if (llSubStringIndex(TextToRender, "\e") > x) {
extendedlen = 5;
} else {
extendedlen = RenderExtended(link, TextToRender, 0);
}
if (extendedlen > 5) {
x += extendedlen - 5;
}
}
llMessageLinked(LINK_THIS, SLAVE_DISPLAY_EXTENDED, TextToRender,
(key)((string)link + "," + slave_name));
// llOwnerSay((string)llGetAndResetTime());
// sorry, no fade effect with slave
} else {
-----
用いない場合はこちら
-----
DISPLAY_STRING で呼ばれた時は render は 1 なので
-----
if (render == 1) {
RenderString(link, TextToRender);
}
-----
ここを実行するだけ
-----
if (render == 2) {
extendedlen = RenderExtended(link, TextToRender,1);
if (extendedlen > 5) {
x += extendedlen - 5;
}
}
if (render == 3) {
RenderWithEffects(link, TextToRender);
}
}
i++;
}
if (bank_highest_dirty == 0) {
bank_highest_dirty = bank_length;
}
integer current_highest_dirty = i;
while (i < bank_highest_dirty) {
link = unpack(gXyTextPrims, (i + bank_offset));
if (gSlaveRegistered && (link % (num_slaves + 1) != 0)) {
slave_name = llList2String(gSlaveNames, (link % (num_slaves + 1)) - 1);
llMessageLinked(LINK_THIS, SLAVE_DISPLAY, " ",
(key)((string)link + "," + slave_name));
// sorry, no fade effect with slave
} else {
RenderString(link," ");
}
i++;
}
gBankingData = llListReplaceList(gBankingData, (list)current_highest_dirty,
(bank * BANK_STRIDE) + 2, (bank * BANK_STRIDE) + 2);
-----
ここも何をしてるんだろう w
-----
}
// Bitwise Voodoo by Gigs Taggart and optimized by Strife Onizuka
list gXyTextPrims;
integer get_number_of_prims() {
integer a = llGetNumberOfPrims();
// Mono tweak
vector size = llGetAgentSize(llGetLinkKey(a));
while (size.z > 0) {
a--;
size = llGetAgentSize(llGetLinkKey(a));
}
return a;
}
-----
リンクされているプリム数を求めているが
-----
sit しているアバターの数を除く処理をしている
-----
// functions to pack 8-bit shorts into ints
list pack_and_insert(list in_list, integer pos, integer value) {
//
// //figure out the bitpack position
// integer pack = pos & 3; //4 bytes per int
// pos=pos >> 2;
// integer shifted = value << (pack << 3);
// integer old_value = llList2Integer(in_list, pos);
// shifted = old_value | shifted;
// in_list = llListReplaceList(in_list, (list)shifted, pos, pos);
// return in_list;
//
// Safe optimized version
integer index = pos >> 2;
return llListReplaceList(in_list,
(list)(llList2Integer(in_list, index) | (value << ((pos & 3) << 3))),
index, index);
}
-----
与えられたリストの pos の位置に 値 value を詰め込んでいる のかな... w
-----
integer unpack(list in_list, integer pos) {
return (llList2Integer(in_list, pos >> 2) >> ((pos & 3) << 3)) & 0x000000FF; // unsigned
// return (llList2Integer(in_list, pos >> 2) << (((~pos) & 3) << 3)) >> 24; //signed
}
-----
与えられたリストの pos の位置から 値を取り出している
-----
change_color(vector color) {
integer num_prims = llGetListLength(gXyTextPrims) << 2;
integer i = 0;
for (; i <= num_prims; ++i) {
integer link = unpack(gXyTextPrims, i);
if (!link) {
return ;
}
llSetLinkPrimitiveParams(link, [
PRIM_COLOR, FACE_1, color, 1.0,
PRIM_COLOR, FACE_2, color, 1.0,
PRIM_COLOR, FACE_3, color, 1.0,
PRIM_COLOR, FACE_4, color, 1.0,
PRIM_COLOR, FACE_5, color, 1.0
]);
}
}
-----
リスト gXyTextPrims で リンク番号を 管理された全てのプリムの色を color にする
-----
change_line_color(integer bank, vector color) {
// get the bank offset and length
integer i = llList2Integer(gBankingData, (bank * BANK_STRIDE));
integer bank_end = i + llList2Integer(gBankingData, (bank * BANK_STRIDE) + 1);
for (; i < bank_end; ++i) {
integer link = unpack(gXyTextPrims,i);
if (!link) {
return ;
}
llSetLinkPrimitiveParams(link, [
PRIM_COLOR, FACE_1, color, 1.0,
PRIM_COLOR, FACE_2, color, 1.0,
PRIM_COLOR, FACE_3, color, 1.0,
PRIM_COLOR, FACE_4, color, 1.0,
PRIM_COLOR, FACE_5, color, 1.0
]);
}
}
-----
リスト gXyTextPrims で リンク番号を 管理された bank に属す プリムの色を color にする
(続く)
Posted by walkinglint at 20:02│Comments(0)
│walking のスクリプティング講座