1 /*
2  * Copyright (c) 2000 Mark B. Allan. All rights reserved.
3  * Copyright 2008 Paul Wise
4  *
5  * "Chromium B.S.U." is free software; you can redistribute
6  * it and/or use it and/or modify it under the terms of the
7  * "Clarified Artistic License"
8  */
9 
10 #ifdef HAVE_CONFIG_H
11 #include <chromium-bsu-config.h>
12 #endif
13 
14 #include "gettext.h"
15 
16 #include "MainGL.h"
17 
18 #include <cstdio>
19 #include <cstdlib>
20 #include <cstring>
21 #include <cmath>
22 #include <sys/stat.h>
23 
24 #include "compatibility.h"
25 
26 #if defined(HAVE_APPLE_OPENGL_FRAMEWORK) || (defined(HAVE_OPENGL_GL_H) && defined(HAVE_OPENGL_GLU_H))
27 #include <OpenGL/gl.h>
28 #include <OpenGL/glu.h>
29 #else
30 #include <GL/gl.h>
31 #include <GL/glu.h>
32 #endif
33 
34 #if IMAGE_GLPNG
35 #if defined(HAVE_APPLE_OPENGL_FRAMEWORK) || defined(HAVE_GLPNG_GLPNG_H)
36 #include <glpng/glpng.h>
37 #else
38 #include <GL/glpng.h>
39 #endif
40 #endif
41 
42 #if defined(TEXT_GLC)
43 #include "TextGLC.h"
44 #endif
45 #if defined(TEXT_FTGL)
46 #include "TextFTGL.h"
47 #endif
48 
49 #include "Config.h"
50 
51 #include "extern.h"
52 #include "Global.h"
53 #include "HiScore.h"
54 #include "EnemyFleet.h"
55 #include "HeroAmmo.h"
56 #include "EnemyAmmo.h"
57 #include "HeroAircraft.h"
58 #include "Explosions.h"
59 #include "PowerUps.h"
60 #include "Audio.h"
61 #include "MenuGL.h"
62 #include "StatusDisplay.h"
63 #include "ScreenItemAdd.h"
64 
65 #include "GroundMetal.h"
66 #include "GroundSea.h"
67 
68 //====================================================================
MainGL()69 MainGL::MainGL()
70 {
71 	game = Global::getInstance();
72 	initGL();
73 	loadTextures();
74 }
75 
76 
~MainGL()77 MainGL::~MainGL()
78 {
79 	deleteTextures();
80 }
81 
82 //----------------------------------------------------------
initGL()83 int MainGL::initGL()
84 {
85 	Config *config = Config::instance();
86 	if( config->debug() ) fprintf(stderr, _("initGL()\n"));
87 	reshapeGL(config->screenW(), config->screenH());
88 
89 	glDisable(GL_DEPTH_TEST);
90 	glDepthFunc(GL_LEQUAL);
91 
92 	glEnable(GL_TEXTURE_2D);
93 
94 	glEnable(GL_BLEND);
95 //	glDisable(GL_BLEND);
96 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
97 
98 	if(config->blend())
99 	{
100 		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
101 
102 		glEnable(GL_BLEND);
103 		glDisable(GL_ALPHA_TEST);
104 	}
105 	else
106 	{
107 		glAlphaFunc(GL_GREATER, 0.2);
108 
109 		glDisable(GL_BLEND);
110 		glEnable(GL_ALPHA_TEST);
111 	}
112 
113 //	glDisable(GL_CULL_FACE);
114 	glEnable(GL_CULL_FACE);
115 	glDisable(GL_NORMALIZE);
116 
117 	glPointSize(1.0);
118 	glLineWidth(1.0);
119 	glClearColor( 0.0, 0.0, 0.0, 1.0 );
120 
121 #ifdef IMAGE_GLPNG
122 	pngSetViewingGamma(config->viewGamma());
123 #endif
124 
125 	return 0;
126 }
127 
128 //----------------------------------------------------------
loadTextures()129 void MainGL::loadTextures()
130 {
131 	try {
132 #if defined(TEXT_GLC) && defined(TEXT_FTGL)
133 		Config *config = Config::instance();
134 		if(config->textType() == Config::TextGLC)
135 			game->text = new TextGLC();
136 		else
137 			game->text = new TextFTGL();
138 #elif defined(TEXT_GLC)
139 		game->text = new TextGLC();
140 #elif defined(TEXT_FTGL)
141 		game->text = new TextFTGL();
142 #else
143 		#error "TEXT_GLC or TEXT_FTGL must be defined"
144 #endif
145 	}
146 	catch (char* str)
147 	{
148 		fprintf(stderr, _("error loading font: %s\n"), str);
149 		exit(1);
150 	}
151 	catch (...)
152 	{
153 		fprintf(stderr, _("error loading font\n"));
154 		exit(1);
155 	}
156 }
157 
158 //----------------------------------------------------------
deleteTextures()159 void MainGL::deleteTextures()
160 {
161 	delete game->text;
162 	game->text = 0;
163 }
164 
165 //----------------------------------------------------------
drawGL()166 void MainGL::drawGL()
167 {
168 	switch(game->gameMode)
169 	{
170 		case Global::Game:
171 			drawGameGL();
172 			break;
173 		case Global::HeroDead:
174 			drawDeadGL();
175 			break;
176 		case Global::LevelOver:
177 			drawSuccessGL();
178 			break;
179 		case Global::Menu:
180 			game->menu->drawGL();
181 			break;
182 		default:
183 			fprintf(stderr, _("!!MainGL::drawGL() HUH?\n"));
184 			break;
185 	}
186 }
187 
188 //----------------------------------------------------------
drawGameGL()189 void MainGL::drawGameGL()
190 {
191 	Config *config = Config::instance();
192 	//-- Clear buffers
193 	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
194 //	glClear( GL_COLOR_BUFFER_BIT );
195 
196 	//-- Place camera
197 	glLoadIdentity();
198 	glTranslatef(0.0, 0.0, config->zTrans());
199 //	glTranslatef(0.0, 5.0, -12.0);
200 
201 	if(!game->game_pause)
202 	{
203 		//-- Add items to scene
204 		game->itemAdd->putScreenItems();
205 		//addItems();
206 
207 		//-- Update scene
208 		game->enemyFleet->update();
209 		game->powerUps->update();
210 		game->heroAmmo->updateAmmo();
211 		game->enemyAmmo->updateAmmo();
212 		game->heroAmmo->checkForHits(game->enemyFleet);
213 		if(game->gameMode == Global::Game)
214 		{
215 			game->enemyAmmo->checkForHits(game->hero);
216 			game->hero->checkForCollisions(game->enemyFleet);
217 			game->hero->checkForPowerUps(game->powerUps);
218 		}
219 		game->explosions->update();
220 		game->audio->update();
221 
222 		game->hero->update();
223 		game->gameFrame++;
224 	}
225 
226 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
227 
228 	//-- Draw background
229 	game->ground->drawGL();
230 
231 	//-- Draw actors
232 	game->enemyFleet->drawGL();
233 	game->hero->drawGL();
234 
235 	if(config->gfxLevel() > 0)
236 		game->statusDisplay->darkenGL();
237 
238 	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
239 
240 	game->powerUps->drawGL();
241 
242 	//-- Draw ammo
243 	game->heroAmmo->drawGL();
244 	game->enemyAmmo->drawGL();
245 
246 	//-- Draw explosions
247 	game->explosions->drawGL();
248 
249 	//-- Draw stats
250 	game->statusDisplay->drawGL(game->hero);
251 
252 }
253 
254 //----------------------------------------------------------
drawDeadGL()255 void MainGL::drawDeadGL()
256 {
257 	Config *config = Config::instance();
258 	game->heroDeath--;
259 
260 	//-- Clear buffers
261 	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
262 
263 	//-- Place camera
264 	glLoadIdentity();
265 	if(game->heroDeath > 0)
266 	{
267 		float z = 1.0*game->heroDeath/DEATH_TIME;
268 		glTranslatef(0.0, 0.0, config->zTrans()-z*z);
269 	}
270 	else
271 		glTranslatef(0.0, 0.0, config->zTrans());
272 
273 	//-- Add items to scene
274 	game->itemAdd->putScreenItems();
275 	//-- Update scene
276 	game->explosions->update();
277 	game->powerUps->update();
278 	game->enemyFleet->update();
279 	game->heroAmmo->updateAmmo();
280 	game->enemyAmmo->updateAmmo();
281 	game->heroAmmo->checkForHits(game->enemyFleet);
282 	game->audio->update();
283 	game->hero->update();
284 	game->gameFrame++;
285 
286 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
287 	//-- Draw background
288 	game->ground->drawGL();
289 	//-- Draw actors
290 	game->enemyFleet->drawGL();
291 
292 	if(config->gfxLevel() > 0)
293 		game->statusDisplay->darkenGL();
294 
295 	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
296 	game->powerUps->drawGL();
297 	//-- Draw ammo
298 	game->heroAmmo->drawGL();
299 	game->enemyAmmo->drawGL();
300 	//-- Draw explosions
301 	game->explosions->drawGL();
302 	//-- Draw stats
303 	game->statusDisplay->drawGL(game->hero);
304 
305 	int		skill = config->intSkill();
306 	float	heroScore = game->hero->getScore();
307 	HiScore *hiScore = HiScore::getInstance();
308 	char buffer[256];
309 	if(hiScore->check(skill, heroScore) == 1)
310 	{
311 		sprintf(buffer, _("new high score!\n\n%d"), (int)heroScore);
312 		drawTextGL(buffer, game->heroDeath, 0.15);
313 	}
314 	else if(hiScore->check(skill, heroScore) > 1)
315 	{
316 		sprintf(buffer, _("n o t   b a d !\nrank : %d\n\n%d"), hiScore->check(skill, heroScore), (int)heroScore);
317 		drawTextGL(buffer, game->heroDeath, 0.15);
318 	}
319 	else
320 	{
321 		drawTextGL(_("l o s e r"), game->heroDeath, 0.25);
322 	}
323 }
324 
325 //----------------------------------------------------------
drawSuccessGL()326 void MainGL::drawSuccessGL()
327 {
328 	Config *config = Config::instance();
329 	game->heroSuccess--;
330 
331 	if(game->heroSuccess < -500)
332 	{
333 		game->gotoNextLevel();
334 		game->gameMode = Global::Game;
335 		game->audio->setMusicMode(Audio::MusicGame);
336 		game->audio->setMusicVolume(config->volMusic());
337 		return;
338 	}
339 
340 	float f	= -game->heroSuccess/450.0;
341 	if(game->heroSuccess < 0)
342 	{
343 		float vol = config->volMusic() - (config->volMusic()*f);
344 		game->audio->setMusicVolume(vol);
345 	}
346 
347 	//-- Clear buffers
348 	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
349 
350 	//-- Place camera
351 	glLoadIdentity();
352 	glTranslatef(0.0, 0.0, config->zTrans());
353 
354 	//-- Update scene
355 	game->enemyFleet->update();
356 	game->explosions->update();
357 	game->heroAmmo->updateAmmo();
358 	game->hero->update();
359 	game->audio->update();
360 
361 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
362 	//-- Draw background
363 	game->ground->drawGL();
364 	//-- Draw actors
365 	game->hero->drawGL();
366 
367 	if(config->gfxLevel() > 0)
368 		game->statusDisplay->darkenGL();
369 
370 	glBlendFunc(GL_SRC_ALPHA, GL_ONE);
371 	//-- Draw ammo
372 	game->heroAmmo->drawGL();
373 	//-- Draw explosions
374 	game->explosions->drawGL();
375 	//-- Draw stats
376 	game->statusDisplay->drawGL(game->hero);
377 
378 	char	buffer[512];
379 	sprintf(buffer, _("congratulations!\n \nl e v e l\n %d \nc o m p l e t e\n \n"), game->gameLevel);
380 //	if(game->hero->getScore() > game->hiScore[config->intSkill()][0])
381 //	{
382 //		sprintf(buffer, _("congratulations!\n \nl e v e l\n %d \nc o m p l e t e\n \n"), game->gameLevel);
383 //	}
384 //	else
385 //	{
386 //		sprintf(buffer, _("congratulations!\n \nl e v e l\n %d \nc o m p l e t e\n \nn e w   h i g h   s c o r e : \n %g \n"), game->gameLevel, game->hero->getScore());
387 //	}
388 
389 	drawTextGL(buffer, game->heroSuccess, 0.15);
390 }
391 
392 //----------------------------------------------------------
drawTextGL(const char * string,float pulse,float scale)393 void MainGL::drawTextGL(const char *string, float pulse, float scale)
394 {
395 	int i, l, lines = 1;
396 	float	aa, ca;
397 	float	x_sin, y_sin, y, min_y;
398 	float	width, height;
399 	char	*walker,*newline;
400 	char	*index[10] = { 0,0,0,0,0,0,0,0,0,0 };
401 	char	buffer[128];
402 
403 	//-- alpha
404 	float tmp = 0.5+0.5*(sin(pulse*0.02));
405 	aa = 0.7-0.5*tmp;
406 	if(pulse > -50.0)
407 		aa *= (-pulse/50.0);
408 	ca = 1.0-tmp;
409 
410 	height = 1.5 * game->text->LineHeight();
411 
412 	strncpy(buffer, string, 128);
413 	index[0] = buffer;
414 	walker   = buffer;
415 	while( (newline = strchr(walker, '\n')) != NULL )
416 	{
417 		walker = newline+1;
418 		index[lines] = newline+1;
419 		*newline = '\0';
420 		lines++;
421 	}
422 
423 	min_y = 0.5*height*lines;
424 	for(l = 0; l< lines; l++)
425 	{
426 		y = min_y-height*(l+1);
427 		if(index[l] && strlen(index[l]) > 0)
428 		{
429 			for(i = 0; i < 6; i++)
430 			{
431 				glColor4f(1.0, ca*ca*0.3, ca*0.3, aa*aa);
432 				x_sin = 1.75*sin(i+game->frame*0.06);
433 				y_sin = 0.75*sin(i+game->frame*0.09);
434 
435 				glPushMatrix();
436 				glScalef(scale, scale*0.75, 1.0);
437 				width = game->text->Advance(index[l]);
438 				glTranslatef(-(width/2.0)-x_sin, y+y_sin, 0.0);
439 				game->text->Render(index[l]);
440 				glPopMatrix();
441 
442 			}
443 		}
444 	}
445 }
446 
447 /**
448  * incoming width and height are ignored - Config values are always used
449  */
450 //----------------------------------------------------------
reshapeGL(int,int)451 void MainGL::reshapeGL(int , int )
452 {
453 	Config *config = Config::instance();
454 	glMatrixMode(GL_PROJECTION);
455 	glLoadIdentity();
456 	gluPerspective( config->screenFOV(),
457 					config->screenA(),
458 					config->screenNear(),
459 					config->screenFar());
460 	glMatrixMode(GL_MODELVIEW);
461 	glViewport(0, 0, config->screenW(), config->screenH());
462 }
463