Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: inputLine is working.

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