Subversion Repositories spk

Rev

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