Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: better method to register Shell-Commands (now via the Factory-algorithm proposed)

BUT!! NOW ONLY SINGLETON IS SUPPORTED → fixing!!

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