Subversion Repositories spk

Rev

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

// LcdCustomScreen.cpp: implementation of the CLcdCustomScreen class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "LcdCustomScreen.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Utils::WString GetEndOfLine(FILE* id, int* line, bool upper)
{
        std::string word;

        char c = fgetc(id);
        if (c == -1)
                return L"";

        while ((c != 13) && (!feof(id)) && (c != '\n'))
        {
                word += c;
                c = fgetc(id);
        }

        if (line)
                ++(*line);

        if (upper)
                return Utils::WString(word).upper();

        return Utils::WString(word);
}


CLcdCustomScreen::CLcdCustomScreen( CEzLcd *lcd )
{
        m_pLcd = lcd;
        m_iArraySize = 10;
        m_pHandles = (HANDLE *)malloc(sizeof(HANDLE) * m_iArraySize);
        m_iCycles = 10;
        m_bDebug = false;
        m_pMoveObject = m_pEndMoveObject = NULL;
        m_pText = m_pEndText = NULL;
}

CLcdCustomScreen::~CLcdCustomScreen()
{
        Reset ();
        free ( m_pHandles );
}

void CLcdCustomScreen::IncreaseArraySize ()
{
        m_iArraySize += 5;
        m_pHandles = (HANDLE *)realloc(m_pHandles, sizeof(HANDLE) * m_iArraySize);
}

Utils::WString CLcdCustomScreen::parseFilename(const Utils::WString &filename, const Utils::WString &dir)
{
        Utils::WString f = filename;
        
        f = f.findReplace(L"$progdir", m_sProgDir);
        f = f.findReplace(L"$gamedir", m_sGameDir);

        // relative filename
        if ( !f.contains(L":") )
                f = dir + L"/" + f;

        f = f.findReplace(L"/", L"\\");
        f = f.findReplace(L"\\\\", L"\\");
        return f;
}
bool CLcdCustomScreen::loadScript (const Utils::WString &sDir, const Utils::WString& sProgDir, const Utils::WString& filename)
{
        _lDebugLog.clear();
        _lVaribles.clear();

        int iCurrentPos = 0;

        m_iStartPage = m_pLcd->AddNewPage () - 1;
    m_pLcd->ModifyControlsOnPage( m_iStartPage );

        int iLastX, iLastY;

        m_bDebug = false;
        Utils::WString fname = filename;
        fname = fname.findReplace(L"$progdir", sProgDir);

        // relative path
        if ( !fname.contains(L":") )
                fname = sDir + L"/" + filename;
        fname = fname.findReplace(L"\\", L"/"); // make sure we're using the correct slash
        fname = fname.findReplace(L"//", L"/"); // remove any double slashes
        Utils::WString dir = fname.tokens(L"/", 1);

        m_sScriptDir = dir;
        m_sProgDir = sProgDir;
        m_sGameDir = sDir;

        FILE *id = _wfopen ( fname.c_str(), L"r" );
        if ( id )
        {
                int iLine = 0;
                while ( !feof(id) )
                {
                        Utils::WString line;
                        line = GetEndOfLine ( id, &iLine, false );
                        if ( (line.left (2) == L"//") || (line.empty()) )
                                continue;
                        Utils::WString arg = line.token(L" ", 1).lower();
                        if ( arg == L"displayfor:" )
                        {
                                m_iCycles = line.token(L" ", 2).toInt();
                                if ( (!m_iCycles) || (m_iCycles < 0) )
                                        _lDebugLog.pushBack (Utils::WString((long)iLine) + L": Invalid argument for \"DisplayFor\" (" + line.token(L" ", 2) + L")");
                        }
                        else if ( arg == L"debug" )
                                m_bDebug = true;
                        else if ( arg == L"varible:" )
                        {
                                if ( line.countToken(L" ") < 2)
                                        _lDebugLog.pushBack(Utils::WString((long)iLine) + L": Missing Argument for \"Varible\"");
                                else
                                        _lVaribles.pushBack(line.token(L" ", 2));
                        }
                        else if ( arg == L"icon:" )
                        {
                                if ( line.countToken(L" ") < 6)
                                        _lDebugLog.pushBack(Utils::WString((long)iLine) + L": Missing Arguments for \"Icon\"");
                                else
                                {
                                        Utils::WString sIcon = line.tokens(L" ", 6);
                                        int iSizeX = line.token(L" ", 4).toInt();
                                        int iSizeY = line.token(L" ", 5).toInt();
                                        HICON hIcon = static_cast<HICON>(LoadImage(0, (LPCTSTR)parseFilename(sIcon, dir).c_str(), IMAGE_ICON, iSizeX, iSizeY, LR_LOADFROMFILE));
                                        if ( FAILED (hIcon) )
                                                _lDebugLog.pushBack (Utils::WString((long)iLine) + L": Unable to open icon file: " + sIcon);
                                        else
                                        {
                                                m_pHandles[iCurrentPos] = m_pLcd->AddIcon(hIcon, iSizeX, iSizeY);
                                                int iX = line.token(L" ", 2).toInt();
                                                int iY = line.token (L" ", 3).toInt();
                                                m_pLcd->SetOrigin ( m_pHandles[iCurrentPos], iX, iY );
                                                iLastX = iX;
                                                iLastY = iY;
                                                iCurrentPos++;
                                        }
                                }
                        }
                        else if ( (arg == L"move:") || (arg == L"moverepeat:") )
                        {
                                if ( line.countToken(L" ") < 4)
                                        _lDebugLog.pushBack(Utils::WString((long)iLine) + L": Missing Argument for \"Move\"");
                                else if ( !iCurrentPos )
                                        _lDebugLog.pushBack(Utils::WString((long)iLine) + L": No object before move command");
                                else
                                {
                                        SMoveObject *o = new SMoveObject;
                                        o->hObject = m_pHandles[iCurrentPos - 1];
                                        if ( arg == L"moverepeat:" )
                                                o->bRepeat = true;
                                        else
                                                o->bRepeat = false;
                                        o->iStartX = iLastX;
                                        o->iStartY = iLastY;
                                        if ( line.token(L" ", 2) == L"-")
                                                o->iEndX = o->iStartX;
                                        else
                                                o->iEndX = line.token(L" ", 2).toInt();
                                        if ( line.token(L" ", 3) == L"-")
                                                o->iEndY = o->iStartY;
                                        else
                                                o->iEndY = line.token(L" ", 3).toInt();
                                        o->iTimeRemaining = o->iTotalTime = line.token(L" ", 4).toInt();
                                        AddMoveObject ( o );
                                }
                        }
                        else if ( ((arg.left(9) == L"textsmall") || (arg.left(10) == L"textmedium") || (arg.left(9) == L"textlarge")) && (arg.right(1) == L":") )
                        {
                                if ( line.countToken(L" ") < 6)
                                        _lDebugLog.pushBack(Utils::WString((long)iLine) + L": Missing Argument for \"Text\"");
                                else
                                {
                                        Utils::WString align = line.token(L" ", 5).lower();
                                        int iAlign = DT_CENTER;
                                        if ( align == "center" )
                                                iAlign = DT_CENTER;
                                        else if ( align == "left" )
                                                iAlign = DT_LEFT;
                                        else if ( align == "right" )
                                                iAlign = DT_RIGHT;
                                        else
                                                _lDebugLog.pushBack(Utils::WString((long)iLine) + L": Invalid alignment setting \"" + align + L"\"");

                                        LGTextSize iSize = LG_SMALL;
                                        if ( arg.left(10) == L"textmedium" )
                                                iSize = LG_MEDIUM;
                                        else if ( arg.left(9) == L"textsmall" )
                                                iSize = LG_SMALL;
                                        else if ( arg.left(9) == L"textlarge" )
                                                iSize = LG_BIG;

                                        bool scroll = false;
                                        if ( arg.right (7) == L"Scroll:" )
                                                scroll = true;

                                        int len = line.token(L" ", 4).toInt();
                                        int x = line.token(L" ", 2).toInt();
                                        int y = line.token(L" ", 3).toInt();
                                        Utils::WString str = line.tokens(L" ", 6);
                                        m_pHandles[iCurrentPos] = m_pLcd->AddText ( (scroll) ? LG_SCROLLING_TEXT : LG_STATIC_TEXT, iSize, iAlign, len );
                                        m_pLcd->SetOrigin ( m_pHandles[iCurrentPos], x, y );
                                        m_pLcd->SetText ( m_pHandles[iCurrentPos], (LPCTSTR)str.c_str() );

                                        SText *text = new SText;
                                        text->hObject = m_pHandles[iCurrentPos];
                                        text->sText = str;
                                        AddText ( text );
                                        iCurrentPos++;
                                }
                        }
                        else
                                _lDebugLog.pushBack(Utils::WString((long)iLine) + L": Invalid Command: " + arg );

                        if ( iCurrentPos >= m_iArraySize )
                                IncreaseArraySize();
                }

                fclose ( id );
        }

        // debug
        m_pLcd->AddNewPage ();
    m_pLcd->ModifyControlsOnPage(m_iStartPage + 1);
        for ( int i = 0; i < 5; i++ )
        {
                m_hDebug[i] = m_pLcd->AddText ( LG_SCROLLING_TEXT, LG_SMALL, DT_LEFT, 160 );
                m_pLcd->SetOrigin ( m_hDebug, 0, (i * 9) );
        }

        if ( m_bDebug )
                m_iCycles = 100;

        return true;
}

void CLcdCustomScreen::setVarible(const Utils::WString &v, size_t pos )
{
        if ( pos >= _lVaribles.size() )
                return;

        _lVaribles[pos]->data = v;
}

void CLcdCustomScreen::Reset ()
{
        m_pLcd->RemovePage ( m_iStartPage + 1 );
        m_pLcd->RemovePage ( m_iStartPage );

        _lDebugLog.clear();
        _lVaribles.clear();

        SMoveObject *o = m_pMoveObject;
        while ( o )
        {
                SMoveObject *next = o->pNext;
                delete o;
                o = next;
        }

        SText *t = m_pText;
        while ( t )
        {
                SText *next = t->pNext;
                delete t;
                t = next;
        }
        m_pMoveObject = m_pEndMoveObject = NULL;
        m_pText = m_pEndText = NULL;
}

void CLcdCustomScreen::AddMoveObject ( SMoveObject *o )
{
        o->pNext = NULL;
        if ( !m_pEndMoveObject )
                m_pMoveObject = m_pEndMoveObject = o;
        else
        {
                m_pEndMoveObject->pNext = o;
                m_pEndMoveObject = o;
        }
}

void CLcdCustomScreen::AddText ( SText *t )
{
        t->pNext = NULL;
        if ( !m_pEndText )
                m_pText = m_pEndText = t;
        else
        {
                m_pEndText->pNext = t;
                m_pEndText = t;
        }
}

bool CLcdCustomScreen::Display ()
{
        --m_iCycles;

        if ( m_bDebug )
        {
                m_pLcd->ShowPage ( m_iStartPage + 1 );
            m_pLcd->ModifyControlsOnPage ( m_iStartPage + 1 );

                if (_lDebugLog.empty())
                        m_pLcd->SetText(m_hDebug[0], _T("No errors found!"));
                else
                {
                        size_t max = _lDebugLog.size() > 5 ? 5 : _lDebugLog.size();
                        for (size_t i = 0; i < max; i++)
                                m_pLcd->SetText(m_hDebug[i], _lDebugLog[i]->str.c_str());
                }

        }
        else
        {
                m_pLcd->ShowPage ( m_iStartPage );
            m_pLcd->ModifyControlsOnPage ( m_iStartPage );

                for ( SText *text = m_pText; text; text = text->pNext )
                {
                        Utils::WString newtext = text->sText;
                        for(auto itr = _lVaribles.begin(); itr != _lVaribles.end(); itr++)
                                newtext = newtext.findReplace(L"$" + (*itr)->str, (*itr)->data );
                        m_pLcd->SetText ( text->hObject, newtext.c_str());
                }

                // now do moving objects
                for ( SMoveObject *o = m_pMoveObject; o; o = o->pNext )
                {
                        if ( o->iTimeRemaining > 0 )
                                o->iTimeRemaining--;
                        else if ( o->bRepeat )
                                o->iTimeRemaining = o->iTotalTime;
                        
                        float t = (o->iTotalTime - o->iTimeRemaining)  / (float)o->iTotalTime;
                        float u = 1 - t;

                        int iX, iY;
                        if ( o->iStartX == o->iEndX ) iX = o->iStartX;
                        else                                              iX = (int)((double)((1 - t) * o->iStartX) + (t * o->iEndX));

                        if ( o->iStartY == o->iEndY ) iY = o->iStartY;
                        else                                              iY = (int)((double)((1 - t) * o->iStartY) + (t * o->iEndY));

                        m_pLcd->SetOrigin ( o->hObject, iX, iY );
                }
        }

        if ( m_iCycles > 0 )
                return true;
        return false;
}