Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: better check for SDL (on linux)

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