Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/util/loading/game_loader.cc @ 5498

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

orxonox/trunk: even less debug-info

File size: 8.3 KB
RevLine 
[2636]1
2
[4597]3/*
[2636]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: ...
16*/
17
[5300]18#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOAD
19
[2636]20#include "game_loader.h"
[5139]21
22#include "shell_command.h"
[2636]23#include "campaign.h"
24#include "world.h"
25#include "orxonox.h"
26#include "camera.h"
27#include "vector.h"
[4094]28#include "resource_manager.h"
[4010]29#include "factory.h"
[4410]30#include "event.h"
31#include "event_handler.h"
[2636]32#include <string.h>
33
34
35using namespace std;
36
37
[5195]38SHELL_COMMAND(quit, GameLoader, stop)
39    ->describe("quits the game")
40    ->setAlias("orxoquit");
[2636]41
[5162]42
43GameLoader* GameLoader::singletonRef = NULL;
44
45
[4445]46/**
[4836]47 *  simple constructor
[4487]48*/
[4597]49GameLoader::GameLoader ()
[4017]50{
[4597]51  this->setClassID(CL_GAME_LOADER, "GameLoader");
52  this->setName("GameLoader");
[5139]53
[4017]54}
[2636]55
56
[4445]57/**
[4836]58 *  simple deconstructor
[4487]59*/
[4816]60GameLoader::~GameLoader ()
61{
62  if( this->currentCampaign)
63    delete this->currentCampaign;
64  this->currentCampaign = NULL;
65}
[2636]66
67
[3225]68/**
[4836]69 *  this class is a singleton class
70 * @returns an instance of itself
[3225]71
72   if you are unsure about singleton classes, check the theory out on the internet :)
73*/
[2636]74GameLoader* GameLoader::getInstance()
75{
76  if(singletonRef == NULL)
77    singletonRef = new GameLoader();
78  return singletonRef;
79}
80
[4487]81/**
[4836]82 *  initializes the GameLoader
[4487]83*/
[3222]84ErrorMessage GameLoader::init()
[2636]85{
86  if(this->currentCampaign != NULL)
87    this->currentCampaign->init();
[4411]88
89  this->eventHandler = EventHandler::getInstance();
[5093]90  this->eventHandler->subscribe(this, ES_GAME, KeyMapper::PEV_PAUSE);
[4411]91  this->eventHandler->subscribe(this, ES_ALL, KeyMapper::PEV_QUIT);
[5093]92  this->eventHandler->subscribe(this, ES_GAME, KeyMapper::PEV_NEXT_WORLD);
93  this->eventHandler->subscribe(this, ES_GAME, KeyMapper::PEV_PREVIOUS_WORLD);
[2636]94}
95
96
[3225]97/**
[4836]98 *  reads a campaign definition file into a campaign class
99 * @param fileName to be loaded
100 * @returns the loaded campaign
[3225]101
102   this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
103*/
[4487]104ErrorMessage GameLoader::loadCampaign(const char* fileName)
[2636]105{
[3222]106  ErrorMessage errorCode;
[4487]107  char* campaignName = ResourceManager::getFullName(fileName);
[4216]108  if (campaignName)
[4094]109    {
110      this->currentCampaign = this->fileToCampaign(campaignName);
[5208]111      delete[] campaignName;
[4094]112    }
[4816]113//   World* world0 = new World(DEBUG_WORLD_0);
114//   world0->setNextStoryID(WORLD_ID_GAMEEND);
115//   this->currentCampaign->addEntity(world0, WORLD_ID_2);
[2636]116}
117
[3225]118/**
[4836]119 *  loads a debug campaign for test purposes only.
120 * @param campaignID the identifier of the campaign.
121 * @returns error message if not able to do so.
[3225]122*/
[3222]123ErrorMessage GameLoader::loadDebugCampaign(Uint32 campaignID)
[2636]124{
125  switch(campaignID)
126    {
[4597]127      /*
128         Debug Level 0: Debug level used to test the base frame work.
129         As you can see, all storyentity data is allocated before game
130         start. the storyentity will load themselfs shortly before start
131         through the StoryEntity::init() funtion.
[3629]132      */
[2636]133    case DEBUG_CAMPAIGN_0:
134      {
[4597]135        Campaign* debugCampaign = new Campaign();
[3220]136
[4597]137        World* world0 = new World(DEBUG_WORLD_0);
138        world0->setNextStoryID(WORLD_ID_1);
139        debugCampaign->addEntity(world0, WORLD_ID_0);
[3220]140
[4597]141        World* world1 = new World(DEBUG_WORLD_1);
142        world1->setNextStoryID(WORLD_ID_2);
143        debugCampaign->addEntity(world1, WORLD_ID_1);
[2636]144
[4597]145        World* world2 = new World(DEBUG_WORLD_2);
146        world2->setNextStoryID(WORLD_ID_GAMEEND);
147        debugCampaign->addEntity(world2, WORLD_ID_2);
[3727]148
[4597]149        this->currentCampaign = debugCampaign;
150        break;
[2636]151      }
152    }
153}
154
[4443]155
[4597]156/**
[4836]157  *  starts the current entity
158  * @returns error code if this action has caused a error
[4443]159*/
[3222]160ErrorMessage GameLoader::start()
[2636]161{
162  if(this->currentCampaign != NULL)
163    this->currentCampaign->start();
164}
165
166
[4597]167/**
[4836]168  *  stops the current entity
169  * @returns error code if this action has caused a error
[4443]170
171    ATTENTION: this function shouldn't call other functions, or if so, they must return
172    after finishing. If you ignore or forget to do so, the current entity is not able to
173    terminate and it will run in the background or the ressources can't be freed or even
174    worse: are freed and the program will end in a segmentation fault!
175    hehehe, have ya seen it... :)
176*/
[5139]177void GameLoader::stop()
[2636]178{
179  if(this->currentCampaign != NULL)
180    this->currentCampaign->stop();
181}
182
183
[4597]184/**
[4836]185  *  pause the current entity
186  * @returns error code if this action has caused a error
[4443]187
188    this pauses the current entity or passes this call forth to the running entity.
189*/
[3222]190ErrorMessage GameLoader::pause()
[2636]191{
192  this->isPaused = true;
193  if(this->currentCampaign != NULL)
194    this->currentCampaign->pause();
195}
196
197
[4597]198/**
[4836]199  *  resumes a pause
200  * @returns error code if this action has caused a error
[4443]201
202    this resumess the current entity or passes this call forth to the running entity.
203*/
[3222]204ErrorMessage GameLoader::resume()
[2636]205{
206  this->isPaused = false;
207  if(this->currentCampaign != NULL)
208    this->currentCampaign->resume();
209}
210
[4443]211
[3225]212/**
[4836]213 *  release the mem ATTENTION: not implemented
[3225]214 */
215ErrorMessage GameLoader::destroy()
[4487]216{
[2636]217
[4487]218}
[2636]219
[4487]220
[3225]221/**
[4836]222 *  reads a campaign definition file into a campaign class
223 * @param fileName to be loaded
224 * @returns the loaded campaign
[3225]225
226   this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
227*/
[4487]228Campaign* GameLoader::fileToCampaign(const char* fileName)
[2636]229{
230  /* do not entirely load the campaign. just the current world
231     before start of each world, it has to be initialized so it
232     can load everything it needs into memory then.
233  */
[4597]234
[4487]235  if( fileName == NULL)
[4010]236    {
[4113]237      PRINTF(2)("No filename specified for loading");
[4010]238      return NULL;
239    }
[4597]240
[4487]241  TiXmlDocument* XMLDoc = new TiXmlDocument( fileName);
[4010]242  // load the campaign document
243  if( !XMLDoc->LoadFile())
244    {
245      // report an error
[4487]246      PRINTF(1)("Could not load XML File %s: %s @ %d:%d\n", fileName, XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
[4010]247      delete XMLDoc;
248      return NULL;
249    }
[4597]250
[4010]251  // check basic validity
252  TiXmlElement* root = XMLDoc->RootElement();
253  assert( root != NULL);
[4597]254
[4010]255  if( strcmp( root->Value(), "Campaign"))
256    {
257      // report an error
[4113]258      PRINTF(2)("Specified XML File is not an orxonox campaign file (Campaign element missing)\n");
[4010]259      delete XMLDoc;
260      return NULL;
261    }
[4597]262
[4010]263  // construct campaign
264  Campaign* c = new Campaign( root);
[4597]265
[4010]266  // free the XML data
267  delete XMLDoc;
[4496]268
[4010]269  return c;
[2636]270}
271
272
273/**
[4836]274 *  handle keyboard commands
275 * @param event the event to handle
[2636]276*/
[4410]277void GameLoader::process(const Event& event)
278{
279  if( event.type == KeyMapper::PEV_NEXT_WORLD)
280    {
[4597]281      if( likely(event.bPressed))
282        {
283          this->nextLevel();
284        }
[4410]285    }
286  else if( event.type == KeyMapper::PEV_PREVIOUS_WORLD)
287    {
288      if( likely(event.bPressed))
[4597]289        {
290          this->previousLevel();
291        }
[4410]292    }
293  else if( event.type == KeyMapper::PEV_PAUSE)
294    {
295      if( likely(event.bPressed))
[4597]296        {
297          if(this->isPaused)
298            this->resume();
299          else
300            this->pause();
301        }
[4410]302    }
303  else if( event.type == KeyMapper::PEV_QUIT)
304    {
305      if( event.bPressed) this->stop();
306    }
307}
308
[4443]309
[4487]310/**
[3225]311  \brief this changes to the next level
312*/
[2636]313void GameLoader::nextLevel()
314{
315  if(this->currentCampaign != NULL)
316    this->currentCampaign->nextLevel();
317}
318
[3225]319
[4487]320/**
[3225]321  \brief change to the previous level - not implemented
322
323  this propably useless
324*/
[2636]325void GameLoader::previousLevel()
326{
327  if(this->currentCampaign != NULL)
328    this->currentCampaign->previousLevel();
329}
[4010]330
331/**
[4836]332 *  load a StoryEntity
333 * @param element a XMLElement containing all the needed info
[4010]334*/
[4598]335BaseObject* GameLoader::fabricate(const TiXmlElement* element)
[4010]336{
[4114]337  assert( element != NULL);
[4597]338
[4739]339  if( Factory::getFirst() == NULL)
[4114]340    {
341      PRINTF(1)("GameLoader does not know any factories, fabricate() failed\n");
342      return NULL;
343    }
[4597]344
[4114]345  if( element->Value() != NULL)
346    {
347      PRINTF(4)("Attempting fabrication of a '%s'\n", element->Value());
[4739]348      BaseObject* b = Factory::getFirst()->fabricate( element);
[4597]349      if( b == NULL)
350        PRINTF(2)("Failed to fabricate a '%s'\n", element->Value());
351      else
352        PRINTF(4)("Successfully fabricated a '%s'\n", element->Value());
[4114]353      return b;
354    }
[4597]355
[4114]356  PRINTF(2)("Fabricate failed, TiXmlElement did not contain a value\n");
[4597]357
[4114]358  return NULL;
[4010]359}
Note: See TracBrowser for help on using the repository browser.