Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: some work in the loading process of worlds

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