mElite  1.0
An Elite clone based on TextElite by Jan-Philipp Kappmeier and Melanie Schmidt.
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
App.cpp
Go to the documentation of this file.
1 
6 #pragma once
7 
8 #include <fstream>
9 #include "App.h"
10 #include "BitmapFont.h"
11 #include "TextureFont.h"
12 #include "TextInput.h"
13 #include "Console.h"
14 #include "ColorConstants.h"
15 #include "MouseHandler.h"
16 #include "Frustum.h"
17 #include "HudLoadBar.h"
18 #include "Button.h"
19 #include "World.h"
20 #include "PoliceShip.h"
21 #include "Objects.h"
22 #include "Shapes.h"
23 #include "SpaceStation.h"
24 #include "Star.h"
25 #include "Planet.h"
26 #include "TextureLoaderTGA.h"
27 #include "Textures.h"
28 #include "PlayerObject.h"
29 #include "FileAccess.h"
30 #include "FrameCounter.h"
31 
32 using namespace std;
33 
35 static const bool DEV_MODE = true;
36 
41 consoleCommand App::table[] = {
42  {"showFPS", 0},
43  {"showFrameTime",1},
44  {"showSpeed", 2},
45  {"showRes", 3},
46  {"quit",4},
47  {"toggleFullscreen", 5},// is called in the parent class!
48  {"help",6},
49  {"devmode", 7},
50  {"switchColors",8},
51  {NULL, -1}
52 };
53 
60 OpenGLApplication * OpenGLApplication::create(const char * className) {
61  App * example = new App( className );
62  return reinterpret_cast<OpenGLApplication *>(example);
63 }
64 
72 App::App( const char * className ) : OpenGLApplication( className ) {
73  // create array of function pointer. this can only be done in constructor because it's not static
74  fptr[0] = &App::showFrameRate;
75  fptr[1] = &App::showFrameTime;
76  fptr[2] = &App::showSpeed;
77  fptr[3] = &App::showResolution;
78  fptr[4] = &App::terminate;
79  fptr[5] = &App::toggleFullscreen; // from parent class!
80  fptr[6] = &App::showHelp;
81  fptr[7] = &App::devMode;
82  fptr[8] = &App::switchColors;
83 
84  zoomFactor = 1;
85 
86  handlingSpeedMultiplyer = 5 * 0.01;
87  lightspeed = 0.00815;
88  currentScreen = currentSystem;
89  m_inputmode = false;
90  m_showFrameRate = m_showFrameTime = m_showResolution = true;
91  m_showSpeed = false;
92  m_switchColors = false;
93  //infoOutputLine; // does not need to be initialized, is set to 0 at beginning of every frame
94 
95  // debug only vars
96  devmode = DEV_MODE; // disable debug modus
97  currentSystemInfoNumber = 7; // num for lave ;) right is: World::getWorld()->getCurrentSystem(); //but does not exist! // in debug modus you can switch through the systems in info mode
98 
99  // game status
100  laserActive = false;
101  inStation = false;
102  gameOver = false;
103 
104  // system info view
105  systemInfoViewAngle = -25.0;
106  systemInfoViewAngle2 = -10.0;
107  zoomFactor = 1.0;
108 
109  // initialize the cameras
110  cameraSystemView = new CameraObject( ); // has no radius and creates no collision (for now ;) )
111  cameraSystemView->setPos( 0, 0, 0 );
112  cameraSystemView->setSpeed( lightspeed * 0.2 );
113 }
114 
119 App::~App() {
120  //delete texture;
121  //delete player;
122  delete cameraSystemView;
123 }
124 
130  // delete objects created while initialization
131  delete speedBar;
132  delete laserHeatBar;
133 
135 
136  delete mouse;
137  delete frustum;
138  delete con;
139  delete ti;
140  delete tf2;
141  delete tf;
142 }
143 
153 void App::draw() {
154  if( devmode )
155  gameOver = false;
156 
157  if( gameOver ) {
158  drawGameOver();
159  return;
160  }
161 
162  // reset info output line counter
163  infoOutputLine = 0;
164 
165  static int planetToDraw = -1;
166  static bool showBox = false;
167 
168  switch( currentScreen ) {
169 case currentSystem:
170  {
171  getWindow()->showMousePointer( false );
172  unsigned int oldHeight = getWindow()->getHeight();
173  unsigned int oldWidth = getWindow()->getWidth();
174  getWindow()->setHeight( 128 );
175  getWindow()->setWidth( 128 );
176  getWindow()->reshape();
177  firstDraw = true;
178  drawCurrentSystem();
179 
180 
181  // read the image data for the rear view and load as texture
182  unsigned char *image = 0;
183  image = new unsigned char[getWindow()->getWidth() * getWindow()->getHeight() * 3];
184  glReadPixels( 0, 0, getWindow()->getWidth(), getWindow()->getHeight(), GL_RGB, GL_UNSIGNED_BYTE, image );
185  TextureLoader * loader = new TextureLoaderTGA();
186  loader->load( image, getWindow()->getWidth(), getWindow()->getHeight(), 3);
188  delete[] image;
189 
190  getWindow()->setHeight( oldHeight );
191  getWindow()->setWidth( oldWidth );
192  getWindow()->reshape();
193  firstDraw = false;
194  drawCurrentSystem();
195  }
196  break;
197 case localSystems:
198  {
199  getWindow()->showMousePointer( true );
200  mouse->setMouseHovering( !showBox ); // enable mouse hovering, this enables highlighting planets
201  //if( mouse->getHittedObject() != button || getWindow()->getMouseClick() == false ) // only draw if no button was hit, because status changes!
202  drawLocalSystems();
203  // check if mouse-click has occured and if that happens, do jump if a planet was hit
204  if( getWindow()->getMouseClick() ) {
205  if( mouse->getHittedObject() == planet ) {
206  // a planet was hit
207  // set up an question-box that is painted over the screen --> because of that next time hovering has to be disabled.
208  showBox = !showBox;
209  }
210  if( mouse->getHittedObject() == button ) {
211  // should only be executed if a button is pressed
212  if( mouse->getHittedObjectInfo() == 0 ) {
213  // nothing to do ;)
214  } else {
215  // perform jump
216  World::getWorld()->performJump( planetToDraw );
218  // reload textures
220  getWindow()->showMousePointer( false );
221  setScreen( systemInfo );
222  }
224  planetToDraw=-1;
225  showBox = !showBox;
226  }
227  getWindow()->setMouseClick( false );// click was handled, so delete it!
228  }
229  }
230  break;
231 case marketplace:
232  getWindow()->showMousePointer( true );
233  drawMarketplace();
234  break;
235 case systemInfo:
236  getWindow()->showMousePointer( false );
237  drawSystemInfo();
238  break;
239 case credits:
240  getWindow()->showMousePointer( false );
241  break;
242 case help:
243  getWindow()->showMousePointer( false );
244  drawHelp();
245  break;
246 case helpEnvironment:
247  getWindow()->showMousePointer( false );
248  drawHelpEnvironment();
249  break;
250 case helpInfo:
251  getWindow()->showMousePointer( false );
252  drawHelpInfo();
253  break;
254 case helpLocal:
255  getWindow()->showMousePointer( false );
256  drawHelpLocal();
257  break;
258 case helpMarketplace:
259  getWindow()->showMousePointer( false );
260  drawHelpMarketplace();
261  break;
262 case loadProgram:
263 case loadLevel:
264  getWindow()->showMousePointer( false );
265  break;
266  }
267 
268  if( showBox ) {
269  // print a box and therefore, enable mouse-hitting
270  mouse->setMouseHovering( true );
272 
273  // draw a box
274  // set up an orthogonal screen for printing text and painting the board
275  glMatrixMode( GL_PROJECTION );
276  glPushMatrix();
277  glLoadIdentity();
278  glOrtho( 0, getWindow()->getWidth(), 0, getWindow()->getHeight(), -100, 100 ); // full size orthogonal screen
279  glMatrixMode( GL_MODELVIEW );
280  glPushMatrix();
281  glLoadIdentity();
282 
283  glDisable( GL_TEXTURE_2D );
284  // draw a box in gray that represents the box
285  glColor3fv( colorLightGrey );
286  int writingHeight = tf2->getSize();
287  int writingWidth = tf2->getWidth();
288  int xCenter = getWindow()->getWidth() * 0.5;
289  int yCenter = getWindow()->getHeight() * 0.5;
290  int messageWidth = 38 * writingWidth;
291  int messageHeight = 8 * writingHeight; // 2 * size over and under text, 2 times space for buttons and one time space under the button
292  Shapes::drawRect( xCenter, yCenter, 0, messageWidth, messageHeight );
293  // draw yes and no buttons
294  int buttonWidth = 90;
295  int buttonHeight = 2*writingHeight;
296 
297  glColor3fv( colorDarkGrey );
298  Shapes::drawRect( xCenter - 2*writingWidth - buttonWidth*0.5, yCenter - messageHeight*0.5 + writingHeight + buttonHeight*0.5, 0, buttonWidth, buttonHeight);
299  Shapes::drawRect( xCenter + 2*writingWidth + buttonWidth*0.5, yCenter - messageHeight*0.5 + writingHeight + buttonHeight*0.5, 0, buttonWidth, buttonHeight);
300 
301  // test if mouse is over a button
302  bool overYes = mouse->isMouseOverRectCenter(xCenter - 2*writingWidth - buttonWidth*0.5, getWindow()->getHeight() - (yCenter - messageHeight*0.5 + writingHeight + buttonHeight*0.5), buttonWidth, buttonHeight);
303  bool overNo =mouse->isMouseOverRectCenter(xCenter + 2*writingWidth + buttonWidth*0.5, getWindow()->getHeight() - (yCenter - messageHeight*0.5 + writingHeight + buttonHeight*0.5), buttonWidth, buttonHeight);
304 
305  // print question box
306  glEnable( GL_TEXTURE_2D );
307  glEnable( GL_BLEND );
308  glColor4fv( colorWhite );
309  if( planetToDraw == -1)
310  planetToDraw = mouse->getHittedObjectInfo();
311  string text = "Do you want to jump to " + World::getWorld()->getSystemName( planetToDraw ) + "?";
312  tf2->print( xCenter - messageWidth*0.5 + 2*writingHeight,
313  yCenter + messageHeight*0.5 - 3 * writingHeight,
314  &text
315  );
316  // print questions and so on
317  if( overYes ) {
318  glColor3fv( colorDarkRed );
319  tf2->print( xCenter - 2*writingWidth - buttonWidth*0.5 /* now x-center position */ - 1.5*writingWidth,
320  yCenter - messageHeight*0.5 + writingHeight + buttonHeight*0.5 /* now y center position */ - 0.5*writingHeight,
321  "Yes"
322  );
323  glColor3fv( colorWhite );
326  }
327  else
328  tf2->print( xCenter - 2*writingWidth - buttonWidth*0.5 /* now x-center position */ - 1.5*writingWidth,
329  yCenter - messageHeight*0.5 + writingHeight + buttonHeight*0.5 /* now y center position */ - 0.5*writingHeight,
330  "Yes"
331  );
332  if( overNo ) {
333  glColor3fv( colorDarkRed );
334  tf2->print( xCenter + 2*writingWidth + buttonWidth*0.5 /* now x-center position */ - writingWidth,
335  yCenter - messageHeight*0.5 + writingHeight + buttonHeight*0.5 /* now y center position */ - 0.5*writingHeight,
336  "No"
337  );
338  glColor3fv( colorWhite );
341  }
342  else
343  tf2->print( xCenter + 2*writingWidth + buttonWidth*0.5 /* now x-center position */ - writingWidth,
344  yCenter - messageHeight*0.5 + writingHeight + buttonHeight*0.5 /* now y center position */ - 0.5*writingHeight,
345  "No"
346  );
347  glDisable( GL_BLEND );
348 
349  // restore matrices
350  glMatrixMode( GL_PROJECTION );
351  glPopMatrix();
352  glMatrixMode( GL_MODELVIEW );
353  glPopMatrix();
354  }
355  glFlush();
356 }
357 
364 void App::drawCurrentSystem() {
365  if( !firstDraw ) {
366  // send some information lines to the print-on-display vector
367  if( m_showFrameTime )
368  printInfoLine("Frametime:%3.2f ms", getFrameCounter()->getFrameTimeAverage());
369  if( m_showFrameRate )
370  printInfoLine("Framerate:%d fps", getFrameCounter()->getFrameRateAverage());
371  if( m_showResolution )
372  printInfoLine("Screensize: %dx%d", getWindow()->getWidth(), getWindow()->getHeight());
373  if( m_showSpeed ) {
374  printInfoLine("Speed (abs): %5.4f", player->getSpeed());
375  printInfoLine("Speed: %3.2f", (100*player->getSpeed())/lightspeed);// percentage of lightspeed (= normalspeedmax)
376  }
377  if( player->isRearView() )
378  printInfoLine("Rear view is activated.");
379  }
380 
381  if(firstDraw)
383 
384  // save projection and create frustrum
385  glPushMatrix();
386  player->look();
387 
388  // draw the skysphere. thus the z-buffer is deactivated, so that the skysphere appears to be in the background
389  // fast mode is already activated (at least, it should be ;)
390  fastMode();
391  glPushMatrix();
392  glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
393  glTranslatef( player->getPos().x, player->getPos().y, player->getPos().z );// move sphere with viewer
394  glRotatef( 90, 1, 0, 0 );
396  gluSphere( quadObj, 100, 32, 32 );
397  glPopMatrix();
398 
399  // activate full mode in order to draw the main scene. the z-buffer can now be cleared
400  // render main scene
401  fullMode();
402  glClear( GL_DEPTH_BUFFER_BIT );
403 
404  vector<GraphicsObject*> *objects = World::getWorld()->getGraphicObjects();
405  for( unsigned int i=0; i < objects->size(); i++ ) {
406  CullingLocation res = getFrustum()->isSphereInFrustum( objects->at(i)->getPos(), objects->at(i)->getRadius() );
407  if( player->isRearView() )
408  res = inside;
409  if( res != outside ) {
410  objects->at(i)->draw();
411  SpaceShip* ship = dynamic_cast<SpaceShip*>( objects->at(i) );
412  if( ship ) {
413  glDisable( GL_CULL_FACE );
414  if( ship->isShooting() ) {
415  glDisable( GL_LIGHTING ); // deactivate lighting for the laser
416  glDisable( GL_LIGHT0 ); // star is deactivated (is this really necessary?)
417  glEnable( GL_BLEND ); // blending enabled, as the laser is transparent
419  glColor3fv( colorRed );
420  Vector3 shootVector = ship->getPos() - player->getPos();
421  shootVector.normalize();
422 
423  // new calculation
424  Vector3 p = ship->getPos() - player->getPos(); // vector to the ship
425  Vector3 v = player->getView();
426  v.normalize();
427 
428  Vector3 aimFrom = ship->getPos();
429  Vector3 aimTo = player->getPos() + player->getView()*20;
430 
431  Vector3 sproj = player->getView() * ship->getPos().innerProduct( player->getView() );
432  Vector3 v2 = player->getRight();
433  v2.normalize();
434  Vector3 v3 = ship->getPos() - sproj;
435  v3.normalize();
436 
437  float cosval = v2.innerProduct( v3 );
438  float winkel = acos(cosval) / ANGLE2DEG;
439 
440  if(winkel > 90)
441  winkel = 180 - winkel;
442  Vector3 absbla = player->getUp() * ((90.0-winkel)/90.0) + player->getRight() * (winkel/90.0);
443  Vector3 absbla2 = player->getRight() * ((90.0-winkel)/90.0) + player->getUp() * (winkel/90.0);
444  absbla.normalize();
445 
446  Vector3 aimToLeft = aimTo + absbla * -5.0f;
447  Vector3 aimToRight = aimTo + absbla * 5.0f;
448  Vector3 aimFromLeft = aimFrom + absbla * -5;
449  Vector3 aimFromRight = aimFrom + absbla * 5;
450 
451  glEnable( GL_BLEND );
452  glBegin( GL_QUADS );
453  glTexCoord2f( 0, 1 );
454  glVertex3f( aimFromLeft.x, aimFromLeft.y, aimFromLeft.z );
455  glTexCoord2f( 0, 0 );
456  glVertex3f( aimToLeft.x, aimToLeft.y, aimToLeft.z );
457  glTexCoord2f( 1, 0 );
458  glVertex3f( aimToRight.x, aimToRight.y, aimToRight.z );
459  glTexCoord2f( 1, 1 );
460  glVertex3f( aimFromRight.x, aimFromRight.y, aimFromRight.z );
461  //if( frustum->isInRightHalf( ship->getPos() ) && frustum->isInUpperHalf( ship->getPos() ) ) {
462  Plane aimPlane = Plane(aimToLeft, aimToRight, aimFromRight);
463  Vector3 absblaOrtho = aimPlane.getNormal();
464  aimToLeft = aimTo + absblaOrtho * -5.0f;
465  aimToRight = aimTo + absblaOrtho * 5.0f;
466  aimFromLeft = aimFrom + absblaOrtho * -5;
467  aimFromRight = aimFrom + absblaOrtho * 5;
468  //}
469  glTexCoord2f( 0, 1 );
470  glVertex3f( aimFromLeft.x, aimFromLeft.y, aimFromLeft.z );
471  glTexCoord2f( 0, 0 );
472  glVertex3f( aimToLeft.x, aimToLeft.y, aimToLeft.z );
473  glTexCoord2f( 1, 0 );
474  glVertex3f( aimToRight.x, aimToRight.y, aimToRight.z );
475  glTexCoord2f( 1, 1 );
476  glVertex3f( aimFromRight.x, aimFromRight.y, aimFromRight.z );
477  glEnd();
478  glDisable( GL_BLEND );
479  glEnable( GL_TEXTURE_2D );
480  fullMode();
481  glEnable( GL_LIGHTING );
482  }
483  glEnable( GL_CULL_FACE );
484  }
485  }
486  }
487  delete objects;
488  if( firstDraw ) {
490  glPopMatrix();
491  return;
492  }
493 
494  glEnable( GL_BLEND );
495  if( laserActive ) {
496  glDisable( GL_LIGHTING ); // deactivate lighting,
497  glDisable( GL_LIGHT0 ); // and the star
499  glColor3fv( colorRed );
500 
501  glPushMatrix();
502  glBegin( GL_QUADS );
503  Vector3 target = player->getPos() + player->getView()*4000;
504  Vector3 obenLinks = target + player->getRight()*(-10);
505  Vector3 obenRechts = target + player->getRight()*0;
506  Vector3 untenLinks = player->getPos() + player->getRight()*(-10) + player->getUp()*(-10);
507  Vector3 untenRechts = player->getPos() + player->getRight()*0 + player->getUp()*(-10);
508 
509  glTexCoord2f( 0, 1 ); // upper left
510  glVertex3f( obenLinks.x, obenLinks.y, obenLinks.z );
511  glTexCoord2f( 0, 0 ); // lower left
512  glVertex3f( untenLinks.x, untenLinks.y, untenLinks.z );
513  glTexCoord2f( 1, 0 ); // lower right
514  glVertex3f( untenRechts.x, untenRechts.y, untenRechts.z );
515  glTexCoord2f( 1, 1 ); // upper right
516  glVertex3f( obenRechts.x, obenRechts.y, obenRechts.z );
517 
518  obenLinks = target + player->getRight()*(0);
519  obenRechts = target + player->getRight()*10;
520  untenLinks = player->getPos() + player->getRight()*(0) + player->getUp()*(-10);
521  untenRechts = player->getPos() + player->getRight()*10 + player->getUp()*(-10);
522  glTexCoord2f( 1, 1 ); // upper left
523  glVertex3f( obenLinks.x, obenLinks.y, obenLinks.z );
524  glTexCoord2f( 1, 0 ); // lower left
525  glVertex3f( untenLinks.x, untenLinks.y, untenLinks.z );
526  glTexCoord2f( 0, 0 ); // lower right
527  glVertex3f( untenRechts.x, untenRechts.y, untenRechts.z );
528  glTexCoord2f( 0, 1 ); // upper right
529  glVertex3f( obenRechts.x, obenRechts.y, obenRechts.z );
530  glEnd();
531 
532  glPopMatrix();
533  glEnable( GL_LIGHTING ); // reactivate lighting
534  glEnable( GL_LIGHT0 );
535  }
536 
537  glPopMatrix(); // end of general matrix transformation
538 
539  // switch to fast mode in order to draw the display elements
540  fastMode();
541 
542  // set up an orthogonal screen for printing text and drawing the huds
543  setProjectionOrthogonal();
544  glEnable( GL_BLEND ); // enable blending (for text and transparent items)
545  glColor3fv( colorWhite ); // white color
546  printInfoBox( true ); // actually print the lines and the info box
547 
548  // output if inputmode is on
549  if( m_inputmode ) {
550  this->ti->print();
551  }
552 
553  // draw the sight
554  glColor3f(1,0,0);
556  int x = this->getWindow()->getWidth() * 0.5;
557  int y = this->getWindow()->getHeight() * 0.5;
558  int sightSize = 16;
559  glBegin( GL_QUADS );
560  glTexCoord2f( 0, 1 );
561  glVertex3f(-sightSize*2 + x, sightSize + y, 0);
562  glTexCoord2f( 0, 0 );
563  glVertex3f(-sightSize*2 + x,-sightSize + y, 0);
564  glTexCoord2f( 1, 0 );
565  glVertex3f( sightSize*2 + x,-sightSize + y, 0);
566  glTexCoord2f( 1, 1 );
567  glVertex3f( sightSize*2 + x, sightSize + y, 0);
568  glEnd();
569 
570  // draw missile info
571  glColor3fv( colorLightGrey);
573  y = 48;
574  sightSize = 48;
575  for( unsigned int i = 0; i < player->getMissileCount(); i++ ) {
576  x = this->getWindow()->getWidth() - 230 - i*30;
577  glBegin( GL_QUADS );
578  glTexCoord2f( 0, 1 );
579  glVertex3f(-sightSize + x, sightSize + y, 0);
580  glTexCoord2f( 0, 0 );
581  glVertex3f(-sightSize + x,-sightSize + y, 0);
582  glTexCoord2f( 1, 0 );
583  glVertex3f( sightSize + x,-sightSize + y, 0);
584  glTexCoord2f( 1, 1 );
585  glVertex3f( sightSize + x, sightSize + y, 0);
586  glEnd();
587  }
588 
589  glDisable( GL_BLEND );
590  x = getWindow()->getWidth() - 400;
591  y = 64;
592  int x2 = getWindow()->getWidth() * 0.5;
594  sightSize = 64;
595  int x1 = getWindow()->getWidth() - 440;
596  if(x2 > x1)
597  x = x1;
598  else
599  x=x2;
600  glBegin( GL_QUADS );
601  glTexCoord2f( 0, 1 );
602  glVertex3f(-sightSize + x, sightSize + y, 0);
603  glTexCoord2f( 0, 0 );
604  glVertex3f(-sightSize + x,-sightSize + y, 0);
605  glTexCoord2f( 1, 0 );
606  glVertex3f( sightSize + x,-sightSize + y, 0);
607  glTexCoord2f( 1, 1 );
608  glVertex3f( sightSize + x, sightSize + y, 0);
609  glEnd();
610  glEnable( GL_BLEND );
611 
612  // draw speed and laser heat bar
613  glColor3fv( colorWhite );
614  tf2->print( 10, 76, "Laser heat:" );
615  laserHeatBar->draw( 10, 55, 250, 16 );
616  glColor3fv( colorWhite );
617  tf2->print( 10, 41, "Speed:" );
618  speedBar->draw( 10, 20, 250, 16 );
619  glDisable( GL_BLEND );
620 
621  // draw shield view
622  glPushAttrib( GL_ALL_ATTRIB_BITS );
623  glDisable( GL_TEXTURE_2D );
624  GLfloat colorShieldFront[] = { 1-player->getFrontShieldPowerPercentage(), player->getFrontShieldPowerPercentage(), 0.00f, 1.0f };
625  GLfloat colorShieldBack[]= { 1-player->getFrontShieldPowerPercentage(), player->getFrontShieldPowerPercentage(), 0.00f, 1.0f };
626  Vector3 shieldPos( getWindow()->getWidth() - 56, 56, 0 );
627  Shapes::drawCircleShape( shieldPos, 360, 40, 270, 90, colorShieldFront ); // obere hälfte
628  Shapes::drawCircleShape( shieldPos, 360, 40, 90, 270, colorShieldBack );// untere hälfte
629  glEnable( GL_BLEND );
630  glEnable( GL_TEXTURE_2D );
631  glColor3fv( colorWhite );
632  tf2->print( shieldPos.x - 3 * tf2->getWidth() - 4, shieldPos.y - tf2->getSize() * 0.5, "Shield" );
633  glDisable( GL_BLEND );
634  glDisable( GL_TEXTURE_2D );
635 
636  // draw radar
637  fastMode();
638  glColor3fv( colorWhite );
639  glEnable( GL_BLEND );
640  glEnable( GL_TEXTURE_2D );
642  Vector3 radarPos( getWindow()->getWidth() - 56 - 40 - 56, 56, 0 );
643  Shapes::drawCircleTex( radarPos, 360, 40 );
644  Shapes::drawCircleTex( radarPos, 360, 40 );
645 
646  // draw a red point into the radar
647  Vector3 vEye = ( player->getPos() - World::getWorld()->getStation()->getPos() );
648  vEye.normalize();
649  Vector3 dotPos( 0, 0, 0 );
650  dotPos.x = -vEye.innerProduct( player->getView() * player->getUp() );
651  dotPos.y = -vEye.innerProduct( player->getUp() );
652  float z = -vEye.innerProduct( player->getView() );
653 
654  glDisable( GL_TEXTURE_2D );
655  glDisable( GL_BLEND );
656  // the point indicating position has to be 1/2 * radar size
657  if ( z < 0 )
658  Shapes::drawCircle( radarPos + dotPos*0.5*60, 60, 3, colorDarkRed, colorRed );
659  else
660  Shapes::drawCircle( radarPos + dotPos*0.5*60, 60, 6, colorDarkRed, colorRed );
661 
662  glPopAttrib();
663 
664  // restore procections
665  restoreProjection();
666 }
667 
672 void App::drawGameOver() {
673  glDisable( GL_LIGHTING );
674  glDisable( GL_LIGHT0 );
675  glDisable( GL_BLEND );
676  glDisable( GL_TEXTURE_2D );
677  bf = new BitmapFont( getWindow()->getDC() );
678  bf->buildFont( 20 );
679  glClearColor( 0.0f, 0.0f, 0.0f, 0.2f );
680  glClear( GL_COLOR_BUFFER_BIT );
681 
682  glMatrixMode( GL_MODELVIEW );
683  glLoadIdentity(); // reset the view
684 
685  glLoadIdentity(); // reset the view
686  glTranslatef( 0.0f, 0.0f, -1.0f ); // move a bit into the screen
687  glColor3fv( colorWhite );
688  glRasterPos2f(-0.5,0.3);
689  bf->print("Thank you for playing our Game!");
690  glRasterPos2f(-0.5, 0.15);
691  bf->print("mElite");
692  glRasterPos2f(-0.5, 0.1);
693  bf->print("by Melanie Schmidt & Jan-Philipp Kappmeier");
694  glRasterPos2d(-0.5,-0.3);
695  bf->print("G a m e O v e r");
696  glRasterPos2d(-0.5,-0.4);
697  bf->print("Press any key to exit.");
698  glFlush();
699  delete bf;
700 }
701 
706 void App::drawHelp() {
707  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
708  fastMode();
709  setProjectionOrthogonal();
710 
711  // print text (fps, frametime, etc.)
712  glEnable( GL_BLEND ); // enable blending (for text)
713  glColor3fv( colorWhite );// white color
714 
715  printInfoLine("elite clone");
716  printInfoLine( "copyright 2006 - 2007, Melanie Schmidt & Jan-Philipp Kappmeier");
717  printInfoLine( "" );
718  printInfoLine( "Global keyboard commands (just press the key):" );
719  printInfoLine( " e - show 3D environment in current system." );
720  printInfoLine( " i - show system information for current system." );
721  printInfoLine( " l - show local systems." );
722  printInfoLine( " p - make a screenshot." );
723  printInfoLine( "" );
724  printInfoLine( "Global console commands (press RETURN, enter command, press RETURN):" );
725  printInfoLine( " toggleFullscreen [0|1] - switch to fullscreen or back." );
726  printInfoLine( " showFPS [0|1] - show frames per second or not." );
727  printInfoLine( " showFrameTime [0|1] - show time per frame in milliseconds or not." );
728  printInfoLine( " showSpeed [0|1] - show player speed in absolute values and percent of lightspeed or not." );
729  printInfoLine( " showRes [0|1] - show current resolution or not." );
730  printInfoLine( " devmode [0|1] - enables developer mode or disables." );
731  printInfoLine( " quit - exit the game." );
732  printInfoLine( " help - show this text." );
733  printInfoLine( "" );
734  printInfoLine( "To get further information, there exist different help sites for each screen." );
735  printInfoLine( "Just type in one of the following commands at console:" );
736  printInfoLine( " help info - gives information about the current system screen." );
737  printInfoLine( " help local - gives information about the local systems view." );
738  printInfoLine( " help env - gives information about the 3D environment." );
739 
740  printInfoBox( true );
741 
742  // output if inputmode is on
743  if( m_inputmode ) {
744  this->ti->print();
745  }
746 
747  glDisable( GL_BLEND );
748 
749  restoreProjection();
750 }
751 
756 void App::drawHelpEnvironment() {
757  glClear( GL_COLOR_BUFFER_BIT );
758  fastMode();
759  setProjectionOrthogonal();
760 
761  // print text (fps, frametime, etc.)
762  glEnable( GL_BLEND ); // enable blending (for text)
763  glColor3fv( colorWhite );// white color
764 
765  printInfoLine("elite clone");
766  printInfoLine( "copyright 2006 - 2007, Melanie Schmidt & Jan-Philipp Kappmeier");
767  printInfoLine( "" );
768  printInfoLine( "Keyboard commands for 3D-environment screen (in addition to usual keys):" );
769  printInfoLine( " up key - stick your nose up." );
770  printInfoLine( " down key - stick your nose down." );
771  printInfoLine( " left key - rotate leftwards." );
772  printInfoLine( " right key - rotate rightwards." );
773  printInfoLine( " space - shoot laser." );
774  printInfoLine( " + - increase speed." );
775  printInfoLine( " - - decrease speed." );
776  printInfoLine( " b - toggle back and front view." );
777  printInfoLine( " m - shoot a missile." );
778 
779  printInfoBox( true );
780 
781  // output if inputmode is on
782  if( m_inputmode ) {
783  this->ti->print();
784  }
785 
786  glDisable( GL_BLEND );
787 
788  restoreProjection();}
789 
794 void App::drawHelpInfo() {
795  glClear( GL_COLOR_BUFFER_BIT );
796  fastMode();
797  setProjectionOrthogonal();
798 
799  glEnable( GL_BLEND ); // enable blending (for text)
800  glColor3fv( colorWhite );
801 
802  printInfoLine("elite clone");
803  printInfoLine( "copyright 2006 - 2007, Melanie Schmidt & Jan-Philipp Kappmeier");
804  printInfoLine( "" );
805  printInfoLine( "Keyboard commands for info screen (in addition to usual keys):" );
806  printInfoLine( " arrow keys - move view of the system" );
807  printInfoLine( " + - zoom in." );
808  printInfoLine( " - - zoom out." );
809 
810  printInfoBox( true );
811 
812  // output if inputmode is on
813  if( m_inputmode ) {
814  this->ti->print();
815  }
816 
817  glDisable( GL_BLEND );
818 
819  restoreProjection();
820 }
821 
826 void App::drawHelpLocal() {
827  glClear( GL_COLOR_BUFFER_BIT );
828  fastMode();
829  setProjectionOrthogonal();
830 
831  // print text (fps, frametime, etc.)
832  glEnable( GL_BLEND ); // enable blending (for text)
833  glColor3fv( colorWhite );// white color
834 
835  printInfoLine("elite clone");
836  printInfoLine( "copyright 2006 - 2007, Melanie Schmidt & Jan-Philipp Kappmeier");
837  printInfoLine( "" );
838  printInfoLine( "Keyboard commands for local screen (in addition to usual keys):" );
839  printInfoLine( "-only mouse input possible-" );
840  printInfoLine( "Mouse actions:" );
841  printInfoLine( "- go over a system to see information about it (only possible if system is in local range)" );
842  printInfoLine( "- click on a system to perform jump (only possible if system is reachable)" );
843  printInfoLine( "- confirm jump in messagebox (after clicking on a reachable system)" );
844 
845  printInfoBox( true );
846 
847  // output if inputmode is on
848  if( m_inputmode ) {
849  this->ti->print();
850  }
851 
852  glDisable( GL_BLEND );
853 
854  restoreProjection();
855 }
856 
861 void App::drawHelpMarketplace() {
862  glClear( GL_COLOR_BUFFER_BIT );
863  fastMode();
864  setProjectionOrthogonal();
865 
866  // print text (fps, frametime, etc.)
867  glEnable( GL_BLEND ); // enable blending (for text)
868  glColor3fv( colorWhite );// white color
869 
870  printInfoLine("elite clone");
871  printInfoLine( "copyright 2006 - 2007, Melanie Schmidt & Jan-Philipp Kappmeier");
872  printInfoLine( "" );
873  printInfoLine( "The marketplace:" );
874  printInfoLine( "Here you can buy and sell tradegoods. " );
875  printInfoLine( "Keyboard commands for marketplace screen:" );
876  printInfoLine( "-only mouse input possible-" );
877  printInfoLine( "Mouse actions:" );
878  printInfoLine( "- click on tradegood button - mark the good for selling / buying " );
879  printInfoLine( "- click on buy / sell button - buys / sells one unit of the market good" );
880  printInfoLine( "" );
881  printInfoLine( "Note that buttons can be inactive!" );
882  printInfoLine( "" );
883  printInfoLine( "Rules for the buying:" );
884  printInfoLine( "- you can only buy goods that are available" );
885  printInfoLine( "- you can only buy goods that fit into your cargo bay (only tonnes count)" );
886  printInfoLine( "- you can only buy goods if you have enough money" );
887  printInfoLine( "- there is an infinite amount of fuel" );
888  printInfoLine( "- you cannot buy more fuel than fits into your tank" );
889  printInfoLine( "" );
890  printInfoLine( "Rules for selling:" );
891  printInfoLine( "- you can only sell goods that you have in your cargo bay" );
892  printInfoLine( "- fuel cannot be sold" );
893 
894  printInfoBox( true );
895 
896  // output if inputmode is on
897  if( m_inputmode ) {
898  this->ti->print();
899  }
900 
901  glDisable( GL_BLEND );
902 
903  restoreProjection();
904 }
905 
914 void App::drawLocalSystems() {
915  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
916 
917  // set hit object to none in case that no object is being hit
920 
921  // information for gapsize and so on (writing text)
922  int gap = 10;
923  int size = tf2->getSize();
924  int width = tf2->getWidth();
925  int lines = 1;
926 
927  // set up an orthogonal screen for printing text and painting the board
928  glMatrixMode( GL_PROJECTION );
929  glPushMatrix();
930  glLoadIdentity();
931  glOrtho( 0,
932  getWindow()->getWidth(),
933  0,
934  getWindow()->getHeight(),
935  -100,
936  100
937  );
938  glMatrixMode( GL_MODELVIEW );
939  glPushMatrix();
940  glLoadIdentity();
941 
942  // find out maximal/minimal x and y positions
943  // set minimal and maximal position in a way that the circle with the maximum-reachable distance is visible
945  Position maxPos, minPos;
946  // maxfuel = 7
947  maxPos.x = currentSystem.pos.x + World::getWorld()->getMaxFuel()*2.5;//World::getWorld()->getPlayerStatus()->fuel * 2.5;
948  minPos.x = currentSystem.pos.x - World::getWorld()->getMaxFuel()*2.5;//World::getWorld()->getPlayerStatus()->fuel * 2.5;
949  if(minPos.x > 500)
950  minPos.x = 0;
951  maxPos.y = currentSystem.pos.y + World::getWorld()->getMaxFuel()*2.5;//World::getWorld()->getPlayerStatus()->fuel * 2.5;
952  minPos.y = currentSystem.pos.y - World::getWorld()->getMaxFuel()*2.5;//World::getWorld()->getPlayerStatus()->fuel * 2.5;
953  if(minPos.y > 500)
954  minPos.y = 0;
955 
956  // size of the near environment
957  int envWidth = maxPos.x - minPos.x;
958  int envHeight = maxPos.y - minPos.y;
959 
960  // add some border value
961  int border = 30;
962 
963  // calculate ratio
964  float scaleFactor = min( (float)(getWindow()->getWidth()-border) / (float) envWidth, (float)(getWindow()->getHeight()-border) / (float) envHeight );
965  float xOffset = max( border*0.5, (getWindow()->getWidth() - border-scaleFactor*envWidth )*0.5 );
966  float yOffset = max( border*0.5, (getWindow()->getHeight()- border-scaleFactor*envHeight)*0.5 );
967 
968  // get all systems that fit into the screen!*0.5 --> therefore claculate some additional x and y space used
969  float xPlus = max( 0.0f, (float)((float)(getWindow()->getWidth() -border) - ((maxPos.x - minPos.x) * scaleFactor + xOffset)) / scaleFactor);
970  float yPlus = max( 0.0f, (float)((float)(getWindow()->getHeight()-border) - ((maxPos.y - minPos.y) * scaleFactor + yOffset)) / scaleFactor);
971  vector<SystemInfo> * localSystems = World::getWorld()->getSystems( max( 0.0f, minPos.x - xPlus ),
972  maxPos.x + xPlus,
973  max( 1.0f, minPos.y - yPlus ),
974  maxPos.y + yPlus
975  );
976 
977  fullMode();
978  for( unsigned int i = 0; i < localSystems->size(); i++ ) {
979  Star *sun = new Star( (localSystems->at(i).pos.x - minPos.x) * scaleFactor + xOffset,
980  getWindow()->getHeight()+border*0.5-((localSystems->at(i).pos.y - minPos.y) * scaleFactor + yOffset),
981  -20,
982  1,
983  star
984  );
985  sun->setLightColor( 1, 1, 0 );
986  //sun->setTexture( Textures::getTextures()->getTexture( star_sun ) );
987  //sun->setTexture( World::getWorld()->getSystemStarTexture( localSystems->at(i).systemNumber ) );
988  //sun->setTexture( star );
989  sun->setAxis( 0, 1, 0 );
990  sun->setSpeed( -0.006);
991  sun->setRotateAngle( 0 );
992  sun->setRotateSpeed( 0 );
993  glPushAttrib( GL_ALL_ATTRIB_BITS );
994  sun->draw();
995  glPopAttrib();
996  delete sun;
997  }
998  fastMode();
999  // print the system names
1000  glEnable( GL_BLEND ); // enable blending (for text), remainds active after resetting projection!
1001  glColor3fv( colorWhite );
1002 
1003  // position for mouse-position-rectangle
1004  Position rectPosStart;
1005  Position rectPosEnd;
1006 
1007  // print text for all planets.
1008  // 1. calculate positions of an rect lying over text that is to be printed
1009  // 2. check if mouse position is above, in that case set hit object info
1010  // 3. if that is the case, switch color
1011  // 4. print the text
1012  SystemInfo hoveredSystem;
1013  hoveredSystem.systemNumber = -1;// intialization to save if a system was hit
1014  bool alreadyHighlighted = false;
1015  for( unsigned int i=0; i<localSystems->size(); i++) {
1016  rectPosStart.x = (localSystems->at(i).pos.x - minPos.x) * scaleFactor + xOffset; // left border
1017  rectPosEnd.y = getWindow()->getHeight()+border*0.5-((localSystems->at(i).pos.y - minPos.y) * scaleFactor + yOffset); // lower border ----> print uses lower border as startposition!
1018  int paintPosy = rectPosEnd.y;
1019  // switch positions as the mouse coordinates start with 0 in the upper left corner!
1020  rectPosEnd.y = getWindow()->getHeight() - rectPosEnd.y;
1021  rectPosStart.y = rectPosEnd.y - size; // opper border, size is height of writing
1022  rectPosEnd.x = rectPosStart.x + width * localSystems->at(i).name.length(); // right border
1023 
1024  if( mouse->isMouseOverRect( rectPosStart.x,
1025  rectPosEnd.x,
1026  rectPosStart.y,
1027  rectPosEnd.y
1028  )
1029  && !alreadyHighlighted
1030  && World::getWorld()->isSystemLocal(localSystems->at(i).systemNumber ) // perform this test in class!
1031  ) {
1032  // save hit info
1033  hoveredSystem = localSystems->at(i);
1035  mouse->setHittedObjectInfo( localSystems->at(i).systemNumber );
1036  // print system info
1037  if( World::getWorld()->isSystemReachable( localSystems->at(i).systemNumber ) )
1038  glColor3fv( colorRed );
1039  else
1040  glColor3fv( colorYellow ); // this will (maybe) lead to an brighter yellow because planet is drawn twice
1041 
1042  tf2->print( rectPosStart.x,
1043  paintPosy,
1044  localSystems->at(i).name.c_str()
1045  );
1046  //glColor3fv( colorWhite );
1047  alreadyHighlighted = true;
1048  } else
1049  // if system is local, use yellow color
1050  if( World::getWorld()->isSystemLocal( localSystems->at(i).systemNumber ) )
1051  glColor3fv( colorYellow );
1052  else
1053  glColor3fv( colorWhite );
1054  tf2->print( rectPosStart.x,
1055  paintPosy,
1056  localSystems->at(i).name.c_str()
1057  );
1058  }
1059  delete localSystems;
1060 
1061  // draw the planet information in an box under the planet (TODO: if the planet is at the bottom, maybe draw on top?
1062  // draw information only, if planet is local (that means, reachable with full fuel)
1063  if( hoveredSystem.systemNumber != -1 && World::getWorld()->isSystemLocal( hoveredSystem.systemNumber) ) {
1064  // set hovered object to none if the object is not reachable with current fuel amount
1065  if( !World::getWorld()->isSystemReachable( hoveredSystem.systemNumber ) )
1067  // print
1068  int infoPosx = (hoveredSystem.pos.x - minPos.x) * scaleFactor + xOffset; // left border
1069  int infoPosy = getWindow()->getHeight()+border*0.5-((hoveredSystem.pos.y - minPos.y) * scaleFactor + yOffset); // lower border ----> print uses lower border as startposition!
1070 
1071  // create strings for information output
1072  string government = "Government: " + World::getWorld()->getGovernmentString( hoveredSystem.government );
1073  string economy = "Economy: " + World::getWorld()->getEconomyString( hoveredSystem.economy );
1074 
1075  //tf2->print( gap, getWindow()->getHeight() - gap - lines++*size, "Position: (%d,%d)", sysinfo.pos.x, sysinfo.pos.y );
1076  tf2->print( infoPosx, infoPosy - lines++*size, economy.c_str() );
1077  tf2->print( infoPosx, infoPosy - lines++*size, "Population: %d", hoveredSystem.population );
1078  tf2->print( infoPosx, infoPosy - lines++*size, "Productivity: %d", hoveredSystem.productivity );
1079  tf2->print( infoPosx, infoPosy - lines++*size, "Technology level: %d", hoveredSystem.techLevel );
1080  tf2->print( infoPosx, infoPosy - lines++*size, government.c_str() );
1081  }
1082 
1083  // print input text
1084  glColor3fv( colorWhite );
1085  if( m_inputmode ) {
1086  this->ti->print();
1087  }
1088 
1089  glDisable( GL_BLEND );
1090 
1091  // draw dashed cirle that indicates systems in reachable distance
1092  glDisable( GL_TEXTURE_2D );
1093  Shapes::drawCircleShapeDashed( (World::getWorld()->getSystemInfo().pos.x - minPos.x) * scaleFactor + xOffset,
1094  getWindow()->getHeight()+border*0.5-((World::getWorld()->getSystemInfo().pos.y - minPos.y) * scaleFactor + yOffset),
1095  0,
1096  720,
1097  World::getWorld()->getPlayerStatus()->fuel * 2.5 * scaleFactor,
1098  colorLightGrey
1099  );
1100 
1101  glEnable( GL_TEXTURE_2D );
1102 
1103  // restore procections
1104  glMatrixMode( GL_PROJECTION );
1105  glPopMatrix();
1106  glMatrixMode( GL_MODELVIEW );
1107  glPopMatrix();
1108 }
1109 
1119 void App::drawMarketplace() {
1120  /* clear the screen */
1121  glClearColor( 0.0f, 0.0f, 0.0f, 0.2f );
1122  glClear( GL_COLOR_BUFFER_BIT );
1123 
1124  /* the number of tradegoods is one higher than in the txtelite-game,
1125  because fuel is treated as a tradegood as well. when contacting
1126  the txtelite-game, the last tradegood must be done in a special case */
1127  size_t numOfTradegoods = mktbuttons.size();
1128 
1129  for (unsigned int i =0; i < numOfTradegoods; i++)
1130  mktbuttons.at(i)->switchOn();
1131  buybutton->switchOn();
1132  sellbutton->switchOn();
1133 
1134  float tabularheight = 0.75;
1135  float tabular = 0.05;
1136  float headlines = tabular;
1137  float buysell = tabular+0.02;
1138  float infos = buysell+0.06;
1139  float helplines = tabularheight+infos+0.03;
1140  float helplineheight = 0.02;
1141 
1142 
1143  /* set up a ortho projection for 2D painting */
1144  this->setProjectionOrthogonal();
1145 
1146  /* adjust button position to window size */
1147 
1148  unsigned int wwidth = getWindow()->getWidth();
1149  unsigned int wheight = getWindow()->getHeight();
1150 
1151  unsigned int startx = wwidth / 4;
1152  unsigned int jumpy = wheight*tabularheight / (numOfTradegoods+1);
1153 
1154  for (unsigned int i=0; i < numOfTradegoods; i++)
1155  {
1156  mktbuttons.at(i)->setCenter(startx,wheight-(i+1)*jumpy-tabular*wheight);
1157  mktbuttons.at(i)->setWindowDimensions(wwidth,wheight);
1158  }
1159 
1160  /* position buy and sell button under the markenplace items */
1161  int leftdrift = 0;
1162  if (mktbuttons.size()>0)
1163  leftdrift = (mktbuttons.at(0)->getButtonWidth())/2.0f;
1164  int rightdrift = (buybutton->getButtonWidth())/2.0f;
1165 
1166  buybutton->setCenter(startx-leftdrift+rightdrift, wheight-(numOfTradegoods+1)*jumpy-buysell*wheight);
1167  buybutton->setWindowDimensions(wwidth,wheight);
1168 
1169  rightdrift = leftdrift;
1170  leftdrift = (sellbutton->getButtonWidth())/2.0f;
1171 
1172  sellbutton->setCenter(startx-leftdrift+rightdrift, wheight-(numOfTradegoods+1)*jumpy-buysell*wheight);
1173  sellbutton->setWindowDimensions(wwidth,wheight);
1174 
1175  /* initialize two vectors for saving which items are buyable and sellable */
1176 
1177  std::vector<bool> buyable;
1178  std::vector<bool> sellable;
1179  buyable.reserve(numOfTradegoods);
1180  sellable.reserve(numOfTradegoods);
1181 
1182  {
1183  int freeHoldspace = World::getWorld()->getFreeHoldspace();
1184  for ( unsigned int i = 0; i < numOfTradegoods-1; i++)
1185  {
1186  buyable.push_back( !World::getWorld()->tradegoodIsInTons(i) || (freeHoldspace > 0) );
1187  sellable.push_back( true );
1188  }
1189  }
1190 
1191  /* entries for fuel */
1192  buyable.push_back( World::getWorld()->getMaxFuel() != World::getWorld()->getFuelAmount());
1193  sellable.push_back(false);
1194 
1195  /* print prices and availabilities of actual marketplace */
1196 
1197  std::vector<MarketplaceItem> * mktplace = World::getWorld()->getCurrentMarketplace();
1198 
1199  glPushAttrib( GL_ALL_ATTRIB_BITS );
1200 
1201  glEnable( GL_TEXTURE_2D );
1202  glDisable( GL_LIGHTING );
1203  glEnable( GL_BLEND );
1204 
1205  int currentCash = World::getWorld()->getCurrentCash();
1206 
1207  /* print prices */
1208  int downdrift = 0;
1209  if (mktbuttons.size()>0)
1210  downdrift = (mktbuttons.at(0)->getButtonInnerHeight())/2.0f;
1211 
1212  rightdrift = 0;
1213 
1214  if (mktbuttons.size()>0)
1215  rightdrift = (mktbuttons.at(0)->getButtonWidth())*0.75;
1216 
1217  glColor3fv(colorWhite);
1218  tf2->print(startx+rightdrift, wheight-headlines*wheight-downdrift, "Price");
1219 
1220  for (unsigned int i=0; i < numOfTradegoods; i++)
1221  {
1222  double price =0;
1223  if (i < numOfTradegoods-1)
1224  {
1225  price = mktplace->at(i).price;
1226  }
1227  else
1228  {
1229  price = World::getWorld()->getFuelCost();
1230  }
1231 
1232  if (currentCash >= price)
1233  glColor3fv(colorGreen);
1234  else
1235  {
1236  buyable[i] = false;
1237  glColor3fv(colorWhite);
1238  }
1239 
1240  tf2->print(startx+rightdrift, wheight-(i+1)*jumpy-tabular*wheight-downdrift, "%3.1f",price);
1241 
1242  }
1243 
1244  /* print how much is available */
1245 
1246  rightdrift = 0;
1247 
1248  if (mktbuttons.size()>0)
1249  rightdrift = (mktbuttons.at(0)->getButtonWidth())*1.5;
1250 
1251  glColor3fv(colorWhite);
1252  tf2->print(startx+rightdrift, wheight-headlines*wheight-downdrift, "Market");
1253 
1254  for (unsigned int i=0; i < numOfTradegoods-1; i++)
1255  {
1256 
1257  if (mktplace->at(i).amount > 0)
1258  glColor3fv(colorGreen);
1259  else
1260  {
1261  glColor3fv(colorWhite);
1262  buyable[i] = false;
1263  }
1264 
1265  std::string sunit = World::getWorld()->getTradegoodDescription(i).unit;
1266  const char * unit = sunit.c_str();
1267 
1268  tf2->print(startx+rightdrift, wheight-(i+1)*jumpy-tabular*wheight-downdrift, "%d %s",mktplace->at(i).amount, unit);
1269 
1270  }
1271 
1272  /* print how much we have of each tradegood */
1273 
1274  std::vector<int> * currentCargo = World::getWorld()->getCurrentCargo();
1275  float fuelamount = World::getWorld()->getFuelAmount();
1276 
1277  rightdrift = 0;
1278 
1279  if (mktbuttons.size()>0)
1280  rightdrift = (mktbuttons.at(0)->getButtonWidth())*2.25;
1281 
1282  glColor3fv(colorWhite);
1283  tf2->print(startx+rightdrift, wheight-headlines*wheight-downdrift, "Cargo");
1284 
1285  for (unsigned int i=0; i < numOfTradegoods; i++)
1286  {
1287  if (i < numOfTradegoods-1)
1288  {
1289  if (currentCargo->at(i)>0)
1290  glColor3fv(colorGreen);
1291  else
1292  {
1293  glColor3fv(colorWhite);
1294  sellable[i] = false;
1295  }
1296 
1297  std::string sunit = World::getWorld()->getTradegoodDescription(i).unit;
1298  const char * unit = sunit.c_str();
1299 
1300  tf2->print(startx+rightdrift, wheight-(i+1)*jumpy-tabular*wheight-downdrift, "%d %s",currentCargo->at(i),unit);
1301  }
1302  else
1303  {
1304  /* print fuel amount here as well, but never green, because it cannot be sold */
1305  glColor3fv(colorWhite);
1306  tf2->print(startx+rightdrift, wheight-(i+1)*jumpy-tabular*wheight-downdrift, "%3.1f %s",fuelamount,"LY");
1307  }
1308  }
1309 
1310  /* print current cash, holdspace and fuel */
1311  glColor3fv(colorWhite);
1312 
1313  leftdrift = 0;
1314  if (mktbuttons.size()>0)
1315  leftdrift = (mktbuttons.at(0)->getButtonWidth())/2.0f;
1316 
1317  if (fuelamount == World::getWorld()->getMaxFuel())
1318  tf2->print(startx-leftdrift, wheight-(numOfTradegoods+1)*jumpy-infos*wheight,"Cash: %3.1fFuel: %3.1f (max)HoldSpace: %i",World::getWorld()->getCurrentCash(),fuelamount,World::getWorld()->getFreeHoldspace());
1319  else
1320  tf2->print(startx-leftdrift, wheight-(numOfTradegoods+1)*jumpy-infos*wheight,"Cash: %3.1fFuel: %3.1fHoldSpace: %i",World::getWorld()->getCurrentCash(),fuelamount,World::getWorld()->getFreeHoldspace());
1321 
1322  /* print help lines */
1323  tf2->print(startx-leftdrift, wheight-helplines*wheight,"- Click on item you want to buy / sell.");
1324  tf2->print(startx-leftdrift, wheight-helplineheight*wheight-helplines*wheight,"- Click on buy / sell to buy / sell one unit of the chosen tradegood.");
1325 
1326  /* activate buttons if tradegood can be bought / sold */
1327 
1328  for (unsigned int i=0; i < numOfTradegoods; i++)
1329  {
1330  if (!sellable[i] && !buyable[i])
1331  mktbuttons.at(i)->deactivateButton();
1332  else
1333  mktbuttons.at(i)->activateButton();
1334  }
1335 
1336  if (chosenButton > -1 && buyable[chosenButton])
1337  buybutton->activateButton();
1338  else
1339  buybutton->deactivateButton();
1340  if (chosenButton > -1 && sellable[chosenButton])
1341  sellbutton->activateButton();
1342  else
1343  sellbutton->deactivateButton();
1344 
1345  /* inform buttons about mouse clicks */
1346  if (getWindow()->getMouseClick())
1347  {
1348  ClickableObject::clickAll();
1349  getWindow()->setMouseClick(false);
1350 
1351  bool noButton = true;
1352  for (unsigned int i = 0; i < numOfTradegoods; i++)
1353  {
1354  if (mktbuttons.at(i)->isClicked())
1355  {
1356  noButton = false;
1357  if ( chosenButton == -1 )
1358  {
1359  chosenButton = i;
1360  }
1361  else
1362  { if ( chosenButton != i )
1363  {
1364  mktbuttons.at(chosenButton)->noClick();
1365  chosenButton = i;
1366  }
1367  }
1368  }
1369  }
1370  if (noButton)
1371  chosenButton = -1;
1372 
1373  }
1374 
1375  if (buybutton->isClicked())
1376  {
1377  if ((unsigned)chosenButton == numOfTradegoods-1) World::getWorld()->buyFuel(1);
1378  if ((unsigned)chosenButton < numOfTradegoods-1) World::getWorld()->performPurchase(chosenButton,1);
1379  buybutton->noClick();
1380  }
1381 
1382  if (sellbutton->isClicked())
1383  {
1384  if ((unsigned)chosenButton < numOfTradegoods-1) World::getWorld()->performSale(chosenButton,1);
1385  sellbutton->noClick();
1386  }
1387 
1388  /* draw all buttons */
1389  ClickableObject::drawAll();
1390 
1391  for (unsigned int i =0; i < numOfTradegoods; i++)
1392  mktbuttons.at(i)->switchOff();
1393  buybutton->switchOff();
1394  sellbutton->switchOff();
1395 
1396  // output if inputmode is on
1397  if( m_inputmode ) {
1398  this->ti->print();
1399  }
1400 
1401  glPopAttrib();
1402 
1403  /* restore matrices */
1404  this->restoreProjection();
1405 }
1406 
1415 void App::drawSystemInfo() {
1416  fullMode();
1417  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
1418 
1419  // set up perspective projection, after that it should be possible to draw in a rect -50, 50 both, in x and y
1420  float projectionSize = 1000.0f;
1421  glMatrixMode( GL_PROJECTION );
1422  glPushMatrix();
1423  glLoadIdentity();
1424  static float nearClip = -1;// set to negative, test if zero does not work with float!
1425  static float clipSize; // size of near clipping plane, calculated in the next block
1426  if( nearClip <= 0) {
1427  // folgendes berechnet mit der def. von cosinus die länge der einen seite des frustums bis zur y-achse.
1428  // es ist gewünscht, daß an den achsen eine breite des frustums von projectionSize vorliegt.
1429  double val = (M_PI * 76.5)/ 180.0;
1430  double len1 = (projectionSize * (double)0.5) / ( cos(val) );
1431  // wende satz von pythagoras an um die länge auf der z-achse bis in den koordinaten ursprung des gleichen
1432  // dreiecks zu berechne
1433  double len2 = sqrt( (double)(projectionSize*0.5)*(double)(projectionSize*0.5) + len1*len1 );
1434  nearClip = (float)(len2-projectionSize*0.5);
1435  // calculate clip size
1436  clipSize = (nearClip / len2) * projectionSize*0.5;
1437  }
1438  glFrustum( -clipSize*getWindow()->getAspect(), clipSize*getWindow()->getAspect(), -clipSize, clipSize, nearClip, nearClip+projectionSize+1000);
1439  cameraSystemView->setPos( cameraSystemView->getPos().x, cameraSystemView->getPos().y, (-1*nearClip)-(projectionSize*0.5));
1440  Vector3 v( 0, 0, 1 );
1443 
1444  glMatrixMode( GL_MODELVIEW );
1445  glPushMatrix();
1446  glLoadIdentity();
1447 
1448  // szene drehen
1449  glRotatef( systemInfoViewAngle, 1, 0, 0 );
1450  glRotatef( systemInfoViewAngle2, 0, 0, 1 );
1451 
1452 
1453  vector<PlanetInfoGraphical> planets;
1454  SystemInfo sysinfo;
1455  if( devmode ) {
1456  sysinfo = World::getWorld()->getSystemInfo( currentSystemInfoNumber );
1457  planets = *World::getWorld()->getSystemPlanets( currentSystemInfoNumber );
1458  } else {
1459  sysinfo = World::getWorld()->getSystemInfo();
1460  planets = *World::getWorld()->getSystemPlanets();
1461  }
1462 
1463  // retrieve size
1464  float sysSize = 0;
1465  for( unsigned int i = 0; i < planets.size(); i++) {
1466  PlanetInfoGraphical planet = planets[i];
1467  if( planet.distance > sysSize )
1468  sysSize = planet.distance;
1469  }
1470  size_t numberOfPlanets = planets.size();
1471 
1472 
1473  float scaleFactor = (projectionSize * 0.5) / sysSize;
1474 
1475  // this scales the scene to be full-screen-wide (if size is wider than tall)
1476  //scaleFactor *= getWindow()->getAspect();
1477 
1478  // star
1479  Star *sun = new Star( 0, 0, 0, 2*zoomFactor*10, star );
1480  sun->setLightColor( 1, 1, 0);
1481  sun->setAxis( 0, 1, 0 );
1482  sun->setSpeed( -0.006);
1483  sun->setRotateAngle( 0 );
1484  sun->setRotateSpeed( 0 );
1485  glPushAttrib( GL_ALL_ATTRIB_BITS );
1486  sun->draw();
1487  glPopAttrib();
1488  delete sun;
1489 
1490  // draw planets
1491  for( unsigned int i=0; i < planets.size(); i++) {
1492  PlanetInfoGraphical planet = planets[i];
1493  Planet *erde2 = new Planet( planet.distance * scaleFactor * zoomFactor + zoomFactor*10 , 0, 0, 0.7*zoomFactor *10, planet1+i);
1494  // WARNING: this is possibly unsave. it only works if all planets in the texture-slot are in order!
1495  //erde2->setTexture( planet1 + i );
1496  erde2->setAxis( 0, 1, 0 );
1497  erde2->setSpeed( planet.spinningSpeed );
1498  erde2->setRotateAngle( planet.rotateAngle );
1499  erde2->setRotateSpeed( -1.0 * planet.rotateSpeed * 100);
1500  erde2->setRadiusLineDrawing( true );
1501  //erde2->setRotateSpeed ( erde2->getRotateSpeed() );
1502  erde2->draw();
1503  delete erde2;
1504  }
1505 
1506  // restore projection
1507  glMatrixMode( GL_PROJECTION );
1508  glPopMatrix();
1509  glMatrixMode( GL_MODELVIEW );
1510  glPopMatrix();
1511  glViewport( 0, 0, getWindow()->getWidth(), getWindow()->getHeight() );
1512 
1513  // switch to fast mode and orthogonal screen to print the information text
1514  fastMode();
1515  glMatrixMode(GL_PROJECTION);
1516  glPushMatrix();
1517  glLoadIdentity();
1518  glOrtho( 0, getWindow()->getWidth(), 0, getWindow()->getHeight(), -1, 1 ); // full size orthogonal screen
1519  glMatrixMode( GL_MODELVIEW );
1520  glPushMatrix();
1521  glLoadIdentity();
1522 
1523  // print information
1524  glEnable( GL_BLEND ); // enable blending (for text)
1525  glColor3fv( colorRed );// red color
1526 
1527  // create strings for information output
1528  string name = "Name: " + sysinfo.name;
1529  string government = "Government: " + World::getWorld()->getGovernmentString( sysinfo.government );
1530  string description = "Description: " + sysinfo.description;
1531  string economy = "Economy: " + World::getWorld()->getEconomyString( sysinfo.economy );
1532 
1533  printInfoLine( "System Info:" );
1534  printInfoLine( "" );
1535  printInfoLine( name.c_str() );
1536  if( devmode )
1537  printInfoLine( "Systemnumber: %d", sysinfo.systemNumber );
1538  printInfoLine( "Number of planets: %d", numberOfPlanets );
1539  if( devmode )
1540  printInfoLine( "Position: (%d, %d)", sysinfo.pos.x, sysinfo.pos.y );
1541  printInfoLine( economy.c_str() );
1542  printInfoLine( "Population: %d", sysinfo.population );
1543  printInfoLine( "Productivity: %d", sysinfo.productivity );
1544  printInfoLine( "Radius: %d", sysinfo.radius );
1545  printInfoLine( "Technology level: %d", sysinfo.techLevel );
1546  printInfoLine( government.c_str() );
1547  printInfoLine( description.c_str() );
1548 
1549  printInfoBox( true );
1550 
1551  // output if inputmode is on
1552  if( m_inputmode ) {
1553  this->ti->print();
1554  }
1555 
1556  glDisable( GL_BLEND );
1557 
1558  // restore procections
1559  glMatrixMode( GL_PROJECTION );
1560  glPopMatrix();
1561  glMatrixMode( GL_MODELVIEW );
1562  glPopMatrix();
1563 }
1564 
1576  // print a loading information. no textures are present so use a bitmap font object
1577  bf = new BitmapFont( getWindow()->getDC() );
1578  bf->buildFont( 20 );
1579  glClearColor( 0.0f, 0.0f, 0.0f, 0.2f );
1580  glClear( GL_COLOR_BUFFER_BIT );
1581  glLoadIdentity(); // reset the view
1582  glTranslatef( 0.0f, 0.0f, -1.0f ); // move a bit into the screen
1583  glColor3fv( colorWhite );// white color
1584  glRasterPos2f(-0.5,0.3);
1585  bf->print("Progetto per Grafica al Calcolatore");
1586  glRasterPos2f(-0.5, 0.15);
1587  bf->print("Jan-Philipp Kappmeier");
1588  glRasterPos2f(-0.5, 0.1);
1589  bf->print("Melanie Schmidt");
1590  glRasterPos2d(-0.5,-0.3);
1591  bf->print("Loading in progress. Please stand by ...");
1592  glRasterPos2d(-0.5,-0.4);
1593  bf->print("Press 'help' at console for possible commands. (To show console press 'Return'.)");
1594  glFlush();
1595  getWindow()->swap();
1596 
1597  // OpenGL initialization, loading of memory-resistent textures
1598  initializeGFX();
1600 
1601  // create quadric, will be used for skysphere
1602  quadObj = gluNewQuadric();
1603  gluQuadricDrawStyle( quadObj, GLU_FILL );
1604  gluQuadricTexture( quadObj, GL_TRUE );
1605 
1606  // load texturefonts
1607  tf = new TextureFont( font2 );
1608  tf->buildFont( 16, 8, 16, 16, 10 );
1609  tf2 = new TextureFont( font1 );
1610  tf2->buildFont( 16, 8, 16, 12, 8 );
1611 
1612  // create objects
1613  ti = new TextInput( tf2 );
1614  con = new Console();
1615  frustum = new Frustum( getWindow()->getFrustum() );
1616  mouse = new MouseHandler();
1617  laserHeatBar = new HudLoadBar( 0.0f, 100.0f, 0.0f );
1618  laserHeatBar->setSlopePixel( 10 );
1619 
1620  // load game
1622  initializeObjects();
1623  initMarketplace();
1624 
1627  //player->setView( Vector3(0, 0, 1) );
1628  //player->setPos( 10000,10000,10000 );
1629 
1630  speedBar = new HudLoadBar( player->getMinSpeed(), player->getMaxSpeed(), player->getSpeed() );
1631  speedBar->setSlopePixel( 10 );
1632 
1633  // delete bitmap font
1634  delete bf;
1635  resizeDraw( true );// enable repainting while resizing
1636 
1637  //SpaceShip *ship;
1638  //ship = World::getWorld()->createNewSpaceShip( ball, 1 );
1639  //ship->setPos( 10010, 10010, 10050 );
1640  //ship->setSpeed( 0.00f );
1641 
1642 /* ship = World::getWorld()->createNewSpaceShip( anaconda, 1 );
1643  ship->setPos( 5, 5, 4150 );
1644  ship->setSpeed( 0.01f );
1645  ship = World::getWorld()->createNewSpaceShip( missile, 1 );
1646  ship->setPos( -5, 0, 4150 );
1647  ship->setSpeed( 0.01f );
1648  ship = World::getWorld()->createNewSpaceShip( thargoid, 1 );
1649  ship->setPos( 0, 5, 4150 );
1650  ship->setSpeed( 0.01f );*/
1651  //ship = World::getWorld()->createNewSpaceShip( tieDroid, 1 );
1652  //ship->setPos( 0, -5, 4150 );
1653  //ship->setSpeed( 0.01f );
1654 
1655  loader = new TextureLoaderTGA();
1656  return true;
1657 }
1658 
1663 void App::initializeGFX( void ) {
1664  // do all the opengl-initialization
1665  glShadeModel( GL_SMOOTH ); // activate smooth-shading (Gauraud)
1666  glClearDepth( 1.0f ); // initialize depth-buffer precision
1667  glEnable( GL_DEPTH_TEST ); // enable depth buffer. necessary?
1668  glDepthFunc( GL_LEQUAL ); // quality of depht-testing
1669  glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); // perspective calculations with high precision
1670  //glEnable(GL_CULL_FACE); // enable face culling
1671  glEnable( GL_TEXTURE_2D ); // enable 2D-texturing
1672  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR );
1673 
1674  // inital lights globally
1675  GLfloat ambient_light[] = { 0.0, 0.0, 0.0, 1.0};
1676  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_light);// no ambient light, the sun creates it
1677  GLfloat infinite[] = {0.0};
1678  glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, infinite);// viewer position is infinite
1679  GLfloat one_side[] = {0.0};
1680  glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, one_side);// only light one side of the objects
1681 
1682  // initialize the actual lights
1683  GLfloat ambient_light_sun[] = { 0.35f, 0.35f, 0.35f, 1.0};
1684  glLightfv( GL_LIGHT0, GL_AMBIENT, ambient_light_sun );
1685  GLfloat specular_light_sun[] = { 0.0f, 0.0f, 0.0f, 1.0};
1686  glLightfv( GL_LIGHT0, GL_SPECULAR, specular_light_sun );
1687 }
1688 
1694 void App::initMarketplace() {
1695 
1696  TextureFont * tf3 = new TextureFont( font1 );
1697  tf3->buildFont( 16, 8, 16, 12, 8 );
1698 
1699  int innerBorder = 2;
1700  int outerBorder = 2;
1701 
1702  int numOfTradegoods = World::getWorld()->getNumberOfTradegoods()+1;
1703 
1704  mktbuttons.reserve(numOfTradegoods+2);
1705 
1706  for (int i=0; i < numOfTradegoods-1; i++)
1707  {
1708  mktbuttons.push_back(new Button(innerBorder,outerBorder,mouse,World::getWorld()->getTradegoodDescription(i).name ,tf3,12));
1709  }
1710 
1711  mktbuttons.push_back(new Button(innerBorder,outerBorder,mouse,"Fuel",tf3,12));
1712 
1713  buybutton = new Button(innerBorder,outerBorder,mouse,"Buy",tf3,4);
1714  sellbutton = new Button(innerBorder,outerBorder,mouse,"Sell",tf3,4);
1715 
1716  chosenButton = -1;
1717 }
1718 
1724 void App::initializeObjects() {
1732 }
1733 
1739 void App::update( DWORD deltaTime ) {
1740  if( gameOver ) {
1741  // check if any key was pressed
1742  for( unsigned int i=0; i <256; i++)
1743  if( getWindow()->keyPressed( i ) )
1744  this->terminate();
1745  return;
1746  }
1747  // do some update stuff which is generally executed
1748  getFrameCounter()->update(); // update framecounter to get actual framerate
1749  mouse->setMousePosition( getWindow()->getMousePosition());
1750  mouse->setMouseHovering( false );
1751 
1752  // check the console commandos, available for all game modes
1753  if( getWindow()->keyPressed( 13 ) ) { // go in input mode if 'Return' is pressed
1754  if( !m_inputmode ) {
1755  m_inputmode = true;
1756  ti->reset();
1757  } else {
1758  // send command to console and call local member function
1759  consoleCommand * ptr = table;
1760  while( ptr->command && ptr->arrayAdress > -1) { // searches until the end is found
1761  if( Console::getCommand( ti->getText() ) == ptr->command ) {
1762  (this->*fptr[ptr->arrayAdress])();
1763  }
1764  ptr++;
1765  }
1766  m_inputmode = false;
1767  }
1768  getWindow()->keyUp( 13 );
1769  }
1770 
1771  if( m_inputmode ) { // text input mode is on, all pressed keys go there
1772  performConsoleInput();
1773  } else {// inputmode off, normal commandos and updates. use the different update functison
1774  // first thing, test if the mode should be switched
1775  // if that happend, set new screen mode and quit function, now update is performed
1776  if( getWindow()->keyPressed( 69 ) ) { // test if e was pressed --> show 3d environment
1777  setScreen( currentSystem ); // show 3d-view of current system
1778  getWindow()->keyUp( 69 );
1779  return;
1780  }
1781  if( getWindow()->keyPressed( 73 ) ) { // test if i was pressed --> show info mode
1782  setScreen (systemInfo ); // show system information
1783  getWindow()->keyUp( 73 );
1784  return;
1785  }
1786  if( getWindow()->keyPressed( 76 ) ) { // test if l was pressed --> show local mode
1787  setScreen( localSystems ); // local info anzeigen
1788  getWindow()->keyUp( 76 );
1789  return;
1790  }
1791 
1792  if( getWindow()->keyPressed( 80 ) ) { // test if p was pressed --> create screenshot
1793  // allocate memory
1794  unsigned char *image = 0;
1795  image = new unsigned char[getWindow()->getWidth() * getWindow()->getHeight() * 3];
1796 
1797  // read the image data
1798  glReadPixels( 0, 0, getWindow()->getWidth(), getWindow()->getHeight(), GL_RGB, GL_UNSIGNED_BYTE, image );
1799  TextureLoader * loader = new TextureLoaderTGA();
1800  loader->load( image, getWindow()->getWidth(), getWindow()->getHeight(), 3);
1801  // try to open file
1802  char space[32];
1803  ifstream file;
1804  do {
1805  sprintf_s( space, "screenshot%d.tga", rand() );
1806  file.open( space, ios::binary );
1807  } while( file );
1808  file.close();
1809  loader->write( space );
1810 
1811  // load as image
1813  delete[] image;
1814  getWindow()->keyUp( 80 );
1815  // does not work, however
1816  //TextureLoaderTGA* tga = reinterpret_cast<TextureLoaderTGA*>(loader);
1817  //delete tga;
1818  return;
1819  }
1820 
1821  if( DEV_MODE && getWindow()->keyPressed( 78 ) ) { // test if m was pressed --> show marketplace
1822  currentScreen = marketplace; // enter marketplace
1823  getWindow()->keyUp( 78 );
1824  return;
1825  }
1826 
1827  // let handle other input by the appropriate perform function
1828  switch( currentScreen ) {
1829 case credits:
1830  break;
1831 case currentSystem:
1832  performCurrentSystemInput( deltaTime );
1833  break;
1834 case help:
1835  break;
1836 case helpEnvironment:
1837  break;
1838 case helpInfo:
1839  break;
1840 case helpLocal:
1841  break;
1842 case loadLevel:
1843  break;
1844 case loadProgram:
1845  break;
1846 case localSystems:
1847  performLocalSystemsInput( deltaTime );
1848  break;
1849 case systemInfo:
1850  performSystemInfoInput( deltaTime );
1851  break;
1852  }
1853  }
1854  // call the propriate update functions for the different screen modes
1855  switch( currentScreen ) {
1856 case credits:
1857  break;
1858 case currentSystem:
1859  updateCurrentSystem( deltaTime );
1860  break;
1861 case help:
1862  break;
1863 case helpEnvironment:
1864  break;
1865 case helpInfo:
1866  break;
1867 case helpLocal:
1868  break;
1869 case loadLevel:
1870  break;
1871 case loadProgram:
1872  break;
1873 case localSystems:
1874  updateLocalSystems( deltaTime );
1875  break;
1876 case systemInfo:
1877  updateSystemInfo( deltaTime );
1878  break;
1879  }
1880 }
1881 
1889 void App::stationWasHit(){
1890  vector <PoliceShip*> * pships = World::getWorld()->getPoliceShips();
1891  for (unsigned int i = 0; i < pships->size(); i++)
1892  {
1893  pships->at(i)->stationWasHit();
1894  }
1895  delete pships;
1896 }
1897 
1907 void App::updateCurrentSystem( DWORD deltaTime ) {
1908  // update the game environment in 3d-system-view
1909  // move camera and adjust frustum
1910  player->update( deltaTime );
1912  frustum->update( player );
1913 
1914  // delete all objects that hav hit each other
1917 
1918  // test if on the way to station
1920  if( coriolis->test( player->getPos() ) ) {
1921  setScreen( marketplace ); // enter marketplace
1922  return;
1923  }
1924 
1925  // get all the objects from the world and check if an object was hit or if the player collided with
1926  // an object. the objects have to be deleted after performing the tests
1927  vector<GraphicsObject*> *objects = World::getWorld()->getGraphicObjects();
1928  for( unsigned int i=0; i < objects->size(); i++ ) {// check if we hit another space ship
1929  Vector3 v = objects->at(i)->getPos() - player->getPos();
1930  float distance = v.length();
1931  float shieldDist = objects->at(i)->getRadius() + player->getRadius();
1932  if( distance <shieldDist) {
1933  printInfoLine( "You hit an object");
1934  gameOver = true;
1935  }
1936  }
1937  delete objects;
1938 
1939  vector<SpaceShip*> *ships = World::getWorld()->getSpaceShips();
1940  for( unsigned i=0; i < ships->size(); i++ ) {
1941  ships->at(i)->update( deltaTime );
1942  if( ships->at(i)->isShooting() ) {
1943  //printInfoLine( "You were hit by laser." );
1944  player->receiveHitFront( deltaTime );
1945  if( player->getFrontShieldPower() <= 0 )
1946  //printInfoLine( "You are dead!" );
1947  gameOver = true;
1948  }
1949  }
1950 
1951  if( laserActive ) { // check if laser is active and we hit an object
1952  player->setShoot( true );
1953  laserHeatBar->setCurrent( player->getLaserHeat() );
1954 
1955  SpaceStation * myStation = World::getWorld()->getStation();
1956 
1957  for( unsigned int i=0; i < ships->size()+1; i++ ) {
1958  // check if we hit the the ships by laser
1959  // ships not in frustum can't be hit by laser
1960 
1961  // support for laser hit test with station
1962  Vector3 myPos;
1963  float myRadius;
1964  if (i < ships->size())
1965  {
1966  myPos = ships->at(i)->getPos();
1967  myRadius = ships->at(i)->getRadius();
1968  }
1969  else
1970  {
1971  myPos = myStation->getPos();
1972  myRadius = myStation->getRadius();
1973  }
1974 
1975  CullingLocation res = getFrustum()->isSphereInFrustum( myPos, myRadius );
1976  if( res != outside ) {// ships can't be hit if they are outside the frustum
1977  // (not optimized) calculation of the ray-sphere intersection between the players laser and space ships
1978  Vector3 v = player->getView(); // the current view direction
1979  Vector3 c = myPos;//ships->at(i)->getPos(); // the center of sphere (object position)
1980  Vector3 p = player->getPos(); // the ray initial point
1981  Vector3 u = c-p;
1982  float scalar = v.innerProduct( u );
1983  scalar = scalar / v.length();
1984  Vector3 projectionPosition = p + v * scalar;
1985  Vector3 distance = projectionPosition - c;
1986  float distanceToRay = distance.length();
1987  if( distanceToRay < myRadius ) { //ships->at(i)->getRadius() ) {
1988  // check if projected point is behind or in front of eye point
1989  // pfact is the factor used in the line equation p + pfact*v = projectionPosition.
1990  // it is the same for all three elements of the vector, but it can't be calculated if the entry is zero.
1991  // it can not happen that all three elements of v are zero because v is an orthonormal vector
1992  float pfact;
1993  if(v.x != 0)
1994  pfact = (projectionPosition.x - p.x) / v.x;
1995  else if(v.y != 0)
1996  pfact = (projectionPosition.y - p.y) / v.y;
1997  else if(v.z != 0)
1998  pfact = (projectionPosition.z - p.z) / v.z;
1999  if( pfact > 0 ) {
2000  printInfoLine( "Object hit by laser." );
2001  if (i < ships->size())
2002  ships->at(i)->receiveHitFront( deltaTime );
2003  else
2004  this->stationWasHit();
2005  }
2006  // missing: calculate hit-distance (for accurate drawing of laser ---> if it hit's an object,
2007  // the laser should only be painted 'til it reaches this object
2008  // also it's possible to hit more than one object
2009  }
2010  }
2011  }
2012  } else {// no laser is used
2013  player->setShoot(false);
2014  laserHeatBar->setCurrent( player->getLaserHeat() );
2015  }
2016  delete ships;
2017 }
2018 
2019 void App::updateSystemInfo( DWORD deltaTime ) {
2020 }
2021 
2022 void App::updateLocalSystems( DWORD deltaTime ) {
2023 }
2024 
2029 void App::performConsoleInput() {
2030  // checks for pressed keys. as there is no checking for capital letters, this checking is manually done
2031  if( getWindow()->keyPressed( VK_BACK ) ) {
2032  ti->back();
2033  getWindow()->keyUp( VK_BACK );
2034  }
2035  for( int i = 32; i < 128; i++) {
2036  if( getWindow()->keyPressed( i ) ) {
2037  // check for capital etc
2038  if( i > 64 && i < 92 && !getWindow()->keyPressed( 16 ) ) { // 16 = VK_CAPITAL<-- does not work!
2039  ti->newLetter( i + 32);
2040  getWindow()->keyUp(i);
2041  } else {
2042  ti->newLetter( i );
2043  getWindow()->keyUp( i );
2044  }
2045  }
2046  }
2047 }
2048 
2054 void App::performCurrentSystemInput( DWORD deltaTime ) {
2055  // rear view
2056  if( getWindow()->keyPressed( 66 ) ) { // test if b was pressed --> rear view
2058  getWindow()->keyUp( 66 );
2059  }
2060  if( getWindow()->keyPressed( 77 ) ) { // test if m was pressed --> shoot a missile if possible
2061  if( player->getMissileCount() > 0 && player->getSpeed() > 0 ) {
2063  m->setMaxSpeed( player->getMaxSpeed() + player->getMaxSpeed()*0.3 );
2064  m->setMinSpeed( 0 );
2065  m->setSpeed( player->getSpeed() + player->getMaxSpeed()*0.3 );
2066  m->setView( player->getView() );
2067  m->setPos( player->getPos() + player->getView() * ( player->getRadius() * 10 + 1) );
2068  player->useMissile();
2069  }
2070  getWindow()->keyUp( 77 );
2071  }
2072 
2073  // laser
2074  if( getWindow()->keyPressed( 32 ) ) { // test if space was pressed
2075  if( !player->isOverHeated() )
2076  laserActive=true;
2077  else
2078  laserActive=false;
2079  } else {
2080  laserActive=false;
2081  }
2082 
2083  // enable frame limiter. frame limit is 100 FPS
2084  if( getWindow()->keyPressed( 70 ) ) { // test if f was pressed
2085  if( getFrameLimit() == 0 )
2086  setFrameLimit( 100 );
2087  else
2088  setFrameLimit( 0 );
2089  getWindow()->keyUp( 70 );
2090  }
2091 
2092  // control movement
2093  if( getWindow()->keyPressed( VK_UP ) ) { // test if up was pressed
2094  player->pitch( deltaTime * handlingSpeedMultiplyer );
2095  }
2096  if( getWindow()->keyPressed( VK_DOWN ) ) { // test if down was pressed
2097  player->pitch( -(float)deltaTime * handlingSpeedMultiplyer );
2098  }
2099  if( getWindow()->keyPressed( VK_RIGHT ) ) { // test if right was pressed
2100  player->roll( deltaTime * handlingSpeedMultiplyer );
2101  }
2102  if( getWindow()->keyPressed( VK_LEFT ) ) { // test if left was pressed
2103  player->roll( -(float)deltaTime * handlingSpeedMultiplyer );
2104  }
2105 
2106  // speed
2107  if( getWindow()->keyPressed( 187 ) ) { // test if plus was pressed --> accelerate
2108  player->accelerate( deltaTime * handlingSpeedMultiplyer );
2109  speedBar->setCurrent( player->getSpeed() );
2110  //getWindow()->keyUp( 187 );
2111  }
2112  if( getWindow()->keyPressed( 189 ) ) { // test if minus was pressed --> decrease speed
2113  player->accelerate( -(float)deltaTime * handlingSpeedMultiplyer );
2114  speedBar->setCurrent( player->getSpeed() );
2115  //getWindow()->keyUp( 189 );
2116  }
2117 
2118  // development movement: use wasd control for moving in x and y direction
2119  if( getWindow()->keyPressed( 87 ) ) { // testen if w was pressed
2120  player->moveUp( deltaTime * handlingSpeedMultiplyer * 100);
2121  }
2122  if( getWindow()->keyPressed( 65 ) ) { // test if a was pressed
2123  player->moveLeft( deltaTime * handlingSpeedMultiplyer * 100);
2124  }
2125  if( getWindow()->keyPressed( 83 ) ) { // test if s was pressed
2126  player->moveDown( deltaTime * handlingSpeedMultiplyer * 100);
2127  }
2128  if( getWindow()->keyPressed( 68 ) ) { // test if d was pressed
2129  player->moveRight( deltaTime * handlingSpeedMultiplyer * 100);
2130  }
2131 }
2132 
2133 void App::performLocalSystemsInput( DWORD deltaTime ) {
2134 
2135 }
2136 
2142 void App::performSystemInfoInput( DWORD deltaTime ) {
2143  // switch system in debug mode
2144  if( getWindow()->keyPressed( 66 ) ) { // testen if b was pressed
2145  currentSystemInfoNumber = currentSystemInfoNumber++%256;
2146  getWindow()->keyUp( 66 );
2147  // load new textures for the new system
2149  }
2150 
2151  // change viewing angle
2152  if( getWindow()->keyPressed( VK_UP ) ) { // // test if up was pressed
2153  systemInfoViewAngle++;
2154  getWindow()->keyUp( VK_UP );
2155  }
2156  if( getWindow()->keyPressed( VK_DOWN ) ) { // test if down was pressed
2157  systemInfoViewAngle--;
2158  getWindow()->keyUp( VK_DOWN );
2159  }
2160  if( getWindow()->keyPressed( VK_RIGHT ) ) { // test if right was pressed
2161  systemInfoViewAngle2++;
2162  getWindow()->keyUp( VK_RIGHT );
2163  }
2164  if( getWindow()->keyPressed( VK_LEFT ) ) { // test if left was pressed
2165  systemInfoViewAngle2--;
2166  getWindow()->keyUp( VK_LEFT );
2167  }
2168 
2169  // move camera
2170  // speed
2171  if( getWindow()->keyPressed( 187 ) ) { // // test if plus was pressed
2172  zoomFactor += 0.02;
2173  getWindow()->keyUp( 187 );
2174  }
2175  if( getWindow()->keyPressed( 189 ) ) { // // test if minus was pressed
2176  zoomFactor -= 0.02;
2177  getWindow()->keyUp( 189 );
2178  }
2179 
2180  // development movement: use wasd control for moving in x and y direction
2181  if( getWindow()->keyPressed( 87 ) ) { // test if w was pressed
2182  cameraSystemView->moveDown( deltaTime * handlingSpeedMultiplyer * 2);
2183  }
2184  if( getWindow()->keyPressed( 65 ) ) { // test if a was pressed
2185  cameraSystemView->moveRight( deltaTime * handlingSpeedMultiplyer * 2);
2186  }
2187  if( getWindow()->keyPressed( 83 ) ) { // test if s was pressed
2188  cameraSystemView->moveUp( deltaTime * handlingSpeedMultiplyer * 2);
2189  }
2190  if( getWindow()->keyPressed( 68 ) ) { // test if d was pressed
2191  cameraSystemView->moveLeft( deltaTime * handlingSpeedMultiplyer * 2);
2192  }
2193 }
2194 
2204  Textures::getTextures()->changeColors( m_switchColors );
2205  glClear( GL_COLOR_BUFFER_BIT );
2206  // switch to fast mode in order to draw the display elements
2207  fastMode();
2208 
2209  // set up an orthogonal screen for printing help text
2210  glMatrixMode( GL_PROJECTION );
2211  glPushMatrix();
2212  glLoadIdentity();
2213  glOrtho( 0, getWindow()->getWidth(), 0, getWindow()->getHeight(), -1, 1 ); // full size orthogonal screen
2214  glMatrixMode( GL_MODELVIEW );
2215  glPushMatrix();
2216  glLoadIdentity();
2217 
2218  // print text
2219  glEnable( GL_BLEND ); // enable blending (for text)
2220  glColor3fv( colorWhite );// white color
2221 
2222  if( devmode ) {
2223  vector<PlanetInfoGraphical> *planets = World::getWorld()->getSystemPlanets( currentSystemInfoNumber );
2224  printInfoLine( "Loading new System ..." );
2225  printInfoLine( "" );
2226  printInfoLine( "Textures to load: %d ", planets->size() + 1 ); // +1 for sun
2227  printInfoLine( "" );
2228  for( unsigned int i=0; i < planets->size(); i++ ) {
2229  glClear( GL_COLOR_BUFFER_BIT );
2230  string text = "Loading texture from file " + FileAccess::getTextureFile(planets->at(i).texture);
2231  printInfoLine( text.c_str() );
2232  printInfoBox( false );
2233  glFlush();
2234  getWindow()->swap();
2235  FileAccess::loadTexture( FileAccess::getPlanetSlot(i), planets->at(i).texture );
2236  }
2237  glClear( GL_COLOR_BUFFER_BIT );
2238 
2239  string text = "Loading texture from file " + FileAccess::getTextureFile( World::getWorld()->getSystemStarTexture( currentSystemInfoNumber ) );
2240  printInfoLine( text.c_str() );
2241  printInfoBox( false );
2242  glFlush();
2243  getWindow()->swap();
2244  FileAccess::loadTexture( star, World::getWorld()->getSystemStarTexture( currentSystemInfoNumber ) );
2245 
2246  } else {
2247  vector<PlanetInfoGraphical> *planets = World::getWorld()->getSystemPlanets();
2248  for( unsigned int i=0; i < planets->size(); i++ ) {
2249  glClear( GL_COLOR_BUFFER_BIT );
2250  printInfoLine( "Loading new System ..." );
2251  printInfoLine( "" );
2252  printInfoLine( "%7.2f percent done.", (100 * ((float)(i) / ((float)planets->size()+1.0)) ) ); //+1 for sun
2253  printInfoBox( true );
2254  glFlush();
2255  getWindow()->swap();
2256  FileAccess::loadTexture( FileAccess::getPlanetSlot(i), planets->at(i).texture );
2257  }
2258  glClear( GL_COLOR_BUFFER_BIT );
2259  printInfoLine( "Loading new System ..." );
2260  printInfoLine( "" );
2261  printInfoLine( "%7.2f percent done.", (100 * ((float)(planets->size()) / ((float)planets->size()+1.0)) ) ); //+1 for sun
2262  printInfoBox( true );
2263  glFlush();
2264  getWindow()->swap();
2265  FileAccess::loadTexture( star, World::getWorld()->getSystemStarTexture() );
2266 
2267  printInfoLine( "Loading new System ..." );
2268  printInfoLine( "" );
2269  printInfoLine( "%7.2f percent done.", 100.0f );
2270  }
2271 
2272  // print for last time, clear this time
2273  printInfoBox( true );
2274  glFlush();
2275  getWindow()->swap();
2276 
2277  glDisable( GL_BLEND );
2278 
2279  // restore procections
2280  glMatrixMode( GL_PROJECTION );
2281  glPopMatrix();
2282  glMatrixMode( GL_MODELVIEW );
2283  glPopMatrix();
2284 }
2285 
2293  Textures::getTextures()->reserve( 32 );
2294  Textures::getTextures()->changeColors( m_switchColors );
2305 }
2306 
2312 void App::setScreen( Screens screen ) {
2313  if( screen == marketplace )
2314  inStation = true;
2315  if( screen == currentSystem && inStation ) {
2316  player->setPos( World::getWorld()->getStation()->getOutPosition() );
2317  player->setView( World::getWorld()->getStation()->getOutVector() ); // do stuff that we start outside the coriolis station
2318  player->setSpeed( player->getMaxSpeed() * 0.5 );
2319  speedBar->setCurrent( player->getSpeed() );
2320  inStation = false;
2321  }
2322 
2323  switch( screen ) {
2324  case currentSystem:
2325  case help:
2326  case helpEnvironment:
2327  case helpInfo:
2328  case helpLocal:
2329  case helpMarketplace:
2330  case loadLevel:
2331  case systemInfo:
2332  getWindow()->showMousePointer( false );
2333  break;
2334  case marketplace:
2335  case localSystems:
2336  getWindow()->showMousePointer( true );
2337  break;
2338  default:
2339  getWindow()->showMousePointer( false );
2340  }
2341 
2342  currentScreen = screen;
2343 }
2344 
2350 void App::printInfoLine( const char*inputstring, ... ) {
2351  // copied from the texture font class. variable argument list are old C-style and have to be replaced.
2352  char text[256]; // create space for text
2353  va_list ap; // pointer to list of arguments
2354 
2355  if( inputstring == NULL )// quit, if there is no texst
2356  return;
2357 
2358  va_start( ap, inputstring ); // parse the string for variables
2359  vsprintf_s( text, inputstring, ap ); // convert symbols to actual numbers
2360  va_end( ap ); // store results in text
2361 
2362  // now the string is placed in text and send to the vector
2363  string textString( text );
2364  this->infoBoxLines.push_back(textString);
2365 }
2366 
2373 void App::printInfoBox( bool clear ) {
2374  static const int gap = 10;
2375  static const int size = tf2->getSize();
2376  for( unsigned int i=0; i<infoBoxLines.size(); i++)
2377  tf2->print(gap, getWindow()->getHeight() - gap - ++infoOutputLine*size, &infoBoxLines.at(i));
2378  if( clear )
2379  infoBoxLines.clear();
2380  infoOutputLine = 0;
2381 }
2382 
2388 void App::showFrameRate() {
2389  char opt = Console::getSingleCharacterOption( string(ti->getText()) );
2390  if( opt == '1' )
2391  m_showFrameRate = true;
2392  else if( opt == '0' )
2393  m_showFrameRate = false;
2394  else
2395  ; // error
2396 }
2397 
2405 void App::showFrameTime() {
2407  if( opt == '1' )
2408  m_showFrameTime = true;
2409  else if( opt == '0' )
2410  m_showFrameTime = false;
2411  else
2412  ; // error
2413 }
2414 
2422 void App::showSpeed() {
2424  if( opt == '1' )
2425  m_showSpeed = true;
2426  else if( opt == '0' )
2427  m_showSpeed = false;
2428  else
2429  ; // error
2430 }
2431 
2439 void App::showResolution() {
2441  if( opt == '1' )
2442  m_showResolution = true;
2443  else if( opt == '0' )
2444  m_showResolution = false;
2445  else
2446  ; // error occured
2447 }
2448 
2456 void App::showHelp() {
2457  string option = Console::getOption( ti->getText() );
2458  if( option == "" ) {
2459  getWindow()->showMousePointer( false );
2460  setScreen( help );
2461  }
2462  if( option == "local" ) {
2463  getWindow()->showMousePointer( false );
2464  setScreen( helpLocal );
2465  }
2466  if( option == "info" ) {
2467  getWindow()->showMousePointer( false );
2468  setScreen( helpInfo );
2469  }
2470  if( option == "env" ) {
2471  getWindow()->showMousePointer( false );
2472  setScreen( helpEnvironment );
2473  }
2474  if( option == "mkt" ) {
2475  getWindow()->showMousePointer( false );
2476  setScreen( helpMarketplace );
2477  }
2478 }
2479 
2488 void App::devMode() {
2490  if( opt == '1' ) {
2491  player->setMaxSpeed( lightspeed + lightspeed * 99 );
2492  player->setMinSpeed( -lightspeed*0.5 - lightspeed * 99 );
2493  devmode = true;
2494  } else if( opt == '0' ) {
2495  player->setMaxSpeed( lightspeed );
2496  if( player->getSpeed() > lightspeed )
2497  player->setSpeed( lightspeed );
2498  player->setMinSpeed( -lightspeed*0.5 );
2499  if( player->getSpeed() < -lightspeed*0.5 )
2500  player->setSpeed( -lightspeed*0.5 );
2501  devmode = true;
2502  devmode = false;
2503  } else
2504  ; // an error occured
2505 }
2506 
2513 void App::switchColors() {
2515  if( opt == '1' ) {
2516  m_switchColors = true;
2519  } else if( opt == '0' ) {
2520  m_switchColors = false;
2523  } else
2524  ; // an error occured
2525 }
2526 
2534  return frustum;
2535 }
2536 
2544 void App::setProjectionOrthogonal( void ) {
2545  glMatrixMode( GL_PROJECTION );
2546  glPushMatrix();
2547  glLoadIdentity();
2548  glOrtho( 0, getWindow()->getWidth(), 0, getWindow()->getHeight(), -1, 1 ); // full size orthogonal screen
2549  glMatrixMode( GL_MODELVIEW );
2550  glPushMatrix();
2551  glLoadIdentity();
2552 }
2553 
2562 void App::restoreProjection( void ) {
2563  glMatrixMode( GL_PROJECTION );
2564  glPopMatrix();
2565  glMatrixMode( GL_MODELVIEW );
2566  glPopMatrix();
2567 }