1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2011
3 //
4 // This file is part of Scorched3D.
5 //
6 // Scorched3D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // Scorched3D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 ////////////////////////////////////////////////////////////////////////////////
20
21 #include <dialogs/ProgressDialog.h>
22 #include <dialogs/BackdropDialog.h>
23 #include <landscape/LandscapeMusicManager.h>
24 #include <sound/Sound.h>
25 #include <client/ScorchedClient.h>
26 #include <client/ClientChannelManager.h>
27 #include <graph/Main2DCamera.h>
28 #include <client/ClientMain.h>
29 #include <client/ClientState.h>
30 #include <client/ClientParams.h>
31 #include <client/ClientProcessingLoop.h>
32 #include <server/ScorchedServer.h>
33 #include <engine/MainLoop.h>
34 #include <common/OptionsScorched.h>
35 #include <common/Clock.h>
36 #include <common/Defines.h>
37 #include <common/ChannelText.h>
38 #include <lang/LangResource.h>
39 #include <GLW/GLWFont.h>
40 #include <GLW/GLWWindowManager.h>
41 #include <GLW/GLWColors.h>
42 #include <lang/LangResource.h>
43 #include <image/ImagePngFactory.h>
44 #include <image/ImageFactory.h>
45 #include <math.h>
46 #include <string.h>
47
48 ProgressDialog *ProgressDialog::instance_ = 0;
49
instance()50 ProgressDialog *ProgressDialog::instance()
51 {
52 if (!instance_) instance_ = new ProgressDialog();
53 return instance_;
54 }
55
ProgressDialog()56 ProgressDialog::ProgressDialog() :
57 GLWWindow("Progress", 10.0f, 10.0f, 500.0f, 80.0f, eTransparent | eNoTitle | eHideName, ""),
58 progressPercentage_(0)
59 {
60 setUser(this);
61 }
62
~ProgressDialog()63 ProgressDialog::~ProgressDialog()
64 {
65 }
66
operationChange(const LangString & op)67 void ProgressDialog::operationChange(const LangString &op)
68 {
69 progressChange(op, 0.0f);
70 }
71
progressChange(const LangString & op,const float percentage)72 void ProgressDialog::progressChange(const LangString &op, const float percentage)
73 {
74 progressText_ = op;
75 progressPercentage_ = percentage;
76 }
77
changeTip()78 void ProgressDialog::changeTip()
79 {
80 tips_.getLines().clear();
81 tips_.readFile(S3D::getDataFile("data/tips.txt"));
82 needsCentered();
83
84 std::string tip = tips_.getLines()[rand() % tips_.getLines().size()].c_str();
85 char *nl = (char *) strchr(tip.c_str(), ':');
86 if (nl) *nl = ' ';
87
88 ChannelText text("announce", LANG_RESOURCE_1("TIP_ENTRY", "[t:Tip:] {0}", tip));
89 ClientChannelManager::instance()->showText(text);
90 }
91
setIcon(Image image)92 void ProgressDialog::setIcon(Image image)
93 {
94 Image newMap = image.createResize(64, 64);
95 icon_.create(newMap);
96 }
97
drawRules(ScorchedContext & context)98 void ProgressDialog::drawRules(ScorchedContext &context)
99 {
100 GLState newState(GLState::TEXTURE_OFF | GLState::DEPTH_OFF);
101
102 LANG_RESOURCE_VAR(SINGLE_PLAYER_GAME, "SINGLE_PLAYER_GAME", "Single Player Game");
103 LangString SERVER_NAME = LANG_STRING(context.getOptionsGame().getServerName());
104
105 LangString *text = &SINGLE_PLAYER_GAME;
106 if (ClientParams::instance()->getConnectedToServer())
107 {
108 text = &SERVER_NAME;
109 }
110
111 Vector offWhite(0.9f, 0.9f, 1.0f);
112 GLWFont::instance()->getGameShadowFont()->draw(
113 GLWColors::black,
114 20,
115 x_ + 13.0f - 2.0f, y_ + h_ - 32.0f + 2.0f, 0.0f,
116 *text);
117 GLWFont::instance()->getGameFont()->draw(
118 offWhite,
119 20,
120 x_ + 13.0f, y_ + h_ - 32.0f, 0.0f,
121 *text);
122
123 float top = y_ + 225.0f;
124 float left = x_ + 22.0f;
125 Vector yellow(1.0f, 1.0f, 1.0f); // Hmm, thats not yellow
126
127 const char *type = "Annihilate free for all";
128 if (context.getOptionsGame().getTeams() > 1) type = "Annihilate opposing team(s)";
129
130 LANG_RESOURCE_VAR_1(TYPE_LABEL, "TYPE_LABEL", "Type : {0}", type);
131 GLWFont::instance()->getGameFont()->draw(
132 yellow,
133 12,
134 left, top - 45.0f, 0.0f,
135 TYPE_LABEL);
136
137 LANG_RESOURCE_VAR_1(MOD_LABEL, "MOD_LABEL", "Mod : {0}",
138 context.getOptionsGame().getMod());
139 GLWFont::instance()->getGameFont()->draw(
140 yellow,
141 12,
142 left, top - 75.0f, 0.0f,
143 MOD_LABEL);
144
145 LANG_RESOURCE_VAR_1(GAME_TYPE_LABEL, "GAME_TYPE_LABEL", "Game type : {0}",
146 context.getOptionsGame().getTurnType().getValueAsString());
147 GLWFont::instance()->getGameFont()->draw(
148 yellow,
149 12,
150 left, top - 90.0f, 0.0f,
151 GAME_TYPE_LABEL);
152
153 LANG_RESOURCE_VAR_1(TEAMS_LABEL, "TEAMS_LABEL", "Teams : {0}",
154 S3D::formatStringBuffer("%i", context.getOptionsGame().getTeams()));
155 LANG_RESOURCE_VAR(TEAMS_NONE, "TEAMS_NONE", "Teams : None");
156 GLWFont::instance()->getGameFont()->draw(
157 yellow,
158 12,
159 left, top - 105.0f, 0.0f,
160 (context.getOptionsGame().getTeams() > 1)?TEAMS_LABEL:TEAMS_NONE);
161
162 LANG_RESOURCE_VAR_1(SHOT_TIME_LABEL, "SHOT_TIME_LABEL", "Shot Time : {0}",
163 S3D::formatStringBuffer("%i", context.getOptionsGame().getShotTime()));
164 LANG_RESOURCE_VAR(SHOT_TIME_UNLIMITED, "SHOT_TIME_UNLIMITED", "Shot time : Unlimited");
165 GLWFont::instance()->getGameFont()->draw(
166 yellow,
167 12,
168 left, top - 135.0f, 0.0f,
169 (context.getOptionsGame().getShotTime() > 0)?SHOT_TIME_LABEL:SHOT_TIME_UNLIMITED);
170
171 LANG_RESOURCE_VAR_1(BUYING_TIME_LABEL, "BUYING_TIME_LABEL", "Buying Time : {0}",
172 S3D::formatStringBuffer("%i", context.getOptionsGame().getBuyingTime()));
173 LANG_RESOURCE_VAR(BUYING_TIME_UNLIMITED, "BUYING_TIME_UNLIMITED", "Buying time : Unlimited");
174 GLWFont::instance()->getGameFont()->draw(
175 yellow,
176 12,
177 left, top - 150.0f, 0.0f,
178 (context.getOptionsGame().getBuyingTime() > 0)?BUYING_TIME_LABEL:BUYING_TIME_UNLIMITED);
179
180 glColor3f(0.0f, 0.0f, 0.0f);
181 glBegin(GL_LINES);
182 glVertex2f(x_ + 10.0f, y_ + 55.0f);
183 glVertex2f(x_ + 490.0f, y_ + 55.0f);
184 glEnd();
185 }
186
draw()187 void ProgressDialog::draw()
188 {
189 ScorchedContext *rulesContext = 0;
190 unsigned int state = ScorchedClient::instance()->getGameState().getState();
191 if (state >= ClientState::StateLoadFiles)
192 {
193 rulesContext = ScorchedClient::instance();
194 }
195 else if (ScorchedServer::instance() &&
196 ScorchedServer::instance()->getNetInterfaceValid())
197 {
198 rulesContext = ScorchedServer::instance();
199 }
200
201 if (rulesContext)
202 {
203 needsCentered();
204 h_ = 240.0f;
205 }
206 else
207 {
208 needsCentered();
209 h_ = 55.0f;
210 }
211
212 GLWWindow::draw();
213
214 if (rulesContext)
215 {
216 drawRules(*rulesContext);
217 }
218
219 {
220 GLState state(GLState::DEPTH_OFF | GLState::TEXTURE_ON | GLState::BLEND_ON);
221
222 if (!icon_.textureValid())
223 {
224 Image image = ImageFactory::loadImage(S3D::eDataLocation, "data/images/tank2.bmp");
225 setIcon(image);
226
227 Image bar1 = ImageFactory::loadAlphaImage(S3D::eDataLocation, "data/images/bar1.png");
228 Image bar2 = ImageFactory::loadAlphaImage(S3D::eDataLocation, "data/images/bar2.png");
229 bar1_.create(bar1);
230 bar2_.create(bar2);
231
232 bar1_.draw(true);
233 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
234 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
235
236 bar2_.draw(true);
237 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
238 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
239 }
240
241 // Draw the progress bars
242 glPushMatrix();
243 glTranslatef(x_ + 10.0f, y_ - 4.0f, 0.0f);
244
245 bar1_.draw();
246 glColor3f(1.0f, 1.0f, 1.0f);
247 glBegin(GL_QUADS);
248 glTexCoord2f(0.0f, 0.0f);
249 glVertex2f(0.0f, 15.0f);
250 glTexCoord2f(progressPercentage_ / 100.0f, 0.0f);
251 glVertex2f(480.0f * progressPercentage_ / 100.0f, 15.0f);
252 glTexCoord2f(progressPercentage_ / 100.0f, 1.0f);
253 glVertex2f(480.0f * progressPercentage_ / 100.0f, 26.0f);
254 glTexCoord2f(0.0, 1.0f);
255 glVertex2f(0.0f, 26.0f);
256 glEnd();
257 bar2_.draw();
258 glBegin(GL_QUADS);
259 glTexCoord2f(progressPercentage_ / 100.0f, 0.0f);
260 glVertex2f(480.0f * progressPercentage_ / 100.0f, 15.0f);
261 glTexCoord2f(1.0f, 0.0f);
262 glVertex2f(480.0f, 15.0f);
263 glTexCoord2f(1.0f, 1.0f);
264 glVertex2f(480.0f, 26.0f);
265 glTexCoord2f(progressPercentage_ / 100.0f, 1.0f);
266 glVertex2f(480.0f * progressPercentage_ / 100.0f, 26.0f);
267 glEnd();
268
269 // Draw the progress text
270 GLWFont::instance()->getGameShadowFont()->drawWidth(380.0f,
271 GLWColors::black,
272 14.0f, 5.0f - 2.0f, 33.0f + 2.0f, 0.0f,
273 progressText_);
274
275 Vector white(1.0f, 1.0f, 1.0f);
276 GLWFont::instance()->getGameFont()->drawWidth(380.0f,
277 white,
278 14.0f, 5.0f, 33.0f, 0.0f,
279 progressText_);
280 glPopMatrix();
281
282 // Draw the icon
283 /*
284 icon_.draw();
285 glPushMatrix();
286 {
287 glTranslatef(x_ + 12.0f, y_ + 12.0f, 0.0f);
288 glColor3f(1.0f, 1.0f, 1.0f);
289
290 glBegin(GL_QUADS);
291 glTexCoord2f(0.0f, 0.0f);
292 glVertex2f(0.0f, 0.0f);
293 glTexCoord2f(1.0f, 0.0f);
294 glVertex2f(56.0f, 0.0f);
295 glTexCoord2f(1.0f, 1.0f);
296 glVertex2f(56.0f, 56.0f);
297 glTexCoord2f(0.0f, 1.0f);
298 glVertex2f(0.0f, 56.0f);
299 glEnd();
300 }
301 {
302 GLState state2(GLState::TEXTURE_OFF);
303 glColor3f(0.0f, 0.0f, 0.0f);
304 glLineWidth(2.0f);
305 glBegin(GL_LINE_LOOP);
306 glTexCoord2f(0.0f, 0.0f);
307 glVertex2f(0.0f, 0.0f);
308 glTexCoord2f(1.0f, 0.0f);
309 glVertex2f(56.0f, 0.0f);
310 glTexCoord2f(1.0f, 1.0f);
311 glVertex2f(56.0f, 56.0f);
312 glTexCoord2f(0.0f, 1.0f);
313 glVertex2f(0.0f, 56.0f);
314 glEnd();
315 glLineWidth(1.0f);
316 }
317 glPopMatrix();
318 */
319 }
320 }
321
noevents_instance()322 ProgressDialogSync *ProgressDialogSync::noevents_instance()
323 {
324 static ProgressDialogSync *instance = new ProgressDialogSync(false);
325 return instance;
326 }
327
events_instance()328 ProgressDialogSync *ProgressDialogSync::events_instance()
329 {
330 static ProgressDialogSync *instance = new ProgressDialogSync(true);
331 return instance;
332 }
333
ProgressDialogSync(bool processEvents)334 ProgressDialogSync::ProgressDialogSync(bool processEvents) :
335 processEvents_(processEvents)
336 {
337 setUser(this);
338 }
339
~ProgressDialogSync()340 ProgressDialogSync::~ProgressDialogSync()
341 {
342 }
343
operationChange(const LangString & op)344 void ProgressDialogSync::operationChange(const LangString &op)
345 {
346 progressChange(op, 0.0f);
347 }
348
progressChange(const LangString & op,const float percentage)349 void ProgressDialogSync::progressChange(const LangString &op, const float percentage)
350 {
351 static Clock localTimer;
352 static float timeDelay = 0.0f;
353 static float timeDelay2 = 0.0f;
354 float frameTime = localTimer.getTimeDifference();
355 timeDelay += frameTime;
356 timeDelay2 += frameTime;
357
358 ClientMain::clientEventLoop(frameTime);
359 ClientProcessingLoop::instance()->process(frameTime, processEvents_);
360
361 ProgressDialog::instance()->progressChange(op, percentage);
362
363 if ((timeDelay > 0.25f) ||
364 (percentage > 99.0f))
365 {
366 Main2DCamera::instance()->draw(0);
367
368 unsigned int state = ScorchedClient::instance()->getGameState().getState();
369 if (state >= ClientState::StateLoadFiles)
370 {
371 GLWWindowManager::instance()->simulate(state, MIN(0.25f, timeDelay));
372 GLWWindowManager::instance()->draw(state);
373 }
374 else
375 {
376 BackdropDialog::instance()->draw();
377 ProgressDialog::instance()->draw();
378 }
379
380 LandscapeMusicManager::instance()->simulate(state, frameTime);
381 Sound::instance()->simulate(state, frameTime);
382
383 ScorchedClient::instance()->getMainLoop().swapBuffers();
384
385 timeDelay = 0.0f;
386 }
387
388 if (timeDelay2 > 5.0f)
389 {
390 SDL_Delay(50);
391 timeDelay2 = 0.0f;
392 }
393 }
394