summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorPiotr Dziwinski <piotrdz@gmail.com>2012-04-28 17:53:17 +0200
committerPiotr Dziwinski <piotrdz@gmail.com>2012-04-28 17:53:17 +0200
commit449cc186d5b8117d74ba22d6173497d00939f5f1 (patch)
tree39f38530dab2c9c8b33f5d8e42a81242bd48704b /src/ui
parenteeb69b34d2467e51ff84b3235f94506ce6bb9283 (diff)
downloadcolobot-449cc186d5b8117d74ba22d6173497d00939f5f1.tar.gz
colobot-449cc186d5b8117d74ba22d6173497d00939f5f1.tar.bz2
colobot-449cc186d5b8117d74ba22d6173497d00939f5f1.zip
Source files split into modules
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/README.txt3
-rw-r--r--src/ui/button.cpp248
-rw-r--r--src/ui/button.h58
-rw-r--r--src/ui/check.cpp168
-rw-r--r--src/ui/check.h48
-rw-r--r--src/ui/color.cpp226
-rw-r--r--src/ui/color.h58
-rw-r--r--src/ui/compass.cpp176
-rw-r--r--src/ui/compass.h52
-rw-r--r--src/ui/control.cpp876
-rw-r--r--src/ui/control.h137
-rw-r--r--src/ui/displayinfo.cpp1222
-rw-r--r--src/ui/displayinfo.h92
-rw-r--r--src/ui/displaytext.cpp615
-rw-r--r--src/ui/displaytext.h96
-rw-r--r--src/ui/edit.cpp3318
-rw-r--r--src/ui/edit.h255
-rw-r--r--src/ui/editvalue.cpp380
-rw-r--r--src/ui/editvalue.h85
-rw-r--r--src/ui/gauge.cpp159
-rw-r--r--src/ui/gauge.h52
-rw-r--r--src/ui/group.cpp646
-rw-r--r--src/ui/group.h48
-rw-r--r--src/ui/image.cpp157
-rw-r--r--src/ui/image.h52
-rw-r--r--src/ui/interface.cpp607
-rw-r--r--src/ui/interface.h93
-rw-r--r--src/ui/key.cpp290
-rw-r--r--src/ui/key.h54
-rw-r--r--src/ui/label.cpp95
-rw-r--r--src/ui/label.h48
-rw-r--r--src/ui/list.cpp870
-rw-r--r--src/ui/list.h117
-rw-r--r--src/ui/maindialog.cpp6937
-rw-r--r--src/ui/maindialog.h256
-rw-r--r--src/ui/mainmap.cpp404
-rw-r--r--src/ui/mainmap.h68
-rw-r--r--src/ui/mainshort.cpp376
-rw-r--r--src/ui/mainshort.h61
-rw-r--r--src/ui/map.cpp1342
-rw-r--r--src/ui/map.h141
-rw-r--r--src/ui/scroll.cpp471
-rw-r--r--src/ui/scroll.h84
-rw-r--r--src/ui/shortcut.cpp243
-rw-r--r--src/ui/shortcut.h50
-rw-r--r--src/ui/slider.cpp582
-rw-r--r--src/ui/slider.h84
-rw-r--r--src/ui/studio.cpp1667
-rw-r--r--src/ui/studio.h117
-rw-r--r--src/ui/target.cpp285
-rw-r--r--src/ui/target.h50
-rw-r--r--src/ui/window.cpp1622
-rw-r--r--src/ui/window.h148
53 files changed, 26389 insertions, 0 deletions
diff --git a/src/ui/README.txt b/src/ui/README.txt
new file mode 100644
index 0000000..4ffd8ec
--- /dev/null
+++ b/src/ui/README.txt
@@ -0,0 +1,3 @@
+src/ui
+
+Contains modules responsible for displaying the user interface controls (from game menus and HUD).
diff --git a/src/ui/button.cpp b/src/ui/button.cpp
new file mode 100644
index 0000000..27fea9b
--- /dev/null
+++ b/src/ui/button.cpp
@@ -0,0 +1,248 @@
+// * 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/.
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "language.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "restext.h"
+#include "button.h"
+
+
+
+#define DELAY1 0.4f
+#define DELAY2 0.1f
+
+
+
+// Object's constructor.
+
+CButton::CButton(CInstanceManager* iMan) : CControl(iMan)
+{
+ m_bCapture = FALSE;
+ m_bImmediat = FALSE;
+ m_bRepeat = FALSE;
+ m_repeat = 0.0f;
+}
+
+// Object's destructor.
+
+CButton::~CButton()
+{
+}
+
+
+// Creates a new button.
+
+BOOL CButton::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ CControl::Create(pos, dim, icon, eventMsg);
+
+ if ( icon == -1 )
+ {
+ char name[100];
+ char* p;
+
+ GetResource(RES_EVENT, eventMsg, name);
+ p = strchr(name, '\\');
+ if ( p != 0 ) *p = 0;
+ SetName(name);
+ }
+
+ return TRUE;
+}
+
+
+// Management of an event.
+
+BOOL CButton::EventProcess(const Event &event)
+{
+ if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE;
+ if ( m_state & STATE_DEAD ) return TRUE;
+
+ CControl::EventProcess(event);
+
+ if ( event.event == EVENT_FRAME )
+ {
+ if ( m_bRepeat && m_repeat != 0.0f )
+ {
+ m_repeat -= event.rTime;
+ if ( m_repeat <= 0.0f )
+ {
+ m_repeat = DELAY2;
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ return FALSE;
+ }
+ }
+ }
+
+ if ( event.event == EVENT_LBUTTONDOWN &&
+ (m_state & STATE_VISIBLE) &&
+ (m_state & STATE_ENABLE) )
+ {
+ if ( CControl::Detect(event.pos) )
+ {
+ m_bCapture = TRUE;
+ m_repeat = DELAY1;
+
+ if ( m_bImmediat || m_bRepeat )
+ {
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ }
+ return FALSE;
+ }
+ }
+
+ if ( event.event == EVENT_MOUSEMOVE && m_bCapture )
+ {
+ }
+
+ if ( event.event == EVENT_LBUTTONUP && m_bCapture )
+ {
+ if ( CControl::Detect(event.pos) )
+ {
+ if ( !m_bImmediat && !m_bRepeat )
+ {
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ }
+ }
+
+ m_bCapture = FALSE;
+ m_repeat = 0.0f;
+ }
+
+ return TRUE;
+}
+
+
+// Draw button.
+
+void CButton::Draw()
+{
+ FPOINT pos, dim, uv1, uv2;
+#if !_NEWLOOK
+ float dp;
+#endif
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ if ( m_state & STATE_WARNING ) // shading yellow-black?
+ {
+ pos.x = m_pos.x-( 8.0f/640.0f);
+ pos.y = m_pos.y-( 4.0f/480.0f);
+ dim.x = m_dim.x+(16.0f/640.0f);
+ dim.y = m_dim.y+( 8.0f/480.0f);
+ if ( m_state & STATE_SHADOW )
+ {
+ DrawShadow(pos, dim);
+ }
+ DrawWarning(pos, dim);
+ }
+
+ if ( m_state & STATE_SHADOW )
+ {
+ DrawShadow(m_pos, m_dim);
+ }
+
+ CControl::Draw();
+
+#if !_NEWLOOK
+ if ( m_name[0] != 0 && // button with the name?
+ (m_state & STATE_CARD ) == 0 &&
+ (m_state & STATE_SIMPLY) == 0 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+
+ dp = 0.5f/256.0f;
+
+ uv1.x = 128.0f/256.0f;
+ uv1.y = 96.0f/256.0f;
+ uv2.x = 136.0f/256.0f;
+ uv2.y = 128.0f/256.0f;
+
+ if ( (m_state & STATE_ENABLE) == 0 )
+ {
+ uv1.x += 16.0f/256.0f;
+ uv2.x += 16.0f/256.0f;
+ }
+
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+
+ pos.y = m_pos.y+5.0f/480.0f;
+ dim.y = m_dim.y-10.0f/480.0f;
+ pos.x = m_pos.x+5.0f/640.0f;
+ dim.x = 3.0f/640.0f;
+ DrawIcon(pos, dim, uv1, uv2, 0.0f);
+
+ uv1.x += 8.0f/256.0f;
+ uv2.x += 8.0f/256.0f;
+ pos.x = m_pos.x+m_dim.x-5.0f/640.0f-3.0f/640.0f;
+ DrawIcon(pos, dim, uv1, uv2, 0.0f);
+ }
+#endif
+}
+
+
+// Management of immediate mode, which sends the event "press"
+// before the mouse button is released.
+
+void CButton::SetImmediat(BOOL bImmediat)
+{
+ m_bImmediat = bImmediat;
+}
+
+BOOL CButton::RetImmediat()
+{
+ return m_bImmediat;
+}
+
+
+// Mode management "autorepeat", when the button
+// mouse is held down.
+
+void CButton::SetRepeat(BOOL bRepeat)
+{
+ m_bRepeat = bRepeat;
+}
+
+BOOL CButton::RetRepeat()
+{
+ return m_bRepeat;
+}
+
diff --git a/src/ui/button.h b/src/ui/button.h
new file mode 100644
index 0000000..2d30eea
--- /dev/null
+++ b/src/ui/button.h
@@ -0,0 +1,58 @@
+// * 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/.
+
+// button.h
+
+#ifndef _BUTTON_H_
+#define _BUTTON_H_
+
+
+#include "control.h"
+
+
+class CD3DEngine;
+
+
+
+class CButton : public CControl
+{
+public:
+ CButton(CInstanceManager* iMan);
+ virtual ~CButton();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ BOOL EventProcess(const Event &event);
+
+ void Draw();
+
+ void SetImmediat(BOOL bRepeat);
+ BOOL RetImmediat();
+
+ void SetRepeat(BOOL bRepeat);
+ BOOL RetRepeat();
+
+protected:
+
+protected:
+ BOOL m_bCapture;
+ BOOL m_bImmediat;
+ BOOL m_bRepeat;
+ float m_repeat;
+};
+
+
+#endif //_BUTTON_H_
diff --git a/src/ui/check.cpp b/src/ui/check.cpp
new file mode 100644
index 0000000..f485921
--- /dev/null
+++ b/src/ui/check.cpp
@@ -0,0 +1,168 @@
+// * 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/.
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "restext.h"
+#include "text.h"
+#include "check.h"
+
+
+
+
+// Object's constructor.
+
+CCheck::CCheck(CInstanceManager* iMan) : CControl(iMan)
+{
+}
+
+// Object's destructor.
+
+CCheck::~CCheck()
+{
+}
+
+
+// Creates a new button.
+
+BOOL CCheck::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ char name[100];
+ char* p;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ CControl::Create(pos, dim, icon, eventMsg);
+
+ GetResource(RES_EVENT, eventMsg, name);
+ p = strchr(name, '\\');
+ if ( p != 0 ) *p = 0;
+ SetName(name);
+
+ return TRUE;
+}
+
+
+// Management of an event.
+
+BOOL CCheck::EventProcess(const Event &event)
+{
+ if ( m_state & STATE_DEAD ) return TRUE;
+
+ CControl::EventProcess(event);
+
+ if ( event.event == EVENT_LBUTTONDOWN &&
+ (m_state & STATE_VISIBLE) &&
+ (m_state & STATE_ENABLE) )
+ {
+ if ( CControl::Detect(event.pos) )
+ {
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+// Draw button.
+
+void CCheck::Draw()
+{
+ FPOINT iDim, pos;
+ float zoomExt, zoomInt;
+ int icon;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ iDim = m_dim;
+ m_dim.x = m_dim.y*0.75f; // square
+
+ if ( m_state & STATE_SHADOW )
+ {
+ DrawShadow(m_pos, m_dim);
+ }
+
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+
+ zoomExt = 1.00f;
+ zoomInt = 0.95f;
+
+ icon = 2;
+ 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_PRESS )
+ {
+ icon = 3;
+ zoomInt *= 0.9f;
+ }
+ if ( (m_state & STATE_ENABLE) == 0 )
+ {
+ icon = 7;
+ }
+ if ( m_state & STATE_DEAD )
+ {
+ icon = 17;
+ }
+ DrawPart(icon, zoomExt, 0.0f); // draws the button
+
+ if ( (m_state & STATE_DEAD) == 0 )
+ {
+ m_engine->SetState(D3DSTATETTw);
+
+ if ( m_state & STATE_CHECK )
+ {
+ icon = 16; // seen
+ DrawPart(icon, zoomInt, 0.0f); // draw the icon
+ }
+ }
+
+ m_dim = iDim;
+
+ if ( m_state & STATE_DEAD ) return;
+
+ // Draw the name.
+ pos.x = m_pos.x+m_dim.y/0.9f;
+ pos.y = m_pos.y+m_dim.y*0.50f;
+ pos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f;
+ m_engine->RetText()->DrawText(m_name, pos, m_dim.x, 1, m_fontSize, m_fontStretch, m_fontType, 0);
+}
+
+
diff --git a/src/ui/check.h b/src/ui/check.h
new file mode 100644
index 0000000..118b6cb
--- /dev/null
+++ b/src/ui/check.h
@@ -0,0 +1,48 @@
+// * 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/.
+
+// check.h
+
+#ifndef _CHECK_H_
+#define _CHECK_H_
+
+
+#include "control.h"
+
+
+class CD3DEngine;
+
+
+
+class CCheck : public CControl
+{
+public:
+ CCheck(CInstanceManager* iMan);
+ virtual ~CCheck();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ BOOL EventProcess(const Event &event);
+
+ void Draw();
+
+protected:
+
+protected:
+};
+
+
+#endif //_CHECK_H_
diff --git a/src/ui/color.cpp b/src/ui/color.cpp
new file mode 100644
index 0000000..cf69b0d
--- /dev/null
+++ b/src/ui/color.cpp
@@ -0,0 +1,226 @@
+// * 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/.
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "language.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "restext.h"
+#include "color.h"
+
+
+
+#define DELAY1 0.4f
+#define DELAY2 0.1f
+
+
+
+// Object's constructor.
+
+CColor::CColor(CInstanceManager* iMan) : CControl(iMan)
+{
+ m_bRepeat = FALSE;
+ m_repeat = 0.0f;
+
+ m_color.r = 0.0f;
+ m_color.g = 0.0f;
+ m_color.b = 0.0f;
+ m_color.a = 0.0f;
+}
+
+// Object's destructor.
+
+CColor::~CColor()
+{
+}
+
+
+// Creates a new button.
+
+BOOL CColor::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ CControl::Create(pos, dim, icon, eventMsg);
+
+ if ( icon == -1 )
+ {
+ char name[100];
+ char* p;
+
+ GetResource(RES_EVENT, eventMsg, name);
+ p = strchr(name, '\\');
+ if ( p != 0 ) *p = 0;
+ SetName(name);
+ }
+
+ return TRUE;
+}
+
+
+// Management of an event.
+
+BOOL CColor::EventProcess(const Event &event)
+{
+ if ( m_state & STATE_DEAD ) return TRUE;
+
+ CControl::EventProcess(event);
+
+ if ( event.event == EVENT_FRAME && m_bRepeat )
+ {
+ if ( m_repeat != 0.0f )
+ {
+ m_repeat -= event.rTime;
+ if ( m_repeat <= 0.0f )
+ {
+ m_repeat = DELAY2;
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ return FALSE;
+ }
+ }
+ }
+
+ if ( event.event == EVENT_LBUTTONDOWN &&
+ (m_state & STATE_VISIBLE) &&
+ (m_state & STATE_ENABLE) )
+ {
+ if ( CControl::Detect(event.pos) )
+ {
+ m_repeat = DELAY1;
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ return FALSE;
+ }
+ }
+
+ if ( event.event == EVENT_LBUTTONUP )
+ {
+ m_repeat = 0.0f;
+ }
+
+ return TRUE;
+}
+
+
+// Dessine le bouton.
+
+void CColor::Draw()
+{
+ LPDIRECT3DDEVICE7 device;
+ D3DLVERTEX vertex[4]; // 2 triangles
+ D3DCOLOR color;
+ FPOINT p1, p2;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ if ( m_state & STATE_SHADOW )
+ {
+ DrawShadow(m_pos, m_dim);
+ }
+
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ CControl::Draw();
+
+#if _TEEN
+ color = ::RetColor(m_color);
+
+ m_engine->SetTexture("xxx.tga"); // no texture
+ m_engine->SetState(D3DSTATENORMAL);
+
+ device = m_engine->RetD3DDevice();
+
+ p1.x = m_pos.x+(4.0f/640.0f);
+ p1.y = m_pos.y+(4.0f/480.0f);
+ p2.x = m_pos.x+m_dim.x-(4.0f/640.0f);
+ p2.y = m_pos.y+m_dim.y-(4.0f/480.0f);
+ vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), 0x00000000,0x00000000, 0.0f,0.0f);
+ vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), 0x00000000,0x00000000, 0.0f,0.0f);
+ vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), 0x00000000,0x00000000, 0.0f,0.0f);
+ vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), 0x00000000,0x00000000, 0.0f,0.0f);
+ device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL);
+
+ p1.x = m_pos.x+(5.0f/640.0f);
+ p1.y = m_pos.y+(5.0f/480.0f);
+ p2.x = m_pos.x+m_dim.x-(5.0f/640.0f);
+ p2.y = m_pos.y+m_dim.y-(5.0f/480.0f);
+ vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), color,0x00000000, 0.0f,0.0f);
+ vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), color,0x00000000, 0.0f,0.0f);
+ vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), color,0x00000000, 0.0f,0.0f);
+ vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), color,0x00000000, 0.0f,0.0f);
+ device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL);
+
+ m_engine->AddStatisticTriangle(4);
+#else
+ p1.x = m_pos.x+(3.0f/640.0f);
+ p1.y = m_pos.y+(3.0f/480.0f);
+ p2.x = m_pos.x+m_dim.x-(3.0f/640.0f);
+ p2.y = m_pos.y+m_dim.y-(3.0f/480.0f);
+
+ color = ::RetColor(m_color);
+
+ m_engine->SetTexture("xxx.tga"); // no texture
+ m_engine->SetState(D3DSTATENORMAL);
+
+ vertex[0] = D3DLVERTEX(D3DVECTOR(p1.x, p1.y, 0.0f), color,0x00000000, 0.0f,0.0f);
+ vertex[1] = D3DLVERTEX(D3DVECTOR(p1.x, p2.y, 0.0f), color,0x00000000, 0.0f,0.0f);
+ vertex[2] = D3DLVERTEX(D3DVECTOR(p2.x, p1.y, 0.0f), color,0x00000000, 0.0f,0.0f);
+ vertex[3] = D3DLVERTEX(D3DVECTOR(p2.x, p2.y, 0.0f), color,0x00000000, 0.0f,0.0f);
+
+ device = m_engine->RetD3DDevice();
+ device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_LVERTEX, vertex, 4, NULL);
+ m_engine->AddStatisticTriangle(2);
+#endif
+}
+
+
+void CColor::SetRepeat(BOOL bRepeat)
+{
+ m_bRepeat = bRepeat;
+}
+
+BOOL CColor::RetRepeat()
+{
+ return m_bRepeat;
+}
+
+
+void CColor::SetColor(D3DCOLORVALUE color)
+{
+ m_color = color;
+}
+
+D3DCOLORVALUE CColor::RetColor()
+{
+ return m_color;
+}
+
+
diff --git a/src/ui/color.h b/src/ui/color.h
new file mode 100644
index 0000000..fec01c4
--- /dev/null
+++ b/src/ui/color.h
@@ -0,0 +1,58 @@
+// * 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/.
+
+// color.h
+
+#ifndef _COLOR_H_
+#define _COLOR_H_
+
+
+#include "control.h"
+#include "d3dengine.h"
+
+
+class CD3DEngine;
+
+
+
+class CColor : public CControl
+{
+public:
+ CColor(CInstanceManager* iMan);
+ virtual ~CColor();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ BOOL EventProcess(const Event &event);
+
+ void Draw();
+
+ void SetRepeat(BOOL bRepeat);
+ BOOL RetRepeat();
+
+ void SetColor(D3DCOLORVALUE color);
+ D3DCOLORVALUE RetColor();
+
+protected:
+
+protected:
+ BOOL m_bRepeat;
+ float m_repeat;
+ D3DCOLORVALUE m_color;
+};
+
+
+#endif //_COLOR_H_
diff --git a/src/ui/compass.cpp b/src/ui/compass.cpp
new file mode 100644
index 0000000..92804c2
--- /dev/null
+++ b/src/ui/compass.cpp
@@ -0,0 +1,176 @@
+// * 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/.
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "compass.h"
+
+
+
+
+// Object's constructor.
+
+CCompass::CCompass(CInstanceManager* iMan) : CControl(iMan)
+{
+ m_dir = 0.0f;
+}
+
+// Object's destructor.
+
+CCompass::~CCompass()
+{
+}
+
+
+// Creates a new button.
+
+BOOL CCompass::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ CControl::Create(pos, dim, icon, eventMsg);
+ return TRUE;
+}
+
+
+// Management of an event.
+
+BOOL CCompass::EventProcess(const Event &event)
+{
+ CControl::EventProcess(event);
+
+ if ( event.event == EVENT_LBUTTONDOWN )
+ {
+ if ( CControl::Detect(event.pos) )
+ {
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+// Draw button.
+
+void CCompass::Draw()
+{
+ LPDIRECT3DDEVICE7 device;
+ D3DVERTEX2 vertex[4]; // 2 triangles
+ FPOINT p1, p2, p3, c, uv1, uv2;
+ D3DVECTOR n;
+ float dp;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ device = m_engine->RetD3DDevice();
+
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+
+ 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;
+
+ c.x = (p1.x+p2.x)/2.0f;
+ c.y = (p1.y+p2.y)/2.0f; // center
+
+ uv1.x = 64.0f/256.0f;
+ uv1.y = 32.0f/256.0f;
+ uv2.x = 96.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+
+ dp = 0.5f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+
+ n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal
+
+ vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y);
+ vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y);
+ vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y);
+ vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y);
+
+ device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL);
+ m_engine->AddStatisticTriangle(2);
+
+ if ( m_state & STATE_ENABLE )
+ {
+ p1.x = c.x;
+ p1.y = c.y+m_dim.x*0.40f;
+ p1 = RotatePoint(c, m_dir, p1);
+ p1.x = c.x+(p1.x-c.x)*(m_dim.x/m_dim.y);
+
+ p2.x = c.x+m_dim.x*0.20f;
+ p2.y = c.y-m_dim.x*0.40f;
+ p2 = RotatePoint(c, m_dir, p2);
+ p2.x = c.x+(p2.x-c.x)*(m_dim.x/m_dim.y);
+
+ p3.x = c.x-m_dim.x*0.20f;
+ p3.y = c.y-m_dim.x*0.40f;
+ p3 = RotatePoint(c, m_dir, p3);
+ p3.x = c.x+(p3.x-c.x)*(m_dim.x/m_dim.y);
+
+ uv1.x = 96.0f/256.0f;
+ uv1.y = 32.0f/256.0f;
+ uv2.x = 104.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+
+ vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv1.y);
+ vertex[1] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv1.x,uv2.y);
+ vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv2.x,uv2.y);
+
+ device->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_VERTEX2, vertex, 3, NULL);
+ m_engine->AddStatisticTriangle(1);
+ }
+}
+
+
+// Management directions of the compass.
+
+void CCompass::SetDirection(float dir)
+{
+ m_dir = dir;
+}
+
+float CCompass::RetDirection()
+{
+ return m_dir;
+}
+
+
diff --git a/src/ui/compass.h b/src/ui/compass.h
new file mode 100644
index 0000000..1eed3d6
--- /dev/null
+++ b/src/ui/compass.h
@@ -0,0 +1,52 @@
+// * 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/.
+
+// compass.h
+
+#ifndef _COMPASS_H_
+#define _COMPASS_H_
+
+
+#include "control.h"
+
+
+class CD3DEngine;
+
+
+
+class CCompass : public CControl
+{
+public:
+ CCompass(CInstanceManager* iMan);
+ virtual ~CCompass();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ BOOL EventProcess(const Event &event);
+
+ void Draw();
+
+ void SetDirection(float dir);
+ float RetDirection();
+
+protected:
+
+protected:
+ float m_dir;
+};
+
+
+#endif //_COMPASS_H_
diff --git a/src/ui/control.cpp b/src/ui/control.cpp
new file mode 100644
index 0000000..6ba5cef
--- /dev/null
+++ b/src/ui/control.cpp
@@ -0,0 +1,876 @@
+// * 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/.
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "language.h"
+#include "restext.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "robotmain.h"
+#include "particule.h"
+#include "misc.h"
+#include "iman.h"
+#include "text.h"
+#include "sound.h"
+#include "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 = FPOINT(0.0f, 0.0f);
+ m_glintCorner2 = FPOINT(0.0f, 0.0f);
+ m_glintProgress = 999.0f;
+ m_glintMouse = FPOINT(0.0f, 0.0f);
+}
+
+// Object's destructor.
+
+CControl::~CControl()
+{
+}
+
+
+// Creates a new button.
+// pos: [0..1]
+
+BOOL CControl::Create(FPOINT pos, FPOINT 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(FPOINT pos)
+{
+ m_pos = pos;
+
+ pos.x = m_pos.x;
+ pos.y = m_pos.y+m_dim.y;
+ GlintCreate(pos);
+}
+
+FPOINT CControl::RetPos()
+{
+ return m_pos;
+}
+
+void CControl::SetDim(FPOINT dim)
+{
+ FPOINT pos;
+
+ m_dim = dim;
+
+ pos.x = m_pos.x;
+ pos.y = m_pos.y+m_dim.y;
+ GlintCreate(pos);
+}
+
+FPOINT 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(FPOINT 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(FPOINT 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)
+{
+ D3DVECTOR pos, speed;
+ FPOINT 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)*Rand();
+ pos.y = m_glintCorner1.y + (m_glintCorner2.y-m_glintCorner1.y)*Rand();
+ pos.z = 0.0f;
+ speed = D3DVECTOR(0.0f, 0.0f, 0.0f);
+ dim.x = ((15.0f+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()
+{
+ FPOINT 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)
+{
+ FPOINT 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(FPOINT pos, FPOINT dim, FPOINT uv1, FPOINT uv2,
+ float ex)
+{
+ LPDIRECT3DDEVICE7 device;
+ D3DVERTEX2 vertex[8]; // 6 triangles
+ FPOINT p1, p2, p3, p4;
+ D3DVECTOR 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 = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal
+
+ if ( ex == 0.0f ) // one piece?
+ {
+ vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y);
+ vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y);
+ vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y);
+ vertex[3] = D3DVERTEX2(D3DVECTOR(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(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x, uv2.y);
+ vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x, uv1.y);
+ vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p1.y, 0.0f), n, uv1.x+ex,uv2.y);
+ vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p2.y, 0.0f), n, uv1.x+ex,uv1.y);
+ vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p1.y, 0.0f), n, uv2.x-ex,uv2.y);
+ vertex[5] = D3DVERTEX2(D3DVECTOR(p4.x, p2.y, 0.0f), n, uv2.x-ex,uv1.y);
+ vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x, uv2.y);
+ vertex[7] = D3DVERTEX2(D3DVECTOR(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(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y );
+ vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y );
+ vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p3.y, 0.0f), n, uv2.x,uv2.y-ex);
+ vertex[3] = D3DVERTEX2(D3DVECTOR(p1.x, p3.y, 0.0f), n, uv1.x,uv2.y-ex);
+ vertex[4] = D3DVERTEX2(D3DVECTOR(p2.x, p4.y, 0.0f), n, uv2.x,uv1.y+ex);
+ vertex[5] = D3DVERTEX2(D3DVECTOR(p1.x, p4.y, 0.0f), n, uv1.x,uv1.y+ex);
+ vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y );
+ vertex[7] = D3DVERTEX2(D3DVECTOR(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(FPOINT pos, FPOINT dim, FPOINT uv1, FPOINT uv2,
+ FPOINT corner, float ex)
+{
+ LPDIRECT3DDEVICE7 device;
+ D3DVERTEX2 vertex[8]; // 6 triangles
+ FPOINT p1, p2, p3, p4;
+ D3DVECTOR 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 = D3DVECTOR(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(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x, uv2.y );
+ vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p3.y, 0.0f), n, uv1.x, uv2.y-ex);
+ vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p1.y, 0.0f), n, uv1.x+ex,uv2.y );
+ vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv1.x+ex,uv2.y-ex);
+ vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p1.y, 0.0f), n, uv2.x-ex,uv2.y );
+ vertex[5] = D3DVERTEX2(D3DVECTOR(p4.x, p3.y, 0.0f), n, uv2.x-ex,uv2.y-ex);
+ vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x, uv2.y );
+ vertex[7] = D3DVERTEX2(D3DVECTOR(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(D3DVECTOR(p1.x, p3.y, 0.0f), n, uv1.x, uv2.y-ex);
+ vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p4.y, 0.0f), n, uv1.x, uv1.y+ex);
+ vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv1.x+ex,uv2.y-ex);
+ vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p4.y, 0.0f), n, uv1.x+ex,uv1.y+ex);
+ vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p3.y, 0.0f), n, uv2.x-ex,uv2.y-ex);
+ vertex[5] = D3DVERTEX2(D3DVECTOR(p4.x, p4.y, 0.0f), n, uv2.x-ex,uv1.y+ex);
+ vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p3.y, 0.0f), n, uv2.x, uv2.y-ex);
+ vertex[7] = D3DVERTEX2(D3DVECTOR(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(D3DVECTOR(p1.x, p4.y, 0.0f), n, uv1.x, uv1.y+ex);
+ vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x, uv1.y );
+ vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p4.y, 0.0f), n, uv1.x+ex,uv1.y+ex);
+ vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p2.y, 0.0f), n, uv1.x+ex,uv1.y );
+ vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p4.y, 0.0f), n, uv2.x-ex,uv1.y+ex);
+ vertex[5] = D3DVERTEX2(D3DVECTOR(p4.x, p2.y, 0.0f), n, uv2.x-ex,uv1.y );
+ vertex[6] = D3DVERTEX2(D3DVECTOR(p2.x, p4.y, 0.0f), n, uv2.x, uv1.y+ex);
+ vertex[7] = D3DVERTEX2(D3DVECTOR(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(FPOINT pos, FPOINT dim)
+{
+ FPOINT 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(FPOINT pos, FPOINT dim, float deep)
+{
+ FPOINT 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(FPOINT 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 );
+}
+
+
diff --git a/src/ui/control.h b/src/ui/control.h
new file mode 100644
index 0000000..619cef2
--- /dev/null
+++ b/src/ui/control.h
@@ -0,0 +1,137 @@
+// * 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/.
+
+// control.h
+
+#ifndef _CONTROL_H_
+#define _CONTROL_H_
+
+
+#include "text.h"
+#include "struct.h"
+#include "event.h"
+
+
+class CInstanceManager;
+class CEvent;
+class CD3DEngine;
+class CRobotMain;
+class CParticule;
+class CSound;
+
+
+#define STATE_ENABLE (1<<0) // active
+#define STATE_CHECK (1<<1) // pressed
+#define STATE_HILIGHT (1<<2) // overflown by mouse
+#define STATE_PRESS (1<<3) // pressed by mouse
+#define STATE_VISIBLE (1<<4) // visible
+#define STATE_DEAD (1<<5) // inaccessible (x)
+#define STATE_DEFAULT (1<<6) // actuated by RETURN
+#define STATE_OKAY (1<<7) // green point at the bottom right
+#define STATE_SHADOW (1<<8) // shadow
+#define STATE_GLINT (1<<9) // dynamic reflection
+#define STATE_CARD (1<<10) // tab
+#define STATE_EXTEND (1<<11) // extended mode
+#define STATE_SIMPLY (1<<12) // undecorated
+#define STATE_FRAME (1<<13) // framework highlighting
+#define STATE_WARNING (1<<14) // framework hatched yellow / black
+#define STATE_VALUE (1<<15) // displays the value
+#define STATE_RUN (1<<16) // running program
+
+
+
+class CControl
+{
+public:
+ CControl(CInstanceManager* iMan);
+ virtual ~CControl();
+
+ virtual BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ virtual BOOL EventProcess(const Event &event);
+
+ virtual void SetPos(FPOINT pos);
+ virtual FPOINT RetPos();
+ virtual void SetDim(FPOINT dim);
+ virtual FPOINT RetDim();
+ virtual BOOL SetState(int state, BOOL bState);
+ virtual BOOL SetState(int state);
+ virtual BOOL ClearState(int state);
+ virtual BOOL TestState(int state);
+ virtual int RetState();
+ virtual void SetIcon(int icon);
+ virtual int RetIcon();
+ virtual void SetName(char* name, BOOL bTooltip=TRUE);
+ virtual char* RetName();
+ virtual void SetJustif(int mode);
+ virtual int RetJustif();
+ virtual void SetFontSize(float size);
+ virtual float RetFontSize();
+ virtual void SetFontStretch(float stretch);
+ virtual float RetFontStretch();
+ virtual void SetFontType(FontType font);
+ virtual FontType RetFontType();
+ virtual BOOL SetTooltip(char* name);
+ virtual BOOL GetTooltip(FPOINT pos, char* name);
+ virtual void SetFocus(BOOL bFocus);
+ virtual BOOL RetFocus();
+
+ virtual EventMsg RetEventMsg();
+
+ virtual void Draw();
+
+protected:
+ void GlintDelete();
+ void GlintCreate(FPOINT ref, BOOL bLeft=TRUE, BOOL bUp=TRUE);
+ void GlintFrame(const Event &event);
+ void DrawPart(int icon, float zoom, float ex);
+ void DrawIcon(FPOINT pos, FPOINT dim, FPOINT uv1, FPOINT uv2, float ex=0.0f);
+ void DrawIcon(FPOINT pos, FPOINT dim, FPOINT uv1, FPOINT uv2, FPOINT corner, float ex);
+ void DrawWarning(FPOINT pos, FPOINT dim);
+ void DrawShadow(FPOINT pos, FPOINT dim, float deep=1.0f);
+ virtual BOOL Detect(FPOINT pos);
+
+protected:
+ CInstanceManager* m_iMan;
+ CD3DEngine* m_engine;
+ CEvent* m_event;
+ CRobotMain* m_main;
+ CParticule* m_particule;
+ CSound* m_sound;
+
+ FPOINT m_pos; // corner upper / left
+ FPOINT m_dim; // dimensions
+ int m_icon;
+ EventMsg m_eventMsg; // message to send when clicking
+ int m_state; // states (STATE_ *)
+ float m_fontSize; // size of the button name
+ float m_fontStretch; // stretch of the font
+ FontType m_fontType; // type of font
+ int m_justif; // type of justification (-1,0,1)
+ char m_name[100]; // name of the button
+ char m_tooltip[100]; // name of tooltip
+ BOOL m_bFocus;
+ BOOL m_bCapture;
+
+ BOOL m_bGlint;
+ FPOINT m_glintCorner1;
+ FPOINT m_glintCorner2;
+ float m_glintProgress;
+ FPOINT m_glintMouse;
+};
+
+
+#endif //_CONTROL_H_
diff --git a/src/ui/displayinfo.cpp b/src/ui/displayinfo.cpp
new file mode 100644
index 0000000..473a805
--- /dev/null
+++ b/src/ui/displayinfo.cpp
@@ -0,0 +1,1222 @@
+// * 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/.
+
+// displayinfo.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "d3dmath.h"
+#include "language.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "restext.h"
+#include "math3d.h"
+#include "robotmain.h"
+#include "camera.h"
+#include "object.h"
+#include "motion.h"
+#include "motiontoto.h"
+#include "interface.h"
+#include "button.h"
+#include "slider.h"
+#include "edit.h"
+#include "group.h"
+#include "window.h"
+#include "particule.h"
+#include "light.h"
+#include "text.h"
+#include "cbottoken.h"
+#include "displayinfo.h"
+
+
+
+
+// Object's constructor.
+
+CDisplayInfo::CDisplayInfo(CInstanceManager* iMan)
+{
+ m_iMan = iMan;
+ m_iMan->AddInstance(CLASS_STUDIO, this);
+
+ m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE);
+ m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT);
+ m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE);
+ m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN);
+ m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA);
+ m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE);
+ m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT);
+
+ m_bInfoMaximized = TRUE;
+ m_bInfoMinimized = FALSE;
+
+ m_infoFinalPos = m_infoActualPos = m_infoNormalPos = FPOINT(0.00f, 0.00f);
+ m_infoFinalDim = m_infoActualPos = m_infoNormalDim = FPOINT(1.00f, 1.00f);
+
+ m_lightSuppl = -1;
+ m_toto = 0;
+}
+
+// Object's destructor.
+
+CDisplayInfo::~CDisplayInfo()
+{
+ m_iMan->DeleteInstance(CLASS_STUDIO, this);
+}
+
+
+// Management of an event.
+
+BOOL CDisplayInfo::EventProcess(const Event &event)
+{
+ CWindow* pw;
+ CEdit* edit;
+ CSlider* slider;
+ CMotionToto* toto;
+
+ if ( event.event == EVENT_FRAME )
+ {
+ EventFrame(event);
+ HyperUpdate();
+ }
+
+ if ( event.event == EVENT_MOUSEMOVE )
+ {
+ if ( m_toto != 0 )
+ {
+ toto = (CMotionToto*)m_toto->RetMotion();
+ if ( toto != 0 )
+ {
+ toto->SetMousePos(event.pos);
+ }
+ }
+ }
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw != 0 )
+ {
+ if ( event.event == pw->RetEventMsgClose() )
+ {
+ Event newEvent = event;
+ newEvent.event = EVENT_OBJECT_INFOOK;
+ m_event->AddEvent(newEvent);
+ }
+
+ if ( event.event == EVENT_SATCOM_HUSTON )
+ {
+ ChangeIndexButton(SATCOM_HUSTON);
+ }
+ if ( event.event == EVENT_SATCOM_SAT )
+ {
+ ChangeIndexButton(SATCOM_SAT);
+ }
+//? if ( event.event == EVENT_SATCOM_OBJECT )
+//? {
+//? ChangeIndexButton(SATCOM_OBJECT);
+//? }
+ if ( event.event == EVENT_SATCOM_LOADING )
+ {
+ ChangeIndexButton(SATCOM_LOADING);
+ }
+ if ( event.event == EVENT_SATCOM_PROG )
+ {
+ ChangeIndexButton(SATCOM_PROG);
+ }
+ if ( event.event == EVENT_SATCOM_SOLUCE )
+ {
+ ChangeIndexButton(SATCOM_SOLUCE);
+ }
+
+ if ( event.event == EVENT_HYPER_HOME ||
+ event.event == EVENT_HYPER_PREV ||
+ event.event == EVENT_HYPER_NEXT )
+ {
+ edit = (CEdit*)pw->SearchControl(EVENT_EDIT1);
+ if ( edit != 0 )
+ {
+ edit->HyperGo(event.event);
+ HyperUpdate();
+ }
+ }
+
+ if ( event.event == EVENT_HYPER_SIZE1 ) // size 1?
+ {
+ m_main->SetFontSize(9.0f);
+ slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE);
+ if ( slider != 0 ) slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f);
+ ViewDisplayInfo();
+ }
+ if ( event.event == EVENT_HYPER_SIZE2 ) // size 2?
+ {
+ m_main->SetFontSize(10.0f);
+ slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE);
+ if ( slider != 0 ) slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f);
+ ViewDisplayInfo();
+ }
+ if ( event.event == EVENT_HYPER_SIZE3 ) // size 3?
+ {
+ m_main->SetFontSize(12.0f);
+ slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE);
+ if ( slider != 0 ) slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f);
+ ViewDisplayInfo();
+ }
+ if ( event.event == EVENT_HYPER_SIZE4 ) // size 4?
+ {
+ m_main->SetFontSize(15.0f);
+ slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE);
+ if ( slider != 0 ) slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f);
+ ViewDisplayInfo();
+ }
+
+ if ( event.event == EVENT_STUDIO_SIZE ) // size?
+ {
+ slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE);
+ if ( slider == 0 ) return FALSE;
+ m_main->SetFontSize(9.0f+slider->RetVisibleValue()*6.0f);
+ ViewDisplayInfo();
+ }
+
+ if ( event.event == EVENT_HYPER_COPY ) // copy ?
+ {
+ edit = (CEdit*)pw->SearchControl(EVENT_EDIT1);
+ if ( edit != 0 )
+ {
+ edit->Copy();
+ }
+ }
+
+ if ( event.event == EVENT_LBUTTONDOWN ||
+ event.event == EVENT_LBUTTONUP )
+ {
+ UpdateCopyButton();
+ }
+
+ if ( event.event == EVENT_WINDOW4 ) // window moved?
+ {
+ m_infoNormalPos = m_infoActualPos = m_infoFinalPos = pw->RetPos();
+ m_infoNormalDim = m_infoActualDim = m_infoFinalDim = pw->RetDim();
+ AdjustDisplayInfo(m_infoActualPos, m_infoActualDim);
+ }
+ if ( event.event == pw->RetEventMsgReduce() )
+ {
+ if ( m_bInfoMinimized )
+ {
+ m_infoFinalPos = m_infoNormalPos;
+ m_infoFinalDim = m_infoNormalDim;
+ m_bInfoMinimized = FALSE;
+ m_bInfoMaximized = FALSE;
+ }
+ else
+ {
+ m_infoFinalPos.x = 0.00f;
+ m_infoFinalPos.y = -0.34f;
+ m_infoFinalDim.x = 1.00f;
+ m_infoFinalDim.y = 0.40f;
+ m_bInfoMinimized = TRUE;
+ m_bInfoMaximized = FALSE;
+ }
+//? m_main->SetEditFull(m_bInfoMaximized);
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw != 0 )
+ {
+ pw->SetMaximized(m_bInfoMaximized);
+ pw->SetMinimized(m_bInfoMinimized);
+ }
+ }
+ if ( event.event == pw->RetEventMsgFull() )
+ {
+ if ( m_bInfoMaximized )
+ {
+ m_infoFinalPos = m_infoNormalPos;
+ m_infoFinalDim = m_infoNormalDim;
+ m_bInfoMinimized = FALSE;
+ m_bInfoMaximized = FALSE;
+ }
+ else
+ {
+ m_infoFinalPos.x = 0.00f;
+ m_infoFinalPos.y = 0.00f;
+ m_infoFinalDim.x = 1.00f;
+ m_infoFinalDim.y = 1.00f;
+ m_bInfoMinimized = FALSE;
+ m_bInfoMaximized = TRUE;
+ }
+//? m_main->SetEditFull(m_bInfoMaximized);
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw != 0 )
+ {
+ pw->SetMaximized(m_bInfoMaximized);
+ pw->SetMinimized(m_bInfoMinimized);
+ }
+ }
+ }
+ return TRUE;
+}
+
+
+// The brain is changing by time.
+
+BOOL CDisplayInfo::EventFrame(const Event &event)
+{
+ float time;
+
+ if ( m_infoFinalPos.x != m_infoActualPos.x ||
+ m_infoFinalPos.y != m_infoActualPos.y ||
+ m_infoFinalDim.x != m_infoActualDim.x ||
+ m_infoFinalDim.y != m_infoActualDim.y )
+ {
+ time = event.rTime*20.0f;
+ m_infoActualPos.x += (m_infoFinalPos.x-m_infoActualPos.x)*time;
+ m_infoActualPos.y += (m_infoFinalPos.y-m_infoActualPos.y)*time;
+ m_infoActualDim.x += (m_infoFinalDim.x-m_infoActualDim.x)*time;
+ m_infoActualDim.y += (m_infoFinalDim.y-m_infoActualDim.y)*time;
+ AdjustDisplayInfo(m_infoActualPos, m_infoActualDim);
+ }
+
+ return TRUE;
+}
+
+
+// Updates the buttons for hyperlinks.
+
+void CDisplayInfo::HyperUpdate()
+{
+ CWindow* pw;
+ CEdit* edit;
+ CButton* button;
+ BOOL bEnable;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw == 0 ) return;
+ edit = (CEdit*)pw->SearchControl(EVENT_EDIT1);
+ if ( edit == 0 ) return;
+
+ button = (CButton*)pw->SearchControl(EVENT_HYPER_HOME);
+ if ( button != 0 )
+ {
+ bEnable = edit->HyperTest(EVENT_HYPER_HOME);
+ button->SetState(STATE_ENABLE, bEnable);
+ }
+
+ button = (CButton*)pw->SearchControl(EVENT_HYPER_PREV);
+ if ( button != 0 )
+ {
+ bEnable = edit->HyperTest(EVENT_HYPER_PREV);
+ button->SetState(STATE_ENABLE, bEnable);
+ }
+
+ button = (CButton*)pw->SearchControl(EVENT_HYPER_NEXT);
+ if ( button != 0 )
+ {
+ bEnable = edit->HyperTest(EVENT_HYPER_NEXT);
+ button->SetState(STATE_ENABLE, bEnable);
+ }
+}
+
+
+// Beginning of the display of information.
+
+void CDisplayInfo::StartDisplayInfo(char *filename, int index, BOOL bSoluce)
+{
+ D3DLIGHT7 light;
+ FPOINT pos, dim;
+ CWindow* pw;
+ CEdit* edit;
+ CButton* button;
+ CSlider* slider;
+ CMotionToto* toto;
+
+ m_index = index;
+ m_bSoluce = bSoluce;
+
+//? CreateObjectsFile();
+
+ m_bEditLock = m_main->RetEditLock();
+ if ( m_bEditLock ) // edition running program?
+ {
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw != 0 )
+ {
+ pw->ClearState(STATE_ENABLE); // CStudio inactive
+ }
+ }
+
+ m_main->SetEditLock(TRUE, FALSE);
+ m_main->SetEditFull(FALSE);
+ m_bInitPause = m_engine->RetPause();
+ m_engine->SetPause(TRUE);
+ m_infoCamera = m_camera->RetType();
+ m_camera->SetType(CAMERA_INFO);
+
+ pos = m_infoActualPos = m_infoFinalPos;
+ dim = m_infoActualDim = m_infoFinalDim;
+ pw = m_interface->CreateWindows(pos, dim, 4, EVENT_WINDOW4);
+ if ( pw == 0 ) return;
+//? pw->SetClosable(TRUE);
+//? GetResource(RES_TEXT, RT_DISINFO_TITLE, res);
+//? pw->SetName(res);
+//? pw->SetMinDim(FPOINT(0.56f, 0.40f));
+//? pw->SetMaximized(m_bInfoMaximized);
+//? pw->SetMinimized(m_bInfoMinimized);
+//? m_main->SetEditFull(m_bInfoMaximized);
+
+ edit = pw->CreateEdit(pos, dim, 0, EVENT_EDIT1);
+ if ( edit == 0 ) return;
+ edit->SetState(STATE_SHADOW);
+ edit->SetMultiFont(TRUE);
+ edit->SetMaxChar(10000);
+ edit->SetFontType(FONT_COLOBOT);
+ edit->SetSoluceMode(bSoluce);
+ edit->ReadText(filename);
+ edit->HyperHome(filename);
+ edit->SetEditCap(FALSE); // just to see!
+ edit->SetHiliteCap(FALSE);
+ edit->SetFocus(TRUE);
+
+ ViewDisplayInfo();
+
+ button = pw->CreateButton(pos, dim, 128+57, EVENT_SATCOM_HUSTON);
+ button->SetState(STATE_SHADOW);
+#if _TEEN
+#if !_ENGLISH
+ button = pw->CreateButton(pos, dim, 46, EVENT_SATCOM_SAT);
+#endif
+#else
+ button = pw->CreateButton(pos, dim, 128+58, EVENT_SATCOM_SAT);
+#endif
+ button->SetState(STATE_SHADOW);
+//? button = pw->CreateButton(pos, dim, 128+59, EVENT_SATCOM_OBJECT);
+//? button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 53, EVENT_SATCOM_LOADING);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 128+60, EVENT_SATCOM_PROG);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 20, EVENT_SATCOM_SOLUCE);
+ button->SetState(STATE_SHADOW);
+
+ pw->CreateGroup(pos, dim, 18, EVENT_LABEL1); // arrow >
+ pw->CreateGroup(pos, dim, 19, EVENT_LABEL2); // symbol SatCom
+
+ button = pw->CreateButton(pos, dim, 55, EVENT_HYPER_PREV);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 48, EVENT_HYPER_NEXT);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 30, EVENT_HYPER_HOME);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 82, EVENT_HYPER_SIZE1);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 83, EVENT_HYPER_SIZE2);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 90, EVENT_HYPER_SIZE3);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 91, EVENT_HYPER_SIZE4);
+ button->SetState(STATE_SHADOW);
+ slider = pw->CreateSlider(pos, dim, 0, EVENT_STUDIO_SIZE);
+ slider->SetState(STATE_SHADOW);
+ slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f);
+ button = pw->CreateButton(pos, dim, 61, EVENT_HYPER_COPY);
+ button->SetState(STATE_SHADOW);
+ HyperUpdate();
+
+ button = pw->CreateButton(pos, dim, -1, EVENT_OBJECT_INFOOK);
+ button->SetState(STATE_SHADOW);
+ button->SetState(STATE_SIMPLY);
+ button->SetState(STATE_DEFAULT);
+ pw->CreateGroup(pos, dim, 21, EVENT_LABEL3); // symbol stand-by
+
+ AdjustDisplayInfo(m_infoActualPos, m_infoActualDim);
+ UpdateIndexButton();
+
+ m_engine->SetDrawWorld(FALSE); // doesn't draw anything in the interface
+ m_engine->SetDrawFront(TRUE); // toto draws on the interface
+ m_particule->SetFrameUpdate(SH_WORLD, FALSE); // particles break into world
+
+ m_toto = SearchToto();
+ if ( m_toto != 0 )
+ {
+ m_toto->SetDrawFront(TRUE);
+
+ toto = (CMotionToto*)m_toto->RetMotion();
+ if ( toto != 0 )
+ {
+ toto->StartDisplayInfo();
+ }
+ }
+
+ ZeroMemory(&light, sizeof(light));
+ light.dltType = D3DLIGHT_DIRECTIONAL;
+ light.dcvDiffuse.r = 1.0f;
+ light.dcvDiffuse.g = 1.0f;
+ light.dcvDiffuse.b = 1.0f;
+ light.dvDirection = D3DVECTOR(1.0f, 0.0f, 1.0f);
+ m_lightSuppl = m_light->CreateLight();
+ m_light->SetLight(m_lightSuppl, light);
+ m_light->SetLightExcluType(m_lightSuppl, TYPETERRAIN);
+}
+
+// Repositions all controls editing.
+
+void CDisplayInfo::AdjustDisplayInfo(FPOINT wpos, FPOINT wdim)
+{
+ CWindow* pw;
+ CEdit* edit;
+ CButton* button;
+ CSlider* slider;
+ CGroup* group;
+ FPOINT pos, dim;
+
+ wpos.x = 50.0f/640.0f;
+ wpos.y = 30.0f/480.0f;
+ wdim.x = 540.0f/640.0f;
+ wdim.y = 420.0f/480.0f;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw != 0 )
+ {
+ pw->SetPos(wpos);
+ pw->SetDim(wdim);
+ wdim = pw->RetDim();
+ }
+
+ pos.x = (50.0f+10.0f)/640.0f;
+ pos.y = (30.0f+10.0f+24.0f+10.0f+324.0f-48.0f)/480.0f;
+ dim.x = 48.0f/640.0f;
+ dim.y = 48.0f/480.0f;
+ button = (CButton*)pw->SearchControl(EVENT_SATCOM_HUSTON);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.y -= (48.0f+4.0f)/480.0f;
+ button = (CButton*)pw->SearchControl(EVENT_SATCOM_SAT);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+//? pos.y -= (48.0f+4.0f)/480.0f;
+//? button = (CButton*)pw->SearchControl(EVENT_SATCOM_OBJECT);
+//? if ( button != 0 )
+//? {
+//? button->SetPos(pos);
+//? button->SetDim(dim);
+//? }
+ pos.y -= (48.0f+4.0f)/480.0f;
+ button = (CButton*)pw->SearchControl(EVENT_SATCOM_LOADING);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.y -= (48.0f+4.0f)/480.0f;
+ button = (CButton*)pw->SearchControl(EVENT_SATCOM_PROG);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.y -= (48.0f+4.0f)/480.0f;
+ button = (CButton*)pw->SearchControl(EVENT_SATCOM_SOLUCE);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+
+ pos.x = (50.0f+10.0f+5.0f)/640.0f;
+ pos.y = (30.0f+10.0f+4.0f)/480.0f;
+ dim.x = (48.0f-10.0f)/640.0f;
+ dim.y = 24.0f/480.0f;
+ button = (CButton*)pw->SearchControl(EVENT_OBJECT_INFOOK);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+
+ pos.x = (50.0f+10.0f+48.0f+10.0f)/640.0f;
+ pos.y = (30.0f+10.0f)/480.0f;
+ dim.x = 462.0f/640.0f;
+ dim.y = 358.0f/480.0f;
+ edit = (CEdit*)pw->SearchControl(EVENT_EDIT1);
+ if ( edit != 0 )
+ {
+ edit->SetPos(pos);
+ edit->SetDim(dim);
+ }
+
+ pos.x = (50.0f+10.0f+48.0f+10.0f)/640.0f;
+ pos.y = (30.0f+10.0f+358.0f+10.0f)/480.0f;
+ dim.x = 32.0f/640.0f;
+ dim.y = 32.0f/480.0f;
+ button = (CButton*)pw->SearchControl(EVENT_HYPER_PREV);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x += 35.0f/640.0f;
+ button = (CButton*)pw->SearchControl(EVENT_HYPER_NEXT);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x += 35.0f/640.0f;
+ button = (CButton*)pw->SearchControl(EVENT_HYPER_HOME);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+
+ pos.x += 50.0f/640.0f;
+ button = (CButton*)pw->SearchControl(EVENT_HYPER_SIZE1);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x += 35.0f/640.0f;
+ button = (CButton*)pw->SearchControl(EVENT_HYPER_SIZE2);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x += 35.0f/640.0f;
+ button = (CButton*)pw->SearchControl(EVENT_HYPER_SIZE3);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x += 35.0f/640.0f;
+ button = (CButton*)pw->SearchControl(EVENT_HYPER_SIZE4);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x += 35.0f/640.0f;
+ dim.x = 18.0f/640.0f;
+ slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE);
+ if ( slider != 0 )
+ {
+ slider->SetPos(pos);
+ slider->SetDim(dim);
+ }
+ pos.x += 50.0f/640.0f;
+ dim.x = 32.0f/640.0f;
+ button = (CButton*)pw->SearchControl(EVENT_HYPER_COPY);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+
+ pos.x = (50.0f+10.0f)/640.0f;
+ pos.y = (30.0f+10.0f+24.0f+10.0f+324.0f+6.0f)/480.0f;
+ dim.x = 48.0f/640.0f;
+ dim.y = 40.0f/480.0f;
+ group = (CGroup*)pw->SearchControl(EVENT_LABEL2); // symbol SatCom
+ if ( group != 0 )
+ {
+ group->SetPos(pos);
+ group->SetDim(dim);
+ }
+
+ pos.x = (50.0f+10.0f+14.0f)/640.0f;
+ pos.y = (30.0f+10.0f+6.0f)/480.0f;
+ dim.x = 20.0f/640.0f;
+ dim.y = 20.0f/480.0f;
+ group = (CGroup*)pw->SearchControl(EVENT_LABEL3); // symbol stand-by
+ if ( group != 0 )
+ {
+ group->SetPos(pos);
+ group->SetDim(dim);
+ }
+}
+
+// Change the index button.
+
+void CDisplayInfo::ChangeIndexButton(int index)
+{
+ CWindow* pw;
+ CEdit* edit;
+ char* filename;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw == 0 ) return;
+
+ if ( m_index != -1 )
+ {
+ m_main->SetDisplayInfoPosition(m_index, RetPosition());
+ }
+ m_index = index;
+
+ edit = (CEdit*)pw->SearchControl(EVENT_EDIT1);
+ if ( edit != 0 )
+ {
+ filename = m_main->RetDisplayInfoName(m_index);
+ edit->ReadText(filename);
+ edit->HyperHome(filename);
+ SetPosition(m_main->RetDisplayInfoPosition(m_index));
+ }
+
+ UpdateIndexButton();
+}
+
+// Adapts the index buttons.
+
+void CDisplayInfo::UpdateIndexButton()
+{
+ CWindow* pw;
+ CButton* button;
+ CGroup* group;
+ CEdit* edit;
+ FPOINT pos, dim;
+ char* filename;
+ char* loading;
+
+ static int table[SATCOM_MAX] =
+ {
+ 0, // SATCOM_HUSTON
+ 1, // SATCOM_SAT
+ -1, // SATCOM_OBJECT
+ 2, // SATCOM_LOADING
+ 3, // SATCOM_PROG
+ 4, // SATCOM_SOLUCE
+ };
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw == 0 ) return;
+
+ button = (CButton*)pw->SearchControl(EVENT_SATCOM_HUSTON);
+ if ( button != 0 )
+ {
+ button->SetState(STATE_CHECK, m_index==SATCOM_HUSTON);
+ filename = m_main->RetDisplayInfoName(SATCOM_HUSTON);
+ button->SetState(STATE_VISIBLE, filename[0]!=0);
+ }
+
+ button = (CButton*)pw->SearchControl(EVENT_SATCOM_SAT);
+ if ( button != 0 )
+ {
+ button->SetState(STATE_CHECK, m_index==SATCOM_SAT);
+ filename = m_main->RetDisplayInfoName(SATCOM_SAT);
+ button->SetState(STATE_VISIBLE, filename[0]!=0);
+ }
+
+//? button = (CButton*)pw->SearchControl(EVENT_SATCOM_OBJECT);
+//? if ( button != 0 )
+//? {
+//? button->SetState(STATE_CHECK, m_index==SATCOM_OBJECT);
+//? filename = m_main->RetDisplayInfoName(SATCOM_OBJECT);
+//? button->SetState(STATE_VISIBLE, filename[0]!=0);
+//? }
+
+ loading = 0;
+ button = (CButton*)pw->SearchControl(EVENT_SATCOM_LOADING);
+ if ( button != 0 )
+ {
+ button->SetState(STATE_CHECK, m_index==SATCOM_LOADING);
+ loading = m_main->RetDisplayInfoName(SATCOM_LOADING);
+ button->SetState(STATE_VISIBLE, loading[0]!=0);
+ }
+
+ button = (CButton*)pw->SearchControl(EVENT_SATCOM_PROG);
+ if ( button != 0 )
+ {
+ button->SetState(STATE_CHECK, m_index==SATCOM_PROG);
+ filename = m_main->RetDisplayInfoName(SATCOM_PROG);
+ button->SetState(STATE_VISIBLE, filename[0]!=0 && (m_index==SATCOM_LOADING||m_index==SATCOM_PROG||(loading!=0&&loading[0]==0)));
+ }
+
+ button = (CButton*)pw->SearchControl(EVENT_SATCOM_SOLUCE);
+ if ( button != 0 )
+ {
+ button->SetState(STATE_CHECK, m_index==SATCOM_SOLUCE);
+ filename = m_main->RetDisplayInfoName(SATCOM_SOLUCE);
+ button->SetState(STATE_VISIBLE, filename[0]!=0 && m_bSoluce);
+ }
+
+ group = (CGroup*)pw->SearchControl(EVENT_LABEL1);
+ if ( group != 0 )
+ {
+ if ( m_index == -1 )
+ {
+ group->ClearState(STATE_VISIBLE);
+ }
+ else
+ {
+ group->SetState(STATE_VISIBLE);
+
+ pos.x = (50.0f+10.0f+48.0f-3.0f)/640.0f;
+ pos.y = (30.0f+10.0f+24.0f+10.0f+324.0f-48.0f-1.0f)/480.0f;
+ pos.y -= (48.0f+4.0f)/480.0f*table[m_index];
+ dim.x = 15.0f/640.0f;
+ dim.y = 48.0f/480.0f;
+ group->SetPos(pos);
+ group->SetDim(dim);
+ }
+ }
+
+#if 0
+ button = (CButton*)pw->SearchControl(EVENT_HYPER_COPY);
+ if ( button != 0 )
+ {
+ button->SetState(STATE_VISIBLE, m_index==SATCOM_LOADING);
+ }
+#endif
+
+ edit = (CEdit*)pw->SearchControl(EVENT_EDIT1);
+ if ( edit != 0 )
+ {
+//? edit->SetHiliteCap(m_index==SATCOM_LOADING);
+ edit->SetHiliteCap(TRUE);
+ }
+
+ UpdateCopyButton();
+}
+
+// Adjusts the copy button.
+
+void CDisplayInfo::UpdateCopyButton()
+{
+ CWindow* pw;
+ CButton* button;
+ CEdit* edit;
+ int c1, c2;
+
+//? if ( m_index != SATCOM_LOADING ) return;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw == 0 ) return;
+
+ button = (CButton*)pw->SearchControl(EVENT_HYPER_COPY);
+ if ( button == 0 ) return;
+
+ edit = (CEdit*)pw->SearchControl(EVENT_EDIT1);
+ if ( edit == 0 ) return;
+
+ edit->GetCursor(c1, c2);
+ button->SetState(STATE_ENABLE, c1!=c2);
+
+}
+
+// End of the display of information.
+
+void CDisplayInfo::StopDisplayInfo()
+{
+ CWindow* pw;
+ CMotionToto* toto;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw == 0 ) return;
+
+ m_interface->DeleteControl(EVENT_WINDOW4);
+
+ if ( m_bEditLock ) // editing running program?
+ {
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw != 0 )
+ {
+ pw->SetState(STATE_ENABLE); // CStudio operating
+ }
+ }
+ else
+ {
+ if ( !m_bInitPause ) m_engine->SetPause(FALSE);
+ m_main->SetEditLock(FALSE, FALSE);
+ }
+ m_camera->SetType(m_infoCamera);
+
+ m_engine->SetDrawWorld(TRUE); // draws all on the interface
+ m_engine->SetDrawFront(FALSE); // draws nothing on the interface
+ m_particule->SetFrameUpdate(SH_WORLD, TRUE);
+ m_particule->FlushParticule(SH_FRONT);
+ m_particule->FlushParticule(SH_INTERFACE);
+
+ if ( m_toto != 0 )
+ {
+ toto = (CMotionToto*)m_toto->RetMotion();
+ if ( toto != 0 )
+ {
+ toto->StopDisplayInfo();
+ }
+ }
+
+ m_light->DeleteLight(m_lightSuppl);
+ m_lightSuppl = -1;
+}
+
+
+// Specifies the position.
+
+void CDisplayInfo::SetPosition(int pos)
+{
+ CWindow* pw;
+ CEdit* edit;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw == 0 ) return;
+
+ edit = (CEdit*)pw->SearchControl(EVENT_EDIT1);
+ if ( edit == 0 ) return;
+
+ edit->SetFirstLine(pos);
+}
+
+// Returns the position.
+
+int CDisplayInfo::RetPosition()
+{
+ CWindow* pw;
+ CEdit* edit;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw == 0 ) return 0;
+
+ edit = (CEdit*)pw->SearchControl(EVENT_EDIT1);
+ if ( edit == 0 ) return 0;
+
+ return edit->RetFirstLine();
+}
+
+
+
+// Changing the size of the display of information.
+
+void CDisplayInfo::ViewDisplayInfo()
+{
+ CWindow* pw;
+ CEdit* edit;
+ POINT dim;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw == 0 ) return;
+
+ edit = (CEdit*)pw->SearchControl(EVENT_EDIT1);
+ if ( edit == 0 ) return;
+
+ dim = m_engine->RetDim();
+ edit->SetFontSize(m_main->RetFontSize()/(dim.x/640.0f));
+}
+
+// Returns the object human.
+
+CObject* CDisplayInfo::SearchToto()
+{
+ ObjectType type;
+ CObject* pObj;
+ int i;
+
+ for ( i=0 ; i<1000000 ; i++ )
+ {
+ pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
+ if ( pObj == 0 ) break;
+
+ type = pObj->RetType();
+ if ( type == OBJECT_TOTO )
+ {
+ return pObj;
+ }
+ }
+ return 0;
+}
+
+
+// Creating the list of objects.
+
+typedef struct
+{
+ int total;
+ ObjectType type;
+}
+ObjectList;
+
+void ObjectAdd(ObjectList list[], ObjectType type)
+{
+ int i;
+
+ for ( i=0 ; i<200 ; i++ )
+ {
+ if ( list[i].total == 0 )
+ {
+ list[i].total ++;
+ list[i].type = type;
+ list[i+1].total = 0;
+ return;
+ }
+ if ( list[i].type == type )
+ {
+ list[i].total ++;
+ return;
+ }
+ }
+}
+
+void ObjectWrite(FILE* file, ObjectList list[], int i)
+{
+ char line[100];
+ char res[100];
+ char* p;
+
+ if ( list[i].total < 10 )
+ {
+ sprintf(line, "\\c; %dx \\n;\\l;", list[i].total);
+ }
+ else
+ {
+ sprintf(line, "\\c;%dx \\n;\\l;", list[i].total);
+ }
+
+ GetResource(RES_OBJECT, list[i].type, res);
+ if ( res[0] == 0 ) return;
+ strcat(line, res);
+
+ strcat(line, "\\u ");
+ p = RetHelpFilename(list[i].type);
+ if ( p[0] == 0 ) return;
+ strcat(line, p+5); // skip "help\"
+ p = strstr(line, ".txt");
+ if ( p != 0 ) *p = 0;
+ strcat(line, ";\n");
+ fputs(line, file);
+}
+
+// Creates the file containing the list of objects.
+
+void CDisplayInfo::CreateObjectsFile()
+{
+ FILE* file;
+ CObject* pObj;
+ ObjectType type;
+ ObjectList list[200];
+ char line[100];
+ int i;
+ BOOL bRadar, bAtLeast;
+
+ file = fopen("help\\objects.txt", "w");
+ if ( file == 0 ) return;
+
+ list[0].total = 0; // empty list
+ bRadar = FALSE;
+ for ( i=0 ; i<1000000 ; i++ )
+ {
+ pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
+ if ( pObj == 0 ) break;
+
+ if ( !pObj->RetActif() ) continue;
+ if ( !pObj->RetSelectable() ) continue;
+ if ( pObj->RetProxyActivate() ) continue;
+
+ type = pObj->RetType();
+ if ( type == OBJECT_NULL ) continue;
+ if ( type == OBJECT_FIX ) continue;
+
+ ObjectAdd(list, type);
+
+ if ( type == OBJECT_RADAR ) bRadar = TRUE;
+ }
+
+ if ( bRadar )
+ {
+ GetResource(RES_TEXT, RT_SATCOM_LIST, line);
+ fputs(line, file);
+ bAtLeast = FALSE;
+ for ( i=0 ; i<200 ; i++ )
+ {
+ if ( list[i].total == 0 ) break; // end of the list?
+
+ if ( list[i].type == OBJECT_BASE ||
+ list[i].type == OBJECT_HUMAN )
+ {
+ ObjectWrite(file, list, i);
+ bAtLeast = TRUE;
+ }
+ }
+ if ( !bAtLeast )
+ {
+ GetResource(RES_TEXT, RT_SATCOM_NULL, line);
+ fputs(line, file);
+ }
+
+ strcpy(line, "\n");
+ fputs(line, file);
+ GetResource(RES_TEXT, RT_SATCOM_BOT, line);
+ fputs(line, file);
+ bAtLeast = FALSE;
+ for ( i=0 ; i<200 ; i++ )
+ {
+ if ( list[i].total == 0 ) break; // end of the list?
+
+ if ( list[i].type == OBJECT_MOBILEwt ||
+ list[i].type == OBJECT_MOBILEtt ||
+ list[i].type == OBJECT_MOBILEft ||
+ list[i].type == OBJECT_MOBILEit ||
+ list[i].type == OBJECT_MOBILEwa ||
+ list[i].type == OBJECT_MOBILEta ||
+ list[i].type == OBJECT_MOBILEfa ||
+ list[i].type == OBJECT_MOBILEia ||
+ list[i].type == OBJECT_MOBILEwc ||
+ list[i].type == OBJECT_MOBILEtc ||
+ list[i].type == OBJECT_MOBILEfc ||
+ list[i].type == OBJECT_MOBILEic ||
+ list[i].type == OBJECT_MOBILEwi ||
+ list[i].type == OBJECT_MOBILEti ||
+ list[i].type == OBJECT_MOBILEfi ||
+ list[i].type == OBJECT_MOBILEii ||
+ list[i].type == OBJECT_MOBILEws ||
+ list[i].type == OBJECT_MOBILEts ||
+ list[i].type == OBJECT_MOBILEfs ||
+ list[i].type == OBJECT_MOBILEis ||
+ list[i].type == OBJECT_MOBILErt ||
+ list[i].type == OBJECT_MOBILErc ||
+ list[i].type == OBJECT_MOBILErr ||
+ list[i].type == OBJECT_MOBILErs ||
+ list[i].type == OBJECT_MOBILEsa ||
+ list[i].type == OBJECT_MOBILEtg ||
+ list[i].type == OBJECT_MOBILEdr )
+ {
+ ObjectWrite(file, list, i);
+ bAtLeast = TRUE;
+ }
+ }
+ if ( !bAtLeast )
+ {
+ GetResource(RES_TEXT, RT_SATCOM_NULL, line);
+ fputs(line, file);
+ }
+
+ strcpy(line, "\n");
+ fputs(line, file);
+ GetResource(RES_TEXT, RT_SATCOM_BUILDING, line);
+ fputs(line, file);
+ bAtLeast = FALSE;
+ for ( i=0 ; i<200 ; i++ )
+ {
+ if ( list[i].total == 0 ) break; // end of the list?
+
+ if ( list[i].type == OBJECT_DERRICK ||
+ list[i].type == OBJECT_FACTORY ||
+ list[i].type == OBJECT_STATION ||
+ list[i].type == OBJECT_CONVERT ||
+ list[i].type == OBJECT_REPAIR ||
+ list[i].type == OBJECT_DESTROYER||
+ list[i].type == OBJECT_TOWER ||
+ list[i].type == OBJECT_NEST ||
+ list[i].type == OBJECT_RESEARCH ||
+ list[i].type == OBJECT_RADAR ||
+ list[i].type == OBJECT_ENERGY ||
+ list[i].type == OBJECT_LABO ||
+ list[i].type == OBJECT_NUCLEAR ||
+ list[i].type == OBJECT_START ||
+ list[i].type == OBJECT_END ||
+ list[i].type == OBJECT_INFO ||
+ list[i].type == OBJECT_PARA ||
+ list[i].type == OBJECT_TARGET1 ||
+ list[i].type == OBJECT_TARGET2 ||
+ list[i].type == OBJECT_SAFE ||
+ list[i].type == OBJECT_HUSTON )
+ {
+ ObjectWrite(file, list, i);
+ bAtLeast = TRUE;
+ }
+ }
+ if ( !bAtLeast )
+ {
+ GetResource(RES_TEXT, RT_SATCOM_NULL, line);
+ fputs(line, file);
+ }
+
+ strcpy(line, "\n");
+ fputs(line, file);
+ GetResource(RES_TEXT, RT_SATCOM_FRET, line);
+ fputs(line, file);
+ bAtLeast = FALSE;
+ for ( i=0 ; i<200 ; i++ )
+ {
+ if ( list[i].total == 0 ) break; // end of the list?
+
+ if ( list[i].type == OBJECT_STONE ||
+ list[i].type == OBJECT_URANIUM ||
+ list[i].type == OBJECT_METAL ||
+ list[i].type == OBJECT_POWER ||
+ list[i].type == OBJECT_ATOMIC ||
+ list[i].type == OBJECT_BULLET ||
+ list[i].type == OBJECT_BBOX ||
+ list[i].type == OBJECT_TNT )
+ {
+ ObjectWrite(file, list, i);
+ bAtLeast = TRUE;
+ }
+ }
+ if ( !bAtLeast )
+ {
+ GetResource(RES_TEXT, RT_SATCOM_NULL, line);
+ fputs(line, file);
+ }
+
+ strcpy(line, "\n");
+ fputs(line, file);
+ GetResource(RES_TEXT, RT_SATCOM_ALIEN, line);
+ fputs(line, file);
+ bAtLeast = FALSE;
+ for ( i=0 ; i<200 ; i++ )
+ {
+ if ( list[i].total == 0 ) break; // end of the list?
+
+ if ( list[i].type == OBJECT_MOTHER ||
+ list[i].type == OBJECT_ANT ||
+ list[i].type == OBJECT_BEE ||
+ list[i].type == OBJECT_WORM ||
+ list[i].type == OBJECT_SPIDER )
+ {
+ ObjectWrite(file, list, i);
+ bAtLeast = TRUE;
+ }
+ }
+ if ( !bAtLeast )
+ {
+ GetResource(RES_TEXT, RT_SATCOM_NULL, line);
+ fputs(line, file);
+ }
+ }
+ else
+ {
+ GetResource(RES_TEXT, RT_SATCOM_ERROR1, line);
+ fputs(line, file);
+ GetResource(RES_TEXT, RT_SATCOM_ERROR2, line);
+ fputs(line, file);
+ }
+
+ strcpy(line, "\n");
+ fputs(line, file);
+
+ fclose(file);
+}
+
+
diff --git a/src/ui/displayinfo.h b/src/ui/displayinfo.h
new file mode 100644
index 0000000..61b87ee
--- /dev/null
+++ b/src/ui/displayinfo.h
@@ -0,0 +1,92 @@
+// * 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/.
+
+// displayinfo.h
+
+#ifndef _DISPLAYINFO_H_
+#define _DISPLAYINFO_H_
+
+
+#include "struct.h"
+#include "camera.h"
+
+
+class CInstanceManager;
+class CD3DEngine;
+class CEvent;
+class CRobotMain;
+class CCamera;
+class CInterface;
+class CObject;
+class CParticule;
+class CLight;
+
+
+class CDisplayInfo
+{
+public:
+ CDisplayInfo(CInstanceManager* iMan);
+ ~CDisplayInfo();
+
+ BOOL EventProcess(const Event &event);
+
+ void StartDisplayInfo(char *filename, int index, BOOL bSoluce);
+ void StopDisplayInfo();
+
+ void SetPosition(int pos);
+ int RetPosition();
+
+protected:
+ BOOL EventFrame(const Event &event);
+ void HyperUpdate();
+ void AdjustDisplayInfo(FPOINT wpos, FPOINT wdim);
+ void ChangeIndexButton(int index);
+ void UpdateIndexButton();
+ void UpdateCopyButton();
+ void ViewDisplayInfo();
+ CObject* SearchToto();
+ void CreateObjectsFile();
+
+protected:
+ CInstanceManager* m_iMan;
+ CD3DEngine* m_engine;
+ CEvent* m_event;
+ CRobotMain* m_main;
+ CCamera* m_camera;
+ CInterface* m_interface;
+ CParticule* m_particule;
+ CLight* m_light;
+
+ BOOL m_bInfoMaximized;
+ BOOL m_bInfoMinimized;
+
+ int m_index;
+ CameraType m_infoCamera;
+ FPOINT m_infoNormalPos;
+ FPOINT m_infoNormalDim;
+ FPOINT m_infoActualPos;
+ FPOINT m_infoActualDim;
+ FPOINT m_infoFinalPos;
+ FPOINT m_infoFinalDim;
+ int m_lightSuppl;
+ BOOL m_bEditLock;
+ BOOL m_bInitPause;
+ BOOL m_bSoluce;
+ CObject* m_toto;
+};
+
+
+#endif //_DISPLAYINFO_H_
diff --git a/src/ui/displaytext.cpp b/src/ui/displaytext.cpp
new file mode 100644
index 0000000..a56bf9f
--- /dev/null
+++ b/src/ui/displaytext.cpp
@@ -0,0 +1,615 @@
+// * 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/.
+
+// displaytext.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "event.h"
+#include "misc.h"
+#include "restext.h"
+#include "iman.h"
+#include "object.h"
+#include "motion.h"
+#include "motiontoto.h"
+#include "interface.h"
+#include "button.h"
+#include "label.h"
+#include "window.h"
+#include "group.h"
+#include "text.h"
+#include "sound.h"
+#include "displaytext.h"
+
+
+
+#define FONTSIZE 12.0f
+
+
+
+// Object's constructor.
+
+CDisplayText::CDisplayText(CInstanceManager* iMan)
+{
+ int i;
+
+ m_iMan = iMan;
+ m_iMan->AddInstance(CLASS_DISPLAYTEXT, this);
+
+ m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE);
+ m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE);
+ m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND);
+
+ for ( i=0 ; i<MAXDTLINE ; i++ )
+ {
+ m_bExist[i] = FALSE;
+ m_visitGoal[i] = D3DVECTOR(0.0f, 0.0f, 0.0f);
+ m_visitDist[i] = 0.0f;
+ m_visitHeight[i] = 0.0f;
+ m_time[i] = 0.0f; // nothing displayed
+ }
+
+ m_bHide = FALSE;
+ m_bEnable = TRUE;
+ m_delayFactor = 1.0f;
+}
+
+// Object's destructor.
+
+CDisplayText::~CDisplayText()
+{
+ m_iMan->DeleteInstance(CLASS_DISPLAYTEXT, this);
+}
+
+
+// Destroys the object.
+
+void CDisplayText::DeleteObject()
+{
+ m_interface->DeleteControl(EVENT_WINDOW2);
+}
+
+
+// Management of an event.
+
+BOOL CDisplayText::EventProcess(const Event &event)
+{
+ int i;
+
+ if ( m_engine->RetPause() ) return TRUE;
+
+ if ( event.event == EVENT_FRAME )
+ {
+ for ( i=0 ; i<MAXDTLINE ; i++ )
+ {
+ if ( !m_bExist[i] ) break;
+ m_time[i] -= event.rTime;
+ }
+ while ( TRUE )
+ {
+ if ( !m_bExist[0] ||
+ m_time[0] > 0.0f ) break;
+ if ( !ClearLastText() ) break;
+ }
+ }
+
+ return TRUE;
+}
+
+
+// Displays an error.
+
+void CDisplayText::DisplayError(Error err, CObject* pObj, float time)
+{
+ D3DVECTOR pos;
+ float h, d;
+
+ if ( pObj == 0 ) return;
+
+ pos = pObj->RetPosition(0);
+ h = RetIdealHeight(pObj);
+ d = RetIdealDist(pObj);
+ DisplayError(err, pos, h, d, time);
+}
+
+// Displays an error.
+
+void CDisplayText::DisplayError(Error err, D3DVECTOR goal, float height,
+ float dist, float time)
+{
+ TextType type;
+ char text[100];
+
+ if ( err == ERR_OK ) return;
+
+#if 0
+ type = TT_INFO;
+ if ( err < INFO_FIRST )
+ {
+ type = TT_ERROR;
+ }
+ if ( err == ERR_TOWER_POWER ||
+ err == ERR_RESEARCH_POWER ||
+ err == ERR_ENERGY_EMPTY ||
+ err == ERR_LABO_NULL ||
+ err == ERR_NUCLEAR_EMPTY ||
+ err == ERR_CONVERT_EMPTY )
+ {
+ type = TT_WARNING;
+ }
+#else
+ type = TT_WARNING;
+ if ( err >= INFO_FIRST )
+ {
+ type = TT_INFO;
+ }
+ if ( err == ERR_BAT_VIRUS ||
+ err == ERR_VEH_VIRUS ||
+ err == ERR_DELETEMOBILE ||
+ err == ERR_DELETEBUILDING ||
+ err == ERR_TOOMANY ||
+ err == INFO_LOST )
+ {
+ type = TT_ERROR;
+ }
+#endif
+
+ GetResource(RES_ERR, err, text);
+ DisplayText(text, goal, height, dist, time, type);
+}
+
+// Displays text.
+
+void CDisplayText::DisplayText(char *text, CObject* pObj,
+ float time, TextType type)
+{
+ D3DVECTOR pos;
+ float h, d;
+
+ if ( pObj == 0 ) return;
+
+ pos = pObj->RetPosition(0);
+ h = RetIdealHeight(pObj);
+ d = RetIdealDist(pObj);
+ DisplayText(text, pos, h, d, time, type);
+}
+
+// Displays text.
+
+void CDisplayText::DisplayText(char *text, D3DVECTOR goal, float height,
+ float dist, float time, TextType type)
+{
+ CObject* toto;
+ CMotion* motion;
+ CWindow* pw;
+ CButton* button;
+ CGroup* group;
+ CLabel* label;
+ FPOINT pos, ppos, dim;
+ Sound sound;
+ float hLine, hBox;
+ int nLine, icon, i;
+
+ if ( !m_bEnable ) return;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2);
+ if ( pw == 0 )
+ {
+ pos.x = 0.0f;
+ pos.y = 0.0f;
+ dim.x = 0.0f;
+ dim.y = 0.0f;
+ pw = m_interface->CreateWindows(pos, dim, 10, EVENT_WINDOW2);
+ }
+
+ hBox = 0.045f;
+ hLine = m_engine->RetText()->RetHeight(FONTSIZE, FONT_COLOBOT);
+
+ nLine = 0;
+ for ( i=0 ; i<MAXDTLINE ; i++ )
+ {
+ group = (CGroup*)pw->SearchControl(EventMsg(EVENT_DT_GROUP0+i));
+ if ( group == 0 ) break;
+ nLine ++;
+ }
+
+ if ( nLine == MAXDTLINE )
+ {
+ ClearLastText();
+ nLine --;
+ }
+
+ pos.x = 0.10f;
+ pos.y = 0.92f-hBox-hBox*nLine;
+ dim.x = 0.80f;
+ dim.y = hBox;
+
+ icon = 1; // yellow
+ if ( type == TT_ERROR ) icon = 9; // red
+ if ( type == TT_WARNING ) icon = 10; // blue
+ if ( type == TT_INFO ) icon = 8; // green
+ if ( type == TT_MESSAGE ) icon = 11; // yellow
+ pw->CreateGroup(pos, dim, icon, EventMsg(EVENT_DT_GROUP0+nLine));
+
+ pw->SetTrashEvent(FALSE);
+
+ ppos = pos;
+ ppos.y -= hLine/2.0f;
+ label = pw->CreateLabel(ppos, dim, -1, EventMsg(EVENT_DT_LABEL0+nLine), text);
+ if ( label != 0 )
+ {
+ label->SetFontSize(FONTSIZE);
+ }
+
+ dim.x = dim.y*0.75f;
+ pos.x -= dim.x;
+ button = pw->CreateButton(pos, dim, 14, EventMsg(EVENT_DT_VISIT0+nLine));
+
+ if ( goal.x == 0.0f &&
+ goal.y == 0.0f &&
+ goal.z == 0.0f )
+ {
+ button->ClearState(STATE_ENABLE);
+ }
+
+ m_bExist[nLine] = TRUE;
+ m_visitGoal[nLine] = goal;
+ m_visitDist[nLine] = dist;
+ m_visitHeight[nLine] = height;
+ m_time[nLine] = time*m_delayFactor;
+
+ toto = SearchToto();
+ if ( toto != 0 )
+ {
+ motion = toto->RetMotion();
+ if ( motion != 0 )
+ {
+ if ( type == TT_ERROR )
+ {
+ motion->SetAction(MT_ERROR, 4.0f);
+ }
+ if ( type == TT_WARNING )
+ {
+ motion->SetAction(MT_WARNING, 4.0f);
+ }
+ if ( type == TT_INFO )
+ {
+ motion->SetAction(MT_INFO, 4.0f);
+ }
+ if ( type == TT_MESSAGE )
+ {
+ motion->SetAction(MT_MESSAGE, 4.0f);
+ }
+ }
+ }
+
+ if ( m_bHide )
+ {
+ HideText(m_bHide); // hide all
+ }
+ else
+ {
+ sound = SOUND_CLICK;
+ if ( type == TT_ERROR ) sound = SOUND_ERROR;
+ if ( type == TT_WARNING ) sound = SOUND_WARNING;
+ if ( type == TT_INFO ) sound = SOUND_INFO;
+ if ( type == TT_MESSAGE ) sound = SOUND_MESSAGE;
+
+ if ( sound != SOUND_CLICK )
+ {
+ m_sound->Play(sound);
+ }
+ }
+}
+
+// Clears all text.
+
+void CDisplayText::ClearText()
+{
+ CWindow* pw;
+ int i;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2);
+
+ for ( i=0 ; i<MAXDTLINE ; i++ )
+ {
+ if ( pw != 0 )
+ {
+ pw->DeleteControl(EventMsg(EVENT_DT_GROUP0+i));
+ pw->DeleteControl(EventMsg(EVENT_DT_LABEL0+i));
+ pw->DeleteControl(EventMsg(EVENT_DT_VISIT0+i));
+ }
+ m_bExist[i] = FALSE;
+ m_visitGoal[i] = D3DVECTOR(0.0f, 0.0f, 0.0f);
+ m_visitDist[i] = 0.0f;
+ m_visitHeight[i] = 0.0f;
+ m_time[i] = 0.0f;
+ }
+}
+
+// Hides or shows all texts.
+
+void CDisplayText::HideText(BOOL bHide)
+{
+ CWindow* pw;
+ CGroup* pg;
+ CLabel* pl;
+ CButton* pb;
+ int i;
+
+ m_bHide = bHide;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2);
+ if ( pw == 0 ) return;
+
+ for ( i=0 ; i<MAXDTLINE ; i++ )
+ {
+ pg = (CGroup*)pw->SearchControl(EventMsg(EVENT_DT_GROUP0+i));
+ if ( pg != 0 )
+ {
+ pg->SetState(STATE_VISIBLE, !bHide);
+ }
+
+ pl = (CLabel* )pw->SearchControl(EventMsg(EVENT_DT_LABEL0+i));
+ if ( pl != 0 )
+ {
+ pl->SetState(STATE_VISIBLE, !bHide);
+ }
+
+ pb = (CButton*)pw->SearchControl(EventMsg(EVENT_DT_VISIT0+i));
+ if ( pb != 0 )
+ {
+ pb->SetState(STATE_VISIBLE, !bHide);
+ }
+ }
+}
+
+// Removes the last text (top of the list).
+
+BOOL CDisplayText::ClearLastText()
+{
+ CWindow *pw;
+ CButton *pb1, *pb2;
+ CGroup *pg1, *pg2;
+ CLabel *pl1, *pl2;
+ int i;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2);
+ if ( pw == 0 ) return FALSE;
+
+ pb2 = (CButton*)pw->SearchControl(EVENT_DT_VISIT0);
+ if ( pb2 == 0 ) return FALSE; // same not of first-line
+ pg2 = (CGroup*)pw->SearchControl(EVENT_DT_GROUP0);
+ if ( pg2 == 0 ) return FALSE;
+ pl2 = (CLabel*)pw->SearchControl(EVENT_DT_LABEL0);
+ if ( pl2 == 0 ) return FALSE;
+
+ for ( i=0 ; i<MAXDTLINE-1 ; i++ )
+ {
+ pb1 = pb2;
+ pg1 = pg2;
+ pl1 = pl2;
+
+ pb2 = (CButton*)pw->SearchControl(EventMsg(EVENT_DT_VISIT0+i+1));
+ if ( pb2 == 0 ) break;
+
+ pg2 = (CGroup*)pw->SearchControl(EventMsg(EVENT_DT_GROUP0+i+1));
+ if ( pg2 == 0 ) break;
+
+ pl2 = (CLabel*)pw->SearchControl(EventMsg(EVENT_DT_LABEL0+i+1));
+ if ( pl2 == 0 ) break;
+
+ pb1->SetState(STATE_ENABLE, pb2->TestState(STATE_ENABLE));
+ pg1->SetIcon(pg2->RetIcon());
+ pl1->SetName(pl2->RetName());
+
+ m_time[i] = m_time[i+1];
+ m_visitGoal[i] = m_visitGoal[i+1];
+ m_visitDist[i] = m_visitDist[i+1];
+ m_visitHeight[i] = m_visitHeight[i+1]; // shift
+ }
+
+ pw->DeleteControl(EventMsg(EVENT_DT_VISIT0+i));
+ pw->DeleteControl(EventMsg(EVENT_DT_GROUP0+i));
+ pw->DeleteControl(EventMsg(EVENT_DT_LABEL0+i));
+ m_bExist[i] = FALSE;
+ return TRUE;
+}
+
+
+// Specifies the factor of time.
+
+void CDisplayText::SetDelay(float factor)
+{
+ m_delayFactor = factor;
+}
+
+
+// Enables the display of text.
+
+void CDisplayText::SetEnable(BOOL bEnable)
+{
+ m_bEnable = bEnable;
+}
+
+
+// Returns the goal during a visit.
+
+D3DVECTOR CDisplayText::RetVisitGoal(EventMsg event)
+{
+ int i;
+
+ i = event-EVENT_DT_VISIT0;
+ if ( i < 0 || i >= MAXDTLINE ) return D3DVECTOR(0.0f, 0.0f, 0.0f);
+ return m_visitGoal[i];
+}
+
+// Returns the distance during a visit.
+
+float CDisplayText::RetVisitDist(EventMsg event)
+{
+ int i;
+
+ i = event-EVENT_DT_VISIT0;
+ if ( i < 0 || i >= MAXDTLINE ) return 0.0f;
+ return m_visitDist[i];
+}
+
+// Returns the height on a visit.
+
+float CDisplayText::RetVisitHeight(EventMsg event)
+{
+ int i;
+
+ i = event-EVENT_DT_VISIT0;
+ if ( i < 0 || i >= MAXDTLINE ) return 0.0f;
+ return m_visitHeight[i];
+}
+
+
+// Ranges from ideal visit for a given object.
+
+float CDisplayText::RetIdealDist(CObject* pObj)
+{
+ ObjectType type;
+
+ if ( pObj == 0 ) return 40.0f;
+
+ type = pObj->RetType();
+ if ( type == OBJECT_PORTICO ) return 200.0f;
+ if ( type == OBJECT_BASE ) return 200.0f;
+ if ( type == OBJECT_NUCLEAR ) return 100.0f;
+ if ( type == OBJECT_PARA ) return 100.0f;
+ if ( type == OBJECT_SAFE ) return 100.0f;
+ if ( type == OBJECT_TOWER ) return 80.0f;
+
+ return 60.0f;
+}
+
+// Returns the height of ideal visit for a given object.
+
+float CDisplayText::RetIdealHeight(CObject* pObj)
+{
+ ObjectType type;
+
+ if ( pObj == 0 ) return 5.0f;
+
+ type = pObj->RetType();
+ if ( type == OBJECT_DERRICK ) return 35.0f;
+ if ( type == OBJECT_FACTORY ) return 22.0f;
+ if ( type == OBJECT_REPAIR ) return 30.0f;
+ if ( type == OBJECT_DESTROYER) return 30.0f;
+ if ( type == OBJECT_STATION ) return 13.0f;
+ if ( type == OBJECT_CONVERT ) return 20.0f;
+ if ( type == OBJECT_TOWER ) return 30.0f;
+ if ( type == OBJECT_RESEARCH ) return 22.0f;
+ if ( type == OBJECT_RADAR ) return 19.0f;
+ if ( type == OBJECT_INFO ) return 19.0f;
+ if ( type == OBJECT_ENERGY ) return 20.0f;
+ if ( type == OBJECT_LABO ) return 16.0f;
+ if ( type == OBJECT_NUCLEAR ) return 40.0f;
+ if ( type == OBJECT_PARA ) return 40.0f;
+ if ( type == OBJECT_SAFE ) return 20.0f;
+
+ return 15.0f;
+}
+
+
+// Removes all visits.
+
+void CDisplayText::ClearVisit()
+{
+ CWindow* pw;
+ CButton* pb;
+ int i;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2);
+ if ( pw == 0 ) return;
+
+ for ( i=0 ; i<MAXDTLINE ; i++ )
+ {
+ pb = (CButton*)pw->SearchControl(EventMsg(EVENT_DT_VISIT0+i));
+ if ( pb == 0 ) break;
+ pb->SetIcon(14); // eyes
+ }
+}
+
+// Puts a button in "visit".
+
+void CDisplayText::SetVisit(EventMsg event)
+{
+ CWindow* pw;
+ CButton* pb;
+ int i;
+
+ i = event-EVENT_DT_VISIT0;
+ if ( i < 0 || i >= MAXDTLINE ) return;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2);
+ if ( pw == 0 ) return;
+ pb = (CButton*)pw->SearchControl(EventMsg(EVENT_DT_VISIT0+i));
+ if ( pb == 0 ) return;
+ pb->SetIcon(48); // >
+}
+
+// Indicates whether a button is set to "visit".
+
+BOOL CDisplayText::IsVisit(EventMsg event)
+{
+ CWindow* pw;
+ CButton* pb;
+ int i;
+
+ i = event-EVENT_DT_VISIT0;
+ if ( i < 0 || i >= MAXDTLINE ) return FALSE;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2);
+ if ( pw == 0 ) return FALSE;
+ pb = (CButton*)pw->SearchControl(EventMsg(EVENT_DT_VISIT0+i));
+ if ( pb == 0 ) return FALSE;
+ return (pb->RetIcon() == 48); // > ?
+}
+
+
+// Returns the object toto.
+
+CObject* CDisplayText::SearchToto()
+{
+ ObjectType type;
+ CObject* pObj;
+ int i;
+
+ for ( i=0 ; i<1000000 ; i++ )
+ {
+ pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
+ if ( pObj == 0 ) break;
+
+ type = pObj->RetType();
+ if ( type == OBJECT_TOTO )
+ {
+ return pObj;
+ }
+ }
+ return 0;
+}
+
diff --git a/src/ui/displaytext.h b/src/ui/displaytext.h
new file mode 100644
index 0000000..6a54e1f
--- /dev/null
+++ b/src/ui/displaytext.h
@@ -0,0 +1,96 @@
+// * 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/.
+
+// displaytext.h
+
+#ifndef _DISPLAYTEXT_H_
+#define _DISPLAYTEXT_H_
+
+
+#include "d3dengine.h"
+
+
+class CInstanceManager;
+class CD3DEngine;
+class CInterface;
+class CObject;
+class CSound;
+
+
+enum TextType
+{
+ TT_ERROR = 1,
+ TT_WARNING = 2,
+ TT_INFO = 3,
+ TT_MESSAGE = 4,
+};
+
+#define MAXDTLINE 4
+
+
+class CDisplayText
+{
+public:
+ CDisplayText(CInstanceManager* iMan);
+ ~CDisplayText();
+
+ void DeleteObject();
+
+ BOOL EventProcess(const Event &event);
+
+ void DisplayError(Error err, CObject* pObj, float time=10.0f);
+ void DisplayError(Error err, D3DVECTOR goal, float height=15.0f, float dist=60.0f, float time=10.0f);
+ void DisplayText(char *text, CObject* pObj, float time=10.0f, TextType type=TT_INFO);
+ void DisplayText(char *text, D3DVECTOR goal, float height=15.0f, float dist=60.0f, float time=10.0f, TextType type=TT_INFO);
+ void HideText(BOOL bHide);
+ void ClearText();
+ BOOL ClearLastText();
+ void SetDelay(float factor);
+ void SetEnable(BOOL bEnable);
+
+ D3DVECTOR RetVisitGoal(EventMsg event);
+ float RetVisitDist(EventMsg event);
+ float RetVisitHeight(EventMsg event);
+
+ float RetIdealDist(CObject* pObj);
+ float RetIdealHeight(CObject* pObj);
+
+ void ClearVisit();
+ void SetVisit(EventMsg event);
+ BOOL IsVisit(EventMsg event);
+
+protected:
+ CObject* SearchToto();
+
+protected:
+ CInstanceManager* m_iMan;
+ CD3DEngine* m_engine;
+ CInterface* m_interface;
+ CSound* m_sound;
+
+ BOOL m_bExist[MAXDTLINE];
+ float m_time[MAXDTLINE];
+ D3DVECTOR m_visitGoal[MAXDTLINE];
+ float m_visitDist[MAXDTLINE];
+ float m_visitHeight[MAXDTLINE];
+
+ BOOL m_bHide;
+ BOOL m_bEnable;
+ float m_delayFactor;
+};
+
+
+#endif //_DISPLAYTEXT_H_
diff --git a/src/ui/edit.cpp b/src/ui/edit.cpp
new file mode 100644
index 0000000..f15b0c2
--- /dev/null
+++ b/src/ui/edit.cpp
@@ -0,0 +1,3318 @@
+// * 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/.
+
+// edit.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <windows.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "language.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "restext.h"
+#include "scroll.h"
+#include "text.h"
+#include "edit.h"
+
+
+#define MARGX (5.0f/640.0f)
+#define MARGY (5.0f/480.0f)
+#define MARGYS (4.0f/480.0f)
+#define MARGY1 (1.0f/480.0f)
+#define DELAY_DBCLICK 0.3f // time limit for double-click
+#define DELAY_SCROLL 0.1f // time limit for scroll
+#define BIG_FONT 1.6f // expansion for \b;
+
+
+
+
+// Indicates whether a character is a space.
+
+BOOL IsSpace(int character)
+{
+ return ( character == ' ' ||
+ character == '\t' ||
+ character == '\n' );
+}
+
+// Indicates whether a character is part of a word.
+
+BOOL IsWord(int character)
+{
+ char c;
+
+ c = tolower(RetNoAccent(character));
+
+ return ( (c >= 'a' && c <= 'z') ||
+ (c >= '0' && c <= '9') ||
+ c == '_' );
+}
+
+// Indicates whether a character is a word separator.
+
+BOOL IsSep(int character)
+{
+ if ( IsSpace(character) ) return FALSE;
+ return !IsWord(character);
+}
+
+
+
+// Object's constructor.
+
+CEdit::CEdit(CInstanceManager* iMan) : CControl(iMan)
+{
+ FPOINT pos;
+ int i;
+
+ m_maxChar = 100;
+ m_text = (char*)malloc(sizeof(char)*(m_maxChar+1));
+ m_format = 0;
+ m_len = 0;
+
+ m_fontType = FONT_COURIER;
+ m_scroll = 0;
+ m_bEdit = TRUE;
+ m_bHilite = TRUE;
+ m_bInsideScroll = TRUE;
+ m_bCapture = FALSE;
+ m_bDisplaySpec = FALSE;
+ m_bSoluce = FALSE;
+ m_bGeneric = FALSE;
+ m_bAutoIndent = FALSE;
+ m_cursor1 = 0;
+ m_cursor2 = 0;
+ m_column = 0;
+ m_imageTotal = 0;
+
+ HyperFlush();
+
+ for ( i=0 ; i<EDITUNDOMAX ; i++ )
+ {
+ m_undo[i].text = 0;
+ }
+ m_bUndoForce = TRUE;
+ m_undoOper = OPERUNDO_SPEC;
+}
+
+// Object's destructor.
+
+CEdit::~CEdit()
+{
+ int i;
+
+ FreeImage();
+
+ for ( i=0 ; i<EDITUNDOMAX ; i++ )
+ {
+ delete m_undo[i].text;
+ }
+
+ delete m_text;
+ delete m_format;
+ delete m_scroll;
+}
+
+
+// Creates a new editable line.
+
+BOOL CEdit::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CScroll* pc;
+ FPOINT start, end;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+ CControl::Create(pos, dim, icon, eventMsg);
+
+ m_len = 0;
+ m_lineFirst = 0;
+ m_time = 0.0f;
+ m_timeBlink = 0.0f;
+ m_timeLastClick = 0.0f;
+ m_timeLastScroll = 0.0f;
+
+ m_bMulti = FALSE;
+ MoveAdjust();
+ if ( m_lineVisible <= 1 )
+ {
+ m_bMulti = FALSE;
+ }
+ else
+ {
+ m_bMulti = TRUE;
+ MoveAdjust(); // readjusts multi-line mode
+ m_scroll = new CScroll(m_iMan);
+ pc = (CScroll*)m_scroll;
+ pc->Create(pos, dim, -1, EVENT_NULL);
+ MoveAdjust();
+ }
+
+ return TRUE;
+}
+
+
+void CEdit::SetPos(FPOINT pos)
+{
+ CControl::SetPos(pos);
+ MoveAdjust();
+}
+
+void CEdit::SetDim(FPOINT dim)
+{
+ CControl::SetDim(dim);
+ MoveAdjust();
+}
+
+void CEdit::MoveAdjust()
+{
+ FPOINT pos, dim;
+ float height;
+
+ m_lineDescent = m_engine->RetText()->RetDescent(m_fontSize, m_fontType);
+ m_lineAscent = m_engine->RetText()->RetAscent(m_fontSize, m_fontType);
+ m_lineHeight = m_engine->RetText()->RetHeight(m_fontSize, m_fontType);
+
+ height = m_dim.y-(m_bMulti?MARGY*2.0f:MARGY1);
+ m_lineVisible = (int)(height/m_lineHeight);
+
+ if ( m_scroll != 0 )
+ {
+ if ( m_bInsideScroll )
+ {
+ pos.x = m_pos.x+m_dim.x-MARGX-SCROLL_WIDTH;
+ pos.y = m_pos.y+MARGYS;
+ dim.x = SCROLL_WIDTH;
+ dim.y = m_dim.y-MARGYS*2.0f;
+ }
+ else
+ {
+ pos.x = m_pos.x+m_dim.x-SCROLL_WIDTH;
+ pos.y = m_pos.y;
+ dim.x = SCROLL_WIDTH;
+ dim.y = m_dim.y;
+ }
+ m_scroll->SetPos(pos);
+ m_scroll->SetDim(dim);
+ }
+
+ Justif();
+
+ if ( m_lineFirst > m_lineTotal-m_lineVisible )
+ {
+ m_lineFirst = m_lineTotal-m_lineVisible;
+ if ( m_lineFirst < 0 ) m_lineFirst = 0;
+ }
+
+ pos.x = m_pos.x+m_dim.x-(m_bMulti?SCROLL_WIDTH:0.0f);
+ pos.y = m_pos.y;
+ GlintCreate(pos, FALSE, FALSE);
+}
+
+
+// Management of an event.
+
+BOOL CEdit::EventProcess(const Event &event)
+{
+ BOOL bShift, bControl;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE;
+
+ if ( event.event == EVENT_KEYDOWN &&
+ event.param == VK_WHEELUP &&
+ Detect(event.pos) )
+ {
+ Scroll(m_lineFirst-3, TRUE);
+ return TRUE;
+ }
+ if ( event.event == EVENT_KEYDOWN &&
+ event.param == VK_WHEELDOWN &&
+ Detect(event.pos) )
+ {
+ Scroll(m_lineFirst+3, TRUE);
+ return TRUE;
+ }
+
+ CControl::EventProcess(event);
+
+ if ( event.event == EVENT_FRAME )
+ {
+ m_time += event.rTime;
+ m_timeBlink += event.rTime;
+ }
+
+ if ( event.event == EVENT_MOUSEMOVE )
+ {
+ if ( Detect(event.pos) &&
+ event.pos.x < m_pos.x+m_dim.x-(m_bMulti?MARGX+SCROLL_WIDTH:0.0f) )
+ {
+ if ( m_bEdit )
+ {
+ m_engine->SetMouseType(D3DMOUSEEDIT);
+ }
+ else
+ {
+ if ( IsLinkPos(event.pos) )
+ {
+ m_engine->SetMouseType(D3DMOUSEHAND);
+ }
+ else
+ {
+ m_engine->SetMouseType(D3DMOUSENORM);
+ }
+ }
+ }
+ }
+
+ if ( m_scroll != 0 && !m_bGeneric )
+ {
+ m_scroll->EventProcess(event);
+
+ if ( event.event == m_scroll->RetEventMsg() )
+ {
+ Scroll();
+ return TRUE;
+ }
+ }
+
+ if ( event.event == EVENT_KEYDOWN && m_bFocus )
+ {
+ bShift = (event.keyState&KS_SHIFT);
+ bControl = (event.keyState&KS_CONTROL);
+
+ if ( (event.param == 'X' && !bShift && bControl) ||
+ (event.param == VK_DELETE && bShift && !bControl) )
+ {
+ Cut();
+ return TRUE;
+ }
+ if ( (event.param == 'C' && !bShift && bControl) ||
+ (event.param == VK_INSERT && !bShift && bControl) )
+ {
+ Copy();
+ return TRUE;
+ }
+ if ( (event.param == 'V' && !bShift && bControl) ||
+ (event.param == VK_INSERT && bShift && !bControl) )
+ {
+ Paste();
+ return TRUE;
+ }
+
+ if ( event.param == 'A' && !bShift && bControl )
+ {
+ SetCursor(999999, 0);
+ return TRUE;
+ }
+
+ if ( event.param == 'O' && !bShift && bControl )
+ {
+ Event newEvent;
+ m_event->MakeEvent(newEvent, EVENT_STUDIO_OPEN);
+ m_event->AddEvent(newEvent);
+ }
+ if ( event.param == 'S' && !bShift && bControl )
+ {
+ Event newEvent;
+ m_event->MakeEvent(newEvent, EVENT_STUDIO_SAVE);
+ m_event->AddEvent(newEvent);
+ }
+
+ if ( event.param == 'Z' && !bShift && bControl )
+ {
+ Undo();
+ return TRUE;
+ }
+
+ if ( event.param == 'U' && !bShift && bControl )
+ {
+ if ( MinMaj(FALSE) ) return TRUE;
+ }
+ if ( event.param == 'U' && bShift && bControl )
+ {
+ if ( MinMaj(TRUE) ) return TRUE;
+ }
+
+ if ( event.param == VK_TAB && !bShift && !bControl && !m_bAutoIndent )
+ {
+ if ( Shift(FALSE) ) return TRUE;
+ }
+ if ( event.param == VK_TAB && bShift && !bControl && !m_bAutoIndent )
+ {
+ if ( Shift(TRUE) ) return TRUE;
+ }
+
+ if ( m_bEdit )
+ {
+ if ( event.param == VK_LEFT )
+ {
+ MoveChar(-1, bControl, bShift);
+ return TRUE;
+ }
+ if ( event.param == VK_RIGHT )
+ {
+ MoveChar(1, bControl, bShift);
+ return TRUE;
+ }
+ if ( event.param == VK_UP )
+ {
+ MoveLine(-1, bControl, bShift);
+ return TRUE;
+ }
+ if ( event.param == VK_DOWN )
+ {
+ MoveLine(1, bControl, bShift);
+ return TRUE;
+ }
+
+ if ( event.param == VK_PRIOR ) // PageUp ?
+ {
+ MoveLine(-(m_lineVisible-1), bControl, bShift);
+ return TRUE;
+ }
+ if ( event.param == VK_NEXT ) // PageDown ?
+ {
+ MoveLine(m_lineVisible-1, bControl, bShift);
+ return TRUE;
+ }
+ }
+ else
+ {
+ if ( event.param == VK_LEFT ||
+ event.param == VK_UP )
+ {
+ Scroll(m_lineFirst-1, TRUE);
+ return TRUE;
+ }
+ if ( event.param == VK_RIGHT ||
+ event.param == VK_DOWN )
+ {
+ Scroll(m_lineFirst+1, TRUE);
+ return TRUE;
+ }
+
+ if ( event.param == VK_PRIOR ) // PageUp ?
+ {
+ Scroll(m_lineFirst-(m_lineVisible-1), TRUE);
+ return TRUE;
+ }
+ if ( event.param == VK_NEXT ) // PageDown ?
+ {
+ Scroll(m_lineFirst+(m_lineVisible-1), TRUE);
+ return TRUE;
+ }
+ }
+
+ if ( event.param == VK_HOME )
+ {
+ MoveHome(bControl, bShift);
+ return TRUE;
+ }
+ if ( event.param == VK_END )
+ {
+ MoveEnd(bControl, bShift);
+ return TRUE;
+ }
+
+ if ( event.param == VK_BACK ) // backspace ( <- ) ?
+ {
+ Delete(-1);
+ SendModifEvent();
+ return TRUE;
+ }
+ if ( event.param == VK_DELETE )
+ {
+ Delete(1);
+ SendModifEvent();
+ return TRUE;
+ }
+
+ if ( event.param == VK_RETURN )
+ {
+ Insert('\n');
+ SendModifEvent();
+ return TRUE;
+ }
+ if ( event.param == VK_TAB )
+ {
+ Insert('\t');
+ SendModifEvent();
+ return TRUE;
+ }
+ }
+
+ if ( event.event == EVENT_CHAR && m_bFocus )
+ {
+ if ( event.param >= ' ' && event.param <= 255 )
+ {
+ Insert((char)event.param);
+ SendModifEvent();
+ return TRUE;
+ }
+ }
+
+ if ( event.event == EVENT_FOCUS )
+ {
+ if ( event.param == m_eventMsg )
+ {
+ m_bFocus = TRUE;
+ }
+ else
+ {
+ m_bFocus = FALSE;
+ }
+ }
+
+ if ( event.event == EVENT_LBUTTONDOWN )
+ {
+ m_mouseFirstPos = event.pos;
+ m_mouseLastPos = event.pos;
+ if ( Detect(event.pos) )
+ {
+ if ( event.pos.x < m_pos.x+m_dim.x-(m_bMulti?MARGX+SCROLL_WIDTH:0.0f) )
+ {
+ MouseClick(event.pos);
+ if ( m_bEdit || m_bHilite ) m_bCapture = TRUE;
+ }
+ m_bFocus = TRUE;
+ }
+ else
+ {
+ m_bFocus = FALSE;
+ }
+ }
+
+ if ( event.event == EVENT_MOUSEMOVE && m_bCapture )
+ {
+ m_mouseLastPos = event.pos;
+ MouseMove(event.pos);
+ }
+
+ if ( event.event == EVENT_FRAME && m_bCapture )
+ {
+ MouseMove(m_mouseLastPos);
+ }
+
+ if ( event.event == EVENT_LBUTTONUP )
+ {
+ if ( Detect(event.pos) )
+ {
+ if ( event.pos.x < m_pos.x+m_dim.x-(m_bMulti?MARGX+SCROLL_WIDTH:0.0f) )
+ {
+ MouseRelease(m_mouseFirstPos);
+ }
+ }
+ if ( m_bCapture )
+ {
+ if ( m_timeLastClick+DELAY_DBCLICK > m_time ) // double-click ?
+ {
+ MouseDoubleClick(event.pos);
+ }
+ m_timeLastClick = m_time;
+ m_bCapture = FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+// Sends an event to indicate that the text was modified.
+
+void CEdit::SendModifEvent()
+{
+ Event newEvent;
+
+ m_event->MakeEvent(newEvent, m_eventMsg);
+ m_event->AddEvent(newEvent);
+}
+
+
+// Detects whether the mouse is over a hyperlink character.
+
+BOOL CEdit::IsLinkPos(FPOINT pos)
+{
+ int i;
+
+ if ( m_format == 0 ) return FALSE;
+
+ i = MouseDetect(pos);
+ if ( i == -1 ) return FALSE;
+ if ( i >= m_len ) return FALSE;
+
+ if ( (m_format[i]&COLOR_MASK) == COLOR_LINK ) return TRUE;
+ return FALSE;
+}
+
+
+// Positions the cursor after a double click.
+
+void CEdit::MouseDoubleClick(FPOINT mouse)
+{
+ int i, character;
+
+ if ( m_bMulti ) // Multi-line?
+ {
+ i = MouseDetect(mouse);
+ if ( i == -1 ) return;
+
+ while ( i > 0 )
+ {
+ character = (unsigned char)m_text[i-1];
+ if ( !IsWord(character) ) break;
+ i --;
+ }
+ m_cursor2 = i;
+
+ while ( i < m_len )
+ {
+ character = (unsigned char)m_text[i];
+ if ( !IsWord(character) ) break;
+ i ++;
+ }
+ m_cursor1 = i;
+ }
+ else // single-line?
+ {
+ m_cursor2 = 0;
+ m_cursor1 = m_len; // selects all
+ }
+
+ m_bUndoForce = TRUE;
+
+ Justif();
+ ColumnFix();
+}
+
+// Positions the cursor when clicked.
+
+void CEdit::MouseClick(FPOINT mouse)
+{
+ int i;
+
+ i = MouseDetect(mouse);
+ if ( i == -1 ) return;
+
+ if ( m_bEdit || m_bHilite )
+ {
+ m_cursor1 = i;
+ m_cursor2 = i;
+ m_bUndoForce = TRUE;
+ m_timeBlink = 0.0f; // lights the cursor immediately
+ ColumnFix();
+ }
+}
+
+// Positions the cursor when clicked released.
+
+void CEdit::MouseRelease(FPOINT mouse)
+{
+ int i, j, rank;
+
+ i = MouseDetect(mouse);
+ if ( i == -1 ) return;
+
+ if ( !m_bEdit )
+ {
+ if ( m_format != 0 && i < m_len && m_cursor1 == m_cursor2 &&
+ (m_format[i]&COLOR_MASK) == COLOR_LINK )
+ {
+ rank = -1;
+ for ( j=0 ; j<=i ; j++ )
+ {
+ if ( (j == 0 || (m_format[j-1]&COLOR_MASK) != COLOR_LINK) &&
+ (m_format[j+0]&COLOR_MASK) == COLOR_LINK )
+ {
+ rank ++;
+ }
+ }
+ HyperJump(m_link[rank].name, m_link[rank].marker);
+ }
+ }
+}
+
+// Positions the cursor after movement.
+
+void CEdit::MouseMove(FPOINT mouse)
+{
+ int i;
+
+ if ( m_bMulti &&
+ m_timeLastScroll+DELAY_SCROLL <= m_time )
+ {
+ if ( mouse.y > m_pos.y+m_dim.y ) // above?
+ {
+ Scroll(m_lineFirst-1, FALSE);
+ mouse.y = m_pos.y+m_dim.y-MARGY-m_lineHeight/2.0f;
+ }
+ if ( mouse.y < m_pos.y ) // lower?
+ {
+ Scroll(m_lineFirst+1, FALSE);
+ mouse.y = m_pos.y+m_dim.y-MARGY-m_lineVisible*m_lineHeight+m_lineHeight/2.0f;
+ }
+ m_timeLastScroll = m_time;
+ }
+
+ i = MouseDetect(mouse);
+ if ( i != -1 )
+ {
+ m_cursor1 = i;
+ m_bUndoForce = TRUE;
+ m_timeBlink = 0.0f; // lights the cursor immediately
+ ColumnFix();
+ }
+}
+
+// Positions the cursor when clicked.
+
+int CEdit::MouseDetect(FPOINT mouse)
+{
+ FPOINT pos;
+ float indentLength, offset, size;
+ int i, len, c;
+ BOOL bTitle;
+
+ if ( m_bAutoIndent )
+ {
+ indentLength = m_engine->RetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType)
+ * m_engine->RetEditIndentValue();
+ }
+
+ pos.y = m_pos.y+m_dim.y-m_lineHeight-(m_bMulti?MARGY:MARGY1);
+ for ( i=m_lineFirst ; i<m_lineTotal ; i++ )
+ {
+ bTitle = ( m_format != 0 && (m_format[m_lineOffset[i]]&TITLE_MASK) == TITLE_BIG );
+
+ if ( i >= m_lineFirst+m_lineVisible ) break;
+
+ pos.x = m_pos.x+(10.0f/640.0f);
+ if ( m_bAutoIndent )
+ {
+ pos.x += indentLength*m_lineIndent[i];
+ }
+ offset = mouse.x-pos.x;
+
+ if ( bTitle ) pos.y -= m_lineHeight;
+
+ if ( mouse.y > pos.y )
+ {
+ len = m_lineOffset[i+1] - m_lineOffset[i];
+
+ if ( m_format == 0 )
+ {
+ c = m_engine->RetText()->Detect(m_text+m_lineOffset[i],
+ len, offset, m_fontSize,
+ m_fontStretch, m_fontType);
+ }
+ else
+ {
+ size = m_fontSize;
+ if ( bTitle ) size *= BIG_FONT;
+
+ c = m_engine->RetText()->Detect(m_text+m_lineOffset[i],
+ m_format+m_lineOffset[i],
+ len, offset, size,
+ m_fontStretch);
+ }
+ return m_lineOffset[i]+c;
+ }
+
+ if ( bTitle ) i ++;
+ pos.y -= m_lineHeight;
+ }
+ return -1;
+}
+
+
+// Clears all history.
+
+void CEdit::HyperFlush()
+{
+ m_historyTotal = 0;
+ m_historyCurrent = -1;
+}
+
+// Indicates which is the home page.
+
+void CEdit::HyperHome(char *filename)
+{
+ HyperFlush();
+ HyperAdd(filename, 0);
+}
+
+// Performs a hyper jump through a link.
+
+void CEdit::HyperJump(char *name, char *marker)
+{
+ char filename[100];
+ char sMarker[100];
+ int i, line, pos;
+
+ if ( m_historyCurrent >= 0 )
+ {
+ m_history[m_historyCurrent].firstLine = m_lineFirst;
+ }
+
+ strcpy(sMarker, marker);
+
+//? sprintf(filename, "help\\%s.txt", name);
+ if ( name[0] == '%' )
+ {
+ UserDir(filename, name, "");
+ strcat(filename, ".txt");
+ }
+ else
+ {
+ sprintf(filename, "help\\%s.txt", name);
+ }
+ if ( ReadText(filename) )
+ {
+ Justif();
+
+ line = 0;
+ for ( i=0 ; i<m_markerTotal ; i++ )
+ {
+ if ( strcmp(sMarker, m_marker[i].name) == 0 )
+ {
+ pos = m_marker[i].pos;
+ for ( i=0 ; i<m_lineTotal ; i++ )
+ {
+ if ( pos >= m_lineOffset[i] )
+ {
+ line = i;
+ }
+ }
+ break;
+ }
+ }
+
+ SetFirstLine(line);
+ HyperAdd(filename, line);
+ }
+}
+
+// Adds text to the history of visited.
+
+BOOL CEdit::HyperAdd(char *filename, int firstLine)
+{
+ if ( m_historyCurrent >= EDITHISTORYMAX-1 ) return FALSE;
+
+ m_historyCurrent ++;
+ strcpy(m_history[m_historyCurrent].filename, filename);
+ m_history[m_historyCurrent].firstLine = firstLine;
+
+ m_historyTotal = m_historyCurrent+1;
+ return TRUE;
+}
+
+// Indicates whether a button EVENT_HYPER_ * is active or not.
+
+BOOL CEdit::HyperTest(EventMsg event)
+{
+ if ( event == EVENT_HYPER_HOME )
+ {
+ return ( m_historyCurrent > 0 );
+ }
+
+ if ( event == EVENT_HYPER_PREV )
+ {
+ return ( m_historyCurrent > 0 );
+ }
+
+ if ( event == EVENT_HYPER_NEXT )
+ {
+ return ( m_historyCurrent < m_historyTotal-1 );
+ }
+
+ return FALSE;
+}
+
+// Performs the action corresponding to a button EVENT_HYPER_ *.
+
+BOOL CEdit::HyperGo(EventMsg event)
+{
+ if ( !HyperTest(event) ) return FALSE;
+
+ m_history[m_historyCurrent].firstLine = m_lineFirst;
+
+ if ( event == EVENT_HYPER_HOME )
+ {
+ m_historyCurrent = 0;
+ }
+
+ if ( event == EVENT_HYPER_PREV )
+ {
+ m_historyCurrent --;
+ }
+
+ if ( event == EVENT_HYPER_NEXT )
+ {
+ m_historyCurrent ++;
+ }
+
+ ReadText(m_history[m_historyCurrent].filename);
+ Justif();
+ SetFirstLine(m_history[m_historyCurrent].firstLine);
+ return TRUE;
+}
+
+
+// Draw the editable line.
+
+void CEdit::Draw()
+{
+ FPOINT pos, ppos, dim, start, end;
+ float size, indentLength;
+ int i, j, beg, len, c1, c2, o1, o2, eol, iIndex, line;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ if ( m_state & STATE_SHADOW )
+ {
+ DrawShadow(m_pos, m_dim);
+ }
+
+ pos.x = m_pos.x;
+ pos.y = m_pos.y;
+ dim.x = m_dim.x;
+ if ( !m_bInsideScroll ) dim.x -= m_bMulti?SCROLL_WIDTH:0.0f;
+ dim.y = m_dim.y;
+ DrawBack(pos, dim); // background
+
+ // Displays all lines.
+ c1 = m_cursor1;
+ c2 = m_cursor2;
+ if ( c1 > c2 ) Swap(c1, c2); // always c1 <= c2
+
+ if ( m_bInsideScroll )
+ {
+ dim.x -= m_bMulti?SCROLL_WIDTH:0.0f + (1.0f/640.0f);
+ }
+
+ if ( m_bAutoIndent )
+ {
+ indentLength = m_engine->RetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType)
+ * m_engine->RetEditIndentValue();
+ }
+
+ pos.y = m_pos.y+m_dim.y-m_lineHeight-(m_bMulti?MARGY:MARGY1);
+ for ( i=m_lineFirst ; i<m_lineTotal ; i++ )
+ {
+ if ( i == m_lineFirst && i < m_lineTotal-1 &&
+ m_lineOffset[i] == m_lineOffset[i+1] )
+ {
+ pos.y -= m_lineHeight; // Double jump line \b;
+ i ++;
+ }
+
+ if ( i >= m_lineFirst+m_lineVisible ) break;
+
+ pos.x = m_pos.x+(10.0f/640.0f);
+ if ( m_bAutoIndent )
+ {
+ for ( j=0 ; j<m_lineIndent[i] ; j++ )
+ {
+ char s = '\t'; // line | dotted
+ m_engine->RetText()->DrawText(&s, 1, pos, 1.0f, 1, m_fontSize, m_fontStretch, m_fontType, 0);
+ pos.x += indentLength;
+ }
+ }
+
+ beg = m_lineOffset[i];
+ len = m_lineOffset[i+1] - m_lineOffset[i];
+
+ ppos = pos;
+ size = m_fontSize;
+
+ // Headline \b;?
+ if ( beg+len < m_len && m_format != 0 &&
+ (m_format[beg]&TITLE_MASK) == TITLE_BIG )
+ {
+ start.x = ppos.x-MARGX;
+ end.x = dim.x-MARGX*2.0f;
+ start.y = ppos.y-(m_bMulti?0.0f:MARGY1)-m_lineHeight*(BIG_FONT-1.0f);
+ end.y = m_lineHeight*BIG_FONT;
+ DrawPart(start, end, 2); // blue gradient background ->
+
+ size *= BIG_FONT;
+ ppos.y -= m_lineHeight*(BIG_FONT-1.0f);
+ }
+
+ // As \t;?
+ if ( beg+len < m_len && m_format != 0 &&
+ (m_format[beg]&TITLE_MASK) == TITLE_NORM )
+ {
+ start.x = ppos.x-MARGX;
+ end.x = dim.x-MARGX*2.0f;
+ start.y = ppos.y-(m_bMulti?0.0f:MARGY1);
+ end.y = m_lineHeight;
+ DrawPart(start, end, 2); // blue gradient background ->
+ }
+
+ // Subtitle \s;?
+ if ( beg+len < m_len && m_format != 0 &&
+ (m_format[beg]&TITLE_MASK) == TITLE_LITTLE )
+ {
+ start.x = ppos.x-MARGX;
+ end.x = dim.x-MARGX*2.0f;
+ start.y = ppos.y-(m_bMulti?0.0f:MARGY1);
+ end.y = m_lineHeight;
+ DrawPart(start, end, 3); // yellow background gradient ->
+ }
+
+ // Table \tab;?
+ if ( beg+len < m_len && m_format != 0 &&
+ (m_format[beg]&COLOR_MASK) == COLOR_TABLE )
+ {
+ start.x = ppos.x-MARGX;
+ end.x = dim.x-MARGX*2.0f;
+ start.y = ppos.y-(m_bMulti?0.0f:MARGY1);
+ end.y = m_lineHeight;
+ DrawPart(start, end, 11); // fond orange d�grad� ->
+ }
+
+ // Image \image; ?
+ if ( beg+len < m_len && m_format != 0 &&
+ (m_format[beg]&IMAGE_MASK) != 0 )
+ {
+ line = 1;
+ while ( true ) // includes the image slices
+ {
+ if ( i+line >= m_lineTotal ||
+ i+line >= m_lineFirst+m_lineVisible ||
+ (m_format[beg+line]&IMAGE_MASK) == 0 ) break;
+ line ++;
+ }
+
+ iIndex = m_text[beg]; // character = index in m_image
+ pos.y -= m_lineHeight*(line-1);
+ DrawImage(pos, m_image[iIndex].name,
+ m_image[iIndex].width*(m_fontSize/SMALLFONT),
+ m_image[iIndex].offset, m_image[iIndex].height*line, line);
+ pos.y -= m_lineHeight;
+ i += line-1;
+ continue;
+ }
+
+ if ( ((m_bEdit && m_bFocus && m_bHilite) ||
+ (!m_bEdit && m_bHilite) ) &&
+ c1 != c2 && beg <= c2 && beg+len >= c1 ) // selected area?
+ {
+ o1 = c1; if ( o1 < beg ) o1 = beg;
+ o2 = c2; if ( o2 > beg+len ) o2 = beg+len;
+
+ if ( m_format == 0 )
+ {
+ start.x = ppos.x+m_engine->RetText()->RetStringWidth(m_text+beg, o1-beg, size, m_fontStretch, m_fontType);
+ end.x = m_engine->RetText()->RetStringWidth(m_text+o1, o2-o1, size, m_fontStretch, m_fontType);
+ }
+ else
+ {
+ start.x = ppos.x+m_engine->RetText()->RetStringWidth(m_text+beg, m_format+beg, o1-beg, size, m_fontStretch);
+ end.x = m_engine->RetText()->RetStringWidth(m_text+o1, m_format+o1, o2-o1, size, m_fontStretch);
+ }
+
+ start.y = ppos.y-(m_bMulti?0.0f:MARGY1);
+ end.y = m_lineHeight;
+ if ( m_format != 0 && (m_format[beg]&TITLE_MASK) == TITLE_BIG ) end.y *= BIG_FONT;
+ DrawPart(start, end, 1); // plain yellow background
+ }
+
+ eol = 16; // >
+ if ( len > 0 && m_text[beg+len-1] == '\n' )
+ {
+ len --; // does not display the '\ n'
+ eol = 0; // nothing
+ }
+ if ( beg+len >= m_len )
+ {
+ eol = 2; // square (eot)
+ }
+ if ( !m_bMulti || !m_bDisplaySpec ) eol = 0;
+ if ( m_format == 0 )
+ {
+ m_engine->RetText()->DrawText(m_text+beg, len, ppos, m_dim.x, 1, size, m_fontStretch, m_fontType, eol);
+ }
+ else
+ {
+ m_engine->RetText()->DrawText(m_text+beg, m_format+beg, len, ppos, m_dim.x, 1, size, m_fontStretch, eol);
+ }
+
+ pos.y -= m_lineHeight;
+
+ if ( i < m_lineTotal-2 && m_lineOffset[i+1] == m_lineOffset[i+2] )
+ {
+ pos.y -= m_lineHeight; // double jump line \b;
+ i ++;
+ }
+ }
+
+ // Shows the cursor.
+ if ( (m_bEdit && m_bFocus && m_bHilite && Mod(m_timeBlink, 1.0f) <= 0.5f) ) // it blinks
+ {
+ pos.y = m_pos.y+m_dim.y-m_lineHeight-(m_bMulti?MARGY:MARGY1*2.0f);
+ for ( i=m_lineFirst ; i<m_lineTotal ; i++ )
+ {
+ if ( i == m_lineTotal-1 || m_cursor1 < m_lineOffset[i+1] )
+ {
+ pos.x = m_pos.x+(10.0f/640.0f);
+ if ( m_bAutoIndent )
+ {
+ pos.x += indentLength*m_lineIndent[i];
+ }
+
+ len = m_cursor1 - m_lineOffset[i];
+
+ if ( m_format == 0 )
+ {
+ m_engine->RetText()->DimText(m_text+m_lineOffset[i], len,
+ pos, 1, size,
+ m_fontStretch, m_fontType,
+ start, end);
+ }
+ else
+ {
+ m_engine->RetText()->DimText(m_text+m_lineOffset[i],
+ m_format+m_lineOffset[i],
+ len, pos, 1, size,
+ m_fontStretch,
+ start, end);
+ }
+
+ pos.x = end.x;
+ break;
+ }
+ pos.y -= m_lineHeight;
+ }
+ pos.x -= 1.0f/640.0f;
+ dim.x = 2.0f/640.0f;
+ dim.y = m_lineHeight;
+ DrawPart(pos, dim, 0); // red
+ }
+
+ if ( m_scroll != 0 && !m_bGeneric )
+ {
+ m_scroll->Draw();
+ }
+}
+
+// Draw an image part.
+
+void CEdit::DrawImage(FPOINT pos, char *name, float width,
+ float offset, float height, int nbLine)
+{
+ FPOINT uv1, uv2, dim;
+ float dp;
+ char filename[100];
+
+//? sprintf(filename, "diagram\\%s.bmp", name);
+ UserDir(filename, name, "diagram");
+ strcat(filename, ".bmp");
+
+ m_engine->SetTexture(filename);
+ m_engine->SetState(D3DSTATENORMAL);
+
+ uv1.x = 0.0f;
+ uv2.x = 1.0f;
+ uv1.y = offset;
+ uv2.y = offset+height;
+
+ dp = 0.5f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+
+ dim.x = width;
+ dim.y = m_lineHeight*nbLine;
+ DrawIcon(pos, dim, uv1, uv2);
+}
+
+// Draw the background.
+
+void CEdit::DrawBack(FPOINT pos, FPOINT dim)
+{
+ FPOINT uv1,uv2, corner;
+ float dp;
+
+ if ( m_bGeneric ) return;
+
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+
+ if ( m_bMulti )
+ {
+ uv1.x = 128.0f/256.0f; // light blue
+ uv1.y = 64.0f/256.0f;
+ uv2.x = 160.0f/256.0f;
+ uv2.y = 96.0f/256.0f;
+ }
+ else
+ {
+ uv1.x = 160.0f/256.0f; // medium blue
+ uv1.y = 192.0f/256.0f;
+ uv2.x = 192.0f/256.0f;
+ uv2.y = 224.0f/256.0f;
+ }
+ if ( m_icon == 1 )
+ {
+ uv1.x = 192.0f/256.0f; // orange
+ uv1.y = 96.0f/256.0f;
+ uv2.x = 224.0f/256.0f;
+ uv2.y = 128.0f/256.0f;
+ }
+
+ dp = 0.5f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+
+ if ( m_bMulti )
+ {
+ corner.x = 10.0f/640.0f;
+ corner.y = 10.0f/480.0f;
+ DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f);
+ }
+ else
+ {
+ DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f);
+ }
+}
+
+// Draws an icon background.
+
+void CEdit::DrawPart(FPOINT pos, FPOINT dim, int icon)
+{
+ FPOINT uv1, uv2;
+ float dp;
+
+#if _POLISH
+ m_engine->SetTexture("textp.tga");
+#else
+ m_engine->SetTexture("text.tga");
+#endif
+ m_engine->SetState(D3DSTATENORMAL);
+
+ uv1.x = (16.0f/256.0f)*(icon%16);
+ uv1.y = (240.0f/256.0f);
+ uv2.x = (16.0f/256.0f)+uv1.x;
+ uv2.y = (16.0f/256.0f)+uv1.y;
+
+ dp = 0.5f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+
+ DrawIcon(pos, dim, uv1, uv2);
+}
+
+
+// Give the text to edit.
+
+void CEdit::SetText(char *text, BOOL bNew)
+{
+ int i, j, font;
+ BOOL bBOL;
+
+ if ( !bNew ) UndoMemorize(OPERUNDO_SPEC);
+
+ m_len = strlen(text);
+ if ( m_len > m_maxChar ) m_len = m_maxChar;
+
+ if ( m_format == 0 )
+ {
+ if ( m_bAutoIndent )
+ {
+ j = 0;
+ bBOL = TRUE;
+ for ( i=0 ; i<m_len ; i++ )
+ {
+ if ( text[i] == '\t' )
+ {
+ if ( !bBOL ) m_text[j++] = ' ';
+ continue; // removes tabs
+ }
+ bBOL = ( text[i] == '\n' );
+
+ m_text[j++] = text[i];
+ }
+ m_len = j;
+ }
+ else
+ {
+ strncpy(m_text, text, m_len);
+ }
+ }
+ else
+ {
+ font = m_fontType;
+ j = 0;
+ bBOL = TRUE;
+ for ( i=0 ; i<m_len ; i++ )
+ {
+ if ( m_bAutoIndent )
+ {
+ if ( text[i] == '\t' )
+ {
+ if ( !bBOL )
+ {
+ m_text[j] = ' ';
+ m_format[j] = font;
+ j ++;
+ }
+ continue; // removes tabs
+ }
+ bBOL = ( text[i] == '\n' );
+ }
+
+ if ( text[i] == '\\' && text[i+2] == ';' )
+ {
+ if ( text[i+1] == 'n' ) // normal ?
+ {
+ font &= ~FONT_MASK;
+ font |= FONT_COLOBOT;
+ i += 2;
+ }
+ else if ( text[i+1] == 'c' ) // cbot ?
+ {
+ font &= ~FONT_MASK;
+ font |= FONT_COURIER;
+ i += 2;
+ }
+ else if ( text[i+1] == 'b' ) // big title ?
+ {
+ font &= ~TITLE_MASK;
+ font |= TITLE_BIG;
+ i += 2;
+ }
+ else if ( text[i+1] == 't' ) // title ?
+ {
+ font &= ~TITLE_MASK;
+ font |= TITLE_NORM;
+ i += 2;
+ }
+ else if ( text[i+1] == 's' ) // subtitle ?
+ {
+ font &= ~TITLE_MASK;
+ font |= TITLE_LITTLE;
+ i += 2;
+ }
+ }
+ else
+ {
+ m_text[j] = text[i];
+ m_format[j] = font;
+ j ++;
+
+ font &= ~TITLE_MASK; // reset title
+ }
+ }
+ m_len = j;
+ }
+
+ if ( bNew ) UndoFlush();
+
+ m_cursor1 = 0;
+ m_cursor2 = 0; // cursor to the beginning
+ Justif();
+ ColumnFix();
+}
+
+// Returns a pointer to the edited text.
+
+char* CEdit::RetText()
+{
+ m_text[m_len] = 0;
+ return m_text;
+}
+
+// Returns the edited text.
+
+void CEdit::GetText(char *buffer, int max)
+{
+ if ( m_len < max ) max = m_len;
+ if ( m_len > max ) max = max-1;
+
+ strncpy(buffer, m_text, max);
+ buffer[max] = 0;
+}
+
+// Returns the length of the text.
+
+int CEdit::RetTextLength()
+{
+ return m_len;
+}
+
+
+
+// Returns a name in a command.
+// \x nom1 nom2 nom3;
+
+void GetNameParam(char *cmd, int rank, char *buffer)
+{
+ int i;
+
+ for ( i=0 ; i<rank ; i++ )
+ {
+ while ( *cmd != ' ' && *cmd != ';' )
+ {
+ cmd ++;
+ }
+ if ( *cmd != ';' ) cmd ++;
+ }
+
+ while ( *cmd != ' ' && *cmd != ';' )
+ {
+ *buffer++ = *cmd++;
+ }
+ *buffer = 0;
+}
+
+// Returns a number of a command.
+// \x nom n1 n2;
+
+int RetValueParam(char *cmd, int rank)
+{
+ int n, i;
+
+ for ( i=0 ; i<rank ; i++ )
+ {
+ while ( *cmd != ' ' && *cmd != ';' )
+ {
+ cmd ++;
+ }
+ if ( *cmd != ';' ) cmd ++;
+ }
+
+ sscanf(cmd, "%d", &n);
+ return n;
+}
+
+// Frees all images.
+
+void CEdit::FreeImage()
+{
+ char filename[100];
+ int i;
+
+ for ( i=0 ; i<m_imageTotal ; i++ )
+ {
+//? sprintf(filename, "diagram\\%s.bmp", m_image[i].name);
+ UserDir(filename, m_image[i].name, "diagram");
+ strcat(filename, ".bmp");
+ m_engine->FreeTexture(filename);
+ }
+}
+
+// Reads the texture of an image.
+
+void CEdit::LoadImage(char *name)
+{
+ char filename[100];
+
+//? sprintf(filename, "diagram\\%s.bmp", name);
+ UserDir(filename, name, "diagram");
+ strcat(filename, ".bmp");
+ m_engine->LoadTexture(filename);
+}
+
+// Read from a text file.
+
+BOOL CEdit::ReadText(char *filename, int addSize)
+{
+ FILE *file = NULL;
+ char *buffer;
+ int len, i, j, n, font, iIndex, iLines, iCount, iLink, res;
+ char iName[50];
+ char text[50];
+ float iWidth;
+ KeyRank key;
+ BOOL bInSoluce, bBOL;
+
+ if ( filename[0] == 0 ) return FALSE;
+ file = fopen(filename, "rb");
+ if ( file == NULL ) return FALSE;
+
+ fseek(file, 0, SEEK_END);
+ len = ftell(file);
+ fseek(file, 0, SEEK_SET);
+
+ m_maxChar = len+addSize+100;
+ m_len = len;
+ m_cursor1 = 0;
+ m_cursor2 = 0;
+
+ FreeImage();
+ delete m_text;
+ m_text = (char*)malloc(sizeof(char)*(m_maxChar+1));
+ buffer = (char*)malloc(sizeof(char)*(m_maxChar+1));
+ fread(buffer, 1, len, file);
+
+ if ( m_format != 0 )
+ {
+ delete m_format;
+ m_format = (char*)malloc(sizeof(char)*m_maxChar);
+ }
+
+ fclose(file);
+
+ bInSoluce = FALSE;
+ font = m_fontType;
+ iIndex = 0;
+ iLink = 0;
+ m_imageTotal = 0;
+ m_markerTotal = 0;
+ i = j = 0;
+ bBOL = TRUE;
+ while ( i < m_len )
+ {
+ if ( m_bAutoIndent )
+ {
+ if ( buffer[i] == '\t' )
+ {
+ if ( !bBOL )
+ {
+ m_text[j] = buffer[i];
+ if ( m_format != 0 ) m_format[j] = font;
+ j ++;
+ }
+ i ++;
+ continue; // removes the tabs
+ }
+ bBOL = ( buffer[i] == '\n' || buffer[i] == '\r' );
+ }
+
+ if ( buffer[i] == '\r' ) // removes \ r
+ {
+ i ++;
+ }
+ else if ( m_format != 0 && buffer[i] == '\\' && buffer[i+2] == ';' )
+ {
+ if ( buffer[i+1] == 'n' ) // normal ?
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ font &= ~FONT_MASK;
+ font |= FONT_COLOBOT;
+ }
+ i += 3;
+ }
+ else if ( buffer[i+1] == 'c' ) // cbot ?
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ font &= ~FONT_MASK;
+ font |= FONT_COURIER;
+ }
+ i += 3;
+ }
+ else if ( buffer[i+1] == 'b' ) // big title ?
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ font &= ~TITLE_MASK;
+ font |= TITLE_BIG;
+ }
+ i += 3;
+ }
+ else if ( buffer[i+1] == 't' ) // title ?
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ font &= ~TITLE_MASK;
+ font |= TITLE_NORM;
+ }
+ i += 3;
+ }
+ else if ( buffer[i+1] == 's' ) // subtitle ?
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ font &= ~TITLE_MASK;
+ font |= TITLE_LITTLE;
+ }
+ i += 3;
+ }
+ else if ( buffer[i+1] == 'l' ) // link ?
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ font &= ~COLOR_MASK;
+ font |= COLOR_LINK;
+ }
+ i += 3;
+ }
+ else
+ {
+ i += 3;
+ }
+ }
+ else if ( m_format != 0 &&
+ buffer[i+0] == '\\' && // \u marker name; ?
+ buffer[i+1] == 'u' &&
+ buffer[i+2] == ' ' )
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ if ( iLink < EDITLINKMAX )
+ {
+ GetNameParam(buffer+i+3, 0, m_link[iLink].name);
+ GetNameParam(buffer+i+3, 1, m_link[iLink].marker);
+ iLink ++;
+ }
+ font &= ~COLOR_MASK;
+ }
+ i += strchr(buffer+i, ';')-(buffer+i)+1;
+ }
+ else if ( m_format != 0 &&
+ buffer[i+0] == '\\' && // \m marker; ?
+ buffer[i+1] == 'm' &&
+ buffer[i+2] == ' ' )
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ if ( m_markerTotal < EDITLINKMAX )
+ {
+ GetNameParam(buffer+i+3, 0, m_marker[m_markerTotal].name);
+ m_marker[m_markerTotal].pos = j;
+ m_markerTotal ++;
+ }
+ }
+ i += strchr(buffer+i, ';')-(buffer+i)+1;
+ }
+ else if ( m_format != 0 &&
+ buffer[i+0] == '\\' && // \image name lx ly; ?
+ buffer[i+1] == 'i' &&
+ buffer[i+2] == 'm' &&
+ buffer[i+3] == 'a' &&
+ buffer[i+4] == 'g' &&
+ buffer[i+5] == 'e' &&
+ buffer[i+6] == ' ' )
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+#if _DEMO
+ strcpy(iName, "demo");
+#else
+ GetNameParam(buffer+i+7, 0, iName);
+#endif
+//? iWidth = m_lineHeight*RetValueParam(buffer+i+7, 1);
+ iWidth = (float)RetValueParam(buffer+i+7, 1);
+ iWidth *= m_engine->RetText()->RetHeight(SMALLFONT, FONT_COLOBOT);
+ iLines = RetValueParam(buffer+i+7, 2);
+ LoadImage(iName);
+
+ // A part of image per line of text.
+ for ( iCount=0 ; iCount<iLines ; iCount++ )
+ {
+ strcpy(m_image[iIndex].name, iName);
+ m_image[iIndex].offset = (float)iCount/iLines;
+ m_image[iIndex].height = 1.0f/iLines;
+ m_image[iIndex].width = iWidth*0.75f;
+
+ m_text[j] = (char)(iIndex++); // as an index into m_image
+ m_format[j] = (unsigned char)IMAGE_MASK;
+ j ++;
+ }
+ }
+ i += strchr(buffer+i, ';')-(buffer+i)+1;
+ }
+ else if ( m_format != 0 &&
+ buffer[i+0] == '\\' && // \button; ?
+ buffer[i+1] == 'b' &&
+ buffer[i+2] == 'u' &&
+ buffer[i+3] == 't' &&
+ buffer[i+4] == 't' &&
+ buffer[i+5] == 'o' &&
+ buffer[i+6] == 'n' &&
+ buffer[i+7] == ' ' )
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ m_text[j] = RetValueParam(buffer+i+8, 0);
+ m_format[j] = font|FONT_BUTTON;
+ j ++;
+ }
+ i += strchr(buffer+i, ';')-(buffer+i)+1;
+ }
+ else if ( m_format != 0 &&
+ buffer[i+0] == '\\' && // \token; ?
+ buffer[i+1] == 't' &&
+ buffer[i+2] == 'o' &&
+ buffer[i+3] == 'k' &&
+ buffer[i+4] == 'e' &&
+ buffer[i+5] == 'n' &&
+ buffer[i+6] == ';' )
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ font &= ~COLOR_MASK;
+ font |= COLOR_TOKEN;
+ }
+ i += 7;
+ }
+ else if ( m_format != 0 &&
+ buffer[i+0] == '\\' && // \type; ?
+ buffer[i+1] == 't' &&
+ buffer[i+2] == 'y' &&
+ buffer[i+3] == 'p' &&
+ buffer[i+4] == 'e' &&
+ buffer[i+5] == ';' )
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ font &= ~COLOR_MASK;
+ font |= COLOR_TYPE;
+ }
+ i += 6;
+ }
+ else if ( m_format != 0 &&
+ buffer[i+0] == '\\' && // \const; ?
+ buffer[i+1] == 'c' &&
+ buffer[i+2] == 'o' &&
+ buffer[i+3] == 'n' &&
+ buffer[i+4] == 's' &&
+ buffer[i+5] == 't' &&
+ buffer[i+6] == ';' )
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ font &= ~COLOR_MASK;
+ font |= COLOR_CONST;
+ }
+ i += 7;
+ }
+ else if ( m_format != 0 &&
+ buffer[i+0] == '\\' && // \key; ?
+ buffer[i+1] == 'k' &&
+ buffer[i+2] == 'e' &&
+ buffer[i+3] == 'y' &&
+ buffer[i+4] == ';' )
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ font &= ~COLOR_MASK;
+ font |= COLOR_KEY;
+ }
+ i += 5;
+ }
+ else if ( m_format != 0 &&
+ buffer[i+0] == '\\' && // \tab; ?
+ buffer[i+1] == 't' &&
+ buffer[i+2] == 'a' &&
+ buffer[i+3] == 'b' &&
+ buffer[i+4] == ';' )
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ font |= COLOR_TABLE;
+ }
+ i += 5;
+ }
+ else if ( m_format != 0 &&
+ buffer[i+0] == '\\' && // \norm; ?
+ buffer[i+1] == 'n' &&
+ buffer[i+2] == 'o' &&
+ buffer[i+3] == 'r' &&
+ buffer[i+4] == 'm' &&
+ buffer[i+5] == ';' )
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ font &= ~COLOR_MASK;
+ }
+ i += 6;
+ }
+ else if ( m_format != 0 &&
+ buffer[i+0] == '\\' && // \begin soluce; ?
+ buffer[i+1] == 'b' &&
+ buffer[i+2] == 's' &&
+ buffer[i+3] == ';' )
+ {
+ bInSoluce = TRUE;
+ i += 4;
+ }
+ else if ( m_format != 0 &&
+ buffer[i+0] == '\\' && // \end soluce; ?
+ buffer[i+1] == 'e' &&
+ buffer[i+2] == 's' &&
+ buffer[i+3] == ';' )
+ {
+ bInSoluce = FALSE;
+ i += 4;
+ }
+ else if ( m_format != 0 &&
+ buffer[i+0] == '\\' && // \key name; ?
+ buffer[i+1] == 'k' &&
+ buffer[i+2] == 'e' &&
+ buffer[i+3] == 'y' &&
+ buffer[i+4] == ' ' )
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ if ( SearchKey(buffer+i+5, key) )
+ {
+ res = m_engine->RetKey(key, 0);
+ if ( res != 0 )
+ {
+ if ( GetResource(RES_KEY, res, iName) )
+ {
+ m_text[j] = ' ';
+ m_format[j] = font;
+ j ++;
+ n = 0;
+ while ( iName[n] != 0 )
+ {
+ m_text[j] = iName[n++];
+ m_format[j] = font;
+ j ++;
+ }
+ m_text[j] = ' ';
+ m_format[j] = font;
+ j ++;
+
+ res = m_engine->RetKey(key, 1);
+ if ( res != 0 )
+ {
+ if ( GetResource(RES_KEY, res, iName) )
+ {
+ GetResource(RES_TEXT, RT_KEY_OR, text);
+ n = 0;
+ while ( text[n] != 0 )
+ {
+ m_text[j] = text[n++];
+ m_format[j] = font&~COLOR_MASK;
+ j ++;
+ }
+ n = 0;
+ while ( iName[n] != 0 )
+ {
+ m_text[j] = iName[n++];
+ m_format[j] = font;
+ j ++;
+ }
+ m_text[j] = ' ';
+ m_format[j] = font;
+ j ++;
+ }
+ }
+ while ( buffer[i++] != ';' );
+ continue;
+ }
+ }
+ }
+ m_text[j] = '?';
+ m_format[j] = font;
+ j ++;
+ }
+ while ( buffer[i++] != ';' );
+ }
+ else
+ {
+ if ( m_bSoluce || !bInSoluce )
+ {
+ m_text[j] = buffer[i];
+ if ( m_format != 0 ) m_format[j] = font;
+ j ++;
+ }
+ i ++;
+
+ font &= ~TITLE_MASK; // reset title
+
+ if ( (font&COLOR_MASK) == COLOR_TABLE )
+ {
+ font &= ~COLOR_TABLE;
+ }
+ }
+ }
+ m_len = j;
+ m_imageTotal = iIndex;
+
+ delete buffer;
+
+ Justif();
+ ColumnFix();
+ return TRUE;
+}
+
+// Writes all the text in a file.
+
+BOOL CEdit::WriteText(char *filename)
+{
+ FILE* file;
+ char buffer[1000+20];
+ int i, j, k, n;
+ float iDim;
+
+ if ( filename[0] == 0 ) return FALSE;
+ file = fopen(filename, "wb");
+ if ( file == NULL ) return FALSE;
+
+ if ( m_bAutoIndent )
+ {
+ iDim = m_dim.x;
+ m_dim.x = 1000.0f; // puts an infinite width!
+ Justif();
+ }
+
+ i = j = k = 0;
+ while ( m_text[i] != 0 && i < m_len )
+ {
+ if ( m_bAutoIndent && i == m_lineOffset[k] )
+ {
+ for ( n=0 ; n<m_lineIndent[k] ; n++ )
+ {
+ buffer[j++] = '\t';
+ }
+ k ++;
+ }
+
+ buffer[j++] = m_text[i];
+
+ if ( m_text[i] == '\n' )
+ {
+ buffer[j-1] = '\r';
+ buffer[j++] = '\n'; // \r\n (0x0D, 0x0A)
+ }
+
+ if ( j >= 1000-1 )
+ {
+ fwrite(buffer, 1, j, file);
+ j = 0;
+ }
+
+ i ++;
+ }
+ if ( j > 0 )
+ {
+ fwrite(buffer, 1, j, file);
+ }
+
+ fclose(file);
+
+ if ( m_bAutoIndent )
+ {
+ m_dim.x = iDim; // presents the initial width
+ Justif();
+ }
+
+ return TRUE;
+}
+
+
+// Manage the number of max characters editable.
+
+void CEdit::SetMaxChar(int max)
+{
+ m_maxChar = max;
+ FreeImage();
+ delete m_text;
+ m_text = (char*)malloc(sizeof(char)*(m_maxChar+1));
+
+ if ( m_format != 0 )
+ {
+ delete m_format;
+ m_format = (char*)malloc(sizeof(char)*m_maxChar);
+ }
+
+ m_len = 0;
+ m_cursor1 = 0;
+ m_cursor2 = 0;
+ Justif();
+ UndoFlush();
+}
+
+int CEdit::RetMaxChar()
+{
+ return m_maxChar;
+}
+
+
+// Mode management "editable".
+
+void CEdit::SetEditCap(BOOL bMode)
+{
+ m_bEdit = bMode;
+}
+
+BOOL CEdit::RetEditCap()
+{
+ return m_bEdit;
+}
+
+// Mode management "hilitable" (that's the franch).
+
+void CEdit::SetHiliteCap(BOOL bEnable)
+{
+ m_bHilite = bEnable;
+}
+
+BOOL CEdit::RetHiliteCap()
+{
+ return m_bHilite;
+}
+
+// Lift in / out connection.
+
+void CEdit::SetInsideScroll(BOOL bInside)
+{
+ m_bInsideScroll = bInside;
+}
+
+BOOL CEdit::RetInsideScroll()
+{
+ return m_bInsideScroll;
+}
+
+// Specifies whether to display the links showing the solution.
+
+void CEdit::SetSoluceMode(BOOL bSoluce)
+{
+ m_bSoluce = bSoluce;
+}
+
+BOOL CEdit::RetSoluceMode()
+{
+ return m_bSoluce;
+}
+
+// Indicates whether the text is a defile that generic.
+
+void CEdit::SetGenericMode(BOOL bGeneric)
+{
+ m_bGeneric = bGeneric;
+}
+
+BOOL CEdit::RetGenericMode()
+{
+ return m_bGeneric;
+}
+
+
+// Management of automatic indentation mode with {}.
+
+void CEdit::SetAutoIndent(BOOL bMode)
+{
+ m_bAutoIndent = bMode;
+}
+
+BOOL CEdit::RetAutoIndent()
+{
+ return m_bAutoIndent;
+}
+
+
+
+// Moves the cursors.
+
+void CEdit::SetCursor(int cursor1, int cursor2)
+{
+ if ( cursor1 > m_len ) cursor1 = m_len;
+ if ( cursor2 > m_len ) cursor2 = m_len;
+
+ m_cursor1 = cursor1;
+ m_cursor2 = cursor2;
+ m_bUndoForce = TRUE;
+ ColumnFix();
+}
+
+// Returns the sliders.
+
+void CEdit::GetCursor(int &cursor1, int &cursor2)
+{
+ cursor1 = m_cursor1;
+ cursor2 = m_cursor2;
+}
+
+
+// Displayed line modifies the first.
+
+void CEdit::SetFirstLine(int rank)
+{
+ Scroll(rank, TRUE);
+}
+
+// Returns the first displayed line.
+
+int CEdit::RetFirstLine()
+{
+ if ( m_historyTotal > 0 )
+ {
+ if ( m_historyCurrent == 0 )
+ {
+ return m_lineFirst;
+ }
+ else
+ {
+ return m_history[0].firstLine;
+ }
+ }
+ return m_lineFirst;
+}
+
+
+// Shows the selected area.
+
+void CEdit::ShowSelect()
+{
+ int cursor1, cursor2, line;
+
+ if ( m_cursor1 < m_cursor2 )
+ {
+ cursor1 = m_cursor1;
+ cursor2 = m_cursor2;
+ }
+ else
+ {
+ cursor1 = m_cursor2;
+ cursor2 = m_cursor1;
+ }
+
+ line = RetCursorLine(cursor2);
+ if ( line >= m_lineFirst+m_lineVisible )
+ {
+ line -= m_lineVisible-1;
+ if ( line < 0 ) line = 0;
+ Scroll(line, FALSE);
+ }
+
+ line = RetCursorLine(cursor1);
+ if ( line < m_lineFirst )
+ {
+ Scroll(line, FALSE);
+ }
+}
+
+
+// Management of the display mode of special characters.
+
+void CEdit::SetDisplaySpec(BOOL bDisplay)
+{
+ m_bDisplaySpec = bDisplay;
+}
+
+BOOL CEdit::RetDisplaySpec()
+{
+ return m_bDisplaySpec;
+}
+
+
+// Multi-fonts mode management.
+
+void CEdit::SetMultiFont(BOOL bMulti)
+{
+ if ( bMulti )
+ {
+ delete m_format;
+ m_format = (char*)malloc(sizeof(char)*m_maxChar);
+ memset(m_format, 0, m_maxChar);
+ }
+ else
+ {
+ delete m_format;
+ m_format = 0;
+ }
+}
+
+BOOL CEdit::RetMultiFont()
+{
+ return ( m_format != 0 );
+}
+
+
+// Management of the character size.
+
+void CEdit::SetFontSize(float size)
+{
+ CControl::SetFontSize(size);
+
+ MoveAdjust();
+}
+
+
+// Moves according to the visible lift.
+
+void CEdit::Scroll()
+{
+ float value;
+
+ if ( m_scroll != 0 )
+ {
+ value = m_scroll->RetVisibleValue();
+ value *= m_lineTotal-m_lineVisible;
+ Scroll((int)(value+0.5f), TRUE);
+ }
+}
+
+// Moves according to the visible lift.
+
+void CEdit::Scroll(int pos, BOOL bAdjustCursor)
+{
+ int max, line;
+
+ m_lineFirst = pos;
+
+ if ( m_lineFirst < 0 ) m_lineFirst = 0;
+
+ max = m_lineTotal-m_lineVisible;
+ if ( max < 0 ) max = 0;
+ if ( m_lineFirst > max ) m_lineFirst = max;
+
+ line = RetCursorLine(m_cursor1);
+
+ if ( bAdjustCursor && m_bEdit )
+ {
+ // Cursor too high?
+ if ( line < m_lineFirst )
+ {
+ MoveLine(m_lineFirst-line, FALSE, FALSE);
+ return;
+ }
+
+ // Cursor too low?
+ if ( line >= m_lineFirst+m_lineVisible )
+ {
+ MoveLine(m_lineFirst+m_lineVisible-line-1, FALSE, FALSE);
+ return;
+ }
+ }
+
+ Justif();
+}
+
+// Moves the cursor to the beginning of the line.
+
+void CEdit::MoveHome(BOOL bWord, BOOL bSelect)
+{
+ int begin, tab;
+
+ if ( bWord )
+ {
+ m_cursor1 = 0;
+ }
+ else
+ {
+ begin = m_cursor1;
+ while ( begin > 0 && m_text[begin-1] != '\n' )
+ {
+ begin --;
+ }
+
+ tab = begin;
+ while ( tab < m_len && (m_text[tab] == '\t' || m_text[tab] == ' ') )
+ {
+ tab ++;
+ }
+
+ if ( m_cursor1 == tab )
+ {
+ m_cursor1 = begin;
+ }
+ else
+ {
+ m_cursor1 = tab;
+ }
+ }
+ if ( !bSelect ) m_cursor2 = m_cursor1;
+
+ m_bUndoForce = TRUE;
+ Justif();
+ ColumnFix();
+}
+
+// Moves the cursor to the end of the line.
+
+void CEdit::MoveEnd(BOOL bWord, BOOL bSelect)
+{
+ if ( bWord )
+ {
+ m_cursor1 = m_len;
+ }
+ else
+ {
+ while ( m_cursor1 < m_len && m_text[m_cursor1] != '\n' )
+ {
+ m_cursor1 ++;
+ }
+ }
+ if ( !bSelect ) m_cursor2 = m_cursor1;
+
+ m_bUndoForce = TRUE;
+ Justif();
+ ColumnFix();
+}
+
+// Moves the cursor through characters.
+
+void CEdit::MoveChar(int move, BOOL bWord, BOOL bSelect)
+{
+ int character;
+
+ if ( move == -1 ) // back?
+ {
+ if ( bWord )
+ {
+ while ( m_cursor1 > 0 )
+ {
+ character = (unsigned char)m_text[m_cursor1-1];
+ if ( !IsSpace(character) ) break;
+ m_cursor1 --;
+ }
+
+ if ( m_cursor1 > 0 )
+ {
+ character = (unsigned char)m_text[m_cursor1-1];
+ if ( IsSpace(character) )
+ {
+ while ( m_cursor1 > 0 )
+ {
+ character = (unsigned char)m_text[m_cursor1-1];
+ if ( !IsSpace(character) ) break;
+ m_cursor1 --;
+ }
+ }
+ else if ( IsWord(character) )
+ {
+ while ( m_cursor1 > 0 )
+ {
+ character = (unsigned char)m_text[m_cursor1-1];
+ if ( !IsWord(character) ) break;
+ m_cursor1 --;
+ }
+ }
+ else if ( IsSep(character) )
+ {
+ while ( m_cursor1 > 0 )
+ {
+ character = (unsigned char)m_text[m_cursor1-1];
+ if ( !IsSep(character) ) break;
+ m_cursor1 --;
+ }
+ }
+ }
+ }
+ else
+ {
+ m_cursor1 --;
+ if ( m_cursor1 < 0 ) m_cursor1 = 0;
+ }
+ }
+
+ if ( move == 1 ) // advance?
+ {
+ if ( bWord )
+ {
+ if ( m_cursor1 < m_len )
+ {
+ character = (unsigned char)m_text[m_cursor1];
+ if ( IsSpace(character) )
+ {
+ while ( m_cursor1 < m_len )
+ {
+ character = (unsigned char)m_text[m_cursor1];
+ if ( !IsSpace(character) ) break;
+ m_cursor1 ++;
+ }
+ }
+ else if ( IsWord(character) )
+ {
+ while ( m_cursor1 < m_len )
+ {
+ character = (unsigned char)m_text[m_cursor1];
+ if ( !IsWord(character) ) break;
+ m_cursor1 ++;
+ }
+ }
+ else if ( IsSep(character) )
+ {
+ while ( m_cursor1 < m_len )
+ {
+ character = (unsigned char)m_text[m_cursor1];
+ if ( !IsSep(character) ) break;
+ m_cursor1 ++;
+ }
+ }
+ }
+
+ while ( m_cursor1 < m_len )
+ {
+ character = (unsigned char)m_text[m_cursor1];
+ if ( !IsSpace(character) ) break;
+ m_cursor1 ++;
+ }
+ }
+ else
+ {
+ m_cursor1 ++;
+ if ( m_cursor1 > m_len ) m_cursor1 = m_len;
+ }
+ }
+
+ if ( !bSelect ) m_cursor2 = m_cursor1;
+
+ m_bUndoForce = TRUE;
+ Justif();
+ ColumnFix();
+}
+
+// Moves the cursor lines.
+
+void CEdit::MoveLine(int move, BOOL bWord, BOOL bSelect)
+{
+ float column, indentLength;
+ int i, line, c;
+
+ if ( move == 0 ) return;
+
+ for ( i=0 ; i>move ; i-- ) // back?
+ {
+ while ( m_cursor1 > 0 && m_text[m_cursor1-1] != '\n' )
+ {
+ m_cursor1 --;
+ }
+ if ( m_cursor1 != 0 )
+ {
+ m_cursor1 --;
+ while ( m_cursor1 > 0 )
+ {
+ if ( m_text[--m_cursor1] == '\n' )
+ {
+ m_cursor1 ++;
+ break;
+ }
+ }
+ }
+ }
+
+ for ( i=0 ; i<move ; i++ ) // advance?
+ {
+ while ( m_cursor1 < m_len )
+ {
+ if ( m_text[m_cursor1++] == '\n' )
+ {
+ break;
+ }
+ }
+ }
+
+ line = RetCursorLine(m_cursor1);
+
+ column = m_column;
+ if ( m_bAutoIndent )
+ {
+ indentLength = m_engine->RetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType)
+ * m_engine->RetEditIndentValue();
+ column -= indentLength*m_lineIndent[line];
+ }
+
+ if ( m_format == 0 )
+ {
+ c = m_engine->RetText()->Detect(m_text+m_lineOffset[line],
+ m_lineOffset[line+1]-m_lineOffset[line],
+ column, m_fontSize,
+ m_fontStretch, m_fontType);
+ }
+ else
+ {
+ c = m_engine->RetText()->Detect(m_text+m_lineOffset[line],
+ m_format+m_lineOffset[line],
+ m_lineOffset[line+1]-m_lineOffset[line],
+ column, m_fontSize, m_fontStretch);
+ }
+
+ m_cursor1 = m_lineOffset[line]+c;
+ if ( !bSelect ) m_cursor2 = m_cursor1;
+
+ m_bUndoForce = TRUE;
+ Justif();
+}
+
+// Sets the horizontal position.
+
+void CEdit::ColumnFix()
+{
+ float indentLength;
+ int line;
+
+ line = RetCursorLine(m_cursor1);
+
+ if ( m_format == 0 )
+ {
+ m_column = m_engine->RetText()->RetStringWidth
+ (
+ m_text+m_lineOffset[line],
+ m_cursor1-m_lineOffset[line],
+ m_fontSize, m_fontStretch, m_fontType
+ );
+ }
+ else
+ {
+ m_column = m_engine->RetText()->RetStringWidth
+ (
+ m_text+m_lineOffset[line],
+ m_format+m_lineOffset[line],
+ m_cursor1-m_lineOffset[line],
+ m_fontSize, m_fontStretch
+ );
+ }
+
+ if ( m_bAutoIndent )
+ {
+ indentLength = m_engine->RetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType)
+ * m_engine->RetEditIndentValue();
+ m_column += indentLength*m_lineIndent[line];
+ }
+}
+
+
+// Cut the selected characters or entire line.
+
+BOOL CEdit::Cut()
+{
+ HGLOBAL hg;
+ char* text;
+ char c;
+ int c1, c2, start, len, i, j;
+
+ if ( !m_bEdit ) return FALSE;
+
+ c1 = m_cursor1;
+ c2 = m_cursor2;
+ if ( c1 > c2 ) Swap(c1, c2); // always c1 <= c2
+
+ if ( c1 == c2 )
+ {
+ while ( c1 > 0 )
+ {
+ if ( m_text[c1-1] == '\n' ) break;
+ c1 --;
+ }
+ while ( c2 < m_len )
+ {
+ c2 ++;
+ if ( m_text[c2-1] == '\n' ) break;
+ }
+ }
+
+ if ( c1 == c2 ) return FALSE;
+
+ start = c1;
+ len = c2-c1;
+
+ if ( !(hg = GlobalAlloc(GMEM_DDESHARE, len*2+1)) )
+ {
+ return FALSE;
+ }
+ if ( !(text = (char*)GlobalLock(hg)) )
+ {
+ GlobalFree(hg);
+ return FALSE;
+ }
+
+ j = 0;
+ for ( i=start ; i<start+len ; i++ )
+ {
+ c = m_text[i];
+ if ( c == '\n' ) text[j++] = '\r';
+ text[j++] = c;
+ }
+ text[j] = 0;
+ GlobalUnlock(hg);
+
+ if ( !OpenClipboard(NULL) )
+ {
+ GlobalFree(hg);
+ return FALSE;
+ }
+ if ( !EmptyClipboard() )
+ {
+ GlobalFree(hg);
+ return FALSE;
+ }
+ if ( !SetClipboardData(CF_TEXT, hg) )
+ {
+ GlobalFree(hg);
+ return FALSE;
+ }
+ CloseClipboard();
+
+ UndoMemorize(OPERUNDO_SPEC);
+ m_cursor1 = c1;
+ m_cursor2 = c2;
+ DeleteOne(0); // deletes the selected characters
+ Justif();
+ ColumnFix();
+ SendModifEvent();
+ return TRUE;
+}
+
+// Copy the selected characters or entire line.
+
+BOOL CEdit::Copy()
+{
+ HGLOBAL hg;
+ char* text;
+ char c;
+ int c1, c2, start, len, i, j;
+
+ c1 = m_cursor1;
+ c2 = m_cursor2;
+ if ( c1 > c2 ) Swap(c1, c2); // always c1 <= c2
+
+ if ( c1 == c2 )
+ {
+ while ( c1 > 0 )
+ {
+ if ( m_text[c1-1] == '\n' ) break;
+ c1 --;
+ }
+ while ( c2 < m_len )
+ {
+ c2 ++;
+ if ( m_text[c2-1] == '\n' ) break;
+ }
+ }
+
+ if ( c1 == c2 ) return FALSE;
+
+ start = c1;
+ len = c2-c1;
+
+ if ( !(hg = GlobalAlloc(GMEM_DDESHARE, len*2+1)) )
+ {
+ return FALSE;
+ }
+ if ( !(text = (char*)GlobalLock(hg)) )
+ {
+ GlobalFree(hg);
+ return FALSE;
+ }
+
+ j = 0;
+ for ( i=start ; i<start+len ; i++ )
+ {
+ c = m_text[i];
+ if ( c == '\n' ) text[j++] = '\r';
+ text[j++] = c;
+ }
+ text[j] = 0;
+ GlobalUnlock(hg);
+
+ if ( !OpenClipboard(NULL) )
+ {
+ GlobalFree(hg);
+ return FALSE;
+ }
+ if ( !EmptyClipboard() )
+ {
+ GlobalFree(hg);
+ return FALSE;
+ }
+ if ( !SetClipboardData(CF_TEXT, hg) )
+ {
+ GlobalFree(hg);
+ return FALSE;
+ }
+ CloseClipboard();
+
+ return TRUE;
+}
+
+// Paste the contents of the notebook.
+
+BOOL CEdit::Paste()
+{
+ HANDLE h;
+ char c;
+ char* p;
+
+ if ( !m_bEdit ) return FALSE;
+
+ if ( !OpenClipboard(NULL) )
+ {
+ return FALSE;
+ }
+
+ if ( !(h = GetClipboardData(CF_TEXT)) )
+ {
+ CloseClipboard();
+ return FALSE;
+ }
+
+ if ( !(p = (char*)GlobalLock(h)) )
+ {
+ CloseClipboard();
+ return FALSE;
+ }
+
+ UndoMemorize(OPERUNDO_SPEC);
+
+ while ( *p != 0 )
+ {
+ c = *p++;
+ if ( c == '\r' ) continue;
+ if ( c == '\t' && m_bAutoIndent ) continue;
+ InsertOne(c);
+ }
+
+ GlobalUnlock(h);
+ CloseClipboard();
+
+ Justif();
+ ColumnFix();
+ SendModifEvent();
+ return TRUE;
+}
+
+
+// Cancels the last action.
+
+BOOL CEdit::Undo()
+{
+ if ( !m_bEdit ) return FALSE;
+
+ return UndoRecall();
+}
+
+
+// Inserts a character.
+
+void CEdit::Insert(char character)
+{
+ int i, level, tab;
+
+ if ( !m_bEdit ) return;
+
+ if ( !m_bMulti ) // single-line?
+ {
+ if ( character == '\n' ||
+ character == '\t' ) return;
+ }
+
+ UndoMemorize(OPERUNDO_INSERT);
+
+ if ( m_bMulti && !m_bAutoIndent )
+ {
+ if ( character == '\n' )
+ {
+ InsertOne(character);
+ level = IndentCompute();
+ for ( i=0 ; i<level ; i++ )
+ {
+ InsertOne('\t');
+ }
+ }
+ else if ( character == '{' )
+ {
+ tab = IndentTabCount();
+ if ( tab != -1 )
+ {
+ level = IndentCompute();
+ IndentTabAdjust(level-tab);
+ }
+ InsertOne(character);
+ }
+ else if ( character == '}' )
+ {
+ tab = IndentTabCount();
+ if ( tab != -1 )
+ {
+ level = IndentCompute()-1;
+ IndentTabAdjust(level-tab);
+ }
+ InsertOne(character);
+ }
+ else
+ {
+ InsertOne(character);
+ }
+ }
+ else if ( m_bAutoIndent )
+ {
+ if ( character == '{' )
+ {
+ InsertOne(character);
+ InsertOne('\n');
+ InsertOne('\n');
+ InsertOne('}');
+ MoveChar(-1, FALSE, FALSE);
+ MoveChar(-1, FALSE, FALSE);
+ }
+#if 0
+ else if ( character == '(' )
+ {
+ InsertOne(character);
+ InsertOne(')');
+ MoveChar(-1, FALSE, FALSE);
+ }
+ else if ( character == '[' )
+ {
+ InsertOne(character);
+ InsertOne(']');
+ MoveChar(-1, FALSE, FALSE);
+ }
+#endif
+ else if ( character == '\t' )
+ {
+ for ( i=0 ; i<m_engine->RetEditIndentValue() ; i++ )
+ {
+ InsertOne(' ');
+ }
+ }
+ else
+ {
+ InsertOne(character);
+ }
+ }
+ else
+ {
+ InsertOne(character);
+ }
+
+ Justif();
+ ColumnFix();
+}
+
+// Inserts a plain character.
+
+void CEdit::InsertOne(char character)
+{
+ int i;
+
+ if ( !m_bEdit ) return;
+ if ( !m_bMulti && character == '\n' ) return;
+
+ if ( m_cursor1 != m_cursor2 )
+ {
+ DeleteOne(0); // deletes the selected characters
+ }
+
+ if ( m_len >= m_maxChar ) return;
+
+ for ( i=m_len ; i>=m_cursor1 ; i-- )
+ {
+ m_text[i] = m_text[i-1]; // shoot
+
+ if ( m_format != 0 )
+ {
+ m_format[i] = m_format[i-1]; // shoot
+ }
+ }
+
+ m_len ++;
+
+ m_text[m_cursor1] = character;
+
+ if ( m_format != 0 )
+ {
+ m_format[m_cursor1] = 0;
+ }
+
+ m_cursor1++;
+ m_cursor2 = m_cursor1;
+}
+
+// Deletes the character left of cursor or all selected characters.
+
+void CEdit::Delete(int dir)
+{
+ if ( !m_bEdit ) return;
+
+ UndoMemorize(OPERUNDO_DELETE);
+ DeleteOne(dir);
+
+ Justif();
+ ColumnFix();
+}
+
+// Deletes the character left of cursor or all selected plain characters.
+
+void CEdit::DeleteOne(int dir)
+{
+ int i, end, hole;
+
+ if ( !m_bEdit ) return;
+
+ if ( m_cursor1 == m_cursor2 )
+ {
+ if ( dir < 0 )
+ {
+ if ( m_cursor1 == 0 ) return;
+ m_cursor1 --;
+ }
+ else
+ {
+ if ( m_cursor2 == m_len ) return;
+ m_cursor2 ++;
+ }
+ }
+
+ if ( m_cursor1 > m_cursor2 ) Swap(m_cursor1, m_cursor2);
+ hole = m_cursor2-m_cursor1;
+ end = m_len-hole;
+ for ( i=m_cursor1 ; i<end ; i++ )
+ {
+ m_text[i] = m_text[i+hole];
+
+ if ( m_format != 0 )
+ {
+ m_format[i] = m_format[i+hole];
+ }
+ }
+ m_len -= hole;
+ m_cursor2 = m_cursor1;
+}
+
+
+// Calculates the indentation level of brackets {and}.
+
+int CEdit::IndentCompute()
+{
+ int i, level;
+
+ level = 0;
+ for ( i=0 ; i<m_cursor1 ; i++ )
+ {
+ if ( m_text[i] == '{' ) level ++;
+ if ( m_text[i] == '}' ) level --;
+ }
+
+ if ( level < 0 ) level = 0;
+ return level;
+}
+
+// Counts the number of tabs before the cursor.
+// Returns -1 if there is something else.
+
+int CEdit::IndentTabCount()
+{
+ int i, nb;
+
+ if ( m_cursor1 != m_cursor2 ) return -1;
+
+ i = m_cursor1;
+ nb = 0;
+ while ( i > 0 )
+ {
+ if ( m_text[i-1] == '\n' ) return nb;
+ if ( m_text[i-1] != '\t' ) return -1;
+ nb ++;
+ i --;
+ }
+ return nb;
+}
+
+// Adds or removes qq tabs.
+
+void CEdit::IndentTabAdjust(int number)
+{
+ int i;
+
+ for ( i=0 ; i<number ; i++ ) // add?
+ {
+ InsertOne('\t');
+ }
+
+ for ( i=0 ; i>number ; i-- ) // delete?
+ {
+ DeleteOne(-1);
+ }
+}
+
+
+// Indent the left or right the entire selection.
+
+BOOL CEdit::Shift(BOOL bLeft)
+{
+ BOOL bInvert = FALSE;
+ int c1, c2, i;
+
+ if ( m_cursor1 == m_cursor2 ) return FALSE;
+
+ UndoMemorize(OPERUNDO_SPEC);
+
+ c1 = m_cursor1;
+ c2 = m_cursor2;
+ if ( c1 > c2 )
+ {
+ Swap(c1, c2); // always c1 <= c2
+ bInvert = TRUE;
+ }
+
+ if ( c1 > 0 )
+ {
+ if ( m_text[c1-1] != '\n' ) return FALSE;
+ }
+ if ( c2 < m_len )
+ {
+ if ( m_text[c2-1] != '\n' ) return FALSE;
+ }
+
+ if ( bLeft ) // shifts left?
+ {
+ i = c1;
+ while ( i < c2 )
+ {
+ if ( m_text[i] == '\t' )
+ {
+ m_cursor1 = i;
+ m_cursor2 = i+1;
+ DeleteOne(0);
+ c2 --;
+ }
+ while ( i < c2 && m_text[i++] != '\n' );
+ }
+ }
+ else // shifts right?
+ {
+ i = c1;
+ while ( i < c2 )
+ {
+ m_cursor1 = m_cursor2 = i;
+ InsertOne('\t');
+ c2 ++;
+ while ( i < c2 && m_text[i++] != '\n' );
+ }
+ }
+
+ if ( bInvert ) Swap(c1, c2);
+ m_cursor1 = c1;
+ m_cursor2 = c2;
+
+ Justif();
+ ColumnFix();
+ SendModifEvent();
+ return TRUE;
+}
+
+// Min conversion <-> shift the selection.
+
+BOOL CEdit::MinMaj(BOOL bMaj)
+{
+ int c1, c2, i, character;
+
+ if ( m_cursor1 == m_cursor2 ) return FALSE;
+
+ UndoMemorize(OPERUNDO_SPEC);
+
+ c1 = m_cursor1;
+ c2 = m_cursor2;
+ if ( c1 > c2 ) Swap(c1, c2); // alwyas c1 <= c2
+
+ for ( i=c1 ; i<c2 ; i++ )
+ {
+ character = (unsigned char)m_text[i];
+ if ( bMaj ) character = RetToUpper(character);
+ else character = RetToLower(character);
+ m_text[i] = character;
+ }
+
+ Justif();
+ ColumnFix();
+ SendModifEvent();
+ return TRUE;
+}
+
+
+// Cut all text lines.
+
+void CEdit::Justif()
+{
+ float width, value, size, indentLength;
+ int i, j, line, indent;
+ BOOL bDual, bString, bRem;
+
+ indent = 0;
+ m_lineTotal = 0;
+ m_lineOffset[m_lineTotal] = 0;
+ m_lineIndent[m_lineTotal] = indent;
+ m_lineTotal ++;
+
+ if ( m_bAutoIndent )
+ {
+ indentLength = m_engine->RetText()->RetCharWidth(' ', 0.0f, m_fontSize, m_fontStretch, m_fontType)
+ * m_engine->RetEditIndentValue();
+ }
+
+ bString = bRem = FALSE;
+ i = 0;
+ while ( TRUE )
+ {
+ bDual = FALSE;
+
+ width = m_dim.x-(10.0f/640.0f)*2.0f-(m_bMulti?MARGX*2.0f+SCROLL_WIDTH:0.0f);
+ if ( m_bAutoIndent )
+ {
+ width -= indentLength*m_lineIndent[m_lineTotal-1];
+ }
+
+ if ( m_format == 0 )
+ {
+ i += m_engine->RetText()->Justif(m_text+i, m_len-i, width,
+ m_fontSize, m_fontStretch,
+ m_fontType);
+ }
+ else
+ {
+ size = m_fontSize;
+
+ if ( (m_format[i]&TITLE_MASK) == TITLE_BIG ) // headline?
+ {
+ size *= BIG_FONT;
+ bDual = TRUE;
+ }
+
+ if ( (m_format[i]&IMAGE_MASK) != 0 ) // image part?
+ {
+ i ++; // jumps just a character (index in m_image)
+ }
+ else
+ {
+ i += m_engine->RetText()->Justif(m_text+i, m_format+i,
+ m_len-i, width,
+ size, m_fontStretch);
+ }
+ }
+
+ if ( i >= m_len ) break;
+
+ if ( m_bAutoIndent )
+ {
+ for ( j=m_lineOffset[m_lineTotal-1] ; j<i ; j++ )
+ {
+ if ( !bRem && m_text[j] == '\"' ) bString = !bString;
+ if ( !bString &&
+ m_text[j] == '/' &&
+ m_text[j+1] == '/' ) bRem = TRUE;
+ if ( m_text[j] == '\n' ) bString = bRem = FALSE;
+ if ( m_text[j] == '{' && !bString && !bRem ) indent ++;
+ if ( m_text[j] == '}' && !bString && !bRem ) indent --;
+ }
+ if ( indent < 0 ) indent = 0;
+ }
+
+ m_lineOffset[m_lineTotal] = i;
+ m_lineIndent[m_lineTotal] = indent;
+ m_lineTotal ++;
+ if ( bDual )
+ {
+ m_lineOffset[m_lineTotal] = i;
+ m_lineIndent[m_lineTotal] = indent;
+ m_lineTotal ++;
+ }
+ if ( m_lineTotal >= EDITLINEMAX-2 ) break;
+ }
+ if ( m_len > 0 && m_text[m_len-1] == '\n' )
+ {
+ m_lineOffset[m_lineTotal] = m_len;
+ m_lineIndent[m_lineTotal] = 0;
+ m_lineTotal ++;
+ }
+ m_lineOffset[m_lineTotal] = m_len;
+ m_lineIndent[m_lineTotal] = 0;
+
+ if ( m_bAutoIndent )
+ {
+ for ( i=0 ; i<=m_lineTotal ; i++ )
+ {
+ if ( m_text[m_lineOffset[i]] == '}' )
+ {
+ if ( m_lineIndent[i] > 0 ) m_lineIndent[i] --;
+ }
+ }
+ }
+
+ if ( m_bMulti )
+ {
+ if ( m_bEdit )
+ {
+ line = RetCursorLine(m_cursor1);
+ if ( line < m_lineFirst )
+ {
+ m_lineFirst = line;
+ }
+ if ( line >= m_lineFirst+m_lineVisible )
+ {
+ m_lineFirst = line-m_lineVisible+1;
+ }
+ }
+ }
+ else
+ {
+ m_lineFirst = 0;
+ }
+
+ if ( m_scroll != 0 )
+ {
+ if ( m_lineTotal <= m_lineVisible )
+ {
+ m_scroll->SetVisibleRatio(1.0f);
+ m_scroll->SetVisibleValue(0.0f);
+ m_scroll->SetArrowStep(0.0f);
+ }
+ else
+ {
+ value = (float)m_lineVisible/m_lineTotal;
+ m_scroll->SetVisibleRatio(value);
+
+ value = (float)m_lineFirst/(m_lineTotal-m_lineVisible);
+ m_scroll->SetVisibleValue(value);
+
+ value = (float)1.0f/(m_lineTotal-m_lineVisible);
+ m_scroll->SetArrowStep(value);
+ }
+ }
+
+ m_timeBlink = 0.0f; // lights the cursor immediately
+}
+
+// Returns the rank of the line where the cursor is located.
+
+int CEdit::RetCursorLine(int cursor)
+{
+ int line, i;
+
+ line = 0;
+ for ( i=0 ; i<m_lineTotal ; i++ )
+ {
+ if ( cursor >= m_lineOffset[i] )
+ {
+ line = i;
+ }
+ }
+ return line;
+}
+
+
+// Flush the buffer undo.
+
+void CEdit::UndoFlush()
+{
+ int i;
+
+ for ( i=0 ; i<EDITUNDOMAX ; i++ )
+ {
+ delete m_undo[i].text;
+ m_undo[i].text = 0;
+ }
+
+ m_bUndoForce = TRUE;
+ m_undoOper = OPERUNDO_SPEC;
+}
+
+// Memorize the current state before a change.
+
+void CEdit::UndoMemorize(OperUndo oper)
+{
+ int i, len;
+
+ if ( !m_bUndoForce &&
+ oper != OPERUNDO_SPEC &&
+ m_undoOper != OPERUNDO_SPEC &&
+ oper == m_undoOper ) return;
+
+ m_bUndoForce = FALSE;
+ m_undoOper = oper;
+
+ delete m_undo[EDITUNDOMAX-1].text;
+
+ for ( i=EDITUNDOMAX-1 ; i>=1 ; i-- )
+ {
+ m_undo[i] = m_undo[i-1];
+ }
+
+ len = m_len;
+ if ( len == 0 ) len ++;
+ m_undo[0].text = (char*)malloc(sizeof(char)*(len+1));
+ memcpy(m_undo[0].text, m_text, m_len);
+ m_undo[0].len = m_len;
+
+ m_undo[0].cursor1 = m_cursor1;
+ m_undo[0].cursor2 = m_cursor2;
+ m_undo[0].lineFirst = m_lineFirst;
+}
+
+// Back to previous state.
+
+BOOL CEdit::UndoRecall()
+{
+ int i;
+
+ if ( m_undo[0].text == 0 ) return FALSE;
+
+ m_len = m_undo[0].len;
+ memcpy(m_text, m_undo[0].text, m_len);
+
+ m_cursor1 = m_undo[0].cursor1;
+ m_cursor2 = m_undo[0].cursor2;
+ m_lineFirst = m_undo[0].lineFirst;
+
+ for ( i=0 ; i<EDITUNDOMAX-1 ; i++ )
+ {
+ m_undo[i] = m_undo[i+1];
+ }
+ m_undo[EDITUNDOMAX-1].text = 0;
+
+ m_bUndoForce = TRUE;
+ Justif();
+ ColumnFix();
+ SendModifEvent();
+ return TRUE;
+}
+
+
+// Clears the format of all characters.
+
+BOOL CEdit::ClearFormat()
+{
+ if ( m_format == 0 )
+ {
+ SetMultiFont(TRUE);
+ }
+ memset(m_format, m_fontType, m_len);
+
+ return TRUE;
+}
+
+// Changes the format of a sequence of characters.
+
+BOOL CEdit::SetFormat(int cursor1, int cursor2, int format)
+{
+ int i;
+
+ if ( m_format == 0 ) return FALSE;
+
+ for ( i=cursor1 ; i<cursor2 ; i++ )
+ {
+ m_format[i] |= format;
+ }
+
+ return TRUE;
+}
+
+
diff --git a/src/ui/edit.h b/src/ui/edit.h
new file mode 100644
index 0000000..4ad884f
--- /dev/null
+++ b/src/ui/edit.h
@@ -0,0 +1,255 @@
+// * 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/.
+
+// edit.h
+
+#ifndef _EDIT_H_
+#define _EDIT_H_
+
+
+#include "struct.h"
+#include "control.h"
+
+
+class CD3DEngine;
+class CScroll;
+
+
+
+#define EDITSTUDIOMAX 20000 // maximum number of characters in CBOT edit
+#define EDITLINEMAX 1000 // maximum total number of lines
+#define EDITIMAGEMAX 50 // maximum total number of lines with images
+#define EDITLINKMAX 100 // maximum number of links
+#define EDITHISTORYMAX 50 // max number of levels preserves
+
+#define EDITUNDOMAX 20 // max number of successive undo
+
+typedef struct
+{
+ char* text; // original text
+ int len; // length of the text
+ int cursor1; // offset cursor
+ int cursor2; // offset cursor
+ int lineFirst; // the first line displayed.
+
+}
+EditUndo;
+
+enum OperUndo
+{
+ OPERUNDO_SPEC = 0, // special operation
+ OPERUNDO_INSERT = 1, // inserting characters
+ OPERUNDO_DELETE = 2, // deleting characters
+};
+
+typedef struct
+{
+ char name[40]; // name of the image (without diagram \)
+ float offset; // vertical offset (v texture)
+ float height; // height of the part (dv texture)
+ float width; // width
+}
+ImageLine;
+
+typedef struct
+{
+ char name[40]; // text file name (without help \)
+ char marker[20]; // name of the marker
+}
+HyperLink;
+
+typedef struct
+{
+ char name[20]; // name of the marker
+ int pos; // position in the text
+}
+HyperMarker;
+
+typedef struct
+{
+ char filename[50]; // full file name text
+ int firstLine; // rank of the first displayed line
+}
+HyperHistory;
+
+
+
+
+class CEdit : public CControl
+{
+public:
+ CEdit(CInstanceManager* iMan);
+ virtual ~CEdit();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ void SetPos(FPOINT pos);
+ void SetDim(FPOINT dim);
+
+ BOOL EventProcess(const Event &event);
+ void Draw();
+
+ void SetText(char *text, BOOL bNew=TRUE);
+ void GetText(char *buffer, int max);
+ char* RetText();
+ int RetTextLength();
+
+ BOOL ReadText(char *filename, int addSize=0);
+ BOOL WriteText(char *filename);
+
+ void SetMaxChar(int max);
+ int RetMaxChar();
+
+ void SetEditCap(BOOL bMode);
+ BOOL RetEditCap();
+
+ void SetHiliteCap(BOOL bEnable);
+ BOOL RetHiliteCap();
+
+ void SetInsideScroll(BOOL bInside);
+ BOOL RetInsideScroll();
+
+ void SetSoluceMode(BOOL bSoluce);
+ BOOL RetSoluceMode();
+
+ void SetGenericMode(BOOL bGeneric);
+ BOOL RetGenericMode();
+
+ void SetAutoIndent(BOOL bMode);
+ BOOL RetAutoIndent();
+
+ void SetCursor(int cursor1, int cursor2);
+ void GetCursor(int &cursor1, int &cursor2);
+
+ void SetFirstLine(int rank);
+ int RetFirstLine();
+ void ShowSelect();
+
+ void SetDisplaySpec(BOOL bDisplay);
+ BOOL RetDisplaySpec();
+
+ void SetMultiFont(BOOL bMulti);
+ BOOL RetMultiFont();
+
+ BOOL Cut();
+ BOOL Copy();
+ BOOL Paste();
+ BOOL Undo();
+
+ void HyperFlush();
+ void HyperHome(char *filename);
+ BOOL HyperTest(EventMsg event);
+ BOOL HyperGo(EventMsg event);
+
+ void SetFontSize(float size);
+
+ BOOL ClearFormat();
+ BOOL SetFormat(int cursor1, int cursor2, int format);
+
+protected:
+ void SendModifEvent();
+ BOOL IsLinkPos(FPOINT pos);
+ void MouseDoubleClick(FPOINT mouse);
+ void MouseClick(FPOINT mouse);
+ void MouseMove(FPOINT mouse);
+ void MouseRelease(FPOINT mouse);
+ int MouseDetect(FPOINT mouse);
+ void MoveAdjust();
+
+ void HyperJump(char *name, char *marker);
+ BOOL HyperAdd(char *filename, int firstLine);
+
+ void DrawImage(FPOINT pos, char *name, float width, float offset, float height, int nbLine);
+ void DrawBack(FPOINT pos, FPOINT dim);
+ void DrawPart(FPOINT pos, FPOINT dim, int icon);
+
+ void FreeImage();
+ void LoadImage(char *name);
+ void Scroll(int pos, BOOL bAdjustCursor);
+ void Scroll();
+ void MoveChar(int move, BOOL bWord, BOOL bSelect);
+ void MoveLine(int move, BOOL bWord, BOOL bSelect);
+ void MoveHome(BOOL bWord, BOOL bSelect);
+ void MoveEnd(BOOL bWord, BOOL bSelect);
+ void ColumnFix();
+ void Insert(char character);
+ void InsertOne(char character);
+ void Delete(int dir);
+ void DeleteOne(int dir);
+ int IndentCompute();
+ int IndentTabCount();
+ void IndentTabAdjust(int number);
+ BOOL Shift(BOOL bLeft);
+ BOOL MinMaj(BOOL bMaj);
+ void Justif();
+ int RetCursorLine(int cursor);
+
+ void UndoFlush();
+ void UndoMemorize(OperUndo oper);
+ BOOL UndoRecall();
+
+protected:
+ CScroll* m_scroll; // vertical scrollbar on the right
+
+ int m_maxChar; // max length of the buffer m_text
+ char* m_text; // text (without zero terminator)
+ char* m_format; // format characters
+ int m_len; // length used in m_text
+ int m_cursor1; // offset cursor
+ int m_cursor2; // offset cursor
+
+ BOOL m_bMulti; // TRUE -> multi-line
+ BOOL m_bEdit; // TRUE -> editable
+ BOOL m_bHilite; // TRUE -> hilitable
+ BOOL m_bInsideScroll; // TRUE -> lift as part
+ BOOL m_bDisplaySpec; // TRUE -> displays the special characters
+ BOOL m_bMultiFont; // TRUE -> more fonts possible
+ BOOL m_bSoluce; // TRUE -> shows the links-solution
+ BOOL m_bGeneric; // TRUE -> generic that defile
+ BOOL m_bAutoIndent; // TRUE -> automatic indentation
+ float m_lineHeight; // height of a row
+ float m_lineAscent; // height above the baseline
+ float m_lineDescent; // height below the baseline
+ int m_lineVisible; // total number of viewable lines
+ int m_lineFirst; // the first line displayed
+ int m_lineTotal; // number lines used (in m_lineOffset)
+ int m_lineOffset[EDITLINEMAX];
+ char m_lineIndent[EDITLINEMAX];
+ int m_imageTotal;
+ ImageLine m_image[EDITIMAGEMAX];
+ HyperLink m_link[EDITLINKMAX];
+ int m_markerTotal;
+ HyperMarker m_marker[EDITLINKMAX];
+ int m_historyTotal;
+ int m_historyCurrent;
+ HyperHistory m_history[EDITHISTORYMAX];
+ float m_time; // absolute time
+ float m_timeBlink;
+ float m_timeLastClick;
+ float m_timeLastScroll;
+ FPOINT m_mouseFirstPos;
+ FPOINT m_mouseLastPos;
+ float m_column;
+
+ BOOL m_bCapture;
+
+ BOOL m_bUndoForce;
+ OperUndo m_undoOper;
+ EditUndo m_undo[EDITUNDOMAX];
+};
+
+
+#endif //_EDIT_H_
diff --git a/src/ui/editvalue.cpp b/src/ui/editvalue.cpp
new file mode 100644
index 0000000..ce8515c
--- /dev/null
+++ b/src/ui/editvalue.cpp
@@ -0,0 +1,380 @@
+// * 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/.
+
+// editvalue.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "edit.h"
+#include "button.h"
+#include "editvalue.h"
+
+
+
+
+// Object's constructor.
+
+CEditValue::CEditValue(CInstanceManager* iMan) : CControl(iMan)
+{
+ m_edit = 0;
+ m_buttonUp = 0;
+ m_buttonDown = 0;
+
+ m_type = EVT_100; // %
+ m_stepValue = 0.1f; // 10%
+ m_minValue = 0.0f; // 0%
+ m_maxValue = 1.0f; // 100%
+}
+
+// Object's destructor.
+
+CEditValue::~CEditValue()
+{
+ delete m_edit;
+ delete m_buttonUp;
+ delete m_buttonDown;
+}
+
+
+// Creates a new button.
+
+BOOL CEditValue::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CEdit* pe;
+ CButton* pc;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+ CControl::Create(pos, dim, icon, eventMsg);
+
+ GlintDelete();
+
+ m_edit = new CEdit(m_iMan);
+ pe = (CEdit*)m_edit;
+ pe->Create(pos, dim, 0, EVENT_NULL);
+ pe->SetMaxChar(4);
+
+ m_buttonUp = new CButton(m_iMan);
+ pc = (CButton*)m_buttonUp;
+ pc->Create(pos, dim, 49, EVENT_NULL); // ^
+ pc->SetRepeat(TRUE);
+
+ m_buttonDown = new CButton(m_iMan);
+ pc = (CButton*)m_buttonDown;
+ pc->Create(pos, dim, 50, EVENT_NULL); // v
+ pc->SetRepeat(TRUE);
+
+ MoveAdjust();
+ return TRUE;
+}
+
+
+void CEditValue::SetPos(FPOINT pos)
+{
+ CControl::SetPos(pos);
+ MoveAdjust();
+}
+
+void CEditValue::SetDim(FPOINT dim)
+{
+ CControl::SetDim(dim);
+ MoveAdjust();
+}
+
+void CEditValue::MoveAdjust()
+{
+ FPOINT pos, dim;
+
+ if ( m_edit != 0 )
+ {
+ pos.x = m_pos.x;
+ pos.y = m_pos.y;
+ dim.x = m_dim.x-m_dim.y*0.6f;
+ dim.y = m_dim.y;
+ m_edit->SetPos(pos);
+ m_edit->SetDim(dim);
+ }
+
+ if ( m_buttonUp != 0 )
+ {
+ pos.x = m_pos.x+m_dim.x-m_dim.y*0.6f;
+ pos.y = m_pos.y+m_dim.y*0.5f;
+ dim.x = m_dim.y*0.6f;
+ dim.y = m_dim.y*0.5f;
+ m_buttonUp->SetPos(pos);
+ m_buttonUp->SetDim(dim);
+ }
+
+ if ( m_buttonDown != 0 )
+ {
+ pos.x = m_pos.x+m_dim.x-m_dim.y*0.6f;
+ pos.y = m_pos.y;
+ dim.x = m_dim.y*0.6f;
+ dim.y = m_dim.y*0.5f;
+ m_buttonDown->SetPos(pos);
+ m_buttonDown->SetDim(dim);
+ }
+}
+
+
+// Management of an event.
+
+BOOL CEditValue::EventProcess(const Event &event)
+{
+ float value;
+
+ CControl::EventProcess(event);
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE;
+ if ( (m_state & STATE_ENABLE) == 0 ) return TRUE;
+
+ if ( m_edit != 0 )
+ {
+ if ( m_edit->RetFocus() &&
+ event.event == EVENT_KEYDOWN &&
+ event.param == VK_RETURN )
+ {
+ value = RetValue();
+ if ( value > m_maxValue ) value = m_maxValue;
+ if ( value < m_minValue ) value = m_minValue;
+ SetValue(value, TRUE);
+ HiliteValue(event);
+ }
+ if ( !m_edit->EventProcess(event) ) return FALSE;
+
+ if ( event.event == m_edit->RetEventMsg() )
+ {
+ Event newEvent;
+ m_event->MakeEvent(newEvent, m_eventMsg);
+ m_event->AddEvent(newEvent);
+ }
+ }
+
+ if ( m_buttonUp != 0 )
+ {
+ if ( event.event == m_buttonUp->RetEventMsg() )
+ {
+ value = RetValue()+m_stepValue;
+ if ( value > m_maxValue ) value = m_maxValue;
+ SetValue(value, TRUE);
+ HiliteValue(event);
+ }
+ if ( !m_buttonUp->EventProcess(event) ) return FALSE;
+ }
+
+ if ( m_buttonDown != 0 )
+ {
+ if ( event.event == m_buttonDown->RetEventMsg() )
+ {
+ value = RetValue()-m_stepValue;
+ if ( value < m_minValue ) value = m_minValue;
+ SetValue(value, TRUE);
+ HiliteValue(event);
+ }
+ if ( !m_buttonDown->EventProcess(event) ) return FALSE;
+ }
+
+ if ( event.event == EVENT_KEYDOWN &&
+ event.param == VK_WHEELUP &&
+ Detect(event.pos) )
+ {
+ value = RetValue()+m_stepValue;
+ if ( value > m_maxValue ) value = m_maxValue;
+ SetValue(value, TRUE);
+ HiliteValue(event);
+ }
+ if ( event.event == EVENT_KEYDOWN &&
+ event.param == VK_WHEELDOWN &&
+ Detect(event.pos) )
+ {
+ value = RetValue()-m_stepValue;
+ if ( value < m_minValue ) value = m_minValue;
+ SetValue(value, TRUE);
+ HiliteValue(event);
+ }
+
+ return TRUE;
+}
+
+
+// Puts in evidence the edited value.
+
+void CEditValue::HiliteValue(const Event &event)
+{
+ int pos;
+
+ if ( m_edit == 0 ) return;
+
+ pos = m_edit->RetTextLength();
+ if ( m_type == EVT_100 && pos > 0 )
+ {
+ pos --; // not only selects the "%"
+ }
+
+ m_edit->SetCursor(pos, 0);
+ m_edit->SetFocus(TRUE);
+
+ Event newEvent = event;
+ newEvent.event = EVENT_FOCUS;
+ newEvent.param = m_edit->RetEventMsg();
+ m_event->AddEvent(newEvent); // defocus the other objects
+}
+
+
+// Draw button.
+
+void CEditValue::Draw()
+{
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ if ( m_state & STATE_SHADOW )
+ {
+ DrawShadow(m_pos, m_dim);
+ }
+
+ if ( m_edit != 0 )
+ {
+ m_edit->Draw();
+ }
+ if ( m_buttonUp != 0 )
+ {
+ m_buttonUp->Draw();
+ }
+ if ( m_buttonDown != 0 )
+ {
+ m_buttonDown->Draw();
+ }
+}
+
+
+// Choosing the type of value.
+
+void CEditValue::SetType(EditValueType type)
+{
+ m_type = type;
+}
+
+EditValueType CEditValue::RetType()
+{
+ return m_type;
+}
+
+
+// Changes the value.
+
+void CEditValue::SetValue(float value, BOOL bSendMessage)
+{
+ char text[100];
+
+ if ( m_edit == 0 ) return;
+
+ text[0] = 0;
+
+ if ( m_type == EVT_INT )
+ {
+ sprintf(text, "%d", (int)value);
+ }
+
+ if ( m_type == EVT_FLOAT )
+ {
+ sprintf(text, "%.2f", value);
+ }
+
+ if ( m_type == EVT_100 )
+ {
+ sprintf(text, "%d%%", (int)(value*100.0f));
+ }
+
+ m_edit->SetText(text);
+
+ if ( bSendMessage )
+ {
+ Event newEvent;
+ m_event->MakeEvent(newEvent, m_eventMsg);
+ m_event->AddEvent(newEvent);
+ }
+}
+
+// Return the edited value.
+
+float CEditValue::RetValue()
+{
+ char text[100];
+ float value;
+
+ if ( m_edit == 0 ) 0.0f;
+
+ m_edit->GetText(text, 100);
+ sscanf(text, "%f", &value);
+
+ if ( m_type == EVT_100 )
+ {
+ value = (value+0.5f)/100.0f;
+ if ( value < 0.01f ) value = 0.0f; // less than 1%?
+ }
+
+ return value;
+}
+
+
+// Management not for buttons.
+
+void CEditValue::SetStepValue(float value)
+{
+ m_stepValue = value;
+}
+
+float CEditValue::RetStepValue()
+{
+ return m_stepValue;
+}
+
+
+// Management of the minimum value.
+
+void CEditValue::SetMinValue(float value)
+{
+ m_minValue = value;
+}
+
+float CEditValue::RetMinValue()
+{
+ return m_minValue;
+}
+
+
+// Management of the maximum value.
+
+void CEditValue::SetMaxValue(float value)
+{
+ m_maxValue = value;
+}
+
+float CEditValue::RetMaxValue()
+{
+ return m_maxValue;
+}
+
diff --git a/src/ui/editvalue.h b/src/ui/editvalue.h
new file mode 100644
index 0000000..3203b8b
--- /dev/null
+++ b/src/ui/editvalue.h
@@ -0,0 +1,85 @@
+// * 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/.
+
+// editvalue.h
+
+#ifndef _EDITVALUE_H_
+#define _EDITVALUE_H_
+
+
+#include "control.h"
+
+
+enum EditValueType
+{
+ EVT_INT = 1, // integer
+ EVT_FLOAT = 2, // float value
+ EVT_100 = 3, // percent (0 .. 1)
+};
+
+
+class CD3DEngine;
+class CEdit;
+class CButton;
+
+
+
+class CEditValue : public CControl
+{
+public:
+ CEditValue(CInstanceManager* iMan);
+ virtual ~CEditValue();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ void SetPos(FPOINT pos);
+ void SetDim(FPOINT dim);
+
+ BOOL EventProcess(const Event &event);
+ void Draw();
+
+ void SetType(EditValueType type);
+ EditValueType RetType();
+
+ void SetValue(float value, BOOL bSendMessage=FALSE);
+ float RetValue();
+
+ void SetStepValue(float value);
+ float RetStepValue();
+
+ void SetMinValue(float value);
+ float RetMinValue();
+
+ void SetMaxValue(float value);
+ float RetMaxValue();
+
+protected:
+ void MoveAdjust();
+ void HiliteValue(const Event &event);
+
+protected:
+ CEdit* m_edit;
+ CButton* m_buttonUp;
+ CButton* m_buttonDown;
+
+ EditValueType m_type;
+ float m_stepValue;
+ float m_minValue;
+ float m_maxValue;
+};
+
+
+#endif //_EDITVALUE_H_
diff --git a/src/ui/gauge.cpp b/src/ui/gauge.cpp
new file mode 100644
index 0000000..420cebf
--- /dev/null
+++ b/src/ui/gauge.cpp
@@ -0,0 +1,159 @@
+// * 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/.
+
+// gauge.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "gauge.h"
+
+
+
+
+// Object's constructor.
+
+CGauge::CGauge(CInstanceManager* iMan) : CControl(iMan)
+{
+ m_level = 0.0f;
+}
+
+// Object's destructor.
+
+CGauge::~CGauge()
+{
+}
+
+
+// Creates a new button.
+
+BOOL CGauge::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ CControl::Create(pos, dim, icon, eventMsg);
+ return TRUE;
+}
+
+
+// Management of an event.
+
+BOOL CGauge::EventProcess(const Event &event)
+{
+ CControl::EventProcess(event);
+
+ if ( event.event == EVENT_LBUTTONDOWN )
+ {
+ if ( CControl::Detect(event.pos) )
+ {
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+// Draw the gauge.
+
+void CGauge::Draw()
+{
+ FPOINT pos, dim, ddim, uv1, uv2, corner;
+ float dp;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+
+ dp = 0.5f/256.0f;
+
+ pos = m_pos;
+ dim = m_dim;
+
+ uv1.x = 32.0f/256.0f;
+ uv1.y = 32.0f/256.0f;
+ uv2.x = 64.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, 8.0f/256.0f);
+
+
+ pos.x += 3.0f/640.0f;
+ pos.y += 3.0f/480.0f;
+ dim.x -= 6.0f/640.0f;
+ dim.y -= 6.0f/480.0f;
+
+ if ( m_dim.x < m_dim.y ) // vertical gauge?
+ {
+ uv1.x = (0.0f+m_icon*16.0f)/256.0f;
+ uv2.x = uv1.x+16.0f/256.0f;
+ uv1.y = 128.0f/256.0f+m_level*(64.0f/256.0f);
+ uv2.y = uv1.y+64.0f/256.0f;
+ }
+ else // horizontal gauge?
+ {
+ uv1.x = 64.0f/256.0f+(1.0f-m_level)*(64.0f/256.0f);
+ uv2.x = uv1.x+64.0f/256.0f;
+ uv1.y = (128.0f+m_icon*16.0f)/256.0f;
+ uv2.y = uv1.y+16.0f/256.0f;
+ }
+
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+
+ DrawIcon(pos, dim, uv1, uv2);
+}
+
+
+// Management of level of the gauge.
+
+void CGauge::SetLevel(float level)
+{
+ if ( level < 0.0f ) level = 0.0f;
+ if ( level > 1.0f ) level = 1.0f;
+ m_level = level;
+}
+
+float CGauge::RetLevel()
+{
+ return m_level;
+}
+
+
diff --git a/src/ui/gauge.h b/src/ui/gauge.h
new file mode 100644
index 0000000..9895d75
--- /dev/null
+++ b/src/ui/gauge.h
@@ -0,0 +1,52 @@
+// * 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/.
+
+// gauge.h
+
+#ifndef _GAUGE_H_
+#define _GAUGE_H_
+
+
+#include "control.h"
+
+
+class CD3DEngine;
+
+
+
+class CGauge : public CControl
+{
+public:
+ CGauge(CInstanceManager* iMan);
+ virtual ~CGauge();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ BOOL EventProcess(const Event &event);
+
+ void Draw();
+
+ void SetLevel(float level);
+ float RetLevel();
+
+protected:
+
+protected:
+ float m_level;
+};
+
+
+#endif //_GAUGE_H_
diff --git a/src/ui/group.cpp b/src/ui/group.cpp
new file mode 100644
index 0000000..f49fd69
--- /dev/null
+++ b/src/ui/group.cpp
@@ -0,0 +1,646 @@
+// * 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/.
+
+// group.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "restext.h"
+#include "group.h"
+
+
+
+
+// Object's constructor.
+
+CGroup::CGroup(CInstanceManager* iMan) : CControl(iMan)
+{
+}
+
+// Object's destructor.
+
+CGroup::~CGroup()
+{
+}
+
+
+// Creates a new button.
+
+BOOL CGroup::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ CControl::Create(pos, dim, icon, eventMsg);
+
+ if ( icon == -1 )
+ {
+ char name[100];
+ char* p;
+
+ GetResource(RES_EVENT, eventMsg, name);
+ p = strchr(name, '\\');
+ if ( p != 0 ) *p = 0;
+ SetName(name);
+ }
+
+ return TRUE;
+}
+
+
+// Management of an event.
+
+BOOL CGroup::EventProcess(const Event &event)
+{
+ return TRUE;
+}
+
+
+// Draw button.
+
+void CGroup::Draw()
+{
+ FPOINT uv1,uv2, corner, pos, dim;
+ float dp;
+ int icon;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ if ( m_state & STATE_SHADOW )
+ {
+ DrawShadow(m_pos, m_dim);
+ }
+
+ dp = 0.5f/256.0f;
+
+ if ( m_icon == 0 ) // hollow frame?
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 160.0f/256.0f;
+ uv1.y = 192.0f/256.0f; // u-v texture
+ uv2.x = 192.0f/256.0f;
+ uv2.y = 224.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(m_pos, m_dim, uv1, uv2, corner, 8.0f/256.0f);
+ }
+ if ( m_icon == 1 ) // orange solid opaque?
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 104.0f/256.0f;
+ uv1.y = 48.0f/256.0f;
+ uv2.x = 112.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2);
+ }
+ if ( m_icon == 2 ) // orange degrade -> transparent?
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTw);
+ uv1.x = 112.0f/256.0f;
+ uv1.y = 48.0f/256.0f;
+ uv2.x = 120.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2);
+ }
+ if ( m_icon == 3 ) // transparent gradient -> gray?
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTw);
+ uv1.x = 120.0f/256.0f;
+ uv1.y = 48.0f/256.0f;
+ uv2.x = 128.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2);
+ }
+ if ( m_icon == 4 ) // degrade blue corner?
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTw);
+ uv1.x = 192.0f/256.0f;
+ uv1.y = 128.0f/256.0f;
+ uv2.x = 224.0f/256.0f;
+ uv2.y = 160.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2);
+ }
+ if ( m_icon == 5 ) // degrade orange corner?
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTw);
+ uv1.x = 224.0f/256.0f;
+ uv1.y = 128.0f/256.0f;
+ uv2.x = 256.0f/256.0f;
+ uv2.y = 160.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2);
+ }
+ if ( m_icon == 6 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 0.0f/256.0f; // brown transparent
+ uv1.y = 75.0f/256.0f;
+ uv2.x = 64.0f/256.0f;
+ uv2.y = 128.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 4.0f/640.0f;
+ corner.y = 4.0f/480.0f;
+ DrawIcon(m_pos, m_dim, uv1, uv2, corner, 8.0f/256.0f);
+ }
+ if ( m_icon == 7 )
+ {
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 64.0f/256.0f;
+ uv1.y = 0.0f/256.0f;
+ uv2.x = 96.0f/256.0f;
+ uv2.y = 32.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f);
+ }
+ if ( m_icon == 8 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 64.0f/256.0f; // green transparent
+ uv1.y = 160.0f/256.0f;
+ uv2.x = 160.0f/256.0f;
+ uv2.y = 176.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f);
+ }
+ if ( m_icon == 9 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 64.0f/256.0f; // red transparent
+ uv1.y = 176.0f/256.0f;
+ uv2.x = 160.0f/256.0f;
+ uv2.y = 192.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f);
+ }
+ if ( m_icon == 10 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 64.0f/256.0f; // blue transparent
+ uv1.y = 192.0f/256.0f;
+ uv2.x = 160.0f/256.0f;
+ uv2.y = 208.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f);
+ }
+ if ( m_icon == 11 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 64.0f/256.0f; // yellow transparent
+ uv1.y = 224.0f/256.0f;
+ uv2.x = 160.0f/256.0f;
+ uv2.y = 240.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2, 8.0f/256.0f);
+ }
+ if ( m_icon == 12 ) // viewfinder cross?
+ {
+ dim.x = m_dim.x/2.0f;
+ dim.y = m_dim.y/2.0f;
+
+ m_engine->SetTexture("mouse.tga");
+ m_engine->SetState(D3DSTATETTb);
+ pos.x = m_pos.x-m_dim.x/300.0f;
+ pos.y = m_pos.y+m_dim.y/300.0f+dim.y;
+ uv1.x = 0.5f/256.0f;
+ uv1.y = 192.5f/256.0f;
+ uv2.x = 63.5f/256.0f;
+ uv2.y = 255.5f/256.0f;
+ DrawIcon(pos, dim, uv1, uv2); // ul
+ pos.x += dim.x;
+ Swap(uv1.x, uv2.x);
+ DrawIcon(pos, dim, uv1, uv2); // ur
+ pos.y -= dim.y;
+ Swap(uv1.y, uv2.y);
+ DrawIcon(pos, dim, uv1, uv2); // dr
+ pos.x -= dim.x;
+ Swap(uv1.x, uv2.x);
+ DrawIcon(pos, dim, uv1, uv2); // dl
+
+ m_engine->SetState(D3DSTATETTw);
+ pos.x = m_pos.x+m_dim.x/300.0f;
+ pos.y = m_pos.y-m_dim.y/300.0f+dim.y;
+ uv1.x = 64.5f/256.0f;
+ uv1.y = 192.5f/256.0f;
+ uv2.x = 127.5f/256.0f;
+ uv2.y = 255.5f/256.0f;
+ DrawIcon(pos, dim, uv1, uv2); // ul
+ pos.x += dim.x;
+ Swap(uv1.x, uv2.x);
+ DrawIcon(pos, dim, uv1, uv2); // ur
+ pos.y -= dim.y;
+ Swap(uv1.y, uv2.y);
+ DrawIcon(pos, dim, uv1, uv2); // dr
+ pos.x -= dim.x;
+ Swap(uv1.x, uv2.x);
+ DrawIcon(pos, dim, uv1, uv2); // dl
+ }
+ if ( m_icon == 13 ) // corner upper / left?
+ {
+ m_engine->SetTexture("mouse.tga");
+ m_engine->SetState(D3DSTATETTb);
+ pos.x = m_pos.x-m_dim.x/150.0f;
+ pos.y = m_pos.y+m_dim.y/150.0f;
+ uv1.x = 128.5f/256.0f;
+ uv1.y = 192.5f/256.0f;
+ uv2.x = 191.5f/256.0f;
+ uv2.y = 255.5f/256.0f;
+ DrawIcon(pos, m_dim, uv1, uv2);
+
+ m_engine->SetState(D3DSTATETTw);
+ pos.x = m_pos.x+m_dim.x/150.0f;
+ pos.y = m_pos.y-m_dim.y/150.0f;
+ uv1.x = 192.5f/256.0f;
+ uv1.y = 192.5f/256.0f;
+ uv2.x = 255.5f/256.0f;
+ uv2.y = 255.5f/256.0f;
+ DrawIcon(pos, m_dim, uv1, uv2);
+ }
+ if ( m_icon == 14 ) // corner upper / right?
+ {
+ m_engine->SetTexture("mouse.tga");
+ m_engine->SetState(D3DSTATETTb);
+ pos.x = m_pos.x-m_dim.x/150.0f;
+ pos.y = m_pos.y+m_dim.y/150.0f;
+ uv2.x = 128.5f/256.0f;
+ uv1.y = 192.5f/256.0f;
+ uv1.x = 191.5f/256.0f;
+ uv2.y = 255.5f/256.0f;
+ DrawIcon(pos, m_dim, uv1, uv2);
+
+ m_engine->SetState(D3DSTATETTw);
+ pos.x = m_pos.x+m_dim.x/150.0f;
+ pos.y = m_pos.y-m_dim.y/150.0f;
+ uv2.x = 192.5f/256.0f;
+ uv1.y = 192.5f/256.0f;
+ uv1.x = 255.5f/256.0f;
+ uv2.y = 255.5f/256.0f;
+ DrawIcon(pos, m_dim, uv1, uv2);
+ }
+ if ( m_icon == 15 ) // corner lower / left?
+ {
+ m_engine->SetTexture("mouse.tga");
+ m_engine->SetState(D3DSTATETTb);
+ pos.x = m_pos.x-m_dim.x/150.0f;
+ pos.y = m_pos.y+m_dim.y/150.0f;
+ uv1.x = 128.5f/256.0f;
+ uv2.y = 192.5f/256.0f;
+ uv2.x = 191.5f/256.0f;
+ uv1.y = 255.5f/256.0f;
+ DrawIcon(pos, m_dim, uv1, uv2);
+
+ m_engine->SetState(D3DSTATETTw);
+ pos.x = m_pos.x+m_dim.x/150.0f;
+ pos.y = m_pos.y-m_dim.y/150.0f;
+ uv1.x = 192.5f/256.0f;
+ uv2.y = 192.5f/256.0f;
+ uv2.x = 255.5f/256.0f;
+ uv1.y = 255.5f/256.0f;
+ DrawIcon(pos, m_dim, uv1, uv2);
+ }
+ if ( m_icon == 16 ) // corner lower / left?
+ {
+ m_engine->SetTexture("mouse.tga");
+ m_engine->SetState(D3DSTATETTb);
+ pos.x = m_pos.x-m_dim.x/150.0f;
+ pos.y = m_pos.y+m_dim.y/150.0f;
+ uv2.x = 128.5f/256.0f;
+ uv2.y = 192.5f/256.0f;
+ uv1.x = 191.5f/256.0f;
+ uv1.y = 255.5f/256.0f;
+ DrawIcon(pos, m_dim, uv1, uv2);
+
+ m_engine->SetState(D3DSTATETTw);
+ pos.x = m_pos.x+m_dim.x/150.0f;
+ pos.y = m_pos.y-m_dim.y/150.0f;
+ uv2.x = 192.5f/256.0f;
+ uv2.y = 192.5f/256.0f;
+ uv1.x = 255.5f/256.0f;
+ uv1.y = 255.5f/256.0f;
+ DrawIcon(pos, m_dim, uv1, uv2);
+ }
+ if ( m_icon == 17 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 0.0f/256.0f; // blue frame
+ uv1.y = 75.0f/256.0f;
+ uv2.x = 64.0f/256.0f;
+ uv2.y = 128.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 6.0f/640.0f;
+ corner.y = 6.0f/480.0f;
+ DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f);
+ }
+ if ( m_icon == 18 ) // arrow> for SatCom?
+ {
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATETTw);
+ uv1.x = 0.0f/256.0f; // >
+ uv1.y = 192.0f/256.0f;
+ uv2.x = 32.0f/256.0f;
+ uv2.y = 224.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2);
+ }
+ if ( m_icon == 19 ) // SatCom symbol?
+ {
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATETTw);
+ uv1.x = 224.0f/256.0f; // SatCom symbol
+ uv1.y = 224.0f/256.0f;
+ uv2.x = 256.0f/256.0f;
+ uv2.y = 256.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2);
+ }
+ if ( m_icon == 20 ) // solid blue background?
+ {
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATETTw);
+ uv1.x = 224.0f/256.0f;
+ uv1.y = 32.0f/256.0f;
+ uv2.x = 256.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2);
+ }
+ if ( m_icon == 21 ) // stand-by symbol?
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTw);
+ uv1.x = 160.0f/256.0f;
+ uv1.y = 32.0f/256.0f;
+ uv2.x = 192.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2);
+ }
+ if ( m_icon == 22 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 64.0f/256.0f; // opaque yellow
+ uv1.y = 224.0f/256.0f;
+ uv2.x = 160.0f/256.0f;
+ uv2.y = 240.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 5.0f/640.0f;
+ corner.y = 5.0f/480.0f;
+ DrawIcon(m_pos, m_dim, uv1, uv2, corner, 3.0f/256.0f);
+ }
+
+ if ( m_icon == 23 )
+ {
+ m_engine->SetTexture("button3.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 64.0f/256.0f; // yellow
+ uv1.y = 192.0f/256.0f;
+ uv2.x = 80.0f/256.0f;
+ uv2.y = 208.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 4.0f/640.0f;
+ corner.y = 4.0f/480.0f;
+ DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f);
+ }
+ if ( m_icon == 24 )
+ {
+ m_engine->SetTexture("button3.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 80.0f/256.0f; // orange
+ uv1.y = 192.0f/256.0f;
+ uv2.x = 96.0f/256.0f;
+ uv2.y = 208.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 4.0f/640.0f;
+ corner.y = 4.0f/480.0f;
+ DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f);
+ }
+ if ( m_icon == 25 )
+ {
+ m_engine->SetTexture("button3.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 64.0f/256.0f; // orange
+ uv1.y = 208.0f/256.0f;
+ uv2.x = 80.0f/256.0f;
+ uv2.y = 224.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 4.0f/640.0f;
+ corner.y = 4.0f/480.0f;
+ DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f);
+ }
+ if ( m_icon == 26 )
+ {
+ m_engine->SetTexture("button3.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 80.0f/256.0f; // red
+ uv1.y = 208.0f/256.0f;
+ uv2.x = 96.0f/256.0f;
+ uv2.y = 224.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 4.0f/640.0f;
+ corner.y = 4.0f/480.0f;
+ DrawIcon(m_pos, m_dim, uv1, uv2, corner, 2.0f/256.0f);
+ }
+ if ( m_icon == 27 )
+ {
+ m_engine->SetTexture("button3.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 32.0f/256.0f;
+ uv1.y = 0.0f/256.0f;
+ uv2.x = 64.0f/256.0f;
+ uv2.y = 32.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(m_pos, m_dim, uv1, uv2);
+ }
+
+ if ( m_icon >= 100 && m_icon <= 120 ) // building?
+ {
+ pos = m_pos;
+ dim = m_dim;
+
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 32.0f/256.0f;
+ uv1.y = 32.0f/256.0f;
+ uv2.x = uv1.x+32.0f/256.0f;
+ uv2.y = uv1.y+32.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2);
+
+ m_engine->SetTexture("button3.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ pos.x += 8.0f/640.0f;
+ pos.y += 8.0f/480.0f;
+ dim.x -= 16.0f/640.0f;
+ dim.y -= 16.0f/480.0f;
+ uv1.x = 32.0f/256.0f;
+ uv1.y = 0.0f/256.0f;
+ uv2.x = uv1.x+32.0f/256.0f;
+ uv2.y = uv1.y+32.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2);
+
+ m_engine->SetState(D3DSTATENORMAL);
+ pos.x += 2.0f/640.0f;
+ pos.y += 2.0f/480.0f;
+ dim.x -= 4.0f/640.0f;
+ dim.y -= 4.0f/480.0f;
+ uv1.x = 0.0f/256.0f;
+ uv1.y = 0.0f/256.0f;
+ uv2.x = uv1.x+32.0f/256.0f;
+ uv2.y = uv1.y+32.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2);
+
+ m_engine->SetState(D3DSTATETTb);
+ pos.x += 8.0f/640.0f;
+ pos.y += 8.0f/480.0f;
+ dim.x -= 16.0f/640.0f;
+ dim.y -= 16.0f/480.0f;
+ if ( m_icon == 100 ) icon = 43; // base ?
+ if ( m_icon == 101 ) icon = 32; // factory ?
+ if ( m_icon == 102 ) icon = 35; // research ?
+ if ( m_icon == 103 ) icon = 34; // convert ?
+ if ( m_icon == 104 ) icon = 36; // station ?
+ if ( m_icon == 105 ) icon = 40; // radar ?
+ if ( m_icon == 106 ) icon = 41; // repair ?
+ if ( m_icon == 107 ) icon = 37; // tower ?
+ if ( m_icon == 108 ) icon = 39; // energy ?
+ if ( m_icon == 109 ) icon = 33; // derrick ?
+ if ( m_icon == 110 ) icon = 42; // nuclear ?
+ if ( m_icon == 111 ) icon = 38; // labo ?
+ if ( m_icon == 112 ) icon = 44; // info ?
+ if ( m_icon == 113 ) icon = 46; // lightning protection ?
+ if ( m_icon == 114 ) icon = 47; // vault ?
+ if ( m_icon == 115 ) icon = 48; // control center?
+ uv1.x = (32.0f/256.0f)*(icon%8);
+ uv1.y = (32.0f/256.0f)*(icon/8); // uv texture
+ uv2.x = uv1.x+32.0f/256.0f;
+ uv2.y = uv1.y+32.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2);
+ }
+}
+
+
diff --git a/src/ui/group.h b/src/ui/group.h
new file mode 100644
index 0000000..6dab275
--- /dev/null
+++ b/src/ui/group.h
@@ -0,0 +1,48 @@
+// * 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/.
+
+// group.h
+
+#ifndef _GROUP_H_
+#define _GROUP_H_
+
+
+#include "control.h"
+
+
+class CD3DEngine;
+
+
+
+class CGroup : public CControl
+{
+public:
+ CGroup(CInstanceManager* iMan);
+ virtual ~CGroup();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ BOOL EventProcess(const Event &event);
+
+ void Draw();
+
+protected:
+
+protected:
+};
+
+
+#endif //_GROUP_H_
diff --git a/src/ui/image.cpp b/src/ui/image.cpp
new file mode 100644
index 0000000..974216a
--- /dev/null
+++ b/src/ui/image.cpp
@@ -0,0 +1,157 @@
+// * 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/.
+
+// image.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "restext.h"
+#include "image.h"
+
+
+
+
+// Object's constructor.
+
+CImage::CImage(CInstanceManager* iMan) : CControl(iMan)
+{
+ m_filename[0] = 0;
+}
+
+// Object's destructor.
+
+CImage::~CImage()
+{
+ if ( m_filename[0] != 0 )
+ {
+ m_engine->FreeTexture(m_filename);
+ }
+}
+
+
+// Creates a new button.
+
+BOOL CImage::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ CControl::Create(pos, dim, icon, eventMsg);
+
+ if ( icon == -1 )
+ {
+ char name[100];
+ char* p;
+
+ GetResource(RES_EVENT, eventMsg, name);
+ p = strchr(name, '\\');
+ if ( p != 0 ) *p = 0;
+ SetName(name);
+ }
+
+ return TRUE;
+}
+
+
+// Specifies the name of the image display.
+
+void CImage::SetFilenameImage(char *name)
+{
+ if ( m_filename[0] != 0 )
+ {
+ m_engine->FreeTexture(m_filename);
+ }
+
+ strcpy(m_filename, name);
+}
+
+char* CImage::RetFilenameImage()
+{
+ return m_filename;
+}
+
+
+// Management of an event.
+
+BOOL CImage::EventProcess(const Event &event)
+{
+ return TRUE;
+}
+
+
+// Draws button.
+
+void CImage::Draw()
+{
+ FPOINT uv1,uv2, corner, pos, dim;
+ float dp;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ if ( m_state & STATE_SHADOW )
+ {
+ DrawShadow(m_pos, m_dim);
+ }
+
+ dp = 0.5f/256.0f;
+
+ if ( m_icon == 0 ) // hollow frame?
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 160.0f/256.0f;
+ uv1.y = 192.0f/256.0f; // u-v texture
+ uv2.x = 192.0f/256.0f;
+ uv2.y = 224.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(m_pos, m_dim, uv1, uv2, corner, 8.0f/256.0f);
+ }
+
+ if ( m_filename[0] != 0 ) // displays an image?
+ {
+ m_engine->LoadTexture(m_filename);
+ m_engine->SetTexture(m_filename);
+ m_engine->SetState(D3DSTATENORMAL);
+ pos = m_pos;
+ dim = m_dim;
+ pos.x += 5.0f/640.0f;
+ pos.y += 5.0f/480.0f;
+ dim.x -= 10.0f/640.0f;
+ dim.y -= 10.0f/480.0f;
+ uv1.x = 0.0f;
+ uv1.y = 0.0f;
+ uv2.x = 1.0f;
+ uv2.y = 1.0f;
+ DrawIcon(pos, dim, uv1, uv2);
+ }
+}
+
+
diff --git a/src/ui/image.h b/src/ui/image.h
new file mode 100644
index 0000000..7545ac0
--- /dev/null
+++ b/src/ui/image.h
@@ -0,0 +1,52 @@
+// * 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/.
+
+// image.h
+
+#ifndef _IMAGE_H_
+#define _IMAGE_H_
+
+
+#include "control.h"
+
+
+class CD3DEngine;
+
+
+
+class CImage : public CControl
+{
+public:
+ CImage(CInstanceManager* iMan);
+ virtual ~CImage();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ BOOL EventProcess(const Event &event);
+
+ void Draw();
+
+ void SetFilenameImage(char *name);
+ char* RetFilenameImage();
+
+protected:
+
+protected:
+ char m_filename[100];
+};
+
+
+#endif //_IMAGE_H_
diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp
new file mode 100644
index 0000000..fe1f112
--- /dev/null
+++ b/src/ui/interface.cpp
@@ -0,0 +1,607 @@
+// * 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/.
+
+// interface.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "control.h"
+#include "button.h"
+#include "color.h"
+#include "check.h"
+#include "key.h"
+#include "group.h"
+#include "image.h"
+#include "label.h"
+#include "edit.h"
+#include "editvalue.h"
+#include "scroll.h"
+#include "slider.h"
+#include "list.h"
+#include "shortcut.h"
+#include "compass.h"
+#include "target.h"
+#include "map.h"
+#include "window.h"
+#include "camera.h"
+#include "interface.h"
+
+
+
+
+// Object's constructor.
+
+CInterface::CInterface(CInstanceManager* iMan)
+{
+ int i;
+
+ m_iMan = iMan;
+ m_iMan->AddInstance(CLASS_INTERFACE, this);
+
+ m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE);
+ m_camera = 0;
+
+ for ( i=0 ; i<MAXCONTROL ; i++ )
+ {
+ m_table[i] = 0;
+ }
+}
+
+// Object's destructor.
+
+CInterface::~CInterface()
+{
+ Flush();
+}
+
+
+// Purge all controls.
+
+void CInterface::Flush()
+{
+ int i;
+
+ for ( i=0 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] != 0 )
+ {
+ delete m_table[i];
+ m_table[i] = 0;
+ }
+ }
+}
+
+
+// Creates a new button.
+
+CWindow* CInterface::CreateWindows(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CWindow* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ if ( eventMsg == EVENT_WINDOW0 ) {i=0; goto create;}
+ if ( eventMsg == EVENT_WINDOW1 ) {i=1; goto create;}
+ if ( eventMsg == EVENT_WINDOW2 ) {i=2; goto create;}
+ if ( eventMsg == EVENT_WINDOW3 ) {i=3; goto create;}
+ if ( eventMsg == EVENT_WINDOW4 ) {i=4; goto create;}
+ if ( eventMsg == EVENT_WINDOW5 ) {i=5; goto create;}
+ if ( eventMsg == EVENT_WINDOW6 ) {i=6; goto create;}
+ if ( eventMsg == EVENT_WINDOW7 ) {i=7; goto create;}
+ if ( eventMsg == EVENT_WINDOW8 ) {i=8; goto create;}
+ if ( eventMsg == EVENT_WINDOW9 ) {i=9; goto create;}
+
+ if ( eventMsg == EVENT_TOOLTIP ) {i=MAXCONTROL-1; goto create;}
+
+ for ( i=10 ; i<MAXCONTROL-1 ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ create:
+ m_table[i] = new CWindow(m_iMan);
+ pc = (CWindow*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new button.
+
+CButton* CInterface::CreateButton(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CButton* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CButton(m_iMan);
+ pc = (CButton*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new button.
+
+CColor* CInterface::CreateColor(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CColor* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CColor(m_iMan);
+ pc = (CColor*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new button.
+
+CCheck* CInterface::CreateCheck(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CCheck* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CCheck(m_iMan);
+ pc = (CCheck*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new button.
+
+CKey* CInterface::CreateKey(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CKey* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CKey(m_iMan);
+ pc = (CKey*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new button.
+
+CGroup* CInterface::CreateGroup(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CGroup* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CGroup(m_iMan);
+ pc = (CGroup*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new button.
+
+CImage* CInterface::CreateImage(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CImage* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CImage(m_iMan);
+ pc = (CImage*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new label.
+
+CLabel* CInterface::CreateLabel(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg,
+ char *name)
+{
+ CLabel* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CLabel(m_iMan);
+ pc = (CLabel*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ pc->SetName(name);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new pave editable.
+
+CEdit* CInterface::CreateEdit(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CEdit* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CEdit(m_iMan);
+ pc = (CEdit*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new pave editable.
+
+CEditValue* CInterface::CreateEditValue(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CEditValue* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CEditValue(m_iMan);
+ pc = (CEditValue*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new lift.
+
+CScroll* CInterface::CreateScroll(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CScroll* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CScroll(m_iMan);
+ pc = (CScroll*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new cursor.
+
+CSlider* CInterface::CreateSlider(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CSlider* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CSlider(m_iMan);
+ pc = (CSlider*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new list.
+
+CList* CInterface::CreateList(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg,
+ float expand)
+{
+ CList* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CList(m_iMan);
+ pc = (CList*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg, expand);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new shortcut.
+
+CShortcut* CInterface::CreateShortcut(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CShortcut* ps;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CShortcut(m_iMan);
+ ps = (CShortcut*)m_table[i];
+ ps->Create(pos, dim, icon, eventMsg);
+ return ps;
+ }
+ }
+ return 0;
+}
+
+// Creates a new compass.
+
+CCompass* CInterface::CreateCompass(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CCompass* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CCompass(m_iMan);
+ pc = (CCompass*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new target.
+
+CTarget* CInterface::CreateTarget(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CTarget* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CTarget(m_iMan);
+ pc = (CTarget*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new map.
+
+CMap* CInterface::CreateMap(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CMap* pm;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=10 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CMap(m_iMan);
+ pm = (CMap*)m_table[i];
+ pm->Create(pos, dim, icon, eventMsg);
+ return pm;
+ }
+ }
+ return 0;
+}
+
+// Removes a control.
+
+BOOL CInterface::DeleteControl(EventMsg eventMsg)
+{
+ int i;
+
+ for ( i=0 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] != 0 )
+ {
+ if ( eventMsg == m_table[i]->RetEventMsg() )
+ {
+ delete m_table[i];
+ m_table[i] = 0;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+// Gives a control.
+
+CControl* CInterface::SearchControl(EventMsg eventMsg)
+{
+ int i;
+
+ for ( i=0 ; i<MAXCONTROL ; i++ )
+ {
+ if ( m_table[i] != 0 )
+ {
+ if ( eventMsg == m_table[i]->RetEventMsg() )
+ {
+ return m_table[i];
+ }
+ }
+ }
+ return 0;
+}
+
+// Management of an event.
+
+BOOL CInterface::EventProcess(const Event &event)
+{
+ int i;
+
+ if ( event.event == EVENT_MOUSEMOVE )
+ {
+ if ( m_camera == 0 )
+ {
+ m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA);
+ }
+ m_engine->SetMouseType(m_camera->RetMouseDef(event.pos));
+ }
+
+ for ( i=MAXCONTROL-1 ; i>=0 ; i-- )
+ {
+ if ( m_table[i] != 0 &&
+ m_table[i]->TestState(STATE_ENABLE) )
+ {
+ if ( !m_table[i]->EventProcess(event) )
+ {
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+
+// Gives the tooltip binding to the window.
+
+BOOL CInterface::GetTooltip(FPOINT pos, char* name)
+{
+ int i;
+
+ for ( i=MAXCONTROL-1 ; i>=0 ; i-- )
+ {
+ if ( m_table[i] != 0 )
+ {
+ if ( m_table[i]->GetTooltip(pos, name) )
+ {
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+// Draws all buttons.
+
+void CInterface::Draw()
+{
+ D3DMATERIAL7 material;
+ int i;
+
+ ZeroMemory( &material, sizeof(D3DMATERIAL7) );
+ material.diffuse.r = 1.0f;
+ material.diffuse.g = 1.0f;
+ material.diffuse.b = 1.0f;
+ material.ambient.r = 0.5f;
+ material.ambient.g = 0.5f;
+ material.ambient.b = 0.5f;
+ m_engine->SetMaterial(material);
+
+ for ( i=0 ; i<MAXCONTROL ; i++ )
+//? for ( i=MAXCONTROL-1 ; i>=0 ; i-- )
+ {
+ if ( m_table[i] != 0 )
+ {
+ m_table[i]->Draw();
+ }
+ }
+}
+
+
diff --git a/src/ui/interface.h b/src/ui/interface.h
new file mode 100644
index 0000000..4a8f202
--- /dev/null
+++ b/src/ui/interface.h
@@ -0,0 +1,93 @@
+// * 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/.
+
+// interface.h
+
+#ifndef _INTERFACE_H_
+#define _INTERFACE_H_
+
+
+class CInstanceManager;
+class CD3DEngine;
+class CControl;
+class CWindow;
+class CButton;
+class CColor;
+class CCheck;
+class CKey;
+class CGroup;
+class CImage;
+class CLabel;
+class CEdit;
+class CEditValue;
+class CScroll;
+class CSlider;
+class CList;
+class CShortcut;
+class CMap;
+class CGauge;
+class CCompass;
+class CTarget;
+class CCamera;
+
+
+#define MAXCONTROL 100
+
+
+class CInterface
+{
+public:
+ CInterface(CInstanceManager* iMan);
+ ~CInterface();
+
+ BOOL EventProcess(const Event &event);
+ BOOL GetTooltip(FPOINT pos, char* name);
+
+ void Flush();
+ CWindow* CreateWindows(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CButton* CreateButton(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CColor* CreateColor(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CCheck* CreateCheck(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CKey* CreateKey(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CGroup* CreateGroup(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CImage* CreateImage(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CLabel* CreateLabel(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, char *name);
+ CEdit* CreateEdit(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CEditValue* CreateEditValue(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CScroll* CreateScroll(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CSlider* CreateSlider(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CList* CreateList(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, float expand=1.2f);
+ CShortcut* CreateShortcut(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CCompass* CreateCompass(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CTarget* CreateTarget(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CMap* CreateMap(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ BOOL DeleteControl(EventMsg eventMsg);
+ CControl* SearchControl(EventMsg eventMsg);
+
+ void Draw();
+
+protected:
+
+protected:
+ CInstanceManager* m_iMan;
+ CD3DEngine* m_engine;
+ CCamera* m_camera;
+
+ CControl* m_table[MAXCONTROL];
+};
+
+
+#endif //_INTERFACE_H_
diff --git a/src/ui/key.cpp b/src/ui/key.cpp
new file mode 100644
index 0000000..c59dac3
--- /dev/null
+++ b/src/ui/key.cpp
@@ -0,0 +1,290 @@
+// * 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/.
+
+// key.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "restext.h"
+#include "sound.h"
+#include "text.h"
+#include "key.h"
+
+
+
+
+// Constructs the name of a button.
+
+void GetKeyName(char *name, int key)
+{
+ if ( !GetResource(RES_KEY, key, name) )
+ {
+ if ( (key >= '0' && key <= '9') ||
+ (key >= 'A' && key <= 'Z') ||
+ (key >= 'a' && key <= 'z') )
+ {
+ name[0] = key;
+ name[1] = 0;
+ }
+ else
+ {
+ sprintf(name, "Code %d", key);
+ }
+ }
+}
+
+
+
+
+// Object's constructor.
+
+CKey::CKey(CInstanceManager* iMan) : CControl(iMan)
+{
+ m_key[0] = 0;
+ m_key[1] = 0;
+ m_bCatch = FALSE;
+}
+
+// Object's destructor.
+
+CKey::~CKey()
+{
+}
+
+
+// Creates a new button.
+
+BOOL CKey::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ char name[100];
+ char* p;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ CControl::Create(pos, dim, icon, eventMsg);
+
+ GetResource(RES_EVENT, eventMsg, name);
+ p = strchr(name, '\\');
+ if ( p != 0 ) *p = 0;
+ SetName(name);
+
+ return TRUE;
+}
+
+
+// Management of an event.
+
+BOOL CKey::EventProcess(const Event &event)
+{
+ if ( m_state & STATE_DEAD ) return TRUE;
+
+ CControl::EventProcess(event);
+
+ if ( event.event == EVENT_LBUTTONDOWN )
+ {
+ if ( Detect(event.pos) )
+ {
+ m_bCatch = TRUE;
+ }
+ else
+ {
+ m_bCatch = FALSE;
+ }
+ }
+
+ if ( event.event == EVENT_KEYDOWN && m_bCatch )
+ {
+ m_bCatch = FALSE;
+
+ if ( TestKey(event.param) ) // impossible ?
+ {
+ m_sound->Play(SOUND_TZOING);
+ }
+ else
+ {
+ if ( event.param == m_key[0] ||
+ event.param == m_key[1] )
+ {
+ m_key[0] = event.param;
+ m_key[1] = 0;
+ }
+ else
+ {
+ m_key[1] = m_key[0];
+ m_key[0] = event.param;
+ }
+ m_sound->Play(SOUND_CLICK);
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ }
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+// Seeks when a key is already used.
+
+BOOL CKey::TestKey(int key)
+{
+ int i, j;
+
+ if ( key == VK_PAUSE ||
+ key == VK_SNAPSHOT ) return TRUE; // blocked key
+
+ for ( i=0 ; i<20 ; i++ )
+ {
+ for ( j=0 ; j<2 ; j++ )
+ {
+ if ( key == m_engine->RetKey(i, j) ) // key used?
+ {
+ m_engine->SetKey(i, j, 0); // nothing!
+ }
+ }
+
+ if ( m_engine->RetKey(i, 0) == 0 ) // first free option?
+ {
+ m_engine->SetKey(i, 0, m_engine->RetKey(i, 1)); // shift
+ m_engine->SetKey(i, 1, 0);
+ }
+ }
+
+ return FALSE; // not used
+}
+
+
+// Draws button.
+
+void CKey::Draw()
+{
+ FPOINT iDim, pos;
+ float zoomExt, zoomInt, h;
+ int icon;
+ char text[100];
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ iDim = m_dim;
+ m_dim.x = 200.0f/640.0f;
+
+ if ( m_state & STATE_SHADOW )
+ {
+ DrawShadow(m_pos, m_dim);
+ }
+
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+
+ zoomExt = 1.00f;
+ zoomInt = 0.95f;
+
+ icon = 2;
+ if ( m_key[0] == 0 &&
+ m_key[1] == 0 ) // no shortcut?
+ {
+ icon = 3;
+ }
+ 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 )
+ {
+ 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_bCatch )
+ {
+ icon = 23;
+ }
+ DrawPart(icon, zoomExt, 8.0f/256.0f); // draws the button
+
+ h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f;
+
+ GetKeyName(text, m_key[0]);
+ if ( m_key[1] != 0 )
+ {
+ GetResource(RES_TEXT, RT_KEY_OR, text+strlen(text));
+ GetKeyName(text+strlen(text), m_key[1]);
+ }
+
+ pos.x = m_pos.x+m_dim.x*0.5f;
+ pos.y = m_pos.y+m_dim.y*0.5f;
+ pos.y -= h;
+ m_engine->RetText()->DrawText(text, pos, m_dim.x, 0, m_fontSize, m_fontStretch, m_fontType, 0);
+
+ m_dim = iDim;
+
+ if ( m_state & STATE_DEAD ) return;
+
+ // Draws the name.
+ pos.x = m_pos.x+(214.0f/640.0f);
+ pos.y = m_pos.y+m_dim.y*0.5f;
+ pos.y -= h;
+ m_engine->RetText()->DrawText(m_name, pos, m_dim.x, 1, m_fontSize, m_fontStretch, m_fontType, 0);
+}
+
+
+
+void CKey::SetKey(int option, int key)
+{
+ if ( option < 0 ||
+ option > 1 ) return;
+
+ m_key[option] = key;
+}
+
+int CKey::RetKey(int option)
+{
+ if ( option < 0 ||
+ option > 1 ) return 0;
+
+ return m_key[option];
+}
+
diff --git a/src/ui/key.h b/src/ui/key.h
new file mode 100644
index 0000000..f292425
--- /dev/null
+++ b/src/ui/key.h
@@ -0,0 +1,54 @@
+// * 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/.
+
+// key.h
+
+#ifndef _KEY_H_
+#define _KEY_H_
+
+
+#include "control.h"
+
+
+class CD3DEngine;
+
+
+
+class CKey : public CControl
+{
+public:
+ CKey(CInstanceManager* iMan);
+ virtual ~CKey();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ BOOL EventProcess(const Event &event);
+
+ void Draw();
+
+ void SetKey(int option, int key);
+ int RetKey(int option);
+
+protected:
+ BOOL TestKey(int key);
+
+protected:
+ int m_key[2];
+ BOOL m_bCatch;
+};
+
+
+#endif //_KEY_H_
diff --git a/src/ui/label.cpp b/src/ui/label.cpp
new file mode 100644
index 0000000..46d0099
--- /dev/null
+++ b/src/ui/label.cpp
@@ -0,0 +1,95 @@
+// * 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/.
+
+// label.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "text.h"
+#include "label.h"
+
+
+
+
+// Object's constructor.
+
+CLabel::CLabel(CInstanceManager* iMan) : CControl(iMan)
+{
+}
+
+// Object's destructor.
+
+CLabel::~CLabel()
+{
+}
+
+
+// Creates a new button.
+
+BOOL CLabel::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ CControl::Create(pos, dim, icon, eventMsg);
+ return TRUE;
+}
+
+
+// Management of an event.
+
+BOOL CLabel::EventProcess(const Event &event)
+{
+//? CControl::EventProcess(event);
+ return TRUE;
+}
+
+
+// Draws button.
+
+void CLabel::Draw()
+{
+ FPOINT pos;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ pos.y = m_pos.y+m_dim.y/2.0f;
+
+ if ( m_justif > 0 )
+ {
+ pos.x = m_pos.x;
+ }
+ if ( m_justif == 0 )
+ {
+ pos.x = m_pos.x+m_dim.x/2.0f;
+ }
+ if ( m_justif < 0 )
+ {
+ pos.x = m_pos.x+m_dim.x;
+ }
+ m_engine->RetText()->DrawText(m_name, pos, m_dim.x, m_justif, m_fontSize, m_fontStretch, m_fontType, 0);
+}
+
diff --git a/src/ui/label.h b/src/ui/label.h
new file mode 100644
index 0000000..c36a758
--- /dev/null
+++ b/src/ui/label.h
@@ -0,0 +1,48 @@
+// * 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/.
+
+// label.h
+
+#ifndef _LABEL_H_
+#define _LABEL_H_
+
+
+#include "control.h"
+
+
+class CD3DEngine;
+
+
+
+class CLabel : public CControl
+{
+public:
+ CLabel(CInstanceManager* iMan);
+ virtual ~CLabel();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ BOOL EventProcess(const Event &event);
+
+ void Draw();
+
+protected:
+
+protected:
+};
+
+
+#endif //_LABEL_H_
diff --git a/src/ui/list.cpp b/src/ui/list.cpp
new file mode 100644
index 0000000..08b09c0
--- /dev/null
+++ b/src/ui/list.cpp
@@ -0,0 +1,870 @@
+// * 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/.
+
+// list.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "button.h"
+#include "scroll.h"
+#include "text.h"
+#include "list.h"
+
+
+
+#define MARGING 4.0f
+
+
+
+// Object's constructor.
+
+CList::CList(CInstanceManager* iMan) : CControl(iMan)
+{
+ int i;
+
+ for ( i=0 ; i<LISTMAXDISPLAY ; i++ )
+ {
+ m_button[i] = 0;
+ }
+ m_scroll = 0;
+
+ for ( i=0 ; i<LISTMAXTOTAL ; i++ )
+ {
+ m_text[i][0] = 0;
+ m_check[i] = FALSE;
+ m_enable[i] = TRUE;
+ }
+
+ for ( i=0 ; i<10 ; i++ )
+ {
+ m_tabs[i] = 0.0f;
+ m_justifs[i] = 1;
+ }
+
+ m_totalLine = 0;
+ m_displayLine = 0;
+ m_selectLine = -1;
+ m_firstLine = 0;
+ m_bBlink = FALSE;
+ m_bSelectCap = TRUE;
+ m_blinkTime = 0.0f;
+}
+
+// Object's destructor.
+
+CList::~CList()
+{
+ int i;
+
+ for ( i=0 ; i<LISTMAXDISPLAY ; i++ )
+ {
+ delete m_button[i];
+ }
+ delete m_scroll;
+}
+
+
+// Creates a new list.
+
+BOOL CList::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg,
+ float expand)
+{
+ m_expand = expand;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+ CControl::Create(pos, dim, icon, eventMsg);
+
+ m_scroll = new CScroll(m_iMan);
+ m_scroll->Create(pos, dim, 0, EVENT_NULL);
+ m_eventScroll = m_scroll->RetEventMsg();
+
+ return MoveAdjust();
+}
+
+// Adjusted after a change of dimensions.
+
+BOOL CList::MoveAdjust()
+{
+ FPOINT ipos, idim, ppos, ddim;
+ float marging, h;
+ int i;
+
+ for ( i=0 ; i<LISTMAXDISPLAY ; i++ )
+ {
+ delete m_button[i];
+ m_button[i] = 0;
+ }
+
+ if ( m_icon == 0 ) marging = MARGING;
+ else marging = 0.0f;
+
+ ipos.x = m_pos.x+marging/640.f;
+ ipos.y = m_pos.y+marging/480.f;
+ idim.x = m_dim.x-marging*2.0f/640.f;
+ idim.y = m_dim.y-marging*2.0f/480.f;
+
+ h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType)*m_expand;
+
+ m_displayLine = (int)(idim.y/h);
+ if ( m_displayLine == 0 ) return FALSE;
+ if ( m_displayLine > LISTMAXDISPLAY ) m_displayLine = LISTMAXDISPLAY;
+ idim.y = h*m_displayLine;
+ m_dim.y = idim.y+marging*2.0f/480.f;
+
+ ppos.x = ipos.x;
+ ppos.y = ipos.y+idim.y-h;
+ ddim.x = idim.x-SCROLL_WIDTH;
+ ddim.y = h;
+ for ( i=0 ; i<m_displayLine ; i++ )
+ {
+ m_button[i] = new CButton(m_iMan);
+ m_button[i]->Create(ppos, ddim, -1, EVENT_NULL);
+ m_button[i]->SetJustif(1);
+ m_button[i]->SetState(STATE_SIMPLY);
+ m_button[i]->SetFontType(m_fontType);
+ m_button[i]->SetFontSize(m_fontSize);
+ ppos.y -= h;
+
+ m_eventButton[i] = m_button[i]->RetEventMsg();
+ }
+
+ if ( m_scroll != 0 )
+ {
+ ppos.x = ipos.x+idim.x-SCROLL_WIDTH;
+ ppos.y = ipos.y;
+ ddim.x = SCROLL_WIDTH;
+ ddim.y = idim.y;
+ m_scroll->SetPos(ppos);
+ m_scroll->SetDim(ddim);
+ }
+
+ UpdateScroll();
+ UpdateButton();
+ return TRUE;
+}
+
+
+// Returns the message of a button.
+
+EventMsg CList::RetEventMsgButton(int i)
+{
+ if ( i < 0 || i >= m_displayLine ) return EVENT_NULL;
+ if ( m_button[i] == 0 ) return EVENT_NULL;
+ return m_button[i]->RetEventMsg();
+}
+
+// Returns the message from the elevator.
+
+EventMsg CList::RetEventMsgScroll()
+{
+ if ( m_scroll == 0 ) return EVENT_NULL;
+ return m_scroll->RetEventMsg();
+}
+
+
+void CList::SetPos(FPOINT pos)
+{
+ CControl::SetPos(pos);
+}
+
+void CList::SetDim(FPOINT dim)
+{
+ m_dim = dim;
+ MoveAdjust();
+ CControl::SetDim(dim);
+}
+
+
+BOOL CList::SetState(int state, BOOL bState)
+{
+ int i;
+
+ if ( state & STATE_ENABLE )
+ {
+ for ( i=0 ; i<m_displayLine ; i++ )
+ {
+ if ( m_button[i] != 0 ) m_button[i]->SetState(state, bState);
+ }
+ if ( m_scroll != 0 ) m_scroll->SetState(state, bState);
+ }
+
+ return CControl::SetState(state, bState);
+}
+
+BOOL CList::SetState(int state)
+{
+ int i;
+
+ if ( state & STATE_ENABLE )
+ {
+ for ( i=0 ; i<m_displayLine ; i++ )
+ {
+ if ( m_button[i] != 0 ) m_button[i]->SetState(state);
+ }
+ if ( m_scroll != 0 ) m_scroll->SetState(state);
+ }
+
+ return CControl::SetState(state);
+}
+
+BOOL CList::ClearState(int state)
+{
+ int i;
+
+ if ( state & STATE_ENABLE )
+ {
+ for ( i=0 ; i<m_displayLine ; i++ )
+ {
+ if ( m_button[i] != 0 ) m_button[i]->ClearState(state);
+ }
+ if ( m_scroll != 0 ) m_scroll->ClearState(state);
+ }
+
+ return CControl::ClearState(state);
+}
+
+
+// Management of an event.
+
+BOOL CList::EventProcess(const Event &event)
+{
+ int i;
+
+ if ( m_bBlink && // blinks?
+ event.event == EVENT_FRAME )
+ {
+ i = m_selectLine-m_firstLine;
+
+ if ( i >= 0 && i < 4 &&
+ m_button[i] != 0 )
+ {
+ m_blinkTime += event.rTime;
+ if ( Mod(m_blinkTime, 0.7f) < 0.3f )
+ {
+ m_button[i]->ClearState(STATE_ENABLE);
+ m_button[i]->ClearState(STATE_CHECK);
+ }
+ else
+ {
+ m_button[i]->SetState(STATE_ENABLE);
+ m_button[i]->SetState(STATE_CHECK);
+ }
+ }
+ }
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE;
+ if ( (m_state & STATE_ENABLE) == 0 ) return TRUE;
+
+ if ( event.event == EVENT_KEYDOWN &&
+ event.param == VK_WHEELUP &&
+ Detect(event.pos) )
+ {
+ if ( m_firstLine > 0 ) m_firstLine --;
+ UpdateScroll();
+ UpdateButton();
+ return TRUE;
+ }
+ if ( event.event == EVENT_KEYDOWN &&
+ event.param == VK_WHEELDOWN &&
+ Detect(event.pos) )
+ {
+ if ( m_firstLine < m_totalLine-m_displayLine ) m_firstLine ++;
+ UpdateScroll();
+ UpdateButton();
+ return TRUE;
+ }
+
+ CControl::EventProcess(event);
+
+ if ( event.event == EVENT_MOUSEMOVE && Detect(event.pos) )
+ {
+ m_engine->SetMouseType(D3DMOUSENORM);
+ for ( i=0 ; i<m_displayLine ; i++ )
+ {
+ if ( i+m_firstLine >= m_totalLine ) break;
+ if ( m_button[i] != 0 )
+ {
+ m_button[i]->EventProcess(event);
+ }
+ }
+ }
+
+ if ( m_bSelectCap )
+ {
+ for ( i=0 ; i<m_displayLine ; i++ )
+ {
+ if ( i+m_firstLine >= m_totalLine ) break;
+ if ( m_button[i] != 0 )
+ {
+ if ( !m_button[i]->EventProcess(event) ) return FALSE;
+
+ if ( event.event == m_eventButton[i] )
+ {
+ SetSelect(m_firstLine+i);
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent); // selected line changes
+ }
+ }
+ }
+ }
+
+ if ( m_scroll != 0 )
+ {
+ if ( !m_scroll->EventProcess(event) ) return FALSE;
+
+ if ( event.event == m_eventScroll )
+ {
+ MoveScroll();
+ UpdateButton();
+ }
+ }
+
+ return TRUE;
+}
+
+
+// Draws the list.
+
+void CList::Draw()
+{
+ FPOINT uv1, uv2, corner, pos, dim, ppos, ddim;
+ float dp;
+ int i, j;
+ char text[100];
+ char *pb, *pe;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ if ( m_state & STATE_SHADOW )
+ {
+ DrawShadow(m_pos, m_dim);
+ }
+
+ dp = 0.5f/256.0f;
+
+ if ( m_icon != -1 )
+ {
+ dim = m_dim;
+
+ if ( m_icon == 0 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+
+ uv1.x = 128.0f/256.0f;
+ uv1.y = 64.0f/256.0f; // u-v texture
+ uv2.x = 160.0f/256.0f;
+ uv2.y = 96.0f/256.0f;
+ }
+ else
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+
+ uv1.x = 132.0f/256.0f;
+ uv1.y = 68.0f/256.0f; // u-v texture
+ uv2.x = 156.0f/256.0f;
+ uv2.y = 92.0f/256.0f;
+
+ if ( m_button[0] != 0 )
+ {
+ dim = m_button[0]->RetDim();
+ dim.y *= m_displayLine; // background sounds spot behind
+ }
+ }
+
+ 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(m_pos, dim, uv1, uv2, corner, 8.0f/256.0f);
+ }
+
+ if ( m_totalLine < m_displayLine ) // no buttons to the bottom?
+ {
+ i = m_totalLine;
+ if ( m_button[i] != 0 )
+ {
+ pos = m_button[i]->RetPos();
+ dim = m_button[i]->RetDim();
+ pos.y += dim.y*1.1f;
+ dim.y *= 0.4f;
+ pos.y -= dim.y;
+
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTw);
+ uv1.x = 120.0f/256.0f;
+ uv1.y = 64.0f/256.0f;
+ uv2.x = 128.0f/256.0f;
+ uv2.y = 48.0f/256.0f;
+ uv1.x += dp;
+ uv1.y -= dp;
+ uv2.x -= dp;
+ uv2.y += dp;
+ DrawIcon(pos, dim, uv1, uv2); // ch'tite shadow cute (?)
+ }
+ }
+
+ for ( i=0 ; i<m_displayLine ; i++ )
+ {
+ if ( i+m_firstLine >= m_totalLine ) break;
+
+ if ( m_button[i] != 0 )
+ {
+ if ( !m_bBlink && i+m_firstLine < m_totalLine )
+ {
+ m_button[i]->SetState(STATE_ENABLE, m_enable[i+m_firstLine] && (m_state & STATE_ENABLE) );
+ }
+ m_button[i]->Draw(); // draws a box without text
+
+ // draws text in the box
+ pos = m_button[i]->RetPos();
+ dim = m_button[i]->RetDim();
+ if ( m_tabs[0] == 0.0f )
+ {
+ ppos.x = pos.x+dim.y*0.5f;
+ ppos.y = pos.y+dim.y*0.5f;
+ ppos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f;
+ ddim.x = dim.x-dim.y;
+ DrawCase(m_text[i+m_firstLine], ppos, ddim.x, 1);
+ }
+ else
+ {
+ ppos.x = pos.x+dim.y*0.5f;
+ ppos.y = pos.y+dim.y*0.5f;
+ ppos.y -= m_engine->RetText()->RetHeight(m_fontSize, m_fontType)/2.0f;
+ pb = m_text[i+m_firstLine];
+ for ( j=0 ; j<10 ; j++ )
+ {
+ pe = strchr(pb, '\t');
+ if ( pe == 0 )
+ {
+ strcpy(text, pb);
+ }
+ else
+ {
+ strncpy(text, pb, pe-pb);
+ text[pe-pb] = 0;
+ }
+ DrawCase(text, ppos, m_tabs[j], m_justifs[j]);
+
+ if ( pe == 0 ) break;
+ ppos.x += m_tabs[j];
+ pb = pe+1;
+ }
+ }
+
+ if ( (m_state & STATE_EXTEND) && i < m_totalLine )
+ {
+ pos = m_button[i]->RetPos();
+ dim = m_button[i]->RetDim();
+ pos.x += dim.x-dim.y*0.75f;
+ dim.x = dim.y*0.75f;
+ pos.x += 2.0f/640.0f;
+ pos.y += 2.0f/480.0f;
+ dim.x -= 4.0f/640.0f;
+ dim.y -= 4.0f/480.0f;
+
+ if ( m_check[i+m_firstLine] )
+ {
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 64.0f/256.0f;
+ uv1.y = 0.0f/256.0f;
+ uv2.x = 96.0f/256.0f;
+ uv2.y = 32.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2); // square shape
+
+ m_engine->SetState(D3DSTATETTw);
+ uv1.x = 0.0f/256.0f; // v
+ uv1.y = 64.0f/256.0f;
+ uv2.x = 32.0f/256.0f;
+ uv2.y = 96.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2); // draws v
+ }
+ else
+ {
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATETTw);
+ if ( i+m_firstLine == m_selectLine )
+ {
+ uv1.x =224.0f/256.0f; // <
+ uv1.y =192.0f/256.0f;
+ uv2.x =256.0f/256.0f;
+ uv2.y =224.0f/256.0f;
+ }
+ else
+ {
+ uv1.x = 96.0f/256.0f; // x
+ uv1.y = 32.0f/256.0f;
+ uv2.x =128.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+ }
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2); // draws x
+ }
+ }
+ }
+ }
+
+ if ( m_scroll != 0 )
+ {
+ m_scroll->Draw(); // draws the lift
+ }
+}
+
+// Displays text in a box.
+
+void CList::DrawCase(char *text, FPOINT pos, float width, int justif)
+{
+ if ( justif == 1 )
+ {
+ m_engine->RetText()->DrawText(text, pos, width, 1, m_fontSize, m_fontStretch, m_fontType, 0);
+ }
+ else if ( justif == 0 )
+ {
+ pos.x += width/2.0f;
+ m_engine->RetText()->DrawText(text, pos, width, 0, m_fontSize, m_fontStretch, m_fontType, 0);
+ }
+ else
+ {
+ pos.x += width;
+ m_engine->RetText()->DrawText(text, pos, width, -1, m_fontSize, m_fontStretch, m_fontType, 0);
+ }
+}
+
+
+// Empty the list completely.
+
+void CList::Flush()
+{
+ m_totalLine = 0;
+ m_selectLine = -1;
+ m_firstLine = 0;
+ UpdateButton();
+ UpdateScroll();
+}
+
+
+// Specifies the total number of lines.
+
+void CList::SetTotal(int i)
+{
+ m_totalLine = i;
+}
+
+// Returns the total number of lines.
+
+int CList::RetTotal()
+{
+ return m_totalLine;
+}
+
+
+// Selects a line.
+
+void CList::SetSelect(int i)
+{
+ if ( m_bSelectCap )
+ {
+ m_selectLine = i;
+ }
+ else
+ {
+ m_firstLine = i;
+ UpdateScroll();
+ }
+
+ UpdateButton();
+}
+
+// Returns the selected line.
+
+int CList::RetSelect()
+{
+ if ( m_bSelectCap )
+ {
+ return m_selectLine;
+ }
+ else
+ {
+ return m_firstLine;
+ }
+}
+
+
+// Management of capability has a select box.
+
+void CList::SetSelectCap(BOOL bEnable)
+{
+ m_bSelectCap = bEnable;
+}
+
+BOOL CList::RetSelectCap()
+{
+ return m_bSelectCap;
+}
+
+
+// Blink a line.
+
+void CList::SetBlink(BOOL bEnable)
+{
+ int i;
+
+ m_bBlink = bEnable;
+ m_blinkTime = 0.0f;
+
+ i = m_selectLine-m_firstLine;
+
+ if ( i >= 0 && i < 4 &&
+ m_button[i] != 0 )
+ {
+ if ( !bEnable )
+ {
+ m_button[i]->SetState(STATE_CHECK);
+ m_button[i]->ClearState(STATE_ENABLE);
+ }
+ }
+}
+
+BOOL CList::RetBlink()
+{
+ return m_bBlink;
+}
+
+
+// Specifies the text of a line.
+
+void CList::SetName(int i, char* name)
+{
+ if ( i < 0 || i >= LISTMAXTOTAL ) return;
+
+ if ( i >= m_totalLine )
+ {
+ m_totalLine = i+1; // expands the list
+ }
+
+ if ( name[0] == 0 )
+ {
+ strcpy(m_text[i], " ");
+ }
+ else
+ {
+ strcpy(m_text[i], name);
+ }
+ UpdateButton();
+ UpdateScroll();
+}
+
+// Returns the text of a line.
+
+char* CList::RetName(int i)
+{
+ if ( i < 0 || i >= m_totalLine ) return 0;
+
+ return m_text[i];
+}
+
+
+// Specifies the bit "check" for a box.
+
+void CList::SetCheck(int i, BOOL bMode)
+{
+ if ( i < 0 || i >= m_totalLine ) return;
+
+ m_check[i] = bMode;
+}
+
+// Returns the bit "check" for a box.
+
+BOOL CList::RetCheck(int i)
+{
+ if ( i < 0 || i >= m_totalLine ) return FALSE;
+
+ return m_check[i];
+}
+
+
+// Specifies the bit "enable" for a box.
+
+void CList::SetEnable(int i, BOOL bMode)
+{
+ if ( i < 0 || i >= m_totalLine ) return;
+
+ m_enable[i] = bMode;
+}
+
+// Returns the bit "enable" for a box.
+
+BOOL CList::RetEnable(int i)
+{
+ if ( i < 0 || i >= m_totalLine ) return FALSE;
+
+ return m_enable[i];
+}
+
+
+// Management of the position of the tabs.
+
+void CList::SetTabs(int i, float pos, int justif)
+{
+ if ( i < 0 || i >= 10 ) return;
+ m_tabs[i] = pos;
+ m_justifs[i] = justif;
+}
+
+float CList::RetTabs(int i)
+{
+ if ( i < 0 || i >= 10 ) return 0.0f;
+ return m_tabs[i];
+}
+
+
+// Moves the lift to see the list of the selected line.
+
+void CList::ShowSelect(BOOL bFixed)
+{
+ int sel;
+
+ if ( bFixed &&
+ m_selectLine >= m_firstLine &&
+ m_selectLine < m_firstLine+m_displayLine ) return; // all good
+
+ sel = m_selectLine;
+
+ // Down from 1/2 * h.
+ sel += m_displayLine/2;
+ if ( sel > m_totalLine-1 ) sel = m_totalLine-1;
+
+ // Back to h-1.
+ sel -= m_displayLine-1;
+ if ( sel < 0 ) sel = 0;
+
+ m_firstLine = sel;
+
+ UpdateButton();
+ UpdateScroll();
+}
+
+
+// Updates all button names.
+
+void CList::UpdateButton()
+{
+ int state, i, j;
+
+ state = CControl::RetState();
+
+ j = m_firstLine;
+ for ( i=0 ; i<m_displayLine ; i++ )
+ {
+ if ( m_button[i] == 0 ) continue;
+
+ m_button[i]->SetState(STATE_CHECK, (j == m_selectLine));
+
+ if ( j < m_totalLine )
+ {
+//? m_button[i]->SetName(m_text[j]);
+ m_button[i]->SetName(" "); // blank button
+ m_button[i]->SetState(STATE_ENABLE, (state & STATE_ENABLE));
+ }
+ else
+ {
+ m_button[i]->SetName(" "); // blank button
+ m_button[i]->ClearState(STATE_ENABLE);
+ }
+ j ++;
+ }
+}
+
+// Updates the lift.
+
+void CList::UpdateScroll()
+{
+ float ratio, value, step;
+
+ if ( m_scroll == 0 ) return;
+
+ if ( m_totalLine <= m_displayLine )
+ {
+ ratio = 1.0f;
+ value = 0.0f;
+ step = 0.0f;
+ }
+ else
+ {
+ ratio = (float)m_displayLine/m_totalLine;
+ if ( ratio > 1.0f ) ratio = 1.0f;
+
+ value = (float)m_firstLine/(m_totalLine-m_displayLine);
+ if ( value < 0.0f ) value = 0.0f;
+ if ( value > 1.0f ) value = 1.0f;
+
+ step = (float)1.0f/(m_totalLine-m_displayLine);
+ if ( step < 0.0f ) step = 0.0f;
+ }
+
+ m_scroll->SetVisibleRatio(ratio);
+ m_scroll->SetVisibleValue(value);
+ m_scroll->SetArrowStep(step);
+}
+
+// Update when the lift is moving.
+
+void CList::MoveScroll()
+{
+ float pos;
+ int n;
+
+ if ( m_scroll == 0 ) return;
+
+ n = m_totalLine-m_displayLine;
+ pos = m_scroll->RetVisibleValue();
+ pos += m_scroll->RetArrowStep()/2.0f; // it's magic!
+ m_firstLine = (int)(pos*n);
+ if ( m_firstLine < 0 ) m_firstLine = 0;
+ if ( m_firstLine > n ) m_firstLine = n;
+}
+
+
diff --git a/src/ui/list.h b/src/ui/list.h
new file mode 100644
index 0000000..43d155f
--- /dev/null
+++ b/src/ui/list.h
@@ -0,0 +1,117 @@
+// * 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/.
+
+// list.h
+
+#ifndef _LIST_H_
+#define _LIST_H_
+
+
+#include "control.h"
+#include "event.h"
+
+
+class CD3DEngine;
+class CButton;
+class CScroll;
+
+
+#define LISTMAXDISPLAY 20 // maximum number of visible lines
+#define LISTMAXTOTAL 100 // maximum total number of lines
+
+
+
+class CList : public CControl
+{
+public:
+ CList(CInstanceManager* iMan);
+ ~CList();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, float expand);
+
+ void SetPos(FPOINT pos);
+ void SetDim(FPOINT dim);
+
+ BOOL SetState(int state, BOOL bState);
+ BOOL SetState(int state);
+ BOOL ClearState(int state);
+
+ BOOL EventProcess(const Event &event);
+ void Draw();
+
+ void Flush();
+
+ void SetTotal(int i);
+ int RetTotal();
+
+ void SetSelect(int i);
+ int RetSelect();
+
+ void SetSelectCap(BOOL bEnable);
+ BOOL RetSelectCap();
+
+ void SetBlink(BOOL bEnable);
+ BOOL RetBlink();
+
+ void SetName(int i, char* name);
+ char* RetName(int i);
+
+ void SetCheck(int i, BOOL bMode);
+ BOOL RetCheck(int i);
+
+ void SetEnable(int i, BOOL bEnable);
+ BOOL RetEnable(int i);
+
+ void SetTabs(int i, float pos, int justif=1);
+ float RetTabs(int i);
+
+ void ShowSelect(BOOL bFixed);
+
+ EventMsg RetEventMsgButton(int i);
+ EventMsg RetEventMsgScroll();
+
+protected:
+ BOOL MoveAdjust();
+ void UpdateButton();
+ void UpdateScroll();
+ void MoveScroll();
+ void DrawCase(char *text, FPOINT pos, float width, int justif);
+
+protected:
+ CButton* m_button[LISTMAXDISPLAY];
+ CScroll* m_scroll;
+
+ EventMsg m_eventButton[LISTMAXDISPLAY];
+ EventMsg m_eventScroll;
+
+ float m_expand;
+ int m_totalLine; // total number of lines
+ int m_displayLine; // number of visible lines
+ int m_selectLine; // selected line
+ int m_firstLine; // first visible line
+ BOOL m_bBlink;
+ BOOL m_bSelectCap;
+ float m_blinkTime;
+ float m_tabs[10];
+ int m_justifs[10];
+
+ char m_text[LISTMAXTOTAL][100];
+ char m_check[LISTMAXTOTAL];
+ char m_enable[LISTMAXTOTAL];
+};
+
+
+#endif //_LIST_H_
diff --git a/src/ui/maindialog.cpp b/src/ui/maindialog.cpp
new file mode 100644
index 0000000..a216cd9
--- /dev/null
+++ b/src/ui/maindialog.cpp
@@ -0,0 +1,6937 @@
+// * 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/.
+
+// maindialog.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <time.h>
+#include <direct.h>
+#include <io.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "d3dmath.h"
+#include "global.h"
+#include "language.h"
+#include "event.h"
+#include "misc.h"
+#include "profile.h"
+#include "iman.h"
+#include "restext.h"
+#include "math3d.h"
+#include "particule.h"
+#include "interface.h"
+#include "button.h"
+#include "color.h"
+#include "check.h"
+#include "key.h"
+#include "group.h"
+#include "image.h"
+#include "scroll.h"
+#include "slider.h"
+#include "list.h"
+#include "label.h"
+#include "window.h"
+#include "edit.h"
+#include "editvalue.h"
+#include "text.h"
+#include "camera.h"
+#include "sound.h"
+#include "cmdtoken.h"
+#include "robotmain.h"
+#include "maindialog.h"
+
+
+
+#define KEY_VISIBLE 6 // number of visible keys redefinable
+
+#if _SCHOOL & _TEEN
+#define KEY_TOTAL 13 // total number of keys redefinable
+#else
+#define KEY_TOTAL 21 // total number of keys redefinable
+#endif
+
+#define WELCOME_LENGTH 6.0f
+
+
+
+static int perso_color[3*10*3] =
+{
+ // hair:
+ 193, 221, 226, // white
+ 255, 255, 181, // yellow
+ 204, 155, 84, // blond
+ 165, 48, 10, // red
+ 140, 75, 84, // brown
+ 83, 64, 51, // brown
+ 90, 95, 85, // black
+ 85, 48, 9, // brown
+ 60, 0, 23, // black
+ 0, 0, 0, //
+ // spacesuit:
+ 203, 206, 204, // dirty white
+ 0, 205, 203, // bluish
+ 108, 176, 0, // greenish
+ 207, 207, 32, // yellow
+ 170, 141, 0, // orange
+ 108, 84, 0, // brown
+ 0, 84, 136, // bluish
+ 56, 61, 146, // bluish
+ 56, 56, 56, // black
+ 0, 0, 0, //
+ // strips:
+ 255, 255, 255, // white
+ 255, 255, 0, // yellow
+ 255, 132, 1, // orange
+ 255, 0, 255, // magenta
+ 255, 0, 0, // red
+ 0, 255, 0, // green
+ 0, 255, 255, // cyan
+ 0, 0, 255, // blue
+ 70, 51, 84, // dark
+ 0, 0, 0, //
+};
+
+
+#if _NET
+// Check if the key "school" is present in the registry.
+
+BOOL SchoolCheck()
+{
+ HKEY key;
+ char buffer[100];
+ LONG i;
+ DWORD type, len;
+
+ i = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+#if _NEWLOOK
+ "Software\\Epsitec\\CeeBot\\Setup",
+#else
+ "Software\\Epsitec\\Colobot\\Setup",
+#endif
+ 0, KEY_READ, &key);
+ if ( i != ERROR_SUCCESS ) return FALSE;
+
+ type = REG_SZ;
+ len = sizeof(buffer);
+ i = RegQueryValueEx(key, "School", NULL, &type, (LPBYTE)buffer, &len);
+ if ( i != ERROR_SUCCESS || type != REG_SZ ) return FALSE;
+
+ if ( strcmp(buffer, "ToBoLoC") != 0 ) return FALSE;
+
+ return TRUE;
+}
+#endif
+
+
+// Constructor of robot application.
+
+CMainDialog::CMainDialog(CInstanceManager* iMan)
+{
+ int i;
+
+ m_iMan = iMan;
+ m_iMan->AddInstance(CLASS_DIALOG, this);
+
+ m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN);
+ m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE);
+ m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT);
+ m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE);
+ m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE);
+ m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA);
+ m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND);
+
+ m_phase = PHASE_NAME;
+ m_phaseSetup = PHASE_SETUPg;
+ m_phaseTerm = PHASE_TRAINER;
+ m_sceneRead[0] = 0;
+ m_stackRead[0] = 0;
+ m_sceneName[0] = 0;
+ m_sceneRank = 0;
+ m_bSceneSoluce = FALSE;
+ m_bSimulSetup = FALSE;
+#if _NET
+ m_accessEnable = SchoolCheck();
+ m_accessMission= FALSE;
+ m_accessUser = FALSE;
+#else
+ m_accessEnable = TRUE;
+ m_accessMission= TRUE;
+ m_accessUser = TRUE;
+#endif
+ m_bDeleteGamer = TRUE;
+
+ for ( i=0 ; i<10 ; i++ )
+ {
+ m_chap[i] = 0;
+ m_sel[i] = 0;
+ }
+ m_index = 0;
+ m_maxList = 0;
+
+ ZeroMemory(&m_perso, sizeof(GamerPerso));
+ DefPerso();
+
+ m_bTooltip = TRUE;
+ m_bGlint = TRUE;
+ m_bRain = TRUE;
+ m_bSoluce4 = TRUE;
+ m_bMovies = TRUE;
+ m_bNiceReset = TRUE;
+ m_bHimselfDamage = TRUE;
+#if _TEEN
+ m_bCameraScroll = FALSE;
+#else
+ m_bCameraScroll = TRUE;
+#endif
+ m_bCameraInvertX = FALSE;
+ m_bCameraInvertY = FALSE;
+ m_bEffect = TRUE;
+ m_shotDelay = 0;
+
+ m_glintMouse = FPOINT(0.0f, 0.0f);
+ m_glintTime = 1000.0f;
+
+ for ( i=0 ; i<10 ; i++ )
+ {
+ m_partiPhase[i] = 0;
+ m_partiTime[i] = 0.0f;
+ }
+
+ strcpy(m_sceneDir, "scene");
+ strcpy(m_savegameDir, "savegame");
+ strcpy(m_publicDir, "program");
+ strcpy(m_userDir, "user");
+ strcpy(m_filesDir, "files");
+
+ m_bDialog = FALSE;
+}
+
+// Destructor of robot application.
+
+CMainDialog::~CMainDialog()
+{
+}
+
+
+// Changes phase.
+
+void CMainDialog::ChangePhase(Phase phase)
+{
+ CWindow* pw;
+ CEdit* pe;
+ CEditValue* pv;
+ CLabel* pl;
+ CList* pli;
+ CCheck* pc;
+ CScroll* ps;
+ CSlider* psl;
+ CButton* pb;
+ CColor* pco;
+ CGroup* pg;
+ CImage* pi;
+ FPOINT pos, dim, ddim;
+ float ox, oy, sx, sy;
+ char name[100];
+ char* gamer;
+ int res, i, j;
+
+ m_camera->SetType(CAMERA_DIALOG);
+ m_engine->SetOverFront(FALSE);
+ m_engine->SetOverColor(RetColor(0.0f), D3DSTATETCb);
+
+ if ( phase == PHASE_TERM )
+ {
+ phase = m_phaseTerm;
+ }
+ m_phase = phase; // copy the info to CRobotMain
+ m_phaseTime = 0.0f;
+
+ dim.x = 32.0f/640.0f;
+ dim.y = 32.0f/480.0f;
+ ox = 3.0f/640.0f;
+ oy = 3.0f/480.0f;
+ sx = (32.0f+2.0f)/640.0f;
+ sy = (32.0f+2.0f)/480.0f;
+
+ if ( m_phase == PHASE_INIT )
+ {
+ pos.x = 0.35f;
+ pos.y = 0.10f;
+ ddim.x = 0.30f;
+ ddim.y = 0.80f;
+#if _TEEN
+ pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5);
+#else
+ pw = m_interface->CreateWindows(pos, ddim, 10, EVENT_WINDOW5);
+#endif
+ GetResource(RES_TEXT, RT_TITLE_INIT, name);
+ pw->SetName(name);
+
+ pos.x = 0.35f;
+ pos.y = 0.60f;
+ ddim.x = 0.30f;
+ ddim.y = 0.30f;
+ pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner
+ pos.x = 0.35f;
+ pos.y = 0.10f;
+ ddim.x = 0.30f;
+ ddim.y = 0.30f;
+ pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner
+
+#if _SCHOOL
+ ddim.x = 0.20f;
+ ddim.y = dim.y*2.4f;
+ pos.x = 0.40f;
+ pos.y = oy+sy*7.9f;
+ pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // orange
+ pg->SetState(STATE_SHADOW);
+ pos.y = oy+sy*3.9f;
+ pg = pw->CreateGroup(pos, ddim, 25, EVENT_LABEL1); // orange
+ pg->SetState(STATE_SHADOW);
+ ddim.y = dim.y*1.2f;
+ pos.y = oy+sy*1.9f;
+ pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // red
+ pg->SetState(STATE_SHADOW);
+#else
+ ddim.x = 0.20f;
+ ddim.y = dim.y*2.4f;
+ pos.x = 0.40f;
+ if ( m_accessEnable && m_accessMission )
+ {
+ pos.y = oy+sy*9.1f;
+ pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // yellow
+ pg->SetState(STATE_SHADOW);
+ }
+ pos.y = oy+sy*6.8f;
+ pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // orange
+ pg->SetState(STATE_SHADOW);
+ pos.y = oy+sy*3.9f;
+ pg = pw->CreateGroup(pos, ddim, 25, EVENT_LABEL1); // orange
+ pg->SetState(STATE_SHADOW);
+ ddim.y = dim.y*1.2f;
+ pos.y = oy+sy*1.9f;
+ pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // red
+ pg->SetState(STATE_SHADOW);
+#endif
+
+#if _SCHOOL
+ ddim.x = 0.18f;
+ ddim.y = dim.y*1;
+ pos.x = 0.41f;
+ pos.y = oy+sy*9.1f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_TRAINER);
+ pb->SetState(STATE_SHADOW);
+
+ pos.y = oy+sy*8.0f;
+#if _TEEN
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_TEEN);
+#else
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_DEFI);
+#endif
+#if _CEEBOTDEMO
+ pb->ClearState(STATE_ENABLE);
+#endif
+ pb->SetState(STATE_SHADOW);
+#else
+ ddim.x = 0.18f;
+ ddim.y = dim.y*1;
+ pos.x = 0.41f;
+
+ if ( m_accessEnable && m_accessMission )
+ {
+ pos.y = oy+sy*10.3f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_MISSION);
+ pb->SetState(STATE_SHADOW);
+
+ pos.y = oy+sy*9.2f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_FREE);
+ pb->SetState(STATE_SHADOW);
+ }
+
+ pos.y = oy+sy*8.0f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_TRAINER);
+ pb->SetState(STATE_SHADOW);
+
+ pos.y = oy+sy*6.9f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_DEFI);
+ pb->SetState(STATE_SHADOW);
+#endif
+
+ if ( m_engine->RetSetupMode() )
+ {
+ pos.y = oy+sy*5.1f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUP);
+ pb->SetState(STATE_SHADOW);
+ }
+
+ pos.y = oy+sy*4.0f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NAME);
+ pb->SetState(STATE_SHADOW);
+
+ pos.y = oy+sy*2.0f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_QUIT);
+ pb->SetState(STATE_SHADOW);
+
+#if !_DEMO & !_SCHOOL
+ if ( m_accessEnable && m_accessUser )
+ {
+ pos.x = 447.0f/640.0f;
+ pos.y = 313.0f/480.0f;
+ ddim.x = 0.09f;
+#if _POLISH
+ pos.x -= 5.0f/640.0f;
+ ddim.x += 10.0f/640.0f;
+#endif
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_USER);
+ pb->SetState(STATE_SHADOW);
+ }
+#endif
+
+ if ( m_engine->RetDebugMode() )
+ {
+ pos.x = 139.0f/640.0f;
+ pos.y = 313.0f/480.0f;
+ ddim.x = 0.09f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PROTO);
+ pb->SetState(STATE_SHADOW);
+ }
+
+ pos.x = 0.40f;
+ ddim.x = 0.20f;
+ pos.y = 26.0f/480.0f;
+ ddim.y = 12.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 1, EVENT_LABEL1);
+ pg->SetState(STATE_SHADOW);
+ pos.y -= 5.0f/480.0f;
+#if _WG
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, " ");
+#else
+#if _NEWLOOK
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, "www.epsitec.ch");
+#else
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, "www.ceebot.com");
+#endif
+#endif
+ pl->SetFontType(FONT_COURIER);
+ pl->SetFontSize(8.0f);
+
+ m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE);
+ m_engine->SetBackForce(TRUE);
+ }
+
+ if ( m_phase == PHASE_NAME )
+ {
+ pos.x = 0.10f;
+ pos.y = 0.10f;
+ ddim.x = 0.80f;
+ ddim.y = 0.80f;
+ pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5);
+ GetResource(RES_TEXT, RT_TITLE_NAME, name);
+ pw->SetName(name);
+
+#if _NEWLOOK
+ pos.x = 80.0f/640.0f;
+ pos.y = 93.0f/480.0f;
+ ddim.x = 285.0f/640.0f;
+ ddim.y = 266.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue
+ pg->SetState(STATE_SHADOW);
+ pos.x = 372.0f/640.0f;
+ ddim.x = 188.0f/640.0f;
+ pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet
+ pg->SetState(STATE_SHADOW);
+#endif
+
+ pos.x = 0.10f;
+ pos.y = 0.40f;
+ ddim.x = 0.50f;
+ ddim.y = 0.50f;
+ pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner
+ pos.x = 0.40f;
+ pos.y = 0.10f;
+ ddim.x = 0.50f;
+ ddim.y = 0.50f;
+ pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner
+
+ pos.x = 60.0f/640.0f;
+ pos.y = 313.0f/480.0f;
+ ddim.x = 120.0f/640.0f;
+ ddim.y = 32.0f/480.0f;
+ GetResource(RES_EVENT, EVENT_INTERFACE_NLABEL, name);
+ pl = pw->CreateLabel(pos, ddim, -1, EVENT_INTERFACE_NLABEL, name);
+ pl->SetJustif(-1);
+
+ pos.x = 200.0f/640.0f;
+ pos.y = 320.0f/480.0f;
+ ddim.x = 160.0f/640.0f;
+ ddim.y = 32.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 7, EVENT_LABEL1);
+ pg->SetState(STATE_SHADOW);
+
+ pos.x = 207.0f/640.0f;
+ pos.y = 328.0f/480.0f;
+ ddim.x = 144.0f/640.0f;
+ ddim.y = 18.0f/480.0f;
+ pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_NEDIT);
+ pe->SetMaxChar(15);
+ gamer = m_main->RetGamerName();
+ if ( gamer[0] == 0 )
+ {
+ GetResource(RES_TEXT, RT_NAME_DEFAULT, name);
+ }
+ else
+ {
+ strcpy(name, gamer);
+ }
+ pe->SetText(name);
+ pe->SetCursor(strlen(name), 0);
+ pe->SetFocus(TRUE);
+
+ pos.x = 380.0f/640.0f;
+ pos.y = 320.0f/480.0f;
+ ddim.x =100.0f/640.0f;
+ ddim.y = 32.0f/480.0f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NOK);
+ pb->SetState(STATE_SHADOW);
+
+#if !_TEEN
+ pos.x = 380.0f/640.0f;
+ pos.y = 250.0f/480.0f;
+ ddim.x =100.0f/640.0f;
+ ddim.y = 52.0f/480.0f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PERSO);
+ pb->SetState(STATE_SHADOW);
+#endif
+
+ pos.x = 200.0f/640.0f;
+ pos.y = 150.0f/480.0f;
+ ddim.x = 160.0f/640.0f;
+ ddim.y = 160.0f/480.0f;
+ pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_NLIST);
+ pli->SetState(STATE_SHADOW);
+
+ if ( m_bDeleteGamer )
+ {
+ pos.x = 200.0f/640.0f;
+ pos.y = 100.0f/480.0f;
+ ddim.x = 160.0f/640.0f;
+ ddim.y = 32.0f/480.0f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NDELETE);
+ pb->SetState(STATE_SHADOW);
+ }
+
+ pos.x = 380.0f/640.0f;
+ pos.y = 100.0f/480.0f;
+ ddim.x =100.0f/640.0f;
+ ddim.y = 32.0f/480.0f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NCANCEL);
+ pb->SetState(STATE_SHADOW);
+
+ ReadNameList();
+ UpdateNameList();
+ UpdateNameControl();
+ UpdateNameFace();
+
+ m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE);
+ m_engine->SetBackForce(TRUE);
+ }
+
+ if ( m_phase == PHASE_PERSO )
+ {
+ pos.x = 0.10f;
+ pos.y = 0.10f;
+ ddim.x = 0.80f;
+ ddim.y = 0.80f;
+ pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5);
+ GetResource(RES_TEXT, RT_TITLE_PERSO, name);
+ pw->SetName(name);
+
+#if _NEWLOOK
+ pos.x = 95.0f/640.0f;
+ pos.y = 66.0f/480.0f;
+ ddim.x = 443.0f/640.0f;
+ ddim.y = 42.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet
+ pg->SetState(STATE_SHADOW);
+#endif
+
+ pos.x = 0.10f;
+ pos.y = 0.40f;
+ ddim.x = 0.50f;
+ ddim.y = 0.50f;
+ pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner
+ pos.x = 0.40f;
+ pos.y = 0.10f;
+ ddim.x = 0.50f;
+ ddim.y = 0.50f;
+ pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner
+
+ pos.x = 95.0f/640.0f;
+ pos.y = 108.0f/480.0f;
+ ddim.x = 220.0f/640.0f;
+ ddim.y = 274.0f/480.0f;
+ pw->CreateGroup(pos, ddim, 17, EVENT_NULL); // frame
+
+ pos.x = 100.0f/640.0f;
+ pos.y = 364.0f/480.0f;
+ ddim.x = 210.0f/640.0f;
+ ddim.y = 14.0f/480.0f;
+ pw->CreateGroup(pos, ddim, 3, EVENT_NULL); // transparent -> gray
+
+ pos.x = 120.0f/640.0f;
+ pos.y = 364.0f/480.0f;
+ ddim.x = 80.0f/640.0f;
+ ddim.y = 28.0f/480.0f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PHEAD);
+ pb->SetState(STATE_SHADOW);
+ pb->SetState(STATE_CARD);
+
+ pos.x = 210.0f/640.0f;
+ pos.y = 364.0f/480.0f;
+ ddim.x = 80.0f/640.0f;
+ ddim.y = 28.0f/480.0f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PBODY);
+ pb->SetState(STATE_SHADOW);
+ pb->SetState(STATE_CARD);
+
+ pos.x = 100.0f/640.0f;
+ pos.y = 354.0f/480.0f;
+ ddim.x = 210.0f/640.0f;
+ ddim.y = 10.0f/480.0f;
+ pw->CreateGroup(pos, ddim, 1, EVENT_INTERFACE_GLINTb); // orange bar
+ pos.x = 100.0f/640.0f;
+ pos.y = 154.0f/480.0f;
+ ddim.x = 210.0f/640.0f;
+ ddim.y = 200.0f/480.0f;
+ pw->CreateGroup(pos, ddim, 2, EVENT_INTERFACE_GLINTu); // orange -> transparent
+
+ // Face
+ pos.x = 340.0f/640.0f;
+ pos.y = 356.0f/480.0f;
+ ddim.x = 200.0f/640.0f;
+ ddim.y = 16.0f/480.0f;
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL11, "");
+ pl->SetJustif(1);
+
+ pos.x = 340.0f/640.0f;
+ pos.y = 312.0f/480.0f;
+ ddim.x = 44.0f/640.0f;
+ ddim.y = 44.0f/480.0f;
+ pb = pw->CreateButton(pos, ddim, 43, EVENT_INTERFACE_PFACE1);
+ pb->SetState(STATE_SHADOW);
+ pos.x += 50.0f/640.0f;
+ pb = pw->CreateButton(pos, ddim, 46, EVENT_INTERFACE_PFACE4);
+ pb->SetState(STATE_SHADOW);
+ pos.x += 50.0f/640.0f;
+ pb = pw->CreateButton(pos, ddim, 45, EVENT_INTERFACE_PFACE3);
+ pb->SetState(STATE_SHADOW);
+ pos.x += 50.0f/640.0f;
+ pb = pw->CreateButton(pos, ddim, 44, EVENT_INTERFACE_PFACE2);
+ pb->SetState(STATE_SHADOW);
+
+ // Glasses
+ pos.x = 340.0f/640.0f;
+ pos.y = 270.0f/480.0f;
+ ddim.x = 200.0f/640.0f;
+ ddim.y = 16.0f/480.0f;
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL12, "");
+ pl->SetJustif(1);
+
+ pos.x = 340.0f/640.0f;
+ pos.y = 240.0f/480.0f;
+ ddim.x = 30.0f/640.0f;
+ ddim.y = 30.0f/480.0f;
+ for ( i=0 ; i<6 ; i++ )
+ {
+ int ti[6] = {11, 179, 180, 181, 182, 183};
+ pb = pw->CreateButton(pos, ddim, ti[i], (EventMsg)(EVENT_INTERFACE_PGLASS0+i));
+ pb->SetState(STATE_SHADOW);
+ pos.x += (30.0f+2.8f)/640.0f;
+ }
+
+ // Color A
+ pos.x = 340.0f/640.0f;
+ pos.y = 300.0f/480.0f;
+ ddim.x = 200.0f/640.0f;
+ ddim.y = 16.0f/480.0f;
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL14, "");
+ pl->SetJustif(1);
+
+ pos.y = 282.0f/480.0f;
+ ddim.x = 18.0f/640.0f;
+ ddim.y = 18.0f/480.0f;
+ for ( j=0 ; j<3 ; j++ )
+ {
+ pos.x = 340.0f/640.0f;
+ for ( i=0 ; i<3 ; i++ )
+ {
+ pco = pw->CreateColor(pos, ddim, -1, (EventMsg)(EVENT_INTERFACE_PC0a+j*3+i));
+ pco->SetState(STATE_SHADOW);
+ pos.x += 20.0f/640.0f;
+ }
+ pos.y -= 20.0f/480.0f;
+ }
+
+ pos.x = 420.0f/640.0f;
+ pos.y = 282.0f/480.0f;
+ ddim.x = 100.0f/640.0f;
+ ddim.y = 18.0f/480.0f;
+ for ( i=0 ; i<3 ; i++ )
+ {
+ psl = pw->CreateSlider(pos, ddim, 0, (EventMsg)(EVENT_INTERFACE_PCRa+i));
+ psl->SetState(STATE_SHADOW);
+ psl->SetLimit(0.0f, 255.0f);
+ psl->SetArrowStep(16.0f);
+ pos.y -= 20.0f/480.0f;
+ }
+
+ // Color B
+ pos.x = 340.0f/640.0f;
+ pos.y = 192.0f/480.0f;
+ ddim.x = 200.0f/640.0f;
+ ddim.y = 16.0f/480.0f;
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL13, "");
+ pl->SetJustif(1);
+
+ pos.y = 174.0f/480.0f;
+ ddim.x = 18.0f/640.0f;
+ ddim.y = 18.0f/480.0f;
+ for ( j=0 ; j<3 ; j++ )
+ {
+ pos.x = 340.0f/640.0f;
+ for ( i=0 ; i<3 ; i++ )
+ {
+ pco = pw->CreateColor(pos, ddim, -1, (EventMsg)(EVENT_INTERFACE_PC0b+j*3+i));
+ pco->SetState(STATE_SHADOW);
+ pos.x += 20.0f/640.0f;
+ }
+ pos.y -= 20.0f/480.0f;
+ }
+
+ pos.x = 420.0f/640.0f;
+ pos.y = 174.0f/480.0f;
+ ddim.x = 100.0f/640.0f;
+ ddim.y = 18.0f/480.0f;
+ for ( i=0 ; i<3 ; i++ )
+ {
+ psl = pw->CreateSlider(pos, ddim, 0, (EventMsg)(EVENT_INTERFACE_PCRb+i));
+ psl->SetState(STATE_SHADOW);
+ psl->SetLimit(0.0f, 255.0f);
+ psl->SetArrowStep(16.0f);
+ pos.y -= 20.0f/480.0f;
+ }
+
+ // Rotation
+ pos.x = 100.0f/640.0f;
+ pos.y = 113.0f/480.0f;
+ ddim.x = 20.0f/640.0f;
+ ddim.y = 20.0f/480.0f;
+ pb = pw->CreateButton(pos, ddim, 55, EVENT_INTERFACE_PLROT); // <
+ pb->SetState(STATE_SHADOW);
+ pb->SetRepeat(TRUE);
+
+ pos.x = 290.0f/640.0f;
+ pos.y = 113.0f/480.0f;
+ ddim.x = 20.0f/640.0f;
+ ddim.y = 20.0f/480.0f;
+ pb = pw->CreateButton(pos, ddim, 48, EVENT_INTERFACE_PRROT); // >
+ pb->SetState(STATE_SHADOW);
+ pb->SetRepeat(TRUE);
+
+ pos.x = 100.0f/640.0f;
+ pos.y = 70.0f/480.0f;
+ ddim.x = 100.0f/640.0f;
+ ddim.y = 32.0f/480.0f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_POK);
+ pb->SetState(STATE_SHADOW);
+
+ pos.x = 210.0f/640.0f;
+ pos.y = 70.0f/480.0f;
+ ddim.x =100.0f/640.0f;
+ ddim.y = 32.0f/480.0f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PCANCEL);
+ pb->SetState(STATE_SHADOW);
+
+ pos.x = 340.0f/640.0f;
+ pos.y = 70.0f/480.0f;
+ ddim.x =194.0f/640.0f;
+ ddim.y = 32.0f/480.0f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PDEF);
+ pb->SetState(STATE_SHADOW);
+
+ m_persoCopy = m_perso;
+ m_persoTab = 0;
+ m_persoAngle = -0.6f;
+ UpdatePerso();
+ m_main->ScenePerso();
+ CameraPerso();
+ }
+
+ if ( m_phase == PHASE_TRAINER ||
+ m_phase == PHASE_DEFI ||
+ m_phase == PHASE_MISSION ||
+ m_phase == PHASE_FREE ||
+ m_phase == PHASE_TEEN ||
+ m_phase == PHASE_USER ||
+ m_phase == PHASE_PROTO )
+ {
+ if ( m_phase == PHASE_TRAINER ) m_index = 0;
+ if ( m_phase == PHASE_DEFI ) m_index = 1;
+ if ( m_phase == PHASE_MISSION ) m_index = 2;
+ if ( m_phase == PHASE_FREE ) m_index = 3;
+ if ( m_phase == PHASE_USER ) m_index = 4;
+ if ( m_phase == PHASE_PROTO ) m_index = 5;
+ if ( m_phase == PHASE_TEEN ) m_index = 6;
+
+ if ( m_phase == PHASE_FREE )
+ {
+ strcpy(m_sceneName, "scene");
+ ReadGamerInfo();
+ m_accessChap = RetChapPassed();
+ }
+
+ if ( m_phase == PHASE_TRAINER ) strcpy(m_sceneName, "train");
+ if ( m_phase == PHASE_DEFI ) strcpy(m_sceneName, "defi" );
+ if ( m_phase == PHASE_MISSION ) strcpy(m_sceneName, "scene");
+ if ( m_phase == PHASE_FREE ) strcpy(m_sceneName, "free");
+ if ( m_phase == PHASE_TEEN ) strcpy(m_sceneName, "teen");
+ if ( m_phase == PHASE_USER ) strcpy(m_sceneName, "user");
+ if ( m_phase == PHASE_PROTO ) strcpy(m_sceneName, "proto");
+
+ ReadGamerInfo();
+
+ pos.x = 0.10f;
+ pos.y = 0.10f;
+ ddim.x = 0.80f;
+ ddim.y = 0.80f;
+ pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5);
+ pw->SetClosable(TRUE);
+ if ( m_phase == PHASE_TRAINER ) res = RT_TITLE_TRAINER;
+ if ( m_phase == PHASE_DEFI ) res = RT_TITLE_DEFI;
+ if ( m_phase == PHASE_MISSION ) res = RT_TITLE_MISSION;
+ if ( m_phase == PHASE_FREE ) res = RT_TITLE_FREE;
+ if ( m_phase == PHASE_TEEN ) res = RT_TITLE_TEEN;
+ if ( m_phase == PHASE_USER ) res = RT_TITLE_USER;
+ if ( m_phase == PHASE_PROTO ) res = RT_TITLE_PROTO;
+ GetResource(RES_TEXT, res, name);
+ pw->SetName(name);
+
+#if _NEWLOOK
+ pos.x = 100.0f/640.0f;
+ pos.y = 226.0f/480.0f;
+ ddim.x = 216.0f/640.0f;
+ ddim.y = 160.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue
+ pg->SetState(STATE_SHADOW);
+ pos.x = 322.0f/640.0f;
+ pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan
+ pg->SetState(STATE_SHADOW);
+
+ pos.x = 100.0f/640.0f;
+ pos.y = 122.0f/480.0f;
+ ddim.x = 438.0f/640.0f;
+ ddim.y = 98.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 25, EVENT_LABEL1); // green
+ pg->SetState(STATE_SHADOW);
+ pos.y = 66.0f/480.0f;
+ ddim.y = 42.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet
+ pg->SetState(STATE_SHADOW);
+#endif
+
+ pos.x = 0.10f;
+ pos.y = 0.40f;
+ ddim.x = 0.50f;
+ ddim.y = 0.50f;
+ pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner
+ pos.x = 0.40f;
+ pos.y = 0.10f;
+ ddim.x = 0.50f;
+ ddim.y = 0.50f;
+ pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner
+
+ // Displays a list of chapters:
+ pos.x = ox+sx*3;
+ pos.y = oy+sy*10.5f;
+ ddim.x = dim.x*7.5f;
+ ddim.y = dim.y*0.6f;
+ if ( m_phase == PHASE_TRAINER ) res = RT_PLAY_CHAPt;
+ if ( m_phase == PHASE_DEFI ) res = RT_PLAY_CHAPd;
+ if ( m_phase == PHASE_MISSION ) res = RT_PLAY_CHAPm;
+ if ( m_phase == PHASE_FREE ) res = RT_PLAY_CHAPf;
+ if ( m_phase == PHASE_TEEN ) res = RT_PLAY_CHAPte;
+ if ( m_phase == PHASE_USER ) res = RT_PLAY_CHAPu;
+ if ( m_phase == PHASE_PROTO ) res = RT_PLAY_CHAPp;
+ GetResource(RES_TEXT, res, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL11, name);
+ pl->SetJustif(1);
+
+ pos.y = oy+sy*6.7f;
+ ddim.y = dim.y*4.5f;
+ ddim.x = dim.x*6.5f;
+ pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_CHAP);
+ pli->SetState(STATE_SHADOW);
+ UpdateSceneChap(m_chap[m_index]);
+ if ( m_phase != PHASE_USER ) pli->SetState(STATE_EXTEND);
+
+ // Displays a list of missions:
+ pos.x = ox+sx*9.5f;
+ pos.y = oy+sy*10.5f;
+ ddim.x = dim.x*7.5f;
+ ddim.y = dim.y*0.6f;
+ if ( m_phase == PHASE_TRAINER ) res = RT_PLAY_LISTt;
+ if ( m_phase == PHASE_DEFI ) res = RT_PLAY_LISTd;
+ if ( m_phase == PHASE_MISSION ) res = RT_PLAY_LISTm;
+ if ( m_phase == PHASE_FREE ) res = RT_PLAY_LISTf;
+ if ( m_phase == PHASE_TEEN ) res = RT_PLAY_LISTk;
+ if ( m_phase == PHASE_USER ) res = RT_PLAY_LISTu;
+ if ( m_phase == PHASE_PROTO ) res = RT_PLAY_LISTp;
+ GetResource(RES_TEXT, res, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL12, name);
+ pl->SetJustif(1);
+
+ pos.y = oy+sy*6.7f;
+ ddim.y = dim.y*4.5f;
+ ddim.x = dim.x*6.5f;
+ pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_LIST);
+ pli->SetState(STATE_SHADOW);
+ UpdateSceneList(m_chap[m_index], m_sel[m_index]);
+ if ( m_phase != PHASE_USER ) pli->SetState(STATE_EXTEND);
+ pos = pli->RetPos();
+ ddim = pli->RetDim();
+
+ // Displays the summary:
+ pos.x = ox+sx*3;
+ pos.y = oy+sy*5.4f;
+ ddim.x = dim.x*6.5f;
+ ddim.y = dim.y*0.6f;
+ GetResource(RES_TEXT, RT_PLAY_RESUME, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL13, name);
+ pl->SetJustif(1);
+
+ pos.x = ox+sx*3;
+ pos.y = oy+sy*3.6f;
+ ddim.x = dim.x*13.4f;
+ ddim.y = dim.y*1.9f;
+ pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_RESUME);
+ pe->SetState(STATE_SHADOW);
+ pe->SetMaxChar(500);
+ pe->SetEditCap(FALSE); // just to see
+ pe->SetHiliteCap(FALSE);
+
+ // Button displays the "soluce":
+ if ( m_phase != PHASE_TRAINER &&
+ m_phase != PHASE_FREE &&
+ m_phase != PHASE_TEEN )
+ {
+ pos.x = ox+sx*9.5f;
+ pos.y = oy+sy*5.8f;
+ ddim.x = dim.x*6.5f;
+ ddim.y = dim.y*0.5f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SOLUCE);
+ pc->SetState(STATE_SHADOW);
+ pc->ClearState(STATE_CHECK);
+ }
+ m_bSceneSoluce = FALSE;
+
+ UpdateSceneResume((m_chap[m_index]+1)*100+(m_sel[m_index]+1));
+
+ if ( m_phase == PHASE_MISSION ||
+ m_phase == PHASE_FREE ||
+ m_phase == PHASE_USER )
+ {
+ pos.x = ox+sx*9.5f;
+ pos.y = oy+sy*2;
+ ddim.x = dim.x*3.7f;
+ ddim.y = dim.y*1;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PLAY);
+ pb->SetState(STATE_SHADOW);
+ if ( m_maxList == 0 )
+ {
+ pb->ClearState(STATE_ENABLE);
+ }
+
+ pos.x += dim.x*4.0f;
+ ddim.x = dim.x*2.5f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_READ);
+ pb->SetState(STATE_SHADOW);
+ if ( !IsIOReadScene() ) // no file to read?
+ {
+ pb->ClearState(STATE_ENABLE);
+ }
+ }
+ else
+ {
+ pos.x = ox+sx*9.5f;
+ pos.y = oy+sy*2;
+ ddim.x = dim.x*6.5f;
+ ddim.y = dim.y*1;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_PLAY);
+ pb->SetState(STATE_SHADOW);
+ if ( m_maxList == 0 )
+ {
+ pb->ClearState(STATE_ENABLE);
+ }
+ }
+
+ pos.x = ox+sx*3;
+ ddim.x = dim.x*4;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_BACK);
+ pb->SetState(STATE_SHADOW);
+
+ m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE);
+ m_engine->SetBackForce(TRUE);
+ }
+
+ if ( m_phase == PHASE_SETUPd ||
+ m_phase == PHASE_SETUPg ||
+ m_phase == PHASE_SETUPp ||
+ m_phase == PHASE_SETUPc ||
+ m_phase == PHASE_SETUPs ||
+ m_phase == PHASE_SETUPds ||
+ m_phase == PHASE_SETUPgs ||
+ m_phase == PHASE_SETUPps ||
+ m_phase == PHASE_SETUPcs ||
+ m_phase == PHASE_SETUPss )
+ {
+ if ( m_phase == PHASE_SETUPds )
+ {
+ m_phaseSetup = PHASE_SETUPd;
+ m_bSimulSetup = TRUE;
+ }
+ else if ( m_phase == PHASE_SETUPgs )
+ {
+ m_phaseSetup = PHASE_SETUPg;
+ m_bSimulSetup = TRUE;
+ }
+ else if ( m_phase == PHASE_SETUPps )
+ {
+ m_phaseSetup = PHASE_SETUPp;
+ m_bSimulSetup = TRUE;
+ }
+ else if ( m_phase == PHASE_SETUPcs )
+ {
+ m_phaseSetup = PHASE_SETUPc;
+ m_bSimulSetup = TRUE;
+ }
+ else if ( m_phase == PHASE_SETUPss )
+ {
+ m_phaseSetup = PHASE_SETUPs;
+ m_bSimulSetup = TRUE;
+ }
+ else
+ {
+ m_phaseSetup = m_phase;
+ m_bSimulSetup = FALSE;
+ }
+
+ pos.x = 0.10f;
+ pos.y = 0.10f;
+ ddim.x = 0.80f;
+ ddim.y = 0.80f;
+ pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5);
+ pw->SetClosable(TRUE);
+ GetResource(RES_TEXT, RT_TITLE_SETUP, name);
+ pw->SetName(name);
+
+ pos.x = 0.70f;
+ pos.y = 0.10f;
+ ddim.x = 0.20f;
+ ddim.y = 0.20f;
+ pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner
+
+ pos.x = 0.10f;
+ ddim.x = 0.80f;
+ pos.y = 0.76f;
+ ddim.y = 0.05f;
+ pw->CreateGroup(pos, ddim, 3, EVENT_NULL); // transparent -> gray
+
+#if _NEWLOOK
+ if ( m_phase == PHASE_SETUPd || // setup/display ?
+ m_phase == PHASE_SETUPds )
+ {
+ pos.x = 100.0f/640.0f;
+ pos.y = 130.0f/480.0f;
+ ddim.x = 216.0f/640.0f;
+ ddim.y = 212.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue
+ pg->SetState(STATE_SHADOW);
+ pos.x = 324.0f/640.0f;
+ pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan
+ pg->SetState(STATE_SHADOW);
+ }
+ if ( m_phase == PHASE_SETUPg || // setup/graphic ?
+ m_phase == PHASE_SETUPgs )
+ {
+ pos.x = 100.0f/640.0f;
+ pos.y = 130.0f/480.0f;
+ ddim.x = 174.0f/640.0f;
+ ddim.y = 212.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue
+ pg->SetState(STATE_SHADOW);
+ pos.x = 282.0f/640.0f;
+ ddim.x = 258.0f/640.0f;
+ pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan
+ pg->SetState(STATE_SHADOW);
+ }
+ if ( m_phase == PHASE_SETUPp || // setup/game ?
+ m_phase == PHASE_SETUPps )
+ {
+ pos.x = 100.0f/640.0f;
+ pos.y = 130.0f/480.0f;
+ ddim.x = 226.0f/640.0f;
+ ddim.y = 212.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue
+ pg->SetState(STATE_SHADOW);
+ pos.x = 334.0f/640.0f;
+ ddim.x = 206.0f/640.0f;
+ pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan
+ pg->SetState(STATE_SHADOW);
+ }
+ if ( m_phase == PHASE_SETUPc || // setup/command ?
+ m_phase == PHASE_SETUPcs )
+ {
+ pos.x = 100.0f/640.0f;
+ pos.y = 125.0f/480.0f;
+ ddim.x = 440.0f/640.0f;
+ ddim.y = 222.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue
+ pg->SetState(STATE_SHADOW);
+ }
+ if ( m_phase == PHASE_SETUPs || // setup/sound ?
+ m_phase == PHASE_SETUPss )
+ {
+ pos.x = 100.0f/640.0f;
+ pos.y = 130.0f/480.0f;
+ ddim.x = 216.0f/640.0f;
+ ddim.y = 212.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 23, EVENT_LABEL1); // blue
+ pg->SetState(STATE_SHADOW);
+ pos.x = 324.0f/640.0f;
+ pg = pw->CreateGroup(pos, ddim, 24, EVENT_LABEL1); // cyan
+ pg->SetState(STATE_SHADOW);
+ }
+
+ pos.x = 100.0f/640.0f;
+ pos.y = 66.0f/480.0f;
+ ddim.x = 440.0f/640.0f;
+ ddim.y = 42.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet
+ pg->SetState(STATE_SHADOW);
+#endif
+
+ ddim.x = 0.78f/5-0.01f;
+ ddim.y = 0.06f;
+ pos.x = 0.115f;
+ pos.y = 0.76f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPd);
+ pb->SetState(STATE_SHADOW);
+ pb->SetState(STATE_CARD);
+ pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPd || m_phase == PHASE_SETUPds));
+
+ pos.x += ddim.x+0.01f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPg);
+ pb->SetState(STATE_SHADOW);
+ pb->SetState(STATE_CARD);
+ pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPg || m_phase == PHASE_SETUPgs));
+
+ pos.x += ddim.x+0.01f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPp);
+ pb->SetState(STATE_SHADOW);
+ pb->SetState(STATE_CARD);
+ pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPp || m_phase == PHASE_SETUPps));
+
+ pos.x += ddim.x+0.01f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPc);
+ pb->SetState(STATE_SHADOW);
+ pb->SetState(STATE_CARD);
+ pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPc || m_phase == PHASE_SETUPcs));
+
+ pos.x += ddim.x+0.01f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SETUPs);
+ pb->SetState(STATE_SHADOW);
+ pb->SetState(STATE_CARD);
+ pb->SetState(STATE_CHECK, (m_phase == PHASE_SETUPs || m_phase == PHASE_SETUPss));
+
+ pos.x = 0.10f;
+ ddim.x = 0.80f;
+ pos.y = 0.34f;
+ ddim.y = 0.42f;
+ pw->CreateGroup(pos, ddim, 2, EVENT_INTERFACE_GLINTu); // orange -> transparent
+ pos.x = 0.10f+(6.0f/640.0f);
+ ddim.x = 0.80f-(11.0f/640.0f);
+ pos.y = 0.74f;
+ ddim.y = 0.02f;
+ pw->CreateGroup(pos, ddim, 1, EVENT_INTERFACE_GLINTb); // orange bar
+
+ ddim.x = dim.x*4;
+ ddim.y = dim.y*1;
+ pos.x = ox+sx*3;
+ pos.y = oy+sy*2;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_BACK);
+ pb->SetState(STATE_SHADOW);
+
+ if ( !m_bSimulSetup )
+ {
+ m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE);
+ m_engine->SetBackForce(TRUE);
+ }
+ }
+
+ if ( m_phase == PHASE_SETUPd || // setup/display ?
+ m_phase == PHASE_SETUPds )
+ {
+ pos.x = ox+sx*3;
+ pos.y = oy+sy*9;
+ ddim.x = dim.x*6;
+ ddim.y = dim.y*1;
+ GetResource(RES_TEXT, RT_SETUP_DEVICE, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name);
+ pl->SetJustif(1);
+
+ pos.x = ox+sx*3;
+ pos.y = oy+sy*5.2f;
+ ddim.x = dim.x*6;
+ ddim.y = dim.y*4.5f;
+ pli = pw->CreateList(pos, ddim, 0, EVENT_LIST1);
+ pli->SetState(STATE_SHADOW);
+ UpdateDisplayDevice();
+
+ pos.x = ox+sx*10;
+ pos.y = oy+sy*9;
+ ddim.x = dim.x*6;
+ ddim.y = dim.y*1;
+ GetResource(RES_TEXT, RT_SETUP_MODE, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL2, name);
+ pl->SetJustif(1);
+
+ m_setupFull = m_engine->RetFullScreen();
+ pos.x = ox+sx*10;
+ pos.y = oy+sy*5.2f;
+ ddim.x = dim.x*6;
+ ddim.y = dim.y*4.5f;
+ pli = pw->CreateList(pos, ddim, 0, EVENT_LIST2);
+ pli->SetState(STATE_SHADOW);
+ UpdateDisplayMode();
+ pli->SetState(STATE_ENABLE, m_setupFull);
+
+ ddim.x = dim.x*4;
+ ddim.y = dim.y*0.5f;
+ pos.x = ox+sx*3;
+ pos.y = oy+sy*4.1f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_FULL);
+ pc->SetState(STATE_SHADOW);
+ pc->SetState(STATE_CHECK, m_setupFull);
+
+ ddim.x = dim.x*6;
+ ddim.y = dim.y*1;
+ pos.x = ox+sx*10;
+ pos.y = oy+sy*2;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_APPLY);
+ pb->SetState(STATE_SHADOW);
+ UpdateApply();
+ }
+
+ if ( m_phase == PHASE_SETUPg || // setup/graphic ?
+ m_phase == PHASE_SETUPgs )
+ {
+ ddim.x = dim.x*6;
+ ddim.y = dim.y*0.5f;
+ pos.x = ox+sx*3;
+ pos.y = 0.65f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SHADOW);
+ pc->SetState(STATE_SHADOW);
+ pos.y -= 0.048f;
+ if ( !m_bSimulSetup )
+ {
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_GROUND);
+ pc->SetState(STATE_SHADOW);
+ if ( m_engine->IsVideo8MB() ) pc->ClearState(STATE_ENABLE);
+ }
+ pos.y -= 0.048f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_DIRTY);
+ pc->SetState(STATE_SHADOW);
+ pos.y -= 0.048f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SKY);
+ pc->SetState(STATE_SHADOW);
+ if ( m_engine->IsVideo8MB() ) pc->ClearState(STATE_ENABLE);
+ pos.y -= 0.048f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_LENS);
+ pc->SetState(STATE_SHADOW);
+ pos.y -= 0.048f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_PLANET);
+ pc->SetState(STATE_SHADOW);
+ pos.y -= 0.048f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_FOG);
+ pc->SetState(STATE_SHADOW);
+ pos.y -= 0.048f;
+ if ( !m_bSimulSetup )
+ {
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_LIGHT);
+ pc->SetState(STATE_SHADOW);
+ }
+
+ pos.x = ox+sx*8.5f;
+ pos.y = 0.65f;
+ ddim.x = dim.x*2.2f;
+ ddim.y = 18.0f/480.0f;
+ pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_PARTI);
+ pv->SetState(STATE_SHADOW);
+ pv->SetMinValue(0.0f);
+ pv->SetMaxValue(2.0f);
+ pos.x += 0.13f;
+ pos.y -= 0.015f;
+ ddim.x = 0.40f;
+ GetResource(RES_EVENT, EVENT_INTERFACE_PARTI, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL10, name);
+ pl->SetJustif(1);
+
+ pos.x = ox+sx*8.5f;
+ pos.y = 0.59f;
+ ddim.x = dim.x*2.2f;
+ ddim.y = 18.0f/480.0f;
+ pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_CLIP);
+ pv->SetState(STATE_SHADOW);
+ pv->SetMinValue(0.5f);
+ pv->SetMaxValue(2.0f);
+ pos.x += 0.13f;
+ pos.y -= 0.015f;
+ ddim.x = 0.40f;
+ GetResource(RES_EVENT, EVENT_INTERFACE_CLIP, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL11, name);
+ pl->SetJustif(1);
+
+ pos.x = ox+sx*8.5f;
+ pos.y = 0.53f;
+ ddim.x = dim.x*2.2f;
+ ddim.y = 18.0f/480.0f;
+ pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_DETAIL);
+ pv->SetState(STATE_SHADOW);
+ pv->SetMinValue(0.0f);
+ pv->SetMaxValue(2.0f);
+ pos.x += 0.13f;
+ pos.y -= 0.015f;
+ ddim.x = 0.40f;
+ GetResource(RES_EVENT, EVENT_INTERFACE_DETAIL, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL12, name);
+ pl->SetJustif(1);
+
+ if ( !m_bSimulSetup )
+ {
+ pos.x = ox+sx*8.5f;
+ pos.y = 0.47f;
+ ddim.x = dim.x*2.2f;
+ ddim.y = 18.0f/480.0f;
+ pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_GADGET);
+ pv->SetState(STATE_SHADOW);
+ pv->SetMinValue(0.0f);
+ pv->SetMaxValue(1.0f);
+ pos.x += 0.13f;
+ pos.y -= 0.015f;
+ ddim.x = 0.40f;
+ GetResource(RES_EVENT, EVENT_INTERFACE_GADGET, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL13, name);
+ pl->SetJustif(1);
+ }
+
+#if 0
+ if ( !m_bSimulSetup )
+ {
+ pos.x = ox+sx*8.5f;
+ pos.y = 0.41f;
+ ddim.x = dim.x*2.2f;
+ ddim.y = 18.0f/480.0f;
+ pv = pw->CreateEditValue(pos, ddim, 0, EVENT_INTERFACE_TEXTURE);
+ pv->SetState(STATE_SHADOW);
+ pv->SetType(EVT_INT);
+ pv->SetMinValue(0.0f);
+ pv->SetMaxValue(2.0f);
+ pv->SetStepValue(1.0f);
+ pos.x += 0.13f;
+ pos.y -= 0.015f;
+ ddim.x = 0.40f;
+ GetResource(RES_EVENT, EVENT_INTERFACE_TEXTURE, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL14, name);
+ pl->SetJustif(1);
+ }
+#endif
+
+ ddim.x = dim.x*2;
+ ddim.y = dim.y*1;
+ pos.x = ox+sx*10;
+ pos.y = oy+sy*2;
+#if _POLISH
+ ddim.x += 20.0f/640.0f;
+ pos.x -= 20.0f/640.0f*3.0f;
+#endif
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_MIN);
+ pb->SetState(STATE_SHADOW);
+ pos.x += ddim.x;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NORM);
+ pb->SetState(STATE_SHADOW);
+ pos.x += ddim.x;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_MAX);
+ pb->SetState(STATE_SHADOW);
+
+ UpdateSetupButtons();
+ }
+
+ if ( m_phase == PHASE_SETUPp || // setup/game ?
+ m_phase == PHASE_SETUPps )
+ {
+ ddim.x = dim.x*6;
+ ddim.y = dim.y*0.5f;
+ pos.x = ox+sx*3;
+ pos.y = 0.65f;
+//? pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_TOTO);
+//? pc->SetState(STATE_SHADOW);
+//? pos.y -= 0.048f;
+#if _SCHOOL
+ #if _EDU
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SOLUCE4);
+ pc->SetState(STATE_SHADOW);
+ pos.y -= 0.048f;
+ #endif
+#else
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_MOVIES);
+ pc->SetState(STATE_SHADOW);
+ pos.y -= 0.048f;
+#endif
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SCROLL);
+ pc->SetState(STATE_SHADOW);
+ pos.y -= 0.048f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_INVERTX);
+ pc->SetState(STATE_SHADOW);
+ pos.y -= 0.048f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_INVERTY);
+ pc->SetState(STATE_SHADOW);
+ pos.y -= 0.048f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_EFFECT);
+ pc->SetState(STATE_SHADOW);
+//? pos.y -= 0.048f;
+//? pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_NICERST);
+//? pc->SetState(STATE_SHADOW);
+//? pos.y -= 0.048f;
+//? pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_HIMSELF);
+//? pc->SetState(STATE_SHADOW);
+
+ ddim.x = dim.x*6;
+ ddim.y = dim.y*0.5f;
+ pos.x = ox+sx*10;
+ pos.y = 0.65f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_TOOLTIP);
+ pc->SetState(STATE_SHADOW);
+ pos.y -= 0.048f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_GLINT);
+ pc->SetState(STATE_SHADOW);
+ pos.y -= 0.048f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_RAIN);
+ pc->SetState(STATE_SHADOW);
+ pos.y -= 0.048f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_MOUSE);
+ pc->SetState(STATE_SHADOW);
+ pos.y -= 0.048f;
+ pos.y -= 0.048f;
+ if ( !m_bSimulSetup )
+ {
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_EDITMODE);
+ pc->SetState(STATE_SHADOW);
+ }
+ pos.y -= 0.048f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_EDITVALUE);
+ pc->SetState(STATE_SHADOW);
+
+ UpdateSetupButtons();
+ }
+
+ if ( m_phase == PHASE_SETUPc || // setup/commands ?
+ m_phase == PHASE_SETUPcs )
+ {
+ pos.x = ox+sx*3;
+ pos.y = 320.0f/480.0f;
+ ddim.x = dim.x*15.0f;
+ ddim.y = 18.0f/480.0f;
+ GetResource(RES_TEXT, RT_SETUP_KEY1, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_INTERFACE_KINFO1, name);
+ pl->SetJustif(1);
+
+ pos.x = ox+sx*3;
+ pos.y = 302.0f/480.0f;
+ ddim.x = dim.x*15.0f;
+ ddim.y = 18.0f/480.0f;
+ GetResource(RES_TEXT, RT_SETUP_KEY2, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_INTERFACE_KINFO2, name);
+ pl->SetJustif(1);
+
+ ddim.x = 428.0f/640.0f;
+ ddim.y = 128.0f/480.0f;
+ pos.x = 105.0f/640.0f;
+ pos.y = 164.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 0, EVENT_INTERFACE_KGROUP);
+ pg->ClearState(STATE_ENABLE);
+ pg->SetState(STATE_DEAD);
+ pg->SetState(STATE_SHADOW);
+
+ ddim.x = 18.0f/640.0f;
+ ddim.y = (20.0f/480.0f)*KEY_VISIBLE;
+ pos.x = 510.0f/640.0f;
+ pos.y = 168.0f/480.0f;
+ ps = pw->CreateScroll(pos, ddim, -1, EVENT_INTERFACE_KSCROLL);
+ ps->SetVisibleRatio((float)KEY_VISIBLE/KEY_TOTAL);
+ ps->SetArrowStep(1.0f/((float)KEY_TOTAL-KEY_VISIBLE));
+ UpdateKey();
+
+ ddim.x = dim.x*6;
+ ddim.y = dim.y*0.5f;
+ pos.x = ox+sx*3;
+ pos.y = 130.0f/480.0f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_JOYSTICK);
+ pc->SetState(STATE_SHADOW);
+
+ ddim.x = dim.x*6;
+ ddim.y = dim.y*1;
+ pos.x = ox+sx*10;
+ pos.y = oy+sy*2;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_KDEF);
+ pb->SetState(STATE_SHADOW);
+
+ UpdateSetupButtons();
+ }
+
+ if ( m_phase == PHASE_SETUPs || // setup/sound ?
+ m_phase == PHASE_SETUPss )
+ {
+ pos.x = ox+sx*3;
+ pos.y = 0.55f;
+ ddim.x = dim.x*4.0f;
+ ddim.y = 18.0f/480.0f;
+ psl = pw->CreateSlider(pos, ddim, 0, EVENT_INTERFACE_VOLSOUND);
+ psl->SetState(STATE_SHADOW);
+ psl->SetLimit(0.0f, MAXVOLUME);
+ psl->SetArrowStep(1.0f);
+ pos.y += ddim.y;
+ GetResource(RES_EVENT, EVENT_INTERFACE_VOLSOUND, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name);
+ pl->SetJustif(1);
+
+#if (_FULL | _NET) & _SOUNDTRACKS
+ pos.x = ox+sx*3;
+ pos.y = 0.40f;
+ ddim.x = dim.x*4.0f;
+ ddim.y = 18.0f/480.0f;
+ psl = pw->CreateSlider(pos, ddim, 0, EVENT_INTERFACE_VOLMUSIC);
+ psl->SetState(STATE_SHADOW);
+ psl->SetLimit(0.0f, MAXVOLUME);
+ psl->SetArrowStep(1.0f);
+ pos.y += ddim.y;
+ GetResource(RES_EVENT, EVENT_INTERFACE_VOLMUSIC, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL2, name);
+ pl->SetJustif(1);
+#endif
+
+ ddim.x = dim.x*6;
+ ddim.y = dim.y*0.5f;
+ pos.x = ox+sx*10;
+ pos.y = 0.55f;
+ pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_SOUND3D);
+ pc->SetState(STATE_SHADOW);
+
+ ddim.x = dim.x*3;
+ ddim.y = dim.y*1;
+ pos.x = ox+sx*10;
+ pos.y = oy+sy*2;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_SILENT);
+ pb->SetState(STATE_SHADOW);
+ pos.x += ddim.x;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_NOISY);
+ pb->SetState(STATE_SHADOW);
+
+ UpdateSetupButtons();
+ }
+
+ if ( m_phase == PHASE_WRITE ||
+ m_phase == PHASE_WRITEs )
+ {
+ pos.x = 0.10f;
+ pos.y = 0.10f;
+ ddim.x = 0.80f;
+ ddim.y = 0.80f;
+ pw = m_interface->CreateWindows(pos, ddim, 13, EVENT_WINDOW5);
+ pw->SetClosable(TRUE);
+ GetResource(RES_TEXT, RT_TITLE_WRITE, name);
+ pw->SetName(name);
+
+ pos.x = 0.10f;
+ pos.y = 0.40f;
+ ddim.x = 0.50f;
+ ddim.y = 0.50f;
+ pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner
+ pos.x = 0.40f;
+ pos.y = 0.10f;
+ ddim.x = 0.50f;
+ ddim.y = 0.50f;
+ pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner
+
+#if _NEWLOOK
+ pos.x = 100.0f/640.0f;
+ pos.y = 66.0f/480.0f;
+ ddim.x = 438.0f/640.0f;
+ ddim.y = 42.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet
+ pg->SetState(STATE_SHADOW);
+#endif
+
+ pos.x = 290.0f/640.0f;
+ ddim.x = 245.0f/640.0f;
+
+ pos.y = 146.0f/480.0f;
+ ddim.y = 18.0f/480.0f;
+ GetResource(RES_EVENT, EVENT_INTERFACE_IOLABEL, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_INTERFACE_IOLABEL, name);
+ pl->SetJustif(1);
+
+ pos.y = 130.0f/480.0f;
+ ddim.y = 18.0f/480.0f;
+ pe = pw->CreateEdit(pos, ddim, 0, EVENT_INTERFACE_IONAME);
+ pe->SetState(STATE_SHADOW);
+ pe->SetFontType(FONT_COLOBOT);
+ pe->SetMaxChar(35);
+ IOReadName();
+
+ pos.y = 190.0f/480.0f;
+ ddim.y = 190.0f/480.0f;
+ pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_IOLIST);
+ pli->SetState(STATE_SHADOW);
+
+ pos.y = oy+sy*2;
+ ddim.y = dim.y*1;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_IOWRITE);
+ pb->SetState(STATE_SHADOW);
+
+ pos.x = 105.0f/640.0f;
+ pos.y = 190.0f/480.0f;
+ ddim.x = 170.0f/640.0f;
+ ddim.y = dim.y*1;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_IODELETE);
+ pb->SetState(STATE_SHADOW);
+
+ pos.x = 105.0f/640.0f;
+ pos.y = 250.0f/480.0f;
+ ddim.x = 170.0f/640.0f;
+ ddim.y = 128.0f/480.0f;
+ pi = pw->CreateImage(pos, ddim, 0, EVENT_INTERFACE_IOIMAGE);
+ pi->SetState(STATE_SHADOW);
+
+ ddim.x = dim.x*4;
+ ddim.y = dim.y*1;
+ pos.x = ox+sx*3;
+ pos.y = oy+sy*2;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_BACK);
+ pb->SetState(STATE_SHADOW);
+
+ IOReadList();
+ IOUpdateList();
+ }
+
+ if ( m_phase == PHASE_READ ||
+ m_phase == PHASE_READs )
+ {
+ pos.x = 0.10f;
+ pos.y = 0.10f;
+ ddim.x = 0.80f;
+ ddim.y = 0.80f;
+ pw = m_interface->CreateWindows(pos, ddim, 14, EVENT_WINDOW5);
+ pw->SetClosable(TRUE);
+ GetResource(RES_TEXT, RT_TITLE_READ, name);
+ pw->SetName(name);
+
+ pos.x = 0.10f;
+ pos.y = 0.40f;
+ ddim.x = 0.50f;
+ ddim.y = 0.50f;
+ pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner
+ pos.x = 0.40f;
+ pos.y = 0.10f;
+ ddim.x = 0.50f;
+ ddim.y = 0.50f;
+ pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner
+
+#if _NEWLOOK
+ pos.x = 100.0f/640.0f;
+ pos.y = 66.0f/480.0f;
+ ddim.x = 438.0f/640.0f;
+ ddim.y = 42.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 26, EVENT_LABEL1); // violet
+ pg->SetState(STATE_SHADOW);
+#endif
+
+ pos.x = 290.0f/640.0f;
+ ddim.x = 245.0f/640.0f;
+
+ pos.y = 160.0f/480.0f;
+ ddim.y = 190.0f/480.0f;
+ pli = pw->CreateList(pos, ddim, 0, EVENT_INTERFACE_IOLIST);
+ pli->SetState(STATE_SHADOW);
+
+ pos.y = oy+sy*2;
+ ddim.y = dim.y*1;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_IOREAD);
+ pb->SetState(STATE_SHADOW);
+ if ( m_phase == PHASE_READs )
+ {
+ pb->SetState(STATE_WARNING);
+ }
+
+ pos.x = 105.0f/640.0f;
+ pos.y = 160.0f/480.0f;
+ ddim.x = 170.0f/640.0f;
+ ddim.y = dim.y*1;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_IODELETE);
+ pb->SetState(STATE_SHADOW);
+
+ pos.x = 105.0f/640.0f;
+ pos.y = 220.0f/480.0f;
+ ddim.x = 170.0f/640.0f;
+ ddim.y = 128.0f/480.0f;
+ pi = pw->CreateImage(pos, ddim, 0, EVENT_INTERFACE_IOIMAGE);
+ pi->SetState(STATE_SHADOW);
+
+ ddim.x = dim.x*4;
+ ddim.y = dim.y*1;
+ pos.x = ox+sx*3;
+ pos.y = oy+sy*2;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_INTERFACE_BACK);
+ pb->SetState(STATE_SHADOW);
+
+ IOReadList();
+ IOUpdateList();
+
+ if ( m_phase == PHASE_READ )
+ {
+ m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE);
+ m_engine->SetBackForce(TRUE);
+ }
+ }
+
+ if ( m_phase == PHASE_LOADING )
+ {
+ pos.x = 0.35f;
+ pos.y = 0.10f;
+ ddim.x = 0.30f;
+ ddim.y = 0.80f;
+#if _TEEN
+ pw = m_interface->CreateWindows(pos, ddim, 12, EVENT_WINDOW5);
+#else
+ pw = m_interface->CreateWindows(pos, ddim, 10, EVENT_WINDOW5);
+#endif
+ pw->SetName(" ");
+
+ pos.x = 0.35f;
+ pos.y = 0.60f;
+ ddim.x = 0.30f;
+ ddim.y = 0.30f;
+ pw->CreateGroup(pos, ddim, 5, EVENT_INTERFACE_GLINTl); // orange corner
+ pos.x = 0.35f;
+ pos.y = 0.10f;
+ ddim.x = 0.30f;
+ ddim.y = 0.30f;
+ pw->CreateGroup(pos, ddim, 4, EVENT_INTERFACE_GLINTr); // blue corner
+
+ pos.x = 254.0f/640.0f;
+ pos.y = 208.0f/480.0f;
+ ddim.x = 132.0f/640.0f;
+ ddim.y = 42.0f/480.0f;
+ pg = pw->CreateGroup(pos, ddim, 22, EVENT_NULL);
+ pg->SetState(STATE_SHADOW);
+
+ pos.x = 220.0f/640.0f;
+ pos.y = 210.0f/480.0f;
+ ddim.x = 200.0f/640.0f;
+ ddim.y = 20.0f/480.0f;
+ GetResource(RES_TEXT, RT_DIALOG_LOADING, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name);
+ pl->SetFontSize(12.0f);
+ pl->SetJustif(0);
+
+ m_engine->SetBackground("inter01.tga", 0,0, 0,0, TRUE, TRUE);
+ m_engine->SetBackForce(TRUE);
+
+ m_loadingCounter = 1; // enough time to display!
+ }
+
+ if ( m_phase == PHASE_WELCOME1 )
+ {
+ m_sound->StopMusic();
+ m_sound->PlayMusic(11, FALSE);
+
+ pos.x = 0.0f;
+ pos.y = 0.0f;
+ ddim.x = 0.0f;
+ ddim.y = 0.0f;
+ pw = m_interface->CreateWindows(pos, ddim, -1, EVENT_WINDOW5);
+
+ m_engine->SetOverColor(RetColor(1.0f), D3DSTATETCb);
+ m_engine->SetOverFront(TRUE);
+
+#if _FRENCH
+ m_engine->SetBackground("alsyd.tga", 0,0, 0,0, TRUE, FALSE);
+#endif
+#if _POLISH
+ m_engine->SetBackground("manta.tga", 0,0, 0,0, TRUE, FALSE);
+#endif
+#if _WG
+ m_engine->SetBackground("wg.tga", 0,0, 0,0, TRUE, FALSE);
+#endif
+ m_engine->SetBackForce(TRUE);
+ }
+ if ( m_phase == PHASE_WELCOME2 )
+ {
+#if _ENGLISH
+ m_sound->StopMusic();
+ m_sound->PlayMusic(11, FALSE);
+#endif
+#if _POLISH
+ m_sound->StopMusic();
+ m_sound->PlayMusic(11, FALSE);
+#endif
+
+ pos.x = 0.0f;
+ pos.y = 0.0f;
+ ddim.x = 0.0f;
+ ddim.y = 0.0f;
+ pw = m_interface->CreateWindows(pos, ddim, -1, EVENT_WINDOW5);
+
+ m_engine->SetOverColor(RetColor(1.0f), D3DSTATETCb);
+ m_engine->SetOverFront(TRUE);
+
+ m_engine->SetBackground("colobot.tga", 0,0, 0,0, TRUE, FALSE);
+ m_engine->SetBackForce(TRUE);
+ }
+ if ( m_phase == PHASE_WELCOME3 )
+ {
+ pos.x = 0.0f;
+ pos.y = 0.0f;
+ ddim.x = 0.0f;
+ ddim.y = 0.0f;
+ pw = m_interface->CreateWindows(pos, ddim, -1, EVENT_WINDOW5);
+
+ m_engine->SetOverColor(RetColor(0.0f), D3DSTATETCw);
+ m_engine->SetOverFront(TRUE);
+
+#if _FRENCH
+ m_engine->SetBackground("epsitecf.tga", 0,0, 0,0, TRUE, FALSE);
+#endif
+#if _ENGLISH
+ m_engine->SetBackground("epsitece.tga", 0,0, 0,0, TRUE, FALSE);
+#endif
+#if _GERMAN | _WG
+ m_engine->SetBackground("epsitecd.tga", 0,0, 0,0, TRUE, FALSE);
+#endif
+#if _POLISH
+ m_engine->SetBackground("epsitecp.tga", 0,0, 0,0, TRUE, FALSE);
+#endif
+ m_engine->SetBackForce(TRUE);
+ }
+
+ if ( m_phase == PHASE_GENERIC )
+ {
+ pos.x = 0.0f;
+ pos.y = 0.0f;
+ ddim.x = 0.0f;
+ ddim.y = 0.0f;
+ pw = m_interface->CreateWindows(pos, ddim, -1, EVENT_WINDOW5);
+
+#if _FULL | _NET
+ pos.x = 80.0f/640.0f;
+ pos.y = 240.0f/480.0f;
+ ddim.x = 490.0f/640.0f;
+ ddim.y = 110.0f/480.0f;
+ pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT1);
+ pe->SetGenericMode(TRUE);
+ pe->SetEditCap(FALSE);
+ pe->SetHiliteCap(FALSE);
+ pe->SetFontType(FONT_COURIER);
+ pe->SetFontSize(8.0f);
+ pe->ReadText("help\\authors.txt");
+
+ pos.x = 80.0f/640.0f;
+ pos.y = 140.0f/480.0f;
+ ddim.x = 490.0f/640.0f;
+ ddim.y = 100.0f/480.0f;
+ pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT2);
+ pe->SetGenericMode(TRUE);
+ pe->SetEditCap(FALSE);
+ pe->SetHiliteCap(FALSE);
+ pe->SetFontType(FONT_COURIER);
+ pe->SetFontSize(6.5f);
+ pe->ReadText("help\\licences.txt");
+#endif
+#if _SCHOOL
+#if _CEEBOTDEMO
+ pos.x = 80.0f/640.0f;
+ pos.y = 210.0f/480.0f;
+ ddim.x = 490.0f/640.0f;
+ ddim.y = 150.0f/480.0f;
+#else
+ pos.x = 80.0f/640.0f;
+ pos.y = 200.0f/480.0f;
+ ddim.x = 490.0f/640.0f;
+ ddim.y = 150.0f/480.0f;
+#endif
+ pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT1);
+ pe->SetGenericMode(TRUE);
+ pe->SetEditCap(FALSE);
+ pe->SetHiliteCap(FALSE);
+ pe->SetFontType(FONT_COURIER);
+ pe->SetFontSize(8.0f);
+ pe->ReadText("help\\authors.txt");
+#endif
+#if _DEMO
+//? pos.x = 80.0f/640.0f;
+//? pos.y = 240.0f/480.0f;
+//? ddim.x = 490.0f/640.0f;
+//? ddim.y = 110.0f/480.0f;
+//? pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT1);
+//? pe->SetGenericMode(TRUE);
+//? pe->SetEditCap(FALSE);
+//? pe->SetHiliteCap(FALSE);
+//? pe->SetFontType(FONT_COURIER);
+//? pe->SetFontSize(8.0f);
+//? pe->ReadText("help\\demo.txt");
+
+//? pos.x = 80.0f/640.0f;
+//? pos.y = 140.0f/480.0f;
+//? ddim.x = 490.0f/640.0f;
+//? ddim.y = 100.0f/480.0f;
+//? pe = pw->CreateEdit(pos, ddim, 0, EVENT_EDIT2);
+//? pe->SetGenericMode(TRUE);
+//? pe->SetEditCap(FALSE);
+//? pe->SetHiliteCap(FALSE);
+//? pe->SetFontType(FONT_COURIER);
+//? pe->SetFontSize(8.0f);
+//? pe->ReadText("help\\authors.txt");
+#endif
+
+#if !_DEMO
+ pos.x = 40.0f/640.0f;
+ pos.y = 83.0f/480.0f;
+ ddim.x = 246.0f/640.0f;
+ ddim.y = 16.0f/480.0f;
+ GetResource(RES_TEXT, RT_GENERIC_DEV1, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name);
+ pl->SetFontType(FONT_COURIER);
+ pl->SetFontSize(8.0f);
+
+ pos.y = 13.0f/480.0f;
+ GetResource(RES_TEXT, RT_GENERIC_DEV2, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL2, name);
+ pl->SetFontType(FONT_COURIER);
+ pl->SetFontSize(8.0f);
+
+ pos.x = 355.0f/640.0f;
+ pos.y = 83.0f/480.0f;
+ ddim.x = 246.0f/640.0f;
+ ddim.y = 16.0f/480.0f;
+ GetResource(RES_TEXT, RT_GENERIC_EDIT1, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL3, name);
+ pl->SetFontType(FONT_COURIER);
+ pl->SetFontSize(8.0f);
+
+ pos.y = 13.0f/480.0f;
+ GetResource(RES_TEXT, RT_GENERIC_EDIT2, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL4, name);
+ pl->SetFontType(FONT_COURIER);
+ pl->SetFontSize(8.0f);
+#endif
+
+#if _DEMO
+ pos.x = 481.0f/640.0f;
+ pos.y = 51.0f/480.0f;
+ ddim.x = 30.0f/640.0f;
+ ddim.y = 30.0f/480.0f;
+ pb = pw->CreateButton(pos, ddim, 49, EVENT_INTERFACE_ABORT);
+ pb->SetState(STATE_SHADOW);
+#else
+ pos.x = 306.0f/640.0f;
+ pos.y = 17.0f/480.0f;
+ ddim.x = 30.0f/640.0f;
+ ddim.y = 30.0f/480.0f;
+ pb = pw->CreateButton(pos, ddim, 49, EVENT_INTERFACE_ABORT);
+ pb->SetState(STATE_SHADOW);
+#endif
+
+#if _NEWLOOK
+#if _CEEBOTDEMO
+#if _TEEN
+ m_engine->SetBackground("genedt.tga", 0,0, 0,0, TRUE, TRUE);
+#else
+ m_engine->SetBackground("geneda.tga", 0,0, 0,0, TRUE, TRUE);
+#endif
+#else
+ m_engine->SetBackground("genern.tga", 0,0, 0,0, TRUE, TRUE);
+#endif
+#else
+#if _FRENCH
+#if _DEMO
+ m_engine->SetBackground("genedf.tga", 0,0, 0,0, TRUE, TRUE);
+#else
+ m_engine->SetBackground("generf.tga", 0,0, 0,0, TRUE, TRUE);
+#endif
+#endif
+#if _ENGLISH
+#if _DEMO
+ m_engine->SetBackground("genede.tga", 0,0, 0,0, TRUE, TRUE);
+#else
+ m_engine->SetBackground("genere.tga", 0,0, 0,0, TRUE, TRUE);
+#endif
+#endif
+#if _GERMAN
+#if _DEMO
+ m_engine->SetBackground("genedd.tga", 0,0, 0,0, TRUE, TRUE);
+#else
+ m_engine->SetBackground("genere.tga", 0,0, 0,0, TRUE, TRUE);
+#endif
+#endif
+#if _WG
+#if _DEMO
+ m_engine->SetBackground("genedd.tga", 0,0, 0,0, TRUE, TRUE);
+#else
+ m_engine->SetBackground("generd.tga", 0,0, 0,0, TRUE, TRUE);
+#endif
+#endif
+#if _POLISH
+#if _DEMO
+ m_engine->SetBackground("genedp.tga", 0,0, 0,0, TRUE, TRUE);
+#else
+ m_engine->SetBackground("generp.tga", 0,0, 0,0, TRUE, TRUE);
+#endif
+#endif
+#endif
+ m_engine->SetBackForce(TRUE);
+ }
+
+ if ( m_phase == PHASE_INIT ||
+ m_phase == PHASE_NAME ||
+ m_phase == PHASE_TRAINER ||
+ m_phase == PHASE_DEFI ||
+ m_phase == PHASE_MISSION ||
+ m_phase == PHASE_FREE ||
+ m_phase == PHASE_TEEN ||
+ m_phase == PHASE_USER ||
+ m_phase == PHASE_PROTO ||
+ m_phase == PHASE_SETUPd ||
+ m_phase == PHASE_SETUPg ||
+ m_phase == PHASE_SETUPp ||
+ m_phase == PHASE_SETUPc ||
+ m_phase == PHASE_SETUPs ||
+ m_phase == PHASE_READ ||
+ m_phase == PHASE_LOADING )
+ {
+#if _SCHOOL
+#if _TEEN
+ pos.x = 50.0f/640.0f;
+ pos.y = 430.0f/480.0f;
+ ddim.x = 200.0f/640.0f;
+ ddim.y = 10.0f/480.0f;
+#else
+ pos.x = 450.0f/640.0f;
+ pos.y = 0.0f/480.0f;
+ ddim.x = 170.0f/640.0f;
+ ddim.y = 9.0f/480.0f;
+#endif
+#else
+ pos.x = 540.0f/640.0f;
+ pos.y = 9.0f/480.0f;
+ ddim.x = 90.0f/640.0f;
+ ddim.y = 10.0f/480.0f;
+#endif
+ GetResource(RES_TEXT, RT_VERSION_ID, name);
+ pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name);
+ pl->SetFontType(FONT_COURIER);
+ pl->SetFontSize(9.0f);
+ }
+
+ m_engine->LoadAllTexture();
+}
+
+
+// Processing an event.
+// Returns FALSE if the event has been processed completely.
+
+BOOL CMainDialog::EventProcess(const Event &event)
+{
+ CWindow* pw;
+ CList* pl;
+ CButton* pb;
+ CCheck* pc;
+ Event newEvent;
+ float welcomeLength;
+
+ if ( event.event == EVENT_FRAME )
+ {
+ m_phaseTime += event.rTime;
+
+//? if ( m_phase == PHASE_WELCOME1 ) welcomeLength = WELCOME_LENGTH+2.0f;
+//? else welcomeLength = WELCOME_LENGTH;
+ welcomeLength = WELCOME_LENGTH;
+
+ if ( m_phase == PHASE_WELCOME1 ||
+ m_phase == PHASE_WELCOME2 ||
+ m_phase == PHASE_WELCOME3 )
+ {
+ float intensity;
+ int mode = D3DSTATETCb;
+
+ if ( m_phaseTime < 1.5f )
+ {
+ intensity = 1.0f-(m_phaseTime-0.5f);
+ }
+ else if ( m_phaseTime < welcomeLength-1.0f )
+ {
+ intensity = 0.0f;
+ }
+ else
+ {
+ intensity = m_phaseTime-(welcomeLength-1.0f);
+ }
+ if ( intensity < 0.0f ) intensity = 0.0f;
+ if ( intensity > 1.0f ) intensity = 1.0f;
+
+ if ( (m_phase == PHASE_WELCOME2 && m_phaseTime > welcomeLength/2.0f) ||
+ m_phase == PHASE_WELCOME3 )
+ {
+ intensity = 1.0f-intensity;
+ mode = D3DSTATETCw;
+ }
+
+ m_engine->SetOverColor(RetColor(intensity), mode);
+ }
+
+ if ( m_phase == PHASE_WELCOME1 && m_phaseTime >= welcomeLength )
+ {
+ ChangePhase(PHASE_WELCOME2);
+ return TRUE;
+ }
+ if ( m_phase == PHASE_WELCOME2 && m_phaseTime >= welcomeLength )
+ {
+ ChangePhase(PHASE_WELCOME3);
+ return TRUE;
+ }
+ if ( m_phase == PHASE_WELCOME3 && m_phaseTime >= welcomeLength )
+ {
+ ChangePhase(PHASE_NAME);
+ return TRUE;
+ }
+
+ if ( m_shotDelay > 0 && !m_bDialog ) // screenshot done?
+ {
+ m_shotDelay --;
+ if ( m_shotDelay == 0 )
+ {
+ m_engine->WriteScreenShot(m_shotName, 320, 240);
+//? m_engine->WriteScreenShot(m_shotName, 160, 120);
+ }
+ }
+
+ if ( m_phase == PHASE_LOADING )
+ {
+ if ( m_loadingCounter == 0 )
+ {
+ m_main->ChangePhase(PHASE_SIMUL);
+ }
+ m_loadingCounter --;
+ return FALSE;
+ }
+
+ m_glintTime += event.rTime;
+ GlintMove(); // moves reflections
+
+ FrameParticule(event.rTime);
+
+ if ( m_bDialog ) // this dialogue?
+ {
+ FrameDialog(event.rTime);
+ }
+
+ return TRUE;
+ }
+
+ if ( event.event == EVENT_MOUSEMOVE )
+ {
+ m_glintMouse = event.pos;
+ NiceParticule(event.pos, event.keyState&KS_MLEFT);
+ }
+
+ if ( m_bDialog ) // this dialogue?
+ {
+ m_interface->EventProcess(event);
+
+ if ( event.event == EVENT_DIALOG_OK ||
+ (event.event == EVENT_KEYDOWN && event.param == VK_RETURN ) )
+ {
+ StopDialog();
+ if ( m_phase == PHASE_NAME )
+ {
+ NameDelete();
+ }
+ if ( m_phase == PHASE_INIT )
+ {
+//? m_event->MakeEvent(newEvent, EVENT_QUIT);
+//? m_event->AddEvent(newEvent);
+ m_main->ChangePhase(PHASE_GENERIC);
+ }
+ if ( m_phase == PHASE_SIMUL )
+ {
+ if ( m_bDialogDelete )
+ {
+ m_main->DeleteObject();
+ }
+ else
+ {
+ m_main->ChangePhase(PHASE_TERM);
+ }
+ }
+ }
+ if ( event.event == EVENT_DIALOG_CANCEL ||
+ (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE ) )
+ {
+ StopDialog();
+ }
+ if ( event.event == EVENT_INTERFACE_SETUP )
+ {
+ StopDialog();
+ StartSuspend();
+ if ( m_phaseSetup == PHASE_SETUPd ) ChangePhase(PHASE_SETUPds);
+ if ( m_phaseSetup == PHASE_SETUPg ) ChangePhase(PHASE_SETUPgs);
+ if ( m_phaseSetup == PHASE_SETUPp ) ChangePhase(PHASE_SETUPps);
+ if ( m_phaseSetup == PHASE_SETUPc ) ChangePhase(PHASE_SETUPcs);
+ if ( m_phaseSetup == PHASE_SETUPs ) ChangePhase(PHASE_SETUPss);
+ }
+ if ( event.event == EVENT_INTERFACE_AGAIN )
+ {
+ StopDialog();
+ m_main->ChangePhase(PHASE_LOADING);
+ }
+ if ( event.event == EVENT_INTERFACE_WRITE )
+ {
+ StopDialog();
+ StartSuspend();
+ ChangePhase(PHASE_WRITEs);
+ }
+ if ( event.event == EVENT_INTERFACE_READ )
+ {
+ StopDialog();
+ StartSuspend();
+ ChangePhase(PHASE_READs);
+ }
+
+ return FALSE;
+ }
+
+ if ( !m_engine->RetMouseHide() &&
+ !m_interface->EventProcess(event) )
+ {
+ return FALSE;
+ }
+
+ if ( m_phase == PHASE_INIT )
+ {
+ switch( event.event )
+ {
+ case EVENT_KEYDOWN:
+ if ( event.param == VK_ESCAPE )
+ {
+//? StartQuit(); // would you leave?
+ m_sound->Play(SOUND_TZOING);
+ m_main->ChangePhase(PHASE_GENERIC);
+ }
+ break;
+
+ case EVENT_INTERFACE_QUIT:
+//? StartQuit(); // would you leave?
+ m_sound->Play(SOUND_TZOING);
+ m_main->ChangePhase(PHASE_GENERIC);
+ break;
+
+ case EVENT_INTERFACE_TRAINER:
+ m_main->ChangePhase(PHASE_TRAINER);
+ break;
+
+ case EVENT_INTERFACE_DEFI:
+ m_main->ChangePhase(PHASE_DEFI);
+ break;
+
+ case EVENT_INTERFACE_MISSION:
+ m_main->ChangePhase(PHASE_MISSION);
+ break;
+
+ case EVENT_INTERFACE_FREE:
+ m_main->ChangePhase(PHASE_FREE);
+ break;
+
+ case EVENT_INTERFACE_TEEN:
+ m_main->ChangePhase(PHASE_TEEN);
+ break;
+
+ case EVENT_INTERFACE_USER:
+ m_main->ChangePhase(PHASE_USER);
+ break;
+
+ case EVENT_INTERFACE_PROTO:
+ m_main->ChangePhase(PHASE_PROTO);
+ break;
+
+ case EVENT_INTERFACE_SETUP:
+ m_main->ChangePhase(m_phaseSetup);
+ break;
+
+ case EVENT_INTERFACE_NAME:
+ m_main->ChangePhase(PHASE_NAME);
+ break;
+ }
+ return FALSE;
+ }
+
+ if ( m_phase == PHASE_NAME )
+ {
+ switch( event.event )
+ {
+ case EVENT_KEYDOWN:
+ if ( event.param == VK_RETURN )
+ {
+ NameSelect();
+ }
+ if ( event.param == VK_ESCAPE )
+ {
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) break;
+ pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_NCANCEL);
+ if ( pb == 0 ) break;
+ if ( pb->TestState(STATE_ENABLE) )
+ {
+ m_main->ChangePhase(PHASE_INIT);
+ }
+ }
+ break;
+
+ case EVENT_INTERFACE_NEDIT:
+ UpdateNameList();
+ UpdateNameControl();
+ break;
+
+ case EVENT_INTERFACE_NLIST:
+ UpdateNameEdit();
+ break;
+
+ case EVENT_INTERFACE_NOK:
+ NameSelect();
+ break;
+
+ case EVENT_INTERFACE_PERSO:
+ NameSelect();
+ m_main->ChangePhase(PHASE_PERSO);
+ break;
+
+ case EVENT_INTERFACE_NCANCEL:
+ m_main->ChangePhase(PHASE_INIT);
+ break;
+
+ case EVENT_INTERFACE_NDELETE:
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) break;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST);
+ if ( pl == 0 ) break;
+ StartDeleteGame(pl->RetName(pl->RetSelect()));
+ break;
+ }
+ }
+
+ if ( m_phase == PHASE_PERSO )
+ {
+ switch( event.event )
+ {
+ case EVENT_KEYDOWN:
+ if ( event.param == VK_RETURN )
+ {
+ m_main->ChangePhase(PHASE_INIT);
+ }
+ if ( event.param == VK_ESCAPE )
+ {
+ m_main->ChangePhase(PHASE_NAME);
+ }
+ break;
+
+ case EVENT_INTERFACE_PHEAD:
+ m_persoTab = 0;
+ UpdatePerso();
+ m_main->ScenePerso();
+ CameraPerso();
+ break;
+ case EVENT_INTERFACE_PBODY:
+ m_persoTab = 1;
+ UpdatePerso();
+ m_main->ScenePerso();
+ CameraPerso();
+ break;
+
+ case EVENT_INTERFACE_PFACE1:
+ case EVENT_INTERFACE_PFACE2:
+ case EVENT_INTERFACE_PFACE3:
+ case EVENT_INTERFACE_PFACE4:
+ m_perso.face = event.event-EVENT_INTERFACE_PFACE1;
+ WriteGamerPerso(m_main->RetGamerName());
+ UpdatePerso();
+ m_main->ScenePerso();
+ break;
+
+ case EVENT_INTERFACE_PGLASS0:
+ case EVENT_INTERFACE_PGLASS1:
+ case EVENT_INTERFACE_PGLASS2:
+ case EVENT_INTERFACE_PGLASS3:
+ case EVENT_INTERFACE_PGLASS4:
+ case EVENT_INTERFACE_PGLASS5:
+ case EVENT_INTERFACE_PGLASS6:
+ case EVENT_INTERFACE_PGLASS7:
+ case EVENT_INTERFACE_PGLASS8:
+ case EVENT_INTERFACE_PGLASS9:
+ m_perso.glasses = event.event-EVENT_INTERFACE_PGLASS0;
+ WriteGamerPerso(m_main->RetGamerName());
+ UpdatePerso();
+ m_main->ScenePerso();
+ break;
+
+ case EVENT_INTERFACE_PC0a:
+ case EVENT_INTERFACE_PC1a:
+ case EVENT_INTERFACE_PC2a:
+ case EVENT_INTERFACE_PC3a:
+ case EVENT_INTERFACE_PC4a:
+ case EVENT_INTERFACE_PC5a:
+ case EVENT_INTERFACE_PC6a:
+ case EVENT_INTERFACE_PC7a:
+ case EVENT_INTERFACE_PC8a:
+ case EVENT_INTERFACE_PC9a:
+ FixPerso(event.event-EVENT_INTERFACE_PC0a, 0);
+ WriteGamerPerso(m_main->RetGamerName());
+ UpdatePerso();
+ m_main->ScenePerso();
+ break;
+
+ case EVENT_INTERFACE_PC0b:
+ case EVENT_INTERFACE_PC1b:
+ case EVENT_INTERFACE_PC2b:
+ case EVENT_INTERFACE_PC3b:
+ case EVENT_INTERFACE_PC4b:
+ case EVENT_INTERFACE_PC5b:
+ case EVENT_INTERFACE_PC6b:
+ case EVENT_INTERFACE_PC7b:
+ case EVENT_INTERFACE_PC8b:
+ case EVENT_INTERFACE_PC9b:
+ FixPerso(event.event-EVENT_INTERFACE_PC0b, 1);
+ WriteGamerPerso(m_main->RetGamerName());
+ UpdatePerso();
+ m_main->ScenePerso();
+ break;
+
+ case EVENT_INTERFACE_PCRa:
+ case EVENT_INTERFACE_PCGa:
+ case EVENT_INTERFACE_PCBa:
+ case EVENT_INTERFACE_PCRb:
+ case EVENT_INTERFACE_PCGb:
+ case EVENT_INTERFACE_PCBb:
+ ColorPerso();
+ WriteGamerPerso(m_main->RetGamerName());
+ UpdatePerso();
+ m_main->ScenePerso();
+ break;
+
+ case EVENT_INTERFACE_PDEF:
+ DefPerso();
+ WriteGamerPerso(m_main->RetGamerName());
+ UpdatePerso();
+ m_main->ScenePerso();
+ break;
+
+ case EVENT_INTERFACE_PLROT:
+ m_persoAngle += 0.2f;
+ break;
+ case EVENT_INTERFACE_PRROT:
+ m_persoAngle -= 0.2f;
+ break;
+
+ case EVENT_INTERFACE_POK:
+ m_main->ChangePhase(PHASE_INIT);
+ break;
+
+ case EVENT_INTERFACE_PCANCEL:
+ m_perso = m_persoCopy;
+ WriteGamerPerso(m_main->RetGamerName());
+ m_main->ChangePhase(PHASE_NAME);
+ break;
+ }
+ }
+
+ if ( m_phase == PHASE_TRAINER ||
+ m_phase == PHASE_DEFI ||
+ m_phase == PHASE_MISSION ||
+ m_phase == PHASE_FREE ||
+ m_phase == PHASE_TEEN ||
+ m_phase == PHASE_USER ||
+ m_phase == PHASE_PROTO )
+ {
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return FALSE;
+
+ if ( event.event == pw->RetEventMsgClose() ||
+ event.event == EVENT_INTERFACE_BACK ||
+ (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) )
+ {
+ m_main->ChangePhase(PHASE_INIT);
+ return FALSE;
+ }
+ }
+
+ if ( m_phase == PHASE_TRAINER ||
+ m_phase == PHASE_DEFI ||
+ m_phase == PHASE_MISSION ||
+ m_phase == PHASE_FREE ||
+ m_phase == PHASE_TEEN ||
+ m_phase == PHASE_USER ||
+ m_phase == PHASE_PROTO )
+ {
+ switch( event.event )
+ {
+ case EVENT_INTERFACE_CHAP:
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_CHAP);
+ if ( pl == 0 ) break;
+ m_chap[m_index] = pl->RetSelect();
+ UpdateSceneList(m_chap[m_index], m_sel[m_index]);
+ UpdateSceneResume((m_chap[m_index]+1)*100+(m_sel[m_index]+1));
+ break;
+
+ case EVENT_INTERFACE_LIST:
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_LIST);
+ if ( pl == 0 ) break;
+ m_sel[m_index] = pl->RetSelect();
+ UpdateSceneResume((m_chap[m_index]+1)*100+(m_sel[m_index]+1));
+ break;
+
+ case EVENT_INTERFACE_SOLUCE:
+ pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_SOLUCE);
+ if ( pb == 0 ) break;
+ m_bSceneSoluce = !m_bSceneSoluce;
+ pb->SetState(STATE_CHECK, m_bSceneSoluce);
+ break;
+
+ case EVENT_INTERFACE_PLAY:
+ if ( m_phase == PHASE_PROTO && m_chap[m_index] == 0 && m_sel[m_index] == 0 )
+ {
+ m_main->ChangePhase(PHASE_MODEL);
+ break;
+ }
+ m_sceneRank = (m_chap[m_index]+1)*100+(m_sel[m_index]+1);
+ m_phaseTerm = m_phase;
+ m_main->ChangePhase(PHASE_LOADING);
+ break;
+
+ case EVENT_INTERFACE_READ:
+ m_phaseTerm = m_phase;
+ m_main->ChangePhase(PHASE_READ);
+ break;
+ }
+ return FALSE;
+ }
+
+ if ( m_phase == PHASE_SETUPd ||
+ m_phase == PHASE_SETUPg ||
+ m_phase == PHASE_SETUPp ||
+ m_phase == PHASE_SETUPc ||
+ m_phase == PHASE_SETUPs )
+ {
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return FALSE;
+
+ if ( event.event == pw->RetEventMsgClose() ||
+ event.event == EVENT_INTERFACE_BACK ||
+ (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) )
+ {
+ SetupMemorize();
+ m_engine->ApplyChange();
+ m_main->ChangePhase(PHASE_INIT);
+ return FALSE;
+ }
+
+ switch( event.event )
+ {
+ case EVENT_INTERFACE_SETUPd:
+ m_main->ChangePhase(PHASE_SETUPd);
+ break;
+
+ case EVENT_INTERFACE_SETUPg:
+ m_main->ChangePhase(PHASE_SETUPg);
+ break;
+
+ case EVENT_INTERFACE_SETUPp:
+ m_main->ChangePhase(PHASE_SETUPp);
+ break;
+
+ case EVENT_INTERFACE_SETUPc:
+ m_main->ChangePhase(PHASE_SETUPc);
+ break;
+
+ case EVENT_INTERFACE_SETUPs:
+ m_main->ChangePhase(PHASE_SETUPs);
+ break;
+ }
+ }
+
+ if ( m_phase == PHASE_SETUPds ||
+ m_phase == PHASE_SETUPgs ||
+ m_phase == PHASE_SETUPps ||
+ m_phase == PHASE_SETUPcs ||
+ m_phase == PHASE_SETUPss )
+ {
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return FALSE;
+
+ if ( event.event == pw->RetEventMsgClose() ||
+ event.event == EVENT_INTERFACE_BACK ||
+ (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) )
+ {
+ SetupMemorize();
+ m_engine->ApplyChange();
+ m_interface->DeleteControl(EVENT_WINDOW5);
+ ChangePhase(PHASE_SIMUL);
+ StopSuspend();
+ return FALSE;
+ }
+
+ switch( event.event )
+ {
+ case EVENT_INTERFACE_SETUPd:
+ ChangePhase(PHASE_SETUPds);
+ break;
+
+ case EVENT_INTERFACE_SETUPg:
+ ChangePhase(PHASE_SETUPgs);
+ break;
+
+ case EVENT_INTERFACE_SETUPp:
+ ChangePhase(PHASE_SETUPps);
+ break;
+
+ case EVENT_INTERFACE_SETUPc:
+ ChangePhase(PHASE_SETUPcs);
+ break;
+
+ case EVENT_INTERFACE_SETUPs:
+ ChangePhase(PHASE_SETUPss);
+ break;
+ }
+ }
+
+ if ( m_phase == PHASE_SETUPd || // setup/display ?
+ m_phase == PHASE_SETUPds )
+ {
+ switch( event.event )
+ {
+ case EVENT_LIST1:
+ case EVENT_LIST2:
+ UpdateApply();
+ break;
+
+ case EVENT_INTERFACE_FULL:
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) break;
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_FULL);
+ if ( pc == 0 ) break;
+ pl = (CList*)pw->SearchControl(EVENT_LIST2);
+ if ( pl == 0 ) break;
+ if ( pc->TestState(STATE_CHECK) )
+ {
+ pc->ClearState(STATE_CHECK); // window
+ pl->ClearState(STATE_ENABLE);
+ }
+ else
+ {
+ pc->SetState(STATE_CHECK); // fullscreen
+ pl->SetState(STATE_ENABLE);
+ }
+ UpdateApply();
+ break;
+
+ case EVENT_INTERFACE_APPLY:
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) break;
+ pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_APPLY);
+ if ( pb == 0 ) break;
+ pb->ClearState(STATE_PRESS);
+ pb->ClearState(STATE_HILIGHT);
+ ChangeDisplay();
+ UpdateApply();
+ break;
+ }
+ return FALSE;
+ }
+
+ if ( m_phase == PHASE_SETUPg || // setup/graphic ?
+ m_phase == PHASE_SETUPgs )
+ {
+ switch( event.event )
+ {
+ case EVENT_INTERFACE_SHADOW:
+ m_engine->SetShadow(!m_engine->RetShadow());
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_GROUND:
+ m_engine->SetGroundSpot(!m_engine->RetGroundSpot());
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_DIRTY:
+ m_engine->SetDirty(!m_engine->RetDirty());
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_FOG:
+ m_engine->SetFog(!m_engine->RetFog());
+ m_camera->SetOverBaseColor(RetColor(RetColor(0.0f)));
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_LENS:
+ m_engine->SetLensMode(!m_engine->RetLensMode());
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_SKY:
+ m_engine->SetSkyMode(!m_engine->RetSkyMode());
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_PLANET:
+ m_engine->SetPlanetMode(!m_engine->RetPlanetMode());
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_LIGHT:
+ m_engine->SetLightMode(!m_engine->RetLightMode());
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_PARTI:
+ case EVENT_INTERFACE_CLIP:
+ case EVENT_INTERFACE_DETAIL:
+ case EVENT_INTERFACE_GADGET:
+ case EVENT_INTERFACE_TEXTURE:
+ ChangeSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_MIN:
+ ChangeSetupQuality(-1);
+ UpdateSetupButtons();
+ break;
+ case EVENT_INTERFACE_NORM:
+ ChangeSetupQuality(0);
+ UpdateSetupButtons();
+ break;
+ case EVENT_INTERFACE_MAX:
+ ChangeSetupQuality(1);
+ UpdateSetupButtons();
+ break;
+ }
+ return FALSE;
+ }
+
+ if ( m_phase == PHASE_SETUPp || // setup/game ?
+ m_phase == PHASE_SETUPps )
+ {
+ switch( event.event )
+ {
+ case EVENT_INTERFACE_TOTO:
+ m_engine->SetTotoMode(!m_engine->RetTotoMode());
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_TOOLTIP:
+ m_bTooltip = !m_bTooltip;
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_GLINT:
+ m_bGlint = !m_bGlint;
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_RAIN:
+ m_bRain = !m_bRain;
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_MOUSE:
+ m_engine->SetNiceMouse(!m_engine->RetNiceMouse());
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_EDITMODE:
+ m_engine->SetEditIndentMode(!m_engine->RetEditIndentMode());
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_EDITVALUE:
+ if ( m_engine->RetEditIndentValue() == 2 )
+ {
+ m_engine->SetEditIndentValue(4);
+ }
+ else
+ {
+ m_engine->SetEditIndentValue(2);
+ }
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_SOLUCE4:
+ m_bSoluce4 = !m_bSoluce4;
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_MOVIES:
+ m_bMovies = !m_bMovies;
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_NICERST:
+ m_bNiceReset = !m_bNiceReset;
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_HIMSELF:
+ m_bHimselfDamage = !m_bHimselfDamage;
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_SCROLL:
+ m_bCameraScroll = !m_bCameraScroll;
+ m_camera->SetCameraScroll(m_bCameraScroll);
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_INVERTX:
+ m_bCameraInvertX = !m_bCameraInvertX;
+ m_camera->SetCameraInvertX(m_bCameraInvertX);
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_INVERTY:
+ m_bCameraInvertY = !m_bCameraInvertY;
+ m_camera->SetCameraInvertY(m_bCameraInvertY);
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_EFFECT:
+ m_bEffect = !m_bEffect;
+ m_camera->SetEffect(m_bEffect);
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+ }
+ return FALSE;
+ }
+
+ if ( m_phase == PHASE_SETUPc || // setup/commands ?
+ m_phase == PHASE_SETUPcs )
+ {
+ switch( event.event )
+ {
+ case EVENT_INTERFACE_KSCROLL:
+ UpdateKey();
+ break;
+
+ case EVENT_INTERFACE_KLEFT:
+ case EVENT_INTERFACE_KRIGHT:
+ case EVENT_INTERFACE_KUP:
+ case EVENT_INTERFACE_KDOWN:
+ case EVENT_INTERFACE_KGUP:
+ case EVENT_INTERFACE_KGDOWN:
+ case EVENT_INTERFACE_KCAMERA:
+ case EVENT_INTERFACE_KDESEL:
+ case EVENT_INTERFACE_KACTION:
+ case EVENT_INTERFACE_KNEAR:
+ case EVENT_INTERFACE_KAWAY:
+ case EVENT_INTERFACE_KNEXT:
+ case EVENT_INTERFACE_KHUMAN:
+ case EVENT_INTERFACE_KQUIT:
+ case EVENT_INTERFACE_KHELP:
+ case EVENT_INTERFACE_KPROG:
+ case EVENT_INTERFACE_KCBOT:
+ case EVENT_INTERFACE_KSPEED10:
+ case EVENT_INTERFACE_KSPEED15:
+ case EVENT_INTERFACE_KSPEED20:
+ case EVENT_INTERFACE_KSPEED30:
+ case EVENT_INTERFACE_KVISIT:
+ ChangeKey(event.event);
+ UpdateKey();
+ break;
+
+ case EVENT_INTERFACE_KDEF:
+ m_engine->ResetKey();
+ UpdateKey();
+ break;
+
+ case EVENT_INTERFACE_JOYSTICK:
+ m_engine->SetJoystick(!m_engine->RetJoystick());
+ UpdateSetupButtons();
+ break;
+ }
+ return FALSE;
+ }
+
+ if ( m_phase == PHASE_SETUPs || // setup/sound ?
+ m_phase == PHASE_SETUPss )
+ {
+ switch( event.event )
+ {
+ case EVENT_INTERFACE_VOLSOUND:
+ case EVENT_INTERFACE_VOLMUSIC:
+ ChangeSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_SOUND3D:
+ m_sound->SetSound3D(!m_sound->RetSound3D());
+ ChangeSetupButtons();
+ UpdateSetupButtons();
+ break;
+
+ case EVENT_INTERFACE_SILENT:
+ m_sound->SetAudioVolume(0);
+ m_sound->SetMidiVolume(0);
+ UpdateSetupButtons();
+ break;
+ case EVENT_INTERFACE_NOISY:
+ m_sound->SetAudioVolume(MAXVOLUME);
+ m_sound->SetMidiVolume(MAXVOLUME*3/4);
+ UpdateSetupButtons();
+ break;
+ }
+ return FALSE;
+ }
+
+ if ( m_phase == PHASE_READ )
+ {
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return FALSE;
+
+ if ( event.event == pw->RetEventMsgClose() ||
+ event.event == EVENT_INTERFACE_BACK ||
+ (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) )
+ {
+ ChangePhase(m_phaseTerm);
+ }
+
+ if ( event.event == EVENT_INTERFACE_IOLIST )
+ {
+ IOUpdateList();
+ }
+ if ( event.event == EVENT_INTERFACE_IODELETE )
+ {
+ IODeleteScene();
+ IOUpdateList();
+ }
+ if ( event.event == EVENT_INTERFACE_IOREAD )
+ {
+ if ( IOReadScene() )
+ {
+ m_main->ChangePhase(PHASE_LOADING);
+ }
+ }
+
+ return FALSE;
+ }
+
+ if ( m_phase == PHASE_WRITEs ||
+ m_phase == PHASE_READs )
+ {
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return FALSE;
+
+ if ( event.event == pw->RetEventMsgClose() ||
+ event.event == EVENT_INTERFACE_BACK ||
+ (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) )
+ {
+ m_interface->DeleteControl(EVENT_WINDOW5);
+ ChangePhase(PHASE_SIMUL);
+ StopSuspend();
+ }
+
+ if ( event.event == EVENT_INTERFACE_IOLIST )
+ {
+ IOUpdateList();
+ }
+ if ( event.event == EVENT_INTERFACE_IODELETE )
+ {
+ IODeleteScene();
+ IOUpdateList();
+ }
+ if ( event.event == EVENT_INTERFACE_IOWRITE )
+ {
+ IOWriteScene();
+ m_interface->DeleteControl(EVENT_WINDOW5);
+ ChangePhase(PHASE_SIMUL);
+ StopSuspend();
+ }
+ if ( event.event == EVENT_INTERFACE_IOREAD )
+ {
+ if ( IOReadScene() )
+ {
+ m_interface->DeleteControl(EVENT_WINDOW5);
+ ChangePhase(PHASE_SIMUL);
+ StopSuspend();
+ m_main->ChangePhase(PHASE_LOADING);
+ }
+ }
+
+ return FALSE;
+ }
+
+ if ( m_phase == PHASE_WELCOME1 )
+ {
+ if ( event.event == EVENT_KEYDOWN ||
+ event.event == EVENT_LBUTTONDOWN ||
+ event.event == EVENT_RBUTTONDOWN )
+ {
+ ChangePhase(PHASE_WELCOME2);
+ return TRUE;
+ }
+ }
+ if ( m_phase == PHASE_WELCOME2 )
+ {
+ if ( event.event == EVENT_KEYDOWN ||
+ event.event == EVENT_LBUTTONDOWN ||
+ event.event == EVENT_RBUTTONDOWN )
+ {
+ ChangePhase(PHASE_WELCOME3);
+ return TRUE;
+ }
+ }
+ if ( m_phase == PHASE_WELCOME3 )
+ {
+ if ( event.event == EVENT_KEYDOWN ||
+ event.event == EVENT_LBUTTONDOWN ||
+ event.event == EVENT_RBUTTONDOWN )
+ {
+ ChangePhase(PHASE_NAME);
+ return TRUE;
+ }
+ }
+
+ if ( m_phase == PHASE_GENERIC )
+ {
+ if ( event.event == EVENT_INTERFACE_ABORT )
+ {
+ ChangePhase(PHASE_INIT);
+ }
+
+ if ( event.event == EVENT_KEYDOWN )
+ {
+ if ( event.param == VK_ESCAPE )
+ {
+ ChangePhase(PHASE_INIT);
+ }
+ else
+ {
+ m_event->MakeEvent(newEvent, EVENT_QUIT);
+ m_event->AddEvent(newEvent);
+ }
+ }
+
+ if ( event.event == EVENT_LBUTTONDOWN ||
+ event.event == EVENT_RBUTTONDOWN )
+ {
+ m_event->MakeEvent(newEvent, EVENT_QUIT);
+ m_event->AddEvent(newEvent);
+ }
+ }
+
+ return TRUE;
+}
+
+
+// Moves the reflections.
+
+void CMainDialog::GlintMove()
+{
+ CWindow* pw;
+ CGroup* pg;
+ FPOINT pos, dim, zoom;
+
+ if ( m_phase == PHASE_SIMUL ) return;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+
+ if ( m_phase == PHASE_INIT )
+ {
+ pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTl);
+ if ( pg != 0 )
+ {
+ zoom.x = sinf(m_glintTime*0.23f);
+ zoom.y = sinf(m_glintTime*0.37f);
+ pos.x = 0.35f;
+ pos.y = 0.90f;
+ dim.x = 0.30f-0.10f*(zoom.x+1.0f)/2.0f;
+ dim.y = 0.50f-0.30f*(zoom.y+1.0f)/2.0f;
+ pos.y -= dim.y;
+ pg->SetPos(pos);
+ pg->SetDim(dim);
+ }
+
+ pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTr);
+ if ( pg != 0 )
+ {
+ zoom.x = sinf(m_glintTime*0.21f);
+ zoom.y = sinf(m_glintTime*0.26f);
+ pos.x = 0.65f;
+ pos.y = 0.10f;
+ dim.x = 0.30f-0.10f*(zoom.x+1.0f)/2.0f;
+ dim.y = 0.50f-0.30f*(zoom.y+1.0f)/2.0f;
+ pos.x -= dim.x;
+ pg->SetPos(pos);
+ pg->SetDim(dim);
+ }
+ }
+
+ if ( m_phase == PHASE_NAME ||
+ m_phase == PHASE_TRAINER ||
+ m_phase == PHASE_MISSION ||
+ m_phase == PHASE_FREE ||
+ m_phase == PHASE_TEEN ||
+ m_phase == PHASE_USER ||
+ m_phase == PHASE_PROTO )
+ {
+ pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTl);
+ if ( pg != 0 )
+ {
+ zoom.x = sinf(m_glintTime*0.22f);
+ zoom.y = sinf(m_glintTime*0.37f);
+ pos.x = 0.10f;
+ pos.y = 0.90f;
+ dim.x = 0.60f+0.30f*zoom.x;
+ dim.y = 0.60f+0.30f*zoom.y;
+ pos.y -= dim.y;
+ pg->SetPos(pos);
+ pg->SetDim(dim);
+ }
+
+ pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTr);
+ if ( pg != 0 )
+ {
+ zoom.x = sinf(m_glintTime*0.19f);
+ zoom.y = sinf(m_glintTime*0.28f);
+ pos.x = 0.90f;
+ pos.y = 0.10f;
+ dim.x = 0.60f+0.30f*zoom.x;
+ dim.y = 0.60f+0.30f*zoom.y;
+ pos.x -= dim.x;
+ pg->SetPos(pos);
+ pg->SetDim(dim);
+ }
+ }
+
+ if ( m_phase == PHASE_SETUPd ||
+ m_phase == PHASE_SETUPg ||
+ m_phase == PHASE_SETUPp ||
+ m_phase == PHASE_SETUPc ||
+ m_phase == PHASE_SETUPs ||
+ m_phase == PHASE_SETUPds ||
+ m_phase == PHASE_SETUPgs ||
+ m_phase == PHASE_SETUPps ||
+ m_phase == PHASE_SETUPcs ||
+ m_phase == PHASE_SETUPss )
+ {
+ pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTu);
+ if ( pg != 0 )
+ {
+ zoom.y = sinf(m_glintTime*0.27f);
+ pos.x = 0.10f;
+ pos.y = 0.76f;
+ dim.x = 0.80f;
+ dim.y = 0.32f+0.20f*zoom.y;
+ pos.y -= dim.y;
+ pg->SetPos(pos);
+ pg->SetDim(dim);
+ }
+
+ pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTr);
+ if ( pg != 0 )
+ {
+ zoom.x = sinf(m_glintTime*0.29f);
+ zoom.y = sinf(m_glintTime*0.14f);
+ pos.x = 0.90f;
+ pos.y = 0.10f;
+ dim.x = 0.40f+0.20f*zoom.x;
+ dim.y = 0.40f+0.20f*zoom.y;
+ pos.x -= dim.x;
+ pg->SetPos(pos);
+ pg->SetDim(dim);
+ }
+ }
+
+ if ( m_phase == PHASE_WRITE ||
+ m_phase == PHASE_READ ||
+ m_phase == PHASE_WRITEs ||
+ m_phase == PHASE_READs )
+ {
+ pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTl);
+ if ( pg != 0 )
+ {
+ zoom.x = sinf(m_glintTime*0.22f);
+ zoom.y = sinf(m_glintTime*0.37f);
+ pos.x = 0.10f;
+ pos.y = 0.90f;
+ dim.x = 0.60f+0.30f*zoom.x;
+ dim.y = 0.60f+0.30f*zoom.y;
+ pos.y -= dim.y;
+ pg->SetPos(pos);
+ pg->SetDim(dim);
+ }
+
+ pg = (CGroup*)pw->SearchControl(EVENT_INTERFACE_GLINTr);
+ if ( pg != 0 )
+ {
+ zoom.x = sinf(m_glintTime*0.19f);
+ zoom.y = sinf(m_glintTime*0.28f);
+ pos.x = 0.90f;
+ pos.y = 0.10f;
+ dim.x = 0.60f+0.30f*zoom.x;
+ dim.y = 0.60f+0.30f*zoom.y;
+ pos.x -= dim.x;
+ pg->SetPos(pos);
+ pg->SetDim(dim);
+ }
+ }
+}
+
+
+// Returns the position for a sound.
+
+D3DVECTOR SoundPos(FPOINT pos)
+{
+ D3DVECTOR s;
+
+ s.x = (pos.x-0.5f)*2.0f;
+ s.y = (pos.y-0.5f)*2.0f;
+ s.z = 0.0f;
+
+ return s;
+}
+
+// Returns a random position for a sound.
+
+D3DVECTOR SoundRand()
+{
+ D3DVECTOR s;
+
+ s.x = (Rand()-0.5f)*2.0f;
+ s.y = (Rand()-0.5f)*2.0f;
+ s.z = 0.0f;
+
+ return s;
+}
+
+// Makes pretty qq particles evolve.
+
+void CMainDialog::FrameParticule(float rTime)
+{
+#if _NEWLOOK
+#else
+ D3DVECTOR pos, speed;
+ FPOINT dim;
+ float *pParti, *pGlint;
+ int nParti, nGlint;
+ int i, r, ii;
+
+ static float partiPosInit[1+5*12] =
+ { // x x t2 t2 type
+ 12.0f,
+ 607.0f, 164.0f, 0.2f, 0.8f, 1.0f, // upper cable
+ 604.0f, 205.0f, 0.1f, 0.3f, 1.0f, // middle cable
+ 603.0f, 247.0f, 0.1f, 0.3f, 1.0f, // lower cable
+ 119.0f, 155.0f, 0.2f, 0.4f, 2.0f, // left pipe
+ 366.0f, 23.0f, 0.5f, 1.5f, 4.0f, // upper pipe
+ 560.0f, 414.0f, 0.1f, 0.1f, 1.0f, // button lower/right
+ 20.0f, 413.0f, 0.1f, 0.1f, 2.0f, // button lower/left
+ 39.0f, 78.0f, 0.1f, 0.2f, 1.0f, // left pot
+ 39.0f, 78.0f, 0.5f, 0.9f, 1.0f, // left pot
+ 170.0f, 229.0f, 0.5f, 0.5f, 3.0f, // left smoke
+ 170.0f, 229.0f, 0.5f, 0.5f, 3.0f, // left smoke
+ 474.0f, 229.0f, 0.5f, 0.5f, 3.0f, // right smoke
+ };
+
+ static float glintPosInit[1+2*14] =
+ {
+ 14.0f,
+ 15.0f, 407.0f,
+ 68.0f, 417.0f,
+ 548.0f, 36.0f,
+ 611.0f, 37.0f,
+ 611.0f, 100.0f,
+ 611.0f, 395.0f,
+ 36.0f, 35.0f,
+ 166.0f, 55.0f,
+ 166.0f, 94.0f,
+ 477.0f, 56.0f,
+ 31.0f, 190.0f,
+ 32.0f, 220.0f,
+ 65.0f, 221.0f,
+ 65.0f, 250.0f,
+ };
+
+ static float partiPosBig[1+5*12] =
+ { // x x t2 t2 type
+ 12.0f,
+ 607.0f, 164.0f, 0.2f, 0.8f, 1.0f, // upper cable
+ 604.0f, 205.0f, 0.1f, 0.3f, 1.0f, // middle cable
+ 603.0f, 247.0f, 0.1f, 0.3f, 1.0f, // lower cable
+ 64.0f, 444.0f, 0.2f, 0.8f, 1.0f, // down the left cable
+ 113.0f, 449.0f, 0.1f, 0.3f, 1.0f, // down the left cable
+ 340.0f, 463.0f, 0.2f, 0.8f, 1.0f, // down the middle cable
+ 36.0f, 155.0f, 0.2f, 0.4f, 2.0f, // left pipe
+ 366.0f, 23.0f, 0.5f, 1.5f, 4.0f, // upper pipe
+ 612.0f, 414.0f, 0.1f, 0.1f, 1.0f, // button lower/right
+ 20.0f, 413.0f, 0.1f, 0.1f, 2.0f, // button lower/left
+ 39.0f, 78.0f, 0.1f, 0.2f, 1.0f, // left pot
+ 39.0f, 78.0f, 0.5f, 0.9f, 1.0f, // left pot
+ };
+
+ static float glintPosBig[1+2*12] =
+ {
+ 12.0f,
+ 15.0f, 407.0f,
+ 48.0f, 399.0f,
+ 611.0f, 37.0f,
+ 611.0f, 100.0f,
+ 611.0f, 395.0f,
+ 36.0f, 35.0f,
+ 31.0f, 190.0f,
+ 32.0f, 220.0f,
+ 31.0f, 221.0f,
+ 31.0f, 189.0f,
+ 255.0f, 18.0f,
+ 279.0f, 18.0f,
+ };
+
+ if ( m_bDialog || !m_bRain ) return;
+
+ if ( m_phase == PHASE_INIT )
+ {
+ pParti = partiPosInit;
+ pGlint = glintPosInit;
+ }
+ else if ( m_phase == PHASE_NAME ||
+ m_phase == PHASE_TRAINER ||
+ m_phase == PHASE_DEFI ||
+ m_phase == PHASE_MISSION ||
+ m_phase == PHASE_FREE ||
+ m_phase == PHASE_TEEN ||
+ m_phase == PHASE_USER ||
+ m_phase == PHASE_PROTO ||
+ m_phase == PHASE_SETUPd ||
+ m_phase == PHASE_SETUPg ||
+ m_phase == PHASE_SETUPp ||
+ m_phase == PHASE_SETUPc ||
+ m_phase == PHASE_SETUPs ||
+ m_phase == PHASE_WRITE ||
+ m_phase == PHASE_READ )
+ {
+ pParti = partiPosBig;
+ pGlint = glintPosBig;
+ }
+ else
+ {
+ return;
+ }
+
+ nParti = (int)(*pParti++);
+ nGlint = (int)(*pGlint++);
+
+ for ( i=0 ; i<10 ; i++ )
+ {
+ if ( m_partiPhase[i] == 0 ) // waiting?
+ {
+ m_partiTime[i] -= rTime;
+ if ( m_partiTime[i] <= 0.0f )
+ {
+ r = rand()%3;
+
+ if ( r == 0 )
+ {
+ ii = rand()%nParti;
+ m_partiPos[i].x = pParti[ii*5+0]/640.0f;
+ m_partiPos[i].y = (480.0f-pParti[ii*5+1])/480.0f;
+ m_partiTime[i] = pParti[ii*5+2]+Rand()*pParti[ii*5+3];
+ m_partiPhase[i] = (int)pParti[ii*5+4];
+ if ( m_partiPhase[i] == 3 )
+ {
+ m_sound->Play(SOUND_PSHHH, SoundPos(m_partiPos[i]), 0.3f+Rand()*0.3f);
+ }
+ else
+ {
+ m_sound->Play(SOUND_GGG, SoundPos(m_partiPos[i]), 0.1f+Rand()*0.4f);
+ }
+ }
+
+ if ( r == 1 )
+ {
+ ii = rand()%nGlint;
+ pos.x = pGlint[ii*2+0]/640.0f;
+ pos.y = (480.0f-pGlint[ii*2+1])/480.0f;
+ pos.z = 0.0f;
+ speed.x = 0.0f;
+ speed.y = 0.0f;
+ speed.z = 0.0f;
+ dim.x = 0.04f+Rand()*0.04f;
+ dim.y = dim.x/0.75f;
+ m_particule->CreateParticule(pos, speed, dim,
+ rand()%2?PARTIGLINT:PARTICONTROL,
+ Rand()*0.4f+0.4f, 0.0f, 0.0f,
+ SH_INTERFACE);
+ m_partiTime[i] = 0.5f+Rand()*0.5f;
+ }
+
+ if ( r == 2 )
+ {
+ ii = rand()%7;
+ if ( ii == 0 )
+ {
+ m_sound->Play(SOUND_ENERGY, SoundRand(), 0.2f+Rand()*0.2f);
+ m_partiTime[i] = 1.0f+Rand()*1.0f;
+ }
+ if ( ii == 1 )
+ {
+ m_sound->Play(SOUND_STATION, SoundRand(), 0.2f+Rand()*0.2f);
+ m_partiTime[i] = 1.0f+Rand()*2.0f;
+ }
+ if ( ii == 2 )
+ {
+ m_sound->Play(SOUND_ALARM, SoundRand(), 0.1f+Rand()*0.1f);
+ m_partiTime[i] = 2.0f+Rand()*4.0f;
+ }
+ if ( ii == 3 )
+ {
+ m_sound->Play(SOUND_INFO, SoundRand(), 0.1f+Rand()*0.1f);
+ m_partiTime[i] = 2.0f+Rand()*4.0f;
+ }
+ if ( ii == 4 )
+ {
+ m_sound->Play(SOUND_RADAR, SoundRand(), 0.2f+Rand()*0.2f);
+ m_partiTime[i] = 0.5f+Rand()*1.0f;
+ }
+ if ( ii == 5 )
+ {
+ m_sound->Play(SOUND_GFLAT, SoundRand(), 0.3f+Rand()*0.3f);
+ m_partiTime[i] = 2.0f+Rand()*4.0f;
+ }
+ if ( ii == 6 )
+ {
+ m_sound->Play(SOUND_ALARMt, SoundRand(), 0.1f+Rand()*0.1f);
+ m_partiTime[i] = 2.0f+Rand()*4.0f;
+ }
+ }
+ }
+ }
+
+ if ( m_partiPhase[i] != 0 ) // generates?
+ {
+ m_partiTime[i] -= rTime;
+ if ( m_partiTime[i] > 0.0f )
+ {
+ if ( m_partiPhase[i] == 1 ) // sparks?
+ {
+ pos.x = m_partiPos[i].x;
+ pos.y = m_partiPos[i].y;
+ pos.z = 0.0f;
+ pos.x += (Rand()-0.5f)*0.01f;
+ pos.y += (Rand()-0.5f)*0.01f;
+ speed.x = (Rand()-0.5f)*0.2f;
+ speed.y = (Rand()-0.5f)*0.2f;
+ speed.z = 0.0f;
+ dim.x = 0.005f+Rand()*0.005f;
+ dim.y = dim.x/0.75f;
+ m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ,
+ Rand()*0.2f+0.2f, 0.0f, 0.0f,
+ SH_INTERFACE);
+ pos.x = m_partiPos[i].x;
+ pos.y = m_partiPos[i].y;
+ pos.z = 0.0f;
+ speed.x = (Rand()-0.5f)*0.5f;
+ speed.y = (0.3f+Rand()*0.3f);
+ speed.z = 0.0f;
+ dim.x = 0.01f+Rand()*0.01f;
+ dim.y = dim.x/0.75f;
+ m_particule->CreateParticule(pos, speed, dim,
+ (ParticuleType)(PARTILENS1+rand()%3),
+ Rand()*0.5f+0.5f, 2.0f, 0.0f,
+ SH_INTERFACE);
+ }
+ if ( m_partiPhase[i] == 2 ) // sparks?
+ {
+ pos.x = m_partiPos[i].x;
+ pos.y = m_partiPos[i].y;
+ pos.z = 0.0f;
+ pos.x += (Rand()-0.5f)*0.01f;
+ pos.y += (Rand()-0.5f)*0.01f;
+ speed.x = (Rand()-0.5f)*0.2f;
+ speed.y = (Rand()-0.5f)*0.2f;
+ speed.z = 0.0f;
+ dim.x = 0.005f+Rand()*0.005f;
+ dim.y = dim.x/0.75f;
+ m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ,
+ Rand()*0.2f+0.2f, 0.0f, 0.0f,
+ SH_INTERFACE);
+ pos.x = m_partiPos[i].x;
+ pos.y = m_partiPos[i].y;
+ pos.z = 0.0f;
+ speed.x = (Rand()-0.5f)*0.5f;
+ speed.y = (0.3f+Rand()*0.3f);
+ speed.z = 0.0f;
+ dim.x = 0.005f+Rand()*0.005f;
+ dim.y = dim.x/0.75f;
+ m_particule->CreateParticule(pos, speed, dim, PARTISCRAPS,
+ Rand()*0.5f+0.5f, 2.0f, 0.0f,
+ SH_INTERFACE);
+ }
+ if ( m_partiPhase[i] == 3 ) // smoke?
+ {
+ pos.x = m_partiPos[i].x;
+ pos.y = m_partiPos[i].y;
+ pos.z = 0.0f;
+ pos.x += (Rand()-0.5f)*0.03f;
+ pos.y += (Rand()-0.5f)*0.03f;
+ speed.x = (Rand()-0.5f)*0.2f;
+ speed.y = Rand()*0.5f;
+ speed.z = 0.0f;
+ dim.x = 0.03f+Rand()*0.07f;
+ dim.y = dim.x/0.75f;
+ m_particule->CreateParticule(pos, speed, dim, PARTICRASH,
+ Rand()*0.4f+0.4f, 0.0f, 0.0f,
+ SH_INTERFACE);
+ }
+ }
+ else
+ {
+ m_partiPhase[i] = 0;
+ m_partiTime[i] = 2.0f+Rand()*4.0f;
+ }
+ }
+ }
+#endif
+}
+
+// Some nice particles following the mouse.
+
+void CMainDialog::NiceParticule(FPOINT mouse, BOOL bPress)
+{
+ D3DVECTOR pos, speed;
+ FPOINT dim;
+
+ if ( !m_bRain ) return;
+ if ( (m_phase == PHASE_SIMUL ||
+ m_phase == PHASE_WIN ||
+ m_phase == PHASE_LOST ||
+ m_phase == PHASE_MODEL ) &&
+ !m_bDialog ) return;
+
+ if ( bPress )
+ {
+ pos.x = mouse.x;
+ pos.y = mouse.y;
+ pos.z = 0.0f;
+ speed.x = (Rand()-0.5f)*0.5f;
+ speed.y = (0.3f+Rand()*0.3f);
+ speed.z = 0.0f;
+ dim.x = 0.005f+Rand()*0.005f;
+ dim.y = dim.x/0.75f;
+ m_particule->CreateParticule(pos, speed, dim, PARTISCRAPS,
+ Rand()*0.5f+0.5f, 2.0f, 0.0f,
+ SH_INTERFACE);
+ }
+ else
+ {
+ pos.x = mouse.x;
+ pos.y = mouse.y;
+ pos.z = 0.0f;
+ speed.x = (Rand()-0.5f)*0.5f;
+ speed.y = (0.3f+Rand()*0.3f);
+ speed.z = 0.0f;
+ dim.x = 0.01f+Rand()*0.01f;
+ dim.y = dim.x/0.75f;
+ m_particule->CreateParticule(pos, speed, dim,
+ (ParticuleType)(PARTILENS1+rand()%3),
+ Rand()*0.5f+0.5f, 2.0f, 0.0f,
+ SH_INTERFACE);
+ }
+}
+
+
+
+// Specifies the special user folder if needed.
+
+void CMainDialog::SetUserDir(char *base, int rank)
+{
+ char dir[100];
+
+ if ( strcmp(base, "user") == 0 && rank >= 100 )
+ {
+ sprintf(dir, "%s\\%s", m_userDir, m_userList[rank/100-1]);
+ UserDir(TRUE, dir);
+ }
+ else
+ {
+ UserDir(FALSE, "");
+ }
+}
+
+// Builds the file name of a mission.
+
+void CMainDialog::BuildSceneName(char *filename, char *base, int rank)
+{
+ if ( strcmp(base, "user") == 0 )
+ {
+ sprintf(filename, "%s\\%s\\scene%.2d.txt", m_userDir, m_userList[rank/100-1], rank%100);
+ }
+ else
+ {
+ sprintf(filename, "%s\\%s%.3d.txt", m_sceneDir, base, rank);
+ }
+}
+
+// Built the default descriptive name of a mission.
+
+void CMainDialog::BuildResumeName(char *filename, char *base, int rank)
+{
+ sprintf(filename, "Scene %s %d", base, rank);
+}
+
+// Returns the name of the file or save the files.
+
+char* CMainDialog::RetFilesDir()
+{
+ return m_filesDir;
+}
+
+
+// Updates the list of players after checking the files on disk.
+
+void CMainDialog::ReadNameList()
+{
+ CWindow* pw;
+ CList* pl;
+ long hFile;
+ struct _finddata_t fBuffer;
+ BOOL bDo;
+ char dir[_MAX_FNAME];
+ char temp[_MAX_FNAME];
+ char filenames[_MAX_FNAME][100];
+ int nbFilenames, i;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST);
+ if ( pl == 0 ) return;
+ pl->Flush();
+
+ nbFilenames = 0;
+ sprintf(dir, "%s\\*", m_savegameDir);
+ hFile = _findfirst(dir, &fBuffer);
+ if ( hFile != -1 )
+ {
+ do
+ {
+ if ( (fBuffer.attrib & _A_SUBDIR) && fBuffer.name[0] != '.' )
+ {
+ strcpy(filenames[nbFilenames++], fBuffer.name);
+ }
+ }
+ while ( _findnext(hFile, &fBuffer) == 0 && nbFilenames < 100 );
+ }
+ do // sorts all names:
+ {
+ bDo = FALSE;
+ for ( i=0 ; i<nbFilenames-1 ; i++ )
+ {
+ if ( strcmp(filenames[i], filenames[i+1]) > 0 )
+ {
+ strcpy(temp, filenames[i]);
+ strcpy(filenames[i], filenames[i+1]);
+ strcpy(filenames[i+1], temp);
+ bDo = TRUE;
+ }
+ }
+ }
+ while ( bDo );
+
+ for ( i=0 ; i<nbFilenames ; i++ )
+ {
+ pl->SetName(i, filenames[i]);
+ }
+}
+
+// Updates the controls of the players.
+
+void CMainDialog::UpdateNameControl()
+{
+ CWindow* pw;
+ CList* pl;
+ CButton* pb;
+ CEdit* pe;
+ char name[100];
+ char* gamer;
+ int total, sel;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST);
+ if ( pl == 0 ) return;
+ pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT);
+ if ( pe == 0 ) return;
+
+ gamer = m_main->RetGamerName();
+ total = pl->RetTotal();
+ sel = pl->RetSelect();
+ pe->GetText(name, 100);
+
+ pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_NCANCEL);
+ if ( pb != 0 )
+ {
+ pb->SetState(STATE_ENABLE, gamer[0]!=0);
+ }
+
+ pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_NDELETE);
+ if ( pb != 0 )
+ {
+ pb->SetState(STATE_ENABLE, total>0 && sel!=-1);
+ }
+
+ pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_NOK);
+ if ( pb != 0 )
+ {
+ pb->SetState(STATE_ENABLE, name[0]!=0 || sel!=-1);
+ }
+
+ pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_PERSO);
+ if ( pb != 0 )
+ {
+ pb->SetState(STATE_ENABLE, name[0]!=0 || sel!=-1);
+ }
+}
+
+// Updates the list of players by name frape.
+
+void CMainDialog::UpdateNameList()
+{
+ CWindow* pw;
+ CList* pl;
+ CEdit* pe;
+ char name[100];
+ int total, sel, i;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST);
+ if ( pl == 0 ) return;
+ pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT);
+ if ( pe == 0 ) return;
+
+ pe->GetText(name, 100);
+ total = pl->RetTotal();
+ sel = pl->RetSelect();
+
+ for ( i=0 ; i<total ; i++ )
+ {
+ if ( stricmp(name, pl->RetName(i)) == 0 )
+ {
+ pl->SetSelect(i);
+ pl->ShowSelect(FALSE);
+ return;
+ }
+ }
+
+ pl->SetSelect(-1);
+}
+
+// Updates the player's name and function of the selected list.
+
+void CMainDialog::UpdateNameEdit()
+{
+ CWindow* pw;
+ CList* pl;
+ CEdit* pe;
+ char* name;
+ int sel;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST);
+ if ( pl == 0 ) return;
+ pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT);
+ if ( pe == 0 ) return;
+
+ sel = pl->RetSelect();
+ if ( sel == -1 )
+ {
+ pe->SetText("");
+ pe->SetCursor(0, 0);
+ }
+ else
+ {
+ name = pl->RetName(sel);
+ pe->SetText(name);
+ pe->SetCursor(strlen(name), 0);
+ }
+
+ UpdateNameControl();
+}
+
+// Updates the representation of the player depending on the selected list.
+
+void CMainDialog::UpdateNameFace()
+{
+ CWindow* pw;
+ CList* pl;
+ char* name;
+ int sel;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST);
+ if ( pl == 0 ) return;
+
+ sel = pl->RetSelect();
+ if ( sel == -1 ) return;
+ name = pl->RetName(sel);
+
+ ReadGamerPerso(name);
+}
+
+// Selects a player.
+
+void CMainDialog::NameSelect()
+{
+ CWindow* pw;
+ CList* pl;
+ CEdit* pe;
+ char name[100];
+ int sel;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST);
+ if ( pl == 0 ) return;
+ pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT);
+ if ( pe == 0 ) return;
+
+ pe->GetText(name, 100);
+ sel = pl->RetSelect();
+
+ if ( sel == -1 )
+ {
+ NameCreate();
+ }
+ else
+ {
+ m_main->SetGamerName(pl->RetName(sel));
+ m_main->ChangePhase(PHASE_INIT);
+ }
+
+ RetGamerFace(m_main->RetGamerName());
+
+ SetProfileString("Gamer", "LastName", m_main->RetGamerName());
+}
+
+// Creates a new player.
+
+void CMainDialog::NameCreate()
+{
+ CWindow* pw;
+ CEdit* pe;
+ char name[100];
+ char dir[100];
+ char c;
+ int len, i, j;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_NEDIT);
+ if ( pe == 0 ) return;
+
+ pe->GetText(name, 100);
+ if ( name[0] == 0 )
+ {
+ m_sound->Play(SOUND_TZOING);
+ return;
+ }
+
+ len = strlen(name);
+ j = 0;
+ for ( i=0 ; i<len ; i++ )
+ {
+ c = RetNoAccent(RetToLower(name[i]));
+ if ( (c >= '0' && c <= '9') ||
+ (c >= 'a' && c <= 'z') ||
+ c == ' ' ||
+ c == '-' ||
+ c == '_' ||
+ c == '.' ||
+ c == ',' ||
+ c == '\'' )
+ {
+ name[j++] = name[i];
+ }
+ }
+ name[j] = 0;
+ if ( j == 0 )
+ {
+ m_sound->Play(SOUND_TZOING);
+ return;
+ }
+
+ _mkdir(m_savegameDir); // if does not exist yet!
+
+ sprintf(dir, "%s\\%s", m_savegameDir, name);
+ if ( _mkdir(dir) != 0 )
+ {
+ m_sound->Play(SOUND_TZOING);
+ pe->SetText(name);
+ pe->SetCursor(strlen(name), 0);
+ pe->SetFocus(TRUE);
+ return;
+ }
+
+ SetGamerFace(name, 0);
+
+ m_main->SetGamerName(name);
+ m_main->ChangePhase(PHASE_INIT);
+}
+
+// Deletes a folder and all its offspring.
+
+BOOL RemoveDir(char *dirname)
+{
+ long hFile;
+ struct _finddata_t fBuffer;
+ char filename[100];
+
+ sprintf(filename, "%s\\*", dirname);
+ hFile = _findfirst(filename, &fBuffer);
+ if ( hFile != -1 )
+ {
+ do
+ {
+ if ( fBuffer.name[0] != '.' )
+ {
+ if ( fBuffer.attrib & _A_SUBDIR )
+ {
+ sprintf(filename, "%s\\%s", dirname, fBuffer.name);
+ RemoveDir(filename);
+ }
+ else
+ {
+ sprintf(filename, "%s\\%s", dirname, fBuffer.name);
+ remove(filename);
+ }
+ }
+ }
+ while ( _findnext(hFile, &fBuffer) == 0 );
+ }
+
+ if ( _rmdir(dirname) != 0 )
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+// Removes a player.
+
+void CMainDialog::NameDelete()
+{
+ CWindow* pw;
+ CList* pl;
+ int sel;
+ char* gamer;
+ char dir[100];
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_NLIST);
+ if ( pl == 0 ) return;
+
+ sel = pl->RetSelect();
+ if ( sel == -1 )
+ {
+ m_sound->Play(SOUND_TZOING);
+ return;
+ }
+ gamer = pl->RetName(sel);
+
+ // Deletes all the contents of the file.
+ sprintf(dir, "%s\\%s", m_savegameDir, gamer);
+ if ( !RemoveDir(dir) )
+ {
+ m_sound->Play(SOUND_TZOING);
+ return;
+ }
+
+ m_main->SetGamerName("");
+ pl->SetSelect(-1);
+
+ ReadNameList();
+ UpdateNameList();
+ UpdateNameControl();
+}
+
+
+
+// ests whether two colors are equal or nearly are.
+
+BOOL EqColor(const D3DCOLORVALUE &c1, const D3DCOLORVALUE &c2)
+{
+ return (Abs(c1.r-c2.r) < 0.01f &&
+ Abs(c1.g-c2.g) < 0.01f &&
+ Abs(c1.b-c2.b) < 0.01f );
+}
+
+// Updates all the buttons for the character.
+
+void CMainDialog::UpdatePerso()
+{
+ CWindow* pw;
+ CLabel* pl;
+ CButton* pb;
+ CColor* pc;
+ CSlider* ps;
+ D3DCOLORVALUE color;
+ char name[100];
+ int i;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+
+ pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_PHEAD);
+ if ( pb != 0 )
+ {
+ pb->SetState(STATE_CHECK, m_persoTab==0);
+ }
+ pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_PBODY);
+ if ( pb != 0 )
+ {
+ pb->SetState(STATE_CHECK, m_persoTab==1);
+ }
+
+ pl = (CLabel*)pw->SearchControl(EVENT_LABEL11);
+ if ( pl != 0 )
+ {
+ if ( m_persoTab == 0 )
+ {
+ pl->SetState(STATE_VISIBLE);
+ GetResource(RES_TEXT, RT_PERSO_FACE, name);
+ pl->SetName(name);
+ }
+ else
+ {
+ pl->ClearState(STATE_VISIBLE);
+ }
+ }
+
+ pl = (CLabel*)pw->SearchControl(EVENT_LABEL12);
+ if ( pl != 0 )
+ {
+ if ( m_persoTab == 0 )
+ {
+ pl->SetState(STATE_VISIBLE);
+ GetResource(RES_TEXT, RT_PERSO_GLASSES, name);
+ pl->SetName(name);
+ }
+ else
+ {
+ pl->ClearState(STATE_VISIBLE);
+ }
+ }
+
+ pl = (CLabel*)pw->SearchControl(EVENT_LABEL13);
+ if ( pl != 0 )
+ {
+ if ( m_persoTab == 0 ) GetResource(RES_TEXT, RT_PERSO_HAIR, name);
+ else GetResource(RES_TEXT, RT_PERSO_BAND, name);
+ pl->SetName(name);
+ }
+
+ pl = (CLabel*)pw->SearchControl(EVENT_LABEL14);
+ if ( pl != 0 )
+ {
+ if ( m_persoTab == 0 )
+ {
+ pl->ClearState(STATE_VISIBLE);
+ }
+ else
+ {
+ pl->SetState(STATE_VISIBLE);
+ GetResource(RES_TEXT, RT_PERSO_COMBI, name);
+ pl->SetName(name);
+ }
+ }
+
+ for ( i=0 ; i<4 ; i++ )
+ {
+ pb = (CButton*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PFACE1+i));
+ if ( pb == 0 ) break;
+ pb->SetState(STATE_VISIBLE, m_persoTab==0);
+ pb->SetState(STATE_CHECK, i==m_perso.face);
+ }
+
+ for ( i=0 ; i<10 ; i++ )
+ {
+ pb = (CButton*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PGLASS0+i));
+ if ( pb == 0 ) break;
+ pb->SetState(STATE_VISIBLE, m_persoTab==0);
+ pb->SetState(STATE_CHECK, i==m_perso.glasses);
+ }
+
+ for ( i=0 ; i<3*3 ; i++ )
+ {
+ pc = (CColor*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PC0a+i));
+ if ( pc == 0 ) break;
+ if ( m_persoTab == 0 )
+ {
+ pc->ClearState(STATE_VISIBLE);
+ }
+ else
+ {
+ pc->SetState(STATE_VISIBLE);
+ color.r = perso_color[3*10*1+3*i+0]/255.0f;
+ color.g = perso_color[3*10*1+3*i+1]/255.0f;
+ color.b = perso_color[3*10*1+3*i+2]/255.0f;
+ color.a = 0.0f;
+ pc->SetColor(color);
+ pc->SetState(STATE_CHECK, EqColor(color, m_perso.colorCombi));
+ }
+
+ pc = (CColor*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PC0b+i));
+ if ( pc == 0 ) break;
+ color.r = perso_color[3*10*2*m_persoTab+3*i+0]/255.0f;
+ color.g = perso_color[3*10*2*m_persoTab+3*i+1]/255.0f;
+ color.b = perso_color[3*10*2*m_persoTab+3*i+2]/255.0f;
+ color.a = 0.0f;
+ pc->SetColor(color);
+ pc->SetState(STATE_CHECK, EqColor(color, m_persoTab?m_perso.colorBand:m_perso.colorHair));
+ }
+
+ for ( i=0 ; i<3 ; i++ )
+ {
+ ps = (CSlider*)pw->SearchControl((EventMsg)(EVENT_INTERFACE_PCRa+i));
+ if ( ps == 0 ) break;
+ ps->SetState(STATE_VISIBLE, m_persoTab==1);
+ }
+
+ if ( m_persoTab == 1 )
+ {
+ color = m_perso.colorCombi;
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCRa);
+ if ( ps != 0 ) ps->SetVisibleValue(color.r*255.0f);
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCGa);
+ if ( ps != 0 ) ps->SetVisibleValue(color.g*255.0f);
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCBa);
+ if ( ps != 0 ) ps->SetVisibleValue(color.b*255.0f);
+ }
+
+ if ( m_persoTab == 0 ) color = m_perso.colorHair;
+ else color = m_perso.colorBand;
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCRb);
+ if ( ps != 0 ) ps->SetVisibleValue(color.r*255.0f);
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCGb);
+ if ( ps != 0 ) ps->SetVisibleValue(color.g*255.0f);
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCBb);
+ if ( ps != 0 ) ps->SetVisibleValue(color.b*255.0f);
+}
+
+// Updates the camera for the character.
+
+void CMainDialog::CameraPerso()
+{
+ if ( m_persoTab == 0 )
+ {
+//? m_camera->Init(D3DVECTOR(4.0f, 0.0f, 0.0f),
+//? D3DVECTOR(0.0f, 0.0f, 1.0f), 0.0f);
+ m_camera->Init(D3DVECTOR(6.0f, 0.0f, 0.0f),
+ D3DVECTOR(0.0f, 0.2f, 1.5f), 0.0f);
+ }
+ else
+ {
+ m_camera->Init(D3DVECTOR(18.0f, 0.0f, 4.5f),
+ D3DVECTOR(0.0f, 1.6f, 4.5f), 0.0f);
+ }
+
+ m_camera->SetType(CAMERA_SCRIPT);
+ m_camera->FixCamera();
+}
+
+// Sets a fixed color.
+
+void CMainDialog::FixPerso(int rank, int index)
+{
+ if ( m_persoTab == 0 )
+ {
+ if ( index == 1 )
+ {
+ m_perso.colorHair.r = perso_color[3*10*0+rank*3+0]/255.0f;
+ m_perso.colorHair.g = perso_color[3*10*0+rank*3+1]/255.0f;
+ m_perso.colorHair.b = perso_color[3*10*0+rank*3+2]/255.0f;
+ }
+ }
+ if ( m_persoTab == 1 )
+ {
+ if ( index == 0 )
+ {
+ m_perso.colorCombi.r = perso_color[3*10*1+rank*3+0]/255.0f;
+ m_perso.colorCombi.g = perso_color[3*10*1+rank*3+1]/255.0f;
+ m_perso.colorCombi.b = perso_color[3*10*1+rank*3+2]/255.0f;
+ }
+ if ( index == 1 )
+ {
+ m_perso.colorBand.r = perso_color[3*10*2+rank*3+0]/255.0f;
+ m_perso.colorBand.g = perso_color[3*10*2+rank*3+1]/255.0f;
+ m_perso.colorBand.b = perso_color[3*10*2+rank*3+2]/255.0f;
+ }
+ }
+}
+
+// Updates the color of the character.
+
+void CMainDialog::ColorPerso()
+{
+ CWindow* pw;
+ CSlider* ps;
+ D3DCOLORVALUE color;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+
+ color.a = 0.0f;
+
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCRa);
+ if ( ps != 0 ) color.r = ps->RetVisibleValue()/255.0f;
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCGa);
+ if ( ps != 0 ) color.g = ps->RetVisibleValue()/255.0f;
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCBa);
+ if ( ps != 0 ) color.b = ps->RetVisibleValue()/255.0f;
+ if ( m_persoTab == 1 ) m_perso.colorCombi = color;
+
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCRb);
+ if ( ps != 0 ) color.r = ps->RetVisibleValue()/255.0f;
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCGb);
+ if ( ps != 0 ) color.g = ps->RetVisibleValue()/255.0f;
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_PCBb);
+ if ( ps != 0 ) color.b = ps->RetVisibleValue()/255.0f;
+ if ( m_persoTab == 0 ) m_perso.colorHair = color;
+ else m_perso.colorBand = color;
+}
+
+// Updates the default settings of the character.
+
+void CMainDialog::DefPerso()
+{
+ m_perso.colorCombi.r = 206.0f/256.0f;
+ m_perso.colorCombi.g = 206.0f/256.0f;
+ m_perso.colorCombi.b = 204.0f/256.0f; // ~white
+ m_perso.colorBand.r = 255.0f/256.0f;
+ m_perso.colorBand.g = 132.0f/256.0f;
+ m_perso.colorBand.b = 1.0f/256.0f; // orange
+
+ if ( m_perso.face == 0 ) // normal ?
+ {
+ m_perso.glasses = 0;
+ m_perso.colorHair.r = 90.0f/256.0f;
+ m_perso.colorHair.g = 95.0f/256.0f;
+ m_perso.colorHair.b = 85.0f/256.0f; // black
+ }
+ if ( m_perso.face == 1 ) // bald ?
+ {
+ m_perso.glasses = 0;
+ m_perso.colorHair.r = 83.0f/256.0f;
+ m_perso.colorHair.g = 64.0f/256.0f;
+ m_perso.colorHair.b = 51.0f/256.0f; // brown
+ }
+ if ( m_perso.face == 2 ) // carlos ?
+ {
+ m_perso.glasses = 1;
+ m_perso.colorHair.r = 85.0f/256.0f;
+ m_perso.colorHair.g = 48.0f/256.0f;
+ m_perso.colorHair.b = 9.0f/256.0f; // brown
+ }
+ if ( m_perso.face == 3 ) // blond ?
+ {
+ m_perso.glasses = 4;
+ m_perso.colorHair.r = 255.0f/256.0f;
+ m_perso.colorHair.g = 255.0f/256.0f;
+ m_perso.colorHair.b = 181.0f/256.0f; // yellow
+ }
+
+ m_perso.colorHair.a = 0.0f;
+ m_perso.colorCombi.a = 0.0f;
+ m_perso.colorBand.a = 0.0f;
+}
+
+
+// Indicates if there is at least one backup.
+
+BOOL CMainDialog::IsIOReadScene()
+{
+ FILE* file;
+ char filename[100];
+
+ sprintf(filename, "%s\\%s\\save%c%.3d\\data.sav", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], 0);
+ file = fopen(filename, "r");
+ if ( file == NULL ) return FALSE;
+ fclose(file);
+ return TRUE;
+}
+
+// Builds the file name by default.
+
+void CMainDialog::IOReadName()
+{
+ FILE* file;
+ CWindow* pw;
+ CEdit* pe;
+ char filename[_MAX_FNAME];
+ char op[100];
+ char line[500];
+ char resume[100];
+ char name[100];
+ time_t now;
+ int i;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_IONAME);
+ if ( pe == 0 ) return;
+
+ sprintf(resume, "%s %d", m_sceneName, m_chap[m_index]+1);
+ BuildSceneName(filename, m_sceneName, (m_chap[m_index]+1)*100);
+ file = fopen(filename, "r");
+ if ( file != NULL )
+ {
+ while ( fgets(line, 500, file) != NULL )
+ {
+ for ( i=0 ; i<500 ; i++ )
+ {
+ if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space
+ if ( line[i] == '/' && line[i+1] == '/' )
+ {
+ line[i] = 0;
+ break;
+ }
+ }
+
+ sprintf(op, "Title.%c", RetLanguageLetter());
+ if ( Cmd(line, op) )
+ {
+ OpString(line, "resume", resume);
+ break;
+ }
+ }
+ fclose(file);
+ }
+
+ time(&now);
+ TimeToAscii(now, line);
+ sprintf(name, "%s %d - %s", resume, m_sel[m_index]+1, line);
+ pe->SetText(name);
+ pe->SetCursor(strlen(name), 0);
+ pe->SetFocus(TRUE);
+}
+
+// Updates the list of games recorded on disk.
+
+void CMainDialog::IOReadList()
+{
+ FILE* file = NULL;
+ CWindow* pw;
+ CList* pl;
+ char filename[100];
+ char line[500];
+ char name[100];
+ int i, j;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST);
+ if ( pl == 0 ) return;
+
+ pl->Flush();
+
+ for ( j=0 ; j<999 ; j++ )
+ {
+ sprintf(filename, "%s\\%s\\save%c%.3d\\data.sav", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], j);
+ file = fopen(filename, "r");
+ if ( file == NULL ) break;
+
+ strcmp(name, filename); // default name
+ while ( fgets(line, 500, file) != NULL )
+ {
+ for ( i=0 ; i<500 ; i++ )
+ {
+ if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space
+ if ( line[i] == '/' && line[i+1] == '/' )
+ {
+ line[i] = 0;
+ break;
+ }
+ }
+
+ if ( Cmd(line, "Title") )
+ {
+ OpString(line, "text", name);
+ break;
+ }
+ }
+ fclose(file);
+
+ pl->SetName(j, name);
+ }
+
+ if ( m_phase == PHASE_WRITE ||
+ m_phase == PHASE_WRITEs )
+ {
+ GetResource(RES_TEXT, RT_IO_NEW, name);
+ pl->SetName(j, name);
+ j ++;
+ }
+
+ pl->SetSelect(j-1);
+ pl->ShowSelect(FALSE); // shows the selected columns
+}
+
+// Updates the buttons according to the selected part in the list.
+
+void CMainDialog::IOUpdateList()
+{
+ FILE* file = NULL;
+ CWindow* pw;
+ CList* pl;
+ CButton* pb;
+ CImage* pi;
+ char filename[100];
+ int sel, max;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST);
+ if ( pl == 0 ) return;
+ pi = (CImage*)pw->SearchControl(EVENT_INTERFACE_IOIMAGE);
+ if ( pi == 0 ) return;
+
+ sel = pl->RetSelect();
+ max = pl->RetTotal();
+
+ sprintf(filename, "%s\\%s\\save%c%.3d\\screen.bmp", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel);
+
+ if ( m_phase == PHASE_WRITE ||
+ m_phase == PHASE_WRITEs )
+ {
+ if ( sel < max-1 )
+ {
+ pi->SetFilenameImage(filename);
+ }
+ else
+ {
+ pi->SetFilenameImage("");
+ }
+
+ pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_IODELETE);
+ if ( pb != 0 )
+ {
+ pb->SetState(STATE_ENABLE, sel < max-1);
+ }
+ }
+ else
+ {
+ pi->SetFilenameImage(filename);
+ }
+}
+
+// Deletes the selected scene.
+
+void CMainDialog::IODeleteScene()
+{
+ CWindow* pw;
+ CList* pl;
+ char dir[100];
+ char old[100];
+ long hFile;
+ struct _finddata_t fBuffer;
+ int sel, max, i;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST);
+ if ( pl == 0 ) return;
+
+ sel = pl->RetSelect();
+ if ( sel == -1 )
+ {
+ m_sound->Play(SOUND_TZOING);
+ return;
+ }
+
+ // Deletes all the contents of the file.
+ sprintf(dir, "%s\\%s\\save%c%.3d\\*", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel);
+ hFile = _findfirst(dir, &fBuffer);
+ if ( hFile != -1 )
+ {
+ do
+ {
+ if ( fBuffer.name[0] != '.' )
+ {
+ sprintf(dir, "%s\\%s\\save%c%.3d\\%s", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel, fBuffer.name);
+ remove(dir);
+ }
+ }
+ while ( _findnext(hFile, &fBuffer) == 0 );
+ }
+
+ sprintf(dir, "%s\\%s\\save%c%.3d", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel);
+ if ( _rmdir(dir) != 0 )
+ {
+ m_sound->Play(SOUND_TZOING);
+ return;
+ }
+
+ max = pl->RetTotal();
+ for ( i=sel+1 ; i<max ; i++ )
+ {
+ sprintf(old, "%s\\%s\\save%c%.3d", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], i);
+ sprintf(dir, "%s\\%s\\save%c%.3d", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], i-1);
+ rename(old, dir);
+ }
+ IOReadList();
+}
+
+// Writes the scene.
+
+BOOL CMainDialog::IOWriteScene()
+{
+ CWindow* pw;
+ CList* pl;
+ CEdit* pe;
+ char filename[100];
+ char filecbot[100];
+ char info[100];
+ int sel;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return FALSE;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST);
+ if ( pl == 0 ) return FALSE;
+ pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_IONAME);
+ if ( pe == 0 ) return FALSE;
+
+ sel = pl->RetSelect();
+ if ( sel == -1 ) return FALSE;
+
+ _mkdir("Savegame"); // if doesn't exist yet!
+ sprintf(filename, "%s\\%s", m_savegameDir, m_main->RetGamerName());
+ _mkdir(filename);
+ sprintf(filename, "%s\\%s\\save%c%.3d", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel);
+ _mkdir(filename);
+
+ sprintf(filename, "%s\\%s\\save%c%.3d\\data.sav", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel);
+ sprintf(filecbot, "%s\\%s\\save%c%.3d\\cbot.run", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel);
+ pe->GetText(info, 100);
+ m_main->IOWriteScene(filename, filecbot, info);
+
+ m_shotDelay = 3;
+ sprintf(m_shotName, "%s\\%s\\save%c%.3d\\screen.bmp", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel);
+
+ return TRUE;
+}
+
+// Reads the scene.
+
+BOOL CMainDialog::IOReadScene()
+{
+ FILE* file;
+ CWindow* pw;
+ CList* pl;
+ char filename[100];
+ char filecbot[100];
+ char line[500];
+ char dir[100];
+ int sel, i;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return FALSE;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_IOLIST);
+ if ( pl == 0 ) return FALSE;
+
+ sel = pl->RetSelect();
+ if ( sel == -1 ) return FALSE;
+
+ sprintf(filename, "%s\\%s\\save%c%.3d\\data.sav", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel);
+ sprintf(filecbot, "%s\\%s\\save%c%.3d\\cbot.run", m_savegameDir, m_main->RetGamerName(), m_sceneName[0], sel);
+
+ file = fopen(filename, "r");
+ if ( file == NULL ) return FALSE;
+
+ while ( fgets(line, 500, file) != NULL )
+ {
+ for ( i=0 ; i<500 ; i++ )
+ {
+ if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space
+ if ( line[i] == '/' && line[i+1] == '/' )
+ {
+ line[i] = 0;
+ break;
+ }
+ }
+
+ if ( Cmd(line, "Mission") )
+ {
+ OpString(line, "base", m_sceneName);
+ m_sceneRank = OpInt(line, "rank", 0);
+
+ if ( strcmp(m_sceneName, "user") == 0 )
+ {
+ m_sceneRank = m_sceneRank%100;
+ OpString(line, "dir", dir);
+ for ( i=0 ; i<m_userTotal ; i++ )
+ {
+ if ( strcmp(m_userList[i], dir) == 0 )
+ {
+ m_sceneRank += (i+1)*100;
+ break;
+ }
+ }
+ if ( m_sceneRank/100 == 0 )
+ {
+ fclose(file);
+ return FALSE;
+ }
+ }
+ }
+ }
+ fclose(file);
+
+ m_chap[m_index] = (m_sceneRank/100)-1;
+ m_sel[m_index] = (m_sceneRank%100)-1;
+
+ strcpy(m_sceneRead, filename);
+ strcpy(m_stackRead, filecbot);
+ return TRUE;
+}
+
+
+// Returns the number of accessible chapters.
+
+int CMainDialog::RetChapPassed()
+{
+ int j;
+
+ if ( m_main->RetShowAll() ) return 9;
+
+ for ( j=0 ; j<9 ; j++ )
+ {
+ if ( !RetGamerInfoPassed((j+1)*100) )
+ {
+ return j;
+ }
+ }
+ return 9;
+}
+
+// Updates the lists according to the cheat code.
+
+void CMainDialog::AllMissionUpdate()
+{
+ if ( m_phase == PHASE_TRAINER ||
+ m_phase == PHASE_DEFI ||
+ m_phase == PHASE_MISSION ||
+ m_phase == PHASE_FREE ||
+ m_phase == PHASE_TEEN ||
+ m_phase == PHASE_USER ||
+ m_phase == PHASE_PROTO )
+ {
+ UpdateSceneChap(m_chap[m_index]);
+ UpdateSceneList(m_chap[m_index], m_sel[m_index]);
+ }
+}
+
+// Updates the chapters of exercises or missions.
+
+void CMainDialog::UpdateSceneChap(int &chap)
+{
+ FILE* file = NULL;
+ CWindow* pw;
+ CList* pl;
+ long hFile;
+ struct _finddata_t fileBuffer;
+ char filename[_MAX_FNAME];
+ char op[100];
+ char line[500];
+ char name[100];
+ int i, j;
+ BOOL bPassed, bDo;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_CHAP);
+ if ( pl == 0 ) return;
+
+ pl->Flush();
+
+ if ( m_phase == PHASE_USER )
+ {
+ j = 0;
+ hFile = _findfirst("user\\*", &fileBuffer);
+ if ( hFile != -1 )
+ {
+ do
+ {
+ if ( (fileBuffer.attrib & _A_SUBDIR) != 0 &&
+ fileBuffer.name[0] != '.' )
+ {
+ strcpy(m_userList[j++], fileBuffer.name);
+ }
+ }
+ while ( _findnext(hFile, &fileBuffer) == 0 && j < 100 );
+ }
+ m_userTotal = j;
+
+ do // sorts all names:
+ {
+ bDo = FALSE;
+ for ( i=0 ; i<m_userTotal-1 ; i++ )
+ {
+ if ( strcmp(m_userList[i], m_userList[i+1]) > 0 )
+ {
+ strcpy(name, m_userList[i]);
+ strcpy(m_userList[i], m_userList[i+1]);
+ strcpy(m_userList[i+1], name);
+ bDo = TRUE;
+ }
+ }
+ }
+ while ( bDo );
+
+ for ( j=0 ; j<m_userTotal ; j++ )
+ {
+ BuildSceneName(filename, m_sceneName, (j+1)*100);
+ file = fopen(filename, "r");
+ if ( file == NULL )
+ {
+ strcpy(name, m_userList[j]);
+ }
+ else
+ {
+ BuildResumeName(name, m_sceneName, j+1); // default name
+ while ( fgets(line, 500, file) != NULL )
+ {
+ for ( i=0 ; i<500 ; i++ )
+ {
+ if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space
+ if ( line[i] == '/' && line[i+1] == '/' )
+ {
+ line[i] = 0;
+ break;
+ }
+ }
+
+ sprintf(op, "Title.%c", RetLanguageLetter());
+ if ( Cmd(line, op) )
+ {
+ OpString(line, "text", name);
+ break;
+ }
+ }
+ fclose(file);
+ }
+
+ pl->SetName(j, name);
+ pl->SetEnable(j, TRUE);
+ }
+ }
+ else
+ {
+ for ( j=0 ; j<9 ; j++ )
+ {
+#if _SCHOOL
+ if ( m_phase == PHASE_MISSION ) break;
+ if ( m_phase == PHASE_FREE ) break;
+#if _CEEBOTDEMO
+ if ( m_phase == PHASE_TRAINER && j >= 2 ) break;
+#endif
+#endif
+#if _DEMO
+ if ( m_phase == PHASE_MISSION && j >= 4 ) break;
+ if ( m_phase == PHASE_TRAINER && j >= 1 ) break;
+#endif
+ BuildSceneName(filename, m_sceneName, (j+1)*100);
+ file = fopen(filename, "r");
+ if ( file == NULL ) break;
+
+ BuildResumeName(name, m_sceneName, j+1); // default name
+ while ( fgets(line, 500, file) != NULL )
+ {
+ for ( i=0 ; i<500 ; i++ )
+ {
+ if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space
+ if ( line[i] == '/' && line[i+1] == '/' )
+ {
+ line[i] = 0;
+ break;
+ }
+ }
+
+ sprintf(op, "Title.%c", RetLanguageLetter());
+ if ( Cmd(line, op) )
+ {
+ OpString(line, "text", name);
+ break;
+ }
+ }
+ fclose(file);
+
+ bPassed = RetGamerInfoPassed((j+1)*100);
+ sprintf(line, "%d: %s", j+1, name);
+ pl->SetName(j, line);
+ pl->SetCheck(j, bPassed);
+ pl->SetEnable(j, TRUE);
+
+ if ( m_phase == PHASE_MISSION && !m_main->RetShowAll() && !bPassed )
+ {
+ j ++;
+ break;
+ }
+
+#if _TEEN
+ if ( m_phase == PHASE_TRAINER && !m_main->RetShowAll() && !bPassed )
+ {
+ j ++;
+ break;
+ }
+#endif
+
+ if ( m_phase == PHASE_FREE && j == m_accessChap )
+ {
+ j ++;
+ break;
+ }
+ }
+ }
+
+ if ( chap > j-1 ) chap = j-1;
+
+ pl->SetSelect(chap);
+ pl->ShowSelect(FALSE); // shows the selected columns
+}
+
+// Updates the list of exercises or missions.
+
+void CMainDialog::UpdateSceneList(int chap, int &sel)
+{
+ FILE* file = NULL;
+ CWindow* pw;
+ CList* pl;
+ char filename[_MAX_FNAME];
+ char op[100];
+ char line[500];
+ char name[100];
+ int i, j;
+ BOOL bPassed;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_INTERFACE_LIST);
+ if ( pl == 0 ) return;
+
+ pl->Flush();
+
+ for ( j=0 ; j<99 ; j++ )
+ {
+#if _SCHOOL
+ if ( m_phase == PHASE_MISSION ) break;
+ if ( m_phase == PHASE_FREE ) break;
+#if _CEEBOTDEMO
+#if _TEEN
+ if ( m_phase == PHASE_TRAINER && j >= 5 ) break;
+#else
+ if ( m_phase == PHASE_TRAINER && j >= 3 ) break;
+#endif
+#endif
+#endif
+#if _DEMO
+ if ( m_phase == PHASE_MISSION && j >= 3 ) break;
+ if ( m_phase == PHASE_TRAINER && j >= 5 ) break;
+#endif
+ BuildSceneName(filename, m_sceneName, (chap+1)*100+(j+1));
+ file = fopen(filename, "r");
+ if ( file == NULL ) break;
+
+ BuildResumeName(name, m_sceneName, j+1); // default name
+ while ( fgets(line, 500, file) != NULL )
+ {
+ for ( i=0 ; i<500 ; i++ )
+ {
+ if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space
+ if ( line[i] == '/' && line[i+1] == '/' )
+ {
+ line[i] = 0;
+ break;
+ }
+ }
+
+ sprintf(op, "Title.%c", RetLanguageLetter());
+ if ( Cmd(line, op) )
+ {
+ OpString(line, "text", name);
+ break;
+ }
+ }
+ fclose(file);
+
+ bPassed = RetGamerInfoPassed((chap+1)*100+(j+1));
+ sprintf(line, "%d: %s", j+1, name);
+ pl->SetName(j, line);
+ pl->SetCheck(j, bPassed);
+ pl->SetEnable(j, TRUE);
+
+ if ( m_phase == PHASE_MISSION && !m_main->RetShowAll() && !bPassed )
+ {
+ j ++;
+ break;
+ }
+
+#if _TEEN
+ if ( m_phase == PHASE_TRAINER && !m_main->RetShowAll() && !bPassed )
+ {
+ j ++;
+ break;
+ }
+#endif
+ }
+
+ BuildSceneName(filename, m_sceneName, (chap+1)*100+(j+1));
+ file = fopen(filename, "r");
+ if ( file == NULL )
+ {
+ m_maxList = j;
+ }
+ else
+ {
+ m_maxList = j+1; // this is not the last!
+ fclose(file);
+ }
+
+ if ( sel > j-1 ) sel = j-1;
+
+ pl->SetSelect(sel);
+ pl->ShowSelect(FALSE); // shows the selected columns
+}
+
+// Updates the button "solution" according to cheat code.
+
+void CMainDialog::ShowSoluceUpdate()
+{
+ CWindow* pw;
+ CEdit* pe;
+ CCheck* pc;
+
+ if ( m_phase == PHASE_TRAINER ||
+ m_phase == PHASE_DEFI ||
+ m_phase == PHASE_MISSION ||
+ m_phase == PHASE_FREE ||
+ m_phase == PHASE_TEEN ||
+ m_phase == PHASE_USER ||
+ m_phase == PHASE_PROTO )
+ {
+ m_bSceneSoluce = FALSE;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_RESUME);
+ if ( pe == 0 ) return;
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SOLUCE);
+ if ( pc == 0 ) return;
+
+ if ( m_main->RetShowSoluce() )
+ {
+ pc->SetState(STATE_VISIBLE);
+ pc->SetState(STATE_CHECK);
+ m_bSceneSoluce = TRUE;
+ }
+ else
+ {
+ pc->ClearState(STATE_VISIBLE);
+ pc->ClearState(STATE_CHECK);
+ m_bSceneSoluce = FALSE;
+ }
+ }
+}
+
+// Updates a summary of exercise or mission.
+
+void CMainDialog::UpdateSceneResume(int rank)
+{
+ FILE* file = NULL;
+ CWindow* pw;
+ CEdit* pe;
+ CCheck* pc;
+ char filename[_MAX_FNAME];
+ char op[100];
+ char line[500];
+ char name[500];
+ int i, numTry;
+ BOOL bPassed, bVisible;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pe = (CEdit*)pw->SearchControl(EVENT_INTERFACE_RESUME);
+ if ( pe == 0 ) return;
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SOLUCE);
+
+ if ( pc == 0 )
+ {
+ m_bSceneSoluce = FALSE;
+ }
+ else
+ {
+ numTry = RetGamerInfoTry(rank);
+ bPassed = RetGamerInfoPassed(rank);
+ bVisible = ( numTry > 2 || bPassed || m_main->RetShowSoluce() );
+ if ( !RetSoluce4() ) bVisible = FALSE;
+ pc->SetState(STATE_VISIBLE, bVisible);
+ if ( !bVisible )
+ {
+ pc->ClearState(STATE_CHECK);
+ m_bSceneSoluce = FALSE;
+ }
+ }
+
+ BuildSceneName(filename, m_sceneName, rank);
+ file = fopen(filename, "r");
+ if ( file == NULL ) return;
+
+ name[0] = 0;
+ while ( fgets(line, 500, file) != NULL )
+ {
+ for ( i=0 ; i<500 ; i++ )
+ {
+ if ( line[i] == '\t' ) line[i] = ' '; // replaces tab by space
+ if ( line[i] == '/' && line[i+1] == '/' )
+ {
+ line[i] = 0;
+ break;
+ }
+ }
+
+ sprintf(op, "Resume.%c", RetLanguageLetter());
+ if ( Cmd(line, op) )
+ {
+ OpString(line, "text", name);
+ break;
+ }
+ }
+ fclose(file);
+
+ pe->SetText(name);
+}
+
+// Updates the list of devices.
+
+void CMainDialog::UpdateDisplayDevice()
+{
+ CWindow* pw;
+ CList* pl;
+ char bufDevices[1000];
+ char bufModes[5000];
+ int i, j, totalDevices, selectDevices, totalModes, selectModes;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_LIST1);
+ if ( pl == 0 ) return;
+ pl->Flush();
+
+ m_engine->EnumDevices(bufDevices, 1000,
+ bufModes, 5000,
+ totalDevices, selectDevices,
+ totalModes, selectModes);
+
+ i = 0;
+ j = 0;
+ while ( bufDevices[i] != 0 )
+ {
+ pl->SetName(j++, bufDevices+i);
+ while ( bufDevices[i++] != 0 );
+ }
+
+ pl->SetSelect(selectDevices);
+ pl->ShowSelect(FALSE);
+
+ m_setupSelDevice = selectDevices;
+}
+
+// Updates the list of modes.
+
+void CMainDialog::UpdateDisplayMode()
+{
+ CWindow* pw;
+ CList* pl;
+ char bufDevices[1000];
+ char bufModes[5000];
+ int i, j, totalDevices, selectDevices, totalModes, selectModes;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_LIST2);
+ if ( pl == 0 ) return;
+ pl->Flush();
+
+ m_engine->EnumDevices(bufDevices, 1000,
+ bufModes, 5000,
+ totalDevices, selectDevices,
+ totalModes, selectModes);
+
+ i = 0;
+ j = 0;
+ while ( bufModes[i] != 0 )
+ {
+ pl->SetName(j++, bufModes+i);
+ while ( bufModes[i++] != 0 );
+ }
+
+ pl->SetSelect(selectModes);
+ pl->ShowSelect(FALSE);
+
+ m_setupSelMode = selectModes;
+}
+
+// Change the graphics mode.
+
+void CMainDialog::ChangeDisplay()
+{
+ CWindow* pw;
+ CList* pl;
+ CCheck* pc;
+ char* device;
+ char* mode;
+ BOOL bFull;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+
+ pl = (CList*)pw->SearchControl(EVENT_LIST1);
+ if ( pl == 0 ) return;
+ m_setupSelDevice = pl->RetSelect();
+ device = pl->RetName(m_setupSelDevice);
+
+ pl = (CList*)pw->SearchControl(EVENT_LIST2);
+ if ( pl == 0 ) return;
+ m_setupSelMode = pl->RetSelect();
+ mode = pl->RetName(m_setupSelMode);
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_FULL);
+ if ( pc == 0 ) return;
+ bFull = pc->TestState(STATE_CHECK);
+ m_setupFull = bFull;
+
+ m_engine->ChangeDevice(device, mode, bFull);
+
+ if ( m_bSimulSetup )
+ {
+ m_main->ChangeColor();
+ m_main->UpdateMap();
+ }
+}
+
+
+
+// Updates the "apply" button.
+
+void CMainDialog::UpdateApply()
+{
+ CWindow* pw;
+ CButton* pb;
+ CList* pl;
+ CCheck* pc;
+ int sel1, sel2;
+ BOOL bFull;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+
+ pb = (CButton*)pw->SearchControl(EVENT_INTERFACE_APPLY);
+ if ( pb == 0 ) return;
+
+ pl = (CList*)pw->SearchControl(EVENT_LIST1);
+ if ( pl == 0 ) return;
+ sel1 = pl->RetSelect();
+
+ pl = (CList*)pw->SearchControl(EVENT_LIST2);
+ if ( pl == 0 ) return;
+ sel2 = pl->RetSelect();
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_FULL);
+ bFull = pc->TestState(STATE_CHECK);
+
+ if ( sel1 == m_setupSelDevice &&
+ sel2 == m_setupSelMode &&
+ bFull == m_setupFull )
+ {
+ pb->ClearState(STATE_ENABLE);
+ }
+ else
+ {
+ pb->SetState(STATE_ENABLE);
+ }
+}
+
+// Updates the buttons during the setup phase.
+
+void CMainDialog::UpdateSetupButtons()
+{
+ CWindow* pw;
+ CCheck* pc;
+ CEditValue* pv;
+ CSlider* ps;
+ float value;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_TOTO);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_engine->RetTotoMode());
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_TOOLTIP);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_bTooltip);
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_GLINT);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_bGlint);
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_RAIN);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_bRain);
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_MOUSE);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_engine->RetNiceMouse());
+ pc->SetState(STATE_ENABLE, m_engine->RetNiceMouseCap());
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_EDITMODE);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_engine->RetEditIndentMode());
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_EDITVALUE);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_engine->RetEditIndentValue()>2);
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SOLUCE4);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_bSoluce4);
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_MOVIES);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_bMovies);
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_NICERST);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_bNiceReset);
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_HIMSELF);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_bHimselfDamage);
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SCROLL);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_bCameraScroll);
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_INVERTX);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_bCameraInvertX);
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_INVERTY);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_bCameraInvertY);
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_EFFECT);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_bEffect);
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SHADOW);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_engine->RetShadow());
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_GROUND);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_engine->RetGroundSpot());
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_DIRTY);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_engine->RetDirty());
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_FOG);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_engine->RetFog());
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_LENS);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_engine->RetLensMode());
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SKY);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_engine->RetSkyMode());
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_PLANET);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_engine->RetPlanetMode());
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_LIGHT);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_engine->RetLightMode());
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_JOYSTICK);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_engine->RetJoystick());
+ }
+
+ pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_PARTI);
+ if ( pv != 0 )
+ {
+ value = m_engine->RetParticuleDensity();
+ pv->SetValue(value);
+ }
+
+ pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_CLIP);
+ if ( pv != 0 )
+ {
+ value = m_engine->RetClippingDistance();
+ pv->SetValue(value);
+ }
+
+ pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_DETAIL);
+ if ( pv != 0 )
+ {
+ value = m_engine->RetObjectDetail();
+ pv->SetValue(value);
+ }
+
+ pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_GADGET);
+ if ( pv != 0 )
+ {
+ value = m_engine->RetGadgetQuantity();
+ pv->SetValue(value);
+ }
+
+ pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_TEXTURE);
+ if ( pv != 0 )
+ {
+ value = (float)m_engine->RetTextureQuality();
+ pv->SetValue(value);
+ }
+
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_VOLSOUND);
+ if ( ps != 0 )
+ {
+ value = (float)m_sound->RetAudioVolume();
+ ps->SetVisibleValue(value);
+ }
+
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_VOLMUSIC);
+ if ( ps != 0 )
+ {
+ value = (float)m_sound->RetMidiVolume();
+ ps->SetVisibleValue(value);
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_INTERFACE_SOUND3D);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_sound->RetSound3D());
+ pc->SetState(STATE_ENABLE, m_sound->RetSound3DCap());
+ }
+}
+
+// Updates the engine function of the buttons after the setup phase.
+
+void CMainDialog::ChangeSetupButtons()
+{
+ CWindow* pw;
+ CEditValue* pv;
+ CSlider* ps;
+ float value;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+
+ pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_PARTI);
+ if ( pv != 0 )
+ {
+ value = pv->RetValue();
+ m_engine->SetParticuleDensity(value);
+ }
+
+ pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_CLIP);
+ if ( pv != 0 )
+ {
+ value = pv->RetValue();
+ m_engine->SetClippingDistance(value);
+ }
+
+ pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_DETAIL);
+ if ( pv != 0 )
+ {
+ value = pv->RetValue();
+ m_engine->SetObjectDetail(value);
+ }
+
+ pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_GADGET);
+ if ( pv != 0 )
+ {
+ value = pv->RetValue();
+ m_engine->SetGadgetQuantity(value);
+ }
+
+ pv = (CEditValue*)pw->SearchControl(EVENT_INTERFACE_TEXTURE);
+ if ( pv != 0 )
+ {
+ value = pv->RetValue();
+ m_engine->SetTextureQuality((int)value);
+ }
+
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_VOLSOUND);
+ if ( ps != 0 )
+ {
+ value = ps->RetVisibleValue();
+ m_sound->SetAudioVolume((int)value);
+ }
+
+ ps = (CSlider*)pw->SearchControl(EVENT_INTERFACE_VOLMUSIC);
+ if ( ps != 0 )
+ {
+ value = ps->RetVisibleValue();
+ m_sound->SetMidiVolume((int)value);
+ }
+}
+
+
+// Memorizes all the settings.
+
+void CMainDialog::SetupMemorize()
+{
+ float fValue;
+ int iValue, i, j;
+ char key[500];
+ char num[10];
+
+ SetProfileString("Directory", "scene", m_sceneDir);
+ SetProfileString("Directory", "savegame", m_savegameDir);
+ SetProfileString("Directory", "public", m_publicDir);
+ SetProfileString("Directory", "user", m_userDir);
+ SetProfileString("Directory", "files", m_filesDir);
+
+ iValue = m_engine->RetTotoMode();
+ SetProfileInt("Setup", "TotoMode", iValue);
+
+ iValue = m_bTooltip;
+ SetProfileInt("Setup", "Tooltips", iValue);
+
+ iValue = m_bGlint;
+ SetProfileInt("Setup", "InterfaceGlint", iValue);
+
+ iValue = m_bRain;
+ SetProfileInt("Setup", "InterfaceGlint", iValue);
+
+ iValue = m_engine->RetNiceMouse();
+ SetProfileInt("Setup", "NiceMouse", iValue);
+
+ iValue = m_bSoluce4;
+ SetProfileInt("Setup", "Soluce4", iValue);
+
+ iValue = m_bMovies;
+ SetProfileInt("Setup", "Movies", iValue);
+
+ iValue = m_bNiceReset;
+ SetProfileInt("Setup", "NiceReset", iValue);
+
+ iValue = m_bHimselfDamage;
+ SetProfileInt("Setup", "HimselfDamage", iValue);
+
+ iValue = m_bCameraScroll;
+ SetProfileInt("Setup", "CameraScroll", iValue);
+
+ iValue = m_bCameraInvertX;
+ SetProfileInt("Setup", "CameraInvertX", iValue);
+
+ iValue = m_bEffect;
+ SetProfileInt("Setup", "InterfaceEffect", iValue);
+
+ iValue = m_engine->RetShadow();
+ SetProfileInt("Setup", "GroundShadow", iValue);
+
+ iValue = m_engine->RetGroundSpot();
+ SetProfileInt("Setup", "GroundSpot", iValue);
+
+ iValue = m_engine->RetDirty();
+ SetProfileInt("Setup", "ObjectDirty", iValue);
+
+ iValue = m_engine->RetFog();
+ SetProfileInt("Setup", "FogMode", iValue);
+
+ iValue = m_engine->RetLensMode();
+ SetProfileInt("Setup", "LensMode", iValue);
+
+ iValue = m_engine->RetSkyMode();
+ SetProfileInt("Setup", "SkyMode", iValue);
+
+ iValue = m_engine->RetPlanetMode();
+ SetProfileInt("Setup", "PlanetMode", iValue);
+
+ iValue = m_engine->RetLightMode();
+ SetProfileInt("Setup", "LightMode", iValue);
+
+ iValue = m_engine->RetJoystick();
+ SetProfileInt("Setup", "UseJoystick", iValue);
+
+ fValue = m_engine->RetParticuleDensity();
+ SetProfileFloat("Setup", "ParticuleDensity", fValue);
+
+ fValue = m_engine->RetClippingDistance();
+ SetProfileFloat("Setup", "ClippingDistance", fValue);
+
+ fValue = m_engine->RetObjectDetail();
+ SetProfileFloat("Setup", "ObjectDetail", fValue);
+
+ fValue = m_engine->RetGadgetQuantity();
+ SetProfileFloat("Setup", "GadgetQuantity", fValue);
+
+ iValue = m_engine->RetTextureQuality();
+ SetProfileInt("Setup", "TextureQuality", iValue);
+
+ iValue = m_sound->RetAudioVolume();
+ SetProfileInt("Setup", "AudioVolume", iValue);
+
+ iValue = m_sound->RetMidiVolume();
+ SetProfileInt("Setup", "MidiVolume", iValue);
+
+ iValue = m_sound->RetSound3D();
+ SetProfileInt("Setup", "Sound3D", iValue);
+
+ iValue = m_engine->RetEditIndentMode();
+ SetProfileInt("Setup", "EditIndentMode", iValue);
+
+ iValue = m_engine->RetEditIndentValue();
+ SetProfileInt("Setup", "EditIndentValue", iValue);
+
+ key[0] = 0;
+ for ( i=0 ; i<100 ; i++ )
+ {
+ if ( m_engine->RetKey(i, 0) == 0 ) break;
+
+ for ( j=0 ; j<2 ; j++ )
+ {
+ iValue = m_engine->RetKey(i, j);
+ sprintf(num, "%d%c", iValue, j==0?'+':' ');
+ strcat(key, num);
+ }
+ }
+ SetProfileString("Setup", "KeyMap", key);
+
+#if _NET
+ if ( m_accessEnable )
+ {
+ iValue = m_accessMission;
+ SetProfileInt("Setup", "AccessMission", iValue);
+
+ iValue = m_accessUser;
+ SetProfileInt("Setup", "AccessUser", iValue);
+ }
+#endif
+
+ iValue = m_bDeleteGamer;
+ SetProfileInt("Setup", "DeleteGamer", iValue);
+
+ m_engine->WriteProfile();
+}
+
+// Remember all the settings.
+
+void CMainDialog::SetupRecall()
+{
+ float fValue;
+ int iValue, i, j;
+ char key[500];
+ char* p;
+
+ if ( GetProfileString("Directory", "scene", key, _MAX_FNAME) )
+ {
+ strcpy(m_sceneDir, key);
+ }
+
+ if ( GetProfileString("Directory", "savegame", key, _MAX_FNAME) )
+ {
+ strcpy(m_savegameDir, key);
+ }
+
+ if ( GetProfileString("Directory", "public", key, _MAX_FNAME) )
+ {
+ strcpy(m_publicDir, key);
+ }
+
+ if ( GetProfileString("Directory", "user", key, _MAX_FNAME) )
+ {
+ strcpy(m_userDir, key);
+ }
+
+ if ( GetProfileString("Directory", "files", key, _MAX_FNAME) )
+ {
+ strcpy(m_filesDir, key);
+ }
+
+
+ if ( GetProfileInt("Setup", "TotoMode", iValue) )
+ {
+ m_engine->SetTotoMode(iValue);
+ }
+
+ if ( GetProfileInt("Setup", "Tooltips", iValue) )
+ {
+ m_bTooltip = iValue;
+ }
+
+ if ( GetProfileInt("Setup", "InterfaceGlint", iValue) )
+ {
+ m_bGlint = iValue;
+ }
+
+ if ( GetProfileInt("Setup", "InterfaceGlint", iValue) )
+ {
+ m_bRain = iValue;
+ }
+
+ if ( GetProfileInt("Setup", "NiceMouse", iValue) )
+ {
+ m_engine->SetNiceMouse(iValue);
+ }
+
+ if ( GetProfileInt("Setup", "Soluce4", iValue) )
+ {
+ m_bSoluce4 = iValue;
+ }
+
+ if ( GetProfileInt("Setup", "Movies", iValue) )
+ {
+ m_bMovies = iValue;
+ }
+
+ if ( GetProfileInt("Setup", "NiceReset", iValue) )
+ {
+ m_bNiceReset = iValue;
+ }
+
+ if ( GetProfileInt("Setup", "HimselfDamage", iValue) )
+ {
+ m_bHimselfDamage = iValue;
+ }
+
+ if ( GetProfileInt("Setup", "CameraScroll", iValue) )
+ {
+ m_bCameraScroll = iValue;
+ m_camera->SetCameraScroll(m_bCameraScroll);
+ }
+
+ if ( GetProfileInt("Setup", "CameraInvertX", iValue) )
+ {
+ m_bCameraInvertX = iValue;
+ m_camera->SetCameraInvertX(m_bCameraInvertX);
+ }
+
+ if ( GetProfileInt("Setup", "CameraInvertY", iValue) )
+ {
+ m_bCameraInvertY = iValue;
+ m_camera->SetCameraInvertY(m_bCameraInvertY);
+ }
+
+ if ( GetProfileInt("Setup", "InterfaceEffect", iValue) )
+ {
+ m_bEffect = iValue;
+ }
+
+ if ( GetProfileInt("Setup", "GroundShadow", iValue) )
+ {
+ m_engine->SetShadow(iValue);
+ }
+
+ if ( GetProfileInt("Setup", "GroundSpot", iValue) )
+ {
+ m_engine->SetGroundSpot(iValue);
+ }
+
+ if ( GetProfileInt("Setup", "ObjectDirty", iValue) )
+ {
+ m_engine->SetDirty(iValue);
+ }
+
+ if ( GetProfileInt("Setup", "FogMode", iValue) )
+ {
+ m_engine->SetFog(iValue);
+ m_camera->SetOverBaseColor(RetColor(RetColor(0.0f)));
+ }
+
+ if ( GetProfileInt("Setup", "LensMode", iValue) )
+ {
+ m_engine->SetLensMode(iValue);
+ }
+
+ if ( GetProfileInt("Setup", "SkyMode", iValue) )
+ {
+ m_engine->SetSkyMode(iValue);
+ }
+
+ if ( GetProfileInt("Setup", "PlanetMode", iValue) )
+ {
+ m_engine->SetPlanetMode(iValue);
+ }
+
+ if ( GetProfileInt("Setup", "LightMode", iValue) )
+ {
+ m_engine->SetLightMode(iValue);
+ }
+
+ if ( GetProfileInt("Setup", "UseJoystick", iValue) )
+ {
+ m_engine->SetJoystick(iValue);
+ }
+
+ if ( GetProfileFloat("Setup", "ParticuleDensity", fValue) )
+ {
+ m_engine->SetParticuleDensity(fValue);
+ }
+
+ if ( GetProfileFloat("Setup", "ClippingDistance", fValue) )
+ {
+ m_engine->SetClippingDistance(fValue);
+ }
+
+ if ( GetProfileFloat("Setup", "ObjectDetail", fValue) )
+ {
+ m_engine->SetObjectDetail(fValue);
+ }
+
+ if ( GetProfileFloat("Setup", "GadgetQuantity", fValue) )
+ {
+ m_engine->SetGadgetQuantity(fValue);
+ }
+
+ if ( GetProfileInt("Setup", "TextureQuality", iValue) )
+ {
+ m_engine->SetTextureQuality(iValue);
+ }
+
+ if ( GetProfileInt("Setup", "AudioVolume", iValue) )
+ {
+ m_sound->SetAudioVolume(iValue);
+ }
+
+ if ( GetProfileInt("Setup", "MidiVolume", iValue) )
+ {
+ m_sound->SetMidiVolume(iValue);
+ }
+
+ if ( GetProfileInt("Setup", "EditIndentMode", iValue) )
+ {
+ m_engine->SetEditIndentMode(iValue);
+ }
+
+ if ( GetProfileInt("Setup", "EditIndentValue", iValue) )
+ {
+ m_engine->SetEditIndentValue(iValue);
+ }
+
+ if ( GetProfileString("Setup", "KeyMap", key, 500) )
+ {
+ p = key;
+ for ( i=0 ; i<100 ; i++ )
+ {
+ if ( p[0] == 0 ) break;
+
+ for ( j=0 ; j<2 ; j++ )
+ {
+ sscanf(p, "%d", &iValue);
+ m_engine->SetKey(i, j, iValue);
+ while ( *p >= '0' && *p <= '9' ) p++;
+ while ( *p == ' ' || *p == '+' ) p++;
+ }
+ }
+ }
+
+#if _NET
+ if ( m_accessEnable )
+ {
+ if ( GetProfileInt("Setup", "AccessMission", iValue) )
+ {
+ m_accessMission = iValue;
+ }
+
+ if ( GetProfileInt("Setup", "AccessUser", iValue) )
+ {
+ m_accessUser = iValue;
+ }
+ }
+#endif
+
+ if ( GetProfileInt("Setup", "DeleteGamer", iValue) )
+ {
+ m_bDeleteGamer = iValue;
+ }
+}
+
+
+// Changes the general level of quality.
+
+void CMainDialog::ChangeSetupQuality(int quality)
+{
+ BOOL bEnable;
+ float value;
+ int iValue;
+
+ bEnable = (quality >= 0);
+ m_engine->SetShadow(bEnable);
+ m_engine->SetGroundSpot(bEnable);
+ m_engine->SetDirty(bEnable);
+ m_engine->SetFog(bEnable);
+ m_engine->SetLensMode(bEnable);
+ m_engine->SetSkyMode(bEnable);
+ m_engine->SetPlanetMode(bEnable);
+ m_engine->SetLightMode(bEnable);
+ m_camera->SetOverBaseColor(RetColor(RetColor(0.0f)));
+
+ if ( quality < 0 ) value = 0.0f;
+ if ( quality == 0 ) value = 1.0f;
+ if ( quality > 0 ) value = 2.0f;
+ m_engine->SetParticuleDensity(value);
+
+ if ( quality < 0 ) value = 0.5f;
+ if ( quality == 0 ) value = 1.0f;
+ if ( quality > 0 ) value = 2.0f;
+ m_engine->SetClippingDistance(value);
+
+ if ( quality < 0 ) value = 0.0f;
+ if ( quality == 0 ) value = 1.0f;
+ if ( quality > 0 ) value = 2.0f;
+ m_engine->SetObjectDetail(value);
+
+ if ( quality < 0 ) value = 0.5f;
+ if ( quality == 0 ) value = 1.0f;
+ if ( quality > 0 ) value = 1.0f;
+ m_engine->SetGadgetQuantity(value);
+
+ if ( quality < 0 ) iValue = 0;
+ if ( quality == 0 ) iValue = 1;
+ if ( quality > 0 ) iValue = 2;
+ m_engine->SetTextureQuality(iValue);
+
+ m_engine->FirstExecuteAdapt(FALSE);
+}
+
+
+// Redefinable keys:
+
+static int key_table[KEY_TOTAL] =
+{
+#if _SCHOOL & _TEEN
+ KEYRANK_LEFT,
+ KEYRANK_RIGHT,
+ KEYRANK_UP,
+ KEYRANK_DOWN,
+ KEYRANK_CAMERA,
+ KEYRANK_NEAR,
+ KEYRANK_AWAY,
+ KEYRANK_HELP,
+ KEYRANK_PROG,
+ KEYRANK_SPEED10,
+ KEYRANK_SPEED15,
+ KEYRANK_SPEED20,
+ KEYRANK_QUIT,
+#else
+ KEYRANK_LEFT,
+ KEYRANK_RIGHT,
+ KEYRANK_UP,
+ KEYRANK_DOWN,
+ KEYRANK_GUP,
+ KEYRANK_GDOWN,
+ KEYRANK_ACTION,
+ KEYRANK_CAMERA,
+ KEYRANK_VISIT,
+ KEYRANK_NEXT,
+ KEYRANK_HUMAN,
+ KEYRANK_DESEL,
+ KEYRANK_NEAR,
+ KEYRANK_AWAY,
+ KEYRANK_HELP,
+ KEYRANK_PROG,
+ KEYRANK_CBOT,
+ KEYRANK_SPEED10,
+ KEYRANK_SPEED15,
+ KEYRANK_SPEED20,
+ KEYRANK_QUIT,
+#endif
+};
+
+static EventMsg key_event[KEY_TOTAL] =
+{
+#if _SCHOOL & _TEEN
+ EVENT_INTERFACE_KLEFT,
+ EVENT_INTERFACE_KRIGHT,
+ EVENT_INTERFACE_KUP,
+ EVENT_INTERFACE_KDOWN,
+ EVENT_INTERFACE_KCAMERA,
+ EVENT_INTERFACE_KNEAR,
+ EVENT_INTERFACE_KAWAY,
+ EVENT_INTERFACE_KHELP,
+ EVENT_INTERFACE_KPROG,
+ EVENT_INTERFACE_KSPEED10,
+ EVENT_INTERFACE_KSPEED15,
+ EVENT_INTERFACE_KSPEED20,
+ EVENT_INTERFACE_KQUIT,
+#else
+ EVENT_INTERFACE_KLEFT,
+ EVENT_INTERFACE_KRIGHT,
+ EVENT_INTERFACE_KUP,
+ EVENT_INTERFACE_KDOWN,
+ EVENT_INTERFACE_KGUP,
+ EVENT_INTERFACE_KGDOWN,
+ EVENT_INTERFACE_KACTION,
+ EVENT_INTERFACE_KCAMERA,
+ EVENT_INTERFACE_KVISIT,
+ EVENT_INTERFACE_KNEXT,
+ EVENT_INTERFACE_KHUMAN,
+ EVENT_INTERFACE_KDESEL,
+ EVENT_INTERFACE_KNEAR,
+ EVENT_INTERFACE_KAWAY,
+ EVENT_INTERFACE_KHELP,
+ EVENT_INTERFACE_KPROG,
+ EVENT_INTERFACE_KCBOT,
+ EVENT_INTERFACE_KSPEED10,
+ EVENT_INTERFACE_KSPEED15,
+ EVENT_INTERFACE_KSPEED20,
+ EVENT_INTERFACE_KQUIT,
+#endif
+};
+
+// Updates the list of keys.
+
+void CMainDialog::UpdateKey()
+{
+ CWindow* pw;
+ CScroll* ps;
+ CKey* pk;
+ FPOINT pos, dim;
+ int first, i;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+
+ ps = (CScroll*)pw->SearchControl(EVENT_INTERFACE_KSCROLL);
+ if ( ps == 0 ) return;
+
+ first = (int)(ps->RetVisibleValue()*(KEY_TOTAL-KEY_VISIBLE));
+
+ for ( i=0 ; i<KEY_TOTAL ; i++ )
+ {
+ pw->DeleteControl(key_event[i]);
+ }
+
+ dim.x = 400.0f/640.0f;
+ dim.y = 20.0f/480.0f;
+ pos.x = 110.0f/640.0f;
+ pos.y = 168.0f/480.0f + dim.y*(KEY_VISIBLE-1);
+ for ( i=0 ; i<KEY_VISIBLE ; i++ )
+ {
+ pw->CreateKey(pos, dim, -1, key_event[first+i]);
+ pk = (CKey*)pw->SearchControl(key_event[first+i]);
+ if ( pk == 0 ) break;
+ pk->SetKey(0, m_engine->RetKey(key_table[first+i], 0));
+ pk->SetKey(1, m_engine->RetKey(key_table[first+i], 1));
+ pos.y -= dim.y;
+ }
+}
+
+// Change a key.
+
+void CMainDialog::ChangeKey(EventMsg event)
+{
+ CWindow* pw;
+ CScroll* ps;
+ CKey* pk;
+ int i;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw == 0 ) return;
+
+ ps = (CScroll*)pw->SearchControl(EVENT_INTERFACE_KSCROLL);
+ if ( ps == 0 ) return;
+
+ for ( i=0 ; i<KEY_TOTAL ; i++ )
+ {
+ if ( key_event[i] == event )
+ {
+ pk = (CKey*)pw->SearchControl(key_event[i]);
+ if ( pk == 0 ) break;
+ m_engine->SetKey(key_table[i], 0, pk->RetKey(0));
+ m_engine->SetKey(key_table[i], 1, pk->RetKey(1));
+ }
+ }
+}
+
+
+
+// Do you want to quit the current mission?
+
+void CMainDialog::StartAbort()
+{
+ CWindow* pw;
+ CButton* pb;
+ FPOINT pos, dim;
+ char name[100];
+
+ StartDialog(FPOINT(0.3f, 0.8f), TRUE, FALSE, FALSE);
+ m_bDialogDelete = FALSE;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9);
+ if ( pw == 0 ) return;
+
+ pos.x = 0.35f;
+ pos.y = 0.60f;
+ dim.x = 0.30f;
+ dim.y = 0.30f;
+ pw->CreateGroup(pos, dim, 5, EVENT_INTERFACE_GLINTl); // orange corner
+ pos.x = 0.35f;
+ pos.y = 0.10f;
+ dim.x = 0.30f;
+ dim.y = 0.30f;
+ pw->CreateGroup(pos, dim, 4, EVENT_INTERFACE_GLINTr); // blue corner
+
+ pos.x = 0.40f;
+ dim.x = 0.20f;
+#if _POLISH
+ pos.x -= 7.0f/640.0f;
+ dim.x += 14.0f/640.0f;
+#endif
+ dim.y = 32.0f/480.0f;
+
+ pos.y = 0.74f;
+ pb = pw->CreateButton(pos, dim, -1, EVENT_DIALOG_CANCEL);
+ pb->SetState(STATE_SHADOW);
+ GetResource(RES_TEXT, RT_DIALOG_NO, name);
+ pb->SetName(name);
+
+ if ( m_index == 2 || // missions ?
+ m_index == 3 || // free games?
+ m_index == 4 ) // user ?
+ {
+ pos.y = 0.62f;
+ pb = pw->CreateButton(pos, dim, -1, EVENT_INTERFACE_WRITE);
+ pb->SetState(STATE_SHADOW);
+ if ( m_main->IsBusy() ) // current task?
+ {
+ pb->ClearState(STATE_ENABLE);
+ }
+
+ pos.y = 0.53f;
+ pb = pw->CreateButton(pos, dim, -1, EVENT_INTERFACE_READ);
+ pb->SetState(STATE_SHADOW);
+ if ( !IsIOReadScene() ) // no file to read?
+ {
+ pb->ClearState(STATE_ENABLE);
+ }
+ pb->SetState(STATE_WARNING);
+ }
+
+ if ( m_engine->RetSetupMode() )
+ {
+ pos.y = 0.39f;
+ pb = pw->CreateButton(pos, dim, -1, EVENT_INTERFACE_SETUP);
+ pb->SetState(STATE_SHADOW);
+ }
+
+ pos.y = 0.25f;
+ pb = pw->CreateButton(pos, dim, -1, EVENT_INTERFACE_AGAIN);
+ pb->SetState(STATE_SHADOW);
+ pb->SetState(STATE_WARNING);
+
+ pos.y = 0.16f;
+ pb = pw->CreateButton(pos, dim, -1, EVENT_DIALOG_OK);
+ pb->SetState(STATE_SHADOW);
+ pb->SetState(STATE_WARNING);
+ GetResource(RES_TEXT, RT_DIALOG_YES, name);
+ pb->SetName(name);
+}
+
+// Do you want to destroy the building?
+
+void CMainDialog::StartDeleteObject()
+{
+ CWindow* pw;
+ CButton* pb;
+ FPOINT pos, dim;
+ char name[100];
+
+ StartDialog(FPOINT(0.7f, 0.3f), FALSE, TRUE, TRUE);
+ m_bDialogDelete = TRUE;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9);
+ if ( pw == 0 ) return;
+
+ pos.x = 0.00f;
+ pos.y = 0.50f;
+ dim.x = 1.00f;
+ dim.y = 0.05f;
+ GetResource(RES_TEXT, RT_DIALOG_DELOBJ, name);
+ pw->CreateLabel(pos, dim, -1, EVENT_DIALOG_LABEL, name);
+
+ pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK);
+ if ( pb == 0 ) return;
+ GetResource(RES_TEXT, RT_DIALOG_YESDEL, name);
+ pb->SetName(name);
+ pb->SetState(STATE_WARNING);
+
+ pb = (CButton*)pw->SearchControl(EVENT_DIALOG_CANCEL);
+ if ( pb == 0 ) return;
+ GetResource(RES_TEXT, RT_DIALOG_NODEL, name);
+ pb->SetName(name);
+}
+
+// Do you want to delete the player?
+
+void CMainDialog::StartDeleteGame(char *gamer)
+{
+ CWindow* pw;
+ CButton* pb;
+ FPOINT pos, dim;
+ char name[100];
+ char text[100];
+
+ StartDialog(FPOINT(0.7f, 0.3f), FALSE, TRUE, TRUE);
+ m_bDialogDelete = TRUE;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9);
+ if ( pw == 0 ) return;
+
+ pos.x = 0.00f;
+ pos.y = 0.50f;
+ dim.x = 1.00f;
+ dim.y = 0.05f;
+ GetResource(RES_TEXT, RT_DIALOG_DELGAME, name);
+ sprintf(text, name, gamer);
+ pw->CreateLabel(pos, dim, -1, EVENT_DIALOG_LABEL, text);
+
+ pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK);
+ if ( pb == 0 ) return;
+ GetResource(RES_TEXT, RT_DIALOG_YESDEL, name);
+ pb->SetName(name);
+ pb->SetState(STATE_WARNING);
+
+ pb = (CButton*)pw->SearchControl(EVENT_DIALOG_CANCEL);
+ if ( pb == 0 ) return;
+ GetResource(RES_TEXT, RT_DIALOG_NODEL, name);
+ pb->SetName(name);
+}
+
+// Would you quit the game?
+
+void CMainDialog::StartQuit()
+{
+ CWindow* pw;
+ CButton* pb;
+ FPOINT pos, dim;
+ char name[100];
+
+ StartDialog(FPOINT(0.6f, 0.3f), FALSE, TRUE, TRUE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9);
+ if ( pw == 0 ) return;
+
+ pos.x = 0.00f;
+ pos.y = 0.50f;
+ dim.x = 1.00f;
+ dim.y = 0.05f;
+ GetResource(RES_TEXT, RT_DIALOG_QUIT, name);
+ pw->CreateLabel(pos, dim, -1, EVENT_DIALOG_LABEL, name);
+
+ pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK);
+ if ( pb == 0 ) return;
+ GetResource(RES_TEXT, RT_DIALOG_YESQUIT, name);
+ pb->SetName(name);
+ pb->SetState(STATE_WARNING);
+
+ pb = (CButton*)pw->SearchControl(EVENT_DIALOG_CANCEL);
+ if ( pb == 0 ) return;
+ GetResource(RES_TEXT, RT_DIALOG_NOQUIT, name);
+ pb->SetName(name);
+}
+
+// Beginning of displaying a dialog.
+
+void CMainDialog::StartDialog(FPOINT dim, BOOL bFire, BOOL bOK, BOOL bCancel)
+{
+ CWindow* pw;
+ CButton* pb;
+ FPOINT pos, ddim;
+ char name[100];
+
+ StartSuspend();
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW6);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW7);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW8);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT);
+ if ( pb != 0 )
+ {
+ pb->ClearState(STATE_VISIBLE);
+ }
+
+ m_bDialogFire = bFire;
+
+ pos.x = (1.0f-dim.x)/2.0f;
+ pos.y = (1.0f-dim.y)/2.0f;
+ pw = m_interface->CreateWindows(pos, dim, bFire?12:8, EVENT_WINDOW9);
+ pw->SetState(STATE_SHADOW);
+ GetResource(RES_TEXT, RT_TITLE_BASE, name);
+ pw->SetName(name);
+
+ m_dialogPos = pos;
+ m_dialogDim = dim;
+ m_dialogTime = 0.0f;
+ m_dialogParti = 999.0f;
+
+ if ( bOK )
+ {
+ pos.x = 0.50f-0.15f-0.02f;
+ pos.y = 0.50f-dim.y/2.0f+0.03f;
+ ddim.x = 0.15f;
+ ddim.y = 0.06f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_DIALOG_OK);
+ pb->SetState(STATE_SHADOW);
+ GetResource(RES_EVENT, EVENT_DIALOG_OK, name);
+ pb->SetName(name);
+ }
+
+ if ( bCancel )
+ {
+ pos.x = 0.50f+0.02f;
+ pos.y = 0.50f-dim.y/2.0f+0.03f;
+ ddim.x = 0.15f;
+ ddim.y = 0.06f;
+ pb = pw->CreateButton(pos, ddim, -1, EVENT_DIALOG_CANCEL);
+ pb->SetState(STATE_SHADOW);
+ GetResource(RES_EVENT, EVENT_DIALOG_CANCEL, name);
+ pb->SetName(name);
+ }
+
+ m_sound->Play(SOUND_TZOING);
+ m_bDialog = TRUE;
+}
+
+// Animation of a dialog.
+
+void CMainDialog::FrameDialog(float rTime)
+{
+ CWindow* pw;
+ D3DVECTOR pos, speed;
+ FPOINT dim, dpos, ddim;
+ float zoom;
+ int i;
+
+ dpos = m_dialogPos;
+ ddim = m_dialogDim;
+
+ m_dialogTime += rTime;
+ if ( m_dialogTime < 1.0f )
+ {
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9);
+ if ( pw != 0 )
+ {
+ if ( m_dialogTime < 0.50f )
+ {
+ zoom = Bounce(m_dialogTime/0.50f);
+ }
+ else
+ {
+ zoom = 1.0f;
+ }
+
+ dpos.x += ddim.x/2.0f;
+ dpos.y += ddim.y/2.0f;
+
+ ddim.x *= zoom;
+//? ddim.y *= zoom;
+
+ dpos.x -= ddim.x/2.0f;
+ dpos.y -= ddim.y/2.0f;
+
+ pw->SetPos(dpos);
+ pw->SetDim(ddim);
+ }
+ }
+
+ if ( !m_bGlint ) return;
+
+ m_dialogParti += rTime;
+ if ( m_dialogParti < m_engine->ParticuleAdapt(0.05f) ) return;
+ m_dialogParti = 0.0f;
+
+ if ( !m_bDialogFire ) return;
+
+ dpos = m_dialogPos;
+ ddim = m_dialogDim;
+
+ pos.z = 0.0f;
+ speed = D3DVECTOR(0.0f, 0.0f, 0.0f);
+
+ for ( i=0 ; i<2 ; i++ )
+ {
+ // Bottom.
+ pos.x = dpos.x + ddim.x*Rand();
+ pos.y = dpos.y;
+ pos.x += (Rand()-0.5f)*(6.0f/640.0f);
+ pos.y += Rand()*(16.0f/480.0f)-(10.0f/480.0f);
+ dim.x = 0.01f+Rand()*0.01f;
+ dim.y = dim.x/0.75f;
+ m_particule->CreateParticule(pos, speed, dim,
+ (ParticuleType)(PARTILENS1+rand()%3),
+ 1.0f, 0.0f, 0.0f, SH_INTERFACE);
+
+ // Top.
+ pos.x = dpos.x + ddim.x*Rand();
+ pos.y = dpos.y + ddim.y;
+ pos.x += (Rand()-0.5f)*(6.0f/640.0f);
+ pos.y -= Rand()*(16.0f/480.0f)-(10.0f/480.0f);
+ dim.x = 0.01f+Rand()*0.01f;
+ dim.y = dim.x/0.75f;
+ m_particule->CreateParticule(pos, speed, dim,
+ (ParticuleType)(PARTILENS1+rand()%3),
+ 1.0f, 0.0f, 0.0f, SH_INTERFACE);
+
+ // Left.
+ pos.y = dpos.y + ddim.y*Rand();
+ pos.x = dpos.x;
+ pos.x += Rand()*(16.0f/640.0f)-(10.0f/640.0f);
+ pos.y += (Rand()-0.5f)*(6.0f/480.0f);
+ dim.x = 0.01f+Rand()*0.01f;
+ dim.y = dim.x/0.75f;
+ m_particule->CreateParticule(pos, speed, dim,
+ (ParticuleType)(PARTILENS1+rand()%3),
+ 1.0f, 0.0f, 0.0f, SH_INTERFACE);
+
+ // Right.
+ pos.y = dpos.y + ddim.y*Rand();
+ pos.x = dpos.x + ddim.x;
+ pos.x -= Rand()*(16.0f/640.0f)-(10.0f/640.0f);
+ pos.y += (Rand()-0.5f)*(6.0f/480.0f);
+ dim.x = 0.01f+Rand()*0.01f;
+ dim.y = dim.x/0.75f;
+ m_particule->CreateParticule(pos, speed, dim,
+ (ParticuleType)(PARTILENS1+rand()%3),
+ 1.0f, 0.0f, 0.0f, SH_INTERFACE);
+ }
+}
+
+// End of the display of a dialogue.
+
+void CMainDialog::StopDialog()
+{
+ CWindow* pw;
+ CButton* pb;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW2);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW6);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW7);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW8);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pb = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT);
+ if ( pb != 0 )
+ {
+ pb->SetState(STATE_VISIBLE);
+ }
+
+ StopSuspend();
+ m_interface->DeleteControl(EVENT_WINDOW9);
+ m_bDialog = FALSE;
+}
+
+// Suspends the simulation for a dialog phase.
+
+void CMainDialog::StartSuspend()
+{
+ m_sound->MuteAll(TRUE);
+ m_main->ClearInterface();
+ m_bInitPause = m_engine->RetPause();
+ m_engine->SetPause(TRUE);
+ m_engine->SetOverFront(FALSE); // over flat behind
+ m_main->CreateShortcuts();
+ m_main->StartSuspend();
+ m_initCamera = m_camera->RetType();
+ m_camera->SetType(CAMERA_DIALOG);
+}
+
+// Resume the simulation after a period of dialog.
+
+void CMainDialog::StopSuspend()
+{
+ m_sound->MuteAll(FALSE);
+ m_main->ClearInterface();
+ if ( !m_bInitPause ) m_engine->SetPause(FALSE);
+ m_engine->SetOverFront(TRUE); // over flat front
+ m_main->CreateShortcuts();
+ m_main->StopSuspend();
+ m_camera->SetType(m_initCamera);
+}
+
+
+// Whether to use tooltips.
+
+BOOL CMainDialog::RetTooltip()
+{
+ return m_bTooltip;
+}
+
+// Specifies whether a dialog is displayed.
+
+BOOL CMainDialog::IsDialog()
+{
+ return m_bDialog;
+}
+
+
+
+
+// Specifies the name of the scene to read.
+
+void CMainDialog::SetSceneRead(char* name)
+{
+ strcpy(m_sceneRead, name);
+}
+
+// Returns the name of the scene to read.
+
+char* CMainDialog::RetSceneRead()
+{
+ return m_sceneRead;
+}
+
+// Specifies the name of the scene to read.
+
+void CMainDialog::SetStackRead(char* name)
+{
+ strcpy(m_stackRead, name);
+}
+
+// Returns the name of the scene to read.
+
+char* CMainDialog::RetStackRead()
+{
+ return m_stackRead;
+}
+
+// Specifies the name of the chosen to play scene.
+
+void CMainDialog::SetSceneName(char* name)
+{
+ strcpy(m_sceneName, name);
+}
+
+// Returns the name of the chosen to play scene.
+
+char* CMainDialog::RetSceneName()
+{
+ return m_sceneName;
+}
+
+// Specifies the rank of the chosen to play scene.
+
+void CMainDialog::SetSceneRank(int rank)
+{
+ m_sceneRank = rank;
+}
+
+// Returns the rank of the chosen to play scene.
+
+int CMainDialog::RetSceneRank()
+{
+ return m_sceneRank;
+}
+
+// Returns folder name of the scene that user selected to play.
+
+char* CMainDialog::RetSceneDir()
+{
+ int i;
+
+ i = (m_sceneRank/100)-1;
+
+ if ( i < 0 || i >= m_userTotal ) return 0;
+ return m_userList[i];
+}
+
+// Whether to show the solution.
+
+BOOL CMainDialog::RetSceneSoluce()
+{
+ return m_bSceneSoluce;
+}
+
+// Returns the name of the folder to save.
+
+char* CMainDialog::RetSavegameDir()
+{
+ return m_savegameDir;
+}
+
+// Returns the name of public folder.
+
+char* CMainDialog::RetPublicDir()
+{
+ return m_publicDir;
+}
+
+
+// Indicates if there are reflections on the buttons.
+
+BOOL CMainDialog::RetGlint()
+{
+ return m_bGlint;
+}
+
+// Whether to show 4:solutions.
+
+BOOL CMainDialog::RetSoluce4()
+{
+ return m_bSoluce4;
+}
+
+// Whether to show the cinematics.
+
+BOOL CMainDialog::RetMovies()
+{
+ return m_bMovies;
+}
+
+// IWhether to make an animation in CTaskReset.
+
+BOOL CMainDialog::RetNiceReset()
+{
+ return m_bNiceReset;
+}
+
+// Indicates whether the fire causes damage to its own units.
+
+BOOL CMainDialog::RetHimselfDamage()
+{
+ return m_bHimselfDamage;
+}
+
+
+
+// Saves the personalized player.
+
+void CMainDialog::WriteGamerPerso(char *gamer)
+{
+ FILE* file;
+ char filename[100];
+ char line[100];
+
+ sprintf(filename, "%s\\%s\\face.gam", m_savegameDir, gamer);
+ file = fopen(filename, "w");
+ if ( file == NULL ) return;
+
+ sprintf(line, "Head face=%d glasses=%d hair=%.2f;%.2f;%.2f;%.2f\n",
+ m_perso.face, m_perso.glasses,
+ m_perso.colorHair.r, m_perso.colorHair.g, m_perso.colorHair.b, m_perso.colorHair.a);
+ fputs(line, file);
+
+ sprintf(line, "Body combi=%.2f;%.2f;%.2f;%.2f band=%.2f;%.2f;%.2f;%.2f\n",
+ m_perso.colorCombi.r, m_perso.colorCombi.g, m_perso.colorCombi.b, m_perso.colorCombi.a,
+ m_perso.colorBand.r, m_perso.colorBand.g, m_perso.colorBand.b, m_perso.colorBand.a);
+ fputs(line, file);
+
+ fclose(file);
+}
+
+// Reads the personalized player.
+
+void CMainDialog::ReadGamerPerso(char *gamer)
+{
+ FILE* file;
+ char filename[100];
+ char line[100];
+ D3DCOLORVALUE color;
+
+ m_perso.face = 0;
+ DefPerso();
+
+ sprintf(filename, "%s\\%s\\face.gam", m_savegameDir, gamer);
+ file = fopen(filename, "r");
+ if ( file == NULL ) return;
+
+ while ( fgets(line, 100, file) != NULL )
+ {
+ if ( Cmd(line, "Head") )
+ {
+ m_perso.face = OpInt(line, "face", 0);
+ m_perso.glasses = OpInt(line, "glasses", 0);
+
+ color.r = 0.0f;
+ color.g = 0.0f;
+ color.b = 0.0f;
+ color.a = 0.0f;
+ m_perso.colorHair = OpColorValue(line, "hair", color);
+ }
+
+ if ( Cmd(line, "Body") )
+ {
+ color.r = 0.0f;
+ color.g = 0.0f;
+ color.b = 0.0f;
+ color.a = 0.0f;
+ m_perso.colorCombi = OpColorValue(line, "combi", color);
+
+ color.r = 0.0f;
+ color.g = 0.0f;
+ color.b = 0.0f;
+ color.a = 0.0f;
+ m_perso.colorBand = OpColorValue(line, "band", color);
+ }
+ }
+
+ fclose(file);
+}
+
+// Specifies the face of the player.
+
+void CMainDialog::SetGamerFace(char *gamer, int face)
+{
+ m_perso.face = face;
+ WriteGamerPerso(gamer);
+}
+
+// Gives the face of the player.
+
+int CMainDialog::RetGamerFace(char *gamer)
+{
+ ReadGamerPerso(gamer);
+ return m_perso.face;
+}
+
+// Gives the face of the player.
+
+int CMainDialog::RetGamerFace()
+{
+ return m_perso.face;
+}
+
+int CMainDialog::RetGamerGlasses()
+{
+ return m_perso.glasses;
+}
+
+BOOL CMainDialog::RetGamerOnlyHead()
+{
+ return (m_phase == PHASE_PERSO && m_persoTab == 0);
+}
+
+float CMainDialog::RetPersoAngle()
+{
+ return m_persoAngle;
+}
+
+D3DCOLORVALUE CMainDialog::RetGamerColorHair()
+{
+ return m_perso.colorHair;
+}
+
+D3DCOLORVALUE CMainDialog::RetGamerColorCombi()
+{
+ return m_perso.colorCombi;
+}
+
+D3DCOLORVALUE CMainDialog::RetGamerColorBand()
+{
+ return m_perso.colorBand;
+}
+
+
+// Reads the file of the player.
+
+BOOL CMainDialog::ReadGamerInfo()
+{
+ FILE* file;
+ char line[100];
+ int chap, i, numTry, passed;
+
+ for ( i=0 ; i<MAXSCENE ; i++ )
+ {
+ m_sceneInfo[i].numTry = 0;
+ m_sceneInfo[i].bPassed = FALSE;
+ }
+
+ sprintf(line, "%s\\%s\\%s.gam", m_savegameDir, m_main->RetGamerName(), m_sceneName);
+ file = fopen(line, "r");
+ if ( file == NULL ) return FALSE;
+
+ if ( fgets(line, 100, file) != NULL )
+ {
+ sscanf(line, "CurrentChapter=%d CurrentSel=%d\n", &chap, &i);
+ m_chap[m_index] = chap-1;
+ m_sel[m_index] = i-1;
+ }
+
+ while ( fgets(line, 100, file) != NULL )
+ {
+ sscanf(line, "Chapter %d: Scene %d: numTry=%d passed=%d\n",
+ &chap, &i, &numTry, &passed);
+
+ i += chap*100;
+ if ( i >= 0 && i < MAXSCENE )
+ {
+ m_sceneInfo[i].numTry = numTry;
+ m_sceneInfo[i].bPassed = passed;
+ }
+ }
+
+ fclose(file);
+ return TRUE;
+}
+
+// Writes the file of the player.
+
+BOOL CMainDialog::WriteGamerInfo()
+{
+ FILE* file;
+ char line[100];
+ int i;
+
+ sprintf(line, "%s\\%s\\%s.gam", m_savegameDir, m_main->RetGamerName(), m_sceneName);
+ file = fopen(line, "w");
+ if ( file == NULL ) return FALSE;
+
+ sprintf(line, "CurrentChapter=%d CurrentSel=%d\n",
+ m_chap[m_index]+1, m_sel[m_index]+1);
+ fputs(line, file);
+
+ for ( i=0 ; i<MAXSCENE ; i++ )
+ {
+ if ( m_sceneInfo[i].numTry == 0 ) continue;
+
+ sprintf(line, "Chapter %d: Scene %d: numTry=%d passed=%d\n",
+ i/100, i%100, m_sceneInfo[i].numTry, m_sceneInfo[i].bPassed);
+ fputs(line, file);
+ }
+
+ fclose(file);
+ return TRUE;
+}
+
+void CMainDialog::SetGamerInfoTry(int rank, int numTry)
+{
+ if ( rank < 0 || rank >= MAXSCENE ) return;
+ if ( numTry > 100 ) numTry = 100;
+ m_sceneInfo[rank].numTry = numTry;
+}
+
+int CMainDialog::RetGamerInfoTry(int rank)
+{
+ if ( rank < 0 || rank >= MAXSCENE ) return 0;
+ return m_sceneInfo[rank].numTry;
+}
+
+void CMainDialog::SetGamerInfoPassed(int rank, BOOL bPassed)
+{
+ int chap, i;
+ BOOL bAll;
+
+ if ( rank < 0 || rank >= MAXSCENE ) return;
+ m_sceneInfo[rank].bPassed = bPassed;
+
+ if ( bPassed )
+ {
+ bAll = TRUE;
+ chap = rank/100;
+ for ( i=0 ; i<m_maxList ; i++ )
+ {
+ bAll &= m_sceneInfo[chap*100+i+1].bPassed;
+ }
+ m_sceneInfo[chap*100].numTry ++;
+ m_sceneInfo[chap*100].bPassed = bAll;
+ }
+}
+
+BOOL CMainDialog::RetGamerInfoPassed(int rank)
+{
+ if ( rank < 0 || rank >= MAXSCENE ) return FALSE;
+ return m_sceneInfo[rank].bPassed;
+}
+
+
+// Passes to the next mission, and possibly in the next chapter.
+
+BOOL CMainDialog::NextMission()
+{
+ m_sel[m_index] ++; // next mission
+
+ if ( m_sel[m_index] >= m_maxList ) // last mission of the chapter?
+ {
+ m_chap[m_index] ++; // next chapter
+ m_sel[m_index] = 0; // first mission
+ }
+
+ return TRUE;
+}
+
+
diff --git a/src/ui/maindialog.h b/src/ui/maindialog.h
new file mode 100644
index 0000000..21dca18
--- /dev/null
+++ b/src/ui/maindialog.h
@@ -0,0 +1,256 @@
+// * 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/.
+
+// maindialog.h
+
+#ifndef _MAINDIALOG_H_
+#define _MAINDIALOG_H_
+
+#include "struct.h"
+#include "camera.h"
+#include "robotmain.h"
+
+
+class CInstanceManager;
+class CEvent;
+class CD3DEngine;
+class CInterface;
+class CWindow;
+class CControl;
+class CParticule;
+class CSound;
+
+
+#define USERLISTMAX 100
+#define MAXSCENE 1000
+
+typedef struct
+{
+ char numTry;
+ char bPassed;
+}
+SceneInfo;
+
+typedef struct
+{
+ int face; // face
+ int glasses; // glasses
+ D3DCOLORVALUE colorHair; // hair color
+ D3DCOLORVALUE colorCombi; // spacesuit volor
+ D3DCOLORVALUE colorBand; // strips color
+}
+GamerPerso;
+
+
+
+class CMainDialog
+{
+public:
+ CMainDialog(CInstanceManager* iMan);
+ ~CMainDialog();
+
+ BOOL EventProcess(const Event &event);
+ void ChangePhase(Phase phase);
+
+ void SetSceneRead(char* name);
+ void SetStackRead(char* name);
+ void SetSceneName(char* name);
+ void SetSceneRank(int rank);
+ char* RetSceneRead();
+ char* RetStackRead();
+ char* RetSceneName();
+ int RetSceneRank();
+ char* RetSceneDir();
+ BOOL RetSceneSoluce();
+ char* RetSavegameDir();
+ char* RetPublicDir();
+
+ BOOL RetTooltip();
+ BOOL RetGlint();
+ BOOL RetSoluce4();
+ BOOL RetMovies();
+ BOOL RetNiceReset();
+ BOOL RetHimselfDamage();
+
+ void SetUserDir(char *base, int rank);
+ void BuildSceneName(char *filename, char *base, int rank);
+ void BuildResumeName(char *filename, char *base, int rank);
+ char* RetFilesDir();
+
+ void StartAbort();
+ void StartDeleteObject();
+ void StartDeleteGame(char *gamer);
+ void StartQuit();
+ void StartDialog(FPOINT dim, BOOL bFire, BOOL bOK, BOOL bCancel);
+ void FrameDialog(float rTime);
+ void StopDialog();
+ BOOL IsDialog();
+
+ void StartSuspend();
+ void StopSuspend();
+
+ void SetupMemorize();
+ void SetupRecall();
+
+ BOOL ReadGamerInfo();
+ BOOL WriteGamerInfo();
+ void SetGamerInfoTry(int rank, int numTry);
+ int RetGamerInfoTry(int rank);
+ void SetGamerInfoPassed(int rank, BOOL bPassed);
+ BOOL RetGamerInfoPassed(int rank);
+ BOOL NextMission();
+
+ void WriteGamerPerso(char *gamer);
+ void ReadGamerPerso(char *gamer);
+ void SetGamerFace(char *gamer, int face);
+ int RetGamerFace(char *gamer);
+ int RetGamerFace();
+ int RetGamerGlasses();
+ BOOL RetGamerOnlyHead();
+ float RetPersoAngle();
+ D3DCOLORVALUE RetGamerColorHair();
+ D3DCOLORVALUE RetGamerColorCombi();
+ D3DCOLORVALUE RetGamerColorBand();
+
+ void AllMissionUpdate();
+ void ShowSoluceUpdate();
+
+protected:
+ void GlintMove();
+ void FrameParticule(float rTime);
+ void NiceParticule(FPOINT mouse, BOOL bPress);
+ void ReadNameList();
+ void UpdateNameList();
+ void UpdateNameEdit();
+ void UpdateNameControl();
+ void UpdateNameFace();
+ void NameSelect();
+ void NameCreate();
+ void NameDelete();
+ void UpdatePerso();
+ void CameraPerso();
+ void FixPerso(int rank, int index);
+ void ColorPerso();
+ void DefPerso();
+ BOOL IsIOReadScene();
+ void IOReadName();
+ void IOReadList();
+ void IOUpdateList();
+ void IODeleteScene();
+ BOOL IOWriteScene();
+ BOOL IOReadScene();
+ int RetChapPassed();
+ void UpdateSceneChap(int &chap);
+ void UpdateSceneList(int chap, int &sel);
+ void UpdateSceneResume(int rank);
+ void UpdateDisplayDevice();
+ void UpdateDisplayMode();
+ void ChangeDisplay();
+ void UpdateApply();
+ void UpdateSetupButtons();
+ void ChangeSetupButtons();
+ void ChangeSetupQuality(int quality);
+ void UpdateKey();
+ void ChangeKey(EventMsg event);
+
+protected:
+ CInstanceManager* m_iMan;
+ CRobotMain* m_main;
+ CEvent* m_event;
+ CD3DEngine* m_engine;
+ CInterface* m_interface;
+ CParticule* m_particule;
+ CCamera* m_camera;
+ CSound* m_sound;
+
+ Phase m_phase; // copy of CRobotMain
+ Phase m_phaseSetup; // tab selected
+ Phase m_phaseTerm; // phase trainer/scene/proto
+ float m_phaseTime;
+
+ GamerPerso m_perso; // perso: description
+ GamerPerso m_persoCopy; // perso: copy for cancellation
+ int m_persoTab; // perso: tab selected
+ float m_persoAngle; // perso: angle of presentation
+
+ char m_sceneDir[_MAX_FNAME]; // scene folder
+ char m_savegameDir[_MAX_FNAME]; // savegame folder
+ char m_publicDir[_MAX_FNAME]; // program folder
+ char m_userDir[_MAX_FNAME]; // user folder
+ char m_filesDir[_MAX_FNAME]; // case files
+
+ int m_index; // 0..4
+ int m_chap[10]; // selected chapter (0..8)
+ int m_sel[10]; // chosen mission (0..98)
+ int m_maxList;
+ int m_accessChap;
+ char m_sceneRead[100]; // name of the scene to read
+ char m_stackRead[100]; // name of the scene to read
+ char m_sceneName[20]; // name of the scene to play
+ int m_sceneRank; // rank of the scene to play
+ BOOL m_bSceneSoluce; // shows the solution
+ BOOL m_bSimulSetup; // adjustment during the game
+ BOOL m_accessEnable;
+ BOOL m_accessMission;
+ BOOL m_accessUser;
+ BOOL m_bDeleteGamer;
+
+ int m_userTotal;
+ char m_userList[USERLISTMAX][100];
+
+ int m_shotDelay; // number of frames before copy
+ char m_shotName[100]; // generate a file name
+
+ int m_setupSelDevice;
+ int m_setupSelMode;
+ BOOL m_setupFull;
+
+ BOOL m_bTooltip; // tooltips to be displayed?
+ BOOL m_bGlint; // reflections on buttons?
+ BOOL m_bRain; // rain in the interface?
+ BOOL m_bSoluce4; // solutions in program 4?
+ BOOL m_bMovies; // cinematics?
+ BOOL m_bNiceReset; // for CTaskReset
+ BOOL m_bHimselfDamage; // for shots
+ BOOL m_bCameraScroll; // for CCamera
+ BOOL m_bCameraInvertX; // for CCamera
+ BOOL m_bCameraInvertY; // for CCamera
+ BOOL m_bEffect; // for CCamera
+
+ FPOINT m_glintMouse;
+ float m_glintTime;
+
+ int m_loadingCounter;
+
+ BOOL m_bDialog; // this dialogue?
+ BOOL m_bDialogFire; // setting on fire?
+ BOOL m_bDialogDelete;
+ FPOINT m_dialogPos;
+ FPOINT m_dialogDim;
+ float m_dialogParti;
+ float m_dialogTime;
+ BOOL m_bInitPause;
+ CameraType m_initCamera;
+
+ int m_partiPhase[10];
+ float m_partiTime[10];
+ FPOINT m_partiPos[10];
+
+ SceneInfo m_sceneInfo[MAXSCENE];
+};
+
+
+#endif //_MAINDIALOG_H_
diff --git a/src/ui/mainmap.cpp b/src/ui/mainmap.cpp
new file mode 100644
index 0000000..c66edf2
--- /dev/null
+++ b/src/ui/mainmap.cpp
@@ -0,0 +1,404 @@
+// * 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/.
+
+// mainmap.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "d3dmath.h"
+#include "global.h"
+#include "event.h"
+#include "iman.h"
+#include "interface.h"
+#include "map.h"
+#include "image.h"
+#include "group.h"
+#include "slider.h"
+#include "scroll.h"
+#include "window.h"
+#include "mainmap.h"
+
+
+
+#define ZOOM_MIN 1.0f
+#define ZOOM_MAX 16.0f
+
+
+
+// Constructor of the application card.
+
+CMainMap::CMainMap(CInstanceManager* iMan)
+{
+ m_iMan = iMan;
+ m_iMan->AddInstance(CLASS_MAP, this);
+
+ m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE);
+ m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT);
+ m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE);
+
+ m_mapMode = 1;
+ m_bFixImage = FALSE;
+}
+
+// Destructor of the application card.
+
+CMainMap::~CMainMap()
+{
+}
+
+
+// Created the mini-map and the corresponding buttons.
+
+void CMainMap::CreateMap()
+{
+ CWindow* pw;
+ FPOINT pos, dim;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw == 0 )
+ {
+ pos.x = 0.0f;
+ pos.y = 0.0f;
+ dim.x = 0.0f;
+ dim.y = 0.0f;
+ pw = m_interface->CreateWindows(pos, dim, 10, EVENT_WINDOW1);
+ }
+
+ dim.x = 10.0f/640.0f;
+ dim.y = 10.0f/480.0f;
+ pos.x = 10.0f/640.0f;
+ pos.y = 10.0f/480.0f;
+ pw->CreateMap (pos, dim, 2, EVENT_OBJECT_MAP);
+ pw->CreateSlider(pos, dim, 0, EVENT_OBJECT_MAPZOOM);
+
+ DimMap();
+}
+
+// Indicates whether the mini-map should display a still image.
+
+void CMainMap::SetFixImage(char *filename)
+{
+ CWindow* pw;
+ CMap* pm;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw == 0 ) return;
+
+ pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP);
+ if ( pm == 0 ) return;
+
+ pw->DeleteControl(EVENT_OBJECT_MAPZOOM);
+ m_bFixImage = TRUE;
+
+ pm->SetFixImage(filename);
+}
+
+// Choosing colors of soil and water for the mini-map.
+
+void CMainMap::FloorColorMap(D3DCOLORVALUE floor, D3DCOLORVALUE water)
+{
+ CWindow* pw;
+ CMap* pm;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw == 0 ) return;
+
+ pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP);
+ if ( pm != 0 )
+ {
+ pm->SetFloorColor(floor);
+ pm->SetWaterColor(water);
+ }
+}
+
+// Shows or hides the minimap.
+
+void CMainMap::ShowMap(BOOL bShow)
+{
+ CWindow* pw;
+ CMap* pm;
+ CSlider* ps;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw == 0 ) return;
+
+ if ( bShow )
+ {
+ DimMap();
+ }
+ else
+ {
+ pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP);
+ if ( pm != 0 )
+ {
+ pm->ClearState(STATE_VISIBLE);
+ }
+
+ ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM);
+ if ( ps != 0 )
+ {
+ ps->ClearState(STATE_VISIBLE);
+ }
+ }
+}
+
+// Dimensions of the mini-map.
+
+void CMainMap::DimMap()
+{
+ CWindow* pw;
+ CMap* pm;
+ CSlider* ps;
+ FPOINT pos, dim;
+ float value;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw == 0 ) return;
+ pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP);
+ if ( pm == 0 ) return;
+
+ pm->SetState(STATE_VISIBLE, (m_mapMode != 0));
+
+ dim.x = 100.0f/640.0f;
+ dim.y = 100.0f/480.0f;
+ pos.x = 540.0f/640.0f;
+ pos.y = 0.0f/480.0f;
+ pm->SetPos(pos);
+ pm->SetDim(dim);
+
+ ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM);
+ if ( ps != 0 )
+ {
+ ps->SetState(STATE_VISIBLE, (m_mapMode != 0));
+
+ dim.x = SCROLL_WIDTH;
+ dim.y = 66.0f/480.0f;
+ pos.x = 523.0f/640.0f;
+ pos.y = 3.0f/480.0f;
+ ps->SetPos(pos);
+ ps->SetDim(dim);
+
+ value = pm->RetZoom();
+ value = (value-ZOOM_MIN)/(ZOOM_MAX-ZOOM_MIN);
+ value = powf(value, 0.5f);
+ ps->SetVisibleValue(value);
+ ps->SetArrowStep(0.2f);
+ }
+}
+
+// Returns the current zoom of the minimap.
+
+float CMainMap::RetZoomMap()
+{
+ CWindow* pw;
+ CMap* pm;
+ CSlider* ps;
+
+ pw = (CWindow*)pw->SearchControl(EVENT_WINDOW1);
+ if ( pw == 0 ) return ZOOM_MIN;
+
+ pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP);
+ if ( pm == 0 ) return ZOOM_MIN;
+
+ ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM);
+ if ( ps == 0 ) return ZOOM_MIN;
+
+ return pm->RetZoom();
+}
+
+// Zoom the mini-map of any factor.
+
+void CMainMap::ZoomMap(float zoom)
+{
+ CWindow* pw;
+ CMap* pm;
+ CSlider* ps;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw == 0 ) return;
+ pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP);
+ if ( pm == 0 ) return;
+
+ ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM);
+ if ( ps == 0 ) return;
+
+ if ( zoom < ZOOM_MIN ) zoom = ZOOM_MIN;
+ if ( zoom > ZOOM_MAX ) zoom = ZOOM_MAX;
+ pm->SetZoom(zoom);
+
+ DimMap();
+}
+
+// The mini-map zoom depending on the slider.
+
+void CMainMap::ZoomMap()
+{
+ CWindow* pw;
+ CMap* pm;
+ CSlider* ps;
+ float zoom;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw == 0 ) return;
+ pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP);
+ if ( pm == 0 ) return;
+
+ ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM);
+ if ( ps == 0 ) return;
+
+ zoom = ps->RetVisibleValue();
+ zoom = powf(zoom, 2.0f);
+ zoom = ZOOM_MIN+zoom*(ZOOM_MAX-ZOOM_MIN);
+ pm->SetZoom(zoom);
+
+ DimMap();
+}
+
+// Enables or disables the card.
+
+void CMainMap::MapEnable(BOOL bEnable)
+{
+ CWindow* pw;
+ CMap* pm;
+ CSlider* ps;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw == 0 ) return;
+
+ pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP);
+ if ( pm != 0 )
+ {
+ pm->SetEnable(bEnable);
+ }
+
+ ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_MAPZOOM);
+ if ( ps != 0 )
+ {
+ ps->SetState(STATE_ENABLE, bEnable);
+ }
+}
+
+// Specifies the type of icon for the selected object.
+
+void CMainMap::SetToy(BOOL bToy)
+{
+ CWindow* pw;
+ CMap* pm;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw == 0 ) return;
+
+ pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP);
+ if ( pm == 0 ) return;
+
+ pm->SetToy(bToy);
+}
+
+// Specifies the parameters when using a still image.
+
+void CMainMap::SetFixParam(float zoom, float ox, float oy, float angle,
+ int mode, BOOL bDebug)
+{
+ CWindow* pw;
+ CMap* pm;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw == 0 ) return;
+
+ pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP);
+ if ( pm == 0 ) return;
+
+ pm->SetZoom(zoom);
+ pm->SetOffset(ox, oy);
+ pm->SetAngle(angle);
+ pm->SetMode(mode);
+ pm->SetDebug(bDebug);
+}
+
+// Updates the mini-map following to a change of terrain.
+
+void CMainMap::UpdateMap()
+{
+ CWindow* pw;
+ CMap* pm;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw == 0 ) return;
+
+ pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP);
+ if ( pm != 0 )
+ {
+ pm->UpdateTerrain();
+ }
+}
+
+// Indicates if the mini-map is visible.
+
+BOOL CMainMap::RetShowMap()
+{
+ return ( m_mapMode != 0 );
+}
+
+// Indicates whether the mini-map displays a still image.
+
+BOOL CMainMap::RetFixImage()
+{
+ return m_bFixImage;
+}
+
+
+// The object is detected in the mini-map.
+
+CObject* CMainMap::DetectMap(FPOINT pos, BOOL &bInMap)
+{
+ CWindow* pw;
+ CMap* pm;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw == 0 ) return 0;
+
+ bInMap = FALSE;
+ pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP);
+ if ( pm == 0 ) return 0;
+ return pm->DetectObject(pos, bInMap);
+}
+
+
+// Indicates the object with the mouse hovers over.
+
+void CMainMap::SetHilite(CObject* pObj)
+{
+ CWindow* pw;
+ CMap* pm;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw == 0 ) return;
+
+ pm = (CMap*)pw->SearchControl(EVENT_OBJECT_MAP);
+ if ( pm != 0 )
+ {
+ pm->SetHilite(pObj);
+ }
+}
+
+
diff --git a/src/ui/mainmap.h b/src/ui/mainmap.h
new file mode 100644
index 0000000..f9fe0be
--- /dev/null
+++ b/src/ui/mainmap.h
@@ -0,0 +1,68 @@
+// * 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/.
+
+// mainmap.h
+
+#ifndef _MAINMAP_H_
+#define _MAINMAP_H_
+
+
+class CInstanceManager;
+class CEvent;
+class CD3DEngine;
+class CInterface;
+class CObject;
+
+
+
+class CMainMap
+{
+public:
+ CMainMap(CInstanceManager* iMan);
+ ~CMainMap();
+
+ void UpdateMap();
+ void CreateMap();
+ void SetFixImage(char *filename);
+ void FloorColorMap(D3DCOLORVALUE floor, D3DCOLORVALUE water);
+ void ShowMap(BOOL bShow);
+ void DimMap();
+ float RetZoomMap();
+ void ZoomMap(float zoom);
+ void ZoomMap();
+ void MapEnable(BOOL bEnable);
+ BOOL RetShowMap();
+ BOOL RetFixImage();
+ CObject* DetectMap(FPOINT pos, BOOL &bInMap);
+ void SetHilite(CObject* pObj);
+ void SetToy(BOOL bToy);
+ void SetFixParam(float zoom, float ox, float oy, float angle, int mode, BOOL bDebug);
+
+protected:
+ void CenterMap();
+
+protected:
+ CInstanceManager* m_iMan;
+ CEvent* m_event;
+ CD3DEngine* m_engine;
+ CInterface* m_interface;
+
+ int m_mapMode;
+ BOOL m_bFixImage;
+};
+
+
+#endif //_MAINMAP_H_
diff --git a/src/ui/mainshort.cpp b/src/ui/mainshort.cpp
new file mode 100644
index 0000000..4e934e5
--- /dev/null
+++ b/src/ui/mainshort.cpp
@@ -0,0 +1,376 @@
+// * 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/.
+
+// mainshort.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "global.h"
+#include "event.h"
+#include "iman.h"
+#include "object.h"
+#include "interface.h"
+#include "map.h"
+#include "button.h"
+#include "robotmain.h"
+#include "mainshort.h"
+
+
+
+
+// Constructor of the application card.
+
+CMainShort::CMainShort(CInstanceManager* iMan)
+{
+ m_iMan = iMan;
+ m_iMan->AddInstance(CLASS_SHORT, this);
+
+ m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE);
+ m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT);
+ m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE);
+ m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN);
+
+ FlushShortcuts();
+}
+
+// Destructor of the application card.
+
+CMainShort::~CMainShort()
+{
+}
+
+
+
+void CMainShort::SetMode(BOOL bBuilding)
+{
+ m_bBuilding = bBuilding;
+}
+
+
+
+// Reset all shortcuts.
+
+void CMainShort::FlushShortcuts()
+{
+ int i;
+
+ for ( i=0 ; i<20 ; i++ )
+ {
+ m_shortcuts[i] = 0;
+ }
+}
+
+static EventMsg table_sc_em[20] =
+{
+ EVENT_OBJECT_SHORTCUT00,
+ EVENT_OBJECT_SHORTCUT01,
+ EVENT_OBJECT_SHORTCUT02,
+ EVENT_OBJECT_SHORTCUT03,
+ EVENT_OBJECT_SHORTCUT04,
+ EVENT_OBJECT_SHORTCUT05,
+ EVENT_OBJECT_SHORTCUT06,
+ EVENT_OBJECT_SHORTCUT07,
+ EVENT_OBJECT_SHORTCUT08,
+ EVENT_OBJECT_SHORTCUT09,
+ EVENT_OBJECT_SHORTCUT10,
+ EVENT_OBJECT_SHORTCUT11,
+ EVENT_OBJECT_SHORTCUT12,
+ EVENT_OBJECT_SHORTCUT13,
+ EVENT_OBJECT_SHORTCUT14,
+ EVENT_OBJECT_SHORTCUT15,
+ EVENT_OBJECT_SHORTCUT16,
+ EVENT_OBJECT_SHORTCUT17,
+ EVENT_OBJECT_SHORTCUT18,
+ EVENT_OBJECT_SHORTCUT19,
+};
+
+// Interface creates shortcuts to the units.
+
+BOOL CMainShort::CreateShortcuts()
+{
+ CObject* pObj;
+ CControl* pc;
+ ObjectType type;
+ FPOINT pos, dim;
+ int i, rank, icon;
+ char name[100];
+
+ if ( m_main->RetFixScene() ) return FALSE;
+
+ m_interface->DeleteControl(EVENT_OBJECT_MOVIELOCK);
+ m_interface->DeleteControl(EVENT_OBJECT_EDITLOCK);
+ for ( i=0 ; i<20 ; i++ )
+ {
+ if ( i != 0 && m_shortcuts[i] == 0 ) continue;
+
+ m_interface->DeleteControl(table_sc_em[i]);
+ m_shortcuts[i] = 0;
+ }
+
+ dim.x = 28.0f/640.0f;
+ dim.y = 28.0f/480.0f;
+ pos.x = 4.0f/640.0f;
+ pos.y = (480.0f-32.0f)/480.0f;
+
+ if ( m_main->RetMovieLock() &&
+ !m_main->RetEditLock() ) // hangs during film?
+ {
+ m_interface->CreateShortcut(pos, dim, 7, EVENT_OBJECT_MOVIELOCK);
+ return TRUE;
+ }
+ if ( !m_main->RetFreePhoto() &&
+ (m_main->RetEditLock() ||
+ m_engine->RetPause()) ) // hangs during edition?
+ {
+ m_interface->CreateShortcut(pos, dim, 6, EVENT_OBJECT_EDITLOCK);
+ return TRUE;
+ }
+
+ rank = 0;
+
+ m_interface->CreateShortcut(pos, dim, 2, table_sc_em[rank]);
+ pos.x += dim.x*1.2f;
+ m_shortcuts[rank] = 0;
+ rank ++;
+
+ for ( i=0 ; i<1000000 ; i++ )
+ {
+ pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
+ if ( pObj == 0 ) break;
+
+ if ( !pObj->RetActif() ) continue;
+ if ( !pObj->RetSelectable() ) continue;
+ if ( pObj->RetProxyActivate() ) continue;
+
+ type = pObj->RetType();
+ icon = -1;
+ if ( m_bBuilding )
+ {
+ if ( type == OBJECT_FACTORY ) icon = 32;
+ if ( type == OBJECT_DERRICK ) icon = 33;
+ if ( type == OBJECT_CONVERT ) icon = 34;
+ if ( type == OBJECT_RESEARCH ) icon = 35;
+ if ( type == OBJECT_STATION ) icon = 36;
+ if ( type == OBJECT_TOWER ) icon = 37;
+ if ( type == OBJECT_LABO ) icon = 38;
+ if ( type == OBJECT_ENERGY ) icon = 39;
+ if ( type == OBJECT_RADAR ) icon = 40;
+ if ( type == OBJECT_INFO ) icon = 44;
+ if ( type == OBJECT_REPAIR ) icon = 41;
+ if ( type == OBJECT_DESTROYER) icon = 41;
+ if ( type == OBJECT_NUCLEAR ) icon = 42;
+ if ( type == OBJECT_PARA ) icon = 46;
+ if ( type == OBJECT_SAFE ) icon = 47;
+ if ( type == OBJECT_HUSTON ) icon = 48;
+ if ( type == OBJECT_BASE ) icon = 43;
+ }
+ else
+ {
+ if ( type == OBJECT_HUMAN ) icon = 8;
+ if ( type == OBJECT_MOBILEfa ) icon = 11;
+ if ( type == OBJECT_MOBILEta ) icon = 10;
+ if ( type == OBJECT_MOBILEwa ) icon = 9;
+ if ( type == OBJECT_MOBILEia ) icon = 22;
+ if ( type == OBJECT_MOBILEfc ) icon = 17;
+ if ( type == OBJECT_MOBILEtc ) icon = 16;
+ if ( type == OBJECT_MOBILEwc ) icon = 15;
+ if ( type == OBJECT_MOBILEic ) icon = 23;
+ if ( type == OBJECT_MOBILEfi ) icon = 27;
+ if ( type == OBJECT_MOBILEti ) icon = 26;
+ if ( type == OBJECT_MOBILEwi ) icon = 25;
+ if ( type == OBJECT_MOBILEii ) icon = 28;
+ if ( type == OBJECT_MOBILEfs ) icon = 14;
+ if ( type == OBJECT_MOBILEts ) icon = 13;
+ if ( type == OBJECT_MOBILEws ) icon = 12;
+ if ( type == OBJECT_MOBILEis ) icon = 24;
+ if ( type == OBJECT_MOBILErt ) icon = 18;
+ if ( type == OBJECT_MOBILErc ) icon = 19;
+ if ( type == OBJECT_MOBILErr ) icon = 20;
+ if ( type == OBJECT_MOBILErs ) icon = 29;
+ if ( type == OBJECT_MOBILEsa ) icon = 21;
+ if ( type == OBJECT_MOBILEft ) icon = 30;
+ if ( type == OBJECT_MOBILEtt ) icon = 30;
+ if ( type == OBJECT_MOBILEwt ) icon = 30;
+ if ( type == OBJECT_MOBILEit ) icon = 30;
+ if ( type == OBJECT_MOBILEdr ) icon = 48;
+ if ( type == OBJECT_APOLLO2 ) icon = 49;
+ }
+ if ( icon == -1 ) continue;
+
+ m_interface->CreateShortcut(pos, dim, icon, table_sc_em[rank]);
+ pos.x += dim.x;
+ m_shortcuts[rank] = pObj;
+
+ pc = m_interface->SearchControl(table_sc_em[rank]);
+ if ( pc != 0 )
+ {
+ pObj->GetTooltipName(name);
+ pc->SetTooltip(name);
+ }
+ rank ++;
+
+ if ( rank >= 20 ) break;
+ }
+
+ UpdateShortcuts();
+ return TRUE;
+}
+
+// Updates the interface shortcuts to the units.
+
+BOOL CMainShort::UpdateShortcuts()
+{
+ CControl* pc;
+ int i;
+
+ for ( i=0 ; i<20 ; i++ )
+ {
+ if ( m_shortcuts[i] == 0 ) continue;
+
+ pc = m_interface->SearchControl(table_sc_em[i]);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_shortcuts[i]->RetSelect());
+ pc->SetState(STATE_RUN, m_shortcuts[i]->IsProgram());
+ }
+ }
+ return TRUE;
+}
+
+// Selects an object through a shortcut.
+
+void CMainShort::SelectShortcut(EventMsg event)
+{
+ int i;
+
+ for ( i=0 ; i<20 ; i++ )
+ {
+ if ( event == table_sc_em[i] )
+ {
+ if ( i != 0 && m_shortcuts[i] == 0 ) continue;
+
+ if ( i == 0 ) // buildings <-> vehicles?
+ {
+ m_bBuilding = !m_bBuilding;
+ CreateShortcuts();
+ }
+ else
+ {
+ m_main->SelectObject(m_shortcuts[i]);
+ }
+ return;
+ }
+ }
+}
+
+
+// Selects the next object.
+
+void CMainShort::SelectNext()
+{
+ CObject* pPrev;
+ int i;
+
+ if ( m_main->RetMovieLock() ||
+ m_main->RetEditLock() ||
+ m_engine->RetPause() ) return;
+
+ pPrev = m_main->DeselectAll();
+
+ for ( i=1 ; i<20 ; i++ )
+ {
+ if ( m_shortcuts[i] == pPrev )
+ {
+ if ( m_shortcuts[++i] == 0 ) i = 1;
+ break;
+ }
+ }
+
+ if ( i == 20 || m_shortcuts[i] == 0 )
+ {
+ m_main->SelectHuman();
+ }
+ else
+ {
+ m_main->SelectObject(m_shortcuts[i]);
+ }
+}
+
+
+// The object detected by the mouse hovers over.
+
+CObject* CMainShort::DetectShort(FPOINT pos)
+{
+ CControl* pc;
+ FPOINT cpos, cdim;
+ int i;
+
+ for ( i=0 ; i<20 ; i++ )
+ {
+ if ( m_shortcuts[i] == 0 ) continue;
+
+ pc = m_interface->SearchControl(table_sc_em[i]);
+ if ( pc != 0 )
+ {
+ cpos = pc->RetPos();
+ cdim = pc->RetDim();
+
+ if ( pos.x >= cpos.x &&
+ pos.x <= cpos.x+cdim.x &&
+ pos.y >= cpos.y &&
+ pos.y <= cpos.y+cdim.y )
+ {
+ return m_shortcuts[i];
+ }
+ }
+ }
+ return 0;
+}
+
+// Reports the object with the mouse hovers over.
+
+void CMainShort::SetHilite(CObject* pObj)
+{
+ CControl* pc;
+ int i;
+
+ for ( i=0 ; i<20 ; i++ )
+ {
+ if ( m_shortcuts[i] == 0 ) continue;
+
+ pc = m_interface->SearchControl(table_sc_em[i]);
+ if ( pc == 0 ) continue;
+
+ if ( m_shortcuts[i] == pObj )
+ {
+ pc->SetState(STATE_HILIGHT);
+ pc->SetState(STATE_FRAME);
+ }
+ else
+ {
+ pc->ClearState(STATE_HILIGHT);
+ pc->ClearState(STATE_FRAME);
+ }
+ }
+}
+
diff --git a/src/ui/mainshort.h b/src/ui/mainshort.h
new file mode 100644
index 0000000..648dbbc
--- /dev/null
+++ b/src/ui/mainshort.h
@@ -0,0 +1,61 @@
+// * 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/.
+
+// mainshort.h
+
+#ifndef _MAINSHORT_H_
+#define _MAINSHORT_H_
+
+
+class CInstanceManager;
+class CEvent;
+class CD3DEngine;
+class CInterface;
+class CRobotMain;
+class CObject;
+
+
+
+class CMainShort
+{
+public:
+ CMainShort(CInstanceManager* iMan);
+ ~CMainShort();
+
+ void SetMode(BOOL bBuilding);
+ void FlushShortcuts();
+ BOOL CreateShortcuts();
+ BOOL UpdateShortcuts();
+ void SelectShortcut(EventMsg event);
+ void SelectNext();
+ CObject* DetectShort(FPOINT pos);
+ void SetHilite(CObject* pObj);
+
+protected:
+
+protected:
+ CInstanceManager* m_iMan;
+ CEvent* m_event;
+ CD3DEngine* m_engine;
+ CInterface* m_interface;
+ CRobotMain* m_main;
+
+ CObject* m_shortcuts[20];
+ BOOL m_bBuilding;
+};
+
+
+#endif //_MAINSHORT_H_
diff --git a/src/ui/map.cpp b/src/ui/map.cpp
new file mode 100644
index 0000000..c44a218
--- /dev/null
+++ b/src/ui/map.cpp
@@ -0,0 +1,1342 @@
+// * 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/.
+
+// map.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "event.h"
+#include "math3d.h"
+#include "terrain.h"
+#include "water.h"
+#include "object.h"
+#include "event.h"
+#include "misc.h"
+#include "robotmain.h"
+#include "iman.h"
+#include "map.h"
+
+
+
+
+// Object's constructor.
+
+CMap::CMap(CInstanceManager* iMan) : CControl(iMan)
+{
+ CControl::CControl(iMan);
+
+ m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN);
+ m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN);
+ m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER);
+
+ m_bEnable = TRUE;
+ m_time = 0.0f;
+ m_zoom = 2.0f;
+ m_offset.x = 0.0f;
+ m_offset.y = 0.0f;
+ m_angle = 0.0f;
+
+ m_floorColor.r = 1.00f;
+ m_floorColor.g = 0.50f;
+ m_floorColor.b = 0.00f; // orange
+
+ m_waterColor.r = 0.00f;
+ m_waterColor.g = 0.80f;
+ m_waterColor.b = 1.00f; // blue
+
+ m_half = m_terrain->RetMosaic()*m_terrain->RetBrick()*m_terrain->RetSize()/2.0f;
+
+ m_hiliteRank = -1;
+ FlushObject();
+
+ m_fixImage[0] = 0;
+ m_mode = 0;
+ m_bToy = FALSE;
+ m_bDebug = FALSE;
+}
+
+// Object's destructor.
+
+CMap::~CMap()
+{
+}
+
+
+// Creates a new button.
+
+BOOL CMap::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ CControl::Create(pos, dim, icon, eventMsg);
+ return TRUE;
+}
+
+
+// Choice of the offset, when image is displayed.
+
+void CMap::SetOffset(float ox, float oy)
+{
+ m_offset.x = ox;
+ m_offset.y = oy;
+ m_half = m_terrain->RetMosaic()*m_terrain->RetBrick()*m_terrain->RetSize()/2.0f;
+}
+
+// Choice of the global angle of rotation.
+
+void CMap::SetAngle(float angle)
+{
+ m_angle = angle;
+}
+
+// Specifies the alternate mode.
+
+void CMap::SetMode(int mode)
+{
+ m_mode = mode;
+}
+
+// Specifies the type of icon for the selected object.
+
+void CMap::SetToy(BOOL bToy)
+{
+ m_bToy = bToy;
+}
+
+void CMap::SetDebug(BOOL bDebug)
+{
+ m_bDebug = bDebug;
+}
+
+
+//Choice of magnification of the map.
+
+void CMap::SetZoom(float value)
+{
+ m_zoom = value;
+ m_half = m_terrain->RetMosaic()*m_terrain->RetBrick()*m_terrain->RetSize()/2.0f;
+}
+
+float CMap::RetZoom()
+{
+ return m_zoom;
+}
+
+// Choosing a fixed offset.
+
+// Enables or disables the card.
+
+void CMap::SetEnable(BOOL bEnable)
+{
+ m_bEnable = bEnable;
+ SetState(STATE_DEAD, !bEnable);
+}
+
+BOOL CMap::RetEnable()
+{
+ return m_bEnable;
+}
+
+
+// Choosing the color of the soil.
+
+void CMap::SetFloorColor(D3DCOLORVALUE color)
+{
+ m_floorColor = color;
+}
+
+// Choosing the color of the water.
+
+void CMap::SetWaterColor(D3DCOLORVALUE color)
+{
+ m_waterColor = color;
+}
+
+
+// Specifies a fixed image in place of the drawing of the relief.
+
+void CMap::SetFixImage(char *filename)
+{
+ strcpy(m_fixImage, filename);
+}
+
+// Whether to use a still image.
+
+BOOL CMap::RetFixImage()
+{
+ return (m_fixImage[0] != 0);
+}
+
+
+// Management of an event.
+
+BOOL CMap::EventProcess(const Event &event)
+{
+ BOOL bInMap;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE;
+
+ CControl::EventProcess(event);
+
+ if ( event.event == EVENT_FRAME )
+ {
+ m_time += event.rTime;
+ }
+
+ if ( event.event == EVENT_MOUSEMOVE && Detect(event.pos) )
+ {
+ m_engine->SetMouseType(D3DMOUSENORM);
+ if ( DetectObject(event.pos, bInMap) != 0 )
+ {
+ m_engine->SetMouseType(D3DMOUSEHAND);
+ }
+ }
+
+ if ( event.event == EVENT_LBUTTONDOWN )
+ {
+ if ( CControl::Detect(event.pos) )
+ {
+ SelectObject(event.pos);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+// Adjusts the offset to not exceed the card.
+
+FPOINT CMap::AdjustOffset(FPOINT offset)
+{
+ float limit;
+
+ limit = m_half - m_half/m_zoom;
+ if ( offset.x < -limit ) offset.x = -limit;
+ if ( offset.x > limit ) offset.x = limit;
+ if ( offset.y < -limit ) offset.y = -limit;
+ if ( offset.y > limit ) offset.y = limit;
+
+ return offset;
+}
+
+// Indicates the object with the mouse hovers over.
+
+void CMap::SetHilite(CObject* pObj)
+{
+ int i;
+
+ m_hiliteRank = -1;
+ if ( m_bToy || m_fixImage[0] != 0 ) return; // card with still image?
+ if ( pObj == 0 ) return;
+
+ for ( i=0 ; i<MAPMAXOBJECT ; i++ )
+ {
+ if ( !m_map[i].bUsed ) continue;
+
+ if ( m_map[i].object == pObj )
+ {
+ m_hiliteRank = i;
+ break;
+ }
+ }
+}
+
+// Detects an object in the map.
+
+CObject* CMap::DetectObject(FPOINT pos, BOOL &bInMap)
+{
+ float dist, min;
+ int i, best;
+
+ bInMap = FALSE;
+ if ( pos.x < m_pos.x ||
+ pos.y < m_pos.y ||
+ pos.x > m_pos.x+m_dim.x ||
+ pos.y > m_pos.y+m_dim.y ) return 0;
+
+ bInMap = TRUE;
+
+ pos.x = (pos.x-m_pos.x)/m_dim.x*256.0f;
+ pos.y = (pos.y-m_pos.y)/m_dim.y*256.0f; // 0..256
+ pos.x = (pos.x-128.0f)*m_half/(m_zoom*128.0f)+m_offset.x;
+ pos.y = (pos.y-128.0f)*m_half/(m_zoom*128.0f)+m_offset.y;
+
+ min = 10000.0f;
+ best = -1;
+ for ( i=MAPMAXOBJECT-1 ; i>=0 ; i-- )
+ {
+ if ( !m_map[i].bUsed ) continue;
+ if ( m_map[i].color == MAPCOLOR_BBOX && !m_bRadar ) continue;
+ if ( m_map[i].color == MAPCOLOR_ALIEN && !m_bRadar ) continue;
+
+ dist = Length(m_map[i].pos.x-pos.x, m_map[i].pos.y-pos.y);
+ if ( dist > m_half/m_zoom*8.0f/100.0f ) continue; // too far?
+ if ( dist < min )
+ {
+ min = dist;
+ best = i;
+ }
+ }
+ if ( best == -1 ) return 0;
+ return m_map[best].object;
+}
+
+// Selects an object.
+
+void CMap::SelectObject(FPOINT pos)
+{
+ CObject *pObj;
+ BOOL bInMap;
+
+ pObj = DetectObject(pos, bInMap);
+ if ( pObj != 0 )
+ {
+ m_main->SelectObject(pObj);
+ }
+}
+
+
+// Draw the map.
+
+void CMap::Draw()
+{
+ FPOINT uv1, uv2;
+ int i;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ CControl::Draw(); // draws the bottom (button)
+
+ if ( !m_bEnable ) return;
+
+ if ( m_fixImage[0] == 0 && m_map[MAPMAXOBJECT-1].bUsed )
+ {
+ m_offset = AdjustOffset(m_map[MAPMAXOBJECT-1].pos);
+ }
+
+ if ( m_fixImage[0] == 0 ) // drawing of the relief?
+ {
+ m_engine->SetTexture("map.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 0.5f+(m_offset.x-(m_half/m_zoom))/(m_half*2.0f);
+ uv1.y = 0.5f-(m_offset.y+(m_half/m_zoom))/(m_half*2.0f);
+ uv2.x = 0.5f+(m_offset.x+(m_half/m_zoom))/(m_half*2.0f);
+ uv2.y = 0.5f-(m_offset.y-(m_half/m_zoom))/(m_half*2.0f);
+ DrawVertex(uv1, uv2, 0.97f); // drawing the map
+ }
+ else // still image?
+ {
+ m_engine->LoadTexture(m_fixImage);
+ m_engine->SetTexture(m_fixImage);
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 0.0f;
+ uv1.y = 0.0f;
+ uv2.x = 1.0f;
+ uv2.y = 1.0f;
+ DrawVertex(uv1, uv2, 0.97f); // drawing the map
+ }
+
+ i = MAPMAXOBJECT-1;
+ if ( m_map[i].bUsed ) // selection:
+ {
+ DrawFocus(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color);
+ }
+
+ for ( i=0 ; i<m_totalFix ; i++ ) // fixed objects:
+ {
+ if ( i == m_hiliteRank ) continue;
+ DrawObject(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color, FALSE, FALSE);
+ }
+
+ for ( i=MAPMAXOBJECT-2 ; i>m_totalMove ; i-- ) // moving objects:
+ {
+ if ( i == m_hiliteRank ) continue;
+ DrawObject(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color, FALSE, FALSE);
+ }
+
+ i = MAPMAXOBJECT-1;
+ if ( m_map[i].bUsed && i != m_hiliteRank ) // selection:
+ {
+ DrawObject(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color, TRUE, FALSE);
+ }
+
+ if ( m_hiliteRank != -1 && m_map[m_hiliteRank].bUsed )
+ {
+ i = m_hiliteRank;
+ DrawObject(m_map[i].pos, m_map[i].dir, m_map[i].type, m_map[i].color, FALSE, TRUE);
+ DrawHilite(m_map[i].pos);
+ }
+}
+
+// Computing a point for drawFocus.
+
+FPOINT CMap::MapInter(FPOINT pos, float dir)
+{
+ FPOINT p1;
+ float limit;
+
+ p1.x = pos.x+1.0f;
+ p1.y = pos.y;
+ p1 = RotatePoint(pos, dir, p1);
+
+ p1.x -= pos.x;
+ p1.y -= pos.y;
+
+ limit = m_mapPos.x+m_mapDim.x-pos.x;
+ if ( p1.x > limit ) // exceeds the right?
+ {
+ p1.y = limit*p1.y/p1.x;
+ p1.x = limit;
+ }
+ limit = m_mapPos.y*0.75f+m_mapDim.y*0.75f-pos.y;
+ if ( p1.y > limit ) // exceeds the top?
+ {
+ p1.x = limit*p1.x/p1.y;
+ p1.y = limit;
+ }
+ limit = m_mapPos.x-pos.x;
+ if ( p1.x < limit ) // exceeds the left?
+ {
+ p1.y = limit*p1.y/p1.x;
+ p1.x = limit;
+ }
+ limit = m_mapPos.y*0.75f-pos.y;
+ if ( p1.y < limit ) // exceeds the bottom?
+ {
+ p1.x = limit*p1.x/p1.y;
+ p1.y = limit;
+ }
+
+ p1.x += pos.x;
+ p1.y += pos.y;
+ return p1;
+}
+
+// Draw the field of vision of the selected object.
+
+void CMap::DrawFocus(FPOINT pos, float dir, ObjectType type, MapColor color)
+{
+ FPOINT p0, p1, p2, uv1, uv2, rel;
+ float aMin, aMax, aOct, focus, a;
+ float limit[5];
+ BOOL bEnding;
+ int quart;
+
+ if ( m_bToy || m_fixImage[0] != 0 ) return; // map with still image?
+ if ( color != MAPCOLOR_MOVE ) return;
+
+ pos.x = (pos.x-m_offset.x)*(m_zoom*0.5f)/m_half+0.5f;
+ pos.y = (pos.y-m_offset.y)*(m_zoom*0.5f)/m_half+0.5f;
+
+ if ( pos.x < 0.0f || pos.x > 1.0f ||
+ pos.y < 0.0f || pos.y > 1.0f ) return;
+
+ rel.x = pos.x*2.0f-1.0f;
+ rel.y = pos.y*2.0f-1.0f; // rel [-1..1]
+
+ pos.x = m_mapPos.x+m_mapDim.x*pos.x;
+ pos.y = m_mapPos.y*0.75f+m_mapDim.y*pos.y*0.75f;
+
+ focus = m_engine->RetFocus();
+ dir += PI/2.0f;
+ aMin = NormAngle(dir-PI/4.0f*focus);
+ aMax = NormAngle(dir+PI/4.0f*focus);
+
+ if ( aMin > aMax )
+ {
+ aMax += PI*2.0f; // aMax always after aMin
+ }
+
+ limit[0] = RotateAngle( 1.0f-rel.x, 1.0f-rel.y); // upper/right
+ limit[1] = RotateAngle(-1.0f-rel.x, 1.0f-rel.y); // upper/left
+ limit[2] = RotateAngle(-1.0f-rel.x, -1.0f-rel.y); // lower/left
+ limit[3] = RotateAngle( 1.0f-rel.x, -1.0f-rel.y); // lower/right
+ limit[4] = limit[0]+PI*2.0f;
+
+ a = NormAngle(aMin);
+ for ( quart=0 ; quart<4 ; quart++ )
+ {
+ if ( a >= limit[quart+0] &&
+ a <= limit[quart+1] ) break;
+ }
+ if ( quart == 4 ) quart = -1;
+
+ uv1.x = 113.0f/256.0f; // degrade green
+ uv1.y = 240.5f/256.0f;
+ uv2.x = 126.0f/256.0f;
+ uv2.y = 255.0f/256.0f;
+
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTw);
+
+ bEnding = FALSE;
+ do
+ {
+ quart ++;
+ aOct = limit[quart%4];
+ if ( quart >= 4 ) aOct += PI*2.0f;
+ if ( aOct >= aMax-CHOUIA )
+ {
+ aOct = aMax;
+ bEnding = TRUE;
+ }
+
+ p0 = pos;
+ p1 = MapInter(pos, aMin);
+ p2 = MapInter(pos, aOct);
+ p0.y /= 0.75f;
+ p1.y /= 0.75f;
+ p2.y /= 0.75f;
+ DrawTriangle(p0, p2, p1, uv1, uv2);
+
+ aMin = aOct;
+ }
+ while ( !bEnding );
+}
+
+// Draw an object.
+
+void CMap::DrawObject(FPOINT pos, float dir, ObjectType type, MapColor color,
+ BOOL bSelect, BOOL bHilite)
+{
+ FPOINT p1, p2, p3, p4, p5, dim, uv1, uv2;
+ BOOL bOut, bUp, bDown, bLeft, bRight;
+
+ pos.x = (pos.x-m_offset.x)*(m_zoom*0.5f)/m_half+0.5f;
+ pos.y = (pos.y-m_offset.y)*(m_zoom*0.5f)/m_half+0.5f;
+
+ bOut = bUp = bDown = bLeft = bRight = FALSE;
+ if ( pos.x < 0.06f ) { pos.x = 0.02f; bOut = bLeft = TRUE; }
+ if ( pos.y < 0.06f ) { pos.y = 0.02f; bOut = bDown = TRUE; }
+ if ( pos.x > 0.94f ) { pos.x = 0.98f; bOut = bRight = TRUE; }
+ if ( pos.y > 0.94f ) { pos.y = 0.98f; bOut = bUp = TRUE; }
+
+ pos.x = m_mapPos.x+m_mapDim.x*pos.x;
+ pos.y = m_mapPos.y+m_mapDim.y*pos.y;
+ dim.x = 2.0f/128.0f*0.75f;
+ dim.y = 2.0f/128.0f;
+
+ if ( bOut ) // outside the map?
+ {
+ if ( color == MAPCOLOR_BBOX && !m_bRadar ) return;
+ if ( color == MAPCOLOR_ALIEN && !m_bRadar ) return;
+
+ if ( Mod(m_time+(pos.x+pos.y)*4.0f, 0.6f) > 0.2f )
+ {
+ return; // flashes
+ }
+
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ if ( bUp )
+ {
+ uv1.x = 160.5f/256.0f; // yellow triangle ^
+ uv1.y = 240.5f/256.0f;
+ uv2.x = 175.0f/256.0f;
+ uv2.y = 255.0f/256.0f;
+ }
+ if ( bDown )
+ {
+ uv1.x = 160.5f/256.0f; // yellow triangle v
+ uv1.y = 255.0f/256.0f;
+ uv2.x = 175.0f/256.0f;
+ uv2.y = 240.5f/256.0f;
+ }
+ if ( bRight )
+ {
+ uv1.x = 176.5f/256.0f; // yellow triangle >
+ uv1.y = 240.5f/256.0f;
+ uv2.x = 191.0f/256.0f;
+ uv2.y = 255.0f/256.0f;
+ }
+ if ( bLeft )
+ {
+ uv1.x = 191.0f/256.0f; // yellow triangle <
+ uv1.y = 240.5f/256.0f;
+ uv2.x = 176.5f/256.0f;
+ uv2.y = 255.0f/256.0f;
+ }
+ pos.x -= dim.x/2.0f;
+ pos.y -= dim.y/2.0f;
+ DrawIcon(pos, dim, uv1, uv2);
+ return;
+ }
+
+ if ( bSelect )
+ {
+ if ( m_bToy )
+ {
+ dim.x *= 1.2f+sinf(m_time*8.0f)*0.1f;
+ dim.y *= 1.2f+sinf(m_time*8.0f)*0.1f;
+ }
+ else
+ {
+ dim.x *= 1.2f+sinf(m_time*8.0f)*0.3f;
+ dim.y *= 1.2f+sinf(m_time*8.0f)*0.3f;
+ }
+ }
+ if ( color == MAPCOLOR_BASE ||
+ color == MAPCOLOR_FIX ||
+ color == MAPCOLOR_MOVE )
+ {
+ if ( bHilite )
+ {
+ dim.x *= 2.2f;
+ dim.y *= 2.2f;
+ }
+ else
+ {
+ dim.x *= 0.6f;
+ dim.y *= 0.6f;
+ }
+ }
+ if ( color == MAPCOLOR_ALIEN )
+ {
+ dim.x *= 1.4f;
+ dim.y *= 1.4f;
+ }
+ if ( type == OBJECT_TEEN28 ) // bottle?
+ {
+ dim.x *= 3.0f;
+ dim.y *= 3.0f;
+ bHilite = TRUE;
+ }
+ if ( type == OBJECT_TEEN34 ) // stone?
+ {
+ dim.x *= 2.0f;
+ dim.y *= 2.0f;
+ bHilite = TRUE;
+ }
+
+ if ( color == MAPCOLOR_MOVE && bSelect )
+ {
+ if ( m_bToy )
+ {
+ p1.x = pos.x;
+ p1.y = pos.y+dim.y*1.4f;
+ p1 = RotatePoint(pos, dir, p1);
+ p1.x = pos.x+(p1.x-pos.x)*0.75f;
+
+ p2.x = pos.x+dim.x*1.2f;
+ p2.y = pos.y+dim.y*0.8f;
+ p2 = RotatePoint(pos, dir, p2);
+ p2.x = pos.x+(p2.x-pos.x)*0.75f;
+
+ p3.x = pos.x+dim.x*1.2f;
+ p3.y = pos.y-dim.y*1.0f;
+ p3 = RotatePoint(pos, dir, p3);
+ p3.x = pos.x+(p3.x-pos.x)*0.75f;
+
+ p4.x = pos.x-dim.x*1.2f;
+ p4.y = pos.y-dim.y*1.0f;
+ p4 = RotatePoint(pos, dir, p4);
+ p4.x = pos.x+(p4.x-pos.x)*0.75f;
+
+ p5.x = pos.x-dim.x*1.2f;
+ p5.y = pos.y+dim.y*0.8f;
+ p5 = RotatePoint(pos, dir, p5);
+ p5.x = pos.x+(p5.x-pos.x)*0.75f;
+ }
+ else
+ {
+ p1.x = pos.x;
+ p1.y = pos.y+dim.y*2.4f;
+ p1 = RotatePoint(pos, dir, p1);
+ p1.x = pos.x+(p1.x-pos.x)*0.75f;
+
+ p2.x = pos.x+dim.x*1.0f;
+ p2.y = pos.y-dim.y*1.6f;
+ p2 = RotatePoint(pos, dir, p2);
+ p2.x = pos.x+(p2.x-pos.x)*0.75f;
+
+ p3.x = pos.x-dim.x*1.0f;
+ p3.y = pos.y-dim.y*1.6f;
+ p3 = RotatePoint(pos, dir, p3);
+ p3.x = pos.x+(p3.x-pos.x)*0.75f;
+ }
+ }
+
+ pos.x -= dim.x/2.0f;
+ pos.y -= dim.y/2.0f;
+
+ if ( color == MAPCOLOR_BASE ||
+ color == MAPCOLOR_FIX )
+ {
+ DrawObjectIcon(pos, dim, color, type, bHilite);
+ }
+
+ if ( color == MAPCOLOR_MOVE )
+ {
+ if ( bSelect )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ if ( m_bToy )
+ {
+ uv1.x = 164.5f/256.0f; // black pentagon
+ uv1.y = 228.5f/256.0f;
+ uv2.x = 172.0f/256.0f;
+ uv2.y = 236.0f/256.0f;
+ DrawPenta(p1, p2, p3, p4, p5, uv1, uv2);
+ }
+ else
+ {
+ uv1.x = 144.5f/256.0f; // red triangle
+ uv1.y = 240.5f/256.0f;
+ uv2.x = 159.0f/256.0f;
+ uv2.y = 255.0f/256.0f;
+ DrawTriangle(p1, p2, p3, uv1, uv2);
+ }
+ }
+ DrawObjectIcon(pos, dim, color, type, bHilite);
+ }
+
+ if ( color == MAPCOLOR_BBOX )
+ {
+ if ( m_bRadar )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTw);
+ uv1.x = 64.5f/256.0f; // blue triangle
+ uv1.y = 240.5f/256.0f;
+ uv2.x = 79.0f/256.0f;
+ uv2.y = 255.0f/256.0f;
+ DrawIcon(pos, dim, uv1, uv2);
+ }
+ }
+
+ if ( color == MAPCOLOR_ALIEN )
+ {
+ if ( m_bRadar )
+ {
+ DrawObjectIcon(pos, dim, color, type, TRUE);
+ }
+ }
+
+ if ( color == MAPCOLOR_WAYPOINTb )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 192.5f/256.0f; // blue cross
+ uv1.y = 240.5f/256.0f;
+ uv2.x = 207.0f/256.0f;
+ uv2.y = 255.0f/256.0f;
+ DrawIcon(pos, dim, uv1, uv2);
+ }
+ if ( color == MAPCOLOR_WAYPOINTr )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 208.5f/256.0f; // red cross
+ uv1.y = 240.5f/256.0f;
+ uv2.x = 223.0f/256.0f;
+ uv2.y = 255.0f/256.0f;
+ DrawIcon(pos, dim, uv1, uv2);
+ }
+ if ( color == MAPCOLOR_WAYPOINTg )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 224.5f/256.0f; // green cross
+ uv1.y = 240.5f/256.0f;
+ uv2.x = 239.0f/256.0f;
+ uv2.y = 255.0f/256.0f;
+ DrawIcon(pos, dim, uv1, uv2);
+ }
+ if ( color == MAPCOLOR_WAYPOINTy )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 240.5f/256.0f; // yellow cross
+ uv1.y = 240.5f/256.0f;
+ uv2.x = 255.0f/256.0f;
+ uv2.y = 255.0f/256.0f;
+ DrawIcon(pos, dim, uv1, uv2);
+ }
+ if ( color == MAPCOLOR_WAYPOINTv )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 192.5f/256.0f; // violet cross
+ uv1.y = 224.5f/256.0f;
+ uv2.x = 207.0f/256.0f;
+ uv2.y = 239.0f/256.0f;
+ DrawIcon(pos, dim, uv1, uv2);
+ }
+}
+
+// Draws the icon of an object.
+
+void CMap::DrawObjectIcon(FPOINT pos, FPOINT dim, MapColor color,
+ ObjectType type, BOOL bHilite)
+{
+ FPOINT ppos, ddim, uv1, uv2;
+ float dp;
+ int icon;
+
+ dp = 0.5f/256.0f;
+
+ m_engine->SetTexture("button3.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ if ( color == MAPCOLOR_MOVE )
+ {
+ uv1.x = 160.0f/256.0f; // blue
+ uv1.y = 224.0f/256.0f;
+ }
+ else if ( color == MAPCOLOR_ALIEN )
+ {
+ uv1.x = 224.0f/256.0f; // green
+ uv1.y = 224.0f/256.0f;
+ }
+ else
+ {
+ uv1.x = 192.0f/256.0f; // yellow
+ uv1.y = 224.0f/256.0f;
+ }
+ uv2.x = uv1.x+32.0f/256.0f;
+ uv2.y = uv1.y+32.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2); // background colors
+
+ if ( bHilite )
+ {
+ icon = -1;
+ if ( type == OBJECT_FACTORY ) icon = 32;
+ if ( type == OBJECT_DERRICK ) icon = 33;
+ if ( type == OBJECT_CONVERT ) icon = 34;
+ if ( type == OBJECT_RESEARCH ) icon = 35;
+ if ( type == OBJECT_STATION ) icon = 36;
+ if ( type == OBJECT_TOWER ) icon = 37;
+ if ( type == OBJECT_LABO ) icon = 38;
+ if ( type == OBJECT_ENERGY ) icon = 39;
+ if ( type == OBJECT_RADAR ) icon = 40;
+ if ( type == OBJECT_INFO ) icon = 44;
+ if ( type == OBJECT_REPAIR ) icon = 41;
+ if ( type == OBJECT_DESTROYER) icon = 41;
+ if ( type == OBJECT_NUCLEAR ) icon = 42;
+ if ( type == OBJECT_PARA ) icon = 46;
+ if ( type == OBJECT_SAFE ) icon = 47;
+ if ( type == OBJECT_HUSTON ) icon = 48;
+ if ( type == OBJECT_TARGET1 ) icon = 45;
+ if ( type == OBJECT_BASE ) icon = 43;
+ if ( type == OBJECT_HUMAN ) icon = 8;
+ if ( type == OBJECT_MOBILEfa ) icon = 11;
+ if ( type == OBJECT_MOBILEta ) icon = 10;
+ if ( type == OBJECT_MOBILEwa ) icon = 9;
+ if ( type == OBJECT_MOBILEia ) icon = 22;
+ if ( type == OBJECT_MOBILEfc ) icon = 17;
+ if ( type == OBJECT_MOBILEtc ) icon = 16;
+ if ( type == OBJECT_MOBILEwc ) icon = 15;
+ if ( type == OBJECT_MOBILEic ) icon = 23;
+ if ( type == OBJECT_MOBILEfi ) icon = 27;
+ if ( type == OBJECT_MOBILEti ) icon = 26;
+ if ( type == OBJECT_MOBILEwi ) icon = 25;
+ if ( type == OBJECT_MOBILEii ) icon = 28;
+ if ( type == OBJECT_MOBILEfs ) icon = 14;
+ if ( type == OBJECT_MOBILEts ) icon = 13;
+ if ( type == OBJECT_MOBILEws ) icon = 12;
+ if ( type == OBJECT_MOBILEis ) icon = 24;
+ if ( type == OBJECT_MOBILErt ) icon = 18;
+ if ( type == OBJECT_MOBILErc ) icon = 19;
+ if ( type == OBJECT_MOBILErr ) icon = 20;
+ if ( type == OBJECT_MOBILErs ) icon = 29;
+ if ( type == OBJECT_MOBILEsa ) icon = 21;
+ if ( type == OBJECT_MOBILEft ) icon = 30;
+ if ( type == OBJECT_MOBILEtt ) icon = 30;
+ if ( type == OBJECT_MOBILEwt ) icon = 30;
+ if ( type == OBJECT_MOBILEit ) icon = 30;
+ if ( type == OBJECT_MOBILEtg ) icon = 45;
+ if ( type == OBJECT_MOBILEdr ) icon = 48;
+ if ( type == OBJECT_APOLLO2 ) icon = 49;
+ if ( type == OBJECT_MOTHER ) icon = 31;
+ if ( type == OBJECT_ANT ) icon = 31;
+ if ( type == OBJECT_SPIDER ) icon = 31;
+ if ( type == OBJECT_BEE ) icon = 31;
+ if ( type == OBJECT_WORM ) icon = 31;
+ if ( type == OBJECT_TEEN28 ) icon = 48; // bottle
+ if ( type == OBJECT_TEEN34 ) icon = 48; // stone
+ if ( icon == -1 ) return;
+
+ m_engine->SetState(D3DSTATETTw);
+ uv1.x = (32.0f/256.0f)*(icon%8);
+ uv1.y = (32.0f/256.0f)*(icon/8);
+ uv2.x = uv1.x+32.0f/256.0f;
+ uv2.y = uv1.y+32.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2); // icon
+ }
+}
+
+// Draw the object with the mouse hovers over.
+
+void CMap::DrawHilite(FPOINT pos)
+{
+ FPOINT dim, uv1, uv2;
+ BOOL bOut, bUp, bDown, bLeft, bRight;
+
+ if ( m_bToy || m_fixImage[0] != 0 ) return; // map with still image?
+
+ pos.x = (pos.x-m_offset.x)*(m_zoom*0.5f)/m_half+0.5f;
+ pos.y = (pos.y-m_offset.y)*(m_zoom*0.5f)/m_half+0.5f;
+
+ bOut = bUp = bDown = bLeft = bRight = FALSE;
+ if ( pos.x < 0.06f ) { pos.x = 0.02f; bOut = bLeft = TRUE; }
+ if ( pos.y < 0.06f ) { pos.y = 0.02f; bOut = bDown = TRUE; }
+ if ( pos.x > 0.94f ) { pos.x = 0.98f; bOut = bRight = TRUE; }
+ if ( pos.y > 0.94f ) { pos.y = 0.98f; bOut = bUp = TRUE; }
+
+ pos.x = m_mapPos.x+m_mapDim.x*pos.x;
+ pos.y = m_mapPos.y+m_mapDim.y*pos.y;
+ dim.x = 2.0f/128.0f*0.75f;
+ dim.y = 2.0f/128.0f;
+ dim.x *= 2.0f+cosf(m_time*8.0f)*0.5f;
+ dim.y *= 2.0f+cosf(m_time*8.0f)*0.5f;
+
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 160.5f/256.0f; // hilite
+ uv1.y = 224.5f/256.0f;
+ uv2.x = 175.0f/256.0f;
+ uv2.y = 239.0f/256.0f;
+ pos.x -= dim.x/2.0f;
+ pos.y -= dim.y/2.0f;
+ DrawIcon(pos, dim, uv1, uv2);
+}
+
+// Draws a triangular icon.
+
+void CMap::DrawTriangle(FPOINT p1, FPOINT p2, FPOINT p3, FPOINT uv1, FPOINT uv2)
+{
+ LPDIRECT3DDEVICE7 device;
+ D3DVERTEX2 vertex[3]; // 1 triangle
+ D3DVECTOR n;
+
+ device = m_engine->RetD3DDevice();
+
+ n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal
+
+ vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv1.y);
+ vertex[1] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv1.x,uv2.y);
+ vertex[2] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv2.x,uv2.y);
+
+ device->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_VERTEX2, vertex, 3, NULL);
+ m_engine->AddStatisticTriangle(1);
+}
+
+// Draw a pentagon icon (a 5 rating, what!).
+
+void CMap::DrawPenta(FPOINT p1, FPOINT p2, FPOINT p3, FPOINT p4, FPOINT p5, FPOINT uv1, FPOINT uv2)
+{
+ LPDIRECT3DDEVICE7 device;
+ D3DVERTEX2 vertex[5]; // 1 pentagon
+ D3DVECTOR n;
+
+ device = m_engine->RetD3DDevice();
+
+ n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal
+
+#if 1
+ vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv1.y);
+ vertex[1] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv1.x,uv2.y);
+ vertex[2] = D3DVERTEX2(D3DVECTOR(p5.x, p5.y, 0.0f), n, uv2.x,uv2.y);
+ vertex[3] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv2.x,uv2.y);
+ vertex[4] = D3DVERTEX2(D3DVECTOR(p4.x, p4.y, 0.0f), n, uv2.x,uv2.y);
+
+ device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 5, NULL);
+#else
+ vertex[0] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv1.x,uv1.y);
+ vertex[1] = D3DVERTEX2(D3DVECTOR(p3.x, p3.y, 0.0f), n, uv1.x,uv2.y);
+ vertex[2] = D3DVERTEX2(D3DVECTOR(p4.x, p4.y, 0.0f), n, uv2.x,uv2.y);
+
+ device->DrawPrimitive(D3DPT_TRIANGLELIST, D3DFVF_VERTEX2, vertex, 3, NULL);
+#endif
+ m_engine->AddStatisticTriangle(3);
+}
+
+// Draw the vertex array.
+
+void CMap::DrawVertex(FPOINT uv1, FPOINT uv2, float zoom)
+{
+ LPDIRECT3DDEVICE7 device;
+ D3DVERTEX2 vertex[4]; // 2 triangles
+ FPOINT p1, p2, c;
+ D3DVECTOR n;
+
+ device = m_engine->RetD3DDevice();
+
+ 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;
+
+ 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;
+
+ m_mapPos = p1;
+ m_mapDim.x = p2.x-p1.x;
+ m_mapDim.y = p2.y-p1.y;
+
+ n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal
+
+ vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, uv1.x,uv2.y);
+ vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, uv1.x,uv1.y);
+ vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, uv2.x,uv2.y);
+ vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, uv2.x,uv1.y);
+
+ device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL);
+ m_engine->AddStatisticTriangle(2);
+}
+
+
+// Updates the field in the map.
+
+void CMap::UpdateTerrain()
+{
+ D3DCOLORVALUE color;
+ D3DVECTOR pos;
+ float scale, water, level, intensity;
+ int x, y;
+
+ if ( m_fixImage[0] != 0 ) return; // still image?
+ if ( !m_engine->OpenImage("map.tga") ) return;
+
+ scale = m_terrain->RetScaleRelief();
+ water = m_water->RetLevel();
+ color.a = 0.0f;
+
+ for ( y=0 ; y<256 ; y++ )
+ {
+ for ( x=0 ; x<256 ; x++ )
+ {
+ pos.x = ((float)x-128.0f)*m_half/128.0f;
+ pos.z = -((float)y-128.0f)*m_half/128.0f;
+ pos.y = 0.0f;
+
+ if ( pos.x >= -m_half && pos.x <= m_half &&
+ pos.z >= -m_half && pos.z <= m_half )
+ {
+ level = m_terrain->RetFloorLevel(pos, TRUE)/scale;
+ }
+ else
+ {
+ level = 1000.0f;
+ }
+
+ intensity = level/256.0f;
+ if ( intensity < 0.0f ) intensity = 0.0f;
+ if ( intensity > 1.0f ) intensity = 1.0f;
+
+ if ( level >= water ) // on water?
+ {
+ color.r = m_floorColor.r + (intensity-0.5f);
+ color.g = m_floorColor.g + (intensity-0.5f);
+ color.b = m_floorColor.b + (intensity-0.5f);
+ }
+ else // underwater?
+ {
+ color.r = m_waterColor.r + (intensity-0.5f);
+ color.g = m_waterColor.g + (intensity-0.5f);
+ color.b = m_waterColor.b + (intensity-0.5f);
+ }
+
+ m_engine->SetDot(x, y, color);
+ }
+ }
+
+ m_engine->CopyImage(); // copy the ground drawing
+ m_engine->CloseImage();
+}
+
+// Updates the field in the map.
+
+void CMap::UpdateTerrain(int bx, int by, int ex, int ey)
+{
+ D3DCOLORVALUE color;
+ D3DVECTOR pos;
+ float scale, water, level, intensity;
+ int x, y;
+
+ if ( m_fixImage[0] != 0 ) return; // still image?
+ if ( !m_engine->OpenImage("map.tga") ) return;
+ m_engine->LoadImage();
+
+ scale = m_terrain->RetScaleRelief();
+ water = m_water->RetLevel();
+ color.a = 0.0f;
+
+ for ( y=by ; y<ey ; y++ )
+ {
+ for ( x=bx ; x<ex ; x++ )
+ {
+ pos.x = ((float)x-128.0f)*m_half/128.0f;
+ pos.z = -((float)y-128.0f)*m_half/128.0f;
+ pos.y = 0.0f;
+
+ if ( pos.x >= -m_half && pos.x <= m_half &&
+ pos.z >= -m_half && pos.z <= m_half )
+ {
+ level = m_terrain->RetFloorLevel(pos, TRUE)/scale;
+ }
+ else
+ {
+ level = 1000.0f;
+ }
+
+ intensity = level/256.0f;
+ if ( intensity < 0.0f ) intensity = 0.0f;
+ if ( intensity > 1.0f ) intensity = 1.0f;
+
+ if ( level > water ) // on water?
+ {
+ color.r = m_floorColor.r + (intensity-0.5f);
+ color.g = m_floorColor.g + (intensity-0.5f);
+ color.b = m_floorColor.b + (intensity-0.5f);
+ }
+ else // underwater?
+ {
+ color.r = m_waterColor.r + (intensity-0.5f);
+ color.g = m_waterColor.g + (intensity-0.5f);
+ color.b = m_waterColor.b + (intensity-0.5f);
+ }
+
+ m_engine->SetDot(x, y, color);
+ }
+ }
+
+ m_engine->CopyImage(); // copy the ground drawing
+ m_engine->CloseImage();
+}
+
+
+// Empty all objects.
+
+void CMap::FlushObject()
+{
+ int i;
+
+ m_totalFix = 0; // object index fixed
+ m_totalMove = MAPMAXOBJECT-2; // moving vehicles index
+ m_bRadar = m_main->RetCheatRadar(); // no radar
+
+ for ( i=0 ; i<MAPMAXOBJECT ; i++ )
+ {
+ m_map[i].bUsed = FALSE;
+ }
+}
+
+// Updates an object in the map.
+
+void CMap::UpdateObject(CObject* pObj)
+{
+ ObjectType type;
+ MapColor color;
+ D3DVECTOR pos;
+ FPOINT ppos;
+ float dir;
+
+ if ( !m_bEnable ) return;
+ if ( m_totalFix >= m_totalMove ) return; // full table?
+
+ if ( !pObj->RetActif() ) return;
+ if ( !pObj->RetSelectable() ) return;
+ if ( pObj->RetProxyActivate() ) return;
+ if ( pObj->RetTruck() != 0 ) return;
+
+ type = pObj->RetType();
+ pos = pObj->RetPosition(0);
+ dir = -(pObj->RetAngleY(0)+PI/2.0f);
+
+ if ( m_angle != 0.0f )
+ {
+ ppos = RotatePoint(m_angle, FPOINT(pos.x, pos.z));
+ pos.x = ppos.x;
+ pos.z = ppos.y;
+ dir += m_angle;
+ }
+
+ if ( type == OBJECT_RADAR )
+ {
+ m_bRadar = TRUE; // radar exists
+ }
+
+ color = MAPCOLOR_NULL;
+ if ( type == OBJECT_BASE )
+ {
+ color = MAPCOLOR_BASE;
+ }
+ if ( type == OBJECT_DERRICK ||
+ type == OBJECT_FACTORY ||
+ type == OBJECT_STATION ||
+ type == OBJECT_CONVERT ||
+ type == OBJECT_REPAIR ||
+ type == OBJECT_DESTROYER||
+ type == OBJECT_TOWER ||
+ type == OBJECT_RESEARCH ||
+ type == OBJECT_RADAR ||
+ type == OBJECT_INFO ||
+ type == OBJECT_ENERGY ||
+ type == OBJECT_LABO ||
+ type == OBJECT_NUCLEAR ||
+ type == OBJECT_PARA ||
+ type == OBJECT_SAFE ||
+ type == OBJECT_HUSTON ||
+ type == OBJECT_TARGET1 ||
+ type == OBJECT_START ||
+ type == OBJECT_END || // stationary object?
+ type == OBJECT_TEEN28 || // bottle?
+ type == OBJECT_TEEN34 ) // stone?
+ {
+ color = MAPCOLOR_FIX;
+ }
+ if ( type == OBJECT_BBOX ||
+ type == OBJECT_KEYa ||
+ type == OBJECT_KEYb ||
+ type == OBJECT_KEYc ||
+ type == OBJECT_KEYd )
+ {
+ color = MAPCOLOR_BBOX;
+ }
+ if ( type == OBJECT_HUMAN ||
+ type == OBJECT_MOBILEwa ||
+ type == OBJECT_MOBILEta ||
+ type == OBJECT_MOBILEfa ||
+ type == OBJECT_MOBILEia ||
+ type == OBJECT_MOBILEwc ||
+ type == OBJECT_MOBILEtc ||
+ type == OBJECT_MOBILEfc ||
+ type == OBJECT_MOBILEic ||
+ type == OBJECT_MOBILEwi ||
+ type == OBJECT_MOBILEti ||
+ type == OBJECT_MOBILEfi ||
+ type == OBJECT_MOBILEii ||
+ type == OBJECT_MOBILEws ||
+ type == OBJECT_MOBILEts ||
+ type == OBJECT_MOBILEfs ||
+ type == OBJECT_MOBILEis ||
+ type == OBJECT_MOBILErt ||
+ type == OBJECT_MOBILErc ||
+ type == OBJECT_MOBILErr ||
+ type == OBJECT_MOBILErs ||
+ type == OBJECT_MOBILEsa ||
+ type == OBJECT_MOBILEtg ||
+ type == OBJECT_MOBILEwt ||
+ type == OBJECT_MOBILEtt ||
+ type == OBJECT_MOBILEft ||
+ type == OBJECT_MOBILEit ||
+ type == OBJECT_MOBILEdr ||
+ type == OBJECT_APOLLO2 ) // moving vehicle?
+ {
+ color = MAPCOLOR_MOVE;
+ }
+ if ( type == OBJECT_ANT ||
+ type == OBJECT_BEE ||
+ type == OBJECT_WORM ||
+ type == OBJECT_SPIDER ) // mobile enemy?
+ {
+ color = MAPCOLOR_ALIEN;
+ }
+ if ( type == OBJECT_WAYPOINT ||
+ type == OBJECT_FLAGb )
+ {
+ color = MAPCOLOR_WAYPOINTb;
+ }
+ if ( type == OBJECT_FLAGr )
+ {
+ color = MAPCOLOR_WAYPOINTr;
+ }
+ if ( type == OBJECT_FLAGg )
+ {
+ color = MAPCOLOR_WAYPOINTg;
+ }
+ if ( type == OBJECT_FLAGy )
+ {
+ color = MAPCOLOR_WAYPOINTy;
+ }
+ if ( type == OBJECT_FLAGv )
+ {
+ color = MAPCOLOR_WAYPOINTv;
+ }
+
+ if ( color == MAPCOLOR_NULL ) return;
+
+ if ( m_fixImage[0] != 0 && !m_bDebug ) // map with still image?
+ {
+ if ( (type == OBJECT_TEEN28 ||
+ type == OBJECT_TEEN34 ) &&
+ m_mode == 0 ) return;
+
+ if ( type != OBJECT_TEEN28 &&
+ type != OBJECT_TEEN34 &&
+ color != MAPCOLOR_MOVE ) return;
+ }
+
+ if ( pObj->RetSelect() )
+ {
+ m_map[MAPMAXOBJECT-1].type = type;
+ m_map[MAPMAXOBJECT-1].object = pObj;
+ m_map[MAPMAXOBJECT-1].color = color;
+ m_map[MAPMAXOBJECT-1].pos.x = pos.x;
+ m_map[MAPMAXOBJECT-1].pos.y = pos.z;
+ m_map[MAPMAXOBJECT-1].dir = dir;
+ m_map[MAPMAXOBJECT-1].bUsed = TRUE;
+ }
+ else
+ {
+ if ( color == MAPCOLOR_BASE ||
+ color == MAPCOLOR_FIX )
+ {
+ m_map[m_totalFix].type = type;
+ m_map[m_totalFix].object = pObj;
+ m_map[m_totalFix].color = color;
+ m_map[m_totalFix].pos.x = pos.x;
+ m_map[m_totalFix].pos.y = pos.z;
+ m_map[m_totalFix].dir = dir;
+ m_map[m_totalFix].bUsed = TRUE;
+ m_totalFix ++;
+ }
+ else
+ {
+ m_map[m_totalMove].type = type;
+ m_map[m_totalMove].object = pObj;
+ m_map[m_totalMove].color = color;
+ m_map[m_totalMove].pos.x = pos.x;
+ m_map[m_totalMove].pos.y = pos.z;
+ m_map[m_totalMove].dir = dir;
+ m_map[m_totalMove].bUsed = TRUE;
+ m_totalMove --;
+ }
+ }
+}
+
diff --git a/src/ui/map.h b/src/ui/map.h
new file mode 100644
index 0000000..4b1f793
--- /dev/null
+++ b/src/ui/map.h
@@ -0,0 +1,141 @@
+// * 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/.
+
+// map.h
+
+#ifndef _MAP_H_
+#define _MAP_H_
+
+
+#include "control.h"
+#include "struct.h"
+#include "object.h"
+
+
+class CD3DEngine;
+class CTerrain;
+class CWater;
+class CRobotMain;
+
+
+
+#define MAPMAXOBJECT 100
+
+enum MapColor
+{
+ MAPCOLOR_NULL,
+ MAPCOLOR_BASE,
+ MAPCOLOR_FIX,
+ MAPCOLOR_MOVE,
+ MAPCOLOR_ALIEN,
+ MAPCOLOR_WAYPOINTb,
+ MAPCOLOR_WAYPOINTr,
+ MAPCOLOR_WAYPOINTg,
+ MAPCOLOR_WAYPOINTy,
+ MAPCOLOR_WAYPOINTv,
+ MAPCOLOR_BBOX,
+};
+
+typedef struct
+{
+ char bUsed;
+ CObject* object;
+ MapColor color;
+ ObjectType type;
+ FPOINT pos;
+ float dir;
+}
+MapObject;
+
+
+
+class CMap : public CControl
+{
+public:
+ CMap(CInstanceManager* iMan);
+ ~CMap();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ BOOL EventProcess(const Event &event);
+ void Draw();
+
+ void UpdateTerrain();
+ void UpdateTerrain(int bx, int by, int ex, int ey);
+
+ void SetFixImage(char *filename);
+ BOOL RetFixImage();
+
+ void SetOffset(float ox, float oy);
+ void SetAngle(float angle);
+ void SetMode(int mode);
+ void SetToy(BOOL bToy);
+ void SetDebug(BOOL bDebug);
+
+ void SetZoom(float value);
+ float RetZoom();
+
+ void SetEnable(BOOL bEnable);
+ BOOL RetEnable();
+
+ void SetFloorColor(D3DCOLORVALUE color);
+ void SetWaterColor(D3DCOLORVALUE color);
+
+ void FlushObject();
+ void UpdateObject(CObject* pObj);
+
+ CObject* DetectObject(FPOINT pos, BOOL &bInMap);
+ void SetHilite(CObject* pObj);
+
+protected:
+ FPOINT AdjustOffset(FPOINT offset);
+ void SelectObject(FPOINT pos);
+ FPOINT MapInter(FPOINT pos, float dir);
+ void DrawFocus(FPOINT pos, float dir, ObjectType type, MapColor color);
+ void DrawObject(FPOINT pos, float dir, ObjectType type, MapColor color, BOOL bSelect, BOOL bHilite);
+ void DrawObjectIcon(FPOINT pos, FPOINT dim, MapColor color, ObjectType type, BOOL bHilite);
+ void DrawHilite(FPOINT pos);
+ void DrawTriangle(FPOINT p1, FPOINT p2, FPOINT p3, FPOINT uv1, FPOINT uv2);
+ void DrawPenta(FPOINT p1, FPOINT p2, FPOINT p3, FPOINT p4, FPOINT p5, FPOINT uv1, FPOINT uv2);
+ void DrawVertex(FPOINT uv1, FPOINT uv2, float zoom);
+
+protected:
+ CTerrain* m_terrain;
+ CWater* m_water;
+ CRobotMain* m_main;
+
+ BOOL m_bEnable;
+ float m_time;
+ float m_half;
+ float m_zoom;
+ FPOINT m_offset;
+ float m_angle;
+ D3DCOLORVALUE m_floorColor;
+ D3DCOLORVALUE m_waterColor;
+ MapObject m_map[MAPMAXOBJECT];
+ int m_totalFix;
+ int m_totalMove;
+ int m_hiliteRank;
+ FPOINT m_mapPos;
+ FPOINT m_mapDim;
+ BOOL m_bRadar;
+ char m_fixImage[100];
+ int m_mode;
+ BOOL m_bToy;
+ BOOL m_bDebug;
+};
+
+
+#endif //_MAP_H_
diff --git a/src/ui/scroll.cpp b/src/ui/scroll.cpp
new file mode 100644
index 0000000..1122ac5
--- /dev/null
+++ b/src/ui/scroll.cpp
@@ -0,0 +1,471 @@
+// * 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/.
+
+// scroll.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "button.h"
+#include "scroll.h"
+
+
+
+
+// Object's constructor.
+
+CScroll::CScroll(CInstanceManager* iMan) : CControl(iMan)
+{
+ m_buttonUp = 0;
+ m_buttonDown = 0;
+
+ m_visibleValue = 0.0f;
+ m_visibleRatio = 1.0f;
+ m_step = 0.0f;
+
+ m_eventUp = EVENT_NULL;
+ m_eventDown = EVENT_NULL;
+
+ m_bCapture = FALSE;
+}
+
+// Object's destructor.
+
+CScroll::~CScroll()
+{
+ delete m_buttonUp;
+ delete m_buttonDown;
+}
+
+
+// Creates a new button.
+
+BOOL CScroll::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+ CControl::Create(pos, dim, icon, eventMsg);
+
+ MoveAdjust();
+ return TRUE;
+}
+
+
+void CScroll::SetPos(FPOINT pos)
+{
+ CControl::SetPos(pos);
+ MoveAdjust();
+}
+
+void CScroll::SetDim(FPOINT dim)
+{
+ CControl::SetDim(dim);
+ MoveAdjust();
+}
+
+// Adjust both buttons.
+
+void CScroll::MoveAdjust()
+{
+ CButton* pc;
+ FPOINT pos, dim;
+
+ if ( m_dim.y < m_dim.x*2.0f ) // very short lift?
+ {
+ delete m_buttonUp;
+ m_buttonUp = 0;
+
+ delete m_buttonDown;
+ m_buttonDown = 0;
+ }
+ else
+ {
+ if ( m_buttonUp == 0 )
+ {
+ m_buttonUp = new CButton(m_iMan);
+ pc = (CButton*)m_buttonUp;
+ pc->Create(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), 49, EVENT_NULL);
+ pc->SetRepeat(TRUE);
+ m_eventUp = pc->RetEventMsg();
+ }
+
+ if ( m_buttonDown == 0 )
+ {
+ m_buttonDown = new CButton(m_iMan);
+ pc = (CButton*)m_buttonDown;
+ pc->Create(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), 50, EVENT_NULL);
+ pc->SetRepeat(TRUE);
+ m_eventDown = pc->RetEventMsg();
+ }
+ }
+
+ if ( m_buttonUp != 0 )
+ {
+ pos.x = m_pos.x;
+ pos.y = m_pos.y+m_dim.y-m_dim.x/0.75f;
+ dim.x = m_dim.x;
+ dim.y = m_dim.x/0.75f;
+ m_buttonUp->SetPos(pos);
+ m_buttonUp->SetDim(dim);
+ }
+
+ if ( m_buttonDown != 0 )
+ {
+ pos.x = m_pos.x;
+ pos.y = m_pos.y;
+ dim.x = m_dim.x;
+ dim.y = m_dim.x/0.75f;
+ m_buttonDown->SetPos(pos);
+ m_buttonDown->SetDim(dim);
+ }
+
+ AdjustGlint();
+}
+
+// Adjusts the position of reflection.
+
+void CScroll::AdjustGlint()
+{
+ FPOINT ref;
+ float hButton, h;
+
+ hButton = m_buttonUp?m_dim.x/0.75f:0.0f;
+ h = m_dim.y-hButton*2.0f;
+
+ ref.x = m_pos.x;
+ ref.y = m_pos.y+hButton+h*m_visibleRatio+0.003f;
+ ref.y += h*(1.0f-m_visibleRatio)*(1.0f-m_visibleValue);
+
+ GlintCreate(ref);
+}
+
+
+
+BOOL CScroll::SetState(int state, BOOL bState)
+{
+ if ( state & STATE_ENABLE )
+ {
+ if ( m_buttonUp != 0 ) m_buttonUp->SetState(state, bState);
+ if ( m_buttonDown != 0 ) m_buttonDown->SetState(state, bState);
+ }
+
+ return CControl::SetState(state, bState);
+}
+
+BOOL CScroll::SetState(int state)
+{
+ if ( state & STATE_ENABLE )
+ {
+ if ( m_buttonUp != 0 ) m_buttonUp->SetState(state);
+ if ( m_buttonDown != 0 ) m_buttonDown->SetState(state);
+ }
+
+ return CControl::SetState(state);
+}
+
+BOOL CScroll::ClearState(int state)
+{
+ if ( state & STATE_ENABLE )
+ {
+ if ( m_buttonUp != 0 ) m_buttonUp->ClearState(state);
+ if ( m_buttonDown != 0 ) m_buttonDown->ClearState(state);
+ }
+
+ return CControl::ClearState(state);
+}
+
+
+// Management of an event.
+
+BOOL CScroll::EventProcess(const Event &event)
+{
+ FPOINT pos, dim;
+ float hButton, h, value;
+
+ CControl::EventProcess(event);
+
+ if ( m_buttonUp != 0 && !m_bCapture )
+ {
+ if ( !m_buttonUp->EventProcess(event) ) return FALSE;
+ }
+ if ( m_buttonDown != 0 && !m_bCapture )
+ {
+ if ( !m_buttonDown->EventProcess(event) ) return FALSE;
+ }
+
+ if ( event.event == m_eventUp && m_step > 0.0f )
+ {
+ m_visibleValue -= m_step;
+ if ( m_visibleValue < 0.0f ) m_visibleValue = 0.0f;
+ AdjustGlint();
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ }
+
+ if ( event.event == m_eventDown && m_step > 0.0f )
+ {
+ m_visibleValue += m_step;
+ if ( m_visibleValue > 1.0f ) m_visibleValue = 1.0f;
+ AdjustGlint();
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ }
+
+ hButton = m_buttonUp?m_dim.x/0.75f:0.0f;
+
+ if ( event.event == EVENT_LBUTTONDOWN &&
+ (m_state & STATE_VISIBLE) &&
+ (m_state & STATE_ENABLE) )
+ {
+ if ( CControl::Detect(event.pos) )
+ {
+ pos.y = m_pos.y+hButton;
+ dim.y = m_dim.y-hButton*2.0f;
+ pos.y += dim.y*(1.0f-m_visibleRatio)*(1.0f-m_visibleValue);
+ dim.y *= m_visibleRatio;
+ if ( event.pos.y < pos.y ||
+ event.pos.y > pos.y+dim.y ) // click outside cabin?
+ {
+ h = (m_dim.y-hButton*2.0f)*(1.0f-m_visibleRatio);
+ value = 1.0f-(event.pos.y-(m_pos.y+hButton+dim.y*0.5f))/h;
+ if ( value < 0.0f ) value = 0.0f;
+ if ( value > 1.0f ) value = 1.0f;
+ m_visibleValue = value;
+ AdjustGlint();
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ }
+ m_bCapture = TRUE;
+ m_pressPos = event.pos;
+ m_pressValue = m_visibleValue;
+ }
+ }
+
+ if ( event.event == EVENT_MOUSEMOVE && m_bCapture )
+ {
+ h = (m_dim.y-hButton*2.0f)*(1.0f-m_visibleRatio);
+ if ( h != 0 )
+ {
+ value = m_pressValue - (event.pos.y-m_pressPos.y)/h;
+ if ( value < 0.0f ) value = 0.0f;
+ if ( value > 1.0f ) value = 1.0f;
+
+ if ( value != m_visibleValue )
+ {
+ m_visibleValue = value;
+ AdjustGlint();
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ }
+ }
+ }
+
+ if ( event.event == EVENT_LBUTTONUP && m_bCapture )
+ {
+ m_bCapture = FALSE;
+ }
+
+ if ( event.event == EVENT_KEYDOWN &&
+ event.param == VK_WHEELUP &&
+ Detect(event.pos) &&
+ m_buttonUp != 0 )
+ {
+ Event newEvent = event;
+ newEvent.event = m_buttonUp->RetEventMsg();
+ m_event->AddEvent(newEvent);
+ }
+ if ( event.event == EVENT_KEYDOWN &&
+ event.param == VK_WHEELDOWN &&
+ Detect(event.pos) &&
+ m_buttonDown != 0 )
+ {
+ Event newEvent = event;
+ newEvent.event = m_buttonDown->RetEventMsg();
+ m_event->AddEvent(newEvent);
+ }
+
+ return TRUE;
+}
+
+
+// Draws the button.
+
+void CScroll::Draw()
+{
+ FPOINT pos, dim, ppos, ddim;
+ float hButton;
+ int icon, n, i;
+
+ hButton = m_buttonUp?m_dim.x/0.75f:0.0f;
+
+ // Draws the bottom.
+ pos.x = m_pos.x;
+ pos.y = m_pos.y+hButton;
+ dim.x = m_dim.x;
+ dim.y = m_dim.y-hButton*2.0f;
+ if ( m_state & STATE_ENABLE ) icon = 0;
+ else icon = 1;
+ DrawVertex(pos, dim, icon);
+
+ // Draws the cabin.
+ if ( m_visibleRatio < 1.0f && (m_state & STATE_ENABLE) )
+ {
+ pos.x += 0.003f; // ch'tite(?) margin
+ pos.y += 0.003f;
+ dim.x -= 0.006f;
+ dim.y -= 0.006f;
+ pos.y += dim.y*(1.0f-m_visibleRatio)*(1.0f-m_visibleValue);
+ dim.y *= m_visibleRatio;
+ DrawVertex(pos, dim, 2);
+
+ n = (int)(dim.y*0.8f/0.012f);
+ if ( n < 1 ) n = 1;
+ if ( n > 5 ) n = 5;
+
+ ppos.x = pos.x+0.003f;
+ ppos.y = pos.y+(dim.y-(n-1)*0.012f-0.008f)/2.0f;
+ ddim.x = dim.x-0.006f;
+ ddim.y = 0.008f;
+ for ( i=0 ; i<n ; i++ )
+ {
+ DrawVertex(ppos, ddim, 3); // horizontal bar
+ ppos.y += 0.012f;
+ }
+ }
+
+ if ( m_buttonUp != 0 )
+ {
+ m_buttonUp->Draw();
+ }
+ if ( m_buttonDown != 0 )
+ {
+ m_buttonDown->Draw();
+ }
+}
+
+// Draws a rectangle.
+
+void CScroll::DrawVertex(FPOINT pos, FPOINT dim, int icon)
+{
+ FPOINT uv1, uv2;
+ float ex, dp;
+
+ if ( icon == 0 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 0.0f/256.0f; // yellow rectangle
+ uv1.y = 32.0f/256.0f;
+ uv2.x = 32.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+ ex = 8.0f/256.0f;
+ }
+ else if ( icon == 1 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 128.0f/256.0f; // gray rectangle
+ uv1.y = 32.0f/256.0f;
+ uv2.x = 160.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+ ex = 8.0f/256.0f;
+ }
+ else if ( icon == 2 )
+ {
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 64.0f/256.0f; // blue rectangle
+ uv1.y = 0.0f/256.0f;
+ uv2.x = 96.0f/256.0f;
+ uv2.y = 32.0f/256.0f;
+ ex = 8.0f/256.0f;
+ }
+ else
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 104.0f/256.0f; // blue line -
+ uv1.y = 32.0f/256.0f;
+ uv2.x = 128.0f/256.0f;
+ uv2.y = 40.0f/256.0f;
+ ex = 0.0f;
+ }
+
+ dp = 0.5f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+
+ DrawIcon(pos, dim, uv1, uv2, ex);
+}
+
+
+void CScroll::SetVisibleValue(float value)
+{
+ if ( value < 0.0 ) value = 0.0f;
+ if ( value > 1.0 ) value = 1.0f;
+ m_visibleValue = value;
+ AdjustGlint();
+}
+
+float CScroll::RetVisibleValue()
+{
+ return m_visibleValue;
+}
+
+
+void CScroll::SetVisibleRatio(float value)
+{
+ if ( value < 0.1 ) value = 0.1f;
+ if ( value > 1.0 ) value = 1.0f;
+ m_visibleRatio = value;
+ AdjustGlint();
+}
+
+float CScroll::RetVisibleRatio()
+{
+ return m_visibleRatio;
+}
+
+
+void CScroll::SetArrowStep(float step)
+{
+ m_step = step;
+}
+
+float CScroll::RetArrowStep()
+{
+ return m_step;
+}
+
diff --git a/src/ui/scroll.h b/src/ui/scroll.h
new file mode 100644
index 0000000..6c08a19
--- /dev/null
+++ b/src/ui/scroll.h
@@ -0,0 +1,84 @@
+// * 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/.
+
+// scroll.h
+
+#ifndef _SCROLL_H_
+#define _SCROLL_H_
+
+
+#include "control.h"
+#include "struct.h"
+
+
+class CD3DEngine;
+class CButton;
+
+
+#define SCROLL_WIDTH (15.0f/640.0f)
+
+
+
+class CScroll : public CControl
+{
+public:
+ CScroll(CInstanceManager* iMan);
+ ~CScroll();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ void SetPos(FPOINT pos);
+ void SetDim(FPOINT dim);
+
+ BOOL SetState(int state, BOOL bState);
+ BOOL SetState(int state);
+ BOOL ClearState(int state);
+
+ BOOL EventProcess(const Event &event);
+ void Draw();
+
+ void SetVisibleValue(float value);
+ float RetVisibleValue();
+
+ void SetVisibleRatio(float value);
+ float RetVisibleRatio();
+
+ void SetArrowStep(float step);
+ float RetArrowStep();
+
+protected:
+ void MoveAdjust();
+ void AdjustGlint();
+ void DrawVertex(FPOINT pos, FPOINT dim, int icon);
+
+protected:
+ CButton* m_buttonUp;
+ CButton* m_buttonDown;
+
+ float m_visibleValue;
+ float m_visibleRatio;
+ float m_step;
+
+ BOOL m_bCapture;
+ FPOINT m_pressPos;
+ float m_pressValue;
+
+ EventMsg m_eventUp;
+ EventMsg m_eventDown;
+};
+
+
+#endif //_SCROLL_H_
diff --git a/src/ui/shortcut.cpp b/src/ui/shortcut.cpp
new file mode 100644
index 0000000..21a6191
--- /dev/null
+++ b/src/ui/shortcut.cpp
@@ -0,0 +1,243 @@
+// * 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/.
+
+// shortcut.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "shortcut.h"
+
+
+
+
+// Object's constructor.
+
+CShortcut::CShortcut(CInstanceManager* iMan) : CControl(iMan)
+{
+ m_time = 0.0f;
+}
+
+// Object's destructor.
+
+CShortcut::~CShortcut()
+{
+}
+
+
+// Creates a new button.
+
+BOOL CShortcut::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ CControl::Create(pos, dim, icon, eventMsg);
+ return TRUE;
+}
+
+
+// Management of an event.
+
+BOOL CShortcut::EventProcess(const Event &event)
+{
+ CControl::EventProcess(event);
+
+ if ( event.event == EVENT_FRAME )
+ {
+ m_time += event.rTime;
+ }
+
+ if ( event.event == EVENT_LBUTTONDOWN )
+ {
+ if ( CControl::Detect(event.pos) )
+ {
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+// Draws the button.
+
+void CShortcut::Draw()
+{
+ float zoom;
+ int icon, mode;
+
+ icon = 0;
+ zoom = 0.8f;
+ mode = D3DSTATETTw;
+ if ( m_state & STATE_HILIGHT )
+ {
+ icon = 4;
+ zoom = 0.9f;
+ mode = D3DSTATENORMAL;
+ }
+ if ( m_state & STATE_CHECK )
+ {
+ icon = 1;
+ zoom = 0.8f;
+ mode = D3DSTATENORMAL;
+ }
+ if ( m_state & STATE_PRESS )
+ {
+ icon = 1;
+ zoom = 1.0f;
+ mode = D3DSTATENORMAL;
+ }
+ if ( m_icon == 6 || m_icon == 7 ) // pause or film?
+ {
+ icon = -1; // no bottom
+ zoom = 1.0f;
+ }
+
+ m_engine->SetTexture("button3.tga");
+
+ if ( icon != -1 )
+ {
+ m_engine->SetState(mode);
+ DrawVertex(icon, 0.95f);
+ }
+
+ m_engine->SetState(D3DSTATETTb);
+ DrawVertex(m_icon, zoom);
+
+ if ( m_state & STATE_FRAME )
+ {
+ FPOINT p1, p2, c, uv1, uv2;
+ float zoom, dp;
+
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTw);
+
+ zoom = 0.9f+sinf(m_time*8.0f)*0.1f;
+
+ 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;
+
+ 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 = 176.0f/256.0f;
+ uv1.y = 224.0f/256.0f;
+ uv2.x = 192.0f/256.0f;
+ uv2.y = 240.0f/256.0f;
+
+ dp = 0.5f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+
+ DrawIcon(p1, p2, uv1, uv2);
+ }
+
+ if ( (m_state & STATE_RUN) && Mod(m_time, 0.7f) >= 0.3f )
+ {
+ FPOINT uv1, uv2;
+ float dp;
+
+ m_engine->SetTexture("button3.tga");
+ m_engine->SetState(D3DSTATETTw);
+
+ uv1.x = 160.0f/256.0f;
+ uv1.y = 0.0f/256.0f;
+ uv2.x = 192.0f/256.0f;
+ uv2.y = 32.0f/256.0f;
+
+ dp = 0.5f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+
+ DrawIcon(m_pos, m_dim, uv1, uv2);
+ }
+}
+
+// Draw the vertex array.
+
+void CShortcut::DrawVertex(int icon, float zoom)
+{
+ LPDIRECT3DDEVICE7 device;
+ D3DVERTEX2 vertex[4]; // 2 triangles
+ FPOINT p1, p2, c;
+ D3DVECTOR n;
+ float u1, u2, v1, v2, dp;
+
+ device = m_engine->RetD3DDevice();
+
+ 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;
+
+ 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;
+
+ u1 = (32.0f/256.0f)*(icon%8);
+ v1 = (32.0f/256.0f)*(icon/8); // u-v texture
+ u2 = (32.0f/256.0f)+u1;
+ v2 = (32.0f/256.0f)+v1;
+
+ dp = 0.5f/256.0f;
+ u1 += dp;
+ v1 += dp;
+ u2 -= dp;
+ v2 -= dp;
+
+ n = D3DVECTOR(0.0f, 0.0f, -1.0f); // normal
+
+ vertex[0] = D3DVERTEX2(D3DVECTOR(p1.x, p1.y, 0.0f), n, u1,v2);
+ vertex[1] = D3DVERTEX2(D3DVECTOR(p1.x, p2.y, 0.0f), n, u1,v1);
+ vertex[2] = D3DVERTEX2(D3DVECTOR(p2.x, p1.y, 0.0f), n, u2,v2);
+ vertex[3] = D3DVERTEX2(D3DVECTOR(p2.x, p2.y, 0.0f), n, u2,v1);
+
+ device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL);
+ m_engine->AddStatisticTriangle(2);
+}
+
diff --git a/src/ui/shortcut.h b/src/ui/shortcut.h
new file mode 100644
index 0000000..e76402b
--- /dev/null
+++ b/src/ui/shortcut.h
@@ -0,0 +1,50 @@
+// * 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/.
+
+// shortcut.h
+
+#ifndef _SHORTCUT_H_
+#define _SHORTCUT_H_
+
+
+#include "control.h"
+
+
+class CD3DEngine;
+
+
+
+class CShortcut : public CControl
+{
+public:
+ CShortcut(CInstanceManager* iMan);
+ ~CShortcut();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ BOOL EventProcess(const Event &event);
+
+ void Draw();
+
+protected:
+ void DrawVertex(int icon, float zoom);
+
+protected:
+ float m_time;
+};
+
+
+#endif //_SHORTCUT_H_
diff --git a/src/ui/slider.cpp b/src/ui/slider.cpp
new file mode 100644
index 0000000..95bd3a4
--- /dev/null
+++ b/src/ui/slider.cpp
@@ -0,0 +1,582 @@
+// * 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/.
+
+// slider.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "text.h"
+#include "button.h"
+#include "slider.h"
+
+
+
+#define CURSOR_WIDTH (10.0f/640.0f)
+#define HOLE_WIDTH (5.0f/480.0f)
+
+
+
+
+// Object's constructor.
+
+CSlider::CSlider(CInstanceManager* iMan) : CControl(iMan)
+{
+ m_buttonLeft = 0;
+ m_buttonRight = 0;
+
+ m_min = 0.0f;
+ m_max = 1.0f;
+ m_visibleValue = 0.0f;
+ m_step = 0.0f;
+
+ m_marginButton = 0.0f;
+ m_bHoriz = FALSE;
+
+ m_eventUp = EVENT_NULL;
+ m_eventDown = EVENT_NULL;
+
+ m_bCapture = FALSE;
+}
+
+// Object's destructor.
+
+CSlider::~CSlider()
+{
+ delete m_buttonLeft;
+ delete m_buttonRight;
+}
+
+
+// Creates a new button.
+
+BOOL CSlider::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+ CControl::Create(pos, dim, icon, eventMsg);
+
+ MoveAdjust();
+ return TRUE;
+}
+
+
+void CSlider::SetPos(FPOINT pos)
+{
+ CControl::SetPos(pos);
+ MoveAdjust();
+}
+
+void CSlider::SetDim(FPOINT dim)
+{
+ CControl::SetDim(dim);
+ MoveAdjust();
+}
+
+void CSlider::MoveAdjust()
+{
+ FPOINT pos, dim;
+
+ m_bHoriz = ( m_dim.x > m_dim.y );
+
+ if ( ( m_bHoriz && m_dim.x < m_dim.y*4.0f) ||
+ (!m_bHoriz && m_dim.y < m_dim.x*4.0f) ) // very short slider?
+ {
+ delete m_buttonLeft;
+ m_buttonLeft = 0;
+
+ delete m_buttonRight;
+ m_buttonRight = 0;
+
+ m_marginButton = 0.0f;
+ }
+ else
+ {
+#if 1
+ if ( m_buttonLeft == 0 )
+ {
+ m_buttonLeft = new CButton(m_iMan);
+ m_buttonLeft->Create(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), m_bHoriz?55:49, EVENT_NULL); // </^
+ m_buttonLeft->SetRepeat(TRUE);
+ if ( m_state & STATE_SHADOW ) m_buttonLeft->SetState(STATE_SHADOW);
+ m_eventUp = m_buttonLeft->RetEventMsg();
+ }
+
+ if ( m_buttonRight == 0 )
+ {
+ m_buttonRight = new CButton(m_iMan);
+ m_buttonRight->Create(FPOINT(0.0f, 0.0f), FPOINT(0.0f, 0.0f), m_bHoriz?48:50, EVENT_NULL); // >/v
+ m_buttonRight->SetRepeat(TRUE);
+ if ( m_state & STATE_SHADOW ) m_buttonRight->SetState(STATE_SHADOW);
+ m_eventDown = m_buttonRight->RetEventMsg();
+ }
+
+ m_marginButton = m_bHoriz?(m_dim.y*0.75f):(m_dim.x/0.75f);
+#endif
+ }
+
+ if ( m_buttonLeft != 0 )
+ {
+ if ( m_bHoriz )
+ {
+ pos.x = m_pos.x;
+ pos.y = m_pos.y;
+ dim.x = m_dim.y*0.75f;
+ dim.y = m_dim.y;
+ }
+ else
+ {
+ pos.x = m_pos.x;
+ pos.y = m_pos.y+m_dim.y-m_dim.x/0.75f;
+ dim.x = m_dim.x;
+ dim.y = m_dim.x/0.75f;
+ }
+ m_buttonLeft->SetPos(pos);
+ m_buttonLeft->SetDim(dim);
+ }
+
+ if ( m_buttonRight != 0 )
+ {
+ if ( m_bHoriz )
+ {
+ pos.x = m_pos.x+m_dim.x-m_dim.y*0.75f;
+ pos.y = m_pos.y;
+ dim.x = m_dim.y*0.75f;
+ dim.y = m_dim.y;
+ }
+ else
+ {
+ pos.x = m_pos.x;
+ pos.y = m_pos.y;
+ dim.x = m_dim.x;
+ dim.y = m_dim.x/0.75f;
+ }
+ m_buttonRight->SetPos(pos);
+ m_buttonRight->SetDim(dim);
+ }
+
+ AdjustGlint();
+}
+
+// Adjusts the position of reflection.
+
+void CSlider::AdjustGlint()
+{
+ FPOINT ref;
+ float w;
+
+ if ( m_bHoriz )
+ {
+ w = m_dim.x-m_marginButton*0.75f;
+ ref.x = m_pos.x+m_marginButton;
+ ref.x += (w-CURSOR_WIDTH)*m_visibleValue;
+ ref.y = m_pos.y+m_dim.y;
+ }
+ else
+ {
+ w = m_dim.y-m_marginButton*2.0f;
+ ref.y = m_pos.y+m_marginButton+CURSOR_WIDTH;
+ ref.y += (w-CURSOR_WIDTH)*m_visibleValue;
+ ref.x = m_pos.x;
+ }
+
+ GlintCreate(ref);
+}
+
+
+BOOL CSlider::SetState(int state, BOOL bState)
+{
+ if ( (state & STATE_ENABLE) ||
+ (state & STATE_SHADOW) )
+ {
+ if ( m_buttonLeft != 0 ) m_buttonLeft->SetState(state, bState);
+ if ( m_buttonRight != 0 ) m_buttonRight->SetState(state, bState);
+ }
+
+ return CControl::SetState(state, bState);
+}
+
+BOOL CSlider::SetState(int state)
+{
+ if ( (state & STATE_ENABLE) ||
+ (state & STATE_SHADOW) )
+ {
+ if ( m_buttonLeft != 0 ) m_buttonLeft->SetState(state);
+ if ( m_buttonRight != 0 ) m_buttonRight->SetState(state);
+ }
+
+ return CControl::SetState(state);
+}
+
+BOOL CSlider::ClearState(int state)
+{
+ if ( (state & STATE_ENABLE) ||
+ (state & STATE_SHADOW) )
+ {
+ if ( m_buttonLeft != 0 ) m_buttonLeft->ClearState(state);
+ if ( m_buttonRight != 0 ) m_buttonRight->ClearState(state);
+ }
+
+ return CControl::ClearState(state);
+}
+
+
+// Management of an event.
+
+BOOL CSlider::EventProcess(const Event &event)
+{
+ FPOINT pos, dim;
+ float value;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE;
+
+ CControl::EventProcess(event);
+
+ if ( m_buttonLeft != 0 && !m_bCapture )
+ {
+ if ( !m_buttonLeft->EventProcess(event) ) return FALSE;
+ }
+ if ( m_buttonRight != 0 && !m_bCapture )
+ {
+ if ( !m_buttonRight->EventProcess(event) ) return FALSE;
+ }
+
+ if ( event.event == m_eventUp && m_step > 0.0f )
+ {
+ m_visibleValue -= m_bHoriz?m_step:-m_step;
+ if ( m_visibleValue < 0.0f ) m_visibleValue = 0.0f;
+ if ( m_visibleValue > 1.0f ) m_visibleValue = 1.0f;
+ AdjustGlint();
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ }
+
+ if ( event.event == m_eventDown && m_step > 0.0f )
+ {
+ m_visibleValue += m_bHoriz?m_step:-m_step;
+ if ( m_visibleValue < 0.0f ) m_visibleValue = 0.0f;
+ if ( m_visibleValue > 1.0f ) m_visibleValue = 1.0f;
+ AdjustGlint();
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ }
+
+ if ( event.event == EVENT_LBUTTONDOWN &&
+ (m_state & STATE_VISIBLE) &&
+ (m_state & STATE_ENABLE) )
+ {
+ if ( CControl::Detect(event.pos) )
+ {
+ if ( m_bHoriz )
+ {
+ pos.x = m_pos.x+m_marginButton;
+ dim.x = m_dim.x-m_marginButton*2.0f;
+ value = (event.pos.x-pos.x-CURSOR_WIDTH/2.0f);
+ value /= (dim.x-CURSOR_WIDTH);
+ }
+ else
+ {
+ pos.y = m_pos.y+m_marginButton;
+ dim.y = m_dim.y-m_marginButton*2.0f;
+ value = (event.pos.y-pos.y-CURSOR_WIDTH/2.0f);
+ value /= (dim.y-CURSOR_WIDTH);
+ }
+ if ( value < 0.0f ) value = 0.0f;
+ if ( value > 1.0f ) value = 1.0f;
+ m_visibleValue = value;
+ AdjustGlint();
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+
+ m_bCapture = TRUE;
+ m_pressPos = event.pos;
+ m_pressValue = m_visibleValue;
+ }
+ }
+
+ if ( event.event == EVENT_MOUSEMOVE && m_bCapture )
+ {
+ if ( m_bHoriz )
+ {
+ pos.x = m_pos.x+m_marginButton;
+ dim.x = m_dim.x-m_marginButton*2.0f;
+ value = (event.pos.x-pos.x-CURSOR_WIDTH/2.0f);
+ value /= (dim.x-CURSOR_WIDTH);
+ }
+ else
+ {
+ pos.y = m_pos.y+m_marginButton;
+ dim.y = m_dim.y-m_marginButton*2.0f;
+ value = (event.pos.y-pos.y-CURSOR_WIDTH/2.0f);
+ value /= (dim.y-CURSOR_WIDTH);
+ }
+ if ( value < 0.0f ) value = 0.0f;
+ if ( value > 1.0f ) value = 1.0f;
+
+ if ( value != m_visibleValue )
+ {
+ m_visibleValue = value;
+ AdjustGlint();
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ }
+ }
+
+ if ( event.event == EVENT_LBUTTONUP && m_bCapture )
+ {
+ m_bCapture = FALSE;
+ }
+
+ if ( event.event == EVENT_KEYDOWN &&
+ event.param == VK_WHEELUP &&
+ Detect(event.pos) &&
+ m_buttonLeft != 0 )
+ {
+ Event newEvent = event;
+ newEvent.event = m_buttonLeft->RetEventMsg();
+ m_event->AddEvent(newEvent);
+ }
+ if ( event.event == EVENT_KEYDOWN &&
+ event.param == VK_WHEELDOWN &&
+ Detect(event.pos) &&
+ m_buttonRight != 0 )
+ {
+ Event newEvent = event;
+ newEvent.event = m_buttonRight->RetEventMsg();
+ m_event->AddEvent(newEvent);
+ }
+
+ return TRUE;
+}
+
+
+// Draws button.
+
+void CSlider::Draw()
+{
+ FPOINT pos, dim, ppos, ddim, spos;
+ int icon;
+ float h;
+ char text[100];
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ if ( m_buttonLeft != 0 )
+ {
+ m_buttonLeft->Draw();
+ }
+
+ if ( m_bHoriz )
+ {
+ pos.x = m_pos.x+m_marginButton;
+ pos.y = m_pos.y;
+ dim.x = m_dim.x-m_marginButton*2.0f;
+ dim.y = m_dim.y;
+ }
+ else
+ {
+ pos.x = m_pos.x;
+ pos.y = m_pos.y+m_marginButton;
+ dim.x = m_dim.x;
+ dim.y = m_dim.y-m_marginButton*2.0f;
+ }
+
+ // Draws the bottom.
+ if ( m_bHoriz )
+ {
+ ppos.x = pos.x + CURSOR_WIDTH/2.0f;
+ ppos.y = pos.y + (dim.y-HOLE_WIDTH)/2.0f;
+ ddim.x = dim.x - CURSOR_WIDTH;
+ ddim.y = HOLE_WIDTH;
+ }
+ else
+ {
+ ppos.x = pos.x + (dim.x-HOLE_WIDTH*0.75f)/2.0f;
+ ppos.y = pos.y + CURSOR_WIDTH/2.0f;
+ ddim.x = HOLE_WIDTH*0.75f;
+ ddim.y = dim.y - CURSOR_WIDTH;
+ }
+
+ if ( m_state & STATE_SHADOW )
+ {
+ spos = ppos;
+ spos.x -= 0.005f*0.75f;
+ spos.y += 0.005f;
+ DrawShadow(spos, ddim);
+ }
+
+ if ( m_state & STATE_ENABLE ) icon = 0;
+ else icon = 1;
+ DrawVertex(ppos, ddim, icon);
+
+ // Draws the cabin.
+ if ( m_state & STATE_ENABLE )
+ {
+ if ( m_bHoriz )
+ {
+ ppos.x = pos.x + (dim.x-CURSOR_WIDTH)*m_visibleValue;
+ ppos.y = pos.y;
+ ddim.x = CURSOR_WIDTH;
+ ddim.y = dim.y;
+ }
+ else
+ {
+ ppos.x = pos.x;
+ ppos.y = pos.y + (dim.y-CURSOR_WIDTH)*m_visibleValue;
+ ddim.x = dim.x;
+ ddim.y = CURSOR_WIDTH;
+ }
+ DrawShadow(ppos, ddim, 0.7f);
+ DrawVertex(ppos, ddim, 2);
+ }
+
+ if ( m_buttonRight != 0 )
+ {
+ m_buttonRight->Draw();
+ }
+
+ if ( m_bHoriz )
+ {
+ sprintf(text, "%d", (int)(m_min+m_visibleValue*(m_max-m_min)));
+ h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType);
+ pos.x = m_pos.x+m_dim.x+(10.0f/640.0f);
+ pos.y = m_pos.y+(m_dim.y-h)/2.0f;
+ m_engine->RetText()->DrawText(text, pos, m_dim.x, 1, m_fontSize, m_fontStretch, m_fontType, 0);
+ }
+ else
+ {
+ if ( m_state & STATE_VALUE )
+ {
+ pos.x = m_pos.x+m_dim.x+4.0f/640.0f;
+ h = m_dim.y-m_marginButton*2.0f;
+ pos.y = m_pos.y+m_marginButton-4.0f/480.0f;
+ pos.y += (h-CURSOR_WIDTH)*m_visibleValue;
+ dim.x = 50.0f/640.0f;
+ dim.y = 16.0f/480.0f;
+ sprintf(text, "%d", (int)(m_min+(m_visibleValue*(m_max-m_min))));
+ m_engine->RetText()->DrawText(text, pos, dim.x, 1, m_fontSize, m_fontStretch, m_fontType, 0);
+ }
+ }
+}
+
+// Draws a rectangle.
+
+void CSlider::DrawVertex(FPOINT pos, FPOINT dim, int icon)
+{
+ FPOINT uv1, uv2, corner;
+ float ex, dp;
+
+ if ( icon == 0 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 0.0f/256.0f; // yellow rectangle
+ uv1.y = 32.0f/256.0f;
+ uv2.x = 32.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+ corner.x = 2.0f/640.0f;
+ corner.y = 2.0f/480.0f;
+ ex = 4.0f/256.0f;
+ }
+ else if ( icon == 1 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 128.0f/256.0f; // gray rectangle
+ uv1.y = 32.0f/256.0f;
+ uv2.x = 160.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+ corner.x = 2.0f/640.0f;
+ corner.y = 2.0f/480.0f;
+ ex = 4.0f/256.0f;
+ }
+ else
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 224.0f/256.0f; // cursor
+ uv1.y = 32.0f/256.0f;
+ uv2.x = 256.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+ if ( !m_bHoriz )
+ {
+ uv1.y += 64.0f/256.0f;
+ uv2.y += 64.0f/256.0f;
+ }
+ corner.x = 2.0f/640.0f;
+ corner.y = 2.0f/480.0f;
+ ex = 4.0f/256.0f;
+ }
+
+ dp = 0.5f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+
+ DrawIcon(pos, dim, uv1, uv2, corner, ex);
+}
+
+
+void CSlider::SetLimit(float min, float max)
+{
+ m_min = min;
+ m_max = max;
+}
+
+void CSlider::SetVisibleValue(float value)
+{
+ value = (value-m_min)/(m_max-m_min);
+ if ( value < 0.0 ) value = 0.0f;
+ if ( value > 1.0 ) value = 1.0f;
+ m_visibleValue = value;
+ AdjustGlint();
+}
+
+float CSlider::RetVisibleValue()
+{
+ return m_min+m_visibleValue*(m_max-m_min);
+}
+
+
+void CSlider::SetArrowStep(float step)
+{
+ m_step = step/(m_max-m_min);
+}
+
+float CSlider::RetArrowStep()
+{
+ return m_step*(m_max-m_min);
+}
+
+
diff --git a/src/ui/slider.h b/src/ui/slider.h
new file mode 100644
index 0000000..c254254
--- /dev/null
+++ b/src/ui/slider.h
@@ -0,0 +1,84 @@
+// * 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/.
+
+// slider.h
+
+#ifndef _SLIDER_H_
+#define _SLIDER_H_
+
+
+#include "control.h"
+#include "struct.h"
+
+
+class CD3DEngine;
+class CButton;
+
+
+
+class CSlider : public CControl
+{
+public:
+ CSlider(CInstanceManager* iMan);
+ ~CSlider();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ void SetPos(FPOINT pos);
+ void SetDim(FPOINT dim);
+
+ BOOL SetState(int state, BOOL bState);
+ BOOL SetState(int state);
+ BOOL ClearState(int state);
+
+ BOOL EventProcess(const Event &event);
+ void Draw();
+
+ void SetLimit(float min, float max);
+
+ void SetVisibleValue(float value);
+ float RetVisibleValue();
+
+ void SetArrowStep(float step);
+ float RetArrowStep();
+
+protected:
+ void MoveAdjust();
+ void AdjustGlint();
+ void DrawVertex(FPOINT pos, FPOINT dim, int icon);
+
+protected:
+ CButton* m_buttonLeft;
+ CButton* m_buttonRight;
+
+ float m_min;
+ float m_max;
+ float m_visibleValue;
+ float m_step;
+
+ BOOL m_bHoriz;
+ float m_marginButton;
+
+ BOOL m_bCapture;
+ FPOINT m_pressPos;
+ float m_pressValue;
+
+ EventMsg m_eventUp;
+ EventMsg m_eventDown;
+};
+
+
+#endif //_SLIDER_H_
diff --git a/src/ui/studio.cpp b/src/ui/studio.cpp
new file mode 100644
index 0000000..8839f31
--- /dev/null
+++ b/src/ui/studio.cpp
@@ -0,0 +1,1667 @@
+// * 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/.
+
+// studio.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <windows.h>
+#include <direct.h>
+#include <io.h>
+#include <time.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "d3dmath.h"
+#include "language.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "restext.h"
+#include "math3d.h"
+#include "robotmain.h"
+#include "object.h"
+#include "camera.h"
+#include "sound.h"
+#include "script.h"
+#include "interface.h"
+#include "button.h"
+#include "check.h"
+#include "slider.h"
+#include "edit.h"
+#include "list.h"
+#include "label.h"
+#include "group.h"
+#include "window.h"
+#include "text.h"
+#include "cbottoken.h"
+#include "studio.h"
+
+
+
+
+// Object's constructor.
+
+CStudio::CStudio(CInstanceManager* iMan)
+{
+ m_iMan = iMan;
+ m_iMan->AddInstance(CLASS_STUDIO, this);
+
+ m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE);
+ m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT);
+ m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE);
+ m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN);
+ m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA);
+ m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND);
+
+ m_bEditMaximized = FALSE;
+ m_bEditMinimized = FALSE;
+
+ m_time = 0.0f;
+ m_bRealTime = TRUE;
+ m_bRunning = FALSE;
+ m_fixInfoTextTime = 0.0f;
+ m_helpFilename[0] = 0;
+ m_dialog = SD_NULL;
+}
+
+// Object's destructor.
+
+CStudio::~CStudio()
+{
+ m_iMan->DeleteInstance(CLASS_STUDIO, this);
+}
+
+
+// Management of an event.
+
+BOOL CStudio::EventProcess(const Event &event)
+{
+ CWindow* pw;
+ CEdit* edit;
+ CSlider* slider;
+ char res[100];
+
+ if ( m_dialog != SD_NULL ) // dialogue exists?
+ {
+ return EventDialog(event);
+ }
+
+ if ( event.event == EVENT_FRAME )
+ {
+ EventFrame(event);
+ }
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw == 0 ) return FALSE;
+
+ edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT);
+ if ( edit == 0 ) return FALSE;
+
+ if ( event.event == pw->RetEventMsgClose() )
+ {
+ Event newEvent = event;
+ newEvent.event = EVENT_STUDIO_OK;
+ m_event->AddEvent(newEvent);
+ }
+
+ if ( event.event == EVENT_STUDIO_EDIT ) // text modifief?
+ {
+ ColorizeScript(edit);
+ }
+
+ if ( event.event == EVENT_STUDIO_LIST ) // list clicked?
+ {
+ m_main->StartDisplayInfo(m_helpFilename, -1);
+ }
+
+ if ( event.event == EVENT_STUDIO_NEW ) // new?
+ {
+ m_script->New(edit, "");
+ }
+
+ if ( event.event == EVENT_STUDIO_OPEN ) // open?
+ {
+ StartDialog(SD_OPEN);
+ }
+ if ( event.event == EVENT_STUDIO_SAVE ) // save?
+ {
+ StartDialog(SD_SAVE);
+ }
+
+ if ( event.event == EVENT_STUDIO_UNDO ) // undo?
+ {
+ edit->Undo();
+ }
+ if ( event.event == EVENT_STUDIO_CUT ) // cut?
+ {
+ edit->Cut();
+ }
+ if ( event.event == EVENT_STUDIO_COPY ) // copy?
+ {
+ edit->Copy();
+ }
+ if ( event.event == EVENT_STUDIO_PASTE ) // paste?
+ {
+ edit->Paste();
+ }
+
+ if ( event.event == EVENT_STUDIO_SIZE ) // size?
+ {
+ slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE);
+ if ( slider == 0 ) return FALSE;
+ m_main->SetFontSize(9.0f+slider->RetVisibleValue()*6.0f);
+ ViewEditScript();
+ }
+
+ if ( event.event == EVENT_STUDIO_TOOL && // instructions?
+ m_dialog == SD_NULL )
+ {
+ m_main->StartDisplayInfo(SATCOM_HUSTON, FALSE);
+ }
+ if ( event.event == EVENT_STUDIO_HELP && // help?
+ m_dialog == SD_NULL )
+ {
+ m_main->StartDisplayInfo(SATCOM_PROG, FALSE);
+ }
+
+ if ( event.event == EVENT_STUDIO_COMPILE ) // compile?
+ {
+ char buffer[100];
+
+ if ( m_script->GetScript(edit) ) // compile
+ {
+ GetResource(RES_TEXT, RT_STUDIO_COMPOK, res);
+ SetInfoText(res, FALSE);
+ }
+ else
+ {
+ m_script->GetError(buffer);
+ SetInfoText(buffer, FALSE);
+ }
+ }
+
+ if ( event.event == EVENT_STUDIO_RUN ) // run/stop?
+ {
+ if ( m_script->IsRunning() )
+ {
+ Event newEvent = event;
+ newEvent.event = EVENT_OBJECT_PROGSTOP;
+ m_event->AddEvent(newEvent); // stop
+ }
+ else
+ {
+ if ( m_script->GetScript(edit) ) // compile
+ {
+ SetInfoText("", FALSE);
+
+ Event newEvent = event;
+ newEvent.event = EVENT_OBJECT_PROGSTART;
+ m_event->AddEvent(newEvent); // start
+ }
+ else
+ {
+ char buffer[100];
+ m_script->GetError(buffer);
+ SetInfoText(buffer, FALSE);
+ }
+ }
+ }
+
+ if ( event.event == EVENT_STUDIO_REALTIME ) // real time?
+ {
+ m_bRealTime = !m_bRealTime;
+ m_script->SetStepMode(!m_bRealTime);
+ UpdateFlux();
+ UpdateButtons();
+ }
+
+ if ( event.event == EVENT_STUDIO_STEP ) // step?
+ {
+ m_script->Step(event);
+ }
+
+ if ( event.event == EVENT_KEYDOWN )
+ {
+ if ( event.param == m_engine->RetKey(KEYRANK_CBOT, 0) ||
+ event.param == m_engine->RetKey(KEYRANK_CBOT, 1) )
+ {
+ if ( m_helpFilename[0] != 0 )
+ {
+ m_main->StartDisplayInfo(m_helpFilename, -1);
+ }
+ }
+ }
+
+ if ( event.event == EVENT_WINDOW3 ) // window is moved?
+ {
+ m_editActualPos = m_editFinalPos = pw->RetPos();
+ m_editActualDim = m_editFinalDim = pw->RetDim();
+ m_main->SetWindowPos(m_editActualPos);
+ m_main->SetWindowDim(m_editActualDim);
+ AdjustEditScript();
+ }
+ if ( event.event == pw->RetEventMsgReduce() )
+ {
+ if ( m_bEditMinimized )
+ {
+ m_editFinalPos = m_main->RetWindowPos();
+ m_editFinalDim = m_main->RetWindowDim();
+ m_bEditMinimized = FALSE;
+ m_bEditMaximized = FALSE;
+ }
+ else
+ {
+ m_editFinalPos.x = 0.00f;
+ m_editFinalPos.y = -0.44f;
+ m_editFinalDim.x = 1.00f;
+ m_editFinalDim.y = 0.50f;
+ m_bEditMinimized = TRUE;
+ m_bEditMaximized = FALSE;
+ }
+ m_main->SetEditFull(m_bEditMaximized);
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw != 0 )
+ {
+ pw->SetMaximized(m_bEditMaximized);
+ pw->SetMinimized(m_bEditMinimized);
+ }
+ }
+ if ( event.event == pw->RetEventMsgFull() )
+ {
+ if ( m_bEditMaximized )
+ {
+ m_editFinalPos = m_main->RetWindowPos();
+ m_editFinalDim = m_main->RetWindowDim();
+ m_bEditMinimized = FALSE;
+ m_bEditMaximized = FALSE;
+ }
+ else
+ {
+ m_editFinalPos.x = 0.00f;
+ m_editFinalPos.y = 0.00f;
+ m_editFinalDim.x = 1.00f;
+ m_editFinalDim.y = 1.00f;
+ m_bEditMinimized = FALSE;
+ m_bEditMaximized = TRUE;
+ }
+ m_main->SetEditFull(m_bEditMaximized);
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw != 0 )
+ {
+ pw->SetMaximized(m_bEditMaximized);
+ pw->SetMinimized(m_bEditMinimized);
+ }
+ }
+
+ return TRUE;
+}
+
+
+// Evolves value with time elapsed.
+
+float Evolution(float final, float actual, float time)
+{
+ float value;
+
+ value = actual + (final-actual)*time;
+
+ if ( final > actual )
+ {
+ if ( value > final ) value = final; // does not exceed
+ }
+ else
+ {
+ if ( value < final ) value = final; // does not exceed
+ }
+
+ return value;
+}
+
+// Makes the studio evolve as time elapsed.
+
+BOOL CStudio::EventFrame(const Event &event)
+{
+ CWindow* pw;
+ CEdit* edit;
+ CList* list;
+ float time;
+ int cursor1, cursor2, iCursor1, iCursor2;
+ char res[100];
+
+ m_time += event.rTime;
+ m_fixInfoTextTime -= event.rTime;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw == 0 ) return FALSE;
+
+ edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT);
+ if ( edit == 0 ) return FALSE;
+
+ list = (CList*)pw->SearchControl(EVENT_STUDIO_LIST);
+ if ( list == 0 ) return FALSE;
+
+ if ( !m_script->IsRunning() && m_bRunning ) // stop?
+ {
+ m_bRunning = FALSE;
+ UpdateFlux(); // stop
+ AdjustEditScript();
+ GetResource(RES_TEXT, RT_STUDIO_PROGSTOP, res);
+ SetInfoText(res, FALSE);
+
+ Event newEvent = event;
+ newEvent.event = EVENT_OBJECT_PROGSTOP;
+ m_event->AddEvent(newEvent); // stop
+ }
+
+ if ( m_script->IsRunning() && !m_bRunning ) // starting?
+ {
+ m_bRunning = TRUE;
+ UpdateFlux(); // run
+ AdjustEditScript();
+ }
+ UpdateButtons();
+
+ if ( m_bRunning )
+ {
+ m_script->GetCursor(cursor1, cursor2);
+ edit->GetCursor(iCursor1, iCursor2);
+ if ( cursor1 != iCursor1 ||
+ cursor2 != iCursor2 ) // cursors change?
+ {
+ edit->SetCursor(cursor1, cursor2); // shows it on the execution
+ edit->ShowSelect();
+ }
+
+ m_script->UpdateList(list); // updates the list of variables
+ }
+ else
+ {
+ SearchToken(edit);
+ }
+
+ if ( m_editFinalPos.x != m_editActualPos.x ||
+ m_editFinalPos.y != m_editActualPos.y ||
+ m_editFinalDim.x != m_editActualDim.x ||
+ m_editFinalDim.y != m_editActualDim.y )
+ {
+ time = event.rTime*20.0f;
+ m_editActualPos.x = Evolution(m_editFinalPos.x, m_editActualPos.x, time);
+ m_editActualPos.y = Evolution(m_editFinalPos.y, m_editActualPos.y, time);
+ m_editActualDim.x = Evolution(m_editFinalDim.x, m_editActualDim.x, time);
+ m_editActualDim.y = Evolution(m_editFinalDim.y, m_editActualDim.y, time);
+ AdjustEditScript();
+ }
+
+ return TRUE;
+}
+
+
+// Indicates whether a character is part of a word.
+
+BOOL IsToken(int character)
+{
+ char c;
+
+ c = tolower(RetNoAccent(character));
+
+ return ( (c >= 'a' && c <= 'z') ||
+ (c >= '0' && c <= '9') ||
+ c == '_' );
+}
+
+// Seeks if the cursor is on a keyword.
+
+void CStudio::SearchToken(CEdit* edit)
+{
+ ObjectType type;
+ int len, cursor1, cursor2, i, character, level;
+ char* text;
+ char token[100];
+
+ text = edit->RetText();
+ len = edit->RetTextLength();
+ edit->GetCursor(cursor1, cursor2);
+
+ i = cursor1;
+ if ( i > 0 )
+ {
+ character = (unsigned char)text[i-1];
+ if ( !IsToken(character) )
+ {
+ level = 1;
+ while ( i > 0 )
+ {
+ character = (unsigned char)text[i-1];
+ if ( character == ')' )
+ {
+ level ++;
+ }
+ else if ( character == '(' )
+ {
+ level --;
+ if ( level == 0 ) break;
+ }
+ i --;
+ }
+ if ( level > 0 )
+ {
+ m_helpFilename[0] = 0;
+ SetInfoText("", TRUE);
+ return;
+ }
+ while ( i > 0 )
+ {
+ character = (unsigned char)text[i-1];
+ if ( IsToken(character) ) break;
+ i --;
+ }
+ }
+ }
+
+ while ( i > 0 )
+ {
+ character = (unsigned char)text[i-1];
+ if ( !IsToken(character) ) break;
+ i --;
+ }
+ cursor2 = i;
+
+ while ( i < len )
+ {
+ character = (unsigned char)text[i];
+ if ( !IsToken(character) ) break;
+ i ++;
+ }
+ cursor1 = i;
+ len = cursor1-cursor2;
+
+ if ( len > 100-1 ) len = 100-1;
+ for ( i=0 ; i<len ; i++ )
+ {
+ token[i] = text[cursor2+i];
+ }
+ token[i] = 0;
+
+ strcpy(m_helpFilename, RetHelpFilename(token));
+ if ( m_helpFilename[0] == 0 )
+ {
+ for ( i=0 ; i<OBJECT_MAX ; i++ )
+ {
+ type = (ObjectType)i;
+ text = RetObjectName(type);
+ if ( text[0] != 0 )
+ {
+ if ( strcmp(token, text) == 0 )
+ {
+ strcpy(m_helpFilename, RetHelpFilename(type));
+ SetInfoText(token, TRUE);
+ return;
+ }
+ }
+ text = RetObjectAlias(type);
+ if ( text[0] != 0 )
+ {
+ if ( strcmp(token, text) == 0 )
+ {
+ strcpy(m_helpFilename, RetHelpFilename(type));
+ SetInfoText(token, TRUE);
+ return;
+ }
+ }
+ }
+ }
+
+ text = RetHelpText(token);
+ if ( text[0] == 0 && m_helpFilename[0] != 0 )
+ {
+ SetInfoText(token, TRUE);
+ }
+ else
+ {
+ SetInfoText(text, TRUE);
+ }
+}
+
+// Colors the text according to syntax.
+
+void CStudio::ColorizeScript(CEdit* edit)
+{
+ m_script->ColorizeScript(edit);
+}
+
+
+// Starts editing a program.
+
+void CStudio::StartEditScript(CScript *script, char* name, int rank)
+{
+ FPOINT pos, dim;
+ CWindow* pw;
+ CEdit* edit;
+ CButton* button;
+ CSlider* slider;
+ CList* list;
+ char res[100];
+
+ m_script = script;
+ m_rank = rank;
+
+ m_main->SetEditLock(TRUE, TRUE);
+ m_main->SetEditFull(FALSE);
+ m_bInitPause = m_engine->RetPause();
+ m_main->SetSpeed(1.0f);
+ m_editCamera = m_camera->RetType();
+ m_camera->SetType(CAMERA_EDIT);
+
+ m_bRunning = m_script->IsRunning();
+ m_bRealTime = m_bRunning;
+ m_script->SetStepMode(!m_bRealTime);
+
+ button = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT);
+ if ( button != 0 )
+ {
+ button->ClearState(STATE_VISIBLE);
+ }
+
+ pos = m_editFinalPos = m_editActualPos = m_main->RetWindowPos();
+ dim = m_editFinalDim = m_editActualDim = m_main->RetWindowDim();
+ pw = m_interface->CreateWindows(pos, dim, 8, EVENT_WINDOW3);
+ if ( pw == 0 ) return;
+ pw->SetState(STATE_SHADOW);
+ pw->SetRedim(TRUE); // before SetName!
+ pw->SetMovable(TRUE);
+ pw->SetClosable(TRUE);
+ GetResource(RES_TEXT, RT_STUDIO_TITLE, res);
+ pw->SetName(res);
+ pw->SetMinDim(FPOINT(0.49f, 0.50f));
+ pw->SetMaximized(m_bEditMaximized);
+ pw->SetMinimized(m_bEditMinimized);
+ m_main->SetEditFull(m_bEditMaximized);
+
+ edit = pw->CreateEdit(pos, dim, 0, EVENT_STUDIO_EDIT);
+ if ( edit == 0 ) return;
+ edit->SetState(STATE_SHADOW);
+ edit->SetInsideScroll(FALSE);
+//? if ( m_bRunning ) edit->SetEdit(FALSE);
+ edit->SetMaxChar(EDITSTUDIOMAX);
+ edit->SetFontType(FONT_COURIER);
+ edit->SetFontStretch(0.7f);
+ edit->SetDisplaySpec(TRUE);
+ edit->SetAutoIndent(m_engine->RetEditIndentMode());
+ m_script->PutScript(edit, name);
+ ColorizeScript(edit);
+
+ ViewEditScript();
+
+ list = pw->CreateList(pos, dim, 1, EVENT_STUDIO_LIST, 1.2f);
+ list->SetState(STATE_SHADOW);
+ list->SetFontType(FONT_COURIER);
+ list->SetSelectCap(FALSE);
+ list->SetFontSize(SMALLFONT*0.85f);
+//? list->SetFontStretch(1.0f);
+
+ button = pw->CreateButton(pos, dim, 56, EVENT_STUDIO_NEW);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 57, EVENT_STUDIO_OPEN);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 58, EVENT_STUDIO_SAVE);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 59, EVENT_STUDIO_UNDO);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 60, EVENT_STUDIO_CUT);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 61, EVENT_STUDIO_COPY);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 62, EVENT_STUDIO_PASTE);
+ button->SetState(STATE_SHADOW);
+ slider = pw->CreateSlider(pos, dim, 0, EVENT_STUDIO_SIZE);
+ slider->SetState(STATE_SHADOW);
+ slider->SetVisibleValue((m_main->RetFontSize()-9.0f)/6.0f);
+ pw->CreateGroup(pos, dim, 19, EVENT_LABEL1); // SatCom logo
+ button = pw->CreateButton(pos, dim, 128+57, EVENT_STUDIO_TOOL);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 128+60, EVENT_STUDIO_HELP);
+ button->SetState(STATE_SHADOW);
+
+ button = pw->CreateButton(pos, dim, -1, EVENT_STUDIO_OK);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, -1, EVENT_STUDIO_CANCEL);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 64+23, EVENT_STUDIO_COMPILE);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 21, EVENT_STUDIO_RUN);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 64+22, EVENT_STUDIO_REALTIME);
+ button->SetState(STATE_SHADOW);
+ button = pw->CreateButton(pos, dim, 64+29, EVENT_STUDIO_STEP);
+ button->SetState(STATE_SHADOW);
+
+ UpdateFlux();
+ UpdateButtons();
+ AdjustEditScript();
+}
+
+// Repositions all the editing controls.
+
+void CStudio::AdjustEditScript()
+{
+ CWindow* pw;
+ CEdit* edit;
+ CButton* button;
+ CGroup* group;
+ CSlider* slider;
+ CList* list;
+ FPOINT wpos, wdim, pos, dim, ppos, ddim;
+ float hList;
+
+ wpos = m_editActualPos;
+ wdim = m_editActualDim;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw != 0 )
+ {
+ pw->SetPos(wpos);
+ pw->SetDim(wdim);
+ wdim = pw->RetDim();
+ }
+
+ if ( m_bRunning ) hList = 80.0f/480.0f;
+ else hList = 20.0f/480.0f;
+
+ pos.x = wpos.x+0.01f;
+ pos.y = wpos.y+0.09f+hList;
+ dim.x = wdim.x-0.02f;
+ dim.y = wdim.y-0.22f-hList;
+ edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT);
+ if ( edit != 0 )
+ {
+ edit->SetPos(pos);
+ edit->SetDim(dim);
+ }
+
+ pos.x = wpos.x+0.01f;
+ pos.y = wpos.y+0.09f;
+ dim.x = wdim.x-0.02f;
+ dim.y = hList;
+ list = (CList*)pw->SearchControl(EVENT_STUDIO_LIST);
+ if ( list != 0 )
+ {
+ list->SetPos(pos);
+ list->SetDim(dim);
+ }
+
+ dim.x = 0.04f;
+ dim.y = 0.04f*1.5f;
+ dim.y = 25.0f/480.0f;
+
+ pos.y = wpos.y+wdim.y-dim.y-0.06f;
+ pos.x = wpos.x+0.01f;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_NEW);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x = wpos.x+0.05f;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_OPEN);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x = wpos.x+0.09f;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_SAVE);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x = wpos.x+0.14f;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_UNDO);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x = wpos.x+0.19f;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_CUT);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x = wpos.x+0.23f;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_COPY);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x = wpos.x+0.27f;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_PASTE);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x = wpos.x+0.32f;
+ slider = (CSlider*)pw->SearchControl(EVENT_STUDIO_SIZE);
+ if ( slider != 0 )
+ {
+ ppos = pos;
+ ddim.x = dim.x*0.7f;
+ ddim.y = dim.y;
+ ppos.y -= 3.0f/480.0f;
+ ddim.y += 6.0f/480.0f;
+ slider->SetPos(ppos);
+ slider->SetDim(ddim);
+ }
+ pos.x = wpos.x+0.36f;
+ group = (CGroup*)pw->SearchControl(EVENT_LABEL1);
+ if ( group != 0 )
+ {
+ group->SetPos(pos);
+ group->SetDim(dim);
+ }
+ pos.x = wpos.x+0.40f;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_TOOL);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x = wpos.x+0.44f;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_HELP);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+
+ pos.y = wpos.y+0.02f;
+ pos.x = wpos.x+0.01f;
+ dim.x = 80.0f/640.0f;
+ dim.y = 25.0f/480.0f;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_OK);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x = wpos.x+0.14f;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_CANCEL);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x = wpos.x+0.28f;
+ dim.x = dim.y*0.75f;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_COMPILE);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x = wpos.x+0.28f+dim.x*1;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_RUN);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x = wpos.x+0.28f+dim.x*2;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_REALTIME);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+ pos.x = wpos.x+0.28f+dim.x*3;
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_STEP);
+ if ( button != 0 )
+ {
+ button->SetPos(pos);
+ button->SetDim(dim);
+ }
+}
+
+// Ends edition of a program.
+
+BOOL CStudio::StopEditScript(BOOL bCancel)
+{
+ CWindow* pw;
+ CEdit* edit;
+ CButton* button;
+ char buffer[100];
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw == 0 ) return FALSE;
+
+ if ( !bCancel && !m_script->IsRunning() )
+ {
+ edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT);
+ if ( edit != 0 )
+ {
+ if ( !m_script->GetScript(edit) ) // compile
+ {
+ m_script->GetError(buffer);
+ SetInfoText(buffer, FALSE);
+ return FALSE;
+ }
+ }
+ }
+ m_script->SetStepMode(FALSE);
+
+ m_interface->DeleteControl(EVENT_WINDOW3);
+
+ button = (CButton*)m_interface->SearchControl(EVENT_BUTTON_QUIT);
+ if ( button != 0 )
+ {
+ button->SetState(STATE_VISIBLE);
+ }
+
+ if ( !m_bInitPause ) m_engine->SetPause(FALSE);
+ m_sound->MuteAll(FALSE);
+ m_main->SetEditLock(FALSE, TRUE);
+ m_camera->SetType(m_editCamera);
+ return TRUE;
+}
+
+// Specifies the message to display.
+// The messages are not clickable 8 seconds,
+// even if a message was clickable poster before.
+
+void CStudio::SetInfoText(char *text, BOOL bClickable)
+{
+ CWindow* pw;
+ CList* list;
+ char res[100];
+
+ if ( bClickable && m_fixInfoTextTime > 0.0f ) return;
+ if ( !bClickable ) m_fixInfoTextTime = 8.0f;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw == 0 ) return;
+
+ list = (CList*)pw->SearchControl(EVENT_STUDIO_LIST);
+ if ( list == 0 ) return;
+
+ list->Flush(); // just text
+ list->SetName(0, text);
+
+ if ( text[0] == 0 ) bClickable = FALSE;
+ list->SetSelectCap(bClickable);
+
+ if ( bClickable )
+ {
+ GetResource(RES_TEXT, RT_STUDIO_LISTTT, res);
+ list->SetTooltip(res);
+ list->SetState(STATE_ENABLE);
+ }
+ else
+ {
+ list->SetTooltip("");
+//? list->ClearState(STATE_ENABLE);
+ list->SetState(STATE_ENABLE, text[0] != 0);
+ }
+}
+
+
+// Changing the size of a editing program.
+
+void CStudio::ViewEditScript()
+{
+ CWindow* pw;
+ CEdit* edit;
+ POINT dim;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw == 0 ) return;
+
+ edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT);
+ if ( edit == 0 ) return;
+
+ dim = m_engine->RetDim();
+ edit->SetFontSize(m_main->RetFontSize()/(dim.x/640.0f));
+}
+
+
+// Updates the operating mode.
+
+void CStudio::UpdateFlux()
+{
+ if ( m_bRunning )
+ {
+#if 1
+ if ( m_bRealTime ) // run?
+ {
+ m_engine->SetPause(FALSE);
+ m_sound->MuteAll(FALSE);
+ }
+ else // step by step?
+ {
+ m_engine->SetPause(TRUE);
+ m_sound->MuteAll(TRUE);
+ }
+#else
+ m_engine->SetPause(FALSE);
+ m_sound->MuteAll(FALSE);
+#endif
+ }
+ else // stop?
+ {
+ m_engine->SetPause(TRUE);
+ m_sound->MuteAll(TRUE);
+ }
+}
+
+// Updates the buttons.
+
+void CStudio::UpdateButtons()
+{
+ CWindow* pw;
+ CEdit* edit;
+ CButton* button;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw == 0 ) return;
+
+ edit = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT);
+ if ( edit == 0 ) return;
+
+ if ( m_bRunning )
+ {
+ edit->SetIcon(1); // red background
+ edit->SetEditCap(FALSE); // just to see
+ edit->SetHiliteCap(TRUE);
+ }
+ else
+ {
+ edit->SetIcon(0); // standard background
+ edit->SetEditCap(TRUE);
+ edit->SetHiliteCap(TRUE);
+ }
+
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_COMPILE);
+ if ( button == 0 ) return;
+ button->SetState(STATE_ENABLE, !m_bRunning);
+
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_RUN);
+ if ( button == 0 ) return;
+ button->SetIcon(m_bRunning?8:21); // stop/run
+
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_REALTIME);
+ if ( button == 0 ) return;
+ button->SetIcon(m_bRealTime?64+22:64+21);
+ button->SetState(STATE_ENABLE, (!m_bRunning || !m_script->IsContinue()));
+
+ button = (CButton*)pw->SearchControl(EVENT_STUDIO_STEP);
+ if ( button == 0 ) return;
+ button->SetState(STATE_ENABLE, (m_bRunning && !m_bRealTime && !m_script->IsContinue()));
+}
+
+
+// Beginning of the display of a dialogue.
+
+void CStudio::StartDialog(StudioDialog type)
+{
+ CWindow* pw;
+ CButton* pb;
+ CCheck* pc;
+ CLabel* pla;
+ CList* pli;
+ CEdit* pe;
+ FPOINT pos, dim;
+ char name[100];
+
+ m_dialog = type;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW6);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW7);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW8);
+ if ( pw != 0 ) pw->ClearState(STATE_ENABLE);
+
+ if ( m_dialog == SD_OPEN ||
+ m_dialog == SD_SAVE )
+ {
+ pos = m_main->RetIOPos();
+ dim = m_main->RetIODim();
+ }
+//? pw = m_interface->CreateWindows(pos, dim, 8, EVENT_WINDOW9);
+ pw = m_interface->CreateWindows(pos, dim, m_dialog==SD_OPEN?14:13, EVENT_WINDOW9);
+ pw->SetState(STATE_SHADOW);
+ pw->SetMovable(TRUE);
+ pw->SetClosable(TRUE);
+ pw->SetMinDim(FPOINT(320.0f/640.0f, (121.0f+18.0f*4)/480.0f));
+ if ( m_dialog == SD_OPEN ) GetResource(RES_TEXT, RT_IO_OPEN, name);
+ if ( m_dialog == SD_SAVE ) GetResource(RES_TEXT, RT_IO_SAVE, name);
+ pw->SetName(name);
+
+ pos = FPOINT(0.0f, 0.0f);
+ dim = FPOINT(0.0f, 0.0f);
+
+ if ( m_dialog == SD_OPEN ||
+ m_dialog == SD_SAVE )
+ {
+ GetResource(RES_TEXT, RT_IO_LIST, name);
+ pla = pw->CreateLabel(pos, dim, 0, EVENT_DIALOG_LABEL1, name);
+ pla->SetJustif(1);
+
+ pli = pw->CreateList(pos, dim, 0, EVENT_DIALOG_LIST);
+ pli->SetState(STATE_SHADOW);
+
+ GetResource(RES_TEXT, RT_IO_NAME, name);
+ pla = pw->CreateLabel(pos, dim, 0, EVENT_DIALOG_LABEL2, name);
+ pla->SetJustif(1);
+
+ pe = pw->CreateEdit(pos, dim, 0, EVENT_DIALOG_EDIT);
+ pe->SetState(STATE_SHADOW);
+ if ( m_dialog == SD_SAVE )
+ {
+ pe->SetText(m_script->RetFilename());
+ }
+
+ GetResource(RES_TEXT, RT_IO_DIR, name);
+ pla = pw->CreateLabel(pos, dim, 0, EVENT_DIALOG_LABEL3, name);
+ pla->SetJustif(1);
+
+ pc = pw->CreateCheck(pos, dim, 0, EVENT_DIALOG_CHECK1);
+ GetResource(RES_TEXT, RT_IO_PRIVATE, name);
+ pc->SetName(name);
+ pc->SetState(STATE_SHADOW);
+#if _POLISH
+ pc->SetFontSize(8.0f);
+#endif
+
+ pc = pw->CreateCheck(pos, dim, 0, EVENT_DIALOG_CHECK2);
+ GetResource(RES_TEXT, RT_IO_PUBLIC, name);
+ pc->SetName(name);
+ pc->SetState(STATE_SHADOW);
+#if _POLISH
+ pc->SetFontSize(8.0f);
+#endif
+
+ pb = pw->CreateButton(pos, dim, -1, EVENT_DIALOG_OK);
+ pb->SetState(STATE_SHADOW);
+ if ( m_dialog == SD_OPEN ) GetResource(RES_TEXT, RT_IO_OPEN, name);
+ if ( m_dialog == SD_SAVE ) GetResource(RES_TEXT, RT_IO_SAVE, name);
+ pb->SetName(name);
+
+ pb = pw->CreateButton(pos, dim, -1, EVENT_DIALOG_CANCEL);
+ pb->SetState(STATE_SHADOW);
+ GetResource(RES_EVENT, EVENT_DIALOG_CANCEL, name);
+ pb->SetName(name);
+
+ AdjustDialog();
+ UpdateDialogList();
+ UpdateDialogPublic();
+ UpdateDialogAction();
+
+ pe->SetCursor(999, 0); // selects all
+ pe->SetFocus(TRUE);
+ }
+
+ m_main->SetSatComLock(TRUE); // impossible to use the SatCom
+}
+
+// End of the display of a dialogue.
+
+void CStudio::StopDialog()
+{
+ CWindow* pw;
+
+ if ( m_dialog == SD_NULL ) return;
+ m_dialog = SD_NULL;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW1);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW4);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW5);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW6);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW7);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW8);
+ if ( pw != 0 ) pw->SetState(STATE_ENABLE);
+
+ m_interface->DeleteControl(EVENT_WINDOW9);
+ m_main->SetSatComLock(FALSE); // possible to use the SatCom
+}
+
+// Adjust all controls of dialogue after a change in geometry.
+
+void CStudio::AdjustDialog()
+{
+ CWindow* pw;
+ CButton* pb;
+ CCheck* pc;
+ CLabel* pla;
+ CList* pli;
+ CEdit* pe;
+ FPOINT wpos, wdim, ppos, ddim;
+ int nli, nch;
+ char name[100];
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9);
+ if ( pw == 0 ) return;
+
+ wpos = pw->RetPos();
+ wdim = pw->RetDim();
+ pw->SetPos(wpos); // to move the buttons on the titlebar
+
+ if ( m_dialog == SD_OPEN ||
+ m_dialog == SD_SAVE )
+ {
+ ppos.x = wpos.x+10.0f/640.0f;
+ ppos.y = wpos.y+wdim.y-55.0f/480.0f;
+ ddim.x = wdim.x-20.0f/640.0f;
+ ddim.y = 20.0f/480.0f;
+ pla = (CLabel*)pw->SearchControl(EVENT_DIALOG_LABEL1);
+ if ( pla != 0 )
+ {
+ pla->SetPos(ppos);
+ pla->SetDim(ddim);
+ }
+
+ nli = (int)((wdim.y-120.0f/480.0f)/(18.0f/480.0f));
+ ddim.y = nli*18.0f/480.0f+9.0f/480.0f;
+ ppos.y = wpos.y+wdim.y-48.0f/480.0f-ddim.y;
+ pli = (CList*)pw->SearchControl(EVENT_DIALOG_LIST);
+ if ( pli != 0 )
+ {
+ pli->SetPos(ppos);
+ pli->SetDim(ddim);
+ pli->SetTabs(0, ddim.x-(50.0f+130.0f+16.0f)/640.0f);
+ pli->SetTabs(1, 50.0f/640.0f, -1);
+ pli->SetTabs(2, 130.0f/640.0f);
+//? pli->ShowSelect();
+ }
+
+ ppos.y = wpos.y+30.0f/480.0f;
+ ddim.x = 50.0f/640.0f;
+ ddim.y = 20.0f/480.0f;
+ pla = (CLabel*)pw->SearchControl(EVENT_DIALOG_LABEL2);
+ if ( pla != 0 )
+ {
+ pla->SetPos(ppos);
+ pla->SetDim(ddim);
+ }
+
+ ppos.x += 50.0f/640.0f;
+ ppos.y = wpos.y+36.0f/480.0f;
+ ddim.x = wdim.x-170.0f/640.0f;
+ pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT);
+ if ( pe != 0 )
+ {
+ pe->SetPos(ppos);
+ pe->SetDim(ddim);
+
+ nch = (int)((ddim.x*640.0f-22.0f)/8.0f);
+ pe->GetText(name, 100);
+ pe->SetMaxChar(nch);
+ name[nch] = 0; // truncates the text according to max
+ pe->SetText(name);
+ }
+
+ ppos.x = wpos.x+10.0f/640.0f;
+ ppos.y = wpos.y+5.0f/480.0f;
+ ddim.x = 50.0f/640.0f;
+ ddim.y = 16.0f/480.0f;
+ pla = (CLabel*)pw->SearchControl(EVENT_DIALOG_LABEL3);
+ if ( pla != 0 )
+ {
+ pla->SetPos(ppos);
+ pla->SetDim(ddim);
+ }
+
+ ppos.x += 50.0f/640.0f;
+ ppos.y = wpos.y+12.0f/480.0f;
+ ddim.x = 70.0f/640.0f;
+ pc = (CCheck*)pw->SearchControl(EVENT_DIALOG_CHECK1);
+ if ( pc != 0 )
+ {
+ pc->SetPos(ppos);
+ pc->SetDim(ddim);
+ }
+
+ ppos.x += 80.0f/640.0f;
+ pc = (CCheck*)pw->SearchControl(EVENT_DIALOG_CHECK2);
+ if ( pc != 0 )
+ {
+ pc->SetPos(ppos);
+ pc->SetDim(ddim);
+ }
+
+ ppos.x = wpos.x+wdim.x-100.0f/640.0f;
+ ppos.y = wpos.y+34.0f/480.0f;
+ ddim.x = 90.0f/640.0f;
+ ddim.y = 23.0f/480.0f;
+ pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK);
+ if ( pb != 0 )
+ {
+ pb->SetPos(ppos);
+ pb->SetDim(ddim);
+ }
+
+ ppos.y -= 26.0f/480.0f;
+ pb = (CButton*)pw->SearchControl(EVENT_DIALOG_CANCEL);
+ if ( pb != 0 )
+ {
+ pb->SetPos(ppos);
+ pb->SetDim(ddim);
+ }
+ }
+}
+
+// Management of the event of a dialogue.
+
+BOOL CStudio::EventDialog(const Event &event)
+{
+ CWindow* pw;
+ FPOINT wpos, wdim;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9);
+ if ( pw == 0 ) return FALSE;
+
+ if ( event.event == EVENT_WINDOW9 ) // window is moved?
+ {
+ wpos = pw->RetPos();
+ wdim = pw->RetDim();
+ m_main->SetIOPos(wpos);
+ m_main->SetIODim(wdim);
+ AdjustDialog();
+ }
+
+ if ( m_dialog == SD_OPEN ||
+ m_dialog == SD_SAVE )
+ {
+ if ( event.event == EVENT_DIALOG_LIST )
+ {
+ UpdateChangeList();
+ }
+ if ( event.event == EVENT_DIALOG_EDIT )
+ {
+ UpdateChangeEdit();
+ }
+
+ if ( event.event == EVENT_DIALOG_CHECK1 ) // private?
+ {
+ m_main->SetIOPublic(FALSE);
+ UpdateDialogPublic();
+ UpdateDialogList();
+ }
+ if ( event.event == EVENT_DIALOG_CHECK2 ) // public?
+ {
+ m_main->SetIOPublic(TRUE);
+ UpdateDialogPublic();
+ UpdateDialogList();
+ }
+ }
+
+ if ( event.event == EVENT_DIALOG_OK ||
+ (event.event == EVENT_KEYDOWN && event.param == VK_RETURN) )
+ {
+ if ( m_dialog == SD_OPEN )
+ {
+ if ( !ReadProgram() ) return TRUE;
+ }
+ if ( m_dialog == SD_SAVE )
+ {
+ if ( !WriteProgram() ) return TRUE;
+ }
+
+ StopDialog();
+ return TRUE;
+ }
+
+ if ( event.event == EVENT_DIALOG_CANCEL ||
+ (event.event == EVENT_KEYDOWN && event.param == VK_ESCAPE) ||
+ event.event == pw->RetEventMsgClose() )
+ {
+ StopDialog();
+ return TRUE;
+ }
+
+ return TRUE;
+}
+
+// Updates the name after a click in the list.
+
+void CStudio::UpdateChangeList()
+{
+ CWindow* pw;
+ CList* pl;
+ CEdit* pe;
+ char name[100];
+ char* p;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_DIALOG_LIST);
+ if ( pl == 0 ) return;
+ pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT);
+ if ( pe == 0 ) return;
+
+ strcpy(name, pl->RetName(pl->RetSelect()));
+ name[pe->RetMaxChar()] = 0; // truncates according lg max editable
+ p = strchr(name, '\t'); // seeks first tab
+ if ( p != 0 ) *p = 0;
+ pe->SetText(name);
+ pe->SetCursor(999, 0); // selects all
+ pe->SetFocus(TRUE);
+
+ UpdateDialogAction();
+}
+
+// Updates the list after a change in name.
+
+void CStudio::UpdateChangeEdit()
+{
+ CWindow* pw;
+ CList* pl;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_DIALOG_LIST);
+ if ( pl == 0 ) return;
+
+ pl->SetSelect(-1);
+
+ UpdateDialogAction();
+}
+
+// Updates the action button.
+
+void CStudio::UpdateDialogAction()
+{
+ CWindow* pw;
+ CEdit* pe;
+ CButton* pb;
+ char name[100];
+ int len, i;
+ BOOL bError;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9);
+ if ( pw == 0 ) return;
+ pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT);
+ if ( pe == 0 ) return;
+ pb = (CButton*)pw->SearchControl(EVENT_DIALOG_OK);
+ if ( pb == 0 ) return;
+
+ pe->GetText(name, 100);
+ len = strlen(name);
+ if ( len == 0 )
+ {
+ bError = TRUE;
+ }
+ else
+ {
+ bError = FALSE;
+ for ( i=0 ; i<len ; i++ )
+ {
+ if ( name[i] == '*' ||
+ name[i] == '?' ||
+ name[i] == ':' ||
+ name[i] == '<' ||
+ name[i] == '>' ||
+ name[i] == '"' ||
+ name[i] == '|' ||
+ name[i] == '/' ||
+ name[i] == '\\' ) bError = TRUE;
+ }
+ }
+
+ pb->SetState(STATE_ENABLE, !bError);
+}
+
+// Updates the buttons private/public.
+
+void CStudio::UpdateDialogPublic()
+{
+ CWindow* pw;
+ CCheck* pc;
+ CLabel* pl;
+ char name[100];
+ char dir[_MAX_FNAME];
+ char text[_MAX_FNAME+100];
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9);
+ if ( pw == 0 ) return;
+
+ pc = (CCheck*)pw->SearchControl(EVENT_DIALOG_CHECK1);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, !m_main->RetIOPublic());
+ }
+
+ pc = (CCheck*)pw->SearchControl(EVENT_DIALOG_CHECK2);
+ if ( pc != 0 )
+ {
+ pc->SetState(STATE_CHECK, m_main->RetIOPublic());
+ }
+
+ pl = (CLabel*)pw->SearchControl(EVENT_DIALOG_LABEL1);
+ if ( pl != 0 )
+ {
+ GetResource(RES_TEXT, RT_IO_LIST, name);
+ SearchDirectory(dir, FALSE);
+ sprintf(text, name, dir);
+ pl->SetName(text, FALSE);
+ }
+}
+
+// Fills the list with all programs saved.
+
+void CStudio::UpdateDialogList()
+{
+ CWindow* pw;
+ CList* pl;
+ long hFile;
+ struct _finddata_t fileBuffer;
+ struct _finddata_t* listBuffer;
+ BOOL bDo;
+ char dir[_MAX_FNAME];
+ char temp[_MAX_FNAME];
+ int nbFilenames, i;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9);
+ if ( pw == 0 ) return;
+ pl = (CList*)pw->SearchControl(EVENT_DIALOG_LIST);
+ if ( pl == 0 ) return;
+ pl->Flush();
+
+ nbFilenames = 0;
+ listBuffer = (_finddata_t*)malloc(sizeof(_finddata_t)*1000);
+
+ SearchDirectory(dir, FALSE);
+ strcat(dir, "*"); // list all
+ hFile = _findfirst(dir, &fileBuffer);
+ if ( hFile != -1 )
+ {
+ do
+ {
+ if ( (fileBuffer.attrib & _A_SUBDIR) == 0 )
+ {
+ listBuffer[nbFilenames++] = fileBuffer;
+ }
+ }
+ while ( _findnext(hFile, &fileBuffer) == 0 && nbFilenames < 1000 );
+ }
+ do // sorts all names:
+ {
+ bDo = FALSE;
+ for ( i=0 ; i<nbFilenames-1 ; i++ )
+ {
+ if ( strcmp(listBuffer[i].name, listBuffer[i+1].name) > 0 )
+ {
+ fileBuffer = listBuffer[i]; // exchange i and i +1
+ listBuffer[i] = listBuffer[i+1];
+ listBuffer[i+1] = fileBuffer;
+ bDo = TRUE;
+ }
+ }
+ }
+ while ( bDo );
+
+ for ( i=0 ; i<nbFilenames ; i++ )
+ {
+ TimeToAscii(listBuffer[i].time_write, dir);
+ sprintf(temp, "%s\t%d \t%s", listBuffer[i].name, listBuffer[i].size, dir);
+ pl->SetName(i, temp);
+ }
+
+ free(listBuffer);
+}
+
+// Constructs the name of the folder or open/save.
+// If the folder does not exist, it will be created.
+
+void CStudio::SearchDirectory(char *dir, BOOL bCreate)
+{
+ if ( m_main->RetIOPublic() )
+ {
+ sprintf(dir, "%s\\", m_main->RetPublicDir());
+ }
+ else
+ {
+ sprintf(dir, "%s\\%s\\Program\\", m_main->RetSavegameDir(), m_main->RetGamerName());
+ }
+
+ if ( bCreate )
+ {
+ _mkdir(dir); // if does not exist yet!
+ }
+}
+
+// Reads a new program.
+
+BOOL CStudio::ReadProgram()
+{
+ CWindow* pw;
+ CEdit* pe;
+ char filename[100];
+ char dir[100];
+ char* p;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9);
+ if ( pw == 0 ) return FALSE;
+
+ pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT);
+ if ( pe == 0 ) return FALSE;
+ pe->GetText(filename, 100);
+ if ( filename[0] == 0 ) return FALSE;
+
+ p = strstr(filename, ".txt");
+ if ( p == 0 || p != filename+strlen(filename)-4 )
+ {
+ strcat(filename, ".txt");
+ }
+ SearchDirectory(dir, TRUE);
+ strcat(dir, filename);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw == 0 ) return FALSE;
+ pe = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT);
+ if ( pe == 0 ) return FALSE;
+
+ if ( !pe->ReadText(dir) ) return FALSE;
+
+ m_script->SetFilename(filename);
+ ColorizeScript(pe);
+ return TRUE;
+}
+
+// Writes the current program.
+
+BOOL CStudio::WriteProgram()
+{
+ CWindow* pw;
+ CEdit* pe;
+ char filename[100];
+ char dir[100];
+ char* p;
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW9);
+ if ( pw == 0 ) return FALSE;
+
+ pe = (CEdit*)pw->SearchControl(EVENT_DIALOG_EDIT);
+ if ( pe == 0 ) return FALSE;
+ pe->GetText(filename, 100);
+ if ( filename[0] == 0 ) return FALSE;
+
+ p = strstr(filename, ".txt");
+ if ( p == 0 || p != filename+strlen(filename)-4 )
+ {
+ strcat(filename, ".txt");
+ }
+ SearchDirectory(dir, TRUE);
+ strcat(dir, filename);
+
+ pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW3);
+ if ( pw == 0 ) return FALSE;
+ pe = (CEdit*)pw->SearchControl(EVENT_STUDIO_EDIT);
+ if ( pe == 0 ) return FALSE;
+
+ if ( !pe->WriteText(dir) ) return FALSE;
+
+ m_script->SetFilename(filename);
+ return TRUE;
+}
+
diff --git a/src/ui/studio.h b/src/ui/studio.h
new file mode 100644
index 0000000..a19bedd
--- /dev/null
+++ b/src/ui/studio.h
@@ -0,0 +1,117 @@
+// * 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/.
+
+// studio.h
+
+#ifndef _STUDIO_H_
+#define _STUDIO_H_
+
+
+#include "object.h"
+#include "script.h"
+
+
+class CInstanceManager;
+class CD3DEngine;
+class CEvent;
+class CRobotMain;
+class CCamera;
+class CSound;
+class CInterface;
+class CScript;
+class CList;
+class CEdit;
+
+
+
+enum StudioDialog
+{
+ SD_NULL,
+ SD_OPEN,
+ SD_SAVE,
+ SD_FIND,
+ SD_REPLACE,
+};
+
+
+
+class CStudio
+{
+public:
+ CStudio(CInstanceManager* iMan);
+ ~CStudio();
+
+ BOOL EventProcess(const Event &event);
+
+ void StartEditScript(CScript *script, char* name, int rank);
+ BOOL StopEditScript(BOOL bCancel);
+
+protected:
+ BOOL EventFrame(const Event &event);
+ void SearchToken(CEdit* edit);
+ void ColorizeScript(CEdit* edit);
+ void AdjustEditScript();
+ void SetInfoText(char *text, BOOL bClickable);
+ void ViewEditScript();
+ void UpdateFlux();
+ void UpdateButtons();
+
+ void StartDialog(StudioDialog type);
+ void StopDialog();
+ void AdjustDialog();
+ BOOL EventDialog(const Event &event);
+ void UpdateChangeList();
+ void UpdateChangeEdit();
+ void UpdateDialogAction();
+ void UpdateDialogPublic();
+ void UpdateDialogList();
+ void SearchDirectory(char *dir, BOOL bCreate);
+ BOOL ReadProgram();
+ BOOL WriteProgram();
+
+protected:
+ CInstanceManager* m_iMan;
+ CD3DEngine* m_engine;
+ CEvent* m_event;
+ CRobotMain* m_main;
+ CCamera* m_camera;
+ CSound* m_sound;
+ CInterface* m_interface;
+
+ int m_rank;
+ CScript* m_script;
+
+ BOOL m_bEditMaximized;
+ BOOL m_bEditMinimized;
+
+ CameraType m_editCamera;
+ FPOINT m_editActualPos;
+ FPOINT m_editActualDim;
+ FPOINT m_editFinalPos;
+ FPOINT m_editFinalDim;
+
+ float m_time;
+ float m_fixInfoTextTime;
+ BOOL m_bRunning;
+ BOOL m_bRealTime;
+ BOOL m_bInitPause;
+ char m_helpFilename[100];
+
+ StudioDialog m_dialog;
+};
+
+
+#endif //_STUDIO_H_
diff --git a/src/ui/target.cpp b/src/ui/target.cpp
new file mode 100644
index 0000000..4a6ae43
--- /dev/null
+++ b/src/ui/target.cpp
@@ -0,0 +1,285 @@
+// * 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/.
+
+// target.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "iman.h"
+#include "robotmain.h"
+#include "object.h"
+#include "restext.h"
+#include "target.h"
+
+
+
+
+// Object's constructor.
+
+CTarget::CTarget(CInstanceManager* iMan) : CControl(iMan)
+{
+}
+
+// Object's destructor.
+
+CTarget::~CTarget()
+{
+}
+
+
+// Creates a new button.
+
+BOOL CTarget::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ CControl::Create(pos, dim, icon, eventMsg);
+
+ return TRUE;
+}
+
+
+// Management of an event.
+
+BOOL CTarget::EventProcess(const Event &event)
+{
+#if 0
+ if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE;
+ if ( m_state & STATE_DEAD ) return TRUE;
+
+ CControl::EventProcess(event);
+
+ if ( event.event == EVENT_MOUSEMOVE )
+ {
+ if ( CControl::Detect(event.pos) )
+ {
+ m_engine->SetMouseType(D3DMOUSETARGET);
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ return FALSE;
+ }
+ }
+
+ if ( event.event == EVENT_LBUTTONDOWN &&
+ (m_state & STATE_VISIBLE) &&
+ (m_state & STATE_ENABLE) )
+ {
+ if ( CControl::Detect(event.pos) )
+ {
+ Event newEvent = event;
+ newEvent.event = EVENT_OBJECT_FIRE;
+ m_event->AddEvent(newEvent);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+#else
+ CObject* pObj;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return TRUE;
+ if ( m_state & STATE_DEAD ) return TRUE;
+
+ CControl::EventProcess(event);
+
+ if ( event.event == EVENT_MOUSEMOVE )
+ {
+ m_main->SetFriendAim(FALSE);
+
+ if ( CControl::Detect(event.pos) )
+ {
+ pObj = DetectFriendObject(event.pos);
+ if ( pObj == 0 )
+ {
+ m_engine->SetMouseType(D3DMOUSETARGET);
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ return FALSE;
+ }
+ else
+ {
+ m_main->SetFriendAim(TRUE);
+ m_engine->SetMouseType(D3DMOUSENORM);
+ }
+ }
+ }
+
+ if ( event.event == EVENT_LBUTTONDOWN &&
+ (m_state & STATE_VISIBLE) &&
+ (m_state & STATE_ENABLE) )
+ {
+ if ( CControl::Detect(event.pos) )
+ {
+ if ( !m_main->RetFriendAim() )
+ {
+ Event newEvent = event;
+ newEvent.event = EVENT_OBJECT_FIRE;
+ m_event->AddEvent(newEvent);
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+#endif
+}
+
+
+// Draws button.
+
+void CTarget::Draw()
+{
+ // It is completely invisible!
+}
+
+
+// Returns the tooltip.
+
+BOOL CTarget::GetTooltip(FPOINT pos, char* name)
+{
+#if 0
+ if ( (m_state&STATE_VISIBLE) && Detect(pos) ) // in the window?
+ {
+ strcpy(name, m_tooltip);
+ return TRUE; // does not detect objects below!
+ }
+
+ return FALSE;
+#else
+//? CObject* pObj;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return FALSE;
+
+ if ( (m_state&STATE_VISIBLE) && Detect(pos) ) // in the window?
+ {
+//? pObj = DetectFriendObject(pos);
+//? if ( pObj == 0 )
+ if ( !m_main->RetFriendAim() )
+ {
+ strcpy(name, m_tooltip);
+ return TRUE; // does not detect objects below!
+ }
+ }
+
+ return FALSE;
+#endif
+}
+
+
+// Detects the object aimed by the mouse.
+
+CObject* CTarget::DetectFriendObject(FPOINT pos)
+{
+ ObjectType type;
+ CObject *pObj, *pTarget;
+ int objRank, i, j, rank;
+
+ objRank = m_engine->DetectObject(pos);
+
+ for ( i=0 ; i<1000000 ; i++ )
+ {
+ pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
+ if ( pObj == 0 ) break;
+
+ if ( !pObj->RetActif() ) continue;
+ if ( pObj->RetProxyActivate() ) continue;
+ if ( pObj->RetSelect() ) continue;
+
+ pTarget = 0;
+ type = pObj->RetType();
+ if ( type == OBJECT_DERRICK ||
+ type == OBJECT_FACTORY ||
+ type == OBJECT_REPAIR ||
+ type == OBJECT_DESTROYER ||
+ type == OBJECT_STATION ||
+ type == OBJECT_CONVERT ||
+ type == OBJECT_TOWER ||
+ type == OBJECT_RESEARCH ||
+ type == OBJECT_RADAR ||
+ type == OBJECT_INFO ||
+ type == OBJECT_ENERGY ||
+ type == OBJECT_LABO ||
+ type == OBJECT_NUCLEAR ||
+ type == OBJECT_PARA ||
+ type == OBJECT_SAFE ||
+ type == OBJECT_HUSTON ||
+ type == OBJECT_HUMAN ||
+ type == OBJECT_TECH ||
+ type == OBJECT_TOTO ||
+ type == OBJECT_MOBILEfa ||
+ type == OBJECT_MOBILEta ||
+ type == OBJECT_MOBILEwa ||
+ type == OBJECT_MOBILEia ||
+ type == OBJECT_MOBILEfc ||
+ type == OBJECT_MOBILEtc ||
+ type == OBJECT_MOBILEwc ||
+ type == OBJECT_MOBILEic ||
+ type == OBJECT_MOBILEfi ||
+ type == OBJECT_MOBILEti ||
+ type == OBJECT_MOBILEwi ||
+ type == OBJECT_MOBILEii ||
+ type == OBJECT_MOBILEfs ||
+ type == OBJECT_MOBILEts ||
+ type == OBJECT_MOBILEws ||
+ type == OBJECT_MOBILEis ||
+ type == OBJECT_MOBILErt ||
+ type == OBJECT_MOBILErc ||
+ type == OBJECT_MOBILErr ||
+ type == OBJECT_MOBILErs ||
+ type == OBJECT_MOBILEsa ||
+ type == OBJECT_MOBILEft ||
+ type == OBJECT_MOBILEtt ||
+ type == OBJECT_MOBILEwt ||
+ type == OBJECT_MOBILEit ||
+ type == OBJECT_MOBILEdr )
+ {
+ pTarget = pObj;
+ }
+ else if ( (type == OBJECT_POWER ||
+ type == OBJECT_ATOMIC ) &&
+ pObj->RetTruck() != 0 ) // battery used?
+ {
+ pTarget = pObj->RetTruck();
+ if ( pTarget->RetType() == OBJECT_MOBILEtg )
+ {
+ pTarget = 0;
+ }
+ }
+
+ for ( j=0 ; j<OBJECTMAXPART ; j++ )
+ {
+ rank = pObj->RetObjectRank(j);
+ if ( rank == -1 ) continue;
+ if ( rank != objRank ) continue;
+ return pTarget;
+ }
+ }
+ return 0;
+}
+
diff --git a/src/ui/target.h b/src/ui/target.h
new file mode 100644
index 0000000..632e411
--- /dev/null
+++ b/src/ui/target.h
@@ -0,0 +1,50 @@
+// * 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/.
+
+// target.h
+
+#ifndef _TARGET_H_
+#define _TARGET_H_
+
+
+#include "control.h"
+
+
+class CD3DEngine;
+class CObject;
+
+
+
+class CTarget : public CControl
+{
+public:
+ CTarget(CInstanceManager* iMan);
+ ~CTarget();
+
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+
+ BOOL EventProcess(const Event &event);
+ void Draw();
+ BOOL GetTooltip(FPOINT pos, char* name);
+
+protected:
+ CObject* DetectFriendObject(FPOINT pos);
+
+protected:
+};
+
+
+#endif //_TARGET_H_
diff --git a/src/ui/window.cpp b/src/ui/window.cpp
new file mode 100644
index 0000000..c42493a
--- /dev/null
+++ b/src/ui/window.cpp
@@ -0,0 +1,1622 @@
+// * 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/.
+
+// window.cpp
+
+#define STRICT
+#define D3D_OVERLOADS
+
+#include <windows.h>
+#include <stdio.h>
+#include <d3d.h>
+
+#include "struct.h"
+#include "d3dengine.h"
+#include "language.h"
+#include "math3d.h"
+#include "event.h"
+#include "misc.h"
+#include "restext.h"
+#include "iman.h"
+#include "button.h"
+#include "color.h"
+#include "check.h"
+#include "key.h"
+#include "group.h"
+#include "image.h"
+#include "label.h"
+#include "edit.h"
+#include "editvalue.h"
+#include "scroll.h"
+#include "slider.h"
+#include "list.h"
+#include "shortcut.h"
+#include "map.h"
+#include "gauge.h"
+#include "compass.h"
+#include "target.h"
+#include "text.h"
+#include "window.h"
+
+
+
+
+// Object's constructor.
+
+CWindow::CWindow(CInstanceManager* iMan) : CControl(iMan)
+{
+ int i;
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ m_table[i] = 0;
+ }
+
+ m_bTrashEvent = TRUE;
+ m_bMaximized = FALSE;
+ m_bMinimized = FALSE;
+ m_bFixed = FALSE;
+
+ m_minDim = FPOINT(0.0f, 0.0f);
+ m_maxDim = FPOINT(1.0f, 1.0f);
+
+ m_buttonReduce = 0;
+ m_buttonFull = 0;
+ m_buttonClose = 0;
+
+ m_bMovable = FALSE;
+ m_bRedim = FALSE;
+ m_bClosable = FALSE;
+ m_bCapture = FALSE;
+
+ m_fontStretch = NORMSTRETCH*1.2f;
+}
+
+// Object's destructor.
+
+CWindow::~CWindow()
+{
+ Flush();
+}
+
+
+// Purge all the controls.
+
+void CWindow::Flush()
+{
+ int i;
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] != 0 )
+ {
+ delete m_table[i];
+ m_table[i] = 0;
+ }
+ }
+
+ if ( m_buttonReduce != 0 )
+ {
+ delete m_buttonReduce;
+ m_buttonReduce = 0;
+ }
+
+ if ( m_buttonFull != 0 )
+ {
+ delete m_buttonFull;
+ m_buttonFull = 0;
+ }
+
+ if ( m_buttonClose != 0 )
+ {
+ delete m_buttonClose;
+ m_buttonClose = 0;
+ }
+}
+
+
+// Creates a new window.
+
+BOOL CWindow::Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ CControl::Create(pos, dim, icon, eventMsg);
+ return TRUE;
+}
+
+
+// Creates a new button.
+
+CButton* CWindow::CreateButton(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CButton* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CButton(m_iMan);
+ pc = (CButton*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new button.
+
+CColor* CWindow::CreateColor(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CColor* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CColor(m_iMan);
+ pc = (CColor*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new button.
+
+CCheck* CWindow::CreateCheck(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CCheck* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CCheck(m_iMan);
+ pc = (CCheck*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new button.
+
+CKey* CWindow::CreateKey(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CKey* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CKey(m_iMan);
+ pc = (CKey*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new button.
+
+CGroup* CWindow::CreateGroup(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CGroup* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CGroup(m_iMan);
+ pc = (CGroup*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new button.
+
+CImage* CWindow::CreateImage(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CImage* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CImage(m_iMan);
+ pc = (CImage*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new label.
+
+CLabel* CWindow::CreateLabel(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg,
+ char *name)
+{
+ CLabel* pc;
+ char* p;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CLabel(m_iMan);
+ pc = (CLabel*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+
+ p = strchr(name, '\\');
+ if ( p == 0 )
+ {
+ pc->SetName(name);
+ }
+ else
+ {
+ char text[100];
+ strncpy(text, name, 100);
+ text[100-1] = 0;
+ if ( p-name < 100 )
+ {
+ text[p-name] = 0; // deletes text after "\\" (tooltip)
+ }
+ pc->SetName(text);
+ }
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new editable pave.
+
+CEdit* CWindow::CreateEdit(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CEdit* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CEdit(m_iMan);
+ pc = (CEdit*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new editable pave.
+
+CEditValue* CWindow::CreateEditValue(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CEditValue* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CEditValue(m_iMan);
+ pc = (CEditValue*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new elevator.
+
+CScroll* CWindow::CreateScroll(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CScroll* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CScroll(m_iMan);
+ pc = (CScroll*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new cursor.
+
+CSlider* CWindow::CreateSlider(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CSlider* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CSlider(m_iMan);
+ pc = (CSlider*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new list.
+
+CList* CWindow::CreateList(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg,
+ float expand)
+{
+ CList* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CList(m_iMan);
+ pc = (CList*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg, expand);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new shortcut.
+
+CShortcut* CWindow::CreateShortcut(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CShortcut* ps;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CShortcut(m_iMan);
+ ps = (CShortcut*)m_table[i];
+ ps->Create(pos, dim, icon, eventMsg);
+ return ps;
+ }
+ }
+ return 0;
+}
+
+// Creates a new card.
+
+CMap* CWindow::CreateMap(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CMap* pm;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CMap(m_iMan);
+ pm = (CMap*)m_table[i];
+ pm->Create(pos, dim, icon, eventMsg);
+ return pm;
+ }
+ }
+ return 0;
+}
+
+// Creates a new gauge.
+
+CGauge* CWindow::CreateGauge(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CGauge* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CGauge(m_iMan);
+ pc = (CGauge*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new compass.
+
+CCompass* CWindow::CreateCompass(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CCompass* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CCompass(m_iMan);
+ pc = (CCompass*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Creates a new target.
+
+CTarget* CWindow::CreateTarget(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg)
+{
+ CTarget* pc;
+ int i;
+
+ if ( eventMsg == EVENT_NULL ) eventMsg = GetUniqueEventMsg();
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] == 0 )
+ {
+ m_table[i] = new CTarget(m_iMan);
+ pc = (CTarget*)m_table[i];
+ pc->Create(pos, dim, icon, eventMsg);
+ return pc;
+ }
+ }
+ return 0;
+}
+
+// Removes a control.
+
+BOOL CWindow::DeleteControl(EventMsg eventMsg)
+{
+ int i;
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] != 0 )
+ {
+ if ( eventMsg == m_table[i]->RetEventMsg() )
+ {
+ delete m_table[i];
+ m_table[i] = 0;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+// Gives a control.
+
+CControl* CWindow::SearchControl(EventMsg eventMsg)
+{
+ int i;
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] != 0 )
+ {
+ if ( eventMsg == m_table[i]->RetEventMsg() )
+ {
+ return m_table[i];
+ }
+ }
+ }
+ return 0;
+}
+
+
+// Makes the tooltip binds to the window.
+
+BOOL CWindow::GetTooltip(FPOINT pos, char* name)
+{
+ int i;
+
+ for ( i=MAXWINDOW-1 ; i>=0 ; i-- )
+ {
+ if ( m_table[i] != 0 )
+ {
+ if ( m_table[i]->GetTooltip(pos, name) )
+ {
+ return TRUE;
+ }
+ }
+ }
+
+ if ( m_buttonClose != 0 &&
+ m_buttonClose->GetTooltip(pos, name) )
+ {
+ return TRUE;
+ }
+ if ( m_buttonFull != 0 &&
+ m_buttonFull->GetTooltip(pos, name) )
+ {
+ return TRUE;
+ }
+ if ( m_buttonReduce != 0 &&
+ m_buttonReduce->GetTooltip(pos, name) )
+ {
+ return TRUE;
+ }
+
+ if ( Detect(pos) ) // in the window?
+ {
+ strcpy(name, m_tooltip);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+// Specifies the name for the title bar.
+
+void CWindow::SetName(char* name)
+{
+ CButton* pc;
+ BOOL bAdjust;
+
+ CControl::SetName(name);
+
+ if ( m_buttonReduce != 0 )
+ {
+ delete m_buttonReduce;
+ m_buttonReduce = 0;
+ }
+
+ if ( m_buttonFull != 0 )
+ {
+ delete m_buttonFull;
+ m_buttonFull = 0;
+ }
+
+ if ( m_buttonClose != 0 )
+ {
+ delete m_buttonClose;
+ m_buttonClose = 0;
+ }
+
+ bAdjust = FALSE;
+
+ if ( m_name[0] != 0 && m_bRedim ) // title bar exists?
+ {
+ m_buttonReduce = new CButton(m_iMan);
+ pc = (CButton*)m_buttonReduce;
+ pc->Create(m_pos, m_dim, 0, EVENT_NULL);
+
+ m_buttonFull = new CButton(m_iMan);
+ pc = (CButton*)m_buttonFull;
+ pc->Create(m_pos, m_dim, 0, EVENT_NULL);
+
+ bAdjust = TRUE;
+ }
+
+ if ( m_name[0] != 0 && m_bClosable ) // title bar exists?
+ {
+ m_buttonClose = new CButton(m_iMan);
+ pc = (CButton*)m_buttonClose;
+ pc->Create(m_pos, m_dim, 0, EVENT_NULL);
+
+ bAdjust = TRUE;
+ }
+
+ if ( bAdjust )
+ {
+ AdjustButtons();
+ }
+
+ MoveAdjust();
+}
+
+
+void CWindow::SetPos(FPOINT pos)
+{
+ CControl::SetPos(pos);
+ MoveAdjust();
+}
+
+void CWindow::SetDim(FPOINT dim)
+{
+ if ( dim.x < m_minDim.x ) dim.x = m_minDim.x;
+ if ( dim.x > m_maxDim.x ) dim.x = m_maxDim.x;
+ if ( dim.y < m_minDim.y ) dim.y = m_minDim.y;
+ if ( dim.y > m_maxDim.y ) dim.y = m_maxDim.y;
+
+ CControl::SetDim(dim);
+ MoveAdjust();
+}
+
+void CWindow::MoveAdjust()
+{
+ FPOINT pos, dim;
+ float h, offset;
+
+ h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType);
+ dim.y = h*1.2f;
+ dim.x = dim.y*0.75f;
+
+ if ( m_buttonClose != 0 )
+ {
+ pos.x = m_pos.x+m_dim.x-0.01f-dim.x;
+ pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f;
+ m_buttonClose->SetPos(pos);
+ m_buttonClose->SetDim(dim);
+ offset = dim.x*1.0f;
+ }
+ else
+ {
+ offset = 0.0f;
+ }
+
+ if ( m_buttonFull != 0 )
+ {
+ pos.x = m_pos.x+m_dim.x-0.01f-dim.x-offset;
+ pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f;
+ m_buttonFull->SetPos(pos);
+ m_buttonFull->SetDim(dim);
+ }
+
+ if ( m_buttonReduce != 0 )
+ {
+ pos.x = m_pos.x+m_dim.x-0.01f-dim.x*2.0f-offset;
+ pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f;
+ m_buttonReduce->SetPos(pos);
+ m_buttonReduce->SetDim(dim);
+ }
+}
+
+
+void CWindow::SetMinDim(FPOINT dim)
+{
+ m_minDim = dim;
+}
+
+void CWindow::SetMaxDim(FPOINT dim)
+{
+ m_maxDim = dim;
+}
+
+FPOINT CWindow::RetMinDim()
+{
+ return m_minDim;
+}
+
+FPOINT CWindow::RetMaxDim()
+{
+ return m_maxDim;
+}
+
+
+// Indicates whether the window is moved.
+
+void CWindow::SetMovable(BOOL bMode)
+{
+ m_bMovable = bMode;
+}
+
+BOOL CWindow::RetMovable()
+{
+ return m_bMovable;
+}
+
+
+// Management of the presence of minimize/maximize buttons.
+
+void CWindow::SetRedim(BOOL bMode)
+{
+ m_bRedim = bMode;
+}
+
+BOOL CWindow::RetRedim()
+{
+ return m_bRedim;
+}
+
+
+// Management of the presence of the close button.
+
+void CWindow::SetClosable(BOOL bMode)
+{
+ m_bClosable = bMode;
+}
+
+BOOL CWindow::RetClosable()
+{
+ return m_bClosable;
+}
+
+
+void CWindow::SetMaximized(BOOL bMaxi)
+{
+ m_bMaximized = bMaxi;
+ AdjustButtons();
+}
+
+BOOL CWindow::RetMaximized()
+{
+ return m_bMaximized;
+}
+
+void CWindow::SetMinimized(BOOL bMini)
+{
+ m_bMinimized = bMini;
+ AdjustButtons();
+}
+
+BOOL CWindow::RetMinimized()
+{
+ return m_bMinimized;
+}
+
+void CWindow::SetFixed(BOOL bFix)
+{
+ m_bFixed = bFix;
+}
+
+BOOL CWindow::RetFixed()
+{
+ return m_bFixed;
+}
+
+
+// Adjusts the buttons in the title bar.
+
+void CWindow::AdjustButtons()
+{
+ char res[100];
+
+ if ( m_buttonFull != 0 )
+ {
+ if ( m_bMaximized )
+ {
+ m_buttonFull->SetIcon(54);
+ GetResource(RES_TEXT, RT_WINDOW_STANDARD, res);
+ m_buttonFull->SetTooltip(res);
+ }
+ else
+ {
+ m_buttonFull->SetIcon(52);
+ GetResource(RES_TEXT, RT_WINDOW_MAXIMIZED, res);
+ m_buttonFull->SetTooltip(res);
+ }
+ }
+
+ if ( m_buttonReduce != 0 )
+ {
+ if ( m_bMinimized )
+ {
+ m_buttonReduce->SetIcon(54);
+ GetResource(RES_TEXT, RT_WINDOW_STANDARD, res);
+ m_buttonReduce->SetTooltip(res);
+ }
+ else
+ {
+ m_buttonReduce->SetIcon(51);
+ GetResource(RES_TEXT, RT_WINDOW_MINIMIZED, res);
+ m_buttonReduce->SetTooltip(res);
+ }
+ }
+
+ if ( m_buttonClose != 0 )
+ {
+ m_buttonClose->SetIcon(11); // x
+ GetResource(RES_TEXT, RT_WINDOW_CLOSE, res);
+ m_buttonClose->SetTooltip(res);
+ }
+}
+
+
+void CWindow::SetTrashEvent(BOOL bTrash)
+{
+ m_bTrashEvent = bTrash;
+}
+
+BOOL CWindow::RetTrashEvent()
+{
+ return m_bTrashEvent;
+}
+
+
+// Returns the message from the button "reduce".
+
+EventMsg CWindow::RetEventMsgReduce()
+{
+ if ( m_buttonReduce == 0 ) return EVENT_NULL;
+ return m_buttonReduce->RetEventMsg();
+}
+
+// Returns the message from the button "full".
+
+EventMsg CWindow::RetEventMsgFull()
+{
+ if ( m_buttonFull == 0 ) return EVENT_NULL;
+ return m_buttonFull->RetEventMsg();
+}
+
+// Returns the message from the button "close".
+
+EventMsg CWindow::RetEventMsgClose()
+{
+ if ( m_buttonClose == 0 ) return EVENT_NULL;
+ return m_buttonClose->RetEventMsg();
+}
+
+
+// Detects whether the mouse is in an edge of the window, to resize it.
+// Bit returns: 0 = left, 1 = down, 2 = right, 3 = up, 1 = all.
+
+int CWindow::BorderDetect(FPOINT pos)
+{
+ FPOINT dim;
+ float h;
+ int flags;
+
+ if ( m_bMaximized || m_bMinimized || m_bFixed ) return 0;
+
+ flags = 0;
+ if ( pos.x < m_pos.x+0.030f )
+ {
+ flags |= (1<<0);
+ }
+ if ( pos.y < m_pos.y+0.020f )
+ {
+ flags |= (1<<1);
+ }
+ if ( pos.x > m_pos.x+m_dim.x-0.030f )
+ {
+ flags |= (1<<2);
+ }
+ if ( pos.y > m_pos.y+m_dim.y-0.020f )
+ {
+ flags |= (1<<3);
+ }
+
+ if ( pos.x > m_pos.x+ 0.015f &&
+ pos.x < m_pos.x+m_dim.x-0.015f &&
+ pos.y > m_pos.y+ 0.010f &&
+ pos.y < m_pos.y+m_dim.y-0.010f )
+ {
+ flags = 0;
+ }
+
+ if ( flags == 0 )
+ {
+ h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType);
+ dim.y = h*1.2f;
+ dim.x = dim.y*0.75f;
+ if ( pos.x < m_pos.x+m_dim.x-0.01f-dim.x*3.0f &&
+ pos.y >= m_pos.y+m_dim.y-0.01f-h*1.2f )
+ {
+ flags = -1;
+ }
+ }
+
+ return flags;
+}
+
+// Management of an event.
+
+BOOL CWindow::EventProcess(const Event &event)
+{
+ FPOINT pos;
+ int i, flags;
+
+ if ( event.event == EVENT_MOUSEMOVE )
+ {
+ if ( m_bCapture )
+ {
+ m_engine->SetMouseType(m_pressMouse);
+ }
+ else
+ {
+ m_pressMouse = D3DMOUSENORM;
+
+ if ( m_name[0] != 0 && m_bMovable && // title bar?
+ Detect(event.pos) )
+ {
+ flags = BorderDetect(event.pos);
+ if ( flags == -1 )
+ {
+ m_pressMouse = D3DMOUSEMOVE; // +
+ }
+ else if ( ((flags & (1<<0)) && (flags & (1<<3))) ||
+ ((flags & (1<<1)) && (flags & (1<<2))) )
+ {
+ m_pressMouse = D3DMOUSEMOVEI; // \ //
+ }
+ else if ( ((flags & (1<<0)) && (flags & (1<<1))) ||
+ ((flags & (1<<2)) && (flags & (1<<3))) )
+ {
+ m_pressMouse = D3DMOUSEMOVED; // /
+ }
+ else if ( (flags & (1<<0)) || (flags & (1<<2)) )
+ {
+ m_pressMouse = D3DMOUSEMOVEH; // -
+ }
+ else if ( (flags & (1<<1)) || (flags & (1<<3)) )
+ {
+ m_pressMouse = D3DMOUSEMOVEV; // |
+ }
+ }
+
+ if ( m_pressMouse != D3DMOUSENORM )
+ {
+ m_engine->SetMouseType(m_pressMouse);
+ }
+ }
+ }
+
+ if ( !m_bCapture )
+ {
+ for ( i=MAXWINDOW-1 ; i>=0 ; i-- )
+ {
+ if ( m_table[i] != 0 )
+ {
+ if ( !m_table[i]->EventProcess(event) )
+ {
+ return FALSE;
+ }
+ }
+ }
+
+ if ( m_buttonReduce != 0 )
+ {
+ m_buttonReduce->EventProcess(event);
+ }
+ if ( m_buttonFull != 0 )
+ {
+ m_buttonFull->EventProcess(event);
+ }
+ if ( m_buttonClose != 0 )
+ {
+ m_buttonClose->EventProcess(event);
+ }
+ }
+
+ if ( m_bTrashEvent && event.event == EVENT_LBUTTONDOWN )
+ {
+ if ( Detect(event.pos) )
+ {
+ if ( m_name[0] != 0 && m_bMovable ) // title bar?
+ {
+ m_pressFlags = BorderDetect(event.pos);
+ if ( m_pressFlags != 0 )
+ {
+ m_bCapture = TRUE;
+ m_pressPos = event.pos;
+ }
+ }
+ return FALSE;
+ }
+ }
+
+ if ( event.event == EVENT_MOUSEMOVE && m_bCapture )
+ {
+ pos = event.pos;
+ if ( m_pressFlags == -1 ) // all moves?
+ {
+ m_pos.x += pos.x-m_pressPos.x;
+ m_pos.y += pos.y-m_pressPos.y;
+ }
+ else
+ {
+ if ( m_pressFlags & (1<<0) ) // left edge?
+ {
+ if ( pos.x > m_pressPos.x+m_dim.x-m_minDim.x )
+ {
+ pos.x = m_pressPos.x+m_dim.x-m_minDim.x;
+ }
+ m_pos.x += pos.x-m_pressPos.x;
+ m_dim.x -= pos.x-m_pressPos.x;
+ }
+ if ( m_pressFlags & (1<<1) ) // bottom edge?
+ {
+ if ( pos.y > m_pressPos.y+m_dim.y-m_minDim.y )
+ {
+ pos.y = m_pressPos.y+m_dim.y-m_minDim.y;
+ }
+ m_pos.y += pos.y-m_pressPos.y;
+ m_dim.y -= pos.y-m_pressPos.y;
+ }
+ if ( m_pressFlags & (1<<2) ) // right edge?
+ {
+ if ( pos.x < m_pressPos.x-m_dim.x+m_minDim.x )
+ {
+ pos.x = m_pressPos.x-m_dim.x+m_minDim.x;
+ }
+ m_dim.x += pos.x-m_pressPos.x;
+ }
+ if ( m_pressFlags & (1<<3) ) // top edge?
+ {
+ if ( pos.y < m_pressPos.y-m_dim.y+m_minDim.y )
+ {
+ pos.y = m_pressPos.y-m_dim.y+m_minDim.y;
+ }
+ m_dim.y += pos.y-m_pressPos.y;
+ }
+ }
+ m_pressPos = pos;
+ AdjustButtons();
+
+ Event newEvent = event;
+ newEvent.event = m_eventMsg;
+ m_event->AddEvent(newEvent);
+ }
+
+ if ( event.event == EVENT_LBUTTONUP && m_bCapture )
+ {
+ m_bCapture = FALSE;
+ }
+
+ return TRUE;
+}
+
+
+// Draws the window.
+
+void CWindow::Draw()
+{
+ FPOINT pos, dim;
+ float width, h, sw;
+ int i;
+
+ if ( (m_state & STATE_VISIBLE) == 0 ) return;
+
+ if ( m_state & STATE_SHADOW )
+ {
+ DrawShadow(m_pos, m_dim);
+ }
+
+ DrawVertex(m_pos, m_dim, m_icon); // draws the background
+
+ if ( m_name[0] != 0 ) // title bar?
+ {
+ h = m_engine->RetText()->RetHeight(m_fontSize, m_fontType);
+
+ // Draws the shadow under the title bar.
+ {
+ FPOINT sPos, sDim;
+
+ pos.x = m_pos.x+0.01f;
+ dim.x = m_dim.x-0.02f;
+ pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f;
+ dim.y = h*1.2f;
+ DrawShadow(pos, dim);
+ }
+
+ width = m_dim.x;
+ if ( m_bRedim ) width -= h*1.2f*0.75f*2.0f;
+ if ( m_bClosable ) width -= h*1.2f*0.75f;
+
+ pos.x = m_pos.x+0.01f;
+ dim.x = width-0.02f;
+ pos.y = m_pos.y+m_dim.y-0.01f-h*1.2f;
+ dim.y = h*1.2f;
+ DrawVertex(pos, dim, (m_state&STATE_ENABLE)?2:9);
+
+ sw = m_engine->RetText()->RetStringWidth(m_name, strlen(m_name), m_fontSize, m_fontStretch, m_fontType);
+
+ if ( m_state&STATE_ENABLE )
+ {
+ pos.x = m_pos.x+0.015f;
+ dim.x = (width-sw-0.06f)/2.0f;
+ pos.y = m_pos.y+m_dim.y-0.01f-h*1.0f;
+ dim.y = h*0.8f;
+ DrawHach(pos, dim); // left hatch
+ pos.x = m_pos.x+width-dim.x-0.015f;
+ DrawHach(pos, dim); // right hatch
+ }
+
+ pos.x = m_pos.x+width/2.0f;
+ pos.y = m_pos.y+m_dim.y-0.01f-h*1.10f;
+ m_engine->RetText()->DrawText(m_name, pos, width, 0, m_fontSize, m_fontStretch, m_fontType, 0);
+
+ if ( m_buttonReduce != 0 )
+ {
+ m_buttonReduce->Draw();
+ }
+
+ if ( m_buttonFull != 0 )
+ {
+ m_buttonFull->Draw();
+ }
+
+ if ( m_buttonClose != 0 )
+ {
+ m_buttonClose->Draw();
+ }
+ }
+
+ for ( i=0 ; i<MAXWINDOW ; i++ )
+ {
+ if ( m_table[i] != 0 )
+ {
+ m_table[i]->Draw();
+ }
+ }
+}
+
+// Draws a rectangle.
+
+void CWindow::DrawVertex(FPOINT pos, FPOINT dim, int icon)
+{
+ FPOINT p1, p2, uv1, uv2, corner;
+ float dp;
+ int i;
+
+ dp = 0.5f/256.0f;
+
+ if ( icon == 0 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTw);
+ uv1.x = 64.0f/256.0f; // dark blue transparent
+ uv1.y = 64.0f/256.0f;
+ uv2.x = 128.0f/256.0f;
+ uv2.y = 128.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 14.0f/640.0f;
+ corner.y = 14.0f/480.0f;
+ DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f);
+ }
+ else if ( icon == 1 )
+ {
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 128.0f/256.0f; // yellow tooltip
+ uv1.y = 0.0f/256.0f;
+ uv2.x = 224.0f/256.0f;
+ uv2.y = 16.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f);
+ }
+ else if ( icon == 2 )
+ {
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 128.0f/256.0f; // yellow
+ uv1.y = 16.0f/256.0f;
+ uv2.x = 224.0f/256.0f;
+ uv2.y = 32.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f);
+ }
+ else if ( icon == 3 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 0.0f/256.0f; // transparent blue bar with yellow upper
+ uv1.y = 64.0f/256.0f;
+ uv2.x = 64.0f/256.0f;
+ uv2.y = 128.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f);
+ }
+ else if ( icon == 4 ) // SatCom ?
+ {
+ pos.x -= 50.0f/640.0f;
+ pos.y -= 30.0f/480.0f;
+ dim.x += 100.0f/640.0f;
+ dim.y += 60.0f/480.0f;
+
+ m_engine->SetTexture("human.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 140.0f/256.0f;
+ uv1.y = 32.0f/256.0f;
+ uv2.x = 182.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2); // clothing
+
+ pos.x += 20.0f/640.0f;
+ pos.y -= 10.0f/480.0f;
+ dim.x -= 20.0f/640.0f;
+ dim.y += 0.0f/480.0f;
+
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTw);
+ 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 = 30.0f/640.0f;
+ corner.y = 30.0f/480.0f;
+ DrawIcon(pos, dim, uv1, uv2, corner, 5.0f/256.0f); // shadow
+
+ pos.x += 0.0f/640.0f;
+ pos.y += 20.0f/480.0f;
+ dim.x -= 20.0f/640.0f;
+ dim.y -= 20.0f/480.0f;
+
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 64.0f/256.0f;
+ uv1.y = 0.0f/256.0f;
+ uv2.x = 96.0f/256.0f;
+ uv2.y = 32.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 14.0f/640.0f;
+ corner.y = 14.0f/480.0f;
+ DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); // outside blue
+
+ pos.x += 20.0f/640.0f;
+ pos.y += 10.0f/480.0f;
+ dim.x -= 40.0f/640.0f;
+ dim.y -= 20.0f/480.0f;
+
+ uv1.x = 96.0f/256.0f;
+ uv1.y = 0.0f/256.0f;
+ uv2.x = 128.0f/256.0f;
+ uv2.y = 32.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 14.0f/640.0f;
+ corner.y = 14.0f/480.0f;
+ DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f); // inside blue
+
+ pos.x += 10.0f/640.0f;
+ pos.y += 10.0f/480.0f;
+ dim.x -= 20.0f/640.0f;
+ dim.y -= 20.0f/480.0f;
+
+ m_engine->SetTexture("button3.tga");
+ uv1.x = 0.0f/256.0f;
+ uv1.y = 224.0f/256.0f;
+ uv2.x = 32.0f/256.0f;
+ uv2.y = 256.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2); // dark blue background
+
+ m_engine->SetTexture("button2.tga");
+ uv1.x = 224.0f/256.0f;
+ uv1.y = 224.0f/256.0f;
+ uv2.x = 249.0f/256.0f;
+ uv2.y = 235.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ pos.x = 20.0f/640.0f;
+ pos.y = 70.0f/480.0f;
+ dim.x = 25.0f/640.0f;
+ dim.y = 11.0f/480.0f;
+ for ( i=0 ; i<5 ; i++ )
+ {
+ DrawIcon(pos, dim, uv1, uv2); // = bottom/left
+ pos.y += 15.0f/480.0f;
+ }
+ pos.y = (480.0f-70.0f-11.0f)/480.0f;
+ for ( i=0 ; i<5 ; i++ )
+ {
+ DrawIcon(pos, dim, uv1, uv2); // = top/left
+ pos.y -= 15.0f/480.0f;
+ }
+ pos.x = (640.0f-25.0f-20.0f)/640.0f;
+ pos.y = 70.0f/480.0f;
+ for ( i=0 ; i<5 ; i++ )
+ {
+ DrawIcon(pos, dim, uv1, uv2); // = bottom/right
+ pos.y += 15.0f/480.0f;
+ }
+ pos.y = (480.0f-70.0f-11.0f)/480.0f;
+ for ( i=0 ; i<5 ; i++ )
+ {
+ DrawIcon(pos, dim, uv1, uv2); // = top/right
+ pos.y -= 15.0f/480.0f;
+ }
+
+ uv1.x = 208.0f/256.0f;
+ uv1.y = 224.0f/256.0f;
+ uv2.x = 224.0f/256.0f;
+ uv2.y = 240.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ dim.x = 10.0f/640.0f;
+ dim.y = 10.0f/480.0f;
+ pos.x = 534.0f/640.0f;
+ pos.y = 430.0f/480.0f;
+ for ( i=0 ; i<3 ; i++ )
+ {
+ DrawIcon(pos, dim, uv1, uv2); // micro
+ pos.x += 12.0f/640.0f;
+ }
+ pos.x = 528.0f/640.0f;
+ pos.y -= 12.0f/480.0f;
+ for ( i=0 ; i<4 ; i++ )
+ {
+ DrawIcon(pos, dim, uv1, uv2); // micro
+ pos.x += 12.0f/640.0f;
+ }
+ pos.x = 534.0f/640.0f;
+ pos.y -= 12.0f/480.0f;
+ for ( i=0 ; i<3 ; i++ )
+ {
+ DrawIcon(pos, dim, uv1, uv2); // micro
+ pos.x += 12.0f/640.0f;
+ }
+ }
+ else if ( icon == 5 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 64.0f/256.0f; // transparent green
+ uv1.y = 160.0f/256.0f;
+ uv2.x = 160.0f/256.0f;
+ uv2.y = 176.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f);
+ }
+ else if ( icon == 6 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 64.0f/256.0f; // transparent red
+ uv1.y = 176.0f/256.0f;
+ uv2.x = 160.0f/256.0f;
+ uv2.y = 192.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f);
+ }
+ else if ( icon == 7 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 64.0f/256.0f; // transparent blue
+ uv1.y = 192.0f/256.0f;
+ uv2.x = 160.0f/256.0f;
+ uv2.y = 208.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f);
+ }
+ else if ( icon == 8 )
+ {
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 0.0f/256.0f; // opaque orange
+ uv1.y = 0.0f/256.0f;
+ uv2.x = 32.0f/256.0f;
+ uv2.y = 32.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 14.0f/640.0f;
+ corner.y = 14.0f/480.0f;
+ DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f);
+ }
+ else if ( icon == 9 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 32.0f/256.0f; // opaque gray
+ uv1.y = 32.0f/256.0f;
+ uv2.x = 64.0f/256.0f;
+ uv2.y = 64.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 14.0f/640.0f;
+ corner.y = 14.0f/480.0f;
+ DrawIcon(pos, dim, uv1, uv2, corner, 8.0f/256.0f);
+ }
+ else if ( icon == 10 )
+ {
+ // nothing (in the background image)!
+ }
+ else if ( icon == 11 )
+ {
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATETTb);
+ uv1.x = 64.0f/256.0f; // transparent yellow
+ uv1.y = 224.0f/256.0f;
+ uv2.x = 160.0f/256.0f;
+ uv2.y = 240.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ DrawIcon(pos, dim, uv1, uv2, 8.0f/256.0f);
+ }
+ else if ( icon == 12 )
+ {
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 128.0f/256.0f; // dirty opaque gray
+ uv1.y = 128.0f/256.0f;
+ uv2.x = 160.0f/256.0f;
+ uv2.y = 160.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 6.0f/640.0f;
+ corner.y = 6.0f/480.0f;
+ DrawIcon(pos, dim, uv1, uv2, corner, 5.0f/256.0f);
+ }
+ else if ( icon == 13 )
+ {
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 192.0f/256.0f; // dirty opaque blue
+ uv1.y = 128.0f/256.0f;
+ uv2.x = 224.0f/256.0f;
+ uv2.y = 160.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 6.0f/640.0f;
+ corner.y = 6.0f/480.0f;
+ DrawIcon(pos, dim, uv1, uv2, corner, 5.0f/256.0f);
+ }
+ else if ( icon == 14 )
+ {
+ m_engine->SetTexture("button1.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 160.0f/256.0f; // dirty opaque red
+ uv1.y = 128.0f/256.0f;
+ uv2.x = 192.0f/256.0f;
+ uv2.y = 160.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+ corner.x = 6.0f/640.0f;
+ corner.y = 6.0f/480.0f;
+ DrawIcon(pos, dim, uv1, uv2, corner, 5.0f/256.0f);
+ }
+}
+
+// Draws hatching.
+
+void CWindow::DrawHach(FPOINT pos, FPOINT dim)
+{
+#if _NEWLOOK
+#else
+ FPOINT ppos, ddim, uv1, uv2;
+ float dp, max, ndim;
+ BOOL bStop;
+
+ dp = 0.5f/256.0f;
+
+ m_engine->SetTexture("button2.tga");
+ m_engine->SetState(D3DSTATENORMAL);
+ uv1.x = 64.0f/256.0f; // hatching
+ uv1.y = 208.0f/256.0f;
+ uv2.x = 145.0f/256.0f;
+ uv2.y = 224.0f/256.0f;
+ uv1.x += dp;
+ uv1.y += dp;
+ uv2.x -= dp;
+ uv2.y -= dp;
+
+ max = dim.y*(uv2.x-uv1.x)/(uv2.y-uv1.y);
+
+ ppos = pos;
+ ddim = dim;
+ bStop = FALSE;
+ do
+ {
+ ddim.x = max;
+ if ( ppos.x+ddim.x > pos.x+dim.x )
+ {
+ ndim = pos.x+dim.x-ppos.x;
+ uv2.x = uv1.x+(uv2.x-uv1.x)*(ndim/ddim.x);
+ ddim.x = ndim;
+ bStop = TRUE;
+ }
+ DrawIcon(ppos, ddim, uv1, uv2);
+
+ ppos.x += ddim.x;
+ }
+ while ( !bStop );
+#endif
+}
+
diff --git a/src/ui/window.h b/src/ui/window.h
new file mode 100644
index 0000000..61506d1
--- /dev/null
+++ b/src/ui/window.h
@@ -0,0 +1,148 @@
+// * 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/.
+
+// window.h
+
+#ifndef _WINDOW_H_
+#define _WINDOW_H_
+
+
+#include "control.h"
+
+
+class CD3DEngine;
+class CButton;
+class CColor;
+class CCheck;
+class CKey;
+class CGroup;
+class CImage;
+class CLabel;
+class CEdit;
+class CEditValue;
+class CScroll;
+class CSlider;
+class CList;
+class CShortcut;
+class CMap;
+class CGauge;
+class CCompass;
+class CTarget;
+
+
+#define MAXWINDOW 100
+
+
+class CWindow : public CControl
+{
+public:
+ CWindow(CInstanceManager* iMan);
+ ~CWindow();
+
+ void Flush();
+ BOOL Create(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CButton* CreateButton(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CColor* CreateColor(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CCheck* CreateCheck(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CKey* CreateKey(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CGroup* CreateGroup(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CImage* CreateImage(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CLabel* CreateLabel(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, char *name);
+ CEdit* CreateEdit(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CEditValue* CreateEditValue(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CScroll* CreateScroll(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CSlider* CreateSlider(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CList* CreateList(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg, float expand=1.2f);
+ CShortcut* CreateShortcut(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CMap* CreateMap(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CGauge* CreateGauge(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CCompass* CreateCompass(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ CTarget* CreateTarget(FPOINT pos, FPOINT dim, int icon, EventMsg eventMsg);
+ BOOL DeleteControl(EventMsg eventMsg);
+ CControl* SearchControl(EventMsg eventMsg);
+
+ EventMsg RetEventMsgReduce();
+ EventMsg RetEventMsgFull();
+ EventMsg RetEventMsgClose();
+
+ void SetName(char* name);
+
+ void SetTrashEvent(BOOL bTrash);
+ BOOL RetTrashEvent();
+
+ void SetPos(FPOINT pos);
+ void SetDim(FPOINT dim);
+
+ void SetMinDim(FPOINT dim);
+ void SetMaxDim(FPOINT dim);
+ FPOINT RetMinDim();
+ FPOINT RetMaxDim();
+
+ void SetMovable(BOOL bMode);
+ BOOL RetMovable();
+
+ void SetRedim(BOOL bMode);
+ BOOL RetRedim();
+
+ void SetClosable(BOOL bMode);
+ BOOL RetClosable();
+
+ void SetMaximized(BOOL bMaxi);
+ BOOL RetMaximized();
+ void SetMinimized(BOOL bMini);
+ BOOL RetMinimized();
+ void SetFixed(BOOL bFix);
+ BOOL RetFixed();
+
+ BOOL GetTooltip(FPOINT pos, char* name);
+
+ BOOL EventProcess(const Event &event);
+
+ void Draw();
+
+protected:
+ int BorderDetect(FPOINT pos);
+ void AdjustButtons();
+ void MoveAdjust();
+ void DrawVertex(FPOINT pos, FPOINT dim, int icon);
+ void DrawHach(FPOINT pos, FPOINT dim);
+
+protected:
+ CControl* m_table[MAXWINDOW];
+
+ BOOL m_bTrashEvent;
+ BOOL m_bMaximized;
+ BOOL m_bMinimized;
+ BOOL m_bFixed;
+
+ FPOINT m_minDim;
+ FPOINT m_maxDim;
+
+ CButton* m_buttonReduce;
+ CButton* m_buttonFull;
+ CButton* m_buttonClose;
+
+ BOOL m_bMovable;
+ BOOL m_bRedim;
+ BOOL m_bClosable;
+ BOOL m_bCapture;
+ FPOINT m_pressPos;
+ int m_pressFlags;
+ D3DMouse m_pressMouse;
+};
+
+
+#endif //_WINDOW_H_