Slide Display

From Second Life Wiki
Jump to: navigation, search
KBnote.png Note: Due to licensing issues, all contributions to this wiki have stopped and the articles that we posted are just being maintained. This is one of the projects that has gone further and for updates you are cordially invited to the project page on our wiki.

Introduction

The following script turns a primitive into a display for giving talks. The display allow you to scroll back and forward between the textures in the inventory as well as zoom into a part of the picture and drag it around to show a part of the current displayed texture. It also allows you to add an optional notecard containing lines which will be said on the local channel whenever a slide is displayed.

The script is OpenSIM compatible.

Setup

  • Convert your slides to textures.
  • Create a primitive and drag the resulting textures into that primitive. The script reads the textures in alphanumerical order. For example, if you have a texture called "a" and a textures named "b", then "a" will precede "b". Similarly, "a_1" will be read before "a_2". The case is important as well, "A" gets read before "a".
  • [Optional] Create a notecard and add a description for each slide, line by line making sure you leave a blank newline at the end of the notecard. The first texture will correspond to the first line of text in this notecard and the last texture will correspond to the last line before the newline. After that, drag the notcard as well into the primitive you created in the previous step.
  • Create a new script containing the code below and put it into the primitive you created.

You are set.

Operating

By clicking the primitive you will get a menu with "Next =>", "<= Prev" and "[ Point ]". The "Next =>" option will switch over to the next slide. The "<= Back" option will go back to the previous slide.

To use the "[ Point ]" option, select it from the menu first. After that, left click and hold on any portion of the current slide that you would like to zoom in to. The texture will zoom on that point. If you left click, hold down and drag the mouse as well, the texture will zoom and move around following your cursor. Once you are done, release the left mouse button and the menu will pop-up again, or click the primitive again for the menu.

Code

//////////////////////////////////////////////////////////
// [K] Kira Komarov - 2011, License: GPLv3              //
// Please see: http://www.gnu.org/licenses/gpl.html     //
// for legal details, rights of fair usage and          //
// the disclaimer and warranty conditions.              //
//////////////////////////////////////////////////////////
 
integer comChannel = 0;
integer comHandle = 0;
list slide = [];
list text = [];
string text_card = "";
key cQuery = NULL_KEY;
 
integer dir = 0;
 
integer init()
{
    integer index;
    slide = [];
 
    while (index < llGetInventoryNumber(INVENTORY_TEXTURE))
    {
        slide += [llGetInventoryName(INVENTORY_TEXTURE, index)];
        ++index;
    }
 
    if (!llGetListLength(slide))
    {
        llOwnerSay("The primitive contains no texture, please add a texture.");
        return FALSE;
    }
    llOwnerSay("Loaded textures in sequence: " + llList2CSV(slide) + ".");
 
    if (llGetInventoryNumber(INVENTORY_NOTECARD))
    {
        text_card = llGetInventoryName(INVENTORY_NOTECARD, 0);
        llOwnerSay("Text card found, reading...");
        text = [];
        cQuery = llGetNotecardLine(text_card, (comChannel = 0));
        return FALSE;
    }
 
    return TRUE;
}
 
list next()
{
    string p;
    string w;
 
@a_1;
    p = llList2String(slide, 0);
    slide = llDeleteSubList(slide, 0, 0);
    slide += p;
 
    w = llList2String(text, 0);
    text = llDeleteSubList(text, 0, 0);
    text += w;
 
    if (dir < 0)
    {
        dir = 1;
        jump a_1;
    }
    dir = 1;
 
    return [w, p];
}
 
list prev()
{
    string p;
    string w;
 
@a_2;
    p = llList2String(slide, llGetListLength(slide) - 1);
    slide = llDeleteSubList(slide, llGetListLength(slide) - 1, llGetListLength(slide) - 1);
    slide = llListInsertList(slide, (list)p, 0);
 
    w = llList2String(text, llGetListLength(text) - 1);
    text = llDeleteSubList(text, llGetListLength(text) - 1, llGetListLength(text) - 1);
    text = llListInsertList(text, (list)w, 0);
 
    if (dir > 0) {
        dir = -1;
        jump a_2;
    }
 
    dir = -1;
 
    return [w, p];
}
 
default
{
    on_rez(integer start_param)
    {
        if (init())
            state display;
    }
 
    changed(integer change)
    {
        if (change & (CHANGED_OWNER | CHANGED_INVENTORY))
            if (init())
                state display;
    }
 
    state_entry()
    {
        if (init())
            state display;
    }
 
    dataserver(key query_id, string data)
    {
        if (query_id != cQuery)
            return;
 
        if (data == EOF)
        {
            text = llDeleteSubList(text, llGetListLength(text) - 1, llGetListLength(text) - 1);
            llOwnerSay("Read: " + (string)(comChannel - 1) + " text lines.");
            state display;
            return;
        }
 
        text += (list)data;
        cQuery = llGetNotecardLine(text_card, ++comChannel);
    }
}
 
state display
{
    state_entry()
    {
        if (cQuery == "p")
        {
            key owner = llGetOwner();
 
            comChannel = ((integer)("0x" + llGetSubString((string)llGetKey(), -8, -1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
            llListenRemove(comHandle);
            comHandle = llListen(comChannel, "", owner, "");
            llDialog(owner, "Please select an option: ", ["Next =>", "[ END ]", "<= Prev", " ", "[ Point ]", " "], comChannel);
            return;
        }
        llOwnerSay("Ready for operation, click \"Next =>\" for the next slide.");
    }
 
    touch_start(integer num)
    {
        key id = llDetectedKey(0);
        key owner = llGetOwner();
 
        if (id != owner)
            return;
 
        comChannel = ((integer)("0x" + llGetSubString((string)llGetKey(), -8, -1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF;
        llListenRemove(comHandle);
        comHandle = llListen(comChannel, "", owner, "");
        llDialog(owner, "Please select an option: ", ["Next =>", "[ END ]", "<= Prev", " ", "[ Point ]", " "], comChannel);
    }
 
    listen(integer channel, string name, key id, string message)
    {
        if (message == "Next =>")
        {
            list res = next();
            llSetTexture(llList2String(res, 1), 0);
 
            if (!llGetListLength(text))
                llSay(PUBLIC_CHANNEL, llList2String(res, 0));
        }
        else if (message == "<= Prev")
        {
            list res = prev();
            llSetTexture(llList2String(res, 1), 0);
 
            if (!llGetListLength(text))
                llSay(PUBLIC_CHANNEL, llList2String(res, 0));
        }
        else if (message == "[ END ]")
        {
            llListenRemove(comHandle);
            return;
        }
        else if (message == "[ Point ]")
        {
            state point;
            return;
        }
        llDialog(llGetOwner(), "Please select an option: ", ["Next =>", "[ END ]", "<= Prev", " ", "[ Point ]", " "], comChannel);
        llSetTimerEvent(3600.0);
    }
 
    changed(integer change)
    {
        if (change & CHANGED_INVENTORY)
            llResetScript();
    }
 
    timer()
    {
        llListenRemove(comHandle);
        llSetTimerEvent((float)FALSE);
    }
}
 
state point
{
    touch(integer num_detected)
    {
        vector tc = llDetectedTouchST(num_detected);
 
        llOffsetTexture(tc.x - 0.5, tc.y - 0.5, 0);
        llScaleTexture(0.2, 0.2, 0);
    }
 
    touch_end(integer num_detected)
    {
        llScaleTexture(1.0, 1.0, 0);
        llOffsetTexture(0.0, 0.0, 0);
        cQuery = "p";
 
        state display;
    }
}