Don't click here unless you want to be banned.

LSL Wiki : exchangeTLMLGenerator

HomePage :: PageIndex :: RecentChanges :: RecentlyCommented :: UserSettings :: You are ec2-54-161-166-171.compute-1.amazonaws.com
This script generates TLML code from the prim it is running in. This script doesn't support prim torture, and due to limitations in SL it cannot reproduce hover text or client-side rotations that have been added to the prim with llTargetOmega.

// TLML Exporter v0.30, drop in a page's prim to get the corresponding TLML code

// ===How to get unicode characters in your llSetText_text===
// "\\uxxxx"     where xxxx are 4 hex characters, unicode character 0000xxxx
// "\\Uxxxxxxxx" where xxxxxxxx are 8 hex characters, unicode character xxxxxxxx
// "\\n"         new line do not use "\n"
// "\\\\"         \
// "\\\""         "
// "\\t"         same as "\t", which you may use
// ""

vector offset = <0.0,0.0,1.0>;

string llSetText_text     = "";
vector llSetText_color    = <1.0,1.0,1.0>;
float  llSetText_alpha    = 1.0;

vector llTargetOmega_axis       = ZERO_VECTOR;
float  llTargetOmega_spinrate   = 0.0;
float  llTargetOmega_gain       = 0.0;

//ANIM_ON    ==    0x01
//LOOP      ==    0x02
//REVERSE     ==    0x04
//PING_PONG ==    0x08
//SMOOTH     ==    0x10
//ROTATE      ==    0x20
//SCALE      ==    0x40

integer llSetTextureAnim_mode = 0;
integer llSetTextureAnim_face = ALL_SIDES;
integer llSetTextureAnim_x_frames = 2;
integer llSetTextureAnim_y_frames = 2;
float     llSetTextureAnim_start_frame = 0;
float     llSetTextureAnim_end_frame = 3;
float   llSetTextureAnim_rate = 0.1;

string TLML_URL                 = "";

list llParticleSystem_list      = [];

setParticles()
{
    llParticleSystem_list += [];
}


//////////////////////////////////////////////////////////////
//               DO NOT MODIFY ANYTHING BELOW               //
//////////////////////////////////////////////////////////////
//This script is a nightmare, only the brave should venture deeper
//adding support for new features is pretty easy
//but don't touch the structure of the script
//because of the complexities of TLML, the data layout is complex
//the *right* was to do this would be with 3 passes
//1) determin the mask
//2) parse the masks and filling in the data
//Instead we do it with basicly a single pass
//Then as the masks become aparent we insert them into the stream.
//This saves alot of time with minimal expense
//Unfortunately it's horribly complex and incredibly hard to read
//To grok this script in it's entirety is to be avoided.

//{

//}
//{

//}
//{
string byte2hex(integer x)
{//Helper function for use with unicode characters.
    integer x0  = (x & 0xF);
    return llGetSubString(hexc, x0 = ((x >> 4) & 0xF), x0) + llGetSubString(hexc, x0, x0);
}

string Unescape(string a)
{
    string  b = a;
    integer c = -1;
    integer d;
    integer e;
    integer f = 0; 
    string g;
    while(d = llSubStringIndex(b, "\\") + 1)
    {
        g = llGetSubString(b,d,d);
        c += d;

        if((g == "\"") || (g == "\\"))
            a = llDeleteSubString(a,c,c);
        else if(g == "n")
            a = llInsertString(llDeleteSubString(a,c,c+1), c, "\n");
        else if(g == "t")
            a = llInsertString(llDeleteSubString(a,c,c+1), c, "\t");
        else if(g == "r")//rx[11,22,33,44,55,66,77,88,99,AA,BB,CC,DD,EE,FF]
        {
            g = "";
            if(d+(e = (integer)("0x"+llGetSubString(b,d+1,d+1)) * 2)+1 >= (f = llStringLength(b)))
                e = (f - d - 2) & -2;
            if((f = e))//this may look like a mistake, it's not $[E20002]
            {
                do
                    g = "%"+llGetSubString(b,d + e,d + e + 1) + g;
                while((e-=2) > 0);
            }
            a = llInsertString(llDeleteSubString(a,c, c + 2 + f),c, g = llUnescapeURL(g));
            c += llStringLength(g);//add to c so we don't accidentily unescape result
        }
        else if(g == "u" || (e = (g == "U")))// \uXXXX or  \UXXXXXXXX
        {
            a = llDeleteSubString(a, c, c + 5 + e *= 4);
            if(0 < e = (integer)("0x"+llGetSubString(b,d +1, d +4 + e)))
            {
                if (e >= 0x4000000)
                    f = 5;
                else if (e >= 0x200000)
                    f = 4;
                else if (e >= 0x10000)
                    f = 3;
                else if (e >= 0x800)
                    f = 2;
                else if (e >= 0x80)
                    f = 1;
                g = "%" + byte2hex((e >> (6 * f)) | ((0x3F80 >> f) * (0 != f)));
                while(f)
                    g += "%" + byte2hex((((e >> (6 * --f)) | 0x80) & 0xBF));
                a = llInsertString(a, c++, llUnescapeURL(g));
            }
        }
        b = llDeleteSubString(a,0,c);
    }
    return a;
}

//alternative licensensing exculsively granted for this script, acknowlegment is not required for use.
string Float2Hex(float a)
{// Copyright Strife Onizuka, 2006, LGPL, http://www.gnu.org/copyleft/lesser.html
    if(a != 0)
    {
        float b = llFabs(a);
        string f = "";
        integer c = llFloor(llLog(b) / 0.69314718055994530941723212145818);//floor(log2(b))
        integer d = (integer)((b / llPow(2.0,c)) * 0x1000000);//shift up into integer range
        c -= 24;//the extra c used to make it an integer
        while(!(d & 0xf))
        {//strip extra zeros off before converting or they break "p"
            d = d >> 4;
            c+=4;
        }
        do
            f = llGetSubString(hexc,15&d,15&d) + f;
        while(d = d >> 4);
        if(a < 0)
            return "-0x" + f + "p"+(string)c;
        return "0x" + f + "p"+(string)c;
    }
    return "0";//zero would screw up the log.
}

string flo(float a)
{
    string b = (string)a;
    while(llGetSubString(b,-1,-1) == "0")
        b=llDeleteSubString(b,-1,-1);
    if(llGetSubString(b,-1,-1) == ".")
        return llDeleteSubString(b,-1,-1);
    if(llGetSubString(b,(a<0),(a<0)+1)=="0.")
        return llDeleteSubString(b,(a<0),(a<0));
    return b;
}

string vec(vector a)
{
    if(a == ZERO_VECTOR) return "";
    return "<"+flo(a.x)+","+flo(a.y)+","+flo(a.z)+">";
}

string vecF2H(vector a)
{
    if(a == ZERO_VECTOR) return "";
    list b = ["<",flo(a.x),",",flo(a.y),",",flo(a.z),">"];
    vector c = (vector)((string)b);
    if(c.x != a.x) 
        b = llListReplaceList(b, [Float2Hex(a.x)], 1, 1);
    if(c.y != a.y) 
        b = llListReplaceList(b, [Float2Hex(a.y)], 3, 3);
    if(c.z != a.z) 
        b = llListReplaceList(b, [Float2Hex(a.z)], 5, 5);
    return (string)b;
}

string rot(rotation a)
{
    if(a == ZERO_ROTATION) return "";
    list b = ["<",flo(a.x),",",flo(a.y),",",flo(a.z),",",flo(a.s),">"];
    rotation c = (rotation)((string)b);
    if(c.x != a.x) 
        b = llListReplaceList(b, [Float2Hex(a.x)], 1, 1);
    if(c.y != a.y) 
        b = llListReplaceList(b, [Float2Hex(a.y)], 3, 3);
    if(c.z != a.z) 
        b = llListReplaceList(b, [Float2Hex(a.z)], 5, 5);
    if(c.s != a.s) 
        b = llListReplaceList(b, [Float2Hex(a.s)], 7, 7);
    return (string)b;
}

string int(integer a)
{
    if(a == 0) return "";
    return (string)a;
}

string TightListDump(list a, string b)
{
    string c = (string)a;
    if(llStringLength(b)==1)
        if(llSubStringIndex(c,b) == -1)
            jump end;
    integer d = -llStringLength(b += "|\\/?!@#$%^&*()_=:;~{}[],\n\" qQxXzZ");
    while(1+llSubStringIndex(c,llGetSubString(b,d,d)) && d)
        ++d;
    b = llGetSubString(b,d,d);
    @end;
    c = "";//save memory
    return b + llDumpList2String(a, b+(string)(a = []));
}

string TightListTypeDump(list a, string b) {
    b += "|\\/?!@#$%^&*()_=:;~{}[],\n\" qQxXzZ";
    string c = (string)a;
    integer d = 0;
    do
        if(1+llSubStringIndex(c,llGetSubString(b,d,d)))
            b = llDeleteSubString(b,d,d);
        else
            ++d;
    while(d<6);
    b = " " + c = llGetSubString(b,0,5);
    integer e;
    string f;
    if((d = -llGetListLength(a)))
    {
        do
        {
            e = llGetListEntryType(a,d);

            if((e > 0 && e < 3) || e > 4) f = (string)lis(llList2List(a,d,d));
            else

                f = llList2String(a,d);
            c+= llGetSubString(b,e,e) + f;
        }while(++d);
    }
    return c;
}

list lis(list a)
{
    integer b = -llGetListLength(a) - 1;
    list c;
    integer d;
    while(++b)
    {
        if((d = llGetListEntryType(a,b)) == TYPE_FLOAT)
        {
            float e = llList2Float(a,b);
            if(e != 0.0)
                c += flo(e);
            else
                c += "";
        }
        else if(d == TYPE_VECTOR)
            c += vec(llList2Vector(a,b));
        else if(d == TYPE_ROTATION)
            c += rot(llList2Rot(a,b));
        else if(d == TYPE_INTEGER)
            c += int(llList2Integer(a,b));
        else
            c += llList2String(a,b);
    }
    return c;
}

string hex(integer x) 
{
    integer x0 = x & 0xF;
    string res = llGetSubString(hexc, x0, x0);
    x = (x >> 4) & 0x0FFFFFFF; //otherwise we get infinite loop on negatives.
    while( x != 0 )
    {
        x0 = x & 0xF;
        res = llGetSubString(hexc, x0, x0) + res;
        x = x >> 4;
    } 
    return res;
}

string hexc="0123456789ABCDEF";
//}
add(string value, integer mask)
{
    if(llStringLength(llDumpList2String(header+params," ")+value) > 247)
    {
        store();
        if(mode & param_mask)
            mode = mode & attribute_mask;
    }
    mode = mode | mask;
    params += value;
}
store()
{
    break();
    if(mode & param_mask)
    {
        recycle_mask = recycle_mask & ~default_mask;
        ++cc;
    }
    commands += TightListDump(llDeleteSubList(params,-1,-1),(string)(params = []));
    if(llGetListLength(commands) == 1)
        header = llListReplaceList(header,[""],1,1);
    params = header + [sep];
}
break()
{
    list s = [sep];
    integer b = llListFindList(params, s);
    integer a;
    integer k;

    if(llList2String(params,-1) != sep)//it's possible we might be on a boarder already.
        params += mode;
    else
        params = llDeleteSubList(params,-1,-1);

    if(b + 1)
    {
        list r = [hex(recycle_mask)];
        string p = hex(a = recycle_mask & ~default_mask);
        if((recycle_mask && !cc) || (a && cc))
        {
            if(cc)
                r = [p];
            k = config_mask;
        }
        else
            r = [];
        while((b = 1 + llListFindList(llDeleteSubList(params + s, 0, a = b),s)))
        {
            b += a;
            params = llListReplaceList(llDeleteSubList(params,b - 1, b),[hex(llList2Integer(params, b - 1) | k)] + r, a, a);
            if(k)
                r = [p];
        }
    }
//    llOwnerSay("a"+(string)recycle_mask+TightListDump(params,""));
    params += sep;
}
burn()
{
    integer a = -llGetListLength(commands);
    integer k;
    string m = hex(recycle_mask);
    string p = hex(recycle_mask & ~default_mask);
    string n;
    integer j = llStringLength(sep) - 1;
    if(a)
    {
        do
        {
            if(1 + k = llSubStringIndex(n = llList2String(commands,a),sep))
            {
                do
                    n = llInsertString(llDeleteSubString(n, k, k+j),k,m);
                while(1 + k = llSubStringIndex(n,sep));
                commands = llListReplaceList(commands, [n], a, a);
            }
//            llOwnerSay("b"+(string)recycle_mask+n);
            m = p;
        }
        while(++a);
    }
    cc = 0;
}
//{
theFace(integer f)
{
    mode = (((multiplefaces >> 32) | f) & 0xF);

    if(multiplefaces & 0x40)
        mode = mode | 0x40 | 
        (0x80 * (llList2Integer(llGetPrimitiveParams([PRIM_FULLBRIGHT, f]), 0) !=0));

    string t_s;
    if(multiplefaces & 0x100)
    {
        if((t_s = llGetTexture(f)) == "5748decc-f629-461c-9a36-a35a221fe21f")
            recycle_mask = recycle_mask | 0x1;
        else
            add(t_s, 0x100);
    }

    vector t_v;
    if(multiplefaces & 0x200)
    {
        if ((t_v = llGetColor(f)) != <1.0, 1.0, 1.0>)
            add(vec(t_v), 0x200);
        else
            recycle_mask = recycle_mask | 0x2;
    }

    float t_f;
    if(multiplefaces & 0x400)
    {
        if  ((t_f = llGetAlpha(f)) != 1.0)
            add(flo(t_f), 0x400);
        else
            recycle_mask = recycle_mask | 0x4;
    }

    if(multiplefaces & 0x800)
    {
        if ((t_v = llGetTextureScale(f)) != <1.0, 1.0, 0.0>)
            add(vec(t_v), 0x800);
        else
            recycle_mask = recycle_mask | 0x8;
    }

    if(multiplefaces & 0x1000)
    {
        if ((t_v = llGetTextureOffset(f)) != ZERO_VECTOR)
            add(vec(t_v), 0x1000);
        else
            recycle_mask = recycle_mask | 0x10;
    }

    if(multiplefaces & 0x2000)
    {
        if ((t_f = llGetTextureRot(f)) != 0.0)
            add(flo(t_f), 0x2000);
        else
            recycle_mask = recycle_mask | 0x20;
    }

    if(multiplefaces & (0x4000 | 0x8000))
    {
        list t_l = llGetPrimitiveParams([PRIM_BUMP_SHINY, f]);
        integer t_i;
        if(multiplefaces & 0x4000)
        {
            if ((t_i = llList2Integer(t_l, 0)) != PRIM_SHINY_NONE)
                add((string)t_i, 0x4000);
            else
                recycle_mask = recycle_mask | 0x40;
        }

        if(multiplefaces & 0x8000)
        {
            if ((t_i = llList2Integer(t_l, 1)) != PRIM_BUMP_NONE)
                add((string)t_i, 0x8000);
            else
                recycle_mask = recycle_mask | 0x80;
        }
    }
}

checkFaces()
{
    integer max = llGetNumberOfSides();
    multiplefaces = FALSE;
    string texture = llGetTexture(0);
    vector texture_scale = llGetTextureScale(0);
    vector texture_offset = llGetTextureOffset(0);
    float texture_rot = llGetTextureRot(0);

    vector color = llGetColor(0);
    float alpha = llGetAlpha(0);
    list fullbrights = llGetPrimitiveParams([PRIM_FULLBRIGHT, ALL_SIDES]);
    integer fullbright = llList2Integer(fullbrights, 0);
    list bump_shiny = llGetPrimitiveParams([PRIM_BUMP_SHINY, ALL_SIDES]);
    integer bump = llList2Integer(bump_shiny,1);
    integer shiny = llList2Integer(bump_shiny,0);

    integer i = 1;
    integer m = 0x40 | 0x100 | 0x200 | 0x400 | 0x800 |
                0x1000 | 0x2000 | 0x4000 | 0x8000;

    for (; i<max && multiplefaces != m; ++i)
    {
        if (llList2Integer(fullbrights, i) != fullbright)
            multiplefaces = multiplefaces | 0x40;

        if (llGetTexture(i) != texture)
            multiplefaces = multiplefaces | 0x100;

        if (llGetColor(i) != color)
            multiplefaces = multiplefaces | 0x200;

        if (llGetAlpha(i) != alpha)
            multiplefaces = multiplefaces | 0x400;

        if (llGetTextureScale(i) != texture_scale)
            multiplefaces = multiplefaces | 0x800;

        if (llGetTextureOffset(i) != texture_offset)
            multiplefaces = multiplefaces | 0x1000;

        if (llGetTextureRot(i) != texture_rot)
            multiplefaces = multiplefaces | 0x2000;

        if (llList2Integer(bump_shiny, i* 2 + 1) != bump)
            multiplefaces = multiplefaces | 0x4000;

        if (llList2Integer(bump_shiny, i* 2) != shiny)
            multiplefaces = multiplefaces | 0x8000;
    }
    if(multiplefaces != m)
    {
        mode = mode | 0x1;
        multiplefaces = ~(i = multiplefaces);
        theFace(0);
        multiplefaces = i;
    }
}

checkPrim()
{
    list type = llGetPrimitiveParams([PRIM_TYPE]);
    if (llList2Integer(type, 0) == 0)
        if (llList2Integer(type, 1) == 0)
            if (llList2Vector(type, 2) == <0.0, 1.0, 0.0>)
                if (llList2Float(type, 3) == 0.0)
                    if (llList2Vector(type, 4) == ZERO_VECTOR)
                        if (llList2Vector(type, 5) == <1.0, 1.0, 0.0>)
                            if (llList2Vector(type, 6) == ZERO_VECTOR)
                            {
                                recycle_mask = recycle_mask | 0x1;
                                return;
                            }
    add(TightListDump(lis(type),"*"), 0x4);
}
//}
string sep;

integer mode;

integer multiplefaces;

list params;
list header;

integer recycle_mask;

list commands;
integer cc;

integer default_mask;
integer config_mask;
integer param_mask;
integer attribute_mask;

default
{
    state_entry()
    {
        setParticles();
        llSetText(Unescape(llSetText_text), llSetText_color, llSetText_alpha);
        llTargetOmega(llTargetOmega_axis, llTargetOmega_spinrate, llTargetOmega_gain);
        llParticleSystem(llParticleSystem_list);
        llSetTextureAnim(llSetTextureAnim_mode, llSetTextureAnim_face, llSetTextureAnim_x_frames, llSetTextureAnim_y_frames,
                                llSetTextureAnim_start_frame,llSetTextureAnim_end_frame,llSetTextureAnim_rate);

        llOwnerSay("--------------------------------------");

        sep = llUnescapeURL("%01");
//        sep = "        ";

        if((llGetObjectPermMask(MASK_OWNER) & 0x0000E000) != 0x0000E000)
        {//If you remove this check the script will not function any better.
        //Many of the functions used to gather information do the same permissions check internaly
        //Those functions will cause error messages and an invalid TLML stream.
        //YOU HAVE BEEN WARNED.
            llOwnerSay("You cannot clone an object you do not have full permission on");
            return;
        }

        if(TLML_URL == "")
            TLML_URL = "-"+llGetObjectDesc();

        header = [llGetLinkNumber(), TLML_URL];

        params = header + [sep];
        default_mask = 0xF;
        param_mask = 0xffffFFFC;
        attribute_mask = 0x0;
        config_mask = 0x1;
//{        
        checkPrim();

        add(vec(llGetScale()), 0x10);

        if (llGetLinkNumber() >= 2)// || rot_offset != ZERO_ROTATION)
        {
            vector pos = offset + (llGetLocalPos() );//* rot_offset);
            if(pos != ZERO_VECTOR)
                add(vecF2H(pos), 0x20);

            rotation local = llGetLocalRot();// * rot_offset; // or is it rot_offset * llGetLocalRot(); ?
            if (local != ZERO_ROTATION)
                add(rot(llGetLocalRot()), 0x80);
            else
                recycle_mask = recycle_mask | 0x2;
        }
        else
        {
            recycle_mask = recycle_mask | 0x2;
            if(offset != ZERO_VECTOR)
                add(vecF2H(offset), 0x20);
        }

        if(llSetText_text != "")
        {
            add(llSetText_text, 0x100);
            if(llSetText_color != <1.0,1.0,1.0> || llSetText_alpha != 1.0)
                add(rot(<llSetText_color.x, llSetText_color.y, llSetText_color.z, llSetText_alpha>), 0x200);
            else
                recycle_mask = recycle_mask | 0x8;
        }
        else
            recycle_mask = recycle_mask | 0x4 | 0x8;

        if(llParticleSystem_list != [])
        {
            add(TightListTypeDump(llParticleSystem_list,"*@#$%^&"), 0x400);
            recycle_mask = recycle_mask | 0x10;
        }

        if(llTargetOmega_axis != ZERO_VECTOR || llTargetOmega_spinrate != 0.0 || llTargetOmega_gain != 0.0)// $[E20011]
        {
            add(TightListDump([vec(llTargetOmega_axis),flo(llTargetOmega_spinrate),flo(llTargetOmega_gain)],"*"), 0x800);
            recycle_mask = recycle_mask | 0x20;
        }

        if(llSetTextureAnim_mode)
        {
            add(TightListDump([llSetTextureAnim_face, llSetTextureAnim_mode, llSetTextureAnim_x_frames, llSetTextureAnim_y_frames,
                    flo(llSetTextureAnim_start_frame),flo(llSetTextureAnim_end_frame),flo(llSetTextureAnim_rate)],"*"), 0x1000);
            recycle_mask = recycle_mask | 0x40;
        }
//}        
        break();
        burn();
        header += "-";
        default_mask = 0xFF;
        recycle_mask = 0;
        param_mask = 0xffffFFF0;
        config_mask = 0x10;
        attribute_mask = 0x0CF;
        checkFaces();

        integer t = llGetNumberOfSides();
        integer c;
        if(multiplefaces)
        {
            while(c < t)
            {
                break();
                burn();
                recycle_mask = 0;
                theFace(c++);
            }
        }
        store();
        burn();

        t = -llGetListLength(commands);

//        llOwnerSay("-----------------------");
        while(t)
            llOwnerSay("T"+llList2String(commands,t++));

        llRemoveInventory(llGetScriptName());
    }
}
There is no comment on this page. [Display comments/form]