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;
}