Blame | Last modification | View Log | RSS feed
//#include "stdafx.h"
#include "Display.h"
#include "../Hook/MyDirect3DDevice9.h"
CDisplay::CDisplay ( COverlay *overlay, MyDirect3DDevice9 *device, CyString name )
{
m_sGuiName = name;
m_pOverlay = overlay;
m_iWidth = m_iHeight = 0;
m_bLongWait = false;
m_bClosed = false;
m_pMouseX = m_pMouseY = NULL;
m_bHaltMouse = false;
m_pBorderFile = NULL;
m_pCursorFile = NULL;
m_lastUpdate = timeGetTime();
m_pDevice = device;
m_iFadeState = FADE_NONE;
m_bNoBorder = false;
m_iBorderSizeX = m_iBorderSizeY = 42;
m_bRender = true;
m_iAlpha = 255;
m_iStartDisplay = 0;
m_bLog = false;
m_borderTexture = NULL;
D3DXCreateTextureFromFile ( device, "Overlay/border.png", &m_borderTexture );
m_cursorTexture = NULL;
if ( FAILED(D3DXCreateSprite (device, &m_sprite) ) )
m_sprite = NULL;
}
CDisplay::~CDisplay ()
{
if ( m_borderTexture )
m_borderTexture->Release ();
if ( m_sprite )
m_sprite->Release ();
ClearObjects ();
for ( SSound *s = m_lSounds.First(); s; s = m_lSounds.Next() )
delete s;
if ( m_pBorderFile )
delete m_pBorderFile;
if ( m_pCursorFile )
delete m_pCursorFile;
for ( SCloseOn *close = m_lClose.First(); close; close = m_lClose.Next() )
delete close;
for ( SFunction *func = m_lFunctions.First(); func; func = m_lFunctions.Next() )
delete func;
m_lFunctions.clear();
m_lSounds.clear();
m_lClose.clear();
}
void CDisplay::CreateSound ( CyString file, long start )
{
file = file.FindReplace ( "\\", "/" );
file.RemoveSpaces ();
if ( !m_pOverlay )
return;
if ( m_pOverlay->CreateSound ( file ) )
{
SSound *sound = new SSound;
sound->iStart = start;
m_lSounds.push_back ( sound );
}
}
void CDisplay::SetCursorTexture ( CyString t )
{
CyString ext = t.GetToken ( ".", t.NumToken ('.') ).ToLower();
if ( ext == "stx" )
{
m_pCursorFile = new CTextureFile ();
if ( !m_pCursorFile->Load ( t.c_str() ) )
{
delete m_pCursorFile;
m_pCursorFile = NULL;
}
else
m_cursorTexture = m_pCursorFile->CreateTexture ( m_pDevice );
}
if ( t == "default" )
D3DXCreateTextureFromFile ( m_pDevice, "Overlay/cursor.png", &m_cursorTexture );
else
D3DXCreateTextureFromFile ( m_pDevice, t.c_str(), &m_cursorTexture );
}
void CDisplay::SetBorderTexture ( CyString t )
{
if ( m_borderTexture )
m_borderTexture->Release();
m_borderTexture = NULL;
CyString ext = t.GetToken ( ".", t.NumToken ('.') ).ToLower();
if ( ext == "stx" )
{
m_pBorderFile = new CTextureFile ();
if ( !m_pBorderFile->Load ( t.c_str() ) )
{
delete m_pBorderFile;
m_pBorderFile = NULL;
}
else
{
m_borderTexture = m_pBorderFile->CreateTexture ( m_pDevice );
m_iBorderSizeX = m_pBorderFile->GetFrameWidth();
m_iBorderSizeY = m_pBorderFile->GetFrameHeight();
}
}
else
D3DXCreateTextureFromFile ( m_pDevice, t.c_str(), &m_borderTexture );
if ( (!m_borderTexture) && (!m_pBorderFile) )
D3DXCreateTextureFromFile ( m_pDevice, "Overlay/border.png", &m_borderTexture );
}
float CDisplay::Update ( DWORD tNow )
{
float dt = tNow - (float) m_lastUpdate;
if ( dt < 15 ) // dont update so quickly
return 0;
m_lastUpdate = tNow;
// dont update more than 1 second at a time
m_bLongWait = false;
if ( dt > 1000 )
{
dt = 1000;
m_bLongWait = true;
m_bLog = true;
CDisplay::Log ( "LongWait(), setting log flag\n" );
// for ( CRenderObject *o = m_objects.Last(); o; o = m_objects.Prev() )
// {
// if ( o->DoReopen () )
// m_bClosed = true;
// }
}
m_iStartDisplay += (int)dt;
dt /= 1000;
if ( m_iFadeState != FADE_AFTER )
{
bool mouseOver = (!m_pMouseX || !m_pMouseY) ? true : false;
for ( CListNode<CRenderObject> *node = m_objects.Back(); node; node = node->prev() )
{
CRenderObject *o = node->Data();
if ( mouseOver )
o->Update ( m_pOverlay, dt, -1, -1, m_iCornerX, m_iCornerY );
else
{
o->Update ( m_pOverlay, dt, *m_pMouseX, *m_pMouseY, m_iCornerX, m_iCornerY );
if ( o->MouseOver() )
mouseOver = true;
}
}
}
if ( m_pOverlay )
{
for ( SSound *s = m_lSounds.First(); s; s = m_lSounds.Next() )
{
if ( s->bStarted )
continue;
if ( s->iStart > m_iStartDisplay )
continue;
s->bStarted = true;
m_pOverlay->PlaySound ( s->sFilename );
}
}
return dt;
}
bool CDisplay::IsMouseInGui ()
{
if ( !m_pMouseX || !m_pMouseY )
return false;
if ( *m_pMouseX < m_iCornerX )
return false;
else if ( *m_pMouseX > (m_iCornerX + m_iSizeX) )
return false;
else if ( *m_pMouseY < m_iCornerY )
return false;
else if ( *m_pMouseY > (m_iCornerY + m_iSizeY) )
return false;
return true;
}
bool CDisplay::MouseClick ( int b, bool on )
{
bool clicked = false;
if ( on )
{
for ( SCloseOn *close = m_lClose.First(); close; close = m_lClose.Next() )
{
if ( (close->iStart) && (close->iStart > m_iStartDisplay) )
continue;
if ( (close->iEnd) && (close->iEnd < m_iStartDisplay) )
continue;
if ( (b == 0) && (close->iMouseCommands & COMMAND_LEFTCLICK) )
clicked = true;
else if ( (b == 0) && (close->iMouseCommands & COMMAND_LEFTCLICKIN) && (IsMouseInGui()) )
clicked = true;
else if ( (b == 1) && (close->iMouseCommands & COMMAND_RIGHTCLICK) )
clicked = true;
else if ( (b == 1) && (close->iMouseCommands & COMMAND_RIGHTCLICKIN) && (IsMouseInGui()) )
clicked = true;
if ( clicked )
break;
}
if ( clicked )
m_bClosed = true;
// now click all objects
bool c = false;
for ( CRenderObject *o = m_objects.Last(); o; o = m_objects.Prev() )
{
if ( (!c) && (o->CheckMouse ( *m_pMouseX, *m_pMouseY, m_iCornerX, m_iCornerY )) )
{
int ret = o->SetMouseClicked ( m_pOverlay, m_sGuiName, b, true );
c = true;
if ( ret == 1 )
m_bClosed = true;
}
else
o->SetMouseClicked ( m_pOverlay, m_sGuiName, b, false );
}
if ( c )
clicked = true;
}
// declick all objects
else
{
for ( CRenderObject *o = m_objects.Last(); o; o = m_objects.Prev() )
o->SetMouseClicked ( m_pOverlay, m_sGuiName, b, false );
}
return clicked;
}
bool CDisplay::CheckCloseEventKey ( int key )
{
bool pressed = false;
for ( SCloseOn *close = m_lClose.First(); close; close = m_lClose.Next() )
{
if ( (close->iStart) && (close->iStart > m_iStartDisplay) )
continue;
if ( (close->iEnd) && (close->iEnd < m_iStartDisplay) )
continue;
if ( (key == DIK_RETURN) && (close->iKeyCommands & COMMAND_KEY_ENTER) )
pressed = true;
else if ( (key == DIK_SPACE) && (close->iKeyCommands & COMMAND_KEY_SPACE) )
pressed = true;
if ( pressed )
break;
}
if ( pressed )
m_bClosed = true;
return pressed;
}
int CDisplay::GetMouseX ()
{
if ( !m_pMouseX )
return 0;
if ( m_bContainMouse )
{
if ( *m_pMouseX < m_iCornerX )
return m_iCornerX;
else if ( *m_pMouseX > (m_iCornerX + m_iSizeX) )
return m_iCornerX + m_iSizeX;
}
return *m_pMouseX;
}
int CDisplay::GetMouseY ()
{
if ( !m_pMouseY )
return 0;
if ( m_bContainMouse )
{
if ( *m_pMouseY < m_iCornerY )
return m_iCornerY;
else if ( *m_pMouseY > (m_iCornerY + m_iSizeY) )
return m_iCornerY + m_iSizeY;
}
return *m_pMouseY;
}
void CDisplay::render ( MyDirect3DDevice9 *device )
{
if ( m_bLongWait )
m_bLog = true;
if ( (m_bLongWait) || (m_bClosed) )
return;
if ( !m_bRender )
return;
if ( m_bLog ) CDisplay::Log ( "Setting render state\n" );
device->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);
if ( m_bLog ) CDisplay::Log ( "Setting up sprite rendering\n" );
m_sprite->Begin(D3DXSPRITE_ALPHABLEND);
if ( m_bLog ) CDisplay::Log ( "Rendering the border\n" );
if ( !m_bNoBorder )
RenderBorder ( device );
if ( m_iFadeState != FADE_AFTER )
{
if ( m_bLog ) CDisplay::Log ( "Fading in all objects\n" );
for ( CRenderObject *o = m_objects.First(); o; o = m_objects.Next() )
{
if ( (m_iFadeIn) && (m_iFadeState == FADE_ALL) && (!o->StartHidden()) )
o->SetAlpha ( m_iAlpha );
o->render ( device, m_iCornerX, m_iCornerY, m_sprite );
}
}
if ( m_bLog ) CDisplay::Log ( "Rendering of the cursor\n" );
RenderCursor ( device );
if ( m_bLog ) CDisplay::Log ( "Ending the sprite render\n" );
m_sprite->End ();
if ( m_bLog ) CDisplay::Log ( "render() finished\n" );
}
CyString CDisplay::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->data, it->str );
}
return str;
}
void CDisplay::RenderCursor ( MyDirect3DDevice9 *device )
{
if ( (!m_cursorTexture) || (!m_sprite) )
return;
if ( (!m_pMouseX) || (!m_pMouseY) )
return;
D3DXMATRIX mat;
D3DXMatrixTransformation2D ( &mat, NULL, 0.0, NULL, NULL, 0, &D3DXVECTOR2 ((float)GetMouseX(), (float)GetMouseY()) );
m_sprite->SetTransform(&mat);
m_sprite->Draw ( m_cursorTexture, NULL, NULL, NULL, 0xFFFFFFFF );
}
void CDisplay::RenderBorder ( MyDirect3DDevice9 *device )
{
if ( !m_borderTexture )
return;
if ( !m_sprite )
return;
int bx = GetBorderSizeX();
int by = GetBorderSizeY();
D3DXMATRIX mat;
D3DCOLOR color = D3DCOLOR_RGBA ( 255,255, 255, m_iAlpha );
// render top left corner
D3DXMatrixTransformation2D ( &mat, NULL, 0.0, NULL, NULL, 0, &D3DXVECTOR2 ((float)m_iCornerX - bx, (float)m_iCornerY - by) );
m_sprite->SetTransform(&mat);
m_sprite->Draw ( m_borderTexture, GetFrame(1), NULL, NULL, color );
// render top right corner
D3DXMatrixTransformation2D ( &mat, NULL, 0.0, NULL, NULL, 0, &D3DXVECTOR2 ((float)m_iCornerX + m_iSizeX, (float)m_iCornerY - by) );
m_sprite->SetTransform(&mat);
m_sprite->Draw ( m_borderTexture, GetFrame(3), NULL, NULL, color );
// render bottom left corner
D3DXMatrixTransformation2D ( &mat, NULL, 0.0, NULL, NULL, 0, &D3DXVECTOR2 ((float)m_iCornerX - bx, (float)m_iCornerY + m_iSizeY) );
m_sprite->SetTransform(&mat);
m_sprite->Draw ( m_borderTexture, GetFrame(7), NULL, NULL, color );
// render bottom right corner
D3DXMatrixTransformation2D ( &mat, NULL, 0.0, NULL, NULL, 0, &D3DXVECTOR2 ((float)m_iCornerX + m_iSizeX, (float)m_iCornerY + m_iSizeY) );
m_sprite->SetTransform(&mat);
m_sprite->Draw ( m_borderTexture, GetFrame(9), NULL, NULL, color );
// render top/bottom
int i;
for ( i = 1; i <= (m_iSizeX / bx); i++ )
{
D3DXMatrixTransformation2D ( &mat, NULL, 0.0, NULL, NULL, 0, &D3DXVECTOR2 ( ((float)m_iCornerX - bx) + (i * bx), (float)m_iCornerY - by) );
m_sprite->SetTransform(&mat);
m_sprite->Draw ( m_borderTexture, GetFrame(2), NULL, NULL, color );
D3DXMatrixTransformation2D ( &mat, NULL, 0.0, NULL, NULL, 0, &D3DXVECTOR2 ( ((float)m_iCornerX - bx) + (i * bx), (float)m_iCornerY + m_iSizeY) );
m_sprite->SetTransform(&mat);
m_sprite->Draw ( m_borderTexture, GetFrame(8), NULL, NULL, color );
}
//render sides
for ( i = 1; i <= (m_iSizeY / by); i++ )
{
D3DXMatrixTransformation2D ( &mat, NULL, 0.0, NULL, NULL, 0, &D3DXVECTOR2 ( ((float)m_iCornerX - bx), ((float)m_iCornerY - by) + (i * by)) );
m_sprite->SetTransform(&mat);
m_sprite->Draw ( m_borderTexture, GetFrame(4), NULL, NULL, color );
D3DXMatrixTransformation2D ( &mat, NULL, 0.0, NULL, NULL, 0, &D3DXVECTOR2 ((float)m_iCornerX + m_iSizeX, ((float)m_iCornerY - by) + (i * by)) );
m_sprite->SetTransform(&mat);
m_sprite->Draw ( m_borderTexture, GetFrame(6), NULL, NULL, color );
}
// render center
for ( i = 1; i <= (m_iSizeX / bx); i++ )
{
for ( int j = 1; j <= (m_iSizeY / by); j++ )
{
D3DXMatrixTransformation2D ( &mat, NULL, 0.0, NULL, NULL, 0, &D3DXVECTOR2 ( ((float)m_iCornerX - bx) + (i * bx), ((float)m_iCornerY - by) + (j * by)) );
m_sprite->SetTransform(&mat);
m_sprite->Draw ( m_borderTexture, GetFrame(5), NULL, NULL, color );
}
}
}
RECT *CDisplay::GetFrame ( int frame )
{
RECT *rect = new RECT;
int row = ((frame - 1) / 3) + 1;
int col = frame % 3;
if ( col == 0)
col = 3;
int bx = GetBorderSizeX();
int by = GetBorderSizeY();
int x = bx * col;
int y = by * row;
SetRect ( rect, x - bx, y - by, x, y );
return rect;
}
void CDisplay::SetPosition(int x, int y)
{
m_iCornerX = x;
m_iCornerY = y;
}
void CDisplay::SetSize(int width, int height)
{
m_iSizeX = width;
m_iSizeY = height;
}
void CDisplay::SetSize ( int width, int height, int maxwidth, int maxheight )
{
SetMaxSize(maxwidth, maxheight);
int bx = GetBorderSizeX();
int by = GetBorderSizeY();
if ( (width == maxwidth) && (height == maxheight) )
{
m_iSizeX = maxwidth;
m_iSizeY = maxheight;
m_iCornerX = m_iCornerY = 0;
}
else
{
if ( !m_bNoBorder )
{
width += (bx - (width % bx));
height += (by - (height % by));
}
m_iSizeX = width;
m_iSizeY = height;
m_iCornerX = (maxwidth / 2) - (width / 2);
m_iCornerY = (maxheight / 2) - (height / 2);
}
m_iWidth = maxwidth;
m_iHeight = maxheight;
}