diff options
Diffstat (limited to 'src/ui/control.cpp')
-rw-r--r-- | src/ui/control.cpp | 1748 |
1 files changed, 874 insertions, 874 deletions
diff --git a/src/ui/control.cpp b/src/ui/control.cpp index 525cab2..6ff7c2f 100644 --- a/src/ui/control.cpp +++ b/src/ui/control.cpp @@ -1,874 +1,874 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-
-#include <windows.h>
-#include <stdio.h>
-#include <d3d.h>
-
-#include "common/struct.h"
-#include "old/d3dengine.h"
-#include "common/language.h"
-#include "common/restext.h"
-#include "old/math3d.h"
-#include "common/event.h"
-#include "common/misc.h"
-#include "object/robotmain.h"
-#include "old/particule.h"
-#include "common/misc.h"
-#include "common/iman.h"
-#include "old/text.h"
-#include "old/sound.h"
-#include "ui/control.h"
-
-
-
-
-// Object's constructor.
-
-CControl::CControl(CInstanceManager* iMan)
-{
- m_iMan = iMan;
-
- m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE);
- m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT);
- m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN);
- m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE);
- m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND);
- m_eventMsg = EVENT_NULL;
- m_state = STATE_ENABLE|STATE_VISIBLE|STATE_GLINT;
- m_fontSize = SMALLFONT;
- m_fontStretch = NORMSTRETCH;
- m_fontType = FONT_COLOBOT;
- m_justif = 0;
- m_name[0] = 0;
- m_tooltip[0] = 0;
- m_bFocus = false;
- m_bCapture = false;
-
- m_bGlint = false;
- m_glintCorner1 = Math::Point(0.0f, 0.0f);
- m_glintCorner2 = Math::Point(0.0f, 0.0f);
- m_glintProgress = 999.0f;
- m_glintMouse = Math::Point(0.0f, 0.0f);
-}
-
-// Object's destructor.
-
-CControl::~CControl()
-{
-}
-
-
-// Creates a new button.
-// pos: [0..1]
-
-bool CControl::Create(Math::Point pos, Math::Point dim, int icon, EventMsg eventMsg)
-{
- char text[100];
- char* p;
-
- if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
-
- m_pos = pos;
- m_dim = dim;
- m_icon = icon;
- m_eventMsg = eventMsg;
-
- pos.x = m_pos.x;
- pos.y = m_pos.y+m_dim.y;
- GlintCreate(pos);
-
- GetResource(RES_EVENT, m_eventMsg, text);
- p = strchr(text, '\\');
- if ( p == 0 )
- {
- if ( icon != -1 )
- {
- strcpy(m_tooltip, text);
- }
- }
- else
- {
- strcpy(m_tooltip, p+1); // text after "\\"
- }
-
- return true;
-}
-
-
-void CControl::SetPos(Math::Point pos)
-{
- m_pos = pos;
-
- pos.x = m_pos.x;
- pos.y = m_pos.y+m_dim.y;
- GlintCreate(pos);
-}
-
-Math::Point CControl::RetPos()
-{
- return m_pos;
-}
-
-void CControl::SetDim(Math::Point dim)
-{
- Math::Point pos;
-
- m_dim = dim;
-
- pos.x = m_pos.x;
- pos.y = m_pos.y+m_dim.y;
- GlintCreate(pos);
-}
-
-Math::Point CControl::RetDim()
-{
- return m_dim;
-}
-
-
-// Modify an attribute of state.
-
-bool CControl::SetState(int state, bool bState)
-{
- if ( bState ) m_state |= state;
- else m_state &= ~state;
- return true;
-}
-
-// Sets an attribute of state.
-
-bool CControl::SetState(int state)
-{
- m_state |= state;
- return true;
-}
-
-// Removes an attribute of state.
-
-bool CControl::ClearState(int state)
-{
- m_state &= ~state;
- return true;
-}
-
-// Tests an attribute of state.
-
-bool CControl::TestState(int state)
-{
- return (m_state & state) ? true:false;
-}
-
-// Returns all attributes of state.
-
-int CControl::RetState()
-{
- return m_state;
-}
-
-
-// Management icon.
-
-void CControl::SetIcon(int icon)
-{
- m_icon = icon;
-}
-
-int CControl::RetIcon()
-{
- return m_icon;
-}
-
-
-// Management of the button name.
-
-void CControl::SetName(char* name, bool bTooltip)
-{
- char* p;
-
- if ( bTooltip )
- {
- p = strchr(name, '\\');
- if ( p == 0 )
- {
- strncpy(m_name, name, 100);
- m_name[100-1] = 0;
- }
- else
- {
- char buffer[100];
-
- strncpy(m_tooltip, p+1, 100); // text after "\\"
- m_tooltip[100-1] = 0;
-
- strncpy(buffer, name, 100);
- buffer[100-1] = 0;
- p = strchr(buffer, '\\');
- if ( p != 0 ) *p = 0;
- strncpy(m_name, buffer, 100);
- m_name[100-1] = 0;
- }
- }
- else
- {
- strncpy(m_name, name, 100);
- m_name[100-1] = 0;
- }
-}
-
-char* CControl::RetName()
-{
- return m_name;
-}
-
-
-// Management of the mode of justification (-1,0,1).
-
-void CControl::SetJustif(int mode)
-{
- m_justif = mode;
-}
-
-int CControl::RetJustif()
-{
- return m_justif;
-}
-
-
-// Management of the size of the font.
-
-void CControl::SetFontSize(float size)
-{
- m_fontSize = size;
-}
-
-float CControl::RetFontSize()
-{
- return m_fontSize;
-}
-
-
-// Management of the stretch of font.
-
-void CControl::SetFontStretch(float stretch)
-{
- m_fontStretch = stretch;
-}
-
-float CControl::RetFontStretch()
-{
- return m_fontStretch;
-}
-
-
-// Choice of the font.
-
-void CControl::SetFontType(FontType font)
-{
- m_fontType = font;
-}
-
-FontType CControl::RetFontType()
-{
- return m_fontType;
-}
-
-
-// Specifies the tooltip.
-
-bool CControl::SetTooltip(char* name)
-{
- strcpy(m_tooltip, name);
- return true;
-}
-
-bool CControl::GetTooltip(Math::Point pos, char* name)
-{
- if ( m_tooltip[0] == 0 ) return false;
- if ( (m_state & STATE_VISIBLE) == 0 ) return false;
- if ( (m_state & STATE_ENABLE) == 0 ) return false;
- if ( m_state & STATE_DEAD ) return false;
- if ( !Detect(pos) ) return false;
-
- strcpy(name, m_tooltip);
- return true;
-}
-
-
-// Management of the focus.
-
-void CControl::SetFocus(bool bFocus)
-{
- m_bFocus = bFocus;
-}
-
-bool CControl::RetFocus()
-{
- return m_bFocus;
-}
-
-
-// Returns the event associated with the control.
-
-EventMsg CControl::RetEventMsg()
-{
- return m_eventMsg;
-}
-
-
-// Management of an event.
-
-bool CControl::EventProcess(const Event &event)
-{
- if ( m_state & STATE_DEAD ) return true;
-
- if ( event.event == EVENT_FRAME && m_bGlint )
- {
- GlintFrame(event);
- }
-
- if ( event.event == EVENT_MOUSEMOVE )
- {
- m_glintMouse = event.pos;
-
- if ( Detect(event.pos) )
- {
- if ( (m_state & STATE_VISIBLE) &&
- (m_state & STATE_ENABLE ) )
- {
- m_engine->SetMouseType(D3DMOUSEHAND);
- }
- SetState(STATE_HILIGHT);
- }
- else
- {
- ClearState(STATE_HILIGHT);
- }
- }
-
- if ( event.event == EVENT_LBUTTONDOWN )
- {
- if ( Detect(event.pos) )
- {
- m_bCapture = true;
- SetState(STATE_PRESS);
- }
- }
-
- if ( event.event == EVENT_MOUSEMOVE && m_bCapture )
- {
- if ( Detect(event.pos) )
- {
- SetState(STATE_PRESS);
- }
- else
- {
- ClearState(STATE_PRESS);
- }
- }
-
- if ( event.event == EVENT_LBUTTONUP && m_bCapture )
- {
- m_bCapture = false;
- ClearState(STATE_PRESS);
- }
-
- return true;
-}
-
-
-// Removes the reflection.
-
-void CControl::GlintDelete()
-{
- m_bGlint = false;
-}
-
-// Creates a reflection for that button.
-
-void CControl::GlintCreate(Math::Point ref, bool bLeft, bool bUp)
-{
- float offset;
-
- offset = 8.0f/640.0f;
- if ( offset > m_dim.x/4.0f) offset = m_dim.x/4.0f;
-
- if ( bLeft )
- {
- m_glintCorner1.x = ref.x;
- m_glintCorner2.x = ref.x+offset;
- }
- else
- {
- m_glintCorner1.x = ref.x-offset;
- m_glintCorner2.x = ref.x;
- }
-
- offset = 8.0f/480.0f;
- if ( offset > m_dim.y/4.0f) offset = m_dim.y/4.0f;
-
- if ( bUp )
- {
- m_glintCorner1.y = ref.y-offset;
- m_glintCorner2.y = ref.y;
- }
- else
- {
- m_glintCorner1.y = ref.y;
- m_glintCorner2.y = ref.y+offset;
- }
-
- m_bGlint = true;
-}
-
-// Management of reflection.
-
-void CControl::GlintFrame(const Event &event)
-{
- Math::Vector pos, speed;
- Math::Point dim;
-
- if ( (m_state & STATE_GLINT ) == 0 ||
- (m_state & STATE_ENABLE ) == 0 ||
- (m_state & STATE_VISIBLE) == 0 ) return;
-
- if ( !m_main->RetGlint() ) return;
-
- m_glintProgress += event.rTime;
-
- if ( m_glintProgress >= 2.0f && Detect(m_glintMouse) )
- {
- pos.x = m_glintCorner1.x + (m_glintCorner2.x-m_glintCorner1.x)*Math::Rand();
- pos.y = m_glintCorner1.y + (m_glintCorner2.y-m_glintCorner1.y)*Math::Rand();
- pos.z = 0.0f;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = ((15.0f+Math::Rand()*15.0f)/640.0f);
- dim.y = dim.x/0.75f;
- m_particule->CreateParticule(pos, speed, dim, PARTICONTROL,
- 1.0f, 0.0f, 0.0f, SH_INTERFACE);
-
- m_glintProgress = 0.0f;
- }
-}
-
-
-// Draw button.
-
-void CControl::Draw()
-{
- Math::Point pos;
- float zoomExt, zoomInt;
- int icon;
-
- if ( (m_state & STATE_VISIBLE) == 0 ) return;
-
- m_engine->SetTexture("button1.tga");
- m_engine->SetState(D3DSTATENORMAL);
-
- zoomExt = 1.00f;
- zoomInt = 0.95f;
-
- if ( m_icon >= 128 )
- {
- zoomInt = 0.80f;
- }
-
- icon = 2;
- if ( m_state & STATE_CARD )
- {
- icon = 26;
- }
- if ( m_state & STATE_DEFAULT )
- {
- DrawPart(23, 1.3f, 0.0f);
-
- zoomExt *= 1.15f;
- zoomInt *= 1.15f;
- }
- if ( m_state & STATE_HILIGHT )
- {
- icon = 1;
- }
- if ( m_state & STATE_CHECK )
- {
- if ( m_state & STATE_CARD )
- {
- icon = 27;
- }
- else
- {
- icon = 0;
- }
- }
- if ( m_state & STATE_PRESS )
- {
- icon = 3;
- zoomInt *= 0.9f;
- }
- if ( (m_state & STATE_ENABLE) == 0 )
- {
- icon = 7;
- }
- if ( m_state & STATE_DEAD )
- {
- icon = 17;
- }
-
- if ( m_state & STATE_OKAY )
- {
- m_engine->SetTexture("button3.tga");
- icon = 3; // yellow with green point pressed
- }
-
- if ( m_name[0] == 0 ) // button without name?
- {
-//? DrawPart(icon, zoomExt, 0.0f);
- DrawPart(icon, zoomExt, 8.0f/256.0f);
-
- if ( m_state & STATE_DEAD ) return;
-
- icon = m_icon;
- if ( icon >= 192 )
- {
- icon -= 192;
-#if _POLISH
- m_engine->SetTexture("textp.tga");
-#else
- m_engine->SetTexture("text.tga");
-#endif
- m_engine->SetState(D3DSTATETTw);
- }
- else if ( icon >= 128 )
- {
- icon -= 128;
- m_engine->SetTexture("button3.tga");
- m_engine->SetState(D3DSTATETTw);
- }
- else if ( icon >= 64 )
- {
- icon -= 64;
- m_engine->SetTexture("button2.tga");
- m_engine->SetState(D3DSTATETTw);
- }
- else
- {
- m_engine->SetState(D3DSTATETTw);
- }
- if ( icon != -1 )
- {
- DrawPart(icon, zoomInt, 0.0f);
- }
- }
- else // button with the name?
- {
- DrawPart(icon, 1.0f, 8.0f/256.0f);
-
- if ( m_state & STATE_DEAD ) return;
-
- if ( m_justif < 0 )
- {
- pos.x = m_pos.x+m_dim.x-m_dim.y*0.5f;
- pos.y = m_pos.y+m_dim.y*0.5f;
- pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2;
- m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0);
- }
- else if ( m_justif > 0 )
- {
- pos.x = m_pos.x+m_dim.y*0.5f;
- pos.y = m_pos.y+m_dim.y*0.5f;
- pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f;
- m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0);
- }
- else
- {
- pos.x = m_pos.x+m_dim.x*0.5f;
- pos.y = m_pos.y+m_dim.y*0.5f;
- pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f;
- m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0);
- }
- }
-}
-
-// Draw the vertex array.
-
-void CControl::DrawPart(int icon, float zoom, float ex)
-{
- Math::Point p1, p2, c, uv1, uv2;
- float dp;
-
- p1.x = m_pos.x;
- p1.y = m_pos.y;
- p2.x = m_pos.x + m_dim.x;
- p2.y = m_pos.y + m_dim.y;
-
- if ( (m_state & STATE_CARD ) &&
- (m_state & STATE_CHECK) )
- {
- p2.y += (2.0f/480.0f); // a bit above
- }
-
- c.x = (p1.x+p2.x)/2.0f;
- c.y = (p1.y+p2.y)/2.0f; // center
-
- p1.x = (p1.x-c.x)*zoom + c.x;
- p1.y = (p1.y-c.y)*zoom + c.y;
- p2.x = (p2.x-c.x)*zoom + c.x;
- p2.y = (p2.y-c.y)*zoom + c.y;
-
- p2.x -= p1.x;
- p2.y -= p1.y;
-
- uv1.x = (32.0f/256.0f)*(icon%8);
- uv1.y = (32.0f/256.0f)*(icon/8); // uv texture
- uv2.x = (32.0f/256.0f)+uv1.x;
- uv2.y = (32.0f/256.0f)+uv1.y;
-
- dp = 0.5f/256.0f;
- uv1.x += dp;
- uv1.y += dp;
- uv2.x -= dp;
- uv2.y -= dp;
-
- DrawIcon(p1, p2, uv1, uv2, ex);
-}
-
-// Draws an icon made up of a rectangular (if x = 0)
-// or 3 pieces.
-
-void CControl::DrawIcon(Math::Point pos, Math::Point dim, Math::Point uv1, Math::Point uv2,
- float ex)
-{
- LPDIRECT3DDEVICE7 device;
- D3DVERTEX2 vertex[8]; // 6 triangles
- Math::Point p1, p2, p3, p4;
- Math::Vector n;
-
- device = m_engine->RetD3DDevice();
-
- p1.x = pos.x;
- p1.y = pos.y;
- p2.x = pos.x + dim.x;
- p2.y = pos.y + dim.y;
-
- n = Math::Vector(0.0f, 0.0f, -1.0f); // normal
-
- if ( ex == 0.0f ) // one piece?
- {
- vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y);
- vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y);
- vertex[2] = D3DVERTEX2(Math::Vector(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y);
- vertex[3] = D3DVERTEX2(Math::Vector(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y);
-
- device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL);
- m_engine->AddStatisticTriangle(2);
- }
- else // 3 pieces?
- {
- if ( dim.x >= dim.y )
- {
- p3.x = p1.x + ex*dim.y/(uv2.y-uv1.y);
- p4.x = p2.x - ex*dim.y/(uv2.y-uv1.y);
-
- vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p1.y, 0.0f), n, uv1.x, uv2.y);
- vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p2.y, 0.0f), n, uv1.x, uv1.y);
- vertex[2] = D3DVERTEX2(Math::Vector(p3.x, p1.y, 0.0f), n, uv1.x+ex,uv2.y);
- vertex[3] = D3DVERTEX2(Math::Vector(p3.x, p2.y, 0.0f), n, uv1.x+ex,uv1.y);
- vertex[4] = D3DVERTEX2(Math::Vector(p4.x, p1.y, 0.0f), n, uv2.x-ex,uv2.y);
- vertex[5] = D3DVERTEX2(Math::Vector(p4.x, p2.y, 0.0f), n, uv2.x-ex,uv1.y);
- vertex[6] = D3DVERTEX2(Math::Vector(p2.x, p1.y, 0.0f), n, uv2.x, uv2.y);
- vertex[7] = D3DVERTEX2(Math::Vector(p2.x, p2.y, 0.0f), n, uv2.x, uv1.y);
-
- device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL);
- m_engine->AddStatisticTriangle(6);
- }
- else
- {
- p3.y = p1.y + ex*dim.x/(uv2.x-uv1.x);
- p4.y = p2.y - ex*dim.x/(uv2.x-uv1.x);
-
- vertex[0] = D3DVERTEX2(Math::Vector(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y );
- vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y );
- vertex[2] = D3DVERTEX2(Math::Vector(p2.x, p3.y, 0.0f), n, uv2.x,uv2.y-ex);
- vertex[3] = D3DVERTEX2(Math::Vector(p1.x, p3.y, 0.0f), n, uv1.x,uv2.y-ex);
- vertex[4] = D3DVERTEX2(Math::Vector(p2.x, p4.y, 0.0f), n, uv2.x,uv1.y+ex);
- vertex[5] = D3DVERTEX2(Math::Vector(p1.x, p4.y, 0.0f), n, uv1.x,uv1.y+ex);
- vertex[6] = D3DVERTEX2(Math::Vector(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y );
- vertex[7] = D3DVERTEX2(Math::Vector(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y );
-
- device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL);
- m_engine->AddStatisticTriangle(6);
- }
- }
-}
-
-// Draws a rectangular icon made up of 9 pieces.
-
-void CControl::DrawIcon(Math::Point pos, Math::Point dim, Math::Point uv1, Math::Point uv2,
- Math::Point corner, float ex)
-{
- LPDIRECT3DDEVICE7 device;
- D3DVERTEX2 vertex[8]; // 6 triangles
- Math::Point p1, p2, p3, p4;
- Math::Vector n;
-
- device = m_engine->RetD3DDevice();
-
- p1.x = pos.x;
- p1.y = pos.y;
- p2.x = pos.x + dim.x;
- p2.y = pos.y + dim.y;
-
- n = Math::Vector(0.0f, 0.0f, -1.0f); // normal
-
- if ( corner.x > dim.x/2.0f ) corner.x = dim.x/2.0f;
- if ( corner.y > dim.y/2.0f ) corner.y = dim.y/2.0f;
-
- p1.x = pos.x;
- p1.y = pos.y;
- p2.x = pos.x + dim.x;
- p2.y = pos.y + dim.y;
- p3.x = p1.x + corner.x;
- p3.y = p1.y + corner.y;
- p4.x = p2.x - corner.x;
- p4.y = p2.y - corner.y;
-
- // Bottom horizontal band.
- vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p1.y, 0.0f), n, uv1.x, uv2.y );
- vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p3.y, 0.0f), n, uv1.x, uv2.y-ex);
- vertex[2] = D3DVERTEX2(Math::Vector(p3.x, p1.y, 0.0f), n, uv1.x+ex,uv2.y );
- vertex[3] = D3DVERTEX2(Math::Vector(p3.x, p3.y, 0.0f), n, uv1.x+ex,uv2.y-ex);
- vertex[4] = D3DVERTEX2(Math::Vector(p4.x, p1.y, 0.0f), n, uv2.x-ex,uv2.y );
- vertex[5] = D3DVERTEX2(Math::Vector(p4.x, p3.y, 0.0f), n, uv2.x-ex,uv2.y-ex);
- vertex[6] = D3DVERTEX2(Math::Vector(p2.x, p1.y, 0.0f), n, uv2.x, uv2.y );
- vertex[7] = D3DVERTEX2(Math::Vector(p2.x, p3.y, 0.0f), n, uv2.x, uv2.y-ex);
- device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL);
- m_engine->AddStatisticTriangle(6);
-
- // Central horizontal band.
- vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p3.y, 0.0f), n, uv1.x, uv2.y-ex);
- vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p4.y, 0.0f), n, uv1.x, uv1.y+ex);
- vertex[2] = D3DVERTEX2(Math::Vector(p3.x, p3.y, 0.0f), n, uv1.x+ex,uv2.y-ex);
- vertex[3] = D3DVERTEX2(Math::Vector(p3.x, p4.y, 0.0f), n, uv1.x+ex,uv1.y+ex);
- vertex[4] = D3DVERTEX2(Math::Vector(p4.x, p3.y, 0.0f), n, uv2.x-ex,uv2.y-ex);
- vertex[5] = D3DVERTEX2(Math::Vector(p4.x, p4.y, 0.0f), n, uv2.x-ex,uv1.y+ex);
- vertex[6] = D3DVERTEX2(Math::Vector(p2.x, p3.y, 0.0f), n, uv2.x, uv2.y-ex);
- vertex[7] = D3DVERTEX2(Math::Vector(p2.x, p4.y, 0.0f), n, uv2.x, uv1.y+ex);
- device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL);
- m_engine->AddStatisticTriangle(6);
-
- // Top horizontal band.
- vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p4.y, 0.0f), n, uv1.x, uv1.y+ex);
- vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p2.y, 0.0f), n, uv1.x, uv1.y );
- vertex[2] = D3DVERTEX2(Math::Vector(p3.x, p4.y, 0.0f), n, uv1.x+ex,uv1.y+ex);
- vertex[3] = D3DVERTEX2(Math::Vector(p3.x, p2.y, 0.0f), n, uv1.x+ex,uv1.y );
- vertex[4] = D3DVERTEX2(Math::Vector(p4.x, p4.y, 0.0f), n, uv2.x-ex,uv1.y+ex);
- vertex[5] = D3DVERTEX2(Math::Vector(p4.x, p2.y, 0.0f), n, uv2.x-ex,uv1.y );
- vertex[6] = D3DVERTEX2(Math::Vector(p2.x, p4.y, 0.0f), n, uv2.x, uv1.y+ex);
- vertex[7] = D3DVERTEX2(Math::Vector(p2.x, p2.y, 0.0f), n, uv2.x, uv1.y );
- device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL);
- m_engine->AddStatisticTriangle(6);
-}
-
-// Draw round the hatch of a button.
-
-void CControl::DrawWarning(Math::Point pos, Math::Point dim)
-{
- Math::Point uv1, uv2;
- float dp;
-
- dp = 0.5f/256.0f;
-
- m_engine->SetTexture("button2.tga");
- m_engine->SetState(D3DSTATENORMAL);
-
- uv1.x = 64.0f/256.0f;
- uv1.y = 208.0f/256.0f;
- uv2.x = 160.0f/256.0f;
- uv2.y = 224.0f/256.0f;
-
- uv1.x += dp;
- uv1.y += dp;
- uv2.x -= dp;
- uv2.y -= dp;
-
- if ( dim.x < dim.y*4.0f )
- {
- dim.y /= 2.0f;
- DrawIcon(pos, dim, uv1, uv2);
- pos.y += dim.y;
- DrawIcon(pos, dim, uv1, uv2);
- }
- else
- {
- dim.x /= 2.0f;
- dim.y /= 2.0f;
- DrawIcon(pos, dim, uv1, uv2);
- pos.x += dim.x;
- DrawIcon(pos, dim, uv1, uv2);
- pos.x -= dim.x;
- pos.y += dim.y;
- DrawIcon(pos, dim, uv1, uv2);
- pos.x += dim.x;
- DrawIcon(pos, dim, uv1, uv2);
- }
-}
-
-// Draw the shade under a button.
-
-void CControl::DrawShadow(Math::Point pos, Math::Point dim, float deep)
-{
- Math::Point uv1, uv2, corner;
- float dp;
-
- dp = 0.5f/256.0f;
-
- m_engine->SetTexture("button2.tga");
- m_engine->SetState(D3DSTATETTw);
-
- pos.x += deep*0.010f*0.75f;
- pos.y -= deep*0.015f;
- dim.x += deep*0.005f*0.75f;
- dim.y += deep*0.005f;
-
- uv1.x = 192.0f/256.0f;
- uv1.y = 32.0f/256.0f;
- uv2.x = 224.0f/256.0f;
- uv2.y = 64.0f/256.0f;
-
- uv1.x += dp;
- uv1.y += dp;
- uv2.x -= dp;
- uv2.y -= dp;
-
- corner.x = 10.0f/640.0f;
- corner.y = 10.0f/480.0f;
-
- DrawIcon(pos, dim, uv1, uv2, corner, 6.0f/256.0f);
-}
-
-
-// Detects whether a position is in the button.
-
-bool CControl::Detect(Math::Point pos)
-{
- return ( pos.x >= m_pos.x &&
- pos.x <= m_pos.x+m_dim.x &&
- pos.y >= m_pos.y &&
- pos.y <= m_pos.y+m_dim.y );
-}
-
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + + +#include <windows.h> +#include <stdio.h> +#include <d3d.h> + +#include "common/struct.h" +#include "old/d3dengine.h" +#include "common/language.h" +#include "common/restext.h" +#include "old/math3d.h" +#include "common/event.h" +#include "common/misc.h" +#include "object/robotmain.h" +#include "old/particule.h" +#include "common/misc.h" +#include "common/iman.h" +#include "old/text.h" +#include "old/sound.h" +#include "ui/control.h" + + + + +// Object's constructor. + +CControl::CControl(CInstanceManager* iMan) +{ + m_iMan = iMan; + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + m_eventMsg = EVENT_NULL; + m_state = STATE_ENABLE|STATE_VISIBLE|STATE_GLINT; + m_fontSize = SMALLFONT; + m_fontStretch = NORMSTRETCH; + m_fontType = FONT_COLOBOT; + m_justif = 0; + m_name[0] = 0; + m_tooltip[0] = 0; + m_bFocus = false; + m_bCapture = false; + + m_bGlint = false; + m_glintCorner1 = Math::Point(0.0f, 0.0f); + m_glintCorner2 = Math::Point(0.0f, 0.0f); + m_glintProgress = 999.0f; + m_glintMouse = Math::Point(0.0f, 0.0f); +} + +// Object's destructor. + +CControl::~CControl() +{ +} + + +// Creates a new button. +// pos: [0..1] + +bool CControl::Create(Math::Point pos, Math::Point dim, int icon, EventMsg eventMsg) +{ + char text[100]; + char* p; + + if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg(); + + m_pos = pos; + m_dim = dim; + m_icon = icon; + m_eventMsg = eventMsg; + + pos.x = m_pos.x; + pos.y = m_pos.y+m_dim.y; + GlintCreate(pos); + + GetResource(RES_EVENT, m_eventMsg, text); + p = strchr(text, '\\'); + if ( p == 0 ) + { + if ( icon != -1 ) + { + strcpy(m_tooltip, text); + } + } + else + { + strcpy(m_tooltip, p+1); // text after "\\" + } + + return true; +} + + +void CControl::SetPos(Math::Point pos) +{ + m_pos = pos; + + pos.x = m_pos.x; + pos.y = m_pos.y+m_dim.y; + GlintCreate(pos); +} + +Math::Point CControl::RetPos() +{ + return m_pos; +} + +void CControl::SetDim(Math::Point dim) +{ + Math::Point pos; + + m_dim = dim; + + pos.x = m_pos.x; + pos.y = m_pos.y+m_dim.y; + GlintCreate(pos); +} + +Math::Point CControl::RetDim() +{ + return m_dim; +} + + +// Modify an attribute of state. + +bool CControl::SetState(int state, bool bState) +{ + if ( bState ) m_state |= state; + else m_state &= ~state; + return true; +} + +// Sets an attribute of state. + +bool CControl::SetState(int state) +{ + m_state |= state; + return true; +} + +// Removes an attribute of state. + +bool CControl::ClearState(int state) +{ + m_state &= ~state; + return true; +} + +// Tests an attribute of state. + +bool CControl::TestState(int state) +{ + return (m_state & state) ? true:false; +} + +// Returns all attributes of state. + +int CControl::RetState() +{ + return m_state; +} + + +// Management icon. + +void CControl::SetIcon(int icon) +{ + m_icon = icon; +} + +int CControl::RetIcon() +{ + return m_icon; +} + + +// Management of the button name. + +void CControl::SetName(char* name, bool bTooltip) +{ + char* p; + + if ( bTooltip ) + { + p = strchr(name, '\\'); + if ( p == 0 ) + { + strncpy(m_name, name, 100); + m_name[100-1] = 0; + } + else + { + char buffer[100]; + + strncpy(m_tooltip, p+1, 100); // text after "\\" + m_tooltip[100-1] = 0; + + strncpy(buffer, name, 100); + buffer[100-1] = 0; + p = strchr(buffer, '\\'); + if ( p != 0 ) *p = 0; + strncpy(m_name, buffer, 100); + m_name[100-1] = 0; + } + } + else + { + strncpy(m_name, name, 100); + m_name[100-1] = 0; + } +} + +char* CControl::RetName() +{ + return m_name; +} + + +// Management of the mode of justification (-1,0,1). + +void CControl::SetJustif(int mode) +{ + m_justif = mode; +} + +int CControl::RetJustif() +{ + return m_justif; +} + + +// Management of the size of the font. + +void CControl::SetFontSize(float size) +{ + m_fontSize = size; +} + +float CControl::RetFontSize() +{ + return m_fontSize; +} + + +// Management of the stretch of font. + +void CControl::SetFontStretch(float stretch) +{ + m_fontStretch = stretch; +} + +float CControl::RetFontStretch() +{ + return m_fontStretch; +} + + +// Choice of the font. + +void CControl::SetFontType(FontType font) +{ + m_fontType = font; +} + +FontType CControl::RetFontType() +{ + return m_fontType; +} + + +// Specifies the tooltip. + +bool CControl::SetTooltip(char* name) +{ + strcpy(m_tooltip, name); + return true; +} + +bool CControl::GetTooltip(Math::Point pos, char* name) +{ + if ( m_tooltip[0] == 0 ) return false; + if ( (m_state & STATE_VISIBLE) == 0 ) return false; + if ( (m_state & STATE_ENABLE) == 0 ) return false; + if ( m_state & STATE_DEAD ) return false; + if ( !Detect(pos) ) return false; + + strcpy(name, m_tooltip); + return true; +} + + +// Management of the focus. + +void CControl::SetFocus(bool bFocus) +{ + m_bFocus = bFocus; +} + +bool CControl::RetFocus() +{ + return m_bFocus; +} + + +// Returns the event associated with the control. + +EventMsg CControl::RetEventMsg() +{ + return m_eventMsg; +} + + +// Management of an event. + +bool CControl::EventProcess(const Event &event) +{ + if ( m_state & STATE_DEAD ) return true; + + if ( event.event == EVENT_FRAME && m_bGlint ) + { + GlintFrame(event); + } + + if ( event.event == EVENT_MOUSEMOVE ) + { + m_glintMouse = event.pos; + + if ( Detect(event.pos) ) + { + if ( (m_state & STATE_VISIBLE) && + (m_state & STATE_ENABLE ) ) + { + m_engine->SetMouseType(D3DMOUSEHAND); + } + SetState(STATE_HILIGHT); + } + else + { + ClearState(STATE_HILIGHT); + } + } + + if ( event.event == EVENT_LBUTTONDOWN ) + { + if ( Detect(event.pos) ) + { + m_bCapture = true; + SetState(STATE_PRESS); + } + } + + if ( event.event == EVENT_MOUSEMOVE && m_bCapture ) + { + if ( Detect(event.pos) ) + { + SetState(STATE_PRESS); + } + else + { + ClearState(STATE_PRESS); + } + } + + if ( event.event == EVENT_LBUTTONUP && m_bCapture ) + { + m_bCapture = false; + ClearState(STATE_PRESS); + } + + return true; +} + + +// Removes the reflection. + +void CControl::GlintDelete() +{ + m_bGlint = false; +} + +// Creates a reflection for that button. + +void CControl::GlintCreate(Math::Point ref, bool bLeft, bool bUp) +{ + float offset; + + offset = 8.0f/640.0f; + if ( offset > m_dim.x/4.0f) offset = m_dim.x/4.0f; + + if ( bLeft ) + { + m_glintCorner1.x = ref.x; + m_glintCorner2.x = ref.x+offset; + } + else + { + m_glintCorner1.x = ref.x-offset; + m_glintCorner2.x = ref.x; + } + + offset = 8.0f/480.0f; + if ( offset > m_dim.y/4.0f) offset = m_dim.y/4.0f; + + if ( bUp ) + { + m_glintCorner1.y = ref.y-offset; + m_glintCorner2.y = ref.y; + } + else + { + m_glintCorner1.y = ref.y; + m_glintCorner2.y = ref.y+offset; + } + + m_bGlint = true; +} + +// Management of reflection. + +void CControl::GlintFrame(const Event &event) +{ + Math::Vector pos, speed; + Math::Point dim; + + if ( (m_state & STATE_GLINT ) == 0 || + (m_state & STATE_ENABLE ) == 0 || + (m_state & STATE_VISIBLE) == 0 ) return; + + if ( !m_main->RetGlint() ) return; + + m_glintProgress += event.rTime; + + if ( m_glintProgress >= 2.0f && Detect(m_glintMouse) ) + { + pos.x = m_glintCorner1.x + (m_glintCorner2.x-m_glintCorner1.x)*Math::Rand(); + pos.y = m_glintCorner1.y + (m_glintCorner2.y-m_glintCorner1.y)*Math::Rand(); + pos.z = 0.0f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = ((15.0f+Math::Rand()*15.0f)/640.0f); + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, PARTICONTROL, + 1.0f, 0.0f, 0.0f, SH_INTERFACE); + + m_glintProgress = 0.0f; + } +} + + +// Draw button. + +void CControl::Draw() +{ + Math::Point pos; + float zoomExt, zoomInt; + int icon; + + if ( (m_state & STATE_VISIBLE) == 0 ) return; + + m_engine->SetTexture("button1.tga"); + m_engine->SetState(D3DSTATENORMAL); + + zoomExt = 1.00f; + zoomInt = 0.95f; + + if ( m_icon >= 128 ) + { + zoomInt = 0.80f; + } + + icon = 2; + if ( m_state & STATE_CARD ) + { + icon = 26; + } + if ( m_state & STATE_DEFAULT ) + { + DrawPart(23, 1.3f, 0.0f); + + zoomExt *= 1.15f; + zoomInt *= 1.15f; + } + if ( m_state & STATE_HILIGHT ) + { + icon = 1; + } + if ( m_state & STATE_CHECK ) + { + if ( m_state & STATE_CARD ) + { + icon = 27; + } + else + { + icon = 0; + } + } + if ( m_state & STATE_PRESS ) + { + icon = 3; + zoomInt *= 0.9f; + } + if ( (m_state & STATE_ENABLE) == 0 ) + { + icon = 7; + } + if ( m_state & STATE_DEAD ) + { + icon = 17; + } + + if ( m_state & STATE_OKAY ) + { + m_engine->SetTexture("button3.tga"); + icon = 3; // yellow with green point pressed + } + + if ( m_name[0] == 0 ) // button without name? + { +//? DrawPart(icon, zoomExt, 0.0f); + DrawPart(icon, zoomExt, 8.0f/256.0f); + + if ( m_state & STATE_DEAD ) return; + + icon = m_icon; + if ( icon >= 192 ) + { + icon -= 192; +#if _POLISH + m_engine->SetTexture("textp.tga"); +#else + m_engine->SetTexture("text.tga"); +#endif + m_engine->SetState(D3DSTATETTw); + } + else if ( icon >= 128 ) + { + icon -= 128; + m_engine->SetTexture("button3.tga"); + m_engine->SetState(D3DSTATETTw); + } + else if ( icon >= 64 ) + { + icon -= 64; + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + } + else + { + m_engine->SetState(D3DSTATETTw); + } + if ( icon != -1 ) + { + DrawPart(icon, zoomInt, 0.0f); + } + } + else // button with the name? + { + DrawPart(icon, 1.0f, 8.0f/256.0f); + + if ( m_state & STATE_DEAD ) return; + + if ( m_justif < 0 ) + { + pos.x = m_pos.x+m_dim.x-m_dim.y*0.5f; + pos.y = m_pos.y+m_dim.y*0.5f; + pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2; + m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0); + } + else if ( m_justif > 0 ) + { + pos.x = m_pos.x+m_dim.y*0.5f; + pos.y = m_pos.y+m_dim.y*0.5f; + pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; + m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0); + } + else + { + pos.x = m_pos.x+m_dim.x*0.5f; + pos.y = m_pos.y+m_dim.y*0.5f; + pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f; + m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0); + } + } +} + +// Draw the vertex array. + +void CControl::DrawPart(int icon, float zoom, float ex) +{ + Math::Point p1, p2, c, uv1, uv2; + float dp; + + p1.x = m_pos.x; + p1.y = m_pos.y; + p2.x = m_pos.x + m_dim.x; + p2.y = m_pos.y + m_dim.y; + + if ( (m_state & STATE_CARD ) && + (m_state & STATE_CHECK) ) + { + p2.y += (2.0f/480.0f); // a bit above + } + + c.x = (p1.x+p2.x)/2.0f; + c.y = (p1.y+p2.y)/2.0f; // center + + p1.x = (p1.x-c.x)*zoom + c.x; + p1.y = (p1.y-c.y)*zoom + c.y; + p2.x = (p2.x-c.x)*zoom + c.x; + p2.y = (p2.y-c.y)*zoom + c.y; + + p2.x -= p1.x; + p2.y -= p1.y; + + uv1.x = (32.0f/256.0f)*(icon%8); + uv1.y = (32.0f/256.0f)*(icon/8); // uv texture + uv2.x = (32.0f/256.0f)+uv1.x; + uv2.y = (32.0f/256.0f)+uv1.y; + + dp = 0.5f/256.0f; + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + DrawIcon(p1, p2, uv1, uv2, ex); +} + +// Draws an icon made up of a rectangular (if x = 0) +// or 3 pieces. + +void CControl::DrawIcon(Math::Point pos, Math::Point dim, Math::Point uv1, Math::Point uv2, + float ex) +{ + LPDIRECT3DDEVICE7 device; + D3DVERTEX2 vertex[8]; // 6 triangles + Math::Point p1, p2, p3, p4; + Math::Vector n; + + device = m_engine->RetD3DDevice(); + + p1.x = pos.x; + p1.y = pos.y; + p2.x = pos.x + dim.x; + p2.y = pos.y + dim.y; + + n = Math::Vector(0.0f, 0.0f, -1.0f); // normal + + if ( ex == 0.0f ) // one piece? + { + vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y); + vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y); + vertex[2] = D3DVERTEX2(Math::Vector(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y); + vertex[3] = D3DVERTEX2(Math::Vector(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y); + + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); + } + else // 3 pieces? + { + if ( dim.x >= dim.y ) + { + p3.x = p1.x + ex*dim.y/(uv2.y-uv1.y); + p4.x = p2.x - ex*dim.y/(uv2.y-uv1.y); + + vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p1.y, 0.0f), n, uv1.x, uv2.y); + vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p2.y, 0.0f), n, uv1.x, uv1.y); + vertex[2] = D3DVERTEX2(Math::Vector(p3.x, p1.y, 0.0f), n, uv1.x+ex,uv2.y); + vertex[3] = D3DVERTEX2(Math::Vector(p3.x, p2.y, 0.0f), n, uv1.x+ex,uv1.y); + vertex[4] = D3DVERTEX2(Math::Vector(p4.x, p1.y, 0.0f), n, uv2.x-ex,uv2.y); + vertex[5] = D3DVERTEX2(Math::Vector(p4.x, p2.y, 0.0f), n, uv2.x-ex,uv1.y); + vertex[6] = D3DVERTEX2(Math::Vector(p2.x, p1.y, 0.0f), n, uv2.x, uv2.y); + vertex[7] = D3DVERTEX2(Math::Vector(p2.x, p2.y, 0.0f), n, uv2.x, uv1.y); + + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); + m_engine->AddStatisticTriangle(6); + } + else + { + p3.y = p1.y + ex*dim.x/(uv2.x-uv1.x); + p4.y = p2.y - ex*dim.x/(uv2.x-uv1.x); + + vertex[0] = D3DVERTEX2(Math::Vector(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y ); + vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y ); + vertex[2] = D3DVERTEX2(Math::Vector(p2.x, p3.y, 0.0f), n, uv2.x,uv2.y-ex); + vertex[3] = D3DVERTEX2(Math::Vector(p1.x, p3.y, 0.0f), n, uv1.x,uv2.y-ex); + vertex[4] = D3DVERTEX2(Math::Vector(p2.x, p4.y, 0.0f), n, uv2.x,uv1.y+ex); + vertex[5] = D3DVERTEX2(Math::Vector(p1.x, p4.y, 0.0f), n, uv1.x,uv1.y+ex); + vertex[6] = D3DVERTEX2(Math::Vector(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y ); + vertex[7] = D3DVERTEX2(Math::Vector(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y ); + + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); + m_engine->AddStatisticTriangle(6); + } + } +} + +// Draws a rectangular icon made up of 9 pieces. + +void CControl::DrawIcon(Math::Point pos, Math::Point dim, Math::Point uv1, Math::Point uv2, + Math::Point corner, float ex) +{ + LPDIRECT3DDEVICE7 device; + D3DVERTEX2 vertex[8]; // 6 triangles + Math::Point p1, p2, p3, p4; + Math::Vector n; + + device = m_engine->RetD3DDevice(); + + p1.x = pos.x; + p1.y = pos.y; + p2.x = pos.x + dim.x; + p2.y = pos.y + dim.y; + + n = Math::Vector(0.0f, 0.0f, -1.0f); // normal + + if ( corner.x > dim.x/2.0f ) corner.x = dim.x/2.0f; + if ( corner.y > dim.y/2.0f ) corner.y = dim.y/2.0f; + + p1.x = pos.x; + p1.y = pos.y; + p2.x = pos.x + dim.x; + p2.y = pos.y + dim.y; + p3.x = p1.x + corner.x; + p3.y = p1.y + corner.y; + p4.x = p2.x - corner.x; + p4.y = p2.y - corner.y; + + // Bottom horizontal band. + vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p1.y, 0.0f), n, uv1.x, uv2.y ); + vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p3.y, 0.0f), n, uv1.x, uv2.y-ex); + vertex[2] = D3DVERTEX2(Math::Vector(p3.x, p1.y, 0.0f), n, uv1.x+ex,uv2.y ); + vertex[3] = D3DVERTEX2(Math::Vector(p3.x, p3.y, 0.0f), n, uv1.x+ex,uv2.y-ex); + vertex[4] = D3DVERTEX2(Math::Vector(p4.x, p1.y, 0.0f), n, uv2.x-ex,uv2.y ); + vertex[5] = D3DVERTEX2(Math::Vector(p4.x, p3.y, 0.0f), n, uv2.x-ex,uv2.y-ex); + vertex[6] = D3DVERTEX2(Math::Vector(p2.x, p1.y, 0.0f), n, uv2.x, uv2.y ); + vertex[7] = D3DVERTEX2(Math::Vector(p2.x, p3.y, 0.0f), n, uv2.x, uv2.y-ex); + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); + m_engine->AddStatisticTriangle(6); + + // Central horizontal band. + vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p3.y, 0.0f), n, uv1.x, uv2.y-ex); + vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p4.y, 0.0f), n, uv1.x, uv1.y+ex); + vertex[2] = D3DVERTEX2(Math::Vector(p3.x, p3.y, 0.0f), n, uv1.x+ex,uv2.y-ex); + vertex[3] = D3DVERTEX2(Math::Vector(p3.x, p4.y, 0.0f), n, uv1.x+ex,uv1.y+ex); + vertex[4] = D3DVERTEX2(Math::Vector(p4.x, p3.y, 0.0f), n, uv2.x-ex,uv2.y-ex); + vertex[5] = D3DVERTEX2(Math::Vector(p4.x, p4.y, 0.0f), n, uv2.x-ex,uv1.y+ex); + vertex[6] = D3DVERTEX2(Math::Vector(p2.x, p3.y, 0.0f), n, uv2.x, uv2.y-ex); + vertex[7] = D3DVERTEX2(Math::Vector(p2.x, p4.y, 0.0f), n, uv2.x, uv1.y+ex); + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); + m_engine->AddStatisticTriangle(6); + + // Top horizontal band. + vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p4.y, 0.0f), n, uv1.x, uv1.y+ex); + vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p2.y, 0.0f), n, uv1.x, uv1.y ); + vertex[2] = D3DVERTEX2(Math::Vector(p3.x, p4.y, 0.0f), n, uv1.x+ex,uv1.y+ex); + vertex[3] = D3DVERTEX2(Math::Vector(p3.x, p2.y, 0.0f), n, uv1.x+ex,uv1.y ); + vertex[4] = D3DVERTEX2(Math::Vector(p4.x, p4.y, 0.0f), n, uv2.x-ex,uv1.y+ex); + vertex[5] = D3DVERTEX2(Math::Vector(p4.x, p2.y, 0.0f), n, uv2.x-ex,uv1.y ); + vertex[6] = D3DVERTEX2(Math::Vector(p2.x, p4.y, 0.0f), n, uv2.x, uv1.y+ex); + vertex[7] = D3DVERTEX2(Math::Vector(p2.x, p2.y, 0.0f), n, uv2.x, uv1.y ); + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 8, NULL); + m_engine->AddStatisticTriangle(6); +} + +// Draw round the hatch of a button. + +void CControl::DrawWarning(Math::Point pos, Math::Point dim) +{ + Math::Point uv1, uv2; + float dp; + + dp = 0.5f/256.0f; + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATENORMAL); + + uv1.x = 64.0f/256.0f; + uv1.y = 208.0f/256.0f; + uv2.x = 160.0f/256.0f; + uv2.y = 224.0f/256.0f; + + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + if ( dim.x < dim.y*4.0f ) + { + dim.y /= 2.0f; + DrawIcon(pos, dim, uv1, uv2); + pos.y += dim.y; + DrawIcon(pos, dim, uv1, uv2); + } + else + { + dim.x /= 2.0f; + dim.y /= 2.0f; + DrawIcon(pos, dim, uv1, uv2); + pos.x += dim.x; + DrawIcon(pos, dim, uv1, uv2); + pos.x -= dim.x; + pos.y += dim.y; + DrawIcon(pos, dim, uv1, uv2); + pos.x += dim.x; + DrawIcon(pos, dim, uv1, uv2); + } +} + +// Draw the shade under a button. + +void CControl::DrawShadow(Math::Point pos, Math::Point dim, float deep) +{ + Math::Point uv1, uv2, corner; + float dp; + + dp = 0.5f/256.0f; + + m_engine->SetTexture("button2.tga"); + m_engine->SetState(D3DSTATETTw); + + pos.x += deep*0.010f*0.75f; + pos.y -= deep*0.015f; + dim.x += deep*0.005f*0.75f; + dim.y += deep*0.005f; + + uv1.x = 192.0f/256.0f; + uv1.y = 32.0f/256.0f; + uv2.x = 224.0f/256.0f; + uv2.y = 64.0f/256.0f; + + uv1.x += dp; + uv1.y += dp; + uv2.x -= dp; + uv2.y -= dp; + + corner.x = 10.0f/640.0f; + corner.y = 10.0f/480.0f; + + DrawIcon(pos, dim, uv1, uv2, corner, 6.0f/256.0f); +} + + +// Detects whether a position is in the button. + +bool CControl::Detect(Math::Point pos) +{ + return ( pos.x >= m_pos.x && + pos.x <= m_pos.x+m_dim.x && + pos.y >= m_pos.y && + pos.y <= m_pos.y+m_dim.y ); +} + + |