Agregados dos tipos de disparos y mejora visual en los checkpoints.
[nespa.git] / src / nespa.cpp
blobe34ace713863b84bc2865736344f0dcd934371b8
1 #ifdef WIN32
2 #define WIN32_LEAN_AND_MEAN
3 #include <windows.h>
4 #endif
5 #if defined(__APPLE__) && defined(__MACH__)
6 #include <OpenGL/gl.h> // Header File For The OpenGL32 Library
7 #include <OpenGL/glu.h> // Header File For The GLu32 Library
8 #else
9 #include <GL/gl.h> // Header File For The OpenGL32 Library
10 #include <GL/glu.h> // Header File For The GLu32 Library
11 #endif
12 #include "SDL/SDL.h"
13 #include "SDL/SDL_image.h"
14 #include "SDL/SDL_timer.h"
15 #include "SDL/SDL_mixer.h"
16 #include "SDL_Pango.h"
19 #include "ModelType.h"
20 #include "e3d_engine.h"
22 #define NUM_PLANETS 3
23 #define NUM_SHOOTS 3
24 #define MAX_SHOTS 512
26 // 640x480 * 2 * 2 = 1280 x 960
28 SDL_Surface *pixshoot[NUM_SHOOTS];
30 e3D_Application *e3D_App;
31 e3D_Render *Render;
32 e3D_Video *Video;
33 e3D_Sound *Sound;
34 e3D_Controller *Controller;
36 uint sound_checkpoint1,
37 sound_checkpoint2a,
38 sound_checkpoint2b,
39 sound_checkpoint2c,
40 sound_destroyed,
41 sound_engine1,
42 sound_planet1a,
43 sound_shoot1dd,
44 sound_shoot1d,
45 sound_shoot1f,
46 sound_shoot1,
47 sound_shoot2;
49 int channel_engine;
51 GLuint texplanet[NUM_PLANETS]; // Storage For NUM_PLANETS Textures
52 GLuint texshoot[NUM_SHOOTS]; // Storage For NUM_SHOOTS Textures
54 GLuint cube; // Storage For The Display List
55 //GLuint top; // Storage For The Second Display List
56 GLuint sprite;
58 GLuint xloop; // Loop For X Axis
59 GLuint yloop; // Loop For Y Axis
60 float zoom=1;
62 GLfloat xrot; // Rotates Cube On The X Axis
63 GLfloat yrot; // Rotates Cube On The Y Axis
68 matriz camera_position, camera_orientation, camera, perspective;
69 matriz ship;
70 double sz;
71 ModelType MTObject[15];
73 // Build Cube Display List
74 GLvoid BuildList()
76 sprite=glGenLists(1);
77 glNewList(sprite,GL_COMPILE);
78 glBegin(GL_QUADS);
79 // Top Face
80 glNormal3f( 0.0f, 0.0f, -1.0f);
81 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.0f);
82 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 0.0f);
83 glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 0.0f);
84 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 0.0f);
85 glEnd();
86 glEndList();
89 // Load Bitmaps And Convert To Textures
90 void LoadGLTextures(void)
92 // Load Texture
93 int i;
96 i=0;
98 pixshoot[i] = IMG_Load("images/particles/supernova-256-8.png");
99 if (!pixshoot[i]) {SDL_Quit();exit(1);}
100 i++;
101 pixshoot[i] = IMG_Load("images/particles/cross1.png");
102 if (!pixshoot[i]) {SDL_Quit();exit(1);}
103 i++;
104 pixshoot[i] = IMG_Load("images/particles/cross2.png");
105 if (!pixshoot[i]) {SDL_Quit();exit(1);}
106 i++;
108 /* SDLPango_Context *pango_test1 = SDLPango_CreateContext();
109 SDLPango_SetDefaultColor(pango_test1, MATRIX_TRANSPARENT_BACK_WHITE_LETTER);
110 SDLPango_SetDpi(pango_test1, TTF_DPI, TTF_DPI);
111 SDLPango_SetMinimumSize(pango_test1, -1, 0);
112 SDLPango_SetMarkup(pango_test1, "world", -1);
113 int ps_w = SDLPango_GetLayoutWidth(pango_test1);
114 int ps_h = SDLPango_GetLayoutHeight(pango_test1);
115 // int margin_x = 10;
116 // int margin_y = 10;
117 // pixshoot[2]= SDLPango_CreateSurfaceDraw(pango_test1);
118 pixshoot[2] = SDL_CreateRGBSurface(SDL_SWSURFACE, ps_w, ps_h,
119 32, (Uint32)(255 << (8 * 0)), (Uint32)(255 << (8 * 1)),
120 (Uint32)(255 << (8 * 2)), (Uint32)(255 << (8 * 3)));
121 SDLPango_Draw(pango_test1, pixshoot[2], 0, 0);
122 //int totalbytes=4*pixshoot[2]->w*pixshoot[2]->h;
125 // Create MipMapped Texture
126 glGenTextures(NUM_SHOOTS, texshoot);
128 for (i=0;i<NUM_SHOOTS;i++)
130 glBindTexture(GL_TEXTURE_2D, texshoot[i]);
131 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
132 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
133 gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB,
134 pixshoot[i]->w, pixshoot[i]->h, GL_RGB, GL_UNSIGNED_BYTE,
135 pixshoot[i]->pixels);
140 /* A general OpenGL initialization function. Sets all of the initial parameters. */
141 void TempInitGL() // We call this right after our OpenGL window is created.
143 LoadGLTextures(); // Load The Texture
144 BuildList(); // Build The Display List
147 /* The main drawing function. */
148 int puntos=0;
150 void DrawGLScene(float d=0.03, float angle=0, float vel=0)
152 static int frame=0;
154 glMatrixMode(GL_MODELVIEW);
157 glDisable(GL_LIGHTING);
158 glEnable(GL_BLEND);
159 glDisable(GL_ALPHA_TEST);
160 glDepthMask(GL_FALSE);
162 glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Aditivo
164 glMatrixMode(GL_PROJECTION);
165 glLoadIdentity(); // Reset The Projection Matrix
166 gluOrtho2D(-1,1,-1,1);
167 glMatrixMode(GL_MODELVIEW);
169 glDisable(GL_LIGHTING);
170 glEnable(GL_COLOR_MATERIAL);
172 frame++;
175 if (frame%6==0)
177 char txt_puntos[256];
178 puntos++;
179 sprintf(txt_puntos,"Time:%06d",puntos);
180 Render->Score->setText(txt_puntos);
182 char txt_vel[256];
183 sprintf(txt_vel,"Speed:%.2f",Render->Ship1->lv);
184 Render->Speed->setText(txt_vel);
186 sprintf(txt_vel,"Fuel:%.2f",Render->Ship1->used_fuel);
187 Render->Fuel->setText(txt_vel);
188 frame=0;
190 glLoadIdentity();
191 glTranslatef(-0.80,-0.90,0);
192 Render->Score->Draw(1);
194 glLoadIdentity();
195 glTranslatef(-0.10,-0.90,0);
196 Render->Speed->Draw(1);
198 glLoadIdentity();
199 glTranslatef(+0.60,-0.90,0);
200 Render->Fuel->Draw(1);
205 glBindTexture(GL_TEXTURE_2D, texshoot[2]);
207 glLoadIdentity();
208 glScalef(d/(4.0/3.0),d,1.0f);
209 //glScalef(5,5,1.0f);
210 glRotatef(angle,0,0,1);
211 glColor4f(1.0f,1.0f,1.0f,0.05f/d-0.05);
212 glCallList(sprite);
214 glBindTexture(GL_TEXTURE_2D, texshoot[2]);
215 static float va=0;
216 va+=vel*2.0;
217 glLoadIdentity();
218 glTranslatef(0.8+1/vel,-0.8-1/vel,0);
219 glScalef(3.0/4.0/vel,1.0f/vel,1.0f);
220 glRotatef(va,0,0,1);
221 glColor4f(1.0f,1.0f,1.0f,vel/10.0);
222 glCallList(sprite);
228 void nearCallback (void *data, dGeomID o0, dGeomID o1) {
229 e3D_Render *Render=(e3D_Render *)data;
230 // Create an array of dContact objects to hold the contact joints
231 static const int MAX_CONTACTS = 10;
232 dContact contact[MAX_CONTACTS];
234 for (int i = 0; i < MAX_CONTACTS; i++)
236 contact[i].surface.mode = dContactSoftERP | dContactSoftCFM;
237 contact[i].surface.mu = dInfinity;
238 contact[i].surface.mu2 = 0;
239 contact[i].surface.bounce = 0.0;
240 contact[i].surface.bounce_vel = 0.0;
241 contact[i].surface.soft_cfm = 0.1;
242 contact[i].surface.soft_erp = 0.1;
244 if (int numc = dCollide(o0, o1, MAX_CONTACTS, &contact[0].geom, sizeof(dContact)))
246 Sound->play_sound(sound_shoot1f,.4);
247 // Get the dynamics body for each geom
248 dBodyID b1 = dGeomGetBody(o0);
249 dBodyID b2 = dGeomGetBody(o1);
250 // To add each contact point found to our joint group we call dJointCreateContact which is just one of the many
251 // different joint types available.
252 for (int i = 0; i < numc; i++)
254 // dJointCreateContact needs to know which world and joint group to work with as well as the dContact
255 // object itself. It returns a new dJointID which we then use with dJointAttach to finally create the
256 // temporary contact joint between the two geom bodies.
257 dJointID c = dJointCreateContact(Render->world, Render->_contactgroup, contact + i);
258 dJointAttach(c, b1, b2);
264 void callback_Checkpoint_onChange(int new_checkpoint)
266 switch(rand()%3)
268 case 0: Sound->play_sound(sound_checkpoint2a); break;
269 case 1: Sound->play_sound(sound_checkpoint2b); break;
270 case 2: Sound->play_sound(sound_checkpoint2c); break;
274 #ifdef WIN32
275 int WINAPI WinMain (HINSTANCE hInstance,
276 HINSTANCE hPrevInstance,
277 LPSTR lpCmdLine,
278 int iCmdShow)
279 #endif
280 #ifndef WIN32
281 int main(int argc, char **argv)
282 #endif
285 int done;
286 Uint8 *keys;
287 float zoom_d=1;
288 Uint32 start;
291 e3D_App=new e3D_Application();
292 Sound=e3D_App->Sound;
293 Video=e3D_App->Video;
294 Controller=e3D_App->Controller;
295 Render=e3D_App->Render;
297 Video->Width=1024;
298 Video->Height=768;
299 Video->Bitsperpixel=0;
300 Video->Fullscreen=0;
302 Video->InitializeVideo();
303 Controller->SetWarpPos(Video->Width/2,Video->Height/2);
305 e3D_App->SetFPS(60);
307 sound_checkpoint1=Sound->load_sound("sounds/checkpoint1.ogg");
308 sound_checkpoint2a=Sound->load_sound("sounds/checkpoint2a.ogg");
309 sound_checkpoint2b=Sound->load_sound("sounds/checkpoint2b.ogg");
310 sound_checkpoint2c=Sound->load_sound("sounds/checkpoint2c.ogg");
311 sound_destroyed=Sound->load_sound("sounds/destroyed.ogg");
312 sound_engine1=Sound->load_sound("sounds/engine1.ogg");
313 sound_planet1a=Sound->load_sound("sounds/planet1a.ogg");
314 sound_shoot1dd=Sound->load_sound("sounds/shoot1-dd.ogg");
315 sound_shoot1d=Sound->load_sound("sounds/shoot1-d.ogg");
316 sound_shoot1f=Sound->load_sound("sounds/shoot1-f.ogg");
317 sound_shoot1=Sound->load_sound("sounds/shoot1.ogg");
318 sound_shoot2=Sound->load_sound("sounds/shoot2.ogg");
320 SDL_Joystick *joystick=0;
321 int njj=SDL_NumJoysticks();
322 if (njj >= 1)
324 cout << "Se encontraron " << njj << " joysticks." << endl;
325 joystick = SDL_JoystickOpen(0);
328 TempInitGL();
330 done = 0;
331 start=SDL_GetTicks();
332 e3D_Ship *Nave=Render->Ship1;
333 // e3D_Ship *Nave2=Render->Ship2;
334 // e3D_Ship *Nave3=Render->Ship3;
335 Render->zoom=10;
337 dWorldID world = Render->world;
339 int weapon1=0;
341 double joyx=0,joycx=0;
342 double joyy=0,joycy=0;
343 double joyz=0,joycz=0;
345 cout << "Iniciando juego." << endl;
346 channel_engine=Sound->play_sound(sound_engine1,0,-1);
348 while ( ! done ) {
349 if (e3D_App->StartFrame())
352 if (Controller->grab)
354 Nave->dfriction=5.0/(Nave->lv+100);
355 dSpaceCollide(Render->space, Render, &nearCallback);
356 dWorldStep(world,1.0/60.0);
357 dJointGroupEmpty(Render->_contactgroup);
359 double x2,y2,z2;
360 double x3,y3,z3;
361 glLoadIdentity();
362 Render->LoadCamera(Render->Ship1);
363 Render->Ship2->GetXYZ(&x2,&y2,&z2);
364 Render->Ship3->GetXYZ(&x3,&y3,&z3);
366 // Draw only when StartFrame returns True
367 Render->Render();
368 float e1=Nave->energy;
369 if (e1>1000) e1=1000;
370 float d=10.0/e1*zoom;
371 if (d>0.5) d=0.5;
372 if (d<0.02) d=0.02;
373 //float a=1;
374 // Indicadores varios y disparos
375 DrawGLScene(d,-weapon1*90/5,fabs(Nave->dz));
376 Mix_Volume(channel_engine,MIX_MAX_VOLUME/10.0*sqrt(fabs(Nave->dz)));
379 // GUIAS DE JOYSTICK
380 glBindTexture(GL_TEXTURE_2D, texshoot[0]);
381 glLoadIdentity();
382 glScalef(0.1/(4.0/3.0),0.1,1.0f);
383 glTranslated(joyx*fabs(joyx)/10.0,joyy*fabs(joyy)/10.0,0);
384 glColor4f(1.0f,0.0f,0.0f,1.0f);
385 glCallList(sprite);
386 glLoadIdentity();
387 glScalef(0.1/(4.0/3.0),0.1,1.0f);
388 glTranslated(-joycx*5,-joycy*5,0);
389 glColor4f(0.0f,0.0f,1.0f,1.0f);
390 glCallList(sprite);
392 // El HUD / radar que dibuja a los enemigos.
393 /* glBindTexture(GL_TEXTURE_2D, texshoot[1]);
394 if (z2<-500 && Render->Ship2->hull)
396 x2/=-z2/zoom/3.8;
397 y2/=-z2/zoom/3.8;
398 glLoadIdentity();
399 glScalef(1.0/(4.0/3.0),1,1.0f);
400 glTranslated(x2,y2,0);
401 d=1.8/sqrt(-z2+500)*sqrt(zoom);
403 a=d/0.1;
404 if (a>1) a=1;
405 if (d>0.5) d=0.5;
406 if (d<0.02) d=0.02;
408 glScalef(d,d,1.0f);
409 glColor4f(1.0f,1.0f,1.0f,(0.05f/d-0.05)*a);
410 glCallList(sprite);
412 if (z3<-500 && Render->Ship3->hull)
414 x3/=-z3/zoom/3.8;
415 y3/=-z3/zoom/3.8;
416 glLoadIdentity();
417 glScalef(1.0/(4.0/3.0),1,1.0f);
418 glTranslated(x3,y3,0);
419 d=1.8/sqrt(-z3+500)*sqrt(zoom);
421 a=d/0.1;
422 if (a>1) a=1;
423 if (d>0.5) d=0.5;
424 if (d<0.02) d=0.02;
426 glScalef(d,d,1.0f);
427 glColor4f(1.0f,1.0f,1.0f,(0.05f/d-0.05)*a);
428 glCallList(sprite);
432 SDL_GL_SwapBuffers();
434 else
436 Mix_Volume(channel_engine,0);
438 done=Controller->GetEvents(); // OJO!! Esto asigna *keys.
441 // Control de la nave por teclado y joystick
442 if (joystick)
444 double jdz=0;
445 joyx = (joyx *0.5 + SDL_JoystickGetAxis(joystick, 0)/32768.0)/.6;
446 joyy = (joyy *0.5 + SDL_JoystickGetAxis(joystick, 1)/32768.0)/.6;
447 joyz = (joyz *0.5 + SDL_JoystickGetAxis(joystick, 2)/32768.0)/.6;
449 jdz = (SDL_JoystickGetAxis(joystick, 3))/-3276.8+9.9;
451 joycx = (joycx*300.0+joyx*0.1)/(300.1);
452 joycy = (joycy*300.0+joyy*0.1)/(300.1);
453 joycz = (joycz*300.0+joyz*0.1)/(300.1);
454 joycx/=1+fabs(joycx/10.0);
455 joycy/=1+fabs(joycy/10.0);
456 joycz/=1+fabs(joycz/10.0);
458 joyx -= joycx;
459 joyy -= joycy;
460 joyz -= joycz;
463 Nave->ry+=joyz*fabs(joyz)/2000.0/zoom;
464 Nave->rx-=joyy*fabs(joyy)/1000.0/zoom;
465 Nave->rz+=joyx*fabs(joyx)/500.0/zoom;
466 Nave->dz+=jdz*jdz*jdz/100.0;
467 int jhat=SDL_JoystickGetHat(joystick,0);
468 switch(jhat)
470 case SDL_HAT_UP:
471 zoom_d+=zoom_d/100.0;
472 break;
473 case SDL_HAT_DOWN:
474 zoom_d-=zoom_d/100.0;
475 break;
478 // zoom_d+=jdx/1000.0;
480 else
482 Nave->ry+=Controller->mouse_x/200.0/zoom;
483 Nave->rx+=Controller->mouse_y/200.0/zoom;
484 Nave->dz+=1;
486 Nave->ry=Controller->mouse_x/20.0/zoom;
487 Nave->rx=Controller->mouse_y/20.0/zoom;
489 // Suavizado del zoom.
490 zoom=(zoom_d+zoom*50.0)/51.0;
492 Render->zoom=zoom;
493 sz=Nave->energy;
495 /* Check current key state for special commands */
496 keys = Controller->keys;
498 // Control de la nave por teclado
499 if (Nave->energy>0)
501 if ( keys[SDLK_w] == SDL_PRESSED ) Nave->dy-= 0.05f;
502 if ( keys[SDLK_s] == SDL_PRESSED ) Nave->dy+= 0.05f;
503 if ( keys[SDLK_a] == SDL_PRESSED ) Nave->dx+= 0.05f;
504 if ( keys[SDLK_d] == SDL_PRESSED ) Nave->dx-= 0.05f;
507 if ( keys[SDLK_q] == SDL_PRESSED ) Nave->rx+= 0.1f;
508 if ( keys[SDLK_e] == SDL_PRESSED ) Nave->rx-= 0.1f;
509 if ( keys[SDLK_r] == SDL_PRESSED ) Nave->ry+= 0.1f;
510 if ( keys[SDLK_f] == SDL_PRESSED ) Nave->ry-= 0.1f;
511 if ( keys[SDLK_z] == SDL_PRESSED ) Nave->rz-= 0.1f;
512 if ( keys[SDLK_x] == SDL_PRESSED ) Nave->rz+= 0.1f;
515 if ( keys[SDLK_a] == SDL_PRESSED ) Nave->rz-= 0.2f;
516 if ( keys[SDLK_s] == SDL_PRESSED ) Nave->rz+= 0.2f;
518 if ( keys[SDLK_z] == SDL_PRESSED ) {Nave->dz+=.5;}
519 if ( keys[SDLK_x] == SDL_PRESSED ) {Nave->dz-=1;}
520 if (weapon1<60) weapon1++;
521 if (weapon1>=30)
524 if (keys[SDLK_v] == SDL_PRESSED)
526 weapon1=0;
527 Sound->play_sound(sound_shoot1,.2);
528 Nave->Shoot(0);
530 if (keys[SDLK_b] == SDL_PRESSED)
532 weapon1=0;
533 Sound->play_sound(sound_shoot1,.2);
534 Nave->Shoot(1);
539 // Sobre música y gramola
540 if ( keys[SDLK_1] == SDL_PRESSED && playing>=0 )
542 if (Mix_FadeOutMusic(10000)) playing=-1;
545 if (playing==-1 || !Mix_PlayingMusic())
547 if (Mix_FadingMusic()==MIX_NO_FADING)
549 playing=rand()%11;
550 Mix_FadeInMusicPos(music[playing],1,10000,0);
556 // Teclas de función
557 if ( keys[SDLK_F1] == SDL_PRESSED ) Render->Camera=Render->Ship1;
558 if ( keys[SDLK_F2] == SDL_PRESSED ) Render->Camera=Render->Ship2;
559 if ( keys[SDLK_F3] == SDL_PRESSED ) Render->Camera=Render->Ship3;
561 if ( keys[SDLK_F7] == SDL_PRESSED ) Controller->Grab();
562 if ( keys[SDLK_F8] == SDL_PRESSED ) Controller->UnGrab();
565 // Freno
567 if ( keys[SDLK_LCTRL])
569 Nave->dz/=1.10;
570 Nave->dx/=1.10;
571 Nave->dy/=1.10;
574 // Zoom
575 if ( Controller->mouse_wheel>0 && zoom_d < 100) zoom_d*=1.5;
576 if ( Controller->mouse_wheel<0 && zoom_d > 0.5) zoom_d/=1.5;
577 if (zoom_d > 100) zoom_d=100;
578 if (zoom_d < 0.5) zoom_d=0.5;
580 // ********************************************
583 if (joystick && SDL_JoystickOpened(0))
585 SDL_JoystickClose(joystick);
587 delete e3D_App;
588 return 1;