Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: campaign now gets loaded via LoadParam

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