Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: more elaborate and MUCH easier through Macro-definition

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