Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 5112 was 5093, checked in by bensch, 20 years ago

orxonox/trunk: inputLine is working.

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