Subversion Repositories spk

Rev

Rev 11 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "RenderObject.h"

CRenderObject::CRenderObject () 
{ 
        m_bClicked = false;
        m_iStarted = 0; 
        m_iStartFade = 0;
        m_iFadeTo = 0;
        m_iAlpha = 255;
        m_iMaxAlpha = 255;
        m_bStartHidden = false;
        m_iColour[0] = m_iColour[1] = m_iColour[2] = 255;
        m_bMouseOver = false;
        m_bDontRender = false;
}

CRenderObject::~CRenderObject ()
{
        for ( SAnimate *it = m_lAnimations.First(); it; it = m_lAnimations.Next() )
                delete it;

        CLinkList<SMouseOver> *list = NULL;
        for ( int i = 0; i < 2; i++ )
        {
                if ( i == 0 )
                        list = &m_lMouseOver;
                else if ( i == 1 )
                        list = &m_lMouseClick;

                for ( SMouseOver *mo = list->First(); mo; mo = list->Next() )
                {
                        if ( mo->iType == MO_TEXTURE )
                        {
                                if ( ((SMOTexture *)mo)->pTexture )
                                        ((SMOTexture *)mo)->pTexture->Release();
                        }
                        delete mo;
                }
        }

        m_lVaribles.Clear();
        m_lAnimations.clear();
        m_lMouseOver.clear();
        m_lMouseClick.clear();
}

void CRenderObject::AddMouseEvent ( CyString section, SMouseOver *e )
{
        if ( section == "MOUSEOVER" )
                m_lMouseOver.push_back ( e );
        else if ( section == "ONCLICK" )
                m_lMouseClick.push_back ( e );
}

void CRenderObject::ParseSetting ( COverlay *overlay, CyString cmd, CyString rest, CyString section ) 
{
        cmd.ToUpper();
        if ( section == "ANIMATE" )
        {
                SAnimate *anim = NULL;
                if ( cmd == "FADEOUT" )
                {
                        anim = (SAnimate *)new SAnimateFadeOut;
                        ((SAnimateFadeOut *)anim)->iTime = rest.GetToken ( ",", 2, 2 ).ConvertEquation();
                }
                else if ( cmd == "FADEIN" )
                {
                        anim = (SAnimate *)new SAnimateFadeIn;
                        ((SAnimateFadeIn *)anim)->iTime = rest.GetToken ( ",", 2, 2 ).ConvertEquation();
                }
                else if ( cmd == "FLASH" )
                {
                        anim = (SAnimate *)new SAnimateFlash;
                        ((SAnimateFlash *)anim)->iTime = rest.GetToken ( ",", 2, 2 ).ConvertEquation();
                        ((SAnimateFlash *)anim)->iCycle = rest.GetToken ( ",", 3, 3 ).ConvertEquation();
                }
                else if ( cmd == "MOVE" )
                {
                        anim = (SAnimate *)new SAnimatePos;
                        ((SAnimatePos *)anim)->iX = rest.GetToken ( ",", 2, 2 ).ConvertEquation();
                        ((SAnimatePos *)anim)->iY = rest.GetToken ( ",", 3, 3 ).ConvertEquation();
                }
                else if ( cmd == "MOVELINEAR" )
                {
                        anim = (SAnimate *)new SAnimateLinear;
                        ((SAnimateLinear *)anim)->iX = rest.GetToken ( ",", 2, 2 ).ConvertEquation();
                        ((SAnimateLinear *)anim)->iY = rest.GetToken ( ",", 3, 3 ).ConvertEquation();
                        ((SAnimateLinear *)anim)->iTime = rest.GetToken ( ",", 4, 4 ).ConvertEquation();
                }

                if ( anim )
                {
                        anim->iDone = 0;
                        anim->bRemove = false;
                        anim->iStartTime = ConvertAnimationTime ( rest.GetToken ( ",", 1, 1 ) );
                        m_lAnimations.push_back ( anim );
                }
        }
        else if ( (section == "MOUSEOVER") || (section == "ONCLICK") )
        {
                if ( (cmd == "SOUND") && (overlay) )
                {
                        CyString file = rest;
                        file = file.FindReplace ( "\\", "/" );
                        file.RemoveSpaces ();

#ifdef FMOD
                        if ( overlay->CreateSound ( file ) )
                        {
                                SMOSound *s = new SMOSound;
                                s->sFilename = file;
                                AddMouseEvent ( section, s );
                        }
#endif
                }
                else if ( cmd == "COLOUR" )
                {
                        SMOColour *c = new SMOColour;
                        c->iColour[0] = rest.GetToken ( ",", 1, 1 ).ConvertEquation();
                        c->iColour[1] = rest.GetToken ( ",", 2, 2 ).ConvertEquation();
                        c->iColour[2] = rest.GetToken ( ",", 3, 3 ).ConvertEquation();
                        AddMouseEvent ( section, c );
                }
                else if ( cmd == "SWITCHVARIABLE" )
                {
                        SMOSwitchV *v = new SMOSwitchV;
                        v->sVariable = rest.GetToken ( ",", 1, 1 ).upper();
                        v->lSwitch.SplitToken ( ',', rest.GetToken ( ",", 2 ) );
                        AddMouseEvent ( section, v );
                }
                else if ( cmd == "CLOSE" )
                {
                        SMouseOver *m = new SMouseOver;
                        m->iType = MO_CLOSE;
                        AddMouseEvent ( section, m );
                }
                else if ( cmd == "SEND" )
                {
                        SMOSend *m = new SMOSend;
                        m->sName = rest.GetToken ( ",", 1, 1 );
                        m->sData = rest.GetToken ( ",", 2 );
                        if ( m->sData.Empty() )
                                m->sData = "1";
                        AddMouseEvent ( section, m );
                }
        }
        else if ( section.Empty() )
        {
                if ( cmd == "POS" )
                {
                        m_iX = rest.GetToken ( ",", 1, 1 ).ConvertEquation();
                        m_iY = rest.GetToken ( ",", 2, 2 ).ConvertEquation();
                }
                if ( cmd == "FadeIn" )
                {
                        m_iStartFade = rest.GetToken ( ",", 1, 1 ).ConvertEquation();
                        m_iFadeTo = rest.GetToken ( ",", 2, 2 ).ConvertEquation();
                }
                else if ( cmd == "ALPHA" )
                        m_iMaxAlpha = rest.ConvertEquation();
                else if ( cmd == "STARTHIDDEN" )
                        m_bStartHidden = true;
                else if ( cmd == "LOCALVARIABLE" )
                        m_lVaribles.PushBack ( CyString("$") + rest.GetToken ( ",", 1, 1 ).upper() + "$" , rest.GetToken ( ",", 2, 2 ));
        }
}


CyString CRenderObject::ParseVaribles ( CyString str, CyStringList *varibles )
{
        if ( !str.IsIn ( "$" ) )
                return str;

        for ( SStringList *it = varibles->Head(); it; it = it->next )
        {
                if ( it->data.Empty() )
                        continue;
                str.FindReplace ( it->str, it->data );
        }
        return str;
}


void CRenderObject::StartAnimation ( SAnimate *anim )
{
        if ( anim->iType == ANIM_MOVE )
        {
                SAnimatePos *pos = (SAnimatePos *)anim;
                m_iX = pos->iX;
                m_iY = pos->iY;
                EndAnimation ( anim );
        }
        else if ( anim->iType == ANIM_MOVELINEAR )
        {
                m_iStartX = m_iX;
                m_iStartY = m_iY;
        }
}

void CRenderObject::EndAnimation ( SAnimate *anim )
{
        if ( anim->iType == ANIM_FLASH )
                m_iAlpha = m_iMaxAlpha;
        anim->bRemove = true;
}

void CRenderObject::DoAnimation ( SAnimate *anim, int iDt )
{
        switch ( anim->iType )
        {
                case ANIM_FADEOUT:
                        if ( Fade ( ((SAnimateFadeOut*)anim)->iTime, anim->iDone, ((SAnimateFadeOut*)anim)->iTime, true ) )
                                EndAnimation ( anim );
                        break;
                case ANIM_FADEIN:
                        if ( Fade ( ((SAnimateFadeIn*)anim)->iTime, anim->iDone, ((SAnimateFadeIn*)anim)->iTime, false ) )
                                EndAnimation ( anim );
                        break;
                case ANIM_FLASH:
                        {
                                SAnimateFlash *fa = (SAnimateFlash*)anim;
                                fa->iDoneCycle += iDt;
                                if ( Fade ( fa->iCycle, fa->iDoneCycle, fa->iCycle, fa->bIn ) )
                                {
                                        fa->bIn = !fa->bIn;
                                        fa->iDoneCycle = 0;
                                }
                                if ( fa->iDone >= fa->iTime )
                                        EndAnimation ( anim );
                        }
                        break;
                case ANIM_MOVELINEAR:
                        {
                                SAnimateLinear *l = (SAnimateLinear*)anim;
                                if ( l->iDone > l->iTime )
                                {
                                        m_iX = l->iX;
                                        m_iY = l->iY;
                                        EndAnimation ( anim );
                                }
                                else
                                {
                                        float t = (float)l->iDone / (float)l->iTime;

                                        if ( l->iX == m_iX ) m_iX = l->iX;
                                        else                             m_iX = (int)(((1 - t) * (float)m_iStartX) + (t * (float)l->iX));

                                        if ( l->iY == m_iY ) m_iY = l->iY;
                                        else                             m_iY = (int)(((1 - t) * (float)m_iStartY) + (t * (float)l->iY));
                                }
                        }
                        break;
        }
}

bool CRenderObject::Fade ( int end, int current, int maxtime, bool reverse )
{
        if ( current >= end )
        {
                if ( reverse )
                        m_iAlpha = 0;
                else
                        m_iAlpha = m_iMaxAlpha;
                return true;
        }
        else
        {
                float t = (float)current / (float)maxtime;
                if ( reverse )
                        t = (1 - t);
                m_iAlpha = (int) (t * (float)m_iMaxAlpha);
        }
        return false;
}

int CRenderObject::SetMouseClicked ( COverlay *overlay, CyString name, int but, bool b ) 
{ 
        int ret = 0;

        if ( but == 0 )
        {
                m_bClicked = b; 
                for ( SMouseOver *mo = m_lMouseClick.First(); mo; mo = m_lMouseClick.Next() )
                {
                        if ( (mo->iType == MO_CLOSE) && (b) )
                                ret = 1;
                        else if ( (b) && (!mo->bStarted) )
                        {
                                if ( mo->iType == MO_SOUND )
                                {
#ifdef FMOD
                                        SMOSound *s = (SMOSound *)mo;
                                        overlay->PlaySound ( s->sFilename );
#endif
                                }
                                else if ( mo->iType == MO_SWITCHVARIABLE )
                                {
                                        SMOSwitchV *s = (SMOSwitchV *)mo;
                                        // find the varible to switch
                                        SStringList *node, *opt;
                                        for ( node = m_lVaribles.Head(); node; node = node->next )
                                        {
                                                if ( node->str == (CyString("$") + s->sVariable + "$") )
                                                        break;
                                        }

                                        if ( node )
                                        {
                                                // find the current option;
                                                for ( opt = s->lSwitch.Head(); opt; opt = opt->next )
                                                {
                                                        if ( opt->str == node->data )
                                                                break;
                                                }

                                                if ( opt )
                                                {
                                                        if ( opt->next )
                                                                node->data = opt->next->str;
                                                        else
                                                                node->data = s->lSwitch.Head()->str;
                                                }
                                        }
                                }
                                else if ( mo->iType == MO_SEND )
                                {
                                        SMOSend *s = (SMOSend *)mo;
                                        overlay->Send ( name + ":" + s->sName + ":" + s->sData );
                                }
                                mo->bStarted = true;
                        }
                        else if ( !b )
                                mo->bStarted = false;
                }
        }

        return ret;
}

void CRenderObject::Update ( COverlay *overlay, float dt, int mousex, int mousey, int offsetx, int offsety ) 
{
        int iDt = (int)(dt * 1000);
        m_iStarted += iDt;

        if ( m_iAlpha > m_iMaxAlpha )
                m_iAlpha = m_iMaxAlpha;

        if ( (m_iFadeTo) && (m_iStarted >= m_iStartFade) )
        {
                if ( Fade (m_iFadeTo + m_iStartFade, m_iStarted, m_iFadeTo - m_iStartFade, false) )
                        m_iFadeTo = 0;
        }

        for ( SAnimate *it = m_lAnimations.First(); it; it = m_lAnimations.Next() )
        {
                if ( it->iDone )
                {
                        DoAnimation ( it, iDt );
                        it->iDone += iDt;
                }
                else if ( m_iStarted > it->iStartTime )
                {
                        it->iDone = iDt;
                        StartAnimation ( it );
                }

                if ( it->bRemove )
                        m_lAnimations.RemoveCurrent ();
        }
        
        m_bMouseOver = false;
        if ( (!m_lMouseOver.empty()) && (mousex != -1) && (mousey != -1) )
        {
                for ( SMouseOver *mo = m_lMouseOver.First(); mo; mo = m_lMouseOver.Next() )
                {       
                        m_bMouseOver = CheckMouse ( mousex, mousey, offsetx, offsety );

                        if ( m_bMouseOver )
                        {
                                if ( (mo->iType == MO_SOUND) && (!((SMOSound *)mo)->bStarted) )
                                {
                                        SMOSound *s = (SMOSound *)mo;
#ifdef FMOD
                                        overlay->PlaySound ( s->sFilename );
#endif
                                        s->bStarted = true;
                                }
                        }
                        else
                        {
                                if ( mo->iType == MO_SOUND )
                                        ((SMOSound *)mo)->bStarted = false;
                        }
                }
        }
}

int CRenderObject::ConvertAnimationTime ( CyString t )
{
        if ( t.Left(1) == '+' )
        {
                if ( !m_lAnimations.empty() )
                        t = CyString::Number(m_lAnimations.Last()->iStartTime) + t;
        }
        return t.ConvertEquation ();
}