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