1 /*
2 Copyright (C) 2000/2002 Xavier Hosxe <xhosxe@free.fr>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #include "sprite.hpp"
20 #include "listsprite.hpp"
21
22 #include "pngtex.hpp"
23 #include "myship.hpp"
24 #include "bandit2.hpp"
25 #include "fighter2.hpp"
26 #include "ship1.hpp"
27 #include "diamond.hpp"
28 #include "cube.hpp"
29 #include "scratcher.hpp"
30 #include "tank.hpp"
31 #include "fire.hpp"
32
33 GLfloat static_pos_space [] = { -35,0,-50,-15,90 ,
34 45,-20,30,-35,60,
35 0,2,16,18, 90,
36 55,5,45,-5,90};
37
38 char *static_fileSample[SAMPLE_UNDEF] = {
39 "welcome.wav",
40 "tir.wav",
41 "explode1.wav",
42 "explode2.wav",
43 "tachefire.wav",
44 "glups.wav",
45 "powerup.wav",
46 "detection.wav",
47 "gameover.wav"
48 };
49
50 GLfloat slight_position[] = { 2, 5, -1, 0 };
51
52
53 GLfloat smat_ambient[] = { .5, .5, .5, 1.0 };
54 GLfloat smat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
55 GLfloat slm_ambient[] = { 0.5, 0.5, 0.5, 1.0 };
56 GLfloat slm_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
57 GLfloat slm_specular[] = { 1.0, 0, 0, 1.0 };
58 GLfloat sblanc_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
59 GLfloat snothing[] = { 0, 0, 0, 0 };
60 GLfloat sjaune_diffuse[] = { 1.0, 1.0, 0.0, 1.0 };
61 GLfloat sjaune_diffuse_trans[] = { 1.0, 1.0, 0.0, 0.5 };
62 GLfloat sjaune_diffuse_tres_trans[] = { 1.0, 1.0, 0.0, 0.25 };
63 GLfloat sbleu_diffuse_trans[] = { 0.4, 0.4, 1.0, 0.5 };
64 GLfloat srouge_diffuse_trans[] = { 1.0, 0.2, 0.2, 0.7 };
65 GLfloat srouge_diffuse[] = { 1, 0, 0.0, 1 };
66 GLfloat sjaune_emission[] = { .5, .5, 0.1, 0.8 };
67 GLfloat svert_diffuse[] = { 0, 1.0, 0, 1.0 };
68 GLfloat sbleu_diffuse[] = { 0, 0.0, 1, 1.0 };
69 GLfloat sbleu_clair_diffuse[] = { .3, 0.7, .8, 1.0 };
70 GLfloat sgris_diffuse[] = { 0.5, 0.5, 0.3, 1.0 };
71 GLfloat sgris2_diffuse[] = { 0.6, 0.6, .6, 1.0 };
72 GLfloat smarron_diffuse[] = {.6,.3,0,1.0};
73 GLfloat snoir_diffuse[] = { 0.0, 0.0, 0.0, 1.0 };
74
75 void changeAllTexturesAnis(int anisValue);
76 void changeAllTextures(GLenum mag, GLenum min);
77
getGlaxiumVariables()78 GlaxiumVariables* GlaxiumVariables::getGlaxiumVariables() {
79 if (GLvar==NULL) {
80 GLvar = new GlaxiumVariables();
81 }
82 return GLvar;
83 }
84
GlaxiumVariables()85 GlaxiumVariables::GlaxiumVariables() {
86 initInstallDir();
87 initVariables();
88 initTextures();
89 #ifdef HAVE_LIBSDL_MIXER
90 initSound();
91 #endif
92 initJoystick();
93 // printf("Variables initialized...\n");
94 }
95
96
initOptionsFile(bool bShad)97 void GlaxiumVariables::initOptionsFile(bool bShad) {
98 FILE *fOptions = fopen(getFullOptionsPath(), "r");
99 if (fOptions == NULL) {
100 fOptions = fopen(getFullOptionsPath(), "w+");
101 // printf("====> %s\n", getFullOptionsPath());
102 // printf("%d %d %d %d\n", 2, (int)fMaxAnis, 2, bShadows?1:0);
103 fprintf(fOptions, "%d %d %d %d", 2, (int)fMaxAnis, 2, bShad?1:0);
104 details = 2;
105 bShadows = bShad;
106 } else {
107 int filter, anis, nShad;
108 fscanf(fOptions, "%d %d %d %d", &filter, &anis, &details, &nShad);
109 bShadows = (nShad == 1);
110 changeAllTexturesAnis(anis);
111 switch (filter) {
112 case 0:
113 changeAllTextures(GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST);
114 break;
115 case 1:
116 changeAllTextures(GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST);
117 break;
118 case 2:
119 changeAllTextures(GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR);
120 break;
121 }
122 }
123
124 fclose(fOptions);
125 }
126
127
initVariables()128 void GlaxiumVariables::initVariables() {
129 mySpaceShip = NULL;
130 global_timeadjustment=1;
131 global_pause=0;
132 camera=1;
133 mat_ambient=smat_ambient;
134 mat_specular=smat_specular;
135 light_position=slight_position;
136 lm_ambient=slm_ambient;
137 lm_diffuse=slm_diffuse;
138 lm_specular=slm_specular;
139 blanc_diffuse=sblanc_diffuse;
140 nothing=snothing;
141 jaune_diffuse=sjaune_diffuse;
142 jaune_diffuse_trans=sjaune_diffuse_trans;
143 jaune_diffuse_tres_trans=sjaune_diffuse_tres_trans;
144 bleu_diffuse_trans=sbleu_diffuse_trans;
145 rouge_diffuse_trans=srouge_diffuse_trans;
146 rouge_diffuse=srouge_diffuse;
147 jaune_emission=sjaune_emission;
148 vert_diffuse=svert_diffuse;
149 bleu_diffuse=sbleu_diffuse;
150 bleu_clair_diffuse=sbleu_clair_diffuse;
151 gris_diffuse=sgris_diffuse;
152 gris2_diffuse=sgris2_diffuse;
153 marron_diffuse=smarron_diffuse;
154 noir_diffuse=snoir_diffuse;
155 float shadowMatrixTmp[] = { light_position[1]*10,0,0,0, -light_position[0]*10,0,-light_position[2]*10,-1,0,0,light_position[1]*10,0,0,0,0,light_position[1]*10};
156 shadowMatrix = new float [16];
157 for (int i=0;i<16;i++) {
158 shadowMatrix[i]= shadowMatrixTmp[i];
159 }
160
161 space_name[0] = "textures/space1.png";
162 space_name[1] = "textures/space0.png";
163 space_name[2] = "textures/space3.png";
164 space_name[3] = "textures/space2.png";
165
166 pos_space = static_pos_space;
167 fileSample = static_fileSample ;
168
169 rotateMyShip=0.0f;
170 delay =0;
171 bShadows=true;
172 bNVExtension = isExtensionSupported("GL_NV_register_combiners") && isExtensionSupported("GL_NV_vertex_program");
173 bEXTEnvDot3 = isExtensionSupported("GL_EXT_texture_env_dot3")&& isExtensionSupported("GL_EXT_texture_env_combine");
174 bARBCubeMap = isExtensionSupported("GL_ARB_texture_cube_map");
175 details = 0;
176 // Number of teture unit
177 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&m_nTextureUnits);
178 printf("Number of texture units : %d\n", m_nTextureUnits);
179
180 if (bNVExtension) {
181 // Number of register combiners
182 glGetIntegerv(GL_MAX_GENERAL_COMBINERS_NV, &m_nRegisterCombiners);
183 printf("Number of general combiners available : %d\n", m_nRegisterCombiners);
184 if (m_nRegisterCombiners==2 && m_nTextureUnits==2) {
185 printf("Nvidia NV1x video card found (geforce 256/2)\n");
186 } else if (m_nRegisterCombiners==8 && m_nTextureUnits==4) {
187 printf("Nvidia NV2x video card found (geforce 3/4)\n");
188 }
189 } else if (bEXTEnvDot3) {
190 printf("Found GL_EXT_texture_env_dot3 extension, i'll use it.\n");
191 } else {
192 printf(" Cannot load dot3 extension neither NVidia neither ARB.\r\n");
193 printf(" Fall back to basic openGL. The floor will be very simple.\r\n");
194 }
195
196
197 bSeparateSpecularColor = isExtensionSupported("GL_EXT_separate_specular_color");
198
199
200 fMaxAnis = 0;
201
202 if (isExtensionSupported("GL_EXT_texture_filter_anisotropic")) {
203 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, & fMaxAnis);
204 if (fMaxAnis>0) {
205 fMaxAnis = (fMaxAnis>8?8:fMaxAnis);
206 printf("Glaxium will use anisotropy texture : %f\n", fMaxAnis);
207 }
208 } else {
209 printf("NO anisotropy texture...\n");
210 }
211
212 }
213
214
initTexture(GLuint & textureToBind,char * path)215 void GlaxiumVariables::initTexture(GLuint &textureToBind, char* path) {
216 // printf("Loading : %s\n", getFullPath(path));
217 PngTex* tmpTexture = new PngTex(getFullPath(path));
218 tmpTexture->bindToTexture(textureToBind);
219 delete tmpTexture;
220 }
221
222
initTextures()223 void GlaxiumVariables::initTextures() {
224 int i,j,k,l;
225 PngTex* texture,*texture2;
226 int *tmpTexture;
227 int *tmpTexture2;
228
229 initTexture(texture_floorMap[0], "textures/floormap.png");
230 if (fMaxAnis>0)
231 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT, fMaxAnis);
232 initTexture(texture_floorMap[1], "textures/floormap1.png");
233 if (fMaxAnis>0)
234 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT, fMaxAnis);
235 initTexture(texture_floorMap[2], "textures/floormap2.png");
236 if (fMaxAnis>0)
237 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT, fMaxAnis);
238 initTexture(texture_floorMap[3], "textures/floormap3.png");
239 if (fMaxAnis>0)
240 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT, fMaxAnis);
241 initTexture(texture_floorMap[4], "textures/floormap4.png");
242 if (fMaxAnis>0)
243 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT, fMaxAnis);
244
245 initTexture(texture_mark, "textures/mark.png");
246 initTexture(texture_building, "textures/cube.png");
247 initTexture(texture_tache, "textures/tache.png");
248 initTexture(texture_deadtache, "textures/deadtache.png");
249 initTexture(texture_camouflage, "textures/camouflage.png");
250 initTexture(texture_thunder, "textures/thunder.png");
251 initTexture(texture_specialeffect1, "textures/effect1.png");
252
253 initTexture(texture_chaine, "textures/chain.png");
254 initTexture(texture_myship, "textures/myship.png");
255 initTexture(texture_piege, "textures/piege.png");
256 initTexture(texture_bandit1, "textures/bandit1.png");
257 initTexture(texture_fire3, "textures/missile.png");
258 initTexture(texture_fighter2, "textures/fighter2.png");
259
260 initTexture(texture_bandit2, "textures/bandit2.png");
261 initTexture(texture_sphere, "textures/sphere.png");
262
263 initTexture(texture_fumee[0], "textures/fumee1.png");
264 initTexture(texture_fumee[1], "textures/fumee2.png");
265 initTexture(texture_fumee[2], "textures/fumee3.png");
266
267 initTexture(texture_gameover, "textures/gameover.png");
268 initTexture(texture_board, "textures/board.png");
269 initTexture(texture_galaxy, "textures/galaxy.png");
270
271 initTexture(texture_capsule[Diamond::POWER], "textures/capsule_shield.png");
272 initTexture(texture_capsule[Diamond::POWERUP], "textures/capsule_power.png");
273 initTexture(texture_capsule[Diamond::BOMB], "textures/capsule_bomb.png");
274 initTexture(texture_capsule[Diamond::INVUL], "textures/capsule_invul.png");
275
276 initTexture(texture_floor[0], "textures/floor.png");
277 initTexture(texture_letters, "textures/chars.png");
278
279 if (fMaxAnis>0)
280 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT, fMaxAnis);
281 initTexture(texture_floor[1], "textures/floor1.png");
282 if (fMaxAnis>0)
283 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT, fMaxAnis);
284 initTexture(texture_floor[2], "textures/floor2.png");
285 if (fMaxAnis>0)
286 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT, fMaxAnis);
287 initTexture(texture_floor[3], "textures/floor3.png");
288 if (fMaxAnis>0)
289 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT, fMaxAnis);
290 initTexture(texture_floor[4], "textures/floor4.png");
291 if (fMaxAnis>0)
292 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT, fMaxAnis);
293 initTexture(texture_border, "textures/border2.png");
294
295 // only for border :
296 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
297 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
298
299 if (fMaxAnis>0)
300 glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAX_ANISOTROPY_EXT, fMaxAnis);
301
302
303 for (i=0; i< SPACE;i++) {
304 initTexture(texture_space[i], space_name[i]);
305 }
306
307
308 texture = new PngTex(getFullPath("textures/glax2.png"));
309 tmpTexture = (int*)texture->getTextureForOpenGl();
310 for (j=0;j<2;j++) {
311 for (i=0;i<3;i++) {
312 tmpTexture2 = new int[256*256];
313 for (k=0; k<256; k++) {
314 for (l=0; l<256; l++) {
315 if ((i*256+l<640) && +(j*256+k<480)) {
316 tmpTexture2[k*256+l] = tmpTexture[l+i*256+(j*256+k)*640];
317 }
318 }
319 }
320 texture2 = new PngTex();
321 texture2->setAll(256,256,(char*)tmpTexture2);
322 texture2->bindToTexture(texture_title[j*3+i]);
323 delete texture2;
324 }
325 }
326
327 // Letters
328 // printf("Loading : %s\n", path);
329
330 }
331
332
333
334 #ifdef HAVE_LIBSDL_MIXER
initSound()335 void GlaxiumVariables::initSound()
336 {
337 int audio_rate=MIX_DEFAULT_FREQUENCY;
338 Uint16 audio_format=MIX_DEFAULT_FORMAT;
339 int audio_channels=MIX_DEFAULT_CHANNELS;
340 #ifndef WIN32
341 int audio_buffers=1024;
342 #else
343 int audio_buffers=1024;
344 #endif
345
346 // printf("Init SDL_mixer\n");
347 /* Open the audio device */
348 if (Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) < 0) {
349 fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
350 exit(2);
351 } else {
352 Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
353 printf("Opened audio at %d Hz %d bit %s, %d bytes audio buffer\n", audio_rate,
354 (audio_format&0xFF),
355 (audio_channels > 1) ? "stereo" : "mono",
356 audio_buffers );
357 }
358
359 int nTotalChannel = Mix_AllocateChannels(22);
360 printf("Number of mixing channels : %d\n", nTotalChannel);
361
362 /* Load the requested module file */
363 // module1 = Mix_LoadMUS(getFullPath("samples/glax.xm"));
364 module2 = Mix_LoadMUS(getFullPath("samples/glax3.xm"));
365 Mix_PlayMusic(module2,-1);
366
367 for (int i=SAMPLE_WELCOME;i<SAMPLE_UNDEF;i++) {
368 char fileToLoad[256];
369 strcpy(fileToLoad,"samples/");
370 strcat(fileToLoad,fileSample[i]);
371 // printf("Loading %d : '%s'\n",i,fileToLoad);
372
373 samples[i] = Mix_LoadWAV(getFullPath(fileToLoad));
374 if (!samples[i]) {
375 fprintf(stderr, "Could not load sound '%s' , reason: %s\n",
376 fileSample[i],
377 SDL_GetError());
378 }
379 }
380 }
381
382 #endif
initInstallDir()383 void GlaxiumVariables::initInstallDir() {
384
385 installDir= NULL;
386 #ifdef DATADIR
387 FILE *fp = fopen("textures/space1.png", "rb");
388
389 if (fp==NULL) {
390 char path[1024];
391 sprintf(path, "%s/textures/space1.png", DATADIR);
392 fp = fopen(path, "rb");
393 if (fp==NULL) {
394 printf("Installation problem... cannot find textures...\n");
395 printf("Neither in ./ nor in %s\n",DATADIR);
396 } else {
397 printf("Found textures in %s\n", DATADIR);
398 installDir = DATADIR"/";
399 }
400 } else {
401 printf("Found textures in ./\n", DATADIR);
402 }
403 #endif
404 }
405
406
initJoystick()407 void GlaxiumVariables::initJoystick() {
408 // test joystick
409 joy=NULL;
410 if (SDL_NumJoysticks()>0) {
411 printf("YES !!! I found a joystick...\n");
412 joy=SDL_JoystickOpen(0);
413 if (joy==NULL) {
414 printf("AOUCH !!Joysick initialisation error !!!");
415 }
416
417 } else {
418 printf("No SDL joystick found...\n");
419 }
420 }
421
422
423
initAllLists()424 void GlaxiumVariables::initAllLists() {
425 MyShip::initList();
426 Ship1::initList();
427 Bandit2::initList();
428 Fighter2::initList();
429 Cube::initList();
430 Diamond::initList();
431 Scratcher::initList();
432 MyFire3::initList();
433 Tank::initList();
434 }
435
436
getFullPath(char * name)437 char* GlaxiumVariables::getFullPath(char *name) {
438 static char returnString[1024];
439
440 if (installDir==NULL) {
441 return name;
442 } else {
443 strcpy(returnString,installDir);
444 strcat(returnString, name);
445 return returnString;
446 }
447 }
448
getFullOptionsPath()449 char* GlaxiumVariables::getFullOptionsPath() {
450 #ifdef WIN32
451 return "glaxiumrc";
452 #else
453 static char strReturn[1024];
454 strcpy(strReturn, getenv("HOME"));
455 strcat(strReturn, "/.glaxiumrc");
456 return strReturn;
457 #endif
458 }
459
myRandom(int i)460 bool GlaxiumVariables::myRandom(int i) {
461 if (i==0) return false;
462 #ifndef WIN32
463 if ((random()%(i<<4))<(int)(GLvar->global_timeadjustment*16.0)) {
464 return true;
465 }
466 #else
467 if ((float)rand()*i/32000 < GLvar->global_timeadjustment) {
468 return true;
469 }
470 #endif
471 return false;
472 }
473
474
isExtensionSupported(const char * extension)475 bool GlaxiumVariables::isExtensionSupported(const char *extension)
476 {
477 const GLubyte *extensions = NULL;
478 const GLubyte *start;
479 GLubyte *where, *terminator;
480
481 /* Extension names should not have spaces. */
482 where = (GLubyte *) strchr(extension, ' ');
483 if (where || *extension == '\0')
484 return false;
485 extensions = glGetString(GL_EXTENSIONS);
486 /* It takes a bit of care to be fool-proof about parsing the
487 OpenGL extensions string. Don't be fooled by sub-strings,
488 etc. */
489 start = extensions;
490 for (;;) {
491 where = (GLubyte *) strstr((const char *) start, extension);
492 if (!where)
493 break;
494 terminator = where + strlen(extension);
495 if (where == start || *(where - 1) == ' ')
496 if (*terminator == ' ' || *terminator == '\0')
497 return true;
498 start = terminator;
499 }
500 return false;
501 }
502
503
504
505