Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/2d-recalc/src/util/loading/game_loader.cc @ 5808

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

orxonox/trunk: even less debug-info

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