Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: more doxygen-tags in util

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