vegastrike  0.5.1.r1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
main_loop.cpp
Go to the documentation of this file.
1 #include <stdlib.h>
2 #ifndef _WIN32
3 #include <fenv.h>
4 #endif
5 #include <stdio.h>
6 #include <assert.h>
7 #include <string.h>
8 #include <stdlib.h>
9 #include "lin_time.h"
10 #include "cmd/unit.h"
11 #include "cmd/unit_factory.h"
12 #include "vegastrike.h"
13 #include "vs_globals.h"
14 #include "in.h"
15 #include "gfx/mesh.h"
16 #include "gfx/sprite.h"
17 #include "physics.h"
18 #include "gfxlib.h"
19 #include "cmd/bolt.h"
20 #include "gfx/loc_select.h"
21 #include <string>
22 #include "cmd/collection.h"
23 #include "star_system.h"
24 #include "cmd/planet.h"
25 #include "gfx/sphere.h"
26 #include "gfx/coord_select.h"
27 #include "cmd/building.h"
28 #include "cmd/ai/fire.h"
29 #include "cmd/ai/aggressive.h"
30 #include "cmd/ai/navigation.h"
31 #include "cmd/beam.h"
32 #include "gfx/halo.h"
33 #include "gfx/matrix.h"
34 #include "cmd/ai/flyjoystick.h"
35 #include "cmd/ai/firekeyboard.h"
36 #include "cmd/ai/script.h"
37 #include "gfx/cockpit.h"
38 #include "gfx/aux_texture.h"
39 #include "gfx/background.h"
40 #include "cmd/music.h"
41 #include "main_loop.h"
42 #include "cmd/music.h"
43 #include "audiolib.h"
44 #include "cmd/nebula.h"
45 #include "vsfilesystem.h"
46 #include "cmd/script/mission.h"
47 #include "xml_support.h"
48 #include "config_xml.h"
49 #include "cmd/ai/missionscript.h"
50 #include "cmd/enhancement.h"
51 #include "cmd/cont_terrain.h"
52 #include "cmd/script/flightgroup.h"
53 #include "force_feedback.h"
54 #include "universe_util.h"
55 #include "networking/netclient.h"
56 #include "save_util.h"
57 #include "in_kb_data.h"
58 #include "vs_random.h"
59 
60 #include "options.h"
61 
62 #include "audio/SceneManager.h"
63 
64 #ifndef NO_GFX
65 #include "gldrv/gl_globals.h"
66 #endif
67 
69 
70 extern std::string global_username;
71 #define KEYDOWN( name, key ) (name[key]&0x80)
72 
73 static Texture *tmpcockpittexture;
74 Unit **fighters;
75 Unit *carrier = NULL;
76 Unit *fighter = NULL;
77 Unit *fighter2 = NULL;
78 Unit *midway = NULL;
81 bool _Slew = true;
82 bool QuitAllow = false;
83 extern bool cleanexit;
84 #ifndef _WIN32
85 int allexcept = FE_DIVBYZERO; //|FE_INVALID;//|FE_OVERFLOW|FE_UNDERFLOW;
86 #else
87 int allexcept = 0;
88 #endif
89 int shiftup( int );
90 string getUnitNameAndFgNoBase( Unit *target );
91 ContinuousTerrain *myterrain;
92 int numf = 0;
93 CoordinateSelect *locSel = NULL;
94 SphereMesh *bg2 = NULL;
95 ClickList *shipList = NULL;
96 
97 void VolUp( const KBData&, KBSTATE newState )
98 {
99  if (newState == PRESS) {
100  float gain = AUDGetListenerGain();
101  if (gain < 1) {
102  gain += .0625;
103  if (gain > 1) gain = 1;
104  AUDListenerGain( gain );
105  Music::ChangeVolume( 0 );
106  }
107  }
108 }
109 
110 
111 void VolDown( const KBData&, KBSTATE newState )
112 {
113  if (newState == PRESS) {
114  float gain = AUDGetListenerGain();
115  if (gain > 0) {
116  gain -= .03125;
117  if (gain < 0) gain = 0;
118  AUDListenerGain( gain );
119  Music::ChangeVolume( 0 );
120  }
121  }
122 }
123 
124 static void SwitchVDUTo( VDU::VDU_MODE v )
125 {
126  int i;
127  static int whichvdu = 1;
128  for (int j = 0; j < 3; ++j) {
129  if ( v != _Universe->AccessCockpit()->getVDUMode( whichvdu ) || (v != VDU::VIEW && v != VDU::WEAPON) ) {
130  whichvdu += 1;
131  whichvdu %= 2;
132  }
133  int curmode = _Universe->AccessCockpit()->getVDUMode( whichvdu );
134  if ( v == _Universe->AccessCockpit()->getVDUMode( whichvdu ) ) {
135  if (v == VDU::VIEW)
136  _Universe->AccessCockpit()->VDUSwitch( whichvdu ); //get different view mode
137  return;
138  }
139  for (i = 0; i < 32; ++i) {
140  _Universe->AccessCockpit()->VDUSwitch( whichvdu );
141  if ( v == _Universe->AccessCockpit()->getVDUMode( whichvdu ) )
142  return;
143  }
144  for (i = 0; i < 32; ++i) {
145  _Universe->AccessCockpit()->VDUSwitch( whichvdu );
146  if ( curmode == _Universe->AccessCockpit()->getVDUMode( whichvdu ) )
147  break;
148  }
149  }
150 }
151 
153 {
154  if (game_options.switchToTargetModeOnKey) {
155  int view = 0;
156  int examine = 0;
157  for (; view < 2; ++view)
158  if (_Universe->AccessCockpit()->getVDUMode( view ) == VDU::VIEW)
159  break;
160  for (; examine < 2; ++examine)
161  if (_Universe->AccessCockpit()->getVDUMode( examine ) == VDU::TARGET)
162  break;
163  if ( (examine == 2) && (view == 2) )
164  SwitchVDUTo( VDU::TARGET );
165  }
166 }
167 
168 namespace CockpitKeys
169 {
170 unsigned int textmessager = 0;
171 static bool waszero = false;
172 
173 void TextMessageCallback( unsigned int ch, unsigned int mod, bool release, int x, int y )
174 {
175  GameCockpit *gcp = static_cast< GameCockpit* > ( _Universe->AccessCockpit( textmessager ) );
176  gcp->editingTextMessage = true;
177  if ( ( release
178  && (waszero || ch == WSK_KP_ENTER || ch == WSK_ESCAPE) ) || ( release == false && (ch == ']' || ch == '[') ) ) {
179  waszero = false;
180  gcp->editingTextMessage = false;
181  RestoreKB();
182  }
183  if ( release || (ch == ']' || ch == '[') ) return;
184  unsigned int code =
185  ( ( WSK_MOD_LSHIFT == (mod&WSK_MOD_LSHIFT) ) || ( WSK_MOD_RSHIFT == (mod&WSK_MOD_RSHIFT) ) ) ? shiftup(
186  ch ) : ch;
187  if ( textmessager < _Universe->numPlayers() ) {
188  if (ch == WSK_BACKSPACE || ch == WSK_DELETE) {
189  gcp->textMessage = gcp->textMessage.substr( 0, gcp->textMessage.length()-1 );
190  } else if (ch == WSK_RETURN || ch == WSK_KP_ENTER) {
191  if (gcp->textMessage.length() != 0) {
192  std::string name = gcp->savegame->GetCallsign();
193  if (Network != NULL) {
194  Unit *par = gcp->GetParent();
195  if (0 && par)
196  name = getUnitNameAndFgNoBase( par );
197  Network[textmessager].textMessage( gcp->textMessage );
198  } else if (gcp->textMessage[0] == '/') {
199  string cmd;
200  string args;
201  std::string::size_type space = gcp->textMessage.find( ' ' );
202  if (space) {
203  cmd = gcp->textMessage.substr( 1, space-1 );
204  args = gcp->textMessage.substr( space+1 );
205  } else {
206  cmd = gcp->textMessage.substr( 1 );
207  //Send custom message to itself.
208  }
209  UniverseUtil::receivedCustom( textmessager, true, cmd, args, string() );
210  }
211  waszero = false;
212  } else {waszero = true; } gcp->textMessage = "";
213  } else if (code != 0 && code <= 127) {
214  char newstr[2] = {(char) code, 0};
215  gcp->textMessage += newstr;
216  }
217  } else {
218  RestoreKB();
219  gcp->editingTextMessage = false;
220  }
221 }
222 
223 void TextMessageKey( const KBData&, KBSTATE newState )
224 {
225  if (newState == PRESS) {
226  static bool chat_only_in_network =
227  XMLSupport::parse_bool( vs_config->getVariable( "network", "chat_only_in_network", "false" ) );
228  if ( (Network == NULL) && chat_only_in_network )
229  return;
230  winsys_set_keyboard_func( TextMessageCallback );
232  }
233 }
234 void QuitNow()
235 {
236  if (!cleanexit)
237  {
238  cleanexit = true;
239  if (Network == NULL && game_options.write_savegame_on_exit)
240  _Universe->WriteSaveGame( true ); //gotta do important stuff first
241  for (unsigned int i = 0; i < active_missions.size(); i++)
242  if (active_missions[i])
243  active_missions[i]->DirectorEnd();
244  if (forcefeedback)
245  {
246  delete forcefeedback;
247  forcefeedback = NULL;
248  }
249  VSExit( 0 );
250  }
251 }
252 
253 void SkipMusicTrack( const KBData&, KBSTATE newState )
254 {
255  if (newState == PRESS) {
256  printf( "skipping\n" );
257  muzak->Skip();
258  }
259 }
260 
261 static void _PitchDown( KBSTATE newState, int fromCam = 0, int toCam = NUM_CAM-1 )
262 {
263  static Vector Q;
264  static Vector R;
265  for (int i = fromCam; i <= toCam; i++) {
266  if (newState == PRESS) {
267  if (QuitAllow)
268  QuitNow();
269  Q = _Universe->AccessCockpit()->AccessCamera( i )->Q;
270  R = _Universe->AccessCockpit()->AccessCamera( i )->R;
271  _Universe->AccessCockpit()->AccessCamera( i )->myPhysics.ApplyBalancedLocalTorque( -Q,
272  R,
273  game_options.camera_pan_speed );
274  }
275  if (_Slew && newState == RELEASE)
276  _Universe->AccessCockpit()->AccessCamera( i )->myPhysics.SetAngularVelocity( Vector( 0, 0, 0 ) );
277  }
278 }
279 
280 static void _PitchUp( KBSTATE newState, int fromCam = 0, int toCam = NUM_CAM-1 )
281 {
282  static Vector Q;
283  static Vector R;
284  for (int i = fromCam; i <= toCam; i++) {
285  if (newState == PRESS) {
286  Q = _Universe->AccessCockpit()->AccessCamera( i )->Q;
287  R = _Universe->AccessCockpit()->AccessCamera( i )->R;
288  _Universe->AccessCockpit()->AccessCamera( i )->myPhysics.ApplyBalancedLocalTorque( Q,
289  R,
290  game_options.camera_pan_speed );
291  }
292  if (_Slew && newState == RELEASE)
293  _Universe->AccessCockpit()->AccessCamera( i )->myPhysics.SetAngularVelocity( Vector( 0, 0, 0 ) );
294  }
295 }
296 
297 static void _YawLeft( KBSTATE newState, int fromCam = 0, int toCam = NUM_CAM-1 )
298 {
299  static Vector P;
300  static Vector R;
301  for (int i = fromCam; i <= toCam; i++) {
302  if (newState == PRESS) {
303  P = _Universe->AccessCockpit()->AccessCamera( i )->P;
304  R = _Universe->AccessCockpit()->AccessCamera( i )->R;
305  _Universe->AccessCockpit()->AccessCamera( i )->myPhysics.ApplyBalancedLocalTorque( -P,
306  R,
307  game_options.camera_pan_speed );
308  }
309  if (_Slew && newState == RELEASE)
310  _Universe->AccessCockpit()->AccessCamera( i )->myPhysics.SetAngularVelocity( Vector( 0, 0, 0 ) );
311  }
312 }
313 
314 static void _YawRight( KBSTATE newState, int fromCam = 0, int toCam = NUM_CAM-1 )
315 {
316  for (int i = fromCam; i <= toCam; i++) {
317  static Vector P;
318  static Vector R;
319  if (newState == PRESS) {
320  P = _Universe->AccessCockpit()->AccessCamera( i )->P;
321  R = _Universe->AccessCockpit()->AccessCamera( i )->R;
322  _Universe->AccessCockpit()->AccessCamera( i )->myPhysics.ApplyBalancedLocalTorque( P,
323  R,
324  game_options.camera_pan_speed );
325  }
326  if (_Slew && newState == RELEASE)
327  _Universe->AccessCockpit()->AccessCamera( i )->myPhysics.SetAngularVelocity( Vector( 0, 0, 0 ) );
328  }
329 }
330 
331 void PitchDown( const KBData&, KBSTATE newState )
332 {
333  _PitchDown(newState);
334 }
335 
336 void PitchUp( const KBData&, KBSTATE newState )
337 {
338  _PitchUp(newState);
339 }
340 
341 void YawLeft( const KBData&, KBSTATE newState )
342 {
343  _YawLeft(newState);
344 }
345 
346 void YawRight( const KBData&, KBSTATE newState )
347 {
348  _YawRight(newState);
349 }
350 
351 static void InitPanInside()
352 {
353  YawLeft( std::string(), RELEASE );
354  YawRight( std::string(), RELEASE );
355  PitchUp( std::string(), RELEASE );
356  PitchDown( std::string(), RELEASE );
357  _Universe->AccessCockpit()->SetView( CP_PANINSIDE );
358 }
359 
360 void LookDown( const KBData& kbdata, KBSTATE newState )
361 {
362  if (newState == PRESS && QuitAllow)
363  QuitNow();
364  if (newState == PRESS || newState == DOWN) {
365  if (_Universe->AccessCockpit()->GetView() <= CP_RIGHT) {
366  InitPanInside();
367  } else if (_Universe->AccessCockpit()->GetView() == CP_PANINSIDE) {
368  _Universe->AccessCockpit()->SetInsidePanPitchSpeed(game_options.camera_pan_speed*1000.0);
369  } else {
370  PitchDown( kbdata, newState );
371  }
372  } else if (newState == RELEASE) {
373  if (_Universe->AccessCockpit()->GetView() == CP_PANINSIDE)
374  _Universe->AccessCockpit()->SetInsidePanPitchSpeed(0);
375  else
376  PitchDown( kbdata, newState );
377  }
378 }
379 
380 void LookUp( const KBData& kbdata, KBSTATE newState )
381 {
382  if (newState == PRESS || newState == DOWN) {
383  if (_Universe->AccessCockpit()->GetView() <= CP_RIGHT) {
384  InitPanInside();
385  } else if (_Universe->AccessCockpit()->GetView() == CP_PANINSIDE) {
386  _Universe->AccessCockpit()->SetInsidePanPitchSpeed(-game_options.camera_pan_speed*1000.0);
387  } else {
388  PitchUp( kbdata, newState );
389  }
390  } else if (newState == RELEASE) {
391  if (_Universe->AccessCockpit()->GetView() == CP_PANINSIDE)
392  _Universe->AccessCockpit()->SetInsidePanPitchSpeed(0);
393  else
394  PitchUp( kbdata, newState );
395  }
396 }
397 
398 void LookLeft( const KBData& kbdata, KBSTATE newState )
399 {
400  if (newState == PRESS || newState == DOWN) {
401  if (_Universe->AccessCockpit()->GetView() <= CP_RIGHT) {
402  InitPanInside();
403  } else if (_Universe->AccessCockpit()->GetView() == CP_PANINSIDE) {
404  _Universe->AccessCockpit()->SetInsidePanYawSpeed(game_options.camera_pan_speed*1000.0);
405  } else {
406  YawLeft( kbdata, newState );
407  }
408  } else if (newState == RELEASE) {
409  if (_Universe->AccessCockpit()->GetView() == CP_PANINSIDE)
410  _Universe->AccessCockpit()->SetInsidePanYawSpeed(0);
411  else
412  YawLeft( kbdata, newState );
413  }
414 }
415 
416 void LookRight( const KBData& kbdata, KBSTATE newState )
417 {
418  if (newState == PRESS || newState == DOWN) {
419  if (_Universe->AccessCockpit()->GetView() <= CP_RIGHT) {
420  InitPanInside();
421  } else if (_Universe->AccessCockpit()->GetView() == CP_PANINSIDE) {
422  _Universe->AccessCockpit()->SetInsidePanYawSpeed(-game_options.camera_pan_speed*1000.0);
423  } else {
424  YawRight( kbdata, newState );
425  }
426  } else if (newState == RELEASE) {
427  if (_Universe->AccessCockpit()->GetView() == CP_PANINSIDE)
428  _Universe->AccessCockpit()->SetInsidePanYawSpeed(0);
429  else
430  YawRight( kbdata, newState );
431  }
432 }
433 
434 
435 void Quit( const KBData&, KBSTATE newState )
436 {
437  if (newState == PRESS) {
438  QuitAllow = !QuitAllow;
439  }
440 }
441 
442 void Inside( const KBData&, KBSTATE newState )
443 {
444  {
446  _Universe->activeStarSystem()->getBackground()->EnableBG( game_options.background );
447  }
448  static int tmp = (game_options.cockpit ? 1 : 0);
449  if (newState == PRESS && (_Universe->AccessCockpit()->GetView() == CP_FRONT) && game_options.disabled_cockpit_allowed) {
450  YawLeft( KBData(), RELEASE );
451  YawRight( KBData(), RELEASE );
452  PitchUp( KBData(), RELEASE );
453  PitchDown( KBData(), RELEASE );
454  string cockpit = "disabled-cockpit.cpt";
455  if ( _Universe->AccessCockpit()->GetParent() )
456  cockpit = _Universe->AccessCockpit()->GetParent()->getCockpit();
457  Unit *u = NULL; //= NULL just to shut off a warning about its possibly being used uninitialized --chuck_starchaser
458  if ( (_Universe->AccessCockpit()->GetParent() != NULL)
459  && (_Universe->AccessCockpit()->GetParent()->name == "return_to_cockpit")
460  && (_Universe->AccessCockpit()->GetParent()->owner != NULL)
461  && ( u = findUnitInStarsystem( _Universe->AccessCockpit()->GetParent()->owner ) ) )
462  cockpit = u->getCockpit();
463  _Universe->AccessCockpit()->Init( cockpit.c_str(), ( (tmp) && _Universe->AccessCockpit()->GetParent() ) == false );
464  tmp = (tmp+1)%2;
465  }
466  if (newState == PRESS || newState == DOWN) {
467  _Universe->AccessCockpit()->SetView( CP_FRONT );
468  }
469 }
470 void ZoomOut( const KBData&, KBSTATE newState )
471 {
472  if (newState == PRESS || newState == DOWN)
474 }
475 
476 static float scrolltime = 0;
477 void ScrollUp( const KBData&, KBSTATE newState )
478 {
479  scrolltime += GetElapsedTime();
480  if ( newState == PRESS || (newState == DOWN && scrolltime >= .5) ) {
481  scrolltime = 0;
482  printf( "Enabling exceptions %d\n", allexcept );
483  _Universe->AccessCockpit()->ScrollAllVDU( -1 );
484  }
485 }
486 void ScrollDown( const KBData&, KBSTATE newState )
487 {
488  scrolltime += GetElapsedTime();
489  if ( newState == PRESS || (newState == DOWN && scrolltime >= .5) ) {
490  scrolltime = 0;
491  printf( "Disabling exceptions\n" );
492  _Universe->AccessCockpit()->ScrollAllVDU( 1 );
493  }
494 }
495 void ZoomIn( const KBData&, KBSTATE newState )
496 {
497  if (newState == PRESS || newState == DOWN)
499 }
500 
501 void ZoomReset( const KBData&, KBSTATE newState )
502 {
503  if (newState == PRESS || newState == DOWN)
504  _Universe->AccessCockpit()->zoomfactor = 1.f;
505 }
506 
507 void InsideLeft( const KBData&, KBSTATE newState )
508 {
509  if (newState == PRESS || newState == DOWN) {
510  YawLeft( std::string(), RELEASE );
511  YawRight( std::string(), RELEASE );
512  PitchUp( std::string(), RELEASE );
513  PitchDown( std::string(), RELEASE );
514 
515  _Universe->AccessCockpit()->SetView( CP_LEFT );
516  }
517 }
518 void InsideRight( const KBData&, KBSTATE newState )
519 {
520  if (newState == PRESS || newState == DOWN) {
521  _Universe->AccessCockpit()->SetView( CP_RIGHT );
522  }
523 }
524 void PanTarget( const KBData&, KBSTATE newState )
525 {
526  if (newState == PRESS || newState == DOWN) {
527  _Universe->AccessCockpit()->SetView( CP_PANTARGET );
528  }
529 }
530 void ViewTarget( const KBData&, KBSTATE newState )
531 {
532  if (newState == PRESS || newState == DOWN) {
533  YawLeft( std::string(), RELEASE );
534  YawRight( std::string(), RELEASE );
535  PitchUp( std::string(), RELEASE );
536  PitchDown( std::string(), RELEASE );
537 
538  _Universe->AccessCockpit()->SetView( CP_VIEWTARGET );
539  }
540 }
541 void OutsideTarget( const KBData&, KBSTATE newState )
542 {
543  if (newState == PRESS || newState == DOWN) {
544  YawLeft( std::string(), RELEASE );
545  YawRight( std::string(), RELEASE );
546  PitchUp( std::string(), RELEASE );
547  PitchDown( std::string(), RELEASE );
548 
549  _Universe->AccessCockpit()->SetView( CP_TARGET );
550  }
551 }
552 
553 void InsideBack( const KBData&, KBSTATE newState )
554 {
555  if (newState == PRESS || newState == DOWN) {
556  YawLeft( std::string(), RELEASE );
557  YawRight( std::string(), RELEASE );
558  PitchUp( std::string(), RELEASE );
559  PitchDown( std::string(), RELEASE );
560 
561  _Universe->AccessCockpit()->SetView( CP_BACK );
562  }
563 }
564 void CommModeVDU( const KBData&, KBSTATE newState )
565 {
566  if (newState == PRESS) {
567  static soundContainer sc;
568  if (sc.sound < 0)
569  sc.loadsound( game_options.comm );
570  sc.playsound();
571  SwitchVDUTo( VDU::COMM );
572  }
573 }
574 void ScanningModeVDU( const KBData&, KBSTATE newState )
575 {
576  if (newState == PRESS) {
577  static soundContainer sc;
578  if (sc.sound < 0)
579  sc.loadsound( game_options.scanning );
580  sc.playsound();
581  SwitchVDUTo( VDU::SCANNING );
582  }
583 }
584 void ObjectiveModeVDU( const KBData&, KBSTATE newState )
585 {
586  if (newState == PRESS) {
587  static soundContainer sc;
588  if (sc.sound < 0)
589  sc.loadsound( game_options.objective );
590  sc.playsound();
591 
592  SwitchVDUTo( VDU::OBJECTIVES );
593  }
594 }
595 void TargetModeVDU( const KBData&, KBSTATE newState )
596 {
597  if (newState == PRESS) {
598  static soundContainer sc;
599  if (sc.sound < 0)
600  sc.loadsound( game_options.examine );
601  sc.playsound();
602 
603  SwitchVDUTo( VDU::TARGET );
604  }
605 }
606 void ViewModeVDU( const KBData&, KBSTATE newState )
607 {
608  if (newState == PRESS) {
609  static soundContainer sc;
610  if (sc.sound < 0)
611  sc.loadsound( game_options.view );
612  sc.playsound();
613  SwitchVDUTo( VDU::VIEW );
614  }
615 }
616 void DamageModeVDU( const KBData&, KBSTATE newState )
617 {
618  if (newState == PRESS) {
619  static soundContainer sc;
620  if (sc.sound < 0)
621  sc.loadsound( game_options.repair );
622  sc.playsound();
623 
624  SwitchVDUTo( VDU::DAMAGE );
625  }
626 }
627 void ManifestModeVDU( const KBData&, KBSTATE newState )
628 {
629  if (newState == PRESS) {
630  static soundContainer sc;
631  if (sc.sound < 0)
632  sc.loadsound( game_options.manifest );
633  sc.playsound();
634 
635  SwitchVDUTo( VDU::MANIFEST );
636  }
637 }
638 void GunModeVDU( const KBData &s, KBSTATE newState )
639 {
640  if (newState == PRESS) SwitchVDUTo( VDU::WEAPON );
641  FireKeyboard::WeapSelKey( s, newState );
642 }
643 void ReverseGunModeVDU( const KBData &s, KBSTATE newState )
644 {
645  if (newState == PRESS) SwitchVDUTo( VDU::WEAPON );
646  FireKeyboard::ReverseWeapSelKey( s, newState );
647 }
648 void MissileModeVDU( const KBData &s, KBSTATE newState )
649 {
650  if (newState == PRESS) SwitchVDUTo( VDU::WEAPON );
651  FireKeyboard::MisSelKey( s, newState );
652 }
653 void ReverseMissileModeVDU( const KBData &s, KBSTATE newState )
654 {
655  if (newState == PRESS) SwitchVDUTo( VDU::WEAPON );
656  FireKeyboard::ReverseMisSelKey( s, newState );
657 }
658 void SwitchLVDU( const KBData&, KBSTATE newState )
659 {
660  if (newState == PRESS)
661  _Universe->AccessCockpit()->VDUSwitch( 0 );
662 }
663 void SwitchRVDU( const KBData&, KBSTATE newState )
664 {
665  if (newState == PRESS)
666  _Universe->AccessCockpit()->VDUSwitch( 1 );
667 }
668 void SwitchMVDU( const KBData&, KBSTATE newState )
669 {
670  if (newState == PRESS)
671  _Universe->AccessCockpit()->VDUSwitch( 2 );
672 }
673 void SwitchULVDU( const KBData&, KBSTATE newState )
674 {
675  if (newState == PRESS)
676  _Universe->AccessCockpit()->VDUSwitch( 3 );
677 }
678 void SwitchURVDU( const KBData&, KBSTATE newState )
679 {
680  if (newState == PRESS)
681  _Universe->AccessCockpit()->VDUSwitch( 4 );
682 }
683 void SwitchUMVDU( const KBData&, KBSTATE newState )
684 {
685  if (newState == PRESS)
686  _Universe->AccessCockpit()->VDUSwitch( 5 );
687 }
688 
689 void Behind( const KBData&, KBSTATE newState )
690 {
691  if (newState == PRESS || newState == DOWN) {
692  YawLeft( std::string(), RELEASE );
693  YawRight( std::string(), RELEASE );
694  PitchUp( std::string(), RELEASE );
695  PitchDown( std::string(), RELEASE );
696 
697  _Universe->AccessCockpit()->SetView( CP_CHASE );
698  }
699 }
700 void Pan( const KBData&, KBSTATE newState )
701 {
702  if (newState == PRESS || newState == DOWN) {
703  YawLeft( std::string(), RELEASE );
704  YawRight( std::string(), RELEASE );
705  PitchUp( std::string(), RELEASE );
706  PitchDown( std::string(), RELEASE );
707 
708  _Universe->AccessCockpit()->SetView( CP_PAN );
709  }
710 }
711 }
712 
713 using namespace CockpitKeys;
714 
716 {
717  BindKey( 27, 0, 0, Quit, KBData() ); //always have quit on esc
718 }
719 
721 {
722  if (mission->getVariable( "savegame", "" ).length() == 0)
723  return;
724  int len = getSaveDataLength( 0, "436457r1K3574r7uP71m35" );
725  float var = FLT_MAX;
726  if (len <= 0) {
727  pushSaveData( 0, "436457r1K3574r7uP71m35", 1 );
728  var = 1;
729  } else {
730  var = getSaveData( 0, "436457r1K3574r7uP71m35", 0 );
731  putSaveData( 0, "436457r1K3574r7uP71m35", 0, var+1 );
732  }
733  if (var <= game_options.times_to_show_help_screen)
734  GameCockpit::NavScreen( KBData(), PRESS ); //HELP FIXME
735 }
736 
737 void createObjects( std::vector< std::string > &fighter0name,
738  std::vector< StarSystem* > &ssys,
739  std::vector< QVector > &savedloc,
740  vector< vector< std::string > > &savefiles )
741 {
742  vector< std::string >fighter0mods;
743  vector< int > fighter0indices;
744 
745  static Vector TerrainScale( game_options.xscale, game_options.yscale, game_options.zscale );
746 
747  myterrain = NULL;
748  std::string stdstr = mission->getVariable( "terrain", "" );
749  if (stdstr.length() > 0) {
750  Terrain *terr = new Terrain( stdstr.c_str(), TerrainScale, game_options.mass, game_options.radius );
751  Matrix tmp;
752  ScaleMatrix( tmp, TerrainScale );
753  QVector pos;
754  mission->GetOrigin( pos, stdstr );
755  tmp.p = -pos;
756  terr->SetTransformation( tmp );
757  }
758  stdstr = mission->getVariable( "continuousterrain", "" );
759  if (stdstr.length() > 0) {
760  myterrain = new ContinuousTerrain( stdstr.c_str(), TerrainScale, game_options.mass );
761  Matrix tmp;
762  Identity( tmp );
763  QVector pos;
764  mission->GetOrigin( pos, stdstr );
765  tmp.p = -pos;
766  myterrain->SetTransformation( tmp );
767  }
768  BindKey( 1, CoordinateSelect::MouseMoveHandle );
769 
770  int numf = mission->number_of_ships;
771 
772  fighters = new Unit*[numf];
773  int *tmptarget = new int[numf];
774 
775  GFXEnable( TEXTURE0 );
776  GFXEnable( TEXTURE1 );
777 
778  vsUMap< string, int >targetmap;
779 
780  char fightername[1024] = "hornet.xunit";
781  int a = 0;
782 
783  vector< Flightgroup* >::const_iterator siter;
784  vector< Flightgroup* >fg = mission->flightgroups;
785  int squadnum = 0;
786  for (siter = fg.begin(); siter != fg.end(); siter++) {
787  Flightgroup *fg = *siter;
788  string fg_name = fg->name;
789  string fullname = fg->type; //+ ".xunit";
790  strcpy( fightername, fullname.c_str() );
791  string ainame = fg->ainame;
792  float fg_radius = 0.0;
793  Cockpit *cp = NULL;
794  for (int s = 0; s < fg->nr_ships; s++) {
795  if (a >= mission->number_of_ships) {
796  a -= 22;
797  printf( "Error: in createObjects: more ships in flightgroups than in total for mission!\n"
798  "Variables a=%d, fg-number-of-ships=%d, total nr=%d, fact=%s, fgname=%s\n",
799  a, fg->nr_ships, mission->number_of_ships, fg->faction.c_str(), fg->name.c_str() );
800  break;
801  }
802  numf++;
803  QVector pox( 1000+150*a, 100*a, 100 );
804 
805  pox.i = fg->pos.i+s*fg_radius*3;
806  pox.j = fg->pos.j+s*fg_radius*3;
807  pox.k = fg->pos.k+s*fg_radius*3;
808  if (pox.i == pox.j && pox.j == pox.k && pox.k == 0) {
809  pox.i = rand()*10000./RAND_MAX-5000;
810  pox.j = rand()*10000./RAND_MAX-5000;
811  pox.k = rand()*10000./RAND_MAX-5000;
812  }
813  tmptarget[a] = FactionUtil::GetFactionIndex( fg->faction ); //that should not be in xml?
814  int fg_terrain = -1;
815  if ( fg_terrain == -1 || (fg_terrain == -2 && myterrain == NULL) ) {
816  string modifications( "" );
817  if ( s == 0 && squadnum < (int) fighter0name.size() ) {
818  cp = _Universe->AccessCockpit( squadnum );
819  cp->activeStarSystem = ssys[squadnum];
820  fighter0indices.push_back( a );
821  if (fighter0name[squadnum].length() == 0)
822  fighter0name[squadnum] = string( fightername );
823  else
824  strcpy( fightername, fighter0name[squadnum].c_str() );
825  if (mission->getVariable( "savegame", "" ).length() > 0) {
826  if (savedloc[squadnum].i != FLT_MAX)
827  pox = UniverseUtil::SafeEntrancePoint( savedloc[squadnum] );
828  vector< std::string > *dat = &cp->savegame->getMissionStringData( "jump_from" );
829  if ( dat->size() ) {
830  std::string srcsys = (*dat)[0];
831  Unit *grav;
832  for (un_iter ui = cp->activeStarSystem->gravitationalUnits().createIterator();
833  (grav = *ui) != NULL;
834  ++ui) {
835  size_t siz = grav->GetDestinations().size();
836  for (unsigned int i = 0; i < siz; ++i)
837  if (srcsys == grav->GetDestinations()[i]) {
838  QVector newpos = grav->LocalPosition()
839  +QVector( vsrandom.uniformExc( -grav->rSize()/4, grav->rSize()/4 ),
840  vsrandom.uniformExc( -grav->rSize()/4,
841  grav->rSize()/4 ),
842  vsrandom.uniformExc( -grav->rSize()/4,
843  grav->rSize()/4 ) );
844  if (grav->isUnit() != PLANETPTR)
845  newpos = UniverseUtil::SafeEntrancePoint( newpos );
846  cp->savegame->SetPlayerLocation( newpos );
847  pox = newpos;
848  }
849  }
850  dat->clear();
851  }
852  fighter0mods.push_back( modifications = game_options.getCallsign( squadnum ) );
853  if ( squadnum == 0 && global_username.length() ) {
854  fighter0mods.back() = global_username;
855  modifications = global_username;
856  }
857  fprintf( stderr, "FOUND MODIFICATION = %s FOR PLAYER #%d\n", modifications.c_str(), squadnum );
858  } else {
859  fighter0mods.push_back( "" );
860  }
861  }
862  Cockpit *backupcp = _Universe->AccessCockpit();
863  if ( squadnum < (int) fighter0name.size() ) {
864  _Universe->pushActiveStarSystem( _Universe->AccessCockpit( squadnum )->activeStarSystem );
866  }
867  //In networking mode we name the ship save with .xml as they are xml files
868  if ( Network != NULL && squadnum < (int) fighter0name.size() ) {
869  if (Network[squadnum].getCallsign() != modifications) {
870  cout<<"Not CREATING A NETWORK PLAYER "<<fightername<<" FOR "<<modifications<<endl;
871  break;
872  }
873  cout<<"CREATING A NETWORK PLAYER : "<<fightername<<endl;
874  fighters[a] = UnitFactory::createUnit( fightername, false, tmptarget[a], "", fg, s, &savefiles[squadnum][1] );
875  //Set the faction we have in the save file instead of the mission file (that is to be ignored in networking mode)
876  fighters[a]->faction = FactionUtil::GetFactionIndex( cp->savegame->GetPlayerFaction() );
877  fighters[a]->SetNetworkMode();
878  fighters[a]->SetSerial( Network[squadnum].serial );
879  Network[squadnum].setUnit( fighters[a] );
880  cout<<"Creating fighter["<<squadnum<<"] from "<<modifications<<" on Network["<<squadnum<<"] named "
881  <<Network[squadnum].getCallsign()<<endl;
882  } else if (Network != NULL) {
883  cout<<"Not CREATING A LOCAL SHIP : "<<fightername<<endl;
884  break;
885  } else {
886  cout<<"CREATING A LOCAL SHIP : "<<fightername<<endl;
887  fighters[a] = UnitFactory::createUnit( fightername, false, tmptarget[a], modifications, fg, s );
888  }
890  if ( s == 0 && squadnum < (int) fighter0name.size() ) {
891  _Universe->AccessCockpit( squadnum )->Init( fighters[a]->getCockpit().c_str() );
892  _Universe->AccessCockpit( squadnum )->SetParent( fighters[a], fighter0name[squadnum].c_str(),
893  fighter0mods[squadnum].c_str(), pox );
894  }
895  if ( squadnum < (int) fighter0name.size() ) {
897  _Universe->SetActiveCockpit( backupcp );
898  }
899  } else {
900  bool isvehicle = false;
901  if (fg_terrain == -2) {
902  fighters[a] =
903  UnitFactory::createBuilding( myterrain, isvehicle, fightername, false, tmptarget[a], string( "" ), fg );
904  } else {
905  if ( fg_terrain >= (int) _Universe->activeStarSystem()->numTerrain() ) {
906  ContinuousTerrain *t;
907  assert(
908  fg_terrain-_Universe->activeStarSystem()->numTerrain()
911  fighters[a] = UnitFactory::createBuilding( t, isvehicle, fightername, false, tmptarget[a], string(
912  "" ), fg );
913  } else {
914  Terrain *t = _Universe->activeStarSystem()->getTerrain( fg_terrain );
915  fighters[a] = UnitFactory::createBuilding( t, isvehicle, fightername, false, tmptarget[a], string(
916  "" ), fg );
917  }
918  }
920  }
921  printf( "pox %lf %lf %lf\n", pox.i, pox.j, pox.k );
922  fighters[a]->SetPosAndCumPos( pox );
923  fg_radius = fighters[a]->rSize();
924  if ( benchmark > 0.0 || ( s != 0 || squadnum >= (int) fighter0name.size() ) ) {
925  fighters[a]->LoadAIScript( ainame );
926  fighters[a]->SetTurretAI();
927  }
928  a++;
929  } //for nr_ships
930  squadnum++;
931  } //end of for flightgroups
932 
933  delete[] tmptarget;
934  for (int m_i = 0; m_i < muzak_count; m_i++)
935  muzak[m_i].SetParent( fighters[0] );
937  AUDListenerSize( fighters[0]->rSize()*4 );
938  for (unsigned int cnum = 0; cnum < fighter0indices.size(); cnum++) {
939  if (benchmark == -1) {
940  fighters[fighter0indices[cnum]]->EnqueueAI( new FlyByJoystick( cnum ) );
941  fighters[fighter0indices[cnum]]->EnqueueAI( new FireKeyboard( cnum, cnum ) );
942  }
943  fighters[fighter0indices[cnum]]->SetTurretAI();
944  fighters[fighter0indices[cnum]]->DisableTurretAI();
945  }
947  locSel = new CoordinateSelect( QVector( 0, 0, 5 ) );
948  UpdateTime();
949 
950  mission->DirectorInitgame();
952 }
953 
954 void AddUnitToSystem( const SavedUnits *su )
955 {
956  Unit *un = NULL;
957  switch (su->type)
958  {
959  case ENHANCEMENTPTR:
960  un =
961  UnitFactory::createEnhancement( su->filename.get().c_str(), FactionUtil::GetFactionIndex( su->faction ), string( "" ) );
962  un->SetPosition( QVector( 0, 0, 0 ) );
963  break;
964  case UNITPTR:
965  default:
966  un = UnitFactory::createUnit( su->filename.get().c_str(), false, FactionUtil::GetFactionIndex( su->faction ) );
967  un->EnqueueAI( new Orders::AggressiveAI( "default.agg.xml" ) );
968  un->SetTurretAI();
969  if ( _Universe->AccessCockpit()->GetParent() )
970  un->SetPosition( _Universe->AccessCockpit()->GetParent()->Position()
971  +QVector( rand()*10000./RAND_MAX-5000, rand()*10000./RAND_MAX-5000, rand()*10000./RAND_MAX-5000 ) );
972  break;
973  }
975 }
976 
978 {
979  if (myterrain)
980  delete myterrain;
981  Terrain::DeleteAll();
982  delete tmpcockpittexture;
983  delete[] fighters;
984  delete locSel;
985 }
986 
988 {
989  return game_options.threadtime;
990 }
991 
993 {
994  RestoreKB();
995  RestoreMouse();
996  GFXLoop( main_loop );
997 }
998 
999 void main_loop()
1000 {
1001  //Evaluate number of loops per second each XX loops
1002  if (loop_count == 500) {
1004  cur_check = getNewTime();
1005  if (last_check != 1) {
1006  //Time to update test
1008  nb_checks = nb_checks+1;
1009  }
1010  loop_count = -1;
1011  }
1012  loop_count++;
1013 
1014  //Execute DJ script
1015  Music::MuzakCycle();
1016 
1017  _Universe->StartDraw();
1018  if (myterrain)
1019  myterrain->AdjustTerrain( _Universe->activeStarSystem() );
1020  if (Network != NULL)
1021  for (size_t jj = 0; jj < _Universe->numPlayers(); jj++)
1022  Network[jj].checkMsg( NULL );
1023 
1024 #ifndef NO_GFX
1025  VSFileSystem::vs_dprintf(3, "Drawn %d vertices in %d batches\n",
1026  gl_vertices_this_frame,
1027  gl_batches_this_frame);
1028  gl_vertices_this_frame = 0;
1029  gl_batches_this_frame = 0;
1030 #endif
1031 
1032  //Commit audio scene status to renderer
1033  if (g_game.sound_enabled)
1034  Audio::SceneManager::getSingleton()->commit();
1035 }
1036