summaryrefslogtreecommitdiffstats
path: root/src/ui/control.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/control.cpp')
-rw-r--r--src/ui/control.cpp1748
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 );
+}
+
+