Go to most recent revision | 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
//////////////////////////////////////////////////////////////////////
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);
}
CyString CLcdCustomScreen::ParseFilename(CyString &filename, CyString &dir)
{
CyString f = filename;
f = f.FindReplace("$progdir", m_sProgDir);
f = f.FindReplace("$gamedir", m_sGameDir);
// relative filename
if ( !f.IsIn(":") )
f = dir + "/" + f;
f = f.FindReplace("/", "\\");
f = f.FindReplace("\\\\", "\\");
return f;
}
bool CLcdCustomScreen::LoadScript ( CyString sDir, CyString sProgDir, const char *filename )
{
m_lDebugLog.Clear();
m_lVaribles.Clear();
int iCurrentPos = 0;
m_iStartPage = m_pLcd->AddNewPage () - 1;
m_pLcd->ModifyControlsOnPage( m_iStartPage );
int iLastX, iLastY;
m_bDebug = false;
CyString fname = filename;
fname = fname.FindReplace("$progdir", sProgDir);
// relative path
if ( !fname.IsIn(":") )
fname = sDir + "/" + filename;
fname = fname.FindReplace("\\", "/"); // make sure we're using the correct slash
fname = fname.FindReplace("//", "/"); // remove any double slashes
CyString dir = fname.GetToken("/", 1, -1);
m_sScriptDir = dir;
m_sProgDir = sProgDir;
m_sGameDir = sDir;
FILE *id = fopen ( fname.c_str(), "r" );
if ( id )
{
int iLine = 0;
while ( !feof(id) )
{
CyString line;
line = line.GetEndOfLine ( id, &iLine, false );
if ( (line.Left (2) == "//") || (line.Empty()) )
continue;
CyString arg = line.GetToken ( 1, ' ' ).ToLower();
if ( arg == "displayfor:" )
{
m_iCycles = line.GetToken ( 2, ' ' ).ToInt();
if ( (!m_iCycles) || (m_iCycles < 0) )
m_lDebugLog.PushBack ( CyString((long)iLine) + (CyString(": Invalid argument for \"DisplayFor\" (") + line.GetToken ( 2, ' ' )) + ")", false );
}
else if ( arg == "debug" )
m_bDebug = true;
else if ( arg == "varible:" )
{
if ( line.NumToken ( ' ' ) < 2 )
m_lDebugLog.PushBack ( CyString((long)iLine) + CyString(": Missing Argument for \"Varible\""), false );
else
m_lVaribles.PushBack ( line.GetToken ( 2, ' ' ) );
}
else if ( arg == "icon:" )
{
if ( line.NumToken ( ' ' ) < 6 )
m_lDebugLog.PushBack ( CyString((long)iLine) + CyString(": Missing Arguments for \"Icon\""), false );
else
{
CyString sIcon = line.GetToken ( 6, -1, ' ' );
int iSizeX = line.GetToken ( 4, ' ' ).ToInt();
int iSizeY = line.GetToken ( 5, ' ' ).ToInt();
HICON hIcon = static_cast<HICON>(LoadImage(0, (LPCTSTR)ParseFilename(sIcon, dir).c_str(), IMAGE_ICON, iSizeX, iSizeY, LR_LOADFROMFILE));
if ( FAILED (hIcon) )
m_lDebugLog.PushBack ( CyString((long)iLine) + CyString(": Unable to open icon file: ") + sIcon, false );
else
{
m_pHandles[iCurrentPos] = m_pLcd->AddIcon(hIcon, iSizeX, iSizeY);
int iX = line.GetToken ( 2, ' ' ).ToInt ();
int iY = line.GetToken ( 3, ' ' ).ToInt ();
m_pLcd->SetOrigin ( m_pHandles[iCurrentPos], iX, iY );
iLastX = iX;
iLastY = iY;
iCurrentPos++;
}
}
}
else if ( (arg == "move:") || (arg == "moverepeat:") )
{
if ( line.NumToken ( ' ' ) < 4 )
m_lDebugLog.PushBack ( CyString((long)iLine) + CyString(": Missing Argument for \"Move\""), false );
else if ( !iCurrentPos )
m_lDebugLog.PushBack ( CyString((long)iLine) + CyString(": No object before move command"), false );
else
{
SMoveObject *o = new SMoveObject;
o->hObject = m_pHandles[iCurrentPos - 1];
if ( arg == "moverepeat:" )
o->bRepeat = true;
else
o->bRepeat = false;
o->iStartX = iLastX;
o->iStartY = iLastY;
if ( line.GetToken ( 2, ' ' ) == "-" )
o->iEndX = o->iStartX;
else
o->iEndX = line.GetToken ( 2, ' ' ).ToInt();
if ( line.GetToken ( 3, ' ' ) == "-" )
o->iEndY = o->iStartY;
else
o->iEndY = line.GetToken ( 3, ' ' ).ToInt();
o->iTimeRemaining = o->iTotalTime = line.GetToken ( 4, ' ' ).ToInt();
AddMoveObject ( o );
}
}
else if ( ((arg.Left(9) == "textsmall") || (arg.Left(10) == "textmedium") || (arg.Left(9) == "textlarge")) && (arg.Right(1) == ":") )
{
if ( line.NumToken ( ' ' ) < 6 )
m_lDebugLog.PushBack ( CyString((long)iLine) + CyString(": Missing Argument for \"Text\""), false );
else
{
CyString align = line.GetToken ( 5, ' ' ).ToLower();
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
m_lDebugLog.PushBack ( CyString((long)iLine) + CyString(": Invalid alignment setting \"") + align + "\"", false );
LGTextSize iSize = LG_SMALL;
if ( arg.Left(10) == "textmedium" )
iSize = LG_MEDIUM;
else if ( arg.Left(9) == "textsmall" )
iSize = LG_SMALL;
else if ( arg.Left(9) == "textlarge" )
iSize = LG_BIG;
bool scroll = false;
if ( arg.Right (7) == "Scroll:" )
scroll = true;
int len = line.GetToken ( 4, ' ' ).ToInt();
int x = line.GetToken ( 2, ' ' ).ToInt ();
int y = line.GetToken ( 3, ' ' ).ToInt ();
CyString str = line.GetToken ( 6, -1, ' ' );
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
m_lDebugLog.PushBack ( CyString((long)iLine) + CyString(": 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 ( CyString v, int pos )
{
if ( pos >= m_lVaribles.Count() )
return;
m_lVaribles.GetAt ( pos )->data = v;
}
void CLcdCustomScreen::Reset ()
{
m_pLcd->RemovePage ( m_iStartPage + 1 );
m_pLcd->RemovePage ( m_iStartPage );
m_lDebugLog.Clear();
m_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 );
SStringList *str = m_lDebugLog.Head();
for ( int i = 0; i < 5; i++ )
{
if ( !str )
break;
m_pLcd->SetText ( m_hDebug[i], (LPCTSTR)str->str.c_str() );
str = str->next;
}
if ( !m_lDebugLog.Head() )
m_pLcd->SetText ( m_hDebug[0], _T("No errors found!") );
}
else
{
m_pLcd->ShowPage ( m_iStartPage );
m_pLcd->ModifyControlsOnPage ( m_iStartPage );
for ( SText *text = m_pText; text; text = text->pNext )
{
CyString newtext = text->sText;
for ( SStringList *v = m_lVaribles.Head(); v; v = v->next )
newtext.FindReplace ( CyString("$") + v->str, v->data );
m_pLcd->SetText ( text->hObject, (LPCTSTR)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;
}