Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/story_entities/world.cc @ 4961

Last change on this file since 4961 was 4961, checked in by bensch, 19 years ago

orxonox/trunk: music now plays back, as one would expect, and the ReosurceManager handles ogg's.
Also the naming has changed a bit, and doxygen tags are complete in ogg_player.h/cc

File size: 29.5 KB
Line 
1
2
3/*
4   orxonox - the future of 3D-vertical-scrollers
5
6   Copyright (C) 2004 orx
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 2, or (at your option)
11   any later version.
12
13   ### File Specific:
14   main-programmer: Patrick Boenzli
15   co-programmer: Christian Meyer
16*/
17
18#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
19
20#include "world.h"
21
22#include "orxonox.h"
23
24#include "state.h"
25
26#include "p_node.h"
27#include "null_parent.h"
28#include "pilot_node.h"
29#include "track_node.h"
30#include "world_entity.h"
31#include "player.h"
32#include "camera.h"
33#include "environment.h"
34#include "skysphere.h"
35#include "skybox.h"
36#include "satellite.h"
37#include "test_entity.h"
38#include "terrain.h"
39#include "light.h"
40#include "text_engine.h"
41#include "load_param.h"
42
43#include "track_manager.h"
44#include "garbage_collector.h"
45#include "fast_factory.h"
46#include "animation_player.h"
47#include "particle_engine.h"
48#include "graphics_engine.h"
49#include "physics_engine.h"
50#include "fields.h"
51
52#include "md2Model.h"
53
54#include "glmenu_imagescreen.h"
55#include "list.h"
56#include "game_loader.h"
57
58#include "animation3d.h"
59
60#include "substring.h"
61
62#include "factory.h"
63
64#include "projectile.h"
65#include "event_handler.h"
66
67#include "sound_engine.h"
68#include "ogg_player.h"
69
70#include "class_list.h"
71
72#include "cd_engine.h"
73
74
75using namespace std;
76
77WorldInterface* WorldInterface::singletonRef = 0;
78
79
80/**
81 *  private constructor because of singleton
82*/
83WorldInterface::WorldInterface()
84{
85  this->worldIsInitialized = false;
86  this->worldReference = NULL;
87}
88
89/**
90 *  public deconstructor
91*/
92WorldInterface::~WorldInterface()
93{
94  this->singletonRef = NULL;
95  this->worldIsInitialized = false;
96  this->worldReference = NULL;
97}
98
99/**
100 *  gets the singleton instance
101 * @returns singleton instance
102*/
103WorldInterface* WorldInterface::getInstance()
104{
105  if( singletonRef == NULL)
106    singletonRef = new WorldInterface();
107  return singletonRef;
108}
109
110
111/**
112 *  initializes the interface
113 * @param reference to the world
114
115   if the worldinterface is not initilizes, there wont be any
116   useable interface
117*/
118void WorldInterface::init(World* world)
119{
120  this->worldReference = world;
121  if( world != NULL)
122    {
123      this->worldIsInitialized = true;
124      PRINTF(3)("WorldInterface up and running\n");
125    }
126}
127
128
129/**
130 *  gets the entity list from the world
131 * @return entity list
132*/
133tList<WorldEntity>* WorldInterface::getEntityList()
134{
135  if( this->worldIsInitialized)
136    return this->worldReference->getEntities();
137  PRINT(1)("tried to use the WorldInterface before it has been initizlized! this can result in SEGFAULTs!\n");
138  return NULL;
139}
140
141CREATE_FACTORY(World);
142
143World::World(const TiXmlElement* root)
144{
145  this->constuctorInit("", -1);
146  this->path = NULL;
147
148  this->loadParams(root);
149}
150
151/**
152  *  create a new World
153
154    This creates a new empty world!
155*/
156World::World (char* name)
157{
158  this->path = NULL;
159  this->constuctorInit(name, -1);
160  //NullParent* np = NullParent::getInstance();
161}
162
163/**
164 *  creates a new World...
165 * @param worldID with this ID
166*/
167World::World (int worldID)
168{
169  this->path = NULL;
170  this->constuctorInit(NULL, worldID);
171}
172
173/**
174 *  remove the World from memory
175
176    delete everything explicitly, that isn't contained in the parenting tree!
177    things contained in the tree are deleted automaticaly
178 */
179World::~World ()
180{
181  PRINTF(3)("World::~World() - deleting current world\n");
182
183  ParticleEngine::getInstance()->debug();
184
185  delete WorldInterface::getInstance();
186  delete this->entities;
187  State::setWorldEntityList(NULL);
188//  delete NullParent::getInstance();
189
190
191  delete LightManager::getInstance();
192  delete TrackManager::getInstance();
193  delete ParticleEngine::getInstance();
194
195  TextEngine::getInstance()->flush();
196  SoundEngine::getInstance()->flushAllBuffers();
197  SoundEngine::getInstance()->flushAllSources();
198
199  delete AnimationPlayer::getInstance(); // this should be at the end of the unloading sequence.
200  delete PhysicsEngine::getInstance();
201  //delete garbagecollecor
202  //delete animator
203
204  FastFactory::flushAll();
205  delete NullParent::getInstance();
206  EventHandler::getInstance()->debug();
207
208  LoadClassDescription::printAll();
209
210
211  ResourceManager::getInstance()->unload(this->music);
212  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
213}
214
215/**
216 *  initializes the world.
217
218   set all stuff here that is world generic and does not use to much memory
219   because the real init() function StoryEntity::init() will be called
220   shortly before start of the game.
221   since all worlds are initiated/referenced before they will be started.
222   NO LEVEL LOADING HERE - NEVER!
223*/
224void World::constuctorInit(char* name, int worldID)
225{
226  this->setClassID(CL_WORLD, "World");
227
228  //this->worldName = name;
229  //this->worldName = new char[strlen(name)+1];
230  //strcpy(this->worldName, name);
231  this->debugWorldNr = worldID;
232
233  this->music = NULL;
234}
235
236void World::loadParams(const TiXmlElement* root)
237{
238  const char *string;
239  char *name;
240  int id;
241
242  PRINTF(4)("Creating a World\n");
243
244  LoadParam<World>(root, "identifier", this, &World::setStoryID)
245    .describe("Sets the StoryID of this world");
246
247  LoadParam<World>(root, "nextid", this, &World::setNextStoryID)
248    .describe("Sets the ID of the next world");
249
250  LoadParam<World>(root, "path", this, &World::setPath)
251    .describe("The Filename of this World (relative from the data-dir)");
252}
253
254
255/**
256 *  this is executed before load
257
258   since the load function sometimes needs data, that has been init before
259   the load and after the proceeding storyentity has finished
260*/
261ErrorMessage World::preLoad()
262{
263  State::setWorldEntityList(this->entities = new tList<WorldEntity>());
264  this->cycle = 0;
265
266
267  /* init the world interface */
268  WorldInterface* wi = WorldInterface::getInstance();
269  wi->init(this);
270
271  LightManager::getInstance();
272  this->nullParent = NullParent::getInstance ();
273  this->nullParent->setName ("NullParent");
274
275  AnimationPlayer::getInstance(); // initializes the animationPlayer
276  PhysicsEngine::getInstance();
277
278  this->localCamera = new Camera();
279  this->localCamera->setName ("Camera");
280
281  State::setCamera(this->localCamera, this->localCamera->getTarget());
282
283  GraphicsEngine::getInstance()->displayFPS(true);
284
285  CDEngine::getInstance()->setEntityList( this->entities);
286}
287
288
289/**
290 *  loads the World by initializing all resources, and set their default values.
291*/
292ErrorMessage World::load()
293{
294  PRINTF(3)("> Loading world: '%s'\n", getPath());
295  TiXmlElement* element;
296  GameLoader* loader = GameLoader::getInstance();
297
298  if( getPath() == NULL)
299    {
300      PRINTF(1)("World has no path specified for loading");
301      this->loadDebugWorld(this->getStoryID());
302      return (ErrorMessage){213,"Path not specified","World::load()"};
303    }
304
305  TiXmlDocument* XMLDoc = new TiXmlDocument( path);
306  // load the campaign document
307  if( !XMLDoc->LoadFile())
308  {
309    // report an error
310    PRINTF(1)("loading XML File: %s @ %d:%d\n", XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
311    delete XMLDoc;
312    return (ErrorMessage){213,"XML File parsing error","World::load()"};
313  }
314
315  // check basic validity
316  TiXmlElement* root = XMLDoc->RootElement();
317  assert( root != NULL);
318
319  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
320    {
321      // report an error
322      PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
323      delete XMLDoc;
324      return (ErrorMessage){213,"Path not a WorldDataFile","World::load()"};
325    }
326
327  // load the parameters
328  // name
329  char* temp;
330  const char* string = grabParameter( root, "name");
331  if( string == NULL)
332    {
333      PRINTF(2)("World is missing a proper 'name'\n");
334      string = "Unknown";
335      temp = new char[strlen(string + 2)];
336      strcpy( temp, string);
337      this->worldName = temp;
338    }
339  else
340    {
341      temp = new char[strlen(string + 2)];
342      strcpy( temp, string);
343      this->worldName = temp;
344    }
345  ////////////////
346  // LOADSCREEN //
347  ////////////////
348  element = root->FirstChildElement("LoadScreen");
349  if (element == NULL)
350    {
351      PRINTF(2)("no LoadScreen specified, loading default\n");
352
353      glmis->setBackgroundImage("pictures/load_screen.jpg");
354      this->glmis->setMaximum(8);
355      this->glmis->draw();
356    }
357  else
358    {
359      this->glmis->loadParams(element);
360      this->glmis->draw();
361    }
362  this->glmis->draw();
363
364  ////////////////////////
365  // find WorldEntities //
366  ////////////////////////
367
368  element = root->FirstChildElement("WorldEntities");
369
370  if( element == NULL)
371    {
372      PRINTF(1)("World is missing 'WorldEntities'\n");
373    }
374  else
375    {
376      element = element->FirstChildElement();
377      // load Players/Objects/Whatever
378      PRINTF(4)("Loading WorldEntities\n");
379      while( element != NULL)
380        {
381          WorldEntity* created = dynamic_cast<WorldEntity*>( loader->fabricate( element));
382          if( created != NULL) this->spawn( created);
383          // if we load a 'Player' we use it as localPlayer
384          //todo do this more elegant
385          if( element->Value() != NULL && !strcmp( element->Value(), "Player"))
386          {
387            localPlayer = (Player*) created;
388            CDEngine::getInstance()->setPlayer(localPlayer);
389          }
390          if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox")) sky = (SkyBox*) created;
391          if( element->Value() != NULL && !strcmp( element->Value(), "Terrain"))
392          {
393            terrain = (Terrain*) created;
394            CDEngine::getInstance()->setTerrain(terrain);
395          }
396          element = element->NextSiblingElement();
397          glmis->step(); //! @todo temporary
398        }
399      PRINTF(4)("Done loading WorldEntities\n");
400    }
401
402    //////////////////////////////
403    // LOADING ADDITIONAL STUFF //
404    //////////////////////////////
405
406    LoadParam<LightManager>(root, "LightManager", LightManager::getInstance(), &LightManager::loadParams);
407
408    LoadParam<ParticleEngine>(root, "ParticleEngine", ParticleEngine::getInstance(), &ParticleEngine::loadParams);
409    LoadParam<PhysicsEngine>(root, "PhysicsEngine", PhysicsEngine::getInstance(), &PhysicsEngine::loadParams);
410
411  // find Track
412  element = root->FirstChildElement( "Track");
413  if( element == NULL)
414    {
415      PRINTF(0)("World is missing a 'Track'\n");
416    }
417  else
418    {
419      //load track
420      PRINTF(4)("Loading Track\n");
421
422      TrackManager::getInstance()->loadParams( element);
423      TrackManager::getInstance()->finalize();
424    }
425
426  // free the XML data
427
428  delete XMLDoc;
429  /* GENERIC LOADING PROCESS FINISHED */
430
431  // bind input
432  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_UP);
433  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_DOWN);
434  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_LEFT);
435  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_RIGHT);
436  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
437  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
438  EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
439
440  // bind camera
441  //this->localCamera->bind (localPlayer);
442  this->localPlayer->addChild (this->localCamera);
443
444
445//   lightMan->setAmbientColor(.1,.1,.1);
446//   lightMan->addLight();
447//   //      lightMan->setAttenuation(1.0, .01, 0.0);
448//   //      lightMan->setDiffuseColor(1,1,1);
449//   //  lightMan->addLight(1);
450//   //  lightMan->setPosition(20, 10, -20);
451//   //  lightMan->setDiffuseColor(0,0,0);
452//   //lightMan->debug();
453//   lightMan->setPosition(-5.0, 50.0, -40.0);
454//   lightMan->addLight();
455//   lightMan->setPosition(100, 80, 60);
456
457  //        TrackManager::getInstance()->setBindSlave(env);
458  PNode* tn = TrackManager::getInstance()->getTrackNode();
459  tn->addChild(this->localPlayer);
460
461  //localCamera->setParent(TrackNode::getInstance());
462  tn->addChild(this->localCamera);
463  localCamera->lookAt(tn);
464  localCamera->setParentMode(PNODE_MOVEMENT);
465  localCamera->setClipRegion(1, 10000.0);
466  this->localPlayer->setParentMode(PNODE_ALL);
467  Vector* cameraOffset = new Vector (0, 5, -10);
468  TrackManager::getInstance()->condition(1, LEFTRIGHT, this->localPlayer);
469
470  this->sky->setParent(this->localCamera);
471
472  // initialize debug coord system
473  objectList = glGenLists(1);
474  glNewList (objectList, GL_COMPILE);
475
476  //TrackManager::getInstance()->drawGraph(.01);
477  //TrackManager::getInstance()->debug(2);
478  glEndList();
479
480  SoundEngine::getInstance()->setListener(this->localCamera);
481
482
483
484
485  ////////////
486  // STATIC //
487  ////////////
488
489  Gravity* test = new Gravity();
490
491  // SYSTEM TRAILING THE PLAYER
492  // Creating a Test Particle System
493
494  //new PhysicsConnection(system, gravity);
495  //    new PhysicsConnection(this->localPlayer, gravity);
496
497//   TestEntity* testEntity = new TestEntity();
498//   testEntity->setRelCoor(Vector(570, 10, -15));
499//   testEntity->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
500//   this->spawn(testEntity);
501
502  TestEntity* testEntity2 = new TestEntity();
503  testEntity2->setAnim(RUN);
504  testEntity2->setRelCoor(Vector(2400, 25, 260));
505  testEntity2->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
506  this->spawn(testEntity2);
507
508  TestEntity* testEntity3 = new TestEntity();
509  testEntity3->setAnim(RUN);
510  testEntity3->setRelCoor(Vector(2400, 25, 280));
511  testEntity3->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
512  this->spawn(testEntity3);
513
514  TestEntity* testEntity4 = new TestEntity();
515  testEntity4->setAnim(RUN);
516  testEntity4->setRelCoor(Vector(2430, 25, 250));
517  testEntity4->setRelDir(Quaternion(M_PI, Vector(0, 1, 0)));
518  this->spawn(testEntity4);
519
520
521  PhysicsEngine::getInstance()->debug();
522
523
524  ClassList::debug();
525
526  this->music = (OggPlayer*)ResourceManager::getInstance()->load("sound/00-luke_grey_-_hypermode.ogg", OGG, RP_LEVEL);
527  music->playback();
528}
529
530
531
532/**
533 *  loads the debug world: only for experimental stuff
534*/
535void World::loadDebugWorld(int worldID)
536{
537  /*monitor progress*/
538  this->glmis->step();
539  // stuff beyond this point remains to be loaded properly
540
541  // initializing the TrackManager
542  TrackManager::getInstance()->addPointV(Vector(150, -35, 5));
543  TrackManager::getInstance()->addPointV(Vector(200,-35, 5));
544  TrackManager::getInstance()->addPointV(Vector(250, -35, 5));
545  TrackManager::getInstance()->addPointV(Vector(320,-33,-.55));
546  TrackManager::getInstance()->setDuration(1);
547  TrackManager::getInstance()->setSavePoint();
548
549  TrackManager::getInstance()->addPointV(Vector(410, 0, 0));
550  TrackManager::getInstance()->addPointV(Vector(510, 20, -10));
551  TrackManager::getInstance()->addPointV(Vector(550, 20, -10));
552  TrackManager::getInstance()->addPointV(Vector(570, 20, -10));
553  TrackManager::getInstance()->setDuration(2);
554
555  TrackManager::getInstance()->forkS("testFork1,testFork2");
556  TrackManager::getInstance()->workOnS("testFork1");
557  TrackManager::getInstance()->addPointV(Vector(640, 25, -30));
558  TrackManager::getInstance()->addPointV(Vector(700, 40, -120));
559  TrackManager::getInstance()->addPointV(Vector(800, 50, -150));
560  TrackManager::getInstance()->addPointV(Vector(900, 60, -100));
561  TrackManager::getInstance()->addPointV(Vector(900, 60, -70));
562  TrackManager::getInstance()->addPointV(Vector(990, 65, -15));
563  TrackManager::getInstance()->addPointV(Vector(1050, 65, -10));
564  TrackManager::getInstance()->addPointV(Vector(1100, 65, -20));
565  TrackManager::getInstance()->setDuration(4);
566
567  TrackManager::getInstance()->workOnS("testFork2");
568  TrackManager::getInstance()->addPointV(Vector(640, 25, 20));
569  TrackManager::getInstance()->addPointV(Vector(670, 50, 120));
570  TrackManager::getInstance()->addPointV(Vector(700, 70, 80));
571  TrackManager::getInstance()->addPointV(Vector(800, 70, 65));
572  TrackManager::getInstance()->addPointV(Vector(850, 65, 65));
573  TrackManager::getInstance()->addPointV(Vector(920, 35, 40));
574  TrackManager::getInstance()->addPointV(Vector(945, 40, 40));
575  TrackManager::getInstance()->addPointV(Vector(970, 24, 40));
576  TrackManager::getInstance()->addPointV(Vector(1000, 40, -7));
577
578  TrackManager::getInstance()->setDuration(4);
579
580
581  TrackManager::getInstance()->joinS("testFork1,testFork2");
582
583  TrackManager::getInstance()->addPointV(Vector(1200, 60, -50));
584  TrackManager::getInstance()->addPointV(Vector(1300, 50, -50));
585  TrackManager::getInstance()->addPointV(Vector(1400, 40, -50));
586  TrackManager::getInstance()->addPointV(Vector(1500, 40, -60));
587  TrackManager::getInstance()->addPointV(Vector(1600, 35, -55));
588  TrackManager::getInstance()->addPointV(Vector(1700, 45, -40));
589  TrackManager::getInstance()->addPointV(Vector(1750, 60, -40));
590  TrackManager::getInstance()->addPointV(Vector(1770, 80, -40));
591  TrackManager::getInstance()->addPointV(Vector(1800, 100, -40));
592  TrackManager::getInstance()->setDuration(10);
593
594  TrackManager::getInstance()->finalize();
595
596
597  // LIGHT initialisation
598  LightManager::getInstance()->setAmbientColor(.1,.1,.1);
599//  LightManager::getInstance()->addLight();
600  LightManager::getInstance()->debug();
601
602  switch(this->debugWorldNr)
603    {
604      /*
605        this loads the hard-coded debug world. this only for simplicity and will be
606        removed by a reald world-loader, which interprets a world-file.
607        if you want to add an own debug world, just add a case DEBUG_WORLD_[nr] and
608        make whatever you want...
609      */
610    case DEBUG_WORLD_0:
611      {
612        LightManager::getInstance()->getLight()->setAbsCoor(-5.0, 10.0, -40.0);
613
614
615        this->localPlayer = new Player ();
616        this->localPlayer->setName ("player");
617        this->spawn (this->localPlayer);
618        this->localPlayer->setRelCoor(Vector(5,0,0));
619        /*monitor progress*/
620        this->glmis->step();
621
622
623        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_FIRE1);
624        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_NEXT_WEAPON);
625        EventHandler::getInstance()->subscribe(this->localPlayer, ES_GAME, KeyMapper::PEV_PREVIOUS_WEAPON);
626
627        /*
628        Field* testField = new Gravity();
629        testField->setMagnitude(10);
630        new PhysicsConnection(this->localPlayer, testField);
631        */
632
633        // bind camera
634        this->localCamera = new Camera();
635        this->localCamera->setName ("camera");
636        /*monitor progress*/
637        this->glmis->step();
638
639
640        // Create SkySphere
641        this->sky = new Skysphere("pictures/sky-replace.jpg");
642        this->sky->setName("SkySphere");
643        this->spawn(this->sky);
644        this->localCamera->addChild(this->sky);
645        this->sky->setParentMode(PNODE_MOVEMENT);
646        /*monitor progress*/
647        this->glmis->step();
648
649
650        terrain = new Terrain("worlds/newGround.obj");
651        terrain->setRelCoor(Vector(0,-10,0));
652        this->spawn(terrain);
653        /*monitor progress*/
654        this->glmis->step();
655
656        this->pilotNode = new PilotNode();
657        this->spawn(this->pilotNode);
658        this->pilotNode->setAbsCoor(Vector(150, -35, 5));
659        this->pilotNode->addChild(this->localPlayer);
660        this->pilotNode->addChild(this->localCamera);
661        this->localCamera->lookAt(this->localPlayer);
662
663        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_UP);
664        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_DOWN);
665        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_LEFT);
666        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, KeyMapper::PEV_RIGHT);
667        EventHandler::getInstance()->subscribe(this->pilotNode, ES_GAME, EV_MOUSE_MOTION);
668
669        // bind input
670        Orxonox *orx = Orxonox::getInstance ();
671        //orx->getLocalInput()->bind (this->pilotNode);
672
673        /*
674        PNode* tn = TrackManager::getInstance()->getTrackNode();
675        tn->addChild(this->localPlayer);
676        this->localCamera->lookAt(tn);
677
678        tn->addChild(this->localCamera);
679        this->localPlayer->setParentMode(PNODE_ALL);
680        TrackManager::getInstance()->condition(2, LEFTRIGHT, this->localPlayer);
681        */
682        this->glmis->step();
683        break;
684      }
685    case DEBUG_WORLD_1:
686      {
687
688        break;
689      }
690    case DEBUG_WORLD_2:
691      {
692
693        break;
694      }
695    default:
696      break;
697    }
698}
699
700
701
702/**
703 *  initializes a new World shortly before start
704
705   this is the function, that will be loaded shortly before the world is
706   started
707*/
708ErrorMessage World::init()
709{
710  this->bPause = false;
711  this->pilotNode = NULL;
712}
713
714
715/**
716 *  starts the World
717*/
718ErrorMessage World::start()
719{
720  PRINTF(3)("World::start() - starting current World: nr %i\n", this->debugWorldNr);
721  this->bQuitOrxonox = false;
722  this->bQuitCurrentGame = false;
723  this->mainLoop();
724}
725
726/**
727 *  stops the world.
728
729   This happens, when the player decides to end the Level.
730*/
731ErrorMessage World::stop()
732{
733  PRINTF(3)("World::stop() - got stop signal\n");
734  this->bQuitCurrentGame = true;
735}
736
737/**
738 *  pauses the Game
739*/
740ErrorMessage World::pause()
741{
742  this->isPaused = true;
743}
744
745/**
746 *  ends the pause Phase
747*/
748ErrorMessage World::resume()
749{
750  this->isPaused = false;
751}
752
753/**
754 *  destroys the World
755*/
756ErrorMessage World::destroy()
757{
758
759}
760
761/**
762 *  shows the loading screen
763*/
764void World::displayLoadScreen ()
765{
766  PRINTF(3)("World::displayLoadScreen - start\n");
767
768  //GLMenuImageScreen*
769  this->glmis = new GLMenuImageScreen();
770  this->glmis->setMaximum(8);
771
772  PRINTF(3)("World::displayLoadScreen - end\n");
773}
774
775/**
776 *  removes the loadscreen, and changes over to the game
777
778   @todo take out the delay
779*/
780void World::releaseLoadScreen ()
781{
782  PRINTF(3)("World::releaseLoadScreen - start\n");
783  this->glmis->setValue(this->glmis->getMaximum());
784  PRINTF(3)("World::releaseLoadScreen - end\n");
785  delete this->glmis;
786}
787
788
789/**
790 *  gets the list of entities from the world
791 * @returns entity list
792*/
793tList<WorldEntity>* World::getEntities()
794{
795  return this->entities;
796}
797
798
799/**
800 *  this returns the current game time
801 * @returns elapsed game time
802*/
803double World::getGameTime()
804{
805  return this->gameTime;
806}
807
808
809/**
810 *  function to put your own debug stuff into it. it can display informations about
811   the current class/procedure
812*/
813void World::debug()
814{
815}
816
817
818/**
819  \brief main loop of the world: executing all world relevant function
820
821  in this loop we synchronize (if networked), handle input events, give the heart-beat to
822  all other member-entities of the world (tick to player, enemies etc.), checking for
823  collisions drawing everything to the screen.
824*/
825void World::mainLoop()
826{
827  this->lastFrame = SDL_GetTicks ();
828  PRINTF(3)("World::mainLoop() - Entering main loop\n");
829  while( !this->bQuitOrxonox && !this->bQuitCurrentGame) /* @todo implement pause */
830    {
831      ++this->cycle;
832      PRINTF(3)("World::mainloop() - number of entities: %i\n", this->entities->getSize());
833      // Network
834      this->synchronize ();
835      // Process input
836      this->handleInput ();
837      if( this->bQuitCurrentGame || this->bQuitOrxonox)
838          break;
839      // Process collision
840      this->collide ();
841      // Process time
842      this->tick ();
843      // Update the state
844      this->update ();
845      // Draw
846      this->display ();
847
848      //      for( int i = 0; i < 5000000; i++) {}
849      /* @todo this is to slow down the program for openGl Software emulator computers, reimplement*/
850    }
851  PRINTF(3)("World::mainLoop() - Exiting the main loop\n");
852}
853
854
855/**
856 *  synchronize local data with remote data
857*/
858void World::synchronize ()
859{
860  // Get remote input
861  // Update synchronizables
862}
863
864
865/**
866 *  run all input processing
867
868   the command node is the central input event dispatcher. the node uses the even-queue from
869   sdl and has its own event-passing-queue.
870*/
871void World::handleInput ()
872{
873  // localinput
874  //CommandNode* cn = Orxonox::getInstance()->getLocalInput();
875  //cn->process();
876
877  EventHandler::getInstance()->process();
878
879  // remoteinput
880}
881
882
883/**
884 *  advance the timeline
885
886   this calculates the time used to process one frame (with all input handling, drawing, etc)
887   the time is mesured in ms and passed to all world-entities and other classes that need
888   a heart-beat.
889*/
890void World::tick ()
891{
892  Uint32 currentFrame = SDL_GetTicks();
893  if(!this->bPause)
894    {
895      this->dt = currentFrame - this->lastFrame;
896
897      if( this->dt > 10)
898        {
899          float fps = 1000/dt;
900
901          // temporary, only for showing how fast the text-engine is
902          char tmpChar[20];
903          sprintf(tmpChar, "fps: %4.0f", fps);
904        }
905      else
906        {
907          /* the frame-rate is limited to 100 frames per second, all other things are for
908             nothing.
909          */
910          PRINTF(2)("fps = 1000 - frame rate is adjusted\n");
911          SDL_Delay(10-dt);
912          this->dt = 10;
913        }
914
915      this->dtS = (float)this->dt / 1000.0;
916      this->gameTime += this->dtS;
917
918      tIterator<WorldEntity>* iterator = this->entities->getIterator();
919      WorldEntity* entity = iterator->nextElement();
920      while( entity != NULL)
921        {
922          entity->tick (this->dtS);
923          entity = iterator->nextElement();
924        }
925      delete iterator;
926
927      /* update tick the rest */
928      TrackManager::getInstance()->tick(this->dtS);
929      this->localCamera->tick(this->dtS);
930      // tick the engines
931      AnimationPlayer::getInstance()->tick(this->dtS);
932      if (this->cycle > 5)
933        PhysicsEngine::getInstance()->tick(this->dtS);
934
935      ParticleEngine::getInstance()->tick(this->dtS);
936      GarbageCollector::getInstance()->tick(this->dtS);
937
938
939      /** actualy the Graphics Engine should tick the world not the other way around...
940         but since we like the things not too complicated we got it this way around
941         until there is need or time to do it the other way around.
942         @todo: GraphicsEngine ticks world: separation of processes and data...
943
944        bensch: in my opinion the GraphicsEngine could draw the world, but not tick it,
945         beceause graphics have nothing(or at least not much) to do with Motion.
946      */
947      GraphicsEngine::getInstance()->tick(this->dtS);
948    }
949  this->lastFrame = currentFrame;
950}
951
952
953/**
954 *  this function gives the world a consistant state
955
956   after ticking (updating the world state) this will give a constistant
957   state to the whole system.
958*/
959void World::update()
960{
961  GarbageCollector::getInstance()->update();
962  this->nullParent->update (this->dtS);
963
964  SoundEngine::getInstance()->update();
965  music->update();
966}
967
968
969void World::collide()
970{
971  CDEngine::getInstance()->checkCollisions();
972}
973
974/**
975 *  render the current frame
976
977   clear all buffers and draw the world
978*/
979void World::display ()
980{
981  // clear buffer
982  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
983  // set camera
984  this->localCamera->apply ();
985  // draw world
986  this->draw();
987  // draw HUD
988  /** @todo draw HUD */
989  // flip buffers
990  GraphicsEngine::swapBuffers();
991  //SDL_Surface* screen = Orxonox::getInstance()->getScreen ();
992  //SDL_Flip (screen);
993}
994
995
996/**
997 *  runs through all entities calling their draw() methods
998 */
999void World::draw ()
1000{
1001  /* draw entities */
1002  WorldEntity* entity;
1003  glLoadIdentity();
1004  //entity = this->entities->enumerate();
1005  tIterator<WorldEntity>* iterator = this->entities->getIterator();
1006  entity = iterator->nextElement();
1007  while( entity != NULL )
1008  {
1009    if( entity->isVisible() ) entity->draw();
1010      //entity = this->entities->nextElement();
1011    entity = iterator->nextElement();
1012  }
1013  delete iterator;
1014
1015  glCallList (objectList);
1016
1017  ParticleEngine::getInstance()->draw();
1018
1019  GraphicsEngine::getInstance()->draw();
1020  //TextEngine::getInstance()->draw();
1021}
1022
1023/**
1024 *  add and spawn a new entity to this world
1025 * @param entity to be added
1026*/
1027void World::spawn(WorldEntity* entity)
1028{
1029  this->entities->add (entity);
1030  entity->postSpawn ();
1031}
1032
1033
1034/**
1035 *  add and spawn a new entity to this world
1036 * @param entity to be added
1037 * @param absCoor At what coordinates to add this entity.
1038 * @param absDir In which direction should it look.
1039*/
1040void World::spawn(WorldEntity* entity, Vector* absCoor, Quaternion* absDir)
1041{
1042  this->entities->add (entity);
1043
1044  entity->setAbsCoor (*absCoor);
1045  entity->setAbsDir (*absDir);
1046
1047  entity->postSpawn ();
1048}
1049
1050
1051/**
1052 *  add and spawn a new entity to this world
1053 * @param entity to be added
1054 * @param entity to be added to (PNode)
1055 * @param At what relative  coordinates to add this entity.
1056 * @param In which relative direction should it look.
1057*/
1058void World::spawn(WorldEntity* entity, PNode* parentNode,
1059                  Vector* relCoor, Quaternion* relDir)
1060{
1061  this->nullParent = NullParent::getInstance();
1062  if( parentNode != NULL)
1063    {
1064      parentNode->addChild (entity);
1065
1066      entity->setRelCoor (*relCoor);
1067      entity->setRelDir (*relDir);
1068
1069      this->entities->add (entity);
1070
1071      entity->postSpawn ();
1072    }
1073}
1074
1075
1076
1077/**
1078  \brief commands that the world must catch
1079  @returns false if not used by the world
1080*/
1081bool World::command(Command* cmd)
1082{
1083  if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW0)) this->localCamera->setViewMode(VIEW_NORMAL);
1084  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW1)) this->localCamera->setViewMode(VIEW_BEHIND);
1085  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW2)) this->localCamera->setViewMode(VIEW_FRONT);
1086  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW3)) this->localCamera->setViewMode(VIEW_LEFT);
1087  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW4)) this->localCamera->setViewMode(VIEW_RIGHT);
1088  else if( !strcmp( cmd->cmd, CONFIG_NAME_VIEW5)) this->localCamera->setViewMode(VIEW_TOP);
1089  return false;
1090}
1091
1092void World::setPath( const char* name)
1093{
1094  if (this->path)
1095    delete this->path;
1096  if (ResourceManager::isFile(name))
1097  {
1098    this->path = new char[strlen(name)+1];
1099    strcpy(this->path, name);
1100  }
1101  else
1102    {
1103      this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
1104      sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
1105    }
1106}
1107
1108const char* World::getPath( void)
1109{
1110  return path;
1111}
Note: See TracBrowser for help on using the repository browser.