Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/network/src/story_entities/game_world.cc @ 6409

Last change on this file since 6409 was 6409, checked in by patrick, 18 years ago

network: the network loading now works again, couldn't test it over the network, since my laptop realy is too slow (600MHz and no hw gl). now we can continue working on the network stuff

File size: 11.6 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Patrick Boenzli
13   co-programmer: Christian Meyer
14   co-programmer: Benjamin Grauer
15*/
16
17#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
18
19#include "game_world.h"
20#include "game_world_data.h"
21
22#include "resource_manager.h"
23#include "state.h"
24#include "class_list.h"
25#include "substring.h"
26
27#include "game_loader.h"
28
29#include "p_node.h"
30#include "world_entity.h"
31#include "player.h"
32#include "camera.h"
33#include "environment.h"
34#include "terrain.h"
35#include "test_entity.h"
36#include "terrain.h"
37#include "md2Model.h"
38#include "weapons/projectile.h"
39#include "npcs/npc_test1.h"
40#include "playable.h"
41
42#include "light.h"
43
44#include "factory.h"
45#include "fast_factory.h"
46#include "load_param.h"
47#include "shell_command.h"
48
49#include "particle_engine.h"
50#include "graphics_engine.h"
51#include "event_handler.h"
52#include "sound_engine.h"
53#include "cd_engine.h"
54#include "network_manager.h"
55#include "physics_engine.h"
56#include "fields.h"
57
58#include "glmenu_imagescreen.h"
59#include "shell.h"
60
61#include "animation_player.h"
62#include "animation3d.h"
63
64#include "ogg_player.h"
65#include "shader.h"
66
67
68using namespace std;
69
70
71SHELL_COMMAND(speed, GameWorld, setSpeed);
72SHELL_COMMAND(togglePNodeVisibility, GameWorld, togglePNodeVisibility);
73SHELL_COMMAND(toggleBVVisibility, GameWorld, toggleBVVisibility);
74
75
76
77GameWorld::GameWorld(const TiXmlElement* root)
78    : StoryEntity()
79{
80  this->setClassID(CL_GAME_WORLD, "GameWorld");
81  this->setName("Preloaded World - no name yet");
82
83  this->gameTime = 0.0f;
84  this->setSpeed(1.0f);
85  this->shell = NULL;
86
87  this->showPNodes = false;
88  this->showBV = false;
89
90  this->path = NULL;
91}
92
93/**
94 *  remove the GameWorld from memory
95 *
96 *  delete everything explicitly, that isn't contained in the parenting tree!
97 *  things contained in the tree are deleted automaticaly
98 */
99GameWorld::~GameWorld ()
100{
101  PRINTF(4)("Deleted GameWorld\n");
102}
103
104
105
106/**
107 * loads the parameters of a GameWorld from an XML-element
108 * @param root the XML-element to load from
109 */
110void GameWorld::loadParams(const TiXmlElement* root)
111{
112  static_cast<StoryEntity*>(this)->loadParams(root);
113
114  LoadParam(root, "path", this, GameWorld, setPath)
115  .describe("The Filename of this GameWorld (relative from the data-dir)");
116
117  PRINTF(4)("Loaded GameWorld specific stuff\n");
118}
119
120
121/**
122 * this is executed just before load
123 *
124 * since the load function sometimes needs data, that has been initialized
125 * before the load and after the proceeding storyentity has finished
126*/
127ErrorMessage GameWorld::init()
128{
129  this->cycle = 0;
130  /* init the world interface */
131  this->shell = new Shell();
132
133  this->dataTank->init();
134}
135
136
137/**
138 *  loads the GameWorld by initializing all resources, and set their default values.
139 */
140ErrorMessage GameWorld::loadData()
141{
142  this->displayLoadScreen();
143
144  PRINTF(0)("Loading the GameWorld\n");
145
146  PRINTF(3)("> Loading world: '%s'\n", getPath());
147  TiXmlElement* element;
148  GameLoader* loader = GameLoader::getInstance();
149
150  if( getPath() == NULL)
151  {
152    PRINTF(1)("GameWorld has no path specified for loading");
153    return (ErrorMessage){213,"Path not specified","GameWorld::load()"};
154  }
155
156  TiXmlDocument* XMLDoc = new TiXmlDocument( getPath());
157  // load the xml world file for further loading
158  if( !XMLDoc->LoadFile())
159  {
160    PRINTF(1)("loading XML File: %s @ %s:l%d:c%d\n", XMLDoc->ErrorDesc(), this->getPath(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
161    delete XMLDoc;
162    return (ErrorMessage){213,"XML File parsing error","GameWorld::load()"};
163  }
164  // check basic validity
165  TiXmlElement* root = XMLDoc->RootElement();
166  assert( root != NULL);
167  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
168  {
169    // report an error
170    PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
171    delete XMLDoc;
172    return (ErrorMessage){213,"Path not a WorldDataFile","GameWorld::load()"};
173  }
174  /* the whole loading process for the GameWorld */
175  this->dataTank->loadData(root);
176
177  delete XMLDoc;
178  this->releaseLoadScreen();
179}
180
181
182/**
183 *  unload the data of this GameWorld
184 */
185ErrorMessage GameWorld::unloadData()
186{
187  delete this->shell;
188  PRINTF(3)("GameWorld::~GameWorld() - unloading the current GameWorld\n");
189
190  this->dataTank->unloadData();
191}
192
193
194/**
195 *  starts the GameWorld
196 */
197bool GameWorld::start()
198{
199  this->isPaused = false;
200  this->isRunning = true;
201
202  this->run();
203}
204
205
206/**
207 *  stops the world.
208 */
209bool GameWorld::stop()
210{
211  PRINTF(3)("GameWorld::stop() - got stop signal\n");
212  this->isRunning = false;
213}
214
215
216/**
217 *  pauses the game
218 */
219bool GameWorld::pause()
220{
221  this->isPaused = true;
222}
223
224
225/**
226 *  ends the pause Phase
227 */
228bool GameWorld::resume()
229{
230  this->isPaused = false;
231}
232
233
234/**
235 *  main loop of the world: executing all world relevant function
236 *
237 * in this loop we synchronize (if networked), handle input events, give the heart-beat to
238 * all other member-entities of the world (tick to player, enemies etc.), checking for
239 * collisions drawing everything to the screen.
240 */
241void GameWorld::run()
242{
243  this->lastFrame = SDL_GetTicks ();
244  PRINTF(3)("GameWorld::mainLoop() - Entering main loop\n");
245
246  while( this->isRunning) /* @todo implement pause */
247  {
248    ++this->cycle;
249    /* process intput */
250    this->handleInput ();
251    if( !this->isRunning)
252      break;
253
254    /* network synchronisation */
255    this->synchronize ();
256    /* process time */
257    this->tick ();
258    /* process collision */
259    this->collide ();
260    /* update the state */
261    this->update ();
262    /* draw everything */
263    this->display ();
264  }
265
266  PRINTF(3)("GameWorld::mainLoop() - Exiting the main loop\n");
267}
268
269
270/**
271 *  synchronize local data with remote data
272*/
273void GameWorld::synchronize ()
274{}
275
276
277/**
278 *  run all input processing
279
280   the command node is the central input event dispatcher. the node uses the even-queue from
281   sdl and has its own event-passing-queue.
282*/
283void GameWorld::handleInput ()
284{
285  EventHandler::getInstance()->process();
286}
287
288
289/**
290 *  ticks a WorldEntity list
291 * @param entityList list of the WorldEntities
292 * @param dt time passed since last frame
293 */
294void GameWorld::tick(std::list<WorldEntity*> entityList, float dt)
295{
296  std::list<WorldEntity*>::iterator entity;
297  for (entity = entityList.begin(); entity != entityList.end(); entity++)
298    (*entity)->tick(dt);
299
300}
301
302/**
303 *  advance the timeline
304 *
305 * this calculates the time used to process one frame (with all input handling, drawing, etc)
306 * the time is mesured in ms and passed to all world-entities and other classes that need
307 * a heart-beat.
308 */
309void GameWorld::tick ()
310{
311  Uint32 currentFrame = SDL_GetTicks();
312
313  if( !this->isPaused)
314  {
315    this->dt = currentFrame - this->lastFrame;
316
317    /* limit the the frame rate to 100 frames per second (fps) */
318    if( this->dt < 10)
319    {
320      /* the frame-rate is limited to 100 frames per second, all other things are for nothing. */
321      PRINTF(0)("fps = 1000 - frame rate is adjusted\n");
322      SDL_Delay(10 - dt);
323      this->dt = 10;
324    }
325
326    this->dtS = (float)this->dt / 1000.0f * this->speed;
327    this->gameTime += this->dtS;
328
329    this->tick(this->dataTank->objectManager->getObjectList(OM_DEAD_TICK), this->dtS);
330    this->tick(this->dataTank->objectManager->getObjectList(OM_COMMON), this->dtS);
331    this->tick(this->dataTank->objectManager->getObjectList(OM_GROUP_00), this->dtS);
332    this->tick(this->dataTank->objectManager->getObjectList(OM_GROUP_01), this->dtS);
333    this->tick(this->dataTank->objectManager->getObjectList(OM_GROUP_01_PROJ), this->dtS);
334
335    /* update tick the rest */
336    this->dataTank->localCamera->tick(this->dtS);
337    AnimationPlayer::getInstance()->tick(this->dtS);
338    ParticleEngine::getInstance()->tick(this->dtS);
339    PhysicsEngine::getInstance()->tick(this->dtS);
340
341    GraphicsEngine::getInstance()->tick(this->dtS);
342  }
343  this->lastFrame = currentFrame;
344}
345
346
347/**
348 *  this function gives the world a consistant state
349 *
350 * after ticking (updating the world state) this will give a constistant
351 * state to the whole system.
352 */
353void GameWorld::update()
354{
355  GraphicsEngine::getInstance()->update(this->dtS);
356  PNode::getNullParent()->updateNode (this->dtS);
357  SoundEngine::getInstance()->update();
358  //music->update();
359}
360
361
362/**
363 * kicks the CDEngine to detect the collisions between the object groups in the world
364 */
365void GameWorld::collide()
366{
367  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getObjectList(OM_GROUP_00),
368      this->dataTank->objectManager->getObjectList(OM_GROUP_01_PROJ));
369  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getObjectList(OM_GROUP_01),
370      this->dataTank->objectManager->getObjectList(OM_COMMON));
371}
372
373/**
374 *  render the current frame
375 *
376 * clear all buffers and draw the world
377 */
378void GameWorld::display ()
379{
380  // clear buffer
381  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
382  // set camera
383  this->dataTank->localCamera->apply ();
384  // draw world
385  this->draw();
386  // flip buffers
387  GraphicsEngine::swapBuffers();
388}
389
390
391/**
392 *  runs through all entities calling their draw() methods
393 */
394void GameWorld::draw ()
395{
396  GraphicsEngine* engine = GraphicsEngine::getInstance();
397
398   /* to draw the bounding boxes of the objects at level 2 for debug purp */
399  if( unlikely( this->showBV))
400  {
401    CDEngine* engine = CDEngine::getInstance();
402    engine->drawBV(State::getObjectManager()->getObjectList(OM_ENVIRON_NOTICK));
403    engine->drawBV(State::getObjectManager()->getObjectList(OM_ENVIRON));
404    engine->drawBV(State::getObjectManager()->getObjectList(OM_COMMON));
405    engine->drawBV(State::getObjectManager()->getObjectList(OM_GROUP_00));
406    engine->drawBV(State::getObjectManager()->getObjectList(OM_GROUP_01));
407    engine->drawBV(State::getObjectManager()->getObjectList(OM_GROUP_01_PROJ));
408  }
409  /* debug draw the PNodes */
410  if( unlikely(this->showPNodes))
411    PNode::getNullParent()->debugDraw(0);
412
413  /* draw all WorldEntiy groups */
414  engine->draw(State::getObjectManager()->getObjectList(OM_ENVIRON_NOTICK));
415  engine->draw(State::getObjectManager()->getObjectList(OM_ENVIRON));
416  engine->draw(State::getObjectManager()->getObjectList(OM_COMMON));
417  engine->draw(State::getObjectManager()->getObjectList(OM_GROUP_00));
418  engine->draw(State::getObjectManager()->getObjectList(OM_GROUP_01));
419  engine->draw(State::getObjectManager()->getObjectList(OM_GROUP_01_PROJ));
420  /* draws the particles */
421  ParticleEngine::getInstance()->draw();
422
423  /* final draw command */
424  engine->draw();
425}
426
427
428/**
429 *  sets the track path of this world
430 * @param name the name of the path
431 */
432void GameWorld::setPath( const char* name)
433{
434  if (this->path)
435    delete this->path;
436  if (ResourceManager::isFile(name))
437  {
438    this->path = new char[strlen(name)+1];
439    strcpy(this->path, name);
440  }
441  else
442  {
443    this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
444    sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
445  }
446}
447
448
449/**
450 *  shows the loading screen
451 */
452void GameWorld::displayLoadScreen ()
453{
454  PRINTF(3)("GameWorld::displayLoadScreen - start\n");
455  this->dataTank->glmis = new GLMenuImageScreen();
456  this->dataTank->glmis->setMaximum(8);
457  PRINTF(3)("GameWorld::displayLoadScreen - end\n");
458}
459
460
461/**
462 *  removes the loadscreen, and changes over to the game
463 */
464void GameWorld::releaseLoadScreen ()
465{
466  PRINTF(3)("GameWorld::releaseLoadScreen - start\n");
467  this->dataTank->glmis->setValue(this->dataTank->glmis->getMaximum());
468  PRINTF(3)("GameWorld::releaseLoadScreen - end\n");
469}
470
Note: See TracBrowser for help on using the repository browser.