Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: Quit Events are listened on.

  1. Quit-Button from the Windows Handler works
  2. ctrl-c also quits the game.

(smoothly)

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